@udecode/plate-core
Version:
The core of Plate – a plugin system for slate
1,476 lines (1,445 loc) • 227 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
AUTO_SCROLL: () => AUTO_SCROLL,
AffinityPlugin: () => AffinityPlugin,
AstPlugin: () => AstPlugin,
BaseParagraphPlugin: () => BaseParagraphPlugin,
CARRIAGE_RETURN: () => CARRIAGE_RETURN,
DOMPlugin: () => DOMPlugin,
DebugPlugin: () => DebugPlugin,
ElementStatic: () => ElementStatic,
HistoryPlugin: () => HistoryPlugin,
Hotkeys: () => Hotkeys,
HtmlPlugin: () => HtmlPlugin,
LINE_FEED: () => LINE_FEED,
LeafStatic: () => LeafStatic,
LengthPlugin: () => LengthPlugin,
NO_BREAK_SPACE: () => NO_BREAK_SPACE,
NodeIdPlugin: () => NodeIdPlugin,
OverridePlugin: () => OverridePlugin,
ParserPlugin: () => ParserPlugin,
PlateError: () => PlateError,
PlateStatic: () => PlateStatic,
SPACE: () => SPACE,
SlateElement: () => SlateElement,
SlateExtensionPlugin: () => SlateExtensionPlugin,
SlateLeaf: () => SlateLeaf,
SlateText: () => SlateText,
TAB: () => TAB,
ZERO_WIDTH_SPACE: () => ZERO_WIDTH_SPACE,
applyDeepToNodes: () => applyDeepToNodes,
cleanHtmlBrElements: () => cleanHtmlBrElements,
cleanHtmlCrLf: () => cleanHtmlCrLf,
cleanHtmlEmptyElements: () => cleanHtmlEmptyElements,
cleanHtmlFontElements: () => cleanHtmlFontElements,
cleanHtmlLinkElements: () => cleanHtmlLinkElements,
cleanHtmlTextNodes: () => cleanHtmlTextNodes,
collapseString: () => collapseString,
collapseWhiteSpace: () => collapseWhiteSpace,
collapseWhiteSpaceChildren: () => collapseWhiteSpaceChildren,
collapseWhiteSpaceElement: () => collapseWhiteSpaceElement,
collapseWhiteSpaceNode: () => collapseWhiteSpaceNode,
collapseWhiteSpaceText: () => collapseWhiteSpaceText,
copyBlockMarksToSpanChild: () => copyBlockMarksToSpanChild,
createHotkey: () => createHotkey,
createSlateEditor: () => createSlateEditor,
createSlatePlugin: () => createSlatePlugin,
createStaticString: () => createStaticString,
createTSlatePlugin: () => createTSlatePlugin,
createZustandStore: () => import_zustand_x2.createZustandStore,
defaultsDeepToNodes: () => defaultsDeepToNodes,
deserializeHtml: () => deserializeHtml,
deserializeHtmlElement: () => deserializeHtmlElement,
deserializeHtmlNode: () => deserializeHtmlNode,
deserializeHtmlNodeChildren: () => deserializeHtmlNodeChildren,
endInlineFormattingContext: () => endInlineFormattingContext,
findHtmlElement: () => findHtmlElement,
getContainerTypes: () => getContainerTypes,
getCorePlugins: () => getCorePlugins,
getDataNodeProps: () => getDataNodeProps,
getEdgeNodes: () => getEdgeNodes,
getEditorDOMFromHtmlString: () => getEditorDOMFromHtmlString,
getEditorPlugin: () => getEditorPlugin,
getHtmlComments: () => getHtmlComments,
getInjectMatch: () => getInjectMatch,
getInjectedPlugins: () => getInjectedPlugins,
getKeyByType: () => getKeyByType,
getKeysByTypes: () => getKeysByTypes,
getMarkBoundaryAffinity: () => getMarkBoundaryAffinity,
getNodeDataAttributeKeys: () => getNodeDataAttributeKeys,
getNodeDataAttributes: () => getNodeDataAttributes,
getPluginByType: () => getPluginByType,
getPluginDataAttributes: () => getPluginDataAttributes,
getPluginKey: () => getPluginKey,
getPluginNodeProps: () => getPluginNodeProps,
getPluginType: () => getPluginType,
getPluginTypes: () => getPluginTypes,
getRenderNodeStaticProps: () => getRenderNodeStaticProps,
getSlateClass: () => getSlateClass,
getSlateElements: () => getSlateElements,
getSlatePlugin: () => getSlatePlugin,
htmlBodyToFragment: () => htmlBodyToFragment,
htmlBrToNewLine: () => htmlBrToNewLine,
htmlElementToElement: () => htmlElementToElement,
htmlElementToLeaf: () => htmlElementToLeaf,
htmlStringToDOMNode: () => htmlStringToDOMNode,
htmlTextNodeToString: () => htmlTextNodeToString,
inferWhiteSpaceRule: () => inferWhiteSpaceRule,
init: () => init,
inlineTagNames: () => inlineTagNames,
insertExitBreak: () => insertExitBreak,
isHotkey: () => import_is_hotkey2.isHotkey,
isHtmlBlockElement: () => isHtmlBlockElement,
isHtmlComment: () => isHtmlComment,
isHtmlElement: () => isHtmlElement,
isHtmlFragmentHref: () => isHtmlFragmentHref,
isHtmlInlineElement: () => isHtmlInlineElement,
isHtmlTable: () => isHtmlTable,
isHtmlText: () => isHtmlText,
isLastNonEmptyTextOfInlineFormattingContext: () => isLastNonEmptyTextOfInlineFormattingContext,
isNodeAffinity: () => isNodeAffinity,
isNodesAffinity: () => isNodesAffinity,
isOlSymbol: () => isOlSymbol,
isSlateEditor: () => isSlateEditor,
isSlateElement: () => isSlateElement,
isSlateLeaf: () => isSlateLeaf,
isSlateNode: () => isSlateNode,
isSlatePluginElement: () => isSlatePluginElement,
isSlatePluginNode: () => isSlatePluginNode,
isSlateString: () => isSlateString,
isSlateText: () => isSlateText,
isSlateVoid: () => isSlateVoid,
isType: () => isType,
keyToDataAttribute: () => keyToDataAttribute,
mergeDeepToNodes: () => mergeDeepToNodes,
nanoid: () => import_nanoid3.nanoid,
normalizeDescendantsToDocumentFragment: () => normalizeDescendantsToDocumentFragment,
omitPluginContext: () => omitPluginContext,
overridePluginsByKey: () => overridePluginsByKey,
parseHtmlDocument: () => parseHtmlDocument,
parseHtmlElement: () => parseHtmlElement,
pipeDecorate: () => pipeDecorate,
pipeDeserializeHtmlElement: () => pipeDeserializeHtmlElement,
pipeDeserializeHtmlLeaf: () => pipeDeserializeHtmlLeaf,
pipeInsertDataQuery: () => pipeInsertDataQuery,
pipeRenderElementStatic: () => pipeRenderElementStatic,
pipeRenderLeafStatic: () => pipeRenderLeafStatic,
pipeRenderTextStatic: () => pipeRenderTextStatic,
pluginDeserializeHtml: () => pluginDeserializeHtml,
pluginRenderElementStatic: () => pluginRenderElementStatic,
pluginRenderLeafStatic: () => pluginRenderLeafStatic,
pluginRenderTextStatic: () => pluginRenderTextStatic,
postCleanHtml: () => postCleanHtml,
preCleanHtml: () => preCleanHtml,
removeHtmlNodesBetweenComments: () => removeHtmlNodesBetweenComments,
removeHtmlSurroundings: () => removeHtmlSurroundings,
replaceTagName: () => replaceTagName,
resetBlock: () => resetBlock,
serializeHtml: () => serializeHtml,
setAffinitySelection: () => setAffinitySelection,
setValue: () => setValue,
someHtmlElement: () => someHtmlElement,
stripHtmlClassNames: () => stripHtmlClassNames,
stripSlateDataAttributes: () => stripSlateDataAttributes,
traverseHtmlComments: () => traverseHtmlComments,
traverseHtmlElements: () => traverseHtmlElements,
traverseHtmlNode: () => traverseHtmlNode,
traverseHtmlTexts: () => traverseHtmlTexts,
unwrapHtmlElement: () => unwrapHtmlElement,
upsertInlineFormattingContext: () => upsertInlineFormattingContext,
useNodeAttributes: () => useNodeAttributes,
withBreakRules: () => withBreakRules,
withDeleteRules: () => withDeleteRules,
withMergeRules: () => withMergeRules,
withNodeId: () => withNodeId,
withNormalizeRules: () => withNormalizeRules,
withOverrides: () => withOverrides,
withPlateHistory: () => withPlateHistory,
withScrolling: () => withScrolling,
withSlate: () => withSlate
});
module.exports = __toCommonJS(index_exports);
// src/lib/editor/withSlate.ts
var import_slate23 = require("@udecode/slate");
var import_nanoid2 = require("nanoid");
// src/internal/plugin/resolvePlugins.ts
var import_slate = require("@udecode/slate");
var import_utils2 = require("@udecode/utils");
var import_merge2 = __toESM(require("lodash/merge.js"));
var import_zustand_x = require("zustand-x");
// src/lib/plugin/createSlatePlugin.ts
var import_utils = require("@udecode/utils");
// src/internal/utils/isFunction.ts
function isFunction(value) {
return typeof value === "function";
}
// src/internal/utils/mergePlugins.ts
var import_mergeWith = __toESM(require("lodash/mergeWith.js"));
function mergePlugins(basePlugin, ...sourcePlugins) {
return (0, import_mergeWith.default)(
{},
basePlugin,
...sourcePlugins,
(objValue, srcValue, key) => {
if (Array.isArray(srcValue)) {
return srcValue;
}
if (key === "options") {
return { ...objValue, ...srcValue };
}
}
);
}
// src/lib/plugin/createSlatePlugin.ts
function createSlatePlugin(config = {}) {
let baseConfig;
let initialExtension;
if (isFunction(config)) {
baseConfig = { key: "" };
initialExtension = (editor) => config(editor);
} else {
baseConfig = config;
}
const key = baseConfig.key ?? "";
const plugin = mergePlugins(
{
key,
__apiExtensions: [],
__configuration: null,
__extensions: initialExtension ? [initialExtension] : [],
__selectorExtensions: [],
api: {},
dependencies: [],
editor: {},
handlers: {},
inject: {},
node: { type: key },
options: {},
override: {},
parser: {},
parsers: {},
plugins: [],
priority: 100,
render: {},
rules: {},
shortcuts: {},
transforms: {}
},
config
);
if (plugin.node.isLeaf && !(0, import_utils.isDefined)(plugin.node.isDecoration)) {
plugin.node.isDecoration = true;
}
plugin.configure = (config2) => {
const newPlugin = { ...plugin };
newPlugin.__configuration = (ctx) => isFunction(config2) ? config2(ctx) : config2;
return createSlatePlugin(newPlugin);
};
plugin.configurePlugin = (p, config2) => {
const newPlugin = { ...plugin };
const configureNestedPlugin = (plugins2) => {
let found = false;
const updatedPlugins = plugins2.map((nestedPlugin) => {
if (nestedPlugin.key === p.key) {
found = true;
return createSlatePlugin({
...nestedPlugin,
__configuration: (ctx) => isFunction(config2) ? config2(ctx) : config2
});
}
if (nestedPlugin.plugins && nestedPlugin.plugins.length > 0) {
const result2 = configureNestedPlugin(nestedPlugin.plugins);
if (result2.found) {
found = true;
return { ...nestedPlugin, plugins: result2.plugins };
}
}
return nestedPlugin;
});
return { found, plugins: updatedPlugins };
};
const result = configureNestedPlugin(newPlugin.plugins);
newPlugin.plugins = result.plugins;
return createSlatePlugin(newPlugin);
};
plugin.extendEditorApi = (extension) => {
const newPlugin = { ...plugin };
newPlugin.__apiExtensions = [
...newPlugin.__apiExtensions,
{ extension, isPluginSpecific: false }
];
return createSlatePlugin(newPlugin);
};
plugin.extendSelectors = (extension) => {
const newPlugin = { ...plugin };
newPlugin.__selectorExtensions = [
...newPlugin.__selectorExtensions,
extension
];
return createSlatePlugin(newPlugin);
};
plugin.extendApi = (extension) => {
const newPlugin = { ...plugin };
newPlugin.__apiExtensions = [
...newPlugin.__apiExtensions,
{ extension, isPluginSpecific: true }
];
return createSlatePlugin(newPlugin);
};
plugin.extendEditorTransforms = (extension) => {
const newPlugin = { ...plugin };
newPlugin.__apiExtensions = [
...newPlugin.__apiExtensions,
{ extension, isPluginSpecific: false, isTransform: true }
];
return createSlatePlugin(newPlugin);
};
plugin.extendTransforms = (extension) => {
const newPlugin = { ...plugin };
newPlugin.__apiExtensions = [
...newPlugin.__apiExtensions,
{ extension, isPluginSpecific: true, isTransform: true }
];
return createSlatePlugin(newPlugin);
};
plugin.overrideEditor = (extension) => {
const newPlugin = { ...plugin };
newPlugin.__apiExtensions = [
...newPlugin.__apiExtensions,
{
extension,
isOverride: true,
isPluginSpecific: false,
isTransform: true
}
];
return createSlatePlugin(newPlugin);
};
plugin.extend = (extendConfig) => {
let newPlugin = { ...plugin };
if (isFunction(extendConfig)) {
newPlugin.__extensions = [
...newPlugin.__extensions,
extendConfig
];
} else {
newPlugin = mergePlugins(newPlugin, extendConfig);
}
return createSlatePlugin(newPlugin);
};
plugin.clone = () => mergePlugins(plugin);
plugin.extendPlugin = (p, extendConfig) => {
const newPlugin = { ...plugin };
const extendNestedPlugin = (plugins2) => {
let found = false;
const updatedPlugins = plugins2.map((nestedPlugin) => {
if (nestedPlugin.key === p.key) {
found = true;
return createSlatePlugin({
...nestedPlugin,
__extensions: [
...nestedPlugin.__extensions,
(ctx) => isFunction(extendConfig) ? extendConfig(ctx) : extendConfig
]
});
}
if (nestedPlugin.plugins && nestedPlugin.plugins.length > 0) {
const result2 = extendNestedPlugin(nestedPlugin.plugins);
if (result2.found) {
found = true;
return { ...nestedPlugin, plugins: result2.plugins };
}
}
return nestedPlugin;
});
return { found, plugins: updatedPlugins };
};
const result = extendNestedPlugin(newPlugin.plugins);
newPlugin.plugins = result.plugins;
if (!result.found) {
newPlugin.plugins.push(
createSlatePlugin({
key: p.key,
__extensions: [
(ctx) => isFunction(extendConfig) ? extendConfig(ctx) : extendConfig
]
})
);
}
return createSlatePlugin(newPlugin);
};
plugin.withComponent = (component) => {
return plugin.extend({
node: { component },
render: { node: component }
});
};
return plugin;
}
function createTSlatePlugin(config = {}) {
return createSlatePlugin(config);
}
// src/lib/plugin/getEditorPlugin.ts
function getEditorPlugin(editor, p) {
const plugin = editor.getPlugin(p);
return {
api: editor.api,
editor,
plugin,
setOption: (keyOrOptions, value) => editor.setOption(plugin, keyOrOptions, value),
setOptions: (options) => editor.setOptions(plugin, options),
tf: editor.transforms,
type: plugin.node.type,
getOption: (key, ...args) => editor.getOption(plugin, key, ...args),
getOptions: () => editor.getOptions(plugin)
};
}
// src/internal/plugin/resolvePlugin.ts
var import_merge = __toESM(require("lodash/merge.js"));
var resolvePlugin = (editor, _plugin) => {
let plugin = mergePlugins({}, _plugin);
plugin.__resolved = true;
if (plugin.__configuration) {
const configResult = plugin.__configuration(
getEditorPlugin(editor, plugin)
);
plugin = mergePlugins(plugin, configResult);
delete plugin.__configuration;
}
if (plugin.__extensions && plugin.__extensions.length > 0) {
plugin.__extensions.forEach((extension) => {
plugin = mergePlugins(
plugin,
extension(getEditorPlugin(editor, plugin))
);
});
plugin.__extensions = [];
}
const targetPluginToInject = plugin.inject?.targetPluginToInject;
const targetPlugins = plugin.inject?.targetPlugins;
if (targetPluginToInject && targetPlugins && targetPlugins.length > 0) {
plugin.inject = plugin.inject || {};
plugin.inject.plugins = (0, import_merge.default)(
{},
plugin.inject.plugins,
Object.fromEntries(
targetPlugins.map((targetPlugin) => {
const injectedPlugin = targetPluginToInject({
...getEditorPlugin(editor, plugin),
targetPlugin
});
return [targetPlugin, injectedPlugin];
})
)
);
}
if (plugin.node?.component) {
plugin.render.node = plugin.node.component;
}
if (plugin.render?.node) {
plugin.node.component = plugin.render.node;
}
validatePlugin(editor, plugin);
return plugin;
};
var validatePlugin = (editor, plugin) => {
if (!plugin.__extensions) {
editor.api.debug.error(
`Invalid plugin '${plugin.key}', you should use createSlatePlugin.`,
"USE_CREATE_PLUGIN"
);
}
if (plugin.node.isElement && plugin.node.isLeaf) {
editor.api.debug.error(
`Plugin ${plugin.key} cannot be both an element and a leaf.`,
"PLUGIN_NODE_TYPE"
);
}
};
// src/lib/plugin/getSlatePlugin.ts
function getSlatePlugin(editor, p) {
let plugin = p;
const editorPlugin = editor.plugins[p.key];
if (!editorPlugin) {
if (!plugin.node) {
plugin = createSlatePlugin(plugin);
}
return plugin.__resolved ? plugin : resolvePlugin(editor, plugin);
}
return editorPlugin;
}
function getPluginType(editor, key) {
const p = editor.getPlugin({ key });
return p.node.type ?? p.key ?? "";
}
var getPluginTypes = (editor, keys) => keys.map((key) => editor.getType(key));
var getPluginKey = (editor, type) => editor.meta.pluginCache.node.types[type];
var getPluginByType = (editor, type) => {
const key = getPluginKey(editor, type);
if (!key) return null;
return editor.getPlugin({ key });
};
var getContainerTypes = (editor) => {
return getPluginTypes(editor, editor.meta.pluginCache.node.isContainer);
};
// src/internal/plugin/resolvePlugins.ts
var resolvePlugins = (editor, plugins2 = []) => {
editor.plugins = {};
editor.meta.pluginList = [];
editor.meta.shortcuts = {};
editor.meta.components = {};
editor.meta.pluginCache = {
decorate: [],
handlers: {
onChange: []
},
inject: {
nodeProps: []
},
node: {
isContainer: [],
isElement: [],
isInline: [],
isLeaf: [],
isMarkableVoid: [],
isNotSelectable: [],
isStrictSiblings: [],
isVoid: [],
types: {}
},
normalizeInitialValue: [],
render: {
aboveEditable: [],
aboveNodes: [],
aboveSlate: [],
afterContainer: [],
afterEditable: [],
beforeContainer: [],
beforeEditable: [],
belowNodes: [],
belowRootNodes: []
},
rules: {
match: []
},
useHooks: []
};
const resolvedPlugins = resolveAndSortPlugins(editor, plugins2);
applyPluginsToEditor(editor, resolvedPlugins);
resolvePluginOverrides(editor);
resolvePluginStores(editor);
editor.meta.pluginList.forEach((plugin) => {
if (plugin.extendEditor) {
editor = plugin.extendEditor(getEditorPlugin(editor, plugin));
(0, import_slate.syncLegacyMethods)(editor);
}
resolvePluginMethods(editor, plugin);
if (plugin.node?.isContainer) {
editor.meta.pluginCache.node.isContainer.push(plugin.key);
}
editor.meta.pluginCache.node.types[plugin.node.type] = plugin.key;
if (plugin.inject?.nodeProps) {
editor.meta.pluginCache.inject.nodeProps.push(plugin.key);
}
if (plugin.render?.node) {
editor.meta.components[plugin.key] = plugin.render.node;
}
if (plugin.node?.isLeaf) {
editor.meta.pluginCache.node.isLeaf.push(plugin.key);
}
if (plugin.node?.isElement) {
editor.meta.pluginCache.node.isElement.push(plugin.key);
}
if (plugin.node?.isInline) {
editor.meta.pluginCache.node.isInline.push(plugin.key);
}
if (plugin.node?.isVoid) {
editor.meta.pluginCache.node.isVoid.push(plugin.key);
}
if (plugin.node?.isMarkableVoid) {
editor.meta.pluginCache.node.isMarkableVoid.push(plugin.key);
}
if (plugin.node?.isStrictSiblings) {
editor.meta.pluginCache.node.isStrictSiblings.push(plugin.key);
}
if (plugin.node?.isSelectable === false) {
editor.meta.pluginCache.node.isNotSelectable.push(plugin.key);
}
if (plugin.render.aboveEditable) {
editor.meta.pluginCache.render.aboveEditable.push(plugin.key);
}
if (plugin.render.aboveSlate) {
editor.meta.pluginCache.render.aboveSlate.push(plugin.key);
}
if (plugin.render.afterEditable) {
editor.meta.pluginCache.render.afterEditable.push(plugin.key);
}
if (plugin.render.beforeEditable) {
editor.meta.pluginCache.render.beforeEditable.push(plugin.key);
}
if (plugin.rules?.match) {
editor.meta.pluginCache.rules.match.push(plugin.key);
}
if (plugin.render.afterContainer) {
editor.meta.pluginCache.render.afterContainer.push(plugin.key);
}
if (plugin.render.beforeContainer) {
editor.meta.pluginCache.render.beforeContainer.push(plugin.key);
}
if (plugin.render.belowRootNodes) {
editor.meta.pluginCache.render.belowRootNodes.push(plugin.key);
}
if (plugin.normalizeInitialValue) {
editor.meta.pluginCache.normalizeInitialValue.push(plugin.key);
}
if (plugin.decorate) {
editor.meta.pluginCache.decorate.push(plugin.key);
}
if (plugin.render.aboveNodes) {
editor.meta.pluginCache.render.aboveNodes.push(plugin.key);
}
if (plugin.render.belowNodes) {
editor.meta.pluginCache.render.belowNodes.push(plugin.key);
}
if (plugin.useHooks) {
editor.meta.pluginCache.useHooks.push(plugin.key);
}
if (plugin.handlers?.onChange) {
editor.meta.pluginCache.handlers.onChange.push(plugin.key);
}
});
resolvePluginShortcuts(editor);
return editor;
};
var resolvePluginStores = (editor) => {
editor.meta.pluginList.forEach((plugin) => {
let store = (0, import_zustand_x.createZustandStore)(plugin.options, {
mutative: true,
name: plugin.key
});
if (plugin.__selectorExtensions && plugin.__selectorExtensions.length > 0) {
plugin.__selectorExtensions.forEach((extension) => {
const extendedOptions = extension(getEditorPlugin(editor, plugin));
store = store.extendSelectors(() => extendedOptions);
});
}
plugin.optionsStore = store;
});
};
var resolvePluginMethods = (editor, plugin) => {
Object.entries(plugin.api).forEach(([apiKey, apiFunction]) => {
editor.api[apiKey] = apiFunction;
});
if (plugin.__apiExtensions && plugin.__apiExtensions.length > 0) {
plugin.__apiExtensions.forEach(
({ extension, isOverride, isPluginSpecific, isTransform }) => {
const newExtensions = extension(getEditorPlugin(editor, plugin));
if (isOverride) {
if (newExtensions.api) {
(0, import_merge2.default)(editor.api, newExtensions.api);
(0, import_merge2.default)(plugin.api, newExtensions.api);
(0, import_slate.assignLegacyApi)(editor, editor.api);
}
if (newExtensions.transforms) {
(0, import_merge2.default)(editor.transforms, newExtensions.transforms);
(0, import_merge2.default)(plugin.transforms, newExtensions.transforms);
(0, import_slate.assignLegacyTransforms)(editor, newExtensions.transforms);
}
} else if (isTransform) {
if (isPluginSpecific) {
if (!editor.transforms[plugin.key]) {
editor.transforms[plugin.key] = {};
}
if (!plugin.transforms[plugin.key]) {
plugin.transforms[plugin.key] = {};
}
(0, import_merge2.default)(editor.transforms[plugin.key], newExtensions);
(0, import_merge2.default)(plugin.transforms[plugin.key], newExtensions);
} else {
(0, import_merge2.default)(editor.transforms, newExtensions);
(0, import_merge2.default)(plugin.transforms, newExtensions);
(0, import_slate.assignLegacyTransforms)(editor, newExtensions);
}
} else {
if (isPluginSpecific) {
if (!editor.api[plugin.key]) {
editor.api[plugin.key] = {};
}
if (!plugin.api[plugin.key]) {
plugin.api[plugin.key] = {};
}
(0, import_merge2.default)(editor.api[plugin.key], newExtensions);
(0, import_merge2.default)(plugin.api[plugin.key], newExtensions);
} else {
(0, import_merge2.default)(editor.api, newExtensions);
(0, import_merge2.default)(plugin.api, newExtensions);
(0, import_slate.assignLegacyApi)(editor, editor.api);
}
}
}
);
delete plugin.__apiExtensions;
}
};
var resolvePluginShortcuts = (editor) => {
editor.meta.shortcuts = {};
editor.meta.pluginList.forEach((plugin) => {
Object.entries(plugin.shortcuts).forEach(([originalKey, hotkey]) => {
const namespacedKey = `${plugin.key}.${originalKey}`;
if (hotkey === null) {
delete editor.meta.shortcuts[namespacedKey];
} else if (hotkey && typeof hotkey === "object") {
const resolvedHotkey = { ...hotkey };
if (!resolvedHotkey.handler) {
const pluginSpecificTransforms = plugin.transforms?.[plugin.key];
const pluginSpecificApi = plugin.api?.[plugin.key];
if (pluginSpecificTransforms?.[originalKey]) {
resolvedHotkey.handler = () => {
return pluginSpecificTransforms[originalKey]();
};
} else if (pluginSpecificApi?.[originalKey]) {
resolvedHotkey.handler = () => {
return pluginSpecificApi[originalKey]();
};
}
}
resolvedHotkey.priority = resolvedHotkey.priority ?? plugin.priority;
editor.meta.shortcuts[namespacedKey] = resolvedHotkey;
}
});
});
};
var flattenAndResolvePlugins = (editor, plugins2) => {
const pluginMap = /* @__PURE__ */ new Map();
const processPlugin = (plugin) => {
const resolvedPlugin = resolvePlugin(editor, plugin);
if (resolvedPlugin.key) {
const existingPlugin = pluginMap.get(resolvedPlugin.key);
if (existingPlugin) {
pluginMap.set(
resolvedPlugin.key,
mergePlugins(existingPlugin, resolvedPlugin)
);
} else {
pluginMap.set(resolvedPlugin.key, resolvedPlugin);
}
} else {
}
if (resolvedPlugin.plugins && resolvedPlugin.plugins.length > 0) {
resolvedPlugin.plugins.forEach(processPlugin);
}
};
plugins2.forEach(processPlugin);
return pluginMap;
};
var resolveAndSortPlugins = (editor, plugins2) => {
const pluginMap = flattenAndResolvePlugins(editor, plugins2);
const enabledPlugins = Array.from(pluginMap.values()).filter(
(plugin) => plugin.enabled !== false
);
enabledPlugins.sort((a, b) => b.priority - a.priority);
const orderedPlugins = [];
const visited = /* @__PURE__ */ new Set();
const visit = (plugin) => {
if (visited.has(plugin.key)) return;
visited.add(plugin.key);
plugin.dependencies?.forEach((depKey) => {
const depPlugin = pluginMap.get(depKey);
if (depPlugin) {
visit(depPlugin);
} else {
editor.api.debug.warn(
`Plugin "${plugin.key}" depends on missing plugin "${depKey}"`,
"PLUGIN_DEPENDENCY_MISSING"
);
}
});
orderedPlugins.push(plugin);
};
enabledPlugins.forEach(visit);
return orderedPlugins;
};
var applyPluginsToEditor = (editor, plugins2) => {
editor.meta.pluginList = plugins2;
editor.plugins = Object.fromEntries(
plugins2.map((plugin) => [plugin.key, plugin])
);
};
var resolvePluginOverrides = (editor) => {
const applyOverrides = (plugins2) => {
let overriddenPlugins = [...plugins2];
const enabledOverrides = {};
const componentOverrides = {};
const pluginOverrides = {};
for (const plugin of plugins2) {
if (plugin.override.enabled) {
Object.assign(enabledOverrides, plugin.override.enabled);
}
if (plugin.override.components) {
Object.entries(plugin.override.components).forEach(
([key, component]) => {
if (!componentOverrides[key] || plugin.priority > componentOverrides[key].priority) {
componentOverrides[key] = {
component,
priority: plugin.priority
};
}
}
);
}
if (plugin.override.plugins) {
Object.entries(plugin.override.plugins).forEach(([key, value]) => {
pluginOverrides[key] = mergePlugins(pluginOverrides[key], value);
if (value.enabled !== void 0) {
enabledOverrides[key] = value.enabled;
}
});
}
}
overriddenPlugins = overriddenPlugins.map((p) => {
let updatedPlugin = { ...p };
if (pluginOverrides[p.key]) {
updatedPlugin = mergePlugins(updatedPlugin, pluginOverrides[p.key]);
}
if (componentOverrides[p.key] && (!p.render.node && !p.node.component || componentOverrides[p.key].priority > p.priority)) {
updatedPlugin.render.node = componentOverrides[p.key].component;
updatedPlugin.node.component = componentOverrides[p.key].component;
}
const enabled = enabledOverrides[p.key] ?? updatedPlugin.enabled;
if ((0, import_utils2.isDefined)(enabled)) {
updatedPlugin.enabled = enabled;
}
return updatedPlugin;
});
return overriddenPlugins.filter((p) => p.enabled !== false).map((plugin) => ({
...plugin,
plugins: applyOverrides(plugin.plugins || [])
}));
};
applyPluginsToEditor;
editor.meta.pluginList = applyOverrides(editor.meta.pluginList);
editor.plugins = Object.fromEntries(
editor.meta.pluginList.map((plugin) => [plugin.key, plugin])
);
};
// src/lib/plugins/AstPlugin.ts
var AstPlugin = createSlatePlugin({
key: "ast",
parser: {
format: "application/x-slate-fragment",
deserialize: ({ data }) => {
const decoded = decodeURIComponent(window.atob(data));
let parsed;
try {
parsed = JSON.parse(decoded);
} catch {
}
return parsed;
}
}
});
// src/lib/plugins/HistoryPlugin.ts
var import_slate2 = require("@udecode/slate");
var withPlateHistory = ({ editor }) => (0, import_slate2.withHistory)(editor);
var HistoryPlugin = createSlatePlugin({
key: "history",
extendEditor: withPlateHistory
});
// src/lib/plugins/paragraph/BaseParagraphPlugin.ts
var BaseParagraphPlugin = createSlatePlugin({
key: "p",
node: {
isElement: true
},
parsers: {
html: {
deserializer: {
rules: [
{
validNodeName: "P"
}
],
query: ({ element }) => element.style.fontFamily !== "Consolas"
}
}
},
rules: {
merge: { removeEmpty: true }
}
});
// src/lib/plugins/override/withBreakRules.ts
var import_slate3 = require("@udecode/slate");
var withBreakRules = (ctx) => {
const {
editor,
tf: { insertBreak }
} = ctx;
const checkMatchRulesOverride = (rule, blockNode, blockPath) => {
const matchRulesKeys = editor.meta.pluginCache.rules.match;
for (const key of matchRulesKeys) {
const overridePlugin = editor.getPlugin({ key });
if (overridePlugin.rules?.break && overridePlugin.rules?.match?.({
...ctx,
node: blockNode,
path: blockPath,
rule
})) {
return overridePlugin.rules.break;
}
}
return null;
};
const executeBreakAction = (action, blockPath) => {
if (action === "reset") {
editor.tf.resetBlock({ at: blockPath });
return true;
}
if (action === "exit") {
editor.tf.insertExitBreak();
return true;
}
if (action === "deleteExit") {
editor.tf.deleteBackward("character");
editor.tf.insertExitBreak();
return true;
}
if (action === "lineBreak") {
editor.tf.insertSoftBreak();
return true;
}
return false;
};
return {
transforms: {
insertBreak() {
if (editor.selection && editor.api.isCollapsed()) {
const block = editor.api.block();
if (block) {
const [blockNode, blockPath] = block;
const plugin = getPluginByType(editor, blockNode.type);
const breakRules = plugin?.rules.break;
if (editor.api.isEmpty(editor.selection, {
block: true
})) {
const overrideBreakRules = checkMatchRulesOverride(
"break.empty",
blockNode,
blockPath
);
const effectiveBreakRules = overrideBreakRules || breakRules;
const emptyAction = effectiveBreakRules?.empty;
if (executeBreakAction(emptyAction, blockPath)) return;
}
if (!editor.api.isEmpty(editor.selection, {
block: true
}) && editor.api.isAt({ end: true })) {
const range = editor.api.range("before", editor.selection);
if (range) {
const char = editor.api.string(range);
if (char === "\n") {
const overrideBreakRules = checkMatchRulesOverride(
"break.emptyLineEnd",
blockNode,
blockPath
);
const effectiveBreakRules = overrideBreakRules || breakRules;
const emptyLineEndAction = effectiveBreakRules?.emptyLineEnd;
if (executeBreakAction(emptyLineEndAction, blockPath)) return;
}
}
}
const overrideDefaultBreakRules = checkMatchRulesOverride(
"break.default",
blockNode,
blockPath
);
const defaultAction = (overrideDefaultBreakRules || breakRules)?.default;
if (executeBreakAction(defaultAction, blockPath)) return;
const overrideSplitResetBreakRules = checkMatchRulesOverride(
"break.splitReset",
blockNode,
blockPath
);
const splitReset = overrideSplitResetBreakRules?.splitReset ?? breakRules?.splitReset;
if (splitReset) {
const isAtStart = editor.api.isAt({ start: true });
insertBreak();
editor.tf.resetBlock({
at: isAtStart ? blockPath : import_slate3.PathApi.next(blockPath)
});
return;
}
}
}
insertBreak();
}
}
};
};
// src/lib/plugins/override/withDeleteRules.ts
var import_slate4 = require("@udecode/slate");
var withDeleteRules = (ctx) => {
const {
editor,
tf: { deleteBackward, deleteForward, deleteFragment }
} = ctx;
const resetMarks = () => {
if (editor.api.isAt({ start: true })) {
editor.tf.removeMarks();
}
};
const checkMatchRulesOverride = (rule, blockNode, blockPath) => {
const matchRulesKeys = editor.meta.pluginCache.rules.match;
for (const key of matchRulesKeys) {
const overridePlugin = editor.getPlugin({ key });
if (overridePlugin.rules?.delete && overridePlugin.rules?.match?.({
...ctx,
node: blockNode,
path: blockPath,
rule
})) {
return overridePlugin.rules.delete;
}
}
return null;
};
const executeDeleteAction = (action, blockPath) => {
if (action === "reset") {
editor.tf.resetBlock({ at: blockPath });
return true;
}
return false;
};
return {
transforms: {
deleteBackward(unit) {
if (editor.selection && editor.api.isCollapsed()) {
const block = editor.api.block();
if (block) {
const [blockNode, blockPath] = block;
const plugin = getPluginByType(editor, blockNode.type);
const deleteRules = plugin?.rules.delete;
if (editor.api.isAt({ start: true })) {
const overrideDeleteRules = checkMatchRulesOverride(
"delete.start",
blockNode,
blockPath
);
const effectiveDeleteRules = overrideDeleteRules || deleteRules;
const startAction = effectiveDeleteRules?.start;
if (executeDeleteAction(startAction, blockPath)) {
return;
}
}
if (editor.api.isEmpty(editor.selection, { block: true })) {
const overrideDeleteRules = checkMatchRulesOverride(
"delete.empty",
blockNode,
blockPath
);
const effectiveDeleteRules = overrideDeleteRules || deleteRules;
const emptyAction = effectiveDeleteRules?.empty;
if (executeDeleteAction(emptyAction, blockPath)) return;
}
}
if (import_slate4.PointApi.equals(editor.selection.anchor, editor.api.start([]))) {
editor.tf.resetBlock({ at: [0] });
return;
}
}
deleteBackward(unit);
resetMarks();
},
deleteForward(unit) {
deleteForward(unit);
resetMarks();
},
deleteFragment(options) {
if (editor.selection && import_slate4.RangeApi.equals(editor.selection, editor.api.range([]))) {
editor.tf.reset({
children: true,
select: true
});
return;
}
deleteFragment(options);
resetMarks();
}
}
};
};
// src/lib/plugins/override/withMergeRules.ts
var import_slate5 = require("@udecode/slate");
var withMergeRules = (ctx) => {
const {
editor,
tf: { removeNodes }
} = ctx;
const checkMatchRulesOverride = (rule, blockNode, blockPath) => {
const matchRulesKeys = editor.meta.pluginCache.rules.match;
for (const key of matchRulesKeys) {
const overridePlugin = editor.getPlugin({ key });
if (overridePlugin.rules.merge && overridePlugin.rules?.match?.({
...ctx,
node: blockNode,
path: blockPath,
rule
})) {
return overridePlugin.rules.merge;
}
}
return null;
};
return {
api: {
shouldMergeNodes(prevNodeEntry, nextNodeEntry, { reverse } = {}) {
const [prevNode, prevPath] = prevNodeEntry;
const [, nextPath] = nextNodeEntry;
const [curNode, curPath] = reverse ? prevNodeEntry : nextNodeEntry;
const [targetNode, targetPath] = reverse ? nextNodeEntry : prevNodeEntry;
if (import_slate5.TextApi.isText(prevNode) && prevNode.text === "" && prevPath.at(-1) !== 0) {
editor.tf.removeNodes({ at: prevPath });
return false;
}
const shouldRemove = (node, path) => {
const plugin = getPluginByType(editor, node.type);
if (!plugin) {
return true;
}
const mergeRules = plugin.rules.merge;
if (!mergeRules?.removeEmpty) {
return false;
}
const overrideMergeRules = checkMatchRulesOverride(
"merge.removeEmpty",
node,
path
);
if (overrideMergeRules?.removeEmpty === false) {
return false;
}
return true;
};
if (import_slate5.ElementApi.isElement(targetNode) && editor.api.isVoid(targetNode)) {
if (shouldRemove(targetNode, targetPath)) {
editor.tf.removeNodes({ at: prevPath });
} else if (import_slate5.ElementApi.isElement(curNode) && editor.api.isEmpty(curNode)) {
editor.tf.removeNodes({ at: curPath });
}
return false;
}
if (import_slate5.ElementApi.isElement(prevNode) && editor.api.isEmpty(prevNode) && import_slate5.PathApi.isSibling(prevPath, nextPath) && shouldRemove(prevNode, prevPath)) {
editor.tf.removeNodes({ at: prevPath });
return false;
}
return true;
}
},
transforms: {
removeNodes(options = {}) {
if (options.event?.type === "mergeNodes" && options.at) {
const nodeEntry = editor.api.node(options.at);
if (nodeEntry) {
const [node, path] = nodeEntry;
if (import_slate5.ElementApi.isElement(node)) {
const plugin = getPluginByType(editor, node.type);
if (plugin) {
const mergeRules = plugin.rules.merge;
const overrideMergeRules = checkMatchRulesOverride(
"merge.removeEmpty",
node,
path
);
const shouldNotRemove = overrideMergeRules?.removeEmpty === false || mergeRules?.removeEmpty === false;
if (shouldNotRemove) {
return;
}
}
}
}
}
removeNodes(options);
}
}
};
};
// src/lib/plugins/override/withNormalizeRules.ts
var import_slate6 = require("@udecode/slate");
var withNormalizeRules = (ctx) => {
const {
editor,
tf: { normalizeNode }
} = ctx;
const checkMatchRulesOverride = (rule, node, path) => {
const matchRulesKeys = editor.meta.pluginCache.rules.match;
for (const key of matchRulesKeys) {
const overridePlugin = editor.getPlugin({ key });
if (overridePlugin.rules?.normalize && overridePlugin.rules?.match?.({
...ctx,
node,
path,
rule
})) {
return overridePlugin.rules.normalize;
}
}
return null;
};
return {
transforms: {
normalizeNode([node, path]) {
if (import_slate6.ElementApi.isElement(node) && node.type) {
const plugin = getPluginByType(editor, node.type);
const normalizeRules = plugin?.rules.normalize;
const overridenormalizeRules = checkMatchRulesOverride(
"normalize.removeEmpty",
node,
path
);
const effectivenormalizeRules = overridenormalizeRules || normalizeRules;
if (effectivenormalizeRules?.removeEmpty && editor.api.isEmpty(node)) {
editor.tf.removeNodes({ at: path });
return;
}
}
normalizeNode([node, path]);
}
}
};
};
// src/lib/plugins/override/OverridePlugin.ts
var withOverrides = ({
api: { isInline, isSelectable, isVoid, markableVoid },
editor
}) => {
const voidTypes = editor.meta.pluginCache.node.isVoid;
const inlineTypes = editor.meta.pluginCache.node.isInline;
const markableVoidTypes = editor.meta.pluginCache.node.isMarkableVoid;
const notSelectableTypes = editor.meta.pluginCache.node.isNotSelectable;
return {
api: {
create: {
block: (node) => ({
children: [{ text: "" }],
type: editor.getType(BaseParagraphPlugin.key),
...node
})
},
isInline(element) {
return inlineTypes.includes(element.type) ? true : isInline(element);
},
isSelectable(element) {
return notSelectableTypes.includes(element.type) ? false : isSelectable(element);
},
isVoid(element) {
return voidTypes.includes(element.type) ? true : isVoid(element);
},
markableVoid(element) {
return markableVoidTypes.includes(element.type) ? true : markableVoid(element);
}
}
};
};
var OverridePlugin = createSlatePlugin({
key: "override"
}).overrideEditor(withOverrides).overrideEditor(withBreakRules).overrideEditor(withDeleteRules).overrideEditor(withMergeRules).overrideEditor(withNormalizeRules);
// src/internal/plugin/pipeInsertFragment.ts
var pipeInsertFragment = (editor, injectedPlugins, { fragment, ...options }) => {
editor.tf.withoutNormalizing(() => {
injectedPlugins.some((p) => {
return p.parser?.preInsert?.({
...getEditorPlugin(editor, p),
fragment,
...options
}) === true;
});
editor.tf.insertFragment(fragment);
});
};
// src/internal/plugin/pipeTransformData.ts
var pipeTransformData = (editor, plugins2, { data, dataTransfer }) => {
plugins2.forEach((p) => {
const transformData = p.parser?.transformData;
if (!transformData) return;
data = transformData({
...getEditorPlugin(editor, p),
data,
dataTransfer
});
});
return data;
};
// src/internal/plugin/pipeTransformFragment.ts
var pipeTransformFragment = (editor, plugins2, { fragment, ...options }) => {
plugins2.forEach((p) => {
const transformFragment = p.parser?.transformFragment;
if (!transformFragment) return;
fragment = transformFragment({
fragment,
...options,
...getEditorPlugin(editor, p)
});
});
return fragment;
};
// src/lib/utils/applyDeepToNodes.ts
var import_slate7 = require("@udecode/slate");
var applyDeepToNodes = ({
apply,
node,
path = [],
query,
source
}) => {
const entry = [node, path];
if ((0, import_slate7.queryNode)(entry, query)) {
if (typeof source === "function") {
apply(node, source());
} else {
apply(node, source);
}
}
if (!import_slate7.NodeApi.isAncestor(node)) return;
node.children.forEach((child, index) => {
applyDeepToNodes({
apply,
node: child,
path: path.concat([index]),
query,
source
});
});
};
// src/lib/utils/defaultsDeepToNodes.ts
var import_defaults = __toESM(require("lodash/defaults.js"));
var defaultsDeepToNodes = (options) => {
applyDeepToNodes({ ...options, apply: import_defaults.default });
};
// src/lib/utils/getInjectMatch.ts
var import_slate8 = require("@udecode/slate");
// src/lib/utils/getKeysByTypes.ts
var getKeysByTypes = (editor, types) => {
return Object.values(editor.plugins).filter((plugin) => types.includes(plugin.node.type)).map((plugin) => plugin.key);
};
var getKeyByType = (editor, type) => {
const plugin = Object.values(editor.plugins).find(
(plugin2) => plugin2.node.type === type
);
return plugin?.key ?? type;
};
// src/lib/utils/getInjectMatch.ts
var getInjectMatch = (editor, plugin) => {
return (node, path) => {
const {
inject: {
excludeBelowPlugins,
excludePlugins,
isBlock: _isBlock,
isElement: _isElement,
isLeaf,
maxLevel,
targetPlugins
}
} = plugin;
const element = import_slate8.ElementApi.isElement(node) ? node : void 0;
if (_isElement && !element) return false;
if (_isBlock && (!element || !editor.api.isBlock(element))) return false;
if (isLeaf && element) return false;
if (element?.type) {
if (excludePlugins?.includes(getKeyByType(editor, element.type))) {
return false;
}
if (targetPlugins && !targetPlugins.includes(getKeyByType(editor, element.type))) {
return false;
}
}
if (excludeBelowPlugins || maxLevel) {
if (maxLevel && path.length > maxLevel) {
return false;
}
if (excludeBelowPlugins) {
const excludeTypes = getKeysByTypes(editor, excludeBelowPlugins);
const isBelow = editor.api.above({
at: path,
match: (n) => import_slate8.ElementApi.isElement(n) && excludeTypes.includes(n.type)
});
if (isBelow) return false;
}
}
return true;
};
};
// src/lib/utils/getInjectedPlugins.ts
var getInjectedPlugins = (editor, plugin) => {
const injectedPlugins = [];
[...editor.meta.pluginList].reverse().forEach((p) => {
const injectedPlugin = p.inject.plugins?.[plugin.key];
if (injectedPlugin) injectedPlugins.push(injectedPlugin);
});
return [plugin, ...injectedPlugins];
};
// src/lib/utils/getPluginNodeProps.ts
var import_pick = __toESM(require("lodash/pick.js"));
// src/lib/static/pipeRenderElementStatic.tsx
var import_react4 = __toESM(require("react"));
// src/lib/static/components/slate-nodes.tsx
var import_react = __toESM(require("react"));
var import_clsx = require("clsx");
var useNodeAttributes = (props, ref) => {
return {
...props.attributes,
className: (0, import_clsx.clsx)(props.attributes.className, props.className) || void 0,
ref,
style: { ...props.attributes.style, ...props.style }
};
};
var SlateElement = import_react.default.forwardRef(function SlateElement2({ as: Tag = "div", children, ...props }, ref) {
const attributes = useNodeAttributes(props, ref);
const block = !!props.element.id && !!props.editor.api.isBlock(props.element);
return /* @__PURE__ */ import_react.default.createElement(
Tag,
{
"data-slate-node": "element",
"data-slate-inline": attributes["data-slate-inline"],
"data-block-id": block ? props.element.id : void 0,
...attributes,
style: {
position: "relative",
...attributes?.style
}
},
children
);
});
var SlateText = import_react.default.forwardRef(({ as: Tag = "span", children, ...props }, ref) => {
const attributes = useNodeAttributes(props, ref);
return /* @__PURE__ */ import_react.default.createElement(Tag, { ...attributes