AliExpress Enhanced Listings

Shows full listing titles and highlights Choice, Bundle deals, and Premium Quality tagged listings in a unique way.

当前为 2025-10-19 提交的版本,查看 最新版本

// ==UserScript==
// @name         AliExpress Enhanced Listings
// @namespace    https://aliexpress.com/
// @version      1.6
// @description  Shows full listing titles and highlights Choice, Bundle deals, and Premium Quality tagged listings in a unique way.
// @author       ObnubiladO
// @match        https://*.aliexpress.com/*
// @grant        GM_addStyle
// @run-at       document-idle
// @license      GPL-3.0-or-later
// ==/UserScript==

(function () {
    'use strict';

    // --- Safe addStyle fallback ---
    const addStyle = (typeof GM_addStyle === 'function')
        ? GM_addStyle
        : (css) => {
            const s = document.createElement('style');
            s.type = 'text/css';
            s.appendChild(document.createTextNode(css));
            document.head.appendChild(s);
        };

    // ==================== Full Titles v1.1 ====================
    // Break clamping + allow cards to expand; tuned for newer AliExpress layouts.
    addStyle(`
        /* Card wrappers (legacy + current) */
        .search-item-card-wrapper-gallery,
        .search-item-card-wrapper-list,
        [class*="search-item-card-wrapper"],
        .product-card,
        .product-container,
        .list-item,
        [data-widget*="product"],
        [data-widget*="list"],
        [class*="search-card"] {
            overflow: visible !important;
            height: auto !important;
            max-height: none !important;
            min-height: unset !important;
            position: static !important;
            display: block !important;
        }

        /* Titles (new & old) inside product links / cards */
        a[href*="/item/"] h3,
        a[href*="/item/"] [numberoflines],
        a[href*="/item/"] [title],
        [class*="search-item-card-wrapper"] h3,
        [class*="search-item-card-wrapper"] [numberoflines],
        [class*="search-item-card-wrapper"] [title],
        [class*="search-item-card-wrapper"] [style*="-webkit-line-clamp"],
        a[href*="/item/"] [style*="-webkit-line-clamp"],
        h3.kt_ki {
            display: block !important;
            white-space: normal !important;
            -webkit-line-clamp: initial !important;
            -webkit-box-orient: unset !important;
            overflow: visible !important;
            text-overflow: clip !important;
            height: auto !important;
            max-height: none !important;
            line-height: 1.35 !important;
        }

        /* Optional spacing so cards don't overlap when titles grow */
        .product-container {
            margin-bottom: 25px !important;
        }
    `);

    // Free heights up the DOM tree so titles can expand
    function freeHeights(node) {
        let n = node;
        while (n && n !== document.body) {
            if (n.style) {
                if (n.style.height) n.style.height = 'auto';
                if (n.style.minHeight) n.style.minHeight = '0';
                if (n.style.maxHeight) n.style.maxHeight = 'none';
                n.style.overflow = 'visible';
            }
            n = n.parentElement;
        }
    }

    // If @title holds longer text than visible content, replace with full text
    function maybeUseTitleAttribute(el) {
        const t = el.getAttribute && el.getAttribute('title');
        if (!t) return;
        const visible = (el.innerText || '').trim();
        if (t.trim().length > visible.length) {
            el.textContent = t;
        }
    }

    function revealFullTitles() {
        const selector = [
            'a[href*="/item/"] h3',
            'a[href*="/item/"] [numberoflines]',
            'a[href*="/item/"] [title]',
            'a[href*="/item/"] [style*="-webkit-line-clamp"]',
            '[class*="search-item-card-wrapper"] h3',
            '[class*="search-item-card-wrapper"] [numberoflines]',
            '[class*="search-item-card-wrapper"] [title]',
            '[class*="search-item-card-wrapper"] [style*="-webkit-line-clamp"]',
            'h3.kt_ki'
        ].join(',');

        document.querySelectorAll(selector).forEach(el => {
            // Inline overrides to beat stubborn inline styles
            el.style.webkitLineClamp = 'initial';
            el.style.webkitBoxOrient = 'unset';
            el.style.overflow = 'visible';
            el.style.whiteSpace = 'normal';
            el.style.height = 'auto';
            el.style.maxHeight = 'none';

            freeHeights(el);
            maybeUseTitleAttribute(el);
        });
    }

    // ==================== Highlight Tags Script (unchanged from 1.5) ====================
    const CHOICE_HIGHLIGHT_STYLE = 'background-color: #fff8c4 !important; border: 2px solid #f5c518 !important;';
    const CHOICE_HIGHLIGHT_CLASS = 'choice-highlight';

    const BUNDLE_HIGHLIGHT_STYLE = 'background-color: #ff3b3b !important; color: white !important; font-weight: bold !important; border-radius: 4px;';
    const BUNDLE_HIGHLIGHT_CLASS = 'bundle-highlight';

    const PREMIUM_HIGHLIGHT_STYLE = 'background-color: #ffc501 !important; color: #666666 !important; font-weight: bold !important; border-radius: 4px; padding: 0 4px;';
    const PREMIUM_HIGHLIGHT_CLASS = 'premium-highlight';

    function clearHighlights() {
        // Choice card highlights
        document.querySelectorAll(`.${CHOICE_HIGHLIGHT_CLASS}`).forEach(card => {
            card.style.removeProperty('background-color');
            card.style.removeProperty('border');
            card.classList.remove(CHOICE_HIGHLIGHT_CLASS);
        });

        // Bundle tags
        document.querySelectorAll(`.${BUNDLE_HIGHLIGHT_CLASS}`).forEach(tag => {
            tag.style.removeProperty('background-color');
            tag.style.removeProperty('color');
            tag.style.removeProperty('font-weight');
            tag.style.removeProperty('border-radius');
            tag.classList.remove(BUNDLE_HIGHLIGHT_CLASS);
        });

        // Premium Quality tags
        document.querySelectorAll(`.${PREMIUM_HIGHLIGHT_CLASS}`).forEach(tag => {
            tag.style.removeProperty('background-color');
            tag.style.removeProperty('color');
            tag.style.removeProperty('font-weight');
            tag.style.removeProperty('border-radius');
            tag.style.removeProperty('padding');
            tag.classList.remove(PREMIUM_HIGHLIGHT_CLASS);
        });
    }

    function highlightChoiceCards() {
        const choiceImages = document.querySelectorAll(
            'img[src*="154x64.png"], img[src*="S1887a285b60743859ac7bdbfca5e0896Z"]'
        );
        const foundCards = new Set();

        choiceImages.forEach(img => {
            if (img.offsetWidth > 0 && img.offsetHeight > 0) {
                let card = img;
                while (card && !card.classList.contains('search-item-card-wrapper-gallery')) {
                    card = card.parentElement;
                    if (!card) break;
                }
                if (card && !foundCards.has(card)) {
                    card.style.cssText += CHOICE_HIGHLIGHT_STYLE;
                    card.classList.add(CHOICE_HIGHLIGHT_CLASS);
                    foundCards.add(card);
                }
            }
        });
    }

    function highlightBundleTags() {
        const elements = document.querySelectorAll('*');
        elements.forEach(el => {
            if (
                el.textContent.trim() === 'Bundle deals' &&
                el.offsetWidth > 0 &&
                el.offsetHeight > 0
            ) {
                el.style.cssText += BUNDLE_HIGHLIGHT_STYLE;
                el.classList.add(BUNDLE_HIGHLIGHT_CLASS);
            }
        });
    }

    function highlightPremiumQualityTags() {
        const elements = document.querySelectorAll('*');
        elements.forEach(el => {
            if (el.childNodes.length === 1 && el.childNodes[0].nodeType === Node.TEXT_NODE) {
                const text = el.textContent.trim();
                if (text === 'Premium Quality' && el.offsetWidth > 0 && el.offsetHeight > 0) {
                    const span = document.createElement('span');
                    span.textContent = 'Premium Quality';
                    span.style.cssText = PREMIUM_HIGHLIGHT_STYLE;
                    span.classList.add(PREMIUM_HIGHLIGHT_CLASS);

                    el.textContent = '';
                    el.appendChild(span);
                }
            }
        });
    }

    function applyHighlights() {
        clearHighlights();
        highlightChoiceCards();
        highlightBundleTags();
        highlightPremiumQualityTags();
    }

    // ==================== Combined Functionality ====================
    function updateAll() {
        revealFullTitles();
        applyHighlights();
    }

    // Debounced update function
    let timeout;
    function debouncedUpdateAll() {
        clearTimeout(timeout);
        timeout = setTimeout(updateAll, 300);
    }

    // Set up mutation observer and events
    function setupObserversAndEvents() {
        const observer = new MutationObserver(debouncedUpdateAll);
        observer.observe(document.body, { childList: true, subtree: true });

        window.addEventListener('load', debouncedUpdateAll, { passive: true });
        document.addEventListener('scroll', debouncedUpdateAll, { passive: true });

        // URL change detection (SPA)
        let lastUrl = location.href;
        setInterval(() => {
            if (location.href !== lastUrl) {
                lastUrl = location.href;
                debouncedUpdateAll();
            }
        }, 1000);
    }

    // ==================== Initialization ====================
    function init() {
        console.log('[AliExpress Enhanced Listings v1.6] Initializing...');
        updateAll();
        setupObserversAndEvents();
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init, { once: true });
    } else {
        setTimeout(init, 500);
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址