您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
划词翻译,使用必应词典
当前为
// ==UserScript== // @namespace ATGT // @name bing-dict // @name:zh-CN 必应词典 // @description Select any word in any web to show it's definition from Bing Dict. // @description:zh-CN 划词翻译,使用必应词典 // @version 1.3.6 // @author StrongOp // @supportURL https://github.com/strongop/user-scripts/issues // @match http://*/* // @match https://*/* // -match https://github.com/* // @grant GM.xmlHttpRequest // @grant GM_xmlhttpRequest // @grant GM.setValue // @grant GM.getValue // @connect www.bing.com // @icon https://www.bing.com/favicon.ico // @run-at document-end // ==/UserScript== /* Change Log: v1.3.6: 30 Jan 2019, Need user click on checkbox to enable translate. v1.3.5: 21 Dec 2018, Fix GM_xmlhttpRequest not def in Greasemonkey, GM not define in Tampermonkey v1.3.4: 28 Nov 2018, Fix GM.xmlHttpRequest not def in chrome. v1.3.3: 28 Jan 2018, Fix dict provider overlap with result. Add test cases. v1.3.2: 27 Jan 2018, Add dict provider name: Bing Dict. v1.3.1: 19 Jan 2018, Escape suggested words. v1.3: 19 Jan 2018, refactor & parse search suggestion. v1.2: 14 Jan 2018, Escape search word and result. v1.1: 13 Jan 2018, Reset style for result div. v1.0: 12 Jan 2018, Initial version. */ console.log("!!!!!!!!!!!!!!!!!!!!!bing-dict!!!!!!!!!!!!!!!!!!!!!!!!"); (function () { (function addStyleSheet() { var style = document.createElement("STYLE"); style.type = "text/css"; var css = ` div#ATGT-bing-dict-result-wrapper-reset { all: initial; * { all: initial; } } div#ATGT-bing-dict-result-wrapper { display: block; position: fixed; left: 2px; bottom: 2px; max-width: 32%; z-index: 2100000000; padding: 0; margin: 0; color: black; background-color: rgba(255,255,255,0.9); font-size: small; font-family: sans-serif; white-space: normal; } div#ATGT-bing-dict-result-wrapper .dict-provider { font-size: xx-small; float: right; margin-left: 0.5rem; /* position: absolute; top: 2px; right: 2px; */ } div#ATGT-bing-dict-result-wrapper .dict-provider input { display: inline; vertical-align: bottom; transform: scale(0.7); margin: 0 0; } div#ATGT-bing-dict-result-wrapper .search_suggest_area { font-size: xx-small; } div#ATGT-bing-dict-result-wrapper .error { color: red; } div#ATGT-bing-dict-result-wrapper .headword { font-weight: bold; font-size: medium; } div#ATGT-bing-dict-result-wrapper .div_title { font-weight: bold; } div#ATGT-bing-dict-result-wrapper .suggest_word { margin-right: 5px; } div#ATGT-bing-dict-result-wrapper .mach_trans { font-style: italic; font-size: x-small; } div#ATGT-bing-dict-result-wrapper a:link { color: #37a; text-decoration: none; } div#ATGT-bing-dict-result-wrapper a:hover { color: white; background-color: #37a; } div#ATGT-bing-dict-result-wrapper .pronuce { color: gray; } div#ATGT-bing-dict-result-wrapper .mach_trans_result { color: gray; } div#ATGT-bing-dict-result-wrapper ul { list-style-type: none; padding: 1px; margin: 0px; } div#ATGT-bing-dict-result-wrapper ul li{ margin-top: 1px; } div#ATGT-bing-dict-result-wrapper ul li span { float:left; color: white; background-color: gray; text-align: center; padding: 0 2px; margin-right: 3px; } `; style.appendChild(document.createTextNode(css)); document.head.appendChild(style); })(); var dictResultDiv = (function createDictResultDiv() { var div_wrapper_reset = document.createElement("DIV"); div_wrapper_reset.id = "ATGT-bing-dict-result-wrapper-reset"; var div = document.createElement("DIV"); div.id = "ATGT-bing-dict-result-wrapper"; div_wrapper_reset.appendChild(div); document.body.appendChild(div_wrapper_reset); return div; })(); var dictCache = {}; var entityMap = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/', '`': '`', '=': '=' }; function escapeHtml (string) { return String(string).replace(/[&<>"'`=\/]/g, function (s) { return entityMap[s]; }); } var dictProvider = '<div class=dict-provider><input type=checkbox id=enableTrans><span>Bing Dict<span></div>'; function setResult(defs) { dictResultDiv.innerHTML = dictProvider + defs; showEnableTransChoice(); } function hideResult() { dictResultDiv.innerHTML = ''; transEnableShown = false; } function parseDefinition(page, url) { //console.log("parseDefinition"); var qdef = page.querySelector(".qdef"); //console.log("qdef ", qdef); var hd_area = qdef.childNodes[0]; try { var headword = escapeHtml(hd_area.querySelector("#headword").innerText); } catch (e) { var headword = ""; } var hd_pr = ""; try { /* en to cn */ hd_pr = escapeHtml(hd_area.querySelector(".hd_prUS").innerText) + " " + escapeHtml(hd_area.querySelector(".hd_pr").innerText); } catch (e) { } try { if (!hd_pr) /* cn to en */ hd_pr = escapeHtml(hd_area.querySelector(".hd_tf_lh").innerText); } catch (e) { } headword = "<div class='headword'>" + "<a href='"+url+"' target='_blank'>" + headword + "</a>" + "</div>"; hd_pr = "<div class='pronuce'>" + hd_pr + "</div>"; try { var def_area = qdef.childNodes[1]; var def_list = def_area.querySelectorAll("li"); var defs = "<ul>"; for (var def of def_list) { defs += "<li><span>" + escapeHtml(def.childNodes[0].innerText) + "</span>" + escapeHtml(def.childNodes[1].innerText) + "</li>"; } defs += "</ul>"; } catch (e) { var defs = ""; } return headword + hd_pr + defs; } function parseMachTrans(page, url) { //console.log("parseMachTrans"); var trans_area = page.querySelector(".lf_area"); try { var smt_hw_elem = trans_area.querySelector(".smt_hw"); var smt_hw = escapeHtml(smt_hw_elem.innerText); var headword_elem = smt_hw_elem.nextElementSibling; var headword = escapeHtml(headword_elem.innerText); var trans_result_elem = headword_elem.nextElementSibling; var trans_result = escapeHtml(trans_result_elem.innerText); } catch (e) { } smt_hw = "<div class='mach_trans'>" + smt_hw + "</div>"; headword = "<div class='headsentence'>" +"<a href='"+url+"' target='_blank'>" + headword + "</a>" +"</div>"; trans_result = "<div class='mach_trans_result'>" + trans_result + "</div>"; return smt_hw + headword + trans_result; } function parseBingDymArea(dym) { var suggest = escapeHtml(dym.querySelector(".df_wb_a").innerText); suggest = "<div class='div_title'>"+suggest+"</div>"; var defs = "<ul>"; for (var s of dym.querySelectorAll(".df_wb_c")) { var r0 = s.childNodes[0]; var r1 = s.childNodes[1]; defs += "<li><a class='suggest_word' href='" + "//www.bing.com" + r0.pathname + r0.search + "'>" + escapeHtml(r0.innerText) + "</a>" + escapeHtml(r1.innerText) + "</li>"; } defs += "</ul>"; return suggest + defs; } function parseSearchSuggest(page, url) { //console.log("parseSearchSuggest"); var trans_area = page.querySelector(".lf_area"); var headword = escapeHtml(trans_area.querySelector(".dym_p").innerText); var suggest = escapeHtml(trans_area.querySelector(".p2-2").innerText); headword = "<div class='headword'><a href='" + url + "'>" + headword + "</a></div>"; suggest = "<div class='div_title'>" + suggest + "</div>"; var defs = ""; for (var dym of trans_area.querySelectorAll(".dym_area")) { defs += parseBingDymArea(dym); } return "<div class='search_suggest_area'>" + headword + suggest + defs + "</div>"; } function parseDictResultDom(page, url) { //console.log("page ", page); var qdef = page.querySelector(".qdef"); var smt_hw = page.querySelector(".smt_hw"); var search_suggest = page.querySelector(".dym_area") && page.querySelector(".df_wb_c"); //var no_result = page.querySelector(".no_results"); if (qdef) return parseDefinition(page, url); else if (smt_hw) return parseMachTrans(page, url); else if (search_suggest) return parseSearchSuggest(page, url); else return ""; } const fallback_message = "No result.<br />Try <a href='https://www.bing.com/translator' target=_blank>Microsoft Translator</a>."; function parseDictResult(word, response) { //console.log("search dict ok", response); var url = response.finalUrl; try { var parser = new DOMParser(); var doc = parser.parseFromString(response.responseText, "text/html"); var defs = parseDictResultDom(doc, url); if (!defs) defs = fallback_message; defs = defs; dictCache[word] = defs; } catch (e){ console.log("parseDictResult failed:\n " + e.stack); var defs = "<span class='error'>Error</span> parsing result of <a href='" + url + "'>" + escapeHtml(word) + "</a>, <br />" + fallback_message; } setResult(defs); } function searchDictFail(word, response) { //console.log("search dict fail ", response); var url = response.finalUrl; var status = (response.status ? response.status : "") + " " + (response.statusText ? response.statusText : ""); setResult("<span class='error'>Error</span> searching <a href='" + url + "'>" + escapeHtml(word) + "</a>, " + status + "<br />" + fallback_message); } function searchBingDict(word) { if (word in dictCache && dictCache[word]) { console.log("cache hit \"", word, "\""); setResult(dictCache[word]); return; } else { console.log("cache miss"); } var url = "http://www.bing.com/dict/search?q=" + encodeURIComponent(word); console.log(url); setResult("Searching <a href='" + url + "' target='_blank'>" + escapeHtml(word) + "</a>"); (typeof GM_xmlhttpRequest != "undefined" && GM_xmlhttpRequest || GM.xmlHttpRequest)({ url : url, method : "GET", onload : (response) => parseDictResult(word, response), onerror : (response) => searchDictFail(word, response), }); } var CurrentSelWord = ''; var transEnabledOnPage = false; var transEnableShown = false; async function updateTransEnabledList(key, value) { let transEnabledList = JSON.parse(await GM.getValue("transEnabledList", "{}")); transEnabledList[key] = value; GM.setValue("transEnabledList", transEnabledList) } function showEnableTransChoice() { transEnableShown = true; function enableTransChoiceHandler(event){ console.log("enableTransChoiceHandler called, translate enable ", event.target.checked); updateTransEnabledList(location.host, event.target.checked); transEnabledOnPage = event.target.checked; if (transEnabledOnPage && CurrentSelWord.length > 0) searchBingDict(CurrentSelWord); else hideResult(); } let enableInput = document.querySelector("div#ATGT-bing-dict-result-wrapper input#enableTrans"); enableInput.checked = transEnabledOnPage; enableInput.onclick = enableTransChoiceHandler; } async function checkEnableTrans() { let transEnabledList = JSON.parse(await GM.getValue("transEnabledList", "{}")); if (!transEnabledList) { //GM.setValue("enableTrans", "{}"); return; } if (transEnabledList[location.host] === true) transEnabledOnPage = true; } checkEnableTrans(); document.addEventListener("mouseup", function (event) { CurrentSelWord = window.getSelection().toString().replace(/^\s*|\s*$/g, ""); console.log("selected: \"", CurrentSelWord, "\", length", CurrentSelWord.length); if (CurrentSelWord.length == 0) { hideResult(); return; } if (!transEnabledOnPage) { if (!transEnableShown) setResult(""); console.log("translate not enabled."); return; } var divRect = dictResultDiv.getBoundingClientRect(); if (event.clientX >= divRect.left && event.clientX <= divRect.right && event.clientY >= divRect.top && event.clientY <= divRect.bottom) { // Mouse is inside result element, do nothing. return; } searchBingDict(CurrentSelWord); }); function dictTest() { var testWords = ["hello", // word definition "hello, this is world", //machine translation "ndalo", // ambigous "DNS queries", // example sentence only "<script>", // html escape "", "overrideMimeType", // no result ]; for (var i=0; i<testWords.length; i++) { setTimeout(searchBingDict, i*1500, testWords[i]); } } // dictTest(); })(); console.log("!!!!!!!!!!!!!!!!!!!!!/bing-dict!!!!!!!!!!!!!!!!!!!!!!!!");