@lobehub/editor 4.23.1 โ 4.23.2
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/editor-kernel/index.js +1 -0
- package/es/editor-kernel/kernel.js +47 -40
- package/es/editor-kernel/react/useLexicalNodeSelection.js +4 -2
- package/es/headless.js +201 -175
- package/es/index.js +5 -2
- package/es/plugins/auto-complete/plugin/index.js +4 -2
- package/es/plugins/block/react/ReactBlockPlugin.js +5 -4
- package/es/plugins/codeblock/command/index.js +8 -6
- package/es/plugins/codeblock/plugin/index.js +4 -2
- package/es/plugins/codeblock/react/ReactCodeblockPlugin.js +2 -1
- package/es/plugins/codemirror-block/command/index.js +8 -6
- package/es/plugins/common/data-source/json-data-source.js +5 -4
- package/es/plugins/common/plugin/index.js +1 -3
- package/es/plugins/common/plugin/paste-handler.js +2 -1
- package/es/plugins/hr/command/index.js +2 -1
- package/es/plugins/image/react/components/BrokenImage.js +2 -1
- package/es/plugins/image/react/components/Image.js +18 -15
- package/es/plugins/image/react/components/ImageEditPopover.js +42 -41
- package/es/plugins/image/react/components/ResizeHandle.js +1 -3
- package/es/plugins/link/node/LinkNode.js +4 -2
- package/es/plugins/link/plugin/registry.js +17 -12
- package/es/plugins/link/react/components/LinkEdit.js +9 -8
- package/es/plugins/list/plugin/index.js +1 -4
- package/es/plugins/list/utils/index.js +4 -2
- package/es/plugins/litexml/command/index.js +69 -62
- package/es/plugins/litexml/node/DiffNode.js +14 -10
- package/es/plugins/litexml/plugin/index.js +6 -12
- package/es/plugins/markdown/data-source/markdown-data-source.js +5 -4
- package/es/plugins/markdown/plugin/index.js +2 -1
- package/es/plugins/markdown/service/transformers.js +4 -2
- package/es/plugins/markdown/utils/index.js +10 -8
- package/es/plugins/math/command/index.js +4 -2
- package/es/plugins/math/react/components/MathInline.js +14 -13
- package/es/plugins/slash/plugin/index.js +13 -4
- package/es/plugins/slash/react/components/DefaultSlashMenu.js +2 -1
- package/es/plugins/slash/react/components/menuLoading.js +4 -0
- package/es/plugins/slash/service/i-slash-service.d.ts +6 -1
- package/es/plugins/slash/service/i-slash-service.js +16 -2
- package/es/plugins/slash/utils/utils.js +1 -1
- package/es/plugins/table/react/TableActionMenu/ActionMenu.js +69 -67
- package/es/plugins/table/react/TableColController.js +29 -26
- package/es/plugins/table/react/TableHoverActions/index.js +0 -2
- package/es/plugins/table/react/TableRowController.js +29 -26
- package/es/plugins/table/utils/index.js +4 -2
- package/es/react/Editor/Editor.js +24 -23
- package/es/react/hooks/useEditorState/index.js +28 -21
- package/es/react/hooks/useEditorState/utils.js +2 -1
- package/es/renderer/engine/render-builtin-node.js +26 -18
- package/es/renderer/engine/render-tree.js +4 -1
- package/es/renderer/renderers/mermaid.js +2 -1
- package/package.json +1 -1
package/es/headless.js
CHANGED
|
@@ -1093,17 +1093,19 @@ var Kernel = class Kernel extends EventEmitter {
|
|
|
1093
1093
|
return datasource.write(this.editor, { selection: true });
|
|
1094
1094
|
}
|
|
1095
1095
|
registerDecorator(name, decorator) {
|
|
1096
|
-
if (this.decorators[name])
|
|
1097
|
-
this.
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
} else {
|
|
1101
|
-
if (this.decorators[name] === decorator) {
|
|
1102
|
-
this.logger.warn(`[Editor] Decorator "${name}" is already registered with the same function`);
|
|
1096
|
+
if (this.decorators[name]) {
|
|
1097
|
+
if (this.hotReloadMode) {
|
|
1098
|
+
this.logger.warn(`๐ Hot reload: decorator "${name}"`);
|
|
1099
|
+
this.decorators[name] = decorator;
|
|
1103
1100
|
return this;
|
|
1101
|
+
} else {
|
|
1102
|
+
if (this.decorators[name] === decorator) {
|
|
1103
|
+
this.logger.warn(`[Editor] Decorator "${name}" is already registered with the same function`);
|
|
1104
|
+
return this;
|
|
1105
|
+
}
|
|
1106
|
+
this.logger.error(`[Editor] Attempting to register duplicate decorator "${name}". Enable hot reload mode if this is intended.`);
|
|
1107
|
+
throw new Error(`Decorator with name "${name}" is already registered.`);
|
|
1104
1108
|
}
|
|
1105
|
-
this.logger.error(`[Editor] Attempting to register duplicate decorator "${name}". Enable hot reload mode if this is intended.`);
|
|
1106
|
-
throw new Error(`Decorator with name "${name}" is already registered.`);
|
|
1107
1109
|
}
|
|
1108
1110
|
this.decorators[name] = decorator;
|
|
1109
1111
|
this.logger.debug(`๐ญ Decorator: ${name}`);
|
|
@@ -1144,31 +1146,34 @@ var Kernel = class Kernel extends EventEmitter {
|
|
|
1144
1146
|
}
|
|
1145
1147
|
registerPlugin(plugin, config) {
|
|
1146
1148
|
const findPlugin = this.plugins.find((p) => p.pluginName === plugin.pluginName);
|
|
1147
|
-
if (findPlugin)
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1149
|
+
if (findPlugin) {
|
|
1150
|
+
if (findPlugin !== plugin) {
|
|
1151
|
+
if (this.hotReloadMode) {
|
|
1152
|
+
this.logger.warn(`๐ Hot reload: plugin "${plugin.pluginName}"`);
|
|
1153
|
+
const index = this.plugins.findIndex((p) => p.pluginName === plugin.pluginName);
|
|
1154
|
+
if (index !== -1) {
|
|
1155
|
+
this.plugins.splice(index, 1);
|
|
1156
|
+
const instanceIndex = this.pluginsInstances.findIndex((instance) => {
|
|
1157
|
+
return instance.constructor.pluginName === plugin.pluginName;
|
|
1158
|
+
});
|
|
1159
|
+
if (instanceIndex !== -1) {
|
|
1160
|
+
const oldInstance = this.pluginsInstances[instanceIndex];
|
|
1161
|
+
if (oldInstance instanceof KernelPlugin) {
|
|
1162
|
+
const decoratorNames = oldInstance.getRegisteredDecorators();
|
|
1163
|
+
for (const decoratorName of decoratorNames) {
|
|
1164
|
+
this.unregisterDecorator(decoratorName);
|
|
1165
|
+
this.logger.debug(`๐งจ Cleanup: decorator "${decoratorName}"`);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
if (oldInstance.destroy) oldInstance.destroy();
|
|
1169
|
+
this.pluginsInstances.splice(instanceIndex, 1);
|
|
1162
1170
|
}
|
|
1163
1171
|
}
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1172
|
+
} else throw new Error(`Plugin with name "${plugin.pluginName}" is already registered with a different implementation.`);
|
|
1173
|
+
} else {
|
|
1174
|
+
if (config !== void 0) this.pluginsConfig.set(plugin, config);
|
|
1175
|
+
return this;
|
|
1167
1176
|
}
|
|
1168
|
-
} else throw new Error(`Plugin with name "${plugin.pluginName}" is already registered with a different implementation.`);
|
|
1169
|
-
else {
|
|
1170
|
-
if (config !== void 0) this.pluginsConfig.set(plugin, config);
|
|
1171
|
-
return this;
|
|
1172
1177
|
}
|
|
1173
1178
|
this.pluginsConfig.set(plugin, config || {});
|
|
1174
1179
|
this.plugins.push(plugin);
|
|
@@ -1235,17 +1240,19 @@ var Kernel = class Kernel extends EventEmitter {
|
|
|
1235
1240
|
}
|
|
1236
1241
|
registerService(serviceId, service) {
|
|
1237
1242
|
const serviceIdString = serviceId.__serviceId;
|
|
1238
|
-
if (this.serviceMap.has(serviceIdString))
|
|
1239
|
-
this.
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
} else {
|
|
1243
|
-
if (this.serviceMap.get(serviceIdString) === service) {
|
|
1244
|
-
this.logger.warn(`[Editor] Service "${serviceIdString}" is already registered with the same instance`);
|
|
1243
|
+
if (this.serviceMap.has(serviceIdString)) {
|
|
1244
|
+
if (this.hotReloadMode) {
|
|
1245
|
+
this.logger.warn(`๐ Hot reload: service "${serviceIdString}"`);
|
|
1246
|
+
this.serviceMap.set(serviceIdString, service);
|
|
1245
1247
|
return;
|
|
1248
|
+
} else {
|
|
1249
|
+
if (this.serviceMap.get(serviceIdString) === service) {
|
|
1250
|
+
this.logger.warn(`[Editor] Service "${serviceIdString}" is already registered with the same instance`);
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
this.logger.error(`[Editor] Attempting to register duplicate service "${serviceIdString}". Enable hot reload mode if this is intended.`);
|
|
1254
|
+
throw new Error(`Service with ID "${serviceIdString}" is already registered.`);
|
|
1246
1255
|
}
|
|
1247
|
-
this.logger.error(`[Editor] Attempting to register duplicate service "${serviceIdString}". Enable hot reload mode if this is intended.`);
|
|
1248
|
-
throw new Error(`Service with ID "${serviceIdString}" is already registered.`);
|
|
1249
1256
|
}
|
|
1250
1257
|
this.serviceMap.set(serviceIdString, service);
|
|
1251
1258
|
this.logger.debug(`๐ง Service: ${serviceIdString}`);
|
|
@@ -1645,11 +1652,13 @@ var DiffNode = class DiffNode extends CardLikeElementNode {
|
|
|
1645
1652
|
content.className = "content";
|
|
1646
1653
|
el.append(content);
|
|
1647
1654
|
const decorator = getKernelFromEditor(editor)?.getDecorator("diff") || null;
|
|
1648
|
-
if (decorator)
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1655
|
+
if (decorator) {
|
|
1656
|
+
if (typeof decorator === "function") reconcileDecorator(editor, this.getKey(), decorator(this, editor));
|
|
1657
|
+
else reconcileDecorator(editor, this.getKey(), {
|
|
1658
|
+
queryDOM: decorator.queryDOM,
|
|
1659
|
+
render: decorator.render(this, editor)
|
|
1660
|
+
});
|
|
1661
|
+
}
|
|
1653
1662
|
return el;
|
|
1654
1663
|
}
|
|
1655
1664
|
updateDOM(_prevNode, _dom, _config) {
|
|
@@ -1658,11 +1667,13 @@ var DiffNode = class DiffNode extends CardLikeElementNode {
|
|
|
1658
1667
|
const editor = kernel?.getLexicalEditor();
|
|
1659
1668
|
if (editor) {
|
|
1660
1669
|
const decorator = kernel?.getDecorator("diff") || null;
|
|
1661
|
-
if (decorator)
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1670
|
+
if (decorator) {
|
|
1671
|
+
if (typeof decorator === "function") reconcileDecorator(editor, this.getKey(), decorator(this, editor));
|
|
1672
|
+
else reconcileDecorator(editor, this.getKey(), {
|
|
1673
|
+
queryDOM: decorator.queryDOM,
|
|
1674
|
+
render: decorator.render(this, editor)
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1666
1677
|
}
|
|
1667
1678
|
return false;
|
|
1668
1679
|
}
|
|
@@ -1782,22 +1793,24 @@ function finalizeModifyBlocks(modifyBlockNodes, diffNodeMap, editor) {
|
|
|
1782
1793
|
for (const blockNodeKey of modifyBlockNodes) {
|
|
1783
1794
|
const blockNode = $getNodeByKey(blockNodeKey);
|
|
1784
1795
|
const diffNode = diffNodeMap.get(blockNodeKey);
|
|
1785
|
-
if (diffNode && blockNode)
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1796
|
+
if (diffNode && blockNode) {
|
|
1797
|
+
if (blockNode.getType() === "listitem" && $isElementNode(blockNode)) {
|
|
1798
|
+
const newDiffNode = $createDiffNode("listItemModify");
|
|
1799
|
+
const firstChild = diffNode.getFirstChild();
|
|
1800
|
+
if (firstChild && $isElementNode(firstChild)) newDiffNode.append(firstChild);
|
|
1801
|
+
const children = blockNode.getChildren();
|
|
1802
|
+
const p = $createParagraphNode();
|
|
1803
|
+
children.forEach((child) => {
|
|
1804
|
+
child.remove();
|
|
1805
|
+
p.append(child);
|
|
1806
|
+
});
|
|
1807
|
+
newDiffNode.append(p);
|
|
1808
|
+
blockNode.append(newDiffNode);
|
|
1809
|
+
continue;
|
|
1810
|
+
} else {
|
|
1811
|
+
diffNode.append($cloneNode(blockNode, editor));
|
|
1812
|
+
blockNode.replace(diffNode, false);
|
|
1813
|
+
}
|
|
1801
1814
|
}
|
|
1802
1815
|
}
|
|
1803
1816
|
}
|
|
@@ -1905,15 +1918,18 @@ function handleModify(editor, dataSource, arrayXml, delay) {
|
|
|
1905
1918
|
try {
|
|
1906
1919
|
const { oldNode, newNode } = tryParseChild(child, editor);
|
|
1907
1920
|
if (oldNode && newNode) prevNode = oldNode.replace(newNode, false);
|
|
1908
|
-
else if (newNode)
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1921
|
+
else if (newNode) {
|
|
1922
|
+
if (prevNode) {
|
|
1923
|
+
if (!newNode.isInline()) {
|
|
1924
|
+
const prevBlock = $closest(prevNode, (node) => node.isInline() === false);
|
|
1925
|
+
if (prevBlock) prevNode = prevBlock.insertAfter(newNode);
|
|
1926
|
+
else {
|
|
1927
|
+
$insertNodes([newNode]);
|
|
1928
|
+
prevNode = newNode;
|
|
1929
|
+
}
|
|
1930
|
+
} else prevNode = prevNode.insertAfter(newNode);
|
|
1931
|
+
} else $insertNodes([newNode]);
|
|
1932
|
+
}
|
|
1917
1933
|
} catch (error) {
|
|
1918
1934
|
logger$7.error("โ Error replacing node:", error);
|
|
1919
1935
|
}
|
|
@@ -1948,8 +1964,6 @@ function handleRemove(editor, key, delay) {
|
|
|
1948
1964
|
originDiffNode.replace(children[0], false).selectEnd();
|
|
1949
1965
|
return;
|
|
1950
1966
|
}
|
|
1951
|
-
case "remove":
|
|
1952
|
-
case "unchanged": break;
|
|
1953
1967
|
}
|
|
1954
1968
|
return;
|
|
1955
1969
|
}
|
|
@@ -1985,9 +1999,10 @@ function handleInsert(editor, payload, dataSource) {
|
|
|
1985
1999
|
editor.update(() => {
|
|
1986
2000
|
try {
|
|
1987
2001
|
let referenceNode = null;
|
|
1988
|
-
if (isBefore)
|
|
1989
|
-
|
|
1990
|
-
|
|
2002
|
+
if (isBefore) {
|
|
2003
|
+
if (payload.beforeId === "root") referenceNode = $getRoot().getFirstChild();
|
|
2004
|
+
else referenceNode = $getNodeByKey(charToId(payload.beforeId));
|
|
2005
|
+
} else if (payload.afterId === "root") referenceNode = $getRoot().getLastChild();
|
|
1991
2006
|
else referenceNode = $getNodeByKey(charToId(payload.afterId));
|
|
1992
2007
|
if (!referenceNode) throw new Error("Reference node not found for insertion.");
|
|
1993
2008
|
const newNodes = inode.root.children.map((child) => $parseSerializedNodeImpl(child, editor));
|
|
@@ -2000,43 +2015,46 @@ function handleInsert(editor, payload, dataSource) {
|
|
|
2000
2015
|
});
|
|
2001
2016
|
return;
|
|
2002
2017
|
}
|
|
2003
|
-
if (isBefore)
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
if (referenceNode)
|
|
2018
|
-
});
|
|
2019
|
-
else wrapBlockModify(refBlock, editor, () => {
|
|
2020
|
-
newNodes.forEach((node) => {
|
|
2018
|
+
if (isBefore) {
|
|
2019
|
+
if (referenceNode.isInline() === false) {
|
|
2020
|
+
const originDiffNode = $closest(referenceNode, (node) => node.getType() === DiffNode.getType());
|
|
2021
|
+
if (originDiffNode) referenceNode = originDiffNode;
|
|
2022
|
+
newNodes.map((node) => {
|
|
2023
|
+
const diffNode = $createDiffNode("add");
|
|
2024
|
+
diffNode.append(node);
|
|
2025
|
+
return diffNode;
|
|
2026
|
+
}).reverse().forEach((diffNode) => {
|
|
2027
|
+
if (referenceNode) referenceNode = referenceNode.insertBefore(diffNode);
|
|
2028
|
+
});
|
|
2029
|
+
} else {
|
|
2030
|
+
const refBlock = $closest(referenceNode, (node) => node.isInline() === false);
|
|
2031
|
+
if (!refBlock) throw new Error("Reference block node not found for insertion.");
|
|
2032
|
+
if ($closest(referenceNode, (node) => node.getType() === DiffNode.getType())) newNodes.forEach((node) => {
|
|
2021
2033
|
if (referenceNode) referenceNode = referenceNode.insertBefore(node);
|
|
2022
2034
|
});
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2035
|
+
else wrapBlockModify(refBlock, editor, () => {
|
|
2036
|
+
newNodes.forEach((node) => {
|
|
2037
|
+
if (referenceNode) referenceNode = referenceNode.insertBefore(node);
|
|
2038
|
+
});
|
|
2039
|
+
});
|
|
2040
|
+
}
|
|
2041
|
+
} else if (referenceNode.isInline() === false) {
|
|
2026
2042
|
const originDiffNode = $closest(referenceNode, (node) => node.getType() === DiffNode.getType());
|
|
2027
2043
|
if (originDiffNode) referenceNode = originDiffNode;
|
|
2028
2044
|
newNodes.forEach((node) => {
|
|
2029
|
-
if (referenceNode)
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2045
|
+
if (referenceNode) {
|
|
2046
|
+
if ($isListItemNode(node)) {
|
|
2047
|
+
const diffNode = $createDiffNode("listItemAdd");
|
|
2048
|
+
node.getChildren().forEach((child) => {
|
|
2049
|
+
diffNode.append(child);
|
|
2050
|
+
});
|
|
2051
|
+
node.append(diffNode);
|
|
2052
|
+
referenceNode = referenceNode.insertAfter(node);
|
|
2053
|
+
} else {
|
|
2054
|
+
const diffNode = $createDiffNode("add");
|
|
2055
|
+
diffNode.append(node);
|
|
2056
|
+
referenceNode = referenceNode.insertAfter(diffNode);
|
|
2057
|
+
}
|
|
2040
2058
|
}
|
|
2041
2059
|
});
|
|
2042
2060
|
} else {
|
|
@@ -2724,7 +2742,7 @@ function indexBy(list, callback) {
|
|
|
2724
2742
|
}
|
|
2725
2743
|
let Punctuation = /[!"#$%&'()*+,./:;<=>?@[\\\]^_`{|}~\u00A1\u2010-\u2027-]/;
|
|
2726
2744
|
try {
|
|
2727
|
-
Punctuation =
|
|
2745
|
+
Punctuation = new RegExp("[\\p{Pc}|\\p{Pd}|\\p{Pe}|\\p{Pf}|\\p{Pi}|\\p{Po}|\\p{Ps}]", "u");
|
|
2728
2746
|
} catch {}
|
|
2729
2747
|
/**
|
|
2730
2748
|
* Checks if a character is a punctuation character.
|
|
@@ -2739,13 +2757,15 @@ function $updateSelectionOnInsert(selection) {
|
|
|
2739
2757
|
const anchor = selection.anchor;
|
|
2740
2758
|
let nodeToInspect = null;
|
|
2741
2759
|
const anchorCaret = $caretFromPoint(anchor, "previous");
|
|
2742
|
-
if (anchorCaret)
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2760
|
+
if (anchorCaret) {
|
|
2761
|
+
if ($isTextPointCaret(anchorCaret)) nodeToInspect = anchorCaret.origin;
|
|
2762
|
+
else {
|
|
2763
|
+
const range = $getCaretRange(anchorCaret, $getChildCaret($getRoot(), "next").getFlipped());
|
|
2764
|
+
for (const caret of range) if ($isTextNode(caret.origin)) {
|
|
2765
|
+
nodeToInspect = caret.origin;
|
|
2766
|
+
break;
|
|
2767
|
+
} else if ($isElementNode(caret.origin) && !caret.origin.isInline()) break;
|
|
2768
|
+
}
|
|
2749
2769
|
}
|
|
2750
2770
|
if (nodeToInspect && $isTextNode(nodeToInspect)) {
|
|
2751
2771
|
const newFormat = nodeToInspect.getFormat();
|
|
@@ -3009,10 +3029,11 @@ var MarkdownDataSource = class extends DataSource {
|
|
|
3009
3029
|
...node.exportJSON(),
|
|
3010
3030
|
$key: node.getKey()
|
|
3011
3031
|
};
|
|
3012
|
-
if (node === firstNode)
|
|
3013
|
-
if (
|
|
3014
|
-
|
|
3015
|
-
|
|
3032
|
+
if (node === firstNode) {
|
|
3033
|
+
if (node === lastNode) {
|
|
3034
|
+
if (anchor.type !== "element" || focus.type !== "element" || focus.offset === anchor.offset) sNode.text = anchorOffset < focusOffset ? sNode.text.slice(anchorOffset, focusOffset) : sNode.text.slice(focusOffset, anchorOffset);
|
|
3035
|
+
} else sNode.text = isBefore ? sNode.text.slice(anchorOffset) : sNode.text.slice(focusOffset);
|
|
3036
|
+
} else if (node === lastNode) sNode.text = isBefore ? sNode.text.slice(0, focusOffset) : sNode.text.slice(0, anchorOffset);
|
|
3016
3037
|
let hasPush = false;
|
|
3017
3038
|
for (let i = lastElement.length - 1; i >= 0; i--) if ($getNodeByKey(lastElement[i].$key)?.isParentOf(node)) {
|
|
3018
3039
|
lastElement[i].children.push(sNode);
|
|
@@ -3073,7 +3094,8 @@ var MarkdownDataSource = class extends DataSource {
|
|
|
3073
3094
|
//#endregion
|
|
3074
3095
|
//#region src/plugins/markdown/service/transformers.ts
|
|
3075
3096
|
function testElementTransformers(parentNode, anchorNode, anchorOffset, elementTransformers, fromTrigger) {
|
|
3076
|
-
|
|
3097
|
+
const grandParentNode = parentNode.getParent();
|
|
3098
|
+
if (!$isRootOrShadowRoot(grandParentNode) || parentNode.getFirstChild() !== anchorNode) return false;
|
|
3077
3099
|
const textContent = anchorNode.getTextContent();
|
|
3078
3100
|
if (fromTrigger !== "enter" && textContent[anchorOffset - 1] !== " ") return false;
|
|
3079
3101
|
for (const { regExp, trigger } of elementTransformers) {
|
|
@@ -3083,7 +3105,8 @@ function testElementTransformers(parentNode, anchorNode, anchorOffset, elementTr
|
|
|
3083
3105
|
return false;
|
|
3084
3106
|
}
|
|
3085
3107
|
function runElementTransformers(parentNode, anchorNode, anchorOffset, elementTransformers, fromTrigger) {
|
|
3086
|
-
|
|
3108
|
+
const grandParentNode = parentNode.getParent();
|
|
3109
|
+
if (!$isRootOrShadowRoot(grandParentNode) || parentNode.getFirstChild() !== anchorNode) return false;
|
|
3087
3110
|
const textContent = anchorNode.getTextContent();
|
|
3088
3111
|
if (fromTrigger !== "enter" && textContent[anchorOffset - 1] !== " ") return false;
|
|
3089
3112
|
for (const { regExp, replace, trigger } of elementTransformers) {
|
|
@@ -3728,7 +3751,8 @@ const MarkdownPlugin = class extends KernelPlugin {
|
|
|
3728
3751
|
const markdown = this.markdownDataSource.write(editor, { selection: true });
|
|
3729
3752
|
if (!markdown) return false;
|
|
3730
3753
|
event.preventDefault();
|
|
3731
|
-
|
|
3754
|
+
const data = $getClipboardDataFromSelection(selection);
|
|
3755
|
+
setLexicalClipboardDataTransfer(clipboardData, data);
|
|
3732
3756
|
clipboardData.setData("text/plain", markdown);
|
|
3733
3757
|
clipboardData.setData("text/markdown", markdown);
|
|
3734
3758
|
this.logger.debug("copy with text/markdown:", { markdownLength: markdown.length });
|
|
@@ -3861,12 +3885,9 @@ const LitexmlPlugin = class extends KernelPlugin {
|
|
|
3861
3885
|
nodeToXML(diffNode.getChildAtIndex(0), lines, indent);
|
|
3862
3886
|
break;
|
|
3863
3887
|
case "remove": break;
|
|
3864
|
-
case "listItemModify":
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
});
|
|
3868
|
-
break;
|
|
3869
|
-
default: break;
|
|
3888
|
+
case "listItemModify": diffNode.getChildAtIndex(1).getChildren().forEach((child) => {
|
|
3889
|
+
nodeToXML(child, lines, indent);
|
|
3890
|
+
});
|
|
3870
3891
|
}
|
|
3871
3892
|
return { lines };
|
|
3872
3893
|
});
|
|
@@ -3882,12 +3903,9 @@ const LitexmlPlugin = class extends KernelPlugin {
|
|
|
3882
3903
|
ctx.processChild(ctx, diffNode.getChildAtIndex(0));
|
|
3883
3904
|
break;
|
|
3884
3905
|
case "remove": break;
|
|
3885
|
-
case "listItemModify":
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
});
|
|
3889
|
-
break;
|
|
3890
|
-
default: break;
|
|
3906
|
+
case "listItemModify": diffNode.getChildAtIndex(1).getChildren().forEach((child) => {
|
|
3907
|
+
ctx.processChild(ctx, child);
|
|
3908
|
+
});
|
|
3891
3909
|
}
|
|
3892
3910
|
return true;
|
|
3893
3911
|
});
|
|
@@ -3984,10 +4002,11 @@ var JSONDataSource = class extends DataSource {
|
|
|
3984
4002
|
...node.exportJSON(),
|
|
3985
4003
|
$key: node.getKey()
|
|
3986
4004
|
};
|
|
3987
|
-
if (node === firstNode)
|
|
3988
|
-
if (
|
|
3989
|
-
|
|
3990
|
-
|
|
4005
|
+
if (node === firstNode) {
|
|
4006
|
+
if (node === lastNode) {
|
|
4007
|
+
if (anchor.type !== "element" || focus.type !== "element" || focus.offset === anchor.offset) sNode.text = anchorOffset < focusOffset ? sNode.text.slice(anchorOffset, focusOffset) : sNode.text.slice(focusOffset, anchorOffset);
|
|
4008
|
+
} else sNode.text = isBefore ? sNode.text.slice(anchorOffset) : sNode.text.slice(focusOffset);
|
|
4009
|
+
} else if (node === lastNode) sNode.text = isBefore ? sNode.text.slice(0, focusOffset) : sNode.text.slice(0, anchorOffset);
|
|
3991
4010
|
let hasPush = false;
|
|
3992
4011
|
for (let i = lastElement.length - 1; i >= 0; i--) if ($getNodeByKey(lastElement[i].$key)?.isParentOf(node)) {
|
|
3993
4012
|
lastElement[i].children.push(sNode);
|
|
@@ -4359,7 +4378,8 @@ const handleVSCodePaste = ({ clipboardData, config, editor, event }) => {
|
|
|
4359
4378
|
if (!text) return "next";
|
|
4360
4379
|
event.preventDefault();
|
|
4361
4380
|
editor.update(() => {
|
|
4362
|
-
|
|
4381
|
+
const selection = $getSelection();
|
|
4382
|
+
if (!$isRangeSelection(selection)) return;
|
|
4363
4383
|
const codeNode = $createCodeMirrorNode(language, text);
|
|
4364
4384
|
$insertNodes([codeNode]);
|
|
4365
4385
|
const nodeSelection = $createNodeSelection();
|
|
@@ -4843,9 +4863,7 @@ const CommonPlugin = class extends KernelPlugin {
|
|
|
4843
4863
|
case "h6":
|
|
4844
4864
|
ctx.wrap("###### ", "\n\n");
|
|
4845
4865
|
break;
|
|
4846
|
-
default:
|
|
4847
|
-
ctx.wrap("", "\n\n");
|
|
4848
|
-
break;
|
|
4866
|
+
default: ctx.wrap("", "\n\n");
|
|
4849
4867
|
}
|
|
4850
4868
|
});
|
|
4851
4869
|
markdownService.registerMarkdownWriter("text", (ctx, node) => {
|
|
@@ -5205,12 +5223,14 @@ function registerCodeMirrorCommand(editor) {
|
|
|
5205
5223
|
}, COMMAND_PRIORITY_EDITOR), editor.registerCommand(UPDATE_CODEBLOCK_LANG, (payload) => {
|
|
5206
5224
|
const codeMirrorNode = editor.getEditorState().read(() => {
|
|
5207
5225
|
const selection = $getSelection();
|
|
5208
|
-
if ($isRangeSelection(selection))
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5226
|
+
if ($isRangeSelection(selection)) {
|
|
5227
|
+
if (selection.isCollapsed()) return $findMatchingParent(selection.anchor.getNode(), $isCodeMirrorNode);
|
|
5228
|
+
else {
|
|
5229
|
+
const anchor = $findMatchingParent(selection.anchor.getNode(), $isCodeMirrorNode);
|
|
5230
|
+
const focus = $findMatchingParent(selection.focus.getNode(), $isCodeMirrorNode);
|
|
5231
|
+
if (anchor && focus && anchor === focus) return anchor;
|
|
5232
|
+
return null;
|
|
5233
|
+
}
|
|
5214
5234
|
}
|
|
5215
5235
|
return false;
|
|
5216
5236
|
});
|
|
@@ -6148,7 +6168,8 @@ const INSERT_HORIZONTAL_RULE_COMMAND = createCommand("INSERT_HORIZONTAL_RULE_COM
|
|
|
6148
6168
|
function registerHorizontalRuleCommand(editor) {
|
|
6149
6169
|
return editor.registerCommand(INSERT_HORIZONTAL_RULE_COMMAND, () => {
|
|
6150
6170
|
editor.update(() => {
|
|
6151
|
-
$
|
|
6171
|
+
const hrNode = $createHorizontalRuleNode();
|
|
6172
|
+
$insertNodes([hrNode]);
|
|
6152
6173
|
});
|
|
6153
6174
|
return true;
|
|
6154
6175
|
}, COMMAND_PRIORITY_EDITOR);
|
|
@@ -6804,8 +6825,10 @@ var LinkNode = class LinkNode extends ElementNode {
|
|
|
6804
6825
|
]) {
|
|
6805
6826
|
const key = `__${attr}`;
|
|
6806
6827
|
const value = this[key];
|
|
6807
|
-
if (!prevNode || prevNode[key] !== value)
|
|
6808
|
-
|
|
6828
|
+
if (!prevNode || prevNode[key] !== value) {
|
|
6829
|
+
if (value) anchor[attr] = value;
|
|
6830
|
+
else anchor.removeAttribute(attr);
|
|
6831
|
+
}
|
|
6809
6832
|
}
|
|
6810
6833
|
}
|
|
6811
6834
|
}
|
|
@@ -7310,17 +7333,19 @@ function registerLinkCommands(editor, kernel, options) {
|
|
|
7310
7333
|
let expandTo = null;
|
|
7311
7334
|
editor.getEditorState().read(() => {
|
|
7312
7335
|
const selection = $getSelection();
|
|
7313
|
-
if ($isRangeSelection(selection))
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7336
|
+
if ($isRangeSelection(selection)) {
|
|
7337
|
+
if (!selection.isCollapsed()) {
|
|
7338
|
+
const maybeUrl = formatUrl(selection.getTextContent().trim());
|
|
7339
|
+
if (validateUrl?.(maybeUrl)) nextUrl = maybeUrl;
|
|
7340
|
+
} else {
|
|
7341
|
+
const found = extractUrlFromText(selection.anchor.getNode().getTextContent());
|
|
7342
|
+
if (found && validateUrl?.(formatUrl(found.url))) {
|
|
7343
|
+
nextUrl = formatUrl(found.url);
|
|
7344
|
+
expandTo = {
|
|
7345
|
+
index: found.index,
|
|
7346
|
+
length: found.length
|
|
7347
|
+
};
|
|
7348
|
+
}
|
|
7324
7349
|
}
|
|
7325
7350
|
}
|
|
7326
7351
|
});
|
|
@@ -7475,14 +7500,16 @@ const listReplace = (listType) => {
|
|
|
7475
7500
|
};
|
|
7476
7501
|
};
|
|
7477
7502
|
function $indentOverTab(selection) {
|
|
7478
|
-
|
|
7503
|
+
const nodes = selection.getNodes();
|
|
7504
|
+
if ($filter(nodes, (node) => {
|
|
7479
7505
|
if ($isBlockElementNode(node) && node.canIndent()) return node;
|
|
7480
7506
|
return null;
|
|
7481
7507
|
}).length > 0) return true;
|
|
7482
7508
|
const anchor = selection.anchor;
|
|
7483
7509
|
const focus = selection.focus;
|
|
7484
7510
|
const first = focus.isBefore(anchor) ? focus : anchor;
|
|
7485
|
-
const
|
|
7511
|
+
const firstNode = first.getNode();
|
|
7512
|
+
const firstBlock = $getNearestBlockElementAncestorOrThrow(firstNode);
|
|
7486
7513
|
if (firstBlock.canIndent()) {
|
|
7487
7514
|
const firstBlockKey = firstBlock.getKey();
|
|
7488
7515
|
let selectionAtStart = $createRangeSelection();
|
|
@@ -7814,10 +7841,7 @@ const ListPlugin = class extends KernelPlugin {
|
|
|
7814
7841
|
case "number":
|
|
7815
7842
|
ctx.wrap(`${prefix}${node.getValue()}. `, "\n");
|
|
7816
7843
|
break;
|
|
7817
|
-
case "check":
|
|
7818
|
-
ctx.wrap(`${prefix}- [${node.getChecked() ? "x" : " "}] `, "\n");
|
|
7819
|
-
break;
|
|
7820
|
-
default: break;
|
|
7844
|
+
case "check": ctx.wrap(`${prefix}- [${node.getChecked() ? "x" : " "}] `, "\n");
|
|
7821
7845
|
}
|
|
7822
7846
|
}
|
|
7823
7847
|
});
|
|
@@ -8046,8 +8070,10 @@ function registerMathCommand(editor) {
|
|
|
8046
8070
|
const { key, prev } = payload;
|
|
8047
8071
|
editor.update(() => {
|
|
8048
8072
|
const mathNode = $getNodeByKey(key);
|
|
8049
|
-
if (mathNode)
|
|
8050
|
-
|
|
8073
|
+
if (mathNode) {
|
|
8074
|
+
if (prev) mathNode.selectPrevious();
|
|
8075
|
+
else mathNode.selectNext();
|
|
8076
|
+
}
|
|
8051
8077
|
});
|
|
8052
8078
|
return true;
|
|
8053
8079
|
}, COMMAND_PRIORITY_HIGH));
|
package/es/index.js
CHANGED
|
@@ -2,8 +2,8 @@ import { __toCommonJS } from "./_virtual/_rolldown/runtime.js";
|
|
|
2
2
|
import { browserDebug, createDebugLogger, debugLogger, debugLoggers, debug_exports, devConsole, init_debug, prodSafeLogger } from "./utils/debug.js";
|
|
3
3
|
import { HotkeyEnum, HotkeyScopeEnum, KeyEnum, init_hotkey } from "./types/hotkey.js";
|
|
4
4
|
import { getHotkeyById, init_registerHotkey } from "./utils/hotkey/registerHotkey.js";
|
|
5
|
-
import { HOVER_COMMAND } from "./editor-kernel/event.js";
|
|
6
|
-
import { $closest, $closestNodeType, $getNearestNodeFromDOMNode, $getNodeFromDOMNode, DOM_DOCUMENT_FRAGMENT_TYPE, DOM_DOCUMENT_TYPE, DOM_ELEMENT_TYPE, DOM_TEXT_TYPE, EDITOR_THEME_KEY, assert, compareNodeOrder, createEmptyEditorState, genServiceId, generateEditorId, getKernelFromEditor, getKernelFromEditorConfig, getNodeKeyFromDOMNode, getParentElement, isDOMNode, isDocumentFragment, moment, noop, reconcileDecorator, registerEditorKernel, unregisterEditorKernel } from "./editor-kernel/utils.js";
|
|
5
|
+
import { HOVER_COMMAND, init_event } from "./editor-kernel/event.js";
|
|
6
|
+
import { $closest, $closestNodeType, $getNearestNodeFromDOMNode, $getNodeFromDOMNode, DOM_DOCUMENT_FRAGMENT_TYPE, DOM_DOCUMENT_TYPE, DOM_ELEMENT_TYPE, DOM_TEXT_TYPE, EDITOR_THEME_KEY, assert, compareNodeOrder, createEmptyEditorState, genServiceId, generateEditorId, getKernelFromEditor, getKernelFromEditorConfig, getNodeKeyFromDOMNode, getParentElement, init_utils, isDOMNode, isDocumentFragment, moment, noop, reconcileDecorator, registerEditorKernel, unregisterEditorKernel } from "./editor-kernel/utils.js";
|
|
7
7
|
import { Kernel, init_kernel, kernel_exports } from "./editor-kernel/kernel.js";
|
|
8
8
|
import DataSource from "./editor-kernel/data-source.js";
|
|
9
9
|
import { resetRandomKey } from "./editor-kernel/index.js";
|
|
@@ -105,6 +105,9 @@ init_hotkey();
|
|
|
105
105
|
init_registerHotkey();
|
|
106
106
|
init_debug();
|
|
107
107
|
init_kernel();
|
|
108
|
+
init_hotkey();
|
|
109
|
+
init_event();
|
|
110
|
+
init_utils();
|
|
108
111
|
/**
|
|
109
112
|
* Enable hot reload mode globally for all editor instances
|
|
110
113
|
* Call this in your app's entry point during development
|
|
@@ -283,8 +283,10 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
283
283
|
}
|
|
284
284
|
let collectedText = "";
|
|
285
285
|
let collectedTextAfter = "";
|
|
286
|
-
if (node.getTextContent && node.getType() === "text")
|
|
287
|
-
|
|
286
|
+
if (node.getTextContent && node.getType() === "text") {
|
|
287
|
+
if (founded) collectedTextAfter += node.getTextContent();
|
|
288
|
+
else collectedText += node.getTextContent();
|
|
289
|
+
}
|
|
288
290
|
if (node.getChildren) {
|
|
289
291
|
const children = node.getChildren();
|
|
290
292
|
for (const child of children) {
|
|
@@ -581,12 +581,13 @@ const ReactBlockPlugin = (props) => {
|
|
|
581
581
|
onMouseDown: preventEditorSelectionLost,
|
|
582
582
|
children: [actionButtons.map((item) => {
|
|
583
583
|
const title = typeof item.title === "function" ? item.title(menuContext) : item.title;
|
|
584
|
+
const icon = item.icon === "plus" ? /* @__PURE__ */ jsx(Icon, {
|
|
585
|
+
icon: PlusIcon,
|
|
586
|
+
size: 14
|
|
587
|
+
}) : void 0;
|
|
584
588
|
return /* @__PURE__ */ jsx(Button$1, {
|
|
585
589
|
"aria-label": title,
|
|
586
|
-
icon
|
|
587
|
-
icon: PlusIcon,
|
|
588
|
-
size: 14
|
|
589
|
-
}) : void 0,
|
|
590
|
+
icon,
|
|
590
591
|
onClick: () => item.onClick(menuContext),
|
|
591
592
|
size: "small",
|
|
592
593
|
title,
|