@lexical/link 0.47.1-nightly.20260716.0 → 0.48.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.
package/dist/LexicalLink.dev.js
CHANGED
|
@@ -111,6 +111,7 @@ class LinkNode extends lexical.ElementNode {
|
|
|
111
111
|
return super.updateFromJSON(serializedNode).setURL(serializedNode.url).setRel(serializedNode.rel || null).setTarget(serializedNode.target || null).setTitle(serializedNode.title || null);
|
|
112
112
|
}
|
|
113
113
|
sanitizeUrl(url) {
|
|
114
|
+
const rawUrl = url;
|
|
114
115
|
url = formatUrl(url);
|
|
115
116
|
try {
|
|
116
117
|
const parsedUrl = new URL(formatUrl(url));
|
|
@@ -118,7 +119,34 @@ class LinkNode extends lexical.ElementNode {
|
|
|
118
119
|
return 'about:blank';
|
|
119
120
|
}
|
|
120
121
|
} catch (_unused) {
|
|
121
|
-
|
|
122
|
+
// `new URL()` threw, so we could not verify the protocol via the
|
|
123
|
+
// parser. Preserve fail-secure behavior: default unparseable URLs to
|
|
124
|
+
// `about:blank` and only allow through inputs that positively match an
|
|
125
|
+
// allowlisted scheme.
|
|
126
|
+
//
|
|
127
|
+
// Check the ORIGINAL input, not the `formatUrl()` output: `formatUrl()`
|
|
128
|
+
// prepends `https://` to anything it does not recognize as already
|
|
129
|
+
// having a scheme, which would mask a control-character-obfuscated
|
|
130
|
+
// scheme (e.g. `java\x00script:` becomes `https://java\x00script:`).
|
|
131
|
+
//
|
|
132
|
+
// Before extracting the scheme, strip C0 control characters, DEL and
|
|
133
|
+
// whitespace, mirroring how browsers ignore these when resolving a
|
|
134
|
+
// scheme. Without this, control-character-obfuscated schemes that throw
|
|
135
|
+
// in `new URL()` but are still navigated by some browsers would slip
|
|
136
|
+
// past a naive scheme check and retain their original, attacker-
|
|
137
|
+
// controlled value. Stripping C0 control characters and DEL is the
|
|
138
|
+
// intended, security-relevant behavior here.
|
|
139
|
+
// eslint-disable-next-line no-control-regex
|
|
140
|
+
const normalizedUrl = rawUrl.replace(/[\u0000-\u001F\u007F\s]/g, '');
|
|
141
|
+
const schemeMatch = normalizedUrl.match(/^([a-z][a-z0-9+.-]*):/i);
|
|
142
|
+
if (schemeMatch != null && !SUPPORTED_URL_PROTOCOLS.has(`${schemeMatch[1].toLowerCase()}:`)) {
|
|
143
|
+
// An explicit, non-allowlisted scheme survived normalization (e.g.
|
|
144
|
+
// `javascript:`, `data:`) — neutralize it. Inputs with no scheme
|
|
145
|
+
// (relative URLs such as `/path` or `#anchor`) or an allowlisted
|
|
146
|
+
// scheme are left unchanged: they cannot carry a dangerous scheme
|
|
147
|
+
// and are handled elsewhere.
|
|
148
|
+
return 'about:blank';
|
|
149
|
+
}
|
|
122
150
|
}
|
|
123
151
|
return url;
|
|
124
152
|
}
|
package/dist/LexicalLink.dev.mjs
CHANGED
|
@@ -109,6 +109,7 @@ class LinkNode extends ElementNode {
|
|
|
109
109
|
return super.updateFromJSON(serializedNode).setURL(serializedNode.url).setRel(serializedNode.rel || null).setTarget(serializedNode.target || null).setTitle(serializedNode.title || null);
|
|
110
110
|
}
|
|
111
111
|
sanitizeUrl(url) {
|
|
112
|
+
const rawUrl = url;
|
|
112
113
|
url = formatUrl(url);
|
|
113
114
|
try {
|
|
114
115
|
const parsedUrl = new URL(formatUrl(url));
|
|
@@ -116,7 +117,34 @@ class LinkNode extends ElementNode {
|
|
|
116
117
|
return 'about:blank';
|
|
117
118
|
}
|
|
118
119
|
} catch (_unused) {
|
|
119
|
-
|
|
120
|
+
// `new URL()` threw, so we could not verify the protocol via the
|
|
121
|
+
// parser. Preserve fail-secure behavior: default unparseable URLs to
|
|
122
|
+
// `about:blank` and only allow through inputs that positively match an
|
|
123
|
+
// allowlisted scheme.
|
|
124
|
+
//
|
|
125
|
+
// Check the ORIGINAL input, not the `formatUrl()` output: `formatUrl()`
|
|
126
|
+
// prepends `https://` to anything it does not recognize as already
|
|
127
|
+
// having a scheme, which would mask a control-character-obfuscated
|
|
128
|
+
// scheme (e.g. `java\x00script:` becomes `https://java\x00script:`).
|
|
129
|
+
//
|
|
130
|
+
// Before extracting the scheme, strip C0 control characters, DEL and
|
|
131
|
+
// whitespace, mirroring how browsers ignore these when resolving a
|
|
132
|
+
// scheme. Without this, control-character-obfuscated schemes that throw
|
|
133
|
+
// in `new URL()` but are still navigated by some browsers would slip
|
|
134
|
+
// past a naive scheme check and retain their original, attacker-
|
|
135
|
+
// controlled value. Stripping C0 control characters and DEL is the
|
|
136
|
+
// intended, security-relevant behavior here.
|
|
137
|
+
// eslint-disable-next-line no-control-regex
|
|
138
|
+
const normalizedUrl = rawUrl.replace(/[\u0000-\u001F\u007F\s]/g, '');
|
|
139
|
+
const schemeMatch = normalizedUrl.match(/^([a-z][a-z0-9+.-]*):/i);
|
|
140
|
+
if (schemeMatch != null && !SUPPORTED_URL_PROTOCOLS.has(`${schemeMatch[1].toLowerCase()}:`)) {
|
|
141
|
+
// An explicit, non-allowlisted scheme survived normalization (e.g.
|
|
142
|
+
// `javascript:`, `data:`) — neutralize it. Inputs with no scheme
|
|
143
|
+
// (relative URLs such as `/path` or `#anchor`) or an allowlisted
|
|
144
|
+
// scheme are left unchanged: they cannot carry a dangerous scheme
|
|
145
|
+
// and are handled elsewhere.
|
|
146
|
+
return 'about:blank';
|
|
147
|
+
}
|
|
120
148
|
}
|
|
121
149
|
return url;
|
|
122
150
|
}
|
package/dist/LexicalLink.prod.js
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
"use strict";var e=require("@lexical/extension"),t=require("lexical"),n=require("@lexical/html"),r=require("@lexical/utils");const i=new Set(["http:","https:","mailto:","sms:","tel:"]);class s extends t.ElementNode{__url;__target;__rel;__title;static getType(){return"link"}static clone(e){return new s(e.__url,{rel:e.__rel,target:e.__target,title:e.__title},e.__key)}constructor(e="",t={},n){super(n);const{target:r=null,rel:i=null,title:s=null}=t;this.__url=e,this.__target=r,this.__rel=i,this.__title=s}afterCloneFrom(e){super.afterCloneFrom(e),this.__url=e.__url,this.__rel=e.__rel,this.__target=e.__target,this.__title=e.__title}createDOM(e){const n=t.$getDocument().createElement("a");return this.updateLinkDOM(null,n,e),t.addClassNamesToElement(n,e.theme.link),n}updateLinkDOM(e,n,r){if(t.isHTMLAnchorElement(n)){e&&e.__url===this.__url||(n.href=this.sanitizeUrl(this.__url));for(const t of["target","rel","title"]){const r=`__${t}`,i=this[r];e&&e[r]===i||(i?n[t]=i:n.removeAttribute(t))}}}updateDOM(e,t,n){return this.updateLinkDOM(e,t,n),!1}static importDOM(){return{a:e=>({conversion:u,priority:1})}}static importJSON(e){return c().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setURL(e.url).setRel(e.rel||null).setTarget(e.target||null).setTitle(e.title||null)}sanitizeUrl(e){e=N(e);try{const t=new URL(N(e));if(!i.has(t.protocol))return"about:blank"}catch(t){return e}return e}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),url:this.getURL()}}getURL(){return this.getLatest().__url}setURL(e){const t=this.getWritable();return t.__url=e,t}getTarget(){return this.getLatest().__target}setTarget(e){const t=this.getWritable();return t.__target=e,t}getRel(){return this.getLatest().__rel}setRel(e){const t=this.getWritable();return t.__rel=e,t}getTitle(){return this.getLatest().__title}setTitle(e){const t=this.getWritable();return t.__title=e,t}insertNewAfter(e,n=!0){const r=t.$copyNode(this);return this.insertAfter(r,n),r}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(e,n,r){if(!t.$isRangeSelection(n))return!1;const i=n.anchor.getNode(),s=n.focus.getNode();return(this.is(i)||this.isParentOf(i))&&(this.is(s)||this.isParentOf(s))&&n.getTextContent().length>0}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")||this.__url.startsWith("http://")}shouldMergeAdjacentLink(e){return this.getType()===e.getType()&&this.__url===e.__url&&this.__target===e.__target&&this.__rel===e.__rel&&this.__title===e.__title}}function l(e){const n=t.$caretFromPoint(e,"next");return[n,n.getFlipped()]}function o(e,n){for(const r of n)if(r.origin.isAttached()){const n=t.$normalizeCaret(r);return void t.$setPointFromCaret(e,n)}}function a(e){const n=t.$getSelection();let r=null,i=null;function s(){t.$isRangeSelection(n)&&(o(n.anchor,r),o(n.focus,i),t.$normalizeSelection__EXPERIMENTAL(n))}t.$isRangeSelection(n)&&(r=l(n.anchor),i=l(n.focus));let a=!1;for(const n of t.$getChildCaret(e,"next")){const r=n.origin;if(t.$isElementNode(r)&&!r.isInline()){const i=r.getChildren();if(i.length>0){const n=t.$copyNode(e);n.append(...i),r.append(n),a=!0}t.$insertNodeToNearestRootAtCaret(r,t.$rewindSiblingCaret(n),{$shouldSplit:()=>!1})}}function u(e,n,r){const[i,s]=e,l=e=>t.$isSiblingCaret(e)&&e.origin.is(n);if(!l(i)&&!l(s))return e;const o=t.$normalizeCaret(t.$getChildCaret(r,"next"));return[o,o.getFlipped()]}if(e.isAttached()){const t=e.getPreviousSibling();if(g(t)&&t.shouldMergeAdjacentLink(e))return r&&(r=u(r,t,e)),i&&(i=u(i,t,e)),t.append(...e.getChildren()),e.remove(),void s();const n=e.getNextSibling();g(n)&&e.shouldMergeAdjacentLink(n)&&(r&&(r=u(r,e,n)),i&&(i=u(i,e,n)),e.append(...n.getChildren()),n.remove(),a=!0)}if(a){if(!e.canBeEmpty()&&e.isEmpty()){const t=e.getParent();e.remove(),t&&t.isEmpty()&&t.remove()}s()}}function u(e){let n=null;if(t.isHTMLAnchorElement(e)){const t=e.textContent;(null!==t&&""!==t||e.children.length>0)&&(n=c(e.getAttribute("href")||"",{rel:e.getAttribute("rel"),target:e.getAttribute("target"),title:e.getAttribute("title")}))}return{node:n}}function c(e="",n){return t.$applyNodeReplacement(new s(e,n))}function g(e){return e instanceof s}class d extends s{__isUnlinked;constructor(e="",t={},n){super(e,t,n),this.__isUnlinked=void 0!==t.isUnlinked&&null!==t.isUnlinked&&t.isUnlinked}afterCloneFrom(e){super.afterCloneFrom(e),this.__isUnlinked=e.__isUnlinked}static getType(){return"autolink"}static clone(e){return new d(e.__url,{isUnlinked:e.__isUnlinked,rel:e.__rel,target:e.__target,title:e.__title},e.__key)}shouldMergeAdjacentLink(e){return!1}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(e){const t=this.getWritable();return t.__isUnlinked=e,t}createDOM(e){return this.__isUnlinked?t.$getDocument().createElement("span"):super.createDOM(e)}updateDOM(e,t,n){return super.updateDOM(e,t,n)||e.__isUnlinked!==this.__isUnlinked}static importJSON(e){return f().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setIsUnlinked(e.isUnlinked||!1)}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked}}insertNewAfter(e,t=!0){const n=f(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(n,t),n}}function f(e="",n){return t.$applyNodeReplacement(new d(e,n))}function h(e){return e instanceof d}const p=/* @__PURE__ */t.createCommand("TOGGLE_LINK_COMMAND");function _(e,n){if("element"===e.type){const r=e.getNode();t.$isElementNode(r)||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.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.`)}(252);return r.getChildren()[e.offset+n]||null}return null}function m(e,n={}){let r;if(e&&"object"==typeof e){const{url:t,...i}=e;r=t,n={...i,...n}}else r=e;const{target:i,title:s}=n,l=void 0===n.rel?"noreferrer":n.rel,o=t.$getSelection();if(null===o||!t.$isRangeSelection(o)&&!t.$isNodeSelection(o))return;if(t.$isNodeSelection(o)){const e=o.getNodes();if(0===e.length)return;return void e.forEach(e=>{if(null===r){const n=t.$findMatchingParent(e,e=>!h(e)&&g(e));n&&(n.insertBefore(e),0===n.getChildren().length&&n.remove())}else{const n=t.$findMatchingParent(e,e=>!h(e)&&g(e));if(n)n.setURL(r),void 0!==i&&n.setTarget(i),void 0!==l&&n.setRel(l);else{const t=c(r,{rel:l,target:i});e.insertBefore(t),t.append(e)}}})}if(o.isCollapsed()&&null===r)for(const e of o.getNodes()){const n=t.$findMatchingParent(e,e=>!h(e)&&g(e));return void(null!==n&&(n.getParentOrThrow().splice(n.getIndexWithinParent(),0,n.getChildren()),n.remove()))}const a=o.extract();if(null===r){const e=new Set;return void a.forEach(n=>{const r=t.$findMatchingParent(n,e=>!h(e)&&g(e));if(null!==r){const n=r.getKey();if(e.has(n))return;!function(e,n){const r=new Set(n.filter(t=>e.isParentOf(t)).map(e=>e.getKey())),i=e.getChildren(),s=i=>r.has(i.getKey())||t.$isElementNode(i)&&n.some(t=>e.isParentOf(t)&&i.isParentOf(t)),l=i.filter(s);if(l.length===i.length)return i.forEach(t=>e.insertBefore(t)),void e.remove();const o=i.findIndex(s),a=i.findLastIndex(s),u=0===o,c=a===i.length-1;if(u)l.forEach(t=>e.insertBefore(t));else if(c)for(let t=l.length-1;t>=0;t--)e.insertAfter(l[t]);else{for(let t=l.length-1;t>=0;t--)e.insertAfter(l[t]);const n=i.slice(a+1);if(n.length>0){const r=t.$copyNode(e);l[l.length-1].insertAfter(r),n.forEach(e=>r.append(e))}}}(r,a),e.add(n)}})}const u=new Set,d=e=>{u.has(e.getKey())||(u.add(e.getKey()),e.setURL(r),void 0!==i&&e.setTarget(i),void 0!==l&&e.setRel(l),void 0!==s&&e.setTitle(s))};if(1===a.length){const e=a[0],n=t.$findMatchingParent(e,g);if(null!==n)return d(n)}!function(e){const n=t.$getSelection();if(!t.$isRangeSelection(n))return e();const r=t.$normalizeSelection__EXPERIMENTAL(n),i=r.isBackward(),s=_(r.anchor,i?-1:0),l=_(r.focus,i?0:-1),o=e();if(s||l){const e=t.$getSelection();if(t.$isRangeSelection(e)){const n=e.clone();if(s){const e=s.getParent();e&&n.anchor.set(e.getKey(),s.getIndexWithinParent()+(i?1:0),"element")}if(l){const e=l.getParent();e&&n.focus.set(e.getKey(),l.getIndexWithinParent()+(i?0:1),"element")}t.$setSelection(t.$normalizeSelection__EXPERIMENTAL(n))}}}(()=>{let e=null;for(const n of a){if(!n.isAttached())continue;const o=t.$findMatchingParent(n,g);if(o){d(o);continue}if(t.$isElementNode(n)){if(!n.isInline())continue;if(g(n)){if(!(h(n)||null!==e&&e.getParentOrThrow().isParentOf(n))){d(n),e=n;continue}for(const e of n.getChildren())n.insertBefore(e);n.remove();continue}}const a=n.getPreviousSibling();g(a)&&a.is(e)?a.append(n):(e=c(r,{rel:l,target:i,title:s}),n.insertAfter(e),e.append(n))}})}const x=/^\+?[0-9\s()-]{5,}$/;function N(e){return e.match(/^[a-z][a-z0-9+.-]*:/i)||e.match(/^[/#.]/)?e:e.includes("@")?`mailto:${e}`:x.test(e)?`tel:${e}`:`https://${e}`}const k=[/* @__PURE__ */n.defineImportRule({$import:(e,t)=>{if(!t.textContent&&0===t.children.length)return[];const r=t.getAttribute("href")||"",i={rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")};return n.$distributeInlineWrapper(e.$importChildren(t),()=>c(r,i))},match:n.sel.tag("a"),name:"@lexical/link/a"})],$={attributes:void 0,validateUrl:void 0};function L(n,i){return t.mergeRegister(n.registerNodeTransform(s,a),n.registerCommand(p,e=>{const t=i.validateUrl.peek(),n=i.attributes.peek();if(null===e)return m(null),!0;if("string"==typeof e)return!(void 0!==t&&!t(e))&&(m(e,n),!0);{const{url:t,target:r,rel:i,title:s}=e;return m(t,{...n,rel:i,target:r,title:s}),!0}},t.COMMAND_PRIORITY_EDITOR),e.effect(()=>{const e=i.validateUrl.value;if(!e)return;const s=i.attributes.value;return n.registerCommand(t.PASTE_COMMAND,i=>{const l=t.$getSelection();if(!t.$isRangeSelection(l)||l.isCollapsed()||!r.objectKlassEquals(i,ClipboardEvent))return!1;if(null===i.clipboardData)return!1;const o=i.clipboardData.getData("text");if(!e(o))return!1;return!l.getNodes().some(e=>t.$isElementNode(e)||t.$isTextNode(e)&&!e.isSimpleText())&&(n.dispatchCommand(p,{...s,url:o}),i.preventDefault(),!0)},t.COMMAND_PRIORITY_LOW)}))}const T=/* @__PURE__ */t.defineExtension({build:(t,n,r)=>e.namedSignals(n),config:$,dependencies:[n.CoreImportExtension,/* @__PURE__ */t.configExtension(n.DOMImportExtension,{rules:k})],mergeConfig(e,n){const r=t.shallowMergeConfig(e,n);return e.attributes&&(r.attributes=t.shallowMergeConfig(e.attributes,r.attributes)),r},name:"@lexical/link/Link",nodes:()=>[s],register:(e,t,n)=>L(e,n.getOutput())}),S=/* @__PURE__ */t.defineExtension({dependencies:[T],name:"@lexical/link/Import"});function b(e,n,r={}){const i=r=>{const i=r.target;if(!t.isDOMNode(i))return;const s=t.getNearestEditorFromDOMNode(i);if(null===s)return;let l=null,o=null,a=!1;if(s.update(()=>{const e=t.$getNearestNodeFromDOMNode(i);if(null!==e){const r=t.$findMatchingParent(e,t.$isElementNode);if(!n.disabled.peek())if(g(r))a=h(r)&&r.getIsUnlinked(),l=r.sanitizeUrl(r.getURL()),o=r.getTarget();else{const e=function(e,t){let n=e;for(;null!=n;){if(t(n))return n;n=n.parentNode}return null}(i,t.isHTMLAnchorElement);null!==e&&(l=e.href,o=e.target)}}}),null===l||""===l||a)return;const u=e.read("latest",t.$getSelection);if(t.$isRangeSelection(u)&&!u.isCollapsed())return void r.preventDefault();const c="auxclick"===r.type&&1===r.button;window.open(l,n.newTab.peek()||c||r.metaKey||r.ctrlKey||"_blank"===o?"_blank":"_self"),r.preventDefault()},s=e=>{1===e.button&&i(e)};return e.registerRootListener(e=>{if(e)return t.registerEventListeners(e,{click:i,mouseup:s},r)})}const C=/* @__PURE__ */t.defineExtension({build:(t,n,r)=>e.namedSignals(n),config:/* @__PURE__ */t.safeCast({disabled:!1,newTab:!1}),dependencies:[T],name:"@lexical/link/ClickableLink",register:(e,t,n)=>b(e,n.getOutput())});function R(e,t=e=>e){return n=>{const r=e.exec(n);return null===r?null:{index:r.index,length:r[0].length,text:r[0],url:t(r[0])}}}const U=/((https?:\/\/(www\.)?)|(www\.))[-\p{L}\p{N}@:%._+~#=]{1,256}\.[\p{L}\p{N}]{1,6}(?:[-\p{L}\p{N}()@:%_+.~#?&//=]*[\p{L}\p{N}()@_~#?&//=])?/u,E=R(/(([^<>()[\]\\.,;:\s@"]{1,64}(\.[^<>()[\]\\.,;:\s@"]{1,64}){0,63})|(".{1,255}"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]{1,63}\.){1,127}[a-zA-Z]{2,63}))/,e=>`mailto:${e}`);function v(e,t){for(let n=0;n<t.length;n++){const r=t[n](e);if(r)return r}return null}const A=/[.,;\s]/;function O(e,t){return t.test(e)}function M(e,t){return O(e[e.length-1],t)}function P(e,t){return O(e[0],t)}function I(e,n){let r=e.getPreviousSibling();return t.$isElementNode(r)&&(r=r.getLastDescendant()),null===r||t.$isLineBreakNode(r)||t.$isTextNode(r)&&M(r.getTextContent(),n)}function y(e,n){let r=e.getNextSibling();return t.$isElementNode(r)&&(r=r.getFirstDescendant()),null===r||t.$isLineBreakNode(r)||t.$isTextNode(r)&&P(r.getTextContent(),n)}function D(e,t,n,r,i){if(!(e>0?O(r[e-1],n):I(i[0],n)))return!1;return t<r.length?O(r[t],n):y(i[i.length-1],n)}function w(e,t,n){const r=[],i=[],s=[];let l=0,o=0;const a=[...e];for(;a.length>0;){const e=a[0],u=e.getTextContent().length,c=o;o+u<=t?(r.push(e),l+=u):c>=n?s.push(e):i.push(e),o+=u,a.shift()}return[l,r,i,s]}function F(e,n,r,i){const s=f(i.url,i.attributes);if(1===e.length){let l,o=e[0];0===n?[l,o]=o.splitText(r):[,l,o]=o.splitText(n,r);const a=t.$createTextNode(i.text);return a.setFormat(l.getFormat()),a.setDetail(l.getDetail()),a.setStyle(l.getStyle()),s.append(a),l.replace(s),o}if(e.length>1){const i=e[0];let l,o=i.getTextContent().length;0===n?l=i:[,l]=i.splitText(n);const a=[];let u;for(let t=1;t<e.length;t++){const n=e[t],i=n.getTextContent().length,s=o;if(s<r)if(o+i<=r)a.push(n);else{const[e,t]=n.splitText(r-s);a.push(e),u=t}o+=i}const c=t.$getSelection(),g=c?c.getNodes().find(t.$isTextNode):void 0,d=t.$createTextNode(l.getTextContent());return d.setFormat(l.getFormat()),d.setDetail(l.getDetail()),d.setStyle(l.getStyle()),s.append(d,...a),g&&g===l&&(t.$isRangeSelection(c)?d.select(c.anchor.offset,c.focus.offset):t.$isNodeSelection(c)&&d.select(0,d.getTextContent().length)),l.replace(s),u}}function W(e,n,r,i){const s=e.getChildren(),l=s.length;for(let n=0;n<l;n++){const i=s[n];if(!t.$isTextNode(i)||!i.isSimpleText())return z(e),void r(null,e.getURL())}const o=e.getTextContent(),a=v(o,n);if(null===a||a.text!==o)return z(e),void r(null,e.getURL());if(!I(e,i)||!y(e,i))return z(e),void r(null,e.getURL());const u=e.getURL();if(u!==a.url&&(e.setURL(a.url),r(a.url,u)),a.attributes){const t=e.getRel();t!==a.attributes.rel&&(e.setRel(a.attributes.rel||null),r(a.attributes.rel||null,t));const n=e.getTarget();n!==a.attributes.target&&(e.setTarget(a.attributes.target||null),r(a.attributes.target||null,n))}}function z(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())}const J={changeHandlers:[],excludeParents:[],matchers:[],separatorRegex:A};function K(e,n=J){const{matchers:r,changeHandlers:i,excludeParents:s,separatorRegex:l=A}=n,o=(e,t)=>{for(const n of i)n(e,t)};return t.mergeRegister(e.registerNodeTransform(t.TextNode,e=>{const n=e.getParentOrThrow(),i=e.getPreviousSibling();if(h(n))W(n,r,o,l);else if(!g(n)&&!s.some(e=>e(n))){if(e.isSimpleText()&&(P(e.getTextContent(),l)||!h(i))){const n=function(e){const n=[e];let r=e.getNextSibling();for(;null!==r&&t.$isTextNode(r)&&r.isSimpleText()&&(n.push(r),!/[\s]/.test(r.getTextContent()));)r=r.getNextSibling();return n}(e);!function(e,t,n,r){for(const t of e){const e=t.getParent();if(h(e)&&!e.getIsUnlinked())return}let i=[...e];const s=i.map(e=>e.getTextContent()).join("");let l,o=s,a=0;for(;(l=v(o,t))&&null!==l;){const e=l.index,t=e+l.length;if(D(a+e,a+t,r,s,i)){const[r,,s,u]=w(i,a+e,a+t);let c=!1;for(const e of s){const t=e.getParent();if(h(t)&&!t.getIsUnlinked()){c=!0;break}}if(c){a+=t,o=o.substring(t);continue}const g=F(s,a+e-r,a+t-r,l);i=g?[g,...u]:u,n(l.url,null),a=0}else a+=t;o=o.substring(t)}}(n,r,o,l)}!function(e,t,n,r){const i=e.getParent(),s=e.getPreviousSibling(),l=e.getNextSibling(),o=e.getTextContent();if(!h(i)||i.getIsUnlinked()){if(h(s)&&!s.getIsUnlinked()&&s.is(e.getPreviousSibling())&&e.getParent()===s.getParent()){if(!P(o,r))return z(s),void n(null,s.getURL());if(a=o,s.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(a):/^\.[a-zA-Z0-9]{1,}/.test(a)){const i=s.getTextContent()+o,l=v(i,t);null!==l&&l.text===i&&(s.append(e),W(s,t,n,r),n(null,s.getURL()))}}var a;!h(l)||l.getIsUnlinked()||M(o,r)||l.is(e.getNextSibling())&&e.getParent()===l.getParent()&&(z(l),n(null,l.getURL()))}}(e,r,o,l)}}),e.registerCommand(p,e=>{const n=t.$getSelection();if(null!==e||!t.$isRangeSelection(n))return!1;return n.extract().forEach(e=>{const t=e.getParent();h(t)&&(t.setIsUnlinked(!t.getIsUnlinked()),t.markDirty())}),!1},t.COMMAND_PRIORITY_LOW))}const B=/* @__PURE__ */t.defineExtension({config:J,dependencies:[T],mergeConfig(e,n){const r=t.shallowMergeConfig(e,n);for(const t of["matchers","changeHandlers","excludeParents"]){const i=n[t];Array.isArray(i)&&(r[t]=[...e[t],...i])}return r},name:"@lexical/link/AutoLink",nodes:[d],register:K});exports.$createAutoLinkNode=f,exports.$createLinkNode=c,exports.$isAutoLinkNode=h,exports.$isLinkNode=g,exports.$toggleLink=m,exports.AutoLinkExtension=B,exports.AutoLinkNode=d,exports.ClickableLinkExtension=C,exports.LinkExtension=T,exports.LinkImportExtension=S,exports.LinkImportRules=k,exports.LinkNode=s,exports.TOGGLE_LINK_COMMAND=p,exports.autoLinkEmailMatcher=E,exports.autoLinkUrlMatcher=e=>{const t=U.exec(e);if(null===t)return null;let n=t[0],r=0;for(const e of n)"("===e?r++:")"===e&&r--;for(;r<0&&n.endsWith(")");)n=n.slice(0,-1),r++;return{index:t.index,length:n.length,text:n,url:n.startsWith("http")?n:`https://${n}`}},exports.createLinkMatcherWithRegExp=R,exports.formatUrl=N,exports.registerAutoLink=K,exports.registerClickableLink=b,exports.registerLink=L;
|
|
9
|
+
"use strict";var e=require("@lexical/extension"),t=require("lexical"),n=require("@lexical/html"),r=require("@lexical/utils");const i=new Set(["http:","https:","mailto:","sms:","tel:"]);class s extends t.ElementNode{__url;__target;__rel;__title;static getType(){return"link"}static clone(e){return new s(e.__url,{rel:e.__rel,target:e.__target,title:e.__title},e.__key)}constructor(e="",t={},n){super(n);const{target:r=null,rel:i=null,title:s=null}=t;this.__url=e,this.__target=r,this.__rel=i,this.__title=s}afterCloneFrom(e){super.afterCloneFrom(e),this.__url=e.__url,this.__rel=e.__rel,this.__target=e.__target,this.__title=e.__title}createDOM(e){const n=t.$getDocument().createElement("a");return this.updateLinkDOM(null,n,e),t.addClassNamesToElement(n,e.theme.link),n}updateLinkDOM(e,n,r){if(t.isHTMLAnchorElement(n)){e&&e.__url===this.__url||(n.href=this.sanitizeUrl(this.__url));for(const t of["target","rel","title"]){const r=`__${t}`,i=this[r];e&&e[r]===i||(i?n[t]=i:n.removeAttribute(t))}}}updateDOM(e,t,n){return this.updateLinkDOM(e,t,n),!1}static importDOM(){return{a:e=>({conversion:u,priority:1})}}static importJSON(e){return c().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setURL(e.url).setRel(e.rel||null).setTarget(e.target||null).setTitle(e.title||null)}sanitizeUrl(e){const t=e;e=N(e);try{const t=new URL(N(e));if(!i.has(t.protocol))return"about:blank"}catch(e){const n=t.replace(/[\u0000-\u001F\u007F\s]/g,"").match(/^([a-z][a-z0-9+.-]*):/i);if(null!=n&&!i.has(`${n[1].toLowerCase()}:`))return"about:blank"}return e}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),url:this.getURL()}}getURL(){return this.getLatest().__url}setURL(e){const t=this.getWritable();return t.__url=e,t}getTarget(){return this.getLatest().__target}setTarget(e){const t=this.getWritable();return t.__target=e,t}getRel(){return this.getLatest().__rel}setRel(e){const t=this.getWritable();return t.__rel=e,t}getTitle(){return this.getLatest().__title}setTitle(e){const t=this.getWritable();return t.__title=e,t}insertNewAfter(e,n=!0){const r=t.$copyNode(this);return this.insertAfter(r,n),r}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(e,n,r){if(!t.$isRangeSelection(n))return!1;const i=n.anchor.getNode(),s=n.focus.getNode();return(this.is(i)||this.isParentOf(i))&&(this.is(s)||this.isParentOf(s))&&n.getTextContent().length>0}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")||this.__url.startsWith("http://")}shouldMergeAdjacentLink(e){return this.getType()===e.getType()&&this.__url===e.__url&&this.__target===e.__target&&this.__rel===e.__rel&&this.__title===e.__title}}function l(e){const n=t.$caretFromPoint(e,"next");return[n,n.getFlipped()]}function o(e,n){for(const r of n)if(r.origin.isAttached()){const n=t.$normalizeCaret(r);return void t.$setPointFromCaret(e,n)}}function a(e){const n=t.$getSelection();let r=null,i=null;function s(){t.$isRangeSelection(n)&&(o(n.anchor,r),o(n.focus,i),t.$normalizeSelection__EXPERIMENTAL(n))}t.$isRangeSelection(n)&&(r=l(n.anchor),i=l(n.focus));let a=!1;for(const n of t.$getChildCaret(e,"next")){const r=n.origin;if(t.$isElementNode(r)&&!r.isInline()){const i=r.getChildren();if(i.length>0){const n=t.$copyNode(e);n.append(...i),r.append(n),a=!0}t.$insertNodeToNearestRootAtCaret(r,t.$rewindSiblingCaret(n),{$shouldSplit:()=>!1})}}function u(e,n,r){const[i,s]=e,l=e=>t.$isSiblingCaret(e)&&e.origin.is(n);if(!l(i)&&!l(s))return e;const o=t.$normalizeCaret(t.$getChildCaret(r,"next"));return[o,o.getFlipped()]}if(e.isAttached()){const t=e.getPreviousSibling();if(g(t)&&t.shouldMergeAdjacentLink(e))return r&&(r=u(r,t,e)),i&&(i=u(i,t,e)),t.append(...e.getChildren()),e.remove(),void s();const n=e.getNextSibling();g(n)&&e.shouldMergeAdjacentLink(n)&&(r&&(r=u(r,e,n)),i&&(i=u(i,e,n)),e.append(...n.getChildren()),n.remove(),a=!0)}if(a){if(!e.canBeEmpty()&&e.isEmpty()){const t=e.getParent();e.remove(),t&&t.isEmpty()&&t.remove()}s()}}function u(e){let n=null;if(t.isHTMLAnchorElement(e)){const t=e.textContent;(null!==t&&""!==t||e.children.length>0)&&(n=c(e.getAttribute("href")||"",{rel:e.getAttribute("rel"),target:e.getAttribute("target"),title:e.getAttribute("title")}))}return{node:n}}function c(e="",n){return t.$applyNodeReplacement(new s(e,n))}function g(e){return e instanceof s}class d extends s{__isUnlinked;constructor(e="",t={},n){super(e,t,n),this.__isUnlinked=void 0!==t.isUnlinked&&null!==t.isUnlinked&&t.isUnlinked}afterCloneFrom(e){super.afterCloneFrom(e),this.__isUnlinked=e.__isUnlinked}static getType(){return"autolink"}static clone(e){return new d(e.__url,{isUnlinked:e.__isUnlinked,rel:e.__rel,target:e.__target,title:e.__title},e.__key)}shouldMergeAdjacentLink(e){return!1}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(e){const t=this.getWritable();return t.__isUnlinked=e,t}createDOM(e){return this.__isUnlinked?t.$getDocument().createElement("span"):super.createDOM(e)}updateDOM(e,t,n){return super.updateDOM(e,t,n)||e.__isUnlinked!==this.__isUnlinked}static importJSON(e){return f().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setIsUnlinked(e.isUnlinked||!1)}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked}}insertNewAfter(e,t=!0){const n=f(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(n,t),n}}function f(e="",n){return t.$applyNodeReplacement(new d(e,n))}function h(e){return e instanceof d}const p=/* @__PURE__ */t.createCommand("TOGGLE_LINK_COMMAND");function _(e,n){if("element"===e.type){const r=e.getNode();t.$isElementNode(r)||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.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.`)}(252);return r.getChildren()[e.offset+n]||null}return null}function m(e,n={}){let r;if(e&&"object"==typeof e){const{url:t,...i}=e;r=t,n={...i,...n}}else r=e;const{target:i,title:s}=n,l=void 0===n.rel?"noreferrer":n.rel,o=t.$getSelection();if(null===o||!t.$isRangeSelection(o)&&!t.$isNodeSelection(o))return;if(t.$isNodeSelection(o)){const e=o.getNodes();if(0===e.length)return;return void e.forEach(e=>{if(null===r){const n=t.$findMatchingParent(e,e=>!h(e)&&g(e));n&&(n.insertBefore(e),0===n.getChildren().length&&n.remove())}else{const n=t.$findMatchingParent(e,e=>!h(e)&&g(e));if(n)n.setURL(r),void 0!==i&&n.setTarget(i),void 0!==l&&n.setRel(l);else{const t=c(r,{rel:l,target:i});e.insertBefore(t),t.append(e)}}})}if(o.isCollapsed()&&null===r)for(const e of o.getNodes()){const n=t.$findMatchingParent(e,e=>!h(e)&&g(e));return void(null!==n&&(n.getParentOrThrow().splice(n.getIndexWithinParent(),0,n.getChildren()),n.remove()))}const a=o.extract();if(null===r){const e=new Set;return void a.forEach(n=>{const r=t.$findMatchingParent(n,e=>!h(e)&&g(e));if(null!==r){const n=r.getKey();if(e.has(n))return;!function(e,n){const r=new Set(n.filter(t=>e.isParentOf(t)).map(e=>e.getKey())),i=e.getChildren(),s=i=>r.has(i.getKey())||t.$isElementNode(i)&&n.some(t=>e.isParentOf(t)&&i.isParentOf(t)),l=i.filter(s);if(l.length===i.length)return i.forEach(t=>e.insertBefore(t)),void e.remove();const o=i.findIndex(s),a=i.findLastIndex(s),u=0===o,c=a===i.length-1;if(u)l.forEach(t=>e.insertBefore(t));else if(c)for(let t=l.length-1;t>=0;t--)e.insertAfter(l[t]);else{for(let t=l.length-1;t>=0;t--)e.insertAfter(l[t]);const n=i.slice(a+1);if(n.length>0){const r=t.$copyNode(e);l[l.length-1].insertAfter(r),n.forEach(e=>r.append(e))}}}(r,a),e.add(n)}})}const u=new Set,d=e=>{u.has(e.getKey())||(u.add(e.getKey()),e.setURL(r),void 0!==i&&e.setTarget(i),void 0!==l&&e.setRel(l),void 0!==s&&e.setTitle(s))};if(1===a.length){const e=a[0],n=t.$findMatchingParent(e,g);if(null!==n)return d(n)}!function(e){const n=t.$getSelection();if(!t.$isRangeSelection(n))return e();const r=t.$normalizeSelection__EXPERIMENTAL(n),i=r.isBackward(),s=_(r.anchor,i?-1:0),l=_(r.focus,i?0:-1),o=e();if(s||l){const e=t.$getSelection();if(t.$isRangeSelection(e)){const n=e.clone();if(s){const e=s.getParent();e&&n.anchor.set(e.getKey(),s.getIndexWithinParent()+(i?1:0),"element")}if(l){const e=l.getParent();e&&n.focus.set(e.getKey(),l.getIndexWithinParent()+(i?0:1),"element")}t.$setSelection(t.$normalizeSelection__EXPERIMENTAL(n))}}}(()=>{let e=null;for(const n of a){if(!n.isAttached())continue;const o=t.$findMatchingParent(n,g);if(o){d(o);continue}if(t.$isElementNode(n)){if(!n.isInline())continue;if(g(n)){if(!(h(n)||null!==e&&e.getParentOrThrow().isParentOf(n))){d(n),e=n;continue}for(const e of n.getChildren())n.insertBefore(e);n.remove();continue}}const a=n.getPreviousSibling();g(a)&&a.is(e)?a.append(n):(e=c(r,{rel:l,target:i,title:s}),n.insertAfter(e),e.append(n))}})}const x=/^\+?[0-9\s()-]{5,}$/;function N(e){return e.match(/^[a-z][a-z0-9+.-]*:/i)||e.match(/^[/#.]/)?e:e.includes("@")?`mailto:${e}`:x.test(e)?`tel:${e}`:`https://${e}`}const k=[/* @__PURE__ */n.defineImportRule({$import:(e,t)=>{if(!t.textContent&&0===t.children.length)return[];const r=t.getAttribute("href")||"",i={rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")};return n.$distributeInlineWrapper(e.$importChildren(t),()=>c(r,i))},match:n.sel.tag("a"),name:"@lexical/link/a"})],$={attributes:void 0,validateUrl:void 0};function L(n,i){return t.mergeRegister(n.registerNodeTransform(s,a),n.registerCommand(p,e=>{const t=i.validateUrl.peek(),n=i.attributes.peek();if(null===e)return m(null),!0;if("string"==typeof e)return!(void 0!==t&&!t(e))&&(m(e,n),!0);{const{url:t,target:r,rel:i,title:s}=e;return m(t,{...n,rel:i,target:r,title:s}),!0}},t.COMMAND_PRIORITY_EDITOR),e.effect(()=>{const e=i.validateUrl.value;if(!e)return;const s=i.attributes.value;return n.registerCommand(t.PASTE_COMMAND,i=>{const l=t.$getSelection();if(!t.$isRangeSelection(l)||l.isCollapsed()||!r.objectKlassEquals(i,ClipboardEvent))return!1;if(null===i.clipboardData)return!1;const o=i.clipboardData.getData("text");if(!e(o))return!1;return!l.getNodes().some(e=>t.$isElementNode(e)||t.$isTextNode(e)&&!e.isSimpleText())&&(n.dispatchCommand(p,{...s,url:o}),i.preventDefault(),!0)},t.COMMAND_PRIORITY_LOW)}))}const T=/* @__PURE__ */t.defineExtension({build:(t,n,r)=>e.namedSignals(n),config:$,dependencies:[n.CoreImportExtension,/* @__PURE__ */t.configExtension(n.DOMImportExtension,{rules:k})],mergeConfig(e,n){const r=t.shallowMergeConfig(e,n);return e.attributes&&(r.attributes=t.shallowMergeConfig(e.attributes,r.attributes)),r},name:"@lexical/link/Link",nodes:()=>[s],register:(e,t,n)=>L(e,n.getOutput())}),S=/* @__PURE__ */t.defineExtension({dependencies:[T],name:"@lexical/link/Import"});function b(e,n,r={}){const i=r=>{const i=r.target;if(!t.isDOMNode(i))return;const s=t.getNearestEditorFromDOMNode(i);if(null===s)return;let l=null,o=null,a=!1;if(s.update(()=>{const e=t.$getNearestNodeFromDOMNode(i);if(null!==e){const r=t.$findMatchingParent(e,t.$isElementNode);if(!n.disabled.peek())if(g(r))a=h(r)&&r.getIsUnlinked(),l=r.sanitizeUrl(r.getURL()),o=r.getTarget();else{const e=function(e,t){let n=e;for(;null!=n;){if(t(n))return n;n=n.parentNode}return null}(i,t.isHTMLAnchorElement);null!==e&&(l=e.href,o=e.target)}}}),null===l||""===l||a)return;const u=e.read("latest",t.$getSelection);if(t.$isRangeSelection(u)&&!u.isCollapsed())return void r.preventDefault();const c="auxclick"===r.type&&1===r.button;window.open(l,n.newTab.peek()||c||r.metaKey||r.ctrlKey||"_blank"===o?"_blank":"_self"),r.preventDefault()},s=e=>{1===e.button&&i(e)};return e.registerRootListener(e=>{if(e)return t.registerEventListeners(e,{click:i,mouseup:s},r)})}const C=/* @__PURE__ */t.defineExtension({build:(t,n,r)=>e.namedSignals(n),config:/* @__PURE__ */t.safeCast({disabled:!1,newTab:!1}),dependencies:[T],name:"@lexical/link/ClickableLink",register:(e,t,n)=>b(e,n.getOutput())});function R(e,t=e=>e){return n=>{const r=e.exec(n);return null===r?null:{index:r.index,length:r[0].length,text:r[0],url:t(r[0])}}}const U=/((https?:\/\/(www\.)?)|(www\.))[-\p{L}\p{N}@:%._+~#=]{1,256}\.[\p{L}\p{N}]{1,6}(?:[-\p{L}\p{N}()@:%_+.~#?&//=]*[\p{L}\p{N}()@_~#?&//=])?/u,E=R(/(([^<>()[\]\\.,;:\s@"]{1,64}(\.[^<>()[\]\\.,;:\s@"]{1,64}){0,63})|(".{1,255}"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]{1,63}\.){1,127}[a-zA-Z]{2,63}))/,e=>`mailto:${e}`);function v(e,t){for(let n=0;n<t.length;n++){const r=t[n](e);if(r)return r}return null}const A=/[.,;\s]/;function O(e,t){return t.test(e)}function M(e,t){return O(e[e.length-1],t)}function P(e,t){return O(e[0],t)}function I(e,n){let r=e.getPreviousSibling();return t.$isElementNode(r)&&(r=r.getLastDescendant()),null===r||t.$isLineBreakNode(r)||t.$isTextNode(r)&&M(r.getTextContent(),n)}function y(e,n){let r=e.getNextSibling();return t.$isElementNode(r)&&(r=r.getFirstDescendant()),null===r||t.$isLineBreakNode(r)||t.$isTextNode(r)&&P(r.getTextContent(),n)}function D(e,t,n,r,i){if(!(e>0?O(r[e-1],n):I(i[0],n)))return!1;return t<r.length?O(r[t],n):y(i[i.length-1],n)}function w(e,t,n){const r=[],i=[],s=[];let l=0,o=0;const a=[...e];for(;a.length>0;){const e=a[0],u=e.getTextContent().length,c=o;o+u<=t?(r.push(e),l+=u):c>=n?s.push(e):i.push(e),o+=u,a.shift()}return[l,r,i,s]}function F(e,n,r,i){const s=f(i.url,i.attributes);if(1===e.length){let l,o=e[0];0===n?[l,o]=o.splitText(r):[,l,o]=o.splitText(n,r);const a=t.$createTextNode(i.text);return a.setFormat(l.getFormat()),a.setDetail(l.getDetail()),a.setStyle(l.getStyle()),s.append(a),l.replace(s),o}if(e.length>1){const i=e[0];let l,o=i.getTextContent().length;0===n?l=i:[,l]=i.splitText(n);const a=[];let u;for(let t=1;t<e.length;t++){const n=e[t],i=n.getTextContent().length,s=o;if(s<r)if(o+i<=r)a.push(n);else{const[e,t]=n.splitText(r-s);a.push(e),u=t}o+=i}const c=t.$getSelection(),g=c?c.getNodes().find(t.$isTextNode):void 0,d=t.$createTextNode(l.getTextContent());return d.setFormat(l.getFormat()),d.setDetail(l.getDetail()),d.setStyle(l.getStyle()),s.append(d,...a),g&&g===l&&(t.$isRangeSelection(c)?d.select(c.anchor.offset,c.focus.offset):t.$isNodeSelection(c)&&d.select(0,d.getTextContent().length)),l.replace(s),u}}function W(e,n,r,i){const s=e.getChildren(),l=s.length;for(let n=0;n<l;n++){const i=s[n];if(!t.$isTextNode(i)||!i.isSimpleText())return z(e),void r(null,e.getURL())}const o=e.getTextContent(),a=v(o,n);if(null===a||a.text!==o)return z(e),void r(null,e.getURL());if(!I(e,i)||!y(e,i))return z(e),void r(null,e.getURL());const u=e.getURL();if(u!==a.url&&(e.setURL(a.url),r(a.url,u)),a.attributes){const t=e.getRel();t!==a.attributes.rel&&(e.setRel(a.attributes.rel||null),r(a.attributes.rel||null,t));const n=e.getTarget();n!==a.attributes.target&&(e.setTarget(a.attributes.target||null),r(a.attributes.target||null,n))}}function z(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())}const J={changeHandlers:[],excludeParents:[],matchers:[],separatorRegex:A};function K(e,n=J){const{matchers:r,changeHandlers:i,excludeParents:s,separatorRegex:l=A}=n,o=(e,t)=>{for(const n of i)n(e,t)};return t.mergeRegister(e.registerNodeTransform(t.TextNode,e=>{const n=e.getParentOrThrow(),i=e.getPreviousSibling();if(h(n))W(n,r,o,l);else if(!g(n)&&!s.some(e=>e(n))){if(e.isSimpleText()&&(P(e.getTextContent(),l)||!h(i))){const n=function(e){const n=[e];let r=e.getNextSibling();for(;null!==r&&t.$isTextNode(r)&&r.isSimpleText()&&(n.push(r),!/[\s]/.test(r.getTextContent()));)r=r.getNextSibling();return n}(e);!function(e,t,n,r){for(const t of e){const e=t.getParent();if(h(e)&&!e.getIsUnlinked())return}let i=[...e];const s=i.map(e=>e.getTextContent()).join("");let l,o=s,a=0;for(;(l=v(o,t))&&null!==l;){const e=l.index,t=e+l.length;if(D(a+e,a+t,r,s,i)){const[r,,s,u]=w(i,a+e,a+t);let c=!1;for(const e of s){const t=e.getParent();if(h(t)&&!t.getIsUnlinked()){c=!0;break}}if(c){a+=t,o=o.substring(t);continue}const g=F(s,a+e-r,a+t-r,l);i=g?[g,...u]:u,n(l.url,null),a=0}else a+=t;o=o.substring(t)}}(n,r,o,l)}!function(e,t,n,r){const i=e.getParent(),s=e.getPreviousSibling(),l=e.getNextSibling(),o=e.getTextContent();if(!h(i)||i.getIsUnlinked()){if(h(s)&&!s.getIsUnlinked()&&s.is(e.getPreviousSibling())&&e.getParent()===s.getParent()){if(!P(o,r))return z(s),void n(null,s.getURL());if(a=o,s.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(a):/^\.[a-zA-Z0-9]{1,}/.test(a)){const i=s.getTextContent()+o,l=v(i,t);null!==l&&l.text===i&&(s.append(e),W(s,t,n,r),n(null,s.getURL()))}}var a;!h(l)||l.getIsUnlinked()||M(o,r)||l.is(e.getNextSibling())&&e.getParent()===l.getParent()&&(z(l),n(null,l.getURL()))}}(e,r,o,l)}}),e.registerCommand(p,e=>{const n=t.$getSelection();if(null!==e||!t.$isRangeSelection(n))return!1;return n.extract().forEach(e=>{const t=e.getParent();h(t)&&(t.setIsUnlinked(!t.getIsUnlinked()),t.markDirty())}),!1},t.COMMAND_PRIORITY_LOW))}const B=/* @__PURE__ */t.defineExtension({config:J,dependencies:[T],mergeConfig(e,n){const r=t.shallowMergeConfig(e,n);for(const t of["matchers","changeHandlers","excludeParents"]){const i=n[t];Array.isArray(i)&&(r[t]=[...e[t],...i])}return r},name:"@lexical/link/AutoLink",nodes:[d],register:K});exports.$createAutoLinkNode=f,exports.$createLinkNode=c,exports.$isAutoLinkNode=h,exports.$isLinkNode=g,exports.$toggleLink=m,exports.AutoLinkExtension=B,exports.AutoLinkNode=d,exports.ClickableLinkExtension=C,exports.LinkExtension=T,exports.LinkImportExtension=S,exports.LinkImportRules=k,exports.LinkNode=s,exports.TOGGLE_LINK_COMMAND=p,exports.autoLinkEmailMatcher=E,exports.autoLinkUrlMatcher=e=>{const t=U.exec(e);if(null===t)return null;let n=t[0],r=0;for(const e of n)"("===e?r++:")"===e&&r--;for(;r<0&&n.endsWith(")");)n=n.slice(0,-1),r++;return{index:t.index,length:n.length,text:n,url:n.startsWith("http")?n:`https://${n}`}},exports.createLinkMatcherWithRegExp=R,exports.formatUrl=N,exports.registerAutoLink=K,exports.registerClickableLink=b,exports.registerLink=L;
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import{namedSignals as t,effect as e}from"@lexical/extension";import{ElementNode as n,$getDocument as r,addClassNamesToElement as i,isHTMLAnchorElement as l,$copyNode as s,$isRangeSelection as o,$applyNodeReplacement as u,createCommand as a,$getSelection as c,$isNodeSelection as g,$findMatchingParent as f,$normalizeSelection__EXPERIMENTAL as d,$setSelection as h,$getChildCaret as p,$isElementNode as _,$insertNodeToNearestRootAtCaret as m,$rewindSiblingCaret as x,$caretFromPoint as k,$normalizeCaret as b,$isSiblingCaret as U,$setPointFromCaret as v,defineExtension as T,shallowMergeConfig as C,configExtension as L,mergeRegister as S,COMMAND_PRIORITY_EDITOR as N,PASTE_COMMAND as O,$isTextNode as A,COMMAND_PRIORITY_LOW as P,safeCast as y,registerEventListeners as R,isDOMNode as w,getNearestEditorFromDOMNode as I,$getNearestNodeFromDOMNode as D,TextNode as M,$isLineBreakNode as E,$createTextNode as F}from"lexical";import{defineImportRule as W,sel as J,$distributeInlineWrapper as $,CoreImportExtension as K,DOMImportExtension as z}from"@lexical/html";import{objectKlassEquals as B}from"@lexical/utils";const j=new Set(["http:","https:","mailto:","sms:","tel:"]);class Z extends n{__url;__target;__rel;__title;static getType(){return"link"}static clone(t){return new Z(t.__url,{rel:t.__rel,target:t.__target,title:t.__title},t.__key)}constructor(t="",e={},n){super(n);const{target:r=null,rel:i=null,title:l=null}=e;this.__url=t,this.__target=r,this.__rel=i,this.__title=l}afterCloneFrom(t){super.afterCloneFrom(t),this.__url=t.__url,this.__rel=t.__rel,this.__target=t.__target,this.__title=t.__title}createDOM(t){const e=r().createElement("a");return this.updateLinkDOM(null,e,t),i(e,t.theme.link),e}updateLinkDOM(t,e,n){if(l(e)){t&&t.__url===this.__url||(e.href=this.sanitizeUrl(this.__url));for(const n of["target","rel","title"]){const r=`__${n}`,i=this[r];t&&t[r]===i||(i?e[n]=i:e.removeAttribute(n))}}}updateDOM(t,e,n){return this.updateLinkDOM(t,e,n),!1}static importDOM(){return{a:t=>({conversion:Q,priority:1})}}static importJSON(t){return V().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setURL(t.url).setRel(t.rel||null).setTarget(t.target||null).setTitle(t.title||null)}sanitizeUrl(t){t=st(t);try{const e=new URL(st(t));if(!j.has(e.protocol))return"about:blank"}catch(e){return t}return t}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),url:this.getURL()}}getURL(){return this.getLatest().__url}setURL(t){const e=this.getWritable();return e.__url=t,e}getTarget(){return this.getLatest().__target}setTarget(t){const e=this.getWritable();return e.__target=t,e}getRel(){return this.getLatest().__rel}setRel(t){const e=this.getWritable();return e.__rel=t,e}getTitle(){return this.getLatest().__title}setTitle(t){const e=this.getWritable();return e.__title=t,e}insertNewAfter(t,e=!0){const n=s(this);return this.insertAfter(n,e),n}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(t,e,n){if(!o(e))return!1;const r=e.anchor.getNode(),i=e.focus.getNode();return(this.is(r)||this.isParentOf(r))&&(this.is(i)||this.isParentOf(i))&&e.getTextContent().length>0}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")||this.__url.startsWith("http://")}shouldMergeAdjacentLink(t){return this.getType()===t.getType()&&this.__url===t.__url&&this.__target===t.__target&&this.__rel===t.__rel&&this.__title===t.__title}}function H(t){const e=k(t,"next");return[e,e.getFlipped()]}function G(t,e){for(const n of e)if(n.origin.isAttached()){const e=b(n);return void v(t,e)}}function q(t){const e=c();let n=null,r=null;function i(){o(e)&&(G(e.anchor,n),G(e.focus,r),d(e))}o(e)&&(n=H(e.anchor),r=H(e.focus));let l=!1;for(const e of p(t,"next")){const n=e.origin;if(_(n)&&!n.isInline()){const r=n.getChildren();if(r.length>0){const e=s(t);e.append(...r),n.append(e),l=!0}m(n,x(e),{$shouldSplit:()=>!1})}}function u(t,e,n){const[r,i]=t,l=t=>U(t)&&t.origin.is(e);if(!l(r)&&!l(i))return t;const s=b(p(n,"next"));return[s,s.getFlipped()]}if(t.isAttached()){const e=t.getPreviousSibling();if(X(e)&&e.shouldMergeAdjacentLink(t))return n&&(n=u(n,e,t)),r&&(r=u(r,e,t)),e.append(...t.getChildren()),t.remove(),void i();const s=t.getNextSibling();X(s)&&t.shouldMergeAdjacentLink(s)&&(n&&(n=u(n,t,s)),r&&(r=u(r,t,s)),t.append(...s.getChildren()),s.remove(),l=!0)}if(l){if(!t.canBeEmpty()&&t.isEmpty()){const e=t.getParent();t.remove(),e&&e.isEmpty()&&e.remove()}i()}}function Q(t){let e=null;if(l(t)){const n=t.textContent;(null!==n&&""!==n||t.children.length>0)&&(e=V(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}))}return{node:e}}function V(t="",e){return u(new Z(t,e))}function X(t){return t instanceof Z}class Y extends Z{__isUnlinked;constructor(t="",e={},n){super(t,e,n),this.__isUnlinked=void 0!==e.isUnlinked&&null!==e.isUnlinked&&e.isUnlinked}afterCloneFrom(t){super.afterCloneFrom(t),this.__isUnlinked=t.__isUnlinked}static getType(){return"autolink"}static clone(t){return new Y(t.__url,{isUnlinked:t.__isUnlinked,rel:t.__rel,target:t.__target,title:t.__title},t.__key)}shouldMergeAdjacentLink(t){return!1}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(t){const e=this.getWritable();return e.__isUnlinked=t,e}createDOM(t){return this.__isUnlinked?r().createElement("span"):super.createDOM(t)}updateDOM(t,e,n){return super.updateDOM(t,e,n)||t.__isUnlinked!==this.__isUnlinked}static importJSON(t){return tt().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setIsUnlinked(t.isUnlinked||!1)}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked}}insertNewAfter(t,e=!0){const n=tt(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(n,e),n}}function tt(t="",e){return u(new Y(t,e))}function et(t){return t instanceof Y}const nt=/* @__PURE__ */a("TOGGLE_LINK_COMMAND");function rt(t,e){if("element"===t.type){const n=t.getNode();_(n)||function(t,...e){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",t);for(const t of e)r.append("v",t);throw n.search=r.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(252);return n.getChildren()[t.offset+e]||null}return null}function it(t,e={}){let n;if(t&&"object"==typeof t){const{url:r,...i}=t;n=r,e={...i,...e}}else n=t;const{target:r,title:i}=e,l=void 0===e.rel?"noreferrer":e.rel,u=c();if(null===u||!o(u)&&!g(u))return;if(g(u)){const t=u.getNodes();if(0===t.length)return;return void t.forEach(t=>{if(null===n){const e=f(t,t=>!et(t)&&X(t));e&&(e.insertBefore(t),0===e.getChildren().length&&e.remove())}else{const e=f(t,t=>!et(t)&&X(t));if(e)e.setURL(n),void 0!==r&&e.setTarget(r),void 0!==l&&e.setRel(l);else{const e=V(n,{rel:l,target:r});t.insertBefore(e),e.append(t)}}})}if(u.isCollapsed()&&null===n)for(const t of u.getNodes()){const e=f(t,t=>!et(t)&&X(t));return void(null!==e&&(e.getParentOrThrow().splice(e.getIndexWithinParent(),0,e.getChildren()),e.remove()))}const a=u.extract();if(null===n){const t=new Set;return void a.forEach(e=>{const n=f(e,t=>!et(t)&&X(t));if(null!==n){const e=n.getKey();if(t.has(e))return;!function(t,e){const n=new Set(e.filter(e=>t.isParentOf(e)).map(t=>t.getKey())),r=t.getChildren(),i=r=>n.has(r.getKey())||_(r)&&e.some(e=>t.isParentOf(e)&&r.isParentOf(e)),l=r.filter(i);if(l.length===r.length)return r.forEach(e=>t.insertBefore(e)),void t.remove();const o=r.findIndex(i),u=r.findLastIndex(i),a=0===o,c=u===r.length-1;if(a)l.forEach(e=>t.insertBefore(e));else if(c)for(let e=l.length-1;e>=0;e--)t.insertAfter(l[e]);else{for(let e=l.length-1;e>=0;e--)t.insertAfter(l[e]);const e=r.slice(u+1);if(e.length>0){const n=s(t);l[l.length-1].insertAfter(n),e.forEach(t=>n.append(t))}}}(n,a),t.add(e)}})}const p=new Set,m=t=>{p.has(t.getKey())||(p.add(t.getKey()),t.setURL(n),void 0!==r&&t.setTarget(r),void 0!==l&&t.setRel(l),void 0!==i&&t.setTitle(i))};if(1===a.length){const t=a[0],e=f(t,X);if(null!==e)return m(e)}!function(t){const e=c();if(!o(e))return t();const n=d(e),r=n.isBackward(),i=rt(n.anchor,r?-1:0),l=rt(n.focus,r?0:-1),s=t();if(i||l){const t=c();if(o(t)){const e=t.clone();if(i){const t=i.getParent();t&&e.anchor.set(t.getKey(),i.getIndexWithinParent()+(r?1:0),"element")}if(l){const t=l.getParent();t&&e.focus.set(t.getKey(),l.getIndexWithinParent()+(r?0:1),"element")}h(d(e))}}}(()=>{let t=null;for(const e of a){if(!e.isAttached())continue;const s=f(e,X);if(s){m(s);continue}if(_(e)){if(!e.isInline())continue;if(X(e)){if(!(et(e)||null!==t&&t.getParentOrThrow().isParentOf(e))){m(e),t=e;continue}for(const t of e.getChildren())e.insertBefore(t);e.remove();continue}}const o=e.getPreviousSibling();X(o)&&o.is(t)?o.append(e):(t=V(n,{rel:l,target:r,title:i}),e.insertAfter(t),t.append(e))}})}const lt=/^\+?[0-9\s()-]{5,}$/;function st(t){return t.match(/^[a-z][a-z0-9+.-]*:/i)||t.match(/^[/#.]/)?t:t.includes("@")?`mailto:${t}`:lt.test(t)?`tel:${t}`:`https://${t}`}const ot=[/* @__PURE__ */W({$import:(t,e)=>{if(!e.textContent&&0===e.children.length)return[];const n=e.getAttribute("href")||"",r={rel:e.getAttribute("rel"),target:e.getAttribute("target"),title:e.getAttribute("title")};return $(t.$importChildren(e),()=>V(n,r))},match:J.tag("a"),name:"@lexical/link/a"})];function ut(t,n){return S(t.registerNodeTransform(Z,q),t.registerCommand(nt,t=>{const e=n.validateUrl.peek(),r=n.attributes.peek();if(null===t)return it(null),!0;if("string"==typeof t)return!(void 0!==e&&!e(t))&&(it(t,r),!0);{const{url:e,target:n,rel:i,title:l}=t;return it(e,{...r,rel:i,target:n,title:l}),!0}},N),e(()=>{const e=n.validateUrl.value;if(!e)return;const r=n.attributes.value;return t.registerCommand(O,n=>{const i=c();if(!o(i)||i.isCollapsed()||!B(n,ClipboardEvent))return!1;if(null===n.clipboardData)return!1;const l=n.clipboardData.getData("text");if(!e(l))return!1;return!i.getNodes().some(t=>_(t)||A(t)&&!t.isSimpleText())&&(t.dispatchCommand(nt,{...r,url:l}),n.preventDefault(),!0)},P)}))}const at=/* @__PURE__ */T({build:(e,n,r)=>t(n),config:{attributes:void 0,validateUrl:void 0},dependencies:[K,/* @__PURE__ */L(z,{rules:ot})],mergeConfig(t,e){const n=C(t,e);return t.attributes&&(n.attributes=C(t.attributes,n.attributes)),n},name:"@lexical/link/Link",nodes:()=>[Z],register:(t,e,n)=>ut(t,n.getOutput())}),ct=/* @__PURE__ */T({dependencies:[at],name:"@lexical/link/Import"});function gt(t,e,n={}){const r=n=>{const r=n.target;if(!w(r))return;const i=I(r);if(null===i)return;let s=null,u=null,a=!1;if(i.update(()=>{const t=D(r);if(null!==t){const n=f(t,_);if(!e.disabled.peek())if(X(n))a=et(n)&&n.getIsUnlinked(),s=n.sanitizeUrl(n.getURL()),u=n.getTarget();else{const t=function(t,e){let n=t;for(;null!=n;){if(e(n))return n;n=n.parentNode}return null}(r,l);null!==t&&(s=t.href,u=t.target)}}}),null===s||""===s||a)return;const g=t.read("latest",c);if(o(g)&&!g.isCollapsed())return void n.preventDefault();const d="auxclick"===n.type&&1===n.button;window.open(s,e.newTab.peek()||d||n.metaKey||n.ctrlKey||"_blank"===u?"_blank":"_self"),n.preventDefault()},i=t=>{1===t.button&&r(t)};return t.registerRootListener(t=>{if(t)return R(t,{click:r,mouseup:i},n)})}const ft=/* @__PURE__ */T({build:(e,n,r)=>t(n),config:/* @__PURE__ */y({disabled:!1,newTab:!1}),dependencies:[at],name:"@lexical/link/ClickableLink",register:(t,e,n)=>gt(t,n.getOutput())});function dt(t,e=t=>t){return n=>{const r=t.exec(n);return null===r?null:{index:r.index,length:r[0].length,text:r[0],url:e(r[0])}}}const ht=/((https?:\/\/(www\.)?)|(www\.))[-\p{L}\p{N}@:%._+~#=]{1,256}\.[\p{L}\p{N}]{1,6}(?:[-\p{L}\p{N}()@:%_+.~#?&//=]*[\p{L}\p{N}()@_~#?&//=])?/u,pt=t=>{const e=ht.exec(t);if(null===e)return null;let n=e[0],r=0;for(const t of n)"("===t?r++:")"===t&&r--;for(;r<0&&n.endsWith(")");)n=n.slice(0,-1),r++;return{index:e.index,length:n.length,text:n,url:n.startsWith("http")?n:`https://${n}`}},_t=dt(/(([^<>()[\]\\.,;:\s@"]{1,64}(\.[^<>()[\]\\.,;:\s@"]{1,64}){0,63})|(".{1,255}"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]{1,63}\.){1,127}[a-zA-Z]{2,63}))/,t=>`mailto:${t}`);function mt(t,e){for(let n=0;n<e.length;n++){const r=e[n](t);if(r)return r}return null}const xt=/[.,;\s]/;function kt(t,e){return e.test(t)}function bt(t,e){return kt(t[t.length-1],e)}function Ut(t,e){return kt(t[0],e)}function vt(t,e){let n=t.getPreviousSibling();return _(n)&&(n=n.getLastDescendant()),null===n||E(n)||A(n)&&bt(n.getTextContent(),e)}function Tt(t,e){let n=t.getNextSibling();return _(n)&&(n=n.getFirstDescendant()),null===n||E(n)||A(n)&&Ut(n.getTextContent(),e)}function Ct(t,e,n,r,i){if(!(t>0?kt(r[t-1],n):vt(i[0],n)))return!1;return e<r.length?kt(r[e],n):Tt(i[i.length-1],n)}function Lt(t,e,n){const r=[],i=[],l=[];let s=0,o=0;const u=[...t];for(;u.length>0;){const t=u[0],a=t.getTextContent().length,c=o;o+a<=e?(r.push(t),s+=a):c>=n?l.push(t):i.push(t),o+=a,u.shift()}return[s,r,i,l]}function St(t,e,n,r){const i=tt(r.url,r.attributes);if(1===t.length){let l,s=t[0];0===e?[l,s]=s.splitText(n):[,l,s]=s.splitText(e,n);const o=F(r.text);return o.setFormat(l.getFormat()),o.setDetail(l.getDetail()),o.setStyle(l.getStyle()),i.append(o),l.replace(i),s}if(t.length>1){const r=t[0];let l,s=r.getTextContent().length;0===e?l=r:[,l]=r.splitText(e);const u=[];let a;for(let e=1;e<t.length;e++){const r=t[e],i=r.getTextContent().length,l=s;if(l<n)if(s+i<=n)u.push(r);else{const[t,e]=r.splitText(n-l);u.push(t),a=e}s+=i}const f=c(),d=f?f.getNodes().find(A):void 0,h=F(l.getTextContent());return h.setFormat(l.getFormat()),h.setDetail(l.getDetail()),h.setStyle(l.getStyle()),i.append(h,...u),d&&d===l&&(o(f)?h.select(f.anchor.offset,f.focus.offset):g(f)&&h.select(0,h.getTextContent().length)),l.replace(i),a}}function Nt(t,e,n,r){const i=t.getChildren(),l=i.length;for(let e=0;e<l;e++){const r=i[e];if(!A(r)||!r.isSimpleText())return Ot(t),void n(null,t.getURL())}const s=t.getTextContent(),o=mt(s,e);if(null===o||o.text!==s)return Ot(t),void n(null,t.getURL());if(!vt(t,r)||!Tt(t,r))return Ot(t),void n(null,t.getURL());const u=t.getURL();if(u!==o.url&&(t.setURL(o.url),n(o.url,u)),o.attributes){const e=t.getRel();e!==o.attributes.rel&&(t.setRel(o.attributes.rel||null),n(o.attributes.rel||null,e));const r=t.getTarget();r!==o.attributes.target&&(t.setTarget(o.attributes.target||null),n(o.attributes.target||null,r))}}function Ot(t){const e=t.getChildren();for(let n=e.length-1;n>=0;n--)t.insertAfter(e[n]);return t.remove(),e.map(t=>t.getLatest())}const At={changeHandlers:[],excludeParents:[],matchers:[],separatorRegex:xt};function Pt(t,e=At){const{matchers:n,changeHandlers:r,excludeParents:i,separatorRegex:l=xt}=e,s=(t,e)=>{for(const n of r)n(t,e)};return S(t.registerNodeTransform(M,t=>{const e=t.getParentOrThrow(),r=t.getPreviousSibling();if(et(e))Nt(e,n,s,l);else if(!X(e)&&!i.some(t=>t(e))){if(t.isSimpleText()&&(Ut(t.getTextContent(),l)||!et(r))){const e=function(t){const e=[t];let n=t.getNextSibling();for(;null!==n&&A(n)&&n.isSimpleText()&&(e.push(n),!/[\s]/.test(n.getTextContent()));)n=n.getNextSibling();return e}(t);!function(t,e,n,r){for(const e of t){const t=e.getParent();if(et(t)&&!t.getIsUnlinked())return}let i=[...t];const l=i.map(t=>t.getTextContent()).join("");let s,o=l,u=0;for(;(s=mt(o,e))&&null!==s;){const t=s.index,e=t+s.length;if(Ct(u+t,u+e,r,l,i)){const[r,,l,a]=Lt(i,u+t,u+e);let c=!1;for(const t of l){const e=t.getParent();if(et(e)&&!e.getIsUnlinked()){c=!0;break}}if(c){u+=e,o=o.substring(e);continue}const g=St(l,u+t-r,u+e-r,s);i=g?[g,...a]:a,n(s.url,null),u=0}else u+=e;o=o.substring(e)}}(e,n,s,l)}!function(t,e,n,r){const i=t.getParent(),l=t.getPreviousSibling(),s=t.getNextSibling(),o=t.getTextContent();if(!et(i)||i.getIsUnlinked()){if(et(l)&&!l.getIsUnlinked()&&l.is(t.getPreviousSibling())&&t.getParent()===l.getParent()){if(!Ut(o,r))return Ot(l),void n(null,l.getURL());if(u=o,l.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(u):/^\.[a-zA-Z0-9]{1,}/.test(u)){const i=l.getTextContent()+o,s=mt(i,e);null!==s&&s.text===i&&(l.append(t),Nt(l,e,n,r),n(null,l.getURL()))}}var u;!et(s)||s.getIsUnlinked()||bt(o,r)||s.is(t.getNextSibling())&&t.getParent()===s.getParent()&&(Ot(s),n(null,s.getURL()))}}(t,n,s,l)}}),t.registerCommand(nt,t=>{const e=c();if(null!==t||!o(e))return!1;return e.extract().forEach(t=>{const e=t.getParent();et(e)&&(e.setIsUnlinked(!e.getIsUnlinked()),e.markDirty())}),!1},P))}const yt=/* @__PURE__ */T({config:At,dependencies:[at],mergeConfig(t,e){const n=C(t,e);for(const r of["matchers","changeHandlers","excludeParents"]){const i=e[r];Array.isArray(i)&&(n[r]=[...t[r],...i])}return n},name:"@lexical/link/AutoLink",nodes:[Y],register:Pt});export{tt as $createAutoLinkNode,V as $createLinkNode,et as $isAutoLinkNode,X as $isLinkNode,it as $toggleLink,yt as AutoLinkExtension,Y as AutoLinkNode,ft as ClickableLinkExtension,at as LinkExtension,ct as LinkImportExtension,ot as LinkImportRules,Z as LinkNode,nt as TOGGLE_LINK_COMMAND,_t as autoLinkEmailMatcher,pt as autoLinkUrlMatcher,dt as createLinkMatcherWithRegExp,st as formatUrl,Pt as registerAutoLink,gt as registerClickableLink,ut as registerLink};
|
|
9
|
+
import{namedSignals as t,effect as e}from"@lexical/extension";import{ElementNode as n,$getDocument as r,addClassNamesToElement as i,isHTMLAnchorElement as l,$copyNode as s,$isRangeSelection as o,$applyNodeReplacement as u,createCommand as a,$getSelection as c,$isNodeSelection as g,$findMatchingParent as f,$normalizeSelection__EXPERIMENTAL as d,$setSelection as h,$getChildCaret as p,$isElementNode as _,$insertNodeToNearestRootAtCaret as m,$rewindSiblingCaret as x,$caretFromPoint as b,$normalizeCaret as k,$isSiblingCaret as U,$setPointFromCaret as v,defineExtension as T,shallowMergeConfig as C,configExtension as L,mergeRegister as S,COMMAND_PRIORITY_EDITOR as N,PASTE_COMMAND as O,$isTextNode as A,COMMAND_PRIORITY_LOW as P,safeCast as y,registerEventListeners as R,isDOMNode as w,getNearestEditorFromDOMNode as I,$getNearestNodeFromDOMNode as D,TextNode as F,$isLineBreakNode as M,$createTextNode as E}from"lexical";import{defineImportRule as W,sel as $,$distributeInlineWrapper as J,CoreImportExtension as z,DOMImportExtension as K}from"@lexical/html";import{objectKlassEquals as B}from"@lexical/utils";const j=new Set(["http:","https:","mailto:","sms:","tel:"]);class Z extends n{__url;__target;__rel;__title;static getType(){return"link"}static clone(t){return new Z(t.__url,{rel:t.__rel,target:t.__target,title:t.__title},t.__key)}constructor(t="",e={},n){super(n);const{target:r=null,rel:i=null,title:l=null}=e;this.__url=t,this.__target=r,this.__rel=i,this.__title=l}afterCloneFrom(t){super.afterCloneFrom(t),this.__url=t.__url,this.__rel=t.__rel,this.__target=t.__target,this.__title=t.__title}createDOM(t){const e=r().createElement("a");return this.updateLinkDOM(null,e,t),i(e,t.theme.link),e}updateLinkDOM(t,e,n){if(l(e)){t&&t.__url===this.__url||(e.href=this.sanitizeUrl(this.__url));for(const n of["target","rel","title"]){const r=`__${n}`,i=this[r];t&&t[r]===i||(i?e[n]=i:e.removeAttribute(n))}}}updateDOM(t,e,n){return this.updateLinkDOM(t,e,n),!1}static importDOM(){return{a:t=>({conversion:Q,priority:1})}}static importJSON(t){return V().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setURL(t.url).setRel(t.rel||null).setTarget(t.target||null).setTitle(t.title||null)}sanitizeUrl(t){const e=t;t=st(t);try{const e=new URL(st(t));if(!j.has(e.protocol))return"about:blank"}catch(t){const n=e.replace(/[\u0000-\u001F\u007F\s]/g,"").match(/^([a-z][a-z0-9+.-]*):/i);if(null!=n&&!j.has(`${n[1].toLowerCase()}:`))return"about:blank"}return t}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),url:this.getURL()}}getURL(){return this.getLatest().__url}setURL(t){const e=this.getWritable();return e.__url=t,e}getTarget(){return this.getLatest().__target}setTarget(t){const e=this.getWritable();return e.__target=t,e}getRel(){return this.getLatest().__rel}setRel(t){const e=this.getWritable();return e.__rel=t,e}getTitle(){return this.getLatest().__title}setTitle(t){const e=this.getWritable();return e.__title=t,e}insertNewAfter(t,e=!0){const n=s(this);return this.insertAfter(n,e),n}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(t,e,n){if(!o(e))return!1;const r=e.anchor.getNode(),i=e.focus.getNode();return(this.is(r)||this.isParentOf(r))&&(this.is(i)||this.isParentOf(i))&&e.getTextContent().length>0}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")||this.__url.startsWith("http://")}shouldMergeAdjacentLink(t){return this.getType()===t.getType()&&this.__url===t.__url&&this.__target===t.__target&&this.__rel===t.__rel&&this.__title===t.__title}}function H(t){const e=b(t,"next");return[e,e.getFlipped()]}function G(t,e){for(const n of e)if(n.origin.isAttached()){const e=k(n);return void v(t,e)}}function q(t){const e=c();let n=null,r=null;function i(){o(e)&&(G(e.anchor,n),G(e.focus,r),d(e))}o(e)&&(n=H(e.anchor),r=H(e.focus));let l=!1;for(const e of p(t,"next")){const n=e.origin;if(_(n)&&!n.isInline()){const r=n.getChildren();if(r.length>0){const e=s(t);e.append(...r),n.append(e),l=!0}m(n,x(e),{$shouldSplit:()=>!1})}}function u(t,e,n){const[r,i]=t,l=t=>U(t)&&t.origin.is(e);if(!l(r)&&!l(i))return t;const s=k(p(n,"next"));return[s,s.getFlipped()]}if(t.isAttached()){const e=t.getPreviousSibling();if(X(e)&&e.shouldMergeAdjacentLink(t))return n&&(n=u(n,e,t)),r&&(r=u(r,e,t)),e.append(...t.getChildren()),t.remove(),void i();const s=t.getNextSibling();X(s)&&t.shouldMergeAdjacentLink(s)&&(n&&(n=u(n,t,s)),r&&(r=u(r,t,s)),t.append(...s.getChildren()),s.remove(),l=!0)}if(l){if(!t.canBeEmpty()&&t.isEmpty()){const e=t.getParent();t.remove(),e&&e.isEmpty()&&e.remove()}i()}}function Q(t){let e=null;if(l(t)){const n=t.textContent;(null!==n&&""!==n||t.children.length>0)&&(e=V(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}))}return{node:e}}function V(t="",e){return u(new Z(t,e))}function X(t){return t instanceof Z}class Y extends Z{__isUnlinked;constructor(t="",e={},n){super(t,e,n),this.__isUnlinked=void 0!==e.isUnlinked&&null!==e.isUnlinked&&e.isUnlinked}afterCloneFrom(t){super.afterCloneFrom(t),this.__isUnlinked=t.__isUnlinked}static getType(){return"autolink"}static clone(t){return new Y(t.__url,{isUnlinked:t.__isUnlinked,rel:t.__rel,target:t.__target,title:t.__title},t.__key)}shouldMergeAdjacentLink(t){return!1}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(t){const e=this.getWritable();return e.__isUnlinked=t,e}createDOM(t){return this.__isUnlinked?r().createElement("span"):super.createDOM(t)}updateDOM(t,e,n){return super.updateDOM(t,e,n)||t.__isUnlinked!==this.__isUnlinked}static importJSON(t){return tt().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setIsUnlinked(t.isUnlinked||!1)}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked}}insertNewAfter(t,e=!0){const n=tt(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(n,e),n}}function tt(t="",e){return u(new Y(t,e))}function et(t){return t instanceof Y}const nt=/* @__PURE__ */a("TOGGLE_LINK_COMMAND");function rt(t,e){if("element"===t.type){const n=t.getNode();_(n)||function(t,...e){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",t);for(const t of e)r.append("v",t);throw n.search=r.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(252);return n.getChildren()[t.offset+e]||null}return null}function it(t,e={}){let n;if(t&&"object"==typeof t){const{url:r,...i}=t;n=r,e={...i,...e}}else n=t;const{target:r,title:i}=e,l=void 0===e.rel?"noreferrer":e.rel,u=c();if(null===u||!o(u)&&!g(u))return;if(g(u)){const t=u.getNodes();if(0===t.length)return;return void t.forEach(t=>{if(null===n){const e=f(t,t=>!et(t)&&X(t));e&&(e.insertBefore(t),0===e.getChildren().length&&e.remove())}else{const e=f(t,t=>!et(t)&&X(t));if(e)e.setURL(n),void 0!==r&&e.setTarget(r),void 0!==l&&e.setRel(l);else{const e=V(n,{rel:l,target:r});t.insertBefore(e),e.append(t)}}})}if(u.isCollapsed()&&null===n)for(const t of u.getNodes()){const e=f(t,t=>!et(t)&&X(t));return void(null!==e&&(e.getParentOrThrow().splice(e.getIndexWithinParent(),0,e.getChildren()),e.remove()))}const a=u.extract();if(null===n){const t=new Set;return void a.forEach(e=>{const n=f(e,t=>!et(t)&&X(t));if(null!==n){const e=n.getKey();if(t.has(e))return;!function(t,e){const n=new Set(e.filter(e=>t.isParentOf(e)).map(t=>t.getKey())),r=t.getChildren(),i=r=>n.has(r.getKey())||_(r)&&e.some(e=>t.isParentOf(e)&&r.isParentOf(e)),l=r.filter(i);if(l.length===r.length)return r.forEach(e=>t.insertBefore(e)),void t.remove();const o=r.findIndex(i),u=r.findLastIndex(i),a=0===o,c=u===r.length-1;if(a)l.forEach(e=>t.insertBefore(e));else if(c)for(let e=l.length-1;e>=0;e--)t.insertAfter(l[e]);else{for(let e=l.length-1;e>=0;e--)t.insertAfter(l[e]);const e=r.slice(u+1);if(e.length>0){const n=s(t);l[l.length-1].insertAfter(n),e.forEach(t=>n.append(t))}}}(n,a),t.add(e)}})}const p=new Set,m=t=>{p.has(t.getKey())||(p.add(t.getKey()),t.setURL(n),void 0!==r&&t.setTarget(r),void 0!==l&&t.setRel(l),void 0!==i&&t.setTitle(i))};if(1===a.length){const t=a[0],e=f(t,X);if(null!==e)return m(e)}!function(t){const e=c();if(!o(e))return t();const n=d(e),r=n.isBackward(),i=rt(n.anchor,r?-1:0),l=rt(n.focus,r?0:-1),s=t();if(i||l){const t=c();if(o(t)){const e=t.clone();if(i){const t=i.getParent();t&&e.anchor.set(t.getKey(),i.getIndexWithinParent()+(r?1:0),"element")}if(l){const t=l.getParent();t&&e.focus.set(t.getKey(),l.getIndexWithinParent()+(r?0:1),"element")}h(d(e))}}}(()=>{let t=null;for(const e of a){if(!e.isAttached())continue;const s=f(e,X);if(s){m(s);continue}if(_(e)){if(!e.isInline())continue;if(X(e)){if(!(et(e)||null!==t&&t.getParentOrThrow().isParentOf(e))){m(e),t=e;continue}for(const t of e.getChildren())e.insertBefore(t);e.remove();continue}}const o=e.getPreviousSibling();X(o)&&o.is(t)?o.append(e):(t=V(n,{rel:l,target:r,title:i}),e.insertAfter(t),t.append(e))}})}const lt=/^\+?[0-9\s()-]{5,}$/;function st(t){return t.match(/^[a-z][a-z0-9+.-]*:/i)||t.match(/^[/#.]/)?t:t.includes("@")?`mailto:${t}`:lt.test(t)?`tel:${t}`:`https://${t}`}const ot=[/* @__PURE__ */W({$import:(t,e)=>{if(!e.textContent&&0===e.children.length)return[];const n=e.getAttribute("href")||"",r={rel:e.getAttribute("rel"),target:e.getAttribute("target"),title:e.getAttribute("title")};return J(t.$importChildren(e),()=>V(n,r))},match:$.tag("a"),name:"@lexical/link/a"})];function ut(t,n){return S(t.registerNodeTransform(Z,q),t.registerCommand(nt,t=>{const e=n.validateUrl.peek(),r=n.attributes.peek();if(null===t)return it(null),!0;if("string"==typeof t)return!(void 0!==e&&!e(t))&&(it(t,r),!0);{const{url:e,target:n,rel:i,title:l}=t;return it(e,{...r,rel:i,target:n,title:l}),!0}},N),e(()=>{const e=n.validateUrl.value;if(!e)return;const r=n.attributes.value;return t.registerCommand(O,n=>{const i=c();if(!o(i)||i.isCollapsed()||!B(n,ClipboardEvent))return!1;if(null===n.clipboardData)return!1;const l=n.clipboardData.getData("text");if(!e(l))return!1;return!i.getNodes().some(t=>_(t)||A(t)&&!t.isSimpleText())&&(t.dispatchCommand(nt,{...r,url:l}),n.preventDefault(),!0)},P)}))}const at=/* @__PURE__ */T({build:(e,n,r)=>t(n),config:{attributes:void 0,validateUrl:void 0},dependencies:[z,/* @__PURE__ */L(K,{rules:ot})],mergeConfig(t,e){const n=C(t,e);return t.attributes&&(n.attributes=C(t.attributes,n.attributes)),n},name:"@lexical/link/Link",nodes:()=>[Z],register:(t,e,n)=>ut(t,n.getOutput())}),ct=/* @__PURE__ */T({dependencies:[at],name:"@lexical/link/Import"});function gt(t,e,n={}){const r=n=>{const r=n.target;if(!w(r))return;const i=I(r);if(null===i)return;let s=null,u=null,a=!1;if(i.update(()=>{const t=D(r);if(null!==t){const n=f(t,_);if(!e.disabled.peek())if(X(n))a=et(n)&&n.getIsUnlinked(),s=n.sanitizeUrl(n.getURL()),u=n.getTarget();else{const t=function(t,e){let n=t;for(;null!=n;){if(e(n))return n;n=n.parentNode}return null}(r,l);null!==t&&(s=t.href,u=t.target)}}}),null===s||""===s||a)return;const g=t.read("latest",c);if(o(g)&&!g.isCollapsed())return void n.preventDefault();const d="auxclick"===n.type&&1===n.button;window.open(s,e.newTab.peek()||d||n.metaKey||n.ctrlKey||"_blank"===u?"_blank":"_self"),n.preventDefault()},i=t=>{1===t.button&&r(t)};return t.registerRootListener(t=>{if(t)return R(t,{click:r,mouseup:i},n)})}const ft=/* @__PURE__ */T({build:(e,n,r)=>t(n),config:/* @__PURE__ */y({disabled:!1,newTab:!1}),dependencies:[at],name:"@lexical/link/ClickableLink",register:(t,e,n)=>gt(t,n.getOutput())});function dt(t,e=t=>t){return n=>{const r=t.exec(n);return null===r?null:{index:r.index,length:r[0].length,text:r[0],url:e(r[0])}}}const ht=/((https?:\/\/(www\.)?)|(www\.))[-\p{L}\p{N}@:%._+~#=]{1,256}\.[\p{L}\p{N}]{1,6}(?:[-\p{L}\p{N}()@:%_+.~#?&//=]*[\p{L}\p{N}()@_~#?&//=])?/u,pt=t=>{const e=ht.exec(t);if(null===e)return null;let n=e[0],r=0;for(const t of n)"("===t?r++:")"===t&&r--;for(;r<0&&n.endsWith(")");)n=n.slice(0,-1),r++;return{index:e.index,length:n.length,text:n,url:n.startsWith("http")?n:`https://${n}`}},_t=dt(/(([^<>()[\]\\.,;:\s@"]{1,64}(\.[^<>()[\]\\.,;:\s@"]{1,64}){0,63})|(".{1,255}"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]{1,63}\.){1,127}[a-zA-Z]{2,63}))/,t=>`mailto:${t}`);function mt(t,e){for(let n=0;n<e.length;n++){const r=e[n](t);if(r)return r}return null}const xt=/[.,;\s]/;function bt(t,e){return e.test(t)}function kt(t,e){return bt(t[t.length-1],e)}function Ut(t,e){return bt(t[0],e)}function vt(t,e){let n=t.getPreviousSibling();return _(n)&&(n=n.getLastDescendant()),null===n||M(n)||A(n)&&kt(n.getTextContent(),e)}function Tt(t,e){let n=t.getNextSibling();return _(n)&&(n=n.getFirstDescendant()),null===n||M(n)||A(n)&&Ut(n.getTextContent(),e)}function Ct(t,e,n,r,i){if(!(t>0?bt(r[t-1],n):vt(i[0],n)))return!1;return e<r.length?bt(r[e],n):Tt(i[i.length-1],n)}function Lt(t,e,n){const r=[],i=[],l=[];let s=0,o=0;const u=[...t];for(;u.length>0;){const t=u[0],a=t.getTextContent().length,c=o;o+a<=e?(r.push(t),s+=a):c>=n?l.push(t):i.push(t),o+=a,u.shift()}return[s,r,i,l]}function St(t,e,n,r){const i=tt(r.url,r.attributes);if(1===t.length){let l,s=t[0];0===e?[l,s]=s.splitText(n):[,l,s]=s.splitText(e,n);const o=E(r.text);return o.setFormat(l.getFormat()),o.setDetail(l.getDetail()),o.setStyle(l.getStyle()),i.append(o),l.replace(i),s}if(t.length>1){const r=t[0];let l,s=r.getTextContent().length;0===e?l=r:[,l]=r.splitText(e);const u=[];let a;for(let e=1;e<t.length;e++){const r=t[e],i=r.getTextContent().length,l=s;if(l<n)if(s+i<=n)u.push(r);else{const[t,e]=r.splitText(n-l);u.push(t),a=e}s+=i}const f=c(),d=f?f.getNodes().find(A):void 0,h=E(l.getTextContent());return h.setFormat(l.getFormat()),h.setDetail(l.getDetail()),h.setStyle(l.getStyle()),i.append(h,...u),d&&d===l&&(o(f)?h.select(f.anchor.offset,f.focus.offset):g(f)&&h.select(0,h.getTextContent().length)),l.replace(i),a}}function Nt(t,e,n,r){const i=t.getChildren(),l=i.length;for(let e=0;e<l;e++){const r=i[e];if(!A(r)||!r.isSimpleText())return Ot(t),void n(null,t.getURL())}const s=t.getTextContent(),o=mt(s,e);if(null===o||o.text!==s)return Ot(t),void n(null,t.getURL());if(!vt(t,r)||!Tt(t,r))return Ot(t),void n(null,t.getURL());const u=t.getURL();if(u!==o.url&&(t.setURL(o.url),n(o.url,u)),o.attributes){const e=t.getRel();e!==o.attributes.rel&&(t.setRel(o.attributes.rel||null),n(o.attributes.rel||null,e));const r=t.getTarget();r!==o.attributes.target&&(t.setTarget(o.attributes.target||null),n(o.attributes.target||null,r))}}function Ot(t){const e=t.getChildren();for(let n=e.length-1;n>=0;n--)t.insertAfter(e[n]);return t.remove(),e.map(t=>t.getLatest())}const At={changeHandlers:[],excludeParents:[],matchers:[],separatorRegex:xt};function Pt(t,e=At){const{matchers:n,changeHandlers:r,excludeParents:i,separatorRegex:l=xt}=e,s=(t,e)=>{for(const n of r)n(t,e)};return S(t.registerNodeTransform(F,t=>{const e=t.getParentOrThrow(),r=t.getPreviousSibling();if(et(e))Nt(e,n,s,l);else if(!X(e)&&!i.some(t=>t(e))){if(t.isSimpleText()&&(Ut(t.getTextContent(),l)||!et(r))){const e=function(t){const e=[t];let n=t.getNextSibling();for(;null!==n&&A(n)&&n.isSimpleText()&&(e.push(n),!/[\s]/.test(n.getTextContent()));)n=n.getNextSibling();return e}(t);!function(t,e,n,r){for(const e of t){const t=e.getParent();if(et(t)&&!t.getIsUnlinked())return}let i=[...t];const l=i.map(t=>t.getTextContent()).join("");let s,o=l,u=0;for(;(s=mt(o,e))&&null!==s;){const t=s.index,e=t+s.length;if(Ct(u+t,u+e,r,l,i)){const[r,,l,a]=Lt(i,u+t,u+e);let c=!1;for(const t of l){const e=t.getParent();if(et(e)&&!e.getIsUnlinked()){c=!0;break}}if(c){u+=e,o=o.substring(e);continue}const g=St(l,u+t-r,u+e-r,s);i=g?[g,...a]:a,n(s.url,null),u=0}else u+=e;o=o.substring(e)}}(e,n,s,l)}!function(t,e,n,r){const i=t.getParent(),l=t.getPreviousSibling(),s=t.getNextSibling(),o=t.getTextContent();if(!et(i)||i.getIsUnlinked()){if(et(l)&&!l.getIsUnlinked()&&l.is(t.getPreviousSibling())&&t.getParent()===l.getParent()){if(!Ut(o,r))return Ot(l),void n(null,l.getURL());if(u=o,l.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(u):/^\.[a-zA-Z0-9]{1,}/.test(u)){const i=l.getTextContent()+o,s=mt(i,e);null!==s&&s.text===i&&(l.append(t),Nt(l,e,n,r),n(null,l.getURL()))}}var u;!et(s)||s.getIsUnlinked()||kt(o,r)||s.is(t.getNextSibling())&&t.getParent()===s.getParent()&&(Ot(s),n(null,s.getURL()))}}(t,n,s,l)}}),t.registerCommand(nt,t=>{const e=c();if(null!==t||!o(e))return!1;return e.extract().forEach(t=>{const e=t.getParent();et(e)&&(e.setIsUnlinked(!e.getIsUnlinked()),e.markDirty())}),!1},P))}const yt=/* @__PURE__ */T({config:At,dependencies:[at],mergeConfig(t,e){const n=C(t,e);for(const r of["matchers","changeHandlers","excludeParents"]){const i=e[r];Array.isArray(i)&&(n[r]=[...t[r],...i])}return n},name:"@lexical/link/AutoLink",nodes:[Y],register:Pt});export{tt as $createAutoLinkNode,V as $createLinkNode,et as $isAutoLinkNode,X as $isLinkNode,it as $toggleLink,yt as AutoLinkExtension,Y as AutoLinkNode,ft as ClickableLinkExtension,at as LinkExtension,ct as LinkImportExtension,ot as LinkImportRules,Z as LinkNode,nt as TOGGLE_LINK_COMMAND,_t as autoLinkEmailMatcher,pt as autoLinkUrlMatcher,dt as createLinkMatcherWithRegExp,st as formatUrl,Pt as registerAutoLink,gt as registerClickableLink,ut as registerLink};
|
package/package.json
CHANGED
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
"link"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.48.0",
|
|
12
12
|
"main": "./dist/LexicalLink.js",
|
|
13
13
|
"types": "./dist/typescript-too-old.d.ts",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@lexical/extension": "0.
|
|
16
|
-
"@lexical/html": "0.
|
|
17
|
-
"@lexical/internal": "0.
|
|
18
|
-
"
|
|
19
|
-
"lexical": "0.
|
|
15
|
+
"@lexical/extension": "0.48.0",
|
|
16
|
+
"@lexical/html": "0.48.0",
|
|
17
|
+
"@lexical/internal": "0.48.0",
|
|
18
|
+
"lexical": "0.48.0",
|
|
19
|
+
"@lexical/utils": "0.48.0"
|
|
20
20
|
},
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
package/src/LexicalLinkNode.ts
CHANGED
|
@@ -178,6 +178,7 @@ export class LinkNode extends ElementNode {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
sanitizeUrl(url: string): string {
|
|
181
|
+
const rawUrl = url;
|
|
181
182
|
url = formatUrl(url);
|
|
182
183
|
try {
|
|
183
184
|
const parsedUrl = new URL(formatUrl(url));
|
|
@@ -186,7 +187,37 @@ export class LinkNode extends ElementNode {
|
|
|
186
187
|
return 'about:blank';
|
|
187
188
|
}
|
|
188
189
|
} catch {
|
|
189
|
-
|
|
190
|
+
// `new URL()` threw, so we could not verify the protocol via the
|
|
191
|
+
// parser. Preserve fail-secure behavior: default unparseable URLs to
|
|
192
|
+
// `about:blank` and only allow through inputs that positively match an
|
|
193
|
+
// allowlisted scheme.
|
|
194
|
+
//
|
|
195
|
+
// Check the ORIGINAL input, not the `formatUrl()` output: `formatUrl()`
|
|
196
|
+
// prepends `https://` to anything it does not recognize as already
|
|
197
|
+
// having a scheme, which would mask a control-character-obfuscated
|
|
198
|
+
// scheme (e.g. `java\x00script:` becomes `https://java\x00script:`).
|
|
199
|
+
//
|
|
200
|
+
// Before extracting the scheme, strip C0 control characters, DEL and
|
|
201
|
+
// whitespace, mirroring how browsers ignore these when resolving a
|
|
202
|
+
// scheme. Without this, control-character-obfuscated schemes that throw
|
|
203
|
+
// in `new URL()` but are still navigated by some browsers would slip
|
|
204
|
+
// past a naive scheme check and retain their original, attacker-
|
|
205
|
+
// controlled value. Stripping C0 control characters and DEL is the
|
|
206
|
+
// intended, security-relevant behavior here.
|
|
207
|
+
// eslint-disable-next-line no-control-regex
|
|
208
|
+
const normalizedUrl = rawUrl.replace(/[\u0000-\u001F\u007F\s]/g, '');
|
|
209
|
+
const schemeMatch = normalizedUrl.match(/^([a-z][a-z0-9+.-]*):/i);
|
|
210
|
+
if (
|
|
211
|
+
schemeMatch != null &&
|
|
212
|
+
!SUPPORTED_URL_PROTOCOLS.has(`${schemeMatch[1].toLowerCase()}:`)
|
|
213
|
+
) {
|
|
214
|
+
// An explicit, non-allowlisted scheme survived normalization (e.g.
|
|
215
|
+
// `javascript:`, `data:`) — neutralize it. Inputs with no scheme
|
|
216
|
+
// (relative URLs such as `/path` or `#anchor`) or an allowlisted
|
|
217
|
+
// scheme are left unchanged: they cannot carry a dangerous scheme
|
|
218
|
+
// and are handled elsewhere.
|
|
219
|
+
return 'about:blank';
|
|
220
|
+
}
|
|
190
221
|
}
|
|
191
222
|
return url;
|
|
192
223
|
}
|