@nerd-bible/wordgard 0.5.3-beta7 → 0.6.2-beta10

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/editor.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as wordgard_doc from 'wordgard/doc';
2
- import { Elt, Node as Node$1, ChangeSet, Plot, Pos } from 'wordgard/doc';
2
+ import { Elt, Node as Node$1, Mark, Shape, ChangeSet, Plot, Pos } from 'wordgard/doc';
3
3
  import { GardState, TextblockMap, Transaction, GardSelection } from 'wordgard/state';
4
4
  import { PhraseSet } from 'wordgard/phrases';
5
5
  import { StyleModule, StyleSpec } from 'style-mod';
@@ -8,6 +8,7 @@ import { PointSet, Set, RangeSet } from 'wordgard/set';
8
8
 
9
9
  type MakeSelectionStyle = (wg: Wordgard, event: MouseEvent) => Wordgard.MouseSelectionStyle | null;
10
10
 
11
+ import Mark_ = Mark;
11
12
  /**
12
13
  A widget describes a piece of DOM content that can be used to
13
14
  render a node, a part of a node, or an extra element added via a
@@ -125,7 +126,7 @@ declare namespace Decoration {
125
126
  This function allows you to define a {@link Decoration.Tag.shape
126
127
  custom node shape} that depends on the editor state. It will
127
128
  automatically track which state slots (see {@link
128
- GardState.Facet.compute}) you use, and make sure the nodes
129
+ GardState.Facet.derive}) you use, and make sure the nodes
129
130
  are redrawn when those change.
130
131
 
131
132
  If your shape function returns a function from a tag, you
@@ -141,8 +142,7 @@ declare namespace Decoration {
141
142
  When providing a shape for a plot that changes whether it is
142
143
  rendered as an atom, provide the `atom` option.
143
144
  */
