@lexical/link 0.50.1-nightly.20260916.0 → 0.51.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 +312 -35
- package/dist/LexicalLink.js.flow +4 -1
- package/dist/LexicalLink.prod.js +1 -1
- package/dist/LexicalLinkGeneratedJSON.d.ts +27 -0
- package/dist/LexicalLinkNode.d.ts +71 -9
- package/package.json +7 -7
- package/src/LexicalLinkGeneratedJSON.ts +370 -0
- package/src/LexicalLinkNode.ts +67 -49
package/dist/LexicalLink.dev.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { AriaLiveRegionExtension } from '@lexical/a11y';
|
|
10
10
|
import { effect } from '@lexical/extension/signals';
|
|
11
11
|
import { namedSignals } from '@lexical/extension/namedSignals';
|
|
12
|
-
import { ElementNode, $getDocument, addClassNamesToElement, isHTMLAnchorElement, $copyNode, $isRangeSelection, $applyNodeReplacement, createCommand, $getSelection, $isNodeSelection, $findMatchingParent, $normalizeSelection__EXPERIMENTAL, $setSelection, $getChildCaret, $isElementNode, $insertNodeToNearestRootAtCaret, $rewindSiblingCaret, $caretFromPoint, $normalizeCaret, $isSiblingCaret, $setPointFromCaret, shallowMergeConfig, mergeRegister, COMMAND_PRIORITY_EDITOR, PASTE_COMMAND, $isTextNode, COMMAND_PRIORITY_LOW, registerEventListeners, isDOMNode, getNearestEditorFromDOMNode, $getNearestNodeFromDOMNode, TextNode, $isLineBreakNode, $createTextNode } from 'lexical';
|
|
12
|
+
import { getterTableOf, setterTableOf, setterDefaultOf, ElementNode, $getDocument, addClassNamesToElement, isHTMLAnchorElement, $copyNode, $isRangeSelection, $applyNodeReplacement, createCommand, $getSelection, $isNodeSelection, $findMatchingParent, nodeSchema, withField, stringValue, nullable, booleanValue, $normalizeSelection__EXPERIMENTAL, $setSelection, $getChildCaret, $isElementNode, $insertNodeToNearestRootAtCaret, $rewindSiblingCaret, $caretFromPoint, $normalizeCaret, $isSiblingCaret, $setPointFromCaret, shallowMergeConfig, mergeRegister, COMMAND_PRIORITY_EDITOR, PASTE_COMMAND, $isTextNode, COMMAND_PRIORITY_LOW, registerEventListeners, isDOMNode, getNearestEditorFromDOMNode, $getNearestNodeFromDOMNode, TextNode, $isLineBreakNode, $createTextNode } from 'lexical';
|
|
13
13
|
import { sel, $distributeInlineWrapper, CoreImportExtension, DOMImportExtension } from '@lexical/html';
|
|
14
14
|
import { objectKlassEquals } from '@lexical/utils';
|
|
15
15
|
|
|
@@ -27,9 +27,301 @@ function formatDevErrorMessage(message) {
|
|
|
27
27
|
throw new Error(message);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
32
|
+
*
|
|
33
|
+
* This source code is licensed under the MIT license found in the
|
|
34
|
+
* LICENSE file in the root directory of this source tree.
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
// The JSON number grammar, anchored, matching numberValue: `Number()` alone
|
|
40
|
+
// reads '0x10' as 16 and '' as 0, and neither is a shape a JSON encoder
|
|
41
|
+
// produces. Emitted from the same source the codegen verified against, so the
|
|
42
|
+
// two cannot be different functions.
|
|
43
|
+
const JSON_NUMBER = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
44
|
+
function num(v, d) {
|
|
45
|
+
if (typeof v === 'number') {
|
|
46
|
+
return Number.isFinite(v) ? v : d;
|
|
47
|
+
}
|
|
48
|
+
if (typeof v !== 'string' || !JSON_NUMBER.test(v)) {
|
|
49
|
+
return d;
|
|
50
|
+
}
|
|
51
|
+
const n = Number(v);
|
|
52
|
+
return Number.isFinite(n) ? n : d;
|
|
53
|
+
}
|
|
54
|
+
function numC(v, d, min, max, integer) {
|
|
55
|
+
const n = num(v, d);
|
|
56
|
+
return n >= min && n <= max && (false || Number.isInteger(n)) ? n : d;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* LinkNode's schema-declared fields, for a clone. Generated from that
|
|
61
|
+
* schema; do not edit by hand.
|
|
62
|
+
*
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
function afterCloneLinkNode(node, prevNode) {
|
|
66
|
+
node.__rel = prevNode.__rel;
|
|
67
|
+
node.__target = prevNode.__target;
|
|
68
|
+
node.__title = prevNode.__title;
|
|
69
|
+
node.__url = prevNode.__url;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** LinkNode's generated implementations, for its `$config`. @internal */
|
|
73
|
+
const GENERATED_LINK = fields => {
|
|
74
|
+
const LINK_FORMAT_GETTER = getterTableOf(fields, 'format');
|
|
75
|
+
const LINK_FORMAT_SETTER = setterTableOf(fields, 'format');
|
|
76
|
+
const LINK_FORMAT_SETTER_DEFAULT = setterDefaultOf(fields, 'format');
|
|
77
|
+
|
|
78
|
+
/** Generated from LinkNode's serialization schema. Do not edit by hand. */
|
|
79
|
+
function exportLinkNode(node) {
|
|
80
|
+
const textFormat = node.__textFormat;
|
|
81
|
+
const textStyle = node.__textStyle;
|
|
82
|
+
const shouldSerializeTextStyles = (textFormat !== 0 || textStyle !== '') && node.shouldSerializeTextStyles();
|
|
83
|
+
return {
|
|
84
|
+
children: [],
|
|
85
|
+
rel: node.__rel,
|
|
86
|
+
target: node.__target,
|
|
87
|
+
title: node.__title,
|
|
88
|
+
url: node.__url,
|
|
89
|
+
direction: node.__dir,
|
|
90
|
+
format: LINK_FORMAT_GETTER[node.__format],
|
|
91
|
+
indent: node.__indent,
|
|
92
|
+
textFormat: textFormat !== 0 && shouldSerializeTextStyles ? textFormat : undefined,
|
|
93
|
+
textStyle: textStyle !== '' && shouldSerializeTextStyles ? textStyle : undefined,
|
|
94
|
+
type: node.__type,
|
|
95
|
+
version: 1
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Generated from LinkNode's serialization schema. Do not edit by hand. */
|
|
100
|
+
function exportCompactLinkNode(node) {
|
|
101
|
+
const textFormat = node.__textFormat;
|
|
102
|
+
const textStyle = node.__textStyle;
|
|
103
|
+
const shouldSerializeTextStyles = (textFormat !== 0 || textStyle !== '') && node.shouldSerializeTextStyles();
|
|
104
|
+
const json = {
|
|
105
|
+
type: node.__type,
|
|
106
|
+
children: []
|
|
107
|
+
};
|
|
108
|
+
const rel = node.__rel;
|
|
109
|
+
if (rel != null) {
|
|
110
|
+
json.rel = rel;
|
|
111
|
+
}
|
|
112
|
+
const target = node.__target;
|
|
113
|
+
if (target != null) {
|
|
114
|
+
json.target = target;
|
|
115
|
+
}
|
|
116
|
+
const title = node.__title;
|
|
117
|
+
if (title != null) {
|
|
118
|
+
json.title = title;
|
|
119
|
+
}
|
|
120
|
+
const url = node.__url;
|
|
121
|
+
if (url !== undefined && url !== '') {
|
|
122
|
+
json.url = url;
|
|
123
|
+
}
|
|
124
|
+
const direction = node.__dir;
|
|
125
|
+
if (direction != null) {
|
|
126
|
+
json.direction = direction;
|
|
127
|
+
}
|
|
128
|
+
const format = LINK_FORMAT_GETTER[node.__format];
|
|
129
|
+
if (format !== undefined && format !== '') {
|
|
130
|
+
json.format = format;
|
|
131
|
+
}
|
|
132
|
+
const indent = node.__indent;
|
|
133
|
+
if (indent !== undefined && indent !== 0) {
|
|
134
|
+
json.indent = indent;
|
|
135
|
+
}
|
|
136
|
+
if (textFormat !== undefined && textFormat !== 0 && shouldSerializeTextStyles) {
|
|
137
|
+
json.textFormat = textFormat;
|
|
138
|
+
}
|
|
139
|
+
if (textStyle !== undefined && textStyle !== '' && shouldSerializeTextStyles) {
|
|
140
|
+
json.textStyle = textStyle;
|
|
141
|
+
}
|
|
142
|
+
return json;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Generated from LinkNode's serialization schema. Do not edit by hand. */
|
|
146
|
+
function updateLinkNode(node, json) {
|
|
147
|
+
const direction = json.direction;
|
|
148
|
+
node.__dir = direction === null || direction === 'ltr' || direction === 'rtl' ? direction : null;
|
|
149
|
+
const format = json.format;
|
|
150
|
+
node.__format = typeof format === 'string' && format in LINK_FORMAT_SETTER ? LINK_FORMAT_SETTER[format] : LINK_FORMAT_SETTER_DEFAULT;
|
|
151
|
+
node.__indent = numC(json.indent, 0, 0, Infinity);
|
|
152
|
+
node.__textFormat = num(json.textFormat, 0);
|
|
153
|
+
const textStyle = json.textStyle;
|
|
154
|
+
node.__textStyle = typeof textStyle === 'string' ? textStyle : '';
|
|
155
|
+
const rel = json.rel;
|
|
156
|
+
node.__rel = typeof rel === 'string' && rel !== '' ? rel : null;
|
|
157
|
+
const target = json.target;
|
|
158
|
+
node.__target = typeof target === 'string' && target !== '' ? target : null;
|
|
159
|
+
const title = json.title;
|
|
160
|
+
node.__title = typeof title === 'string' && title !== '' ? title : null;
|
|
161
|
+
const url = json.url;
|
|
162
|
+
node.__url = typeof url === 'string' ? url : '';
|
|
163
|
+
return node;
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
exportJSON: exportLinkNode,
|
|
167
|
+
exportCompactJSON: exportCompactLinkNode,
|
|
168
|
+
updateFromJSON: updateLinkNode,
|
|
169
|
+
afterCloneFrom: afterCloneLinkNode
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* AutoLinkNode's schema-declared fields, for a clone. Generated from that
|
|
175
|
+
* schema; do not edit by hand.
|
|
176
|
+
*
|
|
177
|
+
* @internal
|
|
178
|
+
*/
|
|
179
|
+
function afterCloneAutoLinkNode(node, prevNode) {
|
|
180
|
+
node.__isUnlinked = prevNode.__isUnlinked;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** AutoLinkNode's generated implementations, for its `$config`. @internal */
|
|
184
|
+
const GENERATED_AUTOLINK = fields => {
|
|
185
|
+
const AUTOLINK_FORMAT_GETTER = getterTableOf(fields, 'format');
|
|
186
|
+
const AUTOLINK_FORMAT_SETTER = setterTableOf(fields, 'format');
|
|
187
|
+
const AUTOLINK_FORMAT_SETTER_DEFAULT = setterDefaultOf(fields, 'format');
|
|
188
|
+
|
|
189
|
+
/** Generated from AutoLinkNode's serialization schema. Do not edit by hand. */
|
|
190
|
+
function exportAutoLinkNode(node) {
|
|
191
|
+
const textFormat = node.__textFormat;
|
|
192
|
+
const textStyle = node.__textStyle;
|
|
193
|
+
const shouldSerializeTextStyles = (textFormat !== 0 || textStyle !== '') && node.shouldSerializeTextStyles();
|
|
194
|
+
return {
|
|
195
|
+
children: [],
|
|
196
|
+
isUnlinked: node.__isUnlinked,
|
|
197
|
+
rel: node.__rel,
|
|
198
|
+
target: node.__target,
|
|
199
|
+
title: node.__title,
|
|
200
|
+
url: node.__url,
|
|
201
|
+
direction: node.__dir,
|
|
202
|
+
format: AUTOLINK_FORMAT_GETTER[node.__format],
|
|
203
|
+
indent: node.__indent,
|
|
204
|
+
textFormat: textFormat !== 0 && shouldSerializeTextStyles ? textFormat : undefined,
|
|
205
|
+
textStyle: textStyle !== '' && shouldSerializeTextStyles ? textStyle : undefined,
|
|
206
|
+
type: node.__type,
|
|
207
|
+
version: 1
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Generated from AutoLinkNode's serialization schema. Do not edit by hand. */
|
|
212
|
+
function exportCompactAutoLinkNode(node) {
|
|
213
|
+
const textFormat = node.__textFormat;
|
|
214
|
+
const textStyle = node.__textStyle;
|
|
215
|
+
const shouldSerializeTextStyles = (textFormat !== 0 || textStyle !== '') && node.shouldSerializeTextStyles();
|
|
216
|
+
const json = {
|
|
217
|
+
type: node.__type,
|
|
218
|
+
children: []
|
|
219
|
+
};
|
|
220
|
+
const isUnlinked = node.__isUnlinked;
|
|
221
|
+
if (isUnlinked !== undefined && isUnlinked !== false) {
|
|
222
|
+
json.isUnlinked = isUnlinked;
|
|
223
|
+
}
|
|
224
|
+
const rel = node.__rel;
|
|
225
|
+
if (rel != null) {
|
|
226
|
+
json.rel = rel;
|
|
227
|
+
}
|
|
228
|
+
const target = node.__target;
|
|
229
|
+
if (target != null) {
|
|
230
|
+
json.target = target;
|
|
231
|
+
}
|
|
232
|
+
const title = node.__title;
|
|
233
|
+
if (title != null) {
|
|
234
|
+
json.title = title;
|
|
235
|
+
}
|
|
236
|
+
const url = node.__url;
|
|
237
|
+
if (url !== undefined && url !== '') {
|
|
238
|
+
json.url = url;
|
|
239
|
+
}
|
|
240
|
+
const direction = node.__dir;
|
|
241
|
+
if (direction != null) {
|
|
242
|
+
json.direction = direction;
|
|
243
|
+
}
|
|
244
|
+
const format = AUTOLINK_FORMAT_GETTER[node.__format];
|
|
245
|
+
if (format !== undefined && format !== '') {
|
|
246
|
+
json.format = format;
|
|
247
|
+
}
|
|
248
|
+
const indent = node.__indent;
|
|
249
|
+
if (indent !== undefined && indent !== 0) {
|
|
250
|
+
json.indent = indent;
|
|
251
|
+
}
|
|
252
|
+
if (textFormat !== undefined && textFormat !== 0 && shouldSerializeTextStyles) {
|
|
253
|
+
json.textFormat = textFormat;
|
|
254
|
+
}
|
|
255
|
+
if (textStyle !== undefined && textStyle !== '' && shouldSerializeTextStyles) {
|
|
256
|
+
json.textStyle = textStyle;
|
|
257
|
+
}
|
|
258
|
+
return json;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/** Generated from AutoLinkNode's serialization schema. Do not edit by hand. */
|
|
262
|
+
function updateAutoLinkNode(node, json) {
|
|
263
|
+
const direction = json.direction;
|
|
264
|
+
node.__dir = direction === null || direction === 'ltr' || direction === 'rtl' ? direction : null;
|
|
265
|
+
const format = json.format;
|
|
266
|
+
node.__format = typeof format === 'string' && format in AUTOLINK_FORMAT_SETTER ? AUTOLINK_FORMAT_SETTER[format] : AUTOLINK_FORMAT_SETTER_DEFAULT;
|
|
267
|
+
node.__indent = numC(json.indent, 0, 0, Infinity);
|
|
268
|
+
node.__textFormat = num(json.textFormat, 0);
|
|
269
|
+
const textStyle = json.textStyle;
|
|
270
|
+
node.__textStyle = typeof textStyle === 'string' ? textStyle : '';
|
|
271
|
+
const rel = json.rel;
|
|
272
|
+
node.__rel = typeof rel === 'string' && rel !== '' ? rel : null;
|
|
273
|
+
const target = json.target;
|
|
274
|
+
node.__target = typeof target === 'string' && target !== '' ? target : null;
|
|
275
|
+
const title = json.title;
|
|
276
|
+
node.__title = typeof title === 'string' && title !== '' ? title : null;
|
|
277
|
+
const url = json.url;
|
|
278
|
+
node.__url = typeof url === 'string' ? url : '';
|
|
279
|
+
const isUnlinked = json.isUnlinked;
|
|
280
|
+
node.__isUnlinked = typeof isUnlinked === 'boolean' ? isUnlinked : false;
|
|
281
|
+
return node;
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
exportJSON: exportAutoLinkNode,
|
|
285
|
+
exportCompactJSON: exportCompactAutoLinkNode,
|
|
286
|
+
updateFromJSON: updateAutoLinkNode,
|
|
287
|
+
afterCloneFrom: afterCloneAutoLinkNode
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
|
|
30
291
|
const SUPPORTED_URL_PROTOCOLS = new Set(['http:', 'https:', 'mailto:', 'sms:', 'tel:']);
|
|
292
|
+
const linkNodeSchema = /* @__PURE__ */nodeSchema()({
|
|
293
|
+
// defaultAsNull preserves the legacy `value || null` semantics: an empty
|
|
294
|
+
// string (or junk that coerces to it) imports as null, not ''.
|
|
295
|
+
// Every property *is* its node field in both directions — each accessor is
|
|
296
|
+
// a bare read or write — so each is declared as the field it is. Only `url`
|
|
297
|
+
// names its accessors, because getURL/setURL are not the conventional
|
|
298
|
+
// getUrl/setUrl the others are resolved to.
|
|
299
|
+
rel: /* @__PURE__ */withField(/* @__PURE__ */nullable(/* @__PURE__ */stringValue(), {
|
|
300
|
+
defaultAsNull: true
|
|
301
|
+
}), {
|
|
302
|
+
field: '__rel'
|
|
303
|
+
}),
|
|
304
|
+
target: /* @__PURE__ */withField(/* @__PURE__ */nullable(/* @__PURE__ */stringValue(), {
|
|
305
|
+
defaultAsNull: true
|
|
306
|
+
}), {
|
|
307
|
+
field: '__target'
|
|
308
|
+
}),
|
|
309
|
+
title: /* @__PURE__ */withField(/* @__PURE__ */nullable(/* @__PURE__ */stringValue(), {
|
|
310
|
+
defaultAsNull: true
|
|
311
|
+
}), {
|
|
312
|
+
field: '__title'
|
|
313
|
+
}),
|
|
314
|
+
url: /* @__PURE__ */withField(/* @__PURE__ */stringValue(), {
|
|
315
|
+
field: '__url',
|
|
316
|
+
getter: 'getURL',
|
|
317
|
+
setter: 'setURL'
|
|
318
|
+
})
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
31
322
|
|
|
32
323
|
/** @noInheritDoc */
|
|
324
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
33
325
|
class LinkNode extends ElementNode {
|
|
34
326
|
/** @internal */
|
|
35
327
|
__url;
|
|
@@ -42,12 +334,14 @@ class LinkNode extends ElementNode {
|
|
|
42
334
|
$config() {
|
|
43
335
|
return this.config('link', {
|
|
44
336
|
extends: ElementNode,
|
|
337
|
+
generated: GENERATED_LINK,
|
|
45
338
|
importDOM: {
|
|
46
339
|
a: () => ({
|
|
47
340
|
conversion: $convertAnchorElement,
|
|
48
341
|
priority: 1
|
|
49
342
|
})
|
|
50
|
-
}
|
|
343
|
+
},
|
|
344
|
+
json: linkNodeSchema
|
|
51
345
|
});
|
|
52
346
|
}
|
|
53
347
|
constructor(url = '', attributes = {}, key) {
|
|
@@ -62,13 +356,6 @@ class LinkNode extends ElementNode {
|
|
|
62
356
|
this.__rel = rel;
|
|
63
357
|
this.__title = title;
|
|
64
358
|
}
|
|
65
|
-
afterCloneFrom(prevNode) {
|
|
66
|
-
super.afterCloneFrom(prevNode);
|
|
67
|
-
this.__url = prevNode.__url;
|
|
68
|
-
this.__rel = prevNode.__rel;
|
|
69
|
-
this.__target = prevNode.__target;
|
|
70
|
-
this.__title = prevNode.__title;
|
|
71
|
-
}
|
|
72
359
|
createDOM(config) {
|
|
73
360
|
const element = $getDocument().createElement('a');
|
|
74
361
|
this.updateLinkDOM(null, element, config);
|
|
@@ -97,9 +384,6 @@ class LinkNode extends ElementNode {
|
|
|
97
384
|
this.updateLinkDOM(prevNode, anchor, config);
|
|
98
385
|
return false;
|
|
99
386
|
}
|
|
100
|
-
updateFromJSON(serializedNode) {
|
|
101
|
-
return super.updateFromJSON(serializedNode).setURL(serializedNode.url).setRel(serializedNode.rel || null).setTarget(serializedNode.target || null).setTitle(serializedNode.title || null);
|
|
102
|
-
}
|
|
103
387
|
sanitizeUrl(url) {
|
|
104
388
|
const rawUrl = url;
|
|
105
389
|
url = formatUrl(url);
|
|
@@ -140,15 +424,6 @@ class LinkNode extends ElementNode {
|
|
|
140
424
|
}
|
|
141
425
|
return url;
|
|
142
426
|
}
|
|
143
|
-
exportJSON() {
|
|
144
|
-
return {
|
|
145
|
-
...super.exportJSON(),
|
|
146
|
-
rel: this.getRel(),
|
|
147
|
-
target: this.getTarget(),
|
|
148
|
-
title: this.getTitle(),
|
|
149
|
-
url: this.getURL()
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
427
|
getURL() {
|
|
153
428
|
return this.getLatest().__url;
|
|
154
429
|
}
|
|
@@ -354,8 +629,21 @@ function $createLinkNode(url = '', attributes) {
|
|
|
354
629
|
function $isLinkNode(node) {
|
|
355
630
|
return node instanceof LinkNode;
|
|
356
631
|
}
|
|
632
|
+
const autoLinkNodeSchema = /* @__PURE__ */nodeSchema()({
|
|
633
|
+
// The property *is* the field in both directions — both accessors are bare —
|
|
634
|
+
// so it is declared as the field it is. The conventional
|
|
635
|
+
// getIsUnlinked/setIsUnlinked are still deferred to, so a subclass that
|
|
636
|
+
// overrides either still decides.
|
|
637
|
+
isUnlinked: /* @__PURE__ */withField(/* @__PURE__ */booleanValue(), {
|
|
638
|
+
field: '__isUnlinked'
|
|
639
|
+
})
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
643
|
+
|
|
357
644
|
// Custom node type to override `canInsertTextAfter` that will
|
|
358
645
|
// allow typing within the link
|
|
646
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
359
647
|
class AutoLinkNode extends LinkNode {
|
|
360
648
|
/** @internal */
|
|
361
649
|
/** Indicates whether the autolink was ever unlinked. **/
|
|
@@ -364,13 +652,11 @@ class AutoLinkNode extends LinkNode {
|
|
|
364
652
|
super(url, attributes, key);
|
|
365
653
|
this.__isUnlinked = attributes.isUnlinked !== undefined && attributes.isUnlinked !== null ? attributes.isUnlinked : false;
|
|
366
654
|
}
|
|
367
|
-
afterCloneFrom(prevNode) {
|
|
368
|
-
super.afterCloneFrom(prevNode);
|
|
369
|
-
this.__isUnlinked = prevNode.__isUnlinked;
|
|
370
|
-
}
|
|
371
655
|
$config() {
|
|
372
656
|
return this.config('autolink', {
|
|
373
|
-
extends: LinkNode
|
|
657
|
+
extends: LinkNode,
|
|
658
|
+
generated: GENERATED_AUTOLINK,
|
|
659
|
+
json: autoLinkNodeSchema
|
|
374
660
|
});
|
|
375
661
|
}
|
|
376
662
|
shouldMergeAdjacentLink(_otherLink) {
|
|
@@ -394,15 +680,6 @@ class AutoLinkNode extends LinkNode {
|
|
|
394
680
|
updateDOM(prevNode, anchor, config) {
|
|
395
681
|
return super.updateDOM(prevNode, anchor, config) || prevNode.__isUnlinked !== this.__isUnlinked;
|
|
396
682
|
}
|
|
397
|
-
updateFromJSON(serializedNode) {
|
|
398
|
-
return super.updateFromJSON(serializedNode).setIsUnlinked(serializedNode.isUnlinked || false);
|
|
399
|
-
}
|
|
400
|
-
exportJSON() {
|
|
401
|
-
return {
|
|
402
|
-
...super.exportJSON(),
|
|
403
|
-
isUnlinked: this.__isUnlinked
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
683
|
|
|
407
684
|
// insertNewAfter is deliberately not overridden: LinkNode's implementation
|
|
408
685
|
// uses $copyNode, which runs clone() + afterCloneFrom() and so carries the
|
package/dist/LexicalLink.js.flow
CHANGED
|
@@ -40,7 +40,10 @@ declare export class LinkNode extends ElementNode {
|
|
|
40
40
|
__title: null | string;
|
|
41
41
|
constructor(url?: string, attributes?: LinkAttributes, key?: NodeKey): void;
|
|
42
42
|
createDOM(config: EditorConfig): HTMLElement;
|
|
43
|
-
exportJSON
|
|
43
|
+
// See LexicalNode.exportJSON: one signature, the legacy form, and `false`
|
|
44
|
+
// rather than `boolean` so a compact call is refused instead of answered
|
|
45
|
+
// with a shape the value does not have.
|
|
46
|
+
exportJSON(compact?: false): SerializedLinkNode;
|
|
44
47
|
getURL(): string;
|
|
45
48
|
setURL(url: string): void;
|
|
46
49
|
getTarget(): null | string;
|
package/dist/LexicalLink.prod.js
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import{AriaLiveRegionExtension as t}from"@lexical/a11y";import{effect as e}from"@lexical/extension/signals";import{namedSignals as n}from"@lexical/extension/namedSignals";import{ElementNode as r,$getDocument as i,addClassNamesToElement as s,isHTMLAnchorElement as l,$copyNode as o,$isRangeSelection as u,$applyNodeReplacement as a,createCommand as c,$getSelection as g,$isNodeSelection as f,$findMatchingParent as d,$normalizeSelection__EXPERIMENTAL as h,$setSelection as p,$getChildCaret as m,$isElementNode as x,$insertNodeToNearestRootAtCaret as _,$rewindSiblingCaret as k,$caretFromPoint as b,$normalizeCaret as v,$isSiblingCaret as U,$setPointFromCaret as T,shallowMergeConfig as L,mergeRegister as C,COMMAND_PRIORITY_EDITOR as S,PASTE_COMMAND as y,$isTextNode as R,COMMAND_PRIORITY_LOW as A,registerEventListeners as P,isDOMNode as O,getNearestEditorFromDOMNode as N,$getNearestNodeFromDOMNode as w,TextNode as I,$isLineBreakNode as D,$createTextNode as M}from"lexical";import{sel as E,$distributeInlineWrapper as F,CoreImportExtension as W,DOMImportExtension as $}from"@lexical/html";import{objectKlassEquals as z}from"@lexical/utils";const K=new Set(["http:","https:","mailto:","sms:","tel:"]);class B extends r{__url;__target;__rel;__title;$config(){return this.config("link",{extends:r,importDOM:{a:()=>({conversion:H,priority:1})}})}constructor(t="",e={},n){super(n);const{target:r=null,rel:i=null,title:s=null}=e;this.__url=t,this.__target=r,this.__rel=i,this.__title=s}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=i().createElement("a");return this.updateLinkDOM(null,e,t),s(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}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=rt(t);try{const e=new URL(rt(t));if(!K.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&&!K.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=o(this);return this.insertAfter(n,e),n}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(t,e,n){if(!u(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.getURL().startsWith("mailto:")}isWebSiteURI(){const t=this.getURL();return t.startsWith("https://")||t.startsWith("http://")}shouldMergeAdjacentLink(t){return this.getType()===t.getType()&&this.getURL()===t.getURL()&&this.getTarget()===t.getTarget()&&this.getRel()===t.getRel()&&this.getTitle()===t.getTitle()}}function J(t){const e=b(t,"next");return[e,e.getFlipped()]}function j(t,e){for(const n of e)if(n.origin.isAttached()){const e=v(n);return void T(t,e)}}function Z(t){const e=g();let n=null,r=null;function i(){u(e)&&(j(e.anchor,n),j(e.focus,r),h(e))}u(e)&&(n=J(e.anchor),r=J(e.focus));let s=!1;for(const e of m(t,"next")){const n=e.origin;if(x(n)&&!n.isInline()){const r=n.getChildren();if(r.length>0){const e=o(t);e.append(...r),n.append(e),s=!0}_(n,k(e),{$shouldSplit:()=>!1})}}function l(t,e,n){const[r,i]=t,s=t=>U(t)&&t.origin.is(e);if(!s(r)&&!s(i))return t;const l=v(m(n,"next"));return[l,l.getFlipped()]}if(t.isAttached()){const e=t.getPreviousSibling();if(q(e)&&e.shouldMergeAdjacentLink(t))return n&&(n=l(n,e,t)),r&&(r=l(r,e,t)),e.append(...t.getChildren()),t.remove(),void i();const o=t.getNextSibling();q(o)&&t.shouldMergeAdjacentLink(o)&&(n&&(n=l(n,t,o)),r&&(r=l(r,t,o)),t.append(...o.getChildren()),o.remove(),s=!0)}if(s){if(!t.canBeEmpty()&&t.isEmpty()){const e=t.getParent();t.remove(),e&&e.isEmpty()&&e.remove()}i()}}function H(t){let e=null;if(l(t)){const n=t.textContent;(null!==n&&""!==n||t.children.length>0)&&(e=G(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}))}return{node:e}}function G(t="",e){return a(new B(t,e))}function q(t){return t instanceof B}class Q extends B{__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}$config(){return this.config("autolink",{extends:B})}shouldMergeAdjacentLink(t){return!1}getIsUnlinked(){return this.getLatest().__isUnlinked}setIsUnlinked(t){const e=this.getWritable();return e.__isUnlinked=t,e}createDOM(t){return this.__isUnlinked?i().createElement("span"):super.createDOM(t)}updateDOM(t,e,n){return super.updateDOM(t,e,n)||t.__isUnlinked!==this.__isUnlinked}updateFromJSON(t){return super.updateFromJSON(t).setIsUnlinked(t.isUnlinked||!1)}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked}}}function V(t="",e){return a(new Q(t,e))}function X(t){return t instanceof Q}const Y=/* @__PURE__ */c("TOGGLE_LINK_COMMAND");function tt(t,e){if("element"===t.type){const n=t.getNode();x(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 et(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,s=void 0===e.rel?"noreferrer":e.rel,l=g();if(null===l||!u(l)&&!f(l))return;if(f(l)){const t=l.getNodes();if(0===t.length)return;return void t.forEach(t=>{if(null===n){const e=d(t,t=>!X(t)&&q(t));e&&(e.insertBefore(t),0===e.getChildren().length&&e.remove())}else{const e=d(t,t=>!X(t)&&q(t));if(e)e.setURL(n),void 0!==r&&e.setTarget(r),void 0!==s&&e.setRel(s),void 0!==i&&e.setTitle(i);else{const e=G(n,{rel:s,target:r,title:i});t.insertBefore(e),e.append(t)}}})}if(l.isCollapsed()&&null===n)for(const t of l.getNodes()){const e=d(t,t=>!X(t)&&q(t));return void(null!==e&&(e.getParentOrThrow().splice(e.getIndexWithinParent(),0,e.getChildren()),e.remove()))}const a=l.extract();if(null===n){const t=new Set;return void a.forEach(e=>{const n=d(e,t=>!X(t)&&q(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())||x(r)&&e.some(e=>t.isParentOf(e)&&r.isParentOf(e)),s=r.filter(i);if(s.length===r.length)return r.forEach(e=>t.insertBefore(e)),void t.remove();const l=r.findIndex(i),u=r.findLastIndex(i),a=0===l,c=u===r.length-1;if(a)s.forEach(e=>t.insertBefore(e));else if(c)for(let e=s.length-1;e>=0;e--)t.insertAfter(s[e]);else{for(let e=s.length-1;e>=0;e--)t.insertAfter(s[e]);const e=r.slice(u+1);if(e.length>0){const n=o(t);s[s.length-1].insertAfter(n),e.forEach(t=>n.append(t))}}}(n,a),t.add(e)}})}const c=new Set,m=t=>{c.has(t.getKey())||(c.add(t.getKey()),t.setURL(n),void 0!==r&&t.setTarget(r),void 0!==s&&t.setRel(s),void 0!==i&&t.setTitle(i))};if(1===a.length){const t=a[0],e=d(t,q);if(null!==e)return m(e)}!function(t){const e=g();if(!u(e))return t();const n=h(e),r=n.isBackward(),i=tt(n.anchor,r?-1:0),s=tt(n.focus,r?0:-1),l=t();if(i||s){const t=g();if(u(t)){const e=t.clone();if(i){const t=i.getParent();t&&e.anchor.set(t.getKey(),i.getIndexWithinParent()+(r?1:0),"element")}if(s){const t=s.getParent();t&&e.focus.set(t.getKey(),s.getIndexWithinParent()+(r?0:1),"element")}p(h(e))}}}(()=>{let t=null;for(const e of a){if(!e.isAttached())continue;const l=d(e,q);if(l){m(l);continue}if(x(e)){if(!e.isInline())continue;if(q(e)){if(!(X(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();q(o)&&o.is(t)?o.append(e):(t=G(n,{rel:s,target:r,title:i}),e.insertAfter(t),t.append(e))}})}const nt=/^\+?[0-9\s()-]{5,}$/;function rt(t){return t.match(/^[a-z][a-z0-9+.-]*:/i)||t.match(/^[/#.]/)?t:t.includes("@")?`mailto:${t}`:nt.test(t)?`tel:${t}`:`https://${t}`}const it={build:(t,e)=>n(e),config:{created:"Link",createdMany:"%s links",destroyed:"Link removed",destroyedMany:"%s links removed",disabled:!1},dependencies:[t],name:"@lexical/link/AutoLinkAnnounce",register(n,r,i){const{created:s,createdMany:l,destroyed:o,destroyedMany:u,disabled:a}=i.getOutput(),{announce:c}=i.getDependency(t).output;return e(()=>a.value?void 0:n.registerMutationListener(Q,t=>{let e=0,n=0;for(const[,r]of t)"created"===r?e++:"destroyed"===r&&n++;e>0&&0===n?c(1===e?s.peek():l.peek().replace("%s",String(e))):n>0&&0===e&&c(1===n?o.peek():u.peek().replace("%s",String(n)))},{skipInitialization:!0}))}},st=[{$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 F(t.$importChildren(e),()=>G(n,r))},match:/* @__PURE__ */E.tag("a"),name:"@lexical/link/a"}];function lt(t,n){return C(t.registerNodeTransform(B,Z),t.registerCommand(Y,t=>{const e=n.validateUrl.peek(),r=n.attributes.peek();if(null===t)return et(null),!0;if("string"==typeof t)return!(void 0!==e&&!e(t))&&(et(t,r),!0);{const{url:n,...i}=t;return!(void 0!==e&&!e(n))&&(et(n,{...r,...i}),!0)}},S),e(()=>{const e=n.validateUrl.value;if(!e)return;const r=n.attributes.value;return t.registerCommand(y,n=>{const i=g();if(!u(i)||i.isCollapsed()||!z(n,ClipboardEvent))return!1;if(null===n.clipboardData)return!1;const s=n.clipboardData.getData("text");if(!e(s))return!1;return!i.getNodes().some(t=>x(t)||R(t)&&!t.isSimpleText())&&(t.dispatchCommand(Y,{...r,url:s}),n.preventDefault(),!0)},A)}))}const ot={build:(t,e,r)=>n(e),config:{attributes:void 0,validateUrl:void 0},dependencies:[W,[$,{rules:st}]],mergeConfig(t,e){const n=L(t,e);return t.attributes&&(n.attributes=L(t.attributes,n.attributes)),n},name:"@lexical/link/Link",nodes:()=>[B],register:(t,e,n)=>lt(t,n.getOutput())},ut={dependencies:[ot],name:"@lexical/link/Import"};function at(t,e,n={}){const r=n=>{const r=1===n.button;if("auxclick"===n.type&&!r)return;const i=n.target;if(!O(i))return;const s=N(i);if(null===s)return;let o=null,a=null,c=!1;if(s.update(()=>{const t=w(i);if(null!==t){const n=d(t,x);if(!e.disabled.peek())if(q(n))c=X(n)&&n.getIsUnlinked(),o=n.sanitizeUrl(n.getURL()),a=n.getTarget();else{const t=function(t,e){let n=t;for(;null!=n;){if(e(n))return n;n=n.parentNode}return null}(i,l);null!==t&&(o=t.href,a=t.target)}}}),null===o||""===o||c)return;const f=t.read("latest",g);!u(f)||f.isCollapsed()?(window.open(o,e.newTab.peek()||r||n.metaKey||n.ctrlKey||"_blank"===a?"_blank":"_self"),n.preventDefault()):n.preventDefault()};return t.registerRootListener(t=>{if(t)return P(t,{auxclick:r,click:r},n)})}const ct={build:(t,e,r)=>n(e),config:{disabled:!1,newTab:!1},dependencies:[ot],name:"@lexical/link/ClickableLink",register:(t,e,n)=>at(t,n.getOutput())};function gt(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 ft=/((https?:\/\/(www\.)?)|(www\.))[-\p{L}\p{N}@:%._+~#=]{1,256}\.[\p{L}\p{N}]{1,6}(?:[-\p{L}\p{N}()@:%_+.~#?&//=]*[\p{L}\p{N}()@_~#?&//=])?/u,dt=t=>{const e=ft.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}`}},ht=/* @__PURE__ */gt(/(([^<>()[\]\\.,;:\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 pt(t,e){for(let n=0;n<e.length;n++){const r=e[n](t);if(r)return r}return null}const mt=/[.,;\s]/;function xt(t,e){return e.test(t)}function _t(t,e){return xt(t[t.length-1],e)}function kt(t,e){return xt(t[0],e)}function bt(t,e){let n=t.getPreviousSibling();return x(n)&&(n=n.getLastDescendant()),null===n||D(n)||R(n)&&_t(n.getTextContent(),e)}function vt(t,e){let n=t.getNextSibling();return x(n)&&(n=n.getFirstDescendant()),null===n||D(n)||R(n)&&kt(n.getTextContent(),e)}function Ut(t,e,n,r,i){if(!(t>0?xt(r[t-1],n):bt(i[0],n)))return!1;return e<r.length?xt(r[e],n):vt(i[i.length-1],n)}function Tt(t,e,n){const r=[],i=[],s=[];let l=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),l+=a):c>=n?s.push(t):i.push(t),o+=a,u.shift()}return[l,r,i,s]}function Lt(t,e,n,r){const i=V(r.url,r.attributes);if(1===t.length){let s,l=t[0];0===e?[s,l]=l.splitText(n):[,s,l]=l.splitText(e,n);const o=M(r.text);return o.setFormat(s.getFormat()),o.setDetail(s.getDetail()),o.setStyle(s.getStyle()),i.append(o),s.replace(i),l}if(t.length>1){const r=t[0];let s,l=r.getTextContent().length;0===e?s=r:[,s]=r.splitText(e);const o=[];let a;for(let e=1;e<t.length;e++){const r=t[e],i=r.getTextContent().length,s=l;if(s<n)if(l+i<=n)o.push(r);else{const[t,e]=r.splitText(n-s);o.push(t),a=e}l+=i}const c=g(),d=c?c.getNodes().find(R):void 0,h=M(s.getTextContent());return h.setFormat(s.getFormat()),h.setDetail(s.getDetail()),h.setStyle(s.getStyle()),i.append(h,...o),d&&d===s&&(u(c)?h.select(c.anchor.offset,c.focus.offset):f(c)&&h.select(0,h.getTextContent().length)),s.replace(i),a}}function Ct(t,e,n,r){const i=t.getChildren(),s=i.length;for(let e=0;e<s;e++){const r=i[e];if(!R(r)||!r.isSimpleText())return St(t),void n(null,t.getURL())}const l=t.getTextContent(),o=pt(l,e);if(null===o||o.text!==l)return St(t),void n(null,t.getURL());if(!bt(t,r)||!vt(t,r))return St(t),void n(null,t.getURL());const u=t.getURL();u!==o.url&&(t.setURL(o.url),n(o.url,u)),o.attributes&&(t.getRel()!==o.attributes.rel&&t.setRel(o.attributes.rel||null),t.getTarget()!==o.attributes.target&&t.setTarget(o.attributes.target||null),t.getTitle()!==o.attributes.title&&t.setTitle(o.attributes.title||null))}function St(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 yt={changeHandlers:[],excludeParents:[],matchers:[],separatorRegex:mt};function Rt(t,e=yt){const{matchers:n,changeHandlers:r,excludeParents:i,separatorRegex:s=mt}=e,l=(t,e)=>{for(const n of r)n(t,e)};return C(t.registerNodeTransform(I,t=>{const e=t.getParentOrThrow(),r=t.getPreviousSibling();if(X(e))Ct(e,n,l,s);else if(!q(e)&&!i.some(t=>t(e))){if(t.isSimpleText()&&(kt(t.getTextContent(),s)||!X(r))){const e=function(t){const e=[t];let n=t.getNextSibling();for(;null!==n&&R(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(X(t)&&!t.getIsUnlinked())return}let i=[...t];const s=i.map(t=>t.getTextContent()).join("");let l,o=s,u=0;for(;(l=pt(o,e))&&null!==l;){const t=l.index,e=t+l.length;if(Ut(u+t,u+e,r,s,i)){const[r,,s,a]=Tt(i,u+t,u+e);let c=!1;for(const t of s){const e=t.getParent();if(X(e)&&!e.getIsUnlinked()){c=!0;break}}if(c){u+=e,o=o.substring(e);continue}const g=Lt(s,u+t-r,u+e-r,l);i=g?[g,...a]:a,n(l.url,null),u=0}else u+=e;o=o.substring(e)}}(e,n,l,s)}!function(t,e,n,r){const i=t.getParent(),s=t.getPreviousSibling(),l=t.getNextSibling(),o=t.getTextContent();if(!X(i)||i.getIsUnlinked()){if(X(s)&&!s.getIsUnlinked()&&s.is(t.getPreviousSibling())&&t.getParent()===s.getParent()){if(!kt(o,r))return St(s),void n(null,s.getURL());if(u=o,s.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(u):/^\.[a-zA-Z0-9]{1,}/.test(u)){const i=s.getTextContent()+o,l=pt(i,e);null!==l&&l.text===i&&(s.append(t),Ct(s,e,n,r),n(null,s.getURL()))}}var u;!X(l)||l.getIsUnlinked()||_t(o,r)||l.is(t.getNextSibling())&&t.getParent()===l.getParent()&&(St(l),n(null,l.getURL()))}}(t,n,l,s)}}),t.registerCommand(Y,t=>{const e=g();if(null!==t||!u(e))return!1;return e.extract().forEach(t=>{const e=t.getParent();X(e)&&(e.setIsUnlinked(!e.getIsUnlinked()),e.markDirty())}),!1},A))}const At={config:yt,dependencies:[it,ot],mergeConfig(t,e){const n=L(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:[Q],register:Rt};export{V as $createAutoLinkNode,G as $createLinkNode,X as $isAutoLinkNode,q as $isLinkNode,et as $toggleLink,it as AutoLinkAnnounceExtension,At as AutoLinkExtension,Q as AutoLinkNode,ct as ClickableLinkExtension,ot as LinkExtension,ut as LinkImportExtension,st as LinkImportRules,B as LinkNode,Y as TOGGLE_LINK_COMMAND,ht as autoLinkEmailMatcher,dt as autoLinkUrlMatcher,gt as createLinkMatcherWithRegExp,rt as formatUrl,Rt as registerAutoLink,at as registerClickableLink,lt as registerLink};
|
|
9
|
+
import{AriaLiveRegionExtension as t}from"@lexical/a11y";import{effect as e}from"@lexical/extension/signals";import{namedSignals as n}from"@lexical/extension/namedSignals";import{getterTableOf as r,setterTableOf as i,setterDefaultOf as l,ElementNode as o,$getDocument as s,addClassNamesToElement as u,isHTMLAnchorElement as a,$copyNode as c,$isRangeSelection as f,$applyNodeReplacement as g,createCommand as d,$getSelection as _,$isNodeSelection as p,$findMatchingParent as h,nodeSchema as m,withField as x,stringValue as y,nullable as v,booleanValue as k,$normalizeSelection__EXPERIMENTAL as b,$setSelection as U,$getChildCaret as S,$isElementNode as T,$insertNodeToNearestRootAtCaret as L,$rewindSiblingCaret as C,$caretFromPoint as A,$normalizeCaret as N,$isSiblingCaret as R,$setPointFromCaret as P,shallowMergeConfig as O,mergeRegister as I,COMMAND_PRIORITY_EDITOR as w,PASTE_COMMAND as F,$isTextNode as D,COMMAND_PRIORITY_LOW as M,registerEventListeners as E,isDOMNode as z,getNearestEditorFromDOMNode as $,$getNearestNodeFromDOMNode as W,TextNode as K,$isLineBreakNode as B,$createTextNode as j}from"lexical";import{sel as J,$distributeInlineWrapper as Z,CoreImportExtension as H,DOMImportExtension as G}from"@lexical/html";import{objectKlassEquals as q}from"@lexical/utils";const Q=/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;function V(t,e){if("number"==typeof t)return Number.isFinite(t)?t:e;if("string"!=typeof t||!Q.test(t))return e;const n=Number(t);return Number.isFinite(n)?n:e}function X(t,e,n,r,i){const l=V(t,e);return l>=n&&l<=r&&Number.isInteger(l)?l:e}function Y(t,e){t.__rel=e.__rel,t.__target=e.__target,t.__title=e.__title,t.__url=e.__url}const tt=t=>{const e=r(t,"format"),n=i(t,"format"),o=l(t,"format");return{exportJSON:function(t){const n=t.__textFormat,r=t.__textStyle,i=(0!==n||""!==r)&&t.shouldSerializeTextStyles();return{children:[],rel:t.__rel,target:t.__target,title:t.__title,url:t.__url,direction:t.__dir,format:e[t.__format],indent:t.__indent,textFormat:0!==n&&i?n:void 0,textStyle:""!==r&&i?r:void 0,type:t.__type,version:1}},exportCompactJSON:function(t){const n=t.__textFormat,r=t.__textStyle,i=(0!==n||""!==r)&&t.shouldSerializeTextStyles(),l={type:t.__type,children:[]},o=t.__rel;null!=o&&(l.rel=o);const s=t.__target;null!=s&&(l.target=s);const u=t.__title;null!=u&&(l.title=u);const a=t.__url;void 0!==a&&""!==a&&(l.url=a);const c=t.__dir;null!=c&&(l.direction=c);const f=e[t.__format];void 0!==f&&""!==f&&(l.format=f);const g=t.__indent;return void 0!==g&&0!==g&&(l.indent=g),void 0!==n&&0!==n&&i&&(l.textFormat=n),void 0!==r&&""!==r&&i&&(l.textStyle=r),l},updateFromJSON:function(t,e){const r=e.direction;t.__dir=null===r||"ltr"===r||"rtl"===r?r:null;const i=e.format;t.__format="string"==typeof i&&i in n?n[i]:o,t.__indent=X(e.indent,0,0,Infinity),t.__textFormat=V(e.textFormat,0);const l=e.textStyle;t.__textStyle="string"==typeof l?l:"";const s=e.rel;t.__rel="string"==typeof s&&""!==s?s:null;const u=e.target;t.__target="string"==typeof u&&""!==u?u:null;const a=e.title;t.__title="string"==typeof a&&""!==a?a:null;const c=e.url;return t.__url="string"==typeof c?c:"",t},afterCloneFrom:Y}};function et(t,e){t.__isUnlinked=e.__isUnlinked}const nt=t=>{const e=r(t,"format"),n=i(t,"format"),o=l(t,"format");return{exportJSON:function(t){const n=t.__textFormat,r=t.__textStyle,i=(0!==n||""!==r)&&t.shouldSerializeTextStyles();return{children:[],isUnlinked:t.__isUnlinked,rel:t.__rel,target:t.__target,title:t.__title,url:t.__url,direction:t.__dir,format:e[t.__format],indent:t.__indent,textFormat:0!==n&&i?n:void 0,textStyle:""!==r&&i?r:void 0,type:t.__type,version:1}},exportCompactJSON:function(t){const n=t.__textFormat,r=t.__textStyle,i=(0!==n||""!==r)&&t.shouldSerializeTextStyles(),l={type:t.__type,children:[]},o=t.__isUnlinked;void 0!==o&&!1!==o&&(l.isUnlinked=o);const s=t.__rel;null!=s&&(l.rel=s);const u=t.__target;null!=u&&(l.target=u);const a=t.__title;null!=a&&(l.title=a);const c=t.__url;void 0!==c&&""!==c&&(l.url=c);const f=t.__dir;null!=f&&(l.direction=f);const g=e[t.__format];void 0!==g&&""!==g&&(l.format=g);const d=t.__indent;return void 0!==d&&0!==d&&(l.indent=d),void 0!==n&&0!==n&&i&&(l.textFormat=n),void 0!==r&&""!==r&&i&&(l.textStyle=r),l},updateFromJSON:function(t,e){const r=e.direction;t.__dir=null===r||"ltr"===r||"rtl"===r?r:null;const i=e.format;t.__format="string"==typeof i&&i in n?n[i]:o,t.__indent=X(e.indent,0,0,Infinity),t.__textFormat=V(e.textFormat,0);const l=e.textStyle;t.__textStyle="string"==typeof l?l:"";const s=e.rel;t.__rel="string"==typeof s&&""!==s?s:null;const u=e.target;t.__target="string"==typeof u&&""!==u?u:null;const a=e.title;t.__title="string"==typeof a&&""!==a?a:null;const c=e.url;t.__url="string"==typeof c?c:"";const f=e.isUnlinked;return t.__isUnlinked="boolean"==typeof f&&f,t},afterCloneFrom:et}},rt=new Set(["http:","https:","mailto:","sms:","tel:"]),it=/* @__PURE__ */m()({rel:/* @__PURE__ */x(/* @__PURE__ */v(/* @__PURE__ */y(),{defaultAsNull:!0}),{field:"__rel"}),target:/* @__PURE__ */x(/* @__PURE__ */v(/* @__PURE__ */y(),{defaultAsNull:!0}),{field:"__target"}),title:/* @__PURE__ */x(/* @__PURE__ */v(/* @__PURE__ */y(),{defaultAsNull:!0}),{field:"__title"}),url:/* @__PURE__ */x(/* @__PURE__ */y(),{field:"__url",getter:"getURL",setter:"setURL"})});class lt extends o{__url;__target;__rel;__title;$config(){return this.config("link",{extends:o,generated:tt,importDOM:{a:()=>({conversion:at,priority:1})},json:it})}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}createDOM(t){const e=s().createElement("a");return this.updateLinkDOM(null,e,t),u(e,t.theme.link),e}updateLinkDOM(t,e,n){if(a(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}sanitizeUrl(t){const e=t;t=vt(t);try{const e=new URL(vt(t));if(!rt.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&&!rt.has(`${n[1].toLowerCase()}:`))return"about:blank"}return t}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=c(this);return this.insertAfter(n,e),n}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(t,e,n){if(!f(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.getURL().startsWith("mailto:")}isWebSiteURI(){const t=this.getURL();return t.startsWith("https://")||t.startsWith("http://")}shouldMergeAdjacentLink(t){return this.getType()===t.getType()&&this.getURL()===t.getURL()&&this.getTarget()===t.getTarget()&&this.getRel()===t.getRel()&&this.getTitle()===t.getTitle()}}function ot(t){const e=A(t,"next");return[e,e.getFlipped()]}function st(t,e){for(const n of e)if(n.origin.isAttached()){const e=N(n);return void P(t,e)}}function ut(t){const e=_();let n=null,r=null;function i(){f(e)&&(st(e.anchor,n),st(e.focus,r),b(e))}f(e)&&(n=ot(e.anchor),r=ot(e.focus));let l=!1;for(const e of S(t,"next")){const n=e.origin;if(T(n)&&!n.isInline()){const r=n.getChildren();if(r.length>0){const e=c(t);e.append(...r),n.append(e),l=!0}L(n,C(e),{$shouldSplit:()=>!1})}}function o(t,e,n){const[r,i]=t,l=t=>R(t)&&t.origin.is(e);if(!l(r)&&!l(i))return t;const o=N(S(n,"next"));return[o,o.getFlipped()]}if(t.isAttached()){const e=t.getPreviousSibling();if(ft(e)&&e.shouldMergeAdjacentLink(t))return n&&(n=o(n,e,t)),r&&(r=o(r,e,t)),e.append(...t.getChildren()),t.remove(),void i();const s=t.getNextSibling();ft(s)&&t.shouldMergeAdjacentLink(s)&&(n&&(n=o(n,t,s)),r&&(r=o(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 at(t){let e=null;if(a(t)){const n=t.textContent;(null!==n&&""!==n||t.children.length>0)&&(e=ct(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}))}return{node:e}}function ct(t="",e){return g(new lt(t,e))}function ft(t){return t instanceof lt}const gt=/* @__PURE__ */m()({isUnlinked:/* @__PURE__ */x(/* @__PURE__ */k(),{field:"__isUnlinked"})});class dt extends lt{__isUnlinked;constructor(t="",e={},n){super(t,e,n),this.__isUnlinked=void 0!==e.isUnlinked&&null!==e.isUnlinked&&e.isUnlinked}$config(){return this.config("autolink",{extends:lt,generated:nt,json:gt})}shouldMergeAdjacentLink(t){return!1}getIsUnlinked(){return this.getLatest().__isUnlinked}setIsUnlinked(t){const e=this.getWritable();return e.__isUnlinked=t,e}createDOM(t){return this.__isUnlinked?s().createElement("span"):super.createDOM(t)}updateDOM(t,e,n){return super.updateDOM(t,e,n)||t.__isUnlinked!==this.__isUnlinked}}function _t(t="",e){return g(new dt(t,e))}function pt(t){return t instanceof dt}const ht=/* @__PURE__ */d("TOGGLE_LINK_COMMAND");function mt(t,e){if("element"===t.type){const n=t.getNode();T(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 xt(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,o=_();if(null===o||!f(o)&&!p(o))return;if(p(o)){const t=o.getNodes();if(0===t.length)return;return void t.forEach(t=>{if(null===n){const e=h(t,t=>!pt(t)&&ft(t));e&&(e.insertBefore(t),0===e.getChildren().length&&e.remove())}else{const e=h(t,t=>!pt(t)&&ft(t));if(e)e.setURL(n),void 0!==r&&e.setTarget(r),void 0!==l&&e.setRel(l),void 0!==i&&e.setTitle(i);else{const e=ct(n,{rel:l,target:r,title:i});t.insertBefore(e),e.append(t)}}})}if(o.isCollapsed()&&null===n)for(const t of o.getNodes()){const e=h(t,t=>!pt(t)&&ft(t));return void(null!==e&&(e.getParentOrThrow().splice(e.getIndexWithinParent(),0,e.getChildren()),e.remove()))}const s=o.extract();if(null===n){const t=new Set;return void s.forEach(e=>{const n=h(e,t=>!pt(t)&&ft(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())||T(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),s=r.findLastIndex(i),u=0===o,a=s===r.length-1;if(u)l.forEach(e=>t.insertBefore(e));else if(a)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(s+1);if(e.length>0){const n=c(t);l[l.length-1].insertAfter(n),e.forEach(t=>n.append(t))}}}(n,s),t.add(e)}})}const u=new Set,a=t=>{u.has(t.getKey())||(u.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===s.length){const t=s[0],e=h(t,ft);if(null!==e)return a(e)}!function(t){const e=_();if(!f(e))return t();const n=b(e),r=n.isBackward(),i=mt(n.anchor,r?-1:0),l=mt(n.focus,r?0:-1),o=t();if(i||l){const t=_();if(f(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")}U(b(e))}}}(()=>{let t=null;for(const e of s){if(!e.isAttached())continue;const o=h(e,ft);if(o){a(o);continue}if(T(e)){if(!e.isInline())continue;if(ft(e)){if(!(pt(e)||null!==t&&t.getParentOrThrow().isParentOf(e))){a(e),t=e;continue}for(const t of e.getChildren())e.insertBefore(t);e.remove();continue}}const s=e.getPreviousSibling();ft(s)&&s.is(t)?s.append(e):(t=ct(n,{rel:l,target:r,title:i}),e.insertAfter(t),t.append(e))}})}const yt=/^\+?[0-9\s()-]{5,}$/;function vt(t){return t.match(/^[a-z][a-z0-9+.-]*:/i)||t.match(/^[/#.]/)?t:t.includes("@")?`mailto:${t}`:yt.test(t)?`tel:${t}`:`https://${t}`}const kt={build:(t,e)=>n(e),config:{created:"Link",createdMany:"%s links",destroyed:"Link removed",destroyedMany:"%s links removed",disabled:!1},dependencies:[t],name:"@lexical/link/AutoLinkAnnounce",register(n,r,i){const{created:l,createdMany:o,destroyed:s,destroyedMany:u,disabled:a}=i.getOutput(),{announce:c}=i.getDependency(t).output;return e(()=>a.value?void 0:n.registerMutationListener(dt,t=>{let e=0,n=0;for(const[,r]of t)"created"===r?e++:"destroyed"===r&&n++;e>0&&0===n?c(1===e?l.peek():o.peek().replace("%s",String(e))):n>0&&0===e&&c(1===n?s.peek():u.peek().replace("%s",String(n)))},{skipInitialization:!0}))}},bt=[{$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 Z(t.$importChildren(e),()=>ct(n,r))},match:/* @__PURE__ */J.tag("a"),name:"@lexical/link/a"}];function Ut(t,n){return I(t.registerNodeTransform(lt,ut),t.registerCommand(ht,t=>{const e=n.validateUrl.peek(),r=n.attributes.peek();if(null===t)return xt(null),!0;if("string"==typeof t)return!(void 0!==e&&!e(t))&&(xt(t,r),!0);{const{url:n,...i}=t;return!(void 0!==e&&!e(n))&&(xt(n,{...r,...i}),!0)}},w),e(()=>{const e=n.validateUrl.value;if(!e)return;const r=n.attributes.value;return t.registerCommand(F,n=>{const i=_();if(!f(i)||i.isCollapsed()||!q(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(t)||D(t)&&!t.isSimpleText())&&(t.dispatchCommand(ht,{...r,url:l}),n.preventDefault(),!0)},M)}))}const St={build:(t,e,r)=>n(e),config:{attributes:void 0,validateUrl:void 0},dependencies:[H,[G,{rules:bt}]],mergeConfig(t,e){const n=O(t,e);return t.attributes&&(n.attributes=O(t.attributes,n.attributes)),n},name:"@lexical/link/Link",nodes:()=>[lt],register:(t,e,n)=>Ut(t,n.getOutput())},Tt={dependencies:[St],name:"@lexical/link/Import"};function Lt(t,e,n={}){const r=n=>{const r=1===n.button;if("auxclick"===n.type&&!r)return;const i=n.target;if(!z(i))return;const l=$(i);if(null===l)return;let o=null,s=null,u=!1;if(l.update(()=>{const t=W(i);if(null!==t){const n=h(t,T);if(!e.disabled.peek())if(ft(n))u=pt(n)&&n.getIsUnlinked(),o=n.sanitizeUrl(n.getURL()),s=n.getTarget();else{const t=function(t,e){let n=t;for(;null!=n;){if(e(n))return n;n=n.parentNode}return null}(i,a);null!==t&&(o=t.href,s=t.target)}}}),null===o||""===o||u)return;const c=t.read("latest",_);!f(c)||c.isCollapsed()?(window.open(o,e.newTab.peek()||r||n.metaKey||n.ctrlKey||"_blank"===s?"_blank":"_self"),n.preventDefault()):n.preventDefault()};return t.registerRootListener(t=>{if(t)return E(t,{auxclick:r,click:r},n)})}const Ct={build:(t,e,r)=>n(e),config:{disabled:!1,newTab:!1},dependencies:[St],name:"@lexical/link/ClickableLink",register:(t,e,n)=>Lt(t,n.getOutput())};function At(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 Nt=/((https?:\/\/(www\.)?)|(www\.))[-\p{L}\p{N}@:%._+~#=]{1,256}\.[\p{L}\p{N}]{1,6}(?:[-\p{L}\p{N}()@:%_+.~#?&//=]*[\p{L}\p{N}()@_~#?&//=])?/u,Rt=t=>{const e=Nt.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}`}},Pt=/* @__PURE__ */At(/(([^<>()[\]\\.,;:\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 Ot(t,e){for(let n=0;n<e.length;n++){const r=e[n](t);if(r)return r}return null}const It=/[.,;\s]/;function wt(t,e){return e.test(t)}function Ft(t,e){return wt(t[t.length-1],e)}function Dt(t,e){return wt(t[0],e)}function Mt(t,e){let n=t.getPreviousSibling();return T(n)&&(n=n.getLastDescendant()),null===n||B(n)||D(n)&&Ft(n.getTextContent(),e)}function Et(t,e){let n=t.getNextSibling();return T(n)&&(n=n.getFirstDescendant()),null===n||B(n)||D(n)&&Dt(n.getTextContent(),e)}function zt(t,e,n,r,i){if(!(t>0?wt(r[t-1],n):Mt(i[0],n)))return!1;return e<r.length?wt(r[e],n):Et(i[i.length-1],n)}function $t(t,e,n){const r=[],i=[],l=[];let o=0,s=0;const u=[...t];for(;u.length>0;){const t=u[0],a=t.getTextContent().length,c=s;s+a<=e?(r.push(t),o+=a):c>=n?l.push(t):i.push(t),s+=a,u.shift()}return[o,r,i,l]}function Wt(t,e,n,r){const i=_t(r.url,r.attributes);if(1===t.length){let l,o=t[0];0===e?[l,o]=o.splitText(n):[,l,o]=o.splitText(e,n);const s=j(r.text);return s.setFormat(l.getFormat()),s.setDetail(l.getDetail()),s.setStyle(l.getStyle()),i.append(s),l.replace(i),o}if(t.length>1){const r=t[0];let l,o=r.getTextContent().length;0===e?l=r:[,l]=r.splitText(e);const s=[];let u;for(let e=1;e<t.length;e++){const r=t[e],i=r.getTextContent().length,l=o;if(l<n)if(o+i<=n)s.push(r);else{const[t,e]=r.splitText(n-l);s.push(t),u=e}o+=i}const a=_(),c=a?a.getNodes().find(D):void 0,g=j(l.getTextContent());return g.setFormat(l.getFormat()),g.setDetail(l.getDetail()),g.setStyle(l.getStyle()),i.append(g,...s),c&&c===l&&(f(a)?g.select(a.anchor.offset,a.focus.offset):p(a)&&g.select(0,g.getTextContent().length)),l.replace(i),u}}function Kt(t,e,n,r){const i=t.getChildren(),l=i.length;for(let e=0;e<l;e++){const r=i[e];if(!D(r)||!r.isSimpleText())return Bt(t),void n(null,t.getURL())}const o=t.getTextContent(),s=Ot(o,e);if(null===s||s.text!==o)return Bt(t),void n(null,t.getURL());if(!Mt(t,r)||!Et(t,r))return Bt(t),void n(null,t.getURL());const u=t.getURL();u!==s.url&&(t.setURL(s.url),n(s.url,u)),s.attributes&&(t.getRel()!==s.attributes.rel&&t.setRel(s.attributes.rel||null),t.getTarget()!==s.attributes.target&&t.setTarget(s.attributes.target||null),t.getTitle()!==s.attributes.title&&t.setTitle(s.attributes.title||null))}function Bt(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 jt={changeHandlers:[],excludeParents:[],matchers:[],separatorRegex:It};function Jt(t,e=jt){const{matchers:n,changeHandlers:r,excludeParents:i,separatorRegex:l=It}=e,o=(t,e)=>{for(const n of r)n(t,e)};return I(t.registerNodeTransform(K,t=>{const e=t.getParentOrThrow(),r=t.getPreviousSibling();if(pt(e))Kt(e,n,o,l);else if(!ft(e)&&!i.some(t=>t(e))){if(t.isSimpleText()&&(Dt(t.getTextContent(),l)||!pt(r))){const e=function(t){const e=[t];let n=t.getNextSibling();for(;null!==n&&D(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(pt(t)&&!t.getIsUnlinked())return}let i=[...t];const l=i.map(t=>t.getTextContent()).join("");let o,s=l,u=0;for(;(o=Ot(s,e))&&null!==o;){const t=o.index,e=t+o.length;if(zt(u+t,u+e,r,l,i)){const[r,,l,a]=$t(i,u+t,u+e);let c=!1;for(const t of l){const e=t.getParent();if(pt(e)&&!e.getIsUnlinked()){c=!0;break}}if(c){u+=e,s=s.substring(e);continue}const f=Wt(l,u+t-r,u+e-r,o);i=f?[f,...a]:a,n(o.url,null),u=0}else u+=e;s=s.substring(e)}}(e,n,o,l)}!function(t,e,n,r){const i=t.getParent(),l=t.getPreviousSibling(),o=t.getNextSibling(),s=t.getTextContent();if(!pt(i)||i.getIsUnlinked()){if(pt(l)&&!l.getIsUnlinked()&&l.is(t.getPreviousSibling())&&t.getParent()===l.getParent()){if(!Dt(s,r))return Bt(l),void n(null,l.getURL());if(u=s,l.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(u):/^\.[a-zA-Z0-9]{1,}/.test(u)){const i=l.getTextContent()+s,o=Ot(i,e);null!==o&&o.text===i&&(l.append(t),Kt(l,e,n,r),n(null,l.getURL()))}}var u;!pt(o)||o.getIsUnlinked()||Ft(s,r)||o.is(t.getNextSibling())&&t.getParent()===o.getParent()&&(Bt(o),n(null,o.getURL()))}}(t,n,o,l)}}),t.registerCommand(ht,t=>{const e=_();if(null!==t||!f(e))return!1;return e.extract().forEach(t=>{const e=t.getParent();pt(e)&&(e.setIsUnlinked(!e.getIsUnlinked()),e.markDirty())}),!1},M))}const Zt={config:jt,dependencies:[kt,St],mergeConfig(t,e){const n=O(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:[dt],register:Jt};export{_t as $createAutoLinkNode,ct as $createLinkNode,pt as $isAutoLinkNode,ft as $isLinkNode,xt as $toggleLink,kt as AutoLinkAnnounceExtension,Zt as AutoLinkExtension,dt as AutoLinkNode,Ct as ClickableLinkExtension,St as LinkExtension,Tt as LinkImportExtension,bt as LinkImportRules,lt as LinkNode,ht as TOGGLE_LINK_COMMAND,Pt as autoLinkEmailMatcher,Rt as autoLinkUrlMatcher,At as createLinkMatcherWithRegExp,vt as formatUrl,Jt as registerAutoLink,Lt as registerClickableLink,Ut as registerLink};
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
*/
|
|
8
|
+
import type { AutoLinkNode, LinkNode } from './LexicalLinkNode.js';
|
|
9
|
+
import { type GeneratedJSONFactory } from 'lexical';
|
|
10
|
+
/**
|
|
11
|
+
* LinkNode's schema-declared fields, for a clone. Generated from that
|
|
12
|
+
* schema; do not edit by hand.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export declare function afterCloneLinkNode(node: LinkNode, prevNode: LinkNode): void;
|
|
17
|
+
/** LinkNode's generated implementations, for its `$config`. @internal */
|
|
18
|
+
export declare const GENERATED_LINK: GeneratedJSONFactory;
|
|
19
|
+
/**
|
|
20
|
+
* AutoLinkNode's schema-declared fields, for a clone. Generated from that
|
|
21
|
+
* schema; do not edit by hand.
|
|
22
|
+
*
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export declare function afterCloneAutoLinkNode(node: AutoLinkNode, prevNode: AutoLinkNode): void;
|
|
26
|
+
/** AutoLinkNode's generated implementations, for its `$config`. @internal */
|
|
27
|
+
export declare const GENERATED_AUTOLINK: GeneratedJSONFactory;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import { type BaseSelection, type DOMConversionOutput, type EditorConfig, ElementNode, type LexicalCommand, type LexicalNode, type
|
|
8
|
+
import { type BaseSelection, type DOMConversionOutput, type EditorConfig, ElementNode, type LexicalCommand, type LexicalNode, type LexicalParseJSON, type NodeKey, type RangeSelection, type SerializedElementNode, type SerializedPartial, type Spread } from 'lexical';
|
|
9
9
|
export type LinkAttributes = {
|
|
10
10
|
rel?: null | string;
|
|
11
11
|
target?: null | string;
|
|
@@ -18,6 +18,11 @@ export type SerializedLinkNode = Spread<{
|
|
|
18
18
|
url: string;
|
|
19
19
|
}, Spread<LinkAttributes, SerializedElementNode>>;
|
|
20
20
|
type LinkHTMLElementType = HTMLAnchorElement | HTMLSpanElement;
|
|
21
|
+
export interface LinkNode {
|
|
22
|
+
exportJSON(compact?: false): SerializedLinkNode;
|
|
23
|
+
exportJSON(compact: boolean): SerializedPartial<SerializedLinkNode>;
|
|
24
|
+
updateFromJSON(serializedNode: LexicalParseJSON<SerializedLinkNode>): this;
|
|
25
|
+
}
|
|
21
26
|
/** @noInheritDoc */
|
|
22
27
|
export declare class LinkNode extends ElementNode {
|
|
23
28
|
/** @internal */
|
|
@@ -28,33 +33,55 @@ export declare class LinkNode extends ElementNode {
|
|
|
28
33
|
__rel: null | string;
|
|
29
34
|
/** @internal */
|
|
30
35
|
__title: null | string;
|
|
31
|
-
$config(): import("lexical").BaseStaticNodeConfig & {
|
|
36
|
+
$config(): import("lexical").BaseStaticNodeConfig & import("lexical").StaticNodeConfigAccessor<{
|
|
37
|
+
readonly $transform: (node: ElementNode) => void;
|
|
38
|
+
readonly extends: typeof LexicalNode;
|
|
39
|
+
readonly generated: import("lexical").GeneratedJSONFactory;
|
|
40
|
+
readonly json: import("lexical").NodeSerializationSchema<ElementNode, {
|
|
41
|
+
readonly direction?: "ltr" | "rtl" | null | undefined;
|
|
42
|
+
readonly format?: "" | "left" | "start" | "center" | "right" | "end" | "justify" | undefined;
|
|
43
|
+
readonly indent?: string | number | undefined;
|
|
44
|
+
readonly textFormat?: string | number | undefined;
|
|
45
|
+
readonly textStyle?: string | undefined;
|
|
46
|
+
}>;
|
|
47
|
+
}> & {
|
|
32
48
|
readonly link?: {
|
|
33
49
|
readonly extends: typeof ElementNode;
|
|
50
|
+
readonly generated: import("lexical").GeneratedJSONFactory;
|
|
34
51
|
readonly importDOM: {
|
|
35
52
|
readonly a: () => {
|
|
36
53
|
conversion: typeof $convertAnchorElement;
|
|
37
54
|
priority: 1;
|
|
38
55
|
};
|
|
39
56
|
};
|
|
57
|
+
readonly json: import("lexical").NodeSerializationSchema<LinkNode, {
|
|
58
|
+
readonly rel?: string | null | undefined;
|
|
59
|
+
readonly target?: string | null | undefined;
|
|
60
|
+
readonly title?: string | null | undefined;
|
|
61
|
+
readonly url?: string | undefined;
|
|
62
|
+
}>;
|
|
40
63
|
} | undefined;
|
|
41
64
|
} & import("lexical").StaticNodeTypeAccessor<"link"> & import("lexical").StaticNodeConfigAccessor<{
|
|
42
65
|
readonly extends: typeof ElementNode;
|
|
66
|
+
readonly generated: import("lexical").GeneratedJSONFactory;
|
|
43
67
|
readonly importDOM: {
|
|
44
68
|
readonly a: () => {
|
|
45
69
|
conversion: typeof $convertAnchorElement;
|
|
46
70
|
priority: 1;
|
|
47
71
|
};
|
|
48
72
|
};
|
|
73
|
+
readonly json: import("lexical").NodeSerializationSchema<LinkNode, {
|
|
74
|
+
readonly rel?: string | null | undefined;
|
|
75
|
+
readonly target?: string | null | undefined;
|
|
76
|
+
readonly title?: string | null | undefined;
|
|
77
|
+
readonly url?: string | undefined;
|
|
78
|
+
}>;
|
|
49
79
|
}>;
|
|
50
80
|
constructor(url?: string, attributes?: LinkAttributes, key?: NodeKey);
|
|
51
|
-
afterCloneFrom(prevNode: this): void;
|
|
52
81
|
createDOM(config: EditorConfig): LinkHTMLElementType;
|
|
53
82
|
updateLinkDOM(prevNode: this | null, anchor: LinkHTMLElementType, config: EditorConfig): void;
|
|
54
83
|
updateDOM(prevNode: this, anchor: LinkHTMLElementType, config: EditorConfig): boolean;
|
|
55
|
-
updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedLinkNode>): this;
|
|
56
84
|
sanitizeUrl(url: string): string;
|
|
57
|
-
exportJSON(): SerializedLinkNode | SerializedAutoLinkNode;
|
|
58
85
|
getURL(): string;
|
|
59
86
|
setURL(url: string): this;
|
|
60
87
|
getTarget(): null | string;
|
|
@@ -96,44 +123,79 @@ export declare function $isLinkNode(node: LexicalNode | null | undefined): node
|
|
|
96
123
|
export type SerializedAutoLinkNode = Spread<{
|
|
97
124
|
isUnlinked: boolean;
|
|
98
125
|
}, SerializedLinkNode>;
|
|
126
|
+
export interface AutoLinkNode {
|
|
127
|
+
exportJSON(compact?: false): SerializedAutoLinkNode;
|
|
128
|
+
exportJSON(compact: boolean): SerializedPartial<SerializedAutoLinkNode>;
|
|
129
|
+
updateFromJSON(serializedNode: LexicalParseJSON<SerializedAutoLinkNode>): this;
|
|
130
|
+
}
|
|
99
131
|
export declare class AutoLinkNode extends LinkNode {
|
|
100
132
|
/** @internal */
|
|
101
133
|
/** Indicates whether the autolink was ever unlinked. **/
|
|
102
134
|
__isUnlinked: boolean;
|
|
103
135
|
constructor(url?: string, attributes?: AutoLinkAttributes, key?: NodeKey);
|
|
104
|
-
|
|
105
|
-
|
|
136
|
+
$config(): import("lexical").BaseStaticNodeConfig & import("lexical").StaticNodeConfigAccessor<{
|
|
137
|
+
readonly $transform: (node: ElementNode) => void;
|
|
138
|
+
readonly extends: typeof LexicalNode;
|
|
139
|
+
readonly generated: import("lexical").GeneratedJSONFactory;
|
|
140
|
+
readonly json: import("lexical").NodeSerializationSchema<ElementNode, {
|
|
141
|
+
readonly direction?: "ltr" | "rtl" | null | undefined;
|
|
142
|
+
readonly format?: "" | "left" | "start" | "center" | "right" | "end" | "justify" | undefined;
|
|
143
|
+
readonly indent?: string | number | undefined;
|
|
144
|
+
readonly textFormat?: string | number | undefined;
|
|
145
|
+
readonly textStyle?: string | undefined;
|
|
146
|
+
}>;
|
|
147
|
+
}> & {
|
|
106
148
|
readonly link?: {
|
|
107
149
|
readonly extends: typeof ElementNode;
|
|
150
|
+
readonly generated: import("lexical").GeneratedJSONFactory;
|
|
108
151
|
readonly importDOM: {
|
|
109
152
|
readonly a: () => {
|
|
110
153
|
conversion: typeof $convertAnchorElement;
|
|
111
154
|
priority: 1;
|
|
112
155
|
};
|
|
113
156
|
};
|
|
157
|
+
readonly json: import("lexical").NodeSerializationSchema<LinkNode, {
|
|
158
|
+
readonly rel?: string | null | undefined;
|
|
159
|
+
readonly target?: string | null | undefined;
|
|
160
|
+
readonly title?: string | null | undefined;
|
|
161
|
+
readonly url?: string | undefined;
|
|
162
|
+
}>;
|
|
114
163
|
} | undefined;
|
|
115
164
|
} & import("lexical").StaticNodeTypeAccessor<"link"> & import("lexical").StaticNodeConfigAccessor<{
|
|
116
165
|
readonly extends: typeof ElementNode;
|
|
166
|
+
readonly generated: import("lexical").GeneratedJSONFactory;
|
|
117
167
|
readonly importDOM: {
|
|
118
168
|
readonly a: () => {
|
|
119
169
|
conversion: typeof $convertAnchorElement;
|
|
120
170
|
priority: 1;
|
|
121
171
|
};
|
|
122
172
|
};
|
|
173
|
+
readonly json: import("lexical").NodeSerializationSchema<LinkNode, {
|
|
174
|
+
readonly rel?: string | null | undefined;
|
|
175
|
+
readonly target?: string | null | undefined;
|
|
176
|
+
readonly title?: string | null | undefined;
|
|
177
|
+
readonly url?: string | undefined;
|
|
178
|
+
}>;
|
|
123
179
|
}> & {
|
|
124
180
|
readonly autolink?: {
|
|
125
181
|
readonly extends: typeof LinkNode;
|
|
182
|
+
readonly generated: import("lexical").GeneratedJSONFactory;
|
|
183
|
+
readonly json: import("lexical").NodeSerializationSchema<AutoLinkNode, {
|
|
184
|
+
readonly isUnlinked?: boolean | undefined;
|
|
185
|
+
}>;
|
|
126
186
|
} | undefined;
|
|
127
187
|
} & import("lexical").StaticNodeTypeAccessor<"autolink"> & import("lexical").StaticNodeConfigAccessor<{
|
|
128
188
|
readonly extends: typeof LinkNode;
|
|
189
|
+
readonly generated: import("lexical").GeneratedJSONFactory;
|
|
190
|
+
readonly json: import("lexical").NodeSerializationSchema<AutoLinkNode, {
|
|
191
|
+
readonly isUnlinked?: boolean | undefined;
|
|
192
|
+
}>;
|
|
129
193
|
}>;
|
|
130
194
|
shouldMergeAdjacentLink(_otherLink: LinkNode): boolean;
|
|
131
195
|
getIsUnlinked(): boolean;
|
|
132
196
|
setIsUnlinked(value: boolean): this;
|
|
133
197
|
createDOM(config: EditorConfig): LinkHTMLElementType;
|
|
134
198
|
updateDOM(prevNode: this, anchor: LinkHTMLElementType, config: EditorConfig): boolean;
|
|
135
|
-
updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedAutoLinkNode>): this;
|
|
136
|
-
exportJSON(): SerializedAutoLinkNode;
|
|
137
199
|
}
|
|
138
200
|
/**
|
|
139
201
|
* Takes a URL and creates an AutoLinkNode. AutoLinkNodes are generally automatically generated
|
package/package.json
CHANGED
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
"link"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.51.0",
|
|
12
12
|
"main": "./dist/LexicalLink.js",
|
|
13
13
|
"types": "./dist/typescript-too-old.d.ts",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@lexical/a11y": "0.
|
|
16
|
-
"@lexical/extension": "0.
|
|
17
|
-
"@lexical/html": "0.
|
|
18
|
-
"@lexical/internal": "0.
|
|
19
|
-
"@lexical/utils": "0.
|
|
20
|
-
"lexical": "0.
|
|
15
|
+
"@lexical/a11y": "0.51.0",
|
|
16
|
+
"@lexical/extension": "0.51.0",
|
|
17
|
+
"@lexical/html": "0.51.0",
|
|
18
|
+
"@lexical/internal": "0.51.0",
|
|
19
|
+
"@lexical/utils": "0.51.0",
|
|
20
|
+
"lexical": "0.51.0"
|
|
21
21
|
},
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
@@ -0,0 +1,370 @@
|
|
|
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
|
+
*/
|
|
8
|
+
|
|
9
|
+
// @generated by scripts/generate-node-json.mjs from each class's `json`
|
|
10
|
+
// schema. Run `pnpm run generate-node-json` to regenerate; do not edit.
|
|
11
|
+
|
|
12
|
+
// Keys are emitted in the order the schema-driven walk writes them, so the two
|
|
13
|
+
// produce byte-identical JSON. That order is the schema's, not alphabetical.
|
|
14
|
+
/* eslint-disable sort-keys-fix/sort-keys-fix */
|
|
15
|
+
|
|
16
|
+
import type {AutoLinkNode, LinkNode} from './LexicalLinkNode';
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
type GeneratedJSONFactory,
|
|
20
|
+
getterTableOf,
|
|
21
|
+
setterDefaultOf,
|
|
22
|
+
setterTableOf,
|
|
23
|
+
} from 'lexical';
|
|
24
|
+
|
|
25
|
+
// The JSON number grammar, anchored, matching numberValue: `Number()` alone
|
|
26
|
+
// reads '0x10' as 16 and '' as 0, and neither is a shape a JSON encoder
|
|
27
|
+
// produces. Emitted from the same source the codegen verified against, so the
|
|
28
|
+
// two cannot be different functions.
|
|
29
|
+
const JSON_NUMBER = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
30
|
+
|
|
31
|
+
function num(v: unknown, d: number): number {
|
|
32
|
+
if (typeof v === 'number') {
|
|
33
|
+
return Number.isFinite(v) ? v : d;
|
|
34
|
+
}
|
|
35
|
+
if (typeof v !== 'string' || !JSON_NUMBER.test(v)) {
|
|
36
|
+
return d;
|
|
37
|
+
}
|
|
38
|
+
const n = Number(v);
|
|
39
|
+
return Number.isFinite(n) ? n : d;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function numC(
|
|
43
|
+
v: unknown,
|
|
44
|
+
d: number,
|
|
45
|
+
min: number,
|
|
46
|
+
max: number,
|
|
47
|
+
integer: boolean,
|
|
48
|
+
): number {
|
|
49
|
+
const n = num(v, d);
|
|
50
|
+
return n >= min && n <= max && (!integer || Number.isInteger(n)) ? n : d;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* LinkNode's schema-declared fields, for a clone. Generated from that
|
|
55
|
+
* schema; do not edit by hand.
|
|
56
|
+
*
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
export function afterCloneLinkNode(node: LinkNode, prevNode: LinkNode): void {
|
|
60
|
+
node.__rel = prevNode.__rel;
|
|
61
|
+
node.__target = prevNode.__target;
|
|
62
|
+
node.__title = prevNode.__title;
|
|
63
|
+
node.__url = prevNode.__url;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** LinkNode's generated implementations, for its `$config`. @internal */
|
|
67
|
+
export const GENERATED_LINK: GeneratedJSONFactory = fields => {
|
|
68
|
+
const LINK_FORMAT_GETTER = getterTableOf(fields, 'format') as {
|
|
69
|
+
readonly [key: string]:
|
|
70
|
+
| ''
|
|
71
|
+
| 'center'
|
|
72
|
+
| 'end'
|
|
73
|
+
| 'justify'
|
|
74
|
+
| 'left'
|
|
75
|
+
| 'right'
|
|
76
|
+
| 'start';
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const LINK_FORMAT_SETTER = setterTableOf(fields, 'format') as {
|
|
80
|
+
readonly [key: string]: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const LINK_FORMAT_SETTER_DEFAULT = setterDefaultOf(fields, 'format') as
|
|
84
|
+
| 0
|
|
85
|
+
| 1
|
|
86
|
+
| 2
|
|
87
|
+
| 3
|
|
88
|
+
| 4
|
|
89
|
+
| 5
|
|
90
|
+
| 6;
|
|
91
|
+
|
|
92
|
+
/** Generated from LinkNode's serialization schema. Do not edit by hand. */
|
|
93
|
+
function exportLinkNode(node: LinkNode): {[key: string]: unknown} {
|
|
94
|
+
const textFormat = node.__textFormat;
|
|
95
|
+
const textStyle = node.__textStyle;
|
|
96
|
+
const shouldSerializeTextStyles =
|
|
97
|
+
(textFormat !== 0 || textStyle !== '') &&
|
|
98
|
+
node.shouldSerializeTextStyles();
|
|
99
|
+
return {
|
|
100
|
+
children: [],
|
|
101
|
+
rel: node.__rel,
|
|
102
|
+
target: node.__target,
|
|
103
|
+
title: node.__title,
|
|
104
|
+
url: node.__url,
|
|
105
|
+
direction: node.__dir,
|
|
106
|
+
format: LINK_FORMAT_GETTER[node.__format],
|
|
107
|
+
indent: node.__indent,
|
|
108
|
+
textFormat:
|
|
109
|
+
textFormat !== 0 && shouldSerializeTextStyles ? textFormat : undefined,
|
|
110
|
+
textStyle:
|
|
111
|
+
textStyle !== '' && shouldSerializeTextStyles ? textStyle : undefined,
|
|
112
|
+
type: node.__type,
|
|
113
|
+
version: 1,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Generated from LinkNode's serialization schema. Do not edit by hand. */
|
|
118
|
+
function exportCompactLinkNode(node: LinkNode): {[key: string]: unknown} {
|
|
119
|
+
const textFormat = node.__textFormat;
|
|
120
|
+
const textStyle = node.__textStyle;
|
|
121
|
+
const shouldSerializeTextStyles =
|
|
122
|
+
(textFormat !== 0 || textStyle !== '') &&
|
|
123
|
+
node.shouldSerializeTextStyles();
|
|
124
|
+
const json: {[key: string]: unknown} = {type: node.__type, children: []};
|
|
125
|
+
const rel = node.__rel;
|
|
126
|
+
if (rel != null) {
|
|
127
|
+
json.rel = rel;
|
|
128
|
+
}
|
|
129
|
+
const target = node.__target;
|
|
130
|
+
if (target != null) {
|
|
131
|
+
json.target = target;
|
|
132
|
+
}
|
|
133
|
+
const title = node.__title;
|
|
134
|
+
if (title != null) {
|
|
135
|
+
json.title = title;
|
|
136
|
+
}
|
|
137
|
+
const url = node.__url;
|
|
138
|
+
if (url !== undefined && url !== '') {
|
|
139
|
+
json.url = url;
|
|
140
|
+
}
|
|
141
|
+
const direction = node.__dir;
|
|
142
|
+
if (direction != null) {
|
|
143
|
+
json.direction = direction;
|
|
144
|
+
}
|
|
145
|
+
const format = LINK_FORMAT_GETTER[node.__format];
|
|
146
|
+
if (format !== undefined && format !== '') {
|
|
147
|
+
json.format = format;
|
|
148
|
+
}
|
|
149
|
+
const indent = node.__indent;
|
|
150
|
+
if (indent !== undefined && indent !== 0) {
|
|
151
|
+
json.indent = indent;
|
|
152
|
+
}
|
|
153
|
+
if (
|
|
154
|
+
textFormat !== undefined &&
|
|
155
|
+
textFormat !== 0 &&
|
|
156
|
+
shouldSerializeTextStyles
|
|
157
|
+
) {
|
|
158
|
+
json.textFormat = textFormat;
|
|
159
|
+
}
|
|
160
|
+
if (
|
|
161
|
+
textStyle !== undefined &&
|
|
162
|
+
textStyle !== '' &&
|
|
163
|
+
shouldSerializeTextStyles
|
|
164
|
+
) {
|
|
165
|
+
json.textStyle = textStyle;
|
|
166
|
+
}
|
|
167
|
+
return json;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Generated from LinkNode's serialization schema. Do not edit by hand. */
|
|
171
|
+
function updateLinkNode(
|
|
172
|
+
node: LinkNode,
|
|
173
|
+
json: {readonly [key: string]: unknown},
|
|
174
|
+
): LinkNode {
|
|
175
|
+
const direction = json.direction;
|
|
176
|
+
node.__dir =
|
|
177
|
+
direction === null || direction === 'ltr' || direction === 'rtl'
|
|
178
|
+
? direction
|
|
179
|
+
: null;
|
|
180
|
+
const format = json.format;
|
|
181
|
+
node.__format =
|
|
182
|
+
typeof format === 'string' && format in LINK_FORMAT_SETTER
|
|
183
|
+
? LINK_FORMAT_SETTER[format]
|
|
184
|
+
: LINK_FORMAT_SETTER_DEFAULT;
|
|
185
|
+
node.__indent = numC(json.indent, 0, 0, Infinity, true);
|
|
186
|
+
node.__textFormat = num(json.textFormat, 0);
|
|
187
|
+
const textStyle = json.textStyle;
|
|
188
|
+
node.__textStyle = typeof textStyle === 'string' ? textStyle : '';
|
|
189
|
+
const rel = json.rel;
|
|
190
|
+
node.__rel = typeof rel === 'string' && rel !== '' ? rel : null;
|
|
191
|
+
const target = json.target;
|
|
192
|
+
node.__target = typeof target === 'string' && target !== '' ? target : null;
|
|
193
|
+
const title = json.title;
|
|
194
|
+
node.__title = typeof title === 'string' && title !== '' ? title : null;
|
|
195
|
+
const url = json.url;
|
|
196
|
+
node.__url = typeof url === 'string' ? url : '';
|
|
197
|
+
return node;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
exportJSON: exportLinkNode,
|
|
202
|
+
exportCompactJSON: exportCompactLinkNode,
|
|
203
|
+
updateFromJSON: updateLinkNode,
|
|
204
|
+
afterCloneFrom: afterCloneLinkNode,
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* AutoLinkNode's schema-declared fields, for a clone. Generated from that
|
|
210
|
+
* schema; do not edit by hand.
|
|
211
|
+
*
|
|
212
|
+
* @internal
|
|
213
|
+
*/
|
|
214
|
+
export function afterCloneAutoLinkNode(
|
|
215
|
+
node: AutoLinkNode,
|
|
216
|
+
prevNode: AutoLinkNode,
|
|
217
|
+
): void {
|
|
218
|
+
node.__isUnlinked = prevNode.__isUnlinked;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** AutoLinkNode's generated implementations, for its `$config`. @internal */
|
|
222
|
+
export const GENERATED_AUTOLINK: GeneratedJSONFactory = fields => {
|
|
223
|
+
const AUTOLINK_FORMAT_GETTER = getterTableOf(fields, 'format') as {
|
|
224
|
+
readonly [key: string]:
|
|
225
|
+
| ''
|
|
226
|
+
| 'center'
|
|
227
|
+
| 'end'
|
|
228
|
+
| 'justify'
|
|
229
|
+
| 'left'
|
|
230
|
+
| 'right'
|
|
231
|
+
| 'start';
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const AUTOLINK_FORMAT_SETTER = setterTableOf(fields, 'format') as {
|
|
235
|
+
readonly [key: string]: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const AUTOLINK_FORMAT_SETTER_DEFAULT = setterDefaultOf(fields, 'format') as
|
|
239
|
+
| 0
|
|
240
|
+
| 1
|
|
241
|
+
| 2
|
|
242
|
+
| 3
|
|
243
|
+
| 4
|
|
244
|
+
| 5
|
|
245
|
+
| 6;
|
|
246
|
+
|
|
247
|
+
/** Generated from AutoLinkNode's serialization schema. Do not edit by hand. */
|
|
248
|
+
function exportAutoLinkNode(node: AutoLinkNode): {[key: string]: unknown} {
|
|
249
|
+
const textFormat = node.__textFormat;
|
|
250
|
+
const textStyle = node.__textStyle;
|
|
251
|
+
const shouldSerializeTextStyles =
|
|
252
|
+
(textFormat !== 0 || textStyle !== '') &&
|
|
253
|
+
node.shouldSerializeTextStyles();
|
|
254
|
+
return {
|
|
255
|
+
children: [],
|
|
256
|
+
isUnlinked: node.__isUnlinked,
|
|
257
|
+
rel: node.__rel,
|
|
258
|
+
target: node.__target,
|
|
259
|
+
title: node.__title,
|
|
260
|
+
url: node.__url,
|
|
261
|
+
direction: node.__dir,
|
|
262
|
+
format: AUTOLINK_FORMAT_GETTER[node.__format],
|
|
263
|
+
indent: node.__indent,
|
|
264
|
+
textFormat:
|
|
265
|
+
textFormat !== 0 && shouldSerializeTextStyles ? textFormat : undefined,
|
|
266
|
+
textStyle:
|
|
267
|
+
textStyle !== '' && shouldSerializeTextStyles ? textStyle : undefined,
|
|
268
|
+
type: node.__type,
|
|
269
|
+
version: 1,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/** Generated from AutoLinkNode's serialization schema. Do not edit by hand. */
|
|
274
|
+
function exportCompactAutoLinkNode(node: AutoLinkNode): {
|
|
275
|
+
[key: string]: unknown;
|
|
276
|
+
} {
|
|
277
|
+
const textFormat = node.__textFormat;
|
|
278
|
+
const textStyle = node.__textStyle;
|
|
279
|
+
const shouldSerializeTextStyles =
|
|
280
|
+
(textFormat !== 0 || textStyle !== '') &&
|
|
281
|
+
node.shouldSerializeTextStyles();
|
|
282
|
+
const json: {[key: string]: unknown} = {type: node.__type, children: []};
|
|
283
|
+
const isUnlinked = node.__isUnlinked;
|
|
284
|
+
if (isUnlinked !== undefined && isUnlinked !== false) {
|
|
285
|
+
json.isUnlinked = isUnlinked;
|
|
286
|
+
}
|
|
287
|
+
const rel = node.__rel;
|
|
288
|
+
if (rel != null) {
|
|
289
|
+
json.rel = rel;
|
|
290
|
+
}
|
|
291
|
+
const target = node.__target;
|
|
292
|
+
if (target != null) {
|
|
293
|
+
json.target = target;
|
|
294
|
+
}
|
|
295
|
+
const title = node.__title;
|
|
296
|
+
if (title != null) {
|
|
297
|
+
json.title = title;
|
|
298
|
+
}
|
|
299
|
+
const url = node.__url;
|
|
300
|
+
if (url !== undefined && url !== '') {
|
|
301
|
+
json.url = url;
|
|
302
|
+
}
|
|
303
|
+
const direction = node.__dir;
|
|
304
|
+
if (direction != null) {
|
|
305
|
+
json.direction = direction;
|
|
306
|
+
}
|
|
307
|
+
const format = AUTOLINK_FORMAT_GETTER[node.__format];
|
|
308
|
+
if (format !== undefined && format !== '') {
|
|
309
|
+
json.format = format;
|
|
310
|
+
}
|
|
311
|
+
const indent = node.__indent;
|
|
312
|
+
if (indent !== undefined && indent !== 0) {
|
|
313
|
+
json.indent = indent;
|
|
314
|
+
}
|
|
315
|
+
if (
|
|
316
|
+
textFormat !== undefined &&
|
|
317
|
+
textFormat !== 0 &&
|
|
318
|
+
shouldSerializeTextStyles
|
|
319
|
+
) {
|
|
320
|
+
json.textFormat = textFormat;
|
|
321
|
+
}
|
|
322
|
+
if (
|
|
323
|
+
textStyle !== undefined &&
|
|
324
|
+
textStyle !== '' &&
|
|
325
|
+
shouldSerializeTextStyles
|
|
326
|
+
) {
|
|
327
|
+
json.textStyle = textStyle;
|
|
328
|
+
}
|
|
329
|
+
return json;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/** Generated from AutoLinkNode's serialization schema. Do not edit by hand. */
|
|
333
|
+
function updateAutoLinkNode(
|
|
334
|
+
node: AutoLinkNode,
|
|
335
|
+
json: {readonly [key: string]: unknown},
|
|
336
|
+
): AutoLinkNode {
|
|
337
|
+
const direction = json.direction;
|
|
338
|
+
node.__dir =
|
|
339
|
+
direction === null || direction === 'ltr' || direction === 'rtl'
|
|
340
|
+
? direction
|
|
341
|
+
: null;
|
|
342
|
+
const format = json.format;
|
|
343
|
+
node.__format =
|
|
344
|
+
typeof format === 'string' && format in AUTOLINK_FORMAT_SETTER
|
|
345
|
+
? AUTOLINK_FORMAT_SETTER[format]
|
|
346
|
+
: AUTOLINK_FORMAT_SETTER_DEFAULT;
|
|
347
|
+
node.__indent = numC(json.indent, 0, 0, Infinity, true);
|
|
348
|
+
node.__textFormat = num(json.textFormat, 0);
|
|
349
|
+
const textStyle = json.textStyle;
|
|
350
|
+
node.__textStyle = typeof textStyle === 'string' ? textStyle : '';
|
|
351
|
+
const rel = json.rel;
|
|
352
|
+
node.__rel = typeof rel === 'string' && rel !== '' ? rel : null;
|
|
353
|
+
const target = json.target;
|
|
354
|
+
node.__target = typeof target === 'string' && target !== '' ? target : null;
|
|
355
|
+
const title = json.title;
|
|
356
|
+
node.__title = typeof title === 'string' && title !== '' ? title : null;
|
|
357
|
+
const url = json.url;
|
|
358
|
+
node.__url = typeof url === 'string' ? url : '';
|
|
359
|
+
const isUnlinked = json.isUnlinked;
|
|
360
|
+
node.__isUnlinked = typeof isUnlinked === 'boolean' ? isUnlinked : false;
|
|
361
|
+
return node;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return {
|
|
365
|
+
exportJSON: exportAutoLinkNode,
|
|
366
|
+
exportCompactJSON: exportCompactAutoLinkNode,
|
|
367
|
+
updateFromJSON: updateAutoLinkNode,
|
|
368
|
+
afterCloneFrom: afterCloneAutoLinkNode,
|
|
369
|
+
};
|
|
370
|
+
};
|
package/src/LexicalLinkNode.ts
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
$setSelection,
|
|
28
28
|
addClassNamesToElement,
|
|
29
29
|
type BaseSelection,
|
|
30
|
+
booleanValue,
|
|
30
31
|
createCommand,
|
|
31
32
|
type DOMConversionOutput,
|
|
32
33
|
type EditorConfig,
|
|
@@ -34,16 +35,23 @@ import {
|
|
|
34
35
|
isHTMLAnchorElement,
|
|
35
36
|
type LexicalCommand,
|
|
36
37
|
type LexicalNode,
|
|
37
|
-
type
|
|
38
|
+
type LexicalParseJSON,
|
|
38
39
|
type NodeKey,
|
|
40
|
+
nodeSchema,
|
|
41
|
+
nullable,
|
|
39
42
|
type Point,
|
|
40
43
|
type PointCaret,
|
|
41
44
|
type PointType,
|
|
42
45
|
type RangeSelection,
|
|
43
46
|
type SerializedElementNode,
|
|
47
|
+
type SerializedPartial,
|
|
44
48
|
type Spread,
|
|
49
|
+
stringValue,
|
|
50
|
+
withField,
|
|
45
51
|
} from 'lexical';
|
|
46
52
|
|
|
53
|
+
import {GENERATED_AUTOLINK, GENERATED_LINK} from './LexicalLinkGeneratedJSON';
|
|
54
|
+
|
|
47
55
|
export type LinkAttributes = {
|
|
48
56
|
rel?: null | string;
|
|
49
57
|
target?: null | string;
|
|
@@ -71,7 +79,38 @@ const SUPPORTED_URL_PROTOCOLS = new Set([
|
|
|
71
79
|
'tel:',
|
|
72
80
|
]);
|
|
73
81
|
|
|
82
|
+
const linkNodeSchema = nodeSchema<LinkNode>()({
|
|
83
|
+
// defaultAsNull preserves the legacy `value || null` semantics: an empty
|
|
84
|
+
// string (or junk that coerces to it) imports as null, not ''.
|
|
85
|
+
// Every property *is* its node field in both directions — each accessor is
|
|
86
|
+
// a bare read or write — so each is declared as the field it is. Only `url`
|
|
87
|
+
// names its accessors, because getURL/setURL are not the conventional
|
|
88
|
+
// getUrl/setUrl the others are resolved to.
|
|
89
|
+
rel: withField(nullable(stringValue(), {defaultAsNull: true}), {
|
|
90
|
+
field: '__rel',
|
|
91
|
+
}),
|
|
92
|
+
target: withField(nullable(stringValue(), {defaultAsNull: true}), {
|
|
93
|
+
field: '__target',
|
|
94
|
+
}),
|
|
95
|
+
title: withField(nullable(stringValue(), {defaultAsNull: true}), {
|
|
96
|
+
field: '__title',
|
|
97
|
+
}),
|
|
98
|
+
url: withField(stringValue(), {
|
|
99
|
+
field: '__url',
|
|
100
|
+
getter: 'getURL',
|
|
101
|
+
setter: 'setURL',
|
|
102
|
+
}),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
106
|
+
export interface LinkNode {
|
|
107
|
+
exportJSON(compact?: false): SerializedLinkNode;
|
|
108
|
+
exportJSON(compact: boolean): SerializedPartial<SerializedLinkNode>;
|
|
109
|
+
updateFromJSON(serializedNode: LexicalParseJSON<SerializedLinkNode>): this;
|
|
110
|
+
}
|
|
111
|
+
|
|
74
112
|
/** @noInheritDoc */
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
75
114
|
export class LinkNode extends ElementNode {
|
|
76
115
|
/** @internal */
|
|
77
116
|
__url: string;
|
|
@@ -85,12 +124,14 @@ export class LinkNode extends ElementNode {
|
|
|
85
124
|
$config() {
|
|
86
125
|
return this.config('link', {
|
|
87
126
|
extends: ElementNode,
|
|
127
|
+
generated: GENERATED_LINK,
|
|
88
128
|
importDOM: {
|
|
89
129
|
a: () => ({
|
|
90
130
|
conversion: $convertAnchorElement,
|
|
91
131
|
priority: 1,
|
|
92
132
|
}),
|
|
93
133
|
},
|
|
134
|
+
json: linkNodeSchema,
|
|
94
135
|
});
|
|
95
136
|
}
|
|
96
137
|
|
|
@@ -107,14 +148,6 @@ export class LinkNode extends ElementNode {
|
|
|
107
148
|
this.__title = title;
|
|
108
149
|
}
|
|
109
150
|
|
|
110
|
-
afterCloneFrom(prevNode: this): void {
|
|
111
|
-
super.afterCloneFrom(prevNode);
|
|
112
|
-
this.__url = prevNode.__url;
|
|
113
|
-
this.__rel = prevNode.__rel;
|
|
114
|
-
this.__target = prevNode.__target;
|
|
115
|
-
this.__title = prevNode.__title;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
151
|
createDOM(config: EditorConfig): LinkHTMLElementType {
|
|
119
152
|
const element = $getDocument().createElement('a');
|
|
120
153
|
this.updateLinkDOM(null, element, config);
|
|
@@ -154,15 +187,6 @@ export class LinkNode extends ElementNode {
|
|
|
154
187
|
return false;
|
|
155
188
|
}
|
|
156
189
|
|
|
157
|
-
updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedLinkNode>): this {
|
|
158
|
-
return super
|
|
159
|
-
.updateFromJSON(serializedNode)
|
|
160
|
-
.setURL(serializedNode.url)
|
|
161
|
-
.setRel(serializedNode.rel || null)
|
|
162
|
-
.setTarget(serializedNode.target || null)
|
|
163
|
-
.setTitle(serializedNode.title || null);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
190
|
sanitizeUrl(url: string): string {
|
|
167
191
|
const rawUrl = url;
|
|
168
192
|
url = formatUrl(url);
|
|
@@ -208,16 +232,6 @@ export class LinkNode extends ElementNode {
|
|
|
208
232
|
return url;
|
|
209
233
|
}
|
|
210
234
|
|
|
211
|
-
exportJSON(): SerializedLinkNode | SerializedAutoLinkNode {
|
|
212
|
-
return {
|
|
213
|
-
...super.exportJSON(),
|
|
214
|
-
rel: this.getRel(),
|
|
215
|
-
target: this.getTarget(),
|
|
216
|
-
title: this.getTitle(),
|
|
217
|
-
url: this.getURL(),
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
|
|
221
235
|
getURL(): string {
|
|
222
236
|
return this.getLatest().__url;
|
|
223
237
|
}
|
|
@@ -482,8 +496,28 @@ export type SerializedAutoLinkNode = Spread<
|
|
|
482
496
|
SerializedLinkNode
|
|
483
497
|
>;
|
|
484
498
|
|
|
499
|
+
const autoLinkNodeSchema = nodeSchema<AutoLinkNode>()({
|
|
500
|
+
// The property *is* the field in both directions — both accessors are bare —
|
|
501
|
+
// so it is declared as the field it is. The conventional
|
|
502
|
+
// getIsUnlinked/setIsUnlinked are still deferred to, so a subclass that
|
|
503
|
+
// overrides either still decides.
|
|
504
|
+
isUnlinked: withField(booleanValue(), {
|
|
505
|
+
field: '__isUnlinked',
|
|
506
|
+
}),
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
510
|
+
export interface AutoLinkNode {
|
|
511
|
+
exportJSON(compact?: false): SerializedAutoLinkNode;
|
|
512
|
+
exportJSON(compact: boolean): SerializedPartial<SerializedAutoLinkNode>;
|
|
513
|
+
updateFromJSON(
|
|
514
|
+
serializedNode: LexicalParseJSON<SerializedAutoLinkNode>,
|
|
515
|
+
): this;
|
|
516
|
+
}
|
|
517
|
+
|
|
485
518
|
// Custom node type to override `canInsertTextAfter` that will
|
|
486
519
|
// allow typing within the link
|
|
520
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
487
521
|
export class AutoLinkNode extends LinkNode {
|
|
488
522
|
/** @internal */
|
|
489
523
|
/** Indicates whether the autolink was ever unlinked. **/
|
|
@@ -501,13 +535,12 @@ export class AutoLinkNode extends LinkNode {
|
|
|
501
535
|
: false;
|
|
502
536
|
}
|
|
503
537
|
|
|
504
|
-
afterCloneFrom(prevNode: this): void {
|
|
505
|
-
super.afterCloneFrom(prevNode);
|
|
506
|
-
this.__isUnlinked = prevNode.__isUnlinked;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
538
|
$config() {
|
|
510
|
-
return this.config('autolink', {
|
|
539
|
+
return this.config('autolink', {
|
|
540
|
+
extends: LinkNode,
|
|
541
|
+
generated: GENERATED_AUTOLINK,
|
|
542
|
+
json: autoLinkNodeSchema,
|
|
543
|
+
});
|
|
511
544
|
}
|
|
512
545
|
|
|
513
546
|
shouldMergeAdjacentLink(_otherLink: LinkNode): boolean {
|
|
@@ -543,21 +576,6 @@ export class AutoLinkNode extends LinkNode {
|
|
|
543
576
|
);
|
|
544
577
|
}
|
|
545
578
|
|
|
546
|
-
updateFromJSON(
|
|
547
|
-
serializedNode: LexicalUpdateJSON<SerializedAutoLinkNode>,
|
|
548
|
-
): this {
|
|
549
|
-
return super
|
|
550
|
-
.updateFromJSON(serializedNode)
|
|
551
|
-
.setIsUnlinked(serializedNode.isUnlinked || false);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
exportJSON(): SerializedAutoLinkNode {
|
|
555
|
-
return {
|
|
556
|
-
...super.exportJSON(),
|
|
557
|
-
isUnlinked: this.__isUnlinked,
|
|
558
|
-
};
|
|
559
|
-
}
|
|
560
|
-
|
|
561
579
|
// insertNewAfter is deliberately not overridden: LinkNode's implementation
|
|
562
580
|
// uses $copyNode, which runs clone() + afterCloneFrom() and so carries the
|
|
563
581
|
// element props (format/indent/style/dir/textFormat/textStyle) and NodeState
|