// ==UserScript== // @name Youdao Dictionary Enhancer // @namespace http://tampermonkey.net/ // @homepage https://github.com/creamidea/YoudaoDictionaryEnhancer // @version 1.2.0 // @description Search words in Celerity // @author creamidea // @match http://*.youdao.com/* // @require http://cdn.bootcss.com/jquery/3.1.0/jquery.min.js // @require http://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js // @resource nprogress_css http://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css // @resource etymoline_css http://www.etymonline.com/style.css // @resource etymoline_font http://fonts.googleapis.com/css?family=Slabo+27px:400&lang=en // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @grant GM_getResourceText // @grant GM_xmlhttpRequest // @connect www.etymonline.com // @connect www.google.com // @downloadURL none // ==/UserScript== // changelog: // version 1.2 add record of google define // version 1.1 add translation function in etymoline area // version 1.0 initial release GM_addStyle(GM_getResourceText("nprogress_css")); GM_addStyle('body{font-famile:"Hiragino Sans GB",STHeiti,"Microsoft YaHei","Wenquanyi Micro Hei","WenQuanYi Micro Hei Mono","WenQuanYi Zen Hei","WenQuanYi Zen Hei Mono",LiGothicMed}'); GM_addStyle('.youdao-trans-icon {position: absolute;border-radius: 5px;padding: 3px; background-color: rgb(245, 245, 245);box-sizing: content-box;cursor: pointer;height: 18px;width: 18px;z-index: 2147483647;border: 1px solid rgb(220, 220, 220);color: rgb(51, 51, 51);}'); GM_addStyle('.etymoline .hint {text-align: center;font-size: 24px;margin: 24px 0;color: rebeccapurple;}'); GM_addStyle('#container{background: #f6f4ec;border-radius: 6px;box-shadow: 2px 2px 9px 1px gray;padding-left: 16px;padding-right: 16px;padding-bottom: 26px;margin-top: 16px;}'); GM_addStyle('.keyword{font-family: Georgia,"Lucida Grande","Lucida Sans Unicode","Lucida Sans",Geneva,Arial,sans-serif; font-size: 39px;border-bottom: 2px gray dotted;}'); GM_addStyle('#phrsListTab .trans-container>ul{font-size: 16px;} #phrsListTab .trans-container>ul>li{margin: 4px auto;}'); GM_addStyle('li .collinsMajorTrans{background: gainsboro !important;}'); GM_addStyle('.c-topbar-wrapper{box-shadow: 0 0 0 #fcfcfe;}'); (function () { 'use strict'; if (NProgress === undefined) NProgress = { set: function () { }, start: function () { }, inc: function () { }, done: function () { }, configure: function () { }, }; var ETYMONLINEHTTP = 'http://www.etymonline.com'; var GOOGLEHTTP = 'https://www.google.com'; var YOUDAOHTTP = $(location).attr('protocol') + '//' + $(location).attr('hostname'); var $scontainer = $('#scontainer'); var $query = $('#query'); var $topImgAd = $('#topImgAd'); var $webTrans = $('#webTrans'); var injectEtymolineName = 'creamidea' + makeId(9); // make the name of injecting function is unique var openURLFunName = 'openurl' + makeId(9); var proxySelection = 'proxySelection' + makeId(9); var sltContainerName = 'selectionContainer' + makeId(9); var youdaoSearchButtonId = 'youdaoSearchButton' + makeId(9); var googleFrameId = 'googleResult' + makeId(9); // remove the ad $topImgAd.remove(); $('#baidu-adv').remove(); $('#follow').remove(); // window global function. It is the callback in the iframe window[injectEtymolineName] = function (event) { // open the next page in the etymoline.com iframe event.preventDefault(); var target = event.target; request(ETYMONLINEHTTP + target.attributes.href.value); }; window[openURLFunName] = function (event) { event.preventDefault(); location.href = event.target.attributes.href.value; }; window[proxySelection] = function (event) { var sel = window.getSelection(); var range = document.createRange(); var targetSel = this.getSelection(); var $sltContainer = $('#' + sltContainerName); var selectionText = encodeURIComponent(targetSel.toString()); var $youdaoSearchButton = $('#' + youdaoSearchButtonId); if ($sltContainer.length === 0) $sltContainer = $('
').appendTo('body'); if ($youdaoSearchButton.length === 0) $youdaoSearchButton = $('').append('').appendTo('body'); if (selectionText === "") { $youdaoSearchButton.css({ display: 'none' }); return; } $sltContainer.css({ position: "absolute", zIndex: -1, top: "-1000px" }).text(selectionText); setTimeout(function () { $youdaoSearchButton.find('a').attr('href', YOUDAOHTTP + '/w/' + selectionText + '/') .end().css({ left: $('#' + injectEtymolineName).data('click-x'), top: $('#' + injectEtymolineName).data('click-y'), display: 'block' }); }, 24); range.selectNode($sltContainer[0]); sel.removeAllRanges(); sel.addRange(range); // range.setStart(targetSel.anchorNode, targetSel.anchorOffset); // range.setEnd(targetSel.focusNode, targetSel.focusOffset); // sel.removeAllRanges(); // sel.empty(); // sel.setBaseAndExtent(targetSel.anchorNode, targetSel.anchorOffset, targetSel.focusNode, targetSel.focusOffset); // window.getSelection().anchorNode.textContent.substring(this.getSelection().extentOffset, this.getSelection().anchorOffset); }; // create the frame wrapper var $frameWrapper = $('
').css({ border: 0, width: '100%' }).html( '
Etymoline.com ...
'); // var $googleFrameWrapper = // $('
').css({ border: 0, width: '100%' }).html( // '
google.com ...
'); if ($webTrans.length === 0) return; // maybe no result :) $frameWrapper.insertBefore($webTrans); // $googleFrameWrapper.insertBefore($webTrans); // set NProgress NProgress.configure({ parent: '#' + injectEtymolineName + '-wrapper' }); NProgress.set(0.7); NProgress.inc(0.2); // request the etymoline.com page var $phrsListTab = $('#phrsListTab'); var queryWord; if ($phrsListTab.length > 0 && $phrsListTab.find('.keyword').length > 0) queryWord = $phrsListTab.find('.keyword').text(); else queryWord = $query.val(); setTimeout(function () { NProgress.start(); request(ETYMONLINEHTTP + '/index.php?term=' + encodeURIComponent(queryWord), etymolineHandler); }, 0); setTimeout(function () { request(GOOGLEHTTP + '/search?sclient=psy-ab&hl=en&fp=1&num=1&start=0&q=' + encodeURIComponent('define: ' + queryWord), googleHandler); }, 60); // set the default explanation $('#webTrans .tabs a').each(function (i, link) { if (link.innerText === '英英释义') link.click(); }); // from: http://stackoverflow.com/a/12444641/1925954 var keys = {}; function test_key(selkey) { var alias = { "Ctrl": 17, "Shift": 16, "/": 191, "a": 65, "e": 69 }; return keys[selkey] || keys[alias[selkey]]; } function test_keys() { var i, keylist = arguments, status = true; for (i = 0; i < keylist.length; i++) { if (!test_key(keylist[i])) { // status = false; return false; } } return status; } function globalKeydown(event) { var keyCode = event.keyCode; keys[keyCode] = event.type === 'keydown'; if (test_keys('Shift', 'e')) { if ($('.baav .voice-js')[0]) $('.baav .voice-js')[0].click(); keys = {}; return false; } else if (test_keys('Shift', 'a')) { if ($('.baav .voice-js')[1]) $('.baav .voice-js')[1].click(); keys = {}; return false; } else if (test_keys('Shift', '/')) { // ? => help toggleHelp(); keys = {}; return false; } else if (test_keys('/')) { $query.focus().select(); keys = {}; return false; // to avoid input '/' in inputbox. } } function globalKeyup(event) { var keyCode = event.keyCode; keys[keyCode] = false; } $(document).keydown(globalKeydown).keyup(globalKeyup); // adjust the youdao css // move top navigation $('#container').css({ width: "1000px" }); $('#results').css({ width: "680px" }); $('#ads').css({ width: "320px" }); var transformToggle = []; $('#eTransform .tabs').children().each(function (index, elt) { transformToggle.push(elt.innerText); }); $('#transformToggle').children().each(function (index, elt) { if (elt.id === 'wordGroup') return; var $clone = $(elt).clone(); $clone.addClass('follow').removeClass('hide').css({ display: 'block' }).prepend('

