@lexical/react 0.1.7 → 0.1.8
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 +84 -0
- package/DEPRECATED_useLexical.js +9 -2
- package/DEPRECATED_useLexical.prod.js +8 -0
- package/DEPRECATED_useLexicalAutoFormatter.dev.js +642 -0
- package/DEPRECATED_useLexicalAutoFormatter.js +9 -11
- package/DEPRECATED_useLexicalAutoFormatter.prod.js +22 -0
- package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +136 -0
- package/DEPRECATED_useLexicalCanShowPlaceholder.js +9 -3
- package/DEPRECATED_useLexicalCanShowPlaceholder.prod.js +8 -0
- package/DEPRECATED_useLexicalCharacterLimit.dev.js +294 -0
- package/DEPRECATED_useLexicalCharacterLimit.js +9 -8
- package/DEPRECATED_useLexicalCharacterLimit.prod.js +14 -0
- package/DEPRECATED_useLexicalDecorators.dev.js +82 -0
- package/DEPRECATED_useLexicalDecorators.js +9 -2
- package/DEPRECATED_useLexicalDecorators.prod.js +8 -0
- package/DEPRECATED_useLexicalEditor.dev.js +52 -0
- package/DEPRECATED_useLexicalEditor.js +9 -1
- package/DEPRECATED_useLexicalEditor.prod.js +7 -0
- package/DEPRECATED_useLexicalEditorEvents.dev.js +96 -0
- package/DEPRECATED_useLexicalEditorEvents.js +9 -2
- package/DEPRECATED_useLexicalEditorEvents.prod.js +8 -0
- package/DEPRECATED_useLexicalHistory.dev.js +339 -0
- package/DEPRECATED_useLexicalHistory.js +9 -7
- package/DEPRECATED_useLexicalHistory.prod.js +13 -0
- package/DEPRECATED_useLexicalList.dev.js +64 -0
- package/DEPRECATED_useLexicalList.js +9 -1
- package/DEPRECATED_useLexicalList.prod.js +7 -0
- package/DEPRECATED_useLexicalPlainText.dev.js +755 -0
- package/DEPRECATED_useLexicalPlainText.js +9 -16
- package/DEPRECATED_useLexicalPlainText.prod.js +22 -0
- package/DEPRECATED_useLexicalRichText.dev.js +1326 -0
- package/DEPRECATED_useLexicalRichText.js +9 -30
- package/DEPRECATED_useLexicalRichText.prod.js +35 -0
- package/LexicalAutoFormatterPlugin.dev.js +645 -0
- package/LexicalAutoFormatterPlugin.js +9 -12
- package/LexicalAutoFormatterPlugin.prod.js +23 -0
- package/LexicalAutoLinkPlugin.dev.js +227 -0
- package/LexicalAutoLinkPlugin.js +9 -6
- package/LexicalAutoLinkPlugin.prod.js +12 -0
- package/LexicalBootstrapPlugin.dev.js +124 -0
- package/LexicalBootstrapPlugin.js +9 -0
- package/LexicalBootstrapPlugin.prod.js +8 -0
- package/LexicalCharacterLimitPlugin.dev.js +352 -0
- package/LexicalCharacterLimitPlugin.js +9 -8
- package/LexicalCharacterLimitPlugin.prod.js +14 -0
- package/LexicalCollaborationPlugin.dev.js +235 -0
- package/LexicalCollaborationPlugin.js +9 -8
- package/LexicalCollaborationPlugin.prod.js +14 -0
- package/LexicalComposer.dev.js +76 -0
- package/LexicalComposer.js +9 -3
- package/LexicalComposer.prod.js +9 -0
- package/LexicalComposerContext.dev.js +53 -0
- package/LexicalComposerContext.js +9 -1
- package/LexicalComposerContext.prod.js +7 -0
- package/LexicalContentEditable.dev.js +71 -0
- package/LexicalContentEditable.js +9 -3
- package/LexicalContentEditable.prod.js +9 -0
- package/LexicalHashtagPlugin.dev.js +152 -0
- package/LexicalHashtagPlugin.js +9 -4
- package/LexicalHashtagPlugin.prod.js +10 -0
- package/LexicalHistoryPlugin.dev.js +344 -0
- package/LexicalHistoryPlugin.js +9 -7
- package/LexicalHistoryPlugin.prod.js +13 -0
- package/LexicalHorizontalRulePlugin.dev.js +51 -0
- package/LexicalHorizontalRulePlugin.js +9 -1
- package/LexicalHorizontalRulePlugin.prod.js +7 -0
- package/LexicalLinkPlugin.dev.js +137 -0
- package/LexicalLinkPlugin.js +9 -3
- package/LexicalLinkPlugin.prod.js +9 -0
- package/LexicalListPlugin.dev.js +67 -0
- package/LexicalListPlugin.js +9 -2
- package/LexicalListPlugin.prod.js +8 -0
- package/LexicalNestedComposer.dev.js +60 -0
- package/LexicalNestedComposer.js +9 -2
- package/LexicalNestedComposer.prod.js +8 -0
- package/LexicalOnChangePlugin.dev.js +57 -0
- package/LexicalOnChangePlugin.js +9 -1
- package/LexicalOnChangePlugin.prod.js +7 -0
- package/LexicalPlainTextPlugin.dev.js +565 -0
- package/LexicalPlainTextPlugin.js +9 -13
- package/LexicalPlainTextPlugin.prod.js +17 -0
- package/LexicalRichTextPlugin.dev.js +1136 -0
- package/LexicalRichTextPlugin.js +9 -27
- package/LexicalRichTextPlugin.prod.js +31 -0
- package/LexicalTablePlugin.dev.js +95 -0
- package/LexicalTablePlugin.js +9 -3
- package/LexicalTablePlugin.prod.js +9 -0
- package/LexicalTreeView.dev.js +340 -0
- package/LexicalTreeView.js +9 -13
- package/LexicalTreeView.prod.js +19 -0
- package/README.md +1 -0
- package/package.json +4 -4
- package/useLexicalDecoratorMap.dev.js +83 -0
- package/useLexicalDecoratorMap.js +9 -2
- package/useLexicalDecoratorMap.prod.js +8 -0
- package/useLexicalIsTextContentEmpty.dev.js +84 -0
- package/useLexicalIsTextContentEmpty.js +9 -2
- package/useLexicalIsTextContentEmpty.prod.js +8 -0
- package/withSubscriptions.dev.js +23 -0
- package/withSubscriptions.js +9 -1
- package/withSubscriptions.prod.js +7 -0
|
@@ -0,0 +1,344 @@
|
|
|
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 withSubscriptions = require('@lexical/react/withSubscriptions');
|
|
11
|
+
var lexical = require('lexical');
|
|
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
|
+
const MERGE = 0;
|
|
23
|
+
const NO_MERGE = 1;
|
|
24
|
+
const DISCARD = 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 (nextSelection === null || prevSelection === null || !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;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const changeType = getChangeType(prevEditorState, nextEditorState, dirtyLeaves, dirtyElements, editor.isComposing());
|
|
156
|
+
|
|
157
|
+
const mergeAction = (() => {
|
|
158
|
+
if (tags.has('without-history')) {
|
|
159
|
+
return MERGE;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (prevEditorState === null) {
|
|
163
|
+
return NO_MERGE;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const selection = nextEditorState._selection;
|
|
167
|
+
const prevSelection = prevEditorState._selection;
|
|
168
|
+
const hasDirtyNodes = dirtyLeaves.size > 0 || dirtyElements.size > 0;
|
|
169
|
+
|
|
170
|
+
if (!hasDirtyNodes) {
|
|
171
|
+
if (prevSelection === null && selection !== null) {
|
|
172
|
+
return MERGE;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return DISCARD;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const isSameEditor = currentHistoryEntry === null || currentHistoryEntry.editor === editor;
|
|
179
|
+
|
|
180
|
+
if (changeType !== OTHER && changeType === prevChangeType && changeTime < prevChangeTime + delay && isSameEditor) {
|
|
181
|
+
return MERGE;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return NO_MERGE;
|
|
185
|
+
})();
|
|
186
|
+
|
|
187
|
+
prevChangeTime = changeTime;
|
|
188
|
+
prevChangeType = changeType;
|
|
189
|
+
return mergeAction;
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function useHistory(editor, externalHistoryState, delay = 1000) {
|
|
194
|
+
const historyState = react.useMemo(() => externalHistoryState || createEmptyHistoryState(), [externalHistoryState]);
|
|
195
|
+
const clearHistory = react.useCallback(() => {
|
|
196
|
+
historyState.undoStack = [];
|
|
197
|
+
historyState.redoStack = [];
|
|
198
|
+
historyState.current = null;
|
|
199
|
+
}, [historyState]);
|
|
200
|
+
react.useEffect(() => {
|
|
201
|
+
const getMergeAction = createMergeActionGetter(editor, delay);
|
|
202
|
+
|
|
203
|
+
const applyChange = ({
|
|
204
|
+
editorState,
|
|
205
|
+
prevEditorState,
|
|
206
|
+
dirtyLeaves,
|
|
207
|
+
dirtyElements,
|
|
208
|
+
tags
|
|
209
|
+
}) => {
|
|
210
|
+
const current = historyState.current;
|
|
211
|
+
const redoStack = historyState.redoStack;
|
|
212
|
+
const undoStack = historyState.undoStack;
|
|
213
|
+
const currentEditorState = current === null ? null : current.editorState;
|
|
214
|
+
|
|
215
|
+
if (current !== null && editorState === currentEditorState) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const mergeAction = getMergeAction(prevEditorState, editorState, current, dirtyLeaves, dirtyElements, tags);
|
|
220
|
+
|
|
221
|
+
if (mergeAction === NO_MERGE) {
|
|
222
|
+
if (redoStack.length !== 0) {
|
|
223
|
+
historyState.redoStack = [];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (current !== null) {
|
|
227
|
+
undoStack.push({ ...current,
|
|
228
|
+
undoSelection: prevEditorState.read(lexical.$getSelection)
|
|
229
|
+
});
|
|
230
|
+
editor.execCommand('canUndo', true);
|
|
231
|
+
}
|
|
232
|
+
} else if (mergeAction === DISCARD) {
|
|
233
|
+
return;
|
|
234
|
+
} // Else we merge
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
historyState.current = {
|
|
238
|
+
editor,
|
|
239
|
+
editorState
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const undo = () => {
|
|
244
|
+
const redoStack = historyState.redoStack;
|
|
245
|
+
const undoStack = historyState.undoStack;
|
|
246
|
+
const undoStackLength = undoStack.length;
|
|
247
|
+
|
|
248
|
+
if (undoStackLength !== 0) {
|
|
249
|
+
const current = historyState.current;
|
|
250
|
+
const historyStateEntry = undoStack.pop();
|
|
251
|
+
|
|
252
|
+
if (current !== null) {
|
|
253
|
+
redoStack.push(current);
|
|
254
|
+
editor.execCommand('canRedo', true);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (undoStack.length === 0) {
|
|
258
|
+
editor.execCommand('canUndo', false);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
historyState.current = historyStateEntry;
|
|
262
|
+
historyStateEntry.editor.setEditorState(historyStateEntry.editorState.clone(historyStateEntry.undoSelection), {
|
|
263
|
+
tag: 'historic'
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const redo = () => {
|
|
269
|
+
const redoStack = historyState.redoStack;
|
|
270
|
+
const undoStack = historyState.undoStack;
|
|
271
|
+
|
|
272
|
+
if (redoStack.length !== 0) {
|
|
273
|
+
const current = historyState.current;
|
|
274
|
+
|
|
275
|
+
if (current !== null) {
|
|
276
|
+
undoStack.push(current);
|
|
277
|
+
editor.execCommand('canUndo', true);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const historyStateEntry = redoStack.pop();
|
|
281
|
+
|
|
282
|
+
if (redoStack.length === 0) {
|
|
283
|
+
editor.execCommand('canRedo', false);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
historyState.current = historyStateEntry;
|
|
287
|
+
historyStateEntry.editor.setEditorState(historyStateEntry.editorState, {
|
|
288
|
+
tag: 'historic'
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const applyCommand = type => {
|
|
294
|
+
switch (type) {
|
|
295
|
+
case 'undo':
|
|
296
|
+
undo();
|
|
297
|
+
return true;
|
|
298
|
+
|
|
299
|
+
case 'redo':
|
|
300
|
+
redo();
|
|
301
|
+
return true;
|
|
302
|
+
|
|
303
|
+
case 'clearEditor':
|
|
304
|
+
clearHistory();
|
|
305
|
+
return false;
|
|
306
|
+
|
|
307
|
+
case 'clearHistory':
|
|
308
|
+
clearHistory();
|
|
309
|
+
return true;
|
|
310
|
+
|
|
311
|
+
default:
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
return withSubscriptions(editor.addListener('command', applyCommand, EditorPriority), editor.addListener('update', applyChange));
|
|
317
|
+
}, [clearHistory, delay, editor, historyState]);
|
|
318
|
+
}
|
|
319
|
+
function createEmptyHistoryState() {
|
|
320
|
+
return {
|
|
321
|
+
current: null,
|
|
322
|
+
redoStack: [],
|
|
323
|
+
undoStack: []
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
329
|
+
*
|
|
330
|
+
* This source code is licensed under the MIT license found in the
|
|
331
|
+
* LICENSE file in the root directory of this source tree.
|
|
332
|
+
*
|
|
333
|
+
*
|
|
334
|
+
*/
|
|
335
|
+
function HistoryPlugin({
|
|
336
|
+
externalHistoryState
|
|
337
|
+
}) {
|
|
338
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
339
|
+
useHistory(editor, externalHistoryState);
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
exports.HistoryPlugin = HistoryPlugin;
|
|
344
|
+
exports.createEmptyHistoryState = createEmptyHistoryState;
|
package/LexicalHistoryPlugin.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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 LexicalHistoryPlugin = process.env.NODE_ENV === 'development' ? require('./LexicalHistoryPlugin.dev.js') : require('./LexicalHistoryPlugin.prod.js')
|
|
9
|
+
module.exports = LexicalHistoryPlugin;
|
|
@@ -0,0 +1,13 @@
|
|
|
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';var n=require("@lexical/react/LexicalComposerContext"),r=require("@lexical/react/withSubscriptions"),v=require("lexical"),w=require("react");
|
|
8
|
+
function x(b,d,k,a,h){if(null===b||0===k.size&&0===a.size)return 0;var g=d._selection,c=b._selection;if(h)return 1;if(null===g||null===c||!c.isCollapsed()||!g.isCollapsed())return 0;var e=Array.from(k);a=Array.from(a);k=d._nodeMap;h=[];for(var f=0;f<e.length;f++){const l=k.get(e[f]);void 0!==l&&h.push(l)}for(e=0;e<a.length;e++)a[e][1]&&(f=k.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),c=a.get(c.anchor.key),d&&
|
|
9
|
+
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 k=Date.now(),a=0;return(h,g,c,e,f,l)=>{const p=Date.now();if(l.has("historic"))return a=0,k=p,2;const m=x(h,g,e,f,b.isComposing()),u=(()=>{if(l.has("without-history"))return 0;if(null===h)return 1;var q=g._selection;const t=h._selection;if(!(0<e.size||0<f.size))return null===t&&null!==q?0:2;q=null===c||c.editor===b;return 0!==m&&m===a&&p<k+d&&q?0:1})();k=p;a=m;return u}}
|
|
11
|
+
function z(b,d,k=1E3){const a=w.useMemo(()=>d||A(),[d]),h=w.useCallback(()=>{a.undoStack=[];a.redoStack=[];a.current=null},[a]);w.useEffect(()=>{const g=y(b,k);return r(b.addListener("command",c=>{switch(c){case "undo":c=a.redoStack;var e=a.undoStack;if(0!==e.length){var f=a.current;const l=e.pop();null!==f&&(c.push(f),b.execCommand("canRedo",!0));0===e.length&&b.execCommand("canUndo",!1);a.current=l;l.editor.setEditorState(l.editorState.clone(l.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:l,tags:p})=>{const m=a.current,u=a.redoStack,q=a.undoStack,t=null===m?null:m.editorState;if(null===m||
|
|
13
|
+
c!==t){f=g(e,c,m,f,l,p);if(1===f)0!==u.length&&(a.redoStack=[]),null!==m&&(q.push({...m,undoSelection:e.read(v.$getSelection)}),b.execCommand("canUndo",!0));else if(2===f)return;a.current={editor:b,editorState:c}}}))},[h,k,b,a])}function A(){return{current:null,redoStack:[],undoStack:[]}}exports.HistoryPlugin=function({externalHistoryState:b}){const [d]=n.useLexicalComposerContext();z(d,b);return null};exports.createEmptyHistoryState=A;
|
|
@@ -0,0 +1,51 @@
|
|
|
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 lexical = require('lexical');
|
|
11
|
+
var react = require('react');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
15
|
+
*
|
|
16
|
+
* This source code is licensed under the MIT license found in the
|
|
17
|
+
* LICENSE file in the root directory of this source tree.
|
|
18
|
+
*
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
const EditorPriority = 0;
|
|
22
|
+
function HorizontalRulePlugin() {
|
|
23
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
24
|
+
react.useEffect(() => {
|
|
25
|
+
return editor.addListener('command', type => {
|
|
26
|
+
if (type === 'insertHorizontalRule') {
|
|
27
|
+
lexical.$log('insertHorizontalRule');
|
|
28
|
+
const selection = lexical.$getSelection();
|
|
29
|
+
|
|
30
|
+
if (selection === null) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const focusNode = selection.focus.getNode();
|
|
35
|
+
|
|
36
|
+
if (focusNode !== null) {
|
|
37
|
+
const horizontalRuleNode = lexical.$createHorizontalRuleNode();
|
|
38
|
+
selection.insertParagraph();
|
|
39
|
+
selection.focus.getNode().getTopLevelElementOrThrow().insertBefore(horizontalRuleNode);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return false;
|
|
46
|
+
}, EditorPriority);
|
|
47
|
+
}, [editor]);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = HorizontalRulePlugin;
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
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 LexicalHorizontalRulePlugin = process.env.NODE_ENV === 'development' ? require('./LexicalHorizontalRulePlugin.dev.js') : require('./LexicalHorizontalRulePlugin.prod.js')
|
|
9
|
+
module.exports = LexicalHorizontalRulePlugin;
|
|
@@ -0,0 +1,7 @@
|
|
|
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';var b=require("@lexical/react/LexicalComposerContext"),d=require("lexical"),e=require("react");module.exports=function(){const [c]=b.useLexicalComposerContext();e.useEffect(()=>c.addListener("command",a=>{if("insertHorizontalRule"===a){d.$log("insertHorizontalRule");a=d.$getSelection();if(null===a)return!1;if(null!==a.focus.getNode()){const f=d.$createHorizontalRuleNode();a.insertParagraph();a.focus.getNode().getTopLevelElementOrThrow().insertBefore(f)}return!0}return!1},0),[c]);return null};
|
|
@@ -0,0 +1,137 @@
|
|
|
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 lexical = require('lexical');
|
|
11
|
+
var LinkNode = require('lexical/LinkNode');
|
|
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
|
+
const EditorPriority = 0;
|
|
23
|
+
|
|
24
|
+
function toggleLink(url) {
|
|
25
|
+
const selection = lexical.$getSelection();
|
|
26
|
+
lexical.$log('toggleLink');
|
|
27
|
+
|
|
28
|
+
if (selection !== null) {
|
|
29
|
+
lexical.$setSelection(selection);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const sel = lexical.$getSelection();
|
|
33
|
+
|
|
34
|
+
if (sel !== null) {
|
|
35
|
+
const nodes = sel.extract();
|
|
36
|
+
|
|
37
|
+
if (url === null) {
|
|
38
|
+
// Remove LinkNodes
|
|
39
|
+
nodes.forEach(node => {
|
|
40
|
+
const parent = node.getParent();
|
|
41
|
+
|
|
42
|
+
if (LinkNode.$isLinkNode(parent)) {
|
|
43
|
+
const children = parent.getChildren();
|
|
44
|
+
|
|
45
|
+
for (let i = 0; i < children.length; i++) {
|
|
46
|
+
parent.insertBefore(children[i]);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
parent.remove();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
// Add or merge LinkNodes
|
|
54
|
+
let prevParent = null;
|
|
55
|
+
let linkNode = null;
|
|
56
|
+
|
|
57
|
+
if (nodes.length === 1) {
|
|
58
|
+
const firstNode = nodes[0]; // if the first node is a LinkNode or if its
|
|
59
|
+
// parent is a LinkNode, we update the URL.
|
|
60
|
+
|
|
61
|
+
if (LinkNode.$isLinkNode(firstNode)) {
|
|
62
|
+
firstNode.setURL(url);
|
|
63
|
+
return;
|
|
64
|
+
} else {
|
|
65
|
+
const parent = firstNode.getParent();
|
|
66
|
+
|
|
67
|
+
if (LinkNode.$isLinkNode(parent)) {
|
|
68
|
+
// set parent to be the current linkNode
|
|
69
|
+
// so that other nodes in the same parent
|
|
70
|
+
// aren't handled separately below.
|
|
71
|
+
linkNode = parent;
|
|
72
|
+
parent.setURL(url);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
nodes.forEach(node => {
|
|
79
|
+
const parent = node.getParent();
|
|
80
|
+
|
|
81
|
+
if (parent === linkNode || parent === null) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!parent.is(prevParent)) {
|
|
86
|
+
prevParent = parent;
|
|
87
|
+
linkNode = LinkNode.$createLinkNode(url);
|
|
88
|
+
|
|
89
|
+
if (LinkNode.$isLinkNode(parent)) {
|
|
90
|
+
if (node.getPreviousSibling() === null) {
|
|
91
|
+
parent.insertBefore(linkNode);
|
|
92
|
+
} else {
|
|
93
|
+
parent.insertAfter(linkNode);
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
node.insertBefore(linkNode);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (LinkNode.$isLinkNode(node)) {
|
|
101
|
+
if (linkNode !== null) {
|
|
102
|
+
const children = node.getChildren();
|
|
103
|
+
|
|
104
|
+
for (let i = 0; i < children.length; i++) {
|
|
105
|
+
linkNode.append(children[i]);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
node.remove();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (linkNode !== null) {
|
|
114
|
+
linkNode.append(node);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function LinkPlugin() {
|
|
122
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
123
|
+
react.useEffect(() => {
|
|
124
|
+
return editor.addListener('command', (type, payload) => {
|
|
125
|
+
if (type === 'toggleLink') {
|
|
126
|
+
const url = payload;
|
|
127
|
+
toggleLink(url);
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return false;
|
|
132
|
+
}, EditorPriority);
|
|
133
|
+
}, [editor]);
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = LinkPlugin;
|
package/LexicalLinkPlugin.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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 LexicalLinkPlugin = process.env.NODE_ENV === 'development' ? require('./LexicalLinkPlugin.dev.js') : require('./LexicalLinkPlugin.prod.js')
|
|
9
|
+
module.exports = LexicalLinkPlugin;
|
|
@@ -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';var h=require("@lexical/react/LexicalComposerContext"),k=require("lexical"),m=require("lexical/LinkNode"),n=require("react");
|
|
8
|
+
function p(g){var b=k.$getSelection();k.$log("toggleLink");null!==b&&k.$setSelection(b);b=k.$getSelection();if(null!==b)if(b=b.extract(),null===g)b.forEach(e=>{e=e.getParent();if(m.$isLinkNode(e)){const a=e.getChildren();for(let c=0;c<a.length;c++)e.insertBefore(a[c]);e.remove()}});else{let e=null,a=null;if(1===b.length){var f=b[0];if(m.$isLinkNode(f)){f.setURL(g);return}f=f.getParent();if(m.$isLinkNode(f)){a=f;f.setURL(g);return}}b.forEach(c=>{var d=c.getParent();if(d!==a&&null!==d)if(d.is(e)||(e=
|
|
9
|
+
d,a=m.$createLinkNode(g),m.$isLinkNode(d)?null===c.getPreviousSibling()?d.insertBefore(a):d.insertAfter(a):c.insertBefore(a)),m.$isLinkNode(c)){if(null!==a){d=c.getChildren();for(let l=0;l<d.length;l++)a.append(d[l])}c.remove()}else null!==a&&a.append(c)})}}module.exports=function(){const [g]=h.useLexicalComposerContext();n.useEffect(()=>g.addListener("command",(b,f)=>"toggleLink"===b?(p(f),!0):!1,0),[g]);return null};
|
|
@@ -0,0 +1,67 @@
|
|
|
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 list = require('@lexical/list');
|
|
11
|
+
var react = require('react');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
15
|
+
*
|
|
16
|
+
* This source code is licensed under the MIT license found in the
|
|
17
|
+
* LICENSE file in the root directory of this source tree.
|
|
18
|
+
*
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
const LowPriority = 1;
|
|
22
|
+
function useList(editor) {
|
|
23
|
+
react.useEffect(() => {
|
|
24
|
+
return editor.addListener('command', type => {
|
|
25
|
+
if (type === 'indentContent') {
|
|
26
|
+
const hasHandledIndention = list.indentList();
|
|
27
|
+
|
|
28
|
+
if (hasHandledIndention) {
|
|
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');
|
|
42
|
+
return true;
|
|
43
|
+
} else if (type === 'removeList') {
|
|
44
|
+
list.removeList(editor);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return false;
|
|
49
|
+
}, LowPriority);
|
|
50
|
+
}, [editor]);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
55
|
+
*
|
|
56
|
+
* This source code is licensed under the MIT license found in the
|
|
57
|
+
* LICENSE file in the root directory of this source tree.
|
|
58
|
+
*
|
|
59
|
+
*
|
|
60
|
+
*/
|
|
61
|
+
function ListPlugin() {
|
|
62
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
63
|
+
useList(editor);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = ListPlugin;
|