@lexical/selection 0.12.5 → 0.13.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.
@@ -240,14 +240,16 @@ function $cloneWithProperties(node) {
240
240
  * @returns The updated TextNode.
241
241
  */
242
242
  function $sliceSelectedTextNodeContent(selection, textNode) {
243
- if (textNode.isSelected() && !textNode.isSegmented() && !textNode.isToken() && lexical.$INTERNAL_isPointSelection(selection)) {
244
- const anchorNode = selection.anchor.getNode();
245
- const focusNode = selection.focus.getNode();
243
+ const anchorAndFocus = selection.getStartEndPoints();
244
+ if (textNode.isSelected(selection) && !textNode.isSegmented() && !textNode.isToken() && anchorAndFocus !== null) {
245
+ const [anchor, focus] = anchorAndFocus;
246
+ const isBackward = selection.isBackward();
247
+ const anchorNode = anchor.getNode();
248
+ const focusNode = focus.getNode();
246
249
  const isAnchor = textNode.is(anchorNode);
247
250
  const isFocus = textNode.is(focusNode);
248
251
  if (isAnchor || isFocus) {
249
- const isBackward = selection.isBackward();
250
- const [anchorOffset, focusOffset] = selection.getCharacterOffsets();
252
+ const [anchorOffset, focusOffset] = lexical.$getCharacterOffsets(selection);
251
253
  const isSame = anchorNode.is(focusNode);
252
254
  const isFirst = textNode.is(isBackward ? focusNode : anchorNode);
253
255
  const isLast = textNode.is(isBackward ? anchorNode : focusNode);
@@ -281,7 +283,11 @@ function $isAtNodeEnd(point) {
281
283
  if (point.type === 'text') {
282
284
  return point.offset === point.getNode().getTextContentSize();
283
285
  }
284
- return point.offset === point.getNode().getChildrenSize();
286
+ const node = point.getNode();
287
+ if (!lexical.$isElementNode(node)) {
288
+ throw Error(`isAtNodeEnd: node must be a TextNode or ElementNode`);
289
+ }
290
+ return point.offset === node.getChildrenSize();
285
291
  }
286
292
 
287
293
  /**
@@ -408,7 +414,9 @@ function $addNodeStyle(node) {
408
414
  function $patchStyle(target, patch) {
409
415
  const prevStyles = getStyleObjectFromCSS('getStyle' in target ? target.getStyle() : target.style);
410
416
  const newStyles = Object.entries(patch).reduce((styles, [key, value]) => {
411
- if (value === null) {
417
+ if (value instanceof Function) {
418
+ styles[key] = value(prevStyles[key]);
419
+ } else if (value === null) {
412
420
  delete styles[key];
413
421
  } else {
414
422
  styles[key] = value;
@@ -427,26 +435,16 @@ function $patchStyle(target, patch) {
427
435
  * Will update partially selected TextNodes by splitting the TextNode and applying
428
436
  * the styles to the appropriate one.
429
437
  * @param selection - The selected node(s) to update.
430
- * @param patch - The patch to apply, which can include multiple styles. { CSSProperty: value }
438
+ * @param patch - The patch to apply, which can include multiple styles. { CSSProperty: value }. Can also accept a function that returns the new property value.
431
439
  */
432
440
  function $patchStyleText(selection, patch) {
433
441
  const selectedNodes = selection.getNodes();
434
442
  const selectedNodesLength = selectedNodes.length;
435
- if (lexical.DEPRECATED_$isGridSelection(selection)) {
436
- const cellSelection = lexical.$createRangeSelection();
437
- const cellSelectionAnchor = cellSelection.anchor;
438
- const cellSelectionFocus = cellSelection.focus;
439
- for (let i = 0; i < selectedNodesLength; i++) {
440
- const node = selectedNodes[i];
441
- if (lexical.DEPRECATED_$isGridCellNode(node)) {
442
- cellSelectionAnchor.set(node.getKey(), 0, 'element');
443
- cellSelectionFocus.set(node.getKey(), node.getChildrenSize(), 'element');
444
- $patchStyleText(lexical.$normalizeSelection__EXPERIMENTAL(cellSelection), patch);
445
- }
446
- }
447
- lexical.$setSelection(selection);
443
+ const anchorAndFocus = selection.getStartEndPoints();
444
+ if (anchorAndFocus === null) {
448
445
  return;
449
446
  }
447
+ const [anchor, focus] = anchorAndFocus;
450
448
  const lastIndex = selectedNodesLength - 1;
451
449
  let firstNode = selectedNodes[0];
452
450
  let lastNode = selectedNodes[lastIndex];
@@ -454,8 +452,6 @@ function $patchStyleText(selection, patch) {
454
452
  $patchStyle(selection, patch);
455
453
  return;
456
454
  }
457
- const anchor = selection.anchor;
458
- const focus = selection.focus;
459
455
  const firstNodeText = firstNode.getTextContent();
460
456
  const firstNodeTextLength = firstNodeText.length;
461
457
  const focusOffset = focus.offset;
@@ -481,7 +477,7 @@ function $patchStyleText(selection, patch) {
481
477
 
482
478
  // This is the case where we only selected a single node
483
479
  if (selectedNodes.length === 1) {
484
- if (lexical.$isTextNode(firstNode)) {
480
+ if (lexical.$isTextNode(firstNode) && firstNode.canHaveFormat()) {
485
481
  startOffset = startType === 'element' ? 0 : anchorOffset > focusOffset ? focusOffset : anchorOffset;
486
482
  endOffset = endType === 'element' ? firstNodeTextLength : anchorOffset > focusOffset ? anchorOffset : focusOffset;
487
483
 
@@ -504,7 +500,7 @@ function $patchStyleText(selection, patch) {
504
500
  }
505
501
  } // multiple nodes selected.
506
502
  } else {
507
- if (lexical.$isTextNode(firstNode) && startOffset < firstNode.getTextContentSize()) {
503
+ if (lexical.$isTextNode(firstNode) && startOffset < firstNode.getTextContentSize() && firstNode.canHaveFormat()) {
508
504
  if (startOffset !== 0) {
509
505
  // the entire first node isn't selected, so split it
510
506
  firstNode = firstNode.splitText(startOffset)[1];
@@ -513,7 +509,7 @@ function $patchStyleText(selection, patch) {
513
509
  }
514
510
  $patchStyle(firstNode, patch);
515
511
  }
516
- if (lexical.$isTextNode(lastNode)) {
512
+ if (lexical.$isTextNode(lastNode) && lastNode.canHaveFormat()) {
517
513
  const lastNodeText = lastNode.getTextContent();
518
514
  const lastNodeTextLength = lastNodeText.length;
519
515
 
@@ -529,7 +525,7 @@ function $patchStyleText(selection, patch) {
529
525
  if (endOffset !== lastNodeTextLength) {
530
526
  [lastNode] = lastNode.splitText(endOffset);
531
527
  }
532
- if (endOffset !== 0) {
528
+ if (endOffset !== 0 || endType === 'element') {
533
529
  $patchStyle(lastNode, patch);
534
530
  }
535
531
  }
@@ -538,7 +534,7 @@ function $patchStyleText(selection, patch) {
538
534
  for (let i = 1; i < lastIndex; i++) {
539
535
  const selectedNode = selectedNodes[i];
540
536
  const selectedNodeKey = selectedNode.getKey();
541
- if (lexical.$isTextNode(selectedNode) && selectedNodeKey !== firstNode.getKey() && selectedNodeKey !== lastNode.getKey() && !selectedNode.isToken()) {
537
+ if (lexical.$isTextNode(selectedNode) && selectedNode.canHaveFormat() && selectedNodeKey !== firstNode.getKey() && selectedNodeKey !== lastNode.getKey() && !selectedNode.isToken()) {
542
538
  $patchStyle(selectedNode, patch);
543
539
  }
544
540
  }
@@ -559,7 +555,12 @@ function $patchStyleText(selection, patch) {
559
555
  * @param createElement - The function that creates the node. eg. $createParagraphNode.
560
556
  */
561
557
  function $setBlocksType(selection, createElement) {
562
- if (selection.anchor.key === 'root') {
558
+ if (selection === null) {
559
+ return;
560
+ }
561
+ const anchorAndFocus = selection.getStartEndPoints();
562
+ const anchor = anchorAndFocus ? anchorAndFocus[0] : null;
563
+ if (anchor !== null && anchor.key === 'root') {
563
564
  const element = createElement();
564
565
  const root = lexical.$getRoot();
565
566
  const firstChild = root.getFirstChild();
@@ -571,7 +572,7 @@ function $setBlocksType(selection, createElement) {
571
572
  return;
572
573
  }
573
574
  const nodes = selection.getNodes();
574
- const firstSelectedBlock = $getAncestor(selection.anchor.getNode(), INTERNAL_$isBlock);
575
+ const firstSelectedBlock = anchor !== null ? $getAncestor(anchor.getNode(), INTERNAL_$isBlock) : false;
575
576
  if (firstSelectedBlock && nodes.indexOf(firstSelectedBlock) === -1) {
576
577
  nodes.push(firstSelectedBlock);
577
578
  }
@@ -580,6 +581,9 @@ function $setBlocksType(selection, createElement) {
580
581
  if (!INTERNAL_$isBlock(node)) {
581
582
  continue;
582
583
  }
584
+ if (!lexical.$isElementNode(node)) {
585
+ throw Error(`Expected block node to be an ElementNode`);
586
+ }
583
587
  const targetElement = createElement();
584
588
  targetElement.setFormat(node.getFormatType());
585
589
  targetElement.setIndent(node.getIndent());
@@ -609,10 +613,11 @@ function $removeParentEmptyElements(startingNode) {
609
613
  * @param wrappingElement - An element to append the wrapped selection and its children to.
610
614
  */
611
615
  function $wrapNodes(selection, createElement, wrappingElement = null) {
616
+ const anchorAndFocus = selection.getStartEndPoints();
617
+ const anchor = anchorAndFocus ? anchorAndFocus[0] : null;
612
618
  const nodes = selection.getNodes();
613
619
  const nodesLength = nodes.length;
614
- const anchor = selection.anchor;
615
- if (nodesLength === 0 || nodesLength === 1 && anchor.type === 'element' && anchor.getNode().getChildrenSize() === 0) {
620
+ if (anchor !== null && (nodesLength === 0 || nodesLength === 1 && anchor.type === 'element' && anchor.getNode().getChildrenSize() === 0)) {
616
621
  const target = anchor.type === 'text' ? anchor.getNode().getParentOrThrow() : anchor.getNode();
617
622
  const children = target.getChildren();
618
623
  let element = createElement();
@@ -725,6 +730,9 @@ function $wrapNodesImpl(selection, nodes, nodesLength, createElement, wrappingEl
725
730
  $removeParentEmptyElements(parent);
726
731
  }
727
732
  } else if (emptyElements.has(node.getKey())) {
733
+ if (!lexical.$isElementNode(node)) {
734
+ throw Error(`Expected node in emptyElements to be an ElementNode`);
735
+ }
728
736
  const targetElement = createElement();
729
737
  targetElement.setFormat(node.getFormatType());
730
738
  targetElement.setIndent(node.getIndent());
@@ -944,8 +952,8 @@ function $getSelectionStyleValueForProperty(selection, styleProperty, defaultVal
944
952
  * Please do not use it as it may change in the future.
945
953
  */
946
954
  function INTERNAL_$isBlock(node) {
947
- if (lexical.$isDecoratorNode(node) && !node.isInline()) {
948
- return true;
955
+ if (lexical.$isDecoratorNode(node)) {
956
+ return false;
949
957
  }
950
958
  if (!lexical.$isElementNode(node) || lexical.$isRootOrShadowRoot(node)) {
951
959
  return false;
@@ -11,9 +11,9 @@ import type {
11
11
  LexicalEditor,
12
12
  LexicalNode,
13
13
  NodeKey,
14
+ BaseSelection,
14
15
  NodeSelection,
15
16
  Point,
16
- INTERNAL_PointSelection,
17
17
  RangeSelection,
18
18
  } from 'lexical';
19
19
  declare export function $cloneWithProperties<T: LexicalNode>(node: T): T;
@@ -21,7 +21,7 @@ declare export function getStyleObjectFromCSS(css: string): {
21
21
  [string]: string,
22
22
  };
23
23
  declare export function $patchStyleText(
24
- selection: INTERNAL_PointSelection,
24
+ selection: BaseSelection,
25
25
  patch: {
26
26
  [string]: string | null,
27
27
  },
@@ -45,7 +45,7 @@ declare export function $moveCharacter(
45
45
  ): void;
46
46
  declare export function $selectAll(selection: RangeSelection): void;
47
47
  declare export function $wrapNodes(
48
- selection: INTERNAL_PointSelection,
48
+ selection: BaseSelection,
49
49
  createElement: () => ElementNode,
50
50
  wrappingElement?: ElementNode,
51
51
  ): void;
@@ -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 d of a)if(""!==d){let [f,c]=d.split(/:([^]+)/);f&&c&&(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()&&k.$isRangeSelection(a))B(a,b);else{e=a.anchor;var m=a.focus;l=c.getTextContent().length;var p=m.offset,n=e.offset,
10
- r=e.isBefore(m);h=r?n:p;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)&&
11
- (h=g.getTextContent().length,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.$INTERNAL_isPointSelection(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};
7
+ 'use strict';var k=require("lexical");let v=new Map;function w(a){for(;null!=a;){if(a.nodeType===Node.TEXT_NODE)return a;a=a.firstChild}return null}function x(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(/:([^]+)/);e&&d&&(b[e.trim()]=d.trim())}return b}function z(a){let b=v.get(a);void 0===b&&(b=y(a),v.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){let c=z("getStyle"in a?a.getStyle():a.style);b=Object.entries(b).reduce((d,[g,h])=>{h instanceof Function?d[g]=h(c[g]):null===h?delete d[g]:d[g]=h;return d},{...c});let e=A(b);a.setStyle(e);v.set(e,b)}function C(a){for(;null!==a&&!k.$isRootOrShadowRoot(a);){let b=a.getLatest(),c=a.getParent();0===b.getChildrenSize()&&a.remove(!0);a=c}}
9
+ function D(a,b,c,e,d=null){if(0!==b.length){var g=b[0],h=new Map,f=[];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<c;p++){var q=b[p];k.$isElementNode(q)&&0===q.getChildrenSize()&&m.add(q.getKey())}var n=new Set;for(p=0;p<c;p++){q=b[p];var r=q.getParent();null!==r&&r.isInline()&&(r=r.getParent());if(null!==
10
+ r&&k.$isLeafNode(q)&&!n.has(q.getKey())){if(q=r.getKey(),void 0===h.get(q)){let t=e();t.setFormat(r.getFormatType());t.setIndent(r.getIndent());f.push(t);h.set(q,t);r.getChildren().forEach(u=>{t.append(u);n.add(u.getKey());k.$isElementNode(u)&&u.getChildrenKeys().forEach(H=>n.add(H))});C(r)}}else if(m.has(q.getKey())){if(!k.$isElementNode(q))throw Error("Expected node in emptyElements to be an ElementNode");r=e();r.setFormat(q.getFormatType());r.setIndent(q.getIndent());f.push(r);q.remove(!0)}}if(null!==
11
+ d)for(b=0;b<f.length;b++)d.append(f[b]);b=null;if(k.$isRootOrShadowRoot(g))if(l)if(null!==d)g.insertAfter(d);else for(d=f.length-1;0<=d;d--)g.insertAfter(f[d]);else if(l=g.getFirstChild(),k.$isElementNode(l)&&(g=l),null===l)if(d)g.append(d);else for(d=0;d<f.length;d++)l=f[d],g.append(l),b=l;else if(null!==d)l.insertBefore(d);else for(g=0;g<f.length;g++)d=f[g],l.insertBefore(d),b=d;else if(d)g.insertAfter(d);else for(d=f.length-1;0<=d;d--)l=f[d],g.insertAfter(l),b=l;f=k.$getPreviousSelection();k.$isRangeSelection(f)&&
12
+ f.anchor.getNode().isAttached()&&f.focus.getNode().isAttached()?k.$setSelection(f.clone()):null!==b?b.selectEnd():a.dirty=!0}}function E(a,b,c,e){a.modify(b?"extend":"move",c,e)}function F(a){a=a.anchor.getNode();return"rtl"===(k.$isRootNode(a)?a:a.getParentOrThrow()).getDirection()}
13
+ function G(a){if(k.$isDecoratorNode(a)||!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}exports.$addNodeStyle=function(a){a=a.getStyle();let b=y(a);v.set(a,b)};
14
+ 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};
15
+ exports.$getSelectionStyleValueForProperty=function(a,b,c=""){let e=null,d=a.getNodes();var g=a.anchor,h=a.focus,f=a.isBackward();let l=f?h.offset:g.offset;g=f?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<d.length;a++){var m=d[a];if((0===a||0!==l||!m.is(g))&&k.$isTextNode(m))if(h=b,f=c,m=m.getStyle(),m=z(m),h=null!==m?m[h]||f:f,null===e)e=h;else if(e!==h){e="";break}}return null===e?c:e};
16
+ exports.$isAtNodeEnd=function(a){if("text"===a.type)return a.offset===a.getNode().getTextContentSize();let b=a.getNode();if(!k.$isElementNode(b))throw Error("isAtNodeEnd: node must be a TextNode or ElementNode");return a.offset===b.getChildrenSize()};exports.$isParentElementRTL=F;exports.$moveCaretSelection=E;exports.$moveCharacter=function(a,b,c){let e=F(a);E(a,b,c?!e:e,"character")};
17
+ exports.$patchStyleText=function(a,b){var c=a.getNodes(),e=c.length,d=a.getStartEndPoints();if(null!==d){var [g,h]=d;--e;d=c[0];var f=c[e];if(a.isCollapsed()&&k.$isRangeSelection(a))B(a,b);else{var l=d.getTextContent().length,m=h.offset,p=g.offset,q=g.isBefore(h),n=q?p:m;a=q?m:p;var r=q?g.type:h.type,t=q?h.type:g.type;q=q?h.key:g.key;if(k.$isTextNode(d)&&n===l){let u=d.getNextSibling();k.$isTextNode(u)&&(n=p=0,d=u)}if(1===c.length)k.$isTextNode(d)&&d.canHaveFormat()&&(n="element"===r?0:p>m?m:p,a=
18
+ "element"===t?l:p>m?p:m,n!==a&&(0===n&&a===l?(B(d,b),d.select(n,a)):(c=d.splitText(n,a),c=0===n?c[0]:c[1],B(c,b),c.select(0,a-n))));else for(k.$isTextNode(d)&&n<d.getTextContentSize()&&d.canHaveFormat()&&(0!==n&&(d=d.splitText(n)[1],n=0,g.set(d.getKey(),n,"text")),B(d,b)),k.$isTextNode(f)&&f.canHaveFormat()&&(n=f.getTextContent().length,f.__key!==q&&0!==a&&(a=n),a!==n&&([f]=f.splitText(a)),0===a&&"element"!==t||B(f,b)),a=1;a<e;a++)n=c[a],t=n.getKey(),k.$isTextNode(n)&&n.canHaveFormat()&&t!==d.getKey()&&
19
+ t!==f.getKey()&&!n.isToken()&&B(n,b)}}};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",g="element",h=0;k.$isTextNode(e)?d="text":k.$isElementNode(e)||null===e||(e=e.getParentOrThrow());k.$isTextNode(c)?(g="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,g))};
20
+ exports.$setBlocksType=function(a,b){if(null!==a){var c=a.getStartEndPoints();c=c?c[0]:null;if(null!==c&&"root"===c.key)b=b(),a=k.$getRoot(),(c=a.getFirstChild())?c.replace(b,!0):a.append(b);else{a=a.getNodes();if(null!==c){for(c=c.getNode();null!==c&&null!==c.getParent()&&!G(c);)c=c.getParentOrThrow();c=G(c)?c:null}else c=!1;c&&-1===a.indexOf(c)&&a.push(c);for(c=0;c<a.length;c++){let e=a[c];if(!G(e))continue;if(!k.$isElementNode(e))throw Error("Expected block node to be an ElementNode");let d=b();
21
+ d.setFormat(e.getFormatType());d.setIndent(e.getIndent());e.replace(d,!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){var c=a.getStartEndPoints();if(b.isSelected(a)&&!b.isSegmented()&&!b.isToken()&&null!==c){let [f,l]=c;c=a.isBackward();var e=f.getNode(),d=l.getNode(),g=b.is(e),h=b.is(d);if(g||h){let [m,p]=k.$getCharacterOffsets(a);a=e.is(d);g=b.is(c?d:e);d=b.is(c?e:d);e=0;h=void 0;a?(e=m>p?p:m,h=m>p?m:p):g?(e=c?p:m,h=void 0):d&&(c=c?m:p,e=0,h=c);b.__text=b.__text.slice(e,h)}}return b};
23
+ exports.$wrapNodes=function(a,b,c=null){var e=a.getStartEndPoints(),d=e?e[0]:null;e=a.getNodes();let g=e.length;if(null!==d&&(0===g||1===g&&"element"===d.type&&0===d.getNode().getChildrenSize())){a="text"===d.type?d.getNode().getParentOrThrow():d.getNode();e=a.getChildren();let f=b();f.setFormat(a.getFormatType());f.setIndent(a.getIndent());e.forEach(l=>f.append(l));c&&(f=c.append(f));a.replace(f)}else{d=null;var h=[];for(let f=0;f<g;f++){let l=e[f];k.$isRootOrShadowRoot(l)?(D(a,h,h.length,b,c),h=
24
+ [],d=l):null===d||null!==d&&k.$hasAncestor(l,d)?h.push(l):(D(a,h,h.length,b,c),h=[l])}D(a,h,h.length,b,c)}};
25
+ exports.createDOMRange=function(a,b,c,e,d){let g=b.getKey(),h=e.getKey(),f=document.createRange(),l=a.getElementByKey(g);a=a.getElementByKey(h);k.$isTextNode(b)&&(l=w(l));k.$isTextNode(e)&&(a=w(a));if(void 0===b||void 0===e||null===l||null===a)return null;"BR"===l.nodeName&&([l,c]=x(l));"BR"===a.nodeName&&([a,d]=x(a));b=l.firstChild;l===a&&null!=b&&"BR"===b.nodeName&&0===c&&0===d&&(d=1);try{f.setStart(l,c),f.setEnd(a,d)}catch(m){return null}!f.collapsed||c===d&&g===h||(f.setStart(a,d),f.setEnd(l,
26
+ c));return f};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((g,h)=>{let f=g.top-h.top;return 3>=Math.abs(f)?g.left-h.left:f});let d;for(let g=0;g<e;g++){let h=b[g],f=h.width+c===a.width;d&&d.top<=h.top&&d.top+d.height>h.top&&d.left+d.width>h.left||f?(b.splice(g--,1),e--):d=h}return b};
27
27
  exports.getStyleObjectFromCSS=z;
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}}}
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;){k.$isElementNode(e)&&(d=e.getLastDescendant(),null!==d&&(e=d));var g=e.getPreviousSibling(),h=0;if(null===g){d=e.getParentOrThrow();for(var f=d.getPreviousSibling();null===f;){d=d.getParent();if(null===d){g=null;break}f=d.getPreviousSibling()}null!==d&&(h=d.isInline()?0:2,g=f)}f=e.getTextContent();""===f&&k.$isElementNode(e)&&!e.isInline()&&
29
+ (f="\n\n");d=f.length;if(!k.$isTextNode(e)||c>=d)f=e.getParent(),e.remove(),null==f||0!==f.getChildrenSize()||k.$isRootNode(f)||f.remove(),c-=d+h,e=g;else{let l=e.getKey();h=a.getEditorState().read(()=>{const p=k.$getNodeByKey(l);return k.$isTextNode(p)&&p.isSimpleText()?p.getTextContent():null});g=d-c;let m=f.slice(0,g);null!==h&&h!==f?(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,
30
+ d.select(c,c))):e.isSimpleText()?(h=b.key===l,f=b.offset,f<c&&(f=d),c=h?f-c:0,d=h?f:g,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}}}
package/README.md CHANGED
@@ -21,7 +21,7 @@ the valid CSS properties (i.e., kebab-case).
21
21
 
22
22
  ```ts
23
23
  export function $patchStyleText(
24
- selection: RangeSelection | GridSelection,
24
+ selection: BaseSelection,
25
25
  patch: {
26
26
  [key: string]: string;
27
27
  },
package/lexical-node.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import { BaseSelection, INTERNAL_PointSelection, LexicalEditor, LexicalNode, Point, TextNode } from 'lexical';
8
+ import { BaseSelection, LexicalEditor, LexicalNode, Point, TextNode } from 'lexical';
9
9
  /**
10
10
  * Returns a copy of a node, but generates a new key for the copy.
11
11
  * @param node - The node to be cloned.
@@ -45,6 +45,6 @@ export declare function $addNodeStyle(node: TextNode): void;
45
45
  * Will update partially selected TextNodes by splitting the TextNode and applying
46
46
  * the styles to the appropriate one.
47
47
  * @param selection - The selected node(s) to update.
48
- * @param patch - The patch to apply, which can include multiple styles. { CSSProperty: value }
48
+ * @param patch - The patch to apply, which can include multiple styles. { CSSProperty: value }. Can also accept a function that returns the new property value.
49
49
  */
50
- export declare function $patchStyleText(selection: INTERNAL_PointSelection, patch: Record<string, string | null>): void;
50
+ export declare function $patchStyleText(selection: BaseSelection, patch: Record<string, string | null | ((currentStyleValue: string | null) => string)>): void;
package/package.json CHANGED
@@ -9,10 +9,10 @@
9
9
  "selection"
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "0.12.5",
12
+ "version": "0.13.0",
13
13
  "main": "LexicalSelection.js",
14
14
  "peerDependencies": {
15
- "lexical": "0.12.5"
15
+ "lexical": "0.13.0"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
@@ -5,13 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import type { DecoratorNode, ElementNode, INTERNAL_PointSelection, LexicalNode, RangeSelection } from 'lexical';
8
+ import type { BaseSelection, ElementNode, 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.
12
12
  * @param createElement - The function that creates the node. eg. $createParagraphNode.
13
13
  */
14
- export declare function $setBlocksType(selection: INTERNAL_PointSelection, createElement: () => ElementNode): void;
14
+ export declare function $setBlocksType(selection: BaseSelection | null, createElement: () => ElementNode): void;
15
15
  /**
16
16
  * @deprecated
17
17
  * Wraps all nodes in the selection into another node of the type returned by createElement.
@@ -19,7 +19,7 @@ export declare function $setBlocksType(selection: INTERNAL_PointSelection, creat
19
19
  * @param createElement - A function that creates the wrapping ElementNode. eg. $createParagraphNode.
20
20
  * @param wrappingElement - An element to append the wrapped selection and its children to.
21
21
  */
22
- export declare function $wrapNodes(selection: INTERNAL_PointSelection, createElement: () => ElementNode, wrappingElement?: null | ElementNode): void;
22
+ export declare function $wrapNodes(selection: BaseSelection, createElement: () => ElementNode, wrappingElement?: null | ElementNode): void;
23
23
  /**
24
24
  * Wraps each node into a new ElementNode.
25
25
  * @param selection - The selection of nodes to wrap.
@@ -29,7 +29,7 @@ export declare function $wrapNodes(selection: INTERNAL_PointSelection, createEle
29
29
  * @param wrappingElement - An element to wrap all the nodes into.
30
30
  * @returns
31
31
  */
32
- export declare function $wrapNodesImpl(selection: INTERNAL_PointSelection, nodes: LexicalNode[], nodesLength: number, createElement: () => ElementNode, wrappingElement?: null | ElementNode): void;
32
+ export declare function $wrapNodesImpl(selection: BaseSelection, nodes: LexicalNode[], nodesLength: number, createElement: () => ElementNode, wrappingElement?: null | ElementNode): void;
33
33
  /**
34
34
  * Determines if the default character selection should be overridden. Used with DecoratorNodes
35
35
  * @param selection - The selection whose default character selection may need to be overridden.
@@ -76,5 +76,5 @@ export declare function $getSelectionStyleValueForProperty(selection: RangeSelec
76
76
  * This function is for internal use of the library.
77
77
  * Please do not use it as it may change in the future.
78
78
  */
79
- export declare function INTERNAL_$isBlock(node: LexicalNode): node is ElementNode | DecoratorNode<unknown>;
79
+ export declare function INTERNAL_$isBlock(node: LexicalNode): node is ElementNode;
80
80
  export declare function $getAncestor<NodeType extends LexicalNode = LexicalNode>(node: LexicalNode, predicate: (ancestor: LexicalNode) => ancestor is NodeType): NodeType | null;