' + transformToggle[index] + '

').next().css({ marginTop: "8px" }); $clone.appendTo('#ads'); });//.end().parent().remove(); $('#doc>.c-topbar-wrapper').css({ height: "81px", top: "-42px" }).find('.c-subtopbar').remove(); $scontainer.css({ marginTop: "42px" }); function request(url, callback) { var xhr = new GM_xmlhttpRequest({ method: 'GET', url: url, // anonymous: true, onreadystatechange: function (resp) { onreadystatechange(resp, callback); } }); } function onreadystatechange(resp, callback) { var readyState = resp.readyState; if (readyState === 0) { // Client has been created. open() not called yet. } else if (readyState === 1) { // open() has been called. } else if (readyState === 2) { // send() has been called, and headers and status are available. } else if (readyState === 3) { // Downloading; responseText holds partial data. } else if (readyState === 4) { switch (resp.status) { case 200: // etymolineHandler(resp.responseText); callback(resp.responseText); break; default: GM_log(['Ger Error: ', '\nState: ', resp.readyState, '\nMessage: ', resp.responseText].join('')); } } } function etymolineHandler(responseText) { var domParser = new DOMParser(); var doc = domParser.parseFromString(responseText, 'text/html'); var $dictionary = doc.querySelector('#dictionary'); $dictionary.style.border = 0; $dictionary.style.marginBottom = 0; var $frame = $('#' + injectEtymolineName); if ($frame.length === 0) { $frame = $('