// ==UserScript== // @name Astro Indonesia - Unit price calculator // @description Displays the unit price of items in Astro Indonesia webstore // @namespace Violentmonkey Scripts // @author Angelo // @icon // @version 0.0.1 // @license AGPL-3.0-or-later // // @updateURL https://tangled.org/strings/angelo.fyi/3mm5rryhyuq22/raw // @supportURL mailto:me@angelo.fyi?subject=Astro%20Unit%20Price%20Question // // @include https://www.astronauts.id/* // @match https://www.astronauts.id/* // @grant none // // ==/UserScript== // TODO: Further filter pages // https://www.astronauts.id/c/produk-terbaru-123456789 // https://www.astronauts.id/c/astro-basics-11065 // https://www.astronauts.id/search?q=bawang const UNIT_REGEX = /(\d+)(?:-\d+)?(\w+)/; const ID_CURRENCY_LOCALE = new Intl.NumberFormat("id-ID", { style: "currency", currency: "IDR" }); function renderUnitPrice() { const items = document.querySelectorAll(".css-ks6u10"); for (const item of items) { // Items that doesnt have units literally doesnt have the element const unitEl = item.querySelector(".css-1nnfyv8"); if (unitEl == null) continue; // Don't need to re-apply unit price to already calculated if (item.querySelector("[data-unit-price]") != null) continue; const priceEl = item.querySelector(".css-tg7xtj"); const priceString = priceEl.textContent; const unitString = unitEl.textContent; const price = Number.parseInt(priceString.replaceAll("Rp", "").replaceAll(".", "")); let [_, unitCount, unitSymbol] = UNIT_REGEX.exec(unitString); // Standardize units switch (unitSymbol) { // Weights case "gram": case "gr": unitCount /= 1000; unitSymbol = "kg"; break; // Fluids case "liter": case "liters": case "litre": case "litres": unitSymbol = "l"; break; case "ml": unitCount /= 1000; unitSymbol = "l"; break; case "oz": unitCount *= 29.5735295625; unitCount /= 1000; unitSymbol = "l"; break; } // Remove plurals; probably too basic of a check if (unitSymbol.endsWith("s")) unitSymbol = unitSymbol.slice(0, -1); // Create & append unit price const unitPriceEl = document.createElement("span"); unitPriceEl.setAttribute("data-unit-price", "true"); unitPriceEl.style = `font-size: 0.5rem;`; unitPriceEl.className = "MuiTypography-root MuiTypography-caption-tiny"; unitPriceEl.innerText = `(${ID_CURRENCY_LOCALE.format(price / unitCount)}/${unitSymbol})`; priceEl.append(unitPriceEl); } } (function () { // Mounted on ; dehydrated html doesn't contain any sensible HTML structure new MutationObserver(renderUnitPrice).observe(document.querySelector("body"), { subtree: true, childList: true }); })();