@nerd-bible/wordgard 0.5.3-beta4 → 0.5.3-beta6

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/doc.js CHANGED
@@ -2158,43 +2158,8 @@ class ChangeSet {
2158
2158
  return fix ? set.compose(fix) : set;
2159
2159
  }
2160
2160
  compose(other) {
2161
- let sectionsA = this.sections, dataA = this.data;
2162
- let sectionsB = other.sections, dataB = other.data;
2163
- let sections = [], data = [];
2164
- let a = new SectionIter(sectionsA, dataA), b = new SectionIter(sectionsB, dataB);
2165
- for (let open = false;;) {
2166
- if (a.done && b.done) {
2167
- return new ChangeSet(sections, data);
2168
- }
2169
- else if (a.ins == 0) { addSection(sections, data, a.len, 0, a.slice, open);
2170
- a.next();
2171
- }
2172
- else if (b.len == 0 && !b.done) { addSection(sections, data, 0, b.ins, b.slice, open);
2173
- b.next();
2174
- }
2175
- else if (a.done || b.done) {
2176
- throw new ValidationError("Mismatched change set lengths");
2177
- }
2178
- else {
2179
- let len = Math.min(a.len2, b.len), sectionLen = sections.length;
2180
- if (a.keep && b.keep) {
2181
- let mods = combineMods(a.mods, b.mods);
2182
- addSection(sections, data, len, mods ? -2 : -1, mods, open);
2183
- }
2184
- else if (a.keep) {
2185
- addSection(sections, data, len, b.off ? 0 : b.ins, b.off ? Slice.empty : b.slice, open);
2186
- }
2187
- else if (b.keep) {
2188
- addSection(sections, data, a.off ? 0 : a.len, len, applyModsToSlice(a.slicePart(len), b.mods), open);
2189
- }
2190
- else {
2191
- addSection(sections, data, a.off ? 0 : a.len, b.off ? 0 : b.ins, b.off ? Slice.empty : b.slice, open);
2192
- }
2193
- open = (a.ins > len || b.ins >= 0 && b.len > len) && (open || sections.length > sectionLen);
2194
- a.forward2(len);
2195
- b.forward(len);
2196
- }
2197
- }
2161
+ let { sections, data } = compose(this.sections, other.sections, this.data, other.data);
2162
+ return new ChangeSet(sections, data);
2198
2163
  }
2199
2164
  invert(doc) {
2200
2165
  let sections = [], data = [];
@@ -2415,6 +2380,9 @@ class ChangeSet {
2415
2380
  }
2416
2381
  return result;
2417
2382
  }
2383
+ static composeSections(a, b) {
2384
+ return compose(a, b).sections;
2385
+ }
2418
2386
  static transform(doc, a, b) {
2419
2387
  let { set: mA, fix } = transform(a, b, doc, true, true);
2420
2388
  let mB = transform(b, a, doc, false, false).set;
@@ -2613,6 +2581,43 @@ function transform(setA, setB, doc, before, fit) {
2613
2581
  }
2614
2582
  }
2615
2583
  }
2584
+ function compose(sectionsA, sectionsB, dataA, dataB) {
2585
+ let sections = [], data = dataA ? [] : null;
2586
+ let a = new SectionIter(sectionsA, dataA), b = new SectionIter(sectionsB, dataB);
2587
+ for (let open = false;;) {
2588
+ if (a.done && b.done) {
2589
+ return { sections, data };
2590
+ }
2591
+ else if (a.ins == 0) { addSection(sections, data, a.len, 0, a.slice, open);
2592
+ a.next();
2593
+ }
2594
+ else if (b.len == 0 && !b.done) { addSection(sections, data, 0, b.ins, b.slice, open);
2595
+ b.next();
2596
+ }
2597
+ else if (a.done || b.done) {
2598
+ throw new ValidationError("Mismatched change set lengths");
2599
+ }
2600
+ else {
2601
+ let len = Math.min(a.len2, b.len), sectionLen = sections.length;
2602
+ if (a.keep && b.keep) {
2603
+ let mods = combineMods(a.mods, b.mods);
2604
+ addSection(sections, data, len, (data ? mods : a.ins == -2 || b.ins == -2) ? -2 : -1, mods, open);
2605
+ }
2606
+ else if (a.keep) {
2607
+ addSection(sections, data, len, b.off ? 0 : b.ins, b.off ? Slice.empty : b.slice, open);
2608
+ }
2609
+ else if (b.keep) {
2610
+ addSection(sections, data, a.off ? 0 : a.len, len, data ? applyModsToSlice(a.slicePart(len), b.mods) : null, open);
2611
+ }
2612
+ else {
2613
+ addSection(sections, data, a.off ? 0 : a.len, b.off ? 0 : b.ins, b.off ? Slice.empty : b.slice, open);
2614
+ }
2615
+ open = (a.ins > len || b.ins >= 0 && b.len > len) && (open || sections.length > sectionLen);
2616
+ a.forward2(len);
2617
+ b.forward(len);
2618
+ }
2619
+ }
2620
+ }
2616
2621
  function combineMods(a, b) {
2617
2622
  return !a ? b : !b ? a : a.concat(b);
2618
2623
  }
