您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在豆瓣/TMDb、MoviePilot、Emby Toolkit 中添加“搜索爱影”按钮(样式与逻辑隔离,无冲突合并版)
// ==UserScript== // @name 爱影搜索助手 · 三合一(豆瓣/TMDb + MoviePilot + Emby Toolkit) // @namespace http://tampermonkey.net/ // @version 3.1.3 // @description 在豆瓣/TMDb、MoviePilot、Emby Toolkit 中添加“搜索爱影”按钮(样式与逻辑隔离,无冲突合并版) // @author ccdfccgfddx+chill // @license MIT // @match https://*.douban.com/subject/* // @match https://www.themoviedb.org/* // @match https://域名+端口/* // @match https://域名+端口/* // @icon https://raw.githubusercontent.com/Chill-lucky/icons/main/ay.jpg // @grant GM_addStyle // @grant GM_openInTab // @run-at document-end // ==/UserScript== (() => { 'use strict'; const AY = { config: { searchUrl: 'https://subs.ayclub.vip/index.php?query=', winW: 1200, winH: 800 }, addStyle(id, css){ if(!document.getElementById(id)){ const s=document.createElement('style'); s.id=id; s.textContent=css; document.head.appendChild(s);} }, cleanTitle(raw){ if(!raw) return ''; let t=String(raw); t=t.replace(/\s*\(\d{4}\)\s*$/,''); [/第[一二三四五六七八九十百零0-9]+\s*季/gi,/第[一二三四五六七八九十百零0-9]+\s*部/gi,/Season\s*\d+/gi,/\bS\d+\b/gi,/Part\s*\d+/gi,/第\s*\d+\s*部分/gi].forEach(r=>t=t.replace(r,'')); [/完整版$/i,/未删减版$/i,/高清版$/i,/蓝光版$/i,/国语版$/i,/粤语版$/i,/中文字幕$/i,/英文字幕$/i,/双语字幕$/i,/抢先版$/i,/TC版$/i,/TS版$/i,/HD版$/i,/BD版$/i,/DVD版$/i,/超清版$/i,/4K版$/i,/1080P$/i,/720P$/i].forEach(r=>t=t.replace(r,'')); t=t.replace(/[【】\[\]{}()《》「」『』"“”'‘’]/g,' ').replace(/\s+/g,' ').replace(/^\s+|\s+$/g,''); t=t.replace(/\s*[-—~–]\s*$/,'').replace(/^\.+|\.+$/g,''); return t.trim(); }, searchAy(title){ const q = AY.cleanTitle(title); if(!q){ alert('无法获取标题信息'); return; } const url = `${AY.config.searchUrl}${encodeURIComponent(q)}`; if (typeof GM_openInTab === 'function'){ GM_openInTab(url, {active:true, insert:true, setParent:true}); return; } const left=Math.max(0,(screen.width-AY.config.winW)/2), top=Math.max(0,(screen.height-AY.config.winH)/2); const features=[`width=${AY.config.winW}`,`height=${AY.config.winH}`,`left=${left}`,`top=${top}`,'scrollbars=yes','resizable=yes','toolbar=no','menubar=no','location=no','status=no'].join(','); const w=window.open(url,'_blank',features); if(!w) location.href=url; }, onReady(fn){ if(document.readyState==='loading') document.addEventListener('DOMContentLoaded', fn); else setTimeout(fn,0); } }; // A. 豆瓣 / TMDb (function(){ const isDouban=/douban\.com\/subject\//.test(location.href); const isTMDb=/themoviedb\.org/.test(location.host); if(!isDouban && !isTMDb) return; AY.addStyle('ay-style-dt', ` .ay-dt-btn{background:linear-gradient(135deg,#5d78ff 0%,#3b5bdb 100%);color:#fff;border:none;border-radius:6px;padding:8px 14px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s ease;box-shadow:0 2px 6px rgba(93,120,255,.3);display:inline-flex;align-items:center;gap:6px;margin-left:12px;white-space:nowrap;vertical-align:middle;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;} .ay-dt-btn::before{content:"🔍";font-size:16px} .ay-dt-btn:hover{background:linear-gradient(135deg,#4c6ef5 0%,#364fc7 100%);box-shadow:0 4px 12px rgba(93,120,255,.4);transform:translateY(-2px)} .ay-dt-btn.added{animation:ay-dt-fade .3s ease-out} @keyframes ay-dt-fade{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}} .ay-dt-card-btn{position:absolute;bottom:10px;right:10px;background:linear-gradient(135deg,#5d78ff 0%,#3b5bdb 100%);color:#fff;border:none;border-radius:5px;padding:6px 12px;font-size:12px;font-weight:500;cursor:pointer;transition:all .2s ease;box-shadow:0 2px 8px rgba(0,0,0,.3);z-index:1000;opacity:0;transform:translateY(10px);pointer-events:none;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;} .card.style_1:hover .ay-dt-card-btn{opacity:1;transform:translateY(0);pointer-events:auto} .subject-title .ay-dt-btn{margin-left:15px} [data-testid="hero-title-block__title"] + .ay-dt-btn{margin-left:15px} `); function isTMDbDetail(){ return /^\/(movie|tv|tv-show)\/\d+/.test(location.pathname); } function init(){ if(isDouban) initDouban(); if(isTMDb) (isTMDbDetail()? initTMDbDetail() : initTMDbCards()); } function initDouban(){ const add=()=>{ const titleEl=document.querySelector('[property="v:itemreviewed"]'); const yearEl=document.querySelector('.year'); if(titleEl && yearEl && !document.querySelector('.ay-dt-btn')) mountBtnAfter(titleEl, yearEl.nextSibling, titleEl.textContent.trim()); }; new MutationObserver(add).observe(document.body,{childList:true,subtree:true}); add(); } function initTMDbDetail(){ const run=()=>{ const el=document.querySelector('[data-testid="hero-title-block__title"]')||document.querySelector('.title h2')||document.querySelector('h2.title'); if(el && !el.nextElementSibling?.classList?.contains('ay-dt-btn')) mountBtnAfter(el, null, extractTMDbTitle(el)); }; new MutationObserver(run).observe(document.body,{childList:true,subtree:true}); setTimeout(run,500); } function initTMDbCards(){ const process=()=>{ document.querySelectorAll('.card.style_1').forEach(card=>{ if(card.hasAttribute('data-ay-dt')) return; card.setAttribute('data-ay-dt','1'); card.style.position='relative'; card.addEventListener('mouseenter', ()=> setTimeout(()=> addBtnToCard(card), 300)); }); }; new MutationObserver(process).observe(document.body,{childList:true,subtree:true}); setTimeout(process,500); } function addBtnToCard(card){ card.querySelector('.ay-dt-card-btn')?.remove(); const t=getCardTitle(card); if(!t) return; const btn=document.createElement('button'); btn.className='ay-dt-card-btn'; btn.textContent='搜索爱影'; btn.onclick=()=> AY.searchAy(t); card.appendChild(btn); } function getCardTitle(card){ const el=card.querySelector('h2,.title,[class*="title"],[data-title]'); if(el?.textContent?.trim()) return AY.cleanTitle(el.textContent.trim()); const img=card.querySelector('img'); if(img?.alt) return AY.cleanTitle(img.alt); return null; } function extractTMDbTitle(el){ const a=el.querySelector && el.querySelector('a'); const full=(a?.textContent||el.textContent||'').trim(); const noParen=full.replace(/\s*\(\d{4}\)\s*$/,''); if(noParen && noParen!==full) return AY.cleanTitle(noParen); const noTail=full.replace(/\s*\d{4}\s*$/,''); if(noTail && noTail!==full) return AY.cleanTitle(noTail); return AY.cleanTitle(full); } function mountBtnAfter(targetEl, insertBefore, title){ const btn=document.createElement('button'); btn.className='ay-dt-btn'; btn.textContent='搜索爱影'; btn.onclick=()=> AY.searchAy(title); if(insertBefore) insertBefore.parentNode.insertBefore(btn, insertBefore); else targetEl.parentNode.insertBefore(btn, targetEl.nextSibling); setTimeout(()=>btn.classList.add('added'),10); } AY.onReady(init); })(); // B. MoviePilot (function(){ AY.addStyle('ay-style-mp', ` .ay-mp-card-btn{position:absolute;top:8px;right:8px;background:linear-gradient(135deg,#5d78ff 0%,#3b5bdb 100%);color:#fff;border:none;border-radius:4px;padding:6px 10px;font-size:12px;font-weight:500;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 8px rgba(0,0,0,.3);z-index:100;opacity:0;transform:translateY(-10px);pointer-events:none;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;} .media-card:hover .ay-mp-card-btn{opacity:1;transform:translateY(0);pointer-events:auto} .ay-mp-chip{background:linear-gradient(135deg,#5d78ff 0%,#3b5bdb 100%)!important;border:none!important;color:#fff!important;cursor:pointer;transition:all .2s ease;margin-right:8px!important;} .ay-mp-nav-btn{background:linear-gradient(135deg,#5d78ff 0%,#3b5bdb 100%);color:#fff;border:none;border-radius:6px;padding:8px 14px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s ease;box-shadow:0 2px 6px rgba(93,120,255,.3);display:flex;align-items:center;gap:6px;margin-left:10px;white-space:nowrap;} `); function init(){ initCards(); initSearchHeader(); initDetailNav(); setupObserver(); } function initCards(){ const process=()=>{ document.querySelectorAll('.media-card').forEach(card=>{ if(card.hasAttribute('data-ay-mp')) return; card.setAttribute('data-ay-mp','1'); card.style.position='relative'; addBtnToCard(card); }); }; new MutationObserver(process).observe(document.body,{childList:true,subtree:true}); setTimeout(process,500); } function addBtnToCard(card){ card.querySelector('.ay-mp-card-btn')?.remove(); const t = AY.cleanTitle(card.querySelector('.media-card-title')?.textContent?.trim() || card.querySelector('img')?.alt || ''); if(!t) return; const btn=document.createElement('button'); btn.className='ay-mp-card-btn'; btn.textContent='搜索爱影'; btn.onclick=(e)=>{ e.stopPropagation(); AY.searchAy(t); }; card.appendChild(btn); } function initSearchHeader(){ let tries=0, timer=setInterval(()=>{ if(tries++>=15) return clearInterval(timer); const header=document.querySelector('.search-header.v-card'); if(header && !header.querySelector('.ay-mp-chip')){ clearInterval(timer); const container=header.querySelector('.search-tags'); const sample=document.querySelector('.search-tag'); if(container && sample){ const chip=sample.cloneNode(true); chip.classList.add('ay-mp-chip'); const content=chip.querySelector('.v-chip__content'); if(content) content.textContent='搜索爱影'; chip.onclick=(e)=>{ e.stopPropagation(); const t=extractTitleFromHeader(header); if(t) AY.searchAy(t); else alert('无法获取搜索标题'); }; container.appendChild(chip); } } }, 1000); } function extractTitleFromHeader(header){ const chips=header.querySelectorAll('.v-chip__content'); for(const c of chips){ if(c.textContent.includes('标题:')) return c.textContent.replace('标题:','').trim(); } return ''; } function isDetailPage(){ return location.hash.includes('#/media?mediaid='); } function initDetailNav(){ if(isDetailPage()) addNavBtn(); new MutationObserver(()=>{ if(isDetailPage() && !document.querySelector('.ay-mp-nav-btn')) addNavBtn(); }).observe(document.body,{childList:true,subtree:true}); } function addNavBtn(){ document.querySelector('.ay-mp-nav-btn')?.remove(); const navbar=document.querySelector('.navbar-content-container'); const row=navbar?.querySelector('.d-flex.h-14.align-center.mx-1'); const anchor=row?.querySelector('.d-flex.align-center.cursor-pointer.ms-lg-n2'); if(!anchor) return; const btn=document.createElement('button'); btn.className='ay-mp-nav-btn'; btn.textContent='搜索爱影'; btn.onclick=()=>{ const t=getTitleFromUrl() || getTitleFromPage(); if(t) AY.searchAy(t); else alert('无法提取标题信息'); }; anchor.parentNode.insertBefore(btn, anchor.nextSibling); } function getTitleFromUrl(){ const hp=location.hash.split('?')[1]; if(!hp) return ''; const p=new URLSearchParams(hp); const t=p.get('title'); if(!t) return ''; let d=decodeURIComponent(t); if(d.includes('&')) d=d.split('&')[0]; return AY.cleanTitle(d); } function getTitleFromPage(){ const t=document.querySelector('.v-card-title')?.textContent?.trim() || document.querySelector('h1,h2,h3')?.textContent?.trim() || ''; return AY.cleanTitle(t); } function setupObserver(){ new MutationObserver(()=>{ document.querySelectorAll('.media-card:not([data-ay-mp])').length && initCards(); const header=document.querySelector('.search-header.v-card'); if(header && !header.querySelector('.ay-mp-chip')) initSearchHeader(); if(isDetailPage() && !document.querySelector('.ay-mp-nav-btn')) addNavBtn(); }).observe(document.body,{childList:true,subtree:true}); } AY.onReady(init); })(); // C. Emby Toolkit (function(){ AY.addStyle('ay-style-et', ` .ay-et-btn{background:linear-gradient(135deg,#5d78ff 0%,#3b5bdb 100%);color:#fff;border:none;border-radius:4px;padding:4px 0;font-size:11px;font-weight:500;cursor:pointer;transition:all .3s ease;box-shadow:0 2px 6px rgba(0,0,0,.3);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;position:absolute;bottom:4px;left:4px;right:4px;z-index:1000;opacity:0;pointer-events:none;transform:translateY(5px);white-space:nowrap;display:flex;align-items:center;justify-content:center;overflow:hidden;height:20px;line-height:1;} .movie-info:hover .ay-et-btn{opacity:1;pointer-events:auto;transform:translateY(0)} .ay-et-marquee{display:flex;align-items:center;width:100%;justify-content:center;position:relative} .ay-et-icon{margin-right:6px;font-size:11px;flex-shrink:0} .ay-et-text{display:inline-block;white-space:nowrap;animation:ay-et-marquee 5s linear infinite;padding-left:100%} @keyframes ay-et-marquee{0%{transform:translateX(0)}100%{transform:translateX(-100%)}} .ay-et-btn:hover .ay-et-text{animation-play-state:paused} `); function init(){ processItems(); setInterval(processItems, 1000); watchUrl(); } function processItems(){ document.querySelectorAll('.movie-info:not([data-ay-et])').forEach(info=>{ info.setAttribute('data-ay-et','1'); if(getComputedStyle(info).position==='static') info.style.position='relative'; mountBtn(info); }); } function mountBtn(container){ container.querySelector('.ay-et-btn')?.remove(); const el=container.querySelector('.movie-title'); if(!el) return; const t=AY.cleanTitle(el.textContent.trim()); if(!t) return; const btn=document.createElement('button'); btn.className='ay-et-btn'; btn.title=`搜索: ${t}`; const wrap=document.createElement('div'); wrap.className='ay-et-marquee'; const icon=document.createElement('span'); icon.className='ay-et-icon'; icon.textContent='🔍'; const txt=document.createElement('span'); txt.className='ay-et-text'; txt.textContent='搜索爱影'; wrap.appendChild(icon); wrap.appendChild(txt); btn.appendChild(wrap); btn.onclick=(e)=>{ e.stopPropagation(); AY.searchAy(t); }; container.appendChild(btn); } function watchUrl(){ let last=location.href; new MutationObserver(()=>{ if(location.href!==last){ last=location.href; setTimeout(init,500);} }).observe(document,{subtree:true,childList:true}); } AY.onReady(init); })(); })();