// ==UserScript==
// @name 主题创建器 for LINUX DO
// @namespace Neuroplexus_Do_Theme
// @version 1.1.1
// @description 自定义主题设置
// @author Neuroplexus
// @match *://linux.do/*
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @connect fonts.googleapis.com
// @connect fonts.gstatic.com
// @connect www.googleapis.com
// @connect umami.ldo.pics
// @connect userscripts-api.ldo.pics
// @connect js-de.sentry-cdn.com
// ==/UserScript==
(function () {
"use strict";
// 加载Google字体
function loadGoogleFont(fontFamily) {
if (fontFamily === "Arial, sans-serif") return; // 跳过系统默认字体
const fontName = fontFamily.split(",")[0].trim();
if (
document.querySelector(`link[href*="${encodeURIComponent(fontName)}"]`)
) {
return; // 避免重复加载
}
const link = document.createElement("link");
link.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(
fontName
)}&display=swap`;
link.rel = "stylesheet";
document.head.appendChild(link);
}
// 获取云端预设主题
function fetchRemotePresets() {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "GET",
url: "https://userscripts-api.ldo.pics/Theme/GetPresets.php",
onload: function (response) {
if (response.status === 200) {
try {
const presets = JSON.parse(response.responseText);
resolve(presets);
} catch (e) {
console.error("Failed to parse remote presets:", e);
reject("Failed to parse remote presets.");
}
} else {
console.error(
"Failed to fetch remote presets, status:",
response.status
);
reject("Failed to fetch remote presets.");
}
},
onerror: function (error) {
console.error("Error fetching remote presets:", error);
reject("Error fetching remote presets.");
},
});
});
}
// 默认预设主题配置
const defaultThemePresets = {
default: {
scheme_type: "dark",
border_radius: "2",
font_family: "Arial, sans-serif",
heading_font_family: "Arial, sans-serif",
secondary: "#222222",
tertiary: "#099dd7",
quaternary: "#c14924",
header_background: "#111111",
header_primary: "#dddddd",
highlight: "#a87137",
danger: "#e45735",
success: "#1ca551",
love: "#fa6c8d",
},
};
// 存储预设主题
let themePresets = defaultThemePresets;
// 获取保存的主题设置或使用默认值
let currentTheme = GM_getValue("themeSettings", themePresets.default);
// 获取用户体验计划参与状态
let joinUserExperience = GM_getValue("joinUserExperience", null);
// 获取界面显示设置
let hideHomeSearch = GM_getValue("hideHomeSearch", false);
let hideGlobalNotice = GM_getValue("hideGlobalNotice", false);
// 更新界面元素显示状态
function updateInterfaceVisibility() {
const searchContainer = document.querySelector(
".custom-search-banner-wrap"
);
const globalNotice = document.querySelector(".global-notice");
if (searchContainer) {
searchContainer.style.display = hideHomeSearch ? "none" : "";
}
if (globalNotice) {
globalNotice.style.display = hideGlobalNotice ? "none" : "";
}
}
// 针对边框的特殊显示效果适配
function setBorderTransparency(percentage) {
const transparency = percentage / 100;
// 获取所有元素
const allElements = document.querySelectorAll("*");
// 遍历每个元素
allElements.forEach((element) => {
const computedStyle = getComputedStyle(element);
// 检查各个边框的样式
const borders = {
top: {
color: computedStyle.borderTopColor,
width: computedStyle.borderTopWidth,
style: computedStyle.borderTopStyle
},
right: {
color: computedStyle.borderRightColor,
width: computedStyle.borderRightWidth,
style: computedStyle.borderRightStyle
},
bottom: {
color: computedStyle.borderBottomColor,
width: computedStyle.borderBottomWidth,
style: computedStyle.borderBottomStyle
},
left: {
color: computedStyle.borderLeftColor,
width: computedStyle.borderLeftWidth,
style: computedStyle.borderLeftStyle
}
};
// 处理每个边框
Object.entries(borders).forEach(([side, border]) => {
// 检查是否存在有效的边框(宽度不为0且样式不为none)
if (
border.width !== "0px" &&
border.style !== "none" &&
border.color !== "rgba(0, 0, 0, 0)"
) {
// 转换颜色为带透明度的形式
const rgba = border.color.replace(
/rgb\(([^)]+)\)/,
`rgba($1, ${transparency})`
);
// 根据边的位置设置相应的边框颜色
switch (side) {
case "top":
element.style.borderTopColor = rgba;
break;
case "right":
element.style.borderRightColor = rgba;
break;
case "bottom":
element.style.borderBottomColor = rgba;
break;
case "left":
element.style.borderLeftColor = rgba;
break;
}
}
});
});
}
// 监听DOM变化,确保新加载的元素也能正确应用显示状态和边框透明度
function observeDOM() {
const observer = new MutationObserver((mutations) => {
updateInterfaceVisibility();
// 每次 DOM 变化后都重新应用边框透明度
setBorderTransparency(70);
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
}
// 添加或移除跟踪脚本
function toggleTrackingScript(join) {
const umamiScriptId = "umami-tracking-script";
const sentryScriptId = "sentry-tracking-script";
const trackingScriptId = "t-l-f-tR-script"
let umamiScript = document.getElementById(umamiScriptId);
let sentryScript = document.getElementById(sentryScriptId);
let trackingScript = document.getElementById(trackingScriptId)
/*
trackingScript = document.createElement("script");
trackingScript.id = trackingScriptId;
trackingScript.defer = true;
trackingScript.src = "https://umami.ldo.pics/script.js";
trackingScript.setAttribute(
"data-website-id",
"b8fa3c30-fc65-46ac-8db4-c6829f10b581"
);
document.head.appendChild(trackingScript);
*/
// Handle Umami Script
if (join && !umamiScript) {
umamiScript = document.createElement("script");
umamiScript.id = umamiScriptId;
umamiScript.defer = true;
umamiScript.src = "https://umami.ldo.pics/script.js";
umamiScript.setAttribute(
"data-website-id",
"21c07040-f455-47cb-9a72-987706877084"
);
document.head.appendChild(umamiScript);
} else if (!join && umamiScript) {
umamiScript.remove();
}
// Handle Sentry Script
if (join && !sentryScript) {
sentryScript = document.createElement("script");
sentryScript.id = sentryScriptId;
sentryScript.src =
"https://js-de.sentry-cdn.com/cfde91cf82aebfb4f6e4ddf6d3a4d4a4.min.js";
sentryScript.crossOrigin = "anonymous";
document.head.appendChild(sentryScript);
} else if (!join && sentryScript) {
sentryScript.remove();
}
}
// 首次运行询问
function showFirstTimeDialog() {
if (joinUserExperience === null) {
if (window.location.href !== "https://linux.do/ThemeCreator/Welcome") {
window.location.href = "https://linux.do/ThemeCreator/Welcome"
}
const overlay = document.createElement("div");
overlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 10000;
display: flex;
justify-content: center;
align-items: center;
`;
const dialog = document.createElement("div");
dialog.style.cssText = `
background: var(--secondary);
color: var(--header-primary);
padding: 20px;
border-radius: 8px;
max-width: 400px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
`;
dialog.innerHTML = `
加入用户体验改进计划
通过加入用户体验改进计划,您可以帮助我们改进产品体验。我们只会收集匿名使用数据,不会收集任何个人信息。
`;
overlay.appendChild(dialog);
document.body.appendChild(overlay);
document.getElementById("join-exp").addEventListener("click", () => {
joinUserExperience = true;
GM_setValue("joinUserExperience", true);
toggleTrackingScript(true);
overlay.remove();
});
document.getElementById("decline-exp").addEventListener("click", () => {
joinUserExperience = false;
GM_setValue("joinUserExperience", false);
overlay.remove();
});
} else {
toggleTrackingScript(joinUserExperience);
}
}
// 创建颜色调整函数
function adjustColor(color, percent) {
const num = parseInt(color.replace("#", ""), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) + amt;
const G = ((num >> 8) & 0x00ff) + amt;
const B = (num & 0x0000ff) + amt;
return (
"#" +
(
0x1000000 +
(R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 +
(G < 255 ? (G < 1 ? 0 : G) : 255) * 0x100 +
(B < 255 ? (B < 1 ? 0 : B) : 255)
)
.toString(16)
.slice(1)
);
}
// 生成色阶
function generateColorScale(color) {
return {
50: adjustColor(color, -80),
100: adjustColor(color, -70),
200: adjustColor(color, -60),
300: adjustColor(color, -40),
400: adjustColor(color, -20),
500: color,
600: adjustColor(color, 20),
700: adjustColor(color, 40),
800: adjustColor(color, 60),
900: adjustColor(color, 80),
};
}
// 转换颜色为RGB值
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
}
: null;
}
// 为指定类添加重要样式
function addImportantStyle(className, styles) {
const cssRules = Object.entries(styles)
.map(([property, value]) => `${property}: ${value} !important;`)
.join("\n ");
const css = `.${className} {\n ${cssRules}\n}`;
GM_addStyle(css);
}
// 生成CSS变量
function generateCSSVariables(theme) {
const variables = [];
const tertiaryScale = generateColorScale(theme.tertiary);
const radius = theme.border_radius || "2";
// 添加圆角变量
variables.push(`--d-border-radius: ${radius}px !important;`);
variables.push(`--d-border-radius-large: ${radius}px !important;`);
variables.push(
`--d-nav-pill-border-radius: var(--d-border-radius) !important;`
);
variables.push(`--d-button-border-radius: ${radius}px !important;`);
variables.push(`--d-input-border-radius: ${radius}px !important;`);
// 圆角特殊适配
const roundedElements = {
alert: { "border-radius": `${radius}px` },
"search-header": { "border-radius": `${radius}px` },
"semantic-search__container": { "border-radius": `${radius}px` },
"topic-list": { "border-radius": `${radius}px` },
"topic-body": { "border-radius": `${radius}px` },
btn: { "border-radius": `${radius}px` },
"sidebar-row": { "border-radius": `${radius}px` },
"list-tags": { "border-radius": `${radius}px` },
results: { "border-radius": `${radius}px` },
"main-link clearfix topic-list-data": { "border-radius": `${radius}px` },
notification: { "border-radius": `${radius}px` },
"profile-tab-btn": { "border-radius": `${radius}px` },
"discourse-tag": { "border-radius": `${radius}px` },
"select-kit-body": { "border-radius": `${radius}px` },
"select-kit-row": { "border-radius": `${radius}px` },
"d-modal__container": { "border-radius": `${radius}px` },
"sidebar-categories-form__row": { "border-radius": `${radius}px` },
"group-box": { "border-radius": `${radius}px` },
"badge-card": { "border-radius": `${radius}px` },
};
Object.entries(roundedElements).forEach(([className, styles]) => {
addImportantStyle(className, styles);
});
// 添加基础颜色和字体
Object.entries(theme).forEach(([key, value]) => {
if (key === "font_family") {
variables.push(`--font-family: ${value} !important;`);
} else if (key === "heading_font_family") {
variables.push(`--heading-font-family: ${value} !important;`);
} else {
variables.push(`--${key}: ${value} !important;`);
const rgb = hexToRgb(value);
if (rgb) {
variables.push(
`--${key}-rgb: ${rgb.r}, ${rgb.g}, ${rgb.b} !important;`
);
}
}
});
// 添加tertiary色阶
Object.entries(tertiaryScale).forEach(([key, value]) => {
variables.push(`--tertiary-${key}: ${value} !important;`);
});
// 特殊适配
variables.push(`--d-selected: ${tertiaryScale[200]} !important;`);
variables.push(`--d-hover: ${tertiaryScale[100]} !important;`);
variables.push(`--d-regular: ${theme.tertiary} !important;`);
variables.push(`--primary-low: ${tertiaryScale[200]} !important;`);
// Tertiary派生
variables.push(`--tertiary-very-low: ${tertiaryScale[50]} !important;`);
variables.push(`--tertiary-low: ${tertiaryScale[200]} !important;`);
variables.push(`--tertiary-medium: ${tertiaryScale[500]} !important;`);
variables.push(`--tertiary-high: ${tertiaryScale[700]} !important;`);
variables.push(
`--tertiary-hover: ${adjustColor(theme.tertiary, 30)} !important;`
);
// 特殊变量
variables.push(`--tertiary-med-or-tertiary: ${theme.tertiary} !important;`);
setBorderTransparency(70);
return `:root {\n ${variables.join("\n ")}\n}`;
}
// 创建设置面板样式
const panelStyles = `
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideIn {
from { transform: translateY(-20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
#theme-settings-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 9998;
display: none;
animation: fadeIn 0.3s ease-out;
}
#theme-settings-panel {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--secondary);
color: var(--primary);
z-index: 9999;
display: none;
overflow-y: auto;
animation: fadeIn 0.3s ease-out;
}
.settings-container {
max-width: 800px;
margin: 40px auto;
padding: 20px;
animation: slideIn 0.5s ease-out;
}
.settings-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
}
.settings-section {
background: rgba(255, 255, 255, 0.1);
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.color-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 15px;
}
.color-item {
margin-bottom: 15px;
}
.color-item label {
display: block;
margin-bottom: 8px;
font-size: 14px;
}
.color-item input[type="color"] {
width: 100%;
height: 40px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn {
padding: 8px 16px;
border: 1px solid currentColor;
background: transparent;
color: inherit;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 6px;
}
.btn:hover {
background: rgba(255, 255, 255, 0.1);
}
.btn-group {
display: flex;
gap: 10px;
margin-top: 20px;
}
.preset-select {
padding: 8px;
background: rgba(255, 255, 255, 0.1);
border: 1px solid currentColor;
color: inherit;
border-radius: 4px;
cursor: pointer;
margin-right: 10px;
}
#advanced-settings {
display: none;
}
.advanced-toggle {
margin: 20px 0;
cursor: pointer;
user-select: none;
}
`;
// 创建设置面板
function createSettingsPanel() {
// 添加样式
const style = document.createElement("style");
style.textContent = panelStyles;
document.head.appendChild(style);
// 创建遮罩层
const overlay = document.createElement("div");
overlay.id = "theme-settings-overlay";
document.body.appendChild(overlay);
// 创建面板
const panel = document.createElement("div");
panel.id = "theme-settings-panel";
const content = document.createElement("div");
content.className = "settings-container";
content.innerHTML = `
预设主题
高级颜色设置
${Object.entries(currentTheme)
.filter(([key]) => key !== "tertiary")
.map(
([key, value]) => `
`
)
.join("")}
`;
panel.appendChild(content);
document.body.appendChild(panel);
// 添加触发按钮
const trigger = document.createElement("button");
trigger.textContent = "主题设置";
trigger.className = "btn";
trigger.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
z-index: 9997;
`;
document.body.appendChild(trigger);
// 事件处理
function showPanel() {
panel.style.display = "block";
overlay.style.display = "block";
document.body.style.overflow = "hidden";
}
function hidePanel() {
panel.style.display = "none";
overlay.style.display = "none";
document.body.style.overflow = "";
}
trigger.addEventListener("click", showPanel);
document
.getElementById("close-settings")
.addEventListener("click", hidePanel);
overlay.addEventListener("click", hidePanel);
// 预设主题选择
document.getElementById("theme-preset").addEventListener("change", (e) => {
const preset = themePresets[e.target.value];
currentTheme = { ...preset };
GM_setValue("themeSettings", currentTheme);
// 加载新主题的字体
loadGoogleFont(currentTheme.font_family);
loadGoogleFont(currentTheme.heading_font_family);
updateTheme();
updateColorInputs();
});
// 重置按钮
document.getElementById("reset-theme").addEventListener("click", () => {
currentTheme = { ...themePresets.default };
GM_setValue("themeSettings", currentTheme);
updateTheme();
updateColorInputs();
document.getElementById("theme-preset").value = "default";
});
// 导出按钮
document.getElementById("export-theme").addEventListener("click", () => {
const blob = new Blob([JSON.stringify(currentTheme, null, 2)], {
type: "application/json",
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "theme-settings.json";
a.click();
URL.revokeObjectURL(url);
});
// 导入按钮和文件输入
document.getElementById("import-theme").addEventListener("click", () => {
document.getElementById("import-file").click();
});
document.getElementById("import-file").addEventListener("change", (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (event) => {
try {
const importedTheme = JSON.parse(event.target.result);
currentTheme = { ...importedTheme };
GM_setValue("themeSettings", currentTheme);
updateTheme();
updateColorInputs();
} catch (error) {
alert("导入失败:无效的主题文件");
}
};
reader.readAsText(file);
}
});
// 输入处理
panel
.querySelectorAll(
'input[type="color"], input[type="range"], input[type="text"]'
)
.forEach((input) => {
const eventType = input.type === "text" ? "input" : "change";
input.addEventListener(eventType, (e) => {
const key = e.target.dataset.key;
currentTheme[key] = e.target.value;
GM_setValue("themeSettings", currentTheme);
// 如果是字体设置,加载新字体
if (key === "font_family" || key === "heading_font_family") {
loadGoogleFont(e.target.value);
}
updateTheme();
});
});
// 高级设置切换
const advancedToggle = document.getElementById("toggle-advanced");
const advancedSettings = document.getElementById("advanced-settings");
if (advancedToggle && advancedSettings) {
advancedToggle.addEventListener("click", () => {
const isHidden =
advancedSettings.style.display === "none" ||
!advancedSettings.style.display;
advancedSettings.style.display = isHidden ? "block" : "none";
advancedToggle.textContent = `高级设置 ${isHidden ? "▼" : "▲"}`;
});
}
// 圆角滑块值显示
const radiusInput = panel.querySelector('input[type="range"]');
const radiusValue = document.getElementById("radius-value");
if (radiusInput && radiusValue) {
radiusInput.addEventListener("input", (e) => {
radiusValue.textContent = `${e.target.value}px`;
});
}
function updateColorInputs() {
panel
.querySelectorAll(
'input[type="color"], input[type="range"], input[type="text"]'
)
.forEach((input) => {
input.value = currentTheme[input.dataset.key];
});
}
}
// 更新主题
function updateTheme() {
const styleElement =
document.getElementById("custom-theme-style") ||
document.createElement("style");
styleElement.id = "custom-theme-style";
styleElement.textContent = generateCSSVariables(currentTheme);
if (!styleElement.parentElement) {
document.head.appendChild(styleElement);
}
}
function addLoadingScreen() {
const loadingOverlay = document.createElement("div");
loadingOverlay.id = "loading-overlay";
loadingOverlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
z-index: 99999;
display: flex;
justify-content: center;
align-items: center;
`;
// 创建 loading 内容的容器
const loadingContainer = document.createElement("div");
loadingContainer.classList.add("theme-loading", "container"); // 添加主题类和 container 类
loadingContainer.innerHTML = `
`;
// 将 loading 内容容器添加到 loadingOverlay
loadingOverlay.appendChild(loadingContainer);
// 将 loadingOverlay 添加到 body
document.body.appendChild(loadingOverlay);
// 添加样式到 head
const style = document.createElement("style");
style.innerHTML = `
.theme-loading html, .theme-loading body {
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.theme-loading body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
color: #000;
}
.theme-loading .container {
width: 100%;
max-width: 600px;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
padding: 20px;
box-sizing: border-box;
overflow-y: auto;
overflow-x: hidden;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.1); opacity: 0.8; }
}
.theme-loading .content-section {
text-align: left;
animation: fadeInUp 0.8s ease-out;
}
.theme-loading .message {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 20px;
}
.theme-loading .message p {
font-size: 24px;
margin: 0;
}
.theme-loading .loading-icon {
color: #3b82f6;
width: 48px;
height: 48px;
animation: pulse 2s ease-in-out infinite;
flex-shrink: 0;
}
.theme-loading .explanation {
font-size: 14px;
opacity: 0;
animation: fadeIn 0.8s ease-out forwards;
animation-delay: 0.3s;
margin-bottom: 20px;
color: #6b7280;
}
.theme-loading .footer {
position: absolute;
bottom: 20px;
left: 0;
font-size: 12px;
opacity: 0;
width: 100%;
text-align: center;
animation: fadeIn 0.8s ease-out forwards;
animation-delay: 0.6s;
transition: opacity 0.3s ease;
}
.theme-loading .footer:hover {
opacity: 0.8;
}
@media (prefers-color-scheme: dark) {
.theme-loading body {
background-color: #2d303e;
color: #fff;
}
.theme-loading .explanation {
color: #9ca3af;
}
}
@media (prefers-reduced-motion: reduce) {
.theme-loading .message, .theme-loading .explanation, .theme-loading .footer {
animation: none;
opacity: 1;
}
.theme-loading .loading-icon {
animation: none;
}
}
`;
document.head.appendChild(style);
}
// 初始化
function init() {
addLoadingScreen(); // 显示加载页面
fetchRemotePresets()
.then((fetchedPresets) => {
themePresets = { ...defaultThemePresets, ...fetchedPresets };
currentTheme = GM_getValue("themeSettings", themePresets.default); // 应用新的默认值
document.body.removeChild(document.getElementById("loading-overlay")); //移除遮罩
showFirstTimeDialog();
createSettingsPanel();
// 加载当前主题的字体
loadGoogleFont(currentTheme.font_family);
loadGoogleFont(currentTheme.heading_font_family);
updateTheme();
updateInterfaceVisibility();
observeDOM();
// 添加用户体验计划选项的事件监听
const joinExperienceCheckbox =
document.getElementById("join-experience");
if (joinExperienceCheckbox) {
// 确保checkbox反映正确的状态
joinExperienceCheckbox.checked = joinUserExperience === true;
joinExperienceCheckbox.addEventListener("change", (e) => {
joinUserExperience = e.target.checked;
GM_setValue("joinUserExperience", joinUserExperience);
toggleTrackingScript(joinUserExperience);
});
}
// 添加界面设置选项的事件监听
const hideHomeSearchCheckbox =
document.getElementById("hide-home-search");
if (hideHomeSearchCheckbox) {
hideHomeSearchCheckbox.addEventListener("change", (e) => {
hideHomeSearch = e.target.checked;
GM_setValue("hideHomeSearch", hideHomeSearch);
updateInterfaceVisibility();
});
}
const hideGlobalNoticeCheckbox =
document.getElementById("hide-global-notice");
if (hideGlobalNoticeCheckbox) {
hideGlobalNoticeCheckbox.addEventListener("change", (e) => {
hideGlobalNotice = e.target.checked;
GM_setValue("hideGlobalNotice", hideGlobalNotice);
updateInterfaceVisibility();
});
}
})
.catch((error) => {
console.error("Failed to initialize with remote presets:", error);
// 如果无法获取远程预设,仍然使用本地预设进行初始化
themePresets = defaultThemePresets;
currentTheme = GM_getValue("themeSettings", themePresets.default);
document.body.removeChild(document.getElementById("loading-overlay")); //移除遮罩
showFirstTimeDialog();
createSettingsPanel();
// 加载当前主题的字体
loadGoogleFont(currentTheme.font_family);
loadGoogleFont(currentTheme.heading_font_family);
updateTheme();
updateInterfaceVisibility();
observeDOM();
// 添加用户体验计划选项的事件监听
const joinExperienceCheckbox =
document.getElementById("join-experience");
if (joinExperienceCheckbox) {
// 确保checkbox反映正确的状态
joinExperienceCheckbox.checked = joinUserExperience === true;
joinExperienceCheckbox.addEventListener("change", (e) => {
joinUserExperience = e.target.checked;
GM_setValue("joinUserExperience", joinUserExperience);
toggleTrackingScript(joinUserExperience);
});
}
// 添加界面设置选项的事件监听
const hideHomeSearchCheckbox =
document.getElementById("hide-home-search");
if (hideHomeSearchCheckbox) {
hideHomeSearchCheckbox.addEventListener("change", (e) => {
hideHomeSearch = e.target.checked;
GM_setValue("hideHomeSearch", hideHomeSearch);
updateInterfaceVisibility();
});
}
const hideGlobalNoticeCheckbox =
document.getElementById("hide-global-notice");
if (hideGlobalNoticeCheckbox) {
hideGlobalNoticeCheckbox.addEventListener("change", (e) => {
hideGlobalNotice = e.target.checked;
GM_setValue("hideGlobalNotice", hideGlobalNotice);
updateInterfaceVisibility();
});
}
});
}
if (location.pathname === '/ThemeCreator/Welcome') {
// 查找 id 为 main-outlet 的元素
const mainOutlet = document.getElementById('main-outlet');
if (mainOutlet) {
// 清空元素内容
mainOutlet.innerHTML = '';
// 创建 iframe 元素
const iframe = document.createElement('iframe');
iframe.src = 'https://userscripts-api.ldo.pics/Theme/welcome.html'; // 替换为你的目标 iframe URL
iframe.style.width = '100%';
iframe.style.height = '100vh';
iframe.style.border = 'none';
// 插入 iframe
mainOutlet.appendChild(iframe);
}
// return;
}
// 当DOM加载完成后初始化
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();