Aliexpress Plus 2

Sorts search results by item price properly with shipping costs included

As of 2020-03-02. See the latest version.

// ==UserScript==
// @name         Aliexpress Plus 2
// @namespace    http://www.facebook.com/Tophness
// @version      2.0
// @description  Sorts search results by item price properly with shipping costs included
// @author       Tophness
// @match        https://www.aliexpress.com/wholesale?*
// @require      https://cdnjs.cloudflare.com/ajax/libs/tinysort/2.3.6/tinysort.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/tinysort/2.3.6/tinysort.charorder.min.js
// @run-at document-idle
// ==/UserScript==

var elh = {
    'sortchange' : 'Cheapest Unit Price',
    'sortchange2' : 'Cheapest Total Price',
    'sortchange3' : 'Cheapest Price',
    'sortchange4l' : 'Max Price'
};

var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if(mutation.type == 'childList'){
            for (var j = 0; j < mutation.addedNodes.length; j++) {
                processall(mutation.addedNodes[j].childNodes);
            }
        }
    });
});

function waitForEl(){
    var observera = new MutationObserver(function (mutations, me) {
        if(document.querySelector("ul.list-items")) {
            me.disconnect();
            if(document.location.href.indexOf('g=y') == -1){
                observer.observe(document.querySelector("ul.list-items"), { childList: true,  subtree: true });
            }
            else{
                observer.observe(document.querySelector("ul.list-items"), { childList: true });
            }
            return;
        }
    });

    observera.observe(document, {
        childList: true,
        subtree: true
    });
}

waitForEl();
var sortmethod = 1;
var count = 0;
function process(listitem){
    if(listitem.querySelector){
        var price = listitem.querySelector('.price-current');
        var shipping = listitem.querySelector('.shipping-value');
        if(price && price.innerText.indexOf('$') != -1 && listitem.className != "moved" && listitem.className.indexOf('product-card') == -1){
            var pricefixed = price.innerText.substring(price.innerText.indexOf('$')+1);
            var shippingfixed;
            if(shipping.innerText.indexOf('Free Shipping') == -1){
                shippingfixed = shipping.innerText.substring(shipping.innerText.indexOf('$')+1);
            }
            else{
                shippingfixed = "0.00";
            }
            var pricepretext = price.innerText.substring(0, price.innerText.indexOf('$')+1);
            var finalcost = "";
            if(pricefixed.indexOf(' - ') != -1){
                var pricesplit = pricefixed.split(' - ');
                finalcost = (parseFloat(pricesplit[0]) + parseFloat(shippingfixed)).toFixed(2) + " - " + (parseFloat(pricesplit[1]) + parseFloat(shippingfixed)).toFixed(2);
            }
            else{
                finalcost = (parseFloat(pricefixed) + parseFloat(shippingfixed)).toFixed(2);
            }
            var finalcostpost;
            var finalcostpostwhole;
            var priceunitparttemp;
            if(listitem.querySelector('.price-unit')){
                var priceunitel = listitem.querySelector('div.item-price-row.packaging-sale').querySelector('span.price-unit');
                var priceuniteltext = priceunitel.innerText;
                var priceunit = priceuniteltext.substring(0, priceuniteltext.indexOf(' '));
                var priceunitposttext = priceuniteltext.substring(priceuniteltext.indexOf(' '));
                var finalcostpart = (finalcost / parseFloat(priceunit)).toFixed(2);
                if(priceunitposttext.indexOf('/') != -1){
                    var priceunitsplit = priceunitposttext.split('/');
                    var priceunitpart = priceunitsplit[0];
                    var priceunitwhole = priceunitsplit[1];
                    finalcostpostwhole = finalcost + " / " + priceunitwhole;
                    finalcost = finalcostpart + " / " + priceunitpart;
                    priceunitparttemp = priceunitpart;
                }
            }
            var finalcostdiv = document.createElement('div');
            finalcostdiv.className = 'item-total-wrap';
            if(finalcostpostwhole){
                var finalcostpretext = document.createElement('span');
                finalcostpretext.className = 'total-pretext';
                finalcostpretext.innerHTML = "Total: " + pricepretext;
                var finalcostspan = document.createElement('span');
                finalcostspan.className = 'total-current';
                finalcostspan.innerHTML = finalcostpostwhole;

                var pricerow = listitem.querySelector('.item-price-row');
                if(pricerow){
                    var priceunitel2 = pricerow.querySelector('span.price-unit');
                    priceunitel2.innerHTML = " / " + priceunitparttemp;
                    price.innerHTML = pricepretext + finalcostpart;
                }
                finalcostdiv.appendChild(finalcostpretext);
                if(sortmethod == 0){
                    finalcostspan.className = 'total-posttext';
                    var finalcostbr = document.createElement('br');
                    finalcostbr.style.display = "none";
                    var finalcostspan2 = document.createElement('span');
                    finalcostspan2.className = 'total-current';
                    finalcostspan2.innerHTML = finalcost;
                    finalcostspan2.style.display = "none";
                    finalcostdiv.appendChild(finalcostspan2);
                    finalcostdiv.appendChild(finalcostbr);
                }
                finalcostdiv.appendChild(finalcostspan);
            }
            else{
                var finalcostpretext = document.createElement('span');
                finalcostpretext.className = 'total-pretext';
                finalcostpretext.innerHTML = "Total: " + pricepretext;
                var finalcostspan = document.createElement('span');
                finalcostspan.className = 'total-current';
                finalcostspan.innerHTML = finalcost;
                finalcostdiv.appendChild(finalcostpretext);
                finalcostdiv.appendChild(finalcostspan);
            }
            if(shipping.parentNode.nextSibling.className != finalcostdiv.className){
                price.parentNode.parentNode.parentNode.insertBefore(finalcostdiv, shipping.parentNode.nextSibling);
            }
            if(count >= 3){
                sortall(document.querySelectorAll("li.list-item"));
                count = 0;
            }
            else{
                count++;
            }
        }
    }
}