144
- function dynamic<T extends Node$1.Type<any>>(// FIXME find better name?
145
- type: T, shape: (state: GardState) => Shape | ((tag: Node$1.Tag.For<T>) => Shape), config?: {
145
+ function derived<T extends Node$1.Type<any>>(type: T, shape: (state: GardState) => Shape | ((tag: Node$1.Tag.For<T>) => Shape), config?: {
146
146
  atom?: boolean;
147
147
  }): GardState.Extension;
148
148
  }
@@ -172,9 +172,9 @@ declare namespace Decoration {
172
172
  /**
173
173
  Define a node widget decoration that depends on some aspect
174
174
  of the editor state. See the notes for {@link
175
- Decoration.Tag.shape.dynamic}.
175
+ Decoration.Tag.shape.derived}.
176
176
  */
177
- function dynamic<T extends Node$1.Type.Ref<any>>(type: T, place: "before" | "after" | "start" | "end", widget: (state: GardState) => Widget | ((tag: Node$1.Tag.For<T>) => Widget)): GardState.Extension;
177
+ function derived<T extends Node$1.Type.Ref<any>>(type: T, place: "before" | "after" | "start" | "end", widget: (state: GardState) => Widget | ((tag: Node$1.Tag.For<T>) => Widget)): GardState.Extension;
178
178
  }
179
179
  /**
180
180
  Add an attribute to the representation of a given node type.
@@ -190,6 +190,13 @@ declare namespace Decoration {
190
190
  target?: string;
191
191
  }): GardState.Extension;
192
192
  }
193
+ namespace Mark {
194
+ /**
195
+ Override the shape used for a given mark inside the editor.
196
+ */
197
+ function shape<V>(type: Mark_.Type<V>, shape: Shape.Element<V> | Shape.Attribute<V> | Shape.Attributes<V>): GardState.Extension;
198
+ function shape(mark: Mark_<null>, shape: Shape.Element<null> | Shape.Attribute<null> | Shape.Attributes<null>): GardState.Extension;
199
+ }
193
200
  /**
194
201
  A point decoration is a decoration that targets a given position
195
202
  in the document, or the node after a given position. Sets of
@@ -369,10 +376,11 @@ declare const enum TileFlag {
369
376
  Composition = 128,
370
377
  Synced = 256,// Node has been synced. DOM content matches child list / text content, child array becomes read-only
371
378
  Atom = 512,// Composite tile whose length isn't determined by child length
372
- HasContent = 1024,// EltTile whose elt has a content hole
373
- AfterContent = 2048,// Tiles that sit after their parent's content position
374
- ContentNotLast = 4096,// EltTile that has children with AfterContent flag
375
- Dirty = 8192
379
+ Uneditable = 1024,// Tile's DOM is uneditable
380
+ HasContent = 2048,// EltTile whose elt has a content hole
381
+ AfterContent = 4096,// Tiles that sit after their parent's content position
382
+ ContentNotLast = 8192,// EltTile that has children with AfterContent flag
383
+ Dirty = 16384
376
384
  }
377
385
  declare const enum Orientation {
378
386
  Row = 0,
@@ -414,14 +422,15 @@ declare abstract class Tile {
414
422
  get boundary(): 0 | 1;
415
423
  get firstChild(): Tile | null;
416
424
  get lastChild(): Tile | null;
417
- get nodeParent(): Tile;
418
425
  ignoreEvent(event: Event): boolean;
419
426
  get ignoreMutations(): boolean;
420
427
  toString(): string;
421
428
  abstract sync(): void;
422
429
  connect(): void;
423
430
  disconnect(reused?: Map<Tile, Reused>): void;
424
- nearestNode(): Tile;
431
+ nearestNode(): Tile & {
432
+ tag: Node$1.Tag;
433
+ };
425
434
  markDirty(): void;
426
435
  posAtCoords(state: GardState, x: number, y: number): CoordPos;
427
436
  abstract posAtCoordsInner(start: number, state: GardState, x: number, y: number, textblock: TextblockMap | null, orientation: Orientation): CoordPos;
@@ -431,6 +440,7 @@ declare class CompositeTile extends Tile {
431
440
  children: Tile[];
432
441
  dom: Element;
433
442
  addChild(child: Tile): void;
443
+ putChild(child: Tile, index: number): void;
434
444
  sync(): void;
435
445
  syncChildren(): void;
436
446
  posAtCoordsInner(start: number, state: GardState, x: number, y: number, textblock: TextblockMap | null, orientation: Orientation): CoordPos;
@@ -691,7 +701,7 @@ declare class Wordgard {
691
701
  Serializers are tried in order of precedence until one returns
692
702
  a string.
693
703
  */
694
- static clipboardTextSerializer: GardState.Facet<(slice: wordgard_doc.Slice, context: readonly wordgard_doc.Plot.Tag[], state: GardState) => string | null, readonly ((slice: wordgard_doc.Slice, context: readonly wordgard_doc.Plot.Tag[], state: GardState) => string | null)[]>;
704
+ static clipboardTextSerializer: GardState.Facet<(slice: wordgard_doc.Slice, state: GardState) => string | null, readonly ((slice: wordgard_doc.Slice, state: GardState) => string | null)[]>;
695
705
  /**
696
706
  Filter to run on the plain text representation of content put
697
707
  onto the clipboard.
@@ -721,7 +731,13 @@ declare class Wordgard {
721
731
  Facet that allows you to register handlers to override paste
722
732
  behavior.
723
733
  */
