@lexical/react 0.7.7 → 0.7.9
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/DEPRECATED_useLexical.dev.js +3 -4
- package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +1 -3
- package/DEPRECATED_useLexicalCharacterLimit.dev.js +7 -39
- package/DEPRECATED_useLexicalEditor.dev.js +1 -3
- package/DEPRECATED_useLexicalPlainText.dev.js +4 -1
- package/DEPRECATED_useLexicalRichText.dev.js +4 -1
- package/LexicalAutoEmbedPlugin.dev.js +0 -11
- package/LexicalAutoFocusPlugin.dev.js +0 -1
- package/LexicalAutoLinkPlugin.dev.js +7 -50
- package/LexicalBlockWithAlignableContents.dev.js +0 -11
- package/LexicalCharacterLimitPlugin.dev.js +7 -46
- package/LexicalCheckListPlugin.dev.js +10 -48
- package/LexicalClearEditorPlugin.dev.js +1 -1
- package/LexicalCollaborationContext.dev.js +0 -3
- package/LexicalCollaborationPlugin.dev.js +6 -34
- package/LexicalComposer.dev.js +6 -10
- package/LexicalComposerContext.dev.js +0 -6
- package/LexicalContentEditable.dev.js +3 -1
- package/LexicalDecoratorBlockNode.dev.js +0 -5
- package/LexicalHashtagPlugin.dev.js +73 -43
- package/LexicalHorizontalRuleNode.dev.js +0 -22
- package/LexicalHorizontalRulePlugin.dev.js +0 -4
- package/LexicalLinkPlugin.dev.js +4 -10
- package/LexicalListPlugin.dev.js +0 -2
- package/LexicalMarkdownShortcutPlugin.dev.js +2 -2
- package/LexicalNestedComposer.dev.js +6 -11
- package/LexicalNodeEventPlugin.dev.js +5 -3
- package/LexicalOnChangePlugin.dev.js +1 -1
- package/LexicalPlainTextPlugin.dev.js +8 -12
- package/LexicalRichTextPlugin.dev.js +8 -12
- package/LexicalTabIndentationPlugin.dev.js +1 -3
- package/LexicalTableOfContents__EXPERIMENTAL.dev.js +5 -33
- package/LexicalTablePlugin.dev.js +5 -19
- package/LexicalTreeView.dev.js +12 -61
- package/LexicalTypeaheadMenuPlugin.dev.js +23 -108
- package/LexicalTypeaheadMenuPlugin.prod.js +18 -18
- package/package.json +19 -19
- package/useLexicalEditable.dev.js +1 -5
- package/useLexicalIsTextContentEmpty.dev.js +1 -0
- package/useLexicalNodeSelection.dev.js +0 -7
- package/useLexicalSubscription.dev.js +1 -3
|
@@ -45,16 +45,13 @@ function useCharacterLimit(editor, maxCharacters, optional = Object.freeze({}))
|
|
|
45
45
|
}) => {
|
|
46
46
|
const isComposing = editor.isComposing();
|
|
47
47
|
const hasDirtyLeaves = dirtyLeaves.size > 0;
|
|
48
|
-
|
|
49
48
|
if (isComposing || !hasDirtyLeaves) {
|
|
50
49
|
return;
|
|
51
50
|
}
|
|
52
|
-
|
|
53
51
|
const textLength = strlen(text$1);
|
|
54
52
|
const textLengthAboveThreshold = textLength > maxCharacters || lastComputedTextLength !== null && lastComputedTextLength > maxCharacters;
|
|
55
53
|
const diff = maxCharacters - textLength;
|
|
56
54
|
remainingCharacters(diff);
|
|
57
|
-
|
|
58
55
|
if (lastComputedTextLength === null || textLengthAboveThreshold) {
|
|
59
56
|
const offset = findOffset(text$1, maxCharacters, strlen);
|
|
60
57
|
editor.update(() => {
|
|
@@ -63,75 +60,62 @@ function useCharacterLimit(editor, maxCharacters, optional = Object.freeze({}))
|
|
|
63
60
|
tag: 'history-merge'
|
|
64
61
|
});
|
|
65
62
|
}
|
|
66
|
-
|
|
67
63
|
lastComputedTextLength = textLength;
|
|
68
64
|
}));
|
|
69
65
|
}, [editor, maxCharacters, remainingCharacters, strlen]);
|
|
70
66
|
}
|
|
71
|
-
|
|
72
67
|
function findOffset(text, maxCharacters, strlen) {
|
|
73
68
|
// @ts-ignore This is due to be added in a later version of TS
|
|
74
69
|
const Segmenter = Intl.Segmenter;
|
|
75
70
|
let offsetUtf16 = 0;
|
|
76
71
|
let offset = 0;
|
|
77
|
-
|
|
78
72
|
if (typeof Segmenter === 'function') {
|
|
79
73
|
const segmenter = new Segmenter();
|
|
80
74
|
const graphemes = segmenter.segment(text);
|
|
81
|
-
|
|
82
75
|
for (const {
|
|
83
76
|
segment: grapheme
|
|
84
77
|
} of graphemes) {
|
|
85
78
|
const nextOffset = offset + strlen(grapheme);
|
|
86
|
-
|
|
87
79
|
if (nextOffset > maxCharacters) {
|
|
88
80
|
break;
|
|
89
81
|
}
|
|
90
|
-
|
|
91
82
|
offset = nextOffset;
|
|
92
83
|
offsetUtf16 += grapheme.length;
|
|
93
84
|
}
|
|
94
85
|
} else {
|
|
95
86
|
const codepoints = Array.from(text);
|
|
96
87
|
const codepointsLength = codepoints.length;
|
|
97
|
-
|
|
98
88
|
for (let i = 0; i < codepointsLength; i++) {
|
|
99
89
|
const codepoint = codepoints[i];
|
|
100
90
|
const nextOffset = offset + strlen(codepoint);
|
|
101
|
-
|
|
102
91
|
if (nextOffset > maxCharacters) {
|
|
103
92
|
break;
|
|
104
93
|
}
|
|
105
|
-
|
|
106
94
|
offset = nextOffset;
|
|
107
95
|
offsetUtf16 += codepoint.length;
|
|
108
96
|
}
|
|
109
97
|
}
|
|
110
|
-
|
|
111
98
|
return offsetUtf16;
|
|
112
99
|
}
|
|
113
|
-
|
|
114
100
|
function $wrapOverflowedNodes(offset) {
|
|
115
101
|
const dfsNodes = utils.$dfs();
|
|
116
102
|
const dfsNodesLength = dfsNodes.length;
|
|
117
103
|
let accumulatedLength = 0;
|
|
118
|
-
|
|
119
104
|
for (let i = 0; i < dfsNodesLength; i += 1) {
|
|
120
105
|
const {
|
|
121
106
|
node
|
|
122
107
|
} = dfsNodes[i];
|
|
123
|
-
|
|
124
108
|
if (overflow.$isOverflowNode(node)) {
|
|
125
109
|
const previousLength = accumulatedLength;
|
|
126
110
|
const nextLength = accumulatedLength + node.getTextContentSize();
|
|
127
|
-
|
|
128
111
|
if (nextLength <= offset) {
|
|
129
112
|
const parent = node.getParent();
|
|
130
113
|
const previousSibling = node.getPreviousSibling();
|
|
131
114
|
const nextSibling = node.getNextSibling();
|
|
132
115
|
$unwrapNode(node);
|
|
133
|
-
const selection = lexical.$getSelection();
|
|
116
|
+
const selection = lexical.$getSelection();
|
|
134
117
|
|
|
118
|
+
// Restore selection when the overflow children are removed
|
|
135
119
|
if (lexical.$isRangeSelection(selection) && (!selection.anchor.getNode().isAttached() || !selection.focus.getNode().isAttached())) {
|
|
136
120
|
if (lexical.$isTextNode(previousSibling)) {
|
|
137
121
|
previousSibling.select();
|
|
@@ -144,12 +128,11 @@ function $wrapOverflowedNodes(offset) {
|
|
|
144
128
|
} else if (previousLength < offset) {
|
|
145
129
|
const descendant = node.getFirstDescendant();
|
|
146
130
|
const descendantLength = descendant !== null ? descendant.getTextContentSize() : 0;
|
|
147
|
-
const previousPlusDescendantLength = previousLength + descendantLength;
|
|
131
|
+
const previousPlusDescendantLength = previousLength + descendantLength;
|
|
132
|
+
// For simple text we can redimension the overflow into a smaller and more accurate
|
|
148
133
|
// container
|
|
149
|
-
|
|
150
134
|
const firstDescendantIsSimpleText = lexical.$isTextNode(descendant) && descendant.isSimpleText();
|
|
151
135
|
const firstDescendantDoesNotOverflow = previousPlusDescendantLength <= offset;
|
|
152
|
-
|
|
153
136
|
if (firstDescendantIsSimpleText || firstDescendantDoesNotOverflow) {
|
|
154
137
|
$unwrapNode(node);
|
|
155
138
|
}
|
|
@@ -157,59 +140,49 @@ function $wrapOverflowedNodes(offset) {
|
|
|
157
140
|
} else if (lexical.$isLeafNode(node)) {
|
|
158
141
|
const previousAccumulatedLength = accumulatedLength;
|
|
159
142
|
accumulatedLength += node.getTextContentSize();
|
|
160
|
-
|
|
161
143
|
if (accumulatedLength > offset && !overflow.$isOverflowNode(node.getParent())) {
|
|
162
144
|
const previousSelection = lexical.$getSelection();
|
|
163
|
-
let overflowNode;
|
|
164
|
-
// on the split point
|
|
145
|
+
let overflowNode;
|
|
165
146
|
|
|
147
|
+
// For simple text we can improve the limit accuracy by splitting the TextNode
|
|
148
|
+
// on the split point
|
|
166
149
|
if (previousAccumulatedLength < offset && lexical.$isTextNode(node) && node.isSimpleText()) {
|
|
167
150
|
const [, overflowedText] = node.splitText(offset - previousAccumulatedLength);
|
|
168
151
|
overflowNode = $wrapNode(overflowedText);
|
|
169
152
|
} else {
|
|
170
153
|
overflowNode = $wrapNode(node);
|
|
171
154
|
}
|
|
172
|
-
|
|
173
155
|
if (previousSelection !== null) {
|
|
174
156
|
lexical.$setSelection(previousSelection);
|
|
175
157
|
}
|
|
176
|
-
|
|
177
158
|
mergePrevious(overflowNode);
|
|
178
159
|
}
|
|
179
160
|
}
|
|
180
161
|
}
|
|
181
162
|
}
|
|
182
|
-
|
|
183
163
|
function $wrapNode(node) {
|
|
184
164
|
const overflowNode = overflow.$createOverflowNode();
|
|
185
165
|
node.insertBefore(overflowNode);
|
|
186
166
|
overflowNode.append(node);
|
|
187
167
|
return overflowNode;
|
|
188
168
|
}
|
|
189
|
-
|
|
190
169
|
function $unwrapNode(node) {
|
|
191
170
|
const children = node.getChildren();
|
|
192
171
|
const childrenLength = children.length;
|
|
193
|
-
|
|
194
172
|
for (let i = 0; i < childrenLength; i++) {
|
|
195
173
|
node.insertBefore(children[i]);
|
|
196
174
|
}
|
|
197
|
-
|
|
198
175
|
node.remove();
|
|
199
176
|
return childrenLength > 0 ? children[childrenLength - 1] : null;
|
|
200
177
|
}
|
|
201
|
-
|
|
202
178
|
function mergePrevious(overflowNode) {
|
|
203
179
|
const previousNode = overflowNode.getPreviousSibling();
|
|
204
|
-
|
|
205
180
|
if (!overflow.$isOverflowNode(previousNode)) {
|
|
206
181
|
return;
|
|
207
182
|
}
|
|
208
|
-
|
|
209
183
|
const firstChild = overflowNode.getFirstChild();
|
|
210
184
|
const previousNodeChildren = previousNode.getChildren();
|
|
211
185
|
const previousNodeChildrenLength = previousNodeChildren.length;
|
|
212
|
-
|
|
213
186
|
if (firstChild === null) {
|
|
214
187
|
overflowNode.append(...previousNodeChildren);
|
|
215
188
|
} else {
|
|
@@ -217,28 +190,23 @@ function mergePrevious(overflowNode) {
|
|
|
217
190
|
firstChild.insertBefore(previousNodeChildren[i]);
|
|
218
191
|
}
|
|
219
192
|
}
|
|
220
|
-
|
|
221
193
|
const selection = lexical.$getSelection();
|
|
222
|
-
|
|
223
194
|
if (lexical.$isRangeSelection(selection)) {
|
|
224
195
|
const anchor = selection.anchor;
|
|
225
196
|
const anchorNode = anchor.getNode();
|
|
226
197
|
const focus = selection.focus;
|
|
227
198
|
const focusNode = anchor.getNode();
|
|
228
|
-
|
|
229
199
|
if (anchorNode.is(previousNode)) {
|
|
230
200
|
anchor.set(overflowNode.getKey(), anchor.offset, 'element');
|
|
231
201
|
} else if (anchorNode.is(overflowNode)) {
|
|
232
202
|
anchor.set(overflowNode.getKey(), previousNodeChildrenLength + anchor.offset, 'element');
|
|
233
203
|
}
|
|
234
|
-
|
|
235
204
|
if (focusNode.is(previousNode)) {
|
|
236
205
|
focus.set(overflowNode.getKey(), focus.offset, 'element');
|
|
237
206
|
} else if (focusNode.is(overflowNode)) {
|
|
238
207
|
focus.set(overflowNode.getKey(), previousNodeChildrenLength + focus.offset, 'element');
|
|
239
208
|
}
|
|
240
209
|
}
|
|
241
|
-
|
|
242
210
|
previousNode.remove();
|
|
243
211
|
}
|
|
244
212
|
|
|
@@ -251,31 +219,24 @@ function mergePrevious(overflowNode) {
|
|
|
251
219
|
*/
|
|
252
220
|
const CHARACTER_LIMIT = 5;
|
|
253
221
|
let textEncoderInstance = null;
|
|
254
|
-
|
|
255
222
|
function textEncoder() {
|
|
256
223
|
if (window.TextEncoder === undefined) {
|
|
257
224
|
return null;
|
|
258
225
|
}
|
|
259
|
-
|
|
260
226
|
if (textEncoderInstance === null) {
|
|
261
227
|
textEncoderInstance = new window.TextEncoder();
|
|
262
228
|
}
|
|
263
|
-
|
|
264
229
|
return textEncoderInstance;
|
|
265
230
|
}
|
|
266
|
-
|
|
267
231
|
function utf8Length(text) {
|
|
268
232
|
const currentTextEncoder = textEncoder();
|
|
269
|
-
|
|
270
233
|
if (currentTextEncoder === null) {
|
|
271
234
|
// http://stackoverflow.com/a/5515960/210370
|
|
272
235
|
const m = encodeURIComponent(text).match(/%[89ABab]/g);
|
|
273
236
|
return text.length + (m ? m.length : 0);
|
|
274
237
|
}
|
|
275
|
-
|
|
276
238
|
return currentTextEncoder.encode(text).length;
|
|
277
239
|
}
|
|
278
|
-
|
|
279
240
|
function CharacterLimitPlugin({
|
|
280
241
|
charset = 'UTF-16',
|
|
281
242
|
maxLength = CHARACTER_LIMIT
|
|
@@ -31,25 +31,19 @@ function CheckListPlugin() {
|
|
|
31
31
|
return handleArrownUpOrDown(event, editor, true);
|
|
32
32
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ESCAPE_COMMAND, event => {
|
|
33
33
|
const activeItem = getActiveCheckListItem();
|
|
34
|
-
|
|
35
34
|
if (activeItem != null) {
|
|
36
35
|
const rootElement = editor.getRootElement();
|
|
37
|
-
|
|
38
36
|
if (rootElement != null) {
|
|
39
37
|
rootElement.focus();
|
|
40
38
|
}
|
|
41
|
-
|
|
42
39
|
return true;
|
|
43
40
|
}
|
|
44
|
-
|
|
45
41
|
return false;
|
|
46
42
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_SPACE_COMMAND, event => {
|
|
47
43
|
const activeItem = getActiveCheckListItem();
|
|
48
|
-
|
|
49
44
|
if (activeItem != null && editor.isEditable()) {
|
|
50
45
|
editor.update(() => {
|
|
51
46
|
const listItemNode = lexical.$getNearestNodeFromDOMNode(activeItem);
|
|
52
|
-
|
|
53
47
|
if (list.$isListItemNode(listItemNode)) {
|
|
54
48
|
event.preventDefault();
|
|
55
49
|
listItemNode.toggleChecked();
|
|
@@ -57,28 +51,22 @@ function CheckListPlugin() {
|
|
|
57
51
|
});
|
|
58
52
|
return true;
|
|
59
53
|
}
|
|
60
|
-
|
|
61
54
|
return false;
|
|
62
55
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_ARROW_LEFT_COMMAND, event => {
|
|
63
56
|
return editor.getEditorState().read(() => {
|
|
64
57
|
const selection = lexical.$getSelection();
|
|
65
|
-
|
|
66
58
|
if (lexical.$isRangeSelection(selection) && selection.isCollapsed()) {
|
|
67
59
|
const {
|
|
68
60
|
anchor
|
|
69
61
|
} = selection;
|
|
70
62
|
const isElement = anchor.type === 'element';
|
|
71
|
-
|
|
72
63
|
if (isElement || anchor.offset === 0) {
|
|
73
64
|
const anchorNode = anchor.getNode();
|
|
74
65
|
const elementNode = utils.$findMatchingParent(anchorNode, node => lexical.$isElementNode(node) && !node.isInline());
|
|
75
|
-
|
|
76
66
|
if (list.$isListItemNode(elementNode)) {
|
|
77
67
|
const parent = elementNode.getParent();
|
|
78
|
-
|
|
79
68
|
if (list.$isListNode(parent) && parent.getListType() === 'check' && (isElement || elementNode.getFirstDescendant() === anchorNode)) {
|
|
80
69
|
const domNode = editor.getElementByKey(elementNode.__key);
|
|
81
|
-
|
|
82
70
|
if (domNode != null && document.activeElement !== domNode) {
|
|
83
71
|
domNode.focus();
|
|
84
72
|
event.preventDefault();
|
|
@@ -88,7 +76,6 @@ function CheckListPlugin() {
|
|
|
88
76
|
}
|
|
89
77
|
}
|
|
90
78
|
}
|
|
91
|
-
|
|
92
79
|
return false;
|
|
93
80
|
});
|
|
94
81
|
}, lexical.COMMAND_PRIORITY_LOW), editor.registerRootListener((rootElement, prevElement) => {
|
|
@@ -96,7 +83,6 @@ function CheckListPlugin() {
|
|
|
96
83
|
rootElement.addEventListener('click', handleClick);
|
|
97
84
|
rootElement.addEventListener('pointerdown', handlePointerDown);
|
|
98
85
|
}
|
|
99
|
-
|
|
100
86
|
if (prevElement !== null) {
|
|
101
87
|
prevElement.removeEventListener('click', handleClick);
|
|
102
88
|
prevElement.removeEventListener('pointerdown', handlePointerDown);
|
|
@@ -105,45 +91,37 @@ function CheckListPlugin() {
|
|
|
105
91
|
});
|
|
106
92
|
return null;
|
|
107
93
|
}
|
|
108
|
-
|
|
109
94
|
function handleCheckItemEvent(event, callback) {
|
|
110
95
|
const target = event.target;
|
|
111
|
-
|
|
112
96
|
if (!(target instanceof HTMLElement)) {
|
|
113
97
|
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
98
|
+
}
|
|
116
99
|
|
|
100
|
+
// Ignore clicks on LI that have nested lists
|
|
117
101
|
const firstChild = target.firstChild;
|
|
118
|
-
|
|
119
102
|
if (firstChild != null && firstChild instanceof HTMLElement && (firstChild.tagName === 'UL' || firstChild.tagName === 'OL')) {
|
|
120
103
|
return;
|
|
121
104
|
}
|
|
105
|
+
const parentNode = target.parentNode;
|
|
122
106
|
|
|
123
|
-
|
|
124
|
-
|
|
107
|
+
// @ts-ignore internal field
|
|
125
108
|
if (!parentNode || parentNode.__lexicalListType !== 'check') {
|
|
126
109
|
return;
|
|
127
110
|
}
|
|
128
|
-
|
|
129
111
|
const pageX = event.pageX;
|
|
130
112
|
const rect = target.getBoundingClientRect();
|
|
131
|
-
|
|
132
113
|
if (target.dir === 'rtl' ? pageX < rect.right && pageX > rect.right - 20 : pageX > rect.left && pageX < rect.left + 20) {
|
|
133
114
|
callback();
|
|
134
115
|
}
|
|
135
116
|
}
|
|
136
|
-
|
|
137
117
|
function handleClick(event) {
|
|
138
118
|
handleCheckItemEvent(event, () => {
|
|
139
119
|
const domNode = event.target;
|
|
140
120
|
const editor = findEditor(domNode);
|
|
141
|
-
|
|
142
121
|
if (editor != null && editor.isEditable()) {
|
|
143
122
|
editor.update(() => {
|
|
144
123
|
if (event.target) {
|
|
145
124
|
const node = lexical.$getNearestNodeFromDOMNode(domNode);
|
|
146
|
-
|
|
147
125
|
if (list.$isListItemNode(node)) {
|
|
148
126
|
domNode.focus();
|
|
149
127
|
node.toggleChecked();
|
|
@@ -153,80 +131,65 @@ function handleClick(event) {
|
|
|
153
131
|
}
|
|
154
132
|
});
|
|
155
133
|
}
|
|
156
|
-
|
|
157
134
|
function handlePointerDown(event) {
|
|
158
135
|
handleCheckItemEvent(event, () => {
|
|
159
136
|
// Prevents caret moving when clicking on check mark
|
|
160
137
|
event.preventDefault();
|
|
161
138
|
});
|
|
162
139
|
}
|
|
163
|
-
|
|
164
140
|
function findEditor(target) {
|
|
165
141
|
let node = target;
|
|
166
|
-
|
|
167
142
|
while (node) {
|
|
168
143
|
// @ts-ignore internal field
|
|
169
144
|
if (node.__lexicalEditor) {
|
|
170
145
|
// @ts-ignore internal field
|
|
171
146
|
return node.__lexicalEditor;
|
|
172
147
|
}
|
|
173
|
-
|
|
174
148
|
node = node.parentNode;
|
|
175
149
|
}
|
|
176
|
-
|
|
177
150
|
return null;
|
|
178
151
|
}
|
|
179
|
-
|
|
180
152
|
function getActiveCheckListItem() {
|
|
181
153
|
const activeElement = document.activeElement;
|
|
182
|
-
return activeElement != null && activeElement.tagName === 'LI' && activeElement.parentNode != null &&
|
|
154
|
+
return activeElement != null && activeElement.tagName === 'LI' && activeElement.parentNode != null &&
|
|
155
|
+
// @ts-ignore internal field
|
|
183
156
|
activeElement.parentNode.__lexicalListType === 'check' ? activeElement : null;
|
|
184
157
|
}
|
|
185
|
-
|
|
186
158
|
function findCheckListItemSibling(node, backward) {
|
|
187
159
|
let sibling = backward ? node.getPreviousSibling() : node.getNextSibling();
|
|
188
|
-
let parent = node;
|
|
160
|
+
let parent = node;
|
|
189
161
|
|
|
162
|
+
// Going up in a tree to get non-null sibling
|
|
190
163
|
while (sibling == null && list.$isListItemNode(parent)) {
|
|
191
164
|
// Get li -> parent ul/ol -> parent li
|
|
192
165
|
parent = parent.getParentOrThrow().getParent();
|
|
193
|
-
|
|
194
166
|
if (parent != null) {
|
|
195
167
|
sibling = backward ? parent.getPreviousSibling() : parent.getNextSibling();
|
|
196
168
|
}
|
|
197
|
-
}
|
|
198
|
-
|
|
169
|
+
}
|
|
199
170
|
|
|
171
|
+
// Going down in a tree to get first non-nested list item
|
|
200
172
|
while (list.$isListItemNode(sibling)) {
|
|
201
173
|
const firstChild = backward ? sibling.getLastChild() : sibling.getFirstChild();
|
|
202
|
-
|
|
203
174
|
if (!list.$isListNode(firstChild)) {
|
|
204
175
|
return sibling;
|
|
205
176
|
}
|
|
206
|
-
|
|
207
177
|
sibling = backward ? firstChild.getLastChild() : firstChild.getFirstChild();
|
|
208
178
|
}
|
|
209
|
-
|
|
210
179
|
return null;
|
|
211
180
|
}
|
|
212
|
-
|
|
213
181
|
function handleArrownUpOrDown(event, editor, backward) {
|
|
214
182
|
const activeItem = getActiveCheckListItem();
|
|
215
|
-
|
|
216
183
|
if (activeItem != null) {
|
|
217
184
|
editor.update(() => {
|
|
218
185
|
const listItem = lexical.$getNearestNodeFromDOMNode(activeItem);
|
|
219
|
-
|
|
220
186
|
if (!list.$isListItemNode(listItem)) {
|
|
221
187
|
return;
|
|
222
188
|
}
|
|
223
|
-
|
|
224
189
|
const nextListItem = findCheckListItemSibling(listItem, backward);
|
|
225
|
-
|
|
226
190
|
if (nextListItem != null) {
|
|
227
191
|
nextListItem.selectStart();
|
|
228
192
|
const dom = editor.getElementByKey(nextListItem.__key);
|
|
229
|
-
|
|
230
193
|
if (dom != null) {
|
|
231
194
|
event.preventDefault();
|
|
232
195
|
setTimeout(() => {
|
|
@@ -236,7 +199,6 @@ function handleArrownUpOrDown(event, editor, backward) {
|
|
|
236
199
|
}
|
|
237
200
|
});
|
|
238
201
|
}
|
|
239
|
-
|
|
240
202
|
return false;
|
|
241
203
|
}
|
|
242
204
|
|
|
@@ -17,6 +17,7 @@ var react = require('react');
|
|
|
17
17
|
* LICENSE file in the root directory of this source tree.
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
|
+
|
|
20
21
|
const CAN_USE_DOM = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined';
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -49,7 +50,6 @@ function ClearEditorPlugin({
|
|
|
49
50
|
const paragraph = lexical.$createParagraphNode();
|
|
50
51
|
root.clear();
|
|
51
52
|
root.append(paragraph);
|
|
52
|
-
|
|
53
53
|
if (selection !== null) {
|
|
54
54
|
paragraph.select();
|
|
55
55
|
}
|
|
@@ -26,15 +26,12 @@ const CollaborationContext = /*#__PURE__*/react.createContext({
|
|
|
26
26
|
});
|
|
27
27
|
function useCollaborationContext(username, color) {
|
|
28
28
|
const collabContext = react.useContext(CollaborationContext);
|
|
29
|
-
|
|
30
29
|
if (username != null) {
|
|
31
30
|
collabContext.name = username;
|
|
32
31
|
}
|
|
33
|
-
|
|
34
32
|
if (color != null) {
|
|
35
33
|
collabContext.color = color;
|
|
36
34
|
}
|
|
37
|
-
|
|
38
35
|
return collabContext;
|
|
39
36
|
}
|
|
40
37
|
|
|
@@ -31,7 +31,8 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
31
31
|
const disconnect = React.useCallback(() => {
|
|
32
32
|
try {
|
|
33
33
|
provider.disconnect();
|
|
34
|
-
} catch (e) {
|
|
34
|
+
} catch (e) {
|
|
35
|
+
// Do nothing
|
|
35
36
|
}
|
|
36
37
|
}, [provider]);
|
|
37
38
|
React.useEffect(() => {
|
|
@@ -41,45 +42,37 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
41
42
|
const {
|
|
42
43
|
awareness
|
|
43
44
|
} = provider;
|
|
44
|
-
|
|
45
45
|
const onStatus = ({
|
|
46
46
|
status
|
|
47
47
|
}) => {
|
|
48
48
|
editor.dispatchCommand(yjs.CONNECTED_COMMAND, status === 'connected');
|
|
49
49
|
};
|
|
50
|
-
|
|
51
50
|
const onSync = isSynced => {
|
|
52
51
|
if (shouldBootstrap && isSynced && root.isEmpty() && root._xmlText._length === 0 && isReloadingDoc.current === false) {
|
|
53
52
|
initializeEditor(editor, initialEditorState);
|
|
54
53
|
}
|
|
55
|
-
|
|
56
54
|
isReloadingDoc.current = false;
|
|
57
55
|
};
|
|
58
|
-
|
|
59
56
|
const onAwarenessUpdate = () => {
|
|
60
57
|
yjs.syncCursorPositions(binding, provider);
|
|
61
58
|
};
|
|
62
|
-
|
|
63
59
|
const onYjsTreeChanges = (events, transaction) => {
|
|
64
60
|
if (transaction.origin !== binding) {
|
|
65
61
|
yjs.syncYjsChangesToLexical(binding, provider, events);
|
|
66
62
|
}
|
|
67
63
|
};
|
|
68
|
-
|
|
69
64
|
yjs.initLocalState(provider, name, color, document.activeElement === editor.getRootElement());
|
|
70
|
-
|
|
71
65
|
const onProviderDocReload = ydoc => {
|
|
72
66
|
clearEditorSkipCollab(editor, binding);
|
|
73
67
|
setDoc(ydoc);
|
|
74
68
|
docMap.set(id, ydoc);
|
|
75
69
|
isReloadingDoc.current = true;
|
|
76
70
|
};
|
|
77
|
-
|
|
78
71
|
provider.on('reload', onProviderDocReload);
|
|
79
72
|
provider.on('status', onStatus);
|
|
80
73
|
provider.on('sync', onSync);
|
|
81
|
-
awareness.on('update', onAwarenessUpdate);
|
|
82
|
-
|
|
74
|
+
awareness.on('update', onAwarenessUpdate);
|
|
75
|
+
// This updates the local editor state when we recieve updates from other clients
|
|
83
76
|
root.getSharedType().observeDeep(onYjsTreeChanges);
|
|
84
77
|
const removeListener = editor.registerUpdateListener(({
|
|
85
78
|
prevEditorState,
|
|
@@ -98,7 +91,6 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
98
91
|
if (isReloadingDoc.current === false) {
|
|
99
92
|
disconnect();
|
|
100
93
|
}
|
|
101
|
-
|
|
102
94
|
provider.off('sync', onSync);
|
|
103
95
|
provider.off('status', onStatus);
|
|
104
96
|
provider.off('reload', onProviderDocReload);
|
|
@@ -112,7 +104,6 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
112
104
|
const ref = element => {
|
|
113
105
|
binding.cursorsContainer = element;
|
|
114
106
|
};
|
|
115
|
-
|
|
116
107
|
return /*#__PURE__*/reactDom.createPortal( /*#__PURE__*/React.createElement("div", {
|
|
117
108
|
ref: ref
|
|
118
109
|
}), cursorsContainerRef && cursorsContainerRef.current || document.body);
|
|
@@ -121,7 +112,6 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
121
112
|
return editor.registerCommand(yjs.TOGGLE_CONNECT_COMMAND, payload => {
|
|
122
113
|
if (connect !== undefined && disconnect !== undefined) {
|
|
123
114
|
const shouldConnect = payload;
|
|
124
|
-
|
|
125
115
|
if (shouldConnect) {
|
|
126
116
|
// eslint-disable-next-line no-console
|
|
127
117
|
console.log('Collaboration connected!');
|
|
@@ -132,7 +122,6 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
132
122
|
disconnect();
|
|
133
123
|
}
|
|
134
124
|
}
|
|
135
|
-
|
|
136
125
|
return true;
|
|
137
126
|
}, lexical.COMMAND_PRIORITY_EDITOR);
|
|
138
127
|
}, [connect, disconnect, editor]);
|
|
@@ -155,11 +144,9 @@ function useYjsHistory(editor, binding) {
|
|
|
155
144
|
const undo = () => {
|
|
156
145
|
undoManager.undo();
|
|
157
146
|
};
|
|
158
|
-
|
|
159
147
|
const redo = () => {
|
|
160
148
|
undoManager.redo();
|
|
161
149
|
};
|
|
162
|
-
|
|
163
150
|
return utils.mergeRegister(editor.registerCommand(lexical.UNDO_COMMAND, () => {
|
|
164
151
|
undo();
|
|
165
152
|
return true;
|
|
@@ -173,11 +160,9 @@ function useYjsHistory(editor, binding) {
|
|
|
173
160
|
}, [undoManager]);
|
|
174
161
|
return clearHistory;
|
|
175
162
|
}
|
|
176
|
-
|
|
177
163
|
function initializeEditor(editor, initialEditorState) {
|
|
178
164
|
editor.update(() => {
|
|
179
165
|
const root = lexical.$getRoot();
|
|
180
|
-
|
|
181
166
|
if (root.isEmpty()) {
|
|
182
167
|
if (initialEditorState) {
|
|
183
168
|
switch (typeof initialEditorState) {
|
|
@@ -189,7 +174,6 @@ function initializeEditor(editor, initialEditorState) {
|
|
|
189
174
|
});
|
|
190
175
|
break;
|
|
191
176
|
}
|
|
192
|
-
|
|
193
177
|
case 'object':
|
|
194
178
|
{
|
|
195
179
|
editor.setEditorState(initialEditorState, {
|
|
@@ -197,12 +181,10 @@ function initializeEditor(editor, initialEditorState) {
|
|
|
197
181
|
});
|
|
198
182
|
break;
|
|
199
183
|
}
|
|
200
|
-
|
|
201
184
|
case 'function':
|
|
202
185
|
{
|
|
203
186
|
editor.update(() => {
|
|
204
187
|
const root1 = lexical.$getRoot();
|
|
205
|
-
|
|
206
188
|
if (root1.isEmpty()) {
|
|
207
189
|
initialEditorState(editor);
|
|
208
190
|
}
|
|
@@ -218,7 +200,6 @@ function initializeEditor(editor, initialEditorState) {
|
|
|
218
200
|
const {
|
|
219
201
|
activeElement
|
|
220
202
|
} = document;
|
|
221
|
-
|
|
222
203
|
if (lexical.$getSelection() !== null || activeElement !== null && activeElement === editor.getRootElement()) {
|
|
223
204
|
paragraph.select();
|
|
224
205
|
}
|
|
@@ -228,7 +209,6 @@ function initializeEditor(editor, initialEditorState) {
|
|
|
228
209
|
tag: 'history-merge'
|
|
229
210
|
});
|
|
230
211
|
}
|
|
231
|
-
|
|
232
212
|
function clearEditorSkipCollab(editor, binding) {
|
|
233
213
|
// reset editor state
|
|
234
214
|
editor.update(() => {
|
|
@@ -238,33 +218,25 @@ function clearEditorSkipCollab(editor, binding) {
|
|
|
238
218
|
}, {
|
|
239
219
|
tag: 'skip-collab'
|
|
240
220
|
});
|
|
241
|
-
|
|
242
221
|
if (binding.cursors == null) {
|
|
243
222
|
return;
|
|
244
223
|
}
|
|
245
|
-
|
|
246
224
|
const cursors = binding.cursors;
|
|
247
|
-
|
|
248
225
|
if (cursors == null) {
|
|
249
226
|
return;
|
|
250
227
|
}
|
|
251
|
-
|
|
252
228
|
const cursorsContainer = binding.cursorsContainer;
|
|
253
|
-
|
|
254
229
|
if (cursorsContainer == null) {
|
|
255
230
|
return;
|
|
256
|
-
}
|
|
257
|
-
|
|
231
|
+
}
|
|
258
232
|
|
|
233
|
+
// reset cursors in dom
|
|
259
234
|
const cursorsArr = Array.from(cursors.values());
|
|
260
|
-
|
|
261
235
|
for (let i = 0; i < cursorsArr.length; i++) {
|
|
262
236
|
const cursor = cursorsArr[i];
|
|
263
237
|
const selection = cursor.selection;
|
|
264
|
-
|
|
265
238
|
if (selection && selection.selections != null) {
|
|
266
239
|
const selections = selection.selections;
|
|
267
|
-
|
|
268
240
|
for (let j = 0; j < selections.length; j++) {
|
|
269
241
|
cursorsContainer.removeChild(selections[i]);
|
|
270
242
|
}
|