@kerebron/extension-yjs 0.2.1 → 0.3.1

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.
Files changed (70) hide show
  1. package/esm/editor/src/CoreEditor.d.ts +11 -5
  2. package/esm/editor/src/CoreEditor.d.ts.map +1 -1
  3. package/esm/editor/src/CoreEditor.js +64 -61
  4. package/esm/editor/src/DummyEditorView.d.ts +60 -0
  5. package/esm/editor/src/DummyEditorView.d.ts.map +1 -0
  6. package/esm/editor/src/DummyEditorView.js +277 -0
  7. package/esm/editor/src/Extension.d.ts +9 -9
  8. package/esm/editor/src/Extension.d.ts.map +1 -1
  9. package/esm/editor/src/Extension.js +2 -2
  10. package/esm/editor/src/ExtensionManager.d.ts +8 -7
  11. package/esm/editor/src/ExtensionManager.d.ts.map +1 -1
  12. package/esm/editor/src/ExtensionManager.js +58 -39
  13. package/esm/editor/src/Mark.d.ts +8 -6
  14. package/esm/editor/src/Mark.d.ts.map +1 -1
  15. package/esm/editor/src/Mark.js +8 -2
  16. package/esm/editor/src/Node.d.ts +14 -12
  17. package/esm/editor/src/Node.d.ts.map +1 -1
  18. package/esm/editor/src/Node.js +10 -4
  19. package/esm/editor/src/commands/CommandManager.d.ts +5 -9
  20. package/esm/editor/src/commands/CommandManager.d.ts.map +1 -1
  21. package/esm/editor/src/commands/CommandManager.js +7 -6
  22. package/esm/editor/src/commands/mod.d.ts +12 -6
  23. package/esm/editor/src/commands/mod.d.ts.map +1 -1
  24. package/esm/editor/src/commands/mod.js +0 -45
  25. package/esm/editor/src/mod.d.ts +1 -0
  26. package/esm/editor/src/mod.d.ts.map +1 -1
  27. package/esm/editor/src/mod.js +1 -0
  28. package/esm/editor/src/nodeToTreeString.d.ts +8 -2
  29. package/esm/editor/src/nodeToTreeString.d.ts.map +1 -1
  30. package/esm/editor/src/nodeToTreeString.js +47 -29
  31. package/esm/editor/src/plugins/input-rules/InputRulesPlugin.js +2 -2
  32. package/esm/editor/src/plugins/keymap/keymap.d.ts +11 -0
  33. package/esm/editor/src/plugins/keymap/keymap.d.ts.map +1 -0
  34. package/esm/editor/src/plugins/keymap/keymap.js +125 -0
  35. package/esm/editor/src/plugins/keymap/w3c-keyname.d.ts +4 -0
  36. package/esm/editor/src/plugins/keymap/w3c-keyname.d.ts.map +1 -0
  37. package/esm/editor/src/plugins/keymap/w3c-keyname.js +124 -0
  38. package/esm/editor/src/types.d.ts +10 -5
  39. package/esm/editor/src/types.d.ts.map +1 -1
  40. package/esm/editor/src/utilities/SmartOutput.d.ts +39 -0
  41. package/esm/editor/src/utilities/SmartOutput.d.ts.map +1 -0
  42. package/esm/editor/src/utilities/SmartOutput.js +213 -0
  43. package/esm/editor/src/utilities/createNodeFromContent.d.ts +4 -3
  44. package/esm/editor/src/utilities/createNodeFromContent.d.ts.map +1 -1
  45. package/esm/editor/src/utilities/createNodeFromContent.js +4 -5
  46. package/esm/editor/src/utilities/getHtmlAttributes.d.ts +8 -3
  47. package/esm/editor/src/utilities/getHtmlAttributes.d.ts.map +1 -1
  48. package/esm/extension-yjs/src/ExtensionYjs.d.ts +5 -5
  49. package/esm/extension-yjs/src/ExtensionYjs.d.ts.map +1 -1
  50. package/esm/extension-yjs/src/ExtensionYjs.js +3 -2
  51. package/esm/extension-yjs/src/keys.d.ts +15 -0
  52. package/esm/extension-yjs/src/keys.d.ts.map +1 -0
  53. package/esm/extension-yjs/src/keys.js +13 -0
  54. package/esm/extension-yjs/src/lib.js +269 -0
  55. package/esm/extension-yjs/src/utils.d.ts +0 -3
  56. package/esm/extension-yjs/src/utils.d.ts.map +1 -1
  57. package/esm/extension-yjs/src/utils.js +0 -8
  58. package/esm/extension-yjs/src/yCursorPlugin.d.ts +3 -17
  59. package/esm/extension-yjs/src/yCursorPlugin.d.ts.map +1 -1
  60. package/esm/extension-yjs/src/yCursorPlugin.js +21 -13
  61. package/esm/extension-yjs/src/ySyncPlugin.d.ts +54 -91
  62. package/esm/extension-yjs/src/ySyncPlugin.d.ts.map +1 -1
  63. package/esm/extension-yjs/src/ySyncPlugin.js +99 -222
  64. package/esm/extension-yjs/src/yUndoPlugin.d.ts +21 -0
  65. package/esm/extension-yjs/src/yUndoPlugin.d.ts.map +1 -0
  66. package/esm/extension-yjs/src/yUndoPlugin.js +86 -0
  67. package/package.json +2 -4
  68. package/LICENSE +0 -23
  69. package/README.md +0 -57
  70. package/esm/package.json +0 -3
