@lexical/react 0.12.2 → 0.12.4
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/LexicalAutoEmbedPlugin.d.ts +3 -2
- package/LexicalAutoEmbedPlugin.dev.js +4 -14
- package/LexicalAutoEmbedPlugin.prod.js +4 -3
- package/LexicalAutoFocusPlugin.dev.js +0 -1
- package/LexicalAutoLinkPlugin.dev.js +126 -73
- package/LexicalAutoLinkPlugin.prod.js +11 -7
- package/LexicalBlockWithAlignableContents.dev.js +0 -10
- package/LexicalCharacterLimitPlugin.dev.js +7 -46
- package/LexicalCheckListPlugin.dev.js +10 -48
- package/LexicalClearEditorPlugin.dev.js +1 -1
- package/LexicalClickableLinkPlugin.dev.js +2 -20
- package/LexicalCollaborationContext.dev.js +0 -3
- package/LexicalCollaborationPlugin.dev.js +8 -37
- package/LexicalComposer.d.ts +3 -7
- package/LexicalComposer.dev.js +9 -11
- package/LexicalComposer.js.flow +4 -4
- package/LexicalComposer.prod.js +2 -1
- package/LexicalComposerContext.dev.js +0 -6
- package/LexicalContentEditable.dev.js +1 -2
- package/LexicalContextMenuPlugin.d.ts +3 -2
- package/LexicalContextMenuPlugin.dev.js +28 -82
- package/LexicalContextMenuPlugin.prod.js +16 -15
- package/LexicalDecoratorBlockNode.dev.js +0 -6
- package/LexicalEditorRefPlugin.dev.js +0 -3
- package/LexicalHashtagPlugin.dev.js +73 -43
- package/LexicalHorizontalRuleNode.dev.js +0 -21
- 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.d.ts +2 -2
- package/LexicalNestedComposer.dev.js +18 -16
- package/LexicalNestedComposer.js.flow +7 -2
- package/LexicalNestedComposer.prod.js +4 -3
- package/LexicalNodeEventPlugin.dev.js +2 -6
- package/LexicalNodeMenuPlugin.d.ts +3 -2
- package/LexicalNodeMenuPlugin.dev.js +27 -83
- package/LexicalNodeMenuPlugin.prod.js +15 -15
- package/LexicalOnChangePlugin.dev.js +1 -1
- package/LexicalPlainTextPlugin.dev.js +8 -12
- package/LexicalRichTextPlugin.dev.js +8 -12
- package/LexicalTabIndentationPlugin.dev.js +7 -16
- package/LexicalTableOfContents.dev.js +5 -33
- package/LexicalTablePlugin.dev.js +11 -28
- package/LexicalTreeView.dev.js +14 -79
- package/LexicalTypeaheadMenuPlugin.d.ts +4 -3
- package/LexicalTypeaheadMenuPlugin.dev.js +39 -176
- package/LexicalTypeaheadMenuPlugin.prod.js +19 -20
- package/package.json +19 -19
- package/shared/LexicalMenu.d.ts +3 -2
- package/useLexicalEditable.dev.js +1 -5
- package/useLexicalIsTextContentEmpty.dev.js +1 -0
- package/useLexicalNodeSelection.dev.js +0 -7
- package/useLexicalSubscription.dev.js +1 -3
|
@@ -46,16 +46,13 @@ function useCharacterLimit(editor, maxCharacters, optional = Object.freeze({}))
|
|
|
46
46
|
}) => {
|
|
47
47
|
const isComposing = editor.isComposing();
|
|
48
48
|
const hasContentChanges = dirtyLeaves.size > 0 || dirtyElements.size > 0;
|
|
49
|
-
|
|
50
49
|
if (isComposing || !hasContentChanges) {
|
|
51
50
|
return;
|
|
52
51
|
}
|
|
53
|
-
|
|
54
52
|
const textLength = strlen(text$1);
|
|
55
53
|
const textLengthAboveThreshold = textLength > maxCharacters || lastComputedTextLength !== null && lastComputedTextLength > maxCharacters;
|
|
56
54
|
const diff = maxCharacters - textLength;
|
|
57
55
|
remainingCharacters(diff);
|
|
58
|
-
|
|
59
56
|
if (lastComputedTextLength === null || textLengthAboveThreshold) {
|
|
60
57
|
const offset = findOffset(text$1, maxCharacters, strlen);
|
|
61
58
|
editor.update(() => {
|
|
@@ -64,75 +61,62 @@ function useCharacterLimit(editor, maxCharacters, optional = Object.freeze({}))
|
|
|
64
61
|
tag: 'history-merge'
|
|
65
62
|
});
|
|
66
63
|
}
|
|
67
|
-
|
|
68
64
|
lastComputedTextLength = textLength;
|
|
69
65
|
}));
|
|
70
66
|
}, [editor, maxCharacters, remainingCharacters, strlen]);
|
|
71
67
|
}
|
|
72
|
-
|
|
73
68
|
function findOffset(text, maxCharacters, strlen) {
|
|
74
69
|
// @ts-ignore This is due to be added in a later version of TS
|
|
75
70
|
const Segmenter = Intl.Segmenter;
|
|
76
71
|
let offsetUtf16 = 0;
|
|
77
72
|
let offset = 0;
|
|
78
|
-
|
|
79
73
|
if (typeof Segmenter === 'function') {
|
|
80
74
|
const segmenter = new Segmenter();
|
|
81
75
|
const graphemes = segmenter.segment(text);
|
|
82
|
-
|
|
83
76
|
for (const {
|
|
84
77
|
segment: grapheme
|
|
85
78
|
} of graphemes) {
|
|
86
79
|
const nextOffset = offset + strlen(grapheme);
|
|
87
|
-
|
|
88
80
|
if (nextOffset > maxCharacters) {
|
|
89
81
|
break;
|
|
90
82
|
}
|
|
91
|
-
|
|
92
83
|
offset = nextOffset;
|
|
93
84
|
offsetUtf16 += grapheme.length;
|
|
94
85
|
}
|
|
95
86
|
} else {
|
|
96
87
|
const codepoints = Array.from(text);
|
|
97
88
|
const codepointsLength = codepoints.length;
|
|
98
|
-
|
|
99
89
|
for (let i = 0; i < codepointsLength; i++) {
|
|
100
90
|
const codepoint = codepoints[i];
|
|
101
91
|
const nextOffset = offset + strlen(codepoint);
|
|
102
|
-
|
|
103
92
|
if (nextOffset > maxCharacters) {
|
|
104
93
|
break;
|
|
105
94
|
}
|
|
106
|
-
|
|
107
95
|
offset = nextOffset;
|
|
108
96
|
offsetUtf16 += codepoint.length;
|
|
109
97
|
}
|
|
110
98
|
}
|
|
111
|
-
|
|
112
99
|
return offsetUtf16;
|
|
113
100
|
}
|
|
114
|
-
|
|
115
101
|
function $wrapOverflowedNodes(offset) {
|
|
116
102
|
const dfsNodes = utils.$dfs();
|
|
117
103
|
const dfsNodesLength = dfsNodes.length;
|
|
118
104
|
let accumulatedLength = 0;
|
|
119
|
-
|
|
120
105
|
for (let i = 0; i < dfsNodesLength; i += 1) {
|
|
121
106
|
const {
|
|
122
107
|
node
|
|
123
108
|
} = dfsNodes[i];
|
|
124
|
-
|
|
125
109
|
if (overflow.$isOverflowNode(node)) {
|
|
126
110
|
const previousLength = accumulatedLength;
|
|
127
111
|
const nextLength = accumulatedLength + node.getTextContentSize();
|
|
128
|
-
|
|
129
112
|
if (nextLength <= offset) {
|
|
130
113
|
const parent = node.getParent();
|
|
131
114
|
const previousSibling = node.getPreviousSibling();
|
|
132
115
|
const nextSibling = node.getNextSibling();
|
|
133
116
|
$unwrapNode(node);
|
|
134
|
-
const selection = lexical.$getSelection();
|
|
117
|
+
const selection = lexical.$getSelection();
|
|
135
118
|
|
|
119
|
+
// Restore selection when the overflow children are removed
|
|
136
120
|
if (lexical.$isRangeSelection(selection) && (!selection.anchor.getNode().isAttached() || !selection.focus.getNode().isAttached())) {
|
|
137
121
|
if (lexical.$isTextNode(previousSibling)) {
|
|
138
122
|
previousSibling.select();
|
|
@@ -145,12 +129,11 @@ function $wrapOverflowedNodes(offset) {
|
|
|
145
129
|
} else if (previousLength < offset) {
|
|
146
130
|
const descendant = node.getFirstDescendant();
|
|
147
131
|
const descendantLength = descendant !== null ? descendant.getTextContentSize() : 0;
|
|
148
|
-
const previousPlusDescendantLength = previousLength + descendantLength;
|
|
132
|
+
const previousPlusDescendantLength = previousLength + descendantLength;
|
|
133
|
+
// For simple text we can redimension the overflow into a smaller and more accurate
|
|
149
134
|
// container
|
|
150
|
-
|
|
151
135
|
const firstDescendantIsSimpleText = lexical.$isTextNode(descendant) && descendant.isSimpleText();
|
|
152
136
|
const firstDescendantDoesNotOverflow = previousPlusDescendantLength <= offset;
|
|
153
|
-
|
|
154
137
|
if (firstDescendantIsSimpleText || firstDescendantDoesNotOverflow) {
|
|
155
138
|
$unwrapNode(node);
|
|
156
139
|
}
|
|
@@ -158,59 +141,49 @@ function $wrapOverflowedNodes(offset) {
|
|
|
158
141
|
} else if (lexical.$isLeafNode(node)) {
|
|
159
142
|
const previousAccumulatedLength = accumulatedLength;
|
|
160
143
|
accumulatedLength += node.getTextContentSize();
|
|
161
|
-
|
|
162
144
|
if (accumulatedLength > offset && !overflow.$isOverflowNode(node.getParent())) {
|
|
163
145
|
const previousSelection = lexical.$getSelection();
|
|
164
|
-
let overflowNode;
|
|
165
|
-
// on the split point
|
|
146
|
+
let overflowNode;
|
|
166
147
|
|
|
148
|
+
// For simple text we can improve the limit accuracy by splitting the TextNode
|
|
149
|
+
// on the split point
|
|
167
150
|
if (previousAccumulatedLength < offset && lexical.$isTextNode(node) && node.isSimpleText()) {
|
|
168
151
|
const [, overflowedText] = node.splitText(offset - previousAccumulatedLength);
|
|
169
152
|
overflowNode = $wrapNode(overflowedText);
|
|
170
153
|
} else {
|
|
171
154
|
overflowNode = $wrapNode(node);
|
|
172
155
|
}
|
|
173
|
-
|
|
174
156
|
if (previousSelection !== null) {
|
|
175
157
|
lexical.$setSelection(previousSelection);
|
|
176
158
|
}
|
|
177
|
-
|
|
178
159
|
mergePrevious(overflowNode);
|
|
179
160
|
}
|
|
180
161
|
}
|
|
181
162
|
}
|
|
182
163
|
}
|
|
183
|
-
|
|
184
164
|
function $wrapNode(node) {
|
|
185
165
|
const overflowNode = overflow.$createOverflowNode();
|
|
186
166
|
node.insertBefore(overflowNode);
|
|
187
167
|
overflowNode.append(node);
|
|
188
168
|
return overflowNode;
|
|
189
169
|
}
|
|
190
|
-
|
|
191
170
|
function $unwrapNode(node) {
|
|
192
171
|
const children = node.getChildren();
|
|
193
172
|
const childrenLength = children.length;
|
|
194
|
-
|
|
195
173
|
for (let i = 0; i < childrenLength; i++) {
|
|
196
174
|
node.insertBefore(children[i]);
|
|
197
175
|
}
|
|
198
|
-
|
|
199
176
|
node.remove();
|
|
200
177
|
return childrenLength > 0 ? children[childrenLength - 1] : null;
|
|
201
178
|
}
|
|
202
|
-
|
|
203
179
|
function mergePrevious(overflowNode) {
|
|
204
180
|
const previousNode = overflowNode.getPreviousSibling();
|
|
205
|
-
|
|
206
181
|
if (!overflow.$isOverflowNode(previousNode)) {
|
|
207
182
|
return;
|
|
208
183
|
}
|
|
209
|
-
|
|
210
184
|
const firstChild = overflowNode.getFirstChild();
|
|
211
185
|
const previousNodeChildren = previousNode.getChildren();
|
|
212
186
|
const previousNodeChildrenLength = previousNodeChildren.length;
|
|
213
|
-
|
|
214
187
|
if (firstChild === null) {
|
|
215
188
|
overflowNode.append(...previousNodeChildren);
|
|
216
189
|
} else {
|
|
@@ -218,28 +191,23 @@ function mergePrevious(overflowNode) {
|
|
|
218
191
|
firstChild.insertBefore(previousNodeChildren[i]);
|
|
219
192
|
}
|
|
220
193
|
}
|
|
221
|
-
|
|
222
194
|
const selection = lexical.$getSelection();
|
|
223
|
-
|
|
224
195
|
if (lexical.$isRangeSelection(selection)) {
|
|
225
196
|
const anchor = selection.anchor;
|
|
226
197
|
const anchorNode = anchor.getNode();
|
|
227
198
|
const focus = selection.focus;
|
|
228
199
|
const focusNode = anchor.getNode();
|
|
229
|
-
|
|
230
200
|
if (anchorNode.is(previousNode)) {
|
|
231
201
|
anchor.set(overflowNode.getKey(), anchor.offset, 'element');
|
|
232
202
|
} else if (anchorNode.is(overflowNode)) {
|
|
233
203
|
anchor.set(overflowNode.getKey(), previousNodeChildrenLength + anchor.offset, 'element');
|
|
234
204
|
}
|
|
235
|
-
|
|
236
205
|
if (focusNode.is(previousNode)) {
|
|
237
206
|
focus.set(overflowNode.getKey(), focus.offset, 'element');
|
|
238
207
|
} else if (focusNode.is(overflowNode)) {
|
|
239
208
|
focus.set(overflowNode.getKey(), previousNodeChildrenLength + focus.offset, 'element');
|
|
240
209
|
}
|
|
241
210
|
}
|
|
242
|
-
|
|
243
211
|
previousNode.remove();
|
|
244
212
|
}
|
|
245
213
|
|
|
@@ -252,31 +220,24 @@ function mergePrevious(overflowNode) {
|
|
|
252
220
|
*/
|
|
253
221
|
const CHARACTER_LIMIT = 5;
|
|
254
222
|
let textEncoderInstance = null;
|
|
255
|
-
|
|
256
223
|
function textEncoder() {
|
|
257
224
|
if (window.TextEncoder === undefined) {
|
|
258
225
|
return null;
|
|
259
226
|
}
|
|
260
|
-
|
|
261
227
|
if (textEncoderInstance === null) {
|
|
262
228
|
textEncoderInstance = new window.TextEncoder();
|
|
263
229
|
}
|
|
264
|
-
|
|
265
230
|
return textEncoderInstance;
|
|
266
231
|
}
|
|
267
|
-
|
|
268
232
|
function utf8Length(text) {
|
|
269
233
|
const currentTextEncoder = textEncoder();
|
|
270
|
-
|
|
271
234
|
if (currentTextEncoder === null) {
|
|
272
235
|
// http://stackoverflow.com/a/5515960/210370
|
|
273
236
|
const m = encodeURIComponent(text).match(/%[89ABab]/g);
|
|
274
237
|
return text.length + (m ? m.length : 0);
|
|
275
238
|
}
|
|
276
|
-
|
|
277
239
|
return currentTextEncoder.encode(text).length;
|
|
278
240
|
}
|
|
279
|
-
|
|
280
241
|
function CharacterLimitPlugin({
|
|
281
242
|
charset = 'UTF-16',
|
|
282
243
|
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 === null || !utils.isHTMLElement(target)) {
|
|
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 && utils.isHTMLElement(firstChild) && (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
|
}
|
|
@@ -19,21 +19,16 @@ var react = require('react');
|
|
|
19
19
|
* LICENSE file in the root directory of this source tree.
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
22
|
-
|
|
23
22
|
function findMatchingDOM(startNode, predicate) {
|
|
24
23
|
let node = startNode;
|
|
25
|
-
|
|
26
24
|
while (node != null) {
|
|
27
25
|
if (predicate(node)) {
|
|
28
26
|
return node;
|
|
29
27
|
}
|
|
30
|
-
|
|
31
28
|
node = node.parentNode;
|
|
32
29
|
}
|
|
33
|
-
|
|
34
30
|
return null;
|
|
35
31
|
}
|
|
36
|
-
|
|
37
32
|
function LexicalClickableLinkPlugin({
|
|
38
33
|
newTab = true
|
|
39
34
|
}) {
|
|
@@ -41,31 +36,24 @@ function LexicalClickableLinkPlugin({
|
|
|
41
36
|
react.useEffect(() => {
|
|
42
37
|
const onClick = event => {
|
|
43
38
|
const target = event.target;
|
|
44
|
-
|
|
45
39
|
if (!(target instanceof Node)) {
|
|
46
40
|
return;
|
|
47
41
|
}
|
|
48
|
-
|
|
49
42
|
const nearestEditor = lexical.getNearestEditorFromDOMNode(target);
|
|
50
|
-
|
|
51
43
|
if (nearestEditor === null) {
|
|
52
44
|
return;
|
|
53
45
|
}
|
|
54
|
-
|
|
55
46
|
let url = null;
|
|
56
47
|
let urlTarget = null;
|
|
57
48
|
nearestEditor.update(() => {
|
|
58
49
|
const clickedNode = lexical.$getNearestNodeFromDOMNode(target);
|
|
59
|
-
|
|
60
50
|
if (clickedNode !== null) {
|
|
61
51
|
const maybeLinkNode = utils.$findMatchingParent(clickedNode, lexical.$isElementNode);
|
|
62
|
-
|
|
63
52
|
if (link.$isLinkNode(maybeLinkNode)) {
|
|
64
53
|
url = maybeLinkNode.getURL();
|
|
65
54
|
urlTarget = maybeLinkNode.getTarget();
|
|
66
55
|
} else {
|
|
67
56
|
const a = findMatchingDOM(target, utils.isHTMLAnchorElement);
|
|
68
|
-
|
|
69
57
|
if (a !== null) {
|
|
70
58
|
url = a.href;
|
|
71
59
|
urlTarget = a.target;
|
|
@@ -73,36 +61,30 @@ function LexicalClickableLinkPlugin({
|
|
|
73
61
|
}
|
|
74
62
|
}
|
|
75
63
|
});
|
|
76
|
-
|
|
77
64
|
if (url === null || url === '') {
|
|
78
65
|
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
66
|
+
}
|
|
81
67
|
|
|
68
|
+
// Allow user to select link text without follwing url
|
|
82
69
|
const selection = editor.getEditorState().read(lexical.$getSelection);
|
|
83
|
-
|
|
84
70
|
if (lexical.$isRangeSelection(selection) && !selection.isCollapsed()) {
|
|
85
71
|
event.preventDefault();
|
|
86
72
|
return;
|
|
87
73
|
}
|
|
88
|
-
|
|
89
74
|
const isMiddle = event.type === 'auxclick' && event.button === 1;
|
|
90
75
|
window.open(url, newTab || isMiddle || event.metaKey || event.ctrlKey || urlTarget === '_blank' ? '_blank' : '_self');
|
|
91
76
|
event.preventDefault();
|
|
92
77
|
};
|
|
93
|
-
|
|
94
78
|
const onMouseUp = event => {
|
|
95
79
|
if (event.button === 1 && editor.isEditable()) {
|
|
96
80
|
onClick(event);
|
|
97
81
|
}
|
|
98
82
|
};
|
|
99
|
-
|
|
100
83
|
return editor.registerRootListener((rootElement, prevRootElement) => {
|
|
101
84
|
if (prevRootElement !== null) {
|
|
102
85
|
prevRootElement.removeEventListener('click', onClick);
|
|
103
86
|
prevRootElement.removeEventListener('mouseup', onMouseUp);
|
|
104
87
|
}
|
|
105
|
-
|
|
106
88
|
if (rootElement !== null) {
|
|
107
89
|
rootElement.addEventListener('click', onClick);
|
|
108
90
|
rootElement.addEventListener('mouseup', onMouseUp);
|
|
@@ -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
|
|