您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add Twitter search links to AO3 works
当前为
// ==UserScript== // @name AO3 Vanity // @namespace https://github.com/serpentineegg/ao3-vanity // @version 0.1.1 // @description Add Twitter search links to AO3 works // @author serpentineegg // @match *://archiveofourown.org/* // @grant GM_addStyle // @run-at document-idle // @license MIT // ==/UserScript== (function () { 'use strict'; // Create Twitter search URL using twiiit.com function createTwitterSearchUrl(workUrl) { const cleanUrl = workUrl.replace('https://', ''); const encodedUrl = encodeURIComponent(cleanUrl); return `https://twiiit.com/search?f=tweets&q=${encodedUrl}`; } // Create a Twitter search link element function createTwitterLink(twitterUrl, linkText = 'Twitter') { const searchLink = document.createElement('a'); searchLink.href = twitterUrl; searchLink.target = '_blank'; searchLink.rel = 'noopener noreferrer'; searchLink.className = 'twitter-links'; searchLink.textContent = linkText; searchLink.title = 'Search Twitter for mentions of this work'; return searchLink; } // Add Twitter search info to any work stats section function addTwitterSearchToStats(workElement, workUrl) { // Check if already exists if (workElement.querySelector('.twitter-links')) { return; } const twitterUrl = createTwitterSearchUrl(workUrl); // Check if this is a work.meta.group first if (workElement.matches('dl.work.meta.group')) { // For work.meta.group, insert after the stats section const statsSection = workElement.querySelector('dd.stats'); if (statsSection) { const dt = document.createElement('dt'); dt.className = 'twitter-links'; dt.textContent = 'External Links:'; const dd = document.createElement('dd'); dd.className = 'twitter-links'; dd.appendChild(createTwitterLink(twitterUrl)); // Insert after the stats section const nextSibling = statsSection.nextSibling; if (nextSibling) { workElement.insertBefore(dt, nextSibling); workElement.insertBefore(dd, nextSibling); } else { workElement.appendChild(dt); workElement.appendChild(dd); } } return; } // Try different stats container locations for other elements let statsContainer = workElement.querySelector('dl.stats'); // If no dl.stats, try the nested stats in work meta if (!statsContainer) { statsContainer = workElement.querySelector('dd.stats dl.stats'); } if (!statsContainer) { return; } // Create the dd wrapper element const dd = document.createElement('dd'); dd.className = 'twitter-links'; dd.appendChild(createTwitterLink(twitterUrl, 'Twitter Links')); // For regular stats containers, append the wrapped link statsContainer.appendChild(dd); } // Process all work elements on any page function processAllWorks() { // Find all work elements with different selectors const workSelectors = [ 'li.work.blurb', // Standard work listings 'li.reading.work.blurb', // Reading history 'li.bookmark.blurb', // Bookmarks 'div.work.meta', // Individual work pages 'dl.work.meta.group', // Work metadata sections 'li.work' // Generic work items ]; workSelectors.forEach(selector => { const workElements = document.querySelectorAll(selector); workElements.forEach(workElement => { let workUrl = null; // Try to find the work URL in different ways const titleLink = workElement.querySelector('h4.heading a[href*="/works/"]'); if (titleLink) { workUrl = titleLink.href; } else if (selector === 'div.work.meta' || selector === 'dl.work.meta.group') { // For individual work pages workUrl = window.location.href; } else { // Try to find work ID in element attributes const workId = workElement.id?.match(/work[_-](\d+)/)?.[1] || workElement.className?.match(/work-(\d+)/)?.[1]; if (workId) { workUrl = `https://archiveofourown.org/works/${workId}`; } } if (workUrl) { addTwitterSearchToStats(workElement, workUrl); } }); }); } // Main initialization function function init() { // Process all works on any AO3 page processAllWorks(); // Set up observer for dynamically loaded content const observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.addedNodes.length > 0) { // Debounce the processing to avoid excessive calls clearTimeout(window.twitterSearchTimeout); window.twitterSearchTimeout = setTimeout(processAllWorks, 500); } }); }); // Observe the main content area const mainContent = document.querySelector('#main') || document.body; if (mainContent) { observer.observe(mainContent, { childList: true, subtree: true }); } } // Wait for page to load and initialize if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址