@kerebron/extension-yjs 0.3.2 → 0.4.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 (72) hide show
  1. package/README.md +26 -11
  2. package/esm/editor/src/CoreEditor.d.ts +13 -4
  3. package/esm/editor/src/CoreEditor.d.ts.map +1 -1
  4. package/esm/editor/src/CoreEditor.js +64 -12
  5. package/esm/editor/src/Extension.d.ts +6 -1
  6. package/esm/editor/src/Extension.d.ts.map +1 -1
  7. package/esm/editor/src/Extension.js +21 -1
  8. package/esm/editor/src/ExtensionManager.d.ts +5 -6
  9. package/esm/editor/src/ExtensionManager.d.ts.map +1 -1
  10. package/esm/editor/src/ExtensionManager.js +43 -55
  11. package/esm/editor/src/Mark.d.ts +3 -0
  12. package/esm/editor/src/Mark.d.ts.map +1 -1
  13. package/esm/editor/src/Mark.js +11 -0
  14. package/esm/editor/src/Node.d.ts +5 -2
  15. package/esm/editor/src/Node.d.ts.map +1 -1
  16. package/esm/editor/src/Node.js +13 -2
  17. package/esm/editor/src/commands/CommandManager.d.ts +13 -6
  18. package/esm/editor/src/commands/CommandManager.d.ts.map +1 -1
  19. package/esm/editor/src/commands/CommandManager.js +59 -2
  20. package/esm/editor/src/commands/baseCommandFactories.d.ts +3 -0
  21. package/esm/editor/src/commands/baseCommandFactories.d.ts.map +1 -0
  22. package/esm/editor/src/commands/baseCommandFactories.js +836 -0
  23. package/esm/editor/src/commands/keyCommandFactories.d.ts +3 -0
  24. package/esm/editor/src/commands/keyCommandFactories.d.ts.map +1 -0
  25. package/esm/editor/src/commands/keyCommandFactories.js +10 -0
  26. package/esm/editor/src/commands/mod.d.ts +5 -53
  27. package/esm/editor/src/commands/mod.d.ts.map +1 -1
  28. package/esm/editor/src/commands/mod.js +14 -821
  29. package/esm/editor/src/commands/replaceCommandFactories.d.ts +3 -0
  30. package/esm/editor/src/commands/replaceCommandFactories.d.ts.map +1 -0
  31. package/esm/editor/src/commands/replaceCommandFactories.js +94 -0
  32. package/esm/editor/src/commands/types.d.ts +18 -0
  33. package/esm/editor/src/commands/types.d.ts.map +1 -0
  34. package/esm/editor/src/commands/types.js +1 -0
  35. package/esm/editor/src/mod.d.ts +2 -0
  36. package/esm/editor/src/mod.d.ts.map +1 -1
  37. package/esm/editor/src/mod.js +2 -0
  38. package/esm/editor/src/plugins/TrackSelecionPlugin.d.ts +6 -0
  39. package/esm/editor/src/plugins/TrackSelecionPlugin.d.ts.map +1 -0
  40. package/esm/editor/src/plugins/TrackSelecionPlugin.js +24 -0
  41. package/esm/editor/src/types.d.ts +19 -1
  42. package/esm/editor/src/types.d.ts.map +1 -1
  43. package/esm/editor/src/ui.d.ts +15 -0
  44. package/esm/editor/src/ui.d.ts.map +1 -0
  45. package/esm/editor/src/ui.js +16 -0
  46. package/esm/editor/src/utilities/SmartOutput.d.ts +9 -7
  47. package/esm/editor/src/utilities/SmartOutput.d.ts.map +1 -1
  48. package/esm/editor/src/utilities/SmartOutput.js +35 -20
  49. package/esm/extension-basic-editor/src/remote-selection/ExtensionRemoteSelection.d.ts +24 -0
  50. package/esm/extension-basic-editor/src/remote-selection/ExtensionRemoteSelection.d.ts.map +1 -0
  51. package/esm/extension-basic-editor/src/remote-selection/ExtensionRemoteSelection.js +35 -0
  52. package/esm/extension-basic-editor/src/remote-selection/remoteSelectionPlugin.d.ts +25 -0
  53. package/esm/extension-basic-editor/src/remote-selection/remoteSelectionPlugin.d.ts.map +1 -0
  54. package/esm/extension-basic-editor/src/remote-selection/remoteSelectionPlugin.js +96 -0
  55. package/esm/extension-yjs/src/ExtensionYjs.d.ts +9 -4
  56. package/esm/extension-yjs/src/ExtensionYjs.d.ts.map +1 -1
  57. package/esm/extension-yjs/src/ExtensionYjs.js +12 -6
  58. package/esm/extension-yjs/src/keys.d.ts +0 -4
  59. package/esm/extension-yjs/src/keys.d.ts.map +1 -1
  60. package/esm/extension-yjs/src/keys.js +0 -4
  61. package/esm/extension-yjs/src/lib.d.ts.map +1 -1
  62. package/esm/extension-yjs/src/lib.js +0 -2
  63. package/esm/extension-yjs/src/yPositionPlugin.d.ts +14 -0
  64. package/esm/extension-yjs/src/yPositionPlugin.d.ts.map +1 -0
  65. package/esm/extension-yjs/src/yPositionPlugin.js +121 -0
  66. package/esm/extension-yjs/src/ySyncPlugin.d.ts +1 -1
  67. package/esm/extension-yjs/src/ySyncPlugin.d.ts.map +1 -1
  68. package/esm/extension-yjs/src/ySyncPlugin.js +13 -9
  69. package/package.json +1 -1
  70. package/esm/extension-yjs/src/yCursorPlugin.d.ts +0 -29
  71. package/esm/extension-yjs/src/yCursorPlugin.d.ts.map +0 -1
  72. package/esm/extension-yjs/src/yCursorPlugin.js +0 -177
