dsh-any-background 0.3.8 → 0.3.10
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/README.md +17 -29
- package/README.zh.md +16 -28
- package/lib/client.js +310 -104
- package/lib/client.js.map +1 -1
- package/lib/index.js +6 -0
- package/package.json +11 -10
package/lib/client.js
CHANGED
|
@@ -57,6 +57,12 @@ window.__ModuleLoader__.load({
|
|
|
57
57
|
uiProduced: "产出物/高亮内容",
|
|
58
58
|
uiHeader: "顶栏选项",
|
|
59
59
|
uiHeaderBar: "标题栏",
|
|
60
|
+
captionInkLabel: "标题条带文字",
|
|
61
|
+
captionInkHint: "桌面端顶部那条标题带上的文字(原生「应用 / 编辑」菜单与侧栏开合按钮)由谁上色。条带是侧栏材质压在壁纸上的结果,两者可能一个深一个浅。",
|
|
62
|
+
captionInkAuto: "自动",
|
|
63
|
+
captionInkTheme: "跟随主题",
|
|
64
|
+
captionInkWhite: "始终白色",
|
|
65
|
+
captionInkBlack: "始终黑色",
|
|
60
66
|
fontPageTitle: "字体与描边",
|
|
61
67
|
fontTitle: "自定义字体",
|
|
62
68
|
fontHint: "支持 ttf/otf/woff/woff2 字体文件(上限 100MB),将应用到整个界面的文字;代码块的等宽字体保持不变。中文字体通常有几十 MB,首次上传与刷新加载需要片刻",
|
|
@@ -249,6 +255,12 @@ window.__ModuleLoader__.load({
|
|
|
249
255
|
uiProduced: "Produced / highlights",
|
|
250
256
|
uiHeader: "Header popovers",
|
|
251
257
|
uiHeaderBar: "Header bar",
|
|
258
|
+
captionInkLabel: "Caption strip text",
|
|
259
|
+
captionInkHint: "Who paints the text on the desktop caption strip — the native 「应用 / 编辑」 menu bar and the sidebar toggle. The strip is the sidebar material over the wallpaper, so it can end up on the opposite side of the theme.",
|
|
260
|
+
captionInkAuto: "Auto",
|
|
261
|
+
captionInkTheme: "Follow theme",
|
|
262
|
+
captionInkWhite: "Always white",
|
|
263
|
+
captionInkBlack: "Always black",
|
|
252
264
|
fontPageTitle: "Font & outline",
|
|
253
265
|
fontTitle: "Custom font",
|
|
254
266
|
fontHint: "Accepts ttf/otf/woff/woff2 files (up to 100MB) and applies them to the whole interface; code blocks keep their monospace stack. CJK fonts routinely span tens of MB, so the first upload and each reload take a moment",
|
|
@@ -518,6 +530,7 @@ window.__ModuleLoader__.load({
|
|
|
518
530
|
producedOpacity: .5,
|
|
519
531
|
headerOpacity: .5,
|
|
520
532
|
headerBarOpacity: .5,
|
|
533
|
+
captionInk: "auto",
|
|
521
534
|
profiles: [],
|
|
522
535
|
rotation: {
|
|
523
536
|
enabled: false,
|
|
@@ -539,6 +552,17 @@ window.__ModuleLoader__.load({
|
|
|
539
552
|
activeProfile: null
|
|
540
553
|
};
|
|
541
554
|
const clamp01 = (n, def) => typeof n === "number" ? Math.min(1, Math.max(0, n)) : def;
|
|
555
|
+
/** One place decides what a stored / adopted 「标题栏文字」 value means: anything the
|
|
556
|
+
* host half or an older config file did not name is `auto`, which is 0.3.8's behaviour. */
|
|
557
|
+
const CAPTION_INK_MODES = [
|
|
558
|
+
"auto",
|
|
559
|
+
"theme",
|
|
560
|
+
"white",
|
|
561
|
+
"black"
|
|
562
|
+
];
|
|
563
|
+
function adoptCaptionInk(v) {
|
|
564
|
+
return CAPTION_INK_MODES.includes(v) ? v : DEFAULT_CONFIG.captionInk;
|
|
565
|
+
}
|
|
542
566
|
let cfg = {
|
|
543
567
|
...DEFAULT_CONFIG,
|
|
544
568
|
opacities: { ...DEFAULT_CONFIG.opacities },
|
|
@@ -732,6 +756,10 @@ window.__ModuleLoader__.load({
|
|
|
732
756
|
function rHeaderBarOpacity() {
|
|
733
757
|
return clamp01(cfg.headerBarOpacity, DEFAULT_CONFIG.headerBarOpacity);
|
|
734
758
|
}
|
|
759
|
+
/** Who owns the desktop caption strip's chrome ink — see `CaptionInkMode`. */
|
|
760
|
+
function rCaptionInk() {
|
|
761
|
+
return adoptCaptionInk(cfg.captionInk);
|
|
762
|
+
}
|
|
735
763
|
function rBgState() {
|
|
736
764
|
return cfg.bgState;
|
|
737
765
|
}
|
|
@@ -968,6 +996,7 @@ window.__ModuleLoader__.load({
|
|
|
968
996
|
producedOpacity: clamp01(c.producedOpacity, DEFAULT_CONFIG.producedOpacity),
|
|
969
997
|
headerOpacity: clamp01(c.headerOpacity, DEFAULT_CONFIG.headerOpacity),
|
|
970
998
|
headerBarOpacity: clamp01(c.headerBarOpacity, DEFAULT_CONFIG.headerBarOpacity),
|
|
999
|
+
captionInk: adoptCaptionInk(c.captionInk),
|
|
971
1000
|
profiles: adoptProfiles(c.profiles),
|
|
972
1001
|
rotation: adoptRotation(c.rotation),
|
|
973
1002
|
schedule: adoptSchedule(c.schedule),
|
|
@@ -1058,6 +1087,10 @@ window.__ModuleLoader__.load({
|
|
|
1058
1087
|
{
|
|
1059
1088
|
channel: "0.2.1",
|
|
1060
1089
|
release: "0.2.1-rc.2"
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
channel: "0.2.1",
|
|
1093
|
+
release: "0.2.1-rc.3"
|
|
1061
1094
|
}
|
|
1062
1095
|
];
|
|
1063
1096
|
const UNKNOWN_HOST_INFO = {
|
|
@@ -1304,8 +1337,9 @@ window.__ModuleLoader__.load({
|
|
|
1304
1337
|
* painting element. A 15th file names the same token without consuming it:
|
|
1305
1338
|
* `ui-theme/src/styles/gradient-shadow-text.css` DECLARES it on `body` —
|
|
1306
1339
|
* `blur(40px) saturate(150%)`, no media query — which is exactly why writing the
|
|
1307
|
-
* token on a menu with a `none` fallback deletes a frost the host always had
|
|
1308
|
-
*
|
|
1340
|
+
* token on a menu with a `none` fallback deletes a frost the host always had.
|
|
1341
|
+
* That is now the intended reading of a 0 on the menu blur sliders — see the note
|
|
1342
|
+
* above `popoverBlurRule` in `wallpaper.ts`. `MenuSurface.tsx` / `.module.css` are
|
|
1309
1343
|
* byte-identical from rc.2 through `0.2.1-alpha.2`, and the consumer set moved only
|
|
1310
1344
|
* in line numbers (the same 15 files at every tag in the table, checked per tag).
|
|
1311
1345
|
*
|
|
@@ -1533,7 +1567,7 @@ window.__ModuleLoader__.load({
|
|
|
1533
1567
|
//#region src/client/host-compat/versions/v0-2-1/adapter.ts
|
|
1534
1568
|
/**
|
|
1535
1569
|
* Adapter for the DSH `0.2.1` patch line, verified at `0.2.1-alpha.1`,
|
|
1536
|
-
* `alpha.2`, `alpha.3`, `alpha.4`, `alpha.5`, `rc.1` and `rc.
|
|
1570
|
+
* `alpha.2`, `alpha.3`, `alpha.4`, `alpha.5`, `rc.1`, `rc.2` and `rc.3`.
|
|
1537
1571
|
*
|
|
1538
1572
|
* A new MINOR line opened with a prerelease, and the answer is the `0.2.0-rc.2`
|
|
1539
1573
|
* folder's — which is a statement this file has to earn, because "same as the
|
|
@@ -1557,6 +1591,34 @@ window.__ModuleLoader__.load({
|
|
|
1557
1591
|
* · `TextShimmer` still marks its root `data-shimmer`, so the stroke exemption
|
|
1558
1592
|
* written for rc.1 stands.
|
|
1559
1593
|
*
|
|
1594
|
+
* Re-checked at `0.2.1-rc.3` (`git diff rc.2 rc.3` on every file above), the
|
|
1595
|
+
* facts hold untouched: `design-platform.css`, both menu stylesheets and
|
|
1596
|
+
* `MenuGroup.tsx` byte-identical; `SidebarRight.module.css`, `TabLayout.tsx`,
|
|
1597
|
+
* `base.css`, `gradient-shadow-text.css`, `AppFrame.*`, `InlineEditor.module.css`,
|
|
1598
|
+
* `TextShimmer`, `JobListAction`, `TaskMenu`, `scoped-slots` and
|
|
1599
|
+
* `PluginManagerPage.tsx` all unchanged, and the five header slot keys stand.
|
|
1600
|
+
* What rc.3 did move, and why none of it needs a fact from this folder:
|
|
1601
|
+
* · `ui-primitives/Menu.tsx` is ADDITIVE — a `current` prop that renders
|
|
1602
|
+
* `aria-current="page"` and a `minWidthFromAnchor` switch that sets a
|
|
1603
|
+
* `min-width` style in portal mode. No stylesheet moved with it
|
|
1604
|
+
* (`MenuSurface.module.css` is byte-identical), so the menu paint and the
|
|
1605
|
+
* frost stay exactly where the facts say.
|
|
1606
|
+
* · the guide (`GuideBody.tsx`) and the sidebar panel list (`SidebarRoot.tsx`)
|
|
1607
|
+
* grow pin state and a More menu AROUND the existing registrations — guide
|
|
1608
|
+
* entries still arrive through `useGuideEntries`, panels through
|
|
1609
|
+
* `selectPanel`, and the new menus mount empty until something registers
|
|
1610
|
+
* into their `*.actions` slots, which this plugin does not. The tab
|
|
1611
|
+
* registry itself (`shell/`), which `native-tab.tsx` speaks to, is untouched.
|
|
1612
|
+
* · the session header's View tab row gained its own More menu
|
|
1613
|
+
* (`conversation.session.header.views.actions` slot). It mounts through
|
|
1614
|
+
* `<Menu … portal>` to `document.body`, so `header-tag.ts` already claims
|
|
1615
|
+
* it through the portaled arm — the trigger sits in the header and reports
|
|
1616
|
+
* `aria-expanded`, which is all that arm asks. The five in-place header
|
|
1617
|
+
* slot anchors are unchanged.
|
|
1618
|
+
* · `ConversationRoot.module.css` re-laid the View tab row (wrap, gaps, the
|
|
1619
|
+
* More launcher's classes). Layout inside the header, not a surface the
|
|
1620
|
+
* plugin styles by these class names.
|
|
1621
|
+
*
|
|
1560
1622
|
* Re-checked again across the rest of the line (`alpha.3` … `rc.2`, `git diff
|
|
1561
1623
|
* <tag> rc.2` on every file above): the menu token contract, both menu stylesheets
|
|
1562
1624
|
* (`MenuSurface`, `MenuGroup`), `gradient-shadow-text.css` / `base.css`,
|
|
@@ -1648,7 +1710,7 @@ window.__ModuleLoader__.load({
|
|
|
1648
1710
|
}
|
|
1649
1711
|
function createAdapter$1(host) {
|
|
1650
1712
|
return {
|
|
1651
|
-
id: "0.2.1-alpha.1…rc.
|
|
1713
|
+
id: "0.2.1-alpha.1…rc.3",
|
|
1652
1714
|
channel: "0.2.1",
|
|
1653
1715
|
host,
|
|
1654
1716
|
panelFragments: panelFragments$1,
|
|
@@ -2161,16 +2223,18 @@ window.__ModuleLoader__.load({
|
|
|
2161
2223
|
* A header dropdown can only be open while its trigger reports
|
|
2162
2224
|
* `aria-expanded="true"`, and opening one is what mounts the popover. So a
|
|
2163
2225
|
* popover tag is maintained as: "there is at least one expanded header trigger,
|
|
2164
|
-
* AND this popover is
|
|
2226
|
+
* AND this popover is a header candidate" — see `isHeaderSurface` for the two
|
|
2227
|
+
* shapes that qualify (portaled to `<body>`, or mounted inside one of the
|
|
2228
|
+
* header's own slot anchors) and for what stays foreign. Popovers are only ever
|
|
2165
2229
|
* tagged/released on a change of that combined state, which makes the tag
|
|
2166
2230
|
* self-consistent and idempotent.
|
|
2167
2231
|
*
|
|
2168
2232
|
* The one hazard is a popover that is open for an unrelated reason (a composer
|
|
2169
|
-
* menu, a hover card) *while* a header trigger stays expanded. Such a popover
|
|
2170
|
-
*
|
|
2171
|
-
*
|
|
2172
|
-
* dropdowns are transient (opening one closes the others), so this is a
|
|
2173
|
-
* rather than the common path.
|
|
2233
|
+
* menu, a hover card) *while* a header trigger stays expanded. Such a popover is
|
|
2234
|
+
* not a candidate: it is neither portaled nor a descendant of a header anchor,
|
|
2235
|
+
* and the composer's in-place lists keep belonging to the card group. In practice
|
|
2236
|
+
* header dropdowns are transient (opening one closes the others), so this is a
|
|
2237
|
+
* guard rather than the common path.
|
|
2174
2238
|
*
|
|
2175
2239
|
* THE SURFACE MARKER IS PART OF THE CANDIDATE SET (`0.2.1-alpha.3` and up).
|
|
2176
2240
|
* That release moved the background-job list onto the shared `MenuSurface`, whose
|
|
@@ -2209,20 +2273,54 @@ window.__ModuleLoader__.load({
|
|
|
2209
2273
|
for (const anchor of document.querySelectorAll(headerSlotAnchors())) if (anchor.querySelector("[aria-expanded=\"true\"]") !== null) return true;
|
|
2210
2274
|
return false;
|
|
2211
2275
|
}
|
|
2212
|
-
/**
|
|
2213
|
-
*
|
|
2214
|
-
*
|
|
2215
|
-
* its
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2276
|
+
/** Whether this popover can belong to the header.
|
|
2277
|
+
*
|
|
2278
|
+
* Two shapes, and the second one is the reason this is not just "portaled to body":
|
|
2279
|
+
* `session-log-export/HeaderAction.tsx` renders its `Menu` WITHOUT the `portal` prop,
|
|
2280
|
+
* so the card is mounted in place, inside `[data-slot="conversation.session.header
|
|
2281
|
+
* .utilities"]` — a DOM descendant of the row, exactly where a header trigger's own
|
|
2282
|
+
* popover belongs. Keyed on `parentElement === body` alone it was never claimable, and
|
|
2283
|
+
* the only thing that styled it at all was the header group's
|
|
2284
|
+
* `[role="menu"][class*="_denseList"]:not([class*="_portal"])` arm — which dies the
|
|
2285
|
+
* moment the host drops `dense` (or adds a header popover that is not a dense menu),
|
|
2286
|
+
* and leaves the surface following the card slider while it sits in the title row.
|
|
2287
|
+
*
|
|
2288
|
+
* A popover that is neither portaled nor inside a header anchor stays foreign: that is
|
|
2289
|
+
* the composer's in-place lists (permission / command / model), which the card group
|
|
2290
|
+
* owns and this group must never reach. */
|
|
2291
|
+
function isHeaderSurface(el) {
|
|
2292
|
+
if (el.getAttribute("aria-modal") === "true") return false;
|
|
2293
|
+
return el.parentElement === document.body || el.closest(headerSlotAnchors()) !== null;
|
|
2219
2294
|
}
|
|
2220
2295
|
let observer = null;
|
|
2221
|
-
let
|
|
2296
|
+
let pending = null;
|
|
2297
|
+
/** False once the effect is torn down, so a pass already queued on the microtask queue
|
|
2298
|
+
* cannot re-mark a popover after the teardown cleared it. */
|
|
2299
|
+
let active = false;
|
|
2300
|
+
/** Coalesce the observer's batches into ONE pass, but flush it on the microtask queue
|
|
2301
|
+
* rather than a animation frame.
|
|
2302
|
+
*
|
|
2303
|
+
* The frame version was the bug, not the batching: `requestAnimationFrame` callbacks
|
|
2304
|
+
* do not run while a window is not rendering — a hidden tab, an occluded or minimized
|
|
2305
|
+
* desktop window, a background Electron surface — and a queued frame never fires, so
|
|
2306
|
+
* the tag never lands and the 「顶栏选项」 pair silently keeps whatever the card group
|
|
2307
|
+
* gave the panel. Observed live: with the page not painting, an open header menu stayed
|
|
2308
|
+
* `data-dsh-any-header-popover`-less indefinitely, and the same menu was tagged the
|
|
2309
|
+
* moment rAF was made to run. A `MutationObserver` callback is already delivered once
|
|
2310
|
+
* per batch at microtask time, so a microtask flush coalesces exactly as well and has no
|
|
2311
|
+
* dependency on the compositor at all — and it lands in the SAME frame the popover
|
|
2312
|
+
* mounts, which also removes the one-frame flash of card styling on open. */
|
|
2313
|
+
function schedule() {
|
|
2314
|
+
if (pending !== null || !active) return;
|
|
2315
|
+
pending = Promise.resolve().then(() => {
|
|
2316
|
+
pending = null;
|
|
2317
|
+
if (active) refreshHeaderPopovers();
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
2222
2320
|
/** Recompute tags from the current open state. */
|
|
2223
2321
|
function refreshHeaderPopovers() {
|
|
2224
2322
|
const open = headerTriggerOpen();
|
|
2225
|
-
const candidates = [...document.querySelectorAll(POPOVER_SELECTOR)].filter(
|
|
2323
|
+
const candidates = [...document.querySelectorAll(POPOVER_SELECTOR)].filter(isHeaderSurface);
|
|
2226
2324
|
if (!open) {
|
|
2227
2325
|
for (const el of document.querySelectorAll(`[${HEADER_POPOVER_ATTR}]`)) el.removeAttribute(HEADER_POPOVER_ATTR);
|
|
2228
2326
|
return;
|
|
@@ -2230,16 +2328,10 @@ window.__ModuleLoader__.load({
|
|
|
2230
2328
|
for (const el of candidates) el.setAttribute(HEADER_POPOVER_ATTR, "");
|
|
2231
2329
|
for (const el of document.querySelectorAll(`[${HEADER_POPOVER_ATTR}]`)) if (!candidates.includes(el)) el.removeAttribute(HEADER_POPOVER_ATTR);
|
|
2232
2330
|
}
|
|
2233
|
-
function schedule() {
|
|
2234
|
-
if (raf !== null) return;
|
|
2235
|
-
raf = window.requestAnimationFrame(() => {
|
|
2236
|
-
raf = null;
|
|
2237
|
-
refreshHeaderPopovers();
|
|
2238
|
-
});
|
|
2239
|
-
}
|
|
2240
2331
|
/** Start tagging. Returns a teardown that stops observing and clears markings. */
|
|
2241
2332
|
function startHeaderPopoverTagging() {
|
|
2242
2333
|
if (typeof MutationObserver === "undefined" || typeof document === "undefined") return () => {};
|
|
2334
|
+
active = true;
|
|
2243
2335
|
refreshHeaderPopovers();
|
|
2244
2336
|
observer = new MutationObserver(schedule);
|
|
2245
2337
|
observer.observe(document.body, {
|
|
@@ -2249,12 +2341,9 @@ window.__ModuleLoader__.load({
|
|
|
2249
2341
|
attributeFilter: ["aria-expanded"]
|
|
2250
2342
|
});
|
|
2251
2343
|
return () => {
|
|
2344
|
+
active = false;
|
|
2252
2345
|
observer?.disconnect();
|
|
2253
2346
|
observer = null;
|
|
2254
|
-
if (raf !== null) {
|
|
2255
|
-
window.cancelAnimationFrame(raf);
|
|
2256
|
-
raf = null;
|
|
2257
|
-
}
|
|
2258
2347
|
for (const el of document.querySelectorAll(`[${HEADER_POPOVER_ATTR}]`)) el.removeAttribute(HEADER_POPOVER_ATTR);
|
|
2259
2348
|
};
|
|
2260
2349
|
}
|
|
@@ -3610,16 +3699,40 @@ window.__ModuleLoader__.load({
|
|
|
3610
3699
|
if (rSchemeOverride() !== "auto") return genTokens(220, .04, scheme === "dark" ? .14 : .92, scheme).tokens;
|
|
3611
3700
|
return null;
|
|
3612
3701
|
}
|
|
3613
|
-
/** Surface colors the opacity sliders fade when the plugin has NO palette of
|
|
3614
|
-
*
|
|
3615
|
-
*
|
|
3616
|
-
*
|
|
3617
|
-
*
|
|
3618
|
-
*
|
|
3619
|
-
*
|
|
3702
|
+
/** Surface colors the opacity sliders fade when the plugin has NO palette of its own
|
|
3703
|
+
* (no picked color, no forced scheme), read live from the host's own resolved tokens —
|
|
3704
|
+
* the same trick applyPanelOverrides uses for the workbench panel. The sliders only
|
|
3705
|
+
* ever supply the alpha: the host still decides the colors, so a custom host skin
|
|
3706
|
+
* survives. Returns null when the host exposes none.
|
|
3707
|
+
*
|
|
3708
|
+
* SAMPLED ON `<body>`, NOT `:root`: `design-platform.css` declares this whole token set
|
|
3709
|
+
* inside a `body { … }` block (light at :166, dark at :284), and a custom property is
|
|
3710
|
+
* inherited DOWNWARD only — read off the root element every one of them is the empty
|
|
3711
|
+
* string, this function answers null, `applyCustomTokensNow` takes its `surfaces ===
|
|
3712
|
+
* null` exit, and on an install with no picked color every interface-opacity slider does
|
|
3713
|
+
* nothing at all (the frame never gets cleared either, so the wallpaper stays hidden).
|
|
3714
|
+
* Measured against the host's own declarations: `:root` → all five tokens empty,
|
|
3715
|
+
* `body` → all five resolve.
|
|
3716
|
+
*
|
|
3717
|
+
* …AND CACHED PER HOST GENERATION, with our own sheet switched off while reading: the
|
|
3718
|
+
* plugin re-scopes these same names on `body`
|
|
3719
|
+
* (`body{--dsw-specific-menu:var(--dsh-any-op-menu)!important}`), so a second read after
|
|
3720
|
+
* the first write returns the plugin's OWN substituted literal — the surfaces would
|
|
3721
|
+
* freeze at whatever color they first sampled instead of following the host. The
|
|
3722
|
+
* generation key is what can flip the host's palette without anything in this plugin
|
|
3723
|
+
* moving: its dark-mode marker, and the platform attribute (`[data-platform='darwin']`
|
|
3724
|
+
* re-declares `--dsw-specific-menu`). */
|
|
3725
|
+
let hostSurfaceSample = null;
|
|
3620
3726
|
function readHostOpacityTokens() {
|
|
3621
|
-
if (typeof getComputedStyle === "undefined") return null;
|
|
3622
|
-
const
|
|
3727
|
+
if (typeof getComputedStyle === "undefined" || typeof document === "undefined") return null;
|
|
3728
|
+
const body = document.body;
|
|
3729
|
+
if (body === null) return null;
|
|
3730
|
+
const key = `${body.getAttribute("data-ds-dark-theme") ?? ""}|${document.documentElement.getAttribute("data-platform") ?? ""}`;
|
|
3731
|
+
if (hostSurfaceSample !== null && hostSurfaceSample.key === key) return hostSurfaceSample.map;
|
|
3732
|
+
const sheet = tokenStyleEl;
|
|
3733
|
+
const wasDisabled = sheet === null ? false : sheet.disabled;
|
|
3734
|
+
if (sheet !== null) sheet.disabled = true;
|
|
3735
|
+
const cs = getComputedStyle(body);
|
|
3623
3736
|
const out = {};
|
|
3624
3737
|
let found = false;
|
|
3625
3738
|
for (const g of OPACITY_TOKEN_GROUPS) for (const name of g.names) {
|
|
@@ -3628,7 +3741,12 @@ window.__ModuleLoader__.load({
|
|
|
3628
3741
|
out[name] = v;
|
|
3629
3742
|
found = true;
|
|
3630
3743
|
}
|
|
3631
|
-
|
|
3744
|
+
if (sheet !== null) sheet.disabled = wasDisabled;
|
|
3745
|
+
hostSurfaceSample = {
|
|
3746
|
+
key,
|
|
3747
|
+
map: found ? out : null
|
|
3748
|
+
};
|
|
3749
|
+
return hostSurfaceSample.map;
|
|
3632
3750
|
}
|
|
3633
3751
|
function applyCustomTokensNow(ops) {
|
|
3634
3752
|
const hasColor = rHasColor();
|
|
@@ -3708,34 +3826,30 @@ window.__ModuleLoader__.load({
|
|
|
3708
3826
|
function menuFrost(blurVar) {
|
|
3709
3827
|
return hostAdapter().menus.frostDecl(`var(${blurVar},none)`);
|
|
3710
3828
|
}
|
|
3711
|
-
/** The
|
|
3829
|
+
/** The frost token, asserted ALWAYS — and what that means for the slider's bottom end.
|
|
3712
3830
|
*
|
|
3713
|
-
*
|
|
3714
|
-
*
|
|
3715
|
-
*
|
|
3716
|
-
*
|
|
3717
|
-
*
|
|
3718
|
-
*
|
|
3719
|
-
* fallback does not "add no blur" at slider 0 — it DELETES the host's frost. The
|
|
3720
|
-
* result is a faded menu with nothing behind it: the page shows through it crisp and
|
|
3721
|
-
* bright, so the popup stops reading as a raised surface at all. (This is a DIFFERENT
|
|
3722
|
-
* defect from the reported "the background-job list is under the conversation" one,
|
|
3723
|
-
* which is a stacking-context injury the row takes with its own frost — see the
|
|
3724
|
-
* `z-index` note on `HEADER_BAR_RULE`. Both were live at once on `0.2.0-rc.1`.)
|
|
3725
|
-
* `none` stays correct for the exempt group: `applyExemptDefaults` pins those
|
|
3726
|
-
* surfaces at alpha 1 alongside the cleared frost, so they are opaque by design.
|
|
3831
|
+
* The host declares its own menu frost on `body` (`ui-theme/src/styles/gradient-shadow-text.css`
|
|
3832
|
+
* — `--dsw-menu-backdrop-filter: blur(40px) saturate(150%)`, no media query), and every menu
|
|
3833
|
+
* frosts from that INHERITED value, whether it filters itself (the background-job `<ul>`) or
|
|
3834
|
+
* hands the value to a `MenuSurface` `.material` child. An element's own declaration always
|
|
3835
|
+
* beats what it inherits, so writing the token with a `none` fallback does not "add no blur"
|
|
3836
|
+
* at slider 0 — it DELETES the host's frost.
|
|
3727
3837
|
*
|
|
3728
|
-
*
|
|
3729
|
-
*
|
|
3730
|
-
*
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
*
|
|
3735
|
-
*
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3838
|
+
* 0.3.7 answered that with a `<html>` class gate (`dab-card-frost` / `dab-header-frost`) that
|
|
3839
|
+
* only let the declaration through while the slider was non-zero, so 0 meant "leave the host
|
|
3840
|
+
* alone". That was the wrong trade and this is the report that says so: with the gate on, the
|
|
3841
|
+
* slider's LOW end is its HIGH end — 0 renders the host's 40 px frost and 1 renders 1 px — so
|
|
3842
|
+
* the control reads as dead in both directions, and 「把模糊关掉」 is simply not reachable
|
|
3843
|
+
* (measured in `dsh web` with 顶栏选项 at 0/0: the open-in-app panel still came out a soft,
|
|
3844
|
+
* opaque-looking card, because what it was showing was the host's blur, not the plugin's).
|
|
3845
|
+
* The token is therefore asserted at every value, `none` included: **0 means no frost**.
|
|
3846
|
+
* Nothing loses the host look by accident, because the part DEFAULTS are 30 px — a stock
|
|
3847
|
+
* install is frosted like the host's and only an explicit drag to 0 clears it. The same is
|
|
3848
|
+
* already true of every other blur slider in this plugin (0 = off), which is the interface
|
|
3849
|
+
* consistency the gate broke.
|
|
3850
|
+
*
|
|
3851
|
+
* `none` stays correct for the exempt group as well: `applyExemptDefaults` pins those surfaces
|
|
3852
|
+
* at alpha 1 alongside the cleared frost, so they are opaque by design. */
|
|
3739
3853
|
/** Declare EVERY token this release's menus can paint their fill from with the same
|
|
3740
3854
|
* value. One slider, one value, every layer reached — and a token the host does not
|
|
3741
3855
|
* read is inert, so this is safe to emit on a line that only needs one.
|
|
@@ -3749,7 +3863,7 @@ window.__ModuleLoader__.load({
|
|
|
3749
3863
|
return hostAdapter().menus.fillTokens.map((name) => `${name}:${value}`).join(";");
|
|
3750
3864
|
}
|
|
3751
3865
|
function popoverBlurRule() {
|
|
3752
|
-
return `${
|
|
3866
|
+
return `${POPOVER_MENU_SEL},${MENU_MATERIAL_SEL}{${menuFrost(CARD_BLUR_VAR)}}${POPOVER_OTHER_SEL}{${elementFrostDecl(`var(${CARD_BLUR_VAR},none)`)}}`;
|
|
3753
3867
|
}
|
|
3754
3868
|
const INPUT_FROST_CLASS = "dab-input-frost";
|
|
3755
3869
|
const TAKEOVER_FROST_CLASS = "dab-takeover-frost";
|
|
@@ -3802,6 +3916,8 @@ window.__ModuleLoader__.load({
|
|
|
3802
3916
|
}
|
|
3803
3917
|
const MOBILE_HEADER_RULE = ".dsh-mobile-app-header{background:var(--dsh-any-op-bg,transparent)!important;backdrop-filter:var(--dsh-any-part-blur-global,none);-webkit-backdrop-filter:var(--dsh-any-part-blur-global,none)}";
|
|
3804
3918
|
const HEADER_BAR_CLASS = "dab-header-bar";
|
|
3919
|
+
/** Added to the same row only while its blur is non-zero — see `HEADER_BAR_RULE`. */
|
|
3920
|
+
const HEADER_BAR_FROST_CLASS = "dab-header-bar-frost";
|
|
3805
3921
|
const HEADER_BAR_ANCHOR = "[data-slot^=\"conversation.session.header\"]";
|
|
3806
3922
|
/** The session header bar, or null where this host has no such element.
|
|
3807
3923
|
*
|
|
@@ -3819,13 +3935,35 @@ window.__ModuleLoader__.load({
|
|
|
3819
3935
|
if (bar.className.includes("headerBlank")) return null;
|
|
3820
3936
|
return bar;
|
|
3821
3937
|
}
|
|
3822
|
-
/** Exactly one owner: the row the current conversation mounted. A row that went
|
|
3823
|
-
* blank, or one the host replaced, must not keep a class from an earlier pass. */
|
|
3824
3938
|
let headerBarEl = null;
|
|
3825
|
-
|
|
3826
|
-
|
|
3939
|
+
/** Exactly one owner: the row the current conversation mounted. A row that went
|
|
3940
|
+
* blank, or one the host replaced, must not keep a class — or a `position` — from an
|
|
3941
|
+
* earlier pass. `frost` decides whether the row also carries the underlay arm, and the
|
|
3942
|
+
* underlay's containing block is written inline only while it is needed. */
|
|
3943
|
+
function releaseHeaderBar(bar) {
|
|
3944
|
+
bar.classList.remove(HEADER_BAR_CLASS, HEADER_BAR_FROST_CLASS);
|
|
3945
|
+
if (bar.getAttribute(TAKEOVER_POS_ATTR) === "1") {
|
|
3946
|
+
bar.style.removeProperty("position");
|
|
3947
|
+
bar.removeAttribute(TAKEOVER_POS_ATTR);
|
|
3948
|
+
}
|
|
3949
|
+
}
|
|
3950
|
+
function claimHeaderBar(bar, frost) {
|
|
3951
|
+
if (headerBarEl !== null && headerBarEl !== bar) releaseHeaderBar(headerBarEl);
|
|
3952
|
+
if (bar === null) {
|
|
3953
|
+
headerBarEl = null;
|
|
3954
|
+
return;
|
|
3955
|
+
}
|
|
3827
3956
|
headerBarEl = bar;
|
|
3828
|
-
|
|
3957
|
+
bar.classList.add(HEADER_BAR_CLASS);
|
|
3958
|
+
if (!frost) {
|
|
3959
|
+
bar.classList.remove(HEADER_BAR_FROST_CLASS);
|
|
3960
|
+
return;
|
|
3961
|
+
}
|
|
3962
|
+
if (getComputedStyle(bar).position === "static") {
|
|
3963
|
+
bar.style.position = "relative";
|
|
3964
|
+
bar.setAttribute(TAKEOVER_POS_ATTR, "1");
|
|
3965
|
+
}
|
|
3966
|
+
bar.classList.add(HEADER_BAR_FROST_CLASS);
|
|
3829
3967
|
}
|
|
3830
3968
|
/** The bar's paint. The variables are written by `applyHeaderBar`; the class is
|
|
3831
3969
|
* only ever added when they are, so a host the plugin is not theming keeps its
|
|
@@ -3865,12 +4003,27 @@ window.__ModuleLoader__.load({
|
|
|
3865
4003
|
* filter never had to be blamed for its anchoring). 10 sits in that gap: above 9, far
|
|
3866
4004
|
* below 100, so a portaled list still covers the title row exactly as the host intends.
|
|
3867
4005
|
*
|
|
3868
|
-
* `z-index` needs no `position` here and none is written: the row is
|
|
3869
|
-
* `ConversationRoot .root{display:flex;flex-direction:column}` on every
|
|
3870
|
-
* and z-index applies to flex items as they are. Writing
|
|
3871
|
-
* make the row a containing block — and deciding a host
|
|
3872
|
-
* race this plugin lost once already (issue #24).
|
|
3873
|
-
|
|
4006
|
+
* `z-index` needs no `position` here and none is written by the BASE rule: the row is
|
|
4007
|
+
* a flex ITEM of `ConversationRoot .root{display:flex;flex-direction:column}` on every
|
|
4008
|
+
* release in range, and z-index applies to flex items as they are. Writing
|
|
4009
|
+
* `position:relative` would also make the row a containing block — and deciding a host
|
|
4010
|
+
* box's positioning is the exact race this plugin lost once already (issue #24).
|
|
4011
|
+
*
|
|
4012
|
+
* THE FROST DOES NOT SIT ON THE ROW. That was the first version of this rule, and it
|
|
4013
|
+
* cost the row's own children their backdrop: `backdrop-filter` makes an element a
|
|
4014
|
+
* BACKDROP ROOT as well as a stacking context, so an in-place header popover (the
|
|
4015
|
+
* session-log `…` menu, which `HeaderAction.tsx` renders without `portal`) could only
|
|
4016
|
+
* ever blur what the row itself paints — a flat tint — and the 「标题栏」 blur slider
|
|
4017
|
+
* read as dead on exactly the panel that hangs off the row. `isolation:isolate` is a
|
|
4018
|
+
* stacking context WITHOUT being a backdrop root, so the frost now rides a `::before`
|
|
4019
|
+
* underlay like it does on every other host part this plugin filters (`PART_BLUR_RULE`,
|
|
4020
|
+
* `inputBlurRule`), and the row's children sample the wallpaper again. The underlay
|
|
4021
|
+
* needs the row to be its containing block, which is why the frost arm adds
|
|
4022
|
+
* `position:relative` — INLINE, only when the host left the row `static`, and marked
|
|
4023
|
+
* `data-dab-pos-patched` so only this writer takes it back: the same guard
|
|
4024
|
+
* `setBlur` uses, for the same reason (a stylesheet `position` would cascade against
|
|
4025
|
+
* whatever the host or another plugin decides that box's position is). */
|
|
4026
|
+
const HEADER_BAR_RULE = `.${HEADER_BAR_CLASS}{background:var(--dsh-any-op-header-bar,transparent)!important;z-index:10}.${HEADER_BAR_FROST_CLASS}{isolation:isolate}.${HEADER_BAR_FROST_CLASS}::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;-webkit-backdrop-filter:var(--dsh-any-blur-header-bar,none);backdrop-filter:var(--dsh-any-blur-header-bar,none)}`;
|
|
3874
4027
|
/** The 「标题栏」card's paint: the card's material at the card's opacity, empty
|
|
3875
4028
|
* where the plugin is not theming. The conversation header row, the Windows
|
|
3876
4029
|
* caption band, and — through the desktop preload's probe — the native
|
|
@@ -3889,7 +4042,7 @@ window.__ModuleLoader__.load({
|
|
|
3889
4042
|
const bar = discoverHeaderBar();
|
|
3890
4043
|
const paint = headerBarPaint(src);
|
|
3891
4044
|
if (paint === "") {
|
|
3892
|
-
claimHeaderBar(null);
|
|
4045
|
+
claimHeaderBar(null, false);
|
|
3893
4046
|
root.style.removeProperty("--dsh-any-op-header-bar");
|
|
3894
4047
|
root.style.removeProperty("--dsh-any-blur-header-bar");
|
|
3895
4048
|
applyNativeCaption(surfaces);
|
|
@@ -3899,7 +4052,7 @@ window.__ModuleLoader__.load({
|
|
|
3899
4052
|
const px = rBlurs().headerBar;
|
|
3900
4053
|
if (px > 0) root.style.setProperty("--dsh-any-blur-header-bar", `blur(${px}px)`);
|
|
3901
4054
|
else root.style.removeProperty("--dsh-any-blur-header-bar");
|
|
3902
|
-
claimHeaderBar(bar);
|
|
4055
|
+
claimHeaderBar(bar, px > 0);
|
|
3903
4056
|
applyNativeCaption(surfaces);
|
|
3904
4057
|
}
|
|
3905
4058
|
const CAPTION_FRAME_CLASS = "dab-frame-caption";
|
|
@@ -3911,7 +4064,7 @@ window.__ModuleLoader__.load({
|
|
|
3911
4064
|
const CAPTION_INK_ATTR = "data-dab-caption-ink";
|
|
3912
4065
|
/** The strip's chrome ink, and its collapsed-state variant.
|
|
3913
4066
|
*
|
|
3914
|
-
* WHY THIS IS NOT THE LABEL INK: the plugin flips the label tokens against the
|
|
4067
|
+
* WHY THIS IS NOT SIMPLY THE LABEL INK: the plugin flips the label tokens against the
|
|
3915
4068
|
* PICKED PALETTE (white on a dark pick), but the caption band is that palette at
|
|
3916
4069
|
* the sidebar/header-bar opacity OVER the wallpaper. At a low opacity the strip
|
|
3917
4070
|
* is mostly wallpaper, so white ink lands on a light band and the toggle
|
|
@@ -3920,11 +4073,31 @@ window.__ModuleLoader__.load({
|
|
|
3920
4073
|
* painted on: past ~85% opacity the surface dominates and the palette direction
|
|
3921
4074
|
* is the truth; below it the wallpaper's brightness verdict decides.
|
|
3922
4075
|
*
|
|
4076
|
+
* WHY THAT DERIVATION IS NOT THE WHOLE ANSWER (issue #30): the same derivation makes
|
|
4077
|
+
* the native caption menubar (「应用 / 编辑」) black on a dark theme whose sidebar is
|
|
4078
|
+
* translucent over a bright wallpaper — the strip really is light there, so the strip
|
|
4079
|
+
* is right and the rest of the window is wrong, and the two reports of this same
|
|
4080
|
+
* situation asked for opposite outcomes. So the policy is the user's: 「标题栏文字」
|
|
4081
|
+
* picks the winner, and `auto` keeps the strip-following behaviour that fixed the
|
|
4082
|
+
* invisible toggle. `theme` returns null, which removes every ink declaration this
|
|
4083
|
+
* function feeds — the menubar and the sidebar's fixed controls then read the host's
|
|
4084
|
+
* own label tokens, exactly as they did before 0.3.8.
|
|
4085
|
+
*
|
|
3923
4086
|
* Returned as `{ ink, collapsedInk }` because the strip's material changes with
|
|
3924
4087
|
* the sidebar: expanded it is the sidebar segment, collapsed it is the 「标题栏」
|
|
3925
|
-
* card's band. `null` means "no verdict and no palette
|
|
3926
|
-
*
|
|
4088
|
+
* card's band. `null` means "no override" — either no verdict and no palette
|
|
4089
|
+
* direction, or the user asked for the theme's own ink. */
|
|
3927
4090
|
function captionInkPair() {
|
|
4091
|
+
const mode = rCaptionInk();
|
|
4092
|
+
if (mode === "theme") return null;
|
|
4093
|
+
if (mode === "white") return {
|
|
4094
|
+
ink: "#fff",
|
|
4095
|
+
collapsedInk: "#fff"
|
|
4096
|
+
};
|
|
4097
|
+
if (mode === "black") return {
|
|
4098
|
+
ink: "#000",
|
|
4099
|
+
collapsedInk: "#000"
|
|
4100
|
+
};
|
|
3928
4101
|
const verdict = rBgDark();
|
|
3929
4102
|
const inkIsWhite = rSchemeOverride() === "auto" ? rHasColor() ? rColorScheme() === "dark" : verdict : rScheme() === "dark";
|
|
3930
4103
|
if (inkIsWhite === null || inkIsWhite === void 0) return null;
|
|
@@ -4030,7 +4203,7 @@ window.__ModuleLoader__.load({
|
|
|
4030
4203
|
const fill = captionFill(src);
|
|
4031
4204
|
const paint = headerBarPaint(src) || fill;
|
|
4032
4205
|
const width = "var(--dsh-windows-sidebar-width,0px)";
|
|
4033
|
-
const css = fill === "" ? "" : `${WCO_PROBE_SEL}{--dsw-specific-sidebar-fill:transparent}[data-windows-titlebar] .${CAPTION_FRAME_CLASS}::before{background:var(--dsh-any-op-header-bar,${paint})!important;backdrop-filter:var(--dsh-any-blur-header-bar,none);-webkit-backdrop-filter:var(--dsh-any-blur-header-bar,none);clip-path:inset(0 0 0 ${width});-webkit-clip-path:inset(0 0 0 ${width})}[data-windows-titlebar] .${CAPTION_FRAME_CLASS}::after{content:"";position:absolute;top:0;left:0;pointer-events:none;z-index:-1;width:${width};height:var(--dsh-windows-titlebar-height,40px);background:var(--dsh-any-op-sidebar,${fill});backdrop-filter:var(--dsh-any-blur-sidebar-band,none);-webkit-backdrop-filter:var(--dsh-any-blur-sidebar-band,none)}[data-windows-titlebar]:has([role="dialog"][aria-modal="true"]) .${CAPTION_FRAME_CLASS}::before,[data-windows-titlebar]:has([role="dialog"][aria-modal="true"]) .${CAPTION_FRAME_CLASS}::after{box-shadow:inset 0 0 0 9999px var(--dsw-alias-bg-mask-1,rgba(0,0,0,.24))}:root:has([data-sidebar-collapsed
|
|
4206
|
+
const css = fill === "" ? "" : `${WCO_PROBE_SEL}{--dsw-specific-sidebar-fill:transparent}[data-windows-titlebar] .${CAPTION_FRAME_CLASS}::before{background:var(--dsh-any-op-header-bar,${paint})!important;backdrop-filter:var(--dsh-any-blur-header-bar,none);-webkit-backdrop-filter:var(--dsh-any-blur-header-bar,none);clip-path:inset(0 0 0 ${width});-webkit-clip-path:inset(0 0 0 ${width})}[data-windows-titlebar] .${CAPTION_FRAME_CLASS}::after{content:"";position:absolute;top:0;left:0;pointer-events:none;z-index:-1;width:${width};height:var(--dsh-windows-titlebar-height,40px);background:var(--dsh-any-op-sidebar,${fill});backdrop-filter:var(--dsh-any-blur-sidebar-band,none);-webkit-backdrop-filter:var(--dsh-any-blur-sidebar-band,none)}[data-windows-titlebar]:has([role="dialog"][aria-modal="true"]) .${CAPTION_FRAME_CLASS}::before,[data-windows-titlebar]:has([role="dialog"][aria-modal="true"]) .${CAPTION_FRAME_CLASS}::after{box-shadow:inset 0 0 0 9999px var(--dsw-alias-bg-mask-1,rgba(0,0,0,.24))}` + (rCaptionInk() === "theme" ? "" : ":root:has([data-sidebar-collapsed=\"true\"]){--dsh-any-caption-ink:var(--dsh-any-caption-ink-collapsed,#fff)!important}[data-windows-titlebar] [data-windows-menu]{--dsw-alias-label-secondary:var(--dsh-any-caption-ink,#fff);--dsw-alias-label-primary:var(--dsh-any-caption-ink,#fff)}") + `[data-windows-titlebar] .${FLAT_CENTER_CLASS}{border-top-left-radius:0!important}`;
|
|
4034
4207
|
const el = ensureWcoStyle();
|
|
4035
4208
|
if (el.textContent !== css) el.textContent = css;
|
|
4036
4209
|
const ink = css === "" ? null : captionInkPair();
|
|
@@ -4102,7 +4275,7 @@ window.__ModuleLoader__.load({
|
|
|
4102
4275
|
* backdrop root each of those files documents avoiding. */
|
|
4103
4276
|
const HEADER_BLUR_VAR = "--dsh-any-blur-header";
|
|
4104
4277
|
function headerPopoverRule() {
|
|
4105
|
-
return `${
|
|
4278
|
+
return `${HEADER_SURFACES_PADDED.join(",")}{${menuFrost(HEADER_BLUR_VAR)}}`;
|
|
4106
4279
|
}
|
|
4107
4280
|
function exemptDefaultRule() {
|
|
4108
4281
|
return `[role="dialog"][aria-modal="true"]:not([aria-labelledby]){backdrop-filter:none;-webkit-backdrop-filter:none}[role="menu"]:has([class*="_danger"]){${hostAdapter().menus.frostDecl("none")};-webkit-text-stroke-width:0}`;
|
|
@@ -4116,13 +4289,8 @@ window.__ModuleLoader__.load({
|
|
|
4116
4289
|
function applyHeaderPopovers() {
|
|
4117
4290
|
const root = document.documentElement;
|
|
4118
4291
|
const px = rBlurs().header;
|
|
4119
|
-
if (px > 0) {
|
|
4120
|
-
|
|
4121
|
-
root.classList.add(HEADER_FROST_GATE);
|
|
4122
|
-
} else {
|
|
4123
|
-
root.style.removeProperty(HEADER_BLUR_VAR);
|
|
4124
|
-
root.classList.remove(HEADER_FROST_GATE);
|
|
4125
|
-
}
|
|
4292
|
+
if (px > 0) root.style.setProperty(HEADER_BLUR_VAR, `blur(${px}px)`);
|
|
4293
|
+
else root.style.removeProperty(HEADER_BLUR_VAR);
|
|
4126
4294
|
let opacity = rHeaderOpacity();
|
|
4127
4295
|
if (opacity < 0) opacity = 0;
|
|
4128
4296
|
if (opacity > 1) opacity = 1;
|
|
@@ -4598,7 +4766,8 @@ window.__ModuleLoader__.load({
|
|
|
4598
4766
|
*
|
|
4599
4767
|
* Bound by the CSS-Module class shape, same as `[class*="_ioCard"]`: the built
|
|
4600
4768
|
* bundle names these `pI_x6G_sidebarCol` — prefix first, local name last, and the
|
|
4601
|
-
* pair is identical across `0.2.0-rc.1`, `0.2.1-alpha.3
|
|
4769
|
+
* pair is identical across `0.2.0-rc.1`, `0.2.1-alpha.3`, `0.2.1-rc.2` and
|
|
4770
|
+
* `0.2.1-rc.3` (`AppFrame.module.css` byte-identical rc.2→rc.3). A build
|
|
4602
4771
|
* that renames the track simply stops matching, which is the untouched host look. */
|
|
4603
4772
|
const SIDEBAR_ONE_LAYER_RULE = "[class*=\"_sidebarCol\"] *{--dsw-specific-sidebar-fill:transparent}";
|
|
4604
4773
|
const PART_BLUR_RULE = `.${PART_BLUR_CLASS}{isolation:isolate}.${PART_BLUR_CLASS}:has([role="dialog"]){isolation:auto}.${PART_UNDERLAY_CLASS}{position:absolute;inset:0;z-index:-1;pointer-events:none;border-radius:inherit;backdrop-filter:var(--dsh-any-part-blur,none);-webkit-backdrop-filter:var(--dsh-any-part-blur,none)}`;
|
|
@@ -4690,17 +4859,13 @@ window.__ModuleLoader__.load({
|
|
|
4690
4859
|
/** Blur of the option panels inside the settings dialog (.dab-card), owned by
|
|
4691
4860
|
* the "dialog option panel" (card) blur slider. Written as a plugin-owned
|
|
4692
4861
|
* variable consumed by SETTINGS_STYLE_RULE — deliberately NOT applied to the
|
|
4693
|
-
* homepage center column, which this slider must never touch.
|
|
4694
|
-
*
|
|
4862
|
+
* homepage center column, which this slider must never touch. At 0 the variable is
|
|
4863
|
+
* removed and the menu rule's `none` fallback wins, which is what "no frost" means
|
|
4864
|
+
* on this slider (see the note above `popoverBlurRule`). */
|
|
4695
4865
|
function applyCardPanelsBlur(px) {
|
|
4696
4866
|
const root = document.documentElement;
|
|
4697
|
-
if (px > 0) {
|
|
4698
|
-
|
|
4699
|
-
root.classList.add(CARD_FROST_GATE);
|
|
4700
|
-
} else {
|
|
4701
|
-
root.style.removeProperty(CARD_BLUR_VAR);
|
|
4702
|
-
root.classList.remove(CARD_FROST_GATE);
|
|
4703
|
-
}
|
|
4867
|
+
if (px > 0) root.style.setProperty(CARD_BLUR_VAR, `blur(${px}px)`);
|
|
4868
|
+
else root.style.removeProperty(CARD_BLUR_VAR);
|
|
4704
4869
|
}
|
|
4705
4870
|
/** Apply per-part interface blur to the AppFrame columns + settings panel. */
|
|
4706
4871
|
function applyPartBlurs(blurs) {
|
|
@@ -5431,7 +5596,7 @@ window.__ModuleLoader__.load({
|
|
|
5431
5596
|
const name = set[k];
|
|
5432
5597
|
if (name) document.documentElement.style.removeProperty(name);
|
|
5433
5598
|
}
|
|
5434
|
-
document.documentElement.classList.remove(INPUT_FROST_CLASS
|
|
5599
|
+
document.documentElement.classList.remove(INPUT_FROST_CLASS);
|
|
5435
5600
|
applyTakeoverFrost(0);
|
|
5436
5601
|
document.documentElement.style.removeProperty("--dsh-any-op-header-bar");
|
|
5437
5602
|
document.documentElement.style.removeProperty("--dsh-any-blur-header-bar");
|
|
@@ -5439,7 +5604,7 @@ window.__ModuleLoader__.load({
|
|
|
5439
5604
|
document.documentElement.style.removeProperty("--dsh-any-caption-ink");
|
|
5440
5605
|
document.documentElement.style.removeProperty("--dsh-any-caption-ink-collapsed");
|
|
5441
5606
|
releaseCaptionInk();
|
|
5442
|
-
document.querySelectorAll(`.${HEADER_BAR_CLASS}`).forEach((el) => el
|
|
5607
|
+
document.querySelectorAll(`.${HEADER_BAR_CLASS}`).forEach((el) => releaseHeaderBar(el));
|
|
5443
5608
|
headerBarEl = null;
|
|
5444
5609
|
frameEl?.classList.remove(CAPTION_FRAME_CLASS);
|
|
5445
5610
|
document.querySelectorAll(`.${FLAT_CENTER_CLASS}`).forEach((el) => el.classList.remove(FLAT_CENTER_CLASS));
|
|
@@ -7464,6 +7629,47 @@ window.__ModuleLoader__.load({
|
|
|
7464
7629
|
blurs[blurKey] = v;
|
|
7465
7630
|
setBlurs(blurs);
|
|
7466
7631
|
}
|
|
7632
|
+
}),
|
|
7633
|
+
isHeaderBar && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7634
|
+
className: "dab-slider-block",
|
|
7635
|
+
title: t("captionInkHint"),
|
|
7636
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7637
|
+
className: "dab-slider-label",
|
|
7638
|
+
children: t("captionInkLabel")
|
|
7639
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7640
|
+
style: {
|
|
7641
|
+
display: "flex",
|
|
7642
|
+
alignItems: "center",
|
|
7643
|
+
gap: 10
|
|
7644
|
+
},
|
|
7645
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
7646
|
+
className: "dab-select",
|
|
7647
|
+
value: rCaptionInk(),
|
|
7648
|
+
onChange: (e) => {
|
|
7649
|
+
cfg.captionInk = e.target.value;
|
|
7650
|
+
applyHeaderBar();
|
|
7651
|
+
saveConfig();
|
|
7652
|
+
},
|
|
7653
|
+
children: [
|
|
7654
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
7655
|
+
value: "auto",
|
|
7656
|
+
children: t("captionInkAuto")
|
|
7657
|
+
}),
|
|
7658
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
7659
|
+
value: "theme",
|
|
7660
|
+
children: t("captionInkTheme")
|
|
7661
|
+
}),
|
|
7662
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
7663
|
+
value: "white",
|
|
7664
|
+
children: t("captionInkWhite")
|
|
7665
|
+
}),
|
|
7666
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
7667
|
+
value: "black",
|
|
7668
|
+
children: t("captionInkBlack")
|
|
7669
|
+
})
|
|
7670
|
+
]
|
|
7671
|
+
})
|
|
7672
|
+
})]
|
|
7467
7673
|
})
|
|
7468
7674
|
]
|
|
7469
7675
|
}, blurKey);
|