Enhancement Userscript for LIHKG

An Enhancement Userscript for LIHKG

2021-06-11 기준 버전입니다. 최신 버전을 확인하세요.

  1. // ==UserScript==
  2. // @name Enhancement Userscript for LIHKG
  3. // @version 0.5.6
  4. // @description An Enhancement Userscript for LIHKG
  5. // @include /https?\:\/\/lihkg\.com/
  6. // @icon https://www.google.com/s2/favicons?domain=lihkg.com
  7. // @grant GM_addStyle
  8. // @namespace https://greatest.deepsurf.us/users/371179
  9. // ==/UserScript==
  10. (function() {
  11. 'use strict';
  12.  
  13. GM_addStyle([
  14. // drag & drop area for image upload
  15. `.EGBBkGyEbfIEpHMLTW84H:not([dragmode]),.EGBBkGyEbfIEpHMLTW84H[dragmode="text"]{position:fixed;left:-9999px;top:-9999px;width:2px;height:2px;}`,
  16. // copy reply content from reply preview
  17. `div[contenteditable] p>img~br:last-child,div[contenteditable] p>a~br:last-child,div[contenteditable] p>div~br:last-child{content:'';}`,
  18. // css fix for thread posts positioning
  19. `
  20. body ._21IQKhlBjN2jlHS_TVgI3l:after {left:0.4rem}
  21. body ._21IQKhlBjN2jlHS_TVgI3l .vv9keWAXpwoonDah6rSIU ._3D2lzCKDMcdgEkexZrTSUh{margin-left: -6px;width: 16px;}
  22. `,
  23. // css fix for like and dislike due to js hack of like count and dislike count (reply posts)
  24. `
  25. body label[for*="-dislike-like"]{display:inline-block !important;}
  26. body label[for*="-like-like"]{display:inline-block !important;}
  27. body ._3ExaynSI6tUp5h1U50MHtI ._3imUf8qB9LmLpk_t5PjDm4>div:first-child+div:last-child{margin-left:-6px;}
  28. `,
  29. // css fix for like and dislike due to js hack of like count and dislike count (main thread)
  30. // empty full space char for maintaining padding when the count is not yet shown
  31. `
  32. span[data-tip="正評"]:not([data-score])::after{content: " ";
  33. font-size: .6rem;
  34. font-weight: 400;
  35. margin-top: .3rem;}
  36. span[data-tip="負評"]:not([data-score])::after{content: " ";
  37. font-size: .6rem;
  38. font-weight: 400;
  39. margin-top: .3rem;}
  40. span[data-tip="正評"],span[data-tip="負評"]{padding-top:0px !important;}
  41. `,
  42. // kiwi browser css fix
  43.  
  44. `
  45. @supports not (padding-bottom: env(safe-area-inset-bottom)){
  46. ._3dwGLtjqTgI2gc9wpc7FuT {
  47. padding: 1rem .6rem calc(1rem + 0px) calc(.7rem + 0px);
  48. }
  49. }`
  50.  
  51. ].map(x => x.trim()).join('\n'))
  52.  
  53.  
  54. var isNumCheck = function(n) {
  55. return n > 0 || n < 0 || n === 0
  56. }
  57. var postDetails = {}
  58. var threadDetails = {}
  59. var pendingRefreshThread = false;
  60.  
  61. var testBlockElm = function(elm) {
  62. if (elm && elm.nodeType == 1) {
  63. switch (elm.tagName) {
  64. case 'DIV':
  65. case 'P':
  66. case 'BLOCKQUOTE':
  67. return true;
  68.  
  69. default:
  70. return false;
  71.  
  72. }
  73.  
  74. }
  75. }
  76.  
  77. var getElementText = function(el) {
  78. var text = '';
  79. // Text node (3) or CDATA node (4) - return its text
  80. if ((el.nodeType === 3) || (el.nodeType === 4)) {
  81. text = el.nodeValue;
  82. // If node is an element (1) and an img, input[type=image], or area element, return its alt text
  83. } else if ((el.nodeType === 1) && (
  84. (el.tagName.toLowerCase() == 'img') ||
  85. (el.tagName.toLowerCase() == 'area') ||
  86. ((el.tagName.toLowerCase() == 'input') && el.getAttribute('type') && (el.getAttribute('type').toLowerCase() == 'image'))
  87. )) {
  88. text = el.getAttribute('alt') || '';
  89. if (el.tagName.toLowerCase() == 'img' && text == '' && el.getAttribute('data-original')) {
  90. text = '[img]' + el.getAttribute('data-original') + '[/img]';
  91. } else if (el.tagName.toLowerCase() == 'img' && text == '' && el.getAttribute('src')) {
  92. text = '[img]' + el.getAttribute('src') + '[/img]';
  93. }
  94. // Traverse children unless this is a script or style element
  95. } else if ((el.nodeType === 1) && (
  96. (el.tagName.toLowerCase() == 'br')
  97. )) {
  98. text = '\n';
  99. // Traverse children unless this is a script or style element
  100. } else if ((el.nodeType === 1) && !el.tagName.match(/^(script|style)$/i)) {
  101. var children = el.childNodes;
  102.  
  103. if (el && testBlockElm(el) && el.previousSibling ? testBlockElm(el.previousSibling) : false) {
  104. text += '\n'
  105. }
  106. if (el.tagName.toLowerCase() == 'blockquote') {
  107. text += '[quote]'
  108. }
  109. for (var i = 0, l = children.length; i < l; i++) {
  110. text += getElementText(children[i]);
  111. }
  112. if (el.tagName.toLowerCase() == 'blockquote') {
  113. text += '[/quote]'
  114. }
  115.  
  116. }
  117. return text;
  118. };
  119.  
  120.  
  121. document.cssAll = function() {
  122.  
  123. var s = document.querySelectorAll.apply(this, arguments)
  124.  
  125. s = Array.prototype.slice.call(s, 0)
  126. return s
  127. }
  128.  
  129. function urlConvert(url) {
  130. var src = url.replace(/\w+\:\/\//, '')
  131. var replacements = [...src.matchAll(/[\w\.]+/g)].filter((t) => /\./.test(t))
  132. if (replacements.length > 1) {
  133. replacements.length--;
  134.  
  135. }
  136. replacements.forEach((s) => {
  137. src = src.replace(s, '')
  138. })
  139.  
  140. src = src.replace(/\/+/g, '/')
  141.  
  142. return src;
  143.  
  144. }
  145.  
  146. var emoji = {};
  147. setTimeout(function() {
  148. console.log(emoji)
  149. }, 1500)
  150.  
  151. setInterval(() => {
  152.  
  153. document.cssAll('img[src*="lihkg.com"][alt]:not([title])').forEach(function(imgElm) {
  154. var src = imgElm.getAttribute('src');
  155. var erc = urlConvert(src)
  156. var imgAlt = imgElm.getAttribute('alt') || "";
  157. if (/^[\x20-\x7E]+$/.test(imgAlt) && /\W/.test(imgAlt)) {
  158. emoji[erc] = imgAlt.trim()
  159. }
  160.  
  161. imgElm.setAttribute('title', imgAlt)
  162.  
  163. })
  164.  
  165.  
  166. document.cssAll('a[href*="profile/"]:not([href*="//"]):not([title])').forEach(function(aElm) {
  167. aElm.setAttribute('title', aElm.getAttribute('href'))
  168. })
  169.  
  170. document.cssAll('[data-ic~="hkgmoji"]:not([title])>img[src*="lihkg.com"]:not([alt])').forEach(function(imgElm) {
  171. var src = imgElm.getAttribute('src');
  172. var erc = urlConvert(src)
  173. var text = emoji[erc] ? emoji[erc] : "[img]" + erc + "[/img]"
  174. imgElm.parentNode.setAttribute('title', text)
  175. imgElm.setAttribute('alt', text)
  176.  
  177.  
  178. })
  179.  
  180. document.cssAll('a[href*="local.lihkg.com"]>img:not([anchored])').forEach(function(img) {
  181. img.setAttribute('anchored', 'true')
  182.  
  183.  
  184. var originalSrc = img.getAttribute('src') || img.getAttribute('data-original') || ""
  185. var newSrc = originalSrc.replace('local.lihkg.com', 'cdn.lihkg.com');
  186.  
  187. if (newSrc && originalSrc != newSrc) {
  188.  
  189. // console.log(originalSrc, newSrc)
  190.  
  191. var fx = function() {
  192. if (img.complete == false) return setTimeout(fx, 33);
  193.  
  194. if (img.currentSrc == "") {
  195.  
  196. var b = img.cloneNode(false);
  197. b.removeAttribute('data-original');
  198. b.removeAttribute('data-src');
  199.  
  200. if (b.getAttribute('alt') == "") b.removeAttribute('alt')
  201. if (b.getAttribute('title') == "") b.removeAttribute('title')
  202.  
  203. b.setAttribute('src', newSrc);
  204. img.parentNode.replaceChild(b, img)
  205.  
  206. if (b.parentNode.getAttribute('href')) {
  207. b.parentNode.setAttribute('href', b.parentNode.getAttribute('href').replace(originalSrc, newSrc));
  208. if (b.nextElementSibling && b.nextElementSibling.hasAttribute('data-error')) b.nextElementSibling.parentNode.removeChild(b.nextElementSibling);
  209. if (b.nextElementSibling && b.nextElementSibling.outerHTML.toLocaleLowerCase() == '<ins></ins>') b.nextElementSibling.parentNode.removeChild(b.nextElementSibling);
  210.  
  211.  
  212.  
  213. }
  214.  
  215. b.removeAttribute('anchored')
  216.  
  217.  
  218. }
  219.  
  220. }
  221. fx();
  222.  
  223.  
  224. }
  225.  
  226. })
  227.  
  228.  
  229. document.cssAll('div[contenteditable] div[data-ic][contenteditable="false"]').forEach((elm) => {
  230.  
  231. elm.removeAttribute('contenteditable')
  232. })
  233.  
  234.  
  235. document.cssAll('img[src]:not([alt]),img[src][alt=""]').forEach((el) => {
  236.  
  237. if (el.getAttribute('alt') || el.getAttribute('title')) return;
  238.  
  239. var text = '';
  240. if (el.tagName.toLowerCase() == 'img' && el.getAttribute('data-original')) {
  241. text = '[img]' + el.getAttribute('data-original') + '[/img]';
  242. } else if (el.tagName.toLowerCase() == 'img' && el.getAttribute('src')) {
  243. text = '[img]' + el.getAttribute('src') + '[/img]';
  244. }
  245. if (text) el.setAttribute('alt', text)
  246. if (text) el.setAttribute('title', text)
  247.  
  248. })
  249.  
  250.  
  251.  
  252.  
  253. document.cssAll('[data-post-id]:not([hacked])').forEach((el) => {
  254.  
  255. el.setAttribute('hacked', 'true');
  256. var post_id = el.getAttribute('data-post-id');
  257. if (!post_id) return;
  258.  
  259. //console.log(post_id, postDetails)
  260. var post_detail = postDetails[post_id]
  261. if (post_detail) {
  262. // console.log(55,post_detail)
  263.  
  264. }
  265.  
  266. })
  267.  
  268.  
  269.  
  270. }, 33)
  271.  
  272.  
  273.  
  274. function refreshingThreadEvent(thread_id) {
  275.  
  276.  
  277. console.log("refreshingThreadEvent", threadDetails[thread_id])
  278. if (thread_id && threadDetails[thread_id]) {
  279.  
  280.  
  281. document.cssAll('span[data-tip="正評"]').forEach((elm) => {
  282.  
  283. elm.setAttribute('data-score', threadDetails[thread_id]["like_count"]);
  284. elm.style.paddingTop = '0px';
  285. })
  286.  
  287.  
  288. document.cssAll('span[data-tip="負評"]').forEach((elm) => {
  289.  
  290. elm.setAttribute('data-score', threadDetails[thread_id]["dislike_count"]);
  291. elm.style.paddingTop = '0px';
  292. })
  293.  
  294.  
  295.  
  296. }
  297.  
  298.  
  299. }
  300.  
  301.  
  302. var cid_refreshingThread = 0;
  303.  
  304. function refreshingThreadRunning() {
  305.  
  306. if (!cid_refreshingThread) return;
  307.  
  308.  
  309. var titlespan = document.cssAll('a[href^="/category/"]+span');
  310. if (titlespan.length == 1) {
  311. var titlespanElm = titlespan[0]
  312.  
  313. if (!titlespanElm.querySelector('noscript')) {
  314. titlespanElm.appendChild(document.createElement('noscript'))
  315.  
  316.  
  317. if (pendingRefreshThread) {
  318.  
  319. var thread_id = pendingRefreshThread === true ? (/thread\/(\d+)\//.exec(location + "") || [null, null])[1] : pendingRefreshThread
  320.  
  321. pendingRefreshThread = false;
  322. clearInterval(cid_refreshingThread);
  323. cid_refreshingThread = 0;
  324. refreshingThreadEvent(thread_id)
  325.  
  326.  
  327. }
  328.  
  329.  
  330. }
  331. }
  332.  
  333. }
  334.  
  335.  
  336.  
  337.  
  338. var makePlain = false;
  339. document.addEventListener('drop', function(evt) {
  340. // console.log(evt, makePlain, evt.target)
  341.  
  342. var p = evt.target;
  343. var contenteditable = false;
  344. while (p) {
  345. if (p.hasAttribute('contenteditable') && p.getAttribute('contenteditable') != 'false') {
  346. contenteditable = true;
  347. break;
  348. }
  349. p = p.parentNode;
  350.  
  351. }
  352.  
  353. if (contenteditable) {
  354.  
  355. if (makePlain && evt.dataTransfer.getData('text/html')) {
  356.  
  357. var text = evt.dataTransfer.getData('text/html');
  358.  
  359.  
  360. setTimeout(function() {
  361. var sel = window.getSelection();
  362. if (sel.getRangeAt && sel.rangeCount) {
  363.  
  364.  
  365. var range = sel.getRangeAt(0);
  366.  
  367. var cloneContents = range.cloneContents();
  368.  
  369.  
  370. var hh = document.createElement('html')
  371. hh.innerHTML = text;
  372. console.log(hh.cloneNode(true))
  373. var hhPlain = getElementText(hh)
  374.  
  375. console.log(hhPlain)
  376. hh.innerText = hhPlain
  377.  
  378.  
  379. if (cloneContents.textContent !== hhPlain) {
  380.  
  381. range.deleteContents();
  382.  
  383. var trueHTML = '<p>' + hh.innerHTML.toLowerCase().replace(/<br\s*\/?>/g, "<br></p><p>") + "</p>"
  384.  
  385. console.log(trueHTML)
  386.  
  387. document.execCommand('insertHTML', false, trueHTML);
  388. }
  389.  
  390. }
  391.  
  392. }, 10);
  393. }
  394.  
  395. }
  396.  
  397.  
  398. }, true)
  399.  
  400.  
  401. document.addEventListener('dragstart', function(evt) {
  402. var editable = document.querySelector('div[contenteditable]')
  403. var dragFrom = evt.target
  404. if (editable && dragFrom) {
  405.  
  406. if (editable == dragFrom || editable.contains(dragFrom)) {
  407.  
  408. } else {
  409. makePlain = true;
  410.  
  411. }
  412.  
  413. }
  414. // console.log(evt)
  415. }, false);
  416.  
  417.  
  418. document.addEventListener('dragend', function(evt) {
  419. if (Event.prototype._preventDefault) {
  420. Event.prototype.preventDefault = Event.prototype._preventDefault
  421. Event.prototype._preventDefault = null
  422.  
  423. }
  424. setTimeout(function() {
  425. makePlain = false;
  426. }, 77);
  427. }, false);
  428.  
  429. document.addEventListener('drop', function(evt) {
  430.  
  431. setTimeout(function() {
  432. makePlain = false;
  433. }, 77);
  434. if (Event.prototype._preventDefault) {
  435. Event.prototype.preventDefault = Event.prototype._preventDefault
  436. Event.prototype._preventDefault = null
  437. }
  438.  
  439. var dropZone = document.querySelector('.EGBBkGyEbfIEpHMLTW84H');
  440. if (!dropZone) return;
  441. dropZone.removeAttribute('dragmode');
  442.  
  443.  
  444. }, true)
  445.  
  446.  
  447.  
  448. document.addEventListener('dragenter', function(evt) {
  449.  
  450. var dropZone = document.querySelector('.EGBBkGyEbfIEpHMLTW84H');
  451.  
  452.  
  453.  
  454. var isFileTransfer = false;
  455. if (evt.dataTransfer.types) {
  456. for (var i = 0; i < evt.dataTransfer.types.length; i++) {
  457. if (evt.dataTransfer.types[i] == "Files") {
  458. isFileTransfer = true;
  459. break;
  460. }
  461. }
  462. }
  463.  
  464. if (!isFileTransfer) {
  465.  
  466. if (dropZone)
  467. dropZone.setAttribute('dragmode', 'text');
  468. // evt.dataTransfer.effectAllowed='copy';
  469. if (!Event.prototype._preventDefault) {
  470. Event.prototype._preventDefault = Event.prototype.preventDefault;
  471. Event.prototype.preventDefault = function() {
  472. if (this.type == 'dragover') {
  473.  
  474. } else {
  475. return this._preventDefault();
  476. }
  477. //console.log(this)
  478. };
  479. }
  480.  
  481.  
  482.  
  483. } else {
  484. makePlain = false;
  485. if (dropZone)
  486. dropZone.setAttribute('dragmode', 'file');
  487.  
  488.  
  489. }
  490. // console.log('dragenter',!isFileTransfer)
  491.  
  492.  
  493.  
  494. }, false)
  495.  
  496.  
  497.  
  498. var injection = function() {
  499.  
  500.  
  501. function extractRawURL(thumbnailURL) {
  502.  
  503. var u = [...thumbnailURL.matchAll(/[\?\&]\w+\=([\x21-\x25\x27-\x3E\x40-\x7E]+)/g)].map(d => d[1])
  504. if (u.length) {
  505. var uMaxT = Math.max(...u.map(t => t.length))
  506. var u0 = u.filter(t => t.length == uMaxT)[0]
  507.  
  508. if (u0) {
  509.  
  510. var v0 = null
  511. try {
  512. v0 = decodeURIComponent(u0)
  513. } catch (e) {}
  514. //console.log(v0,u0)
  515. if (v0) {
  516. return v0
  517. }
  518.  
  519. }
  520. }
  521. return null
  522. }
  523.  
  524. if (!JSON._parse && JSON.parse) {
  525. JSON._parse = JSON.parse
  526. JSON.parse = function(text, r) {
  527.  
  528. if (text && typeof text == "string" && text.indexOf('display_vote') > 0) {
  529. text = text.replace(/([\'\"])display_vote[\'\"]\s*:\s*false/gi, '$1display_vote$1:true')
  530. }
  531. var res = JSON._parse.apply(this, arguments)
  532.  
  533. var contentFix = (resObj) => {
  534. for (var k in resObj) {
  535. if (typeof resObj[k] == 'object') contentFix(resObj[k]);
  536. else if (k == 'msg' && typeof resObj[k] == 'string') {
  537.  
  538. var msg = resObj[k];
  539. var replace = false;
  540. msg = msg.replace(/(\<img\s+src\=\")(https?\:\/\/i\.lih\.kg\/thumbnail\?[^\"]+)(\"[^\>]+\>)/g, function(s, a, b, c) {
  541.  
  542. var v0 = extractRawURL(b)
  543. if (v0) {
  544. replace = true;
  545.  
  546. console.log(v0, b)
  547.  
  548. var v1 = '<img src="' + v0 + '" data-thumbnail-src="' + b + '" />';
  549.  
  550. return v1
  551. }
  552.  
  553. return a + b + c
  554.  
  555. })
  556.  
  557. msg = msg.replace(
  558.  
  559. /<a\s+href=\"(https\:\/\/i\.lih\.kg\/thumbnail\?u=[^\?\s\x00-\x20\x7F-\xFF\"]+)\"[^<>]+>\1<\/a>/g,
  560. function(_, a) {
  561.  
  562. var b = extractRawURL(a)
  563. if (b) {
  564. replace = true
  565. var a01 = encodeURIComponent(a)
  566. var a02 = a01.replace(/\%26amp\%3B/gi, '%26')
  567. var b01 = encodeURIComponent(b)
  568. var c = _.replace(a, b).replace(a, b).replace(a02, b01).replace(a01, b01)
  569.  
  570. return c
  571. }
  572. return _
  573. })
  574.  
  575.  
  576. if (replace) {
  577. console.log(msg)
  578. resObj[k] = msg;
  579.  
  580. }
  581. }
  582. }
  583. }
  584.  
  585. contentFix(res)
  586.  
  587. return res;
  588. }
  589. }
  590.  
  591. var api_callback = "uleccyqjstui"
  592.  
  593. ;
  594. ((xmlhr, xmlhr_pt) => {
  595. if (!xmlhr_pt._open) {
  596. xmlhr_pt._open = xmlhr_pt.open;
  597.  
  598.  
  599. xmlhr_pt.open = function() {
  600. // console.log('xmlhr_open', arguments)
  601. if (/https?\:\/\/[\x20-2E\x30-5B\x5D-\x7E]*lihkg\.com\/[\x20-\x7E]*api[\x20-\x7E]+/.test(arguments[1])) {
  602. this._url = arguments[1];
  603.  
  604. console.log('_url', this._url)
  605. }
  606. this._open.apply(this, arguments)
  607. }
  608. }
  609.  
  610.  
  611.  
  612. if (!xmlhr_pt._send) {
  613. xmlhr_pt._send = xmlhr_pt.send;
  614.  
  615.  
  616. xmlhr_pt.send = function() {
  617. if (this._url) {
  618. this.addEventListener('load', function() {
  619. var resText = this.responseText;
  620. var jsonObj = null;
  621. if (resText && typeof resText == 'string') {
  622. try {
  623. jsonObj = JSON.parse(resText);
  624. } catch (e) {}
  625. }
  626.  
  627. if (jsonObj) {
  628. //like_count
  629.  
  630. var code_num = 0;
  631.  
  632. if (jsonObj.success == 1 && jsonObj.response && jsonObj.response.item_data && jsonObj.response.item_data.length >= 1 && jsonObj.response.item_data[0]["post_id"]) {
  633. code_num |= 16;
  634. }
  635. if (jsonObj.success == 1 && jsonObj.response && jsonObj.response.thread_id) {
  636. code_num |= 8;
  637. }
  638. // console.log('code', code_num);
  639. var event = new CustomEvent(api_callback, {
  640. detail: {
  641. code: code_num,
  642. responseJSON: jsonObj
  643. }
  644. });
  645. document.dispatchEvent(event);
  646.  
  647.  
  648.  
  649. //console.log(jsonObj)
  650. }
  651.  
  652. })
  653. }
  654. // console.log('xmlhr_send', arguments)
  655. this._send.apply(this, arguments)
  656. }
  657. }
  658.  
  659.  
  660. })(XMLHttpRequest, XMLHttpRequest.prototype)
  661.  
  662. }
  663.  
  664. var jsscript = document.createElement('script');
  665. jsscript.type = 'text/javascript';
  666. jsscript.innerHTML = '(' + injection + ')()';
  667. document.documentElement.appendChild(jsscript)
  668.  
  669. var api_callback = "uleccyqjstui"
  670. //data-post-id="5226a9cb7b395fbc182d183a6ee9b35c8adfd2fe"
  671. document.addEventListener(api_callback, function(e) {
  672. if (!e || !e.detail) return;
  673. console.log("API_CALLBACK", e.detail)
  674. var jsonObj;
  675. var code_num = e.detail.code
  676. switch (true) {
  677.  
  678. case (code_num & 8) == 8: //main thread
  679.  
  680. case (code_num & 16) == 16: //posts
  681.  
  682.  
  683. jsonObj = e.detail.responseJSON;
  684.  
  685.  
  686. if (jsonObj.success == 1 && jsonObj.response && jsonObj.response.item_data && jsonObj.response.item_data.length >= 1 && jsonObj.response.item_data[0]["post_id"]) {
  687. var reply_post_fx = (reply_item) => {
  688. if ('dislike_count' in reply_item && 'like_count' in reply_item && reply_item["post_id"]) {
  689.  
  690. var like_count = +reply_item['like_count']
  691. var dislike_count = +reply_item['dislike_count']
  692. var post_id = reply_item['post_id']
  693.  
  694. if (isNumCheck(like_count) && isNumCheck(dislike_count) && post_id) {
  695. postDetails[post_id] = {
  696. 'like_count': like_count,
  697. 'dislike_count': dislike_count
  698. }
  699. }
  700.  
  701. }
  702. };
  703. jsonObj.response.item_data.forEach(reply_post_fx)
  704. if (jsonObj.response.pinned_post && jsonObj.response.pinned_post["post_id"]) reply_post_fx(jsonObj.response.pinned_post)
  705.  
  706. }
  707.  
  708.  
  709.  
  710. if (jsonObj.success == 1 && jsonObj.response && jsonObj.response.thread_id) {
  711. var thread_fx = (thread_item) => {
  712. if ('like_count' in thread_item && 'dislike_count' in thread_item && thread_item["thread_id"]) {
  713.  
  714. var like_count = +thread_item['like_count']
  715. var dislike_count = +thread_item['dislike_count']
  716. var thread_id = thread_item['thread_id']
  717.  
  718. if (isNumCheck(like_count) && isNumCheck(dislike_count) && thread_id) {
  719. threadDetails[thread_id] = {
  720. 'like_count': like_count,
  721. 'dislike_count': dislike_count
  722. }
  723. pendingRefreshThread = thread_id;
  724. if (!cid_refreshingThread) cid_refreshingThread = setInterval(refreshingThreadRunning, 1);
  725. }
  726.  
  727. }
  728. };
  729. thread_fx(jsonObj.response)
  730. //console.log(99, threadDetails)
  731.  
  732. }
  733.  
  734. //console.log(jsonObj)
  735. break;
  736.  
  737.  
  738. default:
  739. }
  740.  
  741. });
  742.  
  743.  
  744. // Your code here...
  745. })();