// ==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(/]+?)?>[\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; } })();