@lexical/react 0.35.1-nightly.20250924.0 → 0.36.0

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.
Files changed (154) hide show
  1. package/ExtensionComponent.d.ts +42 -0
  2. package/LexicalAutoEmbedPlugin.dev.js +2 -0
  3. package/LexicalAutoEmbedPlugin.dev.mjs +2 -0
  4. package/LexicalAutoEmbedPlugin.prod.js +1 -1
  5. package/LexicalAutoEmbedPlugin.prod.mjs +1 -1
  6. package/LexicalAutoLinkPlugin.d.ts +2 -17
  7. package/LexicalAutoLinkPlugin.dev.js +7 -309
  8. package/LexicalAutoLinkPlugin.dev.mjs +9 -310
  9. package/LexicalAutoLinkPlugin.js.flow +4 -18
  10. package/LexicalAutoLinkPlugin.prod.js +1 -1
  11. package/LexicalAutoLinkPlugin.prod.mjs +1 -1
  12. package/LexicalClearEditorPlugin.dev.js +2 -23
  13. package/LexicalClearEditorPlugin.dev.mjs +2 -23
  14. package/LexicalClearEditorPlugin.prod.js +1 -1
  15. package/LexicalClearEditorPlugin.prod.mjs +1 -1
  16. package/LexicalClickableLinkPlugin.dev.js +5 -70
  17. package/LexicalClickableLinkPlugin.dev.mjs +6 -71
  18. package/LexicalClickableLinkPlugin.prod.js +1 -1
  19. package/LexicalClickableLinkPlugin.prod.mjs +1 -1
  20. package/LexicalCollaborationContext.prod.js +1 -1
  21. package/LexicalCollaborationContext.prod.mjs +1 -1
  22. package/LexicalCollaborationPlugin.dev.mjs +2 -2
  23. package/LexicalCollaborationPlugin.prod.mjs +1 -1
  24. package/LexicalContentEditable.dev.js +2 -3
  25. package/LexicalContentEditable.dev.mjs +2 -3
  26. package/LexicalContentEditable.prod.js +1 -1
  27. package/LexicalContentEditable.prod.mjs +1 -1
  28. package/LexicalContextMenuPlugin.dev.js +2 -0
  29. package/LexicalContextMenuPlugin.dev.mjs +4 -2
  30. package/LexicalContextMenuPlugin.prod.js +1 -1
  31. package/LexicalContextMenuPlugin.prod.mjs +1 -1
  32. package/LexicalDecoratorBlockNode.dev.js +1 -0
  33. package/LexicalDecoratorBlockNode.dev.mjs +1 -0
  34. package/LexicalDecoratorBlockNode.js.flow +7 -0
  35. package/LexicalDecoratorBlockNode.prod.js +1 -1
  36. package/LexicalDecoratorBlockNode.prod.mjs +1 -1
  37. package/LexicalDraggableBlockPlugin.dev.js +6 -0
  38. package/LexicalDraggableBlockPlugin.dev.mjs +6 -0
  39. package/LexicalDraggableBlockPlugin.prod.js +1 -1
  40. package/LexicalDraggableBlockPlugin.prod.mjs +1 -1
  41. package/LexicalExtensionComponent.dev.js +53 -0
  42. package/LexicalExtensionComponent.dev.mjs +51 -0
  43. package/LexicalExtensionComponent.js +11 -0
  44. package/LexicalExtensionComponent.js.flow +12 -0
  45. package/LexicalExtensionComponent.mjs +12 -0
  46. package/LexicalExtensionComponent.node.mjs +10 -0
  47. package/LexicalExtensionComponent.prod.js +9 -0
  48. package/LexicalExtensionComponent.prod.mjs +9 -0
  49. package/LexicalExtensionComposer.d.ts +69 -0
  50. package/LexicalExtensionComposer.dev.js +105 -0
  51. package/LexicalExtensionComposer.dev.mjs +103 -0
  52. package/LexicalExtensionComposer.js +11 -0
  53. package/LexicalExtensionComposer.js.flow +20 -0
  54. package/LexicalExtensionComposer.mjs +12 -0
  55. package/LexicalExtensionComposer.node.mjs +10 -0
  56. package/LexicalExtensionComposer.prod.js +9 -0
  57. package/LexicalExtensionComposer.prod.mjs +9 -0
  58. package/LexicalHashtagPlugin.dev.js +1 -136
  59. package/LexicalHashtagPlugin.dev.mjs +3 -138
  60. package/LexicalHashtagPlugin.prod.js +1 -1
  61. package/LexicalHashtagPlugin.prod.mjs +1 -1
  62. package/LexicalHorizontalRuleNode.d.ts +10 -11
  63. package/LexicalHorizontalRuleNode.dev.js +12 -26
  64. package/LexicalHorizontalRuleNode.dev.mjs +14 -27
  65. package/LexicalHorizontalRuleNode.js.flow +2 -3
  66. package/LexicalHorizontalRuleNode.prod.js +1 -1
  67. package/LexicalHorizontalRuleNode.prod.mjs +1 -1
  68. package/LexicalLinkPlugin.d.ts +1 -1
  69. package/LexicalLinkPlugin.dev.js +7 -52
  70. package/LexicalLinkPlugin.dev.mjs +8 -53
  71. package/LexicalLinkPlugin.prod.js +1 -1
  72. package/LexicalLinkPlugin.prod.mjs +1 -1
  73. package/LexicalListPlugin.js.flow +5 -0
  74. package/LexicalMarkdownShortcutPlugin.dev.mjs +1 -1
  75. package/LexicalMarkdownShortcutPlugin.prod.mjs +1 -1
  76. package/LexicalNestedComposer.js.flow +10 -6
  77. package/LexicalNodeContextMenuPlugin.dev.js +10 -0
  78. package/LexicalNodeContextMenuPlugin.dev.mjs +11 -1
  79. package/LexicalNodeContextMenuPlugin.prod.js +1 -1
  80. package/LexicalNodeContextMenuPlugin.prod.mjs +1 -1
  81. package/LexicalNodeMenuPlugin.dev.js +2 -0
  82. package/LexicalNodeMenuPlugin.dev.mjs +4 -2
  83. package/LexicalNodeMenuPlugin.prod.js +1 -1
  84. package/LexicalNodeMenuPlugin.prod.mjs +1 -1
  85. package/LexicalPlainTextPlugin.d.ts +1 -1
  86. package/LexicalPlainTextPlugin.dev.js +85 -30
  87. package/LexicalPlainTextPlugin.dev.mjs +85 -30
  88. package/LexicalPlainTextPlugin.prod.js +1 -1
  89. package/LexicalPlainTextPlugin.prod.mjs +1 -1
  90. package/LexicalReactExtension.dev.js +187 -0
  91. package/LexicalReactExtension.dev.mjs +184 -0
  92. package/LexicalReactExtension.js +11 -0
  93. package/LexicalReactExtension.js.flow +68 -0
  94. package/LexicalReactExtension.mjs +13 -0
  95. package/LexicalReactExtension.node.mjs +11 -0
  96. package/LexicalReactExtension.prod.js +9 -0
  97. package/LexicalReactExtension.prod.mjs +9 -0
  98. package/LexicalReactPluginHostExtension.dev.js +189 -0
  99. package/LexicalReactPluginHostExtension.dev.mjs +181 -0
  100. package/LexicalReactPluginHostExtension.js +11 -0
  101. package/LexicalReactPluginHostExtension.js.flow +84 -0
  102. package/LexicalReactPluginHostExtension.mjs +18 -0
  103. package/LexicalReactPluginHostExtension.node.mjs +16 -0
  104. package/LexicalReactPluginHostExtension.prod.js +9 -0
  105. package/LexicalReactPluginHostExtension.prod.mjs +9 -0
  106. package/LexicalReactProviderExtension.dev.js +33 -0
  107. package/LexicalReactProviderExtension.dev.mjs +31 -0
  108. package/LexicalReactProviderExtension.js +11 -0
  109. package/LexicalReactProviderExtension.js.flow +12 -0
  110. package/LexicalReactProviderExtension.mjs +12 -0
  111. package/LexicalReactProviderExtension.node.mjs +10 -0
  112. package/LexicalReactProviderExtension.prod.js +9 -0
  113. package/LexicalReactProviderExtension.prod.mjs +9 -0
  114. package/LexicalRichTextPlugin.d.ts +1 -1
  115. package/LexicalRichTextPlugin.dev.js +85 -30
  116. package/LexicalRichTextPlugin.dev.mjs +85 -30
  117. package/LexicalRichTextPlugin.prod.js +1 -1
  118. package/LexicalRichTextPlugin.prod.mjs +1 -1
  119. package/LexicalTabIndentationPlugin.d.ts +2 -2
  120. package/LexicalTabIndentationPlugin.dev.js +3 -57
  121. package/LexicalTabIndentationPlugin.dev.mjs +3 -56
  122. package/LexicalTabIndentationPlugin.prod.js +1 -1
  123. package/LexicalTabIndentationPlugin.prod.mjs +1 -1
  124. package/LexicalTreeViewExtension.dev.js +57 -0
  125. package/LexicalTreeViewExtension.dev.mjs +54 -0
  126. package/LexicalTreeViewExtension.js +11 -0
  127. package/LexicalTreeViewExtension.js.flow +12 -0
  128. package/LexicalTreeViewExtension.mjs +13 -0
  129. package/LexicalTreeViewExtension.node.mjs +11 -0
  130. package/LexicalTreeViewExtension.prod.js +9 -0
  131. package/LexicalTreeViewExtension.prod.mjs +9 -0
  132. package/LexicalTypeaheadMenuPlugin.dev.js +2 -0
  133. package/LexicalTypeaheadMenuPlugin.dev.mjs +4 -2
  134. package/LexicalTypeaheadMenuPlugin.prod.js +1 -1
  135. package/LexicalTypeaheadMenuPlugin.prod.mjs +1 -1
  136. package/ReactExtension.d.ts +41 -0
  137. package/ReactPluginHostExtension.d.ts +56 -0
  138. package/ReactProviderExtension.d.ts +9 -0
  139. package/TreeViewExtension.d.ts +18 -0
  140. package/package.json +228 -17
  141. package/shared/LegacyDecorators.d.ts +23 -0
  142. package/shared/buildEditorComponent.d.ts +11 -0
  143. package/shared/mergeRefs.d.ts +2 -1
  144. package/shared/types.d.ts +89 -0
  145. package/shared/useReactDecorators.d.ts +12 -0
  146. package/useExtensionComponent.d.ts +10 -0
  147. package/useLexicalExtensionComponent.dev.js +37 -0
  148. package/useLexicalExtensionComponent.dev.mjs +34 -0
  149. package/useLexicalExtensionComponent.js +11 -0
  150. package/useLexicalExtensionComponent.js.flow +12 -0
  151. package/useLexicalExtensionComponent.mjs +13 -0
  152. package/useLexicalExtensionComponent.node.mjs +11 -0
  153. package/useLexicalExtensionComponent.prod.js +9 -0
  154. package/useLexicalExtensionComponent.prod.mjs +9 -0
