Amazon Order Check

Show alert to avoid multiple order.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 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;
	}
})();