/** * ==VimperatorPlugin== * @name lookup dictionary (Vimperator plugin) * @description Lookup words from Web dictionaries, and show the results in the bottom of the window * @description-ja Web上の辞書を引いた結果をコマンドライン・バッファへ出力します * @author teramako teramako@gmail.com * @version 0.3 * ==/VimperatorPlugin== */ (function(){ const SITE_DEFINITION = [{ names: ['eiji[ro]'], url: 'http://eow.alc.co.jp/%s/UTF-8/', shortHelp: 'SPACE ALC (英辞郎 on the Web)', xpath: 'id("resultList")' },{ names: ['goo'], url: 'http://dictionary.goo.ne.jp/search.php?MT=%s&kind=all&mode=0', shortHelp: 'goo 辞書', encode: 'EUC-JP', xpath: '//div[@id="incontents"]/*[@class="ch04" or @class="fs14" or contains(@class,"diclst")]', multi: true },{ names: ['infokanji'], url: 'http://dictionary.www.infoseek.co.jp/?sc=1&se=on&lp=0&gr=kj&sv=KJ&qt=&qty=%s&qtb=&qtk=0', shorthelp: 'Infoseek 漢字辞書', encode: 'EUC-JP', xpath: '//div[@class="NetDicHead"]' },{ names: ['answers'], url: 'http://www.answers.com/%s', shortHelp: 'Answers.com(英英辞書)', xpath: 'id("firstDs")' }]; // class definition function SpellChecker() { this.initialize.apply(this, arguments); } SpellChecker.prototype = { initialize: function () { const MYSPELL = "@mozilla.org/spellchecker/myspell;1"; const HUNSPELL = "@mozilla.org/spellchecker/hunspell;1"; const ENGINE = "@mozilla.org/spellchecker/engine;1"; var spellclass = MYSPELL; if (HUNSPELL in Components.classes) spellclass = HUNSPELL; if (ENGINE in Components.classes) spellclass = ENGINE; this.engine = Components.classes[spellclass] .createInstance(Components.interfaces.mozISpellCheckingEngine); }, /** * @return {Array} */ getDictionaryList: function () { var dictionaries = {}; this.engine.getDictionaryList(dictionaries, {}); return dictionaries.value; }, /** * @return {String} */ dictionary: function () { var dict; try { dict = this.engine.dictionary; } catch (e) {} return dict ? dict : null; }, /** * @param {String} dict */ setDictionary: function (dict) { this.engine.dictionary = dict; }, /** * @param {Boolean} isBeginningWith */ setBeginningWith: function (isBeginningWith) { this.isBeginningWith = isBeginningWith; }, /** * @param {String} spell * @return {Boolean} */ check: function (spell) { return this.engine.check(spell); }, /** * @param {String} spell * @return {Array} */ suggest: function (spell) { var suggestions = {}; this.engine.suggest(spell, suggestions, {}); suggestions = suggestions.value; if (this.isBeginningWith) { suggestions = suggestions.filter( function (cand) { return (cand.toLowerCase().indexOf(spell) === 0); }); } return suggestions; }, }; var spellChecker = buildSpellChecker(); SITE_DEFINITION.forEach(function(dictionary){ liberator.commands.addUserCommand( dictionary.names, dictionary.shortHelp, function(arg,special){ var sel = (window.content.window.getSelection) ? window.content.window.getSelection().toString() : null; if (special && sel) arg = sel; if (!arg) return; var url; if (dictionary.encode){ var ttbu = Components.classes['@mozilla.org/intl/texttosuburi;1'] .getService( Components.interfaces.nsITextToSubURI); url = dictionary.url.replace(/%s/g, ttbu.ConvertAndEscape(dictionary.encode, arg)); } else { url = dictionary.url.replace(/%s/g,encodeURI(arg)); } //liberator.log('URL: ' +url); var result; getHTML(url, function(str){ var doc = createHTMLDocument(str); var result = getNodeFromXPath(dictionary.xpath, doc, dictionary.multi); if (!result){ liberator.echoerr('Nothing to show...'); } var xs = new XMLSerializer(); liberator.echo('' + xs.serializeToString( result ), true); }, dictionary.encode ? dictionary.encode : 'UTF-8'); }, { completer: function (arg) { if (!spellChecker.dictionary()) return [0, []]; var suggestions = spellChecker.suggest(arg); var candidates = []; for (var i=0, max=suggestions.length ; i