// ==UserScript== // @name Yandex Eda price calculator // @namespace Violentmonkey Scripts // @match *://eda.yandex.ru/* // @grant none // @version 1.2 // @author Insaf Burangulov // @description 12/6/2024, 7:41:34 AM // @license MIT // @downloadURL none // ==/UserScript== // Интервал поиска карточек для расчета const REFRESH_INTERVAL = 1000; // Главный селектор карточки const CARD_PRICE_ROOT_SELECTOR = '.UiKitDesktopProductCard_descriptionWrapper'; // Селектор, исключающий для карточки повторный пересчет цены const CARD_PRICE_CALCULATED_SELECTOR = 'calculated-by-price'; // Внутренний селектор карточки, содержащий вес/объем товара const CARD_WEIGHT_SELECTOR = '.UiKitDesktopProductCard_weight'; // Поиск карточек товаров function findCardsForCalculating(root = document) { return root .querySelectorAll(CARD_PRICE_ROOT_SELECTOR + ':not(.' + CARD_PRICE_CALCULATED_SELECTOR + ')'); } // Извлечение количества и единицы измерения из карточки function extractWeight(card) { const weightDiv = card.querySelector(CARD_WEIGHT_SELECTOR); if (!weightDiv) { return false; } const weightData = weightDiv .textContent .split(/\s| /g) if (weightData.length < 2) { return false; } weightData[0] = parseInt(weightData[0]); return weightData; } // Извлечение узла, содержащего цену товара function extractPriceNode(card) { return card.querySelector('.UiKitDesktopProductCard_priceWrapper') .querySelector('span'); } // Извлечение цены товара function extractPriceData(node) { const priceData = node .textContent .split(/\s| /g); if (priceData.length < 2) { return false; } priceData[0] = parseInt(priceData[0]); return priceData; } // Расчет цены function calculatePrice(price, weight, type) { // Граммы и миллилитры if (type === 'г' || type === 'мл') { return Math.round((price / weight) * 1000); } if (type === 'кг' || type === 'л') { return Math.round(price / weight); } return false; } // Установка текста цены function setPriceText(price, currencyChar, node) { node.textContent = node.textContent + '/' + price + '\u00A0' + currencyChar; } // Метка карточки как просчитанной function markCardAsCalculated(card) { card.classList.add(CARD_PRICE_CALCULATED_SELECTOR); } // Обработка карточки товара function processCard(card) { const weightData = extractWeight(card); if (!weightData) { return; } const weight = weightData[0]; const type = weightData[1]; const priceNode = extractPriceNode(card); if (!priceNode) { return; } const priceData = extractPriceData(priceNode); if (!priceData) { return; } const price = priceData[0]; const currencyChar = priceData[1]; const calculatedPrice = calculatePrice(price, weight, type); if (!calculatedPrice) { return; } setPriceText(calculatedPrice, currencyChar, priceNode); markCardAsCalculated(card); } // Расчет цены на загруженные карточки товаров function calc_prices() { const cards = findCardsForCalculating(); cards.forEach(processCard) } setInterval(calc_prices, REFRESH_INTERVAL);