@lobehub/editor 4.9.8 → 4.9.9
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/es/{ReactSlashPlugin-BZ0TZ1oy.js → ReactSlashPlugin-DEcBg9nL.js} +44 -44
- package/es/headless.js +733 -33
- package/es/index.js +219 -218
- package/es/react.js +1 -1
- package/package.json +1 -1
package/es/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $ as DOM_TEXT_TYPE, A as $createCodeMirrorNode, At as createDebugLogger, B as Editor, C as $createCodeNode$1, Ct as CONTROL_OR_META, Dt as KeyEnum, E as CodeNode$1, Et as HotkeyScopeEnum, F as $isCursorNode, Ft as init_debug, G as kernel_exports, Gt as INodeHelper, H as DataSource, I as CardLikeElementNode, It as prodSafeLogger, J as $getNearestNodeFromDOMNode, K as $closest, Kt as init_helper, M as CodeMirrorNode, Mt as debugLoggers, N as $createCursorNode, Nt as debug_exports, Ot as init_hotkey, P as $isCardLikeElementNode, Pt as devConsole, Q as DOM_ELEMENT_TYPE, R as cursorNodeSerialized, S as formatUrl, St as init_registerHotkey, Tt as HotkeyEnum, U as Kernel, V as resetRandomKey, W as init_kernel, X as DOM_DOCUMENT_FRAGMENT_TYPE, Y as $getNodeFromDOMNode, Yt as __toCommonJS, Z as DOM_DOCUMENT_TYPE, _ as AutoLinkNode, _t as unregisterEditorKernel, a as $createMathBlockNode, at as generateEditorId, b as LinkNode, bt as HOVER_COMMAND, c as MathBlockNode, ct as getNodeKeyFromDOMNode, dt as isDOMNode, et as EDITOR_THEME_KEY, f as LinkHighlightNode, ft as isDocumentFragment, g as $toggleLink, gt as registerEditorKernel, h as $isLinkNode, ht as reconcileDecorator, it as genServiceId, j as $isCodeMirrorNode, jt as debugLogger, kt as browserDebug, l as MathInlineNode, lt as getParentElement, m as $createLinkNode, mt as noop, nt as compareNodeOrder, o as $createMathInlineNode, ot as getKernelFromEditor, pt as moment, q as $closestNodeType, rt as createEmptyEditorState, s as $isMathNode, st as getKernelFromEditorConfig, tt as assert, u as $createLinkHighlightNode, ut as init_utils, v as HOVER_LINK_COMMAND, vt as KernelPlugin, wt as init_sys, x as TOGGLE_LINK_COMMAND, xt as getHotkeyById, y as HOVER_OUT_LINK_COMMAND, yt as init_plugin } from "./style-CLtp6okE.js";
|
|
2
|
-
import { A as detectLanguage, B as INodePlugin, C as ReactPlainText, D as useTranslation, E as ReactMarkdownPlugin, F as GET_MARKDOWN_SELECTION_COMMAND, G as idToChar, H as $cloneNode, I as INSERT_MARKDOWN_COMMAND, J as useLexicalEditor, K as INSERT_HEADING_COMMAND, L as isPunctuationChar, M as MARKDOWN_READER_LEVEL_HIGH, N as MARKDOWN_READER_LEVEL_NORMAL, O as MarkdownPlugin, P as MARKDOWN_WRITER_LEVEL_MAX, R as ILitexmlService, S as registerCodeInlineCommand, T as CommonPlugin, U as $parseSerializedNodeImpl, V as INodeService, W as charToId, X as useLexicalComposerContext, Y as ReactEditor, Z as LexicalErrorBoundary, _ as
|
|
2
|
+
import { A as detectLanguage, B as INodePlugin, C as ReactPlainText, D as useTranslation, E as ReactMarkdownPlugin, F as GET_MARKDOWN_SELECTION_COMMAND, G as idToChar, H as $cloneNode, I as INSERT_MARKDOWN_COMMAND, J as useLexicalEditor, K as INSERT_HEADING_COMMAND, L as isPunctuationChar, M as MARKDOWN_READER_LEVEL_HIGH, N as MARKDOWN_READER_LEVEL_NORMAL, O as MarkdownPlugin, P as MARKDOWN_WRITER_LEVEL_MAX, R as ILitexmlService, S as registerCodeInlineCommand, T as CommonPlugin, U as $parseSerializedNodeImpl, V as INodeService, W as charToId, X as useLexicalComposerContext, Y as ReactEditor, Z as LexicalErrorBoundary, _ as extractUrlFromText, a as ReactMentionPlugin, c as INSERT_LINK_HIGHLIGHT_COMMAND, d as bundledLanguagesInfo, f as CodeblockPlugin, g as registerCheckList, h as INSERT_CHECK_LIST_COMMAND, i as SlashPlugin, j as IMarkdownShortCutService, k as detectCodeLanguage, l as registerLinkHighlightCommand, m as getCodeLanguageByInput, n as ReactSlashOption, o as MentionPlugin, p as UPDATE_CODEBLOCK_LANG, q as INSERT_QUOTE_COMMAND, r as SlashMenu, s as INSERT_MENTION_COMMAND, t as ReactSlashPlugin, u as useLexicalNodeSelection, v as getSelectedNode, w as ReactEditorContent, x as INSERT_CODEINLINE_COMMAND, y as sanitizeUrl, z as LitexmlService } from "./ReactSlashPlugin-DEcBg9nL.js";
|
|
3
3
|
import { S as DiffNode, _ as PlaceholderNode, a as styles$16, b as HorizontalRuleNode, c as ImageNode, d as BlockImageNode, f as styles$15, g as PlaceholderBlockNode, h as FileNode, i as imageBroken, l as $createBlockImageNode, m as $isFileNode, n as styles$18, o as $createImageNode, p as $createFileNode, r as styles$17, s as $isImageNode, t as styles$19, u as $isBlockImageNode, v as $createHorizontalRuleNode, x as $createDiffNode, y as $isHorizontalRuleNode } from "./style-D-dIPHv5.js";
|
|
4
4
|
import { $computeTableMapSkipCellCheck, $createTableNodeWithDimensions, $createTableSelection, $deleteTableColumnAtSelection, $deleteTableRowAtSelection, $findTableNode, $getElementForTableNode, $getNodeTriplet, $getTableAndElementByKey, $getTableCellNodeFromLexicalNode, $getTableColumnIndexFromTableCellNode, $getTableNodeFromLexicalNodeOrThrow, $getTableRowIndexFromTableCellNode, $insertTableColumnAtSelection, $insertTableRowAtSelection, $isTableCellNode, $isTableNode, $isTableRowNode, $isTableSelection, $mergeCells, $unmergeCell, TableCellHeaderStates, TableCellNode, TableNode, TableNode as TableNode$1, TableRowNode, getDOMCellFromTarget, getTableElement, getTableObserverFromTableElement, registerTableCellUnmergeTransform, registerTablePlugin, registerTableSelectionObserver, setScrollableTablesActive } from "@lexical/table";
|
|
5
5
|
import { debounce } from "es-toolkit/compat";
|
|
@@ -1270,6 +1270,223 @@ const HRPlugin = class extends KernelPlugin {
|
|
|
1270
1270
|
}
|
|
1271
1271
|
};
|
|
1272
1272
|
//#endregion
|
|
1273
|
+
//#region src/plugins/link/command/index.ts
|
|
1274
|
+
const INSERT_LINK_COMMAND = createCommand("INSERT_LINK_COMMAND");
|
|
1275
|
+
const UPDATE_LINK_TEXT_COMMAND = createCommand("UPDATE_LINK_TEXT_COMMAND");
|
|
1276
|
+
function registerLinkCommand(editor) {
|
|
1277
|
+
return mergeRegister(editor.registerCommand(INSERT_LINK_COMMAND, (payload) => {
|
|
1278
|
+
const { url, title = url } = payload;
|
|
1279
|
+
editor.update(() => {
|
|
1280
|
+
const linkNode = $createLinkNode(url, { title });
|
|
1281
|
+
const textNode = $createTextNode(title);
|
|
1282
|
+
linkNode.append(textNode);
|
|
1283
|
+
$insertNodes([linkNode]);
|
|
1284
|
+
});
|
|
1285
|
+
return false;
|
|
1286
|
+
}, COMMAND_PRIORITY_EDITOR), editor.registerCommand(UPDATE_LINK_TEXT_COMMAND, (payload) => {
|
|
1287
|
+
const { key, text } = payload;
|
|
1288
|
+
editor.update(() => {
|
|
1289
|
+
const linkNode = $getNodeByKey(key);
|
|
1290
|
+
if (linkNode) {
|
|
1291
|
+
const newLinkNode = $createLinkNode(linkNode.getURL(), { title: text });
|
|
1292
|
+
const textNode = $createTextNode(text);
|
|
1293
|
+
newLinkNode.append(textNode);
|
|
1294
|
+
linkNode?.replace(newLinkNode);
|
|
1295
|
+
newLinkNode.select(1);
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
return false;
|
|
1299
|
+
}, COMMAND_PRIORITY_EDITOR));
|
|
1300
|
+
}
|
|
1301
|
+
//#endregion
|
|
1302
|
+
//#region src/plugins/link/service/i-link-service.ts
|
|
1303
|
+
const ILinkService = genServiceId("LinkService");
|
|
1304
|
+
var LinkService = class extends EventEmitter {
|
|
1305
|
+
constructor(..._args) {
|
|
1306
|
+
super(..._args);
|
|
1307
|
+
this._enableLinkToolbar = true;
|
|
1308
|
+
}
|
|
1309
|
+
get enableLinkToolbar() {
|
|
1310
|
+
return this._enableLinkToolbar;
|
|
1311
|
+
}
|
|
1312
|
+
setLinkToolbar(enable) {
|
|
1313
|
+
this._enableLinkToolbar = enable;
|
|
1314
|
+
this.emit("linkToolbarChange", enable);
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
//#endregion
|
|
1318
|
+
//#region src/plugins/link/plugin/registry.ts
|
|
1319
|
+
init_hotkey();
|
|
1320
|
+
function registerLinkCommands(editor, kernel, options) {
|
|
1321
|
+
const { validateUrl, attributes, enableHotkey = true } = options || {};
|
|
1322
|
+
const state = { isLink: false };
|
|
1323
|
+
const registrations = [editor.registerUpdateListener(() => {
|
|
1324
|
+
const selection = editor.getEditorState().read(() => $getSelection());
|
|
1325
|
+
if (!selection) return;
|
|
1326
|
+
if ($isRangeSelection(selection)) editor.getEditorState().read(() => {
|
|
1327
|
+
const node = getSelectedNode(selection);
|
|
1328
|
+
state.isLink = $isLinkNode(node.getParent()) || $isLinkNode(node);
|
|
1329
|
+
});
|
|
1330
|
+
else state.isLink = false;
|
|
1331
|
+
}), editor.registerCommand(TOGGLE_LINK_COMMAND, (payload) => {
|
|
1332
|
+
if (payload === null) {
|
|
1333
|
+
$toggleLink(payload);
|
|
1334
|
+
return true;
|
|
1335
|
+
} else if (typeof payload === "string") {
|
|
1336
|
+
if (validateUrl === void 0 || validateUrl(payload)) {
|
|
1337
|
+
$toggleLink(payload, attributes);
|
|
1338
|
+
return true;
|
|
1339
|
+
}
|
|
1340
|
+
return false;
|
|
1341
|
+
} else {
|
|
1342
|
+
const { url, target, rel, title } = payload;
|
|
1343
|
+
$toggleLink(url, {
|
|
1344
|
+
...attributes,
|
|
1345
|
+
rel,
|
|
1346
|
+
target,
|
|
1347
|
+
title
|
|
1348
|
+
});
|
|
1349
|
+
return true;
|
|
1350
|
+
}
|
|
1351
|
+
}, COMMAND_PRIORITY_LOW)];
|
|
1352
|
+
registrations.push(kernel.registerHotkey(HotkeyEnum.Link, () => {
|
|
1353
|
+
if (state.isLink) {
|
|
1354
|
+
editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
let nextUrl = sanitizeUrl("https://");
|
|
1358
|
+
let expandTo = null;
|
|
1359
|
+
editor.getEditorState().read(() => {
|
|
1360
|
+
const selection = $getSelection();
|
|
1361
|
+
if ($isRangeSelection(selection)) if (!selection.isCollapsed()) {
|
|
1362
|
+
const maybeUrl = formatUrl(selection.getTextContent().trim());
|
|
1363
|
+
if (validateUrl?.(maybeUrl)) nextUrl = maybeUrl;
|
|
1364
|
+
} else {
|
|
1365
|
+
const found = extractUrlFromText(selection.anchor.getNode().getTextContent());
|
|
1366
|
+
if (found && validateUrl?.(formatUrl(found.url))) {
|
|
1367
|
+
nextUrl = formatUrl(found.url);
|
|
1368
|
+
expandTo = {
|
|
1369
|
+
index: found.index,
|
|
1370
|
+
length: found.length
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
});
|
|
1375
|
+
editor.update(() => {
|
|
1376
|
+
if (expandTo) {
|
|
1377
|
+
const selection = $getSelection();
|
|
1378
|
+
if ($isRangeSelection(selection)) {
|
|
1379
|
+
const anchorNode = selection.anchor.getNode();
|
|
1380
|
+
selection.anchor.set(anchorNode.getKey(), expandTo.index, "text");
|
|
1381
|
+
selection.focus.set(anchorNode.getKey(), expandTo.index + expandTo.length, "text");
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
editor.dispatchCommand(TOGGLE_LINK_COMMAND, nextUrl);
|
|
1385
|
+
});
|
|
1386
|
+
}, {
|
|
1387
|
+
enabled: enableHotkey,
|
|
1388
|
+
preventDefault: true,
|
|
1389
|
+
stopPropagation: true
|
|
1390
|
+
}));
|
|
1391
|
+
return mergeRegister(...registrations);
|
|
1392
|
+
}
|
|
1393
|
+
//#endregion
|
|
1394
|
+
//#region src/plugins/link/plugin/index.ts
|
|
1395
|
+
init_helper();
|
|
1396
|
+
init_plugin();
|
|
1397
|
+
const LinkPlugin = class extends KernelPlugin {
|
|
1398
|
+
static {
|
|
1399
|
+
this.pluginName = "LinkPlugin";
|
|
1400
|
+
}
|
|
1401
|
+
constructor(kernel, config) {
|
|
1402
|
+
super();
|
|
1403
|
+
this.kernel = kernel;
|
|
1404
|
+
this.config = config;
|
|
1405
|
+
this.linkRegex = /^https?:\/\/\S+$/;
|
|
1406
|
+
this.service = new LinkService();
|
|
1407
|
+
kernel.registerNodes([LinkNode, AutoLinkNode]);
|
|
1408
|
+
kernel.registerService(ILinkService, this.service);
|
|
1409
|
+
if (config?.theme) kernel.registerThemes(config.theme);
|
|
1410
|
+
if (config?.linkRegex) this.linkRegex = config.linkRegex;
|
|
1411
|
+
}
|
|
1412
|
+
onInit(editor) {
|
|
1413
|
+
this.register(registerLinkCommand(editor));
|
|
1414
|
+
this.register(registerLinkCommands(editor, this.kernel, {
|
|
1415
|
+
attributes: this.config?.attributes,
|
|
1416
|
+
enableHotkey: this.config?.enableHotkey,
|
|
1417
|
+
validateUrl: this.config?.validateUrl
|
|
1418
|
+
}));
|
|
1419
|
+
this.register(editor.registerCommand(PASTE_COMMAND, (payload) => {
|
|
1420
|
+
const { clipboardData } = payload;
|
|
1421
|
+
if (clipboardData && clipboardData.types && clipboardData.types.length === 1 && clipboardData.types[0] === "text/plain") {
|
|
1422
|
+
const data = clipboardData.getData("text/plain").trim();
|
|
1423
|
+
if (this.linkRegex.test(data)) {
|
|
1424
|
+
payload.stopImmediatePropagation();
|
|
1425
|
+
payload.preventDefault();
|
|
1426
|
+
editor.dispatchCommand(INSERT_LINK_COMMAND, { url: data });
|
|
1427
|
+
return true;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return false;
|
|
1431
|
+
}, COMMAND_PRIORITY_NORMAL));
|
|
1432
|
+
this.registerMarkdown();
|
|
1433
|
+
this.registerLiteXml();
|
|
1434
|
+
}
|
|
1435
|
+
registerLiteXml() {
|
|
1436
|
+
const litexmlService = this.kernel.requireService(ILitexmlService);
|
|
1437
|
+
if (!litexmlService) return;
|
|
1438
|
+
litexmlService.registerXMLWriter(LinkNode.getType(), (node, ctx) => {
|
|
1439
|
+
if ($isLinkNode(node)) {
|
|
1440
|
+
const attributes = { href: node.getURL() };
|
|
1441
|
+
return ctx.createXmlNode("a", attributes);
|
|
1442
|
+
}
|
|
1443
|
+
return false;
|
|
1444
|
+
});
|
|
1445
|
+
litexmlService.registerXMLReader("a", (xmlNode, children) => {
|
|
1446
|
+
return [INodeHelper.createElementNode("link", {
|
|
1447
|
+
children,
|
|
1448
|
+
direction: "ltr",
|
|
1449
|
+
format: "",
|
|
1450
|
+
indent: 0,
|
|
1451
|
+
type: "link",
|
|
1452
|
+
url: xmlNode.getAttribute("href") || "",
|
|
1453
|
+
version: 1
|
|
1454
|
+
})];
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
registerMarkdown() {
|
|
1458
|
+
this.kernel.requireService(IMarkdownShortCutService)?.registerMarkdownShortCut({
|
|
1459
|
+
regExp: /\[([^[]+)]\(([^\s()]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?\)\s?$/,
|
|
1460
|
+
replace: (textNode, match) => {
|
|
1461
|
+
const [, linkText, linkUrl, linkTitle] = match;
|
|
1462
|
+
const linkNode = $createLinkNode(linkUrl, { title: linkTitle });
|
|
1463
|
+
const linkTextNode = $createTextNode(linkText);
|
|
1464
|
+
linkTextNode.setFormat(textNode.getFormat());
|
|
1465
|
+
linkNode.append(linkTextNode);
|
|
1466
|
+
textNode.replace(linkNode);
|
|
1467
|
+
return linkTextNode;
|
|
1468
|
+
},
|
|
1469
|
+
trigger: ")",
|
|
1470
|
+
type: "text-match"
|
|
1471
|
+
});
|
|
1472
|
+
this.kernel.requireService(IMarkdownShortCutService)?.registerMarkdownWriter(LinkNode.getType(), (ctx, node) => {
|
|
1473
|
+
if ($isLinkNode(node)) ctx.wrap("[", `](${node.getURL()})`);
|
|
1474
|
+
});
|
|
1475
|
+
this.kernel.requireService(IMarkdownShortCutService)?.registerMarkdownReader("link", (node, children) => {
|
|
1476
|
+
return [INodeHelper.createElementNode("link", {
|
|
1477
|
+
children,
|
|
1478
|
+
direction: "ltr",
|
|
1479
|
+
format: "",
|
|
1480
|
+
indent: 0,
|
|
1481
|
+
title: node.title || void 0,
|
|
1482
|
+
type: "link",
|
|
1483
|
+
url: node.url || "",
|
|
1484
|
+
version: 1
|
|
1485
|
+
})];
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
};
|
|
1489
|
+
//#endregion
|
|
1273
1490
|
//#region src/utils/cx.ts
|
|
1274
1491
|
const cx$1 = (...classNames) => classNames.filter(Boolean).join(" ");
|
|
1275
1492
|
//#endregion
|
|
@@ -1940,6 +2157,7 @@ const normalizeLegacyEditorData = (editorData) => {
|
|
|
1940
2157
|
const DEFAULT_HEADLESS_EDITOR_PLUGINS = [
|
|
1941
2158
|
[CommonPlugin, { enableHotkey: false }],
|
|
1942
2159
|
MarkdownPlugin,
|
|
2160
|
+
[LinkPlugin, { enableHotkey: false }],
|
|
1943
2161
|
CodePlugin,
|
|
1944
2162
|
HeadlessCodeblockPlugin,
|
|
1945
2163
|
HRPlugin,
|
|
@@ -4979,223 +5197,6 @@ const ReactImagePlugin = ({ theme, className, defaultBlockImage, handleUpload, n
|
|
|
4979
5197
|
};
|
|
4980
5198
|
ReactImagePlugin.displayName = "ReactImagePlugin";
|
|
4981
5199
|
//#endregion
|
|
4982
|
-
//#region src/plugins/link/command/index.ts
|
|
4983
|
-
const INSERT_LINK_COMMAND = createCommand("INSERT_LINK_COMMAND");
|
|
4984
|
-
const UPDATE_LINK_TEXT_COMMAND = createCommand("UPDATE_LINK_TEXT_COMMAND");
|
|
4985
|
-
function registerLinkCommand(editor) {
|
|
4986
|
-
return mergeRegister(editor.registerCommand(INSERT_LINK_COMMAND, (payload) => {
|
|
4987
|
-
const { url, title = url } = payload;
|
|
4988
|
-
editor.update(() => {
|
|
4989
|
-
const linkNode = $createLinkNode(url, { title });
|
|
4990
|
-
const textNode = $createTextNode(title);
|
|
4991
|
-
linkNode.append(textNode);
|
|
4992
|
-
$insertNodes([linkNode]);
|
|
4993
|
-
});
|
|
4994
|
-
return false;
|
|
4995
|
-
}, COMMAND_PRIORITY_EDITOR), editor.registerCommand(UPDATE_LINK_TEXT_COMMAND, (payload) => {
|
|
4996
|
-
const { key, text } = payload;
|
|
4997
|
-
editor.update(() => {
|
|
4998
|
-
const linkNode = $getNodeByKey(key);
|
|
4999
|
-
if (linkNode) {
|
|
5000
|
-
const newLinkNode = $createLinkNode(linkNode.getURL(), { title: text });
|
|
5001
|
-
const textNode = $createTextNode(text);
|
|
5002
|
-
newLinkNode.append(textNode);
|
|
5003
|
-
linkNode?.replace(newLinkNode);
|
|
5004
|
-
newLinkNode.select(1);
|
|
5005
|
-
}
|
|
5006
|
-
});
|
|
5007
|
-
return false;
|
|
5008
|
-
}, COMMAND_PRIORITY_EDITOR));
|
|
5009
|
-
}
|
|
5010
|
-
//#endregion
|
|
5011
|
-
//#region src/plugins/link/service/i-link-service.ts
|
|
5012
|
-
const ILinkService = genServiceId("LinkService");
|
|
5013
|
-
var LinkService = class extends EventEmitter {
|
|
5014
|
-
constructor(..._args) {
|
|
5015
|
-
super(..._args);
|
|
5016
|
-
this._enableLinkToolbar = true;
|
|
5017
|
-
}
|
|
5018
|
-
get enableLinkToolbar() {
|
|
5019
|
-
return this._enableLinkToolbar;
|
|
5020
|
-
}
|
|
5021
|
-
setLinkToolbar(enable) {
|
|
5022
|
-
this._enableLinkToolbar = enable;
|
|
5023
|
-
this.emit("linkToolbarChange", enable);
|
|
5024
|
-
}
|
|
5025
|
-
};
|
|
5026
|
-
//#endregion
|
|
5027
|
-
//#region src/plugins/link/plugin/registry.ts
|
|
5028
|
-
init_hotkey();
|
|
5029
|
-
function registerLinkCommands(editor, kernel, options) {
|
|
5030
|
-
const { validateUrl, attributes, enableHotkey = true } = options || {};
|
|
5031
|
-
const state = { isLink: false };
|
|
5032
|
-
const registrations = [editor.registerUpdateListener(() => {
|
|
5033
|
-
const selection = editor.getEditorState().read(() => $getSelection());
|
|
5034
|
-
if (!selection) return;
|
|
5035
|
-
if ($isRangeSelection(selection)) editor.getEditorState().read(() => {
|
|
5036
|
-
const node = getSelectedNode(selection);
|
|
5037
|
-
state.isLink = $isLinkNode(node.getParent()) || $isLinkNode(node);
|
|
5038
|
-
});
|
|
5039
|
-
else state.isLink = false;
|
|
5040
|
-
}), editor.registerCommand(TOGGLE_LINK_COMMAND, (payload) => {
|
|
5041
|
-
if (payload === null) {
|
|
5042
|
-
$toggleLink(payload);
|
|
5043
|
-
return true;
|
|
5044
|
-
} else if (typeof payload === "string") {
|
|
5045
|
-
if (validateUrl === void 0 || validateUrl(payload)) {
|
|
5046
|
-
$toggleLink(payload, attributes);
|
|
5047
|
-
return true;
|
|
5048
|
-
}
|
|
5049
|
-
return false;
|
|
5050
|
-
} else {
|
|
5051
|
-
const { url, target, rel, title } = payload;
|
|
5052
|
-
$toggleLink(url, {
|
|
5053
|
-
...attributes,
|
|
5054
|
-
rel,
|
|
5055
|
-
target,
|
|
5056
|
-
title
|
|
5057
|
-
});
|
|
5058
|
-
return true;
|
|
5059
|
-
}
|
|
5060
|
-
}, COMMAND_PRIORITY_LOW)];
|
|
5061
|
-
registrations.push(kernel.registerHotkey(HotkeyEnum.Link, () => {
|
|
5062
|
-
if (state.isLink) {
|
|
5063
|
-
editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
|
|
5064
|
-
return;
|
|
5065
|
-
}
|
|
5066
|
-
let nextUrl = sanitizeUrl("https://");
|
|
5067
|
-
let expandTo = null;
|
|
5068
|
-
editor.getEditorState().read(() => {
|
|
5069
|
-
const selection = $getSelection();
|
|
5070
|
-
if ($isRangeSelection(selection)) if (!selection.isCollapsed()) {
|
|
5071
|
-
const maybeUrl = formatUrl(selection.getTextContent().trim());
|
|
5072
|
-
if (validateUrl?.(maybeUrl)) nextUrl = maybeUrl;
|
|
5073
|
-
} else {
|
|
5074
|
-
const found = extractUrlFromText(selection.anchor.getNode().getTextContent());
|
|
5075
|
-
if (found && validateUrl?.(formatUrl(found.url))) {
|
|
5076
|
-
nextUrl = formatUrl(found.url);
|
|
5077
|
-
expandTo = {
|
|
5078
|
-
index: found.index,
|
|
5079
|
-
length: found.length
|
|
5080
|
-
};
|
|
5081
|
-
}
|
|
5082
|
-
}
|
|
5083
|
-
});
|
|
5084
|
-
editor.update(() => {
|
|
5085
|
-
if (expandTo) {
|
|
5086
|
-
const selection = $getSelection();
|
|
5087
|
-
if ($isRangeSelection(selection)) {
|
|
5088
|
-
const anchorNode = selection.anchor.getNode();
|
|
5089
|
-
selection.anchor.set(anchorNode.getKey(), expandTo.index, "text");
|
|
5090
|
-
selection.focus.set(anchorNode.getKey(), expandTo.index + expandTo.length, "text");
|
|
5091
|
-
}
|
|
5092
|
-
}
|
|
5093
|
-
editor.dispatchCommand(TOGGLE_LINK_COMMAND, nextUrl);
|
|
5094
|
-
});
|
|
5095
|
-
}, {
|
|
5096
|
-
enabled: enableHotkey,
|
|
5097
|
-
preventDefault: true,
|
|
5098
|
-
stopPropagation: true
|
|
5099
|
-
}));
|
|
5100
|
-
return mergeRegister(...registrations);
|
|
5101
|
-
}
|
|
5102
|
-
//#endregion
|
|
5103
|
-
//#region src/plugins/link/plugin/index.ts
|
|
5104
|
-
init_helper();
|
|
5105
|
-
init_plugin();
|
|
5106
|
-
const LinkPlugin = class extends KernelPlugin {
|
|
5107
|
-
static {
|
|
5108
|
-
this.pluginName = "LinkPlugin";
|
|
5109
|
-
}
|
|
5110
|
-
constructor(kernel, config) {
|
|
5111
|
-
super();
|
|
5112
|
-
this.kernel = kernel;
|
|
5113
|
-
this.config = config;
|
|
5114
|
-
this.linkRegex = /^https?:\/\/\S+$/;
|
|
5115
|
-
this.service = new LinkService();
|
|
5116
|
-
kernel.registerNodes([LinkNode, AutoLinkNode]);
|
|
5117
|
-
kernel.registerService(ILinkService, this.service);
|
|
5118
|
-
if (config?.theme) kernel.registerThemes(config.theme);
|
|
5119
|
-
if (config?.linkRegex) this.linkRegex = config.linkRegex;
|
|
5120
|
-
}
|
|
5121
|
-
onInit(editor) {
|
|
5122
|
-
this.register(registerLinkCommand(editor));
|
|
5123
|
-
this.register(registerLinkCommands(editor, this.kernel, {
|
|
5124
|
-
attributes: this.config?.attributes,
|
|
5125
|
-
enableHotkey: this.config?.enableHotkey,
|
|
5126
|
-
validateUrl: this.config?.validateUrl
|
|
5127
|
-
}));
|
|
5128
|
-
this.register(editor.registerCommand(PASTE_COMMAND, (payload) => {
|
|
5129
|
-
const { clipboardData } = payload;
|
|
5130
|
-
if (clipboardData && clipboardData.types && clipboardData.types.length === 1 && clipboardData.types[0] === "text/plain") {
|
|
5131
|
-
const data = clipboardData.getData("text/plain").trim();
|
|
5132
|
-
if (this.linkRegex.test(data)) {
|
|
5133
|
-
payload.stopImmediatePropagation();
|
|
5134
|
-
payload.preventDefault();
|
|
5135
|
-
editor.dispatchCommand(INSERT_LINK_COMMAND, { url: data });
|
|
5136
|
-
return true;
|
|
5137
|
-
}
|
|
5138
|
-
}
|
|
5139
|
-
return false;
|
|
5140
|
-
}, COMMAND_PRIORITY_NORMAL));
|
|
5141
|
-
this.registerMarkdown();
|
|
5142
|
-
this.registerLiteXml();
|
|
5143
|
-
}
|
|
5144
|
-
registerLiteXml() {
|
|
5145
|
-
const litexmlService = this.kernel.requireService(ILitexmlService);
|
|
5146
|
-
if (!litexmlService) return;
|
|
5147
|
-
litexmlService.registerXMLWriter(LinkNode.getType(), (node, ctx) => {
|
|
5148
|
-
if ($isLinkNode(node)) {
|
|
5149
|
-
const attributes = { href: node.getURL() };
|
|
5150
|
-
return ctx.createXmlNode("a", attributes);
|
|
5151
|
-
}
|
|
5152
|
-
return false;
|
|
5153
|
-
});
|
|
5154
|
-
litexmlService.registerXMLReader("a", (xmlNode, children) => {
|
|
5155
|
-
return [INodeHelper.createElementNode("link", {
|
|
5156
|
-
children,
|
|
5157
|
-
direction: "ltr",
|
|
5158
|
-
format: "",
|
|
5159
|
-
indent: 0,
|
|
5160
|
-
type: "link",
|
|
5161
|
-
url: xmlNode.getAttribute("href") || "",
|
|
5162
|
-
version: 1
|
|
5163
|
-
})];
|
|
5164
|
-
});
|
|
5165
|
-
}
|
|
5166
|
-
registerMarkdown() {
|
|
5167
|
-
this.kernel.requireService(IMarkdownShortCutService)?.registerMarkdownShortCut({
|
|
5168
|
-
regExp: /\[([^[]+)]\(([^\s()]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?\)\s?$/,
|
|
5169
|
-
replace: (textNode, match) => {
|
|
5170
|
-
const [, linkText, linkUrl, linkTitle] = match;
|
|
5171
|
-
const linkNode = $createLinkNode(linkUrl, { title: linkTitle });
|
|
5172
|
-
const linkTextNode = $createTextNode(linkText);
|
|
5173
|
-
linkTextNode.setFormat(textNode.getFormat());
|
|
5174
|
-
linkNode.append(linkTextNode);
|
|
5175
|
-
textNode.replace(linkNode);
|
|
5176
|
-
return linkTextNode;
|
|
5177
|
-
},
|
|
5178
|
-
trigger: ")",
|
|
5179
|
-
type: "text-match"
|
|
5180
|
-
});
|
|
5181
|
-
this.kernel.requireService(IMarkdownShortCutService)?.registerMarkdownWriter(LinkNode.getType(), (ctx, node) => {
|
|
5182
|
-
if ($isLinkNode(node)) ctx.wrap("[", `](${node.getURL()})`);
|
|
5183
|
-
});
|
|
5184
|
-
this.kernel.requireService(IMarkdownShortCutService)?.registerMarkdownReader("link", (node, children) => {
|
|
5185
|
-
return [INodeHelper.createElementNode("link", {
|
|
5186
|
-
children,
|
|
5187
|
-
direction: "ltr",
|
|
5188
|
-
format: "",
|
|
5189
|
-
indent: 0,
|
|
5190
|
-
title: node.title || void 0,
|
|
5191
|
-
type: "link",
|
|
5192
|
-
url: node.url || "",
|
|
5193
|
-
version: 1
|
|
5194
|
-
})];
|
|
5195
|
-
});
|
|
5196
|
-
}
|
|
5197
|
-
};
|
|
5198
|
-
//#endregion
|
|
5199
5200
|
//#region src/editor-kernel/react/useAnchor.ts
|
|
5200
5201
|
const useAnchor = () => {
|
|
5201
5202
|
const [editor] = useLexicalComposerContext();
|
package/es/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { A as $createCodeMirrorNode, B as Editor$2, Bt as $isRootTextContentEmpty, S as formatUrl, T as $isSelectionInCodeInline, Ut as init_utils, a as $createMathBlockNode, d as $isLinkHighlightNode, h as $isLinkNode, j as $isCodeMirrorNode, mt as noop, o as $createMathInlineNode, x as TOGGLE_LINK_COMMAND } from "./style-CLtp6okE.js";
|
|
2
|
-
import { C as ReactPlainText, E as ReactMarkdownPlugin, Y as ReactEditor, _ as
|
|
2
|
+
import { C as ReactPlainText, E as ReactMarkdownPlugin, Y as ReactEditor, _ as extractUrlFromText, a as ReactMentionPlugin, b as validateUrl, c as INSERT_LINK_HIGHLIGHT_COMMAND, h as INSERT_CHECK_LIST_COMMAND, n as ReactSlashOption, p as UPDATE_CODEBLOCK_LANG, t as ReactSlashPlugin, w as ReactEditorContent, x as INSERT_CODEINLINE_COMMAND, y as sanitizeUrl } from "./ReactSlashPlugin-DEcBg9nL.js";
|
|
3
3
|
import { $createNodeSelection, $createParagraphNode, $getSelection, $isParagraphNode, $isRangeSelection, $isRootOrShadowRoot, $setSelection, CAN_REDO_COMMAND, CAN_UNDO_COMMAND, COMMAND_PRIORITY_LOW, FORMAT_TEXT_COMMAND, REDO_COMMAND, SELECTION_CHANGE_COMMAND, UNDO_COMMAND } from "lexical";
|
|
4
4
|
import { $createQuoteNode, $isHeadingNode, $isQuoteNode } from "@lexical/rich-text";
|
|
5
5
|
import { $findMatchingParent, $getNearestNodeOfType, mergeRegister } from "@lexical/utils";
|
package/package.json
CHANGED