@@ -1,12 +1,17 @@
1
- import type { Schema } from 'prosemirror-model';
2
1
  import type { Plugin } from 'prosemirror-state';
3
- import { type CoreEditor, Extension } from '../../editor/src/mod.js';
2
+ import * as awarenessProtocol from 'y-protocols/awareness';
3
+ import { Extension } from '../../editor/src/mod.js';
4
4
  import type { CommandFactories, CommandShortcuts } from '../../editor/src/commands/mod.js';
5
+ export interface YjsProvider {
6
+ on(eventName: string, callback: (event: any) => void): void;
7
+ awareness: awarenessProtocol.Awareness;
8
+ }
5
9
  export declare class ExtensionYjs extends Extension {
6
10
  name: string;
7
- doc: any;
11
+ conflicts: string[];
12
+ requires: string[];
8
13
  getCommandFactories(): Partial<CommandFactories>;
9
14
  getKeyboardShortcuts(): Partial<CommandShortcuts>;
10
- getProseMirrorPlugins(editor: CoreEditor, schema: Schema): Plugin[];
15
+ getProseMirrorPlugins(): Plugin[];
11
16
  }
12
17
  //# sourceMappingURL=ExtensionYjs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExtensionYjs.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/ExtensionYjs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,KAAK,UAAU,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAErE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,kCAAkC,CAAC;AAM1C,qBAAa,YAAa,SAAQ,SAAS;IACzC,IAAI,SAAS;IACb,GAAG,EAAE,GAAG,CAAC;IAGA,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAOhD,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAOjD,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;CAY7E"}
1
+ {"version":3,"file":"ExtensionYjs.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/ExtensionYjs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,kCAAkC,CAAC;AAM1C,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IAC5D,SAAS,EAAE,iBAAiB,CAAC,SAAS,CAAC;CACxC;AAED,qBAAa,YAAa,SAAQ,SAAS;IACzC,IAAI,SAAS;IAEJ,SAAS,WAAe;IACjC,QAAQ,WAAwB;IAGvB,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAOhD,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAOjD,qBAAqB,IAAI,MAAM,EAAE;CAY3C"}
@@ -1,6 +1,6 @@
1
1
  import { Extension } from '../../editor/src/mod.js';
2
2
  import { ySyncPlugin } from './ySyncPlugin.js';
3
- import { yCursorPlugin } from './yCursorPlugin.js';
3
+ import { yPositionPlugin } from './yPositionPlugin.js';
4
4
  import { redo, undo, yUndoPlugin } from './yUndoPlugin.js';
5
5
  import { initProseMirrorDoc } from './convertUtils.js';
6
6
  export class ExtensionYjs extends Extension {
@@ -12,11 +12,17 @@ export class ExtensionYjs extends Extension {
12
12
  writable: true,
13
13
  value: 'yjs'
14
14
  });
15
- Object.defineProperty(this, "doc", {
15
+ Object.defineProperty(this, "conflicts", {
16
16
  enumerable: true,
17
17
  configurable: true,
18
18
  writable: true,
19
- value: void 0
19
+ value: ['history']
20
+ });
21
+ Object.defineProperty(this, "requires", {
22
+ enumerable: true,
23
+ configurable: true,
24
+ writable: true,
25
+ value: ['remote-selection']
20
26
  });
21
27
  }
22
28
  // declare type Command = (state: EditorState, dispatch?: (tr: Transaction) => void, view?: EditorView) => boolean;
@@ -32,13 +38,13 @@ export class ExtensionYjs extends Extension {
32
38
  'Mod-y': 'redo',
33
39
  };
34
40
  }
