@lexical/link
Advanced tools
Comparing version 0.21.0 to 0.21.1-nightly.20241203.0
@@ -344,4 +344,54 @@ /** | ||
const TOGGLE_LINK_COMMAND = lexical.createCommand('TOGGLE_LINK_COMMAND'); | ||
function $getPointNode(point, offset) { | ||
if (point.type === 'element') { | ||
const node = point.getNode(); | ||
if (!lexical.$isElementNode(node)) { | ||
throw Error(`$getPointNode: element point is not an ElementNode`); | ||
} | ||
const childNode = node.getChildren()[point.offset + offset]; | ||
return childNode || null; | ||
} | ||
return null; | ||
} | ||
/** | ||
* Preserve the logical start/end of a RangeSelection in situations where | ||
* the point is an element that may be reparented in the callback. | ||
* | ||
* @param $fn The function to run | ||
* @returns The result of the callback | ||
*/ | ||
function $withSelectedNodes($fn) { | ||
const initialSelection = lexical.$getSelection(); | ||
if (!lexical.$isRangeSelection(initialSelection)) { | ||
return $fn(); | ||
} | ||
const normalized = lexical.$normalizeSelection__EXPERIMENTAL(initialSelection); | ||
const isBackwards = normalized.isBackward(); | ||
const anchorNode = $getPointNode(normalized.anchor, isBackwards ? -1 : 0); | ||
const focusNode = $getPointNode(normalized.focus, isBackwards ? 0 : -1); | ||
const rval = $fn(); | ||
if (anchorNode || focusNode) { | ||
const updatedSelection = lexical.$getSelection(); | ||
if (lexical.$isRangeSelection(updatedSelection)) { | ||
const finalSelection = updatedSelection.clone(); | ||
if (anchorNode) { | ||
const anchorParent = anchorNode.getParent(); | ||
if (anchorParent) { | ||
finalSelection.anchor.set(anchorParent.getKey(), anchorNode.getIndexWithinParent() + (isBackwards ? 1 : 0), 'element'); | ||
} | ||
} | ||
if (focusNode) { | ||
const focusParent = focusNode.getParent(); | ||
if (focusParent) { | ||
finalSelection.focus.set(focusParent.getKey(), focusNode.getIndexWithinParent() + (isBackwards ? 0 : 1), 'element'); | ||
} | ||
} | ||
lexical.$setSelection(lexical.$normalizeSelection__EXPERIMENTAL(finalSelection)); | ||
} | ||
} | ||
return rval; | ||
} | ||
/** | ||
* Generates or updates a LinkNode. It can also delete a LinkNode if the URL is null, | ||
@@ -375,79 +425,78 @@ * but saves any children and brings them up to the parent node. | ||
}); | ||
} else { | ||
// Add or merge LinkNodes | ||
if (nodes.length === 1) { | ||
const firstNode = nodes[0]; | ||
// if the first node is a LinkNode or if its | ||
// parent is a LinkNode, we update the URL, target and rel. | ||
const linkNode = $getAncestor(firstNode, $isLinkNode); | ||
if (linkNode !== null) { | ||
linkNode.setURL(url); | ||
if (target !== undefined) { | ||
linkNode.setTarget(target); | ||
} | ||
if (rel !== null) { | ||
linkNode.setRel(rel); | ||
} | ||
if (title !== undefined) { | ||
linkNode.setTitle(title); | ||
} | ||
return; | ||
} | ||
return; | ||
} | ||
const updatedNodes = new Set(); | ||
const updateLinkNode = linkNode => { | ||
if (updatedNodes.has(linkNode.getKey())) { | ||
return; | ||
} | ||
let prevParent = null; | ||
updatedNodes.add(linkNode.getKey()); | ||
linkNode.setURL(url); | ||
if (target !== undefined) { | ||
linkNode.setTarget(target); | ||
} | ||
if (rel !== undefined) { | ||
linkNode.setRel(rel); | ||
} | ||
if (title !== undefined) { | ||
linkNode.setTitle(title); | ||
} | ||
}; | ||
// Add or merge LinkNodes | ||
if (nodes.length === 1) { | ||
const firstNode = nodes[0]; | ||
// if the first node is a LinkNode or if its | ||
// parent is a LinkNode, we update the URL, target and rel. | ||
const linkNode = $getAncestor(firstNode, $isLinkNode); | ||
if (linkNode !== null) { | ||
return updateLinkNode(linkNode); | ||
} | ||
} | ||
$withSelectedNodes(() => { | ||
let linkNode = null; | ||
nodes.forEach(node => { | ||
const parent = node.getParent(); | ||
if (parent === linkNode || parent === null || lexical.$isElementNode(node) && !node.isInline()) { | ||
return; | ||
for (const node of nodes) { | ||
if (!node.isAttached()) { | ||
continue; | ||
} | ||
if ($isLinkNode(parent)) { | ||
linkNode = parent; | ||
parent.setURL(url); | ||
if (target !== undefined) { | ||
parent.setTarget(target); | ||
} | ||
if (rel !== null) { | ||
linkNode.setRel(rel); | ||
} | ||
if (title !== undefined) { | ||
linkNode.setTitle(title); | ||
} | ||
return; | ||
const parentLinkNode = $getAncestor(node, $isLinkNode); | ||
if (parentLinkNode) { | ||
updateLinkNode(parentLinkNode); | ||
continue; | ||
} | ||
if (!parent.is(prevParent)) { | ||
prevParent = parent; | ||
linkNode = $createLinkNode(url, { | ||
rel, | ||
target, | ||
title | ||
}); | ||
if ($isLinkNode(parent)) { | ||
if (node.getPreviousSibling() === null) { | ||
parent.insertBefore(linkNode); | ||
} else { | ||
parent.insertAfter(linkNode); | ||
} | ||
} else { | ||
node.insertBefore(linkNode); | ||
if (lexical.$isElementNode(node)) { | ||
if (!node.isInline()) { | ||
// Ignore block nodes, if there are any children we will see them | ||
// later and wrap in a new LinkNode | ||
continue; | ||
} | ||
} | ||
if ($isLinkNode(node)) { | ||
if (node.is(linkNode)) { | ||
return; | ||
} | ||
if (linkNode !== null) { | ||
const children = node.getChildren(); | ||
for (let i = 0; i < children.length; i++) { | ||
linkNode.append(children[i]); | ||
if ($isLinkNode(node)) { | ||
// If it's not an autolink node and we don't already have a LinkNode | ||
// in this block then we can update it and re-use it | ||
if (!$isAutoLinkNode(node) && (linkNode === null || !linkNode.getParentOrThrow().isParentOf(node))) { | ||
updateLinkNode(node); | ||
linkNode = node; | ||
continue; | ||
} | ||
// Unwrap LinkNode, we already have one or it's an AutoLinkNode | ||
for (const child of node.getChildren()) { | ||
node.insertBefore(child); | ||
} | ||
node.remove(); | ||
continue; | ||
} | ||
node.remove(); | ||
return; | ||
} | ||
if (linkNode !== null) { | ||
linkNode.append(node); | ||
const prevLinkNode = node.getPreviousSibling(); | ||
if ($isLinkNode(prevLinkNode) && prevLinkNode.is(linkNode)) { | ||
prevLinkNode.append(node); | ||
continue; | ||
} | ||
}); | ||
} | ||
linkNode = $createLinkNode(url, { | ||
rel, | ||
target, | ||
title | ||
}); | ||
node.insertAfter(linkNode); | ||
linkNode.append(node); | ||
} | ||
}); | ||
} | ||
@@ -454,0 +503,0 @@ /** @deprecated renamed to {@link $toggleLink} by @lexical/eslint-plugin rules-of-lexical */ |
@@ -9,13 +9,15 @@ /** | ||
'use strict';var l=require("@lexical/utils"),m=require("lexical");let n=new Set(["http:","https:","mailto:","sms:","tel:"]); | ||
class p extends m.ElementNode{static getType(){return"link"}static clone(a){return new p(a.__url,{rel:a.__rel,target:a.__target,title:a.__title},a.__key)}constructor(a,b={},d){super(d);let {target:h=null,rel:k=null,title:f=null}=b;this.__url=a;this.__target=h;this.__rel=k;this.__title=f}createDOM(a){let b=document.createElement("a");b.href=this.sanitizeUrl(this.__url);null!==this.__target&&(b.target=this.__target);null!==this.__rel&&(b.rel=this.__rel);null!==this.__title&&(b.title=this.__title);l.addClassNamesToElement(b, | ||
a.theme.link);return b}updateDOM(a,b){if(b instanceof HTMLAnchorElement){let d=this.__url,h=this.__target,k=this.__rel,f=this.__title;d!==a.__url&&(b.href=d);h!==a.__target&&(h?b.target=h:b.removeAttribute("target"));k!==a.__rel&&(k?b.rel=k:b.removeAttribute("rel"));f!==a.__title&&(f?b.title=f:b.removeAttribute("title"))}return!1}static importDOM(){return{a:()=>({conversion:q,priority:1})}}static importJSON(a){let b=r(a.url,{rel:a.rel,target:a.target,title:a.title});b.setFormat(a.format);b.setIndent(a.indent); | ||
b.setDirection(a.direction);return b}sanitizeUrl(a){try{let b=new URL(a);if(!n.has(b.protocol))return"about:blank"}catch(b){}return a}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),type:"link",url:this.getURL(),version:1}}getURL(){return this.getLatest().__url}setURL(a){this.getWritable().__url=a}getTarget(){return this.getLatest().__target}setTarget(a){this.getWritable().__target=a}getRel(){return this.getLatest().__rel}setRel(a){this.getWritable().__rel= | ||
a}getTitle(){return this.getLatest().__title}setTitle(a){this.getWritable().__title=a}insertNewAfter(a,b=!0){a=r(this.__url,{rel:this.__rel,target:this.__target,title:this.__title});this.insertAfter(a,b);return a}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(a,b){if(!m.$isRangeSelection(b))return!1;a=b.anchor.getNode();let d=b.focus.getNode();return this.isParentOf(a)&&this.isParentOf(d)&&0<b.getTextContent().length}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")|| | ||
this.__url.startsWith("http://")}}function q(a){let b=null;if(l.isHTMLAnchorElement(a)){let d=a.textContent;if(null!==d&&""!==d||0<a.children.length)b=r(a.getAttribute("href")||"",{rel:a.getAttribute("rel"),target:a.getAttribute("target"),title:a.getAttribute("title")})}return{node:b}}function r(a,b){return m.$applyNodeReplacement(new p(a,b))}function t(a){return a instanceof p} | ||
class v extends p{constructor(a,b={},d){super(a,b,d);this.__isUnlinked=void 0!==b.isUnlinked&&null!==b.isUnlinked?b.isUnlinked:!1}static getType(){return"autolink"}static clone(a){return new v(a.__url,{isUnlinked:a.__isUnlinked,rel:a.__rel,target:a.__target,title:a.__title},a.__key)}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(a){let b=this.getWritable();b.__isUnlinked=a;return b}createDOM(a){return this.__isUnlinked?document.createElement("span"):super.createDOM(a)}updateDOM(a,b,d){return super.updateDOM(a, | ||
b,d)||a.__isUnlinked!==this.__isUnlinked}static importJSON(a){let b=w(a.url,{isUnlinked:a.isUnlinked,rel:a.rel,target:a.target,title:a.title});b.setFormat(a.format);b.setIndent(a.indent);b.setDirection(a.direction);return b}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked,type:"autolink",version:1}}insertNewAfter(a,b=!0){a=this.getParentOrThrow().insertNewAfter(a,b);return m.$isElementNode(a)?(b=w(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel, | ||
target:this.__target,title:this.__title}),a.append(b),b):null}}function w(a,b){return m.$applyNodeReplacement(new v(a,b))}function x(a){return a instanceof v}let y=m.createCommand("TOGGLE_LINK_COMMAND"); | ||
function z(a,b={}){let {target:d,title:h}=b,k=void 0===b.rel?"noreferrer":b.rel;b=m.$getSelection();if(m.$isRangeSelection(b))if(b=b.extract(),null===a)b.forEach(f=>{if(f=l.$findMatchingParent(f,e=>!x(e)&&t(e))){let e=f.getChildren();for(let c=0;c<e.length;c++)f.insertBefore(e[c]);f.remove()}});else{if(1===b.length){let c=A(b[0],t);if(null!==c){c.setURL(a);void 0!==d&&c.setTarget(d);null!==k&&c.setRel(k);void 0!==h&&c.setTitle(h);return}}let f=null,e=null;b.forEach(c=>{var g=c.getParent();if(g!== | ||
e&&null!==g&&(!m.$isElementNode(c)||c.isInline()))if(t(g))e=g,g.setURL(a),void 0!==d&&g.setTarget(d),null!==k&&e.setRel(k),void 0!==h&&e.setTitle(h);else if(g.is(f)||(f=g,e=r(a,{rel:k,target:d,title:h}),t(g)?null===c.getPreviousSibling()?g.insertBefore(e):g.insertAfter(e):c.insertBefore(e)),t(c)){if(!c.is(e)){if(null!==e){g=c.getChildren();for(let u=0;u<g.length;u++)e.append(g[u])}c.remove()}}else null!==e&&e.append(c)})}} | ||
function A(a,b){for(;null!==a&&null!==a.getParent()&&!b(a);)a=a.getParentOrThrow();return b(a)?a:null}exports.$createAutoLinkNode=w;exports.$createLinkNode=r;exports.$isAutoLinkNode=x;exports.$isLinkNode=t;exports.$toggleLink=z;exports.AutoLinkNode=v;exports.LinkNode=p;exports.TOGGLE_LINK_COMMAND=y;exports.toggleLink=z | ||
'use strict';var f=require("@lexical/utils"),m=require("lexical"),n;function p(a){let b=new URLSearchParams;b.append("code",a);for(let c=1;c<arguments.length;c++)b.append("v",arguments[c]);throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?${b} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}n=p&&p.__esModule&&Object.prototype.hasOwnProperty.call(p,"default")?p["default"]:p; | ||
let q=new Set(["http:","https:","mailto:","sms:","tel:"]); | ||
class r extends m.ElementNode{static getType(){return"link"}static clone(a){return new r(a.__url,{rel:a.__rel,target:a.__target,title:a.__title},a.__key)}constructor(a,b={},c){super(c);let {target:g=null,rel:h=null,title:k=null}=b;this.__url=a;this.__target=g;this.__rel=h;this.__title=k}createDOM(a){let b=document.createElement("a");b.href=this.sanitizeUrl(this.__url);null!==this.__target&&(b.target=this.__target);null!==this.__rel&&(b.rel=this.__rel);null!==this.__title&&(b.title=this.__title);f.addClassNamesToElement(b, | ||
a.theme.link);return b}updateDOM(a,b){if(b instanceof HTMLAnchorElement){let c=this.__url,g=this.__target,h=this.__rel,k=this.__title;c!==a.__url&&(b.href=c);g!==a.__target&&(g?b.target=g:b.removeAttribute("target"));h!==a.__rel&&(h?b.rel=h:b.removeAttribute("rel"));k!==a.__title&&(k?b.title=k:b.removeAttribute("title"))}return!1}static importDOM(){return{a:()=>({conversion:t,priority:1})}}static importJSON(a){let b=u(a.url,{rel:a.rel,target:a.target,title:a.title});b.setFormat(a.format);b.setIndent(a.indent); | ||
b.setDirection(a.direction);return b}sanitizeUrl(a){try{let b=new URL(a);if(!q.has(b.protocol))return"about:blank"}catch(b){}return a}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),type:"link",url:this.getURL(),version:1}}getURL(){return this.getLatest().__url}setURL(a){this.getWritable().__url=a}getTarget(){return this.getLatest().__target}setTarget(a){this.getWritable().__target=a}getRel(){return this.getLatest().__rel}setRel(a){this.getWritable().__rel= | ||
a}getTitle(){return this.getLatest().__title}setTitle(a){this.getWritable().__title=a}insertNewAfter(a,b=!0){a=u(this.__url,{rel:this.__rel,target:this.__target,title:this.__title});this.insertAfter(a,b);return a}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(a,b){if(!m.$isRangeSelection(b))return!1;a=b.anchor.getNode();let c=b.focus.getNode();return this.isParentOf(a)&&this.isParentOf(c)&&0<b.getTextContent().length}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")|| | ||
this.__url.startsWith("http://")}}function t(a){let b=null;if(f.isHTMLAnchorElement(a)){let c=a.textContent;if(null!==c&&""!==c||0<a.children.length)b=u(a.getAttribute("href")||"",{rel:a.getAttribute("rel"),target:a.getAttribute("target"),title:a.getAttribute("title")})}return{node:b}}function u(a,b){return m.$applyNodeReplacement(new r(a,b))}function v(a){return a instanceof r} | ||
class x extends r{constructor(a,b={},c){super(a,b,c);this.__isUnlinked=void 0!==b.isUnlinked&&null!==b.isUnlinked?b.isUnlinked:!1}static getType(){return"autolink"}static clone(a){return new x(a.__url,{isUnlinked:a.__isUnlinked,rel:a.__rel,target:a.__target,title:a.__title},a.__key)}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(a){let b=this.getWritable();b.__isUnlinked=a;return b}createDOM(a){return this.__isUnlinked?document.createElement("span"):super.createDOM(a)}updateDOM(a,b,c){return super.updateDOM(a, | ||
b,c)||a.__isUnlinked!==this.__isUnlinked}static importJSON(a){let b=y(a.url,{isUnlinked:a.isUnlinked,rel:a.rel,target:a.target,title:a.title});b.setFormat(a.format);b.setIndent(a.indent);b.setDirection(a.direction);return b}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked,type:"autolink",version:1}}insertNewAfter(a,b=!0){a=this.getParentOrThrow().insertNewAfter(a,b);return m.$isElementNode(a)?(b=y(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel, | ||
target:this.__target,title:this.__title}),a.append(b),b):null}}function y(a,b){return m.$applyNodeReplacement(new x(a,b))}function z(a){return a instanceof x}let B=m.createCommand("TOGGLE_LINK_COMMAND");function C(a,b){if("element"===a.type){let c=a.getNode();m.$isElementNode(c)||n(252);return c.getChildren()[a.offset+b]||null}return null} | ||
function D(a){var b=m.$getSelection();if(!m.$isRangeSelection(b))return a();var c=m.$normalizeSelection__EXPERIMENTAL(b);b=c.isBackward();var g=C(c.anchor,b?-1:0);c=C(c.focus,b?0:-1);a=a();if(g||c){var h=m.$getSelection();if(m.$isRangeSelection(h)){h=h.clone();if(g){let k=g.getParent();k&&h.anchor.set(k.getKey(),g.getIndexWithinParent()+(b?1:0),"element")}c&&(g=c.getParent())&&h.focus.set(g.getKey(),c.getIndexWithinParent()+(b?0:1),"element");m.$setSelection(m.$normalizeSelection__EXPERIMENTAL(h))}}return a} | ||
function E(a,b={}){let {target:c,title:g}=b,h=void 0===b.rel?"noreferrer":b.rel;b=m.$getSelection();if(m.$isRangeSelection(b)){var k=b.extract();if(null===a)k.forEach(d=>{if(d=f.$findMatchingParent(d,l=>!z(l)&&v(l))){let l=d.getChildren();for(let e=0;e<l.length;e++)d.insertBefore(l[e]);d.remove()}});else{var A=new Set,w=d=>{A.has(d.getKey())||(A.add(d.getKey()),d.setURL(a),void 0!==c&&d.setTarget(c),void 0!==h&&d.setRel(h),void 0!==g&&d.setTitle(g))};if(1===k.length&&(b=F(k[0],v),null!==b))return w(b); | ||
D(()=>{let d=null;for(let e of k)if(e.isAttached()){var l=F(e,v);if(l)w(l);else{if(m.$isElementNode(e)){if(!e.isInline())continue;if(v(e)){if(!(z(e)||null!==d&&d.getParentOrThrow().isParentOf(e))){w(e);d=e;continue}for(let G of e.getChildren())e.insertBefore(G);e.remove();continue}}l=e.getPreviousSibling();v(l)&&l.is(d)?l.append(e):(d=u(a,{rel:h,target:c,title:g}),e.insertAfter(d),d.append(e))}}})}}} | ||
function F(a,b){for(;null!==a&&null!==a.getParent()&&!b(a);)a=a.getParentOrThrow();return b(a)?a:null}exports.$createAutoLinkNode=y;exports.$createLinkNode=u;exports.$isAutoLinkNode=z;exports.$isLinkNode=v;exports.$toggleLink=E;exports.AutoLinkNode=x;exports.LinkNode=r;exports.TOGGLE_LINK_COMMAND=B;exports.toggleLink=E |
@@ -11,8 +11,8 @@ { | ||
"license": "MIT", | ||
"version": "0.21.0", | ||
"version": "0.21.1-nightly.20241203.0", | ||
"main": "LexicalLink.js", | ||
"types": "index.d.ts", | ||
"dependencies": { | ||
"@lexical/utils": "0.21.0", | ||
"lexical": "0.21.0" | ||
"@lexical/utils": "0.21.1-nightly.20241203.0", | ||
"lexical": "0.21.1-nightly.20241203.0" | ||
}, | ||
@@ -19,0 +19,0 @@ "repository": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54625
1221
+ Added@lexical/clipboard@0.21.1-nightly.20241203.0(transitive)
+ Added@lexical/html@0.21.1-nightly.20241203.0(transitive)
+ Added@lexical/list@0.21.1-nightly.20241203.0(transitive)
+ Added@lexical/selection@0.21.1-nightly.20241203.0(transitive)
+ Added@lexical/table@0.21.1-nightly.20241203.0(transitive)
+ Added@lexical/utils@0.21.1-nightly.20241203.0(transitive)
+ Addedlexical@0.21.1-nightly.20241203.0(transitive)
- Removed@lexical/clipboard@0.21.0(transitive)
- Removed@lexical/html@0.21.0(transitive)
- Removed@lexical/list@0.21.0(transitive)
- Removed@lexical/selection@0.21.0(transitive)
- Removed@lexical/table@0.21.0(transitive)
- Removed@lexical/utils@0.21.0(transitive)
- Removedlexical@0.21.0(transitive)