@lexical/react 0.8.0 → 0.9.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 (94) hide show
  1. package/LexicalAutoEmbedPlugin.d.ts +1 -0
  2. package/LexicalAutoEmbedPlugin.dev.js +11 -0
  3. package/LexicalAutoFocusPlugin.dev.js +1 -0
  4. package/LexicalAutoLinkPlugin.d.ts +1 -0
  5. package/LexicalAutoLinkPlugin.dev.js +57 -11
  6. package/LexicalAutoLinkPlugin.prod.js +7 -6
  7. package/LexicalBlockWithAlignableContents.dev.js +13 -2
  8. package/LexicalBlockWithAlignableContents.prod.js +4 -4
  9. package/LexicalCharacterLimitPlugin.d.ts +1 -0
  10. package/LexicalCharacterLimitPlugin.dev.js +46 -7
  11. package/LexicalCheckListPlugin.dev.js +50 -12
  12. package/LexicalCheckListPlugin.prod.js +1 -1
  13. package/LexicalClearEditorPlugin.d.ts +1 -0
  14. package/LexicalClearEditorPlugin.dev.js +1 -1
  15. package/LexicalCollaborationContext.dev.js +3 -0
  16. package/LexicalCollaborationPlugin.d.ts +3 -2
  17. package/LexicalCollaborationPlugin.dev.js +35 -6
  18. package/LexicalComposer.d.ts +1 -0
  19. package/LexicalComposer.dev.js +10 -6
  20. package/LexicalComposerContext.dev.js +6 -0
  21. package/LexicalContentEditable.dev.js +0 -1
  22. package/LexicalContentEditable.js.flow +1 -0
  23. package/LexicalDecoratorBlockNode.d.ts +1 -0
  24. package/LexicalDecoratorBlockNode.dev.js +5 -0
  25. package/LexicalErrorBoundary.d.ts +1 -0
  26. package/LexicalHashtagPlugin.d.ts +1 -0
  27. package/LexicalHashtagPlugin.dev.js +43 -73
  28. package/LexicalHorizontalRuleNode.d.ts +1 -0
  29. package/LexicalHorizontalRuleNode.dev.js +22 -0
  30. package/LexicalHorizontalRulePlugin.dev.js +4 -0
  31. package/LexicalLinkPlugin.dev.js +10 -4
  32. package/LexicalListPlugin.dev.js +2 -0
  33. package/LexicalMarkdownShortcutPlugin.dev.js +2 -2
  34. package/LexicalNestedComposer.dev.js +12 -6
  35. package/LexicalNestedComposer.prod.js +2 -2
  36. package/LexicalNodeEventPlugin.dev.js +3 -5
  37. package/LexicalOnChangePlugin.dev.js +1 -1
  38. package/LexicalPlainTextPlugin.d.ts +1 -0
  39. package/LexicalPlainTextPlugin.dev.js +12 -8
  40. package/LexicalRichTextPlugin.d.ts +1 -0
  41. package/LexicalRichTextPlugin.dev.js +12 -8
  42. package/LexicalTabIndentationPlugin.dev.js +3 -1
  43. package/{LexicalTableOfContents__EXPERIMENTAL.d.ts → LexicalTableOfContents.d.ts} +1 -0
  44. package/{LexicalTableOfContents__EXPERIMENTAL.dev.js → LexicalTableOfContents.dev.js} +33 -5
  45. package/{DEPRECATED_useLexical.js → LexicalTableOfContents.js} +2 -2
  46. package/LexicalTablePlugin.d.ts +1 -0
  47. package/LexicalTablePlugin.dev.js +19 -5
  48. package/LexicalTreeView.d.ts +1 -0
  49. package/LexicalTreeView.dev.js +113 -21
  50. package/LexicalTreeView.prod.js +16 -15
  51. package/LexicalTypeaheadMenuPlugin.dev.js +123 -17
  52. package/LexicalTypeaheadMenuPlugin.prod.js +18 -18
  53. package/package.json +19 -19
  54. package/shared/useYjsCollaboration.d.ts +3 -4
  55. package/useLexicalEditable.dev.js +5 -1
  56. package/useLexicalIsTextContentEmpty.dev.js +0 -1
  57. package/useLexicalNodeSelection.dev.js +7 -0
  58. package/useLexicalSubscription.dev.js +3 -1
  59. package/DEPRECATED_useLexical.d.ts +0 -18
  60. package/DEPRECATED_useLexical.dev.js +0 -104
  61. package/DEPRECATED_useLexical.js.flow +0 -25
  62. package/DEPRECATED_useLexical.prod.js +0 -8
  63. package/DEPRECATED_useLexicalCanShowPlaceholder.d.ts +0 -9
  64. package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +0 -72
  65. package/DEPRECATED_useLexicalCanShowPlaceholder.js +0 -9
  66. package/DEPRECATED_useLexicalCanShowPlaceholder.js.flow +0 -15
  67. package/DEPRECATED_useLexicalCanShowPlaceholder.prod.js +0 -8
  68. package/DEPRECATED_useLexicalCharacterLimit.d.ts +0 -8
  69. package/DEPRECATED_useLexicalCharacterLimit.dev.js +0 -213
  70. package/DEPRECATED_useLexicalCharacterLimit.js +0 -9
  71. package/DEPRECATED_useLexicalCharacterLimit.js.flow +0 -31
  72. package/DEPRECATED_useLexicalCharacterLimit.prod.js +0 -13
  73. package/DEPRECATED_useLexicalEditor.d.ts +0 -9
  74. package/DEPRECATED_useLexicalEditor.dev.js +0 -87
  75. package/DEPRECATED_useLexicalEditor.js +0 -9
  76. package/DEPRECATED_useLexicalEditor.prod.js +0 -8
  77. package/DEPRECATED_useLexicalHistory.d.ts +0 -12
  78. package/DEPRECATED_useLexicalHistory.dev.js +0 -38
  79. package/DEPRECATED_useLexicalHistory.js +0 -9
  80. package/DEPRECATED_useLexicalHistory.js.flow +0 -34
  81. package/DEPRECATED_useLexicalHistory.prod.js +0 -7
  82. package/DEPRECATED_useLexicalPlainText.d.ts +0 -10
  83. package/DEPRECATED_useLexicalPlainText.dev.js +0 -88
  84. package/DEPRECATED_useLexicalPlainText.js +0 -9
  85. package/DEPRECATED_useLexicalPlainText.js.flow +0 -17
  86. package/DEPRECATED_useLexicalPlainText.prod.js +0 -8
  87. package/DEPRECATED_useLexicalRichText.d.ts +0 -10
  88. package/DEPRECATED_useLexicalRichText.dev.js +0 -88
  89. package/DEPRECATED_useLexicalRichText.js +0 -9
  90. package/DEPRECATED_useLexicalRichText.js.flow +0 -17
  91. package/DEPRECATED_useLexicalRichText.prod.js +0 -8
  92. package/LexicalTableOfContents__EXPERIMENTAL.js +0 -9
  93. /package/{LexicalTableOfContents__EXPERIMENTAL.js.flow → LexicalTableOfContents.js.flow} +0 -0
  94. /package/{LexicalTableOfContents__EXPERIMENTAL.prod.js → LexicalTableOfContents.prod.js} +0 -0
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  /**
2
3
  * Copyright (c) Meta Platforms, Inc. and affiliates.
3
4
  *
@@ -28,6 +28,7 @@ class AutoEmbedOption extends LexicalTypeaheadMenuPlugin.TypeaheadOption {
28
28
  this.title = title;
29
29
  this.onSelect = options.onSelect.bind(this);
30
30
  }
31
+
31
32
  }
32
33
  function LexicalAutoEmbedPlugin({
33
34
  embedConfigs,
@@ -45,10 +46,12 @@ function LexicalAutoEmbedPlugin({
45
46
  const checkIfLinkNodeIsEmbeddable = React.useCallback(key => {
46
47
  editor.getEditorState().read(async () => {
47
48
  const linkNode = lexical.$getNodeByKey(key);
49
+
48
50
  if (link.$isLinkNode(linkNode)) {
49
51
  for (let i = 0; i < embedConfigs.length; i++) {
50
52
  const embedConfig = embedConfigs[i];
51
53
  const urlMatch = await Promise.resolve(embedConfig.parseUrl(linkNode.__url));
54
+
52
55
  if (urlMatch != null) {
53
56
  setActiveEmbedConfig(embedConfig);
54
57
  setNodeKey(linkNode.getKey());
@@ -70,6 +73,7 @@ function LexicalAutoEmbedPlugin({
70
73
  }
71
74
  }
72
75
  };
76
+
73
77
  return utils.mergeRegister(...[link.LinkNode, link.AutoLinkNode].map(Klass => editor.registerMutationListener(Klass, (...args) => listener(...args))));
74
78
  }, [checkIfLinkNodeIsEmbeddable, editor, embedConfigs, nodeKey, reset]);
75
79
  React.useEffect(() => {
@@ -77,10 +81,12 @@ function LexicalAutoEmbedPlugin({
77
81
  const embedConfig = embedConfigs.find(({
78
82
  type
79
83
  }) => type === embedConfigType);
84
+
80
85
  if (embedConfig) {
81
86
  onOpenEmbedModalForConfig(embedConfig);
82
87
  return true;
83
88
  }
89
+
84
90
  return false;
85
91
  }, lexical.COMMAND_PRIORITY_EDITOR);
86
92
  }, [editor, embedConfigs, onOpenEmbedModalForConfig]);
@@ -88,16 +94,21 @@ function LexicalAutoEmbedPlugin({
88
94
  if (activeEmbedConfig != null && nodeKey != null) {
89
95
  const linkNode = editor.getEditorState().read(() => {
90
96
  const node = lexical.$getNodeByKey(nodeKey);
97
+
91
98
  if (link.$isLinkNode(node)) {
92
99
  return node;
93
100
  }
101
+
94
102
  return null;
95
103
  });
104
+
96
105
  if (link.$isLinkNode(linkNode)) {
97
106
  const result = await Promise.resolve(activeEmbedConfig.parseUrl(linkNode.__url));
107
+
98
108
  if (result != null) {
99
109
  editor.update(() => {
100
110
  activeEmbedConfig.insertNode(editor, result);
111
+
101
112
  if (linkNode.isAttached()) {
102
113
  linkNode.remove();
103
114
  }
@@ -28,6 +28,7 @@ function AutoFocusPlugin({
28
28
  // of this plugin, which should preserve focus too.
29
29
  const activeElement = document.activeElement;
30
30
  const rootElement = editor.getRootElement();
31
+
31
32
  if (rootElement !== null && (activeElement === null || !rootElement.contains(activeElement))) {
32
33
  // Note: preventScroll won't work in Webkit.
33
34
  rootElement.focus({
@@ -5,6 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
+ /// <reference types="react" />
8
9
  import type { LinkAttributes } from '@lexical/link';
9
10
  declare type ChangeHandler = (url: string | null, prevUrl: string | null) => void;
10
11
  declare type LinkMatcherResult = {
@@ -19,65 +19,86 @@ var react = require('react');
19
19
  * LICENSE file in the root directory of this source tree.
20
20
  *
21
21
  */