724
- static pasteHandler: GardState.Facet<(wg: Wordgard, event: ClipboardEvent, slice: wordgard_doc.Slice, context: readonly wordgard_doc.Plot.Tag[]) => boolean, readonly ((wg: Wordgard, event: ClipboardEvent, slice: wordgard_doc.Slice, context: readonly wordgard_doc.Plot.Tag[]) => boolean)[]>;
734
+ static pasteHandler: GardState.Facet<(wg: Wordgard, event: InputEvent | null, slice: wordgard_doc.Slice, html: string, text: string) => boolean, readonly ((wg: Wordgard, event: InputEvent | null, slice: wordgard_doc.Slice, html: string, text: string) => boolean)[]>;
735
+ /**
736
+ Perform a paste with the given content. This will run {@link
737
+ Wordgard.pasteHandler paste handlers} and, if none handles the
738
+ paste, fall back to the default handling.
739
+ */
740
+ paste(html: string, text?: string): void;
725
741
  /**
726
742
  Facet for custom drop handlers. When the drop is done inside the
727
743
  editor and should move an existing range, the `move` parameter
@@ -730,10 +746,10 @@ declare class Wordgard {
730
746
  static dropHandler: GardState.Facet<(wg: Wordgard, event: DragEvent, pos: number, move: {
731
747
  from: number;
732
748
  to: number;
733
- } | null, slice: wordgard_doc.Slice, context: readonly wordgard_doc.Plot.Tag[]) => boolean, readonly ((wg: Wordgard, event: DragEvent, pos: number, move: {
749
+ } | null, slice: wordgard_doc.Slice) => boolean, readonly ((wg: Wordgard, event: DragEvent, pos: number, move: {
734
750
  from: number;
735
751
  to: number;
736
- } | null, slice: wordgard_doc.Slice, context: readonly wordgard_doc.Plot.Tag[]) => boolean)[]>;
752
+ } | null, slice: wordgard_doc.Slice) => boolean)[]>;
737
753
  /**
738
754
  This annotation is added to transactions created because the
739
755
  editor's focused status changed. It holds `true` when the editor
@@ -847,7 +863,7 @@ declare class Wordgard {
847
863
  the editor's {@link Wordgard.dom wrapper element} (to which the
848
864
  scope class will be added) need to be explicitly differentiated
849
865
  by adding an `&` to the selector for that element—for example
850
- `&:has(wg-content:focus)`.
866
+ `&.wg-focused`.
851
867
  */
852
868
  static theme(spec: Record<string, StyleSpec>): GardState.Extension;
853
869
  /**
@@ -916,6 +932,11 @@ declare class Wordgard {
916
932
  part of the editor (for example a gutter).
917
933
  */
918
934
  static coveredMargins: GardState.Facet<(wg: Wordgard) => Partial<DOMRect> | null, readonly ((wg: Wordgard) => Partial<DOMRect> | null)[]>;
935
+ /**
936
+ Given a DOM element that may be a Wordgard editor, retrieve its
937
+ editor instance.
938
+ */
939
+ static findFromDOM(elt: Element): Wordgard | null;
919
940
  }
920
941
  declare namespace Wordgard {
921
942
  /**
@@ -1160,9 +1181,8 @@ appear in
1160
1181
  Use lowercase letters to refer to letter keys. You can use
1161
1182
  `"Space"` as an alias for the `" "` name.
1162
1183
 
1163
- Modifiers can be given in any order. `Shift-` (or `s-`), `Alt-` (or
1164
- `a-`), `Ctrl-` (or `c-` or `Control-`) and `Cmd-` (or `m-` or
1165
- `Meta-`) are recognized.
1184
+ Modifiers can be given in any order. `Shift-`, `Alt-`, `Ctrl-` and
1185
+ `Cmd-` (or `Meta-`) are recognized.
1166
1186
 
1167
1187
  You can use `Mod-` as a shorthand for `Cmd-` on Mac and `Ctrl-` on
1168
1188
  other platforms. So `Mod-b` is `Ctrl-b` on Linux but `Cmd-b` on
@@ -1238,28 +1258,28 @@ declare namespace KeyBinding {
1238
1258
  */
1239
1259
  any?: (wg: Wordgard, event: KeyboardEvent) => boolean;
1240
1260
  /**
1241
- By default, key bindings apply when focus is on the editor
1242
- content (the `"editor"` scope). Some extensions, mostly those
1243
- that define their own panels, might want to allow registering
1244
- bindings local to that panel. Such bindings should use a custom
1245
- scope name. You may also assign multiple scope names to a
1246
- binding, separating them by spaces.
1247
- */
1248
- scope?: string;
1249
- /**
1250
1261
  By default, all keys events for which a handler exists have
1251
1262
  their `preventDefault` called, even if no handler returns
1252
1263
  true. You can set this to true to disable that behavior.
1253
1264
  */
1254
1265
  allowDefault?: boolean;
1266
+ /**
1267
+ A textual description of what this key does. Will be used by
1268
+ {@link keyBindingHelp} to create a list of active bindings.
1269
+ */
1270
+ description?: PhraseSet.Ref | string;
1271
+ /**
1272
+ A textual description of what the shifted variant of this key
1273
+ does.
1274
+ */
1275
+ shiftDescription?: PhraseSet.Ref | string;
1276
+ /**
1277
+ The group under which the description of this key should be
1278
+ organized in the list of bindings.
1279
+ */
1280
+ group?: Group;
1255
1281
  }
