@webiny/lexical-nodes 6.3.0-beta.4 → 6.4.0-beta.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.
Files changed (45) hide show
  1. package/FontColorNode.js +94 -119
  2. package/FontColorNode.js.map +1 -1
  3. package/HeadingNode.js +160 -183
  4. package/HeadingNode.js.map +1 -1
  5. package/ImageNode.js +101 -131
  6. package/ImageNode.js.map +1 -1
  7. package/LinkNode.js +228 -315
  8. package/LinkNode.js.map +1 -1
  9. package/ListItemNode.js +249 -320
  10. package/ListItemNode.js.map +1 -1
  11. package/ListNode.js +174 -223
  12. package/ListNode.js.map +1 -1
  13. package/ParagraphNode.js +119 -148
  14. package/ParagraphNode.js.map +1 -1
  15. package/QuoteNode.js +97 -102
  16. package/QuoteNode.js.map +1 -1
  17. package/components/ImageNode/ImageComponent.js +117 -147
  18. package/components/ImageNode/ImageComponent.js.map +1 -1
  19. package/components/ImageNode/ImageResizer.js +167 -194
  20. package/components/ImageNode/ImageResizer.js.map +1 -1
  21. package/generateInitialLexicalValue.js +20 -23
  22. package/generateInitialLexicalValue.js.map +1 -1
  23. package/index.js +38 -26
  24. package/index.js.map +1 -1
  25. package/package.json +4 -4
  26. package/prepareLexicalState.js +30 -43
  27. package/prepareLexicalState.js.map +1 -1
  28. package/types.js +0 -3
  29. package/utils/clearNodeFormating.js +14 -15
  30. package/utils/clearNodeFormating.js.map +1 -1
  31. package/utils/formatList.js +277 -368
  32. package/utils/formatList.js.map +1 -1
  33. package/utils/formatToHeading.js +6 -13
  34. package/utils/formatToHeading.js.map +1 -1
  35. package/utils/formatToParagraph.js +6 -7
  36. package/utils/formatToParagraph.js.map +1 -1
  37. package/utils/formatToQuote.js +6 -13
  38. package/utils/formatToQuote.js.map +1 -1
  39. package/utils/getStyleId.js +6 -11
  40. package/utils/getStyleId.js.map +1 -1
  41. package/utils/listNode.js +60 -84
  42. package/utils/listNode.js.map +1 -1
  43. package/utils/toggleLink.js +67 -118
  44. package/utils/toggleLink.js.map +1 -1
  45. package/types.js.map +0 -1
