您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Highlights monthly payments, adds ReviewMeta, CamelCamelCamel, Keepa, sticky UI, themes, ad hiding, and more for Amazon users. Gear icon is now moveable again.
// ==UserScript== // @name Amazon Enhancer: Monthly + ReviewMeta + Camel + Keepa + UI + Dark + Review Highlights // @namespace Eliminater74 // @version 1.4.2 // @description Highlights monthly payments, adds ReviewMeta, CamelCamelCamel, Keepa, sticky UI, themes, ad hiding, and more for Amazon users. Gear icon is now moveable again. // @author Eliminater74 // @license MIT // @match https://www.amazon.com/* // @match https://www.amazon.co.uk/* // @match https://www.amazon.de/* // @match https://www.amazon.fr/* // @match https://www.amazon.it/* // @match https://www.amazon.es/* // @match https://www.amazon.ca/* // @match https://smile.amazon.com/* // @grant GM_xmlhttpRequest // @connect reviewmeta.com // @run-at document-end // ==/UserScript== (function () { 'use strict'; const SETTINGS_KEY = 'amazonEnhancerSettings'; const defaultSettings = { showReviewMeta: true, showCamel: true, showKeepa: true, theme: 'auto', highlightBestReviews: true, hideAds: true, showSoldBy: true, stickyPriceBox: true, autoSortReviews: true, expandReviewsQA: true, highlightMonthlyPayments: true, filterOnlyMonthly: false }; const settings = JSON.parse(localStorage.getItem(SETTINGS_KEY)) || defaultSettings; const locale = getLocale(); const asin = findASIN(); if (asin) { applyTheme(settings.theme); if (settings.showReviewMeta) injectReviewMeta(asin, locale); if (settings.showCamel) injectCamel(asin, locale); if (settings.showKeepa) injectKeepa(asin, locale); } if (settings.highlightBestReviews) highlightReviews(); if (settings.hideAds) hideSponsored(); if (settings.showSoldBy) showSoldByBox(); if (settings.stickyPriceBox) makeStickyPriceBox(); if (settings.autoSortReviews) autoSortReviews(); if (settings.expandReviewsQA) expandSections(); if (settings.highlightMonthlyPayments || settings.filterOnlyMonthly) scanMonthlyPayments(); createToggleUI(); observePageChanges(); function saveSettings() { localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings)); } function applyTheme(mode) { const html = document.documentElement; const theme = (mode === 'auto') ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : mode; html.setAttribute('data-enhancer-theme', theme); let style = document.getElementById('amazon-enhancer-theme-style'); if (style) style.remove(); style = document.createElement('style'); style.id = 'amazon-enhancer-theme-style'; style.textContent = ` [data-enhancer-theme="dark"] .amazon-enhancer-box { background: #1d1d1d !important; color: #f0f0f0 !important; border-color: #555 !important; } [data-enhancer-theme="dark"] .amazon-enhancer-box a { color: #7dddf2 !important; } [data-enhancer-theme="dark"] .amazon-enhancer-panel { background: #2c2c2c !important; color: #eee !important; border-color: #555; } .highlighted-review { border: 2px solid gold !important; background-color: #fffbea !important; } .monthly-badge { position: absolute; top: 10px; left: 10px; background: #0099cc !important; color: #ffffff !important; padding: 2px 6px; font-weight: bold; font-size: 12px; border-radius: 4px; z-index: 2147483647 !important; } `; document.head.appendChild(style); } function getLocale() { const host = location.hostname; if (host.includes(".co.uk")) return "uk"; if (host.includes(".de")) return "de"; if (host.includes(".fr")) return "fr"; if (host.includes(".es")) return "es"; if (host.includes(".it")) return "it"; if (host.includes(".ca")) return "ca"; return "us"; } function findASIN() { const match = location.href.match(/\/([A-Z0-9]{10})(?:[/?]|$)/); if (match) return match[1]; const el = document.getElementById("ASIN") || document.querySelector('[name="ASIN.0"]'); return el?.value || null; } function injectCamel(asin, locale) { const div = document.createElement("div"); div.className = 'amazon-enhancer-box'; div.innerHTML = `<a href='https://${locale}.camelcamelcamel.com/product/${asin}' target='_blank'> <img src='https://charts.camelcamelcamel.com/${locale}/${asin}/amazon-new-used.png?force=1&zero=0&w=500&h=300' style='max-width:100%;'> </a>`; appendToTarget(div); } function injectKeepa(asin, locale) { const div = document.createElement("div"); div.className = 'amazon-enhancer-box'; div.innerHTML = `<a href='https://keepa.com/#!product/1-${asin}' target='_blank'> <img src='https://graph.keepa.com/pricehistory.png?used=1&amazon=1&new=1&domain=${locale}&asin=${asin}' style='max-width:100%;height:auto;'> </a>`; appendToTarget(div); } function injectReviewMeta(asin, locale) { const url = `https://reviewmeta.com/amazon${locale === 'us' ? '' : '-' + locale}/${asin}`; GM_xmlhttpRequest({ method: 'GET', url, onload: res => { const doc = new DOMParser().parseFromString(res.responseText, "text/html"); const stars = doc.querySelector('#adjusted-rating-large')?.textContent?.trim(); const percent = Array.from(doc.querySelectorAll('small')).find(e => e.textContent.includes('potentially unnatural'))?.querySelector('span span')?.textContent?.trim(); const div = document.createElement('div'); div.className = 'amazon-enhancer-box'; div.style = 'margin-top:10px;padding:10px;border:1px solid #ccc;'; div.innerHTML = stars ? `<b>ReviewMeta Adjusted:</b> <span style='color:firebrick'>${stars}/5</span><br/> <b>Fake Reviews:</b> <span style='color:firebrick'>${percent}</span><br/> <a href='${url}' target='_blank' style='color:green;'>View on ReviewMeta</a>` : `<b style='color:red;'>ReviewMeta data not found.</b><br/><a href='${url}' target='_blank'>Submit product</a>`; appendToTarget(div); } }); } function appendToTarget(el) { const target = document.getElementById("unifiedPrice_feature_div") || document.getElementById("title")?.closest(".a-section"); if (target) target.appendChild(el); } function createToggleUI() { const gear = document.createElement("div"); gear.innerText = "⚙️"; gear.id = "amazon-enhancer-gear"; gear.style.cssText = ` position: fixed; bottom: 20px; right: 20px; width: 40px; height: 40px; font-size: 22px; background: #222; color: #fff; border: 2px solid #888; border-radius: 50%; display: flex; justify-content: center; align-items: center; cursor: move; box-shadow: 0 0 12px rgba(0,0,0,0.8); z-index: 2147483647; `; const panel = document.createElement("div"); panel.className = 'amazon-enhancer-panel'; panel.style.cssText = 'position:fixed;bottom:70px;right:20px;border:1px solid #ccc;padding:10px;border-radius:8px;z-index:99999;background:#fff;display:none;'; const toggles = [ ['showReviewMeta', 'ReviewMeta'], ['showCamel', 'CamelCamelCamel'], ['showKeepa', 'Keepa'], ['highlightBestReviews', 'Highlight Best Reviews'], ['hideAds', 'Hide Sponsored Ads'], ['showSoldBy', 'Show Sold By'], ['stickyPriceBox', 'Sticky Price Box'], ['autoSortReviews', 'Auto Sort Reviews'], ['expandReviewsQA', 'Expand Q&A/Reviews'], ['highlightMonthlyPayments', 'Highlight Monthly Payments'], ['filterOnlyMonthly', 'Filter: Only Monthly Payment Items'] ]; panel.innerHTML = toggles.map(([key, label]) => `<label><input type='checkbox' id='${key}' ${settings[key] ? 'checked' : ''}/> ${label}</label><br/>` ).join('') + ` <label>Theme: <select id='themeSelect'> <option value='auto' ${settings.theme === 'auto' ? 'selected' : ''}>Auto</option> <option value='light' ${settings.theme === 'light' ? 'selected' : ''}>Light</option> <option value='dark' ${settings.theme === 'dark' ? 'selected' : ''}>Dark</option> </select> </label>`; toggles.forEach(([key]) => { panel.querySelector(`#${key}`).addEventListener('change', e => { settings[key] = e.target.checked; saveSettings(); location.reload(); }); }); panel.querySelector('#themeSelect').addEventListener('change', e => { settings.theme = e.target.value; saveSettings(); applyTheme(settings.theme); }); // Make gear draggable and clickable let isDragging = false, offsetX = 0, offsetY = 0; gear.addEventListener('mousedown', (e) => { isDragging = true; offsetX = e.clientX - gear.getBoundingClientRect().left; offsetY = e.clientY - gear.getBoundingClientRect().top; e.preventDefault(); }); document.addEventListener('mousemove', (e) => { if (isDragging) { gear.style.left = `${e.clientX - offsetX}px`; gear.style.top = `${e.clientY - offsetY}px`; gear.style.right = 'auto'; gear.style.bottom = 'auto'; } }); document.addEventListener('mouseup', () => { if (!isDragging) return; isDragging = false; }); gear.addEventListener('click', () => { if (!isDragging) panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; }); gear.ondragstart = () => false; document.body.appendChild(gear); document.body.appendChild(panel); } function highlightReviews() { const reviews = [...document.querySelectorAll('.review')]; const scored = reviews.map(el => { const helpful = parseInt(el.innerText.match(/(\d+,?\d*) people found this helpful/)?.[1]?.replace(',', '') || '0'); const verified = el.innerHTML.includes('Verified Purchase') ? 5 : 0; const longText = el.innerText.length > 500 ? 5 : 0; const hasMedia = el.querySelectorAll('img').length ? 5 : 0; return { el, score: helpful + verified + longText + hasMedia }; }); scored.sort((a, b) => b.score - a.score); scored.slice(0, 3).forEach(r => r.el.classList.add('highlighted-review')); } function scanMonthlyPayments() { const results = document.querySelectorAll('[data-component-type="s-search-result"], .s-result-item'); results.forEach(result => { const text = result.innerText; const match = /(?:\$\d+\.\d{2}\/month|\d+\s+monthly payments|\$[\d,]+(?:\.\d+)?\/mo\.?)/i.test(text); const already = result.querySelector('.monthly-badge'); if (match) { if (!already && settings.highlightMonthlyPayments) { const badge = document.createElement('div'); badge.className = 'monthly-badge'; badge.textContent = '💳 Monthly Payments'; result.style.position = 'relative'; result.appendChild(badge); } result.style.display = ''; } else if (settings.filterOnlyMonthly) { result.style.display = 'none'; } else { result.style.display = ''; } }); } function hideSponsored() { document.querySelectorAll("[data-component-type='sp-sponsored-result']").forEach(el => el.remove()); } function showSoldByBox() { const el = document.querySelector("#merchant-info"); if (el) el.style.border = "2px dashed orange"; } function makeStickyPriceBox() { const box = document.getElementById("corePrice_feature_div"); if (box) { box.style.position = "sticky"; box.style.top = "0"; box.style.background = "#fff"; box.style.zIndex = 9999; box.style.borderBottom = "2px solid #ccc"; } } function autoSortReviews() { const sortSelect = document.querySelector('select[name="sortBy"]'); if (sortSelect) sortSelect.value = "recent"; } function expandSections() { document.querySelectorAll(".a-expander-prompt").forEach(e => e.click()); } function observePageChanges() { const observer = new MutationObserver(() => { if (settings.highlightMonthlyPayments || settings.filterOnlyMonthly) scanMonthlyPayments(); }); observer.observe(document.body, { childList: true, subtree: true }); } })();