35
- getProseMirrorPlugins(editor, schema) {
41
+ getProseMirrorPlugins() {
36
42
  const ydoc = this.config.ydoc;
37
43
  const fragment = ydoc.getXmlFragment('prosemirror');
38
- const { mapping } = initProseMirrorDoc(fragment, schema);
44
+ const { mapping } = initProseMirrorDoc(fragment, this.editor.schema);
39
45
  return [
40
46
  ySyncPlugin(fragment, { mapping }),
41
- yCursorPlugin(this.config.provider.awareness),
47
+ yPositionPlugin(this.config.provider.awareness, this.editor),
42
48
  yUndoPlugin(),
43
49
  ];
44
50
  }
@@ -8,8 +8,4 @@ export declare const ySyncPluginKey: PluginKey<any>;
8
8
  * The unique prosemirror plugin key for undoPlugin
9
9
  */
10
10
  export declare const yUndoPluginKey: PluginKey<UndoPluginState>;
11
- /**
12
- * The unique prosemirror plugin key for cursorPlugin
13
- */
14
- export declare const yCursorPluginKey: PluginKey<any>;
15
11
  //# sourceMappingURL=keys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,cAAc,gBAA0B,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,eAAe,CAErD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,gBAA8B,CAAC"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,cAAc,gBAA0B,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,eAAe,CAErD,CAAC"}
@@ -7,7 +7,3 @@ export const ySyncPluginKey = new PluginKey('y-sync');
7
7
  * The unique prosemirror plugin key for undoPlugin
8
8
  */
9
9
  export const yUndoPluginKey = new PluginKey('y-undo');
10
- /**
11
- * The unique prosemirror plugin key for cursorPlugin
12
- */
13
- export const yCursorPluginKey = new PluginKey('yjs-cursor');
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAI9C;;GAEG;AACH,KAAK,kBAAkB,GAAG,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AA2BzD,eAAO,MAAM,OAAO,GAAI,MAAM,UAAU,EAAE,QAAG,EAAE,UAAK,SAYnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kCAAkC,GAC7C,KAAK,MAAM,EACX,MAAM,CAAC,CAAC,WAAW,EACnB,SAAS,kBAAkB,KAC1B,GA+FF,CAAC;AAaF,eAAO,MAAM,kCAAkC,GAC7C,MAAM,CAAC,CAAC,GAAG,EACX,cAAc,CAAC,CAAC,WAAW,EAC3B,QAAQ,GAAG,EACX,SAAS,kBAAkB,KAC1B,IAAI,GAAG,MA6DT,CAAC"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAI9C;;GAEG;AACH,KAAK,kBAAkB,GAAG,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AA2BzD,eAAO,MAAM,OAAO,GAAI,MAAM,UAAU,EAAE,QAAG,EAAE,UAAK,SAYnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kCAAkC,GAC7C,KAAK,MAAM,EACX,MAAM,CAAC,CAAC,WAAW,EACnB,SAAS,kBAAkB,KAC1B,GA+FF,CAAC;AAaF,eAAO,MAAM,kCAAkC,GAC7C,MAAM,CAAC,CAAC,GAAG,EACX,cAAc,CAAC,CAAC,WAAW,EAC3B,QAAQ,GAAG,EACX,SAAS,kBAAkB,KAC1B,IAAI,GAAG,MA2DT,CAAC"}
@@ -159,12 +159,10 @@ export const relativePositionToAbsolutePosition = (yDoc, documentType, relPos, m
159
159
  pos += 1; // increase because we go out of n
160
160
  }
