@vectojs/markdown 0.20.2 → 0.20.3
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 +118 -0
- package/dist/index.mjs +118 -0
- package/dist/markdown-code.d.ts +21 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1327,6 +1327,70 @@ function highlightLine(line, lang, theme, carry = null) {
|
|
|
1327
1327
|
flush(theme.codeColor);
|
|
1328
1328
|
return { segments, carry: null };
|
|
1329
1329
|
}
|
|
1330
|
+
var HSCROLL_HIT_H = 12;
|
|
1331
|
+
var HSCROLL_THUMB_H = 4;
|
|
1332
|
+
var HSCROLL_THUMB_INSET = 4;
|
|
1333
|
+
var HSCROLL_THUMB_MIN = 24;
|
|
1334
|
+
var HSCROLL_TRACK_COLOR = "rgba(128, 128, 128, 0.14)";
|
|
1335
|
+
var HSCROLL_THUMB_COLOR = "rgba(128, 128, 128, 0.45)";
|
|
1336
|
+
var HSCROLL_THUMB_ACTIVE_COLOR = "rgba(128, 128, 128, 0.75)";
|
|
1337
|
+
function hScrollMetrics(trackW, maxScrollX) {
|
|
1338
|
+
const content = trackW + maxScrollX;
|
|
1339
|
+
const proportional = content > 0 ? trackW / content * trackW : trackW;
|
|
1340
|
+
const thumbW = Math.min(trackW, Math.max(HSCROLL_THUMB_MIN, proportional));
|
|
1341
|
+
return { thumbW, range: Math.max(1, trackW - thumbW) };
|
|
1342
|
+
}
|
|
1343
|
+
var HScrollTrack = class extends import_ui.UIComponent {
|
|
1344
|
+
constructor(block) {
|
|
1345
|
+
super();
|
|
1346
|
+
this.block = block;
|
|
1347
|
+
this.on("pointerdown", (e) => {
|
|
1348
|
+
if (e.localX === void 0) return;
|
|
1349
|
+
const maxSX = this.block.maxScrollX;
|
|
1350
|
+
if (maxSX <= 0) return;
|
|
1351
|
+
const { thumbW, range } = hScrollMetrics(this.width, maxSX);
|
|
1352
|
+
const thumbX = this.block.scrollX / maxSX * range;
|
|
1353
|
+
if (e.localX < thumbX || e.localX > thumbX + thumbW) {
|
|
1354
|
+
this.block.setScrollX((e.localX - thumbW / 2) / range * maxSX);
|
|
1355
|
+
}
|
|
1356
|
+
this.dragging = true;
|
|
1357
|
+
this.dragAnchorX = e.localX;
|
|
1358
|
+
this.scrollAtDragStart = this.block.scrollX;
|
|
1359
|
+
this.scene?.markDirty();
|
|
1360
|
+
});
|
|
1361
|
+
this.on("pointermove", (e) => {
|
|
1362
|
+
if (!this.dragging || e.localX === void 0) return;
|
|
1363
|
+
const maxSX = this.block.maxScrollX;
|
|
1364
|
+
const { range } = hScrollMetrics(this.width, maxSX);
|
|
1365
|
+
const dx = e.localX - this.dragAnchorX;
|
|
1366
|
+
this.block.setScrollX(this.scrollAtDragStart + dx / range * maxSX);
|
|
1367
|
+
});
|
|
1368
|
+
const endDrag = () => {
|
|
1369
|
+
if (!this.dragging) return;
|
|
1370
|
+
this.dragging = false;
|
|
1371
|
+
this.scene?.markDirty();
|
|
1372
|
+
};
|
|
1373
|
+
this.on("pointerup", endDrag);
|
|
1374
|
+
this.on("pointerleave", endDrag);
|
|
1375
|
+
}
|
|
1376
|
+
block;
|
|
1377
|
+
/** True while a drag owns the thumb; read by the block's painter for the active tint. */
|
|
1378
|
+
dragging = false;
|
|
1379
|
+
dragAnchorX = 0;
|
|
1380
|
+
scrollAtDragStart = 0;
|
|
1381
|
+
getA11yAttributes() {
|
|
1382
|
+
return {
|
|
1383
|
+
role: "scrollbar",
|
|
1384
|
+
label: "Scroll code horizontally",
|
|
1385
|
+
value: String(Math.round(this.block.scrollX)),
|
|
1386
|
+
valuemin: "0",
|
|
1387
|
+
valuemax: String(Math.round(this.block.maxScrollX))
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
/** Nothing to draw: the thumb is painted by the owning block, so both share one pass. */
|
|
1391
|
+
render() {
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1330
1394
|
var CodeBlock = class extends import_ui.UIComponent {
|
|
1331
1395
|
lines;
|
|
1332
1396
|
/**
|
|
@@ -1364,6 +1428,12 @@ var CodeBlock = class extends import_ui.UIComponent {
|
|
|
1364
1428
|
/** Memoized widest prepared line, keyed by the grid identity it came from. */
|
|
1365
1429
|
contentWidthGrid = null;
|
|
1366
1430
|
contentWidthValue = 0;
|
|
1431
|
+
/**
|
|
1432
|
+
* The interactive horizontal scrollbar strip (#527), created lazily by
|
|
1433
|
+
* {@link syncScrollTrack} the first time the block overflows. Kept, and merely
|
|
1434
|
+
* disabled, when the overflow later disappears — see there for why.
|
|
1435
|
+
*/
|
|
1436
|
+
hTrack = null;
|
|
1367
1437
|
lang;
|
|
1368
1438
|
theme;
|
|
1369
1439
|
/**
|
|
@@ -1668,6 +1738,31 @@ var CodeBlock = class extends import_ui.UIComponent {
|
|
|
1668
1738
|
}
|
|
1669
1739
|
return this.grid;
|
|
1670
1740
|
}
|
|
1741
|
+
/**
|
|
1742
|
+
* Fit the interactive scrollbar strip (#527) to the current overflow.
|
|
1743
|
+
*
|
|
1744
|
+
* Called from {@link render} rather than from `setWidth` or `buildLines`:
|
|
1745
|
+
* `setWidth` is documented as costing nothing and `maxScrollX` costs a grid
|
|
1746
|
+
* build, while `render` is about to pay for that grid anyway. Once created,
|
|
1747
|
+
* the child is KEPT and merely de-`interactive`d when the overflow disappears
|
|
1748
|
+
* — this runs inside the scene's tree walk, and removing a child mid-walk is
|
|
1749
|
+
* how siblings get skipped.
|
|
1750
|
+
*/
|
|
1751
|
+
syncScrollTrack() {
|
|
1752
|
+
if (this.maxScrollX <= 0) {
|
|
1753
|
+
if (this.hTrack) this.hTrack.interactive = false;
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1756
|
+
if (!this.hTrack) {
|
|
1757
|
+
this.hTrack = new HScrollTrack(this);
|
|
1758
|
+
this.add(this.hTrack);
|
|
1759
|
+
}
|
|
1760
|
+
this.hTrack.interactive = true;
|
|
1761
|
+
this.hTrack.x = this.pad;
|
|
1762
|
+
this.hTrack.y = this.height - HSCROLL_HIT_H;
|
|
1763
|
+
this.hTrack.width = Math.max(0, this.width - this.pad * 2);
|
|
1764
|
+
this.hTrack.height = HSCROLL_HIT_H;
|
|
1765
|
+
}
|
|
1671
1766
|
/**
|
|
1672
1767
|
* Not hit-testable, and deliberately still not `interactive`, even though the
|
|
1673
1768
|
* block now consumes wheel events to scroll.
|
|
@@ -1676,11 +1771,16 @@ var CodeBlock = class extends import_ui.UIComponent {
|
|
|
1676
1771
|
* hit-testing, so no a11y shadow node is needed. Creating one would place a
|
|
1677
1772
|
* `pointer-events: auto` element above the transparent text mirror and swallow
|
|
1678
1773
|
* the mousedown that starts a native drag-selection.
|
|
1774
|
+
*
|
|
1775
|
+
* Pointer-driven scrolling therefore lives on the {@link HScrollTrack} CHILD,
|
|
1776
|
+
* whose shadow node covers only the bottom-padding strip below the last
|
|
1777
|
+
* selectable carrier — never the text itself.
|
|
1679
1778
|
*/
|
|
1680
1779
|
isPointInside() {
|
|
1681
1780
|
return false;
|
|
1682
1781
|
}
|
|
1683
1782
|
render(r) {
|
|
1783
|
+
this.syncScrollTrack();
|
|
1684
1784
|
r.beginPath();
|
|
1685
1785
|
r.roundRect(0, 0, this.width, this.height, this.theme.codeRadius);
|
|
1686
1786
|
r.fill(this.theme.codeBgColor);
|
|
@@ -1750,6 +1850,24 @@ var CodeBlock = class extends import_ui.UIComponent {
|
|
|
1750
1850
|
}
|
|
1751
1851
|
}
|
|
1752
1852
|
r.restore();
|
|
1853
|
+
const maxSX = this.maxScrollX;
|
|
1854
|
+
if (maxSX > 0) {
|
|
1855
|
+
const trackW = Math.max(0, this.width - this.pad * 2);
|
|
1856
|
+
const { thumbW, range } = hScrollMetrics(trackW, maxSX);
|
|
1857
|
+
const trackY = this.height - HSCROLL_THUMB_H - HSCROLL_THUMB_INSET;
|
|
1858
|
+
r.beginPath();
|
|
1859
|
+
r.roundRect(this.pad, trackY, trackW, HSCROLL_THUMB_H, HSCROLL_THUMB_H / 2);
|
|
1860
|
+
r.fill(HSCROLL_TRACK_COLOR);
|
|
1861
|
+
r.beginPath();
|
|
1862
|
+
r.roundRect(
|
|
1863
|
+
this.pad + this.scrollX / maxSX * range,
|
|
1864
|
+
trackY,
|
|
1865
|
+
thumbW,
|
|
1866
|
+
HSCROLL_THUMB_H,
|
|
1867
|
+
HSCROLL_THUMB_H / 2
|
|
1868
|
+
);
|
|
1869
|
+
r.fill(this.hTrack?.dragging ? HSCROLL_THUMB_ACTIVE_COLOR : HSCROLL_THUMB_COLOR);
|
|
1870
|
+
}
|
|
1753
1871
|
}
|
|
1754
1872
|
};
|
|
1755
1873
|
var codeAtlases = /* @__PURE__ */ new Map();
|
package/dist/index.mjs
CHANGED
|
@@ -1273,6 +1273,70 @@ function highlightLine(line, lang, theme, carry = null) {
|
|
|
1273
1273
|
flush(theme.codeColor);
|
|
1274
1274
|
return { segments, carry: null };
|
|
1275
1275
|
}
|
|
1276
|
+
var HSCROLL_HIT_H = 12;
|
|
1277
|
+
var HSCROLL_THUMB_H = 4;
|
|
1278
|
+
var HSCROLL_THUMB_INSET = 4;
|
|
1279
|
+
var HSCROLL_THUMB_MIN = 24;
|
|
1280
|
+
var HSCROLL_TRACK_COLOR = "rgba(128, 128, 128, 0.14)";
|
|
1281
|
+
var HSCROLL_THUMB_COLOR = "rgba(128, 128, 128, 0.45)";
|
|
1282
|
+
var HSCROLL_THUMB_ACTIVE_COLOR = "rgba(128, 128, 128, 0.75)";
|
|
1283
|
+
function hScrollMetrics(trackW, maxScrollX) {
|
|
1284
|
+
const content = trackW + maxScrollX;
|
|
1285
|
+
const proportional = content > 0 ? trackW / content * trackW : trackW;
|
|
1286
|
+
const thumbW = Math.min(trackW, Math.max(HSCROLL_THUMB_MIN, proportional));
|
|
1287
|
+
return { thumbW, range: Math.max(1, trackW - thumbW) };
|
|
1288
|
+
}
|
|
1289
|
+
var HScrollTrack = class extends UIComponent {
|
|
1290
|
+
constructor(block) {
|
|
1291
|
+
super();
|
|
1292
|
+
this.block = block;
|
|
1293
|
+
this.on("pointerdown", (e) => {
|
|
1294
|
+
if (e.localX === void 0) return;
|
|
1295
|
+
const maxSX = this.block.maxScrollX;
|
|
1296
|
+
if (maxSX <= 0) return;
|
|
1297
|
+
const { thumbW, range } = hScrollMetrics(this.width, maxSX);
|
|
1298
|
+
const thumbX = this.block.scrollX / maxSX * range;
|
|
1299
|
+
if (e.localX < thumbX || e.localX > thumbX + thumbW) {
|
|
1300
|
+
this.block.setScrollX((e.localX - thumbW / 2) / range * maxSX);
|
|
1301
|
+
}
|
|
1302
|
+
this.dragging = true;
|
|
1303
|
+
this.dragAnchorX = e.localX;
|
|
1304
|
+
this.scrollAtDragStart = this.block.scrollX;
|
|
1305
|
+
this.scene?.markDirty();
|
|
1306
|
+
});
|
|
1307
|
+
this.on("pointermove", (e) => {
|
|
1308
|
+
if (!this.dragging || e.localX === void 0) return;
|
|
1309
|
+
const maxSX = this.block.maxScrollX;
|
|
1310
|
+
const { range } = hScrollMetrics(this.width, maxSX);
|
|
1311
|
+
const dx = e.localX - this.dragAnchorX;
|
|
1312
|
+
this.block.setScrollX(this.scrollAtDragStart + dx / range * maxSX);
|
|
1313
|
+
});
|
|
1314
|
+
const endDrag = () => {
|
|
1315
|
+
if (!this.dragging) return;
|
|
1316
|
+
this.dragging = false;
|
|
1317
|
+
this.scene?.markDirty();
|
|
1318
|
+
};
|
|
1319
|
+
this.on("pointerup", endDrag);
|
|
1320
|
+
this.on("pointerleave", endDrag);
|
|
1321
|
+
}
|
|
1322
|
+
block;
|
|
1323
|
+
/** True while a drag owns the thumb; read by the block's painter for the active tint. */
|
|
1324
|
+
dragging = false;
|
|
1325
|
+
dragAnchorX = 0;
|
|
1326
|
+
scrollAtDragStart = 0;
|
|
1327
|
+
getA11yAttributes() {
|
|
1328
|
+
return {
|
|
1329
|
+
role: "scrollbar",
|
|
1330
|
+
label: "Scroll code horizontally",
|
|
1331
|
+
value: String(Math.round(this.block.scrollX)),
|
|
1332
|
+
valuemin: "0",
|
|
1333
|
+
valuemax: String(Math.round(this.block.maxScrollX))
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
/** Nothing to draw: the thumb is painted by the owning block, so both share one pass. */
|
|
1337
|
+
render() {
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1276
1340
|
var CodeBlock = class extends UIComponent {
|
|
1277
1341
|
lines;
|
|
1278
1342
|
/**
|
|
@@ -1310,6 +1374,12 @@ var CodeBlock = class extends UIComponent {
|
|
|
1310
1374
|
/** Memoized widest prepared line, keyed by the grid identity it came from. */
|
|
1311
1375
|
contentWidthGrid = null;
|
|
1312
1376
|
contentWidthValue = 0;
|
|
1377
|
+
/**
|
|
1378
|
+
* The interactive horizontal scrollbar strip (#527), created lazily by
|
|
1379
|
+
* {@link syncScrollTrack} the first time the block overflows. Kept, and merely
|
|
1380
|
+
* disabled, when the overflow later disappears — see there for why.
|
|
1381
|
+
*/
|
|
1382
|
+
hTrack = null;
|
|
1313
1383
|
lang;
|
|
1314
1384
|
theme;
|
|
1315
1385
|
/**
|
|
@@ -1614,6 +1684,31 @@ var CodeBlock = class extends UIComponent {
|
|
|
1614
1684
|
}
|
|
1615
1685
|
return this.grid;
|
|
1616
1686
|
}
|
|
1687
|
+
/**
|
|
1688
|
+
* Fit the interactive scrollbar strip (#527) to the current overflow.
|
|
1689
|
+
*
|
|
1690
|
+
* Called from {@link render} rather than from `setWidth` or `buildLines`:
|
|
1691
|
+
* `setWidth` is documented as costing nothing and `maxScrollX` costs a grid
|
|
1692
|
+
* build, while `render` is about to pay for that grid anyway. Once created,
|
|
1693
|
+
* the child is KEPT and merely de-`interactive`d when the overflow disappears
|
|
1694
|
+
* — this runs inside the scene's tree walk, and removing a child mid-walk is
|
|
1695
|
+
* how siblings get skipped.
|
|
1696
|
+
*/
|
|
1697
|
+
syncScrollTrack() {
|
|
1698
|
+
if (this.maxScrollX <= 0) {
|
|
1699
|
+
if (this.hTrack) this.hTrack.interactive = false;
|
|
1700
|
+
return;
|
|
1701
|
+
}
|
|
1702
|
+
if (!this.hTrack) {
|
|
1703
|
+
this.hTrack = new HScrollTrack(this);
|
|
1704
|
+
this.add(this.hTrack);
|
|
1705
|
+
}
|
|
1706
|
+
this.hTrack.interactive = true;
|
|
1707
|
+
this.hTrack.x = this.pad;
|
|
1708
|
+
this.hTrack.y = this.height - HSCROLL_HIT_H;
|
|
1709
|
+
this.hTrack.width = Math.max(0, this.width - this.pad * 2);
|
|
1710
|
+
this.hTrack.height = HSCROLL_HIT_H;
|
|
1711
|
+
}
|
|
1617
1712
|
/**
|
|
1618
1713
|
* Not hit-testable, and deliberately still not `interactive`, even though the
|
|
1619
1714
|
* block now consumes wheel events to scroll.
|
|
@@ -1622,11 +1717,16 @@ var CodeBlock = class extends UIComponent {
|
|
|
1622
1717
|
* hit-testing, so no a11y shadow node is needed. Creating one would place a
|
|
1623
1718
|
* `pointer-events: auto` element above the transparent text mirror and swallow
|
|
1624
1719
|
* the mousedown that starts a native drag-selection.
|
|
1720
|
+
*
|
|
1721
|
+
* Pointer-driven scrolling therefore lives on the {@link HScrollTrack} CHILD,
|
|
1722
|
+
* whose shadow node covers only the bottom-padding strip below the last
|
|
1723
|
+
* selectable carrier — never the text itself.
|
|
1625
1724
|
*/
|
|
1626
1725
|
isPointInside() {
|
|
1627
1726
|
return false;
|
|
1628
1727
|
}
|
|
1629
1728
|
render(r) {
|
|
1729
|
+
this.syncScrollTrack();
|
|
1630
1730
|
r.beginPath();
|
|
1631
1731
|
r.roundRect(0, 0, this.width, this.height, this.theme.codeRadius);
|
|
1632
1732
|
r.fill(this.theme.codeBgColor);
|
|
@@ -1696,6 +1796,24 @@ var CodeBlock = class extends UIComponent {
|
|
|
1696
1796
|
}
|
|
1697
1797
|
}
|
|
1698
1798
|
r.restore();
|
|
1799
|
+
const maxSX = this.maxScrollX;
|
|
1800
|
+
if (maxSX > 0) {
|
|
1801
|
+
const trackW = Math.max(0, this.width - this.pad * 2);
|
|
1802
|
+
const { thumbW, range } = hScrollMetrics(trackW, maxSX);
|
|
1803
|
+
const trackY = this.height - HSCROLL_THUMB_H - HSCROLL_THUMB_INSET;
|
|
1804
|
+
r.beginPath();
|
|
1805
|
+
r.roundRect(this.pad, trackY, trackW, HSCROLL_THUMB_H, HSCROLL_THUMB_H / 2);
|
|
1806
|
+
r.fill(HSCROLL_TRACK_COLOR);
|
|
1807
|
+
r.beginPath();
|
|
1808
|
+
r.roundRect(
|
|
1809
|
+
this.pad + this.scrollX / maxSX * range,
|
|
1810
|
+
trackY,
|
|
1811
|
+
thumbW,
|
|
1812
|
+
HSCROLL_THUMB_H,
|
|
1813
|
+
HSCROLL_THUMB_H / 2
|
|
1814
|
+
);
|
|
1815
|
+
r.fill(this.hTrack?.dragging ? HSCROLL_THUMB_ACTIVE_COLOR : HSCROLL_THUMB_COLOR);
|
|
1816
|
+
}
|
|
1699
1817
|
}
|
|
1700
1818
|
};
|
|
1701
1819
|
var codeAtlases = /* @__PURE__ */ new Map();
|
package/dist/markdown-code.d.ts
CHANGED
|
@@ -71,6 +71,12 @@ export declare class CodeBlock extends UIComponent {
|
|
|
71
71
|
/** Memoized widest prepared line, keyed by the grid identity it came from. */
|
|
72
72
|
private contentWidthGrid;
|
|
73
73
|
private contentWidthValue;
|
|
74
|
+
/**
|
|
75
|
+
* The interactive horizontal scrollbar strip (#527), created lazily by
|
|
76
|
+
* {@link syncScrollTrack} the first time the block overflows. Kept, and merely
|
|
77
|
+
* disabled, when the overflow later disappears — see there for why.
|
|
78
|
+
*/
|
|
79
|
+
private hTrack;
|
|
74
80
|
private lang;
|
|
75
81
|
private theme;
|
|
76
82
|
/**
|
|
@@ -203,6 +209,17 @@ export declare class CodeBlock extends UIComponent {
|
|
|
203
209
|
*/
|
|
204
210
|
private buildLines;
|
|
205
211
|
private ensureGrid;
|
|
212
|
+
/**
|
|
213
|
+
* Fit the interactive scrollbar strip (#527) to the current overflow.
|
|
214
|
+
*
|
|
215
|
+
* Called from {@link render} rather than from `setWidth` or `buildLines`:
|
|
216
|
+
* `setWidth` is documented as costing nothing and `maxScrollX` costs a grid
|
|
217
|
+
* build, while `render` is about to pay for that grid anyway. Once created,
|
|
218
|
+
* the child is KEPT and merely de-`interactive`d when the overflow disappears
|
|
219
|
+
* — this runs inside the scene's tree walk, and removing a child mid-walk is
|
|
220
|
+
* how siblings get skipped.
|
|
221
|
+
*/
|
|
222
|
+
private syncScrollTrack;
|
|
206
223
|
/**
|
|
207
224
|
* Not hit-testable, and deliberately still not `interactive`, even though the
|
|
208
225
|
* block now consumes wheel events to scroll.
|
|
@@ -211,6 +228,10 @@ export declare class CodeBlock extends UIComponent {
|
|
|
211
228
|
* hit-testing, so no a11y shadow node is needed. Creating one would place a
|
|
212
229
|
* `pointer-events: auto` element above the transparent text mirror and swallow
|
|
213
230
|
* the mousedown that starts a native drag-selection.
|
|
231
|
+
*
|
|
232
|
+
* Pointer-driven scrolling therefore lives on the {@link HScrollTrack} CHILD,
|
|
233
|
+
* whose shadow node covers only the bottom-padding strip below the last
|
|
234
|
+
* selectable carrier — never the text itself.
|
|
214
235
|
*/
|
|
215
236
|
isPointInside(): boolean;
|
|
216
237
|
render(r: IRenderer): void;
|