dsh-folia 3.7.1 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +26 -1
- package/lib/routes/skins.js +21 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -16314,7 +16314,7 @@ window.__ModuleLoader__.load({
|
|
|
16314
16314
|
setNote({ kind: "ok", text: weT("已应用:「") + label + weT("」—— 皮肤中心已收敛(无需刷新)") });
|
|
16315
16315
|
return;
|
|
16316
16316
|
}
|
|
16317
|
-
if (tries >=
|
|
16317
|
+
if (tries >= 9) { // 约 11 秒:host 会先写 null 再写目标 id(900ms),引擎每 2s 轮询一次
|
|
16318
16318
|
clearInterval(pollRef.current); pollRef.current = null;
|
|
16319
16319
|
setNote({
|
|
16320
16320
|
kind: "err",
|
|
@@ -25729,6 +25729,27 @@ window.__ModuleLoader__.load({
|
|
|
25729
25729
|
try { return skinYielded === true; } catch { return false; }
|
|
25730
25730
|
}
|
|
25731
25731
|
|
|
25732
|
+
/**
|
|
25733
|
+
* 让路期间把**整张插件样式表**关掉。
|
|
25734
|
+
*
|
|
25735
|
+
* 为什么必须关整张:皮肤是一套完整的外观(自己的底色、圆角、字体色、边框)。我们的
|
|
25736
|
+
* `styles-base.js` 给应用外壳铺透明/玻璃/自定义配色,选择器落在同一批元素上,于是皮肤
|
|
25737
|
+
* 的规则被我们盖掉 —— 表现就是"皮肤显示不全,关掉插件就完整"。让路态此前只关了玻璃
|
|
25738
|
+
* 效果族(`data-we-*` 属性门控),**样式表本体一直在**,所以这个洞一直存在。
|
|
25739
|
+
*
|
|
25740
|
+
* 用 `sheet.disabled` 而不是摘 `<style>`:摘了再插会触发整页重排;disabled 是零成本开关,
|
|
25741
|
+
* 退出让路时立刻原样恢复。
|
|
25742
|
+
*/
|
|
25743
|
+
function syncPluginCssForSkin() {
|
|
25744
|
+
try {
|
|
25745
|
+
const tag = document.querySelector('style[data-plugin-css="dsh-folia/styles-v3"]');
|
|
25746
|
+
if (tag === null) return;
|
|
25747
|
+
const off = skinYieldActive() === true;
|
|
25748
|
+
if (tag.sheet) tag.sheet.disabled = off;
|
|
25749
|
+
else tag.disabled = off;
|
|
25750
|
+
} catch { /* 拿不到 sheet(还在解析 / 被 CSP 拦)就跳过,不影响其它门控 */ }
|
|
25751
|
+
}
|
|
25752
|
+
|
|
25732
25753
|
/** 皮肤上台 ⇒ 退场(幂等)。 */
|
|
25733
25754
|
function enterSkinYield(reason) {
|
|
25734
25755
|
if (skinYielded) return;
|
|
@@ -25743,6 +25764,7 @@ window.__ModuleLoader__.load({
|
|
|
25743
25764
|
applySelection(""); // 清层:url=null ⇒ syncLayers 摘层 / 遮罩 / data-we-wallpaper
|
|
25744
25765
|
persistSelection();
|
|
25745
25766
|
applyEffects(); // 让路态里玻璃门控整族摘除
|
|
25767
|
+
syncPluginCssForSkin(); // 连同整张样式表一起让位 —— 否则皮肤被我们的外框盖住(显示不全)
|
|
25746
25768
|
emit();
|
|
25747
25769
|
reportClientDiag("skin-yield", "enter · " + reason + " · restore=" + (skinYieldMemory.id || "-"));
|
|
25748
25770
|
}
|
|
@@ -25765,6 +25787,7 @@ window.__ModuleLoader__.load({
|
|
|
25765
25787
|
setSetting("skinYieldRestoreRotation", false);
|
|
25766
25788
|
persistSelection();
|
|
25767
25789
|
applyEffects();
|
|
25790
|
+
syncPluginCssForSkin(); // 皮肤退场:把我们的样式表原样开回来
|
|
25768
25791
|
emit();
|
|
25769
25792
|
reportClientDiag("skin-yield", "exit · " + reason);
|
|
25770
25793
|
}
|
|
@@ -25884,6 +25907,7 @@ window.__ModuleLoader__.load({
|
|
|
25884
25907
|
rotationEnabled: rid ? selection.skinYieldRestoreRotation === true : selection.rotationEnabled === true,
|
|
25885
25908
|
};
|
|
25886
25909
|
applyEffects(); // 认领即刻摘玻璃门控(首次 applyEffects 可能已经跑过)
|
|
25910
|
+
syncPluginCssForSkin(); // 启动即认领时也要让出样式表:否则一开机皮肤就被外框盖着
|
|
25887
25911
|
reportClientDiag("skin-yield", "adopt · install/dom");
|
|
25888
25912
|
} else if (!document.documentElement.hasAttribute("data-dsh-skin") && !selection.id
|
|
25889
25913
|
&& String(selection.skinYieldRestoreId || "")) {
|
|
@@ -25905,6 +25929,7 @@ window.__ModuleLoader__.load({
|
|
|
25905
25929
|
try { unsubAdopt(); } catch { /* ignore */ }
|
|
25906
25930
|
skinYielded = false;
|
|
25907
25931
|
skinYieldMemory = null;
|
|
25932
|
+
syncPluginCssForSkin(); // 清理后让路态清零 ⇒ 样式表恢复
|
|
25908
25933
|
};
|
|
25909
25934
|
}
|
|
25910
25935
|
|
package/lib/routes/skins.js
CHANGED
|
@@ -552,12 +552,31 @@ export function registerSkinRoutes(webServer, c) {
|
|
|
552
552
|
doc = JSON.parse(readFileSync(file, 'utf8')) || {};
|
|
553
553
|
} catch { /* 文件不存在 / 坏掉 ⇒ 用最小骨架重建 */ }
|
|
554
554
|
// 只改 `active`:background 那一段是皮肤中心自己的设置,一个字都不能丢。
|
|
555
|
+
const previous = typeof doc.active === 'string' ? doc.active : null;
|
|
555
556
|
doc.active = id;
|
|
556
557
|
if (typeof doc.initialized !== 'boolean') doc.initialized = true;
|
|
557
558
|
try {
|
|
559
|
+
// ⚠️ 这里必须先写一次 `null`,再写目标 id —— 不是画蛇添足。
|
|
560
|
+
//
|
|
561
|
+
// 皮肤中心客户端的收敛逻辑(lib/client.js,watchPersistedSelection):
|
|
562
|
+
//
|
|
563
|
+
// applied = persisted === undefined ? undefined
|
|
564
|
+
// : (stamp === null || stamp === persisted ? persisted : undefined);
|
|
565
|
+
// // tick: next === applied ⇒ return ← 相同就永远不动
|
|
566
|
+
//
|
|
567
|
+
// 页面启动时若 `html[data-dsh-skin]` 为空,它会把**持久化的值直接当成已应用**。
|
|
568
|
+
// 于是我们写一个"和它记录里一样"的 id 时,轮询认为没有变化,皮肤永远不上。
|
|
569
|
+
// 先归零(写 null)能让它收敛到"无皮肤",紧接着写目标 id 就必然是一次变化,
|
|
570
|
+
// 轮询一定会应用 —— 这是绕开它这个初始化的唯一办法,且完全走它自己的路径。
|
|
571
|
+
if (previous === id) {
|
|
572
|
+
doc.active = null;
|
|
573
|
+
writeFileSync(file, JSON.stringify(doc, null, 2) + '\n');
|
|
574
|
+
await new Promise((r) => setTimeout(r, 900));
|
|
575
|
+
doc.active = id;
|
|
576
|
+
}
|
|
558
577
|
writeFileSync(file, JSON.stringify(doc, null, 2) + '\n');
|
|
559
|
-
note('[skins] activated ' + id);
|
|
560
|
-
sendJson(res, 200, { ok: true, id, active: id, restartRequired:
|
|
578
|
+
note('[skins] activated ' + id + (previous === id ? ' (after clearing the same id)' : ''));
|
|
579
|
+
sendJson(res, 200, { ok: true, id, active: id, restartRequired: false, nudged: previous === id });
|
|
561
580
|
} catch (err) {
|
|
562
581
|
sendJson(res, 500, { ok: false, error: 'write-failed', detail: String(err && err.message || err) });
|
|
563
582
|
}
|