@vectojs/core 1.38.1 → 1.39.1
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-QVTCKWDO.mjs → chunk-7PYD5UDX.mjs} +93 -43
- package/dist/{chunk-LWEMD34D.mjs → chunk-AISSDI6U.mjs} +132 -33
- package/dist/{chunk-ZYYP2M5D.js → chunk-BKXERWAD.js} +181 -82
- package/dist/{chunk-SRXU3ZXK.js → chunk-POPXUPKR.js} +141 -91
- package/dist/index.js +772 -401
- package/dist/index.mjs +459 -88
- package/dist/renderer/CanvasRenderer.d.ts +6 -0
- package/dist/renderer/SVGRenderer.d.ts +17 -2
- package/dist/renderer/WebGPUParticleSystemManager.d.ts +2 -0
- package/dist/renderer.js +2 -2
- package/dist/renderer.mjs +1 -1
- package/dist/text/MSDFTextEntity.d.ts +0 -1
- package/dist/text.js +2 -2
- package/dist/text.mjs +1 -1
- package/dist/tree/Entity.d.ts +8 -2
- package/dist/tree/Scene.d.ts +123 -0
- package/dist/tree/scene/A11yProjectionManager.d.ts +12 -0
- package/dist/tree/scene/HitTester.d.ts +14 -2
- package/dist/tree/scene/WasmBackendFacade.d.ts +17 -0
- package/dist/tree/scene/keyboard.d.ts +56 -0
- package/dist/wasm/backend.d.ts +7 -7
- package/dist/wasm/vectojs_core.wasm +0 -0
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -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 _chunkPOPXUPKRjs = require('./chunk-POPXUPKR.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 _chunkPOPXUPKRjs.Entity {
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
|
|
@@ -225,14 +225,14 @@ var ComputeParticleEntity = (_class = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
225
225
|
const bounceDamping = Math.max(0, Math.min(1, this.bounceDamping));
|
|
226
226
|
const maxVelocity = Math.max(1, this.maxVelocity);
|
|
227
227
|
for (let i = 0; i < this.maxParticles; i++) {
|
|
228
|
-
const offset = i *
|
|
229
|
-
let px = this.particleData[offset];
|
|
230
|
-
let py = this.particleData[offset +
|
|
231
|
-
let vx = this.particleData[offset +
|
|
232
|
-
let vy = this.particleData[offset +
|
|
233
|
-
const ox = this.particleData[offset +
|
|
234
|
-
const oy = this.particleData[offset +
|
|
235
|
-
const life = this.particleData[offset +
|
|
228
|
+
const offset = i * PARTICLE_STRIDE_FLOATS;
|
|
229
|
+
let px = this.particleData[offset + PARTICLE_OFFSET_POSITION_X];
|
|
230
|
+
let py = this.particleData[offset + PARTICLE_OFFSET_POSITION_Y];
|
|
231
|
+
let vx = this.particleData[offset + PARTICLE_OFFSET_VELOCITY_X];
|
|
232
|
+
let vy = this.particleData[offset + PARTICLE_OFFSET_VELOCITY_Y];
|
|
233
|
+
const ox = this.particleData[offset + PARTICLE_OFFSET_ORIGIN_X];
|
|
234
|
+
const oy = this.particleData[offset + PARTICLE_OFFSET_ORIGIN_Y];
|
|
235
|
+
const life = this.particleData[offset + PARTICLE_OFFSET_LIFE];
|
|
236
236
|
if (isNaN(px)) px = ox;
|
|
237
237
|
if (isNaN(py)) py = oy;
|
|
238
238
|
if (isNaN(vx)) vx = 0;
|
|
@@ -290,11 +290,11 @@ var ComputeParticleEntity = (_class = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
290
290
|
if (life >= 0) {
|
|
291
291
|
nlife = Math.max(0, life - safeDt * 0.5);
|
|
292
292
|
}
|
|
293
|
-
this.particleData[offset] = npx;
|
|
294
|
-
this.particleData[offset +
|
|
295
|
-
this.particleData[offset +
|
|
296
|
-
this.particleData[offset +
|
|
297
|
-
this.particleData[offset +
|
|
293
|
+
this.particleData[offset + PARTICLE_OFFSET_POSITION_X] = npx;
|
|
294
|
+
this.particleData[offset + PARTICLE_OFFSET_POSITION_Y] = npy;
|
|
295
|
+
this.particleData[offset + PARTICLE_OFFSET_VELOCITY_X] = nvx;
|
|
296
|
+
this.particleData[offset + PARTICLE_OFFSET_VELOCITY_Y] = nvy;
|
|
297
|
+
this.particleData[offset + PARTICLE_OFFSET_LIFE] = nlife;
|
|
298
298
|
}
|
|
299
299
|
this.pendingExplosion = null;
|
|
300
300
|
}
|
|
@@ -594,7 +594,12 @@ var ContentGridProjector = class {
|
|
|
594
594
|
lineIndex === 0
|
|
595
595
|
);
|
|
596
596
|
const reusable = existingLines[domIndex];
|
|
597
|
-
if (reusable !== void 0 && reusable.dataset.vectoGridLineSig === lineSignature
|
|
597
|
+
if (reusable !== void 0 && reusable.dataset.vectoGridLineSig === lineSignature) {
|
|
598
|
+
const indexLabel = `${lineIndex}`;
|
|
599
|
+
if (reusable.dataset.vectoGridLine !== indexLabel) {
|
|
600
|
+
reusable.dataset.vectoGridLine = indexLabel;
|
|
601
|
+
reusable.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _34 => _34.y]), () => ( lineIndex * grid.lineHeight))) + baseline - _text.cssLineBoxBaseline.call(void 0, lineFont, lineHeight)}px`;
|
|
602
|
+
}
|
|
598
603
|
continue;
|
|
599
604
|
}
|
|
600
605
|
if (selectionLine !== null && selectionLine === lineIndex) rebuiltSelectionLine = true;
|
|
@@ -603,8 +608,8 @@ var ContentGridProjector = class {
|
|
|
603
608
|
lineElement.dir = "ltr";
|
|
604
609
|
lineElement.dataset.vectoGridLine = `${lineIndex}`;
|
|
605
610
|
lineElement.style.position = "absolute";
|
|
606
|
-
lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
607
|
-
lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
611
|
+
lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _35 => _35.x]), () => ( 0))}px`;
|
|
612
|
+
lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _36 => _36.y]), () => ( lineIndex * grid.lineHeight))) + baseline - _text.cssLineBoxBaseline.call(void 0, lineFont, lineHeight)}px`;
|
|
608
613
|
lineElement.style.width = `${gridLine.width}px`;
|
|
609
614
|
lineElement.style.height = `${lineHeight}px`;
|
|
610
615
|
lineElement.style.whiteSpace = "pre";
|
|
@@ -673,7 +678,7 @@ var ContentGridProjector = class {
|
|
|
673
678
|
}
|
|
674
679
|
const windowLength = gridWindow.end - gridWindow.start;
|
|
675
680
|
while (el.children.length > windowLength) {
|
|
676
|
-
_optionalChain([el, 'access',
|
|
681
|
+
_optionalChain([el, 'access', _37 => _37.lastElementChild, 'optionalAccess', _38 => _38.remove, 'call', _39 => _39()]);
|
|
677
682
|
}
|
|
678
683
|
if (rebuiltSelectionLine) {
|
|
679
684
|
this.contentProjection.restoreGridSelection(el, selectionSnapshot);
|
|
@@ -713,8 +718,8 @@ var ContentGridProjector = class {
|
|
|
713
718
|
function contentGridLineSignature(grid, line, projected, lineHeight, baseline, font, isFirstLine) {
|
|
714
719
|
const parts = [
|
|
715
720
|
// Line box: position, size, and the font that resolves its baseline.
|
|
716
|
-
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess',
|
|
717
|
-
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess',
|
|
721
|
+
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _40 => _40.x]), () => ( 0))}`,
|
|
722
|
+
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _41 => _41.y]), () => ( ""))}`,
|
|
718
723
|
`${lineHeight}`,
|
|
719
724
|
`${baseline}`,
|
|
720
725
|
font,
|
|
@@ -780,7 +785,13 @@ function projectionCaretAt(root, absoluteOffset, affinity) {
|
|
|
780
785
|
}
|
|
781
786
|
|
|
782
787
|
// src/tree/scene/A11yProjectionManager.ts
|
|
783
|
-
|
|
788
|
+
function orderBandBottom(r) {
|
|
789
|
+
return r.container ? r.top + 4 : r.top + Math.max(Number.parseFloat(r.el.style.height) || 0, 4);
|
|
790
|
+
}
|
|
791
|
+
var byTopThenIndex = (p, q) => p.top - q.top || p.i - q.i;
|
|
792
|
+
var byLeftAscThenIndex = (p, q) => p.left - q.left || p.i - q.i;
|
|
793
|
+
var byLeftDescThenIndex = (p, q) => q.left - p.left || p.i - q.i;
|
|
794
|
+
var A11yProjectionManager = (_class2 = class {constructor() { _class2.prototype.__init8.call(this);_class2.prototype.__init9.call(this);_class2.prototype.__init10.call(this);_class2.prototype.__init11.call(this);_class2.prototype.__init12.call(this);_class2.prototype.__init13.call(this);_class2.prototype.__init14.call(this);_class2.prototype.__init15.call(this);_class2.prototype.__init16.call(this);_class2.prototype.__init17.call(this);_class2.prototype.__init18.call(this);_class2.prototype.__init19.call(this); }
|
|
784
795
|
/**
|
|
785
796
|
* Set by anything that changes which elements exist or how they nest, and
|
|
786
797
|
* cleared by the reorder pass. Public so `Scene` can expose it under its
|
|
@@ -821,6 +832,18 @@ var A11yProjectionManager = (_class2 = class {constructor() { _class2.prototype.
|
|
|
821
832
|
* implicit root region. See {@link sortNormalElementsVisually}.
|
|
822
833
|
*/
|
|
823
834
|
__init15() {this.orderRegions = /* @__PURE__ */ new Map()}
|
|
835
|
+
/**
|
|
836
|
+
* Decoration records for {@link sortNormalElementsVisually}: one per ordered
|
|
837
|
+
* element, pooled across passes and rewritten in place — the sort runs on
|
|
838
|
+
* structure-change frames, where the module's zero-GC policy applies.
|
|
839
|
+
*/
|
|
840
|
+
__init16() {this.orderDecorated = []}
|
|
841
|
+
/** Region → decorated elements, reused by {@link sortNormalElementsVisually}. */
|
|
842
|
+
__init17() {this.orderBucketByRegion = /* @__PURE__ */ new Map()}
|
|
843
|
+
/** Pool of bucket arrays backing {@link orderBucketByRegion} across passes. */
|
|
844
|
+
__init18() {this.orderBuckets = []}
|
|
845
|
+
/** Scratch for one visual row inside {@link sortNormalElementsVisually}. */
|
|
846
|
+
__init19() {this.orderRowScratch = []}
|
|
824
847
|
/** Mark the projected DOM as needing a reorder on the next pass. */
|
|
825
848
|
markNeedsReorder() {
|
|
826
849
|
this.needsReorder = true;
|
|
@@ -878,11 +901,12 @@ var A11yProjectionManager = (_class2 = class {constructor() { _class2.prototype.
|
|
|
878
901
|
this.orderCursors.set(parent, at + 1);
|
|
879
902
|
const current = parent.childNodes[at];
|
|
880
903
|
if (current !== expected) {
|
|
881
|
-
const
|
|
904
|
+
const active = document.activeElement;
|
|
905
|
+
const refocusTarget = active && (active === expected || expected.contains(active)) ? active : null;
|
|
882
906
|
if (!selectionSnapshotTaken) {
|
|
883
907
|
selectionSnapshotTaken = true;
|
|
884
908
|
const live = typeof window !== "undefined" && typeof window.getSelection === "function" ? window.getSelection() : null;
|
|
885
|
-
if (_optionalChain([live, 'optionalAccess',
|
|
909
|
+
if (_optionalChain([live, 'optionalAccess', _42 => _42.anchorNode]) && live.focusNode) {
|
|
886
910
|
selection = live;
|
|
887
911
|
selAnchorNode = live.anchorNode;
|
|
888
912
|
selFocusNode = live.focusNode;
|
|
@@ -894,7 +918,7 @@ var A11yProjectionManager = (_class2 = class {constructor() { _class2.prototype.
|
|
|
894
918
|
selectionMoved = true;
|
|
895
919
|
}
|
|
896
920
|
parent.insertBefore(expected, current || null);
|
|
897
|
-
if (
|
|
921
|
+
if (refocusTarget) refocusTarget.focus({ preventScroll: true });
|
|
898
922
|
}
|
|
899
923
|
}
|
|
900
924
|
if (selectionMoved && selection && selAnchorNode && selFocusNode) {
|
|
@@ -941,7 +965,6 @@ var A11yProjectionManager = (_class2 = class {constructor() { _class2.prototype.
|
|
|
941
965
|
sortNormalElementsVisually(rtl) {
|
|
942
966
|
const els = this.normalElements;
|
|
943
967
|
if (els.length < 2) return;
|
|
944
|
-
const heightOf = (el) => Math.max(Number.parseFloat(el.style.height) || 0, 4);
|
|
945
968
|
const members = this.orderMembers;
|
|
946
969
|
const containers = this.orderContainers;
|
|
947
970
|
members.clear();
|
|
@@ -952,52 +975,70 @@ var A11yProjectionManager = (_class2 = class {constructor() { _class2.prototype.
|
|
|
952
975
|
if (members.has(p)) containers.add(p);
|
|
953
976
|
}
|
|
954
977
|
}
|
|
955
|
-
const
|
|
978
|
+
const decorated = this.orderDecorated;
|
|
979
|
+
while (decorated.length < els.length) {
|
|
980
|
+
decorated.push({ el: els[0], i: 0, top: 0, left: 0, container: false });
|
|
981
|
+
}
|
|
982
|
+
for (let i = 0; i < els.length; i++) {
|
|
983
|
+
const rec = decorated[i];
|
|
956
984
|
let top = 0;
|
|
957
985
|
let left = 0;
|
|
958
|
-
for (let node =
|
|
986
|
+
for (let node = els[i]; node; node = node.parentElement) {
|
|
959
987
|
top += Number.parseFloat(node.style.top) || 0;
|
|
960
988
|
left += Number.parseFloat(node.style.left) || 0;
|
|
961
989
|
const parent = node.parentElement;
|
|
962
990
|
if (!parent || !members.has(parent)) break;
|
|
963
991
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
}
|
|
992
|
+
rec.el = els[i];
|
|
993
|
+
rec.i = i;
|
|
994
|
+
rec.top = top;
|
|
995
|
+
rec.left = left;
|
|
996
|
+
rec.container = containers.has(els[i]);
|
|
997
|
+
}
|
|
970
998
|
const regions = this.orderRegions;
|
|
971
|
-
const buckets =
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
999
|
+
const buckets = this.orderBucketByRegion;
|
|
1000
|
+
const bucketPool = this.orderBuckets;
|
|
1001
|
+
let bucketsUsed = 0;
|
|
1002
|
+
buckets.clear();
|
|
1003
|
+
for (let i = 0; i < els.length; i++) {
|
|
1004
|
+
const rec = decorated[i];
|
|
1005
|
+
const key = _nullishCoalesce(regions.get(rec.el), () => ( null));
|
|
1006
|
+
let bucket = buckets.get(key);
|
|
1007
|
+
if (!bucket) {
|
|
1008
|
+
bucket = bucketPool[bucketsUsed];
|
|
1009
|
+
if (bucket === void 0) {
|
|
1010
|
+
bucket = [];
|
|
1011
|
+
bucketPool.push(bucket);
|
|
1012
|
+
}
|
|
1013
|
+
bucketsUsed++;
|
|
1014
|
+
bucket.length = 0;
|
|
1015
|
+
buckets.set(key, bucket);
|
|
1016
|
+
}
|
|
1017
|
+
bucket.push(rec);
|
|
1018
|
+
}
|
|
1019
|
+
let out = 0;
|
|
980
1020
|
for (const order of buckets.values()) {
|
|
981
|
-
order.sort(
|
|
1021
|
+
order.sort(byTopThenIndex);
|
|
982
1022
|
let rowStart = 0;
|
|
983
|
-
let rowBottom = order.length ?
|
|
1023
|
+
let rowBottom = order.length ? orderBandBottom(order[0]) : 0;
|
|
984
1024
|
const flushRow = (end) => {
|
|
985
|
-
const row =
|
|
986
|
-
row.
|
|
987
|
-
for (
|
|
1025
|
+
const row = this.orderRowScratch;
|
|
1026
|
+
row.length = 0;
|
|
1027
|
+
for (let m = rowStart; m < end; m++) row.push(order[m]);
|
|
1028
|
+
row.sort(rtl ? byLeftDescThenIndex : byLeftAscThenIndex);
|
|
1029
|
+
for (const r of row) els[out++] = r.el;
|
|
988
1030
|
};
|
|
989
1031
|
for (let k = 1; k < order.length; k++) {
|
|
990
1032
|
if (order[k].top < rowBottom) {
|
|
991
|
-
rowBottom = Math.max(rowBottom,
|
|
1033
|
+
rowBottom = Math.max(rowBottom, orderBandBottom(order[k]));
|
|
992
1034
|
} else {
|
|
993
1035
|
flushRow(k);
|
|
994
1036
|
rowStart = k;
|
|
995
|
-
rowBottom =
|
|
1037
|
+
rowBottom = orderBandBottom(order[k]);
|
|
996
1038
|
}
|
|
997
1039
|
}
|
|
998
1040
|
flushRow(order.length);
|
|
999
1041
|
}
|
|
1000
|
-
for (let i = 0; i < sorted.length; i++) els[i] = sorted[i];
|
|
1001
1042
|
}
|
|
1002
1043
|
}, _class2);
|
|
1003
1044
|
|
|
@@ -1009,15 +1050,15 @@ var CanvasGeometry = (_class3 = class {
|
|
|
1009
1050
|
/** Last geometry {@link syncOverlay} wrote, so an unchanged frame can skip the
|
|
1010
1051
|
* style writes entirely. Cleared by {@link invalidateOverlay} to force the next
|
|
1011
1052
|
* sync (a new overlay layer was created and has never been positioned). */
|
|
1012
|
-
|
|
1013
|
-
constructor(canvas, a11yRoot, portalRoot) {;_class3.prototype.
|
|
1053
|
+
__init20() {this.overlayGeometry = null}
|
|
1054
|
+
constructor(canvas, a11yRoot, portalRoot) {;_class3.prototype.__init20.call(this);
|
|
1014
1055
|
this.canvas = canvas;
|
|
1015
1056
|
this.a11yRoot = a11yRoot;
|
|
1016
1057
|
this.portalRoot = portalRoot;
|
|
1017
1058
|
}
|
|
1018
1059
|
/** Convert browser viewport coordinates into the scene's logical coordinates. */
|
|
1019
1060
|
clientToScene(clientX, clientY, width, height) {
|
|
1020
|
-
const rect = _optionalChain([this, 'access',
|
|
1061
|
+
const rect = _optionalChain([this, 'access', _43 => _43.canvas, 'access', _44 => _44.getBoundingClientRect, 'optionalCall', _45 => _45()]);
|
|
1021
1062
|
if (!rect) return { x: clientX, y: clientY };
|
|
1022
1063
|
const cssWidth = rect.width || this.canvas.clientWidth || width;
|
|
1023
1064
|
const cssHeight = rect.height || this.canvas.clientHeight || height;
|
|
@@ -1029,8 +1070,11 @@ var CanvasGeometry = (_class3 = class {
|
|
|
1029
1070
|
/** Effective device pixel ratio, matching CanvasRenderer: real DPR clamped to
|
|
1030
1071
|
* `maxDPR` when set. */
|
|
1031
1072
|
effectiveDPR(maxDPR) {
|
|
1032
|
-
const
|
|
1033
|
-
|
|
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);
|
|
1034
1078
|
}
|
|
1035
1079
|
/** Size the WebGPU particle canvas: backing store at logical × DPR, CSS box at
|
|
1036
1080
|
* the logical size. Sizing the backing store in logical px (the old
|
|
@@ -1055,14 +1099,14 @@ var CanvasGeometry = (_class3 = class {
|
|
|
1055
1099
|
syncOverlay(width, height, glCanvas, gpuCanvas) {
|
|
1056
1100
|
const parent = this.canvas.parentElement;
|
|
1057
1101
|
if (!parent) return;
|
|
1058
|
-
const canvasRect = _optionalChain([this, 'access',
|
|
1059
|
-
const parentRect = _optionalChain([parent, 'access',
|
|
1060
|
-
const cssWidth = _optionalChain([canvasRect, 'optionalAccess',
|
|
1061
|
-
const cssHeight = _optionalChain([canvasRect, 'optionalAccess',
|
|
1102
|
+
const canvasRect = _optionalChain([this, 'access', _46 => _46.canvas, 'access', _47 => _47.getBoundingClientRect, 'optionalCall', _48 => _48()]);
|
|
1103
|
+
const parentRect = _optionalChain([parent, 'access', _49 => _49.getBoundingClientRect, 'optionalCall', _50 => _50()]);
|
|
1104
|
+
const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _51 => _51.width]) || this.canvas.clientWidth || width;
|
|
1105
|
+
const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _52 => _52.height]) || this.canvas.clientHeight || height;
|
|
1062
1106
|
const canvasPosition = typeof getComputedStyle === "function" ? getComputedStyle(this.canvas).position : "";
|
|
1063
1107
|
const position = canvasPosition === "fixed" ? "fixed" : "absolute";
|
|
1064
|
-
const left = position === "fixed" ? _nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess',
|
|
1065
|
-
const top = position === "fixed" ? _nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess',
|
|
1108
|
+
const left = position === "fixed" ? _nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _53 => _53.left]), () => ( 0)) : (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _54 => _54.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _55 => _55.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
|
|
1109
|
+
const top = position === "fixed" ? _nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _56 => _56.top]), () => ( 0)) : (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _57 => _57.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _58 => _58.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
|
|
1066
1110
|
const scaleX = width > 0 ? cssWidth / width : 1;
|
|
1067
1111
|
const scaleY = height > 0 ? cssHeight / height : 1;
|
|
1068
1112
|
const prev = this.overlayGeometry;
|
|
@@ -1100,12 +1144,12 @@ var CanvasGeometry = (_class3 = class {
|
|
|
1100
1144
|
}, _class3);
|
|
1101
1145
|
|
|
1102
1146
|
// src/tree/scene/DirtyTracker.ts
|
|
1103
|
-
var DirtyTracker = (_class4 = class _DirtyTracker {constructor() { _class4.prototype.
|
|
1147
|
+
var DirtyTracker = (_class4 = class _DirtyTracker {constructor() { _class4.prototype.__init21.call(this);_class4.prototype.__init22.call(this);_class4.prototype.__init23.call(this); }
|
|
1104
1148
|
/** Cap on distinct recorded dirty reasons (see {@link record}). */
|
|
1105
1149
|
static __initStatic() {this.MAX_DIRTY_REASONS = 200}
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1150
|
+
__init21() {this.tracking = false}
|
|
1151
|
+
__init22() {this.reasons = /* @__PURE__ */ new Map()}
|
|
1152
|
+
__init23() {this.isDirty = true}
|
|
1109
1153
|
/** Whether the next frame must redraw. */
|
|
1110
1154
|
get dirty() {
|
|
1111
1155
|
return this.isDirty;
|
|
@@ -1187,20 +1231,20 @@ var DriverTicker = (_class5 = class {
|
|
|
1187
1231
|
// an entity whose drivers have since all completed or been removed. This is
|
|
1188
1232
|
// what lets the batch pass find its candidates in O(active drivers), not
|
|
1189
1233
|
// O(tree size) — the exact mistake G3's first integrated benchmark made.
|
|
1190
|
-
|
|
1234
|
+
__init24() {this.activeEntities = /* @__PURE__ */ new Set()}
|
|
1191
1235
|
// Reused across frames instead of allocating a fresh array + N {entity,prop,
|
|
1192
1236
|
// driver} objects every call — the integrated benchmark
|
|
1193
1237
|
// (benchmarks/anim-wasm-scene) found that allocation churn was the
|
|
1194
1238
|
// dominant integrated cost, not the wasm kernel itself. Parallel arrays,
|
|
1195
1239
|
// truncated to the live count after each use so a stale tail slot never
|
|
1196
1240
|
// pins a no-longer-active entity/driver in memory.
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
constructor(backends) {;_class5.prototype.
|
|
1241
|
+
__init25() {this.springEntities = []}
|
|
1242
|
+
__init26() {this.springProps = []}
|
|
1243
|
+
__init27() {this.springDrivers = []}
|
|
1244
|
+
__init28() {this.tweenEntities = []}
|
|
1245
|
+
__init29() {this.tweenProps = []}
|
|
1246
|
+
__init30() {this.tweenDrivers = []}
|
|
1247
|
+
constructor(backends) {;_class5.prototype.__init24.call(this);_class5.prototype.__init25.call(this);_class5.prototype.__init26.call(this);_class5.prototype.__init27.call(this);_class5.prototype.__init28.call(this);_class5.prototype.__init29.call(this);_class5.prototype.__init30.call(this);
|
|
1204
1248
|
this.backends = backends;
|
|
1205
1249
|
}
|
|
1206
1250
|
/** The candidate set, for the delegating accessor `Scene` keeps for its tests. */
|
|
@@ -1328,6 +1372,8 @@ var DriverTicker = (_class5 = class {
|
|
|
1328
1372
|
tD.length = tweenCount;
|
|
1329
1373
|
backend.ensure(springCount, tweenCount);
|
|
1330
1374
|
backend.revalidateViews();
|
|
1375
|
+
let springsRejected = false;
|
|
1376
|
+
let tweensRejected = false;
|
|
1331
1377
|
if (springCount > 0) {
|
|
1332
1378
|
const sv = backend.springView();
|
|
1333
1379
|
for (let i = 0; i < springCount; i++) {
|
|
@@ -1343,8 +1389,7 @@ var DriverTicker = (_class5 = class {
|
|
|
1343
1389
|
for (let i = 0; i < springCount; i++) sD[i].syncExternal(sv.val[i], sv.vel[i]);
|
|
1344
1390
|
} else {
|
|
1345
1391
|
for (let i = 0; i < springCount; i++) sD[i].tick(dt);
|
|
1346
|
-
|
|
1347
|
-
this.backends.animBatchedLastFrame = false;
|
|
1392
|
+
springsRejected = true;
|
|
1348
1393
|
}
|
|
1349
1394
|
}
|
|
1350
1395
|
if (tweenCount > 0) {
|
|
@@ -1362,10 +1407,13 @@ var DriverTicker = (_class5 = class {
|
|
|
1362
1407
|
for (let i = 0; i < tweenCount; i++) tD[i].syncExternal(tv.val[i], tv.elapsed[i]);
|
|
1363
1408
|
} else {
|
|
1364
1409
|
for (let i = 0; i < tweenCount; i++) tD[i].tick(dt);
|
|
1365
|
-
|
|
1366
|
-
this.backends.animBatchedLastFrame = false;
|
|
1410
|
+
tweensRejected = true;
|
|
1367
1411
|
}
|
|
1368
1412
|
}
|
|
1413
|
+
if (springsRejected || tweensRejected) {
|
|
1414
|
+
this.backends.animReason = springsRejected && tweensRejected ? "rejected" : springsRejected ? "springs-rejected" : "tweens-rejected";
|
|
1415
|
+
this.backends.animBatchedLastFrame = springCount > 0 && !springsRejected || tweenCount > 0 && !tweensRejected;
|
|
1416
|
+
}
|
|
1369
1417
|
for (let i = 0; i < springCount; i++) sE[i]._applyDriverTick(sP[i], sD[i]);
|
|
1370
1418
|
for (let i = 0; i < tweenCount; i++) tE[i]._applyDriverTick(tP[i], tD[i]);
|
|
1371
1419
|
}
|
|
@@ -1526,20 +1574,17 @@ function intersectBounds(a, b) {
|
|
|
1526
1574
|
height: Math.max(0, bottom - y)
|
|
1527
1575
|
};
|
|
1528
1576
|
}
|
|
1529
|
-
function pointInBounds(b, x, y) {
|
|
1530
|
-
return x >= b.x && x <= b.x + b.width && y >= b.y && y <= b.y + b.height;
|
|
1531
|
-
}
|
|
1532
1577
|
var HitTester = (_class6 = class {
|
|
1533
1578
|
|
|
1534
1579
|
|
|
1535
1580
|
|
|
1536
1581
|
/** Slot index → entity, as built by the most recent grid build. */
|
|
1537
|
-
|
|
1582
|
+
__init31() {this.slotEntity = []}
|
|
1538
1583
|
/** Entities with no `getBounds()`, which the grid cannot index. */
|
|
1539
|
-
|
|
1584
|
+
__init32() {this.boundless = []}
|
|
1540
1585
|
/** Reused buffer for the fused gather, so a pointer query allocates nothing. */
|
|
1541
|
-
|
|
1542
|
-
constructor(root, overlayRoot, backends) {;_class6.prototype.
|
|
1586
|
+
__init33() {this.gatherBuffer = null}
|
|
1587
|
+
constructor(root, overlayRoot, backends) {;_class6.prototype.__init31.call(this);_class6.prototype.__init32.call(this);_class6.prototype.__init33.call(this);
|
|
1543
1588
|
this.root = root;
|
|
1544
1589
|
this.overlayRoot = overlayRoot;
|
|
1545
1590
|
this.backends = backends;
|
|
@@ -1575,7 +1620,7 @@ var HitTester = (_class6 = class {
|
|
|
1575
1620
|
this.backends.hitReason = "not-installed";
|
|
1576
1621
|
return false;
|
|
1577
1622
|
}
|
|
1578
|
-
if (this.backends.hitGridFrame === frame) {
|
|
1623
|
+
if (this.backends.hitGridFrame === frame && this.backends.hitGridStructureVersion === this.backends.structureVersion) {
|
|
1579
1624
|
return this.backends.hitGridOk;
|
|
1580
1625
|
}
|
|
1581
1626
|
let gathered = null;
|
|
@@ -1606,6 +1651,7 @@ var HitTester = (_class6 = class {
|
|
|
1606
1651
|
this.slotEntity = gathered.slotEntity;
|
|
1607
1652
|
this.boundless = gathered.boundless;
|
|
1608
1653
|
this.backends.hitGridFrame = frame;
|
|
1654
|
+
this.backends.hitGridStructureVersion = this.backends.structureVersion;
|
|
1609
1655
|
this.backends.hitGridOk = ok;
|
|
1610
1656
|
this.backends.hitReason = ok ? "active" : "rejected";
|
|
1611
1657
|
return ok;
|
|
@@ -1630,7 +1676,7 @@ var HitTester = (_class6 = class {
|
|
|
1630
1676
|
const idx = cell[k];
|
|
1631
1677
|
if (x < minx[idx] || x > maxx[idx] || y < miny[idx] || y > maxy[idx]) continue;
|
|
1632
1678
|
const entity = this.slotEntity[idx];
|
|
1633
|
-
if (_optionalChain([entity, 'optionalAccess',
|
|
1679
|
+
if (_optionalChain([entity, 'optionalAccess', _59 => _59.isPointInside, 'call', _60 => _60(x, y)]) && this.isHitEligible(entity, x, y)) {
|
|
1634
1680
|
bestIndex = idx;
|
|
1635
1681
|
bestEntity = entity;
|
|
1636
1682
|
break;
|
|
@@ -1656,7 +1702,7 @@ var HitTester = (_class6 = class {
|
|
|
1656
1702
|
const hit = this.findHitRecursively(node.children[i], x, y, childClip);
|
|
1657
1703
|
if (hit) return hit;
|
|
1658
1704
|
}
|
|
1659
|
-
if (node.isPointInside && node.isPointInside(x, y) && (
|
|
1705
|
+
if (node.isPointInside && node.isPointInside(x, y) && this.isInsideAllClippers(node, x, y) && !this.isPointerTransparent(node)) {
|
|
1660
1706
|
return node;
|
|
1661
1707
|
}
|
|
1662
1708
|
return null;
|
|
@@ -1668,6 +1714,25 @@ var HitTester = (_class6 = class {
|
|
|
1668
1714
|
const attrs = node.getA11yAttributes();
|
|
1669
1715
|
return attrs.disabled === true || attrs.pointerEvents === "none";
|
|
1670
1716
|
}
|
|
1717
|
+
/**
|
|
1718
|
+
* Exact rotation-aware `clipChildren` test shared by BOTH hit paths: the
|
|
1719
|
+
* point must lie inside every clipChildren ancestor's local rect — the same
|
|
1720
|
+
* shape rendering clips to — not merely inside the ancestor's world AABB.
|
|
1721
|
+
* For a rotated clipper those disagree, and until both paths used the exact
|
|
1722
|
+
* rect a query's answer depended on which backend was active (#680). The
|
|
1723
|
+
* clip-stack AABB intersection in {@link findHitRecursively} remains purely
|
|
1724
|
+
* as a subtree-pruning pre-filter; this is the authoritative gate.
|
|
1725
|
+
*/
|
|
1726
|
+
isInsideAllClippers(node, x, y) {
|
|
1727
|
+
for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
|
|
1728
|
+
if (!ancestor.clipChildren) continue;
|
|
1729
|
+
const local = ancestor.worldToLocal(x, y);
|
|
1730
|
+
if (!local || local.x < 0 || local.y < 0 || local.x > ancestor.width || local.y > ancestor.height) {
|
|
1731
|
+
return false;
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
return true;
|
|
1735
|
+
}
|
|
1671
1736
|
/**
|
|
1672
1737
|
* Whether a confirmed geometric hit on `node` at world `(x, y)` is a REAL hit,
|
|
1673
1738
|
* applying the same visibility/input gating as {@link findHitRecursively} but
|
|
@@ -1682,14 +1747,8 @@ var HitTester = (_class6 = class {
|
|
|
1682
1747
|
if (node.opacity <= 0) return false;
|
|
1683
1748
|
for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
|
|
1684
1749
|
if (ancestor.opacity <= 0) return false;
|
|
1685
|
-
if (ancestor.clipChildren && ancestor.width > 0 && ancestor.height > 0) {
|
|
1686
|
-
const local = ancestor.worldToLocal(x, y);
|
|
1687
|
-
if (!local || local.x < 0 || local.y < 0 || local.x > ancestor.width || local.y > ancestor.height) {
|
|
1688
|
-
return false;
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
1750
|
}
|
|
1692
|
-
return
|
|
1751
|
+
return this.isInsideAllClippers(node, x, y);
|
|
1693
1752
|
}
|
|
1694
1753
|
}, _class6);
|
|
1695
1754
|
|
|
@@ -1709,9 +1768,9 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1709
1768
|
* Mid-drag the browser is authoritative, so a rebuild must not try to preserve
|
|
1710
1769
|
* anything.
|
|
1711
1770
|
*/
|
|
1712
|
-
|
|
1771
|
+
__init34() {this.blankRegionDrag = false}
|
|
1713
1772
|
/** Tracked drag anchor. Survives a drag, unlike the live DOM selection. */
|
|
1714
|
-
|
|
1773
|
+
__init35() {this.anchor = null}
|
|
1715
1774
|
/**
|
|
1716
1775
|
* Memo for {@link selectionPresent}, valid for one sync walk.
|
|
1717
1776
|
*
|
|
@@ -1719,20 +1778,20 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1719
1778
|
* is resolved once per walk rather than once per rebuilt element. `null` means
|
|
1720
1779
|
* "not yet asked this walk".
|
|
1721
1780
|
*/
|
|
1722
|
-
|
|
1781
|
+
__init36() {this.presentThisSync = null}
|
|
1723
1782
|
// --- grid calibration ------------------------------------------------------
|
|
1724
1783
|
/** Pending calibration rAF handle per projected grid entity. */
|
|
1725
|
-
|
|
1784
|
+
__init37() {this.calibrationFrameHandles = /* @__PURE__ */ new Map()}
|
|
1726
1785
|
/** Detached, untransformed font probes used by the cold calibration pass. */
|
|
1727
|
-
|
|
1786
|
+
__init38() {this.calibrationProbes = /* @__PURE__ */ new Map()}
|
|
1728
1787
|
/**
|
|
1729
1788
|
* Bumped when the conditions a measurement depends on change, which
|
|
1730
1789
|
* invalidates every existing per-cell `scaleX` at once without touching them.
|
|
1731
1790
|
*/
|
|
1732
|
-
|
|
1791
|
+
__init39() {this.calibrationGeneration = 0}
|
|
1733
1792
|
/** The conditions the current generation was measured under. */
|
|
1734
|
-
|
|
1735
|
-
constructor(a11yRoot, phases) {;_class7.prototype.
|
|
1793
|
+
__init40() {this.calibrationStamp = ""}
|
|
1794
|
+
constructor(a11yRoot, phases) {;_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_class7.prototype.__init40.call(this);
|
|
1736
1795
|
this.a11yRoot = a11yRoot;
|
|
1737
1796
|
this.phases = phases;
|
|
1738
1797
|
}
|
|
@@ -1786,16 +1845,16 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1786
1845
|
* to the live DOM selection.
|
|
1787
1846
|
*/
|
|
1788
1847
|
gridSelectionLine(el) {
|
|
1789
|
-
const candidates = [_optionalChain([this, 'access',
|
|
1848
|
+
const candidates = [_optionalChain([this, 'access', _61 => _61.anchor, 'optionalAccess', _62 => _62.node])];
|
|
1790
1849
|
if (typeof window !== "undefined" && typeof window.getSelection === "function") {
|
|
1791
1850
|
const selection = window.getSelection();
|
|
1792
|
-
candidates.push(_optionalChain([selection, 'optionalAccess',
|
|
1851
|
+
candidates.push(_optionalChain([selection, 'optionalAccess', _63 => _63.anchorNode]), _optionalChain([selection, 'optionalAccess', _64 => _64.focusNode]));
|
|
1793
1852
|
}
|
|
1794
1853
|
for (const candidate of candidates) {
|
|
1795
1854
|
if (!candidate || !el.contains(candidate)) continue;
|
|
1796
1855
|
let cursor = candidate;
|
|
1797
1856
|
while (cursor && cursor.parentNode !== el) cursor = cursor.parentNode;
|
|
1798
|
-
const lineIndex = _optionalChain([cursor, 'optionalAccess',
|
|
1857
|
+
const lineIndex = _optionalChain([cursor, 'optionalAccess', _65 => _65.dataset, 'optionalAccess', _66 => _66.vectoGridLine]);
|
|
1799
1858
|
if (lineIndex !== void 0) return Number(lineIndex);
|
|
1800
1859
|
}
|
|
1801
1860
|
return null;
|
|
@@ -1820,10 +1879,10 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1820
1879
|
releaseSelectionForRebuild(el) {
|
|
1821
1880
|
if (!this.anchor && !this.selectionPresent()) return;
|
|
1822
1881
|
const selection = typeof window !== "undefined" && typeof window.getSelection === "function" ? window.getSelection() : null;
|
|
1823
|
-
const ownsSelection = this.anchor && el.contains(this.anchor.node) || (_optionalChain([selection, 'optionalAccess',
|
|
1882
|
+
const ownsSelection = this.anchor && el.contains(this.anchor.node) || (_optionalChain([selection, 'optionalAccess', _67 => _67.anchorNode]) ? el.contains(selection.anchorNode) : false) || (_optionalChain([selection, 'optionalAccess', _68 => _68.focusNode]) ? el.contains(selection.focusNode) : false);
|
|
1824
1883
|
if (!ownsSelection) return;
|
|
1825
1884
|
this.endDrag();
|
|
1826
|
-
_optionalChain([selection, 'optionalAccess',
|
|
1885
|
+
_optionalChain([selection, 'optionalAccess', _69 => _69.removeAllRanges, 'call', _70 => _70()]);
|
|
1827
1886
|
this.presentThisSync = null;
|
|
1828
1887
|
}
|
|
1829
1888
|
/**
|
|
@@ -1898,7 +1957,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1898
1957
|
let cursor = node;
|
|
1899
1958
|
while (cursor && cursor !== el) {
|
|
1900
1959
|
const cell = cursor;
|
|
1901
|
-
const start = _optionalChain([cell, 'access',
|
|
1960
|
+
const start = _optionalChain([cell, 'access', _71 => _71.dataset, 'optionalAccess', _72 => _72.vectoGridSourceStart]);
|
|
1902
1961
|
if (start !== void 0) {
|
|
1903
1962
|
const sourceStart = Number(start);
|
|
1904
1963
|
const sourceLength = Number(_nullishCoalesce(cell.dataset.vectoGridSourceLength, () => ( 0)));
|
|
@@ -1992,7 +2051,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1992
2051
|
cancelAnimationFrame(calibrationFrame);
|
|
1993
2052
|
}
|
|
1994
2053
|
this.calibrationFrameHandles.delete(entityId);
|
|
1995
|
-
_optionalChain([this, 'access',
|
|
2054
|
+
_optionalChain([this, 'access', _73 => _73.calibrationProbes, 'access', _74 => _74.get, 'call', _75 => _75(entityId), 'optionalAccess', _76 => _76.remove, 'call', _77 => _77()]);
|
|
1996
2055
|
this.calibrationProbes.delete(entityId);
|
|
1997
2056
|
delete el.dataset.vectoGridCalibrationPending;
|
|
1998
2057
|
delete el.dataset.vectoGridCalibration;
|
|
@@ -2056,7 +2115,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
2056
2115
|
if (previous !== void 0 && typeof cancelAnimationFrame === "function") {
|
|
2057
2116
|
cancelAnimationFrame(previous);
|
|
2058
2117
|
}
|
|
2059
|
-
_optionalChain([this, 'access',
|
|
2118
|
+
_optionalChain([this, 'access', _78 => _78.calibrationProbes, 'access', _79 => _79.get, 'call', _80 => _80(entityId), 'optionalAccess', _81 => _81.remove, 'call', _82 => _82()]);
|
|
2060
2119
|
this.calibrationProbes.delete(entityId);
|
|
2061
2120
|
const calibrationStart = typeof performance !== "undefined" ? performance.now() : 0;
|
|
2062
2121
|
const probe = document.createElement("div");
|
|
@@ -2090,7 +2149,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
2090
2149
|
target.dataset.vectoGridCalib = generation;
|
|
2091
2150
|
continue;
|
|
2092
2151
|
}
|
|
2093
|
-
const sourceText = _nullishCoalesce(_optionalChain([target, 'access',
|
|
2152
|
+
const sourceText = _nullishCoalesce(_optionalChain([target, 'access', _83 => _83.textContent, 'optionalAccess', _84 => _84.slice, 'call', _85 => _85(0, sourceLength)]), () => ( ""));
|
|
2094
2153
|
if (!sourceText) {
|
|
2095
2154
|
target.dataset.vectoGridCalib = generation;
|
|
2096
2155
|
continue;
|
|
@@ -2201,17 +2260,17 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
2201
2260
|
}, _class7);
|
|
2202
2261
|
|
|
2203
2262
|
// src/tree/scene/PhaseTimer.ts
|
|
2204
|
-
var PhaseTimer = (_class8 = class {constructor() { _class8.prototype.
|
|
2263
|
+
var PhaseTimer = (_class8 = class {constructor() { _class8.prototype.__init41.call(this);_class8.prototype.__init42.call(this);_class8.prototype.__init43.call(this); }
|
|
2205
2264
|
/**
|
|
2206
2265
|
* Whether per-phase timing is being recorded.
|
|
2207
2266
|
*
|
|
2208
2267
|
* A field rather than an accessor: it is tested on the frame path once per
|
|
2209
2268
|
* probe, and the disabled cost has to be a single boolean read.
|
|
2210
2269
|
*/
|
|
2211
|
-
|
|
2270
|
+
__init41() {this.enabled = false}
|
|
2212
2271
|
/** Whether browser User Timing instrumentation is enabled. */
|
|
2213
|
-
|
|
2214
|
-
|
|
2272
|
+
__init42() {this.userTiming = false}
|
|
2273
|
+
__init43() {this.totals = /* @__PURE__ */ new Map()}
|
|
2215
2274
|
/** Start or stop recording. Disabling also drops what was collected. */
|
|
2216
2275
|
setEnabled(enabled) {
|
|
2217
2276
|
this.enabled = enabled;
|
|
@@ -2389,10 +2448,10 @@ function viewsStale(cap, probe, memory) {
|
|
|
2389
2448
|
}
|
|
2390
2449
|
var PAD2 = 8;
|
|
2391
2450
|
var WasmTransformBackend = (_class9 = class {
|
|
2392
|
-
|
|
2451
|
+
__init44() {this.available = true}
|
|
2393
2452
|
|
|
2394
|
-
|
|
2395
|
-
|
|
2453
|
+
__init45() {this.cap = 0}
|
|
2454
|
+
__init46() {this.runCap = 0}
|
|
2396
2455
|
// Views over wasm linear memory, valid until the next init().
|
|
2397
2456
|
|
|
2398
2457
|
|
|
@@ -2419,7 +2478,7 @@ var WasmTransformBackend = (_class9 = class {
|
|
|
2419
2478
|
|
|
2420
2479
|
|
|
2421
2480
|
|
|
2422
|
-
constructor(instance) {;_class9.prototype.
|
|
2481
|
+
constructor(instance) {;_class9.prototype.__init44.call(this);_class9.prototype.__init45.call(this);_class9.prototype.__init46.call(this);_class9.prototype.__init47.call(this);
|
|
2423
2482
|
this.ex = instance.exports;
|
|
2424
2483
|
}
|
|
2425
2484
|
/** Compose world matrices for `store` in WASM, writing back into its
|
|
@@ -2442,7 +2501,8 @@ var WasmTransformBackend = (_class9 = class {
|
|
|
2442
2501
|
this.lastStatus = WASM_STATUS.CAPACITY;
|
|
2443
2502
|
return;
|
|
2444
2503
|
}
|
|
2445
|
-
const
|
|
2504
|
+
const simd = kernel === "simd" && typeof this.ex.compose_simd === "function";
|
|
2505
|
+
const status = simd ? this.ex.compose_simd() : this.ex.compose_scalar();
|
|
2446
2506
|
this.lastStatus = status;
|
|
2447
2507
|
if (status !== WASM_STATUS.OK) return;
|
|
2448
2508
|
store.wa.set(this.vwa.subarray(0, n));
|
|
@@ -2464,7 +2524,8 @@ var WasmTransformBackend = (_class9 = class {
|
|
|
2464
2524
|
* {@link uploadRuns} after a topology change.
|
|
2465
2525
|
*/
|
|
2466
2526
|
runKernel(kernel = "simd") {
|
|
2467
|
-
const
|
|
2527
|
+
const simd = kernel === "simd" && typeof this.ex.compose_simd === "function";
|
|
2528
|
+
const status = simd ? this.ex.compose_simd() : this.ex.compose_scalar();
|
|
2468
2529
|
this.lastStatus = status;
|
|
2469
2530
|
return status;
|
|
2470
2531
|
}
|
|
@@ -2486,7 +2547,7 @@ var WasmTransformBackend = (_class9 = class {
|
|
|
2486
2547
|
* Status of the most recent kernel or run-table call. `WASM_STATUS.OK` unless
|
|
2487
2548
|
* the crate rejected its arguments, in which case that call was a no-op.
|
|
2488
2549
|
*/
|
|
2489
|
-
|
|
2550
|
+
__init47() {this.lastStatus = WASM_STATUS.OK}
|
|
2490
2551
|
/** The resident wasm input views (`x,y,sx,sy,cos,sin,opacity`), valid until
|
|
2491
2552
|
* the next capacity growth. Writing here is what makes uploads unnecessary. */
|
|
2492
2553
|
inputView() {
|
|
@@ -2516,21 +2577,21 @@ var WasmTransformBackend = (_class9 = class {
|
|
|
2516
2577
|
/**
|
|
2517
2578
|
* Compute world-space AABBs for `store` in WASM (G1+), writing back into its
|
|
2518
2579
|
* `aminx/aminy/amaxx/amaxy` arrays. Uploads the local bounds, runs the AABB
|
|
2519
|
-
* pass, reads results back. Result is bit-identical to `computeAabbsJS(store)
|
|
2520
|
-
* `compose` (or `runKernel`) must have populated the world
|
|
2521
|
-
* this pass reads them. For the resident (no-copy)
|
|
2522
|
-
* via {@link boundsView} and read via
|
|
2523
|
-
* {@link runAabbs} instead.
|
|
2580
|
+
* pass, reads results back. Result is bit-identical to `computeAabbsJS(store)`
|
|
2581
|
+
* for both kernels. `compose` (or `runKernel`) must have populated the world
|
|
2582
|
+
* matrices first — this pass reads them. For the resident (no-copy)
|
|
2583
|
+
* integration, write bounds via {@link boundsView} and read via
|
|
2584
|
+
* {@link aabbView} + call {@link runAabbs} instead.
|
|
2524
2585
|
*/
|
|
2525
|
-
computeAabbs(store) {
|
|
2586
|
+
computeAabbs(store, kernel = "simd") {
|
|
2526
2587
|
this.ensure(store.count, store.runCount);
|
|
2527
2588
|
const n = store.count;
|
|
2528
2589
|
this.vbx.set(store.bx.subarray(0, n));
|
|
2529
2590
|
this.vby.set(store.by.subarray(0, n));
|
|
2530
2591
|
this.vbw.set(store.bw.subarray(0, n));
|
|
2531
2592
|
this.vbh.set(store.bh.subarray(0, n));
|
|
2532
|
-
|
|
2533
|
-
if (
|
|
2593
|
+
const ok = this.runAabbs(n, kernel);
|
|
2594
|
+
if (!ok) return;
|
|
2534
2595
|
store.aminx.set(this.vaminx.subarray(0, n));
|
|
2535
2596
|
store.aminy.set(this.vaminy.subarray(0, n));
|
|
2536
2597
|
store.amaxx.set(this.vamaxx.subarray(0, n));
|
|
@@ -2541,8 +2602,9 @@ var WasmTransformBackend = (_class9 = class {
|
|
|
2541
2602
|
* composed). No upload/readback — the per-frame resident path. Returns
|
|
2542
2603
|
* `false` if the kernel rejected `count` (beyond capacity, or uninitialized),
|
|
2543
2604
|
* in which case {@link aabbView} still holds the previous frame's bounds. */
|
|
2544
|
-
runAabbs(count) {
|
|
2545
|
-
|
|
2605
|
+
runAabbs(count, kernel = "simd") {
|
|
2606
|
+
const simd = kernel === "simd" && typeof this.ex.compute_aabbs_simd === "function";
|
|
2607
|
+
this.lastStatus = simd ? this.ex.compute_aabbs_simd(count) : this.ex.compute_aabbs(count);
|
|
2546
2608
|
return this.lastStatus === WASM_STATUS.OK;
|
|
2547
2609
|
}
|
|
2548
2610
|
/** Resident wasm local-bounds input views (`bx,by,bw,bh`) for the AABB pass. */
|
|
@@ -2627,11 +2689,11 @@ var WasmTransformBackend = (_class9 = class {
|
|
|
2627
2689
|
var PAD3 = 8;
|
|
2628
2690
|
var AnimBackend = (_class10 = class {
|
|
2629
2691
|
|
|
2630
|
-
|
|
2631
|
-
|
|
2692
|
+
__init48() {this.springCap = 0}
|
|
2693
|
+
__init49() {this.tweenCap = 0}
|
|
2632
2694
|
|
|
2633
2695
|
|
|
2634
|
-
constructor(instance) {;_class10.prototype.
|
|
2696
|
+
constructor(instance) {;_class10.prototype.__init48.call(this);_class10.prototype.__init49.call(this);_class10.prototype.__init50.call(this);
|
|
2635
2697
|
this.ex = instance.exports;
|
|
2636
2698
|
}
|
|
2637
2699
|
/** The resident spring SoA input/output views, valid until the next capacity
|
|
@@ -2698,7 +2760,7 @@ var AnimBackend = (_class10 = class {
|
|
|
2698
2760
|
* Status of the most recent kernel call — `WASM_STATUS.OK` unless the kernel
|
|
2699
2761
|
* declined it. Mirrors {@link TransformBackend.lastStatus}.
|
|
2700
2762
|
*/
|
|
2701
|
-
|
|
2763
|
+
__init50() {this.lastStatus = WASM_STATUS.OK}
|
|
2702
2764
|
refreshViews() {
|
|
2703
2765
|
const buf = this.ex.memory.buffer;
|
|
2704
2766
|
const sCap = this.springCap;
|
|
@@ -2728,9 +2790,9 @@ var PAD4 = 8;
|
|
|
2728
2790
|
var CELLS_PER_ENTITY_HINT = 4;
|
|
2729
2791
|
var HitTestBackend = (_class11 = class {
|
|
2730
2792
|
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2793
|
+
__init51() {this.entityCap = 0}
|
|
2794
|
+
__init52() {this.cellCap = 0}
|
|
2795
|
+
__init53() {this.itemCap = 0}
|
|
2734
2796
|
|
|
2735
2797
|
|
|
2736
2798
|
|
|
@@ -2739,10 +2801,10 @@ var HitTestBackend = (_class11 = class {
|
|
|
2739
2801
|
|
|
2740
2802
|
|
|
2741
2803
|
/** Grid geometry from the last {@link ensure} call. */
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
constructor(instance) {;_class11.prototype.
|
|
2804
|
+
__init54() {this.gridW = 0}
|
|
2805
|
+
__init55() {this.gridH = 0}
|
|
2806
|
+
__init56() {this.cellSize = 64}
|
|
2807
|
+
constructor(instance) {;_class11.prototype.__init51.call(this);_class11.prototype.__init52.call(this);_class11.prototype.__init53.call(this);_class11.prototype.__init54.call(this);_class11.prototype.__init55.call(this);_class11.prototype.__init56.call(this);
|
|
2746
2808
|
this.ex = instance.exports;
|
|
2747
2809
|
}
|
|
2748
2810
|
/** The resident AABB input views (`minx/miny/maxx/maxy`), valid until the
|
|
@@ -2843,9 +2905,9 @@ var HitTestBackend = (_class11 = class {
|
|
|
2843
2905
|
var PAD5 = 8;
|
|
2844
2906
|
var ParticleBackend = (_class12 = class {
|
|
2845
2907
|
|
|
2846
|
-
|
|
2908
|
+
__init57() {this.cap = 0}
|
|
2847
2909
|
|
|
2848
|
-
constructor(instance) {;_class12.prototype.
|
|
2910
|
+
constructor(instance) {;_class12.prototype.__init57.call(this);_class12.prototype.__init58.call(this);
|
|
2849
2911
|
this.ex = instance.exports;
|
|
2850
2912
|
}
|
|
2851
2913
|
/** The resident SoA views, valid until the next capacity growth. */
|
|
@@ -2916,7 +2978,7 @@ var ParticleBackend = (_class12 = class {
|
|
|
2916
2978
|
* Status of the most recent {@link step} — `WASM_STATUS.OK` unless the kernel
|
|
2917
2979
|
* declined it. Mirrors {@link TransformBackend.lastStatus}.
|
|
2918
2980
|
*/
|
|
2919
|
-
|
|
2981
|
+
__init58() {this.lastStatus = WASM_STATUS.OK}
|
|
2920
2982
|
/** Transpose the AoS stride-8 buffer into the SoA views (position/velocity/
|
|
2921
2983
|
* life every frame; origin upload-once when `withOrigin`). */
|
|
2922
2984
|
gather(data, count, withOrigin) {
|
|
@@ -3007,11 +3069,11 @@ async function loadCoreWasmModule(source) {
|
|
|
3007
3069
|
}
|
|
3008
3070
|
var CoreWasmRuntime = (_class13 = class {
|
|
3009
3071
|
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
constructor(instance) {;_class13.prototype.
|
|
3072
|
+
__init59() {this.transformBackend = null}
|
|
3073
|
+
__init60() {this.animBackend = null}
|
|
3074
|
+
__init61() {this.hitBackend = null}
|
|
3075
|
+
__init62() {this.particleBackendInstance = null}
|
|
3076
|
+
constructor(instance) {;_class13.prototype.__init59.call(this);_class13.prototype.__init60.call(this);_class13.prototype.__init61.call(this);_class13.prototype.__init62.call(this);
|
|
3015
3077
|
this.instance = instance;
|
|
3016
3078
|
}
|
|
3017
3079
|
/**
|
|
@@ -3063,7 +3125,7 @@ var WasmBackendFacade = (_class14 = class {
|
|
|
3063
3125
|
* path, so the overlay root is not needed here.
|
|
3064
3126
|
*/
|
|
3065
3127
|
|
|
3066
|
-
constructor(root) {;_class14.prototype.
|
|
3128
|
+
constructor(root) {;_class14.prototype.__init63.call(this);_class14.prototype.__init64.call(this);_class14.prototype.__init65.call(this);_class14.prototype.__init66.call(this);_class14.prototype.__init67.call(this);_class14.prototype.__init68.call(this);_class14.prototype.__init69.call(this);_class14.prototype.__init70.call(this);_class14.prototype.__init71.call(this);_class14.prototype.__init72.call(this);_class14.prototype.__init73.call(this);_class14.prototype.__init74.call(this);_class14.prototype.__init75.call(this);_class14.prototype.__init76.call(this);_class14.prototype.__init77.call(this);_class14.prototype.__init78.call(this);_class14.prototype.__init79.call(this);_class14.prototype.__init80.call(this);_class14.prototype.__init81.call(this);_class14.prototype.__init82.call(this);_class14.prototype.__init83.call(this);_class14.prototype.__init84.call(this);_class14.prototype.__init85.call(this);_class14.prototype.__init86.call(this);_class14.prototype.__init87.call(this);
|
|
3067
3129
|
this.root = root;
|
|
3068
3130
|
}
|
|
3069
3131
|
// ── WASM transform backend (invisible accelerator) ──────────────────────────
|
|
@@ -3073,34 +3135,34 @@ var WasmBackendFacade = (_class14 = class {
|
|
|
3073
3135
|
// default: a null backend, a non-main renderer, or any entity absent from the
|
|
3074
3136
|
// store all fall back to the JS composition, so WASM can only ever change
|
|
3075
3137
|
// *how fast* a world matrix is produced, never *what* it is.
|
|
3076
|
-
|
|
3077
|
-
|
|
3138
|
+
__init63() {this._transform = null}
|
|
3139
|
+
__init64() {this._mode = "js"}
|
|
3078
3140
|
// Resident store state (Stage 3). The store layout — slot assignment + sibling
|
|
3079
3141
|
// runs — depends only on tree TOPOLOGY, so it is rebuilt only when the
|
|
3080
3142
|
// structure changes (add/remove/reparent bump `structureVersion`). Between
|
|
3081
3143
|
// rebuilds the per-frame cost is: gather each entity's transform into the
|
|
3082
3144
|
// resident wasm input view + run the kernel — no reallocation, no readback.
|
|
3083
|
-
|
|
3084
|
-
|
|
3145
|
+
__init65() {this._treeStore = null}
|
|
3146
|
+
__init66() {this._slotEntity = []}
|
|
3085
3147
|
// store slot -> entity (also validates slots)
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3148
|
+
__init67() {this._inputs = null}
|
|
3149
|
+
__init68() {this._world = null}
|
|
3150
|
+
__init69() {this._structureVersion = 0}
|
|
3151
|
+
__init70() {this._storeStructureVersion = -1}
|
|
3090
3152
|
/**
|
|
3091
3153
|
* Consecutive `uploadRuns` rejections. Reset by any success and by
|
|
3092
3154
|
* {@link setTransform}; at {@link WASM_UPLOAD_REJECT_LIMIT} the backend mode
|
|
3093
3155
|
* flips to `'js'` permanently.
|
|
3094
3156
|
*/
|
|
3095
|
-
|
|
3157
|
+
__init71() {this._uploadRejections = 0}
|
|
3096
3158
|
/** Latch for the permanent-fallback warning, which fires from a per-frame path. */
|
|
3097
|
-
|
|
3159
|
+
__init72() {this.hasWarnedUploadFallback = false}
|
|
3098
3160
|
/**
|
|
3099
3161
|
* Whether `compute_aabbs` has run against the current frame's world matrices.
|
|
3100
3162
|
* The AABB pass is only meaningful after a `compose_*`, so the fused gather
|
|
3101
3163
|
* must not read the views before then.
|
|
3102
3164
|
*/
|
|
3103
|
-
|
|
3165
|
+
__init73() {this._aabbsFresh = false}
|
|
3104
3166
|
/** The installed transform backend, or `null` on the JS path. */
|
|
3105
3167
|
get transform() {
|
|
3106
3168
|
return this._transform;
|
|
@@ -3165,7 +3227,7 @@ var WasmBackendFacade = (_class14 = class {
|
|
|
3165
3227
|
* cached globally; the instance is per-Scene, which is the isolation that
|
|
3166
3228
|
* actually matters.
|
|
3167
3229
|
*/
|
|
3168
|
-
|
|
3230
|
+
__init74() {this._runtime = null}
|
|
3169
3231
|
/** The shared WASM runtime, if one has been loaded. */
|
|
3170
3232
|
get runtime() {
|
|
3171
3233
|
return this._runtime;
|
|
@@ -3194,9 +3256,9 @@ var WasmBackendFacade = (_class14 = class {
|
|
|
3194
3256
|
return runtime;
|
|
3195
3257
|
}
|
|
3196
3258
|
// ── The other three backend handles ─────────────────────────────────────────
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3259
|
+
__init75() {this._hit = null}
|
|
3260
|
+
__init76() {this._anim = null}
|
|
3261
|
+
__init77() {this._particle = null}
|
|
3200
3262
|
/** The installed hit-test backend, or `null` for the JS depth-first walk. */
|
|
3201
3263
|
get hit() {
|
|
3202
3264
|
return this._hit;
|
|
@@ -3205,6 +3267,7 @@ var WasmBackendFacade = (_class14 = class {
|
|
|
3205
3267
|
setHit(backend) {
|
|
3206
3268
|
this._hit = backend;
|
|
3207
3269
|
this.hitGridFrame = -1;
|
|
3270
|
+
this.hitGridStructureVersion = -1;
|
|
3208
3271
|
this.hitReason = backend ? "not-applicable" : "not-installed";
|
|
3209
3272
|
}
|
|
3210
3273
|
/** The installed batched-animation backend, or `null` for the JS tick. */
|
|
@@ -3231,9 +3294,9 @@ var WasmBackendFacade = (_class14 = class {
|
|
|
3231
3294
|
* Why the transform accelerator did or did not run on the most recent frame.
|
|
3232
3295
|
* Written by the render walk and {@link syncStore}.
|
|
3233
3296
|
*/
|
|
3234
|
-
|
|
3297
|
+
__init78() {this.transformReason = "not-installed"}
|
|
3235
3298
|
/** Why the batched-driver accelerator did or did not run. */
|
|
3236
|
-
|
|
3299
|
+
__init79() {this.animReason = "not-installed"}
|
|
3237
3300
|
/**
|
|
3238
3301
|
* Why the hit-test accelerator did or did not serve the last pointer query.
|
|
3239
3302
|
* The grid is built lazily on demand, not every frame, so this describes the
|
|
@@ -3241,28 +3304,35 @@ var WasmBackendFacade = (_class14 = class {
|
|
|
3241
3304
|
* before a backend exists; the grid build moves it to `'not-applicable'` once
|
|
3242
3305
|
* one is installed but nothing has queried yet.
|
|
3243
3306
|
*/
|
|
3244
|
-
|
|
3307
|
+
__init80() {this.hitReason = "not-installed"}
|
|
3245
3308
|
/** Why the particle accelerator did or did not run. */
|
|
3246
|
-
|
|
3309
|
+
__init81() {this.particleReason = "not-applicable"}
|
|
3247
3310
|
/** Which particle implementation actually simulated the most recent frame. */
|
|
3248
|
-
|
|
3311
|
+
__init82() {this.particlePath = "none"}
|
|
3249
3312
|
/**
|
|
3250
3313
|
* Whether the last grid build sourced its AABBs from the WASM transform store
|
|
3251
3314
|
* rather than recomputing them in JS. Diagnostic only — both paths must
|
|
3252
3315
|
* produce the same entity for a given point.
|
|
3253
3316
|
*/
|
|
3254
|
-
|
|
3317
|
+
__init83() {this.hitFusedGather = false}
|
|
3255
3318
|
/** Whether the WASM batch path actually ran on the most recent frame. */
|
|
3256
|
-
|
|
3319
|
+
__init84() {this.animBatchedLastFrame = false}
|
|
3257
3320
|
// Hit-grid cache key: which frame + structure version the grid was last
|
|
3258
3321
|
// (successfully, non-overflowing) built for. Owned here rather than by
|
|
3259
3322
|
// `HitTester` because {@link setHit} has to invalidate it, and a backend swap
|
|
3260
3323
|
// is this facade's job. The grid contents themselves stay with the hit-test
|
|
3261
3324
|
// domain.
|
|
3262
3325
|
/** Frame the hit grid was last built for; `-1` forces a rebuild. */
|
|
3263
|
-
|
|
3326
|
+
__init85() {this.hitGridFrame = -1}
|
|
3327
|
+
/**
|
|
3328
|
+
* Structure version the hit grid was built for; `-1` forces a rebuild.
|
|
3329
|
+
* Half of the cache key the comment above promises: without it, a pointer
|
|
3330
|
+
* query in the same frame as a structural mutation would resolve against
|
|
3331
|
+
* pre-mutation geometry while the JS walk sees live state.
|
|
3332
|
+
*/
|
|
3333
|
+
__init86() {this.hitGridStructureVersion = -1}
|
|
3264
3334
|
/** Whether that build succeeded (did not overflow its item budget). */
|
|
3265
|
-
|
|
3335
|
+
__init87() {this.hitGridOk = false}
|
|
3266
3336
|
/**
|
|
3267
3337
|
* Per-frame status of every invisible accelerator: whether each is installed,
|
|
3268
3338
|
* whether it actually ran on the most recent frame, and why.
|
|
@@ -3400,6 +3470,38 @@ var WasmBackendFacade = (_class14 = class {
|
|
|
3400
3470
|
}
|
|
3401
3471
|
}, _class14);
|
|
3402
3472
|
|
|
3473
|
+
// src/tree/scene/keyboard.ts
|
|
3474
|
+
function normalizeChord(input) {
|
|
3475
|
+
if (typeof input === "string") {
|
|
3476
|
+
const parts = input.split("+").map((p) => p.trim()).filter(Boolean);
|
|
3477
|
+
const mods = /* @__PURE__ */ new Set();
|
|
3478
|
+
let key2 = "";
|
|
3479
|
+
for (const p of parts) {
|
|
3480
|
+
const low = p.toLowerCase();
|
|
3481
|
+
if (low === "ctrl" || low === "control") mods.add("Control");
|
|
3482
|
+
else if (low === "alt") mods.add("Alt");
|
|
3483
|
+
else if (low === "shift") mods.add("Shift");
|
|
3484
|
+
else if (low === "meta" || low === "cmd" || low === "super") mods.add("Meta");
|
|
3485
|
+
else key2 = p.length === 1 ? p.toUpperCase() : p;
|
|
3486
|
+
}
|
|
3487
|
+
const ordered2 = ["Control", "Alt", "Shift", "Meta"].filter((m) => mods.has(m));
|
|
3488
|
+
return key2 ? [...ordered2, key2].join("+") : ordered2.join("+");
|
|
3489
|
+
}
|
|
3490
|
+
const ordered = [];
|
|
3491
|
+
if (input.ctrlKey) ordered.push("Control");
|
|
3492
|
+
if (input.altKey) ordered.push("Alt");
|
|
3493
|
+
if (input.shiftKey) ordered.push("Shift");
|
|
3494
|
+
if (input.metaKey) ordered.push("Meta");
|
|
3495
|
+
let key = input.key;
|
|
3496
|
+
if (key === " ") key = "Space";
|
|
3497
|
+
else if (key.length === 1) key = key.toUpperCase();
|
|
3498
|
+
if (["Control", "Alt", "Shift", "Meta"].includes(key)) {
|
|
3499
|
+
return ordered.join("+");
|
|
3500
|
+
}
|
|
3501
|
+
ordered.push(key);
|
|
3502
|
+
return ordered.join("+");
|
|
3503
|
+
}
|
|
3504
|
+
|
|
3403
3505
|
// src/tree/Scene.ts
|
|
3404
3506
|
var RANGE_VALUE_ROLES = /* @__PURE__ */ new Set(["slider", "spinbutton", "progressbar", "scrollbar", "meter"]);
|
|
3405
3507
|
var INTERACTIVE_A11Y_ROLES = /* @__PURE__ */ new Set([
|
|
@@ -3413,6 +3515,24 @@ var INTERACTIVE_A11Y_ROLES = /* @__PURE__ */ new Set([
|
|
|
3413
3515
|
"slider",
|
|
3414
3516
|
"combobox"
|
|
3415
3517
|
]);
|
|
3518
|
+
var KEYBOARD_OWNING_ROLES = /* @__PURE__ */ new Set([
|
|
3519
|
+
...INTERACTIVE_A11Y_ROLES,
|
|
3520
|
+
"option",
|
|
3521
|
+
"listbox",
|
|
3522
|
+
"textbox",
|
|
3523
|
+
"searchbox",
|
|
3524
|
+
"spinbutton"
|
|
3525
|
+
]);
|
|
3526
|
+
function ownsKeyboard(el) {
|
|
3527
|
+
if (!el) return false;
|
|
3528
|
+
if (el === document.body || el === document.documentElement) return false;
|
|
3529
|
+
if (el.hasAttribute("data-vecto-a11y-root")) return false;
|
|
3530
|
+
const tag = el.tagName;
|
|
3531
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
3532
|
+
if (el.isContentEditable) return true;
|
|
3533
|
+
const role = el.getAttribute("role");
|
|
3534
|
+
return role !== null && KEYBOARD_OWNING_ROLES.has(role);
|
|
3535
|
+
}
|
|
3416
3536
|
var A11Y_REQUIRED_OWNED = /* @__PURE__ */ new Map([
|
|
3417
3537
|
["grid", /* @__PURE__ */ new Set(["row", "rowgroup"])],
|
|
3418
3538
|
["table", /* @__PURE__ */ new Set(["row", "rowgroup"])],
|
|
@@ -3561,9 +3681,9 @@ function parseCssMatrix(transform) {
|
|
|
3561
3681
|
}
|
|
3562
3682
|
function clientToGridLocal(contentEl, canvas, clientX, clientY) {
|
|
3563
3683
|
const line = contentEl.querySelector("[data-vecto-grid-line]");
|
|
3564
|
-
const originMarker = _optionalChain([line, 'optionalAccess',
|
|
3565
|
-
const xMarker = _optionalChain([line, 'optionalAccess',
|
|
3566
|
-
const yMarker = _optionalChain([line, 'optionalAccess',
|
|
3684
|
+
const originMarker = _optionalChain([line, 'optionalAccess', _86 => _86.querySelector, 'call', _87 => _87('[data-vecto-grid-basis="origin"]')]);
|
|
3685
|
+
const xMarker = _optionalChain([line, 'optionalAccess', _88 => _88.querySelector, 'call', _89 => _89('[data-vecto-grid-basis="x"]')]);
|
|
3686
|
+
const yMarker = _optionalChain([line, 'optionalAccess', _90 => _90.querySelector, 'call', _91 => _91('[data-vecto-grid-basis="y"]')]);
|
|
3567
3687
|
if (line && originMarker && xMarker && yMarker) {
|
|
3568
3688
|
const origin = originMarker.getBoundingClientRect();
|
|
3569
3689
|
const xPoint = xMarker.getBoundingClientRect();
|
|
@@ -3647,7 +3767,7 @@ function nearestTextPositionInLine(line, x, y) {
|
|
|
3647
3767
|
nearest = { position: { node, offset }, distance: candidate.distance };
|
|
3648
3768
|
}
|
|
3649
3769
|
}
|
|
3650
|
-
return _nullishCoalesce(_optionalChain([nearest, 'optionalAccess',
|
|
3770
|
+
return _nullishCoalesce(_optionalChain([nearest, 'optionalAccess', _92 => _92.position]), () => ( null));
|
|
3651
3771
|
}
|
|
3652
3772
|
function nearestTextPositionInProjection(contentEl, canvas, x, y, eventTarget) {
|
|
3653
3773
|
if (contentEl.dataset.vectoContentGrid !== void 0) {
|
|
@@ -3661,7 +3781,7 @@ function nearestTextPositionInProjection(contentEl, canvas, x, y, eventTarget) {
|
|
|
3661
3781
|
}
|
|
3662
3782
|
targetLine = targetLine.parentElement;
|
|
3663
3783
|
}
|
|
3664
|
-
if (_optionalChain([targetLine, 'optionalAccess',
|
|
3784
|
+
if (_optionalChain([targetLine, 'optionalAccess', _93 => _93.parentElement]) === contentEl) {
|
|
3665
3785
|
return nearestTextPositionInLine(targetLine, x, y);
|
|
3666
3786
|
}
|
|
3667
3787
|
let bestLine = null;
|
|
@@ -3766,15 +3886,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
3766
3886
|
|
|
3767
3887
|
|
|
3768
3888
|
|
|
3769
|
-
|
|
3889
|
+
__init88() {this.isRunning = false}
|
|
3770
3890
|
/** Whether the canvas is at least partially in the viewport. When it scrolls
|
|
3771
3891
|
* fully off-screen the rAF loop pauses (stops rescheduling) instead of
|
|
3772
3892
|
* burning frames on a scene nobody can see; an IntersectionObserver resumes
|
|
3773
3893
|
* it on re-entry. Defaults true (and stays true where IntersectionObserver
|
|
3774
3894
|
* is unavailable, e.g. SSR/jsdom, so behavior is unchanged there). */
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3895
|
+
__init89() {this._canvasOnScreen = true}
|
|
3896
|
+
__init90() {this._canvasObserver = null}
|
|
3897
|
+
__init91() {this.lastTime = 0}
|
|
3778
3898
|
|
|
3779
3899
|
// --- domain: render-scheduler — mode, phase timing, frame telemetry, FPS caps ---
|
|
3780
3900
|
/**
|
|
@@ -3784,7 +3904,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
3784
3904
|
* {@link markDirty}) or while an animation is pending. Ideal for static /
|
|
3785
3905
|
* event-driven UIs where idle frames should cost ~0.
|
|
3786
3906
|
*/
|
|
3787
|
-
|
|
3907
|
+
__init92() {this.renderMode = "always"}
|
|
3788
3908
|
/**
|
|
3789
3909
|
* Per-phase frame timing and the browser User Timing flag.
|
|
3790
3910
|
*
|
|
@@ -3794,7 +3914,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
3794
3914
|
* domains write phases, so this is a shared leaf rather than any one domain's
|
|
3795
3915
|
* property — see `DEC-0021`.
|
|
3796
3916
|
*/
|
|
3797
|
-
|
|
3917
|
+
__init93() {this.phases = new PhaseTimer()}
|
|
3798
3918
|
/**
|
|
3799
3919
|
* Start or stop per-phase render timing.
|
|
3800
3920
|
*
|
|
@@ -3849,7 +3969,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
3849
3969
|
* injected input, so it follows {@link phases} and {@link a11yOrder} rather
|
|
3850
3970
|
* than the definite-assignment collaborators.
|
|
3851
3971
|
*/
|
|
3852
|
-
|
|
3972
|
+
__init94() {this._dirty = new DirtyTracker()}
|
|
3853
3973
|
/**
|
|
3854
3974
|
* The redraw-pending flag, under its original name.
|
|
3855
3975
|
*
|
|
@@ -3869,34 +3989,34 @@ var Scene = (_class15 = class _Scene {
|
|
|
3869
3989
|
* Whether to throttle the `'always'` loop when the scene is static to save
|
|
3870
3990
|
* power. The idle floor is {@link Scene.idleFPS} (default 60).
|
|
3871
3991
|
*/
|
|
3872
|
-
|
|
3992
|
+
__init95() {this.autoThrottle = true}
|
|
3873
3993
|
/**
|
|
3874
3994
|
* Frame-rate floor for an idle `'always'` scene when {@link Scene.autoThrottle}
|
|
3875
3995
|
* is on. Default `60`. Set `2` for the legacy aggressive idle sleep, `0` to
|
|
3876
3996
|
* keep the scene's `maxFPS` cadence while idle.
|
|
3877
3997
|
*/
|
|
3878
|
-
|
|
3998
|
+
__init96() {this.idleFPS = 60}
|
|
3879
3999
|
// --- Frame telemetry (read via `frameStats`) ---------------------------
|
|
3880
4000
|
/** Wall-clock ms spent inside the last `render()` call. */
|
|
3881
|
-
|
|
4001
|
+
__init97() {this._lastFrameMs = 0}
|
|
3882
4002
|
/** Rolling exponential average of rendered-frame intervals, in ms. */
|
|
3883
|
-
|
|
4003
|
+
__init98() {this._avgFrameIntervalMs = 0}
|
|
3884
4004
|
/** dt (ms) handed to the last rendered frame. */
|
|
3885
|
-
|
|
4005
|
+
__init99() {this._lastDt = 0}
|
|
3886
4006
|
/** Count of frames actually rendered since the loop started. */
|
|
3887
|
-
|
|
4007
|
+
__init100() {this._renderedFrames = 0}
|
|
3888
4008
|
/** Count of rAF ticks skipped (idle / capped) since the loop started. */
|
|
3889
|
-
|
|
4009
|
+
__init101() {this._skippedFrames = 0}
|
|
3890
4010
|
/** `time` of the previous *rendered* frame, for interval measurement. */
|
|
3891
|
-
|
|
4011
|
+
__init102() {this._lastRenderTick = 0}
|
|
3892
4012
|
/**
|
|
3893
4013
|
* Frame-rate cap (power saving). `0` = uncapped (native refresh). When set,
|
|
3894
4014
|
* the loop renders at most `maxFPS` times per second; animations still run,
|
|
3895
4015
|
* just less often. See {@link SceneOptions.maxFPS}.
|
|
3896
4016
|
*/
|
|
3897
|
-
|
|
4017
|
+
__init103() {this.maxFPS = 60}
|
|
3898
4018
|
/** Whether the OS prefers-reduced-motion setting auto-caps the loop. */
|
|
3899
|
-
|
|
4019
|
+
__init104() {this.respectReducedMotion = true}
|
|
3900
4020
|
/**
|
|
3901
4021
|
* Reading direction for accessibility tab/traversal order (`'ltr'` default,
|
|
3902
4022
|
* `'rtl'`). Controls the inline sort within a visual row in
|
|
@@ -3912,18 +4032,18 @@ var Scene = (_class15 = class _Scene {
|
|
|
3912
4032
|
this.a11yOrder.markNeedsReorder();
|
|
3913
4033
|
}
|
|
3914
4034
|
}
|
|
3915
|
-
|
|
4035
|
+
__init105() {this._readingDirection = "ltr"}
|
|
3916
4036
|
/** Cached media-query list; `.matches` is read live each frame. */
|
|
3917
|
-
|
|
4037
|
+
__init106() {this.reducedMotionQuery = null}
|
|
3918
4038
|
/** Cached `(forced-colors: active)` query (Windows High Contrast etc.). A
|
|
3919
4039
|
* canvas gets NO automatic forced-colors treatment from the browser (it's
|
|
3920
4040
|
* opaque pixels), so components must read {@link forcedColors} and repaint
|
|
3921
4041
|
* with system colors themselves; a change listener repaints idle scenes. */
|
|
3922
|
-
|
|
3923
|
-
|
|
4042
|
+
__init107() {this.forcedColorsQuery = null}
|
|
4043
|
+
__init108() {this.forcedColorsChangeHandler = null}
|
|
3924
4044
|
/** True when the OS asks for reduced motion and we respect it. Read by the animation drivers. */
|
|
3925
4045
|
get prefersReducedMotion() {
|
|
3926
|
-
return this.respectReducedMotion && !!_optionalChain([this, 'access',
|
|
4046
|
+
return this.respectReducedMotion && !!_optionalChain([this, 'access', _94 => _94.reducedMotionQuery, 'optionalAccess', _95 => _95.matches]);
|
|
3927
4047
|
}
|
|
3928
4048
|
/**
|
|
3929
4049
|
* True when the OS is in a forced-colors mode (Windows High Contrast, and the
|
|
@@ -3934,26 +4054,29 @@ var Scene = (_class15 = class _Scene {
|
|
|
3934
4054
|
* when the setting toggles.
|
|
3935
4055
|
*/
|
|
3936
4056
|
get forcedColors() {
|
|
3937
|
-
return !!_optionalChain([this, 'access',
|
|
4057
|
+
return !!_optionalChain([this, 'access', _96 => _96.forcedColorsQuery, 'optionalAccess', _97 => _97.matches]);
|
|
3938
4058
|
}
|
|
3939
4059
|
// --- domain: a11y-projection — sync throttle and shadow-DOM state ---
|
|
3940
4060
|
/**
|
|
3941
4061
|
* Throttle interval (ms) for the a11y/automation shadow sync. `0` = every
|
|
3942
4062
|
* frame. See {@link SceneOptions.a11ySyncInterval}.
|
|
3943
4063
|
*/
|
|
3944
|
-
|
|
4064
|
+
__init109() {this.a11ySyncInterval = 0}
|
|
3945
4065
|
/** Timestamp of the last a11y sync, for throttling. */
|
|
3946
|
-
|
|
4066
|
+
__init110() {this.lastA11ySync = -Infinity}
|
|
3947
4067
|
/** True if we skipped an a11y sync during animation and need to sync when at rest. */
|
|
3948
|
-
|
|
4068
|
+
__init111() {this.a11yPendingSyncAfterAnimation = false}
|
|
3949
4069
|
// A11y / Automation Layer. `null` in non-DOM (SSR/Node) environments — the
|
|
3950
4070
|
// whole projection degrades to a no-op so the engine's logic stays usable
|
|
3951
4071
|
// server-side (e.g. headless layout / vector export) without jsdom.
|
|
3952
4072
|
|
|
3953
|
-
|
|
4073
|
+
__init112() {this.a11yElements = /* @__PURE__ */ new Map()}
|
|
4074
|
+
/** Elements that already have the synthetic Enter/Space activation handler
|
|
4075
|
+
* (see the syncA11y refresh pass) — install-once bookkeeping (#694). */
|
|
4076
|
+
__init113() {this.keyboardActivatedA11y = /* @__PURE__ */ new WeakSet()}
|
|
3954
4077
|
// --- domain: content-projection — projected DOM, sync state, calibration, selection ---
|
|
3955
4078
|
/** DOM nodes mirroring static text content, keyed by entity id. */
|
|
3956
|
-
|
|
4079
|
+
__init114() {this.contentElements = /* @__PURE__ */ new Map()}
|
|
3957
4080
|
/**
|
|
3958
4081
|
* What the last completed content-projection sync was built from, per entity.
|
|
3959
4082
|
*
|
|
@@ -3962,9 +4085,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
3962
4085
|
* build. Only populated for entities that opt in via
|
|
3963
4086
|
* {@link Entity.getContentEpoch}. (carryctx CTX-0199)
|
|
3964
4087
|
*/
|
|
3965
|
-
|
|
4088
|
+
__init115() {this.contentSyncState = /* @__PURE__ */ new Map()}
|
|
3966
4089
|
/** Invalidates grid font calibration after browser font availability changes. */
|
|
3967
|
-
|
|
4090
|
+
__init116() {this.contentFontEpoch = 0}
|
|
3968
4091
|
/**
|
|
3969
4092
|
* Bumped whenever the viewport itself changes shape, which re-tiers blocks
|
|
3970
4093
|
* without moving any of them.
|
|
@@ -3977,7 +4100,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
3977
4100
|
* carriers it no longer needs. Scrolling needs no such epoch: it moves the root,
|
|
3978
4101
|
* so every block's parent world transform changes and the check fails honestly.
|
|
3979
4102
|
*/
|
|
3980
|
-
|
|
4103
|
+
__init117() {this.contentViewportEpoch = 0}
|
|
3981
4104
|
/**
|
|
3982
4105
|
* One-entry memo for a parent's world transform, held as scalars.
|
|
3983
4106
|
*
|
|
@@ -3992,16 +4115,16 @@ var Scene = (_class15 = class _Scene {
|
|
|
3992
4115
|
* sync, so a memo can never survive into a frame in which the parent has
|
|
3993
4116
|
* moved.
|
|
3994
4117
|
*/
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4118
|
+
__init118() {this._pwNode = null}
|
|
4119
|
+
__init119() {this._pwSerial = -1}
|
|
4120
|
+
__init120() {this._pwa = 1}
|
|
4121
|
+
__init121() {this._pwb = 0}
|
|
4122
|
+
__init122() {this._pwc = 0}
|
|
4123
|
+
__init123() {this._pwd = 1}
|
|
4124
|
+
__init124() {this._pwe = 0}
|
|
4125
|
+
__init125() {this._pwf = 0}
|
|
4003
4126
|
/** Incremented once per top-level `syncA11y`, invalidating `_pwNode`. */
|
|
4004
|
-
|
|
4127
|
+
__init126() {this._syncSerial = 0}
|
|
4005
4128
|
/**
|
|
4006
4129
|
* Disables the settled-walk fast path in {@link syncContentProjection}.
|
|
4007
4130
|
*
|
|
@@ -4013,38 +4136,38 @@ var Scene = (_class15 = class _Scene {
|
|
|
4013
4136
|
* Not part of the public API and not documented as an option: turning it on only
|
|
4014
4137
|
* makes a settled document slower, never more correct.
|
|
4015
4138
|
*/
|
|
4016
|
-
|
|
4139
|
+
__init127() {this.disableSettledFastPath = false}
|
|
4017
4140
|
/** Cached Canvas-to-client scale for the current font/viewport epoch. */
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4141
|
+
__init128() {this.contentMetricScaleEpoch = -1}
|
|
4142
|
+
__init129() {this.contentMetricScaleX = 1}
|
|
4143
|
+
__init130() {this.contentProjectionEnabled = true}
|
|
4021
4144
|
// Virtualization margin (px) for the content-projection CARRIER band;
|
|
4022
4145
|
// `undefined` → one viewport height, resolved at sync time. `Infinity` is
|
|
4023
4146
|
// unsupported here: it unwindows every carrier, which is O(total glyphs).
|
|
4024
|
-
|
|
4147
|
+
__init131() {this.contentProjectionMargin = void 0}
|
|
4025
4148
|
// Virtualization margin (px) for the SEMANTIC tier — whether a block has
|
|
4026
4149
|
// any projected DOM. `undefined` → falls back to contentProjectionMargin, so
|
|
4027
4150
|
// the default keeps one gate. `Infinity` = every block keeps resident text.
|
|
4028
|
-
|
|
4151
|
+
__init132() {this.contentSemanticMargin = void 0}
|
|
4029
4152
|
// How many coarse-tier blocks may be MATERIALIZED per sync, spreading the
|
|
4030
4153
|
// resident tier's document-open cost across frames. `Infinity` = one
|
|
4031
4154
|
// synchronous pass.
|
|
4032
|
-
|
|
4155
|
+
__init133() {this.contentSemanticBudget = DEFAULT_CONTENT_SEMANTIC_BUDGET}
|
|
4033
4156
|
// Remaining materializations in the CURRENT sync. Reset at the start of each
|
|
4034
4157
|
// a11y walk; decremented per coarse block that creates its element.
|
|
4035
|
-
|
|
4158
|
+
__init134() {this.contentSemanticBudgetLeft = 0}
|
|
4036
4159
|
// Set when a sync deferred at least one block, so the scene knows to keep
|
|
4037
4160
|
// drawing frames until the resident tier is complete. Without it a static
|
|
4038
4161
|
// scene in `onDemand` mode would stop rendering with the document half
|
|
4039
4162
|
// materialized and never finish.
|
|
4040
|
-
|
|
4041
|
-
|
|
4163
|
+
__init135() {this.contentSemanticDeferred = false}
|
|
4164
|
+
__init136() {this.contentSelectionEndListener = null}
|
|
4042
4165
|
// --- domain: render-scheduler — per-frame walk flags ---
|
|
4043
4166
|
// Animation/interactive flags collected during the render walk (tree-walk
|
|
4044
4167
|
// fusion): the loop reads last frame's answers instead of re-walking the
|
|
4045
4168
|
// tree up to 4× per tick. Start true so the first tick stays conservative.
|
|
4046
|
-
|
|
4047
|
-
|
|
4169
|
+
__init137() {this.frameHadAnimation = true}
|
|
4170
|
+
__init138() {this.frameHadInteractive = true}
|
|
4048
4171
|
// --- domain: context-and-resize — resize handler, DPR query, canvas observer ---
|
|
4049
4172
|
|
|
4050
4173
|
/** Active `(resolution: Ndppx)` media query watching for a runtime DPR change
|
|
@@ -4052,15 +4175,17 @@ var Scene = (_class15 = class _Scene {
|
|
|
4052
4175
|
* can be re-scaled — otherwise it stays rasterized at the old DPR and blurs.
|
|
4053
4176
|
* A resolution media query only fires when leaving its exact value, so the
|
|
4054
4177
|
* handler re-arms a fresh query for the new DPR each time. */
|
|
4055
|
-
|
|
4178
|
+
__init139() {this.dprMediaQuery = null}
|
|
4056
4179
|
/** For embedded (`disableWindowResize`) scenes: observes the canvas element so
|
|
4057
4180
|
* a CSS/layout-driven size change re-runs `resize()`. A window `resize`
|
|
4058
4181
|
* listener never fires for these (the window isn't what changed), so without
|
|
4059
4182
|
* this an embedded canvas stayed at its initial size forever. */
|
|
4060
|
-
|
|
4061
|
-
|
|
4183
|
+
__init140() {this.canvasResizeObserver = null}
|
|
4184
|
+
__init141() {this.dprChangeHandler = null}
|
|
4185
|
+
__init142() {this.dprPollInterval = null}
|
|
4186
|
+
__init143() {this.lastDpr = 1}
|
|
4062
4187
|
// --- domain: a11y-projection — focus, overlay geometry, DOM ordering, portals ---
|
|
4063
|
-
|
|
4188
|
+
__init144() {this.focusedA11yElement = null}
|
|
4064
4189
|
/**
|
|
4065
4190
|
* Canvas box geometry: the CSS↔logical mapping, overlay layer alignment, and
|
|
4066
4191
|
* the DPR math (extraction 5, `DEC-0024`).
|
|
@@ -4087,7 +4212,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4087
4212
|
/** Shadow elements the pointer is currently inside. Lets a removal that happens
|
|
4088
4213
|
* mid-hover synthesize the `pointerleave` the browser never sends for a
|
|
4089
4214
|
* detached element, so the entity doesn't keep its hover state. */
|
|
4090
|
-
|
|
4215
|
+
__init145() {this.hoveredA11yElements = /* @__PURE__ */ new WeakSet()}
|
|
4091
4216
|
/**
|
|
4092
4217
|
* Entity ids the application has pinned via {@link requestA11yProjection}.
|
|
4093
4218
|
*
|
|
@@ -4095,13 +4220,13 @@ var Scene = (_class15 = class _Scene {
|
|
|
4095
4220
|
* a stale id simply never matches. Cleared per-entity by
|
|
4096
4221
|
* {@link releaseA11yProjection}.
|
|
4097
4222
|
*/
|
|
4098
|
-
|
|
4223
|
+
__init146() {this.a11yProjectionRequests = /* @__PURE__ */ new Set()}
|
|
4099
4224
|
/** Persistent tabindex=-1 element in a11yRoot. When the focused a11y mirror is
|
|
4100
4225
|
* pruned (virtualization/streaming/removal) while it holds focus, we move
|
|
4101
4226
|
* focus here instead of letting the browser drop it to <body> — keeping the
|
|
4102
4227
|
* screen-reader virtual cursor inside the scene's a11y region. */
|
|
4103
|
-
|
|
4104
|
-
|
|
4228
|
+
__init147() {this.focusSentinel = null}
|
|
4229
|
+
__init148() {this.caretBlinkTimer = null}
|
|
4105
4230
|
/**
|
|
4106
4231
|
* The projected DOM's ordering engine — the reorder flag, the per-pass scratch
|
|
4107
4232
|
* collections, the visual reading-order sort and the cursor-based
|
|
@@ -4111,7 +4236,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4111
4236
|
* delegate here; the collect-and-prune walk stays behind because it needs
|
|
4112
4237
|
* {@link shouldProjectA11y} and the focus/caret state.
|
|
4113
4238
|
*/
|
|
4114
|
-
|
|
4239
|
+
__init149() {this.a11yOrder = new A11yProjectionManager()}
|
|
4115
4240
|
/**
|
|
4116
4241
|
* The content projection's selection preservation and grid calibration
|
|
4117
4242
|
* (extraction 3, `DEC-0022`).
|
|
@@ -4163,11 +4288,11 @@ var Scene = (_class15 = class _Scene {
|
|
|
4163
4288
|
set a11yNeedsReorder(value) {
|
|
4164
4289
|
this.a11yOrder.needsReorder = value;
|
|
4165
4290
|
}
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4291
|
+
__init150() {this.portalRoot = null}
|
|
4292
|
+
__init151() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
|
|
4293
|
+
__init152() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
|
|
4294
|
+
__init153() {this.portalEntities = /* @__PURE__ */ new Map()}
|
|
4295
|
+
__init154() {this.renderOrderCounter = 0}
|
|
4171
4296
|
// --- domain: render-scheduler — authoritative frame counter ---
|
|
4172
4297
|
/**
|
|
4173
4298
|
* Monotonic render-frame counter, bumped once per authoritative `render()`
|
|
@@ -4177,7 +4302,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4177
4302
|
* back to the ancestor walk. Public for the same reason `Entity._getTrig`/
|
|
4178
4303
|
* `_setWorldCache` are: it is a cross-class render-internal contract.
|
|
4179
4304
|
*/
|
|
4180
|
-
|
|
4305
|
+
__init155() {this.currentFrame = 0}
|
|
4181
4306
|
// --- domain: wasm-backend-facade — EXTRACTED (see scene/WasmBackendFacade.ts) ---
|
|
4182
4307
|
/**
|
|
4183
4308
|
* The four invisible WASM accelerators and the resident transform store.
|
|
@@ -4247,8 +4372,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
4247
4372
|
// Stays on `Scene`: it walks `root` *and* `overlayRoot` for entities the
|
|
4248
4373
|
// render walk consumes, so only its cache key is store state. The facade owns
|
|
4249
4374
|
// the key; the walk stays here.
|
|
4250
|
-
|
|
4251
|
-
|
|
4375
|
+
__init156() {this._computeEntities = []}
|
|
4376
|
+
__init157() {this._computeEntitiesVersion = -1}
|
|
4252
4377
|
/** Invalidate the resident WASM store layout; the next wasm-mode frame rebuilds
|
|
4253
4378
|
* it. Called by `Entity.add`/`remove` (topology changes only). */
|
|
4254
4379
|
markStructureChanged() {
|
|
@@ -4487,7 +4612,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4487
4612
|
get animBatchedLastFrame() {
|
|
4488
4613
|
return this._wasmBackend.animBatchedLastFrame;
|
|
4489
4614
|
}
|
|
4490
|
-
|
|
4615
|
+
__init158() {this.animGate = {
|
|
4491
4616
|
spring: 128,
|
|
4492
4617
|
tween: 256,
|
|
4493
4618
|
mixed: 128
|
|
@@ -4575,6 +4700,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
4575
4700
|
_registerActiveDriverSubtree(entity) {
|
|
4576
4701
|
this._driverTicker.registerSubtree(entity);
|
|
4577
4702
|
}
|
|
4703
|
+
/**
|
|
4704
|
+
* The `dt` of the frame currently executing its update walk (the WASM-mode
|
|
4705
|
+
* pre-pass or the JS-mode interleaved render walk), or `null` outside it.
|
|
4706
|
+
* Read by `Entity._spawnDriver`: a driver spawned mid-walk onto an entity the
|
|
4707
|
+
* batched pass already claimed this frame must be advanced once here, or
|
|
4708
|
+
* `tickDrivers()`'s per-frame stamp would skip it a full frame — a one-frame
|
|
4709
|
+
* JS/WASM divergence. Written in {@link render} next to `_tickBatchedDrivers`.
|
|
4710
|
+
*/
|
|
4711
|
+
__init159() {this._updateWalkDt = null}
|
|
4578
4712
|
// --- domain: render-scheduler — batched driver tick (extraction 6), reads the anim backend ---
|
|
4579
4713
|
/**
|
|
4580
4714
|
* Advance every registered entity's active drivers for this frame, batching
|
|
@@ -4602,25 +4736,25 @@ var Scene = (_class15 = class _Scene {
|
|
|
4602
4736
|
* sync, so retaining the order prevents a newly opened overlay from spending
|
|
4603
4737
|
* its first frame below previously projected controls.
|
|
4604
4738
|
*/
|
|
4605
|
-
|
|
4739
|
+
__init160() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
|
|
4606
4740
|
// --- domain: context-and-resize — GL/GPU canvases, device state, pointer, size warnings ---
|
|
4607
4741
|
// Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4742
|
+
__init161() {this.pointRenderer = null}
|
|
4743
|
+
__init162() {this.glCanvas = null}
|
|
4744
|
+
__init163() {this.glContextLostHandler = null}
|
|
4745
|
+
__init164() {this.glContextRestoredHandler = null}
|
|
4612
4746
|
|
|
4613
4747
|
|
|
4614
4748
|
|
|
4615
|
-
|
|
4749
|
+
__init165() {this.disableWindowResize = false}
|
|
4616
4750
|
/** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
|
|
4617
4751
|
|
|
4618
4752
|
// WebGPU properties
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4753
|
+
__init166() {this.destroyed = false}
|
|
4754
|
+
__init167() {this.device = null}
|
|
4755
|
+
__init168() {this.deviceLost = false}
|
|
4756
|
+
__init169() {this.particleBackend = "auto"}
|
|
4757
|
+
__init170() {this._webgpuDisabled = false}
|
|
4624
4758
|
get webgpuDisabled() {
|
|
4625
4759
|
return this._webgpuDisabled || this.particleBackend === "cpu";
|
|
4626
4760
|
}
|
|
@@ -4634,7 +4768,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4634
4768
|
* active.
|
|
4635
4769
|
*/
|
|
4636
4770
|
get webglDrawStats() {
|
|
4637
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
4771
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _98 => _98.pointRenderer, 'optionalAccess', _99 => _99.stats, 'optionalCall', _100 => _100()]), () => ( null));
|
|
4638
4772
|
}
|
|
4639
4773
|
/**
|
|
4640
4774
|
* Whether a WebGPU device is currently live for particle compute.
|
|
@@ -4648,21 +4782,28 @@ var Scene = (_class15 = class _Scene {
|
|
|
4648
4782
|
set webgpuDisabled(value) {
|
|
4649
4783
|
this._webgpuDisabled = value;
|
|
4650
4784
|
}
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4785
|
+
__init171() {this.recoveryTimerId = null}
|
|
4786
|
+
__init172() {this.manager = null}
|
|
4787
|
+
__init173() {this.initializingWebGPU = false}
|
|
4788
|
+
__init174() {this.gpuCanvas = null}
|
|
4789
|
+
__init175() {this.gpuContext = null}
|
|
4656
4790
|
/** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4791
|
+
__init176() {this.gpuHasContent = false}
|
|
4792
|
+
__init177() {this.mouseX = -9999}
|
|
4793
|
+
__init178() {this.mouseY = -9999}
|
|
4794
|
+
__init179() {this.pointerMoveListener = null}
|
|
4795
|
+
__init180() {this.pointerLeaveListener = null}
|
|
4662
4796
|
/** Element the pointer listeners are bound to (parent container if present,
|
|
4663
4797
|
* else the canvas). Stored so `destroy()` detaches from the same element. */
|
|
4664
|
-
|
|
4665
|
-
|
|
4798
|
+
__init181() {this.pointerEventTarget = null}
|
|
4799
|
+
// --- scene-level keyboard channel state (see on/off/registerShortcut) ---
|
|
4800
|
+
__init182() {this.keydownHandlers = []}
|
|
4801
|
+
__init183() {this.keyupHandlers = []}
|
|
4802
|
+
/** Chord-normalized shortcut table, matched on keydown only. */
|
|
4803
|
+
__init184() {this.shortcuts = []}
|
|
4804
|
+
__init185() {this.windowKeyDownHandler = null}
|
|
4805
|
+
__init186() {this.windowKeyUpHandler = null}
|
|
4806
|
+
__init187() {this.hasWarnedZeroSize = false}
|
|
4666
4807
|
/**
|
|
4667
4808
|
* Latch for {@link Scene.resize}'s invalid-dimension warning.
|
|
4668
4809
|
*
|
|
@@ -4672,8 +4813,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
4672
4813
|
* because `resize()` is commonly driven from a `ResizeObserver`, which would
|
|
4673
4814
|
* otherwise warn on every frame of a drag.
|
|
4674
4815
|
*/
|
|
4675
|
-
|
|
4676
|
-
|
|
4816
|
+
__init188() {this.hasWarnedInvalidResize = false}
|
|
4817
|
+
__init189() {this.fontLoadHandler = null}
|
|
4677
4818
|
// --- domain: scene-facade — dev-mode diagnostics ---
|
|
4678
4819
|
// ── Dev-mode warning infrastructure ──────────────────────────────
|
|
4679
4820
|
//
|
|
@@ -4698,17 +4839,17 @@ var Scene = (_class15 = class _Scene {
|
|
|
4698
4839
|
}
|
|
4699
4840
|
static set devMode(active) {
|
|
4700
4841
|
_Scene._devMode = active;
|
|
4701
|
-
|
|
4842
|
+
_chunkBKXERWADjs.setRendererDevMode.call(void 0, active);
|
|
4702
4843
|
}
|
|
4703
4844
|
static _devModeDetected() {
|
|
4704
4845
|
if (_Scene._devMode) return true;
|
|
4705
4846
|
const gp = typeof globalThis !== "undefined" ? globalThis : void 0;
|
|
4706
|
-
if (_optionalChain([gp, 'optionalAccess',
|
|
4707
|
-
if (_optionalChain([gp, 'optionalAccess',
|
|
4847
|
+
if (_optionalChain([gp, 'optionalAccess', _101 => _101.__DEV__])) return true;
|
|
4848
|
+
if (_optionalChain([gp, 'optionalAccess', _102 => _102.process, 'optionalAccess', _103 => _103.env, 'optionalAccess', _104 => _104.NODE_ENV]) === "development") return true;
|
|
4708
4849
|
return false;
|
|
4709
4850
|
}
|
|
4710
4851
|
|
|
4711
|
-
|
|
4852
|
+
__init190() {this._devFrameCount = 0}
|
|
4712
4853
|
_devWarn(message) {
|
|
4713
4854
|
if (!this._devActive) return;
|
|
4714
4855
|
console.warn(`[vectojs/dev] ${message}`);
|
|
@@ -4766,9 +4907,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
4766
4907
|
let checked = 0;
|
|
4767
4908
|
const walkProjections = (node) => {
|
|
4768
4909
|
if (checked > 10) return;
|
|
4769
|
-
const proj = _optionalChain([node, 'access',
|
|
4770
|
-
if (_optionalChain([proj, 'optionalAccess',
|
|
4771
|
-
const el = _optionalChain([this, 'access',
|
|
4910
|
+
const proj = _optionalChain([node, 'access', _105 => _105.getContentProjection, 'optionalCall', _106 => _106()]);
|
|
4911
|
+
if (_optionalChain([proj, 'optionalAccess', _107 => _107.text]) && proj.selectable !== false) {
|
|
4912
|
+
const el = _optionalChain([this, 'access', _108 => _108.contentElements, 'optionalAccess', _109 => _109.get, 'call', _110 => _110(node.id)]);
|
|
4772
4913
|
if (el) {
|
|
4773
4914
|
const projectedText = el.textContent || "";
|
|
4774
4915
|
const windowed = el.dataset.vectoProjectionWindow !== void 0;
|
|
@@ -4786,22 +4927,27 @@ var Scene = (_class15 = class _Scene {
|
|
|
4786
4927
|
walkProjections(this.root);
|
|
4787
4928
|
}
|
|
4788
4929
|
// --- domain: scene-facade — construction (wires every collaborator) ---
|
|
4789
|
-
constructor(canvas, options = {}) {;_class15.prototype.
|
|
4930
|
+
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);
|
|
4790
4931
|
this.canvas = canvas;
|
|
4791
4932
|
this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
|
|
4792
4933
|
this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
|
|
4793
4934
|
this.maxDPR = options.maxDPR;
|
|
4794
4935
|
if (this.disableWindowResize) {
|
|
4795
|
-
const styleWidth = parseInlinePx(_optionalChain([canvas, 'access',
|
|
4796
|
-
const styleHeight = parseInlinePx(_optionalChain([canvas, 'access',
|
|
4936
|
+
const styleWidth = parseInlinePx(_optionalChain([canvas, 'access', _111 => _111.style, 'optionalAccess', _112 => _112.width]));
|
|
4937
|
+
const styleHeight = parseInlinePx(_optionalChain([canvas, 'access', _113 => _113.style, 'optionalAccess', _114 => _114.height]));
|
|
4797
4938
|
this.width = _nullishCoalesce(styleWidth, () => ( (canvas.width || canvas.clientWidth || 0)));
|
|
4798
4939
|
this.height = _nullishCoalesce(styleHeight, () => ( (canvas.height || canvas.clientHeight || 0)));
|
|
4799
4940
|
} else {
|
|
4800
|
-
|
|
4801
|
-
|
|
4941
|
+
if (typeof canvas.isConnected === "boolean" && !canvas.isConnected) {
|
|
4942
|
+
this.width = 0;
|
|
4943
|
+
this.height = 0;
|
|
4944
|
+
} else {
|
|
4945
|
+
this.width = typeof window !== "undefined" ? window.innerWidth : canvas.clientWidth || canvas.width || 800;
|
|
4946
|
+
this.height = typeof window !== "undefined" ? window.innerHeight : canvas.clientHeight || canvas.height || 600;
|
|
4947
|
+
}
|
|
4802
4948
|
}
|
|
4803
4949
|
const globalProcess = typeof globalThis !== "undefined" ? globalThis.process : void 0;
|
|
4804
|
-
const isTest = globalProcess && (_optionalChain([globalProcess, 'access',
|
|
4950
|
+
const isTest = globalProcess && (_optionalChain([globalProcess, 'access', _115 => _115.env, 'optionalAccess', _116 => _116.NODE_ENV]) === "test" || _optionalChain([globalProcess, 'access', _117 => _117.env, 'optionalAccess', _118 => _118.VITEST]) === "true");
|
|
4805
4951
|
this.maxFPS = _nullishCoalesce(options.maxFPS, () => ( (isTest ? 0 : 60)));
|
|
4806
4952
|
this.respectReducedMotion = _nullishCoalesce(options.respectReducedMotion, () => ( true));
|
|
4807
4953
|
this.autoThrottle = _nullishCoalesce(options.autoThrottle, () => ( true));
|
|
@@ -4816,15 +4962,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
4816
4962
|
this.readingDirection = _nullishCoalesce(options.readingDirection, () => ( "ltr"));
|
|
4817
4963
|
this.renderMode = _nullishCoalesce(options.renderMode, () => ( "always"));
|
|
4818
4964
|
this._devActive = _Scene._devModeDetected();
|
|
4819
|
-
|
|
4965
|
+
_chunkBKXERWADjs.setRendererDevMode.call(void 0, this._devActive);
|
|
4820
4966
|
this._warnUnknownOptions(options);
|
|
4821
4967
|
this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
|
|
4822
4968
|
if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
|
|
4823
4969
|
this.forcedColorsQuery = window.matchMedia("(forced-colors: active)");
|
|
4824
4970
|
this.forcedColorsChangeHandler = () => this.markDirty();
|
|
4825
|
-
_optionalChain([this, 'access',
|
|
4971
|
+
_optionalChain([this, 'access', _119 => _119.forcedColorsQuery, 'access', _120 => _120.addEventListener, 'optionalCall', _121 => _121("change", this.forcedColorsChangeHandler)]);
|
|
4826
4972
|
}
|
|
4827
|
-
this.root = new class RootEntity extends
|
|
4973
|
+
this.root = new class RootEntity extends _chunkPOPXUPKRjs.Entity {
|
|
4828
4974
|
isPointInside() {
|
|
4829
4975
|
return false;
|
|
4830
4976
|
}
|
|
@@ -4834,7 +4980,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4834
4980
|
}("root");
|
|
4835
4981
|
this.root._scene = this;
|
|
4836
4982
|
this._wasmBackend = new WasmBackendFacade(this.root);
|
|
4837
|
-
this.overlayRoot = new class OverlayRoot extends
|
|
4983
|
+
this.overlayRoot = new class OverlayRoot extends _chunkPOPXUPKRjs.Entity {
|
|
4838
4984
|
isPointInside() {
|
|
4839
4985
|
return false;
|
|
4840
4986
|
}
|
|
@@ -4847,15 +4993,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
4847
4993
|
if (options.renderer) {
|
|
4848
4994
|
this.renderer = options.renderer;
|
|
4849
4995
|
} else {
|
|
4850
|
-
this.renderer = new (0,
|
|
4996
|
+
this.renderer = new (0, _chunkBKXERWADjs.CanvasRenderer)(
|
|
4851
4997
|
canvas,
|
|
4852
4998
|
this.disableWindowResize ? { width: this.width, height: this.height } : void 0,
|
|
4853
4999
|
this.maxDPR
|
|
4854
5000
|
);
|
|
4855
5001
|
}
|
|
4856
|
-
_optionalChain([this, 'access',
|
|
5002
|
+
_optionalChain([this, 'access', _122 => _122.renderer, 'access', _123 => _123.onContextRestored, 'optionalCall', _124 => _124(() => {
|
|
4857
5003
|
this.markDirty();
|
|
4858
|
-
if (_optionalChain([this, 'access',
|
|
5004
|
+
if (_optionalChain([this, 'access', _125 => _125.renderer, 'access', _126 => _126.isContextLost, 'optionalCall', _127 => _127()]) !== true) this.render(this.renderer);
|
|
4859
5005
|
})]);
|
|
4860
5006
|
if (typeof document !== "undefined") {
|
|
4861
5007
|
this.a11yRoot = document.createElement("div");
|
|
@@ -5028,18 +5174,54 @@ var Scene = (_class15 = class _Scene {
|
|
|
5028
5174
|
watchDevicePixelRatio() {
|
|
5029
5175
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
5030
5176
|
if (this.dprMediaQuery && this.dprChangeHandler) {
|
|
5031
|
-
_optionalChain([this, 'access',
|
|
5177
|
+
_optionalChain([this, 'access', _128 => _128.dprMediaQuery, 'access', _129 => _129.removeEventListener, 'optionalCall', _130 => _130("change", this.dprChangeHandler)]);
|
|
5032
5178
|
}
|
|
5033
|
-
const
|
|
5179
|
+
const raw = window.devicePixelRatio;
|
|
5180
|
+
const dpr = Number.isFinite(raw) && raw > 0 ? raw : 1;
|
|
5034
5181
|
const query = window.matchMedia(`(resolution: ${dpr}dppx)`);
|
|
5035
5182
|
const handler = () => {
|
|
5036
|
-
|
|
5037
|
-
|
|
5183
|
+
const curRaw = window.devicePixelRatio;
|
|
5184
|
+
const cur = Number.isFinite(curRaw) && curRaw > 0 ? curRaw : 1;
|
|
5185
|
+
if (Math.abs(cur - dpr) <= 1e-3) {
|
|
5186
|
+
this.watchDevicePixelRatio();
|
|
5187
|
+
return;
|
|
5188
|
+
}
|
|
5189
|
+
this.lastDpr = cur;
|
|
5190
|
+
try {
|
|
5191
|
+
this.resize(this.width, this.height);
|
|
5192
|
+
} catch (err) {
|
|
5193
|
+
console.warn("[VectoJS] DPR resize failed", err);
|
|
5194
|
+
}
|
|
5195
|
+
try {
|
|
5196
|
+
if (_optionalChain([this, 'access', _131 => _131.renderer, 'access', _132 => _132.isContextLost, 'optionalCall', _133 => _133()]) !== true) this.render(this.renderer);
|
|
5197
|
+
} catch (err) {
|
|
5198
|
+
console.warn("[VectoJS] DPR repaint failed", err);
|
|
5199
|
+
}
|
|
5038
5200
|
this.watchDevicePixelRatio();
|
|
5039
5201
|
};
|
|
5040
|
-
_optionalChain([query, 'access',
|
|
5202
|
+
_optionalChain([query, 'access', _134 => _134.addEventListener, 'optionalCall', _135 => _135("change", handler)]);
|
|
5041
5203
|
this.dprMediaQuery = query;
|
|
5042
5204
|
this.dprChangeHandler = handler;
|
|
5205
|
+
this.lastDpr = dpr;
|
|
5206
|
+
if (this.dprPollInterval === null && typeof setInterval === "function") {
|
|
5207
|
+
this.dprPollInterval = setInterval(() => {
|
|
5208
|
+
const rawPoll = window.devicePixelRatio;
|
|
5209
|
+
const curPoll = Number.isFinite(rawPoll) && rawPoll > 0 ? rawPoll : 1;
|
|
5210
|
+
if (Math.abs(curPoll - this.lastDpr) <= 1e-3) return;
|
|
5211
|
+
this.lastDpr = curPoll;
|
|
5212
|
+
try {
|
|
5213
|
+
this.resize(this.width, this.height);
|
|
5214
|
+
} catch (err) {
|
|
5215
|
+
console.warn("[VectoJS] DPR poll resize failed", err);
|
|
5216
|
+
}
|
|
5217
|
+
try {
|
|
5218
|
+
if (_optionalChain([this, 'access', _136 => _136.renderer, 'access', _137 => _137.isContextLost, 'optionalCall', _138 => _138()]) !== true) this.render(this.renderer);
|
|
5219
|
+
} catch (err) {
|
|
5220
|
+
console.warn("[VectoJS] DPR poll repaint failed", err);
|
|
5221
|
+
}
|
|
5222
|
+
this.watchDevicePixelRatio();
|
|
5223
|
+
}, 1e3);
|
|
5224
|
+
}
|
|
5043
5225
|
}
|
|
5044
5226
|
/**
|
|
5045
5227
|
* Recover the WebGL point layer from a GPU context loss (driver TDR reset,
|
|
@@ -5057,7 +5239,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5057
5239
|
if (typeof gl.addEventListener !== "function") return;
|
|
5058
5240
|
this.glContextLostHandler = (e) => {
|
|
5059
5241
|
e.preventDefault();
|
|
5060
|
-
_optionalChain([this, 'access',
|
|
5242
|
+
_optionalChain([this, 'access', _139 => _139.pointRenderer, 'optionalAccess', _140 => _140.destroy, 'call', _141 => _141()]);
|
|
5061
5243
|
this.pointRenderer = null;
|
|
5062
5244
|
};
|
|
5063
5245
|
this.glContextRestoredHandler = () => {
|
|
@@ -5073,6 +5255,35 @@ var Scene = (_class15 = class _Scene {
|
|
|
5073
5255
|
gl.addEventListener("webglcontextlost", this.glContextLostHandler);
|
|
5074
5256
|
gl.addEventListener("webglcontextrestored", this.glContextRestoredHandler);
|
|
5075
5257
|
}
|
|
5258
|
+
/**
|
|
5259
|
+
* One-shot adoption of the window viewport once an initially-detached canvas
|
|
5260
|
+
* gains layout (#817). A full-window scene constructed before its canvas is
|
|
5261
|
+
* attached starts at 0×0, and no window `resize` fires on attachment — so
|
|
5262
|
+
* without this latch the scene would stay unsized forever. The first nonzero
|
|
5263
|
+
* layout box adopts `window.innerWidth/innerHeight` (the same sizing the
|
|
5264
|
+
* window resize handler applies, keeping the full-window contract), then the
|
|
5265
|
+
* observer disconnects: steady-state sizing stays exactly as if the canvas
|
|
5266
|
+
* had been attached before construction. An explicit user `resize()` between
|
|
5267
|
+
* construction and attachment is respected and skips adoption.
|
|
5268
|
+
*
|
|
5269
|
+
* No-op when the scene already has a size (attached at construction) or when
|
|
5270
|
+
* `ResizeObserver` is unavailable (the caller then drives sizing explicitly).
|
|
5271
|
+
*/
|
|
5272
|
+
armAttachmentViewportLatch() {
|
|
5273
|
+
if (this.width > 0 && this.height > 0) return;
|
|
5274
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
5275
|
+
const observer = new ResizeObserver((entries) => {
|
|
5276
|
+
const box = _optionalChain([entries, 'access', _142 => _142[0], 'optionalAccess', _143 => _143.contentRect]);
|
|
5277
|
+
if (!box || !(box.width > 0) || !(box.height > 0)) return;
|
|
5278
|
+
observer.disconnect();
|
|
5279
|
+
this.canvasResizeObserver = null;
|
|
5280
|
+
if (this.width === 0 || this.height === 0) {
|
|
5281
|
+
this.resize(window.innerWidth, window.innerHeight);
|
|
5282
|
+
}
|
|
5283
|
+
});
|
|
5284
|
+
this.canvasResizeObserver = observer;
|
|
5285
|
+
observer.observe(this.canvas);
|
|
5286
|
+
}
|
|
5076
5287
|
// --- domain: scene-facade — renderer accessor ---
|
|
5077
5288
|
/**
|
|
5078
5289
|
* Expose the underlying {@link IRenderer} for advanced direct-draw operations.
|
|
@@ -5154,7 +5365,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5154
5365
|
}
|
|
5155
5366
|
if (this.hoveredA11yElements.has(el)) {
|
|
5156
5367
|
this.hoveredA11yElements.delete(el);
|
|
5157
|
-
node.dispatchEvent(new (0,
|
|
5368
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("pointerleave", node, void 0, false));
|
|
5158
5369
|
}
|
|
5159
5370
|
this.preserveFocusOnRemoval(el);
|
|
5160
5371
|
el.remove();
|
|
@@ -5254,12 +5465,16 @@ var Scene = (_class15 = class _Scene {
|
|
|
5254
5465
|
this.canvasResizeObserver = null;
|
|
5255
5466
|
}
|
|
5256
5467
|
if (this.dprMediaQuery && this.dprChangeHandler) {
|
|
5257
|
-
_optionalChain([this, 'access',
|
|
5468
|
+
_optionalChain([this, 'access', _144 => _144.dprMediaQuery, 'access', _145 => _145.removeEventListener, 'optionalCall', _146 => _146("change", this.dprChangeHandler)]);
|
|
5258
5469
|
this.dprMediaQuery = null;
|
|
5259
5470
|
this.dprChangeHandler = null;
|
|
5260
5471
|
}
|
|
5472
|
+
if (this.dprPollInterval !== null) {
|
|
5473
|
+
clearInterval(this.dprPollInterval);
|
|
5474
|
+
this.dprPollInterval = null;
|
|
5475
|
+
}
|
|
5261
5476
|
if (this.forcedColorsQuery && this.forcedColorsChangeHandler) {
|
|
5262
|
-
_optionalChain([this, 'access',
|
|
5477
|
+
_optionalChain([this, 'access', _147 => _147.forcedColorsQuery, 'access', _148 => _148.removeEventListener, 'optionalCall', _149 => _149("change", this.forcedColorsChangeHandler)]);
|
|
5263
5478
|
this.forcedColorsQuery = null;
|
|
5264
5479
|
this.forcedColorsChangeHandler = null;
|
|
5265
5480
|
}
|
|
@@ -5268,6 +5483,19 @@ var Scene = (_class15 = class _Scene {
|
|
|
5268
5483
|
window.removeEventListener("blur", this.contentSelectionEndListener);
|
|
5269
5484
|
this.contentSelectionEndListener = null;
|
|
5270
5485
|
}
|
|
5486
|
+
if (typeof window !== "undefined") {
|
|
5487
|
+
if (this.windowKeyDownHandler) {
|
|
5488
|
+
window.removeEventListener("keydown", this.windowKeyDownHandler);
|
|
5489
|
+
}
|
|
5490
|
+
if (this.windowKeyUpHandler) {
|
|
5491
|
+
window.removeEventListener("keyup", this.windowKeyUpHandler);
|
|
5492
|
+
}
|
|
5493
|
+
}
|
|
5494
|
+
this.windowKeyDownHandler = null;
|
|
5495
|
+
this.windowKeyUpHandler = null;
|
|
5496
|
+
this.keydownHandlers.length = 0;
|
|
5497
|
+
this.keyupHandlers.length = 0;
|
|
5498
|
+
this.shortcuts.length = 0;
|
|
5271
5499
|
if (typeof window !== "undefined" && this.pointerEventTarget && typeof this.pointerEventTarget.removeEventListener === "function") {
|
|
5272
5500
|
if (this.pointerMoveListener) {
|
|
5273
5501
|
this.pointerEventTarget.removeEventListener("pointermove", this.pointerMoveListener);
|
|
@@ -5277,9 +5505,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
5277
5505
|
}
|
|
5278
5506
|
this.pointerEventTarget = null;
|
|
5279
5507
|
}
|
|
5280
|
-
_optionalChain([this, 'access',
|
|
5508
|
+
_optionalChain([this, 'access', _150 => _150.a11yRoot, 'optionalAccess', _151 => _151.remove, 'call', _152 => _152()]);
|
|
5281
5509
|
this.focusSentinel = null;
|
|
5282
|
-
_optionalChain([this, 'access',
|
|
5510
|
+
_optionalChain([this, 'access', _153 => _153.portalRoot, 'optionalAccess', _154 => _154.remove, 'call', _155 => _155()]);
|
|
5283
5511
|
this.a11yElements.clear();
|
|
5284
5512
|
for (const el of this.contentElements.values()) el.remove();
|
|
5285
5513
|
this.contentElements.clear();
|
|
@@ -5295,10 +5523,10 @@ var Scene = (_class15 = class _Scene {
|
|
|
5295
5523
|
}
|
|
5296
5524
|
this.glContextLostHandler = null;
|
|
5297
5525
|
this.glContextRestoredHandler = null;
|
|
5298
|
-
_optionalChain([this, 'access',
|
|
5299
|
-
_optionalChain([this, 'access',
|
|
5300
|
-
_optionalChain([this, 'access',
|
|
5301
|
-
_optionalChain([this, 'access',
|
|
5526
|
+
_optionalChain([this, 'access', _156 => _156.pointRenderer, 'optionalAccess', _157 => _157.destroy, 'call', _158 => _158()]);
|
|
5527
|
+
_optionalChain([this, 'access', _159 => _159.renderer, 'access', _160 => _160.dispose, 'optionalCall', _161 => _161()]);
|
|
5528
|
+
_optionalChain([this, 'access', _162 => _162.glCanvas, 'optionalAccess', _163 => _163.remove, 'call', _164 => _164()]);
|
|
5529
|
+
_optionalChain([this, 'access', _165 => _165.gpuCanvas, 'optionalAccess', _166 => _166.remove, 'call', _167 => _167()]);
|
|
5302
5530
|
this.gpuCanvas = null;
|
|
5303
5531
|
this.gpuContext = null;
|
|
5304
5532
|
if (this.recoveryTimerId) {
|
|
@@ -5310,7 +5538,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5310
5538
|
this.manager = null;
|
|
5311
5539
|
}
|
|
5312
5540
|
if (this.device) {
|
|
5313
|
-
_optionalChain([this, 'access',
|
|
5541
|
+
_optionalChain([this, 'access', _168 => _168.device, 'access', _169 => _169.destroy, 'optionalCall', _170 => _170()]);
|
|
5314
5542
|
this.device = null;
|
|
5315
5543
|
}
|
|
5316
5544
|
}
|
|
@@ -5318,6 +5546,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5318
5546
|
setupEvents() {
|
|
5319
5547
|
if (typeof window !== "undefined" && !this.disableWindowResize) {
|
|
5320
5548
|
window.addEventListener("resize", this.resizeHandler);
|
|
5549
|
+
this.armAttachmentViewportLatch();
|
|
5321
5550
|
} else if (this.disableWindowResize && typeof ResizeObserver !== "undefined" && this.canvas && typeof this.canvas.getBoundingClientRect === "function") {
|
|
5322
5551
|
this.canvasResizeObserver = new ResizeObserver((entries) => {
|
|
5323
5552
|
const entry = entries[0];
|
|
@@ -5367,6 +5596,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5367
5596
|
this.lastTime = typeof performance !== "undefined" ? performance.now() : 0;
|
|
5368
5597
|
this.watchCanvasVisibility();
|
|
5369
5598
|
this.scheduleFrame();
|
|
5599
|
+
this.attachWindowKeyListeners();
|
|
5370
5600
|
const isTextFocused = this.focusedA11yElement instanceof HTMLInputElement || this.focusedA11yElement instanceof HTMLTextAreaElement;
|
|
5371
5601
|
if (isTextFocused && this.renderMode === "onDemand" && !this.caretBlinkTimer) {
|
|
5372
5602
|
this.caretBlinkTimer = setInterval(() => {
|
|
@@ -5434,6 +5664,132 @@ var Scene = (_class15 = class _Scene {
|
|
|
5434
5664
|
}
|
|
5435
5665
|
this._canvasOnScreen = true;
|
|
5436
5666
|
}
|
|
5667
|
+
// --- domain: input — scene-level keyboard channel ---
|
|
5668
|
+
/**
|
|
5669
|
+
* Register a listener on the scene-level keyboard channel.
|
|
5670
|
+
*
|
|
5671
|
+
* Mirrors {@link Entity.on} minus the options parameter (bubble-only, and
|
|
5672
|
+
* there is no capture phase for a single window tap). Handlers fire only
|
|
5673
|
+
* when ALL of these hold:
|
|
5674
|
+
*
|
|
5675
|
+
* 1. the native event was not already `defaultPrevented`,
|
|
5676
|
+
* 2. it is not an auto-repeat (`e.repeat`),
|
|
5677
|
+
* 3. `document.activeElement` does not own the keyboard
|
|
5678
|
+
* (see {@link ownsKeyboard}) — typing in an `<input>` or focusing a
|
|
5679
|
+
* slider-role element suppresses the scene channel, unconditionally,
|
|
5680
|
+
* including modifier chords.
|
|
5681
|
+
*
|
|
5682
|
+
* The listeners are window-level BUBBLE-phase taps, so an entity handler
|
|
5683
|
+
* that calls `nativeEvent.stopPropagation()` keeps the key from ever
|
|
5684
|
+
* reaching this channel. Deliberately not registered in the capture phase:
|
|
5685
|
+
* a window-capture listener would preempt Modal's document-capture trap.
|
|
5686
|
+
*
|
|
5687
|
+
* Listeners attach at `start()` and survive `stop()`; only `destroy()`
|
|
5688
|
+
* removes them.
|
|
5689
|
+
*
|
|
5690
|
+
* @param event - `'keydown'` or `'keyup'`; anything else is rejected with a
|
|
5691
|
+
* dev warning (guards JS callers — TypeScript already narrows this).
|
|
5692
|
+
* @param callback - Handler invoked with a {@link SceneKeyEvent}.
|
|
5693
|
+
* @returns `this` for method chaining.
|
|
5694
|
+
*/
|
|
5695
|
+
on(event, callback) {
|
|
5696
|
+
if (event !== "keydown" && event !== "keyup") {
|
|
5697
|
+
console.warn(
|
|
5698
|
+
`[VectoJS] Scene.on: unsupported event '${String(event)}'. Only 'keydown' and 'keyup' are supported.`
|
|
5699
|
+
);
|
|
5700
|
+
return this;
|
|
5701
|
+
}
|
|
5702
|
+
(event === "keydown" ? this.keydownHandlers : this.keyupHandlers).push(callback);
|
|
5703
|
+
return this;
|
|
5704
|
+
}
|
|
5705
|
+
/**
|
|
5706
|
+
* Remove a listener previously registered with {@link Scene.on}. Silent
|
|
5707
|
+
* no-op for unknown handlers, unsupported event names, or after
|
|
5708
|
+
* {@link Scene.destroy}.
|
|
5709
|
+
*
|
|
5710
|
+
* @returns `this` for method chaining.
|
|
5711
|
+
*/
|
|
5712
|
+
off(event, callback) {
|
|
5713
|
+
if (event !== "keydown" && event !== "keyup") {
|
|
5714
|
+
console.warn(
|
|
5715
|
+
`[VectoJS] Scene.off: unsupported event '${String(event)}'. Only 'keydown' and 'keyup' are supported.`
|
|
5716
|
+
);
|
|
5717
|
+
return this;
|
|
5718
|
+
}
|
|
5719
|
+
const handlers = event === "keydown" ? this.keydownHandlers : this.keyupHandlers;
|
|
5720
|
+
const idx = handlers.indexOf(callback);
|
|
5721
|
+
if (idx !== -1) handlers.splice(idx, 1);
|
|
5722
|
+
return this;
|
|
5723
|
+
}
|
|
5724
|
+
/**
|
|
5725
|
+
* Sugar over the keyboard channel: invoke `spec.handler` whenever a
|
|
5726
|
+
* non-repeat `keydown` whose normalized chord matches `spec.chord`
|
|
5727
|
+
* (via {@link normalizeChord}) passes the same gates as {@link Scene.on} —
|
|
5728
|
+
* including the unconditional `ownsKeyboard(activeElement)` suppression.
|
|
5729
|
+
*
|
|
5730
|
+
* @param spec - `{ chord, handler }`; the chord is normalized once at
|
|
5731
|
+
* registration, so `'ctrl+n'`, `'Control+n'` and `'Ctrl+N'` are aliases.
|
|
5732
|
+
* @returns `this` for method chaining.
|
|
5733
|
+
*/
|
|
5734
|
+
registerShortcut(spec) {
|
|
5735
|
+
this.shortcuts.push({ chord: normalizeChord(spec.chord), handler: spec.handler });
|
|
5736
|
+
return this;
|
|
5737
|
+
}
|
|
5738
|
+
/**
|
|
5739
|
+
* Remove a shortcut previously registered with {@link Scene.registerShortcut}.
|
|
5740
|
+
* Matches on normalized chord + exact handler reference; silent no-op when
|
|
5741
|
+
* nothing matches.
|
|
5742
|
+
*
|
|
5743
|
+
* @param spec - The same spec object (chord spelling may differ; it is
|
|
5744
|
+
* re-normalized before matching).
|
|
5745
|
+
* @returns `this` for method chaining.
|
|
5746
|
+
*/
|
|
5747
|
+
unregisterShortcut(spec) {
|
|
5748
|
+
const chord = normalizeChord(spec.chord);
|
|
5749
|
+
const idx = this.shortcuts.findIndex((s) => s.chord === chord && s.handler === spec.handler);
|
|
5750
|
+
if (idx !== -1) this.shortcuts.splice(idx, 1);
|
|
5751
|
+
return this;
|
|
5752
|
+
}
|
|
5753
|
+
/** Attach the window bubble-phase keyboard listeners exactly once. */
|
|
5754
|
+
attachWindowKeyListeners() {
|
|
5755
|
+
if (this.windowKeyDownHandler || typeof window === "undefined") return;
|
|
5756
|
+
this.windowKeyDownHandler = (e) => this.dispatchKeyboard(e, "keydown");
|
|
5757
|
+
this.windowKeyUpHandler = (e) => this.dispatchKeyboard(e, "keyup");
|
|
5758
|
+
window.addEventListener("keydown", this.windowKeyDownHandler);
|
|
5759
|
+
window.addEventListener("keyup", this.windowKeyUpHandler);
|
|
5760
|
+
}
|
|
5761
|
+
/**
|
|
5762
|
+
* Gate a native keyboard event and fan it out to scene handlers +
|
|
5763
|
+
* chord-matched shortcuts. See {@link Scene.on} for the gate contract.
|
|
5764
|
+
*/
|
|
5765
|
+
dispatchKeyboard(e, type) {
|
|
5766
|
+
if (e.defaultPrevented) return;
|
|
5767
|
+
if (e.repeat) return;
|
|
5768
|
+
const active = typeof document !== "undefined" ? document.activeElement : null;
|
|
5769
|
+
if (ownsKeyboard(active)) return;
|
|
5770
|
+
const event = {
|
|
5771
|
+
type,
|
|
5772
|
+
key: e.key,
|
|
5773
|
+
code: e.code,
|
|
5774
|
+
repeat: e.repeat,
|
|
5775
|
+
ctrlKey: e.ctrlKey,
|
|
5776
|
+
altKey: e.altKey,
|
|
5777
|
+
shiftKey: e.shiftKey,
|
|
5778
|
+
metaKey: e.metaKey,
|
|
5779
|
+
target: e.target,
|
|
5780
|
+
nativeEvent: e,
|
|
5781
|
+
stopPropagation: () => e.stopPropagation(),
|
|
5782
|
+
preventDefault: () => e.preventDefault()
|
|
5783
|
+
};
|
|
5784
|
+
const handlers = type === "keydown" ? this.keydownHandlers : this.keyupHandlers;
|
|
5785
|
+
for (const handler of [...handlers]) handler(event);
|
|
5786
|
+
if (type === "keydown") {
|
|
5787
|
+
const chord = normalizeChord(e);
|
|
5788
|
+
for (const shortcut of [...this.shortcuts]) {
|
|
5789
|
+
if (shortcut.chord === chord) shortcut.handler(event);
|
|
5790
|
+
}
|
|
5791
|
+
}
|
|
5792
|
+
}
|
|
5437
5793
|
// --- domain: scene-facade — tree accessors ---
|
|
5438
5794
|
/**
|
|
5439
5795
|
* Manually advance the scene clock by `dt` milliseconds and render synchronously.
|
|
@@ -5635,7 +5991,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5635
5991
|
if (this.mouseX > -9e3 && !this.projectsSelectableText(node)) {
|
|
5636
5992
|
if (node.isPointInside(this.mouseX, this.mouseY)) return true;
|
|
5637
5993
|
}
|
|
5638
|
-
const existing = _optionalChain([this, 'access',
|
|
5994
|
+
const existing = _optionalChain([this, 'access', _171 => _171.a11yElements, 'optionalAccess', _172 => _172.get, 'call', _173 => _173(node.id)]);
|
|
5639
5995
|
if (existing && typeof document !== "undefined" && document.activeElement === existing) {
|
|
5640
5996
|
return true;
|
|
5641
5997
|
}
|
|
@@ -5649,8 +6005,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
5649
6005
|
* selection.
|
|
5650
6006
|
*/
|
|
5651
6007
|
projectsSelectableText(node) {
|
|
5652
|
-
const projection = _optionalChain([node, 'access',
|
|
5653
|
-
return !!_optionalChain([projection, 'optionalAccess',
|
|
6008
|
+
const projection = _optionalChain([node, 'access', _174 => _174.getContentProjection, 'optionalCall', _175 => _175()]);
|
|
6009
|
+
return !!_optionalChain([projection, 'optionalAccess', _176 => _176.text]) && projection.selectable !== false;
|
|
5654
6010
|
}
|
|
5655
6011
|
/**
|
|
5656
6012
|
* Keep `entity`'s a11y shadow node projected while it has
|
|
@@ -5745,20 +6101,20 @@ var Scene = (_class15 = class _Scene {
|
|
|
5745
6101
|
el.style.background = "transparent";
|
|
5746
6102
|
}
|
|
5747
6103
|
el.addEventListener("click", (e) => {
|
|
5748
|
-
node.dispatchEvent(new (0,
|
|
6104
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("click", node, e));
|
|
5749
6105
|
});
|
|
5750
6106
|
el.addEventListener("dblclick", (e) => {
|
|
5751
|
-
node.dispatchEvent(new (0,
|
|
6107
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("dblclick", node, e));
|
|
5752
6108
|
});
|
|
5753
6109
|
el.addEventListener("mouseenter", (e) => {
|
|
5754
6110
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
|
|
5755
6111
|
this.hoveredA11yElements.add(el);
|
|
5756
|
-
node.dispatchEvent(new (0,
|
|
6112
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("hover", node, e, false));
|
|
5757
6113
|
});
|
|
5758
6114
|
el.addEventListener("mouseleave", (e) => {
|
|
5759
6115
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
|
|
5760
6116
|
this.hoveredA11yElements.delete(el);
|
|
5761
|
-
node.dispatchEvent(new (0,
|
|
6117
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("pointerleave", node, e, false));
|
|
5762
6118
|
});
|
|
5763
6119
|
const capEl = el;
|
|
5764
6120
|
const releasePointer = (event) => {
|
|
@@ -5776,24 +6132,24 @@ var Scene = (_class15 = class _Scene {
|
|
|
5776
6132
|
if (e.target === capEl && typeof capEl.setPointerCapture === "function") {
|
|
5777
6133
|
capEl.setPointerCapture(e.pointerId);
|
|
5778
6134
|
}
|
|
5779
|
-
node.dispatchEvent(new (0,
|
|
6135
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("pointerdown", node, e));
|
|
5780
6136
|
});
|
|
5781
6137
|
el.addEventListener("pointerup", (e) => {
|
|
5782
6138
|
releasePointer(e);
|
|
5783
|
-
node.dispatchEvent(new (0,
|
|
6139
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("pointerup", node, e));
|
|
5784
6140
|
});
|
|
5785
6141
|
el.addEventListener("pointercancel", (e) => {
|
|
5786
6142
|
releasePointer(e);
|
|
5787
|
-
node.dispatchEvent(new (0,
|
|
6143
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("pointercancel", node, e));
|
|
5788
6144
|
});
|
|
5789
6145
|
el.addEventListener(
|
|
5790
6146
|
"pointermove",
|
|
5791
|
-
(e) => node.dispatchEvent(new (0,
|
|
6147
|
+
(e) => node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("pointermove", node, e))
|
|
5792
6148
|
);
|
|
5793
6149
|
el.addEventListener(
|
|
5794
6150
|
"wheel",
|
|
5795
6151
|
(e) => {
|
|
5796
|
-
node.dispatchEvent(new (0,
|
|
6152
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("wheel", node, e));
|
|
5797
6153
|
},
|
|
5798
6154
|
{ passive: false }
|
|
5799
6155
|
);
|
|
@@ -5818,10 +6174,10 @@ var Scene = (_class15 = class _Scene {
|
|
|
5818
6174
|
);
|
|
5819
6175
|
emitInitialScroll = emitScroll;
|
|
5820
6176
|
el.addEventListener("keydown", (e) => {
|
|
5821
|
-
node.dispatchEvent(new (0,
|
|
6177
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("keydown", node, e));
|
|
5822
6178
|
});
|
|
5823
6179
|
el.addEventListener("keyup", (e) => {
|
|
5824
|
-
node.dispatchEvent(new (0,
|
|
6180
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("keyup", node, e));
|
|
5825
6181
|
});
|
|
5826
6182
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
5827
6183
|
const input = el;
|
|
@@ -5852,7 +6208,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5852
6208
|
el.addEventListener("compositionupdate", (e) => {
|
|
5853
6209
|
const data = _nullishCoalesce(e.data, () => ( ""));
|
|
5854
6210
|
composition = {
|
|
5855
|
-
start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess',
|
|
6211
|
+
start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _177 => _177.start]), () => ( 0)),
|
|
5856
6212
|
length: data.length
|
|
5857
6213
|
};
|
|
5858
6214
|
forward();
|
|
@@ -5883,14 +6239,6 @@ var Scene = (_class15 = class _Scene {
|
|
|
5883
6239
|
}
|
|
5884
6240
|
node.emit("blur", {});
|
|
5885
6241
|
});
|
|
5886
|
-
if (!isNativelyFocusable(el) && attrs.role && INTERACTIVE_A11Y_ROLES.has(attrs.role)) {
|
|
5887
|
-
el.addEventListener("keydown", (e) => {
|
|
5888
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
5889
|
-
e.preventDefault();
|
|
5890
|
-
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("click", node, e));
|
|
5891
|
-
}
|
|
5892
|
-
});
|
|
5893
|
-
}
|
|
5894
6242
|
if (node.a11yFullViewport) {
|
|
5895
6243
|
this.a11yRoot.insertBefore(el, this.a11yRoot.firstChild);
|
|
5896
6244
|
} else {
|
|
@@ -5909,7 +6257,24 @@ var Scene = (_class15 = class _Scene {
|
|
|
5909
6257
|
if (renderOrder !== void 0 && el.style.zIndex !== String(renderOrder)) {
|
|
5910
6258
|
el.style.zIndex = String(renderOrder);
|
|
5911
6259
|
}
|
|
5912
|
-
const
|
|
6260
|
+
const interactiveRole = !isNativelyFocusable(el) && !!attrs.role && INTERACTIVE_A11Y_ROLES.has(attrs.role);
|
|
6261
|
+
if (interactiveRole && !this.keyboardActivatedA11y.has(el)) {
|
|
6262
|
+
el.addEventListener("keydown", (e) => {
|
|
6263
|
+
if (e.key === "Enter") {
|
|
6264
|
+
e.preventDefault();
|
|
6265
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("click", node, e));
|
|
6266
|
+
} else if (e.key === " ") {
|
|
6267
|
+
e.preventDefault();
|
|
6268
|
+
}
|
|
6269
|
+
});
|
|
6270
|
+
el.addEventListener("keyup", (e) => {
|
|
6271
|
+
if (e.key === " ") {
|
|
6272
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("click", node, e));
|
|
6273
|
+
}
|
|
6274
|
+
});
|
|
6275
|
+
this.keyboardActivatedA11y.add(el);
|
|
6276
|
+
}
|
|
6277
|
+
const implicitTabIndex = interactiveRole ? 0 : null;
|
|
5913
6278
|
const desiredTabIndex = _nullishCoalesce(attrs.tabIndex, () => ( implicitTabIndex));
|
|
5914
6279
|
if (desiredTabIndex === null) {
|
|
5915
6280
|
if (el.hasAttribute("tabindex")) el.removeAttribute("tabindex");
|
|
@@ -5925,7 +6290,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5925
6290
|
this.syncOptionalAttribute(
|
|
5926
6291
|
el,
|
|
5927
6292
|
"href",
|
|
5928
|
-
attrs.href === void 0 ? void 0 :
|
|
6293
|
+
attrs.href === void 0 ? void 0 : _chunkBKXERWADjs.sanitizeUrl.call(void 0, attrs.href)
|
|
5929
6294
|
);
|
|
5930
6295
|
this.syncOptionalAttribute(el, "target", attrs.target);
|
|
5931
6296
|
}
|
|
@@ -6094,7 +6459,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6094
6459
|
const display = visible ? "" : "none";
|
|
6095
6460
|
if (el.style.display !== display) el.style.display = display;
|
|
6096
6461
|
}
|
|
6097
|
-
_optionalChain([emitInitialScroll, 'optionalCall',
|
|
6462
|
+
_optionalChain([emitInitialScroll, 'optionalCall', _178 => _178()]);
|
|
6098
6463
|
}
|
|
6099
6464
|
if (this.phases.enabled) {
|
|
6100
6465
|
const projectionStart = performance.now();
|
|
@@ -6324,7 +6689,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6324
6689
|
el.addEventListener(
|
|
6325
6690
|
"wheel",
|
|
6326
6691
|
(e2) => {
|
|
6327
|
-
node.dispatchEvent(new (0,
|
|
6692
|
+
node.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)("wheel", node, e2));
|
|
6328
6693
|
},
|
|
6329
6694
|
{ passive: false }
|
|
6330
6695
|
);
|
|
@@ -6555,8 +6920,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
6555
6920
|
next.f = f2;
|
|
6556
6921
|
next.tier = tier;
|
|
6557
6922
|
next.hasBand = lineBand !== null;
|
|
6558
|
-
next.bandMin = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess',
|
|
6559
|
-
next.bandMax = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess',
|
|
6923
|
+
next.bandMin = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess', _179 => _179.minY]), () => ( 0));
|
|
6924
|
+
next.bandMax = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess', _180 => _180.maxY]), () => ( 0));
|
|
6560
6925
|
next.visible = visible;
|
|
6561
6926
|
next.width = node.width;
|
|
6562
6927
|
next.height = node.height;
|
|
@@ -6742,7 +7107,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6742
7107
|
* (and {@link respectReducedMotion} is on). `0` means uncapped.
|
|
6743
7108
|
*/
|
|
6744
7109
|
effectiveMaxFPS() {
|
|
6745
|
-
const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access',
|
|
7110
|
+
const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _181 => _181.reducedMotionQuery, 'optionalAccess', _182 => _182.matches]);
|
|
6746
7111
|
if (reduced)
|
|
6747
7112
|
return this.maxFPS > 0 ? Math.min(this.maxFPS, REDUCED_MOTION_FPS) : REDUCED_MOTION_FPS;
|
|
6748
7113
|
return this.maxFPS;
|
|
@@ -6837,7 +7202,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6837
7202
|
* @param time - Current absolute time in milliseconds (default 0).
|
|
6838
7203
|
*/
|
|
6839
7204
|
render(renderer, dt = 0, time = 0) {
|
|
6840
|
-
if (_optionalChain([renderer, 'access',
|
|
7205
|
+
if (_optionalChain([renderer, 'access', _183 => _183.isContextLost, 'optionalCall', _184 => _184()])) return;
|
|
6841
7206
|
const isMainRenderer = renderer === this.renderer;
|
|
6842
7207
|
if (isMainRenderer && this.a11yRoot && this.canvas.parentElement) {
|
|
6843
7208
|
const parentStyle = this.canvas.parentElement.style;
|
|
@@ -6851,6 +7216,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6851
7216
|
this.renderOrderCounter = 0;
|
|
6852
7217
|
this.a11yRenderOrders.clear();
|
|
6853
7218
|
this.activePortalsThisFrame.clear();
|
|
7219
|
+
this._updateWalkDt = dt;
|
|
6854
7220
|
this._tickBatchedDrivers(dt);
|
|
6855
7221
|
}
|
|
6856
7222
|
const computeEntities = this._computeEntitiesFor(this._structureVersion);
|
|
@@ -6986,14 +7352,14 @@ var Scene = (_class15 = class _Scene {
|
|
|
6986
7352
|
}
|
|
6987
7353
|
renderer.clear();
|
|
6988
7354
|
if (isMainRenderer) {
|
|
6989
|
-
_optionalChain([this, 'access',
|
|
7355
|
+
_optionalChain([this, 'access', _185 => _185.pointRenderer, 'optionalAccess', _186 => _186.begin, 'call', _187 => _187()]);
|
|
6990
7356
|
}
|
|
6991
7357
|
const vw = this.width;
|
|
6992
7358
|
const vh = this.height;
|
|
6993
7359
|
let walkHadAnimation = false;
|
|
6994
7360
|
let walkHadInteractive = false;
|
|
6995
7361
|
const runUpdate = (node) => {
|
|
6996
|
-
const overridesUpdate = node.update !==
|
|
7362
|
+
const overridesUpdate = node.update !== _chunkPOPXUPKRjs.Entity.prototype.update;
|
|
6997
7363
|
let pending = node.hasPendingAnimations();
|
|
6998
7364
|
if (pending || overridesUpdate) {
|
|
6999
7365
|
node.update(dt, time);
|
|
@@ -7002,7 +7368,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7002
7368
|
if (pending) walkHadAnimation = true;
|
|
7003
7369
|
if (!walkHadInteractive && node.interactive) walkHadInteractive = true;
|
|
7004
7370
|
if (this._devActive && this._devFrameCount % 120 === 0) {
|
|
7005
|
-
if (overridesUpdate && node.hasPendingAnimations ===
|
|
7371
|
+
if (overridesUpdate && node.hasPendingAnimations === _chunkPOPXUPKRjs.Entity.prototype.hasPendingAnimations) {
|
|
7006
7372
|
this._devWarn(
|
|
7007
7373
|
`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.`
|
|
7008
7374
|
);
|
|
@@ -7021,6 +7387,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7021
7387
|
};
|
|
7022
7388
|
updateWalk(this.root);
|
|
7023
7389
|
for (const overlay of this.overlayRoot.children) updateWalk(overlay);
|
|
7390
|
+
this._updateWalkDt = null;
|
|
7024
7391
|
}
|
|
7025
7392
|
const transformTiming = this.phases.userTiming ? beginVectoUserTiming(VECTO_USER_TIMING.scene.transform) : null;
|
|
7026
7393
|
const wasmT0 = this.phases.enabled ? performance.now() : 0;
|
|
@@ -7221,6 +7588,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7221
7588
|
for (const overlay of this.overlayRoot.children) {
|
|
7222
7589
|
renderNode(overlay, 1, 0, 0, 1, 0, 0, 1);
|
|
7223
7590
|
}
|
|
7591
|
+
if (isMainRenderer) this._updateWalkDt = null;
|
|
7224
7592
|
if (this.phases.enabled) this.phases.record("drawWalk", performance.now() - drawT0);
|
|
7225
7593
|
if (drawTiming) endVectoUserTiming(drawTiming);
|
|
7226
7594
|
if (this.phases.userTiming) {
|
|
@@ -7235,9 +7603,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
7235
7603
|
const flushT0 = this.phases.enabled ? performance.now() : 0;
|
|
7236
7604
|
renderer.flush();
|
|
7237
7605
|
if (isMainRenderer) {
|
|
7238
|
-
_optionalChain([this, 'access',
|
|
7606
|
+
_optionalChain([this, 'access', _188 => _188.pointRenderer, 'optionalAccess', _189 => _189.flush, 'call', _190 => _190()]);
|
|
7239
7607
|
}
|
|
7240
|
-
_optionalChain([renderer, 'access',
|
|
7608
|
+
_optionalChain([renderer, 'access', _191 => _191.present, 'optionalCall', _192 => _192()]);
|
|
7241
7609
|
if (this.phases.enabled) this.phases.record("flush", performance.now() - flushT0);
|
|
7242
7610
|
if (flushTiming) endVectoUserTiming(flushTiming);
|
|
7243
7611
|
if (this._devActive) {
|
|
@@ -7250,7 +7618,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7250
7618
|
* Export the current scene state to a lightweight, flat SVG XML string.
|
|
7251
7619
|
*/
|
|
7252
7620
|
toSVG() {
|
|
7253
|
-
const renderer = new (0,
|
|
7621
|
+
const renderer = new (0, _chunkBKXERWADjs.SVGRenderer)(this.width, this.height);
|
|
7254
7622
|
this.render(renderer, 0, 0);
|
|
7255
7623
|
return renderer.toXMLString();
|
|
7256
7624
|
}
|
|
@@ -7463,20 +7831,20 @@ function defaultMeasurer() {
|
|
|
7463
7831
|
sharedMeasurer ??= _layout.resolveGlyphMeasurer.call(void 0, "sans-serif");
|
|
7464
7832
|
return sharedMeasurer;
|
|
7465
7833
|
}
|
|
7466
|
-
var TextEntity = (_class16 = class extends
|
|
7834
|
+
var TextEntity = (_class16 = class extends _chunkPOPXUPKRjs.Entity {
|
|
7467
7835
|
|
|
7468
7836
|
|
|
7469
7837
|
|
|
7470
7838
|
|
|
7471
|
-
|
|
7839
|
+
__init191() {this.nodes = []}
|
|
7472
7840
|
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7841
|
+
__init192() {this.fillStyle = "#94a3b8"}
|
|
7842
|
+
__init193() {this.strokeStyle = null}
|
|
7843
|
+
__init194() {this.hoveredFillStyle = "#ffffff"}
|
|
7844
|
+
__init195() {this.lineWidth = 1}
|
|
7845
|
+
__init196() {this.isHovered = false}
|
|
7478
7846
|
/** Bumped by {@link applyLayout}; read by `Scene` to skip an unchanged sync. */
|
|
7479
|
-
|
|
7847
|
+
__init197() {this.contentEpoch = 0}
|
|
7480
7848
|
/**
|
|
7481
7849
|
* Visual lines with real canvas geometry, rebuilt by {@link applyLayout}
|
|
7482
7850
|
* exactly when `this.nodes` changes.
|
|
@@ -7488,9 +7856,9 @@ var TextEntity = (_class16 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
7488
7856
|
* ~0.35 em per line for a 24 px font, Firefox). Per-line carriers pin the DOM
|
|
7489
7857
|
* baseline to the canvas baseline by construction, same as `ui/Text`.
|
|
7490
7858
|
*/
|
|
7491
|
-
|
|
7859
|
+
__init198() {this.projectionLines = []}
|
|
7492
7860
|
constructor(text, atlas, maxWidth, fontSize = 24) {
|
|
7493
|
-
super();_class16.prototype.
|
|
7861
|
+
super();_class16.prototype.__init191.call(this);_class16.prototype.__init192.call(this);_class16.prototype.__init193.call(this);_class16.prototype.__init194.call(this);_class16.prototype.__init195.call(this);_class16.prototype.__init196.call(this);_class16.prototype.__init197.call(this);_class16.prototype.__init198.call(this);;
|
|
7494
7862
|
this.text = text;
|
|
7495
7863
|
this.atlas = atlas;
|
|
7496
7864
|
this.fontSize = fontSize;
|
|
@@ -7667,17 +8035,17 @@ var TextEntity = (_class16 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
7667
8035
|
}, _class16);
|
|
7668
8036
|
|
|
7669
8037
|
// src/components/GridTextEntity.ts
|
|
7670
|
-
var GridTextEntity = (_class17 = class extends
|
|
8038
|
+
var GridTextEntity = (_class17 = class extends _chunkPOPXUPKRjs.Entity {
|
|
7671
8039
|
|
|
7672
|
-
|
|
7673
|
-
|
|
8040
|
+
__init199() {this.fillStyle = "#ffffff"}
|
|
8041
|
+
__init200() {this.grid = []}
|
|
7674
8042
|
// Array of rows
|
|
7675
|
-
|
|
7676
|
-
|
|
8043
|
+
__init201() {this.cols = 0}
|
|
8044
|
+
__init202() {this.rows = 0}
|
|
7677
8045
|
|
|
7678
8046
|
|
|
7679
8047
|
constructor(_atlas, fontSize = 10) {
|
|
7680
|
-
super();_class17.prototype.
|
|
8048
|
+
super();_class17.prototype.__init199.call(this);_class17.prototype.__init200.call(this);_class17.prototype.__init201.call(this);_class17.prototype.__init202.call(this);;
|
|
7681
8049
|
this.fontSize = fontSize;
|
|
7682
8050
|
this.charWidth = fontSize * 1;
|
|
7683
8051
|
this.charHeight = fontSize * 1.1;
|
|
@@ -7686,7 +8054,7 @@ var GridTextEntity = (_class17 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
7686
8054
|
updateGrid(ascii) {
|
|
7687
8055
|
this.grid = ascii;
|
|
7688
8056
|
this.rows = ascii.length;
|
|
7689
|
-
this.cols = ascii.reduce((widest, row) => Math.max(widest, _nullishCoalesce(_optionalChain([row, 'optionalAccess',
|
|
8057
|
+
this.cols = ascii.reduce((widest, row) => Math.max(widest, _nullishCoalesce(_optionalChain([row, 'optionalAccess', _193 => _193.length]), () => ( 0))), 0);
|
|
7690
8058
|
}
|
|
7691
8059
|
isPointInside(_globalX, _globalY) {
|
|
7692
8060
|
return false;
|
|
@@ -7761,7 +8129,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
|
|
|
7761
8129
|
const ey = py - cy;
|
|
7762
8130
|
return ex * ex + ey * ey;
|
|
7763
8131
|
}
|
|
7764
|
-
var SplineEntity = (_class18 = class extends
|
|
8132
|
+
var SplineEntity = (_class18 = class extends _chunkPOPXUPKRjs.Entity {
|
|
7765
8133
|
|
|
7766
8134
|
|
|
7767
8135
|
|
|
@@ -7769,17 +8137,17 @@ var SplineEntity = (_class18 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
7769
8137
|
|
|
7770
8138
|
|
|
7771
8139
|
|
|
7772
|
-
|
|
7773
|
-
|
|
8140
|
+
__init203() {this.offscreen = null}
|
|
8141
|
+
__init204() {this.baked = false}
|
|
7774
8142
|
/** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
|
|
7775
|
-
|
|
7776
|
-
|
|
8143
|
+
__init205() {this.bakedWidth = 0}
|
|
8144
|
+
__init206() {this.bakedHeight = 0}
|
|
7777
8145
|
/**
|
|
7778
8146
|
* Device-pixel ratio the bitmap was rasterized at. Tracked so a DPR change
|
|
7779
8147
|
* (browser zoom, a monitor move, a renderer whose clamp changed) re-bakes
|
|
7780
8148
|
* instead of blitting a bitmap at the wrong device density forever.
|
|
7781
8149
|
*/
|
|
7782
|
-
|
|
8150
|
+
__init207() {this.bakedDPR = 0}
|
|
7783
8151
|
/**
|
|
7784
8152
|
* Gradient strokes can't be baked to a solid-color bitmap; they render
|
|
7785
8153
|
* per-frame. Derived from `_doc`, so it is NOT readonly — assigning a new
|
|
@@ -7787,7 +8155,7 @@ var SplineEntity = (_class18 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
7787
8155
|
*/
|
|
7788
8156
|
|
|
7789
8157
|
/** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
|
|
7790
|
-
|
|
8158
|
+
__init208() {this.polylines = null}
|
|
7791
8159
|
/**
|
|
7792
8160
|
* The spline document to render. Assigning a new document invalidates all
|
|
7793
8161
|
* caches (baked canvas, flattened polylines, bounds).
|
|
@@ -7821,9 +8189,9 @@ var SplineEntity = (_class18 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
7821
8189
|
* local bounds after painting the curves. Useful for drag feedback and
|
|
7822
8190
|
* debugging hit areas. Defaults to `false`.
|
|
7823
8191
|
*/
|
|
7824
|
-
|
|
8192
|
+
__init209() {this.showBounds = false}
|
|
7825
8193
|
constructor(doc, opts = {}) {
|
|
7826
|
-
super();_class18.prototype.
|
|
8194
|
+
super();_class18.prototype.__init203.call(this);_class18.prototype.__init204.call(this);_class18.prototype.__init205.call(this);_class18.prototype.__init206.call(this);_class18.prototype.__init207.call(this);_class18.prototype.__init208.call(this);_class18.prototype.__init209.call(this);;
|
|
7827
8195
|
this._doc = doc;
|
|
7828
8196
|
this._lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
|
|
7829
8197
|
this.cache = _nullishCoalesce(opts.cache, () => ( true));
|
|
@@ -7843,7 +8211,7 @@ var SplineEntity = (_class18 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
7843
8211
|
*/
|
|
7844
8212
|
computeContainsGradient() {
|
|
7845
8213
|
const isGradient = (c) => c !== null && !Array.isArray(c);
|
|
7846
|
-
return (_nullishCoalesce(_optionalChain([this, 'access',
|
|
8214
|
+
return (_nullishCoalesce(_optionalChain([this, 'access', _194 => _194._doc, 'access', _195 => _195.equations, 'optionalAccess', _196 => _196.some, 'call', _197 => _197((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _198 => _198._doc, 'access', _199 => _199.paths, 'optionalAccess', _200 => _200.some, 'call', _201 => _201((p) => isGradient(p.color_rgb))]), () => ( false)));
|
|
7847
8215
|
}
|
|
7848
8216
|
/** Clear cached baked canvas and hit-test polylines. */
|
|
7849
8217
|
invalidateCache() {
|
|
@@ -8089,7 +8457,7 @@ async function loadSpline(url) {
|
|
|
8089
8457
|
}
|
|
8090
8458
|
|
|
8091
8459
|
// src/components/Rect.ts
|
|
8092
|
-
var Rect = class extends
|
|
8460
|
+
var Rect = class extends _chunkPOPXUPKRjs.Entity {
|
|
8093
8461
|
|
|
8094
8462
|
|
|
8095
8463
|
|
|
@@ -8145,7 +8513,7 @@ var Rect = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
8145
8513
|
};
|
|
8146
8514
|
|
|
8147
8515
|
// src/components/Circle.ts
|
|
8148
|
-
var Circle = class extends
|
|
8516
|
+
var Circle = class extends _chunkPOPXUPKRjs.Entity {
|
|
8149
8517
|
|
|
8150
8518
|
|
|
8151
8519
|
|
|
@@ -8209,7 +8577,7 @@ var Circle = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
8209
8577
|
};
|
|
8210
8578
|
|
|
8211
8579
|
// src/components/Group.ts
|
|
8212
|
-
var Group = class extends
|
|
8580
|
+
var Group = class extends _chunkPOPXUPKRjs.Entity {
|
|
8213
8581
|
constructor(...children) {
|
|
8214
8582
|
super();
|
|
8215
8583
|
if (children.length > 0) this.add(...children);
|
|
@@ -8228,21 +8596,21 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
|
|
|
8228
8596
|
|
|
8229
8597
|
|
|
8230
8598
|
// src/tree/DOMPortalEntity.ts
|
|
8231
|
-
var DOMPortalEntity = (_class19 = class extends
|
|
8599
|
+
var DOMPortalEntity = (_class19 = class extends _chunkPOPXUPKRjs.Entity {
|
|
8232
8600
|
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8601
|
+
__init210() {this.isDOMPortal = true}
|
|
8602
|
+
__init211() {this.domListeners = []}
|
|
8603
|
+
__init212() {this.resizeObserver = null}
|
|
8604
|
+
__init213() {this.domBound = false}
|
|
8605
|
+
__init214() {this.cachedWidth = 100}
|
|
8606
|
+
__init215() {this.cachedHeight = 100}
|
|
8607
|
+
__init216() {this.lastWidth = ""}
|
|
8608
|
+
__init217() {this.lastHeight = ""}
|
|
8609
|
+
__init218() {this.lastTransform = ""}
|
|
8610
|
+
__init219() {this.lastZIndex = ""}
|
|
8611
|
+
__init220() {this.lastOpacity = ""}
|
|
8244
8612
|
constructor(domElement, width, height, id) {
|
|
8245
|
-
super(id);_class19.prototype.
|
|
8613
|
+
super(id);_class19.prototype.__init210.call(this);_class19.prototype.__init211.call(this);_class19.prototype.__init212.call(this);_class19.prototype.__init213.call(this);_class19.prototype.__init214.call(this);_class19.prototype.__init215.call(this);_class19.prototype.__init216.call(this);_class19.prototype.__init217.call(this);_class19.prototype.__init218.call(this);_class19.prototype.__init219.call(this);_class19.prototype.__init220.call(this);;
|
|
8246
8614
|
this.domElement = domElement;
|
|
8247
8615
|
this.width = _nullishCoalesce(width, () => ( 0));
|
|
8248
8616
|
this.height = _nullishCoalesce(height, () => ( 0));
|
|
@@ -8284,7 +8652,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
8284
8652
|
];
|
|
8285
8653
|
for (const type of events) {
|
|
8286
8654
|
const handler = (e) => {
|
|
8287
|
-
this.dispatchEvent(new (0,
|
|
8655
|
+
this.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)(type, this, e));
|
|
8288
8656
|
};
|
|
8289
8657
|
this.domElement.addEventListener(type, handler);
|
|
8290
8658
|
this.domListeners.push({ type, handler, capture: false });
|
|
@@ -8295,7 +8663,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
8295
8663
|
];
|
|
8296
8664
|
for (const { native, vecto } of hoverEvents) {
|
|
8297
8665
|
const handler = (e) => {
|
|
8298
|
-
this.dispatchEvent(new (0,
|
|
8666
|
+
this.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)(vecto, this, e, false));
|
|
8299
8667
|
};
|
|
8300
8668
|
this.domElement.addEventListener(native, handler);
|
|
8301
8669
|
this.domListeners.push({ type: native, handler, capture: false });
|
|
@@ -8303,7 +8671,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
8303
8671
|
const focusEvents = ["focus", "blur"];
|
|
8304
8672
|
for (const type of focusEvents) {
|
|
8305
8673
|
const handler = (e) => {
|
|
8306
|
-
this.dispatchEvent(new (0,
|
|
8674
|
+
this.dispatchEvent(new (0, _chunkPOPXUPKRjs.VectoJSEvent)(type, this, e, true));
|
|
8307
8675
|
};
|
|
8308
8676
|
this.domElement.addEventListener(type, handler, true);
|
|
8309
8677
|
this.domListeners.push({ type, handler, capture: true });
|
|
@@ -8354,8 +8722,11 @@ var DOMPortalEntity = (_class19 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
|
8354
8722
|
}, _class19);
|
|
8355
8723
|
|
|
8356
8724
|
// src/index.ts
|
|
8357
|
-
Scene.registerWebGLPointRendererCreator(
|
|
8358
|
-
Scene.registerWebGPUParticleSystemManager(
|
|
8725
|
+
Scene.registerWebGLPointRendererCreator(_chunkBKXERWADjs.createWebGLPointRenderer);
|
|
8726
|
+
Scene.registerWebGPUParticleSystemManager(_chunkBKXERWADjs.WebGPUParticleSystemManager);
|
|
8727
|
+
|
|
8728
|
+
|
|
8729
|
+
|
|
8359
8730
|
|
|
8360
8731
|
|
|
8361
8732
|
|
|
@@ -8401,4 +8772,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkZYYP2M5Djs.WebGPUParticleSystemM
|
|
|
8401
8772
|
|
|
8402
8773
|
|
|
8403
8774
|
|
|
8404
|
-
exports.CanvasRenderer =
|
|
8775
|
+
exports.CanvasRenderer = _chunkBKXERWADjs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DEFAULT_CONTENT_SEMANTIC_BUDGET = DEFAULT_CONTENT_SEMANTIC_BUDGET; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkPOPXUPKRjs.Entity; exports.GlyphRasterAtlas = _chunkBKXERWADjs.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.KEYBOARD_OWNING_ROLES = KEYBOARD_OWNING_ROLES; exports.MSDFTextEntity = _chunkPOPXUPKRjs.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.REDUCED_MOTION_FPS = REDUCED_MOTION_FPS; exports.Rect = Rect; exports.SCENE_OPTION_KEYS = SCENE_OPTION_KEYS; exports.SVGEntity = _chunkPOPXUPKRjs.SVGEntity; exports.SVGRenderer = _chunkBKXERWADjs.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkBKXERWADjs.TextRasterCache; exports.VECTO_USER_TIMING = VECTO_USER_TIMING; exports.VectoJSEvent = _chunkPOPXUPKRjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkBKXERWADjs.WebGPUParticleSystemManager; exports.beginVectoUserTiming = beginVectoUserTiming; exports.contentLineInHint = _chunkPOPXUPKRjs.contentLineInHint; exports.createWebGLPointRenderer = _chunkBKXERWADjs.createWebGLPointRenderer; exports.endVectoUserTiming = endVectoUserTiming; exports.installRendererDevTraps = _chunkBKXERWADjs.installRendererDevTraps; 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.sanitizeUrl = _chunkBKXERWADjs.sanitizeUrl; exports.setRendererDevMode = _chunkBKXERWADjs.setRendererDevMode;
|