Sorts items by price per unit (e.g. `per kg` or `per litre`) in Carrefour online shops in Poland.
// ==UserScript== // @name carrefour per unit price sorter // @name:pl carrefour sortowanie po cenie jednostki // @namespace cprn // @license GPLv3 // @match https://*.carrefour.pl/* // @grant none // @version 0.2 // @author cprn // @run-at document-idle // @date 2024-07-18 00:34:09 // @description Sorts items by price per unit (e.g. `per kg` or `per litre`) in Carrefour online shops in Poland. // @description:pl Sortuje produkty po cenie za jednostkę (np. za `kg` albo `l`) w sklepie internetowym polskiego Carrefoura. // ==/UserScript== console.debug('cprn: start') function discoverClasses () { let priceTag = null; ['zł/1 l', 'zł/1 kg'].every(s => { let xpath = ''.concat("//p[contains(., '", s, "')]"); priceTag = document.evaluate(xpath, document, null, XPathR###lt.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; // console.log('priceTag', priceTag); return priceTag === null; }); return { item: priceTag.parentNode.parentNode.parentNode.parentNode.classList[0], perUnitStrip: priceTag.parentNode.classList[0], mass: priceTag.parentNode.children[0].classList[0], perMass: priceTag.parentNode.previousSibling.children[0].children[0].classList[0], }; } const classes = discoverClasses(); const firstItem = document.getElementsByClassName(classes.item)[0]; console.debug('[discovered classes]\n--------------------\n' + 'item: ' + classes.item, document.getElementsByClassName(classes.item)[0], '\n' + 'perUnitStrip: ' + classes.perUnitStrip, document.getElementsByClassName(classes.perUnitStrip)[0], '\n' + 'mass: ' + classes.mass, document.getElementsByClassName(classes.mass)[0], '\n' + 'perMass: ' + classes.perMass, document.getElementsByClassName(classes.perMass)[0], '\n' + 'perUnit: ', perUnitPrice(firstItem) ); function perUnitPrice (e) { let perUnit = e.getElementsByClassName(classes.perUnitStrip)[0].lastChild; let perMass = e.getElementsByClassName(classes.perMass)[0]; let mass = e.getElementsByClassName(classes.mass)[0].lastChild; if (mass.innerText == '1 szt.' || perUnit === undefined) { console.debug('unknown price', e); return .0; } else if (mass.innerText == '1 l' || mass.innerText == '1 kg') { price = ''.concat(perMass.children[0].innerText, '.', perMass.children[1].innerText) } else { price = perUnit.innerText.slice(0, -7).replace(',', '.'); } return parseFloat(price) } function sortItems () { console.debug('sorting...'); [...firstItem.parentNode.children] .sort((a, b) => perUnitPrice(a) > perUnitPrice(b) ? 1 : -1 ) .forEach(e => firstItem.parentNode.appendChild(e)) console.debug('sorting done'); } window.sortItems = sortItems; // window.addEventListener('load', sortItems, false) // setTimeout(sortItems, 300) // setTimeout(sortItems, 600) // setTimeout(sortItems, 900) setTimeout(sortItems, 2000) console.debug('cprn: done')