// ==UserScript== // @name Amazon Product Price Loader (Optimized) // @namespace http://tampermonkey.net/ // @version 1.0 // @description Load Amazon product pages and display price in a tooltip // @license MIT https://opensource.org/licenses/MIT // @match https://sellercentral.amazon.com/* // @match https://sellercentral.amazon.co.uk/* // @match https://sellercentral.amazon.de/* // @match https://sellercentral.amazon.fr/* // @match https://sellercentral.amazon.it/* // @match https://sellercentral.amazon.es/* // @match https://sellercentral.amazon.ca/* // @match https://sellercentral.amazon.com.mx/* // @match https://sellercentral.amazon.com.br/* // @match https://sellercentral.amazon.co.jp/* // @match https://sellercentral.amazon.in/* // @match https://sellercentral.amazon.com.au/* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @run-at document-end // @downloadURL none // ==/UserScript== (function() { 'use strict'; // Create and append tooltip element const tooltip = document.createElement('div'); tooltip.id = 'priceTooltip'; GM_addStyle(` #priceTooltip { position: fixed; background-color: #fff; border: 1px solid #ddd; padding: 5px 10px; border-radius: 4px; box-shadow: 0 2px 5px rgba(0,0,0,0.2); display: none; z-index: 10000; font-family: Arial, sans-serif; font-size: 14px; } `); document.body.appendChild(tooltip); let tooltipTimeout; const priceCache = {}; function extractPrice(html) { const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const priceSelectors = [ '.a-price .a-offscreen', '#priceblock_ourprice', '#priceblock_dealprice', '.a-price-whole', '.a-offscreen' ]; for (let selector of priceSelectors) { const priceElement = doc.querySelector(selector); if (priceElement) { return priceElement.textContent.trim(); } } return null; } async function loadProductPage(url) { if (priceCache[url]) { return Promise.resolve(priceCache[url]); } return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: url, onload: function(response) { if (response.status === 200) { const price = extractPrice(response.responseText); priceCache[url] = price; resolve(price); } else { reject('Failed to load page'); } }, onerror: function(error) { reject(error); } }); }); } function debounce(func, wait) { let timeout; return function(...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), wait); }; } const handleMouseover = debounce(function(e) { const link = e.target.closest('a[href*="/dp/"], a[href*="/product/"]'); if (link) { const url = link.href; clearTimeout(tooltipTimeout); tooltipTimeout = setTimeout(() => { tooltip.textContent = 'Loading price...'; tooltip.style.display = 'block'; updateTooltipPosition(e); loadProductPage(url) .then(price => { if (price) { tooltip.textContent = `Price: ${price}`; } else { tooltip.textContent = 'Price not found'; } }) .catch(error => { tooltip.textContent = 'Error loading price'; console.error('Error loading price:', error); }); }, 300); // Reduced delay for faster response } }, 200); // Debounce mouseover to limit request frequency document.addEventListener('mouseover', handleMouseover); document.addEventListener('mouseout', function(e) { if (e.target.closest('a[href*="/dp/"], a[href*="/product/"]')) { clearTimeout(tooltipTimeout); tooltipTimeout = setTimeout(() => { tooltip.style.display = 'none'; }, 100); } }); document.addEventListener('mousemove', updateTooltipPosition); function updateTooltipPosition(e) { const x = e.clientX + 10; const y = e.clientY + 10; tooltip.style.left = x + 'px'; tooltip.style.top = y + 'px'; } })();