Greasy Fork is available in English.

Aliexpress Url Cleaner

Removes unnecessary parameters to Aliexpress urls

2019-05-27 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name         Aliexpress Url Cleaner
// @version      0.3
// @description  Removes unnecessary parameters to Aliexpress urls
// @match        *://*.aliexpress.com/*
// @namespace    https://greasyfork.org/users/168
// @run-at       document-start
// @grant        unsafeWindow
// @noframes
// ==/UserScript==

function whenReady() {
    return new Promise((resolve) => {
        function completed() {
            document.removeEventListener('DOMContentLoaded', completed);
            window.removeEventListener('load', completed);
            resolve();
        }

        if (document.readyState === 'complete' ||
            document.readyState === 'interactive') {
            resolve();
        } else {
            document.addEventListener('DOMContentLoaded', completed);
            window.addEventListener('load', completed);
        }
    });
}

// Required by firefox to make functions available to page scripts.
function exportFn(fn, target, name) {
    if (typeof exportFunction === 'function') {
        exportFunction(fn, target, {
            defineAs: name
        });
    } else {
        target[name] = fn;
    }
}


let reg = /((?:https?:)?\/\/(?:\w+\.)?aliexpress\.com\/(?:store\/product\/[^\/]+\/[0-9_]+|item\/(?:[^\/]+\/)?[0-9_]+)\.html)(\?[^#\r\n]+)?(#.+)?/i;

function toCanonical(original) {
    let match = original.match(reg);
    if (match) {
        return match[1] + (match[3] || '');
    }
    return null;
}

// For lazy-loaded links. Mutation observer listening to jsonP requests.
let observer = new MutationObserver(function (mutationsList) {
    for (let mutation of mutationsList) {
        for (let node of mutation.addedNodes) {
            const match = (node.src || '').match(/(\/getI2iRecommendingResults\.do|\/b2bad\.html).+[?|&](?:callback|cb)=(__jp\d+)/);
            if (match) {
                let requestUrl = match[1];
                let callbackName = match[2];
                let originalCallback = unsafeWindow[callbackName];

                function objCleaner(obj) {
                    try {
                        if (requestUrl === '/getI2iRecommendingResults.do' && obj.success) {
                            for (let product of obj.results) {
                                let canonical = toCanonical(product.productDetailUrl)
                                if (canonical) {
                                    product.productDetailUrl = canonical;
                                }
                            }
                        } else if (requestUrl === '/b2bad.html') {
                            for (let product of obj.PRODUCTS) {
                                let canonical = toCanonical(product.DETAILURL)
                                if (canonical) {
                                    product.DETAILURL = canonical;
                                }
                            }
                        }
                    } catch (e) {

                    }
                    originalCallback(obj);
                }
                exportFn(objCleaner, unsafeWindow, callbackName);
            };
        }
    }
});

observer.observe(document.head, {
    childList: true
});

// Tab url.
let canonical = toCanonical(window.location.href);
if (!canonical) {
    let link = document.querySelector('head > link[rel=canonical]');
    if (link) {
        canonical = toCanonical(link.href + window.location.hash);
    }
}
if (canonical) {
    window.history.replaceState(history.state, document.title, canonical);
}

// Non lazy-loaded links.
whenReady().then(() => {
    document.querySelectorAll('a').forEach((e) => {
        let canonical = toCanonical(e.href);
        if (canonical) {
            e.href = canonical;
        }
    });
});