Greasy Fork

Greasy Fork is available in English.

价格历史 - 亚马逊英国

以非侵入式的方式来展示亚马逊英国商品的历史价格,使用第三方价格服务。

当前为 2021-01-05 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name               Price History - Amazon UK
// @description        A non-intrusive way to display Amazon UK item's history price, featuring third-party price history.
// @version            1.0

// @name:zh-CN         价格历史 - 亚马逊英国
// @description:zh-CN  以非侵入式的方式来展示亚马逊英国商品的历史价格,使用第三方价格服务。

// @namespace          uk.jixun
// @match              https://amazon.co.uk/*
// @match              https://www.amazon.co.uk/*
// @match              https://smile.amazon.co.uk/*
// @author             Jixun
// @license            bsd-3-clause
// @run-at             document-start
// @grant              none
// ==/UserScript==

const services = [{
  name: 'CCC',
  inline: false,
  url: asin => `https://uk.camelcamelcamel.com/product/${asin}`,
}, {
  name: 'Keepa',
  inline: asin => () => {
    const prevImage = $('keepa-history-embed');
    if (prevImage) {
      prevImage.style.display = prevImage.style.display === 'none' ? 'block' : 'none';
      return;
    }
    
    const src = `https://graph.keepa.com/pricehistory.png?asin=${asin}&domain=co.uk`;
    const $img = h('img', {src, id: 'keepa-history-embed'});
    const $price = $('price');
    if ($price) {
      $price.parentNode.insertBefore($img, $price.nextSibling);      
    } else {
      $('olp_feature_div').appendChild($img);
    }
  },
  url: asin => `https://keepa.com/#!product/2-${asin}`,
}];

const serviceStyle = {
  'marginRight': '0.5em',
  'display': 'inline-block',
};

const inlineStyle = {
  background: 'none',
  border: 'none',
};

function insertServices(asin) {
  return services.map(service => h('li', { style: serviceStyle }, [
    service.url && h('a', { href: service.url(asin), target: '_blank', rel: 'noreferrer' }, [service.name]),
    !service.url && h('span', null, [service.name]),
    service.inline && h('span', null, [
      ' (',
      h('a', { href: 'javascript:void(0)', onclick: service.inline(asin) }, 'inline'),
      ')',
    ])
  ]));
}

function $(id) {
  return document.getElementById(id);
}

function insertChildren(root, children = []) {
  if (!children) return;
  if (Array.isArray(children)) {
    for (const c of children) {
      insertChildren(root, c);
    }
    return;
  }
  if (typeof children === 'string') {
    children = document.createTextNode(children);
  }
  root.appendChild(children);
}

function h(tag, attr, ...children) {
  const el = document.createElement(tag);
  if (attr) {
    for(const [name, value] of Object.entries(attr)) {
      if (name === 'style') {
        Object.assign(el.style, value);
      } else {
        el[name] = value;
      }
    }
  }
  insertChildren(el, children);
  return el;
}

function injectPriceCompare() {
  const $asin = $('ASIN');
  if (!$asin || $asin.tagName !== 'INPUT') {
    console.info('asin not found.');
    return;
  }
  
  const asin = $asin.value;
  const $priceTable = document.querySelector('#price table > tbody') || $('olp_feature_div');
  const root = h('tr', null, [
    h('td', { className: 'a-color-secondary' }, ['History']),
    h('td', null, [
      h('ul', { style: {cssText: 'margin:0'} }, insertServices(asin)),
    ])
  ]);
  $priceTable.appendChild(root);
  return root;
}

function init() {
  const root = $('desktop_buybox');
  if (!root) {
    return;
  }

  const observer = new MutationObserver((mutationsList, observer) => {
    for(const {removedNodes} of mutationsList) {
      console.info(removedNodes);
      if (!removedNodes) continue;
      
      for (const node of removedNodes) {
        if (node.id === 'buybox') {
          injectPriceCompare();
          return;
        }
      }
    }
  });

  // Start observing the target node for configured mutations
  observer.observe(root, { childList: true });
  injectPriceCompare();
}

addEventListener('DOMContentLoaded', init);