161
161
  while (type !== documentType && type._item !== null) {
162
- // @ts-ignore
163
162
  const parent = type._item.parent;
164
163
  if (parent instanceof Y.ID || parent === null) {
165
164
  continue;
166
165
  }
167
- // @ts-ignore
168
166
  if (parent._item === null || !parent._item.deleted) {
169
167
  pos += 1; // the start tag
170
168
  let n = /** @type {Y.AbstractType} */ (parent)._first;
@@ -0,0 +1,14 @@
1
+ import * as awarenessProtocol from 'y-protocols/awareness';
2
+ import { Plugin, PluginKey } from 'prosemirror-state';
3
+ import type { CoreEditor } from '../../editor/src/mod.js';
4
+ export declare const yPositionPluginKey: PluginKey<any>;
5
+ interface PositionPluginConfig {
6
+ getSelection?: (arg0: any) => any;
7
+ }
8
+ /**
9
+ * Default awareness state filter
10
+ */
11
+ export declare const defaultAwarenessStateFilter: (currentClientId: number, userClientId: number, _user: any) => boolean;
12
+ export declare const yPositionPlugin: (awareness: awarenessProtocol.Awareness, editor: CoreEditor, { getSelection, }?: PositionPluginConfig, cursorStateField?: string) => Plugin<any>;
13
+ export {};
14
+ //# sourceMappingURL=yPositionPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yPositionPlugin.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/yPositionPlugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAe,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAc1D,eAAO,MAAM,kBAAkB,gBAAgC,CAAC;AAYhE,UAAU,oBAAoB;IAC5B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED;;GAEG;AACH,eAAO,MAAM,2BAA2B,GACtC,iBAAiB,MAAM,EACvB,cAAc,MAAM,EACpB,OAAO,GAAG,KACT,OAA2C,CAAC;AAE/C,eAAO,MAAM,eAAe,GAC1B,WAAW,iBAAiB,CAAC,SAAS,EACtC,QAAQ,UAAU,EAClB,oBAEG,oBAAyB,EAC5B,mBAAkB,MAAiB,gBAiLpC,CAAC"}
@@ -0,0 +1,121 @@
1
+ import * as Y from 'yjs';
2
+ import { Plugin, PluginKey } from 'prosemirror-state';
3
+ import { remoteSelectionPluginKey } from '../../extension-basic-editor/src/remote-selection/ExtensionRemoteSelection.js';
4
+ import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta, } from './lib.js';
5
+ import { ySyncPluginKey } from './keys.js';
6
+ export const yPositionPluginKey = new PluginKey('yjs-position');
7
+ /**
8
+ * Default awareness state filter
9
+ */
10
+ export const defaultAwarenessStateFilter = (currentClientId, userClientId, _user) => currentClientId !== userClientId;
11
+ export const yPositionPlugin = (awareness, editor, { getSelection = (state) => state.selection, } = {}, cursorStateField = 'cursor') => {
12
+ return new Plugin({
13
+ key: yPositionPluginKey,
14
+ view: (view) => {
15
+ const extension = editor.getExtension('remote-selection');
16
+ const awarenessListener = ({ added, updated, removed }) => {
17
+ const clients = added.concat(updated).concat(removed);
18
+ if (clients.findIndex((id) => id !== awareness.doc.clientID) ===
19
+ -1) {
20
+ return;
21
+ }
22
+ if (view.docView) {
23
+ setMeta(view, remoteSelectionPluginKey, {
24
+ remotePositionUpdated: true,
25
+ });
26
+ }
27
+ const remoteStates = [];
28
+ const ystate = ySyncPluginKey.getState(view.state);
29
+ const y = ystate.doc;
30
+ awareness.getStates().forEach((aw, clientId) => {
31
+ if (!defaultAwarenessStateFilter(y.clientID, clientId, aw)) {
32
+ return;
33
+ }
34
+ if (!aw.cursor) {
35
+ return;
36
+ }
37
+ let anchor = relativePositionToAbsolutePosition(y, ystate.type, Y.createRelativePositionFromJSON(aw.cursor.anchor), ystate.binding.mapping);
38
+ let head = relativePositionToAbsolutePosition(y, ystate.type, Y.createRelativePositionFromJSON(aw.cursor.head), ystate.binding.mapping);
39
+ if (anchor !== null && head !== null) {
40
+ remoteStates.push({
41
+ clientId,
42
+ user: {
43
+ name: aw.user?.name,
44
+ color: aw.user?.color,
45
+ colorLight: aw.user?.colorLight,
46
+ },
47
+ cursor: {
48
+ anchor,
49
+ head,
50
+ },
51
+ });
52
+ }
53
+ });
54
+ extension.setRemoteStates(remoteStates);
55
+ // view.dispatch({ annotations: [yRemoteSelectionsAnnotation.of([])] });
56
+ };
57
+ {
58
+ // if (
59
+ // ystate.snapshot != null || ystate.prevSnapshot != null ||
60
+ // ystate.binding.mapping.size === 0
61
+ // ) {
62
+ // // do not render cursors while snapshot is active
63
+ // return DecorationSet.create(state.doc, []);
64
+ // }
65
+ }
66
+ const updateAwareness = (selectionAnchor, selectionHead) => {
67
+ const ystate = ySyncPluginKey.getState(view.state);
68
+ const current = awareness.getLocalState() || {};
69
+ const anchor = absolutePositionToRelativePosition(selectionAnchor, ystate.type, ystate.binding.mapping);
70
+ const head = absolutePositionToRelativePosition(selectionHead, ystate.type, ystate.binding.mapping);
71
+ if (current.cursor == null ||
72
+ !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.anchor), anchor) ||
73
+ !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.head), head)) {
74
+ awareness.setLocalStateField(cursorStateField, {
75
+ anchor,
76
+ head,
77
+ });
78
+ }
79
+ };
80
+ const clearAwareness = () => {
81
+ const ystate = ySyncPluginKey.getState(view.state);
82
+ const current = awareness.getLocalState() || {};
83
+ if (current.cursor != null &&
84
+ relativePositionToAbsolutePosition(ystate.doc, ystate.type, Y.createRelativePositionFromJSON(current.cursor.anchor), ystate.binding.mapping) !== null) {
85
+ // delete cursor information if current cursor information is owned by this editor binding
86
+ awareness.setLocalStateField(cursorStateField, null);
87
+ }
88
+ };
89
+ const updateCursorInfo = () => {
90
+ if (view.hasFocus()) {
91
+ const selection = getSelection(view.state);
92
+ updateAwareness(selection.anchor, selection.head);
93
+ }
94
+ else {
95
+ // clearAwareness();
96
+ }
97
+ };
98
+ const localPositionChangedListener = (event) => {
99
+ const { detail } = event;
100
+ updateAwareness(detail.anchor, detail.head);
101
+ };
102
+ editor.addEventListener('localPositionChanged', localPositionChangedListener);
103
+ awareness.on('change', awarenessListener);
104
+ view.dom.addEventListener('focusin', updateCursorInfo);
105
+ view.dom.addEventListener('focusout', updateCursorInfo);
106
+ return {
107
+ update: updateCursorInfo,
108
+ destroy: () => {
109
+ view.dom.removeEventListener('focusin', updateCursorInfo);
110
+ view.dom.removeEventListener('focusout', updateCursorInfo);
111
+ awareness.off('change', awarenessListener);
112
+ awareness.setLocalStateField(cursorStateField, null);
113
+ editor.removeEventListener('localPositionChanged', localPositionChangedListener);
114
+ },
115
+ };
116
+ },
117
+ updateCursorInfo(state) {
118
+ throw new Error('TODO: merge with updateCursorInfo above');
119
+ },
120
+ });
121
+ };
@@ -19,7 +19,7 @@ interface YSyncOpts {
19
19
  colorMapping?: Map<string, ColorDef>;
20
20
  permanentUserData?: Y.PermanentUserData | null;
21
21
  mapping?: ProsemirrorMapping;
22
- onFirstRender?: Function;
22
+ onFirstRender?: () => void;
23
23
  }
