Greasy Fork

Greasy Fork is available in English.

TriX Addons Library

The Add-on Store UI and logic for the TriX Executor.

当前为 2025-07-11 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/542296/1622791/TriX%20Addons%20Library.js

// ==UserScript==
// @name        TriX Addons Library
// @namespace   https://github.com/YourUsername/TriX-Executor
// @version     1.1.0
// @description The Add-on Store UI and logic for the TriX Executor.
// @author      You
// @license     MIT
// ==/UserScript==

const TriX_Addons = (function() {
    'use strict';
    
    // --- The real URL to your hosted manifest file ---
    const ADDON_MANIFEST_URL = 'https://raw.githubusercontent.com/COURTESYCOIL/TrixScripts/refs/heads/main/trix%20addons';

    const AddonStore = {
        isInitialized: false,
        manifestCache: null,

        // Called by the UI library on startup to pre-fetch the manifest
        init() {
            this.fetchAndCacheManifest();
        },

        fetchAndCacheManifest() {
            if (!ADDON_MANIFEST_URL.startsWith('https://')) {
                console.error('[TriX Addons] Manifest URL is not set. Add-on store will not work.');
                this.manifestCache = { error: true, message: "Manifest URL not configured by developer." };
                return;
            }
            GM.xmlHttpRequest({
                method: "GET", url: ADDON_MANIFEST_URL,
                onload: (response) => {
                    try {
                        this.manifestCache = JSON.parse(response.responseText);
                        console.log('[TriX Addons] Manifest pre-loaded and cached.');
                    } catch (e) {
                        this.manifestCache = { error: true, message: "Could not parse addon manifest." };
                    }
                },
                onerror: () => {
                    this.manifestCache = { error: true, message: "Could not fetch addon manifest." };
                }
            });
        },
        
        show() {
            // Lazy-init the UI only when it's first opened
            if (!this.isInitialized) {
                this.injectCSS();
                this.injectHTML();
                this.attachEventListeners();
                this.isInitialized = true;
            }
            const overlay = document.getElementById('trix-addons-modal-overlay');
            overlay.style.display = 'flex';
            setTimeout(() => overlay.classList.add('visible'), 10);
            this.buildUI();
        },

        buildUI() {
            const listEl = document.getElementById('addons-list');
            if (this.manifestCache) {
                if (this.manifestCache.error) {
                    listEl.innerHTML = `<p style="color:#f7768e;">Error: ${this.manifestCache.message}</p>`;
                } else {
                    this.buildCards(this.manifestCache);
                }
            } else {
                // Fallback if the pre-fetch isn't done yet
                listEl.innerHTML = '<p>Fetching latest addons...</p>';
                this.fetchAndCacheManifest(); 
                setTimeout(() => this.buildUI(), 1000);
            }
        },

        buildCards(manifest) {
            const listEl = document.getElementById('addons-list');
            listEl.innerHTML = '';
            manifest.addons.forEach(addon => {
                const card = document.createElement('div');
                card.className = 'addon-card';
                card.innerHTML = `<h4>${addon.name}</h4><p>${addon.description}</p><div class="addon-controls"><select class="addon-version-select" id="select-${addon.id}"><option value="">Select a version...</option></select><button class="addon-install-btn" id="install-${addon.id}" disabled>Install</button></div>`;
                listEl.appendChild(card);
                const selectEl = document.getElementById(`select-${addon.id}`);
                const installBtn = document.getElementById(`install-${addon.id}`);
                addon.versions.forEach(v => { const o=document.createElement('option'); o.value=v.url; o.textContent=v.version; selectEl.appendChild(o); });
                selectEl.onchange = () => { installBtn.disabled = !selectEl.value; };
                installBtn.onclick = () => { this.install(addon.name, selectEl.value, installBtn); };
            });
        },
        
        // --- The rest of the functions are minified as they are unchanged ---
        injectCSS:function(){GM_addStyle(`#trix-addons-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.7);z-index:1000001;display:none;align-items:center;justify-content:center;backdrop-filter:blur(5px);animation:fadeIn .3s ease}@keyframes fadeIn{from{opacity:0}to{opacity:1}}#trix-addons-modal{background-color:var(--trix-bg-secondary,#2d2d2d);width:700px;max-width:90vw;max-height:80vh;border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.5);display:flex;flex-direction:column;transform:scale(.95);opacity:0;transition:transform .3s ease,opacity .3s ease}#trix-addons-modal-overlay.visible #trix-addons-modal{transform:scale(1);opacity:1}.addons-header{padding:15px 20px;font-size:20px;font-weight:700;border-bottom:1px solid var(--trix-border-color,#4a4a4a);display:flex;justify-content:space-between;align-items:center;color:var(--trix-text-primary,#d4d4d4)}.addons-header .close-btn{font-size:24px;cursor:pointer;color:var(--trix-text-secondary,#8c8c8c);transition:color .2s}.addons-header .close-btn:hover{color:var(--trix-accent-color,#00aeff)}#addons-list{padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:15px}.addon-card{background-color:var(--trix-bg-primary,#1e1e1e);border:1px solid var(--trix-border-color,#4a4a4a);border-radius:6px;padding:15px;display:flex;flex-direction:column;gap:10px}.addon-card h4{margin:0;color:var(--trix-accent-color,#00aeff)}.addon-card p{margin:0;font-size:14px;color:var(--trix-text-secondary,#8c8c8c)}.addon-controls{display:flex;gap:10px;margin-top:10px}.addon-version-select{flex-grow:1;background-color:var(--trix-bg-tertiary,#3c3c3c);border:1px solid var(--trix-border-color,#4a4a4a);color:var(--trix-text-primary,#d4d4d4);padding:8px 12px;border-radius:5px}.addon-install-btn{background-color:#28a745;border:1px solid #1c7430;font-weight:700;color:#fff;padding:8px 15px;cursor:pointer;border-radius:5px}.addon-install-btn:disabled{background-color:#414868;border-color:#414868;color:#8c8c8c;cursor:not-allowed}`)},
        injectHTML:function(){const e=`<div id="trix-addons-modal-overlay"><div id="trix-addons-modal"><div class="addons-header"><span>Add-on Store</span><span class="close-btn">✕</span></div><div id="addons-list"><p>Loading addons...</p></div></div></div>`;document.body.insertAdjacentHTML("beforeend",e)},
        attachEventListeners:function(){document.querySelector("#trix-addons-modal .close-btn").addEventListener("click",()=>this.hide())},
        hide:function(){const e=document.getElementById("trix-addons-modal-overlay");e.classList.remove("visible"),setTimeout(()=>{e.style.display="none"},300)},
        install:function(e,t,i){TriX_Core.Executor.log(`Installing addon "${e}"...`,"info"),i.disabled=!0,i.textContent="Installing...",GM.xmlHttpRequest({method:"GET",url:t,onload:t=>{TriX_Core.Executor.execute(t.responseText),TriX_Core.Executor.log(`Successfully installed "${e}"!`,"info"),this.hide()},onerror:()=>{TriX_Core.Executor.log(`Failed to install "${e}". Could not fetch script.`,"error"),i.disabled=!1,i.textContent="Install"}})}
    };
    return AddonStore;
})();