@lexical/selection
Version:
This package contains utilities and helpers for handling Lexical selection.
10 lines (8 loc) • 10.4 kB
JavaScript
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import{$isTextNode as e,$getEditor as t,$isRootNode as n,$getSelection as o,$isRangeSelection as l,$caretRangeFromSelection as r,$isTokenOrSegmented as i,$isElementNode as s,$getCharacterOffsets as c,$cloneWithPropertiesEphemeral as f,$getNodeByKey as u,$getPreviousSelection as g,$createTextNode as d,getStyleObjectFromCSS as a,$findMatchingParent as p,INTERNAL_$isBlock as h,$caretFromPoint as y,$isExtendableTextPointCaret as m,$extendCaretToRange as S,$isChildCaret as x,$isDecoratorNode as N,$isRootOrShadowRoot as T,$hasAncestor as C,$isLeafNode as v,$setSelection as w}from"lexical";export{$cloneWithProperties,$selectAll}from"lexical";function P(e,...t){const n=new URL("https://lexical.dev/docs/error"),o=new URLSearchParams;o.append("code",e);for(const e of t)o.append("v",e);throw n.search=o.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function K(e){let t=e;for(;null!=t;){if(t.nodeType===Node.TEXT_NODE)return t;t=t.firstChild}return null}function E(e){const t=e.parentNode;if(null==t)throw new Error("Should never happen");return[t,Array.from(t.childNodes).indexOf(e)]}function I(t,n,o,l,r){const i=n.getKey(),s=l.getKey(),c=document.createRange();let f=t.getElementByKey(i),u=t.getElementByKey(s),g=o,d=r;if(e(n)&&(f=K(f)),e(l)&&(u=K(u)),void 0===n||void 0===l||null===f||null===u)return null;"BR"===f.nodeName&&([f,g]=E(f)),"BR"===u.nodeName&&([u,d]=E(u));const a=f.firstChild;f===u&&null!=a&&"BR"===a.nodeName&&0===g&&0===d&&(d=1);try{c.setStart(f,g),c.setEnd(u,d)}catch(e){return null}return!c.collapsed||g===d&&i===s||(c.setStart(u,d),c.setEnd(f,g)),c}function B(e,t){const n=e.getRootElement();if(null===n)return[];const o=n.getBoundingClientRect(),l=getComputedStyle(n),r=parseFloat(l.paddingLeft)+parseFloat(l.paddingRight),i=Array.from(t.getClientRects());let s,c=i.length;i.sort((e,t)=>{const n=e.top-t.top;return Math.abs(n)<=3?e.left-t.left:n});for(let e=0;e<c;e++){const t=i[e],n=s&&s.top<=t.top&&s.top+s.height>t.top&&s.left+s.width>t.left,l=t.width+r===o.width;n||l?(i.splice(e--,1),c--):s=t}return i}function F(e){let t="";for(const n in e)n&&(t+=`${n}: ${e[n]};`);return t}function b(e){const n=t().getElementByKey(e.getKey());if(null===n)return null;const o=n.ownerDocument.defaultView;return null===o?null:o.getComputedStyle(n)}function k(e){return b(n(e)?e:e.getParentOrThrow())}function z(e){const t=k(e);return null!==t&&"rtl"===t.direction}function O(e,t,n="self"){const o=e.getStartEndPoints();if(t.isSelected(e)&&!i(t)&&null!==o){const[l,r]=o,i=e.isBackward(),s=l.getNode(),u=r.getNode(),g=t.is(s),d=t.is(u);if(g||d){const[o,l]=c(e),r=s.is(u),g=t.is(i?u:s),d=t.is(i?s:u);let a,p=0;if(r)p=o>l?l:o,a=o>l?o:l;else if(g){p=i?l:o,a=void 0}else if(d){p=0,a=i?o:l}const h=t.__text.slice(p,a);h!==t.__text&&("clone"===n&&(t=f(t)),t.__text=h)}}return t}function R(e){if("text"===e.type)return e.offset===e.getNode().getTextContentSize();const t=e.getNode();return s(t)||P(177),e.offset===t.getChildrenSize()}function A(t,o,r){let i=o.getNode(),c=r;if(s(i)){const e=i.getDescendantByIndex(o.offset);null!==e&&(i=e)}for(;c>0&&null!==i;){if(s(i)){const e=i.getLastDescendant();null!==e&&(i=e)}let r=i.getPreviousSibling(),f=0;if(null===r){let e=i.getParentOrThrow(),t=e.getPreviousSibling();for(;null===t;){if(e=e.getParent(),null===e){r=null;break}t=e.getPreviousSibling()}null!==e&&(f=e.isInline()?0:2,r=t)}let a=i.getTextContent();""===a&&s(i)&&!i.isInline()&&(a="\n\n");const p=a.length;if(!e(i)||c>=p){const e=i.getParent();i.remove(),null==e||0!==e.getChildrenSize()||n(e)||e.remove(),c-=p+f,i=r}else{const n=i.getKey(),r=t.getEditorState().read(()=>{const t=u(n);return e(t)&&t.isSimpleText()?t.getTextContent():null}),s=p-c,f=a.slice(0,s);if(null!==r&&r!==a){const e=g();let t=i;if(i.isSimpleText())i.setTextContent(r);else{const e=d(r);i.replace(e),t=e}if(l(e)&&e.isCollapsed()){const n=e.anchor.offset;t.select(n,n)}}else if(i.isSimpleText()){const e=o.key===n;let t=o.offset;t<c&&(t=p);const l=e?t-c:0,r=e?t:s;if(e&&0===l){const[e]=i.splitText(l,r);e.remove()}else{const[,e]=i.splitText(l,r);e.remove()}}else{const e=d(f);i.replace(e)}c=0}}}const _=()=>{};function L(t,n){(l(t)?t.isCollapsed():e(t)||s(t))||P(280);const o=a(l(t)?t.style:e(t)?t.getStyle():t.getTextStyle()),r=F(Object.entries(n).reduce((e,[n,l])=>("function"==typeof l?e[n]=l(o[n],t):null===l?delete e[n]:e[n]=l,e),{...o}));l(t)||e(t)?t.setStyle(r):t.setTextStyle(r)}function M(e,t){if(l(e)&&e.isCollapsed()){L(e,t);const n=e.anchor.getNode();s(n)&&n.isEmpty()&&L(n,t)}$(e=>{L(e,t)});const n=e.getNodes();if(n.length>0){const e=new Set;for(const o of n){if(!s(o)||!o.canBeEmpty()||0!==o.getChildrenSize())continue;const n=o.getKey();e.has(n)||(e.add(n),L(o,t))}}}function $(t){const n=o();if(!n)return;const s=new Map,c=e=>s.get(e.getKey())||[0,e.getTextContentSize()];if(l(n))for(const e of r(n).getTextSlices())e&&s.set(e.caret.origin.getKey(),e.getSliceIndices());const f=n.getNodes();for(const n of f){if(!e(n)||!n.canHaveFormat())continue;const[o,l]=c(n);if(l!==o)if(i(n)||0===o&&l===n.getTextContentSize())t(n);else{t(n.splitText(o,l)[0===o?0:1])}}l(n)&&"text"===n.anchor.type&&"text"===n.focus.type&&n.anchor.key===n.focus.key&&D(n)}function D(e){if(e.isBackward()){const{anchor:t,focus:n}=e,{key:o,offset:l,type:r}=t;t.set(n.key,n.offset,n.type),n.set(o,l,r)}}function j(e,t){const n=e.getFormatType(),o=e.getIndent();n!==t.getFormatType()&&t.setFormat(n),o!==t.getIndent()&&t.setIndent(o)}function U(e,t,n=j){if(!e)return;const o=e.getStartEndPoints();let l=!1,r=null;const i=new Map;if(o){const[e,t]=o,n=p(e.getNode(),h);r=p(t.getNode(),h),l=s(r)&&!r.is(n)&&function(e,t){if(0!==e.offset)return!1;let n=e.getNode();if(s(n)&&n.isEmpty())return!1;for(;!n.is(t);){if(null!==n.getPreviousSibling())return!1;const e=n.getParent();if(null===e)return!1;n=e}return!0}(t,r),s(n)&&i.set(n.getKey(),n),s(r)&&!l&&i.set(r.getKey(),r)}for(const t of e.getNodes())if(s(t)&&h(t)){if(l&&t.is(r))continue;i.set(t.getKey(),t)}else if(!o){const e=p(t,h);s(e)&&i.set(e.getKey(),e)}for(const e of i.values()){const o=t();n(e,o),e.replace(o,!0)}}function H(e){return e.getNode().isAttached()}function V(e){let t=e;for(;null!==t&&!T(t);){const e=t.getLatest(),n=t.getParent();0===e.getChildrenSize()&&t.remove(!0),t=n}}function W(e,t,n=null){const o=e.getStartEndPoints(),l=o?o[0]:null,r=e.getNodes(),i=r.length;if(null!==l&&(0===i||1===i&&"element"===l.type&&0===l.getNode().getChildrenSize())){const e="text"===l.type?l.getNode().getParentOrThrow():l.getNode(),o=e.getChildren();let r=t();return r.setFormat(e.getFormatType()),r.setIndent(e.getIndent()),o.forEach(e=>r.append(e)),n&&(r=n.append(r)),void e.replace(r)}let s=null,c=[];for(let o=0;o<i;o++){const l=r[o];T(l)?(X(e,c,c.length,t,n),c=[],s=l):null===s||null!==s&&C(l,s)?c.push(l):(X(e,c,c.length,t,n),c=[l])}X(e,c,c.length,t,n)}function X(e,t,n,o,r=null){if(0===t.length)return;const i=t[0],c=new Map,f=[];let u=s(i)?i:i.getParentOrThrow();u.isInline()&&(u=u.getParentOrThrow());let d=!1;for(;null!==u;){const e=u.getPreviousSibling();if(null!==e){u=e,d=!0;break}if(u=u.getParentOrThrow(),T(u))break}const a=new Set;for(let e=0;e<n;e++){const n=t[e];s(n)&&0===n.getChildrenSize()&&a.add(n.getKey())}const p=new Set;for(let e=0;e<n;e++){const n=t[e];let l=n.getParent();if(null!==l&&l.isInline()&&(l=l.getParent()),null!==l&&v(n)&&!p.has(n.getKey())){const e=l.getKey();if(void 0===c.get(e)){const t=o();t.setFormat(l.getFormatType()),t.setIndent(l.getIndent()),f.push(t),c.set(e,t);const n=l.getChildren();t.splice(t.getChildrenSize(),0,n);for(const e of n)if(p.add(e.getKey()),s(e))for(const t of e.getChildrenKeys())p.add(t);V(l)}}else if(a.has(n.getKey())){s(n)||P(179);const e=o();e.setFormat(n.getFormatType()),e.setIndent(n.getIndent()),f.push(e),n.remove(!0)}}if(null!==r)for(let e=0;e<f.length;e++){const t=f[e];r.append(t)}let h=null;if(T(u))if(d)if(null!==r)u.insertAfter(r);else for(let e=f.length-1;e>=0;e--){const t=f[e];u.insertAfter(t)}else{const e=u.getFirstChild();if(s(e)&&(u=e),null===e)if(r)u.append(r);else for(let e=0;e<f.length;e++){const t=f[e];u.append(t),h=t}else if(null!==r)e.insertBefore(r);else for(let t=0;t<f.length;t++){const n=f[t];e.insertBefore(n),h=n}}else if(r)u.insertAfter(r);else for(let e=f.length-1;e>=0;e--){const t=f[e];u.insertAfter(t),h=t}const y=g();l(y)&&H(y.anchor)&&H(y.focus)?w(y.clone()):null!==h?h.selectEnd():e.dirty=!0}function q(e){const t=G(e);return null!==t&&"vertical-rl"===t.writingMode}function G(e){const t=e.anchor.getNode();return s(t)?b(t):k(t)}function J(e,t){let n=q(e)?!t:t;Y(e)&&(n=!n);const o=y(e.focus,n?"previous":"next");if(m(o))return!1;for(const e of S(o)){if(x(e))return!e.origin.isInline();if(!s(e.origin)){if(N(e.origin))return!0;break}}return!1}function Q(e,t,n,o){e.modify(t?"extend":"move",n,o)}function Y(e){const t=G(e);return null!==t&&"rtl"===t.direction}function Z(e,t,n){const o=Y(e);let l;l=q(e)||o?!n:n,Q(e,t,l,"character")}function ee(e,t,n){const o=e.getStyle(),l=a(o);return null!==l&&l[t]||n}function te(t,n,o=""){let r=null;const i=t.getNodes();let s,c;if(l(t)){if(t.isCollapsed()&&""!==t.style){const e=a(t.style);if(null!==e&&n in e)return e[n]}const{anchor:o,focus:l}=t,r=t.isBackward(),i=r?l.getNode():o.getNode(),f=r?o.getNode():l.getNode(),u=r?l.offset:o.offset,g=r?o.offset:l.offset;e(i)&&u===i.getTextContentSize()&&(s=i),0===g&&(c=f)}for(let t=0;t<i.length;t++){const l=i[t];if(e(l)&&!l.is(0===t?s:c)){const e=ee(l,n,o);if(null===r)r=e;else if(r!==e){r="";break}}}return null===r?o:r}const ne=a,oe=A;export{_ as $addNodeStyle,j as $copyBlockFormatIndent,D as $ensureForwardRangeSelection,$ as $forEachSelectedTextNode,b as $getComputedStyleForElement,k as $getComputedStyleForParent,te as $getSelectionStyleValueForProperty,R as $isAtNodeEnd,Y as $isParentElementRTL,z as $isParentRTL,Q as $moveCaretSelection,Z as $moveCharacter,M as $patchStyleText,U as $setBlocksType,J as $shouldOverrideDefaultCharacterSelection,O as $sliceSelectedTextNodeContent,A as $trimTextContentFromAnchor,W as $wrapNodes,I as createDOMRange,B as createRectsFromDOMRange,F as getCSSFromStyleObject,ne as getStyleObjectFromCSS,oe as trimTextContentFromAnchor};