您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Consolidates AO3 userscript menus into a single, unified menu.
// ==UserScript== // @name AO3: Userscript Menu // @namespace https://github.com/ao3-userscripts // @version 1.1 // @description Consolidates AO3 userscript menus into a single, unified menu. // @author Blackbatcat // @license MIT // @match *://archiveofourown.org/* // @match *://*.archiveofourown.org/* // @grant none // @run-at document-end // ==/UserScript== // Inject AO3UserScriptMenu into the real page context for cross-script access (function injectMenuLibrary() { const src = ` (function() { if (window.AO3UserScriptMenu) return; const menuItems = []; function createMenu() { const nav = document.querySelector('ul.primary') || document.querySelector('nav.primary') || document.querySelector('#dashboard ul.actions'); if (!nav) return; let container = document.getElementById('ao3-userscript-menu'); if (!container) { container = document.createElement('li'); container.className = 'dropdown'; container.id = 'ao3-userscript-menu'; const title = document.createElement('a'); title.href = '#'; title.textContent = 'Userscripts'; container.appendChild(title); const menu = document.createElement('ul'); menu.className = 'menu dropdown-menu'; container.appendChild(menu); const searchItem = nav.querySelector('li.search'); if (searchItem) { nav.insertBefore(container, searchItem); } else { nav.appendChild(container); } } renderMenu(); } function renderMenu() { const menu = document.querySelector('#ao3-userscript-menu ul.menu'); if (!menu) return; menu.innerHTML = ''; menuItems.forEach(item => { const li = document.createElement('li'); const a = document.createElement('a'); a.href = '#'; a.textContent = item.label; a.addEventListener('click', e => { e.preventDefault(); item.onClick(); }); li.appendChild(a); menu.appendChild(li); }); if (menuItems.length > 0) { console.debug('[AO3UserScriptMenu] Rendered menu with', menuItems.length, 'items:', menuItems.map(i => i.label)); } else { console.debug('[AO3UserScriptMenu] Rendered menu with 0 items'); } } window.AO3UserScriptMenu = { register: function(item) { if (!item || typeof item.label !== 'string' || typeof item.onClick !== 'function') return; menuItems.push(item); console.debug('[AO3UserScriptMenu] Registered menu item:', item.label, '| Total:', menuItems.length, '| All:', menuItems.map(i => i.label)); if (!document.getElementById('ao3-userscript-menu')) { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', createMenu); } else { createMenu(); } } else { renderMenu(); } } }; })(); `; const script = document.createElement('script'); script.textContent = src; document.documentElement.appendChild(script); script.remove(); })();