// ==UserScript==
// @name 微软翻译组件
// @description 微软翻译组件 右下角点击翻译
// @include *
// @exclude *.jpg
// @exclude *.png
// @exclude *.jpeg
// @exclude *.gif
// @exclude *.pdf
// @exclude *115.com/*
// @require https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.1.3/js.cookie.min.js
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_getResourceText
// @grant GM_xmlhttpRequest
// @resource httpJs http://www.microsofttranslator.com/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=False&ui=false&settings=Manual&from=
// @resource httpsJs https://ssl.microsofttranslator.com/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=False&ui=false&settings=Manual&from=
// @author aogg
// @version 2.3.16
// @namespace https://gf.qytechs.cn/users/25818
// ==/UserScript==
(function (){
var width = '79',
height = '23';
var divId = 'MicrosoftTranslatorWidget',
divMenu = null, // 菜单div
divOne = null, // 一键翻译div
selectNode = null, // 选择框
divNode = null, // 主div
translatorSwitch = function (){}, // 执行翻译函数
localStorageLocalsKey = divId + 'localStorageLocals',
localStorageAppCloseKey = divId + 'localStorageClose',
localStorageAppOneKey = divId + 'localStorageOne',
appOneFunc = { // 一键翻译处理函数
get: function (){
return GM_getValue(localStorageAppOneKey);
},
set: function (val){
GM_setValue(localStorageAppOneKey, val);
if (divOne){ // 修改文案
divOne.innerText = divOne.oneTitleFunc();
}
}
};
GM_registerMenuCommand('切换微软一键翻译', function (){
if (divOne){
if (divNode){
divNode.changeMenu('show'); // 显示菜单
setTimeout(function (){
divNode.changeMenu('hide');
}, 500); // 关闭菜单
}
divOne.click();
}
});
if (
parent !== parent.parent || document.documentElement.clientWidth <= width * 2 || document.documentElement.clientHeight <= height * 2 || // iframe过多,或者屏幕过小
(document.body.childElementCount === 1 && document.body.firstElementChild.nodeName === 'SCRIPT') || // 只有一个script就不显示
checkVideoFull() || // 检测视屏是否占满屏
localStorage.getItem(localStorageAppCloseKey)
){
// 控制层次,避免无限调用,如:http://www.w3school.com.cn/html/html_entities.asp
// 控制宽高小的不显示
return;
}
// 重置cookie
try{
Cookies.remove('mstto');
console.log('remove cookie mstto');
}catch(e){
console.log(e);
}
var locals = ''; // zh-chs
var source = null;
var mainStatus = false; // 是否执行了main方法
/**
var noTranslator = ['wangpan'];
if (self.frameElement && noTranslator.indexOf(self.frameElement.name) !== -1){
return;
}
*/
/*
var scriptNode = document.createElement('script');
scriptNode.innerHTML = "setTimeout(function(){{var s=document.createElement('script');s.type='text/javascript';s.charset='UTF-8';s.src=((location && location.href && location.href.indexOf('https') == 0)?'https://ssl.microsofttranslator.com':'http://www.microsofttranslator.com')+'/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=False&ui=false&settings=Manual&from=';var p=document.head[0]||document.documentElement;p.insertBefore(s,p.firstChild); }},0);";
document.body.appendChild(scriptNode);
*/
/*
// 有缓存
var code = location && location.href && location.href.indexOf('https') == 0?GM_getResourceText('httpsJs'):GM_getResourceText('httpJs');
try{
unsafeWindow.eval(code);
}catch(e){
console.log('无法执行eval,如github的CSP策略');
return;
}
*/
(function (){
var url =((location && location.href && location.href.indexOf('https') == 0)?'https://ssl.microsofttranslator.com':'http://www.microsofttranslator.com')+
'/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=False&ui=false&settings=Manual&from=';
try{
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: function(response) {
unsafeWindow.eval(response.responseText);
}
});
}catch(e){
console.log('无法执行eval,如github的CSP策略');
return;
}
})()
divNode = document.createElement('div');
divNode.id = divId;
divNode.style.color = 'white';
divNode.style.backgroundColor = '#555555';
divNode.style.position = 'fixed';
divNode.style.right = '0';
divNode.style.bottom = '1px';
divNode.style.zIndex = '9999999';
divNode.style.fontSize = '13px';
divNode.title = '翻译为,或双击隐藏';
divNode.style.width= width + 'px';
divNode.ondblclick = function(){ // 双击隐藏
translatorHide();
};
divNode.changeMenu = function (action){
var showArr = {'none':'block', 'block':'none'};
if (divMenu){
if (action === 'show'){ // 显示
divMenu.style.display = 'block';
}else if (action === 'hide'){ // 隐藏
divMenu.style.display = 'none';
}else {
divMenu.style.display = showArr[divMenu.style.display] ? showArr[divMenu.style.display] : 'none';
}
}
};
divNode.oncontextmenu = function (event){ // 设置菜单
event.preventDefault();
this.changeMenu();
}
divMenu = menu(divNode);
document.body.appendChild(divNode);
document.onreadystatechange = main;
setTimeout(main, 500); // 最少500ms内显示
// 隐藏全部
var translatorHide = (function(div){
return function (){
div.style.display = 'none';
}
})(divNode)
function main(){
if (mainStatus || (document.readyState !== 'complete' && document.readyState !== 'interactive')){
return;
}
mainStatus = true;
// 多语言翻译
var selectHtml = document.createElement('select'),
selected = appOneFunc.get() || '',
status = false, // 翻译状态,false为未翻译
translateFunc = function (locals, setNodeNot){
// var option = selectHtml.selectedOptions;
source = selectHtml.getAttribute('data-source') || null;
setLocals(locals, setNodeNot);
translateStart();
};
selectHtml.style.backgroundColor = 'rgb(178, 178, 178)';
selectHtml.ondblclick = function(){ // 双击隐藏
this.parentNode.style.display = 'none';
};
selectHtml.style.margin = 0;
selectHtml.style.padding = 0;
selectHtml.style.fontSize = '13.3px';
selectHtml.style.width= width + 'px';
selectHtml.style.height= height + 'px';
selectHtml.onclick = (function (){
return function (event){ // 一键翻译
var selected = appOneFunc.get(); // 每次重新获取
if (selected){ // 需要一键翻译
if (!status){ // 翻译
event.preventDefault();
translateFunc(selected)
}else{ // 关闭
closeTranslator();
}
status = !status;
}
}
})();
// Microsoft.Translator.Widget.GetLanguagesForTranslateLocalized()获取所有支持的翻译选项
selectHtml.innerHTML = "\
<option id='MicrosoftTranslatorWidget-option-select' value=''>翻译为</option>\
<option value='zh-chs'>简体中文</option>\
<option value='zh-cht'>繁体中文</option>\
<option value='yue'>粤语</option>\
<option value='ja'>日文</option>\
<option id='MicrosoftTranslatorWidget-option-en' value='en'>英文</option>\
";
if (selected){ // 修改默认值
for (var i in selectHtml.options){
if (selectHtml.options[i] && selectHtml.options[i].value == selected){
selectHtml.options[i].selected = true;
}
}
// selectHtml.value = selected; 此方法无效
}
selectHtml.onchange = function (){
if (!this.value){ // 选择翻译为时,关闭翻译
closeTranslator();
}
status = !!this.value;
translateFunc(this.value, true);
};
var parentDiv = document.body.children.namedItem(divId);
// parentDiv.style.display = 'block';
parentDiv.appendChild(selectHtml);
selectNode = selectHtml; // 放置到外部变量
translateStart();
}
function translateStart(){
if (mainStatus && locals && unsafeWindow['Microsoft']){
// null, 'es', onProgress, onError, onComplete, onRestoreOriginal, 2000
Microsoft.Translator.Widget.Translate(source, locals, null, null, onComplete);
}
}
function onComplete(){
var option = selectNode.options;
option.namedItem('MicrosoftTranslatorWidget-option-en').innerText = '英文';
option.namedItem('MicrosoftTranslatorWidget-option-select').innerText = '翻译为';
}
function addGlobalStyle(css) {
var head, style;
head = document.getElementsByTagName('head')[0];
if (!head) { return; }
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
}
console.log('完成');
// 右击层
function menu(parentDiv){
var div = document.createElement('div');
div.id= divId + "-menu";
div.style.display = 'none';
div.oncontextmenu = function (event){
event.preventDefault();
this.style.display = 'none';
}
// 当前网站永久隐藏
var divHide = document.createElement('div');
divHide.innerText = '当前网站隐藏';
divHide.height = '20px';
divHide.onclick = function (){
if(window.confirm('确定要当前网站隐藏?')){
localStorage.setItem(localStorageAppCloseKey, 1);
translatorHide();
}
}
div.appendChild(divHide);
// 切换为一键翻译样式
divOne = document.createElement('div');
divOne.oneTitleFunc = function (){
return (appOneFunc.get()?'取消':'') + '一键翻译'
};
divOne.innerText = divOne.oneTitleFunc();
divOne.height = '20px';
divOne.onclick = function (){
var localValue = appOneFunc.get(),
val = localValue ? '' : (locals || 'zh-chs');
appOneFunc.set(val);
}
div.appendChild(divOne);
parentDiv.appendChild(div);
return div;
}
function setLocals(value, nodeNot){
locals = value;
localStorage.setItem(localStorageLocalsKey, value);
!nodeNot && (selectNode.value = value);
}
function closeTranslator(){
unsafeWindow['Microsoft'] && Microsoft.Translator && Microsoft.Translator.FloaterOnClose();
if (divOne){ // 恢复文案
divOne.innerText = divOne.oneTitleFunc();
}
}
function checkVideoFull(){ // 检测视频是否占满屏
var ele = document.getElementsByTagName('object') || document.getElementsByTagName('embed');
if (ele.length){
for (var i = 0; i < ele.length; ++i){
if (ele.item(i).clientHeight == document.documentElement.clientHeight && ele.item(i).clientWidth == document.documentElement.clientWidth) {
return true
}
}
}
return false;
}
})()