dsh-any-background 0.4.1 → 0.4.3
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 +95 -90
- package/README.zh.md +95 -86
- package/lib/client.js +712 -203
- package/lib/client.js.map +1 -1
- package/lib/index.js +14 -0
- package/package.json +13 -10
package/lib/client.js
CHANGED
|
@@ -62,6 +62,13 @@ window.__ModuleLoader__.load({
|
|
|
62
62
|
captionInkTheme: "跟随主题",
|
|
63
63
|
captionInkWhite: "始终白色",
|
|
64
64
|
captionInkBlack: "始终黑色",
|
|
65
|
+
tpTitle: "第三方插件兼容",
|
|
66
|
+
tpEnabled: "保护第三方表面",
|
|
67
|
+
tpHint: "本插件把宿主的一批底色令牌改成了半透明,好让壁纸透出来。其它插件如果用同样的令牌画表面,就会跟着一起变透明、和滚过的文字叠在一起。开启后认出这些插件,只把它们的那几块钉在可读的密度上,不随滑块调节。",
|
|
68
|
+
tpNone: "未检测到读取这些令牌的其它插件。",
|
|
69
|
+
tpPinned: "已钉住",
|
|
70
|
+
tpUnpinned: "未登记 —— 若它的表面变透明或看不清,请把开机日志这一行发给我",
|
|
71
|
+
tpReaderLanes: "吸顶总结栏",
|
|
65
72
|
fontPageTitle: "字体与描边",
|
|
66
73
|
fontTitle: "自定义字体",
|
|
67
74
|
fontHint: "支持 ttf/otf/woff/woff2 字体文件(上限 100MB),将应用到整个界面的文字;代码块的等宽字体保持不变。中文字体通常有几十 MB,首次上传与刷新加载需要片刻",
|
|
@@ -261,6 +268,13 @@ window.__ModuleLoader__.load({
|
|
|
261
268
|
captionInkTheme: "Follow theme",
|
|
262
269
|
captionInkWhite: "Always white",
|
|
263
270
|
captionInkBlack: "Always black",
|
|
271
|
+
tpTitle: "Third-party compatibility",
|
|
272
|
+
tpEnabled: "Protect third-party surfaces",
|
|
273
|
+
tpHint: "This plugin turns a batch of the host’s background tokens translucent so the wallpaper shows through. Another plugin that paints its surfaces with those same tokens goes translucent with it and collides with the text scrolling underneath. When on, those plugins are detected and only their surfaces are pinned to a legible density — outside the sliders.",
|
|
274
|
+
tpNone: "No other plugin was seen filling from these tokens.",
|
|
275
|
+
tpPinned: "pinned",
|
|
276
|
+
tpUnpinned: "not registered — if its surface fades or becomes unreadable, send me that boot-log line",
|
|
277
|
+
tpReaderLanes: "its sticky reading lanes",
|
|
264
278
|
fontPageTitle: "Font & outline",
|
|
265
279
|
fontTitle: "Custom font",
|
|
266
280
|
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",
|
|
@@ -533,6 +547,7 @@ window.__ModuleLoader__.load({
|
|
|
533
547
|
headerOpacity: .5,
|
|
534
548
|
headerBarOpacity: .5,
|
|
535
549
|
captionInk: "auto",
|
|
550
|
+
protectThirdParty: true,
|
|
536
551
|
profiles: [],
|
|
537
552
|
rotation: {
|
|
538
553
|
enabled: false,
|
|
@@ -762,6 +777,10 @@ window.__ModuleLoader__.load({
|
|
|
762
777
|
function rCaptionInk() {
|
|
763
778
|
return adoptCaptionInk(cfg.captionInk);
|
|
764
779
|
}
|
|
780
|
+
/** Whether the third-party compatibility pins are active — see `third-party.ts`. */
|
|
781
|
+
function rProtectThirdParty() {
|
|
782
|
+
return typeof cfg.protectThirdParty === "boolean" ? cfg.protectThirdParty : DEFAULT_CONFIG.protectThirdParty;
|
|
783
|
+
}
|
|
765
784
|
function rBgState() {
|
|
766
785
|
return cfg.bgState;
|
|
767
786
|
}
|
|
@@ -999,6 +1018,7 @@ window.__ModuleLoader__.load({
|
|
|
999
1018
|
headerOpacity: clamp01(c.headerOpacity, DEFAULT_CONFIG.headerOpacity),
|
|
1000
1019
|
headerBarOpacity: clamp01(c.headerBarOpacity, DEFAULT_CONFIG.headerBarOpacity),
|
|
1001
1020
|
captionInk: adoptCaptionInk(c.captionInk),
|
|
1021
|
+
protectThirdParty: typeof c.protectThirdParty === "boolean" ? c.protectThirdParty : DEFAULT_CONFIG.protectThirdParty,
|
|
1002
1022
|
profiles: adoptProfiles(c.profiles),
|
|
1003
1023
|
rotation: adoptRotation(c.rotation),
|
|
1004
1024
|
schedule: adoptSchedule(c.schedule),
|
|
@@ -1093,6 +1113,18 @@ window.__ModuleLoader__.load({
|
|
|
1093
1113
|
{
|
|
1094
1114
|
channel: "0.2.1",
|
|
1095
1115
|
release: "0.2.1-rc.3"
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
channel: "0.2.1",
|
|
1119
|
+
release: "0.2.1-rc.4"
|
|
1120
|
+
},
|
|
1121
|
+
{
|
|
1122
|
+
channel: "0.2.1",
|
|
1123
|
+
release: "0.2.1-rc.5"
|
|
1124
|
+
},
|
|
1125
|
+
{
|
|
1126
|
+
channel: "0.2.2",
|
|
1127
|
+
release: "0.2.2-alpha.2"
|
|
1096
1128
|
}
|
|
1097
1129
|
];
|
|
1098
1130
|
const UNKNOWN_HOST_INFO = {
|
|
@@ -1478,18 +1510,18 @@ window.__ModuleLoader__.load({
|
|
|
1478
1510
|
*
|
|
1479
1511
|
* @module
|
|
1480
1512
|
*/
|
|
1481
|
-
function panelFragments$
|
|
1513
|
+
function panelFragments$4() {
|
|
1482
1514
|
return {
|
|
1483
1515
|
promotion: "",
|
|
1484
1516
|
blur: panelBlurRule(DOCKKIT_SLIDERS)
|
|
1485
1517
|
};
|
|
1486
1518
|
}
|
|
1487
|
-
function createAdapter$
|
|
1519
|
+
function createAdapter$4(host) {
|
|
1488
1520
|
return {
|
|
1489
1521
|
id: "0.2.0-rc.1",
|
|
1490
1522
|
channel: "0.2.0-rc",
|
|
1491
1523
|
host,
|
|
1492
|
-
panelFragments: panelFragments$
|
|
1524
|
+
panelFragments: panelFragments$4,
|
|
1493
1525
|
pluginPageRule: PLUGIN_PAGE_FROST_RULE,
|
|
1494
1526
|
menus: LAYERED_MENU_SURFACE,
|
|
1495
1527
|
surface: {
|
|
@@ -1545,18 +1577,18 @@ window.__ModuleLoader__.load({
|
|
|
1545
1577
|
*
|
|
1546
1578
|
* @module
|
|
1547
1579
|
*/
|
|
1548
|
-
function panelFragments$
|
|
1580
|
+
function panelFragments$3() {
|
|
1549
1581
|
return {
|
|
1550
1582
|
promotion: "",
|
|
1551
1583
|
blur: panelBlurRule(DOCKKIT_SLIDERS)
|
|
1552
1584
|
};
|
|
1553
1585
|
}
|
|
1554
|
-
function createAdapter$
|
|
1586
|
+
function createAdapter$3(host) {
|
|
1555
1587
|
return {
|
|
1556
1588
|
id: "0.2.0-rc.2",
|
|
1557
1589
|
channel: "0.2.0-rc.2",
|
|
1558
1590
|
host,
|
|
1559
|
-
panelFragments: panelFragments$
|
|
1591
|
+
panelFragments: panelFragments$3,
|
|
1560
1592
|
pluginPageRule: PLUGIN_PAGE_FROST_RULE,
|
|
1561
1593
|
menus: LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,
|
|
1562
1594
|
surface: {
|
|
@@ -1569,7 +1601,8 @@ window.__ModuleLoader__.load({
|
|
|
1569
1601
|
//#region src/client/host-compat/versions/v0-2-1/adapter.ts
|
|
1570
1602
|
/**
|
|
1571
1603
|
* Adapter for the DSH `0.2.1` patch line, verified at `0.2.1-alpha.1`,
|
|
1572
|
-
* `alpha.2`, `alpha.3`, `alpha.4`, `alpha.5`, `rc.1`, `rc.2`
|
|
1604
|
+
* `alpha.2`, `alpha.3`, `alpha.4`, `alpha.5`, `rc.1`, `rc.2`, `rc.3`, `rc.4`
|
|
1605
|
+
* and `rc.5`.
|
|
1573
1606
|
*
|
|
1574
1607
|
* A new MINOR line opened with a prerelease, and the answer is the `0.2.0-rc.2`
|
|
1575
1608
|
* folder's — which is a statement this file has to earn, because "same as the
|
|
@@ -1621,6 +1654,25 @@ window.__ModuleLoader__.load({
|
|
|
1621
1654
|
* More launcher's classes). Layout inside the header, not a surface the
|
|
1622
1655
|
* plugin styles by these class names.
|
|
1623
1656
|
*
|
|
1657
|
+
* Re-checked at `0.2.1-rc.4` and `rc.5`, and the answer is blunter than for `rc.3`:
|
|
1658
|
+
* those two builds ship artifacts BYTE-IDENTICAL to `rc.3`. The whole install was
|
|
1659
|
+
* hashed — 296 `@deepseek-ai/dsh-*` packages, 5604 shipped files — and 30 files
|
|
1660
|
+
* moved across `rc.3 → rc.5`, none of them a stylesheet this folder speaks for:
|
|
1661
|
+
* · `ui-sidebar`, `ui-settings-general`, `ui-settings-account` changed only an
|
|
1662
|
+
* inlined version-string literal; `ui-llm-deepseek-account`, `dsh-mcp-client`
|
|
1663
|
+
* and `dsh-mcp-resources` are not surfaces at all.
|
|
1664
|
+
* · `ui-conversation` (`rc.4`) made the header View tab label's tooltip
|
|
1665
|
+
* CONDITIONAL — `ViewTabLabel` now passes `disabled: !labelNeedsTooltip(label)`
|
|
1666
|
+
* and keeps `portal: true`. It stays a body-level portal (z-1100, §2-T), so the
|
|
1667
|
+
* `dab-part-blur-side` lift of `rc.3`'s issue #32 is unaffected: the arm that
|
|
1668
|
+
* needed the lift was the in-place `span[role=tooltip]`, and this one never was.
|
|
1669
|
+
* · `ui-chat` + `cordis-client-runner` (`rc.5`) moved the reasoning-body slot
|
|
1670
|
+
* contract: `ReasoningBodyOwnerProps` gains `rawText`, and a new
|
|
1671
|
+
* `reasoningText()` helper strips a leading `<signature>` block. This plugin
|
|
1672
|
+
* registers no chat slot, so it reads none of that contract.
|
|
1673
|
+
* No token, no `[class*="…"]` shape, no `z-index` and no `data-slot` key moved on
|
|
1674
|
+
* either build, so `rc.4`/`rc.5` join this folder's name instead of opening one.
|
|
1675
|
+
*
|
|
1624
1676
|
* Re-checked again across the rest of the line (`alpha.3` … `rc.2`, `git diff
|
|
1625
1677
|
* <tag> rc.2` on every file above): the menu token contract, both menu stylesheets
|
|
1626
1678
|
* (`MenuSurface`, `MenuGroup`), `gradient-shadow-text.css` / `base.css`,
|
|
@@ -1704,6 +1756,105 @@ window.__ModuleLoader__.load({
|
|
|
1704
1756
|
*
|
|
1705
1757
|
* @module
|
|
1706
1758
|
*/
|
|
1759
|
+
function panelFragments$2() {
|
|
1760
|
+
return {
|
|
1761
|
+
promotion: "",
|
|
1762
|
+
blur: panelBlurRule(DOCKKIT_SLIDERS)
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
function createAdapter$2(host) {
|
|
1766
|
+
return {
|
|
1767
|
+
id: "0.2.1-alpha.1…rc.5",
|
|
1768
|
+
channel: "0.2.1",
|
|
1769
|
+
host,
|
|
1770
|
+
panelFragments: panelFragments$2,
|
|
1771
|
+
pluginPageRule: PLUGIN_PAGE_FROST_RULE,
|
|
1772
|
+
menus: LAYERED_MENU_SURFACE_WITH_GROUP_HEADER,
|
|
1773
|
+
surface: {
|
|
1774
|
+
ownsSidebarGuideSurface: true,
|
|
1775
|
+
headerSlotKeys: BASE_HEADER_SLOT_KEYS
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
}
|
|
1779
|
+
//#endregion
|
|
1780
|
+
//#region src/client/host-compat/versions/v0-2-2/adapter.ts
|
|
1781
|
+
/**
|
|
1782
|
+
* Adapter for the DSH `0.2.2` patch line, verified at `0.2.2-alpha.2`.
|
|
1783
|
+
*
|
|
1784
|
+
* A second MINOR line opened (`0.2.2-alpha.2` is the `alpha` dist-tag; no `alpha.1`
|
|
1785
|
+
* was ever published), and the answer it gives is the `0.2.1` folder's. That is a
|
|
1786
|
+
* claim this file has to earn rather than inherit — `0.2.2-alpha.2` is a large
|
|
1787
|
+
* release: across the 296 `@deepseek-ai/dsh-*` packages of a `0.2.1-rc.5` install,
|
|
1788
|
+
* 1151 shipped files changed, 1709 were added and 57 removed. What matters is that
|
|
1789
|
+
* none of them is a fact this plugin speaks for. Every claim below was read out of
|
|
1790
|
+
* the published artifacts of `0.2.2-alpha.2` and compared against `0.2.1-rc.5`.
|
|
1791
|
+
*
|
|
1792
|
+
* Earned (identical, so the same constants are returned):
|
|
1793
|
+
* · The z-index ladder of §2-T is byte-for-byte the load-bearing one:
|
|
1794
|
+
* `ui-layout` still emits `_handle{z-index:11…`, `_leadingSeat{z-index:15…` and
|
|
1795
|
+
* `_overlayLayer{z-index:20…`. So `dab-part-blur-side`'s ceiling of 1 and
|
|
1796
|
+
* `HEADER_BAR_RULE`'s 10 are argued exactly as before. The only `z-index` deltas
|
|
1797
|
+
* on the whole line are local values in `ui-chat` (6), `client-ui-plugin-manager`
|
|
1798
|
+
* (2) and `ui-settings-models` (1), plus one removed in
|
|
1799
|
+
* `ui-sidebar-documentpreview` (2) — none of them a layer the ladder names.
|
|
1800
|
+
* · The menu frost contract is unchanged: `--dsw-menu-surface-fill` still
|
|
1801
|
+
* `#f8f9fa94` / `#43454a73`, `--dsw-specific-menu` still
|
|
1802
|
+
* `var(--dsw-menu-surface-fill)` with the darwin scheme override intact,
|
|
1803
|
+
* `--dsw-alias-menu-group-header-fill` still `#f8f9faf0` / `#303136f0`, and the
|
|
1804
|
+
* same 8 packages still consume `--dsw-menu-backdrop-filter`. That is
|
|
1805
|
+
* `LAYERED_MENU_SURFACE_WITH_GROUP_HEADER`, unchanged.
|
|
1806
|
+
* · `ui-theme` still composes the font token itself on `body`
|
|
1807
|
+
* (`--dsw-font-family: var(--dsh-font-family-text, var(--dsh-font-family-text-default)),
|
|
1808
|
+
* var(--dsh-font-family-text-default)`), which is precisely the competitor
|
|
1809
|
+
* `applyFontFace`'s `!important` assertion was added to beat (§E, same specificity,
|
|
1810
|
+
* order decides). It still has to win, so the rule stays.
|
|
1811
|
+
* · `data-shimmer` still occurs the same number of times → the rc.1 stroke
|
|
1812
|
+
* exemption stands; `data-shell-bottom` / `data-rightbar-col` likewise, so
|
|
1813
|
+
* `discoverParts()` still anchors on the same two children.
|
|
1814
|
+
* · All five `conversation.session.header*` slot keys are unchanged, and
|
|
1815
|
+
* `conversation.session.header.views.actions` is still the one addition — the
|
|
1816
|
+
* tagger's portaled arm already covers it.
|
|
1817
|
+
* · Selector resolution: of the 75 host attribute/class selectors this plugin's
|
|
1818
|
+
* rules name, all 75 still match host output; 13 changed occurrence COUNT
|
|
1819
|
+
* (`_panel` 88→96, `_portal` 4→6, `data-dockkit-host` 8→10,
|
|
1820
|
+
* `data-windows-titlebar` 35→51 …), none reached zero. All nine
|
|
1821
|
+
* `[class*="_…"]` shapes are unchanged.
|
|
1822
|
+
* · `dsh-app-boot`'s peer gate is byte-identical: same
|
|
1823
|
+
* `name !== "@deepseek-ai/dsh" && !name.startsWith("@deepseek-ai/dsh-")` prefix
|
|
1824
|
+
* test, same `satisfies(…, { includePrerelease: true })`. §C's four-place
|
|
1825
|
+
* enumeration means the same thing on this line as on the last.
|
|
1826
|
+
*
|
|
1827
|
+
* Two host-side deltas did reach this plugin. Neither is a rule change, and both are
|
|
1828
|
+
* recorded here because they are the two places a 0.2.2 bug report will land:
|
|
1829
|
+
* 1. `--dsw-specific-sidebar-nav-item-hover` is DELETED. Its only consumer was
|
|
1830
|
+
* `ui-settings-general`'s sidebar nav hover, and that rule is gone with it — the
|
|
1831
|
+
* host stopped painting the hover at all. `paletteTokens()` still emits the token
|
|
1832
|
+
* (`utils/color.ts`, both scheme blocks), which on this line writes a custom
|
|
1833
|
+
* property nobody reads. Harmless, still correct on 0.2.0/0.2.1, and NOT a reason
|
|
1834
|
+
* to branch: nothing regressed relative to the host's own default.
|
|
1835
|
+
* 2. `ui-plugin-manager` gained a NEW consumer of `--dsw-alias-bg-base` — the token
|
|
1836
|
+
* the 「主界面」 slider takes over:
|
|
1837
|
+
* `.…_pageBar[data-natural]:before{background:var(--dsw-alias-bg-base);pointer-events:none;
|
|
1838
|
+
* inset:0 0 auto}`. This is §2-V's "who reads this token" question, and the
|
|
1839
|
+
* answer now has one more host-side row. At the default (`opacities.bg = 0`) it
|
|
1840
|
+
* paints nothing, which is what the slider intends, and the plugin already frames
|
|
1841
|
+
* that page (`PLUGIN_PAGE_FROST_RULE`), so nothing is pinned. If a 0.2.2 report
|
|
1842
|
+
* says the plugin-manager page header shows a seam or a doubled band, start here.
|
|
1843
|
+
*
|
|
1844
|
+
* New host tokens on this line that this plugin does NOT claim: the
|
|
1845
|
+
* `--dsw-alias-illustration-*` family (6), `--dsw-alias-state-done-primary`,
|
|
1846
|
+
* `--dsh-dockkit-float-{x,y,width,height}`, `--dsh-sidebar-{paint-inset,row-padding,
|
|
1847
|
+
* label-gap}`, `--dsh-hairline-width`, `--dsh-button-outline-color`,
|
|
1848
|
+
* `--dsh-tab-hit-inline`. `--dsh-dockkit-float-top`, which the panel rule does read,
|
|
1849
|
+
* is still there. If a future surface stops following the theme colour, check whether
|
|
1850
|
+
* it paints from one of these instead.
|
|
1851
|
+
*
|
|
1852
|
+
* NOT done for this line: no real-host smoke. Only `0.2.1-rc.3` is installed on the
|
|
1853
|
+
* machine this folder was written from, so §4.3 is still open for 0.2.2 — the claims
|
|
1854
|
+
* above are artifact reads, not screenshots.
|
|
1855
|
+
*
|
|
1856
|
+
* @module
|
|
1857
|
+
*/
|
|
1707
1858
|
function panelFragments$1() {
|
|
1708
1859
|
return {
|
|
1709
1860
|
promotion: "",
|
|
@@ -1712,8 +1863,8 @@ window.__ModuleLoader__.load({
|
|
|
1712
1863
|
}
|
|
1713
1864
|
function createAdapter$1(host) {
|
|
1714
1865
|
return {
|
|
1715
|
-
id: "0.2.
|
|
1716
|
-
channel: "0.2.
|
|
1866
|
+
id: "0.2.2-alpha.2",
|
|
1867
|
+
channel: "0.2.2",
|
|
1717
1868
|
host,
|
|
1718
1869
|
panelFragments: panelFragments$1,
|
|
1719
1870
|
pluginPageRule: PLUGIN_PAGE_FROST_RULE,
|
|
@@ -1769,9 +1920,10 @@ window.__ModuleLoader__.load({
|
|
|
1769
1920
|
//#endregion
|
|
1770
1921
|
//#region src/client/host-compat/versions/registry.ts
|
|
1771
1922
|
const ADAPTERS = {
|
|
1772
|
-
"0.2.0-rc": createAdapter$
|
|
1773
|
-
"0.2.0-rc.2": createAdapter$
|
|
1774
|
-
"0.2.1": createAdapter$
|
|
1923
|
+
"0.2.0-rc": createAdapter$4,
|
|
1924
|
+
"0.2.0-rc.2": createAdapter$3,
|
|
1925
|
+
"0.2.1": createAdapter$2,
|
|
1926
|
+
"0.2.2": createAdapter$1,
|
|
1775
1927
|
unknown: createAdapter
|
|
1776
1928
|
};
|
|
1777
1929
|
/** Pick the adapter for a resolved host. `host.channel` is already narrowed to
|
|
@@ -1800,7 +1952,7 @@ window.__ModuleLoader__.load({
|
|
|
1800
1952
|
/** False until the server verdict lands. Feature gates must not read "not asked
|
|
1801
1953
|
* yet" as "an old host" — see `adapterResolved()`. */
|
|
1802
1954
|
let resolved = false;
|
|
1803
|
-
const subs$
|
|
1955
|
+
const subs$2 = /* @__PURE__ */ new Set();
|
|
1804
1956
|
/** Cached adapter, keyed by the verdict it was built from. Held because React's
|
|
1805
1957
|
* `useSyncExternalStore` requires a stable snapshot between notifications. */
|
|
1806
1958
|
let adapterCache = null;
|
|
@@ -1823,14 +1975,14 @@ window.__ModuleLoader__.load({
|
|
|
1823
1975
|
resolved = true;
|
|
1824
1976
|
if (changed) {
|
|
1825
1977
|
adapterCache = null;
|
|
1826
|
-
subs$
|
|
1978
|
+
subs$2.forEach((cb) => cb());
|
|
1827
1979
|
}
|
|
1828
1980
|
}
|
|
1829
1981
|
/** Subscribe to the verdict landing (or changing). */
|
|
1830
1982
|
function subscribeHostInfo(cb) {
|
|
1831
|
-
subs$
|
|
1983
|
+
subs$2.add(cb);
|
|
1832
1984
|
return () => {
|
|
1833
|
-
subs$
|
|
1985
|
+
subs$2.delete(cb);
|
|
1834
1986
|
};
|
|
1835
1987
|
}
|
|
1836
1988
|
/** Whether the server verdict has landed at all. */
|
|
@@ -2243,14 +2395,21 @@ window.__ModuleLoader__.load({
|
|
|
2243
2395
|
}
|
|
2244
2396
|
//#endregion
|
|
2245
2397
|
//#region src/client/dom-watch.ts
|
|
2246
|
-
const listeners =
|
|
2398
|
+
const listeners = {
|
|
2399
|
+
body: /* @__PURE__ */ new Set(),
|
|
2400
|
+
head: /* @__PURE__ */ new Set()
|
|
2401
|
+
};
|
|
2247
2402
|
let observer = null;
|
|
2248
|
-
/** Subscribe to
|
|
2249
|
-
function watchDom(cb) {
|
|
2250
|
-
listeners.add(cb);
|
|
2403
|
+
/** Subscribe to mutations of one tree. Returns an unsubscribe. */
|
|
2404
|
+
function watchDom(cb, target = "body") {
|
|
2405
|
+
listeners[target].add(cb);
|
|
2251
2406
|
if (observer === null && typeof MutationObserver !== "undefined" && typeof document !== "undefined") {
|
|
2252
2407
|
observer = new MutationObserver((records) => {
|
|
2253
|
-
for (const l of listeners) l(records);
|
|
2408
|
+
for (const l of listeners.body) l(records);
|
|
2409
|
+
if (listeners.head.size > 0) {
|
|
2410
|
+
const head = records.filter((r) => r.target === document.head);
|
|
2411
|
+
if (head.length > 0) for (const l of listeners.head) l(head);
|
|
2412
|
+
}
|
|
2254
2413
|
});
|
|
2255
2414
|
observer.observe(document.body, {
|
|
2256
2415
|
childList: true,
|
|
@@ -2258,10 +2417,11 @@ window.__ModuleLoader__.load({
|
|
|
2258
2417
|
attributes: true,
|
|
2259
2418
|
attributeFilter: ["aria-expanded"]
|
|
2260
2419
|
});
|
|
2420
|
+
observer.observe(document.head, { childList: true });
|
|
2261
2421
|
}
|
|
2262
2422
|
return () => {
|
|
2263
|
-
listeners.delete(cb);
|
|
2264
|
-
if (listeners.size === 0) {
|
|
2423
|
+
listeners[target].delete(cb);
|
|
2424
|
+
if (listeners.body.size + listeners.head.size === 0) {
|
|
2265
2425
|
observer?.disconnect();
|
|
2266
2426
|
observer = null;
|
|
2267
2427
|
}
|
|
@@ -3741,6 +3901,12 @@ window.__ModuleLoader__.load({
|
|
|
3741
3901
|
"--dsw-specific-input-major": "--dsh-any-op-input",
|
|
3742
3902
|
"--dsw-specific-menu": "--dsh-any-op-menu"
|
|
3743
3903
|
};
|
|
3904
|
+
/** Every host token this plugin re-emits on `body` at a slider's alpha. Exported
|
|
3905
|
+
* because it is also the answer to "what can another plugin collide with": anything
|
|
3906
|
+
* that fills from one of these names fades with our sliders whether or not its author
|
|
3907
|
+
* knew we existed — the whole of §2-V. `third-party.ts` scans installed plugin
|
|
3908
|
+
* stylesheets for exactly this list. */
|
|
3909
|
+
const OWNED_TOKENS = Object.keys(OPACITY_VARS);
|
|
3744
3910
|
let baseTokenKey = "";
|
|
3745
3911
|
let pendingOps = null;
|
|
3746
3912
|
let tokensRaf = null;
|
|
@@ -3877,6 +4043,7 @@ window.__ModuleLoader__.load({
|
|
|
3877
4043
|
applyPartOpacities(ops);
|
|
3878
4044
|
}
|
|
3879
4045
|
applyExemptDefaults();
|
|
4046
|
+
applyReaderLanes(surfaces);
|
|
3880
4047
|
} catch {}
|
|
3881
4048
|
}
|
|
3882
4049
|
const SETTINGS_PANEL_SEL = "[role=\"dialog\"][aria-modal=\"true\"][aria-labelledby][class*=\"_panel\"]";
|
|
@@ -4417,7 +4584,8 @@ window.__ModuleLoader__.load({
|
|
|
4417
4584
|
const dialog = "[role=\"dialog\"][aria-modal=\"true\"]:not([aria-labelledby])";
|
|
4418
4585
|
const registry = "[data-install-registry]";
|
|
4419
4586
|
const body = decls.join(";");
|
|
4420
|
-
const
|
|
4587
|
+
const ground = source?.["--dsw-alias-bg-base"];
|
|
4588
|
+
const css = `${dialog},${dialog} *{${ground === void 0 || ground === "" ? body : `${body};--dsw-alias-bg-base:${toRgba(ground, 1)}`}}[role="menu"]:has([class*="_danger"]){${body}}${registry},${registry} *{${body}}`;
|
|
4421
4589
|
if (el.textContent !== css) el.textContent = css;
|
|
4422
4590
|
}
|
|
4423
4591
|
let exemptStyleEl = null;
|
|
@@ -4428,6 +4596,89 @@ window.__ModuleLoader__.load({
|
|
|
4428
4596
|
document.head.appendChild(exemptStyleEl);
|
|
4429
4597
|
return exemptStyleEl;
|
|
4430
4598
|
}
|
|
4599
|
+
const READER_ROOT = "[data-dsh-better-display]:not([data-reader-glass])";
|
|
4600
|
+
/** Plate density the lanes are pinned at: 「主界面」 at 20% — a band that reads as a
|
|
4601
|
+
* band while still letting the wallpaper through. */
|
|
4602
|
+
const READER_LANE_ALPHA = .2;
|
|
4603
|
+
/** Frost the lanes are pinned at (px) — the middle of the 0–60 blur range, i.e. the
|
|
4604
|
+
* plugin's own default, so the band looks like every other frosted surface here. */
|
|
4605
|
+
const READER_LANE_BLUR_PX = 30;
|
|
4606
|
+
/** The sticky wrapper holding the status lane and the closed-turn digest. It paints
|
|
4607
|
+
* NOTHING today (`Reader.module.css:27`), and `:556` forces both children
|
|
4608
|
+
* `position:static; z-index:auto` — so it is the one element whose box can simply BE
|
|
4609
|
+
* the band: one plate, one frost region, one pair of rounded corners. */
|
|
4610
|
+
const READER_WRAP = `${READER_ROOT} [class*="_turnStickyLanes"]`;
|
|
4611
|
+
/** The band's two height levers, both published by that plugin itself
|
|
4612
|
+
* (`StickyLane.tsx:11-13` writes the measured toolbar and status-lane heights onto
|
|
4613
|
+
* ancestors the wrapper inherits from), so the merged box tracks real text wrapping
|
|
4614
|
+
* instead of a hardcoded 40px. */
|
|
4615
|
+
const READER_TOOLBAR_H = "var(--reader-toolbar-height,40px)";
|
|
4616
|
+
const READER_BAND_TOP = `max(${READER_TOOLBAR_H},var(--reader-status-height,40px))`;
|
|
4617
|
+
/** The two surfaces that paint a band, spelled once so the static and dynamic halves
|
|
4618
|
+
* cannot drift: the merged wrapper, and the live-fold summary cell — which cannot be
|
|
4619
|
+
* merged into it, because it sticks at `z-index:5` BELOW the wrapper's 6, so growing
|
|
4620
|
+
* the wrapper over that row would paint the wrapper's plate straight across the row's
|
|
4621
|
+
* own text (tried, measured, reverted). */
|
|
4622
|
+
const READER_LANE_SEL = `${READER_WRAP},${READER_ROOT} [data-flow-summary]`;
|
|
4623
|
+
/** Everything that used to paint its own plate and must stop now that the wrapper
|
|
4624
|
+
* does. Their plates are what made the stack read as separate bars: the status lane is
|
|
4625
|
+
* `width:calc(100% - var(--reader-control-width))` (`:546`) so it notched short of the
|
|
4626
|
+
* toolbar's width, and each `box-shadow` gap plate (`:555/:564/:565`) lands on a
|
|
4627
|
+
* neighbour and doubles the alpha there — a 14–16px darker strip per seam.
|
|
4628
|
+
*
|
|
4629
|
+
* The toolbar lane hands its plate over only while a band exists to swallow it: a turn
|
|
4630
|
+
* with no process steps renders no wrapper at all, and there the strip would be left
|
|
4631
|
+
* with nothing behind its own button. It can be swallowed at all because its
|
|
4632
|
+
* `z-index:7` (`:538`) sits ABOVE the wrapper's 6 — its own text keeps painting over
|
|
4633
|
+
* the merged plate, which is exactly the arrangement the live-fold cell cannot use. */
|
|
4634
|
+
const READER_SILENT = `${READER_WRAP}>*,${READER_ROOT}:has([class*="_turnStickyLanes"]) [data-reader-lane="toolbar"]`;
|
|
4635
|
+
/** Static half — the merge, the frost, the shape. Every value is a literal or one of
|
|
4636
|
+
* that plugin's own published variables; nothing here reads a slider, which is what
|
|
4637
|
+
* makes the band immune to 调控.
|
|
4638
|
+
*
|
|
4639
|
+
* It is TEXT in the dynamic sheet rather than a rule in `buildStaticStyles()`, and
|
|
4640
|
+
* that is the point: the static sheet is this plugin's contract with the HOST, and a
|
|
4641
|
+
* third-party accommodation must be able to vanish completely — paint, frost and the
|
|
4642
|
+
* merged box's geometry alike — when 「保护第三方表面」 is switched off. One sheet, one
|
|
4643
|
+
* owner, one thing to remove.
|
|
4644
|
+
*
|
|
4645
|
+
* HOW THE BOX GROWS WITHOUT MOVING CONTENT: `padding-top` reaches up over the toolbar
|
|
4646
|
+
* strip and an equal negative `margin-top` cancels it, so the wrapper's margin box
|
|
4647
|
+
* keeps its height and every following sibling stays exactly where it was; `top` is
|
|
4648
|
+
* pulled up by the same amount so the STUCK position puts the wrapper's content back at
|
|
4649
|
+
* `max(toolbar, status)`. The lanes' text does not move a pixel — only the paint does.
|
|
4650
|
+
* Measured in the §4.2 mock with the pin on and off: the column's height and the first
|
|
4651
|
+
* paragraph's offset are identical, and the status row's `top` is unchanged.
|
|
4652
|
+
*
|
|
4653
|
+
* The rounded bottom goes on whichever band is actually LAST: the live-fold cell sticks
|
|
4654
|
+
* 40px below the wrapper (`:558`), so while the turn has one the wrapper is not the
|
|
4655
|
+
* bottom edge and rounding it would open a notch against the cell under it. A build
|
|
4656
|
+
* without `:has()` keeps both bands square; nothing else changes. */
|
|
4657
|
+
const READER_LANE_RULE = `${READER_LANE_SEL}{background:var(--dsw-alias-bg-base);box-shadow:none;${elementFrostDecl(`blur(${READER_LANE_BLUR_PX}px)`)}}${READER_WRAP}{border-radius:0 0 14px 14px;padding-top:${READER_TOOLBAR_H};margin-top:calc(0px - ${READER_TOOLBAR_H});top:calc(${READER_BAND_TOP} - ${READER_TOOLBAR_H})}${READER_ROOT} [data-flow-summary]{border-radius:0 0 14px 14px}${READER_ROOT} [data-reader-turn]:has([data-flow-summary]) [class*="_turnStickyLanes"]{border-radius:0}${READER_SILENT}{background:transparent;box-shadow:none}`;
|
|
4658
|
+
let readerStyleEl = null;
|
|
4659
|
+
/** Emit the whole pin — geometry, frost and the plate literal — into one sheet, or
|
|
4660
|
+
* remove that sheet entirely. Two things switch it off: 「保护第三方表面」 being turned
|
|
4661
|
+
* off, and no color resolving yet (the palette and the host's own tokens are both
|
|
4662
|
+
* empty pre-boot), because a `var()` naming an unwritten property is the §2-E
|
|
4663
|
+
* guaranteed-invalid trap and its symptom here is the very bug being pinned. */
|
|
4664
|
+
function applyReaderLanes(surfaces) {
|
|
4665
|
+
if (typeof document === "undefined") return;
|
|
4666
|
+
const base = rProtectThirdParty() ? (surfaces ?? paletteTokens() ?? readHostOpacityTokens())?.["--dsw-alias-bg-base"] : void 0;
|
|
4667
|
+
if (base === void 0 || base === "") {
|
|
4668
|
+
if (readerStyleEl !== null) {
|
|
4669
|
+
readerStyleEl.remove();
|
|
4670
|
+
readerStyleEl = null;
|
|
4671
|
+
}
|
|
4672
|
+
return;
|
|
4673
|
+
}
|
|
4674
|
+
if (readerStyleEl === null) {
|
|
4675
|
+
readerStyleEl = document.createElement("style");
|
|
4676
|
+
readerStyleEl.dataset.plugin = "dsh-any-background-reader";
|
|
4677
|
+
document.head.appendChild(readerStyleEl);
|
|
4678
|
+
}
|
|
4679
|
+
const css = `${READER_LANE_RULE}${READER_LANE_SEL}{--dsw-alias-bg-base:${toRgba(base, READER_LANE_ALPHA)}}`;
|
|
4680
|
+
if (readerStyleEl.textContent !== css) readerStyleEl.textContent = css;
|
|
4681
|
+
}
|
|
4431
4682
|
const PRODUCED_RULE = `[data-code-block-content] pre,[data-code-block-banner],[data-composer-chip],[data-changed-files],[data-terminal],[data-read],[data-diff],[data-context-injection-body],[data-search],[data-web],[class*="_ioCard"],[data-inspect],[data-turn-trigger],[style*="--dsh-hover-preview-fade"],:not(pre)>code{-webkit-backdrop-filter:var(--dsh-any-blur-prod,none);backdrop-filter:var(--dsh-any-blur-prod,none)}[data-markdown-variant="compact"] :not(pre)>code{-webkit-backdrop-filter:none;backdrop-filter:none}${BETTER_SIDEBAR_PANEL}{-webkit-backdrop-filter:var(--dsh-any-blur-prod,none);backdrop-filter:var(--dsh-any-blur-prod,none)}${BETTER_SIDEBAR_PANEL}{--dsw-alias-bg-base:var(--dsh-any-prod-panel-bg-base);--dsw-alias-bg-layer-1:var(--dsh-any-prod-panel-layer-1);--dsw-alias-bg-layer-2:var(--dsh-any-prod-panel-layer-2);--dsw-alias-bg-layer-3:var(--dsh-any-prod-panel-layer-3)}@supports (background:color-mix(in srgb,red 50%,transparent)){.md-code-block{background:transparent!important}.md-code-block>div{background-color:transparent!important}.md-code-block [data-code-block-content] pre{background-color:color-mix(in srgb,var(--dsl-code-block-background,var(--dsw-alias-markdown-code-block,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}.md-code-block [data-code-block-banner]{background-color:color-mix(in srgb,var(--dsl-code-block-banner-background-color,var(--dsw-alias-markdown-code-block-banner,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}[data-code-block-banner]{background-color:color-mix(in srgb,var(--dsl-code-block-banner-background-color,var(--dsl-code-block-background,var(--dsw-alias-markdown-code-block,transparent))) var(--dsh-any-prod-pct,100%),transparent)!important}[data-code-block-content]{--shiki-background:color-mix(in srgb,var(--dsw-alias-markdown-code-block,var(--dsl-code-block-background,transparent)) var(--dsh-any-prod-pct,100%),transparent)}:not(pre)>code{background-color:color-mix(in srgb,var(--dsw-alias-markdown-inline-code,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[data-composer-chip]>*{background-color:color-mix(in srgb,var(--dsw-alias-interactive-bg-hover,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[data-terminal]{background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[data-terminal] button{background-color:transparent!important}[data-read],[data-diff]{background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[data-read]>div:first-child:not([data-code-block-banner]),[data-diff]>div:first-child:not([data-code-block-banner]){background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block-banner,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[data-context-injection-body]{background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[data-inspect]{background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[data-turn-trigger]{background-color:color-mix(in srgb,var(--dsw-alias-turn-trigger-bg,var(--dsw-alias-markdown-code-block,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}[data-turn-trigger]:hover{background-color:color-mix(in srgb,var(--dsw-alias-turn-trigger-bg-hover,var(--dsw-alias-interactive-bg-hover,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}[data-changed-files]{background-color:var(--dsh-any-prod-layer-1,var(--dsw-alias-bg-layer-1,transparent))!important}[data-changed-files]>button:first-child{background-color:color-mix(in srgb,var(--changes-fill,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[data-changed-files]>button:first-child:hover{background-color:color-mix(in srgb,var(--changes-hover,var(--changes-fill,transparent)) var(--dsh-any-prod-pct,100%),transparent)!important}[data-changed-files]>button:first-child>span:first-child{background-color:color-mix(in srgb,var(--changes-fill,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[style*="--dsh-hover-preview-fade"]{background-color:color-mix(in srgb,var(--dsw-hovercard-bg,#2c2c2e) var(--dsh-any-prod-pct,100%),transparent)!important}[style*="--dsh-hover-preview-fade"][class*="_preview"]{background-color:var(--dsh-any-prod-layer-1,var(--dsw-alias-bg-layer-1,transparent))!important}[data-search]{background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[data-web]{background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}[class*="_ioCard"]{background-color:color-mix(in srgb,var(--dsw-alias-markdown-code-block,transparent) var(--dsh-any-prod-pct,100%),transparent)!important}}`;
|
|
4432
4683
|
const STROKE_RULE = [
|
|
4433
4684
|
`${SETTINGS_PANEL_SEL}{-webkit-text-stroke:var(--dsh-any-stroke-settings-w,0px) var(--dsh-any-stroke-settings-c,transparent);paint-order:stroke fill}`,
|
|
@@ -4790,6 +5041,45 @@ window.__ModuleLoader__.load({
|
|
|
4790
5041
|
let rightEl = null;
|
|
4791
5042
|
const PART_BLUR_CLASS = "dab-part-blur";
|
|
4792
5043
|
const PART_UNDERLAY_CLASS = "dab-part-underlay";
|
|
5044
|
+
/** Paint-order lift for the frosted SIDEBAR column (issue #32).
|
|
5045
|
+
*
|
|
5046
|
+
* The host's `Tooltip` bubble is an IN-PLACE `span[role="tooltip"]`: its sheet
|
|
5047
|
+
* (`dsh-web-frontend` `Tooltip.module.css`, read on 0.2.1-rc.3) reads
|
|
5048
|
+
* `position:fixed;z-index:100`, going to `z-index:1100` only under
|
|
5049
|
+
* `[data-portal]` — and the `portal` prop defaults to FALSE, which the
|
|
5050
|
+
* workspace browser's 添加工作区 trigger (`ui-workspace` `headerActions`) does
|
|
5051
|
+
* not pass. `position:fixed` keeps the bubble anchored to the viewport, but
|
|
5052
|
+
* its z-index only competes INSIDE the nearest stacking-context ancestor. The
|
|
5053
|
+
* frosted sidebar column IS that ancestor — `PART_BLUR_RULE`'s
|
|
5054
|
+
* `isolation:isolate` is what keeps the underlay's `z-index:-1` inside — so
|
|
5055
|
+
* the bubble, hanging below the icon row and past the column's right edge, is
|
|
5056
|
+
* painted as part of the sidebar's subtree, and the center column (a later
|
|
5057
|
+
* sibling, itself an isolated stacking context once 「主界面」模糊 is up)
|
|
5058
|
+
* paints its translucent fill + frost OVER the overhang: the tooltip's right
|
|
5059
|
+
* half comes out blurred and tinted. The trap is not the tooltip's alone —
|
|
5060
|
+
* every in-place float the sidebar hangs (the workspace pick flow anchors
|
|
5061
|
+
* there too) sits in the same local context.
|
|
5062
|
+
*
|
|
5063
|
+
* Lifting the FROSTED sidebar column to `z-index:1` moves its whole paint
|
|
5064
|
+
* slot after the center column's. The two are grid siblings on separate
|
|
5065
|
+
* tracks — they never overlap geometrically, so the lift only matters to
|
|
5066
|
+
* floating layers that overhang a column edge, which is exactly the set that
|
|
5067
|
+
* must win. It stays below everything that has to beat it: the host's overlay
|
|
5068
|
+
* layer (`AppFrame.module.css` `.overlayLayer{z-index:20}`, byte-identical on
|
|
5069
|
+
* 0.2.0-rc.1 and 0.2.1-rc.3), the settings modal (it escapes the center
|
|
5070
|
+
* column through the `isolation:auto` arm below and carries z-index 1000+),
|
|
5071
|
+
* and body-level portaled menus/tooltips (z-index 100 / 1100). Grid items
|
|
5072
|
+
* honor `z-index` without `position`, so this lands even on a column the
|
|
5073
|
+
* host leaves `static`.
|
|
5074
|
+
*
|
|
5075
|
+
* The `:has([role="dialog"])` arm must pair `z-index:auto` with the
|
|
5076
|
+
* isolation arm: with the settings view open the sidebar column itself holds
|
|
5077
|
+
* a `[role="dialog"]` (counted live when the isolation arm was written), and
|
|
5078
|
+
* a column pinned at `z-index:1` would REMAIN a stacking context through that
|
|
5079
|
+
* arm — the dialog would keep its z-index local and paint under the overlay
|
|
5080
|
+
* layer instead of covering the page. Back at `auto` it escapes the column
|
|
5081
|
+
* exactly as it did before this class existed. */
|
|
5082
|
+
const PART_LIFT_CLASS = "dab-part-blur-side";
|
|
4793
5083
|
/** The AppFrame's main-bg clear-out, as a class rather than an inline write.
|
|
4794
5084
|
*
|
|
4795
5085
|
* WHY NOT INLINE (measured on 0.1.7): the frame's own translucent
|
|
@@ -4842,7 +5132,7 @@ window.__ModuleLoader__.load({
|
|
|
4842
5132
|
* `0.2.1-rc.3` (`AppFrame.module.css` byte-identical rc.2→rc.3). A build
|
|
4843
5133
|
* that renames the track simply stops matching, which is the untouched host look. */
|
|
4844
5134
|
const SIDEBAR_ONE_LAYER_RULE = "[class*=\"_sidebarCol\"] *{--dsw-specific-sidebar-fill:transparent}";
|
|
4845
|
-
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)}`;
|
|
5135
|
+
const PART_BLUR_RULE = `.${PART_BLUR_CLASS}{isolation:isolate}.${PART_BLUR_CLASS}:has([role="dialog"]){isolation:auto}.${PART_LIFT_CLASS}{z-index:1}.${PART_LIFT_CLASS}:has([role="dialog"]){z-index: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)}`;
|
|
4846
5136
|
let partBlurStyleEl = null;
|
|
4847
5137
|
function ensurePartBlurStyle() {
|
|
4848
5138
|
if (partBlurStyleEl?.isConnected) return;
|
|
@@ -4878,9 +5168,9 @@ window.__ModuleLoader__.load({
|
|
|
4878
5168
|
centerEl = children[overlayIdx - 2] ?? null;
|
|
4879
5169
|
}
|
|
4880
5170
|
}
|
|
4881
|
-
function setBlur(el, px) {
|
|
5171
|
+
function setBlur(el, px, lift = false) {
|
|
4882
5172
|
if (el === null) return;
|
|
4883
|
-
if (px === 0 && !el.classList.contains(PART_BLUR_CLASS) && el.getAttribute("data-dab-pos-patched") !== "1") return;
|
|
5173
|
+
if (px === 0 && !el.classList.contains(PART_BLUR_CLASS) && !el.classList.contains(PART_LIFT_CLASS) && el.getAttribute("data-dab-pos-patched") !== "1") return;
|
|
4884
5174
|
const underlay = el.querySelector(`:scope > .${PART_UNDERLAY_CLASS}`);
|
|
4885
5175
|
if (px > 0) {
|
|
4886
5176
|
ensurePartBlurStyle();
|
|
@@ -4889,6 +5179,7 @@ window.__ModuleLoader__.load({
|
|
|
4889
5179
|
el.setAttribute("data-dab-pos-patched", "1");
|
|
4890
5180
|
}
|
|
4891
5181
|
el.classList.add(PART_BLUR_CLASS);
|
|
5182
|
+
el.classList.toggle(PART_LIFT_CLASS, lift);
|
|
4892
5183
|
if (underlay === null) {
|
|
4893
5184
|
const node = document.createElement("div");
|
|
4894
5185
|
node.className = PART_UNDERLAY_CLASS;
|
|
@@ -4897,6 +5188,7 @@ window.__ModuleLoader__.load({
|
|
|
4897
5188
|
el.style.setProperty("--dsh-any-part-blur", `blur(${px}px)`);
|
|
4898
5189
|
} else {
|
|
4899
5190
|
el.classList.remove(PART_BLUR_CLASS);
|
|
5191
|
+
el.classList.remove(PART_LIFT_CLASS);
|
|
4900
5192
|
el.style.removeProperty("--dsh-any-part-blur");
|
|
4901
5193
|
underlay?.remove();
|
|
4902
5194
|
if (el.getAttribute("data-dab-pos-patched") === "1") {
|
|
@@ -4943,7 +5235,7 @@ window.__ModuleLoader__.load({
|
|
|
4943
5235
|
function applyPartBlurs(blurs) {
|
|
4944
5236
|
discoverParts();
|
|
4945
5237
|
setBlur(frameEl, 0);
|
|
4946
|
-
setBlur(sidebarEl, blurs.sidebar);
|
|
5238
|
+
setBlur(sidebarEl, blurs.sidebar, true);
|
|
4947
5239
|
setBlur(centerEl, blurs.bg);
|
|
4948
5240
|
setBlur(rightEl, 0);
|
|
4949
5241
|
applyBgBlurGlobal(blurs.bg);
|
|
@@ -5020,7 +5312,7 @@ window.__ModuleLoader__.load({
|
|
|
5020
5312
|
applyBgBlurGlobal(v);
|
|
5021
5313
|
return;
|
|
5022
5314
|
}
|
|
5023
|
-
setBlur(sidebarEl, v);
|
|
5315
|
+
setBlur(sidebarEl, v, true);
|
|
5024
5316
|
applySidebarBandBlur(v);
|
|
5025
5317
|
}
|
|
5026
5318
|
const VIEW_CARDS = [{
|
|
@@ -5628,6 +5920,7 @@ window.__ModuleLoader__.load({
|
|
|
5628
5920
|
}
|
|
5629
5921
|
applyPanelOverrides(rPanelOpacity());
|
|
5630
5922
|
applyExemptDefaults();
|
|
5923
|
+
applyReaderLanes();
|
|
5631
5924
|
applyPartBlurs(rBlurs());
|
|
5632
5925
|
applyStrokes();
|
|
5633
5926
|
}
|
|
@@ -5687,6 +5980,8 @@ window.__ModuleLoader__.load({
|
|
|
5687
5980
|
headerStyleEl = null;
|
|
5688
5981
|
exemptStyleEl?.remove();
|
|
5689
5982
|
exemptStyleEl = null;
|
|
5983
|
+
readerStyleEl?.remove();
|
|
5984
|
+
readerStyleEl = null;
|
|
5690
5985
|
for (const v of Object.values(OPACITY_VARS)) document.documentElement.style.removeProperty(v);
|
|
5691
5986
|
baseTokenKey = "";
|
|
5692
5987
|
lastBgKey = "";
|
|
@@ -7428,6 +7723,161 @@ window.__ModuleLoader__.load({
|
|
|
7428
7723
|
] });
|
|
7429
7724
|
}
|
|
7430
7725
|
//#endregion
|
|
7726
|
+
//#region src/client/third-party.ts
|
|
7727
|
+
/**
|
|
7728
|
+
* Third-party plugin compatibility — the registry, and the boot self-check that names
|
|
7729
|
+
* collisions out loud.
|
|
7730
|
+
*
|
|
7731
|
+
* WHY THIS FILE EXISTS
|
|
7732
|
+
* This plugin does not restyle surfaces; it re-emits HOST TOKENS on `<body>` at a
|
|
7733
|
+
* slider's alpha (`OWNED_TOKENS`), and every element that fills from one of those names
|
|
7734
|
+
* fades with it — the host's own, and any other plugin's too. A third-party author has
|
|
7735
|
+
* no reason to expect that: a sticky bar painted with `background:var(--dsw-alias-bg-base)`
|
|
7736
|
+
* is correct on an unthemed host and invisible on ours, because our 「主界面」 slider
|
|
7737
|
+
* defaults to 0. That is issue-class §2-V, and it was found the slow way — a user
|
|
7738
|
+
* reported unreadable text, and someone had to grep another plugin's stylesheet to see
|
|
7739
|
+
* which token it drank.
|
|
7740
|
+
*
|
|
7741
|
+
* WHAT THE SELF-CHECK DOES
|
|
7742
|
+
* Third-party plugins tag their own stylesheets (`style[data-plugin="<package>"]` —
|
|
7743
|
+
* dsh-better-display mounts exactly that, at module load, before any of its views
|
|
7744
|
+
* exists). So the page can answer "who is installed and what of ours do they read"
|
|
7745
|
+
* without anyone reporting it: scan those sheets, look for `var(--<owned token>)`, and
|
|
7746
|
+
* name each hit once in the console. A registered pin says so and stays quiet; an
|
|
7747
|
+
* UNREGISTERED collision logs a warning, which turns "the user finds broken pixels and
|
|
7748
|
+
* files an issue" into "the boot log already knows which plugin and which token".
|
|
7749
|
+
*
|
|
7750
|
+
* WHAT IT DELIBERATELY DOES NOT DO
|
|
7751
|
+
* It never auto-pins an unknown surface. Guessing which of another plugin's elements are
|
|
7752
|
+
* "supposed to stay legible" would repaint someone else's design on a heuristic — the
|
|
7753
|
+
* §2-G lesson about heuristics with side effects. Detection is automatic; protection is
|
|
7754
|
+
* a reviewed table entry, and the settings card exposes it so a user can switch the
|
|
7755
|
+
* whole class off.
|
|
7756
|
+
*/
|
|
7757
|
+
/** The table. Adding a plugin is one row here plus the CSS that honors it. */
|
|
7758
|
+
const THIRD_PARTY_PINS = [{
|
|
7759
|
+
plugin: "dsh-better-display",
|
|
7760
|
+
labelKey: "tpReaderLanes",
|
|
7761
|
+
probe: "[data-dsh-better-display]",
|
|
7762
|
+
tokens: ["--dsw-alias-bg-base"]
|
|
7763
|
+
}];
|
|
7764
|
+
/** This plugin's own sheets are tagged with its name (plus a suffix per table); they
|
|
7765
|
+
* consume the tokens by design, so they must never count as a collision. */
|
|
7766
|
+
const SELF = "dsh-any-background";
|
|
7767
|
+
/** The host's own client modules tag their stylesheets the same way — measured on
|
|
7768
|
+
* 0.2.1-rc.3: **157 of the 172 `style[data-plugin]` sheets on a real page belong to
|
|
7769
|
+
* `@deepseek-ai/…`**, and they read these tokens on purpose (fading them IS the
|
|
7770
|
+
* product). Treating them as collisions would concatenate ~540 KB of host CSS per
|
|
7771
|
+
* scan, warn about the host's own UI, and fill the settings card with a hundred rows.
|
|
7772
|
+
* So the host namespace is excluded by prefix. The cost of that rule is asymmetric on
|
|
7773
|
+
* purpose: a scoped third-party package gets missed (no log, no wrong pixel), while a
|
|
7774
|
+
* false positive would spam and mislead. */
|
|
7775
|
+
const HOST_NAMESPACE = "@deepseek-ai/";
|
|
7776
|
+
function isHost(name) {
|
|
7777
|
+
return name.startsWith(HOST_NAMESPACE);
|
|
7778
|
+
}
|
|
7779
|
+
function isSelf(name) {
|
|
7780
|
+
return name === SELF || name.startsWith("dsh-any-background-");
|
|
7781
|
+
}
|
|
7782
|
+
/** The package a sheet came from. Scoped names keep their scope (`@hytime/dsh-x` →
|
|
7783
|
+
* `@hytime/dsh-x`, not `@hytime`), and a `pkg/module.css`-style tag trims to its
|
|
7784
|
+
* package. Ordering matters: this runs AFTER the host/self tests, which must see the
|
|
7785
|
+
* raw attribute — truncating first turned `@deepseek-ai/dsh-client-ui-chat` into
|
|
7786
|
+
* `@deepseek-ai`, which no longer matches the `@deepseek-ai/` prefix and so let 157
|
|
7787
|
+
* host sheets through as one phantom "plugin" (found on the real host, not in the
|
|
7788
|
+
* mock: the mock only ever had one host-ish sheet to begin with). */
|
|
7789
|
+
function pluginKey(name) {
|
|
7790
|
+
if (name.startsWith("@")) {
|
|
7791
|
+
const i = name.indexOf("/", 1);
|
|
7792
|
+
return i > 0 ? name.slice(0, i) : name;
|
|
7793
|
+
}
|
|
7794
|
+
const i = name.indexOf("/");
|
|
7795
|
+
return i > 0 ? name.slice(0, i) : name;
|
|
7796
|
+
}
|
|
7797
|
+
let sightings = [];
|
|
7798
|
+
const subs$1 = /* @__PURE__ */ new Set();
|
|
7799
|
+
const logged = /* @__PURE__ */ new Set();
|
|
7800
|
+
/** Read every tagged third-party stylesheet in `<head>` and report the collisions.
|
|
7801
|
+
* Runs at boot and again whenever a sheet appears; per sheet, not concatenated — the
|
|
7802
|
+
* real page has 170+ sheets and the difference is measurable. */
|
|
7803
|
+
function scan() {
|
|
7804
|
+
if (typeof document === "undefined") return;
|
|
7805
|
+
const hits = /* @__PURE__ */ new Map();
|
|
7806
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7807
|
+
const note = (plugin, tokens) => {
|
|
7808
|
+
seen.add(plugin);
|
|
7809
|
+
if (tokens.length === 0) return;
|
|
7810
|
+
const set = hits.get(plugin) ?? /* @__PURE__ */ new Set();
|
|
7811
|
+
for (const t of tokens) set.add(t);
|
|
7812
|
+
hits.set(plugin, set);
|
|
7813
|
+
};
|
|
7814
|
+
for (const el of Array.from(document.querySelectorAll("style[data-plugin]"))) {
|
|
7815
|
+
const raw = (el.getAttribute("data-plugin") ?? "").trim();
|
|
7816
|
+
if (raw === "" || isSelf(raw) || isHost(raw)) continue;
|
|
7817
|
+
const plugin = pluginKey(raw);
|
|
7818
|
+
const text = el.textContent ?? "";
|
|
7819
|
+
note(plugin, OWNED_TOKENS.filter((t) => text.includes(`var(${t})`) || text.includes(`var(${t},`) || text.includes(`var(${t} `)));
|
|
7820
|
+
}
|
|
7821
|
+
for (const pin of THIRD_PARTY_PINS) if (pin.probe !== void 0 && !seen.has(pin.plugin) && document.querySelector(pin.probe) !== null) note(pin.plugin, []);
|
|
7822
|
+
const next = [];
|
|
7823
|
+
for (const plugin of seen) {
|
|
7824
|
+
const read = [...hits.get(plugin) ?? []];
|
|
7825
|
+
const pin = THIRD_PARTY_PINS.find((p) => p.plugin === plugin);
|
|
7826
|
+
if (pin === void 0 && read.length === 0) continue;
|
|
7827
|
+
const s = {
|
|
7828
|
+
plugin,
|
|
7829
|
+
tokens: read.length > 0 ? read : [...pin?.tokens ?? []],
|
|
7830
|
+
pinned: pin !== void 0,
|
|
7831
|
+
labelKey: pin?.labelKey
|
|
7832
|
+
};
|
|
7833
|
+
next.push(s);
|
|
7834
|
+
report(plugin, s);
|
|
7835
|
+
}
|
|
7836
|
+
const changed = JSON.stringify(next) !== JSON.stringify(sightings);
|
|
7837
|
+
sightings = next;
|
|
7838
|
+
if (changed) subs$1.forEach((cb) => cb());
|
|
7839
|
+
}
|
|
7840
|
+
function report(plugin, s) {
|
|
7841
|
+
if (logged.has(plugin)) return;
|
|
7842
|
+
logged.add(plugin);
|
|
7843
|
+
if (s.pinned) {
|
|
7844
|
+
const state = rProtectThirdParty() ? "the registered compatibility pin keeps them legible" : "a pin exists for it but 「保护第三方表面」 is currently OFF";
|
|
7845
|
+
console.log(`dsh-any-background: ${plugin} detected — its surfaces fill from tokens this plugin fades, and ${state} (${s.tokens.join(", ")})`);
|
|
7846
|
+
return;
|
|
7847
|
+
}
|
|
7848
|
+
console.warn(`dsh-any-background: ${plugin} paints from ${s.tokens.join(", ")} — the same tokens the interface-opacity sliders own, so those surfaces fade with them. No compatibility pin is registered for ${plugin}; if one of its surfaces goes transparent or unreadable, report this line and a pin can be added.`);
|
|
7849
|
+
}
|
|
7850
|
+
/** Snapshot of what the scan found (for the settings card). */
|
|
7851
|
+
function thirdPartySightings() {
|
|
7852
|
+
return sightings;
|
|
7853
|
+
}
|
|
7854
|
+
/** Subscribe to sightings changing. */
|
|
7855
|
+
function subscribeThirdParty(cb) {
|
|
7856
|
+
subs$1.add(cb);
|
|
7857
|
+
return () => {
|
|
7858
|
+
subs$1.delete(cb);
|
|
7859
|
+
};
|
|
7860
|
+
}
|
|
7861
|
+
/** Run the scan at boot and keep it current. Returns an unsubscribe for teardown. */
|
|
7862
|
+
function startThirdPartyWatch() {
|
|
7863
|
+
scan();
|
|
7864
|
+
return watchDom((records) => {
|
|
7865
|
+
let relevant = false;
|
|
7866
|
+
for (const r of records) {
|
|
7867
|
+
for (const n of r.addedNodes) {
|
|
7868
|
+
if (!(n instanceof HTMLStyleElement)) continue;
|
|
7869
|
+
const name = n.getAttribute("data-plugin");
|
|
7870
|
+
if (name !== null && !isSelf(name) && !isHost(name)) {
|
|
7871
|
+
relevant = true;
|
|
7872
|
+
break;
|
|
7873
|
+
}
|
|
7874
|
+
}
|
|
7875
|
+
if (relevant) break;
|
|
7876
|
+
}
|
|
7877
|
+
if (relevant) scan();
|
|
7878
|
+
}, "head");
|
|
7879
|
+
}
|
|
7880
|
+
//#endregion
|
|
7431
7881
|
//#region src/client/components/LiveSlider.tsx
|
|
7432
7882
|
/**
|
|
7433
7883
|
* Zero-lag slider: the thumb and value label update through DOM refs while
|
|
@@ -7564,186 +8014,244 @@ window.__ModuleLoader__.load({
|
|
|
7564
8014
|
function InterfacePage({ p }) {
|
|
7565
8015
|
const { t, setOps, setBlurs, setSop, setPanelOp, useStore } = p;
|
|
7566
8016
|
useStore((s) => s.metaRev);
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
if (isChat) {
|
|
7654
|
-
cfg.chatTextOpacity = op;
|
|
7655
|
-
applyViewCards();
|
|
7656
|
-
saveConfig();
|
|
7657
|
-
} else if (isTrajectory) {
|
|
7658
|
-
cfg.trajectoryOpacity = op;
|
|
7659
|
-
applyTrajectoryOverrides(op);
|
|
7660
|
-
saveConfig();
|
|
7661
|
-
} else if (isSettings) setSop(op);
|
|
7662
|
-
else if (isPanel) setPanelOp(op);
|
|
7663
|
-
else if (isProduced) {
|
|
7664
|
-
cfg.producedOpacity = op;
|
|
7665
|
-
applyProduced();
|
|
7666
|
-
saveConfig();
|
|
7667
|
-
} else if (isHeader) {
|
|
7668
|
-
cfg.headerOpacity = op;
|
|
7669
|
-
applyHeaderPopovers();
|
|
7670
|
-
saveConfig();
|
|
7671
|
-
} else if (isHeaderBar) {
|
|
7672
|
-
cfg.headerBarOpacity = op;
|
|
7673
|
-
applyHeaderBar();
|
|
8017
|
+
const [tpRev, setTpRev] = (0, react.useState)(0);
|
|
8018
|
+
(0, react.useEffect)(() => subscribeThirdParty(() => setTpRev((v) => v + 1)), []);
|
|
8019
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
8020
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
8021
|
+
className: "dab-head dab-rise",
|
|
8022
|
+
style: { "--d": 0 },
|
|
8023
|
+
children: [
|
|
8024
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8025
|
+
className: "dab-overline",
|
|
8026
|
+
children: "Surfaces"
|
|
8027
|
+
}),
|
|
8028
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
8029
|
+
className: "dab-h1",
|
|
8030
|
+
children: t("uiTitle")
|
|
8031
|
+
}),
|
|
8032
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
8033
|
+
className: "dab-desc",
|
|
8034
|
+
children: t("descInterface")
|
|
8035
|
+
})
|
|
8036
|
+
]
|
|
8037
|
+
}),
|
|
8038
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8039
|
+
className: "dab-grid-parts",
|
|
8040
|
+
children: PARTS$1.map((part, i) => {
|
|
8041
|
+
const { labelKey, Icon, isSettings, isChat, isTrajectory, isPanel, isProduced, isHeader, isHeaderBar } = part;
|
|
8042
|
+
const opKey = part.opKey;
|
|
8043
|
+
const label = t(labelKey);
|
|
8044
|
+
const blurKey = isChat ? "chat" : isTrajectory ? "trajectory" : isSettings ? "settings" : isPanel ? "panel" : isProduced ? "produced" : isHeader ? "header" : isHeaderBar ? "headerBar" : opKey;
|
|
8045
|
+
const opacity = isChat ? rChatTextOpacity() : isTrajectory ? rTrajectoryOpacity() : isSettings ? rSop() : isPanel ? rPanelOpacity() : isProduced ? rProducedOpacity() : isHeader ? rHeaderOpacity() : isHeaderBar ? rHeaderBarOpacity() : rOps()[opKey];
|
|
8046
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
8047
|
+
className: "dab-card dab-card-hover dab-rise",
|
|
8048
|
+
style: { "--d": i + 1 },
|
|
8049
|
+
children: [
|
|
8050
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8051
|
+
className: "dab-part-head",
|
|
8052
|
+
children: [
|
|
8053
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8054
|
+
className: "dab-part-ico",
|
|
8055
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { size: 16 })
|
|
8056
|
+
}),
|
|
8057
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8058
|
+
className: "dab-part-name",
|
|
8059
|
+
children: label
|
|
8060
|
+
}),
|
|
8061
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8062
|
+
className: "dab-part-badge",
|
|
8063
|
+
children: [Math.round(opacity * 100), "%"]
|
|
8064
|
+
})
|
|
8065
|
+
]
|
|
8066
|
+
}),
|
|
8067
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
|
|
8068
|
+
label: t("uiOpacity"),
|
|
8069
|
+
min: 0,
|
|
8070
|
+
max: 100,
|
|
8071
|
+
step: 1,
|
|
8072
|
+
def: Math.round(opacity * 100),
|
|
8073
|
+
fmt: (v) => `${v}%`,
|
|
8074
|
+
onInput: (v) => {
|
|
8075
|
+
const op = v / 100;
|
|
8076
|
+
if (isChat) {
|
|
8077
|
+
cfg.chatTextOpacity = op;
|
|
8078
|
+
applyViewCards();
|
|
8079
|
+
} else if (isTrajectory) {
|
|
8080
|
+
cfg.trajectoryOpacity = op;
|
|
8081
|
+
applyTrajectoryOverrides(op);
|
|
8082
|
+
} else if (isSettings) {
|
|
8083
|
+
cfg.settingsOpacity = op;
|
|
8084
|
+
applySettingsOverrides(op);
|
|
8085
|
+
} else if (isPanel) {
|
|
8086
|
+
cfg.panelOpacity = op;
|
|
8087
|
+
applyPanelOverrides(op);
|
|
8088
|
+
} else if (isProduced) {
|
|
8089
|
+
cfg.producedOpacity = op;
|
|
8090
|
+
applyProduced();
|
|
8091
|
+
} else if (isHeader) {
|
|
8092
|
+
cfg.headerOpacity = op;
|
|
8093
|
+
applyHeaderPopovers();
|
|
8094
|
+
} else if (isHeaderBar) {
|
|
8095
|
+
cfg.headerBarOpacity = op;
|
|
8096
|
+
applyHeaderBar();
|
|
8097
|
+
} else {
|
|
8098
|
+
const ops = { ...rOps() };
|
|
8099
|
+
ops[opKey] = op;
|
|
8100
|
+
cfg.opacities = ops;
|
|
8101
|
+
applyCustomTokens(ops);
|
|
8102
|
+
}
|
|
7674
8103
|
saveConfig();
|
|
7675
|
-
} else {
|
|
7676
|
-
const ops = { ...rOps() };
|
|
7677
|
-
ops[opKey] = op;
|
|
7678
|
-
setOps(ops);
|
|
7679
|
-
}
|
|
7680
|
-
}
|
|
7681
|
-
}),
|
|
7682
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
|
|
7683
|
-
label: t("uiBlur"),
|
|
7684
|
-
min: 0,
|
|
7685
|
-
max: 60,
|
|
7686
|
-
step: 1,
|
|
7687
|
-
def: rBlurs()[blurKey],
|
|
7688
|
-
fmt: (v) => `${v}px`,
|
|
7689
|
-
onInput: (v) => {
|
|
7690
|
-
const blurs = { ...rBlurs() };
|
|
7691
|
-
blurs[blurKey] = v;
|
|
7692
|
-
cfg.blurs = blurs;
|
|
7693
|
-
setPartBlur(blurKey, v);
|
|
7694
|
-
saveConfig();
|
|
7695
|
-
},
|
|
7696
|
-
onChange: (v) => {
|
|
7697
|
-
const blurs = { ...rBlurs() };
|
|
7698
|
-
blurs[blurKey] = v;
|
|
7699
|
-
setBlurs(blurs);
|
|
7700
|
-
}
|
|
7701
|
-
}),
|
|
7702
|
-
isHeaderBar && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7703
|
-
className: "dab-slider-block",
|
|
7704
|
-
title: t("captionInkHint"),
|
|
7705
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7706
|
-
className: "dab-slider-label",
|
|
7707
|
-
children: t("captionInkLabel")
|
|
7708
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7709
|
-
style: {
|
|
7710
|
-
display: "flex",
|
|
7711
|
-
alignItems: "center",
|
|
7712
|
-
gap: 10
|
|
7713
8104
|
},
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
8105
|
+
onChange: (v) => {
|
|
8106
|
+
const op = v / 100;
|
|
8107
|
+
if (isChat) {
|
|
8108
|
+
cfg.chatTextOpacity = op;
|
|
8109
|
+
applyViewCards();
|
|
8110
|
+
saveConfig();
|
|
8111
|
+
} else if (isTrajectory) {
|
|
8112
|
+
cfg.trajectoryOpacity = op;
|
|
8113
|
+
applyTrajectoryOverrides(op);
|
|
8114
|
+
saveConfig();
|
|
8115
|
+
} else if (isSettings) setSop(op);
|
|
8116
|
+
else if (isPanel) setPanelOp(op);
|
|
8117
|
+
else if (isProduced) {
|
|
8118
|
+
cfg.producedOpacity = op;
|
|
8119
|
+
applyProduced();
|
|
8120
|
+
saveConfig();
|
|
8121
|
+
} else if (isHeader) {
|
|
8122
|
+
cfg.headerOpacity = op;
|
|
8123
|
+
applyHeaderPopovers();
|
|
8124
|
+
saveConfig();
|
|
8125
|
+
} else if (isHeaderBar) {
|
|
8126
|
+
cfg.headerBarOpacity = op;
|
|
7719
8127
|
applyHeaderBar();
|
|
7720
8128
|
saveConfig();
|
|
8129
|
+
} else {
|
|
8130
|
+
const ops = { ...rOps() };
|
|
8131
|
+
ops[opKey] = op;
|
|
8132
|
+
setOps(ops);
|
|
8133
|
+
}
|
|
8134
|
+
}
|
|
8135
|
+
}),
|
|
8136
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
|
|
8137
|
+
label: t("uiBlur"),
|
|
8138
|
+
min: 0,
|
|
8139
|
+
max: 60,
|
|
8140
|
+
step: 1,
|
|
8141
|
+
def: rBlurs()[blurKey],
|
|
8142
|
+
fmt: (v) => `${v}px`,
|
|
8143
|
+
onInput: (v) => {
|
|
8144
|
+
const blurs = { ...rBlurs() };
|
|
8145
|
+
blurs[blurKey] = v;
|
|
8146
|
+
cfg.blurs = blurs;
|
|
8147
|
+
setPartBlur(blurKey, v);
|
|
8148
|
+
saveConfig();
|
|
8149
|
+
},
|
|
8150
|
+
onChange: (v) => {
|
|
8151
|
+
const blurs = { ...rBlurs() };
|
|
8152
|
+
blurs[blurKey] = v;
|
|
8153
|
+
setBlurs(blurs);
|
|
8154
|
+
}
|
|
8155
|
+
}),
|
|
8156
|
+
isHeaderBar && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8157
|
+
className: "dab-slider-block",
|
|
8158
|
+
title: t("captionInkHint"),
|
|
8159
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8160
|
+
className: "dab-slider-label",
|
|
8161
|
+
children: t("captionInkLabel")
|
|
8162
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8163
|
+
style: {
|
|
8164
|
+
display: "flex",
|
|
8165
|
+
alignItems: "center",
|
|
8166
|
+
gap: 10
|
|
7721
8167
|
},
|
|
7722
|
-
children:
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
8168
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
8169
|
+
className: "dab-select",
|
|
8170
|
+
value: rCaptionInk(),
|
|
8171
|
+
onChange: (e) => {
|
|
8172
|
+
cfg.captionInk = e.target.value;
|
|
8173
|
+
applyHeaderBar();
|
|
8174
|
+
saveConfig();
|
|
8175
|
+
},
|
|
8176
|
+
children: [
|
|
8177
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8178
|
+
value: "auto",
|
|
8179
|
+
children: t("captionInkAuto")
|
|
8180
|
+
}),
|
|
8181
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8182
|
+
value: "theme",
|
|
8183
|
+
children: t("captionInkTheme")
|
|
8184
|
+
}),
|
|
8185
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8186
|
+
value: "white",
|
|
8187
|
+
children: t("captionInkWhite")
|
|
8188
|
+
}),
|
|
8189
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8190
|
+
value: "black",
|
|
8191
|
+
children: t("captionInkBlack")
|
|
8192
|
+
})
|
|
8193
|
+
]
|
|
8194
|
+
})
|
|
8195
|
+
})]
|
|
8196
|
+
})
|
|
8197
|
+
]
|
|
8198
|
+
}, blurKey);
|
|
8199
|
+
})
|
|
8200
|
+
}),
|
|
8201
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
8202
|
+
className: "dab-card dab-rise",
|
|
8203
|
+
style: { "--d": PARTS$1.length + 1 },
|
|
8204
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8205
|
+
className: "dab-row-head",
|
|
8206
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8207
|
+
style: {
|
|
8208
|
+
display: "flex",
|
|
8209
|
+
alignItems: "center",
|
|
8210
|
+
gap: 10
|
|
8211
|
+
},
|
|
8212
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8213
|
+
className: "dab-part-ico",
|
|
8214
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PanelIcon, { size: 16 })
|
|
8215
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8216
|
+
className: "dab-part-name",
|
|
8217
|
+
children: t("tpTitle")
|
|
8218
|
+
})]
|
|
8219
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8220
|
+
type: "button",
|
|
8221
|
+
className: `dab-toggle${rProtectThirdParty() ? " is-on" : ""}`,
|
|
8222
|
+
role: "switch",
|
|
8223
|
+
"aria-checked": rProtectThirdParty(),
|
|
8224
|
+
"aria-label": t("tpEnabled"),
|
|
8225
|
+
title: t("tpHint"),
|
|
8226
|
+
onClick: () => {
|
|
8227
|
+
cfg.protectThirdParty = !rProtectThirdParty();
|
|
8228
|
+
applyReaderLanes();
|
|
8229
|
+
saveConfig();
|
|
8230
|
+
setTpRev((v) => v + 1);
|
|
8231
|
+
},
|
|
8232
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "dab-toggle-knob" })
|
|
8233
|
+
})]
|
|
8234
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8235
|
+
className: "dab-slider-block",
|
|
8236
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8237
|
+
className: "dab-slider-label",
|
|
8238
|
+
title: t("tpHint"),
|
|
8239
|
+
children: t("tpEnabled")
|
|
8240
|
+
}), thirdPartySightings().length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8241
|
+
style: { fontSize: 12 },
|
|
8242
|
+
children: t("tpNone")
|
|
8243
|
+
}) : thirdPartySightings().map((s) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8244
|
+
style: { fontSize: 12 },
|
|
8245
|
+
title: s.tokens.join(", "),
|
|
8246
|
+
children: [
|
|
8247
|
+
s.plugin,
|
|
8248
|
+
":",
|
|
8249
|
+
s.pinned && s.labelKey ? `${t(s.labelKey)} ${t("tpPinned")}` : s.pinned ? t("tpPinned") : t("tpUnpinned")
|
|
8250
|
+
]
|
|
8251
|
+
}, s.plugin))]
|
|
8252
|
+
})]
|
|
7745
8253
|
})
|
|
7746
|
-
|
|
8254
|
+
] });
|
|
7747
8255
|
}
|
|
7748
8256
|
//#endregion
|
|
7749
8257
|
//#region src/client/components/pages/FontPage.tsx
|
|
@@ -10697,6 +11205,7 @@ window.__ModuleLoader__.load({
|
|
|
10697
11205
|
teardownWp();
|
|
10698
11206
|
}, "dsh-any-background: wp cleanup");
|
|
10699
11207
|
ctx.effect(() => startBetterSidebarWatch(), "dsh-any-background: better-sidebar watch");
|
|
11208
|
+
ctx.effect(() => startThirdPartyWatch(), "dsh-any-background: third-party scan");
|
|
10700
11209
|
ctx.effect(() => startHeaderPopoverTagging(), "dsh-any-background: header popover tagging");
|
|
10701
11210
|
ctx.effect(() => ctx.on("theme/change", () => {
|
|
10702
11211
|
if (rHasColor() || rBgDark() !== null || rSchemeOverride() !== "auto") {
|