Google Translator Tooltip Expanded Fork

Translates the selected text into a tooltip automatically. Fork from https://gf.qytechs.cn/scripts/5727/

  1. // ==UserScript==
  2. // @name Google Translator Tooltip Expanded Fork
  3. // @description Translates the selected text into a tooltip automatically. Fork from https://gf.qytechs.cn/scripts/5727/
  4. // @namespace https://gf.qytechs.cn/scripts/16204/
  5. // @homepage https://gf.qytechs.cn/scripts/16204/
  6. // @version 1.29
  7. // @icon http://translate.google.com/favicon.ico
  8. // @include http*
  9. // @include https*
  10. // @include chrome*
  11. // @grant GM_getValue
  12. // @grant GM_xmlhttpRequest
  13. // @grant GM_log
  14. // @grant GM_deleteValue
  15. // @grant GM_addStyle
  16. // @grant GM_openInTab
  17. // @grant GM_registerMenuCommand
  18. // @grant GM_setValue
  19. // ==/UserScript==
  20.  
  21. var UA = navigator.userAgent;
  22. var googleDomain = "translate.google.com";
  23. var dictURL= "https://" + googleDomain + "/translate_a/single?client=t";
  24. var ttsURL= "http://" + googleDomain + "/translate_tts?client=t";
  25.  
  26. const HREF_NO = 'javascript:void(0)';
  27. initCrossBrowserSupportForGmFunctions();
  28. var languagesGoogle = '<option value="auto">Detect language</option><option value="af">Afrikaans</option><option value="sq">Albanian</option><option value="ar">Arabic</option><option value="hy">Armenian</option><option value="az">Aerbaijani</option><option value="eu">Basque</option><option value="be">Belarusian</option><option value="bn">Bengali</option><option value="bg">Bulgarian</option><option value="ca">Catalan</option><option value="zh-CN">Chinese (simplified)</option><option value="zh-TW">Chinese (traditional)</option><option value="hr">Croatian</option><option value="cs">Czech</option><option value="da">Danish</option><option value="nl">Dutch</option><option value="en">English</option><option value="et">Estonian</option><option value="tl">Filipino</option><option value="fi">Finnish</option><option value="fr">French</option><option value="gl">Galician</option><option value="ka">Georgian</option><option value="de">German</option><option value="el">Greek</option><option value="ht">Haitian Creole</option><option value="iw">Hebrew</option><option value="hi">Hindi</option><option value="hu">Hungarian</option><option value="is">Icelandic</option><option value="id">Indonesian</option><option value="ga">Irish</option><option value="it">Italian</option><option value="ja">Japanese</option><option value="ko">Korean</option><option value="lv">Latvian</option><option value="lt">Lithuanian</option><option value="mk">Macedonian</option><option value="ms">Malay</option><option value="mt">Maltese</option><option value="no">Norwegian</option><option value="fa">Persian</option><option value="pl">Polish</option><option value="pt">Portuguese</option><option value="ro">Romanian</option><option value="ru">Russian</option><option value="sr">Serbian</option><option value="sk">Slovak</option><option value="sl">Slovenian</option><option value="es">Spanish</option><option value="sw">Swahili</option><option value="sv">Swedish</option><option value="th">Thai</option><option value="tr">Turkish</option><option value="uk">Ukrainian</option><option value="ur">Urdu</option><option value="vi">Vietnamese</option><option value="cy">Welsh</option><option value="yi">Yiddish</option>';
  29. var body = getTag('body')[0];
  30. var imgLookup;
  31. var txtSel = encodeURIComponent(txtSel); // text selected
  32. var translation2Element = document.createElement('span');
  33. var translation3Element = document.createElement('span');
  34. var currentURL;
  35. var context;
  36. var initialized = false;
  37. images();
  38. css();
  39. document.addEventListener('mouseup', showLookupIcon, false);
  40. document.addEventListener('mousedown', mousedownCleaning, false);
  41. function mousedownCleaning(evt) {
  42. var divDic = getId('divDic');
  43. var divLookup = getId('divLookup');
  44. if (divDic) {
  45. if (!clickedInsideID(evt.target, 'divDic'))
  46. divDic.parentNode.removeChild(divDic);
  47. }
  48. if (divLookup)
  49. divLookup.parentNode.removeChild(divLookup);
  50. }
  51. function showLookupIcon(evt) {
  52. if (evt.ctrlKey && evt.altKey && (!GM_getValue('ctrl') || !GM_getValue('alt')))
  53. return;
  54. // XOR http://www.howtocreate.co.uk/xor.html
  55. if (evt.ctrlKey ? !GM_getValue('ctrl') : GM_getValue('ctrl'))
  56. return;
  57. if (evt.altKey ? !GM_getValue('alt') : GM_getValue('alt'))
  58. return;
  59. if (!initialized) {
  60. images();
  61. css();
  62. initialized = true;
  63. }
  64. var divDic = getId('divDic');
  65. var divLookup = getId('divLookup');
  66. txtSel = getSelection();
  67. // Exit if no text is selected
  68. if (!txtSel || txtSel == "") {
  69. if (divDic) {
  70. if (!clickedInsideID(evt.target, 'divDic'))
  71. divDic.parentNode.removeChild(divDic);
  72. }
  73. if (divLookup)
  74. divLookup.parentNode.removeChild(divLookup);
  75. return;
  76. }
  77. // Possible cleanup
  78. if (divDic) {
  79. if (!clickedInsideID(evt.target, 'divDic'))
  80. divDic.parentNode.removeChild(divDic);
  81. return;
  82. }
  83. // Remove div if exists
  84. if (divLookup) {
  85. divLookup.parentNode.removeChild(divLookup);
  86. }
  87. if(context!=null){
  88. context.close();
  89. context = null;
  90. }
  91. if(GM_getValue('tts', false) == true)context = new AudioContext();
  92. // Div container
  93. divLookup = createElement('div', {
  94. id : 'divLookup',
  95. style : 'background-color:transparent; color:#000000; position:absolute; top:' + (evt.clientY + window.pageYOffset + 10) + 'px; left:' + (evt.clientX + window.pageXOffset + 10) + 'px; padding:0px; z-index:10000; border-radius:2px;'
  96. });
  97. divLookup.appendChild(imgLookup.cloneNode(false));
  98. divLookup.addEventListener('mouseover', function(evt){setTimeout(lookup,parseInt(GM_getValue('delay')))}, false);
  99. body.appendChild(divLookup);
  100. }
  101. // Create the tooltip and launch the Google Translate request to get the translation
  102. function lookup(evt) {
  103. var divResult = null;
  104. var divDic = getId('divDic');
  105. var divLookup = getId('divLookup');
  106. var top = divLookup.style.top;
  107. var left = divLookup.style.left;
  108. // No text selected
  109. if (!txtSel || txtSel == "") {
  110. if (divDic = getId('divDic'))
  111. divDic.parentNode.removeChild(divDic);
  112. return;
  113. }
  114. // Cleanup divs
  115. if (divDic = getId('divDic')) {
  116. divDic.parentNode.removeChild(divDic);
  117. }
  118. divLookup.parentNode.removeChild(divLookup);
  119. // Div container
  120. divDic = createElement('div', {
  121. id : 'divDic',
  122. style : 'opacity: 1; font-family: "Open Sans", Arial, Helvetica, sans-serif !important; font-size: ' + GM_getValue('fontsize', 'small') + '; background-color: ' + GM_getValue('backgroundColor', '#EDF4FC') + '; color: ' + GM_getValue('textcolor', 'Gray') + '; position:absolute; top:' + top + '; left:' + left + '; min-width:250px; min-height:50px; max-width:50%; padding:5px; text-align:left; z-index:10000; border-radius:4px; box-shadow: -2px 0px 9px 5px #898D91'
  123. });
  124. divDic.addEventListener('mousedown', dragHandler, false);
  125. body.appendChild(divDic);
  126. // Div result
  127. // This awfull wall of text is the "+" image
  128. divResult = createElement('div', {
  129. id : 'divResult',
  130. style : 'overflow:auto; padding:3px;'
  131. }, null, '<img src="data:image/gif;base64,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' +
  132. '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' +
  133. 'SX8jiuicMMBFd2OmKwQFs2tjXpDfnPE1j30V3c7iRHlrzBD2HONzODyZtsQJMI4r0AUNaE3XNHQw95c9GC001MpIxDacFQ+ulTNTZlU3O1eWVHa6vb/pnQUUrgHHSBKIuwG+bCPyEqbAg25gMVV1iOB/IGh5YOKLKIQ6xBAcUHmzjIcIqgajZ+Ro42DcvXl7j0U4WOUd+2IGu7DWjI1pt4DYq8BPm0entuGSQY/4tBi9Ss0HqfwngBQtHbCH88MQXb/zxyFfRRRHMN+/889BHL/301Fdv/fXYZ39CCAAh+QQJCgAAACwAAAAA3AATAAAF/yAgjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgECAaEpHLJbDqf0Kh0Sq1ar9isdjoQtAQFh2fAKXsKm7R6Q+Y43vABep0mGwwOPH7w2CT+gHZ3d3lyagl+CQNvg4yGh36LcHoGfHR/ZYOElQ9/a4ocmoRygIiRk5p8pYmZjXePaYBujHoOqp5qZHBlHAUFXitddg8PBg8KGsgayxvGkAkFDwgICtPTzX2mftHW3QnOpojG3dbYkNjk1waxsdDS1N7ga9zw1t/aifTk35fu6Qj3numL14fOuHTNECHqU4DDgQEsCCwidiHBAwYQMmpcUOCAhI8gJVzUuLGThAQnP/9abEAyI4MCIVOKZNnyJUqUJxNcGNlywYOQgHZirGkSJ8gHNEky+AkS58qWEJYC/bMzacmbQHkqNdlUJ1KoSz2i9COhmQYCEXtVrCBgwYS3cCf8qTcNQ9u4cFFOq2bPLV65Cf7dxZthbjW+CgbjnWtNgWPFcAsHdoxgWWK/iyV045sAc2S96SDn1exYw17REwpLQEYt2eW/qtPZRQAB7QoC61RW+GsBwYZ/CXb/XRCYLsAKFizEtUAc+G7lcZsjroscOvTmsoUvx15PwccJ0N8yL17N9PG/E7jv9S4hOV7pdIPDdZ+ePDzv2qMXn2b5+wTbKuAWnF3oZbABZY' +
  134. '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' +
  135. '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"/><br/>Loading...');
  136. divDic.appendChild(divResult);
  137. // Options link
  138. var optionLink = createElement('a', {
  139. id : 'optionsLink',
  140. href : HREF_NO,
  141. style : 'opacity:0.2; position:absolute; bottom:3px; right:13px; font-size:18px; text-decoration:none!important;background:#528DDF;padding:1px;color:#fff;border-radius:6px 6px 6px 6px;border:2px solid #EEEEEE;font-weight:bold;width:20px;text-align:center;display:block;'
  142. }, {
  143. type: 'click',
  144. handler: openCloseOptions,
  145. capture: false
  146. }, '+');
  147. divDic.appendChild(optionLink);
  148. optionLink.addEventListener('mouseover', function (e) {
  149. e.target.style.opacity = 1.0
  150. });
  151. optionLink.addEventListener('mouseout', function (e) {
  152. e.target.style.opacity = 0.2
  153. });
  154. // Send the Google Translate request
  155. if ((txtSel + " ").search(/^\s*https?:\/\//) > -1) {
  156. divResult.innerHTML = '<a href="' + txtSel + '" target="_blank" >' + txtSel + '</a>';
  157. } else if ((txtSel + " ").search(/^\s*\S+(\.\S+)+/) > -1) // site.dom
  158. {
  159. divResult.innerHTML = '<a style="color:#888;" href="http://' + txtSel + '" target="_blank" >' + txtSel + '</a>';
  160. } else {
  161. var sl, tl;
  162. sl = GM_getValue('from') ? GM_getValue('from') : "auto";
  163. tl = GM_getValue('to') ? GM_getValue('to') : "auto";
  164. Request(txtSel, sl, tl, extractResult);
  165.  
  166. if (GM_getValue('to2', 'Disabled') != 'Disabled') {
  167. sl = GM_getValue('from') ? GM_getValue('from') : "auto";
  168. tl = GM_getValue('to2') ? GM_getValue('to2') : "auto";
  169. Request(txtSel, sl, tl, extractResult2);
  170. } else {
  171. translation2Element.innerHTML = '';
  172. }
  173.  
  174. if (GM_getValue('to3', 'Disabled') != 'Disabled') {
  175. sl = GM_getValue('from') ? GM_getValue('from') : "auto";
  176. tl = GM_getValue('to3') ? GM_getValue('to3') : "auto";
  177. Request(txtSel, sl, tl, extractResult3);
  178. } else {
  179. translation3Element.innerHTML = '';
  180. }
  181. }
  182. }
  183. // Lanched when we select an other language in the setup menu
  184. function quickLookup() {
  185. getId('divDic').style.fontSize = getId('optFontSize').value;
  186. getId('divDic').style.color = getId('optTextColor').value;
  187. getId('divResult').innerHTML = 'Loading...';
  188. if((context == null) && (GM_getValue('tts', false) == true) ) context = new AudioContext();
  189. var sl,tl;
  190. sl = getId('optSelLangFrom').value;
  191. tl = getId('optSelLangTo').value;
  192. Request(txtSel, sl, tl, extractResult);
  193.  
  194. if (getId('optSelLangTo2').value != 'Disabled') {
  195. var sl,tl;
  196. sl = getId('optSelLangFrom').value;
  197. tl = getId('optSelLangTo2').value;
  198. Request(txtSel, sl, tl, extractResult2);
  199. } else {
  200. translation2Element.innerHTML = '';
  201. }
  202.  
  203. if (getId('optSelLangTo3').value != 'Disabled') {
  204. var sl,tl;
  205. sl = getId('optSelLangFrom').value;
  206. tl = getId('optSelLangTo3').value;
  207. Request(txtSel, sl, tl, extractResult3);
  208. } else {
  209. translation3Element.innerHTML = '';
  210. }
  211. }
  212.  
  213. function init_google_value_tk() {
  214. var url = "https://" + googleDomain + "/translate_a/element.js";
  215. GM_xmlhttpRequest({
  216. method: "GET",
  217. url: url,
  218. onreadystatechange: function(resp) {
  219. if (resp.readyState == 4) {
  220. clearTimeout(setTimeout( function(){ this.abort(); }, 2000));
  221. if (resp.status == 200) {
  222. init_google_value_tk_parse(resp.responseText);
  223. }
  224. }
  225. }
  226. });
  227. }
  228.  
  229. function init_google_value_tk_parse(responseText) {
  230. var res = /c\._ctkk='(.+?)'/i.exec(responseText);
  231. if (res != null) {
  232. GM_setValue('google_value_tk', res[1]);
  233. };
  234. }
  235.  
  236. // return token for the new API
  237. function googleTK(text) {
  238. // view-source:https://translate.google.com/translate/releases/twsfe_w_20160620_RC00/r/js/desktop_module_main.js && TKK from HTML
  239. var uM = GM_getValue('google_value_tk');
  240. if (uM == 'undefined' || uM == null) {
  241. init_google_value_tk();
  242. uM = "427110.1469889687";
  243. } else if (Number(uM.split('.')[0]) !== Math.floor(Date.now() / 3600000)) {
  244. init_google_value_tk();
  245. };
  246. var cb="&";
  247. var k="";
  248. var Gf="=";
  249. var Vb="+-a^+6";
  250. var t="a";
  251. var Yb="+";
  252. var Zb="+-3^+b+-f";
  253. var jd=".";
  254. var sM=function(a){return function(){return a}}
  255. var tM=function(a,b){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};
  256. var vM=function(a){
  257. var b;
  258. if(null!==uM) {
  259. b=uM;
  260. }else{
  261. b=sM(String.fromCharCode(84));var c=sM(String.fromCharCode(75));b=[b(),b()];
  262. b[1]=c();
  263. b=(uM=window[b.join(c())]||k)||k
  264. }
  265. var d=sM(String.fromCharCode(116)),c=sM(String.fromCharCode(107)),d=[d(),d()];
  266. d[1]=c();
  267. c=cb+d.join(k)+Gf;
  268. d=b.split(jd);
  269. b=Number(d[0])||0;
  270.  
  271. for(var e=[],f=0,g=0;g<a.length;g++){
  272. var m=a.charCodeAt(g);
  273. 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)
  274. }
  275. a=b||0;
  276. for(f=0;f<e.length;f++) { a+=e[f],a=tM(a,Vb)};
  277. a=tM(a,Zb);
  278. a^=Number(d[1])||0;
  279. 0>a&&(a=(a&2147483647)+2147483648);
  280. a%=1E6;
  281. return a.toString()+jd+(a^b);
  282. };
  283. return vM(text);
  284. }
  285.  
  286. // Google Translate Request
  287. function Request(txt, sl, tl, parse) {
  288. var tk=googleTK(txt);
  289. var Url = dictURL +
  290. "&hl=auto" +
  291. "&sl=" + sl + "&tl=" + tl +
  292. "&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=at&ie=UTF-8&oe=UTF-8&otf=2&trs=1&inputm=1&ssel=0&tsel=0&source=btn&kc=3"+
  293. "&tk=" + tk +
  294. "&q="+ encodeURI(txt);
  295. var method='POST';
  296. var Data='';
  297. var Hdr= {
  298. "User-Agent": UA,
  299. "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  300. "Accept-Encoding": "gzip, deflate"
  301. }
  302. var Q=Url.split('&q=');
  303. Url=Q[0];
  304. Data='&q='+Q[1];
  305. Hdr["Content-Length"]=Data.length+'';
  306. Hdr["Content-Type"]="application/x-www-form-urlencoded; charset=UTF-8";
  307. GM_xmlhttpRequest({
  308. method: method,
  309. url: Url,
  310. data: Data,
  311. headers: Hdr,
  312. onload: function(resp) {
  313. try{
  314. parse(resp.responseText)
  315. }catch(e){
  316. GM_log(e);
  317. }
  318. }
  319. });
  320. }
  321.  
  322. function extractResult(gTradStringArray) {
  323. var arr = parseTranslationResponse(gTradStringArray);
  324. if (!arr) {
  325. // Handle error case
  326. getId('divResult').innerHTML = 'Translation error occurred';
  327. return;
  328. }
  329. /*
  330. Content of the gTrad array :
  331. 0 / 0:Translation 1:Source text
  332. 1 / i:Grammar / 0:Types (word, verb, ...) 1: Other translations
  333. 5 / Array of other translations
  334. */
  335.  
  336. var translation = '';
  337. // 0 - Full translation
  338. translation += '<small><a style="color:#1a0dab;" target="_blank" href="https://' + googleDomain + '/#' + GM_getValue('from', 'auto') + '/' + GM_getValue('to', 'auto') + '/' + txtSel + '">[' + arr[2] + '] ';
  339. for (var i = 0; i < arr[0].length; i++) { if (typeof arr[0][i][1] != 'undefined' && arr[0][i][1] != null) translation += arr[0][i][1]; }
  340. translation += '</a> <span id="texttospeechbuttonfrom"></span></small><br/>';
  341. translation += '[' + GM_getValue('to', 'auto') + '] ';
  342. for (var i = 0; i < arr[0].length; i++) { if (typeof arr[0][i][0] != 'undefined' && arr[0][i][0] != null) translation += arr[0][i][0]; }
  343. translation += ' <span id="texttospeechbuttonto"></span><br/>';
  344. translation += '<span id="translation2Element"></span>';
  345. translation += '<span id="translation3Element"></span>';
  346. translation += '<a id="toggleShowDetails" style="color:#000;' + (!GM_getValue('details', 'false') ? 'display:none;"' : '"') + '>Show details</a>';
  347. translation += '<span id="divDetails" ' + (GM_getValue('details', 'false') ? 'style="display:none;"' : '') + '><a style="color:#000;" id="toggleHideDetails">Hide details</a><br/>';
  348.  
  349. // 1 - Grammar
  350. if (typeof arr[1] != 'undefined' && arr[1] != null ||
  351. typeof arr[5] != 'undefined' && arr[5] != null ||
  352. typeof arr[14] != 'undefined' && arr[14] != null) {
  353. translation += '<strong>Translations</strong><br/>';
  354. }
  355.  
  356. if (typeof arr[1] != 'undefined' && arr[1] != null) {
  357. for (var i = 0; i < arr[1].length; i++) {
  358. translation += arr[1][i][0] + ': ';
  359. translation += arr[1][i][1].join(', ');
  360. translation += '<br/>';
  361. }
  362. }
  363.  
  364. // 5 - Alternatives
  365. if (GM_getValue('alternatives', 'true')) {
  366. if (typeof arr[5] != 'undefined' && arr[5] != null) {
  367. for (var i = 0; i < arr[5].length; i++) {
  368. if (typeof arr[5][i][2] != 'undefined' && arr[5][i][2] != null) { // 5/i/2 array of alternatives, 5/i/0 the part of the text we are studying
  369. translation += '<i>alternatives: </i>';
  370. for (var j = 0; j < arr[5][i][2].length; j++) {
  371. translation += '<i>' + ((j == 0) ? '' : ', ') + arr[5][i][2][j][0] + '</i>';
  372. }
  373. translation += '<br/>';
  374. }
  375. }
  376. }
  377. }
  378.  
  379. // 14 - See also
  380. if (typeof arr[14] != 'undefined' && arr[14] != null) {
  381. // for (var i = 0; i < arr[14].length; i++) {
  382. translation += '<i>See also: </i>';
  383. translation += '<i>' + arr[14][0].join(', ') + '</i>';
  384. translation += '<br/>';
  385. // }
  386. }
  387.  
  388. // if ((typeof arr[1] != 'undefined' && arr[1] != null ||
  389. // typeof arr[5] != 'undefined' && arr[5] != null ||
  390. // typeof arr[14] != 'undefined' && arr[14] != null) &&
  391. // (typeof arr[12] != 'undefined' && arr[12] != null)) {
  392. // translation += '<br/>';
  393. // }
  394.  
  395. // 12 and 11 - Definitions and Synonyms
  396. if (typeof arr[12] != 'undefined' && arr[12] != null) {
  397. translation += '<strong>Definitions</strong><br/>';
  398. for (var i = 0; i < arr[12].length; i++) {
  399. if (typeof arr[12][i][1] != 'undefined' && arr[12][i][1] != null) { // 11/i/1 array of alternatives, 11/i/0 the part of the text we are studying
  400. for (var j = 0; j < arr[12][i][1].length; j++) {
  401. translation += '' + arr[12][i][0] + ': ';
  402. translation += arr[12][i][1][j][0];
  403. translation += '<br/>';
  404. if (GM_getValue('synonyms', 'true')) {
  405. if (typeof arr[11] != 'undefined' && arr[11] != null) {
  406. if (typeof arr[11][i] != 'undefined' && [11][i] != null) {
  407. for (var k = 0; k < arr[11][i][1].length; k++) {
  408. if (arr[12][i][1][j][1] == arr[11][i][1][k][1]) {
  409. translation += '<i>synonyms:</i> ';
  410. translation += '<i>' + arr[11][i][1][k][0].join(', ') + '</i>';
  411. translation += '<br/>';
  412. break;
  413. }
  414. }
  415. }
  416. }
  417. }
  418. }
  419. }
  420. }
  421. }
  422.  
  423. translation += '</span>'; // Detail end
  424.  
  425. getId('divResult').innerHTML = '<p style="margin:0px;padding:0px;line-height:150%;text-align:left;">' + translation + '</p>';
  426. getId('translation2Element').appendChild(translation2Element); // Optional second translation
  427. getId('translation3Element').appendChild(translation3Element); // Optional third translation
  428. getId('toggleShowDetails').addEventListener('click', function () {
  429. getId('toggleShowDetails').style.display = 'none';
  430. getId('divDetails').style.display = 'block';
  431. }, false);
  432. getId('toggleHideDetails').addEventListener('click', function () {
  433. getId('toggleShowDetails').style.display = 'inline';
  434. getId('divDetails').style.display = 'none';
  435. }, false);
  436. // Create the Text to speech
  437. var fromText = '';
  438. var toText = '';
  439. for (var i = 0; i < arr[0].length; i++) { if (typeof arr[0][i][1] != 'undefined' && arr[0][i][1] != null) fromText += arr[0][i][1]; }
  440. for (var i = 0; i < arr[0].length; i++) { if (typeof arr[0][i][0] != 'undefined' && arr[0][i][0] != null) toText += arr[0][i][0]; }
  441. addTextTospeechLink(getId('texttospeechbuttonfrom'), arr[2], fromText); // arr[2] contains the detected input language
  442. addTextTospeechLink(getId('texttospeechbuttonto'), GM_getValue('to', 'auto') == 'auto' ? 'en' : GM_getValue('to', 'auto'), toText); // I cannot find a way to get the detected destination language, so if the requested destination is 'auto', I use the english Text to speech language
  443. }
  444. function extractResult2(gTradStringArray) {
  445. var arr = parseTranslationResponse(gTradStringArray);
  446. if (!arr) {
  447. // Handle error case
  448. getId('divResult').innerHTML = 'Translation error occurred';
  449. return;
  450. }
  451.  
  452. var translation = '';
  453. translation += '#[' + GM_getValue('to2', 'auto') + '] ';
  454. for (var i = 0; i < arr[0].length; i++) { if (typeof arr[0][i][0] != 'undefined' && arr[0][i][0] != null) translation += arr[0][i][0]; }
  455. translation += ' <span id="texttospeechbuttonto2"></span><br/>';
  456. translation2Element.innerHTML = translation;
  457. var toText2 = '';
  458. for (var i = 0; i < arr[0].length; i++) { if (typeof arr[0][i][0] != 'undefined' && arr[0][i][0] != null) toText2 += arr[0][i][0]; }
  459. addTextTospeechLink(getId('texttospeechbuttonto2'), GM_getValue('to2', 'auto') == 'auto' ? 'en' : GM_getValue('to2', 'auto'), toText2);
  460. }
  461. function extractResult3(gTradStringArray) {
  462. var arr = parseTranslationResponse(gTradStringArray);
  463. if (!arr) {
  464. // Handle error case
  465. getId('divResult').innerHTML = 'Translation error occurred';
  466. return;
  467. }
  468.  
  469. var translation = '';
  470. translation += '#[' + GM_getValue('to3', 'auto') + '] ';
  471. for (var i = 0; i < arr[0].length; i++) { if (typeof arr[0][i][0] != 'undefined' && arr[0][i][0] != null) translation += arr[0][i][0]; }
  472. translation += ' <span id="texttospeechbuttonto3"></span><br/>';
  473. translation3Element.innerHTML = translation;
  474. var toText3 = '';
  475. for (var i = 0; i < arr[0].length; i++) { if (typeof arr[0][i][0] != 'undefined' && arr[0][i][0] != null) toText3 += arr[0][i][0]; }
  476. addTextTospeechLink(getId('texttospeechbuttonto3'), GM_getValue('to3', 'auto') == 'auto' ? 'en' : GM_getValue('to3', 'auto'), toText3);
  477. }
  478.  
  479. function parseTranslationResponse(gTradStringArray) {
  480. // If it's already an array, return it
  481. if (Array.isArray(gTradStringArray)) {
  482. return gTradStringArray;
  483. }
  484.  
  485. // Remove any leading/trailing whitespace
  486. let str = gTradStringArray.trim();
  487.  
  488. // Handle common escaping issues
  489. str = str
  490. .replace(/\\x/g, '\\u00') // Convert \x escapes to \u escapes
  491. .replace(/\r?\n/g, '\\n') // Handle actual newlines
  492. .replace(/\\/g, '\\\\') // Escape backslashes
  493. .replace(/\\\\"/g, '\\"') // Fix double-escaped quotes
  494. .replace(/\\\\n/g, '\\n') // Fix double-escaped newlines
  495. .replace(/\\\\/g, '\\'); // Fix over-escaped backslashes
  496.  
  497. try {
  498. // Try parsing directly
  499. return JSON.parse(str);
  500. } catch (e1) {
  501. try {
  502. // If the string isn't wrapped in brackets, wrap it
  503. if (!str.startsWith('[')) {
  504. str = '[' + str + ']';
  505. }
  506. return JSON.parse(str);
  507. } catch (e2) {
  508. // If both attempts fail, log the error and the string for debugging
  509. console.error('Failed to parse translation response');
  510. console.log('Original string:', gTradStringArray);
  511. console.log('Processed string:', str);
  512. console.error('Parse error:', e2);
  513. return null;
  514. }
  515. }
  516. }
  517.  
  518. function addTextTospeechLink(element, lang, text) {
  519. if (GM_getValue('tts', false) == false) return;
  520.  
  521. var img = document.createElement('img');
  522. img.setAttribute('src', "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QEQDhUFQkzk7wAAAIpJREFUOMtj/P//PwNFgAQD3jMwMDRg6MVjwHw0/n4GBob/DAwM5xkYGAQIGTAfqhgdFEDF1+MzAKYZl9P6oXIO2AxA1owsAXc2lH7PwMCwHtmA/zgwPLygYYBi0f///xmYSIgwByT2QxiDiYFCQIoBB5DY8rgSEtmBSLVopEpCokpSJjozMVKanQFy4nkNOfntnwAAAABJRU5ErkJggg==");
  523. img.setAttribute('width', '16');
  524. img.setAttribute('height', '16');
  525. img.setAttribute('align', "top");
  526. element.appendChild(img);
  527.  
  528. // var context = new AudioContext();
  529. element.addEventListener('click', function() { playTTS(lang, text, context) }, false);
  530. }
  531.  
  532. function playTTS(lang, text, context) {
  533. text = text.replace(/[«»'"]/g, ' ');
  534. tk = googleTK(text);
  535. Url = ttsURL + "&ie=UTF-8&total=1&idx=0" +
  536. "&tl=" + lang +
  537. "&q=" + text +
  538. "&textlen=" + text.length +
  539. "&tk=" + tk;
  540. window.AudioContext = window.AudioContext || window.webkitAudioContext;
  541. //var context = new AudioContext();
  542. var source = context.createBufferSource();
  543.  
  544. var soundRequest = GM_xmlhttpRequest({
  545. method: "GET",
  546. url: Url,
  547. responseType: 'arraybuffer',
  548. onload: function(response) {
  549. try {
  550. context.decodeAudioData(response.response, function(buffer) {
  551. source.buffer = buffer;
  552. source.connect(context.destination);
  553. source.start(0);
  554. });
  555. } catch(e) {
  556. GM_log(e);
  557. }
  558. }
  559. });
  560. }
  561.  
  562. function getSelection() {
  563. var text = null;
  564. //get selected text
  565. if (window.getSelection && !window.opera) // window.getSelection() bugs with Opera 12.16 and ViolentMonkey
  566. {
  567. if (document.activeElement &&
  568. (document.activeElement.tagName.toLowerCase() == "textarea" ||
  569. document.activeElement.tagName.toLowerCase() == "input")) {
  570. text = document.activeElement.value;
  571. text = text.substring (document.activeElement.selectionStart, document.activeElement.selectionEnd);
  572. } else {
  573. text = window.getSelection().toString();
  574. }
  575. } else if (document.getSelection) {
  576. text = document.getSelection().toString();
  577. } else if (document.selection) {
  578. text = document.selection.createRange().text;
  579. }
  580. // text = text.replace(/[«»'"]/g, ' ');
  581. text = text.replace(/&/g,'\u00E6').replace(/</g,'\u227A').replace(/\+/g,'\u2795');
  582. return text;
  583. }
  584. function openCloseOptions(evt) {
  585. var divOptions = getId('divOpt');
  586. if (!divOptions) //Show options
  587. {
  588. divOptions = createElement('div', {
  589. id : 'divOpt',
  590. style : 'border-top:2px solid #5A91D8;position:relative; padding:5px;'
  591. });
  592. getId('divDic').appendChild(divOptions);
  593. getId('optionsLink').style.visibility = 'hidden';
  594.  
  595. //fields container
  596. divOptionsFields = createElement('p', {style: "margin:0px;padding:0px;line-height:160%;"});
  597. divOptions.appendChild(divOptionsFields);
  598. //from
  599. divOptionsFields.appendChild(createElement('span', null, null, 'From: '));
  600. divOptionsFields.appendChild(createElement('select', {
  601. id : 'optSelLangFrom'
  602. }, null, languagesGoogle));
  603. getId('optSelLangFrom').value = GM_getValue('from') ? GM_getValue('from') : 'auto';
  604. getId('optSelLangFrom').addEventListener('change', quickLookup, false);
  605. //to
  606. divOptionsFields.appendChild(createElement('br'));
  607. divOptionsFields.appendChild(createElement('span', null, null, 'To: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'));
  608. divOptionsFields.appendChild(createElement('select', {
  609. id : 'optSelLangTo'
  610. }, null, languagesGoogle));
  611. getId('optSelLangTo').value = GM_getValue('to') ? GM_getValue('to') : 'auto';
  612. getId('optSelLangTo').addEventListener('change', quickLookup, false);
  613. //to2
  614. divOptionsFields.appendChild(createElement('br'));
  615. divOptionsFields.appendChild(createElement('span', null, null, 'To 2: &nbsp;&nbsp;'));
  616. divOptionsFields.appendChild(createElement('select', {
  617. id : 'optSelLangTo2'
  618. }, null, '<option value="Disabled">Disabled</option>' + languagesGoogle));
  619. getId('optSelLangTo2').value = GM_getValue('to2') ? GM_getValue('to2') : 'Disabled';
  620. getId('optSelLangTo2').addEventListener('change', quickLookup, false);
  621. //to3
  622. divOptionsFields.appendChild(createElement('br'));
  623. divOptionsFields.appendChild(createElement('span', null, null, 'To 3: &nbsp;&nbsp;'));
  624. divOptionsFields.appendChild(createElement('select', {
  625. id : 'optSelLangTo3'
  626. }, null, '<option value="Disabled">Disabled</option>' + languagesGoogle));
  627. getId('optSelLangTo3').value = GM_getValue('to3') ? GM_getValue('to3') : 'Disabled';
  628. getId('optSelLangTo3').addEventListener('change', quickLookup, false);
  629. //use text to speech
  630. divOptionsFields.appendChild(createElement('br'));
  631. divOptionsFields.appendChild(createElement('input', {
  632. id : 'checkTTS',
  633. type : 'checkbox',
  634. style: "margin-left:0px;"
  635. }));
  636. divOptionsFields.appendChild(createElement('span', null, null, '<span title="The feature has many issues. You often have to refresh the page to launch the .mp3 file. If you use the langage auto-detection, you have to change the langage in the url of the new tab."> Display Text To Speech</span>'));
  637. getId('checkTTS').checked = GM_getValue('tts');
  638. //hide details
  639. divOptionsFields.appendChild(createElement('br'));
  640. divOptionsFields.appendChild(createElement('input', {
  641. id : 'checkDetails',
  642. type : 'checkbox',
  643. style: "margin-left:0px;"
  644. }));
  645. divOptionsFields.appendChild(createElement('span', null, null, ' Hide details by default'));
  646. getId('checkDetails').checked = GM_getValue('details');
  647.  
  648. //show alternatives in details
  649. divOptionsFields.appendChild(createElement('br'));
  650. divOptionsFields.appendChild(createElement('input', {
  651. id: 'checkAlternatives',
  652. type: 'checkbox',
  653. style: "margin-left:0px;"
  654. }));
  655. divOptionsFields.appendChild(createElement('span', null, null, ' Show alternatives in details'));
  656. getId('checkAlternatives').checked = GM_getValue('alternatives');
  657.  
  658. //show synonyms in definitions
  659. divOptionsFields.appendChild(createElement('br'));
  660. divOptionsFields.appendChild(createElement('input', {
  661. id: 'checkSynonyms',
  662. type: 'checkbox',
  663. style: "margin-left:0px;"
  664. }));
  665. divOptionsFields.appendChild(createElement('span', null, null, ' Show synonyms in definitions'));
  666. getId('checkSynonyms').checked = GM_getValue('synonyms');
  667.  
  668. //font size
  669. divOptionsFields.appendChild(createElement('br'));
  670. divOptionsFields.appendChild(createElement('span', null, null, 'Font size: &nbsp;&nbsp;'));
  671. divOptionsFields.appendChild(createElement('select', {
  672. id : 'optFontSize',
  673. style: 'width:141px'
  674. }, null, '<option value="x-small">Extra small</option><option value="small">Small (default)</option><option value="medium">Medium</option><option value="large">Large</option>'));
  675. getId('optFontSize').value = GM_getValue('fontsize') ? GM_getValue('fontsize') : 'small';
  676. getId('optFontSize').addEventListener('change', quickLookup, false);
  677. //text color
  678. divOptionsFields.appendChild(createElement('br'));
  679. divOptionsFields.appendChild(createElement('span', null, null, 'Text color: '));
  680. divOptionsFields.appendChild(createElement('select', {
  681. id : 'optTextColor',
  682. style: 'width:141px'
  683. }, null, '<option value="Gray">Gray (default)</option><option value="Black">Black</option><option value="White">White</option><option value="CadetBlue">CadetBlue</option><option value="ForestGreen">ForestGreen</option><option value="FireBrick">FireBrick</option>'));
  684. getId('optTextColor').value = GM_getValue('textcolor') ? GM_getValue('textcolor') : 'Gray';
  685. getId('optTextColor').addEventListener('change', quickLookup, false);
  686. //use ctrl
  687. divOptionsFields.appendChild(createElement('br'));
  688. divOptionsFields.appendChild(createElement('input', {
  689. id : 'checkCtrl',
  690. type : 'checkbox',
  691. style: "margin-left:0px;"
  692. }));
  693. divOptionsFields.appendChild(createElement('span', null, null, ' Use Ctrl key'));
  694. getId('checkCtrl').checked = GM_getValue('ctrl');
  695. //use alt
  696. divOptionsFields.appendChild(createElement('br'));
  697. divOptionsFields.appendChild(createElement('input', {
  698. id : 'checkAlt',
  699. type : 'checkbox',
  700. style: "margin-left:0px;"
  701. }));
  702. divOptionsFields.appendChild(createElement('span', null, null, ' Use Alt key'));
  703. getId('checkAlt').checked = GM_getValue('alt');
  704. //delay display
  705. divOptionsFields.appendChild(createElement('br'));
  706. divOptionsFields.appendChild(createElement('span', null, null, 'Delay '));
  707. divOptionsFields.appendChild(createElement('input', {
  708. id: 'delayDisplay',
  709. type: 'text',
  710. style: "height:20px;width:50px;padding:0px;text-align:center;",
  711. }));
  712. divOptionsFields.appendChild(createElement('span', null, null, ' ms'));
  713. getId('delayDisplay').value = GM_getValue('delay') ? GM_getValue('delay') : '0';
  714. //save
  715. divOptionsFields.appendChild(createElement('br'));
  716. divOptionsFields.appendChild(createElement('a', {
  717. href : HREF_NO,
  718. class : "gootranslink"
  719. }, {
  720. type: 'click',
  721. handler: saveOptions,
  722. capture: false
  723. }, 'Save'));
  724. //reset
  725. divOptionsFields.appendChild(createElement('span', null, null, ' - '));
  726. divOptionsFields.appendChild(createElement('a', {
  727. href : HREF_NO,
  728. class : "gootranslink"
  729. }, {
  730. type: 'click',
  731. handler: resetOptions,
  732. capture: false
  733. }, 'Reset'));
  734. //cancel
  735. divOptionsFields.appendChild(createElement('span', null, null, ' - '));
  736. divOptionsFields.appendChild(createElement('a', {
  737. href : HREF_NO,
  738. class : "gootranslink"
  739. }, {
  740. type: 'click',
  741. handler: openCloseOptions,
  742. capture: false
  743. }, 'Cancel'));
  744. } else // Hide options
  745. {
  746. divOptions.parentNode.removeChild(divOptions);
  747. getId('optionsLink').style.visibility = 'visible';
  748. }
  749. }
  750.  
  751. function saveOptions(evt) {
  752.  
  753. var backgroundColor = getId('divDic').style.backgroundColor;
  754. var from = getId('optSelLangFrom').value;
  755. var to = getId('optSelLangTo').value;
  756. var to2 = getId('optSelLangTo2').value;
  757. var to3 = getId('optSelLangTo3').value;
  758. var tts = getId('checkTTS').checked;
  759. var details = getId('checkDetails').checked;
  760. var alternatives = getId('checkAlternatives').checked;
  761. var synonyms = getId('checkSynonyms').checked;
  762. var fontsize = getId('optFontSize').value;
  763. var textcolor = getId('optTextColor').value;
  764. var ctrl = getId('checkCtrl').checked;
  765. var alt = getId('checkAlt').checked;
  766. var delay = getId('delayDisplay').value;
  767.  
  768. GM_setValue('backgroundColor', backgroundColor);
  769. GM_setValue('from', from);
  770. GM_setValue('to', to);
  771. GM_setValue('to2', to2);
  772. GM_setValue('to3', to3);
  773. GM_setValue('tts', tts);
  774. GM_setValue('details', details);
  775. GM_setValue('alternatives', alternatives);
  776. GM_setValue('synonyms', synonyms);
  777. GM_setValue('fontsize', fontsize);
  778. GM_setValue('textcolor', textcolor);
  779. GM_setValue('ctrl', ctrl);
  780. GM_setValue('alt', alt);
  781. GM_setValue('delay', delay);
  782.  
  783. quickLookup();
  784. getId('divDic').removeChild(getId('divOpt'));
  785. getId('optionsLink').style.visibility = 'visible';
  786. }
  787.  
  788. function resetOptions(evt) {
  789.  
  790. GM_deleteValue('backgroundColor');
  791. GM_deleteValue('from');
  792. GM_deleteValue('to');
  793. GM_deleteValue('to2');
  794. GM_deleteValue('to3');
  795. GM_deleteValue('tts');
  796. GM_deleteValue('details');
  797. GM_deleteValue('alternatives');
  798. GM_deleteValue('synonyms');
  799. GM_deleteValue('fontsize');
  800. GM_deleteValue('textcolor');
  801. GM_deleteValue('ctrl');
  802. GM_deleteValue('alt');
  803. GM_deleteValue('delay');
  804.  
  805. getId('divDic').parentNode.removeChild(getId('divDic'));
  806. }
  807.  
  808. function css() {
  809. var style = createElement('style', {
  810. type : "text/css"
  811. }, null, "" +
  812. 'a.gootranslink:link {color: #0000FF !important; text-decoration: underline !important;}' +
  813. 'a.gootranslink:visited {color: #0000FF !important; text-decoration: underline !important;}' +
  814. 'a.gootranslink:hover {color: #0000FF !important; text-decoration: underline !important;}' +
  815. 'a.gootranslink:active {color: #0000FF !important; text-decoration: underline !important;}' +
  816. '.picker-wrapper,.slide-wrapper{position:relative;float:left}.picker-indicator,.slide-indicator{position:absolute;left:0;top:0;pointer-events:none}.picker,.slide{cursor:crosshair;float:left}.cp-default{background-color:gray;padding:12px;box-shadow:0 0 40px #000;border-radius:15px;float:left}.cp-default .picker{width:200px;height:200px}.cp-default .slide{width:30px;height:200px}.cp-default .slide-wrapper{margin-left:10px}.cp-default .picker-indicator{width:5px;height:5px;border:2px solid darkblue;-moz-border-radius:4px;-o-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;opacity:.5;-ms-filter:"alpha(opacity=50)";filter:alpha(opacity=50);filter:alpha(opacity=50);background-color:white}.cp-default .slide-indicator{width:100%;height:10px;left:-4px;opacity:.6;-ms-filter:"alpha(opacity=60)";filter:alpha(opacity=60);filter:alpha(opacity=60);border:4px solid lightblue;-moz-border-radius:4px;-o-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;background-color:white}.cp-small{padding:5px;background-color:white;float:left;border-radius:5px}.cp-small .picker{width:100px;height:100px}.cp-small .slide{width:15px;height:100px}.cp-small .slide-wrapper{margin-left:5px}.cp-small .picker-indicator{width:1px;height:1px;border:1px solid black;background-color:white}.cp-small .slide-indicator{width:100%;height:2px;left:0;background-color:black}.cp-fancy{padding:10px;background:-webkit-linear-gradient(top,#aaa 0,#222 100%);float:left;border:1px solid #999;box-shadow:inset 0 0 10px white}.cp-fancy .picker{width:200px;height:200px}.cp-fancy .slide{width:30px;height:200px}.cp-fancy .slide-wrapper{margin-left:10px}.cp-fancy .picker-indicator{width:24px;height:24px;background-image:url(http://cdn1.iconfinder.com/data/icons/fugue/bonus/icons-24/target.png)}.cp-fancy .slide-indicator{width:30px;height:31px;left:30px;background-image:url(http://cdn1.iconfinder.com/data/icons/bluecoral/Left.png)}.cp-normal{padding:10px;background-color:white;float:left;border:4px solid #d6d6d6;box-shadow:inset 0 0 10px white}.cp-normal .picker{width:200px;height:200px}.cp-normal .slide{width:30px;height:200px}.cp-normal .slide-wrapper{margin-left:10px}.cp-normal .picker-indicator{width:5px;height:5px;border:1px solid gray;opacity:.5;-ms-filter:"alpha(opacity=50)";filter:alpha(opacity=50);filter:alpha(opacity=50);background-color:white;pointer-events:none}.cp-normal .slide-indicator{width:100%;height:10px;left:-4px;opacity:.6;-ms-filter:"alpha(opacity=60)";filter:alpha(opacity=60);filter:alpha(opacity=60);border:4px solid gray;background-color:white;pointer-events:none}');
  817. getTag('head')[0].appendChild(style);
  818. }
  819. /*
  820. * Short functions to replace the document.createElement document.getElementById and document.getElementsByTagName
  821. */
  822.  
  823. function createElement(type, attrArray, eventObj, html) {
  824. var node = document.createElement(type);
  825. for (var attr in attrArray)
  826. if (attrArray.hasOwnProperty(attr)) {
  827. node.setAttribute(attr, attrArray[attr]);
  828. }
  829. if (eventObj) {
  830. node.addEventListener(eventObj.type, eventObj.handler, eventObj.capture || false);
  831. }
  832. if (html)
  833. node.innerHTML = html;
  834. return node;
  835. }
  836.  
  837. function getId(id, parent) {
  838. if (!parent)
  839. return document.getElementById(id);
  840. return parent.getElementById(id);
  841. }
  842.  
  843. function getTag(name, parent) {
  844. if (!parent)
  845. return document.getElementsByTagName(name);
  846. return parent.getElementsByTagName(name);
  847. }
  848. /*
  849. * Drag and drop support adapted from http://www.hunlock.com/blogs/Javascript_Drag_and_Drop
  850. */
  851. var savedTarget = null; // The target layer (effectively vidPane)
  852. var orgCursor = null; // The original mouse style so we can restore it
  853. var dragOK = false; // True if we're allowed to move the element under mouse
  854. var dragXoffset = 0; // How much we've moved the element on the horozontal
  855. var dragYoffset = 0; // How much we've moved the element on the verticle
  856. var didDrag = false; // Set to true when we do a drag
  857. function moveHandler(e) {
  858. if (e == null)
  859. return; // { e = window.event }
  860. if (e.button <= 1 && dragOK) {
  861. savedTarget.style.left = e.clientX - dragXoffset + 'px';
  862. savedTarget.style.top = e.clientY - dragYoffset + 'px';
  863. return false;
  864. }
  865. }
  866. function dragCleanup(e) {
  867. document.removeEventListener('mousemove', moveHandler, false);
  868. document.removeEventListener('mouseup', dragCleanup, false);
  869. savedTarget.style.cursor = orgCursor;
  870. dragOK = false; // Its been dragged now
  871. didDrag = true;
  872. }
  873. function dragHandler(e) {
  874. var htype = '-moz-grabbing';
  875. if (e == null)
  876. return; // { e = window.event;} // htype='move';}
  877. var target = e.target; // != null ? e.target : e.srcElement;
  878. orgCursor = target.style.cursor;
  879. if (target.nodeName != 'DIV' && target.nodeName != 'P')
  880. return;
  881. if (target = clickedInsideID(target, 'divDic')) {
  882. savedTarget = target;
  883. target.style.cursor = htype;
  884. dragOK = true;
  885. dragXoffset = e.clientX - target.offsetLeft;
  886. dragYoffset = e.clientY - target.offsetTop;
  887. // Set the left before removing the right
  888. target.style.left = e.clientX - dragXoffset + 'px';
  889. target.style.right = null;
  890. document.addEventListener('mousemove', moveHandler, false);
  891. document.addEventListener('mouseup', dragCleanup, false);
  892. return false;
  893. }
  894. }
  895. function clickedInsideID(target, id) {
  896. if (target.getAttribute('id') == id)
  897. return getId(id);
  898. if (target.parentNode) {
  899. while (target = target.parentNode) {
  900. try {
  901. if (target.getAttribute('id') == id)
  902. return getId(id);
  903. } catch (e) {}
  904. }
  905. }
  906. return null;
  907. }
  908. // End drag code
  909. /*
  910. * Images
  911. */
  912. function images() {
  913. imgLookup = createElement('img', {
  914. border : 0
  915. });
  916. imgLookup.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVQ4jY2SP4viQBiHX0UQWz/AXb+VX8Iu/YqFhdhcd5BKEOTKC9jJFYrFgo3FIjYiCRauhTCQDMp4bJFklzCuLJLOWNj8rpDMJt7u7Q08xQzze953/hAR0el4QJLw8KR4fXkE/Wtch01zjP6gmxLsd9uPJafjAf1BF82WjmZLR61eRa1eVfNmS4cMxP8JksGk6FPB6XjAii1Qq1fBBYMMBL79+InvDIrbB0CzIpSmQHF0RnF0vkiTFxZX7A+6MOzwU0FxdEZKYJpj1fp1eO5KzF0JzYreF/iekzr77QMUhh2q1zDsUIULPQl6fXkEFww53cWKLWCaY3DBVMuaFWHuSsT7fM/5W5DTXYUMBGQgUJoCpelFst9tcc84DDuE7znQrAiFnrwIkuGY/W6rBIYdQgYC7RmHZkXwPQf3jL8JiCglISLKVCaqzfhZfc9RcMFwc/eMfGd9EWQbS+R0F9nGEtnGEpnKBJnKJFWxPNygPNygPePggqE942nBdTjG9xyUhxvVcqEnsWILrNjiTfCRJN9ZI99Zp8LxWsy73ztTmYCI6ObuGV/7Tym+/PqtICL6A7F/dNYyWabFAAAAAElFTkSuQmCC';
  917. }
  918. if (typeof GM_deleteValue == 'undefined') {
  919. GM_addStyle = function (css) {
  920. var style = document.createElement('style');
  921. style.textContent = css;
  922. document.getElementsByTagName('head')[0].appendChild(style);
  923. }
  924. GM_deleteValue = function (name) {
  925. localStorage.removeItem(name);
  926. }
  927. GM_getValue = function (name, defaultValue) {
  928. var value = localStorage.getItem(name);
  929. if (!value)
  930. return defaultValue;
  931. var type = value[0];
  932. value = value.substring(1);
  933. switch (type) {
  934. case 'b':
  935. return value == 'true';
  936. case 'n':
  937. return Number(value);
  938. default:
  939. return value;
  940. }
  941. }
  942. GM_log = function (message) {
  943. console.log(message);
  944. }
  945. GM_openInTab = function (url) {
  946. return window.open(url, "_blank");
  947. }
  948. GM_registerMenuCommand = function (name, funk) {
  949. //todo
  950. }
  951. GM_setValue = function (name, value) {
  952. value = (typeof value)[0] + value;
  953. localStorage.setItem(name, value);
  954. }
  955. }
  956. /*
  957. * Cross browser support for GM functions
  958. * http://userscripts.org/topics/41177
  959. */
  960. function initCrossBrowserSupportForGmFunctions() {
  961. if (typeof GM_deleteValue == 'undefined') {
  962. GM_addStyle = function (css) {
  963. var style = document.createElement('style');
  964. style.textContent = css;
  965. document.getElementsByTagName('head')[0].appendChild(style);
  966. }
  967. GM_deleteValue = function (name) {
  968. localStorage.removeItem(name);
  969. }
  970. GM_getValue = function (name, defaultValue) {
  971. var value = localStorage.getItem(name);
  972. if (!value)
  973. return defaultValue;
  974. var type = value[0];
  975. value = value.substring(1);
  976. switch (type) {
  977. case 'b':
  978. return value == 'true';
  979. case 'n':
  980. return Number(value);
  981. default:
  982. return value;
  983. }
  984. }
  985. GM_log = function (message) {
  986. console.log(message);
  987. }
  988. GM_openInTab = function (url) {
  989. return window.open(url, "_blank");
  990. }
  991. GM_registerMenuCommand = function (name, funk) {
  992. //todo
  993. }
  994. GM_setValue = function (name, value) {
  995. value = (typeof value)[0] + value;
  996. localStorage.setItem(name, value);
  997. }
  998. }
  999. }

QingJ © 2025

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