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.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 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();
})();