0) { Array.from(node.children).forEach(fixNode); } } const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { mutation.addedNodes.forEach(function(node) { fixNode(node); }); // 属性変更の監視(lazyloadがdataset→srcを書き換えるケース) if (mutation.type === 'attributes') { const node = mutation.target; const attr = mutation.attributeName; if (attr && URL_ATTRS.includes(attr) && node.nodeType === 1) { const val = node.getAttribute(attr); if (val && !val.includes('atoshin.com') && !/^(data:|blob:|javascript:)/.test(val)) { const tag = (node.tagName || '').toLowerCase(); const proxied = tag === 'iframe' ? proxyUrlIframe(val) : proxyUrl(val); if (proxied !== val) _origSetAttr.call(node, attr, proxied); } } } }); }); observer.observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['src', 'href', 'data-src', 'data-original', 'data-lazy-src', 'data-lazy', 'poster', 'srcset', 'style'] }); // ===== document.write フック ===== const _origWrite = document.write.bind(document); document.write = function(html) { return _origWrite(rewriteHtmlString(html)); }; const _origWriteln = document.writeln.bind(document); document.writeln = function(html) { return _origWriteln(rewriteHtmlString(html)); }; // ===== WebSocket フック (ホスト書き換え) ===== if (window.WebSocket) { const _OrigWS = window.WebSocket; window.WebSocket = function(url, protocols) { if (typeof url === 'string') { // ws://orig-host/... → wss://proxy_host/ws-proxy/...等への変換は // プロキシ側に実装が必要なため、ここでは接続先ホスト情報を補正するのみ url = url.replace( new RegExp('^ws(s?)://' + PROXY_HOST.replace(/\./g,'\.')), 'ws$1://' + ORIG_HOST ); } return protocols ? new _OrigWS(url, protocols) : new _OrigWS(url); }; window.WebSocket.prototype = _OrigWS.prototype; window.WebSocket.CONNECTING = _OrigWS.CONNECTING; window.WebSocket.OPEN = _OrigWS.OPEN; window.WebSocket.CLOSING = _OrigWS.CLOSING; window.WebSocket.CLOSED = _OrigWS.CLOSED; } // ===== 競合回避版 jQuery 自動注入 (window.jq) ===== function injectSafeJQuery() { if (typeof window.jq !== 'undefined') return; const originalDefine = window.define; window.define = null; const script = document.createElement('script'); script.src = 'https://code.jquery.com/jquery-3.7.1.min.js'; script.async = false; script.onload = function() { window.define = originalDefine; if (window.jQuery) { window.jq = window.jQuery.noConflict(true); console.log('%c[Proxy] jQ 3.7.1 → window.jq', 'color:#0f0;background:#000'); } }; script.onerror = function() { window.define = originalDefine; }; (document.head || document.documentElement).appendChild(script); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', injectSafeJQuery); } else { injectSafeJQuery(); } // ===== Eruda 開発者ツール ===== function loadEruda() { try { const show = localStorage.getItem('_eruda_show') === '1' || sessionStorage.getItem('_eruda_show') === '1'; if (show && !window.eruda) { const s = document.createElement('script'); s.src = 'https://cdn.jsdelivr.net/npm/eruda'; s.onload = function() { eruda.init(); }; document.head.appendChild(s); } } catch(e) {} } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', loadEruda); else loadEruda(); console.log('%c[Proxy Hook] Active — origin: ' + ORIG_ORIGIN, 'color:#0af;background:#000;padding:2px 6px'); })();

TODO...