@lemoncat7/dsh-theme-xiaohei 0.4.6 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/README.md +15 -9
  2. package/THIRD_PARTY_NOTICES.md +13 -1
  3. package/docs/dsh-021-compatibility.md +23 -0
  4. package/docs/releases/0.5.0.md +24 -0
  5. package/docs/rift-interaction.md +35 -0
  6. package/docs/rift-preview.md +39 -0
  7. package/lib/client.companion.js +3 -4
  8. package/lib/client.decorations.js +224 -51
  9. package/lib/client.js +532 -2405
  10. package/lib/index.d.ts +1 -2
  11. package/lib/index.js +393 -11
  12. package/lib/rift/boot.d.ts +6 -0
  13. package/package.json +29 -19
  14. package/lib/appearance.d.ts +0 -12
  15. package/lib/appearance.js +0 -42
  16. package/lib/blink.d.ts +0 -4
  17. package/lib/blink.js +0 -110
  18. package/lib/bloub-heixiu/ambient.d.ts +0 -3
  19. package/lib/bloub-heixiu/ambient.js +0 -12
  20. package/lib/bloub-heixiu/character.d.ts +0 -33
  21. package/lib/bloub-heixiu/character.js +0 -124
  22. package/lib/bloub-heixiu/effects.d.ts +0 -4
  23. package/lib/bloub-heixiu/effects.js +0 -91
  24. package/lib/bloub-heixiu/flight.d.ts +0 -15
  25. package/lib/bloub-heixiu/flight.js +0 -66
  26. package/lib/bloub-heixiu/follow.d.ts +0 -13
  27. package/lib/bloub-heixiu/follow.js +0 -23
  28. package/lib/bloub-heixiu/layout.d.ts +0 -34
  29. package/lib/bloub-heixiu/layout.js +0 -26
  30. package/lib/bloub-heixiu/renderer.d.ts +0 -16
  31. package/lib/bloub-heixiu/renderer.js +0 -94
  32. package/lib/bloub-heixiu/runtime.d.ts +0 -6
  33. package/lib/bloub-heixiu/runtime.js +0 -440
  34. package/lib/bloub-heixiu/signals.d.ts +0 -17
  35. package/lib/bloub-heixiu/signals.js +0 -55
  36. package/lib/bloub-heixiu/styles.d.ts +0 -2
  37. package/lib/bloub-heixiu/styles.js +0 -98
  38. package/lib/boot-appearance.d.ts +0 -10
  39. package/lib/boot-appearance.js +0 -47
  40. package/lib/boot-loader.d.ts +0 -5
  41. package/lib/boot-loader.js +0 -158
  42. package/lib/chrome/accessibility.d.ts +0 -3
  43. package/lib/chrome/accessibility.js +0 -69
  44. package/lib/chrome/blink.d.ts +0 -3
  45. package/lib/chrome/blink.js +0 -15
  46. package/lib/chrome/composer-avatar.d.ts +0 -10
  47. package/lib/chrome/composer-avatar.js +0 -599
  48. package/lib/chrome/composer-send-heixiu.d.ts +0 -3
  49. package/lib/chrome/composer-send-heixiu.js +0 -143
  50. package/lib/chrome/composer.d.ts +0 -3
  51. package/lib/chrome/composer.js +0 -135
  52. package/lib/chrome/controls.d.ts +0 -8
  53. package/lib/chrome/controls.js +0 -348
  54. package/lib/chrome/conversation-messages.d.ts +0 -3
  55. package/lib/chrome/conversation-messages.js +0 -329
  56. package/lib/chrome/conversation-submissions.d.ts +0 -3
  57. package/lib/chrome/conversation-submissions.js +0 -68
  58. package/lib/chrome/conversation.d.ts +0 -3
  59. package/lib/chrome/conversation.js +0 -67
  60. package/lib/chrome/frames.d.ts +0 -6
  61. package/lib/chrome/frames.js +0 -134
  62. package/lib/chrome/gaze.d.ts +0 -3
  63. package/lib/chrome/gaze.js +0 -103
  64. package/lib/chrome/identity.d.ts +0 -6
  65. package/lib/chrome/identity.js +0 -47
  66. package/lib/chrome/overlays.d.ts +0 -3
  67. package/lib/chrome/overlays.js +0 -104
  68. package/lib/chrome/portal.d.ts +0 -6
  69. package/lib/chrome/portal.js +0 -169
  70. package/lib/chrome/reactions.d.ts +0 -3
  71. package/lib/chrome/reactions.js +0 -85
  72. package/lib/chrome/sidebar.d.ts +0 -3
  73. package/lib/chrome/sidebar.js +0 -313
  74. package/lib/chrome/tokens.d.ts +0 -3
  75. package/lib/chrome/tokens.js +0 -224
  76. package/lib/chrome/workspace.d.ts +0 -3
  77. package/lib/chrome/workspace.js +0 -94
  78. package/lib/chrome.d.ts +0 -10
  79. package/lib/chrome.js +0 -46
  80. package/lib/client-entry.d.ts +0 -3
  81. package/lib/client-entry.js +0 -3
  82. package/lib/client.d.ts +0 -10
  83. package/lib/client.pose-chin-dark.js +0 -4
  84. package/lib/client.pose-chin-light.js +0 -4
  85. package/lib/client.pose-doze-dark.js +0 -4
  86. package/lib/client.pose-doze-light.js +0 -4
  87. package/lib/client.pose-halfpeek-dark.js +0 -4
  88. package/lib/client.pose-halfpeek-light.js +0 -4
  89. package/lib/client.pose-peek-dark.js +0 -4
  90. package/lib/client.pose-peek-light.js +0 -4
  91. package/lib/client.pose-seated-dark.js +0 -4
  92. package/lib/client.pose-seated-light.js +0 -4
  93. package/lib/client.rig-chin-dark.js +0 -4
  94. package/lib/client.rig-chin-light.js +0 -4
  95. package/lib/client.rig-halfpeek-dark.js +0 -4
  96. package/lib/client.rig-halfpeek-light.js +0 -4
  97. package/lib/client.rig-peek-dark.js +0 -4
  98. package/lib/client.rig-peek-light.js +0 -4
  99. package/lib/client.rig-seated-dark.js +0 -4
  100. package/lib/client.rig-seated-light.js +0 -4
  101. package/lib/companion-entry.d.ts +0 -3
  102. package/lib/companion-entry.js +0 -3
  103. package/lib/composer-avatar.d.ts +0 -18
  104. package/lib/composer-avatar.js +0 -441
  105. package/lib/composer-draft-preview.d.ts +0 -4
  106. package/lib/composer-draft-preview.js +0 -8
  107. package/lib/composer-send-heixiu.d.ts +0 -8
  108. package/lib/composer-send-heixiu.js +0 -133
  109. package/lib/current-session.d.ts +0 -6
  110. package/lib/current-session.js +0 -5
  111. package/lib/decorations-entry.d.ts +0 -3
  112. package/lib/decorations-entry.js +0 -18
  113. package/lib/deferred-companion.d.ts +0 -5
  114. package/lib/deferred-companion.js +0 -9
  115. package/lib/deferred-decorations.d.ts +0 -3
  116. package/lib/deferred-decorations.js +0 -51
  117. package/lib/gaze.d.ts +0 -4
  118. package/lib/gaze.js +0 -230
  119. package/lib/generated-backgrounds.d.ts +0 -14
  120. package/lib/generated-backgrounds.js +0 -14
  121. package/lib/generated-character-motion.d.ts +0 -4
  122. package/lib/generated-character-motion.js +0 -2
  123. package/lib/generated-identity.d.ts +0 -6
  124. package/lib/generated-identity.js +0 -6
  125. package/lib/generated-keyart.d.ts +0 -34
  126. package/lib/generated-keyart.js +0 -34
  127. package/lib/generated-loading-assets.d.ts +0 -4
  128. package/lib/generated-loading-assets.js +0 -4
  129. package/lib/heixiu-interactions.d.ts +0 -10
  130. package/lib/heixiu-interactions.js +0 -161
  131. package/lib/host-contract.d.ts +0 -9
  132. package/lib/host-contract.js +0 -13
  133. package/lib/host-dom.d.ts +0 -11
  134. package/lib/host-dom.js +0 -72
  135. package/lib/loading-heixiu.d.ts +0 -8
  136. package/lib/loading-heixiu.js +0 -287
  137. package/lib/metallic-brand-mark.d.ts +0 -10
  138. package/lib/metallic-brand-mark.js +0 -296
  139. package/lib/plugin.d.ts +0 -6
  140. package/lib/plugin.js +0 -60
  141. package/lib/portal.d.ts +0 -40
  142. package/lib/portal.js +0 -225
  143. package/lib/reactions.d.ts +0 -20
  144. package/lib/reactions.js +0 -380
  145. package/lib/scene/avatar-model.d.ts +0 -6
  146. package/lib/scene/avatar-model.js +0 -646
  147. package/lib/scene/avatar-motion.d.ts +0 -3
  148. package/lib/scene/avatar-motion.js +0 -799
  149. package/lib/scene/character-assets.d.ts +0 -13
  150. package/lib/scene/character-assets.js +0 -26
  151. package/lib/scene/character-expression.d.ts +0 -4
  152. package/lib/scene/character-expression.js +0 -15
  153. package/lib/scene/character-eye-material.d.ts +0 -13
  154. package/lib/scene/character-eye-material.js +0 -88
  155. package/lib/scene/character-eye-renderer.d.ts +0 -5
  156. package/lib/scene/character-eye-renderer.js +0 -80
  157. package/lib/scene/character-eye-rig.d.ts +0 -20
  158. package/lib/scene/character-eye-rig.js +0 -35
  159. package/lib/scene/character-gaze.d.ts +0 -16
  160. package/lib/scene/character-gaze.js +0 -36
  161. package/lib/scene/character-idle.d.ts +0 -17
  162. package/lib/scene/character-idle.js +0 -65
  163. package/lib/scene/character-layout.d.ts +0 -24
  164. package/lib/scene/character-layout.js +0 -51
  165. package/lib/scene/character-motion-clock.d.ts +0 -18
  166. package/lib/scene/character-motion-clock.js +0 -70
  167. package/lib/scene/character-motion-types.d.ts +0 -12
  168. package/lib/scene/character-motion-types.js +0 -2
  169. package/lib/scene/character-motion.d.ts +0 -6
  170. package/lib/scene/character-motion.js +0 -187
  171. package/lib/scene/character-poses.d.ts +0 -26
  172. package/lib/scene/character-poses.js +0 -11
  173. package/lib/scene/character-rig-renderer.d.ts +0 -5
  174. package/lib/scene/character-rig-renderer.js +0 -95
  175. package/lib/scene/character-rig.d.ts +0 -22
  176. package/lib/scene/character-rig.js +0 -61
  177. package/lib/scene/heixiu-feedback.d.ts +0 -3
  178. package/lib/scene/heixiu-feedback.js +0 -64
  179. package/lib/scene/heixiu-interactions.d.ts +0 -3
  180. package/lib/scene/heixiu-interactions.js +0 -92
  181. package/lib/scene/ids.d.ts +0 -5
  182. package/lib/scene/ids.js +0 -5
  183. package/lib/scene/pointer-bridge.d.ts +0 -21
  184. package/lib/scene/pointer-bridge.js +0 -155
  185. package/lib/scene/runtime.d.ts +0 -12
  186. package/lib/scene/runtime.js +0 -74
  187. package/lib/scene/state-transitions.d.ts +0 -3
  188. package/lib/scene/state-transitions.js +0 -37
  189. package/lib/scene/styles.d.ts +0 -5
  190. package/lib/scene/styles.js +0 -69
  191. package/lib/scene/sylva-performance.d.ts +0 -11
  192. package/lib/scene/sylva-performance.js +0 -58
  193. package/lib/scene/wallpaper-character-styles.d.ts +0 -3
  194. package/lib/scene/wallpaper-character-styles.js +0 -49
  195. package/lib/scene/wallpaper-character.d.ts +0 -5
  196. package/lib/scene/wallpaper-character.js +0 -222
  197. package/lib/scene.d.ts +0 -8
  198. package/lib/scene.js +0 -8
  199. package/lib/sidebar-glass.d.ts +0 -16
  200. package/lib/sidebar-glass.js +0 -168
  201. package/lib/sidebar-heixiu-escape.d.ts +0 -44
  202. package/lib/sidebar-heixiu-escape.js +0 -340
  203. package/lib/sidebar-heixiu-roaming.d.ts +0 -27
  204. package/lib/sidebar-heixiu-roaming.js +0 -310
  205. package/lib/sidebar-reveal.d.ts +0 -8
  206. package/lib/sidebar-reveal.js +0 -59
  207. package/lib/state.d.ts +0 -21
  208. package/lib/state.js +0 -123
  209. package/lib/theme.d.ts +0 -19
  210. package/lib/theme.js +0 -188
  211. package/lib/vendor/bloub/decor.d.ts +0 -114
  212. package/lib/vendor/bloub/decor.js +0 -198
  213. package/lib/vendor/bloub/engine.d.ts +0 -213
  214. package/lib/vendor/bloub/engine.js +0 -452
  215. package/lib/vendor/bloub/expressions.d.ts +0 -35
  216. package/lib/vendor/bloub/expressions.js +0 -143
  217. package/lib/vendor/bloub/eyefit.d.ts +0 -75
  218. package/lib/vendor/bloub/eyefit.js +0 -393
  219. package/lib/vendor/bloub/face.d.ts +0 -63
  220. package/lib/vendor/bloub/face.js +0 -106
  221. package/lib/vendor/bloub/math.d.ts +0 -22
  222. package/lib/vendor/bloub/math.js +0 -36
  223. package/lib/vendor/bloub/profiles.d.ts +0 -8
  224. package/lib/vendor/bloub/profiles.js +0 -20
  225. package/lib/vendor/bloub/repere.d.ts +0 -30
  226. package/lib/vendor/bloub/repere.js +0 -32
  227. package/lib/vendor/bloub/shape.d.ts +0 -80
  228. package/lib/vendor/bloub/shape.js +0 -268
  229. package/lib/vendor/bloub/skins.d.ts +0 -36
  230. package/lib/vendor/bloub/skins.js +0 -74
  231. package/lib/vendor/bloub/states.d.ts +0 -87
  232. package/lib/vendor/bloub/states.js +0 -468
@@ -1,222 +0,0 @@
1
- import { subscribeXiaoheiHostDom } from '../host-dom.js';
2
- import { XIAOHEI_HOST_SELECTORS } from '../host-contract.js';
3
- import { XIAOHEI_SCENE_LAYER_ID } from './ids.js';
4
- import { resolveCharacterPlacement } from './character-layout.js';
5
- import { createCharacterIdleController } from './character-idle.js';
6
- import { characterAssets, CHARACTER_POSE_NAMES } from './character-assets.js';
7
- import { createCharacterMotion } from './character-motion.js';
8
- export const XIAOHEI_WALLPAPER_CHARACTER_ID = 'dsh-theme-xiaohei/wallpaper-character';
9
- /** Places the layered character only when the host geometry is settled. */
10
- export function installXiaoheiWallpaperCharacter(doc = typeof document === 'undefined' ? undefined : document, loadPose = characterAssets.pose) {
11
- const win = doc?.defaultView;
12
- if (!doc || !win)
13
- return () => { };
14
- let disposed = false;
15
- let frame;
16
- let settled;
17
- let host;
18
- let targets = [];
19
- let dirty = true;
20
- let placement = { pose: 'hidden', left: 0, top: 0, width: 0, height: 0 };
21
- const ready = new Map();
22
- const loading = new Set();
23
- const failed = new Set();
24
- const motion = typeof win.matchMedia === 'function' ? createCharacterMotion(doc) : undefined;
25
- const idle = createCharacterIdleController({ now: () => win.performance.now(),
26
- setTimeout: (fn, delay) => win.setTimeout(fn, delay), clearTimeout: handle => win.clearTimeout(handle),
27
- }, () => schedule());
28
- const sizes = new WeakMap();
29
- const observer = typeof win.ResizeObserver === 'function' ? new win.ResizeObserver(entries => {
30
- for (const entry of entries) {
31
- const previous = sizes.get(entry.target);
32
- const width = entry.contentRect.width;
33
- const height = entry.contentRect.height;
34
- sizes.set(entry.target, { width, height });
35
- // Appending streamed paragraphs changes flow height, not its horizontal
36
- // safe area. Ignore that size change instead of measuring the whole UI.
37
- if (!previous || previous.width !== width || (entry.target === targets[0] && previous.height !== height))
38
- dirty = true;
39
- }
40
- if (dirty) {
41
- schedule();
42
- scheduleSettled();
43
- }
44
- }) : undefined;
45
- function reconcile() {
46
- if (disposed || !doc)
47
- return;
48
- // The glass owner already tracks the native column's animated geometry.
49
- // Do not measure controls or rebuild a different rig at intermediate widths.
50
- if (doc.documentElement?.hasAttribute('data-xiaohei-sidebar-resizing')) {
51
- dirty = true;
52
- if (host && host.dataset.pose !== 'hidden')
53
- host.dataset.pose = 'hidden';
54
- idle.setPaused(true);
55
- motion?.setPose(undefined, 'hidden');
56
- scheduleSettled();
57
- return;
58
- }
59
- const layer = doc.getElementById(XIAOHEI_SCENE_LAYER_ID);
60
- const next = [
61
- doc.querySelector(XIAOHEI_HOST_SELECTORS.sidebarShell),
62
- doc.querySelector('[data-conversation-scroll]'),
63
- doc.querySelector('[data-chat-flow]'),
64
- doc.querySelector(XIAOHEI_HOST_SELECTORS.composerCard),
65
- ];
66
- if (next.some((element, i) => element !== targets[i])) {
67
- targets = next;
68
- observer?.disconnect();
69
- for (const element of targets)
70
- if (element)
71
- observer?.observe(element);
72
- dirty = true;
73
- }
74
- if (!layer) {
75
- host?.remove();
76
- host = undefined;
77
- idle.setPaused(true);
78
- motion?.setPose(undefined, 'hidden');
79
- return;
80
- }
81
- if (!host || host.parentElement !== layer) {
82
- host?.remove();
83
- doc.getElementById(XIAOHEI_WALLPAPER_CHARACTER_ID)?.remove();
84
- host = doc.createElement('div');
85
- host.id = XIAOHEI_WALLPAPER_CHARACTER_ID;
86
- host.className = 'xiaohei-wallpaper-character';
87
- host.setAttribute('aria-hidden', 'true');
88
- host.dataset.pose = 'hidden';
89
- for (const pose of CHARACTER_POSE_NAMES) {
90
- const part = doc.createElement('span');
91
- part.className = `xiaohei-wallpaper-character__${pose}`;
92
- host.append(part);
93
- }
94
- layer.append(host);
95
- dirty = true;
96
- }
97
- if (!dirty) {
98
- renderPose();
99
- return;
100
- }
101
- dirty = false;
102
- const [sidebar, scroll, flow, composer] = targets;
103
- if (!sidebar || !scroll || !composer) {
104
- placement = { ...placement, pose: 'hidden' };
105
- renderPose();
106
- return;
107
- }
108
- const sidebarBounds = sidebar.getBoundingClientRect();
109
- const controls = sidebarBounds.width < 100
110
- ? [...sidebar.querySelectorAll('button,a,input,[role="button"],[role="treeitem"]')]
111
- .map(e => e.getBoundingClientRect()).filter(r => r.width > 0 && r.height > 0)
112
- : [];
113
- const composerBounds = composer.getBoundingClientRect();
114
- // Native message content is inset 16px from its composer column. Use the
115
- // same horizontal footprint on the empty welcome page; never use its Y.
116
- const flowBounds = flow?.getBoundingClientRect() ?? {
117
- left: composerBounds.left + 16, right: composerBounds.right - 16, top: 0, bottom: 0
118
- };
119
- placement = resolveCharacterPlacement({ sidebar: sidebarBounds,
120
- scroll: scroll.getBoundingClientRect(), flow: flowBounds,
121
- viewportWidth: win.innerWidth, viewportHeight: win.innerHeight, controls });
122
- renderPose();
123
- }
124
- function renderPose() {
125
- if (!host || disposed)
126
- return;
127
- idle.setPaused(doc.hidden || placement.pose !== 'seated');
128
- const pose = doc.hidden ? 'hidden' : placement.pose === 'seated' ? idle.pose : placement.pose;
129
- if (pose === 'hidden') {
130
- if (host.dataset.pose !== 'hidden')
131
- host.dataset.pose = 'hidden';
132
- motion?.setPose(undefined, 'hidden');
133
- return;
134
- }
135
- const appearance = doc.documentElement.dataset.xiaoheiAppearance === 'light' ? 'light' : 'dark';
136
- const key = `${pose}-${appearance}`;
137
- if (!ready.has(key)) {
138
- motion?.setPose(undefined, 'hidden');
139
- // Do not retain the old location across a layout change: it could now
140
- // overlap a message. Idle changes keep the already decoded seated pose.
141
- if (placement.pose !== 'seated' || !['seated', 'chin', 'doze'].includes(host.dataset.pose ?? ''))
142
- host.dataset.pose = 'hidden';
143
- if (!loading.has(key) && !failed.has(key)) {
144
- loading.add(key);
145
- // Fetch only the requested pose and palette, not the complete catalog.
146
- void loadPose(pose, appearance).then(async (src) => {
147
- if (disposed)
148
- return;
149
- const image = new win.Image();
150
- image.src = src;
151
- await image.decode();
152
- if (disposed)
153
- return;
154
- loading.delete(key);
155
- ready.set(key, src);
156
- schedule();
157
- }).catch(() => { loading.delete(key); failed.add(key); });
158
- }
159
- return;
160
- }
161
- // Each pose keeps its own coordinates during the short crossfade. No
162
- // travelling from the right edge through the conversation to the sidebar.
163
- const part = host.querySelector(`.xiaohei-wallpaper-character__${pose}`);
164
- if (part.dataset.appearance !== appearance) {
165
- part.style.setProperty(`--xiaohei-${pose}-art`, `url("${ready.get(key)}")`);
166
- part.dataset.appearance = appearance;
167
- }
168
- for (const key of ['left', 'top', 'width', 'height']) {
169
- const value = `${Math.round(placement[key] * 100) / 100}px`;
170
- if (part.style[key] !== value)
171
- part.style[key] = value;
172
- }
173
- if (!part.dataset.ready)
174
- part.dataset.ready = 'true';
175
- if (host.dataset.pose !== pose)
176
- host.dataset.pose = pose;
177
- motion?.setPose(part, pose);
178
- }
179
- function schedule() {
180
- if (disposed || frame !== undefined)
181
- return;
182
- frame = win.requestAnimationFrame(() => { frame = undefined; reconcile(); });
183
- }
184
- function scheduleSettled() {
185
- if (settled !== undefined)
186
- win.clearTimeout(settled);
187
- // Native rail/collapse transitions can move the sidebar after its last
188
- // size notification. One final measurement catches that resting position.
189
- settled = win.setTimeout(() => { settled = undefined; dirty = true; schedule(); }, 240);
190
- }
191
- const unsubscribe = subscribeXiaoheiHostDom(doc, schedule);
192
- const appearanceObserver = new win.MutationObserver(schedule);
193
- appearanceObserver.observe(doc.documentElement, { attributes: true, attributeFilter: ['data-xiaohei-appearance'] });
194
- const resized = () => { dirty = true; schedule(); scheduleSettled(); };
195
- win.addEventListener('resize', resized, { passive: true });
196
- const activity = () => idle.activity();
197
- const events = ['pointermove', 'pointerdown', 'keydown', 'input', 'wheel'];
198
- for (const event of events)
199
- doc.addEventListener(event, activity, { passive: true, capture: true });
200
- const visibility = () => { if (doc.hidden)
201
- idle.setPaused(true); schedule(); };
202
- doc.addEventListener('visibilitychange', visibility);
203
- schedule();
204
- return () => {
205
- disposed = true;
206
- if (frame !== undefined)
207
- win.cancelAnimationFrame(frame);
208
- if (settled !== undefined)
209
- win.clearTimeout(settled);
210
- unsubscribe();
211
- observer?.disconnect();
212
- appearanceObserver.disconnect();
213
- idle.dispose();
214
- motion?.dispose();
215
- for (const event of events)
216
- doc.removeEventListener(event, activity, true);
217
- doc.removeEventListener('visibilitychange', visibility);
218
- win.removeEventListener('resize', resized);
219
- host?.remove();
220
- };
221
- }
222
- //# sourceMappingURL=wallpaper-character.js.map
package/lib/scene.d.ts DELETED
@@ -1,8 +0,0 @@
1
- /** Public scene facade. Runtime structure and visual styling evolve independently. */
2
- export { XIAOHEI_SCENE_CSS, XIAOHEI_SCENE_LAYER_ID, XIAOHEI_SCENE_STYLE_ID, XIAOHEI_SCENE_WORLD_CLASS, } from './scene/styles.js';
3
- export { configureXiaoheiWorldRenderer, installXiaoheiScene, XIAOHEI_SCENE_PART_COUNT, } from './scene/runtime.js';
4
- export { injectXiaoheiSylvaAvatarModel, prepareXiaoheiSylvaAvatarFrame, XIAOHEI_SYLVA_AVATAR_MARKER, } from './scene/avatar-model.js';
5
- export { XIAOHEI_AVATAR_MOTION_RUNTIME } from './scene/avatar-motion.js';
6
- export { injectXiaoheiSylvaPerformanceProfile, XIAOHEI_SYLVA_PERFORMANCE_MARKER, } from './scene/sylva-performance.js';
7
- export { injectXiaoheiSylvaPointerBridge, prepareXiaoheiSylvaPointerFrame, resolveXiaoheiSylvaPointer, XIAOHEI_SYLVA_POINTER_CHANNEL, XIAOHEI_SYLVA_POINTER_MARKER, } from './scene/pointer-bridge.js';
8
- //# sourceMappingURL=scene.d.ts.map
package/lib/scene.js DELETED
@@ -1,8 +0,0 @@
1
- /** Public scene facade. Runtime structure and visual styling evolve independently. */
2
- export { XIAOHEI_SCENE_CSS, XIAOHEI_SCENE_LAYER_ID, XIAOHEI_SCENE_STYLE_ID, XIAOHEI_SCENE_WORLD_CLASS, } from './scene/styles.js';
3
- export { configureXiaoheiWorldRenderer, installXiaoheiScene, XIAOHEI_SCENE_PART_COUNT, } from './scene/runtime.js';
4
- export { injectXiaoheiSylvaAvatarModel, prepareXiaoheiSylvaAvatarFrame, XIAOHEI_SYLVA_AVATAR_MARKER, } from './scene/avatar-model.js';
5
- export { XIAOHEI_AVATAR_MOTION_RUNTIME } from './scene/avatar-motion.js';
6
- export { injectXiaoheiSylvaPerformanceProfile, XIAOHEI_SYLVA_PERFORMANCE_MARKER, } from './scene/sylva-performance.js';
7
- export { injectXiaoheiSylvaPointerBridge, prepareXiaoheiSylvaPointerFrame, resolveXiaoheiSylvaPointer, XIAOHEI_SYLVA_POINTER_CHANNEL, XIAOHEI_SYLVA_POINTER_MARKER, } from './scene/pointer-bridge.js';
8
- //# sourceMappingURL=scene.js.map
@@ -1,16 +0,0 @@
1
- /** Stable id for the paint-only glass surface behind DSH's native sidebar. */
2
- export declare const XIAOHEI_SIDEBAR_GLASS_ID = "dsh-theme-xiaohei/sidebar-glass";
3
- export interface XiaoheiSidebarGlassBounds {
4
- left: number;
5
- top: number;
6
- width: number;
7
- height: number;
8
- }
9
- /** Keep the visual surface inside the native sidebar without changing layout. */
10
- export declare function resolveXiaoheiSidebarGlassBounds(rect: Pick<DOMRect, 'left' | 'top' | 'width' | 'height'>): XiaoheiSidebarGlassBounds;
11
- /**
12
- * Mount a visual-only glass surface in the scene layer. It mirrors the native
13
- * sidebar geometry but never becomes an ancestor of controls or fixed dialogs.
14
- */
15
- export declare function installXiaoheiSidebarGlass(doc?: Document | undefined): () => void;
16
- //# sourceMappingURL=sidebar-glass.d.ts.map
@@ -1,168 +0,0 @@
1
- import { XIAOHEI_SCENE_LAYER_ID, XIAOHEI_SCENE_WORLD_CLASS } from './scene/ids.js';
2
- import { subscribeXiaoheiHostDom } from './host-dom.js';
3
- import { XIAOHEI_HOST_SELECTORS } from './host-contract.js';
4
- import { createSidebarReveal } from './sidebar-reveal.js';
5
- /** Stable id for the paint-only glass surface behind DSH's native sidebar. */
6
- export const XIAOHEI_SIDEBAR_GLASS_ID = 'dsh-theme-xiaohei/sidebar-glass';
7
- const HORIZONTAL_INSET_START = 7;
8
- const HORIZONTAL_INSET_END = 7;
9
- const VERTICAL_INSET = 8;
10
- const RESIZE_SETTLE_MS = 120;
11
- /** Keep the visual surface inside the native sidebar without changing layout. */
12
- export function resolveXiaoheiSidebarGlassBounds(rect) {
13
- return {
14
- left: rect.left + HORIZONTAL_INSET_START,
15
- top: rect.top + VERTICAL_INSET,
16
- width: Math.max(0, rect.width - HORIZONTAL_INSET_START - HORIZONTAL_INSET_END),
17
- height: Math.max(0, rect.height - VERTICAL_INSET * 2),
18
- };
19
- }
20
- /**
21
- * Mount a visual-only glass surface in the scene layer. It mirrors the native
22
- * sidebar geometry but never becomes an ancestor of controls or fixed dialogs.
23
- */
24
- export function installXiaoheiSidebarGlass(doc = typeof document === 'undefined' ? undefined : document) {
25
- if (doc === undefined)
26
- return () => { };
27
- const browserWindow = doc.defaultView;
28
- if (browserWindow === null)
29
- return () => { };
30
- const win = browserWindow;
31
- let disposed = false;
32
- let glass;
33
- let sidebarColumn;
34
- let animationFrame;
35
- let resizeSettleTimer;
36
- let resizing = false;
37
- let appliedBounds;
38
- let geometryDirty = true;
39
- const reveal = createSidebarReveal(doc);
40
- const clearResizeState = () => {
41
- if (resizeSettleTimer !== undefined)
42
- win.clearTimeout(resizeSettleTimer);
43
- resizeSettleTimer = undefined;
44
- resizing = false;
45
- doc.documentElement.removeAttribute('data-xiaohei-sidebar-resizing');
46
- };
47
- const markResizeActivity = () => {
48
- if (glass === undefined)
49
- return;
50
- if (!resizing) {
51
- resizing = true;
52
- doc.documentElement.setAttribute('data-xiaohei-sidebar-resizing', '');
53
- }
54
- if (resizeSettleTimer !== undefined)
55
- win.clearTimeout(resizeSettleTimer);
56
- resizeSettleTimer = win.setTimeout(() => {
57
- resizeSettleTimer = undefined;
58
- resizing = false;
59
- doc.documentElement.removeAttribute('data-xiaohei-sidebar-resizing');
60
- }, RESIZE_SETTLE_MS);
61
- };
62
- const resizeObserver = typeof win.ResizeObserver === 'function'
63
- ? new win.ResizeObserver(() => {
64
- if (disposed)
65
- return;
66
- // RO runs after host layout and before paint. Update the independent
67
- // paint layer now, not in next frame's RAF (which visibly trails).
68
- const changed = applyBounds();
69
- geometryDirty = false;
70
- if (changed)
71
- markResizeActivity();
72
- })
73
- : undefined;
74
- const applyBounds = () => {
75
- if (glass === undefined || sidebarColumn === undefined)
76
- return false;
77
- const bounds = resolveXiaoheiSidebarGlassBounds(sidebarColumn.getBoundingClientRect());
78
- reveal.resize(bounds.width + HORIZONTAL_INSET_START + HORIZONTAL_INSET_END);
79
- const changed = appliedBounds !== undefined && (bounds.left !== appliedBounds.left || bounds.top !== appliedBounds.top ||
80
- bounds.width !== appliedBounds.width || bounds.height !== appliedBounds.height);
81
- if (bounds.left !== appliedBounds?.left) {
82
- glass.style.setProperty('--xiaohei-sidebar-glass-left', `${bounds.left}px`);
83
- }
84
- if (bounds.top !== appliedBounds?.top) {
85
- glass.style.setProperty('--xiaohei-sidebar-glass-top', `${bounds.top}px`);
86
- }
87
- if (bounds.width !== appliedBounds?.width) {
88
- glass.style.setProperty('--xiaohei-sidebar-glass-width', `${bounds.width}px`);
89
- }
90
- if (bounds.height !== appliedBounds?.height) {
91
- glass.style.setProperty('--xiaohei-sidebar-glass-height', `${bounds.height}px`);
92
- }
93
- appliedBounds = bounds;
94
- return changed;
95
- };
96
- const reconcile = () => {
97
- if (disposed)
98
- return;
99
- const sceneLayer = doc.getElementById(XIAOHEI_SCENE_LAYER_ID);
100
- const nextSidebarColumn = doc.querySelector(XIAOHEI_HOST_SELECTORS.sidebarColumn) ?? undefined;
101
- if (nextSidebarColumn !== sidebarColumn) {
102
- resizeObserver?.disconnect();
103
- sidebarColumn = nextSidebarColumn;
104
- geometryDirty = true;
105
- if (sidebarColumn !== undefined)
106
- resizeObserver?.observe(sidebarColumn);
107
- }
108
- if (sceneLayer === null || sidebarColumn === undefined) {
109
- reveal.setColumn(undefined);
110
- clearResizeState();
111
- glass?.remove();
112
- glass = undefined;
113
- appliedBounds = undefined;
114
- geometryDirty = true;
115
- return;
116
- }
117
- reveal.setColumn(sidebarColumn);
118
- if (glass === undefined || glass.parentElement !== sceneLayer) {
119
- doc.getElementById(XIAOHEI_SIDEBAR_GLASS_ID)?.remove();
120
- glass = doc.createElement('div');
121
- glass.id = XIAOHEI_SIDEBAR_GLASS_ID;
122
- glass.setAttribute('aria-hidden', 'true');
123
- appliedBounds = undefined;
124
- geometryDirty = true;
125
- const world = sceneLayer.querySelector(`.${XIAOHEI_SCENE_WORLD_CLASS}`);
126
- // null is meaningful here: insertBefore(node, null) appends after a
127
- // last-child wallpaper. Falling back to firstChild hides glass UNDER it.
128
- sceneLayer.insertBefore(glass, world !== null ? world.nextSibling : sceneLayer.firstChild);
129
- }
130
- // Streamed text mutates the host tree frequently. Recheck slot identity,
131
- // but do not force layout unless sidebar geometry actually changed.
132
- if (geometryDirty) {
133
- applyBounds();
134
- geometryDirty = false;
135
- }
136
- };
137
- function scheduleReconcile() {
138
- if (disposed || animationFrame !== undefined)
139
- return;
140
- animationFrame = win.requestAnimationFrame(() => {
141
- animationFrame = undefined;
142
- reconcile();
143
- });
144
- }
145
- const unsubscribeHostDom = subscribeXiaoheiHostDom(doc, scheduleReconcile);
146
- const onViewportResize = () => {
147
- geometryDirty = true;
148
- scheduleReconcile();
149
- };
150
- win.addEventListener('resize', onViewportResize, { passive: true });
151
- scheduleReconcile();
152
- return () => {
153
- disposed = true;
154
- if (animationFrame !== undefined)
155
- win.cancelAnimationFrame(animationFrame);
156
- animationFrame = undefined;
157
- unsubscribeHostDom();
158
- resizeObserver?.disconnect();
159
- reveal.dispose();
160
- win.removeEventListener('resize', onViewportResize);
161
- clearResizeState();
162
- glass?.remove();
163
- glass = undefined;
164
- sidebarColumn = undefined;
165
- appliedBounds = undefined;
166
- };
167
- }
168
- //# sourceMappingURL=sidebar-glass.js.map
@@ -1,44 +0,0 @@
1
- interface Point {
2
- x: number;
3
- y: number;
4
- }
5
- interface Box {
6
- left: number;
7
- top: number;
8
- right: number;
9
- bottom: number;
10
- }
11
- export interface XiaoheiSidebarEscapeSpace {
12
- width: number;
13
- height: number;
14
- creatureWidth: number;
15
- creatureHeight: number;
16
- controls: readonly Box[];
17
- }
18
- export interface XiaoheiSidebarEscapeTarget {
19
- creature: HTMLElement;
20
- host: HTMLElement;
21
- space: XiaoheiSidebarEscapeSpace;
22
- }
23
- interface XiaoheiSidebarEscapeControllerOptions {
24
- doc: Document;
25
- isDisabled: () => boolean;
26
- resolveTarget: () => XiaoheiSidebarEscapeTarget | undefined;
27
- onFreeze: (position: Point) => void;
28
- onTeleport: (destination: Point) => void;
29
- onComplete: (destination: Point) => void;
30
- }
31
- export interface XiaoheiSidebarEscapeController {
32
- cancel: () => void;
33
- dispose: () => void;
34
- isRunning: () => boolean;
35
- }
36
- export declare const XIAOHEI_SIDEBAR_ESCAPE_CSS = "\n.xiaohei-sidebar-escape-layer {\n position: absolute;\n inset: 0;\n z-index: 5;\n overflow: hidden;\n contain: layout paint style;\n pointer-events: none;\n}\n\n.xiaohei-sidebar-escape-portal {\n position: absolute;\n left: var(--xiaohei-sidebar-portal-x, 50%);\n top: var(--xiaohei-sidebar-portal-y, 50%);\n display: block;\n width: 2rem;\n height: 2.8rem;\n border-radius: 48% 52% 45% 55% / 54% 46% 55% 45%;\n opacity: 0;\n background:\n radial-gradient(ellipse at 46% 50%, #010304 0%, #020608 57%, #0a2528 70%, rgb(77 194 171 / 40%) 77%, transparent 83%);\n box-shadow:\n inset 0 0 0.55rem rgb(0 0 0 / 94%),\n 0 0 0.65rem rgb(76 201 177 / 16%);\n transform: translate3d(-50%, -50%, 0) rotate(var(--xiaohei-sidebar-portal-angle, 0deg)) scale3d(.06, .16, 1);\n transform-origin: center;\n will-change: transform, opacity;\n}\n\n.xiaohei-sidebar-escape-portal::after {\n position: absolute;\n inset: 14% 19%;\n display: block;\n content: '';\n border-radius: inherit;\n background: #000102;\n box-shadow: inset 0.15rem 0 0.36rem rgb(18 68 67 / 42%);\n}\n\n.xiaohei-sidebar-escape-layer[data-xiaohei-sidebar-escape-phase='enter']\n .xiaohei-sidebar-escape-portal--entry,\n.xiaohei-sidebar-escape-layer[data-xiaohei-sidebar-escape-phase='exit']\n .xiaohei-sidebar-escape-portal--exit {\n animation: xiaohei-sidebar-escape-portal-open 520ms cubic-bezier(.2, .76, .24, 1) both;\n}\n\n.xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase]::before {\n opacity: 0;\n}\n\n.xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase]\n .xiaohei-scene__heixiu-body {\n position: absolute;\n inset: 0;\n display: block;\n transition: none;\n transform-origin: center;\n will-change: transform, opacity;\n}\n\n.xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase='enter']\n .xiaohei-scene__heixiu-body {\n animation: xiaohei-sidebar-heixiu-enter 460ms cubic-bezier(.42, 0, .72, .38) both;\n}\n\n.xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase='exit']\n .xiaohei-scene__heixiu-body {\n animation: xiaohei-sidebar-heixiu-exit 540ms cubic-bezier(.18, .76, .24, 1) both;\n}\n\n@keyframes xiaohei-sidebar-escape-portal-open {\n 0% {\n opacity: 0;\n transform: translate3d(-50%, -50%, 0) rotate(var(--xiaohei-sidebar-portal-angle, 0deg)) scale3d(.06, .16, 1);\n }\n 20%, 72% {\n opacity: .94;\n transform: translate3d(-50%, -50%, 0) rotate(var(--xiaohei-sidebar-portal-angle, 0deg)) scale3d(1, 1, 1);\n }\n 100% {\n opacity: 0;\n transform: translate3d(-50%, -50%, 0) rotate(var(--xiaohei-sidebar-portal-angle, 0deg)) scale3d(.06, .16, 1);\n }\n}\n\n@keyframes xiaohei-sidebar-heixiu-enter {\n 0%, 15% { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }\n 70% { opacity: .82; }\n 100% {\n transform: translate3d(var(--xiaohei-sidebar-escape-in-x), var(--xiaohei-sidebar-escape-in-y), 0) scale(.08);\n opacity: 0;\n }\n}\n\n@keyframes xiaohei-sidebar-heixiu-exit {\n 0%, 16% {\n transform: translate3d(var(--xiaohei-sidebar-escape-out-x), var(--xiaohei-sidebar-escape-out-y), 0) scale(.08);\n opacity: 0;\n }\n 38% { opacity: .72; }\n 100% { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }\n}\n\nhtml[data-xiaohei-appearance='light'] .xiaohei-sidebar-escape-portal {\n background:\n radial-gradient(ellipse at 46% 50%, #010304 0%, #030708 58%, #123231 70%, rgb(46 142 121 / 34%) 77%, transparent 83%);\n box-shadow:\n inset 0 0 0.55rem rgb(0 0 0 / 94%),\n 0 0 0.58rem rgb(44 139 118 / 18%);\n}\n\n@media (prefers-reduced-motion: reduce), (hover: none) and (pointer: coarse), (forced-colors: active) {\n .xiaohei-sidebar-escape-layer { display: none; }\n\n .xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase]\n .xiaohei-scene__heixiu-body {\n animation: none;\n will-change: auto;\n }\n}\n";
37
- /** True when the pointer is close enough for the sidebar companion to flee. */
38
- export declare function isXiaoheiSidebarPointerNear(pointer: Point, creatureCenter: Point): boolean;
39
- /** Choose a low-obstruction endpoint that is meaningfully away from the pointer. */
40
- export declare function chooseXiaoheiSidebarEscapeDestination(space: XiaoheiSidebarEscapeSpace, pointer: Point, current: Point, random?: () => number): Point;
41
- /** Own pointer proximity and the enter/exit portal sequence; roaming owns position. */
42
- export declare function createXiaoheiSidebarEscapeController(options: XiaoheiSidebarEscapeControllerOptions): XiaoheiSidebarEscapeController;
43
- export {};
44
- //# sourceMappingURL=sidebar-heixiu-escape.d.ts.map