NovelUpdates Tag Sorter

Sort NovelUpdates series finder results by tag count

安裝腳本?
作者推薦腳本

您可能也會喜歡 NovelUpdates Tag Filter

安裝腳本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         NovelUpdates Tag Sorter
// @namespace    http://tampermonkey.net/
// @version      3.0
// @description  Sort NovelUpdates series finder results by tag count
// @author       MasuRii
// @match        https://www.novelupdates.com/series-finder/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // ========================================================================
    //  USER CONFIGURATION -  IMPORTANT!
    // ========================================================================
    //  Set this to 'true' to enable console logging for debugging,
    //  or 'false' to disable console logs for cleaner console output.
    const enableLogging = false; // <===== ADJUST THIS TO 'true' TO ENABLE LOGGING, 'false' TO DISABLE
    // ========================================================================
    //  END USER CONFIGURATION
    // ========================================================================

    // Function to count tags within a search result box
    function countTags(searchBox) {
        return searchBox.querySelectorAll('.genre[id="etagme"]').length;
    }

    // Function to perform GLOBAL sorting across all containers and preserve elements in first container
    function sortAllContainersGlobally() {
        const searchResultContainers = document.querySelectorAll('.w-blog-content.other');
        let allSearchResultBoxes = [];

        if (searchResultContainers.length > 0) {
            searchResultContainers.forEach(container => {
                // Collect ALL search result boxes from ALL containers
                const containerBoxes = Array.from(container.querySelectorAll('.search_main_box_nu'));
                allSearchResultBoxes = allSearchResultBoxes.concat(containerBoxes);
            });

            if (allSearchResultBoxes.length > 0) {
                const seriesData = [];

                allSearchResultBoxes.forEach(box => {
                    const tagCount = countTags(box);
                    seriesData.push({ box: box, tagCount: tagCount });
                });

                seriesData.sort((a, b) => b.tagCount - a.tagCount); // GLOBAL sort

                // Clear search result boxes from ALL containers, preserving other elements in the first container
                searchResultContainers.forEach((container, index) => {
                    const existingBoxes = Array.from(container.querySelectorAll('.search_main_box_nu'));
                    existingBoxes.forEach(box => {
                        container.removeChild(box); // Remove existing boxes individually
                    });
                    if (index === 0) {
                        if (enableLogging) console.log("Preserving elements in the first container.");
                        // Do NOT clear innerHTML of the first container
                    } else {
                        container.innerHTML = ''; // Clear innerHTML for subsequent containers
                    }
                });


                // Re-populate containers with sorted results
                let seriesIndex = 0;
                searchResultContainers.forEach(container => {
                    const containerBoxLimit = 10; // Example: Limit of 10 series per container (adjust as needed)
                    let boxCount = 0;
                    while (seriesIndex < seriesData.length && boxCount < containerBoxLimit) {
                        container.appendChild(seriesData[seriesIndex].box); // Append sorted box
                        seriesIndex++;
                        boxCount++;
                    }
                });

                if (enableLogging) console.log("NovelUpdates search results sorted by tag count (descending) - GLOBAL Sort (Preserve First Container Elements).");

            } else {
                if (enableLogging) console.log("No search results found in any container for sorting.");
            }
        } else {
            if (enableLogging) console.error("Could not find any search result containers (.w-blog-content.other) for sorting.");
        }
    }

    // Create the floating re-sort button (same as before, bottom right)
    function createSortButton() {
        const sortButton = document.createElement('button');
        sortButton.textContent = 'Sort by Tags';
        sortButton.className = 'btnrev review';

        sortButton.style.position = 'fixed';
        sortButton.style.bottom = '20px'; // Bottom right position
        sortButton.style.right = '20px';
        sortButton.style.zIndex = '1000';
        sortButton.style.padding = '8px 15px';
        sortButton.style.borderRadius = '5px';
        sortButton.style.cursor = 'pointer';

        sortButton.addEventListener('click', function(event) {
            event.preventDefault();
            if (enableLogging) console.log("Sort by Tags button clicked!");
            sortAllContainersGlobally(); // Call the GLOBAL sorting function
        });

        document.body.appendChild(sortButton);
    }

    // Perform initial GLOBAL sort on page load AND create the button
    sortAllContainersGlobally(); // Call GLOBAL sort on initial load
    createSortButton();

})();