// ==UserScript== // @name IsThereCouponForThis // @name:en IsThereCouponForThis // @namespace https://greasyfork.org/users/2205 // @description Отображает доступные купоны с помощью значка на странице магазина, на виджетах встроенных на форуме и в вишлисте. // @description:en Show coupons available on game steam store page, on wishlist and on widgets embedded in steamcommunity discussions. // @license Apache-2.0 // @author Rudokhvist // @include http://store.steampowered.com/* // @include https://store.steampowered.com/* // @connect pastebin.com // @run-at document-end // @version 2.8 // @grant GM.xmlhttpRequest // @grant GM_xmlhttpRequest // @language English // @downloadURL https://update.greasyfork.icu/scripts/38175/IsThereCouponForThis.user.js // @updateURL https://update.greasyfork.icu/scripts/38175/IsThereCouponForThis.meta.js // ==/UserScript== var debug = false; var getJSON = function(url, callback) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'json'; xhr.onload = function() { var status = xhr.status; if (status === 200) { callback(null, xhr.response); } else { callback(status, xhr.response); } }; xhr.send(); }; //rate limiting var getJSONRL = function(url, callback) { var Rate=1500; //ms between requests; var lastCall=localStorage.getItem ('ITCFTRateLimiter'); if (lastCall!==null) { if ((parseInt(lastCall) + Rate) > Date.now()) { window.setTimeout(function(){ getJSONRL(url,callback); },parseInt(lastCall)+Rate-Date.now()); } else { //already time getJSON(url,callback); localStorage.setItem('ITCFTRateLimiter',Date.now()); } } else { //first call ever getJSON(url,callback); localStorage.setItem('ITCFTRateLimiter',Date.now()); } }; var elemVisible =function( elem ) { if (elem===null) { return false; } else { return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); } }; var processWishlist = function (subids,couponMap,container){ var NewElement=document.createElement("span"); NewElement.setAttribute("style","font-size:18px;text-align: center;cursor:default;border-radius: 2px 2px 2px; border: 1px solid; user-select: none !important; pointer-events:auto !important; line-height: 1; margin-left: 5px; margin-right: 5px;"); NewElement.setAttribute("class","platform_img"); NewElement.setAttribute("tag","coupondata"); var foundcoupons=0; var foundlist=""; if (subids.length == 0){ if (debug) {console.log(' placeholder used');} NewElement.setAttribute("title","Getting data"); var img = document.createElement("img"); img.witdh = 16; img.height = 16; img.src = "https://steamcommunity-a.akamaihd.net/public/images/login/throbber.gif"; NewElement.appendChild(img); } else { for (var m=0;m0) { foundlist=foundlist+", "; } foundlist=foundlist+couponMap.get(subids[m]); foundcoupons++; } } if (foundcoupons>0) { NewElement.setAttribute("title","Coupons: "+foundlist); NewElement.appendChild(document.createTextNode("$")); } else { NewElement.setAttribute("title","No Coupons Found"); NewElement.appendChild(document.createTextNode("X")); } } var showplace=container.getElementsByClassName('platform_icons')[0]; if (showplace.querySelector('[tag="coupondata"]')!==null){ showplace.removeChild(showplace.querySelector('[tag="coupondata"]')); } var newchild=showplace.appendChild(NewElement); newchild.addEventListener('touchstart', function() { this.classList.add('touched'); }.bind(newchild)); }; var processWishlistRow = function(container,couponMap){ if (container.querySelector('[tag="coupondata"]')!==null){ return; } var subidContainer=container.querySelector('[name="subid"]'); var subids=[]; if (subidContainer===null) { if (debug) {console.log(new Date(Date.now()).toTimeString()+' We dont have subid for '+ container.getElementsByClassName('title')[0].innerText);} var appid=container.getAttribute('data-app-id'); (function(appid,subids,couponMap,container){ var cachedPackages=sessionStorage.getItem("ITCFTappid"+appid); if (cachedPackages===null) { if (debug) {console.log(new Date(Date.now()).toTimeString()+' Getting subids for '+ container.getElementsByClassName('title')[0].innerText);} processWishlist([],couponMap,container); getJSONRL('https://store.steampowered.com/api/appdetails?appids='+appid, function(err, data) { if (err !== null) { console.log(new Date(Date.now()).toTimeString()+' Something went wrong: ' + err); } else { subids.lenght=0; if (typeof(data[appid].data.packages)!=='undefined') { sessionStorage.setItem("ITCFTappid"+appid,data[appid].data.packages.toString()); for (var w=0;w3) { var subids=coupondata[3].split(','); for (var j=0; j0) { renewWishlist(couponMap); var mutationObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { mutation.addedNodes.forEach( function(currentValue, currentIndex, listObj) { if (currentValue.nodeType == Node.ELEMENT_NODE) { if (currentValue.className == 'wishlist_row'){ processWishlistRow(currentValue,couponMap); } } }); }); }); mutationObserver.observe(document.documentElement, { childList: true, subtree: true }); } } //main work },100); //SetInterval }, onerror: function() { console.log('Error.'); } }); }();