@@ -1,71 +1,33 @@
1
- /**
2
- * @module bindings/prosemirror
3
- */
1
+ import * as Y from 'yjs';
4
2
  import { createMutex } from 'lib0/mutex';
5
3
  import * as PModel from 'prosemirror-model';
6
- import { AllSelection, NodeSelection, Plugin, TextSelection, } from 'prosemirror-state'; // eslint-disable-line
4
+ import { AllSelection, NodeSelection, Plugin, TextSelection, } from 'prosemirror-state';
7
5
  import * as math from 'lib0/math';
8
6
  import * as object from 'lib0/object';
9
7
  import * as set from 'lib0/set';
10
8
  import { simpleDiff } from 'lib0/diff';
11
9
  import * as error from 'lib0/error';
12
- import { ySyncPluginKey, yUndoPluginKey } from 'y-prosemirror';
13
- import * as Y from 'yjs';
14
- import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, } from 'y-prosemirror';
15
10
  import * as random from 'lib0/random';
16
11
  import * as environment from 'lib0/environment';
17
12
  import * as dom from 'lib0/dom';
18
13
  import * as eventloop from 'lib0/eventloop';
19
14
  import * as map from 'lib0/map';
15
+ import { ySyncPluginKey, yUndoPluginKey } from './keys.js';
20
16
  import * as utils from './utils.js';
21
- /**
22
- * @typedef {Object} BindingMetadata
23
- * @property {ProsemirrorMapping} BindingMetadata.mapping
24
- * @property {Map<import('prosemirror-model').MarkType, boolean>} BindingMetadata.isOMark - is overlapping mark
25
- */
26
- /**
27
- * @return {BindingMetadata}
28
- */
17
+ import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, } from './lib.js';
29
18
  export const createEmptyMeta = () => ({
30
19
  mapping: new Map(),
31
20
  isOMark: new Map(),
32
21
  });
33
- /**
34
- * @param {Y.Item} item
35
- * @param {Y.Snapshot} [snapshot]
36
- */
37
22
  export const isVisible = (item, snapshot) => snapshot === undefined
38
23
  ? !item.deleted
39
24
  : (snapshot.sv.has(item.id.client) && /** @type {number} */
40
25
  (snapshot.sv.get(item.id.client)) > item.id.clock &&
41
26
  !Y.isDeleted(snapshot.ds, item.id));
