Amazon商品ページでKindle配信先を自動的に選択する Chrome(またはEdge)の拡張機能を作った(その1)
の続き。
インストール方法
(その1)を参照。コードのデバイスIDに書き換えも(その1)で説明している。
解説
配信先関連のエレメントについては(その1)で説明。
(その2)の特殊な点は以下のとおり。
- manifest.json の設定でrun_at の属性値が document_start になっている。
- MutationObserverを利用し、DOM構築中に処理を行っている。
manifest.json
{
"name": "Kindle DeliverTo Selector",
"description": "Autoselect deliverTo Kindle device.",
"version": "2.0",
"manifest_version": 3,
"content_scripts": [
{
"matches": ["https://www.amazon.co.jp/dp/*",
"https://www.amazon.co.jp/*/dp/*",
"https://www.amazon.co.jp/gp/product/*",
"https://www.amazon.co.jp/exec/obidos/ASIN/*",
"https://www.amazon.co.jp/o/ASIN/*"],
"run_at": "document_start",
"js": ["content_script.js"]
}
]
}
content_script.js
'use strict';
(function () {
//デバイスID
const deviceId = 'AL13906LU4VTW';
//これを自分のデバイスIDに書き換えること
//デバイスIDはHTMLソースにてSELECTエレメント(id="deliverTo")を調査すれば分かる
const observeConfig = { childList: true, subtree: true};
//DOM変更時処理
// 本関数はDOMに変更があった際、オブザーバーより呼び出される
function onMutate(mutations) {
for(const m of mutations) {
const elem = m.target;
//ドロップダウンの選択結果を表示するSPANエレメントか判定
if(elem.tagName === 'SPAN' && elem.classList.contains('a-dropdown-prompt')) {
do {
//祖先の配信先divを取得
const div = elem.closest('div#deliverTo');
if(div == null) {
break;
}
//SELECTエレメントを取得
const select = div.querySelector('select#deliverTo');
if(select == null) {
break;
}
//OPTIONエレメントを取得
const opts = select.getElementsByTagName('option');
for(const opt of opts) {
if(opt.value === deviceId) {
//エレメントを変更するため、無限ループに陥らないよう変更監視を停止する
observer.disconnect();
//SELECTエレメントの値を設定
select.value = opt.value;
//elem.dispatchEvent(new Event('change', { bubbles: true }));
//SPANのデバイス名を書き換える
elem.innerHTML = opt.innerHTML;
//監視の再始動
observer.observe(document, observeConfig);
break;
}
}
} while(false);
}
}
}
//オブザーバを作成
const observer = new MutationObserver(onMutate);
//ロード時イベントの処理登録(オブザーバーを停止させる)
addEventListener('DOMContentLoaded',
function (event) { observer.disconnect(); }, {capture: true, once: true});
//監視の始動
observer.observe(document, observeConfig);
})();