@vectojs/core 1.39.0 → 1.40.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.
- package/README.md +43 -135
- package/dist/{chunk-RUM2KEDI.mjs → chunk-AISSDI6U.mjs} +15 -8
- package/dist/{chunk-KRUDTGNR.js → chunk-BKXERWAD.js} +15 -8
- package/dist/{chunk-7PYD5UDX.mjs → chunk-CIRZ3S2Z.mjs} +48 -3
- package/dist/{chunk-POPXUPKR.js → chunk-HC5EZOZJ.js} +80 -35
- package/dist/components/VirtualizedSetAggregate.d.ts +110 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1130 -216
- package/dist/index.mjs +927 -13
- package/dist/renderer.js +2 -2
- package/dist/renderer.mjs +1 -1
- package/dist/text.js +2 -2
- package/dist/text.mjs +1 -1
- package/dist/tree/Entity.d.ts +59 -1
- package/dist/tree/Scene.d.ts +212 -1
- package/dist/tree/scene/HitResult.d.ts +50 -0
- package/dist/tree/scene/HitTester.d.ts +30 -0
- package/dist/tree/scene/ProjectionBackend.d.ts +64 -0
- package/dist/tree/scene/ProjectionPolicy.d.ts +162 -0
- package/dist/tree/scene/SemanticProjectionPolicy.d.ts +119 -0
- package/dist/wasm/vectojs_core.wasm +0 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _createStarExport(obj) { Object.keys(obj) .filter((key) => key !== "default" && key !== "__esModule") .forEach((key) => { if (exports.hasOwnProperty(key)) { return; } Object.defineProperty(exports, key, {enumerable: true, configurable: true, get: () => obj[key]}); }); } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14; var _class15; var _class16; var _class17; var _class18; var _class19;const __vecto_cjs_url=require("url").pathToFileURL(__filename).href;
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _createStarExport(obj) { Object.keys(obj) .filter((key) => key !== "default" && key !== "__esModule") .forEach((key) => { if (exports.hasOwnProperty(key)) { return; } Object.defineProperty(exports, key, {enumerable: true, configurable: true, get: () => obj[key]}); }); } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14; var _class15; var _class16; var _class17; var _class18; var _class19; var _class20; var _class21;const __vecto_cjs_url=require("url").pathToFileURL(__filename).href;
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
var
|
|
15
|
+
var _chunkBKXERWADjs = require('./chunk-BKXERWAD.js');
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
var
|
|
22
|
+
var _chunkHC5EZOZJjs = require('./chunk-HC5EZOZJ.js');
|
|
23
23
|
|
|
24
24
|
// src/tree/ComputeParticleEntity.ts
|
|
25
25
|
var PARTICLE_STRIDE_FLOATS = 8;
|
|
@@ -31,7 +31,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
|
|
|
31
31
|
var PARTICLE_OFFSET_ORIGIN_Y = 5;
|
|
32
32
|
var PARTICLE_OFFSET_SIZE = 6;
|
|
33
33
|
var PARTICLE_OFFSET_LIFE = 7;
|
|
34
|
-
var ComputeParticleEntity = (_class = class extends
|
|
34
|
+
var ComputeParticleEntity = (_class = class extends _chunkHC5EZOZJjs.Entity {
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
|
|
@@ -1070,8 +1070,11 @@ var CanvasGeometry = (_class3 = class {
|
|
|
1070
1070
|
/** Effective device pixel ratio, matching CanvasRenderer: real DPR clamped to
|
|
1071
1071
|
* `maxDPR` when set. */
|
|
1072
1072
|
effectiveDPR(maxDPR) {
|
|
1073
|
-
const
|
|
1074
|
-
|
|
1073
|
+
const raw = typeof window !== "undefined" ? window.devicePixelRatio : 1;
|
|
1074
|
+
const real = Number.isFinite(raw) && raw > 0 ? raw : 1;
|
|
1075
|
+
if (maxDPR === void 0) return real;
|
|
1076
|
+
if (!Number.isFinite(maxDPR) || maxDPR <= 0) return real;
|
|
1077
|
+
return Math.min(real, maxDPR);
|
|
1075
1078
|
}
|
|
1076
1079
|
/** Size the WebGPU particle canvas: backing store at logical × DPR, CSS box at
|
|
1077
1080
|
* the logical size. Sizing the backing store in logical px (the old
|
|
@@ -1596,6 +1599,62 @@ var HitTester = (_class6 = class {
|
|
|
1596
1599
|
findEntityAt(x, y, frame, width, height) {
|
|
1597
1600
|
const overlayHit = this.findHitRecursively(this.overlayRoot, x, y);
|
|
1598
1601
|
if (overlayHit) return overlayHit;
|
|
1602
|
+
return this.findMainTreeHit(x, y, frame, width, height);
|
|
1603
|
+
}
|
|
1604
|
+
/**
|
|
1605
|
+
* The merged hit list (RFC5 §2, CTX-0600): the canvas spatial test plus
|
|
1606
|
+
* caller-observed DOM-native candidates (mirror / portal / `dom-visual`
|
|
1607
|
+
* extension point for CTX-0598) as ONE ordered candidate list.
|
|
1608
|
+
*
|
|
1609
|
+
* Query API only — no dispatch change: `findEntityAt` keeps its single
|
|
1610
|
+
* topmost answer byte-for-byte. Coordinates enter in scene space (callers
|
|
1611
|
+
* map client coordinates first, e.g. `Scene.findHitsAtClient`); backend
|
|
1612
|
+
* attribution follows. DOM candidates pass through the same
|
|
1613
|
+
* `disabled` / `pointerEvents: 'none'` predicate as the canvas paths
|
|
1614
|
+
* (RFC5 §2 rule 4); the browser's hit test is their geometric authority,
|
|
1615
|
+
* so scene-space `isPointInside` is not re-checked.
|
|
1616
|
+
*
|
|
1617
|
+
* Overlay order is authoritative (RFC5 §2 rule 2): overlay-subtree
|
|
1618
|
+
* candidates sort above main-tree candidates, DOM-native backends above
|
|
1619
|
+
* canvas within one subtree. Sorted descending by `priority`; ties keep
|
|
1620
|
+
* insertion order (canvas overlay, canvas main, then DOM in caller order).
|
|
1621
|
+
*/
|
|
1622
|
+
findHitsAt(x, y, frame, width, height, domCandidates = []) {
|
|
1623
|
+
const results = [];
|
|
1624
|
+
const overlayHit = this.findHitRecursively(this.overlayRoot, x, y);
|
|
1625
|
+
if (overlayHit) results.push(this.toHitResult(overlayHit, "canvas", x, y));
|
|
1626
|
+
const mainHit = this.findMainTreeHit(x, y, frame, width, height);
|
|
1627
|
+
if (mainHit) results.push(this.toHitResult(mainHit, "canvas", x, y));
|
|
1628
|
+
for (const candidate of domCandidates) {
|
|
1629
|
+
if (!this.isHitEligible(candidate.node, x, y)) continue;
|
|
1630
|
+
results.push(this.toHitResult(candidate.node, candidate.backend, x, y));
|
|
1631
|
+
}
|
|
1632
|
+
results.sort((a, b) => b.priority - a.priority);
|
|
1633
|
+
return results;
|
|
1634
|
+
}
|
|
1635
|
+
/**
|
|
1636
|
+
* Attribute one candidate: scene-space point plus node-local point, with
|
|
1637
|
+
* the compositor-layer priority (overlay subtree above main tree,
|
|
1638
|
+
* DOM-native backends above canvas within one subtree).
|
|
1639
|
+
*/
|
|
1640
|
+
toHitResult(node, backend, x, y) {
|
|
1641
|
+
return {
|
|
1642
|
+
node,
|
|
1643
|
+
backend,
|
|
1644
|
+
localPoint: node.worldToLocal(x, y),
|
|
1645
|
+
worldPoint: { x, y },
|
|
1646
|
+
priority: (this.isInOverlaySubtree(node) ? 2 : 0) + (backend === "canvas" ? 0 : 1)
|
|
1647
|
+
};
|
|
1648
|
+
}
|
|
1649
|
+
/** Whether `node` lives under the overlay root (drawn above the main tree). */
|
|
1650
|
+
isInOverlaySubtree(node) {
|
|
1651
|
+
for (let current = node; current; current = current.parent) {
|
|
1652
|
+
if (current === this.overlayRoot) return true;
|
|
1653
|
+
}
|
|
1654
|
+
return false;
|
|
1655
|
+
}
|
|
1656
|
+
/** Main-tree arm of {@link findEntityAt}, shared with {@link findHitsAt}. */
|
|
1657
|
+
findMainTreeHit(x, y, frame, width, height) {
|
|
1599
1658
|
if (this.backends.hit && this.ensureHitGrid(frame, width, height)) {
|
|
1600
1659
|
return this.findEntityAtWasm(x, y);
|
|
1601
1660
|
}
|
|
@@ -3499,6 +3558,207 @@ function normalizeChord(input) {
|
|
|
3499
3558
|
return ordered.join("+");
|
|
3500
3559
|
}
|
|
3501
3560
|
|
|
3561
|
+
// src/tree/scene/SemanticProjectionPolicy.ts
|
|
3562
|
+
var DEFAULT_SEMANTIC_PROJECTION_POLICY = {
|
|
3563
|
+
choose: () => "project"
|
|
3564
|
+
};
|
|
3565
|
+
function getSemanticProjectionCapabilities() {
|
|
3566
|
+
return {
|
|
3567
|
+
htmlInCanvas: supportsHTMLInCanvas(),
|
|
3568
|
+
canvasTextRecovery: false
|
|
3569
|
+
};
|
|
3570
|
+
}
|
|
3571
|
+
var CONTROL_SEMANTIC_ROLES = /* @__PURE__ */ new Set([
|
|
3572
|
+
"button",
|
|
3573
|
+
"link",
|
|
3574
|
+
"checkbox",
|
|
3575
|
+
"radio",
|
|
3576
|
+
"switch",
|
|
3577
|
+
"slider",
|
|
3578
|
+
"spinbutton",
|
|
3579
|
+
"combobox",
|
|
3580
|
+
"listbox",
|
|
3581
|
+
"option",
|
|
3582
|
+
"menuitem",
|
|
3583
|
+
"menuitemcheckbox",
|
|
3584
|
+
"menuitemradio",
|
|
3585
|
+
"tab",
|
|
3586
|
+
"textbox",
|
|
3587
|
+
"searchbox",
|
|
3588
|
+
"progressbar",
|
|
3589
|
+
"scrollbar",
|
|
3590
|
+
"meter"
|
|
3591
|
+
]);
|
|
3592
|
+
function isDeferrableSemanticNode(node) {
|
|
3593
|
+
const attrs = node.getA11yAttributes();
|
|
3594
|
+
if (attrs.tag !== void 0 && attrs.tag !== "div") return false;
|
|
3595
|
+
if (attrs.role !== void 0 && CONTROL_SEMANTIC_ROLES.has(attrs.role)) return false;
|
|
3596
|
+
if (typeof attrs.tabIndex === "number" && attrs.tabIndex >= 0) return false;
|
|
3597
|
+
const projection = _optionalChain([node, 'access', _86 => _86.getContentProjection, 'optionalCall', _87 => _87()]);
|
|
3598
|
+
if (_optionalChain([projection, 'optionalAccess', _88 => _88.selectable])) return false;
|
|
3599
|
+
return true;
|
|
3600
|
+
}
|
|
3601
|
+
function describeHTMLInCanvasSupport() {
|
|
3602
|
+
if (typeof document === "undefined") return { supported: false, reason: "no-dom" };
|
|
3603
|
+
try {
|
|
3604
|
+
const canvas = document.createElement("canvas");
|
|
3605
|
+
const ctx = canvas.getContext("2d");
|
|
3606
|
+
const native2D = typeof CanvasRenderingContext2D !== "undefined" && ctx instanceof CanvasRenderingContext2D;
|
|
3607
|
+
if (native2D && typeof ctx["drawElementImage"] === "function") {
|
|
3608
|
+
return { supported: true };
|
|
3609
|
+
}
|
|
3610
|
+
} catch (e15) {
|
|
3611
|
+
return { supported: false, reason: "no-backend" };
|
|
3612
|
+
}
|
|
3613
|
+
return { supported: false, reason: "no-backend" };
|
|
3614
|
+
}
|
|
3615
|
+
function supportsHTMLInCanvas() {
|
|
3616
|
+
return describeHTMLInCanvasSupport().supported;
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
// src/tree/scene/ProjectionPolicy.ts
|
|
3620
|
+
var DEFAULT_PROJECTION_CAPABILITIES = {
|
|
3621
|
+
/** Static text (short): findability already covered by content projection. */
|
|
3622
|
+
text: {
|
|
3623
|
+
domSupported: true,
|
|
3624
|
+
nativeValue: "medium",
|
|
3625
|
+
domCost: "low",
|
|
3626
|
+
canvasCost: "low",
|
|
3627
|
+
autoDefault: "canvas"
|
|
3628
|
+
},
|
|
3629
|
+
/** Long/selectable text, Markdown blocks: selection, Ctrl+F, translation. */
|
|
3630
|
+
prose: {
|
|
3631
|
+
domSupported: true,
|
|
3632
|
+
nativeValue: "high",
|
|
3633
|
+
domCost: "medium",
|
|
3634
|
+
canvasCost: "high",
|
|
3635
|
+
autoDefault: "dom"
|
|
3636
|
+
},
|
|
3637
|
+
/** Code blocks: selectable source, but canvas carriers already serve selection — rests canvas until measured (RFC4 §6 hybrid mapping). */
|
|
3638
|
+
code: {
|
|
3639
|
+
domSupported: true,
|
|
3640
|
+
nativeValue: "medium",
|
|
3641
|
+
domCost: "medium",
|
|
3642
|
+
canvasCost: "high",
|
|
3643
|
+
autoDefault: "canvas"
|
|
3644
|
+
},
|
|
3645
|
+
/** Text input / editable: IME, caret, clipboard, BiDi come free in DOM. */
|
|
3646
|
+
input: {
|
|
3647
|
+
domSupported: true,
|
|
3648
|
+
nativeValue: "high",
|
|
3649
|
+
domCost: "low",
|
|
3650
|
+
canvasCost: "prohibitive",
|
|
3651
|
+
autoDefault: "dom"
|
|
3652
|
+
},
|
|
3653
|
+
/** Button / Link: cheap either way, native wins on focus + AT clicks. */
|
|
3654
|
+
button: {
|
|
3655
|
+
domSupported: true,
|
|
3656
|
+
nativeValue: "medium",
|
|
3657
|
+
domCost: "low",
|
|
3658
|
+
canvasCost: "low",
|
|
3659
|
+
autoDefault: "dom"
|
|
3660
|
+
},
|
|
3661
|
+
link: {
|
|
3662
|
+
domSupported: true,
|
|
3663
|
+
nativeValue: "medium",
|
|
3664
|
+
domCost: "low",
|
|
3665
|
+
canvasCost: "low",
|
|
3666
|
+
autoDefault: "dom"
|
|
3667
|
+
},
|
|
3668
|
+
/** Select / Dropdown / Checkbox / Radio: popup, keyboard, form semantics. */
|
|
3669
|
+
select: {
|
|
3670
|
+
domSupported: true,
|
|
3671
|
+
nativeValue: "high",
|
|
3672
|
+
domCost: "low",
|
|
3673
|
+
canvasCost: "high",
|
|
3674
|
+
autoDefault: "dom"
|
|
3675
|
+
},
|
|
3676
|
+
/** Container / layout group: no direct representation, children negotiate. */
|
|
3677
|
+
container: {
|
|
3678
|
+
domSupported: true,
|
|
3679
|
+
nativeValue: "none",
|
|
3680
|
+
domCost: "n/a",
|
|
3681
|
+
canvasCost: "low",
|
|
3682
|
+
autoDefault: "canvas"
|
|
3683
|
+
},
|
|
3684
|
+
/** Transform / camera rig: owns space, not pixels — never materialized. */
|
|
3685
|
+
transform: {
|
|
3686
|
+
domSupported: true,
|
|
3687
|
+
nativeValue: "none",
|
|
3688
|
+
domCost: "n/a",
|
|
3689
|
+
canvasCost: "n/a",
|
|
3690
|
+
autoDefault: "canvas"
|
|
3691
|
+
},
|
|
3692
|
+
/** Image / video frame: blit is cheap, one element per item is not. */
|
|
3693
|
+
image: {
|
|
3694
|
+
domSupported: true,
|
|
3695
|
+
nativeValue: "low",
|
|
3696
|
+
domCost: "medium",
|
|
3697
|
+
canvasCost: "low",
|
|
3698
|
+
autoDefault: "canvas"
|
|
3699
|
+
},
|
|
3700
|
+
/** Particles / danmaku / chart glyphs: bulk stays canvas, unconditionally. */
|
|
3701
|
+
particles: {
|
|
3702
|
+
domSupported: true,
|
|
3703
|
+
nativeValue: "none",
|
|
3704
|
+
domCost: "prohibitive",
|
|
3705
|
+
canvasCost: "low",
|
|
3706
|
+
autoDefault: "canvas"
|
|
3707
|
+
},
|
|
3708
|
+
/** Graph nodes/edges (interactive, moderate count): canvas until measured. */
|
|
3709
|
+
graph: {
|
|
3710
|
+
domSupported: true,
|
|
3711
|
+
nativeValue: "low",
|
|
3712
|
+
domCost: "medium",
|
|
3713
|
+
canvasCost: "medium",
|
|
3714
|
+
autoDefault: "canvas"
|
|
3715
|
+
},
|
|
3716
|
+
/** Custom shader / GPU particles: no DOM representation exists. */
|
|
3717
|
+
shader: {
|
|
3718
|
+
domSupported: false,
|
|
3719
|
+
nativeValue: "none",
|
|
3720
|
+
domCost: "unsupported",
|
|
3721
|
+
canvasCost: "low",
|
|
3722
|
+
autoDefault: "canvas"
|
|
3723
|
+
}
|
|
3724
|
+
};
|
|
3725
|
+
var UNKNOWN_PROJECTION_CAPABILITY = {
|
|
3726
|
+
domSupported: false,
|
|
3727
|
+
nativeValue: "none",
|
|
3728
|
+
domCost: "unsupported",
|
|
3729
|
+
canvasCost: "low",
|
|
3730
|
+
autoDefault: "canvas"
|
|
3731
|
+
};
|
|
3732
|
+
var PROJECTION_AUTO_HYSTERESIS_FRAMES = 3;
|
|
3733
|
+
var PROJECTION_AUTO_DOM_BUDGET = 500;
|
|
3734
|
+
function resolveProjection(want, cap, ctx) {
|
|
3735
|
+
if (want === "canvas") return { resolved: "canvas", reason: null };
|
|
3736
|
+
if (!ctx.hasDOM || !ctx.domBackendMounted) {
|
|
3737
|
+
return { resolved: "canvas", reason: "no-dom-backend" };
|
|
3738
|
+
}
|
|
3739
|
+
if (!cap.domSupported) return { resolved: "canvas", reason: "unsupported-kind" };
|
|
3740
|
+
if (want === "dom") {
|
|
3741
|
+
if (cap.domCost === "prohibitive") return { resolved: "canvas", reason: "prohibitive-cost" };
|
|
3742
|
+
return { resolved: "dom", reason: null };
|
|
3743
|
+
}
|
|
3744
|
+
if (cap.nativeValue === "high" && cap.domCost !== "prohibitive") {
|
|
3745
|
+
return { resolved: "dom", reason: null };
|
|
3746
|
+
}
|
|
3747
|
+
if (cap.canvasCost === "prohibitive" && cap.domSupported) {
|
|
3748
|
+
return { resolved: "dom", reason: null };
|
|
3749
|
+
}
|
|
3750
|
+
if (cap.autoDefault === "dom") return { resolved: "dom", reason: null };
|
|
3751
|
+
return { resolved: "canvas", reason: null };
|
|
3752
|
+
}
|
|
3753
|
+
function hysteresisVote(current, desired, consecutive, hysteresisFrames) {
|
|
3754
|
+
if (current === void 0 || current === desired) {
|
|
3755
|
+
return { resolved: desired, consecutive: 0, flipped: false };
|
|
3756
|
+
}
|
|
3757
|
+
const next = consecutive + 1;
|
|
3758
|
+
if (next >= hysteresisFrames) return { resolved: desired, consecutive: 0, flipped: true };
|
|
3759
|
+
return { resolved: current, consecutive: next, flipped: false };
|
|
3760
|
+
}
|
|
3761
|
+
|
|
3502
3762
|
// src/tree/Scene.ts
|
|
3503
3763
|
var RANGE_VALUE_ROLES = /* @__PURE__ */ new Set(["slider", "spinbutton", "progressbar", "scrollbar", "meter"]);
|
|
3504
3764
|
var INTERACTIVE_A11Y_ROLES = /* @__PURE__ */ new Set([
|
|
@@ -3522,7 +3782,8 @@ var KEYBOARD_OWNING_ROLES = /* @__PURE__ */ new Set([
|
|
|
3522
3782
|
]);
|
|
3523
3783
|
function ownsKeyboard(el) {
|
|
3524
3784
|
if (!el) return false;
|
|
3525
|
-
if (el === document.body || el === document.documentElement)
|
|
3785
|
+
if (typeof document !== "undefined" && (el === document.body || el === document.documentElement))
|
|
3786
|
+
return false;
|
|
3526
3787
|
if (el.hasAttribute("data-vecto-a11y-root")) return false;
|
|
3527
3788
|
const tag = el.tagName;
|
|
3528
3789
|
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
@@ -3562,6 +3823,7 @@ var SCENE_OPTION_KEYS = [
|
|
|
3562
3823
|
"renderer",
|
|
3563
3824
|
"renderMode",
|
|
3564
3825
|
"respectReducedMotion",
|
|
3826
|
+
"semanticProjectionPolicy",
|
|
3565
3827
|
"userTiming"
|
|
3566
3828
|
];
|
|
3567
3829
|
var SCENE_FIELD_NOT_OPTION = {
|
|
@@ -3678,9 +3940,9 @@ function parseCssMatrix(transform) {
|
|
|
3678
3940
|
}
|
|
3679
3941
|
function clientToGridLocal(contentEl, canvas, clientX, clientY) {
|
|
3680
3942
|
const line = contentEl.querySelector("[data-vecto-grid-line]");
|
|
3681
|
-
const originMarker = _optionalChain([line, 'optionalAccess',
|
|
3682
|
-
const xMarker = _optionalChain([line, 'optionalAccess',
|
|
3683
|
-
const yMarker = _optionalChain([line, 'optionalAccess',
|
|
3943
|
+
const originMarker = _optionalChain([line, 'optionalAccess', _89 => _89.querySelector, 'call', _90 => _90('[data-vecto-grid-basis="origin"]')]);
|
|
3944
|
+
const xMarker = _optionalChain([line, 'optionalAccess', _91 => _91.querySelector, 'call', _92 => _92('[data-vecto-grid-basis="x"]')]);
|
|
3945
|
+
const yMarker = _optionalChain([line, 'optionalAccess', _93 => _93.querySelector, 'call', _94 => _94('[data-vecto-grid-basis="y"]')]);
|
|
3684
3946
|
if (line && originMarker && xMarker && yMarker) {
|
|
3685
3947
|
const origin = originMarker.getBoundingClientRect();
|
|
3686
3948
|
const xPoint = xMarker.getBoundingClientRect();
|
|
@@ -3764,7 +4026,7 @@ function nearestTextPositionInLine(line, x, y) {
|
|
|
3764
4026
|
nearest = { position: { node, offset }, distance: candidate.distance };
|
|
3765
4027
|
}
|
|
3766
4028
|
}
|
|
3767
|
-
return _nullishCoalesce(_optionalChain([nearest, 'optionalAccess',
|
|
4029
|
+
return _nullishCoalesce(_optionalChain([nearest, 'optionalAccess', _95 => _95.position]), () => ( null));
|
|
3768
4030
|
}
|
|
3769
4031
|
function nearestTextPositionInProjection(contentEl, canvas, x, y, eventTarget) {
|
|
3770
4032
|
if (contentEl.dataset.vectoContentGrid !== void 0) {
|
|
@@ -3778,7 +4040,7 @@ function nearestTextPositionInProjection(contentEl, canvas, x, y, eventTarget) {
|
|
|
3778
4040
|
}
|
|
3779
4041
|
targetLine = targetLine.parentElement;
|
|
3780
4042
|
}
|
|
3781
|
-
if (_optionalChain([targetLine, 'optionalAccess',
|
|
4043
|
+
if (_optionalChain([targetLine, 'optionalAccess', _96 => _96.parentElement]) === contentEl) {
|
|
3782
4044
|
return nearestTextPositionInLine(targetLine, x, y);
|
|
3783
4045
|
}
|
|
3784
4046
|
let bestLine = null;
|
|
@@ -3840,13 +4102,13 @@ function extendSelection(selection, anchor, focus) {
|
|
|
3840
4102
|
try {
|
|
3841
4103
|
selection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset);
|
|
3842
4104
|
return;
|
|
3843
|
-
} catch (
|
|
4105
|
+
} catch (e16) {
|
|
3844
4106
|
}
|
|
3845
4107
|
try {
|
|
3846
4108
|
selection.collapse(anchor.node, anchor.offset);
|
|
3847
4109
|
selection.extend(focus.node, focus.offset);
|
|
3848
4110
|
return;
|
|
3849
|
-
} catch (
|
|
4111
|
+
} catch (e17) {
|
|
3850
4112
|
}
|
|
3851
4113
|
const anchorRange = document.createRange();
|
|
3852
4114
|
anchorRange.setStart(anchor.node, anchor.offset);
|
|
@@ -4040,7 +4302,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4040
4302
|
__init108() {this.forcedColorsChangeHandler = null}
|
|
4041
4303
|
/** True when the OS asks for reduced motion and we respect it. Read by the animation drivers. */
|
|
4042
4304
|
get prefersReducedMotion() {
|
|
4043
|
-
return this.respectReducedMotion && !!_optionalChain([this, 'access',
|
|
4305
|
+
return this.respectReducedMotion && !!_optionalChain([this, 'access', _97 => _97.reducedMotionQuery, 'optionalAccess', _98 => _98.matches]);
|
|
4044
4306
|
}
|
|
4045
4307
|
/**
|
|
4046
4308
|
* True when the OS is in a forced-colors mode (Windows High Contrast, and the
|
|
@@ -4051,7 +4313,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4051
4313
|
* when the setting toggles.
|
|
4052
4314
|
*/
|
|
4053
4315
|
get forcedColors() {
|
|
4054
|
-
return !!_optionalChain([this, 'access',
|
|
4316
|
+
return !!_optionalChain([this, 'access', _99 => _99.forcedColorsQuery, 'optionalAccess', _100 => _100.matches]);
|
|
4055
4317
|
}
|
|
4056
4318
|
// --- domain: a11y-projection — sync throttle and shadow-DOM state ---
|
|
4057
4319
|
/**
|
|
@@ -4059,21 +4321,41 @@ var Scene = (_class15 = class _Scene {
|
|
|
4059
4321
|
* frame. See {@link SceneOptions.a11ySyncInterval}.
|
|
4060
4322
|
*/
|
|
4061
4323
|
__init109() {this.a11ySyncInterval = 0}
|
|
4324
|
+
/**
|
|
4325
|
+
* Per-node semantic projection policy (RFC3 §5, CTX-0599). Consulted once
|
|
4326
|
+
* per node by {@link shouldProjectA11y}; the default projects everything
|
|
4327
|
+
* the legacy predicate projects, so reassigning nothing changes nothing.
|
|
4328
|
+
* See {@link SceneOptions.semanticProjectionPolicy}.
|
|
4329
|
+
*/
|
|
4330
|
+
__init110() {this.semanticProjectionPolicy = DEFAULT_SEMANTIC_PROJECTION_POLICY}
|
|
4331
|
+
/**
|
|
4332
|
+
* Consecutive syncs an `'auto'`-policy node must keep voting for the other
|
|
4333
|
+
* backend before its sticky resolution flips (RFC4 §3 rule 3, CTX-0601).
|
|
4334
|
+
* Documented tunable — see {@link PROJECTION_AUTO_HYSTERESIS_FRAMES}.
|
|
4335
|
+
*/
|
|
4336
|
+
__init111() {this.projectionHysteresisFrames = PROJECTION_AUTO_HYSTERESIS_FRAMES}
|
|
4337
|
+
/**
|
|
4338
|
+
* Maximum `'auto'`-resolved DOM residents per scene per frame (RFC4 §4
|
|
4339
|
+
* particle-row backstop: bulk-count nodes stay canvas). Explicit `'dom'`
|
|
4340
|
+
* requests bypass it. Documented tunable — see
|
|
4341
|
+
* {@link PROJECTION_AUTO_DOM_BUDGET}.
|
|
4342
|
+
*/
|
|
4343
|
+
__init112() {this.projectionAutoDomBudget = PROJECTION_AUTO_DOM_BUDGET}
|
|
4062
4344
|
/** Timestamp of the last a11y sync, for throttling. */
|
|
4063
|
-
|
|
4345
|
+
__init113() {this.lastA11ySync = -Infinity}
|
|
4064
4346
|
/** True if we skipped an a11y sync during animation and need to sync when at rest. */
|
|
4065
|
-
|
|
4347
|
+
__init114() {this.a11yPendingSyncAfterAnimation = false}
|
|
4066
4348
|
// A11y / Automation Layer. `null` in non-DOM (SSR/Node) environments — the
|
|
4067
4349
|
// whole projection degrades to a no-op so the engine's logic stays usable
|
|
4068
4350
|
// server-side (e.g. headless layout / vector export) without jsdom.
|
|
4069
4351
|
|
|
4070
|
-
|
|
4352
|
+
__init115() {this.a11yElements = /* @__PURE__ */ new Map()}
|
|
4071
4353
|
/** Elements that already have the synthetic Enter/Space activation handler
|
|
4072
4354
|
* (see the syncA11y refresh pass) — install-once bookkeeping (#694). */
|
|
4073
|
-
|
|
4355
|
+
__init116() {this.keyboardActivatedA11y = /* @__PURE__ */ new WeakSet()}
|
|
4074
4356
|
// --- domain: content-projection — projected DOM, sync state, calibration, selection ---
|
|
4075
4357
|
/** DOM nodes mirroring static text content, keyed by entity id. */
|
|
4076
|
-
|
|
4358
|
+
__init117() {this.contentElements = /* @__PURE__ */ new Map()}
|
|
4077
4359
|
/**
|
|
4078
4360
|
* What the last completed content-projection sync was built from, per entity.
|
|
4079
4361
|
*
|
|
@@ -4082,9 +4364,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
4082
4364
|
* build. Only populated for entities that opt in via
|
|
4083
4365
|
* {@link Entity.getContentEpoch}. (carryctx CTX-0199)
|
|
4084
4366
|
*/
|
|
4085
|
-
|
|
4367
|
+
__init118() {this.contentSyncState = /* @__PURE__ */ new Map()}
|
|
4086
4368
|
/** Invalidates grid font calibration after browser font availability changes. */
|
|
4087
|
-
|
|
4369
|
+
__init119() {this.contentFontEpoch = 0}
|
|
4088
4370
|
/**
|
|
4089
4371
|
* Bumped whenever the viewport itself changes shape, which re-tiers blocks
|
|
4090
4372
|
* without moving any of them.
|
|
@@ -4097,7 +4379,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4097
4379
|
* carriers it no longer needs. Scrolling needs no such epoch: it moves the root,
|
|
4098
4380
|
* so every block's parent world transform changes and the check fails honestly.
|
|
4099
4381
|
*/
|
|
4100
|
-
|
|
4382
|
+
__init120() {this.contentViewportEpoch = 0}
|
|
4101
4383
|
/**
|
|
4102
4384
|
* One-entry memo for a parent's world transform, held as scalars.
|
|
4103
4385
|
*
|
|
@@ -4112,16 +4394,16 @@ var Scene = (_class15 = class _Scene {
|
|
|
4112
4394
|
* sync, so a memo can never survive into a frame in which the parent has
|
|
4113
4395
|
* moved.
|
|
4114
4396
|
*/
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4397
|
+
__init121() {this._pwNode = null}
|
|
4398
|
+
__init122() {this._pwSerial = -1}
|
|
4399
|
+
__init123() {this._pwa = 1}
|
|
4400
|
+
__init124() {this._pwb = 0}
|
|
4401
|
+
__init125() {this._pwc = 0}
|
|
4402
|
+
__init126() {this._pwd = 1}
|
|
4403
|
+
__init127() {this._pwe = 0}
|
|
4404
|
+
__init128() {this._pwf = 0}
|
|
4123
4405
|
/** Incremented once per top-level `syncA11y`, invalidating `_pwNode`. */
|
|
4124
|
-
|
|
4406
|
+
__init129() {this._syncSerial = 0}
|
|
4125
4407
|
/**
|
|
4126
4408
|
* Disables the settled-walk fast path in {@link syncContentProjection}.
|
|
4127
4409
|
*
|
|
@@ -4133,38 +4415,38 @@ var Scene = (_class15 = class _Scene {
|
|
|
4133
4415
|
* Not part of the public API and not documented as an option: turning it on only
|
|
4134
4416
|
* makes a settled document slower, never more correct.
|
|
4135
4417
|
*/
|
|
4136
|
-
|
|
4418
|
+
__init130() {this.disableSettledFastPath = false}
|
|
4137
4419
|
/** Cached Canvas-to-client scale for the current font/viewport epoch. */
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4420
|
+
__init131() {this.contentMetricScaleEpoch = -1}
|
|
4421
|
+
__init132() {this.contentMetricScaleX = 1}
|
|
4422
|
+
__init133() {this.contentProjectionEnabled = true}
|
|
4141
4423
|
// Virtualization margin (px) for the content-projection CARRIER band;
|
|
4142
4424
|
// `undefined` → one viewport height, resolved at sync time. `Infinity` is
|
|
4143
4425
|
// unsupported here: it unwindows every carrier, which is O(total glyphs).
|
|
4144
|
-
|
|
4426
|
+
__init134() {this.contentProjectionMargin = void 0}
|
|
4145
4427
|
// Virtualization margin (px) for the SEMANTIC tier — whether a block has
|
|
4146
4428
|
// any projected DOM. `undefined` → falls back to contentProjectionMargin, so
|
|
4147
4429
|
// the default keeps one gate. `Infinity` = every block keeps resident text.
|
|
4148
|
-
|
|
4430
|
+
__init135() {this.contentSemanticMargin = void 0}
|
|
4149
4431
|
// How many coarse-tier blocks may be MATERIALIZED per sync, spreading the
|
|
4150
4432
|
// resident tier's document-open cost across frames. `Infinity` = one
|
|
4151
4433
|
// synchronous pass.
|
|
4152
|
-
|
|
4434
|
+
__init136() {this.contentSemanticBudget = DEFAULT_CONTENT_SEMANTIC_BUDGET}
|
|
4153
4435
|
// Remaining materializations in the CURRENT sync. Reset at the start of each
|
|
4154
4436
|
// a11y walk; decremented per coarse block that creates its element.
|
|
4155
|
-
|
|
4437
|
+
__init137() {this.contentSemanticBudgetLeft = 0}
|
|
4156
4438
|
// Set when a sync deferred at least one block, so the scene knows to keep
|
|
4157
4439
|
// drawing frames until the resident tier is complete. Without it a static
|
|
4158
4440
|
// scene in `onDemand` mode would stop rendering with the document half
|
|
4159
4441
|
// materialized and never finish.
|
|
4160
|
-
|
|
4161
|
-
|
|
4442
|
+
__init138() {this.contentSemanticDeferred = false}
|
|
4443
|
+
__init139() {this.contentSelectionEndListener = null}
|
|
4162
4444
|
// --- domain: render-scheduler — per-frame walk flags ---
|
|
4163
4445
|
// Animation/interactive flags collected during the render walk (tree-walk
|
|
4164
4446
|
// fusion): the loop reads last frame's answers instead of re-walking the
|
|
4165
4447
|
// tree up to 4× per tick. Start true so the first tick stays conservative.
|
|
4166
|
-
|
|
4167
|
-
|
|
4448
|
+
__init140() {this.frameHadAnimation = true}
|
|
4449
|
+
__init141() {this.frameHadInteractive = true}
|
|
4168
4450
|
// --- domain: context-and-resize — resize handler, DPR query, canvas observer ---
|
|
4169
4451
|
|
|
4170
4452
|
/** Active `(resolution: Ndppx)` media query watching for a runtime DPR change
|
|
@@ -4172,15 +4454,17 @@ var Scene = (_class15 = class _Scene {
|
|
|
4172
4454
|
* can be re-scaled — otherwise it stays rasterized at the old DPR and blurs.
|
|
4173
4455
|
* A resolution media query only fires when leaving its exact value, so the
|
|
4174
4456
|
* handler re-arms a fresh query for the new DPR each time. */
|
|
4175
|
-
|
|
4457
|
+
__init142() {this.dprMediaQuery = null}
|
|
4176
4458
|
/** For embedded (`disableWindowResize`) scenes: observes the canvas element so
|
|
4177
4459
|
* a CSS/layout-driven size change re-runs `resize()`. A window `resize`
|
|
4178
4460
|
* listener never fires for these (the window isn't what changed), so without
|
|
4179
4461
|
* this an embedded canvas stayed at its initial size forever. */
|
|
4180
|
-
|
|
4181
|
-
|
|
4462
|
+
__init143() {this.canvasResizeObserver = null}
|
|
4463
|
+
__init144() {this.dprChangeHandler = null}
|
|
4464
|
+
__init145() {this.dprPollInterval = null}
|
|
4465
|
+
__init146() {this.lastDpr = 1}
|
|
4182
4466
|
// --- domain: a11y-projection — focus, overlay geometry, DOM ordering, portals ---
|
|
4183
|
-
|
|
4467
|
+
__init147() {this.focusedA11yElement = null}
|
|
4184
4468
|
/**
|
|
4185
4469
|
* Canvas box geometry: the CSS↔logical mapping, overlay layer alignment, and
|
|
4186
4470
|
* the DPR math (extraction 5, `DEC-0024`).
|
|
@@ -4207,7 +4491,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4207
4491
|
/** Shadow elements the pointer is currently inside. Lets a removal that happens
|
|
4208
4492
|
* mid-hover synthesize the `pointerleave` the browser never sends for a
|
|
4209
4493
|
* detached element, so the entity doesn't keep its hover state. */
|
|
4210
|
-
|
|
4494
|
+
__init148() {this.hoveredA11yElements = /* @__PURE__ */ new WeakSet()}
|
|
4211
4495
|
/**
|
|
4212
4496
|
* Entity ids the application has pinned via {@link requestA11yProjection}.
|
|
4213
4497
|
*
|
|
@@ -4215,13 +4499,13 @@ var Scene = (_class15 = class _Scene {
|
|
|
4215
4499
|
* a stale id simply never matches. Cleared per-entity by
|
|
4216
4500
|
* {@link releaseA11yProjection}.
|
|
4217
4501
|
*/
|
|
4218
|
-
|
|
4502
|
+
__init149() {this.a11yProjectionRequests = /* @__PURE__ */ new Set()}
|
|
4219
4503
|
/** Persistent tabindex=-1 element in a11yRoot. When the focused a11y mirror is
|
|
4220
4504
|
* pruned (virtualization/streaming/removal) while it holds focus, we move
|
|
4221
4505
|
* focus here instead of letting the browser drop it to <body> — keeping the
|
|
4222
4506
|
* screen-reader virtual cursor inside the scene's a11y region. */
|
|
4223
|
-
|
|
4224
|
-
|
|
4507
|
+
__init150() {this.focusSentinel = null}
|
|
4508
|
+
__init151() {this.caretBlinkTimer = null}
|
|
4225
4509
|
/**
|
|
4226
4510
|
* The projected DOM's ordering engine — the reorder flag, the per-pass scratch
|
|
4227
4511
|
* collections, the visual reading-order sort and the cursor-based
|
|
@@ -4231,7 +4515,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4231
4515
|
* delegate here; the collect-and-prune walk stays behind because it needs
|
|
4232
4516
|
* {@link shouldProjectA11y} and the focus/caret state.
|
|
4233
4517
|
*/
|
|
4234
|
-
|
|
4518
|
+
__init152() {this.a11yOrder = new A11yProjectionManager()}
|
|
4235
4519
|
/**
|
|
4236
4520
|
* The content projection's selection preservation and grid calibration
|
|
4237
4521
|
* (extraction 3, `DEC-0022`).
|
|
@@ -4283,11 +4567,35 @@ var Scene = (_class15 = class _Scene {
|
|
|
4283
4567
|
set a11yNeedsReorder(value) {
|
|
4284
4568
|
this.a11yOrder.needsReorder = value;
|
|
4285
4569
|
}
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4570
|
+
__init153() {this.portalRoot = null}
|
|
4571
|
+
__init154() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
|
|
4572
|
+
__init155() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
|
|
4573
|
+
__init156() {this.portalEntities = /* @__PURE__ */ new Map()}
|
|
4574
|
+
/**
|
|
4575
|
+
* Generic projection backends (RFC1 §5 vocabulary, `tree/scene/ProjectionBackend.ts`).
|
|
4576
|
+
* Render-independent: the interface exchanges only node identity, world
|
|
4577
|
+
* matrix, and lifecycle calls, so registering a DOM backend adds no
|
|
4578
|
+
* `HTMLElement` surface to core. `@vectojs/dom` owns the only implementation.
|
|
4579
|
+
*/
|
|
4580
|
+
__init157() {this.projectionBackends = []}
|
|
4581
|
+
/** Per-frame seen-sets driving {@link pruneProjectionBackends} (portal-precedent). */
|
|
4582
|
+
__init158() {this.domSeenPrevFrame = /* @__PURE__ */ new Set()}
|
|
4583
|
+
__init159() {this.domSeenThisFrame = /* @__PURE__ */ new Set()}
|
|
4584
|
+
__init160() {this.domSeenNodes = /* @__PURE__ */ new Map()}
|
|
4585
|
+
/**
|
|
4586
|
+
* Negotiation state (RFC4 §3, CTX-0601): last resolution per node (the
|
|
4587
|
+
* per-scene queryable surface behind {@link getProjectionResolutions}),
|
|
4588
|
+
* hysteresis votes, per-kind capability overrides, and explicit gesture
|
|
4589
|
+
* pins. Plain data only — no `HTMLElement` surface in core.
|
|
4590
|
+
*/
|
|
4591
|
+
__init161() {this.projectionResolutions = /* @__PURE__ */ new Map()}
|
|
4592
|
+
__init162() {this.projectionHysteresis = /* @__PURE__ */ new Map()}
|
|
4593
|
+
__init163() {this.projectionCapabilityOverrides = /* @__PURE__ */ new Map()}
|
|
4594
|
+
__init164() {this.projectionGesturePins = /* @__PURE__ */ new Map()}
|
|
4595
|
+
/** Frame id the `'auto'` DOM budget count belongs to (bulk backstop). */
|
|
4596
|
+
__init165() {this.projectionBudgetFrame = -1}
|
|
4597
|
+
__init166() {this.projectionDomAutoCount = 0}
|
|
4598
|
+
__init167() {this.renderOrderCounter = 0}
|
|
4291
4599
|
// --- domain: render-scheduler — authoritative frame counter ---
|
|
4292
4600
|
/**
|
|
4293
4601
|
* Monotonic render-frame counter, bumped once per authoritative `render()`
|
|
@@ -4297,7 +4605,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4297
4605
|
* back to the ancestor walk. Public for the same reason `Entity._getTrig`/
|
|
4298
4606
|
* `_setWorldCache` are: it is a cross-class render-internal contract.
|
|
4299
4607
|
*/
|
|
4300
|
-
|
|
4608
|
+
__init168() {this.currentFrame = 0}
|
|
4301
4609
|
// --- domain: wasm-backend-facade — EXTRACTED (see scene/WasmBackendFacade.ts) ---
|
|
4302
4610
|
/**
|
|
4303
4611
|
* The four invisible WASM accelerators and the resident transform store.
|
|
@@ -4367,8 +4675,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
4367
4675
|
// Stays on `Scene`: it walks `root` *and* `overlayRoot` for entities the
|
|
4368
4676
|
// render walk consumes, so only its cache key is store state. The facade owns
|
|
4369
4677
|
// the key; the walk stays here.
|
|
4370
|
-
|
|
4371
|
-
|
|
4678
|
+
__init169() {this._computeEntities = []}
|
|
4679
|
+
__init170() {this._computeEntitiesVersion = -1}
|
|
4372
4680
|
/** Invalidate the resident WASM store layout; the next wasm-mode frame rebuilds
|
|
4373
4681
|
* it. Called by `Entity.add`/`remove` (topology changes only). */
|
|
4374
4682
|
markStructureChanged() {
|
|
@@ -4607,7 +4915,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4607
4915
|
get animBatchedLastFrame() {
|
|
4608
4916
|
return this._wasmBackend.animBatchedLastFrame;
|
|
4609
4917
|
}
|
|
4610
|
-
|
|
4918
|
+
__init171() {this.animGate = {
|
|
4611
4919
|
spring: 128,
|
|
4612
4920
|
tween: 256,
|
|
4613
4921
|
mixed: 128
|
|
@@ -4703,7 +5011,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4703
5011
|
* `tickDrivers()`'s per-frame stamp would skip it a full frame — a one-frame
|
|
4704
5012
|
* JS/WASM divergence. Written in {@link render} next to `_tickBatchedDrivers`.
|
|
4705
5013
|
*/
|
|
4706
|
-
|
|
5014
|
+
__init172() {this._updateWalkDt = null}
|
|
4707
5015
|
// --- domain: render-scheduler — batched driver tick (extraction 6), reads the anim backend ---
|
|
4708
5016
|
/**
|
|
4709
5017
|
* Advance every registered entity's active drivers for this frame, batching
|
|
@@ -4731,25 +5039,25 @@ var Scene = (_class15 = class _Scene {
|
|
|
4731
5039
|
* sync, so retaining the order prevents a newly opened overlay from spending
|
|
4732
5040
|
* its first frame below previously projected controls.
|
|
4733
5041
|
*/
|
|
4734
|
-
|
|
5042
|
+
__init173() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
|
|
4735
5043
|
// --- domain: context-and-resize — GL/GPU canvases, device state, pointer, size warnings ---
|
|
4736
5044
|
// Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
5045
|
+
__init174() {this.pointRenderer = null}
|
|
5046
|
+
__init175() {this.glCanvas = null}
|
|
5047
|
+
__init176() {this.glContextLostHandler = null}
|
|
5048
|
+
__init177() {this.glContextRestoredHandler = null}
|
|
4741
5049
|
|
|
4742
5050
|
|
|
4743
5051
|
|
|
4744
|
-
|
|
5052
|
+
__init178() {this.disableWindowResize = false}
|
|
4745
5053
|
/** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
|
|
4746
5054
|
|
|
4747
5055
|
// WebGPU properties
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
5056
|
+
__init179() {this.destroyed = false}
|
|
5057
|
+
__init180() {this.device = null}
|
|
5058
|
+
__init181() {this.deviceLost = false}
|
|
5059
|
+
__init182() {this.particleBackend = "auto"}
|
|
5060
|
+
__init183() {this._webgpuDisabled = false}
|
|
4753
5061
|
get webgpuDisabled() {
|
|
4754
5062
|
return this._webgpuDisabled || this.particleBackend === "cpu";
|
|
4755
5063
|
}
|
|
@@ -4763,7 +5071,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4763
5071
|
* active.
|
|
4764
5072
|
*/
|
|
4765
5073
|
get webglDrawStats() {
|
|
4766
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
5074
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _101 => _101.pointRenderer, 'optionalAccess', _102 => _102.stats, 'optionalCall', _103 => _103()]), () => ( null));
|
|
4767
5075
|
}
|
|
4768
5076
|
/**
|
|
4769
5077
|
* Whether a WebGPU device is currently live for particle compute.
|
|
@@ -4777,28 +5085,28 @@ var Scene = (_class15 = class _Scene {
|
|
|
4777
5085
|
set webgpuDisabled(value) {
|
|
4778
5086
|
this._webgpuDisabled = value;
|
|
4779
5087
|
}
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
5088
|
+
__init184() {this.recoveryTimerId = null}
|
|
5089
|
+
__init185() {this.manager = null}
|
|
5090
|
+
__init186() {this.initializingWebGPU = false}
|
|
5091
|
+
__init187() {this.gpuCanvas = null}
|
|
5092
|
+
__init188() {this.gpuContext = null}
|
|
4785
5093
|
/** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
5094
|
+
__init189() {this.gpuHasContent = false}
|
|
5095
|
+
__init190() {this.mouseX = -9999}
|
|
5096
|
+
__init191() {this.mouseY = -9999}
|
|
5097
|
+
__init192() {this.pointerMoveListener = null}
|
|
5098
|
+
__init193() {this.pointerLeaveListener = null}
|
|
4791
5099
|
/** Element the pointer listeners are bound to (parent container if present,
|
|
4792
5100
|
* else the canvas). Stored so `destroy()` detaches from the same element. */
|
|
4793
|
-
|
|
5101
|
+
__init194() {this.pointerEventTarget = null}
|
|
4794
5102
|
// --- scene-level keyboard channel state (see on/off/registerShortcut) ---
|
|
4795
|
-
|
|
4796
|
-
|
|
5103
|
+
__init195() {this.keydownHandlers = []}
|
|
5104
|
+
__init196() {this.keyupHandlers = []}
|
|
4797
5105
|
/** Chord-normalized shortcut table, matched on keydown only. */
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
5106
|
+
__init197() {this.shortcuts = []}
|
|
5107
|
+
__init198() {this.windowKeyDownHandler = null}
|
|
5108
|
+
__init199() {this.windowKeyUpHandler = null}
|
|
5109
|
+
__init200() {this.hasWarnedZeroSize = false}
|
|
4802
5110
|
/**
|
|
4803
5111
|
* Latch for {@link Scene.resize}'s invalid-dimension warning.
|
|
4804
5112
|
*
|
|
@@ -4808,8 +5116,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
4808
5116
|
* because `resize()` is commonly driven from a `ResizeObserver`, which would
|
|
4809
5117
|
* otherwise warn on every frame of a drag.
|
|
4810
5118
|
*/
|
|
4811
|
-
|
|
4812
|
-
|
|
5119
|
+
__init201() {this.hasWarnedInvalidResize = false}
|
|
5120
|
+
__init202() {this.fontLoadHandler = null}
|
|
4813
5121
|
// --- domain: scene-facade — dev-mode diagnostics ---
|
|
4814
5122
|
// ── Dev-mode warning infrastructure ──────────────────────────────
|
|
4815
5123
|
//
|
|
@@ -4834,17 +5142,17 @@ var Scene = (_class15 = class _Scene {
|
|
|
4834
5142
|
}
|
|
4835
5143
|
static set devMode(active) {
|
|
4836
5144
|
_Scene._devMode = active;
|
|
4837
|
-
|
|
5145
|
+
_chunkBKXERWADjs.setRendererDevMode.call(void 0, active);
|
|
4838
5146
|
}
|
|
4839
5147
|
static _devModeDetected() {
|
|
4840
5148
|
if (_Scene._devMode) return true;
|
|
4841
5149
|
const gp = typeof globalThis !== "undefined" ? globalThis : void 0;
|
|
4842
|
-
if (_optionalChain([gp, 'optionalAccess',
|
|
4843
|
-
if (_optionalChain([gp, 'optionalAccess',
|
|
5150
|
+
if (_optionalChain([gp, 'optionalAccess', _104 => _104.__DEV__])) return true;
|
|
5151
|
+
if (_optionalChain([gp, 'optionalAccess', _105 => _105.process, 'optionalAccess', _106 => _106.env, 'optionalAccess', _107 => _107.NODE_ENV]) === "development") return true;
|
|
4844
5152
|
return false;
|
|
4845
5153
|
}
|
|
4846
5154
|
|
|
4847
|
-
|
|
5155
|
+
__init203() {this._devFrameCount = 0}
|
|
4848
5156
|
_devWarn(message) {
|
|
4849
5157
|
if (!this._devActive) return;
|
|
4850
5158
|
console.warn(`[vectojs/dev] ${message}`);
|
|
@@ -4902,9 +5210,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
4902
5210
|
let checked = 0;
|
|
4903
5211
|
const walkProjections = (node) => {
|
|
4904
5212
|
if (checked > 10) return;
|
|
4905
|
-
const proj = _optionalChain([node, 'access',
|
|
4906
|
-
if (_optionalChain([proj, 'optionalAccess',
|
|
4907
|
-
const el = _optionalChain([this, 'access',
|
|
5213
|
+
const proj = _optionalChain([node, 'access', _108 => _108.getContentProjection, 'optionalCall', _109 => _109()]);
|
|
5214
|
+
if (_optionalChain([proj, 'optionalAccess', _110 => _110.text]) && proj.selectable !== false) {
|
|
5215
|
+
const el = _optionalChain([this, 'access', _111 => _111.contentElements, 'optionalAccess', _112 => _112.get, 'call', _113 => _113(node.id)]);
|
|
4908
5216
|
if (el) {
|
|
4909
5217
|
const projectedText = el.textContent || "";
|
|
4910
5218
|
const windowed = el.dataset.vectoProjectionWindow !== void 0;
|
|
@@ -4922,22 +5230,27 @@ var Scene = (_class15 = class _Scene {
|
|
|
4922
5230
|
walkProjections(this.root);
|
|
4923
5231
|
}
|
|
4924
5232
|
// --- domain: scene-facade — construction (wires every collaborator) ---
|
|
4925
|
-
constructor(canvas, options = {}) {;_class15.prototype.__init88.call(this);_class15.prototype.__init89.call(this);_class15.prototype.__init90.call(this);_class15.prototype.__init91.call(this);_class15.prototype.__init92.call(this);_class15.prototype.__init93.call(this);_class15.prototype.__init94.call(this);_class15.prototype.__init95.call(this);_class15.prototype.__init96.call(this);_class15.prototype.__init97.call(this);_class15.prototype.__init98.call(this);_class15.prototype.__init99.call(this);_class15.prototype.__init100.call(this);_class15.prototype.__init101.call(this);_class15.prototype.__init102.call(this);_class15.prototype.__init103.call(this);_class15.prototype.__init104.call(this);_class15.prototype.__init105.call(this);_class15.prototype.__init106.call(this);_class15.prototype.__init107.call(this);_class15.prototype.__init108.call(this);_class15.prototype.__init109.call(this);_class15.prototype.__init110.call(this);_class15.prototype.__init111.call(this);_class15.prototype.__init112.call(this);_class15.prototype.__init113.call(this);_class15.prototype.__init114.call(this);_class15.prototype.__init115.call(this);_class15.prototype.__init116.call(this);_class15.prototype.__init117.call(this);_class15.prototype.__init118.call(this);_class15.prototype.__init119.call(this);_class15.prototype.__init120.call(this);_class15.prototype.__init121.call(this);_class15.prototype.__init122.call(this);_class15.prototype.__init123.call(this);_class15.prototype.__init124.call(this);_class15.prototype.__init125.call(this);_class15.prototype.__init126.call(this);_class15.prototype.__init127.call(this);_class15.prototype.__init128.call(this);_class15.prototype.__init129.call(this);_class15.prototype.__init130.call(this);_class15.prototype.__init131.call(this);_class15.prototype.__init132.call(this);_class15.prototype.__init133.call(this);_class15.prototype.__init134.call(this);_class15.prototype.__init135.call(this);_class15.prototype.__init136.call(this);_class15.prototype.__init137.call(this);_class15.prototype.__init138.call(this);_class15.prototype.__init139.call(this);_class15.prototype.__init140.call(this);_class15.prototype.__init141.call(this);_class15.prototype.__init142.call(this);_class15.prototype.__init143.call(this);_class15.prototype.__init144.call(this);_class15.prototype.__init145.call(this);_class15.prototype.__init146.call(this);_class15.prototype.__init147.call(this);_class15.prototype.__init148.call(this);_class15.prototype.__init149.call(this);_class15.prototype.__init150.call(this);_class15.prototype.__init151.call(this);_class15.prototype.__init152.call(this);_class15.prototype.__init153.call(this);_class15.prototype.__init154.call(this);_class15.prototype.__init155.call(this);_class15.prototype.__init156.call(this);_class15.prototype.__init157.call(this);_class15.prototype.__init158.call(this);_class15.prototype.__init159.call(this);_class15.prototype.__init160.call(this);_class15.prototype.__init161.call(this);_class15.prototype.__init162.call(this);_class15.prototype.__init163.call(this);_class15.prototype.__init164.call(this);_class15.prototype.__init165.call(this);_class15.prototype.__init166.call(this);_class15.prototype.__init167.call(this);_class15.prototype.__init168.call(this);_class15.prototype.__init169.call(this);_class15.prototype.__init170.call(this);_class15.prototype.__init171.call(this);_class15.prototype.__init172.call(this);_class15.prototype.__init173.call(this);_class15.prototype.__init174.call(this);_class15.prototype.__init175.call(this);_class15.prototype.__init176.call(this);_class15.prototype.__init177.call(this);_class15.prototype.__init178.call(this);_class15.prototype.__init179.call(this);_class15.prototype.__init180.call(this);_class15.prototype.__init181.call(this);_class15.prototype.__init182.call(this);_class15.prototype.__init183.call(this);_class15.prototype.__init184.call(this);_class15.prototype.__init185.call(this);_class15.prototype.__init186.call(this);_class15.prototype.__init187.call(this);_class15.prototype.__init188.call(this);
|
|
5233
|
+
constructor(canvas, options = {}) {;_class15.prototype.__init88.call(this);_class15.prototype.__init89.call(this);_class15.prototype.__init90.call(this);_class15.prototype.__init91.call(this);_class15.prototype.__init92.call(this);_class15.prototype.__init93.call(this);_class15.prototype.__init94.call(this);_class15.prototype.__init95.call(this);_class15.prototype.__init96.call(this);_class15.prototype.__init97.call(this);_class15.prototype.__init98.call(this);_class15.prototype.__init99.call(this);_class15.prototype.__init100.call(this);_class15.prototype.__init101.call(this);_class15.prototype.__init102.call(this);_class15.prototype.__init103.call(this);_class15.prototype.__init104.call(this);_class15.prototype.__init105.call(this);_class15.prototype.__init106.call(this);_class15.prototype.__init107.call(this);_class15.prototype.__init108.call(this);_class15.prototype.__init109.call(this);_class15.prototype.__init110.call(this);_class15.prototype.__init111.call(this);_class15.prototype.__init112.call(this);_class15.prototype.__init113.call(this);_class15.prototype.__init114.call(this);_class15.prototype.__init115.call(this);_class15.prototype.__init116.call(this);_class15.prototype.__init117.call(this);_class15.prototype.__init118.call(this);_class15.prototype.__init119.call(this);_class15.prototype.__init120.call(this);_class15.prototype.__init121.call(this);_class15.prototype.__init122.call(this);_class15.prototype.__init123.call(this);_class15.prototype.__init124.call(this);_class15.prototype.__init125.call(this);_class15.prototype.__init126.call(this);_class15.prototype.__init127.call(this);_class15.prototype.__init128.call(this);_class15.prototype.__init129.call(this);_class15.prototype.__init130.call(this);_class15.prototype.__init131.call(this);_class15.prototype.__init132.call(this);_class15.prototype.__init133.call(this);_class15.prototype.__init134.call(this);_class15.prototype.__init135.call(this);_class15.prototype.__init136.call(this);_class15.prototype.__init137.call(this);_class15.prototype.__init138.call(this);_class15.prototype.__init139.call(this);_class15.prototype.__init140.call(this);_class15.prototype.__init141.call(this);_class15.prototype.__init142.call(this);_class15.prototype.__init143.call(this);_class15.prototype.__init144.call(this);_class15.prototype.__init145.call(this);_class15.prototype.__init146.call(this);_class15.prototype.__init147.call(this);_class15.prototype.__init148.call(this);_class15.prototype.__init149.call(this);_class15.prototype.__init150.call(this);_class15.prototype.__init151.call(this);_class15.prototype.__init152.call(this);_class15.prototype.__init153.call(this);_class15.prototype.__init154.call(this);_class15.prototype.__init155.call(this);_class15.prototype.__init156.call(this);_class15.prototype.__init157.call(this);_class15.prototype.__init158.call(this);_class15.prototype.__init159.call(this);_class15.prototype.__init160.call(this);_class15.prototype.__init161.call(this);_class15.prototype.__init162.call(this);_class15.prototype.__init163.call(this);_class15.prototype.__init164.call(this);_class15.prototype.__init165.call(this);_class15.prototype.__init166.call(this);_class15.prototype.__init167.call(this);_class15.prototype.__init168.call(this);_class15.prototype.__init169.call(this);_class15.prototype.__init170.call(this);_class15.prototype.__init171.call(this);_class15.prototype.__init172.call(this);_class15.prototype.__init173.call(this);_class15.prototype.__init174.call(this);_class15.prototype.__init175.call(this);_class15.prototype.__init176.call(this);_class15.prototype.__init177.call(this);_class15.prototype.__init178.call(this);_class15.prototype.__init179.call(this);_class15.prototype.__init180.call(this);_class15.prototype.__init181.call(this);_class15.prototype.__init182.call(this);_class15.prototype.__init183.call(this);_class15.prototype.__init184.call(this);_class15.prototype.__init185.call(this);_class15.prototype.__init186.call(this);_class15.prototype.__init187.call(this);_class15.prototype.__init188.call(this);_class15.prototype.__init189.call(this);_class15.prototype.__init190.call(this);_class15.prototype.__init191.call(this);_class15.prototype.__init192.call(this);_class15.prototype.__init193.call(this);_class15.prototype.__init194.call(this);_class15.prototype.__init195.call(this);_class15.prototype.__init196.call(this);_class15.prototype.__init197.call(this);_class15.prototype.__init198.call(this);_class15.prototype.__init199.call(this);_class15.prototype.__init200.call(this);_class15.prototype.__init201.call(this);_class15.prototype.__init202.call(this);_class15.prototype.__init203.call(this);
|
|
4926
5234
|
this.canvas = canvas;
|
|
4927
5235
|
this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
|
|
4928
5236
|
this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
|
|
4929
5237
|
this.maxDPR = options.maxDPR;
|
|
4930
5238
|
if (this.disableWindowResize) {
|
|
4931
|
-
const styleWidth = parseInlinePx(_optionalChain([canvas, 'access',
|
|
4932
|
-
const styleHeight = parseInlinePx(_optionalChain([canvas, 'access',
|
|
5239
|
+
const styleWidth = parseInlinePx(_optionalChain([canvas, 'access', _114 => _114.style, 'optionalAccess', _115 => _115.width]));
|
|
5240
|
+
const styleHeight = parseInlinePx(_optionalChain([canvas, 'access', _116 => _116.style, 'optionalAccess', _117 => _117.height]));
|
|
4933
5241
|
this.width = _nullishCoalesce(styleWidth, () => ( (canvas.width || canvas.clientWidth || 0)));
|
|
4934
5242
|
this.height = _nullishCoalesce(styleHeight, () => ( (canvas.height || canvas.clientHeight || 0)));
|
|
4935
5243
|
} else {
|
|
4936
|
-
|
|
4937
|
-
|
|
5244
|
+
if (typeof canvas.isConnected === "boolean" && !canvas.isConnected) {
|
|
5245
|
+
this.width = 0;
|
|
5246
|
+
this.height = 0;
|
|
5247
|
+
} else {
|
|
5248
|
+
this.width = typeof window !== "undefined" ? window.innerWidth : canvas.clientWidth || canvas.width || 800;
|
|
5249
|
+
this.height = typeof window !== "undefined" ? window.innerHeight : canvas.clientHeight || canvas.height || 600;
|
|
5250
|
+
}
|
|
4938
5251
|
}
|
|
4939
5252
|
const globalProcess = typeof globalThis !== "undefined" ? globalThis.process : void 0;
|
|
4940
|
-
const isTest = globalProcess && (_optionalChain([globalProcess, 'access',
|
|
5253
|
+
const isTest = globalProcess && (_optionalChain([globalProcess, 'access', _118 => _118.env, 'optionalAccess', _119 => _119.NODE_ENV]) === "test" || _optionalChain([globalProcess, 'access', _120 => _120.env, 'optionalAccess', _121 => _121.VITEST]) === "true");
|
|
4941
5254
|
this.maxFPS = _nullishCoalesce(options.maxFPS, () => ( (isTest ? 0 : 60)));
|
|
4942
5255
|
this.respectReducedMotion = _nullishCoalesce(options.respectReducedMotion, () => ( true));
|
|
4943
5256
|
this.autoThrottle = _nullishCoalesce(options.autoThrottle, () => ( true));
|
|
@@ -4945,6 +5258,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
4945
5258
|
this.phases.userTiming = _nullishCoalesce(options.userTiming, () => ( false));
|
|
4946
5259
|
this.particleBackend = _nullishCoalesce(options.particleBackend, () => ( "auto"));
|
|
4947
5260
|
this.a11ySyncInterval = _nullishCoalesce(options.a11ySyncInterval, () => ( 0));
|
|
5261
|
+
this.semanticProjectionPolicy = _nullishCoalesce(options.semanticProjectionPolicy, () => ( DEFAULT_SEMANTIC_PROJECTION_POLICY));
|
|
5262
|
+
this.projectionHysteresisFrames = _nullishCoalesce(options.projectionHysteresisFrames, () => ( PROJECTION_AUTO_HYSTERESIS_FRAMES));
|
|
5263
|
+
this.projectionAutoDomBudget = _nullishCoalesce(options.projectionAutoDomBudget, () => ( PROJECTION_AUTO_DOM_BUDGET));
|
|
4948
5264
|
this.contentProjectionEnabled = _nullishCoalesce(options.contentProjection, () => ( true));
|
|
4949
5265
|
this.contentProjectionMargin = options.contentProjectionMargin;
|
|
4950
5266
|
this.contentSemanticMargin = options.contentSemanticMargin;
|
|
@@ -4952,15 +5268,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
4952
5268
|
this.readingDirection = _nullishCoalesce(options.readingDirection, () => ( "ltr"));
|
|
4953
5269
|
this.renderMode = _nullishCoalesce(options.renderMode, () => ( "always"));
|
|
4954
5270
|
this._devActive = _Scene._devModeDetected();
|
|
4955
|
-
|
|
5271
|
+
_chunkBKXERWADjs.setRendererDevMode.call(void 0, this._devActive);
|
|
4956
5272
|
this._warnUnknownOptions(options);
|
|
4957
5273
|
this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
|
|
4958
5274
|
if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
|
|
4959
5275
|
this.forcedColorsQuery = window.matchMedia("(forced-colors: active)");
|
|
4960
5276
|
this.forcedColorsChangeHandler = () => this.markDirty();
|
|
4961
|
-
_optionalChain([this, 'access',
|
|
5277
|
+
_optionalChain([this, 'access', _122 => _122.forcedColorsQuery, 'access', _123 => _123.addEventListener, 'optionalCall', _124 => _124("change", this.forcedColorsChangeHandler)]);
|
|
4962
5278
|
}
|
|
4963
|
-
this.root = new class RootEntity extends
|
|
5279
|
+
this.root = new class RootEntity extends _chunkHC5EZOZJjs.Entity {
|
|
4964
5280
|
isPointInside() {
|
|
4965
5281
|
return false;
|
|
4966
5282
|
}
|
|
@@ -4970,7 +5286,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4970
5286
|
}("root");
|
|
4971
5287
|
this.root._scene = this;
|
|
4972
5288
|
this._wasmBackend = new WasmBackendFacade(this.root);
|
|
4973
|
-
this.overlayRoot = new class OverlayRoot extends
|
|
5289
|
+
this.overlayRoot = new class OverlayRoot extends _chunkHC5EZOZJjs.Entity {
|
|
4974
5290
|
isPointInside() {
|
|
4975
5291
|
return false;
|
|
4976
5292
|
}
|
|
@@ -4983,15 +5299,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
4983
5299
|
if (options.renderer) {
|
|
4984
5300
|
this.renderer = options.renderer;
|
|
4985
5301
|
} else {
|
|
4986
|
-
this.renderer = new (0,
|
|
5302
|
+
this.renderer = new (0, _chunkBKXERWADjs.CanvasRenderer)(
|
|
4987
5303
|
canvas,
|
|
4988
5304
|
this.disableWindowResize ? { width: this.width, height: this.height } : void 0,
|
|
4989
5305
|
this.maxDPR
|
|
4990
5306
|
);
|
|
4991
5307
|
}
|
|
4992
|
-
_optionalChain([this, 'access',
|
|
5308
|
+
_optionalChain([this, 'access', _125 => _125.renderer, 'access', _126 => _126.onContextRestored, 'optionalCall', _127 => _127(() => {
|
|
4993
5309
|
this.markDirty();
|
|
4994
|
-
if (_optionalChain([this, 'access',
|
|
5310
|
+
if (_optionalChain([this, 'access', _128 => _128.renderer, 'access', _129 => _129.isContextLost, 'optionalCall', _130 => _130()]) !== true) this.render(this.renderer);
|
|
4995
5311
|
})]);
|
|
4996
5312
|
if (typeof document !== "undefined") {
|
|
4997
5313
|
this.a11yRoot = document.createElement("div");
|
|
@@ -5164,18 +5480,54 @@ var Scene = (_class15 = class _Scene {
|
|
|
5164
5480
|
watchDevicePixelRatio() {
|
|
5165
5481
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
5166
5482
|
if (this.dprMediaQuery && this.dprChangeHandler) {
|
|
5167
|
-
_optionalChain([this, 'access',
|
|
5483
|
+
_optionalChain([this, 'access', _131 => _131.dprMediaQuery, 'access', _132 => _132.removeEventListener, 'optionalCall', _133 => _133("change", this.dprChangeHandler)]);
|
|
5168
5484
|
}
|
|
5169
|
-
const
|
|
5485
|
+
const raw = window.devicePixelRatio;
|
|
5486
|
+
const dpr = Number.isFinite(raw) && raw > 0 ? raw : 1;
|
|
5170
5487
|
const query = window.matchMedia(`(resolution: ${dpr}dppx)`);
|
|
5171
5488
|
const handler = () => {
|
|
5172
|
-
|
|
5173
|
-
|
|
5489
|
+
const curRaw = window.devicePixelRatio;
|
|
5490
|
+
const cur = Number.isFinite(curRaw) && curRaw > 0 ? curRaw : 1;
|
|
5491
|
+
if (Math.abs(cur - dpr) <= 1e-3) {
|
|
5492
|
+
this.watchDevicePixelRatio();
|
|
5493
|
+
return;
|
|
5494
|
+
}
|
|
5495
|
+
this.lastDpr = cur;
|
|
5496
|
+
try {
|
|
5497
|
+
this.resize(this.width, this.height);
|
|
5498
|
+
} catch (err) {
|
|
5499
|
+
console.warn("[VectoJS] DPR resize failed", err);
|
|
5500
|
+
}
|
|
5501
|
+
try {
|
|
5502
|
+
if (_optionalChain([this, 'access', _134 => _134.renderer, 'access', _135 => _135.isContextLost, 'optionalCall', _136 => _136()]) !== true) this.render(this.renderer);
|
|
5503
|
+
} catch (err) {
|
|
5504
|
+
console.warn("[VectoJS] DPR repaint failed", err);
|
|
5505
|
+
}
|
|
5174
5506
|
this.watchDevicePixelRatio();
|
|
5175
5507
|
};
|
|
5176
|
-
_optionalChain([query, 'access',
|
|
5508
|
+
_optionalChain([query, 'access', _137 => _137.addEventListener, 'optionalCall', _138 => _138("change", handler)]);
|
|
5177
5509
|
this.dprMediaQuery = query;
|
|
5178
5510
|
this.dprChangeHandler = handler;
|
|
5511
|
+
this.lastDpr = dpr;
|
|
5512
|
+
if (this.dprPollInterval === null && typeof setInterval === "function") {
|
|
5513
|
+
this.dprPollInterval = setInterval(() => {
|
|
5514
|
+
const rawPoll = window.devicePixelRatio;
|
|
5515
|
+
const curPoll = Number.isFinite(rawPoll) && rawPoll > 0 ? rawPoll : 1;
|
|
5516
|
+
if (Math.abs(curPoll - this.lastDpr) <= 1e-3) return;
|
|
5517
|
+
this.lastDpr = curPoll;
|
|
5518
|
+
try {
|
|
5519
|
+
this.resize(this.width, this.height);
|
|
5520
|
+
} catch (err) {
|
|
5521
|
+
console.warn("[VectoJS] DPR poll resize failed", err);
|
|
5522
|
+
}
|
|
5523
|
+
try {
|
|
5524
|
+
if (_optionalChain([this, 'access', _139 => _139.renderer, 'access', _140 => _140.isContextLost, 'optionalCall', _141 => _141()]) !== true) this.render(this.renderer);
|
|
5525
|
+
} catch (err) {
|
|
5526
|
+
console.warn("[VectoJS] DPR poll repaint failed", err);
|
|
5527
|
+
}
|
|
5528
|
+
this.watchDevicePixelRatio();
|
|
5529
|
+
}, 1e3);
|
|
5530
|
+
}
|
|
5179
5531
|
}
|
|
5180
5532
|
/**
|
|
5181
5533
|
* Recover the WebGL point layer from a GPU context loss (driver TDR reset,
|
|
@@ -5193,7 +5545,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5193
5545
|
if (typeof gl.addEventListener !== "function") return;
|
|
5194
5546
|
this.glContextLostHandler = (e) => {
|
|
5195
5547
|
e.preventDefault();
|
|
5196
|
-
_optionalChain([this, 'access',
|
|
5548
|
+
_optionalChain([this, 'access', _142 => _142.pointRenderer, 'optionalAccess', _143 => _143.destroy, 'call', _144 => _144()]);
|
|
5197
5549
|
this.pointRenderer = null;
|
|
5198
5550
|
};
|
|
5199
5551
|
this.glContextRestoredHandler = () => {
|
|
@@ -5209,6 +5561,35 @@ var Scene = (_class15 = class _Scene {
|
|
|
5209
5561
|
gl.addEventListener("webglcontextlost", this.glContextLostHandler);
|
|
5210
5562
|
gl.addEventListener("webglcontextrestored", this.glContextRestoredHandler);
|
|
5211
5563
|
}
|
|
5564
|
+
/**
|
|
5565
|
+
* One-shot adoption of the window viewport once an initially-detached canvas
|
|
5566
|
+
* gains layout (#817). A full-window scene constructed before its canvas is
|
|
5567
|
+
* attached starts at 0×0, and no window `resize` fires on attachment — so
|
|
5568
|
+
* without this latch the scene would stay unsized forever. The first nonzero
|
|
5569
|
+
* layout box adopts `window.innerWidth/innerHeight` (the same sizing the
|
|
5570
|
+
* window resize handler applies, keeping the full-window contract), then the
|
|
5571
|
+
* observer disconnects: steady-state sizing stays exactly as if the canvas
|
|
5572
|
+
* had been attached before construction. An explicit user `resize()` between
|
|
5573
|
+
* construction and attachment is respected and skips adoption.
|
|
5574
|
+
*
|
|
5575
|
+
* No-op when the scene already has a size (attached at construction) or when
|
|
5576
|
+
* `ResizeObserver` is unavailable (the caller then drives sizing explicitly).
|
|
5577
|
+
*/
|
|
5578
|
+
armAttachmentViewportLatch() {
|
|
5579
|
+
if (this.width > 0 && this.height > 0) return;
|
|
5580
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
5581
|
+
const observer = new ResizeObserver((entries) => {
|
|
5582
|
+
const box = _optionalChain([entries, 'access', _145 => _145[0], 'optionalAccess', _146 => _146.contentRect]);
|
|
5583
|
+
if (!box || !(box.width > 0) || !(box.height > 0)) return;
|
|
5584
|
+
observer.disconnect();
|
|
5585
|
+
this.canvasResizeObserver = null;
|
|
5586
|
+
if (this.width === 0 || this.height === 0) {
|
|
5587
|
+
this.resize(window.innerWidth, window.innerHeight);
|
|
5588
|
+
}
|
|
5589
|
+
});
|
|
5590
|
+
this.canvasResizeObserver = observer;
|
|
5591
|
+
observer.observe(this.canvas);
|
|
5592
|
+
}
|
|
5212
5593
|
// --- domain: scene-facade — renderer accessor ---
|
|
5213
5594
|
/**
|
|
5214
5595
|
* Expose the underlying {@link IRenderer} for advanced direct-draw operations.
|
|
@@ -5231,6 +5612,37 @@ var Scene = (_class15 = class _Scene {
|
|
|
5231
5612
|
findEntityAt(x, y) {
|
|
5232
5613
|
return this._hitTester.findEntityAt(x, y, this.currentFrame, this.width, this.height);
|
|
5233
5614
|
}
|
|
5615
|
+
// --- domain: hit-test — merged HitResult query (RFC5 §2, CTX-0600) ---
|
|
5616
|
+
/**
|
|
5617
|
+
* The merged hit list for a scene-space point: the canvas spatial test
|
|
5618
|
+
* plus caller-observed DOM-native candidates (mirror / portal /
|
|
5619
|
+
* `dom-visual` extension point for CTX-0598) as ONE ordered candidate
|
|
5620
|
+
* list (`HitResult`, overlay order authoritative).
|
|
5621
|
+
*
|
|
5622
|
+
* Query API alongside {@link findEntityAt} — no dispatch change:
|
|
5623
|
+
* `findEntityAt` keeps its single topmost answer byte-for-byte, keyboard
|
|
5624
|
+
* and AT flows are untouched. For browser pointer coordinates use
|
|
5625
|
+
* {@link findHitsAtClient}, which maps through {@link clientToScene} first.
|
|
5626
|
+
*/
|
|
5627
|
+
findHitsAt(x, y, domCandidates = []) {
|
|
5628
|
+
return this._hitTester.findHitsAt(
|
|
5629
|
+
x,
|
|
5630
|
+
y,
|
|
5631
|
+
this.currentFrame,
|
|
5632
|
+
this.width,
|
|
5633
|
+
this.height,
|
|
5634
|
+
domCandidates
|
|
5635
|
+
);
|
|
5636
|
+
}
|
|
5637
|
+
/**
|
|
5638
|
+
* {@link findHitsAt} for browser viewport coordinates: maps through
|
|
5639
|
+
* {@link clientToScene} so coordinates enter in scene space (RFC5 §2
|
|
5640
|
+
* rule 3) and backend attribution follows.
|
|
5641
|
+
*/
|
|
5642
|
+
findHitsAtClient(clientX, clientY, domCandidates = []) {
|
|
5643
|
+
const point = this.clientToScene(clientX, clientY);
|
|
5644
|
+
return this.findHitsAt(point.x, point.y, domCandidates);
|
|
5645
|
+
}
|
|
5234
5646
|
// --- domain: hit-test — client-to-scene mapping ---
|
|
5235
5647
|
/** Convert browser viewport coordinates into this Scene's logical coordinates. */
|
|
5236
5648
|
clientToScene(clientX, clientY) {
|
|
@@ -5271,6 +5683,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
5271
5683
|
this.activePortalsThisFrame.delete(node.id);
|
|
5272
5684
|
this.activePortalsPrevFrame.delete(node.id);
|
|
5273
5685
|
}
|
|
5686
|
+
if (node.domPolicy === "dom" || node.domResident) {
|
|
5687
|
+
for (const backend of this.projectionBackends) backend.unmount(node);
|
|
5688
|
+
this.domSeenThisFrame.delete(node.id);
|
|
5689
|
+
this.domSeenPrevFrame.delete(node.id);
|
|
5690
|
+
this.domSeenNodes.delete(node.id);
|
|
5691
|
+
}
|
|
5692
|
+
this.projectionResolutions.delete(node.id);
|
|
5693
|
+
this.projectionHysteresis.delete(node.id);
|
|
5694
|
+
this.projectionGesturePins.delete(node.id);
|
|
5274
5695
|
const contentEl = this.contentElements.get(node.id);
|
|
5275
5696
|
if (contentEl) {
|
|
5276
5697
|
this._contentProjection.clearGridState(node.id, contentEl);
|
|
@@ -5290,7 +5711,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5290
5711
|
}
|
|
5291
5712
|
if (this.hoveredA11yElements.has(el)) {
|
|
5292
5713
|
this.hoveredA11yElements.delete(el);
|
|
5293
|
-
node.dispatchEvent(new (0,
|
|
5714
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("pointerleave", node, void 0, false));
|
|
5294
5715
|
}
|
|
5295
5716
|
this.preserveFocusOnRemoval(el);
|
|
5296
5717
|
el.remove();
|
|
@@ -5390,12 +5811,16 @@ var Scene = (_class15 = class _Scene {
|
|
|
5390
5811
|
this.canvasResizeObserver = null;
|
|
5391
5812
|
}
|
|
5392
5813
|
if (this.dprMediaQuery && this.dprChangeHandler) {
|
|
5393
|
-
_optionalChain([this, 'access',
|
|
5814
|
+
_optionalChain([this, 'access', _147 => _147.dprMediaQuery, 'access', _148 => _148.removeEventListener, 'optionalCall', _149 => _149("change", this.dprChangeHandler)]);
|
|
5394
5815
|
this.dprMediaQuery = null;
|
|
5395
5816
|
this.dprChangeHandler = null;
|
|
5396
5817
|
}
|
|
5818
|
+
if (this.dprPollInterval !== null) {
|
|
5819
|
+
clearInterval(this.dprPollInterval);
|
|
5820
|
+
this.dprPollInterval = null;
|
|
5821
|
+
}
|
|
5397
5822
|
if (this.forcedColorsQuery && this.forcedColorsChangeHandler) {
|
|
5398
|
-
_optionalChain([this, 'access',
|
|
5823
|
+
_optionalChain([this, 'access', _150 => _150.forcedColorsQuery, 'access', _151 => _151.removeEventListener, 'optionalCall', _152 => _152("change", this.forcedColorsChangeHandler)]);
|
|
5399
5824
|
this.forcedColorsQuery = null;
|
|
5400
5825
|
this.forcedColorsChangeHandler = null;
|
|
5401
5826
|
}
|
|
@@ -5426,9 +5851,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
5426
5851
|
}
|
|
5427
5852
|
this.pointerEventTarget = null;
|
|
5428
5853
|
}
|
|
5429
|
-
_optionalChain([this, 'access',
|
|
5854
|
+
_optionalChain([this, 'access', _153 => _153.a11yRoot, 'optionalAccess', _154 => _154.remove, 'call', _155 => _155()]);
|
|
5430
5855
|
this.focusSentinel = null;
|
|
5431
|
-
_optionalChain([this, 'access',
|
|
5856
|
+
_optionalChain([this, 'access', _156 => _156.portalRoot, 'optionalAccess', _157 => _157.remove, 'call', _158 => _158()]);
|
|
5432
5857
|
this.a11yElements.clear();
|
|
5433
5858
|
for (const el of this.contentElements.values()) el.remove();
|
|
5434
5859
|
this.contentElements.clear();
|
|
@@ -5444,10 +5869,10 @@ var Scene = (_class15 = class _Scene {
|
|
|
5444
5869
|
}
|
|
5445
5870
|
this.glContextLostHandler = null;
|
|
5446
5871
|
this.glContextRestoredHandler = null;
|
|
5447
|
-
_optionalChain([this, 'access',
|
|
5448
|
-
_optionalChain([this, 'access',
|
|
5449
|
-
_optionalChain([this, 'access',
|
|
5450
|
-
_optionalChain([this, 'access',
|
|
5872
|
+
_optionalChain([this, 'access', _159 => _159.pointRenderer, 'optionalAccess', _160 => _160.destroy, 'call', _161 => _161()]);
|
|
5873
|
+
_optionalChain([this, 'access', _162 => _162.renderer, 'access', _163 => _163.dispose, 'optionalCall', _164 => _164()]);
|
|
5874
|
+
_optionalChain([this, 'access', _165 => _165.glCanvas, 'optionalAccess', _166 => _166.remove, 'call', _167 => _167()]);
|
|
5875
|
+
_optionalChain([this, 'access', _168 => _168.gpuCanvas, 'optionalAccess', _169 => _169.remove, 'call', _170 => _170()]);
|
|
5451
5876
|
this.gpuCanvas = null;
|
|
5452
5877
|
this.gpuContext = null;
|
|
5453
5878
|
if (this.recoveryTimerId) {
|
|
@@ -5459,7 +5884,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5459
5884
|
this.manager = null;
|
|
5460
5885
|
}
|
|
5461
5886
|
if (this.device) {
|
|
5462
|
-
_optionalChain([this, 'access',
|
|
5887
|
+
_optionalChain([this, 'access', _171 => _171.device, 'access', _172 => _172.destroy, 'optionalCall', _173 => _173()]);
|
|
5463
5888
|
this.device = null;
|
|
5464
5889
|
}
|
|
5465
5890
|
}
|
|
@@ -5467,6 +5892,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5467
5892
|
setupEvents() {
|
|
5468
5893
|
if (typeof window !== "undefined" && !this.disableWindowResize) {
|
|
5469
5894
|
window.addEventListener("resize", this.resizeHandler);
|
|
5895
|
+
this.armAttachmentViewportLatch();
|
|
5470
5896
|
} else if (this.disableWindowResize && typeof ResizeObserver !== "undefined" && this.canvas && typeof this.canvas.getBoundingClientRect === "function") {
|
|
5471
5897
|
this.canvasResizeObserver = new ResizeObserver((entries) => {
|
|
5472
5898
|
const entry = entries[0];
|
|
@@ -5875,15 +6301,48 @@ var Scene = (_class15 = class _Scene {
|
|
|
5875
6301
|
shouldProjectA11y(node) {
|
|
5876
6302
|
if (!node.interactive) return false;
|
|
5877
6303
|
if (!(node.width > 0 || node.a11yFullViewport)) return false;
|
|
6304
|
+
if (node.domPolicy === "dom" || this.resolveProjectionFor(node) === "dom") return false;
|
|
5878
6305
|
switch (node.a11yProjection) {
|
|
5879
6306
|
case "never":
|
|
5880
6307
|
return false;
|
|
5881
6308
|
case "onDemand":
|
|
5882
|
-
return this.a11yEngaged(node);
|
|
6309
|
+
return this.a11yEngaged(node) && this.resolveSemanticProjection(node);
|
|
5883
6310
|
default:
|
|
5884
|
-
return
|
|
6311
|
+
return this.resolveSemanticProjection(node);
|
|
5885
6312
|
}
|
|
5886
6313
|
}
|
|
6314
|
+
/**
|
|
6315
|
+
* Policy half of {@link shouldProjectA11y} (RFC3 §5, CTX-0599).
|
|
6316
|
+
*
|
|
6317
|
+
* The legacy gates above (interactive, box, `a11yProjection` engagement)
|
|
6318
|
+
* are unchanged; this only maps a {@link SemanticProjectionPolicy} decision
|
|
6319
|
+
* onto project/suppress. Out of the box the default policy returns
|
|
6320
|
+
* `'project'`, so behaviour is identical to having no policy.
|
|
6321
|
+
*
|
|
6322
|
+
* `'defer-to-browser'` always falls back to projection today: no deferral
|
|
6323
|
+
* backend exists (`supportsHTMLInCanvas()` is `false`), so deferring would
|
|
6324
|
+
* silently drop semantics — the exact failure RFC §3 rules out. When a
|
|
6325
|
+
* backend lands, only allow-listed plain display text
|
|
6326
|
+
* ({@link isDeferrableSemanticNode}; never controls) may actually defer. A
|
|
6327
|
+
* throwing policy likewise falls back to projection: a policy must never be
|
|
6328
|
+
* able to drop semantics by accident.
|
|
6329
|
+
*/
|
|
6330
|
+
resolveSemanticProjection(node) {
|
|
6331
|
+
const policy = _nullishCoalesce(this.semanticProjectionPolicy, () => ( DEFAULT_SEMANTIC_PROJECTION_POLICY));
|
|
6332
|
+
let decision;
|
|
6333
|
+
try {
|
|
6334
|
+
decision = policy.choose(node, getSemanticProjectionCapabilities(), {
|
|
6335
|
+
hasDOM: this.a11yRoot !== null
|
|
6336
|
+
});
|
|
6337
|
+
} catch (e18) {
|
|
6338
|
+
decision = "project";
|
|
6339
|
+
}
|
|
6340
|
+
if (decision === "never") return false;
|
|
6341
|
+
if (decision === "defer-to-browser" && isDeferrableSemanticNode(node) && supportsHTMLInCanvas()) {
|
|
6342
|
+
return false;
|
|
6343
|
+
}
|
|
6344
|
+
return true;
|
|
6345
|
+
}
|
|
5887
6346
|
/**
|
|
5888
6347
|
* Whether an `a11yProjection: 'onDemand'` entity is currently engaged enough to
|
|
5889
6348
|
* deserve a shadow node.
|
|
@@ -5911,7 +6370,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5911
6370
|
if (this.mouseX > -9e3 && !this.projectsSelectableText(node)) {
|
|
5912
6371
|
if (node.isPointInside(this.mouseX, this.mouseY)) return true;
|
|
5913
6372
|
}
|
|
5914
|
-
const existing = _optionalChain([this, 'access',
|
|
6373
|
+
const existing = _optionalChain([this, 'access', _174 => _174.a11yElements, 'optionalAccess', _175 => _175.get, 'call', _176 => _176(node.id)]);
|
|
5915
6374
|
if (existing && typeof document !== "undefined" && document.activeElement === existing) {
|
|
5916
6375
|
return true;
|
|
5917
6376
|
}
|
|
@@ -5925,8 +6384,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
5925
6384
|
* selection.
|
|
5926
6385
|
*/
|
|
5927
6386
|
projectsSelectableText(node) {
|
|
5928
|
-
const projection = _optionalChain([node, 'access',
|
|
5929
|
-
return !!_optionalChain([projection, 'optionalAccess',
|
|
6387
|
+
const projection = _optionalChain([node, 'access', _177 => _177.getContentProjection, 'optionalCall', _178 => _178()]);
|
|
6388
|
+
return !!_optionalChain([projection, 'optionalAccess', _179 => _179.text]) && projection.selectable !== false;
|
|
5930
6389
|
}
|
|
5931
6390
|
/**
|
|
5932
6391
|
* Keep `entity`'s a11y shadow node projected while it has
|
|
@@ -6021,20 +6480,20 @@ var Scene = (_class15 = class _Scene {
|
|
|
6021
6480
|
el.style.background = "transparent";
|
|
6022
6481
|
}
|
|
6023
6482
|
el.addEventListener("click", (e) => {
|
|
6024
|
-
node.dispatchEvent(new (0,
|
|
6483
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("click", node, e));
|
|
6025
6484
|
});
|
|
6026
6485
|
el.addEventListener("dblclick", (e) => {
|
|
6027
|
-
node.dispatchEvent(new (0,
|
|
6486
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("dblclick", node, e));
|
|
6028
6487
|
});
|
|
6029
6488
|
el.addEventListener("mouseenter", (e) => {
|
|
6030
6489
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
|
|
6031
6490
|
this.hoveredA11yElements.add(el);
|
|
6032
|
-
node.dispatchEvent(new (0,
|
|
6491
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("hover", node, e, false));
|
|
6033
6492
|
});
|
|
6034
6493
|
el.addEventListener("mouseleave", (e) => {
|
|
6035
6494
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
|
|
6036
6495
|
this.hoveredA11yElements.delete(el);
|
|
6037
|
-
node.dispatchEvent(new (0,
|
|
6496
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("pointerleave", node, e, false));
|
|
6038
6497
|
});
|
|
6039
6498
|
const capEl = el;
|
|
6040
6499
|
const releasePointer = (event) => {
|
|
@@ -6052,24 +6511,27 @@ var Scene = (_class15 = class _Scene {
|
|
|
6052
6511
|
if (e.target === capEl && typeof capEl.setPointerCapture === "function") {
|
|
6053
6512
|
capEl.setPointerCapture(e.pointerId);
|
|
6054
6513
|
}
|
|
6055
|
-
|
|
6514
|
+
this.pinProjectionForGesture(node);
|
|
6515
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("pointerdown", node, e));
|
|
6056
6516
|
});
|
|
6057
6517
|
el.addEventListener("pointerup", (e) => {
|
|
6058
6518
|
releasePointer(e);
|
|
6059
|
-
|
|
6519
|
+
this.unpinProjectionForGesture(node);
|
|
6520
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("pointerup", node, e));
|
|
6060
6521
|
});
|
|
6061
6522
|
el.addEventListener("pointercancel", (e) => {
|
|
6062
6523
|
releasePointer(e);
|
|
6063
|
-
|
|
6524
|
+
this.unpinProjectionForGesture(node);
|
|
6525
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("pointercancel", node, e));
|
|
6064
6526
|
});
|
|
6065
6527
|
el.addEventListener(
|
|
6066
6528
|
"pointermove",
|
|
6067
|
-
(e) => node.dispatchEvent(new (0,
|
|
6529
|
+
(e) => node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("pointermove", node, e))
|
|
6068
6530
|
);
|
|
6069
6531
|
el.addEventListener(
|
|
6070
6532
|
"wheel",
|
|
6071
6533
|
(e) => {
|
|
6072
|
-
node.dispatchEvent(new (0,
|
|
6534
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("wheel", node, e));
|
|
6073
6535
|
},
|
|
6074
6536
|
{ passive: false }
|
|
6075
6537
|
);
|
|
@@ -6094,10 +6556,10 @@ var Scene = (_class15 = class _Scene {
|
|
|
6094
6556
|
);
|
|
6095
6557
|
emitInitialScroll = emitScroll;
|
|
6096
6558
|
el.addEventListener("keydown", (e) => {
|
|
6097
|
-
node.dispatchEvent(new (0,
|
|
6559
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("keydown", node, e));
|
|
6098
6560
|
});
|
|
6099
6561
|
el.addEventListener("keyup", (e) => {
|
|
6100
|
-
node.dispatchEvent(new (0,
|
|
6562
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("keyup", node, e));
|
|
6101
6563
|
});
|
|
6102
6564
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
6103
6565
|
const input = el;
|
|
@@ -6128,7 +6590,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6128
6590
|
el.addEventListener("compositionupdate", (e) => {
|
|
6129
6591
|
const data = _nullishCoalesce(e.data, () => ( ""));
|
|
6130
6592
|
composition = {
|
|
6131
|
-
start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess',
|
|
6593
|
+
start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _180 => _180.start]), () => ( 0)),
|
|
6132
6594
|
length: data.length
|
|
6133
6595
|
};
|
|
6134
6596
|
forward();
|
|
@@ -6182,14 +6644,14 @@ var Scene = (_class15 = class _Scene {
|
|
|
6182
6644
|
el.addEventListener("keydown", (e) => {
|
|
6183
6645
|
if (e.key === "Enter") {
|
|
6184
6646
|
e.preventDefault();
|
|
6185
|
-
node.dispatchEvent(new (0,
|
|
6647
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("click", node, e));
|
|
6186
6648
|
} else if (e.key === " ") {
|
|
6187
6649
|
e.preventDefault();
|
|
6188
6650
|
}
|
|
6189
6651
|
});
|
|
6190
6652
|
el.addEventListener("keyup", (e) => {
|
|
6191
6653
|
if (e.key === " ") {
|
|
6192
|
-
node.dispatchEvent(new (0,
|
|
6654
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("click", node, e));
|
|
6193
6655
|
}
|
|
6194
6656
|
});
|
|
6195
6657
|
this.keyboardActivatedA11y.add(el);
|
|
@@ -6210,7 +6672,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6210
6672
|
this.syncOptionalAttribute(
|
|
6211
6673
|
el,
|
|
6212
6674
|
"href",
|
|
6213
|
-
attrs.href === void 0 ? void 0 :
|
|
6675
|
+
attrs.href === void 0 ? void 0 : _chunkBKXERWADjs.sanitizeUrl.call(void 0, attrs.href)
|
|
6214
6676
|
);
|
|
6215
6677
|
this.syncOptionalAttribute(el, "target", attrs.target);
|
|
6216
6678
|
}
|
|
@@ -6379,7 +6841,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6379
6841
|
const display = visible ? "" : "none";
|
|
6380
6842
|
if (el.style.display !== display) el.style.display = display;
|
|
6381
6843
|
}
|
|
6382
|
-
_optionalChain([emitInitialScroll, 'optionalCall',
|
|
6844
|
+
_optionalChain([emitInitialScroll, 'optionalCall', _181 => _181()]);
|
|
6383
6845
|
}
|
|
6384
6846
|
if (this.phases.enabled) {
|
|
6385
6847
|
const projectionStart = performance.now();
|
|
@@ -6609,7 +7071,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6609
7071
|
el.addEventListener(
|
|
6610
7072
|
"wheel",
|
|
6611
7073
|
(e2) => {
|
|
6612
|
-
node.dispatchEvent(new (0,
|
|
7074
|
+
node.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)("wheel", node, e2));
|
|
6613
7075
|
},
|
|
6614
7076
|
{ passive: false }
|
|
6615
7077
|
);
|
|
@@ -6840,8 +7302,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
6840
7302
|
next.f = f2;
|
|
6841
7303
|
next.tier = tier;
|
|
6842
7304
|
next.hasBand = lineBand !== null;
|
|
6843
|
-
next.bandMin = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess',
|
|
6844
|
-
next.bandMax = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess',
|
|
7305
|
+
next.bandMin = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess', _182 => _182.minY]), () => ( 0));
|
|
7306
|
+
next.bandMax = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess', _183 => _183.maxY]), () => ( 0));
|
|
6845
7307
|
next.visible = visible;
|
|
6846
7308
|
next.width = node.width;
|
|
6847
7309
|
next.height = node.height;
|
|
@@ -7020,6 +7482,197 @@ var Scene = (_class15 = class _Scene {
|
|
|
7020
7482
|
this.activePortalsPrevFrame = new Set(this.activePortalsThisFrame);
|
|
7021
7483
|
this.activePortalsThisFrame.clear();
|
|
7022
7484
|
}
|
|
7485
|
+
/**
|
|
7486
|
+
* Register a generic projection backend (RFC1 §5, RFC2 P1 CTX-0598).
|
|
7487
|
+
* Registration is idempotent per backend instance. Core drives
|
|
7488
|
+
* mount/update/unmount from the render walk; the backend owns all
|
|
7489
|
+
* medium-specific state.
|
|
7490
|
+
*/
|
|
7491
|
+
addProjectionBackend(backend) {
|
|
7492
|
+
if (!this.projectionBackends.includes(backend)) this.projectionBackends.push(backend);
|
|
7493
|
+
return this;
|
|
7494
|
+
}
|
|
7495
|
+
/**
|
|
7496
|
+
* Remove a previously registered projection backend by instance or
|
|
7497
|
+
* {@link ProjectionBackendKind | kind}. Removing does not unmount resident
|
|
7498
|
+
* nodes — unmount the backend first if teardown order matters.
|
|
7499
|
+
*/
|
|
7500
|
+
removeProjectionBackend(backend) {
|
|
7501
|
+
this.projectionBackends = this.projectionBackends.filter(
|
|
7502
|
+
(b) => typeof backend === "string" ? b.kind !== backend : b !== backend
|
|
7503
|
+
);
|
|
7504
|
+
return this;
|
|
7505
|
+
}
|
|
7506
|
+
/**
|
|
7507
|
+
* Scene-level projection capabilities (RFC4 §3 rule 2, CTX-0601).
|
|
7508
|
+
*
|
|
7509
|
+
* Plain-data feature detection in the shape of the proposed
|
|
7510
|
+
* `scene.inputCapabilities` (input-dispatch-contract-v2 §4): apps and
|
|
7511
|
+
* devtools query where a node _would_ materialize and why, without touching
|
|
7512
|
+
* any backend. Additive only — no existing surface moves.
|
|
7513
|
+
*/
|
|
7514
|
+
get projectionCapabilities() {
|
|
7515
|
+
return {
|
|
7516
|
+
hasDOM: typeof document !== "undefined",
|
|
7517
|
+
domBackendMounted: this.projectionBackends.some((b) => b.kind === "dom"),
|
|
7518
|
+
backends: this.projectionBackends.map((b) => b.kind),
|
|
7519
|
+
autoHysteresisFrames: this.projectionHysteresisFrames,
|
|
7520
|
+
autoDomBudget: this.projectionAutoDomBudget
|
|
7521
|
+
};
|
|
7522
|
+
}
|
|
7523
|
+
/**
|
|
7524
|
+
* Register (or replace) the Capability Matrix row for one `domKind`
|
|
7525
|
+
* (RFC4 §4, CTX-0601). Custom kinds start at the unknown-kind default
|
|
7526
|
+
* (`unsupported-kind` → canvas); registering a row is how a custom backend
|
|
7527
|
+
* kind opts into `'auto'` resolution and how tests drive oscillating costs.
|
|
7528
|
+
*/
|
|
7529
|
+
registerProjectionCapability(domKind, row) {
|
|
7530
|
+
this.projectionCapabilityOverrides.set(domKind, row);
|
|
7531
|
+
return this;
|
|
7532
|
+
}
|
|
7533
|
+
/** Matrix row for a node's `domKind` (override wins, unknown → canvas). */
|
|
7534
|
+
getProjectionCapability(node) {
|
|
7535
|
+
return _nullishCoalesce(_nullishCoalesce(this.projectionCapabilityOverrides.get(node.domKind), () => ( DEFAULT_PROJECTION_CAPABILITIES[node.domKind])), () => ( UNKNOWN_PROJECTION_CAPABILITY));
|
|
7536
|
+
}
|
|
7537
|
+
/**
|
|
7538
|
+
* Pin a node's backend for the duration of an active gesture (RFC4 §5 +
|
|
7539
|
+
* input-dispatch-contract-v2 §4 gesture stickiness: no mid-gesture handoff).
|
|
7540
|
+
* The a11y-mirror pointerdown/up/cancel listeners maintain this; DOM-side
|
|
7541
|
+
* gestures are consulted through
|
|
7542
|
+
* {@link ProjectionBackend.hasActiveGesture | backend.hasActiveGesture}.
|
|
7543
|
+
* Refcounted so multi-pointer gestures on one node unpin exactly once.
|
|
7544
|
+
*/
|
|
7545
|
+
pinProjectionForGesture(node) {
|
|
7546
|
+
this.projectionGesturePins.set(node.id, (_nullishCoalesce(this.projectionGesturePins.get(node.id), () => ( 0))) + 1);
|
|
7547
|
+
}
|
|
7548
|
+
/** Release one gesture pin taken by {@link pinProjectionForGesture}. */
|
|
7549
|
+
unpinProjectionForGesture(node) {
|
|
7550
|
+
const count = (_nullishCoalesce(this.projectionGesturePins.get(node.id), () => ( 0))) - 1;
|
|
7551
|
+
if (count <= 0) this.projectionGesturePins.delete(node.id);
|
|
7552
|
+
else this.projectionGesturePins.set(node.id, count);
|
|
7553
|
+
}
|
|
7554
|
+
/** Whether `node` currently owns an active gesture on a core mirror. */
|
|
7555
|
+
isProjectionPinned(node) {
|
|
7556
|
+
return (_nullishCoalesce(this.projectionGesturePins.get(node.id), () => ( 0))) > 0;
|
|
7557
|
+
}
|
|
7558
|
+
/**
|
|
7559
|
+
* Last negotiation for one node, if it was ever resolved on this scene.
|
|
7560
|
+
* Accepts the node or its id; returns the stored record (not a copy — treat
|
|
7561
|
+
* as read-only).
|
|
7562
|
+
*/
|
|
7563
|
+
getProjectionResolution(node) {
|
|
7564
|
+
return this.projectionResolutions.get(typeof node === "string" ? node : node.id);
|
|
7565
|
+
}
|
|
7566
|
+
/** Every node's last negotiation, in first-resolution order. */
|
|
7567
|
+
getProjectionResolutions() {
|
|
7568
|
+
return [...this.projectionResolutions.values()];
|
|
7569
|
+
}
|
|
7570
|
+
/**
|
|
7571
|
+
* Resolve one node's `domPolicy` to its effective backend (RFC4 §3, CTX-0601).
|
|
7572
|
+
*
|
|
7573
|
+
* Memoized per main frame (`currentFrame`, bumped once per authoritative
|
|
7574
|
+
* render): the render walk and the later a11y sync must agree within a
|
|
7575
|
+
* frame, or a node could lose its mirror the same frame it gains an element.
|
|
7576
|
+
* `'auto'` applies, in order: no-DOM short-circuit → pure negotiation →
|
|
7577
|
+
* gesture/focus hard bars (a pinned node keeps its current backend, never
|
|
7578
|
+
* flips mid-gesture, focus is preserved-or-moved never dropped to `body` per
|
|
7579
|
+
* input-dispatch-contract-v2 §4) → hysteresis stickiness → bulk budget.
|
|
7580
|
+
* Every outcome is recorded on the per-scene queryable surface
|
|
7581
|
+
* ({@link getProjectionResolutions}) with its reason — fallbacks are
|
|
7582
|
+
* reported, not silent (§3 rule 2).
|
|
7583
|
+
*/
|
|
7584
|
+
resolveProjectionFor(node) {
|
|
7585
|
+
const want = node.domPolicy;
|
|
7586
|
+
if (this.projectionBackends.length === 0 && want === "canvas") return "canvas";
|
|
7587
|
+
const memo = this.projectionHysteresis.get(node.id);
|
|
7588
|
+
if (memo && memo.lastFrame === this.currentFrame) return memo.resolved;
|
|
7589
|
+
const hasDOM = typeof document !== "undefined";
|
|
7590
|
+
const domBackendMounted = this.projectionBackends.some((b) => b.kind === "dom");
|
|
7591
|
+
const outcome = resolveProjection(want, this.getProjectionCapability(node), {
|
|
7592
|
+
hasDOM,
|
|
7593
|
+
domBackendMounted
|
|
7594
|
+
});
|
|
7595
|
+
let resolved = outcome.resolved;
|
|
7596
|
+
let reason = outcome.reason;
|
|
7597
|
+
if (want === "auto" && memo !== void 0) {
|
|
7598
|
+
if (resolved !== memo.resolved) {
|
|
7599
|
+
const gesturePinned = this.isProjectionPinned(node) || this.projectionBackends.some((b) => _optionalChain([b, 'access', _184 => _184.hasActiveGesture, 'optionalCall', _185 => _185(node)]) === true);
|
|
7600
|
+
if (gesturePinned) {
|
|
7601
|
+
resolved = memo.resolved;
|
|
7602
|
+
reason = "active-gesture";
|
|
7603
|
+
} else if (this.ownsProjectionFocus(node)) {
|
|
7604
|
+
resolved = memo.resolved;
|
|
7605
|
+
reason = "focus-pinned";
|
|
7606
|
+
} else {
|
|
7607
|
+
const vote = hysteresisVote(
|
|
7608
|
+
memo.resolved,
|
|
7609
|
+
resolved,
|
|
7610
|
+
memo.consecutive,
|
|
7611
|
+
this.projectionHysteresisFrames
|
|
7612
|
+
);
|
|
7613
|
+
resolved = vote.resolved;
|
|
7614
|
+
memo.consecutive = vote.consecutive;
|
|
7615
|
+
reason = vote.flipped ? reason : "hysteresis";
|
|
7616
|
+
}
|
|
7617
|
+
} else {
|
|
7618
|
+
memo.consecutive = 0;
|
|
7619
|
+
}
|
|
7620
|
+
}
|
|
7621
|
+
if (want === "auto" && resolved === "dom") {
|
|
7622
|
+
if (this.projectionBudgetFrame !== this.currentFrame) {
|
|
7623
|
+
this.projectionBudgetFrame = this.currentFrame;
|
|
7624
|
+
this.projectionDomAutoCount = 0;
|
|
7625
|
+
}
|
|
7626
|
+
this.projectionDomAutoCount += 1;
|
|
7627
|
+
if (this.projectionDomAutoCount > this.projectionAutoDomBudget) {
|
|
7628
|
+
resolved = "canvas";
|
|
7629
|
+
reason = "bulk-budget";
|
|
7630
|
+
}
|
|
7631
|
+
}
|
|
7632
|
+
this.projectionHysteresis.set(node.id, {
|
|
7633
|
+
resolved,
|
|
7634
|
+
consecutive: _nullishCoalesce(_optionalChain([memo, 'optionalAccess', _186 => _186.consecutive]), () => ( 0)),
|
|
7635
|
+
lastFrame: this.currentFrame
|
|
7636
|
+
});
|
|
7637
|
+
const prev = this.projectionResolutions.get(node.id);
|
|
7638
|
+
if (!prev || prev.want !== want || prev.resolved !== resolved || prev.reason !== reason) {
|
|
7639
|
+
this.projectionResolutions.set(node.id, { nodeId: node.id, want, resolved, reason });
|
|
7640
|
+
}
|
|
7641
|
+
return resolved;
|
|
7642
|
+
}
|
|
7643
|
+
/**
|
|
7644
|
+
* Whether `node`'s a11y mirror currently owns browser focus (RFC4 §5 focus
|
|
7645
|
+
* rule, input-dispatch-contract-v2 §4: focus stays DOM-based; flipping
|
|
7646
|
+
* `projection` must preserve or deliberately move focus, never drop it to
|
|
7647
|
+
* `body`). A focused node keeps its backend until blur — the actual move, if
|
|
7648
|
+
* any, goes through the existing sentinels (`preserveFocusOnRemoval`, the
|
|
7649
|
+
* DOM backend's own fallback), never a bare removal.
|
|
7650
|
+
*/
|
|
7651
|
+
ownsProjectionFocus(node) {
|
|
7652
|
+
if (typeof document === "undefined") return false;
|
|
7653
|
+
const mirror = this.a11yElements.get(node.id);
|
|
7654
|
+
if (!mirror || mirror !== this.focusedA11yElement) return false;
|
|
7655
|
+
return document.activeElement === mirror;
|
|
7656
|
+
}
|
|
7657
|
+
/**
|
|
7658
|
+
* RFC2 P1 (CTX-0598): unmount DOM-projection residents the walk did not see
|
|
7659
|
+
* this frame (viewport-culled, removed without `remove()`, policy-flipped).
|
|
7660
|
+
* Mirrors {@link reconcilePortals} above; unmount is idempotent per the
|
|
7661
|
+
* `ProjectionBackend` contract so notifying every backend is safe.
|
|
7662
|
+
*/
|
|
7663
|
+
pruneProjectionBackends() {
|
|
7664
|
+
for (const id of this.domSeenPrevFrame) {
|
|
7665
|
+
if (!this.domSeenThisFrame.has(id)) {
|
|
7666
|
+
const node = this.domSeenNodes.get(id);
|
|
7667
|
+
if (node) {
|
|
7668
|
+
for (const backend of this.projectionBackends) backend.unmount(node);
|
|
7669
|
+
this.domSeenNodes.delete(id);
|
|
7670
|
+
}
|
|
7671
|
+
}
|
|
7672
|
+
}
|
|
7673
|
+
this.domSeenPrevFrame = new Set(this.domSeenThisFrame);
|
|
7674
|
+
this.domSeenThisFrame.clear();
|
|
7675
|
+
}
|
|
7023
7676
|
// --- domain: render-scheduler — the loop and the render walk ---
|
|
7024
7677
|
/**
|
|
7025
7678
|
* The frame-rate cap actually in effect: the explicit {@link maxFPS}, further
|
|
@@ -7027,7 +7680,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7027
7680
|
* (and {@link respectReducedMotion} is on). `0` means uncapped.
|
|
7028
7681
|
*/
|
|
7029
7682
|
effectiveMaxFPS() {
|
|
7030
|
-
const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access',
|
|
7683
|
+
const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _187 => _187.reducedMotionQuery, 'optionalAccess', _188 => _188.matches]);
|
|
7031
7684
|
if (reduced)
|
|
7032
7685
|
return this.maxFPS > 0 ? Math.min(this.maxFPS, REDUCED_MOTION_FPS) : REDUCED_MOTION_FPS;
|
|
7033
7686
|
return this.maxFPS;
|
|
@@ -7097,6 +7750,12 @@ var Scene = (_class15 = class _Scene {
|
|
|
7097
7750
|
/**
|
|
7098
7751
|
* Render the entire scene graph onto the specified renderer.
|
|
7099
7752
|
*
|
|
7753
|
+
* This is the `CanvasProjection` row of {@link ProjectionBackend}:
|
|
7754
|
+
* the per-frame materialization of scene semantics into pixels through the
|
|
7755
|
+
* backend-agnostic `IRenderer` contract. (The `A11yProjection` /
|
|
7756
|
+
* `ContentProjection` rows run on the same cadence via {@link Scene.syncA11y}
|
|
7757
|
+
* below; the `DOMProjection` row does not exist yet — RFC2/CTX-0598.)
|
|
7758
|
+
*
|
|
7100
7759
|
* Main-frame causal order is a correctness contract:
|
|
7101
7760
|
*
|
|
7102
7761
|
* 1. Browser/input callbacks finish before the scheduled frame begins.
|
|
@@ -7122,7 +7781,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7122
7781
|
* @param time - Current absolute time in milliseconds (default 0).
|
|
7123
7782
|
*/
|
|
7124
7783
|
render(renderer, dt = 0, time = 0) {
|
|
7125
|
-
if (_optionalChain([renderer, 'access',
|
|
7784
|
+
if (_optionalChain([renderer, 'access', _189 => _189.isContextLost, 'optionalCall', _190 => _190()])) return;
|
|
7126
7785
|
const isMainRenderer = renderer === this.renderer;
|
|
7127
7786
|
if (isMainRenderer && this.a11yRoot && this.canvas.parentElement) {
|
|
7128
7787
|
const parentStyle = this.canvas.parentElement.style;
|
|
@@ -7272,14 +7931,14 @@ var Scene = (_class15 = class _Scene {
|
|
|
7272
7931
|
}
|
|
7273
7932
|
renderer.clear();
|
|
7274
7933
|
if (isMainRenderer) {
|
|
7275
|
-
_optionalChain([this, 'access',
|
|
7934
|
+
_optionalChain([this, 'access', _191 => _191.pointRenderer, 'optionalAccess', _192 => _192.begin, 'call', _193 => _193()]);
|
|
7276
7935
|
}
|
|
7277
7936
|
const vw = this.width;
|
|
7278
7937
|
const vh = this.height;
|
|
7279
7938
|
let walkHadAnimation = false;
|
|
7280
7939
|
let walkHadInteractive = false;
|
|
7281
7940
|
const runUpdate = (node) => {
|
|
7282
|
-
const overridesUpdate = node.update !==
|
|
7941
|
+
const overridesUpdate = node.update !== _chunkHC5EZOZJjs.Entity.prototype.update;
|
|
7283
7942
|
let pending = node.hasPendingAnimations();
|
|
7284
7943
|
if (pending || overridesUpdate) {
|
|
7285
7944
|
node.update(dt, time);
|
|
@@ -7288,7 +7947,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7288
7947
|
if (pending) walkHadAnimation = true;
|
|
7289
7948
|
if (!walkHadInteractive && node.interactive) walkHadInteractive = true;
|
|
7290
7949
|
if (this._devActive && this._devFrameCount % 120 === 0) {
|
|
7291
|
-
if (overridesUpdate && node.hasPendingAnimations ===
|
|
7950
|
+
if (overridesUpdate && node.hasPendingAnimations === _chunkHC5EZOZJjs.Entity.prototype.hasPendingAnimations) {
|
|
7292
7951
|
this._devWarn(
|
|
7293
7952
|
`Entity "${node.id}" overrides update() but not hasPendingAnimations(). Custom motion in update() without overriding hasPendingAnimations() causes the idle throttle to slow the animation. Override hasPendingAnimations() to return true while motion is in flight.`
|
|
7294
7953
|
);
|
|
@@ -7389,6 +8048,16 @@ var Scene = (_class15 = class _Scene {
|
|
|
7389
8048
|
visible = maxX >= 0 && minX <= vw && maxY >= 0 && minY <= vh;
|
|
7390
8049
|
}
|
|
7391
8050
|
if (!visible && node.children.length === 0) return;
|
|
8051
|
+
if (isMainRenderer && this.projectionBackends.length > 0 && this.resolveProjectionFor(node) === "dom" && visible) {
|
|
8052
|
+
for (const backend of this.projectionBackends) {
|
|
8053
|
+
backend.update(node, { a, b, c, d, e: te, f: tf });
|
|
8054
|
+
}
|
|
8055
|
+
if (node.domResident) {
|
|
8056
|
+
this.domSeenThisFrame.add(node.id);
|
|
8057
|
+
this.domSeenNodes.set(node.id, node);
|
|
8058
|
+
if (node.children.length === 0) return;
|
|
8059
|
+
}
|
|
8060
|
+
}
|
|
7392
8061
|
if (node.children.length === 0 && node.scaleX === node.scaleY) {
|
|
7393
8062
|
const bc = node.getBatchCircle();
|
|
7394
8063
|
if (bc) {
|
|
@@ -7518,14 +8187,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
7518
8187
|
this.frameHadAnimation = walkHadAnimation;
|
|
7519
8188
|
this.frameHadInteractive = walkHadInteractive;
|
|
7520
8189
|
this.reconcilePortals();
|
|
8190
|
+
this.pruneProjectionBackends();
|
|
7521
8191
|
}
|
|
7522
8192
|
const flushTiming = this.phases.userTiming ? beginVectoUserTiming(VECTO_USER_TIMING.scene.flush) : null;
|
|
7523
8193
|
const flushT0 = this.phases.enabled ? performance.now() : 0;
|
|
7524
8194
|
renderer.flush();
|
|
7525
8195
|
if (isMainRenderer) {
|
|
7526
|
-
_optionalChain([this, 'access',
|
|
8196
|
+
_optionalChain([this, 'access', _194 => _194.pointRenderer, 'optionalAccess', _195 => _195.flush, 'call', _196 => _196()]);
|
|
7527
8197
|
}
|
|
7528
|
-
_optionalChain([renderer, 'access',
|
|
8198
|
+
_optionalChain([renderer, 'access', _197 => _197.present, 'optionalCall', _198 => _198()]);
|
|
7529
8199
|
if (this.phases.enabled) this.phases.record("flush", performance.now() - flushT0);
|
|
7530
8200
|
if (flushTiming) endVectoUserTiming(flushTiming);
|
|
7531
8201
|
if (this._devActive) {
|
|
@@ -7538,7 +8208,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7538
8208
|
* Export the current scene state to a lightweight, flat SVG XML string.
|
|
7539
8209
|
*/
|
|
7540
8210
|
toSVG() {
|
|
7541
|
-
const renderer = new (0,
|
|
8211
|
+
const renderer = new (0, _chunkBKXERWADjs.SVGRenderer)(this.width, this.height);
|
|
7542
8212
|
this.render(renderer, 0, 0);
|
|
7543
8213
|
return renderer.toXMLString();
|
|
7544
8214
|
}
|
|
@@ -7616,7 +8286,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7616
8286
|
});
|
|
7617
8287
|
pass.end();
|
|
7618
8288
|
this.device.queue.submit([encoder.finish()]);
|
|
7619
|
-
} catch (
|
|
8289
|
+
} catch (e19) {
|
|
7620
8290
|
}
|
|
7621
8291
|
this.gpuHasContent = false;
|
|
7622
8292
|
}
|
|
@@ -7751,20 +8421,20 @@ function defaultMeasurer() {
|
|
|
7751
8421
|
sharedMeasurer ??= _layout.resolveGlyphMeasurer.call(void 0, "sans-serif");
|
|
7752
8422
|
return sharedMeasurer;
|
|
7753
8423
|
}
|
|
7754
|
-
var TextEntity = (_class16 = class extends
|
|
8424
|
+
var TextEntity = (_class16 = class extends _chunkHC5EZOZJjs.Entity {
|
|
7755
8425
|
|
|
7756
8426
|
|
|
7757
8427
|
|
|
7758
8428
|
|
|
7759
|
-
|
|
8429
|
+
__init204() {this.nodes = []}
|
|
7760
8430
|
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
8431
|
+
__init205() {this.fillStyle = "#94a3b8"}
|
|
8432
|
+
__init206() {this.strokeStyle = null}
|
|
8433
|
+
__init207() {this.hoveredFillStyle = "#ffffff"}
|
|
8434
|
+
__init208() {this.lineWidth = 1}
|
|
8435
|
+
__init209() {this.isHovered = false}
|
|
7766
8436
|
/** Bumped by {@link applyLayout}; read by `Scene` to skip an unchanged sync. */
|
|
7767
|
-
|
|
8437
|
+
__init210() {this.contentEpoch = 0}
|
|
7768
8438
|
/**
|
|
7769
8439
|
* Visual lines with real canvas geometry, rebuilt by {@link applyLayout}
|
|
7770
8440
|
* exactly when `this.nodes` changes.
|
|
@@ -7776,9 +8446,9 @@ var TextEntity = (_class16 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
7776
8446
|
* ~0.35 em per line for a 24 px font, Firefox). Per-line carriers pin the DOM
|
|
7777
8447
|
* baseline to the canvas baseline by construction, same as `ui/Text`.
|
|
7778
8448
|
*/
|
|
7779
|
-
|
|
8449
|
+
__init211() {this.projectionLines = []}
|
|
7780
8450
|
constructor(text, atlas, maxWidth, fontSize = 24) {
|
|
7781
|
-
super();_class16.prototype.
|
|
8451
|
+
super();_class16.prototype.__init204.call(this);_class16.prototype.__init205.call(this);_class16.prototype.__init206.call(this);_class16.prototype.__init207.call(this);_class16.prototype.__init208.call(this);_class16.prototype.__init209.call(this);_class16.prototype.__init210.call(this);_class16.prototype.__init211.call(this);;
|
|
7782
8452
|
this.text = text;
|
|
7783
8453
|
this.atlas = atlas;
|
|
7784
8454
|
this.fontSize = fontSize;
|
|
@@ -7954,18 +8624,250 @@ var TextEntity = (_class16 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
7954
8624
|
}
|
|
7955
8625
|
}, _class16);
|
|
7956
8626
|
|
|
8627
|
+
// src/components/VirtualizedSetAggregate.ts
|
|
8628
|
+
var VirtualizedSetAggregate = (_class17 = class extends _chunkHC5EZOZJjs.Entity {
|
|
8629
|
+
|
|
8630
|
+
|
|
8631
|
+
|
|
8632
|
+
|
|
8633
|
+
|
|
8634
|
+
|
|
8635
|
+
|
|
8636
|
+
/** First item index currently bound to the pool (the scroll window). */
|
|
8637
|
+
__init212() {this._visibleStart = 0}
|
|
8638
|
+
/** Item id owning the roving tab stop / keyboard focus. */
|
|
8639
|
+
__init213() {this._activeId = null}
|
|
8640
|
+
__init214() {this._selectedId = null}
|
|
8641
|
+
/** One focusable hotspot per visible slot; re-bound, never rebuilt per item. */
|
|
8642
|
+
__init215() {this._hotspots = []}
|
|
8643
|
+
constructor(opts = {}) {
|
|
8644
|
+
super();_class17.prototype.__init212.call(this);_class17.prototype.__init213.call(this);_class17.prototype.__init214.call(this);_class17.prototype.__init215.call(this);;
|
|
8645
|
+
this._items = _nullishCoalesce(opts.items, () => ( []));
|
|
8646
|
+
this._label = _nullishCoalesce(opts.label, () => ( "Items"));
|
|
8647
|
+
this._role = _nullishCoalesce(opts.role, () => ( "list"));
|
|
8648
|
+
this._itemRole = _nullishCoalesce(opts.itemRole, () => ( "listitem"));
|
|
8649
|
+
this._rowHeight = _nullishCoalesce(opts.rowHeight, () => ( 28));
|
|
8650
|
+
this._visibleCapacity = opts.visibleCapacity;
|
|
8651
|
+
this._onActivate = opts.onActivate;
|
|
8652
|
+
this.width = _nullishCoalesce(opts.width, () => ( 0));
|
|
8653
|
+
this.height = _nullishCoalesce(opts.height, () => ( 0));
|
|
8654
|
+
this.interactive = true;
|
|
8655
|
+
this._syncHotspots();
|
|
8656
|
+
}
|
|
8657
|
+
/** Full item count — the number the container label states. */
|
|
8658
|
+
get itemCount() {
|
|
8659
|
+
return this._items.length;
|
|
8660
|
+
}
|
|
8661
|
+
/** Live pool size (bounded by the visible capacity, never by the item count). */
|
|
8662
|
+
get poolSize() {
|
|
8663
|
+
return this._hotspots.length;
|
|
8664
|
+
}
|
|
8665
|
+
/** First item index currently bound to the pool. */
|
|
8666
|
+
get visibleStart() {
|
|
8667
|
+
return this._visibleStart;
|
|
8668
|
+
}
|
|
8669
|
+
getA11yAttributes() {
|
|
8670
|
+
return {
|
|
8671
|
+
role: this._role,
|
|
8672
|
+
label: `${this._label}, ${this._items.length} items`,
|
|
8673
|
+
pointerEvents: "none"
|
|
8674
|
+
};
|
|
8675
|
+
}
|
|
8676
|
+
render(_renderer) {
|
|
8677
|
+
}
|
|
8678
|
+
/** Axis-aligned hit-test against the container box (the `UIComponent` default). */
|
|
8679
|
+
isPointInside(globalX, globalY) {
|
|
8680
|
+
const local = this.worldToLocal(globalX, globalY);
|
|
8681
|
+
if (!local) return false;
|
|
8682
|
+
return local.x >= 0 && local.x <= this.width && local.y >= 0 && local.y <= this.height;
|
|
8683
|
+
}
|
|
8684
|
+
/** Replace the item set; the pool re-binds and the label count follows. */
|
|
8685
|
+
setItems(items) {
|
|
8686
|
+
this._items = items;
|
|
8687
|
+
if (this._activeId !== null && !items.some((item) => item.id === this._activeId)) {
|
|
8688
|
+
this._activeId = null;
|
|
8689
|
+
}
|
|
8690
|
+
if (this._selectedId !== null && !items.some((item) => item.id === this._selectedId)) {
|
|
8691
|
+
this._selectedId = null;
|
|
8692
|
+
}
|
|
8693
|
+
this._visibleStart = Math.max(0, Math.min(this._visibleStart, Math.max(0, items.length - 1)));
|
|
8694
|
+
this._syncHotspots();
|
|
8695
|
+
_optionalChain([this, 'access', _199 => _199.scene, 'optionalAccess', _200 => _200.markDirty, 'call', _201 => _201()]);
|
|
8696
|
+
}
|
|
8697
|
+
/** Move the pool window to start at `start` (the scroll position). */
|
|
8698
|
+
setVisibleStart(start) {
|
|
8699
|
+
const clamped = Math.max(0, Math.min(start, Math.max(0, this._items.length - 1)));
|
|
8700
|
+
if (clamped === this._visibleStart) return;
|
|
8701
|
+
this._visibleStart = clamped;
|
|
8702
|
+
this._syncHotspots();
|
|
8703
|
+
_optionalChain([this, 'access', _202 => _202.scene, 'optionalAccess', _203 => _203.markDirty, 'call', _204 => _204()]);
|
|
8704
|
+
}
|
|
8705
|
+
/**
|
|
8706
|
+
* Keep one hotspot per visible slot, positioned over it. The pool is sized
|
|
8707
|
+
* to the viewport (capacity), each slot re-bound to whatever item currently
|
|
8708
|
+
* occupies it — the `Tree._syncHotspots` shape, minus tree structure.
|
|
8709
|
+
*/
|
|
8710
|
+
_syncHotspots() {
|
|
8711
|
+
const capacity = _nullishCoalesce(this._visibleCapacity, () => ( Math.max(1, Math.ceil(this.height / this._rowHeight))));
|
|
8712
|
+
const need = Math.max(0, Math.min(capacity, this._items.length - this._visibleStart));
|
|
8713
|
+
while (this._hotspots.length < need) {
|
|
8714
|
+
const hotspot = new AggregateItemHotspot(this);
|
|
8715
|
+
this._hotspots.push(hotspot);
|
|
8716
|
+
this.add(hotspot);
|
|
8717
|
+
}
|
|
8718
|
+
while (this._hotspots.length > need) {
|
|
8719
|
+
const hotspot = this._hotspots.pop();
|
|
8720
|
+
_optionalChain([this, 'access', _205 => _205.scene, 'optionalAccess', _206 => _206.detachA11y, 'call', _207 => _207(hotspot)]);
|
|
8721
|
+
this.remove(hotspot);
|
|
8722
|
+
}
|
|
8723
|
+
for (let slot = 0; slot < need; slot++) {
|
|
8724
|
+
const index = this._visibleStart + slot;
|
|
8725
|
+
const hotspot = this._hotspots[slot];
|
|
8726
|
+
hotspot.bind(index, this._items[index]);
|
|
8727
|
+
hotspot.x = 0;
|
|
8728
|
+
hotspot.y = slot * this._rowHeight;
|
|
8729
|
+
hotspot.width = this.width;
|
|
8730
|
+
hotspot.height = this._rowHeight;
|
|
8731
|
+
}
|
|
8732
|
+
}
|
|
8733
|
+
/** Whether `id` owns the roving tab stop: active, else selected, else first. */
|
|
8734
|
+
isTabStop(id) {
|
|
8735
|
+
const anchor = _nullishCoalesce(_nullishCoalesce((this._activeId !== null && this._items.some((item) => item.id === this._activeId) ? this._activeId : null), () => ( (this._selectedId !== null && this._items.some((item) => item.id === this._selectedId) ? this._selectedId : null))), () => ( _optionalChain([this, 'access', _208 => _208._items, 'access', _209 => _209[0], 'optionalAccess', _210 => _210.id])));
|
|
8736
|
+
return id === anchor;
|
|
8737
|
+
}
|
|
8738
|
+
isSelected(id) {
|
|
8739
|
+
return this._selectedId === id;
|
|
8740
|
+
}
|
|
8741
|
+
/** Item role the hotspots announce (kept on the parent: one source of truth). */
|
|
8742
|
+
get itemRole() {
|
|
8743
|
+
return this._itemRole;
|
|
8744
|
+
}
|
|
8745
|
+
/** Activate an item (pointer tap-through or Enter/Space): selects and notifies. */
|
|
8746
|
+
activateItem(id, focusIt = false) {
|
|
8747
|
+
const index = this._items.findIndex((item) => item.id === id);
|
|
8748
|
+
if (index === -1) return;
|
|
8749
|
+
this._activeId = id;
|
|
8750
|
+
this._selectedId = id;
|
|
8751
|
+
_optionalChain([this, 'access', _211 => _211._onActivate, 'optionalCall', _212 => _212(this._items[index], index)]);
|
|
8752
|
+
if (focusIt) this.focusItem(id);
|
|
8753
|
+
_optionalChain([this, 'access', _213 => _213.scene, 'optionalAccess', _214 => _214.markDirty, 'call', _215 => _215()]);
|
|
8754
|
+
}
|
|
8755
|
+
/** Move keyboard focus to the hotspot currently bound to `id`, if any. */
|
|
8756
|
+
focusItem(id) {
|
|
8757
|
+
_optionalChain([this, 'access', _216 => _216._hotspots, 'access', _217 => _217.find, 'call', _218 => _218((hotspot) => hotspot.itemId === id), 'optionalAccess', _219 => _219.focus, 'call', _220 => _220()]);
|
|
8758
|
+
}
|
|
8759
|
+
/**
|
|
8760
|
+
* Aggregate keyboard model: Up/Down move the active item (scrolling the pool
|
|
8761
|
+
* window so it stays bound), Home/End jump, Enter/Space activate. The active
|
|
8762
|
+
* item is focused as it moves so focus is never stranded on a re-bound slot.
|
|
8763
|
+
*/
|
|
8764
|
+
handleItemKey(e, id) {
|
|
8765
|
+
const index = this._items.findIndex((item) => item.id === id);
|
|
8766
|
+
if (index === -1) return;
|
|
8767
|
+
let next = -1;
|
|
8768
|
+
switch (e.key) {
|
|
8769
|
+
case "ArrowDown":
|
|
8770
|
+
next = Math.min(index + 1, this._items.length - 1);
|
|
8771
|
+
break;
|
|
8772
|
+
case "ArrowUp":
|
|
8773
|
+
next = Math.max(index - 1, 0);
|
|
8774
|
+
break;
|
|
8775
|
+
case "Home":
|
|
8776
|
+
next = 0;
|
|
8777
|
+
break;
|
|
8778
|
+
case "End":
|
|
8779
|
+
next = this._items.length - 1;
|
|
8780
|
+
break;
|
|
8781
|
+
case "Enter":
|
|
8782
|
+
case " ":
|
|
8783
|
+
e.preventDefault();
|
|
8784
|
+
this.activateItem(id, true);
|
|
8785
|
+
return;
|
|
8786
|
+
default:
|
|
8787
|
+
return;
|
|
8788
|
+
}
|
|
8789
|
+
e.preventDefault();
|
|
8790
|
+
this._activeId = this._items[next].id;
|
|
8791
|
+
this._ensureVisible(next);
|
|
8792
|
+
this.focusItem(this._activeId);
|
|
8793
|
+
_optionalChain([this, 'access', _221 => _221.scene, 'optionalAccess', _222 => _222.markDirty, 'call', _223 => _223()]);
|
|
8794
|
+
}
|
|
8795
|
+
/** Scroll the pool window just enough to keep `index` bound. */
|
|
8796
|
+
_ensureVisible(index) {
|
|
8797
|
+
const capacity = _nullishCoalesce(this._visibleCapacity, () => ( Math.max(1, Math.ceil(this.height / this._rowHeight))));
|
|
8798
|
+
if (index < this._visibleStart) this.setVisibleStart(index);
|
|
8799
|
+
else if (index >= this._visibleStart + capacity) {
|
|
8800
|
+
this.setVisibleStart(index - capacity + 1);
|
|
8801
|
+
} else {
|
|
8802
|
+
this._syncHotspots();
|
|
8803
|
+
}
|
|
8804
|
+
}
|
|
8805
|
+
update(_dt, _time) {
|
|
8806
|
+
super.update(_dt, _time);
|
|
8807
|
+
this._syncHotspots();
|
|
8808
|
+
}
|
|
8809
|
+
}, _class17);
|
|
8810
|
+
var AggregateItemHotspot = (_class18 = class extends _chunkHC5EZOZJjs.Entity {
|
|
8811
|
+
constructor(aggregate) {
|
|
8812
|
+
super();_class18.prototype.__init216.call(this);_class18.prototype.__init217.call(this);_class18.prototype.__init218.call(this);;
|
|
8813
|
+
this.aggregate = aggregate;
|
|
8814
|
+
this.interactive = true;
|
|
8815
|
+
this.on("click", () => this.aggregate.activateItem(this.itemId, true));
|
|
8816
|
+
this.on("keydown", (e) => this.aggregate.handleItemKey(e, this.itemId));
|
|
8817
|
+
}
|
|
8818
|
+
|
|
8819
|
+
__init216() {this.itemId = ""}
|
|
8820
|
+
__init217() {this._index = 0}
|
|
8821
|
+
__init218() {this._label = ""}
|
|
8822
|
+
bind(index, item) {
|
|
8823
|
+
this._index = index;
|
|
8824
|
+
this.itemId = item.id;
|
|
8825
|
+
this._label = item.label;
|
|
8826
|
+
}
|
|
8827
|
+
/** The aggregate positions and sizes one pooled hotspot per visible slot. */
|
|
8828
|
+
getLayoutControlledProperties() {
|
|
8829
|
+
return ["x", "y", "width", "height"];
|
|
8830
|
+
}
|
|
8831
|
+
getA11yAttributes() {
|
|
8832
|
+
return {
|
|
8833
|
+
role: this.aggregate.itemRole,
|
|
8834
|
+
label: this._label,
|
|
8835
|
+
// 1-based position within the FULL set, not the pool: without these a
|
|
8836
|
+
// virtualized window announces the pool position as the set position.
|
|
8837
|
+
posInSet: this._index + 1,
|
|
8838
|
+
setSize: this.aggregate.itemCount,
|
|
8839
|
+
selected: this.aggregate.isSelected(this.itemId),
|
|
8840
|
+
// Roving tabindex: only the active item is a tab stop; arrows move within.
|
|
8841
|
+
tabIndex: this.aggregate.isTabStop(this.itemId) ? 0 : -1,
|
|
8842
|
+
// The owner keeps the pointer (canvas handling or an underlying
|
|
8843
|
+
// selectable-text mirror); this hotspot exists for semantics + keyboard
|
|
8844
|
+
// focus, so it opts out of hit-testing. Keyboard focus and
|
|
8845
|
+
// AT-synthesized `click` still work under `pointer-events:none`.
|
|
8846
|
+
pointerEvents: "none"
|
|
8847
|
+
};
|
|
8848
|
+
}
|
|
8849
|
+
render() {
|
|
8850
|
+
}
|
|
8851
|
+
/** Axis-aligned hit-test against the hotspot slot (the `UIComponent` default). */
|
|
8852
|
+
isPointInside(globalX, globalY) {
|
|
8853
|
+
const local = this.worldToLocal(globalX, globalY);
|
|
8854
|
+
if (!local) return false;
|
|
8855
|
+
return local.x >= 0 && local.x <= this.width && local.y >= 0 && local.y <= this.height;
|
|
8856
|
+
}
|
|
8857
|
+
}, _class18);
|
|
8858
|
+
|
|
7957
8859
|
// src/components/GridTextEntity.ts
|
|
7958
|
-
var GridTextEntity = (
|
|
8860
|
+
var GridTextEntity = (_class19 = class extends _chunkHC5EZOZJjs.Entity {
|
|
7959
8861
|
|
|
7960
|
-
|
|
7961
|
-
|
|
8862
|
+
__init219() {this.fillStyle = "#ffffff"}
|
|
8863
|
+
__init220() {this.grid = []}
|
|
7962
8864
|
// Array of rows
|
|
7963
|
-
|
|
7964
|
-
|
|
8865
|
+
__init221() {this.cols = 0}
|
|
8866
|
+
__init222() {this.rows = 0}
|
|
7965
8867
|
|
|
7966
8868
|
|
|
7967
8869
|
constructor(_atlas, fontSize = 10) {
|
|
7968
|
-
super();
|
|
8870
|
+
super();_class19.prototype.__init219.call(this);_class19.prototype.__init220.call(this);_class19.prototype.__init221.call(this);_class19.prototype.__init222.call(this);;
|
|
7969
8871
|
this.fontSize = fontSize;
|
|
7970
8872
|
this.charWidth = fontSize * 1;
|
|
7971
8873
|
this.charHeight = fontSize * 1.1;
|
|
@@ -7974,7 +8876,7 @@ var GridTextEntity = (_class17 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
7974
8876
|
updateGrid(ascii) {
|
|
7975
8877
|
this.grid = ascii;
|
|
7976
8878
|
this.rows = ascii.length;
|
|
7977
|
-
this.cols = ascii.reduce((widest, row) => Math.max(widest, _nullishCoalesce(_optionalChain([row, 'optionalAccess',
|
|
8879
|
+
this.cols = ascii.reduce((widest, row) => Math.max(widest, _nullishCoalesce(_optionalChain([row, 'optionalAccess', _224 => _224.length]), () => ( 0))), 0);
|
|
7978
8880
|
}
|
|
7979
8881
|
isPointInside(_globalX, _globalY) {
|
|
7980
8882
|
return false;
|
|
@@ -7996,7 +8898,7 @@ var GridTextEntity = (_class17 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
7996
8898
|
}
|
|
7997
8899
|
}
|
|
7998
8900
|
}
|
|
7999
|
-
},
|
|
8901
|
+
}, _class19);
|
|
8000
8902
|
|
|
8001
8903
|
// src/components/SplineEntity.ts
|
|
8002
8904
|
function polySegmentToBezier(seg) {
|
|
@@ -8049,7 +8951,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
|
|
|
8049
8951
|
const ey = py - cy;
|
|
8050
8952
|
return ex * ex + ey * ey;
|
|
8051
8953
|
}
|
|
8052
|
-
var SplineEntity = (
|
|
8954
|
+
var SplineEntity = (_class20 = class extends _chunkHC5EZOZJjs.Entity {
|
|
8053
8955
|
|
|
8054
8956
|
|
|
8055
8957
|
|
|
@@ -8057,17 +8959,17 @@ var SplineEntity = (_class18 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8057
8959
|
|
|
8058
8960
|
|
|
8059
8961
|
|
|
8060
|
-
|
|
8061
|
-
|
|
8962
|
+
__init223() {this.offscreen = null}
|
|
8963
|
+
__init224() {this.baked = false}
|
|
8062
8964
|
/** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
|
|
8063
|
-
|
|
8064
|
-
|
|
8965
|
+
__init225() {this.bakedWidth = 0}
|
|
8966
|
+
__init226() {this.bakedHeight = 0}
|
|
8065
8967
|
/**
|
|
8066
8968
|
* Device-pixel ratio the bitmap was rasterized at. Tracked so a DPR change
|
|
8067
8969
|
* (browser zoom, a monitor move, a renderer whose clamp changed) re-bakes
|
|
8068
8970
|
* instead of blitting a bitmap at the wrong device density forever.
|
|
8069
8971
|
*/
|
|
8070
|
-
|
|
8972
|
+
__init227() {this.bakedDPR = 0}
|
|
8071
8973
|
/**
|
|
8072
8974
|
* Gradient strokes can't be baked to a solid-color bitmap; they render
|
|
8073
8975
|
* per-frame. Derived from `_doc`, so it is NOT readonly — assigning a new
|
|
@@ -8075,7 +8977,7 @@ var SplineEntity = (_class18 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8075
8977
|
*/
|
|
8076
8978
|
|
|
8077
8979
|
/** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
|
|
8078
|
-
|
|
8980
|
+
__init228() {this.polylines = null}
|
|
8079
8981
|
/**
|
|
8080
8982
|
* The spline document to render. Assigning a new document invalidates all
|
|
8081
8983
|
* caches (baked canvas, flattened polylines, bounds).
|
|
@@ -8109,9 +9011,9 @@ var SplineEntity = (_class18 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8109
9011
|
* local bounds after painting the curves. Useful for drag feedback and
|
|
8110
9012
|
* debugging hit areas. Defaults to `false`.
|
|
8111
9013
|
*/
|
|
8112
|
-
|
|
9014
|
+
__init229() {this.showBounds = false}
|
|
8113
9015
|
constructor(doc, opts = {}) {
|
|
8114
|
-
super();
|
|
9016
|
+
super();_class20.prototype.__init223.call(this);_class20.prototype.__init224.call(this);_class20.prototype.__init225.call(this);_class20.prototype.__init226.call(this);_class20.prototype.__init227.call(this);_class20.prototype.__init228.call(this);_class20.prototype.__init229.call(this);;
|
|
8115
9017
|
this._doc = doc;
|
|
8116
9018
|
this._lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
|
|
8117
9019
|
this.cache = _nullishCoalesce(opts.cache, () => ( true));
|
|
@@ -8131,7 +9033,7 @@ var SplineEntity = (_class18 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8131
9033
|
*/
|
|
8132
9034
|
computeContainsGradient() {
|
|
8133
9035
|
const isGradient = (c) => c !== null && !Array.isArray(c);
|
|
8134
|
-
return (_nullishCoalesce(_optionalChain([this, 'access',
|
|
9036
|
+
return (_nullishCoalesce(_optionalChain([this, 'access', _225 => _225._doc, 'access', _226 => _226.equations, 'optionalAccess', _227 => _227.some, 'call', _228 => _228((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _229 => _229._doc, 'access', _230 => _230.paths, 'optionalAccess', _231 => _231.some, 'call', _232 => _232((p) => isGradient(p.color_rgb))]), () => ( false)));
|
|
8135
9037
|
}
|
|
8136
9038
|
/** Clear cached baked canvas and hit-test polylines. */
|
|
8137
9039
|
invalidateCache() {
|
|
@@ -8370,14 +9272,14 @@ var SplineEntity = (_class18 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8370
9272
|
r.stroke("rgba(0, 150, 255, 0.8)", 2);
|
|
8371
9273
|
}
|
|
8372
9274
|
}
|
|
8373
|
-
},
|
|
9275
|
+
}, _class20);
|
|
8374
9276
|
async function loadSpline(url) {
|
|
8375
9277
|
const res = await fetch(url);
|
|
8376
9278
|
return await res.json();
|
|
8377
9279
|
}
|
|
8378
9280
|
|
|
8379
9281
|
// src/components/Rect.ts
|
|
8380
|
-
var Rect = class extends
|
|
9282
|
+
var Rect = class extends _chunkHC5EZOZJjs.Entity {
|
|
8381
9283
|
|
|
8382
9284
|
|
|
8383
9285
|
|
|
@@ -8433,7 +9335,7 @@ var Rect = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8433
9335
|
};
|
|
8434
9336
|
|
|
8435
9337
|
// src/components/Circle.ts
|
|
8436
|
-
var Circle = class extends
|
|
9338
|
+
var Circle = class extends _chunkHC5EZOZJjs.Entity {
|
|
8437
9339
|
|
|
8438
9340
|
|
|
8439
9341
|
|
|
@@ -8497,7 +9399,7 @@ var Circle = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8497
9399
|
};
|
|
8498
9400
|
|
|
8499
9401
|
// src/components/Group.ts
|
|
8500
|
-
var Group = class extends
|
|
9402
|
+
var Group = class extends _chunkHC5EZOZJjs.Entity {
|
|
8501
9403
|
constructor(...children) {
|
|
8502
9404
|
super();
|
|
8503
9405
|
if (children.length > 0) this.add(...children);
|
|
@@ -8516,21 +9418,21 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
|
|
|
8516
9418
|
|
|
8517
9419
|
|
|
8518
9420
|
// src/tree/DOMPortalEntity.ts
|
|
8519
|
-
var DOMPortalEntity = (
|
|
9421
|
+
var DOMPortalEntity = (_class21 = class extends _chunkHC5EZOZJjs.Entity {
|
|
8520
9422
|
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
9423
|
+
__init230() {this.isDOMPortal = true}
|
|
9424
|
+
__init231() {this.domListeners = []}
|
|
9425
|
+
__init232() {this.resizeObserver = null}
|
|
9426
|
+
__init233() {this.domBound = false}
|
|
9427
|
+
__init234() {this.cachedWidth = 100}
|
|
9428
|
+
__init235() {this.cachedHeight = 100}
|
|
9429
|
+
__init236() {this.lastWidth = ""}
|
|
9430
|
+
__init237() {this.lastHeight = ""}
|
|
9431
|
+
__init238() {this.lastTransform = ""}
|
|
9432
|
+
__init239() {this.lastZIndex = ""}
|
|
9433
|
+
__init240() {this.lastOpacity = ""}
|
|
8532
9434
|
constructor(domElement, width, height, id) {
|
|
8533
|
-
super(id);
|
|
9435
|
+
super(id);_class21.prototype.__init230.call(this);_class21.prototype.__init231.call(this);_class21.prototype.__init232.call(this);_class21.prototype.__init233.call(this);_class21.prototype.__init234.call(this);_class21.prototype.__init235.call(this);_class21.prototype.__init236.call(this);_class21.prototype.__init237.call(this);_class21.prototype.__init238.call(this);_class21.prototype.__init239.call(this);_class21.prototype.__init240.call(this);;
|
|
8534
9436
|
this.domElement = domElement;
|
|
8535
9437
|
this.width = _nullishCoalesce(width, () => ( 0));
|
|
8536
9438
|
this.height = _nullishCoalesce(height, () => ( 0));
|
|
@@ -8572,7 +9474,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8572
9474
|
];
|
|
8573
9475
|
for (const type of events) {
|
|
8574
9476
|
const handler = (e) => {
|
|
8575
|
-
this.dispatchEvent(new (0,
|
|
9477
|
+
this.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)(type, this, e));
|
|
8576
9478
|
};
|
|
8577
9479
|
this.domElement.addEventListener(type, handler);
|
|
8578
9480
|
this.domListeners.push({ type, handler, capture: false });
|
|
@@ -8583,7 +9485,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8583
9485
|
];
|
|
8584
9486
|
for (const { native, vecto } of hoverEvents) {
|
|
8585
9487
|
const handler = (e) => {
|
|
8586
|
-
this.dispatchEvent(new (0,
|
|
9488
|
+
this.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)(vecto, this, e, false));
|
|
8587
9489
|
};
|
|
8588
9490
|
this.domElement.addEventListener(native, handler);
|
|
8589
9491
|
this.domListeners.push({ type: native, handler, capture: false });
|
|
@@ -8591,7 +9493,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8591
9493
|
const focusEvents = ["focus", "blur"];
|
|
8592
9494
|
for (const type of focusEvents) {
|
|
8593
9495
|
const handler = (e) => {
|
|
8594
|
-
this.dispatchEvent(new (0,
|
|
9496
|
+
this.dispatchEvent(new (0, _chunkHC5EZOZJjs.VectoJSEvent)(type, this, e, true));
|
|
8595
9497
|
};
|
|
8596
9498
|
this.domElement.addEventListener(type, handler, true);
|
|
8597
9499
|
this.domListeners.push({ type, handler, capture: true });
|
|
@@ -8639,11 +9541,23 @@ var DOMPortalEntity = (_class19 = class extends _chunkPOPXUPKRjs.Entity {
|
|
|
8639
9541
|
}
|
|
8640
9542
|
super.destroy();
|
|
8641
9543
|
}
|
|
8642
|
-
},
|
|
9544
|
+
}, _class21);
|
|
8643
9545
|
|
|
8644
9546
|
// src/index.ts
|
|
8645
|
-
Scene.registerWebGLPointRendererCreator(
|
|
8646
|
-
Scene.registerWebGPUParticleSystemManager(
|
|
9547
|
+
Scene.registerWebGLPointRendererCreator(_chunkBKXERWADjs.createWebGLPointRenderer);
|
|
9548
|
+
Scene.registerWebGPUParticleSystemManager(_chunkBKXERWADjs.WebGPUParticleSystemManager);
|
|
9549
|
+
|
|
9550
|
+
|
|
9551
|
+
|
|
9552
|
+
|
|
9553
|
+
|
|
9554
|
+
|
|
9555
|
+
|
|
9556
|
+
|
|
9557
|
+
|
|
9558
|
+
|
|
9559
|
+
|
|
9560
|
+
|
|
8647
9561
|
|
|
8648
9562
|
|
|
8649
9563
|
|
|
@@ -8692,4 +9606,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkKRUDTGNRjs.WebGPUParticleSystemM
|
|
|
8692
9606
|
|
|
8693
9607
|
|
|
8694
9608
|
|
|
8695
|
-
exports.CanvasRenderer =
|
|
9609
|
+
exports.CanvasRenderer = _chunkBKXERWADjs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DEFAULT_CONTENT_SEMANTIC_BUDGET = DEFAULT_CONTENT_SEMANTIC_BUDGET; exports.DEFAULT_PROJECTION_CAPABILITIES = DEFAULT_PROJECTION_CAPABILITIES; exports.DEFAULT_SEMANTIC_PROJECTION_POLICY = DEFAULT_SEMANTIC_PROJECTION_POLICY; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkHC5EZOZJjs.Entity; exports.GlyphRasterAtlas = _chunkBKXERWADjs.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.KEYBOARD_OWNING_ROLES = KEYBOARD_OWNING_ROLES; exports.MSDFTextEntity = _chunkHC5EZOZJjs.MSDFTextEntity; exports.PARTICLE_OFFSET_LIFE = PARTICLE_OFFSET_LIFE; exports.PARTICLE_OFFSET_ORIGIN_X = PARTICLE_OFFSET_ORIGIN_X; exports.PARTICLE_OFFSET_ORIGIN_Y = PARTICLE_OFFSET_ORIGIN_Y; exports.PARTICLE_OFFSET_POSITION_X = PARTICLE_OFFSET_POSITION_X; exports.PARTICLE_OFFSET_POSITION_Y = PARTICLE_OFFSET_POSITION_Y; exports.PARTICLE_OFFSET_SIZE = PARTICLE_OFFSET_SIZE; exports.PARTICLE_OFFSET_VELOCITY_X = PARTICLE_OFFSET_VELOCITY_X; exports.PARTICLE_OFFSET_VELOCITY_Y = PARTICLE_OFFSET_VELOCITY_Y; exports.PARTICLE_STRIDE_FLOATS = PARTICLE_STRIDE_FLOATS; exports.PROJECTION_AUTO_DOM_BUDGET = PROJECTION_AUTO_DOM_BUDGET; exports.PROJECTION_AUTO_HYSTERESIS_FRAMES = PROJECTION_AUTO_HYSTERESIS_FRAMES; exports.REDUCED_MOTION_FPS = REDUCED_MOTION_FPS; exports.Rect = Rect; exports.SCENE_OPTION_KEYS = SCENE_OPTION_KEYS; exports.SVGEntity = _chunkHC5EZOZJjs.SVGEntity; exports.SVGRenderer = _chunkBKXERWADjs.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkBKXERWADjs.TextRasterCache; exports.UNKNOWN_PROJECTION_CAPABILITY = UNKNOWN_PROJECTION_CAPABILITY; exports.VECTO_USER_TIMING = VECTO_USER_TIMING; exports.VectoJSEvent = _chunkHC5EZOZJjs.VectoJSEvent; exports.VirtualizedSetAggregate = VirtualizedSetAggregate; exports.WebGPUParticleSystemManager = _chunkBKXERWADjs.WebGPUParticleSystemManager; exports.beginVectoUserTiming = beginVectoUserTiming; exports.contentLineInHint = _chunkHC5EZOZJjs.contentLineInHint; exports.createWebGLPointRenderer = _chunkBKXERWADjs.createWebGLPointRenderer; exports.describeHTMLInCanvasSupport = describeHTMLInCanvasSupport; exports.endVectoUserTiming = endVectoUserTiming; exports.getSemanticProjectionCapabilities = getSemanticProjectionCapabilities; exports.hysteresisVote = hysteresisVote; exports.installRendererDevTraps = _chunkBKXERWADjs.installRendererDevTraps; exports.isDeferrableSemanticNode = isDeferrableSemanticNode; exports.isRendererDevMode = _chunkBKXERWADjs.isRendererDevMode; exports.isSafeUrl = _chunkBKXERWADjs.isSafeUrl; exports.loadSpline = loadSpline; exports.measureVectoUserTiming = measureVectoUserTiming; exports.normalizeChord = normalizeChord; exports.ownsKeyboard = ownsKeyboard; exports.parseColorToRGBA = _chunkBKXERWADjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.resolveProjection = resolveProjection; exports.sanitizeUrl = _chunkBKXERWADjs.sanitizeUrl; exports.setRendererDevMode = _chunkBKXERWADjs.setRendererDevMode; exports.supportsHTMLInCanvas = supportsHTMLInCanvas;
|