42
- /**
43
- * Either a node if type is YXmlElement or an Array of text nodes if YXmlText
44
- * @typedef {Map<Y.AbstractType<any>, PModel.Node | Array<PModel.Node>>} ProsemirrorMapping
45
- */
46
- /**
47
- * @typedef {Object} ColorDef
48
- * @property {string} ColorDef.light
49
- * @property {string} ColorDef.dark
50
- */
51
- /**
52
- * @typedef {Object} YSyncOpts
53
- * @property {Array<ColorDef>} [YSyncOpts.colors]
54
- * @property {Map<string,ColorDef>} [YSyncOpts.colorMapping]
55
- * @property {Y.PermanentUserData|null} [YSyncOpts.permanentUserData]
56
- * @property {ProsemirrorMapping} [YSyncOpts.mapping]
57
- * @property {function} [YSyncOpts.onFirstRender] Fired when the content from Yjs is initially rendered to ProseMirror
58
- */
59
- /**
60
- * @type {Array<ColorDef>}
61
- */
62
- const defaultColors = [{ light: '#ecd44433', dark: '#ecd444' }];
63
- /**
64
- * @param {Map<string,ColorDef>} colorMapping
65
- * @param {Array<ColorDef>} colors
66
- * @param {string} user
67
- * @return {ColorDef}
68
- */
27
+ const defaultColors = [{
28
+ light: '#ecd44433',
29
+ dark: '#ecd444',
30
+ }];
69
31
  const getUserColor = (colorMapping, colors, user) => {
70
32
  // @todo do not hit the same color twice if possible
71
33
  if (!colorMapping.has(user)) {
@@ -82,11 +44,9 @@ const getUserColor = (colorMapping, colors, user) => {
82
44
  * This plugin listens to changes in prosemirror view and keeps yXmlState and view in sync.
83
45
  *
84
46
  * This plugin also keeps references to the type and the shared document so other plugins can access it.
85
- * @param {Y.XmlFragment} yXmlFragment
86
- * @param {YSyncOpts} opts
87
- * @return {any} Returns a prosemirror plugin that binds to this type
88
47
  */
89
- export const ySyncPlugin = (yXmlFragment, { colors = defaultColors, colorMapping = new Map(), permanentUserData = null, onFirstRender = () => { }, mapping, } = {}) => {
48
+ export const ySyncPlugin = (yXmlFragment, { colors = defaultColors, colorMapping = new Map(), permanentUserData = null, onFirstRender = () => {
49
+ }, mapping, } = {}) => {
90
50
  let initialContentChanged = false;
91
51
  const binding = new ProsemirrorBinding(yXmlFragment, mapping);
92
52
  const plugin = new Plugin({
@@ -178,10 +138,8 @@ export const ySyncPlugin = (yXmlFragment, { colors = defaultColors, colorMapping
178
138
  if (pluginState.addToHistory === false &&
179
139
  !pluginState.isChangeOrigin) {
180
140
  const yUndoPluginState = yUndoPluginKey.getState(view.state);
181
- /**
182
- * @type {Y.UndoManager}
183
- */
184
- const um = yUndoPluginState && yUndoPluginState.undoManager;
141
+ const um = yUndoPluginState &&
142
+ yUndoPluginState.undoManager;
185
143
  if (um) {
186
144
  um.stopCapturing();
187
145
  }
@@ -203,11 +161,6 @@ export const ySyncPlugin = (yXmlFragment, { colors = defaultColors, colorMapping
203
161
  });
204
162
  return plugin;
205
163
  };
206
- /**
207
- * @param {import('prosemirror-state').Transaction} tr
208
- * @param {ReturnType<typeof getRelativeSelection>} relSel
209
- * @param {ProsemirrorBinding} binding
210
- */
211
164
  const restoreRelativeSelection = (tr, relSel, binding) => {
212
165
  if (relSel !== null && relSel.anchor !== null && relSel.head !== null) {
213
166
  if (relSel.type === 'all') {
@@ -227,10 +180,6 @@ const restoreRelativeSelection = (tr, relSel, binding) => {
227
180
  }
228
181
  }
229
182
  };
230
- /**
231
- * @param {ProsemirrorBinding} pmbinding
232
- * @param {import('prosemirror-state').EditorState} state
233
- */
234
183
  export const getRelativeSelection = (pmbinding, state) => ({
235
184
  type: /** @type {any} */ (state.selection).jsonID,
236
185
  anchor: absolutePositionToRelativePosition(state.selection.anchor, pmbinding.type, pmbinding.mapping),
@@ -242,42 +191,101 @@ export const getRelativeSelection = (pmbinding, state) => ({
242
191
  * @protected
243
192
  */
244
193
  export class ProsemirrorBinding {
245
- /**
246
- * @param {Y.XmlFragment} yXmlFragment The bind source
247
- * @param {ProsemirrorMapping} mapping
248
- */
194
+ get beforeTransactionSelection() {
195
+ return this._beforeTransactionSelection;
196
+ }
197
+ set beforeTransactionSelection(value) {
198
+ this._beforeTransactionSelection = value;
199
+ }
249
200
  constructor(yXmlFragment, mapping = new Map()) {
201
+ Object.defineProperty(this, "doc", {
202
+ enumerable: true,
203
+ configurable: true,
204
+ writable: true,
205
+ value: void 0
206
+ });
207
+ Object.defineProperty(this, "type", {
208
+ enumerable: true,
209
+ configurable: true,
210
+ writable: true,
211
+ value: void 0
212
+ });
213
+ Object.defineProperty(this, "mux", {
214
+ enumerable: true,
215
+ configurable: true,
216
+ writable: true,
217
+ value: void 0
218
+ });
219
+ Object.defineProperty(this, "prosemirrorView", {
220
+ enumerable: true,
221
+ configurable: true,
222
+ writable: true,
223
+ value: void 0
224
+ });
225
+ Object.defineProperty(this, "isOMark", {
226
+ enumerable: true,
227
+ configurable: true,
228
+ writable: true,
229
+ value: void 0
230
+ });
231
+ Object.defineProperty(this, "_observeFunction", {
232
+ enumerable: true,
233
+ configurable: true,
234
+ writable: true,
235
+ value: void 0
236
+ });
237
+ Object.defineProperty(this, "mapping", {
238
+ enumerable: true,
239
+ configurable: true,
240
+ writable: true,
241
+ value: void 0
242
+ });
243
+ Object.defineProperty(this, "_beforeTransactionSelection", {
244
+ enumerable: true,
245
+ configurable: true,
246
+ writable: true,
247
+ value: void 0
248
+ });
249
+ Object.defineProperty(this, "beforeAllTransactions", {
250
+ enumerable: true,
251
+ configurable: true,
252
+ writable: true,
253
+ value: void 0
254
+ });
255
+ Object.defineProperty(this, "afterAllTransactions", {
256
+ enumerable: true,
257
+ configurable: true,
258
+ writable: true,
259
+ value: void 0
260
+ });
261
+ Object.defineProperty(this, "_domSelectionInView", {
262
+ enumerable: true,
263
+ configurable: true,
264
+ writable: true,
265
+ value: void 0
266
+ });
250
267
  this.type = yXmlFragment;
251
- /**
252
- * this will be set once the view is created
253
- * @type {any}
254
- */
255
268
  this.prosemirrorView = null;
256
269
  this.mux = createMutex();
257
270
  this.mapping = mapping;
258
271
  /**
259
272
  * Is overlapping mark - i.e. mark does not exclude itself.
260
- *
261
- * @type {Map<import('prosemirror-model').MarkType, boolean>}
262
273
  */
263
274
  this.isOMark = new Map();
264
275
  this._observeFunction = this._typeChanged.bind(this);
265
- /**
266
- * @type {Y.Doc}
267
- */
268
- // @ts-ignore
269
276
  this.doc = yXmlFragment.doc;
270
277
  /**
271
278
  * current selection as relative positions in the Yjs model
272
279
  */
273
- this.beforeTransactionSelection = null;
280
+ this._beforeTransactionSelection = null;
274
281
  this.beforeAllTransactions = () => {
275
- if (this.beforeTransactionSelection === null && this.prosemirrorView != null) {
276
- this.beforeTransactionSelection = getRelativeSelection(this, this.prosemirrorView.state);
282
+ if (this._beforeTransactionSelection === null &&
283
+ this.prosemirrorView != null) {
284
+ this._beforeTransactionSelection = getRelativeSelection(this, this.prosemirrorView.state);
277
285
  }
278
286
  };
279
287
  this.afterAllTransactions = () => {
280
- this.beforeTransactionSelection = null;
288
+ this._beforeTransactionSelection = null;
281
289
  };
282
290
  this._domSelectionInView = null;
283
291
  }
@@ -302,7 +310,7 @@ export class ProsemirrorBinding {
302
310
  return this._domSelectionInView;
303
311
  }
304
312
  _isDomSelectionInView() {
305
- const selection = this.prosemirrorView._root.getSelection();
313
+ const selection = this.prosemirrorView.root.getSelection(); // https://stackoverflow.com/questions/62054839/shadowroot-getselection
306
314
  if (selection == null || selection.anchorNode == null)
307
315
  return false;
308
316
  const range = dom.doc.createRange(); // https://github.com/yjs/y-prosemirror/pull/193
@@ -325,10 +333,6 @@ export class ProsemirrorBinding {
325
333
  (globalThis.innerWidth || documentElement.clientWidth || 0) &&
326
334
  bounding.top <= (globalThis.innerHeight || documentElement.clientHeight || 0);
327
335
  }
328
- /**
329
- * @param {Y.Snapshot} snapshot
330
- * @param {Y.Snapshot} prevSnapshot
331
- */
332
336
  renderSnapshot(snapshot, prevSnapshot) {
333
337
  if (!prevSnapshot) {
334
338
  prevSnapshot = Y.createSnapshot(Y.createDeleteSet(), new Map());
@@ -352,7 +356,7 @@ export class ProsemirrorBinding {
352
356
  // If this is a forced rerender, this might neither happen as a pm change nor within a Yjs
353
357
  // transaction. Then the "before selection" doesn't exist. In this case, we need to create a
354
358
  // relative position before replacing content. Fixes #126
355
- const sel = this.beforeTransactionSelection !== null
359
+ const sel = this._beforeTransactionSelection !== null
356
360
  ? null
357
361
  : this.prosemirrorView.state.selection;
358
362
  const fragmentContent = this.type.toArray().map((t) => createNodeFromYElement(
@@ -372,15 +376,9 @@ export class ProsemirrorBinding {
372
376
  this.prosemirrorView.dispatch(tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, binding: this }));
373
377
  });
374
378
  }
375
- /**
376
- * @param {Y.Snapshot|Uint8Array} snapshot
377
- * @param {Y.Snapshot|Uint8Array} prevSnapshot
378
- * @param {Object} pluginState
379
- */
380
379
  _renderSnapshot(snapshot, prevSnapshot, pluginState) {
381
380
  /**
382
381
  * The document that contains the full history of this document.
383
- * @type {Y.Doc}
384
382
  */
385
383
  let historyDoc = this.doc;
386
384
  let historyType = this.type;
@@ -432,10 +430,6 @@ export class ProsemirrorBinding {
432
430
  Y.iterateDeletedStructs(transaction, ds, (_item) => { });
433
431
  });
434
432
  }
435
- /**
436
- * @param {'removed'|'added'} type
437
- * @param {Y.ID} id
438
- */
439
433
  const computeYChange = (type, id) => {
440
434
  const user = type === 'added'
441
435
  ? pud.getUserByClientId(id.client)
@@ -464,10 +458,6 @@ export class ProsemirrorBinding {
464
458
  }, ySyncPluginKey);
465
459
  });
466
460
  }
467
- /**
468
- * @param {Array<Y.YEvent<any>>} events
469
- * @param {Y.Transaction} transaction
470
- */
471
461
  _typeChanged(events, transaction) {
472
462
  if (this.prosemirrorView == null)
473
463
  return;
@@ -479,10 +469,6 @@ export class ProsemirrorBinding {
479
469
  return;
480
470
  }
481
471
  this.mux(() => {
482
- /**
483
- * @param {any} _
484
- * @param {Y.AbstractType<any>} type
485
- */
486
472
  const delType = (_, type) => this.mapping.delete(type);
487
473
  Y.iterateDeletedStructs(transaction, transaction.deleteSet, (struct) => {
488
474
  if (struct.constructor === Y.Item) {
@@ -498,29 +484,25 @@ export class ProsemirrorBinding {
498
484
  /** @type {Y.XmlElement | Y.XmlHook} */ (t), this.prosemirrorView.state.schema, this)).filter((n) => n !== null);
499
485
  // @ts-ignore
500
486
  let tr = this._tr.replace(0, this.prosemirrorView.state.doc.content.size, new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0));
501
- restoreRelativeSelection(tr, this.beforeTransactionSelection, this);
487
+ restoreRelativeSelection(tr, this._beforeTransactionSelection, this);
502
488
  tr = tr.setMeta(ySyncPluginKey, {
503
489
  isChangeOrigin: true,
504
490
  isUndoRedoOperation: transaction.origin instanceof Y.UndoManager,
505
491
  });
506
- if (this.beforeTransactionSelection !== null && this._isLocalCursorInView()) {
492
+ if (this._beforeTransactionSelection !== null && this._isLocalCursorInView()) {
507
493
  tr.scrollIntoView();
508
494
  }
509
495
  this.prosemirrorView.dispatch(tr);
510
496
  });
511
497
  }
512
- /**
513
- * @param {import('prosemirror-model').Node} doc
514
- */
515
498
  _prosemirrorChanged(doc) {
516
499
  this.doc.transact(() => {
517
500
  updateYFragment(this.doc, this.type, doc, this);
518
- this.beforeTransactionSelection = getRelativeSelection(this, this.prosemirrorView.state);
501
+ this._beforeTransactionSelection = getRelativeSelection(this, this.prosemirrorView.state);
519
502
  }, ySyncPluginKey);
520
503
  }
521
504
  /**
522
505
  * View is ready to listen to changes. Register observers.
523
- * @param {any} prosemirrorView
524
506
  */
525
507
  initView(prosemirrorView) {
526
508
  if (this.prosemirrorView != null)
@@ -539,16 +521,6 @@ export class ProsemirrorBinding {
539
521
  this.doc.off('afterAllTransactions', this.afterAllTransactions);
540
522
  }
541
523
  }
542
- /**
543
- * @private
544
- * @param {Y.XmlElement | Y.XmlHook} el
545
- * @param {PModel.Schema} schema
546
- * @param {BindingMetadata} meta
547
- * @param {Y.Snapshot} [snapshot]
548
- * @param {Y.Snapshot} [prevSnapshot]
549
- * @param {function('removed' | 'added', Y.ID):any} [computeYChange]
550
- * @return {PModel.Node | null}
551
- */
552
524
  const createNodeIfNotExists = (el, schema, meta, snapshot, prevSnapshot, computeYChange) => {
553
525
  const node = /** @type {PModel.Node} */ (meta.mapping.get(el));
554
526
  if (node === undefined) {
@@ -561,21 +533,8 @@ const createNodeIfNotExists = (el, schema, meta, snapshot, prevSnapshot, compute
561
533
  }
562
534
  return node;
563
535
  };
564
- /**
565
- * @private
566
- * @param {Y.XmlElement} el
567
- * @param {any} schema
568
- * @param {BindingMetadata} meta
569
- * @param {Y.Snapshot} [snapshot]
570
- * @param {Y.Snapshot} [prevSnapshot]
571
- * @param {function('removed' | 'added', Y.ID):any} [computeYChange]
572
- * @return {PModel.Node | null} Returns node if node could be created. Otherwise it deletes the yjs type and returns null
573
- */
574
536
  export const createNodeFromYElement = (el, schema, meta, snapshot, prevSnapshot, computeYChange) => {
575
537
  const children = [];
576
- /**
577
- * @param {Y.XmlElement | Y.XmlText} type
578
- */
579
538
  const createChildren = (type) => {
580
539
  if (type instanceof Y.XmlElement) {
581
540
  const n = createNodeIfNotExists(type, schema, meta, snapshot, prevSnapshot, computeYChange);
@@ -646,13 +605,6 @@ export const createNodeFromYElement = (el, schema, meta, snapshot, prevSnapshot,
646
605
  };
647
606
  /**
648
607
  * @private
649
- * @param {Y.XmlText} text
650
- * @param {import('prosemirror-model').Schema} schema
651
- * @param {BindingMetadata} _meta
652
- * @param {Y.Snapshot} [snapshot]
653
- * @param {Y.Snapshot} [prevSnapshot]
654
- * @param {function('removed' | 'added', Y.ID):any} [computeYChange]
655
- * @return {Array<PModel.Node>|null}
656
608
  */
657
609
  const createTextNodesFromYText = (text, schema, _meta, snapshot, prevSnapshot, computeYChange) => {
658
610
  const nodes = [];
@@ -675,9 +627,6 @@ const createTextNodesFromYText = (text, schema, _meta, snapshot, prevSnapshot, c
675
627
  };
676
628
  /**
677
629
  * @private
678
- * @param {Array<any>} nodes prosemirror node
679
- * @param {BindingMetadata} meta
680
- * @return {Y.XmlText}
681
630
  */
682
631
  const createTypeFromTextNodes = (nodes, meta) => {
683
632
  const type = new Y.XmlText();
@@ -692,9 +641,6 @@ const createTypeFromTextNodes = (nodes, meta) => {
692
641
  };
693
642
  /**
694
643
  * @private
695
- * @param {any} node prosemirror node
696
- * @param {BindingMetadata} meta
697
- * @return {Y.XmlElement}
698
644
  */
699
645
  const createTypeFromElementNode = (node, meta) => {
700
646
  const type = new Y.XmlElement(node.type.name);
@@ -710,21 +656,11 @@ const createTypeFromElementNode = (node, meta) => {
710
656
  };
711
657
  /**
712
658
  * @private
713
- * @param {PModel.Node|Array<PModel.Node>} node prosemirror text node
714
- * @param {BindingMetadata} meta
715
- * @return {Y.XmlElement|Y.XmlText}
716
659
  */
717
660
  const createTypeFromTextOrElementNode = (node, meta) => node instanceof Array
718
661
  ? createTypeFromTextNodes(node, meta)
719
662
  : createTypeFromElementNode(node, meta);
720
- /**
721
- * @param {any} val
722
- */
723
663
  const isObject = (val) => typeof val === 'object' && val !== null;
724
- /**
725
- * @param {any} pattrs
726
- * @param {any} yattrs
727
- */
728
664
  const equalAttrs = (pattrs, yattrs) => {
729
665
  const keys = Object.keys(pattrs).filter((key) => pattrs[key] !== null);
730
666
  let eq = keys.length ===
@@ -740,13 +676,6 @@ const equalAttrs = (pattrs, yattrs) => {
740
676
  }
741
677
  return eq;
742
678
  };
743
- /**
744
- * @typedef {Array<Array<PModel.Node>|PModel.Node>} NormalizedPNodeContent
745
- */
746
- /**
747
- * @param {any} pnode
748
- * @return {NormalizedPNodeContent}
749
- */
750
679
  const normalizePNodeContent = (pnode) => {
751
680
  const c = pnode.content.content;
752
681
  const res = [];
@@ -766,25 +695,17 @@ const normalizePNodeContent = (pnode) => {
766
695
  }
767
696
  return res;
768
697
  };
769
- /**
770
- * @param {Y.XmlText} ytext
771
- * @param {Array<any>} ptexts
772
- */
773
698
  const equalYTextPText = (ytext, ptexts) => {
774
699
  const delta = ytext.toDelta();
775
700
  return delta.length === ptexts.length &&
776
- delta.every(/** @type {(d:any,i:number) => boolean} */ (d, i) => d.insert === /** @type {any} */ (ptexts[i]).text &&
701
+ delta.every((d, i) => d.insert === /** @type {any} */ (ptexts[i]).text &&
777
702
  object.keys(d.attributes || {}).length === ptexts[i].marks.length &&
778
703
  object.every(d.attributes, (attr, yattrname) => {
779
704
  const markname = yattr2markname(yattrname);
780
705
  const pmarks = ptexts[i].marks;
781
- return equalAttrs(attr, pmarks.find(/** @param {any} mark */ (mark) => mark.type.name === markname)?.attrs);
706
+ return equalAttrs(attr, pmarks.find((mark) => mark.type.name === markname)?.attrs);
782
707
  }));
783
708
  };
784
- /**
785
- * @param {Y.XmlElement|Y.XmlText|Y.XmlHook} ytype
786
- * @param {any|Array<any>} pnode
787
- */
788
709
  const equalYTypePNode = (ytype, pnode) => {
789
710
  if (ytype instanceof Y.XmlElement && !(pnode instanceof Array) &&
790
711
  matchNodeName(ytype, pnode)) {
@@ -796,20 +717,10 @@ const equalYTypePNode = (ytype, pnode) => {
796
717
  return ytype instanceof Y.XmlText && pnode instanceof Array &&
797
718
  equalYTextPText(ytype, pnode);
798
719
  };
799
- /**
800
- * @param {PModel.Node | Array<PModel.Node> | undefined} mapped
801
- * @param {PModel.Node | Array<PModel.Node>} pcontent
802
- */
803
720
  const mappedIdentity = (mapped, pcontent) => mapped === pcontent ||
804
721
  (mapped instanceof Array && pcontent instanceof Array &&
805
722
  mapped.length === pcontent.length &&
806
723
  mapped.every((a, i) => pcontent[i] === a));
807
- /**
808
- * @param {Y.XmlElement} ytype
809
- * @param {PModel.Node} pnode
810
- * @param {BindingMetadata} meta
811
- * @return {{ foundMappedChild: boolean, equalityFactor: number }}
812
- */
813
724
  const computeChildEqualityFactor = (ytype, pnode, meta) => {
814
725
  const yChildren = ytype.toArray();
815
726
  const pChildren = normalizePNodeContent(pnode);
@@ -844,9 +755,6 @@ const computeChildEqualityFactor = (ytype, pnode, meta) => {
844
755
  foundMappedChild,
845
756
  };
846
757
  };
847
- /**
848
- * @param {Y.Text} ytext
849
- */
850
758
  const ytextTrans = (ytext) => {
851
759
  let str = '';
852
760
  /**
@@ -872,10 +780,6 @@ const ytextTrans = (ytext) => {
872
780
  };
873
781
  /**
874
782
  * @todo test this more
875
- *
876
- * @param {Y.Text} ytext
877
- * @param {Array<any>} ptexts
878
- * @param {BindingMetadata} meta
879
783
  */
880
784
  const updateYText = (ytext, ptexts, meta) => {
881
785
  meta.mapping.set(ytext, ptexts);
@@ -890,20 +794,11 @@ const updateYText = (ytext, ptexts, meta) => {
890
794
  ytext.applyDelta(content.map((c) => ({ retain: c.insert.length, attributes: c.attributes })));
891
795
  };
892
796
  const hashedMarkNameRegex = /(.*)(--[a-zA-Z0-9+/=]{8})$/;
893
- /**
894
- * @param {string} attrName
895
- */
896
797
  export const yattr2markname = (attrName) => hashedMarkNameRegex.exec(attrName)?.[1] ?? attrName;
897
798
  /**
898
799
  * @todo move this to markstoattributes
899
- *
900
- * @param {Object<string, any>} attrs
901
- * @param {import('prosemirror-model').Schema} schema
902
800
  */
903
801
  export const attributesToMarks = (attrs, schema) => {
904
- /**
905
- * @type {Array<import('prosemirror-model').Mark>}
906
- */
907
802
  const marks = [];
908
803
  for (const markName in attrs) {
909
804
  // remove hashes if necessary
@@ -911,10 +806,6 @@ export const attributesToMarks = (attrs, schema) => {
911
806
  }
912
807
  return marks;
913
808
  };
914
- /**
915
- * @param {Array<import('prosemirror-model').Mark>} marks
916
- * @param {BindingMetadata} meta
917
- */
918
809
  const marksToAttributes = (marks, meta) => {
919
810
  const pattrs = {};
920
811
  marks.forEach((mark) => {
@@ -934,11 +825,6 @@ const marksToAttributes = (marks, meta) => {
934
825
  *
935
826
  * @private
936
827
  * @unstable
937
- *
938
- * @param {{transact: Function}} y
939
- * @param {Y.XmlFragment} yDomFragment
940
- * @param {any} pNode
941
- * @param {BindingMetadata} meta
942
828
  */
943
829
  export const updateYFragment = (y, yDomFragment, pNode, meta) => {
944
830
  if (yDomFragment instanceof Y.XmlElement &&
@@ -1022,13 +908,9 @@ export const updateYFragment = (y, yDomFragment, pNode, meta) => {
1022
908
  let updateRight = rightY instanceof Y.XmlElement &&
1023
909
  matchNodeName(rightY, rightP);
1024
910
  if (updateLeft && updateRight) {
1025
- // decide which which element to update
1026
- const equalityLeft = computeChildEqualityFactor(
1027
- /** @type {Y.XmlElement} */ (leftY),
1028
- /** @type {PModel.Node} */ (leftP), meta);
1029
- const equalityRight = computeChildEqualityFactor(
1030
- /** @type {Y.XmlElement} */ (rightY),
1031
- /** @type {PModel.Node} */ (rightP), meta);
911
+ // decide which element to update
912
+ const equalityLeft = computeChildEqualityFactor(leftY, leftP, meta);
913
+ const equalityRight = computeChildEqualityFactor(rightY, rightP, meta);
1032
914
  if (equalityLeft.foundMappedChild && !equalityRight.foundMappedChild) {
1033
915
  updateRight = false;
1034
916
  }
@@ -1084,9 +966,4 @@ export const updateYFragment = (y, yDomFragment, pNode, meta) => {
1084
966
  }
1085
967
  }, ySyncPluginKey);
1086
968
  };
1087
- /**
1088
- * @function
1089
- * @param {Y.XmlElement} yElement
1090
- * @param {any} pNode Prosemirror Node
1091
- */
1092
969
  const matchNodeName = (yElement, pNode) => !(pNode instanceof Array) && yElement.nodeName === pNode.type.name;
@@ -0,0 +1,21 @@
1
+ import { Command, EditorState, Plugin } from 'prosemirror-state';
2
+ import { UndoManager } from 'yjs';
3
+ import { getRelativeSelection } from './ySyncPlugin.js';
4
+ export interface UndoPluginState {
5
+ undoManager: UndoManager;
6
+ prevSel: ReturnType<typeof getRelativeSelection> | null;
7
+ hasUndoOps: boolean;
8
+ hasRedoOps: boolean;
9
+ }
10
+ export declare const undo: (state: EditorState) => boolean;
11
+ export declare const redo: (state: EditorState) => boolean;
12
+ export declare const undoCommand: Command;
13
+ export declare const redoCommand: Command;
14
+ export declare const defaultProtectedNodes: Set<string>;
15
+ export declare const defaultDeleteFilter: (item: import("yjs").Item, protectedNodes: Set<string>) => boolean;
16
+ export declare const yUndoPlugin: ({ protectedNodes, trackedOrigins, undoManager, }?: {
17
+ protectedNodes?: Set<string>;
18
+ trackedOrigins?: any[];
19
+ undoManager?: import("yjs").UndoManager | null;
20
+ }) => Plugin<any>;
21
+ //# sourceMappingURL=yUndoPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yUndoPlugin.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/yUndoPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAA2B,WAAW,EAAc,MAAM,KAAK,CAAC;AAEvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGxD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,GAAG,IAAI,CAAC;IACxD,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,IAAI,GAAI,OAAO,WAAW,KAAG,OACmB,CAAC;AAE9D,eAAO,MAAM,IAAI,GAAI,OAAO,WAAW,KAAG,OACmB,CAAC;AAE9D,eAAO,MAAM,WAAW,EAAE,OAGT,CAAC;AAElB,eAAO,MAAM,WAAW,EAAE,OAGT,CAAC;AAElB,eAAO,MAAM,qBAAqB,aAAyB,CAAC;AAE5D,eAAO,MAAM,mBAAmB,GAC9B,MAAM,OAAO,KAAK,EAAE,IAAI,EACxB,gBAAgB,GAAG,CAAC,MAAM,CAAC,KAC1B,OAM8B,CAAC;AAElC,eAAO,MAAM,WAAW,GAAI,mDAIzB;IACD,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CAC3C,gBAoEF,CAAC"}