@@ -6,10 +6,9 @@
6
6
  *
7
7
  */
8
8
 
9
- import { AutoLinkNode, $isAutoLinkNode, $isLinkNode, TOGGLE_LINK_COMMAND, $createAutoLinkNode } from '@lexical/link';
9
+ import { AutoLinkNode, registerAutoLink } from '@lexical/link';
10
+ export { createLinkMatcherWithRegExp } from '@lexical/link';
10
11
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
11
- import { mergeRegister } from '@lexical/utils';
12
- import { TextNode, $getSelection, $isRangeSelection, COMMAND_PRIORITY_LOW, $isTextNode, $isElementNode, $isLineBreakNode, $createTextNode, $isNodeSelection } from 'lexical';
13
12
  import { useEffect } from 'react';
14
13
 
15
14
  /**
@@ -26,279 +25,6 @@ function formatDevErrorMessage(message) {
26
25
  throw new Error(message);
27
26
  }
28
27
 
29
- function createLinkMatcherWithRegExp(regExp, urlTransformer = text => text) {
30
- return text => {
31
- const match = regExp.exec(text);
32
- if (match === null) {
33
- return null;
34
- }
35
- return {
36
- index: match.index,
37
- length: match[0].length,
38
- text: match[0],
39
- url: urlTransformer(match[0])
40
- };
41
- };
42
- }
43
- function findFirstMatch(text, matchers) {
44
- for (let i = 0; i < matchers.length; i++) {
45
- const match = matchers[i](text);
46
- if (match) {
47
- return match;
48
- }
49
- }
50
- return null;
51
- }
52
- const PUNCTUATION_OR_SPACE = /[.,;\s]/;
53
- function isSeparator(char) {
54
- return PUNCTUATION_OR_SPACE.test(char);
55
- }
56
- function endsWithSeparator(textContent) {
57
- return isSeparator(textContent[textContent.length - 1]);
58
- }
59
- function startsWithSeparator(textContent) {
60
- return isSeparator(textContent[0]);
61
- }
62
-
63
- /**
64
- * Check if the text content starts with a fullstop followed by a top-level domain.
65
- * Meaning if the text content can be a beginning of a top level domain.
66
- * @param textContent
67
- * @param isEmail
68
- * @returns boolean
69
- */
70
- function startsWithTLD(textContent, isEmail) {
71
- if (isEmail) {
72
- return /^\.[a-zA-Z]{2,}/.test(textContent);
73
- } else {
74
- return /^\.[a-zA-Z0-9]{1,}/.test(textContent);
75
- }
76
- }
77
- function isPreviousNodeValid(node) {
78
- let previousNode = node.getPreviousSibling();
79
- if ($isElementNode(previousNode)) {
80
- previousNode = previousNode.getLastDescendant();
81
- }
82
- return previousNode === null || $isLineBreakNode(previousNode) || $isTextNode(previousNode) && endsWithSeparator(previousNode.getTextContent());
83
- }
84
- function isNextNodeValid(node) {
85
- let nextNode = node.getNextSibling();
86
- if ($isElementNode(nextNode)) {
87
- nextNode = nextNode.getFirstDescendant();
88
- }
89
- return nextNode === null || $isLineBreakNode(nextNode) || $isTextNode(nextNode) && startsWithSeparator(nextNode.getTextContent());
90
- }
91
- function isContentAroundIsValid(matchStart, matchEnd, text, nodes) {
92
- const contentBeforeIsValid = matchStart > 0 ? isSeparator(text[matchStart - 1]) : isPreviousNodeValid(nodes[0]);
93
- if (!contentBeforeIsValid) {
94
- return false;
95
- }
96
- const contentAfterIsValid = matchEnd < text.length ? isSeparator(text[matchEnd]) : isNextNodeValid(nodes[nodes.length - 1]);
97
- return contentAfterIsValid;
98
- }
99
- function extractMatchingNodes(nodes, startIndex, endIndex) {
100
- const unmodifiedBeforeNodes = [];
101
- const matchingNodes = [];
102
- const unmodifiedAfterNodes = [];
103
- let matchingOffset = 0;
104
- let currentOffset = 0;
105
- const currentNodes = [...nodes];
106
- while (currentNodes.length > 0) {
107
- const currentNode = currentNodes[0];
108
- const currentNodeText = currentNode.getTextContent();
109
- const currentNodeLength = currentNodeText.length;
110
- const currentNodeStart = currentOffset;
111
- const currentNodeEnd = currentOffset + currentNodeLength;
112
- if (currentNodeEnd <= startIndex) {
113
- unmodifiedBeforeNodes.push(currentNode);
114
- matchingOffset += currentNodeLength;
115
- } else if (currentNodeStart >= endIndex) {
116
- unmodifiedAfterNodes.push(currentNode);
117
- } else {
118
- matchingNodes.push(currentNode);
119
- }
120
- currentOffset += currentNodeLength;
121
- currentNodes.shift();
122
- }
123
- return [matchingOffset, unmodifiedBeforeNodes, matchingNodes, unmodifiedAfterNodes];
124
- }
125
- function $createAutoLinkNode_(nodes, startIndex, endIndex, match) {
126
- const linkNode = $createAutoLinkNode(match.url, match.attributes);
127
- if (nodes.length === 1) {
128
- let remainingTextNode = nodes[0];
129
- let linkTextNode;
130
- if (startIndex === 0) {
131
- [linkTextNode, remainingTextNode] = remainingTextNode.splitText(endIndex);
132
- } else {
133
- [, linkTextNode, remainingTextNode] = remainingTextNode.splitText(startIndex, endIndex);
134
- }
135
- const textNode = $createTextNode(match.text);
136
- textNode.setFormat(linkTextNode.getFormat());
137
- textNode.setDetail(linkTextNode.getDetail());
138
- textNode.setStyle(linkTextNode.getStyle());
139
- linkNode.append(textNode);
140
- linkTextNode.replace(linkNode);
141
- return remainingTextNode;
142
- } else if (nodes.length > 1) {
143
- const firstTextNode = nodes[0];
144
- let offset = firstTextNode.getTextContent().length;
145
- let firstLinkTextNode;
146
- if (startIndex === 0) {
147
- firstLinkTextNode = firstTextNode;
148
- } else {
149
- [, firstLinkTextNode] = firstTextNode.splitText(startIndex);
150
- }
151
- const linkNodes = [];
152
- let remainingTextNode;
153
- for (let i = 1; i < nodes.length; i++) {
154
- const currentNode = nodes[i];
155
- const currentNodeText = currentNode.getTextContent();
156
- const currentNodeLength = currentNodeText.length;
157
- const currentNodeStart = offset;
158
- const currentNodeEnd = offset + currentNodeLength;
159
- if (currentNodeStart < endIndex) {
160
- if (currentNodeEnd <= endIndex) {
161
- linkNodes.push(currentNode);
162
- } else {
163
- const [linkTextNode, endNode] = currentNode.splitText(endIndex - currentNodeStart);
164
- linkNodes.push(linkTextNode);
165
- remainingTextNode = endNode;
166
- }
167
- }
168
- offset += currentNodeLength;
169
- }
170
- const selection = $getSelection();
171
- const selectedTextNode = selection ? selection.getNodes().find($isTextNode) : undefined;
172
- const textNode = $createTextNode(firstLinkTextNode.getTextContent());
173
- textNode.setFormat(firstLinkTextNode.getFormat());
174
- textNode.setDetail(firstLinkTextNode.getDetail());
175
- textNode.setStyle(firstLinkTextNode.getStyle());
176
- linkNode.append(textNode, ...linkNodes);
177
- // it does not preserve caret position if caret was at the first text node
178
- // so we need to restore caret position
179
- if (selectedTextNode && selectedTextNode === firstLinkTextNode) {
180
- if ($isRangeSelection(selection)) {
181
- textNode.select(selection.anchor.offset, selection.focus.offset);
182
- } else if ($isNodeSelection(selection)) {
183
- textNode.select(0, textNode.getTextContent().length);
184
- }
185
- }
186
- firstLinkTextNode.replace(linkNode);
187
- return remainingTextNode;
188
- }
189
- return undefined;
190
- }
191
- function $handleLinkCreation(nodes, matchers, onChange) {
192
- let currentNodes = [...nodes];
193
- const initialText = currentNodes.map(node => node.getTextContent()).join('');
194
- let text = initialText;
195
- let match;
196
- let invalidMatchEnd = 0;
197
- while ((match = findFirstMatch(text, matchers)) && match !== null) {
198
- const matchStart = match.index;
199
- const matchLength = match.length;
200
- const matchEnd = matchStart + matchLength;
201
- const isValid = isContentAroundIsValid(invalidMatchEnd + matchStart, invalidMatchEnd + matchEnd, initialText, currentNodes);
202
- if (isValid) {
203
- const [matchingOffset,, matchingNodes, unmodifiedAfterNodes] = extractMatchingNodes(currentNodes, invalidMatchEnd + matchStart, invalidMatchEnd + matchEnd);
204
- const actualMatchStart = invalidMatchEnd + matchStart - matchingOffset;
205
- const actualMatchEnd = invalidMatchEnd + matchEnd - matchingOffset;
206
- const remainingTextNode = $createAutoLinkNode_(matchingNodes, actualMatchStart, actualMatchEnd, match);
207
- currentNodes = remainingTextNode ? [remainingTextNode, ...unmodifiedAfterNodes] : unmodifiedAfterNodes;
208
- onChange(match.url, null);
209
- invalidMatchEnd = 0;
210
- } else {
211
- invalidMatchEnd += matchEnd;
212
- }
213
- text = text.substring(matchEnd);
214
- }
215
- }
216
- function handleLinkEdit(linkNode, matchers, onChange) {
217
- // Check children are simple text
218
- const children = linkNode.getChildren();
219
- const childrenLength = children.length;
220
- for (let i = 0; i < childrenLength; i++) {
221
- const child = children[i];
222
- if (!$isTextNode(child) || !child.isSimpleText()) {
223
- replaceWithChildren(linkNode);
224
- onChange(null, linkNode.getURL());
225
- return;
226
- }
227
- }
228
-
229
- // Check text content fully matches
230
- const text = linkNode.getTextContent();
231
- const match = findFirstMatch(text, matchers);
232
- if (match === null || match.text !== text) {
233
- replaceWithChildren(linkNode);
234
- onChange(null, linkNode.getURL());
235
- return;
236
- }
237
-
238
- // Check neighbors
239
- if (!isPreviousNodeValid(linkNode) || !isNextNodeValid(linkNode)) {
240
- replaceWithChildren(linkNode);
241
- onChange(null, linkNode.getURL());
242
- return;
243
- }
244
- const url = linkNode.getURL();
245
- if (url !== match.url) {
246
- linkNode.setURL(match.url);
247
- onChange(match.url, url);
248
- }
249
- if (match.attributes) {
250
- const rel = linkNode.getRel();
251
- if (rel !== match.attributes.rel) {
252
- linkNode.setRel(match.attributes.rel || null);
253
- onChange(match.attributes.rel || null, rel);
254
- }
255
- const target = linkNode.getTarget();
256
- if (target !== match.attributes.target) {
257
- linkNode.setTarget(match.attributes.target || null);
258
- onChange(match.attributes.target || null, target);
259
- }
260
- }
261
- }
262
-
263
- // Bad neighbors are edits in neighbor nodes that make AutoLinks incompatible.
264
- // Given the creation preconditions, these can only be simple text nodes.
265
- function handleBadNeighbors(textNode, matchers, onChange) {
266
- const previousSibling = textNode.getPreviousSibling();
267
- const nextSibling = textNode.getNextSibling();
268
- const text = textNode.getTextContent();
269
- if ($isAutoLinkNode(previousSibling) && !previousSibling.getIsUnlinked() && (!startsWithSeparator(text) || startsWithTLD(text, previousSibling.isEmailURI()))) {
270
- previousSibling.append(textNode);
271
- handleLinkEdit(previousSibling, matchers, onChange);
272
- onChange(null, previousSibling.getURL());
273
- }
274
- if ($isAutoLinkNode(nextSibling) && !nextSibling.getIsUnlinked() && !endsWithSeparator(text)) {
275
- replaceWithChildren(nextSibling);
276
- handleLinkEdit(nextSibling, matchers, onChange);
277
- onChange(null, nextSibling.getURL());
278
- }
279
- }
280
- function replaceWithChildren(node) {
281
- const children = node.getChildren();
282
- const childrenLength = children.length;
283
- for (let j = childrenLength - 1; j >= 0; j--) {
284
- node.insertAfter(children[j]);
285
- }
286
- node.remove();
287
- return children.map(child => child.getLatest());
288
- }
289
- function getTextNodesToMatch(textNode) {
290
- // check if next siblings are simple text nodes till a node contains a space separator
291
- const textNodesToMatch = [textNode];
292
- let nextSibling = textNode.getNextSibling();
293
- while (nextSibling !== null && $isTextNode(nextSibling) && nextSibling.isSimpleText()) {
294
- textNodesToMatch.push(nextSibling);
295
- if (/[\s]/.test(nextSibling.getTextContent())) {
296
- break;
297
- }
298
- nextSibling = nextSibling.getNextSibling();
299
- }
300
- return textNodesToMatch;
301
- }
302
28
  function useAutoLink(editor, matchers, onChange) {
303
29
  useEffect(() => {
304
30
  if (!editor.hasNodes([AutoLinkNode])) {
@@ -306,39 +32,12 @@ function useAutoLink(editor, matchers, onChange) {
306
32
  formatDevErrorMessage(`LexicalAutoLinkPlugin: AutoLinkNode not registered on editor`);
307
33
  }
308
34
  }
309
- const onChangeWrapped = (url, prevUrl) => {
310
- if (onChange) {
311
- onChange(url, prevUrl);
312
- }
313
- };
314
- return mergeRegister(editor.registerNodeTransform(TextNode, textNode => {
315
- const parent = textNode.getParentOrThrow();
316
- const previous = textNode.getPreviousSibling();
317
- if ($isAutoLinkNode(parent) && !parent.getIsUnlinked()) {
318
- handleLinkEdit(parent, matchers, onChangeWrapped);
319
- } else if (!$isLinkNode(parent)) {
320
- if (textNode.isSimpleText() && (startsWithSeparator(textNode.getTextContent()) || !$isAutoLinkNode(previous))) {
321
- const textNodesToMatch = getTextNodesToMatch(textNode);
322
- $handleLinkCreation(textNodesToMatch, matchers, onChangeWrapped);
323
- }
324
- handleBadNeighbors(textNode, matchers, onChangeWrapped);
325
- }
326
- }), editor.registerCommand(TOGGLE_LINK_COMMAND, payload => {
327
- const selection = $getSelection();
328
- if (payload !== null || !$isRangeSelection(selection)) {
329
- return false;
330
- }
331
- const nodes = selection.extract();
332
- nodes.forEach(node => {
333
- const parent = node.getParent();
334
- if ($isAutoLinkNode(parent)) {
335
- // invert the value
336
- parent.setIsUnlinked(!parent.getIsUnlinked());
337
- parent.markDirty();
338
- }
339
- });
340
- return false;
341
- }, COMMAND_PRIORITY_LOW));
35
+ });
36
+ useEffect(() => {
37
+ return registerAutoLink(editor, {
38
+ changeHandlers: onChange ? [onChange] : [],
39
+ matchers
40
+ });
342
41
  }, [editor, matchers, onChange]);
343
42
  }
