您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show Bing image preview for reg plate in Flickr search link; works on all hovers. Spinner included.
// ==UserScript== // @name Reg Plate Hover Preview (Multi-Fix) // @version 1.1 // @namespace https://bustimes.org/ // @description Show Bing image preview for reg plate in Flickr search link; works on all hovers. Spinner included. // @match https://bustimes.org/* // @grant GM_xmlhttpRequest // @connect bing.com // ==/UserScript== (function () { 'use strict'; const style = document.createElement('style'); style.textContent = ` .reg-hover-preview { position: absolute; border: 2px solid #333; background: #fff; z-index: 9999; width: 300px; height: 200px; display: none; box-shadow: 0 0 10px rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; } .reg-spinner { border: 4px solid #f3f3f3; border-top: 4px solid #333; border-radius: 50%; width: 24px; height: 24px; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `; document.head.appendChild(style); function createPopup() { const popup = document.createElement('div'); popup.className = 'reg-hover-preview'; const spinner = document.createElement('div'); spinner.className = 'reg-spinner'; const img = document.createElement('img'); img.style.maxWidth = '100%'; img.style.maxHeight = '100%'; img.style.display = 'none'; popup.appendChild(spinner); popup.appendChild(img); document.body.appendChild(popup); return { popup, spinner, img }; } function getPlateFromURL(url) { const match = decodeURIComponent(url).match(/text=([A-Z0-9]+)(?:[+% ]|$)/i); return match ? match[1] : null; } function fetchImageFromBing(plate, callback) { const url = window.location.href; let operator = ""; // Use regex to extract the operator slug from the URL path const match = url.match(/\/operators\/([^\/]+)/); if (match && match[1]) { operator = match[1]; } const query = `${plate} ${operator}`; const searchURL = `https://www.bing.com/images/search?q=${encodeURIComponent(query)}`; GM_xmlhttpRequest({ method: "GET", url: searchURL, onload(res) { const doc = new DOMParser().parseFromString(res.responseText, "text/html"); const img = doc.querySelector('img.mimg'); callback(img?.src || null); } }); } document.addEventListener('mouseover', function (e) { const link = e.target.closest('a[href*="flickr.com/search/?text="]'); if (!link || link._hasHoverListener) return; link._hasHoverListener = true; link.addEventListener('mouseenter', (ev) => { const plate = getPlateFromURL(link.href); if (!plate) return; const { popup, spinner, img } = createPopup(); popup.style.left = `${ev.pageX + 15}px`; popup.style.top = `${ev.pageY + 15}px`; popup.style.display = 'flex'; spinner.style.display = 'block'; img.style.display = 'none'; img.src = ''; fetchImageFromBing(plate, (imgSrc) => { if (imgSrc) { img.onload = () => { spinner.style.display = 'none'; img.style.display = 'block'; }; img.onerror = () => { spinner.style.display = 'none'; popup.textContent = 'Image failed to load.'; }; img.src = imgSrc; } else { spinner.style.display = 'none'; popup.textContent = 'No image found.'; } }); const moveHandler = (ev) => { popup.style.left = `${ev.pageX + 15}px`; popup.style.top = `${ev.pageY + 15}px`; }; const leaveHandler = () => { popup.remove(); link.removeEventListener('mousemove', moveHandler); link.removeEventListener('mouseleave', leaveHandler); }; link.addEventListener('mousemove', moveHandler); link.addEventListener('mouseleave', leaveHandler); }); }); })();