您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Fixes image/link/url references to the local host automatically, allowing you to browse servers normally. Functionality inspired by 'Twonky Viewer' chrome extension developed by
// ==UserScript== // @name Twonky host origin fix // @namespace https://greasyfork.org/en/users/1443383 // @version 1.0 // @license MIT // @description Fixes image/link/url references to the local host automatically, allowing you to browse servers normally. Functionality inspired by 'Twonky Viewer' chrome extension developed by // @author kryo // @match *://*:9000/* // @match *://*:9001/* // @match *://*:9002/* // @match *://*:9443/* // @include *://*:*/* // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; const TWONKY_PORTS = ['9000', '9001', '9002', '9443']; // Regex to match http(s)://127.0.0.1:PORT/... where PORT is one of the Twonky ports const urlPattern = new RegExp(`^https?:\/\/127\\.0\\.0\\.1:(${TWONKY_PORTS.join('|')})(\/|$)`); // Get the correct hostname from the current page URL const correctHostname = window.location.hostname; // --- Function to fix attributes of a given node --- function fixNodeAttributes(node) { // Only process element nodes if (node.nodeType !== Node.ELEMENT_NODE) { return; } // List of attributes that commonly contain URLs const urlAttributes = ['src', 'href', 'action', 'data-url']; // Add other attributes if needed urlAttributes.forEach(attr => { if (node.hasAttribute(attr)) { const originalUrl = node.getAttribute(attr); if (originalUrl && urlPattern.test(originalUrl)) { const newUrl = originalUrl.replace('127.0.0.1', correctHostname); console.log(`Tampermonkey: Fixing URL in ${node.tagName} ${attr}: ${originalUrl} -> ${newUrl}`); node.setAttribute(attr, newUrl); // Special handling for anchors to potentially update text content if it mirrors the href if (node.tagName === 'A' && node.textContent === originalUrl) { node.textContent = newUrl; } } } }); // Add specific handling for other elements/attributes if necessary // e.g., <object data="...">, <embed src="...">, background-image styles if (node.style && node.style.backgroundImage) { const originalUrl = node.style.backgroundImage; // Basic check: url("http://127.0.0.1:9000/...") if (originalUrl.includes('url("') && originalUrl.includes('127.0.0.1:')) { // More robust regex might be needed here depending on variations const potentialUrl = originalUrl.substring(originalUrl.indexOf('url("') + 5, originalUrl.lastIndexOf('")')); if (urlPattern.test(potentialUrl)) { const newUrl = potentialUrl.replace('127.0.0.1', correctHostname); console.log(`Tampermonkey: Fixing background-image URL: ${potentialUrl} -> ${newUrl}`); node.style.backgroundImage = `url("${newUrl}")`; } } } } // --- Function to recursively scan a node and its children --- function scanAndFixNodes(node) { fixNodeAttributes(node); // Recursively scan child elements if (node.children) { for (let i = 0; i < node.children.length; i++) { scanAndFixNodes(node.children[i]); } } } // --- MutationObserver to watch for dynamically added elements --- const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { // Check added nodes mutation.addedNodes.forEach(newNode => { scanAndFixNodes(newNode); // Scan the new node and its children }); // Check if attributes changed (less common for initial load, but good for dynamic updates) if (mutation.type === 'attributes' && mutation.target) { fixNodeAttributes(mutation.target); } }); }); // --- Start observing --- // We run at document-start, so wait for the documentElement to be available // and observe it for additions/changes to head and body const observerConfig = { childList: true, // Watch for adding/removing child nodes subtree: true, // Watch descendants as well attributes: true, // Watch for attribute changes attributeFilter: ['src', 'href', 'action', 'data-url', 'style'] // Optional: Be specific about watched attributes }; // Function to start the observer once the document element exists function observeRoot() { if (document.documentElement) { console.log('Tampermonkey: Twonky Fixer - Starting MutationObserver.'); observer.observe(document.documentElement, observerConfig); // --- Initial Scan --- // Perform an initial scan of the document in case elements already exist // when the script runs (especially important if @run-at is not document-start, // but good practice anyway). console.log('Tampermonkey: Twonky Fixer - Performing initial DOM scan.'); scanAndFixNodes(document.documentElement); } else { // If documentElement is not yet ready (should be rare with document-start), retry shortly console.log('Tampermonkey: Twonky Fixer - documentElement not ready, retrying...'); setTimeout(observeRoot, 50); } } observeRoot(); // Optional: Disconnect observer when page unloads (usually not strictly necessary for userscripts) // window.addEventListener('unload', () => { // if (observer) { // observer.disconnect(); // console.log('Tampermonkey: Twonky Fixer - Disconnected MutationObserver.'); // } // }); })();