tampermonkey-script/translate/translate-dictionary.js

1004 lines
46 KiB
JavaScript
Raw Normal View History

2019-01-04 11:07:50 +00:00
// ==UserScript==
// @name 划词翻译:多词典查询
2019-01-04 11:07:50 +00:00
// @namespace http://tampermonkey.net/
2019-02-21 13:53:56 +00:00
// @version 3.0
// @description 划词翻译调用“有道词典有道翻译、金山词霸、Bing 词典必应词典、剑桥高阶、沪江小D、谷歌翻译”
2019-01-04 11:07:50 +00:00
// @author https://github.com/barrer
// @match http://*/*
// @include https://*/*
// @include file:///*
// @run-at document-end
// @connect youdao.com
// @connect iciba.com
2019-01-07 10:59:21 +00:00
// @connect translate.google.cn
// @connect hjenglish.com
2019-01-24 05:38:10 +00:00
// @connect bing.com
// @connect chinacloudapi.cn
// @connect cambridge.org
2019-01-04 11:07:50 +00:00
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function () {
'use strict';
// Your code here...
2019-01-07 10:59:21 +00:00
/**样式*/
var style = document.createElement('style');
style.textContent = `
2019-02-21 04:21:09 +00:00
/*组件样式*/
*{word-wrap:break-word!important}
a{color:#36f;text-decoration:none;cursor:pointer}
a:hover{text-decoration:underline}
img{cursor:pointer;display:inline-block;width:22px;height:22px;border:1px solid #dfe1e5;border-radius:22px;background-color:rgba(255,255,255,1);padding:2px;margin:0;margin-right:5px;box-sizing:content-box;vertical-align:middle}
img:last-of-type{margin-right:auto}
img:hover{border:1px solid #c6c6c6;-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.1);box-shadow:1px 1px 3px rgba(0,0,0,0.1)}
img[activate]{border:1px solid transparent;-webkit-box-shadow:0 0 0 1px #f90;box-shadow:0 0 0 1px #f90}
tr-icon{display:none;position:absolute;padding:2px;margin:0;cursor:move;box-sizing:content-box;font-size:13px;text-align:left;border:0;color:black;z-index:2147483647;background:#fff;border-radius:2px;-webkit-box-shadow:0 3px 8px 0 rgba(0,0,0,0.2),0 0 0 1px rgba(0,0,0,0.08);box-shadow:0 3px 8px 0 rgba(0,0,0,0.2),0 0 0 1px rgba(0,0,0,0.08)}
tr-audio{display:block;margin-bottom:5px}
tr-audio a{color:#36f;text-decoration:none;cursor:pointer;margin-right:10px}
tr-audio a:last-of-type{margin-right:auto}
tr-audio a:hover{text-decoration:underline}
tr-content{display:block;max-width:300px;max-height:200px;width:300px;height:200px;overflow-x:auto;overflow-y:scroll;background:white;padding:2px 8px;margin-top:5px;box-sizing:content-box;font-family:"Helvetica Neue","Helvetica","Arial","sans-serif";font-size:14px;line-height:18px}
a.audio-button{color:#36f;text-decoration:none;cursor:pointer;margin-right:10px}
a.audio-button:last-of-type{margin-right:auto}
a.audio-button:hover{text-decoration:underline}
.br{border-top:1px dashed #777;margin:.5em auto .3em auto}
.list-title~.list-title{margin-top:1em}
.list-title{color:#00c;display:inline-block;text-decoration:none;cursor:inherit}
.list-title:hover{text-decoration:none;cursor:inherit}
/*各引擎样式*/
.google .sentences,.google .trans,.google .orig,.google .dict,.google .pos,.none{display:block}
.google .backend,.google .entry,.google .base_form,.google .pos_enum,.google .src,.google .confidence,.google .ld_result,.none{display:none}
.google .orig{font-style:italic;color:#777}
.google .pos{margin-top:1em}
.google .pos:before{content:"["}
.google .pos:after{content:"]"}
.google .terms:before{content:"【"}
.google .terms:after{content:"】"}
.google .terms{margin-right:.2em}
.youdao .pron{margin-right:1em}
.youdao .phone{color:#777;margin-right:1em}
.youdao .phone:before{content:"["}
.youdao .phone:after{content:"]"}
.youdao .phrs:before{content:"[短语]";display:block}
.youdao .trs>.tr>.exam:before{content:"[例句]";display:block}
.youdao .trs>.tr>.l:before{content:"[释义]";display:block}
.youdao [class="#text"]{font-style:italic}
.youdao .return-phrase,.youdao [class="@action"],.none{display:none}
.hjenglish dl,.hjenglish dt,.hjenglish dd,.hjenglish p,.hjenglish ul,.hjenglish li,.hjenglish h3{margin:0;padding:0;margin-block-start:0;margin-block-end:0;margin-inline-start:0;margin-inline-end:0}
.hjenglish h3{font-size:1em;font-weight:normal}
.hjenglish .detail-pron,.hjenglish .pronounces{color:#777}
.hjenglish ul{margin-left:2em}
.hjenglish .def-sentence-from,.hjenglish .def-sentence-to{display:none}
.hjenglish .detail-groups dd h3:before{counter-increment:eq;content:counter(eq) ".";display:block;width:22px;float:left}
.hjenglish .detail-groups dl{counter-reset:eq;margin-bottom:.5em;clear:both}
.hjenglish ol,.hjenglish ul{list-style:none}
.hjenglish dd{margin-left:1em}
.hjenglish dd>p{margin-left:2.5em}
.bing h1,.bing strong{font-size:1em;font-weight:normal;margin:0;padding:0}
.bing .concise ul{list-style:none;margin:0;padding:0}
.bing .hd_tf{margin-right:1em}
.bing .concise .pos{margin-right:.2em}
.bing .concise .web{margin-right:auto}
.bing .concise .web:after{content:""}
.bing .oald{margin-top:.4em}
.bing .hd_tf_lh div{display:inline;color:#777}
.bing #authid td:first-child{width:22px;margin:0;padding:0}
.bing .def_row{vertical-align:top}
.bing .bil_dis,.bing .val_dis{padding-right:.25em}
.bing .li_exs{display:none}
.bing .li_id{border:0;padding:.2em}
.bing .infor,.bing .sen_com,.bing .com_sep,.bing .bil,.bing .gra{padding-right:.25em}
.bing .infor,.bing .label{padding-left:.25em}
.bing .each_seg+.each_seg{margin-top:.5em}
.bing .de_co div{display:inline}
.bing .idm_seg,.bing .li_ids_co{margin-left:1em}
.bing .sim{display:inline}
.cambridge .entry~.entry{margin-top:1em}
.cambridge p,.cambridge h2,.cambridge h3{padding:0;margin:0}
.cambridge h2,.cambridge h3{font-size:1em;font-weight:normal}
.cambridge .headword .hw{display:block}
.cambridge .pron{color:#777;margin-right:1em}
.cambridge b.def{font-weight:normal}
.cambridge .epp-xref{border:1px solid #777;border-radius:.5em;padding:0 2px;font-size:.8em}
.cambridge .examp,.cambridge .extraexamps,.cambridge .cols,.cambridge .xref,.cambridge .fcdo{display:none}
.cambridge .entry-body__el+.entry-body__el{margin-top:1em}
.cambridge .pos-body{margin-left:1em}
.iciba h1{font-size:1em;font-weight:normal}
.iciba ul,.iciba li{list-style:none;margin:0;padding:0}
.iciba p,.iciba h1{margin:0;padding:0}
.iciba p{display:inline}
.iciba .base-speak{color:#777}
.iciba .base-speak>span{margin-right:1em}
.iciba .base-speak>span:last-of-type{margin-right:auto}
.iciba .change{margin-top:.4em}
.iciba .change span{margin-right:.5em}
.iciba .change span:last-of-type{margin-right:auto}
2019-01-07 10:59:21 +00:00
`;
2019-01-23 10:40:19 +00:00
// iframe 工具库
var iframe = document.createElement('iframe');
var iframeWin = null;
var iframeDoc = null;
iframe.style.display = 'none';
2019-02-17 01:52:33 +00:00
var icon = document.createElement('tr-icon'), //翻译图标
content = document.createElement('tr-content'), // 内容面板
contentList = document.createElement('div'), //翻译内容结果集HTML内容列表
selected, // 当前选中文本
engineId, // 当前翻译引擎
engineTriggerTime, // 引擎触发时间milliseconds
idsType; // 当前翻译面板内容列表数组
// 初始化内容面板
content.appendChild(contentList);
// 发音引擎
var audioEngines = []; // [{name: 'abc', url: 'http://*.mp3', ...}, ...]
// 翻译引擎结果集
var engineResult = {}; // id: DOM
// ID 类别
var ids = {
ICIBA: 'iciba',
ICIBA_LOWER_CASE: 'icibaLowerCase',
YOUDAO: 'youdao',
YOUDAO_LOWER_CASE: 'youdaoLowerCase',
BING: 'bing',
BING_LOWER_CASE: 'bingLowerCase',
HJENGLISH: 'hjenglish',
GOOGLE: 'google',
CAMBRIDGE: 'cambridge'
};
var idsExtension = {
2019-02-21 04:21:09 +00:00
LIST_DICT: [ids.ICIBA, ids.YOUDAO, ids.BING, ids.HJENGLISH, ids.CAMBRIDGE],
LIST_DICT_LOWER_CASE: [ids.ICIBA, ids.ICIBA_LOWER_CASE, ids.YOUDAO, ids.YOUDAO_LOWER_CASE, ids.BING, ids.BING_LOWER_CASE, ids.HJENGLISH, ids.CAMBRIDGE],
LIST_GOOGLE: [ids.GOOGLE],
lowerCaseMap: (function () {
var obj = {};
obj[ids.ICIBA_LOWER_CASE] = ids.ICIBA;
obj[ids.YOUDAO_LOWER_CASE] = ids.YOUDAO;
obj[ids.BING_LOWER_CASE] = ids.BING;
return obj;
})(),
names: (function () {
var obj = {};
obj[ids.ICIBA] = '《金山词霸》';
obj[ids.ICIBA_LOWER_CASE] = '';
obj[ids.YOUDAO] = '《有道词典》';
obj[ids.YOUDAO_LOWER_CASE] = '';
obj[ids.BING] = '《Bing 词典》';
obj[ids.BING_LOWER_CASE] = '';
obj[ids.HJENGLISH] = '《沪江小D》';
2019-01-21 10:07:07 +00:00
obj[ids.GOOGLE] = '《谷歌翻译》';
obj[ids.CAMBRIDGE] = '《剑桥高阶》';
return obj;
})(),
links: (function () {
var obj = {};
obj[ids.ICIBA] = 'http://www.iciba.com/%q%';
obj[ids.ICIBA_LOWER_CASE] = '';
obj[ids.YOUDAO] = 'https://dict.youdao.com/w/eng/%q%';
obj[ids.YOUDAO_LOWER_CASE] = '';
obj[ids.BING] = 'https://cn.bing.com/dict/search?q=%q%';
obj[ids.BING_LOWER_CASE] = '';
obj[ids.HJENGLISH] = 'https://dict.hjenglish.com/w/%q%';
obj[ids.GOOGLE] = function (text) {
var rst = '';
if (hasChineseByRange(text)) {
rst = 'https://translate.google.cn/#view=home&op=translate&sl=auto&tl=en&text=' + encodeURIComponent(text);
} else {
rst = 'https://translate.google.cn/#view=home&op=translate&sl=auto&tl=zh-CN&text=' + encodeURIComponent(text);
}
return rst;
};
obj[ids.CAMBRIDGE] = 'https://dictionary.cambridge.org/dictionary/english-chinese-simplified/%q%';
return obj;
})(),
engines: (function () {
var obj = {};
2019-02-17 01:52:33 +00:00
obj[ids.ICIBA] = function (text, time) {
2019-02-21 04:21:09 +00:00
ajax('http://www.iciba.com/' + encodeURIComponent(text), function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.ICIBA, parseIciba(rst), time);
showContent();
}, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.ICIBA, htmlToDom('error: 无法连接翻译服务'), time);
showContent();
});
};
2019-02-17 01:52:33 +00:00
obj[ids.ICIBA_LOWER_CASE] = function (text, time) {
2019-02-21 04:21:09 +00:00
ajax('http://www.iciba.com/' + encodeURIComponent(text.toLowerCase()), function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.ICIBA_LOWER_CASE, parseIciba(rst), time);
showContent();
}, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.ICIBA_LOWER_CASE, htmlToDom('error: 无法连接翻译服务'), time);
showContent();
});
};
2019-02-17 01:52:33 +00:00
obj[ids.YOUDAO] = function (text, time) {
ajax('http://dict.youdao.com/jsonapi?xmlVersion=5.1&jsonversion=2&q=' + encodeURIComponent(text), function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.YOUDAO, parseYoudao(rst), time)
showContent();
}, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.YOUDAO, htmlToDom('error: 无法连接翻译服务'), time);
showContent();
});
};
2019-02-17 01:52:33 +00:00
obj[ids.YOUDAO_LOWER_CASE] = function (text, time) {
ajax('http://dict.youdao.com/jsonapi?xmlVersion=5.1&jsonversion=2&q=' + encodeURIComponent(text.toLowerCase()), function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.YOUDAO_LOWER_CASE, parseYoudao(rst), time);
showContent();
}, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.YOUDAO_LOWER_CASE, htmlToDom('error: 无法连接翻译服务'), time)
showContent();
});
};
2019-02-17 01:52:33 +00:00
obj[ids.BING] = function (text, time) {
2019-02-18 10:17:08 +00:00
ajax('https://cn.bing.com/dict/search?q=' + encodeURIComponent(text), function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.BING, parseBing(rst), time);
showContent();
}, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.BING, htmlToDom('error: 无法连接翻译服务'), time);
showContent();
});
};
2019-02-17 01:52:33 +00:00
obj[ids.BING_LOWER_CASE] = function (text, time) {
2019-02-18 10:17:08 +00:00
ajax('https://cn.bing.com/dict/search?q=' + encodeURIComponent(text.toLowerCase()), function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.BING_LOWER_CASE, parseBing(rst), time);
showContent();
}, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.BING_LOWER_CASE, htmlToDom('error: 无法连接翻译服务'), time);
showContent();
});
};
2019-02-17 01:52:33 +00:00
obj[ids.HJENGLISH] = function (text, time) {
ajax('https://dict.hjenglish.com/w/' + encodeURIComponent(text), function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.HJENGLISH, parseHjenglish(rst), time);
showContent();
}, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.HJENGLISH, htmlToDom('error: 无法连接翻译服务'), time);
showContent();
}, {
headers: {
'Cookie': 'HJ_SID=' + uuid() + '; HJ_SSID_3=' + uuid() + '; HJ_CST=1; HJ_CSST_3=1; HJ_UID=' + uuid()
}
});
};
2019-02-17 01:52:33 +00:00
obj[ids.GOOGLE] = function (text, time) {
var url = 'https://translate.google.cn/translate_a/single?client=gtx&dt=t&dt=bd&dj=1&source=input&hl=zh-CN&sl=auto';
url += '&tk=' + token(text);
if (hasChineseByRange(text)) {
url += '&tl=en&q=' + encodeURIComponent(text);
} else {
url += '&tl=zh-CN&q=' + encodeURIComponent(text);
}
ajax(url, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.GOOGLE, parseGoogle(rst), time);
showContent();
}, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.GOOGLE, htmlToDom('error: 无法连接翻译服务'), time);
showContent();
});
};
2019-02-17 01:52:33 +00:00
obj[ids.CAMBRIDGE] = function (text, time) {
var url = 'https://dictionary.cambridge.org/dictionary/english-chinese-simplified/' + encodeURIComponent(text);
ajax(url, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.CAMBRIDGE, parseCambridge(rst), time);
showContent();
}, function (rst) {
2019-02-17 01:52:33 +00:00
putEngineResult(ids.CAMBRIDGE, htmlToDom('error: 无法连接翻译服务'), time);
showContent();
});
};
return obj;
})()
}
// 绑定图标拖动事件
var iconDrag = new Drag(icon);
// 图标数组
var iconArray = [{
name: '多词典查询',
id: 'icon-dict',
image: 'data:image/png;base64,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',
2019-02-17 01:52:33 +00:00
trigger: function (text, time) {
idsType = idsExtension.LIST_DICT;
if (text != text.toLowerCase()) {
idsType = idsExtension.LIST_DICT_LOWER_CASE; // 大小写各请求一次
}
idsType.forEach(function (id) {
2019-02-17 01:52:33 +00:00
idsExtension.engines[id](text, time);
});
2019-01-04 11:07:50 +00:00
}
2019-01-07 10:59:21 +00:00
}, {
name: '谷歌翻译',
id: 'icon-google',
image: 'data:image/png;base64,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',
2019-02-17 01:52:33 +00:00
trigger: function (text, time) {
idsType = idsExtension.LIST_GOOGLE;
idsType.forEach(function (id) {
2019-02-17 01:52:33 +00:00
idsExtension.engines[id](text, time);
2019-01-07 10:59:21 +00:00
});
}
2019-01-04 11:07:50 +00:00
}];
2019-01-09 12:50:31 +00:00
// 添加翻译引擎图标
2019-01-04 11:07:50 +00:00
iconArray.forEach(function (obj) {
var img = document.createElement('img');
img.setAttribute('src', obj.image);
img.setAttribute('alt', obj.name);
img.setAttribute('title', obj.name);
img.setAttribute('icon-id', obj.id);
2019-01-04 11:07:50 +00:00
img.addEventListener('mouseup', function () {
if (!isDrag()) { // 没有拖动鼠标抬起的时候触发点击事件
if (engineId == obj.id) {
return; // 已经是当前翻译引擎
}
contentList.innerHTML = ''; // 清空翻译内容列表
content.style.display = 'block'; // 立马显示翻译面板
content.scrollTop = 0; // 翻译面板滚动到顶端
content.scrollLeft = 0; // 翻译面板滚动到左端
2019-01-07 10:59:21 +00:00
engineId = obj.id; // 翻译引擎 ID
2019-02-17 01:52:33 +00:00
engineTriggerTime = new Date().getTime(); // 引擎触发时间
2019-01-08 10:15:14 +00:00
engineActivateShow(); // 显示翻译引擎指示器
audioEngines = []; // 清空发音引擎
engineResult = {}; // 清空翻译引擎结果集
2019-02-17 01:52:33 +00:00
obj.trigger(selected, engineTriggerTime); // 启动翻译引擎
}
2019-01-04 11:07:50 +00:00
});
icon.appendChild(img);
});
2019-01-09 12:50:31 +00:00
// 添加内容面板(放图标后面)
icon.appendChild(content);
// 添加样式、翻译图标到 DOM
2019-01-07 03:44:12 +00:00
var root = document.createElement('div');
document.documentElement.appendChild(root);
var shadow = root.attachShadow({
mode: 'open'
});
2019-01-23 10:40:19 +00:00
// iframe 工具库加入 Shadow
shadow.appendChild(iframe);
iframeWin = iframe.contentWindow;
iframeDoc = iframe.contentDocument;
// 外部样式表
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = createObjectURLWithTry(new Blob(['\ufeff', style.textContent], {
type: 'text/css;charset=UTF-8'
}));
2019-01-07 10:59:21 +00:00
// 多种方式最大化兼容Content Security Policy
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
shadow.appendChild(style); // 内部样式表
shadow.appendChild(link); // 外部样式表
// 翻译图标加入 Shadow
2019-01-07 03:44:12 +00:00
shadow.appendChild(icon);
2019-01-04 11:07:50 +00:00
// 鼠标事件:防止选中的文本消失
document.addEventListener('mousedown', function (e) {
2019-01-07 10:59:21 +00:00
log('mousedown event:', e);
2019-01-04 11:07:50 +00:00
if (e.target == icon || (e.target.parentNode && e.target.parentNode == icon)) { // 点击了翻译图标
e.preventDefault();
}
});
// 鼠标事件:防止选中的文本消失;显示、隐藏翻译图标
document.addEventListener('mouseup', function (e) {
2019-01-07 10:59:21 +00:00
log('mouseup event:', e);
2019-01-04 11:07:50 +00:00
if (e.target == icon || (e.target.parentNode && e.target.parentNode == icon)) { // 点击了翻译图标
e.preventDefault();
return;
}
2019-01-07 10:59:21 +00:00
selected = window.getSelection().toString().trim(); // 当前选中文本
log('click text:' + selected);
2019-01-09 12:50:31 +00:00
if (selected && icon.style.display == 'none') { // 显示翻译图标
2019-01-04 11:07:50 +00:00
log('show icon');
2019-01-07 10:59:21 +00:00
log(selected + ' | ' + e.pageX + ' | ' + e.pageY);
2019-01-04 11:07:50 +00:00
icon.style.top = e.pageY + 10 + 'px';
icon.style.left = e.pageX + 10 + 'px';
icon.style.display = 'block';
2019-01-07 10:59:21 +00:00
// 兼容部分 Content Security Policy
icon.style.position = 'absolute';
icon.style.zIndex = '2147483647';
2019-01-09 12:50:31 +00:00
} else if (!selected) { // 隐藏翻译图标
log('hide icon:mouseup');
hideIcon();
2019-01-04 11:07:50 +00:00
}
});
2019-01-09 12:50:31 +00:00
// 选中变化事件:当点击已经选中的文本的时候,隐藏翻译图标(此时浏览器动作是:选中的文本已经取消选中了)
document.addEventListener('selectionchange', function (e) {
2019-01-07 10:59:21 +00:00
log('selectionchange event:', e);
log('selectionchange:' + window.getSelection().toString());
if (!window.getSelection().toString().trim()) {
log('hide icon:selectionchange');
hideIcon();
}
});
// 内容面板滚动事件
content.addEventListener('scroll', function (e) {
if (content.scrollHeight - content.scrollTop === content.clientHeight) {
log('scroll bottom', e);
e.preventDefault();
e.stopPropagation();
} else if (content.scrollTop === 0) {
log('scroll top', e);
e.preventDefault();
e.stopPropagation();
2019-01-07 10:59:21 +00:00
}
});
2019-01-04 11:07:50 +00:00
/**日志输出*/
function log() {
2019-01-16 13:01:02 +00:00
var debug = false;
if (!debug) {
2019-01-04 11:07:50 +00:00
return;
}
2019-01-04 11:07:50 +00:00
if (arguments) {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
}
/**鼠标拖动*/
function Drag(element) {
this.dragging = false;
this.startDragTime = 0;
this.stopDragTime = 0;
2019-01-04 11:07:50 +00:00
this.mouseDownPositionX = 0;
this.mouseDownPositionY = 0;
this.elementOriginalLeft = parseInt(element.style.left);
this.elementOriginalTop = parseInt(element.style.top);
2019-01-04 11:07:50 +00:00
var ref = this;
this.startDrag = function (e) {
e.preventDefault();
ref.dragging = true;
ref.startDragTime = new Date().getTime();
2019-01-04 11:07:50 +00:00
ref.mouseDownPositionX = e.clientX;
ref.mouseDownPositionY = e.clientY;
ref.elementOriginalLeft = parseInt(element.style.left);
ref.elementOriginalTop = parseInt(element.style.top);
// set mousemove event
window.addEventListener('mousemove', ref.dragElement);
log('startDrag');
};
this.unsetMouseMove = function () {
// unset mousemove event
window.removeEventListener('mousemove', ref.dragElement);
};
this.stopDrag = function (e) {
e.preventDefault();
ref.dragging = false;
ref.stopDragTime = new Date().getTime();
2019-01-04 11:07:50 +00:00
ref.unsetMouseMove();
log('stopDrag');
};
this.dragElement = function (e) {
log('dragging');
if (!ref.dragging) {
2019-01-04 11:07:50 +00:00
return;
}
2019-01-04 11:07:50 +00:00
e.preventDefault();
// move element
element.style.left = ref.elementOriginalLeft + (e.clientX - ref.mouseDownPositionX) + 'px';
element.style.top = ref.elementOriginalTop + (e.clientY - ref.mouseDownPositionY) + 'px';
log('dragElement');
};
element.onmousedown = this.startDrag;
element.onmouseup = this.stopDrag;
}
/**是否拖动图标*/
function isDrag() {
return iconDrag.elementOriginalLeft != parseInt(icon.style.left) ||
iconDrag.elementOriginalTop != parseInt(icon.style.top);
}
/**强制结束拖动*/
function forceStopDrag() {
if (iconDrag) {
// 强制设置鼠标拖动事件结束防止由于网页本身的其它鼠标事件冲突而导致没有侦测到mouseup
iconDrag.dragging = false;
iconDrag.unsetMouseMove();
}
}
2019-01-07 13:26:29 +00:00
/**是否包含汉字*/
2019-01-07 10:59:21 +00:00
function hasChineseByRange(str) {
for (var i = 0; i < str.length; i++) {
if (str.charCodeAt(i) >= 0x4E00 && str.charCodeAt(i) <= 0x9FBF) {
return true;
}
}
return false;
}
/**uuid*/
function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
2019-01-07 10:59:21 +00:00
/**对象转 xml*/
function objToXml(obj) {
var xml = '';
for (var prop in obj) {
2019-01-23 10:40:19 +00:00
if (obj[prop] instanceof iframeWin.Function) {
continue;
}
2019-01-23 10:40:19 +00:00
xml += obj[prop] instanceof iframeWin.Array ? '' : '<' + prop + '>';
if (obj[prop] instanceof iframeWin.Array) {
2019-01-07 10:59:21 +00:00
for (var array in obj[prop]) {
2019-01-23 10:40:19 +00:00
if (obj[prop][array] instanceof iframeWin.Function) {
continue;
}
xml += '<' + prop + '>';
2019-01-23 10:40:19 +00:00
xml += objToXml(new iframeWin.Object(obj[prop][array]));
xml += '</' + prop + '>';
2019-01-07 10:59:21 +00:00
}
2019-01-23 10:40:19 +00:00
} else if (obj[prop] instanceof iframeWin.Object) {
xml += objToXml(new iframeWin.Object(obj[prop]));
2019-01-07 10:59:21 +00:00
} else {
xml += obj[prop];
}
2019-01-23 10:40:19 +00:00
xml += obj[prop] instanceof iframeWin.Array ? '' : '</' + prop + '>';
2019-01-07 10:59:21 +00:00
}
var xml = xml.replace(/<\/?[0-9]{1,}>/g, '');
return xml
}
/**xml 转 html*/
function xmlToHtml(xml, tag) {
return xml.replace(/<([^/]+?)>/g, '<' + tag + ' class="$1">')
2019-01-07 10:59:21 +00:00
.replace(/<\/(.+?)>/g, '</' + tag + '>');
}
// html 字符串转 DOM
function htmlToDom(htmlStr) {
var div = document.createElement('div');
div.innerHTML = htmlStr;
return div;
}
/**清理 html*/
function cleanHtml(htmlStr) {
return htmlStr.replace(/<script[\s\S]*?<\/script>/ig, '')
.replace(/<link[\s\S]*?>/ig, '')
.replace(/<style[\s\S]*?<\/style>/ig, '')
.replace(/<img[\s\S]*?>/ig, '')
.replace(/on[a-z]*=".*?"/ig, '');
}
2019-01-23 10:40:19 +00:00
/**带异常处理的 createObjectURL*/
function createObjectURLWithTry(blob) {
try {
return iframeWin.URL.createObjectURL(blob);
} catch (error) {
log(error);
}
return '';
}
2019-01-04 11:07:50 +00:00
/**ajax 跨域访问公共方法*/
function ajax(url, success, error, obj) {
if (!!!obj) {
obj = {};
}
if (!!!obj.method) {
obj.method = 'GET';
}
2019-01-04 11:07:50 +00:00
// >>>因为Tampermonkey跨域访问(a.com)时会自动携带对应域名(a.com)的对应cookie
// 不会携带当前域名的cookie
// 所以GM_xmlhttpRequest【不存在】cookie跨域访问安全性问题
// 以下设置的cookie会添加到已有cookie的后面<<<
if (!!!obj.headers) {
obj.headers = {
2019-01-04 11:07:50 +00:00
'cookie': ''
};
}
2019-01-04 11:07:50 +00:00
GM_xmlhttpRequest({
method: obj.method,
2019-01-04 11:07:50 +00:00
url: url,
headers: obj.headers,
responseType: obj.responseType,
data: obj.data,
2019-01-04 11:07:50 +00:00
onload: function (res) {
success(res.responseText, res, obj);
2019-01-04 11:07:50 +00:00
},
onerror: function (res) {
error(res.responseText, res, obj);
},
onabort: function (res) {
error('the request was aborted', res, obj);
},
ontimeout: function (res) {
error('the request failed due to a timeout', res, obj);
},
onreadystatechange: function () {
log('ajax:', arguments);
2019-01-04 11:07:50 +00:00
}
});
}
2019-02-17 01:52:33 +00:00
/**放入翻译引擎结果集*/
function putEngineResult(id, value, time) {
if (time == engineTriggerTime) { // 是本次触发的异步ajax请求
engineResult[id] = value;
}
}
/**翻译引擎结果集状态判断*/
function isAllDone() {
var rst = true;
var count = 0;
idsType.forEach(function (id) {
if (count < 1) { // 判断指定数量的完成情况
count++;
if (!(id in engineResult)) {
log('isAllDone(not found):' + id);
rst = false;
}
}
});
return rst;
}
2019-01-04 11:07:50 +00:00
/**显示内容面板*/
function showContent() {
log('showContent:', idsType, engineResult);
if (isAllDone()) {
2019-01-21 10:07:07 +00:00
log('showContent allDone');
} else {
return;
}
log('showContent rendering');
// 发音
2019-01-21 10:07:07 +00:00
audioEngines = []; // 清空防止多次渲染
audioEngines.push({
name: '♪us',
url: 'http://dict.youdao.com/dictvoice?audio=' + selected + '&type=2'
});
audioEngines.push({
name: '♪uk',
url: 'http://dict.youdao.com/dictvoice?audio=' + selected + '&type=1'
});
var audio = document.createElement('tr-audio');
audioEngines.forEach(function (obj) {
audio.appendChild(getPlayButton(obj));
});
contentList.innerHTML = ''; // 清空翻译内容列表
// 比较大小写内容
var needDel = {};
for (var key in idsExtension.lowerCaseMap) {
if (engineResult[key] &&
engineResult[idsExtension.lowerCaseMap[key]] &&
(engineResult[key].innerHTML == engineResult[idsExtension.lowerCaseMap[key]].innerHTML ||
engineResult[key].innerHTML.toLowerCase() == engineResult[idsExtension.lowerCaseMap[key]].innerHTML.toLowerCase())) {
needDel[key] = key;
}
}
idsType.forEach(function (id) {
2019-01-21 10:07:07 +00:00
if (engineResult[id] && !(id in needDel)) {
if (idsExtension.names[id]) {
var title = document.createElement('a');
title.innerHTML = idsExtension.names[id];
title.setAttribute('class', 'list-title');
// 添加跳转
var href = 'javascript:void(0)';
if (idsExtension.links[id]) {
var link = idsExtension.links[id];
if (typeof link == 'string') {
if (link.length > 0) {
href = link.replace(/%q%/ig, encodeURIComponent(selected));
}
} else if (typeof link == 'function') {
var fnHref = link(selected);
if (fnHref.length > 0) {
href = fnHref;
}
}
}
title.setAttribute('rel', 'noreferrer noopener');
title.setAttribute('target', '_blank');
title.setAttribute('href', href);
// 事件
title.addEventListener('click', linkEvent);
contentList.appendChild(title);
}
contentList.appendChild(engineResult[id]);
}
});
if (engineId != 'icon-google') { // 谷歌翻译不显示发音图标
contentList.insertBefore(audio, contentList.childNodes[0]);
2019-01-07 10:59:21 +00:00
}
2019-01-04 11:07:50 +00:00
}
2019-01-08 10:15:14 +00:00
/**隐藏翻译引擎指示器*/
function engineActivateHide() {
icon.querySelectorAll('img[activate]').forEach(function (ele) {
ele.removeAttribute('activate');
});
}
/**显示翻译引擎指示器*/
function engineActivateShow() {
engineActivateHide();
icon.querySelector('img[icon-id="' + engineId + '"').setAttribute('activate', 'activate');
2019-01-08 10:15:14 +00:00
}
/**隐藏 icon*/
function hideIcon() {
icon.style.display = 'none';
content.style.display = 'none';
engineId = '';
2019-02-17 01:52:33 +00:00
engineTriggerTime = 0;
audioEngines = [];
engineResult = {};
engineActivateHide();
forceStopDrag();
}
/**发音*/
function play(obj) {
if (isDrag()) { // 拖动时候不触发发音
return;
}
2019-01-23 10:40:19 +00:00
var audio = new iframeWin.Audio();
ajax(obj.url, function (rst, res) {
2019-01-23 10:40:19 +00:00
audio.src = createObjectURLWithTry(res.response);
audio.play();
}, function (rst) {
log(rst);
}, {
responseType: 'blob'
});
}
/**得到发音按钮*/
function getPlayButton(obj) {
var type = document.createElement('a');
type.innerHTML = obj.name;
type.setAttribute('href', 'javascript:void(0)');
type.setAttribute('class', 'audio-button');
type.addEventListener('mouseup', function () {
play(obj);
});
return type;
}
/**链接点击事件*/
function linkEvent(e) {
if (isDrag()) { // 拖动时候不触发跳转
e.preventDefault();
}
}
2019-01-04 11:07:50 +00:00
/**有道词典排版*/
function parseYoudao(rst) {
var html = '';
2019-01-04 11:07:50 +00:00
try {
2019-01-23 10:40:19 +00:00
var rstJson = iframeWin.JSON.parse(rst),
2019-01-07 10:59:21 +00:00
phoneStyle = 'color:#777;';
2019-01-04 11:07:50 +00:00
if (rstJson.ec) {
var word = rstJson.ec.word[0],
tr = '';
var trs = word.trs,
ukphone = word.ukphone,
usphone = word.usphone,
2019-01-08 10:15:14 +00:00
phone = word.phone,
returnPhrase = word['return-phrase'];
if (returnPhrase && returnPhrase.l && returnPhrase.l.i) {
html += '<div>' + returnPhrase.l.i + '</div>';
}
html += '<div>';
2019-01-04 11:07:50 +00:00
if (ukphone && ukphone.length != 0) {
2019-02-21 04:21:09 +00:00
html += '<span class="pron" style="' + phoneStyle + '">英 [' + ukphone + '] </span>';
2019-01-04 11:07:50 +00:00
}
if (usphone && usphone.length != 0) {
2019-02-21 04:21:09 +00:00
html += '<span class="pron" style="' + phoneStyle + '">美 [' + usphone + '] </span>';
2019-01-04 11:07:50 +00:00
}
2019-01-08 10:15:14 +00:00
html += '</div>';
if (phone && phone.length != 0) {
2019-02-21 04:21:09 +00:00
html += '<div class="pron" style="' + phoneStyle + '">[' + phone + '] </div>';
2019-01-04 11:07:50 +00:00
}
trs.forEach(element => {
2019-01-08 10:15:14 +00:00
tr += '<div>' + element.tr[0].l.i[0] + '</div>';
2019-01-04 11:07:50 +00:00
});
html += tr;
}
2019-01-04 14:16:33 +00:00
// 中英翻译
if (rstJson.ce_new && rstJson.ce_new.word) {
html += '<div>' +
'《新汉英大辞典》<br>' + xmlToHtml(objToXml(rstJson.ce_new.word), 'div') +
'</div>';
}
// 中文翻译
if (rstJson.hh && rstJson.hh.word) {
html += '<div>' +
'《现代汉语大词典》<br>' + xmlToHtml(objToXml(rstJson.hh.word), 'span') +
'</div>';
2019-01-04 14:16:33 +00:00
}
// 长句翻译
2019-01-04 11:07:50 +00:00
if (rstJson.fanyi && rstJson.fanyi.tran) {
html += rstJson.fanyi.tran;
}
} catch (error) {
log(error);
html += error;
2019-01-04 11:07:50 +00:00
}
var dom = document.createElement('div');
dom.setAttribute('class', ids.YOUDAO);
dom.innerHTML = html;
return dom;
2019-01-04 11:07:50 +00:00
}
/**金山词霸排版*/
function parseIciba(rst) {
2019-02-21 04:21:09 +00:00
var dom = document.createElement('div');
dom.setAttribute('class', ids.ICIBA);
2019-01-07 10:59:21 +00:00
try {
2019-02-21 04:21:09 +00:00
rst = cleanHtml(rst)
.replace(/(?:a>)/ig, 'span>')
.replace(/(?:<a)/ig, '<span')
.replace(/style=".*?"/ig, '')
2019-02-21 13:53:56 +00:00
.replace(/<span class="prop">释义<\/span>/ig, '<span class="prop">释义:<\/span>')
2019-02-21 04:21:09 +00:00
.replace(/<h1 class="base-word abbr chinese change-base">变形<\/h1>/ig, '');
var doc = htmlToDom(rst);
// 发音
doc.querySelectorAll('[ms-on-mouseover]').forEach(function (ele) {
var str = ele.getAttribute('ms-on-mouseover');
var regex = /'(http:\/\/.*?)'/ig;
var match = regex.exec(str);
if (match && match.length >= 1) {
ele.appendChild(getPlayButton({
name: '♫',
url: match[1]
}));
}
});
// 内容
doc.querySelectorAll('.in-base .in-base-top,.in-base .base-list,.in-base .change').forEach(function (ele) {
dom.appendChild(ele);
});
} catch (error) {
log(error);
2019-02-21 04:21:09 +00:00
dom.appendChild(htmlToDom(error));
}
return dom;
}
/**沪江小D排版*/
function parseHjenglish(rst) {
var dom = document.createElement('div');
dom.setAttribute('class', ids.HJENGLISH);
try {
var doc = htmlToDom(cleanHtml(rst));
2019-02-15 05:38:48 +00:00
var label = doc.querySelector('.word-details-item-content header');
var entry = doc.querySelector('.word-text h2');
var collins = doc.querySelector('div[data-id="detail"] .word-details-item-content .detail-groups');
if (entry) {
var entryDom = document.createElement('div');
entryDom.setAttribute('class', 'entry');
entryDom.innerHTML = entry.innerHTML;
dom.appendChild(entryDom);
if (collins) {
2019-02-15 05:38:48 +00:00
if (label) {
var regex = /(《.*?》)/ig;
var match = regex.exec(label.innerHTML);
if (match && match[1]) {
dom.appendChild(htmlToDom('<div>' + match[1] + '</div>'));
}
}
dom.appendChild(collins);
}
}
} catch (error) {
log(error);
dom.appendChild(htmlToDom(error));
}
return dom;
}
/**必应词典排版*/
function parseBing(rst) {
var html = '';
try {
2019-02-21 04:21:09 +00:00
rst = rst.replace(/onmouseover/ig, 'data-sound'); // 发音链接预处理
rst = cleanHtml(rst)
.replace(/(?:a>)/ig, 'span>')
.replace(/(?:<a)/ig, '<span');
var doc = htmlToDom(rst);
doc.querySelectorAll('.hw_ti').forEach(function (ele) { // 牛津词头(不准)
ele.remove();
});
var entry = doc.querySelector('.qdef .hd_area');
var concise = doc.querySelector('.qdef ul');
var tense = doc.querySelector('.qdef .hd_div1');
var oald = doc.querySelector('#authid');
if (entry) {
html += '<div class="entry">' + entry.innerHTML + '</div>';
if (concise) {
html += '<div class="concise">' + concise.outerHTML + '</div>';
}
if (tense) {
html += '<div class="tense">' + tense.outerHTML + '</div>';
}
if (oald) {
html += '<div class="oald">《牛津高阶英汉双解词典第八版》<br>' + oald.outerHTML + '</div>';
}
}
// 计算机翻译
var machineTrans = doc.querySelector('.smt_hw');
if (machineTrans && machineTrans.innerHTML.indexOf('计算机翻译') != -1) {
var parent = machineTrans.parentNode;
var zhText = parent.querySelector('.p1-11');
if (zhText) {
html += '<div class="machine-trans">' + zhText.outerHTML + '</div>';;
}
}
2019-01-07 10:59:21 +00:00
} catch (error) {
log(error);
html += error;
2019-01-07 10:59:21 +00:00
}
var dom = document.createElement('div');
dom.setAttribute('class', ids.BING);
dom.innerHTML = html;
// 发音
dom.querySelectorAll('[data-sound]').forEach(function (ele) {
var str = ele.getAttribute('data-sound');
var regex = /'(https:\/\/.*?)'/ig;
var match = regex.exec(str);
if (match && match.length >= 1) {
ele.appendChild(getPlayButton({
name: '♫',
url: match[1]
}));
}
});
return dom;
2019-01-07 10:59:21 +00:00
}
/**谷歌翻译排版*/
function parseGoogle(rst) {
var dom = document.createElement('div');
dom.setAttribute('class', ids.GOOGLE);
2019-01-07 10:59:21 +00:00
try {
dom.appendChild(htmlToDom(xmlToHtml(objToXml(iframeWin.JSON.parse(rst)), 'span')));
} catch (error) {
log(error);
dom.appendChild(htmlToDom(error));
}
return dom;
}
/**剑桥高阶排版*/
function parseCambridge(rst) {
var dom = document.createElement('div');
dom.setAttribute('class', ids.CAMBRIDGE);
try {
rst = cleanHtml(rst).replace(/(?:a>)/ig, 'span>')
.replace(/(?:<a)/ig, '<span');
var doc = htmlToDom(rst);
// 发音
doc.querySelectorAll('.audio_play_button').forEach(function (ele) {
ele.appendChild(getPlayButton({
name: '♫',
url: 'https://dictionary.cambridge.org/' + ele.getAttribute('data-src-mp3')
}));
});
// 内容
doc.querySelectorAll('.entry').forEach(function (ele) {
dom.appendChild(ele);
});
2019-01-07 10:59:21 +00:00
} catch (error) {
log(error);
dom.appendChild(htmlToDom(error));
2019-01-07 10:59:21 +00:00
}
return dom;
2019-01-04 11:07:50 +00:00
}
/**
* 谷歌翻译 token 计算
* https://github.com/hujingshuang/MTrans
* */
function token(a) {
var k = "";
var b = 406644;
var b1 = 3293161072;
var jd = ".";
var sb = "+-a^+6";
var Zb = "+-3^+b+-f";
for (var e = [], f = 0, g = 0; g < a.length; g++) {
var m = a.charCodeAt(g);
128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023), e[f++] = m >> 18 | 240, e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224, e[f++] = m >> 6 & 63 | 128), e[f++] = m & 63 | 128)
}
a = b;
for (f = 0; f < e.length; f++) a += e[f],
a = RL(a, sb);
a = RL(a, Zb);
a ^= b1 || 0;
0 > a && (a = (a & 2147483647) + 2147483648);
a %= 1E6;
return a.toString() + jd + (a ^ b)
};
function RL(a, b) {
var t = "a";
var Yb = "+";
for (var c = 0; c < b.length - 2; c += 3) {
var d = b.charAt(c + 2),
d = d >= t ? d.charCodeAt(0) - 87 : Number(d),
d = b.charAt(c + 1) == Yb ? a >>> d : a << d;
a = b.charAt(c) == Yb ? a + d & 4294967295 : a ^ d
}
return a
}
2019-01-04 11:07:50 +00:00
})();