22
+
22
23
  function findFirstMatch(text, matchers) {
23
24
  for (let i = 0; i < matchers.length; i++) {
24
25
  const match = matchers[i](text);
26
+
25
27
  if (match) {
26
28
  return match;
27
29
  }
28
30
  }
31
+
29
32
  return null;
30
33
  }
34
+
31
35
  const PUNCTUATION_OR_SPACE = /[.,;\s]/;
36
+
32
37
  function isSeparator(char) {
33
38
  return PUNCTUATION_OR_SPACE.test(char);
34
39
  }
40
+
35
41
  function endsWithSeparator(textContent) {
36
42
  return isSeparator(textContent[textContent.length - 1]);
37
43
  }
44
+
38
45
  function startsWithSeparator(textContent) {
39
46
  return isSeparator(textContent[0]);
40
47
  }
48
+
41
49
  function isPreviousNodeValid(node) {
42
50
  let previousNode = node.getPreviousSibling();
51
+
43
52
  if (lexical.$isElementNode(previousNode)) {
44
53
  previousNode = previousNode.getLastDescendant();
45
54
  }
55
+
46
56
  return previousNode === null || lexical.$isLineBreakNode(previousNode) || lexical.$isTextNode(previousNode) && endsWithSeparator(previousNode.getTextContent());
47
57
  }
