您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Hover preview for links to other comments
当前为
// ==UserScript== // @name Derpibooru Comment Preview // @description Hover preview for links to other comments // @version 1.0.15 // @author Marker // @namespace https://github.com/marktaiwan/ // @homepageURL https://github.com/marktaiwan/Derpibooru-Quote-Preview // @include /^https?://(www\.)?(derpiboo\.ru|derpibooru\.org|trixiebooru\.org)/\d{1,}(/|\.html)?/ // @include /^https?://(www\.)?(derpiboo\.ru|derpibooru\.org|trixiebooru\.org)/lists/my_comments(\?page=\d{1,})?(/|\.html)?$/ // @grant none // ==/UserScript== (function() { 'use strict'; function displayHover(comment, link) { const PADDING = 5; // px if (!hover) return; var preview = document.querySelectorAll('#hover_preview'); if (preview !== null) { for (i = 0; i < preview.length; i++) { preview[i].parentNode.removeChild(preview[i]); } } comment.id = 'hover_preview'; comment.style.position = 'absolute'; comment.style.maxWidth = '980px'; comment.style.minWidth = '490px'; // Make spoiler visible var i; var list = comment.querySelectorAll('span.spoiler, span.imgspoiler'); if (list !== null) { for (i = 0; i < list.length; i++) { list[i].style.color = '#333'; list[i].style.backgroundColor = '#f7d4d4'; } } // img spoiler list = comment.querySelectorAll('span.imgspoiler img'); if (list !== null) { for (i = 0; i < list.length; i++) { list[i].style.visibility = 'visible'; } } var container = document.getElementById('image_comments') || document.getElementById('content'); if (container) { container.appendChild(comment); } // calculate link position var linkRect = link.getBoundingClientRect(); var linkTop = linkRect.top + viewportPos().top; var linkLeft = linkRect.left + viewportPos().left; var commentRect = comment.getBoundingClientRect(); var commentTop; var commentLeft; // When there is room, place the preview above the link // otherwise place it to the right and aligns it to the top of viewport if (linkRect.top > commentRect.height + PADDING) { commentTop = linkTop - commentRect.height - PADDING; commentLeft = linkLeft; } else { commentTop = viewportPos().top + PADDING; commentLeft = linkLeft + linkRect.width + PADDING; } comment.style.top = commentTop + 'px'; comment.style.left = commentLeft + 'px'; } function linkEnter(e) { // filtering if (!e.target.matches('.communication__body__text a[href*="#comment_"], .communication__body__text a[href*="#comment_"]>*')) return; hover = true; // Example: e.target.hash == "#comment_5430424" var sourceLink = e.target.parentNode.matches('a[href*="#comment_"]') ? e.target.parentNode : e.target; var targetID = sourceLink.hash.slice(9); var targetComment = document.getElementById('comment_' + targetID); // ignore quotes // this is terrible if (sourceLink.nextElementSibling && sourceLink.nextElementSibling.nextElementSibling && sourceLink.nextElementSibling.nextElementSibling.matches('blockquote')) return; if (targetComment !== null) { // Post exist on current page if (!elementInViewport(targetComment)) { displayHover(targetComment.cloneNode(true), sourceLink); } // Highlight linked post targetComment.firstChild.style.backgroundColor = 'rgba(230,230,30,0.3)'; } else { // External post, display from cached response if possible if (fetchCache[targetID] !== undefined) { displayHover(fetchCache[targetID], sourceLink); } else { fetch(window.location.origin + '/comment/' + targetID + '.html') .then((response) => response.text()) .then((text) => { var d = document.createElement('div'); d.innerHTML = text; fetchCache[targetID] = d.firstChild; displayHover(d.firstChild, sourceLink); }); } } } function linkLeave(e) { // filtering if (!e.target.matches('.communication__body__text a[href*="#comment_"], .communication__body__text a[href*="#comment_"]>*')) return; hover = false; var i; var sourceLink = e.target.parentNode.matches('a[href*="#comment_"]') ? e.target.parentNode : e.target; var targetID = sourceLink.hash.slice(9); var targetComment = document.getElementById('comment_' + targetID); var preview = document.getElementById('hover_preview'); // ignore quotes // this is terrible if (sourceLink.nextElementSibling && sourceLink.nextElementSibling.nextElementSibling && sourceLink.nextElementSibling.nextElementSibling.matches('blockquote')) return; //remove highlight if (targetComment !== null) { targetComment.firstChild.style.backgroundColor = ''; } if (preview !== null) preview.parentNode.removeChild(preview); } // Chrome/Firefox compatibility hack for getting viewport position function viewportPos() { return { top: (document.documentElement.scrollTop || document.body.scrollTop), left: (document.documentElement.scrollLeft || document.body.scrollLeft) }; } function elementInViewport(el) { var rect = el.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } var hover = false; var fetchCache = {}; var container = document.getElementById('image_comments') || document.getElementById('content'); if (container) { container.addEventListener('mouseover', linkEnter); container.addEventListener('mouseout', linkLeave); } })();