@iasiv5/dsh-skins 1.5.18 → 1.5.20
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 +81 -0
- package/package.json +2 -2
package/lib/client.js
CHANGED
|
@@ -413,6 +413,9 @@
|
|
|
413
413
|
const [r, g, b, a] = channels;
|
|
414
414
|
return { r, g, b, a: Math.min(1, Math.max(0, a)) };
|
|
415
415
|
}
|
|
416
|
+
function sidebarPaintOrderCss(bodyAttribute) {
|
|
417
|
+
return `body[${datasetAttribute(bodyAttribute)}] [class*="_sidebarCol"]{position:relative;z-index:1}`;
|
|
418
|
+
}
|
|
416
419
|
function buildShellAlignmentCss(bodyAttribute, opaqueFills, backdrop) {
|
|
417
420
|
const body = `body[${datasetAttribute(bodyAttribute)}]`;
|
|
418
421
|
const scoped = `html[data-windows-titlebar] ${body}`;
|
|
@@ -446,6 +449,20 @@
|
|
|
446
449
|
}
|
|
447
450
|
return lines.join("\n");
|
|
448
451
|
}
|
|
452
|
+
function buildFullscreenBaseCss(bodyAttribute, opaqueFills) {
|
|
453
|
+
if (opaqueFills === null) return "";
|
|
454
|
+
const body = `body[${datasetAttribute(bodyAttribute)}]`;
|
|
455
|
+
const column = ' [data-rightbar-fullscreen] [class*="_rightbarCol"]';
|
|
456
|
+
const emptyPaneGuard = ':not(:has([class*="_paneBody"] > [class*="_empty"]))';
|
|
457
|
+
const openGate = '[data-sidebar-right-open="true"]';
|
|
458
|
+
const dockPanel = ` [data-sidebar-right-panel="fullscreen"]${openGate}${emptyPaneGuard}`;
|
|
459
|
+
const dockPane = ` [data-sidebar-right-panel="fullscreen"]${openGate} [data-dockkit-pane]${emptyPaneGuard}`;
|
|
460
|
+
return [
|
|
461
|
+
"/* dsh-skins fullscreen base (ADR-0020): solid skin-tone base while data-rightbar-fullscreen is set — the fullscreen dockkit PANE paints a translucent bg token where the official theme paints opaque white (DOM-dump evidence), so the pane is the bleed surface; solid matches the official look. Docked column untouched. Sheet rules gated on data-sidebar-right-open (stale-fullscreen collapse, ADR-0021 amendment 四) */",
|
|
462
|
+
`${body}${column},${body}${dockPanel},${body}${dockPane}{background-color:${opaqueFills.light}!important}`,
|
|
463
|
+
`${body}[data-ds-dark-theme]${column},${body}[data-ds-dark-theme]${dockPanel},${body}[data-ds-dark-theme]${dockPane}{background-color:${opaqueFills.dark}!important}`
|
|
464
|
+
].join("\n");
|
|
465
|
+
}
|
|
449
466
|
var PRODUCTION_FIELDS = /* @__PURE__ */ new Set([
|
|
450
467
|
"id",
|
|
451
468
|
"label",
|
|
@@ -626,6 +643,54 @@ ${darkSelector}{${dark.join(";")}}`;
|
|
|
626
643
|
return () => {
|
|
627
644
|
};
|
|
628
645
|
}
|
|
646
|
+
function refreshSkinStyleTags() {
|
|
647
|
+
if (typeof requestAnimationFrame !== "function" || typeof document === "undefined" || document.head?.querySelectorAll === void 0) return;
|
|
648
|
+
const tags = [...document.head.querySelectorAll('style[data-plugin-css^="dsh-skins/"]')];
|
|
649
|
+
if (tags.length === 0) return;
|
|
650
|
+
const saved = tags.map((tag) => ({ id: tag.dataset.pluginCss, content: tag.textContent }));
|
|
651
|
+
for (const tag of tags) tag.remove();
|
|
652
|
+
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
653
|
+
for (const { id, content } of saved) {
|
|
654
|
+
if (document.querySelector(`style[data-plugin-css="${id}"]`) !== null) continue;
|
|
655
|
+
const fresh = document.createElement("style");
|
|
656
|
+
fresh.dataset.plugin = "dsh-skins";
|
|
657
|
+
fresh.dataset.pluginCss = id;
|
|
658
|
+
fresh.textContent = content;
|
|
659
|
+
document.head.append(fresh);
|
|
660
|
+
}
|
|
661
|
+
}));
|
|
662
|
+
}
|
|
663
|
+
let rightPanelRepaintHookInstalled = false;
|
|
664
|
+
function installRightPanelRepaintHook() {
|
|
665
|
+
if (rightPanelRepaintHookInstalled || typeof MutationObserver !== "function") return;
|
|
666
|
+
if (typeof document === "undefined" || document.body === void 0 || document.body === null) return;
|
|
667
|
+
rightPanelRepaintHookInstalled = true;
|
|
668
|
+
const observer = new MutationObserver((records) => {
|
|
669
|
+
for (const record of records ?? []) {
|
|
670
|
+
const before = record.oldValue;
|
|
671
|
+
const after = record.target.getAttribute?.("data-sidebar-right-panel");
|
|
672
|
+
if (before !== "fullscreen" || after === "fullscreen") continue;
|
|
673
|
+
const tag = document.querySelector('style[data-plugin-css$=".fullscreen.css"]');
|
|
674
|
+
if (tag === null) continue;
|
|
675
|
+
const id = tag.dataset.pluginCss;
|
|
676
|
+
const content = tag.textContent;
|
|
677
|
+
tag.remove();
|
|
678
|
+
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
679
|
+
const fresh = document.createElement("style");
|
|
680
|
+
fresh.dataset.plugin = "dsh-skins";
|
|
681
|
+
fresh.dataset.pluginCss = id;
|
|
682
|
+
fresh.textContent = content;
|
|
683
|
+
document.head.append(fresh);
|
|
684
|
+
}));
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
observer.observe(document.body, {
|
|
688
|
+
subtree: true,
|
|
689
|
+
attributes: true,
|
|
690
|
+
attributeFilter: ["data-sidebar-right-panel"],
|
|
691
|
+
attributeOldValue: true
|
|
692
|
+
});
|
|
693
|
+
}
|
|
629
694
|
function buildEffects(skin, effects) {
|
|
630
695
|
if (!ctx) throw new Error("[dsh-skins] mount before apply");
|
|
631
696
|
const body = document.body;
|
|
@@ -676,6 +741,13 @@ ${darkSelector}{${dark.join(";")}}`;
|
|
|
676
741
|
const tag = styleTag(`dsh-skins/${skin.id}.css`, effects.staticCss);
|
|
677
742
|
stops.push(() => tag.remove());
|
|
678
743
|
}
|
|
744
|
+
{
|
|
745
|
+
const tag = styleTag(
|
|
746
|
+
`dsh-skins/${skin.id}.paintorder.css`,
|
|
747
|
+
sidebarPaintOrderCss(effects.bodyAttribute)
|
|
748
|
+
);
|
|
749
|
+
stops.push(() => tag.remove());
|
|
750
|
+
}
|
|
679
751
|
{
|
|
680
752
|
const fills = effects.tokenOverrides?.["--dsw-specific-sidebar-fill"] ?? null;
|
|
681
753
|
const lightFill = fills === null ? null : parseRgbaChannels(fills.light);
|
|
@@ -693,6 +765,11 @@ ${darkSelector}{${dark.join(";")}}`;
|
|
|
693
765
|
buildShellAlignmentCss(effects.bodyAttribute, opaqueFills, backdrop2)
|
|
694
766
|
);
|
|
695
767
|
stops.push(() => tag.remove());
|
|
768
|
+
const fullscreenCss = buildFullscreenBaseCss(effects.bodyAttribute, opaqueFills);
|
|
769
|
+
if (fullscreenCss !== "") {
|
|
770
|
+
const fullscreenTag = styleTag(`dsh-skins/${skin.id}.fullscreen.css`, fullscreenCss);
|
|
771
|
+
stops.push(() => fullscreenTag.remove());
|
|
772
|
+
}
|
|
696
773
|
}
|
|
697
774
|
const backdrop = backdropCss(effects);
|
|
698
775
|
if (backdrop !== null) {
|
|
@@ -784,6 +861,8 @@ ${darkSelector}{${dark.join(";")}}`;
|
|
|
784
861
|
mounted = { skin, effects, overrides, stop };
|
|
785
862
|
selectedId = skin.id;
|
|
786
863
|
announce(skin.id);
|
|
864
|
+
installRightPanelRepaintHook();
|
|
865
|
+
if (previous !== null) refreshSkinStyleTags();
|
|
787
866
|
return true;
|
|
788
867
|
}
|
|
789
868
|
function restorePrevious(previous, cause) {
|
|
@@ -2007,6 +2086,8 @@ ${references.join("\n")}`,
|
|
|
2007
2086
|
type: "button",
|
|
2008
2087
|
role: "menuitemradio",
|
|
2009
2088
|
"aria-checked": activeId === skin.id,
|
|
2089
|
+
"data-skin-id": skin.id,
|
|
2090
|
+
// ADR-0021/R21: stable hook for tests and headless verification — never match on localized labels
|
|
2010
2091
|
className: `dsh-skins-pop-card${activeId === skin.id ? " dsh-skins-pop-card-on" : ""}`,
|
|
2011
2092
|
onClick: () => {
|
|
2012
2093
|
if (personalizeId !== null && personalizeId !== skin.id) {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@iasiv5/dsh-skins",
|
|
3
3
|
"description": "DSH Web 皮肤插件:多套品牌皮肤侧栏热切换。",
|
|
4
4
|
"icon": "./icon.svg",
|
|
5
|
-
"version": "1.5.
|
|
5
|
+
"version": "1.5.20",
|
|
6
6
|
"homepage": "https://github.com/iasiv5/dsh-skins#readme",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"build": "node scripts/build-client.mjs",
|
|
83
83
|
"watch": "node scripts/build-client.mjs --watch",
|
|
84
84
|
"check:lockfile": "pnpm install --frozen-lockfile",
|
|
85
|
-
"test": "pnpm run build && node smoke-test.cjs && node --test tests/*.test.mjs",
|
|
85
|
+
"test": "pnpm run build && node smoke-test.cjs && node scripts/repro-stale-grid-paint.mjs --gate && node scripts/repro-fullscreen-collapse.mjs --gate && node --test tests/*.test.mjs",
|
|
86
86
|
"verify:readme": "node scripts/verify-readme-pairing.mjs",
|
|
87
87
|
"verify:bundle": "node scripts/verify-bundle-guard.mjs",
|
|
88
88
|
"verify:hooks": "node scripts/verify-upstream-hooks.mjs",
|