1256
1282
  /**
1257
- Run the key handlers registered for a given scope. The event
1258
- object should be a `"keydown"` event. Returns true if any of the
1259
- handlers handled it.
1260
- */
1261
- function runScopeHandlers(wg: Wordgard, event: KeyboardEvent, scope: string): boolean;
1262
- /**
1263
1283
  Facet used for registering key bindings. Extension precedence
1264
1284
  determines the order in which bindings that match the same key
1265
1285
  are called. When a handler has returned `true` for a given key,
@@ -1273,6 +1293,38 @@ declare namespace KeyBinding {
1273
1293
  */
1274
1294
  const useDefaultKeymap: GardState.Facet<boolean, boolean>;
1275
1295
  /**
1296
+ Key binding groups are used to {@link KeyBinding.Spec.group
1297
+ organize} key bindings in the user-presented {@link
1298
+ keyBindingHelp list} of bindings.
1299
+ */
1300
+ class Group {
1301
+ /**
1302
+ The description given for this group.
1303
+ */
1304
+ readonly description: PhraseSet.Ref | string;
1305
+ /**
1306
+ A sorting rank.
1307
+ */
1308
+ readonly rank: number;
1309
+ private constructor();
1310
+ /**
1311
+ Define a key binding group.
1312
+ */
1313
+ static define(spec: {
1314
+ description: PhraseSet.Ref | string;
1315
+ rank?: number;
1316
+ }): Group;
1317
+ static Inline: Group;
1318
+ static Block: Group;
1319
+ static History: Group;
1320
+ }
1321
+ /**
1322
+ Look for a key associated with the given description in the
1323
+ state's key bindings, and if found, return its key name as a
1324
+ string.
1325
+ */
1326
+ function lookupByDescription(state: GardState, desc: string | PhraseSet.Ref): string | null;
1327
+ /**
1276
1328
  The editor's set of default key bindings. Binds the following
1277
1329
  keys. Most cursor motion bindings include a `Shift-` variant
1278
1330
  that passes the `extend` flag to the command. Enabled by default
@@ -1326,6 +1378,27 @@ declare namespace KeyBinding {
1326
1378
  const defaultKeymap: readonly KeyBinding[];
1327
1379
  }
1328
1380
 
1381
+ /**
1382
+ Returns an extension that binds `Mod-?` to {@link
1383
+ keyBindingHelp.showKeyBindings}.
1384
+ */
1385
+ declare function keyBindingHelp(): GardState.Extension;
1386
+ declare namespace keyBindingHelp {
1387
+ /**
1388
+ This command opens a dialog displaying the key bindings that
1389
+ have a description associated with them.
1390
+ */
1391
+ const showKeyBindings: Command;
1392
+ /**
1393
+ A menu button that, when clicked, displays the available key bindings.
1394
+ */
1395
+ const button: Menu.Button;
1396
+ /**
1397
+ Bind `Mod-?` to {@link keyBindingHelp.showKeyBindings `showKeyBindings`}.
1398
+ */
1399
+ const keyBindings: KeyBinding[];
1400
+ }
1401
+
1329
1402
  type Config = {
1330
1403
  /**
1331
1404
  The type of plot to decorate.
@@ -1433,81 +1506,6 @@ declare function menuBar(config?: {
1433
1506
  template?: Menu.Template | readonly Menu.Template[];
1434
1507
  }): GardState.Extension;
1435
1508
 
1436
- /**
1437
- Dialogs are {@link Panel panels} opened as a side-effect, and
1438
- closed by user action. This interface is used to describe them.
1439
- */
1440
- interface Dialog {
1441
- /**
1442
- A function to render the content of the dialog. The result
1443
- should contain at least one `<form>` element. Submit handlers
1444
- and a handler for the Escape key will be added to the form.
1445
-
1446
- If this is not given, the `label`, `input`, and `submitLabel`
1447
- fields will be used to create a simple form for you.
1448
- */
1449
- content?: (wg: Wordgard, close: () => void) => Element;
1450
- /**
1451
- When `content` isn't given, this provides the text shown in the
1452
- dialog.
1453
- */
1454
- label?: string;
1455
- /**
1456
- The attributes for an input element shown next to the label. If
1457
- not given, no input element is added.
1458
- */
1459
- input?: {
1460
- [attr: string]: string;
1461
- };
1462
- /**
1463
- The label for the button that submits the form. Defaults to
1464
- `"OK"`.
1465
- */
1466
- submitLabel?: string;
1467
- /**
1468
- Extra classes to add to the panel.
1469
- */
1470
- class?: string;
1471
- /**
1472
- A query selector to find the field that should be focused when
1473
- the dialog is opened. When set to true, this picks the first
1474
- `<input>` or `<button>` element in the form. When set to
1475
- `false`, focus is not moved into the dialog.
1476
- */
1477
- focus?: string | boolean;
1478
- /**
1479
- By default, dialogs are shown above the editor. Set this to
1480
- `false` to have it show up at the bottom.
1481
- */
1482
- top?: boolean;
1483
- }
1484
- declare namespace Dialog {
1485
- /**
1486
- Show a dialog to display a message or prompt the user for input.
1487
- Returns an effect that can be dispatched to close the dialog,
1488
- and a promise that resolves when the dialog is closed or a form
1489
- inside of it is submitted.
1490
-
1491
- You are encouraged, if your handling of the result of the promise
1492
- dispatches a transaction, to include the `close` effect in it. If
1493
- you don't, this function will automatically dispatch a separate
1494
- transaction right after.
1495
- */
1496
- function show(wg: Wordgard, config: Dialog): {
1497
- close: Transaction.Effect<unknown>;
1498
- result: Promise<HTMLFormElement | null>;
1499
- };
1500
- /**
1501
- Find the {@link Panel} for an open dialog, using a class name as
1502
- identifier.
1503
- */
1504
- function get(wg: Wordgard, className: string): Panel | null;
1505
- /**
1506
- Close the {@link Panel} for an open dialog, by class name.
1507
- */
1508
- function close(wg: Wordgard, className: string): boolean;
1509
- }
1510
-
1511
1509
  /**
1512
1510
  Describes a tooltip. Values of this type, when provided through
1513
1511
  the {@link Tooltip.show} facet, provide the active tooltips on an
@@ -1732,6 +1730,109 @@ hover tooltip source}.
1732
1730
  */
1733
1731
  type HoverTooltipSource = (wg: Wordgard, pos: number, side: -1 | 1) => Tooltip | readonly Tooltip[] | null | Promise<Tooltip | readonly Tooltip[] | null>;
1734
1732
 
1733
+ /**
1734
+ Dialogs are UI elements opened as a side-effect and closed by user
1735
+ action. They may be either placed near some document position (as
1736
+ a {@link Tooltip tooltip}), or free-floating.
1737
+ */
1738
+ interface Dialog {
1739
+ /**
1740
+ An arbitrary value used to identify this dialog. Used to query
1741
+ for it via {@link Dialog.get}.
1742
+ */
1743
+ key?: any;
1744
+ /**
1745
+ A function to render the content of the dialog. The result
1746
+ should contain at least one `<form>` element. Submit handlers
1747
+ and a handler for the Escape key will be added to the form.
1748
+
1749
+ If this is not given, the `label`, `input`, and `submitLabel`
1750
+ fields will be used to create a simple form for you.
1751
+ */
1752
+ content?: (wg: Wordgard, close: () => void) => Element | DocumentFragment;
1753
+ /**
1754
+ When `content` isn't given, this provides the text shown in the
1755
+ dialog.
1756
+ */
1757
+ label?: string;
1758
+ /**
1759
+ The attributes for an input element shown next to the label. If
1760
+ not given, no input element is added.
1761
+ */
1762
+ input?: {
1763
+ [attr: string]: string;
1764
+ };
1765
+ /**
1766
+ The label for the button that submits the form. Defaults to
1767
+ `"OK"`.
1768
+ */
1769
+ submitLabel?: string;
1770
+ /**
1771
+ Extra classes to add to the element.
1772
+ */
1773
+ class?: string;
1774
+ /**
1775
+ A query selector to find the field that should be focused when
1776
+ the dialog is opened. When set to true, this picks the first
1777
+ `<input>` or `<button>` element in the form. When set to
1778
+ `false`, focus is not moved into the dialog.
1779
+ */
1780
+ focus?: string | boolean;
1781
+ /**
1782
+ If given, a transaction for which the predicate returns true
1783
+ will automatically close the dialog.
1784
+ */
1785
+ closedBy?: (tr: Transaction) => boolean;
1786
+ /**
1787
+ Provide this option to position this dialog like a tooltip,
1788
+ relative to some document position.
1789
+ */
1790
+ tooltip?: Omit<Tooltip, "create">;
1791
+ /**
1792
+ If given try to align the left top (or right top, in a
1793
+ right-to-left layout) with the corner of this rectangle. If set
1794
+ to `true`, call {@link PositioningHint.get} to try and get a
1795
+ rectangle. When available, this will override the `tooltip`
1796
+ option.
1797
+ */
1798
+ positioningHint?: DOMRect | true;
1799
+ }
1800
+ declare namespace Dialog {
1801
+ /**
1802
+ Show a dialog to display a message or prompt the user for input.
1803
+ Returns a function that closes the dialog and a promise that
1804
+ resolves when the dialog is closed or a form inside of it is
1805
+ submitted.
1806
+ */
1807
+ function show(wg: Wordgard, config: Dialog): {
1808
+ close: () => void;
1809
+ result: Promise<HTMLFormElement | null>;
1810
+ };
1811
+ /**
1812
+ See whether a dialog with the given key is present in the
1813
+ editor, and if so return its DOM representation and a functionto
1814
+ close it. Note that `dom` may be `null` if the dialog is present
1815
+ but not yet rendered.
1816
+ */
1817
+ function get(wg: Wordgard, key: any): {
1818
+ dom: HTMLElement | null;
1819
+ close: () => void;
1820
+ } | null;
1821
+ }
1822
+ declare namespace PositioningHint {
1823
+ /**
1824
+ Run function `run` with the positioning hint provided by `hint`
1825
+ available. Until that function returns, {@link
1826
+ PositioningHint.get} will return this rectangle, unless a nested
1827
+ call to `runWith` shadows it.
1828
+ */
1829
+ function runWith<T>(hint: () => DOMRect, run: () => T): T;
1830
+ /**
1831
+ Get the current positioning hint, if available.
1832
+ */
1833
+ function get(): DOMRect | null;
1834
+ }
1835
+
1735
1836
  /**
1736
1837
  Objects of this type represent input rules.
1737
1838
  */
@@ -1861,4 +1962,4 @@ being dragged over the editor.
1861
1962
  */
1862
1963
  declare function dropCursor(): GardState.Extension;
1863
1964
 
1864
- export { Decoration, Dialog, InputRule, KeyBinding, Panel, Tooltip, Widget, Wordgard, decoratePlots, dropCursor, menuBar, placeholder };
1965
+ export { Decoration, Dialog, InputRule, KeyBinding, Panel, PositioningHint, Tooltip, Widget, Wordgard, decoratePlots, dropCursor, keyBindingHelp, menuBar, placeholder };