24
24
  /**
25
25
  * This plugin listens to changes in prosemirror view and keeps yXmlState and view in sync.
@@ -1 +1 @@
1
- {"version":3,"file":"ySyncPlugin.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/ySyncPlugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ySyncPlugin.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/ySyncPlugin.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ // deno-lint-ignore-file no-window
1
2
  import * as Y from 'yjs';
2
3
  import { createMutex } from 'lib0/mutex';
3
4
  import * as PModel from 'prosemirror-model';
@@ -12,6 +13,7 @@ import * as environment from 'lib0/environment';
12
13
  import * as dom from 'lib0/dom';
13
14
  import * as eventloop from 'lib0/eventloop';
14
15
  import * as map from 'lib0/map';
16
+ import { remoteSelectionPluginKey } from '../../extension-basic-editor/src/remote-selection/ExtensionRemoteSelection.js';
15
17
  import { ySyncPluginKey, yUndoPluginKey } from './keys.js';
16
18
  import * as utils from './utils.js';
17
19
  import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, } from './lib.js';
@@ -34,7 +36,7 @@ const getUserColor = (colorMapping, colors, user) => {
34
36
  }
35
37
  colorMapping.set(user, random.oneOf(colors));
36
38
  }
37
- return colorMapping.get(user);
39
+ return colorMapping.get(user) || defaultColors[0];
38
40
  };
39
41
  /**
40
42
  * This plugin listens to changes in prosemirror view and keeps yXmlState and view in sync.
@@ -350,7 +352,6 @@ export class ProsemirrorBinding {
350
352
  }
351
353
  const state = this.prosemirrorView.state;
352
354
  const fragmentContent = this.type.toArray().map((t) => createNodeFromYElement(t, state.schema, this)).filter((n) => n !== null);
353
- // @ts-ignore
354
355
  const _tr = state.tr.setMeta('addToHistory', false);
355
356
  const tr = _tr.replace(0, state.doc.content.size, new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0));
356
357
  tr.setMeta(ySyncPluginKey, { snapshot: null, prevSnapshot: null });
@@ -372,7 +373,6 @@ export class ProsemirrorBinding {
372
373
  : state.selection;
373
374
  const fragmentContent = this.type.toArray().map((t) => createNodeFromYElement(
374
375
  /** @type {Y.XmlElement} */ (t), state.schema, this)).filter((n) => n !== null);
375
- // @ts-ignore
376
376
  const _tr = state.tr.setMeta('addToHistory', false);
377
377
  const tr = _tr.replace(0, state.doc.content.size, new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0));
