// ==UserScript==
// @name Amazon送料込
// @version 0.86
// @description Amazonで送料込みの値段を表示する
// @match https://www.amazon.co.jp/dp/*
// @match https://www.amazon.co.jp/*/dp/*
// @match https://www.amazon.co.jp/gp/product/*
// @match https://www.amazon.co.jp/*/ASIN/*
// @match https://www.amazon.co.jp/product-reviews/*
// @match https://www.amazon.co.jp/*/product-reviews/**
// @author TNB
// @license MIT
// @grant none
// @namespace https://gf.qytechs.cn/users/3989
// ==/UserScript==
/******************** SETTING **************************/
// ハイライトテキストの色
const highlight_color = '#f00';
// 評価の設定値を下回った出品者の背景色
const caution_exhibitors_bg_color = 'rgba(255, 0, 0, 0.2)';
// 新規出品者の背景色
const new_exhibitors_bg_color = 'rgba(0, 0, 255, 0.2)';
// 一つでも下記の設定未満の評価がある場合出品者の背景色をcaution_exhibitors_bg_colorに変えます。0にするとその項目ではフィルターされません。
// 星の数
const star = 4;
// 評価件数
const evaluations_count = 15;
// 高評価の割合(%)
const evaluation = 70;
// 一つでも下記の設定未満の評価がある場合出品者を非表示にします。各項目の意味は上の設定と同じ。
const min_star = 3;
const min_evaluations_count = 0;
const min_evaluation = 60;
/********************************************************/
(function() {
'use strict';
(function() {
const style = document.head.appendChild(document.createElement('style'));
style.innerHTML = `
.aas_rated_low{filter: invert(12%) sepia(77%) saturate(7199%) hue-rotate(359deg) brightness(102%) contrast(108%);}
span.aas_highlight_text,.aas_highlight_text>span,.aas_count_low{color:${highlight_color} !important;}
.aas_bold_text{font-weight:bold;}
.aas_remove_exhibitors{display:none;}
.aas_caution_exhibitors{background:${caution_exhibitors_bg_color};}
.aas_new_exhibitors{background:${new_exhibitors_bg_color};}
span.aas_base_price{display:block;position:absolute;padding:1px 10px;background:#fff;color:#000 !important;top:0;margin-top:-35px;border:1px solid #ddd;border-radius:10%;font-size:14px;font-weight:normal;opacity:0;visibility:hidden;z-index:9999999;}
.aas_base_price:before,.aas_base_price:after{content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);}
.aas_base_price:before{border:6px solid transparent;border-top:6px solid #ddd;}
.aas_base_price:after{border:4px solid transparent;border-top:4px solid #fff;margin-top:0;}
span+span>.aas_base_price{left:0;}
#moreBuyingChoices_feature_div .aas_base_price{margin-top:-25px;}
#usedOnlyBuybox .aas_base_price{margin-top:-10px;}
#usedAccordionRow .aas_base_price{margin-top:0;}
#buyBoxAccordion>div{overflow:initial;}
.aas_highlight_text:hover>.aas_base_price:not(:hover){opacity:1;visibility:visible;transition:opacity .2s;}
/*** for Chrome ***/
#usedOnlyBuybox .a-price-whole+.aas_base_price,#usedAccordionRow .a-price-whole+.aas_base_price{margin-top:-30px;}
.a-accordion .a-accordion-inner{overflow:initial !important;}
`;
})();
function isHighlighting(i) {
const rating = i.firstElementChild.className.match(/\sa-star-brand-mini-(.*?)\s/);
if (!rating) return 'aas_new_exhibitors';
const data = i.textContent.match(/(\d+).+?(\d+)%/);
const r = rating[1].replace(/-/, '.');
const len = data[1];
const par = data[2];
if (min_star > r || min_evaluations_count > len || min_evaluation > par) return 'aas_remove_exhibitors';
if (star > r) i.firstElementChild.classList.add('aas_rated_low');
if (evaluations_count > len) i.innerHTML = addHighlightText(i, `${len}件`, 'aas_count_low');
if (evaluation > par) i.innerHTML = addHighlightText(i, `${par}%`, 'aas_count_low');
if (i.querySelector('.aas_count_low, .aas_rated_low')) return 'aas_caution_exhibitors';
}
function checkExhibitors() {
const exhibitors = document.querySelectorAll('#aod-offer-seller-rating:not(.aas_rating_checked)');
if (exhibitors.length === 0) return;
for (const i of exhibitors) {
i.closest('#aod-offer-soldBy').parentElement.classList.add(isHighlighting(i));
i.classList.add('aas_rating_checked');
}
}
function convertToInt(text) {
return text.replace(/[^\d]/g, '') * 1;
}
function getShipping(data) {
return data? data.textContent.match(/^.+?[\u00A5|\uffe5]([,|\d]+)(\s+[\u4E00-\u9FFF]{3})?/m): '';
}
function getCostPrice(item) {
// ポップアップ
if (document.querySelector('body[style *= "overflow: hidden"]')) return [item.closest('#aod-offer-price, #aod-pinned-offer, #aod-sticky-pinned-offer').querySelector('.a-price-whole')];
// その他のおすすめ
if (item.closest('#moreBuyingChoices_feature_div')) return [item.closest('.a-row').firstElementChild];
// アコーディオン無し
if (document.querySelector('#gsod_singleOfferDisplay_Desktop')) return document.querySelectorAll('#desktop_buybox .a-price-whole, #desktop_buybox .offer-price, #apex_desktop .a-price-whole, #apex_desktop .offer-price, #formats .a-color-price');
// アコーディオン新品
if (item.closest('#newAccordionRow_0')) return [item.closest('.a-accordion-row-container').querySelector('.a-offscreen + span'), document.querySelector('li.selected .a-size-base'), document.querySelector('#corePriceDisplay_desktop_feature_div .a-price-whole')];
// アコーディオン中古
return item.closest('.a-accordion-row-container').querySelectorAll('#usedPrice, .a-price-whole');
}
function addHighlightText(base_text, replace_text, css) {
return base_text.innerHTML.replace(replace_text, `<span class="${css}">${replace_text.replace(/^\+/, '')}</span>`);
}
function addShipping(price, shipping) {
if (!price.textContent) return;
const base = price.textContent.trim().match(/^(\D)?([,|\d]+)$/);
return (base[1] || '') + (convertToInt(base[2]) + convertToInt(shipping)).toLocaleString();
}
function formattingText(price, shipping) {
price.textContent = addShipping(price, shipping);
price.parentElement.classList.add('aas_highlight_text');
}
function createBaseCostPanel(price) {
const basePrice = document.createElement('span');
basePrice.textContent = price.textContent.replace(/^\D?([,|\d]+)$/, '\¥$1');
basePrice.classList.add('aas_base_price');
return basePrice;
}
new MutationObserver(() => {
const postages = document.querySelectorAll('span[data-csa-c-delivery-price]:not(.aas_in-taxed), #moreBuyingChoices_feature_div .a-size-base:not(.aas_in-taxed)');
if (postages.length === 0) return;
for (const item of postages) {
item.classList.add('aas_in-taxed');
const postage = getShipping(item);
if (postage) {
const cost = Array.from(getCostPrice(item)).filter(c => c);
item.innerHTML = addHighlightText(item, postage[0], 'aas_highlight_text aas_bold_text');
for (const price of cost) {
price.parentElement.appendChild(createBaseCostPanel(price));
formattingText(price, postage[1]);
}
}
}
if (document.querySelector('body[style *= "overflow: hidden"]')) checkExhibitors();
}).observe(document.body, {childList: true, subtree: true});
})();