dsh-deepseek-style-theme 2.0.85 → 2.0.87
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/THIRD-PARTY-NOTICES.md +30 -10
- package/lib/client.js +163 -20
- package/lib/index.js +1116 -1107
- package/package.json +1 -1
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -23,16 +23,36 @@ dispersion / specular-parallax subsystem of **dsh-theme-mineradio v2.3.8**:
|
|
|
23
23
|
Only naming and external dependencies were adapted: plugin-scoped identifiers
|
|
24
24
|
were renamed to this plugin's `dshome-` prefix, and the upstream settings/theme
|
|
25
25
|
store and React layer were replaced by function parameters. **The GLSL shader
|
|
26
|
-
sources are copies of upstream, with
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
`
|
|
32
|
-
bits of mantissa, so at 16 bits the hash collapses into
|
|
33
|
-
noise lattice shows up as large drifting squares.
|
|
34
|
-
fragment shaders, and on GPUs that promoted mediump
|
|
35
|
-
|
|
26
|
+
sources are copies of upstream, with two recorded deviations:**
|
|
27
|
+
|
|
28
|
+
1. **(v2.0.74)** the `precision mediump float;` qualifier in FLOW_SHADER and
|
|
29
|
+
DISPLAY_SHADER was changed to `precision highp float;`. The reason is a
|
|
30
|
+
rendering defect, not a feature: under ANGLE/D3D11 on Intel integrated GPUs
|
|
31
|
+
`mediump` is a real 16-bit float (`min16float`), and the display shader's noise
|
|
32
|
+
needs roughly 24 bits of mantissa, so at 16 bits the hash collapses into
|
|
33
|
+
constant plateaus and the noise lattice shows up as large drifting squares.
|
|
34
|
+
WebGL2 guarantees highp in fragment shaders, and on GPUs that promoted mediump
|
|
35
|
+
to 32 bits the change is a no-op.
|
|
36
|
+
2. **(v2.0.86)** DISPLAY_SHADER's `random(vec2 st)` -- upstream's classic
|
|
37
|
+
`fract(sin(dot(st, vec2(12.9898,78.233))) * 43758.5453123)` -- was replaced by
|
|
38
|
+
Dave Hoskins' sin-free hash (`fract(vec3(p.xyx) * 0.1031)` plus one dot and one
|
|
39
|
+
multiply). The reason is the same class of defect, one layer down and this time
|
|
40
|
+
precision-independent: this shader scales the noise coordinate to ~1e5
|
|
41
|
+
(`uv *= ns * u_resolution`, doubled again for `n2`), and at that magnitude the
|
|
42
|
+
error left by `sin()`'s argument reduction in float32 is multiplied by 43758
|
|
43
|
+
into ~100 units, so neighbouring cells receive nearly the same value and the
|
|
44
|
+
warp field degenerates into flat plateaus with hard edges (measured on an Intel
|
|
45
|
+
Arc 130V: 39.6% flat 8x8 blocks, an 800x1000px plateau, 60-90/255 jumps along
|
|
46
|
+
its boundary -- the user's 大方块). The sin-free hash keeps every intermediate
|
|
47
|
+
small, so it behaves identically on every GPU, and it preserves upstream's
|
|
48
|
+
per-cell white noise rather than shrinking the domain warp (which would cure the
|
|
49
|
+
symptom by removing the effect). `noise()`'s interpolation and every other line
|
|
50
|
+
of every shader are unchanged.
|
|
51
|
+
|
|
52
|
+
The two deviations are related on purpose: deviation 1 fixed a 16-bit intermediate
|
|
53
|
+
precision collapse, deviation 2 the 32-bit argument-magnitude collapse that
|
|
54
|
+
survived it. Both were diagnosed from the same symptom on the same machine class,
|
|
55
|
+
and both were verified there rather than assumed.
|
|
36
56
|
|
|
37
57
|
Upstream notes that its fluid shader is itself a faithful port of the
|
|
38
58
|
`ds-join-shader-bg` shader in the deepseek.com site bundle, with the shader
|
package/lib/client.js
CHANGED
|
@@ -238,7 +238,27 @@ out vec4 fragColor;
|
|
|
238
238
|
#define PI 3.14159265358979323846
|
|
239
239
|
|
|
240
240
|
vec2 rotate(vec2 uv, float th) { return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv; }
|
|
241
|
-
|
|
241
|
+
/* Upstream's hash is the classic fract(sin(dot(st, vec2(12.9898, 78.233))) * 43758.5453123)
|
|
242
|
+
-- no backticks in this comment: it lives inside a template literal, and a pair of
|
|
243
|
+
them ends the literal (tools/parse-smoke.mjs exists because that has happened three
|
|
244
|
+
times). Its argument is NOT small in this shader: uv is scaled by ns * u_resolution
|
|
245
|
+
(about 2900 at the user's viewport) and doubled again for n2, so dot() reaches ~2e5.
|
|
246
|
+
At that magnitude float32 leaves ~2.5e-3 of error inside sin(), the 43758x multiplier
|
|
247
|
+
turns it into ~100 units, and the hash stops behaving like a hash: neighbouring cells
|
|
248
|
+
receive almost the same value, so the warp field degenerates into flat plateaus with
|
|
249
|
+
hard edges -- the 大方块 of the 2026-09-16 fluid report, measured on an Intel Arc 130V
|
|
250
|
+
as 39.6% flat 8x8 blocks, an 800x1000px plateau, and 60-90/255 jumps along its
|
|
251
|
+
boundary (the two earlier fixes, mediump -> highp and RGBA8 -> RGBA16F, were both
|
|
252
|
+
verified active on that machine and the blocks survived, which is what pointed here).
|
|
253
|
+
This is Dave Hoskins' sin-free hash: every intermediate stays small, so it behaves the
|
|
254
|
+
same on every GPU and keeps upstream's per-cell white noise instead of deleting the
|
|
255
|
+
domain warp (the ablation's noDistort variant cures the symptom by removing the
|
|
256
|
+
effect). Recorded as deviation #2 in THIRD-PARTY-NOTICES.md. */
|
|
257
|
+
float random(vec2 st) {
|
|
258
|
+
vec3 p3 = fract(vec3(st.xyx) * 0.1031);
|
|
259
|
+
p3 += dot(p3, p3.yzx + 33.33);
|
|
260
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
261
|
+
}
|
|
242
262
|
float noise(vec2 st) {
|
|
243
263
|
vec2 i = floor(st); vec2 f = fract(st);
|
|
244
264
|
float a = random(i), b = random(i + vec2(1,0)), c = random(i + vec2(0,1)), d = random(i + vec2(1,1));
|
|
@@ -758,7 +778,16 @@ void main() {
|
|
|
758
778
|
// a separate constant so the frosted recipe keeps receiving 60.
|
|
759
779
|
var LIQUID_REF_SCALE = 104;
|
|
760
780
|
var EDGE_DX = -14;
|
|
761
|
-
|
|
781
|
+
// The lens tint. It is mixed into `|backdrop - backdrop shifted by EDGE_DX|`,
|
|
782
|
+
// which is meant to be non-zero only along a hard edge -- but over a GRADIENT
|
|
783
|
+
// backdrop (the `bold` background recipe is exactly that) the difference is
|
|
784
|
+
// non-zero across the WHOLE pane, so the tint stopped being an edge fringe and
|
|
785
|
+
// became a wash: the first user to see it (2.0.84 restored the mount after ATTR
|
|
786
|
+
// had been missing since 1.43.6) reported "我的玻璃怎么变成凝胶了" with a
|
|
787
|
+
// screenshot of a solid pink composer. 0.45 -> 0.16 keeps the fringing (that
|
|
788
|
+
// comes from the per-channel chromatic displacement, not from the tint) while
|
|
789
|
+
// the wash drops to a hint.
|
|
790
|
+
var TINT_OPACITY = 0.16;
|
|
762
791
|
var TINT_SAT = 0.85;
|
|
763
792
|
var TINT_LIGHT = 0.6;
|
|
764
793
|
var DEFAULT_TINT_HUE = 44;
|
|
@@ -1080,15 +1109,27 @@ html,body{background-color:transparent!important}
|
|
|
1080
1109
|
The invisible-text hazard stays open on purpose. A stuck appearance switch is
|
|
1081
1110
|
a broken control; near-white text on a near-white page at least still reads
|
|
1082
1111
|
once the marker agrees. Do not re-add these two rules. */
|
|
1083
|
-
|
|
1112
|
+
/* The themed background lives on a FIXED PSEUDO-ELEMENT, not on the body with
|
|
1113
|
+
background-attachment: fixed. Two reasons, and the second is the one the user hit:
|
|
1114
|
+
a fixed-attachment background is painted in its own phase, so Chromium's
|
|
1115
|
+
backdrop-filter does not sample it -- every glass pane over the page wash ended up
|
|
1116
|
+
blurring "nothing" and read as plain translucency ("现在的效果是半透明,没有背景模糊
|
|
1117
|
+
效果"). A position:fixed layer is ordinary painted content and is part of the
|
|
1118
|
+
backdrop. The visual is the same (the wash stays put), and z-index:-2 keeps it under
|
|
1119
|
+
the fluid canvas (-1), which is what the glass should blur next. No backticks in this
|
|
1120
|
+
comment: it lives inside a template literal and a pair of them ends it. */
|
|
1121
|
+
body:not([data-dshome-bg=custom])::before{content:"";position:fixed;inset:0;z-index:-2;pointer-events:none;background:radial-gradient(1200px 700px at 12% -10%,color-mix(in srgb,var(--ds-brand) 14%,transparent),transparent 60%),radial-gradient(1000px 600px at 105% 12%,color-mix(in srgb,var(--ds-brand-light) 16%,transparent),transparent 55%),radial-gradient(900px 700px at 50% 115%,color-mix(in srgb,var(--ds-brand) 10%,transparent),transparent 60%),linear-gradient(180deg,#fbfbfd 0%,#f5f6fa 100%)}
|
|
1084
1122
|
body[data-dshome-color=red]{--ds-brand:#F5222D;--ds-brand-deep:#CF1322;--ds-brand-mid:#FF4D4F;--ds-brand-light:#FF7875}
|
|
1085
1123
|
body[data-dshome-color=blue]{--ds-brand:#4D6BFE;--ds-brand-deep:#3A65C2;--ds-brand-mid:#4176E6;--ds-brand-light:#73A3D2}
|
|
1086
1124
|
body[data-dshome-dark]{--ds-brand:#10B981;--ds-brand-deep:#059669;--ds-brand-mid:#34D399;--ds-brand-light:#6EE7B7}
|
|
1087
|
-
body[data-dshome-dark]:not([data-dshome-bg=custom]){background:radial-gradient(1100px 650px at 8% -8%,#0a3a28 0,transparent 62%),radial-gradient(950px 600px at 104% 10%,#0d4d35 0,transparent 58%),radial-gradient(800px 600px at 50% 118%,#06291c 0,transparent 60%),linear-gradient(180deg,#081b14 0%,#0a241a 55%,#081b14 100%)
|
|
1125
|
+
body[data-dshome-dark]:not([data-dshome-bg=custom])::before{background:radial-gradient(1100px 650px at 8% -8%,#0a3a28 0,transparent 62%),radial-gradient(950px 600px at 104% 10%,#0d4d35 0,transparent 58%),radial-gradient(800px 600px at 50% 118%,#06291c 0,transparent 60%),linear-gradient(180deg,#081b14 0%,#0a241a 55%,#081b14 100%)}
|
|
1088
1126
|
body[data-dshome-dark][data-dshome-color=red]{--ds-brand:#FF4D4F;--ds-brand-deep:#F5222D;--ds-brand-mid:#FF7875;--ds-brand-light:#FFA39E}
|
|
1089
|
-
body[data-dshome-dark][data-dshome-color=red]:not([data-dshome-bg=custom]){background:radial-gradient(1100px 650px at 8% -8%,#5c0f14 0,transparent 62%),radial-gradient(950px 600px at 104% 10%,#7d1a20 0,transparent 58%),radial-gradient(800px 600px at 50% 118%,#3f0a0e 0,transparent 60%),linear-gradient(180deg,#260709 0%,#330a0d 55%,#260709 100%)
|
|
1127
|
+
body[data-dshome-dark][data-dshome-color=red]:not([data-dshome-bg=custom])::before{background:radial-gradient(1100px 650px at 8% -8%,#5c0f14 0,transparent 62%),radial-gradient(950px 600px at 104% 10%,#7d1a20 0,transparent 58%),radial-gradient(800px 600px at 50% 118%,#3f0a0e 0,transparent 60%),linear-gradient(180deg,#260709 0%,#330a0d 55%,#260709 100%)}
|
|
1090
1128
|
body[data-dshome-dark][data-dshome-color=blue]{--ds-brand:#5D79FF;--ds-brand-deep:#4D6BFE;--ds-brand-mid:#7A96FF;--ds-brand-light:#9DB9FF}
|
|
1091
|
-
body[data-dshome-dark][data-dshome-color=blue]:not([data-dshome-bg=custom]){background:radial-gradient(1100px 650px at 8% -8%,#1a3870 0,transparent 62%),radial-gradient(950px 600px at 104% 10%,#2d5f9e 0,transparent 58%),radial-gradient(800px 600px at 50% 118%,#0d1f4a 0,transparent 60%),linear-gradient(180deg,#0a1a3a 0%,#0d1f4a 55%,#0a1a3a 100%)
|
|
1129
|
+
body[data-dshome-dark][data-dshome-color=blue]:not([data-dshome-bg=custom])::before{background:radial-gradient(1100px 650px at 8% -8%,#1a3870 0,transparent 62%),radial-gradient(950px 600px at 104% 10%,#2d5f9e 0,transparent 58%),radial-gradient(800px 600px at 50% 118%,#0d1f4a 0,transparent 60%),linear-gradient(180deg,#0a1a3a 0%,#0d1f4a 55%,#0a1a3a 100%)}
|
|
1130
|
+
/* The body itself must NOT paint a background: any opaque page background sits
|
|
1131
|
+
below the pseudo-element and would be what the glass samples. */
|
|
1132
|
+
body:not([data-dshome-bg=custom]){background:none!important}
|
|
1092
1133
|
/* ── background recipe: 自选背景 ─────────────────────────────────────────
|
|
1093
1134
|
The custom value never enters this sheet. It arrives as the custom property
|
|
1094
1135
|
--dshome-custom-bg on <body>, and only after the client's CSS.supports()
|
|
@@ -1464,6 +1505,19 @@ body[data-dshome-dark] :is([class*="_headline"]){background:linear-gradient(120d
|
|
|
1464
1505
|
{ anchor: ".wSkVaW_scrollBody", css: `
|
|
1465
1506
|
:is(${USER_BUBBLE}){background:rgba(255,255,255,.6)!important;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);border:1px solid rgba(0,0,0,.05);box-shadow:0 4px 16px rgba(13,30,60,.06)}
|
|
1466
1507
|
body[data-dshome-dark] :is(${USER_BUBBLE}){background:rgba(21,42,86,.65)!important;border:1px solid rgba(255,255,255,.1);box-shadow:0 4px 16px rgba(0,0,0,.25)}
|
|
1508
|
+
` },
|
|
1509
|
+
// The line under the composer (round/step/token stats, `[data-dsh-stats]` is
|
|
1510
|
+
// product markup that has never been renamed) gets the LENS touch the user
|
|
1511
|
+
// asked for: "模糊效果,你对对话窗下方文字进行放大(模拟液体放大)". A real lens
|
|
1512
|
+
// magnifies what is behind the glass, which a backdrop filter cannot do --
|
|
1513
|
+
// but the pane is directly above this line, so scaling it a touch reads as
|
|
1514
|
+
// the pane's magnification, and scaling it further while the pane leans
|
|
1515
|
+
// (html[data-dshome-leaning], written by startComposerTilt) ties the motion
|
|
1516
|
+
// to the hover. Small on purpose: 6% is a lens hint, 12% while leaning.
|
|
1517
|
+
{ anchor: "[data-dsh-stats]", css: `
|
|
1518
|
+
[data-dsh-stats]{transform:scale(1.06);transform-origin:center center;transition:transform .24s cubic-bezier(.2,.8,.2,1)}
|
|
1519
|
+
html[data-dshome-leaning] [data-dsh-stats]{transform:scale(1.12)}
|
|
1520
|
+
@media (prefers-reduced-motion:reduce){[data-dsh-stats]{transition:none}}
|
|
1467
1521
|
` },
|
|
1468
1522
|
// Trajectory view bar.
|
|
1469
1523
|
{ anchor: ".fV0t5q_root", css: `
|
|
@@ -1761,10 +1815,14 @@ html[data-dshome-glass="liquid"] :is(${USER_BUBBLE}){
|
|
|
1761
1815
|
/* The composer leans under the cursor (see startComposerTilt). The transition
|
|
1762
1816
|
is what turns the release into a settle rather than a snap: the ported
|
|
1763
1817
|
routine writes the neutral transform back and only drops the inline
|
|
1764
|
-
properties 240ms later.
|
|
1818
|
+
properties 240ms later.
|
|
1819
|
+
will-change: transform used to sit here as a perf hint and is deliberately
|
|
1820
|
+
GONE: promoting the pane to its own layer is the other half of "no blur" --
|
|
1821
|
+
Chromium's backdrop sampling is unreliable on a will-changed element, and the
|
|
1822
|
+
compositor already promotes a transformed element while it is actually being
|
|
1823
|
+
transformed. The hint cost the effect it was meant to smooth. */
|
|
1765
1824
|
html[data-dshome-glass="liquid"] [data-composer-card]{
|
|
1766
1825
|
transition:transform .24s cubic-bezier(.2,.8,.2,1),background-color .18s ease,box-shadow .18s ease!important;
|
|
1767
|
-
will-change:transform;
|
|
1768
1826
|
}
|
|
1769
1827
|
html[data-dshome-glass="liquid"] :is(${USER_BUBBLE}):hover{
|
|
1770
1828
|
background-color:rgb(255 255 255 / .18)!important;
|
|
@@ -1830,8 +1888,11 @@ html[data-dshome-dispersion][data-dshome-glass="liquid"][data-dshome-composer="o
|
|
|
1830
1888
|
actually behind it, so the fade shows up as a lighter band above 设置 (the
|
|
1831
1889
|
user's red box). The pane itself already separates the list from the
|
|
1832
1890
|
conversation, so the fade is dropped. Scoped to the sidebar and to the
|
|
1833
|
-
product's own <hash>_fade naming so nothing else is touched.
|
|
1834
|
-
|
|
1891
|
+
product's own <hash>_fade naming so nothing else is touched.
|
|
1892
|
+
NOT gated on the liquid recipe: it was, and the user sent a screenshot of the
|
|
1893
|
+
same light band in 白磨砂 ("白磨砂,有这个渐变") — the frosted pane is translucent
|
|
1894
|
+
too, so its end stop mismatches just the same. Both recipes drop it. */
|
|
1895
|
+
body .hHd-Xa_root [class*="_fade" i]{
|
|
1835
1896
|
background-image:none!important;
|
|
1836
1897
|
}
|
|
1837
1898
|
/* The sidebar's own, heavier blur. Written after the two rules above because it
|
|
@@ -2392,11 +2453,26 @@ html[data-dshome-blur="off"] body{
|
|
|
2392
2453
|
// `spots` (0 means the composer no longer matches TILT_SELECTOR), and the
|
|
2393
2454
|
// reduced-motion case logs one info line instead of vanishing.
|
|
2394
2455
|
const TILT_SELECTOR = '[data-composer-card],.uV2eYG_card';
|
|
2395
|
-
|
|
2456
|
+
/** On <html> while the composer leans; the lens touch on the line under the
|
|
2457
|
+
* composer reads it (see the [data-dsh-stats] patch block). */
|
|
2458
|
+
const LEAN_ATTR = 'data-dshome-leaning';
|
|
2459
|
+
// 0.0175 rad was upstream's conservative lean, and after 2.0.85 finally made
|
|
2460
|
+
// the effect reachable the verdict was "倾斜效果很微弱" -- fair, at ~4 degrees
|
|
2461
|
+
// end to end over a pane this wide it reads as a wobble, not as depth. Raised
|
|
2462
|
+
// ~1.7x, with TILT_RELEASE_PAD keeping the stronger movement from feeding a loop.
|
|
2463
|
+
const TILT_MAX = 0.03;
|
|
2396
2464
|
const TILT_PERSPECTIVE = 800;
|
|
2397
|
-
const TILT_SCALE = 1.
|
|
2465
|
+
const TILT_SCALE = 1.015;
|
|
2398
2466
|
const TILT_SETTLE_MS = 240;
|
|
2399
2467
|
const TILT_COOLDOWN_MS = 200;
|
|
2468
|
+
/**
|
|
2469
|
+
* How far outside the card's own rectangle the pointer must travel before the
|
|
2470
|
+
* lean is released. Engagement is geometric (see spotAt), so without a pad the
|
|
2471
|
+
* lean's own movement could carry the card's edge past a stationary pointer:
|
|
2472
|
+
* out -> release -> back in -> engage, at frame rate. 8px is comfortably more
|
|
2473
|
+
* than the lift moves an edge (1.5% of a ~112px pane is under 2px).
|
|
2474
|
+
*/
|
|
2475
|
+
const TILT_RELEASE_PAD = 8;
|
|
2400
2476
|
/** The lean's own easing. Mirrors the liquid sheet's values, and is removed
|
|
2401
2477
|
* together with the inline transform so nothing keeps animating afterwards. */
|
|
2402
2478
|
const TILT_TRANSITION = 'transform .24s cubic-bezier(.2,.8,.2,1),background-color .18s ease,box-shadow .18s ease';
|
|
@@ -2452,6 +2528,7 @@ html[data-dshome-blur="off"] body{
|
|
|
2452
2528
|
if (!tilted.has(spot)) return;
|
|
2453
2529
|
releasedAt = performance.now();
|
|
2454
2530
|
tilted.delete(spot);
|
|
2531
|
+
document.documentElement.removeAttribute(LEAN_ATTR);
|
|
2455
2532
|
spot.style.transform = 'perspective(' + TILT_PERSPECTIVE + 'px) rotateX(0rad) rotateY(0rad) scale(1)';
|
|
2456
2533
|
const handle = window.setTimeout(() => {
|
|
2457
2534
|
settle.delete(spot);
|
|
@@ -2478,6 +2555,11 @@ html[data-dshome-blur="off"] body{
|
|
|
2478
2555
|
+ ' scale(' + TILT_SCALE + ')';
|
|
2479
2556
|
if (!tilted.has(spot)) engagements += 1;
|
|
2480
2557
|
tilted.add(spot);
|
|
2558
|
+
// The marker the lens touch reads (see the composer-stats block in
|
|
2559
|
+
// PATCH_BLOCKS): while the pane leans, the line under it is scaled a
|
|
2560
|
+
// little further, which is the closest thing to a lens without
|
|
2561
|
+
// touching the backdrop.
|
|
2562
|
+
if (!document.documentElement.hasAttribute(LEAN_ATTR)) document.documentElement.setAttribute(LEAN_ATTR, '');
|
|
2481
2563
|
});
|
|
2482
2564
|
};
|
|
2483
2565
|
/**
|
|
@@ -2534,10 +2616,17 @@ html[data-dshome-blur="off"] body{
|
|
|
2534
2616
|
const onMove = (event) => {
|
|
2535
2617
|
const hit = spotAt(event.clientX, event.clientY);
|
|
2536
2618
|
if (hit === null) {
|
|
2537
|
-
// Off the card
|
|
2619
|
+
// Off the card: release the lean, but only past the release pad --
|
|
2620
|
+
// the lean's own movement must not be able to hand the card back
|
|
2621
|
+
// and forth under a stationary pointer.
|
|
2538
2622
|
if (current !== null) {
|
|
2539
|
-
|
|
2540
|
-
|
|
2623
|
+
const rect = current.getBoundingClientRect();
|
|
2624
|
+
const outside = event.clientX < rect.left - TILT_RELEASE_PAD || event.clientX > rect.right + TILT_RELEASE_PAD
|
|
2625
|
+
|| event.clientY < rect.top - TILT_RELEASE_PAD || event.clientY > rect.bottom + TILT_RELEASE_PAD;
|
|
2626
|
+
if (outside) {
|
|
2627
|
+
release(current);
|
|
2628
|
+
current = null;
|
|
2629
|
+
}
|
|
2541
2630
|
}
|
|
2542
2631
|
return;
|
|
2543
2632
|
}
|
|
@@ -2565,7 +2654,8 @@ html[data-dshome-blur="off"] body{
|
|
|
2565
2654
|
const onOut = (event) => {
|
|
2566
2655
|
if (current === null) return;
|
|
2567
2656
|
const rect = current.getBoundingClientRect();
|
|
2568
|
-
if (event.clientX >= rect.left && event.clientX <= rect.right
|
|
2657
|
+
if (event.clientX >= rect.left - TILT_RELEASE_PAD && event.clientX <= rect.right + TILT_RELEASE_PAD
|
|
2658
|
+
&& event.clientY >= rect.top - TILT_RELEASE_PAD && event.clientY <= rect.bottom + TILT_RELEASE_PAD) return;
|
|
2569
2659
|
release(current);
|
|
2570
2660
|
current = null;
|
|
2571
2661
|
};
|
|
@@ -2584,6 +2674,7 @@ html[data-dshome-blur="off"] body{
|
|
|
2584
2674
|
spot.style.removeProperty('transform-origin');
|
|
2585
2675
|
spot.style.removeProperty('transition');
|
|
2586
2676
|
}
|
|
2677
|
+
document.documentElement.removeAttribute(LEAN_ATTR);
|
|
2587
2678
|
current = null;
|
|
2588
2679
|
};
|
|
2589
2680
|
}
|
|
@@ -2602,7 +2693,7 @@ html[data-dshome-blur="off"] body{
|
|
|
2602
2693
|
if (!supportsWebgl2()) return startParticles();
|
|
2603
2694
|
// Which build is running, readable from the page (see README). One line in
|
|
2604
2695
|
// the console answers "is the bundle I just installed actually live?".
|
|
2605
|
-
try { window.__dshomeBuild = '2.0.
|
|
2696
|
+
try { window.__dshomeBuild = '2.0.87 lens-blur'; } catch (error) {}
|
|
2606
2697
|
const canvas = document.createElement('canvas');
|
|
2607
2698
|
canvas.setAttribute('data-dsh-deepseek-canvas', '');
|
|
2608
2699
|
const style = canvas.style;
|
|
@@ -2707,7 +2798,59 @@ html[data-dshome-blur="off"] body{
|
|
|
2707
2798
|
function startGlassExtras() {
|
|
2708
2799
|
const stopSpotter = startSpecularSpotter();
|
|
2709
2800
|
const stopParallax = startSpecularParallax();
|
|
2710
|
-
|
|
2801
|
+
/**
|
|
2802
|
+
* The refraction is OPT-IN, and `off` means "do not mount it at all".
|
|
2803
|
+
*
|
|
2804
|
+
* Two measured reasons, both from the user's machine (2.0.84, the first
|
|
2805
|
+
* build that mounted it since 1.43.6): the tint washed the whole composer
|
|
2806
|
+
* ("玻璃怎么变成凝胶了"), and the SVG filter inside `backdrop-filter` took the
|
|
2807
|
+
* BLUR down with it -- a `url()` that fails to render invalidates the whole
|
|
2808
|
+
* declaration, so the pane lost its frost and read as plain translucency
|
|
2809
|
+
* ("没有背景模糊效果"). A decorative filter must never be able to cost a
|
|
2810
|
+
* surface its glass, so the chain stays out of the DOM unless asked for, and
|
|
2811
|
+
* the switch covers all four surfaces rather than only the composer.
|
|
2812
|
+
*/
|
|
2813
|
+
const dispersion = dsttGetComposer() === 'off'
|
|
2814
|
+
? { setTint() {}, setRefraction() {}, dispose() {} }
|
|
2815
|
+
: startGlassDispersion({ hue: FLUID_HUES[dshomeColor()] });
|
|
2816
|
+
// Readable from the page, next to __dshomeBuild / __dshomeFluidFormat /
|
|
2817
|
+
// __dshomeTilt: "is the refraction in the DOM, and what is driving it" is
|
|
2818
|
+
// the first question any glass report needs answered.
|
|
2819
|
+
try {
|
|
2820
|
+
window.__dshomeDispersion = () => ({
|
|
2821
|
+
composer: dsttGetComposer(),
|
|
2822
|
+
mounted: document.documentElement.hasAttribute(ATTR),
|
|
2823
|
+
filters: document.querySelectorAll('svg filter').length,
|
|
2824
|
+
recipe: dsttGetGlass()
|
|
2825
|
+
});
|
|
2826
|
+
} catch (error) {}
|
|
2827
|
+
/**
|
|
2828
|
+
* "Why is there no blur" answered in one call: the computed backdrop chain of
|
|
2829
|
+
* every glass surface, the two things that can silently stop Chromium from
|
|
2830
|
+
* sampling a backdrop (a fixed-attachment body background and a will-changed
|
|
2831
|
+
* pane), and the setting that turns the radii off on purpose.
|
|
2832
|
+
*/
|
|
2833
|
+
try {
|
|
2834
|
+
window.__dshomeGlassProbe = () => {
|
|
2835
|
+
const card = document.querySelector(TILT_SELECTOR);
|
|
2836
|
+
const chain = (selector, pseudo) => {
|
|
2837
|
+
const node = document.querySelector(selector);
|
|
2838
|
+
if (node === null) return null;
|
|
2839
|
+
try { return getComputedStyle(node, pseudo === undefined ? null : pseudo).backdropFilter; } catch (error) { return 'ERR'; }
|
|
2840
|
+
};
|
|
2841
|
+
return {
|
|
2842
|
+
recipe: dsttGetGlass(),
|
|
2843
|
+
backdropBlurSetting: dsttState.blur,
|
|
2844
|
+
bodyBackgroundAttachment: getComputedStyle(document.body).backgroundAttachment,
|
|
2845
|
+
bodyBackgroundImage: getComputedStyle(document.body).backgroundImage.slice(0, 32),
|
|
2846
|
+
washLayer: getComputedStyle(document.body, '::before').position,
|
|
2847
|
+
tiltCard: card === null ? null : getComputedStyle(card).backdropFilter,
|
|
2848
|
+
tiltCardWillChange: card === null ? null : (getComputedStyle(card).willChange || 'auto'),
|
|
2849
|
+
sidebar: chain('.hHd-Xa_root', '::before'),
|
|
2850
|
+
bubble: chain(USER_BUBBLE)
|
|
2851
|
+
};
|
|
2852
|
+
};
|
|
2853
|
+
} catch (error) {}
|
|
2711
2854
|
// Both recipes share one filter pair, so the recipe selects the scale:
|
|
2712
2855
|
// 104 for liquid (visible edge refraction) and the untouched 60 for
|
|
2713
2856
|
// frosted, which is what the pane has always used.
|
|
@@ -2741,7 +2884,7 @@ html[data-dshome-blur="off"] body{
|
|
|
2741
2884
|
}
|
|
2742
2885
|
|
|
2743
2886
|
function startParticles() {
|
|
2744
|
-
try { window.__dshomeBuild = '2.0.
|
|
2887
|
+
try { window.__dshomeBuild = '2.0.87 lens-blur'; } catch (error) {}
|
|
2745
2888
|
const canvas = document.createElement('canvas');
|
|
2746
2889
|
canvas.setAttribute('data-dsh-deepseek-canvas', '');
|
|
2747
2890
|
const style = canvas.style;
|
|
@@ -4134,7 +4277,7 @@ body[data-dshome-dark] .${CLS}{background:rgba(14,30,60,.94);box-shadow:0 18px 4
|
|
|
4134
4277
|
// `origin` was this option's first id and is still accepted from a settings
|
|
4135
4278
|
// file written before the rename; it reads back as `wide`.
|
|
4136
4279
|
const DSTT_COMPOSER = ["narrow", "wide", "off"];
|
|
4137
|
-
const DSTT_COMPOSER_DEFAULT = "
|
|
4280
|
+
const DSTT_COMPOSER_DEFAULT = "off";
|
|
4138
4281
|
const DSTT_COMPOSER_LABELS = {
|
|
4139
4282
|
narrow: { zh: "窄 8px", en: "Narrow 8px" },
|
|
4140
4283
|
wide: { zh: "宽 16px", en: "Wide 16px" },
|