Show stock level for Frasers Group sites

Show stock level for Frasers Group sites. A full list of the group URLs is included, but it doesn't work on some for various reasons, eg. the stock-qty is 0 for everything. Works well on Sports Direct, Game and eBuyer though.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Show stock level for Frasers Group sites
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Show stock level for Frasers Group sites. A full list of the group URLs is included, but it doesn't work on some for various reasons, eg. the stock-qty is 0 for everything. Works well on Sports Direct, Game and eBuyer though.
// @author       Gareth79
//
// @match       https://www.18montrose.com/*
// @match       https://www.agentprovocateur.com/*
// @match       https://www.amara.com/*
// @match       https://antiguaapparelshop.com/*
// @match       https://www.campri.com/*
// @match       https://carlton-sports.com/*
// @match       https://www.cruisefashion.com/*
// @match       https://www.donnay.com/*
// @match       https://www.ebuyer.com/*
// @match       https://www.evanscycles.com/*
// @match       https://www.everlast.com/*
// @match       https://www.everlastgyms.com/*
// @match       https://www.firetrap.com/*
// @match       https://www.flannels.com/*
// @match       https://www.frasers.com/*
// @match       https://www.game.co.uk/*
// @match       https://www.gelert.com/*
// @match       https://www.gievesandhawkes.com/*
// @match       https://www.gul.com/*
// @match       https://www.houseoffraser.co.uk/*
// @match       https://www.isawitfirst.com/*
// @match       https://www.jackwills.com/*
// @match       https://www.karrimor.com/*
// @match       https://lagear.com/*
// @match       https://www.lovellsports.com/*
// @match       https://www.lillywhites.com/*
// @match       https://www.lonsdale.com/*
// @match       https://www.muddyfox.com/*
// @match       https://ukstore.nofear.com/*
// @match       https://www.scottsmenswear.com/*
// @match       https://store.slazenger.com/*
// @match       https://www.sofa.com/gb/*
// @match       https://www.sondico.com/*
// @match       https://www.soulcal.co.uk/*
// @match       https://www.sportsdirect.com/*
// @match       https://sportmaster.dk/*
// @match       https://www.studio.co.uk/*
// @match       https://www.tessuti.co.uk/*
// @match       https://www.usapro.co.uk/*
// @match       https://www.usc.co.uk/*
// @match       https://www.vanmildert.com/*
// @match       https://www.slazenger.com/*
// @match       https://www.sofa.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
    'use strict';

    // Function to update the list item text
    function updateListItems() {
        // Include hidden elements in the search
        const listItems = document.querySelectorAll('li[data-stock-qty]');
        listItems.forEach(item => {
            const stockQty = item.getAttribute('data-stock-qty');
            const sizeText = item.getAttribute('data-text') || item.querySelector('span')?.textContent.trim();

            // Remove hidden class if present to make stock info visible
            if (item.classList.contains('hidden')) {
                item.classList.remove('hidden');
            }

            // Find the <span> inside the <li> to update its text
            const span = item.querySelector('span');

            // Avoid duplicate updates
            if (span && !span.textContent.includes('Stock:')) {
                // Get the original size text without any existing stock info
                const originalText = sizeText || span.textContent.trim();
                span.textContent = `${originalText} (Stock: ${stockQty})`;
            }
        });
    }

    // Function to update select dropdown options
    function updateSelectOptions() {
        const selectElement = document.querySelector('#sizeDdl, select[class*="SizeDropDown"]');
        if (selectElement) {
            // Remove hidden class from the select element if present
            if (selectElement.classList.contains('hidden')) {
                selectElement.classList.remove('hidden');
            }

            const options = selectElement.querySelectorAll('option[data-stock-qty]');
            options.forEach(option => {
                const stockQty = option.getAttribute('data-stock-qty');
                const originalText = option.textContent.trim();

                // Avoid duplicate updates
                if (!originalText.includes('Stock:')) {
                    option.textContent = `${originalText} (Stock: ${stockQty})`;
                }
            });
        }
    }

    // Function to show hidden size containers
    function showHiddenSizeContainers() {
        // Look for the specific product variant container that might be hidden
        const productVariantContainer = document.querySelector('#productVariantAndPrice');
        if (productVariantContainer && productVariantContainer.classList.contains('hidden')) {
            productVariantContainer.classList.remove('hidden');
        }

        // Also look for containers with SzQuantGroup class that might be hidden
        const sizeQuantContainers = document.querySelectorAll('.SzQuantGroup.hidden');
        sizeQuantContainers.forEach(container => {
            container.classList.remove('hidden');
        });

        // Look for other common size container elements that might be hidden
        const sizeContainers = document.querySelectorAll('#divSize, #ulSizes, .sizeButtons, .swapSize');
        sizeContainers.forEach(container => {
            if (container.classList.contains('hidden')) {
                container.classList.remove('hidden');
            }
        });
    }

    // Observe DOM changes for dynamic content loading
    const observer = new MutationObserver(() => {
        showHiddenSizeContainers();
        updateListItems();
        updateSelectOptions();
    });

    // Start observing the body for changes
    observer.observe(document.body, { childList: true, subtree: true });

    // Initial check in case elements are already present
    showHiddenSizeContainers();
    updateListItems();
    updateSelectOptions();
})();