主题与字号从页面顶栏搬进设置页的「外观」,顶部导航加上预设入口。
顶栏那套汉堡菜单在每页都要单独挂载、样式也重复,收进设置页后只剩一处改;顺手把「整组都没有曾用型号」的配置组整组收起,不再留空卡片。
This commit is contained in:
+7
-116
@@ -1,13 +1,6 @@
|
||||
/* Apply the conversation workspace theme before first paint, then mount the
|
||||
* same theme controls in every secondary-page top bar. */
|
||||
/* Apply the workspace theme + UI font scale before first paint.
|
||||
* The controls live in 设置 → 外观 (see settings.js); pages only read storage. */
|
||||
(function () {
|
||||
var themes = [
|
||||
{ id: "paper", icon: "📖", name: "仿纸暖黄", description: "经典护眼" },
|
||||
{ id: "modern", icon: "✨", name: "现代清爽", description: "干净明快" },
|
||||
{ id: "dark", icon: "🌙", name: "夜间暗色", description: "黑底灰字" },
|
||||
{ id: "green", icon: "🍃", name: "豆沙绿", description: "自然疗愈" },
|
||||
];
|
||||
|
||||
function normalizeTheme(value) {
|
||||
return /^(paper|modern|dark|green)$/.test(value || "") ? value : "modern";
|
||||
}
|
||||
@@ -24,9 +17,6 @@
|
||||
var next = normalizeTheme(theme);
|
||||
document.documentElement.setAttribute("data-color-theme", next);
|
||||
document.documentElement.setAttribute("data-theme", next);
|
||||
try {
|
||||
localStorage.setItem("wa-color-theme", next);
|
||||
} catch (_) {}
|
||||
return next;
|
||||
}
|
||||
|
||||
@@ -34,9 +24,6 @@
|
||||
var next = normalizeScale(scale);
|
||||
document.documentElement.setAttribute("data-ui-font-scale", String(next));
|
||||
document.documentElement.style.setProperty("--ui-font-scale", String(next / 100));
|
||||
try {
|
||||
localStorage.setItem("wa-ui-font-scale", String(next));
|
||||
} catch (_) {}
|
||||
return next;
|
||||
}
|
||||
|
||||
@@ -47,105 +34,9 @@
|
||||
/* Storage may be unavailable; CSS defaults remain usable. */
|
||||
}
|
||||
|
||||
function mountThemeMenu() {
|
||||
var top = document.querySelector(".st-top");
|
||||
if (!top || top.querySelector(".st-theme-menu")) return;
|
||||
|
||||
var actions = document.createElement("div");
|
||||
actions.className = "st-top-actions";
|
||||
actions.innerHTML =
|
||||
'<details class="st-theme-menu">' +
|
||||
'<summary class="st-theme-summary" title="主题与字号" aria-label="主题与字号">' +
|
||||
'<span class="st-hamburger" aria-hidden="true"></span>' +
|
||||
"</summary>" +
|
||||
'<div class="st-theme-panel">' +
|
||||
'<div class="st-theme-label">主题</div>' +
|
||||
themes
|
||||
.map(function (item) {
|
||||
return (
|
||||
'<button type="button" class="st-theme-item" data-st-theme="' +
|
||||
item.id +
|
||||
'">' +
|
||||
'<span class="st-theme-icon" aria-hidden="true">' +
|
||||
item.icon +
|
||||
"</span>" +
|
||||
'<span class="st-theme-copy"><span class="st-theme-name">' +
|
||||
item.name +
|
||||
'</span><span class="st-theme-desc">' +
|
||||
item.description +
|
||||
"</span></span>" +
|
||||
"</button>"
|
||||
);
|
||||
})
|
||||
.join("") +
|
||||
'<div class="st-theme-separator"></div>' +
|
||||
'<div class="st-theme-label">字号</div>' +
|
||||
'<div class="st-font-scale" role="group" aria-label="字号">' +
|
||||
'<button type="button" data-st-scale="-1" aria-label="缩小字号">−</button>' +
|
||||
'<span class="st-font-value" aria-live="polite"></span>' +
|
||||
'<button type="button" data-st-scale="1" aria-label="放大字号">+</button>' +
|
||||
"</div></div></details>";
|
||||
top.appendChild(actions);
|
||||
|
||||
var menu = actions.querySelector(".st-theme-menu");
|
||||
var value = actions.querySelector(".st-font-value");
|
||||
|
||||
function sync() {
|
||||
var active = normalizeTheme(
|
||||
document.documentElement.getAttribute("data-color-theme"),
|
||||
);
|
||||
var scale = normalizeScale(
|
||||
document.documentElement.getAttribute("data-ui-font-scale"),
|
||||
);
|
||||
actions.querySelectorAll("[data-st-theme]").forEach(function (button) {
|
||||
var selected = button.getAttribute("data-st-theme") === active;
|
||||
button.classList.toggle("is-active", selected);
|
||||
button.setAttribute("aria-pressed", String(selected));
|
||||
});
|
||||
value.textContent = String(scale);
|
||||
var minus = actions.querySelector('[data-st-scale="-1"]');
|
||||
var plus = actions.querySelector('[data-st-scale="1"]');
|
||||
minus.disabled = scale <= 80;
|
||||
plus.disabled = scale >= 150;
|
||||
}
|
||||
|
||||
actions.addEventListener("click", function (event) {
|
||||
var themeButton = event.target.closest("[data-st-theme]");
|
||||
if (themeButton) {
|
||||
applyTheme(themeButton.getAttribute("data-st-theme"));
|
||||
sync();
|
||||
return;
|
||||
}
|
||||
var scaleButton = event.target.closest("[data-st-scale]");
|
||||
if (scaleButton) {
|
||||
var current = normalizeScale(
|
||||
document.documentElement.getAttribute("data-ui-font-scale"),
|
||||
);
|
||||
applyScale(current + Number(scaleButton.getAttribute("data-st-scale")) * 5);
|
||||
sync();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("click", function (event) {
|
||||
if (menu.open && !menu.contains(event.target)) menu.removeAttribute("open");
|
||||
});
|
||||
document.addEventListener("keydown", function (event) {
|
||||
if (event.key === "Escape" && menu.open) {
|
||||
menu.removeAttribute("open");
|
||||
menu.querySelector("summary").focus();
|
||||
}
|
||||
});
|
||||
window.addEventListener("storage", function (event) {
|
||||
if (event.key === "wa-color-theme") applyTheme(event.newValue);
|
||||
if (event.key === "wa-ui-font-scale") applyScale(event.newValue);
|
||||
sync();
|
||||
});
|
||||
sync();
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", mountThemeMenu, { once: true });
|
||||
} else {
|
||||
mountThemeMenu();
|
||||
}
|
||||
/* Keep tabs in sync when 设置 · 外观 changes the stored values. */
|
||||
window.addEventListener("storage", function (event) {
|
||||
if (event.key === "wa-color-theme") applyTheme(event.newValue);
|
||||
if (event.key === "wa-ui-font-scale") applyScale(event.newValue);
|
||||
});
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user