您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds listed pages to a Navbox upon request with UI, CSRF token, adaptive speed, duplicate checker, and highlighted links option.
当前为
// ==UserScript== // @name OSRS Wiki Auto-Navbox with UI, Adaptive Speed, Duplicate Checker (Slow Version) // @namespace https://github.com/Nick2bad4u/UserStyles // @version 4.8 // @description Adds listed pages to a Navbox upon request with UI, CSRF token, adaptive speed, duplicate checker, and highlighted links option. // @author Nick2bad4u // @match https://oldschool.runescape.wiki/* // @match https://runescape.wiki/* // @match https://*.runescape.wiki/* // @match https://api.runescape.wiki/* // @match https://classic.runescape.wiki/* // @match *://*.runescape.wiki/* // @grant GM_xmlhttpRequest // @icon https://www.google.com/s2/favicons?sz=64&domain=oldschool.runescape.wiki // @license UnLicense // ==/UserScript== (function() { 'use strict'; const versionNumber = '4.8'; let navboxName = ''; let pageLinks = []; let selectedLinks = []; let currentIndex = 0; let csrfToken = ''; let isCancelled = false; let isRunning = false; let requestInterval = 10000; const maxInterval = 20000; const excludedPrefixes = ["Template:", "File:", "Navbox:", "Module:", "RuneScape:", "Update:", "Exchange:", "RuneScape:", "User:", "Help:"]; let actionLog = []; // Track actions for summary let existingNavboxes = []; // Stores existing navboxes function addButtonAndProgressBar() { console.log("Adding button and progress bar to the UI."); const container = document.createElement('div'); container.id = 'Navbox-ui'; container.style = `position: fixed; bottom: 20px; right: 20px; z-index: 1000; background-color: #2b2b2b; color: #ffffff; padding: 12px; border: 1px solid #595959; border-radius: 8px; font-family: Arial, sans-serif; width: 250px;`; const startButton = document.createElement('button'); startButton.textContent = 'Start Categorizing'; startButton.style = `background-color: #4caf50; color: #fff; border: none; padding: 6px 12px; border-radius: 5px; cursor: pointer;`; startButton.onclick = promptnavboxName; container.appendChild(startButton); const cancelButton = document.createElement('button'); cancelButton.textContent = 'Cancel'; cancelButton.style = `background-color: #d9534f; color: #fff; border: none; padding: 6px 12px; border-radius: 5px; cursor: pointer; margin-left: 10px;`; cancelButton.onclick = cancelNavbox; container.appendChild(cancelButton); const progressBarContainer = document.createElement('div'); progressBarContainer.style = `width: 100%; margin-top: 10px; background-color: #3d3d3d; height: 20px; border-radius: 5px; position: relative;`; progressBarContainer.id = 'progress-bar-container'; const progressBar = document.createElement('div'); progressBar.style = `width: 0%; height: 100%; background-color: #4caf50; border-radius: 5px;`; progressBar.id = 'progress-bar'; progressBarContainer.appendChild(progressBar); const progressText = document.createElement('span'); progressText.id = 'progress-text'; progressText.style = `position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 12px; color: #ffffff; white-space: nowrap; overflow: visible; text-align: center;`; progressBarContainer.appendChild(progressText); container.appendChild(progressBarContainer); document.body.appendChild(container); } function promptnavboxName() { navboxName = prompt("Enter the Navbox name you'd like to add:"); console.log("Navbox name entered:", navboxName); if (!navboxName) { alert("Navbox name is required."); return; } fetchExistingNavboxes(navboxName, () => { getPageLinks(); if (pageLinks.length === 0) { alert("No pages found to Navbox."); console.log("No pages found after filtering."); return; } displayPageSelectionPopup(); }); } // Function to fetch all existing navboxes function fetchExistingNavboxes(navboxName, callback) { const apiUrl = `https://oldschool.runescape.wiki/api.php?action=query&list=allpages&apprefix=Navbox:${navboxName}&apnamespace=10&format=json`; GM_xmlhttpRequest({ method: 'GET', url: apiUrl, onload(response) { const responseJson = JSON.parse(response.responseText); existingNavboxes = responseJson.query.allpages.map(page => page.title); console.log("Existing navboxes fetched:", existingNavboxes); callback(); } }); } // Function to check for highlighted text function getHighlightedText() { const selection = window.getSelection(); if (selection.rangeCount > 0) { const container = document.createElement('div'); for (let i = 0; i < selection.rangeCount; i++) { container.appendChild(selection.getRangeAt(i).cloneContents()); } return container.innerHTML; } return ''; } // Modify getPageLinks to consider highlighted text function getPageLinks() { let contextElement = document.querySelector('#mw-content-text'); const highlightedText = getHighlightedText(); if (highlightedText) { const tempContainer = document.createElement('div'); tempContainer.innerHTML = highlightedText; contextElement = tempContainer; } pageLinks = Array.from(new Set( Array.from(contextElement.querySelectorAll('a')) .map(link => link.getAttribute('href')) .filter(href => href && href.startsWith('/w/')) .map(href => decodeURIComponent(href.replace('/w/', ''))) .filter(page => !excludedPrefixes.some(prefix => page.startsWith(prefix)) && !page.includes('?') && !page.includes('/') && !page.includes('#') ) )); console.log("Filtered unique page links:", pageLinks); } function displayPageSelectionPopup() { // Display page selection code (same as previous) } function startNavbox() { console.log("Starting Navbox process."); isCancelled = false; isRunning = true; currentIndex = 0; document.getElementById('progress-bar-container').style.display = 'block'; fetchCsrfToken(() => processNextPage()); } function processNextPage() { if (isCancelled || currentIndex >= selectedLinks.length) { console.log("Navbox ended. Reason:", isCancelled ? "Cancelled" : "Completed"); isRunning = false; if (!isCancelled) { displayCompletionSummary(); } resetUI(); return; } const pageTitle = selectedLinks[currentIndex]; updateProgressBar(`Processing: ${pageTitle}`); console.log(`Processing page: ${pageTitle}`); addNavboxToPage(pageTitle, () => { currentIndex++; updateProgressBar(`Processed: ${pageTitle}`); setTimeout(processNextPage, requestInterval); }); } function addNavboxToPage(pageTitle, callback) { const categories = []; function fetchCategories(clcontinue) { const apiUrl = `https://oldschool.runescape.wiki/api.php?action=query&prop=categories|revisions&titles=${encodeURIComponent(pageTitle)}&rvprop=content&format=json${clcontinue ? `&clcontinue=${clcontinue}` : ''}`; GM_xmlhttpRequest({ method: 'GET', url: apiUrl, onload(response) { const responseJson = JSON.parse(response.responseText); const pageId = Object.keys(responseJson.query.pages)[0]; const page = responseJson.query.pages[pageId]; if (page.categories) { categories.push(...page.categories.map(cat => cat.title)); } if (responseJson.continue && responseJson.continue.clcontinue) { fetchCategories(responseJson.continue.clcontinue); } else { if (categories.length === 0) { console.log(`Skipped: '${pageTitle}' has no existing categories.`); actionLog.push(`Skipped: '${pageTitle}' has no existing categories.`); callback(); return; } const standardizedNavboxName = `Navbox:${navboxName}`; const alreadyNavboxd = categories.includes(standardizedNavboxName) || existingNavboxes.includes(standardizedNavboxName); if (alreadyNavboxd) { console.log(`Page '${pageTitle}' is already in the Navbox.`); actionLog.push(`Skipped: '${pageTitle}' already in '${navboxName}'`); callback(); } else { // Add navbox to page } } } }); } fetchCategories(); } function fetchCsrfToken(callback) { const apiUrl = 'https://oldschool.runescape.wiki/api.php?action=query&meta=tokens&type=csrf&format=json'; GM_xmlhttpRequest({ method: 'GET', url: apiUrl, onload(response) { const responseJson = JSON.parse(response.responseText); csrfToken = responseJson.query.tokens.csrftoken; console.log("CSRF token obtained."); callback(); } }); } function cancelNavbox() { isCancelled = true; } function displayCompletionSummary() { const summary = `Operation completed! Summary:\n${actionLog.join('\n')}`; alert(summary); actionLog = []; } function updateProgressBar(text) { const progress = ((currentIndex + 1) / selectedLinks.length) * 100; const progressBar = document.getElementById('progress-bar'); const progressText = document.getElementById('progress-text'); progressBar.style.width = `${progress}%`; progressText.textContent = `${text} (${currentIndex + 1}/${selectedLinks.length})`; } function resetUI() { document.getElementById('progress-bar-container').style.display = 'none'; document.getElementById('progress-bar').style.width = '0%'; document.getElementById('progress-text').textContent = ''; } addButtonAndProgressBar(); })();