STS Helper

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

当前为 2018-02-23 提交的版本,查看 最新版本

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