您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Restore right/middle-click new tab function on manko.fun / solji.kim
// ==UserScript== // @name manko.fun Card Linkifier // @namespace http://tampermonkey.net/ // @version v1.1 // @description Restore right/middle-click new tab function on manko.fun / solji.kim // @author VanillaMilk // @match https://manko.fun/* // @match https://solji.kim/* // @run-at document-end // @license MIT // @match https://manko.fun/* // @match https://solji.kim/* // @run-at document-end // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (async function () { 'use strict'; const ID_ATTR = 'data-id'; const DEST_BASE = 'https://solji.kim/movie-info/'; const STORE_KEY = 'mf_linkifier_open_blank'; // '1' -> _blank, '0' -> _self async function loadMode() { try { return String(await GM_getValue(STORE_KEY, '0')) === '1'; } catch { return false; } } async function saveMode(v) { try { await GM_setValue(STORE_KEY, v ? '1' : '0'); } catch {} } let useBlank = await loadMode(); const currentTarget = () => (useBlank ? '_blank' : '_self'); GM_registerMenuCommand?.( (useBlank ? '☑ ' : '☐ ') + 'Left-click opens in new tab', async () => { useBlank = !useBlank; await saveMode(useBlank); location.reload(); } ); const style = document.createElement('style'); style.textContent = ` .tm-link-wrap { position: relative !important; } .tm-link-overlay { position: absolute !important; inset: 0 !important; width: 100% !important; height: 100% !important; z-index: 2147483646 !important; display: block !important; background: transparent !important; text-decoration: none !important; outline: none !important; } .tm-link-overlay:focus { outline: none !important; } `; document.documentElement.appendChild(style); function linkifyCard(card) { if (!(card instanceof Element)) return; if (!card.hasAttribute(ID_ATTR)) return; if (card.closest('a[href]:not([href^="#"]):not([href^="javascript:"])')) return; if (card.__tm_linkified__) return; const raw = card.getAttribute(ID_ATTR) || ''; const id = raw.split('?')[0].trim(); if (!id) return; card.__tm_linkified__ = true; const wrapper = ensureWrapper(card); let overlay = wrapper.querySelector(':scope > a.tm-link-overlay'); if (!overlay) { overlay = document.createElement('a'); overlay.className = 'tm-link-overlay'; overlay.rel = 'noopener noreferrer'; wrapper.appendChild(overlay); } overlay.target = currentTarget(); overlay.href = DEST_BASE + encodeURIComponent(id); } function ensureWrapper(el) { const parent = el.parentElement; if (parent) { const cs = getComputedStyle(parent); if (cs.position !== 'static') return parent; } const wrapper = document.createElement('span'); wrapper.className = 'tm-link-wrap'; wrapper.style.position = 'relative'; el.parentNode?.insertBefore(wrapper, el); wrapper.appendChild(el); return wrapper; } function scan(root) { if (!root || !root.querySelectorAll) return; root.querySelectorAll(`[${ID_ATTR}]`).forEach(linkifyCard); linkifyCard(root); } scan(document.body || document.documentElement); const mo = new MutationObserver(muts => { for (const m of muts) { if (m.type === 'childList') { m.addedNodes.forEach(n => n.nodeType === 1 && scan(n)); } else if (m.type === 'attributes' && m.attributeName === ID_ATTR) { linkifyCard(m.target); } } }); mo.observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: [ID_ATTR] }); })();