Astro Indonesia's unit price calculator - Userscript to display the unit price of items in Astro Indonesia's webstore
0
astro-unit-price.user.js edited
85 lines 2.9 kB view raw
1// ==UserScript== 2// @name Astro Indonesia - Unit price calculator 3// @description Displays the unit price of items in Astro Indonesia webstore 4// @namespace Violentmonkey Scripts 5// @author Angelo <me@angelo.fyi> 6// @icon 7// @version 0.0.1 8// @license AGPL-3.0-or-later 9// 10// @updateURL https://tangled.org/strings/angelo.fyi/3mm5rryhyuq22/raw 11// @supportURL mailto:me@angelo.fyi?subject=Astro%20Unit%20Price%20Question 12// 13// @include https://www.astronauts.id/* 14// @match https://www.astronauts.id/* 15// @grant none 16// 17// ==/UserScript== 18 19// TODO: Further filter pages 20// https://www.astronauts.id/c/produk-terbaru-123456789 21// https://www.astronauts.id/c/astro-basics-11065 22// https://www.astronauts.id/search?q=bawang 23const UNIT_REGEX = /(\d+)(?:-\d+)?(\w+)/; 24const ID_CURRENCY_LOCALE = new Intl.NumberFormat("id-ID", { style: "currency", currency: "IDR" }); 25 26function renderUnitPrice() { 27 const items = document.querySelectorAll(".css-ks6u10"); 28 for (const item of items) { 29 // Items that doesnt have units literally doesnt have the element 30 const unitEl = item.querySelector(".css-1nnfyv8"); 31 if (unitEl == null) continue; 32 // Don't need to re-apply unit price to already calculated 33 if (item.querySelector("[data-unit-price]") != null) continue; 34 35 const priceEl = item.querySelector(".css-tg7xtj"); 36 const priceString = priceEl.textContent; 37 const unitString = unitEl.textContent; 38 39 const price = Number.parseInt(priceString.replaceAll("Rp", "").replaceAll(".", "")); 40 let [_, unitCount, unitSymbol] = UNIT_REGEX.exec(unitString); 41 42 // Standardize units 43 switch (unitSymbol) { 44 // Weights 45 case "gram": 46 case "gr": 47 unitCount /= 1000; 48 unitSymbol = "kg"; 49 break; 50 51 // Fluids 52 case "liter": 53 case "liters": 54 case "litre": 55 case "litres": 56 unitSymbol = "l"; 57 break; 58 case "ml": 59 unitCount /= 1000; 60 unitSymbol = "l"; 61 break; 62 case "oz": 63 unitCount *= 29.5735295625; 64 unitCount /= 1000; 65 unitSymbol = "l"; 66 break; 67 } 68 69 // Remove plurals; probably too basic of a check 70 if (unitSymbol.endsWith("s")) unitSymbol = unitSymbol.slice(0, -1); 71 72 // Create & append unit price 73 const unitPriceEl = document.createElement("span"); 74 unitPriceEl.setAttribute("data-unit-price", "true"); 75 unitPriceEl.style = `font-size: 0.5rem;`; 76 unitPriceEl.className = "MuiTypography-root MuiTypography-caption-tiny"; 77 unitPriceEl.innerText = `(${ID_CURRENCY_LOCALE.format(price / unitCount)}/${unitSymbol})`; 78 priceEl.append(unitPriceEl); 79 } 80} 81 82(function () { 83 // Mounted on <body>; dehydrated html doesn't contain any sensible HTML structure 84 new MutationObserver(renderUnitPrice).observe(document.querySelector("body"), { subtree: true, childList: true }); 85})();