Skip to content

Instantly share code, notes, and snippets.

@tily
Created April 2, 2010 14:39
Show Gist options
  • Save tily/353191 to your computer and use it in GitHub Desktop.
Save tily/353191 to your computer and use it in GitHub Desktop.
fast look up kihwanujish
// ==UserScript==
// @name Fast Look up Kihwanujish
// @namespace http://kihwanujish.jottit.com/
// @include http://*
// ==/UserScript==
// based on scripts bellow
// - "Fast Look up Alc" by cho45 (http://userscripts.org/scripts/show/12024)
// - "Google Reader Full Feed" by mattn (http://coderepos.org/share/wiki/GoogleReaderFullFeed)
(function () {
var dic = null;
var popups = [];
window.addEventListener("mouseup", function (e) {
var selection = window.getSelection().toString();
log(selection);
selection = selection.replace(/\s/g, '');
if (!selection || !selection.match(/^[ァ-ヶー]+$/i) || selection.match(/^\s+$/)) return;
if(dic == null) dic = eval(GM_getValue('dic')) || null;
if(dic == null) {
dic = {};
getDictionaryData(function(dic) {
showTermDescription(dic, selection);
});
} else {
setTimeout(function() {
showTermDescription(dic, selection);
}, 100);
}
}, false);
document.body.addEventListener('click', function (e) {
var e;
while (e = popups.pop()) {
e.parentNode.removeChild(e);
}
}, false);
GM_registerMenuCommand('Fast Look up Kihwanujish - update dictionary', function() {
dic = {}; getDictionaryData();
});
function showTermDescription(dic, selection) {
if(!dic[selection]) return;
var area = $N('div', {style: [
'position: fixed',
'bottom: 0',
'left: 0',
'right: 0',
'border: 1px solid #000',
'background: #fff',
'color: #000',
'max-height: 50%',
'overflow: auto',
'opacity: 0.9',
'z-index: 500',
'text-align: left'
].join(';')});
area.innerHTML = dic[selection];
area.addEventListener('click', function (e) {
area.style.display = 'none';
}, false);
document.body.appendChild(area);
popups.push(area);
}
function getDictionaryData(callback) {
GM_xmlhttpRequest({
method: 'get',
url: 'http://kihwanujish.jottit.com/%E5%8D%98%E8%AA%9E%E5%B8%B3',
onload : function (req) {
var t = $N('div');
t.innerHTML = req.responseText;
$X('//div[@id="content"]/ul/li', t).forEach(function (e) {
removeXSSRisks(e);
var term = $X('./text()', e)[0].textContent.replace(/\n/g, '');
var desc = e.innerHTML;
desc = desc.replace(/(<[^>]+?[\s"'])on(?:(?:un)?load|(?:dbl)?click|mouse(?:down|up|over|move|out)|key(?:press|down|up)|focus|blur|submit|reset|select|change)\s*=\s*(?:"(?:\\"|[^"])*"?|'(\\'|[^'])*'?|[^\s>]+(?=[\s>]|<\w))(?=[^>]*?>|<\w|\s*$)/gi,"$1");
desc = desc.replace(/<script(?:\s[^>]+?)?>[\S\s]*?<\/script\s*>/gi, "");
dic[term] = desc;
});
GM_setValue('dic', dic.toSource());
if(callback != undefined) callback(dic);
}
});
}
/* template functions */
function removeXSSRisks(htmldoc) {
var attr = "allowScriptAccess";
Array.forEach(htmldoc.getElementsByTagName("embed"), function(embed) {
embed.hasAttribute(attr) && embed.setAttribute(attr, "never");
});
Array.forEach(htmldoc.getElementsByTagName("param"), function(param) {
param.getAttribute("name") == attr && param.setAttribute("value", "never");
});
}
function log () {
var c = unsafeWindow.console;
//if (c) c.log.apply(c, arguments);
}
function $N(name, attr, childs) {
var ret = document.createElement(name);
for (k in attr) {
if (!attr.hasOwnProperty(k)) continue;
v = attr[k];
if (k == "class") {
ret.className = v;
} else {
ret.setAttribute(k, v);
}
}
switch (typeof childs) {
case "string": {
ret.appendChild(document.createTextNode(childs));
break;
}
case "object": {
for (var i = 0, len = childs.length; i < len; i++) {
var child = childs[i];
if (typeof child == "string") {
ret.appendChild(document.createTextNode(child));
} else {
ret.appendChild(child);
}
}
break;
}
}
return ret;
}
function $X(exp, context) {
if (!context) context = document;
var resolver = function (prefix) {
var o = document.createNSResolver(context)(prefix);
return o ? o : (document.contentType == "text/html") ? "" : "http://www.w3.org/1999/xhtml";
}
var exp = document.createExpression(exp, resolver);
var result = exp.evaluate(context, XPathResult.ANY_TYPE, null);
switch (result.resultType) {
case XPathResult.STRING_TYPE : return result.stringValue;
case XPathResult.NUMBER_TYPE : return result.numberValue;
case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: {
result = exp.evaluate(context, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var ret = [];
for (var i = 0, len = result.snapshotLength; i < len ; i++) {
ret.push(result.snapshotItem(i));
}
return ret;
}
}
return null;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment