@vectojs/core 1.32.0 → 1.32.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/dist/index.js CHANGED
@@ -2112,10 +2112,20 @@ var Scene = (_class7 = class _Scene {
2112
2112
  * see {@link sortNormalElementsVisually}.
2113
2113
  */
2114
2114
  __init92() {this.a11yOrderContainers = /* @__PURE__ */ new Set()}
2115
- __init93() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
2116
- __init94() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
2117
- __init95() {this.portalEntities = /* @__PURE__ */ new Map()}
2118
- __init96() {this.renderOrderCounter = 0}
2115
+ /**
2116
+ * Nearest `clipChildren` ancestor per ordered element — its *region* — reused
2117
+ * per pass. Written by `enforceA11yDomOrder`'s collect walk, which already has
2118
+ * the entity in hand, so a region costs one comparison per node rather than an
2119
+ * ancestor walk per element.
2120
+ *
2121
+ * Absent means the element sits under no clipping ancestor and belongs to the
2122
+ * implicit root region. See {@link sortNormalElementsVisually}.
2123
+ */
2124
+ __init93() {this.a11yOrderRegions = /* @__PURE__ */ new Map()}
2125
+ __init94() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
2126
+ __init95() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
2127
+ __init96() {this.portalEntities = /* @__PURE__ */ new Map()}
2128
+ __init97() {this.renderOrderCounter = 0}
2119
2129
  /**
2120
2130
  * Monotonic render-frame counter, bumped once per authoritative `render()`
2121
2131
  * pass. Entities stamp their per-frame world-matrix cache with this value and
@@ -2124,7 +2134,7 @@ var Scene = (_class7 = class _Scene {
2124
2134
  * back to the ancestor walk. Public for the same reason `Entity._getTrig`/
2125
2135
  * `_setWorldCache` are: it is a cross-class render-internal contract.
2126
2136
  */
2127
- __init97() {this.currentFrame = 0}
2137
+ __init98() {this.currentFrame = 0}
2128
2138
  // ── WASM transform backend (invisible accelerator) ──────────────────────────
2129
2139
  // When `_transformBackend === 'wasm'`, the main render walk sources each
2130
2140
  // entity's world matrix from an SoA store composed by `_wasm` (see
@@ -2132,24 +2142,24 @@ var Scene = (_class7 = class _Scene {
2132
2142
  // fallback and the default: a null backend, a non-main renderer, or any entity
2133
2143
  // absent from the store all fall back to the JS composition, so WASM can only
2134
2144
  // ever change *how fast* a world matrix is produced, never *what* it is.
2135
- __init98() {this._wasm = null}
2136
- __init99() {this._transformBackend = "js"}
2145
+ __init99() {this._wasm = null}
2146
+ __init100() {this._transformBackend = "js"}
2137
2147
  // Resident store state (Stage 3). The store layout — slot assignment + sibling
2138
2148
  // runs — depends only on tree TOPOLOGY, so it is rebuilt only when the
2139
2149
  // structure changes (add/remove/reparent bump `_structureVersion`). Between
2140
2150
  // rebuilds the per-frame cost is: gather each entity's transform into the
2141
2151
  // resident wasm input view + run the kernel — no reallocation, no readback.
2142
- __init100() {this._treeStore = null}
2143
- __init101() {this._slotEntity = []}
2152
+ __init101() {this._treeStore = null}
2153
+ __init102() {this._slotEntity = []}
2144
2154
  // store slot -> entity (also validates slots)
2145
- __init102() {this._wasmInputs = null}
2146
- __init103() {this._wasmWorld = null}
2147
- __init104() {this._structureVersion = 0}
2148
- __init105() {this._storeStructureVersion = -1}
2155
+ __init103() {this._wasmInputs = null}
2156
+ __init104() {this._wasmWorld = null}
2157
+ __init105() {this._structureVersion = 0}
2158
+ __init106() {this._storeStructureVersion = -1}
2149
2159
  // Cached list of ComputeParticleEntity instances in the tree, keyed by the
2150
2160
  // structure version it was gathered at. Rebuilt only on a topology change.
2151
- __init106() {this._computeEntities = []}
2152
- __init107() {this._computeEntitiesVersion = -1}
2161
+ __init107() {this._computeEntities = []}
2162
+ __init108() {this._computeEntitiesVersion = -1}
2153
2163
  /** Invalidate the resident WASM store layout; the next wasm-mode frame rebuilds
2154
2164
  * it. Called by `Entity.add`/`remove` (topology changes only). */
2155
2165
  markStructureChanged() {
@@ -2234,7 +2244,7 @@ var Scene = (_class7 = class _Scene {
2234
2244
  * cached globally; the instance is per-Scene, which is the isolation that
2235
2245
  * actually matters.
2236
2246
  */
2237
- __init108() {this._wasmRuntime = null}
2247
+ __init109() {this._wasmRuntime = null}
2238
2248
  /**
2239
2249
  * Load (or reuse) this Scene's shared WASM runtime.
2240
2250
  *
@@ -2262,30 +2272,30 @@ var Scene = (_class7 = class _Scene {
2262
2272
  get wasmRuntime() {
2263
2273
  return this._wasmRuntime;
2264
2274
  }
2265
- __init109() {this._hitWasm = null}
2275
+ __init110() {this._hitWasm = null}
2266
2276
  // Cache key: which frame + structure version the grid was last (successfully,
2267
2277
  // non-overflowing) built for. findEntityAt is called ad-hoc (pointer
2268
2278
  // hover/click), not every frame, so the grid is refreshed lazily on demand
2269
2279
  // rather than proactively every render() — unlike the transform store, which
2270
2280
  // every frame's draw depends on.
2271
- __init110() {this._hitGridFrame = -1}
2272
- __init111() {this._hitGridOk = false}
2273
- __init112() {this._hitSlotEntity = []}
2274
- __init113() {this._hitBoundless = []}
2281
+ __init111() {this._hitGridFrame = -1}
2282
+ __init112() {this._hitGridOk = false}
2283
+ __init113() {this._hitSlotEntity = []}
2284
+ __init114() {this._hitBoundless = []}
2275
2285
  /** Reused buffer for the fused gather, so a pointer query allocates nothing. */
2276
- __init114() {this._hitGatherBuffer = null}
2286
+ __init115() {this._hitGatherBuffer = null}
2277
2287
  /**
2278
2288
  * Whether the last grid build sourced its AABBs from the WASM transform store
2279
2289
  * rather than recomputing them in JS. Diagnostic only — both paths must
2280
2290
  * produce the same entity for a given point.
2281
2291
  */
2282
- __init115() {this._hitFusedGather = false}
2292
+ __init116() {this._hitFusedGather = false}
2283
2293
  /**
2284
2294
  * Whether `compute_aabbs` has run against the current frame's world matrices.
2285
2295
  * The AABB pass is only meaningful after a `compose_*`, so the fused gather
2286
2296
  * must not read the views before then.
2287
2297
  */
2288
- __init116() {this._wasmAabbsFresh = false}
2298
+ __init117() {this._wasmAabbsFresh = false}
2289
2299
  /** Did the last hit-grid build use the fused (WASM-store) gather? */
2290
2300
  get hitGatherPath() {
2291
2301
  return this._hitFusedGather ? "fused" : "js";
@@ -2294,9 +2304,9 @@ var Scene = (_class7 = class _Scene {
2294
2304
  * Why the transform accelerator did or did not run on the most recent frame.
2295
2305
  * Written by the render walk and `_syncWasmStore`.
2296
2306
  */
2297
- __init117() {this._transformReason = "not-installed"}
2307
+ __init118() {this._transformReason = "not-installed"}
2298
2308
  /** Why the batched-driver accelerator did or did not run. */
2299
- __init118() {this._animReason = "not-installed"}
2309
+ __init119() {this._animReason = "not-installed"}
2300
2310
  /**
2301
2311
  * Why the hit-test accelerator did or did not serve the last pointer query.
2302
2312
  * The grid is built lazily on demand, not every frame, so this describes the
@@ -2304,11 +2314,11 @@ var Scene = (_class7 = class _Scene {
2304
2314
  * before a backend exists; `_ensureHitGrid` moves it to `'not-applicable'`
2305
2315
  * once one is installed but nothing has queried yet.
2306
2316
  */
2307
- __init119() {this._hitReason = "not-installed"}
2317
+ __init120() {this._hitReason = "not-installed"}
2308
2318
  /** Why the particle accelerator did or did not run. */
2309
- __init120() {this._particleReason = "not-applicable"}
2319
+ __init121() {this._particleReason = "not-applicable"}
2310
2320
  /** Which particle implementation actually simulated the most recent frame. */
2311
- __init121() {this._particlePath = "none"}
2321
+ __init122() {this._particlePath = "none"}
2312
2322
  /**
2313
2323
  * Per-frame status of every invisible accelerator: whether each is installed,
2314
2324
  * whether it actually ran on the most recent frame, and why.
@@ -2468,25 +2478,25 @@ var Scene = (_class7 = class _Scene {
2468
2478
  // EasingFn (which cannot cross into WASM) all fall through to it — WASM can
2469
2479
  // only ever change *how* a driver is advanced, never *what* value it lands
2470
2480
  // on.
2471
- __init122() {this._animWasm = null}
2481
+ __init123() {this._animWasm = null}
2472
2482
  // Entities with at least one active driver, added by Entity._spawnDriver.
2473
2483
  // Self-pruning: _tickBatchedDrivers drops an entry the first time it visits
2474
2484
  // an entity whose drivers have since all completed or been removed. This is
2475
2485
  // what lets the batch pass find its candidates in O(active drivers), not
2476
2486
  // O(tree size) — the exact mistake G3's first integrated benchmark made.
2477
- __init123() {this._activeDriverEntities = /* @__PURE__ */ new Set()}
2487
+ __init124() {this._activeDriverEntities = /* @__PURE__ */ new Set()}
2478
2488
  // Reused across frames instead of allocating a fresh array + N {entity,prop,
2479
2489
  // driver} objects every call — the integrated benchmark
2480
2490
  // (benchmarks/anim-wasm-scene) found that allocation churn was the
2481
2491
  // dominant integrated cost, not the wasm kernel itself. Parallel arrays,
2482
2492
  // truncated to the live count after each use so a stale tail slot never
2483
2493
  // pins a no-longer-active entity/driver in memory.
2484
- __init124() {this._springEntities = []}
2485
- __init125() {this._springProps = []}
2486
- __init126() {this._springDrivers = []}
2487
- __init127() {this._tweenEntities = []}
2488
- __init128() {this._tweenProps = []}
2489
- __init129() {this._tweenDrivers = []}
2494
+ __init125() {this._springEntities = []}
2495
+ __init126() {this._springProps = []}
2496
+ __init127() {this._springDrivers = []}
2497
+ __init128() {this._tweenEntities = []}
2498
+ __init129() {this._tweenProps = []}
2499
+ __init130() {this._tweenDrivers = []}
2490
2500
  /**
2491
2501
  * Minimum number of batchable (spring, or named-easing tween) active drivers
2492
2502
  * before a frame engages the WASM batch path at all; below it, every driver
@@ -2558,7 +2568,7 @@ var Scene = (_class7 = class _Scene {
2558
2568
  * Setting {@link animDriverGateCount} overwrites all three, so existing code
2559
2569
  * that tuned the single knob keeps working unchanged.
2560
2570
  */
2561
- __init130() {this._animBatchedLastFrame = false}
2571
+ __init131() {this._animBatchedLastFrame = false}
2562
2572
  /**
2563
2573
  * Whether the WASM batch path actually ran on the most recent frame.
2564
2574
  *
@@ -2570,7 +2580,7 @@ var Scene = (_class7 = class _Scene {
2570
2580
  get animBatchedLastFrame() {
2571
2581
  return this._animBatchedLastFrame;
2572
2582
  }
2573
- __init131() {this.animGate = {
2583
+ __init132() {this.animGate = {
2574
2584
  spring: 128,
2575
2585
  tween: 256,
2576
2586
  mixed: 128
@@ -2608,7 +2618,7 @@ var Scene = (_class7 = class _Scene {
2608
2618
  // (benchmarks/particle-wasm). f32 (matches the WGSL shader), bit-identical to
2609
2619
  // a JS f32 reference oracle; updateCPU (f64) stays the permanent fallback when
2610
2620
  // no backend is installed or a scene runs on WebGPU.
2611
- __init132() {this._particleWasm = null}
2621
+ __init133() {this._particleWasm = null}
2612
2622
  /** Which backend runs the CPU particle simulation. Reflects only whether a
2613
2623
  * backend is installed (the WebGPU compute path, when active, is used first
2614
2624
  * regardless). */
@@ -2885,24 +2895,24 @@ var Scene = (_class7 = class _Scene {
2885
2895
  * sync, so retaining the order prevents a newly opened overlay from spending
2886
2896
  * its first frame below previously projected controls.
2887
2897
  */
2888
- __init133() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
2898
+ __init134() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
2889
2899
  // Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
2890
- __init134() {this.pointRenderer = null}
2891
- __init135() {this.glCanvas = null}
2892
- __init136() {this.glContextLostHandler = null}
2893
- __init137() {this.glContextRestoredHandler = null}
2900
+ __init135() {this.pointRenderer = null}
2901
+ __init136() {this.glCanvas = null}
2902
+ __init137() {this.glContextLostHandler = null}
2903
+ __init138() {this.glContextRestoredHandler = null}
2894
2904
 
2895
2905
 
2896
2906
 
2897
- __init138() {this.disableWindowResize = false}
2907
+ __init139() {this.disableWindowResize = false}
2898
2908
  /** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
2899
2909
 
2900
2910
  // WebGPU properties
2901
- __init139() {this.destroyed = false}
2902
- __init140() {this.device = null}
2903
- __init141() {this.deviceLost = false}
2904
- __init142() {this.particleBackend = "auto"}
2905
- __init143() {this._webgpuDisabled = false}
2911
+ __init140() {this.destroyed = false}
2912
+ __init141() {this.device = null}
2913
+ __init142() {this.deviceLost = false}
2914
+ __init143() {this.particleBackend = "auto"}
2915
+ __init144() {this._webgpuDisabled = false}
2906
2916
  get webgpuDisabled() {
2907
2917
  return this._webgpuDisabled || this.particleBackend === "cpu";
2908
2918
  }
@@ -2930,22 +2940,22 @@ var Scene = (_class7 = class _Scene {
2930
2940
  set webgpuDisabled(value) {
2931
2941
  this._webgpuDisabled = value;
2932
2942
  }
2933
- __init144() {this.recoveryTimerId = null}
2934
- __init145() {this.manager = null}
2935
- __init146() {this.initializingWebGPU = false}
2936
- __init147() {this.gpuCanvas = null}
2937
- __init148() {this.gpuContext = null}
2943
+ __init145() {this.recoveryTimerId = null}
2944
+ __init146() {this.manager = null}
2945
+ __init147() {this.initializingWebGPU = false}
2946
+ __init148() {this.gpuCanvas = null}
2947
+ __init149() {this.gpuContext = null}
2938
2948
  /** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
2939
- __init149() {this.gpuHasContent = false}
2940
- __init150() {this.mouseX = -9999}
2941
- __init151() {this.mouseY = -9999}
2942
- __init152() {this.pointerMoveListener = null}
2943
- __init153() {this.pointerLeaveListener = null}
2949
+ __init150() {this.gpuHasContent = false}
2950
+ __init151() {this.mouseX = -9999}
2951
+ __init152() {this.mouseY = -9999}
2952
+ __init153() {this.pointerMoveListener = null}
2953
+ __init154() {this.pointerLeaveListener = null}
2944
2954
  /** Element the pointer listeners are bound to (parent container if present,
2945
2955
  * else the canvas). Stored so `destroy()` detaches from the same element. */
2946
- __init154() {this.pointerEventTarget = null}
2947
- __init155() {this.hasWarnedZeroSize = false}
2948
- __init156() {this.fontLoadHandler = null}
2956
+ __init155() {this.pointerEventTarget = null}
2957
+ __init156() {this.hasWarnedZeroSize = false}
2958
+ __init157() {this.fontLoadHandler = null}
2949
2959
  // ── Dev-mode warning infrastructure ──────────────────────────────
2950
2960
  //
2951
2961
  // Enable with `Scene.devMode = true` or by setting `globalThis.__DEV__`.
@@ -2979,7 +2989,7 @@ var Scene = (_class7 = class _Scene {
2979
2989
  return false;
2980
2990
  }
2981
2991
 
2982
- __init157() {this._devFrameCount = 0}
2992
+ __init158() {this._devFrameCount = 0}
2983
2993
  _devWarn(message) {
2984
2994
  if (!this._devActive) return;
2985
2995
  console.warn(`[vectojs/dev] ${message}`);
@@ -3056,7 +3066,7 @@ var Scene = (_class7 = class _Scene {
3056
3066
  };
3057
3067
  walkProjections(this.root);
3058
3068
  }
3059
- constructor(canvas, options = {}) {;_class7.prototype.__init27.call(this);_class7.prototype.__init28.call(this);_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_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);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);_class7.prototype.__init50.call(this);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);_class7.prototype.__init53.call(this);_class7.prototype.__init54.call(this);_class7.prototype.__init55.call(this);_class7.prototype.__init56.call(this);_class7.prototype.__init57.call(this);_class7.prototype.__init58.call(this);_class7.prototype.__init59.call(this);_class7.prototype.__init60.call(this);_class7.prototype.__init61.call(this);_class7.prototype.__init62.call(this);_class7.prototype.__init63.call(this);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);_class7.prototype.__init90.call(this);_class7.prototype.__init91.call(this);_class7.prototype.__init92.call(this);_class7.prototype.__init93.call(this);_class7.prototype.__init94.call(this);_class7.prototype.__init95.call(this);_class7.prototype.__init96.call(this);_class7.prototype.__init97.call(this);_class7.prototype.__init98.call(this);_class7.prototype.__init99.call(this);_class7.prototype.__init100.call(this);_class7.prototype.__init101.call(this);_class7.prototype.__init102.call(this);_class7.prototype.__init103.call(this);_class7.prototype.__init104.call(this);_class7.prototype.__init105.call(this);_class7.prototype.__init106.call(this);_class7.prototype.__init107.call(this);_class7.prototype.__init108.call(this);_class7.prototype.__init109.call(this);_class7.prototype.__init110.call(this);_class7.prototype.__init111.call(this);_class7.prototype.__init112.call(this);_class7.prototype.__init113.call(this);_class7.prototype.__init114.call(this);_class7.prototype.__init115.call(this);_class7.prototype.__init116.call(this);_class7.prototype.__init117.call(this);_class7.prototype.__init118.call(this);_class7.prototype.__init119.call(this);_class7.prototype.__init120.call(this);_class7.prototype.__init121.call(this);_class7.prototype.__init122.call(this);_class7.prototype.__init123.call(this);_class7.prototype.__init124.call(this);_class7.prototype.__init125.call(this);_class7.prototype.__init126.call(this);_class7.prototype.__init127.call(this);_class7.prototype.__init128.call(this);_class7.prototype.__init129.call(this);_class7.prototype.__init130.call(this);_class7.prototype.__init131.call(this);_class7.prototype.__init132.call(this);_class7.prototype.__init133.call(this);_class7.prototype.__init134.call(this);_class7.prototype.__init135.call(this);_class7.prototype.__init136.call(this);_class7.prototype.__init137.call(this);_class7.prototype.__init138.call(this);_class7.prototype.__init139.call(this);_class7.prototype.__init140.call(this);_class7.prototype.__init141.call(this);_class7.prototype.__init142.call(this);_class7.prototype.__init143.call(this);_class7.prototype.__init144.call(this);_class7.prototype.__init145.call(this);_class7.prototype.__init146.call(this);_class7.prototype.__init147.call(this);_class7.prototype.__init148.call(this);_class7.prototype.__init149.call(this);_class7.prototype.__init150.call(this);_class7.prototype.__init151.call(this);_class7.prototype.__init152.call(this);_class7.prototype.__init153.call(this);_class7.prototype.__init154.call(this);_class7.prototype.__init155.call(this);_class7.prototype.__init156.call(this);_class7.prototype.__init157.call(this);
3069
+ constructor(canvas, options = {}) {;_class7.prototype.__init27.call(this);_class7.prototype.__init28.call(this);_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_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);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);_class7.prototype.__init50.call(this);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);_class7.prototype.__init53.call(this);_class7.prototype.__init54.call(this);_class7.prototype.__init55.call(this);_class7.prototype.__init56.call(this);_class7.prototype.__init57.call(this);_class7.prototype.__init58.call(this);_class7.prototype.__init59.call(this);_class7.prototype.__init60.call(this);_class7.prototype.__init61.call(this);_class7.prototype.__init62.call(this);_class7.prototype.__init63.call(this);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);_class7.prototype.__init90.call(this);_class7.prototype.__init91.call(this);_class7.prototype.__init92.call(this);_class7.prototype.__init93.call(this);_class7.prototype.__init94.call(this);_class7.prototype.__init95.call(this);_class7.prototype.__init96.call(this);_class7.prototype.__init97.call(this);_class7.prototype.__init98.call(this);_class7.prototype.__init99.call(this);_class7.prototype.__init100.call(this);_class7.prototype.__init101.call(this);_class7.prototype.__init102.call(this);_class7.prototype.__init103.call(this);_class7.prototype.__init104.call(this);_class7.prototype.__init105.call(this);_class7.prototype.__init106.call(this);_class7.prototype.__init107.call(this);_class7.prototype.__init108.call(this);_class7.prototype.__init109.call(this);_class7.prototype.__init110.call(this);_class7.prototype.__init111.call(this);_class7.prototype.__init112.call(this);_class7.prototype.__init113.call(this);_class7.prototype.__init114.call(this);_class7.prototype.__init115.call(this);_class7.prototype.__init116.call(this);_class7.prototype.__init117.call(this);_class7.prototype.__init118.call(this);_class7.prototype.__init119.call(this);_class7.prototype.__init120.call(this);_class7.prototype.__init121.call(this);_class7.prototype.__init122.call(this);_class7.prototype.__init123.call(this);_class7.prototype.__init124.call(this);_class7.prototype.__init125.call(this);_class7.prototype.__init126.call(this);_class7.prototype.__init127.call(this);_class7.prototype.__init128.call(this);_class7.prototype.__init129.call(this);_class7.prototype.__init130.call(this);_class7.prototype.__init131.call(this);_class7.prototype.__init132.call(this);_class7.prototype.__init133.call(this);_class7.prototype.__init134.call(this);_class7.prototype.__init135.call(this);_class7.prototype.__init136.call(this);_class7.prototype.__init137.call(this);_class7.prototype.__init138.call(this);_class7.prototype.__init139.call(this);_class7.prototype.__init140.call(this);_class7.prototype.__init141.call(this);_class7.prototype.__init142.call(this);_class7.prototype.__init143.call(this);_class7.prototype.__init144.call(this);_class7.prototype.__init145.call(this);_class7.prototype.__init146.call(this);_class7.prototype.__init147.call(this);_class7.prototype.__init148.call(this);_class7.prototype.__init149.call(this);_class7.prototype.__init150.call(this);_class7.prototype.__init151.call(this);_class7.prototype.__init152.call(this);_class7.prototype.__init153.call(this);_class7.prototype.__init154.call(this);_class7.prototype.__init155.call(this);_class7.prototype.__init156.call(this);_class7.prototype.__init157.call(this);_class7.prototype.__init158.call(this);
3060
3070
  this.canvas = canvas;
3061
3071
  this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
3062
3072
  this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
@@ -5170,12 +5180,14 @@ var Scene = (_class7 = class _Scene {
5170
5180
  this.fullViewportElements.length = 0;
5171
5181
  this.normalElements.length = 0;
5172
5182
  this.activeIds.clear();
5173
- const collect = (node) => {
5183
+ this.a11yOrderRegions.clear();
5184
+ const collect = (node, region) => {
5174
5185
  if (node.isDOMPortal) return;
5175
5186
  const contentEl = this.contentElements.get(node.id);
5176
5187
  if (contentEl) {
5177
5188
  if (node.a11yFullViewport) this.fullViewportElements.push(contentEl);
5178
5189
  else this.normalElements.push(contentEl);
5190
+ if (region) this.a11yOrderRegions.set(contentEl, region);
5179
5191
  }
5180
5192
  if (this.shouldProjectA11y(node)) {
5181
5193
  const el = this.a11yElements.get(node.id);
@@ -5183,14 +5195,16 @@ var Scene = (_class7 = class _Scene {
5183
5195
  this.activeIds.add(node.id);
5184
5196
  if (node.a11yFullViewport) this.fullViewportElements.push(el);
5185
5197
  else this.normalElements.push(el);
5198
+ if (region) this.a11yOrderRegions.set(el, region);
5186
5199
  }
5187
5200
  }
5188
- for (const child of node.children) collect(child);
5201
+ const childRegion = node.clipChildren && node.width > 0 && node.height > 0 ? node : region;
5202
+ for (const child of node.children) collect(child, childRegion);
5189
5203
  if (node === this.root) {
5190
- for (const overlay of this.overlayRoot.children) collect(overlay);
5204
+ for (const overlay of this.overlayRoot.children) collect(overlay, null);
5191
5205
  }
5192
5206
  };
5193
- collect(this.root);
5207
+ collect(this.root, null);
5194
5208
  let elementsPruned = false;
5195
5209
  for (const [id, el] of this.a11yElements.entries()) {
5196
5210
  if (!this.activeIds.has(id)) {
@@ -5252,6 +5266,18 @@ var Scene = (_class7 = class _Scene {
5252
5266
  * parents, which no `insertBefore` ever acts on. Normalizing everything back
5253
5267
  * to world coordinates here would cost a transform per element per frame to
5254
5268
  * change nothing observable.
5269
+ *
5270
+ * Banding runs **per region** — per nearest `clipChildren` ancestor, recorded
5271
+ * by {@link enforceA11yDomOrder}'s collect walk — rather than once over the
5272
+ * whole scene. Purely visual banding is right for a screen reader but wrong
5273
+ * for selection: a DOM `Selection` covers everything between anchor and focus
5274
+ * in DOM order, so under one global banding a vertical drag through a
5275
+ * transcript also swallowed a sidebar whose headings happened to fall in the
5276
+ * same rows. Regions are laid out side by side, so ordering region-major keeps
5277
+ * each one a contiguous DOM run and a drag stays inside it, while reading
5278
+ * order *within* a region is unchanged. Regions are emitted in the order their
5279
+ * clipper is first reached by the depth-first walk, so a screen reader still
5280
+ * meets them in the author's declared order.
5255
5281
  */
5256
5282
  sortNormalElementsVisually() {
5257
5283
  const els = this.normalElements;
@@ -5279,30 +5305,40 @@ var Scene = (_class7 = class _Scene {
5279
5305
  }
5280
5306
  return { top, left };
5281
5307
  };
5282
- const order = els.map((el, i) => {
5308
+ const decorated = els.map((el, i) => {
5283
5309
  const { top, left } = absolute(el);
5284
5310
  return { el, i, top, left, container: containers.has(el) };
5285
5311
  });
5286
- order.sort((p, q) => p.top - q.top || p.i - q.i);
5312
+ const regions = this.a11yOrderRegions;
5313
+ const buckets = /* @__PURE__ */ new Map();
5314
+ for (const d of decorated) {
5315
+ const key = _nullishCoalesce(regions.get(d.el), () => ( null));
5316
+ const bucket = buckets.get(key);
5317
+ if (bucket) bucket.push(d);
5318
+ else buckets.set(key, [d]);
5319
+ }
5287
5320
  const bandBottom = (r) => r.top + (r.container ? 4 : heightOf(r.el));
5288
5321
  const sorted = [];
5289
- let rowStart = 0;
5290
- let rowBottom = order.length ? bandBottom(order[0]) : 0;
5291
- const flushRow = (end) => {
5292
- const row = order.slice(rowStart, end);
5293
- row.sort((p, q) => (rtl ? q.left - p.left : p.left - q.left) || p.i - q.i);
5294
- for (const r of row) sorted.push(r.el);
5295
- };
5296
- for (let k = 1; k < order.length; k++) {
5297
- if (order[k].top < rowBottom) {
5298
- rowBottom = Math.max(rowBottom, bandBottom(order[k]));
5299
- } else {
5300
- flushRow(k);
5301
- rowStart = k;
5302
- rowBottom = bandBottom(order[k]);
5322
+ for (const order of buckets.values()) {
5323
+ order.sort((p, q) => p.top - q.top || p.i - q.i);
5324
+ let rowStart = 0;
5325
+ let rowBottom = order.length ? bandBottom(order[0]) : 0;
5326
+ const flushRow = (end) => {
5327
+ const row = order.slice(rowStart, end);
5328
+ row.sort((p, q) => (rtl ? q.left - p.left : p.left - q.left) || p.i - q.i);
5329
+ for (const r of row) sorted.push(r.el);
5330
+ };
5331
+ for (let k = 1; k < order.length; k++) {
5332
+ if (order[k].top < rowBottom) {
5333
+ rowBottom = Math.max(rowBottom, bandBottom(order[k]));
5334
+ } else {
5335
+ flushRow(k);
5336
+ rowStart = k;
5337
+ rowBottom = bandBottom(order[k]);
5338
+ }
5303
5339
  }
5340
+ flushRow(order.length);
5304
5341
  }
5305
- flushRow(order.length);
5306
5342
  for (let i = 0; i < sorted.length; i++) els[i] = sorted[i];
5307
5343
  }
5308
5344
  /** Keep DOM/WebGL overlay layers aligned with the canvas's CSS box. */
@@ -6237,17 +6273,17 @@ var TextEntity = (_class8 = class extends _chunkTRT2TRCWjs.Entity {
6237
6273
 
6238
6274
 
6239
6275
 
6240
- __init158() {this.nodes = []}
6276
+ __init159() {this.nodes = []}
6241
6277
 
6242
- __init159() {this.fillStyle = "#94a3b8"}
6243
- __init160() {this.strokeStyle = null}
6244
- __init161() {this.hoveredFillStyle = "#ffffff"}
6245
- __init162() {this.lineWidth = 1}
6246
- __init163() {this.isHovered = false}
6278
+ __init160() {this.fillStyle = "#94a3b8"}
6279
+ __init161() {this.strokeStyle = null}
6280
+ __init162() {this.hoveredFillStyle = "#ffffff"}
6281
+ __init163() {this.lineWidth = 1}
6282
+ __init164() {this.isHovered = false}
6247
6283
  /** Bumped by {@link applyLayout}; read by `Scene` to skip an unchanged sync. */
6248
- __init164() {this.contentEpoch = 0}
6284
+ __init165() {this.contentEpoch = 0}
6249
6285
  constructor(text, atlas, maxWidth, fontSize = 24) {
6250
- super();_class8.prototype.__init158.call(this);_class8.prototype.__init159.call(this);_class8.prototype.__init160.call(this);_class8.prototype.__init161.call(this);_class8.prototype.__init162.call(this);_class8.prototype.__init163.call(this);_class8.prototype.__init164.call(this);;
6286
+ super();_class8.prototype.__init159.call(this);_class8.prototype.__init160.call(this);_class8.prototype.__init161.call(this);_class8.prototype.__init162.call(this);_class8.prototype.__init163.call(this);_class8.prototype.__init164.call(this);_class8.prototype.__init165.call(this);;
6251
6287
  this.text = text;
6252
6288
  this.atlas = atlas;
6253
6289
  this.fontSize = fontSize;
@@ -6366,15 +6402,15 @@ var TextEntity = (_class8 = class extends _chunkTRT2TRCWjs.Entity {
6366
6402
  // src/components/GridTextEntity.ts
6367
6403
  var GridTextEntity = (_class9 = class extends _chunkTRT2TRCWjs.Entity {
6368
6404
 
6369
- __init165() {this.fillStyle = "#ffffff"}
6370
- __init166() {this.grid = []}
6405
+ __init166() {this.fillStyle = "#ffffff"}
6406
+ __init167() {this.grid = []}
6371
6407
  // Array of rows
6372
- __init167() {this.cols = 0}
6373
- __init168() {this.rows = 0}
6408
+ __init168() {this.cols = 0}
6409
+ __init169() {this.rows = 0}
6374
6410
 
6375
6411
 
6376
6412
  constructor(_atlas, fontSize = 10) {
6377
- super();_class9.prototype.__init165.call(this);_class9.prototype.__init166.call(this);_class9.prototype.__init167.call(this);_class9.prototype.__init168.call(this);;
6413
+ super();_class9.prototype.__init166.call(this);_class9.prototype.__init167.call(this);_class9.prototype.__init168.call(this);_class9.prototype.__init169.call(this);;
6378
6414
  this.fontSize = fontSize;
6379
6415
  this.charWidth = fontSize * 1;
6380
6416
  this.charHeight = fontSize * 1.1;
@@ -6466,23 +6502,23 @@ var SplineEntity = (_class10 = class extends _chunkTRT2TRCWjs.Entity {
6466
6502
 
6467
6503
 
6468
6504
 
6469
- __init169() {this.offscreen = null}
6470
- __init170() {this.baked = false}
6505
+ __init170() {this.offscreen = null}
6506
+ __init171() {this.baked = false}
6471
6507
  /** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
6472
- __init171() {this.bakedWidth = 0}
6473
- __init172() {this.bakedHeight = 0}
6508
+ __init172() {this.bakedWidth = 0}
6509
+ __init173() {this.bakedHeight = 0}
6474
6510
  /** Gradient strokes can't be baked to a solid-color bitmap; they render per-frame. */
6475
6511
 
6476
6512
  /** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
6477
- __init173() {this.polylines = null}
6513
+ __init174() {this.polylines = null}
6478
6514
  /**
6479
6515
  * When `true`, the renderer draws a rounded-rect outline of the entity's
6480
6516
  * local bounds after painting the curves. Useful for drag feedback and
6481
6517
  * debugging hit areas. Defaults to `false`.
6482
6518
  */
6483
- __init174() {this.showBounds = false}
6519
+ __init175() {this.showBounds = false}
6484
6520
  constructor(doc, opts = {}) {
6485
- super();_class10.prototype.__init169.call(this);_class10.prototype.__init170.call(this);_class10.prototype.__init171.call(this);_class10.prototype.__init172.call(this);_class10.prototype.__init173.call(this);_class10.prototype.__init174.call(this);;
6521
+ super();_class10.prototype.__init170.call(this);_class10.prototype.__init171.call(this);_class10.prototype.__init172.call(this);_class10.prototype.__init173.call(this);_class10.prototype.__init174.call(this);_class10.prototype.__init175.call(this);;
6486
6522
  this.doc = doc;
6487
6523
  this.lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
6488
6524
  this.cache = _nullishCoalesce(opts.cache, () => ( true));
@@ -6863,19 +6899,19 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
6863
6899
  // src/tree/DOMPortalEntity.ts
6864
6900
  var DOMPortalEntity = (_class11 = class extends _chunkTRT2TRCWjs.Entity {
6865
6901
 
6866
- __init175() {this.isDOMPortal = true}
6867
- __init176() {this.domListeners = []}
6868
- __init177() {this.resizeObserver = null}
6869
- __init178() {this.domBound = false}
6870
- __init179() {this.cachedWidth = 100}
6871
- __init180() {this.cachedHeight = 100}
6872
- __init181() {this.lastWidth = ""}
6873
- __init182() {this.lastHeight = ""}
6874
- __init183() {this.lastTransform = ""}
6875
- __init184() {this.lastZIndex = ""}
6876
- __init185() {this.lastOpacity = ""}
6902
+ __init176() {this.isDOMPortal = true}
6903
+ __init177() {this.domListeners = []}
6904
+ __init178() {this.resizeObserver = null}
6905
+ __init179() {this.domBound = false}
6906
+ __init180() {this.cachedWidth = 100}
6907
+ __init181() {this.cachedHeight = 100}
6908
+ __init182() {this.lastWidth = ""}
6909
+ __init183() {this.lastHeight = ""}
6910
+ __init184() {this.lastTransform = ""}
6911
+ __init185() {this.lastZIndex = ""}
6912
+ __init186() {this.lastOpacity = ""}
6877
6913
  constructor(domElement, width, height, id) {
6878
- super(id);_class11.prototype.__init175.call(this);_class11.prototype.__init176.call(this);_class11.prototype.__init177.call(this);_class11.prototype.__init178.call(this);_class11.prototype.__init179.call(this);_class11.prototype.__init180.call(this);_class11.prototype.__init181.call(this);_class11.prototype.__init182.call(this);_class11.prototype.__init183.call(this);_class11.prototype.__init184.call(this);_class11.prototype.__init185.call(this);;
6914
+ super(id);_class11.prototype.__init176.call(this);_class11.prototype.__init177.call(this);_class11.prototype.__init178.call(this);_class11.prototype.__init179.call(this);_class11.prototype.__init180.call(this);_class11.prototype.__init181.call(this);_class11.prototype.__init182.call(this);_class11.prototype.__init183.call(this);_class11.prototype.__init184.call(this);_class11.prototype.__init185.call(this);_class11.prototype.__init186.call(this);;
6879
6915
  this.domElement = domElement;
6880
6916
  this.width = _nullishCoalesce(width, () => ( 0));
6881
6917
  this.height = _nullishCoalesce(height, () => ( 0));
package/dist/index.mjs CHANGED
@@ -2111,6 +2111,16 @@ var Scene = class _Scene {
2111
2111
  * see {@link sortNormalElementsVisually}.
2112
2112
  */
2113
2113
  a11yOrderContainers = /* @__PURE__ */ new Set();
2114
+ /**
2115
+ * Nearest `clipChildren` ancestor per ordered element — its *region* — reused
2116
+ * per pass. Written by `enforceA11yDomOrder`'s collect walk, which already has
2117
+ * the entity in hand, so a region costs one comparison per node rather than an
2118
+ * ancestor walk per element.
2119
+ *
2120
+ * Absent means the element sits under no clipping ancestor and belongs to the
2121
+ * implicit root region. See {@link sortNormalElementsVisually}.
2122
+ */
2123
+ a11yOrderRegions = /* @__PURE__ */ new Map();
2114
2124
  activePortalsThisFrame = /* @__PURE__ */ new Set();
2115
2125
  activePortalsPrevFrame = /* @__PURE__ */ new Set();
2116
2126
  portalEntities = /* @__PURE__ */ new Map();
@@ -5169,12 +5179,14 @@ var Scene = class _Scene {
5169
5179
  this.fullViewportElements.length = 0;
5170
5180
  this.normalElements.length = 0;
5171
5181
  this.activeIds.clear();
5172
- const collect = (node) => {
5182
+ this.a11yOrderRegions.clear();
5183
+ const collect = (node, region) => {
5173
5184
  if (node.isDOMPortal) return;
5174
5185
  const contentEl = this.contentElements.get(node.id);
5175
5186
  if (contentEl) {
5176
5187
  if (node.a11yFullViewport) this.fullViewportElements.push(contentEl);
5177
5188
  else this.normalElements.push(contentEl);
5189
+ if (region) this.a11yOrderRegions.set(contentEl, region);
5178
5190
  }
5179
5191
  if (this.shouldProjectA11y(node)) {
5180
5192
  const el = this.a11yElements.get(node.id);
@@ -5182,14 +5194,16 @@ var Scene = class _Scene {
5182
5194
  this.activeIds.add(node.id);
5183
5195
  if (node.a11yFullViewport) this.fullViewportElements.push(el);
5184
5196
  else this.normalElements.push(el);
5197
+ if (region) this.a11yOrderRegions.set(el, region);
5185
5198
  }
5186
5199
  }
5187
- for (const child of node.children) collect(child);
5200
+ const childRegion = node.clipChildren && node.width > 0 && node.height > 0 ? node : region;
5201
+ for (const child of node.children) collect(child, childRegion);
5188
5202
  if (node === this.root) {
5189
- for (const overlay of this.overlayRoot.children) collect(overlay);
5203
+ for (const overlay of this.overlayRoot.children) collect(overlay, null);
5190
5204
  }
5191
5205
  };
5192
- collect(this.root);
5206
+ collect(this.root, null);
5193
5207
  let elementsPruned = false;
5194
5208
  for (const [id, el] of this.a11yElements.entries()) {
5195
5209
  if (!this.activeIds.has(id)) {
@@ -5251,6 +5265,18 @@ var Scene = class _Scene {
5251
5265
  * parents, which no `insertBefore` ever acts on. Normalizing everything back
5252
5266
  * to world coordinates here would cost a transform per element per frame to
5253
5267
  * change nothing observable.
5268
+ *
5269
+ * Banding runs **per region** — per nearest `clipChildren` ancestor, recorded
5270
+ * by {@link enforceA11yDomOrder}'s collect walk — rather than once over the
5271
+ * whole scene. Purely visual banding is right for a screen reader but wrong
5272
+ * for selection: a DOM `Selection` covers everything between anchor and focus
5273
+ * in DOM order, so under one global banding a vertical drag through a
5274
+ * transcript also swallowed a sidebar whose headings happened to fall in the
5275
+ * same rows. Regions are laid out side by side, so ordering region-major keeps
5276
+ * each one a contiguous DOM run and a drag stays inside it, while reading
5277
+ * order *within* a region is unchanged. Regions are emitted in the order their
5278
+ * clipper is first reached by the depth-first walk, so a screen reader still
5279
+ * meets them in the author's declared order.
5254
5280
  */
5255
5281
  sortNormalElementsVisually() {
5256
5282
  const els = this.normalElements;
@@ -5278,30 +5304,40 @@ var Scene = class _Scene {
5278
5304
  }
5279
5305
  return { top, left };
5280
5306
  };
5281
- const order = els.map((el, i) => {
5307
+ const decorated = els.map((el, i) => {
5282
5308
  const { top, left } = absolute(el);
5283
5309
  return { el, i, top, left, container: containers.has(el) };
5284
5310
  });
5285
- order.sort((p, q) => p.top - q.top || p.i - q.i);
5311
+ const regions = this.a11yOrderRegions;
5312
+ const buckets = /* @__PURE__ */ new Map();
5313
+ for (const d of decorated) {
5314
+ const key = regions.get(d.el) ?? null;
5315
+ const bucket = buckets.get(key);
5316
+ if (bucket) bucket.push(d);
5317
+ else buckets.set(key, [d]);
5318
+ }
5286
5319
  const bandBottom = (r) => r.top + (r.container ? 4 : heightOf(r.el));
5287
5320
  const sorted = [];
5288
- let rowStart = 0;
5289
- let rowBottom = order.length ? bandBottom(order[0]) : 0;
5290
- const flushRow = (end) => {
5291
- const row = order.slice(rowStart, end);
5292
- row.sort((p, q) => (rtl ? q.left - p.left : p.left - q.left) || p.i - q.i);
5293
- for (const r of row) sorted.push(r.el);
5294
- };
5295
- for (let k = 1; k < order.length; k++) {
5296
- if (order[k].top < rowBottom) {
5297
- rowBottom = Math.max(rowBottom, bandBottom(order[k]));
5298
- } else {
5299
- flushRow(k);
5300
- rowStart = k;
5301
- rowBottom = bandBottom(order[k]);
5321
+ for (const order of buckets.values()) {
5322
+ order.sort((p, q) => p.top - q.top || p.i - q.i);
5323
+ let rowStart = 0;
5324
+ let rowBottom = order.length ? bandBottom(order[0]) : 0;
5325
+ const flushRow = (end) => {
5326
+ const row = order.slice(rowStart, end);
5327
+ row.sort((p, q) => (rtl ? q.left - p.left : p.left - q.left) || p.i - q.i);
5328
+ for (const r of row) sorted.push(r.el);
5329
+ };
5330
+ for (let k = 1; k < order.length; k++) {
5331
+ if (order[k].top < rowBottom) {
5332
+ rowBottom = Math.max(rowBottom, bandBottom(order[k]));
5333
+ } else {
5334
+ flushRow(k);
5335
+ rowStart = k;
5336
+ rowBottom = bandBottom(order[k]);
5337
+ }
5302
5338
  }
5339
+ flushRow(order.length);
5303
5340
  }
5304
- flushRow(order.length);
5305
5341
  for (let i = 0; i < sorted.length; i++) els[i] = sorted[i];
5306
5342
  }
5307
5343
  /** Keep DOM/WebGL overlay layers aligned with the canvas's CSS box. */
@@ -719,6 +719,16 @@ export declare class Scene {
719
719
  * see {@link sortNormalElementsVisually}.
720
720
  */
721
721
  private a11yOrderContainers;
722
+ /**
723
+ * Nearest `clipChildren` ancestor per ordered element — its *region* — reused
724
+ * per pass. Written by `enforceA11yDomOrder`'s collect walk, which already has
725
+ * the entity in hand, so a region costs one comparison per node rather than an
726
+ * ancestor walk per element.
727
+ *
728
+ * Absent means the element sits under no clipping ancestor and belongs to the
729
+ * implicit root region. See {@link sortNormalElementsVisually}.
730
+ */
731
+ private a11yOrderRegions;
722
732
  private activePortalsThisFrame;
723
733
  private activePortalsPrevFrame;
724
734
  private portalEntities;
@@ -1609,6 +1619,18 @@ export declare class Scene {
1609
1619
  * parents, which no `insertBefore` ever acts on. Normalizing everything back
1610
1620
  * to world coordinates here would cost a transform per element per frame to
1611
1621
  * change nothing observable.
1622
+ *
1623
+ * Banding runs **per region** — per nearest `clipChildren` ancestor, recorded
1624
+ * by {@link enforceA11yDomOrder}'s collect walk — rather than once over the
1625
+ * whole scene. Purely visual banding is right for a screen reader but wrong
1626
+ * for selection: a DOM `Selection` covers everything between anchor and focus
1627
+ * in DOM order, so under one global banding a vertical drag through a
1628
+ * transcript also swallowed a sidebar whose headings happened to fall in the
1629
+ * same rows. Regions are laid out side by side, so ordering region-major keeps
1630
+ * each one a contiguous DOM run and a drag stays inside it, while reading
1631
+ * order *within* a region is unchanged. Regions are emitted in the order their
1632
+ * clipper is first reached by the depth-first walk, so a screen reader still
1633
+ * meets them in the author's declared order.
1612
1634
  */
1613
1635
  private sortNormalElementsVisually;
1614
1636
  /** Keep DOM/WebGL overlay layers aligned with the canvas's CSS box. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectojs/core",
3
- "version": "1.32.0",
3
+ "version": "1.32.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },