Greasy Fork is available in English.

carrefour per unit price sorter

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, XPathResult.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')