@lexical/link 0.13.1 → 0.14.1
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/LexicalLink.dev.esm.js +412 -0
- package/LexicalLink.esm.js +17 -0
- package/LexicalLink.js +1 -1
- package/LexicalLink.prod.esm.js +7 -0
- package/README.md +2 -0
- package/package.json +6 -4
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import { addClassNamesToElement, isHTMLAnchorElement } from '@lexical/utils';
|
|
8
|
+
import { createCommand, ElementNode, $applyNodeReplacement, $isRangeSelection, $isElementNode, $getSelection } from 'lexical';
|
|
9
|
+
|
|
10
|
+
/** @module @lexical/link */
|
|
11
|
+
const SUPPORTED_URL_PROTOCOLS = new Set(['http:', 'https:', 'mailto:', 'sms:', 'tel:']);
|
|
12
|
+
|
|
13
|
+
/** @noInheritDoc */
|
|
14
|
+
class LinkNode extends ElementNode {
|
|
15
|
+
/** @internal */
|
|
16
|
+
|
|
17
|
+
/** @internal */
|
|
18
|
+
|
|
19
|
+
/** @internal */
|
|
20
|
+
|
|
21
|
+
/** @internal */
|
|
22
|
+
|
|
23
|
+
static getType() {
|
|
24
|
+
return 'link';
|
|
25
|
+
}
|
|
26
|
+
static clone(node) {
|
|
27
|
+
return new LinkNode(node.__url, {
|
|
28
|
+
rel: node.__rel,
|
|
29
|
+
target: node.__target,
|
|
30
|
+
title: node.__title
|
|
31
|
+
}, node.__key);
|
|
32
|
+
}
|
|
33
|
+
constructor(url, attributes = {}, key) {
|
|
34
|
+
super(key);
|
|
35
|
+
const {
|
|
36
|
+
target = null,
|
|
37
|
+
rel = null,
|
|
38
|
+
title = null
|
|
39
|
+
} = attributes;
|
|
40
|
+
this.__url = url;
|
|
41
|
+
this.__target = target;
|
|
42
|
+
this.__rel = rel;
|
|
43
|
+
this.__title = title;
|
|
44
|
+
}
|
|
45
|
+
createDOM(config) {
|
|
46
|
+
const element = document.createElement('a');
|
|
47
|
+
element.href = this.sanitizeUrl(this.__url);
|
|
48
|
+
if (this.__target !== null) {
|
|
49
|
+
element.target = this.__target;
|
|
50
|
+
}
|
|
51
|
+
if (this.__rel !== null) {
|
|
52
|
+
element.rel = this.__rel;
|
|
53
|
+
}
|
|
54
|
+
if (this.__title !== null) {
|
|
55
|
+
element.title = this.__title;
|
|
56
|
+
}
|
|
57
|
+
addClassNamesToElement(element, config.theme.link);
|
|
58
|
+
return element;
|
|
59
|
+
}
|
|
60
|
+
updateDOM(prevNode, anchor, config) {
|
|
61
|
+
const url = this.__url;
|
|
62
|
+
const target = this.__target;
|
|
63
|
+
const rel = this.__rel;
|
|
64
|
+
const title = this.__title;
|
|
65
|
+
if (url !== prevNode.__url) {
|
|
66
|
+
anchor.href = url;
|
|
67
|
+
}
|
|
68
|
+
if (target !== prevNode.__target) {
|
|
69
|
+
if (target) {
|
|
70
|
+
anchor.target = target;
|
|
71
|
+
} else {
|
|
72
|
+
anchor.removeAttribute('target');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (rel !== prevNode.__rel) {
|
|
76
|
+
if (rel) {
|
|
77
|
+
anchor.rel = rel;
|
|
78
|
+
} else {
|
|
79
|
+
anchor.removeAttribute('rel');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (title !== prevNode.__title) {
|
|
83
|
+
if (title) {
|
|
84
|
+
anchor.title = title;
|
|
85
|
+
} else {
|
|
86
|
+
anchor.removeAttribute('title');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
static importDOM() {
|
|
92
|
+
return {
|
|
93
|
+
a: node => ({
|
|
94
|
+
conversion: convertAnchorElement,
|
|
95
|
+
priority: 1
|
|
96
|
+
})
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
static importJSON(serializedNode) {
|
|
100
|
+
const node = $createLinkNode(serializedNode.url, {
|
|
101
|
+
rel: serializedNode.rel,
|
|
102
|
+
target: serializedNode.target,
|
|
103
|
+
title: serializedNode.title
|
|
104
|
+
});
|
|
105
|
+
node.setFormat(serializedNode.format);
|
|
106
|
+
node.setIndent(serializedNode.indent);
|
|
107
|
+
node.setDirection(serializedNode.direction);
|
|
108
|
+
return node;
|
|
109
|
+
}
|
|
110
|
+
sanitizeUrl(url) {
|
|
111
|
+
try {
|
|
112
|
+
const parsedUrl = new URL(url);
|
|
113
|
+
// eslint-disable-next-line no-script-url
|
|
114
|
+
if (!SUPPORTED_URL_PROTOCOLS.has(parsedUrl.protocol)) {
|
|
115
|
+
return 'about:blank';
|
|
116
|
+
}
|
|
117
|
+
} catch (_unused) {
|
|
118
|
+
return url;
|
|
119
|
+
}
|
|
120
|
+
return url;
|
|
121
|
+
}
|
|
122
|
+
exportJSON() {
|
|
123
|
+
return {
|
|
124
|
+
...super.exportJSON(),
|
|
125
|
+
rel: this.getRel(),
|
|
126
|
+
target: this.getTarget(),
|
|
127
|
+
title: this.getTitle(),
|
|
128
|
+
type: 'link',
|
|
129
|
+
url: this.getURL(),
|
|
130
|
+
version: 1
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
getURL() {
|
|
134
|
+
return this.getLatest().__url;
|
|
135
|
+
}
|
|
136
|
+
setURL(url) {
|
|
137
|
+
const writable = this.getWritable();
|
|
138
|
+
writable.__url = url;
|
|
139
|
+
}
|
|
140
|
+
getTarget() {
|
|
141
|
+
return this.getLatest().__target;
|
|
142
|
+
}
|
|
143
|
+
setTarget(target) {
|
|
144
|
+
const writable = this.getWritable();
|
|
145
|
+
writable.__target = target;
|
|
146
|
+
}
|
|
147
|
+
getRel() {
|
|
148
|
+
return this.getLatest().__rel;
|
|
149
|
+
}
|
|
150
|
+
setRel(rel) {
|
|
151
|
+
const writable = this.getWritable();
|
|
152
|
+
writable.__rel = rel;
|
|
153
|
+
}
|
|
154
|
+
getTitle() {
|
|
155
|
+
return this.getLatest().__title;
|
|
156
|
+
}
|
|
157
|
+
setTitle(title) {
|
|
158
|
+
const writable = this.getWritable();
|
|
159
|
+
writable.__title = title;
|
|
160
|
+
}
|
|
161
|
+
insertNewAfter(_, restoreSelection = true) {
|
|
162
|
+
const linkNode = $createLinkNode(this.__url, {
|
|
163
|
+
rel: this.__rel,
|
|
164
|
+
target: this.__target,
|
|
165
|
+
title: this.__title
|
|
166
|
+
});
|
|
167
|
+
this.insertAfter(linkNode, restoreSelection);
|
|
168
|
+
return linkNode;
|
|
169
|
+
}
|
|
170
|
+
canInsertTextBefore() {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
canInsertTextAfter() {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
canBeEmpty() {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
isInline() {
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
extractWithChild(child, selection, destination) {
|
|
183
|
+
if (!$isRangeSelection(selection)) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
const anchorNode = selection.anchor.getNode();
|
|
187
|
+
const focusNode = selection.focus.getNode();
|
|
188
|
+
return this.isParentOf(anchorNode) && this.isParentOf(focusNode) && selection.getTextContent().length > 0;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function convertAnchorElement(domNode) {
|
|
192
|
+
let node = null;
|
|
193
|
+
if (isHTMLAnchorElement(domNode)) {
|
|
194
|
+
const content = domNode.textContent;
|
|
195
|
+
if (content !== null && content !== '' || domNode.children.length > 0) {
|
|
196
|
+
node = $createLinkNode(domNode.getAttribute('href') || '', {
|
|
197
|
+
rel: domNode.getAttribute('rel'),
|
|
198
|
+
target: domNode.getAttribute('target'),
|
|
199
|
+
title: domNode.getAttribute('title')
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
node
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Takes a URL and creates a LinkNode.
|
|
210
|
+
* @param url - The URL the LinkNode should direct to.
|
|
211
|
+
* @param attributes - Optional HTML a tag attributes { target, rel, title }
|
|
212
|
+
* @returns The LinkNode.
|
|
213
|
+
*/
|
|
214
|
+
function $createLinkNode(url, attributes) {
|
|
215
|
+
return $applyNodeReplacement(new LinkNode(url, attributes));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Determines if node is a LinkNode.
|
|
220
|
+
* @param node - The node to be checked.
|
|
221
|
+
* @returns true if node is a LinkNode, false otherwise.
|
|
222
|
+
*/
|
|
223
|
+
function $isLinkNode(node) {
|
|
224
|
+
return node instanceof LinkNode;
|
|
225
|
+
}
|
|
226
|
+
// Custom node type to override `canInsertTextAfter` that will
|
|
227
|
+
// allow typing within the link
|
|
228
|
+
class AutoLinkNode extends LinkNode {
|
|
229
|
+
static getType() {
|
|
230
|
+
return 'autolink';
|
|
231
|
+
}
|
|
232
|
+
static clone(node) {
|
|
233
|
+
return new AutoLinkNode(node.__url, {
|
|
234
|
+
rel: node.__rel,
|
|
235
|
+
target: node.__target,
|
|
236
|
+
title: node.__title
|
|
237
|
+
}, node.__key);
|
|
238
|
+
}
|
|
239
|
+
static importJSON(serializedNode) {
|
|
240
|
+
const node = $createAutoLinkNode(serializedNode.url, {
|
|
241
|
+
rel: serializedNode.rel,
|
|
242
|
+
target: serializedNode.target,
|
|
243
|
+
title: serializedNode.title
|
|
244
|
+
});
|
|
245
|
+
node.setFormat(serializedNode.format);
|
|
246
|
+
node.setIndent(serializedNode.indent);
|
|
247
|
+
node.setDirection(serializedNode.direction);
|
|
248
|
+
return node;
|
|
249
|
+
}
|
|
250
|
+
static importDOM() {
|
|
251
|
+
// TODO: Should link node should handle the import over autolink?
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
exportJSON() {
|
|
255
|
+
return {
|
|
256
|
+
...super.exportJSON(),
|
|
257
|
+
type: 'autolink',
|
|
258
|
+
version: 1
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
insertNewAfter(selection, restoreSelection = true) {
|
|
262
|
+
const element = this.getParentOrThrow().insertNewAfter(selection, restoreSelection);
|
|
263
|
+
if ($isElementNode(element)) {
|
|
264
|
+
const linkNode = $createAutoLinkNode(this.__url, {
|
|
265
|
+
rel: this.__rel,
|
|
266
|
+
target: this.__target,
|
|
267
|
+
title: this.__title
|
|
268
|
+
});
|
|
269
|
+
element.append(linkNode);
|
|
270
|
+
return linkNode;
|
|
271
|
+
}
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Takes a URL and creates an AutoLinkNode. AutoLinkNodes are generally automatically generated
|
|
278
|
+
* during typing, which is especially useful when a button to generate a LinkNode is not practical.
|
|
279
|
+
* @param url - The URL the LinkNode should direct to.
|
|
280
|
+
* @param attributes - Optional HTML a tag attributes. { target, rel, title }
|
|
281
|
+
* @returns The LinkNode.
|
|
282
|
+
*/
|
|
283
|
+
function $createAutoLinkNode(url, attributes) {
|
|
284
|
+
return $applyNodeReplacement(new AutoLinkNode(url, attributes));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Determines if node is an AutoLinkNode.
|
|
289
|
+
* @param node - The node to be checked.
|
|
290
|
+
* @returns true if node is an AutoLinkNode, false otherwise.
|
|
291
|
+
*/
|
|
292
|
+
function $isAutoLinkNode(node) {
|
|
293
|
+
return node instanceof AutoLinkNode;
|
|
294
|
+
}
|
|
295
|
+
const TOGGLE_LINK_COMMAND = createCommand('TOGGLE_LINK_COMMAND');
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Generates or updates a LinkNode. It can also delete a LinkNode if the URL is null,
|
|
299
|
+
* but saves any children and brings them up to the parent node.
|
|
300
|
+
* @param url - The URL the link directs to.
|
|
301
|
+
* @param attributes - Optional HTML a tag attributes. { target, rel, title }
|
|
302
|
+
*/
|
|
303
|
+
function toggleLink(url, attributes = {}) {
|
|
304
|
+
const {
|
|
305
|
+
target,
|
|
306
|
+
title
|
|
307
|
+
} = attributes;
|
|
308
|
+
const rel = attributes.rel === undefined ? 'noreferrer' : attributes.rel;
|
|
309
|
+
const selection = $getSelection();
|
|
310
|
+
if (!$isRangeSelection(selection)) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const nodes = selection.extract();
|
|
314
|
+
if (url === null) {
|
|
315
|
+
// Remove LinkNodes
|
|
316
|
+
nodes.forEach(node => {
|
|
317
|
+
const parent = node.getParent();
|
|
318
|
+
if ($isLinkNode(parent)) {
|
|
319
|
+
const children = parent.getChildren();
|
|
320
|
+
for (let i = 0; i < children.length; i++) {
|
|
321
|
+
parent.insertBefore(children[i]);
|
|
322
|
+
}
|
|
323
|
+
parent.remove();
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
} else {
|
|
327
|
+
// Add or merge LinkNodes
|
|
328
|
+
if (nodes.length === 1) {
|
|
329
|
+
const firstNode = nodes[0];
|
|
330
|
+
// if the first node is a LinkNode or if its
|
|
331
|
+
// parent is a LinkNode, we update the URL, target and rel.
|
|
332
|
+
const linkNode = $getAncestor(firstNode, $isLinkNode);
|
|
333
|
+
if (linkNode !== null) {
|
|
334
|
+
linkNode.setURL(url);
|
|
335
|
+
if (target !== undefined) {
|
|
336
|
+
linkNode.setTarget(target);
|
|
337
|
+
}
|
|
338
|
+
if (rel !== null) {
|
|
339
|
+
linkNode.setRel(rel);
|
|
340
|
+
}
|
|
341
|
+
if (title !== undefined) {
|
|
342
|
+
linkNode.setTitle(title);
|
|
343
|
+
}
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
let prevParent = null;
|
|
348
|
+
let linkNode = null;
|
|
349
|
+
nodes.forEach(node => {
|
|
350
|
+
const parent = node.getParent();
|
|
351
|
+
if (parent === linkNode || parent === null || $isElementNode(node) && !node.isInline()) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if ($isLinkNode(parent)) {
|
|
355
|
+
linkNode = parent;
|
|
356
|
+
parent.setURL(url);
|
|
357
|
+
if (target !== undefined) {
|
|
358
|
+
parent.setTarget(target);
|
|
359
|
+
}
|
|
360
|
+
if (rel !== null) {
|
|
361
|
+
linkNode.setRel(rel);
|
|
362
|
+
}
|
|
363
|
+
if (title !== undefined) {
|
|
364
|
+
linkNode.setTitle(title);
|
|
365
|
+
}
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
if (!parent.is(prevParent)) {
|
|
369
|
+
prevParent = parent;
|
|
370
|
+
linkNode = $createLinkNode(url, {
|
|
371
|
+
rel,
|
|
372
|
+
target,
|
|
373
|
+
title
|
|
374
|
+
});
|
|
375
|
+
if ($isLinkNode(parent)) {
|
|
376
|
+
if (node.getPreviousSibling() === null) {
|
|
377
|
+
parent.insertBefore(linkNode);
|
|
378
|
+
} else {
|
|
379
|
+
parent.insertAfter(linkNode);
|
|
380
|
+
}
|
|
381
|
+
} else {
|
|
382
|
+
node.insertBefore(linkNode);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if ($isLinkNode(node)) {
|
|
386
|
+
if (node.is(linkNode)) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (linkNode !== null) {
|
|
390
|
+
const children = node.getChildren();
|
|
391
|
+
for (let i = 0; i < children.length; i++) {
|
|
392
|
+
linkNode.append(children[i]);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
node.remove();
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (linkNode !== null) {
|
|
399
|
+
linkNode.append(node);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function $getAncestor(node, predicate) {
|
|
405
|
+
let parent = node;
|
|
406
|
+
while (parent !== null && parent.getParent() !== null && !predicate(parent)) {
|
|
407
|
+
parent = parent.getParentOrThrow();
|
|
408
|
+
}
|
|
409
|
+
return predicate(parent) ? parent : null;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
export { $createAutoLinkNode, $createLinkNode, $isAutoLinkNode, $isLinkNode, AutoLinkNode, LinkNode, TOGGLE_LINK_COMMAND, toggleLink };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import * as modDev from './LexicalLink.dev.esm.js';
|
|
8
|
+
import * as modProd from './LexicalLink.prod.esm.js';
|
|
9
|
+
const mod = process.env.NODE_ENV === 'development' ? modDev : modProd;
|
|
10
|
+
export const $createAutoLinkNode = mod.$createAutoLinkNode;
|
|
11
|
+
export const $createLinkNode = mod.$createLinkNode;
|
|
12
|
+
export const $isAutoLinkNode = mod.$isAutoLinkNode;
|
|
13
|
+
export const $isLinkNode = mod.$isLinkNode;
|
|
14
|
+
export const AutoLinkNode = mod.AutoLinkNode;
|
|
15
|
+
export const LinkNode = mod.LinkNode;
|
|
16
|
+
export const TOGGLE_LINK_COMMAND = mod.TOGGLE_LINK_COMMAND;
|
|
17
|
+
export const toggleLink = mod.toggleLink;
|
package/LexicalLink.js
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
'use strict'
|
|
8
|
-
const LexicalLink = process.env.NODE_ENV === 'development' ? require('./LexicalLink.dev.js') : require('./LexicalLink.prod.js')
|
|
8
|
+
const LexicalLink = process.env.NODE_ENV === 'development' ? require('./LexicalLink.dev.js') : require('./LexicalLink.prod.js');
|
|
9
9
|
module.exports = LexicalLink;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import{addClassNamesToElement as t,isHTMLAnchorElement as e}from"@lexical/utils";import{createCommand as r,ElementNode as i,$applyNodeReplacement as n,$isRangeSelection as l,$isElementNode as s,$getSelection as u}from"lexical";const o=new Set(["http:","https:","mailto:","sms:","tel:"]);class _ extends i{static getType(){return"link"}static clone(t){return new _(t.__url,{rel:t.__rel,target:t.__target,title:t.__title},t.__key)}constructor(t,e={},r){super(r);const{target:i=null,rel:n=null,title:l=null}=e;this.__url=t,this.__target=i,this.__rel=n,this.__title=l}createDOM(e){const r=document.createElement("a");return r.href=this.sanitizeUrl(this.__url),null!==this.__target&&(r.target=this.__target),null!==this.__rel&&(r.rel=this.__rel),null!==this.__title&&(r.title=this.__title),t(r,e.theme.link),r}updateDOM(t,e,r){const i=this.__url,n=this.__target,l=this.__rel,s=this.__title;return i!==t.__url&&(e.href=i),n!==t.__target&&(n?e.target=n:e.removeAttribute("target")),l!==t.__rel&&(l?e.rel=l:e.removeAttribute("rel")),s!==t.__title&&(s?e.title=s:e.removeAttribute("title")),!1}static importDOM(){return{a:t=>({conversion:a,priority:1})}}static importJSON(t){const e=g(t.url,{rel:t.rel,target:t.target,title:t.title});return e.setFormat(t.format),e.setIndent(t.indent),e.setDirection(t.direction),e}sanitizeUrl(t){try{const e=new URL(t);if(!o.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(),type:"link",url:this.getURL(),version:1}}getURL(){return this.getLatest().__url}setURL(t){this.getWritable().__url=t}getTarget(){return this.getLatest().__target}setTarget(t){this.getWritable().__target=t}getRel(){return this.getLatest().__rel}setRel(t){this.getWritable().__rel=t}getTitle(){return this.getLatest().__title}setTitle(t){this.getWritable().__title=t}insertNewAfter(t,e=!0){const r=g(this.__url,{rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(r,e),r}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(t,e,r){if(!l(e))return!1;const i=e.anchor.getNode(),n=e.focus.getNode();return this.isParentOf(i)&&this.isParentOf(n)&&e.getTextContent().length>0}}function a(t){let r=null;if(e(t)){const e=t.textContent;(null!==e&&""!==e||t.children.length>0)&&(r=g(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}))}return{node:r}}function g(t,e){return n(new _(t,e))}function c(t){return t instanceof _}class h extends _{static getType(){return"autolink"}static clone(t){return new h(t.__url,{rel:t.__rel,target:t.__target,title:t.__title},t.__key)}static importJSON(t){const e=f(t.url,{rel:t.rel,target:t.target,title:t.title});return e.setFormat(t.format),e.setIndent(t.indent),e.setDirection(t.direction),e}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),type:"autolink",version:1}}insertNewAfter(t,e=!0){const r=this.getParentOrThrow().insertNewAfter(t,e);if(s(r)){const t=f(this.__url,{rel:this.__rel,target:this.__target,title:this.__title});return r.append(t),t}return null}}function f(t,e){return n(new h(t,e))}function p(t){return t instanceof h}const d=r("TOGGLE_LINK_COMMAND");function m(t,e={}){const{target:r,title:i}=e,n=void 0===e.rel?"noreferrer":e.rel,o=u();if(!l(o))return;const _=o.extract();if(null===t)_.forEach((t=>{const e=t.getParent();if(c(e)){const t=e.getChildren();for(let r=0;r<t.length;r++)e.insertBefore(t[r]);e.remove()}}));else{if(1===_.length){const e=function(t,e){let r=t;for(;null!==r&&null!==r.getParent()&&!e(r);)r=r.getParentOrThrow();return e(r)?r:null}(_[0],c);if(null!==e)return e.setURL(t),void 0!==r&&e.setTarget(r),null!==n&&e.setRel(n),void(void 0!==i&&e.setTitle(i))}let e=null,l=null;_.forEach((u=>{const o=u.getParent();if(o!==l&&null!==o&&(!s(u)||u.isInline())){if(c(o))return l=o,o.setURL(t),void 0!==r&&o.setTarget(r),null!==n&&l.setRel(n),void(void 0!==i&&l.setTitle(i));if(o.is(e)||(e=o,l=g(t,{rel:n,target:r,title:i}),c(o)?null===u.getPreviousSibling()?o.insertBefore(l):o.insertAfter(l):u.insertBefore(l)),c(u)){if(u.is(l))return;if(null!==l){const t=u.getChildren();for(let e=0;e<t.length;e++)l.append(t[e])}u.remove()}else null!==l&&l.append(u)}}))}}export{f as $createAutoLinkNode,g as $createLinkNode,p as $isAutoLinkNode,c as $isLinkNode,h as AutoLinkNode,_ as LinkNode,d as TOGGLE_LINK_COMMAND,m as toggleLink};
|
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -8,17 +8,19 @@
|
|
|
8
8
|
"link"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.14.1",
|
|
12
12
|
"main": "LexicalLink.js",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"lexical": "0.
|
|
14
|
+
"lexical": "0.14.1"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@lexical/utils": "0.
|
|
17
|
+
"@lexical/utils": "0.14.1"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
21
|
"url": "https://github.com/facebook/lexical",
|
|
22
22
|
"directory": "packages/lexical-link"
|
|
23
|
-
}
|
|
23
|
+
},
|
|
24
|
+
"module": "LexicalLink.esm.js",
|
|
25
|
+
"sideEffects": false
|
|
24
26
|
}
|