您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Highlights and hides sponsored content on eBay
// ==UserScript== // @name Spotless for eBay // @namespace https://github.com/OsborneLabs // @version 1.3.2 // @description Highlights and hides sponsored content on eBay // @author Osborne Labs // @license GPL-3 // @homepageURL https://github.com/OsborneLabs/Spotless // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNDcwLjYgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxLjQwNjU5MzQwNjU5MzQwMTYgMS40MDY1OTM0MDY1OTM0MDE2KSBzY2FsZSgyLjgxIDIuODEpIj4KICAgIDxwYXRoIGZpbGw9IiM4NDg0ODQiIGQ9Ik0xMjcuOCw0Ni4xSDM4LjdWNDJjMC0yMy40LDE5LjEtNDIuNSw0Mi41LTQyLjVoNC4xYzIzLjQsMCw0Mi41LDE5LjEsNDIuNSw0Mi41VjQ2LjF6IE00Mi43LDQyaDgxVjQyIGMwLTIxLjItMTcuMi0zOC40LTM4LjQtMzguNGgtNC4xQzYwLDMuNSw0Mi43LDIwLjgsNDIuNyw0Mkw0Mi43LDQyeiI+PC9wYXRoPgogICAgPHBhdGggZmlsbD0iI0U1MzIzOCIgZD0iTTM1LjEsMTgxLjdoLTkuNmMtMTQuMywwLTI1LjktMTEuNi0yNS45LTI1LjlWNDkuNGMwLTUuMiw0LjMtOS41LDkuNS05LjVoMjYuMUwzNS4xLDE4MS43TDM1LjEsMTgxLjd6Ij48L3BhdGg+CiAgICA8cmVjdCB4PSIzNS4xIiB5PSIzOS45IiBmaWxsPSIjMDA2NEQyIiB3aWR0aD0iNDguMSIgaGVpZ2h0PSIxNDEuOCI+PC9yZWN0PgogICAgPHJlY3QgeD0iODMuMiIgeT0iMzkuOSIgZmlsbD0iI0Y1QUYwMiIgd2lkdGg9IjQ4LjEiIGhlaWdodD0iMTQxLjgiPjwvcmVjdD4KICAgIDxwYXRoIGZpbGw9IiM4NkI4MTciIGQ9Ik0xNDEsMTgxLjdoLTkuNlYzOS45aDI2LjFjNS4yLDAsOS41LDQuMyw5LjUsOS41djEwNi40QzE2NywxNzAuMSwxNTUuMywxODEuNywxNDEsMTgxLjd6Ij48L3BhdGg+CiAgPC9nPgo8L3N2Zz4K // @match https://www.ebay.com/sch/* // @match https://www.ebay.at/sch/* // @match https://www.ebay.ca/sch/* // @match https://www.ebay.ch/sch/* // @match https://www.ebay.com.au/sch/* // @match https://www.ebay.com.hk/sch/* // @match https://www.ebay.com.my/sch/* // @match https://www.ebay.com.sg/sch/* // @match https://www.ebay.co.uk/sch/* // @match https://www.ebay.de/sch/* // @match https://www.ebay.es/sch/* // @match https://www.ebay.fr/sch/* // @match https://www.ebay.ie/sch/* // @match https://www.ebay.it/sch/* // @match https://www.ebay.nl/sch/* // @match https://www.ebay.pl/sch/* // @run-at document-start // @grant none // ==/UserScript== /* jshint esversion: 11 */ (function() { "use strict"; const APP_TITLE = "Spotless"; const SPONSORED_CONTENT_KEY = "hideSponsoredContent"; let hidingEnabled = localStorage.getItem(SPONSORED_CONTENT_KEY); hidingEnabled = hidingEnabled !== "false"; let highlightedSponsoredContent = []; let isProcessing = false; let updateScheduled = false; let observerInitialized = false; const APP_ICONS = { locked: ` <svg class="lock-icon lock-icon-animation" id="lockedIcon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M12 2C9.79 2 8 3.79 8 6v4H7c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2v-8c0-1.1-.9-2-2-2h-1V6c0-2.21-1.79-4-4-4zm-2 8V6c0-1.1.9-2 2-2s2 .9 2 2v4h-4z"/> </svg>`, unlocked: ` <svg class="lock-icon lock-icon-animation" id="unlockedIcon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M17 8V6c0-2.76-2.24-5-5-5S7 3.24 7 6h2c0-1.66 1.34-3 3-3s3 1.34 3 3v2H7c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2h-1z"/> </svg>`, arrow: ` <svg id="arrowIcon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M7 10l5 5 5-5z"/> </svg>`, heart: ` <svg class="heart-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41 0.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/> </svg>` }; function init() { initializeUI(); processSponsoredContent(); } function initializeUI() { createStyles(); buildPanel(); } function createStyles() { const style = document.createElement("style"); style.textContent = ` :root { --size-font-title: 18px; --size-font-body: 14px; --size-font-body-error: 16px; --size-font-footer: 12px; --color-bubble: #e74c3c; --color-divider-border: rgba(255, 255, 255, 0.1); --color-font-text: white; --color-font-link-hover: lightblue; --color-font-link-visited: lightblue; --color-highlight-background: #ffe6e6; --color-highlight-border: red; --color-panel: rgba(34, 50, 70, 0.85); --color-panel-shadow: 0 8px 20px rgba(0, 0, 0, 0.20); --color-row: rgba(20, 30, 45, 0.5); --color-svg-fill: white; --color-svg-fill-heart-hover: red; --color-switch-knob: white; --color-switch-off: #ccc; --color-switch-on: #2AA866; --color-switch-on-shadow: 0 0 4px rgba(39, 174, 96, 0.3); --thickness-highlight-border: 2px; } #panelWrapper { position: fixed; bottom: 10px; right: 5px; z-index: 2147483647; width: 100%; max-width: 320px; padding: 0 16px; box-sizing: border-box; font-family: "Segoe UI", sans-serif; } @media (max-width: 768px) { #panelWrapper { bottom: 5px; left: 50%; transform: translateX(-50%); width: 90% !important; right: unset; padding: 0 16px; } } #panelBox { display: flex; flex-direction: column; gap: 0px; background: var(--color-panel); backdrop-filter: blur(10px); color: var(--color-font-text); padding: 16px; border-radius: 12px; width: 100%; box-shadow: var(--color-panel-shadow); transition: transform 0.2s ease; } #panelBox:hover { transform: translateY(-2px); } #panelHeader { display: flex; align-items: center; gap: 8px; } #panelHeader h2.panel-title { font-size: var(--size-font-title); font-weight: 600; margin: 0; color: var(--color-font-text); } .panel-body-row { margin: 0; font-size: var(--size-font-body); display: flex; align-items: center; justify-content: space-between; background: var(--color-row); backdrop-filter: blur(12px); padding: 12px 16px; border-radius: 8px; } .panel-body-row + .panel-body-row { margin-top: 5px; } .panelFooter { display: flex; align-items: center; justify-content: flex-end; gap: 6px; font-size: var(--size-font-footer); color: var(--color-font-text); } .panelPageContainer { position: relative; width: 100%; } hr.section-divider { flex-grow: 1; border: none; border-top: 1px solid var(--color-divider-border); margin: 12px 0; } #minimizePanelButton { width: 28px; height: 28px; margin-left: auto; padding: 2px; border: none; background: none; display: flex; align-items: center; justify-content: center; cursor: pointer; box-sizing: content-box; } #panelBox.minimized #arrowIcon { transform: rotate(180deg); } #panelBox.minimized { padding: 12px; overflow: hidden; } .lock-icon { width: 24px; height: 24px; padding: 4px; border-radius: 50%; fill: var(--color-svg-fill); } .lock-icon-animation { position: absolute; top: 0; left: 0; width: 28px; height: 28px; opacity: 0; transition: opacity 0.4s ease, transform 0.4s ease; transform: rotate(0deg); } .lock-icon-animation.active { opacity: 1; transform: rotate(360deg); } #lockIconContainer { position: relative; width: 28px; height: 28px; } #arrowIcon { width: 28px; height: 28px; fill: var(--color-svg-fill); transition: transform 0.3s ease; } .heart-icon { width: 10px; height: 10px; vertical-align: middle; fill: var(--color-svg-fill); } .heart-icon:hover { fill: var(--color-svg-fill-heart-hover); } #countBubble { background-color: var(--color-bubble); color: var(--color-font-text); font-size: 12px; font-weight: bold; padding: 3px 8px; border-radius: 999px; min-width: 20px; text-align: center; } .switch { position: relative; display: inline-block; width: 42px; height: 22px; } .switch input { opacity: 0; width: 0; height: 0; } .switch-label { margin-right: 10px; } .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: var(--color-switch-off); transition: 0.3s; border-radius: 34px; } .slider:before { position: absolute; content: ""; height: 18px; width: 18px; top: 2px; left: 2px; background-color: var(--color-switch-knob); transition: 0.3s; border-radius: 50%; } input:checked + .slider { background-color: var(--color-switch-on); box-shadow: var(--color-switch-on-shadow); } input:checked + .slider:before { transform: translateX(20px); } #creator-page { color: var(--color-font-text); transition: color 0.3s ease; } #creator-page:hover, .outbound-status-page:hover, .retry-link:hover{ color: var(--color-font-link-hover); } .error-page { text-align: center; font-size: var(--size-font-body-error); } .outbound-status-page, .retry-link { text-decoration: underline; color: var(--color-font-text); } .outbound-status-page:visited, .retry-link:visited { color: var(--color-font-link-visited); } .sponsored-highlight { border: var(--thickness-highlight-border) solid var(--color-highlight-border) !important; background-color: var(--color-highlight-background); } .sponsored-hidden { display: none !important; } `; document.head.appendChild(style); } function determineCurrentPage(sponsoredCount) { if (sponsoredCount === 0) { return buildPanelErrorPage(); } return buildPanelHomePage(); } function initializeObserver() { if (observerInitialized) return; observer.observe(document.body, { childList: true, subtree: true, }); observerInitialized = true; } async function buildPanel() { const wrapper = document.createElement("div"); wrapper.id = "panelWrapper"; const box = document.createElement("div"); box.id = "panelBox"; const header = buildPanelHeader(); const sponsoredCount = await processSponsoredContent(); const body = determineCurrentPage(sponsoredCount, hidingEnabled); const footer = buildPanelFooter(); const topDivider = document.createElement("hr"); topDivider.className = "section-divider"; const bottomDivider = document.createElement("hr"); bottomDivider.className = "section-divider"; box.appendChild(header); box.appendChild(topDivider); box.appendChild(body); box.appendChild(bottomDivider); box.appendChild(footer); wrapper.appendChild(box); document.body.appendChild(wrapper); const minimizePanelButton = document.getElementById("minimizePanelButton"); minimizePanelButton.addEventListener("click", () => { const panelBox = document.getElementById("panelBox"); const isCurrentlyMinimized = panelBox.classList.contains("minimized"); const newState = !isCurrentlyMinimized; localStorage.setItem("panelMinimized", newState); setPanelMinimized(newState); }); const isPanelMinimized = localStorage.getItem("panelMinimized") === "true"; setPanelMinimized(isPanelMinimized); const toggleSponsoredContentSwitchInput = document.getElementById("toggleSponsoredContentSwitch"); if (!toggleSponsoredContentSwitchInput) { updateLockIcons(); return; } toggleSponsoredContentSwitchInput.addEventListener("change", (e) => { hidingEnabled = e.target.checked; localStorage.setItem(SPONSORED_CONTENT_KEY, hidingEnabled); updateLockIcons(); debounceHighlighting(); }); updateLockIcons(); } function buildPanelHeader() { const header = document.createElement("div"); header.id = "panelHeader"; header.innerHTML = ` <div id="lockIconContainer"> ${APP_ICONS.locked} ${APP_ICONS.unlocked} </div> <h2 class="panel-title" aria-level="1">${APP_TITLE}</h2> <button id="minimizePanelButton" aria-label="Expand or minimize the panel"> ${APP_ICONS.arrow} </button> `; return header; } function buildPanelFooter() { const footer = document.createElement("div"); footer.className = "panelFooter"; const creatorPage = document.createElement("a"); creatorPage.href = "https://github.com/OsborneLabs/Spotless"; creatorPage.target = "_blank"; creatorPage.style.textDecoration = "none"; creatorPage.textContent = "Osborne"; creatorPage.id = "creator-page"; const separator = document.createElement("span"); separator.textContent = " · "; const donatePage = document.createElement("a"); donatePage.href = "https://ko-fi.com/osbornelabs"; donatePage.target = "_blank"; donatePage.innerHTML = APP_ICONS.heart; donatePage.style.display = "inline-flex"; donatePage.style.alignItems = "center"; donatePage.style.justifyContent = "center"; footer.appendChild(creatorPage); footer.appendChild(separator); footer.appendChild(donatePage); return footer; } function buildPanelRow(innerHTML = "") { const row = document.createElement("div"); row.className = "panel-body-row"; row.innerHTML = innerHTML; return row; } function buildCountSponsoredContentRow() { const row = buildPanelRow(` <span>Content found</span> <span id="countBubble">0</span> `); row.id = "count-sponsored-content-row"; return row; } function buildToggleSponsoredContentRow() { const row = buildPanelRow(` <span class="switch-label">Hide sponsored content</span> <label class="switch" aria-label="Toggle visibility of sponsored content"> <input type="checkbox" id="toggleSponsoredContentSwitch" ${hidingEnabled ? "checked" : ""}> <span class="slider"></span> </label> `); row.id = "toggle-sponsored-content-row"; return row; } function buildPanelHomePage() { const pageContainer = document.createElement("div"); pageContainer.id = "panelPageContainer"; pageContainer.classList.add("panelPageContainer"); const homePage = document.createElement("div"); homePage.id = "homePage"; homePage.className = "panel-page"; homePage.style.display = "block"; const countSponsoredContentRow = buildCountSponsoredContentRow(); const toggleSponsoredContentRow = buildToggleSponsoredContentRow(); homePage.appendChild(countSponsoredContentRow); homePage.appendChild(toggleSponsoredContentRow); pageContainer.appendChild(homePage); return pageContainer; } function buildPanelErrorPage() { const errorPage = document.createElement("div"); errorPage.classList.add("error-page", "panel-page"); const errorMessage = document.createElement("p"); errorMessage.textContent = "No sponsored content found. "; errorMessage.appendChild(document.createElement("br")); const outboundRetryPage = document.createElement("a"); outboundRetryPage.textContent = "Retry"; outboundRetryPage.href = "#"; outboundRetryPage.addEventListener("click", function(event) { event.preventDefault(); location.reload(); }); outboundRetryPage.classList.add("retry-link"); const outboundStatusPage = document.createElement("a"); outboundStatusPage.textContent = "check status"; outboundStatusPage.href = "https://github.com/OsborneLabs/Spotless"; outboundStatusPage.target = "_blank"; outboundStatusPage.classList.add("outbound-status-page"); errorMessage.appendChild(outboundRetryPage); errorMessage.appendChild(document.createTextNode(" or ")); errorMessage.appendChild(outboundStatusPage); const endText = document.createTextNode("."); errorMessage.appendChild(endText); errorPage.appendChild(errorMessage); return errorPage; } function setPanelMinimized(minimized) { const panelBox = document.getElementById("panelBox"); if (!panelBox) return; const panelPage = panelBox.querySelector(".panel-page"); const sectionDividers = panelBox.querySelectorAll(".section-divider"); const panelFooter = panelBox.querySelector(".panelFooter"); panelBox.classList.toggle("minimized", minimized); if (panelPage) panelPage.style.display = minimized ? "none" : "block"; sectionDividers.forEach(el => { el.style.display = minimized ? "none" : ""; }); if (panelFooter) panelFooter.style.display = minimized ? "none" : ""; } function updateLockIcons() { const locked = document.getElementById("lockedIcon"); const unlocked = document.getElementById("unlockedIcon"); locked.classList.toggle("active", hidingEnabled); unlocked.classList.toggle("active", !hidingEnabled); } function getListingElements() { return Array.from(document.querySelectorAll("li[class*='s-']")).filter( (el) => el.className.split(/\s+/).some((cls) => /^s-[\w-]+$/.test(cls)) ); } function detectSponsoredListingByBase64(batchSize = 5) { return new Promise((resolve) => { const listings = getListingElements(); const sponsoredElements = []; let index = 0; function processBatch() { const end = Math.min(index + batchSize, listings.length); const batch = listings.slice(index, end); let processedInBatch = 0; if (batch.length === 0) { resolve(sponsoredElements); return; } batch.forEach((listing) => { const svgImage = listing.querySelector(".s-item__sep span[aria-hidden='true']"); if (!svgImage) return done(); const backgroundImage = getComputedStyle(svgImage.parentElement).backgroundImage; const match = backgroundImage.match(/url\("data:image\/svg\+xml;base64,([^"]+)"\)/); if (!match || !match[1]) return done(); const base64 = match[1]; const svgString = atob(base64); const img = new Image(); const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); img.src = "data:image/svg+xml;base64," + btoa(svgString); img.onload = () => { canvas.width = img.naturalWidth || 25; canvas.height = img.naturalHeight || 25; ctx.drawImage(img, 0, 0); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data; for (let i = 0; i < imageData.length; i += 4) { const r = imageData[i]; const g = imageData[i + 1]; const b = imageData[i + 2]; const a = imageData[i + 3]; if (a > 0 && r === 112 && g === 112 && b === 112) { sponsoredElements.push(listing); break; } } done(); }; img.onerror = () => { done(); }; function done() { processedInBatch++; if (processedInBatch === batch.length) { index += batchSize; setTimeout(processBatch, 0); } } }); if (batch.length === 0) resolve(sponsoredElements); } if (listings.length === 0) { resolve([]); } else { processBatch(); } }); } function detectSponsoredListingByAriaID(listings = getListingElements()) { const groupMap = {}; const ariaLabelToGroup = {}; let groupCounter = 0; listings.forEach(listing => { const labelSpans = Array.from(listing.querySelectorAll('span[aria-labelledby]')); if (labelSpans.length === 0) return; for (const spanElement of labelSpans) { const ariaLabel = spanElement.getAttribute('aria-labelledby'); if (!ariaLabel || !ariaLabel.includes("s-")) continue; if (!ariaLabelToGroup[ariaLabel]) { ariaLabelToGroup[ariaLabel] = `Group ${numberToLettersForAriaID(groupCounter)}`; groupCounter++; } const group = ariaLabelToGroup[ariaLabel]; if (!groupMap[group]) { groupMap[group] = []; } groupMap[group].push(listing); break; } }); let sponsoredGroup = null; let minCount = Infinity; for (const [group, groupListings] of Object.entries(groupMap)) { if (groupListings.length < minCount) { sponsoredGroup = group; minCount = groupListings.length; } } return sponsoredGroup ? groupMap[sponsoredGroup] : []; } function numberToLettersForAriaID(num) { let result = ''; while (num >= 0) { result = String.fromCharCode((num % 26) + 65) + result; num = Math.floor(num / 26) - 1; } return result; } function detectSponsoredListingByInvertFilter() { const INVERT_REGEX = /div\.([a-zA-Z0-9_-]+)(?:\s+div)?\s*\{[^}]*color:\s*(black|white);[^}]*filter:\s*invert\(([-\d.]+)\)/g; const sponsoredGroups = {}; const classToInvertMap = {}; const styleTags = Array.from(document.querySelectorAll("style")); styleTags.forEach(styleTag => { const css = styleTag.textContent; let match; while ((match = INVERT_REGEX.exec(css)) !== null) { const [_, className, color, invertValue] = match; if (!classToInvertMap[className]) { classToInvertMap[className] = []; } classToInvertMap[className].push({ color, invert: parseFloat(invertValue) }); } }); const containers = Array.from(document.querySelectorAll('div[role="text"]')).filter(container => { return container.querySelector('div[aria-hidden="true"]'); }); containers.forEach(container => { const targetDiv = container.querySelector('div[aria-hidden="true"]'); if (!targetDiv) return; const ancestorDiv = container.closest("div[class*='_']"); if (!ancestorDiv) return; const classList = Array.from(ancestorDiv.classList); const dynamicClass = classList.find(cls => classToInvertMap[cls]); if (!dynamicClass) return; const candidates = classToInvertMap[dynamicClass]; const invertEntry = candidates?.[0]; if (!invertEntry) return; const key = invertEntry.invert; if (!sponsoredGroups[key]) { sponsoredGroups[key] = []; } sponsoredGroups[key].push(container); }); const groupEntries = Object.entries(sponsoredGroups); if (groupEntries.length === 0) { return { allGroups: [] }; } const sortedGroups = groupEntries.sort((a, b) => a[1].length - b[1].length); const [sponsoredInvert, sponsoredList] = sortedGroups[0]; return { invert: parseFloat(sponsoredInvert), elements: sponsoredList, allGroups: groupEntries }; } function detectSponsoredBanner() { const tld = getEffectiveTLD(); if (tld !== "co.uk" && tld !== "com.au" && tld !== "de") return []; return new Promise((resolve) => { setTimeout(() => { const banners = Array.from( document.querySelectorAll(".s-answer-region-center-top.s-answer-region > div") ).filter((el) => { return !el.className.includes("srp-controls") && el.offsetHeight >= 100; }); resolve(banners); }, 525); }); } async function processSponsoredContent() { if (isProcessing) return 0; isProcessing = true; try { observer.disconnect(); clearDesignateSponsoredContent(); const listings = getListingElements(); const unprocessedListings = listings.filter(el => !el.hasAttribute("data-sponsored-processed")); const detectedSponsoredElements = new Set(); const base64Results = await detectSponsoredListingByBase64(); base64Results.forEach(el => { const li = el.closest("li"); if (li) detectedSponsoredElements.add(li); }); if (detectedSponsoredElements.size === 0) { const ariaMethod = detectSponsoredListingByAriaID(unprocessedListings); ariaMethod.forEach(listing => { const li = listing.closest("li"); if (li) detectedSponsoredElements.add(li); }); } if (detectedSponsoredElements.size === 0) { const invertMethod = detectSponsoredListingByInvertFilter(); invertMethod.elements?.forEach(container => { const li = container.closest("li"); if (li) detectedSponsoredElements.add(li); }); } const banners = await detectSponsoredBanner(); banners.forEach(banner => { detectedSponsoredElements.add(banner); }); requestAnimationFrame(() => { for (const el of detectedSponsoredElements) { if (!el.hasAttribute("data-sponsored-processed")) { designateSponsoredContent(el); highlightSponsoredContent(el); hideShowSponsoredContent(el, hidingEnabled); } } const count = detectedSponsoredElements.size; countSponsoredContent(count); initializeObserver(); isProcessing = false; }); return detectedSponsoredElements.size; } catch (err) { console.error("Error processing sponsored content:", err); isProcessing = false; initializeObserver(); return 0; } } function designateSponsoredContent(el) { el.setAttribute("data-sponsored", "true"); el.setAttribute("data-sponsored-processed", "true"); highlightedSponsoredContent.push(el); } function clearDesignateSponsoredContent() { highlightedSponsoredContent.forEach(el => { el.classList.remove("sponsored-hidden"); el.removeAttribute("data-sponsored"); el.removeAttribute("data-sponsored-processed"); el.style.border = ""; el.style.backgroundColor = ""; }); highlightedSponsoredContent.length = 0; } function highlightSponsoredContent(element) { element.setAttribute("data-sponsored", "true"); element.classList.add("sponsored-highlight"); } function hideShowSponsoredContent(element, hide) { element.classList.toggle("sponsored-hidden", hide); } function countSponsoredContent(count) { const countBubble = document.getElementById("countBubble"); if (countBubble) countBubble.textContent = count; } function debounceHighlighting() { if (updateScheduled || isProcessing) return; updateScheduled = true; requestAnimationFrame(() => { processSponsoredContent().finally(() => { updateScheduled = false; }); }); } function getEffectiveTLD() { const host = window.location.hostname; const tldMap = { "ebay.com.au": "com.au", "ebay.com.hk": "com.hk", "ebay.com.my": "com.my", "ebay.com.sg": "com.sg", "ebay.co.uk": "co.uk", "ebay.at": "at", "ebay.ca": "ca", "ebay.ch": "ch", "ebay.de": "de", "ebay.es": "es", "ebay.fr": "fr", "ebay.ie": "ie", "ebay.it": "it", "ebay.nl": "nl", "ebay.pl": "pl", "ebay.com": "com", }; return Object.entries(tldMap).find(([domain]) => host.endsWith(domain))?.[1] || "Unknown"; } const observer = new MutationObserver(() => { debounceHighlighting(); }); (async function() { if (document.readyState === "complete" || document.readyState === "interactive") { await new Promise(r => setTimeout(r, 200)); init(); } else { window.addEventListener("DOMContentLoaded", async () => { await new Promise(r => setTimeout(r, 200)); init(); }); } })(); window.addEventListener("storage", (event) => { if (event.key === SPONSORED_CONTENT_KEY) { const newValue = event.newValue === "true"; if (newValue !== hidingEnabled) { hidingEnabled = newValue; const toggleSponsoredContentSwitchInput = document.getElementById("toggleSponsoredContentSwitch"); if (toggleSponsoredContentSwitchInput) toggleSponsoredContentSwitchInput.checked = hidingEnabled; updateLockIcons(); debounceHighlighting(); } } else if (event.key === "panelMinimized") { setPanelMinimized(event.newValue === "true"); } }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址