58
+
48
59
  function isNextNodeValid(node) {
49
60
  let nextNode = node.getNextSibling();
61
+
50
62
  if (lexical.$isElementNode(nextNode)) {
51
63
  nextNode = nextNode.getFirstDescendant();
52
64
  }
65
+
53
66
  return nextNode === null || lexical.$isLineBreakNode(nextNode) || lexical.$isTextNode(nextNode) && startsWithSeparator(nextNode.getTextContent());
54
67
  }
68
+
55
69
  function isContentAroundIsValid(matchStart, matchEnd, text, node) {
56
70
  const contentBeforeIsValid = matchStart > 0 ? isSeparator(text[matchStart - 1]) : isPreviousNodeValid(node);
71
+
57
72
  if (!contentBeforeIsValid) {
58
73
  return false;
59
74
  }
75
+
60
76
  const contentAfterIsValid = matchEnd < text.length ? isSeparator(text[matchEnd]) : isNextNodeValid(node);
61
77
  return contentAfterIsValid;
62
78
  }
79
+
63
80
  function handleLinkCreation(node, matchers, onChange) {
64
81
  const nodeText = node.getTextContent();
65
82
  let text = nodeText;
66
83
  let invalidMatchEnd = 0;
67
84
  let remainingTextNode = node;
68
85
  let match;
86
+
69
87
  while ((match = findFirstMatch(text, matchers)) && match !== null) {
70
88
  const matchStart = match.index;
71
89
  const matchLength = match.length;
72
90
  const matchEnd = matchStart + matchLength;
73
91
  const isValid = isContentAroundIsValid(invalidMatchEnd + matchStart, invalidMatchEnd + matchEnd, nodeText, node);
92
+
74
93
  if (isValid) {
75
94
  let linkTextNode;
95
+
76
96
  if (invalidMatchEnd + matchStart === 0) {
77
97
  [linkTextNode, remainingTextNode] = remainingTextNode.splitText(invalidMatchEnd + matchLength);
78
98
  } else {
79
99
  [, linkTextNode, remainingTextNode] = remainingTextNode.splitText(invalidMatchEnd + matchStart, invalidMatchEnd + matchStart + matchLength);
80
100
  }
101
+
81
102
  const linkNode = link.$createAutoLinkNode(match.url, match.attributes);
82
103
  const textNode = lexical.$createTextNode(match.text);
83
104
  textNode.setFormat(linkTextNode.getFormat());
@@ -89,80 +110,99 @@ function handleLinkCreation(node, matchers, onChange) {
89
110
  } else {
90
111
  invalidMatchEnd += matchEnd;
91
112
  }
113
+
92
114
  text = text.substring(matchEnd);
93
115
  }
94
116
  }
117
+
95
118
  function handleLinkEdit(linkNode, matchers, onChange) {
96
119
  // Check children are simple text
97
120
  const children = linkNode.getChildren();
98
121
  const childrenLength = children.length;
122
+
99
123
  for (let i = 0; i < childrenLength; i++) {
100
124
  const child = children[i];
125
+
101
126
  if (!lexical.$isTextNode(child) || !child.isSimpleText()) {
102
127
  replaceWithChildren(linkNode);
103
128
  onChange(null, linkNode.getURL());
104
129
  return;
105
130
  }
106
- }
131
+ } // Check text content fully matches
132
+
107
133
 
108
- // Check text content fully matches
109
134
  const text = linkNode.getTextContent();
110
135
  const match = findFirstMatch(text, matchers);
136
+
111
137
  if (match === null || match.text !== text) {
112
138
  replaceWithChildren(linkNode);
113
139
  onChange(null, linkNode.getURL());
114
140
  return;
115
- }
141
+ } // Check neighbors
142
+
116
143
 
117
- // Check neighbors
118
144
  if (!isPreviousNodeValid(linkNode) || !isNextNodeValid(linkNode)) {
119
145
  replaceWithChildren(linkNode);
120
146
  onChange(null, linkNode.getURL());
121
147
  return;
122
148
  }
149
+
123
150
  const url = linkNode.getURL();
151
+
124
152
  if (url !== match.url) {
125
153
  linkNode.setURL(match.url);
126
154
  onChange(match.url, url);
127
155
  }
156
+
128
157
  if (match.attributes) {
129
158
  const rel = linkNode.getRel();
159
+
130
160
  if (rel !== match.attributes.rel) {
131
161
  linkNode.setRel(match.attributes.rel || null);
132
162
  onChange(match.attributes.rel || null, rel);
133
163
  }
164
+
134
165
  const target = linkNode.getTarget();
166
+
135
167
  if (target !== match.attributes.target) {
136
168
  linkNode.setTarget(match.attributes.target || null);
137
169
  onChange(match.attributes.target || null, target);
138
170
  }
139
171
  }
140
- }
141
-
142
- // Bad neighbours are edits in neighbor nodes that make AutoLinks incompatible.
172
+ } // Bad neighbours are edits in neighbor nodes that make AutoLinks incompatible.
143
173
  // Given the creation preconditions, these can only be simple text nodes.
144
- function handleBadNeighbors(textNode, onChange) {
174
+
175
+
176
+ function handleBadNeighbors(textNode, matchers, onChange) {
145
177
  const previousSibling = textNode.getPreviousSibling();
146
178
  const nextSibling = textNode.getNextSibling();
147
179
  const text = textNode.getTextContent();
180
+
148
181
  if (link.$isAutoLinkNode(previousSibling) && !startsWithSeparator(text)) {
149
- replaceWithChildren(previousSibling);
182
+ previousSibling.append(textNode);
183
+ handleLinkEdit(previousSibling, matchers, onChange);
150
184
  onChange(null, previousSibling.getURL());
151
185
  }
186
+
152
187
  if (link.$isAutoLinkNode(nextSibling) && !endsWithSeparator(text)) {
153
188
  replaceWithChildren(nextSibling);
189
+ handleLinkEdit(nextSibling, matchers, onChange);
154
190
  onChange(null, nextSibling.getURL());
155
191
  }
156
192
  }
193
+
157
194
  function replaceWithChildren(node) {
158
195
  const children = node.getChildren();
159
196
  const childrenLength = children.length;
197
+
160
198
  for (let j = childrenLength - 1; j >= 0; j--) {
161
199
  node.insertAfter(children[j]);
162
200
  }
201
+
163
202
  node.remove();
164
203
  return children.map(child => child.getLatest());
165
204
  }
205
+
166
206
  function useAutoLink(editor, matchers, onChange) {
167
207
  react.useEffect(() => {
168
208
  if (!editor.hasNodes([link.AutoLinkNode])) {
@@ -170,24 +210,30 @@ function useAutoLink(editor, matchers, onChange) {
170
210
  throw Error(`LexicalAutoLinkPlugin: AutoLinkNode not registered on editor`);
171
211
  }
172
212
  }
213
+
173
214
  const onChangeWrapped = (url, prevUrl) => {
174
215
  if (onChange) {
175
216
  onChange(url, prevUrl);
176
217
  }
177
218
  };
219
+
178
220
  return utils.mergeRegister(editor.registerNodeTransform(lexical.TextNode, textNode => {
179
221
  const parent = textNode.getParentOrThrow();
222
+ const previous = textNode.getPreviousSibling();
223
+
180
224
  if (link.$isAutoLinkNode(parent)) {
181
225
  handleLinkEdit(parent, matchers, onChangeWrapped);
182
226
  } else if (!link.$isLinkNode(parent)) {
183
- if (textNode.isSimpleText()) {
227
+ if (textNode.isSimpleText() && (startsWithSeparator(textNode.getTextContent()) || !link.$isAutoLinkNode(previous))) {
184
228
  handleLinkCreation(textNode, matchers, onChangeWrapped);
185
229
  }
186
- handleBadNeighbors(textNode, onChangeWrapped);
230
+
231
+ handleBadNeighbors(textNode, matchers, onChangeWrapped);
187
232
  }
188
233
  }));
189
234
  }, [editor, matchers, onChange]);
190
235
  }
236
+
191
237
  function AutoLinkPlugin({
192
238
  matchers,
193
239
  onChange
@@ -4,9 +4,10 @@
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
- 'use strict';var h=require("@lexical/link"),l=require("@lexical/react/LexicalComposerContext"),m=require("@lexical/utils"),q=require("lexical"),y=require("react");function z(b,f){for(let c=0;c<f.length;c++){let a=f[c](b);if(a)return a}return null}let A=/[.,;\s]/;function C(b){b=b.getPreviousSibling();q.$isElementNode(b)&&(b=b.getLastDescendant());var f;!(f=null===b||q.$isLineBreakNode(b))&&(f=q.$isTextNode(b))&&(b=b.getTextContent(),f=A.test(b[b.length-1]));return f}
8
- function D(b){b=b.getNextSibling();q.$isElementNode(b)&&(b=b.getFirstDescendant());return null===b||q.$isLineBreakNode(b)||q.$isTextNode(b)&&A.test(b.getTextContent()[0])}function E(b){let f=b.getChildren();var c=f.length;for(--c;0<=c;c--)b.insertAfter(f[c]);b.remove();return f.map(a=>a.getLatest())}
9
- function F(b,f,c){y.useEffect(()=>{if(!b.hasNodes([h.AutoLinkNode]))throw Error("Minified Lexical error #77; visit https://lexical.dev/docs/error?code=77 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");return m.mergeRegister(b.registerNodeTransform(q.TextNode,a=>{var e=a.getParentOrThrow();if(h.$isAutoLinkNode(e))a:{a=e.getChildren();var d=a.length;for(var g=0;g<d;g++){var n=a[g];if(!q.$isTextNode(n)||!n.isSimpleText()){E(e);a=e.getURL();
10
- c&&c(null,a);break a}}d=e.getTextContent();a=z(d,f);null===a||a.text!==d?(E(e),a=e.getURL(),c&&c(null,a)):C(e)&&D(e)?(d=e.getURL(),d!==a.url&&(e.setURL(a.url),c&&c(a.url,d)),a.attributes&&(d=e.getRel(),d!==a.attributes.rel&&(e.setRel(a.attributes.rel||null),c&&c(a.attributes.rel||null,d)),d=e.getTarget(),d!==a.attributes.target&&(e.setTarget(a.attributes.target||null),c&&c(a.attributes.target||null,d)))):(E(e),a=e.getURL(),c&&c(null,a))}else if(!h.$isLinkNode(e)){if(a.isSimpleText()){n=e=a.getTextContent();
11
- let k=0,u=a;for(;(d=z(n,f))&&null!==d;){let r=d.index,v=d.length,w=r+v;var t=k+r,p=k+w,x=e,B=a;(0<t?A.test(x[t-1]):C(B))&&(p<x.length?A.test(x[p]):D(B))?(0===k+r?[g,u]=u.splitText(k+v):[,g,u]=u.splitText(k+r,k+r+v),t=h.$createAutoLinkNode(d.url,d.attributes),p=q.$createTextNode(d.text),p.setFormat(g.getFormat()),p.setDetail(g.getDetail()),t.append(p),g.replace(t),c&&c(d.url,null),k=0):k+=w;n=n.substring(w)}}g=a.getPreviousSibling();d=a.getNextSibling();a=a.getTextContent();h.$isAutoLinkNode(g)&&!A.test(a[0])&&
12
- (E(g),g=g.getURL(),c&&c(null,g));h.$isAutoLinkNode(d)&&!A.test(a[a.length-1])&&(E(d),a=d.getURL(),c&&c(null,a))}}))},[b,f,c])}exports.AutoLinkPlugin=function({matchers:b,onChange:f}){let [c]=l.useLexicalComposerContext();F(c,b,f);return null}
7
+ 'use strict';var h=require("@lexical/link"),n=require("@lexical/react/LexicalComposerContext"),p=require("@lexical/utils"),u=require("lexical"),w=require("react");function A(a,b){for(let c=0;c<b.length;c++){let d=b[c](a);if(d)return d}return null}let B=/[.,;\s]/;function C(a){a=a.getPreviousSibling();u.$isElementNode(a)&&(a=a.getLastDescendant());var b;!(b=null===a||u.$isLineBreakNode(a))&&(b=u.$isTextNode(a))&&(a=a.getTextContent(),b=B.test(a[a.length-1]));return b}
8
+ function E(a){a=a.getNextSibling();u.$isElementNode(a)&&(a=a.getFirstDescendant());return null===a||u.$isLineBreakNode(a)||u.$isTextNode(a)&&B.test(a.getTextContent()[0])}
9
+ function F(a,b,c){var d=a.getChildren();let e=d.length;for(let f=0;f<e;f++){let l=d[f];if(!u.$isTextNode(l)||!l.isSimpleText()){G(a);c(null,a.getURL());return}}d=a.getTextContent();b=A(d,b);null===b||b.text!==d?(G(a),c(null,a.getURL())):C(a)&&E(a)?(d=a.getURL(),d!==b.url&&(a.setURL(b.url),c(b.url,d)),b.attributes&&(d=a.getRel(),d!==b.attributes.rel&&(a.setRel(b.attributes.rel||null),c(b.attributes.rel||null,d)),d=a.getTarget(),d!==b.attributes.target&&(a.setTarget(b.attributes.target||null),c(b.attributes.target||
10
+ null,d)))):(G(a),c(null,a.getURL()))}function G(a){let b=a.getChildren();var c=b.length;for(--c;0<=c;c--)a.insertAfter(b[c]);a.remove();return b.map(d=>d.getLatest())}
11
+ function H(a,b,c){w.useEffect(()=>{if(!a.hasNodes([h.AutoLinkNode]))throw Error("Minified Lexical error #77; visit https://lexical.dev/docs/error?code=77 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");let d=(e,f)=>{c&&c(e,f)};return p.mergeRegister(a.registerNodeTransform(u.TextNode,e=>{var f=e.getParentOrThrow(),l=e.getPreviousSibling();if(h.$isAutoLinkNode(f))F(f,b,d);else if(!h.$isLinkNode(f)){if(e.isSimpleText()&&(B.test(e.getTextContent()[0])||
12
+ !h.$isAutoLinkNode(l))){l=f=e.getTextContent();let m=0,v=e;for(var g;(g=A(l,b))&&null!==g;){let r=g.index,x=g.length,y=r+x;var t=m+r,q=m+y,z=f,D=e;if((0<t?B.test(z[t-1]):C(D))&&(q<z.length?B.test(z[q]):E(D))){var k=void 0;0===m+r?[k,v]=v.splitText(m+x):[,k,v]=v.splitText(m+r,m+r+x);t=h.$createAutoLinkNode(g.url,g.attributes);q=u.$createTextNode(g.text);q.setFormat(k.getFormat());q.setDetail(k.getDetail());t.append(q);k.replace(t);c&&c(g.url,null);m=0}else m+=y;l=l.substring(y)}}f=e.getPreviousSibling();
13
+ g=e.getNextSibling();k=e.getTextContent();h.$isAutoLinkNode(f)&&!B.test(k[0])&&(f.append(e),F(f,b,d),e=f.getURL(),c&&c(null,e));h.$isAutoLinkNode(g)&&!B.test(k[k.length-1])&&(G(g),F(g,b,d),e=g.getURL(),c&&c(null,e))}}))},[a,b,c])}exports.AutoLinkPlugin=function({matchers:a,onChange:b}){let [c]=n.useLexicalComposerContext();H(c,a,b);return null}
@@ -34,25 +34,31 @@ function BlockWithAlignableContents({
34
34
  event.preventDefault();
35
35
  editor.update(() => {
36
36
  const node = lexical.$getNodeByKey(nodeKey);
37
+ if (node === null) return;
38
+ lexical.$setSelection(node.selectPrevious());
39
+
37
40
  if (lexical.$isDecoratorNode(node)) {
38
41
  node.remove();
39
42
  }
40
- setSelected(false);
41
43
  });
42
44
  }
45
+
43
46
  return false;
44
- }, [editor, isSelected, nodeKey, setSelected]);
47
+ }, [editor, isSelected, nodeKey]);
45
48
  React.useEffect(() => {
46
49
  return utils.mergeRegister(editor.registerCommand(lexical.FORMAT_ELEMENT_COMMAND, formatType => {
47
50
  if (isSelected) {
48
51
  const selection = lexical.$getSelection();
52
+
49
53
  if (lexical.$isNodeSelection(selection)) {
50
54
  const node = lexical.$getNodeByKey(nodeKey);
55
+
51
56
  if (LexicalDecoratorBlockNode.$isDecoratorBlockNode(node)) {
52
57
  node.setFormat(formatType);
53
58
  }
54
59
  } else if (lexical.$isRangeSelection(selection)) {
55
60
  const nodes = selection.getNodes();
61
+
56
62
  for (const node of nodes) {
57
63
  if (LexicalDecoratorBlockNode.$isDecoratorBlockNode(node)) {
58
64
  node.setFormat(formatType);
@@ -62,18 +68,23 @@ function BlockWithAlignableContents({
62
68
  }
63
69
  }
64
70
  }
71
+
65
72
  return true;
66
73
  }
74
+
67
75
  return false;
68
76
  }, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.CLICK_COMMAND, event => {
69
77
  if (event.target === ref.current) {
70
78
  event.preventDefault();
79
+
71
80
  if (!event.shiftKey) {
72
81
  clearSelection();
73
82
  }
83
+
74
84
  setSelected(!isSelected);
75
85
  return true;
76
86
  }
87
+
77
88
  return false;
78
89
  }, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_DELETE_COMMAND, onDelete, lexical.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical.KEY_BACKSPACE_COMMAND, onDelete, lexical.COMMAND_PRIORITY_LOW));
79
90
  }, [clearSelection, editor, isSelected, nodeKey, onDelete, setSelected]);
@@ -4,7 +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
- 'use strict';var a=require("@lexical/react/LexicalComposerContext"),h=require("@lexical/react/LexicalDecoratorBlockNode"),m=require("@lexical/react/useLexicalNodeSelection"),n=require("@lexical/utils"),u=require("lexical"),v=require("react");
8
- exports.BlockWithAlignableContents=function({children:w,format:p,nodeKey:g,className:q}){let [d]=a.useLexicalComposerContext(),[e,k,r]=m.useLexicalNodeSelection(g),t=v.useRef(null),l=v.useCallback(b=>{e&&u.$isNodeSelection(u.$getSelection())&&(b.preventDefault(),d.update(()=>{const c=u.$getNodeByKey(g);u.$isDecoratorNode(c)&&c.remove();k(!1)}));return!1},[d,e,g,k]);v.useEffect(()=>n.mergeRegister(d.registerCommand(u.FORMAT_ELEMENT_COMMAND,b=>{if(e){var c=u.$getSelection();if(u.$isNodeSelection(c)){var f=
9
- u.$getNodeByKey(g);h.$isDecoratorBlockNode(f)&&f.setFormat(b)}else if(u.$isRangeSelection(c)){c=c.getNodes();for(f of c)h.$isDecoratorBlockNode(f)?f.setFormat(b):n.$getNearestBlockElementAncestorOrThrow(f).setFormat(b)}return!0}return!1},u.COMMAND_PRIORITY_LOW),d.registerCommand(u.CLICK_COMMAND,b=>b.target===t.current?(b.preventDefault(),b.shiftKey||r(),k(!e),!0):!1,u.COMMAND_PRIORITY_LOW),d.registerCommand(u.KEY_DELETE_COMMAND,l,u.COMMAND_PRIORITY_LOW),d.registerCommand(u.KEY_BACKSPACE_COMMAND,l,
10
- u.COMMAND_PRIORITY_LOW)),[r,d,e,g,l,k]);return v.createElement("div",{className:[q.base,e?q.focus:null].filter(Boolean).join(" "),ref:t,style:{textAlign:p?p:void 0}},w)}
7
+ 'use strict';var a=require("@lexical/react/LexicalComposerContext"),h=require("@lexical/react/LexicalDecoratorBlockNode"),l=require("@lexical/react/useLexicalNodeSelection"),m=require("@lexical/utils"),u=require("lexical"),v=require("react");
8
+ exports.BlockWithAlignableContents=function({children:w,format:n,nodeKey:g,className:p}){let [d]=a.useLexicalComposerContext(),[e,q,r]=l.useLexicalNodeSelection(g),t=v.useRef(null),k=v.useCallback(c=>{e&&u.$isNodeSelection(u.$getSelection())&&(c.preventDefault(),d.update(()=>{const b=u.$getNodeByKey(g);null!==b&&(u.$setSelection(b.selectPrevious()),u.$isDecoratorNode(b)&&b.remove())}));return!1},[d,e,g]);v.useEffect(()=>m.mergeRegister(d.registerCommand(u.FORMAT_ELEMENT_COMMAND,c=>{if(e){var b=u.$getSelection();
9
+ if(u.$isNodeSelection(b)){var f=u.$getNodeByKey(g);h.$isDecoratorBlockNode(f)&&f.setFormat(c)}else if(u.$isRangeSelection(b)){b=b.getNodes();for(f of b)h.$isDecoratorBlockNode(f)?f.setFormat(c):m.$getNearestBlockElementAncestorOrThrow(f).setFormat(c)}return!0}return!1},u.COMMAND_PRIORITY_LOW),d.registerCommand(u.CLICK_COMMAND,c=>c.target===t.current?(c.preventDefault(),c.shiftKey||r(),q(!e),!0):!1,u.COMMAND_PRIORITY_LOW),d.registerCommand(u.KEY_DELETE_COMMAND,k,u.COMMAND_PRIORITY_LOW),d.registerCommand(u.KEY_BACKSPACE_COMMAND,
10
+ k,u.COMMAND_PRIORITY_LOW)),[r,d,e,g,k,q]);return v.createElement("div",{className:[p.base,e?p.focus:null].filter(Boolean).join(" "),ref:t,style:{textAlign:n?n:void 0}},w)}
@@ -5,6 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
+ /// <reference types="react" />
8
9
  export declare function CharacterLimitPlugin({ charset, maxLength, }: {
9
10
  charset: 'UTF-8' | 'UTF-16';
10
11
  maxLength: number;
@@ -45,13 +45,16 @@ function useCharacterLimit(editor, maxCharacters, optional = Object.freeze({}))
45
45
  }) => {
46
46
  const isComposing = editor.isComposing();
47
47
  const hasDirtyLeaves = dirtyLeaves.size > 0;
48
+
48
49
  if (isComposing || !hasDirtyLeaves) {
49
50
  return;
50
51
  }
52
+
51
53
  const textLength = strlen(text$1);
52
54
  const textLengthAboveThreshold = textLength > maxCharacters || lastComputedTextLength !== null && lastComputedTextLength > maxCharacters;
53
55
  const diff = maxCharacters - textLength;
54
56
  remainingCharacters(diff);
57
+
55
58
  if (lastComputedTextLength === null || textLengthAboveThreshold) {
56
59
  const offset = findOffset(text$1, maxCharacters, strlen);
57
60
  editor.update(() => {
@@ -60,62 +63,75 @@ function useCharacterLimit(editor, maxCharacters, optional = Object.freeze({}))
60
63
  tag: 'history-merge'
61
64
  });
62
65
  }
66
+
63
67
  lastComputedTextLength = textLength;
64
68
  }));
65
69
  }, [editor, maxCharacters, remainingCharacters, strlen]);
66
70
  }
71
+
67
72
  function findOffset(text, maxCharacters, strlen) {
68
73
  // @ts-ignore This is due to be added in a later version of TS
69
74
  const Segmenter = Intl.Segmenter;
70
75
  let offsetUtf16 = 0;
71
76
  let offset = 0;
77
+
72
78
  if (typeof Segmenter === 'function') {
73
79
  const segmenter = new Segmenter();
74
80
  const graphemes = segmenter.segment(text);
81
+
75
82
  for (const {
76
83
  segment: grapheme
77
84
  } of graphemes) {
78
85
  const nextOffset = offset + strlen(grapheme);
86
+
79
87
  if (nextOffset > maxCharacters) {
80
88
  break;
81
89
  }
90
+
82
91
  offset = nextOffset;
83
92
  offsetUtf16 += grapheme.length;
84
93
  }
85
94
  } else {
86
95
  const codepoints = Array.from(text);
87
96
  const codepointsLength = codepoints.length;
97
+
88
98
  for (let i = 0; i < codepointsLength; i++) {
89
99
  const codepoint = codepoints[i];
90
100
  const nextOffset = offset + strlen(codepoint);
101
+
91
102
  if (nextOffset > maxCharacters) {
92
103
  break;
93
104
  }
105
+
94
106
  offset = nextOffset;
95
107
  offsetUtf16 += codepoint.length;
96
108
  }
97
109
  }
110
+
98
111
  return offsetUtf16;
99
112
  }
113
+
100
114
  function $wrapOverflowedNodes(offset) {
101
115
  const dfsNodes = utils.$dfs();
102
116
  const dfsNodesLength = dfsNodes.length;
103
117
  let accumulatedLength = 0;
118
+
104
119
  for (let i = 0; i < dfsNodesLength; i += 1) {
105
120
  const {
106
121
  node
107
122
  } = dfsNodes[i];
123
+
108
124
  if (overflow.$isOverflowNode(node)) {
109
125
  const previousLength = accumulatedLength;
110
126
  const nextLength = accumulatedLength + node.getTextContentSize();
127
+
111
128
  if (nextLength <= offset) {
112
129
  const parent = node.getParent();
113
130
  const previousSibling = node.getPreviousSibling();
114
131
  const nextSibling = node.getNextSibling();
115
132
  $unwrapNode(node);
116
- const selection = lexical.$getSelection();
133
+ const selection = lexical.$getSelection(); // Restore selection when the overflow children are removed
117
134
 
118
- // Restore selection when the overflow children are removed
119
135
  if (lexical.$isRangeSelection(selection) && (!selection.anchor.getNode().isAttached() || !selection.focus.getNode().isAttached())) {
120
136
  if (lexical.$isTextNode(previousSibling)) {
121
137
  previousSibling.select();
@@ -128,11 +144,12 @@ function $wrapOverflowedNodes(offset) {
128
144
  } else if (previousLength < offset) {
129
145
  const descendant = node.getFirstDescendant();
130
146
  const descendantLength = descendant !== null ? descendant.getTextContentSize() : 0;
131
- const previousPlusDescendantLength = previousLength + descendantLength;
132
- // For simple text we can redimension the overflow into a smaller and more accurate
147
+ const previousPlusDescendantLength = previousLength + descendantLength; // For simple text we can redimension the overflow into a smaller and more accurate
133
148
  // container
149
+
134
150
  const firstDescendantIsSimpleText = lexical.$isTextNode(descendant) && descendant.isSimpleText();
135
151
  const firstDescendantDoesNotOverflow = previousPlusDescendantLength <= offset;
152
+
136
153
  if (firstDescendantIsSimpleText || firstDescendantDoesNotOverflow) {
137
154
  $unwrapNode(node);
138
155
  }
@@ -140,49 +157,59 @@ function $wrapOverflowedNodes(offset) {
140
157
  } else if (lexical.$isLeafNode(node)) {
141
158
  const previousAccumulatedLength = accumulatedLength;
142
159
  accumulatedLength += node.getTextContentSize();
160
+
143
161
  if (accumulatedLength > offset && !overflow.$isOverflowNode(node.getParent())) {
144
162
  const previousSelection = lexical.$getSelection();
145
- let overflowNode;
146
-
147
- // For simple text we can improve the limit accuracy by splitting the TextNode
163
+ let overflowNode; // For simple text we can improve the limit accuracy by splitting the TextNode
148
164
  // on the split point
165
+
149
166
  if (previousAccumulatedLength < offset && lexical.$isTextNode(node) && node.isSimpleText()) {
150
167
  const [, overflowedText] = node.splitText(offset - previousAccumulatedLength);
151
168
  overflowNode = $wrapNode(overflowedText);
152
169
  } else {
153
170
  overflowNode = $wrapNode(node);
154
171
  }
172
+
155
173
  if (previousSelection !== null) {
156
174
  lexical.$setSelection(previousSelection);
157
175
  }
176
+
158
177
  mergePrevious(overflowNode);
159
178
  }
160
179
  }
161
180
  }
162
181
  }
182
+
163
183
  function $wrapNode(node) {
164
184
  const overflowNode = overflow.$createOverflowNode();
165
185
  node.insertBefore(overflowNode);
166
186
  overflowNode.append(node);
167
187
  return overflowNode;
168
188
  }
189
+
169
190
  function $unwrapNode(node) {
170
191
  const children = node.getChildren();
171
192
  const childrenLength = children.length;
193
+
172
194
  for (let i = 0; i < childrenLength; i++) {
173
195
  node.insertBefore(children[i]);
174
196
  }
197
+
175
198
  node.remove();
176
199
  return childrenLength > 0 ? children[childrenLength - 1] : null;
177
200
  }
201
+
178
202
  function mergePrevious(overflowNode) {
179
203
  const previousNode = overflowNode.getPreviousSibling();
204
+
180
205
  if (!overflow.$isOverflowNode(previousNode)) {
181
206
  return;
182
207
  }
208
+
183
209
  const firstChild = overflowNode.getFirstChild();
184
210
  const previousNodeChildren = previousNode.getChildren();
185
211
  const previousNodeChildrenLength = previousNodeChildren.length;
212
+
186
213
  if (firstChild === null) {
187
214
  overflowNode.append(...previousNodeChildren);
188
215
  } else {
@@ -190,23 +217,28 @@ function mergePrevious(overflowNode) {
190
217
  firstChild.insertBefore(previousNodeChildren[i]);
191
218
  }
192
219
  }
220
+
193
221
  const selection = lexical.$getSelection();
222
+
194
223
  if (lexical.$isRangeSelection(selection)) {
195
224
  const anchor = selection.anchor;
196
225
  const anchorNode = anchor.getNode();
197
226
  const focus = selection.focus;
198
227
  const focusNode = anchor.getNode();
228
+
199
229
  if (anchorNode.is(previousNode)) {
200
230
  anchor.set(overflowNode.getKey(), anchor.offset, 'element');
201
231
  } else if (anchorNode.is(overflowNode)) {
202
232
  anchor.set(overflowNode.getKey(), previousNodeChildrenLength + anchor.offset, 'element');
203
233
  }
234
+
204
235
  if (focusNode.is(previousNode)) {
205
236
  focus.set(overflowNode.getKey(), focus.offset, 'element');
206
237
  } else if (focusNode.is(overflowNode)) {
207
238
  focus.set(overflowNode.getKey(), previousNodeChildrenLength + focus.offset, 'element');
208
239
  }
209
240
  }
241
+
210
242
  previousNode.remove();
211
243
  }
212
244
 
@@ -219,24 +251,31 @@ function mergePrevious(overflowNode) {
219
251
  */
220
252
  const CHARACTER_LIMIT = 5;
221
253
  let textEncoderInstance = null;
254
+
222
255
  function textEncoder() {
223
256
  if (window.TextEncoder === undefined) {
224
257
  return null;
225
258
  }
259
+
226
260
  if (textEncoderInstance === null) {
227
261
  textEncoderInstance = new window.TextEncoder();
228
262
  }
263
+
229
264
  return textEncoderInstance;
230
265
  }
266
+
231
267
  function utf8Length(text) {
232
268
  const currentTextEncoder = textEncoder();
269
+
233
270
  if (currentTextEncoder === null) {
234
271
  // http://stackoverflow.com/a/5515960/210370
235
272
  const m = encodeURIComponent(text).match(/%[89ABab]/g);
236
273
  return text.length + (m ? m.length : 0);
237
274
  }
275
+
238
276
  return currentTextEncoder.encode(text).length;
239
277
  }
278
+
240
279
  function CharacterLimitPlugin({
241
280
  charset = 'UTF-16',
242
281
  maxLength = CHARACTER_LIMIT