@lexical/react 0.1.16 → 0.1.19
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_useLexicalAutoFormatter.dev.js +5 -729
- package/DEPRECATED_useLexicalAutoFormatter.prod.js +1 -19
- package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +1 -1
- package/DEPRECATED_useLexicalCanShowPlaceholder.prod.js +1 -1
- package/DEPRECATED_useLexicalCharacterLimit.dev.js +9 -10
- package/DEPRECATED_useLexicalCharacterLimit.prod.js +7 -7
- package/DEPRECATED_useLexicalDecorators.dev.js +1 -1
- package/DEPRECATED_useLexicalDecorators.prod.js +1 -1
- package/DEPRECATED_useLexicalEditorEvents.dev.js +1 -1
- package/DEPRECATED_useLexicalEditorEvents.prod.js +1 -1
- package/DEPRECATED_useLexicalHistory.dev.js +5 -307
- package/DEPRECATED_useLexicalHistory.prod.js +1 -7
- package/DEPRECATED_useLexicalList.dev.js +29 -25
- package/DEPRECATED_useLexicalList.prod.js +3 -1
- package/DEPRECATED_useLexicalPlainText.dev.js +8 -662
- package/DEPRECATED_useLexicalPlainText.prod.js +2 -14
- package/DEPRECATED_useLexicalRichText.dev.js +8 -747
- package/DEPRECATED_useLexicalRichText.prod.js +2 -17
- package/LICENSE +1 -1
- package/{withSubscriptions.prod.js → LexicalAutoFocusPlugin.d.ts} +3 -1
- package/{withSubscriptions.dev.js → LexicalAutoFocusPlugin.dev.js} +10 -5
- package/LexicalAutoFocusPlugin.js +9 -0
- package/{LexicalAutoFormatterPlugin.js.flow → LexicalAutoFocusPlugin.js.flow} +1 -1
- package/LexicalAutoFocusPlugin.prod.js +7 -0
- package/LexicalAutoLinkPlugin.dev.js +12 -15
- package/LexicalAutoLinkPlugin.prod.js +6 -6
- package/LexicalAutoScrollPlugin.d.ts +13 -0
- package/LexicalAutoScrollPlugin.dev.js +82 -0
- package/LexicalAutoScrollPlugin.js +9 -0
- package/{withSubscriptions.d.ts → LexicalAutoScrollPlugin.js.flow} +5 -5
- package/LexicalAutoScrollPlugin.prod.js +8 -0
- package/LexicalCharacterLimitPlugin.dev.js +9 -10
- package/LexicalCharacterLimitPlugin.prod.js +7 -7
- package/LexicalClearEditorPlugin.dev.js +15 -19
- package/LexicalClearEditorPlugin.prod.js +1 -1
- package/LexicalCollaborationPlugin.d.ts +6 -3
- package/LexicalCollaborationPlugin.dev.js +30 -41
- package/LexicalCollaborationPlugin.js.flow +7 -4
- package/LexicalCollaborationPlugin.prod.js +10 -9
- package/LexicalComposer.d.ts +2 -2
- package/LexicalComposer.dev.js +3 -19
- package/LexicalComposer.js.flow +2 -2
- package/LexicalComposer.prod.js +2 -3
- package/LexicalContentEditable.dev.js +3 -1
- package/LexicalContentEditable.prod.js +2 -2
- package/LexicalHashtagPlugin.dev.js +20 -94
- package/LexicalHashtagPlugin.prod.js +4 -7
- package/LexicalHistoryPlugin.dev.js +5 -307
- package/LexicalHistoryPlugin.prod.js +1 -7
- package/LexicalHorizontalRuleNode.d.ts +3 -1
- package/LexicalHorizontalRuleNode.dev.js +2 -0
- package/LexicalHorizontalRuleNode.js.flow +6 -2
- package/LexicalHorizontalRuleNode.prod.js +2 -2
- package/LexicalLinkPlugin.dev.js +19 -20
- package/LexicalLinkPlugin.prod.js +4 -3
- package/LexicalListPlugin.dev.js +29 -25
- package/LexicalListPlugin.prod.js +3 -2
- package/{LexicalAutoFormatterPlugin.d.ts → LexicalMarkdownShortcutPlugin.d.ts} +1 -1
- package/LexicalMarkdownShortcutPlugin.dev.js +42 -0
- package/LexicalMarkdownShortcutPlugin.js +9 -0
- package/{withSubscriptions.js.flow → LexicalMarkdownShortcutPlugin.js.flow} +1 -4
- package/LexicalMarkdownShortcutPlugin.prod.js +7 -0
- package/LexicalNestedComposer.dev.js +20 -15
- package/LexicalNestedComposer.prod.js +3 -3
- package/LexicalOnChangePlugin.dev.js +1 -1
- package/LexicalOnChangePlugin.prod.js +1 -1
- package/LexicalPlainTextPlugin.dev.js +6 -359
- package/LexicalPlainTextPlugin.prod.js +4 -11
- package/LexicalRichTextPlugin.dev.js +6 -444
- package/LexicalRichTextPlugin.prod.js +4 -12
- package/LexicalTablePlugin.dev.js +27 -30
- package/LexicalTablePlugin.prod.js +3 -3
- package/LexicalTreeView.dev.js +1 -1
- package/LexicalTreeView.prod.js +1 -1
- package/package.json +17 -14
- package/useLexicalIsTextContentEmpty.dev.js +1 -1
- package/useLexicalIsTextContentEmpty.prod.js +1 -1
- package/useLexicalNodeSelection.dev.js +1 -1
- package/useLexicalNodeSelection.prod.js +1 -1
- package/useLexicalTextEntity.d.ts +19 -0
- package/useLexicalTextEntity.dev.js +29 -0
- package/{withSubscriptions.js → useLexicalTextEntity.js} +2 -2
- package/useLexicalTextEntity.js.flow +18 -0
- package/useLexicalTextEntity.prod.js +7 -0
- package/LexicalAutoFormatterPlugin.dev.js +0 -766
- package/LexicalAutoFormatterPlugin.js +0 -9
- package/LexicalAutoFormatterPlugin.prod.js +0 -25
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
9
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
10
|
-
var
|
|
11
|
-
var lexical = require('lexical');
|
|
10
|
+
var history = require('@lexical/history');
|
|
12
11
|
var react = require('react');
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -19,312 +18,11 @@ var react = require('react');
|
|
|
19
18
|
*
|
|
20
19
|
*
|
|
21
20
|
*/
|
|
22
|
-
const HISTORY_MERGE = 0;
|
|
23
|
-
const HISTORY_PUSH = 1;
|
|
24
|
-
const DISCARD_HISTORY_CANDIDATE = 2;
|
|
25
|
-
const OTHER = 0;
|
|
26
|
-
const COMPOSING_CHARACTER = 1;
|
|
27
|
-
const INSERT_CHARACTER_AFTER_SELECTION = 2;
|
|
28
|
-
const DELETE_CHARACTER_BEFORE_SELECTION = 3;
|
|
29
|
-
const DELETE_CHARACTER_AFTER_SELECTION = 4;
|
|
30
|
-
const EditorPriority = 0;
|
|
31
|
-
|
|
32
|
-
function getDirtyNodes(editorState, dirtyLeavesSet, dirtyElementsSet) {
|
|
33
|
-
const dirtyLeaves = Array.from(dirtyLeavesSet);
|
|
34
|
-
const dirtyElements = Array.from(dirtyElementsSet);
|
|
35
|
-
const nodeMap = editorState._nodeMap;
|
|
36
|
-
const nodes = [];
|
|
37
|
-
|
|
38
|
-
for (let i = 0; i < dirtyLeaves.length; i++) {
|
|
39
|
-
const dirtyLeafKey = dirtyLeaves[i];
|
|
40
|
-
const dirtyLeaf = nodeMap.get(dirtyLeafKey);
|
|
41
|
-
|
|
42
|
-
if (dirtyLeaf !== undefined) {
|
|
43
|
-
nodes.push(dirtyLeaf);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
for (let i = 0; i < dirtyElements.length; i++) {
|
|
48
|
-
const intentionallyMarkedAsDirty = dirtyElements[i][1];
|
|
49
|
-
|
|
50
|
-
if (!intentionallyMarkedAsDirty) {
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const dirtyElementKey = dirtyElements[i][0];
|
|
55
|
-
const dirtyElement = nodeMap.get(dirtyElementKey);
|
|
56
|
-
|
|
57
|
-
if (dirtyElement !== undefined && !lexical.$isRootNode(dirtyElement)) {
|
|
58
|
-
nodes.push(dirtyElement);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return nodes;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function getChangeType(prevEditorState, nextEditorState, dirtyLeavesSet, dirtyElementsSet, isComposing) {
|
|
66
|
-
if (prevEditorState === null || dirtyLeavesSet.size === 0 && dirtyElementsSet.size === 0) {
|
|
67
|
-
return OTHER;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const nextSelection = nextEditorState._selection;
|
|
71
|
-
const prevSelection = prevEditorState._selection;
|
|
72
|
-
|
|
73
|
-
if (isComposing) {
|
|
74
|
-
return COMPOSING_CHARACTER;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (!lexical.$isRangeSelection(nextSelection) || !lexical.$isRangeSelection(prevSelection) || !prevSelection.isCollapsed() || !nextSelection.isCollapsed()) {
|
|
78
|
-
return OTHER;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const dirtyNodes = getDirtyNodes(nextEditorState, dirtyLeavesSet, dirtyElementsSet);
|
|
82
|
-
|
|
83
|
-
if (dirtyNodes.length === 0) {
|
|
84
|
-
return OTHER;
|
|
85
|
-
} // Catching the case when inserting new text node into an element (e.g. first char in paragraph/list),
|
|
86
|
-
// or after existing node.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (dirtyNodes.length > 1) {
|
|
90
|
-
const nextNodeMap = nextEditorState._nodeMap;
|
|
91
|
-
const nextAnchorNode = nextNodeMap.get(nextSelection.anchor.key);
|
|
92
|
-
const prevAnchorNode = nextNodeMap.get(prevSelection.anchor.key);
|
|
93
|
-
|
|
94
|
-
if (nextAnchorNode && prevAnchorNode && !prevEditorState._nodeMap.has(nextAnchorNode.__key) && lexical.$isTextNode(nextAnchorNode) && nextAnchorNode.__text.length === 1 && nextSelection.anchor.offset === 1) {
|
|
95
|
-
return INSERT_CHARACTER_AFTER_SELECTION;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return OTHER;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const nextDirtyNode = dirtyNodes[0];
|
|
102
|
-
|
|
103
|
-
const prevDirtyNode = prevEditorState._nodeMap.get(nextDirtyNode.__key);
|
|
104
|
-
|
|
105
|
-
if (!lexical.$isTextNode(prevDirtyNode) || !lexical.$isTextNode(nextDirtyNode) || prevDirtyNode.__mode !== nextDirtyNode.__mode) {
|
|
106
|
-
return OTHER;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const prevText = prevDirtyNode.__text;
|
|
110
|
-
const nextText = nextDirtyNode.__text;
|
|
111
|
-
|
|
112
|
-
if (prevText === nextText) {
|
|
113
|
-
return OTHER;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const nextAnchor = nextSelection.anchor;
|
|
117
|
-
const prevAnchor = prevSelection.anchor;
|
|
118
|
-
|
|
119
|
-
if (nextAnchor.key !== prevAnchor.key || nextAnchor.type !== 'text') {
|
|
120
|
-
return OTHER;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const nextAnchorOffset = nextAnchor.offset;
|
|
124
|
-
const prevAnchorOffset = prevAnchor.offset;
|
|
125
|
-
const textDiff = nextText.length - prevText.length;
|
|
126
|
-
|
|
127
|
-
if (textDiff === 1 && prevAnchorOffset === nextAnchorOffset - 1) {
|
|
128
|
-
return INSERT_CHARACTER_AFTER_SELECTION;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (textDiff === -1 && prevAnchorOffset === nextAnchorOffset + 1) {
|
|
132
|
-
return DELETE_CHARACTER_BEFORE_SELECTION;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (textDiff === -1 && prevAnchorOffset === nextAnchorOffset) {
|
|
136
|
-
return DELETE_CHARACTER_AFTER_SELECTION;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return OTHER;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function createMergeActionGetter(editor, delay) {
|
|
143
|
-
let prevChangeTime = Date.now();
|
|
144
|
-
let prevChangeType = OTHER;
|
|
145
|
-
return (prevEditorState, nextEditorState, currentHistoryEntry, dirtyLeaves, dirtyElements, tags) => {
|
|
146
|
-
const changeTime = Date.now(); // If applying changes from history stack there's no need
|
|
147
|
-
// to run history logic again, as history entries already calculated
|
|
148
|
-
|
|
149
|
-
if (tags.has('historic')) {
|
|
150
|
-
prevChangeType = OTHER;
|
|
151
|
-
prevChangeTime = changeTime;
|
|
152
|
-
return DISCARD_HISTORY_CANDIDATE;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const changeType = getChangeType(prevEditorState, nextEditorState, dirtyLeaves, dirtyElements, editor.isComposing());
|
|
156
|
-
|
|
157
|
-
const mergeAction = (() => {
|
|
158
|
-
const shouldPushHistory = tags.has('history-push');
|
|
159
|
-
const shouldMergeHistory = !shouldPushHistory && tags.has('history-merge');
|
|
160
|
-
|
|
161
|
-
if (shouldMergeHistory) {
|
|
162
|
-
return HISTORY_MERGE;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (prevEditorState === null) {
|
|
166
|
-
return HISTORY_PUSH;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const selection = nextEditorState._selection;
|
|
170
|
-
const prevSelection = prevEditorState._selection;
|
|
171
|
-
const hasDirtyNodes = dirtyLeaves.size > 0 || dirtyElements.size > 0;
|
|
172
|
-
|
|
173
|
-
if (!hasDirtyNodes) {
|
|
174
|
-
if (prevSelection === null && selection !== null) {
|
|
175
|
-
return HISTORY_MERGE;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return DISCARD_HISTORY_CANDIDATE;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const isSameEditor = currentHistoryEntry === null || currentHistoryEntry.editor === editor;
|
|
182
|
-
|
|
183
|
-
if (shouldPushHistory === false && changeType !== OTHER && changeType === prevChangeType && changeTime < prevChangeTime + delay && isSameEditor) {
|
|
184
|
-
return HISTORY_MERGE;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return HISTORY_PUSH;
|
|
188
|
-
})();
|
|
189
|
-
|
|
190
|
-
prevChangeTime = changeTime;
|
|
191
|
-
prevChangeType = changeType;
|
|
192
|
-
return mergeAction;
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
|
|
196
21
|
function useHistory(editor, externalHistoryState, delay = 1000) {
|
|
197
|
-
const historyState = react.useMemo(() => externalHistoryState || createEmptyHistoryState(), [externalHistoryState]);
|
|
198
|
-
const clearHistory = react.useCallback(() => {
|
|
199
|
-
historyState.undoStack = [];
|
|
200
|
-
historyState.redoStack = [];
|
|
201
|
-
historyState.current = null;
|
|
202
|
-
}, [historyState]);
|
|
22
|
+
const historyState = react.useMemo(() => externalHistoryState || history.createEmptyHistoryState(), [externalHistoryState]);
|
|
203
23
|
react.useEffect(() => {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const applyChange = ({
|
|
207
|
-
editorState,
|
|
208
|
-
prevEditorState,
|
|
209
|
-
dirtyLeaves,
|
|
210
|
-
dirtyElements,
|
|
211
|
-
tags
|
|
212
|
-
}) => {
|
|
213
|
-
const current = historyState.current;
|
|
214
|
-
const redoStack = historyState.redoStack;
|
|
215
|
-
const undoStack = historyState.undoStack;
|
|
216
|
-
const currentEditorState = current === null ? null : current.editorState;
|
|
217
|
-
|
|
218
|
-
if (current !== null && editorState === currentEditorState) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const mergeAction = getMergeAction(prevEditorState, editorState, current, dirtyLeaves, dirtyElements, tags);
|
|
223
|
-
|
|
224
|
-
if (mergeAction === HISTORY_PUSH) {
|
|
225
|
-
if (redoStack.length !== 0) {
|
|
226
|
-
historyState.redoStack = [];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (current !== null) {
|
|
230
|
-
undoStack.push({ ...current,
|
|
231
|
-
undoSelection: prevEditorState.read(lexical.$getSelection)
|
|
232
|
-
});
|
|
233
|
-
editor.execCommand('canUndo', true);
|
|
234
|
-
}
|
|
235
|
-
} else if (mergeAction === DISCARD_HISTORY_CANDIDATE) {
|
|
236
|
-
return;
|
|
237
|
-
} // Else we merge
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
historyState.current = {
|
|
241
|
-
editor,
|
|
242
|
-
editorState
|
|
243
|
-
};
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
const undo = () => {
|
|
247
|
-
const redoStack = historyState.redoStack;
|
|
248
|
-
const undoStack = historyState.undoStack;
|
|
249
|
-
const undoStackLength = undoStack.length;
|
|
250
|
-
|
|
251
|
-
if (undoStackLength !== 0) {
|
|
252
|
-
const current = historyState.current;
|
|
253
|
-
const historyStateEntry = undoStack.pop();
|
|
254
|
-
|
|
255
|
-
if (current !== null) {
|
|
256
|
-
redoStack.push(current);
|
|
257
|
-
editor.execCommand('canRedo', true);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (undoStack.length === 0) {
|
|
261
|
-
editor.execCommand('canUndo', false);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
historyState.current = historyStateEntry;
|
|
265
|
-
historyStateEntry.editor.setEditorState(historyStateEntry.editorState.clone(historyStateEntry.undoSelection), {
|
|
266
|
-
tag: 'historic'
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
const redo = () => {
|
|
272
|
-
const redoStack = historyState.redoStack;
|
|
273
|
-
const undoStack = historyState.undoStack;
|
|
274
|
-
|
|
275
|
-
if (redoStack.length !== 0) {
|
|
276
|
-
const current = historyState.current;
|
|
277
|
-
|
|
278
|
-
if (current !== null) {
|
|
279
|
-
undoStack.push(current);
|
|
280
|
-
editor.execCommand('canUndo', true);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const historyStateEntry = redoStack.pop();
|
|
284
|
-
|
|
285
|
-
if (redoStack.length === 0) {
|
|
286
|
-
editor.execCommand('canRedo', false);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
historyState.current = historyStateEntry;
|
|
290
|
-
historyStateEntry.editor.setEditorState(historyStateEntry.editorState, {
|
|
291
|
-
tag: 'historic'
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
const applyCommand = type => {
|
|
297
|
-
switch (type) {
|
|
298
|
-
case 'undo':
|
|
299
|
-
undo();
|
|
300
|
-
return true;
|
|
301
|
-
|
|
302
|
-
case 'redo':
|
|
303
|
-
redo();
|
|
304
|
-
return true;
|
|
305
|
-
|
|
306
|
-
case 'clearEditor':
|
|
307
|
-
clearHistory();
|
|
308
|
-
return false;
|
|
309
|
-
|
|
310
|
-
case 'clearHistory':
|
|
311
|
-
clearHistory();
|
|
312
|
-
return true;
|
|
313
|
-
|
|
314
|
-
default:
|
|
315
|
-
return false;
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
return withSubscriptions(editor.addListener('command', applyCommand, EditorPriority), editor.addListener('update', applyChange));
|
|
320
|
-
}, [clearHistory, delay, editor, historyState]);
|
|
321
|
-
}
|
|
322
|
-
function createEmptyHistoryState() {
|
|
323
|
-
return {
|
|
324
|
-
current: null,
|
|
325
|
-
redoStack: [],
|
|
326
|
-
undoStack: []
|
|
327
|
-
};
|
|
24
|
+
return history.registerHistory(editor, historyState, delay);
|
|
25
|
+
}, [delay, editor, historyState]);
|
|
328
26
|
}
|
|
329
27
|
|
|
330
28
|
/**
|
|
@@ -343,5 +41,5 @@ function HistoryPlugin({
|
|
|
343
41
|
return null;
|
|
344
42
|
}
|
|
345
43
|
|
|
44
|
+
exports.createEmptyHistoryState = history.createEmptyHistoryState;
|
|
346
45
|
exports.HistoryPlugin = HistoryPlugin;
|
|
347
|
-
exports.createEmptyHistoryState = createEmptyHistoryState;
|
|
@@ -4,10 +4,4 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var
|
|
8
|
-
function x(b,d,l,a,h){if(null===b||0===l.size&&0===a.size)return 0;var g=d._selection,c=b._selection;if(h)return 1;if(!(v.$isRangeSelection(g)&&v.$isRangeSelection(c)&&c.isCollapsed()&&g.isCollapsed()))return 0;var e=Array.from(l);a=Array.from(a);l=d._nodeMap;h=[];for(var f=0;f<e.length;f++){const k=l.get(e[f]);void 0!==k&&h.push(k)}for(e=0;e<a.length;e++)a[e][1]&&(f=l.get(a[e][0]),void 0===f||v.$isRootNode(f)||h.push(f));if(0===h.length)return 0;if(1<h.length)return a=d._nodeMap,d=a.get(g.anchor.key),
|
|
9
|
-
c=a.get(c.anchor.key),d&&c&&!b._nodeMap.has(d.__key)&&v.$isTextNode(d)&&1===d.__text.length&&1===g.anchor.offset?2:0;d=h[0];b=b._nodeMap.get(d.__key);if(!v.$isTextNode(b)||!v.$isTextNode(d)||b.__mode!==d.__mode)return 0;b=b.__text;d=d.__text;if(b===d)return 0;g=g.anchor;c=c.anchor;if(g.key!==c.key||"text"!==g.type)return 0;g=g.offset;c=c.offset;b=d.length-b.length;return 1===b&&c===g-1?2:-1===b&&c===g+1?3:-1===b&&c===g?4:0}
|
|
10
|
-
function y(b,d){let l=Date.now(),a=0;return(h,g,c,e,f,k)=>{const p=Date.now();if(k.has("historic"))return a=0,l=p,2;const m=x(h,g,e,f,b.isComposing()),u=(()=>{const r=k.has("history-push");if(!r&&k.has("history-merge"))return 0;if(null===h)return 1;var q=g._selection;const A=h._selection;if(!(0<e.size||0<f.size))return null===A&&null!==q?0:2;q=null===c||c.editor===b;return!1===r&&0!==m&&m===a&&p<l+d&&q?0:1})();l=p;a=m;return u}}
|
|
11
|
-
function z(b,d,l=1E3){const a=w.useMemo(()=>d||B(),[d]),h=w.useCallback(()=>{a.undoStack=[];a.redoStack=[];a.current=null},[a]);w.useEffect(()=>{const g=y(b,l);return t(b.addListener("command",c=>{switch(c){case "undo":c=a.redoStack;var e=a.undoStack;if(0!==e.length){var f=a.current;const k=e.pop();null!==f&&(c.push(f),b.execCommand("canRedo",!0));0===e.length&&b.execCommand("canUndo",!1);a.current=k;k.editor.setEditorState(k.editorState.clone(k.undoSelection),{tag:"historic"})}return!0;case "redo":return c=
|
|
12
|
-
a.redoStack,e=a.undoStack,0!==c.length&&(f=a.current,null!==f&&(e.push(f),b.execCommand("canUndo",!0)),e=c.pop(),0===c.length&&b.execCommand("canRedo",!1),a.current=e,e.editor.setEditorState(e.editorState,{tag:"historic"})),!0;case "clearEditor":return h(),!1;case "clearHistory":return h(),!0;default:return!1}},0),b.addListener("update",({editorState:c,prevEditorState:e,dirtyLeaves:f,dirtyElements:k,tags:p})=>{const m=a.current,u=a.redoStack,r=a.undoStack,q=null===m?null:m.editorState;if(null===m||
|
|
13
|
-
c!==q){f=g(e,c,m,f,k,p);if(1===f)0!==u.length&&(a.redoStack=[]),null!==m&&(r.push({...m,undoSelection:e.read(v.$getSelection)}),b.execCommand("canUndo",!0));else if(2===f)return;a.current={editor:b,editorState:c}}}))},[h,l,b,a])}function B(){return{current:null,redoStack:[],undoStack:[]}}exports.HistoryPlugin=function({externalHistoryState:b}){const [d]=n.useLexicalComposerContext();z(d,b);return null};exports.createEmptyHistoryState=B;
|
|
7
|
+
var c=require("@lexical/react/LexicalComposerContext"),d=require("@lexical/history"),g=require("react");function h(a,b,e=1E3){const f=g.useMemo(()=>b||d.createEmptyHistoryState(),[b]);g.useEffect(()=>d.registerHistory(a,f,e),[e,a,f])}exports.createEmptyHistoryState=d.createEmptyHistoryState;exports.HistoryPlugin=function({externalHistoryState:a}){const [b]=c.useLexicalComposerContext();h(b,a);return null};
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type {LexicalNode} from 'lexical';
|
|
9
|
+
import type {LexicalNode, LexicalCommand} from 'lexical';
|
|
10
10
|
import {DecoratorNode} from 'lexical';
|
|
11
11
|
export declare class HorizontalRuleNode extends DecoratorNode<React.ReactNode> {
|
|
12
12
|
getType(): string;
|
|
@@ -21,3 +21,5 @@ export function $createHorizontalRuleNode(): HorizontalRuleNode;
|
|
|
21
21
|
export function $isHorizontalRuleNode(
|
|
22
22
|
node: LexicalNode | null | undefined,
|
|
23
23
|
): boolean;
|
|
24
|
+
|
|
25
|
+
export var INSERT_HORIZONTAL_RULE_COMMAND: LexicalCommand<void>;
|
|
@@ -17,6 +17,7 @@ var React = require('react');
|
|
|
17
17
|
*
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
|
+
const INSERT_HORIZONTAL_RULE_COMMAND = lexical.createCommand();
|
|
20
21
|
|
|
21
22
|
function HorizontalRuleComponent() {
|
|
22
23
|
return /*#__PURE__*/React.createElement("hr", null);
|
|
@@ -64,3 +65,4 @@ function $isHorizontalRuleNode(node) {
|
|
|
64
65
|
exports.$createHorizontalRuleNode = $createHorizontalRuleNode;
|
|
65
66
|
exports.$isHorizontalRuleNode = $isHorizontalRuleNode;
|
|
66
67
|
exports.HorizontalRuleNode = HorizontalRuleNode;
|
|
68
|
+
exports.INSERT_HORIZONTAL_RULE_COMMAND = INSERT_HORIZONTAL_RULE_COMMAND;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @flow strict
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type {LexicalNode} from 'lexical';
|
|
10
|
+
import type {LexicalNode, LexicalCommand} from 'lexical';
|
|
11
11
|
|
|
12
12
|
import {DecoratorNode} from 'lexical';
|
|
13
13
|
|
|
@@ -22,4 +22,8 @@ declare export class HorizontalRuleNode extends DecoratorNode<React$Node> {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
declare export function $createHorizontalRuleNode(): HorizontalRuleNode;
|
|
25
|
-
declare export function $isHorizontalRuleNode(
|
|
25
|
+
declare export function $isHorizontalRuleNode(
|
|
26
|
+
node: ?LexicalNode,
|
|
27
|
+
): boolean %checks(node instanceof HorizontalRuleNode);
|
|
28
|
+
|
|
29
|
+
declare export var INSERT_HORIZONTAL_RULE_COMMAND: LexicalCommand<void>;
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var b=require("lexical"),c=require("react");
|
|
8
|
-
exports.$isHorizontalRuleNode=function(a){return a instanceof
|
|
7
|
+
var b=require("lexical"),c=require("react");const d=b.createCommand();function e(){return c.createElement("hr",null)}class f extends b.DecoratorNode{static getType(){return"horizontalrule"}static clone(a){return new f(a.__state,a.__key)}createDOM(){const a=document.createElement("div");a.style.display="contents";return a}getTextContent(){return"\n"}isTopLevel(){return!0}updateDOM(){return!1}decorate(){return c.createElement(e,null)}}exports.$createHorizontalRuleNode=function(){return new f};
|
|
8
|
+
exports.$isHorizontalRuleNode=function(a){return a instanceof f};exports.HorizontalRuleNode=f;exports.INSERT_HORIZONTAL_RULE_COMMAND=d;
|
package/LexicalLinkPlugin.dev.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
+
var link = require('@lexical/link');
|
|
9
10
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
10
11
|
var lexical = require('lexical');
|
|
11
|
-
var LinkNode = require('lexical/LinkNode');
|
|
12
12
|
var react = require('react');
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -38,7 +38,7 @@ function toggleLink(url) {
|
|
|
38
38
|
nodes.forEach(node => {
|
|
39
39
|
const parent = node.getParent();
|
|
40
40
|
|
|
41
|
-
if (
|
|
41
|
+
if (link.$isLinkNode(parent)) {
|
|
42
42
|
const children = parent.getChildren();
|
|
43
43
|
|
|
44
44
|
for (let i = 0; i < children.length; i++) {
|
|
@@ -50,42 +50,40 @@ function toggleLink(url) {
|
|
|
50
50
|
});
|
|
51
51
|
} else {
|
|
52
52
|
// Add or merge LinkNodes
|
|
53
|
-
let prevParent = null;
|
|
54
|
-
let linkNode = null;
|
|
55
|
-
|
|
56
53
|
if (nodes.length === 1) {
|
|
57
54
|
const firstNode = nodes[0]; // if the first node is a LinkNode or if its
|
|
58
55
|
// parent is a LinkNode, we update the URL.
|
|
59
56
|
|
|
60
|
-
if (
|
|
57
|
+
if (link.$isLinkNode(firstNode)) {
|
|
61
58
|
firstNode.setURL(url);
|
|
62
59
|
return;
|
|
63
60
|
} else {
|
|
64
61
|
const parent = firstNode.getParent();
|
|
65
62
|
|
|
66
|
-
if (
|
|
63
|
+
if (link.$isLinkNode(parent)) {
|
|
67
64
|
// set parent to be the current linkNode
|
|
68
65
|
// so that other nodes in the same parent
|
|
69
66
|
// aren't handled separately below.
|
|
70
|
-
linkNode = parent;
|
|
71
67
|
parent.setURL(url);
|
|
72
68
|
return;
|
|
73
69
|
}
|
|
74
70
|
}
|
|
75
71
|
}
|
|
76
72
|
|
|
73
|
+
let prevParent = null;
|
|
74
|
+
let linkNode = null;
|
|
77
75
|
nodes.forEach(node => {
|
|
78
76
|
const parent = node.getParent();
|
|
79
77
|
|
|
80
|
-
if (parent === linkNode || parent === null) {
|
|
78
|
+
if (parent === linkNode || parent === null || lexical.$isElementNode(node) && !node.isInline()) {
|
|
81
79
|
return;
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
if (!parent.is(prevParent)) {
|
|
85
83
|
prevParent = parent;
|
|
86
|
-
linkNode =
|
|
84
|
+
linkNode = link.$createLinkNode(url);
|
|
87
85
|
|
|
88
|
-
if (
|
|
86
|
+
if (link.$isLinkNode(parent)) {
|
|
89
87
|
if (node.getPreviousSibling() === null) {
|
|
90
88
|
parent.insertBefore(linkNode);
|
|
91
89
|
} else {
|
|
@@ -96,7 +94,7 @@ function toggleLink(url) {
|
|
|
96
94
|
}
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
if (
|
|
97
|
+
if (link.$isLinkNode(node)) {
|
|
100
98
|
if (linkNode !== null) {
|
|
101
99
|
const children = node.getChildren();
|
|
102
100
|
|
|
@@ -120,14 +118,15 @@ function toggleLink(url) {
|
|
|
120
118
|
function LinkPlugin() {
|
|
121
119
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
122
120
|
react.useEffect(() => {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
121
|
+
if (!editor.hasNodes([link.LinkNode])) {
|
|
122
|
+
throw new Error('LinkPlugin: LinkNode not registered on editor');
|
|
123
|
+
}
|
|
124
|
+
}, [editor]);
|
|
125
|
+
react.useEffect(() => {
|
|
126
|
+
return editor.registerCommand(link.TOGGLE_LINK_COMMAND, payload => {
|
|
127
|
+
const url = payload;
|
|
128
|
+
toggleLink(url);
|
|
129
|
+
return true;
|
|
131
130
|
}, EditorPriority);
|
|
132
131
|
}, [editor]);
|
|
133
132
|
return null;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var
|
|
8
|
-
function p(
|
|
9
|
-
|
|
7
|
+
var g=require("@lexical/link"),k=require("@lexical/react/LexicalComposerContext"),m=require("lexical"),n=require("react");
|
|
8
|
+
function p(e){var b=m.$getSelection();null!==b&&m.$setSelection(b);b=m.$getSelection();if(null!==b)if(b=b.extract(),null===e)b.forEach(f=>{f=f.getParent();if(g.$isLinkNode(f)){const c=f.getChildren();for(let a=0;a<c.length;a++)f.insertBefore(c[a]);f.remove()}});else{if(1===b.length){var h=b[0];if(g.$isLinkNode(h)){h.setURL(e);return}h=h.getParent();if(g.$isLinkNode(h)){h.setURL(e);return}}let f=null,c=null;b.forEach(a=>{var d=a.getParent();if(d!==c&&null!==d&&(!m.$isElementNode(a)||a.isInline()))if(d.is(f)||
|
|
9
|
+
(f=d,c=g.$createLinkNode(e),g.$isLinkNode(d)?null===a.getPreviousSibling()?d.insertBefore(c):d.insertAfter(c):a.insertBefore(c)),g.$isLinkNode(a)){if(null!==c){d=a.getChildren();for(let l=0;l<d.length;l++)c.append(d[l])}a.remove()}else null!==c&&c.append(a)})}}
|
|
10
|
+
module.exports=function(){const [e]=k.useLexicalComposerContext();n.useEffect(()=>{if(!e.hasNodes([g.LinkNode]))throw Error("LinkPlugin: LinkNode not registered on editor");},[e]);n.useEffect(()=>e.registerCommand(g.TOGGLE_LINK_COMMAND,b=>{p(b);return!0},0),[e]);return null};
|
package/LexicalListPlugin.dev.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
10
10
|
var list = require('@lexical/list');
|
|
11
|
+
var utils = require('@lexical/utils');
|
|
12
|
+
var lexical = require('lexical');
|
|
11
13
|
var react = require('react');
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -21,38 +23,40 @@ var react = require('react');
|
|
|
21
23
|
const LowPriority = 1;
|
|
22
24
|
function useList(editor) {
|
|
23
25
|
react.useEffect(() => {
|
|
24
|
-
return editor.
|
|
25
|
-
|
|
26
|
-
const hasHandledIndention = list.indentList();
|
|
26
|
+
return utils.mergeRegister(editor.registerCommand(lexical.INDENT_CONTENT_COMMAND, () => {
|
|
27
|
+
const hasHandledIndention = list.indentList();
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
} else if (type === 'outdentContent') {
|
|
32
|
-
const hasHandledIndention = list.outdentList();
|
|
33
|
-
|
|
34
|
-
if (hasHandledIndention) {
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
} else if (type === 'insertOrderedList') {
|
|
38
|
-
list.insertList(editor, 'ol');
|
|
39
|
-
return true;
|
|
40
|
-
} else if (type === 'insertUnorderedList') {
|
|
41
|
-
list.insertList(editor, 'ul');
|
|
29
|
+
if (hasHandledIndention) {
|
|
42
30
|
return true;
|
|
43
|
-
}
|
|
44
|
-
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return false;
|
|
34
|
+
}, LowPriority), editor.registerCommand(lexical.OUTDENT_CONTENT_COMMAND, () => {
|
|
35
|
+
const hasHandledIndention = list.outdentList();
|
|
36
|
+
|
|
37
|
+
if (hasHandledIndention) {
|
|
45
38
|
return true;
|
|
46
|
-
}
|
|
47
|
-
const hasHandledInsertParagraph = list.$handleListInsertParagraph();
|
|
39
|
+
}
|
|
48
40
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
return false;
|
|
42
|
+
}, LowPriority), editor.registerCommand(list.INSERT_ORDERED_LIST_COMMAND, () => {
|
|
43
|
+
list.insertList(editor, 'ol');
|
|
44
|
+
return true;
|
|
45
|
+
}, LowPriority), editor.registerCommand(list.INSERT_UNORDERED_LIST_COMMAND, () => {
|
|
46
|
+
list.insertList(editor, 'ul');
|
|
47
|
+
return true;
|
|
48
|
+
}, LowPriority), editor.registerCommand(list.REMOVE_LIST_COMMAND, () => {
|
|
49
|
+
list.removeList(editor);
|
|
50
|
+
return true;
|
|
51
|
+
}, LowPriority), editor.registerCommand(lexical.INSERT_PARAGRAPH_COMMAND, () => {
|
|
52
|
+
const hasHandledInsertParagraph = list.$handleListInsertParagraph();
|
|
53
|
+
|
|
54
|
+
if (hasHandledInsertParagraph) {
|
|
55
|
+
return true;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
return false;
|
|
55
|
-
}, LowPriority);
|
|
59
|
+
}, LowPriority));
|
|
56
60
|
}, [editor]);
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -4,5 +4,6 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var b=require("@lexical/react/LexicalComposerContext"),
|
|
8
|
-
function
|
|
7
|
+
var b=require("@lexical/react/LexicalComposerContext"),c=require("@lexical/list"),d=require("@lexical/utils"),e=require("lexical"),f=require("react");
|
|
8
|
+
function g(a){f.useEffect(()=>d.mergeRegister(a.registerCommand(e.INDENT_CONTENT_COMMAND,()=>c.indentList()?!0:!1,1),a.registerCommand(e.OUTDENT_CONTENT_COMMAND,()=>c.outdentList()?!0:!1,1),a.registerCommand(c.INSERT_ORDERED_LIST_COMMAND,()=>{c.insertList(a,"ol");return!0},1),a.registerCommand(c.INSERT_UNORDERED_LIST_COMMAND,()=>{c.insertList(a,"ul");return!0},1),a.registerCommand(c.REMOVE_LIST_COMMAND,()=>{c.removeList(a);return!0},1),a.registerCommand(e.INSERT_PARAGRAPH_COMMAND,()=>c.$handleListInsertParagraph()?
|
|
9
|
+
!0:!1,1)),[a])}module.exports=function(){const [a]=b.useLexicalComposerContext();g(a);return null};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
10
|
+
var markdown = require('@lexical/markdown');
|
|
11
|
+
var LexicalHorizontalRuleNode = require('@lexical/react/LexicalHorizontalRuleNode');
|
|
12
|
+
var react = require('react');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
16
|
+
*
|
|
17
|
+
* This source code is licensed under the MIT license found in the
|
|
18
|
+
* LICENSE file in the root directory of this source tree.
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
function useMarkdownShortcuts(editor) {
|
|
23
|
+
react.useEffect(() => {
|
|
24
|
+
return markdown.registerMarkdownShortcuts(editor, LexicalHorizontalRuleNode.$createHorizontalRuleNode);
|
|
25
|
+
}, [editor]);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
30
|
+
*
|
|
31
|
+
* This source code is licensed under the MIT license found in the
|
|
32
|
+
* LICENSE file in the root directory of this source tree.
|
|
33
|
+
*
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
function LexicalMarkdownShortcutPlugin() {
|
|
37
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
38
|
+
useMarkdownShortcuts(editor);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = LexicalMarkdownShortcutPlugin;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
'use strict'
|
|
8
|
+
const LexicalMarkdownShortcutPlugin = process.env.NODE_ENV === 'development' ? require('./LexicalMarkdownShortcutPlugin.dev.js') : require('./LexicalMarkdownShortcutPlugin.prod.js')
|
|
9
|
+
module.exports = LexicalMarkdownShortcutPlugin;
|