@lexical/link 0.43.1-nightly.20260417.0 → 0.44.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/LexicalAutoLinkExtension.d.ts +9 -3
- package/LexicalLink.dev.js +32 -28
- package/LexicalLink.dev.mjs +32 -28
- package/LexicalLink.js.flow +9 -2
- package/LexicalLink.prod.js +1 -1
- package/LexicalLink.prod.mjs +1 -1
- package/package.json +4 -4
|
@@ -23,11 +23,17 @@ export declare function createLinkMatcherWithRegExp(regExp: RegExp, urlTransform
|
|
|
23
23
|
url: string;
|
|
24
24
|
} | null;
|
|
25
25
|
export interface AutoLinkConfig {
|
|
26
|
-
matchers: LinkMatcher[];
|
|
27
26
|
changeHandlers: ChangeHandler[];
|
|
28
|
-
excludeParents:
|
|
27
|
+
excludeParents: ((parent: ElementNode) => boolean)[];
|
|
28
|
+
matchers: LinkMatcher[];
|
|
29
|
+
/**
|
|
30
|
+
* The regular expression used to determine whether surrounding
|
|
31
|
+
* characters count as separators when validating auto-link
|
|
32
|
+
* boundaries. Defaults to `/[.,;\s]/`.
|
|
33
|
+
*/
|
|
34
|
+
separatorRegex: RegExp;
|
|
29
35
|
}
|
|
30
|
-
export declare function registerAutoLink(editor: LexicalEditor, config?: AutoLinkConfig): () => void;
|
|
36
|
+
export declare function registerAutoLink(editor: LexicalEditor, config?: Partial<AutoLinkConfig> & Omit<AutoLinkConfig, 'separatorRegex'>): () => void;
|
|
31
37
|
/**
|
|
32
38
|
* An extension to automatically create AutoLinkNode from text
|
|
33
39
|
* that matches the configured matchers. No default implementation
|
package/LexicalLink.dev.js
CHANGED
|
@@ -881,7 +881,9 @@ function registerClickableLink(editor, stores, eventOptions = {}) {
|
|
|
881
881
|
}
|
|
882
882
|
|
|
883
883
|
// Allow user to select link text without following url
|
|
884
|
-
const selection = editor.getEditorState().read(lexical.$getSelection
|
|
884
|
+
const selection = editor.getEditorState().read(lexical.$getSelection, {
|
|
885
|
+
editor
|
|
886
|
+
});
|
|
885
887
|
if (lexical.$isRangeSelection(selection) && !selection.isCollapsed()) {
|
|
886
888
|
event.preventDefault();
|
|
887
889
|
return;
|
|
@@ -959,14 +961,14 @@ function findFirstMatch(text, matchers) {
|
|
|
959
961
|
return null;
|
|
960
962
|
}
|
|
961
963
|
const PUNCTUATION_OR_SPACE = /[.,;\s]/;
|
|
962
|
-
function isSeparator(char) {
|
|
963
|
-
return
|
|
964
|
+
function isSeparator(char, separatorRegex) {
|
|
965
|
+
return separatorRegex.test(char);
|
|
964
966
|
}
|
|
965
|
-
function endsWithSeparator(textContent) {
|
|
966
|
-
return isSeparator(textContent[textContent.length - 1]);
|
|
967
|
+
function endsWithSeparator(textContent, separatorRegex) {
|
|
968
|
+
return isSeparator(textContent[textContent.length - 1], separatorRegex);
|
|
967
969
|
}
|
|
968
|
-
function startsWithSeparator(textContent) {
|
|
969
|
-
return isSeparator(textContent[0]);
|
|
970
|
+
function startsWithSeparator(textContent, separatorRegex) {
|
|
971
|
+
return isSeparator(textContent[0], separatorRegex);
|
|
970
972
|
}
|
|
971
973
|
|
|
972
974
|
/**
|
|
@@ -983,26 +985,26 @@ function startsWithTLD(textContent, isEmail) {
|
|
|
983
985
|
return /^\.[a-zA-Z0-9]{1,}/.test(textContent);
|
|
984
986
|
}
|
|
985
987
|
}
|
|
986
|
-
function isPreviousNodeValid(node) {
|
|
988
|
+
function isPreviousNodeValid(node, separatorRegex) {
|
|
987
989
|
let previousNode = node.getPreviousSibling();
|
|
988
990
|
if (lexical.$isElementNode(previousNode)) {
|
|
989
991
|
previousNode = previousNode.getLastDescendant();
|
|
990
992
|
}
|
|
991
|
-
return previousNode === null || lexical.$isLineBreakNode(previousNode) || lexical.$isTextNode(previousNode) && endsWithSeparator(previousNode.getTextContent());
|
|
993
|
+
return previousNode === null || lexical.$isLineBreakNode(previousNode) || lexical.$isTextNode(previousNode) && endsWithSeparator(previousNode.getTextContent(), separatorRegex);
|
|
992
994
|
}
|
|
993
|
-
function isNextNodeValid(node) {
|
|
995
|
+
function isNextNodeValid(node, separatorRegex) {
|
|
994
996
|
let nextNode = node.getNextSibling();
|
|
995
997
|
if (lexical.$isElementNode(nextNode)) {
|
|
996
998
|
nextNode = nextNode.getFirstDescendant();
|
|
997
999
|
}
|
|
998
|
-
return nextNode === null || lexical.$isLineBreakNode(nextNode) || lexical.$isTextNode(nextNode) && startsWithSeparator(nextNode.getTextContent());
|
|
1000
|
+
return nextNode === null || lexical.$isLineBreakNode(nextNode) || lexical.$isTextNode(nextNode) && startsWithSeparator(nextNode.getTextContent(), separatorRegex);
|
|
999
1001
|
}
|
|
1000
|
-
function isContentAroundIsValid(matchStart, matchEnd, text, nodes) {
|
|
1001
|
-
const contentBeforeIsValid = matchStart > 0 ? isSeparator(text[matchStart - 1]) : isPreviousNodeValid(nodes[0]);
|
|
1002
|
+
function isContentAroundIsValid(matchStart, matchEnd, separatorRegex, text, nodes) {
|
|
1003
|
+
const contentBeforeIsValid = matchStart > 0 ? isSeparator(text[matchStart - 1], separatorRegex) : isPreviousNodeValid(nodes[0], separatorRegex);
|
|
1002
1004
|
if (!contentBeforeIsValid) {
|
|
1003
1005
|
return false;
|
|
1004
1006
|
}
|
|
1005
|
-
const contentAfterIsValid = matchEnd < text.length ? isSeparator(text[matchEnd]) : isNextNodeValid(nodes[nodes.length - 1]);
|
|
1007
|
+
const contentAfterIsValid = matchEnd < text.length ? isSeparator(text[matchEnd], separatorRegex) : isNextNodeValid(nodes[nodes.length - 1], separatorRegex);
|
|
1006
1008
|
return contentAfterIsValid;
|
|
1007
1009
|
}
|
|
1008
1010
|
function extractMatchingNodes(nodes, startIndex, endIndex) {
|
|
@@ -1097,7 +1099,7 @@ function $createAutoLinkNode_(nodes, startIndex, endIndex, match) {
|
|
|
1097
1099
|
}
|
|
1098
1100
|
return undefined;
|
|
1099
1101
|
}
|
|
1100
|
-
function $handleLinkCreation(nodes, matchers, onChange) {
|
|
1102
|
+
function $handleLinkCreation(nodes, matchers, onChange, separatorRegex) {
|
|
1101
1103
|
// Early return if any node is already part of an AutoLinkNode (idempotency check)
|
|
1102
1104
|
for (const node of nodes) {
|
|
1103
1105
|
const parent = node.getParent();
|
|
@@ -1114,7 +1116,7 @@ function $handleLinkCreation(nodes, matchers, onChange) {
|
|
|
1114
1116
|
const matchStart = match.index;
|
|
1115
1117
|
const matchLength = match.length;
|
|
1116
1118
|
const matchEnd = matchStart + matchLength;
|
|
1117
|
-
const isValid = isContentAroundIsValid(invalidMatchEnd + matchStart, invalidMatchEnd + matchEnd, initialText, currentNodes);
|
|
1119
|
+
const isValid = isContentAroundIsValid(invalidMatchEnd + matchStart, invalidMatchEnd + matchEnd, separatorRegex, initialText, currentNodes);
|
|
1118
1120
|
if (isValid) {
|
|
1119
1121
|
const [matchingOffset,, matchingNodes, unmodifiedAfterNodes] = extractMatchingNodes(currentNodes, invalidMatchEnd + matchStart, invalidMatchEnd + matchEnd);
|
|
1120
1122
|
|
|
@@ -1144,7 +1146,7 @@ function $handleLinkCreation(nodes, matchers, onChange) {
|
|
|
1144
1146
|
text = text.substring(matchEnd);
|
|
1145
1147
|
}
|
|
1146
1148
|
}
|
|
1147
|
-
function handleLinkEdit(linkNode, matchers, onChange) {
|
|
1149
|
+
function handleLinkEdit(linkNode, matchers, onChange, separatorRegex) {
|
|
1148
1150
|
// Check children are simple text
|
|
1149
1151
|
const children = linkNode.getChildren();
|
|
1150
1152
|
const childrenLength = children.length;
|
|
@@ -1167,7 +1169,7 @@ function handleLinkEdit(linkNode, matchers, onChange) {
|
|
|
1167
1169
|
}
|
|
1168
1170
|
|
|
1169
1171
|
// Check neighbors
|
|
1170
|
-
if (!isPreviousNodeValid(linkNode) || !isNextNodeValid(linkNode)) {
|
|
1172
|
+
if (!isPreviousNodeValid(linkNode, separatorRegex) || !isNextNodeValid(linkNode, separatorRegex)) {
|
|
1171
1173
|
replaceWithChildren(linkNode);
|
|
1172
1174
|
onChange(null, linkNode.getURL());
|
|
1173
1175
|
return;
|
|
@@ -1193,7 +1195,7 @@ function handleLinkEdit(linkNode, matchers, onChange) {
|
|
|
1193
1195
|
|
|
1194
1196
|
// Bad neighbors are edits in neighbor nodes that make AutoLinks incompatible.
|
|
1195
1197
|
// Given the creation preconditions, these can only be simple text nodes.
|
|
1196
|
-
function handleBadNeighbors(textNode, matchers, onChange) {
|
|
1198
|
+
function handleBadNeighbors(textNode, matchers, onChange, separatorRegex) {
|
|
1197
1199
|
const parent = textNode.getParent();
|
|
1198
1200
|
const previousSibling = textNode.getPreviousSibling();
|
|
1199
1201
|
const nextSibling = textNode.getNextSibling();
|
|
@@ -1212,7 +1214,7 @@ function handleBadNeighbors(textNode, matchers, onChange) {
|
|
|
1212
1214
|
if (previousSibling.is(textNode.getPreviousSibling()) && textNode.getParent() === previousSibling.getParent()) {
|
|
1213
1215
|
// If text doesn't start with separator, link should be unwrapped
|
|
1214
1216
|
// because non-separator after link makes the boundary invalid
|
|
1215
|
-
if (!startsWithSeparator(text)) {
|
|
1217
|
+
if (!startsWithSeparator(text, separatorRegex)) {
|
|
1216
1218
|
// Non-separator after link - unwrap the link
|
|
1217
1219
|
replaceWithChildren(previousSibling);
|
|
1218
1220
|
onChange(null, previousSibling.getURL());
|
|
@@ -1226,7 +1228,7 @@ function handleBadNeighbors(textNode, matchers, onChange) {
|
|
|
1226
1228
|
const match = findFirstMatch(combinedText, matchers);
|
|
1227
1229
|
if (match !== null && match.text === combinedText) {
|
|
1228
1230
|
previousSibling.append(textNode);
|
|
1229
|
-
handleLinkEdit(previousSibling, matchers, onChange);
|
|
1231
|
+
handleLinkEdit(previousSibling, matchers, onChange, separatorRegex);
|
|
1230
1232
|
onChange(null, previousSibling.getURL());
|
|
1231
1233
|
}
|
|
1232
1234
|
}
|
|
@@ -1235,7 +1237,7 @@ function handleBadNeighbors(textNode, matchers, onChange) {
|
|
|
1235
1237
|
}
|
|
1236
1238
|
|
|
1237
1239
|
// Handle case: textNode added BEFORE a link, making link invalid
|
|
1238
|
-
if ($isAutoLinkNode(nextSibling) && !nextSibling.getIsUnlinked() && !endsWithSeparator(text)) {
|
|
1240
|
+
if ($isAutoLinkNode(nextSibling) && !nextSibling.getIsUnlinked() && !endsWithSeparator(text, separatorRegex)) {
|
|
1239
1241
|
// Check if the nextSibling is still a sibling (hasn't been moved) to prevent loops
|
|
1240
1242
|
if (nextSibling.is(textNode.getNextSibling()) && textNode.getParent() === nextSibling.getParent()) {
|
|
1241
1243
|
replaceWithChildren(nextSibling);
|
|
@@ -1268,13 +1270,15 @@ function getTextNodesToMatch(textNode) {
|
|
|
1268
1270
|
const defaultConfig = {
|
|
1269
1271
|
changeHandlers: [],
|
|
1270
1272
|
excludeParents: [],
|
|
1271
|
-
matchers: []
|
|
1273
|
+
matchers: [],
|
|
1274
|
+
separatorRegex: PUNCTUATION_OR_SPACE
|
|
1272
1275
|
};
|
|
1273
1276
|
function registerAutoLink(editor, config = defaultConfig) {
|
|
1274
1277
|
const {
|
|
1275
1278
|
matchers,
|
|
1276
1279
|
changeHandlers,
|
|
1277
|
-
excludeParents
|
|
1280
|
+
excludeParents,
|
|
1281
|
+
separatorRegex = PUNCTUATION_OR_SPACE
|
|
1278
1282
|
} = config;
|
|
1279
1283
|
const onChange = (url, prevUrl) => {
|
|
1280
1284
|
for (const handler of changeHandlers) {
|
|
@@ -1285,13 +1289,13 @@ function registerAutoLink(editor, config = defaultConfig) {
|
|
|
1285
1289
|
const parent = textNode.getParentOrThrow();
|
|
1286
1290
|
const previous = textNode.getPreviousSibling();
|
|
1287
1291
|
if ($isAutoLinkNode(parent)) {
|
|
1288
|
-
handleLinkEdit(parent, matchers, onChange);
|
|
1292
|
+
handleLinkEdit(parent, matchers, onChange, separatorRegex);
|
|
1289
1293
|
} else if (!$isLinkNode(parent) && !excludeParents.some(pred => pred(parent))) {
|
|
1290
|
-
if (textNode.isSimpleText() && (startsWithSeparator(textNode.getTextContent()) || !$isAutoLinkNode(previous))) {
|
|
1294
|
+
if (textNode.isSimpleText() && (startsWithSeparator(textNode.getTextContent(), separatorRegex) || !$isAutoLinkNode(previous))) {
|
|
1291
1295
|
const textNodesToMatch = getTextNodesToMatch(textNode);
|
|
1292
|
-
$handleLinkCreation(textNodesToMatch, matchers, onChange);
|
|
1296
|
+
$handleLinkCreation(textNodesToMatch, matchers, onChange, separatorRegex);
|
|
1293
1297
|
}
|
|
1294
|
-
handleBadNeighbors(textNode, matchers, onChange);
|
|
1298
|
+
handleBadNeighbors(textNode, matchers, onChange, separatorRegex);
|
|
1295
1299
|
}
|
|
1296
1300
|
}), editor.registerCommand(TOGGLE_LINK_COMMAND, payload => {
|
|
1297
1301
|
const selection = lexical.$getSelection();
|
package/LexicalLink.dev.mjs
CHANGED
|
@@ -879,7 +879,9 @@ function registerClickableLink(editor, stores, eventOptions = {}) {
|
|
|
879
879
|
}
|
|
880
880
|
|
|
881
881
|
// Allow user to select link text without following url
|
|
882
|
-
const selection = editor.getEditorState().read($getSelection
|
|
882
|
+
const selection = editor.getEditorState().read($getSelection, {
|
|
883
|
+
editor
|
|
884
|
+
});
|
|
883
885
|
if ($isRangeSelection(selection) && !selection.isCollapsed()) {
|
|
884
886
|
event.preventDefault();
|
|
885
887
|
return;
|
|
@@ -957,14 +959,14 @@ function findFirstMatch(text, matchers) {
|
|
|
957
959
|
return null;
|
|
958
960
|
}
|
|
959
961
|
const PUNCTUATION_OR_SPACE = /[.,;\s]/;
|
|
960
|
-
function isSeparator(char) {
|
|
961
|
-
return
|
|
962
|
+
function isSeparator(char, separatorRegex) {
|
|
963
|
+
return separatorRegex.test(char);
|
|
962
964
|
}
|
|
963
|
-
function endsWithSeparator(textContent) {
|
|
964
|
-
return isSeparator(textContent[textContent.length - 1]);
|
|
965
|
+
function endsWithSeparator(textContent, separatorRegex) {
|
|
966
|
+
return isSeparator(textContent[textContent.length - 1], separatorRegex);
|
|
965
967
|
}
|
|
966
|
-
function startsWithSeparator(textContent) {
|
|
967
|
-
return isSeparator(textContent[0]);
|
|
968
|
+
function startsWithSeparator(textContent, separatorRegex) {
|
|
969
|
+
return isSeparator(textContent[0], separatorRegex);
|
|
968
970
|
}
|
|
969
971
|
|
|
970
972
|
/**
|
|
@@ -981,26 +983,26 @@ function startsWithTLD(textContent, isEmail) {
|
|
|
981
983
|
return /^\.[a-zA-Z0-9]{1,}/.test(textContent);
|
|
982
984
|
}
|
|
983
985
|
}
|
|
984
|
-
function isPreviousNodeValid(node) {
|
|
986
|
+
function isPreviousNodeValid(node, separatorRegex) {
|
|
985
987
|
let previousNode = node.getPreviousSibling();
|
|
986
988
|
if ($isElementNode(previousNode)) {
|
|
987
989
|
previousNode = previousNode.getLastDescendant();
|
|
988
990
|
}
|
|
989
|
-
return previousNode === null || $isLineBreakNode(previousNode) || $isTextNode(previousNode) && endsWithSeparator(previousNode.getTextContent());
|
|
991
|
+
return previousNode === null || $isLineBreakNode(previousNode) || $isTextNode(previousNode) && endsWithSeparator(previousNode.getTextContent(), separatorRegex);
|
|
990
992
|
}
|
|
991
|
-
function isNextNodeValid(node) {
|
|
993
|
+
function isNextNodeValid(node, separatorRegex) {
|
|
992
994
|
let nextNode = node.getNextSibling();
|
|
993
995
|
if ($isElementNode(nextNode)) {
|
|
994
996
|
nextNode = nextNode.getFirstDescendant();
|
|
995
997
|
}
|
|
996
|
-
return nextNode === null || $isLineBreakNode(nextNode) || $isTextNode(nextNode) && startsWithSeparator(nextNode.getTextContent());
|
|
998
|
+
return nextNode === null || $isLineBreakNode(nextNode) || $isTextNode(nextNode) && startsWithSeparator(nextNode.getTextContent(), separatorRegex);
|
|
997
999
|
}
|
|
998
|
-
function isContentAroundIsValid(matchStart, matchEnd, text, nodes) {
|
|
999
|
-
const contentBeforeIsValid = matchStart > 0 ? isSeparator(text[matchStart - 1]) : isPreviousNodeValid(nodes[0]);
|
|
1000
|
+
function isContentAroundIsValid(matchStart, matchEnd, separatorRegex, text, nodes) {
|
|
1001
|
+
const contentBeforeIsValid = matchStart > 0 ? isSeparator(text[matchStart - 1], separatorRegex) : isPreviousNodeValid(nodes[0], separatorRegex);
|
|
1000
1002
|
if (!contentBeforeIsValid) {
|
|
1001
1003
|
return false;
|
|
1002
1004
|
}
|
|
1003
|
-
const contentAfterIsValid = matchEnd < text.length ? isSeparator(text[matchEnd]) : isNextNodeValid(nodes[nodes.length - 1]);
|
|
1005
|
+
const contentAfterIsValid = matchEnd < text.length ? isSeparator(text[matchEnd], separatorRegex) : isNextNodeValid(nodes[nodes.length - 1], separatorRegex);
|
|
1004
1006
|
return contentAfterIsValid;
|
|
1005
1007
|
}
|
|
1006
1008
|
function extractMatchingNodes(nodes, startIndex, endIndex) {
|
|
@@ -1095,7 +1097,7 @@ function $createAutoLinkNode_(nodes, startIndex, endIndex, match) {
|
|
|
1095
1097
|
}
|
|
1096
1098
|
return undefined;
|
|
1097
1099
|
}
|
|
1098
|
-
function $handleLinkCreation(nodes, matchers, onChange) {
|
|
1100
|
+
function $handleLinkCreation(nodes, matchers, onChange, separatorRegex) {
|
|
1099
1101
|
// Early return if any node is already part of an AutoLinkNode (idempotency check)
|
|
1100
1102
|
for (const node of nodes) {
|
|
1101
1103
|
const parent = node.getParent();
|
|
@@ -1112,7 +1114,7 @@ function $handleLinkCreation(nodes, matchers, onChange) {
|
|
|
1112
1114
|
const matchStart = match.index;
|
|
1113
1115
|
const matchLength = match.length;
|
|
1114
1116
|
const matchEnd = matchStart + matchLength;
|
|
1115
|
-
const isValid = isContentAroundIsValid(invalidMatchEnd + matchStart, invalidMatchEnd + matchEnd, initialText, currentNodes);
|
|
1117
|
+
const isValid = isContentAroundIsValid(invalidMatchEnd + matchStart, invalidMatchEnd + matchEnd, separatorRegex, initialText, currentNodes);
|
|
1116
1118
|
if (isValid) {
|
|
1117
1119
|
const [matchingOffset,, matchingNodes, unmodifiedAfterNodes] = extractMatchingNodes(currentNodes, invalidMatchEnd + matchStart, invalidMatchEnd + matchEnd);
|
|
1118
1120
|
|
|
@@ -1142,7 +1144,7 @@ function $handleLinkCreation(nodes, matchers, onChange) {
|
|
|
1142
1144
|
text = text.substring(matchEnd);
|
|
1143
1145
|
}
|
|
1144
1146
|
}
|
|
1145
|
-
function handleLinkEdit(linkNode, matchers, onChange) {
|
|
1147
|
+
function handleLinkEdit(linkNode, matchers, onChange, separatorRegex) {
|
|
1146
1148
|
// Check children are simple text
|
|
1147
1149
|
const children = linkNode.getChildren();
|
|
1148
1150
|
const childrenLength = children.length;
|
|
@@ -1165,7 +1167,7 @@ function handleLinkEdit(linkNode, matchers, onChange) {
|
|
|
1165
1167
|
}
|
|
1166
1168
|
|
|
1167
1169
|
// Check neighbors
|
|
1168
|
-
if (!isPreviousNodeValid(linkNode) || !isNextNodeValid(linkNode)) {
|
|
1170
|
+
if (!isPreviousNodeValid(linkNode, separatorRegex) || !isNextNodeValid(linkNode, separatorRegex)) {
|
|
1169
1171
|
replaceWithChildren(linkNode);
|
|
1170
1172
|
onChange(null, linkNode.getURL());
|
|
1171
1173
|
return;
|
|
@@ -1191,7 +1193,7 @@ function handleLinkEdit(linkNode, matchers, onChange) {
|
|
|
1191
1193
|
|
|
1192
1194
|
// Bad neighbors are edits in neighbor nodes that make AutoLinks incompatible.
|
|
1193
1195
|
// Given the creation preconditions, these can only be simple text nodes.
|
|
1194
|
-
function handleBadNeighbors(textNode, matchers, onChange) {
|
|
1196
|
+
function handleBadNeighbors(textNode, matchers, onChange, separatorRegex) {
|
|
1195
1197
|
const parent = textNode.getParent();
|
|
1196
1198
|
const previousSibling = textNode.getPreviousSibling();
|
|
1197
1199
|
const nextSibling = textNode.getNextSibling();
|
|
@@ -1210,7 +1212,7 @@ function handleBadNeighbors(textNode, matchers, onChange) {
|
|
|
1210
1212
|
if (previousSibling.is(textNode.getPreviousSibling()) && textNode.getParent() === previousSibling.getParent()) {
|
|
1211
1213
|
// If text doesn't start with separator, link should be unwrapped
|
|
1212
1214
|
// because non-separator after link makes the boundary invalid
|
|
1213
|
-
if (!startsWithSeparator(text)) {
|
|
1215
|
+
if (!startsWithSeparator(text, separatorRegex)) {
|
|
1214
1216
|
// Non-separator after link - unwrap the link
|
|
1215
1217
|
replaceWithChildren(previousSibling);
|
|
1216
1218
|
onChange(null, previousSibling.getURL());
|
|
@@ -1224,7 +1226,7 @@ function handleBadNeighbors(textNode, matchers, onChange) {
|
|
|
1224
1226
|
const match = findFirstMatch(combinedText, matchers);
|
|
1225
1227
|
if (match !== null && match.text === combinedText) {
|
|
1226
1228
|
previousSibling.append(textNode);
|
|
1227
|
-
handleLinkEdit(previousSibling, matchers, onChange);
|
|
1229
|
+
handleLinkEdit(previousSibling, matchers, onChange, separatorRegex);
|
|
1228
1230
|
onChange(null, previousSibling.getURL());
|
|
1229
1231
|
}
|
|
1230
1232
|
}
|
|
@@ -1233,7 +1235,7 @@ function handleBadNeighbors(textNode, matchers, onChange) {
|
|
|
1233
1235
|
}
|
|
1234
1236
|
|
|
1235
1237
|
// Handle case: textNode added BEFORE a link, making link invalid
|
|
1236
|
-
if ($isAutoLinkNode(nextSibling) && !nextSibling.getIsUnlinked() && !endsWithSeparator(text)) {
|
|
1238
|
+
if ($isAutoLinkNode(nextSibling) && !nextSibling.getIsUnlinked() && !endsWithSeparator(text, separatorRegex)) {
|
|
1237
1239
|
// Check if the nextSibling is still a sibling (hasn't been moved) to prevent loops
|
|
1238
1240
|
if (nextSibling.is(textNode.getNextSibling()) && textNode.getParent() === nextSibling.getParent()) {
|
|
1239
1241
|
replaceWithChildren(nextSibling);
|
|
@@ -1266,13 +1268,15 @@ function getTextNodesToMatch(textNode) {
|
|
|
1266
1268
|
const defaultConfig = {
|
|
1267
1269
|
changeHandlers: [],
|
|
1268
1270
|
excludeParents: [],
|
|
1269
|
-
matchers: []
|
|
1271
|
+
matchers: [],
|
|
1272
|
+
separatorRegex: PUNCTUATION_OR_SPACE
|
|
1270
1273
|
};
|
|
1271
1274
|
function registerAutoLink(editor, config = defaultConfig) {
|
|
1272
1275
|
const {
|
|
1273
1276
|
matchers,
|
|
1274
1277
|
changeHandlers,
|
|
1275
|
-
excludeParents
|
|
1278
|
+
excludeParents,
|
|
1279
|
+
separatorRegex = PUNCTUATION_OR_SPACE
|
|
1276
1280
|
} = config;
|
|
1277
1281
|
const onChange = (url, prevUrl) => {
|
|
1278
1282
|
for (const handler of changeHandlers) {
|
|
@@ -1283,13 +1287,13 @@ function registerAutoLink(editor, config = defaultConfig) {
|
|
|
1283
1287
|
const parent = textNode.getParentOrThrow();
|
|
1284
1288
|
const previous = textNode.getPreviousSibling();
|
|
1285
1289
|
if ($isAutoLinkNode(parent)) {
|
|
1286
|
-
handleLinkEdit(parent, matchers, onChange);
|
|
1290
|
+
handleLinkEdit(parent, matchers, onChange, separatorRegex);
|
|
1287
1291
|
} else if (!$isLinkNode(parent) && !excludeParents.some(pred => pred(parent))) {
|
|
1288
|
-
if (textNode.isSimpleText() && (startsWithSeparator(textNode.getTextContent()) || !$isAutoLinkNode(previous))) {
|
|
1292
|
+
if (textNode.isSimpleText() && (startsWithSeparator(textNode.getTextContent(), separatorRegex) || !$isAutoLinkNode(previous))) {
|
|
1289
1293
|
const textNodesToMatch = getTextNodesToMatch(textNode);
|
|
1290
|
-
$handleLinkCreation(textNodesToMatch, matchers, onChange);
|
|
1294
|
+
$handleLinkCreation(textNodesToMatch, matchers, onChange, separatorRegex);
|
|
1291
1295
|
}
|
|
1292
|
-
handleBadNeighbors(textNode, matchers, onChange);
|
|
1296
|
+
handleBadNeighbors(textNode, matchers, onChange, separatorRegex);
|
|
1293
1297
|
}
|
|
1294
1298
|
}), editor.registerCommand(TOGGLE_LINK_COMMAND, payload => {
|
|
1295
1299
|
const selection = $getSelection();
|
package/LexicalLink.js.flow
CHANGED
|
@@ -122,8 +122,10 @@ declare export function registerClickableLink(
|
|
|
122
122
|
): () => void;
|
|
123
123
|
|
|
124
124
|
export type AutoLinkConfig = {
|
|
125
|
-
matchers: LinkMatcher[];
|
|
126
125
|
changeHandlers: ChangeHandler[];
|
|
126
|
+
excludeParents: ((parent: ElementNode) => boolean)[];
|
|
127
|
+
matchers: LinkMatcher[];
|
|
128
|
+
separatorRegex: RegExp;
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
export type ChangeHandler = (
|
|
@@ -154,7 +156,12 @@ declare export var AutoLinkExtension: LexicalExtension<AutoLinkConfig, "@lexical
|
|
|
154
156
|
|
|
155
157
|
declare export function registerAutoLink(
|
|
156
158
|
editor: LexicalEditor,
|
|
157
|
-
config?:
|
|
159
|
+
config?: {
|
|
160
|
+
changeHandlers: ChangeHandler[];
|
|
161
|
+
excludeParents: ((parent: ElementNode) => boolean)[];
|
|
162
|
+
matchers: LinkMatcher[];
|
|
163
|
+
separatorRegex?: RegExp;
|
|
164
|
+
},
|
|
158
165
|
): () => void;
|
|
159
166
|
|
|
160
167
|
export type LinkConfig = {
|
package/LexicalLink.prod.js
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
"use strict";var e=require("@lexical/utils"),t=require("lexical"),n=require("@lexical/extension");const r=new Set(["http:","https:","mailto:","sms:","tel:"]);class i extends t.ElementNode{__url;__target;__rel;__title;static getType(){return"link"}static clone(e){return new i(e.__url,{rel:e.__rel,target:e.__target,title:e.__title},e.__key)}constructor(e="",t={},n){super(n);const{target:r=null,rel:i=null,title:s=null}=t;this.__url=e,this.__target=r,this.__rel=i,this.__title=s}afterCloneFrom(e){super.afterCloneFrom(e),this.__url=e.__url,this.__rel=e.__rel,this.__target=e.__target,this.__title=e.__title}createDOM(t){const n=document.createElement("a");return this.updateLinkDOM(null,n,t),e.addClassNamesToElement(n,t.theme.link),n}updateLinkDOM(t,n,r){if(e.isHTMLAnchorElement(n)){t&&t.__url===this.__url||(n.href=this.sanitizeUrl(this.__url));for(const e of["target","rel","title"]){const r=`__${e}`,i=this[r];t&&t[r]===i||(i?n[e]=i:n.removeAttribute(e))}}}updateDOM(e,t,n){return this.updateLinkDOM(e,t,n),!1}static importDOM(){return{a:e=>({conversion:a,priority:1})}}static importJSON(e){return u().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setURL(e.url).setRel(e.rel||null).setTarget(e.target||null).setTitle(e.title||null)}sanitizeUrl(e){e=x(e);try{const t=new URL(x(e));if(!r.has(t.protocol))return"about:blank"}catch(t){return e}return e}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),url:this.getURL()}}getURL(){return this.getLatest().__url}setURL(e){const t=this.getWritable();return t.__url=e,t}getTarget(){return this.getLatest().__target}setTarget(e){const t=this.getWritable();return t.__target=e,t}getRel(){return this.getLatest().__rel}setRel(e){const t=this.getWritable();return t.__rel=e,t}getTitle(){return this.getLatest().__title}setTitle(e){const t=this.getWritable();return t.__title=e,t}insertNewAfter(e,n=!0){const r=t.$copyNode(this);return this.insertAfter(r,n),r}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(e,n,r){if(!t.$isRangeSelection(n))return!1;const i=n.anchor.getNode(),s=n.focus.getNode();return this.isParentOf(i)&&this.isParentOf(s)&&n.getTextContent().length>0}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")||this.__url.startsWith("http://")}shouldMergeAdjacentLink(e){return this.getType()===e.getType()&&this.__url===e.__url&&this.__target===e.__target&&this.__rel===e.__rel&&this.__title===e.__title}}function s(e){const n=t.$caretFromPoint(e,"next");return[n,n.getFlipped()]}function o(e,n){for(const r of n)if(r.origin.isAttached()){const n=t.$normalizeCaret(r);return void t.$setPointFromCaret(e,n)}}function l(n){const r=t.$getSelection();let i=null,l=null;function a(){t.$isRangeSelection(r)&&(o(r.anchor,i),o(r.focus,l),t.$normalizeSelection__EXPERIMENTAL(r))}t.$isRangeSelection(r)&&(i=s(r.anchor),l=s(r.focus));let u=!1;for(const r of t.$getChildCaret(n,"next")){const i=r.origin;if(t.$isElementNode(i)&&!i.isInline()){const s=i.getChildren();if(s.length>0){const e=t.$copyNode(n);e.append(...s),i.append(e),u=!0}e.$insertNodeToNearestRootAtCaret(i,t.$rewindSiblingCaret(r),{$shouldSplit:()=>!1})}}function g(e,n,r){const[i,s]=e,o=e=>t.$isSiblingCaret(e)&&e.origin.is(n);if(!o(i)&&!o(s))return e;const l=t.$normalizeCaret(t.$getChildCaret(r,"next"));return[l,l.getFlipped()]}if(n.isAttached()){const e=n.getPreviousSibling();if(c(e)&&e.shouldMergeAdjacentLink(n))return i&&(i=g(i,e,n)),l&&(l=g(l,e,n)),e.append(...n.getChildren()),n.remove(),void a();const t=n.getNextSibling();c(t)&&n.shouldMergeAdjacentLink(t)&&(i&&(i=g(i,n,t)),l&&(l=g(l,n,t)),n.append(...t.getChildren()),t.remove(),u=!0)}if(u){if(!n.canBeEmpty()&&n.isEmpty()){const e=n.getParent();n.remove(),e&&e.isEmpty()&&e.remove()}a()}}function a(t){let n=null;if(e.isHTMLAnchorElement(t)){const e=t.textContent;(null!==e&&""!==e||t.children.length>0)&&(n=u(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}))}return{node:n}}function u(e="",n){return t.$applyNodeReplacement(new i(e,n))}function c(e){return e instanceof i}class g extends i{__isUnlinked;constructor(e="",t={},n){super(e,t,n),this.__isUnlinked=void 0!==t.isUnlinked&&null!==t.isUnlinked&&t.isUnlinked}afterCloneFrom(e){super.afterCloneFrom(e),this.__isUnlinked=e.__isUnlinked}static getType(){return"autolink"}static clone(e){return new g(e.__url,{isUnlinked:e.__isUnlinked,rel:e.__rel,target:e.__target,title:e.__title},e.__key)}shouldMergeAdjacentLink(e){return!1}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(e){const t=this.getWritable();return t.__isUnlinked=e,t}createDOM(e){return this.__isUnlinked?document.createElement("span"):super.createDOM(e)}updateDOM(e,t,n){return super.updateDOM(e,t,n)||e.__isUnlinked!==this.__isUnlinked}static importJSON(e){return d().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setIsUnlinked(e.isUnlinked||!1)}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked}}insertNewAfter(e,t=!0){const n=d(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(n,t),n}}function d(e="",n){return t.$applyNodeReplacement(new g(e,n))}function f(e){return e instanceof g}const h=t.createCommand("TOGGLE_LINK_COMMAND");function p(e,n){if("element"===e.type){const r=e.getNode();t.$isElementNode(r)||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(252);return r.getChildren()[e.offset+n]||null}return null}function _(n,r={}){let i;if(n&&"object"==typeof n){const{url:e,...t}=n;i=e,r={...t,...r}}else i=n;const{target:s,title:o}=r,l=void 0===r.rel?"noreferrer":r.rel,a=t.$getSelection();if(null===a||!t.$isRangeSelection(a)&&!t.$isNodeSelection(a))return;if(t.$isNodeSelection(a)){const t=a.getNodes();if(0===t.length)return;return void t.forEach(t=>{if(null===i){const n=e.$findMatchingParent(t,e=>!f(e)&&c(e));n&&(n.insertBefore(t),0===n.getChildren().length&&n.remove())}else{const n=e.$findMatchingParent(t,e=>!f(e)&&c(e));if(n)n.setURL(i),void 0!==s&&n.setTarget(s),void 0!==l&&n.setRel(l);else{const e=u(i,{rel:l,target:s});t.insertBefore(e),e.append(t)}}})}if(a.isCollapsed()&&null===i)for(const t of a.getNodes()){const n=e.$findMatchingParent(t,e=>!f(e)&&c(e));return void(null!==n&&(n.getChildren().forEach(e=>{n.insertBefore(e)}),n.remove()))}const g=a.extract();if(null===i){const n=new Set;return void g.forEach(r=>{const i=e.$findMatchingParent(r,e=>!f(e)&&c(e));if(null!==i){const e=i.getKey();if(n.has(e))return;!function(e,n){const r=new Set(n.filter(t=>e.isParentOf(t)).map(e=>e.getKey())),i=e.getChildren(),s=i=>r.has(i.getKey())||t.$isElementNode(i)&&n.some(t=>e.isParentOf(t)&&i.isParentOf(t)),o=i.filter(s);if(o.length===i.length)return i.forEach(t=>e.insertBefore(t)),void e.remove();const l=i.findIndex(s),a=i.findLastIndex(s),u=0===l,c=a===i.length-1;if(u)o.forEach(t=>e.insertBefore(t));else if(c)for(let t=o.length-1;t>=0;t--)e.insertAfter(o[t]);else{for(let t=o.length-1;t>=0;t--)e.insertAfter(o[t]);const n=i.slice(a+1);if(n.length>0){const r=t.$copyNode(e);o[o.length-1].insertAfter(r),n.forEach(e=>r.append(e))}}}(i,g),n.add(e)}})}const d=new Set,h=e=>{d.has(e.getKey())||(d.add(e.getKey()),e.setURL(i),void 0!==s&&e.setTarget(s),void 0!==l&&e.setRel(l),void 0!==o&&e.setTitle(o))};if(1===g.length){const t=g[0],n=e.$findMatchingParent(t,c);if(null!==n)return h(n)}!function(e){const n=t.$getSelection();if(!t.$isRangeSelection(n))return e();const r=t.$normalizeSelection__EXPERIMENTAL(n),i=r.isBackward(),s=p(r.anchor,i?-1:0),o=p(r.focus,i?0:-1),l=e();if(s||o){const e=t.$getSelection();if(t.$isRangeSelection(e)){const n=e.clone();if(s){const e=s.getParent();e&&n.anchor.set(e.getKey(),s.getIndexWithinParent()+(i?1:0),"element")}if(o){const e=o.getParent();e&&n.focus.set(e.getKey(),o.getIndexWithinParent()+(i?0:1),"element")}t.$setSelection(t.$normalizeSelection__EXPERIMENTAL(n))}}}(()=>{let n=null;for(const r of g){if(!r.isAttached())continue;const a=e.$findMatchingParent(r,c);if(a){h(a);continue}if(t.$isElementNode(r)){if(!r.isInline())continue;if(c(r)){if(!(f(r)||null!==n&&n.getParentOrThrow().isParentOf(r))){h(r),n=r;continue}for(const e of r.getChildren())r.insertBefore(e);r.remove();continue}}const g=r.getPreviousSibling();c(g)&&g.is(n)?g.append(r):(n=u(i,{rel:l,target:s,title:o}),r.insertAfter(n),n.append(r))}})}const m=/^\+?[0-9\s()-]{5,}$/;function x(e){return e.match(/^[a-z][a-z0-9+.-]*:/i)||e.match(/^[/#.]/)?e:e.includes("@")?`mailto:${e}`:m.test(e)?`tel:${e}`:`https://${e}`}const N={attributes:void 0,validateUrl:void 0};function k(r,s){return e.mergeRegister(r.registerNodeTransform(i,l),r.registerCommand(h,e=>{const t=s.validateUrl.peek(),n=s.attributes.peek();if(null===e)return _(null),!0;if("string"==typeof e)return!(void 0!==t&&!t(e))&&(_(e,n),!0);{const{url:t,target:r,rel:i,title:s}=e;return _(t,{...n,rel:i,target:r,title:s}),!0}},t.COMMAND_PRIORITY_EDITOR),n.effect(()=>{const n=s.validateUrl.value;if(!n)return;const i=s.attributes.value;return r.registerCommand(t.PASTE_COMMAND,s=>{const o=t.$getSelection();if(!t.$isRangeSelection(o)||o.isCollapsed()||!e.objectKlassEquals(s,ClipboardEvent))return!1;if(null===s.clipboardData)return!1;const l=s.clipboardData.getData("text");return!!n(l)&&(!o.getNodes().some(e=>t.$isElementNode(e))&&(r.dispatchCommand(h,{...i,url:l}),s.preventDefault(),!0))},t.COMMAND_PRIORITY_LOW)}))}const $=t.defineExtension({build:(e,t,r)=>n.namedSignals(t),config:N,mergeConfig(e,n){const r=t.shallowMergeConfig(e,n);return e.attributes&&(r.attributes=t.shallowMergeConfig(e.attributes,r.attributes)),r},name:"@lexical/link/Link",nodes:()=>[i],register:(e,t,n)=>k(e,n.getOutput())});function S(n,r,i={}){const s=i=>{const s=i.target;if(!t.isDOMNode(s))return;const o=t.getNearestEditorFromDOMNode(s);if(null===o)return;let l=null,a=null;if(o.update(()=>{const n=t.$getNearestNodeFromDOMNode(s);if(null!==n){const i=e.$findMatchingParent(n,t.$isElementNode);if(!r.disabled.peek())if(c(i))l=i.sanitizeUrl(i.getURL()),a=i.getTarget();else{const t=function(e,t){let n=e;for(;null!=n;){if(t(n))return n;n=n.parentNode}return null}(s,e.isHTMLAnchorElement);null!==t&&(l=t.href,a=t.target)}}}),null===l||""===l)return;const u=n.getEditorState().read(t.$getSelection);if(t.$isRangeSelection(u)&&!u.isCollapsed())return void i.preventDefault();const g="auxclick"===i.type&&1===i.button;window.open(l,r.newTab.peek()||g||i.metaKey||i.ctrlKey||"_blank"===a?"_blank":"_self"),i.preventDefault()},o=e=>{1===e.button&&s(e)};return n.registerRootListener(e=>{if(e)return e.addEventListener("click",s,i),e.addEventListener("mouseup",o,i),()=>{e.removeEventListener("click",s),e.removeEventListener("mouseup",o)}})}const L=t.defineExtension({build:(e,t,r)=>n.namedSignals(t),config:t.safeCast({disabled:!1,newTab:!1}),dependencies:[$],name:"@lexical/link/ClickableLink",register:(e,t,n)=>S(e,n.getOutput())});function T(e,t){for(let n=0;n<t.length;n++){const r=t[n](e);if(r)return r}return null}const C=/[.,;\s]/;function b(e){return C.test(e)}function v(e){return b(e[e.length-1])}function E(e){return b(e[0])}function U(e){let n=e.getPreviousSibling();return t.$isElementNode(n)&&(n=n.getLastDescendant()),null===n||t.$isLineBreakNode(n)||t.$isTextNode(n)&&v(n.getTextContent())}function R(e){let n=e.getNextSibling();return t.$isElementNode(n)&&(n=n.getFirstDescendant()),null===n||t.$isLineBreakNode(n)||t.$isTextNode(n)&&E(n.getTextContent())}function O(e,t,n,r){if(!(e>0?b(n[e-1]):U(r[0])))return!1;return t<n.length?b(n[t]):R(r[r.length-1])}function M(e,t,n){const r=[],i=[],s=[];let o=0,l=0;const a=[...e];for(;a.length>0;){const e=a[0],u=e.getTextContent().length,c=l;l+u<=t?(r.push(e),o+=u):c>=n?s.push(e):i.push(e),l+=u,a.shift()}return[o,r,i,s]}function P(e,n,r,i){const s=d(i.url,i.attributes);if(1===e.length){let o,l=e[0];0===n?[o,l]=l.splitText(r):[,o,l]=l.splitText(n,r);const a=t.$createTextNode(i.text);return a.setFormat(o.getFormat()),a.setDetail(o.getDetail()),a.setStyle(o.getStyle()),s.append(a),o.replace(s),l}if(e.length>1){const i=e[0];let o,l=i.getTextContent().length;0===n?o=i:[,o]=i.splitText(n);const a=[];let u;for(let t=1;t<e.length;t++){const n=e[t],i=n.getTextContent().length,s=l;if(s<r)if(l+i<=r)a.push(n);else{const[e,t]=n.splitText(r-s);a.push(e),u=t}l+=i}const c=t.$getSelection(),g=c?c.getNodes().find(t.$isTextNode):void 0,d=t.$createTextNode(o.getTextContent());return d.setFormat(o.getFormat()),d.setDetail(o.getDetail()),d.setStyle(o.getStyle()),s.append(d,...a),g&&g===o&&(t.$isRangeSelection(c)?d.select(c.anchor.offset,c.focus.offset):t.$isNodeSelection(c)&&d.select(0,d.getTextContent().length)),o.replace(s),u}}function A(e,n,r){const i=e.getChildren(),s=i.length;for(let n=0;n<s;n++){const s=i[n];if(!t.$isTextNode(s)||!s.isSimpleText())return y(e),void r(null,e.getURL())}const o=e.getTextContent(),l=T(o,n);if(null===l||l.text!==o)return y(e),void r(null,e.getURL());if(!U(e)||!R(e))return y(e),void r(null,e.getURL());const a=e.getURL();if(a!==l.url&&(e.setURL(l.url),r(l.url,a)),l.attributes){const t=e.getRel();t!==l.attributes.rel&&(e.setRel(l.attributes.rel||null),r(l.attributes.rel||null,t));const n=e.getTarget();n!==l.attributes.target&&(e.setTarget(l.attributes.target||null),r(l.attributes.target||null,n))}}function y(e){const t=e.getChildren();for(let n=t.length-1;n>=0;n--)e.insertAfter(t[n]);return e.remove(),t.map(e=>e.getLatest())}const D={changeHandlers:[],excludeParents:[],matchers:[]};function I(n,r=D){const{matchers:i,changeHandlers:s,excludeParents:o}=r,l=(e,t)=>{for(const n of s)n(e,t)};return e.mergeRegister(n.registerNodeTransform(t.TextNode,e=>{const n=e.getParentOrThrow(),r=e.getPreviousSibling();if(f(n))A(n,i,l);else if(!c(n)&&!o.some(e=>e(n))){if(e.isSimpleText()&&(E(e.getTextContent())||!f(r))){const n=function(e){const n=[e];let r=e.getNextSibling();for(;null!==r&&t.$isTextNode(r)&&r.isSimpleText()&&(n.push(r),!/[\s]/.test(r.getTextContent()));)r=r.getNextSibling();return n}(e);!function(e,t,n){for(const t of e){const e=t.getParent();if(f(e)&&!e.getIsUnlinked())return}let r=[...e];const i=r.map(e=>e.getTextContent()).join("");let s,o=i,l=0;for(;(s=T(o,t))&&null!==s;){const e=s.index,t=e+s.length;if(O(l+e,l+t,i,r)){const[i,,a,u]=M(r,l+e,l+t);let c=!1;for(const e of a){const t=e.getParent();if(f(t)&&!t.getIsUnlinked()){c=!0;break}}if(c){l+=t,o=o.substring(t);continue}const g=P(a,l+e-i,l+t-i,s);r=g?[g,...u]:u,n(s.url,null),l=0}else l+=t;o=o.substring(t)}}(n,i,l)}!function(e,t,n){const r=e.getParent(),i=e.getPreviousSibling(),s=e.getNextSibling(),o=e.getTextContent();if(!f(r)||r.getIsUnlinked()){if(f(i)&&!i.getIsUnlinked()&&i.is(e.getPreviousSibling())&&e.getParent()===i.getParent()){if(!E(o))return y(i),void n(null,i.getURL());if(l=o,i.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(l):/^\.[a-zA-Z0-9]{1,}/.test(l)){const r=i.getTextContent()+o,s=T(r,t);null!==s&&s.text===r&&(i.append(e),A(i,t,n),n(null,i.getURL()))}}var l;!f(s)||s.getIsUnlinked()||v(o)||s.is(e.getNextSibling())&&e.getParent()===s.getParent()&&(y(s),n(null,s.getURL()))}}(e,i,l)}}),n.registerCommand(h,e=>{const n=t.$getSelection();if(null!==e||!t.$isRangeSelection(n))return!1;return n.extract().forEach(e=>{const t=e.getParent();f(t)&&(t.setIsUnlinked(!t.getIsUnlinked()),t.markDirty())}),!1},t.COMMAND_PRIORITY_LOW))}const w=t.defineExtension({config:D,dependencies:[$],mergeConfig(e,n){const r=t.shallowMergeConfig(e,n);for(const t of["matchers","changeHandlers","excludeParents"]){const i=n[t];Array.isArray(i)&&(r[t]=[...e[t],...i])}return r},name:"@lexical/link/AutoLink",nodes:[g],register:I}),F=_;exports.$createAutoLinkNode=d,exports.$createLinkNode=u,exports.$isAutoLinkNode=f,exports.$isLinkNode=c,exports.$toggleLink=_,exports.AutoLinkExtension=w,exports.AutoLinkNode=g,exports.ClickableLinkExtension=L,exports.LinkExtension=$,exports.LinkNode=i,exports.TOGGLE_LINK_COMMAND=h,exports.createLinkMatcherWithRegExp=function(e,t=e=>e){return n=>{const r=e.exec(n);return null===r?null:{index:r.index,length:r[0].length,text:r[0],url:t(r[0])}}},exports.formatUrl=x,exports.registerAutoLink=I,exports.registerClickableLink=S,exports.registerLink=k,exports.toggleLink=F;
|
|
9
|
+
"use strict";var e=require("@lexical/utils"),t=require("lexical"),n=require("@lexical/extension");const r=new Set(["http:","https:","mailto:","sms:","tel:"]);class i extends t.ElementNode{__url;__target;__rel;__title;static getType(){return"link"}static clone(e){return new i(e.__url,{rel:e.__rel,target:e.__target,title:e.__title},e.__key)}constructor(e="",t={},n){super(n);const{target:r=null,rel:i=null,title:s=null}=t;this.__url=e,this.__target=r,this.__rel=i,this.__title=s}afterCloneFrom(e){super.afterCloneFrom(e),this.__url=e.__url,this.__rel=e.__rel,this.__target=e.__target,this.__title=e.__title}createDOM(t){const n=document.createElement("a");return this.updateLinkDOM(null,n,t),e.addClassNamesToElement(n,t.theme.link),n}updateLinkDOM(t,n,r){if(e.isHTMLAnchorElement(n)){t&&t.__url===this.__url||(n.href=this.sanitizeUrl(this.__url));for(const e of["target","rel","title"]){const r=`__${e}`,i=this[r];t&&t[r]===i||(i?n[e]=i:n.removeAttribute(e))}}}updateDOM(e,t,n){return this.updateLinkDOM(e,t,n),!1}static importDOM(){return{a:e=>({conversion:a,priority:1})}}static importJSON(e){return u().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setURL(e.url).setRel(e.rel||null).setTarget(e.target||null).setTitle(e.title||null)}sanitizeUrl(e){e=x(e);try{const t=new URL(x(e));if(!r.has(t.protocol))return"about:blank"}catch(t){return e}return e}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),url:this.getURL()}}getURL(){return this.getLatest().__url}setURL(e){const t=this.getWritable();return t.__url=e,t}getTarget(){return this.getLatest().__target}setTarget(e){const t=this.getWritable();return t.__target=e,t}getRel(){return this.getLatest().__rel}setRel(e){const t=this.getWritable();return t.__rel=e,t}getTitle(){return this.getLatest().__title}setTitle(e){const t=this.getWritable();return t.__title=e,t}insertNewAfter(e,n=!0){const r=t.$copyNode(this);return this.insertAfter(r,n),r}canInsertTextBefore(){return!1}canInsertTextAfter(){return!1}canBeEmpty(){return!1}isInline(){return!0}extractWithChild(e,n,r){if(!t.$isRangeSelection(n))return!1;const i=n.anchor.getNode(),s=n.focus.getNode();return this.isParentOf(i)&&this.isParentOf(s)&&n.getTextContent().length>0}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")||this.__url.startsWith("http://")}shouldMergeAdjacentLink(e){return this.getType()===e.getType()&&this.__url===e.__url&&this.__target===e.__target&&this.__rel===e.__rel&&this.__title===e.__title}}function s(e){const n=t.$caretFromPoint(e,"next");return[n,n.getFlipped()]}function o(e,n){for(const r of n)if(r.origin.isAttached()){const n=t.$normalizeCaret(r);return void t.$setPointFromCaret(e,n)}}function l(n){const r=t.$getSelection();let i=null,l=null;function a(){t.$isRangeSelection(r)&&(o(r.anchor,i),o(r.focus,l),t.$normalizeSelection__EXPERIMENTAL(r))}t.$isRangeSelection(r)&&(i=s(r.anchor),l=s(r.focus));let u=!1;for(const r of t.$getChildCaret(n,"next")){const i=r.origin;if(t.$isElementNode(i)&&!i.isInline()){const s=i.getChildren();if(s.length>0){const e=t.$copyNode(n);e.append(...s),i.append(e),u=!0}e.$insertNodeToNearestRootAtCaret(i,t.$rewindSiblingCaret(r),{$shouldSplit:()=>!1})}}function g(e,n,r){const[i,s]=e,o=e=>t.$isSiblingCaret(e)&&e.origin.is(n);if(!o(i)&&!o(s))return e;const l=t.$normalizeCaret(t.$getChildCaret(r,"next"));return[l,l.getFlipped()]}if(n.isAttached()){const e=n.getPreviousSibling();if(c(e)&&e.shouldMergeAdjacentLink(n))return i&&(i=g(i,e,n)),l&&(l=g(l,e,n)),e.append(...n.getChildren()),n.remove(),void a();const t=n.getNextSibling();c(t)&&n.shouldMergeAdjacentLink(t)&&(i&&(i=g(i,n,t)),l&&(l=g(l,n,t)),n.append(...t.getChildren()),t.remove(),u=!0)}if(u){if(!n.canBeEmpty()&&n.isEmpty()){const e=n.getParent();n.remove(),e&&e.isEmpty()&&e.remove()}a()}}function a(t){let n=null;if(e.isHTMLAnchorElement(t)){const e=t.textContent;(null!==e&&""!==e||t.children.length>0)&&(n=u(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}))}return{node:n}}function u(e="",n){return t.$applyNodeReplacement(new i(e,n))}function c(e){return e instanceof i}class g extends i{__isUnlinked;constructor(e="",t={},n){super(e,t,n),this.__isUnlinked=void 0!==t.isUnlinked&&null!==t.isUnlinked&&t.isUnlinked}afterCloneFrom(e){super.afterCloneFrom(e),this.__isUnlinked=e.__isUnlinked}static getType(){return"autolink"}static clone(e){return new g(e.__url,{isUnlinked:e.__isUnlinked,rel:e.__rel,target:e.__target,title:e.__title},e.__key)}shouldMergeAdjacentLink(e){return!1}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(e){const t=this.getWritable();return t.__isUnlinked=e,t}createDOM(e){return this.__isUnlinked?document.createElement("span"):super.createDOM(e)}updateDOM(e,t,n){return super.updateDOM(e,t,n)||e.__isUnlinked!==this.__isUnlinked}static importJSON(e){return d().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setIsUnlinked(e.isUnlinked||!1)}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked}}insertNewAfter(e,t=!0){const n=d(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(n,t),n}}function d(e="",n){return t.$applyNodeReplacement(new g(e,n))}function f(e){return e instanceof g}const h=t.createCommand("TOGGLE_LINK_COMMAND");function p(e,n){if("element"===e.type){const r=e.getNode();t.$isElementNode(r)||function(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(252);return r.getChildren()[e.offset+n]||null}return null}function _(n,r={}){let i;if(n&&"object"==typeof n){const{url:e,...t}=n;i=e,r={...t,...r}}else i=n;const{target:s,title:o}=r,l=void 0===r.rel?"noreferrer":r.rel,a=t.$getSelection();if(null===a||!t.$isRangeSelection(a)&&!t.$isNodeSelection(a))return;if(t.$isNodeSelection(a)){const t=a.getNodes();if(0===t.length)return;return void t.forEach(t=>{if(null===i){const n=e.$findMatchingParent(t,e=>!f(e)&&c(e));n&&(n.insertBefore(t),0===n.getChildren().length&&n.remove())}else{const n=e.$findMatchingParent(t,e=>!f(e)&&c(e));if(n)n.setURL(i),void 0!==s&&n.setTarget(s),void 0!==l&&n.setRel(l);else{const e=u(i,{rel:l,target:s});t.insertBefore(e),e.append(t)}}})}if(a.isCollapsed()&&null===i)for(const t of a.getNodes()){const n=e.$findMatchingParent(t,e=>!f(e)&&c(e));return void(null!==n&&(n.getChildren().forEach(e=>{n.insertBefore(e)}),n.remove()))}const g=a.extract();if(null===i){const n=new Set;return void g.forEach(r=>{const i=e.$findMatchingParent(r,e=>!f(e)&&c(e));if(null!==i){const e=i.getKey();if(n.has(e))return;!function(e,n){const r=new Set(n.filter(t=>e.isParentOf(t)).map(e=>e.getKey())),i=e.getChildren(),s=i=>r.has(i.getKey())||t.$isElementNode(i)&&n.some(t=>e.isParentOf(t)&&i.isParentOf(t)),o=i.filter(s);if(o.length===i.length)return i.forEach(t=>e.insertBefore(t)),void e.remove();const l=i.findIndex(s),a=i.findLastIndex(s),u=0===l,c=a===i.length-1;if(u)o.forEach(t=>e.insertBefore(t));else if(c)for(let t=o.length-1;t>=0;t--)e.insertAfter(o[t]);else{for(let t=o.length-1;t>=0;t--)e.insertAfter(o[t]);const n=i.slice(a+1);if(n.length>0){const r=t.$copyNode(e);o[o.length-1].insertAfter(r),n.forEach(e=>r.append(e))}}}(i,g),n.add(e)}})}const d=new Set,h=e=>{d.has(e.getKey())||(d.add(e.getKey()),e.setURL(i),void 0!==s&&e.setTarget(s),void 0!==l&&e.setRel(l),void 0!==o&&e.setTitle(o))};if(1===g.length){const t=g[0],n=e.$findMatchingParent(t,c);if(null!==n)return h(n)}!function(e){const n=t.$getSelection();if(!t.$isRangeSelection(n))return e();const r=t.$normalizeSelection__EXPERIMENTAL(n),i=r.isBackward(),s=p(r.anchor,i?-1:0),o=p(r.focus,i?0:-1),l=e();if(s||o){const e=t.$getSelection();if(t.$isRangeSelection(e)){const n=e.clone();if(s){const e=s.getParent();e&&n.anchor.set(e.getKey(),s.getIndexWithinParent()+(i?1:0),"element")}if(o){const e=o.getParent();e&&n.focus.set(e.getKey(),o.getIndexWithinParent()+(i?0:1),"element")}t.$setSelection(t.$normalizeSelection__EXPERIMENTAL(n))}}}(()=>{let n=null;for(const r of g){if(!r.isAttached())continue;const a=e.$findMatchingParent(r,c);if(a){h(a);continue}if(t.$isElementNode(r)){if(!r.isInline())continue;if(c(r)){if(!(f(r)||null!==n&&n.getParentOrThrow().isParentOf(r))){h(r),n=r;continue}for(const e of r.getChildren())r.insertBefore(e);r.remove();continue}}const g=r.getPreviousSibling();c(g)&&g.is(n)?g.append(r):(n=u(i,{rel:l,target:s,title:o}),r.insertAfter(n),n.append(r))}})}const m=/^\+?[0-9\s()-]{5,}$/;function x(e){return e.match(/^[a-z][a-z0-9+.-]*:/i)||e.match(/^[/#.]/)?e:e.includes("@")?`mailto:${e}`:m.test(e)?`tel:${e}`:`https://${e}`}const N={attributes:void 0,validateUrl:void 0};function k(r,s){return e.mergeRegister(r.registerNodeTransform(i,l),r.registerCommand(h,e=>{const t=s.validateUrl.peek(),n=s.attributes.peek();if(null===e)return _(null),!0;if("string"==typeof e)return!(void 0!==t&&!t(e))&&(_(e,n),!0);{const{url:t,target:r,rel:i,title:s}=e;return _(t,{...n,rel:i,target:r,title:s}),!0}},t.COMMAND_PRIORITY_EDITOR),n.effect(()=>{const n=s.validateUrl.value;if(!n)return;const i=s.attributes.value;return r.registerCommand(t.PASTE_COMMAND,s=>{const o=t.$getSelection();if(!t.$isRangeSelection(o)||o.isCollapsed()||!e.objectKlassEquals(s,ClipboardEvent))return!1;if(null===s.clipboardData)return!1;const l=s.clipboardData.getData("text");return!!n(l)&&(!o.getNodes().some(e=>t.$isElementNode(e))&&(r.dispatchCommand(h,{...i,url:l}),s.preventDefault(),!0))},t.COMMAND_PRIORITY_LOW)}))}const $=t.defineExtension({build:(e,t,r)=>n.namedSignals(t),config:N,mergeConfig(e,n){const r=t.shallowMergeConfig(e,n);return e.attributes&&(r.attributes=t.shallowMergeConfig(e.attributes,r.attributes)),r},name:"@lexical/link/Link",nodes:()=>[i],register:(e,t,n)=>k(e,n.getOutput())});function S(n,r,i={}){const s=i=>{const s=i.target;if(!t.isDOMNode(s))return;const o=t.getNearestEditorFromDOMNode(s);if(null===o)return;let l=null,a=null;if(o.update(()=>{const n=t.$getNearestNodeFromDOMNode(s);if(null!==n){const i=e.$findMatchingParent(n,t.$isElementNode);if(!r.disabled.peek())if(c(i))l=i.sanitizeUrl(i.getURL()),a=i.getTarget();else{const t=function(e,t){let n=e;for(;null!=n;){if(t(n))return n;n=n.parentNode}return null}(s,e.isHTMLAnchorElement);null!==t&&(l=t.href,a=t.target)}}}),null===l||""===l)return;const u=n.getEditorState().read(t.$getSelection,{editor:n});if(t.$isRangeSelection(u)&&!u.isCollapsed())return void i.preventDefault();const g="auxclick"===i.type&&1===i.button;window.open(l,r.newTab.peek()||g||i.metaKey||i.ctrlKey||"_blank"===a?"_blank":"_self"),i.preventDefault()},o=e=>{1===e.button&&s(e)};return n.registerRootListener(e=>{if(e)return e.addEventListener("click",s,i),e.addEventListener("mouseup",o,i),()=>{e.removeEventListener("click",s),e.removeEventListener("mouseup",o)}})}const L=t.defineExtension({build:(e,t,r)=>n.namedSignals(t),config:t.safeCast({disabled:!1,newTab:!1}),dependencies:[$],name:"@lexical/link/ClickableLink",register:(e,t,n)=>S(e,n.getOutput())});function T(e,t){for(let n=0;n<t.length;n++){const r=t[n](e);if(r)return r}return null}const C=/[.,;\s]/;function b(e,t){return t.test(e)}function v(e,t){return b(e[e.length-1],t)}function R(e,t){return b(e[0],t)}function E(e,n){let r=e.getPreviousSibling();return t.$isElementNode(r)&&(r=r.getLastDescendant()),null===r||t.$isLineBreakNode(r)||t.$isTextNode(r)&&v(r.getTextContent(),n)}function U(e,n){let r=e.getNextSibling();return t.$isElementNode(r)&&(r=r.getFirstDescendant()),null===r||t.$isLineBreakNode(r)||t.$isTextNode(r)&&R(r.getTextContent(),n)}function O(e,t,n,r,i){if(!(e>0?b(r[e-1],n):E(i[0],n)))return!1;return t<r.length?b(r[t],n):U(i[i.length-1],n)}function M(e,t,n){const r=[],i=[],s=[];let o=0,l=0;const a=[...e];for(;a.length>0;){const e=a[0],u=e.getTextContent().length,c=l;l+u<=t?(r.push(e),o+=u):c>=n?s.push(e):i.push(e),l+=u,a.shift()}return[o,r,i,s]}function P(e,n,r,i){const s=d(i.url,i.attributes);if(1===e.length){let o,l=e[0];0===n?[o,l]=l.splitText(r):[,o,l]=l.splitText(n,r);const a=t.$createTextNode(i.text);return a.setFormat(o.getFormat()),a.setDetail(o.getDetail()),a.setStyle(o.getStyle()),s.append(a),o.replace(s),l}if(e.length>1){const i=e[0];let o,l=i.getTextContent().length;0===n?o=i:[,o]=i.splitText(n);const a=[];let u;for(let t=1;t<e.length;t++){const n=e[t],i=n.getTextContent().length,s=l;if(s<r)if(l+i<=r)a.push(n);else{const[e,t]=n.splitText(r-s);a.push(e),u=t}l+=i}const c=t.$getSelection(),g=c?c.getNodes().find(t.$isTextNode):void 0,d=t.$createTextNode(o.getTextContent());return d.setFormat(o.getFormat()),d.setDetail(o.getDetail()),d.setStyle(o.getStyle()),s.append(d,...a),g&&g===o&&(t.$isRangeSelection(c)?d.select(c.anchor.offset,c.focus.offset):t.$isNodeSelection(c)&&d.select(0,d.getTextContent().length)),o.replace(s),u}}function A(e,n,r,i){const s=e.getChildren(),o=s.length;for(let n=0;n<o;n++){const i=s[n];if(!t.$isTextNode(i)||!i.isSimpleText())return y(e),void r(null,e.getURL())}const l=e.getTextContent(),a=T(l,n);if(null===a||a.text!==l)return y(e),void r(null,e.getURL());if(!E(e,i)||!U(e,i))return y(e),void r(null,e.getURL());const u=e.getURL();if(u!==a.url&&(e.setURL(a.url),r(a.url,u)),a.attributes){const t=e.getRel();t!==a.attributes.rel&&(e.setRel(a.attributes.rel||null),r(a.attributes.rel||null,t));const n=e.getTarget();n!==a.attributes.target&&(e.setTarget(a.attributes.target||null),r(a.attributes.target||null,n))}}function y(e){const t=e.getChildren();for(let n=t.length-1;n>=0;n--)e.insertAfter(t[n]);return e.remove(),t.map(e=>e.getLatest())}const D={changeHandlers:[],excludeParents:[],matchers:[],separatorRegex:C};function I(n,r=D){const{matchers:i,changeHandlers:s,excludeParents:o,separatorRegex:l=C}=r,a=(e,t)=>{for(const n of s)n(e,t)};return e.mergeRegister(n.registerNodeTransform(t.TextNode,e=>{const n=e.getParentOrThrow(),r=e.getPreviousSibling();if(f(n))A(n,i,a,l);else if(!c(n)&&!o.some(e=>e(n))){if(e.isSimpleText()&&(R(e.getTextContent(),l)||!f(r))){const n=function(e){const n=[e];let r=e.getNextSibling();for(;null!==r&&t.$isTextNode(r)&&r.isSimpleText()&&(n.push(r),!/[\s]/.test(r.getTextContent()));)r=r.getNextSibling();return n}(e);!function(e,t,n,r){for(const t of e){const e=t.getParent();if(f(e)&&!e.getIsUnlinked())return}let i=[...e];const s=i.map(e=>e.getTextContent()).join("");let o,l=s,a=0;for(;(o=T(l,t))&&null!==o;){const e=o.index,t=e+o.length;if(O(a+e,a+t,r,s,i)){const[r,,s,u]=M(i,a+e,a+t);let c=!1;for(const e of s){const t=e.getParent();if(f(t)&&!t.getIsUnlinked()){c=!0;break}}if(c){a+=t,l=l.substring(t);continue}const g=P(s,a+e-r,a+t-r,o);i=g?[g,...u]:u,n(o.url,null),a=0}else a+=t;l=l.substring(t)}}(n,i,a,l)}!function(e,t,n,r){const i=e.getParent(),s=e.getPreviousSibling(),o=e.getNextSibling(),l=e.getTextContent();if(!f(i)||i.getIsUnlinked()){if(f(s)&&!s.getIsUnlinked()&&s.is(e.getPreviousSibling())&&e.getParent()===s.getParent()){if(!R(l,r))return y(s),void n(null,s.getURL());if(a=l,s.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(a):/^\.[a-zA-Z0-9]{1,}/.test(a)){const i=s.getTextContent()+l,o=T(i,t);null!==o&&o.text===i&&(s.append(e),A(s,t,n,r),n(null,s.getURL()))}}var a;!f(o)||o.getIsUnlinked()||v(l,r)||o.is(e.getNextSibling())&&e.getParent()===o.getParent()&&(y(o),n(null,o.getURL()))}}(e,i,a,l)}}),n.registerCommand(h,e=>{const n=t.$getSelection();if(null!==e||!t.$isRangeSelection(n))return!1;return n.extract().forEach(e=>{const t=e.getParent();f(t)&&(t.setIsUnlinked(!t.getIsUnlinked()),t.markDirty())}),!1},t.COMMAND_PRIORITY_LOW))}const w=t.defineExtension({config:D,dependencies:[$],mergeConfig(e,n){const r=t.shallowMergeConfig(e,n);for(const t of["matchers","changeHandlers","excludeParents"]){const i=n[t];Array.isArray(i)&&(r[t]=[...e[t],...i])}return r},name:"@lexical/link/AutoLink",nodes:[g],register:I}),F=_;exports.$createAutoLinkNode=d,exports.$createLinkNode=u,exports.$isAutoLinkNode=f,exports.$isLinkNode=c,exports.$toggleLink=_,exports.AutoLinkExtension=w,exports.AutoLinkNode=g,exports.ClickableLinkExtension=L,exports.LinkExtension=$,exports.LinkNode=i,exports.TOGGLE_LINK_COMMAND=h,exports.createLinkMatcherWithRegExp=function(e,t=e=>e){return n=>{const r=e.exec(n);return null===r?null:{index:r.index,length:r[0].length,text:r[0],url:t(r[0])}}},exports.formatUrl=x,exports.registerAutoLink=I,exports.registerClickableLink=S,exports.registerLink=k,exports.toggleLink=F;
|
package/LexicalLink.prod.mjs
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import{addClassNamesToElement as t,isHTMLAnchorElement as e,$findMatchingParent as n,$insertNodeToNearestRootAtCaret as r,mergeRegister as i,objectKlassEquals as s}from"@lexical/utils";import{ElementNode as l,$copyNode as o,$isRangeSelection as u,$applyNodeReplacement as a,createCommand as c,$getSelection as g,$isNodeSelection as f,$normalizeSelection__EXPERIMENTAL as d,$setSelection as h,$getChildCaret as _,$isElementNode as p,$rewindSiblingCaret as m,$caretFromPoint as x,$normalizeCaret as k,$isSiblingCaret as v,$setPointFromCaret as b,defineExtension as U,shallowMergeConfig as T,COMMAND_PRIORITY_EDITOR as L,PASTE_COMMAND as C,COMMAND_PRIORITY_LOW as S,safeCast as O,isDOMNode as y,getNearestEditorFromDOMNode as N,$getNearestNodeFromDOMNode as P,TextNode as R,$isTextNode as A,$isLineBreakNode as D,$createTextNode as E}from"lexical";import{namedSignals as I,effect as w}from"@lexical/extension";const M=new Set(["http:","https:","mailto:","sms:","tel:"]);class F extends l{__url;__target;__rel;__title;static getType(){return"link"}static clone(t){return new F(t.__url,{rel:t.__rel,target:t.__target,title:t.__title},t.__key)}constructor(t="",e={},n){super(n);const{target:r=null,rel:i=null,title: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(e){const n=document.createElement("a");return this.updateLinkDOM(null,n,e),t(n,e.theme.link),n}updateLinkDOM(t,n,r){if(e(n)){t&&t.__url===this.__url||(n.href=this.sanitizeUrl(this.__url));for(const e of["target","rel","title"]){const r=`__${e}`,i=this[r];t&&t[r]===i||(i?n[e]=i:n.removeAttribute(e))}}}updateDOM(t,e,n){return this.updateLinkDOM(t,e,n),!1}static importDOM(){return{a:t=>({conversion:K,priority:1})}}static importJSON(t){return $().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setURL(t.url).setRel(t.rel||null).setTarget(t.target||null).setTitle(t.title||null)}sanitizeUrl(t){t=X(t);try{const e=new URL(X(t));if(!M.has(e.protocol))return"about:blank"}catch(e){return t}return t}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),url:this.getURL()}}getURL(){return this.getLatest().__url}setURL(t){const e=this.getWritable();return e.__url=t,e}getTarget(){return this.getLatest().__target}setTarget(t){const e=this.getWritable();return e.__target=t,e}getRel(){return this.getLatest().__rel}setRel(t){const e=this.getWritable();return e.__rel=t,e}getTitle(){return this.getLatest().__title}setTitle(t){const e=this.getWritable();return e.__title=t,e}insertNewAfter(t,e=!0){const n=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.isParentOf(r)&&this.isParentOf(i)&&e.getTextContent().length>0}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")||this.__url.startsWith("http://")}shouldMergeAdjacentLink(t){return this.getType()===t.getType()&&this.__url===t.__url&&this.__target===t.__target&&this.__rel===t.__rel&&this.__title===t.__title}}function J(t){const e=x(t,"next");return[e,e.getFlipped()]}function W(t,e){for(const n of e)if(n.origin.isAttached()){const e=k(n);return void b(t,e)}}function B(t){const e=g();let n=null,i=null;function s(){u(e)&&(W(e.anchor,n),W(e.focus,i),d(e))}u(e)&&(n=J(e.anchor),i=J(e.focus));let l=!1;for(const e of _(t,"next")){const n=e.origin;if(p(n)&&!n.isInline()){const i=n.getChildren();if(i.length>0){const e=o(t);e.append(...i),n.append(e),l=!0}r(n,m(e),{$shouldSplit:()=>!1})}}function a(t,e,n){const[r,i]=t,s=t=>v(t)&&t.origin.is(e);if(!s(r)&&!s(i))return t;const l=k(_(n,"next"));return[l,l.getFlipped()]}if(t.isAttached()){const e=t.getPreviousSibling();if(z(e)&&e.shouldMergeAdjacentLink(t))return n&&(n=a(n,e,t)),i&&(i=a(i,e,t)),e.append(...t.getChildren()),t.remove(),void s();const r=t.getNextSibling();z(r)&&t.shouldMergeAdjacentLink(r)&&(n&&(n=a(n,t,r)),i&&(i=a(i,t,r)),t.append(...r.getChildren()),r.remove(),l=!0)}if(l){if(!t.canBeEmpty()&&t.isEmpty()){const e=t.getParent();t.remove(),e&&e.isEmpty()&&e.remove()}s()}}function K(t){let n=null;if(e(t)){const e=t.textContent;(null!==e&&""!==e||t.children.length>0)&&(n=$(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}))}return{node:n}}function $(t="",e){return a(new F(t,e))}function z(t){return t instanceof F}class j extends F{__isUnlinked;constructor(t="",e={},n){super(t,e,n),this.__isUnlinked=void 0!==e.isUnlinked&&null!==e.isUnlinked&&e.isUnlinked}afterCloneFrom(t){super.afterCloneFrom(t),this.__isUnlinked=t.__isUnlinked}static getType(){return"autolink"}static clone(t){return new j(t.__url,{isUnlinked:t.__isUnlinked,rel:t.__rel,target:t.__target,title:t.__title},t.__key)}shouldMergeAdjacentLink(t){return!1}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(t){const e=this.getWritable();return e.__isUnlinked=t,e}createDOM(t){return this.__isUnlinked?document.createElement("span"):super.createDOM(t)}updateDOM(t,e,n){return super.updateDOM(t,e,n)||t.__isUnlinked!==this.__isUnlinked}static importJSON(t){return H().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setIsUnlinked(t.isUnlinked||!1)}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked}}insertNewAfter(t,e=!0){const n=H(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(n,e),n}}function H(t="",e){return a(new j(t,e))}function G(t){return t instanceof j}const Z=c("TOGGLE_LINK_COMMAND");function q(t,e){if("element"===t.type){const n=t.getNode();p(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 Q(t,e={}){let r;if(t&&"object"==typeof t){const{url:n,...i}=t;r=n,e={...i,...e}}else r=t;const{target:i,title:s}=e,l=void 0===e.rel?"noreferrer":e.rel,a=g();if(null===a||!u(a)&&!f(a))return;if(f(a)){const t=a.getNodes();if(0===t.length)return;return void t.forEach(t=>{if(null===r){const e=n(t,t=>!G(t)&&z(t));e&&(e.insertBefore(t),0===e.getChildren().length&&e.remove())}else{const e=n(t,t=>!G(t)&&z(t));if(e)e.setURL(r),void 0!==i&&e.setTarget(i),void 0!==l&&e.setRel(l);else{const e=$(r,{rel:l,target:i});t.insertBefore(e),e.append(t)}}})}if(a.isCollapsed()&&null===r)for(const t of a.getNodes()){const e=n(t,t=>!G(t)&&z(t));return void(null!==e&&(e.getChildren().forEach(t=>{e.insertBefore(t)}),e.remove()))}const c=a.extract();if(null===r){const t=new Set;return void c.forEach(e=>{const r=n(e,t=>!G(t)&&z(t));if(null!==r){const e=r.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())||p(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))}}}(r,c),t.add(e)}})}const _=new Set,m=t=>{_.has(t.getKey())||(_.add(t.getKey()),t.setURL(r),void 0!==i&&t.setTarget(i),void 0!==l&&t.setRel(l),void 0!==s&&t.setTitle(s))};if(1===c.length){const t=c[0],e=n(t,z);if(null!==e)return m(e)}!function(t){const e=g();if(!u(e))return t();const n=d(e),r=n.isBackward(),i=q(n.anchor,r?-1:0),s=q(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")}h(d(e))}}}(()=>{let t=null;for(const e of c){if(!e.isAttached())continue;const o=n(e,z);if(o){m(o);continue}if(p(e)){if(!e.isInline())continue;if(z(e)){if(!(G(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 u=e.getPreviousSibling();z(u)&&u.is(t)?u.append(e):(t=$(r,{rel:l,target:i,title:s}),e.insertAfter(t),t.append(e))}})}const V=/^\+?[0-9\s()-]{5,}$/;function X(t){return t.match(/^[a-z][a-z0-9+.-]*:/i)||t.match(/^[/#.]/)?t:t.includes("@")?`mailto:${t}`:V.test(t)?`tel:${t}`:`https://${t}`}function Y(t,e){return i(t.registerNodeTransform(F,B),t.registerCommand(Z,t=>{const n=e.validateUrl.peek(),r=e.attributes.peek();if(null===t)return Q(null),!0;if("string"==typeof t)return!(void 0!==n&&!n(t))&&(Q(t,r),!0);{const{url:e,target:n,rel:i,title:s}=t;return Q(e,{...r,rel:i,target:n,title:s}),!0}},L),w(()=>{const n=e.validateUrl.value;if(!n)return;const r=e.attributes.value;return t.registerCommand(C,e=>{const i=g();if(!u(i)||i.isCollapsed()||!s(e,ClipboardEvent))return!1;if(null===e.clipboardData)return!1;const l=e.clipboardData.getData("text");return!!n(l)&&(!i.getNodes().some(t=>p(t))&&(t.dispatchCommand(Z,{...r,url:l}),e.preventDefault(),!0))},S)}))}const tt=U({build:(t,e,n)=>I(e),config:{attributes:void 0,validateUrl:void 0},mergeConfig(t,e){const n=T(t,e);return t.attributes&&(n.attributes=T(t.attributes,n.attributes)),n},name:"@lexical/link/Link",nodes:()=>[F],register:(t,e,n)=>Y(t,n.getOutput())});function et(t,r,i={}){const s=i=>{const s=i.target;if(!y(s))return;const l=N(s);if(null===l)return;let o=null,a=null;if(l.update(()=>{const t=P(s);if(null!==t){const i=n(t,p);if(!r.disabled.peek())if(z(i))o=i.sanitizeUrl(i.getURL()),a=i.getTarget();else{const t=function(t,e){let n=t;for(;null!=n;){if(e(n))return n;n=n.parentNode}return null}(s,e);null!==t&&(o=t.href,a=t.target)}}}),null===o||""===o)return;const c=t.getEditorState().read(g);if(u(c)&&!c.isCollapsed())return void i.preventDefault();const f="auxclick"===i.type&&1===i.button;window.open(o,r.newTab.peek()||f||i.metaKey||i.ctrlKey||"_blank"===a?"_blank":"_self"),i.preventDefault()},l=t=>{1===t.button&&s(t)};return t.registerRootListener(t=>{if(t)return t.addEventListener("click",s,i),t.addEventListener("mouseup",l,i),()=>{t.removeEventListener("click",s),t.removeEventListener("mouseup",l)}})}const nt=U({build:(t,e,n)=>I(e),config:O({disabled:!1,newTab:!1}),dependencies:[tt],name:"@lexical/link/ClickableLink",register:(t,e,n)=>et(t,n.getOutput())});function rt(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])}}}function it(t,e){for(let n=0;n<e.length;n++){const r=e[n](t);if(r)return r}return null}const st=/[.,;\s]/;function lt(t){return st.test(t)}function ot(t){return lt(t[t.length-1])}function ut(t){return lt(t[0])}function at(t){let e=t.getPreviousSibling();return p(e)&&(e=e.getLastDescendant()),null===e||D(e)||A(e)&&ot(e.getTextContent())}function ct(t){let e=t.getNextSibling();return p(e)&&(e=e.getFirstDescendant()),null===e||D(e)||A(e)&&ut(e.getTextContent())}function gt(t,e,n,r){if(!(t>0?lt(n[t-1]):at(r[0])))return!1;return e<n.length?lt(n[e]):ct(r[r.length-1])}function ft(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 dt(t,e,n,r){const i=H(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=E(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(A):void 0,h=E(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 ht(t,e,n){const r=t.getChildren(),i=r.length;for(let e=0;e<i;e++){const i=r[e];if(!A(i)||!i.isSimpleText())return _t(t),void n(null,t.getURL())}const s=t.getTextContent(),l=it(s,e);if(null===l||l.text!==s)return _t(t),void n(null,t.getURL());if(!at(t)||!ct(t))return _t(t),void n(null,t.getURL());const o=t.getURL();if(o!==l.url&&(t.setURL(l.url),n(l.url,o)),l.attributes){const e=t.getRel();e!==l.attributes.rel&&(t.setRel(l.attributes.rel||null),n(l.attributes.rel||null,e));const r=t.getTarget();r!==l.attributes.target&&(t.setTarget(l.attributes.target||null),n(l.attributes.target||null,r))}}function _t(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 pt={changeHandlers:[],excludeParents:[],matchers:[]};function mt(t,e=pt){const{matchers:n,changeHandlers:r,excludeParents:s}=e,l=(t,e)=>{for(const n of r)n(t,e)};return i(t.registerNodeTransform(R,t=>{const e=t.getParentOrThrow(),r=t.getPreviousSibling();if(G(e))ht(e,n,l);else if(!z(e)&&!s.some(t=>t(e))){if(t.isSimpleText()&&(ut(t.getTextContent())||!G(r))){const e=function(t){const e=[t];let n=t.getNextSibling();for(;null!==n&&A(n)&&n.isSimpleText()&&(e.push(n),!/[\s]/.test(n.getTextContent()));)n=n.getNextSibling();return e}(t);!function(t,e,n){for(const e of t){const t=e.getParent();if(G(t)&&!t.getIsUnlinked())return}let r=[...t];const i=r.map(t=>t.getTextContent()).join("");let s,l=i,o=0;for(;(s=it(l,e))&&null!==s;){const t=s.index,e=t+s.length;if(gt(o+t,o+e,i,r)){const[i,,u,a]=ft(r,o+t,o+e);let c=!1;for(const t of u){const e=t.getParent();if(G(e)&&!e.getIsUnlinked()){c=!0;break}}if(c){o+=e,l=l.substring(e);continue}const g=dt(u,o+t-i,o+e-i,s);r=g?[g,...a]:a,n(s.url,null),o=0}else o+=e;l=l.substring(e)}}(e,n,l)}!function(t,e,n){const r=t.getParent(),i=t.getPreviousSibling(),s=t.getNextSibling(),l=t.getTextContent();if(!G(r)||r.getIsUnlinked()){if(G(i)&&!i.getIsUnlinked()&&i.is(t.getPreviousSibling())&&t.getParent()===i.getParent()){if(!ut(l))return _t(i),void n(null,i.getURL());if(o=l,i.isEmailURI()?/^\.[a-zA-Z]{2,}/.test(o):/^\.[a-zA-Z0-9]{1,}/.test(o)){const r=i.getTextContent()+l,s=it(r,e);null!==s&&s.text===r&&(i.append(t),ht(i,e,n),n(null,i.getURL()))}}var o;!G(s)||s.getIsUnlinked()||ot(l)||s.is(t.getNextSibling())&&t.getParent()===s.getParent()&&(_t(s),n(null,s.getURL()))}}(t,n,l)}}),t.registerCommand(Z,t=>{const e=g();if(null!==t||!u(e))return!1;return e.extract().forEach(t=>{const e=t.getParent();G(e)&&(e.setIsUnlinked(!e.getIsUnlinked()),e.markDirty())}),!1},S))}const xt=U({config:pt,dependencies:[tt],mergeConfig(t,e){const n=T(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:[j],register:mt}),kt=Q;export{H as $createAutoLinkNode,$ as $createLinkNode,G as $isAutoLinkNode,z as $isLinkNode,Q as $toggleLink,xt as AutoLinkExtension,j as AutoLinkNode,nt as ClickableLinkExtension,tt as LinkExtension,F as LinkNode,Z as TOGGLE_LINK_COMMAND,rt as createLinkMatcherWithRegExp,X as formatUrl,mt as registerAutoLink,et as registerClickableLink,Y as registerLink,kt as toggleLink};
|
|
9
|
+
import{addClassNamesToElement as t,isHTMLAnchorElement as e,$findMatchingParent as n,$insertNodeToNearestRootAtCaret as r,mergeRegister as i,objectKlassEquals as s}from"@lexical/utils";import{ElementNode as l,$copyNode as o,$isRangeSelection as u,$applyNodeReplacement as a,createCommand as c,$getSelection as g,$isNodeSelection as f,$normalizeSelection__EXPERIMENTAL as d,$setSelection as h,$getChildCaret as _,$isElementNode as p,$rewindSiblingCaret as m,$caretFromPoint as x,$normalizeCaret as k,$isSiblingCaret as v,$setPointFromCaret as b,defineExtension as U,shallowMergeConfig as T,COMMAND_PRIORITY_EDITOR as L,PASTE_COMMAND as C,COMMAND_PRIORITY_LOW as S,safeCast as O,isDOMNode as y,getNearestEditorFromDOMNode as N,$getNearestNodeFromDOMNode as R,TextNode as P,$isTextNode as A,$isLineBreakNode as D,$createTextNode as E}from"lexical";import{namedSignals as I,effect as w}from"@lexical/extension";const M=new Set(["http:","https:","mailto:","sms:","tel:"]);class F extends l{__url;__target;__rel;__title;static getType(){return"link"}static clone(t){return new F(t.__url,{rel:t.__rel,target:t.__target,title:t.__title},t.__key)}constructor(t="",e={},n){super(n);const{target:r=null,rel:i=null,title: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(e){const n=document.createElement("a");return this.updateLinkDOM(null,n,e),t(n,e.theme.link),n}updateLinkDOM(t,n,r){if(e(n)){t&&t.__url===this.__url||(n.href=this.sanitizeUrl(this.__url));for(const e of["target","rel","title"]){const r=`__${e}`,i=this[r];t&&t[r]===i||(i?n[e]=i:n.removeAttribute(e))}}}updateDOM(t,e,n){return this.updateLinkDOM(t,e,n),!1}static importDOM(){return{a:t=>({conversion:K,priority:1})}}static importJSON(t){return $().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setURL(t.url).setRel(t.rel||null).setTarget(t.target||null).setTitle(t.title||null)}sanitizeUrl(t){t=X(t);try{const e=new URL(X(t));if(!M.has(e.protocol))return"about:blank"}catch(e){return t}return t}exportJSON(){return{...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),url:this.getURL()}}getURL(){return this.getLatest().__url}setURL(t){const e=this.getWritable();return e.__url=t,e}getTarget(){return this.getLatest().__target}setTarget(t){const e=this.getWritable();return e.__target=t,e}getRel(){return this.getLatest().__rel}setRel(t){const e=this.getWritable();return e.__rel=t,e}getTitle(){return this.getLatest().__title}setTitle(t){const e=this.getWritable();return e.__title=t,e}insertNewAfter(t,e=!0){const n=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.isParentOf(r)&&this.isParentOf(i)&&e.getTextContent().length>0}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")||this.__url.startsWith("http://")}shouldMergeAdjacentLink(t){return this.getType()===t.getType()&&this.__url===t.__url&&this.__target===t.__target&&this.__rel===t.__rel&&this.__title===t.__title}}function J(t){const e=x(t,"next");return[e,e.getFlipped()]}function W(t,e){for(const n of e)if(n.origin.isAttached()){const e=k(n);return void b(t,e)}}function B(t){const e=g();let n=null,i=null;function s(){u(e)&&(W(e.anchor,n),W(e.focus,i),d(e))}u(e)&&(n=J(e.anchor),i=J(e.focus));let l=!1;for(const e of _(t,"next")){const n=e.origin;if(p(n)&&!n.isInline()){const i=n.getChildren();if(i.length>0){const e=o(t);e.append(...i),n.append(e),l=!0}r(n,m(e),{$shouldSplit:()=>!1})}}function a(t,e,n){const[r,i]=t,s=t=>v(t)&&t.origin.is(e);if(!s(r)&&!s(i))return t;const l=k(_(n,"next"));return[l,l.getFlipped()]}if(t.isAttached()){const e=t.getPreviousSibling();if(z(e)&&e.shouldMergeAdjacentLink(t))return n&&(n=a(n,e,t)),i&&(i=a(i,e,t)),e.append(...t.getChildren()),t.remove(),void s();const r=t.getNextSibling();z(r)&&t.shouldMergeAdjacentLink(r)&&(n&&(n=a(n,t,r)),i&&(i=a(i,t,r)),t.append(...r.getChildren()),r.remove(),l=!0)}if(l){if(!t.canBeEmpty()&&t.isEmpty()){const e=t.getParent();t.remove(),e&&e.isEmpty()&&e.remove()}s()}}function K(t){let n=null;if(e(t)){const e=t.textContent;(null!==e&&""!==e||t.children.length>0)&&(n=$(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}))}return{node:n}}function $(t="",e){return a(new F(t,e))}function z(t){return t instanceof F}class j extends F{__isUnlinked;constructor(t="",e={},n){super(t,e,n),this.__isUnlinked=void 0!==e.isUnlinked&&null!==e.isUnlinked&&e.isUnlinked}afterCloneFrom(t){super.afterCloneFrom(t),this.__isUnlinked=t.__isUnlinked}static getType(){return"autolink"}static clone(t){return new j(t.__url,{isUnlinked:t.__isUnlinked,rel:t.__rel,target:t.__target,title:t.__title},t.__key)}shouldMergeAdjacentLink(t){return!1}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(t){const e=this.getWritable();return e.__isUnlinked=t,e}createDOM(t){return this.__isUnlinked?document.createElement("span"):super.createDOM(t)}updateDOM(t,e,n){return super.updateDOM(t,e,n)||t.__isUnlinked!==this.__isUnlinked}static importJSON(t){return H().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setIsUnlinked(t.isUnlinked||!1)}static importDOM(){return null}exportJSON(){return{...super.exportJSON(),isUnlinked:this.__isUnlinked}}insertNewAfter(t,e=!0){const n=H(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(n,e),n}}function H(t="",e){return a(new j(t,e))}function G(t){return t instanceof j}const Z=c("TOGGLE_LINK_COMMAND");function q(t,e){if("element"===t.type){const n=t.getNode();p(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 Q(t,e={}){let r;if(t&&"object"==typeof t){const{url:n,...i}=t;r=n,e={...i,...e}}else r=t;const{target:i,title:s}=e,l=void 0===e.rel?"noreferrer":e.rel,a=g();if(null===a||!u(a)&&!f(a))return;if(f(a)){const t=a.getNodes();if(0===t.length)return;return void t.forEach(t=>{if(null===r){const e=n(t,t=>!G(t)&&z(t));e&&(e.insertBefore(t),0===e.getChildren().length&&e.remove())}else{const e=n(t,t=>!G(t)&&z(t));if(e)e.setURL(r),void 0!==i&&e.setTarget(i),void 0!==l&&e.setRel(l);else{const e=$(r,{rel:l,target:i});t.insertBefore(e),e.append(t)}}})}if(a.isCollapsed()&&null===r)for(const t of a.getNodes()){const e=n(t,t=>!G(t)&&z(t));return void(null!==e&&(e.getChildren().forEach(t=>{e.insertBefore(t)}),e.remove()))}const c=a.extract();if(null===r){const t=new Set;return void c.forEach(e=>{const r=n(e,t=>!G(t)&&z(t));if(null!==r){const e=r.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())||p(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))}}}(r,c),t.add(e)}})}const _=new Set,m=t=>{_.has(t.getKey())||(_.add(t.getKey()),t.setURL(r),void 0!==i&&t.setTarget(i),void 0!==l&&t.setRel(l),void 0!==s&&t.setTitle(s))};if(1===c.length){const t=c[0],e=n(t,z);if(null!==e)return m(e)}!function(t){const e=g();if(!u(e))return t();const n=d(e),r=n.isBackward(),i=q(n.anchor,r?-1:0),s=q(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")}h(d(e))}}}(()=>{let t=null;for(const e of c){if(!e.isAttached())continue;const o=n(e,z);if(o){m(o);continue}if(p(e)){if(!e.isInline())continue;if(z(e)){if(!(G(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 u=e.getPreviousSibling();z(u)&&u.is(t)?u.append(e):(t=$(r,{rel:l,target:i,title:s}),e.insertAfter(t),t.append(e))}})}const V=/^\+?[0-9\s()-]{5,}$/;function X(t){return t.match(/^[a-z][a-z0-9+.-]*:/i)||t.match(/^[/#.]/)?t:t.includes("@")?`mailto:${t}`:V.test(t)?`tel:${t}`:`https://${t}`}function Y(t,e){return i(t.registerNodeTransform(F,B),t.registerCommand(Z,t=>{const n=e.validateUrl.peek(),r=e.attributes.peek();if(null===t)return Q(null),!0;if("string"==typeof t)return!(void 0!==n&&!n(t))&&(Q(t,r),!0);{const{url:e,target:n,rel:i,title:s}=t;return Q(e,{...r,rel:i,target:n,title:s}),!0}},L),w(()=>{const n=e.validateUrl.value;if(!n)return;const r=e.attributes.value;return t.registerCommand(C,e=>{const i=g();if(!u(i)||i.isCollapsed()||!s(e,ClipboardEvent))return!1;if(null===e.clipboardData)return!1;const l=e.clipboardData.getData("text");return!!n(l)&&(!i.getNodes().some(t=>p(t))&&(t.dispatchCommand(Z,{...r,url:l}),e.preventDefault(),!0))},S)}))}const tt=U({build:(t,e,n)=>I(e),config:{attributes:void 0,validateUrl:void 0},mergeConfig(t,e){const n=T(t,e);return t.attributes&&(n.attributes=T(t.attributes,n.attributes)),n},name:"@lexical/link/Link",nodes:()=>[F],register:(t,e,n)=>Y(t,n.getOutput())});function et(t,r,i={}){const s=i=>{const s=i.target;if(!y(s))return;const l=N(s);if(null===l)return;let o=null,a=null;if(l.update(()=>{const t=R(s);if(null!==t){const i=n(t,p);if(!r.disabled.peek())if(z(i))o=i.sanitizeUrl(i.getURL()),a=i.getTarget();else{const t=function(t,e){let n=t;for(;null!=n;){if(e(n))return n;n=n.parentNode}return null}(s,e);null!==t&&(o=t.href,a=t.target)}}}),null===o||""===o)return;const c=t.getEditorState().read(g,{editor:t});if(u(c)&&!c.isCollapsed())return void i.preventDefault();const f="auxclick"===i.type&&1===i.button;window.open(o,r.newTab.peek()||f||i.metaKey||i.ctrlKey||"_blank"===a?"_blank":"_self"),i.preventDefault()},l=t=>{1===t.button&&s(t)};return t.registerRootListener(t=>{if(t)return t.addEventListener("click",s,i),t.addEventListener("mouseup",l,i),()=>{t.removeEventListener("click",s),t.removeEventListener("mouseup",l)}})}const nt=U({build:(t,e,n)=>I(e),config:O({disabled:!1,newTab:!1}),dependencies:[tt],name:"@lexical/link/ClickableLink",register:(t,e,n)=>et(t,n.getOutput())});function rt(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])}}}function it(t,e){for(let n=0;n<e.length;n++){const r=e[n](t);if(r)return r}return null}const st=/[.,;\s]/;function lt(t,e){return e.test(t)}function ot(t,e){return lt(t[t.length-1],e)}function ut(t,e){return lt(t[0],e)}function at(t,e){let n=t.getPreviousSibling();return p(n)&&(n=n.getLastDescendant()),null===n||D(n)||A(n)&&ot(n.getTextContent(),e)}function ct(t,e){let n=t.getNextSibling();return p(n)&&(n=n.getFirstDescendant()),null===n||D(n)||A(n)&&ut(n.getTextContent(),e)}function gt(t,e,n,r,i){if(!(t>0?lt(r[t-1],n):at(i[0],n)))return!1;return e<r.length?lt(r[e],n):ct(i[i.length-1],n)}function ft(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 dt(t,e,n,r){const i=H(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=E(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(A):void 0,h=E(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 ht(t,e,n,r){const i=t.getChildren(),s=i.length;for(let e=0;e<s;e++){const r=i[e];if(!A(r)||!r.isSimpleText())return _t(t),void n(null,t.getURL())}const l=t.getTextContent(),o=it(l,e);if(null===o||o.text!==l)return _t(t),void n(null,t.getURL());if(!at(t,r)||!ct(t,r))return _t(t),void n(null,t.getURL());const u=t.getURL();if(u!==o.url&&(t.setURL(o.url),n(o.url,u)),o.attributes){const e=t.getRel();e!==o.attributes.rel&&(t.setRel(o.attributes.rel||null),n(o.attributes.rel||null,e));const r=t.getTarget();r!==o.attributes.target&&(t.setTarget(o.attributes.target||null),n(o.attributes.target||null,r))}}function _t(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 pt={changeHandlers:[],excludeParents:[],matchers:[],separatorRegex:st};function mt(t,e=pt){const{matchers:n,changeHandlers:r,excludeParents:s,separatorRegex:l=st}=e,o=(t,e)=>{for(const n of r)n(t,e)};return i(t.registerNodeTransform(P,t=>{const e=t.getParentOrThrow(),r=t.getPreviousSibling();if(G(e))ht(e,n,o,l);else if(!z(e)&&!s.some(t=>t(e))){if(t.isSimpleText()&&(ut(t.getTextContent(),l)||!G(r))){const e=function(t){const e=[t];let n=t.getNextSibling();for(;null!==n&&A(n)&&n.isSimpleText()&&(e.push(n),!/[\s]/.test(n.getTextContent()));)n=n.getNextSibling();return e}(t);!function(t,e,n,r){for(const e of t){const t=e.getParent();if(G(t)&&!t.getIsUnlinked())return}let i=[...t];const s=i.map(t=>t.getTextContent()).join("");let l,o=s,u=0;for(;(l=it(o,e))&&null!==l;){const t=l.index,e=t+l.length;if(gt(u+t,u+e,r,s,i)){const[r,,s,a]=ft(i,u+t,u+e);let c=!1;for(const t of s){const e=t.getParent();if(G(e)&&!e.getIsUnlinked()){c=!0;break}}if(c){u+=e,o=o.substring(e);continue}const g=dt(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,o,l)}!function(t,e,n,r){const i=t.getParent(),s=t.getPreviousSibling(),l=t.getNextSibling(),o=t.getTextContent();if(!G(i)||i.getIsUnlinked()){if(G(s)&&!s.getIsUnlinked()&&s.is(t.getPreviousSibling())&&t.getParent()===s.getParent()){if(!ut(o,r))return _t(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=it(i,e);null!==l&&l.text===i&&(s.append(t),ht(s,e,n,r),n(null,s.getURL()))}}var u;!G(l)||l.getIsUnlinked()||ot(o,r)||l.is(t.getNextSibling())&&t.getParent()===l.getParent()&&(_t(l),n(null,l.getURL()))}}(t,n,o,l)}}),t.registerCommand(Z,t=>{const e=g();if(null!==t||!u(e))return!1;return e.extract().forEach(t=>{const e=t.getParent();G(e)&&(e.setIsUnlinked(!e.getIsUnlinked()),e.markDirty())}),!1},S))}const xt=U({config:pt,dependencies:[tt],mergeConfig(t,e){const n=T(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:[j],register:mt}),kt=Q;export{H as $createAutoLinkNode,$ as $createLinkNode,G as $isAutoLinkNode,z as $isLinkNode,Q as $toggleLink,xt as AutoLinkExtension,j as AutoLinkNode,nt as ClickableLinkExtension,tt as LinkExtension,F as LinkNode,Z as TOGGLE_LINK_COMMAND,rt as createLinkMatcherWithRegExp,X as formatUrl,mt as registerAutoLink,et as registerClickableLink,Y as registerLink,kt as toggleLink};
|
package/package.json
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
"link"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.44.0",
|
|
12
12
|
"main": "LexicalLink.js",
|
|
13
13
|
"types": "index.d.ts",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@lexical/extension": "0.
|
|
16
|
-
"@lexical/utils": "0.
|
|
17
|
-
"lexical": "0.
|
|
15
|
+
"@lexical/extension": "0.44.0",
|
|
16
|
+
"@lexical/utils": "0.44.0",
|
|
17
|
+
"lexical": "0.44.0"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|