UNPKG

@lexical/selection

Version:

This package contains utilities and helpers for handling Lexical selection.

11 lines (9 loc) • 11.6 kB
/** * 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. * */ "use strict";var e=require("lexical");function t(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.`)} /*@__INLINE__*/function n(e){let t=e;for(;null!=t;){if(t.nodeType===Node.TEXT_NODE)return t;t=t.firstChild}return null}function o(e){const t=e.parentNode;if(null==t)throw new Error("Should never happen");return[t,Array.from(t.childNodes).indexOf(e)]}function r(e){let t="";for(const n in e)n&&(t+=`${n}: ${e[n]};`);return t}function i(t){const n=e.$getEditor().getElementByKey(t.getKey());if(null===n)return null;const o=n.ownerDocument.defaultView;return null===o?null:o.getComputedStyle(n)}function s(t){return i(e.$isRootNode(t)?t:t.getParentOrThrow())}function l(t,n,o){let r=n.getNode(),i=o;if(e.$isElementNode(r)){const e=r.getDescendantByIndex(n.offset);null!==e&&(r=e)}for(;i>0&&null!==r;){if(e.$isElementNode(r)){const e=r.getLastDescendant();null!==e&&(r=e)}let o=r.getPreviousSibling(),s=0;if(null===o){let e=r.getParentOrThrow(),t=e.getPreviousSibling();for(;null===t;){if(e=e.getParent(),null===e){o=null;break}t=e.getPreviousSibling()}null!==e&&(s=e.isInline()?0:2,o=t)}let l=r.getTextContent();""===l&&e.$isElementNode(r)&&!r.isInline()&&(l="\n\n");const c=l.length;if(!e.$isTextNode(r)||i>=c){const t=r.getParent();r.remove(),null==t||0!==t.getChildrenSize()||e.$isRootNode(t)||t.remove(),i-=c+s,r=o}else{const o=r.getKey(),s=t.read("latest",()=>{const t=e.$getNodeByKey(o);return e.$isTextNode(t)&&t.isSimpleText()?t.getTextContent():null}),f=c-i,d=l.slice(0,f);if(null!==s&&s!==l){const t=e.$getPreviousSelection();let n=r;if(r.isSimpleText())r.setTextContent(s);else{const t=e.$createTextNode(s);r.replace(t),n=t}if(e.$isRangeSelection(t)&&t.isCollapsed()){const e=t.anchor.offset;n.select(e,e)}}else if(r.isSimpleText()){const e=n.key===o;let t=n.offset;t<i&&(t=c);const s=e?t-i:0,l=e?t:f;if(e&&0===s){const[e]=r.splitText(s,l);e.remove()}else{const[,e]=r.splitText(s,l);e.remove()}}else{const t=e.$createTextNode(d);r.replace(t)}i=0}}}const c=()=>{};function f(n,o){(e.$isRangeSelection(n)?n.isCollapsed():e.$isTextNode(n)||e.$isElementNode(n))||t(280);const i=e.getStyleObjectFromCSS(e.$isRangeSelection(n)?n.style:e.$isTextNode(n)?n.getStyle():n.getTextStyle()),s=r(Object.entries(o).reduce((e,[t,o])=>("function"==typeof o?e[t]=o(i[t],n):null===o?delete e[t]:e[t]=o,e),{...i}));e.$isRangeSelection(n)||e.$isTextNode(n)?n.setStyle(s):n.setTextStyle(s)}function d(t){const n=e.$getSelection();if(!n)return;const o=new Map,r=e=>o.get(e.getKey())||[0,e.getTextContentSize()];if(e.$isRangeSelection(n))for(const t of e.$caretRangeFromSelection(n).getTextSlices())t&&o.set(t.caret.origin.getKey(),t.getSliceIndices());const i=n.getNodes();for(const n of i){if(!e.$isTextNode(n)||!n.canHaveFormat())continue;const[o,i]=r(n);if(i!==o)if(e.$isTokenOrSegmented(n)||0===o&&i===n.getTextContentSize())t(n);else{t(n.splitText(o,i)[0===o?0:1])}}e.$isRangeSelection(n)&&"text"===n.anchor.type&&"text"===n.focus.type&&n.anchor.key===n.focus.key&&a(n)}function a(e){if(e.isBackward()){const{anchor:t,focus:n}=e,{key:o,offset:r,type:i}=t;t.set(n.key,n.offset,n.type),n.set(o,r,i)}}function g(e,t){const n=e.getFormatType(),o=e.getIndent();n!==t.getFormatType()&&t.setFormat(n),o!==t.getIndent()&&t.setIndent(o)}function u(t,n,o){let r=e.$caretFromPoint(t,o);if(e.$isExtendableTextPointCaret(r))return!1;for(;r;r=r.getParentCaret()){const e=r.getParentAtCaret();if(!e||r.getNodeAtCaret())return!1;if(n.is(e))return!0}return!1}function p(e){return e.getNode().isAttached()}function $(t){let n=t;for(;null!==n&&!e.$isRootOrShadowRoot(n);){const e=n.getLatest(),t=n.getParent();0===e.getChildrenSize()&&n.remove(!0),n=t}}function h(n,o,r,i,s=null){if(0===o.length)return;const l=o[0],c=new Map,f=[],d=e.$isElementNode(l)?l:l.getParentOrThrow();let a=d.isInline()?d.getParentOrThrow():d,g=!1;for(;null!==a;){const t=a.getPreviousSibling();if(null!==t){a=t,g=!0;break}if(a=a.getParentOrThrow(),e.$isRootOrShadowRoot(a))break}const u=new Set;for(let t=0;t<r;t++){const n=o[t];e.$isElementNode(n)&&0===n.getChildrenSize()&&u.add(n.getKey())}const h=new Set;for(let n=0;n<r;n++){const r=o[n];let s=r.getParent();if(null!==s&&s.isInline()&&(s=s.getParent()),null!==s&&e.$isLeafNode(r)&&!h.has(r.getKey())){const t=s.getKey();if(void 0===c.get(t)){const n=i();n.setFormat(s.getFormatType()),n.setIndent(s.getIndent()),f.push(n),c.set(t,n);const o=s.getChildren();n.splice(n.getChildrenSize(),0,o);for(const t of o)if(h.add(t.getKey()),e.$isElementNode(t))for(const e of t.getChildrenKeys())h.add(e);$(s)}}else if(u.has(r.getKey())){e.$isElementNode(r)||t(179);const n=i();n.setFormat(r.getFormatType()),n.setIndent(r.getIndent()),f.push(n),r.remove(!0)}}if(null!==s)for(let e=0;e<f.length;e++){const t=f[e];s.append(t)}let m=null;if(e.$isRootOrShadowRoot(a))if(g)if(null!==s)a.insertAfter(s);else for(let e=f.length-1;e>=0;e--){const t=f[e];a.insertAfter(t)}else{const t=a,n=t.getFirstChild();if(e.$isElementNode(n)&&(a=n),null===n)if(s)t.append(s);else for(let e=0;e<f.length;e++){const n=f[e];t.append(n),m=n}else if(null!==s)n.insertBefore(s);else for(let e=0;e<f.length;e++){const t=f[e];n.insertBefore(t),m=t}}else if(s)a.insertAfter(s);else for(let e=f.length-1;e>=0;e--){const t=f[e];a.insertAfter(t),m=t}const S=e.$getPreviousSelection();e.$isRangeSelection(S)&&p(S.anchor)&&p(S.focus)?e.$setSelection(S.clone()):null!==m?m.selectEnd():n.dirty=!0}function m(e){const t=S(e);return null!==t&&"vertical-rl"===t.writingMode}function S(t){const n=t.anchor.getNode();return e.$isElementNode(n)?i(n):s(n)}function N(e,t,n,o){e.modify(t?"extend":"move",n,o)}function x(e){const t=S(e);return null!==t&&"rtl"===t.direction}function y(t,n,o){const r=t.getStyle(),i=e.getStyleObjectFromCSS(r);return null!==i&&i[n]||o}const T=e.getStyleObjectFromCSS,C=l;exports.$cloneWithProperties=e.$cloneWithProperties,exports.$selectAll=e.$selectAll,exports.$addNodeStyle=c,exports.$copyBlockFormatIndent=g,exports.$ensureForwardRangeSelection=a,exports.$forEachSelectedTextNode=d,exports.$getComputedStyleForElement=i,exports.$getComputedStyleForParent=s,exports.$getSelectionStyleValueForProperty=function(t,n,o=""){let r=null;const i=t.getNodes();let s,l;if(e.$isRangeSelection(t)){if(t.isCollapsed()&&""!==t.style){const o=e.getStyleObjectFromCSS(t.style);if(null!==o&&n in o)return o[n]}const{anchor:o,focus:r}=t,i=t.isBackward(),c=i?r.getNode():o.getNode(),f=i?o.getNode():r.getNode(),d=i?r.offset:o.offset,a=i?o.offset:r.offset;e.$isTextNode(c)&&d===c.getTextContentSize()&&(s=c),0===a&&(l=f)}for(let t=0;t<i.length;t++){const c=i[t];if(e.$isTextNode(c)&&!c.is(0===t?s:l)){const e=y(c,n,o);if(null===r)r=e;else if(r!==e){r="";break}}}return null===r?o:r},exports.$isAtEdgeOfElement=u,exports.$isAtNodeEnd=function(n){if("text"===n.type)return n.offset===n.getNode().getTextContentSize();const o=n.getNode();return e.$isElementNode(o)||t(177),n.offset===o.getChildrenSize()},exports.$isParentElementRTL=x,exports.$isParentRTL=function(e){const t=s(e);return null!==t&&"rtl"===t.direction},exports.$moveCaretSelection=N,exports.$moveCharacter=function(e,t,n){const o=x(e);let r;r=m(e)||o?!n:n,N(e,t,r,"character")},exports.$patchStyleText=function(t,n){if(e.$isRangeSelection(t)&&t.isCollapsed()){f(t,n);const o=t.anchor.getNode();e.$isElementNode(o)&&o.isEmpty()&&f(o,n)}d(e=>{f(e,n)});const o=t.getNodes();if(o.length>0){const t=new Set;for(const r of o){if(!e.$isElementNode(r)||!r.canBeEmpty()||0!==r.getChildrenSize())continue;const o=r.getKey();t.has(o)||(t.add(o),f(r,n))}}},exports.$setBlocksType=function(t,n,o=g){if(!t)return;const r=t.getStartEndPoints();let i=!1,s=null;const l=new Map;if(r){const[n,o]=r,c=e.$findMatchingParent(n.getNode(),e.INTERNAL_$isBlock);s=e.$findMatchingParent(o.getNode(),e.INTERNAL_$isBlock);const f=t.isBackward()?"previous":"next";i=e.$isElementNode(s)&&!s.is(c)&&function(t,n,o){const r=t.getNode();return(!e.$isElementNode(r)||!r.isEmpty())&&u(t,n,o)}(o,s,e.flipDirection(f)),e.$isElementNode(c)&&l.set(c.getKey(),c),e.$isElementNode(s)&&!i&&l.set(s.getKey(),s)}for(const n of t.getNodes())if(e.$isElementNode(n)&&e.INTERNAL_$isBlock(n)){if(i&&n.is(s))continue;l.set(n.getKey(),n)}else if(!r){const t=e.$findMatchingParent(n,e.INTERNAL_$isBlock);e.$isElementNode(t)&&l.set(t.getKey(),t)}for(const e of l.values()){const t=n();o(e,t),e.replace(t,!0)}},exports.$shouldOverrideDefaultCharacterSelection=function(t,n){let o=m(t)?!n:n;x(t)&&(o=!o);const r=e.$caretFromPoint(t.focus,o?"previous":"next");if(e.$isExtendableTextPointCaret(r))return!1;if(e.$isTextPointCaret(r)&&!e.$isTabNode(r.origin)&&r.origin.isUnmergeable()){const t=r.getNodeAtCaret();if(e.$isTextNode(t)&&!e.$isTabNode(t))return!0}for(const t of e.$extendCaretToRange(r)){if(e.$isChildCaret(t))return!t.origin.isInline();if(!e.$isElementNode(t.origin)){if(e.$isDecoratorNode(t.origin))return!0;break}}return!1},exports.$sliceSelectedTextNodeContent=function(t,n,o="self"){const r=t.getStartEndPoints();if(n.isSelected(t)&&!e.$isTokenOrSegmented(n)&&null!==r){const[i,s]=r,l=t.isBackward(),c=i.getNode(),f=s.getNode(),d=n.is(c),a=n.is(f);if(d||a){const[r,i]=e.$getCharacterOffsets(t),s=c.is(f),d=n.is(l?f:c),a=n.is(l?c:f);let g,u=0;if(s)u=r>i?i:r,g=r>i?r:i;else if(d){u=l?i:r,g=void 0}else if(a){u=0,g=l?r:i}const p=n.__text.slice(u,g);p!==n.__text&&("clone"===o&&(n=e.$cloneWithPropertiesEphemeral(n)),n.__text=p)}}return n},exports.$trimTextContentFromAnchor=l,exports.$wrapNodes=function(t,n,o=null){const r=t.getStartEndPoints(),i=r?r[0]:null,s=t.getNodes(),l=s.length;if(null!==i&&(0===l||1===l&&"element"===i.type&&0===i.getNode().getChildrenSize())){const e="text"===i.type?i.getNode().getParentOrThrow():i.getNode(),t=e.getChildren();let r=n();return r.setFormat(e.getFormatType()),r.setIndent(e.getIndent()),t.forEach(e=>r.append(e)),o&&(r=o.append(r)),void e.replace(r)}let c=null,f=[];for(let r=0;r<l;r++){const i=s[r];e.$isRootOrShadowRoot(i)?(h(t,f,f.length,n,o),f=[],c=i):null===c||null!==c&&e.$hasAncestor(i,c)?f.push(i):(h(t,f,f.length,n,o),f=[i])}h(t,f,f.length,n,o)},exports.createDOMRange=function(t,r,i,s,l){const c=r.getKey(),f=s.getKey(),d=e.getRootOwnerDocument(t.getRootElement()).createRange();let a=t.getElementByKey(c),g=t.getElementByKey(f),u=i,p=l;if(e.$isTextNode(r)&&(a=n(a)),e.$isTextNode(s)&&(g=n(g)),void 0===r||void 0===s||null===a||null===g)return null;"BR"===a.nodeName&&([a,u]=o(a)),"BR"===g.nodeName&&([g,p]=o(g));const $=a.firstChild;a===g&&null!=$&&"BR"===$.nodeName&&0===u&&0===p&&(p=1);try{d.setStart(a,u),d.setEnd(g,p)}catch(e){return null}return!d.collapsed||u===p&&c===f||(d.setStart(g,p),d.setEnd(a,u)),d},exports.createRectsFromDOMRange=function(e,t){const n=e.getRootElement();if(null===n)return[];const o=n.getBoundingClientRect(),r=getComputedStyle(n),i=parseFloat(r.paddingLeft)+parseFloat(r.paddingRight),s=Array.from(t.getClientRects());let l,c=s.length;s.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=s[e],n=l&&l.top<=t.top&&l.top+l.height>t.top&&l.left+l.width>t.left,r=t.width+i===o.width;n||r?(s.splice(e--,1),c--):l=t}return s},exports.getCSSFromStyleObject=r,exports.getStyleObjectFromCSS=T,exports.trimTextContentFromAnchor=C;