Steam Badge Helper

Add various features to Steam focus on Trading Cards and Badges

当前为 2017-11-14 提交的版本,查看 最新版本

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