Steam Badge Helper

Add various features to Steam focus on Trading Cards and Badges

  1. // ==UserScript==
  2. // @name Steam Badge Helper
  3. // @namespace iFantz7E.SteamBadgeHelper
  4. // @version 1.41
  5. // @description Add various features to Steam focus on Trading Cards and Badges
  6. // @match *://store.steampowered.com/*
  7. // @match *://steamcommunity.com/*
  8. // @match *://forums.steampowered.com/*
  9. // @match *://store.akamai.steampowered.com/*
  10. // @match *://store.steamgames.com/*
  11. // @run-at document-start
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // @grant GM_listValues
  15. // @grant GM_deleteValue
  16. // @grant GM_xmlhttpRequest
  17. // @grant GM_addStyle
  18. // @connect steamcommunity.com
  19. // @icon https://store.steampowered.com/favicon.ico
  20. // @copyright 2014, 7-elephant
  21. // ==/UserScript==
  22.  
  23. // http://userscripts.org/scripts/show/186163
  24. // https://greasyfork.org/en/scripts/5348-steam-badge-helper
  25.  
  26. (function ()
  27. {
  28. "use strict";
  29. // jshint multistr:true
  30. var timeStart = new Date();
  31.  
  32. // ===== Config =====
  33.  
  34. var enableDebug = false;
  35. var enableDebugConsole = true;
  36. var enableCleanLink = true;
  37. var enableGreenlightNoAutoplay = true;
  38. var enableMoveGreenlitHeader = true;
  39. var enableLinkBadgeToFriend = true;
  40. var enableLinkStoreToBadge = true;
  41. var enableLinkForumToBadge = true;
  42. var enableLinkBadgeToForum = true;
  43. var enableLinkMarketToBadge = true;
  44. var enableLinkBadgeToMarket = true;
  45. var enableLinkInventoryToBadge = true;
  46. var enableLinkProfile = true;
  47. var enableCompareBadge = true;
  48. var enableAlwaysClearCache = false;
  49. var enableCleanSteamMenu = true;
  50. var enableHideEnhancedBadgePrice = true;
  51. var enableAutoscrollSearch = true;
  52. var enableSwapTitle = true;
  53. var enableShowTitleNoti = false;
  54. var enableResizeTradeWindow = true;
  55. var enableMoveMenuEditProfile = true;
  56. var enableRefreshError = true;
  57. var enableSetAllCheckBox = true;
  58. var enableStoreFocus = true;
  59. var enableStoreHideSection = true;
  60. var enableAutoExploreQueue = true;
  61. var enableSkipAgeCheck = true;
  62. var enableSkipLinkFilter = true;
  63. var enableMoveSale = true;
  64. var enableRedirectToLogin = true;
  65. var enableCache = true;
  66. var enableDebugCache = false;
  67. var timeCacheExpireSec = 60;
  68.  
  69. var appCards = ["286120", "203990", "32200", "259720", "245550", "306410", "249610", "291130"
  70. , "218640", "268420", "46500", "102200", "301680", "273770", "264320", "339290", "340280"
  71. , "273830", "303850", "346200", "353980", "296070", "380770", "294190", "258200", "15700"
  72. , "92800", "267920", "257890", "314700", "448010", "94400", "390460", "269990", "383560"
  73. , "252490", "384150", "289690", "492340", "445170", "566270", "432990", "281990", "411590"
  74. , "425220"];
  75. var appCardMaps = {"202970": "202990", "234510": "35450"};
  76.  
  77. var appDlcs = // Exclude
  78. [
  79. "230889", "256576", "256611", "258643", "222606", "222615", "222618", "277751"
  80. ];
  81.  
  82. var marketCurrencies =
  83. {
  84. "USD": "1", "GBP": "2", "EUR": "3", "CHF": "4", "RUB": "5",
  85. "BRL": "7", "JPY": "8", "NOK": "9", "IDR": "10", "MYR": "11",
  86. "PHP": "12", "SGD": "13", "THB": "14", "KRW": "16", "TRY": "17",
  87. "MXN": "19", "CAD": "20", "NZD": "22", "CNY": "23", "INR": "24",
  88. "CLP": "25", "PEN": "26", "COP": "27", "ZAR": "28", "HKD": "29",
  89. "TWD": "30", "SAR": "31", "AED": "32",
  90. };
  91. var marketCountries =
  92. {
  93. "US": "1", "UK": "2", "BE": "3", "IT": "3", "CH": "4", "RU": "5", "AZ": "1",
  94. "BR": "7", "JP": "8", "NO": "9", "ID": "10", "MY": "11",
  95. "PH": "12", "SG": "13", "TH": "14", "KR": "16", "TR": "17",
  96. "MX": "19", "CA": "20", "NZ": "22", "CN": "23", "IN": "24",
  97. "CL": "25", "PE": "26", "CO": "27", "ZA": "28", "HK": "29",
  98. "TW": "30", "SA": "31", "AE": "32",
  99. };
  100. // ===== End Config =====
  101.  
  102. // ===== Cache =====
  103.  
  104. var tmpl_time = "badge_{APP}_time";
  105. var tmpl_price = "badge_{APP}_{SET}_{NUM}_price";
  106. var tmpl_url = "badge_{APP}_{SET}_{NUM}_url";
  107. var tmpl_owned = "badge_{APP}_{SET}_{NUM}_owned";
  108.  
  109. function clearCache()
  110. {
  111. var keep = ["counter"];
  112. var cache = GM_listValues();
  113. debug("clearCache: " + cache.length);
  114. for (var i = 0; i < cache.length; i++)
  115. {
  116. if (keep.indexOf(cache[i]) < 0)
  117. {
  118. GM_deleteValue(cache[i]);
  119. }
  120. }
  121. }
  122. if (enableAlwaysClearCache) clearCache();
  123.  
  124. function debugCache()
  125. {
  126. var cache = GM_listValues()
  127. if (enableDebugCache)
  128. {
  129. debug("debugCache: ");
  130. if (cache != null) for (var i = 0; i < cache.length; i++)
  131. {
  132. debug("-> " + cache[i] + ": " + GM_getValue(cache[i], 0));
  133. }
  134. }
  135. debug("debugCache: " + (cache == null ? 0 : cache.length));
  136. }
  137. setTimeout(debugCache, 0);
  138.  
  139. function generateCacheName(tmpl, app, isFoil, number)
  140. {
  141. var name = tmpl.replace("{APP}", app);
  142. if (isFoil != null)
  143. {
  144. var set = isFoil ? "F1" : "N1";
  145. name = name.replace("{SET}", set);
  146. }
  147. if (number != null)
  148. {
  149. name = name.replace("{NUM}", number);
  150. }
  151. return name;
  152. }
  153. function generateCacheNameTime(app)
  154. {
  155. return generateCacheName(tmpl_time, app);
  156. }
  157. function generateCacheNamePrice(app, isFoil, number)
  158. {
  159. return generateCacheName(tmpl_price, app, isFoil, number);
  160. }
  161. function generateCacheNameUrl(app, isFoil, number)
  162. {
  163. return generateCacheName(tmpl_url, app, isFoil, number);
  164. }
  165. function generateCacheNameOwned(app, isFoil, number)
  166. {
  167. return generateCacheName(tmpl_owned, app, isFoil, number);
  168. }
  169.  
  170. function getCacheTime(app)
  171. {
  172. var name = generateCacheNameTime(app);
  173. return GM_getValue(name, 0);
  174. }
  175. function getCacheTimeDiff(app)
  176. {
  177. return getUnixTimestamp() - getCacheTime(app);
  178. }
  179. function setCacheTime(app)
  180. {
  181. var name = generateCacheNameTime(app);
  182. GM_setValue(name, getUnixTimestamp());
  183. }
  184. function checkCacheExpire(app)
  185. {
  186. var cacheDiff = getCacheTimeDiff(app);
  187. var isCacheExpire = cacheDiff < 0 || cacheDiff > timeCacheExpireSec;
  188.  
  189. debug("cacheTimeDiff: " + cacheDiff + "s");
  190. debug("isCacheExpire: " + isCacheExpire);
  191.  
  192. return isCacheExpire;
  193. }
  194.  
  195. function getCachePrice(app, isFoil, number)
  196. {
  197. var name = generateCacheNamePrice(app, isFoil, number);
  198. return GM_getValue(name, 0);
  199. }
  200. function setCachePrice(app, isFoil, number, data)
  201. {
  202. var name = generateCacheNamePrice(app, isFoil, number);
  203. GM_setValue(name, data);
  204. }
  205.  
  206. function getCacheUrl(app, isFoil, number)
  207. {
  208. var name = generateCacheNameUrl(app, isFoil, number);
  209. return GM_getValue(name, 0);
  210. }
  211. function setCacheUrl(app, isFoil, number, data)
  212. {
  213. var name = generateCacheNameUrl(app, isFoil, number);
  214. GM_setValue(name, data);
  215. }
  216.  
  217. function getCacheOwned(app, isFoil, number)
  218. {
  219. var name = generateCacheNameOwned(app, isFoil, number);
  220. return GM_getValue(name, 0);
  221. }
  222. function setCacheOwned(app, isFoil, number, data)
  223. {
  224. var name = generateCacheNameOwned(app, isFoil, number);
  225. GM_setValue(name, data);
  226. }
  227.  
  228. // ===== End Cache =====
  229.  
  230. // ===== Helper =====
  231.  
  232. setTimeout(function ()
  233. {
  234. var counter = GM_getValue('counter', 0);
  235. GM_setValue('counter', ++counter);
  236. }, 0);
  237.  
  238. function debug(msg)
  239. {
  240. try
  241. {
  242. msg = msg ? (new String(msg)).trim().replace(/\s\s/gi, "").replace(/\s/gi, " ") : "";
  243.  
  244. if (enableDebugConsole)
  245. console.log(msg);
  246.  
  247. if (enableDebug)
  248. {
  249. var divDebugID = "div_debug_7e";
  250. var divDebugOuterID = divDebugID + "_outer";
  251. var divOut = document.getElementById(divDebugOuterID);
  252. var div = document.getElementById(divDebugID);
  253.  
  254. var isExistOuter = divOut != null;
  255. if (!isExistOuter)
  256. {
  257. divOut = document.createElement("div");
  258. divOut.id = divDebugOuterID;
  259. divOut.style = "font-family:'Courier New', Courier; font-size: 11px; z-index: 999999; padding: 3px; text-align: left;"
  260. + " border: 3px solid orange; color: black; background-color: rgba(255,255,255,0.9);"
  261. + " position: fixed; top: 3px; left: 3px; overflow-x:hidden; overflow-y:scroll; resize: both;";
  262. divOut.style.width = "150px";
  263. divOut.style.height = "100px";
  264.  
  265. if (div == null)
  266. {
  267. div = document.createElement("div");
  268. div.id = divDebugID;
  269. div.style.minWidth = "1000px";
  270. div.innerHTML = "<span style='font-weight: bold; line-height: 18px;'>Debug:</span>";
  271. }
  272. divOut.appendChild(div);
  273. document.body.appendChild(divOut);
  274. }
  275. div.innerHTML = div.innerHTML + " <br/> " + msg;
  276. divOut.scrollTop = divOut.scrollHeight;
  277. }
  278. }
  279. catch (e)
  280. {
  281. console.log("Ex: " + e);
  282. }
  283. }
  284.  
  285. function debugTime(header)
  286. {
  287. header = header ? (new String(header)) + ": " : "";
  288. var ms = (new Date()) - timeStart;
  289. debug(header + ms + "ms");
  290. }
  291. function getUnixTimestamp()
  292. {
  293. return parseInt((new Date()) / 1000);
  294. }
  295.  
  296. function randNum()
  297. {
  298. return parseInt(Math.random() * 900000 + 100000);
  299. }
  300.  
  301. function randTempID()
  302. {
  303. return "id_temp_7e_" + randNum();
  304. }
  305.  
  306. function createDivTemp(id, html)
  307. {
  308. var div = document.getElementById(id);
  309. if (div == null)
  310. {
  311. div = document.createElement("div");
  312. div.id = id;
  313. document.body.appendChild(div);
  314. }
  315. div.style.display = "none";
  316. div.style.zIndex = "-999999";
  317.  
  318. // remove all external sources
  319. var pattScript = /(<(script|meta|link|style|title)[^>]*>|<\/(script|meta|link|style|title)>)/gi;
  320. html = html.replace(pattScript, "");
  321.  
  322. // replace http to https
  323. //html = html.replace(/http:\/\//ig, "https://");
  324.  
  325. div.innerHTML = html;
  326. }
  327.  
  328. function removeDivTemp(id)
  329. {
  330. var ele = document.getElementById(id);
  331. ele.parentNode.removeChild(ele);
  332. }
  333.  
  334. function attachOnLoad(callback)
  335. {
  336. window.addEventListener("load", function (e) {
  337. callback();
  338. });
  339. }
  340.  
  341. function attachOnReady(callback)
  342. {
  343. document.addEventListener("DOMContentLoaded", function (e) {
  344. if (document.readyState === "interactive")
  345. {
  346. callback();
  347. }
  348. });
  349. }
  350.  
  351. function reload()
  352. {
  353. var curHref = window.location.href;
  354. var posHashtag = curHref.indexOf("#");
  355. if (posHashtag > -1)
  356. {
  357. window.location = curHref.substr(0, posHashtag);
  358. }
  359. else
  360. {
  361. window.location = curHref;
  362. }
  363. }
  364. function getCookie(c_name)
  365. {
  366. var c_value = document.cookie;
  367. var c_start = c_value.indexOf(" " + c_name + "=");
  368. if (c_start == -1) {
  369. c_start = c_value.indexOf(c_name + "=");
  370. }
  371. if (c_start == -1) {
  372. c_value = null;
  373. }
  374. else {
  375. c_start = c_value.indexOf("=", c_start) + 1;
  376. var c_end = c_value.indexOf(";", c_start);
  377. if (c_end == -1) {
  378. c_end = c_value.length;
  379. }
  380. c_value = unescape(c_value.substring(c_start, c_end));
  381. }
  382. return c_value;
  383. }
  384. var isVisible = (function()
  385. {
  386. var stateKey;
  387. var eventKey;
  388. var keys =
  389. {
  390. hidden: "visibilitychange",
  391. webkitHidden: "webkitvisibilitychange",
  392. mozHidden: "mozvisibilitychange",
  393. msHidden: "msvisibilitychange"
  394. };
  395. for (stateKey in keys)
  396. {
  397. if (stateKey in document)
  398. {
  399. eventKey = keys[stateKey];
  400. break;
  401. }
  402. }
  403. return function(c)
  404. {
  405. if (c)
  406. {
  407. document.addEventListener(eventKey, c);
  408. }
  409. return !document[stateKey];
  410. }
  411. })();
  412.  
  413. function isError()
  414. {
  415. var url = document.documentURI;
  416. var retVal =
  417. url.indexOf("/api") < 0
  418. && url.indexOf("api.") < 0
  419. && url.indexOf("/priceoverview") < 0
  420. && url.indexOf("/render") < 0
  421. && url.indexOf("/login/") < 0
  422. && url.indexOf("/widget/") < 0
  423. && url.indexOf("/actions/") < 0
  424. && url.indexOf("/dynamicstore/") < 0
  425. && url.indexOf("/search/suggest?") < 0
  426. && url.indexOf("/ajax") < 0
  427. && url.indexOf("/moderatormessages") < 0
  428. && url.indexOf("/itemordershistogram") < 0
  429. && url.indexOf("mobile") < 0
  430. && url.indexOf("/chat/") < 0
  431. && url.indexOf(".js") < 0
  432. && window === window.parent
  433. &&
  434. (
  435. (
  436. document.querySelector("body.headerless_page"
  437. + ", body.flat_page"
  438. + ", #main"
  439. + ", #supernav"
  440. + ", table.tborder"
  441. + ", #headerrow"
  442. + ", #global_header"
  443. + ", .page_header_ctn"
  444. + ", .search_page"
  445. + ", #bigpicture_about"
  446. + ", #ig_bottom"
  447. + ", #feedHeaderContainer"
  448. + ", img[alt='Steam']"
  449. + ", .waitforauth"
  450. + ", .no_header"
  451. + ", .mobileBody") == null
  452. )
  453. ||
  454. (
  455. document.querySelector(".profile_fatalerror_message"
  456. + ", #error_msg") != null
  457. //|| document.querySelector("#message") != null
  458. )
  459. );
  460. return retVal;
  461. }
  462. function isErrorBox()
  463. {
  464. var retVal = !!(document.querySelector("#error_box"));
  465. return retVal;
  466. }
  467.  
  468. function isErrorCard()
  469. {
  470. var retVal = document.querySelectorAll("#message > p.returnLink").length > 0;
  471. return retVal;
  472. }
  473.  
  474. function isErrorMarket()
  475. {
  476. var retVal = document.querySelectorAll("#searchResultsTable > .market_listing_table_message").length > 0
  477. ;//&& document.querySelector("#hover_content") == null);
  478. return retVal;
  479. }
  480.  
  481. function getQueryByName(name, url)
  482. {
  483. if (url == null)
  484. url = location.search;
  485. name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  486. var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
  487. var results = regex.exec(url);
  488. var retVal = "";
  489. if (results != null)
  490. {
  491. retVal = results[1].replace(/\+/g, " ");
  492. try
  493. {
  494. retVal = decodeURIComponent(retVal);
  495. }
  496. catch (ex)
  497. {
  498. }
  499. }
  500. return retVal;
  501. }
  502.  
  503. function insertBeforeElement(newNode, referenceNode)
  504. {
  505. referenceNode.parentNode.insertBefore(newNode, referenceNode);
  506. }
  507.  
  508. function insertAfterElement(newNode, referenceNode)
  509. {
  510. referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
  511. }
  512.  
  513. function clickToSelect(ele)
  514. {
  515. if (ele != null)
  516. {
  517. var range = document.createRange();
  518. range.setStartBefore(ele.firstChild);
  519. range.setEndAfter(ele.lastChild);
  520.  
  521. var sel = window.getSelection();
  522. sel.removeAllRanges();
  523. sel.addRange(range);
  524. }
  525. }
  526.  
  527. // ===== End Helper =====
  528.  
  529.  
  530. // ===== Cleaner =====
  531.  
  532. /** Auto refresh when error
  533. */
  534. function refreshError()
  535. {
  536. if(isError())
  537. {
  538. debug("refreshError: activated");
  539. setTimeout(reload, 5000);
  540. }
  541. }
  542. function refreshErrorCard()
  543. {
  544. if(isErrorCard())
  545. {
  546. debug("refreshErrorCard: activated");
  547. setTimeout(reload, 5000);
  548. }
  549. }
  550. function refreshErrorMarket()
  551. {
  552. if(isErrorMarket())
  553. {
  554. debug("refreshErrorMarket: activated");
  555. setTimeout(reload, 5000);
  556. }
  557. }
  558. function refreshErrorExplore()
  559. {
  560. if(isErrorBox())
  561. {
  562. debug("refreshErrorExplore: activated");
  563. setTimeout(reload, 1000);
  564. }
  565. }
  566. function refreshErrorTimeout(tm)
  567. {
  568. function refresh()
  569. {
  570. var url = document.documentURI;
  571. var pattCard = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  572. var pattTrade = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/tradeoffers\//i;
  573. var pattMarket = /^http[s]?:\/\/steamcommunity.com\/market\/listings\/[0-9]+/i;
  574. var pattExplore = /^http[s]?:\/\/store.steampowered.com\/\/?explore/i;
  575.  
  576. if (url.indexOf("#") < 0 && url.indexOf("json") < 0 && url.indexOf("xml") < 0)
  577. {
  578. setTimeout(refreshError, tm);
  579.  
  580. if (pattCard.test(url) || pattTrade.test(url))
  581. {
  582. setTimeout(refreshErrorCard, tm);
  583. }
  584. else if (pattMarket.test(url))
  585. {
  586. setTimeout(refreshErrorMarket, tm);
  587. }
  588. else if (pattExplore.test(url))
  589. {
  590. setTimeout(refreshErrorExplore, tm);
  591. }
  592. }
  593. }
  594. attachOnLoad(refresh);
  595. }
  596. if (enableRefreshError) refreshErrorTimeout(5000);
  597.  
  598. /** Remove unnessary parameters in URL
  599. */
  600. function cleanLink()
  601. {
  602. var url = document.documentURI;
  603. var pattApp = /^http[s]?:\/\/store.steampowered.com\/(app|sub|bundle)\/[0-9]+/i;
  604. var pattSale = /^http[s]?:\/\/store.steampowered.com\/sale\//i;
  605. var pattBadge = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  606. var pattFork = /^http[s]?:\/\/store\.(.+steampowered|steamgames)\.com\//i;
  607. var pattParam = /\/\?.*$/
  608. var pattParamCC = /\/\?cc\=.*$/
  609. var isSameSite = true;
  610. var urlNew = url;
  611.  
  612. if (pattApp.test(url))
  613. {
  614. var urlNews = url.match(pattApp);
  615. if (urlNews != null)
  616. {
  617. var urlTail = url.replace(pattApp, "");
  618.  
  619. if (urlTail == "")
  620. {
  621. urlNew = urlNews[0] + "/";
  622. }
  623. else if (urlTail != "/")
  624. {
  625. if (urlTail[0] === "?")
  626. {
  627. urlTail = "/" + urlTail;
  628. }
  629. if (!pattParamCC.test(urlTail) && pattParam.test(urlTail))
  630. {
  631. urlNew = urlNews[0] + "/";
  632. }
  633. }
  634. }
  635. }
  636. else if (pattSale.test(url))
  637. {
  638. var idxQuery = url.indexOf("?");
  639. if (idxQuery > 0)
  640. {
  641. urlNew = url.substr(0, idxQuery);
  642. }
  643. if (!urlNew.endsWith("/"))
  644. {
  645. urlNew += "/";
  646. }
  647. }
  648. else if (pattBadge.test(url))
  649. {
  650. var urlNews = url.match(pattBadge);
  651. if (urlNews != null)
  652. {
  653. var urlTail = url.replace(pattBadge, "");
  654.  
  655. if (urlTail.charAt(0) != "/")
  656. {
  657. urlNew = urlNews[0] + "/" + urlTail;
  658. }
  659. }
  660. }
  661. else if (pattFork.test(url))
  662. {
  663. urlNew = url.replace(pattFork, "http://store.steampowered.com/");
  664. isSameSite = false;
  665. }
  666.  
  667. if (urlNew != url)
  668. {
  669. debug("cleanLink: activated");
  670. if (isSameSite)
  671. {
  672. try
  673. {
  674. window.history.replaceState(null, null, urlNew);
  675. }
  676. catch (ex)
  677. {
  678. window.location.replace(urlNew);
  679. }
  680. }
  681. else
  682. {
  683. window.location.replace(urlNew);
  684. }
  685. }
  686. }
  687. function cleanLinkAttach()
  688. {
  689. attachOnReady(function()
  690. {
  691. cleanLink();
  692. });
  693. }
  694. if (enableCleanLink) cleanLinkAttach();
  695.  
  696. /** Change search parameter to page 1 to determine visited links
  697. */
  698. function cleanLinkSearch()
  699. {
  700. var pattSearch = /snr=1_7_7_230_150_[0-9]+/i
  701.  
  702. var as = document.querySelectorAll("a.search_result_row");
  703. for (var j = 0; j < as.length; j++)
  704. {
  705. var urlSearch = as[j].href;
  706. urlSearch = urlSearch.replace(pattSearch, "snr=1_7_7_230_150_1");
  707. as[j].href = urlSearch;
  708. }
  709.  
  710. document.addEventListener("DOMNodeInserted", onNodeInserted);
  711. function onNodeInserted(e)
  712. {
  713. try
  714. {
  715. var node = e.target;
  716. if (node.classList.contains("search_result_row"))
  717. {
  718. var urlSearch = node.href;
  719. urlSearch = urlSearch.replace(pattSearch, "snr=1_7_7_230_150_1");
  720. node.href = urlSearch;
  721. }
  722.  
  723. var count = document.querySelectorAll(".search_result_row").length;
  724. var divs = document.querySelectorAll(".search_pagination_left");
  725. for (var i = 0; i < divs.length; i++)
  726. {
  727. var oldVals = divs[i].innerHTML.match(/[0-9]+/g);
  728. var oldVal = oldVals[oldVals.length > 0 ? oldVals.length-1 : 0];
  729. divs[i].innerHTML = "showing " + count + " of " + oldVal;
  730. }
  731. }
  732. catch (ex)
  733. {
  734. }
  735. }
  736.  
  737. if (enableAutoscrollSearch)
  738. {
  739. var divButton = document.createElement("div");
  740. divButton.classList.add("btn_client_small");
  741. divButton.id = "divAutoscroll";
  742. divButton.style = "position: fixed; right: 20px; bottom: 20px; z-index:3;";
  743. 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>";
  744. document.body.appendChild(divButton);
  745. }
  746. }
  747. function cleanLinkSearchAttach(tm)
  748. {
  749. var url = document.documentURI;
  750. var patt = /^http[s]?:\/\/store.steampowered.com\/search\//i;
  751.  
  752. if (patt.test(url))
  753. {
  754. attachOnLoad(function()
  755. {
  756. setTimeout(cleanLinkSearch, tm);
  757. });
  758. }
  759. }
  760. if (enableCleanLink) cleanLinkSearchAttach(100);
  761.  
  762. /** Remove link lifter in URL
  763. */
  764. function cleanLinkLifter()
  765. {
  766. var url = document.documentURI;
  767. var patt = /^http[s]?:\/\/steamcommunity.com\//i;
  768. var pattHome = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/home/i;
  769.  
  770. function cleanLifter()
  771. {
  772. var lifter = "https://steamcommunity.com/linkfilter/";
  773. var lifterLen = lifter.length;
  774. var lifter2 = "?url=";
  775. var lifterLen2 = lifter2.length;
  776. var js = "javascript:"
  777. var jsLen = js.length;
  778.  
  779. var as = document.getElementsByTagName("a");
  780. for (var i = 0; i < as.length; i++)
  781. {
  782. var urlLink = as[i].href;
  783. if (urlLink.indexOf(lifter) == 0)
  784. {
  785. urlLink = urlLink.substr(lifterLen);
  786. if (urlLink.indexOf(lifter2) == 0)
  787. {
  788. urlLink = urlLink.substr(lifterLen2);
  789. }
  790. as[i].href = urlLink;
  791. }
  792. else if (patt.test(url) && urlLink.indexOf(js) == 0)
  793. {
  794. if (as[i].getAttribute('onclick') == null)
  795. {
  796. urlLink = decodeURIComponent(urlLink.substr(jsLen));
  797. as[i].setAttribute('onclick', urlLink + "; return false;");
  798. }
  799. }
  800. }
  801. }
  802.  
  803. var cleanLifterTimeoutId = 0;
  804.  
  805. function cleanLifterTimeout()
  806. {
  807. clearTimeout(cleanLifterTimeoutId);
  808. cleanLifterTimeoutId = setTimeout(cleanLifter, 1000);
  809. }
  810.  
  811. attachOnReady(cleanLifter);
  812.  
  813. if (pattHome.test(url))
  814. {
  815. document.addEventListener("DOMNodeInserted", cleanLifterTimeout);
  816. }
  817. }
  818. if (enableCleanLink) cleanLinkLifter();
  819.  
  820. /** Clean Steam's menu on top
  821. */
  822. function cleanSteamMenuTimeout(tm)
  823. {
  824. attachOnReady(function ()
  825. {
  826. GM_addStyle(
  827. // Steam header
  828. " .header_installsteam_btn_content , .header_installsteam_btn { display: none !important; } "
  829. // Enhanced Steam header
  830. + " #enhanced_pulldown, #es_menu { display: none !important; } "
  831. // SOE header
  832. + " #soe-t-menu { display: none !important; } "
  833. );
  834. setTimeout(function()
  835. {
  836. var eleSoe = document.querySelector("#soe-t-menu");
  837. if (eleSoe)
  838. {
  839. eleSoe.textContent = "SOE";
  840. var node = eleSoe.nextElementSibling.nextSibling;
  841. if (node.nodeName == "#text" && node.nodeValue.toString().trim() == "|")
  842. {
  843. node.parentElement.removeChild(node);
  844. }
  845. }
  846. var eleEs = document.querySelector("#enhanced_pulldown, #es_menu");
  847. if (eleEs != null)
  848. {
  849. var eleNoti = document.querySelector("#header_notification_area");
  850. if (eleNoti)
  851. {
  852. insertAfterElement(eleEs, eleNoti);
  853. }
  854. var eleEsPop = document.querySelector("#es_popup");
  855. if (eleEsPop)
  856. {
  857. insertAfterElement(eleEsPop.parentElement, eleEs);
  858. }
  859. }
  860.  
  861. var menu = document.querySelector("#account_pulldown");
  862. if (menu)
  863. {
  864. menu.addEventListener('mouseover', function() {
  865. var eleSoe = document.querySelector("#soe-t-menu");
  866. if (eleSoe)
  867. {
  868. eleSoe.style.setProperty("display", "inline-block", "important");
  869. }
  870. var eleEs = document.querySelector("#enhanced_pulldown, #es_menu");
  871. if (eleEs)
  872. {
  873. eleEs.style.setProperty("display", "inline-block", "important");
  874. }
  875. });
  876. }
  877. }, tm);
  878. });
  879.  
  880. }
  881. if (enableCleanSteamMenu) cleanSteamMenuTimeout(1000);
  882.  
  883. /** Hide EnhancedSteam's price on Badge page
  884. */
  885. function hideEnhancedBadgePrice()
  886. {
  887. GM_addStyle(".es_card_search, .es_item_action { display: none !important; } ");
  888. }
  889. function hideEnhancedBadgePriceTimeout(tm)
  890. {
  891. var url = document.documentURI;
  892. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/(gamecards\/[0-9]+|inventory)/i;
  893.  
  894. if (patt.test(url))
  895. {
  896. attachOnReady(function()
  897. {
  898. setTimeout(hideEnhancedBadgePrice, tm);
  899. });
  900. }
  901. }
  902. if (enableHideEnhancedBadgePrice) hideEnhancedBadgePriceTimeout(0);
  903.  
  904. // ===== End Cleaner =====
  905.  
  906. // ===== Main =====
  907.  
  908. /** Disable autoplay on Greenlight page while autoplay option is on
  909. */
  910. function disableGreenlightAutoplay()
  911. {
  912. var iframes = document.getElementsByTagName("iframe");
  913. for (var i in iframes)
  914. {
  915. if (iframes[i].className == "highlight_flash_player_notice")
  916. {
  917. iframes[i].src = iframes[i].src.replace("autoplay=1", "autoplay=0");
  918. }
  919. }
  920. }
  921. function disableGreenlightAutoplayTimeout(tm)
  922. {
  923. var url = document.documentURI;
  924. var patt = /^http[s]?:\/\/steamcommunity.com\/sharedfiles\/filedetails\//i;
  925.  
  926. if (patt.test(url))
  927. {
  928. attachOnLoad(function ()
  929. {
  930. setTimeout(disableGreenlightAutoplay, tm);
  931. });
  932. }
  933. }
  934. if (enableGreenlightNoAutoplay) disableGreenlightAutoplayTimeout(0);
  935.  
  936. /** Move Greenlit header to match voting section of Greenlight item
  937. */
  938. function moveGreenlitHeader()
  939. {
  940. var eleGreenlit = document.querySelector(".flag");
  941. if (eleGreenlit)
  942. {
  943. var eleArea = document.querySelector(".workshopItemPreviewArea");
  944. if (eleArea)
  945. {
  946. eleArea.appendChild(eleGreenlit.parentElement.parentElement);
  947. }
  948. }
  949. var eleWait = document.querySelector("#action_wait");
  950. if (eleWait)
  951. {
  952. var eleVote = document.querySelector("#voteNext");
  953. if (eleVote)
  954. {
  955. insertBeforeElement(eleWait, eleVote);
  956. eleWait.style.top = "6px";
  957. eleWait.style.position = "relative";
  958. }
  959. }
  960. }
  961. function moveGreenlitHeaderReady(tm)
  962. {
  963. var url = document.documentURI;
  964. var patt = /^http[s]?:\/\/steamcommunity.com\/sharedfiles\/filedetails\//i;
  965.  
  966. if (patt.test(url))
  967. {
  968. attachOnReady(function ()
  969. {
  970. moveGreenlitHeader();
  971. });
  972. }
  973. }
  974. if (enableMoveGreenlitHeader) moveGreenlitHeaderReady();
  975.  
  976. /** Move button in Edit Profile page to right
  977. */
  978. function moveMenuEditProfile()
  979. {
  980. GM_addStyle(
  981. ".group_content_bodytext { position: fixed; top: 400px; margin-left: 680px; line-height: 34px; z-index: 10; } "
  982. + ".rightcol { position: fixed; top: 230px; margin-left: 658px; z-index: 10; } "
  983. + ".saved_changes_msg { width: 610px; } "
  984. );
  985. }
  986. function moveMenuEditProfileTimeout(tm)
  987. {
  988. var url = document.documentURI;
  989. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/edit/i;
  990.  
  991. if (patt.test(url))
  992. {
  993. attachOnReady(function()
  994. {
  995. setTimeout(moveMenuEditProfile, tm);
  996. });
  997. }
  998. }
  999. if (enableMoveMenuEditProfile) moveMenuEditProfileTimeout(0);
  1000.  
  1001. /** Add small button on friend section in Badge page to view friends' Badge page for comparing cards
  1002. * Reduce height of Review textbox
  1003. */
  1004. function linkBadgeToFriend()
  1005. {
  1006. var url = document.documentURI;
  1007. var pattHead = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]*/i;
  1008. var urlTail = url.replace(pattHead, "");
  1009. //var pattProfile = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+[\/]?$/i;
  1010.  
  1011. // Correct style
  1012. {
  1013. var styleCorrect = "";
  1014.  
  1015. // fix long card name show incorrect column of cards
  1016. styleCorrect += ".badge_card_set_card .badge_card_set_text { max-width: 220px; } ";
  1017.  
  1018. // fix Firefox show incorrect column of friends' avatar
  1019. styleCorrect += ".persona { line-height: 16px; } ";
  1020.  
  1021. // fix EnhancedSteam show incorrect size of next badge progress
  1022. styleCorrect += ".gamecard_badge_progress .badge_info { width: 250px !important; } ";
  1023.  
  1024. // fix oversize friend action button
  1025. styleCorrect += ".badge_friendwithgamecard_actions .btn_medium { padding-bottom: 0px !important;"
  1026. + " width: 26px !important; text-align: center !important; } ";
  1027.  
  1028. // fix card name display over counter
  1029. styleCorrect += ".badge_card_set_text_qty { z-index: 2 !important; position: relative !important; } ";
  1030.  
  1031. // fix card drop counter is behind button and reposition
  1032. styleCorrect += ".badge_title_stats_content { margin-top: -4px; } ";
  1033. if (document.querySelector(".badge_title_playgame") != null)
  1034. {
  1035. styleCorrect += ".badge_title_stats_content { padding-right: 45px; } ";
  1036. }
  1037.  
  1038. GM_addStyle(styleCorrect);
  1039. }
  1040.  
  1041. // Link to friends
  1042. {
  1043. var imgCard = "<img style='height:16px; opacity:0.72'"
  1044. + " src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAAgCAYAAABdP1tmAAAAGXRF"
  1045. + "WHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAA"
  1046. + "ADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4Onht"
  1047. + "cG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1j"
  1048. + "MDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6"
  1049. + "cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNj"
  1050. + "cmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEu"
  1051. + "MC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3Vy"
  1052. + "Y2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdp"
  1053. + "bmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpCOUQ2NEUyQkU4MUZFMzExQUEyMkQ1MDNCQkRFRjU0RCIgeG1w"
  1054. + "TU06RG9jdW1lbnRJRD0ieG1wLmRpZDo5REYxOTJDOTIyM0MxMUUzODY5NTlGQjMwODBFMkI0MyIgeG1w"
  1055. + "TU06SW5zdGFuY2VJRD0ieG1wLmlpZDo5REYxOTJDODIyM0MxMUUzODY5NTlGQjMwODBFMkI0MyIgeG1w"
  1056. + "OkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZy"
  1057. + "b20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3QTQwRjJENkNDMjBFMzExQUEyMkQ1MDNCQkRFRjU0"
  1058. + "RCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpCOUQ2NEUyQkU4MUZFMzExQUEyMkQ1MDNCQkRFRjU0"
  1059. + "RCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVu"
  1060. + "ZD0iciI/PviNBbAAAAD6SURBVHjaYvz//z/DcAIslBowY8YMivRnZGRQ1UNMDMMMMJKS5ICxsRdIOdHA"
  1061. + "HceBMWVFVw8BPcMPpD7QMHAFgJ76OFB56B8Qf6KCJ7iAmG0wFArPgKEpS4XCYzEQxwyqUo5CwIvE/kCg"
  1062. + "xLwDxBrAgPw7mEs5UpKtChDzDJoYwlbfoMUIzkIBqI7oonjY1UOjHhr10KiHRj006qFRD416aNRDg7e1"
  1063. + "zUBCa5vmHTx8/Rxiwc/BEkNCQI9MpoL9toPFQ6B+Sc5ooUAZAPVYvwylQoEqoz4juh76O6w8BEwOoPS7"
  1064. + "nkbuWEON5AYCjJTOPgy2wXrG4TadAhBgANX8SbJBOSc0AAAAAElFTkSuQmCC'></a> ";
  1065. var els = document.querySelectorAll(".badge_friends_have_earned_friends, .badge_friendwithgamecard");
  1066. for (var i = 0; i < els.length; i++)
  1067. {
  1068. var as = els[i].querySelectorAll(".playerAvatar a, a.persona");
  1069. var limit = 1;
  1070. var curLimit = 0;
  1071.  
  1072. for (var j = 0; j < as.length; j++)
  1073. {
  1074. var a = as[j];
  1075. //if (pattProfile.test(a.href))
  1076. {
  1077. var badgeUrl = a.href + urlTail;
  1078.  
  1079. if (els[i].classList.contains("badge_friends_have_earned_friends")
  1080. || !a.parentNode.classList.contains("playerAvatar"))
  1081. {
  1082. a.href = badgeUrl;
  1083. }
  1084.  
  1085. if (curLimit < limit && els[i].classList.contains("badge_friendwithgamecard"))
  1086. {
  1087. var elActs = els[i].getElementsByClassName("badge_friendwithgamecard_actions");
  1088. if (elActs)
  1089. {
  1090. for (var k = 0; k < elActs.length; k++)
  1091. {
  1092. var eleA = document.createElement("a");
  1093. eleA.classList.add("btn_grey_grey");
  1094. eleA.classList.add("btn_medium");
  1095. eleA.setAttribute("title", "View friend's badge");
  1096. eleA.setAttribute("href", badgeUrl);
  1097. eleA.innerHTML = imgCard;
  1098.  
  1099. elActs[k].appendChild(eleA);
  1100.  
  1101. curLimit += 1;
  1102. } // end for k
  1103. }
  1104. }
  1105. }
  1106. } // end for j
  1107. } // end for i
  1108. }
  1109.  
  1110. // Sort friends
  1111. {
  1112. setTimeout(function()
  1113. {
  1114. var eleSections = document.querySelectorAll(".badge_friendswithgamecards_section");
  1115. for (var i = 0; i < eleSections.length; i++)
  1116. {
  1117. var keyArr = new Array();
  1118. var valArr = new Array();
  1119.  
  1120. var eleFriends = eleSections[i].querySelectorAll(".badge_friendwithgamecard");
  1121. for (var j = 0; j < eleFriends.length; j++)
  1122. {
  1123. var elePersona = eleFriends[j].querySelector(".persona");
  1124. if (elePersona != null)
  1125. {
  1126. var key = "";
  1127.  
  1128. if (elePersona.classList.contains("in-game"))
  1129. {
  1130. key = "01";
  1131. }
  1132. else if (elePersona.classList.contains("online"))
  1133. {
  1134. key = "02";
  1135. }
  1136. else
  1137. {
  1138. key = "03";
  1139. }
  1140.  
  1141. var key = key + "___" + elePersona.textContent.trim().toLowerCase()
  1142. + "___" + elePersona.getAttribute("data-miniprofile");
  1143. keyArr.push(key);
  1144. valArr[key] = eleFriends[j];
  1145. eleSections[i].removeChild(eleFriends[j]);
  1146. }
  1147. } // end for j
  1148.  
  1149. keyArr.sort();
  1150.  
  1151. for (var j = keyArr.length - 1; j > -1 ; j--)
  1152. {
  1153. eleSections[i].insertBefore(valArr[keyArr[j]], eleSections[i].firstChild);
  1154. } // end for j
  1155.  
  1156. } // end for i
  1157. }, 100);
  1158. }
  1159. }
  1160. function linkBadgeToFriendAttach()
  1161. {
  1162. var url = document.documentURI;
  1163. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  1164.  
  1165. if (patt.test(url) && !isErrorCard())
  1166. {
  1167. attachOnLoad(linkBadgeToFriend);
  1168. }
  1169. }
  1170. if (enableLinkBadgeToFriend) linkBadgeToFriendAttach();
  1171.  
  1172. /** Add button on top of Store page to view Badge page
  1173. */
  1174. function linkStoreToBadge()
  1175. {
  1176. var url = document.documentURI;
  1177. var patt = /^http[s]?:\/\/store.steampowered.com\/app\//i;
  1178. var pattEnd = /[^0-9].*$/i;
  1179. var app = url.replace(patt, "").replace(pattEnd, "");
  1180.  
  1181. var aOwner = document.querySelector("#global_actions > .user_avatar");
  1182. var isLoggedIn = aOwner != null;
  1183. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1184. var isOwned = document.querySelector(".game_area_already_owned") != null;
  1185.  
  1186. var urlCard = "category2=29";
  1187. var titleCard = "Steam Trading Cards";
  1188. var urlDlc = "category1=21";
  1189. var titleDlc = "Downloadable Content";
  1190. var urlAch = "category2=22";
  1191. var titleAch = "Steam Achievement";
  1192.  
  1193. var isBadge = false;
  1194. var isBadgeMap = false;
  1195. var isAch = false;
  1196.  
  1197. var cookieCountry = getCookie("steamCountry");
  1198. if (cookieCountry)
  1199. {
  1200. GM_setValue("storeCountry", cookieCountry.substr(0, 2));
  1201. }
  1202. var as = document.querySelectorAll(".game_area_details_specs a");
  1203. for (var i = 0; i < as.length; i++)
  1204. {
  1205. if (appDlcs.indexOf(app) > -1 || as[i].href.indexOf(urlDlc) > -1 || as[i].textContent == titleDlc)
  1206. {
  1207. isBadge = false;
  1208. isAch = false;
  1209. break;
  1210. }
  1211. else if (as[i].href.indexOf(urlCard) > -1 || as[i].textContent == titleCard)
  1212. {
  1213. isBadge = true;
  1214. }
  1215. else if (as[i].href.indexOf(urlAch) > -1 || as[i].textContent == titleAch)
  1216. {
  1217. isAch = true;
  1218. }
  1219. }
  1220.  
  1221. if (appCardMaps[app] != null)
  1222. {
  1223. isBadge = true;
  1224. isBadgeMap = true;
  1225. }
  1226. else if (!isBadge)
  1227. {
  1228. if (appCards.indexOf(app) > -1)
  1229. {
  1230. isBadge = true;
  1231. }
  1232. }
  1233.  
  1234. if (isBadge)
  1235. {
  1236. var appCard = app;
  1237. if (isBadgeMap)
  1238. {
  1239. appCard = appCardMaps[app];
  1240. }
  1241.  
  1242. var divs = document.getElementsByClassName("apphub_OtherSiteInfo");
  1243. for (var i = 0; i < divs.length; i++)
  1244. {
  1245. divs[i].innerHTML = divs[i].innerHTML
  1246. + " &nbsp;<a class=\"btnv6_blue_hoverfade btn_medium\""
  1247. + " href=\"" + ownerUrl + "/gamecards/" + appCard + "/\">"
  1248. + "<span>Trading Cards</span></a>";
  1249. }
  1250. }
  1251.  
  1252. if (false && isAch)
  1253. {
  1254. var urlAchLink = (isLoggedIn && isOwned ? ownerUrl + "/stats/appid/" : "http://steamcommunity.com/stats/")
  1255. + app + "/achievements/";
  1256.  
  1257. var divCommu = document.querySelector(".communitylink .block_content_inner");
  1258. if (divCommu != null)
  1259. {
  1260. var aAch = ' <a class="linkbar" href="' + urlAchLink + '">'
  1261. + '<div class="rightblock" style="margin-top: 3px;"><img src="http://cdn4.store.steampowered.com/public/images/ico/ico_achievements.png"'
  1262. + ' align="top" border="0" style="margin-right: -9px; height: 20px; margin-top: -5px;"></div>'
  1263. + 'View Steam Achievements</a>';
  1264. divCommu.innerHTML = divCommu.innerHTML + aAch;
  1265. }
  1266.  
  1267. /*var divDemo = document.querySelector("#demo_block > div");
  1268. if (divDemo != null)
  1269. {
  1270. var divAch = '<div class="demo_area_button"><a class="game_area_wishlist_btn" href="'
  1271. + urlAchLink + '">View Steam Achievements</a></div>';
  1272.  
  1273. divDemo.innerHTML = divAch + divDemo.innerHTML;
  1274. }*/
  1275. }
  1276.  
  1277. var txtRec = document.getElementById("game_recommendation");
  1278. if (txtRec != null)
  1279. {
  1280. // reduce height of review textbox
  1281. txtRec.style.height = "16px";
  1282. txtRec.onfocus = function(){txtRec.style.height="150px";};
  1283. }
  1284.  
  1285. // Move early access zone
  1286. {
  1287. var eleEa = document.querySelector(".early_access_header");
  1288. if (eleEa != null)
  1289. {
  1290. var elePurchase = document.querySelector("#game_area_purchase");
  1291. if (elePurchase != null)
  1292. {
  1293. insertAfterElement(eleEa, elePurchase);
  1294. }
  1295. }
  1296. }
  1297.  
  1298. // Move language zone
  1299. {
  1300. var eleNote = document.querySelector("#purchase_note > .notice_box_content > b");
  1301. if (eleNote != null)
  1302. {
  1303. var elePurchase = document.querySelector("#game_area_purchase");
  1304. if (elePurchase != null)
  1305. {
  1306. /*var elesGame = elePurchase.querySelectorAll(".game_area_purchase_game_wrapper");
  1307. if (elesGame.length > 0)
  1308. {
  1309. insertAfterElement(eleNote.parentElement.parentElement, elesGame[elesGame.length - 1]);
  1310. }
  1311. else*/
  1312. {
  1313. if (elePurchase.lastElementChild.classList.contains("game_area_dlc_section"))
  1314. {
  1315. eleNote.parentElement.parentElement.style.marginTop = "60px";
  1316. }
  1317. insertAfterElement(eleNote.parentElement.parentElement, elePurchase.lastElementChild);
  1318. }
  1319. }
  1320. }
  1321. }
  1322.  
  1323. // Redirect Steam run
  1324. {
  1325. var eleCart = document.querySelector(".btn_addtocart a");
  1326. if (eleCart)
  1327. {
  1328. if (eleCart.href.indexOf("ShowGotSteamModal") > -1)
  1329. {
  1330. eleCart.href = eleCart.href.replace("javascript:ShowGotSteamModal('", "")
  1331. .replace(/\',.*$/i, "").replace("steam://run", "steam://install");
  1332. }
  1333. else if (eleCart.href.indexOf("steam://run") === 0)
  1334. {
  1335. eleCart.href = eleCart.href.replace("steam://run", "steam://install");
  1336. }
  1337. }
  1338. }
  1339.  
  1340. if (!isLoggedIn)
  1341. {
  1342. var eleLoginMain = document.querySelector("a.global_action_link[href*='/login/']");
  1343. var eleLoginQueue = document.querySelector(".queue_actions_ctn a[href*='/login/']");
  1344. if (eleLoginMain != null && eleLoginQueue != null)
  1345. {
  1346. eleLoginMain.setAttribute("href", eleLoginQueue.getAttribute("href"));
  1347. }
  1348. }
  1349. }
  1350. function linkStoreToBadgeAttach(tm)
  1351. {
  1352. var url = document.documentURI;
  1353. var patt = /^http[s]?:\/\/store.steampowered.com\/(app|sub)\//i;
  1354.  
  1355. if (patt.test(url))
  1356. {
  1357. attachOnReady(function()
  1358. {
  1359. setTimeout(linkStoreToBadge, tm);
  1360. });
  1361. }
  1362. }
  1363. if (enableLinkStoreToBadge) linkStoreToBadgeAttach(1000);
  1364.  
  1365. /** Add button in Forum page to view Badge page
  1366. * Mark topic to determine visited links
  1367. */
  1368. function linkForumToBadge()
  1369. {
  1370. var url = document.documentURI;
  1371. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/app\//i;
  1372. var pattAppTail = /[^0-9]+.*/i;
  1373. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1374.  
  1375. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  1376. var isLoggedIn = aOwner != null;
  1377. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1378.  
  1379. var divs = document.getElementsByClassName("apphub_OtherSiteInfo");
  1380. for (var j = 0; j < divs.length; j++)
  1381. {
  1382. var aBadge = " <a class='btn_darkblue_white_innerfade btn_medium' href='"
  1383. + ownerUrl + "/gamecards/" + app
  1384. + "/'><span>Trading Cards</span></a> ";
  1385. divs[j].innerHTML = divs[j].innerHTML + aBadge;
  1386. }
  1387.  
  1388. function markTopic()
  1389. {
  1390. var as = document.getElementsByClassName("forum_topic_overlay");
  1391. for (var i = 0; i < as.length; i++)
  1392. {
  1393. // mark topic
  1394. as[i].style.borderLeft = "3px solid";
  1395. }
  1396. }
  1397. markTopic();
  1398. document.addEventListener("DOMNodeInserted", markTopic);
  1399. }
  1400. function linkForumToBadgeTimeout(tm)
  1401. {
  1402. var url = document.documentURI;
  1403. var patt = /^http[s]?:\/\/steamcommunity.com\/app\/[0-9]+\/tradingforum\//i;
  1404.  
  1405. if (patt.test(url))
  1406. {
  1407. setTimeout(linkForumToBadge, tm);
  1408. }
  1409. }
  1410. if (enableLinkForumToBadge) linkForumToBadgeTimeout(100);
  1411.  
  1412. /** Add buttons in Badge page to view Trading Forum, Store, friend's Inventory and my Badge page
  1413. */
  1414. function linkBadgeToForum()
  1415. {
  1416. var url = document.documentURI;
  1417.  
  1418. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\//i;
  1419. var pattAppTail = /[^0-9]+.*/i;
  1420. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1421.  
  1422. GM_addStyle
  1423. (
  1424. " .sbh_badge_menu_right { float: right; margin-left: 5px; } "
  1425. + " .badge_card_to_collect_links a[href$='/tradingforum/'], .es_visit_tforum { display: none; } "
  1426. );
  1427.  
  1428. var divs = document.getElementsByClassName("gamecards_inventorylink");
  1429. if (divs.length > 0)
  1430. {
  1431. var aStoreUrl = "http://store.steampowered.com/app/" + app + "/";
  1432. var aForumUrl = "http://steamcommunity.com/app/" + app + "/tradingforum/";
  1433. var aCustom = " <a class='btn_grey_grey btn_small_thin sbh_badge_menu_right' href='" + aStoreUrl + "'>"
  1434. + " <span>Visit Store Page</span></a> "
  1435. + " <a class='btn_grey_grey btn_small_thin sbh_badge_menu_right' href='" + aForumUrl + "'>"
  1436. + " <span>Visit Trade Forum</span></a> ";
  1437.  
  1438. divs[0].innerHTML = divs[0].innerHTML + aCustom;
  1439. }
  1440.  
  1441. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  1442. var isLoggedIn = aOwner != null;
  1443. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1444.  
  1445. var aFriend = document.querySelector(".profile_small_header_name > a");
  1446. var isFriendExist = aFriend != null;
  1447. var friendUrl = isFriendExist ? aFriend.href : "http://steamcommunity.com/my";
  1448. var friendName = isFriendExist ? aFriend.textContent.trim() : "my"
  1449. var friendNameOwner = isFriendExist ? friendName + "'s" : friendName;
  1450.  
  1451. var isOwner = isLoggedIn && ownerUrl == friendUrl;
  1452.  
  1453. if (!isOwner)
  1454. {
  1455. var divInv;
  1456. if (divs.length > 0)
  1457. {
  1458. divInv = divs[0];
  1459. }
  1460. else
  1461. {
  1462. divInv = document.createElement("div");
  1463. divInv.classList.add("gamecards_inventorylink");
  1464. var divBadge = document.querySelector(".badge_detail_tasks");
  1465. if (divBadge != null)
  1466. {
  1467. divBadge.insertBefore(divInv, divBadge.firstChild);
  1468. }
  1469. }
  1470. var aFrInvUrl = friendUrl + "/inventory/#753_6";
  1471. var aOwnUrl = url.replace(pattAppHead, ownerUrl + "/gamecards/");
  1472. divInv.innerHTML = divInv.innerHTML
  1473. + "<a class='btn_grey_grey btn_small_thin' href='" + aFrInvUrl + "'><span>View cards in "
  1474. + friendNameOwner + " Inventory</span></a> "
  1475. + " <a class='btn_grey_grey btn_small_thin' href='" + aOwnUrl + "'><span>View my Progress</span></a> ";
  1476.  
  1477. }
  1478. }
  1479. function linkBadgeToForumAttach()
  1480. {
  1481. var url = document.documentURI;
  1482. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  1483.  
  1484. if (patt.test(url) && !isErrorCard())
  1485. {
  1486. attachOnLoad(linkBadgeToForum);
  1487. }
  1488. }
  1489. if (enableLinkBadgeToForum) linkBadgeToForumAttach();
  1490.  
  1491. /** Add button in Market page to view Badge and Store page
  1492. */
  1493. function linkMarketToBadge()
  1494. {
  1495. var url = document.documentURI;
  1496.  
  1497. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/market\/listings\/753\//i;
  1498. var pattAppTail = /[^0-9]+.*/i;
  1499. var pattNumber = /[0-9]+/;
  1500. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1501.  
  1502. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  1503. var isLoggedIn = aOwner != null;
  1504. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1505.  
  1506. GM_addStyle(
  1507. "#market_buynow_dialog_purchase > span:nth-child(1) { line-height: 80px; padding: 0px 50px 0px 50px !important; } "
  1508. + "#market_buynow_dialog { width: 850px; } "
  1509. + ".market_listing_table_header { margin: 0px; } "
  1510. + ".market_listing_row { margin-top: 2px; } "
  1511. + ".market_listing_row > .market_listing_es_lowest:nth-child(3) { visibility: hidden; } "
  1512. + ".market_listing_row > .market_listing_es_lowest:nth-child(8) { display: none; } "
  1513. + ".es_market_lowest_button { display: none; } "
  1514. );
  1515.  
  1516. var div_tabL = document.querySelectorAll("div.market_large_tab_well");
  1517. for (var i = 0; i < div_tabL.length; i++)
  1518. {
  1519. // reduce height of header
  1520. div_tabL[i].style.height = "50px";
  1521. }
  1522. var div_tabLB = document.querySelectorAll("div.market_large_tab_well_gradient");
  1523. for (var i = 0; i < div_tabLB.length; i++)
  1524. {
  1525. div_tabLB[i].style.height = "65px";
  1526. }
  1527.  
  1528. var div_store = document.getElementById("largeiteminfo_game_name");
  1529.  
  1530. if (div_store != null)
  1531. {
  1532. div_store.innerHTML = "<a href='http://store.steampowered.com/app/" + app + "/'>"
  1533. + div_store.innerHTML + "</a>";
  1534. }
  1535.  
  1536. var isFoil = false;
  1537. var ele_name = document.getElementById("largeiteminfo_item_name");
  1538. if (ele_name != null)
  1539. {
  1540. isFoil = (ele_name.innerHTML.search("Foil") > -1);
  1541. ele_name.innerHTML = "<a href='" + ownerUrl + "/gamecards/" + app
  1542. + (isFoil ? "/?border=1" : "/") + "'>" + ele_name.innerHTML + "</a>";
  1543. }
  1544.  
  1545. var ele_icon = document.getElementsByClassName("item_desc_game_icon");
  1546. for (var i = 0; i < ele_icon.length; i++)
  1547. {
  1548. ele_icon[i].innerHTML = "<a href='http://store.steampowered.com/app/" + app + "/'>"
  1549. + ele_icon[i].innerHTML + "</a>";
  1550. }
  1551.  
  1552. var div_nav = document.getElementsByClassName("market_large_tab_well");
  1553. for (var j = 0; j < div_nav.length; j++)
  1554. {
  1555. var aBadge = ' <div class="apphub_OtherSiteInfo" '
  1556. + 'style="position: relative; float: right; right: 2px; top: 2px;"> '
  1557. + '<a style="position: relative; z-index: 1;" class="btn_darkblue_white_innerfade btn_medium" '
  1558. + 'href="#" onclick="document.getElementById(\'pricehistory\').style.display = \'inherit\'; '
  1559. + 'document.querySelector(\'.pricehistory_zoom_controls\').style.display = \'inherit\'; return false; " >'
  1560. + '<span>Show History</span></a> &nbsp;'
  1561. + '<a style="position: relative; z-index: 1;" class="btn_darkblue_white_innerfade btn_medium" '
  1562. + 'href="http://store.steampowered.com/app/' + app + '"><span>Store Page</span></a> &nbsp;'
  1563. + '<a class="btn_darkblue_white_innerfade btn_medium" '
  1564. + 'href="' + ownerUrl + '/gamecards/' + app + (isFoil ? "/?border=1" : "/")
  1565. + '"><span>Trading Cards</span></a></div>';
  1566. div_nav[j].innerHTML = div_nav[j].innerHTML + aBadge;
  1567. GM_addStyle(
  1568. "#pricehistory, .pricehistory_zoom_controls { display: none } "
  1569. );
  1570. }
  1571.  
  1572. var span_list = document.querySelectorAll("div.market_listing_row > div:nth-child(3) > span:nth-child(1) > span:nth-child(1)");
  1573. for (var i = 0; i < span_list.length; i++)
  1574. {
  1575. if (!pattNumber.test(span_list[i].textContent))
  1576. {
  1577. span_list[i].parentElement.parentElement.parentElement.style.display = "none";
  1578. }
  1579. }
  1580.  
  1581. // preview bg in profile
  1582. {
  1583. if (ownerUrl != "http://steamcommunity.com/my")
  1584. {
  1585. var aImg = document.querySelector("#largeiteminfo_item_actions > a");
  1586. if (aImg != null)
  1587. {
  1588. var img = aImg.href;
  1589. if (/\.jpg$/i.test(img))
  1590. {
  1591. var urlPreview = ownerUrl + "?previewbg=" + img;
  1592.  
  1593. var a = document.createElement("a");
  1594. a.classList.add("btn_small");
  1595. a.classList.add("btn_grey_white_innerfade");
  1596. a.setAttribute("target", "_blank");
  1597. a.href = urlPreview;
  1598. a.innerHTML = '<span>Preview in Profile</span>';
  1599. aImg.parentElement.appendChild(a);
  1600. }
  1601. }
  1602. }
  1603. }
  1604. }
  1605. function linkMarketToBadgeAttach()
  1606. {
  1607. var url = document.documentURI;
  1608. var patt = /^http[s]?:\/\/steamcommunity.com\/market\/listings\/753\/[0-9]+/i;
  1609.  
  1610. if (patt.test(url) && !isErrorMarket())
  1611. {
  1612. attachOnLoad(linkMarketToBadge);
  1613. }
  1614. }
  1615. if (enableLinkMarketToBadge) linkMarketToBadgeAttach();
  1616.  
  1617. /** Add price of each cards in Badge page and link to Market page
  1618. */
  1619. function linkBadgeToMarket()
  1620. {
  1621. GM_addStyle(
  1622. ".div_market_price { float: right; } " // padding-top: 1px; display: inline-block; padding-left: 90px;
  1623. + ".gamecard_badge_craftbtn_ctn .badge_craft_button { width: 160px !important; } "
  1624. );
  1625.  
  1626. var url = document.documentURI;
  1627.  
  1628. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\//i;
  1629. var pattAppTail = /[^0-9]+.*/i;
  1630. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1631. var isFoil = getQueryByName("border", url) == "1";
  1632. var urlPrice = "http://steamcommunity.com/market/priceoverview/?appid=753&currency=";
  1633. var urlMarket = "http://steamcommunity.com/market/listings/753/";
  1634.  
  1635. var priceCards = new Array();
  1636. var priceUrls = new Array();
  1637. var cookieCountry = getCookie("steamCountry");
  1638. if (cookieCountry)
  1639. {
  1640. GM_setValue("storeCountry", cookieCountry.substr(0, 2));
  1641. }
  1642.  
  1643. setTimeout(function (app, isFoil)
  1644. {
  1645. var isCacheExpire = checkCacheExpire(app);
  1646. var elesCardName = document.querySelectorAll(".sbh_cardName");
  1647. for (var i = 0; i < elesCardName.length; i++)
  1648. {
  1649. updatePrice(app, isFoil, i);
  1650. if (isCacheExpire || !enableCache)
  1651. {
  1652. var currency = marketCountries[GM_getValue("storeCountry", "US")] || "1";
  1653. var urlPriceCur = urlPrice + currency
  1654. + "&market_hash_name="
  1655. + app + "-" + encodeURIComponent(elesCardName[i].textContent.trim())
  1656. + (isFoil ? "%20(Foil)" : "")
  1657. + "&sbh_appid=" + app
  1658. + (isFoil ? "&sbh_border=1" : "")
  1659. + "&sbh_cardid=" + i
  1660. + "&sbh_cardnum=" + (elesCardName.length + 1)
  1661. + "&sbh_expire=" + (isCacheExpire ? 1 : 0);
  1662. //console.log(urlPriceCur);
  1663. GM_xmlhttpRequest({
  1664. method: "GET",
  1665. url: urlPriceCur,
  1666. onload: getPriceCur,
  1667. });
  1668. }
  1669. }
  1670. }, 100, app, isFoil);
  1671.  
  1672. function getPriceCur(res)
  1673. {
  1674. var urlCur = res.finalUrl;
  1675. try
  1676. {
  1677. var dataRes = JSON.parse(res.responseText);
  1678. var isFoil = getQueryByName("sbh_border", urlCur) == "1";
  1679. var curCard = parseInt(getQueryByName("sbh_cardid", urlCur));
  1680. var numCard = parseInt(getQueryByName("sbh_cardnum", urlCur));
  1681. var app = getQueryByName("sbh_appid", urlCur);
  1682. var marketName = getQueryByName("market_hash_name", urlCur);
  1683. var isResolve = getQueryByName("sbh_resolve", urlCur) == "1";
  1684. var indexCard = (isFoil ? 1 : 0) * numCard + curCard;
  1685. var isCacheExpire = getQueryByName("sbh_expire", urlCur) == "1";
  1686. //console.log("marketName: " + marketName);
  1687. if (dataRes)
  1688. {
  1689. if (!dataRes.success && !isResolve)
  1690. {
  1691. var marketNameNew = marketName;
  1692. if (marketName.indexOf("566020-Mysterious") > -1)
  1693. {
  1694. marketNameNew = marketName.replace("566020-Mysterious", "566020-Mysterious Card");
  1695. }
  1696. else if (marketName.indexOf("639900-Mysterious") > -1)
  1697. {
  1698. marketNameNew = marketName.replace("639900-Mysterious", "639900-Mysterious Card");
  1699. }
  1700. else
  1701. {
  1702. marketNameNew = isFoil ? marketName.replace("(Foil)", "(Foil Trading Card)")
  1703. : marketName + " (Trading Card)";
  1704. }
  1705. //console.log("marketNameNew: " + marketNameNew);
  1706. var currency = marketCountries[GM_getValue("storeCountry", "US")] || "1";
  1707. var urlPriceCur = urlPrice + currency
  1708. + "&market_hash_name=" + encodeURIComponent(marketNameNew)
  1709. + "&sbh_appid=" + app
  1710. + (isFoil ? "&sbh_border=1" : "")
  1711. + "&sbh_cardid=" + curCard
  1712. + "&sbh_cardnum=" + numCard
  1713. + "&sbh_expire=" + (isCacheExpire ? 1 : 0)
  1714. + "&sbh_resolve=1";
  1715. //console.log(urlPriceCur);
  1716. GM_xmlhttpRequest({
  1717. method: "GET",
  1718. url: urlPriceCur,
  1719. onload: getPriceCur,
  1720. });
  1721. }
  1722. else
  1723. {
  1724. var cPrice = dataRes.lowest_price || "0";
  1725. var cUrl = encodeURIComponent(marketName);
  1726.  
  1727. priceCards[indexCard] = cPrice;
  1728. priceUrls[indexCard] = cUrl;
  1729. //console.log("getPriceCur: " + indexCard + ", " + cPrice + ", " + cUrl);
  1730.  
  1731. if (enableCache && isCacheExpire)
  1732. {
  1733. setCacheTime(app);
  1734. if (cPrice != "0")
  1735. {
  1736. setCachePrice(app, isFoil, curCard, cPrice);
  1737. }
  1738. setCacheUrl(app, isFoil, curCard, cUrl);
  1739. }
  1740. if (false)
  1741. {
  1742. var pattNumCard = /Card [0-9]+ of /i;
  1743. var pattMarket = /^http[s]?:\/\/steamcommunity.com\/market\/listings\/753\//i;
  1744. var pattPrice = /(Price: |Last seen: )/i;
  1745.  
  1746. var divTempID = randTempID();
  1747. createDivTemp(divTempID, res.responseText);
  1748. try
  1749. {
  1750. //debug("ID: "+divTempID);
  1751. var divTemp = document.getElementById(divTempID);
  1752. var numCard = 0;
  1753. try
  1754. {
  1755. var spanNumber = divTemp.getElementsByClassName("element-count")[0];
  1756. if (spanNumber == null)
  1757. {
  1758. debug("Warning: can't get price");
  1759. return;
  1760. }
  1761. numCard = parseInt(spanNumber.textContent.replace(pattNumCard, ""));
  1762. }
  1763. catch (e)
  1764. {
  1765. debug("Ex: " + e);
  1766. }
  1767.  
  1768. var offsetCard = isFoil ? numCard : 0;
  1769. var curCard = 0;
  1770.  
  1771. var isCacheExpire = checkCacheExpire(app);
  1772.  
  1773. priceCards = new Array();
  1774. priceUrls = new Array();
  1775.  
  1776. var as = divTemp.getElementsByClassName("button-blue");
  1777. for (var i = 0; i < as.length; i++)
  1778. {
  1779. if (pattMarket.test(as[i].href))
  1780. {
  1781. if (curCard < numCard * 2)
  1782. {
  1783. var cPrice = as[i].textContent.replace(pattPrice, "").trim();
  1784. var cUrl = as[i].href.replace(urlMarket, "");
  1785.  
  1786. var indexCard = curCard - offsetCard;
  1787. if (indexCard >= 0 && indexCard < numCard)
  1788. {
  1789. priceCards[indexCard] = cPrice;
  1790. priceUrls[indexCard] = cUrl;
  1791. }
  1792.  
  1793. // cache
  1794. if (enableCache && isCacheExpire)
  1795. {
  1796. setCacheTime(app);
  1797. if (curCard < numCard)
  1798. {
  1799. setCachePrice(app, false, curCard, cPrice);
  1800. setCacheUrl(app, false, curCard, cUrl);
  1801. }
  1802. else // foil
  1803. {
  1804. setCachePrice(app, true, curCard - numCard, cPrice);
  1805. setCacheUrl(app, true, curCard - numCard, cUrl);
  1806. }
  1807. }
  1808.  
  1809. curCard += 1;
  1810. }
  1811. else
  1812. {
  1813. break;
  1814. }
  1815. }
  1816. }
  1817. }
  1818. catch (e)
  1819. {
  1820. debug("Ex: " + e);
  1821. }
  1822. removeDivTemp(divTempID);
  1823. }
  1824. updatePrice(app, isFoil, curCard);
  1825. }
  1826.  
  1827. //debugTime("getPriceCur");
  1828. }
  1829. else
  1830. {
  1831. debug("getPriceCur: Fail " + urlCur);
  1832. var cUrl = encodeURIComponent(marketName);
  1833. priceUrls[indexCard] = cUrl;
  1834. if (enableCache && getCacheUrl(app, isFoil, curCard) == 0)
  1835. {
  1836. setCacheUrl(app, isFoil, curCard, cUrl);
  1837. }
  1838. updatePrice(app, isFoil, curCard);
  1839. }
  1840. }
  1841. catch (e)
  1842. {
  1843. debug("Ex: " + e + ", URL: " + urlCur);
  1844. }
  1845. }
  1846.  
  1847. function updatePrice(app, isFoil, curCard)
  1848. {
  1849. var pattNum = /[0-9\.]+/;
  1850. var colorUp = "#CC0000";
  1851. var colorDown = "#009900";
  1852.  
  1853. if (enableCache)
  1854. {
  1855. priceCards = new Array();
  1856. priceUrls = new Array();
  1857.  
  1858. var i = curCard;
  1859. if (i < 15)
  1860. //for (var i = 0; i < 15; i++)
  1861. {
  1862. var p = getCachePrice(app, isFoil, i);
  1863. var u = getCacheUrl(app, isFoil, i);
  1864. if (p != 0)
  1865. {
  1866. priceCards[i] = p;
  1867. }
  1868. if (u != 0)
  1869. {
  1870. priceUrls[i] = u;
  1871. }
  1872. }
  1873. }
  1874.  
  1875. var texts = document.getElementsByClassName("badge_card_set_card");
  1876. var numCard = texts.length;
  1877. var priceSet = 0;
  1878.  
  1879. var j = curCard;
  1880. if (j < texts.length)
  1881. //for (var j = 0; j < texts.length; j++)
  1882. {
  1883. var pUrl = priceUrls[j] ? urlMarket + priceUrls[j] : "";
  1884. var pCard = priceCards[j] ? priceCards[j] : "-";
  1885. var pOnClick = priceCards[j] ? "" : " onclick='return false;' ";
  1886. var pDiff = "";
  1887. var pCardOld = "";
  1888.  
  1889. var divTexts = texts[j].querySelectorAll("div.badge_card_set_text");
  1890. var divText = divTexts[divTexts.length - 1];
  1891. var divMarkets = texts[j].getElementsByClassName("div_market_price");
  1892. var divMarket;
  1893. if (divMarkets.length == 0)
  1894. {
  1895. divMarket = document.createElement("div");
  1896. divMarket.classList.add("div_market_price");
  1897. //divMarket.classList.add("badge_card_set_text_qty");
  1898. divText.appendChild(divMarket);
  1899.  
  1900. var divClear = document.createElement("div");
  1901. divClear.style.clear = "right";
  1902. divText.appendChild(divClear);
  1903.  
  1904. divText.style.whiteSpace = "normal";
  1905. }
  1906. else
  1907. {
  1908. divMarket = divMarkets[0];
  1909. var as = divMarket.getElementsByTagName("a");
  1910. if (as.length > 0)
  1911. {
  1912. var pOld = as[0].textContent;
  1913. var pValOld = pOld.match(pattNum);
  1914. if (pValOld != null)
  1915. {
  1916. //debug("oldPrice[" + j + "]: "+ pValOld);
  1917.  
  1918. pCardOld = "title='Cache Price: " + pOld + "'";
  1919.  
  1920. var pVal = pCard.match(pattNum);
  1921. pVal = pVal ? pVal : 0;
  1922.  
  1923. priceSet += parseFloat(pVal);
  1924.  
  1925. var pValDiff = (parseFloat(pVal) - parseFloat(pValOld)).toFixed(2);
  1926. if(pValDiff > 0)
  1927. {
  1928. pDiff = "<span style='cursor: help; color: " + colorUp + ";' "
  1929. + pCardOld + ">+" + pValDiff + "</span>";
  1930. }
  1931. else if (pValDiff < 0)
  1932. {
  1933. pDiff = "<span style='cursor: help; color: " + colorDown + ";' "
  1934. + pCardOld + ">" + pValDiff + "</span>";
  1935. }
  1936. else
  1937. {
  1938. pCardOld = "";
  1939. }
  1940. }
  1941. }
  1942. }
  1943.  
  1944. divMarket.innerHTML = pDiff + ' <a href="' + pUrl + '" ' + pOnClick + ' title="Lowest Price">' + pCard + "</a>";
  1945. } // end for
  1946.  
  1947. if (priceSet > 0)
  1948. {
  1949. //debug("priceSet: " + priceSet);
  1950. }
  1951. }
  1952. }
  1953. function linkBadgeToMarket_old()
  1954. {
  1955. GM_addStyle(
  1956. ".div_market_price { float: right; } " // padding-top: 1px; display: inline-block; padding-left: 90px;
  1957. + ".gamecard_badge_craftbtn_ctn .badge_craft_button { width: 160px !important; } "
  1958. );
  1959.  
  1960. var url = document.documentURI;
  1961.  
  1962. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\//i;
  1963. var pattAppTail = /[^0-9]+.*/i;
  1964. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  1965. var isFoil = getQueryByName("border", url) == "1";
  1966. var urlExternal = "http://www.steamcardexchange.net/index.php?gamepage-appid-" + app;
  1967. var urlMarket = "http://steamcommunity.com/market/listings/753/";
  1968.  
  1969. var priceCards = new Array();
  1970. var priceUrls = new Array();
  1971.  
  1972. updatePrice();
  1973.  
  1974. var isCacheExpire = checkCacheExpire(app);
  1975. if (isCacheExpire || !enableCache)
  1976. {
  1977. setTimeout(function ()
  1978. {
  1979. GM_xmlhttpRequest({
  1980. method: "GET",
  1981. url: urlExternal,
  1982. onload: getExternalPrice,
  1983. });
  1984. }, 0);
  1985. }
  1986.  
  1987. function getExternalPrice(res)
  1988. {
  1989. try
  1990. {
  1991. var pattNumCard = /Card [0-9]+ of /i;
  1992. var pattMarket = /^http[s]?:\/\/steamcommunity.com\/market\/listings\/753\//i;
  1993. var pattPrice = /(Price: |Last seen: )/i;
  1994.  
  1995. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  1996. var isLoggedIn = aOwner != null;
  1997. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  1998.  
  1999. var aFriend = document.querySelector(".profile_small_header_name > a");
  2000. var isFriendExist = aFriend != null;
  2001. var friendUrl = isFriendExist ? aFriend.href : "http://steamcommunity.com/my";
  2002. var friendName = isFriendExist ? aFriend.textContent.trim() : "my"
  2003. var friendNameOwner = isFriendExist ? friendName + "'s" : friendName;
  2004.  
  2005. var isOwner = isLoggedIn && ownerUrl == friendUrl;
  2006.  
  2007. var divTempID = randTempID();
  2008. createDivTemp(divTempID, res.responseText);
  2009. try
  2010. {
  2011. //debug("ID: "+divTempID);
  2012. var divTemp = document.getElementById(divTempID);
  2013. var numCard = 0;
  2014. try
  2015. {
  2016. var spanNumber = divTemp.getElementsByClassName("element-count")[0];
  2017. if (spanNumber == null)
  2018. {
  2019. debug("Warning: can't get price");
  2020. return;
  2021. }
  2022. numCard = parseInt(spanNumber.textContent.replace(pattNumCard, ""));
  2023. }
  2024. catch (e)
  2025. {
  2026. debug("Ex: " + e);
  2027. }
  2028.  
  2029. var offsetCard = isFoil ? numCard : 0;
  2030. var curCard = 0;
  2031.  
  2032. var isCacheExpire = checkCacheExpire(app);
  2033.  
  2034. priceCards = new Array();
  2035. priceUrls = new Array();
  2036.  
  2037. var as = divTemp.getElementsByClassName("button-blue");
  2038. for (var i = 0; i < as.length; i++)
  2039. {
  2040. if (pattMarket.test(as[i].href))
  2041. {
  2042. if (curCard < numCard * 2)
  2043. {
  2044. var cPrice = as[i].textContent.replace(pattPrice, "").trim();
  2045. var cUrl = as[i].href.replace(urlMarket, "");
  2046.  
  2047. var indexCard = curCard - offsetCard;
  2048. if (indexCard >= 0 && indexCard < numCard)
  2049. {
  2050. priceCards[indexCard] = cPrice;
  2051. priceUrls[indexCard] = cUrl;
  2052. }
  2053.  
  2054. // cache
  2055. if (enableCache && isCacheExpire)
  2056. {
  2057. setCacheTime(app);
  2058. if (curCard < numCard)
  2059. {
  2060. setCachePrice(app, false, curCard, cPrice);
  2061. setCacheUrl(app, false, curCard, cUrl);
  2062. }
  2063. else // foil
  2064. {
  2065. setCachePrice(app, true, curCard - numCard, cPrice);
  2066. setCacheUrl(app, true, curCard - numCard, cUrl);
  2067. }
  2068. }
  2069.  
  2070. curCard += 1;
  2071. }
  2072. else
  2073. {
  2074. break;
  2075. }
  2076. }
  2077. }
  2078. }
  2079. catch (e)
  2080. {
  2081. debug("Ex: " + e);
  2082. }
  2083. removeDivTemp(divTempID);
  2084.  
  2085. updatePrice();
  2086.  
  2087. debugTime("getExternalPrice");
  2088. }
  2089. catch (e)
  2090. {
  2091. debug("Ex: " + e);
  2092. }
  2093. }
  2094.  
  2095. function updatePrice()
  2096. {
  2097. var pattNum = /[0-9\.]+/;
  2098. var colorUp = "#CC0000";
  2099. var colorDown = "#009900";
  2100.  
  2101. if (enableCache)
  2102. {
  2103. priceCards = new Array();
  2104. priceUrls = new Array();
  2105.  
  2106. for (var i = 0; i < 15; i++)
  2107. {
  2108. var p = getCachePrice(app, isFoil, i);
  2109. var u = getCacheUrl(app, isFoil, i);
  2110. if (p != 0 && u != 0)
  2111. {
  2112. priceCards[i] = p;
  2113. priceUrls[i] = u;
  2114. }
  2115. else
  2116. {
  2117. break;
  2118. }
  2119. }
  2120. }
  2121.  
  2122. var texts = document.getElementsByClassName("badge_card_set_card");
  2123. var numCard = texts.length;
  2124. var priceSet = 0;
  2125.  
  2126. for (var j = 0; j < texts.length; j++)
  2127. {
  2128. var pUrl = priceUrls[j] ? urlMarket + priceUrls[j] : "";
  2129. var pCard = priceCards[j] ? priceCards[j] : "-";
  2130. var pOnClick = priceCards[j] ? "" : " onclick='return false;' ";
  2131. var pDiff = "";
  2132. var pCardOld = "";
  2133.  
  2134. var divTexts = texts[j].querySelectorAll("div.badge_card_set_text");
  2135. var divText = divTexts[divTexts.length - 1];
  2136. var divMarkets = texts[j].getElementsByClassName("div_market_price");
  2137. var divMarket;
  2138. if (divMarkets.length == 0)
  2139. {
  2140. divMarket = document.createElement("div");
  2141. divMarket.classList.add("div_market_price");
  2142. //divMarket.classList.add("badge_card_set_text_qty");
  2143. divText.appendChild(divMarket);
  2144.  
  2145. var divClear = document.createElement("div");
  2146. divClear.style.clear = "right";
  2147. divText.appendChild(divClear);
  2148.  
  2149. divText.style.whiteSpace = "normal";
  2150. }
  2151. else
  2152. {
  2153. divMarket = divMarkets[0];
  2154. var as = divMarket.getElementsByTagName("a");
  2155. if (as.length > 0)
  2156. {
  2157. var pOld = as[0].textContent;
  2158. var pValOld = pOld.match(pattNum);
  2159. if (pValOld != null)
  2160. {
  2161. //debug("oldPrice[" + j + "]: "+ pValOld);
  2162.  
  2163. pCardOld = "title='Cache Price: " + pOld + "'";
  2164.  
  2165. var pVal = pCard.match(pattNum);
  2166. pVal = pVal ? pVal : 0;
  2167.  
  2168. priceSet += parseFloat(pVal);
  2169.  
  2170. var pValDiff = (parseFloat(pVal) - parseFloat(pValOld)).toFixed(2);
  2171. if(pValDiff > 0)
  2172. {
  2173. pDiff = "<span style='cursor: help; color: " + colorUp + ";' "
  2174. + pCardOld + ">+" + pValDiff + "</span>";
  2175. }
  2176. else if (pValDiff < 0)
  2177. {
  2178. pDiff = "<span style='cursor: help; color: " + colorDown + ";' "
  2179. + pCardOld + ">" + pValDiff + "</span>";
  2180. }
  2181. else
  2182. {
  2183. pCardOld = "";
  2184. }
  2185. }
  2186. }
  2187. }
  2188.  
  2189. divMarket.innerHTML = pDiff + " <a href='" + pUrl + "' " + pOnClick + " title='Lowest Price'>" + pCard + "</a>";
  2190. } // end for
  2191.  
  2192. if (priceSet > 0)
  2193. {
  2194. debug("priceSet: " + priceSet);
  2195. }
  2196. }
  2197. }
  2198. function linkBadgeToMarketAttach()
  2199. {
  2200. var url = document.documentURI;
  2201. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  2202.  
  2203. if (patt.test(url) && !isErrorCard())
  2204. {
  2205. attachOnReady(linkBadgeToMarket);
  2206. }
  2207. }
  2208. if (enableLinkBadgeToMarket) linkBadgeToMarketAttach();
  2209.  
  2210. /** Compare my cards and friend's cards in Badge page
  2211. * Mark color of my cards count (Green) and friend's cards count (Blue)
  2212. */
  2213. function compareBadge()
  2214. {
  2215. var url = document.documentURI;
  2216.  
  2217. var pattAppHead = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\//i;
  2218. var pattAppTail = /[^0-9]+.*/i;
  2219. var app = url.replace(pattAppHead, "").replace(pattAppTail, "");
  2220.  
  2221. {
  2222. try
  2223. {
  2224. var pattNumCard = /Card [0-9]+ of /i;
  2225. var pattMarket = /^http[s]?:\/\/steamcommunity.com\/market\/listings\/753\//i;
  2226. var pattPrice = /Price: /i;
  2227.  
  2228. var isFoil = url.indexOf("border=1") > -1;
  2229.  
  2230. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  2231. var isLoggedIn = aOwner != null;
  2232. var ownerUrl = isLoggedIn ? aOwner.href.substr(0, aOwner.href.length - 1) : "http://steamcommunity.com/my";
  2233.  
  2234. var aFriend = document.querySelector(".profile_small_header_name > a");
  2235. var isFriendExist = aFriend != null;
  2236. var friendUrl = isFriendExist ? aFriend.href : "http://steamcommunity.com/my";
  2237. var friendName = isFriendExist ? aFriend.textContent.trim() : "my"
  2238. var friendNameOwner = isFriendExist ? friendName + "'s" : friendName;
  2239.  
  2240. var isOwner = isLoggedIn && ownerUrl == friendUrl;
  2241.  
  2242. //debug("ownerUrl: "+ownerUrl);
  2243. //debug("friendUrl: "+friendUrl);
  2244.  
  2245. var texts = document.getElementsByClassName("badge_card_set_card");
  2246. var numCard = texts.length;
  2247.  
  2248. //debug("isOwner: "+isOwner);
  2249. //debug("numCard: "+numCard);
  2250.  
  2251. for (var j = 0; j < numCard; j++)
  2252. {
  2253. var divQty = texts[j].querySelector("div.badge_card_set_text_qty");
  2254. var numQty = "(0)";
  2255. if (divQty != null)
  2256. {
  2257. numQty = divQty.textContent.trim();
  2258. }
  2259. else
  2260. {
  2261. divQty = document.createElement("div");
  2262. divQty.classList.add("badge_card_set_text_qty");
  2263. divQty.innerHTML = numQty;
  2264.  
  2265. var divCtn = texts[j].querySelector("div.game_card_ctn");
  2266. if (divCtn != null)
  2267. {
  2268. var divTexts = texts[j].querySelectorAll("div.badge_card_set_text");
  2269. if (divTexts.length < 2)
  2270. {
  2271. texts[j].insertBefore(divQty, divCtn.nextSibling);
  2272. }
  2273. else
  2274. {
  2275. divTexts[0].insertBefore(divQty, divTexts[0].firstChild);
  2276. }
  2277. }
  2278. }
  2279. //debug("numQty: "+numQty);
  2280. } // end for
  2281.  
  2282. var colorOwner = "#8CBE0F";
  2283. var colorFriend = "#5491CF";
  2284. var colorZeroOwner = "#557309";
  2285. var colorZeroFriend = "#355C82";
  2286.  
  2287. var countCardAll = 0;
  2288.  
  2289. var divQtys = document.querySelectorAll("div.badge_card_set_text_qty");
  2290. for (var k = 0; k < divQtys.length; k++)
  2291. {
  2292. var num = divQtys[k].textContent.trim().replace(/[\(\)]/gi, "");
  2293. countCardAll += parseInt(num);
  2294.  
  2295. divQtys[k].innerHTML = "";
  2296.  
  2297. var spanNum = document.createElement("span");
  2298. spanNum.classList.add("span_card_qty");
  2299. spanNum.style.cursor = "help";
  2300. spanNum.innerHTML = " (" + num + ") ";
  2301. divQtys[k].insertBefore(spanNum, null);
  2302.  
  2303. if (isOwner)
  2304. {
  2305. spanNum.classList.add("span_card_qty_owner");
  2306. spanNum.style.color = num > "0" ? colorOwner : colorZeroOwner;
  2307. spanNum.title = "My cards: " + num;
  2308. }
  2309. else
  2310. {
  2311. spanNum.classList.add("span_card_qty_friend");
  2312. spanNum.style.color = num > "0" ? colorFriend : colorZeroFriend;
  2313. spanNum.title = friendNameOwner + " cards: " + num;
  2314. }
  2315. }
  2316.  
  2317. debug("countCard: " + countCardAll);
  2318. debug("maxSet: " + parseInt(countCardAll / numCard));
  2319.  
  2320. if (!isOwner)
  2321. {
  2322. var pattProfile = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]*/i;
  2323. var urlExternal = url.replace(pattProfile, ownerUrl);
  2324. //debug("urlExternal: "+urlExternal);
  2325.  
  2326. setTimeout(function ()
  2327. {
  2328. GM_xmlhttpRequest({
  2329. method: "GET",
  2330. url: urlExternal,
  2331. onload: compareCard,
  2332. });
  2333. }, 0);
  2334.  
  2335. function compareCard(res)
  2336. {
  2337. var divTempID = randTempID();
  2338. createDivTemp(divTempID, res.responseText);
  2339. try
  2340. {
  2341. //debug("ID: "+divTempID);
  2342. var divTemp = document.getElementById(divTempID);
  2343.  
  2344. var owner_texts = divTemp.getElementsByClassName("badge_card_set_card");
  2345. var owner_numCard = owner_texts.length;
  2346.  
  2347. if (numCard == owner_numCard)
  2348. {
  2349. var owner_numQtys = new Array();
  2350.  
  2351. for (var i = 0; i < owner_texts.length; i++)
  2352. {
  2353. var owner_divQty = owner_texts[i].querySelector("div.badge_card_set_text_qty");
  2354. if (owner_divQty != null)
  2355. {
  2356. owner_numQtys[i] = owner_divQty.textContent.trim().replace(/[\(\)]/gi, "");
  2357. }
  2358. else
  2359. {
  2360. owner_numQtys[i] = "0";
  2361. }
  2362. //debug("owner_numQtys[i]: "+owner_numQtys[i]);
  2363. } // end for
  2364.  
  2365. var friend_divQtys = document.querySelectorAll("div.badge_card_set_text_qty");
  2366. for (var k = 0; k < friend_divQtys.length; k++)
  2367. {
  2368. var owner_spanNum = friend_divQtys[k].querySelector("span_card_qty_owner");
  2369. if (owner_spanNum == null)
  2370. {
  2371. owner_spanNum = document.createElement("span");
  2372. owner_spanNum.classList.add("span_card_qty");
  2373. owner_spanNum.style.cursor = "help";
  2374. owner_spanNum.classList.add("span_card_qty_owner");
  2375. owner_spanNum.style.color = owner_numQtys[k] > "0" ? colorOwner : colorZeroOwner;
  2376. owner_spanNum.title = "My cards: " + owner_numQtys[k];
  2377. friend_divQtys[k].insertBefore(owner_spanNum, friend_divQtys[k].firstChild);
  2378. }
  2379. owner_spanNum.innerHTML = " (" + owner_numQtys[k] + ") ";
  2380. }
  2381. }
  2382. }
  2383. catch (e)
  2384. {
  2385. debug("Ex: " + e);
  2386. }
  2387. removeDivTemp(divTempID);
  2388. debugTime("compareBadge");
  2389. }
  2390. }
  2391. }
  2392. catch (e)
  2393. {
  2394. debug("Ex: " + e);
  2395. }
  2396. }
  2397.  
  2398. // Add clickable card name
  2399. {
  2400. GM_addStyle(
  2401. " .sbh_cardName { color: #999; max-width: 170px; text-overflow: ellipsis; "
  2402. + " overflow: hidden; /*display: inline-block;*/ white-space: nowrap;} "
  2403. );
  2404.  
  2405. var eleTexts = document.querySelectorAll(".badge_card_set_card");
  2406. for (var i = 0; i < eleTexts.length; i++)
  2407. {
  2408. var eleText = eleTexts[i].querySelector(".badge_card_set_text");
  2409. for (var j = 0; j < eleText.childNodes.length; j++)
  2410. {
  2411. if (eleText.childNodes[j].nodeName == "#text")
  2412. {
  2413. var text = eleText.childNodes[j].textContent.trim();
  2414. if (text != "")
  2415. {
  2416. var eleSpan = document.createElement("div");
  2417. eleSpan.classList.add("sbh_cardName");
  2418. eleSpan.textContent = text;
  2419. eleText.replaceChild(eleSpan, eleText.childNodes[j]);
  2420.  
  2421. eleSpan.addEventListener("click", function (e)
  2422. {
  2423. var ele = e.target;
  2424. clickToSelect(ele);
  2425. });
  2426.  
  2427. j = eleText.childNodes.length;
  2428. }
  2429. }
  2430. }
  2431. }
  2432. }
  2433. }
  2434. function compareBadgeAttach()
  2435. {
  2436. var url = document.documentURI;
  2437. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/gamecards\/[0-9]+/i;
  2438.  
  2439. if (patt.test(url) && !isErrorCard())
  2440. {
  2441. attachOnReady(compareBadge);
  2442. }
  2443. }
  2444. if (enableCompareBadge) compareBadgeAttach();
  2445.  
  2446. /** Link items in inventory to store and badge page
  2447. */
  2448. function linkInventoryToBadge()
  2449. {
  2450. if (isError())
  2451. return;
  2452.  
  2453. GM_addStyle
  2454. (
  2455. " .view_inventory_page .item.activeInfo "
  2456. + "{ background-image: none !important; background-color: #9B9B9B !important; border: 1px solid #C9C9C9; } "
  2457. + " .descriptor { max-height: 100px; overflow-y: auto; } "
  2458. + " .inventory_iteminfo .item_desc_content { padding-top: 225px !important; padding-bottom: 0px !important; }"
  2459. + " #pricehistory_notavailable { display: none !important; }"
  2460. );
  2461. if (getQueryByName("modal") == "1")
  2462. {
  2463. GM_addStyle
  2464. (
  2465. " .inventory_page_left { padding-bottom: 400px; } "
  2466. + " .descriptor, .item_scrap_actions { display: none; } "
  2467. + " #market_sell_dialog_accept > span { line-height: 30px; } "
  2468. + " #market_sell_dialog_confirm_buttons > .market_dialog_bottom_buttons { margin-top: 110px; } "
  2469. + " #market_sell_dialog_ok { min-width: 150px; } "
  2470. );
  2471. }
  2472. }
  2473. function linkInventoryToBadgeAttach()
  2474. {
  2475. var url = document.documentURI;
  2476. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/inventory/i;
  2477.  
  2478. if (patt.test(url))
  2479. {
  2480. attachOnLoad(linkInventoryToBadge);
  2481. }
  2482. }
  2483. if (enableLinkInventoryToBadge) linkInventoryToBadgeAttach();
  2484.  
  2485. function editTitle()
  2486. {
  2487. var url = document.documentURI;
  2488. try
  2489. {
  2490. var titleOld = document.title;
  2491. var titleNew = titleOld;
  2492. var titleNoti = "";
  2493. var pattSale = /[0-9]+%/i;
  2494. var intervalTitle = null;
  2495.  
  2496. if (enableSwapTitle)
  2497. {
  2498. var splitSpace = titleOld.split(" ");
  2499. if (splitSpace.length > 1)
  2500. {
  2501. if (pattSale.test(splitSpace[1]))
  2502. {
  2503. splitSpace.splice(0, 1);
  2504. splitSpace.splice(1, 1);
  2505. titleOld = splitSpace.join(" ");
  2506. }
  2507. }
  2508. var split = titleOld.split("::").reverse();
  2509. for (var i = 0; i < split.length; i++)
  2510. {
  2511. split[i] = split[i].trim();
  2512. }
  2513. if (url.indexOf("steamcommunity.com/market/listings/") > -1)
  2514. {
  2515. var posApp = split[0].search(/\d/);
  2516. if (posApp > -1)
  2517. {
  2518. split[0] = split[0].substr(posApp);
  2519. }
  2520. var posSub = split[0].indexOf("-");
  2521. if (posSub > 0)
  2522. {
  2523. split[0] = split[0].substr(posSub + 1) + " - " + split[0].substr(0, posSub);
  2524. }
  2525. }
  2526. titleNew = split.join(" :: ");
  2527. document.title = titleNew;
  2528. }
  2529.  
  2530. var divH = document.querySelector("#header_notification_area");
  2531. if (divH != null)
  2532. {
  2533. divH.addEventListener('mouseover', function() {
  2534. clearInterval(intervalTitle);
  2535. document.title = titleNew;
  2536. });
  2537. }
  2538.  
  2539. if (enableShowTitleNoti)
  2540. {
  2541. function updateTitleNoti()
  2542. {
  2543. var noti = document.querySelector("#header_notification_link");
  2544. if (noti != null)
  2545. {
  2546. var notiNum = noti.textContent.trim();
  2547. if (notiNum != "" && notiNum != "0")
  2548. {
  2549. //debug("updateTitleNoti: "+notiNum);
  2550. titleNoti = "("+notiNum+") ";
  2551. }
  2552. else
  2553. {
  2554. titleNoti = "";
  2555. }
  2556. if (document.title != titleNoti + titleNew)
  2557. {
  2558. //debug("changeTitle: "+notiNum);
  2559. document.title = titleNoti + titleNew;
  2560. }
  2561. }
  2562. }
  2563.  
  2564. intervalTitle = setInterval(updateTitleNoti, 1000);
  2565.  
  2566. {
  2567. /*
  2568. var timeoutID = -1;
  2569.  
  2570. noti.addEventListener("DOMSubtreeModified", function (e) {
  2571. debug("DOMSubtreeModified");
  2572. try
  2573. {
  2574. clearTimeout(timeoutID);
  2575. }
  2576. catch (ex)
  2577. {
  2578. }
  2579. updateTitleNoti();
  2580. });
  2581.  
  2582. noti.addEventListener("DOMNodeInserted", function (e) {
  2583. debug("DOMNodeInserted");
  2584. try
  2585. {
  2586. clearTimeout(timeoutID);
  2587. }
  2588. catch (ex)
  2589. {
  2590. }
  2591. updateTitleNoti();
  2592. });
  2593.  
  2594. noti.addEventListener("DOMNodeRemoved", function (e) {
  2595. debug("DOMNodeRemoved");
  2596. timeoutID = setTimeout(updateTitleNoti,100);
  2597. });
  2598. */
  2599. }
  2600. }
  2601. }
  2602. catch (ex)
  2603. {
  2604. debug("editTitle: "+ex);
  2605. }
  2606. }
  2607. function editTitleAttach()
  2608. {
  2609. attachOnReady(editTitle);
  2610. }
  2611. if (enableSwapTitle || enableShowTitleNoti) editTitleAttach();
  2612.  
  2613. /** Resize trade window that is larger than 768px
  2614. */
  2615. function resizeTradeWindow()
  2616. {
  2617. if (window.innerHeight < 800)
  2618. {
  2619. //GM_addStyle("#mainContent { transform: scale(0.8, 0.8); transform-origin: 50% 0px 0px; }");
  2620.  
  2621. if (window.innerWidth > 1000)
  2622. {
  2623. //window.resizeBy(-240,0);
  2624. //window.moveBy(200,0);
  2625. }
  2626. }
  2627.  
  2628. var ele = document.querySelector("#trade_escrow_header, .trade_partner_info_block");
  2629. if (ele != null)
  2630. {
  2631. ele.scrollIntoView();
  2632. }
  2633.  
  2634. // Fix blank box in Firefox
  2635. {
  2636. setInterval(function ()
  2637. {
  2638. if (isVisible())
  2639. {
  2640. var ele = document.querySelector("#inventory_displaycontrols");
  2641. if (ele != null)
  2642. {
  2643. if (ele.offsetHeight > 200)
  2644. {
  2645. if (ele.style.float != "left")
  2646. {
  2647. ele.style.float = "left";
  2648. }
  2649. }
  2650. else
  2651. {
  2652. if (ele.style.float != "")
  2653. {
  2654. ele.style.float = "";
  2655. }
  2656. }
  2657. }
  2658. }
  2659. }, 1000);
  2660. }
  2661. // Use arrow keys to change page
  2662. {
  2663. document.body.addEventListener("keydown", function (e)
  2664. {
  2665. var query = "";
  2666. if (e.keyCode != undefined)
  2667. {
  2668. if (e.keyCode === 37) // Left
  2669. {
  2670. query = "#pagebtn_previous";
  2671. }
  2672. else if (e.keyCode === 39) // Right
  2673. {
  2674. query = "#pagebtn_next";
  2675. }
  2676. }
  2677. if (query !== "")
  2678. {
  2679. var eleTarget = document.querySelector(query);
  2680. if (eleTarget)
  2681. {
  2682. e.preventDefault();
  2683. eleTarget.click();
  2684. return false;
  2685. }
  2686. }
  2687. }, true);
  2688. }
  2689. }
  2690. function resizeTradeWindowAttach(tm)
  2691. {
  2692. var url = document.documentURI;
  2693. var patt = /^http[s]?:\/\/steamcommunity.com\/(tradeoffer|trade)\//i;
  2694.  
  2695. if (patt.test(url))
  2696. {
  2697. attachOnLoad(function ()
  2698. {
  2699. setTimeout(resizeTradeWindow, tm);
  2700. });
  2701. }
  2702. }
  2703. if (enableResizeTradeWindow) resizeTradeWindowAttach(100);
  2704.  
  2705. /** Add link in profile page
  2706. */
  2707. function linkProfile()
  2708. {
  2709. GM_addStyle(".achievement_progress_bar_ctn { width: 118px; margin-left: 4px; } "
  2710. + ".showcase_stat .value { z-index: 2; position: relative; } ");
  2711.  
  2712. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  2713. var isLoggedIn = aOwner != null;
  2714. var url = document.documentURI;
  2715. var urlOwner = url;
  2716.  
  2717. if (urlOwner[urlOwner.length-1] != "/")
  2718. {
  2719. urlOwner = urlOwner + "/";
  2720. }
  2721.  
  2722. var urlName = urlOwner + "namehistory/";
  2723. var urlPost = urlOwner + "posthistory/";
  2724. var labelName = "Name History";
  2725. var labelPost = "Post History";
  2726. var arrUrl = ["", urlName, urlPost];
  2727. var arrLbl = ["", labelName, labelPost];
  2728.  
  2729. var divOuter = document.querySelector(".profile_item_links");
  2730. if (divOuter != null)
  2731. {
  2732. for (var i = 0; i < arrUrl.length; i++)
  2733. {
  2734. var div = document.createElement("div");
  2735. if (div != null)
  2736. {
  2737. div.className = "profile_count_link";
  2738. div.innerHTML = '<a href="' + arrUrl[i] + '"><span class="count_link_label">'
  2739. + arrLbl[i] + '</span> <span class="profile_count_link_total"> </span></a>';
  2740.  
  2741. divOuter.appendChild(div);
  2742. }
  2743. }
  2744. }
  2745.  
  2746. // preview bg in profile
  2747. function previewBg()
  2748. {
  2749. var bg = getQueryByName("previewbg");
  2750. if (bg != "")
  2751. {
  2752. var divBg = document.querySelector("div.has_profile_background");
  2753. if (divBg != null)
  2754. {
  2755. divBg.style.backgroundImage = "url('" + bg + "')";
  2756. }
  2757.  
  2758. var divBgIn = document.querySelector("div.profile_background_image_content");
  2759. if (divBgIn != null)
  2760. {
  2761. divBgIn.style.backgroundImage = "url('" + bg + "')";
  2762. }
  2763. }
  2764. }
  2765. attachOnLoad(previewBg);
  2766. // Focus profile
  2767. if (isLoggedIn)
  2768. {
  2769. var eleTarget = document.querySelector(".no_header");
  2770. if (eleTarget != null)
  2771. {
  2772. eleTarget.scrollIntoView();
  2773. }
  2774. }
  2775. }
  2776. function linkProfileReady()
  2777. {
  2778. var url = document.documentURI;
  2779. var patt = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+(\/?\?.*)?\/?$/i;
  2780.  
  2781. if (patt.test(url))
  2782. {
  2783. attachOnReady(linkProfile);
  2784. }
  2785. }
  2786. if (enableLinkProfile) linkProfileReady();
  2787.  
  2788. /** Set all checkbox to checked
  2789. */
  2790. function setAllCheckBox()
  2791. {
  2792. var eles = document.querySelectorAll("#market_buynow_dialog_accept_ssa"
  2793. + ", #market_sell_dialog_accept_ssa, #accept_ssa, #verify_country_only, #market_buyorder_dialog_accept_ssa");
  2794. for (var i = 0; i < eles.length; i++)
  2795. {
  2796. eles[i].checked = true;
  2797. }
  2798. }
  2799. function setAllCheckBoxReady()
  2800. {
  2801. var url = document.documentURI;
  2802. var pattMarket = /^http[s]?:\/\/steamcommunity.com\/market\/listings\/[0-9]+/i;
  2803. var pattInv = /^http[s]?:\/\/steamcommunity.com\/(id|profiles)\/[^\/]+\/inventory/i;
  2804. var pattCart = /^http[s]?:\/\/store.steampowered.com\/checkout/i;
  2805.  
  2806. if (pattMarket.test(url) || pattInv.test(url) || pattCart.test(url))
  2807. {
  2808. attachOnReady(setAllCheckBox);
  2809. }
  2810. }
  2811. if (enableSetAllCheckBox) setAllCheckBoxReady();
  2812.  
  2813. /** Scroll store page to easy view
  2814. */
  2815. function storeFocus()
  2816. {
  2817. // Store focus
  2818. {
  2819. var eleAccount = document.querySelector("#account_pulldown");
  2820. if (eleAccount != null)
  2821. {
  2822. var divHead = document.querySelector(".breadcrumbs > .blockbg, "
  2823. + " .breadcrumbs > a, div.auction_block:nth-child(1), .market_listing_nav > a");
  2824. if (divHead != null)
  2825. {
  2826. divHead.scrollIntoView();
  2827. }
  2828. }
  2829. }
  2830.  
  2831. // Click to select app name
  2832. {
  2833. var eleName = document.querySelector(".apphub_AppName, .pageheader");
  2834. if (eleName != null)
  2835. {
  2836. eleName.addEventListener("click", function (e)
  2837. {
  2838. var ele = e.target;
  2839. clickToSelect(ele);
  2840. });
  2841. }
  2842. }
  2843. }
  2844. function storeFocusAttach()
  2845. {
  2846. var url = document.documentURI;
  2847. var patt = /^http[s]?:\/\/(store.steampowered.com\/(app|sub|bundle)\/|steamcommunity.com\/(auction\/item\/|sharedfiles\/filedetails\/\?id=|market\/listings\/))/i;
  2848.  
  2849. if (patt.test(url))
  2850. {
  2851. attachOnReady(storeFocus);
  2852. }
  2853. }
  2854. if (enableStoreFocus) storeFocusAttach();
  2855.  
  2856. function autoExploreQueue()
  2857. {
  2858. var url = document.documentURI;
  2859. var pattApp = /^http[s]?:\/\/store.steampowered.com\/app/i;
  2860. var pattExplore = /^http[s]?:\/\/store.steampowered.com\/\/?explore/i;
  2861.  
  2862. // Auto explore queue in app
  2863. if (pattApp.test(url))
  2864. {
  2865. GM_addStyle(
  2866. " .sbh_autoQueueOption { float: right; padding-right: 3px; } "
  2867. + " #sbh_autoQueue { vertical-align: text-top; } "
  2868. );
  2869.  
  2870. // Clean url in next queue
  2871. {
  2872. var eleQueue = document.querySelector("#next_in_queue_form");
  2873. if (eleQueue != null)
  2874. {
  2875. var action = eleQueue.getAttribute("action");
  2876. if (action[action.length] != "/")
  2877. {
  2878. action += "/";
  2879. eleQueue.setAttribute("action", action);
  2880. }
  2881. }
  2882. }
  2883. function autoQueue()
  2884. {
  2885. var tm = 3000;
  2886. debug("AutoQueue: Next in " + tm + "ms");
  2887. setTimeout(function ()
  2888. {
  2889. var eleCheck = document.querySelector("#sbh_autoQueue");
  2890. if (eleCheck != null && eleCheck.checked)
  2891. {
  2892. var ele = document.querySelector(".btn_next_in_queue");
  2893. if (ele != null)
  2894. {
  2895. GM_setValue("storeAutoQueueLast", getUnixTimestamp());
  2896. ele.click();
  2897. }
  2898. }
  2899. }, tm);
  2900. }
  2901.  
  2902. var eleDes = document.querySelector(".queue_controls_description");
  2903. if (eleDes != null)
  2904. {
  2905. var eleSpan = document.createElement("span");
  2906. eleSpan.classList.add("sbh_autoQueueOption");
  2907.  
  2908. var eleInput = document.createElement("input");
  2909. eleInput.id = "sbh_autoQueue";
  2910. eleInput.setAttribute("type", "checkbox");
  2911. eleInput.setAttribute("value", "auto");
  2912.  
  2913. if (GM_getValue("storeAutoQueue", 0) == "true")
  2914. {
  2915. eleInput.checked = true;
  2916.  
  2917. var ele = document.querySelector(".btn_next_in_queue");
  2918. if (ele != null)
  2919. {
  2920. autoQueue();
  2921. }
  2922. }
  2923.  
  2924. eleInput.addEventListener("click", function (e)
  2925. {
  2926. var ele = e.target;
  2927. if (ele.checked)
  2928. {
  2929. GM_setValue("storeAutoQueue", "true");
  2930. autoQueue();
  2931. }
  2932. else
  2933. {
  2934. GM_setValue("storeAutoQueue", "false");
  2935. }
  2936. });
  2937.  
  2938. var eleLabel = document.createElement("label");
  2939. eleLabel.setAttribute("for", "sbh_autoQueue");
  2940. eleLabel.textContent = " Auto Explore Queue";
  2941.  
  2942. eleSpan.appendChild(eleInput);
  2943. eleSpan.appendChild(eleLabel);
  2944. eleDes.appendChild(eleSpan);
  2945. }
  2946. else
  2947. {
  2948. // Session lost
  2949. if (GM_getValue("storeAutoQueue", 0) == "true")
  2950. {
  2951. var aOwner = document.querySelector("#global_actions > .user_avatar");
  2952. var isLoggedIn = aOwner != null;
  2953. if (!isLoggedIn)
  2954. {
  2955. // Auto reload every 10s within 2 minutes
  2956. var tmExpireShort = 120;
  2957. var tmReloadShort = 10000;
  2958. // Auto reload every 30s within 10 minutes
  2959. var tmExpireLong = 600;
  2960. var tmReloadLong = 30000;
  2961. var tmReload = 0;
  2962. var tmDiff = getUnixTimestamp() - GM_getValue("storeAutoQueueLast", 0);
  2963. if (tmDiff < tmExpireShort)
  2964. {
  2965. tmReload = tmReloadShort;
  2966. }
  2967. else if (tmDiff < tmReloadLong)
  2968. {
  2969. tmReload = tmExpireLong;
  2970. }
  2971. if (tmReload > 0)
  2972. {
  2973. debug("AutoQueue: Refresh in " + tmReload + "ms");
  2974. setTimeout(reload, tmReload);
  2975. }
  2976. }
  2977. }
  2978. }
  2979. }
  2980.  
  2981. // Auto explore queue in explore
  2982. if (pattExplore.test(url))
  2983. {
  2984. if (GM_getValue("storeAutoQueue", 0) == "true")
  2985. {
  2986. var eleText = document.querySelector(".subtext");
  2987. if (eleText != null && /[^-][0-9]/.test(eleText.textContent.trim()))
  2988. {
  2989. setTimeout(function ()
  2990. {
  2991. var ele = document.querySelector("#discovery_queue_start_link");
  2992. if (!ele || ele.parentElement.style.display === "none")
  2993. {
  2994. ele = document.querySelector("#refresh_queue_btn");
  2995. }
  2996. if (ele)
  2997. {
  2998. ele.click();
  2999. }
  3000. }, 3000);
  3001. setTimeout(function ()
  3002. {
  3003. var ele = document.querySelector(".newmodal_buttons > .btn_medium");
  3004. if (ele)
  3005. {
  3006. ele.click();
  3007. debug("AutoQueue: Refresh in " + 1000 + "ms");
  3008. setTimeout(reload, 1000);
  3009. }
  3010. }, 10000);
  3011. setTimeout(function ()
  3012. {
  3013. var ele = document.querySelector(".newmodal_buttons > .btn_medium");
  3014. if (ele)
  3015. {
  3016. ele.click();
  3017. debug("AutoQueue: Refresh in " + 1000 + "ms");
  3018. setTimeout(reload, 1000);
  3019. }
  3020. }, 20000);
  3021. }
  3022. }
  3023.  
  3024. }
  3025. }
  3026. function autoExploreQueueAttach()
  3027. {
  3028. var url = document.documentURI;
  3029. var patt = /^http[s]?:\/\/store.steampowered.com\/\/?(app|explore)/i;
  3030.  
  3031. if (patt.test(url))
  3032. {
  3033. // Fix for slow connection
  3034. var didAutoExploreQueue = false;
  3035. var attemptAutoExploreQueue = 0;
  3036. var tmAutoExploreQueue = setInterval(function()
  3037. {
  3038. //console.log("AutoQueue: Slow connection");
  3039. didAutoExploreQueue = true;
  3040. autoExploreQueue();
  3041. if (document.querySelector("#sbh_autoQueue") != null)
  3042. {
  3043. clearInterval(tmAutoExploreQueue);
  3044. }
  3045. else
  3046. {
  3047. if (attemptAutoExploreQueue > 10)
  3048. {
  3049. console.log("AutoQueue: Auto refresh from slow connection");
  3050. reload();
  3051. }
  3052. attemptAutoExploreQueue++;
  3053. }
  3054. }, 5000);
  3055. attachOnReady(function()
  3056. {
  3057. if (!didAutoExploreQueue || document.querySelector("#sbh_autoQueue") == null)
  3058. {
  3059. clearInterval(tmAutoExploreQueue);
  3060. autoExploreQueue();
  3061. }
  3062. });
  3063. }
  3064. }
  3065. if (enableAutoExploreQueue) autoExploreQueueAttach();
  3066.  
  3067. function skipAgeCheck()
  3068. {
  3069. setTimeout(function ()
  3070. {
  3071. var ele = document.querySelector(".btns.agegate_text_container > a, #age_gate_btn_continue");
  3072. if (ele != null)
  3073. {
  3074. ele.setAttribute("onclick", ele.getAttribute("onclick") + "; return false;");
  3075. ele.click();
  3076. }
  3077. var eleAge = document.querySelector("#ageYear option[selected]");
  3078. if (eleAge != null)
  3079. {
  3080. eleAge.removeAttribute("selected");
  3081. var eleAgeFirst = document.querySelector("#ageYear option");
  3082. eleAgeFirst.setAttribute("selected", "true");
  3083. var eleBtn = document.querySelector(".btn_small[onclick^='DoAgeGateSubmit()']");
  3084. if (eleBtn != null)
  3085. {
  3086. eleBtn.click();
  3087. }
  3088. }
  3089. }, 3000);
  3090. }
  3091. function skipAgeCheckAttach()
  3092. {
  3093. var url = document.documentURI;
  3094. var patt = /^http[s]?:\/\/(store\.steampowered\.com\/(app\/[0-9]+\/agecheck|agecheck\/app\/[0-9]+)|steamcommunity\.com\/app\/)/i;
  3095.  
  3096. if (patt.test(url))
  3097. {
  3098. attachOnReady(skipAgeCheck);
  3099. }
  3100. }
  3101. if (enableSkipAgeCheck) skipAgeCheckAttach();
  3102.  
  3103. function skipLinkFilter()
  3104. {
  3105. setTimeout(function ()
  3106. {
  3107. var ele = document.querySelector("#proceedButton");
  3108. if (ele != null)
  3109. {
  3110. ele.click();
  3111. }
  3112. }, 3000);
  3113. }
  3114. function skipLinkFilterAttach()
  3115. {
  3116. var url = document.documentURI;
  3117. var patt = /^http[s]?:\/\/steamcommunity.com\/linkfilter\//i;
  3118.  
  3119. if (patt.test(url))
  3120. {
  3121. attachOnReady(skipLinkFilter);
  3122. }
  3123. }
  3124. if (enableSkipLinkFilter) skipLinkFilterAttach();
  3125.  
  3126. /** Hide queue in already owned in store page
  3127. */
  3128. function storeHideSection()
  3129. {
  3130. var divOwn = document.querySelector(".already_owned_actions");
  3131. if (divOwn)
  3132. {
  3133. GM_addStyle(
  3134. ".game_area_already_owned { margin-top: 10px !important; } "
  3135. + ".queue_ctn { display: none; } "
  3136. + "#review_container, .reviewPostedDescription, .review_box > .thumb { display: none; } "
  3137. + ".sbh_margin_left { margin-left: 5px; } "
  3138. + ".game_area_play_stats { min-height: 50px; } "
  3139. + "#review_container { margin-top: 30px; } "
  3140. + ".game_area_already_owned_btn a[href='http://store.steampowered.com/about/'] { display: none; } "
  3141. );
  3142.  
  3143. var html = ""
  3144.  
  3145. html += ' <a class="btnv6_blue_hoverfade btn_medium right sbh_margin_left sbh_showFollow" onclick="'
  3146. + "var sbhQueue = document.querySelector('.queue_ctn');"
  3147. + "if (sbhQueue != null) { sbhQueue.style.display = 'inherit'; sbhQueue = null;} "
  3148. + "this.style.display = 'none'; return false;"
  3149. + '"><span>Follow</span></a> ';
  3150.  
  3151. var divReview = document.querySelector("#review_container, .reviewPostedDescription");
  3152. if (divReview != null)
  3153. {
  3154. html += ' <a class="btnv6_blue_hoverfade btn_medium right sbh_margin_left" onclick="'
  3155. + "var sbhReview = document.querySelector('#review_container, .reviewPostedDescription'); "
  3156. + "if (sbhReview != null) { sbhReview.style.display = 'inherit'; sbhReview = null; } "
  3157. + "var sbhReviewThumb = document.querySelector('.review_box > .thumb'); "
  3158. + "if (sbhReviewThumb != null) { sbhReviewThumb.style.display = 'inherit'; sbhReviewThumb = null; } "
  3159. + "this.style.display = 'none'; return false;"
  3160. + '"><span>Review</span></a> ';
  3161. }
  3162.  
  3163. divOwn.innerHTML += html;
  3164. setTimeout(function()
  3165. {
  3166. var eleQueue = document.querySelector(".queue_ctn");
  3167. if (eleQueue)
  3168. {
  3169. var eleIgnore = eleQueue.querySelector(".queue_btn_ignore .queue_btn_inactive:first-child");
  3170. if (eleIgnore)
  3171. {
  3172. if (eleIgnore.style.display === "none")
  3173. {
  3174. eleQueue.style.display = 'inherit';
  3175. var eleFollow = document.querySelector(".sbh_showFollow");
  3176. if (eleFollow)
  3177. {
  3178. eleFollow.style.display = 'none';
  3179. }
  3180. }
  3181. }
  3182. }
  3183. }, 500);
  3184. }
  3185. }
  3186. function storeHideSectionReady()
  3187. {
  3188. var url = document.documentURI;
  3189. var patt = /^http[s]?:\/\/store.steampowered.com\/app\//i;
  3190.  
  3191. if (patt.test(url))
  3192. {
  3193. attachOnReady(storeHideSection);
  3194. }
  3195. }
  3196. if (enableStoreHideSection) storeHideSectionReady();
  3197.  
  3198. /** Move sale section in main page
  3199. */
  3200. function moveSale()
  3201. {
  3202. var eleSpecial = document.querySelector(".home_page_content.special_offers");
  3203. if (eleSpecial)
  3204. {
  3205. var eleFeature = document.querySelector(".home_cluster_ctn.home_ctn");
  3206. if (eleFeature)
  3207. {
  3208. var eleMarketing = document.querySelector(".home_ctn.marketingmessage_area");
  3209. if (eleMarketing)
  3210. {
  3211. insertBeforeElement(eleMarketing, eleFeature.firstElementChild);
  3212. }
  3213. insertBeforeElement(eleSpecial, eleFeature.firstElementChild);
  3214. }
  3215. }
  3216. }
  3217. function moveSaleReady()
  3218. {
  3219. var url = document.documentURI;
  3220. var patt = /^http[s]?:\/\/store.steampowered.com\/($|\?)/i;
  3221.  
  3222. if (patt.test(url))
  3223. {
  3224. attachOnReady(moveSale);
  3225. }
  3226. }
  3227. if (enableMoveSale) moveSaleReady();
  3228.  
  3229. /** Move sale section in main page
  3230. */
  3231. function redirectToLogin()
  3232. {
  3233. var url = document.documentURI;
  3234. var aOwner = document.querySelector("#global_actions > a.user_avatar");
  3235. var isLoggedIn = aOwner != null;
  3236. if (!isLoggedIn)
  3237. {
  3238. if (url.indexOf("/login/") > -1)
  3239. {
  3240. var eleRemember = document.querySelector("#remember_login");
  3241. if (eleRemember)
  3242. {
  3243. eleRemember.checked = true;
  3244. }
  3245. }
  3246. else
  3247. {
  3248. window.location = "https://steamcommunity.com/login/home/?goto=";
  3249. }
  3250. }
  3251. }
  3252. function redirectToLoginReady()
  3253. {
  3254. var url = document.documentURI;
  3255. var patt = /^http[s]?:\/\/steamcommunity.com\/(login\/home\/\?goto=)?$/i;
  3256.  
  3257. if (patt.test(url))
  3258. {
  3259. attachOnReady(redirectToLogin);
  3260. }
  3261. }
  3262. if (enableRedirectToLogin) redirectToLoginReady();
  3263.  
  3264. // ===== End Main =====
  3265.  
  3266. attachOnReady(function()
  3267. {
  3268. debugTime("ready");
  3269. var url = document.documentURI;
  3270. var patt = /^http[s]?:\/\/store.steampowered.com\/(app|sub|sale)\//i;
  3271.  
  3272. if (patt.test(url))
  3273. {
  3274. // Fix price position in old ES
  3275. {
  3276. GM_addStyle
  3277. (
  3278. " .game_area_dlc_row, .tab_item { display: inherit !important; } "
  3279. + " .game_purchase_action_bg { white-space: normal !important; } "
  3280. + " .sbh_regional_container { min-width: 220px; } "
  3281. + " .sbh_regional_container.sbh_regional_container_oldEs { right: 300px !important; } "
  3282. );
  3283. var time_fixPosEs = getUnixTimestamp();
  3284. var tmId_fixPosEs = setInterval(function ()
  3285. {
  3286. if (getUnixTimestamp() - time_fixPosEs > 10)
  3287. {
  3288. clearInterval(tmId_fixPosEs);
  3289. }
  3290. var elesContainer = document.querySelectorAll(".es_regional_container");
  3291. if (elesContainer.length > 0)
  3292. {
  3293. clearInterval(tmId_fixPosEs);
  3294. for (var i = 0; i < elesContainer.length; i++)
  3295. {
  3296. elesContainer[i].classList.add("sbh_regional_container");
  3297. }
  3298. if (document.querySelector(".es_regional_icon"))
  3299. {
  3300. // New ES
  3301. }
  3302. else
  3303. {
  3304. // Old ES
  3305. for (var i = 0; i < elesContainer.length; i++)
  3306. {
  3307. elesContainer[i].classList.add("sbh_regional_container_oldEs");
  3308. }
  3309. var elesOrg = document.querySelectorAll(".game_purchase_action .discount_original_price");
  3310. for (var i = 0; i < elesOrg.length; i++)
  3311. {
  3312. if (elesOrg[i].style.position == "relative")
  3313. {
  3314. elesOrg[i].style.position = "";
  3315. }
  3316. }
  3317. var elesPct = document.querySelectorAll(".game_purchase_action .discount_pct");
  3318. for (var i = 0; i < elesPct.length; i++)
  3319. {
  3320. if (elesPct[i].parentElement.style.paddingLeft == "25px")
  3321. {
  3322. elesPct[i].style.marginLeft = "-25px";
  3323. elesPct[i].style.marginRight = "25px";
  3324. }
  3325. }
  3326. }
  3327. }
  3328. }, 300);
  3329. }
  3330. }
  3331. });
  3332.  
  3333. attachOnLoad(function()
  3334. {
  3335. debugTime("load");
  3336.  
  3337. // Set currency for SIH
  3338. {
  3339. setTimeout(function()
  3340. {
  3341. var currency = marketCountries[GM_getValue("storeCountry", "US")] || "1";
  3342. var clientScript = " currencyId = " + currency + "; ";
  3343.  
  3344. var eleClientScript = document.createElement("script");
  3345. eleClientScript.innerHTML = clientScript;
  3346. document.head.appendChild(eleClientScript);
  3347. }, 500);
  3348. }
  3349. // Fix css for older browser
  3350. GM_addStyle(".carousel_container .arrow.left > div { background-position: 23px 0px; } ");
  3351. // Fix css for market transaction display
  3352. GM_addStyle("#market_transactions .transactionRowTitle { display: inline-block; padding-right: 5px; }");
  3353. // Fix css for ES tag
  3354. GM_addStyle(".recent_game .game_info .game_info_cap img.es_overlay { width: auto; }");
  3355. });
  3356.  
  3357. function testEvent()
  3358. {
  3359. /*
  3360. document.querySelector("#header_notification_link").addEventListener("DOMCharacterDataModified", function (e) {
  3361. debugTime("DOMCharacterDataModified");
  3362. });
  3363.  
  3364. document.querySelector("#header_notification_link").addEventListener("DOMSubtreeModified", function (e) {
  3365. debugTime("DOMSubtreeModified");
  3366. });
  3367. {
  3368. // select the target node
  3369. var target = document.querySelector("#header_notification_link");
  3370. // create an observer instance
  3371. var observer = new MutationObserver(function(mutations)
  3372. {
  3373. mutations.forEach(function(mutation)
  3374. {
  3375. debugTime("mutation: " + mutation.type);
  3376. });
  3377. });
  3378. // pass in the target node, as well as the observer options
  3379. observer.observe(target,
  3380. {
  3381. childList: true,
  3382. attributes: true,
  3383. characterData: true,
  3384. subtree: true,
  3385. attributeOldValue: true,
  3386. characterDataOldValue: true,
  3387. });
  3388. // later, you can stop observing
  3389. //observer.disconnect();
  3390. }
  3391. */
  3392. }
  3393. attachOnLoad(testEvent);
  3394.  
  3395. })();
  3396.  
  3397. // End