AO3 Multi-Page Batch Loader

Automatically loads a batch of pages. Page 1 shows 1-10, Page 2 shows 11-20, etc.

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==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);

})();