STS Helper

In Steam Translation Server, add many features to make translate easier.

目前为 2017-11-14 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name STS Helper
  3. // @namespace iFantz7E.StsHelper
  4. // @version 2.13
  5. // @description In Steam Translation Server, add many features to make translate easier.
  6. // @match *://translation.steampowered.com/*
  7. // @icon https://translation.steampowered.com/public/favicon.ico
  8. // @run-at document-start
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @grant GM_addStyle
  12. // @copyright 2014, 7-elephant
  13. // ==/UserScript==
  14.  
  15. //// Compatibility: Firefox 14+ from Mutation Observer
  16.  
  17. // http://userscripts.org/scripts/show/325610
  18. // https://greasyfork.org/scripts/2250-sts-helper/
  19.  
  20. (function ()
  21. {
  22. "use strict";
  23. // jshint multistr:true
  24. function initStyle()
  25. {
  26. GM_addStyle
  27. (" \
  28. /* STSH Modify CSS */ \
  29. #logout { \
  30. position: fixed; z-index: 1001; right: 12px; top: 10px; \
  31. line-height: 24px; text-align: right; } \
  32. input[type='button'], input[type='submit'] { \
  33. cursor: pointer; padding: 1px 9px; } \
  34. input[type='button']:disabled, input[type='submit']:disabled { \
  35. cursor: default; color: #777; } \
  36. #suggestionmain { overflow-x: hidden; } \
  37. #suggestionmain > div:nth-child(4) > form:nth-child(2) > div:nth-child(1) { \
  38. text-align: left; } \
  39. .lbAction > div > input[value^='SUBMIT'] { \
  40. width: 750px; height: 30px; border-color: #777 #333 #777 #777; } \
  41. .lbAction > div > input[value^='RESUBMIT'] { \
  42. width: 641px; height: 30px; border-color: #777 #333 #777 #777; } \
  43. .lbAction > div > input[value='CANCEL'] { \
  44. width: 100px; height: 30px; margin-right: 5px; } \
  45. form.lbAction:nth-child(1) > div:nth-child(2) > input:nth-child(1) { \
  46. width: 90%; margin-top: 5px; } \
  47. .suggestion .lbAction textarea { \
  48. max-width: 700px !important; min-height: 50px; } \
  49. .progress td { vertical-align: top; } \
  50. div#suggestions_nav { \
  51. z-index: 3; position: absolute; width: 440px; \
  52. left: 543px; top: 2px; text-align: right; line-height: 24px; } \
  53. #suggestionmain .smallcopy { width: 855px; min-height: 70px; max-height: 70px; } \
  54. #suggestionmain .progress { margin-top: -12px; } \
  55. #leftAreaContainer > table > tbody:nth-child(1) > tr > td:nth-child(1) { \
  56. vertical-align: top; } \
  57. #leftAreaContainer > table, #leftAreaContainer > table th, #leftAreaContainer > table td { \
  58. border: 1px solid #333; border-collapse: collapse; padding: 4px; } \
  59. #suggestions_box { margin-top: 1px !important; position: relative; z-index: 20; } \
  60. #suggestions_iframe { min-height: 100px !important; } \
  61. #keylist td:nth-child(1) > div { \
  62. background-image: none !important; min-height: 43px; } \
  63. #keylist tr:nth-child(2n) > td:nth-child(1) > div { \
  64. background-color: #060606 !important; } \
  65. #keylist tr:nth-child(2n) > td:nth-child(1) > div:hover { \
  66. background-color: #0D0D0D !important; } \
  67. #keylist td:nth-child(1) > div:hover { \
  68. background-repeat: no-repeat; background-position: center; \
  69. background-color: #0D0D0D !important; \
  70. background-image: url('./public/images/row_over.gif') !important; } \
  71. .progress h1 { display: inline-block; width: 484px; } \
  72. div#suggestions_box iframe { background-color: #111 !important; } \
  73. .suggestions_list { border-right: 0px none !important; } \
  74. .suggestion { \
  75. resize: both; overflow: hidden; border-right: 1px solid #505050; \
  76. max-width: 953px; min-width: 200px; min-height: 50px; } \
  77. .suggestion_signature { font-family: Verdana; } \
  78. .suggestion_signature input[value~='APPROVE'] \
  79. , .suggestion_signature input[value~='Next'] { \
  80. color: #A4B23C } \
  81. .suggestion_signature input[value~='DECLINE'] \
  82. , .suggestion_signature input[value~='Next']:nth-child(5) { \
  83. color: #F22 } \
  84. .suggestion_signature input:disabled { color: #777 !important; } \
  85. .lbAction input[value~='COMMENT'] { \
  86. vertical-align: top; margin-top: 1px; height: 52px; } \
  87. .lbAction input[value~='DISCUSS'] { \
  88. vertical-align: top; margin-top: 1px; height: 21px; top: 0px !important; } \
  89. #votes_container a[title='not translated'] { background-color: #333; } \
  90. #suggestion_value_new { min-height: 84px; max-width: 960px; min-width: 200px; overflow-y: auto; } \
  91. #hours > table > tbody > tr:nth-child(2) > th:nth-child(1) { width: 106px; text-align: center; } \
  92. #hours > table > tbody > tr:nth-child(2) > th:nth-child(3) { text-align: center; } \
  93. #hours > table > tbody > tr:nth-child(2) > th:nth-child(4) { text-align: center; } \
  94. #hours > table > tbody > tr > td:nth-child(1) { padding-right: 4px; } \
  95. #hours > table input[name*='[remarks]'] { width: 520px; } \
  96. #hours > table input[name*='[hours]'] { width: 100px; } \
  97. #hours > table input[name*='[minutes]'] { width: 100px; } \
  98. #suggestions_box_outer { overflow: hidden !important; } \
  99. #add_to_discussion { height: 19px; min-height: 19px; } \
  100. .gradienttable td > div { top: 1px !important; } \
  101. .copysmall > td:nth-child(1) { \
  102. white-space: nowrap; overflow: hidden; text-overflow: ellipsis; \
  103. display: inline-block; width: 430px; direction: ltr; } \
  104. div:hover > table > tbody > tr.copysmall > td:nth-child(1) { \
  105. direction: rtl; text-shadow: 1px 1px 1px #0D0D0D;} \
  106. #search input[type='radio'], #search input[type='checkbox'] \
  107. , #search button, #search label { cursor: pointer; } \
  108. ");
  109. GM_addStyle
  110. (" \
  111. /* STSH Main CSS */ \
  112. .stsh_btn { width: 90px; } \
  113. .stsh_btn_med { min-width: 112px; } \
  114. .stsh_btn_long { min-width: 136px; } \
  115. .stsh_btn_short { min-width: 66px; } \
  116. .stsh_btn_right { position: relative; float: right; margin-left: 4px; } \
  117. .stsh_suggestion_header { color: #A4B23C; } \
  118. .stsh_suggestion_comment:before { background-color: #CF8B37 !important; } \
  119. .stsh_suggestion_pending:before { background-color: #FFF !important; } \
  120. .stsh_suggestion_approved:before { background-color: #A4B23C !important; } \
  121. .stsh_suggestion_declined:before { background-color: red !important; } \
  122. .stsh_suggestion_applied:before { background-color: #2EBCEB !important; } \
  123. .stsh_suggestion_removed:before { background-color: #555 !important; } \
  124. .stsh_suggestion { list-style: none; } \
  125. .stsh_suggestion:before { \
  126. content: ''; display: inline-block; position: relative; height: 6px; width: 6px; \
  127. border-radius: 3px; background-clip: padding-box; margin-right: -6px; \
  128. top: -1px; left: -12px; background-color: green; }\
  129. #stsh_frame { \
  130. text-align: center; position: fixed; z-index: 10; \
  131. top: 100px; left: 50%; margin-left: -322px;} \
  132. #stsh_frame_sub { \
  133. background-color: #111; width: 600px; display: inline-block; \
  134. padding: 20px; border: 2px solid #cf9e5f; } \
  135. .stsh_blue { color: #2ebceb; } \
  136. .stsh_green { color: #a4b23c !important; } \
  137. .stsh_red { color: #F00; } \
  138. .stsh_white { color: #fff; } \
  139. .stsh_grey { color: #777 !important; } \
  140. .stsh_orange { color: #CF8B37; } \
  141. .stsh_pink { color: pink; } \
  142. .stsh_border_green { border-color: #76802B !important; } \
  143. .stsh_border_green_left { border-color: #76802B #474D1A #76802B #76802B !important; } \
  144. .stsh_cursor_notallowed { cursor: not-allowed !important; } \
  145. #stsh_showing { \
  146. color: #CCDAD6; position: fixed; z-index: 1001; \
  147. right: 12px; bottom: 12px; text-align: right; line-height: 14px;} \
  148. #stsh_showing_current { \
  149. color: #CCDAD6; position: fixed; z-index: 1001; \
  150. right: 12px; bottom: 28px; text-align: right; line-height: 14px;} \
  151. .stsh_showing_counter { \
  152. display: inline-block; min-width: 60px; text-align: center; } \
  153. .stsh_showing_header { \
  154. color: #CCDAD6; display: inline-block; width: 135px; \
  155. text-align: center; padding-top: 10px; } \
  156. .stsh_showing_group { \
  157. position: fixed; z-index: 3; right: 10px; top: 74px; \
  158. line-height: 24px; text-align: right; } \
  159. .stsh_home_header { color: #CCDAD6; display: inline-block; padding-top: 10px; } \
  160. .stsh_home_group { \
  161. position: fixed; z-index: 3; right: 0px; top: 74px; \
  162. line-height: 24px; text-align: center; width: 164px; } \
  163. .stsh_scroll_header { \
  164. color: #CCDAD6; display: inline-block; width: 130px; \
  165. text-align: center; padding-top: 10px; } \
  166. #stsh_specialEvent { position: absolute; z-index: 2; right: 164px; top: 13px; } \
  167. .stsh_snapshot { \
  168. position: absolute; top: 320px; left: 790px; \
  169. width: 140px; text-align: center; color: #FFF; } \
  170. .stsh_text_comment_header { vertical-align: top; } \
  171. .stsh_text_comment { vertical-align: top; display: inline-block; max-width: 850px; } \
  172. #stsh_autoApprove { vertical-align: -2px; margin-left: 15px; margin-right: 1px; } \
  173. .stsh_unselectable { \
  174. -webkit-touch-callout: none !important; \
  175. -webkit-user-select: none !important; \
  176. -khtml-user-select: none !important; \
  177. -moz-user-select: none !important; \
  178. -ms-user-select: none !important; \
  179. user-select: none !important; } \
  180. .stsh_a_button { \
  181. background-color: #1D1D1D; \
  182. font-family: tahoma,arial,helvetica,trebuchet ms,sans-serif; \
  183. color: #E1E1E1; font-size: 13px; border: 1px solid #777; padding: 1px 9px; } \
  184. .stsh_a_button:link, .stsh_a_button:hover, .stsh_a_button:active, .stsh_a_button:visited { \
  185. color: #E1E1E1; text-decoration: none; } \
  186. .stsh_a_button.stsh_btn { \
  187. display: inline-block; padding: 0px; \
  188. height: 19px; line-height: 19px; width: 88px; } \
  189. .stsh_a_button.stsh_btn_med { \
  190. display: inline-block; padding: 0px; \
  191. height: 19px; line-height: 19px; min-width: 110px; } \
  192. .stsh_a_button.stsh_btn_long { \
  193. display: inline-block; padding: 0px; \
  194. height: 19px; line-height: 19px; min-width: 134px; } \
  195. .stsh_lineCounter_outer { position: relative; } \
  196. .stsh_lineCounter { \
  197. position: absolute; width: 30px; left: -35px; top: -28px; \
  198. line-height: 28px; text-align: right; \
  199. color: #ACACAC; font-size: 9px; text-shadow: 0px 0px 3px #111; } \
  200. .stsh_glossary_term { min-width: 50px; display: inline-block; } \
  201. .stsh_glossary_header, .stsh_glossary_header td { color: #DDD; } \
  202. .stsh_glossary_header *, .stsh_glossary_header td * { color: #858585; } \
  203. .stsh_glossary_header > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(4) { \
  204. width: 10px !important; } \
  205. .stsh_time_convert { cursor: help; } \
  206. .stsh_comment_img { \
  207. display: block; cursor: zoom-in; cursor: -webkit-zoom-in; cursor: -moz-zoom-in; \
  208. max-width: 400px; margin-top: 5px; margin-bottom: 20px; } \
  209. .stsh_hours_curDate { color: #A4B23C; } \
  210. .stsh_hours_curDate input { border-color: #A4B23C; } \
  211. .stsh_submit_suggestion_right { \
  212. height: 30px; width: 214px; margin-right: 5px; border-color: #777 #777 #777 #333; } \
  213. .stsh_truncate { \
  214. white-space: nowrap; overflow: hidden; text-overflow: ellipsis; \
  215. display: inline-block; vertical-align: bottom; } \
  216. .stsh_token_name { max-width: 500px; } \
  217. .stsh_token_share { max-width: 600px; font-size: 0.8em; direction: rtl; } \
  218. .stsh_token_share:hover { direction: ltr; } \
  219. .stsh_pad { padding-left: 2px; padding-right: 2px; } \
  220. .stsh_hidden { display: none; } \
  221. table.gradienttable .stsh_curLang td, table.gradienttable .stsh_dst_curLang td \
  222. , table.gradienttable .stsh_dst_curLang th { \
  223. background: transparent \
  224. linear-gradient(to bottom, #171717 0%, rgba(71, 77, 26, 0.66) 40%, #121212 100%) \
  225. repeat scroll 0% 0% !important; } \
  226. .stsh_delta #suggestion_value_new { border-color: #1B6A85; } \
  227. .stsh_delta .stsh_text_submit { \
  228. color: #2EBCEB; border-color: #1B6A85 #083F52 #1B6A85 #1B6A85 !important; } \
  229. .stsh_delta .stsh_submit_suggestion_right { \
  230. color: #2EBCEB; border-color: #1B6A85 #1B6A85 #1B6A85 #083F52 !important; } \
  231. .stsh_delta .suggestions_list, .stsh_delta .suggestion { \
  232. border-color: #083F52 !important; } \
  233. .stsh_usThem_curLang { background-color: #2F3317; color: #E1E1E1; } \
  234. .stsh_dst_curLang, table.gradienttable .stsh_dst_curLang th, .stsh_dst_curLang a { \
  235. color: #2ebceb; } \
  236. .stsh_text_trn .lbAction textarea { max-width: 450px !important; } \
  237. .stsh_text_trn .lbAction input[value~='COMMENT'] { height: auto; } \
  238. .stsh_text_trn .stsh_text_submit { width: 270px !important; } \
  239. .stsh_text_trn .stsh_submit_suggestion_right { \
  240. width: 184px !important; margin-right: 32px !important; } \
  241. .stsh_text_org, .stsh_text_trn { min-height: 21px; display: block; max-width: 486px !important; } \
  242. .stsh_text_org { margin-bottom: 3px; } \
  243. .stsh_autoLoginOption { display: inline-block; vertical-align: top; line-height: 69px; padding-left: 30px; } \
  244. #stsh_autoLogin { margin-right: 0px; } \
  245. .stsh_moveSuggestionContainer { margin-top: -3px; } \
  246. #stsh_moveSuggestionBox, #stsh_moveSuggestionList { margin-right: 5px; } \
  247. #stsh_hoursCalc_from { width: 130px; } \
  248. #stsh_hoursCalc_to { width: 130px; border-right: 1px #333 solid; } \
  249. #stsh_hoursCalc_toNow { border-left: 1px #333 solid; } \
  250. ");
  251. }
  252.  
  253. function attachOnLoad(callback)
  254. {
  255. window.addEventListener("load", function (e)
  256. {
  257. callback();
  258. });
  259. }
  260.  
  261. function attachOnReady(callback)
  262. {
  263. document.addEventListener("DOMContentLoaded", function (e)
  264. {
  265. callback();
  266. });
  267. }
  268.  
  269. function insertBeforeElement(newNode, referenceNode)
  270. {
  271. referenceNode.parentNode.insertBefore(newNode, referenceNode);
  272. }
  273.  
  274. function insertAfterElement(newNode, referenceNode)
  275. {
  276. referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
  277. }
  278.  
  279. function addKey(eleListener, eleClick, keyCode, keyName, keyTitleMode, keyModifierName, checkModifierCallback)
  280. {
  281. /*
  282. keyTitleMode:
  283. 0: do nothing
  284. 1: append value
  285. 2: add title if not exist
  286. 4: override title
  287. 8: append textContent
  288. 16: append textContent of firstElementChild
  289. keyModifierName:
  290. Ctrl, Ctrl+Shift, Alt
  291. */
  292. keyCode = keyCode || 0;
  293. keyName = keyName || "";
  294. keyTitleMode = keyTitleMode || 0;
  295. keyModifierName = keyModifierName || "";
  296. if (typeof checkModifierCallback !== "function")
  297. {
  298. checkModifierCallback = function(ev)
  299. {
  300. return ev.ctrlKey && ev.shiftKey && ev.altKey;
  301. };
  302. }
  303. if (eleListener && eleClick)
  304. {
  305. // apply title
  306. var keyTitle = keyModifierName ? keyModifierName + "+" + keyName : "";
  307. if (keyTitle !== "")
  308. {
  309. if ((keyTitleMode & 1) === 1)
  310. {
  311. // 1: append value
  312. if (typeof eleClick.value !== "undefined")
  313. {
  314. eleClick.value += " (" + keyTitle + ")";
  315. }
  316. }
  317. if ((keyTitleMode & 2) === 2)
  318. {
  319. // 2: add title if not exist
  320. if (!eleClick.title)
  321. {
  322. eleClick.title = keyTitle;
  323. }
  324. }
  325. if ((keyTitleMode & 4) === 4)
  326. {
  327. // 4: override title
  328. eleClick.title = keyTitle;
  329. }
  330. if ((keyTitleMode & 8) === 8)
  331. {
  332. // 8: append textContent
  333. eleClick.textContent += " (" + keyTitle + ")";
  334. }
  335. if ((keyTitleMode & 16) === 16)
  336. {
  337. // 16: append textContent of firstElementChild
  338. if (eleClick.firstElementChild)
  339. {
  340. eleClick.firstElementChild.textContent += " (" + keyTitle + ")";
  341. }
  342. }
  343. }
  344. eleListener.addEventListener("keydown", function (ev)
  345. {
  346. if (checkModifierCallback(ev))
  347. {
  348. var isSameKey = false;
  349. if (typeof keyCode === "number" && isFinite(keyCode) && Math.floor(keyCode) === keyCode)
  350. {
  351. // polyfill for Number.isInteger before Firefox 16
  352. isSameKey = (ev.keyCode === keyCode);
  353. }
  354. else
  355. {
  356. // Firefox 32+
  357. isSameKey = (typeof ev.code !== "undefined" && ev.code === keyCode)
  358. }
  359. if (isSameKey)
  360. {
  361. ev.preventDefault();
  362. eleClick.focus();
  363. eleClick.click();
  364. return false;
  365. }
  366. }
  367. }, true);
  368. }
  369. }
  370.  
  371. function addKeyCtrl(eleListener, eleClick, keyCode, keyName, keyTitleMode)
  372. {
  373. addKey(eleListener, eleClick, keyCode, keyName, keyTitleMode, "Ctrl", function(ev)
  374. {
  375. return ev.ctrlKey && !ev.shiftKey && !ev.altKey;
  376. });
  377. }
  378.  
  379. function addKeyCtrlShift(eleListener, eleClick, keyCode, keyName, keyTitleMode)
  380. {
  381. addKey(eleListener, eleClick, keyCode, keyName, keyTitleMode, "Ctrl+Shift", function(ev)
  382. {
  383. return ev.ctrlKey && ev.shiftKey && !ev.altKey;
  384. });
  385. }
  386.  
  387. function addKeyAlt(eleListener, eleClick, keyCode, keyName, keyTitleMode)
  388. {
  389. addKey(eleListener, eleClick, keyCode, keyName, keyTitleMode, "Alt", function(ev)
  390. {
  391. return !ev.ctrlKey && !ev.shiftKey && ev.altKey;
  392. });
  393. }
  394.  
  395. function addKeyCtrlEnter(form, input)
  396. {
  397. addKeyCtrl(form, input, 13, "Enter", 1|2);
  398. }
  399.  
  400. function addKeyCtrlShiftEnter(form, input)
  401. {
  402. addKeyCtrlShift(form, input, 13, "Enter", 1|2);
  403. }
  404.  
  405. function disableAfterClick(ele)
  406. {
  407. ele.addEventListener("click", function (e)
  408. {
  409. var ele = e.target;
  410. var attrClick = ele.getAttribute("onclick");
  411. if (attrClick && attrClick.indexOf("confirm") > -1)
  412. {
  413. // skip if has confirm
  414. return;
  415. }
  416. var tagName = ele.tagName;
  417. if (tagName === "INPUT")
  418. {
  419. // don't change color after disable
  420. var styleCp = window.getComputedStyle(ele);
  421. if (styleCp)
  422. {
  423. ele.style.setProperty("color", styleCp.color, "important");
  424. }
  425. ele.disabled = true;
  426. }
  427. else if (tagName === "IMG")
  428. {
  429. ele.removeAttribute("onclick");
  430. }
  431. }, true);
  432. }
  433.  
  434. function removeAllEventListeners(element)
  435. {
  436. if (element)
  437. {
  438. var clone = element.cloneNode(false);
  439. while (element.firstChild)
  440. {
  441. clone.appendChild(element.lastChild);
  442. }
  443. element.parentNode.replaceChild(clone, element);
  444. }
  445. }
  446.  
  447. function scrollToId(id, offset)
  448. {
  449. scrollToElement("#" + id, offset);
  450. }
  451.  
  452. function scrollToElement(selector, offset)
  453. {
  454. if (typeof offset === "undefined")
  455. {
  456. offset = -20;
  457. }
  458. var ele = document.querySelector(selector);
  459. if (ele)
  460. {
  461. ele.scrollIntoView(true);
  462. window.scrollBy(0, offset);
  463. }
  464. }
  465.  
  466. function resizeSuggestionBox()
  467. {
  468. var script = document.createElement('script');
  469. script.innerHTML =
  470. " \
  471. var stsh_showSuggestionsBox_start = new Date(); \
  472. var stsh_showSuggestionsBox_itv = setIntervalCustom(function() \
  473. { \
  474. var stsh_showSuggestionsBox_isEnd = false; \
  475. var stsh_showSuggestionsBox_cur = new Date(); \
  476. if (typeof showSuggestionsBox !== 'undefined') \
  477. { \
  478. showSuggestionsBox = function(url) \
  479. { \
  480. /* Edit from STS */ \
  481. g_suggestionsBoxIsOpen = true; \
  482. $('suggestions_box_outer').appear( \
  483. { \
  484. duration : 0.1 \
  485. } \
  486. ); \
  487. $('suggestions_iframe').setAttribute('src', url); \
  488. if (!Prototype.Browser.IE) \
  489. { \
  490. $('suggestions_iframe').focus(); \
  491. } \
  492. $('suggestions_iframe').style.height = (document.viewport.getHeight() * 0.99) + 'px'; \
  493. return false; \
  494. }; \
  495. stsh_showSuggestionsBox_isEnd = true; \
  496. } \
  497. if (stsh_showSuggestionsBox_isEnd || stsh_showSuggestionsBox_cur - stsh_showSuggestionsBox_start > 10000) \
  498. { \
  499. clearInterval(stsh_showSuggestionsBox_itv); \
  500. } \
  501. }, 300); \
  502. ";
  503. document.head.appendChild(script);
  504.  
  505. window.addEventListener("resize", function()
  506. {
  507. var iframe = document.querySelector("#suggestions_iframe");
  508. if (iframe)
  509. {
  510. iframe.style.height = (window.innerHeight * 0.99) + "px";
  511. }
  512. });
  513. }
  514.  
  515. function isRally()
  516. {
  517. var date = new Date();
  518. var year = date.getUTCFullYear();
  519. var month = date.getUTCMonth() + 1;
  520. var day = date.getUTCDate();
  521. if ((month > 9) || (month === 9 && day >= 22) || (month === 0 && day <= 2))
  522. {
  523. return true;
  524. }
  525. return false;
  526. }
  527.  
  528. function getQueryByName(name, url)
  529. {
  530. if (!url)
  531. {
  532. url = (!location) ? "" : location.search;
  533. }
  534. name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  535. var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
  536. var results = regex.exec(url);
  537. var retVal = "";
  538. if (results)
  539. {
  540. retVal = results[1].replace(/\+/g, " ");
  541. try
  542. {
  543. retVal = decodeURIComponent(retVal);
  544. }
  545. catch (ex)
  546. {
  547. console.error("getQueryByName", ex.message);
  548. }
  549. }
  550. return retVal;
  551. }
  552.  
  553. function padZero(num, size)
  554. {
  555. return (1e15 + num + "").slice(-size);
  556. }
  557.  
  558. function padZeroHex(num, size)
  559. {
  560. return ("00000000000000000000000" + num.toString(16)).slice(-size).toUpperCase();
  561. }
  562.  
  563. function randNum(min, max)
  564. {
  565. return Math.round(Math.random() * (max - min) + min);
  566. }
  567.  
  568. function isSpecialChar(ch)
  569. {
  570. var chCode = -1;
  571. if (typeof ch === 'number')
  572. {
  573. chCode = ch;
  574. }
  575. else
  576. {
  577. chCode = ch.charCodeAt(0);
  578. }
  579. if ((chCode > -1 && chCode < 9) // 0-8
  580. || (chCode > 10 && chCode < 13) // 11-12
  581. || (chCode > 13 && chCode < 32)) // 14-31
  582. {
  583. return true;
  584. }
  585. return false;
  586. }
  587.  
  588. function hasSpecialChar(str)
  589. {
  590. var rgxSpCh = /[\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F]+/;
  591. return rgxSpCh.test(str);
  592. }
  593. function checkSpecialCharMatched(str1, str2)
  594. {
  595. // return (status, numSp1, numSp2)
  596. // status: 0:Match, 1:NotMatch, 2:NotEqual
  597. str1 = str1 || "";
  598. str2 = str2 || "";
  599. var strOut1 = "";
  600. var strOut2 = "";
  601. for (var i = 0; i < str1.length; i++)
  602. {
  603. if (isSpecialChar(str1[i]))
  604. {
  605. strOut1 += str1[i];
  606. }
  607. }
  608. for (var i = 0; i < str2.length; i++)
  609. {
  610. if (isSpecialChar(str2[i]))
  611. {
  612. strOut2 += str2[i];
  613. }
  614. }
  615. var retVal = 0;
  616. if (strOut1 === strOut2)
  617. retVal = 0;
  618. else if (strOut1.length === strOut2.length)
  619. retVal = 1;
  620. else
  621. retVal = 2;
  622. return new Array(retVal, strOut1.length, strOut2.length);
  623. }
  624.  
  625. function trimSpace(str)
  626. {
  627. return str.replace(/^[ \r\n\t]+/, "").replace(/[ \r\n\t]+$/, "");
  628. }
  629.  
  630. if (!String.prototype.endsWith)
  631. {
  632. String.prototype.endsWith = function(searchString, position)
  633. {
  634. var subjectString = this.toString();
  635. if (typeof position !== 'number' || !isFinite(position)
  636. || Math.floor(position) !== position || position > subjectString.length)
  637. {
  638. position = subjectString.length;
  639. }
  640. position -= searchString.length;
  641. var lastIndex = subjectString.indexOf(searchString, position);
  642. return lastIndex !== -1 && lastIndex === position;
  643. };
  644. }
  645.  
  646. function reload()
  647. {
  648. var curHref = window.location.href;
  649. var posHashtag = curHref.indexOf("#");
  650. if (posHashtag > -1)
  651. {
  652. window.location = curHref.substr(0, posHashtag);
  653. }
  654. else
  655. {
  656. window.location = curHref;
  657. }
  658. }
  659.  
  660. function getCookie(c_name) {
  661. var c_value = document.cookie;
  662. var c_start = c_value.indexOf(" " + c_name + "=");
  663. if (c_start === -1) {
  664. c_start = c_value.indexOf(c_name + "=");
  665. }
  666. if (c_start === -1) {
  667. c_value = null;
  668. }
  669. else {
  670. c_start = c_value.indexOf("=", c_start) + 1;
  671. var c_end = c_value.indexOf(";", c_start);
  672. if (c_end === -1) {
  673. c_end = c_value.length;
  674. }
  675. c_value = unescape(c_value.substring(c_start, c_end));
  676. }
  677. return c_value;
  678. }
  679.  
  680. var isVisible = (function()
  681. {
  682. var stateKey;
  683. var eventKey;
  684. var keys =
  685. {
  686. hidden: "visibilitychange",
  687. webkitHidden: "webkitvisibilitychange",
  688. mozHidden: "mozvisibilitychange",
  689. msHidden: "msvisibilitychange"
  690. };
  691. for (stateKey in keys)
  692. {
  693. if (stateKey in document)
  694. {
  695. eventKey = keys[stateKey];
  696. break;
  697. }
  698. }
  699. return function(c)
  700. {
  701. if (c)
  702. {
  703. document.addEventListener(eventKey, c);
  704. }
  705. return !document[stateKey];
  706. }
  707. })();
  708.  
  709. function isDstUs(year, month, day, hour)
  710. {
  711. // Support: 2007 - 2029
  712. // Params: 2016, 3, 1, 15 === 1 Mar 2016 15:00
  713. var isDst = false;
  714. try
  715. {
  716. var y = parseInt(year);
  717. var m = parseInt(month);
  718. var d = parseInt(day);
  719. var h = parseInt(hour);
  720. function checkDstUsa(dayMar, dayNov, m, d, h)
  721. {
  722. var isDst = false;
  723. if ((m === 3 && d >= dayMar) || (m > 3 && m < 11) || (m === 11 && d <= dayNov))
  724. isDst = true;
  725. if ((m === 3 && d === dayMar && h < 2) || (m === 11 && d === dayNov && h >= 2))
  726. isDst = false;
  727. return isDst;
  728. }
  729. if (y === 2007 || y === 2012 || y === 2018 || y === 2029)
  730. {
  731. isDst = checkDstUsa(11, 4, m, d, h);
  732. }
  733. else if (y === 2013 || y === 2019 || y === 2024)
  734. {
  735. isDst = checkDstUsa(10, 3, m, d, h);
  736. }
  737. else if (y === 2008 || y === 2014 || y === 2025)
  738. {
  739. isDst = checkDstUsa(9, 2, m, d, h);
  740. }
  741. else if (y === 2009 || y === 2015 || y === 2020 || y === 2026)
  742. {
  743. isDst = checkDstUsa(8, 1, m, d, h);
  744. }
  745. else if (y === 2010 || y === 2021 || y === 2027)
  746. {
  747. isDst = checkDstUsa(14, 7, m, d, h);
  748. }
  749. else if (y === 2011 || y === 2016 || y === 2022)
  750. {
  751. isDst = checkDstUsa(13, 6, m, d, h);
  752. }
  753. else if (y === 2017 || y === 2023 || y === 2028)
  754. {
  755. isDst = checkDstUsa(12, 5, m, d, h);
  756. }
  757. }
  758. catch (ex)
  759. {
  760. console.error("isDstUs", ex.message);
  761. }
  762. return isDst;
  763. }
  764.  
  765. function getDateIsoUs()
  766. {
  767. var dateUs = new Date();
  768. dateUs.setTime(dateUs.getTime() - (1000 * 60 * 60 * 8)); // GMT-8
  769. if (isDstUs(dateUs.getUTCFullYear(), dateUs.getUTCMonth() + 1, dateUs.getUTCDate(), dateUs.getUTCHours()))
  770. {
  771. dateUs.setTime(dateUs.getTime() + (1000 * 60 * 60 * 1)); // GMT-7
  772. }
  773. return dateUs.toISOString();
  774. }
  775.  
  776. function getDateUs()
  777. {
  778. return getDateIsoUs().substr(0, 10);
  779. }
  780.  
  781. function getTimeUs()
  782. {
  783. return getDateIsoUs().substr(11, 5);
  784. }
  785.  
  786. function getUnixTimestamp()
  787. {
  788. return parseInt((new Date()) / 1000);
  789. }
  790. var pattUrlTimestamp1 = /\?t=[0-9]{6,}\&/g;
  791. var pattUrlTimestamp2 = /\&t=[0-9]{6,}/g;
  792. var pattUrlTimestamp3 = /\?t=[0-9]{6,}/g;
  793. var pattUrlTimestamp4 = /\&[0-9]{6,}\&/g;
  794.  
  795. function cleanUrlTimestamp(eles)
  796. {
  797. if (!eles || !eles.length)
  798. return;
  799.  
  800. for (var i = 0; i < eles.length; i++)
  801. {
  802. var val = "";
  803. var attr = "";
  804. if (eles[i].tagName === "A")
  805. {
  806. attr = "href";
  807. }
  808. else if (eles[i].tagName === "FORM")
  809. {
  810. attr = "action";
  811. }
  812. else if (eles[i].tagName === "DIV")
  813. {
  814. attr = "onclick";
  815. }
  816. var isEdit = false;
  817. val = eles[i].getAttribute(attr);
  818. if (pattUrlTimestamp1.test(val))
  819. {
  820. eles[i].setAttribute(attr, val.replace(pattUrlTimestamp1,"?"));
  821. isEdit = true;
  822. }
  823. else if (pattUrlTimestamp2.test(val))
  824. {
  825. eles[i].setAttribute(attr, val.replace(pattUrlTimestamp2,""));
  826. isEdit = true;
  827. }
  828. else if (pattUrlTimestamp3.test(val))
  829. {
  830. eles[i].setAttribute(attr, val.replace(pattUrlTimestamp3,""));
  831. isEdit = true;
  832. }
  833. if (isEdit)
  834. {
  835. val = eles[i].getAttribute(attr);
  836. }
  837. if (pattUrlTimestamp4.test(val))
  838. {
  839. eles[i].setAttribute(attr, val.replace(pattUrlTimestamp4,"&"));
  840. }
  841. }
  842. }
  843.  
  844. var timeoutList = new Array();
  845. var intervalList = new Array();
  846.  
  847. function setTimeoutCustom(func, tm, params)
  848. {
  849. var id = setTimeout(func, tm, params);
  850. timeoutList.push(id);
  851. return id;
  852. }
  853.  
  854. function clearTimeoutAll()
  855. {
  856. for (var i = 0; i < timeoutList.length; i++)
  857. {
  858. clearTimeout(timeoutList[i]);
  859. }
  860. }
  861.  
  862. function setIntervalCustom(func, tm, params)
  863. {
  864. var id = setInterval(func, tm, params);
  865. intervalList.push(id);
  866. return id;
  867. }
  868.  
  869. function clearIntervalAll()
  870. {
  871. for (var i = 0; i < intervalList.length; i++)
  872. {
  873. clearInterval(intervalList[i]);
  874. }
  875. }
  876.  
  877. function main()
  878. {
  879. var url = document.documentURI;
  880. var lang = getCookie("Language");
  881. // Auto refresh when error
  882. {
  883. var h1 = document.querySelector("#leftAreaContainer > h1, body > h1");
  884. if (h1)
  885. {
  886. var text = h1.textContent.trim();
  887. if (text === "Steam Translation Server - Maintenance Warning"
  888. || text === "Forbidden")
  889. {
  890. console.log("stsh: refresh");
  891. setTimeoutCustom(reload, 60000);
  892. return;
  893. }
  894. }
  895. }
  896.  
  897. // Clean links
  898. {
  899. setTimeoutCustom(function()
  900. {
  901. var eles = document.querySelectorAll("a, form[action]");
  902. cleanUrlTimestamp(eles);
  903. }, 1000);
  904. }
  905.  
  906. var eleLogout = document.querySelector("#logout");
  907. if (eleLogout)
  908. {
  909. var logoutHtml =
  910. ' \
  911. <a class="stsh_a_button" target="_blank" href="/user_activity.php">My Profile</a> \
  912. <input name="login_button" value="Logout?" type="submit" onclick="return confirm(\'Logout?\');" /> \
  913. ';
  914. eleLogout.innerHTML = logoutHtml;
  915. // Special event button
  916. {
  917. if (isRally())
  918. {
  919. var divSpecial = document.createElement("div");
  920. divSpecial.id = "stsh_specialEvent";
  921. divSpecial.innerHTML =
  922. ' \
  923. <a class="stsh_a_button" target="_blank" href="/rally.php">Year-End Rally</a> \
  924. ';
  925. eleLogout.parentElement.appendChild(divSpecial);
  926. }
  927. }
  928. }
  929. if (url.indexOf("Us_And_Them.php") > -1)
  930. {
  931. var container = "\"";
  932. var tdEng = document.querySelector(
  933. "#leftAreaContainer > table > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2)");
  934. if (tdEng)
  935. {
  936. tdEng.innerHTML = container + tdEng.innerHTML + container;
  937. }
  938. var h1 = document.querySelector("#leftAreaContainer > h1:nth-child(2)");
  939. if (h1)
  940. {
  941. var header = h1.textContent.trim();
  942. var key = header.split(" ")[0];
  943. h1.innerHTML = header.replace(key, "<a href='/translate.php?keyonly=1&search_input="
  944. + encodeURIComponent(key) + "' >" + key + "</a>");
  945. document.title = key + " - " + document.title;
  946. }
  947. // Hilight cur lang
  948. {
  949. //var first = document.querySelector("#leftAreaContainer tr:nth-child(1) > td:nth-child(1) > a");
  950. //if (first)
  951. {
  952. var cur = null;
  953. var elesLang = document.querySelectorAll("#leftAreaContainer tr > td:nth-child(1) > a");
  954. for (var i = 1; i < elesLang.length; i++)
  955. {
  956. if (lang === elesLang[i].textContent.trim().toLowerCase())
  957. {
  958. cur = elesLang[i].parentElement.parentElement;
  959. break;
  960. }
  961. }
  962. if (cur)
  963. {
  964. cur.classList.add("stsh_usThem_curLang");
  965. //insertAfterElement(cur, first.parentElement.parentElement);
  966. }
  967. }
  968. }
  969. } // End Us_And_Them.php
  970.  
  971. if (url.indexOf("suggestions.php") > -1)
  972. {
  973. var eleTextOrg = document.querySelector(".progress > tbody > tr:last-child > td:nth-child(1)");
  974. if (eleTextOrg)
  975. {
  976. eleTextOrg.classList.add("stsh_text_org");
  977. }
  978. var eleTextTrn = document.querySelector(".progress > tbody > tr:last-child > td:nth-child(3)");
  979. if (eleTextTrn)
  980. {
  981. eleTextTrn.classList.add("stsh_text_trn");
  982. }
  983. var eleTextSubmit = document.querySelector(".lbAction[name='suggestion_temp'] input[accesskey='s']");
  984. if (eleTextSubmit)
  985. {
  986. eleTextSubmit.classList.add("stsh_text_submit");
  987. }
  988. var elesTextRemoveComment = document.querySelectorAll(".suggestion_signature .lbAction[name^='mymodcomment'] a");
  989. for (var i = 0; i < elesTextRemoveComment.length; i++)
  990. {
  991. elesTextRemoveComment[i].removeAttribute("href");
  992. elesTextRemoveComment[i].classList.add("stsh_text_removeComment");
  993. }
  994. var elesTextComment = document.querySelectorAll("textarea[name='suggestion_comment']");
  995. for (var i = 0; i < elesTextComment.length; i++)
  996. {
  997. elesTextComment[i].nextElementSibling.classList.add("stsh_submit_comment");
  998. }
  999. var eleTextNew = document.querySelector("#suggestion_value_new");
  1000. if (eleTextNew)
  1001. {
  1002. eleTextNew.style.width = "960px";
  1003. eleTextNew.style.height = "64px";
  1004. eleTextNew.style.marginLeft = "3px";
  1005. }
  1006. var inputClose = document.querySelector("#suggestions_nav > input[value^='Close']");
  1007. if (inputClose)
  1008. {
  1009. inputClose.value = "Close (Esc)";
  1010. }
  1011. // Move region
  1012. {
  1013. var td = eleTextTrn;
  1014. if (td && td.textContent.trim() === "")
  1015. {
  1016. function moveSuggestionBox()
  1017. {
  1018. var td = document.querySelector(".stsh_text_trn");
  1019. if (td && td.textContent.trim() === "")
  1020. {
  1021. td.innerHTML = "";
  1022. var eleTarget = document.querySelector("#suggestionmain > div:nth-child(4) > .lbAction");
  1023. if (eleTarget)
  1024. {
  1025. td.appendChild(eleTarget);
  1026. td.style.padding = "0px";
  1027. var textarea = document.querySelector("#suggestion_value_new");
  1028. if (textarea)
  1029. {
  1030. textarea.style.width = "98%";
  1031. textarea.style.marginLeft = "0px";
  1032. if (textarea.scrollHeight < 500)
  1033. {
  1034. textarea.style.height = (textarea.scrollHeight + 20) + "px";
  1035. }
  1036. else
  1037. {
  1038. textarea.style.height = "500px";
  1039. }
  1040. textarea.focus();
  1041. }
  1042. var eleTextOrg = document.querySelector(".stsh_text_org");
  1043. if (eleTextOrg)
  1044. {
  1045. eleTextOrg.style.display = "table-cell";
  1046. eleTextOrg.style.paddingTop = "6px";
  1047. }
  1048. }
  1049. }
  1050. }
  1051. function moveSuggestionList()
  1052. {
  1053. var td = document.querySelector(".stsh_text_trn");
  1054. if (td && td.textContent.trim() === "")
  1055. {
  1056. td.innerHTML = "";
  1057. var eleTarget = document.querySelector(".suggestion");
  1058. if (eleTarget)
  1059. {
  1060. td.appendChild(eleTarget);
  1061. td.style.padding = "0px";
  1062. eleTarget.style.marginTop = "-2px";
  1063. eleTarget.style.paddingTop = "0px";
  1064. eleTarget.style.borderBottomWidth = "0px";
  1065. eleTarget.style.borderRightWidth = "0px";
  1066. eleTarget.style.resize = "none";
  1067. var eleAutoApprove = document.querySelector("#stsh_autoApprove");
  1068. if (eleAutoApprove)
  1069. {
  1070. eleAutoApprove.classList.add("stsh_hidden");
  1071. }
  1072. var eleAutoApproveLabel = document.querySelector(".stsh_autoApprove_label");
  1073. if (eleAutoApproveLabel)
  1074. {
  1075. eleAutoApproveLabel.classList.add("stsh_hidden");
  1076. }
  1077. }
  1078. }
  1079. }
  1080. var eleDiv = document.createElement("div");
  1081. eleDiv.classList.add("stsh_moveSuggestionContainer");
  1082. td.appendChild(eleDiv);
  1083. var eleMoveBox = document.createElement("input");
  1084. eleMoveBox.id = "stsh_moveSuggestionBox";
  1085. eleMoveBox.setAttribute("value", "Move Box Here");
  1086. eleMoveBox.setAttribute("type", "button");
  1087. eleDiv.appendChild(eleMoveBox);
  1088. eleMoveBox.addEventListener("click", function(e)
  1089. {
  1090. moveSuggestionBox();
  1091. });
  1092. if (document.querySelector(".suggestion"))
  1093. {
  1094. var eleMoveList = document.createElement("input");
  1095. eleMoveList.id = "stsh_moveSuggestionList";
  1096. eleMoveList.setAttribute("value", "Move Suggestion Here");
  1097. eleMoveList.setAttribute("type", "button");
  1098. eleDiv.appendChild(eleMoveList);
  1099. eleMoveList.addEventListener("click", function(e)
  1100. {
  1101. moveSuggestionList();
  1102. });
  1103. }
  1104. }
  1105. }
  1106. if (eleTextNew)
  1107. {
  1108. var resizeTextNew = function(eleTextNew)
  1109. {
  1110. eleTextNew.focus();
  1111. if (eleTextNew.scrollHeight < 500)
  1112. {
  1113. eleTextNew.style.height = (eleTextNew.scrollHeight + 20) + "px";
  1114. }
  1115. else
  1116. {
  1117. eleTextNew.style.height = "500px";
  1118. }
  1119. if (eleTextNew.scrollHeight > 200 && document.querySelector(".suggestion"))
  1120. {
  1121. eleTextNew.scrollIntoView();
  1122. }
  1123. };
  1124. if (isVisible())
  1125. {
  1126. resizeTextNew(eleTextNew);
  1127. }
  1128. else
  1129. {
  1130. // Fix size error when inactive
  1131. setTimeoutCustom(resizeTextNew, 100, eleTextNew);
  1132. }
  1133. }
  1134. var br = document.querySelector("form.lbAction:nth-child(2) > div:nth-child(2) > br:nth-child(1)");
  1135. if (br)
  1136. {
  1137. br.parentElement.removeChild(br);
  1138. }
  1139. var key = "";
  1140. var divNav = document.querySelector("div#suggestions_nav");
  1141. if (divNav)
  1142. {
  1143. var insert = "";
  1144. var spliter = "_";
  1145. var regApp = /[0-9]{4,}/;
  1146. var aKey = document.querySelector(".smallcopy > font:nth-child(2) > a:nth-child(1)");
  1147. if (aKey)
  1148. {
  1149. insert += ' <br/> &nbsp; ';
  1150. key = encodeURIComponent(aKey.textContent.trim());
  1151. if (key === "token-key")
  1152. {
  1153. aKey = document.querySelector(".smallcopy > a:nth-child(3)");
  1154. if (aKey)
  1155. {
  1156. key = encodeURIComponent(aKey.textContent.trim());
  1157. }
  1158. }
  1159. if (key !== "")
  1160. {
  1161. document.title = key + " - " + document.title;
  1162. if (key.split(spliter).length > 1)
  1163. {
  1164. if (key.indexOf("%23") === 0)
  1165. {
  1166. var firstSpliter = key.indexOf(spliter);
  1167. var keySharp = key.substring(0, firstSpliter);
  1168. insert += ' <a class="stsh_a_button" target="_blank" '
  1169. + ' href="/translate.php?keyonly=1&paginationrows=1000&search_input='
  1170. + keySharp + '">Search by Hashtag</a> ';
  1171. }
  1172. var lastSpliter = key.lastIndexOf(spliter);
  1173. var keyGroup = key.substring(0, lastSpliter);
  1174. insert += ' <a class="stsh_a_button" target="_blank" '
  1175. + ' href="/translate.php?keyonly=1&paginationrows=1000&search_input='
  1176. + keyGroup + '">Search by Group</a> ';
  1177. }
  1178. insert += ' <a class="stsh_a_button" target="_blank" '
  1179. + ' href="/translate.php?keyonly=1&search_input='
  1180. + key + '">Search by Key</a> ';
  1181. }
  1182. }
  1183. var tdText = eleTextOrg;
  1184. if (tdText)
  1185. {
  1186. var text = encodeURIComponent(tdText.textContent.trim())
  1187. .replace(/(%20|%09)/g,"+")
  1188. .replace(/'/g,"\\'")
  1189. .replace("%0A", "+")
  1190. .replace(/\++/g, "+")
  1191. .substr(0, 80);
  1192. if (text.length >= 80)
  1193. {
  1194. text = text.substr(0, text.lastIndexOf("+"));
  1195. }
  1196. if (text.indexOf(".") > 20)
  1197. {
  1198. text = text.substr(0, text.indexOf(".") + 1);
  1199. }
  1200. if (text.indexOf("%5C") > 10)
  1201. {
  1202. text = text.substr(0, text.indexOf("%5C"));
  1203. }
  1204. var eleSubmit = document.querySelector(".stsh_text_submit");
  1205. if (eleSubmit)
  1206. {
  1207. var elePrev = eleSubmit.previousElementSibling;
  1208. if (!elePrev || elePrev.tagName !== "BR")
  1209. {
  1210. var eleNew = document.createElement("br");
  1211. insertBeforeElement(eleNew, eleSubmit);
  1212. }
  1213. }
  1214. if (text !== "")
  1215. {
  1216. insert += ' <br/> &nbsp; <a class="stsh_a_button" target="_blank" '
  1217. + ' href="/translate.php?keyonly=2&paginationrows=1000&search_input='
  1218. + text + '">Search by String</a> ';
  1219. var eleSubmitNext = document.querySelector(".lbAction input[type='submit'][accesskey='a']");
  1220. if (eleSubmitNext)
  1221. {
  1222. eleSubmitNext.value = "Next";
  1223. eleSubmitNext.classList.add("stsh_submit_suggestion_right");
  1224. var eleForm = eleSubmitNext.parentElement.parentElement;
  1225. if (eleForm.tagName === "FORM")
  1226. {
  1227. addKeyCtrlShiftEnter(eleForm, eleSubmitNext);
  1228. }
  1229. }
  1230. else
  1231. {
  1232. if (eleSubmit)
  1233. {
  1234. var eleNew = document.createElement("input");
  1235. eleNew.id = "stsh_submit_suggestion_next";
  1236. eleNew.classList.add("stsh_submit_suggestion_right");
  1237. eleNew.setAttribute("type", "submit");
  1238. eleNew.setAttribute("value", "Next");
  1239. eleNew.setAttribute("name", "submitandnext");
  1240. insertAfterElement(eleNew, eleSubmit);
  1241. eleNew.addEventListener("click", function(ev)
  1242. {
  1243. var textOrg = "";
  1244. var textTrn = "";
  1245. var textCur = "";
  1246. var eleTextOrg = document.querySelector(".stsh_text_org");
  1247. if (eleTextOrg)
  1248. {
  1249. textOrg = trimSpace(eleTextOrg.textContent);
  1250. }
  1251. var eleTextTrn = document.querySelector(".stsh_text_trn");
  1252. if (eleTextTrn)
  1253. {
  1254. textTrn = trimSpace(eleTextTrn.textContent);
  1255. }
  1256. var eleTextCur = document.querySelector("#suggestion_value_new");
  1257. if (eleTextCur)
  1258. {
  1259. textCur = trimSpace(eleTextCur.value);
  1260. }
  1261. if (textCur === "" || textOrg === textCur || textTrn === textCur)
  1262. {
  1263. ev.preventDefault();
  1264. var eleSubmit = document.querySelector(".stsh_text_submit");
  1265. if (eleSubmit)
  1266. {
  1267. eleSubmit.click();
  1268. }
  1269. }
  1270. });
  1271. var eleForm = eleSubmit.parentElement.parentElement;
  1272. if (eleForm.tagName === "FORM")
  1273. {
  1274. addKeyCtrlShiftEnter(eleForm, eleNew);
  1275. }
  1276. }
  1277. }
  1278. }
  1279. else
  1280. {
  1281. if (eleTextNew && eleSubmit)
  1282. {
  1283. var eleNew = document.createElement("input");
  1284. eleNew.id = "stsh_submit_suggestion_space";
  1285. eleNew.classList.add("stsh_submit_suggestion_right");
  1286. eleNew.setAttribute("type", "button");
  1287. eleNew.setAttribute("value", "Submit Space (Alt+0160)");
  1288. insertAfterElement(eleNew, eleSubmit);
  1289. eleNew.addEventListener("click", function(ev)
  1290. {
  1291. var eleTextNew = document.querySelector("#suggestion_value_new");
  1292. if (eleTextNew)
  1293. {
  1294. eleTextNew.value = String.fromCharCode(160);
  1295. eleTextNew.focus();
  1296. ev.preventDefault();
  1297. var eleSubmit = document.querySelector(".stsh_text_submit");
  1298. if (eleSubmit)
  1299. {
  1300. eleSubmit.click();
  1301. }
  1302. }
  1303. });
  1304. }
  1305. }
  1306. }
  1307. var app = regApp.exec(key.replace("%23", ""));
  1308. if (key.indexOf("faq") < 0 && app)
  1309. {
  1310. insert += ' <br/> &nbsp; ';
  1311. if (key.indexOf("SharedFiles_App_") === 0)
  1312. {
  1313. insert += ' <a class="stsh_a_button" target="_blank" '
  1314. + ' href="http://steamcommunity.com/workshop/browse?appid='
  1315. + app + '">View Workshop</a> ';
  1316. }
  1317. insert += ' <a class="stsh_a_button" target="_blank" '
  1318. + ' href="http://steamcommunity.com/app/'
  1319. + app + '">View Community</a> '
  1320. insert += ' <a class="stsh_a_button" target="_blank" '
  1321. + ' href="http://store.steampowered.com/app/'
  1322. + app + '">View App</a> ';
  1323. }
  1324. var insertBefore =
  1325. ' \
  1326. <input id="stsh_refresh" value="Refresh" onclick="return false;" type="button"> \
  1327. <a class="stsh_a_button" target="_blank" href="' + url + '">Frame</a> \
  1328. ';
  1329. var innerNew = divNav.innerHTML
  1330. .replace('<input value="Previous', '&nbsp;&nbsp;<input value="Prev')
  1331. .replace('<input value="Close', '&nbsp;&nbsp;<input value="Close');
  1332. divNav.innerHTML = insertBefore + innerNew + insert + " <br/> ";
  1333. var eleRefresh = document.querySelector("#stsh_refresh");
  1334. if (eleRefresh)
  1335. {
  1336. eleRefresh.addEventListener("click", function()
  1337. {
  1338. reload();
  1339. });
  1340. }
  1341. }
  1342. // Regroup glossary and auto replace matched string
  1343. {
  1344. setTimeoutCustom(function()
  1345. {
  1346. var br = "<br>";
  1347. var brSpace = " <br> ";
  1348. var tag = "<a";
  1349. var colon = ">: ";
  1350. var comma = ",";
  1351. var bracket = " (";
  1352. var isEdit = false;
  1353. var p = null;
  1354. var aGls = document.querySelectorAll("a[href='glossary.php']");
  1355. for (var i = 0; i < aGls.length; i++)
  1356. {
  1357. if (aGls[i].textContent.trim() === "GLOSSARY FEATURE")
  1358. {
  1359. p = aGls[i].parentElement;
  1360. break;
  1361. }
  1362. }
  1363. if (p)
  1364. {
  1365. var glosOuters = [];
  1366. var glosInnerStart = 0;
  1367. var countGl = 0;
  1368. var glossaries = p.innerHTML.split(br);
  1369. if (glossaries.length > 2)
  1370. {
  1371. glosOuters = [p];
  1372. glosInnerStart = 2;
  1373. }
  1374. else
  1375. {
  1376. glosOuters = p.nextSibling.querySelectorAll("td");
  1377. glosInnerStart = 0;
  1378. }
  1379. var rgxKey = />[^><]+</;
  1380. var rgxKeyClean = /[><]+/g;
  1381. var rgxKeyPunct = /[\(\)\[\]\:\!]/g;
  1382. var rgxContentClean = /<[^<]*>/g;
  1383. var textOrg = "";
  1384. var textEng = "";
  1385. var isTextReplaced = false;
  1386. var isOutdated = false;
  1387.  
  1388. var eleBtnResummit = document.querySelector("input[type='submit'][value^='RESUBMIT']");
  1389. if (eleBtnResummit)
  1390. {
  1391. isTextReplaced = true;
  1392. }
  1393. else
  1394. {
  1395. var eleTextOrg = document.querySelector("#suggestion_value_new");
  1396. if (eleTextOrg)
  1397. {
  1398. textOrg = eleTextOrg.value.trim().toLowerCase();
  1399. }
  1400. if (textOrg === "" || textOrg.length > 300)
  1401. {
  1402. // Not replace on empty and long strings
  1403. isTextReplaced = true;
  1404. }
  1405. }
  1406. if (!isTextReplaced)
  1407. {
  1408. var eleTrs = document.querySelectorAll(".progress tr");
  1409. isOutdated = (eleTrs.length >= 3);
  1410. if (isOutdated)
  1411. {
  1412. textEng = eleTrs[eleTrs.length - 1].firstElementChild.textContent.trim().toLowerCase();
  1413. }
  1414. }
  1415. for (var i = 0; i < glosOuters.length; i++)
  1416. {
  1417. var glosOuter = glosOuters[i];
  1418. var glosInners = glosOuter.innerHTML.split(br);
  1419. isEdit = false;
  1420. for (var j = glosInnerStart; j < glosInners.length; j++)
  1421. {
  1422. var glossary = glosInners[j].trim();
  1423. if (glossary.length > 0 && glossary.indexOf(tag) === 0)
  1424. {
  1425. var colonIndex = glossary.indexOf(colon);
  1426. var contentHead = glossary.substr(0, colonIndex + 3);
  1427. var contentAll = glossary.substr(colonIndex + 3);
  1428. var contentWords = contentAll.split(comma);
  1429. var contentFirst = contentWords[0].trim();
  1430. for (var k = 0; k < contentWords.length; k++)
  1431. {
  1432. var contentNew = contentWords[k].trim();
  1433. var contentSub = null;
  1434. var bracketPos = contentNew.indexOf(" (");
  1435. if (bracketPos > -1)
  1436. {
  1437. contentSub = contentNew.substr(bracketPos);
  1438. contentNew = contentNew.substr(0, bracketPos);
  1439. }
  1440. contentNew = " <span id='stsh_gls_" + countGl
  1441. + "' onclick='clickToSelect(this)'>"
  1442. + contentNew + "</span>";
  1443. //+ "<span style='color: white; cursor: pointer;'>^</span>";
  1444. if (contentSub)
  1445. {
  1446. contentNew += "<span "
  1447. + "onclick='clickToSelect(this.previousElementSibling)'>"
  1448. + contentSub + "</span>";
  1449. }
  1450. contentWords[k] = contentNew;
  1451. countGl++;
  1452. }
  1453. if (!isTextReplaced)
  1454. {
  1455. var keys = contentHead.match(rgxKey);
  1456. if (keys && keys.length > 0)
  1457. {
  1458. var key = keys[0].replace(rgxKeyClean, "").trim().toLowerCase();
  1459. var contentClean = contentFirst.replace(rgxContentClean, "");
  1460. var contentLower = contentClean.toLowerCase();
  1461. var textCur = "";
  1462. if (key === textOrg.replace(rgxKeyPunct, ""))
  1463. {
  1464. textCur = textOrg;
  1465. }
  1466. else if (key === textEng.replace(rgxKeyPunct, ""))
  1467. {
  1468. textCur = textEng;
  1469. }
  1470. if (textCur !== "" && key !== contentLower)
  1471. {
  1472. var rgxReplace = new RegExp(key, "i");
  1473. eleTextOrg.value = textCur.replace(rgxReplace, contentClean);
  1474. //console.log("Replaced: " + eleTextOrg.value);
  1475. isTextReplaced = true;
  1476. }
  1477. }
  1478. }
  1479. glosInners[j] = contentHead + contentWords.join(comma);
  1480. isEdit = true;
  1481. }
  1482. }
  1483. if (isEdit && false)
  1484. {
  1485. // old feature
  1486. glosOuter.innerHTML = glosInners.join(brSpace);
  1487. }
  1488. }
  1489. }
  1490. }, 200);
  1491. }
  1492. // Insert clicked word in last textarea
  1493. {
  1494. var eleTextLast = null;
  1495. if (document.activeElement && document.activeElement.tagName === "TEXTAREA")
  1496. {
  1497. eleTextLast = document.activeElement;
  1498. }
  1499. var elesText = document.querySelectorAll
  1500. (" \
  1501. textarea#suggestion_value_new \
  1502. , textarea[name='suggestion_comment'] \
  1503. , textarea#add_to_discussion \
  1504. , textarea[name^='autoreplace'] \
  1505. ");
  1506. for (var i = 0; i < elesText.length; i++)
  1507. {
  1508. elesText[i].addEventListener('focus', function(ev)
  1509. {
  1510. eleTextLast = ev.target;
  1511. });
  1512. }
  1513. setTimeoutCustom(function()
  1514. {
  1515. var elesInsert = document.querySelectorAll(".insertword");
  1516. for (var i = 0; i < elesInsert.length; i++)
  1517. {
  1518. removeAllEventListeners(elesInsert[i]);
  1519. }
  1520. function insertAtCaret(txtarea, text)
  1521. {
  1522. // Edit from STS
  1523. var scrollPos = txtarea.scrollTop;
  1524. var strPos = 0;
  1525. var strLength = 0;
  1526. var br = ((txtarea.selectionStart || txtarea.selectionStart === 0) ? "ff" : (document.selection ? "ie" : false));
  1527. if (br === "ie")
  1528. {
  1529. txtarea.focus();
  1530. var range = document.selection.createRange();
  1531. range.moveStart('character', -txtarea.value.length);
  1532. strPos = range.text.length;
  1533. }
  1534. else if (br === "ff")
  1535. {
  1536. strPos = txtarea.selectionStart;
  1537. strLength = txtarea.selectionEnd - txtarea.selectionStart;
  1538. }
  1539. var front = (txtarea.value).substring(0, strPos);
  1540. var back = (txtarea.value).substring(strPos + strLength, txtarea.value.length);
  1541. txtarea.value = front + text + back;
  1542. strPos = strPos + text.length;
  1543. if (br === "ie")
  1544. {
  1545. txtarea.focus();
  1546. var range = document.selection.createRange();
  1547. range.moveStart('character', -txtarea.value.length);
  1548. range.moveStart('character', strPos);
  1549. range.moveEnd('character', 0);
  1550. range.select();
  1551. }
  1552. else if (br === "ff")
  1553. {
  1554. txtarea.selectionStart = strPos;
  1555. txtarea.selectionEnd = strPos;
  1556. txtarea.focus();
  1557. }
  1558. txtarea.scrollTop = scrollPos;
  1559. }
  1560. elesInsert = document.querySelectorAll(".insertword");
  1561. for (var i = 0; i < elesInsert.length; i++)
  1562. {
  1563. //elesInsert[i].classList.add("stsh_unselectable");
  1564. elesInsert[i].addEventListener("click", function(ev)
  1565. {
  1566. if (eleTextLast)
  1567. {
  1568. insertAtCaret(eleTextLast , ev.target.textContent.trim());
  1569. }
  1570. });
  1571. }
  1572. }, 500);
  1573. }
  1574. // Restyle glossary
  1575. {
  1576. var eleP = null;
  1577. var elesA = document.querySelectorAll("a[href='glossary.php']");
  1578. for (var i = 0; i < elesA.length; i++)
  1579. {
  1580. if (elesA[i].textContent.trim() === "GLOSSARY FEATURE")
  1581. {
  1582. eleP = elesA[i].parentElement;
  1583. break;
  1584. }
  1585. }
  1586. if (eleP)
  1587. {
  1588. var nodeText = eleP.firstElementChild.nextSibling;
  1589. if (nodeText.nodeType === document.TEXT_NODE)
  1590. {
  1591. var ele = document.createElement("span");
  1592. ele.textContent = nodeText.textContent;
  1593. nodeText.parentElement.removeChild(nodeText);
  1594. insertAfterElement(ele, eleP.firstElementChild);
  1595. }
  1596. var eleHead;
  1597. if (eleP.nextElementSibling.tagName === "TABLE")
  1598. {
  1599. eleHead = eleP.nextElementSibling;
  1600. }
  1601. else
  1602. {
  1603. eleHead = eleP;
  1604. }
  1605. eleHead.classList.add("stsh_glossary_header");
  1606. var elesTerm = eleHead.querySelectorAll("a[href*='://translation.steampowered.com/translate.php?search_input=']");
  1607. for (var i = 0; i < elesTerm.length; i++)
  1608. {
  1609. elesTerm[i].classList.add("stsh_glossary_term");
  1610. }
  1611. {
  1612. var eleSpan = null;
  1613. if (eleHead.tagName === "TABLE")
  1614. {
  1615. eleSpan = eleHead.previousElementSibling.querySelector("span");
  1616. }
  1617. else
  1618. {
  1619. eleSpan = eleHead.querySelector("span");
  1620. }
  1621. eleSpan.textContent = eleSpan.textContent.replace("(click to copy to top)", "(click to copy to suggestion or comment)");
  1622. }
  1623. }
  1624. }
  1625. // Auto link http
  1626. // Format comment
  1627. {
  1628. var countSugStatus = document.querySelectorAll(
  1629. ".suggestions_list span[class^='suggestion_status_']").length;
  1630. var rgxUrl = /http[^ "]+/ig;
  1631. var rgxHostUrl = /^https?:\/\/translation\.steampowered\.com\//i;
  1632. var hostReplace = "/";
  1633. var eleComments = document.querySelectorAll
  1634. (" \
  1635. .suggestion_signature > i:nth-child(3) \
  1636. , .suggestion_signature div:nth-child(1) > i:nth-child(4) \
  1637. , .suggestion_signature div:nth-child(1) > i:nth-child(6) \
  1638. , *[class^='row'] > td:nth-child(2) \
  1639. ");
  1640. for (var i = 0; i < eleComments.length; i++)
  1641. {
  1642. var comment = eleComments[i].innerHTML + " ";
  1643. if (comment.indexOf("<a") === -1)
  1644. {
  1645. var commentUrls = comment.match(rgxUrl) || [];
  1646. for (var j = 0; j < commentUrls.length; j++)
  1647. {
  1648. var urlDecode = commentUrls[j];
  1649. try
  1650. {
  1651. urlDecode = decodeURIComponent(commentUrls[j])
  1652. .replace(/#/g, "%23").replace(/&amp;/g, "&");
  1653. //console.log(urlDecode);
  1654. if (countSugStatus === 0 && rgxHostUrl.test(urlDecode))
  1655. {
  1656. var query = getQueryByName("search_input", urlDecode);
  1657. if (query !== "")
  1658. {
  1659. urlDecode = query;
  1660. }
  1661. else
  1662. {
  1663. urlDecode = urlDecode.replace(rgxHostUrl, hostReplace);
  1664. }
  1665. }
  1666. }
  1667. catch (ex)
  1668. {
  1669. console.error("FormatComment", ex.message);
  1670. }
  1671. var commentUrl = commentUrls[j] + " ";
  1672. comment = comment.replace(commentUrl, "<a target='_blank' href='"
  1673. + commentUrls[j] + "' >" + urlDecode + "</a> ");
  1674. }
  1675. }
  1676. comment = comment.trim();
  1677. if (comment.indexOf("Comment:") === 0)
  1678. {
  1679. eleComments[i].classList.add("stsh_text_comment_header");
  1680. comment = comment
  1681. .replace("Comment:", "Comment: <span class='stsh_text_comment'>")
  1682. .replace(/\/ /g, "<span class='stsh_white stsh_pad'>/</span> ")
  1683. .replace(/ \//g, " <span class='stsh_white stsh_pad'>/</span>")
  1684. .replace(/\-\&gt\;/g, "<span class='stsh_white stsh_pad'>-&gt;</span>")
  1685. .replace(/\-\-/g, "<span class='stsh_white stsh_pad'>--</span>")
  1686. .replace(/\, /g, "<span class='stsh_white stsh_pad'>, </span>")
  1687. .replace(/\* /g, "<span class='stsh_white stsh_pad'><br>* </span>")
  1688. + "</span>";
  1689. }
  1690. eleComments[i].innerHTML = comment;
  1691. var eleAs = eleComments[i].querySelectorAll("a");
  1692. for (var j = 0; j < eleAs.length; j++)
  1693. {
  1694. var href = eleAs[j].getAttribute("href");
  1695. if (href.indexOf("#") > -1)
  1696. {
  1697. eleAs[j].setAttribute("href", href.replace(/\#/g,"%23"));
  1698. }
  1699. }
  1700. //if (comment.indexOf("Comment:") !== 0)
  1701. {
  1702. // Discussion comment
  1703. var rgxImg = /(\.(jpg|png|gif)|\/ugc\/)/i;
  1704. var rgxLongUrl = /^https?\:\/\/translation\.steampowered\.com\/translate\.php\?search_input\=/i;
  1705. var elesA = eleComments[i].querySelectorAll("a");
  1706. for (var j = 0; j < elesA.length; j++)
  1707. {
  1708. var href = elesA[j].getAttribute("href");
  1709. if (rgxImg.test(href))
  1710. {
  1711. if (elesA[j].querySelectorAll("img").length === 0)
  1712. {
  1713. var ele = document.createElement("img");
  1714. ele.classList.add("stsh_comment_img");
  1715. ele.setAttribute("src", href);
  1716. ele.setAttribute("title", href);
  1717. ele.setAttribute("onclick",
  1718. " \
  1719. if (this.style.minWidth !== '850px') \
  1720. { \
  1721. this.style.minWidth = this.naturalWidth < 850 ? this.naturalWidth + 'px' : '850px'; \
  1722. } \
  1723. else \
  1724. { \
  1725. this.style.minWidth = '400px'; \
  1726. } \
  1727. ");
  1728. insertAfterElement(ele, elesA[j]);
  1729. }
  1730. }
  1731. else
  1732. {
  1733. var content = elesA[j].textContent;
  1734. if (rgxLongUrl.test(content))
  1735. {
  1736. elesA[j].textContent = content.replace(rgxLongUrl, "").replace(/\+/g, " ");
  1737. }
  1738. }
  1739. }
  1740. }
  1741. }
  1742. }
  1743. // Restyle token info
  1744. {
  1745. var divIntro = document.querySelector("#suggestionmain > div.smallcopy");
  1746. if (divIntro)
  1747. {
  1748. var qBranch = getQueryByName("branch");
  1749. var htmlEdit = "You are editing";
  1750. var htmlEditReplace = "";
  1751. var htmlToken = "Token <";
  1752. var htmlTokenReplace = "Token: <";
  1753. var htmlToken2 = "token-key";
  1754. var htmlToken2Replace = "Token";
  1755. var htmlLiveLinkMoved =
  1756. '\
  1757. <font style="color:red;">This FAQ likely does not exist anymore!</font>\
  1758. The generated <a href="https://support.steampowered.com/kb_article.php?ref="\
  1759. target="_blank">live link</a> seems dead or is redirecting.\
  1760. ';
  1761. var htmlLiveLinkMovedReplace =
  1762. '\
  1763. <font style="color:red; cursor: help;"\
  1764. title="The generated live link seems dead or is redirecting.">\
  1765. This FAQ likely does not exist anymore!</font>\
  1766. ';
  1767. var htmlLiveLinkMovedWithLiveLink =
  1768. '\
  1769. <font style="color:red;">This FAQ likely does not exist anymore!</font> The generated \
  1770. <a href="https://support.steampowered.com/kb_article.php?ref=\
  1771. ';
  1772. var htmlLiveLinkMovedWithLiveLinkReplace =
  1773. '<a href="https://support.steampowered.com/kb_article.php?ref=';
  1774. var htmlLiveLinkMovedWithLiveLink2 =
  1775. '" target="_blank">live link</a> seems dead or is redirecting.';
  1776. var htmlLiveLinkMovedWithLiveLink2Replace =
  1777. '\
  1778. " target="_blank">Live link</a> - \
  1779. <font style="color:red; cursor: help;"\
  1780. title="The generated live link seems dead or is redirecting.">\
  1781. This FAQ likely does not exist anymore!</font>';
  1782. var htmlLiveLink = 'target="_blank">Live link';
  1783. var htmlLiveLinkReplace = 'target="_blank">Live link'; // Change in condition
  1784. var htmlFile = " of <";
  1785. var htmlFileReplace =
  1786. ' <br>File: <font class="stsh_info_file stsh_blue" onclick="clickToSelect(this)">' + qBranch + '</font> >> <';
  1787. var htmlFrom = "<br>Added on <";
  1788. var htmlFromReplace = " &nbsp;&nbsp;Added: <";
  1789. var htmlUpdated = ">. Updated on <";
  1790. var htmlUpdatedReplace = "> &nbsp;&nbsp;Updated: <";
  1791. var htmlUpdated2 = "<br> Updated on <";
  1792. var htmlUpdated2Replace = " &nbsp;&nbsp;Updated: <";
  1793. var htmlSugg = 'You have <font style="';
  1794. var htmlSuggReplace =
  1795. 'You have <font title="Enter and submit new suggestions below. Do not alter HTML tags or variables." style="cursor: help; ';
  1796. var htmlIntro =
  1797. "Enter and submit new suggestions below. Do not alter HTML tags or variables.";
  1798. var htmlIntroReplace =
  1799. ' \
  1800. &nbsp;&nbsp;\
  1801. <a href="mailto:translationserver@valvesoftware.com" \
  1802. title="Please report token issues by posting a TOKEN DISCUSSION \r\nor email to translationserver@valvesoftware.com" \
  1803. style="cursor: help; ">\
  1804. <font style="color:white;">Report Tokens</font></a>\
  1805. ';
  1806. var htmlContact =
  1807. '\
  1808. <br>Please report token issues by posting a <font style="color:#a4b23c;">TOKEN DISCUSSION</font> tagged\
  1809. <input style="border:none; color:#FFFFFF; background-color:#111111; cursor:pointer;"\
  1810. onclick="tosts(\'truncated\')" value="[sts_admin][truncated]" type="button">or\
  1811. <input style="border:none; color:#FFFFFF; background-color:#111111; cursor:pointer;"\
  1812. onclick="tosts(\'typo\');" value="[sts_admin][typo]" type="button">or\
  1813. <input style="border:none; color:#FFFFFF; background-color:#111111; cursor:pointer;"\
  1814. onclick="tosts(\'unlockpls\')" value="[sts_admin][unlockpls]" type="button">or by \
  1815. <a href="mailto:translationserver@valvesoftware.com">email</a>.\
  1816. ';
  1817. var htmlContactReplace = '';
  1818. var htmlContact2 =
  1819. '\
  1820. <br>Please report token issues by posting a <font style="color:#a4b23c;">TOKEN DISCUSSION</font> tagged\
  1821. <input style="border:none; color:#FFFFFF; background-color:#111111; cursor:pointer;" type="button"\
  1822. onclick="tosts(\'truncated\')" value="[sts_admin][truncated]">or\
  1823. <input style="border:none; color:#FFFFFF; background-color:#111111; cursor:pointer;" type="button"\
  1824. onclick="tosts(\'typo\');" value="[sts_admin][typo]">or\
  1825. <input style="border:none; color:#FFFFFF; background-color:#111111; cursor:pointer;" type="button"\
  1826. onclick="tosts(\'unlockpls\')" value="[sts_admin][unlockpls]">or by \
  1827. <a href="mailto:translationserver@valvesoftware.com">email</a>.\
  1828. ';
  1829. var htmlContact2Replace = '';
  1830. var rgxTestEmail =
  1831. /<br><font style="color:#a4b23c;">This is part of email message .+ - you can test it by following this link:<\/font> /i;
  1832. var htmlTestEmailReplace = '';
  1833. var rgxTestEmail2 =
  1834. /<a href="test_email\.php\?filename=.+\&amp;lang=[a-z]+" target="_blank">Test<\/a>/i;
  1835. var htmlTestEmail2Replace = '';
  1836. var htmlsTestEmail = rgxTestEmail.exec(divIntro.innerHTML);
  1837. if (htmlsTestEmail)
  1838. {
  1839. var htmlTestEmail = htmlsTestEmail[0]
  1840. .replace('<br><font style="color:#a4b23c;">This is part of email message ', "")
  1841. .replace(' - you can test it by following this link:</font> ', "");
  1842. var htmlTestEmail2 = "";
  1843. var htmlsTestEmail2 = rgxTestEmail2.exec(divIntro.innerHTML);
  1844. if (htmlsTestEmail2)
  1845. {
  1846. htmlTestEmail2 = htmlsTestEmail2[0].replace('<a href="', "")
  1847. .replace('" target="_blank">Test</a>', "");
  1848. }
  1849. htmlIntroReplace += ' &nbsp;&nbsp;Test: <a href="' + htmlTestEmail2
  1850. + '" title="You can test email by following this link." target="_blank">'
  1851. + htmlTestEmail + '</a>';
  1852. }
  1853. if (key !== "")
  1854. {
  1855. htmlIntroReplace +=
  1856. ' \
  1857. <br>Share: \
  1858. <font class="stsh_token_share stsh_green stsh_truncate" onclick="clickToSelect(this)">\
  1859. https://translation.steampowered.com/translate.php?search_input=' + key + '\
  1860. </font> <br>\
  1861. ';
  1862. }
  1863. var urlLiveLink = "https://support.steampowered.com/kb_article.php?ref=";
  1864. var eleLiveLink = divIntro.querySelector("a[href^='" + urlLiveLink + "']");
  1865. if (eleLiveLink)
  1866. {
  1867. htmlLiveLinkReplace = 'target="_blank" title="Live link">'
  1868. + eleLiveLink.getAttribute("href").replace(urlLiveLink, "");
  1869. }
  1870. var isComplete = (divIntro.innerHTML.indexOf(htmlContact) > -1);
  1871. divIntro.innerHTML = divIntro.innerHTML
  1872. .replace(htmlEdit, htmlEditReplace)
  1873. .replace(htmlToken, htmlTokenReplace)
  1874. .replace(htmlToken2, htmlToken2Replace)
  1875. .replace(htmlLiveLinkMoved, htmlLiveLinkMovedReplace)
  1876. .replace(htmlLiveLinkMovedWithLiveLink, htmlLiveLinkMovedWithLiveLinkReplace)
  1877. .replace(htmlLiveLinkMovedWithLiveLink2, htmlLiveLinkMovedWithLiveLink2Replace)
  1878. .replace(htmlLiveLink, htmlLiveLinkReplace)
  1879. .replace(htmlFile, htmlFileReplace)
  1880. .replace(htmlFrom, htmlFromReplace)
  1881. .replace(htmlUpdated, htmlUpdatedReplace)
  1882. .replace(htmlUpdated2, htmlUpdated2Replace)
  1883. .replace(htmlSugg, htmlSuggReplace)
  1884. .replace(htmlIntro, htmlIntroReplace)
  1885. .replace(htmlContact, htmlContactReplace)
  1886. .replace(htmlContact2, htmlContact2Replace)
  1887. .replace(rgxTestEmail, htmlTestEmailReplace)
  1888. .replace(rgxTestEmail2, htmlTestEmail2Replace)
  1889. .trim();
  1890. var eleToken = document.querySelector("a[href^='Us_And_Them.php?']");
  1891. if (eleToken)
  1892. {
  1893. if (eleToken.textContent !== "Token")
  1894. {
  1895. eleToken.classList.add("stsh_token_name");
  1896. eleToken.classList.add("stsh_truncate");
  1897. }
  1898. }
  1899. if (!isComplete)
  1900. {
  1901. var stsh_introReplace_start = new Date();
  1902. var stsh_introReplace_itv = setIntervalCustom(function(params)
  1903. {
  1904. var divIntro = params[0];
  1905. var htmlContact = params[1];
  1906. var htmlContactReplace = params[2];
  1907. var stsh_introReplace_isEnd = false;
  1908. var stsh_introReplace_cur = new Date();
  1909. if (divIntro.innerHTML.indexOf(htmlContact) > -1)
  1910. {
  1911. divIntro.innerHTML = divIntro.innerHTML
  1912. .replace(htmlContact, htmlContactReplace);
  1913. stsh_introReplace_isEnd = true;
  1914. }
  1915. if (stsh_introReplace_isEnd || stsh_introReplace_cur - stsh_introReplace_start > 10000)
  1916. {
  1917. clearInterval(stsh_introReplace_itv);
  1918. }
  1919. }, 100, [divIntro, htmlContact, htmlContactReplace]);
  1920. }
  1921. }
  1922. }
  1923. // Restyle token discussion
  1924. {
  1925. var eleDiscuss = document.querySelector("a[name='tokendiscussion']");
  1926. if (eleDiscuss)
  1927. {
  1928. var htmlHeader = "TOKEN DISCUSSION (keep global comments English please!):";
  1929. var htmlHeaderReplace = "TOKEN DISCUSSION:";
  1930. var eleHeader = eleDiscuss.nextElementSibling;
  1931. if (eleHeader)
  1932. {
  1933. eleHeader.setAttribute("title", "Keep global comments English please!");
  1934. eleHeader.style.cursor = "help";
  1935. eleHeader.textContent = eleHeader.textContent.replace(htmlHeader, htmlHeaderReplace);
  1936. }
  1937. var eleParent = eleDiscuss.parentElement;
  1938. eleParent.classList.add("stsh_discussion_header");
  1939. if (eleParent.nextElementSibling)
  1940. {
  1941. eleParent.nextElementSibling.classList.add("stsh_discussion_section");
  1942. }
  1943. var elesInput = document.querySelectorAll("input[value='[stsadmin]']");
  1944. if (elesInput.length === 2)
  1945. {
  1946. elesInput[1].parentElement.removeChild(elesInput[1]);
  1947. }
  1948. var eleSpan = document.createElement("span");
  1949. eleSpan.innerHTML =
  1950. '\
  1951. <input style="border:none; color:#888888; background-color:#111111; cursor:pointer;"\
  1952. onclick="tosts(\'truncated\')" value="[sts_admin][truncated]" type="button">\
  1953. <input style="border:none; color:#888888; background-color:#111111; cursor:pointer;"\
  1954. onclick="tosts(\'typo\');" value="[sts_admin][typo]" type="button">\
  1955. <input style="border:none; color:#888888; background-color:#111111; cursor:pointer;"\
  1956. onclick="tosts(\'unlockpls\')" value="[sts_admin][unlockpls]" type="button">\
  1957. ';
  1958. eleParent.appendChild(eleSpan);
  1959. var eleCopy = document.querySelector("#autocopy");
  1960. if (eleCopy)
  1961. {
  1962. eleCopy.previousElementSibling.classList.add("stsh_autoCopy_header");
  1963. }
  1964. var eleFriendDiscuss = document.querySelector(".friend_block_discussions");
  1965. if (eleFriendDiscuss)
  1966. {
  1967. if (eleCopy)
  1968. {
  1969. insertBeforeElement(document.createElement("br"), eleCopy.previousElementSibling);
  1970. }
  1971. var eleTableDiscuss = eleFriendDiscuss.parentElement.parentElement.parentElement.parentElement;
  1972. if (eleTableDiscuss.tagName === "TABLE")
  1973. {
  1974. eleTableDiscuss.classList.add("stsh_discussion_table");
  1975. //insertBeforeElement(eleTableDiscuss, eleTableDiscuss.previousElementSibling.previousElementSibling);
  1976. }
  1977. }
  1978. }
  1979. }
  1980. // Move up glossary
  1981. {
  1982. var eleFriendDiscuss = document.querySelector(".friend_block_discussions");
  1983. if (!eleFriendDiscuss)
  1984. {
  1985. var eleDiscuss = document.querySelector(".stsh_discussion_header");
  1986. if (eleDiscuss)
  1987. {
  1988. var eleGlosGroup = document.createElement("div");
  1989. eleGlosGroup.classList.add("stsh_glossary_group");
  1990. insertBeforeElement(eleGlosGroup, eleDiscuss);
  1991. var eleHead = document.querySelector(".stsh_glossary_header");
  1992. if (eleHead)
  1993. {
  1994. if (!(eleHead.childNodes.length === 5
  1995. && eleHead.childNodes[4].nodeType === document.TEXT_NODE
  1996. && eleHead.childNodes[4].nodeValue === "No results"))
  1997. {
  1998. eleGlosGroup.appendChild(document.createElement("br"));
  1999. if (eleHead.tagName === "TABLE")
  2000. {
  2001. eleGlosGroup.appendChild(eleHead.previousElementSibling);
  2002. }
  2003. else
  2004. {
  2005. insertAfterElement(document.createElement("br"), eleHead);
  2006. }
  2007. eleGlosGroup.appendChild(eleHead);
  2008. var eleCopy = document.querySelector(".stsh_autoCopy_header");
  2009. if (eleCopy)
  2010. {
  2011. insertBeforeElement(document.createElement("br"), eleCopy);
  2012. }
  2013. }
  2014. }
  2015. }
  2016. }
  2017. }
  2018. // Add shortcut keys
  2019. {
  2020. var elesNext = document.querySelectorAll(".suggestion_signature input[value~='Next']");
  2021. for (var i = 0; i < elesNext.length; i++)
  2022. {
  2023. elesNext[i].value = "Next";
  2024. }
  2025. var elesForm = document.querySelectorAll(".lbAction");
  2026. for (var i = 0; i < elesForm.length; i++)
  2027. {
  2028. var eleForm = elesForm[i];
  2029. var eleSubmit = eleForm.querySelector("input[type=submit]");
  2030. if (eleSubmit)
  2031. {
  2032. addKeyCtrlEnter(eleForm, eleSubmit);
  2033. }
  2034. }
  2035. var elesInputApprove = document.querySelectorAll(".suggestion_signature input[value~='APPROVE']");
  2036. if (elesInputApprove.length > 0)
  2037. {
  2038. var eleBind = elesInputApprove[0];
  2039. addKeyAlt(document, eleBind, 219); // [
  2040. addKeyAlt(document, eleBind, "BracketLeft"); // [
  2041. addKeyAlt(document, eleBind, 79); // O
  2042. addKeyAlt(document, eleBind, 65); // A
  2043. disableAfterClick(eleBind);
  2044. }
  2045. var eleInputApproveNext = document.querySelector(".suggestion_signature input[value~='Next']");
  2046. if (eleInputApproveNext)
  2047. {
  2048. var eleBind = null;
  2049. if (!eleInputApproveNext.disabled)
  2050. {
  2051. // Can go next
  2052. if (elesInputApprove.length === 1)
  2053. {
  2054. // Go next if only 1 suggestion
  2055. eleBind = eleInputApproveNext;
  2056. }
  2057. else if (elesInputApprove.length > 1)
  2058. {
  2059. // Only approve if more than 1 suggestion
  2060. eleBind = elesInputApprove[0];
  2061. }
  2062. }
  2063. else
  2064. {
  2065. // Can't go next
  2066. if (elesInputApprove.length > 0)
  2067. {
  2068. var eleBind = elesInputApprove[0];
  2069. }
  2070. }
  2071. if (eleBind)
  2072. {
  2073. addKeyAlt(document, eleBind, 221); // ]
  2074. addKeyAlt(document, eleBind, "BracketRight"); // ]
  2075. addKeyAlt(document, eleBind, 80); // P
  2076. addKeyAlt(document, eleBind, 83); // S
  2077. addKeyCtrl(document, eleBind, 220); // Backslash
  2078. addKeyCtrl(document, eleBind, "Backslash"); // Backslash
  2079. addKeyCtrl(document, eleBind, 45, "Ins", 1|2); // INS
  2080. disableAfterClick(eleBind);
  2081. }
  2082. }
  2083. var eleInputDecline = document.querySelector(".suggestion_signature input[value~='DECLINE']");
  2084. if (eleInputDecline)
  2085. {
  2086. var eleBind = eleInputDecline;
  2087. addKeyCtrl(document, eleBind, 46, "Del", 1|2); // DEL
  2088. disableAfterClick(eleBind);
  2089. var eleInpueDeclineNext = eleInputDecline.nextElementSibling;
  2090. if (eleInpueDeclineNext && eleInpueDeclineNext.value.indexOf("Next") > -1
  2091. && !eleInpueDeclineNext.disabled)
  2092. {
  2093. var eleBind = eleInpueDeclineNext;
  2094. addKeyCtrlShift(document, eleBind, 46, "Del", 2); // DEL
  2095. disableAfterClick(eleBind);
  2096. }
  2097. }
  2098. else
  2099. {
  2100. var eleReconsider = document.querySelector(".suggestion_status_approved > a, .suggestion_status_declined > a");
  2101. if (eleReconsider)
  2102. {
  2103. if (eleReconsider.parentElement.classList.contains("suggestion_status_approved"))
  2104. {
  2105. var eleBind = eleReconsider;
  2106. addKeyCtrl(document, eleBind, 46, "Del", 2|16); // DEL
  2107. }
  2108. else
  2109. {
  2110. if (!eleReconsider.parentElement.parentElement
  2111. .querySelector(".suggestion_signature .lbAction[name^='mymodcomment']"))
  2112. {
  2113. var eleBind = eleReconsider;
  2114. addKeyAlt(document, eleBind, 221); // ]
  2115. addKeyAlt(document, eleBind, "BracketRight"); // ]
  2116. addKeyAlt(document, eleBind, 80); // P
  2117. addKeyAlt(document, eleBind, 83); // S
  2118. addKeyCtrl(document, eleBind, 220); // Backslash
  2119. addKeyCtrl(document, eleBind, "Backslash"); // Backslash
  2120. addKeyCtrl(document, eleBind, 45, "Ins", 2|16); // INS
  2121. }
  2122. }
  2123. }
  2124. }
  2125. var elesTextRemoveComment = document.querySelectorAll(".stsh_text_removeComment");
  2126. if (elesTextRemoveComment.length > 0)
  2127. {
  2128. // Remove last comment
  2129. var i = elesTextRemoveComment.length - 1;
  2130.  
  2131. var eleBind = elesTextRemoveComment[i];
  2132. addKeyCtrl(document, eleBind, 8, "Bksp", 2|16); // Backspace
  2133. }
  2134. var inputPrev = document.querySelector("#suggestions_nav > input[value^='Prev']");
  2135. if (inputPrev)
  2136. {
  2137. var eleBind = inputPrev;
  2138. addKeyCtrl(document, eleBind, 219, "[", 1|2); // [
  2139. addKeyCtrl(document, eleBind, "BracketLeft"); // [
  2140. disableAfterClick(eleBind);
  2141. }
  2142. var inputNext = document.querySelector("#suggestions_nav > input[value~='Next']");
  2143. if (inputNext)
  2144. {
  2145. var eleBind = inputNext;
  2146. addKeyCtrl(document, eleBind, 221, "]", 1|2); // ]
  2147. addKeyCtrl(document, eleBind, "BracketRight"); // ]
  2148. disableAfterClick(eleBind);
  2149. }
  2150. }
  2151. // Check special chars
  2152. {
  2153. var h1s = document.querySelectorAll(".progress h1");
  2154. if (h1s.length === 2)
  2155. {
  2156. var h1Org = h1s[0];
  2157. var h1Trn = h1s[1];
  2158. var tdOrg = eleTextOrg;
  2159. var tdTrn = eleTextTrn;
  2160. if (tdOrg && tdTrn)
  2161. {
  2162. var strOrg = trimSpace(tdOrg.textContent);
  2163. var strTrn = trimSpace(tdTrn.textContent);
  2164. var statusTrnArr = checkSpecialCharMatched(strOrg, strTrn);
  2165. var statusTrnMatched = statusTrnArr[0];
  2166. var spOrg = statusTrnArr[1];
  2167. var spTrn = statusTrnArr[2];
  2168. if (spOrg > 0)
  2169. {
  2170. var spanSpOrg = document.createElement("span");
  2171. spanSpOrg.id = "stsh_spanSpOrg";
  2172. spanSpOrg.classList.add("stsh_blue");
  2173. spanSpOrg.innerHTML = " SpecialChar: " + spOrg;
  2174. h1Org.parentElement.appendChild(spanSpOrg);
  2175. // Check chars in translated
  2176. if (strTrn !== "")
  2177. {
  2178. var spanSpTrn = document.createElement("span");
  2179. spanSpTrn.id = "stsh_spanSpTrn";
  2180. if (statusTrnMatched === 0)
  2181. {
  2182. spanSpTrn.classList.add("stsh_green");
  2183. }
  2184. else
  2185. {
  2186. spanSpTrn.classList.add("stsh_red");
  2187. }
  2188. var outputTrn = " SpecialChar: " + spTrn;
  2189. if (statusTrnMatched === 0)
  2190. {
  2191. outputTrn += " (Matched)";
  2192. }
  2193. else if (statusTrnMatched === 1)
  2194. {
  2195. outputTrn += " (Order not matched)";
  2196. }
  2197. else
  2198. {
  2199. outputTrn += " (Not matched)";
  2200. }
  2201. spanSpTrn.innerHTML = outputTrn;
  2202. h1Trn.parentElement.appendChild(spanSpTrn);
  2203. }
  2204. // Check chars in suggested
  2205. var divSugs = document.querySelectorAll(".suggestion_text");
  2206. for (var i = 0; i < divSugs.length; i++)
  2207. {
  2208. var divSug = divSugs[i];
  2209. var strSug = trimSpace(divSug.textContent);
  2210. var statusSugArr = checkSpecialCharMatched(strOrg, strSug);
  2211. var statusSugMatched = statusSugArr[0];
  2212. var spSug = statusSugArr[2];
  2213. var spanSpSug = document.createElement("span");
  2214. spanSpSug.classList.add("stsh_spanSpSug");
  2215. if (statusSugMatched === 0)
  2216. {
  2217. spanSpSug.classList.add("stsh_green");
  2218. }
  2219. else
  2220. {
  2221. spanSpSug.classList.add("stsh_red");
  2222. }
  2223. var outputSug = " SpecialChar: " + spSug;
  2224. if (statusSugMatched === 0)
  2225. {
  2226. outputSug += " (Matched)";
  2227. }
  2228. else if (statusSugMatched === 1)
  2229. {
  2230. outputSug += " (Order not matched)";
  2231. }
  2232. else
  2233. {
  2234. outputSug += " (Not matched)";
  2235. }
  2236. outputSug += " <br/><br/> ";
  2237. spanSpSug.innerHTML = outputSug;
  2238. divSug.insertBefore(spanSpSug, divSug.firstChild);
  2239. }
  2240. }
  2241. }
  2242. }
  2243. }
  2244. // Trim string in same token
  2245. {
  2246. var p = document.querySelector("#suggestionmain > div:nth-child(5) > p:nth-child(4)");
  2247. if (p)
  2248. {
  2249. for (var i = 0; i < p.childNodes.length; i++)
  2250. {
  2251. var child = p.childNodes[i];
  2252. if (child.nodeName === "#text")
  2253. {
  2254. child.nodeValue = child.nodeValue.trim();
  2255. }
  2256. }
  2257. }
  2258. }
  2259. // Display newlines
  2260. // Display specialChars
  2261. // Display HTML tags
  2262. {
  2263. if (eleTextOrg && eleTextTrn)
  2264. {
  2265. var htmlOrg = eleTextOrg.innerHTML.trim();
  2266. var htmlTrn = eleTextTrn.innerHTML.trim();
  2267. // Display newlines
  2268. if ((htmlOrg.indexOf("\n") > -1 || htmlOrg.indexOf("\\n") > -1
  2269. || htmlTrn.indexOf("\n") > -1 || htmlTrn.indexOf("\\n") > -1)
  2270. /*&& htmlOrg.indexOf("<br") < 0
  2271. && htmlOrg.indexOf("<p") < 0 && htmlOrg.indexOf("<div") < 0 && htmlOrg.indexOf("<li") < 0*/)
  2272. {
  2273. var h2SugHeader = document.querySelector("#suggestionmain > div > h2");
  2274. if (h2SugHeader)
  2275. {
  2276. var btn = document.createElement("input");
  2277. btn.id = "stsh_btn_displayNewlines";
  2278. btn.setAttribute("class", "stsh_btn_right");
  2279. btn.setAttribute("type", "button");
  2280. btn.setAttribute("value", "Display Newlines");
  2281. h2SugHeader.appendChild(btn);
  2282. function displayNewlines(ele)
  2283. {
  2284. if (ele)
  2285. {
  2286. ele.innerHTML = ele.innerHTML.trim()
  2287. .replace(/\n/g, "\n<br>")
  2288. .replace(/\\n/g, ' <span class="stsh_grey">\\n</span><br>')
  2289. .replace(/\\r \\n/g, ' <span class="stsh_grey">\\r\\n</span><br>')
  2290. .replace(/\<br\>[\s]+/g, "<br>&nbsp;");
  2291. }
  2292. }
  2293. btn.addEventListener("click", function(e)
  2294. {
  2295. e.target.disabled = true;
  2296. var eleBtnHtmlTags = document.querySelector("#stsh_btn_displayHtmlTags");
  2297. if (eleBtnHtmlTags)
  2298. {
  2299. eleBtnHtmlTags.disabled = true;
  2300. }
  2301. var tdOrg = document.querySelector(".stsh_text_org");
  2302. var tdTrn = document.querySelector(".stsh_text_trn");
  2303. displayNewlines(tdOrg);
  2304. displayNewlines(tdTrn);
  2305. var divSugs = document.querySelectorAll(".suggestion_text");
  2306. for (var i = 0; i < divSugs.length; i++)
  2307. {
  2308. var divSug = divSugs[i];
  2309. displayNewlines(divSug);
  2310. }
  2311. var textarea = document.querySelector("#suggestion_value_new");
  2312. if (textarea)
  2313. {
  2314. textarea.focus();
  2315. }
  2316. });
  2317. }
  2318. }
  2319. // Display specialChars
  2320. if (hasSpecialChar(htmlOrg) || hasSpecialChar(htmlTrn))
  2321. {
  2322. var h2SugHeader = document.querySelector("#suggestionmain > div > h2");
  2323. if (h2SugHeader)
  2324. {
  2325. var btn = document.createElement("input");
  2326. btn.id = "stsh_btn_displaySpecialChars";
  2327. btn.setAttribute("class", "stsh_btn_right");
  2328. btn.setAttribute("type", "button");
  2329. btn.setAttribute("value", "Display SpecialChars");
  2330. h2SugHeader.appendChild(btn);
  2331. function replaceSpecialChars(str, unicodeNumber)
  2332. {
  2333. var rgx = new RegExp("\\u" + padZeroHex(unicodeNumber, 4), "g");
  2334. return str.replace(rgx, '<span class="stsh_grey">[' + unicodeNumber + ']</span>');
  2335. }
  2336. function displaySpecialChars(ele)
  2337. {
  2338. if (ele)
  2339. {
  2340. var strInner = ele.innerHTML.trim();
  2341. for (var i = 0; i < 32; i++)
  2342. {
  2343. if (hasSpecialChar(strInner))
  2344. {
  2345. if (isSpecialChar(i))
  2346. {
  2347. strInner = replaceSpecialChars(strInner, i);
  2348. }
  2349. }
  2350. else
  2351. {
  2352. break;
  2353. }
  2354. }
  2355. ele.innerHTML = strInner;
  2356. }
  2357. }
  2358. btn.addEventListener("click", function(e)
  2359. {
  2360. e.target.disabled = true;
  2361. var tdOrg = document.querySelector(".stsh_text_org");
  2362. var tdTrn = document.querySelector(".stsh_text_trn");
  2363. displaySpecialChars(tdOrg);
  2364. displaySpecialChars(tdTrn);
  2365. var divSugs = document.querySelectorAll(".suggestion_text");
  2366. for (var i = 0; i < divSugs.length; i++)
  2367. {
  2368. var divSug = divSugs[i];
  2369. displaySpecialChars(divSug);
  2370. }
  2371. var textarea = document.querySelector("#suggestion_value_new");
  2372. if (textarea)
  2373. {
  2374. textarea.focus();
  2375. }
  2376. });
  2377. }
  2378. }
  2379. // Display HTML tags
  2380. if (htmlOrg.indexOf("<") > -1
  2381. || (htmlTrn.indexOf("<") > -1 && !eleTextTrn.querySelector("#stsh_moveSuggestionBox"))
  2382. || htmlOrg.indexOf("[/") > -1)
  2383. {
  2384. var h2SugHeader = document.querySelector("#suggestionmain > div > h2");
  2385. if (h2SugHeader)
  2386. {
  2387. var btn = document.createElement("input");
  2388. btn.id = "stsh_btn_displayHtmlTags";
  2389. btn.setAttribute("class", "stsh_btn_right");
  2390. btn.setAttribute("type", "button");
  2391. btn.setAttribute("value", "Display HTML tags");
  2392. btn.setAttribute("title"
  2393. , "Some closing tags and attributes are autogenerated by web browser. \nPlease use with care!");
  2394. h2SugHeader.appendChild(btn);
  2395. function displayHtmlTags(ele)
  2396. {
  2397. if (ele)
  2398. {
  2399. var isSkip = false;
  2400. var isBb = (ele.textContent.indexOf("[/") > -1);
  2401. if (ele.classList.contains("stsh_text_org"))
  2402. {
  2403. if (ele.querySelector("span[style='color:#ff0000;']"))
  2404. {
  2405. ele.innerHTML = ele.innerHTML.replace(/<[\/]?span[^>]*>/ig, "");
  2406. }
  2407. if (ele.querySelector("font[style='BACKGROUND-COLOR: blue']"))
  2408. {
  2409. ele.innerHTML = ele.innerHTML.replace(/<[\/]?font[^>]*>/ig, "");
  2410. }
  2411. }
  2412. else if (ele.classList.contains("stsh_text_trn"))
  2413. {
  2414. if (ele.querySelector("#stsh_moveSuggestionBox"))
  2415. {
  2416. isSkip = true;
  2417. }
  2418. else if (ele.querySelector("span[style='color:#ff0000;']"))
  2419. {
  2420. ele.innerHTML = ele.innerHTML.replace(/<[\/]?span[^>]*>/ig, "");
  2421. }
  2422. }
  2423. else if (ele.classList.contains("suggestion_text"))
  2424. {
  2425. if (ele.querySelector("span[style='color:red;']"))
  2426. {
  2427. ele.innerHTML = ele.innerHTML.replace(/<[\/]?span[^>]*>/ig, "");
  2428. }
  2429. if (ele.querySelector("font[face='Times New Roman']"))
  2430. {
  2431. ele.innerHTML = ele.innerHTML.replace(/<[\/]?font[^>]*>/ig, "");
  2432. }
  2433. }
  2434. if (!isSkip)
  2435. {
  2436. ele.textContent = ele.innerHTML.trim();
  2437. var newHtml = ele.innerHTML;
  2438. if (!isBb)
  2439. {
  2440. newHtml = newHtml
  2441. .replace(/&amp;/ig, "&")
  2442. .replace(/\n/ig, "\n<br>")
  2443. .replace(/&lt;/ig, '<span class="stsh_grey">&lt;')
  2444. .replace(/=""&gt;/ig, "&gt;")
  2445. .replace(/&gt;/ig, "&gt;</span>")
  2446. .replace(/br&gt;/ig, "br&gt;<br>")
  2447. .replace(/&lt;li/ig, "<br>&lt;li");
  2448. }
  2449. else
  2450. {
  2451. newHtml = newHtml
  2452. .replace(/\n/ig, "\n<br>")
  2453. .replace(/\[/ig, '<span class="stsh_grey">[')
  2454. .replace(/\]/ig, "]</span>");
  2455. }
  2456. ele.innerHTML = newHtml;
  2457. }
  2458. }
  2459. }
  2460. btn.addEventListener("click", function(e)
  2461. {
  2462. e.target.disabled = true;
  2463. var eleBtnNewlines = document.querySelector("#stsh_btn_displayNewlines");
  2464. if (eleBtnNewlines)
  2465. {
  2466. eleBtnNewlines.disabled = true;
  2467. }
  2468. var tdOrg = document.querySelector(".stsh_text_org");
  2469. var tdTrn = document.querySelector(".stsh_text_trn");
  2470. displayHtmlTags(tdOrg);
  2471. displayHtmlTags(tdTrn);
  2472. var divSugs = document.querySelectorAll(".suggestion_text");
  2473. for (var i = 0; i < divSugs.length; i++)
  2474. {
  2475. var divSug = divSugs[i];
  2476. displayHtmlTags(divSug);
  2477. }
  2478. var textarea = document.querySelector("#suggestion_value_new");
  2479. if (textarea)
  2480. {
  2481. textarea.focus();
  2482. }
  2483. });
  2484. }
  2485. }
  2486. }
  2487. }
  2488. // Open comment when decline
  2489. // Paste last comment
  2490. {
  2491. var countComment = 0;
  2492. var elesComment = [];
  2493. var countSug = document.querySelectorAll(".suggestions_list .suggestion").length;
  2494. if (countSug > 0)
  2495. {
  2496. var textOrg = "";
  2497. if (eleTextOrg)
  2498. {
  2499. textOrg = trimSpace(eleTextOrg.innerHTML).substr(0, 1000).toLowerCase();
  2500. }
  2501. var isSameTextOrg = textOrg === GM_getValue("textLastOrg_Comment", "");
  2502. var textLastCur = GM_getValue("textLastCur_Comment", "");
  2503. var isSetComment = false;
  2504. var countSugDeclined = document.querySelectorAll(
  2505. ".suggestions_list span[class='suggestion_status_declined']").length;
  2506. if (countSug !== countSugDeclined)
  2507. {
  2508. var elesSugCheck = document.querySelectorAll(".suggestions_list span[class^='suggestion_status_']");
  2509. if (countSug === elesSugCheck.length)
  2510. {
  2511. var eleSugDeclined = document.querySelector(".suggestions_list span[class='suggestion_status_declined']");
  2512. if (eleSugDeclined && eleSugDeclined === elesSugCheck[0] && eleSugDeclined.querySelector("a"))
  2513. {
  2514. countSugDeclined = countSug;
  2515. }
  2516. }
  2517. }
  2518. if (countSug === countSugDeclined)
  2519. {
  2520. var elesSugA = document.querySelectorAll(".suggestions_list span[class^='suggestion_status_'] a");
  2521. for (var i = 0; i < elesSugA.length; i++)
  2522. {
  2523. var eleComment = elesSugA[i].parentElement.parentElement.nextSibling;
  2524. if (eleComment.nodeName === "DIV" && eleComment.classList.contains("copy"))
  2525. {
  2526. if (elesSugA[i].parentElement.classList.contains("suggestion_status_declined"))
  2527. {
  2528. countComment++;
  2529. elesComment.push(eleComment);
  2530. }
  2531. }
  2532. }
  2533. if (countComment === elesSugA.length)
  2534. {
  2535. var isFocus = false;
  2536. for (var i = 0; i < elesComment.length; i++)
  2537. {
  2538. elesComment[i].style.display = "block";
  2539. if (!isFocus)
  2540. {
  2541. var eleTxt = elesComment[i].querySelector("textarea[name='suggestion_comment']");
  2542. if (eleTxt)
  2543. {
  2544. eleTxt.focus();
  2545. // Auto paste last comment
  2546. {
  2547. if (isSameTextOrg)
  2548. {
  2549. if (textLastCur !== "")
  2550. {
  2551. eleTxt.value = textLastCur;
  2552. isSetComment = true;
  2553. }
  2554. setTimeoutCustom(function(ele)
  2555. {
  2556. // paste again after script ran
  2557. if (ele)
  2558. {
  2559. var textLastCur = GM_getValue("textLastCur_Comment", "");
  2560. if (textLastCur !== "")
  2561. {
  2562. ele.value = textLastCur;
  2563. //ele.selectionStart = 0;
  2564. //ele.selectionEnd = ele.value.length;
  2565. }
  2566. }
  2567. }, 250, eleTxt);
  2568. }
  2569. }
  2570. /*
  2571. // Typonion
  2572. var eleSugOuter = elesComment[i].parentElement.parentElement.parentElement.parentElement;
  2573. if (eleSugOuter.classList.contains("suggestion"))
  2574. {
  2575. var eleOnion = eleSugOuter.querySelector(".suggestion_text font[style='color:#01ec00;']");
  2576. if (eleOnion)
  2577. {
  2578. eleTxt.value = "onion";
  2579. }
  2580. }
  2581. */
  2582. var eleSugComment = elesComment[i].parentElement
  2583. .parentElement.parentElement.querySelector(".stsh_text_comment font");
  2584. if (eleSugComment && eleSugComment.textContent.trim() ==
  2585. "ATTENTION - English string was updated. This suggestion might be outdated.")
  2586. {
  2587. eleTxt.value = "outdated";
  2588. isSetComment = true;
  2589. }
  2590. isFocus = true;
  2591. }
  2592. }
  2593. }
  2594. }
  2595. }
  2596. if (isSameTextOrg && !isSetComment && textLastCur !== "")
  2597. {
  2598. // paste last comment to all hidden comment inputs
  2599. var elesTxt = document.querySelectorAll(".suggestions_list textarea[name='suggestion_comment']");
  2600. for (var i = 0; i < elesTxt.length; i++)
  2601. {
  2602. elesTxt[i].value = textLastCur;
  2603. isSetComment = true;
  2604. }
  2605. }
  2606. }
  2607. }
  2608. // Convert time
  2609. {
  2610. var rgxTime = /\d{2}-\d{2}-\d{4}, \d{2}:\d{2} [AP]M/;
  2611. var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  2612. var eleFriends = document.querySelectorAll(".friend_block_avatar, .friend_block_discussions, .suggestions_list");
  2613. for (var i = 0; i < eleFriends.length; i++)
  2614. {
  2615. var nodes = [];
  2616. if (eleFriends[i].classList.contains("friend_block_avatar"))
  2617. {
  2618. nodes = eleFriends[i].childNodes;
  2619. }
  2620. else if (eleFriends[i].classList.contains("friend_block_discussions"))
  2621. {
  2622. nodes = eleFriends[i].parentElement.nextElementSibling.childNodes[2].childNodes;
  2623. }
  2624. else if (eleFriends[i].classList.contains("suggestions_list"))
  2625. {
  2626. if (!eleFriends[i].querySelector(".suggestion"))
  2627. {
  2628. nodes = eleFriends[i].childNodes;
  2629. }
  2630. }
  2631. for (var j = 0; j < nodes.length; j++)
  2632. {
  2633. var nodeVal = nodes[j].nodeValue;
  2634. if (nodeVal)
  2635. {
  2636. var dateTimes = rgxTime.exec(nodeVal);
  2637. if (dateTimes)
  2638. {
  2639. var dateTime = dateTimes[0];
  2640. var month = dateTime.substr(0, 2);
  2641. var day = dateTime.substr(3, 2);
  2642. var year = dateTime.substr(6, 4);
  2643. var hour = dateTime.substr(12, 2);
  2644. var minute = dateTime.substr(15, 2);
  2645. var period = dateTime.substr(18, 2);
  2646. if (period === "AM")
  2647. {
  2648. if (hour === "12")
  2649. {
  2650. hour = "00"
  2651. }
  2652. }
  2653. else if (period === "PM")
  2654. {
  2655. hour = parseInt(hour) + 12;
  2656. if (hour === 24)
  2657. {
  2658. hour = 12;
  2659. }
  2660. }
  2661. var dateTimeStd = year + "-" + month + "-" + day;
  2662. if (isDstUs(year, month, day, hour))
  2663. {
  2664. dateTimeStd += "T" + hour + ":" + minute + ":00-0700";
  2665. }
  2666. else
  2667. {
  2668. dateTimeStd += "T" + hour + ":" + minute + ":00-0800";
  2669. }
  2670. var dateStd = new Date(dateTimeStd);
  2671. if (dateStd.toLocaleString() !== "Invalid Date")
  2672. {
  2673. var gmt = dateStd.getTimezoneOffset() / 60 * -1;
  2674. var gmtStr = " GMT";
  2675. if (gmt > 0)
  2676. {
  2677. gmtStr += "+" + gmt;
  2678. }
  2679. else if (gmt < 0)
  2680. {
  2681. gmtStr += "-" + gmt;
  2682. }
  2683. var dateNew = dateStd.getDate()
  2684. + " " + months[dateStd.getMonth()]
  2685. + " " + dateStd.getFullYear()
  2686. + ", " + padZero(dateStd.getHours(), 2)
  2687. + ":" + padZero(dateStd.getMinutes(), 2)
  2688. + gmtStr;
  2689. //console.log("Time: " + dateTimeStd);
  2690. //console.log("Time: " + dateTime + " -> " + dateNew);
  2691. //var dateNew2 = dateStd.toLocaleString() + gmtStr;
  2692. //console.log("Time: " + dateTime + " -> " + dateNew2);
  2693. var nodeValBegin = nodeVal.substr(0, nodeVal.indexOf(dateTime));
  2694. var nodeValEnd = nodeVal.substr(nodeVal.indexOf(dateTime) + dateTime.length);
  2695. nodes[j].nodeValue = nodeValBegin;
  2696. var ele = document.createElement("span");
  2697. ele.classList.add("stsh_time_convert");
  2698. ele.setAttribute("title", dateTime);
  2699. ele.textContent = dateNew;
  2700. insertAfterElement(ele, nodes[j]);
  2701. if (nodeValEnd !== "")
  2702. {
  2703. insertAfterElement(document.createTextNode(nodeValEnd), ele);
  2704. }
  2705. }
  2706. else
  2707. {
  2708. console.log("Invalid Date: " + dateTimeStd);
  2709. }
  2710. }
  2711. }
  2712. }
  2713. }
  2714. }
  2715. // Add Steam profile links
  2716. {
  2717. var eleSpans = document.querySelectorAll("span[title='Send this user a private message']");
  2718. for (var i = 0; i < eleSpans.length; i++)
  2719. {
  2720. var href = eleSpans[i].parentElement.firstElementChild.getAttribute("href");
  2721. if (href && href.indexOf("user_activity.php?user=") === 0)
  2722. {
  2723. var profile = href.replace("user_activity.php?user=", "");
  2724. var ele = document.createElement("a");
  2725. ele.classList.add("stsh_steamProfile");
  2726. ele.setAttribute("target", "_blank");
  2727. ele.setAttribute("title", "View Steam profile");
  2728. ele.setAttribute("href", "http://steamcommunity.com/profiles/" + profile);
  2729. ele.textContent = " Steam ";
  2730. insertBeforeElement(ele, eleSpans[i]);
  2731. }
  2732. }
  2733. }
  2734. // Add auto approve
  2735. {
  2736. if (elesInputApprove.length > 0)
  2737. {
  2738. var eleInput = document.createElement("input");
  2739. eleInput.id = "stsh_autoApprove";
  2740. eleInput.setAttribute("type", "checkbox");
  2741. eleInput.setAttribute("value", "auto");
  2742. eleInput.textContent = "";
  2743. var eleLabel = document.createElement("label");
  2744. eleLabel.classList.add("stsh_autoApprove_label");
  2745. eleLabel.classList.add("stsh_unselectable");
  2746. eleLabel.setAttribute("for", "stsh_autoApprove");
  2747. eleLabel.setAttribute("title", "Please use with care!");
  2748. eleLabel.textContent = " Auto Approve Next ";
  2749. elesInputApprove[0].parentElement.appendChild(eleInput);
  2750. elesInputApprove[0].parentElement.appendChild(eleLabel);
  2751. function autoApprove()
  2752. {
  2753. var tm = 2000;
  2754. console.log("AutoApprove: Next in " + tm + "ms");
  2755. setTimeoutCustom(function ()
  2756. {
  2757. var eleCheck = document.querySelector("#stsh_autoApprove");
  2758. if (eleCheck && eleCheck.checked)
  2759. {
  2760. var isClicked = false;
  2761. var ele = document.querySelector(".suggestion_signature input[value~='Next']");
  2762. if (ele && !ele.disabled && isVisible())
  2763. {
  2764. var isOutdated = false;
  2765. var eleSugComment = ele.parentElement
  2766. .parentElement.parentElement.querySelector(".stsh_text_comment font");
  2767. if (eleSugComment && eleSugComment.textContent.trim() ==
  2768. "ATTENTION - English string was updated. This suggestion might be outdated.")
  2769. {
  2770. isOutdated = true;
  2771. }
  2772. if (!isOutdated)
  2773. {
  2774. isClicked = true;
  2775. GM_setValue("timeAutoApproveLast", getUnixTimestamp());
  2776. ele.click();
  2777. }
  2778. }
  2779. if (!isClicked)
  2780. {
  2781. eleCheck.checked = false;
  2782. GM_setValue("isAutoApprove", "false");
  2783. }
  2784. }
  2785. }, tm);
  2786. }
  2787. var tmDiff = getUnixTimestamp() - GM_getValue("timeAutoApproveLast", 0);
  2788. if (tmDiff > 10)
  2789. {
  2790. // > 10s
  2791. eleInput.checked = false;
  2792. GM_setValue("isAutoApprove", "false");
  2793. }
  2794. if (window !== window.parent)
  2795. {
  2796. var eleOuter = window.parent.document.querySelector("#suggestions_box_outer");
  2797. if (eleOuter)
  2798. {
  2799. if (eleOuter.style.display === "none")
  2800. {
  2801. // Closed iFrame
  2802. eleInput.checked = false;
  2803. GM_setValue("isAutoApprove", "false");
  2804. }
  2805. }
  2806. }
  2807. if (GM_getValue("isAutoApprove", 0) === "true")
  2808. {
  2809. eleInput.checked = true;
  2810. autoApprove();
  2811. }
  2812.  
  2813. eleInput.addEventListener("click", function (e)
  2814. {
  2815. var ele = e.target;
  2816. if (ele.checked)
  2817. {
  2818. GM_setValue("isAutoApprove", "true");
  2819. autoApprove();
  2820. }
  2821. else
  2822. {
  2823. GM_setValue("isAutoApprove", "false");
  2824. }
  2825. });
  2826. }
  2827. }
  2828. // Warn when remove
  2829. // Suggest to remove
  2830. {
  2831. var elesRemove = document.querySelectorAll(".suggestion_signature input[value='REMOVE']");
  2832. for (var i = 0; i < elesRemove.length; i++)
  2833. {
  2834. var oldClick = elesRemove[i].getAttribute("onclick");
  2835. if (oldClick && oldClick.indexOf("location.href") === 0)
  2836. {
  2837. var eleSug = elesRemove[i].parentElement.parentElement.parentElement.parentElement;
  2838. if (eleSug.classList.contains("suggestion"))
  2839. {
  2840. /*
  2841. // Typonion
  2842. var eleOnion = eleSug.querySelector(".suggestion_text font[style='color:#01ec00;']");
  2843. if (eleOnion)
  2844. {
  2845. var newClick = "if (!confirm(\"Warning: You will delete your onion. Press Cancel to go back.\")) return false; "
  2846. + oldClick;
  2847. elesRemove[i].setAttribute("onclick", newClick);
  2848. elesRemove[i].setAttribute("title", "Do not remove your onion!");
  2849. elesRemove[i].style.color = "#777";
  2850. elesRemove[i].style.cursor = "not-allowed";
  2851. }
  2852. else
  2853. */
  2854. {
  2855. var eleComment = elesRemove[i].previousElementSibling.previousElementSibling;
  2856. if (eleComment)
  2857. {
  2858. // Mod comment
  2859. if (eleComment.textContent.trim().indexOf("Comment:") === 0)
  2860. {
  2861. // Mod commented, suggest to do not remove
  2862. var newClick = "if (!confirm(\"Warning: You should not remove this suggestion."
  2863. + " Press OK if you really want.\")) return false; "
  2864. + oldClick;
  2865. elesRemove[i].setAttribute("onclick", newClick);
  2866. elesRemove[i].setAttribute("title",
  2867. "Your suggestion that has a comment! Should not remove this suggestion.");
  2868. elesRemove[i].classList.add("stsh_grey");
  2869. elesRemove[i].classList.add("stsh_cursor_notallowed");
  2870. }
  2871. else
  2872. {
  2873. // No mod comment, suggest to remove
  2874. elesRemove[i].setAttribute("title",
  2875. "Please remove this suggestion to save admin time.");
  2876. elesRemove[i].classList.add("stsh_green");
  2877. elesRemove[i].classList.add("stsh_border_green");
  2878. }
  2879. }
  2880. else
  2881. {
  2882. eleComment = elesRemove[i].parentElement.parentElement.previousElementSibling;
  2883. if (eleComment.tagName === "I")
  2884. {
  2885. // User comment
  2886. var comment = eleComment.textContent.trim();
  2887. if (comment.indexOf("ATTENTION - English string was updated.") > -1)
  2888. {
  2889. // Outdated, suggest to edit and remove
  2890. elesRemove[i].setAttribute("title",
  2891. "Please edit and remove this outdated suggestion.");
  2892. elesRemove[i].classList.add("stsh_green");
  2893. elesRemove[i].classList.add("stsh_border_green");
  2894. }
  2895. }
  2896. }
  2897. }
  2898. }
  2899. }
  2900. }
  2901. }
  2902. // Suggest to decline outdated
  2903. {
  2904. if (document.querySelector("input[value~='APPROVE']"))
  2905. {
  2906. var elesAttention = document.querySelectorAll(".stsh_text_comment > font > i > b");
  2907. for (var i = 0; i < elesAttention.length; i++)
  2908. {
  2909. if (elesAttention[i].textContent.trim()
  2910. === "ATTENTION - English string was updated. This suggestion might be outdated.")
  2911. {
  2912. var eleAction = elesAttention[i]
  2913. .parentElement.parentElement
  2914. .parentElement.parentElement
  2915. .nextElementSibling;
  2916. var eleApprove = eleAction.querySelector("input[value~='APPROVE']");
  2917. var eleApproveNext = null;
  2918. var eleDecline = null;
  2919. if (eleApprove)
  2920. {
  2921. eleApproveNext = eleApprove.nextElementSibling;
  2922. var oldClick = eleApprove.getAttribute("onclick");
  2923. if (oldClick && oldClick.indexOf("location.href") === 0)
  2924. {
  2925. var newClick = "if (!confirm(\"Warning: Please decline outdated suggestion."
  2926. + " Press OK if you really want to approve.\")) return false; "
  2927. + oldClick;
  2928. eleApprove.setAttribute("onclick", newClick);
  2929. eleApprove.setAttribute("title", "Please decline outdated suggestion.");
  2930. eleApprove.classList.add("stsh_grey");
  2931. eleApprove.classList.add("stsh_cursor_notallowed");
  2932. }
  2933. }
  2934. if (eleApproveNext)
  2935. {
  2936. eleDecline = eleApproveNext.nextElementSibling;
  2937. if (!eleApproveNext.disabled)
  2938. {
  2939. var oldClick = eleApproveNext.getAttribute("onclick");
  2940. if (oldClick && oldClick.indexOf("location.href") === 0)
  2941. {
  2942. var newClick = "if (!confirm(\"Warning: Please decline outdated suggestion."
  2943. + " Press OK if you really want to approve.\")) return false; "
  2944. + oldClick;
  2945. eleApproveNext.setAttribute("onclick", newClick);
  2946. eleApproveNext.setAttribute("title", "Please decline outdated suggestion.");
  2947. eleApproveNext.classList.add("stsh_grey");
  2948. eleApproveNext.classList.add("stsh_cursor_notallowed");
  2949. }
  2950. }
  2951. }
  2952. if (eleDecline)
  2953. {
  2954. eleDecline.setAttribute("title", "Please decline outdated suggestion.");
  2955. eleDecline.classList.add("stsh_green");
  2956. eleDecline.classList.add("stsh_border_green_left");
  2957. }
  2958. }
  2959. }
  2960. }
  2961. }
  2962. // Clean language markers that link to Steam
  2963. {
  2964. var rgxLang = /\?l=[a-z]+$/i;
  2965. var elesFriend = document.querySelectorAll(".friend_block_discussions");
  2966. for (var i = 0; i < elesFriend.length; i++)
  2967. {
  2968. var eleDiscuss = elesFriend[i].parentElement.nextElementSibling;
  2969. if (!eleDiscuss.querySelector("font[style='color:#EDB687;']"))
  2970. {
  2971. var elesA = eleDiscuss.querySelectorAll("a[href*='steam']");
  2972. for (var j = 0; j < elesA.length; j++)
  2973. {
  2974. var href = elesA[j].getAttribute("href");
  2975. if (rgxLang.test(href))
  2976. {
  2977. elesA[j].setAttribute("href", href.replace(rgxLang, ""));
  2978. }
  2979. }
  2980. }
  2981. }
  2982. }
  2983. // Auto paste last suggestion
  2984. {
  2985. if (!/edit/i.test(getQueryByName("action")))
  2986. {
  2987. //var eleTextOrg = document.querySelector(".stsh_text_org");
  2988. if (eleTextOrg)
  2989. {
  2990. var textOrg = trimSpace(eleTextOrg.innerHTML).toLowerCase();
  2991. if (textOrg === GM_getValue("textLastOrg", ""))
  2992. {
  2993. var eleTextCur = document.querySelector("#suggestion_value_new");
  2994. if (eleTextCur)
  2995. {
  2996. var textLastCur = GM_getValue("textLastCur", "");
  2997. if (textLastCur !== "")
  2998. {
  2999. eleTextCur.value = textLastCur;
  3000. }
  3001. }
  3002. setTimeoutCustom(function()
  3003. {
  3004. var eleTextCur = document.querySelector("#suggestion_value_new");
  3005. if (eleTextCur)
  3006. {
  3007. var textLastCur = GM_getValue("textLastCur", "");
  3008. if (textLastCur !== "")
  3009. {
  3010. eleTextCur.value = textLastCur;
  3011. }
  3012. }
  3013. }, 250);
  3014. }
  3015. }
  3016. }
  3017. var elesTextSubmit = document.querySelectorAll(".stsh_text_submit, #stsh_submit_suggestion_next");
  3018. for (var i = 0; i < elesTextSubmit.length; i++)
  3019. {
  3020. elesTextSubmit[i].addEventListener("click", function()
  3021. {
  3022. var eleTextOrg = document.querySelector(".stsh_text_org");
  3023. if (eleTextOrg)
  3024. {
  3025. var textOrg = trimSpace(eleTextOrg.innerHTML);
  3026. if (textOrg.length < 1000)
  3027. {
  3028. var eleTextCur = document.querySelector("#suggestion_value_new");
  3029. if (eleTextCur)
  3030. {
  3031. var textCur = eleTextCur.value;
  3032. GM_setValue("textLastOrg", textOrg.toLowerCase());
  3033. GM_setValue("textLastCur", textCur);
  3034. }
  3035. }
  3036. }
  3037. });
  3038. }
  3039. }
  3040. // Auto store last comment
  3041. {
  3042. //console.log("textLastOrg_Comment: " + GM_getValue("textLastOrg_Comment", ""));
  3043. //console.log("textLastCur_Comment: " + GM_getValue("textLastCur_Comment", ""));
  3044. function storeLastComment(eleTextComment, isRemoved)
  3045. {
  3046. if (eleTextComment)
  3047. {
  3048. var eleTextOrg = document.querySelector(".stsh_text_org");
  3049. if (eleTextOrg)
  3050. {
  3051. var textOrg = trimSpace(eleTextOrg.innerHTML).substr(0, 1000).toLowerCase();
  3052. if (isRemoved)
  3053. {
  3054. if (textOrg === GM_getValue("textLastOrg_Comment", ""))
  3055. {
  3056. // When remove comment, don't store if original text is the same
  3057. return;
  3058. }
  3059. }
  3060. var textCur = trimSpace(eleTextComment.value || eleTextComment.textContent);
  3061. if (textCur !== "outdated")
  3062. {
  3063. GM_setValue("textLastOrg_Comment", textOrg);
  3064. GM_setValue("textLastCur_Comment", textCur);
  3065. }
  3066. }
  3067. }
  3068. }
  3069. var elesTextRemoveComment = document.querySelectorAll(".stsh_text_removeComment");
  3070. for (var i = 0; i < elesTextRemoveComment.length; i++)
  3071. {
  3072. elesTextRemoveComment[i].addEventListener("click", function(ev)
  3073. {
  3074. var target = null;
  3075. if (ev.target.tagName === "FONT")
  3076. {
  3077. target = ev.target.parentElement;
  3078. }
  3079. else
  3080. {
  3081. target = ev.target;
  3082. }
  3083. var eleTextComment = target
  3084. .parentElement.parentElement.parentElement.parentElement
  3085. .querySelector(".stsh_text_comment");
  3086. storeLastComment(eleTextComment, true);
  3087. });
  3088. }
  3089. var elesSubmitComment = document.querySelectorAll(".stsh_submit_comment");
  3090. for (var i = 0; i < elesSubmitComment.length; i++)
  3091. {
  3092. elesSubmitComment[i].addEventListener("click", function(ev)
  3093. {
  3094. var eleTextComment = ev.target.previousElementSibling;
  3095. storeLastComment(eleTextComment, false);
  3096. });
  3097. }
  3098. }
  3099. // Mark showing
  3100. {
  3101. var eleStatus = window.parent.document.querySelector("#stsh_showing_random");
  3102. if (eleStatus)
  3103. {
  3104. eleStatus.dataset.random = (new Date()).getTime();
  3105. }
  3106. }
  3107. // Delta
  3108. {
  3109. var eleFile = document.querySelector(".stsh_info_file");
  3110. if (eleFile)
  3111. {
  3112. if (eleFile.textContent.trim() === "steam/delta")
  3113. {
  3114. document.body.classList.add("stsh_delta");
  3115. }
  3116. }
  3117. }
  3118. // Clean link remove my comment
  3119. {
  3120. var elesRemoveMyComment = document.querySelectorAll(
  3121. ".suggestion_signature .lbAction[name^='myFrm'] a[onclick*='.submit()']");
  3122. for (var i = 0; i < elesRemoveMyComment.length; i++)
  3123. {
  3124. elesRemoveMyComment[i].removeAttribute("href");
  3125. elesRemoveMyComment[i].classList.add("stsh_text_removeMyComment");
  3126. }
  3127. }
  3128. // Hide cursor when typing
  3129. // Expand textarea when typing
  3130. {
  3131. var tmTextChange = 0;
  3132. function autoHideCursor(ele)
  3133. {
  3134. if (ele)
  3135. {
  3136. ele.addEventListener("input", function(ev)
  3137. {
  3138. var ele = ev.target;
  3139. ele.style.setProperty("cursor", "none", "important");
  3140. clearTimeout(tmTextChange);
  3141. tmTextChange = setTimeoutCustom(function(ele)
  3142. {
  3143. ele.style.setProperty("cursor", "auto", "important");
  3144. }, 3000, ele);
  3145. });
  3146. ele.addEventListener("mousemove", function(ev)
  3147. {
  3148. var ele = ev.target;
  3149. clearTimeout(tmTextChange);
  3150. ele.style.setProperty("cursor", "auto", "important");
  3151. });
  3152. }
  3153. }
  3154. function autoExpandEvent(ev)
  3155. {
  3156. var ele = ev.target;
  3157. var maxHeight = ele.param_MaxHeight;
  3158. var styleHeight = parseInt(ele.style.height)
  3159. || parseInt(window.getComputedStyle(ele).height)
  3160. || maxHeight;
  3161. var heightDiff = ele.scrollHeight - styleHeight;
  3162. //console.log("ele.scrollHeight:"+ele.scrollHeight+", styleHeight:"+styleHeight+", heightDiff:"+heightDiff);
  3163. // When press a button
  3164. // Chrome: heightDiff === 4
  3165. // Firefox: heightDiff === 0
  3166. if ((heightDiff > 0 && heightDiff !== 4) && ele.scrollHeight < maxHeight)
  3167. {
  3168. ele.style.height = (ele.scrollHeight + 2) + "px";
  3169. }
  3170. else if (ele.scrollHeight > maxHeight && ele.scrollHeight - maxHeight < 100)
  3171. {
  3172. ele.style.height = maxHeight + "px";
  3173. }
  3174. }
  3175. function autoExpandEventTextarea(ele, maxHeight)
  3176. {
  3177. if (ele)
  3178. {
  3179. ele.param_MaxHeight = maxHeight;
  3180. ele.addEventListener("input", autoExpandEvent);
  3181. ele.addEventListener("keyup", autoExpandEvent);
  3182. }
  3183. }
  3184. var elesTextarea = document.querySelectorAll("textarea");
  3185. for (var i = 0; i < elesTextarea.length; i++)
  3186. {
  3187. autoExpandEventTextarea(elesTextarea[i], 500);
  3188. autoHideCursor(elesTextarea[i]);
  3189. }
  3190. }
  3191. // Focus on mod action
  3192. {
  3193. var elesEdit = document.querySelectorAll("input[value='Edit']");
  3194. if (elesEdit.length > 2)
  3195. {
  3196. setTimeoutCustom(function()
  3197. {
  3198. if (/reconsider|approve|decline/.test(getQueryByName("action")))
  3199. {
  3200. scrollToElement(".suggestions_list", -200);
  3201. }
  3202. }, 200);
  3203. }
  3204. }
  3205. } // End suggestions.php
  3206.  
  3207. if (url.indexOf("translate.php") > -1)
  3208. {
  3209. var searchText = getQueryByName("search_input");
  3210. if (searchText !== "")
  3211. {
  3212. document.title = searchText + " - " + document.title;
  3213. }
  3214. else
  3215. {
  3216. var fileID = getQueryByName("file_ID");
  3217. if (fileID !== "")
  3218. {
  3219. var eleFile = document.querySelector("#leftAreaContainer label[for='chosenfile']");
  3220. if (eleFile)
  3221. {
  3222. var file = eleFile.textContent.trim();
  3223. if (file.indexOf("Limit search results to CURRENT FILE: ") === 0)
  3224. {
  3225. file = file.replace("Limit search results to CURRENT FILE: ", "");
  3226. var fileNew = file.split("#").reverse().join(" # ").trim();
  3227. document.title = fileNew + " - " + document.title;
  3228. }
  3229. }
  3230. }
  3231. else
  3232. {
  3233. var eleInput = document.querySelector("#search_input");
  3234. if (eleInput)
  3235. {
  3236. var valInput = eleInput.value.trim();
  3237. if (valInput.indexOf("SUGGESTIONS FROM: ") === 0)
  3238. {
  3239. document.title = valInput.replace("SUGGESTIONS FROM: ", "") + " - " + document.title;
  3240. }
  3241. }
  3242. }
  3243. }
  3244. var outer = document.querySelector("#suggestions_box_outer");
  3245. if (outer)
  3246. {
  3247. outer.setAttribute("onclick", "hideSuggestionsBox();");
  3248. }
  3249. var divBtn = document.createElement("div");
  3250. document.body.appendChild(divBtn);
  3251. divBtn.innerHTML =
  3252. ' \
  3253. <div class="stsh_showing_group"> \
  3254. <span class="stsh_showing_header">Hide</span>\
  3255. <br/> &nbsp; <input id="stsh_showing_keyApp" value="App" data-hidekey="0" class="stsh_btn_short stsh_showing_key" type="button" /> \
  3256. <input id="stsh_showing_keyGame" value="Game" data-hidekey="1" class="stsh_btn_short stsh_showing_key" type="button" /> \
  3257. <br/> &nbsp; <input id="stsh_showing_keyFaq" value="FAQ" data-hidekey="2" class="stsh_btn_short stsh_showing_key" type="button" /> \
  3258. <input id="stsh_showing_keySupport" value="Support" data-hidekey="3" class="stsh_btn_short stsh_showing_key" type="button" /> \
  3259. <br/> &nbsp; <input id="stsh_showing_keyPromo" value="Promo" data-hidekey="4" class="stsh_btn_short stsh_showing_key" type="button" /> \
  3260. <input id="stsh_showing_keyEmail" value="Email" data-hidekey="5" class="stsh_btn_short stsh_showing_key" type="button" /> \
  3261. <br/> \
  3262. <br/> &nbsp; <input id="stsh_showing_strNotMatch" value="Hide not similar" data-hidestr="0" class="stsh_btn_long stsh_showing_str" type="button" /> \
  3263. <br/> &nbsp; <input id="stsh_showing_strLong" value="Hide very long" data-hidestr="1" class="stsh_btn_long stsh_showing_str" type="button" /> \
  3264. \
  3265. <br/> &nbsp; <span class="stsh_showing_header">Hide Suggestions</span>\
  3266. <br/> &nbsp; <input id="stsh_showing_notTranslated" value="Not Translated (0)" data-hidestatus="0" class="stsh_btn_long stsh_showing_status" type="button" /> \
  3267. <br/> &nbsp; <input id="stsh_showing_suggested" value="Suggested (0)" data-hidestatus="1" class="stsh_btn_long stsh_showing_status" type="button" /> \
  3268. <br/> &nbsp; <input id="stsh_showing_resuggested" value="Resuggested (0)" data-hidestatus="2" class="stsh_btn_long stsh_showing_status" type="button" /> \
  3269. <br/> &nbsp; <input id="stsh_showing_approved" value="Approved (0)" data-hidestatus="3" class="stsh_btn_long stsh_showing_status" type="button" /> \
  3270. <br/> &nbsp; <input id="stsh_showing_declined" value="Declined (0)" data-hidestatus="4" class="stsh_btn_long stsh_showing_status" type="button" /> \
  3271. <br/> &nbsp; <input id="stsh_showing_translated" value="Translated (0)" data-hidestatus="5" class="stsh_btn_long stsh_showing_status" type="button" /> \
  3272. \
  3273. <br/> &nbsp; <span class="stsh_showing_header">Sort by</span>\
  3274. <br/> &nbsp; <input id="stsh_sort_key" value="Key" data-sort="0" class="stsh_btn_short stsh_sort" type="button" /> \
  3275. <input id="stsh_sort_string" value="String" data-sort="1" class="stsh_btn_short stsh_sort" type="button" /> \
  3276. <br/> &nbsp; <input id="stsh_sort_word" value="Word" data-sort="2" class="stsh_btn_short stsh_sort" type="button" /> \
  3277. <input id="stsh_sort_length" value="Length" data-sort="3" class="stsh_btn_short stsh_sort" type="button" /> \
  3278. <br/> \
  3279. <br/> &nbsp; <input id="stsh_showing_refresh" value="Refresh" class="stsh_btn" type="button" onclick="hideSuggestionsBox(); return false;" /> \
  3280. <br/> &nbsp; <input id="stsh_showing_all" value="Show All" class="stsh_btn" type="button" /> \
  3281. </div> \
  3282. <div id="stsh_showing_current"></div> \
  3283. <div id="stsh_showing"></div> \
  3284. ';
  3285.  
  3286. // Count showing
  3287. function countShowing()
  3288. {
  3289. var trKeys = document.querySelectorAll("#keylist > table:nth-child(1) > tbody:nth-child(1) > tr");
  3290. var countAll = document.querySelectorAll("#keylist .copysmall").length;
  3291. var countShow = 0;
  3292. var countSuggest = 0;
  3293. var countResuggest = 0;
  3294. var countApprove = 0;
  3295. var countDecline = 0;
  3296. var countNotTranslated = 0;
  3297. var countTranslated = 0;
  3298. var txtApprove = "ready for Admin";
  3299. var txtDecline = "ready for removal";
  3300. var txtSuggest = "suggestion";
  3301. for (var i = 0; i < trKeys.length; i++)
  3302. {
  3303. if (!trKeys[i].classList.contains("stsh_hidden"))
  3304. {
  3305. var eleCounter = trKeys[i].querySelector("tr.copysmall > td:nth-child(3)");
  3306. if (eleCounter)
  3307. {
  3308. countShow++;
  3309. var txtCounter = eleCounter.textContent.trim();
  3310. if (txtCounter.indexOf(txtApprove) > -1)
  3311. {
  3312. countApprove++;
  3313. }
  3314. else if (txtCounter.indexOf(txtDecline) > -1)
  3315. {
  3316. countDecline++;
  3317. }
  3318. else if (txtCounter.indexOf(txtSuggest) > -1)
  3319. {
  3320. var eleNotTranslated = trKeys[i].querySelector("span.token_nottranslated");
  3321. if (eleNotTranslated)
  3322. {
  3323. countSuggest++;
  3324. }
  3325. else
  3326. {
  3327. countResuggest++;
  3328. }
  3329. }
  3330. else
  3331. {
  3332. var eleNotTranslated = trKeys[i].querySelector("span.token_nottranslated");
  3333. if (eleNotTranslated)
  3334. {
  3335. countNotTranslated++;
  3336. }
  3337. else
  3338. {
  3339. countTranslated++;
  3340. }
  3341. }
  3342. }
  3343. else
  3344. {
  3345. var eleTd = trKeys[i].querySelector("td");
  3346. if (eleTd)
  3347. {
  3348. if (eleTd.textContent.trim() === "")
  3349. {
  3350. trKeys[i].parentElement.removeChild(trKeys[i]);
  3351. }
  3352. }
  3353. }
  3354. }
  3355. }
  3356. var eleShowing = document.querySelector("#stsh_showing");
  3357. if (eleShowing)
  3358. {
  3359. var newHtml = "Showing: <span class=\"stsh_showing_counter\">" + countShow + " of " + countAll + "</span>"
  3360. + "<!-- " + countNotTranslated + ", " + countSuggest + ", " + countResuggest
  3361. + ", " + countApprove + ", " + countDecline + ", " + countTranslated + " -->";
  3362. if (eleShowing.innerHTML !== newHtml)
  3363. {
  3364. eleShowing.innerHTML = newHtml;
  3365.  
  3366. var elesBtnShowingStatus = document.querySelectorAll(".stsh_showing_status");
  3367. if (elesBtnShowingStatus.length === 6)
  3368. {
  3369. var counterArr = [countNotTranslated, countSuggest, countResuggest
  3370. , countApprove, countDecline, countTranslated ];
  3371. var counterTextArr = ["Not Translated", "Suggested", "Resuggested"
  3372. , "Approved", "Declined", "Translated" ];
  3373.  
  3374. for (var i = 0; i < elesBtnShowingStatus.length; i++)
  3375. {
  3376. elesBtnShowingStatus[i].value = counterTextArr[i] + " ("+ counterArr[i] +")" ;
  3377. };
  3378. }
  3379. }
  3380. }
  3381. var eleShowingCur = document.querySelector("#stsh_showing_current");
  3382. if (eleShowingCur)
  3383. {
  3384. var eleOuter = document.querySelector("#suggestions_box_outer");
  3385. if (eleOuter)
  3386. {
  3387. if (eleOuter.style.display !== "none")
  3388. {
  3389. if (eleShowingCur.style.display !== "initial")
  3390. eleShowingCur.style.display = "initial";
  3391. var eleIframe = document.querySelector("#suggestions_iframe");
  3392. if (eleIframe)
  3393. {
  3394. var iUrl = eleIframe.contentWindow.location.href;
  3395. var listId = parseInt(getQueryByName("list_id", iUrl)) || 0;
  3396. listId += 1;
  3397. var newHtml = "Current: <span class=\"stsh_showing_counter\">" + listId + " of " + countShow + "</span>";
  3398. if (eleShowingCur.innerHTML !== newHtml)
  3399. {
  3400. eleShowingCur.innerHTML = newHtml;
  3401. }
  3402. }
  3403. }
  3404. else
  3405. {
  3406. if (eleShowingCur.style.display !== "none")
  3407. {
  3408. eleShowingCur.style.display = "none";
  3409. eleShowingCur.innerHTML = "";
  3410. }
  3411. }
  3412. }
  3413. }
  3414. }
  3415. countShowing();
  3416. var obTarget_count = document.querySelector("#keylist_container");
  3417. if (obTarget_count)
  3418. {
  3419. var tmOb_count = -1;
  3420. var obMu_count = new MutationObserver(function(mutations)
  3421. {
  3422. mutations.forEach(function(mutation)
  3423. {
  3424. if (mutation.type !== "attributes"
  3425. || mutation.target.tagName === "TR")
  3426. {
  3427. clearTimeout(tmOb_count);
  3428. tmOb_count = setTimeoutCustom(function(mutation)
  3429. {
  3430. countShowing();
  3431. //console.log("countShowing: " + tmOb_count);
  3432. }, 50, mutation);
  3433. }
  3434. });
  3435. });
  3436. var obConfig_count = { childList: true, subtree: true, attributes: true, attributeFilter: ["class"] };
  3437. obMu_count.observe(obTarget_count, obConfig_count);
  3438. }
  3439. // Waiting for iframe
  3440. {
  3441. var obTarget_countRand = document.createElement("div");
  3442. obTarget_countRand.id = "stsh_showing_random";
  3443. obTarget_countRand.dataset.random = "0";
  3444. document.body.appendChild(obTarget_countRand);
  3445. var obMu_countRand = new MutationObserver(function(mutations)
  3446. {
  3447. mutations.forEach(function(mutation)
  3448. {
  3449. countShowing();
  3450. });
  3451. });
  3452.  
  3453. var obConfig_countRand = { attributes: true, attributeFilter: ["data-random"] };
  3454. obMu_countRand.observe(obTarget_countRand, obConfig_countRand);
  3455. }
  3456. // End Count showing
  3457.  
  3458. // Line Counter
  3459. function addLineCounter()
  3460. {
  3461. var elesCounter = document.querySelectorAll(".stsh_lineCounter");
  3462. if (elesCounter.length > 0)
  3463. {
  3464. var j = 1;
  3465. for (var i = 0; i < elesCounter.length; i++)
  3466. {
  3467. if (!elesCounter[i].parentElement.parentElement.parentElement
  3468. .parentElement.classList.contains("stsh_hidden"))
  3469. {
  3470. if (elesCounter[i].textContent.trim() != j)
  3471. {
  3472. // Compare string with int using loose equality
  3473. elesCounter[i].textContent = j;
  3474. }
  3475. j++;
  3476. }
  3477. }
  3478. }
  3479. else
  3480. {
  3481. var elesDiv = document.querySelectorAll("#keylist td:nth-child(1) > div");
  3482. for (var i = 0; i < elesDiv.length; i++)
  3483. {
  3484. var eleNew = document.createElement("span");
  3485. eleNew.classList.add("stsh_lineCounter_outer");
  3486. eleNew.innerHTML =
  3487. ' <span class="stsh_lineCounter"> ' + (i + 1) + ' </span> ';
  3488. elesDiv[i].appendChild(eleNew);
  3489. }
  3490. }
  3491. }
  3492. addLineCounter();
  3493. var obTarget_line = document.querySelector("#keylist_container");
  3494. if (obTarget_line)
  3495. {
  3496. var tmOb_line = -1;
  3497. var obMu_line = new MutationObserver(function(mutations)
  3498. {
  3499. mutations.forEach(function(mutation)
  3500. {
  3501. if (mutation.type !== "attributes"
  3502. || mutation.target.tagName === "TR")
  3503. {
  3504. clearTimeout(tmOb_line);
  3505. tmOb_line = setTimeoutCustom(function(mutation)
  3506. {
  3507. addLineCounter();
  3508. //console.log("addLineCounter: " + tmOb_line);
  3509. }, 50, mutation);
  3510. }
  3511. });
  3512. });
  3513. var obConfig_line = { childList: true, subtree: true, attributes: true, attributeFilter: ["class"] };
  3514. obMu_line.observe(obTarget_line, obConfig_line);
  3515. }
  3516. // End Line Counter
  3517. // Hide & sort suggestions
  3518. {
  3519. function hideStatus(mode)
  3520. {
  3521. /*
  3522. mode:
  3523. 0: notTranslated
  3524. 1: suggested
  3525. 2: resuggested
  3526. 3: approved
  3527. 4: declined
  3528. 5: translated
  3529. */
  3530.  
  3531. //console.log("hideStatus: " + mode);
  3532. if (mode < 0 || mode > 5) return;
  3533.  
  3534. var display = "none";
  3535. var txtApprove = "ready for Admin";
  3536. var txtDecline = "ready for removal";
  3537. var txtSuggest = "suggestion";
  3538. var trKeys = document.querySelectorAll("#keylist > table:nth-child(1) > tbody:nth-child(1) > tr");
  3539. for (var i = 0; i < trKeys.length; i++)
  3540. {
  3541. if (!trKeys[i].classList.contains("stsh_hidden"))
  3542. {
  3543. var curMode = -1;
  3544.  
  3545. var eleCounter = trKeys[i].querySelector("tr.copysmall > td:nth-child(3)");
  3546. if (eleCounter)
  3547. {
  3548.  
  3549. var txtCounter = eleCounter.textContent.trim();
  3550. if (txtCounter.indexOf(txtApprove) > -1)
  3551. {
  3552. curMode = 3; // Approved
  3553. }
  3554. else if (txtCounter.indexOf(txtDecline) > -1)
  3555. {
  3556. curMode = 4; // Declined
  3557. }
  3558. else if (txtCounter.indexOf(txtSuggest) > -1)
  3559. {
  3560. var eleNotTranslated = trKeys[i].querySelector("span.token_nottranslated");
  3561. if (eleNotTranslated)
  3562. {
  3563. curMode = 1; // Suggested
  3564. }
  3565. else
  3566. {
  3567. curMode = 2; // Resuggested
  3568. }
  3569. }
  3570. else
  3571. {
  3572. var eleNotTranslated = trKeys[i].querySelector("span.token_nottranslated");
  3573. if (eleNotTranslated)
  3574. {
  3575. curMode = 0; // Not Translated
  3576. }
  3577. else
  3578. {
  3579. curMode = 5; // Translated
  3580. }
  3581. }
  3582. }
  3583.  
  3584. if (curMode === mode)
  3585. {
  3586. trKeys[i].classList.add("stsh_hidden");
  3587. }
  3588. }
  3589. }
  3590. }
  3591. function sortKey(mode)
  3592. {
  3593. /*
  3594. mode:
  3595. 0: key
  3596. 1: string
  3597. 2: word
  3598. 3: length
  3599. */
  3600. if (mode < 0) return;
  3601. var keyArr = new Array();
  3602. var valArr = new Array();
  3603. var dot = "...";
  3604. var dotLengthMinus = 0 - dot.length;
  3605. var strNotTranslated = "NOT TRANSLATED";
  3606. var strTr = "";
  3607. var eleKeys = document.querySelectorAll
  3608. (" \
  3609. #keylist > table:nth-child(1) \
  3610. > tbody:nth-child(1) > tr > td:nth-child(1) > div:nth-child(1) \
  3611. > table:nth-child(1) > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(1) \
  3612. ");
  3613. for (var i = 0; i < eleKeys.length; i++)
  3614. {
  3615. try
  3616. {
  3617. /*
  3618. key:
  3619. tr: is translated
  3620. sg: is suggested
  3621. dt: has dot
  3622. sb: spacebar count
  3623. sc: special char count
  3624. sp: has special char
  3625. ln: length
  3626. lt: length translated
  3627. st: spacebar count translated
  3628. */
  3629. var dot = "...";
  3630. var dotLengthMinus = 0 - dot.length;
  3631. var isDot = false;
  3632. var isSuggested = false;
  3633. var isTranslated = false;
  3634. var key = eleKeys[i].textContent.trim() + " ";
  3635. var str = "";
  3636. if (mode !== 0)
  3637. {
  3638. str = eleKeys[i].parentElement.nextSibling.nextSibling.firstElementChild.textContent.trim();
  3639. isDot = (str.substr(dotLengthMinus) === dot);
  3640. isSuggested = (eleKeys[i].nextElementSibling.nextElementSibling.textContent.trim() !== "");
  3641. strTr = eleKeys[i].parentElement.nextElementSibling.lastElementChild.textContent.trim();
  3642. isTranslated = (strTr !== strNotTranslated);
  3643. }
  3644. if (mode === 0)
  3645. {
  3646. // mode: key
  3647. if (key.indexOf("GLOSSARY") === 0)
  3648. {
  3649. key = "0" + key;
  3650. }
  3651. }
  3652. if (mode === 1)
  3653. {
  3654. // mode: string
  3655. key = (isTranslated ? "tr00_ " : "tr99_ ") + strTr
  3656. + (isSuggested ? " _sg00" : " _sg99") + " ___ " + key;
  3657. key = str + " ___ " + key;
  3658. }
  3659. else if (mode === 2)
  3660. {
  3661. // mode: word
  3662. key = (isTranslated ? "tr00_" : "tr99_")
  3663. + "st" + padZero(strTr.split(" ").length, 2) + "_"
  3664. + "lt" + padZero(strTr.length, 3) + " "
  3665. + strTr + (isSuggested ? " _sg00" : " _sg99") + " ___ " + key;
  3666. key = (isDot ? "dt99_" : "dt00_")
  3667. + "sb" + padZero(str.split(" ").length, 2)
  3668. + "_sc" + padZero(str.split(/[^a-z0-9 ]/i).length, 2)
  3669. + " ___ " + str + " ___ " + key;
  3670. }
  3671. else if (mode === 3)
  3672. {
  3673. // length
  3674. var length = 0;
  3675. if (str[0] === "<" || str[0] === "[")
  3676. {
  3677. length = str.length + 800;
  3678. }
  3679. else if (str.indexOf("<") > 0 || str.indexOf("[") > 0)
  3680. {
  3681. length = str.length + 600;
  3682. }
  3683. else
  3684. {
  3685. length = str.length;
  3686. }
  3687. key = (isTranslated ? "tr00_" : "tr99_") + "lt" + padZero(strTr.length, 3) + " "
  3688. + strTr + (isSuggested ? " _sg00" : " _sg99") + " ___ " + key;
  3689. key = (isDot ? "dt99_" : "dt00_")
  3690. + "sp" + (str.split(/[^a-z0-9]/i).length > 1 ? "99_" : "00_")
  3691. + "ln" + padZero(length, 3)
  3692. + " ___ " + str + " ___ " + key;
  3693. }
  3694. key = key.toLowerCase();
  3695. keyArr.push(key);
  3696. var eleParent = eleKeys[i].parentElement.parentElement.parentElement
  3697. .parentElement.parentElement.parentElement;
  3698. //eleParent.dataset.stshKey = key;
  3699. //console.log("Key: " + key);
  3700. valArr[key] = eleParent.outerHTML.trim();
  3701. }
  3702. catch (ex)
  3703. {
  3704. console.error("sortKey", ex.message);
  3705. }
  3706. }
  3707. var keyArrTmp = keyArr.slice();
  3708. keyArr.sort();
  3709. var isSame = true;
  3710. for (var i = 0; i < keyArr.length; i++)
  3711. {
  3712. if (keyArr[i] !== keyArrTmp[i])
  3713. {
  3714. isSame = false;
  3715. }
  3716. }
  3717. if (!isSame)
  3718. {
  3719. var eleTable = document.querySelector("#keylist > table:nth-child(1) > tbody:nth-child(1)");
  3720. if (eleTable)
  3721. {
  3722. var newInner = "";
  3723. for (var i = 0; i < keyArr.length; i++)
  3724. {
  3725. newInner += valArr[keyArr[i]];
  3726. }
  3727. eleTable.innerHTML = newInner;
  3728. }
  3729. }
  3730. }
  3731. var activeHideStatus = [0, 0, 0, 0, 0, 0];
  3732. // notTranslated, suggested, resuggested, approved, declined, translated
  3733. var activeHideKey = [0, 0, 0, 0, 0, 0];
  3734. // app, game, faq, support, promo, email
  3735. var activeHideStr = [0, 0];
  3736. // notMatch, long
  3737. var activeSort = -1;
  3738. var eleBtnShowAll = document.querySelector("#stsh_showing_all");
  3739. if (eleBtnShowAll)
  3740. {
  3741. eleBtnShowAll.addEventListener("click", function()
  3742. {
  3743. var elesBtnShowing = document.querySelectorAll(
  3744. ".stsh_showing_status, .stsh_showing_key, .stsh_showing_str");
  3745. for (var i = 0; i < elesBtnShowing.length; i++)
  3746. {
  3747. elesBtnShowing[i].disabled = false;
  3748. }
  3749. for (var i = 0; i < activeHideStatus.length; i++)
  3750. {
  3751. activeHideStatus[i] = 0;
  3752. }
  3753. for (var i = 0; i < activeHideKey.length; i++)
  3754. {
  3755. activeHideKey[i] = 0;
  3756. }
  3757. for (var i = 0; i < activeHideStr.length; i++)
  3758. {
  3759. activeHideStr[i] = 0;
  3760. }
  3761. activeSort = -1;
  3762. hideKey(-1); // Show all
  3763. countShowing();
  3764. });
  3765. }
  3766.  
  3767. var elesBtnShowingStatus = document.querySelectorAll(".stsh_showing_status");
  3768. for (var i = 0; i < elesBtnShowingStatus.length; i++)
  3769. {
  3770. elesBtnShowingStatus[i].addEventListener("click", function(ev)
  3771. {
  3772. var mode = parseInt(ev.target.dataset.hidestatus) || 0;
  3773. activeHideStatus[mode] = 1;
  3774. hideStatus(mode);
  3775. ev.target.disabled = true;
  3776. });
  3777. }
  3778. var obTarget_hider = document.querySelector("#keylist_container");
  3779. if (obTarget_hider)
  3780. {
  3781. var obMu_hider = new MutationObserver(function(mutations)
  3782. {
  3783. mutations.forEach(function(mutation)
  3784. {
  3785. //console.log("obMu_hider");
  3786. for (var i = 0; i < activeHideStatus.length; i++)
  3787. {
  3788. if (activeHideStatus[i] === 1)
  3789. {
  3790. hideStatus(i);
  3791. }
  3792. }
  3793. for (var i = 0; i < activeHideKey.length; i++)
  3794. {
  3795. if (activeHideKey[i] === 1)
  3796. {
  3797. hideKey(i);
  3798. }
  3799. }
  3800. for (var i = 0; i < activeHideStr.length; i++)
  3801. {
  3802. if (activeHideStr[i] === 1)
  3803. {
  3804. hideStr(i);
  3805. }
  3806. }
  3807. sortKey(activeSort);
  3808. });
  3809. });
  3810. var obConfig_hider = { childList: true };
  3811. obMu_hider.observe(obTarget_hider, obConfig_hider);
  3812. }
  3813.  
  3814. var elesBtnSort = document.querySelectorAll(".stsh_sort");
  3815. for (var i = 0; i < elesBtnSort.length; i++)
  3816. {
  3817. elesBtnSort[i].addEventListener("click", function(ev)
  3818. {
  3819. var mode = parseInt(ev.target.dataset.sort) || 0;
  3820. activeSort = mode;
  3821. sortKey(activeSort);
  3822. });
  3823. }
  3824.  
  3825. function setVisibleKey(startKey, visible)
  3826. {
  3827. // Use ("", true) to show all
  3828. startKey = startKey.toLowerCase();
  3829. var display = visible !== true ? "none" : "";
  3830. var eleKeys = document.querySelectorAll
  3831. (" \
  3832. #keylist > table:nth-child(1) \
  3833. > tbody:nth-child(1) > tr > td:nth-child(1) > div:nth-child(1) \
  3834. > table:nth-child(1) > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(1) \
  3835. ");
  3836. for (var i = 0; i < eleKeys.length; i++)
  3837. {
  3838. try
  3839. {
  3840. if (eleKeys[i].textContent.trim().toLowerCase().indexOf(startKey) > -1)
  3841. {
  3842. var eleTarget = eleKeys[i].parentElement.parentElement.parentElement
  3843. .parentElement.parentElement.parentElement;
  3844. if (visible && eleTarget.classList.contains("stsh_hidden"))
  3845. {
  3846. eleTarget.classList.remove("stsh_hidden");
  3847. }
  3848. else if (!visible && !eleTarget.classList.contains("stsh_hidden"))
  3849. {
  3850. eleTarget.classList.add("stsh_hidden");
  3851. }
  3852. }
  3853. }
  3854. catch (ex)
  3855. {
  3856. console.error("setVisibleKey", ex.message);
  3857. }
  3858. }
  3859. }
  3860. function hideKey(mode)
  3861. {
  3862. /*
  3863. mode:
  3864. -1: showAll
  3865. 0: app
  3866. 1: game
  3867. 2: faq
  3868. 3: support
  3869. 4: promo
  3870. 5: email
  3871. */
  3872. if (mode === -1) // showAll
  3873. {
  3874. setVisibleKey("", true);
  3875. }
  3876. else if (mode === 0) // app
  3877. {
  3878. setVisibleKey("# storefront_english_apps.txt #", false);
  3879. setVisibleKey("# storefront_english_main.txt # #app_", false);
  3880. setVisibleKey("# community_english.txt # SharedFiles_App_", false);
  3881. setVisibleKey("# appmgmt_english.txt #", false);
  3882. setVisibleKey("STEAM/VR", false);
  3883. }
  3884. else if (mode === 1) // game
  3885. {
  3886. setVisibleKey("GAMES/", false);
  3887. setVisibleKey("TF_", false);
  3888. }
  3889. else if (mode === 2) // faq
  3890. {
  3891. setVisibleKey("# support_faq_english.txt #", false);
  3892. }
  3893. else if (mode === 3) // support
  3894. {
  3895. setVisibleKey("# supportui_english.txt #", false);
  3896. setVisibleKey("# help_english.txt #", false);
  3897. }
  3898. else if (mode === 4) // promo
  3899. {
  3900. setVisibleKey("#promo", false);
  3901. setVisibleKey("#hardware", false);
  3902. setVisibleKey("ControllerBinding", false);
  3903. setVisibleKey("Library_Controller", false);
  3904. setVisibleKey("STEAM/HARDWARE", false);
  3905. setVisibleKey("STEAM/DELTA", false);
  3906. setVisibleKey("GAMES/KILLINGFLOOR2", false);
  3907. }
  3908. else if (mode === 5) // email
  3909. {
  3910. setVisibleKey("#email", false);
  3911. }
  3912. }
  3913. var elesBtnShowingKey = document.querySelectorAll(".stsh_showing_key");
  3914. for (var i = 0; i < elesBtnShowingKey.length; i++)
  3915. {
  3916. elesBtnShowingKey[i].addEventListener("click", function(ev)
  3917. {
  3918. var mode = parseInt(ev.target.dataset.hidekey) || 0;
  3919. activeHideKey[mode] = 1;
  3920. hideKey(mode);
  3921. ev.target.disabled = true;
  3922. });
  3923. }
  3924. function hideStr(mode)
  3925. {
  3926. /*
  3927. mode:
  3928. 0: notMatch
  3929. 1: long
  3930. */
  3931. if (mode === 0) // notMatch
  3932. {
  3933. var searchStr = decodeURIComponent(getQueryByName("search_input")).replace(/\\+/g," ").trim();
  3934. searchStr = searchStr.toLowerCase();
  3935. var eleStrs = document.querySelectorAll
  3936. (" \
  3937. #keylist \
  3938. > table:nth-child(1) > tbody:nth-child(1) > tr > td:nth-child(1) > div:nth-child(1) \
  3939. > table:nth-child(1) > tbody:nth-child(2) > tr:nth-child(2) \
  3940. ");
  3941. for (var i = 0; i < eleStrs.length; i++)
  3942. {
  3943. try
  3944. {
  3945. var valStr = eleStrs[i].children[0].textContent.trim().toLowerCase();
  3946. var valTrn = eleStrs[i].children[2].textContent.trim().toLowerCase();
  3947. if (valStr !== searchStr && valTrn !== searchStr)
  3948. {
  3949. var eleTarget = eleStrs[i].parentElement.parentElement
  3950. .parentElement.parentElement.parentElement;
  3951. if (!eleTarget.classList.contains("stsh_hidden"))
  3952. {
  3953. eleTarget.classList.add("stsh_hidden");
  3954. }
  3955. }
  3956. }
  3957. catch (ex)
  3958. {
  3959. console.error("hideStrNotMatch", ex.message);
  3960. }
  3961. }
  3962. }
  3963. else if (mode === 1) // long
  3964. {
  3965. var dot = "...";
  3966. var dotLengthMinus = 0 - dot.length;
  3967. var eleStrs = document.querySelectorAll
  3968. (" \
  3969. #keylist \
  3970. > table:nth-child(1) > tbody:nth-child(1) > tr > td:nth-child(1) > div:nth-child(1) \
  3971. > table:nth-child(1) > tbody:nth-child(2) > tr:nth-child(2) > td:nth-child(1) \
  3972. ");
  3973. for (var i = 0; i < eleStrs.length; i++)
  3974. {
  3975. try
  3976. {
  3977. var valStr = eleStrs[i].textContent.trim();
  3978. if (valStr.substr(dotLengthMinus) === dot)
  3979. {
  3980. var eleTarget = eleStrs[i].parentElement.parentElement
  3981. .parentElement.parentElement.parentElement.parentElement;
  3982. if (!eleTarget.classList.contains("stsh_hidden"))
  3983. {
  3984. eleTarget.classList.add("stsh_hidden");
  3985. }
  3986. }
  3987. }
  3988. catch (ex)
  3989. {
  3990. console.error("hideStrLong", ex.message);
  3991. }
  3992. }
  3993. }
  3994. }
  3995. var elesBtnShowingStr = document.querySelectorAll(".stsh_showing_str");
  3996. for (var i = 0; i < elesBtnShowingStr.length; i++)
  3997. {
  3998. elesBtnShowingStr[i].addEventListener("click", function(ev)
  3999. {
  4000. var mode = parseInt(ev.target.dataset.hidestr) || 0;
  4001. activeHideStr[mode] = 1;
  4002. hideStr(mode);
  4003. ev.target.disabled = true;
  4004. });
  4005. }
  4006. } // End Hide & sort suggestions
  4007.  
  4008. resizeSuggestionBox();
  4009. // Add Frame button when iframe load failed
  4010. {
  4011. var obTarget_ifrm = document.querySelector("#suggestions_iframe");
  4012. if (obTarget_ifrm)
  4013. {
  4014. var obMu_ifrm = new MutationObserver(function(mutations)
  4015. {
  4016. mutations.forEach(function(mutation)
  4017. {
  4018. var divFrame = document.querySelector("#stsh_frame");
  4019. if (!divFrame)
  4020. {
  4021. var divOuter = document.querySelector("#suggestions_box_outer");
  4022. if (divOuter)
  4023. {
  4024. divFrame = document.createElement("div");
  4025. divFrame.id = "stsh_frame";
  4026. divOuter.appendChild(divFrame);
  4027. }
  4028. }
  4029. if (divFrame)
  4030. {
  4031. var ifrm = document.querySelector("#suggestions_iframe");
  4032. if (ifrm)
  4033. {
  4034. var src = ifrm.getAttribute("src");
  4035. var token = getQueryByName("token_key", src);
  4036. divFrame.innerHTML =
  4037. ' \
  4038. <br/><br/> \
  4039. <div id="stsh_frame_sub"> \
  4040. Token: <span class="stsh_blue">' + token + '</span> \
  4041. <br/><br/> \
  4042. <a class="stsh_a_button" target="_blank" href="' + src + '">Frame</a> \
  4043. <br/><br/> \
  4044. This frame may be blocked by ad blocker software. \
  4045. <br/> \
  4046. Please whitelist https://translation.steampowered.com to prevent this missing frame. \
  4047. </div> \
  4048. ';
  4049. }
  4050. }
  4051. });
  4052. });
  4053.  
  4054. var obConfig_ifrm = { attributes: true, attributeFilter: ["src"] };
  4055. obMu_ifrm.observe(obTarget_ifrm, obConfig_ifrm);
  4056. }
  4057. }
  4058. // Open frame if only one string
  4059. {
  4060. setTimeoutCustom(function()
  4061. {
  4062. var elesCopy = document.querySelectorAll("#keylist .copysmall");
  4063. if (elesCopy.length === 1)
  4064. {
  4065. var eleDiv = elesCopy[0].parentElement.parentElement.parentElement;
  4066. if (eleDiv.tagName === "DIV")
  4067. {
  4068. if (!isVisible())
  4069. {
  4070. eleDiv.click();
  4071. }
  4072. }
  4073. }
  4074. }, 1000);
  4075. }
  4076. // Clean timestamp
  4077. {
  4078. var eleInputTime = document.querySelector("input[name='t']");
  4079. if (eleInputTime)
  4080. {
  4081. eleInputTime.parentElement.removeChild(eleInputTime);
  4082. }
  4083. }
  4084. // fix STS search options
  4085. {
  4086. for (var i = 0; i < 6; i++)
  4087. {
  4088. var elesSort = document.querySelectorAll("#search #sort" + i);
  4089. if (elesSort.length === 2)
  4090. {
  4091. elesSort[1].id = "status" + i;
  4092. }
  4093. }
  4094. var elesLabel = document.querySelectorAll("#search label[for='sort0']");
  4095. if (elesLabel.length === 2)
  4096. {
  4097. elesLabel[1].setAttribute("for", "status0");
  4098. }
  4099. }
  4100. } // End translate.php
  4101.  
  4102. if (url.indexOf("user_activity.php") > -1)
  4103. {
  4104. var user = "";
  4105. var eleAvatar = document.querySelector(".friend_block_avatar > a[href^='https://steamcommunity.com']");
  4106. if (eleAvatar)
  4107. {
  4108. eleAvatar.href = eleAvatar.href.replace("https://steamcommunity.com", "http://steamcommunity.com");
  4109. if (eleAvatar.href.indexOf("http://steamcommunity.com/profiles/") === 0)
  4110. {
  4111. user = eleAvatar.href.replace("http://steamcommunity.com/profiles/", "");
  4112. }
  4113. var name = eleAvatar.firstElementChild.getAttribute("title");
  4114. if (name === "")
  4115. {
  4116. name = user;
  4117. }
  4118. document.title = name + " - " + document.title;
  4119. }
  4120.  
  4121. var stsh_activityAddLink_start = new Date();
  4122. var stsh_activityAddLink_itv = setIntervalCustom(function(user)
  4123. {
  4124. // Add more links in user activity
  4125. var stsh_activityAddLink_isEnd = false;
  4126. var stsh_activityAddLink_cur = new Date();
  4127. var h3s = document.querySelectorAll("#leftAreaContainer h3");
  4128. if (h3s.length === 2)
  4129. {
  4130. var td = h3s[1].parentElement;
  4131. var matchArr = td.innerHTML.match(/<\/h3>.+<br>/i);
  4132. if (matchArr)
  4133. {
  4134. var name = matchArr[0]
  4135. .replace("</h3>-", "")
  4136. .replace("-<br>", "")
  4137. .replace("<br>", "")
  4138. .trim();
  4139. if (name === "")
  4140. {
  4141. name = user;
  4142. }
  4143. if (name === "")
  4144. {
  4145. name = "Steam";
  4146. }
  4147. var tagNew = "";
  4148. if (user === "")
  4149. {
  4150. tagNew =
  4151. "\
  4152. </h3>\
  4153. <a id='stsh_sectionId' class='stsh_blue' target='_blank' href='http://steamcommunity.com/my'>\
  4154. " + name + "</a>, \
  4155. <a class='stsh_green' target='_blank' href='/WhereIsEsty.php'>Esty</a><br><br>\
  4156. ";
  4157. }
  4158. else
  4159. {
  4160. tagNew =
  4161. "\
  4162. </h3>\
  4163. <a id='stsh_sectionId' class='stsh_blue' target='_blank' href='http://steamcommunity.com/profiles/" + user + "'>\
  4164. " + name + "</a>, \
  4165. <a class='stsh_green' target='_blank' href='/WhereIsEsty.php?collectionof=" + user + "'>Esty</a>\
  4166. "
  4167. /*
  4168. // Typonion
  4169. + ", <a class='stsh_green' target='_blank' href='/translate.php?user="
  4170. + user + "&onionhunter=1&liststatus=1'>Onion</a>
  4171. */
  4172. + " <br><br> ";
  4173. }
  4174. td.innerHTML = td.innerHTML.replace(/<\/h3>.+<br>/i, tagNew);
  4175. stsh_activityAddLink_isEnd = true;
  4176. }
  4177. if (stsh_activityAddLink_isEnd || stsh_activityAddLink_cur - stsh_activityAddLink_start > 10000)
  4178. {
  4179. clearInterval(stsh_activityAddLink_itv);
  4180. }
  4181. }
  4182. }, 300, user);
  4183. var countWord = "";
  4184. var countSugg = "";
  4185. var inputDials = document.querySelectorAll("#leftAreaContainer input.dial");
  4186. if (inputDials.length === 2)
  4187. {
  4188. countWord = inputDials[0].getAttribute("title").replace("words", "").trim();
  4189. countSugg = inputDials[1].getAttribute("title").replace("suggestions", "").trim();
  4190. }
  4191. var tdCount = document.querySelector("#leftAreaContainer td[align='left']");
  4192. if (tdCount)
  4193. {
  4194. tdCount.innerHTML =
  4195. '\
  4196. <div style="width: 100px; display: inline-block; text-align: center;">Word: ' + countWord + '</div> \
  4197. <div style="width: 100px; display: inline-block; text-align: center; margin-left: 13px;">Suggestion: ' + countSugg + '</div>\
  4198. ';
  4199. }
  4200. var sug = document.body.textContent;
  4201. var regComment = /VIEW COMMENT/g;
  4202. var regSuggest = /VIEW SUGGESTION/g;
  4203. var strComment = "...RECEIVED A MODERATOR COMMENT";
  4204. var strPending = "...ARE PENDING";
  4205. var strApproved = "...WERE APPROVED";
  4206. var strDeclined = "...WERE DECLINED";
  4207. var strApplied = "...HAVE BEEN APPLIED WITHIN THE LAST 14 DAYS";
  4208. var strRemoved = "...HAVE BEEN REMOVED WITHIN THE LAST 14 DAYS";
  4209. var startComment = sug.indexOf(strComment);
  4210. var startPending = sug.indexOf(strPending);
  4211. var startApproved = sug.indexOf(strApproved);
  4212. var startDeclined = sug.indexOf(strDeclined);
  4213. var startApplied = sug.indexOf(strApplied);
  4214. var startRemoved = sug.indexOf(strRemoved);
  4215. var sugComment = sug.substring(startComment,startPending);
  4216. var sugPending = sug.substring(startPending,startApproved);
  4217. var sugApproved = sug.substring(startApproved,startDeclined);
  4218. var sugDeclined = sug.substring(startDeclined,startApplied);
  4219. var sugApplied = sug.substring(startApplied,startRemoved);
  4220. var sugRemoved = sug.substring(startRemoved);
  4221. var countComment = (sugComment.match(regComment) || []).length;
  4222. var countPending = (sugPending.match(regSuggest) || []).length;
  4223. var countApproved = (sugApproved.match(regSuggest) || []).length;
  4224. var countDeclined = (sugDeclined.match(regSuggest) || []).length;
  4225. var countApplied = (sugApplied.match(regSuggest) || []).length;
  4226. var countRemoved = (sugRemoved.match(regSuggest) || []).length;
  4227. var divBtn = document.createElement("div");
  4228. document.body.appendChild(divBtn);
  4229. divBtn.innerHTML =
  4230. ' \
  4231. <div style="position: fixed; z-index: 3; right: 12px; top: 84px; line-height: 24px; text-align: right;"> \
  4232. &nbsp; <input id="stsh_btnToProgress" value="To Progress" class="stsh_btn_long" type="button" \
  4233. onclick="scrollToId(\'stsh_sectionId\', -50); return false;" /><br/> \
  4234. \
  4235. &nbsp; <span class="stsh_scroll_header">Scroll To</span>\
  4236. <li class="stsh_suggestion_btn stsh_suggestion stsh_suggestion_comment"><input value="Comment (' + countComment + ')" \
  4237. class="stsh_btn_long" type="button" onclick="scrollToId(\'stsh_sectionComment\'); return false;" ></li> \
  4238. <li class="stsh_suggestion_btn stsh_suggestion stsh_suggestion_pending"><input value="Pending (' + countPending + ')" \
  4239. class="stsh_btn_long" type="button" onclick="scrollToId(\'stsh_sectionPending\'); return false;" ></li> \
  4240. <li class="stsh_suggestion_btn stsh_suggestion stsh_suggestion_approved"><input value="Approved (' + countApproved + ')" \
  4241. class="stsh_btn_long" type="button" onclick="scrollToId(\'stsh_sectionApproved\'); return false;" ></li> \
  4242. <li class="stsh_suggestion_btn stsh_suggestion stsh_suggestion_declined"><input value="Declined (' + countDeclined + ')" \
  4243. class="stsh_btn_long" type="button" onclick="scrollToId(\'stsh_sectionDeclined\'); return false;" ></li> \
  4244. <li class="stsh_suggestion_btn stsh_suggestion stsh_suggestion_applied"><input value="Applied (' + countApplied + ')" \
  4245. class="stsh_btn_long" type="button" onclick="scrollToId(\'stsh_sectionApplied\'); return false;" ></li> \
  4246. <li class="stsh_suggestion_btn stsh_suggestion stsh_suggestion_removed"><input value="Removed (' + countRemoved + ')" \
  4247. class="stsh_btn_long" type="button" onclick="scrollToId(\'stsh_sectionRemoved\'); return false;" ></li> \
  4248. <br/> \
  4249. &nbsp; <input value="Hide Suggestions" class="stsh_btn_long" type="button" onclick="hideSuggestion(); return false;" /><br/> \
  4250. &nbsp; <input value="Show Suggestions" class="stsh_btn_long" type="button" onclick="showSuggestion(); return false;" /><br/> \
  4251. <br/> \
  4252. &nbsp; <input value="Refresh" class="stsh_btn_long" type="button" onclick="window.location = window.location.href; return false;" /><br/> \
  4253. </div> \
  4254. ';
  4255.  
  4256. var divContainer = document.querySelector("#leftAreaContainer");
  4257. if (divContainer)
  4258. {
  4259. var inner = divContainer.innerHTML;
  4260. var htmlPending = /\.\.\.ARE \<a [^\<]+\>PENDING\<\/a\>/i.exec(inner);
  4261. var htmlApproved = /\.\.\.WERE \<a [^\<]+\>APPROVED\<\/a\>/i.exec(inner);
  4262. var htmlDeclined = /\.\.\.WERE \<a [^\<]+\>DECLINED\<\/a\>/i.exec(inner);
  4263. if (htmlPending && htmlApproved && htmlDeclined)
  4264. {
  4265. divContainer.innerHTML = inner
  4266. .replace("...RECEIVED A MODERATOR COMMENT",
  4267. "<span id='stsh_sectionComment' class='stsh_suggestion_header'>"
  4268. + "...RECEIVED A MODERATOR COMMENT ("
  4269. + countComment + ")</span>")
  4270. .replace(htmlPending,
  4271. "<span id='stsh_sectionPending' class='stsh_suggestion_header'>" + htmlPending + " ("
  4272. + countPending + ")</span>")
  4273. .replace(htmlApproved,
  4274. "<span id='stsh_sectionApproved' class='stsh_suggestion_header'>" + htmlApproved + " ("
  4275. + countApproved + ")</span>")
  4276. .replace(htmlDeclined,
  4277. "<span id='stsh_sectionDeclined' class='stsh_suggestion_header'>" + htmlDeclined + " ("
  4278. + countDeclined + ")</span>")
  4279. .replace("...HAVE BEEN APPLIED WITHIN THE LAST 14 DAYS",
  4280. "<span id='stsh_sectionApplied' class='stsh_suggestion_header'>"
  4281. + "...HAVE BEEN APPLIED WITHIN THE LAST 14 DAYS ("
  4282. + countApplied + ")</span>")
  4283. .replace("...HAVE BEEN REMOVED WITHIN THE LAST 14 DAYS",
  4284. "<span id='stsh_sectionRemoved' class='stsh_suggestion_header'>"
  4285. + "...HAVE BEEN REMOVED WITHIN THE LAST 14 DAYS ("
  4286. + countRemoved + ")</span>");
  4287. }
  4288. }
  4289. if (document.querySelector("#hours"))
  4290. {
  4291. var eleBtn = document.querySelector("#stsh_btnToProgress");
  4292. if (eleBtn)
  4293. {
  4294. var ele = document.createElement("input");
  4295. ele.classList.add("stsh_btn_long");
  4296. ele.setAttribute("value", "To Hours");
  4297. ele.setAttribute("type", "button");
  4298. ele.setAttribute("onclick", "scrollToElement(\"input[name*='[remarks]']\", -48); return false;");
  4299. insertAfterElement(ele, eleBtn);
  4300. ele = document.createTextNode(" \u00A0 ");
  4301. insertAfterElement(ele, eleBtn);
  4302. ele = document.createElement("br");
  4303. insertAfterElement(ele, eleBtn);
  4304. }
  4305. }
  4306. var cans = document.querySelectorAll("canvas");
  4307. for (var i = 0; i < cans.length; i++)
  4308. {
  4309. cans[i].parentElement.removeChild(cans[i]);
  4310. }
  4311. var aKeys = document.querySelectorAll("#leftAreaContainer li > a:nth-child(1)");
  4312. for (var i = 0; i < aKeys.length; i++)
  4313. {
  4314. var key = aKeys[i].textContent;
  4315. var keyArr = key.substr(21).trim().split(" >> ");
  4316. keyArr[0] = "<span style='color: #FFF !important;'>" + keyArr[0] + "</span>";
  4317. var keyNew = key.substr(0,21) + keyArr.join(" >> ") + "";
  4318. aKeys[i].innerHTML = keyNew;
  4319. }
  4320. var sugModeComment = 0;
  4321. var sugModePending = 1;
  4322. var sugModeApproved = 2;
  4323. var sugModeDeclined = 3;
  4324. var sugModeApplied = 4;
  4325. var sugModeRemoved = 5;
  4326. var sugMode = sugModeComment;
  4327. var eleSugFirst = document.querySelector
  4328. (" \
  4329. #leftAreaContainer > a[href^='translate.php?search_input='] \
  4330. , #leftAreaContainer > form > a[href^='translate.php?search_input='] \
  4331. ");
  4332. if (eleSugFirst)
  4333. {
  4334. var eleSugHeadPrev = eleSugFirst.previousElementSibling.previousElementSibling;
  4335. if (eleSugHeadPrev.id === "stsh_sectionRemoved")
  4336. {
  4337. sugMode = sugModeRemoved;
  4338. }
  4339. else if (eleSugHeadPrev.id === "stsh_sectionApplied")
  4340. {
  4341. sugMode = sugModeApplied;
  4342. }
  4343. else if (eleSugHeadPrev.id === "stsh_sectionDeclined")
  4344. {
  4345. sugMode = sugModeDeclined;
  4346. }
  4347. else if (eleSugHeadPrev.id === "stsh_sectionApproved")
  4348. {
  4349. sugMode = sugModeApproved;
  4350. }
  4351. else if (eleSugHeadPrev.id === "stsh_sectionPending")
  4352. {
  4353. sugMode = sugModePending;
  4354. }
  4355. var eleSugNext = eleSugFirst;
  4356. while (eleSugNext)
  4357. {
  4358. if (eleSugNext.tagName === "A")
  4359. {
  4360. var attrHref = eleSugNext.getAttribute("href");
  4361. if (attrHref && attrHref.indexOf("translate.php?search_input=") === 0)
  4362. {
  4363. eleSugNext.classList.add("stsh_suggestion");
  4364. if (sugMode === sugModeComment)
  4365. {
  4366. eleSugNext.classList.add("stsh_suggestion_comment");
  4367. }
  4368. else if (sugMode === sugModePending)
  4369. {
  4370. eleSugNext.classList.add("stsh_suggestion_pending");
  4371. }
  4372. else if (sugMode === sugModeApproved)
  4373. {
  4374. eleSugNext.classList.add("stsh_suggestion_approved");
  4375. }
  4376. else if (sugMode === sugModeDeclined)
  4377. {
  4378. eleSugNext.classList.add("stsh_suggestion_declined");
  4379. }
  4380. else if (sugMode === sugModeApplied)
  4381. {
  4382. eleSugNext.classList.add("stsh_suggestion_applied");
  4383. }
  4384. else if (sugMode === sugModeRemoved)
  4385. {
  4386. eleSugNext.classList.add("stsh_suggestion_removed");
  4387. }
  4388. }
  4389. }
  4390. else if (eleSugNext.tagName === "SPAN" && eleSugNext.classList.contains("stsh_suggestion_header"))
  4391. {
  4392. if (eleSugNext.id === "stsh_sectionRemoved")
  4393. {
  4394. sugMode = sugModeRemoved;
  4395. }
  4396. else if (eleSugNext.id === "stsh_sectionApplied")
  4397. {
  4398. sugMode = sugModeApplied;
  4399. }
  4400. else if (eleSugNext.id === "stsh_sectionDeclined")
  4401. {
  4402. sugMode = sugModeDeclined;
  4403. }
  4404. else if (eleSugNext.id === "stsh_sectionApproved")
  4405. {
  4406. sugMode = sugModeApproved;
  4407. }
  4408. else if (eleSugNext.id === "stsh_sectionPending")
  4409. {
  4410. sugMode = sugModePending;
  4411. }
  4412. }
  4413. eleSugNext = eleSugNext.nextElementSibling;
  4414. }
  4415. }
  4416. // Change language & correct url
  4417. {
  4418. var aProgresses = document.querySelectorAll("div > .friend_block_avatar a[onmouseout]");
  4419. for (var i = 0; i < aProgresses.length; i++)
  4420. {
  4421. var langCur = getQueryByName("lang", aProgresses[i].href);
  4422. if (langCur === "")
  4423. {
  4424. aProgresses[i].href = aProgresses[i].href + lang;
  4425. }
  4426. else
  4427. {
  4428. if (langCur !== lang)
  4429. {
  4430. //var langQuery = (url.indexOf("?") > -1) ? "&lang=" : "?lang=";
  4431. //window.location = url + langQuery + langCur;
  4432. console.log("Lang: " + langCur);
  4433. }
  4434. }
  4435. var aContent = aProgresses[i].textContent.trim();
  4436. if (aContent.indexOf("SUGGESTIONS") > -1)
  4437. {
  4438. aProgresses[i].href = aProgresses[i].href + "&listsort=5&liststatus=1&paginationrows=1000";
  4439. }
  4440. else if (aContent.indexOf("REVIEWS") > -1)
  4441. {
  4442. aProgresses[i].href = aProgresses[i].href + "&listsort=5&liststatus=3&paginationrows=1000";
  4443. }
  4444. }
  4445. }
  4446. // Hours
  4447. if (document.querySelector("#hours"))
  4448. {
  4449. function calculateHours()
  4450. {
  4451. var rgxDate = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
  4452. var rgxTime = /^(\d{1,2}:\d{2}(:\d{2})?|\d{1,2}\.\d{2})$/;
  4453. var eleFrom = document.querySelector("#stsh_hoursCalc_from");
  4454. var eleTo = document.querySelector("#stsh_hoursCalc_to");
  4455. var eleRes = document.querySelector("#stsh_hoursCalc_result");
  4456. if (eleFrom && eleTo && eleRes)
  4457. {
  4458. var rawFrom = eleFrom.value.trim();
  4459. var rawTo = eleTo.value.trim();
  4460. var valFrom = 0;
  4461. var valTo = 0;
  4462. if (rgxDate.test(rawFrom))
  4463. {
  4464. rawFrom = rawFrom.substr(11);
  4465. }
  4466. if (rgxTime.test(rawFrom))
  4467. {
  4468. var arrTime = rawFrom.split(":");
  4469. if (arrTime.length === 1)
  4470. {
  4471. arrTime = rawFrom.split(".");
  4472. }
  4473. valFrom = parseInt(arrTime[1]) + (parseInt(arrTime[0]) * 60);
  4474. }
  4475. if (rgxDate.test(rawTo))
  4476. {
  4477. rawTo = rawTo.substr(11);
  4478. }
  4479. if (rgxTime.test(rawTo))
  4480. {
  4481. var arrTime = rawTo.split(":");
  4482. if (arrTime.length === 1)
  4483. {
  4484. arrTime = rawTo.split(".");
  4485. }
  4486. valTo = parseInt(arrTime[1]) + (parseInt(arrTime[0]) * 60);
  4487. }
  4488. var valDiff = Math.abs(valTo - valFrom);
  4489. var valHr = parseInt(valDiff / 60);
  4490. var valMn = valDiff % 60;
  4491. eleRes.textContent = padZero(valHr, 2) + ":" + padZero(valMn, 2);
  4492. }
  4493. }
  4494. var curDateStr = getDateUs();
  4495. // Add hours calculator
  4496. {
  4497. var eleFinalize = document.querySelector("#hours input[name='Finalize']");
  4498. if (eleFinalize)
  4499. {
  4500. var eleFinalizeParent = eleFinalize.parentElement;
  4501. eleFinalizeParent.setAttribute("colspan", "2");
  4502. eleFinalizeParent.style.verticalAlign = "top";
  4503. var elePad = document.createElement("td");
  4504. insertBeforeElement(elePad, eleFinalizeParent);
  4505. var eleCalc = document.createElement("td");
  4506. eleCalc.classList.add("stsh_hoursCalc");
  4507. insertBeforeElement(eleCalc, eleFinalizeParent);
  4508. if (eleCalc.parentElement.previousElementSibling.querySelector("input[type='radio']"))
  4509. {
  4510. eleCalc.appendChild(document.createElement("br"));
  4511. }
  4512. var ele = document.createElement("b");
  4513. ele.textContent = " Hours Calculator (Estimated) ";
  4514. eleCalc.appendChild(ele);
  4515. eleCalc.appendChild(document.createElement("br"));
  4516. ele = document.createElement("span");
  4517. ele.innerHTML =
  4518. ' \
  4519. Enter date or time to calculate range (calculate only hours and minutes). \
  4520. <br/>You can enter date "2016-01-01 08:05:00" or time "8:05" or time "8.05".\
  4521. ';
  4522. ele.setAttribute("style", "display: inline-block; padding-bottom: 4px;");
  4523. eleCalc.appendChild(ele);
  4524. eleCalc.appendChild(document.createElement("br"));
  4525. ele = document.createElement("span");
  4526. ele.textContent = " From: ";
  4527. eleCalc.appendChild(ele);
  4528. ele = document.createElement("input");
  4529. ele.id = "stsh_hoursCalc_from";
  4530. ele.setAttribute("type", "text");
  4531. ele.setAttribute("onkeypress", "return event.keyCode !== 13;");
  4532. ele.setAttribute("autocomplete", "off");
  4533. ele.addEventListener("keyup", function()
  4534. {
  4535. calculateHours();
  4536. });
  4537. eleCalc.appendChild(ele);
  4538. ele = document.createElement("span");
  4539. ele.innerHTML = "&nbsp;&nbsp; To: ";
  4540. eleCalc.appendChild(ele);
  4541. ele = document.createElement("input");
  4542. ele.id = "stsh_hoursCalc_to";
  4543. ele.setAttribute("type", "text");
  4544. ele.setAttribute("onkeypress", "return event.keyCode !== 13;");
  4545. ele.setAttribute("autocomplete", "off");
  4546. ele.addEventListener("keyup", function()
  4547. {
  4548. calculateHours();
  4549. });
  4550. eleCalc.appendChild(ele);
  4551. ele = document.createElement("input");
  4552. ele.id = "stsh_hoursCalc_toNow";
  4553. ele.setAttribute("type", "button");
  4554. ele.setAttribute("value", "Now");
  4555. ele.setAttribute("onclick", "return false;");
  4556. ele.addEventListener("click", function()
  4557. {
  4558. var eleTo = document.querySelector("#stsh_hoursCalc_to");
  4559. eleTo.value = getTimeUs();
  4560. calculateHours();
  4561. });
  4562. eleCalc.appendChild(ele);
  4563. ele = document.createElement("span");
  4564. ele.innerHTML = "&nbsp;&nbsp; Result: ";
  4565. eleCalc.appendChild(ele);
  4566. ele = document.createElement("b");
  4567. ele.id = "stsh_hoursCalc_result"
  4568. ele.textContent = " 00:00 ";
  4569. eleCalc.appendChild(ele);
  4570. }
  4571. }
  4572. // Hilight current date
  4573. {
  4574. var elesTd = document.querySelectorAll("#hours > table > tbody > tr > td:nth-child(1)");
  4575. for (var i = 0; i < elesTd.length; i++)
  4576. {
  4577. if (elesTd[i].textContent.indexOf(curDateStr) > -1)
  4578. {
  4579. elesTd[i].parentElement.id = "stsh_hours_curDate";
  4580. elesTd[i].parentElement.classList.add("stsh_hours_curDate");
  4581. break;
  4582. }
  4583. }
  4584. }
  4585. // Auto calculate hours in current date
  4586. {
  4587. var timePendingFirst = "";
  4588. var timePendingLast = "";
  4589. var elesPending = document.querySelectorAll("#mainbody .stsh_suggestion_pending");
  4590. for (var i = 0; i < elesPending.length; i++)
  4591. {
  4592. var content = elesPending[i].textContent.trim().substr(0, 19);
  4593. if (content.substr(0, 10) === curDateStr)
  4594. {
  4595. timePendingFirst = content.substr(11, 5);
  4596. if (timePendingLast === "")
  4597. {
  4598. timePendingLast = timePendingFirst;
  4599. }
  4600. }
  4601. else
  4602. {
  4603. break;
  4604. }
  4605. }
  4606. var timeApprovedFirst = "";
  4607. var timeApprovedLast = "";
  4608. var elesApproved = document.querySelectorAll("#mainbody .stsh_suggestion_approved");
  4609. for (var i = 0; i < elesApproved.length; i++)
  4610. {
  4611. var content = elesApproved[i].textContent.trim().substr(0, 19);
  4612. if (content.substr(0, 10) === curDateStr)
  4613. {
  4614. timeApprovedFirst = content.substr(11, 5);
  4615. if (timeApprovedLast === "")
  4616. {
  4617. timeApprovedLast = timeApprovedFirst;
  4618. }
  4619. }
  4620. else
  4621. {
  4622. break;
  4623. }
  4624. }
  4625. if (timePendingFirst === "")
  4626. {
  4627. timePendingFirst = timeApprovedFirst;
  4628. }
  4629. if (timeApprovedFirst === "")
  4630. {
  4631. timeApprovedFirst = timePendingFirst;
  4632. }
  4633. if (timePendingLast === "")
  4634. {
  4635. timePendingLast = timeApprovedLast;
  4636. }
  4637. if (timeApprovedLast === "")
  4638. {
  4639. timeApprovedLast = timePendingLast;
  4640. }
  4641. var timeFirst = timeApprovedFirst < timePendingFirst ? timeApprovedFirst : timePendingFirst;
  4642. var timeLast = timeApprovedLast > timePendingLast ? timeApprovedLast : timePendingLast;
  4643. if (timeFirst !== "")
  4644. {
  4645. var eleFrom = document.querySelector("#stsh_hoursCalc_from");
  4646. if (eleFrom)
  4647. {
  4648. eleFrom.value = timeFirst;
  4649. }
  4650. var eleTo = document.querySelector("#stsh_hoursCalc_to");
  4651. if (eleTo)
  4652. {
  4653. eleTo.value = timeLast;
  4654. }
  4655. calculateHours();
  4656. }
  4657. }
  4658. // Make minutes add to hours
  4659. setTimeoutCustom(function()
  4660. {
  4661. var elesMn = document.querySelectorAll("#hours input[name*='[minutes]']");
  4662. for (var i = 0; i < elesMn.length; i++)
  4663. {
  4664. elesMn[i].setAttribute("min", "-15");
  4665. elesMn[i].setAttribute("max", "60");
  4666. elesMn[i].addEventListener("change", function(ev)
  4667. {
  4668. var eleMn = ev.target;
  4669. var eleHr = eleMn.parentElement.previousElementSibling.firstElementChild;
  4670. var valMn = parseInt(eleMn.value) || 0;
  4671. var valHr = parseInt(eleHr.value) || 0;
  4672. if (valMn < 0)
  4673. {
  4674. if (valHr > 0)
  4675. {
  4676. eleHr.value = valHr - 1;
  4677. eleMn.value = 45;
  4678. }
  4679. else
  4680. {
  4681. eleMn.value = 0;
  4682. }
  4683. }
  4684. else if (valMn > 59)
  4685. {
  4686. if (valHr < 23)
  4687. {
  4688. eleHr.value = valHr + 1;
  4689. eleMn.value = 0;
  4690. }
  4691. else
  4692. {
  4693. eleMn.value = 45;
  4694. }
  4695. }
  4696. });
  4697. }
  4698. }, 500);
  4699. // Make deferred can be clicked
  4700. {
  4701. var eleDeferred = document.querySelector("#hours td > i > span[title^='DATE']");
  4702. if (eleDeferred)
  4703. {
  4704. eleDeferred.dataset.title = eleDeferred.title;
  4705. eleDeferred.title = "Click to reveal";
  4706. eleDeferred.addEventListener("click", function(ev)
  4707. {
  4708. var ele = ev.target;
  4709. var eleDetail = document.querySelector(".stsh_deferred");
  4710. if (!eleDetail)
  4711. {
  4712. eleDetail = document.createElement("div");
  4713. eleDetail.classList.add("stsh_deferred");
  4714. ele.parentElement.parentElement
  4715. .parentElement.parentElement
  4716. .lastElementChild.firstElementChild
  4717. .appendChild(eleDetail);
  4718. }
  4719. var space = String.fromCharCode(160);
  4720. var space3 = space + space + space;
  4721. eleDetail.innerHTML = "<br/>TOTAL DEFERRED HOURS" + space3 + " <br/>"
  4722. + ele.dataset.title.substr(61).trim()
  4723. .replace(/\n/g, space3 + " <br/>")
  4724. + space3;
  4725. });
  4726. }
  4727. }
  4728. }
  4729. // Hide wallet in other user pages
  4730. {
  4731. var eleASug = document.querySelector(".friend_block_avatar > a[href*='://translation.steampowered.com/translate.php'");
  4732. if (!eleASug || eleASug.textContent.trim() !== "YOUR SUGGESTIONS")
  4733. {
  4734. var elesAWallet = document.querySelectorAll("a[id^='walletkeys']");
  4735. for (var i = 0; i < elesAWallet.length; i++)
  4736. {
  4737. var eleCur = elesAWallet[i];
  4738. for (var j = 0; j < 5; j++)
  4739. {
  4740. eleCur.classList.add("stsh_hidden");
  4741. eleCur = eleCur.nextElementSibling;
  4742. }
  4743. }
  4744. }
  4745. }
  4746. } // End user_activity.php
  4747. if (/\/rally[0-9]{0,4}/.test(url))
  4748. {
  4749. resizeSuggestionBox();
  4750. var outer = document.querySelector("#suggestions_box_outer");
  4751. if (outer)
  4752. {
  4753. outer.setAttribute("onclick", "hideSuggestionsBox();");
  4754. }
  4755. // Set cur lang to first
  4756. {
  4757. var first = document.querySelector(".gradienttable tr:nth-child(6)");
  4758. if (first)
  4759. {
  4760. var cur = null;
  4761. var tdLangs = document.querySelectorAll(".gradienttable tr > td:nth-child(1)");
  4762. for (var i = 0; i < tdLangs.length; i++)
  4763. {
  4764. if (lang === tdLangs[i].textContent.trim().toLowerCase())
  4765. {
  4766. cur = tdLangs[i].parentElement;
  4767. break;
  4768. }
  4769. }
  4770. if (cur)
  4771. {
  4772. cur.classList.add("stsh_curLang");
  4773. first.parentElement.insertBefore(cur, first);
  4774. }
  4775. }
  4776. }
  4777. // Change row per page
  4778. {
  4779. var eleAs = document.querySelectorAll(".gradienttable tr:nth-child(6) a[href^='translate.php?']");
  4780. for (var i = 0; i < eleAs.length; i++)
  4781. {
  4782. eleAs[i].href = eleAs[i].href + "&paginationrows=1000";
  4783. }
  4784. }
  4785. var inputClose = document.querySelector("td:nth-child(3) > input:nth-child(1)");
  4786. if (inputClose)
  4787. {
  4788. inputClose.value = "Close (Esc)";
  4789. }
  4790. } // End rally.php
  4791. if (/\/rally_results_?[0-9]{0,4}/.test(url))
  4792. {
  4793. var h3 = document.querySelector("table.curved h3");
  4794. if (h3)
  4795. {
  4796. document.title = h3.textContent.trim();
  4797. }
  4798. var eleTable = document.querySelector("body > div:nth-child(1) > table:nth-child(1)");
  4799. if (eleTable)
  4800. {
  4801. eleTable.style.width = "";
  4802. }
  4803. var inputClose = document.querySelector("td:nth-child(3) > input:nth-child(1)");
  4804. if (inputClose)
  4805. {
  4806. inputClose.value = "Close (Esc)";
  4807. inputClose.focus();
  4808. }
  4809. // Add frame and background button
  4810. {
  4811. var eleTdFirst = document.querySelector("td:nth-child(1)");
  4812. if (eleTdFirst)
  4813. {
  4814. var eleTdFrame = document.createElement("td");
  4815. eleTdFrame.setAttribute("align", "right");
  4816. eleTdFrame.innerHTML =
  4817. ' <a class="stsh_a_button" target="_blank" href="' + url + '">Frame</a> ';
  4818. insertBeforeElement(eleTdFrame, eleTdFirst);
  4819. var img = document.body.style.backgroundImage;
  4820. if (img.indexOf("url(\"") === 0)
  4821. {
  4822. img = img.replace("url(\"", "").replace("\")", "");
  4823. var eleTdImage = document.createElement("td");
  4824. eleTdImage.setAttribute("align", "right");
  4825. eleTdImage.innerHTML =
  4826. ' <a class="stsh_a_button" target="_blank" href="' + img + '">View Background</a> ';
  4827. insertAfterElement(eleTdImage, eleTdFrame);
  4828. }
  4829. }
  4830. }
  4831. var inputPrev = document.querySelector("input[value^='Prev']");
  4832. if (inputPrev)
  4833. {
  4834. addKeyCtrl(document, inputPrev, 219, "[", 1|2); // [
  4835. addKeyCtrl(document, inputPrev, "BracketLeft"); // [
  4836. disableAfterClick(inputPrev);
  4837. }
  4838. var inputNext = document.querySelector("input[value^='Next']");
  4839. if (inputNext)
  4840. {
  4841. addKeyCtrl(document, inputNext, 221, "]", 1|2); // ]
  4842. addKeyCtrl(document, inputNext, "BracketRight"); // ]
  4843. disableAfterClick(inputNext);
  4844. }
  4845. // Hilight cur lang
  4846. {
  4847. var elesLang = document.querySelectorAll("table.curved > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(3) > h2:nth-child(1)");
  4848. for (var i = 0; i < elesLang.length; i++)
  4849. {
  4850. if (lang === elesLang[i].textContent.trim().toLowerCase())
  4851. {
  4852. var eleParent = elesLang[i].parentElement.parentElement.parentElement.parentElement;
  4853. //eleParent.style.backgroundColor = "#474D1A";
  4854. eleParent.classList.add("stsh_curLang");
  4855. eleParent.setAttribute("bgcolor", "#474D1A");
  4856. eleParent.setAttribute("onmouseout", "this.bgColor='#474D1A'");
  4857. eleParent.setAttribute("onmouseover", "this.bgColor='#76802B'");
  4858. break;
  4859. }
  4860. }
  4861. }
  4862. // Reset points position
  4863. {
  4864. var eleSpan = document.querySelector("h5 > span");
  4865. if (eleSpan)
  4866. {
  4867. eleSpan.parentElement.parentElement.removeAttribute("style");
  4868. }
  4869. }
  4870. } // End rally_results.php
  4871. if (/\/rallyreplay_?[0-9]{0,4}/.test(url))
  4872. {
  4873. // Set cur lang to first
  4874. {
  4875. var elesFrame = document.querySelectorAll("#leftAreaContainer div[id^='frame']");
  4876. for (var i = 0; i < elesFrame.length; i++)
  4877. {
  4878. var first = elesFrame[i].querySelector(".gradienttable tr:nth-child(6)");
  4879. if (first)
  4880. {
  4881. var cur = null;
  4882. var tdLangs = elesFrame[i].querySelectorAll(".gradienttable tr > td:nth-child(1)");
  4883. for (var j = 0; j < tdLangs.length; j++)
  4884. {
  4885. if (lang === tdLangs[j].textContent.trim().toLowerCase())
  4886. {
  4887. cur = tdLangs[j].parentElement;
  4888. break;
  4889. }
  4890. }
  4891. if (cur)
  4892. {
  4893. cur.classList.add("stsh_curLang");
  4894. first.parentElement.insertBefore(cur, first);
  4895. }
  4896. }
  4897. }
  4898. }
  4899. var eleBtn = document.querySelector("input[value='FASTEST']");
  4900. if (eleBtn)
  4901. {
  4902. var ele = document.createElement("input");
  4903. ele.setAttribute("type", "button");
  4904. ele.setAttribute("value", "RESTART");
  4905. ele.setAttribute("style", "padding: 0; border: none; background: none;");
  4906. ele.setAttribute("onclick",
  4907. " \
  4908. indexReplay = 0; \
  4909. elsFrame.eq(indexReplay).fadeOut(0, function() \
  4910. { \
  4911. indexReplay = (indexReplay + 1) % lenFrame; \
  4912. elsFrame.eq(indexReplay).fadeIn(0); \
  4913. }); \
  4914. ");
  4915. insertAfterElement(ele, eleBtn);
  4916. insertAfterElement(document.createTextNode(" | "), eleBtn);
  4917. }
  4918. } // End rallyreplay.php
  4919. if (url.indexOf("/WhereIsEsty.php") > -1)
  4920. {
  4921. resizeSuggestionBox();
  4922. var outer = document.querySelector("#suggestions_box_outer");
  4923. if (outer)
  4924. {
  4925. outer.setAttribute("onclick", "hideSuggestionsBox();");
  4926. }
  4927. var divContainer = document.querySelector("#pageContainer");
  4928. if (divContainer)
  4929. {
  4930. var ele = document.createElement("div");
  4931. ele.id = "logout";
  4932. ele.innerHTML =
  4933. ' <a class="stsh_a_button" target="_blank" href="/home.php">Home</a> ';
  4934. divContainer.appendChild(ele);
  4935. }
  4936.  
  4937. var divContent = document.querySelector("#leftAreaContainer > div");
  4938. if (divContent)
  4939. {
  4940. var countSnap = document.querySelectorAll("div.box").length;
  4941. var user = "";
  4942. var name = "";
  4943.  
  4944. var eleImg = document.querySelector("#leftAreaContainer > div > div > a > img ");
  4945. if (eleImg)
  4946. {
  4947. name = eleImg.getAttribute("title");
  4948. user = eleImg.parentElement.getAttribute("href").replace("https://steamcommunity.com/profiles/", "");
  4949. }
  4950. var ele = document.createElement("div");
  4951. ele.setAttribute("class", "stsh_snapshot");
  4952. ele.innerHTML = "<a class='stsh_blue' target='_blank' href='/user_activity.php?user="
  4953. + user + "'>" + name + "</a>"
  4954. + "<br>Snapshot: " + countSnap;
  4955.  
  4956. divContent.appendChild(ele);
  4957. }
  4958. } // End WhereIsEsty.php
  4959. if (url.indexOf("/stickerbox.php") > -1)
  4960. {
  4961. document.querySelector("textarea[name='add_comment']").focus();
  4962. var inputPrev = document.querySelector("img[src*='z0lEQVRIx5WWaWxVRRTH'");
  4963. if (inputPrev)
  4964. {
  4965. addKeyCtrl(document, inputPrev, 219); // [
  4966. addKeyCtrl(document, inputPrev, "BracketLeft"); // [
  4967. disableAfterClick(inputPrev);
  4968. }
  4969. var inputNext = document.querySelector("img[src*='40lEQVRIx5WWe0xXZRjH'");
  4970. if (inputNext)
  4971. {
  4972. addKeyCtrl(document, inputNext, 221); // ]
  4973. addKeyCtrl(document, inputNext, "BracketRight"); // ]
  4974. disableAfterClick(inputNext);
  4975. }
  4976. } // End stickerbox.php
  4977. if (/\/(home\.php|index\.php)/i.test(url))
  4978. {
  4979. // Set cur lang to first
  4980. {
  4981. var first = null;
  4982. var cur = null;
  4983. var curLang = lang.substring(0, 4);
  4984. if (curLang === "schi")
  4985. curLang = "sim.";
  4986. else if (curLang === "tchi")
  4987. curLang = "tra.";
  4988. var eleLangs = document.querySelectorAll("#overall .progress");
  4989. if (eleLangs.length > 0)
  4990. {
  4991. first = eleLangs[0];
  4992. for (var i = 0; i < eleLangs.length; i++)
  4993. {
  4994. if (curLang === eleLangs[i].textContent.trim().substring(0, 4).toLowerCase())
  4995. {
  4996. cur = eleLangs[i];
  4997. break;
  4998. }
  4999. }
  5000. if (cur)
  5001. {
  5002. var curSib1 = cur.nextSibling;
  5003. var curSib2 = curSib1.nextSibling;
  5004. var curSib3 = curSib2.nextSibling;
  5005. var curSib4 = curSib3.nextSibling;
  5006. var curSib5 = curSib4.nextSibling;
  5007. var curSib6 = curSib5.nextSibling;
  5008. insertBeforeElement(cur, first);
  5009. insertAfterElement(curSib6, cur);
  5010. insertAfterElement(curSib5, cur);
  5011. insertAfterElement(curSib4, cur);
  5012. insertAfterElement(curSib3, cur);
  5013. insertAfterElement(curSib2, cur);
  5014. insertAfterElement(curSib1, cur);
  5015. }
  5016. }
  5017. }
  5018. if (document.querySelector("#logout"))
  5019. {
  5020. var tmplHome =
  5021. ' \
  5022. <div class="stsh_home_group"> \
  5023. <span class="stsh_home_header">Shortcuts</span>\
  5024. <br/> &nbsp; <a class="stsh_a_button stsh_btn_med" target="_blank" \
  5025. href="/translate.php?search_input=DATE%3A+%DATE%&paginationrows=1000">New Today</a> &nbsp; \
  5026. <br/> &nbsp; <a class="stsh_a_button stsh_btn_med" target="_blank" href="/glossary.php">Glossary</a> &nbsp; \
  5027. \
  5028. <br/> <span class="stsh_home_header">Rally</span>\
  5029. <br/> &nbsp; <a class="stsh_a_button stsh_btn_med" target="_blank" href="/rally.php">Rally</a> &nbsp; \
  5030. %RALLY% \
  5031. \
  5032. <br/> <span class="stsh_home_header">Events</span>\
  5033. <br/> &nbsp; <a class="stsh_a_button stsh_btn_med" target="_blank" href="/rallyreplay.php">Rally Replay</a> &nbsp; \
  5034. <br/> &nbsp; <a class="stsh_a_button stsh_btn_med" target="_blank" href="/onionolooorm.php">Typonion</a> &nbsp; \
  5035. <br/> &nbsp; <a class="stsh_a_button stsh_btn_med" target="_blank" href="/dstbattle.php">DST Battle</a> &nbsp; \
  5036. <br/> &nbsp; <a class="stsh_a_button stsh_btn_med" target="_blank" href="/dota2.php">DOTA 2</a> &nbsp; \
  5037. <br/> \
  5038. </div> \
  5039. ';
  5040. tmplHome = tmplHome.replace("%DATE%", getDateUs());
  5041. // Rally
  5042. {
  5043. var date = new Date();
  5044. var yearLast = date.getUTCFullYear();
  5045. var yearFirst = 2013;
  5046. var strRally = "";
  5047. for (var i = yearLast; i >= yearFirst; i--)
  5048. {
  5049. if (i < yearLast || isRally())
  5050. {
  5051. strRally +=
  5052. ' \
  5053. <br/> &nbsp; \
  5054. <a class="stsh_a_button stsh_btn_med" target="_blank" href="/rally' + i + '.php">\
  5055. Rally ' + i + '</a> &nbsp; \
  5056. ';
  5057. }
  5058. }
  5059. tmplHome = tmplHome.replace("%RALLY%", strRally);
  5060. }
  5061. var eleNew = document.createElement("div");
  5062. eleNew.innerHTML = tmplHome;
  5063. document.body.appendChild(eleNew);
  5064. }
  5065. // Fix STS JS error
  5066. {
  5067. var eleTimer = document.querySelector("#timer");
  5068. if (!eleTimer)
  5069. {
  5070. var ele = document.createElement("div");
  5071. ele.id = "timer";
  5072. ele.classList.add("stsh_hidden");
  5073. document.body.appendChild(ele);
  5074. }
  5075. }
  5076. } // End home.php
  5077. if (url.indexOf("/glossary.php") > -1)
  5078. {
  5079. // Add shortcuts
  5080. {
  5081. var contentGlos =
  5082. ' \
  5083. <div class="stsh_home_group"> \
  5084. <span class="stsh_home_header">Shortcuts</span> \
  5085. <br/> &nbsp; \
  5086. <a class="stsh_a_button stsh_btn_med" target="_blank" \
  5087. href="/translate.php?chosenfile=1&listfilter=1&listsort=3&paginationrows=1000&branch_ID=49&file_ID=226"> \
  5088. Glossary</a> &nbsp; \
  5089. <br/> &nbsp; \
  5090. <a class="stsh_a_button stsh_btn_med" target="_blank" \
  5091. href="/translate.php?chosenfile=1&listfilter=1&listsort=3&paginationrows=1000&branch_ID=49&file_ID=232"> \
  5092. Phrases</a> &nbsp; \
  5093. <br/> \
  5094. </div> \
  5095. ';
  5096. var eleNew = document.createElement("div");
  5097. eleNew.innerHTML = contentGlos;
  5098. document.body.appendChild(eleNew);
  5099. }
  5100. // Improve glossary links
  5101. {
  5102. var elesLink = document.querySelectorAll("#votes_container > .lbAction a[href^='./translate.php?search_input=']");
  5103. for (var i = 0; i < elesLink.length; i++)
  5104. {
  5105. elesLink[i].href = elesLink[i].href.replace("keyonly=0", "keyonly=2")
  5106. .replace("listsort=0", "listsort=4")
  5107. .replace("paginationrows=50", "paginationrows=1000");
  5108. }
  5109. }
  5110. } // End glossary.php
  5111. if (url.indexOf("/dstbattle.php") > -1)
  5112. {
  5113. // Hilight cur lang
  5114. {
  5115. var cur = null;
  5116. var elesLang = document.querySelectorAll(".gradienttable > tbody:nth-child(1) > tr > th:nth-child(1)");
  5117. for (var i = 1; i < elesLang.length; i++)
  5118. {
  5119. if (lang === elesLang[i].textContent.trim().replace(/[0-9]+\. /, "").toLowerCase())
  5120. {
  5121. cur = elesLang[i].parentElement;
  5122. break;
  5123. }
  5124. }
  5125. if (cur)
  5126. {
  5127. cur.classList.add("stsh_dst_curLang");
  5128. }
  5129. }
  5130. } // End dstbattle.php
  5131. if (url.indexOf("/statistics.php") > -1)
  5132. {
  5133. setTimeoutCustom(function()
  5134. {
  5135. var qBranch = getQueryByName("branch_ID");
  5136. var qFile = getQueryByName("file_ID");
  5137. if (qBranch === "" && qFile === "")
  5138. {
  5139. var keyIdArr = new Array();
  5140. var valDataArr = new Array();
  5141. var keyBrArr = new Array();
  5142. var valBrArr = new Array();
  5143. var keyTrArr = new Array();
  5144. var valTrArr = new Array();
  5145. var keyApArr = new Array();
  5146. var valApArr = new Array();
  5147. var eleHead = document.querySelector("#overall");
  5148. if (eleHead)
  5149. {
  5150. function getProgress(content)
  5151. {
  5152. var rgxNum = /[0-9]+/g;
  5153. var data = "";
  5154. if (content.indexOf("<15") > -1)
  5155. {
  5156. data = "014"
  5157. }
  5158. else if (content.indexOf("100") < 0)
  5159. {
  5160. data = "0" + (content.match(rgxNum) || ["00"])[0];
  5161. }
  5162. else
  5163. {
  5164. data = "100";
  5165. }
  5166. return data;
  5167. }
  5168. var dataId = -1;
  5169. var dataBr = "";
  5170. var dataTr = "";
  5171. var dataAp = "";
  5172. var eleProgress = document.createElement("div");
  5173. while (eleHead.firstChild)
  5174. {
  5175. var child = eleHead.firstChild;
  5176. if (child.nodeName !== "#text")
  5177. {
  5178. if (child.id === "" && child.classList.contains("progress"))
  5179. {
  5180. dataId++;
  5181. eleProgress = document.createElement("div");
  5182. eleProgress.classList.add("stsh_stat_progress");
  5183. dataBr = child.textContent.trim();
  5184. if (dataBr.indexOf("glossary") === 0)
  5185. {
  5186. dataBr = "0" + dataBr;
  5187. }
  5188. eleProgress.setAttribute("data-br", dataBr);
  5189. eleProgress.setAttribute("data-id", dataId);
  5190. keyIdArr.push(dataId);
  5191. valDataArr[dataId] = eleProgress;
  5192. }
  5193. else if (child.classList.contains("graphtranslatedstats"))
  5194. {
  5195. dataTr = getProgress(child.textContent);
  5196. eleProgress.setAttribute("data-tr", dataTr);
  5197. }
  5198. else if (child.classList.contains("graphapprovedstats"))
  5199. {
  5200. dataAp = getProgress(child.textContent);
  5201. eleProgress.setAttribute("data-ap", dataAp);
  5202. //var dataId = eleProgress.dataset.id;
  5203. //var dataTr = eleProgress.dataset.tr;
  5204. //var dataBr = eleProgress.dataset.br;
  5205. var dataTrApBr = dataTr + "_" + dataAp + "_" + dataBr;
  5206. var dataApTrBr = dataAp + "_" + dataTr + "_" + dataBr;
  5207. //eleProgress.setAttribute("data-trapbr", dataTrApBr);
  5208. //eleProgress.setAttribute("data-aptrbr", dataApTrBr);
  5209. keyBrArr.push(dataBr);
  5210. valBrArr[dataBr] = dataId;
  5211. keyTrArr.push(dataTrApBr);
  5212. valTrArr[dataTrApBr] = dataId;
  5213. keyApArr.push(dataApTrBr);
  5214. valApArr[dataApTrBr] = dataId;
  5215. }
  5216. }
  5217. eleProgress.appendChild(child);
  5218. }
  5219. var i = keyIdArr.length - 1;
  5220. if (i > -1)
  5221. {
  5222. eleHead.appendChild(valDataArr[keyIdArr[i]]);
  5223. }
  5224. for (i--; i > -1; i--)
  5225. {
  5226. insertBeforeElement(valDataArr[keyIdArr[i]], eleHead.firstElementChild);
  5227. }
  5228. keyBrArr.sort();
  5229. keyTrArr.sort().reverse();
  5230. keyApArr.sort().reverse();
  5231. }
  5232. var eleDiv = document.createElement("div");
  5233. document.body.appendChild(eleDiv);
  5234. eleDiv.innerHTML =
  5235. ' \
  5236. <div class="stsh_showing_group"> \
  5237. <span class="stsh_showing_header">Hide</span>\
  5238. <br/> &nbsp; <input id="stsh_stat_hideGame" value="Game" class="stsh_btn_short" type="button" /> \
  5239. <input id="stsh_stat_hideSteam" value="Steam" class="stsh_btn_short" type="button" /> \
  5240. <br/> &nbsp; <input id="stsh_stat_hideApproved" value="Approved" class="stsh_btn_long" type="button" /> \
  5241. <br/> &nbsp; <input id="stsh_stat_hideCompleted" value="Completed" class="stsh_btn_long" type="button" /> \
  5242. \
  5243. <br/> &nbsp; <span class="stsh_showing_header">Sort by</span>\
  5244. <br/> &nbsp; <input id="stsh_stat_sortBr" value="Branch" class="stsh_btn_long" type="button" /> \
  5245. <br/> &nbsp; <input id="stsh_stat_sortTr" value="Translated" class="stsh_btn_long" type="button" /> \
  5246. <br/> &nbsp; <input id="stsh_stat_sortAp" value="Approved" class="stsh_btn_long" type="button" /> \
  5247. <br/> \
  5248. <br/> &nbsp; <input id="stsh_stat_showAll" value="Show All" class="stsh_btn_long" type="button" /> \
  5249. </div> \
  5250. ';
  5251.  
  5252. var eleHideGame = document.querySelector("#stsh_stat_hideGame");
  5253. eleHideGame.addEventListener("click", function()
  5254. {
  5255. var elesProgress = document.querySelectorAll(".stsh_stat_progress:not(.stsh_hidden)");
  5256. for (var i = 0; i < elesProgress.length; i++)
  5257. {
  5258. if (elesProgress[i].dataset.br.indexOf("games/") === 0)
  5259. {
  5260. elesProgress[i].classList.add("stsh_hidden");
  5261. }
  5262. }
  5263. });
  5264. var eleHideSteam = document.querySelector("#stsh_stat_hideSteam");
  5265. eleHideSteam.addEventListener("click", function()
  5266. {
  5267. var elesProgress = document.querySelectorAll(".stsh_stat_progress:not(.stsh_hidden)");
  5268. for (var i = 0; i < elesProgress.length; i++)
  5269. {
  5270. if (elesProgress[i].dataset.br.indexOf("steam") === 0)
  5271. {
  5272. elesProgress[i].classList.add("stsh_hidden");
  5273. }
  5274. }
  5275. });
  5276. var eleHideApproved = document.querySelector("#stsh_stat_hideApproved");
  5277. eleHideApproved.addEventListener("click", function()
  5278. {
  5279. var elesProgress = document.querySelectorAll(".stsh_stat_progress:not(.stsh_hidden)");
  5280. for (var i = 0; i < elesProgress.length; i++)
  5281. {
  5282. if (elesProgress[i].dataset.tr === elesProgress[i].dataset.ap)
  5283. {
  5284. elesProgress[i].classList.add("stsh_hidden");
  5285. }
  5286. }
  5287. });
  5288. var eleHideCompleted = document.querySelector("#stsh_stat_hideCompleted");
  5289. eleHideCompleted.addEventListener("click", function()
  5290. {
  5291. var elesProgress = document.querySelectorAll(".stsh_stat_progress:not(.stsh_hidden)");
  5292. for (var i = 0; i < elesProgress.length; i++)
  5293. {
  5294. if (elesProgress[i].dataset.tr === "100" && elesProgress[i].dataset.ap === "100")
  5295. {
  5296. elesProgress[i].classList.add("stsh_hidden");
  5297. }
  5298. }
  5299. });
  5300. var eleShowAll = document.querySelector("#stsh_stat_showAll");
  5301. eleShowAll.addEventListener("click", function()
  5302. {
  5303. var eleHead = document.querySelector("#overall");
  5304. while (eleHead.firstChild)
  5305. {
  5306. var child = eleHead.firstChild;
  5307. if (child.classList && child.classList.contains("stsh_hidden"))
  5308. {
  5309. child.classList.remove("stsh_hidden");
  5310. }
  5311. eleHead.removeChild(eleHead.firstChild);
  5312. }
  5313. var i = keyIdArr.length - 1;
  5314. if (i > -1)
  5315. {
  5316. eleHead.appendChild(valDataArr[keyIdArr[i]]);
  5317. }
  5318. for (i--; i > -1; i--)
  5319. {
  5320. insertBeforeElement(valDataArr[keyIdArr[i]], eleHead.firstElementChild);
  5321. }
  5322. });
  5323. var eleSortBr = document.querySelector("#stsh_stat_sortBr");
  5324. eleSortBr.addEventListener("click", function()
  5325. {
  5326. var eleHead = document.querySelector("#overall");
  5327. if (eleHead)
  5328. {
  5329. while (eleHead.firstChild)
  5330. {
  5331. eleHead.removeChild(eleHead.firstChild);
  5332. }
  5333. var i = keyBrArr.length - 1;
  5334. if (i > -1)
  5335. {
  5336. eleHead.appendChild(valDataArr[valBrArr[keyBrArr[i]]]);
  5337. }
  5338. for (i--; i > -1; i--)
  5339. {
  5340. insertBeforeElement(valDataArr[valBrArr[keyBrArr[i]]], eleHead.firstElementChild);
  5341. }
  5342. }
  5343. });
  5344. var eleSortTr = document.querySelector("#stsh_stat_sortTr");
  5345. eleSortTr.addEventListener("click", function()
  5346. {
  5347. var eleHead = document.querySelector("#overall");
  5348. if (eleHead)
  5349. {
  5350. while (eleHead.firstChild)
  5351. {
  5352. eleHead.removeChild(eleHead.firstChild);
  5353. }
  5354. var i = keyTrArr.length - 1;
  5355. if (i > -1)
  5356. {
  5357. eleHead.appendChild(valDataArr[valTrArr[keyTrArr[i]]]);
  5358. }
  5359. for (i--; i > -1; i--)
  5360. {
  5361. insertBeforeElement(valDataArr[valTrArr[keyTrArr[i]]], eleHead.firstElementChild);
  5362. }
  5363. }
  5364. });
  5365. var eleSortAp = document.querySelector("#stsh_stat_sortAp");
  5366. eleSortAp.addEventListener("click", function()
  5367. {
  5368. var eleHead = document.querySelector("#overall");
  5369. if (eleHead)
  5370. {
  5371. while (eleHead.firstChild)
  5372. {
  5373. eleHead.removeChild(eleHead.firstChild);
  5374. }
  5375. var i = keyApArr.length - 1;
  5376. if (i > -1)
  5377. {
  5378. eleHead.appendChild(valDataArr[valApArr[keyApArr[i]]]);
  5379. }
  5380. for (i--; i > -1; i--)
  5381. {
  5382. insertBeforeElement(valDataArr[valApArr[keyApArr[i]]], eleHead.firstElementChild);
  5383. }
  5384. }
  5385. });
  5386. }
  5387. }, 100);
  5388. } // End statistics.php
  5389. if (url.indexOf("index.php") > -1
  5390. || url === "http://translation.steampowered.com/"
  5391. || url === "https://translation.steampowered.com/")
  5392. {
  5393. var eleDes = document.querySelector("#verify-form > form");
  5394. if (eleDes)
  5395. {
  5396. var eleSpan = document.createElement("span");
  5397. eleSpan.classList.add("stsh_autoLoginOption");
  5398.  
  5399. var eleInput = document.createElement("input");
  5400. eleInput.id = "stsh_autoLogin";
  5401. eleInput.setAttribute("type", "checkbox");
  5402. eleInput.setAttribute("value", "auto");
  5403. function autoLogin()
  5404. {
  5405. var eleImage = document.querySelector("#verify-form > form > input[class='image']");
  5406. if (eleImage)
  5407. {
  5408. setTimeoutCustom(function()
  5409. {
  5410. var eleInput = document.querySelector("#stsh_autoLogin");
  5411. if (eleInput && eleInput.checked)
  5412. {
  5413. eleImage.click();
  5414. }
  5415. }, 3000);
  5416. }
  5417. }
  5418. if (GM_getValue("autoLogin", 0) === "true")
  5419. {
  5420. eleInput.checked = true;
  5421. autoLogin();
  5422. }
  5423.  
  5424. eleInput.addEventListener("click", function (e)
  5425. {
  5426. var ele = e.target;
  5427. if (ele.checked)
  5428. {
  5429. GM_setValue("autoLogin", "true");
  5430. autoLogin();
  5431. }
  5432. else
  5433. {
  5434. GM_setValue("autoLogin", "false");
  5435. }
  5436. });
  5437.  
  5438. var eleLabel = document.createElement("label");
  5439. eleLabel.setAttribute("for", "stsh_autoLogin");
  5440. eleLabel.textContent = " Auto Login";
  5441.  
  5442. eleSpan.appendChild(eleInput);
  5443. eleSpan.appendChild(eleLabel);
  5444. eleDes.appendChild(eleSpan);
  5445. }
  5446. } // End index.php
  5447. if (url.indexOf("try_auth.php") > -1)
  5448. {
  5449. setTimeoutCustom(function()
  5450. {
  5451. document.forms[0].submit();
  5452. }, 3000);
  5453. } // End try_auth.php
  5454. window.addEventListener("beforeunload", function (e)
  5455. {
  5456. clearTimeoutAll();
  5457. clearIntervalAll();
  5458. });
  5459. } // End Main
  5460.  
  5461. function client()
  5462. {
  5463. var clientScript =
  5464. ' \
  5465. var timeoutList = new Array(); \
  5466. var intervalList = new Array(); \
  5467. \
  5468. function setTimeoutCustom(func, tm, params) \
  5469. { \
  5470. var id = setTimeout(func, tm, params); \
  5471. timeoutList.push(id); \
  5472. return id; \
  5473. } \
  5474. \
  5475. function clearTimeoutAll() \
  5476. { \
  5477. for (var i = 0; i < timeoutList.length; i++) \
  5478. { \
  5479. clearTimeout(timeoutList[i]); \
  5480. } \
  5481. } \
  5482. \
  5483. function setIntervalCustom(func, tm, params) \
  5484. { \
  5485. var id = setInterval(func, tm, params); \
  5486. intervalList.push(id); \
  5487. return id; \
  5488. } \
  5489. \
  5490. function clearIntervalAll() \
  5491. { \
  5492. for (var i = 0; i < intervalList.length; i++) \
  5493. { \
  5494. clearInterval(intervalList[i]); \
  5495. } \
  5496. } \
  5497. \
  5498. function scrollToId(id, offset) \
  5499. { \
  5500. scrollToElement("#" + id, offset); \
  5501. } \
  5502. \
  5503. function scrollToElement(selector, offset) \
  5504. { \
  5505. if (typeof offset === "undefined") \
  5506. { \
  5507. offset = -20; \
  5508. } \
  5509. \
  5510. var ele = document.querySelector(selector); \
  5511. if (ele) \
  5512. { \
  5513. ele.scrollIntoView(true); \
  5514. window.scrollBy(0, offset); \
  5515. } \
  5516. } \
  5517. \
  5518. function setVisibleSuggestion(visible) \
  5519. { \
  5520. var display = visible !== true ? "none" : ""; \
  5521. var eles = document.querySelectorAll(".copy"); \
  5522. for (var i = 0; i < eles.length; i++) \
  5523. { \
  5524. if (eles[i].id && eles[i].id.indexOf("showwalletkeys") < 0 \
  5525. && eles[i].id !== "abuse_report" \
  5526. && eles[i].id !== "moderator_announcement") \
  5527. { \
  5528. if (eles[i].style.display !== display) \
  5529. { \
  5530. eles[i].style.display = display; \
  5531. } \
  5532. } \
  5533. } \
  5534. } \
  5535. \
  5536. function showSuggestion() \
  5537. { \
  5538. setVisibleSuggestion(true); \
  5539. } \
  5540. \
  5541. function hideSuggestion() \
  5542. { \
  5543. setVisibleSuggestion(false); \
  5544. } \
  5545. \
  5546. function pressHideSuggestion() \
  5547. { \
  5548. document.addEventListener("keydown", function(e) { \
  5549. if (e.keyCode === 27) { \
  5550. if (parent) \
  5551. { \
  5552. parent.hideSuggestionsBox(); \
  5553. } \
  5554. else \
  5555. { \
  5556. hideSuggestionsBox(); \
  5557. } \
  5558. } \
  5559. return false; \
  5560. }); \
  5561. } \
  5562. pressHideSuggestion(); \
  5563. \
  5564. function clickToSelect(ele) \
  5565. { \
  5566. var range = document.createRange(); \
  5567. range.setStartBefore(ele.firstChild); \
  5568. range.setEndAfter(ele.lastChild); \
  5569. var sel = window.getSelection(); \
  5570. sel.removeAllRanges(); \
  5571. sel.addRange(range); \
  5572. } \
  5573. \
  5574. \
  5575. function syncUrlArray() \
  5576. { \
  5577. var strStart = "showSuggestionsBox( \'"; \
  5578. var strEnd = "\' ); return false;"; \
  5579. var strCur = "&list_id="; \
  5580. var strAll = "&endnext="; \
  5581. var regPos = /&list_id=\\d+&endnext=\\d+/g; \
  5582. var isEdit = false; \
  5583. var eleDivs = []; \
  5584. var urls = []; \
  5585. \
  5586. var pattUrlTimestamp2 = /\\&t=[0-9]{6,}/g; \
  5587. var pattUrlTimestamp4 = /\\&[0-9]{6,}\\&/g; \
  5588. \
  5589. var trKeys = document.querySelectorAll("#keylist > table:nth-child(1) > tbody:nth-child(1) > tr"); \
  5590. for (var i = 0; i < trKeys.length; i++) \
  5591. { \
  5592. if (!trKeys[i].classList.contains("stsh_hidden")) \
  5593. { \
  5594. var eleDiv = trKeys[i].childNodes[0].childNodes[0]; \
  5595. if (typeof eleDiv.getAttribute !== "undefined" \
  5596. && eleDiv.getAttribute("onclick")) \
  5597. { \
  5598. eleDivs.push(eleDiv); \
  5599. } \
  5600. } \
  5601. } \
  5602. \
  5603. for (var i = 0, l = eleDivs.length; i < l; i++) \
  5604. { \
  5605. var evOld = eleDivs[i].getAttribute("onclick"); \
  5606. if (evOld) \
  5607. { \
  5608. var url = evOld.replace(strStart,"").replace(strEnd,"").replace(regPos,""); \
  5609. url = url + strCur + i + strAll + l; \
  5610. \
  5611. if (pattUrlTimestamp2.test(url)) \
  5612. { \
  5613. url = url.replace(pattUrlTimestamp2,""); \
  5614. } \
  5615. if (pattUrlTimestamp4.test(url)) \
  5616. { \
  5617. url = url.replace(pattUrlTimestamp4,"&"); \
  5618. } \
  5619. \
  5620. urls.push(url); \
  5621. \
  5622. var evNew = strStart + url + strEnd; \
  5623. if (evOld !== evNew) \
  5624. { \
  5625. eleDivs[i].setAttribute("onclick", evNew); \
  5626. isEdit = true; \
  5627. } \
  5628. } \
  5629. } \
  5630. \
  5631. if (isEdit || typeof URLarray === "undefined" || URLarray.length !== urls.length) \
  5632. { \
  5633. URLarray = urls; \
  5634. } \
  5635. } \
  5636. \
  5637. function setFrameColor(color) \
  5638. { \
  5639. var frame = document.querySelector("div#suggestions_box iframe"); \
  5640. if (frame) \
  5641. { \
  5642. if (frame.style.backgroundColor !== color) \
  5643. { \
  5644. frame.style.setProperty("background-color", color, "important"); \
  5645. } \
  5646. } \
  5647. } \
  5648. \
  5649. function padZero(num, size) \
  5650. { \
  5651. return (1e15+num+"").slice(-size); \
  5652. } \
  5653. \
  5654. function doInstant() \
  5655. { \
  5656. var url = document.documentURI; \
  5657. \
  5658. /* Fix STS JS error */ \
  5659. setTimeoutCustom(function() \
  5660. { \
  5661. if (typeof hide_list === "undefined") \
  5662. { \
  5663. hide_list = function() { /*console.log("sts: hide_list");*/ }; \
  5664. } \
  5665. }, 1000); \
  5666. \
  5667. if (url.indexOf("user_activity.php") > -1) \
  5668. { \
  5669. if (typeof $ !== "undefined") \
  5670. { \
  5671. $(".dial").css("display", "none"); \
  5672. } \
  5673. setTimeoutCustom(function() \
  5674. { \
  5675. if (typeof $ !== "undefined") \
  5676. { \
  5677. /* Restore drawing progress */ \
  5678. $(".dial").css("display", ""); \
  5679. $(".dial").knob( \
  5680. { \
  5681. "draw": function() \
  5682. { \
  5683. $(this.i).val(this.cv + "%"); \
  5684. } \
  5685. }); \
  5686. } \
  5687. }, 500); \
  5688. \
  5689. showSuggestion(); \
  5690. } \
  5691. else if (url.indexOf("translate.php") > -1) \
  5692. { \
  5693. getsuggestionURL = function(urlno) \
  5694. { \
  5695. /* Overwrite STS to remove timestamp */ \
  5696. return URLarray[urlno]; \
  5697. }; \
  5698. \
  5699. var obTarget_sync = document.querySelector("#keylist_container"); \
  5700. if (obTarget_sync) \
  5701. { \
  5702. var tmOb_sync = -1; \
  5703. var obMu_sync = new MutationObserver(function(mutations) \
  5704. { \
  5705. mutations.forEach(function(mutation) \
  5706. { \
  5707. if (mutation.type !== "attributes" \
  5708. || mutation.target.tagName === "TR") \
  5709. { \
  5710. clearTimeout(tmOb_sync); \
  5711. tmOb_sync = setTimeoutCustom(function() \
  5712. { \
  5713. syncUrlArray(); \
  5714. /*console.log("syncUrlArray: " + tmOb_sync);*/ \
  5715. }, 50); \
  5716. } \
  5717. }); \
  5718. }); \
  5719. \
  5720. var obConfig_sync = { childList: true, subtree: true, attributes: true, attributeFilter: ["class"] }; \
  5721. obMu_sync.observe(obTarget_sync, obConfig_sync); \
  5722. } \
  5723. \
  5724. /* Fix STS JS error */ \
  5725. setTimeoutCustom(function() \
  5726. { \
  5727. if (typeof getendnext === "undefined") \
  5728. { \
  5729. getendnext = function() { console.log("getendnext"); return ""; }; \
  5730. } \
  5731. }, 1000); \
  5732. } \
  5733. else if (url.indexOf("suggestions.php") > -1) \
  5734. { \
  5735. if (parent !== window) \
  5736. { \
  5737. var main = document.querySelector("#suggestionmain"); \
  5738. if (main) \
  5739. { \
  5740. var styleCp = window.getComputedStyle(main); \
  5741. if (styleCp) \
  5742. { \
  5743. var color = styleCp.backgroundColor; \
  5744. parent.setFrameColor(color); \
  5745. } \
  5746. } \
  5747. } \
  5748. } \
  5749. \
  5750. window.addEventListener("beforeunload", function (e) \
  5751. { \
  5752. clearTimeoutAll(); \
  5753. clearIntervalAll(); \
  5754. }); \
  5755. \
  5756. } \
  5757. doInstant(); \
  5758. \
  5759. ';
  5760.  
  5761. var eleClientScript = document.createElement("script");
  5762. eleClientScript.innerHTML = clientScript;
  5763. document.head.appendChild(eleClientScript);
  5764. } // End client
  5765.  
  5766. attachOnReady(initStyle);
  5767. attachOnReady(client);
  5768. attachOnReady(main);
  5769.  
  5770.  
  5771. })();
  5772.  
  5773. // End