@vectojs/markdown 0.9.0 → 0.11.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,4 +1,4 @@
1
- import { Entity, type DevtoolsDescriptor, GlyphRasterAtlas, type GlyphRasterAtlasStats, IRenderer, type ContentProjection } from '@vectojs/core';
1
+ import { type ContentProjectionHint, Entity, type DevtoolsDescriptor, GlyphRasterAtlas, type GlyphRasterAtlasStats, IRenderer, type ContentProjection } from '@vectojs/core';
2
2
  import { type Token } from 'marked';
3
3
  import { type StreamController, type StreamControllerOptions } from './StreamController';
4
4
  import { Stack, UIComponent } from '@vectojs/ui';
@@ -45,6 +45,8 @@ export declare class CodeBlock extends UIComponent {
45
45
  private rawLines;
46
46
  private cellWidth;
47
47
  private source;
48
+ /** Bumped by {@link buildLines} and {@link setSelectable}; read by `Scene`. */
49
+ private contentEpoch;
48
50
  private lang;
49
51
  private theme;
50
52
  private lineH;
@@ -56,6 +58,7 @@ export declare class CodeBlock extends UIComponent {
56
58
  setCode(code: string, lang?: string): this;
57
59
  /** Enable or disable browser-native selection for this code block. */
58
60
  setSelectable(selectable: boolean): this;
61
+ getContentEpoch(): number;
59
62
  /**
60
63
  * Change the block's box width.
61
64
  *
@@ -69,7 +72,7 @@ export declare class CodeBlock extends UIComponent {
69
72
  * @returns `this` for chaining.
70
73
  */
71
74
  setWidth(width: number): this;
72
- getContentProjection(): ContentProjection | null;
75
+ getContentProjection(hint?: ContentProjectionHint): ContentProjection | null;
73
76
  /**
74
77
  * Re-highlight the code, reusing the highlight of any unchanged line prefix.
75
78
  *
package/dist/index.js CHANGED
@@ -1127,6 +1127,8 @@ var CodeBlock = class extends import_ui.UIComponent {
1127
1127
  rawLines = null;
1128
1128
  cellWidth = 0;
1129
1129
  source;
1130
+ /** Bumped by {@link buildLines} and {@link setSelectable}; read by `Scene`. */
1131
+ contentEpoch = 0;
1130
1132
  lang;
1131
1133
  theme;
1132
1134
  lineH = 24;
@@ -1155,9 +1157,13 @@ var CodeBlock = class extends import_ui.UIComponent {
1155
1157
  /** Enable or disable browser-native selection for this code block. */
1156
1158
  setSelectable(selectable) {
1157
1159
  this.selectable = selectable;
1160
+ this.contentEpoch++;
1158
1161
  this.scene?.markDirty();
1159
1162
  return this;
1160
1163
  }
1164
+ getContentEpoch() {
1165
+ return this.contentEpoch;
1166
+ }
1161
1167
  /**
1162
1168
  * Change the block's box width.
1163
1169
  *
@@ -1177,9 +1183,25 @@ var CodeBlock = class extends import_ui.UIComponent {
1177
1183
  this.scene?.markDirty();
1178
1184
  return this;
1179
1185
  }
1180
- getContentProjection() {
1186
+ getContentProjection(hint) {
1181
1187
  if (!this.source) return null;
1182
1188
  const grid = this.ensureGrid();
1189
+ const rows = [];
1190
+ rows.length = grid.lines.length;
1191
+ for (let row = 0; row < grid.lines.length; row++) {
1192
+ const line = grid.lines[row];
1193
+ const y = this.pad + row * this.lineH;
1194
+ if (!(0, import_core.contentLineInHint)(hint, y, this.lineH)) continue;
1195
+ rows[row] = {
1196
+ text: this.source.slice(line.sourceStart, line.sourceEnd),
1197
+ separatorAfter: this.source.slice(line.sourceEnd, line.nextSourceStart) || void 0,
1198
+ x: this.pad,
1199
+ y,
1200
+ baseline: this.lineH * 0.75,
1201
+ font: this.codeFont,
1202
+ lineHeight: this.lineH
1203
+ };
1204
+ }
1183
1205
  return {
1184
1206
  text: this.source,
1185
1207
  font: this.codeFont,
@@ -1187,15 +1209,8 @@ var CodeBlock = class extends import_ui.UIComponent {
1187
1209
  // Every row is absolutely positioned from the same local coordinates as
1188
1210
  // render(). A single pre-wrap DOM text node would introduce browser
1189
1211
  // wrapping for long source lines that canvas intentionally keeps intact.
1190
- lines: grid.lines.map((line, row) => ({
1191
- text: this.source.slice(line.sourceStart, line.sourceEnd),
1192
- separatorAfter: this.source.slice(line.sourceEnd, line.nextSourceStart) || void 0,
1193
- x: this.pad,
1194
- y: this.pad + row * this.lineH,
1195
- baseline: this.lineH * 0.75,
1196
- font: this.codeFont,
1197
- lineHeight: this.lineH
1198
- })),
1212
+ //
1213
+ lines: rows,
1199
1214
  selectable: this.selectable,
1200
1215
  // render() draws cell-by-cell (no ligatures can form); the DOM copy
1201
1216
  // must not ligate either or Firefox selection geometry drifts.
@@ -1216,6 +1231,7 @@ var CodeBlock = class extends import_ui.UIComponent {
1216
1231
  * lands mid-line, so that line's text (and therefore its tokenization) changes.
1217
1232
  */
1218
1233
  buildLines(code) {
1234
+ this.contentEpoch++;
1219
1235
  const rawLines = code.split(/\r\n|\r|\n/);
1220
1236
  const previous = this.rawLines;
1221
1237
  let reusable = 0;
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/Markdown.ts
2
2
  import {
3
+ contentLineInHint,
3
4
  BidiResolver,
4
5
  Entity,
5
6
  GlyphRasterAtlas,
@@ -1094,6 +1095,8 @@ var CodeBlock = class extends UIComponent {
1094
1095
  rawLines = null;
1095
1096
  cellWidth = 0;
1096
1097
  source;
1098
+ /** Bumped by {@link buildLines} and {@link setSelectable}; read by `Scene`. */
1099
+ contentEpoch = 0;
1097
1100
  lang;
1098
1101
  theme;
1099
1102
  lineH = 24;
@@ -1122,9 +1125,13 @@ var CodeBlock = class extends UIComponent {
1122
1125
  /** Enable or disable browser-native selection for this code block. */
1123
1126
  setSelectable(selectable) {
1124
1127
  this.selectable = selectable;
1128
+ this.contentEpoch++;
1125
1129
  this.scene?.markDirty();
1126
1130
  return this;
1127
1131
  }
1132
+ getContentEpoch() {
1133
+ return this.contentEpoch;
1134
+ }
1128
1135
  /**
1129
1136
  * Change the block's box width.
1130
1137
  *
@@ -1144,9 +1151,25 @@ var CodeBlock = class extends UIComponent {
1144
1151
  this.scene?.markDirty();
1145
1152
  return this;
1146
1153
  }
1147
- getContentProjection() {
1154
+ getContentProjection(hint) {
1148
1155
  if (!this.source) return null;
1149
1156
  const grid = this.ensureGrid();
1157
+ const rows = [];
1158
+ rows.length = grid.lines.length;
1159
+ for (let row = 0; row < grid.lines.length; row++) {
1160
+ const line = grid.lines[row];
1161
+ const y = this.pad + row * this.lineH;
1162
+ if (!contentLineInHint(hint, y, this.lineH)) continue;
1163
+ rows[row] = {
1164
+ text: this.source.slice(line.sourceStart, line.sourceEnd),
1165
+ separatorAfter: this.source.slice(line.sourceEnd, line.nextSourceStart) || void 0,
1166
+ x: this.pad,
1167
+ y,
1168
+ baseline: this.lineH * 0.75,
1169
+ font: this.codeFont,
1170
+ lineHeight: this.lineH
1171
+ };
1172
+ }
1150
1173
  return {
1151
1174
  text: this.source,
1152
1175
  font: this.codeFont,
@@ -1154,15 +1177,8 @@ var CodeBlock = class extends UIComponent {
1154
1177
  // Every row is absolutely positioned from the same local coordinates as
1155
1178
  // render(). A single pre-wrap DOM text node would introduce browser
1156
1179
  // wrapping for long source lines that canvas intentionally keeps intact.
1157
- lines: grid.lines.map((line, row) => ({
1158
- text: this.source.slice(line.sourceStart, line.sourceEnd),
1159
- separatorAfter: this.source.slice(line.sourceEnd, line.nextSourceStart) || void 0,
1160
- x: this.pad,
1161
- y: this.pad + row * this.lineH,
1162
- baseline: this.lineH * 0.75,
1163
- font: this.codeFont,
1164
- lineHeight: this.lineH
1165
- })),
1180
+ //
1181
+ lines: rows,
1166
1182
  selectable: this.selectable,
1167
1183
  // render() draws cell-by-cell (no ligatures can form); the DOM copy
1168
1184
  // must not ligate either or Firefox selection geometry drifts.
@@ -1183,6 +1199,7 @@ var CodeBlock = class extends UIComponent {
1183
1199
  * lands mid-line, so that line's text (and therefore its tokenization) changes.
1184
1200
  */
1185
1201
  buildLines(code) {
1202
+ this.contentEpoch++;
1186
1203
  const rawLines = code.split(/\r\n|\r|\n/);
1187
1204
  const previous = this.rawLines;
1188
1205
  let reusable = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectojs/markdown",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },