@vectojs/core 1.33.0 → 1.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +109 -82
- package/dist/index.mjs +39 -12
- package/dist/tree/Entity.d.ts +14 -0
- package/dist/tree/scene/CanvasGeometry.d.ts +13 -2
- package/dist/tree/scene/content-break-carrier.d.ts +77 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -469,6 +469,21 @@ function rebaseChildBox(parent, parentOriginX, parentOriginY, child, childOrigin
|
|
|
469
469
|
return REBASED_BOX;
|
|
470
470
|
}
|
|
471
471
|
|
|
472
|
+
// src/tree/scene/content-break-carrier.ts
|
|
473
|
+
var HARD_BREAK_ONLY = /^[\r\n]+$/;
|
|
474
|
+
function appendContentBreak(owner, breakText) {
|
|
475
|
+
if (!breakText) return;
|
|
476
|
+
if (!HARD_BREAK_ONLY.test(breakText)) {
|
|
477
|
+
owner.appendChild(document.createTextNode(breakText));
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
const span = document.createElement("span");
|
|
481
|
+
span.textContent = breakText;
|
|
482
|
+
span.style.fontSize = "0";
|
|
483
|
+
span.style.lineHeight = "0";
|
|
484
|
+
owner.appendChild(span);
|
|
485
|
+
}
|
|
486
|
+
|
|
472
487
|
// src/tree/scene/content-line-window.ts
|
|
473
488
|
function projectionLineWindow(lines, band, fallbackLineHeight) {
|
|
474
489
|
const all = {
|
|
@@ -529,7 +544,8 @@ var ContentGridProjector = class {
|
|
|
529
544
|
throw new Error("ContentProjection.grid.source must equal ContentProjection.text");
|
|
530
545
|
}
|
|
531
546
|
const gridWindow = projectionGridLineWindow(grid, projection.lines, lineBand);
|
|
532
|
-
const
|
|
547
|
+
const originSignature = _nullishCoalesce(_optionalChain([projection, 'access', _27 => _27.lines, 'optionalAccess', _28 => _28.find, 'call', _29 => _29((line) => line !== void 0), 'optionalAccess', _30 => _30.x]), () => ( 0));
|
|
548
|
+
const signature = gridWindow.gated ? `${grid.revision}:${gridWindow.start}-${gridWindow.end}:${originSignature}` : `${grid.revision}:${originSignature}`;
|
|
533
549
|
if (el.dataset.vectoContentGrid !== signature) {
|
|
534
550
|
const materializeStart = typeof performance !== "undefined" ? performance.now() : 0;
|
|
535
551
|
this.contentProjection.clearGridState(entityId, el, false);
|
|
@@ -560,9 +576,9 @@ var ContentGridProjector = class {
|
|
|
560
576
|
const domIndex = lineIndex - gridWindow.start;
|
|
561
577
|
const gridLine = grid.lines[lineIndex];
|
|
562
578
|
const projectedLine = projectionLines[lineIndex];
|
|
563
|
-
const lineHeight = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
564
|
-
const baseline = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
565
|
-
const lineFont = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
579
|
+
const lineHeight = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _31 => _31.lineHeight]), () => ( grid.lineHeight));
|
|
580
|
+
const baseline = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _32 => _32.baseline]), () => ( grid.baseline));
|
|
581
|
+
const lineFont = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _33 => _33.font]), () => ( grid.font));
|
|
566
582
|
const lineSignature = contentGridLineSignature(
|
|
567
583
|
grid,
|
|
568
584
|
gridLine,
|
|
@@ -582,24 +598,24 @@ var ContentGridProjector = class {
|
|
|
582
598
|
lineElement.dir = "ltr";
|
|
583
599
|
lineElement.dataset.vectoGridLine = `${lineIndex}`;
|
|
584
600
|
lineElement.style.position = "absolute";
|
|
585
|
-
lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
586
|
-
lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
601
|
+
lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _34 => _34.x]), () => ( 0))}px`;
|
|
602
|
+
lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _35 => _35.y]), () => ( lineIndex * grid.lineHeight))) + baseline - _text.cssLineBoxBaseline.call(void 0, lineFont, lineHeight)}px`;
|
|
587
603
|
lineElement.style.width = `${gridLine.width}px`;
|
|
588
604
|
lineElement.style.height = `${lineHeight}px`;
|
|
589
605
|
lineElement.style.whiteSpace = "pre";
|
|
590
606
|
lineElement.style.font = lineFont;
|
|
591
607
|
lineElement.style.lineHeight = `${lineHeight}px`;
|
|
608
|
+
const breakText = grid.source.slice(gridLine.sourceEnd, gridLine.nextSourceStart);
|
|
592
609
|
if (gridLine.cells.length === 0) {
|
|
593
|
-
lineElement
|
|
610
|
+
appendContentBreak(lineElement, breakText);
|
|
594
611
|
} else {
|
|
595
612
|
let logicalX = 0;
|
|
596
613
|
for (let cellIndex = 0; cellIndex < gridLine.cells.length; cellIndex++) {
|
|
597
614
|
const cell = gridLine.cells[cellIndex];
|
|
598
615
|
const cellElement = document.createElement("span");
|
|
599
616
|
cellElement.dir = "ltr";
|
|
600
|
-
const separator = cellIndex === gridLine.cells.length - 1 ? grid.source.slice(gridLine.sourceEnd, gridLine.nextSourceStart) : "";
|
|
601
617
|
const sourceText = grid.source.slice(cell.sourceStart, cell.sourceEnd);
|
|
602
|
-
cellElement.textContent = sourceText
|
|
618
|
+
cellElement.textContent = sourceText;
|
|
603
619
|
cellElement.dataset.vectoGridCell = `${cellIndex}`;
|
|
604
620
|
cellElement.dataset.vectoGridSourceLength = `${sourceText.length}`;
|
|
605
621
|
cellElement.dataset.vectoGridSourceStart = `${cell.sourceStart}`;
|
|
@@ -625,6 +641,7 @@ var ContentGridProjector = class {
|
|
|
625
641
|
lineElement.appendChild(cellElement);
|
|
626
642
|
logicalX += cell.advance;
|
|
627
643
|
}
|
|
644
|
+
appendContentBreak(lineElement, breakText);
|
|
628
645
|
}
|
|
629
646
|
if (lineIndex === 0) {
|
|
630
647
|
for (const [basis, left, top] of [
|
|
@@ -651,7 +668,7 @@ var ContentGridProjector = class {
|
|
|
651
668
|
}
|
|
652
669
|
const windowLength = gridWindow.end - gridWindow.start;
|
|
653
670
|
while (el.children.length > windowLength) {
|
|
654
|
-
_optionalChain([el, 'access',
|
|
671
|
+
_optionalChain([el, 'access', _36 => _36.lastElementChild, 'optionalAccess', _37 => _37.remove, 'call', _38 => _38()]);
|
|
655
672
|
}
|
|
656
673
|
if (rebuiltSelectionLine) {
|
|
657
674
|
this.contentProjection.restoreGridSelection(el, selectionSnapshot);
|
|
@@ -691,8 +708,8 @@ var ContentGridProjector = class {
|
|
|
691
708
|
function contentGridLineSignature(grid, line, projected, lineHeight, baseline, font, isFirstLine) {
|
|
692
709
|
const parts = [
|
|
693
710
|
// Line box: position, size, and the font that resolves its baseline.
|
|
694
|
-
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess',
|
|
695
|
-
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess',
|
|
711
|
+
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _39 => _39.x]), () => ( 0))}`,
|
|
712
|
+
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _40 => _40.y]), () => ( ""))}`,
|
|
696
713
|
`${lineHeight}`,
|
|
697
714
|
`${baseline}`,
|
|
698
715
|
font,
|
|
@@ -860,7 +877,7 @@ var A11yProjectionManager = (_class2 = class {constructor() { _class2.prototype.
|
|
|
860
877
|
if (!selectionSnapshotTaken) {
|
|
861
878
|
selectionSnapshotTaken = true;
|
|
862
879
|
const live = typeof window !== "undefined" && typeof window.getSelection === "function" ? window.getSelection() : null;
|
|
863
|
-
if (_optionalChain([live, 'optionalAccess',
|
|
880
|
+
if (_optionalChain([live, 'optionalAccess', _41 => _41.anchorNode]) && live.focusNode) {
|
|
864
881
|
selection = live;
|
|
865
882
|
selAnchorNode = live.anchorNode;
|
|
866
883
|
selFocusNode = live.focusNode;
|
|
@@ -995,7 +1012,7 @@ var CanvasGeometry = (_class3 = class {
|
|
|
995
1012
|
}
|
|
996
1013
|
/** Convert browser viewport coordinates into the scene's logical coordinates. */
|
|
997
1014
|
clientToScene(clientX, clientY, width, height) {
|
|
998
|
-
const rect = _optionalChain([this, 'access',
|
|
1015
|
+
const rect = _optionalChain([this, 'access', _42 => _42.canvas, 'access', _43 => _43.getBoundingClientRect, 'optionalCall', _44 => _44()]);
|
|
999
1016
|
if (!rect) return { x: clientX, y: clientY };
|
|
1000
1017
|
const cssWidth = rect.width || this.canvas.clientWidth || width;
|
|
1001
1018
|
const cssHeight = rect.height || this.canvas.clientHeight || height;
|
|
@@ -1033,16 +1050,18 @@ var CanvasGeometry = (_class3 = class {
|
|
|
1033
1050
|
syncOverlay(width, height, glCanvas, gpuCanvas) {
|
|
1034
1051
|
const parent = this.canvas.parentElement;
|
|
1035
1052
|
if (!parent) return;
|
|
1036
|
-
const canvasRect = _optionalChain([this, 'access',
|
|
1037
|
-
const parentRect = _optionalChain([parent, 'access',
|
|
1038
|
-
const cssWidth = _optionalChain([canvasRect, 'optionalAccess',
|
|
1039
|
-
const cssHeight = _optionalChain([canvasRect, 'optionalAccess',
|
|
1040
|
-
const
|
|
1041
|
-
const
|
|
1053
|
+
const canvasRect = _optionalChain([this, 'access', _45 => _45.canvas, 'access', _46 => _46.getBoundingClientRect, 'optionalCall', _47 => _47()]);
|
|
1054
|
+
const parentRect = _optionalChain([parent, 'access', _48 => _48.getBoundingClientRect, 'optionalCall', _49 => _49()]);
|
|
1055
|
+
const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _50 => _50.width]) || this.canvas.clientWidth || width;
|
|
1056
|
+
const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _51 => _51.height]) || this.canvas.clientHeight || height;
|
|
1057
|
+
const canvasPosition = typeof getComputedStyle === "function" ? getComputedStyle(this.canvas).position : "";
|
|
1058
|
+
const position = canvasPosition === "fixed" ? "fixed" : "absolute";
|
|
1059
|
+
const left = position === "fixed" ? _nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _52 => _52.left]), () => ( 0)) : (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _53 => _53.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _54 => _54.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
|
|
1060
|
+
const top = position === "fixed" ? _nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _55 => _55.top]), () => ( 0)) : (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _56 => _56.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _57 => _57.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
|
|
1042
1061
|
const scaleX = width > 0 ? cssWidth / width : 1;
|
|
1043
1062
|
const scaleY = height > 0 ? cssHeight / height : 1;
|
|
1044
1063
|
const prev = this.overlayGeometry;
|
|
1045
|
-
if (prev !== null && prev.left === left && prev.top === top && prev.cssWidth === cssWidth && prev.cssHeight === cssHeight && prev.width === width && prev.height === height) {
|
|
1064
|
+
if (prev !== null && prev.left === left && prev.top === top && prev.cssWidth === cssWidth && prev.cssHeight === cssHeight && prev.width === width && prev.height === height && prev.position === position) {
|
|
1046
1065
|
return;
|
|
1047
1066
|
}
|
|
1048
1067
|
this.overlayGeometry = {
|
|
@@ -1051,10 +1070,12 @@ var CanvasGeometry = (_class3 = class {
|
|
|
1051
1070
|
cssWidth,
|
|
1052
1071
|
cssHeight,
|
|
1053
1072
|
width,
|
|
1054
|
-
height
|
|
1073
|
+
height,
|
|
1074
|
+
position
|
|
1055
1075
|
};
|
|
1056
1076
|
for (const root of [this.a11yRoot, this.portalRoot]) {
|
|
1057
1077
|
if (!root) continue;
|
|
1078
|
+
root.style.position = position;
|
|
1058
1079
|
root.style.left = `${left}px`;
|
|
1059
1080
|
root.style.top = `${top}px`;
|
|
1060
1081
|
root.style.width = `${width}px`;
|
|
@@ -1064,6 +1085,7 @@ var CanvasGeometry = (_class3 = class {
|
|
|
1064
1085
|
}
|
|
1065
1086
|
for (const canvas of [glCanvas, gpuCanvas]) {
|
|
1066
1087
|
if (!canvas) continue;
|
|
1088
|
+
canvas.style.position = position;
|
|
1067
1089
|
canvas.style.left = `${left}px`;
|
|
1068
1090
|
canvas.style.top = `${top}px`;
|
|
1069
1091
|
canvas.style.width = `${cssWidth}px`;
|
|
@@ -1601,7 +1623,7 @@ var HitTester = (_class6 = class {
|
|
|
1601
1623
|
const idx = cell[k];
|
|
1602
1624
|
if (x < minx[idx] || x > maxx[idx] || y < miny[idx] || y > maxy[idx]) continue;
|
|
1603
1625
|
const entity = this.slotEntity[idx];
|
|
1604
|
-
if (_optionalChain([entity, 'optionalAccess',
|
|
1626
|
+
if (_optionalChain([entity, 'optionalAccess', _58 => _58.isPointInside, 'call', _59 => _59(x, y)]) && this.isHitEligible(entity, x, y)) {
|
|
1605
1627
|
bestIndex = idx;
|
|
1606
1628
|
bestEntity = entity;
|
|
1607
1629
|
break;
|
|
@@ -1665,6 +1687,7 @@ var HitTester = (_class6 = class {
|
|
|
1665
1687
|
}, _class6);
|
|
1666
1688
|
|
|
1667
1689
|
// src/tree/scene/ContentProjectionManager.ts
|
|
1690
|
+
var PAGE_SCALE_BASIS_PX = 256;
|
|
1668
1691
|
var ContentProjectionManager = (_class7 = class {
|
|
1669
1692
|
/**
|
|
1670
1693
|
* `a11yRoot` doubles as the projection root: carriers are appended to it, and
|
|
@@ -1756,16 +1779,16 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1756
1779
|
* to the live DOM selection.
|
|
1757
1780
|
*/
|
|
1758
1781
|
gridSelectionLine(el) {
|
|
1759
|
-
const candidates = [_optionalChain([this, 'access',
|
|
1782
|
+
const candidates = [_optionalChain([this, 'access', _60 => _60.anchor, 'optionalAccess', _61 => _61.node])];
|
|
1760
1783
|
if (typeof window !== "undefined" && typeof window.getSelection === "function") {
|
|
1761
1784
|
const selection = window.getSelection();
|
|
1762
|
-
candidates.push(_optionalChain([selection, 'optionalAccess',
|
|
1785
|
+
candidates.push(_optionalChain([selection, 'optionalAccess', _62 => _62.anchorNode]), _optionalChain([selection, 'optionalAccess', _63 => _63.focusNode]));
|
|
1763
1786
|
}
|
|
1764
1787
|
for (const candidate of candidates) {
|
|
1765
1788
|
if (!candidate || !el.contains(candidate)) continue;
|
|
1766
1789
|
let cursor = candidate;
|
|
1767
1790
|
while (cursor && cursor.parentNode !== el) cursor = cursor.parentNode;
|
|
1768
|
-
const lineIndex = _optionalChain([cursor, 'optionalAccess',
|
|
1791
|
+
const lineIndex = _optionalChain([cursor, 'optionalAccess', _64 => _64.dataset, 'optionalAccess', _65 => _65.vectoGridLine]);
|
|
1769
1792
|
if (lineIndex !== void 0) return Number(lineIndex);
|
|
1770
1793
|
}
|
|
1771
1794
|
return null;
|
|
@@ -1790,10 +1813,10 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1790
1813
|
releaseSelectionForRebuild(el) {
|
|
1791
1814
|
if (!this.anchor && !this.selectionPresent()) return;
|
|
1792
1815
|
const selection = typeof window !== "undefined" && typeof window.getSelection === "function" ? window.getSelection() : null;
|
|
1793
|
-
const ownsSelection = this.anchor && el.contains(this.anchor.node) || (_optionalChain([selection, 'optionalAccess',
|
|
1816
|
+
const ownsSelection = this.anchor && el.contains(this.anchor.node) || (_optionalChain([selection, 'optionalAccess', _66 => _66.anchorNode]) ? el.contains(selection.anchorNode) : false) || (_optionalChain([selection, 'optionalAccess', _67 => _67.focusNode]) ? el.contains(selection.focusNode) : false);
|
|
1794
1817
|
if (!ownsSelection) return;
|
|
1795
1818
|
this.endDrag();
|
|
1796
|
-
_optionalChain([selection, 'optionalAccess',
|
|
1819
|
+
_optionalChain([selection, 'optionalAccess', _68 => _68.removeAllRanges, 'call', _69 => _69()]);
|
|
1797
1820
|
this.presentThisSync = null;
|
|
1798
1821
|
}
|
|
1799
1822
|
/**
|
|
@@ -1868,7 +1891,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1868
1891
|
let cursor = node;
|
|
1869
1892
|
while (cursor && cursor !== el) {
|
|
1870
1893
|
const cell = cursor;
|
|
1871
|
-
const start = _optionalChain([cell, 'access',
|
|
1894
|
+
const start = _optionalChain([cell, 'access', _70 => _70.dataset, 'optionalAccess', _71 => _71.vectoGridSourceStart]);
|
|
1872
1895
|
if (start !== void 0) {
|
|
1873
1896
|
const sourceStart = Number(start);
|
|
1874
1897
|
const sourceLength = Number(_nullishCoalesce(cell.dataset.vectoGridSourceLength, () => ( 0)));
|
|
@@ -1962,7 +1985,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
1962
1985
|
cancelAnimationFrame(calibrationFrame);
|
|
1963
1986
|
}
|
|
1964
1987
|
this.calibrationFrameHandles.delete(entityId);
|
|
1965
|
-
_optionalChain([this, 'access',
|
|
1988
|
+
_optionalChain([this, 'access', _72 => _72.calibrationProbes, 'access', _73 => _73.get, 'call', _74 => _74(entityId), 'optionalAccess', _75 => _75.remove, 'call', _76 => _76()]);
|
|
1966
1989
|
this.calibrationProbes.delete(entityId);
|
|
1967
1990
|
delete el.dataset.vectoGridCalibrationPending;
|
|
1968
1991
|
delete el.dataset.vectoGridCalibration;
|
|
@@ -2026,7 +2049,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
2026
2049
|
if (previous !== void 0 && typeof cancelAnimationFrame === "function") {
|
|
2027
2050
|
cancelAnimationFrame(previous);
|
|
2028
2051
|
}
|
|
2029
|
-
_optionalChain([this, 'access',
|
|
2052
|
+
_optionalChain([this, 'access', _77 => _77.calibrationProbes, 'access', _78 => _78.get, 'call', _79 => _79(entityId), 'optionalAccess', _80 => _80.remove, 'call', _81 => _81()]);
|
|
2030
2053
|
this.calibrationProbes.delete(entityId);
|
|
2031
2054
|
const calibrationStart = typeof performance !== "undefined" ? performance.now() : 0;
|
|
2032
2055
|
const probe = document.createElement("div");
|
|
@@ -2047,7 +2070,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
2047
2070
|
probeOrigin.style.top = "0";
|
|
2048
2071
|
const probeX = document.createElement("span");
|
|
2049
2072
|
probeX.style.position = "absolute";
|
|
2050
|
-
probeX.style.left =
|
|
2073
|
+
probeX.style.left = `${PAGE_SCALE_BASIS_PX}px`;
|
|
2051
2074
|
probeX.style.top = "0";
|
|
2052
2075
|
probe.append(probeOrigin, probeX);
|
|
2053
2076
|
const measurements = [];
|
|
@@ -2060,7 +2083,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
2060
2083
|
target.dataset.vectoGridCalib = generation;
|
|
2061
2084
|
continue;
|
|
2062
2085
|
}
|
|
2063
|
-
const sourceText = _nullishCoalesce(_optionalChain([target, 'access',
|
|
2086
|
+
const sourceText = _nullishCoalesce(_optionalChain([target, 'access', _82 => _82.textContent, 'optionalAccess', _83 => _83.slice, 'call', _84 => _84(0, sourceLength)]), () => ( ""));
|
|
2064
2087
|
if (!sourceText) {
|
|
2065
2088
|
target.dataset.vectoGridCalib = generation;
|
|
2066
2089
|
continue;
|
|
@@ -2120,7 +2143,7 @@ var ContentProjectionManager = (_class7 = class {
|
|
|
2120
2143
|
const updates = [];
|
|
2121
2144
|
const probeOriginRect = probeOrigin.getBoundingClientRect();
|
|
2122
2145
|
const probeXRect = probeX.getBoundingClientRect();
|
|
2123
|
-
const basisScale = Math.abs(probeXRect.left - probeOriginRect.left);
|
|
2146
|
+
const basisScale = Math.abs(probeXRect.left - probeOriginRect.left) / PAGE_SCALE_BASIS_PX;
|
|
2124
2147
|
const projectionPageScaleX = Number.isFinite(basisScale) && basisScale > 0 ? basisScale : pageScaleX;
|
|
2125
2148
|
let valid = true;
|
|
2126
2149
|
for (const measurement of measurements) {
|
|
@@ -3456,9 +3479,9 @@ function parseCssMatrix(transform) {
|
|
|
3456
3479
|
}
|
|
3457
3480
|
function clientToGridLocal(contentEl, canvas, clientX, clientY) {
|
|
3458
3481
|
const line = contentEl.querySelector("[data-vecto-grid-line]");
|
|
3459
|
-
const originMarker = _optionalChain([line, 'optionalAccess',
|
|
3460
|
-
const xMarker = _optionalChain([line, 'optionalAccess',
|
|
3461
|
-
const yMarker = _optionalChain([line, 'optionalAccess',
|
|
3482
|
+
const originMarker = _optionalChain([line, 'optionalAccess', _85 => _85.querySelector, 'call', _86 => _86('[data-vecto-grid-basis="origin"]')]);
|
|
3483
|
+
const xMarker = _optionalChain([line, 'optionalAccess', _87 => _87.querySelector, 'call', _88 => _88('[data-vecto-grid-basis="x"]')]);
|
|
3484
|
+
const yMarker = _optionalChain([line, 'optionalAccess', _89 => _89.querySelector, 'call', _90 => _90('[data-vecto-grid-basis="y"]')]);
|
|
3462
3485
|
if (line && originMarker && xMarker && yMarker) {
|
|
3463
3486
|
const origin = originMarker.getBoundingClientRect();
|
|
3464
3487
|
const xPoint = xMarker.getBoundingClientRect();
|
|
@@ -3542,7 +3565,7 @@ function nearestTextPositionInLine(line, x, y) {
|
|
|
3542
3565
|
nearest = { position: { node, offset }, distance: candidate.distance };
|
|
3543
3566
|
}
|
|
3544
3567
|
}
|
|
3545
|
-
return _nullishCoalesce(_optionalChain([nearest, 'optionalAccess',
|
|
3568
|
+
return _nullishCoalesce(_optionalChain([nearest, 'optionalAccess', _91 => _91.position]), () => ( null));
|
|
3546
3569
|
}
|
|
3547
3570
|
function nearestTextPositionInProjection(contentEl, canvas, x, y, eventTarget) {
|
|
3548
3571
|
if (contentEl.dataset.vectoContentGrid !== void 0) {
|
|
@@ -3556,7 +3579,7 @@ function nearestTextPositionInProjection(contentEl, canvas, x, y, eventTarget) {
|
|
|
3556
3579
|
}
|
|
3557
3580
|
targetLine = targetLine.parentElement;
|
|
3558
3581
|
}
|
|
3559
|
-
if (_optionalChain([targetLine, 'optionalAccess',
|
|
3582
|
+
if (_optionalChain([targetLine, 'optionalAccess', _92 => _92.parentElement]) === contentEl) {
|
|
3560
3583
|
return nearestTextPositionInLine(targetLine, x, y);
|
|
3561
3584
|
}
|
|
3562
3585
|
let bestLine = null;
|
|
@@ -3809,7 +3832,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
3809
3832
|
__init102() {this.forcedColorsChangeHandler = null}
|
|
3810
3833
|
/** True when the OS asks for reduced motion and we respect it. Read by the animation drivers. */
|
|
3811
3834
|
get prefersReducedMotion() {
|
|
3812
|
-
return this.respectReducedMotion && !!_optionalChain([this, 'access',
|
|
3835
|
+
return this.respectReducedMotion && !!_optionalChain([this, 'access', _93 => _93.reducedMotionQuery, 'optionalAccess', _94 => _94.matches]);
|
|
3813
3836
|
}
|
|
3814
3837
|
/**
|
|
3815
3838
|
* True when the OS is in a forced-colors mode (Windows High Contrast, and the
|
|
@@ -3820,7 +3843,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
3820
3843
|
* when the setting toggles.
|
|
3821
3844
|
*/
|
|
3822
3845
|
get forcedColors() {
|
|
3823
|
-
return !!_optionalChain([this, 'access',
|
|
3846
|
+
return !!_optionalChain([this, 'access', _95 => _95.forcedColorsQuery, 'optionalAccess', _96 => _96.matches]);
|
|
3824
3847
|
}
|
|
3825
3848
|
// --- domain: a11y-projection — sync throttle and shadow-DOM state ---
|
|
3826
3849
|
/**
|
|
@@ -4520,7 +4543,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4520
4543
|
* active.
|
|
4521
4544
|
*/
|
|
4522
4545
|
get webglDrawStats() {
|
|
4523
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
4546
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _97 => _97.pointRenderer, 'optionalAccess', _98 => _98.stats, 'optionalCall', _99 => _99()]), () => ( null));
|
|
4524
4547
|
}
|
|
4525
4548
|
/**
|
|
4526
4549
|
* Whether a WebGPU device is currently live for particle compute.
|
|
@@ -4589,8 +4612,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
4589
4612
|
static _devModeDetected() {
|
|
4590
4613
|
if (_Scene._devMode) return true;
|
|
4591
4614
|
const gp = typeof globalThis !== "undefined" ? globalThis : void 0;
|
|
4592
|
-
if (_optionalChain([gp, 'optionalAccess',
|
|
4593
|
-
if (_optionalChain([gp, 'optionalAccess',
|
|
4615
|
+
if (_optionalChain([gp, 'optionalAccess', _100 => _100.__DEV__])) return true;
|
|
4616
|
+
if (_optionalChain([gp, 'optionalAccess', _101 => _101.process, 'optionalAccess', _102 => _102.env, 'optionalAccess', _103 => _103.NODE_ENV]) === "development") return true;
|
|
4594
4617
|
return false;
|
|
4595
4618
|
}
|
|
4596
4619
|
|
|
@@ -4652,9 +4675,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
4652
4675
|
let checked = 0;
|
|
4653
4676
|
const walkProjections = (node) => {
|
|
4654
4677
|
if (checked > 10) return;
|
|
4655
|
-
const proj = _optionalChain([node, 'access',
|
|
4656
|
-
if (_optionalChain([proj, 'optionalAccess',
|
|
4657
|
-
const el = _optionalChain([this, 'access',
|
|
4678
|
+
const proj = _optionalChain([node, 'access', _104 => _104.getContentProjection, 'optionalCall', _105 => _105()]);
|
|
4679
|
+
if (_optionalChain([proj, 'optionalAccess', _106 => _106.text]) && proj.selectable !== false) {
|
|
4680
|
+
const el = _optionalChain([this, 'access', _107 => _107.contentElements, 'optionalAccess', _108 => _108.get, 'call', _109 => _109(node.id)]);
|
|
4658
4681
|
if (el) {
|
|
4659
4682
|
const projectedText = el.textContent || "";
|
|
4660
4683
|
const windowed = el.dataset.vectoProjectionWindow !== void 0;
|
|
@@ -4678,8 +4701,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
4678
4701
|
this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
|
|
4679
4702
|
this.maxDPR = options.maxDPR;
|
|
4680
4703
|
if (this.disableWindowResize) {
|
|
4681
|
-
const styleWidth = parseInlinePx(_optionalChain([canvas, 'access',
|
|
4682
|
-
const styleHeight = parseInlinePx(_optionalChain([canvas, 'access',
|
|
4704
|
+
const styleWidth = parseInlinePx(_optionalChain([canvas, 'access', _110 => _110.style, 'optionalAccess', _111 => _111.width]));
|
|
4705
|
+
const styleHeight = parseInlinePx(_optionalChain([canvas, 'access', _112 => _112.style, 'optionalAccess', _113 => _113.height]));
|
|
4683
4706
|
this.width = _nullishCoalesce(styleWidth, () => ( (canvas.width || canvas.clientWidth || 0)));
|
|
4684
4707
|
this.height = _nullishCoalesce(styleHeight, () => ( (canvas.height || canvas.clientHeight || 0)));
|
|
4685
4708
|
} else {
|
|
@@ -4687,7 +4710,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4687
4710
|
this.height = typeof window !== "undefined" ? window.innerHeight : canvas.clientHeight || canvas.height || 600;
|
|
4688
4711
|
}
|
|
4689
4712
|
const globalProcess = typeof globalThis !== "undefined" ? globalThis.process : void 0;
|
|
4690
|
-
const isTest = globalProcess && (_optionalChain([globalProcess, 'access',
|
|
4713
|
+
const isTest = globalProcess && (_optionalChain([globalProcess, 'access', _114 => _114.env, 'optionalAccess', _115 => _115.NODE_ENV]) === "test" || _optionalChain([globalProcess, 'access', _116 => _116.env, 'optionalAccess', _117 => _117.VITEST]) === "true");
|
|
4691
4714
|
this.maxFPS = _nullishCoalesce(options.maxFPS, () => ( (isTest ? 0 : 60)));
|
|
4692
4715
|
this.respectReducedMotion = _nullishCoalesce(options.respectReducedMotion, () => ( true));
|
|
4693
4716
|
this.autoThrottle = _nullishCoalesce(options.autoThrottle, () => ( true));
|
|
@@ -4707,7 +4730,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4707
4730
|
if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
|
|
4708
4731
|
this.forcedColorsQuery = window.matchMedia("(forced-colors: active)");
|
|
4709
4732
|
this.forcedColorsChangeHandler = () => this.markDirty();
|
|
4710
|
-
_optionalChain([this, 'access',
|
|
4733
|
+
_optionalChain([this, 'access', _118 => _118.forcedColorsQuery, 'access', _119 => _119.addEventListener, 'optionalCall', _120 => _120("change", this.forcedColorsChangeHandler)]);
|
|
4711
4734
|
}
|
|
4712
4735
|
this.root = new class RootEntity extends _chunkUEIZDNK7js.Entity {
|
|
4713
4736
|
isPointInside() {
|
|
@@ -4738,9 +4761,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
4738
4761
|
this.maxDPR
|
|
4739
4762
|
);
|
|
4740
4763
|
}
|
|
4741
|
-
_optionalChain([this, 'access',
|
|
4764
|
+
_optionalChain([this, 'access', _121 => _121.renderer, 'access', _122 => _122.onContextRestored, 'optionalCall', _123 => _123(() => {
|
|
4742
4765
|
this.markDirty();
|
|
4743
|
-
if (_optionalChain([this, 'access',
|
|
4766
|
+
if (_optionalChain([this, 'access', _124 => _124.renderer, 'access', _125 => _125.isContextLost, 'optionalCall', _126 => _126()]) !== true) this.render(this.renderer);
|
|
4744
4767
|
})]);
|
|
4745
4768
|
if (typeof document !== "undefined") {
|
|
4746
4769
|
this.a11yRoot = document.createElement("div");
|
|
@@ -4913,16 +4936,16 @@ var Scene = (_class15 = class _Scene {
|
|
|
4913
4936
|
watchDevicePixelRatio() {
|
|
4914
4937
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
4915
4938
|
if (this.dprMediaQuery && this.dprChangeHandler) {
|
|
4916
|
-
_optionalChain([this, 'access',
|
|
4939
|
+
_optionalChain([this, 'access', _127 => _127.dprMediaQuery, 'access', _128 => _128.removeEventListener, 'optionalCall', _129 => _129("change", this.dprChangeHandler)]);
|
|
4917
4940
|
}
|
|
4918
4941
|
const dpr = window.devicePixelRatio || 1;
|
|
4919
4942
|
const query = window.matchMedia(`(resolution: ${dpr}dppx)`);
|
|
4920
4943
|
const handler = () => {
|
|
4921
4944
|
this.resize(this.width, this.height);
|
|
4922
|
-
if (_optionalChain([this, 'access',
|
|
4945
|
+
if (_optionalChain([this, 'access', _130 => _130.renderer, 'access', _131 => _131.isContextLost, 'optionalCall', _132 => _132()]) !== true) this.render(this.renderer);
|
|
4923
4946
|
this.watchDevicePixelRatio();
|
|
4924
4947
|
};
|
|
4925
|
-
_optionalChain([query, 'access',
|
|
4948
|
+
_optionalChain([query, 'access', _133 => _133.addEventListener, 'optionalCall', _134 => _134("change", handler)]);
|
|
4926
4949
|
this.dprMediaQuery = query;
|
|
4927
4950
|
this.dprChangeHandler = handler;
|
|
4928
4951
|
}
|
|
@@ -4942,7 +4965,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4942
4965
|
if (typeof gl.addEventListener !== "function") return;
|
|
4943
4966
|
this.glContextLostHandler = (e) => {
|
|
4944
4967
|
e.preventDefault();
|
|
4945
|
-
_optionalChain([this, 'access',
|
|
4968
|
+
_optionalChain([this, 'access', _135 => _135.pointRenderer, 'optionalAccess', _136 => _136.destroy, 'call', _137 => _137()]);
|
|
4946
4969
|
this.pointRenderer = null;
|
|
4947
4970
|
};
|
|
4948
4971
|
this.glContextRestoredHandler = () => {
|
|
@@ -5143,12 +5166,12 @@ var Scene = (_class15 = class _Scene {
|
|
|
5143
5166
|
this.canvasResizeObserver = null;
|
|
5144
5167
|
}
|
|
5145
5168
|
if (this.dprMediaQuery && this.dprChangeHandler) {
|
|
5146
|
-
_optionalChain([this, 'access',
|
|
5169
|
+
_optionalChain([this, 'access', _138 => _138.dprMediaQuery, 'access', _139 => _139.removeEventListener, 'optionalCall', _140 => _140("change", this.dprChangeHandler)]);
|
|
5147
5170
|
this.dprMediaQuery = null;
|
|
5148
5171
|
this.dprChangeHandler = null;
|
|
5149
5172
|
}
|
|
5150
5173
|
if (this.forcedColorsQuery && this.forcedColorsChangeHandler) {
|
|
5151
|
-
_optionalChain([this, 'access',
|
|
5174
|
+
_optionalChain([this, 'access', _141 => _141.forcedColorsQuery, 'access', _142 => _142.removeEventListener, 'optionalCall', _143 => _143("change", this.forcedColorsChangeHandler)]);
|
|
5152
5175
|
this.forcedColorsQuery = null;
|
|
5153
5176
|
this.forcedColorsChangeHandler = null;
|
|
5154
5177
|
}
|
|
@@ -5166,9 +5189,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
5166
5189
|
}
|
|
5167
5190
|
this.pointerEventTarget = null;
|
|
5168
5191
|
}
|
|
5169
|
-
_optionalChain([this, 'access',
|
|
5192
|
+
_optionalChain([this, 'access', _144 => _144.a11yRoot, 'optionalAccess', _145 => _145.remove, 'call', _146 => _146()]);
|
|
5170
5193
|
this.focusSentinel = null;
|
|
5171
|
-
_optionalChain([this, 'access',
|
|
5194
|
+
_optionalChain([this, 'access', _147 => _147.portalRoot, 'optionalAccess', _148 => _148.remove, 'call', _149 => _149()]);
|
|
5172
5195
|
this.a11yElements.clear();
|
|
5173
5196
|
for (const el of this.contentElements.values()) el.remove();
|
|
5174
5197
|
this.contentElements.clear();
|
|
@@ -5184,10 +5207,10 @@ var Scene = (_class15 = class _Scene {
|
|
|
5184
5207
|
}
|
|
5185
5208
|
this.glContextLostHandler = null;
|
|
5186
5209
|
this.glContextRestoredHandler = null;
|
|
5187
|
-
_optionalChain([this, 'access',
|
|
5188
|
-
_optionalChain([this, 'access',
|
|
5189
|
-
_optionalChain([this, 'access',
|
|
5190
|
-
_optionalChain([this, 'access',
|
|
5210
|
+
_optionalChain([this, 'access', _150 => _150.pointRenderer, 'optionalAccess', _151 => _151.destroy, 'call', _152 => _152()]);
|
|
5211
|
+
_optionalChain([this, 'access', _153 => _153.renderer, 'access', _154 => _154.dispose, 'optionalCall', _155 => _155()]);
|
|
5212
|
+
_optionalChain([this, 'access', _156 => _156.glCanvas, 'optionalAccess', _157 => _157.remove, 'call', _158 => _158()]);
|
|
5213
|
+
_optionalChain([this, 'access', _159 => _159.gpuCanvas, 'optionalAccess', _160 => _160.remove, 'call', _161 => _161()]);
|
|
5191
5214
|
this.gpuCanvas = null;
|
|
5192
5215
|
this.gpuContext = null;
|
|
5193
5216
|
if (this.recoveryTimerId) {
|
|
@@ -5199,7 +5222,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5199
5222
|
this.manager = null;
|
|
5200
5223
|
}
|
|
5201
5224
|
if (this.device) {
|
|
5202
|
-
_optionalChain([this, 'access',
|
|
5225
|
+
_optionalChain([this, 'access', _162 => _162.device, 'access', _163 => _163.destroy, 'optionalCall', _164 => _164()]);
|
|
5203
5226
|
this.device = null;
|
|
5204
5227
|
}
|
|
5205
5228
|
}
|
|
@@ -5523,7 +5546,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5523
5546
|
if (this.mouseX > -9e3 && !this.projectsSelectableText(node)) {
|
|
5524
5547
|
if (node.isPointInside(this.mouseX, this.mouseY)) return true;
|
|
5525
5548
|
}
|
|
5526
|
-
const existing = _optionalChain([this, 'access',
|
|
5549
|
+
const existing = _optionalChain([this, 'access', _165 => _165.a11yElements, 'optionalAccess', _166 => _166.get, 'call', _167 => _167(node.id)]);
|
|
5527
5550
|
if (existing && typeof document !== "undefined" && document.activeElement === existing) {
|
|
5528
5551
|
return true;
|
|
5529
5552
|
}
|
|
@@ -5537,8 +5560,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
5537
5560
|
* selection.
|
|
5538
5561
|
*/
|
|
5539
5562
|
projectsSelectableText(node) {
|
|
5540
|
-
const projection = _optionalChain([node, 'access',
|
|
5541
|
-
return !!_optionalChain([projection, 'optionalAccess',
|
|
5563
|
+
const projection = _optionalChain([node, 'access', _168 => _168.getContentProjection, 'optionalCall', _169 => _169()]);
|
|
5564
|
+
return !!_optionalChain([projection, 'optionalAccess', _170 => _170.text]) && projection.selectable !== false;
|
|
5542
5565
|
}
|
|
5543
5566
|
/**
|
|
5544
5567
|
* Keep `entity`'s a11y shadow node projected while it has
|
|
@@ -5736,7 +5759,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5736
5759
|
el.addEventListener("compositionupdate", (e) => {
|
|
5737
5760
|
const data = _nullishCoalesce(e.data, () => ( ""));
|
|
5738
5761
|
composition = {
|
|
5739
|
-
start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess',
|
|
5762
|
+
start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _171 => _171.start]), () => ( 0)),
|
|
5740
5763
|
length: data.length
|
|
5741
5764
|
};
|
|
5742
5765
|
forward();
|
|
@@ -5978,7 +6001,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5978
6001
|
const display = visible ? "" : "none";
|
|
5979
6002
|
if (el.style.display !== display) el.style.display = display;
|
|
5980
6003
|
}
|
|
5981
|
-
_optionalChain([emitInitialScroll, 'optionalCall',
|
|
6004
|
+
_optionalChain([emitInitialScroll, 'optionalCall', _172 => _172()]);
|
|
5982
6005
|
}
|
|
5983
6006
|
if (this.phases.enabled) {
|
|
5984
6007
|
const projectionStart = performance.now();
|
|
@@ -6267,7 +6290,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6267
6290
|
for (let runIndex = 0; runIndex < line.runs.length; runIndex++) {
|
|
6268
6291
|
const run = line.runs[runIndex];
|
|
6269
6292
|
const runElement = document.createElement("span");
|
|
6270
|
-
runElement.textContent = run.text
|
|
6293
|
+
runElement.textContent = run.text;
|
|
6271
6294
|
if (run.font) runElement.style.font = run.font;
|
|
6272
6295
|
runElement.style.lineHeight = `${lineHeight2}px`;
|
|
6273
6296
|
if (positioned && run.x !== void 0) {
|
|
@@ -6283,8 +6306,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
6283
6306
|
lineElement.appendChild(runElement);
|
|
6284
6307
|
}
|
|
6285
6308
|
} else {
|
|
6286
|
-
lineElement.textContent = line.text
|
|
6309
|
+
lineElement.textContent = line.text;
|
|
6287
6310
|
}
|
|
6311
|
+
appendContentBreak(lineElement, separator);
|
|
6288
6312
|
el.appendChild(lineElement);
|
|
6289
6313
|
}
|
|
6290
6314
|
});
|
|
@@ -6335,6 +6359,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
6335
6359
|
if (node.width > 0) el.style.width = `${node.width}px`;
|
|
6336
6360
|
if (node.height > 0) el.style.height = `${node.height}px`;
|
|
6337
6361
|
el.style.transform = `matrix(${a}, ${b}, ${c}, ${d}, 0, 0)`;
|
|
6362
|
+
const clipToBounds = projection.clipToBounds === true;
|
|
6363
|
+
const clipPath = clipToBounds && node.width > 0 && node.height > 0 ? `inset(${-localY}px ${contentX}px ${localY}px ${-contentX}px)` : "";
|
|
6364
|
+
if (el.style.clipPath !== clipPath) el.style.clipPath = clipPath;
|
|
6338
6365
|
const residentTier = semanticMargin > interactionMargin;
|
|
6339
6366
|
const display = visible || residentTier && !this.projectionBoxVisible(node, worldTf, 0, true) ? "" : "none";
|
|
6340
6367
|
if (el.style.display !== display) el.style.display = display;
|
|
@@ -6373,8 +6400,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
6373
6400
|
next.f = f2;
|
|
6374
6401
|
next.tier = tier;
|
|
6375
6402
|
next.hasBand = lineBand !== null;
|
|
6376
|
-
next.bandMin = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess',
|
|
6377
|
-
next.bandMax = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess',
|
|
6403
|
+
next.bandMin = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess', _173 => _173.minY]), () => ( 0));
|
|
6404
|
+
next.bandMax = _nullishCoalesce(_optionalChain([lineBand, 'optionalAccess', _174 => _174.maxY]), () => ( 0));
|
|
6378
6405
|
next.visible = visible;
|
|
6379
6406
|
next.width = node.width;
|
|
6380
6407
|
next.height = node.height;
|
|
@@ -6560,7 +6587,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6560
6587
|
* (and {@link respectReducedMotion} is on). `0` means uncapped.
|
|
6561
6588
|
*/
|
|
6562
6589
|
effectiveMaxFPS() {
|
|
6563
|
-
const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access',
|
|
6590
|
+
const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _175 => _175.reducedMotionQuery, 'optionalAccess', _176 => _176.matches]);
|
|
6564
6591
|
if (reduced)
|
|
6565
6592
|
return this.maxFPS > 0 ? Math.min(this.maxFPS, REDUCED_MOTION_FPS) : REDUCED_MOTION_FPS;
|
|
6566
6593
|
return this.maxFPS;
|
|
@@ -6655,7 +6682,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6655
6682
|
* @param time - Current absolute time in milliseconds (default 0).
|
|
6656
6683
|
*/
|
|
6657
6684
|
render(renderer, dt = 0, time = 0) {
|
|
6658
|
-
if (_optionalChain([renderer, 'access',
|
|
6685
|
+
if (_optionalChain([renderer, 'access', _177 => _177.isContextLost, 'optionalCall', _178 => _178()])) return;
|
|
6659
6686
|
const isMainRenderer = renderer === this.renderer;
|
|
6660
6687
|
if (isMainRenderer && this.a11yRoot && this.canvas.parentElement) {
|
|
6661
6688
|
const parentStyle = this.canvas.parentElement.style;
|
|
@@ -6804,7 +6831,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6804
6831
|
}
|
|
6805
6832
|
renderer.clear();
|
|
6806
6833
|
if (isMainRenderer) {
|
|
6807
|
-
_optionalChain([this, 'access',
|
|
6834
|
+
_optionalChain([this, 'access', _179 => _179.pointRenderer, 'optionalAccess', _180 => _180.begin, 'call', _181 => _181()]);
|
|
6808
6835
|
}
|
|
6809
6836
|
const vw = this.width;
|
|
6810
6837
|
const vh = this.height;
|
|
@@ -7018,9 +7045,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
7018
7045
|
const flushT0 = this.phases.enabled ? performance.now() : 0;
|
|
7019
7046
|
renderer.flush();
|
|
7020
7047
|
if (isMainRenderer) {
|
|
7021
|
-
_optionalChain([this, 'access',
|
|
7048
|
+
_optionalChain([this, 'access', _182 => _182.pointRenderer, 'optionalAccess', _183 => _183.flush, 'call', _184 => _184()]);
|
|
7022
7049
|
}
|
|
7023
|
-
_optionalChain([renderer, 'access',
|
|
7050
|
+
_optionalChain([renderer, 'access', _185 => _185.present, 'optionalCall', _186 => _186()]);
|
|
7024
7051
|
if (this.phases.enabled) this.phases.record("flush", performance.now() - flushT0);
|
|
7025
7052
|
if (flushTiming) endVectoUserTiming(flushTiming);
|
|
7026
7053
|
if (this._devActive) {
|
|
@@ -7397,7 +7424,7 @@ var GridTextEntity = (_class17 = class extends _chunkUEIZDNK7js.Entity {
|
|
|
7397
7424
|
updateGrid(ascii) {
|
|
7398
7425
|
this.grid = ascii;
|
|
7399
7426
|
this.rows = ascii.length;
|
|
7400
|
-
this.cols = _optionalChain([ascii, 'access',
|
|
7427
|
+
this.cols = _optionalChain([ascii, 'access', _187 => _187[0], 'optionalAccess', _188 => _188.length]) || 0;
|
|
7401
7428
|
}
|
|
7402
7429
|
isPointInside(_globalX, _globalY) {
|
|
7403
7430
|
return false;
|
|
@@ -7548,7 +7575,7 @@ var SplineEntity = (_class18 = class extends _chunkUEIZDNK7js.Entity {
|
|
|
7548
7575
|
*/
|
|
7549
7576
|
computeContainsGradient() {
|
|
7550
7577
|
const isGradient = (c) => c !== null && !Array.isArray(c);
|
|
7551
|
-
return (_nullishCoalesce(_optionalChain([this, 'access',
|
|
7578
|
+
return (_nullishCoalesce(_optionalChain([this, 'access', _189 => _189._doc, 'access', _190 => _190.equations, 'optionalAccess', _191 => _191.some, 'call', _192 => _192((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _193 => _193._doc, 'access', _194 => _194.paths, 'optionalAccess', _195 => _195.some, 'call', _196 => _196((p) => isGradient(p.color_rgb))]), () => ( false)));
|
|
7552
7579
|
}
|
|
7553
7580
|
/** Clear cached baked canvas and hit-test polylines. */
|
|
7554
7581
|
invalidateCache() {
|
package/dist/index.mjs
CHANGED
|
@@ -468,6 +468,21 @@ function rebaseChildBox(parent, parentOriginX, parentOriginY, child, childOrigin
|
|
|
468
468
|
return REBASED_BOX;
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
+
// src/tree/scene/content-break-carrier.ts
|
|
472
|
+
var HARD_BREAK_ONLY = /^[\r\n]+$/;
|
|
473
|
+
function appendContentBreak(owner, breakText) {
|
|
474
|
+
if (!breakText) return;
|
|
475
|
+
if (!HARD_BREAK_ONLY.test(breakText)) {
|
|
476
|
+
owner.appendChild(document.createTextNode(breakText));
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
const span = document.createElement("span");
|
|
480
|
+
span.textContent = breakText;
|
|
481
|
+
span.style.fontSize = "0";
|
|
482
|
+
span.style.lineHeight = "0";
|
|
483
|
+
owner.appendChild(span);
|
|
484
|
+
}
|
|
485
|
+
|
|
471
486
|
// src/tree/scene/content-line-window.ts
|
|
472
487
|
function projectionLineWindow(lines, band, fallbackLineHeight) {
|
|
473
488
|
const all = {
|
|
@@ -528,7 +543,8 @@ var ContentGridProjector = class {
|
|
|
528
543
|
throw new Error("ContentProjection.grid.source must equal ContentProjection.text");
|
|
529
544
|
}
|
|
530
545
|
const gridWindow = projectionGridLineWindow(grid, projection.lines, lineBand);
|
|
531
|
-
const
|
|
546
|
+
const originSignature = projection.lines?.find((line) => line !== void 0)?.x ?? 0;
|
|
547
|
+
const signature = gridWindow.gated ? `${grid.revision}:${gridWindow.start}-${gridWindow.end}:${originSignature}` : `${grid.revision}:${originSignature}`;
|
|
532
548
|
if (el.dataset.vectoContentGrid !== signature) {
|
|
533
549
|
const materializeStart = typeof performance !== "undefined" ? performance.now() : 0;
|
|
534
550
|
this.contentProjection.clearGridState(entityId, el, false);
|
|
@@ -588,17 +604,17 @@ var ContentGridProjector = class {
|
|
|
588
604
|
lineElement.style.whiteSpace = "pre";
|
|
589
605
|
lineElement.style.font = lineFont;
|
|
590
606
|
lineElement.style.lineHeight = `${lineHeight}px`;
|
|
607
|
+
const breakText = grid.source.slice(gridLine.sourceEnd, gridLine.nextSourceStart);
|
|
591
608
|
if (gridLine.cells.length === 0) {
|
|
592
|
-
lineElement
|
|
609
|
+
appendContentBreak(lineElement, breakText);
|
|
593
610
|
} else {
|
|
594
611
|
let logicalX = 0;
|
|
595
612
|
for (let cellIndex = 0; cellIndex < gridLine.cells.length; cellIndex++) {
|
|
596
613
|
const cell = gridLine.cells[cellIndex];
|
|
597
614
|
const cellElement = document.createElement("span");
|
|
598
615
|
cellElement.dir = "ltr";
|
|
599
|
-
const separator = cellIndex === gridLine.cells.length - 1 ? grid.source.slice(gridLine.sourceEnd, gridLine.nextSourceStart) : "";
|
|
600
616
|
const sourceText = grid.source.slice(cell.sourceStart, cell.sourceEnd);
|
|
601
|
-
cellElement.textContent = sourceText
|
|
617
|
+
cellElement.textContent = sourceText;
|
|
602
618
|
cellElement.dataset.vectoGridCell = `${cellIndex}`;
|
|
603
619
|
cellElement.dataset.vectoGridSourceLength = `${sourceText.length}`;
|
|
604
620
|
cellElement.dataset.vectoGridSourceStart = `${cell.sourceStart}`;
|
|
@@ -624,6 +640,7 @@ var ContentGridProjector = class {
|
|
|
624
640
|
lineElement.appendChild(cellElement);
|
|
625
641
|
logicalX += cell.advance;
|
|
626
642
|
}
|
|
643
|
+
appendContentBreak(lineElement, breakText);
|
|
627
644
|
}
|
|
628
645
|
if (lineIndex === 0) {
|
|
629
646
|
for (const [basis, left, top] of [
|
|
@@ -1036,12 +1053,14 @@ var CanvasGeometry = class {
|
|
|
1036
1053
|
const parentRect = parent.getBoundingClientRect?.();
|
|
1037
1054
|
const cssWidth = canvasRect?.width || this.canvas.clientWidth || width;
|
|
1038
1055
|
const cssHeight = canvasRect?.height || this.canvas.clientHeight || height;
|
|
1039
|
-
const
|
|
1040
|
-
const
|
|
1056
|
+
const canvasPosition = typeof getComputedStyle === "function" ? getComputedStyle(this.canvas).position : "";
|
|
1057
|
+
const position = canvasPosition === "fixed" ? "fixed" : "absolute";
|
|
1058
|
+
const left = position === "fixed" ? canvasRect?.left ?? 0 : (canvasRect?.left ?? 0) - (parentRect?.left ?? 0) - (parent.clientLeft || 0) + parent.scrollLeft;
|
|
1059
|
+
const top = position === "fixed" ? canvasRect?.top ?? 0 : (canvasRect?.top ?? 0) - (parentRect?.top ?? 0) - (parent.clientTop || 0) + parent.scrollTop;
|
|
1041
1060
|
const scaleX = width > 0 ? cssWidth / width : 1;
|
|
1042
1061
|
const scaleY = height > 0 ? cssHeight / height : 1;
|
|
1043
1062
|
const prev = this.overlayGeometry;
|
|
1044
|
-
if (prev !== null && prev.left === left && prev.top === top && prev.cssWidth === cssWidth && prev.cssHeight === cssHeight && prev.width === width && prev.height === height) {
|
|
1063
|
+
if (prev !== null && prev.left === left && prev.top === top && prev.cssWidth === cssWidth && prev.cssHeight === cssHeight && prev.width === width && prev.height === height && prev.position === position) {
|
|
1045
1064
|
return;
|
|
1046
1065
|
}
|
|
1047
1066
|
this.overlayGeometry = {
|
|
@@ -1050,10 +1069,12 @@ var CanvasGeometry = class {
|
|
|
1050
1069
|
cssWidth,
|
|
1051
1070
|
cssHeight,
|
|
1052
1071
|
width,
|
|
1053
|
-
height
|
|
1072
|
+
height,
|
|
1073
|
+
position
|
|
1054
1074
|
};
|
|
1055
1075
|
for (const root of [this.a11yRoot, this.portalRoot]) {
|
|
1056
1076
|
if (!root) continue;
|
|
1077
|
+
root.style.position = position;
|
|
1057
1078
|
root.style.left = `${left}px`;
|
|
1058
1079
|
root.style.top = `${top}px`;
|
|
1059
1080
|
root.style.width = `${width}px`;
|
|
@@ -1063,6 +1084,7 @@ var CanvasGeometry = class {
|
|
|
1063
1084
|
}
|
|
1064
1085
|
for (const canvas of [glCanvas, gpuCanvas]) {
|
|
1065
1086
|
if (!canvas) continue;
|
|
1087
|
+
canvas.style.position = position;
|
|
1066
1088
|
canvas.style.left = `${left}px`;
|
|
1067
1089
|
canvas.style.top = `${top}px`;
|
|
1068
1090
|
canvas.style.width = `${cssWidth}px`;
|
|
@@ -1664,6 +1686,7 @@ var HitTester = class {
|
|
|
1664
1686
|
};
|
|
1665
1687
|
|
|
1666
1688
|
// src/tree/scene/ContentProjectionManager.ts
|
|
1689
|
+
var PAGE_SCALE_BASIS_PX = 256;
|
|
1667
1690
|
var ContentProjectionManager = class {
|
|
1668
1691
|
/**
|
|
1669
1692
|
* `a11yRoot` doubles as the projection root: carriers are appended to it, and
|
|
@@ -2046,7 +2069,7 @@ var ContentProjectionManager = class {
|
|
|
2046
2069
|
probeOrigin.style.top = "0";
|
|
2047
2070
|
const probeX = document.createElement("span");
|
|
2048
2071
|
probeX.style.position = "absolute";
|
|
2049
|
-
probeX.style.left =
|
|
2072
|
+
probeX.style.left = `${PAGE_SCALE_BASIS_PX}px`;
|
|
2050
2073
|
probeX.style.top = "0";
|
|
2051
2074
|
probe.append(probeOrigin, probeX);
|
|
2052
2075
|
const measurements = [];
|
|
@@ -2119,7 +2142,7 @@ var ContentProjectionManager = class {
|
|
|
2119
2142
|
const updates = [];
|
|
2120
2143
|
const probeOriginRect = probeOrigin.getBoundingClientRect();
|
|
2121
2144
|
const probeXRect = probeX.getBoundingClientRect();
|
|
2122
|
-
const basisScale = Math.abs(probeXRect.left - probeOriginRect.left);
|
|
2145
|
+
const basisScale = Math.abs(probeXRect.left - probeOriginRect.left) / PAGE_SCALE_BASIS_PX;
|
|
2123
2146
|
const projectionPageScaleX = Number.isFinite(basisScale) && basisScale > 0 ? basisScale : pageScaleX;
|
|
2124
2147
|
let valid = true;
|
|
2125
2148
|
for (const measurement of measurements) {
|
|
@@ -6266,7 +6289,7 @@ var Scene = class _Scene {
|
|
|
6266
6289
|
for (let runIndex = 0; runIndex < line.runs.length; runIndex++) {
|
|
6267
6290
|
const run = line.runs[runIndex];
|
|
6268
6291
|
const runElement = document.createElement("span");
|
|
6269
|
-
runElement.textContent = run.text
|
|
6292
|
+
runElement.textContent = run.text;
|
|
6270
6293
|
if (run.font) runElement.style.font = run.font;
|
|
6271
6294
|
runElement.style.lineHeight = `${lineHeight2}px`;
|
|
6272
6295
|
if (positioned && run.x !== void 0) {
|
|
@@ -6282,8 +6305,9 @@ var Scene = class _Scene {
|
|
|
6282
6305
|
lineElement.appendChild(runElement);
|
|
6283
6306
|
}
|
|
6284
6307
|
} else {
|
|
6285
|
-
lineElement.textContent = line.text
|
|
6308
|
+
lineElement.textContent = line.text;
|
|
6286
6309
|
}
|
|
6310
|
+
appendContentBreak(lineElement, separator);
|
|
6287
6311
|
el.appendChild(lineElement);
|
|
6288
6312
|
}
|
|
6289
6313
|
});
|
|
@@ -6334,6 +6358,9 @@ var Scene = class _Scene {
|
|
|
6334
6358
|
if (node.width > 0) el.style.width = `${node.width}px`;
|
|
6335
6359
|
if (node.height > 0) el.style.height = `${node.height}px`;
|
|
6336
6360
|
el.style.transform = `matrix(${a}, ${b}, ${c}, ${d}, 0, 0)`;
|
|
6361
|
+
const clipToBounds = projection.clipToBounds === true;
|
|
6362
|
+
const clipPath = clipToBounds && node.width > 0 && node.height > 0 ? `inset(${-localY}px ${contentX}px ${localY}px ${-contentX}px)` : "";
|
|
6363
|
+
if (el.style.clipPath !== clipPath) el.style.clipPath = clipPath;
|
|
6337
6364
|
const residentTier = semanticMargin > interactionMargin;
|
|
6338
6365
|
const display = visible || residentTier && !this.projectionBoxVisible(node, worldTf, 0, true) ? "" : "none";
|
|
6339
6366
|
if (el.style.display !== display) el.style.display = display;
|
package/dist/tree/Entity.d.ts
CHANGED
|
@@ -178,6 +178,20 @@ export interface ContentProjection {
|
|
|
178
178
|
* shaping, and bidi boundaries cannot drift between the two surfaces.
|
|
179
179
|
*/
|
|
180
180
|
grid?: PreparedContentGrid;
|
|
181
|
+
/**
|
|
182
|
+
* Confine the projected text's paint to the projection element's own box.
|
|
183
|
+
*
|
|
184
|
+
* Opt in when the entity's `render()` clips its own drawing, so the two
|
|
185
|
+
* surfaces agree on where the content ends. Without it the canvas clips and
|
|
186
|
+
* the DOM copy does not, and a selection highlight over content wider than
|
|
187
|
+
* the box paints past the entity onto whatever is drawn beside it — the
|
|
188
|
+
* defect a horizontally scrollable code block exhibits.
|
|
189
|
+
*
|
|
190
|
+
* Off by default, because the projection element is deliberately unclipped:
|
|
191
|
+
* `Scene` relies on that so selection can start in an entity's blank/padding
|
|
192
|
+
* regions and extend beyond its bounds.
|
|
193
|
+
*/
|
|
194
|
+
clipToBounds?: boolean;
|
|
181
195
|
}
|
|
182
196
|
/** Typography for a native input projected by the accessibility layer. */
|
|
183
197
|
export interface TextInputStyle {
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
*
|
|
17
17
|
* - {@link clientToScene} — browser viewport coordinates to logical ones.
|
|
18
18
|
* - {@link syncOverlay} — keeps the a11y, portal, WebGL and WebGPU layers
|
|
19
|
-
* aligned with the canvas box, including the
|
|
20
|
-
*
|
|
19
|
+
* aligned with the canvas box, including the `position` that layers share with
|
|
20
|
+
* the canvas so a scroll needs no JS compensation, and the memo that makes an
|
|
21
|
+
* unchanged frame write nothing.
|
|
21
22
|
* - {@link effectiveDPR} and {@link sizeGpuCanvas} — the DPR clamp and the
|
|
22
23
|
* backing-store sizing that follows from it.
|
|
23
24
|
*
|
|
@@ -74,6 +75,16 @@ export interface OverlayGeometry {
|
|
|
74
75
|
cssHeight: number;
|
|
75
76
|
width: number;
|
|
76
77
|
height: number;
|
|
78
|
+
/**
|
|
79
|
+
* `position` written to the overlay layers, mirroring the canvas's own.
|
|
80
|
+
*
|
|
81
|
+
* Part of the memo because it is part of the written state: a canvas that
|
|
82
|
+
* becomes `fixed` after the first sync (a scroll-driven CSS class, a
|
|
83
|
+
* full-screen toggle) changes nothing else in here — same box, same logical
|
|
84
|
+
* size — so without this the memo would short-circuit and leave the overlay
|
|
85
|
+
* positioned the old way.
|
|
86
|
+
*/
|
|
87
|
+
position: 'absolute' | 'fixed';
|
|
77
88
|
}
|
|
78
89
|
export declare class CanvasGeometry {
|
|
79
90
|
private readonly canvas;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a projected line carries its trailing hard break.
|
|
3
|
+
*
|
|
4
|
+
* A projected line must hold its own line break in the DOM: copy, find-in-page
|
|
5
|
+
* and screen readers all read the projection, and a block whose lines are
|
|
6
|
+
* separate absolutely-positioned carriers has no flow structure a browser could
|
|
7
|
+
* synthesize a newline from. So the break character is written out explicitly.
|
|
8
|
+
*
|
|
9
|
+
* Writing it as an ordinary inline character is what this module exists to stop.
|
|
10
|
+
* The carriers are `white-space: pre`, so a trailing `\n` is a real preserved
|
|
11
|
+
* character in an inline context, and a browser gives it a selection rectangle
|
|
12
|
+
* of **zero width and full line height** at the end of the line. Chrome paints
|
|
13
|
+
* that rectangle, so selecting a line drew a caret-like vertical bar just past
|
|
14
|
+
* the last glyph — ink the canvas never drew, at a position no glyph occupies.
|
|
15
|
+
*
|
|
16
|
+
* Measured in real headed Chrome (DPR 1.76) on a live page, selecting one
|
|
17
|
+
* paragraph line of `1. 极致的性能与定制化:\n`: four selection rects, the last
|
|
18
|
+
* `x 495.18, w 0, h 31.82`. The same line with the break character removed
|
|
19
|
+
* produced one rect and no bar. Both projection paths were affected — a
|
|
20
|
+
* `CodeBlock` fixture reported one such rect on every line that owned a break
|
|
21
|
+
* (3 of 4 rows, including the empty row whose entire content is the break).
|
|
22
|
+
*
|
|
23
|
+
* ## Why the character stays in the DOM
|
|
24
|
+
*
|
|
25
|
+
* Deleting it fixes the bar and breaks copy: measured on the same page,
|
|
26
|
+
* stripping the trailing `\n` from every line of a block made
|
|
27
|
+
* `getSelection().toString()` return the block as one unbroken run. The break
|
|
28
|
+
* has to remain selectable text; it merely must not paint.
|
|
29
|
+
*
|
|
30
|
+
* `font-size: 0` is what separates those two. A zero font size leaves the
|
|
31
|
+
* character in the text content and in the selected string, while collapsing the
|
|
32
|
+
* line box it would otherwise contribute — measured on the same block, the
|
|
33
|
+
* zero-width full-height rect became `w 0, h 0` and the selected string still
|
|
34
|
+
* ended in `\n`.
|
|
35
|
+
*
|
|
36
|
+
* Rejected alternatives, each measured on the same live block:
|
|
37
|
+
*
|
|
38
|
+
* - **An absolutely positioned zero-size box** (`position: absolute; width: 0;
|
|
39
|
+
* height: 0; overflow: hidden`) still produced the full-height rect, *and*
|
|
40
|
+
* dropped the newline from the selected string — out of flow, the break no
|
|
41
|
+
* longer serialises. Worse on both counts.
|
|
42
|
+
* - **Removing the character** and relying on the carriers' own box structure.
|
|
43
|
+
* The line carriers do compute to `display: block`, so it is a reasonable
|
|
44
|
+
* guess that the browser would synthesize the break — it does not. Copy came
|
|
45
|
+
* back unbroken (see above).
|
|
46
|
+
*
|
|
47
|
+
* ## Why a shared module
|
|
48
|
+
*
|
|
49
|
+
* Both projection branches own break text and both had the defect:
|
|
50
|
+
* `Scene.syncContentProjection`'s carrier branch (plain and positioned-run
|
|
51
|
+
* lines) and {@link ContentGridProjector.syncGrid} (the last cell of a line, and
|
|
52
|
+
* an empty line's whole content). This follows the `content-line-window`
|
|
53
|
+
* precedent — a stateless helper both sides of the grid cut call, rather than a
|
|
54
|
+
* member on either — so the two cannot drift into disagreeing about how a break
|
|
55
|
+
* is represented, which would make copy fidelity depend on which branch drew a
|
|
56
|
+
* given block.
|
|
57
|
+
*
|
|
58
|
+
* Stateless by design: no `Scene`, no entities, no state beyond the node passed
|
|
59
|
+
* in.
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* Append `breakText` to `owner`, suppressing its paint only if it is a hard
|
|
63
|
+
* break.
|
|
64
|
+
*
|
|
65
|
+
* A no-op for empty text, so callers can pass a separator that may legitimately
|
|
66
|
+
* be absent (the document's last line owns no break) without branching.
|
|
67
|
+
*
|
|
68
|
+
* A hard break goes into a `font-size: 0` span: still selectable, copyable and
|
|
69
|
+
* announced, but contributing no line box. Any other separator — a soft-wrap
|
|
70
|
+
* space — is appended as a plain text node, because its width is part of the
|
|
71
|
+
* line the canvas drew.
|
|
72
|
+
*
|
|
73
|
+
* The span is deliberately **not** `aria-hidden` and does **not** set
|
|
74
|
+
* `user-select: none`: the break is real content that a screen reader and a copy
|
|
75
|
+
* both want. Only its painted geometry is suppressed.
|
|
76
|
+
*/
|
|
77
|
+
export declare function appendContentBreak(owner: Node, breakText: string): void;
|