Steam Badge Helper

Add various features to Steam focus on Trading Cards and Badges

当前为 2015-12-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Steam Badge Helper
  3. // @namespace iFantz7E.SteamBadgeHelper
  4. // @version 1.22
  5. // @description Add various features to Steam focus on Trading Cards and Badges
  6. // @match http://store.steampowered.com/*
  7. // @match http://steamcommunity.com/*
  8. // @match https://store.steampowered.com/*
  9. // @match http://forums.steampowered.com/*
  10. // @match https://steamcommunity.com/*
  11. // @match http://store.akamai.steampowered.com/*
  12. // @match http://store.steamgames.com/*
  13. // @run-at document-start
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // @grant GM_listValues
  17. // @grant GM_deleteValue
  18. // @grant GM_xmlhttpRequest
  19. // @grant GM_addStyle
  20. // @icon http://store.steampowered.com/favicon.ico
  21. // @copyright 2014, 7-elephant
  22. // ==/UserScript==
  23.  
  24. // http://userscripts.org/scripts/show/186163
  25. // https://greasyfork.org/en/scripts/5348-steam-badge-helper
  26.  
  27. (function ()
  28. {
  29. var timeStart = new Date();
  30.  
  31. // ===== Config =====
  32.  
  33. var enableDebug = false;
  34. var enableDebugConsole = true;
  35. var enableCleanLink = true;
  36. var enableGreenlightNoAutoplay = true;
  37. var enableMoveGreenlitHeader = true;
  38. var enableLinkBadgeToFriend = true;
  39. var enableLinkStoreToBadge = true;
  40. var enableLinkForumToBadge = true;
  41. var enableLinkBadgeToForum = true;
  42. var enableLinkMarketToBadge = true;
  43. var enableLinkBadgeToMarket = true;
  44. var enableLinkInventoryToBadge = true;
  45. var enableLinkProfile = true;
  46. var enableCompareBadge = true;
  47. var enableAlwaysClearCache = false;
  48. var enableCleanSteamMenu = true;
  49. var enableHideEnhancedBadgePrice = true;
  50. var enableAutoscrollSearch = true;
  51. var enableSwapTitle = true;
  52. var enableShowTitleNoti = false;
  53. var enableResizeTradeWindow = true;
  54. var enableMoveMenuEditProfile = true;
  55. var enableRefreshError = true;
  56. var enableSetAllCheckBox = true;
  57. var enableStoreFocus = true;
  58. var enableStoreHideSection = true;
  59. var enableAutoExploreQueue = true;
  60. var enableCache = true;
  61. var enableDebugCache = false;
  62. var timeCacheExpireSec = 300;
  63. var appCards = ["286120", "203990", "32200", "259720", "245550", "306410", "249610", "291130"
  64. , "218640", "268420", "46500", "102200", "301680", "273770", "264320", "339290", "340280"
  65. , "273830", "303850", "346200", "353980", "296070", "380770", "294190", "258200", "15700"
  66. , "92800", "267920", "257890"];
  67. var appCardMaps = {"202970": "202990", "234510": "35450"};
  68. var appDlcs = // Exclude
  69. [
  70. "230889", "256576", "256611", "258643", "222606", "222615", "222618", "277751"
  71. ];
  72. // ===== End Config =====
  73.  
  74. // ===== Cache =====
  75.  
  76. var tmpl_time = "badge_{APP}_time";
  77. var tmpl_price = "badge_{APP}_{SET}_{NUM}_price";
  78. var tmpl_url = "badge_{APP}_{SET}_{NUM}_url";
  79. var tmpl_owned = "badge_{APP}_{SET}_{NUM}_owned";
  80.  
  81. function clearCache()
  82. {
  83. var keep = ["counter"];
  84. var cache = GM_listValues()
  85. debug("clearCache: " + cache.length);
  86. for (var i = 0; i < cache.length; i++)
  87. {
  88. if (keep.indexOf(cache[i]) < 0)
  89. {
  90. GM_deleteValue(cache[i]);
  91. }
  92. }
  93. }
  94. if (enableAlwaysClearCache) clearCache();
  95.  
  96. function debugCache()
  97. {
  98. var cache = GM_listValues()
  99. if (enableDebugCache)
  100. {
  101. debug("debugCache: ");
  102. if (cache != null) for (var i = 0; i < cache.length; i++)
  103. {
  104. debug("-> " + cache[i] + ": " + GM_getValue(cache[i], 0));
  105. }
  106. }
  107. debug("debugCache: " + (cache == null ? 0 : cache.length));
  108. }
  109. setTimeout(debugCache, 0);
  110.  
  111. function generateCacheName(tmpl, app, isFoil, number)
  112. {
  113. var name = tmpl.replace("{APP}", app);
  114. if (isFoil != null)
  115. {
  116. var set = isFoil ? "F1" : "N1";
  117. name = name.replace("{SET}", set);
  118. }
  119. if (number != null)
  120. {
  121. name = name.replace("{NUM}", number);
  122. }
  123. return name;
  124. }
  125. function generateCacheNameTime(app)
  126. {
  127. return generateCacheName(tmpl_time, app);
  128. }
  129. function generateCacheNamePrice(app, isFoil, number)
  130. {
  131. return generateCacheName(tmpl_price, app, isFoil, number);
  132. }
  133. function generateCacheNameUrl(app, isFoil, number)
  134. {
  135. return generateCacheName(tmpl_url, app, isFoil, number);
  136. }
  137. function generateCacheNameOwned(app, isFoil, number)
  138. {
  139. return generateCacheName(tmpl_owned, app, isFoil, number);
  140. }
  141.  
  142. function getCacheTime(app)
  143. {
  144. var name = generateCacheNameTime(app);
  145. return GM_getValue(name, 0);
  146. }
  147. function getCacheTimeDiff(app)
  148. {
  149. return parseInt((new Date()) / 1000 - getCacheTime(app));
  150. }
  151. function setCacheTime(app)
  152. {
  153. var name = generateCacheNameTime(app);
  154. GM_setValue(name, parseInt((new Date()) / 1000));
  155. }
  156. function checkCacheExpire(app)
  157. {
  158. var cacheDiff = getCacheTimeDiff(app);
  159. var isCacheExpire = cacheDiff < 0 || cacheDiff > timeCacheExpireSec;
  160. debug("cacheTimeDiff: " + cacheDiff + "s");
  161. debug("isCacheExpire: " + isCacheExpire);
  162. return isCacheExpire;
  163. }
  164.  
  165. function getCachePrice(app, isFoil, number)
  166. {
  167. var name = generateCacheNamePrice(app, isFoil, number);
  168. return GM_getValue(name, 0);
  169. }
  170. function setCachePrice(app, isFoil, number, data)
  171. {
  172. var name = generateCacheNamePrice(app, isFoil, number);
  173. GM_setValue(name, data);
  174. }
  175.  
  176. function getCacheUrl(app, isFoil, number)
  177. {
  178. var name = generateCacheNameUrl(app, isFoil, number);
  179. return GM_getValue(name, 0);
  180. }
  181. function setCacheUrl(app, isFoil, number, data)
  182. {
  183. var name = generateCacheNameUrl(app, isFoil, number);
  184. GM_setValue(name, data);
  185. }
  186.  
  187. function getCacheOwned(app, isFoil, number)
  188. {
  189. var name = generateCacheNameOwned(app, isFoil, number);
  190. return GM_getValue(name, 0);
  191. }
  192. function setCacheOwned(app, isFoil, number, data)
  193. {
  194. var name = generateCacheNameOwned(app, isFoil, number);
  195. GM_setValue(name, data);
  196. }
  197.  
  198. // ===== End Cache =====
  199.  
  200. // ===== Helper =====
  201.  
  202. setTimeout(function ()
  203. {
  204. var counter = GM_getValue('counter', 0);
  205. GM_setValue('counter', ++counter);
  206. }, 0);
  207.  
  208. function debug(msg)
  209. {
  210. try
  211. {
  212. msg = msg ? (new String(msg)).trim().replace(/\s\s/gi, "").replace(/\s/gi, " ") : "";
  213. if (enableDebugConsole)
  214. console.log(msg);
  215. if (enableDebug)
  216. {
  217. var divDebugID = "div_debug_7e";
  218. var divDebugOuterID = divDebugID + "_outer";
  219. var divOut = document.getElementById(divDebugOuterID);
  220. var div = document.getElementById(divDebugID);
  221.  
  222. var isExistOuter = divOut != null;
  223. if (!isExistOuter)
  224. {
  225. divOut = document.createElement("div");
  226. divOut.id = divDebugOuterID;
  227. divOut.style = "font-family:'Courier New', Courier; font-size: 11px; z-index: 999999; padding: 3px; text-align: left;"
  228. + " border: 3px solid orange; color: black; background-color: rgba(255,255,255,0.9);"
  229. + " position: fixed; top: 3px; left: 3px; overflow-x:hidden; overflow-y:scroll; resize: both;";
  230. divOut.style.width = "150px";
  231. divOut.style.height = "100px";
  232.  
  233. if (div == null)
  234. {
  235. div = document.createElement("div");
  236. div.id = divDebugID;
  237. div.style.minWidth = "1000px";
  238. div.innerHTML = "<span style='font-weight: bold; line-height: 18px;'>Debug:</span>";
  239. }
  240. divOut.appendChild(div);
  241. document.body.appendChild(divOut);
  242. }
  243. div.innerHTML = div.innerHTML + " <br/> " + msg;
  244. divOut.scrollTop = divOut.scrollHeight;
  245. }
  246. }
  247. catch (e)
  248. {
  249. console.log("Ex: " + e);
  250. }
  251. }
  252.  
  253. function debugTime(header)
  254. {
  255. header = header ? (new String(header)) + ": " : "";
  256. var ms = (new Date()) - timeStart;
  257. debug(header + ms + "ms");
  258. }
  259.  
  260. function randNum()
  261. {
  262. return parseInt(Math.random() * 900000 + 100000);
  263. }
  264.  
  265. function randTempID()
  266. {
  267. return "id_temp_7e_" + randNum();
  268. }
  269.  
  270. function createDivTemp(id, html)
  271. {
  272. var div = document.getElementById(id);
  273. if (div == null)
  274. {
  275. div = document.createElement("div");
  276. div.id = id;
  277. document.body.appendChild(div);
  278. }
  279. div.style.display = "none";
  280. div.style.zIndex = "-999999";
  281.  
  282. // remove all external sources
  283. var pattScript = /(<(script|meta|link|style|title)[^>]*>|<\/(script|meta|link|style|title)>)/gi;
  284. html = html.replace(pattScript, "");
  285. // replace http to https
  286. //html = html.replace(/http:\/\//ig, "https://");
  287.  
  288. div.innerHTML = html;
  289. }
  290.  
  291. function removeDivTemp(id)
  292. {
  293. var ele = document.getElementById(id);
  294. ele.parentNode.removeChild(ele);
  295. }
  296.  
  297. function attachOnLoad(callback)
  298. {
  299. window.addEventListener("load", function (e) {
  300. callback();
  301. });
  302. }
  303. function attachOnReady(callback)
  304. {
  305. document.addEventListener("DOMContentLoaded", function (e) {
  306. if (document.readyState === "interactive")
  307. {
  308. callback();
  309. }
  310. });
  311. }
  312. function reload()
  313. {
  314. window.location = window.location.href;
  315. }
  316. function isError()
  317. {
  318. var retVal =
  319. window.location == window.parent.location
  320. &&
  321. (
  322. (
  323. document.querySelector("body.headerless_page"
  324. + ", body.flat_page"
  325. + ", #main"
  326. + ", #supernav"
  327. + ", table.tborder"
  328. + ", #headerrow"
  329. + ", #global_header"
  330. + ", .page_header_ctn"
  331. + ", .search_page"
  332. + ", #bigpicture_about"
  333. + ", #ig_bottom"
  334. + ", #feedHeaderContainer"
  335. + ", img[alt='Steam']"
  336. + ", .waitforauth") == null
  337. )
  338. ||
  339. (
  340. document.querySelector(".profile_fatalerror_message"
  341. + ", #error_msg") != null
  342. //|| document.querySelector("#error_box") != null
  343. //|| document.querySelector("#message") != null
  344. )
  345. );
  346. return retVal;
  347. }
  348. function isErrorCard()
  349. {
  350. var retVal = document.querySelectorAll("#message > p.returnLink").length > 0;
  351. return retVal;
  352. }
  353. function isErrorMarket()
  354. {
  355. var retVal = document.querySelectorAll("#searchResultsTable > .market_listing_table_message").length > 0
  356. ;//&& document.querySelector("#hover_content") == null);
  357. return retVal;
  358. }
  359. function getQueryByName(name)
  360. {
  361. name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  362. var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
  363. results = regex.exec(location.search);
  364. return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
  365. }
  366.  
  367. function insertBeforeElement(newNode, referenceNode)
  368. {
  369. referenceNode.parentNode.insertBefore(newNode, referenceNode);
  370. }
  371.  
  372. function insertAfterElement(newNode, referenceNode)
  373. {
  374. referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
  375. }
  376. function clickToSelect(ele)
  377. {
  378. if (ele != null)
  379. {
  380. var range = document.createRange();
  381. range.setStartBefore(ele.firstChild);
  382. range.setEndAfter(ele.lastChild);
  383. var sel = window.getSelection();
  384. sel.removeAllRanges();
  385. sel.addRange(range);
  386. }
  387. }
  388.  
  389. // ===== End Helper =====
  390.  
  391.  
  392. // ===== Cleaner =====
  393. /** Auto refresh when error
  394. */
  395. function refreshError()
  396. {
  397. if(isError())
  398. {
  399. debug("refreshError: activated");
  400. setTimeout(reload, 3000);
  401. }
  402. }
  403. function refreshErrorCard()
  404. {
  405. if(isErrorCard())
  406. {
  407. debug("refreshErrorCard: activated");
  408. setTimeout(reload, 3000);
  409. }
  410. }
  411. function refreshErrorMarket()
  412. {
  413. if(isErrorMarket())
  414. {
  415. debug("refreshErrorMarket: activated");
  416. setTimeout(reload, 3000);
  417. }
  418. }
  419. function refreshErrorTimeout(tm)
  420. {
  421. function refresh()
  422. {
  423. var url = document.documentURI;
  424. var pattCard = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  425. var pattTrade = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/tradeoffers\//i;
  426. var pattMarket = /^http:\/\/steamcommunity.com\/market\/listings\/[0-9]+/i;
  427.  
  428. if (url.indexOf("#") < 0 && url.indexOf("json") < 0 && url.indexOf("xml") < 0)
  429. {
  430. setTimeout(refreshError, tm);
  431. if (pattCard.test(url) || pattTrade.test(url))
  432. {
  433. setTimeout(refreshErrorCard, tm);
  434. }
  435.  
  436. if (pattMarket.test(url))
  437. {
  438. setTimeout(refreshErrorMarket, tm);
  439. }
  440. }
  441. }
  442. attachOnLoad(refresh);
  443. }
  444. if (enableRefreshError) refreshErrorTimeout(3000);
  445. /** Remove unnessary parameters in URL
  446. */
  447. function cleanLink()
  448. {
  449. var url = document.documentURI;
  450. var pattApp = /^http[s]?:\/\/store.steampowered.com\/(app|sub)\/[0-9]+/i;
  451. var pattBadge = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  452. var pattFork = /^http[s]?:\/\/store\.(.+steampowered|steamgames)\.com\//i;
  453. var pattParam = /\/\?.*$/
  454. var pattParamCC = /\/\?cc\=.*$/
  455. var urlNew = url;
  456. if (pattApp.test(url))
  457. {
  458. var urlNews = url.match(pattApp);
  459. if (urlNews != null)
  460. {
  461. var urlTail = url.replace(pattApp, "");
  462. if (urlTail == "")
  463. {
  464. urlNew = urlNews[0] + "/";
  465. }
  466. else if (urlTail != "/")
  467. {
  468. if (!pattParamCC.test(urlTail) && pattParam.test(urlTail))
  469. {
  470. urlNew = urlNews[0] + "/";
  471. }
  472. }
  473. }
  474. }
  475. else if (pattBadge.test(url))
  476. {
  477. var urlNews = url.match(pattBadge);
  478. if (urlNews != null)
  479. {
  480. var urlTail = url.replace(pattBadge, "");
  481.  
  482. if (urlTail.charAt(0) != "/")
  483. {
  484. urlNew = urlNews[0] + "/" + urlTail;
  485. }
  486. }
  487. }
  488. else if (pattFork.test(url))
  489. {
  490. urlNew = url.replace(pattFork, "http://store.steampowered.com/");
  491. }
  492. if (urlNew != url)
  493. {
  494. debug("cleanLink: activated");
  495. window.location = urlNew;
  496. }
  497. }
  498. if (enableCleanLink) cleanLink();
  499.  
  500. /** Change search parameter to page 1 to determine visited links
  501. */
  502. function cleanLinkSearch()
  503. {
  504. var pattSearch = /snr=1_7_7_230_150_[0-9]+/i
  505.  
  506. var as = document.querySelectorAll("a.search_result_row");
  507. for (var j = 0; j < as.length; j++)
  508. {
  509. var urlSearch = as[j].href;
  510. urlSearch = urlSearch.replace(pattSearch, "snr=1_7_7_230_150_1");
  511. as[j].href = urlSearch;
  512. }
  513.  
  514. document.addEventListener("DOMNodeInserted", onNodeInserted);
  515. function onNodeInserted(e)
  516. {
  517. try
  518. {
  519. var node = e.target;
  520. if (node.classList.contains("search_result_row"))
  521. {
  522. var urlSearch = node.href;
  523. urlSearch = urlSearch.replace(pattSearch, "snr=1_7_7_230_150_1");
  524. node.href = urlSearch;
  525. }
  526. var count = document.querySelectorAll(".search_result_row").length;
  527. var divs = document.querySelectorAll(".search_pagination_left");
  528. for (var i = 0; i < divs.length; i++)
  529. {
  530. var oldVals = divs[i].innerHTML.match(/[0-9]+/g);
  531. var oldVal = oldVals[oldVals.length > 0 ? oldVals.length-1 : 0];
  532. divs[i].innerHTML = "showing " + count + " of " + oldVal;
  533. }
  534. }
  535. catch (ex)
  536. {
  537. }
  538. }
  539. if (enableAutoscrollSearch)
  540. {
  541. var divButton = document.createElement("div");
  542. divButton.classList.add("btn_client_small");
  543. divButton.id = "divAutoscroll";
  544. divButton.style = "position: fixed; right: 20px; bottom: 20px; z-index:3;";
  545. divButton.innerHTML = "<a href='' onclick='document.addEventListener(\"DOMNodeInserted\", function(){ window.scrollTo(0,document.body.scrollHeight); }); this.parentElement.style.display=\"none\"; window.scrollTo(0,document.body.scrollHeight); return false;'>Autoscroll to end</a>";
  546. document.body.appendChild(divButton);
  547. }
  548. }
  549. function cleanLinkSearchTimeout(tm)
  550. {
  551. var url = document.documentURI;
  552. var patt = /^http[s]?:\/\/store.steampowered.com\/search\//i;
  553.  
  554. if (patt.test(url))
  555. {
  556. setTimeout(cleanLinkSearch, tm);
  557. }
  558. }
  559. if (enableCleanLink) cleanLinkSearchTimeout(100);
  560.  
  561. /** Remove link lifter in URL
  562. */
  563. function cleanLinkLifter()
  564. {
  565. var url = document.documentURI;
  566. var patt = /^http[s]?:\/\/steamcommunity.com\//i;
  567. var pattHome = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/home/i;
  568. function cleanLifter()
  569. {
  570. var lifter = "https://steamcommunity.com/linkfilter/";
  571. var lifterLen = lifter.length;
  572. var lifter2 = "?url=";
  573. var lifterLen2 = lifter2.length;
  574. var js = "javascript:"
  575. var jsLen = js.length;
  576. var as = document.getElementsByTagName("a");
  577. for (var i = 0; i < as.length; i++)
  578. {
  579. var urlLink = as[i].href;
  580. if (urlLink.indexOf(lifter) == 0)
  581. {
  582. urlLink = urlLink.substr(lifterLen);
  583. if (urlLink.indexOf(lifter2) == 0)
  584. {
  585. urlLink = urlLink.substr(lifterLen2);
  586. }
  587. as[i].href = urlLink;
  588. }
  589. else if (patt.test(url) && urlLink.indexOf(js) == 0)
  590. {
  591. if (as[i].getAttribute('onclick') == null)
  592. {
  593. urlLink = decodeURIComponent(urlLink.substr(jsLen));
  594. as[i].setAttribute('onclick', urlLink + "; return false;");
  595. }
  596. }
  597. }
  598. }
  599. var cleanLifterTimeoutId = 0;
  600. function cleanLifterTimeout()
  601. {
  602. clearTimeout(cleanLifterTimeoutId);
  603. cleanLifterTimeoutId = setTimeout(cleanLifter, 1000);
  604. }
  605. attachOnReady(cleanLifter);
  606. if (pattHome.test(url))
  607. {
  608. document.addEventListener("DOMNodeInserted", cleanLifterTimeout);
  609. }
  610. }
  611. if (enableCleanLink) cleanLinkLifter();
  612.  
  613. /** Clean Steam's menu on top
  614. */
  615. function cleanSteamMenuTimeout(tm)
  616. {
  617. GM_addStyle(
  618. " .header_installsteam_btn_content , .header_installsteam_btn { display: none; } " // Steam header
  619. + " #enhanced_pulldown { display: none; } " // Enhanced Steam header
  620. + " #soe-t-menu { display: none !important; } " // SOE header
  621. );
  622. attachOnReady(function ()
  623. {
  624. setTimeout(function()
  625. {
  626. var soe_menu = document.querySelector("#soe-t-menu");
  627. if (soe_menu != null)
  628. {
  629. soe_menu.textContent = "SOE";
  630. var parent = soe_menu.parentElement;
  631. for (var i = 0; i < parent.childNodes.length; i++)
  632. {
  633. var node = parent.childNodes[i];
  634. if (node.nodeName == "#text" && node.nodeValue.toString().trim() == "|")
  635. {
  636. node.parentElement.removeChild(node);
  637. break;
  638. }
  639. }
  640. soe_menu.parentElement.parentElement.insertBefore(soe_menu, null);
  641. }
  642. }, tm);
  643. });
  644. var menu = document.querySelector("#account_pulldown");
  645. if (menu != null)
  646. {
  647. menu.addEventListener('mouseover', function() {
  648. GM_addStyle(
  649. " #enhanced_pulldown { display: inline-block !important; } " // Enhanced Steam header
  650. + " #soe-t-menu { display: inline-block !important; } " // SOE header
  651. );
  652. });
  653. }
  654. // fix market transaction display // temp
  655. GM_addStyle("#market_transactions .transactionRowTitle { display: inline-block; padding-right: 5px; }");
  656. /*
  657. setTimeout(function()
  658. {
  659. var as = document.querySelectorAll(".header_installsteam_btn_content , .header_installsteam_btn");
  660. for (var i = 0; i < as.length; i++)
  661. {
  662. as[i].style.display = "none";
  663. }
  664. }, tm);
  665. attachOnLoad(function ()
  666. {
  667. setTimeout(function()
  668. {
  669. var aE = document.getElementById("enhanced_pulldown");
  670. if (aE != null)
  671. {
  672. aE.style.display = "none";
  673. }
  674. }, tm);
  675. });
  676. */
  677. }
  678. if (enableCleanSteamMenu) cleanSteamMenuTimeout(0);
  679.  
  680. /** Hide EnhancedSteam's price on Badge page
  681. */
  682. function hideEnhancedBadgePrice()
  683. {
  684. GM_addStyle(".es_card_search, .es_item_action { display: none !important; } ");
  685. /*
  686. document.addEventListener("DOMNodeInserted", onNodeInserted);
  687. function onNodeInserted(e)
  688. {
  689. try
  690. {
  691. var node = e.target;
  692. if (node.classList.contains("es_card_search"))
  693. {
  694. debug("hideEnhanced: " + node.innerHTML);
  695. node.style.display = "none";
  696. }
  697. }
  698. catch (ex)
  699. {
  700. }
  701. }
  702. */
  703. }
  704. function hideEnhancedBadgePriceTimeout(tm)
  705. {
  706. var url = document.documentURI;
  707. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/(gamecards\/[0-9]+|inventory)/i;
  708.  
  709. if (patt.test(url))
  710. {
  711. setTimeout(hideEnhancedBadgePrice, tm);
  712. }
  713. }
  714. if (enableHideEnhancedBadgePrice) hideEnhancedBadgePriceTimeout(0);
  715.  
  716. // ===== End Cleaner =====
  717.  
  718. // ===== Main =====
  719.  
  720. /** Disable autoplay on Greenlight page while autoplay option is on
  721. */
  722. function disableGreenlightAutoplay()
  723. {
  724. var iframes = document.getElementsByTagName("iframe");
  725. for (var i in iframes)
  726. {
  727. if (iframes[i].className == "highlight_flash_player_notice")
  728. {
  729. iframes[i].src = iframes[i].src.replace("autoplay=1", "autoplay=0");
  730. }
  731. }
  732. }
  733. function disableGreenlightAutoplayTimeout(tm)
  734. {
  735. var url = document.documentURI;
  736. var patt = /^http:\/\/steamcommunity.com\/sharedfiles\/filedetails\//i;
  737.  
  738. if (patt.test(url))
  739. {
  740. attachOnLoad(function ()
  741. {
  742. setTimeout(disableGreenlightAutoplay, tm);
  743. });
  744. }
  745. }
  746. if (enableGreenlightNoAutoplay) disableGreenlightAutoplayTimeout(0);
  747.  
  748. /** Move Greenlit header to match voting section of Greenlight item
  749. */
  750. function moveGreenlitHeader()
  751. {
  752. var eleGreenlit = document.querySelector(".flag");
  753. var eleArea = document.querySelector(".workshopItemPreviewArea");
  754. if (eleGreenlit != null && eleArea != null)
  755. {
  756. eleArea.appendChild(eleGreenlit.parentElement.parentElement);
  757. }
  758. }
  759. function moveGreenlitHeaderReady(tm)
  760. {
  761. var url = document.documentURI;
  762. var patt = /^http:\/\/steamcommunity.com\/sharedfiles\/filedetails\//i;
  763.  
  764. if (patt.test(url))
  765. {
  766. attachOnReady(function ()
  767. {
  768. moveGreenlitHeader();
  769. });
  770. }
  771. }
  772. if (enableMoveGreenlitHeader) moveGreenlitHeaderReady();
  773.  
  774. /** Move button in Edit Profile page to right
  775. */
  776. function moveMenuEditProfile()
  777. {
  778. GM_addStyle(
  779. ".group_content_bodytext { position: fixed; top: 400px; margin-left: 680px; line-height: 34px; z-index: 10; } "
  780. + ".rightcol { position: fixed; top: 230px; margin-left: 658px; z-index: 10; } "
  781. + ".saved_changes_msg { width: 610px; } "
  782. + ".showcase_stat .value { z-index: 2; position: relative; } "
  783. );
  784. }
  785. function moveMenuEditProfileTimeout(tm)
  786. {
  787. var url = document.documentURI;
  788. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/([^\/]+\/edit)?/i;
  789.  
  790. if (patt.test(url))
  791. {
  792. setTimeout(moveMenuEditProfile, tm);
  793. }
  794. }
  795. if (enableMoveMenuEditProfile) moveMenuEditProfileTimeout(0);
  796.  
  797. /** Add small button on friend section in Badge page to view friends' Badge page for comparing cards
  798. * Reduce height of Review textbox
  799. */
  800. function linkBadgeToFriend()
  801. {
  802. var url = document.documentURI;
  803. var pattHead = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]*/i;
  804. var urlTail = url.replace(pattHead, "");
  805. //var pattProfile = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+[\/]?$/i;
  806.  
  807. // Correct style
  808. {
  809. var styleCorrect = "";
  810. // fix long card name show incorrect column of cards
  811. styleCorrect += ".badge_card_set_card .badge_card_set_text { max-width: 220px; } ";
  812. // fix Firefox show incorrect column of friends' avatar
  813. styleCorrect += ".persona { line-height: 16px; } ";
  814. // fix EnhancedSteam show incorrect size of next badge progress
  815. styleCorrect += ".gamecard_badge_progress .badge_info { width: 250px !important; } ";
  816. // fix oversize friend action button
  817. styleCorrect += ".badge_friendwithgamecard_actions .btn_medium { padding-bottom: 0px !important;"
  818. + " width: 26px !important; text-align: center !important; } ";
  819. // fix card name display over counter
  820. styleCorrect += ".badge_card_set_text_qty { z-index: 2 !important; position: relative !important; } ";
  821. // fix card drop counter is behind button and reposition
  822. styleCorrect += ".badge_title_stats_content { margin-top: -4px; } ";
  823. if (document.querySelector(".badge_title_playgame") != null)
  824. {
  825. styleCorrect += ".badge_title_stats_content { padding-right: 45px; } ";
  826. }
  827. GM_addStyle(styleCorrect);
  828. }
  829. // Link to friends
  830. {
  831. var els = document.querySelectorAll(".badge_friends_have_earned_friends, .badge_friendwithgamecard");
  832. for (var i = 0; i < els.length; i++)
  833. {
  834. var as = els[i].querySelectorAll(".playerAvatar a, a.persona");
  835. var limit = 1;
  836. var curLimit = 0;
  837.  
  838. for (var j = 0; j < as.length; j++)
  839. {
  840. var a = as[j];
  841. //if (pattProfile.test(a.href))
  842. {
  843. var badgeUrl = a.href + urlTail;
  844.  
  845. if (els[i].classList.contains("badge_friends_have_earned_friends")
  846. || !a.parentNode.classList.contains("playerAvatar"))
  847. {
  848. a.href = badgeUrl;
  849. }
  850.  
  851. if (curLimit < limit && els[i].classList.contains("badge_friendwithgamecard"))
  852. {
  853. elActs = els[i].getElementsByClassName("badge_friendwithgamecard_actions");
  854. for (var k = 0; k < elActs.length; k++)
  855. {
  856. var eleA = document.createElement("a");
  857. eleA.classList.add("btn_grey_grey");
  858. eleA.classList.add("btn_medium");
  859. eleA.setAttribute("title", "View friend's badge");
  860. eleA.setAttribute("href", badgeUrl);
  861. eleA.innerHTML = "<img style='height:16px; opacity:0.66'"
  862. + " src='http://cdn4.store.steampowered.com/public/images/ico/ico_cards.png'></a> ";
  863. elActs[k].appendChild(eleA);
  864. curLimit += 1;
  865. } // end for k
  866. }
  867. }
  868. } // end for j
  869. } // end for i
  870. }
  871. // Sort friends
  872. {
  873. setTimeout(function()
  874. {
  875. var eleSections = document.querySelectorAll(".badge_friendswithgamecards_section");
  876. for (var i = 0; i < eleSections.length; i++)
  877. {
  878. var keyArr = new Array();
  879. var valArr = new Array();
  880. var eleFriends = eleSections[i].querySelectorAll(".badge_friendwithgamecard");
  881. for (var j = 0; j < eleFriends.length; j++)
  882. {
  883. var elePersona = eleFriends[j].querySelector(".persona");
  884. if (elePersona != null)
  885. {
  886. var key = "";
  887. if (elePersona.classList.contains("in-game"))
  888. {
  889. key = "01";
  890. }
  891. else if (elePersona.classList.contains("online"))
  892. {
  893. key = "02";
  894. }
  895. else
  896. {
  897. key = "03";
  898. }
  899. var key = key + "___" + elePersona.textContent.trim().toLowerCase()
  900. + "___" + elePersona.getAttribute("data-miniprofile");
  901. keyArr.push(key);
  902. valArr[key] = eleFriends[j];
  903. eleSections[i].removeChild(eleFriends[j]);
  904. }
  905. } // end for j
  906. keyArr.sort();
  907. for (var j = keyArr.length - 1; j > -1 ; j--)
  908. {
  909. eleSections[i].insertBefore(valArr[keyArr[j]], eleSections[i].firstChild);
  910. } // end for j
  911. } // end for i
  912. }, 100);
  913. }
  914. }
  915. function linkBadgeToFriendAttach()
  916. {
  917. var url = document.documentURI;
  918. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  919.  
  920. if (patt.test(url) && !isErrorCard())
  921. {
  922. attachOnLoad(linkBadgeToFriend);
  923. }
  924. }
  925. if (enableLinkBadgeToFriend) linkBadgeToFriendAttach();
  926.  
  927. /** Add button on top of Store page to view Badge page
  928. */
  929. function linkStoreToBadge()
  930. {
  931. var url = document.documentURI;
  932. var patt = /^http[s]?:\/\/store.steampowered.com\/app\//i;
  933. var pattEnd = /[^0-9].*$/i;
  934. var app = url.replace(patt, "").replace(pattEnd, "");
  935.  
  936. var aOwner = document.querySelector("#global_actions > .user_avatar");
  937. var isLoggedIn = aOwner != null;
  938. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  939. var isOwned = document.querySelector(".game_area_already_owned") != null;
  940.  
  941. var urlCard = "category2=29";
  942. var titleCard = "Steam Trading Cards";
  943. var urlDlc = "category1=21";
  944. var titleDlc = "Downloadable Content";
  945. var urlAch = "category2=22";
  946. var titleAch = "Steam Achievement";
  947. var isBadge = false;
  948. var isBadgeMap = false;
  949. var isAch = false;
  950. var as = document.querySelectorAll(".game_area_details_specs a");
  951. for (var i = 0; i < as.length; i++)
  952. {
  953. if (appDlcs.indexOf(app) > -1 || as[i].href.indexOf(urlDlc) > -1 || as[i].textContent == titleDlc)
  954. {
  955. isBadge = false;
  956. isAch = false;
  957. break;
  958. }
  959. else if (as[i].href.indexOf(urlCard) > -1 || as[i].textContent == titleCard)
  960. {
  961. isBadge = true;
  962. }
  963. else if (as[i].href.indexOf(urlAch) > -1 || as[i].textContent == titleAch)
  964. {
  965. isAch = true;
  966. }
  967. }
  968. if (appCardMaps[app] != null)
  969. {
  970. isBadge = true;
  971. isBadgeMap = true;
  972. }
  973. else if (!isBadge)
  974. {
  975. if (appCards.indexOf(app) > -1)
  976. {
  977. isBadge = true;
  978. }
  979. }
  980. if (isBadge)
  981. {
  982. var appCard = app;
  983. if (isBadgeMap)
  984. {
  985. appCard = appCardMaps[app];
  986. }
  987. var divs = document.getElementsByClassName("apphub_OtherSiteInfo");
  988. for (var i = 0; i < divs.length; i++)
  989. {
  990. divs[i].innerHTML = divs[i].innerHTML
  991. + " &nbsp;<a class=\"btnv6_blue_hoverfade btn_medium\""
  992. + " href=\"" + ownerUrl + "/gamecards/" + appCard + "/\">"
  993. + "<span>Trading Cards</span></a>";
  994. }
  995. }
  996. if (false && isAch)
  997. {
  998. var urlAchLink = (isLoggedIn && isOwned ? ownerUrl + "/stats/appid/" : "http://steamcommunity.com/stats/")
  999. + app + "/achievements/";
  1000. var divCommu = document.querySelector(".communitylink .block_content_inner");
  1001. if (divCommu != null)
  1002. {
  1003. var aAch = ' <a class="linkbar" href="' + urlAchLink + '">'
  1004. + '<div class="rightblock" style="margin-top: 3px;"><img src="http://cdn4.store.steampowered.com/public/images/ico/ico_achievements.png"'
  1005. + ' align="top" border="0" style="margin-right: -9px; height: 20px; margin-top: -5px;"></div>'
  1006. + 'View Steam Achievements</a>';
  1007. divCommu.innerHTML = divCommu.innerHTML + aAch;
  1008. }
  1009. /*var divDemo = document.querySelector("#demo_block > div");
  1010. if (divDemo != null)
  1011. {
  1012. var divAch = '<div class="demo_area_button"><a class="game_area_wishlist_btn" href="'
  1013. + urlAchLink + '">View Steam Achievements</a></div>';
  1014. divDemo.innerHTML = divAch + divDemo.innerHTML;
  1015. }*/
  1016. }
  1017. var txtRec = document.getElementById("game_recommendation");
  1018. if (txtRec != null)
  1019. {
  1020. // reduce height of review textbox
  1021. txtRec.style.height = "16px";
  1022. txtRec.onfocus = function(){txtRec.style.height="150px";};
  1023. }
  1024. // Move early access zone
  1025. {
  1026. var eleEa = document.querySelector(".early_access_header");
  1027. if (eleEa != null)
  1028. {
  1029. var elePurchase = document.querySelector("#game_area_purchase");
  1030. if (elePurchase != null)
  1031. {
  1032. insertBeforeElement(elePurchase, eleEa);
  1033. }
  1034. }
  1035. }
  1036. // Redirect Steam run
  1037. {
  1038. var eleCart = document.querySelector(".btn_addtocart a");
  1039. if (eleCart != null)
  1040. {
  1041. if (eleCart.href.indexOf("ShowGotSteamModal") > -1)
  1042. {
  1043. eleCart.href = eleCart.href.replace("javascript:ShowGotSteamModal('", "")
  1044. .replace(/\',.*$/i, "");
  1045. }
  1046. }
  1047. }
  1048. if (!isLoggedIn)
  1049. {
  1050. var eleLoginMain = document.querySelector("a.global_action_link[href*='/login/']");
  1051. var eleLoginQueue = document.querySelector(".queue_actions_ctn a[href*='/login/']");
  1052. if (eleLoginMain != null && eleLoginQueue != null)
  1053. {
  1054. eleLoginMain.setAttribute("href", eleLoginQueue.getAttribute("href"));
  1055. }
  1056. }
  1057. GM_addStyle(".game_area_dlc_row, .tab_item { display: inherit !important; } "
  1058. + " .game_purchase_action_bg { white-space: normal !important; } ");
  1059. }
  1060. function linkStoreToBadgeAttach(tm)
  1061. {
  1062. var url = document.documentURI;
  1063. var patt = /^http[s]?:\/\/store.steampowered.com\/(app|sub)\//i;
  1064.  
  1065. if (patt.test(url))
  1066. {
  1067. attachOnLoad(function()
  1068. {
  1069. setTimeout(linkStoreToBadge, tm);
  1070. });
  1071. }
  1072. }
  1073. if (enableLinkStoreToBadge) linkStoreToBadgeAttach(100);
  1074.  
  1075. /** Add button in Forum page to view Badge page
  1076. * Mark topic to determine visited links
  1077. */
  1078. function linkForumToBadge()
  1079. {
  1080. var url = document.documentURI;
  1081. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/app\//i;
  1082. var pattAppTail = /[^0-9]+.*/i;
  1083. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1084.  
  1085. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  1086. var isLoggedIn = aOwner != null;
  1087. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1088.  
  1089. var divs = document.getElementsByClassName("apphub_OtherSiteInfo");
  1090. for (var j = 0; j < divs.length; j++)
  1091. {
  1092. var aBadge = " <a class='btn_darkblue_white_innerfade btn_medium' href='"
  1093. + ownerUrl + "/gamecards/" + app
  1094. + "/'><span>Trading Cards</span></a> ";
  1095. divs[j].innerHTML = divs[j].innerHTML + aBadge;
  1096. }
  1097. function markTopic()
  1098. {
  1099. var as = document.getElementsByClassName("forum_topic_overlay");
  1100. for (var i = 0; i < as.length; i++)
  1101. {
  1102. // mark topic
  1103. as[i].style.borderLeft = "3px solid";
  1104. }
  1105. }
  1106. markTopic();
  1107. document.addEventListener("DOMNodeInserted", markTopic);
  1108. }
  1109. function linkForumToBadgeTimeout(tm)
  1110. {
  1111. var url = document.documentURI;
  1112. var patt = /^http:\/\/steamcommunity.com\/app\/[0-9]+\/tradingforum\//i;
  1113.  
  1114. if (patt.test(url))
  1115. {
  1116. setTimeout(linkForumToBadge, tm);
  1117. }
  1118. }
  1119. if (enableLinkForumToBadge) linkForumToBadgeTimeout(100);
  1120.  
  1121. /** Add buttons in Badge page to view Trading Forum, Store, friend's Inventory and my Badge page
  1122. */
  1123. function linkBadgeToForum()
  1124. {
  1125. var url = document.documentURI;
  1126.  
  1127. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\//i;
  1128. var pattAppTail = /[^0-9]+.*/i;
  1129. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1130. GM_addStyle(".sbh_badge_menu_right { float: right; margin-left: 5px; } ");
  1131.  
  1132. var divs = document.getElementsByClassName("gamecards_inventorylink");
  1133. if (divs.length > 0)
  1134. {
  1135. var aStoreUrl = "http://store.steampowered.com/app/" + app + "/";
  1136. var aForumUrl = "http://steamcommunity.com/app/" + app + "/tradingforum/";
  1137. var aCustom = " <a class='btn_grey_grey btn_small_thin sbh_badge_menu_right' href='" + aStoreUrl + "'>"
  1138. + " <span>Visit Store Page</span></a> "
  1139. + " <a class='btn_grey_grey btn_small_thin sbh_badge_menu_right' href='" + aForumUrl + "'>"
  1140. + " <span>Visit Trade Forum</span></a> ";
  1141.  
  1142. divs[0].innerHTML = divs[0].innerHTML + aCustom;
  1143. }
  1144.  
  1145. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  1146. var isLoggedIn = aOwner != null;
  1147. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1148.  
  1149. var aFriend = document.querySelector(".profile_small_header_name > a");
  1150. var isFriendExist = aFriend != null;
  1151. var friendUrl = isFriendExist ? aFriend.href : "http://steamcommunity.com/my";
  1152. var friendName = isFriendExist ? aFriend.textContent.trim() : "my"
  1153. var friendNameOwner = isFriendExist ? friendName + "'s" : friendName;
  1154.  
  1155. var isOwner = isLoggedIn && ownerUrl == friendUrl;
  1156.  
  1157. if (!isOwner)
  1158. {
  1159. var divInv;
  1160. if (divs.length > 0)
  1161. {
  1162. divInv = divs[0];
  1163. }
  1164. else
  1165. {
  1166. divInv = document.createElement("div");
  1167. divInv.classList.add("gamecards_inventorylink");
  1168. var divBadge = document.querySelector(".badge_detail_tasks");
  1169. if (divBadge != null)
  1170. {
  1171. divBadge.insertBefore(divInv, divBadge.firstChild);
  1172. }
  1173. }
  1174. var aFrInvUrl = friendUrl + "/inventory/#753_6";
  1175. var aOwnUrl = url.replace(pattAppHead, ownerUrl + "/gamecards/");
  1176. divInv.innerHTML = divInv.innerHTML
  1177. + "<a class='btn_grey_grey btn_small_thin' href='" + aFrInvUrl + "'><span>View cards in "
  1178. + friendNameOwner + " Inventory</span></a> "
  1179. + " <a class='btn_grey_grey btn_small_thin' href='" + aOwnUrl + "'><span>View my Progress</span></a> ";
  1180.  
  1181. }
  1182. }
  1183. function linkBadgeToForumAttach()
  1184. {
  1185. var url = document.documentURI;
  1186. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  1187.  
  1188. if (patt.test(url) && !isErrorCard())
  1189. {
  1190. attachOnLoad(linkBadgeToForum);
  1191. }
  1192. }
  1193. if (enableLinkBadgeToForum) linkBadgeToForumAttach();
  1194.  
  1195. /** Add button in Market page to view Badge and Store page
  1196. */
  1197. function linkMarketToBadge()
  1198. {
  1199. var url = document.documentURI;
  1200.  
  1201. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/market\/listings\/753\//i;
  1202. var pattAppTail = /[^0-9]+.*/i;
  1203. var pattNumber = /[0-9]+/;
  1204. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1205.  
  1206. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  1207. var isLoggedIn = aOwner != null;
  1208. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1209.  
  1210. GM_addStyle(
  1211. "#market_buynow_dialog_purchase > span:nth-child(1) { line-height: 80px; padding: 0px 50px 0px 50px !important; } "
  1212. + "#market_buynow_dialog { width: 850px; } "
  1213. + ".market_listing_table_header { margin: 0px; } "
  1214. + ".market_listing_row { margin-top: 2px; } "
  1215. );
  1216. var div_tabL = document.querySelectorAll("div.market_large_tab_well");
  1217. for (var i = 0; i < div_tabL.length; i++)
  1218. {
  1219. // reduce height of header
  1220. div_tabL[i].style.height = "50px";
  1221. }
  1222. var div_tabLB = document.querySelectorAll("div.market_large_tab_well_gradient");
  1223. for (var i = 0; i < div_tabLB.length; i++)
  1224. {
  1225. div_tabLB[i].style.height = "65px";
  1226. }
  1227.  
  1228. var div_store = document.getElementById("largeiteminfo_game_name");
  1229. if (div_store != null)
  1230. {
  1231. div_store.innerHTML = "<a href='http://store.steampowered.com/app/" + app + "/'>"
  1232. + div_store.innerHTML + "</a>";
  1233. }
  1234.  
  1235. var isFoil = false;
  1236. var ele_name = document.getElementById("largeiteminfo_item_name");
  1237. if (ele_name != null)
  1238. {
  1239. isFoil = (ele_name.innerHTML.search("Foil") > -1);
  1240. ele_name.innerHTML = "<a href='" + ownerUrl + "/gamecards/" + app
  1241. + (isFoil ? "/?border=1" : "/") + "'>" + ele_name.innerHTML + "</a>";
  1242. }
  1243.  
  1244. var ele_icon = document.getElementsByClassName("item_desc_game_icon");
  1245. for (var i = 0; i < ele_icon.length; i++)
  1246. {
  1247. ele_icon[i].innerHTML = "<a href='http://store.steampowered.com/app/" + app + "/'>"
  1248. + ele_icon[i].innerHTML + "</a>";
  1249. }
  1250.  
  1251. var div_nav = document.getElementsByClassName("market_large_tab_well");
  1252. for (var j = 0; j < div_nav.length; j++)
  1253. {
  1254. var aBadge = ' <div class="apphub_OtherSiteInfo" '
  1255. + 'style="position: relative; float: right; right: 2px; top: 2px;"> '
  1256. + '<a style="position: relative; z-index: 1;" class="btn_darkblue_white_innerfade btn_medium" '
  1257. + 'href="#" onclick="document.getElementById(\'pricehistory\').style.display = \'inherit\'; '
  1258. + 'document.querySelector(\'.pricehistory_zoom_controls\').style.display = \'inherit\'; return false; " >'
  1259. + '<span>Show History</span></a> &nbsp;'
  1260. + '<a style="position: relative; z-index: 1;" class="btn_darkblue_white_innerfade btn_medium" '
  1261. + 'href="http://store.steampowered.com/app/' + app + '"><span>Store Page</span></a> &nbsp;'
  1262. + '<a class="btn_darkblue_white_innerfade btn_medium" '
  1263. + 'href="' + ownerUrl + '/gamecards/' + app + (isFoil ? "/?border=1" : "/")
  1264. + '"><span>Trading Cards</span></a></div>';
  1265. div_nav[j].innerHTML = div_nav[j].innerHTML + aBadge;
  1266. GM_addStyle(
  1267. "#pricehistory, .pricehistory_zoom_controls { display: none } "
  1268. );
  1269. }
  1270. var span_list = document.querySelectorAll("div.market_listing_row > div:nth-child(3) > span:nth-child(1) > span:nth-child(1)");
  1271. for (var i = 0; i < span_list.length; i++)
  1272. {
  1273. if (!pattNumber.test(span_list[i].textContent))
  1274. {
  1275. span_list[i].parentElement.parentElement.parentElement.style.display = "none";
  1276. }
  1277. }
  1278. // preview bg in profile
  1279. {
  1280. if (ownerUrl != "http://steamcommunity.com/my")
  1281. {
  1282. var aImg = document.querySelector("#largeiteminfo_item_actions > a");
  1283. if (aImg != null)
  1284. {
  1285. var img = aImg.href;
  1286. if (img.indexOf(".jpg") > -1)
  1287. {
  1288. var urlPreview = ownerUrl + "?previewbg=" + img;
  1289. var a = document.createElement("a");
  1290. a.classList.add("btn_small");
  1291. a.classList.add("btn_grey_white_innerfade");
  1292. a.setAttribute("target", "_blank");
  1293. a.href = urlPreview;
  1294. a.innerHTML = '<span>Preview in Profile</span>';
  1295. aImg.parentElement.appendChild(a);
  1296. }
  1297. }
  1298. }
  1299. }
  1300. }
  1301. function linkMarketToBadgeAttach()
  1302. {
  1303. var url = document.documentURI;
  1304. var patt = /^http:\/\/steamcommunity.com\/market\/listings\/753\/[0-9]+/i;
  1305.  
  1306. if (patt.test(url) && !isErrorMarket())
  1307. {
  1308. attachOnLoad(linkMarketToBadge);
  1309. }
  1310. }
  1311. if (enableLinkMarketToBadge) linkMarketToBadgeAttach();
  1312.  
  1313. /** Add price of each cards in Badge page and link to Market page
  1314. */
  1315. function linkBadgeToMarket()
  1316. {
  1317. GM_addStyle(
  1318. ".div_market_price { float: right; } " // padding-top: 1px; display: inline-block; padding-left: 90px;
  1319. + ".gamecard_badge_craftbtn_ctn .badge_craft_button { width: 160px !important; } "
  1320. );
  1321. var url = document.documentURI;
  1322.  
  1323. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\//i;
  1324. var pattAppTail = /[^0-9]+.*/i;
  1325. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1326. var isFoil = url.indexOf("border=1") > -1;
  1327. var urlExternal = "http://www.steamcardexchange.net/index.php?gamepage-appid-" + app;
  1328. var urlMarket = "http://steamcommunity.com/market/listings/753/";
  1329. var priceCards = new Array();
  1330. var priceUrls = new Array();
  1331. updatePrice();
  1332.  
  1333. var isCacheExpire = checkCacheExpire(app);
  1334. if (isCacheExpire || !enableCache)
  1335. {
  1336. setTimeout(function ()
  1337. {
  1338. GM_xmlhttpRequest({
  1339. method: "GET",
  1340. url: urlExternal,
  1341. onload: getExternalPrice,
  1342. });
  1343. }, 0);
  1344. }
  1345.  
  1346. function getExternalPrice(res)
  1347. {
  1348. try
  1349. {
  1350. var pattNumCard = /Card [0-9]+ of /i;
  1351. var pattMarket = /^http:\/\/steamcommunity.com\/market\/listings\/753\//i;
  1352. var pattPrice = /(Price: |Last seen: )/i;
  1353.  
  1354. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  1355. var isLoggedIn = aOwner != null;
  1356. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1357.  
  1358. var aFriend = document.querySelector(".profile_small_header_name > a");
  1359. var isFriendExist = aFriend != null;
  1360. var friendUrl = isFriendExist ? aFriend.href : "http://steamcommunity.com/my";
  1361. var friendName = isFriendExist ? aFriend.textContent.trim() : "my"
  1362. var friendNameOwner = isFriendExist ? friendName + "'s" : friendName;
  1363.  
  1364. var isOwner = isLoggedIn && ownerUrl == friendUrl;
  1365.  
  1366. var divTempID = randTempID();
  1367. createDivTemp(divTempID, res.responseText);
  1368. try
  1369. {
  1370. //debug("ID: "+divTempID);
  1371. var divTemp = document.getElementById(divTempID);
  1372. var numCard = 0;
  1373. try
  1374. {
  1375. var spanNumber = divTemp.getElementsByClassName("element-count")[0];
  1376. if (spanNumber == null)
  1377. {
  1378. debug("Warning: can't get price");
  1379. return;
  1380. }
  1381. numCard = parseInt(spanNumber.textContent.replace(pattNumCard, ""));
  1382. }
  1383. catch (e)
  1384. {
  1385. debug("Ex: " + e);
  1386. }
  1387. var offsetCard = isFoil ? numCard : 0;
  1388. var curCard = 0;
  1389.  
  1390. var isCacheExpire = checkCacheExpire(app);
  1391.  
  1392. priceCards = new Array();
  1393. priceUrls = new Array();
  1394.  
  1395. var as = divTemp.getElementsByClassName("button-blue");
  1396. for (var i = 0; i < as.length; i++)
  1397. {
  1398. if (pattMarket.test(as[i].href))
  1399. {
  1400. if (curCard < numCard * 2)
  1401. {
  1402. var cPrice = as[i].textContent.replace(pattPrice, "").trim();
  1403. var cUrl = as[i].href.replace(urlMarket, "");
  1404.  
  1405. var indexCard = curCard - offsetCard;
  1406. if (indexCard >= 0 && indexCard < numCard)
  1407. {
  1408. priceCards[indexCard] = cPrice;
  1409. priceUrls[indexCard] = cUrl;
  1410. }
  1411.  
  1412. // cache
  1413. if (enableCache && isCacheExpire)
  1414. {
  1415. setCacheTime(app);
  1416. if (curCard < numCard)
  1417. {
  1418. setCachePrice(app, false, curCard, cPrice);
  1419. setCacheUrl(app, false, curCard, cUrl);
  1420. }
  1421. else // foil
  1422. {
  1423. setCachePrice(app, true, curCard - numCard, cPrice);
  1424. setCacheUrl(app, true, curCard - numCard, cUrl);
  1425. }
  1426. }
  1427.  
  1428. curCard += 1;
  1429. }
  1430. else
  1431. {
  1432. break;
  1433. }
  1434. }
  1435. }
  1436. }
  1437. catch (e)
  1438. {
  1439. debug("Ex: " + e);
  1440. }
  1441. removeDivTemp(divTempID);
  1442.  
  1443. updatePrice();
  1444.  
  1445. debugTime("getExternalPrice");
  1446. }
  1447. catch (e)
  1448. {
  1449. debug("Ex: " + e);
  1450. }
  1451. }
  1452.  
  1453. function updatePrice()
  1454. {
  1455. var pattNum = /[0-9\.]+/;
  1456. var colorUp = "#CC0000";
  1457. var colorDown = "#009900";
  1458.  
  1459. if (enableCache)
  1460. {
  1461. priceCards = new Array();
  1462. priceUrls = new Array();
  1463. for (var i = 0; i < 15; i++)
  1464. {
  1465. var p = getCachePrice(app, isFoil, i);
  1466. var u = getCacheUrl(app, isFoil, i);
  1467. if (p != 0 && u != 0)
  1468. {
  1469. priceCards[i] = p;
  1470. priceUrls[i] = u;
  1471. }
  1472. else
  1473. {
  1474. break;
  1475. }
  1476. }
  1477. }
  1478.  
  1479. var texts = document.getElementsByClassName("badge_card_set_card");
  1480. var numCard = texts.length;
  1481. var priceSet = 0;
  1482. for (var j = 0; j < texts.length; j++)
  1483. {
  1484. var pUrl = priceUrls[j] ? urlMarket + priceUrls[j] : "";
  1485. var pCard = priceCards[j] ? priceCards[j] : "-";
  1486. var pOnClick = priceCards[j] ? "" : " onclick='return false;' ";
  1487. var pDiff = "";
  1488. var pCardOld = "";
  1489. var divTexts = texts[j].querySelectorAll("div.badge_card_set_text");
  1490. var divText = divTexts[divTexts.length - 1];
  1491. var divMarkets = texts[j].getElementsByClassName("div_market_price");
  1492. var divMarket;
  1493. if (divMarkets.length == 0)
  1494. {
  1495. divMarket = document.createElement("div");
  1496. divMarket.classList.add("div_market_price");
  1497. //divMarket.classList.add("badge_card_set_text_qty");
  1498. divText.appendChild(divMarket);
  1499. var divClear = document.createElement("div");
  1500. divClear.style.clear = "right";
  1501. divText.appendChild(divClear);
  1502. divText.style.whiteSpace = "normal";
  1503. }
  1504. else
  1505. {
  1506. divMarket = divMarkets[0];
  1507. var as = divMarket.getElementsByTagName("a");
  1508. if (as.length > 0)
  1509. {
  1510. var pOld = as[0].textContent;
  1511. var pValOld = pOld.match(pattNum);
  1512. if (pValOld != null)
  1513. {
  1514. //debug("oldPrice[" + j + "]: "+ pValOld);
  1515. pCardOld = "title='Cache Price: " + pOld + "'";
  1516. var pVal = pCard.match(pattNum);
  1517. pVal = pVal ? pVal : 0;
  1518. priceSet += parseFloat(pVal);
  1519. var pValDiff = (parseFloat(pVal) - parseFloat(pValOld)).toFixed(2);
  1520. if(pValDiff > 0)
  1521. {
  1522. pDiff = "<span style='cursor: help; color: " + colorUp + ";' "
  1523. + pCardOld + ">+" + pValDiff + "</span>";
  1524. }
  1525. else if (pValDiff < 0)
  1526. {
  1527. pDiff = "<span style='cursor: help; color: " + colorDown + ";' "
  1528. + pCardOld + ">" + pValDiff + "</span>";
  1529. }
  1530. else
  1531. {
  1532. pCardOld = "";
  1533. }
  1534. }
  1535. }
  1536. }
  1537.  
  1538. divMarket.innerHTML = pDiff + " <a href='" + pUrl + "' " + pOnClick + " title='Lowest Price'>" + pCard + "</a>";
  1539. } // end for
  1540. if (priceSet > 0)
  1541. {
  1542. debug("priceSet: " + priceSet);
  1543. }
  1544. }
  1545. }
  1546. function linkBadgeToMarketAttach()
  1547. {
  1548. var url = document.documentURI;
  1549. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  1550.  
  1551. if (patt.test(url) && !isErrorCard())
  1552. {
  1553. attachOnLoad(linkBadgeToMarket);
  1554. }
  1555. }
  1556. if (enableLinkBadgeToMarket) linkBadgeToMarketAttach();
  1557.  
  1558. /** Compare my cards and friend's cards in Badge page
  1559. * Mark color of my cards count (Green) and friend's cards count (Blue)
  1560. */
  1561. function compareBadge()
  1562. {
  1563. var url = document.documentURI;
  1564.  
  1565. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\//i;
  1566. var pattAppTail = /[^0-9]+.*/i;
  1567. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1568.  
  1569. {
  1570. try
  1571. {
  1572. var pattNumCard = /Card [0-9]+ of /i;
  1573. var pattMarket = /^http:\/\/steamcommunity.com\/market\/listings\/753\//i;
  1574. var pattPrice = /Price: /i;
  1575.  
  1576. var isFoil = url.indexOf("border=1") > -1;
  1577.  
  1578. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  1579. var isLoggedIn = aOwner != null;
  1580. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1581.  
  1582. var aFriend = document.querySelector(".profile_small_header_name > a");
  1583. var isFriendExist = aFriend != null;
  1584. var friendUrl = isFriendExist ? aFriend.href : "http://steamcommunity.com/my";
  1585. var friendName = isFriendExist ? aFriend.textContent.trim() : "my"
  1586. var friendNameOwner = isFriendExist ? friendName + "'s" : friendName;
  1587.  
  1588. var isOwner = isLoggedIn && ownerUrl == friendUrl;
  1589.  
  1590. //debug("ownerUrl: "+ownerUrl);
  1591. //debug("friendUrl: "+friendUrl);
  1592.  
  1593. var texts = document.getElementsByClassName("badge_card_set_card");
  1594. var numCard = texts.length;
  1595.  
  1596. //debug("isOwner: "+isOwner);
  1597. //debug("numCard: "+numCard);
  1598.  
  1599. for (var j = 0; j < numCard; j++)
  1600. {
  1601. var divQty = texts[j].querySelector("div.badge_card_set_text_qty");
  1602. var numQty = "(0)";
  1603. if (divQty != null)
  1604. {
  1605. numQty = divQty.textContent.trim();
  1606. }
  1607. else
  1608. {
  1609. divQty = document.createElement("div");
  1610. divQty.classList.add("badge_card_set_text_qty");
  1611. divQty.innerHTML = numQty;
  1612.  
  1613. var divCtn = texts[j].querySelector("div.game_card_ctn");
  1614. if (divCtn != null)
  1615. {
  1616. var divTexts = texts[j].querySelectorAll("div.badge_card_set_text");
  1617. if (divTexts.length < 2)
  1618. {
  1619. texts[j].insertBefore(divQty, divCtn.nextSibling);
  1620. }
  1621. else
  1622. {
  1623. divTexts[0].insertBefore(divQty, divTexts[0].firstChild);
  1624. }
  1625. }
  1626. }
  1627. //debug("numQty: "+numQty);
  1628. } // end for
  1629.  
  1630. var colorOwner = "#8CBE0F";
  1631. var colorFriend = "#5491CF";
  1632. var colorZeroOwner = "#557309";
  1633. var colorZeroFriend = "#355C82";
  1634. var countCardAll = 0;
  1635.  
  1636. var divQtys = document.querySelectorAll("div.badge_card_set_text_qty");
  1637. for (var k = 0; k < divQtys.length; k++)
  1638. {
  1639. var num = divQtys[k].textContent.trim().replace(/[\(\)]/gi, "");
  1640. countCardAll += parseInt(num);
  1641. divQtys[k].innerHTML = "";
  1642.  
  1643. var spanNum = document.createElement("span");
  1644. spanNum.classList.add("span_card_qty");
  1645. spanNum.style.cursor = "help";
  1646. spanNum.innerHTML = " (" + num + ") ";
  1647. divQtys[k].insertBefore(spanNum, null);
  1648.  
  1649. if (isOwner)
  1650. {
  1651. spanNum.classList.add("span_card_qty_owner");
  1652. spanNum.style.color = num > "0" ? colorOwner : colorZeroOwner;
  1653. spanNum.title = "My cards: " + num;
  1654. }
  1655. else
  1656. {
  1657. spanNum.classList.add("span_card_qty_friend");
  1658. spanNum.style.color = num > "0" ? colorFriend : colorZeroFriend;
  1659. spanNum.title = friendNameOwner + " cards: " + num;
  1660. }
  1661. }
  1662. debug("countCard: " + countCardAll);
  1663. debug("maxSet: " + parseInt(countCardAll / numCard));
  1664.  
  1665. if (!isOwner)
  1666. {
  1667. var pattProfile = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]*/i;
  1668. var urlExternal = url.replace(pattProfile, ownerUrl);
  1669. //debug("urlExternal: "+urlExternal);
  1670.  
  1671. setTimeout(function ()
  1672. {
  1673. GM_xmlhttpRequest({
  1674. method: "GET",
  1675. url: urlExternal,
  1676. onload: compareCard,
  1677. });
  1678. }, 0);
  1679.  
  1680. function compareCard(res)
  1681. {
  1682. var divTempID = randTempID();
  1683. createDivTemp(divTempID, res.responseText);
  1684. try
  1685. {
  1686. //debug("ID: "+divTempID);
  1687. var divTemp = document.getElementById(divTempID);
  1688.  
  1689. var owner_texts = divTemp.getElementsByClassName("badge_card_set_card");
  1690. var owner_numCard = owner_texts.length;
  1691.  
  1692. if (numCard == owner_numCard)
  1693. {
  1694. var owner_numQtys = new Array();
  1695.  
  1696. for (var i = 0; i < owner_texts.length; i++)
  1697. {
  1698. var owner_divQty = owner_texts[i].querySelector("div.badge_card_set_text_qty");
  1699. if (owner_divQty != null)
  1700. {
  1701. owner_numQtys[i] = owner_divQty.textContent.trim().replace(/[\(\)]/gi, "");
  1702. }
  1703. else
  1704. {
  1705. owner_numQtys[i] = "0";
  1706. }
  1707. //debug("owner_numQtys[i]: "+owner_numQtys[i]);
  1708. } // end for
  1709.  
  1710. var friend_divQtys = document.querySelectorAll("div.badge_card_set_text_qty");
  1711. for (var k = 0; k < friend_divQtys.length; k++)
  1712. {
  1713. var owner_spanNum = friend_divQtys[k].querySelector("span_card_qty_owner");
  1714. if (owner_spanNum == null)
  1715. {
  1716. owner_spanNum = document.createElement("span");
  1717. owner_spanNum.classList.add("span_card_qty");
  1718. owner_spanNum.style.cursor = "help";
  1719. owner_spanNum.classList.add("span_card_qty_owner");
  1720. owner_spanNum.style.color = owner_numQtys[k] > "0" ? colorOwner : colorZeroOwner;
  1721. owner_spanNum.title = "My cards: " + owner_numQtys[k];
  1722. friend_divQtys[k].insertBefore(owner_spanNum, friend_divQtys[k].firstChild);
  1723. }
  1724. owner_spanNum.innerHTML = " (" + owner_numQtys[k] + ") ";
  1725. }
  1726. }
  1727. }
  1728. catch (e)
  1729. {
  1730. debug("Ex: " + e);
  1731. }
  1732. removeDivTemp(divTempID);
  1733. debugTime("compareBadge");
  1734. }
  1735. }
  1736. }
  1737. catch (e)
  1738. {
  1739. debug("Ex: " + e);
  1740. }
  1741. }
  1742. // Add clickable card name
  1743. {
  1744. GM_addStyle(
  1745. " .sbh_cardName { color: #999; } "
  1746. );
  1747. var eleTexts = document.querySelectorAll(".badge_card_set_card");
  1748. for (var i = 0; i < eleTexts.length; i++)
  1749. {
  1750. var eleText = eleTexts[i].querySelector(".badge_card_set_text");
  1751. for (var j = 0; j < eleText.childNodes.length; j++)
  1752. {
  1753. if (eleText.childNodes[j].nodeName == "#text")
  1754. {
  1755. var text = eleText.childNodes[j].textContent.trim();
  1756. if (text != "")
  1757. {
  1758. var eleSpan = document.createElement("div");
  1759. eleSpan.classList.add("sbh_cardName");
  1760. eleSpan.textContent = text;
  1761. eleText.replaceChild(eleSpan, eleText.childNodes[j]);
  1762. eleSpan.addEventListener("click", function (e)
  1763. {
  1764. var ele = e.target;
  1765. clickToSelect(ele);
  1766. });
  1767. j = eleText.childNodes.length;
  1768. }
  1769. }
  1770. }
  1771. }
  1772. }
  1773. }
  1774. function compareBadgeAttach()
  1775. {
  1776. var url = document.documentURI;
  1777. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  1778.  
  1779. if (patt.test(url) && !isErrorCard())
  1780. {
  1781. attachOnLoad(compareBadge);
  1782. }
  1783. }
  1784. if (enableCompareBadge) compareBadgeAttach();
  1785.  
  1786. /** Link items in inventory to store and badge page
  1787. */
  1788. function linkInventoryToBadge()
  1789. {
  1790. if (isError())
  1791. return;
  1792. GM_addStyle
  1793. (
  1794. " .view_inventory_page .item.activeInfo "
  1795. + "{ background-image: none !important; background-color: #9B9B9B !important; border: 1px solid #C9C9C9; } "
  1796. + " .descriptor { max-height: 100px; overflow-y: auto; } "
  1797. + " .inventory_iteminfo .item_desc_content { padding-top: 225px !important; padding-bottom: 0px !important; }"
  1798. );
  1799. }
  1800. function linkInventoryToBadgeAttach()
  1801. {
  1802. var url = document.documentURI;
  1803. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/inventory/i;
  1804.  
  1805. if (patt.test(url))
  1806. {
  1807. attachOnLoad(linkInventoryToBadge);
  1808. }
  1809. }
  1810. if (enableLinkInventoryToBadge) linkInventoryToBadgeAttach();
  1811.  
  1812. function editTitle()
  1813. {
  1814. try
  1815. {
  1816. var titleOld = document.title;
  1817. var titleNew = titleOld;
  1818. var titleNoti = "";
  1819. var pattSale = /[0-9]+%/i;
  1820. var intervalTitle = null;
  1821. if (enableSwapTitle)
  1822. {
  1823. var splitSpace = titleOld.split(" ");
  1824. if (splitSpace.length > 1)
  1825. {
  1826. if (pattSale.test(splitSpace[1]))
  1827. {
  1828. splitSpace.splice(0, 1);
  1829. splitSpace.splice(1, 1);
  1830. titleOld = splitSpace.join(" ");
  1831. }
  1832. }
  1833. var split = titleOld.split("::").reverse();
  1834. for (var i = 0; i < split.length; i++)
  1835. {
  1836. split[i] = split[i].trim();
  1837. }
  1838. titleNew = split.join(" :: ");
  1839. document.title = titleNew;
  1840. }
  1841. var divH = document.querySelector("#header_notification_area");
  1842. if (divH != null)
  1843. {
  1844. divH.addEventListener('mouseover', function() {
  1845. clearInterval(intervalTitle);
  1846. document.title = titleNew;
  1847. });
  1848. }
  1849. if (enableShowTitleNoti)
  1850. {
  1851. function updateTitleNoti()
  1852. {
  1853. var noti = document.querySelector("#header_notification_link");
  1854. if (noti != null)
  1855. {
  1856. var notiNum = noti.textContent.trim();
  1857. if (notiNum != "" && notiNum != "0")
  1858. {
  1859. //debug("updateTitleNoti: "+notiNum);
  1860. titleNoti = "("+notiNum+") ";
  1861. }
  1862. else
  1863. {
  1864. titleNoti = "";
  1865. }
  1866. if (document.title != titleNoti + titleNew)
  1867. {
  1868. //debug("changeTitle: "+notiNum);
  1869. document.title = titleNoti + titleNew;
  1870. }
  1871. }
  1872. }
  1873. intervalTitle = setInterval(updateTitleNoti, 1000);
  1874. {
  1875. /*
  1876. var timeoutID = -1;
  1877. noti.addEventListener("DOMSubtreeModified", function (e) {
  1878. debug("DOMSubtreeModified");
  1879. try
  1880. {
  1881. clearTimeout(timeoutID);
  1882. }
  1883. catch (ex)
  1884. {
  1885. }
  1886. updateTitleNoti();
  1887. });
  1888. noti.addEventListener("DOMNodeInserted", function (e) {
  1889. debug("DOMNodeInserted");
  1890. try
  1891. {
  1892. clearTimeout(timeoutID);
  1893. }
  1894. catch (ex)
  1895. {
  1896. }
  1897. updateTitleNoti();
  1898. });
  1899. noti.addEventListener("DOMNodeRemoved", function (e) {
  1900. debug("DOMNodeRemoved");
  1901. timeoutID = setTimeout(updateTitleNoti,100);
  1902. });
  1903. */
  1904. }
  1905. }
  1906. }
  1907. catch (ex)
  1908. {
  1909. debug("editTitle: "+ex);
  1910. }
  1911. }
  1912. function editTitleAttach()
  1913. {
  1914. attachOnReady(editTitle);
  1915. }
  1916. if (enableSwapTitle || enableShowTitleNoti) editTitleAttach();
  1917.  
  1918. /** Resize trade window that is larger than 768px
  1919. */
  1920. function resizeTradeWindow()
  1921. {
  1922. if (window.innerHeight < 800)
  1923. {
  1924. GM_addStyle("#mainContent { transform: scale(0.8, 0.8); transform-origin: 50% 0px 0px; }");
  1925. if (window.innerWidth > 1000)
  1926. {
  1927. //window.resizeBy(-240,0);
  1928. //window.moveBy(200,0);
  1929. }
  1930. var ele = document.querySelector(".trade_partner_info_block");
  1931. if (ele != null)
  1932. {
  1933. ele.scrollIntoView();
  1934. }
  1935. }
  1936. }
  1937. function resizeTradeWindowTimeout(tm)
  1938. {
  1939. var url = document.documentURI;
  1940. var patt = /^http[s]?:\/\/steamcommunity.com\/(tradeoffer|trade)\//i;
  1941.  
  1942. if (patt.test(url))
  1943. {
  1944. setTimeout(resizeTradeWindow, tm);
  1945. }
  1946. }
  1947. if (enableResizeTradeWindow) resizeTradeWindowTimeout(0);
  1948. /** Add link in profile page
  1949. */
  1950. function linkProfile()
  1951. {
  1952. GM_addStyle(".achievement_progress_bar_ctn { width: 118px; margin-left: 4px; } ");
  1953. var url = document.documentURI;
  1954. var urlOwner = url;
  1955. if (urlOwner[urlOwner.length-1] != "/")
  1956. {
  1957. urlOwner = urlOwner + "/";
  1958. }
  1959. var urlName = urlOwner + "namehistory/";
  1960. var urlPost = urlOwner + "posthistory/";
  1961. var labelName = "Name History";
  1962. var labelPost = "Post History";
  1963. var arrUrl = ["", urlName, urlPost];
  1964. var arrLbl = ["", labelName, labelPost];
  1965. var divOuter = document.querySelector(".profile_item_links");
  1966. if (divOuter != null)
  1967. {
  1968. for (var i = 0; i < arrUrl.length; i++)
  1969. {
  1970. var div = document.createElement("div");
  1971. if (div != null)
  1972. {
  1973. div.className = "profile_count_link";
  1974. div.innerHTML = '<a href="' + arrUrl[i] + '"><span class="count_link_label">'
  1975. + arrLbl[i] + '</span> <span class="profile_count_link_total"> </span></a>';
  1976. divOuter.appendChild(div);
  1977. }
  1978. }
  1979. }
  1980. // preview bg in profile
  1981. function previewBg()
  1982. {
  1983. var bg = getQueryByName("previewbg");
  1984. if (bg != "")
  1985. {
  1986. var divBg = document.querySelector("div.has_profile_background");
  1987. if (divBg != null)
  1988. {
  1989. divBg.style.backgroundImage = "url('" + bg + "')";
  1990. }
  1991. var divBgIn = document.querySelector("div.profile_background_image_content");
  1992. if (divBgIn != null)
  1993. {
  1994. divBgIn.style.backgroundImage = "url('" + bg + "')";
  1995. }
  1996. }
  1997. }
  1998. attachOnLoad(previewBg);
  1999. }
  2000. function linkProfileReady()
  2001. {
  2002. var url = document.documentURI;
  2003. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+(\/?\?.*)?\/?$/i;
  2004. if (patt.test(url))
  2005. {
  2006. attachOnReady(linkProfile);
  2007. }
  2008. }
  2009. if (enableLinkProfile) linkProfileReady();
  2010. /** Set all checkbox to checked
  2011. */
  2012. function setAllCheckBox()
  2013. {
  2014. var ids = ["market_buynow_dialog_accept_ssa", "market_sell_dialog_accept_ssa", "accept_ssa", "verify_country_only"];
  2015. for (var i = 0; i < ids.length; i++)
  2016. {
  2017. var input = document.getElementById(ids[i]);
  2018. if (input != null)
  2019. {
  2020. input.checked = true;
  2021. }
  2022. }
  2023. }
  2024. function setAllCheckBoxReady()
  2025. {
  2026. var url = document.documentURI;
  2027. var pattMarket = /^http:\/\/steamcommunity.com\/market\/listings\/[0-9]+/i;
  2028. var pattInv = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/inventory/i;
  2029. var pattCart = /^http[s]?:\/\/store.steampowered.com\/checkout/i;
  2030. if (pattMarket.test(url) || pattInv.test(url) || pattCart.test(url))
  2031. {
  2032. attachOnReady(setAllCheckBox);
  2033. }
  2034. }
  2035. if (enableSetAllCheckBox) setAllCheckBoxReady();
  2036. /** Scroll store page to easy view
  2037. */
  2038. function storeFocus()
  2039. {
  2040. // Clean url in next queue
  2041. {
  2042. var eleQueue = document.querySelector("#next_in_queue_form");
  2043. if (eleQueue != null)
  2044. {
  2045. var action = eleQueue.getAttribute("action");
  2046. if (action[action.length] != "/")
  2047. {
  2048. action += "/";
  2049. eleQueue.setAttribute("action", action);
  2050. }
  2051. }
  2052. }
  2053. // Store focus
  2054. {
  2055. var eleAccount = document.querySelector("#account_pulldown");
  2056. if (eleAccount != null)
  2057. {
  2058. var divHead = document.querySelector(".breadcrumbs > .blockbg, "
  2059. + " .breadcrumbs > a, div.auction_block:nth-child(1), .market_listing_nav > a");
  2060. if (divHead != null)
  2061. {
  2062. divHead.scrollIntoView();
  2063. }
  2064. }
  2065. }
  2066. // Click to select app name
  2067. {
  2068. var eleName = document.querySelector(".apphub_AppName, .pageheader");
  2069. if (eleName != null)
  2070. {
  2071. eleName.addEventListener("click", function (e)
  2072. {
  2073. var ele = e.target;
  2074. clickToSelect(ele);
  2075. });
  2076. }
  2077. }
  2078. }
  2079. function storeFocusAttach()
  2080. {
  2081. var url = document.documentURI;
  2082. var patt = /^http[s]?:\/\/(store.steampowered.com\/(app|sub)\/|steamcommunity.com\/(auction\/item\/|sharedfiles\/filedetails\/\?id=|market\/listings\/))/i;
  2083. if (patt.test(url))
  2084. {
  2085. attachOnReady(storeFocus);
  2086. }
  2087. }
  2088. if (enableStoreFocus) storeFocusAttach();
  2089. function autoExploreQueue()
  2090. {
  2091. function autoQueue()
  2092. {
  2093. var tm = 3000;
  2094. debug("AutoQueue: In " + tm + "ms");
  2095. setTimeout(function ()
  2096. {
  2097. var eleCheck = document.querySelector("#sbh_autoQueue");
  2098. if (eleCheck != null && eleCheck.checked)
  2099. {
  2100. var ele = document.querySelector(".btn_next_in_queue");
  2101. if (ele != null)
  2102. {
  2103. ele.click();
  2104. }
  2105. }
  2106. else
  2107. {
  2108. debug("AutoQueue: Disabled");
  2109. }
  2110. }, tm);
  2111. }
  2112. var url = document.documentURI;
  2113. var pattApp = /^http[s]?:\/\/store.steampowered.com\/app/i;
  2114. var pattExplore = /^http[s]?:\/\/store.steampowered.com\/explore/i;
  2115. // Auto explore queue in app
  2116. if (pattApp.test(url))
  2117. {
  2118. GM_addStyle(
  2119. " .sbh_autoQueueOption { float: right; padding-right: 3px; } "
  2120. + " #sbh_autoQueue { vertical-align: text-top; } "
  2121. );
  2122. var eleDes = document.querySelector(".queue_controls_description");
  2123. if (eleDes != null)
  2124. {
  2125. var eleSpan = document.createElement("span");
  2126. eleSpan.classList.add("sbh_autoQueueOption");
  2127. var eleInput = document.createElement("input");
  2128. eleInput.id = "sbh_autoQueue";
  2129. eleInput.setAttribute("type", "checkbox");
  2130. eleInput.setAttribute("value", "auto");
  2131. if (GM_getValue("storeAutoQueue") == "true")
  2132. {
  2133. eleInput.checked = true;
  2134. var ele = document.querySelector(".btn_next_in_queue");
  2135. if (ele != null)
  2136. {
  2137. autoQueue();
  2138. }
  2139. }
  2140. eleInput.addEventListener("click", function (e)
  2141. {
  2142. var ele = e.target;
  2143. if (ele.checked)
  2144. {
  2145. GM_setValue("storeAutoQueue", "true");
  2146. autoQueue();
  2147. }
  2148. else
  2149. {
  2150. GM_setValue("storeAutoQueue", "false");
  2151. }
  2152. });
  2153. var eleLabel = document.createElement("label");
  2154. eleLabel.setAttribute("for", "sbh_autoQueue");
  2155. eleLabel.textContent = " Auto Explore Queue";
  2156. eleSpan.appendChild(eleInput);
  2157. eleSpan.appendChild(eleLabel);
  2158. eleDes.appendChild(eleSpan);
  2159. }
  2160. }
  2161. // Auto explore queue in explore
  2162. if (pattExplore.test(url))
  2163. {
  2164. if (GM_getValue("storeAutoQueue") == "true")
  2165. {
  2166. var eleText = document.querySelector(".subtext");
  2167. if (eleText != null && /[0-9]/.test(eleText.textContent.trim()))
  2168. {
  2169. setTimeout(function ()
  2170. {
  2171. var ele = document.querySelector("#refresh_queue_btn");
  2172. if (ele != null)
  2173. {
  2174. ele.click();
  2175. }
  2176. }, 3000);
  2177. }
  2178. }
  2179. }
  2180. }
  2181. function autoExploreQueueAttach()
  2182. {
  2183. var url = document.documentURI;
  2184. var patt = /^http[s]?:\/\/store.steampowered.com\/(app|explore)/i;
  2185. if (patt.test(url))
  2186. {
  2187. attachOnReady(autoExploreQueue);
  2188. }
  2189. }
  2190. if (enableAutoExploreQueue) autoExploreQueueAttach();
  2191. /** Hide queue in already owned in store page
  2192. */
  2193. function storeHideSection()
  2194. {
  2195. var divOwn = document.querySelector(".already_owned_actions");
  2196. if (divOwn != null)
  2197. {
  2198. GM_addStyle(
  2199. ".game_area_already_owned { margin-top: 10px !important; } "
  2200. + ".queue_ctn { display: none; } "
  2201. + "#review_container, .reviewPostedDescription, .review_box > .thumb { display: none; } "
  2202. + ".sbh_margin_left { margin-left: 5px; } "
  2203. + ".game_area_play_stats { min-height: 50px; } "
  2204. + "#review_container { margin-top: 30px; } "
  2205. );
  2206. var html = ""
  2207. html += ' <a class="btnv6_blue_hoverfade btn_medium right sbh_margin_left" onclick="'
  2208. + "var sbhQueue = document.querySelector('.queue_ctn');"
  2209. + "if (sbhQueue != null) { sbhQueue.style.display = 'inherit'; sbhQueue = null;} "
  2210. + "this.style.display = 'none'; return false;"
  2211. + '"><span>Show Follow</span></a> ';
  2212. var divReview = document.querySelector("#review_container, .reviewPostedDescription");
  2213. if (divReview != null)
  2214. {
  2215. html += ' <a class="btnv6_blue_hoverfade btn_medium right sbh_margin_left" onclick="'
  2216. + "var sbhReview = document.querySelector('#review_container, .reviewPostedDescription'); "
  2217. + "if (sbhReview != null) { sbhReview.style.display = 'inherit'; sbhReview = null; } "
  2218. + "var sbhReviewThumb = document.querySelector('.review_box > .thumb'); "
  2219. + "if (sbhReviewThumb != null) { sbhReviewThumb.style.display = 'inherit'; sbhReviewThumb = null; } "
  2220. + "this.style.display = 'none'; return false;"
  2221. + '"><span>Show Review</span></a> ';
  2222. }
  2223. divOwn.innerHTML += html;
  2224. }
  2225. }
  2226. function storeHideSectionReady()
  2227. {
  2228. var url = document.documentURI;
  2229. var patt = /^http[s]?:\/\/store.steampowered.com\/app\//i;
  2230. if (patt.test(url))
  2231. {
  2232. attachOnReady(storeHideSection);
  2233. }
  2234. }
  2235. if (enableStoreHideSection) storeHideSectionReady();
  2236. // ===== End Main =====
  2237.  
  2238. attachOnReady(function()
  2239. {
  2240. debugTime("ready");
  2241. });
  2242.  
  2243. attachOnLoad(function()
  2244. {
  2245. debugTime("load");
  2246. });
  2247. function testEvent()
  2248. {
  2249. /*document.addEventListener("DOMCharacterDataModified", function (e) {
  2250. debugTime("DOMCharacterDataModified");
  2251. });
  2252. document.querySelector("#header_notification_link").addEventListener("DOMSubtreeModified", function (e) {
  2253. debugTime("DOMSubtreeModified");
  2254. });*/
  2255. }
  2256. attachOnLoad(testEvent);
  2257. })();