微软翻译组件

微软翻译组件 右下角点击翻译

目前為 2017-07-25 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name 微软翻译组件
  3. // @description 微软翻译组件 右下角点击翻译
  4. // @include *
  5. // @exclude *.jpg
  6. // @exclude *.png
  7. // @exclude *.jpeg
  8. // @exclude *.gif
  9. // @exclude *.pdf
  10. // @exclude *115.com/*
  11. // @require https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.1.3/js.cookie.min.js
  12. // @grant GM_registerMenuCommand
  13. // @grant GM_getValue
  14. // @grant GM_setValue
  15. // @grant GM_getResourceText
  16. // @resource httpJs http://www.microsofttranslator.com/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=False&ui=false&settings=Manual&from=
  17. // @resource httpsJs https://ssl.microsofttranslator.com/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=False&ui=false&settings=Manual&from=
  18. // @author aogg
  19. // @version 2.3.12
  20. // @namespace https://gf.qytechs.cn/users/25818
  21. // ==/UserScript==
  22.  
  23.  
  24. (function (){
  25.  
  26. var width = '79',
  27. height = '23';
  28. var divId = 'MicrosoftTranslatorWidget',
  29. divMenu = null, // 菜单div
  30. divOne = null, // 一键翻译div
  31. selectNode = null, // 选择框
  32. divNode = null, // 主div
  33. translatorSwitch = function (){}, // 执行翻译函数
  34. localStorageLocalsKey = divId + 'localStorageLocals',
  35. localStorageAppCloseKey = divId + 'localStorageClose',
  36. localStorageAppOneKey = divId + 'localStorageOne',
  37. appOneFunc = { // 一键翻译处理函数
  38. get: function (){
  39. return GM_getValue(localStorageAppOneKey);
  40. },
  41. set: function (val){
  42. GM_setValue(localStorageAppOneKey, val);
  43. if (divOne){ // 修改文案
  44. divOne.innerText = divOne.oneTitleFunc();
  45. }
  46. }
  47. };
  48. GM_registerMenuCommand('切换微软一键翻译', function (){
  49. if (divOne){
  50. if (divNode){
  51. divNode.changeMenu('show'); // 显示菜单
  52. setTimeout(function (){
  53. divNode.changeMenu('hide');
  54. }, 500); // 关闭菜单
  55. }
  56. divOne.click();
  57. }
  58. });
  59. if (
  60. parent !== parent.parent || document.documentElement.clientWidth <= width * 2 || document.documentElement.clientHeight <= height * 2 || // iframe过多,或者屏幕过小
  61. (document.body.childElementCount === 1 && document.body.firstElementChild.nodeName === 'SCRIPT') || // 只有一个script就不显示
  62. checkVideoFull() || // 检测视屏是否占满屏
  63. localStorage.getItem(localStorageAppCloseKey)
  64. ){
  65. // 控制层次,避免无限调用,如:http://www.w3school.com.cn/html/html_entities.asp
  66. // 控制宽高小的不显示
  67. return;
  68. }
  69.  
  70.  
  71. // 重置cookie
  72. try{
  73. Cookies.remove('mstto');
  74. console.log('remove cookie mstto');
  75. }catch(e){
  76. console.log(e);
  77. }
  78.  
  79. var locals = ''; // zh-chs
  80. var source = null;
  81. var mainStatus = false; // 是否执行了main方法
  82.  
  83. /**
  84. var noTranslator = ['wangpan'];
  85. if (self.frameElement && noTranslator.indexOf(self.frameElement.name) !== -1){
  86. return;
  87. }
  88. */
  89. /*
  90. var scriptNode = document.createElement('script');
  91. 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);";
  92. document.body.appendChild(scriptNode);
  93. */
  94. var code = location && location.href && location.href.indexOf('https') == 0?GM_getResourceText('httpsJs'):GM_getResourceText('httpJs');
  95. try{
  96. unsafeWindow.eval(code);
  97. }catch(e){
  98. console.log('无法执行eval,如github的CSP策略');
  99. return;
  100. }
  101. divNode = document.createElement('div');
  102.  
  103. divNode.id = divId;
  104. divNode.style.color = 'white';
  105. divNode.style.backgroundColor = '#555555';
  106. divNode.style.position = 'fixed';
  107. divNode.style.right = '0';
  108. divNode.style.bottom = '1px';
  109. divNode.style.zIndex = '9999999';
  110. divNode.style.fontSize = '13px';
  111. divNode.title = '翻译为,或双击隐藏';
  112. divNode.style.width= width + 'px';
  113. divNode.ondblclick = function(){ // 双击隐藏
  114. translatorHide();
  115. };
  116. divNode.changeMenu = function (action){
  117. var showArr = {'none':'block', 'block':'none'};
  118. if (divMenu){
  119. if (action === 'show'){ // 显示
  120. divMenu.style.display = 'block';
  121. }else if (action === 'hide'){ // 隐藏
  122. divMenu.style.display = 'none';
  123. }else {
  124. divMenu.style.display = showArr[divMenu.style.display] ? showArr[divMenu.style.display] : 'none';
  125. }
  126. }
  127. };
  128. divNode.oncontextmenu = function (event){ // 设置菜单
  129. event.preventDefault();
  130. this.changeMenu();
  131. }
  132.  
  133. divMenu = menu(divNode);
  134. document.body.appendChild(divNode);
  135.  
  136.  
  137. document.onreadystatechange = main;
  138. setTimeout(main, 500); // 最少500ms内显示
  139. // 隐藏全部
  140. var translatorHide = (function(div){
  141. return function (){
  142. div.style.display = 'none';
  143. }
  144. })(divNode)
  145.  
  146.  
  147.  
  148. function main(){
  149. if (mainStatus || document.readyState !== 'complete'){
  150. return;
  151. }
  152. mainStatus = true;
  153.  
  154. // 多语言翻译
  155. var selectHtml = document.createElement('select'),
  156. selected = appOneFunc.get() || '',
  157. status = false, // 翻译状态,false为未翻译
  158. translateFunc = function (locals, setNodeNot){
  159. // var option = selectHtml.selectedOptions;
  160. source = selectHtml.getAttribute('data-source') || null;
  161. setLocals(locals, setNodeNot);
  162. translateStart();
  163. };
  164. selectHtml.style.backgroundColor = 'rgb(178, 178, 178)';
  165. selectHtml.ondblclick = function(){ // 双击隐藏
  166. this.parentNode.style.display = 'none';
  167. };
  168. selectHtml.style.margin = 0;
  169. selectHtml.style.padding = 0;
  170. selectHtml.style.fontSize = '13.3px';
  171. selectHtml.style.width= width + 'px';
  172. selectHtml.style.height= height + 'px';
  173. selectHtml.onclick = (function (){
  174. return function (event){ // 一键翻译
  175. var selected = appOneFunc.get(); // 每次重新获取
  176. if (selected){ // 需要一键翻译
  177. if (!status){ // 翻译
  178. event.preventDefault();
  179. translateFunc(selected)
  180. }else{ // 关闭
  181. closeTranslator();
  182. }
  183. status = !status;
  184. }
  185. }
  186. })();
  187. // Microsoft.Translator.Widget.GetLanguagesForTranslateLocalized()获取所有支持的翻译选项
  188. selectHtml.innerHTML = "\
  189. <option id='MicrosoftTranslatorWidget-option-select' value=''>翻译为</option>\
  190. <option value='zh-chs'>简体中文</option>\
  191. <option value='zh-cht'>繁体中文</option>\
  192. <option value='yue'>粤语</option>\
  193. <option value='ja'>日文</option>\
  194. <option id='MicrosoftTranslatorWidget-option-en' value='en'>英文</option>\
  195. ";
  196. if (selected){ // 修改默认值
  197. for (var i in selectHtml.options){
  198. if (selectHtml.options[i] && selectHtml.options[i].value == selected){
  199. selectHtml.options[i].selected = true;
  200. }
  201. }
  202. // selectHtml.value = selected; 此方法无效
  203. }
  204. selectHtml.onchange = function (){
  205. if (!this.value){ // 选择翻译为时,关闭翻译
  206. closeTranslator();
  207. }
  208. status = !!this.value;
  209. translateFunc(this.value, true);
  210. };
  211. var parentDiv = document.body.children.namedItem(divId);
  212. // parentDiv.style.display = 'block';
  213. parentDiv.appendChild(selectHtml);
  214. selectNode = selectHtml; // 放置到外部变量
  215.  
  216. translateStart();
  217.  
  218. }
  219.  
  220.  
  221. function translateStart(){
  222. if (mainStatus && locals && unsafeWindow['Microsoft']){
  223. // null, 'es', onProgress, onError, onComplete, onRestoreOriginal, 2000
  224. Microsoft.Translator.Widget.Translate(source, locals, null, null, onComplete);
  225. }
  226. }
  227.  
  228. function onComplete(){
  229. var option = selectNode.options;
  230. option.namedItem('MicrosoftTranslatorWidget-option-en').innerText = '英文';
  231. option.namedItem('MicrosoftTranslatorWidget-option-select').innerText = '翻译为';
  232.  
  233. }
  234.  
  235.  
  236. function addGlobalStyle(css) {
  237. var head, style;
  238. head = document.getElementsByTagName('head')[0];
  239. if (!head) { return; }
  240. style = document.createElement('style');
  241. style.type = 'text/css';
  242. style.innerHTML = css;
  243. head.appendChild(style);
  244. }
  245.  
  246.  
  247. console.log('完成');
  248. // 右击层
  249. function menu(parentDiv){
  250. var div = document.createElement('div');
  251. div.id= divId + "-menu";
  252. div.style.display = 'none';
  253. div.oncontextmenu = function (event){
  254. event.preventDefault();
  255. this.style.display = 'none';
  256. }
  257. // 当前网站永久隐藏
  258. var divHide = document.createElement('div');
  259. divHide.innerText = '当前网站隐藏';
  260. divHide.height = '20px';
  261. divHide.onclick = function (){
  262. if(window.confirm('确定要当前网站隐藏?')){
  263. localStorage.setItem(localStorageAppCloseKey, 1);
  264. translatorHide();
  265. }
  266. }
  267. div.appendChild(divHide);
  268. // 切换为一键翻译样式
  269. divOne = document.createElement('div');
  270. divOne.oneTitleFunc = function (){
  271. return (appOneFunc.get()?'取消':'') + '一键翻译'
  272. };
  273. divOne.innerText = divOne.oneTitleFunc();
  274. divOne.height = '20px';
  275. divOne.onclick = function (){
  276. var localValue = appOneFunc.get(),
  277. val = localValue ? '' : (locals || 'zh-chs');
  278. appOneFunc.set(val);
  279. }
  280. div.appendChild(divOne);
  281. parentDiv.appendChild(div);
  282. return div;
  283. }
  284. function setLocals(value, nodeNot){
  285. locals = value;
  286. localStorage.setItem(localStorageLocalsKey, value);
  287. !nodeNot && (selectNode.value = value);
  288. }
  289. function closeTranslator(){
  290. unsafeWindow['Microsoft'] && Microsoft.Translator && Microsoft.Translator.FloaterOnClose();
  291. if (divOne){ // 恢复文案
  292. divOne.innerText = divOne.oneTitleFunc();
  293. }
  294. }
  295. function checkVideoFull(){ // 检测视频是否占满屏
  296. var ele = document.getElementsByTagName('object').item(0) || document.getElementsByTagName('embed').item(0);
  297. if (ele){
  298. return ele.clientHeight == document.body.clientHeight && ele.clientWidth == document.body.clientWidth;
  299. }
  300. return false;
  301. }
  302. })()

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址