UNPKG

@udecode/plate-core

Version:

The core of Plate – a plugin system for slate

1 lines 260 kB
{"version":3,"sources":["../../src/react/slate-react.ts","../../src/react/components/DefaultLeaf.tsx","../../src/lib/editor/withSlate.ts","../../src/internal/utils/isFunction.ts","../../src/internal/utils/mergePlugins.ts","../../src/lib/plugin/createSlatePlugin.ts","../../src/lib/plugin/getEditorPlugin.ts","../../src/internal/plugin/resolvePlugin.ts","../../src/lib/plugin/getSlatePlugin.ts","../../src/internal/plugin/pipeNormalizeInitialValue.ts","../../src/internal/plugin/resolvePlugins.ts","../../src/lib/plugins/AstPlugin.ts","../../src/lib/plugins/DOMPlugin.ts","../../src/lib/plugins/HistoryPlugin.ts","../../src/lib/plugins/InlineVoidPlugin.ts","../../src/internal/plugin/pipeInsertFragment.ts","../../src/internal/plugin/pipeTransformData.ts","../../src/internal/plugin/pipeTransformFragment.ts","../../src/lib/utils/applyDeepToNodes.ts","../../src/lib/utils/getInjectMatch.ts","../../src/lib/utils/getKeysByTypes.ts","../../src/lib/utils/getInjectedPlugins.ts","../../src/lib/utils/getPluginNodeProps.ts","../../src/lib/static/utils/getNodeDataAttributes.ts","../../src/internal/plugin/pipeInjectNodeProps.tsx","../../src/internal/plugin/pluginInjectNodeProps.ts","../../src/lib/static/utils/pipeDecorate.ts","../../src/lib/static/deserialize/checkUtils.ts","../../src/lib/utils/getSlateClass.ts","../../src/lib/utils/mergeDeepToNodes.ts","../../src/lib/utils/normalizeDescendantsToDocumentFragment.ts","../../src/lib/plugins/debug/DebugPlugin.ts","../../src/lib/plugins/html/HtmlPlugin.ts","../../src/lib/plugins/html/utils/isHtmlElement.ts","../../src/lib/plugins/html/utils/isHtmlText.ts","../../src/lib/plugins/html/utils/inlineTagNames.ts","../../src/lib/plugins/html/utils/isHtmlInlineElement.ts","../../src/lib/plugins/html/utils/isHtmlBlockElement.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseString.ts","../../src/lib/plugins/html/utils/collapse-white-space/isLastNonEmptyTextOfInlineFormattingContext.ts","../../src/lib/plugins/html/utils/collapse-white-space/stateTransforms.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpaceText.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpaceNode.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpaceChildren.ts","../../src/lib/plugins/html/utils/collapse-white-space/inferWhiteSpaceRule.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpaceElement.ts","../../src/lib/plugins/html/utils/collapse-white-space/collapseWhiteSpace.ts","../../src/lib/plugins/html/utils/htmlBodyToFragment.ts","../../src/lib/plugins/html/utils/deserializeHtmlNodeChildren.ts","../../src/lib/plugins/html/utils/htmlBrToNewLine.ts","../../src/lib/plugins/html/utils/htmlElementToElement.ts","../../src/lib/plugins/html/utils/pluginDeserializeHtml.ts","../../src/lib/plugins/html/utils/getDataNodeProps.ts","../../src/lib/plugins/html/utils/pipeDeserializeHtmlElement.ts","../../src/lib/plugins/html/utils/htmlElementToLeaf.ts","../../src/lib/plugins/html/utils/pipeDeserializeHtmlLeaf.ts","../../src/lib/plugins/html/utils/htmlTextNodeToString.ts","../../src/lib/plugins/html/utils/deserializeHtmlNode.ts","../../src/lib/plugins/html/utils/deserializeHtmlElement.ts","../../src/lib/plugins/html/utils/htmlStringToDOMNode.ts","../../src/lib/plugins/html/utils/deserializeHtml.ts","../../src/lib/plugins/html/utils/parseHtmlDocument.ts","../../src/lib/plugins/length/LengthPlugin.ts","../../src/lib/plugins/paragraph/BaseParagraphPlugin.ts","../../src/lib/plugins/slate-extension/SlateExtensionPlugin.ts","../../src/lib/utils/pipeInsertDataQuery.ts","../../src/lib/plugins/ParserPlugin.ts","../../src/lib/plugins/getCorePlugins.ts","../../src/lib/libs/zustand.ts","../../src/react/plugin/toPlatePlugin.ts","../../src/react/plugin/createPlatePlugin.ts","../../src/react/plugin/getEditorPlugin.ts","../../src/react/plugin/getPlugin.ts","../../src/react/plugin/omitPluginContext.ts","../../src/react/components/EditorHotkeysEffect.tsx","../../src/react/stores/element/useElement.ts","../../src/react/stores/plate/createPlateStore.ts","../../src/react/libs/jotai.ts","../../src/react/editor/withPlate.ts","../../src/react/plugins/SlateReactExtensionPlugin.ts","../../src/react/plugins/event-editor/EventEditorStore.ts","../../src/react/plugins/event-editor/useFocusEditorEvents.ts","../../src/react/plugins/event-editor/EventEditorPlugin.ts","../../src/react/plugins/event-editor/getEventPlateId.ts","../../src/react/plugins/paragraph/ParagraphPlugin.tsx","../../src/react/plugins/react/withPlateReact.ts","../../src/react/plugins/react/ReactPlugin.ts","../../src/react/editor/getPlateCorePlugins.ts","../../src/react/utils/createPlateFallbackEditor.ts","../../src/react/utils/dom-attributes.ts","../../src/react/utils/getRenderNodeProps.ts","../../src/react/utils/pipeHandler.ts","../../src/react/utils/pipeOnChange.ts","../../src/react/utils/pipeRenderElement.tsx","../../src/react/hooks/useEditableProps.ts","../../src/react/utils/pipeRenderLeaf.tsx","../../src/react/utils/pluginRenderLeaf.tsx","../../src/react/hooks/useNodePath.ts","../../src/react/hooks/useSlateProps.ts","../../src/react/utils/pluginRenderElement.tsx","../../src/react/stores/element/useElementStore.ts","../../src/react/stores/plate-controller/plateControllerStore.ts","../../src/react/stores/plate/useEditorPlugin.ts","../../src/react/stores/plate/useEditorSelector.ts","../../src/react/stores/plate/usePluginOption.ts","../../src/react/stores/element/useElementSelector.ts","../../src/react/stores/element/usePath.ts","../../src/react/stores/event-editor/useEventPlateId.ts","../../src/react/components/EditorMethodsEffect.ts","../../src/react/components/EditorRefEffect.tsx","../../src/react/components/EditorStateEffect.tsx","../../src/react/components/Plate.tsx","../../src/internal/hooks/usePlateInstancesWarn.ts","../../src/react/components/PlateContent.tsx","../../src/react/components/PlateControllerEffect.ts","../../src/react/components/PlateSlate.tsx","../../src/react/components/PlateTest.tsx","../../src/react/editor/usePlateEditor.ts","../../src/react/components/withHOC.tsx"],"sourcesContent":["// Components\nexport {\n type RenderPlaceholderProps,\n DefaultElement,\n DefaultPlaceholder,\n Editable,\n Slate,\n} from 'slate-react';\n\n// Hooks\nexport {\n useComposing,\n useFocused,\n useReadOnly,\n useSelected,\n} from 'slate-react';\n\n// Plugin\nexport { withReact } from 'slate-react';\n","import React from 'react';\n\nimport type { TText } from '@udecode/slate';\n\nimport { clsx } from 'clsx';\n\nimport { type PlateRenderLeafProps, omitPluginContext } from '../plugin';\n\ntype DefaultLeafProps = {\n leafToAttributes?: (leaf: TText) => any;\n} & PlateRenderLeafProps &\n React.HTMLAttributes<HTMLSpanElement>;\n\nconst useDefaultLeaf = (props: DefaultLeafProps) => {\n const { attributes, leaf, leafToAttributes, nodeProps, text, ...rootProps } =\n omitPluginContext(props as any);\n\n return {\n props: {\n ...attributes,\n ...rootProps,\n ...nodeProps,\n ...leafToAttributes?.(leaf),\n className: clsx(props.className, nodeProps?.className),\n },\n };\n};\n\nexport function DefaultLeaf(props: DefaultLeafProps) {\n const { props: rootProps } = useDefaultLeaf(props);\n\n return <span {...rootProps} />;\n}\n","import {\n type Editor,\n type TSelection,\n type Value,\n createEditor,\n} from '@udecode/slate';\nimport { nanoid } from 'nanoid';\n\nimport type { AnyPluginConfig } from '../plugin/BasePlugin';\nimport type { AnySlatePlugin } from '../plugin/SlatePlugin';\nimport type { InferPlugins, SlateEditor, TSlateEditor } from './SlateEditor';\n\nimport { pipeNormalizeInitialValue } from '../../internal/plugin/pipeNormalizeInitialValue';\nimport { resolvePlugins } from '../../internal/plugin/resolvePlugins';\nimport { createSlatePlugin } from '../plugin/createSlatePlugin';\nimport { getPluginType, getSlatePlugin } from '../plugin/getSlatePlugin';\nimport { type CorePlugin, getCorePlugins } from '../plugins/getCorePlugins';\n\nexport type BaseWithSlateOptions<P extends AnyPluginConfig = CorePlugin> = {\n id?: string;\n /**\n * Select the editor after initialization.\n *\n * @default false\n *\n * - `true` | 'end': Select the end of the editor\n * - `false`: Do not select anything\n * - `'start'`: Select the start of the editor\n */\n autoSelect?: boolean | 'end' | 'start';\n /** Specifies the maximum number of characters allowed in the editor. */\n maxLength?: number;\n plugins?: P[];\n selection?: TSelection;\n /**\n * When `true`, it will normalize the initial `value` passed to the `editor`.\n * This is useful when adding normalization rules on already existing\n * content.\n *\n * @default false\n */\n shouldNormalizeEditor?: boolean;\n};\n\nexport type WithSlateOptions<\n V extends Value = Value,\n P extends AnyPluginConfig = CorePlugin,\n> = BaseWithSlateOptions<P> &\n Pick<\n Partial<AnySlatePlugin>,\n | 'api'\n | 'decorate'\n | 'extendEditor'\n | 'inject'\n | 'normalizeInitialValue'\n | 'options'\n | 'override'\n | 'transforms'\n > & {\n value?: ((editor: SlateEditor) => V) | V | string;\n /** Function to configure the root plugin */\n rootPlugin?: (plugin: AnySlatePlugin) => AnySlatePlugin;\n };\n\n/**\n * Applies Plate enhancements to an editor instance (non-React version).\n *\n * @remarks\n * This function supports server-side usage as it doesn't include the\n * ReactPlugin.\n * @see {@link createSlateEditor} for a higher-level non-React editor creation function.\n * @see {@link createPlateEditor} for a higher-level React editor creation function.\n * @see {@link usePlateEditor} for a React memoized version.\n * @see {@link withPlate} for the React-specific enhancement function.\n */\nexport const withSlate = <\n V extends Value = Value,\n P extends AnyPluginConfig = CorePlugin,\n>(\n e: Editor,\n {\n id,\n autoSelect,\n maxLength,\n plugins = [],\n rootPlugin,\n selection,\n shouldNormalizeEditor,\n value,\n ...pluginConfig\n }: WithSlateOptions<V, P> = {}\n): TSlateEditor<V, InferPlugins<P[]>> => {\n const editor = e as SlateEditor;\n\n editor.id = id ?? editor.id ?? nanoid();\n editor.key = editor.key ?? nanoid();\n editor.isFallback = false;\n editor.prevSelection = null;\n editor.currentKeyboardEvent = null;\n\n editor.getApi = () => editor.api as any;\n editor.getTransforms = () => editor.transforms as any;\n editor.getPlugin = (plugin) => getSlatePlugin(editor, plugin) as any;\n editor.getType = (plugin) => getPluginType(editor, plugin);\n editor.getInjectProps = (plugin) => {\n return (\n editor.getPlugin<AnySlatePlugin>(plugin).inject?.nodeProps ?? ({} as any)\n );\n };\n editor.getOptionsStore = (plugin) => {\n return editor.getPlugin(plugin).optionsStore;\n };\n editor.getOptions = (plugin) => {\n const store = editor.getOptionsStore(plugin);\n\n if (!store) return editor.getPlugin(plugin).options;\n\n return editor.getOptionsStore(plugin).get('state');\n };\n editor.getOption = (plugin, key, ...args) => {\n const store = editor.getOptionsStore(plugin);\n\n if (!store) return editor.getPlugin(plugin).options[key];\n\n if (!(key in store.get('state')) && !(key in store.selectors)) {\n editor.api.debug.error(\n `editor.getOption: ${key as string} option is not defined in plugin ${plugin.key}.`,\n 'OPTION_UNDEFINED'\n );\n return;\n }\n\n return (store.get as any)(key, ...args);\n };\n editor.setOption = (plugin: any, key: any, ...args: any) => {\n const store = editor.getOptionsStore(plugin);\n\n if (!store) return;\n\n if (!(key in store.get('state'))) {\n editor.api.debug.error(\n `editor.setOption: ${key} option is not defined in plugin ${plugin.key}.`,\n 'OPTION_UNDEFINED'\n );\n return;\n }\n\n (store.set as any)(key, ...args);\n };\n editor.setOptions = (plugin: any, options: any) => {\n const store = editor.getOptionsStore(plugin);\n\n if (!store) return;\n if (typeof options === 'object') {\n store.set('state', (draft: any) => {\n Object.assign(draft, options);\n });\n } else if (typeof options === 'function') {\n store.set('state', options);\n }\n };\n\n // Plugin initialization code\n const corePlugins = getCorePlugins({\n maxLength,\n plugins,\n });\n\n let rootPluginInstance = createSlatePlugin({\n key: 'root',\n priority: 10_000,\n ...pluginConfig,\n plugins: [...corePlugins, ...plugins],\n });\n\n // Apply rootPlugin configuration if provided\n if (rootPlugin) {\n rootPluginInstance = rootPlugin(rootPluginInstance) as any;\n }\n\n resolvePlugins(editor, [rootPluginInstance]);\n\n if (typeof value === 'string') {\n editor.children = editor.api.html.deserialize({ element: value }) as Value;\n } else if (typeof value === 'function') {\n editor.children = value(editor);\n } else if (value) {\n editor.children = value;\n }\n if (!editor.children || editor.children?.length === 0) {\n editor.children = editor.api.create.value();\n }\n if (selection) {\n editor.selection = selection;\n } else if (autoSelect) {\n const edge = autoSelect === 'start' ? 'start' : 'end';\n const target = edge === 'start' ? editor.api.start([]) : editor.api.end([]);\n editor.tf.select(target!);\n }\n if (editor.children.length > 0) {\n pipeNormalizeInitialValue(editor);\n }\n if (shouldNormalizeEditor) {\n editor.tf.normalize({ force: true });\n }\n\n return editor as any;\n};\n\nexport type CreateSlateEditorOptions<\n V extends Value = Value,\n P extends AnyPluginConfig = CorePlugin,\n> = WithSlateOptions<V, P> & {\n /**\n * Initial editor to be extended with `withPlate`.\n *\n * @default createEditor()\n */\n editor?: Editor;\n};\n\n/**\n * Creates a Slate editor without React-specific enhancements.\n *\n * @see {@link createPlateEditor} for a React-specific version of editor creation.\n * @see {@link usePlateEditor} for a memoized React version.\n * @see {@link withSlate} for the underlying function that applies Slate enhancements to an editor.\n */\nexport const createSlateEditor = <\n V extends Value = Value,\n P extends AnyPluginConfig = CorePlugin,\n>({\n editor = createEditor(),\n ...options\n}: CreateSlateEditorOptions<V, P> = {}) => {\n return withSlate<V, P>(editor, options);\n};\n","export function isFunction(value: any): value is Function {\n return typeof value === 'function';\n}\n","import mergeWith from 'lodash/mergeWith.js';\n\nimport type { SlatePlugin } from '../../lib';\n\nexport function mergePlugins<T>(basePlugin: T, ...sourcePlugins: any[]): T {\n return mergeWith(\n {},\n basePlugin,\n ...sourcePlugins,\n (objValue: unknown, srcValue: unknown, key: keyof SlatePlugin) => {\n // Overwrite array (including plugins) without cloning\n if (Array.isArray(srcValue)) {\n return srcValue;\n }\n // Shallow merge options\n if (key === 'options') {\n return { ...(objValue as any), ...(srcValue as any) };\n }\n }\n );\n}\n","import type { Modify } from '@udecode/utils';\n\nimport type { SlateEditor } from '../editor/SlateEditor';\nimport type { AnyPluginConfig, PluginConfig } from './BasePlugin';\nimport type {\n SlatePlugin,\n SlatePluginMethods,\n SlatePlugins,\n} from './SlatePlugin';\n\nimport { isFunction } from '../../internal/utils/isFunction';\nimport { mergePlugins } from '../../internal/utils/mergePlugins';\n\ntype SlatePluginConfig<\n K extends string = any,\n O = {},\n A = {},\n T = {},\n S = {},\n> = Omit<\n Partial<\n Modify<\n SlatePlugin<PluginConfig<K, O, A, T, S>>,\n {\n node?: Partial<SlatePlugin<PluginConfig<K, O, A, T, S>>['node']>;\n }\n >\n >,\n keyof SlatePluginMethods | 'optionsStore'\n>;\n\ntype TSlatePluginConfig<C extends AnyPluginConfig = PluginConfig> = Omit<\n Partial<\n Modify<\n SlatePlugin<C>,\n {\n node?: Partial<SlatePlugin<C>['node']>;\n }\n >\n >,\n keyof SlatePluginMethods | 'optionsStore'\n>;\n\n/**\n * Creates a new Plate plugin with the given configuration.\n *\n * @remarks\n * - The plugin's key is required and specified by the K generic.\n * - The `__extensions` array stores functions to be applied when `resolvePlugin`\n * is called with an editor.\n * - The `extend` method adds new extensions to be applied later.\n * - The `extendPlugin` method extends an existing plugin (including nested\n * plugins) or adds a new one if not found.\n *\n * @example\n * const myPlugin = createSlatePlugin<\n * 'myPlugin',\n * MyOptions,\n * MyApi,\n * MyTransforms\n * >({\n * key: 'myPlugin',\n * options: { someOption: true },\n * transforms: { someTransform: () => {} },\n * });\n *\n * const extendedPlugin = myPlugin.extend({\n * options: { anotherOption: false },\n * });\n *\n * const pluginWithNestedExtension = extendedPlugin.extendPlugin(\n * nestedPlugin,\n * {\n * options: { nestedOption: true },\n * }\n * );\n *\n * @template K - The literal type of the plugin key.\n * @template O - The type of the plugin options.\n * @template A - The type of the plugin utilities.\n * @template T - The type of the plugin transforms.\n * @template S - The type of the plugin storage.\n * @param {Partial<SlatePlugin<K, O, A, T, S>>} config - The configuration\n * object for the plugin.\n * @returns {SlatePlugin<K, O, A, T, S>} A new Plate plugin instance with the\n * following properties and methods:\n *\n * - All properties from the input config, merged with default values.\n * - `configure`: A method to create a new plugin instance with updated options.\n * - `extend`: A method to create a new plugin instance with additional\n * configuration.\n * - `extendPlugin`: A method to extend an existing plugin (including nested\n * plugins) or add a new one if not found.\n */\nexport function createSlatePlugin<\n K extends string = any,\n O = {},\n A = {},\n T = {},\n S = {},\n>(\n config:\n | ((editor: SlateEditor) => SlatePluginConfig<K, O, A, T, S>)\n | SlatePluginConfig<K, O, A, T, S> = {}\n): SlatePlugin<PluginConfig<K, O, A, T, S>> {\n let baseConfig: Partial<SlatePlugin<PluginConfig<K, O, A, T, S>>>;\n let initialExtension: any;\n\n if (isFunction(config)) {\n baseConfig = { key: '' as K };\n initialExtension = (editor: any) => config(editor);\n } else {\n baseConfig = config as any;\n }\n\n const key = baseConfig.key ?? '';\n\n const plugin = mergePlugins(\n {\n key,\n __apiExtensions: [],\n __configuration: null,\n __extensions: initialExtension ? [initialExtension] : [],\n __selectorExtensions: [],\n api: {},\n dependencies: [],\n editor: {},\n handlers: {},\n inject: {},\n node: { type: key },\n options: {},\n override: {},\n parser: {},\n parsers: {},\n plugins: [],\n priority: 100,\n render: {},\n shortcuts: {},\n transforms: {},\n },\n config\n ) as unknown as SlatePlugin<PluginConfig<K, O, A, T, S>>;\n\n plugin.configure = (config) => {\n const newPlugin = { ...plugin };\n newPlugin.__configuration = (ctx) =>\n isFunction(config) ? config(ctx as any) : config;\n\n return createSlatePlugin(newPlugin) as any;\n };\n\n plugin.configurePlugin = (p, config) => {\n const newPlugin = { ...plugin };\n\n const configureNestedPlugin = (\n plugins: SlatePlugins\n ): { found: boolean; plugins: SlatePlugins } => {\n let found = false;\n\n const updatedPlugins = plugins.map((nestedPlugin) => {\n if (nestedPlugin.key === p.key) {\n found = true;\n\n return createSlatePlugin({\n ...nestedPlugin,\n __configuration: (ctx: any) =>\n isFunction(config) ? config(ctx) : config,\n } as any);\n }\n if (nestedPlugin.plugins && nestedPlugin.plugins.length > 0) {\n const result = configureNestedPlugin(nestedPlugin.plugins);\n\n if (result.found) {\n found = true;\n\n return {\n ...nestedPlugin,\n plugins: result.plugins,\n };\n }\n }\n\n return nestedPlugin;\n });\n\n return { found, plugins: updatedPlugins };\n };\n\n const result = configureNestedPlugin(newPlugin.plugins as any);\n newPlugin.plugins = result.plugins as any;\n\n // We're not adding a new plugin if not found\n\n return createSlatePlugin(newPlugin);\n };\n\n plugin.extendEditorApi = (extension) => {\n const newPlugin = { ...plugin };\n newPlugin.__apiExtensions = [\n ...(newPlugin.__apiExtensions as any),\n { extension, isPluginSpecific: false },\n ];\n\n return createSlatePlugin(newPlugin) as any;\n };\n\n plugin.extendSelectors = (extension) => {\n const newPlugin = { ...plugin };\n newPlugin.__selectorExtensions = [\n ...(newPlugin.__selectorExtensions as any),\n extension,\n ];\n\n return createSlatePlugin(newPlugin) as any;\n };\n\n plugin.extendApi = (extension) => {\n const newPlugin = { ...plugin };\n newPlugin.__apiExtensions = [\n ...(newPlugin.__apiExtensions as any),\n { extension, isPluginSpecific: true },\n ];\n\n return createSlatePlugin(newPlugin) as any;\n };\n\n plugin.extendEditorTransforms = (extension) => {\n const newPlugin = { ...plugin };\n newPlugin.__apiExtensions = [\n ...(newPlugin.__apiExtensions as any),\n { extension, isPluginSpecific: false, isTransform: true },\n ];\n\n return createSlatePlugin(newPlugin) as any;\n };\n\n plugin.extendTransforms = (extension) => {\n const newPlugin = { ...plugin };\n newPlugin.__apiExtensions = [\n ...(newPlugin.__apiExtensions as any),\n { extension, isPluginSpecific: true, isTransform: true },\n ];\n\n return createSlatePlugin(newPlugin) as any;\n };\n\n plugin.overrideEditor = (extension) => {\n const newPlugin = { ...plugin };\n newPlugin.__apiExtensions = [\n ...(newPlugin.__apiExtensions as any),\n {\n extension,\n isOverride: true,\n isPluginSpecific: false,\n isTransform: true,\n },\n ];\n\n return createSlatePlugin(newPlugin) as any;\n };\n\n plugin.extend = (extendConfig) => {\n let newPlugin = { ...plugin };\n\n if (isFunction(extendConfig)) {\n newPlugin.__extensions = [\n ...(newPlugin.__extensions as any),\n extendConfig,\n ];\n } else {\n newPlugin = mergePlugins(newPlugin, extendConfig as any);\n }\n\n return createSlatePlugin(newPlugin) as any;\n };\n\n plugin.clone = () => mergePlugins(plugin);\n\n plugin.extendPlugin = (p, extendConfig) => {\n const newPlugin = { ...plugin };\n\n const extendNestedPlugin = (\n plugins: SlatePlugins\n ): { found: boolean; plugins: SlatePlugins } => {\n let found = false;\n const updatedPlugins = plugins.map((nestedPlugin) => {\n if (nestedPlugin.key === p.key) {\n found = true;\n\n return createSlatePlugin({\n ...nestedPlugin,\n __extensions: [\n ...(nestedPlugin.__extensions as any),\n (ctx: any) =>\n isFunction(extendConfig) ? extendConfig(ctx) : extendConfig,\n ],\n } as any);\n }\n if (nestedPlugin.plugins && nestedPlugin.plugins.length > 0) {\n const result = extendNestedPlugin(nestedPlugin.plugins);\n\n if (result.found) {\n found = true;\n\n return {\n ...nestedPlugin,\n plugins: result.plugins,\n };\n }\n }\n\n return nestedPlugin;\n });\n\n return { found, plugins: updatedPlugins };\n };\n\n const result = extendNestedPlugin(newPlugin.plugins as any);\n newPlugin.plugins = result.plugins as any;\n\n // If the plugin wasn't found at any level, add it at the top level\n if (!result.found) {\n newPlugin.plugins.push(\n createSlatePlugin({\n key: p.key,\n __extensions: [\n (ctx: any) =>\n isFunction(extendConfig)\n ? extendConfig(ctx as any)\n : (extendConfig as any),\n ],\n } as any)\n );\n }\n\n return createSlatePlugin(newPlugin);\n };\n\n return plugin;\n}\n\n/**\n * Explicitly typed version of `createSlatePlugin`.\n *\n * @remarks\n * While `createSlatePlugin` uses type inference, this function requires an\n * explicit type parameter. Use this when you need precise control over the\n * plugin's type structure or when type inference doesn't provide the desired\n * result.\n */\nexport function createTSlatePlugin<C extends AnyPluginConfig = PluginConfig>(\n config:\n | ((editor: SlateEditor) => TSlatePluginConfig<C>)\n | TSlatePluginConfig<C> = {}\n): SlatePlugin<C> {\n return createSlatePlugin(config as any) as any;\n}\n","import type { SlateEditor } from '../editor';\nimport type { AnyPluginConfig, WithRequiredKey } from './BasePlugin';\nimport type {\n InferConfig,\n SlatePlugin,\n SlatePluginContext,\n} from './SlatePlugin';\n\nexport function getEditorPlugin<\n P extends AnyPluginConfig | SlatePlugin<AnyPluginConfig>,\n>(\n editor: SlateEditor,\n p: WithRequiredKey<P>\n): SlatePluginContext<InferConfig<P> extends never ? P : InferConfig<P>> {\n const plugin = editor.getPlugin(p) as any;\n\n return {\n api: editor.api,\n editor,\n plugin: plugin as any,\n setOption: ((keyOrOptions: any, value: any) =>\n editor.setOption(plugin, keyOrOptions, value)) as any,\n setOptions: ((options: any) => editor.setOptions(plugin, options)) as any,\n tf: editor.transforms,\n type: plugin.node.type,\n getOption: (key: any, ...args: any) =>\n (editor.getOption as any)(plugin, key, ...args),\n getOptions: () => editor.getOptions(plugin),\n };\n}\n","import merge from 'lodash/merge.js';\n\nimport type { SlateEditor } from '../../lib/editor';\nimport type { PluginConfig } from '../../lib/plugin/BasePlugin';\nimport type { AnySlatePlugin, SlatePlugin } from '../../lib/plugin/SlatePlugin';\n\nimport { getEditorPlugin } from '../../lib/plugin/getEditorPlugin';\nimport { mergePlugins } from '../utils/mergePlugins';\n\n/**\n * Resolves and finalizes a plugin configuration for use in a Plate editor.\n *\n * This function processes a given plugin configuration, applying any extensions\n * and resolving nested plugins. It prepares the plugin for integration into the\n * Plate editor system by:\n *\n * 1. Cloning the plugin to avoid mutating the original\n * 2. Applying all stored extensions to the plugin\n * 3. Clearing the extensions array after application\n *\n * @example\n * const plugin = createSlatePlugin({ key: 'myPlugin', ...otherOptions }).extend(...);\n * const resolvedPlugin = resolvePlugin(editor, plugin);\n */\nexport const resolvePlugin = <P extends AnySlatePlugin>(\n editor: SlateEditor,\n _plugin: P\n): P => {\n // Create a deep clone of the plugin\n let plugin = mergePlugins({}, _plugin) as P;\n\n plugin.__resolved = true;\n\n // Apply the stored configuration first\n if (plugin.__configuration) {\n const configResult = plugin.__configuration(\n getEditorPlugin(editor, plugin as any)\n );\n\n plugin = mergePlugins(plugin, configResult);\n\n delete (plugin as any).__configuration;\n }\n // Apply all stored extensions\n if (plugin.__extensions && plugin.__extensions.length > 0) {\n plugin.__extensions.forEach((extension) => {\n plugin = mergePlugins(\n plugin,\n extension(getEditorPlugin(editor, plugin as any))\n );\n });\n plugin.__extensions = [];\n }\n\n const targetPluginToInject = plugin.inject?.targetPluginToInject;\n const targetPlugins = plugin.inject?.targetPlugins;\n\n if (targetPluginToInject && targetPlugins && targetPlugins.length > 0) {\n plugin.inject = plugin.inject || {};\n plugin.inject.plugins = merge(\n {},\n plugin.inject.plugins,\n Object.fromEntries(\n targetPlugins.map((targetPlugin) => {\n const injectedPlugin = targetPluginToInject({\n ...getEditorPlugin(editor, plugin as any),\n targetPlugin,\n });\n\n return [targetPlugin, injectedPlugin];\n })\n )\n );\n }\n // TODO React\n if ((plugin as any).node?.component) {\n (plugin as any).render.node = (plugin as any).node.component;\n }\n if ((plugin as any).render?.node) {\n (plugin as any).node.component = (plugin as any).render.node;\n }\n\n validatePlugin(editor, plugin);\n\n return plugin;\n};\n\nexport const validatePlugin = <\n K extends string = any,\n O = {},\n A = {},\n T = {},\n S = {},\n>(\n editor: SlateEditor,\n plugin: SlatePlugin<PluginConfig<K, O, A, T, S>>\n) => {\n if (!plugin.__extensions) {\n editor.api.debug.error(\n `Invalid plugin '${plugin.key}', you should use createSlatePlugin.`,\n 'USE_CREATE_PLUGIN'\n );\n }\n if (plugin.node.isElement && plugin.node.isLeaf) {\n editor.api.debug.error(\n `Plugin ${plugin.key} cannot be both an element and a leaf.`,\n 'PLUGIN_NODE_TYPE'\n );\n }\n};\n","import type { SlateEditor } from '../editor';\nimport type {\n AnyPluginConfig,\n PluginConfig,\n WithRequiredKey,\n} from './BasePlugin';\nimport type { AnySlatePlugin, SlatePlugin } from './SlatePlugin';\n\nimport { resolvePlugin } from '../../internal/plugin/resolvePlugin';\nimport { createSlatePlugin } from './createSlatePlugin';\n\n/** Get editor plugin by key or plugin object. */\nexport function getSlatePlugin<C extends AnyPluginConfig = PluginConfig>(\n editor: SlateEditor,\n p: WithRequiredKey<C>\n): C extends { node: any } ? C : SlatePlugin<C> {\n let plugin = p as any;\n\n const editorPlugin = editor.plugins[p.key] as any;\n\n if (!editorPlugin) {\n // When passing only { key }\n if (!plugin.node) {\n plugin = createSlatePlugin(plugin);\n }\n\n // Resolve is need when passing an external plugin with extensions (e.g. in withLink)\n return plugin.__resolved ? plugin : resolvePlugin(editor, plugin);\n }\n\n return editorPlugin;\n}\n\n/** Get editor plugin type by key or plugin object. */\nexport function getPluginType(\n editor: SlateEditor,\n plugin: WithRequiredKey\n): string {\n const p = editor.getPlugin<AnySlatePlugin>(plugin);\n\n return p.node.type ?? p.key ?? '';\n}\n\n/** Get editor plugin types by key. */\nexport const getPluginTypes = (\n editor: SlateEditor,\n plugins: WithRequiredKey[]\n) => plugins.map((plugin) => editor.getType(plugin));\n","import type { SlateEditor } from '../../lib/editor';\n\nimport { getEditorPlugin } from '../../lib/plugin';\n\n/** Normalize initial value from editor plugins. Set into plate store if diff. */\nexport const pipeNormalizeInitialValue = (editor: SlateEditor) => {\n editor.pluginList.forEach((p) => {\n p.normalizeInitialValue?.({\n ...getEditorPlugin(editor, p),\n value: editor.children,\n } as any);\n });\n};\n","import {\n assignLegacyApi,\n assignLegacyTransforms,\n syncLegacyMethods,\n} from '@udecode/slate';\nimport { isDefined } from '@udecode/utils';\nimport merge from 'lodash/merge.js';\nimport { createZustandStore } from 'zustand-x';\n\nimport type { SlateEditor } from '../../lib/editor';\n\nimport {\n type SlatePlugin,\n type SlatePlugins,\n getEditorPlugin,\n} from '../../lib/plugin';\nimport { mergePlugins } from '../utils/mergePlugins';\nimport { resolvePlugin } from './resolvePlugin';\n\n/**\n * Initialize and configure the editor's plugin system. This function sets up\n * the editor's plugins, resolving core and custom plugins, and applying any\n * overrides specified in the plugins.\n */\nexport const resolvePlugins = (\n editor: SlateEditor,\n plugins: SlatePlugins = []\n) => {\n editor.pluginList = [];\n editor.plugins = {};\n editor.shortcuts = {} as any;\n\n const resolvedPlugins = resolveAndSortPlugins(editor, plugins);\n\n applyPluginsToEditor(editor, resolvedPlugins);\n\n resolvePluginOverrides(editor);\n\n resolvePluginStores(editor);\n\n // extendEditor\n editor.pluginList.forEach((plugin) => {\n if (plugin.extendEditor) {\n editor = plugin.extendEditor(getEditorPlugin(editor, plugin) as any);\n\n // Sync any editor methods that were modified by extendEditor\n syncLegacyMethods(editor);\n }\n\n // Sync overridden plugin methods to legacy editor methods\n resolvePluginMethods(editor, plugin);\n });\n\n resolvePluginShortcuts(editor);\n\n return editor;\n};\n\nconst resolvePluginStores = (editor: SlateEditor) => {\n // Create zustand stores for each plugin\n editor.pluginList.forEach((plugin) => {\n let store = createZustandStore(plugin.options, {\n mutative: true,\n name: plugin.key,\n });\n\n // Apply option extensions\n if (\n (plugin as any).__selectorExtensions &&\n (plugin as any).__selectorExtensions.length > 0\n ) {\n (plugin as any).__selectorExtensions.forEach((extension: any) => {\n const extendedOptions = extension(getEditorPlugin(editor, plugin));\n\n store = store.extendSelectors(() => extendedOptions);\n });\n }\n\n plugin.optionsStore = store;\n });\n};\n\nconst resolvePluginMethods = (editor: SlateEditor, plugin: any) => {\n // Merge APIs\n Object.entries(plugin.api).forEach(([apiKey, apiFunction]) => {\n (editor.api as any)[apiKey] = apiFunction;\n });\n\n // Apply API and transform extensions\n if (plugin.__apiExtensions && plugin.__apiExtensions.length > 0) {\n plugin.__apiExtensions.forEach(\n ({ extension, isOverride, isPluginSpecific, isTransform }: any) => {\n const newExtensions = extension(getEditorPlugin(editor, plugin) as any);\n\n if (isOverride) {\n // Handle combined API and transforms override\n if (newExtensions.api) {\n merge(editor.api, newExtensions.api);\n merge(plugin.api, newExtensions.api);\n assignLegacyApi(editor, editor.api);\n }\n if (newExtensions.transforms) {\n merge(editor.transforms, newExtensions.transforms);\n merge(plugin.transforms, newExtensions.transforms);\n assignLegacyTransforms(editor, newExtensions.transforms);\n }\n } else if (isTransform) {\n // Handle transforms\n if (isPluginSpecific) {\n // Plugin-specific transform\n if (!(editor.transforms as any)[plugin.key]) {\n (editor.transforms as any)[plugin.key] = {};\n }\n if (!(plugin.transforms as any)[plugin.key]) {\n (plugin.transforms as any)[plugin.key] = {};\n }\n\n merge((editor.transforms as any)[plugin.key], newExtensions);\n merge((plugin.transforms as any)[plugin.key], newExtensions);\n } else {\n // Editor-wide transform\n merge(editor.transforms, newExtensions);\n merge(plugin.transforms, newExtensions);\n assignLegacyTransforms(editor, newExtensions);\n }\n } else {\n // Handle APIs\n if (isPluginSpecific) {\n // Plugin-specific API\n if (!(editor.api as any)[plugin.key]) {\n (editor.api as any)[plugin.key] = {};\n }\n if (!(plugin.api as any)[plugin.key]) {\n (plugin.api as any)[plugin.key] = {};\n }\n\n merge((editor.api as any)[plugin.key], newExtensions);\n merge((plugin.api as any)[plugin.key], newExtensions);\n } else {\n // Editor-wide API\n merge(editor.api, newExtensions);\n merge(plugin.api, newExtensions);\n assignLegacyApi(editor, editor.api);\n }\n }\n }\n );\n delete plugin.__apiExtensions;\n }\n};\n\nconst resolvePluginShortcuts = (editor: SlateEditor) => {\n const shortcutsByPriority: any[] = [];\n\n editor.pluginList.forEach((plugin) => {\n // Merge shortcuts\n Object.entries(plugin.shortcuts).forEach(([key, hotkey]) => {\n if (hotkey === null) {\n // Remove any existing hotkey with this key\n const index = shortcutsByPriority.findIndex((item) => item.key === key);\n\n if (index !== -1) {\n shortcutsByPriority.splice(index, 1);\n }\n } else {\n const priority = (hotkey as any).priority ?? plugin.priority;\n const existingIndex = shortcutsByPriority.findIndex(\n (item) => item.key === key\n );\n\n if (\n existingIndex === -1 ||\n priority >= shortcutsByPriority[existingIndex].priority\n ) {\n if (existingIndex !== -1) {\n shortcutsByPriority.splice(existingIndex, 1);\n }\n\n shortcutsByPriority.push({ key, hotkey, priority });\n }\n }\n });\n });\n\n // Sort shortcuts by priority (descending)\n shortcutsByPriority.sort((a, b) => b.hotkey.priority - a.hotkey.priority);\n\n // After processing all plugins, set the final shortcuts on the editor\n editor.shortcuts = Object.fromEntries(\n shortcutsByPriority.map(({ key, hotkey }) => {\n const { priority, ...hotkeyWithoutPriority } = hotkey;\n\n return [key, hotkeyWithoutPriority];\n })\n );\n};\n\nconst flattenAndResolvePlugins = (\n editor: SlateEditor,\n plugins: SlatePlugins\n): Map<string, SlatePlugin> => {\n const pluginMap = new Map<string, SlatePlugin>();\n\n const processPlugin = (plugin: SlatePlugin) => {\n const resolvedPlugin = resolvePlugin(editor, plugin);\n const existingPlugin = pluginMap.get(resolvedPlugin.key);\n\n if (existingPlugin) {\n pluginMap.set(\n resolvedPlugin.key,\n mergePlugins(existingPlugin, resolvedPlugin)\n );\n } else {\n pluginMap.set(resolvedPlugin.key, resolvedPlugin);\n }\n if (resolvedPlugin.plugins && resolvedPlugin.plugins.length > 0) {\n resolvedPlugin.plugins.forEach(processPlugin);\n }\n };\n\n plugins.forEach(processPlugin);\n\n return pluginMap;\n};\n\nexport const resolveAndSortPlugins = (\n editor: SlateEditor,\n plugins: SlatePlugins\n): SlatePlugins => {\n // Step 1: Resolve, flatten, and merge all plugins\n const pluginMap = flattenAndResolvePlugins(editor, plugins);\n\n // Step 2: Filter out disabled plugins\n const enabledPlugins = Array.from(pluginMap.values()).filter(\n (plugin) => plugin.enabled !== false\n );\n\n // Step 3: Sort plugins by priority\n enabledPlugins.sort((a, b) => b.priority - a.priority);\n\n // Step 4: Reorder based on dependencies\n const orderedPlugins: SlatePlugins = [];\n const visited = new Set<string>();\n\n const visit = (plugin: SlatePlugin) => {\n if (visited.has(plugin.key)) return;\n\n visited.add(plugin.key);\n\n plugin.dependencies?.forEach((depKey) => {\n const depPlugin = pluginMap.get(depKey);\n\n if (depPlugin) {\n visit(depPlugin);\n } else {\n editor.api.debug.warn(\n `Plugin \"${plugin.key}\" depends on missing plugin \"${depKey}\"`,\n 'PLUGIN_DEPENDENCY_MISSING'\n );\n }\n });\n\n orderedPlugins.push(plugin);\n };\n\n enabledPlugins.forEach(visit);\n\n return orderedPlugins;\n};\n\nexport const applyPluginsToEditor = (\n editor: SlateEditor,\n plugins: SlatePlugins\n) => {\n editor.pluginList = plugins;\n editor.plugins = Object.fromEntries(\n plugins.map((plugin) => [plugin.key, plugin])\n );\n};\n\nexport const resolvePluginOverrides = (editor: SlateEditor) => {\n const applyOverrides = (plugins: SlatePlugin[]): SlatePlugin[] => {\n let overriddenPlugins = [...plugins];\n\n const enabledOverrides: Record<string, boolean> = {};\n const componentOverrides: Record<\n string,\n { component: any; priority: number }\n > = {};\n const pluginOverrides: Record<string, Partial<SlatePlugin>> = {};\n\n // Collect all overrides\n for (const plugin of plugins) {\n if (plugin.override.enabled) {\n Object.assign(enabledOverrides, plugin.override.enabled);\n }\n // TODO react\n if ((plugin.override as any).components) {\n Object.entries((plugin.override as any).components).forEach(\n ([key, component]) => {\n if (\n !componentOverrides[key] ||\n plugin.priority > componentOverrides[key].priority\n ) {\n componentOverrides[key] = {\n component,\n priority: plugin.priority,\n };\n }\n }\n );\n }\n if (plugin.override.plugins) {\n Object.entries(plugin.override.plugins).forEach(([key, value]) => {\n pluginOverrides[key] = mergePlugins(pluginOverrides[key], value);\n\n if (value.enabled !== undefined) {\n enabledOverrides[key] = value.enabled;\n }\n });\n }\n }\n\n // Apply overrides\n overriddenPlugins = overriddenPlugins.map((p) => {\n let updatedPlugin = { ...p };\n\n // Apply plugin overrides\n if (pluginOverrides[p.key]) {\n updatedPlugin = mergePlugins(updatedPlugin, pluginOverrides[p.key]);\n }\n // Apply component overrides\n // TODO react\n if (\n componentOverrides[p.key] &&\n ((!(p as any).render.node && !(p as any).node.component) ||\n componentOverrides[p.key].priority > p.priority)\n ) {\n (updatedPlugin as any).render.node =\n componentOverrides[p.key].component;\n (updatedPlugin as any).node.component =\n componentOverrides[p.key].component;\n }\n\n // Apply enabled overrides\n const enabled = enabledOverrides[p.key] ?? updatedPlugin.enabled;\n\n if (isDefined(enabled)) {\n updatedPlugin.enabled = enabled;\n }\n\n return updatedPlugin;\n });\n\n return overriddenPlugins\n .filter((p) => p.enabled !== false)\n .map((plugin) => ({\n ...plugin,\n plugins: applyOverrides(plugin.plugins || []),\n }));\n };\n\n editor.pluginList = applyOverrides(editor.pluginList as any);\n editor.plugins = Object.fromEntries(\n editor.pluginList.map((plugin) => [plugin.key, plugin])\n );\n};\n","import { createSlatePlugin } from '../plugin';\n\n/**\n * Enables support for deserializing inserted content from Slate Ast format to\n * Slate format while apply a small bug fix.\n */\nexport const AstPlugin = createSlatePlugin({\n key: 'ast',\n parser: {\n format: 'application/x-slate-fragment',\n deserialize: ({ data }) => {\n const decoded = decodeURIComponent(window.atob(data));\n let parsed;\n\n try {\n parsed = JSON.parse(decoded);\n } catch {\n /* empty */\n }\n\n return parsed;\n },\n },\n});\n","import { createSlatePlugin } from '../plugin';\n\n/**\n * Placeholder plugin for DOM interaction, that could be replaced with\n * ReactPlugin.\n */\nexport const DOMPlugin = createSlatePlugin({\n key: 'dom',\n});\n","import { withHistory } from '@udecode/slate';\n\nimport type { SlateEditor } from '../editor';\n\nimport { type ExtendEditor, createSlatePlugin } from '../plugin';\n\nexport const withPlateHistory: ExtendEditor = ({ editor }) =>\n withHistory(editor as any) as any as SlateEditor;\n\n/** @see {@link withHistory} */\nexport const HistoryPlugin = createSlatePlugin({\n key: 'history',\n extendEditor: withPlateHistory,\n});\n","import { type OverrideEditor, createSlatePlugin } from '../plugin';\n\n/**\n * Merge and register all the inline types and void types from the plugins and\n * options, using `editor.api.isInline`, `editor.api.markableVoid` and\n * `editor.api.isVoid`\n */\nexport const withInlineVoid: OverrideEditor = ({\n api: { isInline, isSelectable, isVoid, markableVoid },\n editor,\n}) => {\n const voidTypes: string[] = [];\n const inlineTypes: string[] = [];\n const markableVoidTypes: string[] = [];\n const nonSelectableTypes: string[] = [];\n\n editor.pluginList.forEach((plugin) => {\n if (plugin.node.isInline) {\n inlineTypes.push(plugin.node.type);\n }\n if (plugin.node.isVoid) {\n voidTypes.push(plugin.node.type);\n }\n if (plugin.node.isMarkableVoid) {\n markableVoidTypes.push(plugin.node.type);\n }\n if (plugin.node.isSelectable === false) {\n nonSelectableTypes.push(plugin.node.type);\n }\n });\n\n return {\n api: {\n isInline(element) {\n return inlineTypes.includes(element.type as any)\n ? true\n : isInline(element);\n },\n isSelectable(element) {\n return nonSelectableTypes.includes(element.type)\n ? false\n : isSelectable(element);\n },\n isVoid(element) {\n return voidTypes.includes(element.type as any) ? true : isVoid(element);\n },\n markableVoid(element) {\n return markableVoidTypes.includes(element.type)\n ? true\n : markableVoid(element);\n },\n },\n };\n};\n\n/** @see {@link withInlineVoid} */\nexport const InlineVoidPlugin = createSlatePlugin({\n key: 'inlineVoid',\n}).overrideEditor(withInlineVoid);\n","import type { Descendant } from '@udecode/slate';\n\nimport type { SlateEditor } from '../../lib/editor';\nimport type { ParserOptions } from '../../lib/plugin/BasePlugin';\nimport type { AnyEditorPlugin } from '../../lib/plugin/SlatePlugin';\n\nimport { getEditorPlugin } from '../../lib/plugin';\n\n/** Pipe preInsert then insertFragment. */\nexport const pipeInsertFragment = (\n editor: SlateEditor,\n injectedPlugins: Partial<AnyEditorPlugin>[],\n { fragment, ...options }: ParserOptions & { fragment: Descendant[] }\n) => {\n editor.tf.withoutNormalizing(() => {\n injectedPlugins.some((p) => {\n return (\n p.parser?.preInsert?.({\n ...getEditorPlugin(editor, p as any),\n fragment,\n ...options,\n }) === true\n );\n });\n\n editor.tf.insertFragment(fragment);\n });\n};\n","import type { SlateEditor } from '../../lib/editor';\nimport type { ParserOptions } from '../../lib/plugin/BasePlugin';\nimport type { AnyEditorPlugin } from '../../lib/plugin/SlatePlugin';\n\nimport { getEditorPlugin } from '../../lib/plugin';\n\n/** Pipe editor.tf.insertData.transformData */\nexport const pipeTransformData = (\n editor: SlateEditor,\n plugins: Partial<AnyEditorPlugin>[],\n { data, dataTransfer }: ParserOptions\n) => {\n plugins.forEach((p) => {\n const transformData = p.parser?.transformData;\n\n if (!transformData) return;\n\n data = transformData({\n ...getEditorPlugin(editor, p as any),\n data,\n dataTransfer,\n });\n });\n\n return data;\n};\n","import type { Descendant } from '@udecode/slate';\n\nimport type { SlateEditor } from '../../lib/editor';\nimport type { ParserOptions } from '../../lib/plugin/BasePlugin';\nimport type { AnyEditorPlugin } from '../../lib/plugin/SlatePlugin';\n\nimport { getEditorPlugin } from '../../lib/plugin';\n\n/** Pipe editor.tf.insertData.transformFragment */\nexport const pipeTransformFragment = (\n editor: SlateEditor,\n plugins: Partial<AnyEditorPlugin>[],\n { fragment, ...options }: ParserOptions & { fragment: Descendant[] }\n) => {\n plugins.forEach((p) => {\n const transformFragment = p.parser?.transformFragment;\n\n if (!transformFragment) return;\n\n fragment = transformFragment({\n fragment,\n ...options,\n ...getEditorPlugin(editor, p as any),\n });\n });\n\n return fragment;\n};\n","import {\n type NodeEntry,\n type NodeOf,\n type Path,\n type QueryNodeOptions,\n type TNode,\n NodeApi,\n queryNode,\n} from '@udecode/slate';\n\nexport interface ApplyDeepToNodesOptions<N extends TNode> {\n // Function to call on each node following the query.\n apply: (\n node: NodeOf<N>,\n source: (() => Record<string, any>) | Record<string, any>\n ) => void;\n // The destination node object.\n node: N;\n // The source object. Can be a factory.\n source: (() => Record<string, any>) | Record<string, any>;\n path?: Path;\n // Query to filter the nodes.\n query?: QueryNodeOptions;\n}\n\n/** Recursively apply an operation to children nodes with a query. */\nexport const applyDeepToNodes = <N extends TNode>({\n apply,\n node,\n path = [],\n query,\n source,\n}: ApplyDeepToNodesOptions<N>) => {\n const entry: NodeEntry<N> = [node, path];\n\n if (queryNode<N>(entry, query)) {\n if (source instanceof Function) {\n apply(node, source());\n } else {\n apply(node, source);\n }\n }\n if (!NodeApi.isAncestor(node)) return;\n\n node.children.forEach((child, index) => {\n applyDeepToNodes({\n apply,\n node: child as any,\n path: path.concat([index]),\n query,\n source,\n });\n });\n};\n","import { type Path, type TNode, ElementApi } from '@udecode/slate';\n\nimport type { SlateEditor } from '../editor';\nimport type { EditorPlugin } from '../plugin';\n\nimport { getKeyByType, getKeysByTypes } from './getKeysByTypes';\n\nexport const getInjectMatch = <E extends SlateEditor>(\n editor: E,\n plugin: EditorPlugin\n) => {\n return (node: TNode, path: Path) => {\n const {\n inject: {\n excludeBelowPlugins,\n excludePlugins,\n isBlock: _isBlock,\n isElement: _isElement,\n isLeaf,\n maxLevel,\n targetPlugins,\n },\n } = plugin;\n\n const element = Elemen