// ==UserScript==
// @name Amazon eBook Mark
// @namespace https://greasyfork.org/users/34380
// @version 20210724
// @description 标记已购的电子书。
// @match https://www.amazon.cn/*
// @grant GM_setValue
// @grant GM_getValue
// @downloadURL https://update.greasyfork.icu/scripts/429768/Amazon%20eBook%20Mark.user.js
// @updateURL https://update.greasyfork.icu/scripts/429768/Amazon%20eBook%20Mark.meta.js
// ==/UserScript==
(function () {
'use strict';
const is_autosave = GM_getValue('is_autosave', false);
const loc = location.href;
let asins_s = GM_getValue('asins_saved', []);
let asins_a = GM_getValue('asins_added', []);
if (loc.match(/\/kindle-dbs\/thankYouPage/) && is_autosave) {
autoSaveBookPage();
}
setTimeout(() => {
addBookButton();
if (document.querySelector('#ng-app')) {
saveAllBooksPage();
} else if (loc.match(/\/dp\//) || loc.match(/\/product\//)) {
viewBookDetailPage();
}
markBooksPage();
}, 5000);
function addBookButton() {
document.querySelector('#nav-xshop').insertAdjacentHTML('afterbegin', `
添加书籍
`);
document.querySelector('body').insertAdjacentHTML('afterbegin', `
`);
document.querySelector('#display-panel').addEventListener('click', () => {
document.querySelector('#fixed-panel').style.display = 'block';
});
document.querySelector('#refresh-page').addEventListener('click', () => {
const nodes_added = document.querySelectorAll('.added');
for (const node of nodes_added) {
const href = node.parentNode.href;
const matched = href.match(/dp\/(\w+)\//) || href.match(/\/product\/(\w+)\?/);
if (!asins_a.includes(matched[1])) {
node.classList.remove('added');
}
}
markOwnedAdded(document);
});
document.querySelector('#btn-add-book').addEventListener('click', () => {
const input_link = document.querySelector('#book-link');
const asin = input_link.value.match(/\/dp\/(\w+)/) || input_link.value.match(/\/product\/(\w+)/);
if (!asins_a.includes(asin[1])) {
asins_a.push(asin[1]);
GM_setValue('asins_added', asins_a);
input_link.value = '';
input_link.setAttribute('placeholder', '添加成功');
} else {
input_link.value = '';
input_link.setAttribute('placeholder', '已添加');
}
});
document.querySelector('#btn-delete-book').addEventListener('click', () => {
const input_link = document.querySelector('#book-link');
const asin = input_link.value.match(/\/dp\/(\w+)/) || input_link.value.match(/\/product\/(\w+)/);
if (asins_a.includes(asin[1])) {
asins_a.splice(asins_a.indexOf(asin[1]), 1);
GM_setValue('asins_added', asins_a);
input_link.value = '';
input_link.setAttribute('placeholder', '删除成功');
} else {
input_link.value = '';
input_link.setAttribute('placeholder', '已删除');
}
});
}
function saveAllBooksPage() {
document.querySelector('.myx-spacing-top-mini').insertAdjacentHTML('beforeend', `
已保存 ${asins_s.length} 本,添加已购 ${asins_a.length}本。
`);
document.querySelector('#save-asins').addEventListener('click', () => {
const items = document.querySelectorAll('.listItem_myx > div');
for (const item of items) {
const asin = item.getAttribute('name').replace('contentTabList_', '');
if (!asins_s.includes(asin)) { asins_s.push(asin); }
}
GM_setValue('asins_saved', asins_s);
document.querySelector('#saved').innerText = asins_s.length;
});
document.querySelector('#clear-asins-added').addEventListener('click', () => {
GM_setValue('asins_added', []);
});
document.querySelector('#cb-autosave').checked = GM_getValue('is_autosave', false);
document.querySelector('#cb-autosave').addEventListener('click', function () {
GM_setValue('is_autosave', this.checked);
});
}
function autoSaveBookPage() {
const asin_loc = loc.match(/asin=(\w+)&/)[1];
if (!asins_s.includes(asin_loc)) {
asins_s.push(asin_loc);
GM_setValue('asins_saved', asins_s);
document.title = '已购电子书自动保存成功。';
}
}
function viewBookDetailPage() {
const asin_loc = loc.match(/\/dp\/(\w+)/) || loc.match(/\/product\/(\w+)/);
if (!asins_s.includes(asin_loc[1])) {
document.querySelector('#title').insertAdjacentHTML('afterbegin', `
`);
document.querySelector('#cb-add-book').checked = asins_a.includes(asin_loc[1]);
document.querySelector('#cb-add-book').addEventListener('click', function () {
if (this.checked) {
asins_a.push(asin_loc[1]);
GM_setValue('asins_added', asins_a);
} else {
asins_a.splice(asins_a.indexOf(asin_loc[1]), 1);
GM_setValue('asins_added', asins_a);
}
});
}
}
function markBooksPage() {
markOwnedAdded(document);
const config = { attributes: false, childList: true, subtree: true };
const threadMutation = (mutationsList) => {
for (let mutation of mutationsList) {
if (mutation.type == 'childList' && mutation.addedNodes.length > 0) {
for (let node of mutation.addedNodes) {
if (node.nodeName == 'DIV') { markOwnedAdded(node); }
}
}
}
};
let container = document.querySelector("#a-page");
let threadObserver = new MutationObserver(threadMutation);
threadObserver.observe(container, config);
}
function markOwnedAdded(node) {
// 1/2 common top and bottom 3 search 4 recommend 5 bestseller 6 product
const title_class1 = ['.acs-product-block__product-title',
'.a-spacing-top-small > .a-link-normal',
'.s-line-clamp-2 > .a-link-normal.a-text-normal'];
const titles1 = node.querySelectorAll(title_class1.join(','));
for (const title of titles1) {
const href = title.href;
const asin = href.match(/\/dp\/(\w+)/)[1] ;
if (asins_s.includes(asin)) {
title.querySelector('*').classList.add('owned');
} else if (asins_a.includes(asin)) {
title.querySelector('*').classList.add('added');
}
}
const title_class2 = ['.a-carousel-card > div > .a-link-normal:nth-last-of-type(1)',
'.aok-inline-block.zg-item > .a-link-normal'];
const titles2 = node.querySelectorAll(title_class2.join(','));
for (const title of titles2) {
const href = title.href;
const asin = href.match(/\/dp\/(\w+)/)[1];
if (asins_s.includes(asin)) {
title.querySelector(':nth-child(2)').classList.add('owned');
} else if (asins_a.includes(asin)) {
title.querySelector(':nth-child(2)').classList.add('added');
}
}
const title_class3 = ['.a-box-group.a-spacing-top-micro >.a-size-small.a-link-normal'];
const titles3 = node.querySelectorAll(title_class3.join(','));
for (const title of titles3) {
const href = title.href;
const asin = href.match(/\/product\/(\w+)/)[1];
if (asins_s.includes(asin)) {
title.classList.add('owned');
} else if (asins_a.includes(asin)) {
title.classList.add('added');
}
}
}
document.querySelector('head').insertAdjacentHTML('beforeend', ``);
})();