@lexical/react
Version:
This package provides Lexical components and hooks for React applications.
10 lines (8 loc) • 5 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.
*
*/
;var e=require("@lexical/link"),t=require("@lexical/react/LexicalComposerContext"),n=require("@lexical/utils"),i=require("lexical"),r=require("react");function o(e,t){for(let n=0;n<t.length;n++){const i=t[n](e);if(i)return i}return null}const l=/[.,;\s]/;function s(e){return l.test(e)}function u(e){return s(e[e.length-1])}function g(e){return s(e[0])}function c(e){let t=e.getPreviousSibling();return i.$isElementNode(t)&&(t=t.getLastDescendant()),null===t||i.$isLineBreakNode(t)||i.$isTextNode(t)&&u(t.getTextContent())}function a(e){let t=e.getNextSibling();return i.$isElementNode(t)&&(t=t.getFirstDescendant()),null===t||i.$isLineBreakNode(t)||i.$isTextNode(t)&&g(t.getTextContent())}function f(e,t,n,i){if(!(e>0?s(n[e-1]):c(i[0])))return!1;return t<n.length?s(n[t]):a(i[i.length-1])}function d(e,t,n){const i=[],r=[],o=[];let l=0,s=0;const u=[...e];for(;u.length>0;){const e=u[0],g=e.getTextContent().length,c=s;s+g<=t?(i.push(e),l+=g):c>=n?o.push(e):r.push(e),s+=g,u.shift()}return[l,i,r,o]}function x(t,n,r,o){const l=e.$createAutoLinkNode(o.url,o.attributes);if(1===t.length){let e,s=t[0];0===n?[e,s]=s.splitText(r):[,e,s]=s.splitText(n,r);const u=i.$createTextNode(o.text);return u.setFormat(e.getFormat()),u.setDetail(e.getDetail()),u.setStyle(e.getStyle()),l.append(u),e.replace(l),s}if(t.length>1){const e=t[0];let o,s=e.getTextContent().length;0===n?o=e:[,o]=e.splitText(n);const u=[];let g;for(let e=1;e<t.length;e++){const n=t[e],i=n.getTextContent().length,o=s;if(o<r)if(s+i<=r)u.push(n);else{const[e,t]=n.splitText(r-o);u.push(e),g=t}s+=i}const c=i.$getSelection(),a=c?c.getNodes().find(i.$isTextNode):void 0,f=i.$createTextNode(o.getTextContent());return f.setFormat(o.getFormat()),f.setDetail(o.getDetail()),f.setStyle(o.getStyle()),l.append(f,...u),a&&a===o&&(i.$isRangeSelection(c)?f.select(c.anchor.offset,c.focus.offset):i.$isNodeSelection(c)&&f.select(0,f.getTextContent().length)),o.replace(l),g}}function h(e,t,n){const r=e.getChildren(),l=r.length;for(let t=0;t<l;t++){const o=r[t];if(!i.$isTextNode(o)||!o.isSimpleText())return p(e),void n(null,e.getURL())}const s=e.getTextContent(),u=o(s,t);if(null===u||u.text!==s)return p(e),void n(null,e.getURL());if(!c(e)||!a(e))return p(e),void n(null,e.getURL());const g=e.getURL();if(g!==u.url&&(e.setURL(u.url),n(u.url,g)),u.attributes){const t=e.getRel();t!==u.attributes.rel&&(e.setRel(u.attributes.rel||null),n(u.attributes.rel||null,t));const i=e.getTarget();i!==u.attributes.target&&(e.setTarget(u.attributes.target||null),n(u.attributes.target||null,i))}}function p(e){const t=e.getChildren();for(let n=t.length-1;n>=0;n--)e.insertAfter(t[n]);return e.remove(),t.map((e=>e.getLatest()))}function T(t,l,s){r.useEffect((()=>{t.hasNodes([e.AutoLinkNode])||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),i=new URLSearchParams;i.append("code",e);for(const e of t)i.append("v",e);throw n.search=i.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.`)}(77);const r=(e,t)=>{s&&s(e,t)};return n.mergeRegister(t.registerNodeTransform(i.TextNode,(t=>{const n=t.getParentOrThrow(),s=t.getPreviousSibling();if(e.$isAutoLinkNode(n)&&!n.getIsUnlinked())h(n,l,r);else if(!e.$isLinkNode(n)){if(t.isSimpleText()&&(g(t.getTextContent())||!e.$isAutoLinkNode(s))){const e=function(e){const t=[e];let n=e.getNextSibling();for(;null!==n&&i.$isTextNode(n)&&n.isSimpleText()&&(t.push(n),!/[\s]/.test(n.getTextContent()));)n=n.getNextSibling();return t}(t);!function(e,t,n){let i=[...e];const r=i.map((e=>e.getTextContent())).join("");let l,s=r,u=0;for(;(l=o(s,t))&&null!==l;){const e=l.index,t=e+l.length;if(f(u+e,u+t,r,i)){const[r,,o,s]=d(i,u+e,u+t),g=x(o,u+e-r,u+t-r,l);i=g?[g,...s]:s,n(l.url,null),u=0}else u+=t;s=s.substring(t)}}(e,l,r)}!function(t,n,i){const r=t.getPreviousSibling(),o=t.getNextSibling(),l=t.getTextContent();var s;!e.$isAutoLinkNode(r)||r.getIsUnlinked()||g(l)&&(s=l,!(r.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(s):/^\.[a-zA-Z0-9]{1,}/.test(s)))||(r.append(t),h(r,n,i),i(null,r.getURL())),!e.$isAutoLinkNode(o)||o.getIsUnlinked()||u(l)||(p(o),h(o,n,i),i(null,o.getURL()))}(t,l,r)}})),t.registerCommand(e.TOGGLE_LINK_COMMAND,(t=>{const n=i.$getSelection();if(null!==t||!i.$isRangeSelection(n))return!1;return n.extract().forEach((t=>{const n=t.getParent();if(e.$isAutoLinkNode(n))return n.setIsUnlinked(!n.getIsUnlinked()),n.markDirty(),!0})),!1}),i.COMMAND_PRIORITY_LOW))}),[t,l,s])}exports.AutoLinkPlugin=function({matchers:e,onChange:n}){const[i]=t.useLexicalComposerContext();return T(i,e,n),null},exports.createLinkMatcherWithRegExp=function(e,t=(e=>e)){return n=>{const i=e.exec(n);return null===i?null:{index:i.index,length:i[0].length,text:i[0],url:t(i[0])}}};