Automatically loads a batch of pages. Page 1 shows 1-10, Page 2 shows 11-20, etc.
// ==UserScript==
// @name AO3 Multi-Page Batch Loader
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Automatically loads a batch of pages. Page 1 shows 1-10, Page 2 shows 11-20, etc.
// @author Gemini
// @match https://archiveofourown.org/admin/tag_wranglers*
// @match https://archiveofourown.org/tags/*/wrangle*
// @license MIT
// ==/UserScript==
(async function() {
'use strict';
// --- Configuration ---
const BATCH_SIZE = 10;
const REQUEST_DELAY = 400;
// 1. Determine the current base page from URL
const urlParams = new URLSearchParams(window.location.search);
let currentPage = parseInt(urlParams.get('page')) || 1;
// 2. Calculate the range of pages to fetch
// Logic: Page 1 triggers loading of pages 2 through 10.
// Page 2 triggers loading of pages 11 through 20.
const startPage = (currentPage === 1) ? 2 : (currentPage - 1) * BATCH_SIZE + 1;
const endPage = currentPage * BATCH_SIZE;
const tableBody = document.querySelector("table tbody");
if (!tableBody) return;
// 3. Create a floating status indicator
const statusDiv = document.createElement('div');
statusDiv.style = "position:fixed; bottom:20px; right:20px; background:rgba(0,0,0,0.8); color:white; padding:10px; z-index:9999; border-radius:5px; font-size:12px; font-family: sans-serif;";
document.body.appendChild(statusDiv);
console.log(`🚀 Base page: ${currentPage}. Batch loading up to page ${endPage}...`);
for (let i = startPage; i <= endPage; i++) {
statusDiv.innerText = `Loading page ${i} of ${endPage}...`;
const fetchParams = new URLSearchParams(window.location.search);
fetchParams.set('page', i);
const targetUrl = `${window.location.pathname}?${fetchParams.toString()}`;
try {
const response = await fetch(targetUrl);
const text = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(text, 'text/html');
const newRows = doc.querySelectorAll("table tbody tr");
// Stop if no more data is found
if (newRows.length === 0) {
statusDiv.innerText = "No more data found.";
setTimeout(() => statusDiv.remove(), 2000);
break;
}
// Append new rows to the existing table
newRows.forEach(row => tableBody.appendChild(row));
} catch (e) {
console.error(`Failed to load page ${i}:`, e);
statusDiv.style.background = "red";
statusDiv.innerText = `Error loading page ${i}`;
}
// Rate-limiting delay
await new Promise(r => setTimeout(r, REQUEST_DELAY));
}
statusDiv.innerText = `✅ Batch load complete (up to page ${endPage})`;
setTimeout(() => statusDiv.remove(), 3000);
})();