// ==UserScript==
// @name PickMe
// @namespace http://tampermonkey.net/
// @version 3.6.3
// @description Plugin d'aide à la navigation pour les membres du discord Amazon Vine FR : https://discord.gg/amazonvinefr
// @author Créateur/Codeur principal : MegaMan / Codeur secondaire : Sulff / Testeurs : Louise, JohnnyBGoody, L'avocat du Diable et Popato (+ du code de lelouch_di_britannia, FMaz008 et Thorvarium)
// @match https://www.amazon.fr/vine/vine-items
// @match https://www.amazon.fr/vine/vine-items?queue=*
// @match https://www.amazon.fr/vine/vine-reviews*
// @match https://www.amazon.fr/vine/orders*
// @match https://www.amazon.fr/vine/account
// @match https://www.amazon.fr/vine/resources
// @match https://www.amazon.fr/gp/buy/thankyou*
// @match https://www.amazon.fr/checkout*
// @match https://www.amazon.fr/*
// @match https://pickme.alwaysdata.net/*
// @match https://vinepick.me/*
// @match https://www.amazon.fr/vine/vine-items?search=*
// @icon https://vinepick.me/img/PM-ICO-2.png
// @updateURL https://raw.githubusercontent.com/teitong/pickme/main/PickMe.user.js
// @downloadURL https://raw.githubusercontent.com/teitong/pickme/main/PickMe.user.js
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_registerMenuCommand
// @grant GM_listValues
// @run-at document-start
// @noframes
// @require https://vinepick.me/scripts/jquery-3.7.1.min.js
// @require https://vinepick.me/scripts/heic2any.min.js
//==/UserScript==
/*
NOTES:
* Votre clé API est lié à votre compte Discord
*/
(function() {
try {
'use strict';
//Pour éviter la multi exécution
if (window.__PM__) {
return;
}
window.__PM__ = true;
initReviewRememberPM();
//On exclu les pages que gère RR, on laisse juste pour les pages
if (!window.location.href.includes('orders') && !window.location.href.includes('vine-reviews'))
{
var apiOk = GM_getValue("apiToken", false);
}
const baseUrlPickme = "https://vinepick.me";
const hostnamePickMe = new URL(baseUrlPickme).hostname;
let defautTab = GM_getValue('defautTab', 'AFA');
let checkoutRedirect = GM_getValue('checkoutRedirect', true);
let checkoutButtonUp = GM_getValue('checkoutButtonUp', true);
let mobileEnabled = GM_getValue("mobileEnabled", false);
let ordersEnabled = GM_getValue('ordersEnabled', true);
let headerEnabled = GM_getValue("headerEnabled", false);
GM_setValue("defautTab", defautTab);
GM_setValue("checkoutRedirect", checkoutRedirect);
GM_setValue("checkoutButtonUp", checkoutButtonUp);
GM_setValue("ordersEnabled", ordersEnabled);
GM_setValue("mobileEnabled", mobileEnabled);
GM_setValue("headerEnabled", headerEnabled);
const lienVine = {
'RFY': 'https://www.amazon.fr/vine/vine-items?queue=potluck',
'AFA': 'https://www.amazon.fr/vine/vine-items?queue=last_chance',
'AI': 'https://www.amazon.fr/vine/vine-items?queue=encore',
'ALL': 'https://www.amazon.fr/vine/vine-items?queue=all_items',
};
//On applique la suppression du header pour toutes les pages concernées par Vine
const urlVine = window.location.href;
const isAmazonTargetPage = [
/^https:\/\/www\.amazon\.fr\/vine\//,
/^https:\/\/www\.amazon\.fr\/gp\/buy\/thankyou/,
/^https:\/\/www\.amazon\.fr\/checkout/,
/^https:\/\/www\.amazon\.fr\/review\/create-review/,
/^https:\/\/www\.amazon\.fr\/review\/edit-review/
].some(pattern => pattern.test(urlVine));
if (isAmazonTargetPage) {
//Cacher le header ou non
if (headerEnabled) {
//Suppression header
var styleHeader = document.createElement('style');
styleHeader.textContent = `
body {
padding-right: 0px !important;
}
/* === Ancien header Amazon === */
#navbar-main,
#nav-main,
#skiplink,
.amzn-ss-wrap {
display: none !important;
}
/* === Nouveau header Amazon (2025) === */
#navbar-backup-backup,
#navbar-mobile-bb,
header#navbar-mobile-bb {
display: none !important;
}
`
document.head.appendChild(styleHeader);
}
}
//Page du passage de commande du nouveau checkout
//Pour tester si le checkout provient bien d'une page vine
const previousPage = document.referrer;
const CHECKOUT_PAGE_PATTERN = /^https:\/\/www\.amazon\.fr\/checkout\/p\/p-/;
//Page de checkout
function checkOut(currentUrl) {
const match_checkout = currentUrl.match(/\/checkout\/p\/p-(\d{3}-\d{7}-\d{7})/);
if (apiOk && previousPage && ordersEnabled && match_checkout && previousPage.includes("vine-items")) {
//On purge les anciennes commandes
function purgeOldPurchaseData() {
const now = Date.now();
const maxAge = 24 * 60 * 60 * 1000; //24 heures en millisecondes
const stored = GM_getValue("purchaseData", {});
let modified = false;
for (const purchaseId in stored) {
const entry = stored[purchaseId];
if (!entry.timestamp || now - entry.timestamp > maxAge) {
delete stored[purchaseId];
modified = true;
}
}
if (modified) {
GM_setValue("purchaseData", stored);
}
}
purgeOldPurchaseData();
const purchaseId = match_checkout[1];
const asinCheckout = GM_getValue("asinCheckout", null);
const asinParentCheckout = GM_getValue("asinParentCheckout", null);
const queueCheckout = GM_getValue("queueCheckout", null);
let stored = GM_getValue("purchaseData", {});
const now = Date.now(); //Timestamp
stored[purchaseId] = {
asin: asinCheckout,
parent: asinParentCheckout,
queue: queueCheckout,
timestamp: now
};
GM_setValue("purchaseData", stored);
GM_deleteValue("asinCheckout");
GM_deleteValue("asinParentCheckout");
GM_deleteValue("queueCheckout");
}
}
//Détection d'un risque de frais de douane sur la page de checkout
function initCustomsAlert() {
if (!CHECKOUT_PAGE_PATTERN.test(window.location.href)) {
return;
}
const ALERT_ID = 'pm-customs-alert';
const ALERT_STYLE_ID = `${ALERT_ID}-style`;
function normalizeText(text) {
if (!text) {
return '';
}
const lowerCase = text.toLowerCase();
const normalized = typeof lowerCase.normalize === 'function' ? lowerCase.normalize('NFD') : lowerCase;
return normalized
.replace(/[\u0300-\u036f]/g, '')
.replace(/["'’`]/g, ' ')
.replace(/[^a-z0-9]+/g, ' ')
.trim();
}
const CUSTOMS_WARNING_PHRASES = [
'Cette commande contient un ou plusieurs articles vendus et expédiés depuis l’étranger.',
'frais d’importation',
'dédouaner le colis',
'expédition à l’international'
];
const NORMALIZED_CUSTOMS_WARNING_PHRASES = CUSTOMS_WARNING_PHRASES
.map(phrase => normalizeText(phrase))
.filter(Boolean);
function textContainsCustomsWarning(text) {
const normalized = normalizeText(text);
if (!normalized) {
return false;
}
return NORMALIZED_CUSTOMS_WARNING_PHRASES.some(phrase => normalized.includes(phrase));
}
function ensureAlertStyle() {
if (document.getElementById(ALERT_STYLE_ID)) {
return;
}
const style = document.createElement('style');
style.id = ALERT_STYLE_ID;
style.textContent = `
#${ALERT_ID} {
background-color: #fff4d6;
border: 2px solid #f0a202;
border-radius: 12px;
color: #1f1f1f;
padding: 12px 16px;
margin: 16px 0;
display: flex;
align-items: center;
gap: 12px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
font-size: 14px;
line-height: 1.5;
}
#${ALERT_ID} .pm-customs-alert__icon {
font-size: 24px;
}
#${ALERT_ID} .pm-customs-alert__content {
flex: 1 1 auto;
}
#${ALERT_ID} .pm-customs-alert__content strong {
display: block;
font-size: 16px;
margin-bottom: 4px;
}
`;
document.head.appendChild(style);
}
function injectAlert() {
if (document.getElementById(ALERT_ID)) {
return true;
}
const referenceContainer = document.querySelector('#a-page') || document.body;
if (!referenceContainer) {
return false;
}
ensureAlertStyle();
const alert = document.createElement('div');
alert.id = ALERT_ID;
alert.innerHTML = `
⚠️
Attention : frais de douane possiblesCette commande contient un article susceptible d’être expédié depuis l’étranger. Des droits ou taxes supplémentaires peuvent être réclamés à la livraison. Vérifiez bien le détail de votre commande avant de valider.
`;
referenceContainer.prepend(alert);
return true;
}
function detectCustomsWarning(textCandidate) {
if (document.getElementById(ALERT_ID)) {
return true;
}
if (textCandidate && textContainsCustomsWarning(textCandidate)) {
return injectAlert();
}
if (!textCandidate && document.body && textContainsCustomsWarning(document.body.textContent)) {
return injectAlert();
}
return false;
}
if (detectCustomsWarning()) {
return;
}
const observerTarget = document.body || document.documentElement;
if (!observerTarget) {
return;
}
const observer = new MutationObserver(mutations => {
for (const mutation of mutations) {
if (mutation.type === 'childList') {
for (const node of mutation.addedNodes) {
const textContent = node && typeof node.textContent === 'string' ? node.textContent : '';
if (textContent && detectCustomsWarning(textContent)) {
observer.disconnect();
return;
}
}
} else if (mutation.type === 'characterData') {
const targetText = mutation.target && typeof mutation.target.textContent === 'string'
? mutation.target.textContent
: '';
if (targetText && detectCustomsWarning(targetText)) {
observer.disconnect();
return;
}
}
}
if (detectCustomsWarning()) {
observer.disconnect();
}
});
observer.observe(observerTarget, { childList: true, subtree: true, characterData: true });
setTimeout(() => observer.disconnect(), 30000);
}
function initBalanceDueAlert() {
if (!CHECKOUT_PAGE_PATTERN.test(window.location.href)) {
return;
}
if (!previousPage || !previousPage.includes('vine-items')) {
return;
}
const ALERT_ID = 'pm-balance-alert';
const STYLE_ID = `${ALERT_ID}-style`;
const HIGHLIGHT_CONTAINER_CLASS = 'pm-balance-warning-container';
const DEFAULT_BALANCE_TITLE = 'Attention : reste à payer';
const DEFAULT_MESSAGE_TEMPLATE = 'Cette commande Vine comporte un reste à payer de {{amount}}. Assurez-vous de vouloir continuer avant de valider.';
const AMOUNT_PLACEHOLDER = '{{amount}}';
const TOTAL_BEFORE_SPECIAL_PAYMENTS = 'TOTAL_BEFORE_SPECIAL_PAYMENTS_TAX_INCLUSIVE';
const GIFT_CARD_BALANCE_TYPE = 'SPECIAL_PAYMENTS_GIFT_CARD_BALANCE';
function ensureStyle() {
if (document.getElementById(STYLE_ID)) {
return;
}
const style = document.createElement('style');
style.id = STYLE_ID;
style.textContent = `
#${ALERT_ID} {
background-color: #ffe8e6;
border: 2px solid #cc1b1b;
border-radius: 12px;
color: #1f1f1f;
padding: 12px 16px;
margin: 16px 0;
display: flex;
align-items: center;
gap: 12px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
font-size: 14px;
line-height: 1.5;
}
#${ALERT_ID} .pm-balance-alert__icon {
font-size: 24px;
}
#${ALERT_ID} .pm-balance-alert__title {
display: block;
font-size: 16px;
margin-bottom: 4px;
}
#${ALERT_ID} .pm-balance-alert__message {
display: block;
}
#${ALERT_ID} .pm-balance-alert__note {
display: block;
margin-top: 4px;
font-size: 13px;
color: #1f1f1f;
}
#${ALERT_ID} .pm-balance-alert__amount {
color: #b12704;
font-weight: 700;
}
.${HIGHLIGHT_CONTAINER_CLASS} .pm-balance-warning-wrapper {
display: inline-flex;
align-items: center;
gap: 8px;
color: #b12704;
font-weight: 700;
}
.${HIGHLIGHT_CONTAINER_CLASS} .pm-balance-warning-icon {
font-size: 18px;
}
`;
document.head.appendChild(style);
}
function parseEuroAmount(text) {
if (!text) {
return null;
}
let sanitized = text
.replace(/\u00a0/g, '')
.replace(/€/g, '')
.replace(/\s/g, '')
.trim();
if (!sanitized) {
return null;
}
if (sanitized.includes(',')) {
sanitized = sanitized.replace(/\./g, '');
sanitized = sanitized.replace(',', '.');
}
const value = parseFloat(sanitized);
if (!Number.isFinite(value)) {
const fallback = sanitized.replace(/[^0-9.-]/g, '');
const fallbackValue = parseFloat(fallback);
return Number.isFinite(fallbackValue) ? fallbackValue : null;
}
return value;
}
function findBalanceContainer() {
const prioritizedContainer = document.querySelector('li.grand-total-cell .order-summary-line-definition');
if (prioritizedContainer) {
const text = prioritizedContainer.textContent || '';
return {
container: prioritizedContainer,
amountText: text,
amountValue: parseEuroAmount(text)
};
}
const labelCandidates = document.querySelectorAll('.order-summary-line-term .break-word');
for (const candidate of labelCandidates) {
const labelText = candidate && candidate.textContent ? candidate.textContent : '';
if (!labelText || !/montant\s+total/i.test(labelText)) {
continue;
}
const grid = candidate.closest('.order-summary-grid');
if (!grid) {
continue;
}
const container = grid.querySelector('.order-summary-line-definition');
if (!container) {
continue;
}
const text = container.textContent || '';
return {
container,
amountText: text,
amountValue: parseEuroAmount(text)
};
}
return null;
}
function appendMessageWithAmount(node, template, normalizedAmount) {
if (!node) {
return;
}
const sanitizedTemplate = typeof template === 'string' && template.trim()
? template
: DEFAULT_MESSAGE_TEMPLATE;
if (sanitizedTemplate.includes(AMOUNT_PLACEHOLDER)) {
const parts = sanitizedTemplate.split(AMOUNT_PLACEHOLDER);
parts.forEach((part, index) => {
if (part) {
node.appendChild(document.createTextNode(part));
}
if (index < parts.length - 1) {
const amountSpan = document.createElement('span');
amountSpan.className = 'pm-balance-alert__amount';
amountSpan.textContent = normalizedAmount;
node.appendChild(amountSpan);
}
});
} else {
node.appendChild(document.createTextNode(sanitizedTemplate));
if (normalizedAmount) {
node.appendChild(document.createTextNode(' '));
const amountSpan = document.createElement('span');
amountSpan.className = 'pm-balance-alert__amount';
amountSpan.textContent = normalizedAmount;
node.appendChild(amountSpan);
}
}
}
function renderBannerContent(alert, normalizedAmount, options) {
if (!alert) {
return;
}
let content = alert.querySelector('.pm-balance-alert__content');
if (!content) {
content = document.createElement('div');
content.className = 'pm-balance-alert__content';
alert.appendChild(content);
}
content.textContent = '';
const title = document.createElement('strong');
title.className = 'pm-balance-alert__title';
title.textContent = options.titleText || DEFAULT_BALANCE_TITLE;
content.appendChild(title);
const message = document.createElement('span');
message.className = 'pm-balance-alert__message';
appendMessageWithAmount(message, options.messageTemplate, normalizedAmount);
content.appendChild(message);
const notes = Array.isArray(options.extraNotes) ? options.extraNotes : [];
for (const note of notes) {
if (!note) {
continue;
}
const noteElement = document.createElement('span');
noteElement.className = 'pm-balance-alert__note';
noteElement.textContent = note;
content.appendChild(noteElement);
}
}
function injectBanner(amountText, options = {}) {
const normalizedAmount = (amountText || '').replace(/\u00a0/g, ' ').trim();
ensureStyle();
let alert = document.getElementById(ALERT_ID);
if (!alert) {
const referenceContainer = document.querySelector('#a-page') || document.body;
if (!referenceContainer) {
return;
}
alert = document.createElement('div');
alert.id = ALERT_ID;
const icon = document.createElement('span');
icon.className = 'pm-balance-alert__icon';
icon.textContent = '⚠️';
alert.appendChild(icon);
referenceContainer.prepend(alert);
}
renderBannerContent(alert, normalizedAmount, options);
}
function highlightAmount(container, amountText) {
if (!container) {
return;
}
ensureStyle();
container.classList.add(HIGHLIGHT_CONTAINER_CLASS);
const normalized = (amountText || '').replace(/\u00a0/g, ' ').trim();
const existingWrapper = container.querySelector('.pm-balance-warning-wrapper');
if (existingWrapper) {
const amountNode = existingWrapper.querySelector('.pm-balance-warning-amount');
if (amountNode) {
amountNode.textContent = normalized;
}
return;
}
const wrapper = document.createElement('span');
wrapper.className = 'pm-balance-warning-wrapper';
const icon = document.createElement('span');
icon.className = 'pm-balance-warning-icon';
icon.textContent = '⚠️';
const amountHolder = document.createElement('span');
amountHolder.className = 'pm-balance-warning-amount';
amountHolder.textContent = normalized;
wrapper.appendChild(icon);
wrapper.appendChild(amountHolder);
container.textContent = '';
container.appendChild(wrapper);
}
function getSubtotalInfoByType(type) {
if (!type) {
return null;
}
const input = document.querySelector(`input[name="subtotalLineType"][value="${type}"]`);
if (!input) {
return null;
}
const grid = input.closest('.order-summary-grid');
if (!grid) {
return null;
}
const container = grid.querySelector('.order-summary-line-definition');
if (!container) {
return null;
}
const text = container.textContent || '';
return {
container,
amountText: text,
amountValue: parseEuroAmount(text)
};
}
function detectGiftCardDetails() {
const totalBefore = getSubtotalInfoByType(TOTAL_BEFORE_SPECIAL_PAYMENTS);
if (!totalBefore || totalBefore.amountValue === null || totalBefore.amountValue <= 0) {
return null;
}
const giftCard = getSubtotalInfoByType(GIFT_CARD_BALANCE_TYPE);
if (!giftCard || giftCard.amountValue === null || giftCard.amountValue >= 0) {
return null;
}
return { totalBefore, giftCard };
}
function removeBalanceWarning(info) {
const alert = document.getElementById(ALERT_ID);
const target = info && info.container ? info.container : null;
const wasApplied = target && target.dataset.pmBalanceWarningApplied === 'true';
if (!alert && !wasApplied) {
return;
}
if (alert && alert.parentElement) {
alert.remove();
}
if (!target || !wasApplied) {
return;
}
target.classList.remove(HIGHLIGHT_CONTAINER_CLASS);
const wrapper = target.querySelector('.pm-balance-warning-wrapper');
if (wrapper) {
wrapper.remove();
}
const normalized = (info.amountText || '').replace(/\u00a0/g, ' ').trim();
target.textContent = normalized;
delete target.dataset.pmBalanceWarningApplied;
delete target.dataset.pmBalanceAmount;
delete target.dataset.pmBalanceMessageType;
}
function applyBalanceWarning(info, options = {}) {
if (!info || !info.container) {
return;
}
const displaySource = options.displayAmountText || info.amountText || '';
const normalizedDisplayAmount = (displaySource || '').replace(/\u00a0/g, ' ').trim();
injectBanner(normalizedDisplayAmount, options);
const highlightTarget = options.highlightContainer || info.container;
if (highlightTarget) {
const highlightText = Object.prototype.hasOwnProperty.call(options, 'highlightAmountText')
? options.highlightAmountText
: normalizedDisplayAmount;
highlightAmount(highlightTarget, highlightText);
}
const datasetTarget = options.datasetTarget || info.container;
if (datasetTarget) {
datasetTarget.dataset.pmBalanceWarningApplied = 'true';
datasetTarget.dataset.pmBalanceAmount = normalizedDisplayAmount;
datasetTarget.dataset.pmBalanceMessageType = options.messageType || 'default';
}
}
function processBalance() {
const info = findBalanceContainer();
if (!info || !info.container) {
return false;
}
if (info.amountValue === null) {
removeBalanceWarning(info);
return false;
}
const normalizedFinalAmount = (info.amountText || '').replace(/\u00a0/g, ' ').trim();
let giftCardDetails = null;
let currentType = 'default';
let comparisonAmount = normalizedFinalAmount;
if (info.amountValue <= 0) {
giftCardDetails = detectGiftCardDetails();
if (giftCardDetails) {
currentType = 'gift-card';
comparisonAmount = (giftCardDetails.totalBefore.amountText || '').replace(/\u00a0/g, ' ').trim();
} else {
currentType = 'none';
}
}
const wasApplied = info.container.dataset.pmBalanceWarningApplied === 'true';
const previousAmount = info.container.dataset.pmBalanceAmount || '';
const previousType = info.container.dataset.pmBalanceMessageType || 'default';
if (currentType === 'none') {
if (wasApplied) {
removeBalanceWarning(info);
}
return false;
}
if (wasApplied && previousAmount === comparisonAmount && previousType === currentType) {
return true;
}
if (wasApplied) {
delete info.container.dataset.pmBalanceWarningApplied;
}
if (info.amountValue <= 0) {
if (!giftCardDetails) {
return false;
}
const extraNotes = [];
const giftCardText = giftCardDetails.giftCard && giftCardDetails.giftCard.amountText
? giftCardDetails.giftCard.amountText.replace(/\u00a0/g, ' ').trim()
: '';
if (giftCardText) {
extraNotes.push(`Carte cadeau appliquée : ${giftCardText}.`);
}
applyBalanceWarning(info, {
displayAmountText: giftCardDetails.totalBefore.amountText,
highlightAmountText: info.amountText,
messageTemplate: 'Cette commande Vine est payante ({{amount}}) mais le montant est couvert par une carte cadeau. Vérifiez que vous souhaitez l’utiliser avant de valider.',
titleText: 'Attention : carte cadeau utilisée',
extraNotes,
messageType: 'gift-card'
});
return true;
}
applyBalanceWarning(info, { messageType: 'default' });
return true;
}
if (processBalance()) {
return;
}
const observerTarget = document.body || document.documentElement;
if (!observerTarget) {
return;
}
const observer = new MutationObserver(() => {
if (processBalance()) {
observer.disconnect();
}
});
observer.observe(observerTarget, { childList: true, subtree: true, characterData: true });
setTimeout(() => observer.disconnect(), 30000);
}
function initCheckoutAlerts() {
initCustomsAlert();
initBalanceDueAlert();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initCheckoutAlerts);
} else {
initCheckoutAlerts();
}
//Pour surveiller la page checkout contenant l'id de commande car c'est une redirection
const targetPattern = /^https:\/\/www\.amazon\.fr\/checkout\/entry\/buynow\?pipelineType=Chewbacca$/;
let previousUrl = location.href;
if (previousPage.includes("vine-items") && targetPattern.test(previousUrl) && ordersEnabled) {
const interval = setInterval(() => {
const currentUrl = location.href;
if (currentUrl !== previousUrl) {
clearInterval(interval); //On arrête la surveillance
console.log("[PïckMe] Changement d’URL détecté :", currentUrl);
checkOut(currentUrl);
}
}, 100); //Vérifie toutes les 100 ms
}
//Page de commande validée
if (apiOk && window.location.href.includes("/gp/buy/thankyou/handlers")) {
if (ordersEnabled) {
const purchaseId = new URLSearchParams(location.search).get('purchaseId');
let stored = GM_getValue("purchaseData", {});
const data = stored[purchaseId];
if (data) {
delete stored[purchaseId];
GM_setValue("purchaseData", stored);
let data_order = {
version: GM_info.script.version,
token: apiOk,
parent_asin: data.parent,
asin: data.asin,
queue: data.queue,
success: "success"
};
const formData = new URLSearchParams(data_order);
fetch(baseUrlPickme + "/shyrka/order", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: formData.toString()
});
}
}
function moveVineButton() {
if (checkoutRedirect) {
const bouton = document.querySelector('#widget-continueShoppingEgress a.a-button-text');
//Vérifie qu'on l'a trouvé et que le texte contient "Vine"
if (bouton && bouton.textContent.includes('Vine')) {
const nouvelleURL = lienVine[defautTab];
if (nouvelleURL) {
bouton.href = nouvelleURL;
}
}
}
if (checkoutButtonUp) {
//Récupère le bouton source
const sourceButtonContainer = document.querySelector('#widget-continueShoppingEgress');
//Vérifie si le bouton contient "Vine"
if (!sourceButtonContainer) return;
const text = sourceButtonContainer.textContent || '';
if (!text.includes('Vine')) return;
//Clone le bouton
const clone = sourceButtonContainer.cloneNode(true);
//Cible la zone de destination
const targetContainer = document.querySelector('#widget-accountLevelActions');
if (targetContainer && clone) {
//Insère le clone juste après le conteneur cible
targetContainer.insertAdjacentElement('afterend', clone);
}
}
}
//Attendre que le DOM soit prêt
//Fix iPhone
if (document.readyState !== 'loading') {
moveVineButton();
}
else {
document.addEventListener('DOMContentLoaded', function () {
moveVineButton();
});
}
}
//URL Vine
const urlPattern = /^https:\/\/www\.amazon\.fr\/vine/;
//Liste des URLs Vine
const excludedPatterns = [
'https://www.amazon.fr/vine/vine-items',
'https://www.amazon.fr/vine/vine-items?queue=*',
'https://www.amazon.fr/vine/vine-items?search=*',
'https://www.amazon.fr/vine/vine-reviews*',
'https://www.amazon.fr/vine/orders*',
'https://www.amazon.fr/vine/account',
'https://www.amazon.fr/vine/resources'
];
//Fonction pour extraire l'ASIN
function getASINfromURL(url) {
//Expression régulière pour trouver l'ASIN dans différentes structures d'URL Amazon
const regex = /\/(dp|gp\/product|product-reviews|gp\/aw\/d)\/([A-Za-z0-9]{10})/i;
const match = url.match(regex);
return match ? match[2] : null; //Retourne l'ASIN ou null si non trouvé
}
function isAffiliateTagPresent() {
return window.location.search.indexOf('tag=monsieurconso-21') > -1;
}
//Ajout du bouton
function isElementVisible(element) {
if (!element) {
return false;
}
if (typeof element.offsetParent !== 'undefined') {
if (element.offsetParent !== null) {
return true;
}
}
const rects = element.getClientRects();
return rects && rects.length > 0;
}
function findButtonPlacement() {
const candidates = [
{
selector: '#corePriceDisplay_desktop_feature_div',
getPlacement: element => {
const targetSection = element.querySelector('.a-section.a-spacing-none') || element;
return { type: 'append', node: targetSection };
}
},
{
selector: '#corePriceDisplay_mobile_feature_div',
getPlacement: element => ({ type: 'append', node: element })
},
{
selector: '#buyboxAccordion .a-accordion-active .basisPriceLegalMessage',
getPlacement: element => ({ type: 'after', node: element })
},
{
selector: '.basisPriceLegalMessage',
getPlacement: element => ({ type: 'after', node: element })
},
{
selector: '#buyboxAccordion .a-accordion-active .priceToPay',
getPlacement: element => {
const parentSection = element.closest('.a-section');
if (parentSection && isElementVisible(parentSection)) {
return { type: 'append', node: parentSection };
}
return null;
}
},
{
selector: '#corePrice_desktop .a-span12',
getPlacement: element => {
const parent = element.parentNode || element;
return { type: 'append', node: parent };
}
},
{
selector: '#corePrice_mobile_feature_div',
getPlacement: element => ({ type: 'append', node: element })
},
{
selector: '#bookDescription_feature_div',
getPlacement: element => ({ type: 'before', node: element })
}
];
for (const candidate of candidates) {
const elements = Array.from(document.querySelectorAll(candidate.selector));
for (const element of elements) {
if (!isElementVisible(element)) {
continue;
}
const placement = candidate.getPlacement(element);
if (placement) {
return placement;
}
}
}
return null;
}
function updateButtonLink(asin) {
const affiliateAnchor = document.querySelector('#pickme-button');
if (affiliateAnchor && !isAffiliateTagPresent()) {
affiliateAnchor.href = baseUrlPickme + `/monsieurconso/product.php?asin=${asin}`;
}
}
function insertButtonContainer(container, placement) {
if (!placement || !placement.node) {
return;
}
if (placement.type === 'after') {
const parentNode = placement.node.parentNode;
if (!parentNode) {
return;
}
if (container.parentNode !== parentNode || container.previousSibling !== placement.node) {
parentNode.insertBefore(container, placement.node.nextSibling);
}
} else if (placement.type === 'append') {
if (container.parentNode !== placement.node) {
placement.node.appendChild(container);
} else if (container !== placement.node.lastElementChild) {
placement.node.appendChild(container);
}
} else if (placement.type === 'before') {
const parentNode = placement.node.parentNode;
if (!parentNode) {
return;
}
if (container.parentNode !== parentNode || container.nextSibling !== placement.node) {
parentNode.insertBefore(container, placement.node);
}
}
}
function addButton(asin) {
const placement = findButtonPlacement();
if (!placement) {
return;
}
let buttonContainer = document.querySelector('#pickme-button-container');
if (!buttonContainer) {
buttonContainer = createButton(asin);
} else {
updateButtonLink(asin);
}
insertButtonContainer(buttonContainer, placement);
}
function submitPost(asin) {
var form = document.createElement('form');
form.method = 'POST';
form.action = baseUrlPickme + '/monsieurconso/top.php';
form.target = '_blank';
var asinField = document.createElement('input');
asinField.type = 'hidden';
asinField.name = 'asin';
asinField.value = asin;
form.appendChild(asinField);
document.body.appendChild(form);
form.submit();
}
function createButton(asin) {
var container = document.createElement('div'); //Créer un conteneur pour le bouton et le texte d'explication
container.id = 'pickme-button-container';
container.style.display = 'inline-flex';
container.style.alignItems = 'center';
var affiliateButton = document.createElement('a');
affiliateButton.className = 'a-button a-button-primary a-button-small';
affiliateButton.id = 'pickme-button';
affiliateButton.style.marginTop = '5px'; //Pour ajouter un peu d'espace au-dessus du bouton
affiliateButton.style.marginBottom = '5px';
affiliateButton.style.color = 'white'; //Changez la couleur du texte en noir
//affiliateButton.style.maxWidth = '200px';
affiliateButton.style.height = '29px';
affiliateButton.style.lineHeight = '29px';
affiliateButton.style.borderRadius = '20px';
affiliateButton.style.whiteSpace = 'nowrap';
affiliateButton.style.padding = '0 40px';
affiliateButton.style.backgroundColor = '#CC0033';
affiliateButton.style.border = '1px solid white';
affiliateButton.style.display = 'inline-block';
if (isAffiliateTagPresent()) {
affiliateButton.innerText = 'Lien PickMe actif';
affiliateButton.style.backgroundColor = 'green'; //Changez la couleur de fond en vert
affiliateButton.style.color = 'white';
affiliateButton.style.pointerEvents = 'none'; //Empêchez tout événement de clic
affiliateButton.style.cursor = 'default';
affiliateButton.style.border = '1px solid black';
container.appendChild(affiliateButton); //Ajouter le bouton et le texte d'explication au conteneur
} else {
/*affiliateButton.onclick = function() {
submitPost(asin);
};*/
affiliateButton.href = baseUrlPickme + `/monsieurconso/product.php?asin=${asin}`;
affiliateButton.innerText = 'Acheter via PickMe';
affiliateButton.target = '_blank';
var infoText = document.createElement('span'); //Créer l'élément de texte d'explication
infoText.innerHTML = 'A quoi sert ce bouton ?';
infoText.style.marginLeft = '5px';
infoText.style.color = '#CC0033';
infoText.style.cursor = 'pointer';
infoText.style.fontSize = '14px';
infoText.onclick = function() {
alert("Ce bouton permet de soutenir le discord Amazon Vine FR. Il n'y a strictement aucune conséquence sur votre achat, mise à part d'aider à maintenir les services du discord et de PickMe.\nVous pourrez réclamer votre achat sur PickMe Web d'ici 24h afin d'augmenter votre score d'activité et éviter d'être AFK.\n\nComment faire ?\n\nIl suffit de cliquer sur 'Acheter via PickMe' et dans la nouvelle fenêtre de cliquer sur 'Acheter sur Amazon'. Normalement le bouton sera devenu vert, il suffit alors d'ajouter le produit au panier (uniquement quand le bouton est vert) et c'est tout !\nMerci beaucoup !");
};
container.appendChild(affiliateButton);
container.appendChild(infoText);
}
affiliateButton.style.fontSize = '14px';
return container; //Retourner le conteneur au lieu du bouton seul
}
//Détermine si on ajoute l'onglet Notifications
var pageProduit = false;
var asinProduct = getASINfromURL(window.location.href);
function asinReady() {
if (asinProduct) {
pageProduit = true;
addButton(asinProduct);
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
asinProduct = getASINfromURL(window.location.href);
addButton(asinProduct);
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
return;
}
}
//Fix iPhone
if (document.readyState !== 'loading') {
asinReady();
}
else {
document.addEventListener('DOMContentLoaded', function () {
asinReady();
});
}
//Notif
//On initialise les variables utiles pour cette partie du script
let notifEnabled = GM_getValue("notifEnabled", false);
let onMobile = GM_getValue("onMobile", false);
let shortcutNotif = GM_getValue("shortcutNotif", false);
let callUrl = GM_getValue("callUrl", "");
var apiKey = GM_getValue("apiToken", false);
let notifUp = GM_getValue('notifUp', true);
let notifRecos = GM_getValue('notifRecos', false);
let notifRFY = GM_getValue('notifRFY', false);
let notifPartageAFA = GM_getValue('notifPartageAFA', true);
let notifPartageAI = GM_getValue('notifPartageAI', false);
let notifPartageALL = GM_getValue('notifPartageALL', true);
let notifAutres = GM_getValue('notifAutres', true);
let notifSound = GM_getValue('notifSound', true);
let notifFav = GM_getValue('notifFav', false);
let favWords = GM_getValue('favWords', '');
let hideWords = GM_getValue('hideWords', '');
let filterOption = GM_getValue('filterOption', 'notifFavOnly');
let hideEnabled = GM_getValue("hideEnabled", true);
let savedTheme = GM_getValue('selectedTheme', 'default');
let notifUrl = GM_getValue('notifUrl', baseUrlPickme + '/sw/notif3.mp3');
let favUrlOn = GM_getValue('favUrlOn', baseUrlPickme + "/img/coeurrouge2.png");
let favUrlOff = GM_getValue('favUrlOff', baseUrlPickme + "/img/coeurgris2.png");
let hideUrlOn = GM_getValue('hideUrlOn', baseUrlPickme + "/img/eye.png");
let hideUrlOff = GM_getValue('hideUrlOff', baseUrlPickme + "/img/eyehidden.png");
let hidePageNavigateEnabled = GM_getValue('hidePageNavigateEnabled', true);
let hidePagePreviousEnabled = GM_getValue('hidePagePreviousEnabled', false);
let NSFWEnabled = GM_getValue('NSFWEnabled', false);
let blurLevel = GM_getValue('blurLevel', '15');
let NSFWHide = GM_getValue('NSFWHide', false);
let notepadEnabled = GM_getValue('notepadEnabled', true);
let notifVolumeEnabled = GM_getValue('notifVolumeEnabled', false);
let notifVolume = GM_getValue('notifVolume', "1");
GM_setValue("notifEnabled", notifEnabled);
GM_setValue("onMobile", onMobile);
GM_setValue("shortcutNotif", shortcutNotif);
GM_setValue("callUrl", callUrl);
GM_setValue("notifUp", notifUp);
GM_setValue("notifRecos", notifRecos);
GM_setValue("notifRFY", notifRFY);
GM_setValue("notifPartageAFA", notifPartageAFA);
GM_setValue("notifPartageAI", notifPartageAI);
GM_setValue("notifPartageALL", notifPartageALL);
GM_setValue("notifAutres", notifAutres);
GM_setValue("notifSound", notifSound);
GM_setValue("notifFav", notifFav);
GM_setValue("favWords", favWords);
GM_setValue("hideWords", hideWords);
GM_setValue("filterOption", filterOption);
GM_setValue("hideEnabled", hideEnabled);
GM_setValue("selectedTheme", savedTheme);
GM_setValue("notifUrl", notifUrl);
GM_setValue("favUrlOn", favUrlOn);
GM_setValue("favUrlOff", favUrlOff);
GM_setValue("hideUrlOn", hideUrlOn);
GM_setValue("hideUrlOff", hideUrlOff);
GM_setValue("hidePageNavigateEnabled", hidePageNavigateEnabled);
GM_setValue("hidePagePreviousEnabled", hidePagePreviousEnabled);
GM_setValue("NSFWEnabled", NSFWEnabled);
GM_setValue("blurLevel", blurLevel);
GM_setValue("NSFWHide", NSFWHide);
GM_setValue("notepadEnabled", notepadEnabled);
GM_setValue("notifVolumeEnabled", notifVolumeEnabled);
GM_setValue("notifVolume", notifVolume);
//Convertir la date SQL en date lisible européenne
function convertToEuropeanDate(mysqlDate) {
if (!mysqlDate) return '';
const date = new Date(mysqlDate);
const day = ('0' + date.getDate()).slice(-2);
const month = ('0' + (date.getMonth() + 1)).slice(-2); //Les mois commencent à 0 en JavaScript
const year = date.getFullYear();
const hours = ('0' + date.getHours()).slice(-2);
const minutes = ('0' + date.getMinutes()).slice(-2);
const seconds = ('0' + date.getSeconds()).slice(-2);
return `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`;
}
//Récupérer les infos d'un produit dans l'API
function infoProduct(asin) {
const formData = new URLSearchParams({
version: GM_info.script.version,
token: apiKey,
asin: asin,
});
return fetch(baseUrlPickme + "/shyrka/infoasin", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: formData.toString()
})
.then(response => {
if (response.status === 200) {
return response.json().then(data => {
const { date_last, title, linkText, linkUrl, main_image } = data;
const date_last_eu = convertToEuropeanDate(date_last);
return { date_last_eu, title, linkText, linkUrl, main_image };
}).catch(error => {
console.error("Erreur lors de l'analyse de la réponse JSON:", error);
throw new Error("Erreur lors de l'analyse de la réponse JSON");
});
} else if (response.status === 201) {
return response.text();
} else {
console.error("Erreur HTTP:", response.status, response.statusText);
throw new Error(`Erreur HTTP: ${response.status} ${response.statusText}`);
}
})
.catch(error => {
console.error("Erreur de requête:", error);
throw error;
});
}
//Fonction pour demander la permission et afficher la notification
function requestNotification(title, text, icon, queue = null, page = null, pn = null, cn = null) {
if (!("Notification" in window)) {
console.log("[PïckMe] Ce navigateur ne supporte pas les notifications de bureau.");
return;
}
if (Notification.permission === "granted") {
if (onMobile) {
navigator.serviceWorker.getRegistration().then(function(reg) {
if (reg) {
reg.showNotification(title, {
body: text || "",
icon: icon,
data: { queue: queue, page : page, cn : cn, pn : pn }
});
}
});
} else {
showNotification(title, text, icon, queue, page, pn, cn);
}
soundNotif();
} else if (Notification.permission !== "denied") {
Notification.requestPermission().then(permission => {
if (permission === "granted") {
if (onMobile) {
navigator.serviceWorker.getRegistration().then(function(reg) {
if (reg) {
reg.showNotification(title, {
body: text || "",
icon: icon,
data: { queue: queue, page : page, cn : cn, pn : pn }
});
}
});
} else {
showNotification(title, text, icon, queue, page, pn, cn);
}
soundNotif();
}
});
}
}
function playSound(url) {
const audio = new Audio(url);
if (notifVolumeEnabled) {
const volume = Math.max(0, Math.min(1, notifVolume));
audio.volume = volume;
}
audio.play().catch((err) => {
console.warn('Erreur lors de la lecture du son :', err);
});
}
function soundNotif() {
if (notifSound) {
var sound = new Audio(notifUrl);
if (notifVolumeEnabled) {
const volume = Math.max(0, Math.min(1, notifVolume));
sound.volume = volume;
}
sound.play().catch((err) => {
console.warn('Erreur lors de la lecture du son :', err);
});
}
}
//Fonction pour afficher la notification sur PC
function showNotification(title, text, icon, queue = null, page = null, pn = null, cn = null) {
var notification = new Notification(title, {
body: text || "",
icon: icon
});
notification.onclick = function () {
window.focus(); //Focus le navigateur quand on clique sur la notification
var baseUrl = "https://www.amazon.fr/vine/vine-items";
var url = baseUrl; //Initialisation de l'URL de base
//Déterminer l'URL en fonction de la queue
if (queue === "0") {
url = baseUrl + "?queue=last_chance";
if (page) url += "&page=" + encodeURIComponent(page);
} else if (queue === "1") {
url = baseUrl + "?queue=encore";
if (pn) url += "&pn=" + encodeURIComponent(pn);
if (cn) url += "&cn=" + encodeURIComponent(cn);
if (page) url += "&page=" + encodeURIComponent(page);
} else if (queue === "2") {
url = baseUrl + "?queue=potluck";
} else if (queue === "3") {
url = baseUrl + "?queue=all_items";
if (pn) url += "&pn=" + encodeURIComponent(pn);
if (cn) url += "&cn=" + encodeURIComponent(cn);
if (page) url += "&page=" + encodeURIComponent(page);
} else {
url = baseUrl + "?queue=encore" + (queue ? "&pn=" + queue : "") + (page ? "&cn=&page=" + page : "");
}
//Ouvrir l'URL dans un nouvel onglet
window.open(url, '_blank');
};
}
//Ecoute des messages entrants
if (notifEnabled && apiKey) {
var lastNotifId = null;
const NOTIF_LEADER_KEY = 'pmNotifLeader';
const NOTIF_LEADER_TTL = 15000; //15 secondes
const currentNotifTabId = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
let isNotifLeader = false;
let notifIframeInitialized = false;
let notifLeaderHeartbeat = null;
let notifLeaderCheckInterval = null;
function parseNotifLeader(rawValue) {
try {
return rawValue ? JSON.parse(rawValue) : null;
} catch (e) {
return null;
}
}
function getNotifLeader() {
return parseNotifLeader(localStorage.getItem(NOTIF_LEADER_KEY));
}
function setNotifLeader(id) {
localStorage.setItem(NOTIF_LEADER_KEY, JSON.stringify({
id: id,
timestamp: Date.now()
}));
}
function isLeaderEntryStale(entry) {
return !entry || (Date.now() - entry.timestamp > NOTIF_LEADER_TTL);
}
function stopNotifLeadership() {
isNotifLeader = false;
if (notifLeaderHeartbeat) {
clearInterval(notifLeaderHeartbeat);
notifLeaderHeartbeat = null;
}
}
function ensureNotifIframe() {
if (notifIframeInitialized) {
return;
}
notifIframeInitialized = true;
function addNotifIframeAndTab() {
if (window.location.hostname !== "pickme.alwaysdata.net" || window.location.hostname !== hostnamePickMe) {
//Initialisation de l'iframe seulement si on est sur le bon domaine
var iframe = document.createElement('iframe');
iframe.style.display = 'none'; //Rendre l'iframe invisible
iframe.src = baseUrlPickme + "/sw/websocket.php?key=" + encodeURIComponent(apiKey);
document.body.appendChild(iframe);
} else {
document.cookie = "pm_apiKey=" + encodeURIComponent(apiKey) + "; path=/; secure";
}
}
if (document.readyState !== 'loading') {
addNotifIframeAndTab();
}
else {
document.addEventListener('DOMContentLoaded', function () {
addNotifIframeAndTab()
});
}
}
function startNotifLeadership() {
if (isNotifLeader) {
return;
}
isNotifLeader = true;
ensureNotifIframe();
notifLeaderHeartbeat = setInterval(function () {
var leader = getNotifLeader();
if (leader && leader.id !== currentNotifTabId) {
stopNotifLeadership();
return;
}
setNotifLeader(currentNotifTabId);
}, 5000);
}
function tryBecomeNotifLeader() {
var leader = getNotifLeader();
if (!leader || leader.id === currentNotifTabId || isLeaderEntryStale(leader)) {
setNotifLeader(currentNotifTabId);
startNotifLeadership();
}
}
function startNotifLeaderWatchdog() {
if (notifLeaderCheckInterval) {
return;
}
notifLeaderCheckInterval = setInterval(function () {
var leader = getNotifLeader();
if (!leader || isLeaderEntryStale(leader)) {
tryBecomeNotifLeader();
}
}, 4000);
}
window.addEventListener('storage', function(event) {
if (event.key === NOTIF_LEADER_KEY) {
var leader = parseNotifLeader(event.newValue);
if (!leader || isLeaderEntryStale(leader)) {
tryBecomeNotifLeader();
} else if (leader.id !== currentNotifTabId) {
stopNotifLeadership();
}
}
});
window.addEventListener('visibilitychange', function() {
if (!document.hidden && !isNotifLeader) {
tryBecomeNotifLeader();
}
});
window.addEventListener('beforeunload', function() {
var leader = getNotifLeader();
if (leader && leader.id === currentNotifTabId) {
localStorage.removeItem(NOTIF_LEADER_KEY);
}
if (notifLeaderCheckInterval) {
clearInterval(notifLeaderCheckInterval);
notifLeaderCheckInterval = null;
}
stopNotifLeadership();
});
tryBecomeNotifLeader();
startNotifLeaderWatchdog();
if (notifFav) {
var titleContentLower;
if (filterOption == "notifFavOnly") {
var favWordsTrimNotif = favWords.trim();
var favArrayNotif = favWordsTrimNotif.length > 0
? favWordsTrimNotif.split(',').map(pattern => {
pattern = pattern.trim();
if (pattern.length > 0) {
try {
return new RegExp(pattern, 'i');
} catch (e) {
console.error('Expression regex invalide :', pattern, e);
return null;
}
} else {
return null;
}
}).filter(regex => regex != null)
: [];
} else if (filterOption == "notifExcludeHidden") {
var hiddenWordsTrimNotif = hideWords.trim();
var hiddenArrayNotif = hiddenWordsTrimNotif.length > 0
? hiddenWordsTrimNotif.split(',').map(pattern => {
pattern = pattern.trim();
if (pattern.length > 0) {
try {
return new RegExp(pattern, 'i');
} catch (e) {
console.error('Expression regex invalide :', pattern, e);
return null;
}
} else {
return null;
}
}).filter(regex => regex != null)
: [];
}
}
//Écouter les messages immédiatement
window.addEventListener('message', function(event) {
//console.log("PickMe :", event);
if (!isNotifLeader) {
return;
}
lastNotifId = GM_getValue('lastNotifId', null);
if (event.data.type === 'NEW_MESSAGE' && (event.origin == "https://pickme.alwaysdata.net" || event.origin == baseUrlPickme) && event.data.id != lastNotifId) {
lastNotifId = event.data.id;
GM_setValue('lastNotifId', lastNotifId);
if ((event.data.info.toUpperCase() === "UP" && notifUp) ||
(event.data.info.toUpperCase() === "RECO" && notifRecos) ||
(event.data.info.toUpperCase() === "PRODUCT_AFA" && notifPartageAFA) ||
(event.data.info.toUpperCase() === "PRODUCT_AI" && notifPartageAI) ||
(event.data.info.toUpperCase() === "PRODUCT_ALL" && notifPartageALL) ||
(event.data.info.toUpperCase() === "PRODUCT_RFY" && notifRFY) ||
(event.data.info.toUpperCase() === "AUTRES" && notifAutres)) {
if (notifFav && (event.data.info.toUpperCase() === "PRODUCT_AI" || event.data.info.toUpperCase() === "PRODUCT_ALL")) {
titleContentLower = event.data.description.toLowerCase().trim().replace(/\s+/g, '');
if (filterOption == "notifFavOnly") {
if (favArrayNotif.length > 0 && favArrayNotif.some(regex => regex.test(titleContentLower))) {
requestNotification(event.data.title, event.data.description, event.data.imageUrl, event.data.queue, event.data.page, event.data.pn, event.data.cn);
}
} else if (filterOption == "notifExcludeHidden") {
if (hiddenArrayNotif.length > 0 && !hiddenArrayNotif.some(regex => regex.test(titleContentLower))) {
requestNotification(event.data.title, event.data.description, event.data.imageUrl, event.data.queue, event.data.page, event.data.pn, event.data.cn);
}
}
} else {
requestNotification(event.data.title, event.data.description, event.data.imageUrl, event.data.queue, event.data.page, event.data.pn, event.data.cn);
}
}
}
});
function addNotifShortcutTab() {
if (shortcutNotif && !pageProduit && window.location.href.indexOf("vine") !== -1) {
//Sélectionner le conteneur des onglets
var tabsContainer = document.querySelector('.a-tabs');
//Créer le nouvel onglet pour Notifications
var newTab1 = document.createElement('li');
newTab1.className = 'a-tab-heading';
newTab1.role = 'presentation';
//Créer le lien à ajouter dans le nouvel onglet Notifications
var link1 = document.createElement('a');
link1.href = baseUrlPickme + "/sw/notification.php?key=" + encodeURIComponent(apiKey);
link1.role = 'tab';
link1.setAttribute('aria-selected', 'false');
link1.tabIndex = -1;
link1.textContent = 'Notifications';
link1.target = '_blank';
link1.style.color = '#f8a103';
link1.style.backgroundColor = 'transparent';
link1.style.border = 'none';
//Ajouter le lien au nouvel onglet Notifications
newTab1.appendChild(link1);
//Ajouter les nouveaux onglets au conteneur des onglets
if (tabsContainer) {
tabsContainer.appendChild(newTab1);
}
}
}
//Fix iPhone
if (document.readyState !== 'loading') {
addNotifShortcutTab();
}
else {
document.addEventListener('DOMContentLoaded', function () {
addNotifShortcutTab()
});
}
}
//Fonction pour charger le fichier CSS
function loadCSS(url) {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = url;
document.getElementsByTagName('head')[0].appendChild(link);
}
//URL des CSS
var baseURLCSS = baseUrlPickme + "/";
//Gestion des favoris sur PickMe Web
if ((window.location.hostname === "pickme.alwaysdata.net" || window.location.hostname === hostnamePickMe) && /^\/[^\/]+\.php$/.test(window.location.pathname)) {
document.addEventListener('click', function(event) {
//Vérifier si l'élément cliqué a la classe 'favori-icon'
if (event.target.classList.contains('favori-icon')) {
//let dataId = event.target.getAttribute('data-id');
let dataFavori = event.target.getAttribute('data-favori');
let dataAsin = event.target.getAttribute('data-asin');
if (dataFavori == 1) {
GM_setValue(dataAsin +'_f', '1');
} else if (dataFavori == 0) {
GM_deleteValue(dataAsin + '_f');
}
}
});
//Auto log si on a pickme installé
//On check s'il y a la zone de saisie de la clé API
const apiKeyInput = document.querySelector('input[type="text"].form-control#api_key[name="api_key"][required]');
//Vérifie si le message d'erreur n'est PAS présent
const errorAlert = document.querySelector('div.alert.alert-danger');
//Récupère le dernier moment de redirection enregistré pour éviter de le faire en boucle
const lastRedirect = localStorage.getItem('lastRedirectTime');
const now = Date.now();
//On le fait seulement s'il y a le champ de saisie, mais sans le message d'erreur et si pas fait depuis plus de 1 minute
if (apiKeyInput && !errorAlert && (!lastRedirect || now - lastRedirect > 60000)) {
if (apiKey) {
localStorage.setItem('lastRedirectTime', now);
const redirectUrl = baseUrlPickme + "/search.php?key=" + encodeURIComponent(apiKey);
window.location.href = redirectUrl;
}
}
}
//Popup pour le bloc-notes
function setNote() {
//Vérifie si une popup existe déjà et la supprime si c'est le cas
const existingPopup = document.getElementById('notePopup');
if (existingPopup) {
existingPopup.remove();
}
//Crée la fenêtre popup
const popup = document.createElement('div');
popup.id = "notePopup";
popup.style.cssText = `
position: fixed;
z-index: 10002;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: white;
border: 1px solid #ccc;
box-shadow: 0px 0px 10px #ccc;
`;
popup.innerHTML = `
Bloc-notes✖
`;
document.body.appendChild(popup);
//Ajoute des écouteurs d'événement pour les boutons
document.getElementById('saveNote').addEventListener('click', function() {
const noteContent = document.getElementById('noteTextArea').value;
//Stocker le contenu de la note avec GM_setValue
GM_setValue("noteContent", noteContent);
popup.remove();
});
document.getElementById('closeNote').addEventListener('click', function() {
popup.remove();
});
document.getElementById('closeNotePopup').addEventListener('click', function() {
popup.remove();
});
//Charger la note existante si elle est stockée avec GM_getValue
const savedNoteContent = GM_getValue("noteContent", "");
if (savedNoteContent) {
document.getElementById('noteTextArea').value = savedNoteContent;
}
//Ajoute la fonctionnalité de déplacement
const header = document.getElementById('configPopupHeader');
let isDragging = false;
let offsetX, offsetY;
header.addEventListener('mousedown', function(e) {
isDragging = true;
header.style.cursor = 'grabbing';
offsetX = e.clientX - popup.getBoundingClientRect().left;
offsetY = e.clientY - popup.getBoundingClientRect().top;
document.addEventListener('mousemove', movePopup);
document.addEventListener('mouseup', stopDragging);
});
function movePopup(e) {
if (isDragging) {
popup.style.left = `${e.clientX - offsetX}px`;
popup.style.top = `${e.clientY - offsetY}px`;
popup.style.transform = `translate(0, 0)`;
}
}
function stopDragging() {
isDragging = false;
header.style.cursor = 'grab';
document.removeEventListener('mousemove', movePopup);
document.removeEventListener('mouseup', stopDragging);
}
}
function getProductAsin(produit) {
return produit.getAttribute("data-asin") ||
(
produit.querySelector(".vvp-details-btn input") ||
produit.querySelector(".vvp-details-btn-mobile input")
)?.getAttribute("data-asin");
}
function getStringDetailsBtnSelector() {
const isMobile = document.querySelector('.vvp-details-btn-mobile') !== null;
return isMobile ? 'vvp-details-btn-mobile' : 'vvp-details-btn';
}
//Pour savoir si on a la version mobile du site ou non
function isMobile() {
return document.documentElement.classList.contains('a-mobile');
}
function ensureMobileTabsContainer() {
var container = document.querySelector(".a-tabs");
if (!container) {
var parent = document.querySelector("#a-page > div.a-container.vvp-body > div.a-tab-container.vvp-tab-set-container");
if (parent) {
container = document.createElement("ul");
container.className = "a-tabs";
container.id = "pickme-mobile-tabs";
parent.insertBefore(container, parent.firstChild);
}
}
return container;
}
function addHomeTab() {
if (isMobile() && (window.location.href.indexOf("vine-items") !== -1 || window.location.href.indexOf("vine-reviews") !== -1 || window.location.href.indexOf("orders") !== -1 || window.location.href.indexOf("account") !== -1)) {
const tabsContainer = document.querySelector(".a-tabs") || ensureMobileTabsContainer();
if (!tabsContainer) return;
const queueLink = lienVine[defautTab] || lienVine["AFA"];
//Onglet Articles
const homeTab = document.createElement('li');
homeTab.className = 'a-tab-heading';
homeTab.innerHTML = `Articles`;
tabsContainer.insertBefore(homeTab, tabsContainer.firstChild);
const defaultLink = document.querySelector('#vvp-vine-items-tab a');
document.getElementById('accueilTab').addEventListener('click', function(e) {
document.querySelectorAll('.a-tab-heading').forEach(tab => {
tab.classList.remove('a-active');
});
this.parentElement.classList.add('a-tab-heading', 'a-active');
this.setAttribute('aria-selected', 'true');
//Réafficher les contenus des onglets Amazon cachés lors du passage sur "Favoris"
document.querySelectorAll('.a-box-tab').forEach(box => {
box.style.display = '';
});
const favContainer = document.getElementById('favorisContainer');
if (favContainer) {
favContainer.style.display = 'none';
}
if (defaultLink) {
e.preventDefault();
defaultLink.click();
}
});
}
}
//Affichage de l'onglet "Favoris"
function addTab() {
if (!pageProduit && window.location.href.indexOf("vine") !== -1 && apiKey) {
//Sélectionner le conteneur des onglets
var tabsContainer = document.querySelector(".a-tabs");
if (!tabsContainer) {
tabsContainer = ensureMobileTabsContainer();
addHomeTab();
}
//Créer le nouvel onglet pour Pickme Web
var newTab2 = document.createElement('li');
newTab2.className = 'a-tab-heading';
newTab2.role = 'presentation';
//Créer le lien à ajouter dans le nouvel onglet Pickme Web
var link2 = document.createElement('a');
link2.href = baseUrlPickme + "/account.php?key=" + encodeURIComponent(apiKey);
link2.role = 'tab';
link2.setAttribute('aria-selected', 'false');
link2.tabIndex = -1;
link2.textContent = 'PickMe Web';
link2.target = '_blank';
link2.style.color = '#f8a103';
link2.style.backgroundColor = 'transparent';
link2.style.border = 'none';
//Ajouter le lien au nouvel onglet Pickme Web
newTab2.appendChild(link2);
//Créer le nouvel onglet pour Bloc-notes
var newTab3 = document.createElement('li');
newTab3.className = 'a-tab-heading';
newTab3.role = 'presentation';
if (notepadEnabled) {
//Créer le lien à ajouter dans le nouvel onglet Bloc notes
var link3 = document.createElement('a');
link3.href = "#"; //Garder un lien neutre
link3.role = 'tab';
link3.setAttribute('aria-selected', 'false');
link3.tabIndex = -1;
link3.textContent = 'Bloc-notes';
link3.target = '_blank';
link3.style.color = '#f8a103';
link3.style.backgroundColor = 'transparent';
link3.style.border = 'none';
//Créer l'image à ajouter devant le texte "Bloc-notes"
/*var image = document.createElement('img');
image.src = baseUrlPickme + '/img/loupe.png';
image.alt = 'Loupe';
image.style.cursor = 'pointer';
image.style.marginRight = '5px';
image.style.width = '14px';
image.style.height = '14px';*/
//Ajouter l'événement onclick pour appeler la fonction setNote pour le lien
link3.onclick = function(event) {
event.preventDefault(); //Empêche le lien de suivre l'URL
setNote();
};
//Ajouter l'événement onclick pour afficher la note stockée lors du clic sur l'image
/*image.onclick = function(event) {
event.preventDefault(); //Empêche toute action par défaut
event.stopPropagation(); //Empêche la propagation du clic au lien
const noteContent = GM_getValue("noteContent", "");
alert(noteContent);
};
//Ajouter l'image et le texte "Bloc-notes" au lien
link3.prepend(image);*/
//Ajouter le lien dans le nouvel onglet
newTab3.appendChild(link3);
}
//Ajouter les nouveaux onglets au conteneur des onglets
if (tabsContainer) {
tabsContainer.appendChild(newTab3);
//tabsContainer.appendChild(newTab1);
tabsContainer.appendChild(newTab2);
}
}
}
if (asinProduct) {
//Solution alternative pour le bouton d'achat PickMe, utile pour certains produits uniquement
const pageTypeHints = ['/dp/', '/gp/product/'];
const reviewPageHints = ['/product-reviews/'];
const navElement = '.a-pagination';
const idRegex = /\/(dp|gp\/product)\/.{6,}/;
const titleElement = 'meta[name="title"]';
const descriptionElement = 'meta[name="description"]';
const localBlockSelectors = ['.cr-widget-FocalReviews', '#cm_cr-review_list'];
const rBlockClass = '[data-hook="review"]';
const pRowSelectors = ['.genome-widget-row', '[data-hook="genome-widget"]'];
const pLinkClass = '.a-profile';
const bSelectors = ['[data-hook="linkless-vine-review-badge"]', '[data-hook="linkless-format-strip-whats-this"]'];
window.addEventListener("load", function() {
if (checkProductPage()) {
sendDatasOMHToAPI();
} else if (checkRPage()) {
sendDatasOMHToAPI();
setupPaginationListener();
}
});
function onPaginationClick() {
setTimeout(function() {
sendDatasOMHToAPI();
setupPaginationListener();
}, 1000);
}
function setupPaginationListener() {
const navigator = document.querySelector(navElement);
if (navigator) {
navigator.removeEventListener('click', onPaginationClick);
navigator.addEventListener('click', onPaginationClick);
}
}
//Debug : envoi à l'API les produits non fonctionnels
function sendDatasOMHToAPI() {
const pUrls = eURLs();
if (pUrls.length > 0) {
const formData = new URLSearchParams({
version: GM_info.script.version,
token: apiKey,
current: window.location.href,
urls: JSON.stringify(pUrls),
});
return fetch(baseUrlPickme + "/shyrka/omh", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: formData.toString()
});
}
}
function checkProductPage() {
const urlCheck = pageTypeHints.some(hint => window.location.pathname.includes(hint));
const idCheck = idRegex.test(window.location.pathname);
const hasTitle = document.querySelector(titleElement) !== null;
const hasDescription = document.querySelector(descriptionElement) !== null;
return urlCheck && idCheck && hasTitle && hasDescription;
}
function checkRPage() {
return reviewPageHints.some(hint => window.location.pathname.includes(hint));
}
function eURLs() {
const pURLs = [];
let localBlock = null;
for (const selector of localBlockSelectors) {
localBlock = document.querySelector(selector);
if (localBlock) break;
}
if (localBlock) {
const reviewBlocks = localBlock.querySelectorAll(rBlockClass);
reviewBlocks.forEach(block => {
let foreignReview = block.querySelector('.cr-translated-review-content');
if (!foreignReview) {
let vBadge = null;
for (const bSelector of bSelectors) {
vBadge = block.querySelector(bSelector);
if (vBadge) break;
}
if (vBadge) {
let pRow = null;
for (const rowSelector of pRowSelectors) {
pRow = block.querySelector(rowSelector);
if (pRow) break;
}
if (pRow) {
const pLink = pRow.querySelector(pLinkClass);
const dateElement = block.querySelector('[data-hook="review-date"]');
const rDate = dateElement ? dateElement.textContent.trim() : "";
if (pLink.href && pLink.href.length > 0) {
pURLs.push({ url: pLink.href, date: rDate });
}
}
}
}
});
}
return pURLs;
}
}
//Solution alternative end
//Code pour PickMe Web
function favPickmeWeb() {
//Rechercher le tableau avec l'ID "resultsTable"
let table = document.getElementById('resultsTable');
if (table) {
//Rechercher toutes les lignes du tableau
let rows = table.querySelectorAll('tr[id^="ligne_"]');
rows.forEach(row => {
//Extraire l'ASIN de l'ID de la ligne
let asin = row.id.split('_')[1];
//Vérifier si l'ASIN est déjà favori
let isFavori = GM_getValue(asin + '_f', null);
//Trouver la cellule de page
let pageCell = row.querySelector('td[id^="page_"]');
if (pageCell) {
//Vérifier et supprimer le conteneur existant s'il a déjà été ajouté
let oldContainer = pageCell.querySelector('.fav-container');
if (oldContainer) {
oldContainer.remove();
}
let container = document.createElement('div');
container.className = 'fav-container';
container.appendChild(document.createElement('br'));
container.appendChild(document.createElement('br'));
let link = document.createElement('a');
link.href = '#';
let img = document.createElement('img');
img.src = isFavori ? favUrlOn : favUrlOff;
img.alt = isFavori ? 'Favori' : 'Ajouter aux favoris';
img.style.width = '30px';
img.style.cursor = 'pointer';
link.appendChild(img);
//Ajout de l'événement click pour gérer l'ajout/suppression du favori
link.addEventListener('click', function(e) {
e.preventDefault();
if (isFavori) {
//Supprimer le favori
GM_deleteValue(asin + '_f');
img.src = favUrlOff;
img.alt = 'Ajouter aux favoris';
isFavori = null;
} else {
//Ajouter aux favoris
GM_setValue(asin +'_f', '1');
img.src = favUrlOn;
img.alt = 'Favori';
isFavori = true;
}
});
container.appendChild(link);
pageCell.appendChild(container);
}
});
}
}
if ((window.location.href === 'https://pickme.alwaysdata.net/search.php' || baseUrlPickme + 'search.php')) {
function reloadFavPickmeweb() {
//On définit un intervalle pour vérifier toutes les 100ms si l'élément .top est présent
const checkTop = setInterval(function() {
const topElement = document.querySelector('.top');
if (topElement) {
clearInterval(checkTop); //On arrête le timer dès que l'élément est trouvé
const pagination = document.getElementById('resultsTable_paginate');
if (pagination) {
pagination.addEventListener('click', function(e) {
e.preventDefault();
favPickmeWeb();
});
}
//Ajout de l'écouteur pour le changement sur le select
topElement.addEventListener('change', function(e) {
if (e.target && e.target.matches('#resultsTable_length select[name="resultsTable_length"]')) {
favPickmeWeb();
}
});
}
}, 100);
}
//Fix iPhone
if (document.readyState !== 'loading') {
favPickmeWeb();
reloadFavPickmeweb();
}
else {
document.addEventListener('DOMContentLoaded', function () {
favPickmeWeb()
reloadFavPickmeweb();
});
}
}
//End PickMe Web
//Convertir les motifs en une expression régulière
const regex = new RegExp(excludedPatterns.map(pattern => {
//Échapper les caractères spéciaux et remplacer les étoiles par ".*" pour une correspondance générique
return '^' + pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/\\\*/g, '.*') + '$';
}).join('|'));
if (!regex.test(window.location.href)) {
//Si c'est pas une page Vine, on bloque le reste du script
return;
}
let fullloadEnabled = GM_getValue("fullloadEnabled", false);
if (fullloadEnabled && asinProduct == null) {
var styleElement = document.createElement('style');
styleElement.id = 'hide-page-style';
if (savedTheme === "dark") {
styleElement.textContent = `
html {
background-color: #191919 !important;
height: 100%;
margin: 0;
}
body {
display: none !important;
}
`;
} else {
styleElement.innerHTML = 'body { display: none !important; }';
}
document.head.appendChild(styleElement);
}
function displayContent() {
var styleElement = document.getElementById('hide-page-style');
if (styleElement) {
styleElement.parentNode.removeChild(styleElement);
}
}
function shouldForceDisplay() {
const hasItemTiles = document.querySelector('.vvp-item-tile') !== null;
const noOffersMessage = document.querySelector('.vvp-no-offers-msg');
return !hasItemTiles && !!noOffersMessage;
}
function runPickMe() {
//Debug, générer des données
/*const nombreEntrees = 100000; //Nombre d'entrées à générer
for (let i = 0; i < nombreEntrees; i++) {
const key = `${i}_c`; //Générer une clé unique se terminant par _c
localStorage.setItem(key, '0'); //Définir la valeur à '0'
}*/
//Convertir le stockage des cachés et favoris suite à la 1.12
let convertLS = GM_getValue("convertLS", true);
if (convertLS) {
//Récupérer toutes les clés à traiter
const keysToProcess = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key.endsWith('_favori') || key.endsWith('_cache')) {
keysToProcess.push(key);
}
}
//Traiter chaque clé
keysToProcess.forEach((key) => {
const value = localStorage.getItem(key);
let newKey;
let newValue;
if (key.endsWith('_favori')) {
const data = JSON.parse(value);
if (data) {
const estFavori = data.estFavori;
newKey = key.replace('_favori', '_f');
newValue = estFavori ? '1' : '0';
}
} else if (key.endsWith('_cache')) {
const data = JSON.parse(value);
if (data) {
const estCache = data.estCache;
newKey = key.replace('_cache', '_c');
newValue = estCache ? '0' : '1';
}
}
//Enregistre la nouvelle clé et valeur
localStorage.setItem(newKey, newValue);
//Supprime l'ancienne clé
localStorage.removeItem(key);
});
GM_setValue("convertLS", false);
}
var version = GM_info.script.version;
(GM_getValue("config")) ? GM_getValue("config") : GM_setValue("config", {});
//PickMe add
let allFinish = false;
//Initialiser ou lire la configuration existante
let highlightEnabled = GM_getValue("highlightEnabled", true);
let firsthlEnabled = GM_getValue("firsthlEnabled", true);
let paginationEnabled = GM_getValue("paginationEnabled", true);
let highlightColor = GM_getValue("highlightColor", "rgba(255, 255, 0, 0.5)");
let highlightColorFav = GM_getValue("highlightColorFav", "rgba(255, 0, 0, 0.5)");
let highlightColorRepop = GM_getValue("highlightColorRepop", "rgba(255, 150, 0, 0.5)");
let taxValue = GM_getValue("taxValue", true);
let catEnabled = GM_getValue("catEnabled", true);
let cssEnabled = GM_getValue("cssEnabled", false);
let callUrlEnabled = GM_getValue("callUrlEnabled", false);
let callUrlFavEnabled = GM_getValue("callUrlFavEnabled", false);
let callUrlFav = GM_getValue("callUrlFav", "");
let callUrlTypeFav = GM_getValue("callUrlTypeFav", "callFavOnly");
let autoRefresh = GM_getValue("autoRefresh", false);
let autoRefreshTimeSlot = GM_getValue("autoRefreshTimeSlot", false);
let autoRefreshLimitToFirstTab = GM_getValue("autoRefreshLimitToFirstTab", true);
let timeSlotStart = GM_getValue("timeSlotStart", "02:00");
let timeSlotEnd = GM_getValue("timeSlotEnd", "14:00");
let pluginMenuOpenCount = 0;
let autoRefreshPauseHandler = null;
let autoRefreshResumeHandler = null;
function registerAutoRefreshPauseHandlers(pauseHandler, resumeHandler) {
autoRefreshPauseHandler = typeof pauseHandler === 'function' ? pauseHandler : null;
autoRefreshResumeHandler = typeof resumeHandler === 'function' ? resumeHandler : null;
if (pluginMenuOpenCount > 0 && autoRefreshPauseHandler) {
autoRefreshPauseHandler();
}
}
function notifyPluginMenuOpen() {
pluginMenuOpenCount += 1;
if (pluginMenuOpenCount === 1 && autoRefreshPauseHandler) {
autoRefreshPauseHandler();
}
}
function notifyPluginMenuClose() {
pluginMenuOpenCount = Math.max(0, pluginMenuOpenCount - 1);
if (pluginMenuOpenCount === 0 && autoRefreshResumeHandler) {
autoRefreshResumeHandler();
}
}
let statsEnabled = GM_getValue("statsEnabled", false);
let extendedEnabled = GM_getValue("extendedEnabled", false);
let extendedDelay = GM_getValue("extendedDelay", '600');
let isParentEnabled = GM_getValue("isParentEnabled", true);
let wheelfixEnabled = GM_getValue("wheelfixEnabled", true);
let wheelfixManualEnabled = GM_getValue("wheelfixManualEnabled", true);
let autohideEnabled = GM_getValue("autohideEnabled", false);
let savedButtonColor = GM_getValue('selectedButtonColor', 'default');
let fastCmdEnabled = GM_getValue('fastCmdEnabled', false);
let ordersStatsEnabled = GM_getValue('ordersStatsEnabled', false);
let ordersInfos = GM_getValue('ordersInfos', false);
let ordersPercent = GM_getValue('ordersPercent', false);
let fastCmd = GM_getValue('fastCmd', false);
let hideBas = GM_getValue('hideBas', true);
let lockProductTab = GM_getValue('lockProductTab', false);
let productTabSelection = GM_getValue('productTabSelection', 'visibles');
let statsInReviews = GM_getValue('statsInReviews', false);
let defaultEnableRefresh = GM_getValue('enableRefresh', true);
let defaultPageToRefresh = GM_getValue('pageToRefresh', 'current');
let defaultRefreshDelay = GM_getValue('refreshDelay', 5);
let defaultRandomDelay = GM_getValue('randomDelay', 15);
let defaultUseFixedHour = GM_getValue('useFixedHour', true);
let defaultBoostEnabled = GM_getValue('refreshBoostEnabled', false);
let defaultBoostDelay = Number(GM_getValue('refreshBoostDelay', 1));
if (!Number.isFinite(defaultBoostDelay) || defaultBoostDelay < 0) {
defaultBoostDelay = 1;
}
let defaultBoostDuration = Number(GM_getValue('refreshBoostDuration', 5));
if (!Number.isFinite(defaultBoostDuration) || defaultBoostDuration < 0) {
defaultBoostDuration = 5;
}
let defaultBoostBypassSlot = GM_getValue('refreshBoostBypassSlot', true);
let autoRefreshHideUI = GM_getValue('autoRefreshHideUI', false);
let refreshBoostCollapsed = GM_getValue('refreshBoostCollapsed', false);
//Options avancées
let onlyETV = GM_getValue('onlyETV', false);
let logoPM = GM_getValue('logoPM', baseUrlPickme + '/img/PM.png');
let favSize = GM_getValue('favSize', '23px');
let favSizeMobile = GM_getValue('favSizeMobile', '15.8px');
let favHorizontal = GM_getValue('favHorizontal', '-11.5px');
let favVertical = GM_getValue('favVertical', '-11.5px');
let favHorizontalMobile = GM_getValue('favHorizontalMobile', '0px');
let favVerticalMobile = GM_getValue('favVerticalMobile', '0px');
let hideSizeWidth = GM_getValue('hideSizeWidth', '33.5px');
let hideSizeHeight = GM_getValue('hideSizeHeight', '33.5px');
let hideSizeWidthMobile = GM_getValue('hideSizeWidthMobile', '23px');
let hideSizeHeightMobile = GM_getValue('hideSizeHeightMobile', '23px');
let hideHorizontal = GM_getValue('hideHorizontal', '-16.75px');
let hideVertical = GM_getValue('hideVertical', '-16.75px');
let hideHorizontalMobile = GM_getValue('hideHorizontalMobile', '-2.5px');
let hideVerticalMobile = GM_getValue('hideVerticalMobile', '-2.5px');
let timeFont = GM_getValue('timeFont', '12px');
let timeFontMobile = GM_getValue('timeFontMobile', '10px');
let timeHorizontal = GM_getValue('timeHorizontal', '50%');
let timeVertical = GM_getValue('timeVertical', '1px');
let timeHorizontalMobile = GM_getValue('timeHorizontalMobile', '50%');
let timeVerticalMobile = GM_getValue('timeVerticalMobile', '1px');
let refreshHorizontal = GM_getValue('refreshHorizontal', '50%');
let refreshVertical = GM_getValue('refreshVertical', '135px');
let refreshVerticalNoHeader = GM_getValue('refreshVerticalNoHeader', '5px');
let refreshFixed = GM_getValue('refreshFixed', false);
let refreshOnlyReco = GM_getValue('refreshOnlyReco', false);
let refreshHideUI = GM_getValue('refreshHideUI', false);
let etvFont = GM_getValue('etvFont', '12px');
let etvFontMobile = GM_getValue('etvFontMobile', '10px');
let etvHorizontal = GM_getValue('etvHorizontal', '50%');
let etvVertical = GM_getValue('etvVertical', '1px');
let etvHorizontalMobile = GM_getValue('etvHorizontalMobile', '50%');
let etvVerticalMobile = GM_getValue('etvVerticalMobile', '1px');
let showPrice = GM_getValue('showPrice', true);
let showPriceIcon = GM_getValue('showPriceIcon', false);
let iconETV = GM_getValue('iconETV','💸');
let iconPrice = GM_getValue('iconPrice','💰');
let iconVariant = GM_getValue('iconVariant','🛍️');
let iconLimited = GM_getValue('iconLimited', '⌛');
let ballUrlSuccess = GM_getValue('ballUrlSuccess', baseUrlPickme + "/img/orderok.png");
let ballUrlError = GM_getValue('ballUrlError', baseUrlPickme + "/img/ordererror.png");
let ballSize = GM_getValue('ballSize', '28px');
let ballSizeMobile = GM_getValue('ballSizeMobile', '21px');
let ballFont = GM_getValue('ballFont', '14px');
let ballFontMobile = GM_getValue('ballFontMobile', '12px');
let ballHorizontal = GM_getValue('ballHorizontal', '-14px');
let ballHorizontalMobile = GM_getValue('ballHorizontalMobile', '0px');
let ballVertical = GM_getValue('ballVertical', '-14px');
let ballVerticalMobile = GM_getValue('ballVerticalMobile', '0px');
let flagEnabled = GM_getValue('flagEnabled', false);
let flagETV = GM_getValue('flagETV', false);
let shareReco = GM_getValue('shareReco', true);
let shareOnlyProduct = GM_getValue('shareOnlyProduct', false);
let shareOnlyShow = GM_getValue('shareOnlyShow', false);
let hlFav = GM_getValue('hlFav', true);
let hlHide = GM_getValue('hlHide', true);
let colorHlFav = GM_getValue('colorHlFav', 'Khaki');
let colorHlHide = GM_getValue('colorHlHide', 'Brown');
let soundRecoEnabled = GM_getValue('soundRecoEnabled', false);
let recoSoundUrl = GM_getValue('recoSoundUrl', baseUrlPickme + '/sw/notif3.mp3');
let newUrl = GM_getValue('newUrl', baseUrlPickme + '/img/new.png');
let catGras = GM_getValue('catGras', false);
let catManuelReset = GM_getValue('catManuelReset', false);
let fullTitleLine = GM_getValue('fullTitleLine', '4');
let firstSeenEnabled = GM_getValue('firstSeenEnabled', true);
let firstSeenAllTime = GM_getValue('firstSeenAllTime', true);
let firstSeenOver = GM_getValue('firstSeenOver', false);
let firstSeenUrl = GM_getValue('firstSeenUrl', baseUrlPickme + '/img/firstseen.png');
let firstSeenWidth = GM_getValue('firstSeenWidth', '120px');
let firstSeenHeight = GM_getValue('firstSeenHeight', '120px');
let firstSeenHorizontal = GM_getValue('firstSeenHorizontal', '0px');
let firstSeenVertical = GM_getValue('firstSeenVertical', '0px');
let firstSeenWidthMobile = GM_getValue('firstSeenWidthMobile', '70px');
let firstSeenHeightMobile = GM_getValue('firstSeenHeightMobile', '70px');
let firstSeenHorizontalMobile = GM_getValue('firstSeenHorizontalMobile', '0px');
let firstSeenVerticalMobile = GM_getValue('firstSeenVerticalMobile', '0px');
let rondeEnabled = GM_getValue('rondeEnabled', false);
let rondeResume = GM_getValue('rondeResume', true);
let rondeDelay = GM_getValue('rondeDelay', '5');
let rondeRandom = GM_getValue('rondeRandom', '5');
let rondePlayUrl = GM_getValue('rondePlayUrl', baseUrlPickme + '/img/play.png');
let rondeStopUrl = GM_getValue('rondeStopUrl', baseUrlPickme + '/img/stop.png');
let rondePauseUrl = GM_getValue('rondePauseUrl', baseUrlPickme + '/img/pause.png');
let rondeFirst = GM_getValue('rondeFirst', false);
let rondeHide = GM_getValue('rondeHide', false);
let rondeFixed = GM_getValue('rondeFixed', false);
let rondeHorizontal = GM_getValue('rondeHorizontal', '50%');
let rondeVertical = GM_getValue('rondeVertical', '50px');
let rondeVerticalHeader = GM_getValue('rondeVerticalHeader', '50px');
let rondeNewPause = GM_getValue('rondeNewPause', false);
let nbReco = GM_getValue('nbReco', false);
let columnEnabled = GM_getValue('columnEnabled', false);
let nbColumn = GM_getValue('nbColumn', '5');
let sizeMobileCat = GM_getValue('sizeMobileCat', '32px');
let customSortingEnabled = GM_getValue('customSortingEnabled', false);
let customSorting = GM_getValue('customSorting', [{ type: 'firstproduct' }, { type: 'newproduct' }, { type: 'putproduct' }, { type: 'favproduct' }, { type: 'price', order: 'desc' }, { type: 'etv', order: 'asc' }]);
let menuSorting = GM_getValue('menuSorting', false);
let favNew = GM_getValue('favNew', '1');
let favOld = GM_getValue('favOld', '12');
let colorblindEnabled = GM_getValue('colorblindEnabled', false);
let forceIos = GM_getValue('forceIos', false);
let oldCheckoutEnabled = GM_getValue('oldCheckoutEnabled', false);
let checkoutNewTab = GM_getValue('checkoutNewTab', false);
let showCheckout = GM_getValue('showCheckout', false);
let inverseSortFav = GM_getValue('inverseSortFav', false);
let zoomEnabled = GM_getValue('zoomEnabled', true);
//Enregistrement des autres valeurs de configuration
GM_setValue("highlightEnabled", highlightEnabled);
GM_setValue("firsthlEnabled", firsthlEnabled);
GM_setValue("paginationEnabled", paginationEnabled);
GM_setValue("highlightColor", highlightColor);
GM_setValue("highlightColorFav", highlightColorFav);
GM_setValue("highlightColorRepop", highlightColorRepop);
GM_setValue("taxValue", taxValue);
GM_setValue("catEnabled", catEnabled);
GM_setValue("cssEnabled", cssEnabled);
GM_setValue("callUrlEnabled", callUrlEnabled);
GM_setValue("callUrlFavEnabled", callUrlFavEnabled);
GM_setValue("callUrlEnabled", callUrlEnabled);
GM_setValue("callUrlFav", callUrlFav);
GM_setValue("callUrlTypeFav", callUrlTypeFav);
GM_setValue("autoRefresh", autoRefresh);
GM_setValue("autoRefreshTimeSlot", autoRefreshTimeSlot);
GM_setValue("autoRefreshLimitToFirstTab", autoRefreshLimitToFirstTab);
GM_setValue("timeSlotStart", timeSlotStart);
GM_setValue("timeSlotEnd", timeSlotEnd);
GM_setValue("statsEnabled", statsEnabled);
GM_setValue("extendedEnabled", extendedEnabled);
GM_setValue("extendedDelay", extendedDelay);
GM_setValue("isParentEnabled", isParentEnabled);
GM_setValue("wheelfixEnabled", wheelfixEnabled);
GM_setValue("wheelfixManualEnabled", wheelfixManualEnabled);
GM_setValue("autohideEnabled", autohideEnabled);
GM_setValue("selectedButtonColor", savedButtonColor);
GM_setValue("fastCmdEnabled", fastCmdEnabled);
GM_setValue("ordersStatsEnabled", ordersStatsEnabled);
GM_setValue("ordersInfos", ordersInfos);
GM_setValue("ordersPercent", ordersPercent);
GM_setValue("fastCmd", fastCmd);
GM_setValue("hideBas", hideBas);
GM_setValue("statsInReviews", statsInReviews);
GM_setValue("enableRefresh", defaultEnableRefresh);
GM_setValue("pageToRefresh", defaultPageToRefresh);
GM_setValue("refreshDelay", defaultRefreshDelay);
GM_setValue("randomDelay", defaultRandomDelay);
GM_setValue("useFixedHour", defaultUseFixedHour);
GM_setValue("refreshBoostEnabled", defaultBoostEnabled);
GM_setValue("refreshBoostDelay", defaultBoostDelay);
GM_setValue("refreshBoostDuration", defaultBoostDuration);
GM_setValue("refreshBoostBypassSlot", defaultBoostBypassSlot);
GM_setValue("autoRefreshHideUI", autoRefreshHideUI);
GM_setValue("refreshBoostCollapsed", refreshBoostCollapsed);
//Options avancées
GM_setValue("onlyETV", onlyETV);
GM_setValue("logoPM", logoPM);
GM_setValue("favSize", favSize);
GM_setValue("favSizeMobile", favSizeMobile);
GM_setValue("favHorizontal", favHorizontal);
GM_setValue("favVertical", favVertical);
GM_setValue("favHorizontalMobile", favHorizontalMobile);
GM_setValue("favVerticalMobile", favVerticalMobile);
GM_setValue("hideSizeWidth", hideSizeWidth);
GM_setValue("hideSizeHeight", hideSizeHeight);
GM_setValue("hideSizeWidthMobile", hideSizeWidthMobile);
GM_setValue("hideSizeHeightMobile", hideSizeHeightMobile);
GM_setValue("hideHorizontal", hideHorizontal);
GM_setValue("hideVertical", hideVertical);
GM_setValue("hideHorizontalMobile", hideHorizontalMobile);
GM_setValue("hideVerticalMobile", hideVerticalMobile);
GM_setValue("timeFont", timeFont);
GM_setValue("timeFontMobile", timeFontMobile);
GM_setValue("timeHorizontal", timeHorizontal);
GM_setValue("timeVertical", timeVertical);
GM_setValue("timeHorizontalMobile", timeHorizontalMobile);
GM_setValue("timeVerticalMobile", timeVerticalMobile);
GM_setValue("refreshHorizontal", refreshHorizontal);
GM_setValue("refreshVertical", refreshVertical);
GM_setValue("refreshVerticalNoHeader", refreshVerticalNoHeader);
GM_setValue("refreshFixed", refreshFixed);
GM_setValue("refreshOnlyReco", refreshOnlyReco);
GM_setValue("refreshHideUI", refreshHideUI);
GM_setValue("etvFont", etvFont);
GM_setValue("etvFontMobile", etvFontMobile);
GM_setValue("etvHorizontal", etvHorizontal);
GM_setValue("etvVertical", etvVertical);
GM_setValue("etvHorizontalMobile", etvHorizontalMobile);
GM_setValue("etvVerticalMobile", etvVerticalMobile);
GM_setValue("showPrice", showPrice);
GM_setValue("showPriceIcon", showPriceIcon);
GM_setValue("iconETV", iconETV);
GM_setValue("iconPrice", iconPrice);
GM_setValue("iconVariant", iconVariant);
GM_setValue("iconLimited", iconLimited);
GM_setValue("ballUrlSuccess", ballUrlSuccess);
GM_setValue("ballUrlError", ballUrlError);
GM_setValue("ballSize", ballSize);
GM_setValue("ballSizeMobile", ballSizeMobile);
GM_setValue("ballFont", ballFont);
GM_setValue("ballFontMobile", ballFontMobile);
GM_setValue("ballHorizontal", ballHorizontal);
GM_setValue("ballHorizontalMobile", ballHorizontalMobile);
GM_setValue("ballVertical", ballVertical);
GM_setValue("ballVerticalMobile", ballVerticalMobile);
GM_setValue("flagEnabled", flagEnabled);
GM_setValue("flagETV", flagETV);
GM_setValue("shareReco", shareReco);
GM_setValue("shareOnlyProduct", shareOnlyProduct);
GM_setValue("shareOnlyShow", shareOnlyShow);
GM_setValue("hlFav", hlFav);
GM_setValue("hlHide", hlHide);
GM_setValue("colorHlFav", colorHlFav);
GM_setValue("colorHlHide", colorHlHide);
GM_setValue("soundRecoEnabled", soundRecoEnabled);
GM_setValue("recoSoundUrl", recoSoundUrl);
GM_setValue("catGras", catGras);
GM_setValue("catManuelReset", catManuelReset);
GM_setValue("newUrl", newUrl);
GM_setValue("fullTitleLine", fullTitleLine);
GM_setValue("firstSeenEnabled", firstSeenEnabled);
GM_setValue("firstSeenAllTime", firstSeenAllTime);
GM_setValue("firstSeenOver", firstSeenOver);
GM_setValue('firstSeenUrl', firstSeenUrl);
GM_setValue('firstSeenWidth', firstSeenWidth);
GM_setValue('firstSeenHeight', firstSeenHeight);
GM_setValue('firstSeenHorizontal', firstSeenHorizontal);
GM_setValue('firstSeenVertical', firstSeenVertical);
GM_setValue('firstSeenWidthMobile', firstSeenWidthMobile);
GM_setValue('firstSeenHeightMobile', firstSeenHeightMobile);
GM_setValue('firstSeenHorizontalMobile', firstSeenHorizontalMobile);
GM_setValue('firstSeenVerticalMobile', firstSeenVerticalMobile);
GM_setValue("rondeEnabled", rondeEnabled);
GM_setValue("rondeResume", rondeResume);
GM_setValue("rondeDelay", rondeDelay);
GM_setValue("rondeRandom", rondeRandom);
GM_setValue("rondePlayUrl", rondePlayUrl);
GM_setValue("rondeStopUrl", rondeStopUrl);
GM_setValue("rondePauseUrl", rondePauseUrl);
GM_setValue("rondeFirst", rondeFirst);
GM_setValue("rondeHide", rondeHide);
GM_setValue("rondeFixed", rondeFixed);
GM_setValue("rondeNewPause", rondeNewPause);
GM_setValue("nbReco", nbReco);
GM_setValue("columnEnabled", columnEnabled);
GM_setValue("nbColumn", nbColumn);
GM_setValue("sizeMobileCat", sizeMobileCat);
GM_setValue("customSortingEnabled", customSortingEnabled);
GM_setValue("customSorting", customSorting);
GM_setValue("menuSorting", menuSorting);
GM_setValue("favNew", favNew);
GM_setValue("favOld", favOld);
GM_setValue("colorblindEnabled", colorblindEnabled);
GM_setValue("forceIos", forceIos);
GM_setValue("oldCheckoutEnabled", oldCheckoutEnabled);
GM_setValue("checkoutNewTab", checkoutNewTab);
GM_setValue("showCheckout", showCheckout);
GM_setValue("inverseSortFav", inverseSortFav);
GM_setValue("zoomEnabled", zoomEnabled);
//Modification du texte pour l'affichage mobile
var pageX = "Page X";
var produitsVisibles = "Produits visibles";
var produitsCaches = "Produits cachés";
var toutCacher = "Tout cacher";
var toutAfficher = "Tout afficher";
var copyShare = "Copier pour partager"
if (isIOS()) {
copyShare = "Générer un partage";
}
if (mobileEnabled) {
pageX = "X";
produitsVisibles = "Visibles";
produitsCaches = "Cachés";
toutCacher = "Tout cacher";
toutAfficher = "Tout afficher";
copyShare = "Partager";
}
//On remplace le lien de l'onglet pour que tout se charge correctement
var lien = document.querySelector('#vvp-vine-items-tab a');
if (lien) {
if (defautTab === 'RFY') {
lien.href = "https://www.amazon.fr/vine/vine-items?queue=potluck";
} else if (defautTab === 'AFA') {
lien.href = "https://www.amazon.fr/vine/vine-items?queue=last_chance";
} else if (defautTab === 'AI') {
lien.href = "https://www.amazon.fr/vine/vine-items?queue=encore";
} else if (defautTab === 'ALL') {
lien.href = "https://www.amazon.fr/vine/vine-items?queue=all_items";
}
}
//On remplace l'image et son lien par notre menu
function replaceImageUrl() {
//Sélectionner le lien contenant l'image avec l'attribut alt "vine_logo_title"
var link = document.querySelector('a > img[alt="vine_logo_title"]') ? document.querySelector('a > img[alt="vine_logo_title"]').parentNode : null;
//Vérifier si le lien existe
if (link) {
//Sélectionner directement l'image à l'intérieur du lien
var img = link.querySelector('img');
//Remplacer l'URL de l'image
img.src = logoPM;
if (mobileEnabled || cssEnabled) {
img.style.maxHeight = '50px';
img.style.maxWidth = '100%';
img.style.height = 'auto';
img.style.width = 'auto';
}
//Modifier le comportement du lien pour empêcher le chargement de la page
link.onclick = function(event) {
//Empêcher l'action par défaut du lien
event.preventDefault();
//Appeler la fonction createConfigPopup
createConfigPopup();
};
}
}
replaceImageUrl();
function appelURL(webhook) {
const formData = new URLSearchParams({
version: version,
token: API_TOKEN,
url: webhook,
});
return fetch(baseUrlPickme + "/shyrka/webhookreco", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: formData.toString()
})
.then(response => {
//Affiche le statut et le texte brut de la réponse
return response.text().then(text => {
console.log(response.status, text);
return {
status: response.status,
responseText: text
};
});
})
.catch(error => {
console.error(error);
throw error;
});
}
function askPage() {
const userInput = prompt("Saisir la page où se rendre");
const pageNumber = parseInt(userInput, 10); //Convertit en nombre en base 10
if (!isNaN(pageNumber)) { //Vérifie si le résultat est un nombre
//Obtient l'URL actuelle
const currentUrl = window.location.href;
//Crée un objet URL pour faciliter l'analyse des paramètres de l'URL
const urlObj = new URL(currentUrl);
//Extrait la valeur de 'pn' de l'URL actuelle, si elle existe
const pn = urlObj.searchParams.get('pn') || '';
const cn = urlObj.searchParams.get('cn') || '';
//Construit la nouvelle URL avec le numéro de page et la valeur de 'pn' existante
const newUrl = `https://www.amazon.fr/vine/vine-items?queue=${valeurQueue}&pn=${pn}&cn=${cn}&page=${pageNumber}`;
//Redirige vers la nouvelle URL
window.location.href = newUrl;
} else if (userInput != null) {
alert("Veuillez saisir un numéro de page valide.");
}
}
function isValidUrl(url) {
try {
new URL(url);
return true;
} catch (_) {
return false;
}
}
function setUrl() {
//Demander à l'utilisateur de choisir une URL
let userInput = prompt("Veuillez saisir l'URL a appeler lors de la découverte d'un nouveau produit dans les recommandations", callUrl);
if (userInput === null) {
return;
}
//Validation de l'URL
if (userInput && isValidUrl(userInput)) {
GM_setValue("callUrl", userInput);
callUrl = userInput;
console.log("[PïckMe] URL enregistrée avec succès :", userInput);
} else {
GM_setValue("callUrl", "");
callUrl = "";
document.getElementById('callUrlEnabled').checked = false;
alert("URL invalide. Veuillez entrer une URL valide.");
console.error("URL invalide fournie. Veuillez entrer une URL valide.");
}
}
function testUrl() {
if (callUrl === false || callUrl === "") {
alert("Aucune URL trouvée.");
return;
}
//Validation de l'URL
if (isValidUrl(callUrl)) {
appelURL(callUrl);
} else {
alert("URL invalide. Veuillez entrer une URL valide.");
}
}
function hexToRgba(hex, alpha = 0.5) {
if (!hex || typeof hex !== 'string') {
return `rgba(255, 255, 255, ${alpha})`;
}
let normalized = hex.trim();
if (!normalized.startsWith('#')) {
normalized = `#${normalized}`;
}
if (!/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(normalized)) {
return `rgba(255, 255, 255, ${alpha})`;
}
normalized = normalized.slice(1);
if (normalized.length === 3) {
normalized = normalized.split('').map((char) => char + char).join('');
}
const r = parseInt(normalized.substr(0, 2), 16);
const g = parseInt(normalized.substr(2, 2), 16);
const b = parseInt(normalized.substr(4, 2), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
function getPreviewLinkColor() {
const selectors = [
'.vvp-item-product-title-container a.a-link-normal',
'#vvp-items .a-link-normal',
'a.a-link-normal',
'a'
];
for (const selector of selectors) {
const element = document.querySelector(selector);
if (element) {
const computedColor = window.getComputedStyle(element).color;
if (computedColor) {
return computedColor;
}
}
}
return '#0073bb';
}
function injectHighlightPreviewStyles(popupElement, baseBackground, borderColor, textColor) {
const styleElement = document.createElement('style');
styleElement.textContent = `
#colorPickerPopup .pm-preview-card {
position: relative;
border-radius: 8px;
border: 1px solid ${borderColor};
background-color: ${baseBackground};
padding: 12px;
text-align: center;
color: ${textColor};
overflow: hidden;
}
#colorPickerPopup .pm-preview-card + .pm-preview-card {
margin-top: 10px;
}
#colorPickerPopup .pm-preview-overlay {
position: absolute;
inset: 0;
border-radius: inherit;
pointer-events: none;
}
#colorPickerPopup .pm-preview-text {
position: relative;
z-index: 1;
}
`;
popupElement.appendChild(styleElement);
}
function setHighlightColor() {
//Pour la suite, on convertit la couleur RGBA existante en format hexadécimal pour .
//Fonction helper pour extraire #rrggbb depuis un rgba(...) ou rgb(...).
function rgbaToHex(rgbaString, defaultHex = '#FFFF00') {
const rgbaMatch = rgbaString.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d*\.?\d+))?\)$/);
if (!rgbaMatch) {
return defaultHex; //Couleur par défaut (ici : jaune) si la conversion échoue
}
const r = parseInt(rgbaMatch[1], 10).toString(16).padStart(2, '0');
const g = parseInt(rgbaMatch[2], 10).toString(16).padStart(2, '0');
const b = parseInt(rgbaMatch[3], 10).toString(16).padStart(2, '0');
return `#${r}${g}${b}`;
}
//Couleurs par défaut (au cas où highlightColor / highlightColorRepop seraient vides)
const defaultHexNew = '#FFFF00';
const defaultHexRepop = '#FF9600';
//Convertit la couleur RGBA existante en hexa
const hexColor = rgbaToHex(highlightColor, defaultHexNew);
const hexColorRepop = rgbaToHex(highlightColorRepop, defaultHexRepop);
//Vérifie si une popup existe déjà et la supprime
const existingPopup = document.getElementById('colorPickerPopup');
if (existingPopup) {
existingPopup.remove();
}
//Crée la fenêtre popup
const popup = document.createElement('div');
popup.id = "colorPickerPopup";
popup.style.cssText = `
position: fixed;
z-index: 10002;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: white;
border: 1px solid #ccc;
box-shadow: 0px 0px 10px #ccc;
width: 300px;
`;
//Construction du HTML de la popup, avec deux sélecteurs de couleur
popup.innerHTML = `
Couleurs de surbrillance
×
Produit de test
Produit de test
`;
document.body.appendChild(popup);
const isDarkTheme = savedTheme === "dark";
const basePreviewBackground = isDarkTheme ? '#191919' : '#ffffff';
const basePreviewBorder = isDarkTheme ? '#2a2a2a' : '#d5d9d9';
const previewLinkColor = getPreviewLinkColor();
injectHighlightPreviewStyles(popup, basePreviewBackground, basePreviewBorder, previewLinkColor);
const updatePreviewOverlay = (type, colorValue) => {
const overlay = popup.querySelector(`.pm-preview-card[data-type="${type}"] .pm-preview-overlay`);
if (overlay) {
overlay.style.backgroundColor = colorValue;
}
};
updatePreviewOverlay('new', highlightColor || hexToRgba(hexColor));
updatePreviewOverlay('repop', highlightColorRepop || hexToRgba(hexColorRepop));
document.getElementById('colorPickerNew').addEventListener('input', function(e) {
updatePreviewOverlay('new', hexToRgba(e.target.value));
});
document.getElementById('colorPickerRepop').addEventListener('input', function(e) {
updatePreviewOverlay('repop', hexToRgba(e.target.value));
});
document.getElementById('saveColor').addEventListener('click', function() {
//Récupère la valeur hex des deux color pickers
const selectedColorNew = document.getElementById('colorPickerNew').value;
const selectedColorRepop = document.getElementById('colorPickerRepop').value;
const rgbaColorNew = hexToRgba(selectedColorNew);
const rgbaColorRepop = hexToRgba(selectedColorRepop);
GM_setValue("highlightColor", rgbaColorNew);
GM_setValue("highlightColorRepop", rgbaColorRepop);
highlightColor = rgbaColorNew;
highlightColorRepop = rgbaColorRepop;
popup.remove();
});
document.getElementById('closeColor').addEventListener('click', function() {
popup.remove();
});
document.getElementById('closeColorPicker').addEventListener('click', function() {
popup.remove();
});
}
function setHighlightColorFav() {
//Extraire les composantes r, g, b de la couleur actuelle
const rgbaMatch = highlightColorFav.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+),\s*(\d*\.?\d+)\)$/);
let hexColor = "#FF0000"; //Fallback couleur jaune si la conversion échoue
if (rgbaMatch) {
const r = parseInt(rgbaMatch[1]).toString(16).padStart(2, '0');
const g = parseInt(rgbaMatch[2]).toString(16).padStart(2, '0');
const b = parseInt(rgbaMatch[3]).toString(16).padStart(2, '0');
hexColor = `#${r}${g}${b}`;
}
//Vérifie si une popup existe déjà et la supprime si c'est le cas
const existingPopup = document.getElementById('colorPickerPopup');
if (existingPopup) {
existingPopup.remove();
}
//Crée la fenêtre popup
const popup = document.createElement('div');
popup.id = "colorPickerPopup";
popup.style.cssText = `
position: fixed;
z-index: 10002;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: white;
border: 1px solid #ccc;
box-shadow: 0px 0px 10px #ccc;
`;
popup.innerHTML = `
Couleur de surbrillance des produits filtrés×
Produit de test
`;
document.body.appendChild(popup);
const isDarkTheme = savedTheme === "dark";
const basePreviewBackground = isDarkTheme ? '#191919' : '#ffffff';
const basePreviewBorder = isDarkTheme ? '#2a2a2a' : '#d5d9d9';
const previewLinkColor = getPreviewLinkColor();
injectHighlightPreviewStyles(popup, basePreviewBackground, basePreviewBorder, previewLinkColor);
const overlay = popup.querySelector('.pm-preview-card[data-type="fav"] .pm-preview-overlay');
if (overlay) {
overlay.style.backgroundColor = highlightColorFav || hexToRgba(hexColor);
}
const colorPickerElement = document.getElementById('colorPicker');
colorPickerElement.addEventListener('input', function(event) {
if (overlay) {
overlay.style.backgroundColor = hexToRgba(event.target.value);
}
});
//Ajoute des écouteurs d'événement pour les boutons
document.getElementById('saveColor').addEventListener('click', function() {
const selectedColor = document.getElementById('colorPicker').value;
//Convertir la couleur hexadécimale en RGBA pour la transparence
const rgbaColor = hexToRgba(selectedColor);
//Stocker la couleur sélectionnée
GM_setValue("highlightColorFav", rgbaColor);
highlightColorFav = rgbaColor;
popup.remove();
});
document.getElementById('closeColor').addEventListener('click', function() {
popup.remove();
});
document.getElementById('closeColorPicker').addEventListener('click', function() {
popup.remove();
});
}
function getStoredProducts() {
try {
let raw = GM_getValue("storedProducts");
// Vérifications supplémentaires avant le JSON.parse
if (!raw || raw === "undefined" || typeof raw !== "string") {
raw = '{}'; // Valeur de secours
}
return JSON.parse(raw);
} catch (error) {
console.error("Erreur lors de la récupération de storedProducts :", error);
return {};
}
}
function saveStoredProducts(products) {
GM_setValue("storedProducts", JSON.stringify(products));
}
var storedProducts = getStoredProducts();
function shouldRunPurge() {
const lastRun = GM_getValue("lastPurgeTimestamp", 0);
const now = Date.now();
const oneDay = 24 * 60 * 60 * 1000;
//Si plus de 24h sont passées depuis la dernière exécution
return (now - lastRun) > oneDay;
}
function runDailyPurge() {
if (shouldRunPurge()) {
purgeStoredProducts();
GM_setValue("lastPurgeTimestamp", Date.now());
console.log("[PïckMe] Purge exécutée.");
}
}
//On purge les anciens produits une fois par jour pour optimiser le chargement des pages
const ITEM_EXPIRY = 7776000000; //90 jours en ms
runDailyPurge();
//purgeStoredProducts();
//Définir des valeurs par défaut
const defaultKeys = {
left: 'q',
right: 'd',
up: 'z',
down: 's',
hide: 'h',
show: 'j',
sync: '',
previousPage: 'a',
homePage: '&',
nextPage: 'e'
};
//Fonction pour récupérer la configuration des touches
function getKeyConfig() {
return {
left: GM_getValue('keyLeft', defaultKeys.left),
right: GM_getValue('keyRight', defaultKeys.right),
up: GM_getValue('keyUp', defaultKeys.up),
down: GM_getValue('keyDown', defaultKeys.down),
hide: GM_getValue('keyHide', defaultKeys.hide),
show: GM_getValue('keyShow', defaultKeys.show),
sync: GM_getValue('keySync', defaultKeys.sync),
previousPage: GM_getValue('keyPrevPage', defaultKeys.previousPage),
homePage: GM_getValue('keyHomePage', defaultKeys.homePage),
nextPage: GM_getValue('keyNextPage', defaultKeys.nextPage)
};
}
//Fonction pour simuler un clic sur un bouton, identifié par son id
function simulerClicSurBouton(boutonId, essais = 1) {
var bouton = document.getElementById(boutonId);
if (bouton) {
bouton.click();
} else {
if (essais < 5) {
setTimeout(function() {
simulerClicSurBouton(boutonId, essais + 1);
}, 100);
}
}
}
function adjustAlpha(rgbaString, alphaDelta) {
//On utilise une RegExp simple pour extraire R, G, B et A
const match = rgbaString.match(/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)$/);
if (!match) {
//Si le format ne correspond pas, on renvoie la couleur telle quelle
return rgbaString;
}
let [ , r, g, b, a ] = match;
r = parseInt(r, 10);
g = parseInt(g, 10);
b = parseInt(b, 10);
a = parseFloat(a);
//On modifie l’alpha en lui ajoutant (ou soustrayant) alphaDelta
a = a + alphaDelta;
//On s’assure de rester dans [0, 1]
a = Math.max(0, Math.min(1, a));
return `rgba(${r}, ${g}, ${b}, ${a})`;
}
//Écouteur d'événements pour la navigation des pages
document.addEventListener('keydown', function(e) {
const activeElement = document.activeElement; //Obtient l'élément actuellement en focus
const searchBox = document.getElementById('twotabsearchtextbox'); //L'élément du champ de recherche d'Amazon
const searchBoxVine = document.getElementById('vvp-search-text-input'); //Recherche vine
const searchBoxBackup = document.getElementById('nav-bb-search'); //Recherche header Amazon (nouvelle interface desktop)
const searchBoxMobileBackup = document.getElementById('nav-mobile-bb-search'); //Recherche header Amazon (nouvelle interface mobile)
//Vérifie si l'élément en focus est le champ de recherche
if (activeElement === searchBox || activeElement === searchBoxVine || activeElement === searchBoxBackup || activeElement === searchBoxMobileBackup) {
return; //Ignore le reste du code si le champ de recherche est en focus
}
const existingPopupNote = document.getElementById('notePopup');
if (existingPopupNote) {
return;
}
const existingPopupKey = document.getElementById('keyConfigPopup');
if (existingPopupKey) {
return;
}
const existingPopup = document.getElementById('configPopup');
if (existingPopup) {
return;
}
const keys = getKeyConfig();
if (keys.previousPage && e.key === keys.previousPage) {
simulerClicSurBouton('boutonCacherPrecedentHaut');
}
else if (keys.homePage && e.key === keys.homePage) {
simulerClicSurBouton('boutonRetourAccueilHaut');
}
else if (keys.nextPage && e.key === keys.nextPage) {
simulerClicSurBouton('boutonCacherSuivantHaut');
}
else if (e.key === keys.left) {
naviguerPage(-1);
}
else if (e.key === keys.right) {
naviguerPage(1);
}
else if (e.key === keys.up) {
naviguerQueue(1);
}
else if (e.key === keys.down) {
naviguerQueue(-1);
}
else if (e.key === keys.hide) {
const boutonProduits = document.querySelector('.bouton-filtre.active');
const infoOnglet = boutonProduits.textContent == produitsCaches;
simulerClicSurBouton('boutonCacherToutHaut');
if (boutonProduits && infoOnglet) {
const boutonCachesHaut = document.getElementById('boutonCachesHaut');
simulerClicSurBouton('boutonCachesHaut');
}
}
else if (e.key === keys.show) {
const boutonProduits = document.querySelector('.bouton-filtre.active');
const infoOnglet = boutonProduits.textContent == produitsVisibles;
simulerClicSurBouton('boutonToutAfficherHaut');
if (boutonProduits && infoOnglet) {
const boutonVisiblesHaut = document.getElementById('boutonVisiblesHaut');
simulerClicSurBouton('boutonVisiblesHaut');
}
}
else if (e.key === keys.sync) {
syncProducts(false, true, true);
}
});
function naviguerQueue(direction) {
const links = document.querySelectorAll('#vvp-items-button-container a');
const queues = Array.from(links).map(link => {
const url = new URL(link.href, window.location.origin);
return url.searchParams.get('queue');
});
const url = new URL(window.location);
const params = url.searchParams;
let currentQueue = params.get('queue') || 'potluck';
let currentIndex = queues.indexOf(currentQueue);
if (direction === 1 && currentIndex < queues.length - 1) {
//Avancer dans la queue
params.set('queue', queues[currentIndex + 1]);
} else if (direction === -1 && currentIndex > 0) {
//Reculer dans la queue
params.set('queue', queues[currentIndex - 1]);
}
url.search = params.toString();
window.location.href = url.toString();
}
function naviguerPage(direction) {
//Extraire le numéro de page actuel de l'URL
const url = new URL(window.location);
const params = url.searchParams;
let page = parseInt(params.get('page') || '1', 10);
//Calculer la nouvelle page
page += direction;
//S'assurer que la page est au minimum à 1
if (page < 1) page = 1;
//Mettre à jour le paramètre de page dans l'URL
params.set('page', page);
url.search = params.toString();
//Naviguer vers la nouvelle page
window.location.href = url.toString();
}
//Fonction pour calculer et formater le temps écoulé
function formaterTempsEcoule(date) {
const maintenant = new Date();
const tempsEcoule = maintenant - new Date(date);
const secondes = tempsEcoule / 1000;
const minutes = secondes / 60;
const heures = minutes / 60;
const jours = heures / 24;
//Si moins d'une minute s'est écoulée
if (secondes < 60) {
const secs = Math.min(59, Math.round(secondes));
return secs + 's';
}
//Si moins d'une heure s'est écoulée
else if (minutes < 60) {
const mins = Math.min(59, Math.round(minutes));
return mins + 'm';
}
//Si moins d'un jour s'est écoulé
else if (heures < 24) {
//Convertir les décimales des heures en minutes arrondies
const heuresArrondies = Math.min(23, Math.floor(heures));
let minutesRestantes = Math.round((heures - heuresArrondies) * 60);
if (minutesRestantes === 60) {
minutesRestantes = 59;
}
return heuresArrondies + 'h ' + minutesRestantes + 'm';
}
//Si un ou plusieurs jours se sont écoulés
else {
//Convertir les décimales des jours en heures arrondies
const joursArrondis = Math.floor(jours);
const heuresRestantes = Math.round((jours - joursArrondis) * 24);
return joursArrondis + 'j ' + heuresRestantes + 'h';
}
}
//Fonction pour ajouter l'étiquette de temps à chaque produit
function ajouterEtiquetteTemps() {
const produits = document.querySelectorAll('.vvp-item-tile');
produits.forEach(produit => {
const asin = getProductAsin(produit);
const storedProducts = getStoredProducts();
if (storedProducts.hasOwnProperty(asin)) {
const dateAjout = storedProducts[asin].dateAdded;
const texteTempsEcoule = formaterTempsEcoule(dateAjout);
//Sélectionner l'image dans le conteneur général
const image = produit.querySelector('.vvp-item-tile-content img');
//Créer un wrapper pour l'image
const wrapper = document.createElement('div');
wrapper.style.position = 'relative';
wrapper.style.display = 'inline-block';
//Insérer le wrapper à la place de l'image, puis y déplacer l'image
image.parentNode.insertBefore(wrapper, image);
wrapper.appendChild(image);
//Créer l'étiquette de temps
const etiquetteTemps = document.createElement('div');
etiquetteTemps.style.position = 'absolute';
if (mobileEnabled || cssEnabled) {
etiquetteTemps.style.top = timeVerticalMobile;
etiquetteTemps.style.left = timeHorizontalMobile;
if (isMobile()) {
etiquetteTemps.style.padding = '2px 3px';
} else {
etiquetteTemps.style.padding = '0px 1px';
}
etiquetteTemps.style.lineHeight = '1.2';
} else {
etiquetteTemps.style.top = timeVertical;
etiquetteTemps.style.left = timeHorizontal;
etiquetteTemps.style.padding = '1px 2px';
}
etiquetteTemps.style.transform = 'translateX(-50%)';
etiquetteTemps.style.backgroundColor = 'rgba(255,255,255,0.7)';
etiquetteTemps.style.color = 'black';
etiquetteTemps.style.borderRadius = '5px';
etiquetteTemps.style.zIndex = '5';
if (cssEnabled || mobileEnabled) {
etiquetteTemps.style.fontSize = timeFontMobile;
} else {
etiquetteTemps.style.fontSize = timeFont;
}
etiquetteTemps.style.whiteSpace = 'nowrap';
etiquetteTemps.textContent = texteTempsEcoule;
//Ajouter l'étiquette dans le wrapper de l'image
wrapper.appendChild(etiquetteTemps);
}
});
}
//Affichage d'une image agrandie lors du clic sur un produit
function openImageOverlay(imgSrc) {
const largeSrc = imgSrc.replace(/_SS\d+_/, '_SS500_');
const overlay = document.createElement('div');
overlay.id = 'pm-image-overlay';
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0,0,0,0.8)';
overlay.style.display = 'flex';
overlay.style.alignItems = 'center';
overlay.style.justifyContent = 'center';
overlay.style.zIndex = '10000';
const img = document.createElement('img');
img.src = largeSrc;
img.style.maxWidth = '90%';
img.style.maxHeight = '90%';
const closeBtn = document.createElement('span');
closeBtn.textContent = '✕';
closeBtn.style.position = 'absolute';
closeBtn.style.top = '20px';
closeBtn.style.right = '30px';
closeBtn.style.fontSize = '30px';
closeBtn.style.color = '#fff';
closeBtn.style.cursor = 'pointer';
closeBtn.addEventListener('click', () => overlay.remove());
overlay.appendChild(img);
overlay.appendChild(closeBtn);
overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.remove(); });
document.body.appendChild(overlay);
}
//Rendre les images des produits cliquables pour les afficher en plus grand
function rendreImagesCliquables() {
if (zoomEnabled) {
const selectors = [
'.vvp-item-tile-content img:first-child', //AI, AFA, RFY
'.vvp-orders-table--image-col img:first-child', //Commandes
'.vvp-reviews-table--image-col img:first-child', //Avis
'#favorisContainer .vvp-orders-table--image-col img:first-child' //Favoris
];
selectors.forEach(sel => {
document.querySelectorAll(sel).forEach(img => {
if (img.dataset.pmClickable) return; //Évite de lier plusieurs fois
img.style.cursor = 'zoom-in';
img.addEventListener('click', () => openImageOverlay(img.src));
img.dataset.pmClickable = 'true';
});
});
}
}
//Observer les changements du DOM pour rendre cliquables les nouvelles images
document.addEventListener('DOMContentLoaded', () => {
rendreImagesCliquables();
const observer = new MutationObserver(rendreImagesCliquables);
observer.observe(document.body, { childList: true, subtree: true });
});
//Variable pour savoir s'il y a eu un nouvel objet
var imgNew = false;
let shouldActivateRefreshBoost = false;
if ((autohideEnabled || extendedEnabled) && apiOk) {
function tryAutoHideAndExtend() {
if (autohideEnabled) {
var favWordsTrim = favWords.trim();
var hideWordsTrim = hideWords.trim();
//Conversion en regex
var favArray = favWordsTrim.length > 0
? favWordsTrim.split(',').map(pattern => {
pattern = pattern.trim();
if (pattern.length > 0) {
try {
return new RegExp(pattern, 'i');
} catch (e) {
console.error('Expression regex invalide :', pattern, e);
return null;
}
} else {
return null;
}
}).filter(regex => regex != null)
: [];
var hideArray = hideWordsTrim.length > 0
? hideWordsTrim.split(',').map(pattern => {
pattern = pattern.trim();
if (pattern.length > 0) {
try {
return new RegExp(pattern, 'i');
} catch (e) {
console.error('Expression regex invalide :', pattern, e);
return null;
}
} else {
return null;
}
}).filter(regex => regex != null)
: [];
}
const itemTiles = document.querySelectorAll('.vvp-item-tile');
if (itemTiles.length > 0) {
itemTiles.forEach(function(tile) {
const fullTextElement = tile.querySelector('.a-truncate-full.a-offscreen');
const cutTextElement = tile.querySelector('.a-truncate-cut');
const truncateTextElement = tile.querySelector('.a-truncate');
const parentDiv = tile.closest('.vvp-item-tile');
if (!fullTextElement) return; //On vérifie que l'élément contenant le texte existe
const textContent = fullTextElement.textContent.trim().replace(/\s+/g, ' ');
//Fonction qui surligne le mot correspondant dans le texte
function highlightMatch(regexArray, highlightStyle) {
for (let regex of regexArray) {
const match = textContent.match(regex);
if (match) {
//Remplace toutes les occurrences (insensible à la casse) par le même match enveloppé dans un span
const highlightedHTML = fullTextElement.textContent.replace(new RegExp(regex.source, 'gi'), `$&`);
cutTextElement.innerHTML = highlightedHTML;
fullTextElement.innerHTML = highlightedHTML;
break;
}
}
}
if (extendedEnabled) {
if (fullTextElement && cutTextElement && fullTextElement.textContent) {
if (!cssEnabled) {
cutTextElement.textContent = fullTextElement.textContent;
fullTextElement.innerHTML = fullTextElement.textContent;
//Appliquez les styles directement pour surmonter les restrictions CSS
cutTextElement.style.cssText = 'height: auto !important; max-height: none !important; overflow: visible !important; white-space: normal !important;';
} else {
document.addEventListener('mouseover', function(event) {
const target = event.target.closest('.vvp-item-product-title-container');
if (target) {
const fullTextElement = target.querySelector('.a-truncate-full.a-offscreen');
if (fullTextElement) {
const fullText = fullTextElement.textContent;
const popup = document.createElement('div');
popup.textContent = fullText;
popup.style.position = 'fixed';
popup.style.maxWidth = '300px';
popup.style.wordWrap = 'break-word';
if (savedTheme == "dark") {
popup.style.backgroundColor = '#fff';
popup.style.color = 'rgba(0, 0, 0, 0.8)';
} else {
popup.style.backgroundColor = 'rgb(25, 25, 25)';
popup.style.color = '#fff';
}
popup.style.padding = '5px 10px';
popup.style.borderRadius = '5px';
popup.style.zIndex = '1000';
popup.style.pointerEvents = 'none';
document.body.appendChild(popup);
const movePopup = (e) => {
popup.style.top = `${e.clientY + 10}px`;
popup.style.left = `${e.clientX + 10}px`;
};
movePopup(event);
document.addEventListener('mousemove', movePopup);
const removePopup = () => {
popup.remove();
document.removeEventListener('mousemove', movePopup);
target.removeEventListener('mouseleave', removePopup);
};
target.addEventListener('mouseleave', removePopup);
}
}
});
}
}
if (!cssEnabled) {
if (fullTitleLine != '4') {
let maxHeightMult = 1.4;
let heightMult = 17.5;
if (mobileEnabled) {
maxHeightMult = 1.35;
heightMult = 14.5;
}
const fullTitleLineInt = parseInt(fullTitleLine, 10);
const maxHeight = fullTitleLineInt * maxHeightMult;
const height = fullTitleLineInt * heightMult;
document.querySelectorAll('.vvp-item-tile .a-truncate').forEach(function(element) {
element.style.cssText = `max-height: ${maxHeight}em !important;`;
});
document.querySelectorAll('#vvp-items-grid .vvp-item-tile .vvp-item-tile-content > .vvp-item-product-title-container').forEach(function(element) {
element.style.height = `${height}px`;
});
} else {
if (mobileEnabled) {
document.querySelectorAll('.vvp-item-tile .a-truncate').forEach(function(element) {
element.style.cssText = 'max-height: 5em !important;';
});
} else {
document.querySelectorAll('.vvp-item-tile .a-truncate').forEach(function(element) {
element.style.cssText = 'max-height: 5.6em !important;';
});
}
}
}
}
if (autohideEnabled) {
//Vérification favoris
if (favArray.length > 0 && favArray.some(regex => regex.test(textContent))) {
parentDiv.style.backgroundColor = highlightColorFav;
parentDiv.parentNode.prepend(parentDiv);
parentDiv.classList.add('putproduct');
if (hlFav) {
highlightMatch(favArray, `background-color: ${colorHlFav};`);
}
}
//Vérification pour cacher
else if (hideArray.length > 0 && hideArray.some(regex => regex.test(textContent))) {
const asin = parentDiv.getAttribute('data-asin') || parentDiv.querySelector('.'+getStringDetailsBtnSelector()+' input').getAttribute('data-asin');
const enrollment = getEnrollment(parentDiv);
const hideKey = getAsinEnrollment(asin, enrollment);
const etatCacheKey = hideKey + '_c';
localStorage.setItem(etatCacheKey, '1');
parentDiv.style.display = 'none';
if (hlHide) {
highlightMatch(hideArray, `background-color: ${colorHlHide};`);
}
}
}
});
if (hideEnabled && autohideEnabled) {
ajouterIconeEtFonctionCacher();
}
rendreImagesCliquables();
}
//On signifie que le script a fini son action la plus "longue" pour les actions de fin
allFinish = true;
}
//On instancie le MutationObserver et on définit la fonction de callback
const observer = new MutationObserver(mutations => {
//À chaque mutation, on vérifie s’il y a au moins un .vvp-item-tile
const itemTiles = document.querySelectorAll('.vvp-item-tile');
if (itemTiles.length > 0) {
setTimeout(tryAutoHideAndExtend, extendedDelay);
//Si on veut n’exécuter cette logique qu’une fois, on peut stopper l’observation :
observer.disconnect();
}
});
//On lance l’observation sur le document entier ou sur un conteneur spécifique
observer.observe(document.body, {
childList: true,
subtree: true
});
}
//Fonction pour parcourir et convertir les favoris de PickMe Web en localstorage
function convertGMFav() {
//Récupérer toutes les clés stockées avec GM_setValue
let keys = GM_listValues();
keys.forEach(key => {
//Vérifier si la clé se termine par "_f"
if (key.endsWith('_f')) {
//Récupérer la valeur correspondante
let value = GM_getValue(key);
//Stocker la valeur dans le localStorage
localStorage.setItem(key, value);
//Supprimer la valeur de GM
GM_deleteValue(key);
}
});
}
function ensureHideButtonStyles() {
if (document.querySelector('style[data-pm-hide-buttons]')) {
return;
}
const style = document.createElement('style');
style.dataset.pmHideButtons = '1';
style.textContent = `
.bouton-reset {
background-color: #f7ca00;
color: black;
font-weight: bold;
text-decoration: none;
display: inline-block;
border: 1px solid #dcdcdc;
border-radius: 20px;
padding: 3px 10px;
margin-left: 5px;
cursor: pointer;
outline: none;
}
`;
style.textContent += `
.bouton-action {
background-color: #f7ca00;
color: black;
font-weight: bold;
text-decoration: none;
display: inline-block;
border: 1px solid #dcdcdc;
border-radius: 20px;
padding: 5px 15px;
margin-right: 5px;
cursor: pointer;
outline: none;
}
.bouton-action:disabled,
.bouton-action[aria-disabled="true"] {
background-color: #dcdcdc;
color: #888 !important;
border-color: #c0c0c0;
cursor: not-allowed;
}
.navigation-buttons {
display: inline-flex;
gap: 5px;
margin-left: 5px;
flex-wrap: wrap;
align-items: center;
}
.navigation-buttons-mobile {
display: flex;
margin-left: 0;
margin-top: 5px;
gap: 5px;
width: 100%;
}
`;
document.head.appendChild(style);
}
function ajouterIconeEtFonctionCacher() {
convertGMFav();
const produits = document.querySelectorAll('.vvp-item-tile');
const resultats = document.querySelector('#vvp-items-grid-container > p');
const vineGrid = document.querySelector('#vvp-items-grid');
const urlParams = new URLSearchParams(window.location.search);
let infoQueue = urlParams.get('queue');
const hideNavigationActive = hidePageNavigateEnabled && (infoQueue === 'encore' || infoQueue === 'all_items');
const isMobileLayout = isMobile();
function normaliserTexte(texte) {
return (texte || '')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.replace(/\s+/g, ' ')
.trim()
.toLowerCase();
}
function trouverLienPagination(type) {
const recherche = type === 'next' ? 'suivant' : 'precedent';
const selecteurs = [
'.a-pagination a[href*="/vine/vine-items"]',
'.a-pagination li a[href*="/vine/vine-items"]',
'li a[href*="/vine/vine-items"]',
'a[href*="/vine/vine-items"]'
];
for (const selecteur of selecteurs) {
const liens = Array.from(document.querySelectorAll(selecteur));
const lien = liens.find(element => normaliserTexte(element.textContent).includes(recherche));
if (lien) {
return lien;
}
}
return null;
}
function recupererLiensPagination() {
return {
precedent: trouverLienPagination('previous'),
suivant: trouverLienPagination('next')
};
}
//Ajout du style pour les boutons
ensureHideButtonStyles();
//Icone pour cacher/montrer
const urlIcone = hideUrlOff;
const urlIconeOeil = hideUrlOn;
//Création des boutons avec le nouveau style
function creerBoutons(position) {
//Bouton pour les produits visibles
const boutonVisibles = document.createElement('button');
boutonVisibles.textContent = produitsVisibles;
boutonVisibles.classList.add('bouton-filtre', 'active');
boutonVisibles.id = `boutonVisibles${position}`;
//Bouton pour les produits cachés
const boutonCaches = document.createElement('button');
boutonCaches.textContent = produitsCaches;
boutonCaches.classList.add('bouton-filtre');
boutonCaches.id = `boutonCaches${position}`;
//Bouton pour cacher tout
const boutonCacherTout = document.createElement('button');
boutonCacherTout.textContent = toutCacher;
boutonCacherTout.classList.add('bouton-action');
boutonCacherTout.id = `boutonCacherTout${position}`;
//Bouton pour tout afficher
const boutonToutAfficher = document.createElement('button');
boutonToutAfficher.textContent = toutAfficher;
boutonToutAfficher.classList.add('bouton-action');
boutonToutAfficher.id = `boutonToutAfficher${position}`;
let boutonCacherPrecedent = null;
let boutonRetourAccueil = null;
let boutonCacherSuivant = null;
let navigationWrapper = null;
if (hideNavigationActive) {
navigationWrapper = document.createElement(isMobileLayout ? 'div' : 'span');
navigationWrapper.classList.add('navigation-buttons');
if (isMobileLayout) {
navigationWrapper.classList.add('navigation-buttons-mobile');
}
if (hidePagePreviousEnabled) {
boutonCacherPrecedent = document.createElement('button');
boutonCacherPrecedent.textContent = '⏮';
boutonCacherPrecedent.classList.add('bouton-action');
boutonCacherPrecedent.id = `boutonCacherPrecedent${position}`;
boutonCacherPrecedent.title = 'Tout cacher puis revenir à la page précédente';
boutonCacherPrecedent.setAttribute('aria-label', 'Tout cacher puis revenir à la page précédente');
navigationWrapper.appendChild(boutonCacherPrecedent);
}
boutonRetourAccueil = document.createElement('button');
boutonRetourAccueil.textContent = '↩';
boutonRetourAccueil.classList.add('bouton-action');
boutonRetourAccueil.id = `boutonRetourAccueil${position}`;
boutonRetourAccueil.title = 'Tout cacher puis revenir à la première page';
boutonRetourAccueil.setAttribute('aria-label', 'Tout cacher puis revenir à la première page');
navigationWrapper.appendChild(boutonRetourAccueil);
boutonCacherSuivant = document.createElement('button');
boutonCacherSuivant.textContent = '⏭';
boutonCacherSuivant.classList.add('bouton-action');
boutonCacherSuivant.id = `boutonCacherSuivant${position}`;
boutonCacherSuivant.title = 'Tout cacher puis passer à la page suivante';
boutonCacherSuivant.setAttribute('aria-label', 'Tout cacher puis passer à la page suivante');
navigationWrapper.appendChild(boutonCacherSuivant);
if (!navigationWrapper.childElementCount) {
navigationWrapper = null;
}
}
return { boutonVisibles, boutonCaches, boutonCacherTout, boutonToutAfficher, boutonCacherPrecedent, boutonRetourAccueil, boutonCacherSuivant, navigationWrapper };
}
//Fonction pour synchroniser les boutons haut et bas
function synchroniserBoutons(boutonsHaut, boutonsBas, hideBas) {
//Synchronisation du bouton "Produits visibles"
boutonsHaut.boutonVisibles.addEventListener('click', () => {
afficherProduits(true);
boutonsHaut.boutonVisibles.classList.add('active');
boutonsHaut.boutonCaches.classList.remove('active');
if (hideBas) {
boutonsBas.boutonVisibles.classList.add('active');
boutonsBas.boutonCaches.classList.remove('active');
}
});
if (hideBas) {
boutonsBas.boutonVisibles.addEventListener('click', () => {
afficherProduits(true);
boutonsHaut.boutonVisibles.classList.add('active');
boutonsHaut.boutonCaches.classList.remove('active');
});
}
//Synchronisation du bouton "Produits cachés"
boutonsHaut.boutonCaches.addEventListener('click', () => {
afficherProduits(false);
boutonsHaut.boutonVisibles.classList.remove('active');
boutonsHaut.boutonCaches.classList.add('active');
if (hideBas) {
boutonsBas.boutonVisibles.classList.remove('active');
boutonsBas.boutonCaches.classList.add('active');
}
});
if (hideBas) {
boutonsBas.boutonCaches.addEventListener('click', () => {
afficherProduits(false);
boutonsHaut.boutonVisibles.classList.remove('active');
boutonsHaut.boutonCaches.classList.add('active');
});
}
//Synchronisation des boutons "Tout cacher" et "Tout afficher"
boutonsHaut.boutonCacherTout.addEventListener('click', () => {
toggleTousLesProduits(true);
boutonsHaut.boutonCacherTout.style.display = '';
boutonsHaut.boutonToutAfficher.style.display = 'none';
if (hideBas) {
boutonsBas.boutonCacherTout.style.display = '';
boutonsBas.boutonToutAfficher.style.display = 'none';
}
});
if (hideBas) {
boutonsBas.boutonCacherTout.addEventListener('click', () => {
toggleTousLesProduits(true);
boutonsHaut.boutonCacherTout.style.display = '';
boutonsHaut.boutonToutAfficher.style.display = 'none';
});
}
boutonsHaut.boutonToutAfficher.addEventListener('click', () => {
toggleTousLesProduits(false);
boutonsHaut.boutonCacherTout.style.display = 'none';
boutonsHaut.boutonToutAfficher.style.display = '';
if (hideBas) {
boutonsBas.boutonCacherTout.style.display = 'none';
boutonsBas.boutonToutAfficher.style.display = '';
}
});
if (hideBas) {
boutonsBas.boutonToutAfficher.addEventListener('click', () => {
toggleTousLesProduits(false);
boutonsHaut.boutonCacherTout.style.display = 'none';
boutonsHaut.boutonToutAfficher.style.display = '';
});
}
}
//Création et insertion des boutons en haut et en bas
const boutonsHaut = creerBoutons('Haut');
const divBoutonsHaut = document.createElement('div');
divBoutonsHaut.id = "divCacherHaut";
divBoutonsHaut.style.marginTop = '5px'; //Réduit l'espace au-dessus des boutons
divBoutonsHaut.style.marginBottom = '15px'; //Augmente l'espace en dessous des boutons
divBoutonsHaut.appendChild(boutonsHaut.boutonVisibles);
divBoutonsHaut.appendChild(boutonsHaut.boutonCaches);
divBoutonsHaut.appendChild(boutonsHaut.boutonCacherTout);
divBoutonsHaut.appendChild(boutonsHaut.boutonToutAfficher);
if (boutonsHaut.navigationWrapper) {
divBoutonsHaut.appendChild(boutonsHaut.navigationWrapper);
}
if (resultats) {
resultats.after(divBoutonsHaut);
} else if (vineGrid) {
vineGrid.before(divBoutonsHaut);
}
const boutonsBas = creerBoutons('Bas');
const divBoutonsBas = document.createElement('div');
if (cssEnabled) {
divBoutonsBas.style.marginTop = '15px';
} else {
divBoutonsBas.style.marginTop = '5px'; //Réduit l'espace au-dessus des boutons
}
divBoutonsBas.style.marginBottom = '15px'; //Augmente l'espace en dessous des boutons
divBoutonsBas.appendChild(boutonsBas.boutonVisibles);
divBoutonsBas.appendChild(boutonsBas.boutonCaches);
divBoutonsBas.appendChild(boutonsBas.boutonCacherTout);
divBoutonsBas.appendChild(boutonsBas.boutonToutAfficher);
if (boutonsBas.navigationWrapper) {
divBoutonsBas.appendChild(boutonsBas.navigationWrapper);
}
if (vineGrid && hideBas) {
vineGrid.after(divBoutonsBas);
}
//Synchronisation des boutons haut et bas
synchroniserBoutons(boutonsHaut, boutonsBas, hideBas);
if (hideNavigationActive) {
const liensPagination = recupererLiensPagination();
const urlPremierePage = (() => {
const urlActuelle = new URL(window.location.href);
const pageParam = urlActuelle.searchParams.get('page');
if (!pageParam || pageParam === '1') {
if (urlActuelle.searchParams.has('page')) {
urlActuelle.searchParams.delete('page');
const nouvelleUrl = urlActuelle.toString();
return nouvelleUrl !== window.location.href ? nouvelleUrl : null;
}
return null;
}
urlActuelle.searchParams.delete('page');
return urlActuelle.toString();
})();
const appliquerEtatApresCacher = () => {
const afficherVisiblesActuels = !boutonsHaut.boutonCaches.classList.contains('active');
const afficherBoutonCacher = lockProductTab ? afficherVisiblesActuels : true;
const afficherBoutonToutAfficher = lockProductTab ? !afficherVisiblesActuels : false;
boutonsHaut.boutonCacherTout.style.display = afficherBoutonCacher ? '' : 'none';
boutonsHaut.boutonToutAfficher.style.display = afficherBoutonToutAfficher ? '' : 'none';
if (hideBas) {
boutonsBas.boutonCacherTout.style.display = afficherBoutonCacher ? '' : 'none';
boutonsBas.boutonToutAfficher.style.display = afficherBoutonToutAfficher ? '' : 'none';
}
};
const desactiverBoutonNavigation = (bouton) => {
if (!bouton) {
return;
}
bouton.disabled = true;
bouton.setAttribute('aria-disabled', 'true');
if (bouton.title && !bouton.title.includes('indisponible depuis cette page')) {
bouton.title = `${bouton.title} (indisponible depuis cette page)`;
}
};
const attacherNavigation = (bouton, lien) => {
if (!bouton) {
return;
}
if (!lien) {
desactiverBoutonNavigation(bouton);
return;
}
bouton.addEventListener('click', () => {
toggleTousLesProduits(true);
appliquerEtatApresCacher();
window.location.href = lien.href;
});
};
const attacherRetourAccueil = (bouton, urlCible) => {
if (!bouton) {
return;
}
if (!urlCible) {
desactiverBoutonNavigation(bouton);
return;
}
bouton.addEventListener('click', () => {
toggleTousLesProduits(true);
appliquerEtatApresCacher();
window.location.href = urlCible;
});
};
attacherNavigation(boutonsHaut.boutonCacherPrecedent, liensPagination.precedent);
attacherRetourAccueil(boutonsHaut.boutonRetourAccueil, urlPremierePage);
attacherNavigation(boutonsHaut.boutonCacherSuivant, liensPagination.suivant);
attacherNavigation(boutonsBas.boutonCacherPrecedent, liensPagination.precedent);
attacherRetourAccueil(boutonsBas.boutonRetourAccueil, urlPremierePage);
attacherNavigation(boutonsBas.boutonCacherSuivant, liensPagination.suivant);
}
//Fonction pour cacher ou afficher tous les produits
function toggleTousLesProduits(cacher) {
produits.forEach(produit => {
const asin = getProductAsin(produit);
const enrollment = getEnrollment(produit);
const hideKey = getAsinEnrollment(asin, enrollment);
const etatCacheKey = hideKey + '_c';
const etatFavoriKey = asin + '_f';
//Vérifie si le produit est en favori avant de changer son état de caché
const etatFavori = localStorage.getItem(etatFavoriKey) || '0';
if (etatFavori == '0') { //Ne modifie l'état de caché que si le produit n'est pas en favori
localStorage.setItem(etatCacheKey, cacher ? '1' : '0');
//Sélection de l'icône d'œil dans le produit actuel et mise à jour si l'état de caché change
const iconeOeil = produit.querySelector('img[src="' + urlIcone + '"], img[src="' + urlIconeOeil + '"]');
if (iconeOeil) {
iconeOeil.setAttribute('src', cacher ? urlIconeOeil : urlIcone);
}
}
});
//Force la mise à jour de l'affichage selon le nouveau statut de visibilité
const afficherVisiblesActuels = !boutonsHaut.boutonCaches.classList.contains('active');
const afficherVisibles = lockProductTab ? afficherVisiblesActuels : cacher;
afficherProduits(afficherVisibles);
}
//Affiche les produits en fonction du filtre : visible ou caché
function afficherProduits(afficherVisibles) {
const produitsFavoris = [];
produits.forEach(produit => {
const asin = getProductAsin(produit);
const enrollment = getEnrollment(produit);
const hideKey = getAsinEnrollment(asin, enrollment);
const etatCacheKey = hideKey + '_c';
const etatFavoriKey = asin + '_f';
//Convertir de la key ASIN à la key ASIN + enrollment, à partir de la 1.14 ou après une synchro
const etatCacheOldKey = asin + '_c';
const oldValue = localStorage.getItem(etatCacheOldKey);
if (oldValue !== null) {
localStorage.setItem(etatCacheKey, oldValue);
localStorage.removeItem(etatCacheOldKey);
}
//Fin de conversion
//Initialisation des états si non définis
let etatCache = localStorage.getItem(etatCacheKey) || '0';
let etatFavori = localStorage.getItem(etatFavoriKey) || '0';
//Enregistre les valeurs par défaut si nécessaire
if (localStorage.getItem(etatCacheKey) === null) {
localStorage.setItem(etatCacheKey, etatCache);
}
if (localStorage.getItem(etatFavoriKey) === null) {
localStorage.setItem(etatFavoriKey, etatFavori);
}
//On test s'il est favori et si on peut le cacher ou non
if (etatFavori == '1') {
//Les produits favoris sont toujours affichés dans l'onglet "Produits visibles"
//et cachés dans l'onglet "Produits cachés"
produit.style.display = afficherVisibles ? '' : 'none';
produitsFavoris.push(produit);
} else {
if ((etatCache == '0' && afficherVisibles) || (etatCache == '1' && !afficherVisibles)) {
produit.style.display = '';
} else {
produit.style.display = 'none';
}
}
});
const containerDiv = document.getElementById('vvp-items-grid'); //L'élément conteneur de tous les produits
if (containerDiv) {
produitsFavoris.reverse().forEach(element => {
containerDiv.prepend(element);
element.classList.add('favproduct');
});
}
boutonsHaut.boutonVisibles.classList.toggle('active', afficherVisibles); //Active ou désactive le bouton des produits visibles
boutonsBas.boutonVisibles.classList.toggle('active', afficherVisibles);
boutonsHaut.boutonCaches.classList.toggle('active', !afficherVisibles); //Active ou désactive le bouton des produits cachés
boutonsBas.boutonCaches.classList.toggle('active', !afficherVisibles);
if (lockProductTab) {
productTabSelection = afficherVisibles ? 'visibles' : 'caches';
GM_setValue('productTabSelection', productTabSelection);
}
//Gestion de l'affichage des boutons "Cacher tout" et "Tout afficher"
boutonsHaut.boutonCacherTout.style.display = afficherVisibles ? '' : 'none';
boutonsBas.boutonCacherTout.style.display = afficherVisibles ? '' : 'none';
boutonsHaut.boutonToutAfficher.style.display = !afficherVisibles ? '' : 'none';
boutonsBas.boutonToutAfficher.style.display = !afficherVisibles ? '' : 'none';
if (customSortingEnabled) {
sortItems(customSorting);
}
}
produits.forEach(produit => {
const image = produit.querySelector('.vvp-item-tile-content img');
const asin = getProductAsin(produit);
const enrollment = getEnrollment(produit);
const hideKey = getAsinEnrollment(asin, enrollment);
const etatCacheKey = hideKey + '_c';
const etatFavoriKey = asin + '_f';
const iconeOeil = document.createElement('img');
let wrapper = image.parentNode;
if (!wrapper.classList.contains('image-wrapper')) {
const newWrapper = document.createElement('div');
newWrapper.classList.add('image-wrapper');
newWrapper.style.position = 'relative';
newWrapper.style.display = 'inline-block';
//Insertion du nouveau wrapper à la place de l'image, puis déplacement de l'image dedans
wrapper.insertBefore(newWrapper, image);
newWrapper.appendChild(image);
wrapper = newWrapper;
}
const etatCache = localStorage.getItem(etatCacheKey) || '0';
iconeOeil.setAttribute('src', etatCache === '1' ? urlIconeOeil : urlIcone);
if (cssEnabled || mobileEnabled) {
iconeOeil.style.cssText = `
position: absolute;
top: ${hideVerticalMobile};
right: ${hideHorizontalMobile};
cursor: pointer;
width: ${hideSizeWidthMobile};
height: ${hideSizeHeightMobile};
z-index: 10;
`;
} else {
iconeOeil.style.cssText = `
position: absolute;
top: ${hideVertical};
right: ${hideHorizontal};
cursor: pointer;
width: ${hideSizeWidth};
height: ${hideSizeHeight};
z-index: 10;
`;
}
iconeOeil.addEventListener('click', () => {
const etatFavoriKey = asin + '_f';
const etatFavori = localStorage.getItem(etatFavoriKey) || '0';
//Vérifie si le produit n'est pas marqué comme favori avant de changer son état de caché
if (etatFavori === '0') {
const etatCacheActuel = localStorage.getItem(etatCacheKey);
const nouvelEtatCache = etatCacheActuel === '1' ? '0' : '1';
localStorage.setItem(etatCacheKey, nouvelEtatCache);
//Met à jour l'icône basée sur le nouvel état après le clic
iconeOeil.setAttribute('src', etatCacheActuel === '1' ? urlIcone : urlIconeOeil);
}
//Force la mise à jour de l'affichage selon l'état actuel des filtres
afficherProduits(!boutonsHaut.boutonCaches.classList.contains('active'));
});
const urlIconeFavoriGris = favUrlOff;
const urlIconeFavoriRouge = favUrlOn;
const iconeFavori = document.createElement('img');
const etatFavori = localStorage.getItem(etatFavoriKey);
iconeFavori.setAttribute('src', (etatFavori && etatFavori == '1') ? urlIconeFavoriRouge : urlIconeFavoriGris);
if (cssEnabled || mobileEnabled) {
iconeFavori.style.cssText = `
position: absolute;
top: ${favVerticalMobile};
left: ${favHorizontalMobile};
cursor: pointer;
width: ${favSizeMobile};
height: ${favSizeMobile};
z-index: 10;
`;
} else {
iconeFavori.style.cssText = `
position: absolute;
top: ${favVertical};
left: ${favHorizontal};
cursor: pointer;
width: ${favSize};
height: ${favSize};
z-index: 10;
`;
}
//Gestion du clic sur l'icône de favori
iconeFavori.addEventListener('click', () => {
var etatFavoriActuel = localStorage.getItem(etatFavoriKey) || '0';
etatFavoriActuel = etatFavoriActuel === '1' ? '0' : '1';
localStorage.setItem(etatFavoriKey, etatFavoriActuel);
iconeFavori.setAttribute('src', etatFavoriActuel === '1' ? urlIconeFavoriRouge : urlIconeFavoriGris);
produit.classList.toggle('favproduct');
if (etatFavoriActuel === '1') {
//Si le produit est marqué comme favori, s'assurer qu'il est marqué comme non caché
localStorage.setItem(etatCacheKey, '0');
produit.style.display = ''; //Assure que le produit est visible
//Mettre à jour l'icône de l'œil pour refléter que le produit n'est plus caché
const iconeOeil = produit.querySelector('img[src="' + urlIcone + '"], img[src="' + urlIconeOeil + '"]');
if (iconeOeil) {
iconeOeil.setAttribute('src', urlIcone);
}
}
afficherProduits(!boutonsHaut.boutonCaches.classList.contains('active'));
});
wrapper.appendChild(iconeOeil);
wrapper.appendChild(iconeFavori);
});
//Initialisation de l'affichage par défaut à l'onglet choisi précédemment si l'option est activée
const afficherVisiblesParDefaut = lockProductTab ? productTabSelection !== 'caches' : true;
afficherProduits(afficherVisiblesParDefaut);
}
if (hideEnabled && apiOk && !autohideEnabled) {
//Appeler la fonction pour ajouter les étiquettes de temps
ajouterIconeEtFonctionCacher();
}
//Exécuter la fonction pour ajouter les icônes et les fonctionnalités de cacher
if (highlightEnabled && apiOk) {
//Appeler la fonction pour ajouter les étiquettes de temps
ajouterEtiquetteTemps();
}
rendreImagesCliquables();
//Suppression footer
var styleFooter = document.createElement('style');
styleFooter.textContent = `
/* === Ancien footer Amazon === */
#rhf,
#rhf-shoveler,
.rhf-frame,
#navFooter,
footer.nav-mobile.nav-ftr-batmobile {
display: none !important;
}
/* === Nouveau footer Amazon (2025) === */
footer.nav-bb-footer,
footer.nav-bb-footer-mobile,
#nav-ftr {
display: none !important;
}
`
document.head.appendChild(styleFooter);
//Nombre de colonnes fixe
if (apiOk && columnEnabled) {
const style = document.createElement('style');
style.innerHTML = `
#vvp-items-grid {
display: grid !important;
grid-template-columns: repeat(${nbColumn}, 1fr) !important;
}
`;
document.head.appendChild(style);
}
//Agrandir la fenetre des adresses
if (fastCmdEnabled && apiOk) {
var styleAddress = document.createElement('style');
styleAddress.textContent = `
#a-popover-4 {
height: 480px !important;
width: 900px !important;
}
`
document.head.appendChild(styleAddress);
}
//Pour monter la valeur de la taxe
if (taxValue && apiOk) {
//Créez une balise