此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/542296/1622763/TriX%20Addons%20Library.js
你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式
你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式
(我已經安裝了使用者樣式管理器,讓我安裝!)
// ==UserScript==
// @name TriX Addons Library
// @namespace https://github.com/YourUsername/TriX-Executor
// @version 1.0.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 URL to your hosted manifest file.
const ADDON_MANIFEST_URL = 'REPLACE_WITH_YOUR_GIST_URL'; // <-- IMPORTANT: REPLACE THIS
const AddonStore = {
init() {
this.injectCSS();
this.injectHTML();
this.attachEventListeners();
},
injectCSS() {
GM_addStyle(`
#trix-addons-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.7); z-index: 1000001; display: none; align-items: center; justify-content: center; backdrop-filter: blur(5px); animation: fadeIn 0.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,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: bold; 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: bold; color: white; padding: 8px 15px; cursor: pointer; border-radius: 5px; }
.addon-install-btn:disabled { background-color: #414868; border-color: #414868; color: #8c8c8c; cursor: not-allowed; }
`);
},
injectHTML() {
const modalHTML = `
<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', modalHTML);
},
attachEventListeners() {
document.querySelector('#trix-addons-modal .close-btn').addEventListener('click', () => this.hide());
},
show() {
const overlay = document.getElementById('trix-addons-modal-overlay');
if (!overlay) { // First time setup
this.init();
}
document.getElementById('trix-addons-modal-overlay').style.display = 'flex';
setTimeout(() => document.getElementById('trix-addons-modal-overlay').classList.add('visible'), 10);
this.fetchAndBuild();
},
hide() {
const overlay = document.getElementById('trix-addons-modal-overlay');
overlay.classList.remove('visible');
setTimeout(() => { overlay.style.display = 'none'; }, 300);
},
fetchAndBuild() {
const listEl = document.getElementById('addons-list');
listEl.innerHTML = '<p>Fetching latest addons...</p>';
GM.xmlHttpRequest({
method: "GET", url: ADDON_MANIFEST_URL,
onload: (response) => {
try {
const manifest = JSON.parse(response.responseText);
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); };
});
} catch (e) { listEl.innerHTML = '<p style="color:#f7768e;">Error: Could not parse addon manifest.</p>'; }
},
onerror: () => { listEl.innerHTML = '<p style="color:#f7768e;">Error: Could not fetch addon manifest.</p>'; }
});
},
install(name, url, btn) {
// Use the globally available TriX_Core object from the other library
TriX_Core.Executor.log(`Installing addon "${name}"...`, 'info');
btn.disabled = true;
btn.textContent = 'Installing...';
GM.xmlHttpRequest({
method: "GET", url: url,
onload: (response) => {
TriX_Core.Executor.execute(response.responseText);
TriX_Core.Executor.log(`Successfully installed "${name}"!`, 'info');
this.hide();
},
onerror: () => {
TriX_Core.Executor.log(`Failed to install "${name}". Could not fetch script.`, 'error');
btn.disabled = false;
btn.textContent = 'Install';
}
});
}
};
return AddonStore;
})();