// ==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. // @downloadURL https://update.greasyfork.icu/scripts/13694/Amazon%20Order%20Check.user.js // @updateURL https://update.greasyfork.icu/scripts/13694/Amazon%20Order%20Check.meta.js // ==/UserScript== (function (){ // 警告メッセージ情報 var warn = { message: '2つ以上注文している商品があります。
' + '二重注文していないか数量を確認してください。', style: { backgroundColor: '#FFC000', borderStyle: 'solid', borderWidth: '4px', fontSize: '32pt', fontWeight: 'bold', padding: '20px' } }; // エラーメッセージ情報 var error = { message: 'Amazon注文チェックスクリプトでエラーが発生しました。
' + '二重注文チェックができませんでした。
' + 'あなたの目で注文数量をよく確認してください。', 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; } })();