@vectojs/core 1.7.1 → 1.9.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.
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2;
2
2
 
3
3
 
4
- var _chunkCTZQOM5Zjs = require('./chunk-CTZQOM5Z.js');
4
+ var _chunk4AR425ARjs = require('./chunk-4AR425AR.js');
5
5
 
6
6
  // src/layout/LayoutEngine.ts
7
7
  function computeLineSegments(top, bottom, maxWidth, exclusions) {
@@ -171,8 +171,8 @@ var LayoutEngine = (_class = class {
171
171
  offset += paragraph.length + 1;
172
172
  continue;
173
173
  }
174
- const { shapedText, indexMap } = _chunkCTZQOM5Zjs.ArabicShaper.shapeArabic(paragraph);
175
- const levels = _chunkCTZQOM5Zjs.BidiResolver.resolveLevels(shapedText);
174
+ const { shapedText, indexMap } = _chunk4AR425ARjs.ArabicShaper.shapeArabic(paragraph);
175
+ const levels = _chunk4AR425ARjs.BidiResolver.resolveLevels(shapedText);
176
176
  const words = [];
177
177
  let shapedCharIdx = 0;
178
178
  let pFallback = false;
@@ -234,7 +234,7 @@ var LayoutEngine = (_class = class {
234
234
  words,
235
235
  isEmpty: false,
236
236
  fallbackToCanvas: pFallback || void 0,
237
- baseLevel: _chunkCTZQOM5Zjs.BidiResolver.getBaseLevel(shapedText)
237
+ baseLevel: _chunk4AR425ARjs.BidiResolver.getBaseLevel(shapedText)
238
238
  };
239
239
  if (this.paragraphCache.size > 1e3) this.paragraphCache.clear();
240
240
  this.paragraphCache.set(key, prepared);
@@ -311,8 +311,8 @@ var LayoutEngine = (_class = class {
311
311
  offset += paragraph.length + 1;
312
312
  continue;
313
313
  }
314
- const { shapedText, indexMap } = _chunkCTZQOM5Zjs.ArabicShaper.shapeArabic(paragraph);
315
- const levels = _chunkCTZQOM5Zjs.BidiResolver.resolveLevels(shapedText);
314
+ const { shapedText, indexMap } = _chunk4AR425ARjs.ArabicShaper.shapeArabic(paragraph);
315
+ const levels = _chunk4AR425ARjs.BidiResolver.resolveLevels(shapedText);
316
316
  const words = [];
317
317
  let shapedCharIdx = 0;
318
318
  let pFallback = false;
@@ -377,7 +377,7 @@ var LayoutEngine = (_class = class {
377
377
  words,
378
378
  isEmpty: false,
379
379
  fallbackToCanvas: pFallback || void 0,
380
- baseLevel: _chunkCTZQOM5Zjs.BidiResolver.getBaseLevel(shapedText)
380
+ baseLevel: _chunk4AR425ARjs.BidiResolver.getBaseLevel(shapedText)
381
381
  };
382
382
  if (this.richParagraphCache.size > 1e3) this.richParagraphCache.clear();
383
383
  this.richParagraphCache.set(key, prepared);
@@ -432,7 +432,7 @@ var LayoutEngine = (_class = class {
432
432
  }
433
433
  for (const run of runs) {
434
434
  const runStartX = run[0].x;
435
- _chunkCTZQOM5Zjs.BidiResolver.reorderVisual(run, paragraphBaseLevel);
435
+ _chunk4AR425ARjs.BidiResolver.reorderVisual(run, paragraphBaseLevel);
436
436
  let x = runStartX;
437
437
  for (const node of run) {
438
438
  node.x = x;
@@ -1,6 +1,8 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7;
2
2
 
3
- var _chunkCTZQOM5Zjs = require('./chunk-CTZQOM5Z.js');
3
+
4
+
5
+ var _chunk4AR425ARjs = require('./chunk-4AR425AR.js');
4
6
 
5
7
  // src/math/SpringPhysics.ts
6
8
  var MAX_FRAME_DT = 0.25;
@@ -370,10 +372,18 @@ var Entity = (_class4 = class {
370
372
  * `child.parent` is only ever `null` or `this`'s ultimate owner, so this
371
373
  * check is O(1) for the overwhelming common case (a brand-new entity).
372
374
  *
373
- * @param child - The entity to add as a child.
375
+ * Accepts multiple children in one call (`parent.add(a, b, c)`); each is
376
+ * attached in argument order with the same detach-then-attach semantics.
377
+ *
378
+ * @param children - One or more entities to add as children.
374
379
  * @returns `this` for method chaining.
375
380
  */
376
- add(child) {
381
+ add(...children) {
382
+ for (const child of children) this._addOne(child);
383
+ return this;
384
+ }
385
+ /** Attach a single child (the O(1) common path). See {@link add}. */
386
+ _addOne(child) {
377
387
  if (child.parent) child.parent.remove(child);
378
388
  child.parent = this;
379
389
  this.children.push(child);
@@ -383,7 +393,6 @@ var Entity = (_class4 = class {
383
393
  s.markDirty();
384
394
  child._notifyMounted();
385
395
  }
386
- return this;
387
396
  }
388
397
  /** Called once when this entity becomes attached to a live Scene. Override to react. */
389
398
  onMounted() {
@@ -415,6 +424,24 @@ var Entity = (_class4 = class {
415
424
  }
416
425
  return this;
417
426
  }
427
+ /**
428
+ * Assign several own properties in one call, each through its normal setter
429
+ * (so a property with a configured {@link setTransition} still animates, and
430
+ * `interactive` still flags the scene for a11y reorder). A construction-time
431
+ * ergonomic only — it is a plain `for…in` over the given object and touches
432
+ * no per-frame path.
433
+ *
434
+ * @param props - Partial set of this entity's own properties to assign.
435
+ * @returns `this` for method chaining.
436
+ * @example rect.set({ x: 40, y: 40, width: 120, fill: '#38bdf8' });
437
+ */
438
+ set(props) {
439
+ for (const key in props) {
440
+ const value = props[key];
441
+ if (value !== void 0) this[key] = value;
442
+ }
443
+ return this;
444
+ }
418
445
  /**
419
446
  * Set the local position of this entity.
420
447
  *
@@ -1102,7 +1129,7 @@ var MSDFTextEntity = (_class6 = class extends Entity {
1102
1129
  this.queueLayout();
1103
1130
  }
1104
1131
  queueLayout() {
1105
- _chunkCTZQOM5Zjs.LayoutWorkerManager.getInstance().queueLayout(this.id, this.text, {
1132
+ _chunk4AR425ARjs.LayoutWorkerManager.getInstance().queueLayout(this.id, this.text, {
1106
1133
  fontId: this.font.id,
1107
1134
  fontSize: this.fontSize,
1108
1135
  maxWidth: this.maxWidth,
@@ -1219,7 +1246,7 @@ var MSDFTextEntity = (_class6 = class extends Entity {
1219
1246
  }
1220
1247
  }
1221
1248
  destroy() {
1222
- _chunkCTZQOM5Zjs.LayoutWorkerManager.getInstance().cancelLayout(this.id);
1249
+ _chunk4AR425ARjs.LayoutWorkerManager.getInstance().cancelLayout(this.id);
1223
1250
  super.destroy();
1224
1251
  }
1225
1252
  }, _class6);
@@ -1459,6 +1486,206 @@ var SVGEntity = (_class7 = class extends Entity {
1459
1486
  }
1460
1487
  }, _class7);
1461
1488
 
1489
+ // src/text/PreparedContentGrid.ts
1490
+ var nextRevision = 1;
1491
+ var graphemeSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
1492
+ var MARK = /\p{Mark}/u;
1493
+ var EXTENDED_PICTOGRAPHIC = /\p{Extended_Pictographic}/u;
1494
+ var REGIONAL_INDICATOR = /\p{Regional_Indicator}/u;
1495
+ var BIDI_CONTROL = /\p{Bidi_Control}/u;
1496
+ var EAST_ASIAN_WIDE = /[ᄀ-ᅟ⌚-⌛⏩-⏬⏰⏳◽-◾⺀-〾ぁ-㏿㐀-䶿一-鿿ꀀ-꓏가-힣豈-﫿︰-﹏＀-⦆¢-₩]/u;
1497
+ function codePointAt(text, index) {
1498
+ const point = text.codePointAt(index);
1499
+ if (point === void 0) return { value: "", next: index };
1500
+ const value = String.fromCodePoint(point);
1501
+ return { value, next: index + value.length };
1502
+ }
1503
+ function fallbackGraphemes(text) {
1504
+ const parts = [];
1505
+ let index = 0;
1506
+ while (index < text.length) {
1507
+ const start = index;
1508
+ let current = codePointAt(text, index);
1509
+ let segment = current.value;
1510
+ index = current.next;
1511
+ let regionalCount = REGIONAL_INDICATOR.test(segment) ? 1 : 0;
1512
+ while (index < text.length) {
1513
+ current = codePointAt(text, index);
1514
+ const point = _nullishCoalesce(current.value.codePointAt(0), () => ( 0));
1515
+ const isVariation = point >= 65024 && point <= 65039;
1516
+ const isEmojiModifier = point >= 127995 && point <= 127999;
1517
+ const isKeycap = point === 8419;
1518
+ if (MARK.test(current.value) || isVariation || isEmojiModifier || isKeycap) {
1519
+ segment += current.value;
1520
+ index = current.next;
1521
+ continue;
1522
+ }
1523
+ if (REGIONAL_INDICATOR.test(current.value) && regionalCount === 1) {
1524
+ segment += current.value;
1525
+ index = current.next;
1526
+ regionalCount++;
1527
+ continue;
1528
+ }
1529
+ if (point === 8205) {
1530
+ segment += current.value;
1531
+ index = current.next;
1532
+ if (index < text.length) {
1533
+ current = codePointAt(text, index);
1534
+ segment += current.value;
1535
+ index = current.next;
1536
+ }
1537
+ continue;
1538
+ }
1539
+ break;
1540
+ }
1541
+ parts.push({ segment, index: start });
1542
+ }
1543
+ return parts;
1544
+ }
1545
+ function graphemes(text) {
1546
+ if (!graphemeSegmenter) return fallbackGraphemes(text);
1547
+ return Array.from(graphemeSegmenter.segment(text), (part) => ({
1548
+ segment: part.segment,
1549
+ index: part.index
1550
+ }));
1551
+ }
1552
+ function lowerBound(values, target) {
1553
+ let low = 0;
1554
+ let high = values.length;
1555
+ while (low < high) {
1556
+ const middle = low + high >>> 1;
1557
+ if (values[middle] < target) low = middle + 1;
1558
+ else high = middle;
1559
+ }
1560
+ return low;
1561
+ }
1562
+ function isWideCluster(cluster) {
1563
+ if (EXTENDED_PICTOGRAPHIC.test(cluster) || REGIONAL_INDICATOR.test(cluster)) return true;
1564
+ if (cluster.includes("\u20E3")) return true;
1565
+ if (EAST_ASIAN_WIDE.test(cluster)) return true;
1566
+ const point = _nullishCoalesce(cluster.codePointAt(0), () => ( 0));
1567
+ return point >= 131072 && point <= 262141;
1568
+ }
1569
+ function sourceLines(source) {
1570
+ const lines = [];
1571
+ let start = 0;
1572
+ while (true) {
1573
+ let end = start;
1574
+ while (end < source.length && source[end] !== "\r" && source[end] !== "\n") end++;
1575
+ if (end === source.length) {
1576
+ lines.push({
1577
+ sourceStart: start,
1578
+ sourceEnd: end,
1579
+ nextSourceStart: end,
1580
+ text: source.slice(start)
1581
+ });
1582
+ break;
1583
+ }
1584
+ const next = source[end] === "\r" && source[end + 1] === "\n" ? end + 2 : end + 1;
1585
+ lines.push({
1586
+ sourceStart: start,
1587
+ sourceEnd: end,
1588
+ nextSourceStart: next,
1589
+ text: source.slice(start, end)
1590
+ });
1591
+ start = next;
1592
+ if (start === source.length) {
1593
+ lines.push({ sourceStart: start, sourceEnd: start, nextSourceStart: start, text: "" });
1594
+ break;
1595
+ }
1596
+ }
1597
+ return lines;
1598
+ }
1599
+ function assertPositiveFinite(value, name) {
1600
+ if (!Number.isFinite(value) || value <= 0) {
1601
+ throw new RangeError(`${name} must be a positive finite number`);
1602
+ }
1603
+ }
1604
+ function prepareContentGrid(source, options) {
1605
+ assertPositiveFinite(options.cellWidth, "cellWidth");
1606
+ assertPositiveFinite(options.lineHeight, "lineHeight");
1607
+ if (!Number.isFinite(options.baseline)) throw new RangeError("baseline must be finite");
1608
+ const tabSize = _nullishCoalesce(options.tabSize, () => ( 4));
1609
+ if (!Number.isInteger(tabSize) || tabSize <= 0) {
1610
+ throw new RangeError("tabSize must be a positive integer");
1611
+ }
1612
+ const rawLines = sourceLines(source);
1613
+ const lines = [];
1614
+ for (let lineIndex = 0; lineIndex < rawLines.length; lineIndex++) {
1615
+ const sourceLine = rawLines[lineIndex];
1616
+ const rawLine = sourceLine.text;
1617
+ const { sourceStart: lineStart, sourceEnd, nextSourceStart } = sourceLine;
1618
+ const rawCaretBoundaries = [
1619
+ 0,
1620
+ ...graphemes(rawLine).map((grapheme) => grapheme.index + grapheme.segment.length)
1621
+ ];
1622
+ const shaped = _chunk4AR425ARjs.ArabicShaper.shapeArabic(rawLine);
1623
+ const shapedParts = graphemes(shaped.shapedText);
1624
+ const levels = _chunk4AR425ARjs.BidiResolver.resolveLevels(shaped.shapedText);
1625
+ const cells = [];
1626
+ let column = 0;
1627
+ for (let index = 0; index < shapedParts.length; index++) {
1628
+ const part = shapedParts[index];
1629
+ const sourceOffset = _nullishCoalesce(shaped.indexMap[part.index], () => ( part.index));
1630
+ const nextPart = shapedParts[index + 1];
1631
+ const sourceOffsetEnd = nextPart ? _nullishCoalesce(shaped.indexMap[nextPart.index], () => ( nextPart.index)) : rawLine.length;
1632
+ const raw = rawLine.slice(sourceOffset, sourceOffsetEnd);
1633
+ const sourceCaretOffsets = [0];
1634
+ for (let caretIndex = lowerBound(rawCaretBoundaries, sourceOffset + 1); caretIndex < rawCaretBoundaries.length && rawCaretBoundaries[caretIndex] < sourceOffsetEnd; caretIndex++) {
1635
+ sourceCaretOffsets.push(rawCaretBoundaries[caretIndex] - sourceOffset);
1636
+ }
1637
+ if (sourceCaretOffsets.at(-1) !== sourceOffsetEnd - sourceOffset) {
1638
+ sourceCaretOffsets.push(sourceOffsetEnd - sourceOffset);
1639
+ }
1640
+ let columns;
1641
+ if (BIDI_CONTROL.test(raw)) columns = 0;
1642
+ else if (raw === " ") columns = tabSize - column % tabSize;
1643
+ else columns = isWideCluster(raw) ? 2 : 1;
1644
+ const advance = columns * options.cellWidth;
1645
+ cells.push({
1646
+ sourceStart: lineStart + sourceOffset,
1647
+ sourceEnd: lineStart + sourceOffsetEnd,
1648
+ sourceCaretOffsets: Object.freeze(sourceCaretOffsets),
1649
+ glyph: part.segment,
1650
+ x: 0,
1651
+ advance,
1652
+ level: _nullishCoalesce(levels[part.index], () => ( 0)),
1653
+ char: part.segment
1654
+ });
1655
+ column += columns;
1656
+ }
1657
+ const visualCells = [...cells];
1658
+ _chunk4AR425ARjs.BidiResolver.reorderVisual(visualCells, _chunk4AR425ARjs.BidiResolver.getBaseLevel(shaped.shapedText));
1659
+ let visualX = 0;
1660
+ for (const cell of visualCells) {
1661
+ cell.x = visualX;
1662
+ visualX += cell.advance;
1663
+ }
1664
+ const frozenCells = cells.map(({ char: _char, ...cell }) => Object.freeze(cell));
1665
+ lines.push(
1666
+ Object.freeze({
1667
+ sourceStart: lineStart,
1668
+ sourceEnd,
1669
+ nextSourceStart,
1670
+ width: visualX,
1671
+ cells: Object.freeze(frozenCells)
1672
+ })
1673
+ );
1674
+ }
1675
+ return Object.freeze({
1676
+ kind: "content-grid",
1677
+ revision: nextRevision++,
1678
+ source,
1679
+ font: options.font,
1680
+ cellWidth: options.cellWidth,
1681
+ lineHeight: options.lineHeight,
1682
+ baseline: options.baseline,
1683
+ tabSize,
1684
+ lines: Object.freeze(lines)
1685
+ });
1686
+ }
1687
+
1688
+
1462
1689
 
1463
1690
 
1464
1691
 
@@ -1472,4 +1699,4 @@ var SVGEntity = (_class7 = class extends Entity {
1472
1699
 
1473
1700
 
1474
1701
 
1475
- exports.SpringPhysics = SpringPhysics; exports.Easing = Easing; exports.isTweenConfig = isTweenConfig; exports.TweenDriver = TweenDriver; exports.SpringDriver = SpringDriver; exports.VectoJSEvent = VectoJSEvent; exports.Entity = Entity; exports.cssLineBoxBaseline = cssLineBoxBaseline; exports.clearCssLineBoxMetrics = clearCssLineBoxMetrics; exports.MSDFFont = MSDFFont; exports.MSDFTextEntity = MSDFTextEntity; exports.SVGEntity = SVGEntity;
1702
+ exports.SpringPhysics = SpringPhysics; exports.Easing = Easing; exports.isTweenConfig = isTweenConfig; exports.TweenDriver = TweenDriver; exports.SpringDriver = SpringDriver; exports.VectoJSEvent = VectoJSEvent; exports.Entity = Entity; exports.cssLineBoxBaseline = cssLineBoxBaseline; exports.clearCssLineBoxMetrics = clearCssLineBoxMetrics; exports.MSDFFont = MSDFFont; exports.MSDFTextEntity = MSDFTextEntity; exports.SVGEntity = SVGEntity; exports.prepareContentGrid = prepareContentGrid;