您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Inline Quoting for holotower.org
// ==UserScript== // @name Holotower Inline Quoting // @namespace http://tampermonkey.net/ // @version 3.0 // @author grem // @license MIT // @description Inline Quoting for holotower.org // @match *://boards.holotower.org/* // @match *://holotower.org/* // @grant GM_addStyle // @grant GM_xmlhttpRequest // @require https://code.jquery.com/jquery-3.6.0.min.js // @connect self // @connect boards.holotower.org // @icon https://boards.holotower.org/favicon.gif // @run-at document-start // ==/UserScript== /* global $, setting */ const IQ_SETTINGS_KEY = "InlineQuote Settings"; const iqDefaultSettings = { enableVideoHoverPreview: false, }; let iqSettings = {}; try { iqSettings = JSON.parse(localStorage.getItem(IQ_SETTINGS_KEY)) || {}; } catch(e) { iqSettings = {}; } for (const k in iqDefaultSettings) if (!(k in iqSettings)) iqSettings[k] = iqDefaultSettings[k]; function saveIQ() { localStorage.setItem(IQ_SETTINGS_KEY, JSON.stringify(iqSettings)); } function getGlobalDefaultVolume() { try { if (typeof setting === "function") { const v = parseFloat(setting("videovolume")); if (!isNaN(v)) return Math.min(Math.max(v,0),1); } } catch {} return 1; } function cleanInlineContainer($container) { $container.find('> .inline-cloned-post > p.intro').each(function() { let next = this.nextSibling; while (next && next.nodeType === 3 && !/\S/.test(next.nodeValue)) { let toRemove = next; next = next.nextSibling; toRemove.parentNode.removeChild(toRemove); } }); $container.find('> .inline-cloned-post > .files').each(function() { let next = this.nextSibling; while (next && next.nodeType === 3 && !/\S/.test(next.nodeValue)) { let toRemove = next; next = next.nextSibling; toRemove.parentNode.removeChild(toRemove); } }); $container.find('> .inline-cloned-post > .files').each(function() { if (!this.innerText.trim() && !this.querySelector('img, video, a, object, embed')) { this.parentNode.removeChild(this); } }); } $(function () { if (typeof Options === "undefined") return; const tab = Options.add_tab("inline-quote", "quote-right", "Inline Quotes"); const $content = $("<div></div>"); const $videoHoverEntry = $( `<div id="enableVideoHoverPreview-container"> <label style="text-decoration: underline; cursor: pointer;"> <input type="checkbox" id="enableVideoHoverPreview">Play videos on hover</label> <span class="description">: Show/Hide previews when hovering videos inside inline quotes</span> </div>`); $content.append($videoHoverEntry); $(tab.content).append($content); $("#enableVideoHoverPreview").prop("checked", iqSettings.enableVideoHoverPreview); $("#enableVideoHoverPreview").on("change", function () { iqSettings.enableVideoHoverPreview = this.checked; saveIQ(); }); }); (function() { 'use strict'; const INLINE_CONTAINER_CLASS = 'inline-quote-container'; const INLINE_ACTIVE_LINK_CLASS = 'inline-active'; const LOADING_DATA_ATTR = 'data-inline-loading'; const ERROR_DATA_ATTR = 'data-inline-error'; const TEMP_HIGHLIGHT_CLASS = 'inline-temp-highlight'; const PROCESSED_ATTR = 'data-inline-processed'; const INLINED_ID_ATTR = 'data-inlined-id'; const CLONED_POST_CLASS = 'inline-cloned-post'; const CLONED_HOVER_PREVIEW_ID_PREFIX = 'iq-preview-'; const HOVER_INITIALIZED_ATTR = 'data-iq-hover-init'; const SITE_PREVIEW_BASE_CLASSES = 'post qp'; const SITE_PREVIEW_REPLY_CLASS = 'reply'; const SITE_PREVIEW_OP_CLASS = 'op'; const POST_SELECTOR_ID_FORMAT = (postId) => `div.post[id$='_${postId}']`; const POTENTIAL_QUOTE_LINK_SELECTOR = "a[onclick*='highlightReply'], a[href*='#q']"; const QUOTE_LINK_REGEX = /^>>(\d+)/; const SITE_HOVER_TARGET_SELECTOR = 'div.body a:not([rel="nofollow"]), span.mentioned a:not([rel="nofollow"]), p.intro a.post_no:not([rel="nofollow"])'; const BOARD_CONTEXT_SELECTOR = '[data-board]'; GM_addStyle(` .${INLINE_CONTAINER_CLASS} { border: 1px dashed var(--subtle-border-color,#888); background-color: var(--inline-background-color,rgba(128,128,128,.05)); padding:5px; margin-top:5px; margin-left:20px; border-radius:4px; } .${INLINE_CONTAINER_CLASS} > .${CLONED_POST_CLASS}[data-board] { border:none!important; margin:0!important; padding:0!important; box-shadow:none!important; background:transparent!important; } a.${INLINE_ACTIVE_LINK_CLASS} { font-weight:bold!important; color:var(--link-hover-color,#d11a1a)!important; opacity:.85; text-decoration:underline dotted!important; } a.${INLINE_ACTIVE_LINK_CLASS}:hover { opacity:1 } a[${LOADING_DATA_ATTR}="true"]::after { content:" (loading.)"; font-style:italic; color:var(--text-color-muted,#888); margin-left:4px } a[${ERROR_DATA_ATTR}="true"]::after { content:" (not found)"; font-style:italic; color:var(--error-text-color,#f00); margin-left:4px } .${TEMP_HIGHLIGHT_CLASS} { transition:outline .1s ease-in-out; outline:2px solid var(--highlight-color,yellow)!important; outline-offset:2px } div.qp[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"] { position:absolute!important; z-index:150!important; max-width:500px } div.qp[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"] > .post { border:none!important; margin:0!important; padding:0!important; box-shadow:none!important; background:transparent!important; } div.qp[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"] .hide-post-button,div.qp[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"] .menu-button,div.qp[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"] input[type=checkbox].delete { display:none!important } div.qp[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"].loading-preview::after { content:"Loading."; font-style:italic; color:var(--text-color-muted,#888); padding:5px; display:block } div.qp[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"].error-preview::after { content:"Not found."; font-style:italic; color:var(--error-text-color,#f00); padding:5px; display:block } `); function adjustInlineQuoteContainer($container) { const $parentPost = $container.closest('.post.reply'); let marginLeft = 0; const $img = $parentPost.find('.files .file .post-image'); if ($img.length && $img.css('display') !== 'none') { marginLeft = parseInt($img[0]?.style.width) || $img[0]?.width || parseInt($img.attr('width')) || 0; } else { const $fullImg = $parentPost.find('.files .file .full-image'); if ($fullImg.length) { marginLeft = parseInt($fullImg[0]?.style.width) || $fullImg[0]?.width || parseInt($fullImg.attr('width')) || 0; } } $container.css('margin-left', marginLeft + 'px'); $container.find('.inline-cloned-post')[0]?.style.setProperty('max-width', '100%', 'important'); $container.find('.inline-cloned-post').css('box-sizing','border-box'); } function getPostIdFromLink(link) { if (!link) return null; const textMatch = link.textContent?.trim().match(QUOTE_LINK_REGEX); if (textMatch) return textMatch[1]; const hrefMatch = link.getAttribute('href')?.match(/#(\d+)$/); if (hrefMatch) return hrefMatch[1]; const quoteHrefMatch = link.getAttribute('href')?.match(/#q(\d+)$/); if (quoteHrefMatch) return quoteHrefMatch[1]; return null; } function fetchPostHtml(url) { const fetchUrl = url?.split('#')[0]; if (!fetchUrl) return Promise.resolve(null); return new Promise((resolve) => { GM_xmlhttpRequest({ method: "GET", url: fetchUrl, onload: r => { (r.status >= 200 && r.status < 300) ? resolve(r.responseText) : resolve(null); }, onerror: r => { resolve(null); }, ontimeout: () => { resolve(null); } }); }); } function parseAndFindPost(html, postId) { try { const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const postElement = doc.querySelector(POST_SELECTOR_ID_FORMAT(postId)); return postElement; } catch (error) { return null; } } function isElementInViewportStrict(el) { el = el && el[0] ? el[0] : el; if (!el) return false; const rect = el.getBoundingClientRect(); return rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0; } function temporaryHighlight(el) { el = el && el[0] ? el[0] : el; if (!el) return; $(el).addClass(TEMP_HIGHLIGHT_CLASS); setTimeout(() => { $(el).removeClass(TEMP_HIGHLIGHT_CLASS); }, 500); } function processLinks(parentElement) { if (!parentElement) return; const links = parentElement.querySelectorAll(POTENTIAL_QUOTE_LINK_SELECTOR); links.forEach(link => { if (!link.hasAttribute(PROCESSED_ATTR)) { const onclickValue = link.getAttribute('onclick'); if (onclickValue && onclickValue.includes('highlightReply')) { link.removeAttribute('onclick'); } link.setAttribute(PROCESSED_ATTR, 'true'); } }); } async function handleInlineQuoteClick(linkElement, postId) { const $link = $(linkElement); let $mainPost = $link.closest('.post.reply'); if ($mainPost.hasClass('post-hover')) { const match = $mainPost.attr('id') && $mainPost.attr('id').match(/^post-hover-(\d+)/); if (match) { $mainPost = $(`.post.reply#reply_${match[1]}`); } } const $body = $mainPost.find('.body').first(); $mainPost.find(`.${INLINE_CONTAINER_CLASS}[${INLINED_ID_ATTR}="${postId}"]`).remove(); if ($link.hasClass(INLINE_ACTIVE_LINK_CLASS)) { $link.removeClass(INLINE_ACTIVE_LINK_CLASS).removeAttr(LOADING_DATA_ATTR).removeAttr(ERROR_DATA_ATTR); return; } let targetPostElement = document.querySelector(POST_SELECTOR_ID_FORMAT(postId)); let boardValue = null; const $linkContext = $link.closest(BOARD_CONTEXT_SELECTOR); if ($linkContext.length > 0) boardValue = $linkContext.data('board'); else if (targetPostElement) { const $targetContext = $(targetPostElement).closest(BOARD_CONTEXT_SELECTOR); if ($targetContext.length > 0) boardValue = $targetContext.data('board'); } if (targetPostElement && isElementInViewportStrict(targetPostElement)) { temporaryHighlight(targetPostElement); $link.removeClass(INLINE_ACTIVE_LINK_CLASS).removeAttr(LOADING_DATA_ATTR).removeAttr(ERROR_DATA_ATTR); return; } const $ancestors = $link.parents(`.${INLINE_CONTAINER_CLASS}`); if ($ancestors.filter(`[${INLINED_ID_ATTR}="${postId}"]`).length) { temporaryHighlight($ancestors.filter(`[${INLINED_ID_ATTR}="${postId}"]`).first()); $link.removeClass(INLINE_ACTIVE_LINK_CLASS).removeAttr(LOADING_DATA_ATTR).removeAttr(ERROR_DATA_ATTR); return; } $link.addClass(INLINE_ACTIVE_LINK_CLASS).attr(LOADING_DATA_ATTR, "true"); if (!targetPostElement && linkElement.href) { const postHtml = await fetchPostHtml(linkElement.href); if (postHtml) { const parsed = parseAndFindPost(postHtml, postId); if (parsed) targetPostElement = parsed; } } $link.removeAttr(LOADING_DATA_ATTR); if (targetPostElement) { const $container = $('<div>') .addClass(INLINE_CONTAINER_CLASS) .attr(INLINED_ID_ATTR, postId); const $mentionedSpan = $link.closest('span.mentioned.unimportant'); let marginLeft = 0; if (!$mentionedSpan.length) { const $files = $mainPost.children('.files'); const $img = $files.find('.file .post-image'); if ($img.length && $img.css('display') !== 'none') { marginLeft = parseInt($img[0]?.style.width) || $img[0]?.width || parseInt($img.attr('width')) || 0; } else { const $fullImg = $files.find('.file .full-image'); if ($fullImg.length && $fullImg.css('display') !== 'none') { marginLeft = parseInt($fullImg[0]?.style.width) || $fullImg[0]?.width || parseInt($fullImg.attr('width')) || 0; } } $container.css('margin-left', marginLeft + 'px'); } if ($mentionedSpan.length) { let $insertionAnchor = $mentionedSpan; const $linksInSpan = $mentionedSpan.find('a'); const clickedLinkIndex = $linksInSpan.index($link); for (let i = clickedLinkIndex - 1; i >= 0; i--) { const id = getPostIdFromLink($linksInSpan[i]); if (id) { const $containerForLink = $mainPost.find(`.${INLINE_CONTAINER_CLASS}[${INLINED_ID_ATTR}="${id}"]`); if ($containerForLink.length) { $insertionAnchor = $containerForLink.first(); break; } } } $insertionAnchor.after($container); } else { $link.after($container); } let handled = false; if (window.g?.posts) { const boardID = boardValue; const postKey = `${boardID}.${postId}`; const postObj = g.posts.get(postKey); if (postObj && typeof postObj.addClone === 'function') { const cloneObj = postObj.addClone($container[0], false); $(cloneObj.nodes.root) .addClass(CLONED_POST_CLASS) .attr(PROCESSED_ATTR, 'true'); handled = true; } } if (!handled) { const cloned = targetPostElement.cloneNode(true); cloned.removeAttribute('id'); cloned.querySelectorAll('[id]').forEach(el => el.removeAttribute('id')); cloned.classList.add(CLONED_POST_CLASS); if (boardValue) cloned.setAttribute('data-board', boardValue); else cloned.setAttribute('data-board-missing', 'true'); $container.append(cloned); cleanInlineContainer($container); initializeInlineHover(cloned); initializeInlineImageHover(cloned); } if (!$mentionedSpan.length) { $container.find('.inline-cloned-post')[0]?.style.setProperty('max-width', '100%', 'important'); $container.find('.inline-cloned-post').css('box-sizing','border-box'); } } else { $link.attr(ERROR_DATA_ATTR, "true").removeClass(INLINE_ACTIVE_LINK_CLASS); setTimeout(() => { $link.removeAttr(ERROR_DATA_ATTR); }, 3000); } } function initializeInlineHover(parentElement) { $(parentElement).find(SITE_HOVER_TARGET_SELECTOR).each(function() { const $link = $(this); if ($link.attr(HOVER_INITIALIZED_ATTR)) return; const $parentPost = $link.closest('.post.reply[id^="reply_"]'); const parentPostId = $parentPost.length ? $parentPost[0].id.replace(/^reply_/, '') : null; const postId = getPostIdFromLink(this); if (parentPostId && postId && parentPostId === postId) { return; } let $preview = null; let targetPostId = null; let currentBoard = $(parentElement).closest(BOARD_CONTEXT_SELECTOR).data('board') || null; let fetchController = null; let mouseMoveTimer = null; function updatePreviewPosition(e) { if (!$preview) return; let top = e.pageY + 10; let left = e.pageX + 10; const win = $(window); const winHeight = win.height(); const winWidth = win.width(); const previewHeight = $preview.outerHeight(); const previewWidth = $preview.outerWidth(); const scrollTop = win.scrollTop(); const scrollLeft = win.scrollLeft(); if (previewHeight > 0 && top + previewHeight > scrollTop + winHeight) top = e.pageY - previewHeight - 10; if (top < scrollTop) top = scrollTop + 5; if (previewWidth > 0 && left + previewWidth > scrollLeft + winWidth) left = e.pageX - previewWidth - 10; if (left < scrollLeft) left = scrollLeft + 5; $preview.css({ top: top, left: left }); } function preparePreviewContent(sourceElement) { const clonedContent = sourceElement.cloneNode(true); clonedContent.removeAttribute('id'); clonedContent.querySelectorAll('[id]').forEach(el => el.removeAttribute('id')); return clonedContent; } function createPreviewDiv(sourceElement, postId) { $(`div[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"]`).remove(); const $previewContainer = $('<div>') .addClass(SITE_PREVIEW_BASE_CLASSES) .attr('id', CLONED_HOVER_PREVIEW_ID_PREFIX + postId) .appendTo('body'); if (sourceElement) { if (sourceElement.classList.contains(SITE_PREVIEW_REPLY_CLASS)) $previewContainer.addClass(SITE_PREVIEW_REPLY_CLASS); else if (sourceElement.classList.contains(SITE_PREVIEW_OP_CLASS)) $previewContainer.addClass(SITE_PREVIEW_OP_CLASS); $previewContainer.append(preparePreviewContent(sourceElement)); } return $previewContainer; } $link.on('mouseenter.iqhover', function(e) { if ($link.hasClass(INLINE_ACTIVE_LINK_CLASS)) return; targetPostId = getPostIdFromLink(this); const $parentInline = $link.parents(`.${INLINE_CONTAINER_CLASS}[${INLINED_ID_ATTR}]`); if ($parentInline.filter(`[${INLINED_ID_ATTR}="${targetPostId}"]`).length) { return; } if (!targetPostId || !currentBoard) return; $(`div[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"]`).remove(); const originalPostElement = document.querySelector(POST_SELECTOR_ID_FORMAT(targetPostId)); if (originalPostElement && $(originalPostElement).closest(BOARD_CONTEXT_SELECTOR).data('board') === currentBoard) { $preview = createPreviewDiv(originalPostElement, targetPostId); updatePreviewPosition(e); } else { const url = $link.attr('href'); if (!url) return; $preview = createPreviewDiv(null, targetPostId); $preview.addClass('loading-preview'); updatePreviewPosition(e); if (fetchController) fetchController.abort(); const controller = new AbortController(); fetchController = controller; const fetchUrl = url.split('#')[0]; GM_xmlhttpRequest({ method: "GET", url: fetchUrl, signal: controller.signal, onload: function(response) { if (controller.signal.aborted) return; fetchController = null; if (response.status >= 200 && response.status < 300) { const fetchedPostElement = parseAndFindPost(response.responseText, targetPostId); if (fetchedPostElement) { if ($preview) { $preview.empty().removeClass('loading-preview loading-error').addClass(SITE_PREVIEW_BASE_CLASSES); if(fetchedPostElement.classList.contains(SITE_PREVIEW_REPLY_CLASS)) $preview.addClass(SITE_PREVIEW_REPLY_CLASS); else if(fetchedPostElement.classList.contains(SITE_PREVIEW_OP_CLASS)) $preview.addClass(SITE_PREVIEW_OP_CLASS); $preview.append(preparePreviewContent(fetchedPostElement)); updatePreviewPosition(e); } } else { if ($preview) $preview.empty().removeClass('loading-preview').addClass('error-preview'); } } else { if ($preview) $preview.empty().removeClass('loading-preview').addClass('error-preview'); } }, onerror: function(response) { if (controller.signal.aborted) return; fetchController = null; if ($preview) $preview.empty().removeClass('loading-preview').addClass('error-preview'); }, ontimeout: function() { if (controller.signal.aborted) return; fetchController = null; if ($preview) $preview.empty().removeClass('loading-preview').addClass('error-preview'); } }); } }).on('mouseleave.iqhover', function(e) { if (fetchController) { fetchController.abort(); fetchController = null; } if ($preview) { $preview.remove(); $preview = null; } targetPostId = null; }).on('mousemove.iqhover', function(e) { clearTimeout(mouseMoveTimer); mouseMoveTimer = setTimeout(() => { updatePreviewPosition(e); }, 20); }).attr(HOVER_INITIALIZED_ATTR, 'true'); }); } function initializeInlineImageHover(parentElement) { const $container = $(parentElement); $container.find('a').each(function() { let href = this.href; if (!href) return; let realHref = href; const urlObj = new URL(href, window.location.origin); if (urlObj.pathname.endsWith('player.php') && urlObj.searchParams.has('v')) { realHref = urlObj.searchParams.get('v'); if (!/^(https?:)?\/\//i.test(realHref)) realHref = window.location.origin + realHref; } if (!/\.(jpe?g|png|gif|webm|mp4)(?:\?.*)?$/i.test(realHref)) return; const $link = $(this); if ($link.data('iq-image-hover')) return; $link.data('iq-image-hover', true); let $preview; function position(e) { if (!$preview) return; const winW = window.innerWidth, winH = window.innerHeight, el = $preview[0]; const naturalW = el.naturalWidth || el.videoWidth || 0, naturalH = el.naturalHeight || el.videoHeight || 0; if (!naturalW||!naturalH) return; const scale = Math.min(1, (winW*0.97)/naturalW, (winH*0.97)/naturalH); const width = naturalW*scale, height = naturalH*scale; let left = e.clientX + 45, top = e.clientY - 45; if (left + width > winW) left = e.clientX - width - 45; if (top + height > winH) top = e.clientY - height; if (left < 0) left = 0; if (top < 0) top = 0; $preview.css({width,height,left,top}); } $link.on('mouseenter.iqimagehover', function(e) { const isVideo = /\.(webm|mp4)$/i.test(realHref); if (isVideo && !iqSettings.enableVideoHoverPreview) return; if (isVideo) { $preview = $('<video>', {src: realHref, autoplay: true, muted: true, loop: true}); const vol = getGlobalDefaultVolume(); $preview.prop('volume', vol); $preview.on('loadedmetadata', () => position(e)); } else { $preview = $('<img>', {src: realHref}).on('load', () => position(e)); } $preview.css({position:'fixed', zIndex:9999, pointerEvents:'none', maxWidth:'97vw', maxHeight:'97vh'}).appendTo('body'); }).on('mousemove.iqimagehover', position).on('mouseleave.iqimagehover', function(){ if($preview) {$preview.remove(); $preview=null;} }); }); } document.documentElement.addEventListener('click', function(event) { const linkElement = event.target.closest('a'); if (!linkElement) return; const postId = getPostIdFromLink(linkElement); if (!postId || !QUOTE_LINK_REGEX.test(linkElement.textContent?.trim() || '')) return; event.preventDefault(); event.stopImmediatePropagation(); handleInlineQuoteClick(linkElement, postId); }, true); $(document).on('mouseenter', SITE_HOVER_TARGET_SELECTOR, function(event) { const linkElement = event.currentTarget; if ($(linkElement).hasClass(INLINE_ACTIVE_LINK_CLASS)) { if ($(event.target).closest(`div[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"]`).length > 0) return; event.stopImmediatePropagation(); } }); $(document).on('mouseleave', SITE_HOVER_TARGET_SELECTOR, function(event) { const linkElement = event.currentTarget; if ($(linkElement).hasClass(INLINE_ACTIVE_LINK_CLASS)) { if ($(event.relatedTarget).closest(`div[id^="${CLONED_HOVER_PREVIEW_ID_PREFIX}"]`).length > 0) return; event.stopImmediatePropagation(); } }); function runInitialProcessing() { if (!document.body) return; processLinks(document.body); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', runInitialProcessing); } else { runInitialProcessing(); } const observer = new MutationObserver(mutations => { if (!document.body) return; mutations.forEach(mutation => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { if (node.matches(POTENTIAL_QUOTE_LINK_SELECTOR) || node.querySelector(POTENTIAL_QUOTE_LINK_SELECTOR)) { processLinks(node); } let containerNode = null; if (node.matches && node.matches(`.${INLINE_CONTAINER_CLASS}`)) containerNode = node; else if (node.querySelector) containerNode = node.querySelector(`.${INLINE_CONTAINER_CLASS}`); if(containerNode) { const clonedPostElement = containerNode.querySelector(`.${CLONED_POST_CLASS}`); if (clonedPostElement) { initializeInlineHover(clonedPostElement); initializeInlineImageHover(clonedPostElement); } } } }); } }); }); observer.observe(document.documentElement, { childList: true, subtree: true }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址