@remirror/extension-yjs 1.0.19 → 1.0.23
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/declarations/src/yjs-extension.d.ts +12 -12
- package/dist/remirror-extension-yjs.browser.cjs.js +155 -55
- package/dist/remirror-extension-yjs.browser.esm.js +157 -57
- package/dist/remirror-extension-yjs.cjs.dev.js +155 -55
- package/dist/remirror-extension-yjs.cjs.prod.js +155 -55
- package/dist/remirror-extension-yjs.esm.js +157 -57
- package/package.json +4 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Doc } from 'yjs';
|
|
2
|
-
import { AcceptUndefined, EditorState, KeyBindingProps, NonChainableCommandFunction, OnSetOptionsProps, PlainExtension, ProsemirrorPlugin, Selection, Shape } from '@remirror/core';
|
|
2
|
+
import { AcceptUndefined, Dispose, EditorState, KeyBindingProps, NonChainableCommandFunction, OnSetOptionsProps, PlainExtension, ProsemirrorPlugin, Selection, Shape, Static } from '@remirror/core';
|
|
3
3
|
export interface ColorDef {
|
|
4
4
|
light: string;
|
|
5
5
|
dark: string;
|
|
@@ -54,13 +54,14 @@ export interface YjsOptions<Provider extends YjsRealtimeProvider = YjsRealtimePr
|
|
|
54
54
|
* @default `(state) => state.selection`
|
|
55
55
|
*/
|
|
56
56
|
getSelection?: (state: EditorState) => Selection;
|
|
57
|
+
disableUndo?: Static<boolean>;
|
|
57
58
|
/**
|
|
58
59
|
* Names of nodes in the editor which should be protected.
|
|
59
60
|
*
|
|
60
61
|
* @default `new Set('paragraph')`
|
|
61
62
|
*/
|
|
62
|
-
protectedNodes?: Set<string
|
|
63
|
-
trackedOrigins?: any[]
|
|
63
|
+
protectedNodes?: Static<Set<string>>;
|
|
64
|
+
trackedOrigins?: Static<any[]>;
|
|
64
65
|
}
|
|
65
66
|
/**
|
|
66
67
|
* The YJS extension is the recommended extension for creating a collaborative
|
|
@@ -73,7 +74,10 @@ export declare class YjsExtension extends PlainExtension<YjsOptions> {
|
|
|
73
74
|
* The provider that is being used for the editor.
|
|
74
75
|
*/
|
|
75
76
|
get provider(): YjsRealtimeProvider;
|
|
76
|
-
|
|
77
|
+
getBinding(): {
|
|
78
|
+
mapping: Map<any, any>;
|
|
79
|
+
} | undefined;
|
|
80
|
+
onView(): Dispose | void;
|
|
77
81
|
/**
|
|
78
82
|
* Create the yjs plugins.
|
|
79
83
|
*/
|
|
@@ -87,19 +91,17 @@ export declare class YjsExtension extends PlainExtension<YjsOptions> {
|
|
|
87
91
|
*/
|
|
88
92
|
onDestroy(): void;
|
|
89
93
|
/**
|
|
90
|
-
* Undo
|
|
91
|
-
*
|
|
92
|
-
* This should be used instead of the built in `undo` command.
|
|
94
|
+
* Undo that last Yjs transaction(s)
|
|
93
95
|
*
|
|
94
96
|
* This command does **not** support chaining.
|
|
97
|
+
* This command is a no-op and always returns `false` when the `disableUndo` option is set.
|
|
95
98
|
*/
|
|
96
99
|
yUndo(): NonChainableCommandFunction;
|
|
97
100
|
/**
|
|
98
|
-
* Redo
|
|
99
|
-
*
|
|
100
|
-
* This should be used instead of the built in `redo` command.
|
|
101
|
+
* Redo the last transaction undone with a previous `yUndo` command.
|
|
101
102
|
*
|
|
102
103
|
* This command does **not** support chaining.
|
|
104
|
+
* This command is a no-op and always returns `false` when the `disableUndo` option is set.
|
|
103
105
|
*/
|
|
104
106
|
yRedo(): NonChainableCommandFunction;
|
|
105
107
|
/**
|
|
@@ -110,8 +112,6 @@ export declare class YjsExtension extends PlainExtension<YjsOptions> {
|
|
|
110
112
|
* Handle the redo keybinding for the editor.
|
|
111
113
|
*/
|
|
112
114
|
redoShortcut(props: KeyBindingProps): boolean;
|
|
113
|
-
private absolutePositionToRelativePosition;
|
|
114
|
-
private relativePositionToAbsolutePosition;
|
|
115
115
|
}
|
|
116
116
|
/**
|
|
117
117
|
* The default destroy provider method.
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var _applyDecoratedDescriptor = require('@babel/runtime/helpers/applyDecoratedDescriptor');
|
|
6
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
7
|
+
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
|
|
6
8
|
var yProsemirror = require('y-prosemirror');
|
|
7
9
|
var yjs = require('yjs');
|
|
8
10
|
var core = require('@remirror/core');
|
|
@@ -10,6 +12,98 @@ var extensionAnnotation = require('@remirror/extension-annotation');
|
|
|
10
12
|
var messages = require('@remirror/messages');
|
|
11
13
|
|
|
12
14
|
var _dec, _dec2, _dec3, _dec4, _dec5, _class, _class2;
|
|
15
|
+
|
|
16
|
+
var _excluded = ["from", "to"],
|
|
17
|
+
_excluded2 = ["from", "to"];
|
|
18
|
+
|
|
19
|
+
class YjsAnnotationStore {
|
|
20
|
+
constructor(doc, pmName, mapName, getMapping) {
|
|
21
|
+
this.doc = doc;
|
|
22
|
+
this.getMapping = getMapping;
|
|
23
|
+
this.type = doc.getXmlFragment(pmName);
|
|
24
|
+
this.map = doc.getMap(mapName);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
addAnnotation(_ref) {
|
|
28
|
+
var from = _ref.from,
|
|
29
|
+
to = _ref.to,
|
|
30
|
+
data = _objectWithoutProperties(_ref, _excluded);
|
|
31
|
+
|
|
32
|
+
// XXX: Why is this cast needed?
|
|
33
|
+
var storedData = _objectSpread(_objectSpread({}, data), {}, {
|
|
34
|
+
from: this.absolutePositionToRelativePosition(from),
|
|
35
|
+
to: this.absolutePositionToRelativePosition(to)
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
this.map.set(data.id, storedData);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
updateAnnotation(id, updateData) {
|
|
42
|
+
var existing = this.map.get(id);
|
|
43
|
+
|
|
44
|
+
if (!existing) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this.map.set(id, _objectSpread(_objectSpread({}, updateData), {}, {
|
|
49
|
+
from: existing.from,
|
|
50
|
+
to: existing.to
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
removeAnnotations(ids) {
|
|
55
|
+
yjs.transact(this.doc, () => {
|
|
56
|
+
ids.forEach(id => this.map.delete(id));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
setAnnotations(annotations) {
|
|
61
|
+
yjs.transact(this.doc, () => {
|
|
62
|
+
this.map.clear();
|
|
63
|
+
annotations.forEach(annotation => this.addAnnotation(annotation));
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
formatAnnotations() {
|
|
68
|
+
var result = [];
|
|
69
|
+
this.map.forEach(_ref2 => {
|
|
70
|
+
var relFrom = _ref2.from,
|
|
71
|
+
relTo = _ref2.to,
|
|
72
|
+
data = _objectWithoutProperties(_ref2, _excluded2);
|
|
73
|
+
|
|
74
|
+
var from = this.relativePositionToAbsolutePosition(relFrom);
|
|
75
|
+
var to = this.relativePositionToAbsolutePosition(relTo);
|
|
76
|
+
|
|
77
|
+
if (!from || !to) {
|
|
78
|
+
return;
|
|
79
|
+
} // XXX: Why is this cast needed?
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
result.push(_objectSpread(_objectSpread({}, data), {}, {
|
|
83
|
+
from,
|
|
84
|
+
to
|
|
85
|
+
}));
|
|
86
|
+
});
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
absolutePositionToRelativePosition(pos) {
|
|
91
|
+
var mapping = this.getMapping();
|
|
92
|
+
return yProsemirror.absolutePositionToRelativePosition(pos, this.type, mapping);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
relativePositionToAbsolutePosition(relPos) {
|
|
96
|
+
var mapping = this.getMapping();
|
|
97
|
+
return yProsemirror.relativePositionToAbsolutePosition(this.doc, this.type, relPos, mapping);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The YJS extension is the recommended extension for creating a collaborative
|
|
103
|
+
* editor.
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
|
|
13
107
|
var YjsExtension = (_dec = core.extension({
|
|
14
108
|
defaultOptions: {
|
|
15
109
|
getProvider: () => {
|
|
@@ -23,29 +117,31 @@ var YjsExtension = (_dec = core.extension({
|
|
|
23
117
|
cursorBuilder: yProsemirror.defaultCursorBuilder,
|
|
24
118
|
cursorStateField: 'cursor',
|
|
25
119
|
getSelection: state => state.selection,
|
|
120
|
+
disableUndo: false,
|
|
26
121
|
protectedNodes: new Set('paragraph'),
|
|
27
122
|
trackedOrigins: []
|
|
28
123
|
},
|
|
124
|
+
staticKeys: ['disableUndo', 'protectedNodes', 'trackedOrigins'],
|
|
29
125
|
defaultPriority: core.ExtensionPriority.High
|
|
30
126
|
}), _dec2 = core.command({
|
|
31
127
|
disableChaining: true,
|
|
32
|
-
description:
|
|
33
|
-
var t =
|
|
128
|
+
description: _ref3 => {
|
|
129
|
+
var t = _ref3.t;
|
|
34
130
|
return t(messages.ExtensionHistoryMessages.UNDO_DESCRIPTION);
|
|
35
131
|
},
|
|
36
|
-
label:
|
|
37
|
-
var t =
|
|
132
|
+
label: _ref4 => {
|
|
133
|
+
var t = _ref4.t;
|
|
38
134
|
return t(messages.ExtensionHistoryMessages.UNDO_LABEL);
|
|
39
135
|
},
|
|
40
136
|
icon: 'arrowGoBackFill'
|
|
41
137
|
}), _dec3 = core.command({
|
|
42
138
|
disableChaining: true,
|
|
43
|
-
description:
|
|
44
|
-
var t =
|
|
139
|
+
description: _ref5 => {
|
|
140
|
+
var t = _ref5.t;
|
|
45
141
|
return t(messages.ExtensionHistoryMessages.REDO_DESCRIPTION);
|
|
46
142
|
},
|
|
47
|
-
label:
|
|
48
|
-
var t =
|
|
143
|
+
label: _ref6 => {
|
|
144
|
+
var t = _ref6.t;
|
|
49
145
|
return t(messages.ExtensionHistoryMessages.REDO_LABEL);
|
|
50
146
|
},
|
|
51
147
|
icon: 'arrowGoForwardFill'
|
|
@@ -70,14 +166,27 @@ var YjsExtension = (_dec = core.extension({
|
|
|
70
166
|
return (_this$_provider = this._provider) !== null && _this$_provider !== void 0 ? _this$_provider : this._provider = getLazyValue(getProvider);
|
|
71
167
|
}
|
|
72
168
|
|
|
169
|
+
getBinding() {
|
|
170
|
+
var state = this.store.getState();
|
|
171
|
+
|
|
172
|
+
var _ySyncPluginKey$getSt = yProsemirror.ySyncPluginKey.getState(state),
|
|
173
|
+
binding = _ySyncPluginKey$getSt.binding;
|
|
174
|
+
|
|
175
|
+
return binding;
|
|
176
|
+
}
|
|
177
|
+
|
|
73
178
|
onView() {
|
|
74
179
|
try {
|
|
180
|
+
var annotationStore = new YjsAnnotationStore(this.provider.doc, 'prosemirror', 'annotations', () => {
|
|
181
|
+
var _this$getBinding;
|
|
182
|
+
|
|
183
|
+
return (_this$getBinding = this.getBinding()) === null || _this$getBinding === void 0 ? void 0 : _this$getBinding.mapping;
|
|
184
|
+
});
|
|
75
185
|
this.store.manager.getExtension(extensionAnnotation.AnnotationExtension).setOptions({
|
|
76
|
-
|
|
77
|
-
transformPosition: this.absolutePositionToRelativePosition.bind(this),
|
|
78
|
-
transformPositionBeforeRender: this.relativePositionToAbsolutePosition.bind(this)
|
|
186
|
+
getStore: () => annotationStore
|
|
79
187
|
});
|
|
80
|
-
|
|
188
|
+
|
|
189
|
+
var handler = (_update, _origin, _doc, yjsTr) => {
|
|
81
190
|
var _this$store$commands$, _this$store$commands;
|
|
82
191
|
|
|
83
192
|
// Ignore own changes
|
|
@@ -86,7 +195,12 @@ var YjsExtension = (_dec = core.extension({
|
|
|
86
195
|
}
|
|
87
196
|
|
|
88
197
|
(_this$store$commands$ = (_this$store$commands = this.store.commands).redrawAnnotations) === null || _this$store$commands$ === void 0 ? void 0 : _this$store$commands$.call(_this$store$commands);
|
|
89
|
-
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
this.provider.doc.on('update', handler);
|
|
201
|
+
return () => {
|
|
202
|
+
this.provider.doc.off('update', handler);
|
|
203
|
+
};
|
|
90
204
|
} catch (_unused) {// AnnotationExtension isn't present in editor
|
|
91
205
|
}
|
|
92
206
|
}
|
|
@@ -101,21 +215,28 @@ var YjsExtension = (_dec = core.extension({
|
|
|
101
215
|
cursorBuilder = _this$options.cursorBuilder,
|
|
102
216
|
getSelection = _this$options.getSelection,
|
|
103
217
|
cursorStateField = _this$options.cursorStateField,
|
|
218
|
+
disableUndo = _this$options.disableUndo,
|
|
104
219
|
protectedNodes = _this$options.protectedNodes,
|
|
105
220
|
trackedOrigins = _this$options.trackedOrigins;
|
|
106
221
|
var yDoc = this.provider.doc;
|
|
107
222
|
var type = yDoc.getXmlFragment('prosemirror');
|
|
108
|
-
var
|
|
109
|
-
trackedOrigins: new Set([yProsemirror.ySyncPluginKey, ...trackedOrigins]),
|
|
110
|
-
deleteFilter: item => yProsemirror.defaultDeleteFilter(item, protectedNodes)
|
|
111
|
-
});
|
|
112
|
-
return [yProsemirror.ySyncPlugin(type, syncPluginOptions), yProsemirror.yCursorPlugin(this.provider.awareness, {
|
|
223
|
+
var plugins = [yProsemirror.ySyncPlugin(type, syncPluginOptions), yProsemirror.yCursorPlugin(this.provider.awareness, {
|
|
113
224
|
cursorBuilder,
|
|
114
225
|
cursorStateField,
|
|
115
226
|
getSelection
|
|
116
|
-
}, cursorStateField)
|
|
117
|
-
|
|
118
|
-
|
|
227
|
+
}, cursorStateField)];
|
|
228
|
+
|
|
229
|
+
if (!disableUndo) {
|
|
230
|
+
var undoManager = new yjs.UndoManager(type, {
|
|
231
|
+
trackedOrigins: new Set([yProsemirror.ySyncPluginKey, ...trackedOrigins]),
|
|
232
|
+
deleteFilter: item => yProsemirror.defaultDeleteFilter(item, protectedNodes)
|
|
233
|
+
});
|
|
234
|
+
plugins.push(yProsemirror.yUndoPlugin({
|
|
235
|
+
undoManager
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return plugins;
|
|
119
240
|
}
|
|
120
241
|
/**
|
|
121
242
|
* This managers the updates of the collaboration provider.
|
|
@@ -125,14 +246,7 @@ var YjsExtension = (_dec = core.extension({
|
|
|
125
246
|
onSetOptions(props) {
|
|
126
247
|
var changes = props.changes,
|
|
127
248
|
pickChanged = props.pickChanged;
|
|
128
|
-
var changedPluginOptions = pickChanged(['cursorBuilder', 'cursorStateField', 'getProvider', 'getSelection', 'syncPluginOptions'
|
|
129
|
-
|
|
130
|
-
if (changes.protectedNodes.changed || changes.trackedOrigins.changed) {
|
|
131
|
-
// Cannot change these, as we would need a new undo manager instance, and for that
|
|
132
|
-
// we would need to unregister the previous instance from the document to avoid
|
|
133
|
-
// memory leaks.
|
|
134
|
-
throw new Error("Cannot change \"protectedNodes\" or \"trackedOrigins\" options");
|
|
135
|
-
}
|
|
249
|
+
var changedPluginOptions = pickChanged(['cursorBuilder', 'cursorStateField', 'getProvider', 'getSelection', 'syncPluginOptions']);
|
|
136
250
|
|
|
137
251
|
if (changes.getProvider.changed) {
|
|
138
252
|
this._provider = undefined;
|
|
@@ -165,16 +279,19 @@ var YjsExtension = (_dec = core.extension({
|
|
|
165
279
|
this._provider = undefined;
|
|
166
280
|
}
|
|
167
281
|
/**
|
|
168
|
-
* Undo
|
|
169
|
-
*
|
|
170
|
-
* This should be used instead of the built in `undo` command.
|
|
282
|
+
* Undo that last Yjs transaction(s)
|
|
171
283
|
*
|
|
172
284
|
* This command does **not** support chaining.
|
|
285
|
+
* This command is a no-op and always returns `false` when the `disableUndo` option is set.
|
|
173
286
|
*/
|
|
174
287
|
|
|
175
288
|
|
|
176
289
|
yUndo() {
|
|
177
290
|
return core.nonChainable(props => {
|
|
291
|
+
if (this.options.disableUndo) {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
|
|
178
295
|
var state = props.state,
|
|
179
296
|
dispatch = props.dispatch;
|
|
180
297
|
var undoManager = yProsemirror.yUndoPluginKey.getState(state).undoManager;
|
|
@@ -191,16 +308,19 @@ var YjsExtension = (_dec = core.extension({
|
|
|
191
308
|
});
|
|
192
309
|
}
|
|
193
310
|
/**
|
|
194
|
-
* Redo
|
|
195
|
-
*
|
|
196
|
-
* This should be used instead of the built in `redo` command.
|
|
311
|
+
* Redo the last transaction undone with a previous `yUndo` command.
|
|
197
312
|
*
|
|
198
313
|
* This command does **not** support chaining.
|
|
314
|
+
* This command is a no-op and always returns `false` when the `disableUndo` option is set.
|
|
199
315
|
*/
|
|
200
316
|
|
|
201
317
|
|
|
202
318
|
yRedo() {
|
|
203
319
|
return core.nonChainable(props => {
|
|
320
|
+
if (this.options.disableUndo) {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
|
|
204
324
|
var state = props.state,
|
|
205
325
|
dispatch = props.dispatch;
|
|
206
326
|
var undoManager = yProsemirror.yUndoPluginKey.getState(state).undoManager;
|
|
@@ -233,26 +353,6 @@ var YjsExtension = (_dec = core.extension({
|
|
|
233
353
|
return this.yRedo()(props);
|
|
234
354
|
}
|
|
235
355
|
|
|
236
|
-
absolutePositionToRelativePosition(pos) {
|
|
237
|
-
var state = this.store.getState();
|
|
238
|
-
|
|
239
|
-
var _ySyncPluginKey$getSt = yProsemirror.ySyncPluginKey.getState(state),
|
|
240
|
-
type = _ySyncPluginKey$getSt.type,
|
|
241
|
-
binding = _ySyncPluginKey$getSt.binding;
|
|
242
|
-
|
|
243
|
-
return yProsemirror.absolutePositionToRelativePosition(pos, type, binding.mapping);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
relativePositionToAbsolutePosition(relPos) {
|
|
247
|
-
var state = this.store.getState();
|
|
248
|
-
|
|
249
|
-
var _ySyncPluginKey$getSt2 = yProsemirror.ySyncPluginKey.getState(state),
|
|
250
|
-
type = _ySyncPluginKey$getSt2.type,
|
|
251
|
-
binding = _ySyncPluginKey$getSt2.binding;
|
|
252
|
-
|
|
253
|
-
return yProsemirror.relativePositionToAbsolutePosition(this.provider.doc, type, relPos, binding.mapping);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
356
|
}, (_applyDecoratedDescriptor(_class2.prototype, "yUndo", [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "yUndo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "yRedo", [_dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "yRedo"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "undoShortcut", [_dec4], Object.getOwnPropertyDescriptor(_class2.prototype, "undoShortcut"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "redoShortcut", [_dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "redoShortcut"), _class2.prototype)), _class2)) || _class);
|
|
257
357
|
/**
|
|
258
358
|
* The default destroy provider method.
|