378
378
  if (sel) {
@@ -385,7 +385,8 @@ export class ProsemirrorBinding {
385
385
  const clampedHead = math.min(math.max(sel.head, 0), tr.doc.content.size);
386
386
  tr.setSelection(TextSelection.create(tr.doc, clampedAnchor, clampedHead));
387
387
  }
388
- this.prosemirrorView.dispatch(tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, binding: this }));
388
+ this.prosemirrorView.dispatch(tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, binding: this })
389
+ .setMeta(remoteSelectionPluginKey, { isChangeOrigin: true }));
389
390
  });
390
391
  }
391
392
  _renderSnapshot(snapshot, prevSnapshot, pluginState) {
@@ -454,6 +455,9 @@ export class ProsemirrorBinding {
454
455
  };
455
456
  // Create document fragment and render
456
457
  const fragmentContent = Y.typeListToArraySnapshot(historyType, new Y.Snapshot(prevSnapshot.ds, snapshot.sv)).map((t) => {
458
+ if (!this.prosemirrorView) {
459
+ return null;
460
+ }
457
461
  if (!t._item.deleted || isVisible(t._item, snapshot) ||
458
462
  isVisible(t._item, prevSnapshot)) {
459
463
  return createNodeFromYElement(t, this.prosemirrorView.state.schema, { mapping: new Map(), isOMark: new Map() }, snapshot, prevSnapshot, computeYChange);
@@ -464,9 +468,11 @@ export class ProsemirrorBinding {
464
468
  return null;
465
469
  }
466
470
  }).filter((n) => n !== null);
467
- const _tr = this.prosemirrorView.state.tr.setMeta('addToHistory', false);
468
- const tr = _tr.replace(0, this.prosemirrorView.state.doc.content.size, new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0));
469
- this.prosemirrorView.dispatch(tr.setMeta(ySyncPluginKey, { isChangeOrigin: true }));
471
+ if (this.prosemirrorView) {
472
+ const _tr = this.prosemirrorView.state.tr.setMeta('addToHistory', false);
473
+ const tr = _tr.replace(0, this.prosemirrorView.state.doc.content.size, new PModel.Slice(PModel.Fragment.from(fragmentContent), 0, 0));
474
+ this.prosemirrorView.dispatch(tr.setMeta(ySyncPluginKey, { isChangeOrigin: true }));
475
+ }
470
476
  }, ySyncPluginKey);
471
477
  });
472
478
  }
@@ -643,7 +649,6 @@ const createTextNodesFromYText = (text, schema, _meta, snapshot, prevSnapshot, c
643
649
  }, ySyncPluginKey);
644
650
  return null;
645
651
  }
646
- // @ts-ignore
647
652
  return nodes;
648
653
  };
