Steam Badge Helper

Add various features to Steam focus on Trading Cards and Badges

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

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