344
43
  function AutoLinkPlugin({
@@ -350,4 +49,4 @@ function AutoLinkPlugin({
350
49
  return null;
351
50
  }
352
51
 
353
- export { AutoLinkPlugin, createLinkMatcherWithRegExp };
52
+ export { AutoLinkPlugin };
@@ -7,24 +7,10 @@
7
7
  * @flow strict
8
8
  */
9
9
 
10
- import type {LinkAttributes} from '@lexical/link';
11
-
12
- type ChangeHandler = (url: string | null, prevUrl: string | null) => void;
13
-
14
- type LinkMatcherResult = {
15
- attributes?: LinkAttributes,
16
- index: number,
17
- length: number,
18
- text: string,
19
- url: string,
20
- };
21
-
22
- export type LinkMatcher = (text: string) => LinkMatcherResult | null;
23
-
24
- declare export function createLinkMatcherWithRegExp(
25
- regExp: RegExp,
26
- urlTransformer?: (text: string) => string,
27
- ): LinkMatcher;
10
+ import type {LinkAttributes, ChangeHandler, LinkMatcher} from '@lexical/link';
11
+ import {createLinkMatcherWithRegExp} from '@lexical/link';
12
+ export {createLinkMatcherWithRegExp};
13
+ export type {ChangeHandler, LinkMatcher};
28
14
 
29
15
  declare export function AutoLinkPlugin(props: {
30
16
  matchers: Array<LinkMatcher>,
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/link"),t=require("@lexical/react/LexicalComposerContext"),n=require("@lexical/utils"),i=require("lexical"),r=require("react");function o(e,t){for(let n=0;n<t.length;n++){const i=t[n](e);if(i)return i}return null}const l=/[.,;\s]/;function s(e){return l.test(e)}function u(e){return s(e[e.length-1])}function g(e){return s(e[0])}function c(e){let t=e.getPreviousSibling();return i.$isElementNode(t)&&(t=t.getLastDescendant()),null===t||i.$isLineBreakNode(t)||i.$isTextNode(t)&&u(t.getTextContent())}function a(e){let t=e.getNextSibling();return i.$isElementNode(t)&&(t=t.getFirstDescendant()),null===t||i.$isLineBreakNode(t)||i.$isTextNode(t)&&g(t.getTextContent())}function f(e,t,n,i){if(!(e>0?s(n[e-1]):c(i[0])))return!1;return t<n.length?s(n[t]):a(i[i.length-1])}function d(e,t,n){const i=[],r=[],o=[];let l=0,s=0;const u=[...e];for(;u.length>0;){const e=u[0],g=e.getTextContent().length,c=s;s+g<=t?(i.push(e),l+=g):c>=n?o.push(e):r.push(e),s+=g,u.shift()}return[l,i,r,o]}function x(t,n,r,o){const l=e.$createAutoLinkNode(o.url,o.attributes);if(1===t.length){let e,s=t[0];0===n?[e,s]=s.splitText(r):[,e,s]=s.splitText(n,r);const u=i.$createTextNode(o.text);return u.setFormat(e.getFormat()),u.setDetail(e.getDetail()),u.setStyle(e.getStyle()),l.append(u),e.replace(l),s}if(t.length>1){const e=t[0];let o,s=e.getTextContent().length;0===n?o=e:[,o]=e.splitText(n);const u=[];let g;for(let e=1;e<t.length;e++){const n=t[e],i=n.getTextContent().length,o=s;if(o<r)if(s+i<=r)u.push(n);else{const[e,t]=n.splitText(r-o);u.push(e),g=t}s+=i}const c=i.$getSelection(),a=c?c.getNodes().find(i.$isTextNode):void 0,f=i.$createTextNode(o.getTextContent());return f.setFormat(o.getFormat()),f.setDetail(o.getDetail()),f.setStyle(o.getStyle()),l.append(f,...u),a&&a===o&&(i.$isRangeSelection(c)?f.select(c.anchor.offset,c.focus.offset):i.$isNodeSelection(c)&&f.select(0,f.getTextContent().length)),o.replace(l),g}}function h(e,t,n){const r=e.getChildren(),l=r.length;for(let t=0;t<l;t++){const o=r[t];if(!i.$isTextNode(o)||!o.isSimpleText())return p(e),void n(null,e.getURL())}const s=e.getTextContent(),u=o(s,t);if(null===u||u.text!==s)return p(e),void n(null,e.getURL());if(!c(e)||!a(e))return p(e),void n(null,e.getURL());const g=e.getURL();if(g!==u.url&&(e.setURL(u.url),n(u.url,g)),u.attributes){const t=e.getRel();t!==u.attributes.rel&&(e.setRel(u.attributes.rel||null),n(u.attributes.rel||null,t));const i=e.getTarget();i!==u.attributes.target&&(e.setTarget(u.attributes.target||null),n(u.attributes.target||null,i))}}function p(e){const t=e.getChildren();for(let n=t.length-1;n>=0;n--)e.insertAfter(t[n]);return e.remove(),t.map((e=>e.getLatest()))}function T(t,l,s){r.useEffect((()=>{t.hasNodes([e.AutoLinkNode])||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),i=new URLSearchParams;i.append("code",e);for(const e of t)i.append("v",e);throw n.search=i.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(77);const r=(e,t)=>{s&&s(e,t)};return n.mergeRegister(t.registerNodeTransform(i.TextNode,(t=>{const n=t.getParentOrThrow(),s=t.getPreviousSibling();if(e.$isAutoLinkNode(n)&&!n.getIsUnlinked())h(n,l,r);else if(!e.$isLinkNode(n)){if(t.isSimpleText()&&(g(t.getTextContent())||!e.$isAutoLinkNode(s))){const e=function(e){const t=[e];let n=e.getNextSibling();for(;null!==n&&i.$isTextNode(n)&&n.isSimpleText()&&(t.push(n),!/[\s]/.test(n.getTextContent()));)n=n.getNextSibling();return t}(t);!function(e,t,n){let i=[...e];const r=i.map((e=>e.getTextContent())).join("");let l,s=r,u=0;for(;(l=o(s,t))&&null!==l;){const e=l.index,t=e+l.length;if(f(u+e,u+t,r,i)){const[r,,o,s]=d(i,u+e,u+t),g=x(o,u+e-r,u+t-r,l);i=g?[g,...s]:s,n(l.url,null),u=0}else u+=t;s=s.substring(t)}}(e,l,r)}!function(t,n,i){const r=t.getPreviousSibling(),o=t.getNextSibling(),l=t.getTextContent();var s;!e.$isAutoLinkNode(r)||r.getIsUnlinked()||g(l)&&(s=l,!(r.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(s):/^\.[a-zA-Z0-9]{1,}/.test(s)))||(r.append(t),h(r,n,i),i(null,r.getURL())),!e.$isAutoLinkNode(o)||o.getIsUnlinked()||u(l)||(p(o),h(o,n,i),i(null,o.getURL()))}(t,l,r)}})),t.registerCommand(e.TOGGLE_LINK_COMMAND,(t=>{const n=i.$getSelection();if(null!==t||!i.$isRangeSelection(n))return!1;return n.extract().forEach((t=>{const n=t.getParent();e.$isAutoLinkNode(n)&&(n.setIsUnlinked(!n.getIsUnlinked()),n.markDirty())})),!1}),i.COMMAND_PRIORITY_LOW))}),[t,l,s])}exports.AutoLinkPlugin=function({matchers:e,onChange:n}){const[i]=t.useLexicalComposerContext();return T(i,e,n),null},exports.createLinkMatcherWithRegExp=function(e,t=(e=>e)){return n=>{const i=e.exec(n);return null===i?null:{index:i.index,length:i[0].length,text:i[0],url:t(i[0])}}};
9
+ "use strict";var e=require("@lexical/link"),r=require("@lexical/react/LexicalComposerContext"),t=require("react");function n(r,n,i){t.useEffect((()=>{r.hasNodes([e.AutoLinkNode])||function(e,...r){const t=new URL("https://lexical.dev/docs/error"),n=new URLSearchParams;n.append("code",e);for(const e of r)n.append("v",e);throw t.search=n.toString(),Error(`Minified Lexical error #${e}; visit ${t.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(77)})),t.useEffect((()=>e.registerAutoLink(r,{changeHandlers:i?[i]:[],matchers:n})),[r,n,i])}exports.createLinkMatcherWithRegExp=e.createLinkMatcherWithRegExp,exports.AutoLinkPlugin=function({matchers:e,onChange:t}){const[i]=r.useLexicalComposerContext();return n(i,e,t),null};
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- import{AutoLinkNode as t,$isAutoLinkNode as e,$isLinkNode as n,TOGGLE_LINK_COMMAND as r,$createAutoLinkNode as l}from"@lexical/link";import{useLexicalComposerContext as o}from"@lexical/react/LexicalComposerContext";import{mergeRegister as i}from"@lexical/utils";import{TextNode as s,$getSelection as u,$isRangeSelection as g,COMMAND_PRIORITY_LOW as c,$isTextNode as a,$isElementNode as f,$isLineBreakNode as x,$createTextNode as h,$isNodeSelection as p}from"lexical";import{useEffect as d}from"react";function m(t,e=(t=>t)){return n=>{const r=t.exec(n);return null===r?null:{index:r.index,length:r[0].length,text:r[0],url:e(r[0])}}}function T(t,e){for(let n=0;n<e.length;n++){const r=e[n](t);if(r)return r}return null}const C=/[.,;\s]/;function S(t){return C.test(t)}function b(t){return S(t[t.length-1])}function U(t){return S(t[0])}function v(t){let e=t.getPreviousSibling();return f(e)&&(e=e.getLastDescendant()),null===e||x(e)||a(e)&&b(e.getTextContent())}function L(t){let e=t.getNextSibling();return f(e)&&(e=e.getFirstDescendant()),null===e||x(e)||a(e)&&U(e.getTextContent())}function R(t,e,n,r){if(!(t>0?S(n[t-1]):v(r[0])))return!1;return e<n.length?S(n[e]):L(r[r.length-1])}function k(t,e,n){const r=[],l=[],o=[];let i=0,s=0;const u=[...t];for(;u.length>0;){const t=u[0],g=t.getTextContent().length,c=s;s+g<=e?(r.push(t),i+=g):c>=n?o.push(t):l.push(t),s+=g,u.shift()}return[i,r,l,o]}function D(t,e,n,r){const o=l(r.url,r.attributes);if(1===t.length){let l,i=t[0];0===e?[l,i]=i.splitText(n):[,l,i]=i.splitText(e,n);const s=h(r.text);return s.setFormat(l.getFormat()),s.setDetail(l.getDetail()),s.setStyle(l.getStyle()),o.append(s),l.replace(o),i}if(t.length>1){const r=t[0];let l,i=r.getTextContent().length;0===e?l=r:[,l]=r.splitText(e);const s=[];let c;for(let e=1;e<t.length;e++){const r=t[e],l=r.getTextContent().length,o=i;if(o<n)if(i+l<=n)s.push(r);else{const[t,e]=r.splitText(n-o);s.push(t),c=e}i+=l}const f=u(),x=f?f.getNodes().find(a):void 0,d=h(l.getTextContent());return d.setFormat(l.getFormat()),d.setDetail(l.getDetail()),d.setStyle(l.getStyle()),o.append(d,...s),x&&x===l&&(g(f)?d.select(f.anchor.offset,f.focus.offset):p(f)&&d.select(0,d.getTextContent().length)),l.replace(o),c}}function N(t,e,n){const r=t.getChildren(),l=r.length;for(let e=0;e<l;e++){const l=r[e];if(!a(l)||!l.isSimpleText())return I(t),void n(null,t.getURL())}const o=t.getTextContent(),i=T(o,e);if(null===i||i.text!==o)return I(t),void n(null,t.getURL());if(!v(t)||!L(t))return I(t),void n(null,t.getURL());const s=t.getURL();if(s!==i.url&&(t.setURL(i.url),n(i.url,s)),i.attributes){const e=t.getRel();e!==i.attributes.rel&&(t.setRel(i.attributes.rel||null),n(i.attributes.rel||null,e));const r=t.getTarget();r!==i.attributes.target&&(t.setTarget(i.attributes.target||null),n(i.attributes.target||null,r))}}function I(t){const e=t.getChildren();for(let n=e.length-1;n>=0;n--)t.insertAfter(e[n]);return t.remove(),e.map((t=>t.getLatest()))}function P(l,o,f){d((()=>{l.hasNodes([t])||function(t,...e){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",t);for(const t of e)r.append("v",t);throw n.search=r.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(77);const x=(t,e)=>{f&&f(t,e)};return i(l.registerNodeTransform(s,(t=>{const r=t.getParentOrThrow(),l=t.getPreviousSibling();if(e(r)&&!r.getIsUnlinked())N(r,o,x);else if(!n(r)){if(t.isSimpleText()&&(U(t.getTextContent())||!e(l))){const e=function(t){const e=[t];let n=t.getNextSibling();for(;null!==n&&a(n)&&n.isSimpleText()&&(e.push(n),!/[\s]/.test(n.getTextContent()));)n=n.getNextSibling();return e}(t);!function(t,e,n){let r=[...t];const l=r.map((t=>t.getTextContent())).join("");let o,i=l,s=0;for(;(o=T(i,e))&&null!==o;){const t=o.index,e=t+o.length;if(R(s+t,s+e,l,r)){const[l,,i,u]=k(r,s+t,s+e),g=D(i,s+t-l,s+e-l,o);r=g?[g,...u]:u,n(o.url,null),s=0}else s+=e;i=i.substring(e)}}(e,o,x)}!function(t,n,r){const l=t.getPreviousSibling(),o=t.getNextSibling(),i=t.getTextContent();var s;!e(l)||l.getIsUnlinked()||U(i)&&(s=i,!(l.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(s):/^\.[a-zA-Z0-9]{1,}/.test(s)))||(l.append(t),N(l,n,r),r(null,l.getURL())),!e(o)||o.getIsUnlinked()||b(i)||(I(o),N(o,n,r),r(null,o.getURL()))}(t,o,x)}})),l.registerCommand(r,(t=>{const n=u();if(null!==t||!g(n))return!1;return n.extract().forEach((t=>{const n=t.getParent();e(n)&&(n.setIsUnlinked(!n.getIsUnlinked()),n.markDirty())})),!1}),c))}),[l,o,f])}function w({matchers:t,onChange:e}){const[n]=o();return P(n,t,e),null}export{w as AutoLinkPlugin,m as createLinkMatcherWithRegExp};
9
+ import{AutoLinkNode as e,registerAutoLink as r}from"@lexical/link";export{createLinkMatcherWithRegExp}from"@lexical/link";import{useLexicalComposerContext as o}from"@lexical/react/LexicalComposerContext";import{useEffect as n}from"react";function t(o,t,i){n((()=>{o.hasNodes([e])||function(e,...r){const o=new URL("https://lexical.dev/docs/error"),n=new URLSearchParams;n.append("code",e);for(const e of r)n.append("v",e);throw o.search=n.toString(),Error(`Minified Lexical error #${e}; visit ${o.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(77)})),n((()=>r(o,{changeHandlers:i?[i]:[],matchers:t})),[o,t,i])}function i({matchers:e,onChange:r}){const[n]=o();return t(n,e,r),null}export{i as AutoLinkPlugin};
@@ -8,8 +8,8 @@
8
8
 
9
9
  'use strict';
10
10
 
11
+ var extension = require('@lexical/extension');
11
12
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
12
- var lexical = require('lexical');
13
13
  var react = require('react');
14
14
 
15
15
  /**
@@ -48,28 +48,7 @@ function ClearEditorPlugin({
48
48
  onClear
49
49
  }) {
50
50
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
51
- useLayoutEffectImpl(() => {
52
- return editor.registerCommand(lexical.CLEAR_EDITOR_COMMAND, payload => {
53
- editor.update(() => {
54
- if (onClear == null) {
55
- const root = lexical.$getRoot();
56
- const selection = lexical.$getSelection();
57
- const paragraph = lexical.$createParagraphNode();
58
- root.clear();
59
- root.append(paragraph);
60
- if (selection !== null) {
61
- paragraph.select();
62
- }
63
- if (lexical.$isRangeSelection(selection)) {
64
- selection.format = 0;
65
- }
66
- } else {
67
- onClear();
68
- }
69
- });
70
- return true;
71
- }, lexical.COMMAND_PRIORITY_EDITOR);
72
- }, [editor, onClear]);
51
+ useLayoutEffectImpl(() => extension.registerClearEditor(editor, onClear), [editor, onClear]);
73
52
  return null;
74
53
  }
75
54
 
@@ -6,8 +6,8 @@
6
6
  *
7
7
  */
8
8
 
9
+ import { registerClearEditor } from '@lexical/extension';
9
10
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
10
- import { CLEAR_EDITOR_COMMAND, $getRoot, $getSelection, $createParagraphNode, $isRangeSelection, COMMAND_PRIORITY_EDITOR } from 'lexical';
11
11
  import { useLayoutEffect, useEffect } from 'react';
12
12
 
13
13
  /**
@@ -46,28 +46,7 @@ function ClearEditorPlugin({
46
46
  onClear
47
47
  }) {
48
48
  const [editor] = useLexicalComposerContext();
49
- useLayoutEffectImpl(() => {
50
- return editor.registerCommand(CLEAR_EDITOR_COMMAND, payload => {
51
- editor.update(() => {
52
- if (onClear == null) {
53
- const root = $getRoot();
54
- const selection = $getSelection();
55
- const paragraph = $createParagraphNode();
56
- root.clear();
57
- root.append(paragraph);
58
- if (selection !== null) {
59
- paragraph.select();
60
- }
61
- if ($isRangeSelection(selection)) {
62
- selection.format = 0;
63
- }
64
- } else {
65
- onClear();
66
- }
67
- });
68
- return true;
69
- }, COMMAND_PRIORITY_EDITOR);
70
- }, [editor, onClear]);
49
+ useLayoutEffectImpl(() => registerClearEditor(editor, onClear), [editor, onClear]);
71
50
  return null;
72
51
  }
73
52
 
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- "use strict";var e=require("@lexical/react/LexicalComposerContext"),t=require("lexical"),o=require("react");const n="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?o.useLayoutEffect:o.useEffect;exports.ClearEditorPlugin=function({onClear:o}){const[r]=e.useLexicalComposerContext();return n((()=>r.registerCommand(t.CLEAR_EDITOR_COMMAND,(e=>(r.update((()=>{if(null==o){const e=t.$getRoot(),o=t.$getSelection(),n=t.$createParagraphNode();e.clear(),e.append(n),null!==o&&n.select(),t.$isRangeSelection(o)&&(o.format=0)}else o()})),!0)),t.COMMAND_PRIORITY_EDITOR)),[r,o]),null};
9
+ "use strict";var e=require("@lexical/extension"),t=require("@lexical/react/LexicalComposerContext"),o=require("react");const r="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?o.useLayoutEffect:o.useEffect;exports.ClearEditorPlugin=function({onClear:o}){const[i]=t.useLexicalComposerContext();return r((()=>e.registerClearEditor(i,o)),[i,o]),null};
@@ -6,4 +6,4 @@
6
6
  *
7
7
  */
8
8
 
9
- import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{CLEAR_EDITOR_COMMAND as o,$getRoot as t,$getSelection as n,$createParagraphNode as r,$isRangeSelection as l,COMMAND_PRIORITY_EDITOR as i}from"lexical";import{useLayoutEffect as c,useEffect as m}from"react";const a="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?c:m;function d({onClear:c}){const[m]=e();return a((()=>m.registerCommand(o,(e=>(m.update((()=>{if(null==c){const e=t(),o=n(),i=r();e.clear(),e.append(i),null!==o&&i.select(),l(o)&&(o.format=0)}else c()})),!0)),i)),[m,c]),null}export{d as ClearEditorPlugin};
9
+ import{registerClearEditor as o}from"@lexical/extension";import{useLexicalComposerContext as e}from"@lexical/react/LexicalComposerContext";import{useLayoutEffect as n,useEffect as t}from"react";const i="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?n:t;function r({onClear:n}){const[t]=e();return i((()=>o(t,n)),[t,n]),null}export{r as ClearEditorPlugin};
@@ -8,10 +8,9 @@
8
8
 
9
9
  'use strict';
10
10
 
11
+ var extension = require('@lexical/extension');
11
12
  var link = require('@lexical/link');
12
13
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
13
- var utils = require('@lexical/utils');
14
- var lexical = require('lexical');
15
14
  var react = require('react');
16
15
 
17
16
  /**
@@ -22,80 +21,16 @@ var react = require('react');
22
21
  *
23
22
  */
24
23
 
25
- function findMatchingDOM(startNode, predicate) {
26
- let node = startNode;
27
- while (node != null) {
28
- if (predicate(node)) {
29
- return node;
30
- }
31
- node = node.parentNode;
32
- }
33
- return null;
34
- }
35
24
  function ClickableLinkPlugin({
36
25
  newTab = true,
37
26
  disabled = false
38
27
  }) {
39
28
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
40
29
  react.useEffect(() => {
41
- const onClick = event => {
42
- const target = event.target;
43
- if (!lexical.isDOMNode(target)) {
44
- return;
45
- }
46
- const nearestEditor = lexical.getNearestEditorFromDOMNode(target);
47
- if (nearestEditor === null) {
48
- return;
49
- }
50
- let url = null;
51
- let urlTarget = null;
52
- nearestEditor.update(() => {
53
- const clickedNode = lexical.$getNearestNodeFromDOMNode(target);
54
- if (clickedNode !== null) {
55
- const maybeLinkNode = utils.$findMatchingParent(clickedNode, lexical.$isElementNode);
56
- if (!disabled) {
57
- if (link.$isLinkNode(maybeLinkNode)) {
58
- url = maybeLinkNode.sanitizeUrl(maybeLinkNode.getURL());
59
- urlTarget = maybeLinkNode.getTarget();
60
- } else {
61
- const a = findMatchingDOM(target, utils.isHTMLAnchorElement);
62
- if (a !== null) {
63
- url = a.href;
64
- urlTarget = a.target;
65
- }
66
- }
67
- }
68
- }
69
- });
70
- if (url === null || url === '') {
71
- return;
72
- }
73
-
74
- // Allow user to select link text without following url
75
- const selection = editor.getEditorState().read(lexical.$getSelection);
76
- if (lexical.$isRangeSelection(selection) && !selection.isCollapsed()) {
77
- event.preventDefault();
78
- return;
79
- }
80
- const isMiddle = event.type === 'auxclick' && event.button === 1;
81
- window.open(url, newTab || isMiddle || event.metaKey || event.ctrlKey || urlTarget === '_blank' ? '_blank' : '_self');
82
- event.preventDefault();
83
- };
84
- const onMouseUp = event => {
85
- if (event.button === 1) {
86
- onClick(event);
87
- }
88
- };
89
- return editor.registerRootListener((rootElement, prevRootElement) => {
90
- if (prevRootElement !== null) {
91
- prevRootElement.removeEventListener('click', onClick);
92
- prevRootElement.removeEventListener('mouseup', onMouseUp);
93
- }
94
- if (rootElement !== null) {
95
- rootElement.addEventListener('click', onClick);
96
- rootElement.addEventListener('mouseup', onMouseUp);
97
- }
98
- });
30
+ return link.registerClickableLink(editor, extension.namedSignals({
31
+ disabled,
32
+ newTab
33
+ }));
99
34
  }, [editor, newTab, disabled]);
100
35
  return null;
101
36
  }