/**
* ==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.2
* ==/VimperatorPlugin==
*/
(function(){
[{
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")'
}].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');
},{}
);
});
/**
* @param {String} url
* @param {Function} callback
* @param {String} charset
*/
function getHTML(url, callback, charset){
var xhr= new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if (xhr.status == 200){
callback.call(this,xhr.responseText);
} else {
throw new Error(xhr.statusText);
}
}
};
xhr.open('GET',url,true);
xhr.overrideMimeType('text/html; charset=' + charset);
xhr.send(null);
}
/**
* @param {String} str
* @return {DOMDocument}
*/
function createHTMLDocument(str){
str = str.replace(/^[\s\S]*?]+?)?>|<\/html\s*>[\S\s]*$/ig,'').replace(/[\r\n]+/g,' ');
var htmlFragment = document.implementation.createDocument(null,'html',null);
var range = document.createRange();
range.setStartAfter(window.content.document.body);
htmlFragment.documentElement.appendChild(htmlFragment.importNode(range.createContextualFragment(str),true));
return htmlFragment;
}
/**
* @param {String} xpath XPath Expression
* @param {DOMDocument} doc
* @param {Boolean} isMulti
* @return {Element}
*/
function getNodeFromXPath(xpath,doc,isMulti){
if (!xpath || !doc) return;
var result;
if (isMulti){
var nodesSnapshot = doc.evaluate(xpath,doc.documentElement,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
if (nodesSnapshot.snapshotLength == 0) return;
result = document.createElementNS(null,'div');
for (var i=0; i