function processall(list){
    for (var i = 0; i < list.length; i++) {
        process(list[i]);
    }
}

function sortall(listitems){
    if(sortmethod == 0){
        tinysort(listitems,{selector:'span.total-current', natural:true});
    }
    else if(sortmethod == 1){
        tinysort(listitems,{selector:'span.total-current', natural:true});
    }
    else if(sortmethod == 2){
        tinysort(listitems,{selector:'span.price-current', natural:true});
    }
    else if(sortmethod == 3){
        tinysort(listitems,{selector:'span.price-current', natural:true, order: 'desc'});
    }
}

processall(document.querySelectorAll("li.list-item"));
//sortall(document.querySelectorAll("li.list-item"));

function SortRows(mode){
    sortmethod = mode;
    sortall(document.querySelectorAll("li.list-item"));
}
function insersearch(){
    var sortdiv = document.createElement('div');
    sortdiv.className = 'sort-item';
    var sortspan = document.createElement('div');
    sortspan.className = 'sort-item';
    var sortspan2 = document.createElement('div');
    sortspan2.className = 'sort-item';
    var sortspan3 = document.createElement('div');
    sortspan3.className = 'sort-item';
    var sortspan4 = document.createElement('div');
    sortspan4.className = 'sort-item';
    var sortchange = document.createElement('div');
    sortchange.id = 'sortchange';
    sortchange.innerHTML = elh[sortchange.id];
    sortchange.addEventListener("click", function () {
        SortRows(0)
    }, false);
    var sortchange2 = document.createElement('div');
    sortchange2.id = 'sortchange2';
    sortchange2.innerHTML = elh[sortchange2.id];
    sortchange2.addEventListener("click", function () {
        SortRows(1)
    }, false);
    var sortchange3 = document.createElement('div');
    sortchange3.id = 'sortchange3';
    sortchange3.innerHTML = elh[sortchange3.id];
    sortchange3.addEventListener("click", function () {
        SortRows(2)
    }, false);
    var sortchange4l = document.createElement('label');
    sortchange4l.id = 'sortchange4l';
    sortchange4l.innerHTML = elh[sortchange4l.id] + ': ';
    var sortchange4t = document.createElement('input');
    sortchange4t.id = 'sortchange4t';
    sortchange4t.addEventListener("keydown", function () {
        SortRows(3)
    }, false);
    sortspan.appendChild(sortchange);
    sortspan2.appendChild(sortchange2);
    sortspan3.appendChild(sortchange3);
    sortspan4.appendChild(sortchange4l);
    sortspan4.appendChild(sortchange4t);
    sortdiv.appendChild(sortspan);
    sortdiv.appendChild(sortspan2);
    sortdiv.appendChild(sortspan3);
    sortdiv.appendChild(sortspan4);
    var searchbox = document.querySelector(".sort-by-wrapper");
    searchbox.appendChild(sortdiv);
    document.getElementById('sortchange2').setAttribute('style', 'font-weight: bold');
}

insersearch();