@lexical/selection 0.12.2 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,30 +24,24 @@ const CSS_TO_STYLES = new Map();
24
24
  * LICENSE file in the root directory of this source tree.
25
25
  *
26
26
  */
27
-
28
27
  function getDOMTextNode(element) {
29
28
  let node = element;
30
-
31
29
  while (node != null) {
32
30
  if (node.nodeType === Node.TEXT_NODE) {
33
31
  return node;
34
32
  }
35
-
36
33
  node = node.firstChild;
37
34
  }
38
-
39
35
  return null;
40
36
  }
41
-
42
37
  function getDOMIndexWithinParent(node) {
43
38
  const parent = node.parentNode;
44
-
45
39
  if (parent == null) {
46
40
  throw new Error('Should never happen');
47
41
  }
48
-
49
42
  return [parent, Array.from(parent.childNodes).indexOf(node)];
50
43
  }
44
+
51
45
  /**
52
46
  * Creates a selection range for the DOM.
53
47
  * @param editor - The lexical editor.
@@ -57,8 +51,6 @@ function getDOMIndexWithinParent(node) {
57
51
  * @param _focusOffset - The amount of space offset from the focus to the anchor.
58
52
  * @returns The range of selection for the DOM that was created.
59
53
  */
60
-
61
-
62
54
  function createDOMRange(editor, anchorNode, _anchorOffset, focusNode, _focusOffset) {
63
55
  const anchorKey = anchorNode.getKey();
64
56
  const focusKey = focusNode.getKey();
@@ -67,154 +59,129 @@ function createDOMRange(editor, anchorNode, _anchorOffset, focusNode, _focusOffs
67
59
  let focusDOM = editor.getElementByKey(focusKey);
68
60
  let anchorOffset = _anchorOffset;
69
61
  let focusOffset = _focusOffset;
70
-
71
62
  if (lexical.$isTextNode(anchorNode)) {
72
63
  anchorDOM = getDOMTextNode(anchorDOM);
73
64
  }
74
-
75
65
  if (lexical.$isTextNode(focusNode)) {
76
66
  focusDOM = getDOMTextNode(focusDOM);
77
67
  }
78
-
79
68
  if (anchorNode === undefined || focusNode === undefined || anchorDOM === null || focusDOM === null) {
80
69
  return null;
81
70
  }
82
-
83
71
  if (anchorDOM.nodeName === 'BR') {
84
72
  [anchorDOM, anchorOffset] = getDOMIndexWithinParent(anchorDOM);
85
73
  }
86
-
87
74
  if (focusDOM.nodeName === 'BR') {
88
75
  [focusDOM, focusOffset] = getDOMIndexWithinParent(focusDOM);
89
76
  }
90
-
91
77
  const firstChild = anchorDOM.firstChild;
92
-
93
78
  if (anchorDOM === focusDOM && firstChild != null && firstChild.nodeName === 'BR' && anchorOffset === 0 && focusOffset === 0) {
94
79
  focusOffset = 1;
95
80
  }
96
-
97
81
  try {
98
82
  range.setStart(anchorDOM, anchorOffset);
99
83
  range.setEnd(focusDOM, focusOffset);
100
84
  } catch (e) {
101
85
  return null;
102
86
  }
103
-
104
87
  if (range.collapsed && (anchorOffset !== focusOffset || anchorKey !== focusKey)) {
105
88
  // Range is backwards, we need to reverse it
106
89
  range.setStart(focusDOM, focusOffset);
107
90
  range.setEnd(anchorDOM, anchorOffset);
108
91
  }
109
-
110
92
  return range;
111
93
  }
94
+
112
95
  /**
113
96
  * Creates DOMRects, generally used to help the editor find a specific location on the screen.
114
97
  * @param editor - The lexical editor
115
98
  * @param range - A fragment of a document that can contain nodes and parts of text nodes.
116
99
  * @returns The selectionRects as an array.
117
100
  */
118
-
119
101
  function createRectsFromDOMRange(editor, range) {
120
102
  const rootElement = editor.getRootElement();
121
-
122
103
  if (rootElement === null) {
123
104
  return [];
124
105
  }
125
-
126
106
  const rootRect = rootElement.getBoundingClientRect();
127
107
  const computedStyle = getComputedStyle(rootElement);
128
108
  const rootPadding = parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight);
129
109
  const selectionRects = Array.from(range.getClientRects());
130
- let selectionRectsLength = selectionRects.length; //sort rects from top left to bottom right.
131
-
110
+ let selectionRectsLength = selectionRects.length;
111
+ //sort rects from top left to bottom right.
132
112
  selectionRects.sort((a, b) => {
133
- const top = a.top - b.top; // Some rects match position closely, but not perfectly,
113
+ const top = a.top - b.top;
114
+ // Some rects match position closely, but not perfectly,
134
115
  // so we give a 3px tolerance.
135
-
136
116
  if (Math.abs(top) <= 3) {
137
117
  return a.left - b.left;
138
118
  }
139
-
140
119
  return top;
141
120
  });
142
121
  let prevRect;
143
-
144
122
  for (let i = 0; i < selectionRectsLength; i++) {
145
- const selectionRect = selectionRects[i]; // Exclude rects that overlap preceding Rects in the sorted list.
146
-
147
- const isOverlappingRect = prevRect && prevRect.top <= selectionRect.top && prevRect.top + prevRect.height > selectionRect.top && prevRect.left + prevRect.width > selectionRect.left; // Exclude selections that span the entire element
148
-
123
+ const selectionRect = selectionRects[i];
124
+ // Exclude rects that overlap preceding Rects in the sorted list.
125
+ const isOverlappingRect = prevRect && prevRect.top <= selectionRect.top && prevRect.top + prevRect.height > selectionRect.top && prevRect.left + prevRect.width > selectionRect.left;
126
+ // Exclude selections that span the entire element
149
127
  const selectionSpansElement = selectionRect.width + rootPadding === rootRect.width;
150
-
151
128
  if (isOverlappingRect || selectionSpansElement) {
152
129
  selectionRects.splice(i--, 1);
153
130
  selectionRectsLength--;
154
131
  continue;
155
132
  }
156
-
157
133
  prevRect = selectionRect;
158
134
  }
159
-
160
135
  return selectionRects;
161
136
  }
137
+
162
138
  /**
163
139
  * Creates an object containing all the styles and their values provided in the CSS string.
164
140
  * @param css - The CSS string of styles and their values.
165
141
  * @returns The styleObject containing all the styles and their values.
166
142
  */
167
-
168
143
  function getStyleObjectFromRawCSS(css) {
169
144
  const styleObject = {};
170
145
  const styles = css.split(';');
171
-
172
146
  for (const style of styles) {
173
147
  if (style !== '') {
174
148
  const [key, value] = style.split(/:([^]+)/); // split on first colon
175
-
176
149
  styleObject[key.trim()] = value.trim();
177
150
  }
178
151
  }
179
-
180
152
  return styleObject;
181
153
  }
154
+
182
155
  /**
183
156
  * Given a CSS string, returns an object from the style cache.
184
157
  * @param css - The CSS property as a string.
185
158
  * @returns The value of the given CSS property.
186
159
  */
187
-
188
160
  function getStyleObjectFromCSS(css) {
189
161
  let value = CSS_TO_STYLES.get(css);
190
-
191
162
  if (value === undefined) {
192
163
  value = getStyleObjectFromRawCSS(css);
193
164
  CSS_TO_STYLES.set(css, value);
194
165
  }
195
-
196
166
  {
197
167
  // Freeze the value in DEV to prevent accidental mutations
198
168
  Object.freeze(value);
199
169
  }
200
-
201
170
  return value;
202
171
  }
172
+
203
173
  /**
204
174
  * Gets the CSS styles from the style object.
205
175
  * @param styles - The style object containing the styles to get.
206
176
  * @returns A string containing the CSS styles and their values.
207
177
  */
208
-
209
178
  function getCSSFromStyleObject(styles) {
210
179
  let css = '';
211
-
212
180
  for (const style in styles) {
213
181
  if (style) {
214
182
  css += `${style}: ${styles[style]};`;
215
183
  }
216
184
  }
217
-
218
185
  return css;
219
186
  }
220
187
 