package/LinkNode.js CHANGED
@@ -1,325 +1,238 @@
1
- /** @module @lexical/link */
2
- /**
3
- * Copyright (c) Meta Platforms, Inc. and affiliates.
4
- *
5
- * This source code is licensed under the MIT license found in the
6
- * LICENSE file in the root directory of this source tree.
7
- *
8
- */
9
-
10
- import { $applyNodeReplacement, $isElementNode, $isRangeSelection, createCommand, ElementNode, addClassNamesToElement, isHTMLAnchorElement } from "lexical";
11
- const SUPPORTED_URL_PROTOCOLS = new Set(["http:", "https:", "mailto:", "sms:", "tel:"]);
12
-
13
- /** @noInheritDoc */
14
- export class LinkNode extends ElementNode {
15
- /** @internal */
16
-
17
- /** @internal */
18
-
19
- /** @internal */
20
-
21
- /** @internal */
22
-
23
- /** @internal */
24
-
25
- static getType() {
26
- return "wby-link";
27
- }
28
- static clone(node) {
29
- return new LinkNode(node.__url, {
30
- rel: node.__rel,
31
- target: node.__target,
32
- title: node.__title,
33
- alt: node.__alt
34
- }, node.__key);
35
- }
36
- constructor(url, attributes = {}, key) {
37
- super(key);
38
- const {
39
- target = null,
40
- rel = null,
41
- title = null,
42
- alt = null
43
- } = attributes;
44
- this.__url = url;
45
- this.__target = target;
46
- this.__rel = rel;
47
- this.__title = title;
48
- this.__alt = alt;
49
- }
50
- createDOM(config) {
51
- const element = document.createElement("a");
52
- element.href = this.sanitizeUrl(this.__url);
53
- if (this.__target !== null) {
54
- element.target = this.__target;
55
- }
56
- if (this.__rel !== null) {
57
- element.rel = this.__rel;
58
- }
59
- if (this.__title !== null) {
60
- element.title = this.__title;
61
- }
62
- if (this.__alt) {
63
- element.setAttribute("alt", this.__alt);
64
- }
65
- addClassNamesToElement(element, config.theme.link);
66
- return element;
67
- }
68
- updateDOM(prevNode, anchor) {
69
- const url = this.__url;
70
- const target = this.__target;
71
- const rel = this.__rel;
72
- const title = this.__title;
73
- const alt = this.__alt;
74
- if (url !== prevNode.__url) {
75
- anchor.href = url;
76
- }
77
- if (target !== prevNode.__target) {
78
- if (target) {
79
- anchor.target = target;
80
- } else {
81
- anchor.removeAttribute("target");
82
- }
83
- }
84
- if (rel !== prevNode.__rel) {
85
- if (rel) {
86
- anchor.rel = rel;
87
- } else {
88
- anchor.removeAttribute("rel");
89
- }
90
- }
91
- if (title !== prevNode.__title) {
92
- if (title) {
93
- anchor.title = title;
94
- } else {
95
- anchor.removeAttribute("title");
96
- }
97
- }
98
- if (alt !== prevNode.__alt) {
99
- if (alt) {
100
- anchor.setAttribute("alt", alt);
101
- } else {
102
- anchor.removeAttribute("alt");
103
- }
104
- }
105
- return false;
106
- }
107
- static importDOM() {
108
- return {
109
- a: () => ({
110
- conversion: convertAnchorElement,
111
- priority: 1
112
- })
113
- };
114
- }
115
- static importJSON(serializedNode) {
116
- const node = $createLinkNode(serializedNode.url, {
117
- rel: serializedNode.rel,
118
- target: serializedNode.target,
119
- title: serializedNode.title,
120
- alt: serializedNode.alt
121
- });
122
- node.setFormat(serializedNode.format);
123
- node.setIndent(serializedNode.indent);
124
- node.setDirection(serializedNode.direction);
125
- return node;
126
- }
127
- sanitizeUrl(url) {
128
- try {
129
- const parsedUrl = new URL(url);
130
- if (!SUPPORTED_URL_PROTOCOLS.has(parsedUrl.protocol)) {
131
- return "about:blank";
132
- }
133
- } catch {
134
- return url;
135
- }
136
- return url;
137
- }
138
- exportJSON() {
139
- return {
140
- ...super.exportJSON(),
141
- rel: this.getRel(),
142
- target: this.getTarget(),
143
- title: this.getTitle(),
144
- alt: this.getAlt(),
145
- type: "wby-link",
146
- url: this.getURL()
147
- };
148
- }
149
- getURL() {
150
- return this.getLatest().__url;
151
- }
152
- setURL(url) {
153
- const writable = this.getWritable();
154
- writable.__url = url;
155
- }
156
- getTarget() {
157
- return this.getLatest().__target;
158
- }
159
- setTarget(target) {
160
- const writable = this.getWritable();
161
- writable.__target = target;
162
- }
163
- getRel() {
164
- return this.getLatest().__rel;
165
- }
166
- setRel(rel) {
167
- const writable = this.getWritable();
168
- writable.__rel = rel;
169
- }
170
- getTitle() {
171
- return this.getLatest().__title;
172
- }
173
- setTitle(title) {
174
- const writable = this.getWritable();
175
- writable.__title = title;
176
- }
177
- getAlt() {
178
- return this.__alt;
179
- }
180
- setAlt(text) {
181
- const writable = super.getWritable();
182
- writable.__alt = text;
183
- }
184
- insertNewAfter(selection, restoreSelection = true) {
185
- const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);
186
- if ($isElementNode(element)) {
187
- const linkNode = $createLinkNode(this.__url, {
188
- rel: this.__rel,
189
- target: this.__target,
190
- title: this.__title,
191
- alt: this.__alt
192
- });
193
- element.append(linkNode);
194
- return linkNode;
195
- }
196
- return null;
197
- }
198
- canInsertTextBefore() {
199
- return false;
200
- }
201
- canInsertTextAfter() {
202
- return false;
203
- }
204
- canBeEmpty() {
205
- return false;
206
- }
207
- isInline() {
208
- return true;
209
- }
210
- extractWithChild(_, selection) {
211
- if (!$isRangeSelection(selection)) {
212
- return false;
213
- }
214
- const anchorNode = selection.anchor.getNode();
215
- const focusNode = selection.focus.getNode();
216
- return this.isParentOf(anchorNode) && this.isParentOf(focusNode) && selection.getTextContent().length > 0;
217
- }
1
+ import { $applyNodeReplacement, $isElementNode, $isRangeSelection, ElementNode, addClassNamesToElement, createCommand, isHTMLAnchorElement } from "lexical";
2
+ const SUPPORTED_URL_PROTOCOLS = new Set([
3
+ "http:",
4
+ "https:",
5
+ "mailto:",
6
+ "sms:",
7
+ "tel:"
8
+ ]);
9
+ class LinkNode extends ElementNode {
10
+ static getType() {
11
+ return "wby-link";
12
+ }
13
+ static clone(node) {
14
+ return new LinkNode(node.__url, {
15
+ rel: node.__rel,
16
+ target: node.__target,
17
+ title: node.__title,
18
+ alt: node.__alt
19
+ }, node.__key);
20
+ }
21
+ constructor(url, attributes = {}, key){
22
+ super(key);
23
+ const { target = null, rel = null, title = null, alt = null } = attributes;
24
+ this.__url = url;
25
+ this.__target = target;
26
+ this.__rel = rel;
27
+ this.__title = title;
28
+ this.__alt = alt;
29
+ }
30
+ createDOM(config) {
31
+ const element = document.createElement("a");
32
+ element.href = this.sanitizeUrl(this.__url);
33
+ if (null !== this.__target) element.target = this.__target;
34
+ if (null !== this.__rel) element.rel = this.__rel;
35
+ if (null !== this.__title) element.title = this.__title;
36
+ if (this.__alt) element.setAttribute("alt", this.__alt);
37
+ addClassNamesToElement(element, config.theme.link);
38
+ return element;
39
+ }
40
+ updateDOM(prevNode, anchor) {
41
+ const url = this.__url;
42
+ const target = this.__target;
43
+ const rel = this.__rel;
44
+ const title = this.__title;
45
+ const alt = this.__alt;
46
+ if (url !== prevNode.__url) anchor.href = url;
47
+ if (target !== prevNode.__target) if (target) anchor.target = target;
48
+ else anchor.removeAttribute("target");
49
+ if (rel !== prevNode.__rel) if (rel) anchor.rel = rel;
50
+ else anchor.removeAttribute("rel");
51
+ if (title !== prevNode.__title) if (title) anchor.title = title;
52
+ else anchor.removeAttribute("title");
53
+ if (alt !== prevNode.__alt) if (alt) anchor.setAttribute("alt", alt);
54
+ else anchor.removeAttribute("alt");
55
+ return false;
56
+ }
57
+ static importDOM() {
58
+ return {
59
+ a: ()=>({
60
+ conversion: convertAnchorElement,
61
+ priority: 1
62
+ })
63
+ };
64
+ }
65
+ static importJSON(serializedNode) {
66
+ const node = $createLinkNode(serializedNode.url, {
67
+ rel: serializedNode.rel,
68
+ target: serializedNode.target,
69
+ title: serializedNode.title,
70
+ alt: serializedNode.alt
71
+ });
72
+ node.setFormat(serializedNode.format);
73
+ node.setIndent(serializedNode.indent);
74
+ node.setDirection(serializedNode.direction);
75
+ return node;
76
+ }
77
+ sanitizeUrl(url) {
78
+ try {
79
+ const parsedUrl = new URL(url);
80
+ if (!SUPPORTED_URL_PROTOCOLS.has(parsedUrl.protocol)) return "about:blank";
81
+ } catch {}
82
+ return url;
83
+ }
84
+ exportJSON() {
85
+ return {
86
+ ...super.exportJSON(),
87
+ rel: this.getRel(),
88
+ target: this.getTarget(),
89
+ title: this.getTitle(),
90
+ alt: this.getAlt(),
91
+ type: "wby-link",
92
+ url: this.getURL()
93
+ };
94
+ }
95
+ getURL() {
96
+ return this.getLatest().__url;
97
+ }
98
+ setURL(url) {
99
+ const writable = this.getWritable();
100
+ writable.__url = url;
101
+ }
102
+ getTarget() {
103
+ return this.getLatest().__target;
104
+ }
105
+ setTarget(target) {
106
+ const writable = this.getWritable();
107
+ writable.__target = target;
108
+ }
109
+ getRel() {
110
+ return this.getLatest().__rel;
111
+ }
112
+ setRel(rel) {
113
+ const writable = this.getWritable();
114
+ writable.__rel = rel;
115
+ }
116
+ getTitle() {
117
+ return this.getLatest().__title;
118
+ }
119
+ setTitle(title) {
120
+ const writable = this.getWritable();
121
+ writable.__title = title;
122
+ }
123
+ getAlt() {
124
+ return this.__alt;
125
+ }
126
+ setAlt(text) {
127
+ const writable = super.getWritable();
128
+ writable.__alt = text;
129
+ }
130
+ insertNewAfter(selection, restoreSelection = true) {
131
+ const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);
132
+ if ($isElementNode(element)) {
133
+ const linkNode = $createLinkNode(this.__url, {
134
+ rel: this.__rel,
135
+ target: this.__target,
136
+ title: this.__title,
137
+ alt: this.__alt
138
+ });
139
+ element.append(linkNode);
140
+ return linkNode;
141
+ }
142
+ return null;
143
+ }
144
+ canInsertTextBefore() {
145
+ return false;
146
+ }
147
+ canInsertTextAfter() {
148
+ return false;
149
+ }
150
+ canBeEmpty() {
151
+ return false;
152
+ }
153
+ isInline() {
154
+ return true;
155
+ }
156
+ extractWithChild(_, selection) {
157
+ if (!$isRangeSelection(selection)) return false;
158
+ const anchorNode = selection.anchor.getNode();
159
+ const focusNode = selection.focus.getNode();
160
+ return this.isParentOf(anchorNode) && this.isParentOf(focusNode) && selection.getTextContent().length > 0;
161
+ }
218
162
  }