@@ -2972,10 +2977,10 @@ class SectionIter {
2972
2977
  get done() { return this.ins == -3; }
2973
2978
  get len2() { return this.ins < 0 ? this.len : this.ins; }
2974
2979
  get mods() {
2975
- return this.data[(this.i - 2) >> 1];
2980
+ return this.data ? this.data[(this.i - 2) >> 1] : null;
2976
2981
  }
2977
2982
  get slice() {
2978
- return this.data[(this.i - 2) >> 1];
2983
+ return this.data ? this.data[(this.i - 2) >> 1] : Slice.empty;
2979
2984
  }
2980
2985
  slicePart(len) {
2981
2986
  return this.slice.slice(this.off, len == null ? undefined : this.off + len);
@@ -3004,7 +3009,7 @@ function addSection(sections, data, len, ins, value, forceJoin = false) {
3004
3009
  return;
3005
3010
  let last = sections.length - 2;
3006
3011
  if (last >= 0 && ins <= 0 && ins == sections[last + 1]) {
3007
- let lastValue = data[data.length - 1];
3012
+ let lastValue = data ? data[data.length - 1] : null;
3008
3013
  let match = ins == 0 ? true
3009
3014
  : value ? lastValue && compareModifications(lastValue, value)
3010
3015
  : !lastValue;
@@ -3016,11 +3021,13 @@ function addSection(sections, data, len, ins, value, forceJoin = false) {
3016
3021
  if (forceJoin || last >= 0 && len == 0 && sections[last] == 0) {
3017
3022
  sections[last] += len;
3018
3023
  sections[last + 1] += ins;
3019
- data[data.length - 1] = data[data.length - 1].concat(value);
3024
+ if (data)
3025
+ data[data.length - 1] = data[data.length - 1].concat(value);
3020
3026
  }
3021
3027
  else {
3022
3028
  sections.push(len, ins);
3023
- data.push(value);
3029
+ if (data)
3030
+ data.push(value);
3024
3031
  }
3025
3032
  }
3026
3033
  function finishCx(cx, schema) {
package/dist/editor.d.ts CHANGED
@@ -4,6 +4,7 @@ import { GardState, TextblockMap, Transaction, GardSelection } from 'wordgard/st
4
4
  import { PhraseSet } from 'wordgard/phrases';
5
5
  import { StyleModule, StyleSpec } from 'style-mod';
6
6
  import { Command, Menu } from 'wordgard/command';
7
+ import { PointSet, Set, RangeSet } from 'wordgard/set';
7
8
 
8
9
  type MakeSelectionStyle = (wg: Wordgard, event: MouseEvent) => Wordgard.MouseSelectionStyle | null;
9
10
 
@@ -123,7 +124,7 @@ declare namespace Decoration {
123
124
  /**
124
125
  This function allows you to define a {@link Decoration.Tag.shape
125
126
  custom node shape} that depends on the editor state. It will
126
- automatically track what slots (see {@link
127
+ automatically track which state slots (see {@link
127
128
  GardState.Facet.compute}) you use, and make sure the nodes
128
129
  are redrawn when those change.
129
130
 
@@ -250,6 +251,21 @@ declare namespace Decoration {
250
251
  keep your set in a state field and update it incrementally.
251
252
  */
252
253
  static source: GardState.Facet<(state: GardState) => PointSet<Point>, readonly ((state: GardState) => PointSet<Point>)[]>;
254
+ /**
255
+ Create a {@link PointSet} from an array or source function of
256
+ point decorations.
257
+ */
258
+ static set(source: Set.Source<Point>): Point.Set;
259
+ /**
260
+ The empty set of point decorations.
261
+ */
262
+ static none: Point.Set;
263
+ }
264
+ namespace Point {
265
+ /**
266
+ The type used for sets of point decorations.
267
+ */
268
+ type Set = PointSet<Point>;
253
269
  }
254
270
  /**
255
271
  Range decorations apply to a document range. They are stored in
@@ -280,7 +296,16 @@ declare namespace Decoration {
280
296
  range sets on the fly will not perform well, so you'll often
281
297
  want to store these in a state field.
282
298
  */
283
- static source: GardState.Facet<(state: GardState) => RangeSet<Range>, readonly ((state: GardState) => RangeSet<Range>)[]>;
299
+ static source: GardState.Facet<(state: GardState) => Range.Set, readonly ((state: GardState) => Range.Set)[]>;
300
+ /**
301
+ Create a {@link RangeSet} from an array or source function of
302
+ range decorations.
303
+ */
304
+ static set(source: Set.Source<Range>): Range.Set;
305
+ /**
306
+ The empty set of range decorations.
307
+ */
308
+ static none: Range.Set;
284
309
  }
285
310
  namespace Range {
286
311
  /**
@@ -324,141 +349,10 @@ declare namespace Decoration {
324
349
  */
325
350
  spanning?: boolean;
326
351
  }
327
- }
328
- }
329
- /**
330
- Data structure used to store sets of points and then track them
331
- across document changes. Mostly used for {@link Decoration.Point
332
- point decorations}, but can also track your own types, if you make
333
- sure they implement the {@link PointSet.Value} interface.
334
- */
335
- declare class PointSet<T extends PointSet.Value = PointSet.Value> {
336
- /**
337
- The values in this set.
338
- */
339
- readonly values: readonly T[];
340
- /**
341
- The positions of the values in this set.
342
- */
343
- readonly positions: readonly number[];
344
- private constructor();
345
- /**
346
- The number of points in this set.
347
- */
348
- get length(): number;
349
- /**
350
- Adjust the points for a set of document changes. Returns a new
351
- set with the adjusted points. May delete points when the content
352
- around them was deleted.
353
- */
354
- map(changes: ChangeSet, start?: number): PointSet<T>;
355
- /**
356
- Returns the union of this set and the given set. If
357
- `maskFrom`/`maskTo` are given, drop any points from `this`
358
- between or at those positions.
359
- */
360
- merge(other: PointSet<T>, maskFrom?: number, maskTo?: number | undefined): PointSet<T>;
361
- /**
362
- Get the value at the given position, if any. If there's multiple
363
- values at that position, the one with the lowest side is
364
- returned.
365
- */
366
- at(pos: number): T | undefined;
367
- /**
368
- Create a point set from an iterable of `[position, value]`
369
- tuples, or a function that calls its argument for every point to
370
- add.
371
- */
372
- static create<T extends PointSet.Value>(source: Iterable<[number, T]> | ((add: (pos: number, value: T) => void) => void)): PointSet<T>;
373
- /**
374
- The empty point set.
375
- */
376
- static empty: PointSet<any>;
377
- }
378
- declare namespace PointSet {
379
- /**
380
- Objects stored in a point set must conform to this interface.
381
- */
382
- interface Value {
383
- /**
384
- The side of the point. Used to provide a sorting of points at
385
- the same position
386
- */
387
- side: number;
388
- /**
389
- Specifies whether the point should be deleted when content
390
- next to it is deleted. See {@link ChangeSet.mapPos}.
391
- */
392
- trackMode: ChangeSet.TrackMode | undefined;
393
352
  /**
394
- Method to compare this value to another.
353
+ The type used for sets of point decorations.
395
354
  */
396
- eq(other: PointSet.Value): boolean;
397
- }
398
- }
399
- /**
400
- Data structure that stores sets of ranges, for use with {@link
401
- Decoration.Range range decorations} or other data types
402
- implementing {@link RangeSet.Value}.
403
- */
404
- declare class RangeSet<T extends RangeSet.Value = RangeSet.Value> {
405
- /**
406
- The value associated with the ranges in the set.
407
- */
408
- readonly values: readonly T[];
409
- /**
410
- The start positions of the ranges in this set.
411
- */
412
- readonly from: readonly number[];
413
- /**
414
- The end positions of the ranges.
415
- */
416
- readonly to: readonly number[];
417
- private constructor();
418
- /**
419
- The number of ranges stored in this set.
420
- */
421
- get length(): number;
422
- /**
423
- Adjust the positions of the ranges for the given change set.
424
- Returns a set with the updated ranges.
425
- */
426
- map(changes: ChangeSet, start?: number): RangeSet<T>;
427
- /**
428
- Merge this set with another set. If `maskFrom`/`maskTo` are
429
- given, any ranges overlapping the masked range in `this` are
430
- not included in the merged set.
431
- */
432
- merge(other: RangeSet<T>, maskFrom?: number, maskTo?: number | undefined): RangeSet<T>;
433
- /**
434
- Create a range set from an iterable of `[from, to, value]`
435
- tuples, or a function that calls its argument for every range to
436
- add.
437
- */
438
- static create<T extends RangeSet.Value>(source: Iterable<[number, number, T]> | ((add: (from: number, to: number, value: T) => void) => void)): RangeSet<T>;
439
- /**
440
- The empty range set.
441
- */
442
- static empty: RangeSet<any>;
443
- }
444
- declare namespace RangeSet {
445
- /**
446
- Values stored in a range set must conform to this interface.
447
- */
448
- interface Value {
449
- /**
450
- Whether content inserted at the start of this value's range is
451
- included in the range.
452
- */
453
- inclusiveStart: boolean;
454
- /**
455
- Whether content inserted at the end is included.
456
- */
457
- inclusiveEnd: boolean;
458
- /**
459
- Compare this value to another.
460
- */
461
- eq(other: Value): boolean;
355
+ type Set = RangeSet<Range>;
462
356
  }
463
357
  }
464
358
 
@@ -511,7 +405,7 @@ declare abstract class Tile {
511
405
  get isSpanning(): boolean;
512
406
  get isComposition(): boolean;
513
407
  get isPoint(): boolean;
514
- get node(): Node$1 | null;
408
+ get tag(): Node$1.Tag | null;
515
409
  posBeforeChild(child: Tile, ownStart?: number): number;
516
410
  get posBefore(): number;
517
411
  get posAtStart(): number;
@@ -1432,6 +1326,35 @@ declare namespace KeyBinding {
1432
1326
  const defaultKeymap: readonly KeyBinding[];
1433
1327
  }
1434
1328
 
1329
+ type Config = {
1330
+ /**
1331
+ The type of plot to decorate.
1332
+ */
1333
+ type: Node$1.Query;
1334
+ /**
1335
+ A function that produces range decorations for a plot. `from`
1336
+ and `to` should be relative to the start of the plot's content,
1337
+ and be fall entirely within the plot.
1338
+ */
1339
+ ranges?: (node: Plot, range: (deco: Decoration.Range, from: number, to: number) => void) => void;
1340
+ /**
1341
+ A function that produces point decorations for a plot. `pos`
1342
+ should be relative to the start of the plot's content.
1343
+ */
1344
+ points?: (node: Plot, point: (deco: Decoration.Point, pos: number) => void) => void;
1345
+ /**
1346
+ An optional function that causes the decorations to be recreated
1347
+ on matching transaction, either for the entire document (`true`)
1348
+ or for any plot where the returned predicate returns `true`.
1349
+ */
1350
+ refresh?: (tr: Transaction) => boolean | ((plot: Plot) => boolean);
1351
+ };
1352
+ /**
1353
+ Create an extension that adds decorations to plots matching the
1354
+ given type.
1355
+ */
1356
+ declare function decoratePlots(config: Config): GardState.Extension;
1357
+
1435
1358
  type PanelConfig = {
1436
1359
  /**
1437
1360
  By default, panels will be placed inside the editor's DOM
@@ -1938,4 +1861,4 @@ being dragged over the editor.
1938
1861
  */
1939
1862
  declare function dropCursor(): GardState.Extension;
1940
1863
 
1941
- export { Decoration, Dialog, InputRule, KeyBinding, Panel, PointSet, RangeSet, Tooltip, Widget, Wordgard, dropCursor, menuBar, placeholder };
1864
+ export { Decoration, Dialog, InputRule, KeyBinding, Panel, Tooltip, Widget, Wordgard, decoratePlots, dropCursor, menuBar, placeholder };