@@ -225,7 +192,6 @@ function getCSSFromStyleObject(styles) {
225
192
  * LICENSE file in the root directory of this source tree.
226
193
  *
227
194
  */
228
-
229
195
  function $updateElementNodeProperties(target, source) {
230
196
  target.__first = source.__first;
231
197
  target.__last = source.__last;
@@ -235,7 +201,6 @@ function $updateElementNodeProperties(target, source) {
235
201
  target.__dir = source.__dir;
236
202
  return target;
237
203
  }
238
-
239
204
  function $updateTextNodeProperties(target, source) {
240
205
  target.__format = source.__format;
241
206
  target.__style = source.__style;
@@ -243,31 +208,28 @@ function $updateTextNodeProperties(target, source) {
243
208
  target.__detail = source.__detail;
244
209
  return target;
245
210
  }
211
+
246
212
  /**
247
213
  * Returns a copy of a node, but generates a new key for the copy.
248
214
  * @param node - The node to be cloned.
249
215
  * @returns The clone of the node.
250
216
  */
251
-
252
-
253
217
  function $cloneWithProperties(node) {
254
- const constructor = node.constructor; // @ts-expect-error
255
-
218
+ const constructor = node.constructor;
219
+ // @ts-expect-error
256
220
  const clone = constructor.clone(node);
257
221
  clone.__parent = node.__parent;
258
222
  clone.__next = node.__next;
259
223
  clone.__prev = node.__prev;
260
-
261
224
  if (lexical.$isElementNode(node) && lexical.$isElementNode(clone)) {
262
225
  return $updateElementNodeProperties(clone, node);
263
226
  }
264
-
265
227
  if (lexical.$isTextNode(node) && lexical.$isTextNode(clone)) {
266
228
  return $updateTextNodeProperties(clone, node);
267
229
  }
268
-
269
230
  return clone;
270
231
  }
232
+
271
233
  /**
272
234
  * Generally used to append text content to HTML and JSON. Grabs the text content and "slices"
273
235
  * it to be generated into the new TextNode.
@@ -275,14 +237,12 @@ function $cloneWithProperties(node) {
275
237
  * @param textNode - The TextNode to be edited.
276
238
  * @returns The updated TextNode.
277
239
  */
278
-
279
240
  function $sliceSelectedTextNodeContent(selection, textNode) {
280
241
  if (textNode.isSelected() && !textNode.isSegmented() && !textNode.isToken() && (lexical.$isRangeSelection(selection) || lexical.DEPRECATED_$isGridSelection(selection))) {
281
242
  const anchorNode = selection.anchor.getNode();
282
243
  const focusNode = selection.focus.getNode();
283
244
  const isAnchor = textNode.is(anchorNode);
284
245
  const isFocus = textNode.is(focusNode);
285
-
286
246
  if (isAnchor || isFocus) {
287
247
  const isBackward = selection.isBackward();
288
248
  const [anchorOffset, focusOffset] = selection.getCharacterOffsets();
@@ -291,7 +251,6 @@ function $sliceSelectedTextNodeContent(selection, textNode) {
291
251
  const isLast = textNode.is(isBackward ? anchorNode : focusNode);
292
252
  let startOffset = 0;
293
253
  let endOffset = undefined;
294
-
295
254
  if (isSame) {
296
255
  startOffset = anchorOffset > focusOffset ? focusOffset : anchorOffset;
297
256
  endOffset = anchorOffset > focusOffset ? anchorOffset : focusOffset;
@@ -304,27 +263,25 @@ function $sliceSelectedTextNodeContent(selection, textNode) {
304
263
  startOffset = 0;
305
264
  endOffset = offset;
306
265
  }
307
-
308
266
  textNode.__text = textNode.__text.slice(startOffset, endOffset);
309
267
  return textNode;
310
268
  }
311
269
  }
312
-
313
270
  return textNode;
314
271
  }
272
+
315
273
  /**
316
274
  * Determines if the current selection is at the end of the node.
317
275
  * @param point - The point of the selection to test.
318
276
  * @returns true if the provided point offset is in the last possible position, false otherwise.
319
277
  */
320
-
321
278
  function $isAtNodeEnd(point) {
322
279
  if (point.type === 'text') {
323
280
  return point.offset === point.getNode().getTextContentSize();
324
281
  }
325
-
326
282
  return point.offset === point.getNode().getChildrenSize();
327
283
  }
284
+
328
285
  /**
329
286
  * Trims text from a node in order to shorten it, eg. to enforce a text's max length. If it deletes text
330
287
  * that is an ancestor of the anchor then it will leave 2 indents, otherwise, if no text content exists, it deletes
@@ -333,89 +290,72 @@ function $isAtNodeEnd(point) {
333
290
  * @param anchor - The anchor of the current selection, where the selection should be pointing.
334
291
  * @param delCount - The amount of characters to delete. Useful as a dynamic variable eg. textContentSize - maxLength;
335
292
  */
336
-
337
293
  function trimTextContentFromAnchor(editor, anchor, delCount) {
338
294
  // Work from the current selection anchor point
339
295
  let currentNode = anchor.getNode();
340
296
  let remaining = delCount;
341
-
342
297
  if (lexical.$isElementNode(currentNode)) {
343
298
  const descendantNode = currentNode.getDescendantByIndex(anchor.offset);
344
-
345
299
  if (descendantNode !== null) {
346
300
  currentNode = descendantNode;
347
301
  }
348
302
  }
349
-
350
303
  while (remaining > 0 && currentNode !== null) {
304
+ if (lexical.$isElementNode(currentNode)) {
305
+ const lastDescendant = currentNode.getLastDescendant();
306
+ if (lastDescendant !== null) {
307
+ currentNode = lastDescendant;
308
+ }
309
+ }
351
310
  let nextNode = currentNode.getPreviousSibling();
352
311
  let additionalElementWhitespace = 0;
353
-
354
312
  if (nextNode === null) {
355
313
  let parent = currentNode.getParentOrThrow();
356
314
  let parentSibling = parent.getPreviousSibling();
357
-
358
315
  while (parentSibling === null) {
359
316
  parent = parent.getParent();
360
-
361
317
  if (parent === null) {
362
318
  nextNode = null;
363
319
  break;
364
320
  }
365
-
366
321
  parentSibling = parent.getPreviousSibling();
367
322
  }
368
-
369
323
  if (parent !== null) {
370
324
  additionalElementWhitespace = parent.isInline() ? 0 : 2;
371
-
372
- if (lexical.$isElementNode(parentSibling)) {
373
- nextNode = parentSibling.getLastDescendant();
374
- } else {
375
- nextNode = parentSibling;
376
- }
325
+ nextNode = parentSibling;
377
326
  }
378
327
  }
379
-
380
- let text = currentNode.getTextContent(); // If the text is empty, we need to consider adding in two line breaks to match
328
+ let text = currentNode.getTextContent();
329
+ // If the text is empty, we need to consider adding in two line breaks to match
381
330
  // the content if we were to get it from its parent.
382
-
383
331
  if (text === '' && lexical.$isElementNode(currentNode) && !currentNode.isInline()) {
384
332
  // TODO: should this be handled in core?
385
333
  text = '\n\n';
386
334
  }
387
-
388
335
  const currentNodeSize = text.length;
389
-
390
336
  if (!lexical.$isTextNode(currentNode) || remaining >= currentNodeSize) {
391
337
  const parent = currentNode.getParent();
392
338
  currentNode.remove();
393
-
394
339
  if (parent != null && parent.getChildrenSize() === 0 && !lexical.$isRootNode(parent)) {
395
340
  parent.remove();
396
341
  }
397
-
398
342
  remaining -= currentNodeSize + additionalElementWhitespace;
399
343
  currentNode = nextNode;
400
344
  } else {
401
- const key = currentNode.getKey(); // See if we can just revert it to what was in the last editor state
402
-
345
+ const key = currentNode.getKey();
346
+ // See if we can just revert it to what was in the last editor state
403
347
  const prevTextContent = editor.getEditorState().read(() => {
404
348
  const prevNode = lexical.$getNodeByKey(key);
405
-
406
349
  if (lexical.$isTextNode(prevNode) && prevNode.isSimpleText()) {
407
350
  return prevNode.getTextContent();
408
351
  }
409
-
410
352
  return null;
411
353
  });
412
354
  const offset = currentNodeSize - remaining;
413
355
  const slicedText = text.slice(0, offset);
414
-
415
356
  if (prevTextContent !== null && prevTextContent !== text) {
416
357
  const prevSelection = lexical.$getPreviousSelection();
417
358
  let target = currentNode;
418
-
419
359
  if (!currentNode.isSimpleText()) {
420
360
  const textNode = lexical.$createTextNode(prevTextContent);
421
361
  currentNode.replace(textNode);
@@ -423,7 +363,6 @@ function trimTextContentFromAnchor(editor, anchor, delCount) {
423
363
  } else {
424
364
  currentNode.setTextContent(prevTextContent);
425
365
  }
426
-
427
366
  if (lexical.$isRangeSelection(prevSelection) && prevSelection.isCollapsed()) {
428
367
  const prevOffset = prevSelection.anchor.offset;
429
368
  target.select(prevOffset, prevOffset);
@@ -431,16 +370,14 @@ function trimTextContentFromAnchor(editor, anchor, delCount) {
431
370
  } else if (currentNode.isSimpleText()) {
432
371
  // Split text
433
372
  const isSelected = anchor.key === key;
434
- let anchorOffset = anchor.offset; // Move offset to end if it's less than the remaining number, otherwise
373
+ let anchorOffset = anchor.offset;
374
+ // Move offset to end if it's less than the remaining number, otherwise
435
375
  // we'll have a negative splitStart.
436
-
437
376
  if (anchorOffset < remaining) {
438
377
  anchorOffset = currentNodeSize;
439
378
  }
440
-
441
379
  const splitStart = isSelected ? anchorOffset - remaining : 0;
442
380
  const splitEnd = isSelected ? anchorOffset : offset;
443
-
444
381
  if (isSelected && splitStart === 0) {
445
382
  const [excessNode] = currentNode.splitText(splitStart, splitEnd);
446
383
  excessNode.remove();
@@ -452,22 +389,20 @@ function trimTextContentFromAnchor(editor, anchor, delCount) {
452
389
  const textNode = lexical.$createTextNode(slicedText);
453
390
  currentNode.replace(textNode);
454
391
  }
455
-
456
392
  remaining = 0;
457
393
  }
458
394
  }
459
395
  }
396
+
460
397
  /**
461
398
  * Gets the TextNode's style object and adds the styles to the CSS.
462
399
  * @param node - The TextNode to add styles to.
463
400
  */
464
-
465
401
  function $addNodeStyle(node) {
466
402
  const CSSText = node.getStyle();
467
403
  const styles = getStyleObjectFromRawCSS(CSSText);
468
404
  CSS_TO_STYLES.set(CSSText, styles);
469
405
  }
470
-
471
406
  function $patchStyle(target, patch) {
472
407
  const prevStyles = getStyleObjectFromCSS('getStyle' in target ? target.getStyle() : target.style);
473
408
  const newStyles = Object.entries(patch).reduce((styles, [key, value]) => {
@@ -476,14 +411,15 @@ function $patchStyle(target, patch) {
476
411
  } else {
477
412
  styles[key] = value;
478
413
  }
479
-
480
414
  return styles;
481
- }, { ...prevStyles
415
+ }, {
416
+ ...prevStyles
482
417
  } || {});
483
418
  const newCSSText = getCSSFromStyleObject(newStyles);
484
419
  target.setStyle(newCSSText);
485
420
  CSS_TO_STYLES.set(newCSSText, newStyles);
486
421
  }
422
+
487
423
  /**
488
424
  * Applies the provided styles to the TextNodes in the provided Selection.
489
425
  * Will update partially selected TextNodes by splitting the TextNode and applying
@@ -491,40 +427,31 @@ function $patchStyle(target, patch) {
491
427
  * @param selection - The selected node(s) to update.
492
428
  * @param patch - The patch to apply, which can include multiple styles. { CSSProperty: value }
493
429
  */
494
-
495
-
496
430
  function $patchStyleText(selection, patch) {
497
431
  const selectedNodes = selection.getNodes();
498
432
  const selectedNodesLength = selectedNodes.length;
499
-
500
433
  if (lexical.DEPRECATED_$isGridSelection(selection)) {
501
434
  const cellSelection = lexical.$createRangeSelection();
502
435
  const cellSelectionAnchor = cellSelection.anchor;
503
436
  const cellSelectionFocus = cellSelection.focus;
504
-
505
437
  for (let i = 0; i < selectedNodesLength; i++) {
506
438
  const node = selectedNodes[i];
507
-
508
439
  if (lexical.DEPRECATED_$isGridCellNode(node)) {
509
440
  cellSelectionAnchor.set(node.getKey(), 0, 'element');
510
441
  cellSelectionFocus.set(node.getKey(), node.getChildrenSize(), 'element');
511
442
  $patchStyleText(lexical.$normalizeSelection__EXPERIMENTAL(cellSelection), patch);
512
443
  }
513
444
  }
514
-
515
445
  lexical.$setSelection(selection);
516
446
  return;
517
447
  }
518
-
519
448
  const lastIndex = selectedNodesLength - 1;
520
449
  let firstNode = selectedNodes[0];
521
450
  let lastNode = selectedNodes[lastIndex];
522
-
523
451
  if (selection.isCollapsed()) {
524
452
  $patchStyle(selection, patch);
525
453
  return;
526
454
  }
527
-
528
455
  const anchor = selection.anchor;
529
456
  const focus = selection.focus;
530
457
  const firstNodeText = firstNode.getTextContent();
@@ -536,31 +463,32 @@ function $patchStyleText(selection, patch) {
536
463
  let endOffset = isBefore ? focusOffset : anchorOffset;
537
464
  const startType = isBefore ? anchor.type : focus.type;
538
465
  const endType = isBefore ? focus.type : anchor.type;
539
- const endKey = isBefore ? focus.key : anchor.key; // This is the case where the user only selected the very end of the
540
- // first node so we don't want to include it in the formatting change.
466
+ const endKey = isBefore ? focus.key : anchor.key;
541
467
 
468
+ // This is the case where the user only selected the very end of the
469
+ // first node so we don't want to include it in the formatting change.
542
470
  if (lexical.$isTextNode(firstNode) && startOffset === firstNodeTextLength) {
543
471
  const nextSibling = firstNode.getNextSibling();
544
-
545
472
  if (lexical.$isTextNode(nextSibling)) {
546
473
  // we basically make the second node the firstNode, changing offsets accordingly
547
474
  anchorOffset = 0;
548
475
  startOffset = 0;
549
476
  firstNode = nextSibling;
550
477
  }
551
- } // This is the case where we only selected a single node
552
-
478
+ }
553
479
 
480
+ // This is the case where we only selected a single node
554
481
  if (selectedNodes.length === 1) {
555
482
  if (lexical.$isTextNode(firstNode)) {
556
483
  startOffset = startType === 'element' ? 0 : anchorOffset > focusOffset ? focusOffset : anchorOffset;
557
- endOffset = endType === 'element' ? firstNodeTextLength : anchorOffset > focusOffset ? anchorOffset : focusOffset; // No actual text is selected, so do nothing.
484
+ endOffset = endType === 'element' ? firstNodeTextLength : anchorOffset > focusOffset ? anchorOffset : focusOffset;
558
485
 
486
+ // No actual text is selected, so do nothing.
559
487
  if (startOffset === endOffset) {
560
488
  return;
561
- } // The entire node is selected, so just format it
562
-
489
+ }
563
490
 
491
+ // The entire node is selected, so just format it
564
492
  if (startOffset === 0 && endOffset === firstNodeTextLength) {
565
493
  $patchStyle(firstNode, patch);
566
494
  firstNode.select(startOffset, endOffset);
@@ -573,44 +501,41 @@ function $patchStyleText(selection, patch) {
573
501
  replacement.select(0, endOffset - startOffset);
574
502
  }
575
503
  } // multiple nodes selected.
576
-
577
504
  } else {
578
505
  if (lexical.$isTextNode(firstNode) && startOffset < firstNode.getTextContentSize()) {
579
506
  if (startOffset !== 0) {
580
507
  // the entire first node isn't selected, so split it
581
508
  firstNode = firstNode.splitText(startOffset)[1];
582
509
  startOffset = 0;
510
+ anchor.set(firstNode.getKey(), startOffset, 'text');
583
511
  }
584
-
585
512
  $patchStyle(firstNode, patch);
586
513
  }
587
-
588
514
  if (lexical.$isTextNode(lastNode)) {
589
515
  const lastNodeText = lastNode.getTextContent();
590
- const lastNodeTextLength = lastNodeText.length; // The last node might not actually be the end node
516
+ const lastNodeTextLength = lastNodeText.length;
517
+
518
+ // The last node might not actually be the end node
591
519
  //
592
520
  // If not, assume the last node is fully-selected unless the end offset is
593
521
  // zero.
594
-
595
522
  if (lastNode.__key !== endKey && endOffset !== 0) {
596
523
  endOffset = lastNodeTextLength;
597
- } // if the entire last node isn't selected, split it
598
-
524
+ }
599
525
 
526
+ // if the entire last node isn't selected, split it
600
527
  if (endOffset !== lastNodeTextLength) {
601
528
  [lastNode] = lastNode.splitText(endOffset);
602
529
  }
603
-
604
530
  if (endOffset !== 0) {
605
531
  $patchStyle(lastNode, patch);
606
532
  }
607
- } // style all the text nodes in between
608
-
533
+ }
609
534
 
535
+ // style all the text nodes in between
610
536
  for (let i = 1; i < lastIndex; i++) {
611
537
  const selectedNode = selectedNodes[i];
612
538
  const selectedNodeKey = selectedNode.getKey();
613
-
614
539
  if (lexical.$isTextNode(selectedNode) && selectedNodeKey !== firstNode.getKey() && selectedNodeKey !== lastNode.getKey() && !selectedNode.isToken()) {
615
540
  $patchStyle(selectedNode, patch);
616
541
  }
@@ -625,84 +550,55 @@ function $patchStyleText(selection, patch) {
625
550
  * LICENSE file in the root directory of this source tree.
626
551
  *
627
552
  */
553
+
628
554
  /**
629
555
  * Converts all nodes in the selection that are of one block type to another.
630
556
  * @param selection - The selected blocks to be converted.
631
557
  * @param createElement - The function that creates the node. eg. $createParagraphNode.
632
558
  */
633
-
634
559
  function $setBlocksType(selection, createElement) {
635
560
  if (selection.anchor.key === 'root') {
636
561
  const element = createElement();
637
562
  const root = lexical.$getRoot();
638
563
  const firstChild = root.getFirstChild();
639
-
640
564
  if (firstChild) {
641
565
  firstChild.replace(element, true);
642
566
  } else {
643
567
  root.append(element);
644
568
  }
645
-
646
569
  return;
647
570
  }
648
-
649
571
  const nodes = selection.getNodes();
650
- let maybeBlock = selection.anchor.getNode().getParentOrThrow();
651
-
652
- if (nodes.indexOf(maybeBlock) === -1) {
653
- nodes.push(maybeBlock);
654
- }
655
-
656
- if (maybeBlock.isInline()) {
657
- maybeBlock = maybeBlock.getParentOrThrow();
658
-
659
- if (nodes.indexOf(maybeBlock) === -1) {
660
- nodes.push(maybeBlock);
661
- }
572
+ const firstSelectedBlock = $getAncestor(selection.anchor.getNode(), INTERNAL_$isBlock);
573
+ if (firstSelectedBlock && nodes.indexOf(firstSelectedBlock) === -1) {
574
+ nodes.push(firstSelectedBlock);
662
575
  }
663
-
664
576
  for (let i = 0; i < nodes.length; i++) {
665
577
  const node = nodes[i];
666
-
667
- if (!isBlock(node)) {
578
+ if (!INTERNAL_$isBlock(node)) {
668
579
  continue;
669
580
  }
670
-
671
581
  const targetElement = createElement();
672
582
  targetElement.setFormat(node.getFormatType());
673
583
  targetElement.setIndent(node.getIndent());
674
584
  node.replace(targetElement, true);
675
585
  }
676
586
  }
677
-
678
- function isBlock(node) {
679
- if (!lexical.$isElementNode(node) || lexical.$isRootOrShadowRoot(node)) {
680
- return false;
681
- }
682
-
683
- const firstChild = node.getFirstChild();
684
- const isLeafElement = firstChild === null || lexical.$isLineBreakNode(firstChild) || lexical.$isTextNode(firstChild) || firstChild.isInline();
685
- return !node.isInline() && node.canBeEmpty() !== false && isLeafElement;
686
- }
687
-
688
587
  function isPointAttached(point) {
689
588
  return point.getNode().isAttached();
690
589
  }
691
-
692
590
  function $removeParentEmptyElements(startingNode) {
693
591
  let node = startingNode;
694
-
695
592
  while (node !== null && !lexical.$isRootOrShadowRoot(node)) {
696
593
  const latest = node.getLatest();
697
594
  const parentNode = node.getParent();
698
-
699
595
  if (latest.getChildrenSize() === 0) {
700
596
  node.remove(true);
701
597
  }
702
-
703
598
  node = parentNode;
704
599
  }
705
600
  }
601
+
706
602
  /**
707
603
  * @deprecated
708
604
  * Wraps all nodes in the selection into another node of the type returned by createElement.
@@ -710,13 +606,10 @@ function $removeParentEmptyElements(startingNode) {
710
606
  * @param createElement - A function that creates the wrapping ElementNode. eg. $createParagraphNode.
711
607
  * @param wrappingElement - An element to append the wrapped selection and its children to.
712
608
  */
713
-
714
-
715
609
  function $wrapNodes(selection, createElement, wrappingElement = null) {
716
610
  const nodes = selection.getNodes();
717
611
  const nodesLength = nodes.length;
718
612
  const anchor = selection.anchor;
719
-
720
613
  if (nodesLength === 0 || nodesLength === 1 && anchor.type === 'element' && anchor.getNode().getChildrenSize() === 0) {
721
614
  const target = anchor.type === 'text' ? anchor.getNode().getParentOrThrow() : anchor.getNode();
722
615
  const children = target.getChildren();
@@ -724,24 +617,20 @@ function $wrapNodes(selection, createElement, wrappingElement = null) {
724
617
  element.setFormat(target.getFormatType());
725
618
  element.setIndent(target.getIndent());
726
619
  children.forEach(child => element.append(child));
727
-
728
620
  if (wrappingElement) {
729
621
  element = wrappingElement.append(element);
730
622
  }
731
-
732
623
  target.replace(element);
733
624
  return;
734
625
  }
735
-
736
626
  let topLevelNode = null;
737
627
  let descendants = [];
738
-
739
628
  for (let i = 0; i < nodesLength; i++) {
740
- const node = nodes[i]; // Determine whether wrapping has to be broken down into multiple chunks. This can happen if the
629
+ const node = nodes[i];
630
+ // Determine whether wrapping has to be broken down into multiple chunks. This can happen if the
741
631
  // user selected multiple Root-like nodes that have to be treated separately as if they are
742
632
  // their own branch. I.e. you don't want to wrap a whole table, but rather the contents of each
743
633
  // of each of the cell nodes.
744
-
745
634
  if (lexical.$isRootOrShadowRoot(node)) {
746
635
  $wrapNodesImpl(selection, descendants, descendants.length, createElement, wrappingElement);
747
636
  descendants = [];
@@ -753,9 +642,9 @@ function $wrapNodes(selection, createElement, wrappingElement = null) {
753
642
  descendants = [node];
754
643
  }
755
644
  }
756
-
757
645
  $wrapNodesImpl(selection, descendants, descendants.length, createElement, wrappingElement);
758
646
  }
647
+
759
648
  /**
760
649
  * Wraps each node into a new ElementNode.
761
650
  * @param selection - The selection of nodes to wrap.
@@ -765,80 +654,67 @@ function $wrapNodes(selection, createElement, wrappingElement = null) {
765
654
  * @param wrappingElement - An element to wrap all the nodes into.
766
655
  * @returns
767
656
  */
768
-
769
657
  function $wrapNodesImpl(selection, nodes, nodesLength, createElement, wrappingElement = null) {
770
658
  if (nodes.length === 0) {
771
659
  return;
772
660
  }
773
-
774
661
  const firstNode = nodes[0];
775
662
  const elementMapping = new Map();
776
- const elements = []; // The below logic is to find the right target for us to
663
+ const elements = [];
664
+ // The below logic is to find the right target for us to
777
665
  // either insertAfter/insertBefore/append the corresponding
778
666
  // elements to. This is made more complicated due to nested
779
667
  // structures.
780
-
781
668
  let target = lexical.$isElementNode(firstNode) ? firstNode : firstNode.getParentOrThrow();
782
-
783
669
  if (target.isInline()) {
784
670
  target = target.getParentOrThrow();
785
671
  }
786
-
787
672
  let targetIsPrevSibling = false;
788
-
789
673
  while (target !== null) {
790
674
  const prevSibling = target.getPreviousSibling();
791
-
792
675
  if (prevSibling !== null) {
793
676
  target = prevSibling;
794
677
  targetIsPrevSibling = true;
795
678
  break;
796
679
  }
797
-
798
680
  target = target.getParentOrThrow();
799
-
800
681
  if (lexical.$isRootOrShadowRoot(target)) {
801
682
  break;
802
683
  }
803
684
  }
685
+ const emptyElements = new Set();
804
686
 
805
- const emptyElements = new Set(); // Find any top level empty elements
806
-
687
+ // Find any top level empty elements
807
688
  for (let i = 0; i < nodesLength; i++) {
808
689
  const node = nodes[i];
809
-
810
690
  if (lexical.$isElementNode(node) && node.getChildrenSize() === 0) {
811
691
  emptyElements.add(node.getKey());
812
692
  }
813
693
  }
694
+ const movedNodes = new Set();
814
695
 
815
- const movedNodes = new Set(); // Move out all leaf nodes into our elements array.
696
+ // Move out all leaf nodes into our elements array.
816
697
  // If we find a top level empty element, also move make
817
698
  // an element for that.
818
-
819
699
  for (let i = 0; i < nodesLength; i++) {
820
700
  const node = nodes[i];
821
701
  let parent = node.getParent();
822
-
823
702
  if (parent !== null && parent.isInline()) {
824
703
  parent = parent.getParent();
825
704
  }
826
-
827
705
  if (parent !== null && lexical.$isLeafNode(node) && !movedNodes.has(node.getKey())) {
828
706
  const parentKey = parent.getKey();
829
-
830
707
  if (elementMapping.get(parentKey) === undefined) {
831
708
  const targetElement = createElement();
832
709
  targetElement.setFormat(parent.getFormatType());
833
710
  targetElement.setIndent(parent.getIndent());
834
711
  elements.push(targetElement);
835
- elementMapping.set(parentKey, targetElement); // Move node and its siblings to the new
712
+ elementMapping.set(parentKey, targetElement);
713
+ // Move node and its siblings to the new
836
714
  // element.
837
-
838
715
  parent.getChildren().forEach(child => {
839
716
  targetElement.append(child);
840
717
  movedNodes.add(child.getKey());
841
-
842
718
  if (lexical.$isElementNode(child)) {
843
719
  // Skip nested leaf nodes if the parent has already been moved
844
720
  child.getChildrenKeys().forEach(key => movedNodes.add(key));
@@ -854,17 +730,16 @@ function $wrapNodesImpl(selection, nodes, nodesLength, createElement, wrappingEl
854
730
  node.remove(true);
855
731
  }
856
732
  }
857
-
858
733
  if (wrappingElement !== null) {
859
734
  for (let i = 0; i < elements.length; i++) {
860
735
  const element = elements[i];
861
736
  wrappingElement.append(element);
862
737
  }
863
738
  }
739
+ let lastElement = null;
864
740
 
865
- let lastElement = null; // If our target is Root-like, let's see if we can re-adjust
741
+ // If our target is Root-like, let's see if we can re-adjust
866
742
  // so that the target is the first child instead.
867
-
868
743
  if (lexical.$isRootOrShadowRoot(target)) {
869
744
  if (targetIsPrevSibling) {
870
745
  if (wrappingElement !== null) {
@@ -877,11 +752,9 @@ function $wrapNodesImpl(selection, nodes, nodesLength, createElement, wrappingEl
877
752
  }
878
753
  } else {
879
754
  const firstChild = target.getFirstChild();
880
-
881
755
  if (lexical.$isElementNode(firstChild)) {
882
756
  target = firstChild;
883
757
  }
884
-
885
758
  if (firstChild === null) {
886
759
  if (wrappingElement) {
887
760
  target.append(wrappingElement);
@@ -915,9 +788,7 @@ function $wrapNodesImpl(selection, nodes, nodesLength, createElement, wrappingEl
915
788
  }
916
789
  }
917
790
  }
918
-
919
791
  const prevSelection = lexical.$getPreviousSelection();
920
-
921
792
  if (lexical.$isRangeSelection(prevSelection) && isPointAttached(prevSelection.anchor) && isPointAttached(prevSelection.focus)) {
922
793
  lexical.$setSelection(prevSelection.clone());
923
794
  } else if (lastElement !== null) {
@@ -926,17 +797,18 @@ function $wrapNodesImpl(selection, nodes, nodesLength, createElement, wrappingEl
926
797
  selection.dirty = true;
927
798
  }
928
799
  }
800
+
929
801
  /**
930
802
  * Determines if the default character selection should be overridden. Used with DecoratorNodes
931
803
  * @param selection - The selection whose default character selection may need to be overridden.
932
804
  * @param isBackward - Is the selection backwards (the focus comes before the anchor)?
933
805
  * @returns true if it should be overridden, false if not.
934
806
  */
935
-
936
807
  function $shouldOverrideDefaultCharacterSelection(selection, isBackward) {
937
808
  const possibleNode = lexical.$getAdjacentNode(selection.focus, isBackward);
938
809
  return lexical.$isDecoratorNode(possibleNode) && !possibleNode.isIsolated() || lexical.$isElementNode(possibleNode) && !possibleNode.isInline() && !possibleNode.canBeEmpty();
939
810
  }
811
+
940
812
  /**
941
813
  * Moves the selection according to the arguments.
942
814
  * @param selection - The selected text or nodes.
@@ -944,37 +816,36 @@ function $shouldOverrideDefaultCharacterSelection(selection, isBackward) {
944
816
  * @param isBackward - Is the selection selected backwards (the focus comes before the anchor)?
945
817
  * @param granularity - The distance to adjust the current selection.
946
818
  */
947
-
948
819
  function $moveCaretSelection(selection, isHoldingShift, isBackward, granularity) {
949
820
  selection.modify(isHoldingShift ? 'extend' : 'move', isBackward, granularity);
950
821
  }
822
+
951
823
  /**
952
824
  * Tests a parent element for right to left direction.
953
825
  * @param selection - The selection whose parent is to be tested.
954
826
  * @returns true if the selections' parent element has a direction of 'rtl' (right to left), false otherwise.
955
827
  */
956
-
957
828
  function $isParentElementRTL(selection) {
958
829
  const anchorNode = selection.anchor.getNode();
959
830
  const parent = lexical.$isRootNode(anchorNode) ? anchorNode : anchorNode.getParentOrThrow();
960
831
  return parent.getDirection() === 'rtl';
961
832
  }
833
+
962
834
  /**
963
835
  * Moves selection by character according to arguments.
964
836
  * @param selection - The selection of the characters to move.
965
837
  * @param isHoldingShift - Is the shift key being held down during the operation.
966
838
  * @param isBackward - Is the selection backward (the focus comes before the anchor)?
967
839
  */
968
-
969
840
  function $moveCharacter(selection, isHoldingShift, isBackward) {
970
841
  const isRTL = $isParentElementRTL(selection);
971
842
  $moveCaretSelection(selection, isHoldingShift, isBackward ? !isRTL : isRTL, 'character');
972
843
  }
844
+
973
845
  /**
974
846
  * Expands the current Selection to cover all of the content in the editor.
975
847
  * @param selection - The current selection.
976
848
  */
977
-
978
849
  function $selectAll(selection) {
979
850
  const anchor = selection.anchor;
980
851
  const focus = selection.focus;
@@ -986,25 +857,23 @@ function $selectAll(selection) {
986
857
  let firstType = 'element';
987
858
  let lastType = 'element';
988
859
  let lastOffset = 0;
989
-
990
860
  if (lexical.$isTextNode(firstNode)) {
991
861
  firstType = 'text';
992
862
  } else if (!lexical.$isElementNode(firstNode) && firstNode !== null) {
993
863
  firstNode = firstNode.getParentOrThrow();
994
864
  }
995
-
996
865
  if (lexical.$isTextNode(lastNode)) {
997
866
  lastType = 'text';
998
867
  lastOffset = lastNode.getTextContentSize();
999
868
  } else if (!lexical.$isElementNode(lastNode) && lastNode !== null) {
1000
869
  lastNode = lastNode.getParentOrThrow();
1001
870
  }
1002
-
1003
871
  if (firstNode && lastNode) {
1004
872
  anchor.set(firstNode.getKey(), 0, firstType);
1005
873
  focus.set(lastNode.getKey(), lastOffset, lastType);
1006
874
  }
1007
875
  }
876
+
1008
877
  /**
1009
878
  * Returns the current value of a CSS property for Nodes, if set. If not set, it returns the defaultValue.
1010
879
  * @param node - The node whose style value to get.
@@ -1012,17 +881,15 @@ function $selectAll(selection) {
1012
881
  * @param defaultValue - The default value for the property.
1013
882
  * @returns The value of the property for node.
1014
883
  */
1015
-
1016
884
  function $getNodeStyleValueForProperty(node, styleProperty, defaultValue) {
1017
885
  const css = node.getStyle();
1018
886
  const styleObject = getStyleObjectFromCSS(css);
1019
-
1020
887
  if (styleObject !== null) {
1021
888
  return styleObject[styleProperty] || defaultValue;
1022
889
  }
1023
-
1024
890
  return defaultValue;
1025
891
  }
892
+
1026
893
  /**
1027
894
  * Returns the current value of a CSS property for TextNodes in the Selection, if set. If not set, it returns the defaultValue.
1028
895
  * If all TextNodes do not have the same value, it returns an empty string.
@@ -1031,8 +898,6 @@ function $getNodeStyleValueForProperty(node, styleProperty, defaultValue) {
1031
898
  * @param defaultValue - The default value for the property, defaults to an empty string.
1032
899
  * @returns The value of the property for the selected TextNodes.
1033
900
  */
1034
-
1035
-
1036
901
  function $getSelectionStyleValueForProperty(selection, styleProperty, defaultValue = '') {
1037
902
  let styleValue = null;
1038
903
  const nodes = selection.getNodes();
@@ -1041,28 +906,24 @@ function $getSelectionStyleValueForProperty(selection, styleProperty, defaultVal
1041
906
  const isBackward = selection.isBackward();
1042
907
  const endOffset = isBackward ? focus.offset : anchor.offset;
1043
908
  const endNode = isBackward ? focus.getNode() : anchor.getNode();
1044
-
1045
- if (selection.style !== '') {
909
+ if (selection.isCollapsed() && selection.style !== '') {
1046
910
  const css = selection.style;
1047
911
  const styleObject = getStyleObjectFromCSS(css);
1048
-
1049
912
  if (styleObject !== null && styleProperty in styleObject) {
1050
913
  return styleObject[styleProperty];
1051
914
  }
1052
915
  }
1053
-
1054
916
  for (let i = 0; i < nodes.length; i++) {
1055
- const node = nodes[i]; // if no actual characters in the end node are selected, we don't
917
+ const node = nodes[i];
918
+
919
+ // if no actual characters in the end node are selected, we don't
1056
920
  // include it in the selection for purposes of determining style
1057
921
  // value
1058
-
1059
922
  if (i !== 0 && endOffset === 0 && node.is(endNode)) {
1060
923
  continue;
1061
924
  }
1062
-
1063
925
  if (lexical.$isTextNode(node)) {
1064
926
  const nodeStyleValue = $getNodeStyleValueForProperty(node, styleProperty, defaultValue);
1065
-
1066
927
  if (styleValue === null) {
1067
928
  styleValue = nodeStyleValue;
1068
929
  } else if (styleValue !== nodeStyleValue) {
@@ -1073,10 +934,32 @@ function $getSelectionStyleValueForProperty(selection, styleProperty, defaultVal
1073
934
  }
1074
935
  }
1075
936
  }
1076
-
1077
937
  return styleValue === null ? defaultValue : styleValue;
1078
938
  }
1079
939
 
940
+ /**
941
+ * This function is for internal use of the library.
942
+ * Please do not use it as it may change in the future.
943
+ */
944
+ function INTERNAL_$isBlock(node) {
945
+ if (lexical.$isDecoratorNode(node) && !node.isInline()) {
946
+ return true;
947
+ }
948
+ if (!lexical.$isElementNode(node) || lexical.$isRootOrShadowRoot(node)) {
949
+ return false;
950
+ }
951
+ const firstChild = node.getFirstChild();
952
+ const isLeafElement = firstChild === null || lexical.$isLineBreakNode(firstChild) || lexical.$isTextNode(firstChild) || firstChild.isInline();
953
+ return !node.isInline() && node.canBeEmpty() !== false && isLeafElement;
954
+ }
955
+ function $getAncestor(node, predicate) {
956
+ let parent = node;
957
+ while (parent !== null && parent.getParent() !== null && !predicate(parent)) {
958
+ parent = parent.getParentOrThrow();
959
+ }
960
+ return predicate(parent) ? parent : null;
961
+ }
962
+
1080
963
  exports.$addNodeStyle = $addNodeStyle;
1081
964
  exports.$cloneWithProperties = $cloneWithProperties;
1082
965
  exports.$getSelectionStyleValueForProperty = $getSelectionStyleValueForProperty;
@@ -4,27 +4,27 @@
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 k=require("lexical");let u=new Map;function v(a){for(;null!=a;){if(a.nodeType===Node.TEXT_NODE)return a;a=a.firstChild}return null}function w(a){let b=a.parentNode;if(null==b)throw Error("Should never happen");return[b,Array.from(b.childNodes).indexOf(a)]}function y(a){let b={};a=a.split(";");for(let c of a)if(""!==c){let [e,d]=c.split(/:([^]+)/);b[e.trim()]=d.trim()}return b}function z(a){let b=u.get(a);void 0===b&&(b=y(a),u.set(a,b));return b}
8
- function A(a){let b="";for(let c in a)c&&(b+=`${c}: ${a[c]};`);return b}function B(a,b){var c=z("getStyle"in a?a.getStyle():a.style);b=Object.entries(b).reduce((e,[d,f])=>{null===f?delete e[d]:e[d]=f;return e},{...c});c=A(b);a.setStyle(c);u.set(c,b)}
9
- function C(a,b){var c=a.getNodes(),e=c.length;if(k.DEPRECATED_$isGridSelection(a)){var d=k.$createRangeSelection(),f=d.anchor,h=d.focus;for(var g=0;g<e;g++){var l=c[g];k.DEPRECATED_$isGridCellNode(l)&&(f.set(l.getKey(),0,"element"),h.set(l.getKey(),l.getChildrenSize(),"element"),C(k.$normalizeSelection__EXPERIMENTAL(d),b))}k.$setSelection(a)}else if(--e,d=c[0],f=c[e],a.isCollapsed())B(a,b);else{var m=a.anchor,p=a.focus;g=d.getTextContent().length;l=p.offset;var n=m.offset,r=m.isBefore(p);h=r?n:l;
10
- a=r?l:n;var q=r?m.type:p.type,t=r?p.type:m.type;m=r?p.key:m.key;k.$isTextNode(d)&&h===g&&(p=d.getNextSibling(),k.$isTextNode(p)&&(h=n=0,d=p));if(1===c.length)k.$isTextNode(d)&&(h="element"===q?0:n>l?l:n,a="element"===t?g:n>l?n:l,h!==a&&(0===h&&a===g?(B(d,b),d.select(h,a)):(c=d.splitText(h,a),c=0===h?c[0]:c[1],B(c,b),c.select(0,a-h))));else for(k.$isTextNode(d)&&h<d.getTextContentSize()&&(0!==h&&(d=d.splitText(h)[1]),B(d,b)),k.$isTextNode(f)&&(h=f.getTextContent().length,f.__key!==m&&0!==a&&(a=h),
11
- a!==h&&([f]=f.splitText(a)),0!==a&&B(f,b)),a=1;a<e;a++)h=c[a],g=h.getKey(),k.$isTextNode(h)&&g!==d.getKey()&&g!==f.getKey()&&!h.isToken()&&B(h,b)}}function D(a){for(;null!==a&&!k.$isRootOrShadowRoot(a);){let b=a.getLatest(),c=a.getParent();0===b.getChildrenSize()&&a.remove(!0);a=c}}
12
- function E(a,b,c,e,d=null){if(0!==b.length){var f=b[0],h=new Map,g=[];f=k.$isElementNode(f)?f:f.getParentOrThrow();f.isInline()&&(f=f.getParentOrThrow());for(var l=!1;null!==f;){var m=f.getPreviousSibling();if(null!==m){f=m;l=!0;break}f=f.getParentOrThrow();if(k.$isRootOrShadowRoot(f))break}m=new Set;for(var p=0;p<c;p++){var n=b[p];k.$isElementNode(n)&&0===n.getChildrenSize()&&m.add(n.getKey())}var r=new Set;for(p=0;p<c;p++){n=b[p];var q=n.getParent();null!==q&&q.isInline()&&(q=q.getParent());if(null!==
13
- q&&k.$isLeafNode(n)&&!r.has(n.getKey())){if(n=q.getKey(),void 0===h.get(n)){let t=e();t.setFormat(q.getFormatType());t.setIndent(q.getIndent());g.push(t);h.set(n,t);q.getChildren().forEach(x=>{t.append(x);r.add(x.getKey());k.$isElementNode(x)&&x.getChildrenKeys().forEach(H=>r.add(H))});D(q)}}else m.has(n.getKey())&&(q=e(),q.setFormat(n.getFormatType()),q.setIndent(n.getIndent()),g.push(q),n.remove(!0))}if(null!==d)for(b=0;b<g.length;b++)d.append(g[b]);b=null;if(k.$isRootOrShadowRoot(f))if(l)if(null!==
14
- d)f.insertAfter(d);else for(d=g.length-1;0<=d;d--)f.insertAfter(g[d]);else if(l=f.getFirstChild(),k.$isElementNode(l)&&(f=l),null===l)if(d)f.append(d);else for(d=0;d<g.length;d++)l=g[d],f.append(l),b=l;else if(null!==d)l.insertBefore(d);else for(f=0;f<g.length;f++)d=g[f],l.insertBefore(d),b=d;else if(d)f.insertAfter(d);else for(d=g.length-1;0<=d;d--)l=g[d],f.insertAfter(l),b=l;g=k.$getPreviousSelection();k.$isRangeSelection(g)&&g.anchor.getNode().isAttached()&&g.focus.getNode().isAttached()?k.$setSelection(g.clone()):
15
- null!==b?b.selectEnd():a.dirty=!0}}function F(a,b,c,e){a.modify(b?"extend":"move",c,e)}function G(a){a=a.anchor.getNode();return"rtl"===(k.$isRootNode(a)?a:a.getParentOrThrow()).getDirection()}exports.$addNodeStyle=function(a){a=a.getStyle();let b=y(a);u.set(a,b)};
16
- exports.$cloneWithProperties=function(a){let b=a.constructor.clone(a);b.__parent=a.__parent;b.__next=a.__next;b.__prev=a.__prev;if(k.$isElementNode(a)&&k.$isElementNode(b))return b.__first=a.__first,b.__last=a.__last,b.__size=a.__size,b.__format=a.__format,b.__indent=a.__indent,b.__dir=a.__dir,b;k.$isTextNode(a)&&k.$isTextNode(b)&&(b.__format=a.__format,b.__style=a.__style,b.__mode=a.__mode,b.__detail=a.__detail);return b};
17
- exports.$getSelectionStyleValueForProperty=function(a,b,c=""){let e=null,d=a.getNodes();var f=a.anchor,h=a.focus,g=a.isBackward();let l=g?h.offset:f.offset;f=g?h.getNode():f.getNode();if(""!==a.style&&(a=z(a.style),null!==a&&b in a))return a[b];for(a=0;a<d.length;a++){var m=d[a];if((0===a||0!==l||!m.is(f))&&k.$isTextNode(m))if(h=b,g=c,m=m.getStyle(),m=z(m),h=null!==m?m[h]||g:g,null===e)e=h;else if(e!==h){e="";break}}return null===e?c:e};
18
- exports.$isAtNodeEnd=function(a){return"text"===a.type?a.offset===a.getNode().getTextContentSize():a.offset===a.getNode().getChildrenSize()};exports.$isParentElementRTL=G;exports.$moveCaretSelection=F;exports.$moveCharacter=function(a,b,c){let e=G(a);F(a,b,c?!e:e,"character")};exports.$patchStyleText=C;
19
- exports.$selectAll=function(a){let b=a.anchor;a=a.focus;var c=b.getNode().getTopLevelElementOrThrow().getParentOrThrow();let e=c.getFirstDescendant();c=c.getLastDescendant();let d="element",f="element",h=0;k.$isTextNode(e)?d="text":k.$isElementNode(e)||null===e||(e=e.getParentOrThrow());k.$isTextNode(c)?(f="text",h=c.getTextContentSize()):k.$isElementNode(c)||null===c||(c=c.getParentOrThrow());e&&c&&(b.set(e.getKey(),0,d),a.set(c.getKey(),h,f))};
20
- exports.$setBlocksType=function(a,b){if("root"===a.anchor.key){b=b();var c=k.$getRoot();(a=c.getFirstChild())?a.replace(b,!0):c.append(b)}else for(c=a.getNodes(),a=a.anchor.getNode().getParentOrThrow(),-1===c.indexOf(a)&&c.push(a),a.isInline()&&(a=a.getParentOrThrow(),-1===c.indexOf(a)&&c.push(a)),a=0;a<c.length;a++){let f=c[a];var e=f;if(!k.$isElementNode(e)||k.$isRootOrShadowRoot(e))e=!1;else{var d=e.getFirstChild();d=null===d||k.$isLineBreakNode(d)||k.$isTextNode(d)||d.isInline();e=!e.isInline()&&
21
- !1!==e.canBeEmpty()&&d}e&&(e=b(),e.setFormat(f.getFormatType()),e.setIndent(f.getIndent()),f.replace(e,!0))}};exports.$shouldOverrideDefaultCharacterSelection=function(a,b){a=k.$getAdjacentNode(a.focus,b);return k.$isDecoratorNode(a)&&!a.isIsolated()||k.$isElementNode(a)&&!a.isInline()&&!a.canBeEmpty()};
22
- exports.$sliceSelectedTextNodeContent=function(a,b){if(b.isSelected()&&!b.isSegmented()&&!b.isToken()&&(k.$isRangeSelection(a)||k.DEPRECATED_$isGridSelection(a))){var c=a.anchor.getNode(),e=a.focus.getNode(),d=b.is(c),f=b.is(e);if(d||f){d=a.isBackward();let [h,g]=a.getCharacterOffsets();a=c.is(e);f=b.is(d?e:c);e=b.is(d?c:e);c=0;let l=void 0;a?(c=h>g?g:h,l=h>g?h:g):f?(c=d?g:h,l=void 0):e&&(d=d?h:g,c=0,l=d);b.__text=b.__text.slice(c,l)}}return b};
23
- exports.$wrapNodes=function(a,b,c=null){var e=a.getNodes();let d=e.length;var f=a.anchor;if(0===d||1===d&&"element"===f.type&&0===f.getNode().getChildrenSize()){a="text"===f.type?f.getNode().getParentOrThrow():f.getNode();e=a.getChildren();let g=b();g.setFormat(a.getFormatType());g.setIndent(a.getIndent());e.forEach(l=>g.append(l));c&&(g=c.append(g));a.replace(g)}else{f=null;var h=[];for(let g=0;g<d;g++){let l=e[g];k.$isRootOrShadowRoot(l)?(E(a,h,h.length,b,c),h=[],f=l):null===f||null!==f&&k.$hasAncestor(l,
24
- f)?h.push(l):(E(a,h,h.length,b,c),h=[l])}E(a,h,h.length,b,c)}};
25
- exports.createDOMRange=function(a,b,c,e,d){let f=b.getKey(),h=e.getKey(),g=document.createRange(),l=a.getElementByKey(f);a=a.getElementByKey(h);k.$isTextNode(b)&&(l=v(l));k.$isTextNode(e)&&(a=v(a));if(void 0===b||void 0===e||null===l||null===a)return null;"BR"===l.nodeName&&([l,c]=w(l));"BR"===a.nodeName&&([a,d]=w(a));b=l.firstChild;l===a&&null!=b&&"BR"===b.nodeName&&0===c&&0===d&&(d=1);try{g.setStart(l,c),g.setEnd(a,d)}catch(m){return null}!g.collapsed||c===d&&f===h||(g.setStart(a,d),g.setEnd(l,
26
- c));return g};exports.createRectsFromDOMRange=function(a,b){var c=a.getRootElement();if(null===c)return[];a=c.getBoundingClientRect();c=getComputedStyle(c);c=parseFloat(c.paddingLeft)+parseFloat(c.paddingRight);b=Array.from(b.getClientRects());let e=b.length;b.sort((f,h)=>{let g=f.top-h.top;return 3>=Math.abs(g)?f.left-h.left:g});let d;for(let f=0;f<e;f++){let h=b[f],g=h.width+c===a.width;d&&d.top<=h.top&&d.top+d.height>h.top&&d.left+d.width>h.left||g?(b.splice(f--,1),e--):d=h}return b};
7
+ 'use strict';var k=require("lexical");let u=new Map;function v(a){for(;null!=a;){if(a.nodeType===Node.TEXT_NODE)return a;a=a.firstChild}return null}function w(a){let b=a.parentNode;if(null==b)throw Error("Should never happen");return[b,Array.from(b.childNodes).indexOf(a)]}function y(a){let b={};a=a.split(";");for(let d of a)if(""!==d){let [f,c]=d.split(/:([^]+)/);b[f.trim()]=c.trim()}return b}function z(a){let b=u.get(a);void 0===b&&(b=y(a),u.set(a,b));return b}
8
+ function A(a){let b="";for(let d in a)d&&(b+=`${d}: ${a[d]};`);return b}function B(a,b){var d=z("getStyle"in a?a.getStyle():a.style);b=Object.entries(b).reduce((f,[c,g])=>{null===g?delete f[c]:f[c]=g;return f},{...d});d=A(b);a.setStyle(d);u.set(d,b)}
9
+ function C(a,b){var d=a.getNodes(),f=d.length;if(k.DEPRECATED_$isGridSelection(a)){var c=k.$createRangeSelection(),g=c.anchor,h=c.focus;for(var e=0;e<f;e++){var l=d[e];k.DEPRECATED_$isGridCellNode(l)&&(g.set(l.getKey(),0,"element"),h.set(l.getKey(),l.getChildrenSize(),"element"),C(k.$normalizeSelection__EXPERIMENTAL(c),b))}k.$setSelection(a)}else if(--f,c=d[0],g=d[f],a.isCollapsed())B(a,b);else{e=a.anchor;var m=a.focus;l=c.getTextContent().length;var p=m.offset,n=e.offset,r=e.isBefore(m);h=r?n:p;
10
+ a=r?p:n;var q=r?e.type:m.type,t=r?m.type:e.type;m=r?m.key:e.key;k.$isTextNode(c)&&h===l&&(r=c.getNextSibling(),k.$isTextNode(r)&&(h=n=0,c=r));if(1===d.length)k.$isTextNode(c)&&(h="element"===q?0:n>p?p:n,a="element"===t?l:n>p?n:p,h!==a&&(0===h&&a===l?(B(c,b),c.select(h,a)):(d=c.splitText(h,a),d=0===h?d[0]:d[1],B(d,b),d.select(0,a-h))));else for(k.$isTextNode(c)&&h<c.getTextContentSize()&&(0!==h&&(c=c.splitText(h)[1],h=0,e.set(c.getKey(),h,"text")),B(c,b)),k.$isTextNode(g)&&(h=g.getTextContent().length,
11
+ g.__key!==m&&0!==a&&(a=h),a!==h&&([g]=g.splitText(a)),0!==a&&B(g,b)),a=1;a<f;a++)h=d[a],e=h.getKey(),k.$isTextNode(h)&&e!==c.getKey()&&e!==g.getKey()&&!h.isToken()&&B(h,b)}}function D(a){for(;null!==a&&!k.$isRootOrShadowRoot(a);){let b=a.getLatest(),d=a.getParent();0===b.getChildrenSize()&&a.remove(!0);a=d}}
12
+ function E(a,b,d,f,c=null){if(0!==b.length){var g=b[0],h=new Map,e=[];g=k.$isElementNode(g)?g:g.getParentOrThrow();g.isInline()&&(g=g.getParentOrThrow());for(var l=!1;null!==g;){var m=g.getPreviousSibling();if(null!==m){g=m;l=!0;break}g=g.getParentOrThrow();if(k.$isRootOrShadowRoot(g))break}m=new Set;for(var p=0;p<d;p++){var n=b[p];k.$isElementNode(n)&&0===n.getChildrenSize()&&m.add(n.getKey())}var r=new Set;for(p=0;p<d;p++){n=b[p];var q=n.getParent();null!==q&&q.isInline()&&(q=q.getParent());if(null!==
13
+ q&&k.$isLeafNode(n)&&!r.has(n.getKey())){if(n=q.getKey(),void 0===h.get(n)){let t=f();t.setFormat(q.getFormatType());t.setIndent(q.getIndent());e.push(t);h.set(n,t);q.getChildren().forEach(x=>{t.append(x);r.add(x.getKey());k.$isElementNode(x)&&x.getChildrenKeys().forEach(I=>r.add(I))});D(q)}}else m.has(n.getKey())&&(q=f(),q.setFormat(n.getFormatType()),q.setIndent(n.getIndent()),e.push(q),n.remove(!0))}if(null!==c)for(b=0;b<e.length;b++)c.append(e[b]);b=null;if(k.$isRootOrShadowRoot(g))if(l)if(null!==
14
+ c)g.insertAfter(c);else for(c=e.length-1;0<=c;c--)g.insertAfter(e[c]);else if(l=g.getFirstChild(),k.$isElementNode(l)&&(g=l),null===l)if(c)g.append(c);else for(c=0;c<e.length;c++)l=e[c],g.append(l),b=l;else if(null!==c)l.insertBefore(c);else for(g=0;g<e.length;g++)c=e[g],l.insertBefore(c),b=c;else if(c)g.insertAfter(c);else for(c=e.length-1;0<=c;c--)l=e[c],g.insertAfter(l),b=l;e=k.$getPreviousSelection();k.$isRangeSelection(e)&&e.anchor.getNode().isAttached()&&e.focus.getNode().isAttached()?k.$setSelection(e.clone()):
15
+ null!==b?b.selectEnd():a.dirty=!0}}function F(a,b,d,f){a.modify(b?"extend":"move",d,f)}function G(a){a=a.anchor.getNode();return"rtl"===(k.$isRootNode(a)?a:a.getParentOrThrow()).getDirection()}function H(a){if(k.$isDecoratorNode(a)&&!a.isInline())return!0;if(!k.$isElementNode(a)||k.$isRootOrShadowRoot(a))return!1;var b=a.getFirstChild();b=null===b||k.$isLineBreakNode(b)||k.$isTextNode(b)||b.isInline();return!a.isInline()&&!1!==a.canBeEmpty()&&b}
16
+ exports.$addNodeStyle=function(a){a=a.getStyle();let b=y(a);u.set(a,b)};exports.$cloneWithProperties=function(a){let b=a.constructor.clone(a);b.__parent=a.__parent;b.__next=a.__next;b.__prev=a.__prev;if(k.$isElementNode(a)&&k.$isElementNode(b))return b.__first=a.__first,b.__last=a.__last,b.__size=a.__size,b.__format=a.__format,b.__indent=a.__indent,b.__dir=a.__dir,b;k.$isTextNode(a)&&k.$isTextNode(b)&&(b.__format=a.__format,b.__style=a.__style,b.__mode=a.__mode,b.__detail=a.__detail);return b};
17
+ exports.$getSelectionStyleValueForProperty=function(a,b,d=""){let f=null,c=a.getNodes();var g=a.anchor,h=a.focus,e=a.isBackward();let l=e?h.offset:g.offset;g=e?h.getNode():g.getNode();if(a.isCollapsed()&&""!==a.style&&(a=z(a.style),null!==a&&b in a))return a[b];for(a=0;a<c.length;a++){var m=c[a];if((0===a||0!==l||!m.is(g))&&k.$isTextNode(m))if(h=b,e=d,m=m.getStyle(),m=z(m),h=null!==m?m[h]||e:e,null===f)f=h;else if(f!==h){f="";break}}return null===f?d:f};
18
+ exports.$isAtNodeEnd=function(a){return"text"===a.type?a.offset===a.getNode().getTextContentSize():a.offset===a.getNode().getChildrenSize()};exports.$isParentElementRTL=G;exports.$moveCaretSelection=F;exports.$moveCharacter=function(a,b,d){let f=G(a);F(a,b,d?!f:f,"character")};exports.$patchStyleText=C;
19
+ exports.$selectAll=function(a){let b=a.anchor;a=a.focus;var d=b.getNode().getTopLevelElementOrThrow().getParentOrThrow();let f=d.getFirstDescendant();d=d.getLastDescendant();let c="element",g="element",h=0;k.$isTextNode(f)?c="text":k.$isElementNode(f)||null===f||(f=f.getParentOrThrow());k.$isTextNode(d)?(g="text",h=d.getTextContentSize()):k.$isElementNode(d)||null===d||(d=d.getParentOrThrow());f&&d&&(b.set(f.getKey(),0,c),a.set(d.getKey(),h,g))};
20
+ exports.$setBlocksType=function(a,b){if("root"===a.anchor.key){b=b();var d=k.$getRoot();(a=d.getFirstChild())?a.replace(b,!0):d.append(b)}else{d=a.getNodes();for(a=a.anchor.getNode();null!==a&&null!==a.getParent()&&!H(a);)a=a.getParentOrThrow();(a=H(a)?a:null)&&-1===d.indexOf(a)&&d.push(a);for(a=0;a<d.length;a++){let f=d[a];if(!H(f))continue;let c=b();c.setFormat(f.getFormatType());c.setIndent(f.getIndent());f.replace(c,!0)}}};
21
+ exports.$shouldOverrideDefaultCharacterSelection=function(a,b){a=k.$getAdjacentNode(a.focus,b);return k.$isDecoratorNode(a)&&!a.isIsolated()||k.$isElementNode(a)&&!a.isInline()&&!a.canBeEmpty()};
22
+ exports.$sliceSelectedTextNodeContent=function(a,b){if(b.isSelected()&&!b.isSegmented()&&!b.isToken()&&(k.$isRangeSelection(a)||k.DEPRECATED_$isGridSelection(a))){var d=a.anchor.getNode(),f=a.focus.getNode(),c=b.is(d),g=b.is(f);if(c||g){c=a.isBackward();let [h,e]=a.getCharacterOffsets();a=d.is(f);g=b.is(c?f:d);f=b.is(c?d:f);d=0;let l=void 0;a?(d=h>e?e:h,l=h>e?h:e):g?(d=c?e:h,l=void 0):f&&(c=c?h:e,d=0,l=c);b.__text=b.__text.slice(d,l)}}return b};
23
+ exports.$wrapNodes=function(a,b,d=null){var f=a.getNodes();let c=f.length;var g=a.anchor;if(0===c||1===c&&"element"===g.type&&0===g.getNode().getChildrenSize()){a="text"===g.type?g.getNode().getParentOrThrow():g.getNode();f=a.getChildren();let e=b();e.setFormat(a.getFormatType());e.setIndent(a.getIndent());f.forEach(l=>e.append(l));d&&(e=d.append(e));a.replace(e)}else{g=null;var h=[];for(let e=0;e<c;e++){let l=f[e];k.$isRootOrShadowRoot(l)?(E(a,h,h.length,b,d),h=[],g=l):null===g||null!==g&&k.$hasAncestor(l,
24
+ g)?h.push(l):(E(a,h,h.length,b,d),h=[l])}E(a,h,h.length,b,d)}};
25
+ exports.createDOMRange=function(a,b,d,f,c){let g=b.getKey(),h=f.getKey(),e=document.createRange(),l=a.getElementByKey(g);a=a.getElementByKey(h);k.$isTextNode(b)&&(l=v(l));k.$isTextNode(f)&&(a=v(a));if(void 0===b||void 0===f||null===l||null===a)return null;"BR"===l.nodeName&&([l,d]=w(l));"BR"===a.nodeName&&([a,c]=w(a));b=l.firstChild;l===a&&null!=b&&"BR"===b.nodeName&&0===d&&0===c&&(c=1);try{e.setStart(l,d),e.setEnd(a,c)}catch(m){return null}!e.collapsed||d===c&&g===h||(e.setStart(a,c),e.setEnd(l,
26
+ d));return e};exports.createRectsFromDOMRange=function(a,b){var d=a.getRootElement();if(null===d)return[];a=d.getBoundingClientRect();d=getComputedStyle(d);d=parseFloat(d.paddingLeft)+parseFloat(d.paddingRight);b=Array.from(b.getClientRects());let f=b.length;b.sort((g,h)=>{let e=g.top-h.top;return 3>=Math.abs(e)?g.left-h.left:e});let c;for(let g=0;g<f;g++){let h=b[g],e=h.width+d===a.width;c&&c.top<=h.top&&c.top+c.height>h.top&&c.left+c.width>h.left||e?(b.splice(g--,1),f--):c=h}return b};
27
27
  exports.getStyleObjectFromCSS=z;
28
- exports.trimTextContentFromAnchor=function(a,b,c){let e=b.getNode();if(k.$isElementNode(e)){var d=e.getDescendantByIndex(b.offset);null!==d&&(e=d)}for(;0<c&&null!==e;){var f=e.getPreviousSibling(),h=0;if(null===f){d=e.getParentOrThrow();for(var g=d.getPreviousSibling();null===g;){d=d.getParent();if(null===d){f=null;break}g=d.getPreviousSibling()}null!==d&&(h=d.isInline()?0:2,f=k.$isElementNode(g)?g.getLastDescendant():g)}g=e.getTextContent();""===g&&k.$isElementNode(e)&&!e.isInline()&&(g="\n\n");
29
- d=g.length;if(!k.$isTextNode(e)||c>=d)g=e.getParent(),e.remove(),null==g||0!==g.getChildrenSize()||k.$isRootNode(g)||g.remove(),c-=d+h,e=f;else{let l=e.getKey();h=a.getEditorState().read(()=>{const p=k.$getNodeByKey(l);return k.$isTextNode(p)&&p.isSimpleText()?p.getTextContent():null});f=d-c;let m=g.slice(0,f);null!==h&&h!==g?(c=k.$getPreviousSelection(),d=e,e.isSimpleText()?e.setTextContent(h):(d=k.$createTextNode(h),e.replace(d)),k.$isRangeSelection(c)&&c.isCollapsed()&&(c=c.anchor.offset,d.select(c,
30
- c))):e.isSimpleText()?(h=b.key===l,g=b.offset,g<c&&(g=d),c=h?g-c:0,d=h?g:f,h&&0===c?([c]=e.splitText(c,d),c.remove()):([,c]=e.splitText(c,d),c.remove())):(c=k.$createTextNode(m),e.replace(c));c=0}}}
28
+ exports.trimTextContentFromAnchor=function(a,b,d){let f=b.getNode();if(k.$isElementNode(f)){var c=f.getDescendantByIndex(b.offset);null!==c&&(f=c)}for(;0<d&&null!==f;){k.$isElementNode(f)&&(c=f.getLastDescendant(),null!==c&&(f=c));var g=f.getPreviousSibling(),h=0;if(null===g){c=f.getParentOrThrow();for(var e=c.getPreviousSibling();null===e;){c=c.getParent();if(null===c){g=null;break}e=c.getPreviousSibling()}null!==c&&(h=c.isInline()?0:2,g=e)}e=f.getTextContent();""===e&&k.$isElementNode(f)&&!f.isInline()&&
29
+ (e="\n\n");c=e.length;if(!k.$isTextNode(f)||d>=c)e=f.getParent(),f.remove(),null==e||0!==e.getChildrenSize()||k.$isRootNode(e)||e.remove(),d-=c+h,f=g;else{let l=f.getKey();h=a.getEditorState().read(()=>{const p=k.$getNodeByKey(l);return k.$isTextNode(p)&&p.isSimpleText()?p.getTextContent():null});g=c-d;let m=e.slice(0,g);null!==h&&h!==e?(d=k.$getPreviousSelection(),c=f,f.isSimpleText()?f.setTextContent(h):(c=k.$createTextNode(h),f.replace(c)),k.$isRangeSelection(d)&&d.isCollapsed()&&(d=d.anchor.offset,
30
+ c.select(d,d))):f.isSimpleText()?(h=b.key===l,e=b.offset,e<d&&(e=c),d=h?e-d:0,c=h?e:g,h&&0===d?([d]=f.splitText(d,c),d.remove()):([,d]=f.splitText(d,c),d.remove())):(d=k.$createTextNode(m),f.replace(d));d=0}}}
package/package.json CHANGED
@@ -9,10 +9,10 @@
9
9
  "selection"
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "0.12.2",
12
+ "version": "0.12.4",
13
13
  "main": "LexicalSelection.js",
14
14
  "peerDependencies": {
15
- "lexical": "0.12.2"
15
+ "lexical": "0.12.4"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import type { ElementNode, GridSelection, LexicalNode, RangeSelection } from 'lexical';
8
+ import type { DecoratorNode, ElementNode, GridSelection, LexicalNode, RangeSelection } from 'lexical';
9
9
  /**
10
10
  * Converts all nodes in the selection that are of one block type to another.
11
11
  * @param selection - The selected blocks to be converted.
@@ -72,3 +72,9 @@ export declare function $selectAll(selection: RangeSelection): void;
72
72
  * @returns The value of the property for the selected TextNodes.
73
73
  */
74
74
  export declare function $getSelectionStyleValueForProperty(selection: RangeSelection, styleProperty: string, defaultValue?: string): string;
75
+ /**
76
+ * This function is for internal use of the library.
77
+ * Please do not use it as it may change in the future.
78
+ */
79
+ export declare function INTERNAL_$isBlock(node: LexicalNode): node is ElementNode | DecoratorNode<unknown>;
80
+ export declare function $getAncestor<NodeType extends LexicalNode = LexicalNode>(node: LexicalNode, predicate: (ancestor: LexicalNode) => ancestor is NodeType): NodeType | null;