@glissade/backend-dom 0.22.0-pre.3 → 0.22.0-pre.5
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 +10 -4
- package/dist/index.d.ts +14 -3
- package/dist/index.js +22 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -108,11 +108,17 @@ base bundle is absent or a different version (never a cryptic `undefined`).
|
|
|
108
108
|
|
|
109
109
|
### Documented divergences (preview/non-parity)
|
|
110
110
|
|
|
111
|
-
- **Text line-breaking** is the browser's layout engine, **not** the canvas/Skia
|
|
112
|
-
rasterizer — so line breaks can differ from `gs render`. Intended.
|
|
113
111
|
- **Text line-breaking** uses the browser's layout engine, so it can differ from
|
|
114
|
-
the canvas/Skia rasterizer
|
|
115
|
-
so wrapping reflects the real font (a detached host would measure 0).
|
|
112
|
+
the canvas/Skia rasterizer (intended). The measuring span is mounted in the live
|
|
113
|
+
document so wrapping reflects the real font (a detached host would measure 0).
|
|
114
|
+
**Web fonts load async**, so text first measured before its font loads wraps on
|
|
115
|
+
the fallback estimate. Pass **`onReflow`** and re-render in it — the backend
|
|
116
|
+
fires it when `document.fonts` becomes ready (and on later `@font-face` batches),
|
|
117
|
+
so the host re-evaluates and text re-wraps with the loaded font:
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
const backend = new DomBackend(stage, { onReflow: () => frame(currentTime) });
|
|
121
|
+
```
|
|
116
122
|
- **`measureText`** measures `width` via a hidden DOM element (matching what this
|
|
117
123
|
backend draws). `ascent`/`descent` are **estimates** (`0.8`/`0.2 × fontSize`),
|
|
118
124
|
not real font metrics — fine for layout composition, not for exact vertical
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,18 @@ import { BackendCaps, DisplayList, FontSpec, RenderBackend, TextMetricsLite, Vid
|
|
|
2
2
|
import { NodeIdStream } from "@glissade/scene/identity";
|
|
3
3
|
|
|
4
4
|
//#region src/index.d.ts
|
|
5
|
-
|
|
5
|
+
/** Construction options for {@link DomBackend}. */
|
|
6
|
+
interface DomBackendOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Called when web fonts finish loading (and on later lazy `@font-face`
|
|
9
|
+
* batches). **Re-render in this callback** so text re-wraps with the loaded
|
|
10
|
+
* fonts — wrapping is computed upstream in the scene from this backend's
|
|
11
|
+
* `measureText`, so a caption measured before its font loaded can render
|
|
12
|
+
* unwrapped at first paint. Typically `() => drive(currentTime)` in a host's
|
|
13
|
+
* draw loop. No-op where `document.fonts` is absent (e.g. jsdom).
|
|
14
|
+
*/
|
|
15
|
+
onReflow?: () => void;
|
|
16
|
+
}
|
|
6
17
|
/**
|
|
7
18
|
* A DOM/SVG `RenderBackend`. Construct with a host element (renders into it) or a
|
|
8
19
|
* bare `Document` (builds a detached `root` you read off `backend.root`). Each
|
|
@@ -13,7 +24,7 @@ import { NodeIdStream } from "@glissade/scene/identity";
|
|
|
13
24
|
declare class DomBackend implements RenderBackend {
|
|
14
25
|
#private;
|
|
15
26
|
readonly root: HTMLElement;
|
|
16
|
-
constructor(target: HTMLElement | Document);
|
|
27
|
+
constructor(target: HTMLElement | Document, opts?: DomBackendOptions);
|
|
17
28
|
readonly caps: BackendCaps;
|
|
18
29
|
/** Supply the out-of-band id stream (S1 `emitWithIds().ids`) the next
|
|
19
30
|
* `render()` stamps as `data-node-id`. Positional by command index. */
|
|
@@ -26,4 +37,4 @@ declare class DomBackend implements RenderBackend {
|
|
|
26
37
|
dispose(): void;
|
|
27
38
|
}
|
|
28
39
|
//#endregion
|
|
29
|
-
export { DomBackend };
|
|
40
|
+
export { DomBackend, DomBackendOptions };
|
package/dist/index.js
CHANGED
|
@@ -157,13 +157,14 @@ var DomBackend = class {
|
|
|
157
157
|
#recon = /* @__PURE__ */ new WeakMap();
|
|
158
158
|
#owned = /* @__PURE__ */ new WeakMap();
|
|
159
159
|
#ids = [];
|
|
160
|
+
#onReflow;
|
|
160
161
|
#measureSpan = null;
|
|
161
162
|
#warnedMeasure = false;
|
|
162
163
|
#warnedMesh = false;
|
|
163
164
|
#warnedGradientInterp = false;
|
|
164
165
|
#warnedShader = false;
|
|
165
166
|
#warnedUnbalanced = false;
|
|
166
|
-
constructor(target) {
|
|
167
|
+
constructor(target, opts = {}) {
|
|
167
168
|
const isDoc = target.nodeType === 9;
|
|
168
169
|
this.#doc = isDoc ? target : target.ownerDocument ?? target;
|
|
169
170
|
this.#host = isDoc ? null : target;
|
|
@@ -172,6 +173,26 @@ var DomBackend = class {
|
|
|
172
173
|
this.root.style.position = "relative";
|
|
173
174
|
this.root.style.overflow = "hidden";
|
|
174
175
|
if (this.#host) this.#host.appendChild(this.root);
|
|
176
|
+
this.#onReflow = opts.onReflow;
|
|
177
|
+
this.#wireFontReflow();
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* When web fonts finish loading, fire `onReflow` so the HOST re-renders. Text
|
|
181
|
+
* wrapping is computed UPSTREAM in the scene (from this backend's `measureText`),
|
|
182
|
+
* so a caption measured before its font loaded wraps on the fallback-font
|
|
183
|
+
* estimate and can render unwrapped at first paint. The backend can't re-wrap
|
|
184
|
+
* alone — the line breaks already live in the DisplayList the scene produced —
|
|
185
|
+
* so per the passive-sink contract it SIGNALS, and the host re-evaluates with
|
|
186
|
+
* the now-loaded fonts. No-op when no `onReflow` is given or the environment
|
|
187
|
+
* has no `document.fonts` (e.g. jsdom).
|
|
188
|
+
*/
|
|
189
|
+
#wireFontReflow() {
|
|
190
|
+
const reflow = this.#onReflow;
|
|
191
|
+
if (!reflow) return;
|
|
192
|
+
const fonts = this.#doc.fonts;
|
|
193
|
+
if (!fonts) return;
|
|
194
|
+
fonts.ready?.then?.(() => reflow())?.catch?.(() => {});
|
|
195
|
+
fonts.addEventListener?.("loadingdone", () => reflow());
|
|
175
196
|
}
|
|
176
197
|
caps = {
|
|
177
198
|
filters: ALL_FILTER_KINDS,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glissade/backend-dom",
|
|
3
|
-
"version": "0.22.0-pre.
|
|
3
|
+
"version": "0.22.0-pre.5",
|
|
4
4
|
"description": "glissade DOM render backend: DisplayList -> HTML/SVG elements. A preview / non-parity realtime tier (accessibility, selectable text, CSS-native embedding) — NOT a Skia-export twin.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@glissade/core": "0.22.0-pre.
|
|
22
|
-
"@glissade/scene": "0.22.0-pre.
|
|
21
|
+
"@glissade/core": "0.22.0-pre.5",
|
|
22
|
+
"@glissade/scene": "0.22.0-pre.5"
|
|
23
23
|
},
|
|
24
24
|
"repository": {
|
|
25
25
|
"type": "git",
|