649
654
  /**
@@ -652,7 +657,6 @@ const createTextNodesFromYText = (text, schema, _meta, snapshot, prevSnapshot, c
652
657
  const createTypeFromTextNodes = (nodes, meta) => {
653
658
  const type = new Y.XmlText();
654
659
  const delta = nodes.map((node) => ({
655
- // @ts-ignore
656
660
  insert: node.text,
657
661
  attributes: marksToAttributes(node.marks, meta),
658
662
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kerebron/extension-yjs",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "license": "MIT",
5
5
  "module": "./esm/extension-yjs/src/ExtensionYjs.js",
6
6
  "exports": {
@@ -1,29 +0,0 @@
1
- import * as awarenessProtocol from 'y-protocols/awareness';
2
- import { Plugin } from 'prosemirror-state';
3
- import { type DecorationAttrs } from 'prosemirror-view';
4
- /**
5
- * Default awareness state filter
6
- */
7
- export declare const defaultAwarenessStateFilter: (currentClientId: number, userClientId: number, _user: any) => boolean;
8
- /**
9
- * Default generator for a cursor element
10
- */
11
- export declare const defaultCursorBuilder: (user: any) => HTMLElement;
12
- /**
13
- * Default generator for the selection attributes
14
- */
15
- export declare const defaultSelectionBuilder: (user: any) => DecorationAttrs;
16
- export declare const createDecorations: (state: any, awareness: awarenessProtocol.Awareness, awarenessFilter: (arg0: number, arg1: number, arg2: any) => boolean, createCursor: (user: {
17
- name: string;
18
- color: string;
19
- }, clientId: number) => Element, createSelection: (user: {
20
- name: string;
21
- color: string;
22
- }, clientId: number) => DecorationAttrs) => any;
23
- export declare const yCursorPlugin: (awareness: awarenessProtocol.Awareness, { awarenessStateFilter, cursorBuilder, selectionBuilder, getSelection, }?: {
24
- awarenessStateFilter?: (arg0: any, arg1: any, arg2: any) => boolean;
25
- cursorBuilder?: (user: any, clientId: number) => HTMLElement;
26
- selectionBuilder?: (user: any, clientId: number) => DecorationAttrs;
27
- getSelection?: (arg0: any) => any;
28
- }, cursorStateField?: string) => Plugin<any>;
29
- //# sourceMappingURL=yCursorPlugin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"yCursorPlugin.d.ts","sourceRoot":"","sources":["../../../src/extension-yjs/src/yCursorPlugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAG3D,OAAO,EAAe,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAYxD;;GAEG;AACH,eAAO,MAAM,2BAA2B,GACtC,iBAAiB,MAAM,EACvB,cAAc,MAAM,EACpB,OAAO,GAAG,KACT,OAA2C,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM,GAAG,KAAG,WAahD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,MAAM,GAAG,KAAG,eAKnD,CAAC;AAIF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,GAAG,EACV,WAAW,iBAAiB,CAAC,SAAS,EACtC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,EACnE,cAAc,CACZ,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EACrC,QAAQ,EAAE,MAAM,KACb,OAAO,EACZ,iBAAiB,CACf,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EACrC,QAAQ,EAAE,MAAM,KACb,eAAe,KACnB,GA6DF,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,WAAW,iBAAiB,CAAC,SAAS,EACtC,2EAKG;IACD,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC;IACpE,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,WAAW,CAAC;IAC7D,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,eAAe,CAAC;IACpE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;CAC9B,EACN,mBAAkB,MAAiB,gBAsJpC,CAAC"}
@@ -1,177 +0,0 @@
1
- import * as Y from 'yjs';
2
- import { Decoration, DecorationSet } from 'prosemirror-view'; // eslint-disable-line
3
- import { Plugin } from 'prosemirror-state'; // eslint-disable-line
4
- import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta, } from './lib.js';
5
- import { yCursorPluginKey, ySyncPluginKey } from './keys.js';
6
- import * as math from 'lib0/math';
7
- /**
8
- * Default awareness state filter
9
- */
10
- export const defaultAwarenessStateFilter = (currentClientId, userClientId, _user) => currentClientId !== userClientId;
11
- /**
12
- * Default generator for a cursor element
13
- */
14
- export const defaultCursorBuilder = (user) => {
15
- const cursor = document.createElement('span');
16
- cursor.classList.add('kb-yjs__cursor');
17
- cursor.setAttribute('style', `border-color: ${user.color};`);
18
- const userDiv = document.createElement('div');
19
- userDiv.setAttribute('style', `background-color: ${user.color}`);
20
- userDiv.insertBefore(document.createTextNode(user.name), null);
21
- const nonbreakingSpace1 = document.createTextNode('\u2060');
22
- const nonbreakingSpace2 = document.createTextNode('\u2060');
23
- cursor.insertBefore(nonbreakingSpace1, null);
24
- cursor.insertBefore(userDiv, null);
25
- cursor.insertBefore(nonbreakingSpace2, null);
26
- return cursor;
27
- };
28
- /**
29
- * Default generator for the selection attributes
30
- */
31
- export const defaultSelectionBuilder = (user) => {
32
- return {
33
- style: `background-color: ${user.color}70`,
34
- class: 'kb-yjs__selection',
35
- };
36
- };
37
- const rxValidColor = /^#[0-9a-fA-F]{6}$/;
38
- export const createDecorations = (state, awareness, awarenessFilter, createCursor, createSelection) => {
39
- const ystate = ySyncPluginKey.getState(state);
40
- const y = ystate.doc;
41
- const decorations = [];
42
- if (ystate.snapshot != null || ystate.prevSnapshot != null ||
43
- ystate.binding.mapping.size === 0) {
44
- // do not render cursors while snapshot is active
45
- return DecorationSet.create(state.doc, []);
46
- }
47
- awareness.getStates().forEach((aw, clientId) => {
48
- if (!awarenessFilter(y.clientID, clientId, aw)) {
49
- return;
50
- }
51
- if (aw.cursor != null) {
52
- const user = aw.user || {};
53
- if (user.color == null) {
54
- user.color = '#ffa500';
55
- }
56
- else if (!rxValidColor.test(user.color)) {
57
- // We only support 6-digit RGB colors in y-prosemirror
58
- console.warn('A user uses an unsupported color format', user);
59
- }
60
- if (user.name == null) {
61
- user.name = `User: ${clientId}`;
62
- }
63
- let anchor = relativePositionToAbsolutePosition(y, ystate.type, Y.createRelativePositionFromJSON(aw.cursor.anchor), ystate.binding.mapping);
64
- let head = relativePositionToAbsolutePosition(y, ystate.type, Y.createRelativePositionFromJSON(aw.cursor.head), ystate.binding.mapping);
65
- if (anchor !== null && head !== null) {
66
- const maxsize = math.max(state.doc.content.size - 1, 0);
67
- anchor = math.min(anchor, maxsize);
68
- head = math.min(head, maxsize);
69
- decorations.push(Decoration.widget(head, () => createCursor(user, clientId), {
70
- key: clientId + '',
71
- side: 10,
72
- }));
73
- const from = math.min(anchor, head);
74
- const to = math.max(anchor, head);
75
- decorations.push(Decoration.inline(from, to, createSelection(user, clientId), {
76
- inclusiveEnd: true,
77
- inclusiveStart: false,
78
- }));
79
- }
80
- }
81
- });
82
- return DecorationSet.create(state.doc, decorations);
83
- };
84
- export const yCursorPlugin = (awareness, { awarenessStateFilter = defaultAwarenessStateFilter, cursorBuilder = defaultCursorBuilder, selectionBuilder = defaultSelectionBuilder, getSelection = (state) => state.selection, } = {}, cursorStateField = 'cursor') => {
85
- return new Plugin({
86
- key: yCursorPluginKey,
87
- state: {
88
- init(_, state) {
89
- return createDecorations(state, awareness, awarenessStateFilter, cursorBuilder, selectionBuilder);
90
- },
91
- apply(tr, prevState, _oldState, newState) {
92
- const ystate = ySyncPluginKey.getState(newState);
93
- const yCursorState = tr.getMeta(yCursorPluginKey);
94
- if ((ystate && ystate.isChangeOrigin) ||
95
- (yCursorState && yCursorState.awarenessUpdated)) {
96
- return createDecorations(newState, awareness, awarenessStateFilter, cursorBuilder, selectionBuilder);
97
- }
98
- return prevState.map(tr.mapping, tr.doc);
99
- },
100
- },
101
- props: {
102
- decorations: (state) => {
103
- return yCursorPluginKey.getState(state);
104
- },
105
- },
106
- view: (view) => {
107
- const awarenessListener = () => {
108
- // @ts-ignore
109
- if (view.docView) {
110
- setMeta(view, yCursorPluginKey, { awarenessUpdated: true });
111
- }
112
- };
113
- const updateCursorInfo = () => {
114
- const ystate = ySyncPluginKey.getState(view.state);
115
- // @note We make implicit checks when checking for the cursor property
116
- const current = awareness.getLocalState() || {};
117
- const selection = getSelection(view.state);
118
- if (view.hasFocus()) {
119
- const selection = getSelection(view.state);
120
- /**
121
- * @type {Y.RelativePosition}
122
- */
123
- const anchor = absolutePositionToRelativePosition(selection.anchor, ystate.type, ystate.binding.mapping);
124
- /**
125
- * @type {Y.RelativePosition}
126
- */
127
- const head = absolutePositionToRelativePosition(selection.head, ystate.type, ystate.binding.mapping);
128
- if (current.cursor == null ||
129
- !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.anchor), anchor) ||
130
- !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.head), head)) {
131
- awareness.setLocalStateField(cursorStateField, {
132
- anchor,
133
- head,
134
- });
135
- awareness.setLocalStateField('cm-cursor', null);
136
- }
137
- }
138
- else if (current.cursor != null &&
139
- relativePositionToAbsolutePosition(ystate.doc, ystate.type, Y.createRelativePositionFromJSON(current.cursor.anchor), ystate.binding.mapping) !== null) {
140
- // delete cursor information if current cursor information is owned by this editor binding
141
- awareness.setLocalStateField(cursorStateField, null);
142
- }
143
- };
144
- awareness.on('change', awarenessListener);
145
- view.dom.addEventListener('focusin', updateCursorInfo);
146
- view.dom.addEventListener('focusout', updateCursorInfo);
147
- return {
148
- update: updateCursorInfo,
149
- destroy: () => {
150
- view.dom.removeEventListener('focusin', updateCursorInfo);
151
- view.dom.removeEventListener('focusout', updateCursorInfo);
152
- awareness.off('change', awarenessListener);
153
- awareness.setLocalStateField(cursorStateField, null);
154
- },
155
- };
156
- },
157
- updateCursorInfo(state) {
158
- const ystate = ySyncPluginKey.getState(state);
159
- // @note We make implicit checks when checking for the cursor property
160
- const current = awareness.getLocalState() || {};
161
- const selection = getSelection(state);
162
- const anchor = absolutePositionToRelativePosition(selection.anchor, ystate.type, ystate.binding.mapping);
163
- const head = absolutePositionToRelativePosition(selection.head, ystate.type, ystate.binding.mapping);
164
- if (current.cursor == null ||
165
- !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.anchor), anchor) ||
166
- !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.head), head)) {
167
- awareness.setLocalStateField(cursorStateField, {
168
- anchor,
169
- head,
170
- });
171
- awareness.setLocalStateField('cm-cursor', null);
172
- }
173
- // delete cursor information if current cursor information is owned by this editor binding
174
- // awareness.setLocalStateField(cursorStateField, null);
175
- },
176
- });
177
- };