Amazon Order Check

Show alert to avoid multiple order.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name           Amazon Order Check
// @description:en Show alert to avoid multiple order.
// @version        0.1
// @namespace      https://twitter.com/foldrr
// @include        http://www.amazon.co.jp/*
// @include        https://www.amazon.co.jp/*
// @description Show alert to avoid multiple order.
// ==/UserScript==

(function (){
	// 警告メッセージ情報
	var warn = {
		message: '2つ以上注文している商品があります。<br>' +
		         '二重注文していないか数量を確認してください。',
		style: {
			backgroundColor: '#FFC000',
			borderStyle: 'solid',
			borderWidth: '4px',
			fontSize: '32pt',
			fontWeight: 'bold',
			padding: '20px'
		}
	};
	
	// エラーメッセージ情報
	var error = {
		message: 'Amazon注文チェックスクリプトでエラーが発生しました。<br>' +
		         '二重注文チェックができませんでした。<br>' +
		         'あなたの目で注文数量をよく確認してください。',
		style: {
			backgroundColor: '#FF8080',
			borderStyle: 'solid',
			borderWidth: '4px',
			fontSize: '32pt',
			fontWeight: 'bold',
			padding: '20px'
		}
	};
	
	// ページ設定
	var pages = [
		// href : チェックを適用するページのURL文字列。
		// cart : カートに商品がある場合に存在するはずのカート要素のXPath文字列。
		// items: カートにある商品要素のXPath文字列。
		// getter: 商品個数を表す要素を取り出すための関数。
		// pattern: 商品個数を抽出するための正規表現文字列。
		{
			// カートに入れた直後の画面
			href: 'http://www.amazon.co.jp/gp/cart/view-upsell.html',
			cart: '//form[@id="cartViewForm"]',
			items: "//td/span[@class='tiny']",
			getter: function(node){
				return node.firstChild.nodeValue;
			},
			pattern: "数量: (\\d+)",
		}
        , {
			// カートを見る
			href: 'http://www.amazon.co.jp/gp/cart/view.html/',
			cart: '//a[@name="tobuynow"]',
			items: '//form[@id="cartViewForm"]//input[@type="text"]',
			getter: function(node){
				return node.value;
			},
			pattern: "(\\d+)",
		}
        , {
			// 注文確定前の確認画面
			href: 'https://www.amazon.co.jp/gp/buy/payselect/handlers/continue.html',
			cart: null,
			items: '//span[@class="tiny"]',
			getter: function(node){
				return node.firstChild.nodeValue;
			},
			pattern: '数量[::  ]*(\\d+)',
		}
        /*
        /**/
	];
	
	main(document);
	
	// メイン処理
	function main(){
		for(var i = 0, n = pages.length; i < n; i++){
			if(! processPage(pages[i])){
				return;
			}
		}
	}
	
	// 指定したページ情報を処理する。
	function processPage(page){
		// 処理対象ページかチェックする。対象外なら正常終了。
		var href = document.location.href;
		if(href.indexOf(page.href) != 0){
			return true;
		}
		
		// 必要があれば、処理対象カートの存在をチェックする。存在しなければ正常終了。
		if(page.cart){
			var cart = $X(page.cart, document);
			if(! cart.snapshotLength){
				return true;
			}
		}
				
		// 処理対象商品の存在をチェックする。存在しなければエラー。
		var items = $X(page.items, document);
		if(! items.snapshotLength){
			return showMessage(error);
		}
		
		// 商品個数をチェックする。
		var hits = 0;
		var re = new RegExp(page.pattern);
		for(var i = 0, n = items.snapshotLength; i < n; i++){
			var text = page.getter(items.snapshotItem(i));
			var counter = (re.exec(text) || [])[1];
			if(counter){
				hits++;
				if(2 <= counter){
					return showMessage(warn);
				}
			}
		}
		
		// 商品個数を表す要素の取得に失敗していればエラー。
		if(hits == 0){
			return showMessage(error);
		}
		
		return true;
	}
	
	// 指定されたメッセージを表示する。
	function showMessage(messageData){
		var elem = document.createElement("div");
		elem.innerHTML = messageData.message;
		for(var k in messageData.style){
			elem.style[k] = messageData.style[k];
		}
		
		var body = document.getElementsByTagName('body')[0];
		body.insertBefore(elem, body.firstChild);
		
		return false;
	}
	
	// 指定したXPath文字列から要素を取得する。
	function $X(xpath, node){
		var nodes = node.evaluate(xpath,
			node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		return nodes;
	}
})();