NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @namespace https://openuserjs.org/users/Seishiin // @name SteamWorkshopSearch // @description Allows you to search for specific mods in your list of subscribed items // @author Seishiin // @version 1.5 // @copyright 2019, Seishiin // @license MIT // @include /https:\/\/steamcommunity\.com\/id\/.*\/myworkshopfiles\/\?appid=\d+.*&browsefilter=mysubscriptions.*/ // @icon https://img.icons8.com/color/48/000000/steam.png // @grant none // @noframes // ==/UserScript== (function () { let iframeNextPage = null; let iframeAllMods = null; let currentPage = 1; const leftContents = document.getElementById("leftContents"); let modList = null; const css = ` #searchBar { width: 251px; padding-left: 8px; padding-right: 8px; background: #101822; border-color: #30485c; } #loader { width: 16px; height: 16px; position: relative; bottom: 24px; right: 3px; float: right; border: 4px solid; border-radius: 50%; border-color: rgb(160, 220, 240) rgb(65, 95, 125) rgb(65, 95, 125); animation: spin 2s linear infinite; } @keyframes spin { 0% {transform: rotate(0deg);} 100% {transform: rotate(360deg);} } `; /////////////////////// // Utility functions // /////////////////////// RegExp.escape = function (s) { return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); }; function getTotalPages() { let pageinfo = document.getElementsByClassName("workshopBrowsePagingInfo")[0].innerText; pageinfo = pageinfo.substring(pageinfo.indexOf("of") + 3, pageinfo.length); pageinfo = pageinfo.substring(0, pageinfo.indexOf("entries") - 1); // totalPages = Math.ceil(pageinfo / 30); return Math.ceil(pageinfo / 30); } ////////////////////// // Search functions // ////////////////////// function searchMods(e) { let searchTerm = e.srcElement.value; let modsFound = 0; // escape special characters so it doesn't break the search searchTerm = RegExp.escape(searchTerm); // hide all mods currently displayed for (let i = 0; i < leftContents.childElementCount; i++) { if (leftContents.children[i].className.includes("workshopItemSubscription")) { leftContents.children[i].style.display = "none"; } } // add mods matching the search string for (let i = 0; i < modList.length; i++) { modsFound = getSearchedMods(modList[i], searchTerm, modsFound); } // update the page info to display the amount of items shown correctly document.getElementsByClassName("workshopBrowsePagingInfo")[0].innerText = "Showing " + modsFound + " of " + modList.length + " entries"; modsFound = 0; } function getSearchedMods(mod, searchTerm, modsFound) { // get the title of the mod let modTitle = mod.children[1].children[2].children[0].children[0].innerText; // show only divs containing the search term let regex = new RegExp(searchTerm, "i"); if (regex.test(modTitle)) { document.getElementById(mod.id).style.display = ""; modsFound++; } return modsFound; } ////////////////////////////////////// // Modlist initialization functions // ////////////////////////////////////// function initializeModList(totalPages) { // create an iframe to load the next page with mods iframeNextPage = document.createElement("iframe"); iframeNextPage.style.display = "none"; // go through each page and insert all mods into "iframeAllMods" iframeNextPage.addEventListener("load", function () { let currentModList = this.contentWindow.document.getElementsByClassName("workshopItemSubscription"); for (let i = 0; i < currentModList.length; i++) { iframeAllMods.contentWindow.document.body.append(currentModList[i]); } // append the modlist after it has beend completely initialized if (currentPage > totalPages) { appendModList(); } if (currentPage <= totalPages) { updateIFrameSource(); } }); document.body.appendChild(iframeNextPage); // create an iframe to store all mods loaded in "iframeNextPage" iframeAllMods = document.createElement("iframe"); iframeAllMods.style.display = "none"; iframeAllMods.src = "about:blank"; document.body.appendChild(iframeAllMods); } // change the url of "iframeNextPage" to the next page function updateIFrameSource() { let baseURL if (iframeNextPage.baseURI.includes("&p=")) baseURL = iframeNextPage.baseURI.substring(0, iframeNextPage.baseURI.indexOf("&p=")); else baseURL = iframeNextPage.baseURI; iframeNextPage.src = baseURL + "&p=" + currentPage + "&numperpage=30"; currentPage++; } function appendModList() { // load mods into the list modList = iframeAllMods.contentWindow.document.getElementsByClassName("workshopItemSubscription"); // remove all mods from the list for (let i = 0; i < leftContents.childElementCount; i++) { if (leftContents.children[i].className.includes("workshopItemSubscription")) { // if we do it only once it doesn't work leftContents.children[i].remove(); leftContents.children[i].remove(); } } // insert all mods from modList into the website // modList = iframeAllMods.contentWindow.document.getElementsByClassName("workshopItemSubscription"); for (let i = 0; i < modList.length; i++) { // if we don't clone this, the corresponding element gets removed from modList let clone = modList[i].cloneNode(true); leftContents.append(clone); } // update the paging info document.getElementsByClassName("workshopBrowsePagingInfo")[0].innerText = "Showing " + modList.length + " of " + modList.length + " entries"; // activate the searchbar and hide the loader after the modlist is loaded document.getElementById("searchBar").disabled = false; document.getElementById("loader").style.display = "none"; } //////////////////////////////// // DOM modification functions // //////////////////////////////// function hideMods() { for (let i = 0; i < leftContents.childElementCount; i++) { if (leftContents.children[i].className.includes("workshopItemSubscription")) { leftContents.children[i].style.display = "none" } } } // remove the workshop banner and paginators + hrs, update the paging info function modifyDivs() { document.getElementsByClassName("workshopBrowsePagingControls")[0].style.display = "none"; document.getElementsByClassName("workshopBrowsePaging")[0].remove(); document.getElementsByClassName("greyHR2")[1].remove(); document.getElementsByClassName("greyHR2")[0].remove(); document.getElementsByClassName("workshopBrowsePagingWithBG")[0].style.marginBottom = "11px"; document.getElementsByClassName("workshopBrowsePagingInfo")[0].innerText = "Loading modlist..."; } function addSearchbar() { let searchBar = document.createElement("input"); searchBar.className = "searchTextContainer"; searchBar.id = "searchBar" searchBar.disabled = true; searchBar.addEventListener("input", searchMods); document.getElementsByClassName("rightSectionHolder")[4].appendChild(searchBar); } function addLoader() { // keyframe animation let style = document.createElement('style'); style.type = 'text/css'; style.appendChild(document.createTextNode(css)); document.head.appendChild(style); // loader let loader = document.createElement("div"); loader.id = "loader"; document.getElementsByClassName("workshopBrowsePagingWithBG")[0].appendChild(loader); } ////////////////// // Start script // ////////////////// function init() { // get the total amount of page if showing 30 items per page let totalPages = getTotalPages(); // remove and update some divs modifyDivs(); // hide mods before loading the modlist to avoid confusion hideMods(); document.getElementsByClassName("rightSectionTopTitle")[0].innerText = "Search for mods:"; document.getElementsByClassName("rightDetailsBlock")[3].remove(); addSearchbar(); // inform the user that the modlist is still loading addLoader(); // after all that is done start loading the mods initializeModList(totalPages); } window.addEventListener('load', function () { init() }, false); })();