@glissade/backend-dom 0.21.0-pre.1 → 0.21.0-pre.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 CHANGED
@@ -44,6 +44,14 @@ function frame(t) {
44
44
  }
45
45
  ```
46
46
 
47
+ > **A node may stamp `data-node-id` on more than one element.** Identity is
48
+ > stamped per emitted command, so a node's transform wrapper *and* its content
49
+ > element (the `<svg>`/text `<div>`) both carry the id. Use `el.closest('[data-node-id]')`
50
+ > for hit-testing (the editing contract — it resolves to the nearest tagged
51
+ > element regardless); if you build a node→element MAP, `querySelectorAll('[data-node-id="x"]')`
52
+ > returns more than one element per node, so dedupe by id (or key off the outer
53
+ > wrapper).
54
+
47
55
  Then the DOM is your **interaction surface** while the scene graph stays the single
48
56
  source of truth — read identity, mutate the scene, never write the DOM back:
49
57
 
@@ -56,6 +64,36 @@ stage.addEventListener('click', (e) => {
56
64
  });
57
65
  ```
58
66
 
67
+ > **One `emitWithIds()` feeds BOTH `setIds` and `render`.** The id stream is
68
+ > positional by command index, so `setIds(...)` and `render(...)` must come from
69
+ > the *same* emit — `setIds(emitWithIds(sceneA, …).ids)` then
70
+ > `render(evaluate(sceneB, …))` silently mis-maps `data-node-id`. Always destructure
71
+ > one call: `const { displayList, ids } = emitWithIds(scene, tl, t)`.
72
+
73
+ ## No-build (`<script src>`)
74
+
75
+ The DOM tier ships as a separate **optional** IIFE, `glissade-dom.browser.js`, a
76
+ second `<script>` loaded *after* the base bundle — it augments `window.glissade`
77
+ with `DomBackend` + `emitWithIds` (the base playback bundle stays lean and
78
+ `DomBackend`-free):
79
+
80
+ ```html
81
+ <script src="https://unpkg.com/@glissade/browser/dist/glissade.browser.js"></script>
82
+ <script src="https://unpkg.com/@glissade/browser/dist/glissade-dom.browser.js"></script>
83
+ <script type="module">
84
+ const backend = new glissade.DomBackend(document.getElementById('stage'));
85
+ function frame(t) {
86
+ for (const m of movements) m.run(t);
87
+ const { displayList, ids } = glissade.emitWithIds(scene, EMPTY, t); // ONE emit
88
+ backend.setIds(ids);
89
+ backend.render(displayList);
90
+ }
91
+ </script>
92
+ ```
93
+
94
+ Load order is fail-loud: `glissade-dom.browser.js` throws a clear error if the
95
+ base bundle is absent or a different version (never a cryptic `undefined`).
96
+
59
97
  ## What it maps
60
98
 
61
99
  | IR op | DOM/SVG |
package/dist/index.js CHANGED
@@ -265,8 +265,8 @@ var DomBackend = class {
265
265
  const o = this.#matchOrCreate(cursor, key, "fillText", () => {
266
266
  const div = doc.createElement("div");
267
267
  div.style.position = "absolute";
268
- div.style.transform = "translateY(-0.8em)";
269
268
  div.style.whiteSpace = "pre";
269
+ div.style.lineHeight = "1";
270
270
  return {
271
271
  op: "fillText",
272
272
  el: div,
@@ -276,11 +276,15 @@ var DomBackend = class {
276
276
  const div = o.el;
277
277
  this.#setStyle(o, div, "left", `${cmd.x}px`);
278
278
  this.#setStyle(o, div, "top", `${cmd.y}px`);
279
- this.#setStyle(o, div, "font", fontString(cmd.font));
279
+ const ax = cmd.align === "center" ? "-50%" : cmd.align === "right" ? "-100%" : "0px";
280
+ this.#setStyle(o, div, "transform", `translate(${ax}, -0.8em)`);
281
+ this.#setStyle(o, div, "fontFamily", cmd.font.family);
282
+ this.#setStyle(o, div, "fontSize", `${cmd.font.size}px`);
283
+ this.#setStyle(o, div, "fontWeight", cmd.font.weight !== void 0 ? String(cmd.font.weight) : void 0);
284
+ this.#setStyle(o, div, "fontStyle", cmd.font.style !== void 0 ? cmd.font.style : void 0);
280
285
  this.#setStyle(o, div, "fontVariationSettings", cmd.font.fontVariationSettings !== void 0 ? cmd.font.fontVariationSettings : void 0);
281
286
  this.#setStyle(o, div, "color", this.#solid(cmd.paint));
282
287
  this.#setAttr(div, o, "dataApprox", "data-approx", cmd.paint.kind !== "color" ? "true" : void 0);
283
- this.#setStyle(o, div, "textAlign", cmd.align !== void 0 ? cmd.align : void 0);
284
288
  this.#setText(div, o, cmd.text);
285
289
  this.#stamp(o, div, id);
286
290
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glissade/backend-dom",
3
- "version": "0.21.0-pre.1",
3
+ "version": "0.21.0-pre.3",
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.21.0-pre.1",
22
- "@glissade/scene": "0.21.0-pre.1"
21
+ "@glissade/core": "0.21.0-pre.3",
22
+ "@glissade/scene": "0.21.0-pre.3"
23
23
  },
24
24
  "repository": {
25
25
  "type": "git",