Steam Badge Helper

Add various features to Steam focus on Trading Cards and Badges

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

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