219
163
  function convertAnchorElement(domNode) {
220
- let node = null;
221
- if (isHTMLAnchorElement(domNode)) {
222
- const content = domNode.textContent;
223
- if (content !== null && content !== "" || domNode.children.length > 0) {
224
- node = $createLinkNode(domNode.getAttribute("href") || "", {
225
- rel: domNode.getAttribute("rel"),
226
- target: domNode.getAttribute("target"),
227
- title: domNode.getAttribute("title"),
228
- alt: domNode.getAttribute("alt")
229
- });
230
- }
231
- }
232
- return {
233
- node
234
- };
164
+ let node = null;
165
+ if (isHTMLAnchorElement(domNode)) {
166
+ const content = domNode.textContent;
167
+ if (null !== content && "" !== content || domNode.children.length > 0) node = $createLinkNode(domNode.getAttribute("href") || "", {
168
+ rel: domNode.getAttribute("rel"),
169
+ target: domNode.getAttribute("target"),
170
+ title: domNode.getAttribute("title"),
171
+ alt: domNode.getAttribute("alt")
172
+ });
173
+ }
174
+ return {
175
+ node
176
+ };
235
177
  }
236
-
237
- /**
238
- * Takes a URL and creates a LinkNode.
239
- * @param url - The URL the LinkNode should direct to.
240
- * @param attributes - Optional HTML a tag attributes { target, rel, title }
241
- * @returns The LinkNode.
242
- */
243
- export function $createLinkNode(url, attributes) {
244
- return $applyNodeReplacement(new LinkNode(url, attributes));
178
+ function $createLinkNode(url, attributes) {
179
+ return $applyNodeReplacement(new LinkNode(url, attributes));
245
180
  }
246
-
247
- /**
248
- * Determines if node is a LinkNode.
249
- * @param node - The node to be checked.
250
- * @returns true if node is a LinkNode, false otherwise.
251
- */
252
- export function $isLinkNode(node) {
253
- return node instanceof LinkNode;
181
+ function $isLinkNode(node) {
182
+ return node instanceof LinkNode;
254
183
  }
255
- // Custom node type to override `canInsertTextAfter` that will
256
- // allow typing within the link
257
- export class AutoLinkNode extends LinkNode {
258
- static getType() {
259
- return "autolink";
260
- }
261
- static clone(node) {
262
- return new AutoLinkNode(node.__url, {
263
- rel: node.__rel,
264
- target: node.__target,
265
- title: node.__title
266
- }, node.__key);
267
- }
268
- static importJSON(serializedNode) {
269
- const node = $createAutoLinkNode(serializedNode.url, {
270
- rel: serializedNode.rel,
271
- target: serializedNode.target,
272
- title: serializedNode.title
273
- });
274
- node.setFormat(serializedNode.format);
275
- node.setIndent(serializedNode.indent);
276
- node.setDirection(serializedNode.direction);
277
- return node;
278
- }
279
- static importDOM() {
280
- // TODO: Should link node should handle the import over autolink?
281
- return null;
282
- }
283
- exportJSON() {
284
- return {
285
- ...super.exportJSON(),
286
- type: "autolink"
287
- };
288
- }
289
- insertNewAfter(selection, restoreSelection = true) {
290
- const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);
291
- if ($isElementNode(element)) {
292
- const linkNode = $createAutoLinkNode(this.__url, {
293
- rel: this.__rel,
294
- target: this.__target,
295
- title: this.__title
296
- });
297
- element.append(linkNode);
298
- return linkNode;
299
- }
300
- return null;
301
- }
184
+ class AutoLinkNode extends LinkNode {
185
+ static getType() {
186
+ return "autolink";
187
+ }
188
+ static clone(node) {
189
+ return new AutoLinkNode(node.__url, {
190
+ rel: node.__rel,
191
+ target: node.__target,
192
+ title: node.__title
193
+ }, node.__key);
194
+ }
195
+ static importJSON(serializedNode) {
196
+ const node = $createAutoLinkNode(serializedNode.url, {
197
+ rel: serializedNode.rel,
198
+ target: serializedNode.target,
199
+ title: serializedNode.title
200
+ });
201
+ node.setFormat(serializedNode.format);
202
+ node.setIndent(serializedNode.indent);
203
+ node.setDirection(serializedNode.direction);
204
+ return node;
205
+ }
206
+ static importDOM() {
207
+ return null;
208
+ }
209
+ exportJSON() {
210
+ return {
211
+ ...super.exportJSON(),
212
+ type: "autolink"
213
+ };
214
+ }
215
+ insertNewAfter(selection, restoreSelection = true) {
216
+ const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);
217
+ if ($isElementNode(element)) {
218
+ const linkNode = $createAutoLinkNode(this.__url, {
219
+ rel: this.__rel,
220
+ target: this.__target,
221
+ title: this.__title
222
+ });
223
+ element.append(linkNode);
224
+ return linkNode;
225
+ }
226
+ return null;
227
+ }
302
228
  }
303
-
304
- /**
305
- * Takes a URL and creates an AutoLinkNode. AutoLinkNodes are generally automatically generated
306
- * during typing, which is especially useful when a button to generate a LinkNode is not practical.
307
- * @param url - The URL the LinkNode should direct to.
308
- * @param attributes - Optional HTML a tag attributes. { target, rel, title }
309
- * @returns The LinkNode.
310
- */
311
- export function $createAutoLinkNode(url, attributes) {
312
- return $applyNodeReplacement(new AutoLinkNode(url, attributes));
229
+ function $createAutoLinkNode(url, attributes) {
230
+ return $applyNodeReplacement(new AutoLinkNode(url, attributes));
313
231
  }
314
-
315
- /**
316
- * Determines if node is an AutoLinkNode.
317
- * @param node - The node to be checked.
318
- * @returns true if node is an AutoLinkNode, false otherwise.
319
- */
320
- export function $isAutoLinkNode(node) {
321
- return node instanceof AutoLinkNode;
232
+ function $isAutoLinkNode(node) {
233
+ return node instanceof AutoLinkNode;
322
234
  }
323
- export const TOGGLE_LINK_COMMAND = createCommand("TOGGLE_LINK_COMMAND");
235
+ const TOGGLE_LINK_COMMAND = createCommand("TOGGLE_LINK_COMMAND");
236
+ export { $createAutoLinkNode, $createLinkNode, $isAutoLinkNode, $isLinkNode, AutoLinkNode, LinkNode, TOGGLE_LINK_COMMAND };
324
237
 
325
238
  //# sourceMappingURL=LinkNode.js.map
package/LinkNode.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"names":["$applyNodeReplacement","$isElementNode","$isRangeSelection","createCommand","ElementNode","addClassNamesToElement","isHTMLAnchorElement","SUPPORTED_URL_PROTOCOLS","Set","LinkNode","getType","clone","node","__url","rel","__rel","target","__target","title","__title","alt","__alt","__key","constructor","url","attributes","key","createDOM","config","element","document","createElement","href","sanitizeUrl","setAttribute","theme","link","updateDOM","prevNode","anchor","removeAttribute","importDOM","a","conversion","convertAnchorElement","priority","importJSON","serializedNode","$createLinkNode","setFormat","format","setIndent","indent","setDirection","direction","parsedUrl","URL","has","protocol","exportJSON","getRel","getTarget","getTitle","getAlt","type","getURL","getLatest","setURL","writable","getWritable","setTarget","setRel","setTitle","setAlt","text","insertNewAfter","selection","restoreSelection","getParentOrThrow","linkNode","append","canInsertTextBefore","canInsertTextAfter","canBeEmpty","isInline","extractWithChild","_","anchorNode","getNode","focusNode","focus","isParentOf","getTextContent","length","domNode","content","textContent","children","getAttribute","$isLinkNode","AutoLinkNode","$createAutoLinkNode","$isAutoLinkNode","TOGGLE_LINK_COMMAND"],"sources":["LinkNode.ts"],"sourcesContent":["/** @module @lexical/link */\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n EditorConfig,\n RangeSelection,\n LexicalCommand,\n LexicalNode,\n NodeKey,\n SerializedElementNode,\n Spread\n} from \"lexical\";\n\nimport {\n $applyNodeReplacement,\n $isElementNode,\n $isRangeSelection,\n createCommand,\n ElementNode,\n addClassNamesToElement,\n isHTMLAnchorElement\n} from \"lexical\";\n\nexport type LinkAttributes = {\n rel?: null | string;\n target?: null | string;\n title?: null | string;\n alt?: null | string;\n};\n\ndeclare global {\n interface HTMLAnchorElement {\n alt?: string;\n }\n}\n\nexport type SerializedLinkNode = Spread<\n {\n url: string;\n },\n Spread<LinkAttributes, SerializedElementNode>\n>;\n\nconst SUPPORTED_URL_PROTOCOLS = new Set([\"http:\", \"https:\", \"mailto:\", \"sms:\", \"tel:\"]);\n\n/** @noInheritDoc */\nexport class LinkNode extends ElementNode {\n /** @internal */\n __url: string;\n /** @internal */\n __target: null | string;\n /** @internal */\n __rel: null | string;\n /** @internal */\n __title: null | string;\n /** @internal */\n __alt: null | string;\n\n static override getType(): string {\n return \"wby-link\";\n }\n\n static override clone(node: LinkNode): LinkNode {\n return new LinkNode(\n node.__url,\n { rel: node.__rel, target: node.__target, title: node.__title, alt: node.__alt },\n node.__key\n );\n }\n\n constructor(url: string, attributes: LinkAttributes = {}, key?: NodeKey) {\n super(key);\n const { target = null, rel = null, title = null, alt = null } = attributes;\n this.__url = url;\n this.__target = target;\n this.__rel = rel;\n this.__title = title;\n this.__alt = alt;\n }\n\n override createDOM(config: EditorConfig): HTMLAnchorElement {\n const element = document.createElement(\"a\") as HTMLAnchorElement;\n element.href = this.sanitizeUrl(this.__url);\n if (this.__target !== null) {\n element.target = this.__target;\n }\n if (this.__rel !== null) {\n element.rel = this.__rel;\n }\n if (this.__title !== null) {\n element.title = this.__title;\n }\n if (this.__alt) {\n element.setAttribute(\"alt\", this.__alt);\n }\n addClassNamesToElement(element, config.theme.link);\n return element;\n }\n\n override updateDOM(prevNode: LinkNode, anchor: HTMLAnchorElement): boolean {\n const url = this.__url;\n const target = this.__target;\n const rel = this.__rel;\n const title = this.__title;\n const alt = this.__alt;\n\n if (url !== prevNode.__url) {\n anchor.href = url;\n }\n\n if (target !== prevNode.__target) {\n if (target) {\n anchor.target = target;\n } else {\n anchor.removeAttribute(\"target\");\n }\n }\n\n if (rel !== prevNode.__rel) {\n if (rel) {\n anchor.rel = rel;\n } else {\n anchor.removeAttribute(\"rel\");\n }\n }\n\n if (title !== prevNode.__title) {\n if (title) {\n anchor.title = title;\n } else {\n anchor.removeAttribute(\"title\");\n }\n }\n\n if (alt !== prevNode.__alt) {\n if (alt) {\n anchor.setAttribute(\"alt\", alt);\n } else {\n anchor.removeAttribute(\"alt\");\n }\n }\n\n return false;\n }\n\n static override importDOM(): DOMConversionMap | null {\n return {\n a: () => ({\n conversion: convertAnchorElement,\n priority: 1\n })\n };\n }\n\n static override importJSON(\n serializedNode: SerializedLinkNode | SerializedAutoLinkNode\n ): LinkNode {\n const node = $createLinkNode(serializedNode.url, {\n rel: serializedNode.rel,\n target: serializedNode.target,\n title: serializedNode.title,\n alt: serializedNode.alt\n });\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n sanitizeUrl(url: string): string {\n try {\n const parsedUrl = new URL(url);\n\n if (!SUPPORTED_URL_PROTOCOLS.has(parsedUrl.protocol)) {\n return \"about:blank\";\n }\n } catch {\n return url;\n }\n return url;\n }\n\n override exportJSON(): SerializedLinkNode | SerializedAutoLinkNode {\n return {\n ...super.exportJSON(),\n rel: this.getRel(),\n target: this.getTarget(),\n title: this.getTitle(),\n alt: this.getAlt(),\n type: \"wby-link\",\n url: this.getURL()\n };\n }\n\n getURL(): string {\n return this.getLatest().__url;\n }\n\n setURL(url: string): void {\n const writable = this.getWritable();\n writable.__url = url;\n }\n\n getTarget(): null | string {\n return this.getLatest().__target;\n }\n\n setTarget(target: null | string): void {\n const writable = this.getWritable();\n writable.__target = target;\n }\n\n getRel(): null | string {\n return this.getLatest().__rel;\n }\n\n setRel(rel: null | string): void {\n const writable = this.getWritable();\n writable.__rel = rel;\n }\n\n getTitle(): null | string {\n return this.getLatest().__title;\n }\n\n setTitle(title: null | string): void {\n const writable = this.getWritable();\n writable.__title = title;\n }\n\n getAlt(): string | null {\n return this.__alt;\n }\n\n setAlt(text: string | null): void {\n const writable = super.getWritable();\n writable.__alt = text;\n }\n\n override insertNewAfter(\n selection: RangeSelection,\n restoreSelection = true\n ): null | ElementNode {\n const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);\n if ($isElementNode(element)) {\n const linkNode = $createLinkNode(this.__url, {\n rel: this.__rel,\n target: this.__target,\n title: this.__title,\n alt: this.__alt\n });\n element.append(linkNode);\n return linkNode;\n }\n return null;\n }\n\n override canInsertTextBefore(): false {\n return false;\n }\n\n override canInsertTextAfter(): false {\n return false;\n }\n\n override canBeEmpty(): false {\n return false;\n }\n\n override isInline(): true {\n return true;\n }\n\n override extractWithChild(_: LexicalNode, selection: RangeSelection): boolean {\n if (!$isRangeSelection(selection)) {\n return false;\n }\n\n const anchorNode = selection.anchor.getNode();\n const focusNode = selection.focus.getNode();\n\n return (\n this.isParentOf(anchorNode) &&\n this.isParentOf(focusNode) &&\n selection.getTextContent().length > 0\n );\n }\n}\n\nfunction convertAnchorElement(domNode: Node): DOMConversionOutput {\n let node = null;\n if (isHTMLAnchorElement(domNode)) {\n const content = domNode.textContent;\n if ((content !== null && content !== \"\") || domNode.children.length > 0) {\n node = $createLinkNode(domNode.getAttribute(\"href\") || \"\", {\n rel: domNode.getAttribute(\"rel\"),\n target: domNode.getAttribute(\"target\"),\n title: domNode.getAttribute(\"title\"),\n alt: domNode.getAttribute(\"alt\")\n });\n }\n }\n return { node };\n}\n\n/**\n * Takes a URL and creates a LinkNode.\n * @param url - The URL the LinkNode should direct to.\n * @param attributes - Optional HTML a tag attributes { target, rel, title }\n * @returns The LinkNode.\n */\nexport function $createLinkNode(url: string, attributes?: LinkAttributes): LinkNode {\n return $applyNodeReplacement(new LinkNode(url, attributes));\n}\n\n/**\n * Determines if node is a LinkNode.\n * @param node - The node to be checked.\n * @returns true if node is a LinkNode, false otherwise.\n */\nexport function $isLinkNode(node: LexicalNode | null | undefined): node is LinkNode {\n return node instanceof LinkNode;\n}\n\nexport type SerializedAutoLinkNode = SerializedLinkNode;\n\n// Custom node type to override `canInsertTextAfter` that will\n// allow typing within the link\nexport class AutoLinkNode extends LinkNode {\n static override getType(): string {\n return \"autolink\";\n }\n\n static override clone(node: AutoLinkNode): AutoLinkNode {\n return new AutoLinkNode(\n node.__url,\n { rel: node.__rel, target: node.__target, title: node.__title },\n node.__key\n );\n }\n\n static override importJSON(serializedNode: SerializedAutoLinkNode): AutoLinkNode {\n const node = $createAutoLinkNode(serializedNode.url, {\n rel: serializedNode.rel,\n target: serializedNode.target,\n title: serializedNode.title\n });\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n static override importDOM(): null {\n // TODO: Should link node should handle the import over autolink?\n return null;\n }\n\n override exportJSON(): SerializedAutoLinkNode {\n return {\n ...super.exportJSON(),\n type: \"autolink\"\n };\n }\n\n override insertNewAfter(\n selection: RangeSelection,\n restoreSelection = true\n ): null | ElementNode {\n const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);\n if ($isElementNode(element)) {\n const linkNode = $createAutoLinkNode(this.__url, {\n rel: this.__rel,\n target: this.__target,\n title: this.__title\n });\n element.append(linkNode);\n return linkNode;\n }\n return null;\n }\n}\n\n/**\n * Takes a URL and creates an AutoLinkNode. AutoLinkNodes are generally automatically generated\n * during typing, which is especially useful when a button to generate a LinkNode is not practical.\n * @param url - The URL the LinkNode should direct to.\n * @param attributes - Optional HTML a tag attributes. { target, rel, title }\n * @returns The LinkNode.\n */\nexport function $createAutoLinkNode(url: string, attributes?: LinkAttributes): AutoLinkNode {\n return $applyNodeReplacement(new AutoLinkNode(url, attributes));\n}\n\n/**\n * Determines if node is an AutoLinkNode.\n * @param node - The node to be checked.\n * @returns true if node is an AutoLinkNode, false otherwise.\n */\nexport function $isAutoLinkNode(node: LexicalNode | null | undefined): node is AutoLinkNode {\n return node instanceof AutoLinkNode;\n}\n\nexport const TOGGLE_LINK_COMMAND: LexicalCommand<\n string | ({ url: string } & LinkAttributes) | null\n> = createCommand(\"TOGGLE_LINK_COMMAND\");\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"LinkNode.js","sources":["../src/LinkNode.ts"],"sourcesContent":["/** @module @lexical/link */\n/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n EditorConfig,\n RangeSelection,\n LexicalCommand,\n LexicalNode,\n NodeKey,\n SerializedElementNode,\n Spread\n} from \"lexical\";\n\nimport {\n $applyNodeReplacement,\n $isElementNode,\n $isRangeSelection,\n createCommand,\n ElementNode,\n addClassNamesToElement,\n isHTMLAnchorElement\n} from \"lexical\";\n\nexport type LinkAttributes = {\n rel?: null | string;\n target?: null | string;\n title?: null | string;\n alt?: null | string;\n};\n\ndeclare global {\n interface HTMLAnchorElement {\n alt?: string;\n }\n}\n\nexport type SerializedLinkNode = Spread<\n {\n url: string;\n },\n Spread<LinkAttributes, SerializedElementNode>\n>;\n\nconst SUPPORTED_URL_PROTOCOLS = new Set([\"http:\", \"https:\", \"mailto:\", \"sms:\", \"tel:\"]);\n\n/** @noInheritDoc */\nexport class LinkNode extends ElementNode {\n /** @internal */\n __url: string;\n /** @internal */\n __target: null | string;\n /** @internal */\n __rel: null | string;\n /** @internal */\n __title: null | string;\n /** @internal */\n __alt: null | string;\n\n static override getType(): string {\n return \"wby-link\";\n }\n\n static override clone(node: LinkNode): LinkNode {\n return new LinkNode(\n node.__url,\n { rel: node.__rel, target: node.__target, title: node.__title, alt: node.__alt },\n node.__key\n );\n }\n\n constructor(url: string, attributes: LinkAttributes = {}, key?: NodeKey) {\n super(key);\n const { target = null, rel = null, title = null, alt = null } = attributes;\n this.__url = url;\n this.__target = target;\n this.__rel = rel;\n this.__title = title;\n this.__alt = alt;\n }\n\n override createDOM(config: EditorConfig): HTMLAnchorElement {\n const element = document.createElement(\"a\") as HTMLAnchorElement;\n element.href = this.sanitizeUrl(this.__url);\n if (this.__target !== null) {\n element.target = this.__target;\n }\n if (this.__rel !== null) {\n element.rel = this.__rel;\n }\n if (this.__title !== null) {\n element.title = this.__title;\n }\n if (this.__alt) {\n element.setAttribute(\"alt\", this.__alt);\n }\n addClassNamesToElement(element, config.theme.link);\n return element;\n }\n\n override updateDOM(prevNode: LinkNode, anchor: HTMLAnchorElement): boolean {\n const url = this.__url;\n const target = this.__target;\n const rel = this.__rel;\n const title = this.__title;\n const alt = this.__alt;\n\n if (url !== prevNode.__url) {\n anchor.href = url;\n }\n\n if (target !== prevNode.__target) {\n if (target) {\n anchor.target = target;\n } else {\n anchor.removeAttribute(\"target\");\n }\n }\n\n if (rel !== prevNode.__rel) {\n if (rel) {\n anchor.rel = rel;\n } else {\n anchor.removeAttribute(\"rel\");\n }\n }\n\n if (title !== prevNode.__title) {\n if (title) {\n anchor.title = title;\n } else {\n anchor.removeAttribute(\"title\");\n }\n }\n\n if (alt !== prevNode.__alt) {\n if (alt) {\n anchor.setAttribute(\"alt\", alt);\n } else {\n anchor.removeAttribute(\"alt\");\n }\n }\n\n return false;\n }\n\n static override importDOM(): DOMConversionMap | null {\n return {\n a: () => ({\n conversion: convertAnchorElement,\n priority: 1\n })\n };\n }\n\n static override importJSON(\n serializedNode: SerializedLinkNode | SerializedAutoLinkNode\n ): LinkNode {\n const node = $createLinkNode(serializedNode.url, {\n rel: serializedNode.rel,\n target: serializedNode.target,\n title: serializedNode.title,\n alt: serializedNode.alt\n });\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n sanitizeUrl(url: string): string {\n try {\n const parsedUrl = new URL(url);\n\n if (!SUPPORTED_URL_PROTOCOLS.has(parsedUrl.protocol)) {\n return \"about:blank\";\n }\n } catch {\n return url;\n }\n return url;\n }\n\n override exportJSON(): SerializedLinkNode | SerializedAutoLinkNode {\n return {\n ...super.exportJSON(),\n rel: this.getRel(),\n target: this.getTarget(),\n title: this.getTitle(),\n alt: this.getAlt(),\n type: \"wby-link\",\n url: this.getURL()\n };\n }\n\n getURL(): string {\n return this.getLatest().__url;\n }\n\n setURL(url: string): void {\n const writable = this.getWritable();\n writable.__url = url;\n }\n\n getTarget(): null | string {\n return this.getLatest().__target;\n }\n\n setTarget(target: null | string): void {\n const writable = this.getWritable();\n writable.__target = target;\n }\n\n getRel(): null | string {\n return this.getLatest().__rel;\n }\n\n setRel(rel: null | string): void {\n const writable = this.getWritable();\n writable.__rel = rel;\n }\n\n getTitle(): null | string {\n return this.getLatest().__title;\n }\n\n setTitle(title: null | string): void {\n const writable = this.getWritable();\n writable.__title = title;\n }\n\n getAlt(): string | null {\n return this.__alt;\n }\n\n setAlt(text: string | null): void {\n const writable = super.getWritable();\n writable.__alt = text;\n }\n\n override insertNewAfter(\n selection: RangeSelection,\n restoreSelection = true\n ): null | ElementNode {\n const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);\n if ($isElementNode(element)) {\n const linkNode = $createLinkNode(this.__url, {\n rel: this.__rel,\n target: this.__target,\n title: this.__title,\n alt: this.__alt\n });\n element.append(linkNode);\n return linkNode;\n }\n return null;\n }\n\n override canInsertTextBefore(): false {\n return false;\n }\n\n override canInsertTextAfter(): false {\n return false;\n }\n\n override canBeEmpty(): false {\n return false;\n }\n\n override isInline(): true {\n return true;\n }\n\n override extractWithChild(_: LexicalNode, selection: RangeSelection): boolean {\n if (!$isRangeSelection(selection)) {\n return false;\n }\n\n const anchorNode = selection.anchor.getNode();\n const focusNode = selection.focus.getNode();\n\n return (\n this.isParentOf(anchorNode) &&\n this.isParentOf(focusNode) &&\n selection.getTextContent().length > 0\n );\n }\n}\n\nfunction convertAnchorElement(domNode: Node): DOMConversionOutput {\n let node = null;\n if (isHTMLAnchorElement(domNode)) {\n const content = domNode.textContent;\n if ((content !== null && content !== \"\") || domNode.children.length > 0) {\n node = $createLinkNode(domNode.getAttribute(\"href\") || \"\", {\n rel: domNode.getAttribute(\"rel\"),\n target: domNode.getAttribute(\"target\"),\n title: domNode.getAttribute(\"title\"),\n alt: domNode.getAttribute(\"alt\")\n });\n }\n }\n return { node };\n}\n\n/**\n * Takes a URL and creates a LinkNode.\n * @param url - The URL the LinkNode should direct to.\n * @param attributes - Optional HTML a tag attributes { target, rel, title }\n * @returns The LinkNode.\n */\nexport function $createLinkNode(url: string, attributes?: LinkAttributes): LinkNode {\n return $applyNodeReplacement(new LinkNode(url, attributes));\n}\n\n/**\n * Determines if node is a LinkNode.\n * @param node - The node to be checked.\n * @returns true if node is a LinkNode, false otherwise.\n */\nexport function $isLinkNode(node: LexicalNode | null | undefined): node is LinkNode {\n return node instanceof LinkNode;\n}\n\nexport type SerializedAutoLinkNode = SerializedLinkNode;\n\n// Custom node type to override `canInsertTextAfter` that will\n// allow typing within the link\nexport class AutoLinkNode extends LinkNode {\n static override getType(): string {\n return \"autolink\";\n }\n\n static override clone(node: AutoLinkNode): AutoLinkNode {\n return new AutoLinkNode(\n node.__url,\n { rel: node.__rel, target: node.__target, title: node.__title },\n node.__key\n );\n }\n\n static override importJSON(serializedNode: SerializedAutoLinkNode): AutoLinkNode {\n const node = $createAutoLinkNode(serializedNode.url, {\n rel: serializedNode.rel,\n target: serializedNode.target,\n title: serializedNode.title\n });\n node.setFormat(serializedNode.format);\n node.setIndent(serializedNode.indent);\n node.setDirection(serializedNode.direction);\n return node;\n }\n\n static override importDOM(): null {\n // TODO: Should link node should handle the import over autolink?\n return null;\n }\n\n override exportJSON(): SerializedAutoLinkNode {\n return {\n ...super.exportJSON(),\n type: \"autolink\"\n };\n }\n\n override insertNewAfter(\n selection: RangeSelection,\n restoreSelection = true\n ): null | ElementNode {\n const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);\n if ($isElementNode(element)) {\n const linkNode = $createAutoLinkNode(this.__url, {\n rel: this.__rel,\n target: this.__target,\n title: this.__title\n });\n element.append(linkNode);\n return linkNode;\n }\n return null;\n }\n}\n\n/**\n * Takes a URL and creates an AutoLinkNode. AutoLinkNodes are generally automatically generated\n * during typing, which is especially useful when a button to generate a LinkNode is not practical.\n * @param url - The URL the LinkNode should direct to.\n * @param attributes - Optional HTML a tag attributes. { target, rel, title }\n * @returns The LinkNode.\n */\nexport function $createAutoLinkNode(url: string, attributes?: LinkAttributes): AutoLinkNode {\n return $applyNodeReplacement(new AutoLinkNode(url, attributes));\n}\n\n/**\n * Determines if node is an AutoLinkNode.\n * @param node - The node to be checked.\n * @returns true if node is an AutoLinkNode, false otherwise.\n */\nexport function $isAutoLinkNode(node: LexicalNode | null | undefined): node is AutoLinkNode {\n return node instanceof AutoLinkNode;\n}\n\nexport const TOGGLE_LINK_COMMAND: LexicalCommand<\n string | ({ url: string } & LinkAttributes) | null\n> = createCommand(\"TOGGLE_LINK_COMMAND\");\n"],"names":["SUPPORTED_URL_PROTOCOLS","Set","LinkNode","ElementNode","node","url","attributes","key","target","rel","title","alt","config","element","document","addClassNamesToElement","prevNode","anchor","convertAnchorElement","serializedNode","$createLinkNode","parsedUrl","URL","writable","text","selection","restoreSelection","$isElementNode","linkNode","_","$isRangeSelection","anchorNode","focusNode","domNode","isHTMLAnchorElement","content","$applyNodeReplacement","$isLinkNode","AutoLinkNode","$createAutoLinkNode","$isAutoLinkNode","TOGGLE_LINK_COMMAND","createCommand"],"mappings":"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"}