Compare commits
14 Commits
v0.0.1-poc
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0086202aa5 | ||
|
|
3c3a7c8180 | ||
|
|
036cf4df77 | ||
|
|
a802f7952d | ||
|
|
7239df4613 | ||
|
|
16c7158763 | ||
|
|
8b89c267e3 | ||
|
|
6b6564ba01 | ||
| c0f11aa940 | |||
| 7b7f516b7a | |||
| 6a254ef49f | |||
| 9a0a848850 | |||
| 4be078da65 | |||
|
|
3625ea3bda |
18
README.md
@ -1,14 +1,8 @@
|
||||
# Steam Workshop Janitor
|
||||
_A userscript that makes browsing through thousands of mods viable_
|
||||
# Steam Janitor
|
||||
_A userscript that makes browsing mods viable_
|
||||
|
||||
## [Install 0.0.1](https://github.com/Jetsparrow/steam-workshop-janitor/raw/main/steam-workshop-janitor.user.js)
|
||||
[Demo, install links](https://jetsparrow.github.io/steam-janitor/)
|
||||
|
||||
**N.B.: this is a very crude, hacked together proof of concept. It doesn't even have a way to undo the filtering yet.**
|
||||
|
||||
## Filter mods
|
||||
|
||||
Adds a little "filter mod" X button to any workshop browse page. Use it, and you will no longer see the hundreds of miscellaneous translations to laguages you don't know, obsolete mods, etc.
|
||||
|
||||
## Endless scrolling
|
||||
|
||||
After the filter runs its course, you will be left with barely any mods. Wndless scrolling fixes that.
|
||||
* Adds a "hide" button to all items on the workshop browse page. Hides item forever, until unhidden.
|
||||
* Adds a "filter" checkbox to the top paging controls, allowing to switch between filtered and unfiltered view.
|
||||
* Adds endless scrolling to workshop browse pages.
|
||||
3
_config.yml
Normal file
@ -0,0 +1,3 @@
|
||||
theme: jekyll-theme-midnight
|
||||
title: Steam Janitor
|
||||
description: A userscript that makes browsing mods viable
|
||||
27
index.md
Normal file
@ -0,0 +1,27 @@
|
||||
<img src="https://user-images.githubusercontent.com/37241560/153679204-15e543d6-f45d-401c-90da-591694240515.png">
|
||||
|
||||
# [Steam Janitor v0.0.4-alpha - install](https://github.com/Jetsparrow/steam-janitor/raw/main/steam-janitor.user.js)
|
||||
_Requires a userscript extension for your browser, e.g. [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en)_
|
||||
|
||||
**N.B.: this is an early alpha. Tested only in Tampermonkey on Google Chrome**
|
||||
|
||||
# How to use
|
||||
Navigate to the browse tab of your game's workshop (`steamcommunity.com/workshop/browse/?appid=###`) and use the new buttons on the workshop items.
|
||||
<video src="https://user-images.githubusercontent.com/37241560/153673942-b35b53e9-4c88-4695-8631-855243251740.mp4" autoplay muted loop style="max-width: 480px;" ></video>
|
||||
|
||||
# Features
|
||||
## Filter unwanted items
|
||||
|
||||
A "hide" button is added to every item on a workshop browse page.
|
||||
Clicking it will hide the item forever - until you turn off the filter and unhide it.
|
||||
Translations to laguages you don't know, obsolete mods, gachimuchi memes, and mods that are just not quite your cup of tea - hide once and never see them again.
|
||||
|
||||
The "filter" checkbox at the top paging controls allows you to switch between the filtered and unfiltered view.
|
||||
|
||||
## Endless scrolling
|
||||
|
||||
After the filter runs its course, you will be left with barely any mods. Endless scrolling fixes that.
|
||||
|
||||
## Download button
|
||||
|
||||
Download the workshop item directly from the web as a .zip archive
|
||||
BIN
res/filter_toggle_closed.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/filter_toggle_open.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
res/janitor_download.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
res/janitor_download_hover.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
res/janitor_hide.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
res/janitor_hide_hover.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
res/janitor_unhide.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
res/janitor_unhide_hover.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
res/source/filter_toggle.psd
Normal file
BIN
res/source/janitor_buttons.psd
Normal file
289
steam-janitor.user.js
Normal file
@ -0,0 +1,289 @@
|
||||
// ==UserScript==
|
||||
// @name Steam Janitor
|
||||
// @namespace jetsparrow-steam-janitor
|
||||
// @author Jetsparrow
|
||||
// @description Hide unwanted user content in browse view, endless scrolling, downloads
|
||||
// @match *://*.steamcommunity.com/workshop/browse/*
|
||||
// @run-at document-end
|
||||
// @version 0.0.4
|
||||
// @grant GM_setValue
|
||||
// @grant GM_getValue
|
||||
// @grant GM_xmlhttpRequest
|
||||
// @grant GM_download
|
||||
// @connect ggntw.com
|
||||
// @downloadURL https://jetsparrow.github.io/steam-janitor/steam-janitor.user.js
|
||||
// ==/UserScript==
|
||||
|
||||
const addGlobalStyle = (doc, css) => {
|
||||
let head = doc.getElementsByTagName('head')[0];
|
||||
if (!head) return null;
|
||||
let style = document.createElement('style');
|
||||
style.type = 'text/css';
|
||||
style.innerHTML = css;
|
||||
head.appendChild(style);
|
||||
return style;
|
||||
}
|
||||
|
||||
const htmlToElement = (doc, html) => {
|
||||
var template = doc.createElement('template');
|
||||
template.innerHTML = html.trim();
|
||||
return template.content.firstChild;
|
||||
}
|
||||
|
||||
const onVisible = (element, callback) => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
callback();
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
},
|
||||
{ rootMargin: "0px 0px 200px 0px" }
|
||||
);
|
||||
|
||||
observer.observe(element);
|
||||
};
|
||||
|
||||
const selector = {
|
||||
PAGING_INFO: ".workshopBrowsePagingWithBG",
|
||||
ITEM_CONTAINER: ".workshopBrowseItems .workshopItemPreviewHolder",
|
||||
ITEMS_CONTAINER: ".workshopBrowseItems",
|
||||
ITEMS_HOVERS: ".workshopBrowseItems script",
|
||||
NEXT_BUTTON: ".workshopBrowsePagingControls .pagebtn:last-child",
|
||||
PAGINATOR: ".workshopBrowsePagingControls",
|
||||
PAGE_INFO: ".workshopBrowsePagingInfo",
|
||||
FOOTER: ".workshopBrowsePaging",
|
||||
};
|
||||
|
||||
const elemId = {
|
||||
scrollTarget: "footer",
|
||||
filterToggleCheckbox: "janitorFilterToggleCheckbox",
|
||||
filterToggleOn: "janitorFilterOnIcon",
|
||||
filterToggleOff: "janitorFilterOffIcon",
|
||||
};
|
||||
|
||||
const cssClass = {
|
||||
unhidden: "janitorItem",
|
||||
hiddenFiltered: "janitorItemHidden",
|
||||
hiddenUnfiltered: "janitorItemHiddenUnfiltered",
|
||||
hideButton: "janitorHideButton",
|
||||
showButton: "janitorShowButton",
|
||||
filterToggle: "janitorFilterToggle",
|
||||
downloadButton: "janitorDownloadButton"
|
||||
};
|
||||
|
||||
const resource = {
|
||||
iconEyeOpen:"https://jetsparrow.github.io/steam-janitor/res/filter_toggle_open.png",
|
||||
iconEyeClosed:"https://jetsparrow.github.io/steam-janitor/res/filter_toggle_closed.png",
|
||||
btnHide:"https://jetsparrow.github.io/steam-janitor/res/janitor_hide.png",
|
||||
btnHideHover:"https://jetsparrow.github.io/steam-janitor/res/janitor_hide_hover.png",
|
||||
btnUnhide:"https://jetsparrow.github.io/steam-janitor/res/janitor_unhide.png",
|
||||
btnUnhideHover:"https://jetsparrow.github.io/steam-janitor/res/janitor_unhide_hover.png",
|
||||
btnDownload:"https://jetsparrow.github.io/steam-janitor/res/janitor_download.png",
|
||||
btnDownloadHover:"https://jetsparrow.github.io/steam-janitor/res/janitor_download_hover.png",
|
||||
};
|
||||
|
||||
const janitorCss = `
|
||||
.${cssClass.filterToggle} * { vertical-align: middle; }
|
||||
|
||||
.${cssClass.hiddenFiltered} {display:none !important; }
|
||||
.${cssClass.hiddenUnfiltered} img {opacity: 0.25;}
|
||||
|
||||
.${cssClass.hideButton} {width:25px; height:25px;}
|
||||
.${cssClass.hiddenUnfiltered} .${cssClass.hideButton}:hover {background-image:url("${resource.btnUnhideHover}")}
|
||||
.${cssClass.hiddenUnfiltered} .${cssClass.hideButton} {background-image:url("${resource.btnUnhide}")}
|
||||
.${cssClass.unhidden} .${cssClass.hideButton}:hover {background-image:url("${resource.btnHideHover}")}
|
||||
.${cssClass.unhidden} .${cssClass.hideButton} {background-image:url("${resource.btnHide}")}
|
||||
.workshopItem .${cssClass.hideButton} { visibility: hidden; }
|
||||
.workshopItem:hover .${cssClass.hideButton} { visibility: visible; position: absolute; top: 4px; right: 6px;}
|
||||
|
||||
.${cssClass.downloadButton} {width:25px; height:25px;}
|
||||
.${cssClass.downloadButton}:hover {background-image:url("${resource.btnDownloadHover}")}
|
||||
.${cssClass.downloadButton} {background-image:url("${resource.btnDownload}")}
|
||||
.workshopItem .${cssClass.downloadButton} { visibility: hidden; }
|
||||
.workshopItem:hover .${cssClass.downloadButton} { visibility: visible; position: absolute; top: 4px; right: 35px;}
|
||||
`;
|
||||
|
||||
const setting = {
|
||||
filterEnabled: "janitorFilterEnabled"
|
||||
};
|
||||
|
||||
const defaultModData = () => {
|
||||
let d = new Object();
|
||||
d.hide = false;
|
||||
return d;
|
||||
}
|
||||
|
||||
const loadModData = (modId) => {
|
||||
var j = GM_getValue("modid:" + modId, "");
|
||||
return j == "" ? defaultModData() : JSON.parse(j);
|
||||
}
|
||||
|
||||
const saveModData = (modId, data) => GM_setValue("modid:" + modId, JSON.stringify(data));
|
||||
|
||||
|
||||
// Update classes on mod container when model changes
|
||||
const updateHiddenClass = (doc, modId, filterOn) => {
|
||||
var container = doc.getElementById(modId)?.parentElement?.parentElement;
|
||||
if (!container) return;
|
||||
const d = loadModData(modId);
|
||||
container.classList.remove(cssClass.unhidden);
|
||||
container.classList.remove(cssClass.hiddenFiltered);
|
||||
container.classList.remove(cssClass.hiddenUnfiltered);
|
||||
|
||||
if (!d.hide) container.classList.add(cssClass.unhidden);
|
||||
else if (filterOn) container.classList.add(cssClass.hiddenFiltered);
|
||||
else container.classList.add(cssClass.hiddenUnfiltered);
|
||||
}
|
||||
|
||||
// When pressing the hide/unhide button on mod container
|
||||
const toggleHidden = (doc, modId) => {
|
||||
var d = loadModData(modId);
|
||||
d.hide = !d.hide;
|
||||
saveModData(modId, d);
|
||||
const filterOn = GM_getValue(setting.filterEnabled);
|
||||
updateHiddenClass(doc, modId, filterOn);
|
||||
}
|
||||
|
||||
// When pressing the download button on mod container
|
||||
const downloadMod = (doc, modId) => {
|
||||
const id = modId.replace("sharedfile_", "");
|
||||
GM_xmlhttpRequest(
|
||||
{
|
||||
url:"https://api.ggntw.com/steam.request",
|
||||
method: "POST",
|
||||
data: JSON.stringify(
|
||||
{
|
||||
url:"https://steamcommunity.com/sharedfiles/filedetails/?id=" + id
|
||||
}),
|
||||
headers:
|
||||
{
|
||||
"Content-type": "application/json; charset=UTF-8"
|
||||
},
|
||||
onload: function(response)
|
||||
{
|
||||
if (response.status>299) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
const res = JSON.parse(response.responseText);
|
||||
console.log(res);
|
||||
const name = res.url.substring(res.url.lastIndexOf('/') + 1);
|
||||
GM_download(res.url, name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Add hide butons to mod container
|
||||
const addJanitorButtons = (doc, container, id) => {
|
||||
const hideButton = htmlToElement(doc, `<div class="${cssClass.hideButton}"> </>`);
|
||||
hideButton.onclick = (e) => {
|
||||
e.cancelBubble = true;
|
||||
toggleHidden(document, id);
|
||||
};
|
||||
container.append(hideButton);
|
||||
|
||||
const downloadButton = htmlToElement(doc, `<div class="${cssClass.downloadButton}"> </>`);
|
||||
downloadButton.onclick = (e) => {
|
||||
e.cancelBubble = true;
|
||||
downloadMod(document, id);
|
||||
};
|
||||
container.append(downloadButton);
|
||||
}
|
||||
|
||||
// Update all loaded mod containers, update their visibility and add janitor buttons if necessary
|
||||
const processContainers = (doc) => {
|
||||
const filterOn = GM_getValue(setting.filterEnabled);
|
||||
for (var el of doc.querySelectorAll(selector.ITEM_CONTAINER)){
|
||||
const container = el.parentElement.parentElement;
|
||||
const id = el.id;
|
||||
updateHiddenClass(doc, id, filterOn);
|
||||
|
||||
if (container.janitorButtonsAdded) continue;
|
||||
container.janitorButtonsAdded = true;
|
||||
addJanitorButtons(doc, container, id);
|
||||
}
|
||||
}
|
||||
|
||||
const loadNextPage = (url) => {
|
||||
fetch(url, { credentials: "same-origin" })
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const newDoc = parser.parseFromString(html, "text/html");
|
||||
processContainers(newDoc);
|
||||
|
||||
const newMods = newDoc.querySelectorAll(selector.ITEM_CONTAINER);
|
||||
const modContainer = document.querySelector(selector.ITEMS_CONTAINER);
|
||||
for (const mod of newMods) {
|
||||
const container = mod.parentElement.parentElement;
|
||||
modContainer.appendChild(container);
|
||||
}
|
||||
|
||||
const scripts = newDoc.querySelectorAll(selector.ITEMS_HOVERS);
|
||||
for (const newScript of scripts){
|
||||
const matches = newScript.innerHTML.match(/(sharedfile_\d+)/);
|
||||
if (matches.length < 1) continue;
|
||||
const data = loadModData(matches[0]);
|
||||
if (data.hide) continue;
|
||||
eval("try{ "+ newScript.innerHTML + " } catch {} ");
|
||||
}
|
||||
|
||||
const nextUrl = newDoc.querySelector(selector.NEXT_BUTTON)?.getAttribute("href");
|
||||
const footer = document.getElementById(elemId.scrollTarget);
|
||||
if (nextUrl) onVisible(footer, loadNextPage.bind(null, nextUrl));
|
||||
window.history.pushState("", "", url);
|
||||
});
|
||||
};
|
||||
|
||||
// When the global filter toggle is pressed
|
||||
function toggleFilter(checkbox) {
|
||||
GM_setValue(setting.filterEnabled, checkbox.checked);
|
||||
const doc = checkbox.ownerDocument;
|
||||
doc.getElementById(elemId.filterToggleOff).hidden = checkbox.checked;
|
||||
doc.getElementById(elemId.filterToggleOn).hidden = !checkbox.checked;
|
||||
processContainers(doc);
|
||||
}
|
||||
|
||||
// main
|
||||
(() => {
|
||||
const load = () => {
|
||||
addGlobalStyle(document, janitorCss);
|
||||
|
||||
document.querySelector(selector.PAGE_INFO)?.remove();
|
||||
const filterToggleRoot = document.querySelector(selector.PAGING_INFO);
|
||||
const toggle = htmlToElement(document, `
|
||||
<div class="${cssClass.filterToggle}">
|
||||
|
||||
<input type="checkbox" id="${elemId.filterToggleCheckbox}">
|
||||
|
||||
<label for="${elemId.filterToggleCheckbox}">
|
||||
<img src="${resource.iconEyeOpen}" id="${elemId.filterToggleOff}">
|
||||
<img src="${resource.iconEyeClosed}" id="${elemId.filterToggleOn}">
|
||||
</label>
|
||||
|
||||
</div>
|
||||
`);
|
||||
const checkbox = toggle.children[0];
|
||||
checkbox.checked = GM_getValue(setting.filterEnabled, true);
|
||||
checkbox.onclick = () => toggleFilter(checkbox);
|
||||
filterToggleRoot.prepend(toggle);
|
||||
toggleFilter(checkbox);
|
||||
processContainers(document);
|
||||
|
||||
const nextUrl = document.querySelector(selector.NEXT_BUTTON)?.getAttribute("href");
|
||||
if (!nextUrl) {
|
||||
console.error(`Could not find nextUrl through "${selector.NEXT_BUTTON}"`);
|
||||
return;
|
||||
}
|
||||
|
||||
loadNextPage(nextUrl);
|
||||
|
||||
document.querySelector(selector.PAGINATOR)?.remove();
|
||||
|
||||
};
|
||||
|
||||
load();
|
||||
})();
|
||||
@ -1,156 +0,0 @@
|
||||
// ==UserScript==
|
||||
// @name Steam Workshop Janitor
|
||||
// @description Hide unwanted mods in the browse view, endless scrolling
|
||||
// @match *://*.steamcommunity.com/workshop/browse/*
|
||||
// @run-at document-end
|
||||
// @version 0.0.1
|
||||
// @grant GM_setValue
|
||||
// @grant GM_getValue
|
||||
// @updateURL https://raw.githubusercontent.com/Jetsparrow/steam-workshop-janitor/main/steam-workshop-janitor.js
|
||||
// @downloadURL https://raw.githubusercontent.com/Jetsparrow/steam-workshop-janitor/main/steam-workshop-janitor.js
|
||||
// ==/UserScript==
|
||||
|
||||
const selectors = {
|
||||
ITEM_CONTAINER: ".workshopBrowseItems .workshopItemPreviewHolder",
|
||||
ITEMS_CONTAINER: ".workshopBrowseItems",
|
||||
ITEMS_HOVERS: ".workshopBrowseItems script",
|
||||
NEXT_BUTTON: ".workshopBrowsePagingControls .pagebtn:last-child",
|
||||
PAGINATOR: ".workshopBrowsePagingControls"
|
||||
};
|
||||
|
||||
function htmlToElement(doc, html) {
|
||||
var template = doc.createElement('template');
|
||||
html = html.trim(); // Never return a text node of whitespace as the result
|
||||
template.innerHTML = html;
|
||||
return template.content.firstChild;
|
||||
}
|
||||
|
||||
const on_visible = (element, callback) => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
callback();
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
},
|
||||
{ rootMargin: "0px 0px -200px 0px" }
|
||||
);
|
||||
|
||||
observer.observe(element);
|
||||
};
|
||||
|
||||
function defaultModData()
|
||||
{
|
||||
var res = new Object();
|
||||
res.hide = false;
|
||||
return res;
|
||||
}
|
||||
function loadModData(id){
|
||||
var j = GM_getValue("modid:" + id, "");
|
||||
return j == "" ? defaultModData() : JSON.parse(j);
|
||||
}
|
||||
function saveModData(id, data){
|
||||
GM_setValue("modid:" + id, JSON.stringify(data));
|
||||
}
|
||||
|
||||
|
||||
function hideId(id){
|
||||
var d = loadModData(id);
|
||||
d.hide = true;
|
||||
saveModData(id, d);
|
||||
var elem = document.getElementById(id);
|
||||
if (elem){
|
||||
elem.parentElement.parentElement.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function sweepHidden(doc){
|
||||
var containers = doc.querySelectorAll(selectors.ITEM_CONTAINER);
|
||||
for (var container of containers)
|
||||
{
|
||||
var id = container.id;
|
||||
var data = loadModData(id);
|
||||
if (data.hide){
|
||||
container.parentElement.parentElement.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addButtonToElement(doc, elem){
|
||||
var janitorButton = htmlToElement(doc, `<a>X</a>`)
|
||||
let id = elem.id;
|
||||
janitorButton.onclick = function(){hideId(id);};
|
||||
elem.parentElement.parentElement.prepend(janitorButton);
|
||||
}
|
||||
|
||||
function addButtons(doc){
|
||||
var containers = doc.querySelectorAll(selectors.ITEM_CONTAINER);
|
||||
for (var container of containers){
|
||||
addButtonToElement(doc, container);
|
||||
}
|
||||
}
|
||||
|
||||
const load_next = (url) => {
|
||||
fetch(url, { credentials: "same-origin" })
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const newDoc = parser.parseFromString(html, "text/html");
|
||||
|
||||
sweepHidden(newDoc);
|
||||
addButtons(newDoc);
|
||||
|
||||
const newPaginator = newDoc.querySelector(selectors.PAGINATOR);
|
||||
const oldPaginator = document.querySelector(selectors.PAGINATOR);
|
||||
const pagParent = oldPaginator.parentElement;
|
||||
oldPaginator.remove();
|
||||
pagParent.append(newPaginator);
|
||||
|
||||
const newMods = newDoc.querySelectorAll(selectors.ITEM_CONTAINER);
|
||||
const lastMod = newMods[newMods.length - 1];
|
||||
|
||||
const modContainer = document.querySelector(selectors.ITEMS_CONTAINER);
|
||||
for (var mod of newMods) {
|
||||
var container = mod.parentElement.parentElement;
|
||||
modContainer.appendChild(container);
|
||||
}
|
||||
|
||||
const scripts = newDoc.querySelectorAll(selectors.ITEMS_HOVERS);
|
||||
for (var newScript of scripts){
|
||||
var matches = newScript.innerHTML.match(/(sharedfile_\d+)/);
|
||||
if (matches.length < 1) continue;
|
||||
var data = loadModData(matches[0]);
|
||||
if (data.hide) continue;
|
||||
eval("try{ "+ newScript.innerHTML + " } catch {} ");
|
||||
}
|
||||
|
||||
const nextButton = document.querySelector(selectors.NEXT_BUTTON);
|
||||
|
||||
if (lastMod && nextButton) {
|
||||
const nextUrl = nextButton.getAttribute("href");
|
||||
on_visible(lastMod, load_next.bind(null, nextUrl));
|
||||
}
|
||||
|
||||
window.history.pushState("", "", url);
|
||||
});
|
||||
};
|
||||
|
||||
(() => {
|
||||
const load = () => {
|
||||
const next_button = document.querySelector(selectors.NEXT_BUTTON);
|
||||
|
||||
if (!next_button) {
|
||||
console.error(`Could not find "${selectors.NEXT_BUTTON}"`);
|
||||
return;
|
||||
}
|
||||
sweepHidden(document);
|
||||
addButtons(document);
|
||||
|
||||
const nextUrl = next_button.getAttribute("href");
|
||||
load_next(nextUrl);
|
||||
};
|
||||
|
||||
load();
|
||||
})();
|
||||