@tiptap/vue-3 3.22.4 → 3.23.1
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/dist/index.cjs +7 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/menus/index.cjs +6 -2
- package/dist/menus/index.cjs.map +1 -1
- package/dist/menus/index.js +6 -2
- package/dist/menus/index.js.map +1 -1
- package/package.json +7 -7
- package/src/VueNodeViewRenderer.ts +9 -3
package/dist/index.cjs
CHANGED
|
@@ -555,12 +555,17 @@ var VueNodeView = class extends import_core3.NodeView {
|
|
|
555
555
|
* If it is, call `selectNode`, otherwise call `deselectNode`.
|
|
556
556
|
*/
|
|
557
557
|
handleSelectionUpdate() {
|
|
558
|
-
const { from, to } = this.editor.state.selection;
|
|
559
558
|
const pos = this.getPos();
|
|
560
559
|
if (typeof pos !== "number") {
|
|
561
560
|
return;
|
|
562
561
|
}
|
|
563
|
-
|
|
562
|
+
const isSelected = (0, import_core3.isNodeViewSelected)({
|
|
563
|
+
selection: this.editor.state.selection,
|
|
564
|
+
pos,
|
|
565
|
+
nodeSize: this.node.nodeSize,
|
|
566
|
+
selectedOnTextSelection: this.options.selectedOnTextSelection
|
|
567
|
+
});
|
|
568
|
+
if (isSelected) {
|
|
564
569
|
if (this.renderer.props.selected) {
|
|
565
570
|
return;
|
|
566
571
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/Editor.ts","../src/EditorContent.ts","../src/NodeViewContent.ts","../src/NodeViewWrapper.ts","../src/useEditor.ts","../src/VueMarkViewRenderer.ts","../src/VueRenderer.ts","../src/VueNodeViewRenderer.ts"],"sourcesContent":["export { Editor } from './Editor.js'\nexport * from './EditorContent.js'\nexport * from './NodeViewContent.js'\nexport * from './NodeViewWrapper.js'\nexport * from './useEditor.js'\nexport * from './VueMarkViewRenderer.js'\nexport * from './VueNodeViewRenderer.js'\nexport * from './VueRenderer.js'\nexport * from '@tiptap/core'\n","/* eslint-disable react-hooks/rules-of-hooks */\nimport type { EditorOptions, Storage } from '@tiptap/core'\nimport { Editor as CoreEditor } from '@tiptap/core'\nimport type { EditorState, Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { AppContext, ComponentInternalInstance, ComponentPublicInstance, Ref } from 'vue'\nimport { customRef, markRaw } from 'vue'\n\nfunction useDebouncedRef<T>(value: T) {\n return customRef<T>((track, trigger) => {\n return {\n get() {\n track()\n return value\n },\n set(newValue) {\n // update state\n value = newValue\n\n // update view as soon as possible\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n trigger()\n })\n })\n },\n }\n })\n}\n\nexport type ContentComponent = ComponentInternalInstance & {\n ctx: ComponentPublicInstance\n}\n\nexport class Editor extends CoreEditor {\n private reactiveState: Ref<EditorState>\n\n private reactiveExtensionStorage: Ref<Storage>\n\n public contentComponent: ContentComponent | null = null\n\n public appContext: AppContext | null = null\n\n constructor(options: Partial<EditorOptions> = {}) {\n super(options)\n\n this.reactiveState = useDebouncedRef(this.view.state)\n this.reactiveExtensionStorage = useDebouncedRef(this.extensionStorage)\n\n this.on('beforeTransaction', ({ nextState }) => {\n this.reactiveState.value = nextState\n this.reactiveExtensionStorage.value = this.extensionStorage\n })\n\n return markRaw(this) // eslint-disable-line\n }\n\n get state() {\n return this.reactiveState ? this.reactiveState.value : this.view.state\n }\n\n get storage() {\n return this.reactiveExtensionStorage ? this.reactiveExtensionStorage.value : super.storage\n }\n\n /**\n * Register a ProseMirror plugin.\n */\n public registerPlugin(\n plugin: Plugin,\n handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[],\n ): EditorState {\n const nextState = super.registerPlugin(plugin, handlePlugins)\n\n if (this.reactiveState) {\n this.reactiveState.value = nextState\n }\n\n return nextState\n }\n\n /**\n * Unregister a ProseMirror plugin.\n */\n public unregisterPlugin(nameOrPluginKey: string | PluginKey): EditorState | undefined {\n const nextState = super.unregisterPlugin(nameOrPluginKey)\n\n if (this.reactiveState && nextState) {\n this.reactiveState.value = nextState\n }\n\n return nextState\n }\n}\n","import type { PropType, Ref } from 'vue'\nimport { defineComponent, getCurrentInstance, h, nextTick, onBeforeUnmount, ref, unref, watchEffect } from 'vue'\n\nimport type { Editor } from './Editor.js'\n\nexport const EditorContent = defineComponent({\n name: 'EditorContent',\n\n props: {\n editor: {\n default: null,\n type: Object as PropType<Editor>,\n },\n },\n\n setup(props) {\n const rootEl: Ref<Element | undefined> = ref()\n const instance = getCurrentInstance()\n\n watchEffect(() => {\n const editor = props.editor\n\n if (editor && editor.options.element && rootEl.value) {\n nextTick(() => {\n if (!rootEl.value || !editor.view.dom?.parentNode) {\n return\n }\n\n // TODO using the new editor.mount method might allow us to remove this\n const element = unref(rootEl.value)\n\n rootEl.value.append(...editor.view.dom.parentNode.childNodes)\n\n // @ts-ignore\n editor.contentComponent = instance.ctx._\n\n if (instance) {\n editor.appContext = {\n ...instance.appContext,\n // Vue internally uses prototype chain to forward/shadow injects across the entire component chain\n // so don't use object spread operator or 'Object.assign' and just set `provides` as is on editor's appContext\n // @ts-expect-error forward instance's 'provides' into appContext\n provides: instance.provides,\n }\n }\n\n editor.setOptions({\n element,\n })\n\n editor.createNodeViews()\n })\n }\n })\n\n onBeforeUnmount(() => {\n const editor = props.editor\n\n if (!editor) {\n return\n }\n\n editor.contentComponent = null\n editor.appContext = null\n })\n\n return { rootEl }\n },\n\n render() {\n return h('div', {\n ref: (el: any) => {\n this.rootEl = el\n },\n })\n },\n})\n","import { defineComponent, h } from 'vue'\n\nexport const NodeViewContent = defineComponent({\n name: 'NodeViewContent',\n\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n render() {\n return h(this.as, {\n style: {\n whiteSpace: 'pre-wrap',\n },\n 'data-node-view-content': '',\n })\n },\n})\n","import { defineComponent, h } from 'vue'\n\nexport const NodeViewWrapper = defineComponent({\n name: 'NodeViewWrapper',\n\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n inject: ['onDragStart', 'decorationClasses'],\n\n render() {\n return h(\n this.as,\n {\n // @ts-ignore\n class: this.decorationClasses,\n style: {\n whiteSpace: 'normal',\n },\n 'data-node-view-wrapper': '',\n // @ts-ignore (https://github.com/vuejs/vue-next/issues/3031)\n onDragstart: this.onDragStart,\n },\n this.$slots.default?.(),\n )\n },\n})\n","import type { EditorOptions } from '@tiptap/core'\nimport { onBeforeUnmount, onMounted, shallowRef } from 'vue'\n\nimport { Editor } from './Editor.js'\n\nexport const useEditor = (options: Partial<EditorOptions> = {}) => {\n const editor = shallowRef<Editor>()\n\n onMounted(() => {\n editor.value = new Editor(options)\n })\n\n onBeforeUnmount(() => {\n // Cloning root node (and its children) to avoid content being lost by destroy\n const nodes = editor.value?.view.dom?.parentNode\n const newEl = nodes?.cloneNode(true) as HTMLElement\n\n nodes?.parentNode?.replaceChild(newEl, nodes)\n\n editor.value?.destroy()\n })\n\n return editor\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { MarkViewProps, MarkViewRenderer, MarkViewRendererOptions } from '@tiptap/core'\nimport { MarkView } from '@tiptap/core'\nimport type { Component, PropType } from 'vue'\nimport { defineComponent, h, toRaw } from 'vue'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport interface VueMarkViewRendererOptions extends MarkViewRendererOptions {\n as?: string\n className?: string\n attrs?: { [key: string]: string }\n}\n\nexport const markViewProps = {\n editor: {\n type: Object as PropType<MarkViewProps['editor']>,\n required: true as const,\n },\n mark: {\n type: Object as PropType<MarkViewProps['mark']>,\n required: true as const,\n },\n extension: {\n type: Object as PropType<MarkViewProps['extension']>,\n required: true as const,\n },\n inline: {\n type: Boolean as PropType<MarkViewProps['inline']>,\n required: true as const,\n },\n view: {\n type: Object as PropType<MarkViewProps['view']>,\n required: true as const,\n },\n updateAttributes: {\n type: Function as PropType<MarkViewProps['updateAttributes']>,\n required: true as const,\n },\n HTMLAttributes: {\n type: Object as PropType<MarkViewProps['HTMLAttributes']>,\n required: true as const,\n },\n}\n\nexport const MarkViewContent = defineComponent({\n name: 'MarkViewContent',\n\n props: {\n as: {\n type: String,\n default: 'span',\n },\n },\n\n render() {\n return h(this.as, {\n style: {\n whiteSpace: 'inherit',\n },\n 'data-mark-view-content': '',\n })\n },\n})\n\nexport class VueMarkView extends MarkView<Component, VueMarkViewRendererOptions> {\n renderer: VueRenderer\n\n constructor(component: Component, props: MarkViewProps, options?: Partial<VueMarkViewRendererOptions>) {\n super(component, props, options)\n\n const componentProps = { ...props, updateAttributes: this.updateAttributes.bind(this) } satisfies MarkViewProps\n\n // Create extended component with provide\n const extendedComponent = defineComponent({\n extends: { ...component },\n props: Object.keys(componentProps),\n template: (this.component as any).template,\n setup: reactiveProps => {\n return (component as any).setup?.(reactiveProps, {\n expose: () => undefined,\n })\n },\n // Add support for scoped styles\n __scopeId: (component as any).__scopeId,\n __cssModules: (component as any).__cssModules,\n __name: (component as any).__name,\n __file: (component as any).__file,\n })\n this.renderer = new VueRenderer(extendedComponent, {\n editor: this.editor,\n props: componentProps,\n })\n }\n\n get dom() {\n return this.renderer.element as HTMLElement\n }\n\n get contentDOM() {\n return this.dom.querySelector('[data-mark-view-content]') as HTMLElement | null\n }\n\n updateAttributes(attrs: Record<string, any>): void {\n // since this.mark is now an proxy, we need to get the actual mark from it\n const unproxiedMark = toRaw(this.mark)\n super.updateAttributes(attrs, unproxiedMark)\n }\n\n destroy() {\n this.renderer.destroy()\n }\n}\n\nexport function VueMarkViewRenderer(\n component: Component,\n options: Partial<VueMarkViewRendererOptions> = {},\n): MarkViewRenderer {\n return props => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {} as unknown as MarkView<any, any>\n }\n\n return new VueMarkView(component, props, options)\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport type { Component, DefineComponent } from 'vue'\nimport { h, markRaw, reactive, render } from 'vue'\n\nimport type { Editor as ExtendedEditor } from './Editor.js'\n\nexport interface VueRendererOptions {\n editor: Editor\n props?: Record<string, any>\n}\n\ntype ExtendedVNode = ReturnType<typeof h> | null\n\ninterface RenderedComponent {\n vNode: ExtendedVNode\n destroy: () => void\n el: Element | null\n}\n\n/**\n * This class is used to render Vue components inside the editor.\n */\nexport class VueRenderer {\n renderedComponent!: RenderedComponent\n\n editor: ExtendedEditor\n\n component: Component\n\n el: Element | null\n\n props: Record<string, any>\n\n /**\n * Flag to track if the renderer has been destroyed, preventing queued or asynchronous renders from executing after teardown.\n */\n destroyed = false\n\n constructor(component: Component, { props = {}, editor }: VueRendererOptions) {\n this.editor = editor as ExtendedEditor\n this.component = markRaw(component)\n this.el = document.createElement('div')\n this.props = reactive(props)\n this.renderedComponent = this.renderComponent()\n }\n\n get element(): Element | null {\n return this.renderedComponent.el\n }\n\n get ref(): any {\n // Composition API\n if (this.renderedComponent.vNode?.component?.exposed) {\n return this.renderedComponent.vNode.component.exposed\n }\n // Option API\n return this.renderedComponent.vNode?.component?.proxy\n }\n\n renderComponent() {\n if (this.destroyed) {\n return this.renderedComponent\n }\n\n let vNode: ExtendedVNode = h(this.component as DefineComponent, this.props)\n\n if (this.editor.appContext) {\n vNode.appContext = this.editor.appContext\n }\n if (typeof document !== 'undefined' && this.el) {\n render(vNode, this.el)\n }\n\n const destroy = () => {\n if (this.el) {\n render(null, this.el)\n }\n this.el = null\n vNode = null\n }\n\n return { vNode, destroy, el: this.el ? this.el.firstElementChild : null }\n }\n\n updateProps(props: Record<string, any> = {}): void {\n if (this.destroyed) {\n return\n }\n\n Object.entries(props).forEach(([key, value]) => {\n this.props[key] = value\n })\n this.renderComponent()\n }\n\n destroy(): void {\n if (this.destroyed) {\n return\n }\n\n this.destroyed = true\n this.renderedComponent.destroy()\n }\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'\nimport { cancelPositionCheck, NodeView, schedulePositionCheck } from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport type { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'\nimport type { Component, PropType, Ref } from 'vue'\nimport { defineComponent, provide, ref } from 'vue'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport const nodeViewProps = {\n editor: {\n type: Object as PropType<NodeViewProps['editor']>,\n required: true as const,\n },\n node: {\n type: Object as PropType<NodeViewProps['node']>,\n required: true as const,\n },\n decorations: {\n type: Object as PropType<NodeViewProps['decorations']>,\n required: true as const,\n },\n selected: {\n type: Boolean as PropType<NodeViewProps['selected']>,\n required: true as const,\n },\n extension: {\n type: Object as PropType<NodeViewProps['extension']>,\n required: true as const,\n },\n getPos: {\n type: Function as PropType<NodeViewProps['getPos']>,\n required: true as const,\n },\n updateAttributes: {\n type: Function as PropType<NodeViewProps['updateAttributes']>,\n required: true as const,\n },\n deleteNode: {\n type: Function as PropType<NodeViewProps['deleteNode']>,\n required: true as const,\n },\n view: {\n type: Object as PropType<NodeViewProps['view']>,\n required: true as const,\n },\n innerDecorations: {\n type: Object as PropType<NodeViewProps['innerDecorations']>,\n required: true as const,\n },\n HTMLAttributes: {\n type: Object as PropType<NodeViewProps['HTMLAttributes']>,\n required: true as const,\n },\n}\n\nexport interface VueNodeViewRendererOptions extends NodeViewRendererOptions {\n update:\n | ((props: {\n oldNode: ProseMirrorNode\n oldDecorations: readonly Decoration[]\n oldInnerDecorations: DecorationSource\n newNode: ProseMirrorNode\n newDecorations: readonly Decoration[]\n innerDecorations: DecorationSource\n updateProps: () => void\n }) => boolean)\n | null\n}\n\nclass VueNodeView extends NodeView<Component, Editor, VueNodeViewRendererOptions> {\n renderer!: VueRenderer\n\n decorationClasses!: Ref<string>\n\n /**\n * The last known position of this node view, used to detect position-only\n * changes that don't produce a new node object reference.\n */\n private currentPos: number | undefined\n\n /**\n * Callback registered with the per-editor position-update registry.\n * Stored so it can be unregistered in destroy().\n */\n private positionCheckCallback: (() => void) | null = null\n\n private cachedExtensionWithSyncedStorage: NodeViewProps['extension'] | null = null\n\n /**\n * Returns a proxy of the extension that redirects storage access to the editor's mutable storage.\n * This preserves the original prototype chain (instanceof checks, methods like configure/extend work).\n * Cached to avoid proxy creation on every update.\n */\n get extensionWithSyncedStorage(): NodeViewProps['extension'] {\n if (!this.cachedExtensionWithSyncedStorage) {\n const editor = this.editor\n const extension = this.extension\n\n this.cachedExtensionWithSyncedStorage = new Proxy(extension, {\n get(target, prop, receiver) {\n if (prop === 'storage') {\n return editor.storage[extension.name as keyof typeof editor.storage] ?? {}\n }\n return Reflect.get(target, prop, receiver)\n },\n })\n }\n\n return this.cachedExtensionWithSyncedStorage\n }\n\n mount() {\n const props = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations as DecorationWithType[],\n innerDecorations: this.innerDecorations,\n view: this.view,\n selected: false,\n extension: this.extensionWithSyncedStorage,\n HTMLAttributes: this.HTMLAttributes,\n getPos: () => this.getPos(),\n updateAttributes: (attributes = {}) => this.updateAttributes(attributes),\n deleteNode: () => this.deleteNode(),\n } satisfies NodeViewProps\n\n const onDragStart = this.onDragStart.bind(this)\n\n this.decorationClasses = ref(this.getDecorationClasses())\n\n const extendedComponent = defineComponent({\n extends: { ...this.component },\n props: Object.keys(props),\n template: (this.component as any).template,\n setup: reactiveProps => {\n provide('onDragStart', onDragStart)\n provide('decorationClasses', this.decorationClasses)\n\n return (this.component as any).setup?.(reactiveProps, {\n expose: () => undefined,\n })\n },\n // add support for scoped styles\n // @ts-ignore\n // eslint-disable-next-line\n __scopeId: this.component.__scopeId,\n // add support for CSS Modules\n // @ts-ignore\n // eslint-disable-next-line\n __cssModules: this.component.__cssModules,\n // add support for vue devtools\n // @ts-ignore\n // eslint-disable-next-line\n __name: this.component.__name,\n // @ts-ignore\n // eslint-disable-next-line\n __file: this.component.__file,\n })\n\n this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this)\n this.editor.on('selectionUpdate', this.handleSelectionUpdate)\n this.currentPos = this.getPos()\n\n this.positionCheckCallback = () => {\n // Guard against the callback firing before the renderer is fully initialized.\n if (!this.renderer) {\n return\n }\n\n const newPos = this.getPos()\n\n if (typeof newPos !== 'number' || newPos === this.currentPos) {\n return\n }\n\n this.currentPos = newPos\n\n // Pass a fresh getPos reference so Vue's reactivity detects a prop change.\n this.renderer.updateProps({ getPos: () => this.getPos() })\n }\n\n schedulePositionCheck(this.editor, this.positionCheckCallback)\n\n this.renderer = new VueRenderer(extendedComponent, {\n editor: this.editor,\n props,\n })\n }\n\n /**\n * Return the DOM element.\n * This is the element that will be used to display the node view.\n */\n get dom() {\n if (!this.renderer.element || !this.renderer.element.hasAttribute('data-node-view-wrapper')) {\n throw Error('Please use the NodeViewWrapper component for your node view.')\n }\n\n return this.renderer.element as HTMLElement\n }\n\n /**\n * Return the content DOM element.\n * This is the element that will be used to display the rich-text content of the node.\n */\n get contentDOM() {\n if (this.node.isLeaf) {\n return null\n }\n\n return this.dom.querySelector('[data-node-view-content]') as HTMLElement | null\n }\n\n /**\n * On editor selection update, check if the node is selected.\n * If it is, call `selectNode`, otherwise call `deselectNode`.\n */\n handleSelectionUpdate() {\n const { from, to } = this.editor.state.selection\n const pos = this.getPos()\n\n if (typeof pos !== 'number') {\n return\n }\n\n if (from <= pos && to >= pos + this.node.nodeSize) {\n if (this.renderer.props.selected) {\n return\n }\n\n this.selectNode()\n } else {\n if (!this.renderer.props.selected) {\n return\n }\n\n this.deselectNode()\n }\n }\n\n /**\n * On update, update the React component.\n * To prevent unnecessary updates, the `update` option can be used.\n */\n update(node: ProseMirrorNode, decorations: readonly Decoration[], innerDecorations: DecorationSource): boolean {\n const rerenderComponent = (props?: Record<string, any>) => {\n this.decorationClasses.value = this.getDecorationClasses()\n this.renderer.updateProps(props)\n }\n\n if (typeof this.options.update === 'function') {\n const oldNode = this.node\n const oldDecorations = this.decorations\n const oldInnerDecorations = this.innerDecorations\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n this.currentPos = this.getPos()\n\n return this.options.update({\n oldNode,\n oldDecorations,\n newNode: node,\n newDecorations: decorations,\n oldInnerDecorations,\n innerDecorations,\n updateProps: () =>\n rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage }),\n })\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n const newPos = this.getPos()\n\n if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {\n if (newPos === this.currentPos) {\n return true\n }\n\n // Position changed without a content/decoration change — trigger re-render\n // so the component receives an up-to-date value from getPos().\n // Pass a fresh getPos reference so Vue's reactivity detects a prop change.\n this.currentPos = newPos\n rerenderComponent({\n node,\n decorations,\n innerDecorations,\n extension: this.extensionWithSyncedStorage,\n getPos: () => this.getPos(),\n })\n return true\n }\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n this.currentPos = newPos\n\n rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage })\n\n return true\n }\n\n /**\n * Select the node.\n * Add the `selected` prop and the `ProseMirror-selectednode` class.\n */\n selectNode() {\n this.renderer.updateProps({\n selected: true,\n })\n if (this.renderer.element) {\n this.renderer.element.classList.add('ProseMirror-selectednode')\n }\n }\n\n /**\n * Deselect the node.\n * Remove the `selected` prop and the `ProseMirror-selectednode` class.\n */\n deselectNode() {\n this.renderer.updateProps({\n selected: false,\n })\n if (this.renderer.element) {\n this.renderer.element.classList.remove('ProseMirror-selectednode')\n }\n }\n\n getDecorationClasses() {\n return (\n this.decorations\n // @ts-ignore\n .flatMap(item => item.type.attrs.class)\n .join(' ')\n )\n }\n\n destroy() {\n this.renderer.destroy()\n this.editor.off('selectionUpdate', this.handleSelectionUpdate)\n\n if (this.positionCheckCallback) {\n cancelPositionCheck(this.editor, this.positionCheckCallback)\n this.positionCheckCallback = null\n }\n }\n}\n\nexport function VueNodeViewRenderer(\n component: Component<NodeViewProps>,\n options?: Partial<VueNodeViewRendererOptions>,\n): NodeViewRenderer {\n return props => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {} as unknown as ProseMirrorNodeView\n }\n // check for class-component and normalize if neccessary\n const normalizedComponent =\n typeof component === 'function' && '__vccOpts' in component ? (component.__vccOpts as Component) : component\n\n return new VueNodeView(normalizedComponent, props, options)\n }\n}\n"],"mappings":"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","names":["CoreEditor","import_vue","import_vue","import_vue","import_vue","import_core","import_vue","import_vue","import_core","import_vue"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/Editor.ts","../src/EditorContent.ts","../src/NodeViewContent.ts","../src/NodeViewWrapper.ts","../src/useEditor.ts","../src/VueMarkViewRenderer.ts","../src/VueRenderer.ts","../src/VueNodeViewRenderer.ts"],"sourcesContent":["export { Editor } from './Editor.js'\nexport * from './EditorContent.js'\nexport * from './NodeViewContent.js'\nexport * from './NodeViewWrapper.js'\nexport * from './useEditor.js'\nexport * from './VueMarkViewRenderer.js'\nexport * from './VueNodeViewRenderer.js'\nexport * from './VueRenderer.js'\nexport * from '@tiptap/core'\n","/* eslint-disable react-hooks/rules-of-hooks */\nimport type { EditorOptions, Storage } from '@tiptap/core'\nimport { Editor as CoreEditor } from '@tiptap/core'\nimport type { EditorState, Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { AppContext, ComponentInternalInstance, ComponentPublicInstance, Ref } from 'vue'\nimport { customRef, markRaw } from 'vue'\n\nfunction useDebouncedRef<T>(value: T) {\n return customRef<T>((track, trigger) => {\n return {\n get() {\n track()\n return value\n },\n set(newValue) {\n // update state\n value = newValue\n\n // update view as soon as possible\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n trigger()\n })\n })\n },\n }\n })\n}\n\nexport type ContentComponent = ComponentInternalInstance & {\n ctx: ComponentPublicInstance\n}\n\nexport class Editor extends CoreEditor {\n private reactiveState: Ref<EditorState>\n\n private reactiveExtensionStorage: Ref<Storage>\n\n public contentComponent: ContentComponent | null = null\n\n public appContext: AppContext | null = null\n\n constructor(options: Partial<EditorOptions> = {}) {\n super(options)\n\n this.reactiveState = useDebouncedRef(this.view.state)\n this.reactiveExtensionStorage = useDebouncedRef(this.extensionStorage)\n\n this.on('beforeTransaction', ({ nextState }) => {\n this.reactiveState.value = nextState\n this.reactiveExtensionStorage.value = this.extensionStorage\n })\n\n return markRaw(this) // eslint-disable-line\n }\n\n get state() {\n return this.reactiveState ? this.reactiveState.value : this.view.state\n }\n\n get storage() {\n return this.reactiveExtensionStorage ? this.reactiveExtensionStorage.value : super.storage\n }\n\n /**\n * Register a ProseMirror plugin.\n */\n public registerPlugin(\n plugin: Plugin,\n handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[],\n ): EditorState {\n const nextState = super.registerPlugin(plugin, handlePlugins)\n\n if (this.reactiveState) {\n this.reactiveState.value = nextState\n }\n\n return nextState\n }\n\n /**\n * Unregister a ProseMirror plugin.\n */\n public unregisterPlugin(nameOrPluginKey: string | PluginKey): EditorState | undefined {\n const nextState = super.unregisterPlugin(nameOrPluginKey)\n\n if (this.reactiveState && nextState) {\n this.reactiveState.value = nextState\n }\n\n return nextState\n }\n}\n","import type { PropType, Ref } from 'vue'\nimport { defineComponent, getCurrentInstance, h, nextTick, onBeforeUnmount, ref, unref, watchEffect } from 'vue'\n\nimport type { Editor } from './Editor.js'\n\nexport const EditorContent = defineComponent({\n name: 'EditorContent',\n\n props: {\n editor: {\n default: null,\n type: Object as PropType<Editor>,\n },\n },\n\n setup(props) {\n const rootEl: Ref<Element | undefined> = ref()\n const instance = getCurrentInstance()\n\n watchEffect(() => {\n const editor = props.editor\n\n if (editor && editor.options.element && rootEl.value) {\n nextTick(() => {\n if (!rootEl.value || !editor.view.dom?.parentNode) {\n return\n }\n\n // TODO using the new editor.mount method might allow us to remove this\n const element = unref(rootEl.value)\n\n rootEl.value.append(...editor.view.dom.parentNode.childNodes)\n\n // @ts-ignore\n editor.contentComponent = instance.ctx._\n\n if (instance) {\n editor.appContext = {\n ...instance.appContext,\n // Vue internally uses prototype chain to forward/shadow injects across the entire component chain\n // so don't use object spread operator or 'Object.assign' and just set `provides` as is on editor's appContext\n // @ts-expect-error forward instance's 'provides' into appContext\n provides: instance.provides,\n }\n }\n\n editor.setOptions({\n element,\n })\n\n editor.createNodeViews()\n })\n }\n })\n\n onBeforeUnmount(() => {\n const editor = props.editor\n\n if (!editor) {\n return\n }\n\n editor.contentComponent = null\n editor.appContext = null\n })\n\n return { rootEl }\n },\n\n render() {\n return h('div', {\n ref: (el: any) => {\n this.rootEl = el\n },\n })\n },\n})\n","import { defineComponent, h } from 'vue'\n\nexport const NodeViewContent = defineComponent({\n name: 'NodeViewContent',\n\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n render() {\n return h(this.as, {\n style: {\n whiteSpace: 'pre-wrap',\n },\n 'data-node-view-content': '',\n })\n },\n})\n","import { defineComponent, h } from 'vue'\n\nexport const NodeViewWrapper = defineComponent({\n name: 'NodeViewWrapper',\n\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n inject: ['onDragStart', 'decorationClasses'],\n\n render() {\n return h(\n this.as,\n {\n // @ts-ignore\n class: this.decorationClasses,\n style: {\n whiteSpace: 'normal',\n },\n 'data-node-view-wrapper': '',\n // @ts-ignore (https://github.com/vuejs/vue-next/issues/3031)\n onDragstart: this.onDragStart,\n },\n this.$slots.default?.(),\n )\n },\n})\n","import type { EditorOptions } from '@tiptap/core'\nimport { onBeforeUnmount, onMounted, shallowRef } from 'vue'\n\nimport { Editor } from './Editor.js'\n\nexport const useEditor = (options: Partial<EditorOptions> = {}) => {\n const editor = shallowRef<Editor>()\n\n onMounted(() => {\n editor.value = new Editor(options)\n })\n\n onBeforeUnmount(() => {\n // Cloning root node (and its children) to avoid content being lost by destroy\n const nodes = editor.value?.view.dom?.parentNode\n const newEl = nodes?.cloneNode(true) as HTMLElement\n\n nodes?.parentNode?.replaceChild(newEl, nodes)\n\n editor.value?.destroy()\n })\n\n return editor\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { MarkViewProps, MarkViewRenderer, MarkViewRendererOptions } from '@tiptap/core'\nimport { MarkView } from '@tiptap/core'\nimport type { Component, PropType } from 'vue'\nimport { defineComponent, h, toRaw } from 'vue'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport interface VueMarkViewRendererOptions extends MarkViewRendererOptions {\n as?: string\n className?: string\n attrs?: { [key: string]: string }\n}\n\nexport const markViewProps = {\n editor: {\n type: Object as PropType<MarkViewProps['editor']>,\n required: true as const,\n },\n mark: {\n type: Object as PropType<MarkViewProps['mark']>,\n required: true as const,\n },\n extension: {\n type: Object as PropType<MarkViewProps['extension']>,\n required: true as const,\n },\n inline: {\n type: Boolean as PropType<MarkViewProps['inline']>,\n required: true as const,\n },\n view: {\n type: Object as PropType<MarkViewProps['view']>,\n required: true as const,\n },\n updateAttributes: {\n type: Function as PropType<MarkViewProps['updateAttributes']>,\n required: true as const,\n },\n HTMLAttributes: {\n type: Object as PropType<MarkViewProps['HTMLAttributes']>,\n required: true as const,\n },\n}\n\nexport const MarkViewContent = defineComponent({\n name: 'MarkViewContent',\n\n props: {\n as: {\n type: String,\n default: 'span',\n },\n },\n\n render() {\n return h(this.as, {\n style: {\n whiteSpace: 'inherit',\n },\n 'data-mark-view-content': '',\n })\n },\n})\n\nexport class VueMarkView extends MarkView<Component, VueMarkViewRendererOptions> {\n renderer: VueRenderer\n\n constructor(component: Component, props: MarkViewProps, options?: Partial<VueMarkViewRendererOptions>) {\n super(component, props, options)\n\n const componentProps = { ...props, updateAttributes: this.updateAttributes.bind(this) } satisfies MarkViewProps\n\n // Create extended component with provide\n const extendedComponent = defineComponent({\n extends: { ...component },\n props: Object.keys(componentProps),\n template: (this.component as any).template,\n setup: reactiveProps => {\n return (component as any).setup?.(reactiveProps, {\n expose: () => undefined,\n })\n },\n // Add support for scoped styles\n __scopeId: (component as any).__scopeId,\n __cssModules: (component as any).__cssModules,\n __name: (component as any).__name,\n __file: (component as any).__file,\n })\n this.renderer = new VueRenderer(extendedComponent, {\n editor: this.editor,\n props: componentProps,\n })\n }\n\n get dom() {\n return this.renderer.element as HTMLElement\n }\n\n get contentDOM() {\n return this.dom.querySelector('[data-mark-view-content]') as HTMLElement | null\n }\n\n updateAttributes(attrs: Record<string, any>): void {\n // since this.mark is now an proxy, we need to get the actual mark from it\n const unproxiedMark = toRaw(this.mark)\n super.updateAttributes(attrs, unproxiedMark)\n }\n\n destroy() {\n this.renderer.destroy()\n }\n}\n\nexport function VueMarkViewRenderer(\n component: Component,\n options: Partial<VueMarkViewRendererOptions> = {},\n): MarkViewRenderer {\n return props => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {} as unknown as MarkView<any, any>\n }\n\n return new VueMarkView(component, props, options)\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport type { Component, DefineComponent } from 'vue'\nimport { h, markRaw, reactive, render } from 'vue'\n\nimport type { Editor as ExtendedEditor } from './Editor.js'\n\nexport interface VueRendererOptions {\n editor: Editor\n props?: Record<string, any>\n}\n\ntype ExtendedVNode = ReturnType<typeof h> | null\n\ninterface RenderedComponent {\n vNode: ExtendedVNode\n destroy: () => void\n el: Element | null\n}\n\n/**\n * This class is used to render Vue components inside the editor.\n */\nexport class VueRenderer {\n renderedComponent!: RenderedComponent\n\n editor: ExtendedEditor\n\n component: Component\n\n el: Element | null\n\n props: Record<string, any>\n\n /**\n * Flag to track if the renderer has been destroyed, preventing queued or asynchronous renders from executing after teardown.\n */\n destroyed = false\n\n constructor(component: Component, { props = {}, editor }: VueRendererOptions) {\n this.editor = editor as ExtendedEditor\n this.component = markRaw(component)\n this.el = document.createElement('div')\n this.props = reactive(props)\n this.renderedComponent = this.renderComponent()\n }\n\n get element(): Element | null {\n return this.renderedComponent.el\n }\n\n get ref(): any {\n // Composition API\n if (this.renderedComponent.vNode?.component?.exposed) {\n return this.renderedComponent.vNode.component.exposed\n }\n // Option API\n return this.renderedComponent.vNode?.component?.proxy\n }\n\n renderComponent() {\n if (this.destroyed) {\n return this.renderedComponent\n }\n\n let vNode: ExtendedVNode = h(this.component as DefineComponent, this.props)\n\n if (this.editor.appContext) {\n vNode.appContext = this.editor.appContext\n }\n if (typeof document !== 'undefined' && this.el) {\n render(vNode, this.el)\n }\n\n const destroy = () => {\n if (this.el) {\n render(null, this.el)\n }\n this.el = null\n vNode = null\n }\n\n return { vNode, destroy, el: this.el ? this.el.firstElementChild : null }\n }\n\n updateProps(props: Record<string, any> = {}): void {\n if (this.destroyed) {\n return\n }\n\n Object.entries(props).forEach(([key, value]) => {\n this.props[key] = value\n })\n this.renderComponent()\n }\n\n destroy(): void {\n if (this.destroyed) {\n return\n }\n\n this.destroyed = true\n this.renderedComponent.destroy()\n }\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'\nimport { cancelPositionCheck, isNodeViewSelected, NodeView, schedulePositionCheck } from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport type { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'\nimport type { Component, PropType, Ref } from 'vue'\nimport { defineComponent, provide, ref } from 'vue'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport const nodeViewProps = {\n editor: {\n type: Object as PropType<NodeViewProps['editor']>,\n required: true as const,\n },\n node: {\n type: Object as PropType<NodeViewProps['node']>,\n required: true as const,\n },\n decorations: {\n type: Object as PropType<NodeViewProps['decorations']>,\n required: true as const,\n },\n selected: {\n type: Boolean as PropType<NodeViewProps['selected']>,\n required: true as const,\n },\n extension: {\n type: Object as PropType<NodeViewProps['extension']>,\n required: true as const,\n },\n getPos: {\n type: Function as PropType<NodeViewProps['getPos']>,\n required: true as const,\n },\n updateAttributes: {\n type: Function as PropType<NodeViewProps['updateAttributes']>,\n required: true as const,\n },\n deleteNode: {\n type: Function as PropType<NodeViewProps['deleteNode']>,\n required: true as const,\n },\n view: {\n type: Object as PropType<NodeViewProps['view']>,\n required: true as const,\n },\n innerDecorations: {\n type: Object as PropType<NodeViewProps['innerDecorations']>,\n required: true as const,\n },\n HTMLAttributes: {\n type: Object as PropType<NodeViewProps['HTMLAttributes']>,\n required: true as const,\n },\n}\n\nexport interface VueNodeViewRendererOptions extends NodeViewRendererOptions {\n update:\n | ((props: {\n oldNode: ProseMirrorNode\n oldDecorations: readonly Decoration[]\n oldInnerDecorations: DecorationSource\n newNode: ProseMirrorNode\n newDecorations: readonly Decoration[]\n innerDecorations: DecorationSource\n updateProps: () => void\n }) => boolean)\n | null\n}\n\nclass VueNodeView extends NodeView<Component, Editor, VueNodeViewRendererOptions> {\n renderer!: VueRenderer\n\n decorationClasses!: Ref<string>\n\n /**\n * The last known position of this node view, used to detect position-only\n * changes that don't produce a new node object reference.\n */\n private currentPos: number | undefined\n\n /**\n * Callback registered with the per-editor position-update registry.\n * Stored so it can be unregistered in destroy().\n */\n private positionCheckCallback: (() => void) | null = null\n\n private cachedExtensionWithSyncedStorage: NodeViewProps['extension'] | null = null\n\n /**\n * Returns a proxy of the extension that redirects storage access to the editor's mutable storage.\n * This preserves the original prototype chain (instanceof checks, methods like configure/extend work).\n * Cached to avoid proxy creation on every update.\n */\n get extensionWithSyncedStorage(): NodeViewProps['extension'] {\n if (!this.cachedExtensionWithSyncedStorage) {\n const editor = this.editor\n const extension = this.extension\n\n this.cachedExtensionWithSyncedStorage = new Proxy(extension, {\n get(target, prop, receiver) {\n if (prop === 'storage') {\n return editor.storage[extension.name as keyof typeof editor.storage] ?? {}\n }\n return Reflect.get(target, prop, receiver)\n },\n })\n }\n\n return this.cachedExtensionWithSyncedStorage\n }\n\n mount() {\n const props = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations as DecorationWithType[],\n innerDecorations: this.innerDecorations,\n view: this.view,\n selected: false,\n extension: this.extensionWithSyncedStorage,\n HTMLAttributes: this.HTMLAttributes,\n getPos: () => this.getPos(),\n updateAttributes: (attributes = {}) => this.updateAttributes(attributes),\n deleteNode: () => this.deleteNode(),\n } satisfies NodeViewProps\n\n const onDragStart = this.onDragStart.bind(this)\n\n this.decorationClasses = ref(this.getDecorationClasses())\n\n const extendedComponent = defineComponent({\n extends: { ...this.component },\n props: Object.keys(props),\n template: (this.component as any).template,\n setup: reactiveProps => {\n provide('onDragStart', onDragStart)\n provide('decorationClasses', this.decorationClasses)\n\n return (this.component as any).setup?.(reactiveProps, {\n expose: () => undefined,\n })\n },\n // add support for scoped styles\n // @ts-ignore\n // eslint-disable-next-line\n __scopeId: this.component.__scopeId,\n // add support for CSS Modules\n // @ts-ignore\n // eslint-disable-next-line\n __cssModules: this.component.__cssModules,\n // add support for vue devtools\n // @ts-ignore\n // eslint-disable-next-line\n __name: this.component.__name,\n // @ts-ignore\n // eslint-disable-next-line\n __file: this.component.__file,\n })\n\n this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this)\n this.editor.on('selectionUpdate', this.handleSelectionUpdate)\n this.currentPos = this.getPos()\n\n this.positionCheckCallback = () => {\n // Guard against the callback firing before the renderer is fully initialized.\n if (!this.renderer) {\n return\n }\n\n const newPos = this.getPos()\n\n if (typeof newPos !== 'number' || newPos === this.currentPos) {\n return\n }\n\n this.currentPos = newPos\n\n // Pass a fresh getPos reference so Vue's reactivity detects a prop change.\n this.renderer.updateProps({ getPos: () => this.getPos() })\n }\n\n schedulePositionCheck(this.editor, this.positionCheckCallback)\n\n this.renderer = new VueRenderer(extendedComponent, {\n editor: this.editor,\n props,\n })\n }\n\n /**\n * Return the DOM element.\n * This is the element that will be used to display the node view.\n */\n get dom() {\n if (!this.renderer.element || !this.renderer.element.hasAttribute('data-node-view-wrapper')) {\n throw Error('Please use the NodeViewWrapper component for your node view.')\n }\n\n return this.renderer.element as HTMLElement\n }\n\n /**\n * Return the content DOM element.\n * This is the element that will be used to display the rich-text content of the node.\n */\n get contentDOM() {\n if (this.node.isLeaf) {\n return null\n }\n\n return this.dom.querySelector('[data-node-view-content]') as HTMLElement | null\n }\n\n /**\n * On editor selection update, check if the node is selected.\n * If it is, call `selectNode`, otherwise call `deselectNode`.\n */\n handleSelectionUpdate() {\n const pos = this.getPos()\n\n if (typeof pos !== 'number') {\n return\n }\n\n const isSelected = isNodeViewSelected({\n selection: this.editor.state.selection,\n pos,\n nodeSize: this.node.nodeSize,\n selectedOnTextSelection: this.options.selectedOnTextSelection,\n })\n\n if (isSelected) {\n if (this.renderer.props.selected) {\n return\n }\n\n this.selectNode()\n } else {\n if (!this.renderer.props.selected) {\n return\n }\n\n this.deselectNode()\n }\n }\n\n /**\n * On update, update the React component.\n * To prevent unnecessary updates, the `update` option can be used.\n */\n update(node: ProseMirrorNode, decorations: readonly Decoration[], innerDecorations: DecorationSource): boolean {\n const rerenderComponent = (props?: Record<string, any>) => {\n this.decorationClasses.value = this.getDecorationClasses()\n this.renderer.updateProps(props)\n }\n\n if (typeof this.options.update === 'function') {\n const oldNode = this.node\n const oldDecorations = this.decorations\n const oldInnerDecorations = this.innerDecorations\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n this.currentPos = this.getPos()\n\n return this.options.update({\n oldNode,\n oldDecorations,\n newNode: node,\n newDecorations: decorations,\n oldInnerDecorations,\n innerDecorations,\n updateProps: () =>\n rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage }),\n })\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n const newPos = this.getPos()\n\n if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {\n if (newPos === this.currentPos) {\n return true\n }\n\n // Position changed without a content/decoration change — trigger re-render\n // so the component receives an up-to-date value from getPos().\n // Pass a fresh getPos reference so Vue's reactivity detects a prop change.\n this.currentPos = newPos\n rerenderComponent({\n node,\n decorations,\n innerDecorations,\n extension: this.extensionWithSyncedStorage,\n getPos: () => this.getPos(),\n })\n return true\n }\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n this.currentPos = newPos\n\n rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage })\n\n return true\n }\n\n /**\n * Select the node.\n * Add the `selected` prop and the `ProseMirror-selectednode` class.\n */\n selectNode() {\n this.renderer.updateProps({\n selected: true,\n })\n if (this.renderer.element) {\n this.renderer.element.classList.add('ProseMirror-selectednode')\n }\n }\n\n /**\n * Deselect the node.\n * Remove the `selected` prop and the `ProseMirror-selectednode` class.\n */\n deselectNode() {\n this.renderer.updateProps({\n selected: false,\n })\n if (this.renderer.element) {\n this.renderer.element.classList.remove('ProseMirror-selectednode')\n }\n }\n\n getDecorationClasses() {\n return (\n this.decorations\n // @ts-ignore\n .flatMap(item => item.type.attrs.class)\n .join(' ')\n )\n }\n\n destroy() {\n this.renderer.destroy()\n this.editor.off('selectionUpdate', this.handleSelectionUpdate)\n\n if (this.positionCheckCallback) {\n cancelPositionCheck(this.editor, this.positionCheckCallback)\n this.positionCheckCallback = null\n }\n }\n}\n\nexport function VueNodeViewRenderer(\n component: Component<NodeViewProps>,\n options?: Partial<VueNodeViewRendererOptions>,\n): NodeViewRenderer {\n return props => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {} as unknown as ProseMirrorNodeView\n }\n // check for class-component and normalize if neccessary\n const normalizedComponent =\n typeof component === 'function' && '__vccOpts' in component ? (component.__vccOpts as Component) : component\n\n return new VueNodeView(normalizedComponent, props, options)\n }\n}\n"],"mappings":"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","names":["CoreEditor","import_vue","import_vue","import_vue","import_vue","import_core","import_vue","import_vue","import_core","import_vue"]}
|
package/dist/index.js
CHANGED
|
@@ -349,7 +349,7 @@ function VueMarkViewRenderer(component, options = {}) {
|
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
// src/VueNodeViewRenderer.ts
|
|
352
|
-
import { cancelPositionCheck, NodeView, schedulePositionCheck } from "@tiptap/core";
|
|
352
|
+
import { cancelPositionCheck, isNodeViewSelected, NodeView, schedulePositionCheck } from "@tiptap/core";
|
|
353
353
|
import { defineComponent as defineComponent5, provide, ref as ref2 } from "vue";
|
|
354
354
|
var nodeViewProps = {
|
|
355
355
|
editor: {
|
|
@@ -517,12 +517,17 @@ var VueNodeView = class extends NodeView {
|
|
|
517
517
|
* If it is, call `selectNode`, otherwise call `deselectNode`.
|
|
518
518
|
*/
|
|
519
519
|
handleSelectionUpdate() {
|
|
520
|
-
const { from, to } = this.editor.state.selection;
|
|
521
520
|
const pos = this.getPos();
|
|
522
521
|
if (typeof pos !== "number") {
|
|
523
522
|
return;
|
|
524
523
|
}
|
|
525
|
-
|
|
524
|
+
const isSelected = isNodeViewSelected({
|
|
525
|
+
selection: this.editor.state.selection,
|
|
526
|
+
pos,
|
|
527
|
+
nodeSize: this.node.nodeSize,
|
|
528
|
+
selectedOnTextSelection: this.options.selectedOnTextSelection
|
|
529
|
+
});
|
|
530
|
+
if (isSelected) {
|
|
526
531
|
if (this.renderer.props.selected) {
|
|
527
532
|
return;
|
|
528
533
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Editor.ts","../src/EditorContent.ts","../src/NodeViewContent.ts","../src/NodeViewWrapper.ts","../src/useEditor.ts","../src/VueMarkViewRenderer.ts","../src/VueRenderer.ts","../src/VueNodeViewRenderer.ts","../src/index.ts"],"sourcesContent":["/* eslint-disable react-hooks/rules-of-hooks */\nimport type { EditorOptions, Storage } from '@tiptap/core'\nimport { Editor as CoreEditor } from '@tiptap/core'\nimport type { EditorState, Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { AppContext, ComponentInternalInstance, ComponentPublicInstance, Ref } from 'vue'\nimport { customRef, markRaw } from 'vue'\n\nfunction useDebouncedRef<T>(value: T) {\n return customRef<T>((track, trigger) => {\n return {\n get() {\n track()\n return value\n },\n set(newValue) {\n // update state\n value = newValue\n\n // update view as soon as possible\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n trigger()\n })\n })\n },\n }\n })\n}\n\nexport type ContentComponent = ComponentInternalInstance & {\n ctx: ComponentPublicInstance\n}\n\nexport class Editor extends CoreEditor {\n private reactiveState: Ref<EditorState>\n\n private reactiveExtensionStorage: Ref<Storage>\n\n public contentComponent: ContentComponent | null = null\n\n public appContext: AppContext | null = null\n\n constructor(options: Partial<EditorOptions> = {}) {\n super(options)\n\n this.reactiveState = useDebouncedRef(this.view.state)\n this.reactiveExtensionStorage = useDebouncedRef(this.extensionStorage)\n\n this.on('beforeTransaction', ({ nextState }) => {\n this.reactiveState.value = nextState\n this.reactiveExtensionStorage.value = this.extensionStorage\n })\n\n return markRaw(this) // eslint-disable-line\n }\n\n get state() {\n return this.reactiveState ? this.reactiveState.value : this.view.state\n }\n\n get storage() {\n return this.reactiveExtensionStorage ? this.reactiveExtensionStorage.value : super.storage\n }\n\n /**\n * Register a ProseMirror plugin.\n */\n public registerPlugin(\n plugin: Plugin,\n handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[],\n ): EditorState {\n const nextState = super.registerPlugin(plugin, handlePlugins)\n\n if (this.reactiveState) {\n this.reactiveState.value = nextState\n }\n\n return nextState\n }\n\n /**\n * Unregister a ProseMirror plugin.\n */\n public unregisterPlugin(nameOrPluginKey: string | PluginKey): EditorState | undefined {\n const nextState = super.unregisterPlugin(nameOrPluginKey)\n\n if (this.reactiveState && nextState) {\n this.reactiveState.value = nextState\n }\n\n return nextState\n }\n}\n","import type { PropType, Ref } from 'vue'\nimport { defineComponent, getCurrentInstance, h, nextTick, onBeforeUnmount, ref, unref, watchEffect } from 'vue'\n\nimport type { Editor } from './Editor.js'\n\nexport const EditorContent = defineComponent({\n name: 'EditorContent',\n\n props: {\n editor: {\n default: null,\n type: Object as PropType<Editor>,\n },\n },\n\n setup(props) {\n const rootEl: Ref<Element | undefined> = ref()\n const instance = getCurrentInstance()\n\n watchEffect(() => {\n const editor = props.editor\n\n if (editor && editor.options.element && rootEl.value) {\n nextTick(() => {\n if (!rootEl.value || !editor.view.dom?.parentNode) {\n return\n }\n\n // TODO using the new editor.mount method might allow us to remove this\n const element = unref(rootEl.value)\n\n rootEl.value.append(...editor.view.dom.parentNode.childNodes)\n\n // @ts-ignore\n editor.contentComponent = instance.ctx._\n\n if (instance) {\n editor.appContext = {\n ...instance.appContext,\n // Vue internally uses prototype chain to forward/shadow injects across the entire component chain\n // so don't use object spread operator or 'Object.assign' and just set `provides` as is on editor's appContext\n // @ts-expect-error forward instance's 'provides' into appContext\n provides: instance.provides,\n }\n }\n\n editor.setOptions({\n element,\n })\n\n editor.createNodeViews()\n })\n }\n })\n\n onBeforeUnmount(() => {\n const editor = props.editor\n\n if (!editor) {\n return\n }\n\n editor.contentComponent = null\n editor.appContext = null\n })\n\n return { rootEl }\n },\n\n render() {\n return h('div', {\n ref: (el: any) => {\n this.rootEl = el\n },\n })\n },\n})\n","import { defineComponent, h } from 'vue'\n\nexport const NodeViewContent = defineComponent({\n name: 'NodeViewContent',\n\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n render() {\n return h(this.as, {\n style: {\n whiteSpace: 'pre-wrap',\n },\n 'data-node-view-content': '',\n })\n },\n})\n","import { defineComponent, h } from 'vue'\n\nexport const NodeViewWrapper = defineComponent({\n name: 'NodeViewWrapper',\n\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n inject: ['onDragStart', 'decorationClasses'],\n\n render() {\n return h(\n this.as,\n {\n // @ts-ignore\n class: this.decorationClasses,\n style: {\n whiteSpace: 'normal',\n },\n 'data-node-view-wrapper': '',\n // @ts-ignore (https://github.com/vuejs/vue-next/issues/3031)\n onDragstart: this.onDragStart,\n },\n this.$slots.default?.(),\n )\n },\n})\n","import type { EditorOptions } from '@tiptap/core'\nimport { onBeforeUnmount, onMounted, shallowRef } from 'vue'\n\nimport { Editor } from './Editor.js'\n\nexport const useEditor = (options: Partial<EditorOptions> = {}) => {\n const editor = shallowRef<Editor>()\n\n onMounted(() => {\n editor.value = new Editor(options)\n })\n\n onBeforeUnmount(() => {\n // Cloning root node (and its children) to avoid content being lost by destroy\n const nodes = editor.value?.view.dom?.parentNode\n const newEl = nodes?.cloneNode(true) as HTMLElement\n\n nodes?.parentNode?.replaceChild(newEl, nodes)\n\n editor.value?.destroy()\n })\n\n return editor\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { MarkViewProps, MarkViewRenderer, MarkViewRendererOptions } from '@tiptap/core'\nimport { MarkView } from '@tiptap/core'\nimport type { Component, PropType } from 'vue'\nimport { defineComponent, h, toRaw } from 'vue'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport interface VueMarkViewRendererOptions extends MarkViewRendererOptions {\n as?: string\n className?: string\n attrs?: { [key: string]: string }\n}\n\nexport const markViewProps = {\n editor: {\n type: Object as PropType<MarkViewProps['editor']>,\n required: true as const,\n },\n mark: {\n type: Object as PropType<MarkViewProps['mark']>,\n required: true as const,\n },\n extension: {\n type: Object as PropType<MarkViewProps['extension']>,\n required: true as const,\n },\n inline: {\n type: Boolean as PropType<MarkViewProps['inline']>,\n required: true as const,\n },\n view: {\n type: Object as PropType<MarkViewProps['view']>,\n required: true as const,\n },\n updateAttributes: {\n type: Function as PropType<MarkViewProps['updateAttributes']>,\n required: true as const,\n },\n HTMLAttributes: {\n type: Object as PropType<MarkViewProps['HTMLAttributes']>,\n required: true as const,\n },\n}\n\nexport const MarkViewContent = defineComponent({\n name: 'MarkViewContent',\n\n props: {\n as: {\n type: String,\n default: 'span',\n },\n },\n\n render() {\n return h(this.as, {\n style: {\n whiteSpace: 'inherit',\n },\n 'data-mark-view-content': '',\n })\n },\n})\n\nexport class VueMarkView extends MarkView<Component, VueMarkViewRendererOptions> {\n renderer: VueRenderer\n\n constructor(component: Component, props: MarkViewProps, options?: Partial<VueMarkViewRendererOptions>) {\n super(component, props, options)\n\n const componentProps = { ...props, updateAttributes: this.updateAttributes.bind(this) } satisfies MarkViewProps\n\n // Create extended component with provide\n const extendedComponent = defineComponent({\n extends: { ...component },\n props: Object.keys(componentProps),\n template: (this.component as any).template,\n setup: reactiveProps => {\n return (component as any).setup?.(reactiveProps, {\n expose: () => undefined,\n })\n },\n // Add support for scoped styles\n __scopeId: (component as any).__scopeId,\n __cssModules: (component as any).__cssModules,\n __name: (component as any).__name,\n __file: (component as any).__file,\n })\n this.renderer = new VueRenderer(extendedComponent, {\n editor: this.editor,\n props: componentProps,\n })\n }\n\n get dom() {\n return this.renderer.element as HTMLElement\n }\n\n get contentDOM() {\n return this.dom.querySelector('[data-mark-view-content]') as HTMLElement | null\n }\n\n updateAttributes(attrs: Record<string, any>): void {\n // since this.mark is now an proxy, we need to get the actual mark from it\n const unproxiedMark = toRaw(this.mark)\n super.updateAttributes(attrs, unproxiedMark)\n }\n\n destroy() {\n this.renderer.destroy()\n }\n}\n\nexport function VueMarkViewRenderer(\n component: Component,\n options: Partial<VueMarkViewRendererOptions> = {},\n): MarkViewRenderer {\n return props => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {} as unknown as MarkView<any, any>\n }\n\n return new VueMarkView(component, props, options)\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport type { Component, DefineComponent } from 'vue'\nimport { h, markRaw, reactive, render } from 'vue'\n\nimport type { Editor as ExtendedEditor } from './Editor.js'\n\nexport interface VueRendererOptions {\n editor: Editor\n props?: Record<string, any>\n}\n\ntype ExtendedVNode = ReturnType<typeof h> | null\n\ninterface RenderedComponent {\n vNode: ExtendedVNode\n destroy: () => void\n el: Element | null\n}\n\n/**\n * This class is used to render Vue components inside the editor.\n */\nexport class VueRenderer {\n renderedComponent!: RenderedComponent\n\n editor: ExtendedEditor\n\n component: Component\n\n el: Element | null\n\n props: Record<string, any>\n\n /**\n * Flag to track if the renderer has been destroyed, preventing queued or asynchronous renders from executing after teardown.\n */\n destroyed = false\n\n constructor(component: Component, { props = {}, editor }: VueRendererOptions) {\n this.editor = editor as ExtendedEditor\n this.component = markRaw(component)\n this.el = document.createElement('div')\n this.props = reactive(props)\n this.renderedComponent = this.renderComponent()\n }\n\n get element(): Element | null {\n return this.renderedComponent.el\n }\n\n get ref(): any {\n // Composition API\n if (this.renderedComponent.vNode?.component?.exposed) {\n return this.renderedComponent.vNode.component.exposed\n }\n // Option API\n return this.renderedComponent.vNode?.component?.proxy\n }\n\n renderComponent() {\n if (this.destroyed) {\n return this.renderedComponent\n }\n\n let vNode: ExtendedVNode = h(this.component as DefineComponent, this.props)\n\n if (this.editor.appContext) {\n vNode.appContext = this.editor.appContext\n }\n if (typeof document !== 'undefined' && this.el) {\n render(vNode, this.el)\n }\n\n const destroy = () => {\n if (this.el) {\n render(null, this.el)\n }\n this.el = null\n vNode = null\n }\n\n return { vNode, destroy, el: this.el ? this.el.firstElementChild : null }\n }\n\n updateProps(props: Record<string, any> = {}): void {\n if (this.destroyed) {\n return\n }\n\n Object.entries(props).forEach(([key, value]) => {\n this.props[key] = value\n })\n this.renderComponent()\n }\n\n destroy(): void {\n if (this.destroyed) {\n return\n }\n\n this.destroyed = true\n this.renderedComponent.destroy()\n }\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'\nimport { cancelPositionCheck, NodeView, schedulePositionCheck } from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport type { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'\nimport type { Component, PropType, Ref } from 'vue'\nimport { defineComponent, provide, ref } from 'vue'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport const nodeViewProps = {\n editor: {\n type: Object as PropType<NodeViewProps['editor']>,\n required: true as const,\n },\n node: {\n type: Object as PropType<NodeViewProps['node']>,\n required: true as const,\n },\n decorations: {\n type: Object as PropType<NodeViewProps['decorations']>,\n required: true as const,\n },\n selected: {\n type: Boolean as PropType<NodeViewProps['selected']>,\n required: true as const,\n },\n extension: {\n type: Object as PropType<NodeViewProps['extension']>,\n required: true as const,\n },\n getPos: {\n type: Function as PropType<NodeViewProps['getPos']>,\n required: true as const,\n },\n updateAttributes: {\n type: Function as PropType<NodeViewProps['updateAttributes']>,\n required: true as const,\n },\n deleteNode: {\n type: Function as PropType<NodeViewProps['deleteNode']>,\n required: true as const,\n },\n view: {\n type: Object as PropType<NodeViewProps['view']>,\n required: true as const,\n },\n innerDecorations: {\n type: Object as PropType<NodeViewProps['innerDecorations']>,\n required: true as const,\n },\n HTMLAttributes: {\n type: Object as PropType<NodeViewProps['HTMLAttributes']>,\n required: true as const,\n },\n}\n\nexport interface VueNodeViewRendererOptions extends NodeViewRendererOptions {\n update:\n | ((props: {\n oldNode: ProseMirrorNode\n oldDecorations: readonly Decoration[]\n oldInnerDecorations: DecorationSource\n newNode: ProseMirrorNode\n newDecorations: readonly Decoration[]\n innerDecorations: DecorationSource\n updateProps: () => void\n }) => boolean)\n | null\n}\n\nclass VueNodeView extends NodeView<Component, Editor, VueNodeViewRendererOptions> {\n renderer!: VueRenderer\n\n decorationClasses!: Ref<string>\n\n /**\n * The last known position of this node view, used to detect position-only\n * changes that don't produce a new node object reference.\n */\n private currentPos: number | undefined\n\n /**\n * Callback registered with the per-editor position-update registry.\n * Stored so it can be unregistered in destroy().\n */\n private positionCheckCallback: (() => void) | null = null\n\n private cachedExtensionWithSyncedStorage: NodeViewProps['extension'] | null = null\n\n /**\n * Returns a proxy of the extension that redirects storage access to the editor's mutable storage.\n * This preserves the original prototype chain (instanceof checks, methods like configure/extend work).\n * Cached to avoid proxy creation on every update.\n */\n get extensionWithSyncedStorage(): NodeViewProps['extension'] {\n if (!this.cachedExtensionWithSyncedStorage) {\n const editor = this.editor\n const extension = this.extension\n\n this.cachedExtensionWithSyncedStorage = new Proxy(extension, {\n get(target, prop, receiver) {\n if (prop === 'storage') {\n return editor.storage[extension.name as keyof typeof editor.storage] ?? {}\n }\n return Reflect.get(target, prop, receiver)\n },\n })\n }\n\n return this.cachedExtensionWithSyncedStorage\n }\n\n mount() {\n const props = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations as DecorationWithType[],\n innerDecorations: this.innerDecorations,\n view: this.view,\n selected: false,\n extension: this.extensionWithSyncedStorage,\n HTMLAttributes: this.HTMLAttributes,\n getPos: () => this.getPos(),\n updateAttributes: (attributes = {}) => this.updateAttributes(attributes),\n deleteNode: () => this.deleteNode(),\n } satisfies NodeViewProps\n\n const onDragStart = this.onDragStart.bind(this)\n\n this.decorationClasses = ref(this.getDecorationClasses())\n\n const extendedComponent = defineComponent({\n extends: { ...this.component },\n props: Object.keys(props),\n template: (this.component as any).template,\n setup: reactiveProps => {\n provide('onDragStart', onDragStart)\n provide('decorationClasses', this.decorationClasses)\n\n return (this.component as any).setup?.(reactiveProps, {\n expose: () => undefined,\n })\n },\n // add support for scoped styles\n // @ts-ignore\n // eslint-disable-next-line\n __scopeId: this.component.__scopeId,\n // add support for CSS Modules\n // @ts-ignore\n // eslint-disable-next-line\n __cssModules: this.component.__cssModules,\n // add support for vue devtools\n // @ts-ignore\n // eslint-disable-next-line\n __name: this.component.__name,\n // @ts-ignore\n // eslint-disable-next-line\n __file: this.component.__file,\n })\n\n this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this)\n this.editor.on('selectionUpdate', this.handleSelectionUpdate)\n this.currentPos = this.getPos()\n\n this.positionCheckCallback = () => {\n // Guard against the callback firing before the renderer is fully initialized.\n if (!this.renderer) {\n return\n }\n\n const newPos = this.getPos()\n\n if (typeof newPos !== 'number' || newPos === this.currentPos) {\n return\n }\n\n this.currentPos = newPos\n\n // Pass a fresh getPos reference so Vue's reactivity detects a prop change.\n this.renderer.updateProps({ getPos: () => this.getPos() })\n }\n\n schedulePositionCheck(this.editor, this.positionCheckCallback)\n\n this.renderer = new VueRenderer(extendedComponent, {\n editor: this.editor,\n props,\n })\n }\n\n /**\n * Return the DOM element.\n * This is the element that will be used to display the node view.\n */\n get dom() {\n if (!this.renderer.element || !this.renderer.element.hasAttribute('data-node-view-wrapper')) {\n throw Error('Please use the NodeViewWrapper component for your node view.')\n }\n\n return this.renderer.element as HTMLElement\n }\n\n /**\n * Return the content DOM element.\n * This is the element that will be used to display the rich-text content of the node.\n */\n get contentDOM() {\n if (this.node.isLeaf) {\n return null\n }\n\n return this.dom.querySelector('[data-node-view-content]') as HTMLElement | null\n }\n\n /**\n * On editor selection update, check if the node is selected.\n * If it is, call `selectNode`, otherwise call `deselectNode`.\n */\n handleSelectionUpdate() {\n const { from, to } = this.editor.state.selection\n const pos = this.getPos()\n\n if (typeof pos !== 'number') {\n return\n }\n\n if (from <= pos && to >= pos + this.node.nodeSize) {\n if (this.renderer.props.selected) {\n return\n }\n\n this.selectNode()\n } else {\n if (!this.renderer.props.selected) {\n return\n }\n\n this.deselectNode()\n }\n }\n\n /**\n * On update, update the React component.\n * To prevent unnecessary updates, the `update` option can be used.\n */\n update(node: ProseMirrorNode, decorations: readonly Decoration[], innerDecorations: DecorationSource): boolean {\n const rerenderComponent = (props?: Record<string, any>) => {\n this.decorationClasses.value = this.getDecorationClasses()\n this.renderer.updateProps(props)\n }\n\n if (typeof this.options.update === 'function') {\n const oldNode = this.node\n const oldDecorations = this.decorations\n const oldInnerDecorations = this.innerDecorations\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n this.currentPos = this.getPos()\n\n return this.options.update({\n oldNode,\n oldDecorations,\n newNode: node,\n newDecorations: decorations,\n oldInnerDecorations,\n innerDecorations,\n updateProps: () =>\n rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage }),\n })\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n const newPos = this.getPos()\n\n if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {\n if (newPos === this.currentPos) {\n return true\n }\n\n // Position changed without a content/decoration change — trigger re-render\n // so the component receives an up-to-date value from getPos().\n // Pass a fresh getPos reference so Vue's reactivity detects a prop change.\n this.currentPos = newPos\n rerenderComponent({\n node,\n decorations,\n innerDecorations,\n extension: this.extensionWithSyncedStorage,\n getPos: () => this.getPos(),\n })\n return true\n }\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n this.currentPos = newPos\n\n rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage })\n\n return true\n }\n\n /**\n * Select the node.\n * Add the `selected` prop and the `ProseMirror-selectednode` class.\n */\n selectNode() {\n this.renderer.updateProps({\n selected: true,\n })\n if (this.renderer.element) {\n this.renderer.element.classList.add('ProseMirror-selectednode')\n }\n }\n\n /**\n * Deselect the node.\n * Remove the `selected` prop and the `ProseMirror-selectednode` class.\n */\n deselectNode() {\n this.renderer.updateProps({\n selected: false,\n })\n if (this.renderer.element) {\n this.renderer.element.classList.remove('ProseMirror-selectednode')\n }\n }\n\n getDecorationClasses() {\n return (\n this.decorations\n // @ts-ignore\n .flatMap(item => item.type.attrs.class)\n .join(' ')\n )\n }\n\n destroy() {\n this.renderer.destroy()\n this.editor.off('selectionUpdate', this.handleSelectionUpdate)\n\n if (this.positionCheckCallback) {\n cancelPositionCheck(this.editor, this.positionCheckCallback)\n this.positionCheckCallback = null\n }\n }\n}\n\nexport function VueNodeViewRenderer(\n component: Component<NodeViewProps>,\n options?: Partial<VueNodeViewRendererOptions>,\n): NodeViewRenderer {\n return props => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {} as unknown as ProseMirrorNodeView\n }\n // check for class-component and normalize if neccessary\n const normalizedComponent =\n typeof component === 'function' && '__vccOpts' in component ? (component.__vccOpts as Component) : component\n\n return new VueNodeView(normalizedComponent, props, options)\n }\n}\n","export { Editor } from './Editor.js'\nexport * from './EditorContent.js'\nexport * from './NodeViewContent.js'\nexport * from './NodeViewWrapper.js'\nexport * from './useEditor.js'\nexport * from './VueMarkViewRenderer.js'\nexport * from './VueNodeViewRenderer.js'\nexport * from './VueRenderer.js'\nexport * from '@tiptap/core'\n"],"mappings":"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","names":["defineComponent","h","defineComponent","h","onBeforeUnmount","onBeforeUnmount","defineComponent","h","h","markRaw","defineComponent","h","defineComponent","ref","ref","defineComponent"]}
|
|
1
|
+
{"version":3,"sources":["../src/Editor.ts","../src/EditorContent.ts","../src/NodeViewContent.ts","../src/NodeViewWrapper.ts","../src/useEditor.ts","../src/VueMarkViewRenderer.ts","../src/VueRenderer.ts","../src/VueNodeViewRenderer.ts","../src/index.ts"],"sourcesContent":["/* eslint-disable react-hooks/rules-of-hooks */\nimport type { EditorOptions, Storage } from '@tiptap/core'\nimport { Editor as CoreEditor } from '@tiptap/core'\nimport type { EditorState, Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { AppContext, ComponentInternalInstance, ComponentPublicInstance, Ref } from 'vue'\nimport { customRef, markRaw } from 'vue'\n\nfunction useDebouncedRef<T>(value: T) {\n return customRef<T>((track, trigger) => {\n return {\n get() {\n track()\n return value\n },\n set(newValue) {\n // update state\n value = newValue\n\n // update view as soon as possible\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n trigger()\n })\n })\n },\n }\n })\n}\n\nexport type ContentComponent = ComponentInternalInstance & {\n ctx: ComponentPublicInstance\n}\n\nexport class Editor extends CoreEditor {\n private reactiveState: Ref<EditorState>\n\n private reactiveExtensionStorage: Ref<Storage>\n\n public contentComponent: ContentComponent | null = null\n\n public appContext: AppContext | null = null\n\n constructor(options: Partial<EditorOptions> = {}) {\n super(options)\n\n this.reactiveState = useDebouncedRef(this.view.state)\n this.reactiveExtensionStorage = useDebouncedRef(this.extensionStorage)\n\n this.on('beforeTransaction', ({ nextState }) => {\n this.reactiveState.value = nextState\n this.reactiveExtensionStorage.value = this.extensionStorage\n })\n\n return markRaw(this) // eslint-disable-line\n }\n\n get state() {\n return this.reactiveState ? this.reactiveState.value : this.view.state\n }\n\n get storage() {\n return this.reactiveExtensionStorage ? this.reactiveExtensionStorage.value : super.storage\n }\n\n /**\n * Register a ProseMirror plugin.\n */\n public registerPlugin(\n plugin: Plugin,\n handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[],\n ): EditorState {\n const nextState = super.registerPlugin(plugin, handlePlugins)\n\n if (this.reactiveState) {\n this.reactiveState.value = nextState\n }\n\n return nextState\n }\n\n /**\n * Unregister a ProseMirror plugin.\n */\n public unregisterPlugin(nameOrPluginKey: string | PluginKey): EditorState | undefined {\n const nextState = super.unregisterPlugin(nameOrPluginKey)\n\n if (this.reactiveState && nextState) {\n this.reactiveState.value = nextState\n }\n\n return nextState\n }\n}\n","import type { PropType, Ref } from 'vue'\nimport { defineComponent, getCurrentInstance, h, nextTick, onBeforeUnmount, ref, unref, watchEffect } from 'vue'\n\nimport type { Editor } from './Editor.js'\n\nexport const EditorContent = defineComponent({\n name: 'EditorContent',\n\n props: {\n editor: {\n default: null,\n type: Object as PropType<Editor>,\n },\n },\n\n setup(props) {\n const rootEl: Ref<Element | undefined> = ref()\n const instance = getCurrentInstance()\n\n watchEffect(() => {\n const editor = props.editor\n\n if (editor && editor.options.element && rootEl.value) {\n nextTick(() => {\n if (!rootEl.value || !editor.view.dom?.parentNode) {\n return\n }\n\n // TODO using the new editor.mount method might allow us to remove this\n const element = unref(rootEl.value)\n\n rootEl.value.append(...editor.view.dom.parentNode.childNodes)\n\n // @ts-ignore\n editor.contentComponent = instance.ctx._\n\n if (instance) {\n editor.appContext = {\n ...instance.appContext,\n // Vue internally uses prototype chain to forward/shadow injects across the entire component chain\n // so don't use object spread operator or 'Object.assign' and just set `provides` as is on editor's appContext\n // @ts-expect-error forward instance's 'provides' into appContext\n provides: instance.provides,\n }\n }\n\n editor.setOptions({\n element,\n })\n\n editor.createNodeViews()\n })\n }\n })\n\n onBeforeUnmount(() => {\n const editor = props.editor\n\n if (!editor) {\n return\n }\n\n editor.contentComponent = null\n editor.appContext = null\n })\n\n return { rootEl }\n },\n\n render() {\n return h('div', {\n ref: (el: any) => {\n this.rootEl = el\n },\n })\n },\n})\n","import { defineComponent, h } from 'vue'\n\nexport const NodeViewContent = defineComponent({\n name: 'NodeViewContent',\n\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n render() {\n return h(this.as, {\n style: {\n whiteSpace: 'pre-wrap',\n },\n 'data-node-view-content': '',\n })\n },\n})\n","import { defineComponent, h } from 'vue'\n\nexport const NodeViewWrapper = defineComponent({\n name: 'NodeViewWrapper',\n\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n inject: ['onDragStart', 'decorationClasses'],\n\n render() {\n return h(\n this.as,\n {\n // @ts-ignore\n class: this.decorationClasses,\n style: {\n whiteSpace: 'normal',\n },\n 'data-node-view-wrapper': '',\n // @ts-ignore (https://github.com/vuejs/vue-next/issues/3031)\n onDragstart: this.onDragStart,\n },\n this.$slots.default?.(),\n )\n },\n})\n","import type { EditorOptions } from '@tiptap/core'\nimport { onBeforeUnmount, onMounted, shallowRef } from 'vue'\n\nimport { Editor } from './Editor.js'\n\nexport const useEditor = (options: Partial<EditorOptions> = {}) => {\n const editor = shallowRef<Editor>()\n\n onMounted(() => {\n editor.value = new Editor(options)\n })\n\n onBeforeUnmount(() => {\n // Cloning root node (and its children) to avoid content being lost by destroy\n const nodes = editor.value?.view.dom?.parentNode\n const newEl = nodes?.cloneNode(true) as HTMLElement\n\n nodes?.parentNode?.replaceChild(newEl, nodes)\n\n editor.value?.destroy()\n })\n\n return editor\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { MarkViewProps, MarkViewRenderer, MarkViewRendererOptions } from '@tiptap/core'\nimport { MarkView } from '@tiptap/core'\nimport type { Component, PropType } from 'vue'\nimport { defineComponent, h, toRaw } from 'vue'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport interface VueMarkViewRendererOptions extends MarkViewRendererOptions {\n as?: string\n className?: string\n attrs?: { [key: string]: string }\n}\n\nexport const markViewProps = {\n editor: {\n type: Object as PropType<MarkViewProps['editor']>,\n required: true as const,\n },\n mark: {\n type: Object as PropType<MarkViewProps['mark']>,\n required: true as const,\n },\n extension: {\n type: Object as PropType<MarkViewProps['extension']>,\n required: true as const,\n },\n inline: {\n type: Boolean as PropType<MarkViewProps['inline']>,\n required: true as const,\n },\n view: {\n type: Object as PropType<MarkViewProps['view']>,\n required: true as const,\n },\n updateAttributes: {\n type: Function as PropType<MarkViewProps['updateAttributes']>,\n required: true as const,\n },\n HTMLAttributes: {\n type: Object as PropType<MarkViewProps['HTMLAttributes']>,\n required: true as const,\n },\n}\n\nexport const MarkViewContent = defineComponent({\n name: 'MarkViewContent',\n\n props: {\n as: {\n type: String,\n default: 'span',\n },\n },\n\n render() {\n return h(this.as, {\n style: {\n whiteSpace: 'inherit',\n },\n 'data-mark-view-content': '',\n })\n },\n})\n\nexport class VueMarkView extends MarkView<Component, VueMarkViewRendererOptions> {\n renderer: VueRenderer\n\n constructor(component: Component, props: MarkViewProps, options?: Partial<VueMarkViewRendererOptions>) {\n super(component, props, options)\n\n const componentProps = { ...props, updateAttributes: this.updateAttributes.bind(this) } satisfies MarkViewProps\n\n // Create extended component with provide\n const extendedComponent = defineComponent({\n extends: { ...component },\n props: Object.keys(componentProps),\n template: (this.component as any).template,\n setup: reactiveProps => {\n return (component as any).setup?.(reactiveProps, {\n expose: () => undefined,\n })\n },\n // Add support for scoped styles\n __scopeId: (component as any).__scopeId,\n __cssModules: (component as any).__cssModules,\n __name: (component as any).__name,\n __file: (component as any).__file,\n })\n this.renderer = new VueRenderer(extendedComponent, {\n editor: this.editor,\n props: componentProps,\n })\n }\n\n get dom() {\n return this.renderer.element as HTMLElement\n }\n\n get contentDOM() {\n return this.dom.querySelector('[data-mark-view-content]') as HTMLElement | null\n }\n\n updateAttributes(attrs: Record<string, any>): void {\n // since this.mark is now an proxy, we need to get the actual mark from it\n const unproxiedMark = toRaw(this.mark)\n super.updateAttributes(attrs, unproxiedMark)\n }\n\n destroy() {\n this.renderer.destroy()\n }\n}\n\nexport function VueMarkViewRenderer(\n component: Component,\n options: Partial<VueMarkViewRendererOptions> = {},\n): MarkViewRenderer {\n return props => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {} as unknown as MarkView<any, any>\n }\n\n return new VueMarkView(component, props, options)\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport type { Component, DefineComponent } from 'vue'\nimport { h, markRaw, reactive, render } from 'vue'\n\nimport type { Editor as ExtendedEditor } from './Editor.js'\n\nexport interface VueRendererOptions {\n editor: Editor\n props?: Record<string, any>\n}\n\ntype ExtendedVNode = ReturnType<typeof h> | null\n\ninterface RenderedComponent {\n vNode: ExtendedVNode\n destroy: () => void\n el: Element | null\n}\n\n/**\n * This class is used to render Vue components inside the editor.\n */\nexport class VueRenderer {\n renderedComponent!: RenderedComponent\n\n editor: ExtendedEditor\n\n component: Component\n\n el: Element | null\n\n props: Record<string, any>\n\n /**\n * Flag to track if the renderer has been destroyed, preventing queued or asynchronous renders from executing after teardown.\n */\n destroyed = false\n\n constructor(component: Component, { props = {}, editor }: VueRendererOptions) {\n this.editor = editor as ExtendedEditor\n this.component = markRaw(component)\n this.el = document.createElement('div')\n this.props = reactive(props)\n this.renderedComponent = this.renderComponent()\n }\n\n get element(): Element | null {\n return this.renderedComponent.el\n }\n\n get ref(): any {\n // Composition API\n if (this.renderedComponent.vNode?.component?.exposed) {\n return this.renderedComponent.vNode.component.exposed\n }\n // Option API\n return this.renderedComponent.vNode?.component?.proxy\n }\n\n renderComponent() {\n if (this.destroyed) {\n return this.renderedComponent\n }\n\n let vNode: ExtendedVNode = h(this.component as DefineComponent, this.props)\n\n if (this.editor.appContext) {\n vNode.appContext = this.editor.appContext\n }\n if (typeof document !== 'undefined' && this.el) {\n render(vNode, this.el)\n }\n\n const destroy = () => {\n if (this.el) {\n render(null, this.el)\n }\n this.el = null\n vNode = null\n }\n\n return { vNode, destroy, el: this.el ? this.el.firstElementChild : null }\n }\n\n updateProps(props: Record<string, any> = {}): void {\n if (this.destroyed) {\n return\n }\n\n Object.entries(props).forEach(([key, value]) => {\n this.props[key] = value\n })\n this.renderComponent()\n }\n\n destroy(): void {\n if (this.destroyed) {\n return\n }\n\n this.destroyed = true\n this.renderedComponent.destroy()\n }\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'\nimport { cancelPositionCheck, isNodeViewSelected, NodeView, schedulePositionCheck } from '@tiptap/core'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport type { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'\nimport type { Component, PropType, Ref } from 'vue'\nimport { defineComponent, provide, ref } from 'vue'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport const nodeViewProps = {\n editor: {\n type: Object as PropType<NodeViewProps['editor']>,\n required: true as const,\n },\n node: {\n type: Object as PropType<NodeViewProps['node']>,\n required: true as const,\n },\n decorations: {\n type: Object as PropType<NodeViewProps['decorations']>,\n required: true as const,\n },\n selected: {\n type: Boolean as PropType<NodeViewProps['selected']>,\n required: true as const,\n },\n extension: {\n type: Object as PropType<NodeViewProps['extension']>,\n required: true as const,\n },\n getPos: {\n type: Function as PropType<NodeViewProps['getPos']>,\n required: true as const,\n },\n updateAttributes: {\n type: Function as PropType<NodeViewProps['updateAttributes']>,\n required: true as const,\n },\n deleteNode: {\n type: Function as PropType<NodeViewProps['deleteNode']>,\n required: true as const,\n },\n view: {\n type: Object as PropType<NodeViewProps['view']>,\n required: true as const,\n },\n innerDecorations: {\n type: Object as PropType<NodeViewProps['innerDecorations']>,\n required: true as const,\n },\n HTMLAttributes: {\n type: Object as PropType<NodeViewProps['HTMLAttributes']>,\n required: true as const,\n },\n}\n\nexport interface VueNodeViewRendererOptions extends NodeViewRendererOptions {\n update:\n | ((props: {\n oldNode: ProseMirrorNode\n oldDecorations: readonly Decoration[]\n oldInnerDecorations: DecorationSource\n newNode: ProseMirrorNode\n newDecorations: readonly Decoration[]\n innerDecorations: DecorationSource\n updateProps: () => void\n }) => boolean)\n | null\n}\n\nclass VueNodeView extends NodeView<Component, Editor, VueNodeViewRendererOptions> {\n renderer!: VueRenderer\n\n decorationClasses!: Ref<string>\n\n /**\n * The last known position of this node view, used to detect position-only\n * changes that don't produce a new node object reference.\n */\n private currentPos: number | undefined\n\n /**\n * Callback registered with the per-editor position-update registry.\n * Stored so it can be unregistered in destroy().\n */\n private positionCheckCallback: (() => void) | null = null\n\n private cachedExtensionWithSyncedStorage: NodeViewProps['extension'] | null = null\n\n /**\n * Returns a proxy of the extension that redirects storage access to the editor's mutable storage.\n * This preserves the original prototype chain (instanceof checks, methods like configure/extend work).\n * Cached to avoid proxy creation on every update.\n */\n get extensionWithSyncedStorage(): NodeViewProps['extension'] {\n if (!this.cachedExtensionWithSyncedStorage) {\n const editor = this.editor\n const extension = this.extension\n\n this.cachedExtensionWithSyncedStorage = new Proxy(extension, {\n get(target, prop, receiver) {\n if (prop === 'storage') {\n return editor.storage[extension.name as keyof typeof editor.storage] ?? {}\n }\n return Reflect.get(target, prop, receiver)\n },\n })\n }\n\n return this.cachedExtensionWithSyncedStorage\n }\n\n mount() {\n const props = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations as DecorationWithType[],\n innerDecorations: this.innerDecorations,\n view: this.view,\n selected: false,\n extension: this.extensionWithSyncedStorage,\n HTMLAttributes: this.HTMLAttributes,\n getPos: () => this.getPos(),\n updateAttributes: (attributes = {}) => this.updateAttributes(attributes),\n deleteNode: () => this.deleteNode(),\n } satisfies NodeViewProps\n\n const onDragStart = this.onDragStart.bind(this)\n\n this.decorationClasses = ref(this.getDecorationClasses())\n\n const extendedComponent = defineComponent({\n extends: { ...this.component },\n props: Object.keys(props),\n template: (this.component as any).template,\n setup: reactiveProps => {\n provide('onDragStart', onDragStart)\n provide('decorationClasses', this.decorationClasses)\n\n return (this.component as any).setup?.(reactiveProps, {\n expose: () => undefined,\n })\n },\n // add support for scoped styles\n // @ts-ignore\n // eslint-disable-next-line\n __scopeId: this.component.__scopeId,\n // add support for CSS Modules\n // @ts-ignore\n // eslint-disable-next-line\n __cssModules: this.component.__cssModules,\n // add support for vue devtools\n // @ts-ignore\n // eslint-disable-next-line\n __name: this.component.__name,\n // @ts-ignore\n // eslint-disable-next-line\n __file: this.component.__file,\n })\n\n this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this)\n this.editor.on('selectionUpdate', this.handleSelectionUpdate)\n this.currentPos = this.getPos()\n\n this.positionCheckCallback = () => {\n // Guard against the callback firing before the renderer is fully initialized.\n if (!this.renderer) {\n return\n }\n\n const newPos = this.getPos()\n\n if (typeof newPos !== 'number' || newPos === this.currentPos) {\n return\n }\n\n this.currentPos = newPos\n\n // Pass a fresh getPos reference so Vue's reactivity detects a prop change.\n this.renderer.updateProps({ getPos: () => this.getPos() })\n }\n\n schedulePositionCheck(this.editor, this.positionCheckCallback)\n\n this.renderer = new VueRenderer(extendedComponent, {\n editor: this.editor,\n props,\n })\n }\n\n /**\n * Return the DOM element.\n * This is the element that will be used to display the node view.\n */\n get dom() {\n if (!this.renderer.element || !this.renderer.element.hasAttribute('data-node-view-wrapper')) {\n throw Error('Please use the NodeViewWrapper component for your node view.')\n }\n\n return this.renderer.element as HTMLElement\n }\n\n /**\n * Return the content DOM element.\n * This is the element that will be used to display the rich-text content of the node.\n */\n get contentDOM() {\n if (this.node.isLeaf) {\n return null\n }\n\n return this.dom.querySelector('[data-node-view-content]') as HTMLElement | null\n }\n\n /**\n * On editor selection update, check if the node is selected.\n * If it is, call `selectNode`, otherwise call `deselectNode`.\n */\n handleSelectionUpdate() {\n const pos = this.getPos()\n\n if (typeof pos !== 'number') {\n return\n }\n\n const isSelected = isNodeViewSelected({\n selection: this.editor.state.selection,\n pos,\n nodeSize: this.node.nodeSize,\n selectedOnTextSelection: this.options.selectedOnTextSelection,\n })\n\n if (isSelected) {\n if (this.renderer.props.selected) {\n return\n }\n\n this.selectNode()\n } else {\n if (!this.renderer.props.selected) {\n return\n }\n\n this.deselectNode()\n }\n }\n\n /**\n * On update, update the React component.\n * To prevent unnecessary updates, the `update` option can be used.\n */\n update(node: ProseMirrorNode, decorations: readonly Decoration[], innerDecorations: DecorationSource): boolean {\n const rerenderComponent = (props?: Record<string, any>) => {\n this.decorationClasses.value = this.getDecorationClasses()\n this.renderer.updateProps(props)\n }\n\n if (typeof this.options.update === 'function') {\n const oldNode = this.node\n const oldDecorations = this.decorations\n const oldInnerDecorations = this.innerDecorations\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n this.currentPos = this.getPos()\n\n return this.options.update({\n oldNode,\n oldDecorations,\n newNode: node,\n newDecorations: decorations,\n oldInnerDecorations,\n innerDecorations,\n updateProps: () =>\n rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage }),\n })\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n const newPos = this.getPos()\n\n if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {\n if (newPos === this.currentPos) {\n return true\n }\n\n // Position changed without a content/decoration change — trigger re-render\n // so the component receives an up-to-date value from getPos().\n // Pass a fresh getPos reference so Vue's reactivity detects a prop change.\n this.currentPos = newPos\n rerenderComponent({\n node,\n decorations,\n innerDecorations,\n extension: this.extensionWithSyncedStorage,\n getPos: () => this.getPos(),\n })\n return true\n }\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n this.currentPos = newPos\n\n rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage })\n\n return true\n }\n\n /**\n * Select the node.\n * Add the `selected` prop and the `ProseMirror-selectednode` class.\n */\n selectNode() {\n this.renderer.updateProps({\n selected: true,\n })\n if (this.renderer.element) {\n this.renderer.element.classList.add('ProseMirror-selectednode')\n }\n }\n\n /**\n * Deselect the node.\n * Remove the `selected` prop and the `ProseMirror-selectednode` class.\n */\n deselectNode() {\n this.renderer.updateProps({\n selected: false,\n })\n if (this.renderer.element) {\n this.renderer.element.classList.remove('ProseMirror-selectednode')\n }\n }\n\n getDecorationClasses() {\n return (\n this.decorations\n // @ts-ignore\n .flatMap(item => item.type.attrs.class)\n .join(' ')\n )\n }\n\n destroy() {\n this.renderer.destroy()\n this.editor.off('selectionUpdate', this.handleSelectionUpdate)\n\n if (this.positionCheckCallback) {\n cancelPositionCheck(this.editor, this.positionCheckCallback)\n this.positionCheckCallback = null\n }\n }\n}\n\nexport function VueNodeViewRenderer(\n component: Component<NodeViewProps>,\n options?: Partial<VueNodeViewRendererOptions>,\n): NodeViewRenderer {\n return props => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {} as unknown as ProseMirrorNodeView\n }\n // check for class-component and normalize if neccessary\n const normalizedComponent =\n typeof component === 'function' && '__vccOpts' in component ? (component.__vccOpts as Component) : component\n\n return new VueNodeView(normalizedComponent, props, options)\n }\n}\n","export { Editor } from './Editor.js'\nexport * from './EditorContent.js'\nexport * from './NodeViewContent.js'\nexport * from './NodeViewWrapper.js'\nexport * from './useEditor.js'\nexport * from './VueMarkViewRenderer.js'\nexport * from './VueNodeViewRenderer.js'\nexport * from './VueRenderer.js'\nexport * from '@tiptap/core'\n"],"mappings":"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","names":["defineComponent","h","defineComponent","h","onBeforeUnmount","onBeforeUnmount","defineComponent","h","h","markRaw","defineComponent","h","defineComponent","ref","ref","defineComponent"]}
|
package/dist/menus/index.cjs
CHANGED
|
@@ -730,6 +730,10 @@ var FloatingMenuView = class {
|
|
|
730
730
|
}
|
|
731
731
|
}
|
|
732
732
|
updatePosition() {
|
|
733
|
+
var _a, _b;
|
|
734
|
+
if (!((_b = (_a = this.view) == null ? void 0 : _a.dom) == null ? void 0 : _b.parentNode)) {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
733
737
|
const { selection } = this.editor.state;
|
|
734
738
|
const domRect = (0, import_core2.posToDOMRect)(this.view, selection.from, selection.to);
|
|
735
739
|
const virtualElement = {
|
|
@@ -741,8 +745,8 @@ var FloatingMenuView = class {
|
|
|
741
745
|
strategy: this.floatingUIOptions.strategy,
|
|
742
746
|
middleware: this.middlewares
|
|
743
747
|
}).then(({ x, y, strategy, middlewareData }) => {
|
|
744
|
-
var
|
|
745
|
-
if (((
|
|
748
|
+
var _a2, _b2;
|
|
749
|
+
if (((_a2 = middlewareData.hide) == null ? void 0 : _a2.referenceHidden) || ((_b2 = middlewareData.hide) == null ? void 0 : _b2.escaped)) {
|
|
746
750
|
this.element.style.visibility = "hidden";
|
|
747
751
|
return;
|
|
748
752
|
}
|
package/dist/menus/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menus/index.ts","../../../extension-bubble-menu/src/bubble-menu-plugin.ts","../../src/menus/BubbleMenu.ts","../../../extension-floating-menu/src/floating-menu-plugin.ts","../../src/menus/FloatingMenu.ts"],"sourcesContent":["export * from './BubbleMenu.js'\nexport * from './FloatingMenu.js'\n","import {\n type Middleware,\n type VirtualElement,\n arrow,\n autoPlacement,\n computePosition,\n flip,\n hide,\n inline,\n offset,\n shift,\n size,\n} from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { isTextSelection, posToDOMRect } from '@tiptap/core'\nimport type { EditorState, PluginView, Transaction } from '@tiptap/pm/state'\nimport { NodeSelection, Plugin, PluginKey } from '@tiptap/pm/state'\nimport { CellSelection } from '@tiptap/pm/tables'\nimport type { EditorView } from '@tiptap/pm/view'\n\nfunction combineDOMRects(rect1: DOMRect, rect2: DOMRect): DOMRect {\n const top = Math.min(rect1.top, rect2.top)\n const bottom = Math.max(rect1.bottom, rect2.bottom)\n const left = Math.min(rect1.left, rect2.left)\n const right = Math.max(rect1.right, rect2.right)\n const width = right - left\n const height = bottom - top\n const x = left\n const y = top\n return new DOMRect(x, y, width, height)\n}\n\nexport interface BubbleMenuPluginProps {\n /**\n * The plugin key.\n * @type {PluginKey | string}\n * @default 'bubbleMenu'\n */\n pluginKey: PluginKey | string\n\n /**\n * The editor instance.\n */\n editor: Editor\n\n /**\n * The DOM element that contains your menu.\n * @type {HTMLElement}\n * @default null\n */\n element: HTMLElement\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 250\n */\n updateDelay?: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 60\n */\n resizeDelay?: number\n\n /**\n * A function that determines whether the menu should be shown or not.\n * If this function returns `false`, the menu will be hidden, otherwise it will be shown.\n */\n shouldShow?:\n | ((props: {\n editor: Editor\n element: HTMLElement\n view: EditorView\n state: EditorState\n oldState?: EditorState\n from: number\n to: number\n }) => boolean)\n | null\n\n /**\n * The DOM element to append your menu to. Default is the editor's parent element.\n *\n * Sometimes the menu needs to be appended to a different DOM context due to accessibility, clipping, or z-index issues.\n *\n * @type {HTMLElement}\n * @default null\n */\n appendTo?: HTMLElement | (() => HTMLElement)\n\n /**\n * A function that returns the virtual element for the menu.\n * This is useful when the menu needs to be positioned relative to a specific DOM element.\n * @type {() => VirtualElement | null}\n * @default Position based on the selection.\n */\n getReferencedVirtualElement?: () => VirtualElement | null\n\n /**\n * The options for the bubble menu. Those are passed to Floating UI and include options for the placement, offset, flip, shift, arrow, size, autoPlacement,\n * hide, and inline middlewares.\n * @default {}\n * @see https://floating-ui.com/docs/computePosition#options\n */\n options?: {\n strategy?: 'absolute' | 'fixed'\n placement?:\n | 'top'\n | 'right'\n | 'bottom'\n | 'left'\n | 'top-start'\n | 'top-end'\n | 'right-start'\n | 'right-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n offset?: Parameters<typeof offset>[0] | boolean\n flip?: Parameters<typeof flip>[0] | boolean\n shift?: Parameters<typeof shift>[0] | boolean\n arrow?: Parameters<typeof arrow>[0] | false\n size?: Parameters<typeof size>[0] | boolean\n autoPlacement?: Parameters<typeof autoPlacement>[0] | boolean\n hide?: Parameters<typeof hide>[0] | boolean\n inline?: Parameters<typeof inline>[0] | boolean\n\n onShow?: () => void\n onHide?: () => void\n onUpdate?: () => void\n onDestroy?: () => void\n\n /**\n * The scrollable element that should be listened to when updating the position of the bubble menu.\n * If not provided, the window will be used.\n * @type {HTMLElement | Window}\n */\n scrollTarget?: HTMLElement | Window\n }\n}\n\nexport type BubbleMenuViewProps = BubbleMenuPluginProps & {\n view: EditorView\n}\n\nexport class BubbleMenuView implements PluginView {\n public editor: Editor\n\n public element: HTMLElement\n\n public view: EditorView\n\n public preventHide = false\n\n public pluginKey: PluginKey | string\n\n public updateDelay: number\n\n public resizeDelay: number\n\n public appendTo: HTMLElement | (() => HTMLElement) | undefined\n\n public getReferencedVirtualElement: (() => VirtualElement | null) | undefined\n\n private updateDebounceTimer: number | undefined\n\n private resizeDebounceTimer: number | undefined\n\n private isVisible = false\n\n private scrollTarget: HTMLElement | Window = window\n\n private floatingUIOptions: NonNullable<BubbleMenuPluginProps['options']> = {\n strategy: 'absolute',\n placement: 'top',\n offset: 8,\n flip: {},\n shift: {},\n arrow: false,\n size: false,\n autoPlacement: false,\n hide: false,\n inline: false,\n onShow: undefined,\n onHide: undefined,\n onUpdate: undefined,\n onDestroy: undefined,\n }\n\n public shouldShow: Exclude<BubbleMenuPluginProps['shouldShow'], null> = ({ view, state, from, to }) => {\n const { doc, selection } = state\n const { empty } = selection\n\n // Sometime check for `empty` is not enough.\n // Doubleclick an empty paragraph returns a node size of 2.\n // So we check also for an empty text size.\n const isEmptyTextBlock = !doc.textBetween(from, to).length && isTextSelection(state.selection)\n\n // When clicking on a element inside the bubble menu the editor \"blur\" event\n // is called and the bubble menu item is focussed. In this case we should\n // consider the menu as part of the editor and keep showing the menu\n const isChildOfMenu = this.element.contains(document.activeElement)\n\n const hasEditorFocus = view.hasFocus() || isChildOfMenu\n\n if (!hasEditorFocus || empty || isEmptyTextBlock || !this.editor.isEditable) {\n return false\n }\n\n return true\n }\n\n get middlewares() {\n const middlewares: Middleware[] = []\n\n if (this.floatingUIOptions.flip) {\n middlewares.push(flip(typeof this.floatingUIOptions.flip !== 'boolean' ? this.floatingUIOptions.flip : undefined))\n }\n\n if (this.floatingUIOptions.shift) {\n middlewares.push(\n shift(typeof this.floatingUIOptions.shift !== 'boolean' ? this.floatingUIOptions.shift : undefined),\n )\n }\n\n if (this.floatingUIOptions.offset) {\n middlewares.push(\n offset(typeof this.floatingUIOptions.offset !== 'boolean' ? this.floatingUIOptions.offset : undefined),\n )\n }\n\n if (this.floatingUIOptions.arrow) {\n middlewares.push(arrow(this.floatingUIOptions.arrow))\n }\n\n if (this.floatingUIOptions.size) {\n middlewares.push(size(typeof this.floatingUIOptions.size !== 'boolean' ? this.floatingUIOptions.size : undefined))\n }\n\n if (this.floatingUIOptions.autoPlacement) {\n middlewares.push(\n autoPlacement(\n typeof this.floatingUIOptions.autoPlacement !== 'boolean' ? this.floatingUIOptions.autoPlacement : undefined,\n ),\n )\n }\n\n if (this.floatingUIOptions.hide) {\n middlewares.push(hide(typeof this.floatingUIOptions.hide !== 'boolean' ? this.floatingUIOptions.hide : undefined))\n }\n\n if (this.floatingUIOptions.inline) {\n middlewares.push(\n inline(typeof this.floatingUIOptions.inline !== 'boolean' ? this.floatingUIOptions.inline : undefined),\n )\n }\n\n return middlewares\n }\n\n private get virtualElement(): VirtualElement | undefined {\n const { selection } = this.editor.state\n\n const referencedVirtualElement = this.getReferencedVirtualElement?.()\n if (referencedVirtualElement) {\n return referencedVirtualElement\n }\n\n if (!this.view?.dom?.parentNode) {\n return\n }\n\n const domRect = posToDOMRect(this.view, selection.from, selection.to)\n let virtualElement = {\n getBoundingClientRect: () => domRect,\n getClientRects: () => [domRect],\n }\n\n if (selection instanceof NodeSelection) {\n let node = this.view.nodeDOM(selection.from) as HTMLElement\n\n const nodeViewWrapper = node.dataset.nodeViewWrapper ? node : node.querySelector('[data-node-view-wrapper]')\n\n if (nodeViewWrapper) {\n node = nodeViewWrapper as HTMLElement\n }\n\n if (node) {\n virtualElement = {\n getBoundingClientRect: () => node.getBoundingClientRect(),\n getClientRects: () => [node.getBoundingClientRect()],\n }\n }\n }\n\n // this is a special case for cell selections\n if (selection instanceof CellSelection) {\n const { $anchorCell, $headCell } = selection\n\n const from = $anchorCell ? $anchorCell.pos : $headCell!.pos\n const to = $headCell ? $headCell.pos : $anchorCell!.pos\n\n const fromDOM = this.view.nodeDOM(from)\n const toDOM = this.view.nodeDOM(to)\n\n if (!fromDOM || !toDOM) {\n return\n }\n\n const clientRect =\n fromDOM === toDOM\n ? (fromDOM as HTMLElement).getBoundingClientRect()\n : combineDOMRects(\n (fromDOM as HTMLElement).getBoundingClientRect(),\n (toDOM as HTMLElement).getBoundingClientRect(),\n )\n\n virtualElement = {\n getBoundingClientRect: () => clientRect,\n getClientRects: () => [clientRect],\n }\n }\n\n return virtualElement\n }\n\n constructor({\n editor,\n element,\n view,\n pluginKey = 'bubbleMenu',\n updateDelay = 250,\n resizeDelay = 60,\n shouldShow,\n appendTo,\n getReferencedVirtualElement,\n options,\n }: BubbleMenuViewProps) {\n this.editor = editor\n this.element = element\n this.view = view\n this.pluginKey = pluginKey\n this.updateDelay = updateDelay\n this.resizeDelay = resizeDelay\n this.appendTo = appendTo\n this.scrollTarget = options?.scrollTarget ?? window\n this.getReferencedVirtualElement = getReferencedVirtualElement\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...options,\n }\n\n this.element.tabIndex = 0\n\n if (shouldShow) {\n this.shouldShow = shouldShow\n }\n\n this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.addEventListener('dragstart', this.dragstartHandler)\n this.editor.on('focus', this.focusHandler)\n this.editor.on('blur', this.blurHandler)\n this.editor.on('transaction', this.transactionHandler)\n window.addEventListener('resize', this.resizeHandler)\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n\n this.update(view, view.state)\n\n if (this.getShouldShow()) {\n this.show()\n this.updatePosition()\n }\n }\n\n mousedownHandler = () => {\n this.preventHide = true\n }\n\n dragstartHandler = () => {\n this.hide()\n }\n\n /**\n * Handles the window resize event to update the position of the bubble menu.\n * It uses a debounce mechanism to prevent excessive updates.\n * The delay is defined by the `resizeDelay` property.\n */\n resizeHandler = () => {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer)\n }\n\n this.resizeDebounceTimer = window.setTimeout(() => {\n this.updatePosition()\n }, this.resizeDelay)\n }\n\n focusHandler = () => {\n // we use `setTimeout` to make sure `selection` is already updated\n setTimeout(() => this.update(this.editor.view))\n }\n\n blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.editor.isDestroyed) {\n this.destroy()\n return\n }\n\n if (this.preventHide) {\n this.preventHide = false\n\n return\n }\n\n if (event?.relatedTarget && this.element.parentNode?.contains(event.relatedTarget as Node)) {\n return\n }\n\n if (event?.relatedTarget === this.editor.view.dom) {\n return\n }\n\n this.hide()\n }\n\n updatePosition() {\n if (!this.isVisible) {\n return\n }\n\n const virtualElement = this.virtualElement\n\n if (!virtualElement) {\n return\n }\n\n computePosition(virtualElement, this.element, {\n placement: this.floatingUIOptions.placement,\n strategy: this.floatingUIOptions.strategy,\n middleware: this.middlewares,\n }).then(({ x, y, strategy, middlewareData }) => {\n if (!this.isVisible || this.editor.isDestroyed || !this.element.isConnected) {\n return\n }\n\n // Handle hide middleware - hide element if reference is hidden or element has escaped\n if (middlewareData.hide?.referenceHidden || middlewareData.hide?.escaped) {\n this.element.style.visibility = 'hidden'\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.width = 'max-content'\n this.element.style.position = strategy\n this.element.style.left = `${x}px`\n this.element.style.top = `${y}px`\n\n if (this.isVisible && this.floatingUIOptions.onUpdate) {\n this.floatingUIOptions.onUpdate()\n }\n })\n }\n\n update(view: EditorView, oldState?: EditorState) {\n const { state } = view\n const hasValidSelection = state.selection.from !== state.selection.to\n\n if (this.updateDelay > 0 && hasValidSelection) {\n this.handleDebouncedUpdate(view, oldState)\n return\n }\n\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }\n\n handleDebouncedUpdate = (view: EditorView, oldState?: EditorState) => {\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n if (!selectionChanged && !docChanged) {\n return\n }\n\n if (this.updateDebounceTimer) {\n clearTimeout(this.updateDebounceTimer)\n }\n\n this.updateDebounceTimer = window.setTimeout(() => {\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }, this.updateDelay)\n }\n\n getShouldShow(oldState?: EditorState) {\n const { state } = this.view\n const { selection } = state\n\n // support for CellSelections\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n\n const shouldShow = this.shouldShow?.({\n editor: this.editor,\n element: this.element,\n view: this.view,\n state,\n oldState,\n from,\n to,\n })\n\n return shouldShow || false\n }\n\n updateHandler = (view: EditorView, selectionChanged: boolean, docChanged: boolean, oldState?: EditorState) => {\n const { composing } = view\n\n const isSame = !selectionChanged && !docChanged\n\n if (composing || isSame) {\n return\n }\n\n const shouldShow = this.getShouldShow(oldState)\n\n if (!shouldShow) {\n this.hide()\n\n return\n }\n\n this.show()\n this.updatePosition()\n }\n\n show() {\n if (this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.opacity = '1'\n\n // attach to appendTo or editor's parent element\n const appendToElement = typeof this.appendTo === 'function' ? this.appendTo() : this.appendTo\n ;(appendToElement ?? this.view.dom.parentElement)?.appendChild(this.element)\n\n if (this.floatingUIOptions.onShow) {\n this.floatingUIOptions.onShow()\n }\n\n this.isVisible = true\n }\n\n hide() {\n if (!this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'hidden'\n this.element.style.opacity = '0'\n // remove from the parent element\n this.element.remove()\n\n if (this.floatingUIOptions.onHide) {\n this.floatingUIOptions.onHide()\n }\n\n this.isVisible = false\n }\n\n /**\n * Handles the transaction event to update the position of the bubble menu.\n * This allows external code to trigger a position update via:\n * `editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'updatePosition'))`\n * The `pluginKey` defaults to `bubbleMenu`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta(this.pluginKey)\n if (meta === 'updatePosition') {\n this.updatePosition()\n } else if (meta && typeof meta === 'object' && meta.type === 'updateOptions') {\n this.updateOptions(meta.options)\n } else if (meta === 'hide') {\n this.hide()\n } else if (meta === 'show') {\n this.updatePosition()\n this.show()\n }\n }\n\n updateOptions(newProps: Partial<Omit<BubbleMenuPluginProps, 'editor' | 'element' | 'pluginKey'>>) {\n if (newProps.updateDelay !== undefined) {\n this.updateDelay = newProps.updateDelay\n }\n\n if (newProps.resizeDelay !== undefined) {\n this.resizeDelay = newProps.resizeDelay\n }\n\n if (newProps.appendTo !== undefined) {\n this.appendTo = newProps.appendTo\n }\n\n if (newProps.getReferencedVirtualElement !== undefined) {\n this.getReferencedVirtualElement = newProps.getReferencedVirtualElement\n }\n\n if (newProps.shouldShow !== undefined) {\n if (newProps.shouldShow) {\n this.shouldShow = newProps.shouldShow\n }\n }\n\n if (newProps.options !== undefined) {\n // Handle scrollTarget change - need to remove old listener and add new one\n // Use nullish coalescing to default to window when scrollTarget is undefined/null\n const newScrollTarget = newProps.options.scrollTarget ?? window\n\n if (newScrollTarget !== this.scrollTarget) {\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.scrollTarget = newScrollTarget\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n }\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...newProps.options,\n }\n }\n }\n\n destroy() {\n this.hide()\n this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.removeEventListener('dragstart', this.dragstartHandler)\n window.removeEventListener('resize', this.resizeHandler)\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.editor.off('focus', this.focusHandler)\n this.editor.off('blur', this.blurHandler)\n this.editor.off('transaction', this.transactionHandler)\n\n if (this.floatingUIOptions.onDestroy) {\n this.floatingUIOptions.onDestroy()\n }\n }\n}\n\nexport const BubbleMenuPlugin = (options: BubbleMenuPluginProps) => {\n return new Plugin({\n key: typeof options.pluginKey === 'string' ? new PluginKey(options.pluginKey) : options.pluginKey,\n view: view => new BubbleMenuView({ view, ...options }),\n })\n}\n","import type { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'\nimport { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { PropType } from 'vue'\nimport { defineComponent, h, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'\n\nexport const BubbleMenu = defineComponent({\n name: 'BubbleMenu',\n\n inheritAttrs: false,\n\n props: {\n pluginKey: {\n type: [String, Object] as PropType<BubbleMenuPluginProps['pluginKey']>,\n default: undefined,\n },\n\n editor: {\n type: Object as PropType<BubbleMenuPluginProps['editor']>,\n required: true,\n },\n\n updateDelay: {\n type: Number as PropType<BubbleMenuPluginProps['updateDelay']>,\n default: undefined,\n },\n\n resizeDelay: {\n type: Number as PropType<BubbleMenuPluginProps['resizeDelay']>,\n default: undefined,\n },\n\n options: {\n type: Object as PropType<BubbleMenuPluginProps['options']>,\n default: () => ({}),\n },\n\n appendTo: {\n type: [Object, Function] as PropType<BubbleMenuPluginProps['appendTo']>,\n default: undefined,\n },\n\n shouldShow: {\n type: Function as PropType<Exclude<Required<BubbleMenuPluginProps>['shouldShow'], null>>,\n default: null,\n },\n\n getReferencedVirtualElement: {\n type: Function as PropType<Exclude<Required<BubbleMenuPluginProps>['getReferencedVirtualElement'], null>>,\n default: undefined,\n },\n },\n\n setup(props, { slots, attrs }) {\n const root = ref<HTMLElement | null>(null)\n const resolvedPluginKey = props.pluginKey ?? new PluginKey('bubbleMenu')\n\n onMounted(() => {\n const { editor, options, resizeDelay, appendTo, shouldShow, getReferencedVirtualElement, updateDelay } = props\n\n const el = root.value\n\n if (!el) {\n return\n }\n\n el.style.visibility = 'hidden'\n el.style.position = 'absolute'\n\n // Remove element from DOM; plugin will re-parent it when shown\n el.remove()\n\n nextTick(() => {\n editor.registerPlugin(\n BubbleMenuPlugin({\n editor,\n element: el,\n options,\n pluginKey: resolvedPluginKey,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n }),\n )\n })\n })\n\n onBeforeUnmount(() => {\n const { editor } = props\n\n editor.unregisterPlugin(resolvedPluginKey)\n })\n\n // Vue owns this element; attrs are applied reactively by Vue\n // Plugin re-parents it when showing the menu\n return () => h('div', { ref: root, ...attrs }, slots.default?.())\n },\n})\n","import {\n type Middleware,\n arrow,\n autoPlacement,\n computePosition,\n flip,\n hide,\n inline,\n offset,\n shift,\n size,\n} from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { getText, getTextSerializersFromSchema, posToDOMRect } from '@tiptap/core'\nimport type { Node as ProsemirrorNode } from '@tiptap/pm/model'\nimport type { EditorState, Transaction } from '@tiptap/pm/state'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\n\nexport interface FloatingMenuPluginProps {\n /**\n * The plugin key for the floating menu.\n * @default 'floatingMenu'\n */\n pluginKey: PluginKey | string\n\n /**\n * The editor instance.\n * @default null\n */\n editor: Editor\n\n /**\n * The DOM element that contains your menu.\n * @default null\n */\n element: HTMLElement\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 250\n */\n updateDelay?: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 60\n */\n resizeDelay?: number\n\n /**\n * The DOM element to append your menu to. Default is the editor's parent element.\n *\n * Sometimes the menu needs to be appended to a different DOM context due to accessibility, clipping, or z-index issues.\n *\n * @type {HTMLElement}\n * @default null\n */\n appendTo?: HTMLElement | (() => HTMLElement)\n\n /**\n * A function that determines whether the menu should be shown or not.\n * If this function returns `false`, the menu will be hidden, otherwise it will be shown.\n */\n shouldShow?:\n | ((props: {\n editor: Editor\n view: EditorView\n state: EditorState\n oldState?: EditorState\n from: number\n to: number\n }) => boolean)\n | null\n\n /**\n * The options for the floating menu. Those are passed to Floating UI and include options for the placement, offset, flip, shift, arrow, size, autoPlacement,\n * hide, and inline middlewares.\n * @default {}\n * @see https://floating-ui.com/docs/computePosition#options\n */\n options?: {\n strategy?: 'absolute' | 'fixed'\n placement?:\n | 'top'\n | 'right'\n | 'bottom'\n | 'left'\n | 'top-start'\n | 'top-end'\n | 'right-start'\n | 'right-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n offset?: Parameters<typeof offset>[0] | boolean\n flip?: Parameters<typeof flip>[0] | boolean\n shift?: Parameters<typeof shift>[0] | boolean\n arrow?: Parameters<typeof arrow>[0] | false\n size?: Parameters<typeof size>[0] | boolean\n autoPlacement?: Parameters<typeof autoPlacement>[0] | boolean\n hide?: Parameters<typeof hide>[0] | boolean\n inline?: Parameters<typeof inline>[0] | boolean\n\n onShow?: () => void\n onHide?: () => void\n onUpdate?: () => void\n onDestroy?: () => void\n\n /**\n * The scrollable element that should be listened to when updating the position of the floating menu.\n * If not provided, the window will be used.\n * @type {HTMLElement | Window}\n */\n scrollTarget?: HTMLElement | Window\n }\n}\n\nexport type FloatingMenuViewProps = FloatingMenuPluginProps & {\n /**\n * The editor view.\n */\n view: EditorView\n}\n\nexport class FloatingMenuView {\n public editor: Editor\n\n public element: HTMLElement\n\n public view: EditorView\n\n public preventHide = false\n\n public pluginKey: PluginKey | string\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * @default 250\n */\n public updateDelay: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * @default 60\n */\n public resizeDelay: number\n\n public appendTo: HTMLElement | (() => HTMLElement) | undefined\n\n private updateDebounceTimer: number | undefined\n\n private resizeDebounceTimer: number | undefined\n\n private isVisible = false\n\n private scrollTarget: HTMLElement | Window = window\n\n private getTextContent(node: ProsemirrorNode) {\n return getText(node, { textSerializers: getTextSerializersFromSchema(this.editor.schema) })\n }\n\n public shouldShow: Exclude<FloatingMenuPluginProps['shouldShow'], null> = ({ view, state }) => {\n const { selection } = state\n const { $anchor, empty } = selection\n const isRootDepth = $anchor.depth === 1\n\n const isEmptyTextBlock =\n $anchor.parent.isTextblock &&\n !$anchor.parent.type.spec.code &&\n !$anchor.parent.textContent &&\n $anchor.parent.childCount === 0 &&\n !this.getTextContent($anchor.parent)\n\n if (!view.hasFocus() || !empty || !isRootDepth || !isEmptyTextBlock || !this.editor.isEditable) {\n return false\n }\n\n return true\n }\n\n private floatingUIOptions: NonNullable<FloatingMenuPluginProps['options']> = {\n strategy: 'absolute',\n placement: 'right',\n offset: 8,\n flip: {},\n shift: {},\n arrow: false,\n size: false,\n autoPlacement: false,\n hide: false,\n inline: false,\n }\n\n get middlewares() {\n const middlewares: Middleware[] = []\n\n if (this.floatingUIOptions.flip) {\n middlewares.push(flip(typeof this.floatingUIOptions.flip !== 'boolean' ? this.floatingUIOptions.flip : undefined))\n }\n\n if (this.floatingUIOptions.shift) {\n middlewares.push(\n shift(typeof this.floatingUIOptions.shift !== 'boolean' ? this.floatingUIOptions.shift : undefined),\n )\n }\n\n if (this.floatingUIOptions.offset) {\n middlewares.push(\n offset(typeof this.floatingUIOptions.offset !== 'boolean' ? this.floatingUIOptions.offset : undefined),\n )\n }\n\n if (this.floatingUIOptions.arrow) {\n middlewares.push(arrow(this.floatingUIOptions.arrow))\n }\n\n if (this.floatingUIOptions.size) {\n middlewares.push(size(typeof this.floatingUIOptions.size !== 'boolean' ? this.floatingUIOptions.size : undefined))\n }\n\n if (this.floatingUIOptions.autoPlacement) {\n middlewares.push(\n autoPlacement(\n typeof this.floatingUIOptions.autoPlacement !== 'boolean' ? this.floatingUIOptions.autoPlacement : undefined,\n ),\n )\n }\n\n if (this.floatingUIOptions.hide) {\n middlewares.push(hide(typeof this.floatingUIOptions.hide !== 'boolean' ? this.floatingUIOptions.hide : undefined))\n }\n\n if (this.floatingUIOptions.inline) {\n middlewares.push(\n inline(typeof this.floatingUIOptions.inline !== 'boolean' ? this.floatingUIOptions.inline : undefined),\n )\n }\n\n return middlewares\n }\n\n constructor({\n editor,\n element,\n view,\n pluginKey = 'floatingMenu',\n updateDelay = 250,\n resizeDelay = 60,\n options,\n appendTo,\n shouldShow,\n }: FloatingMenuViewProps) {\n this.editor = editor\n this.element = element\n this.view = view\n this.pluginKey = pluginKey\n this.updateDelay = updateDelay\n this.resizeDelay = resizeDelay\n this.appendTo = appendTo\n this.scrollTarget = options?.scrollTarget ?? window\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...options,\n }\n\n this.element.tabIndex = 0\n\n if (shouldShow) {\n this.shouldShow = shouldShow\n }\n\n this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.editor.on('focus', this.focusHandler)\n this.editor.on('blur', this.blurHandler)\n this.editor.on('transaction', this.transactionHandler)\n window.addEventListener('resize', this.resizeHandler)\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n\n this.update(view, view.state)\n\n if (this.getShouldShow()) {\n this.show()\n this.updatePosition()\n }\n }\n\n getShouldShow(oldState?: EditorState) {\n const { state } = this.view\n const { selection } = state\n\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n\n const shouldShow = this.shouldShow?.({\n editor: this.editor,\n view: this.view,\n state,\n oldState,\n from,\n to,\n })\n\n return shouldShow\n }\n\n updateHandler = (view: EditorView, selectionChanged: boolean, docChanged: boolean, oldState?: EditorState) => {\n const { composing } = view\n\n const isSame = !selectionChanged && !docChanged\n\n if (composing || isSame) {\n return\n }\n\n const shouldShow = this.getShouldShow(oldState)\n\n if (!shouldShow) {\n this.hide()\n\n return\n }\n\n this.updatePosition()\n this.show()\n }\n\n mousedownHandler = () => {\n this.preventHide = true\n }\n\n focusHandler = () => {\n // we use `setTimeout` to make sure `selection` is already updated\n setTimeout(() => this.update(this.editor.view))\n }\n\n blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.preventHide) {\n this.preventHide = false\n\n return\n }\n\n if (event?.relatedTarget && this.element.parentNode?.contains(event.relatedTarget as Node)) {\n return\n }\n\n if (event?.relatedTarget === this.editor.view.dom) {\n return\n }\n\n this.hide()\n }\n\n /**\n * Handles the transaction event to update the position of the floating menu.\n * This allows external code to trigger a position update via:\n * `editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'updatePosition'))`\n * The `pluginKey` defaults to `floatingMenu`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta(this.pluginKey)\n if (meta === 'updatePosition') {\n this.updatePosition()\n } else if (meta && typeof meta === 'object' && meta.type === 'updateOptions') {\n this.updateOptions(meta.options)\n } else if (meta === 'hide') {\n this.hide()\n } else if (meta === 'show') {\n this.updatePosition()\n this.show()\n }\n }\n\n updateOptions(newProps: Partial<Omit<FloatingMenuPluginProps, 'editor' | 'element' | 'pluginKey'>>) {\n if (newProps.updateDelay !== undefined) {\n this.updateDelay = newProps.updateDelay\n }\n\n if (newProps.resizeDelay !== undefined) {\n this.resizeDelay = newProps.resizeDelay\n }\n\n if (newProps.appendTo !== undefined) {\n this.appendTo = newProps.appendTo\n }\n\n if (newProps.shouldShow !== undefined) {\n if (newProps.shouldShow) {\n this.shouldShow = newProps.shouldShow\n }\n }\n\n if (newProps.options !== undefined) {\n // Handle scrollTarget change - need to remove old listener and add new one\n // Use nullish coalescing to default to window when scrollTarget is undefined/null\n const newScrollTarget = newProps.options.scrollTarget ?? window\n\n if (newScrollTarget !== this.scrollTarget) {\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.scrollTarget = newScrollTarget\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n }\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...newProps.options,\n }\n }\n }\n\n /**\n * Handles the window resize event to update the position of the floating menu.\n * It uses a debounce mechanism to prevent excessive updates.\n * The delay is defined by the `resizeDelay` property.\n */\n resizeHandler = () => {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer)\n }\n\n this.resizeDebounceTimer = window.setTimeout(() => {\n this.updatePosition()\n }, this.resizeDelay)\n }\n\n updatePosition() {\n const { selection } = this.editor.state\n\n const domRect = posToDOMRect(this.view, selection.from, selection.to)\n\n const virtualElement = {\n getBoundingClientRect: () => domRect,\n getClientRects: () => [domRect],\n }\n\n computePosition(virtualElement, this.element, {\n placement: this.floatingUIOptions.placement,\n strategy: this.floatingUIOptions.strategy,\n middleware: this.middlewares,\n }).then(({ x, y, strategy, middlewareData }) => {\n // Handle hide middleware - hide element if reference is hidden or element has escaped\n if (middlewareData.hide?.referenceHidden || middlewareData.hide?.escaped) {\n this.element.style.visibility = 'hidden'\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.width = 'max-content'\n this.element.style.position = strategy\n this.element.style.left = `${x}px`\n this.element.style.top = `${y}px`\n\n if (this.isVisible && this.floatingUIOptions.onUpdate) {\n this.floatingUIOptions.onUpdate()\n }\n })\n }\n\n update(view: EditorView, oldState?: EditorState) {\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }\n\n show() {\n if (this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.opacity = '1'\n\n // attach to appendTo or editor's parent element\n const appendToElement = typeof this.appendTo === 'function' ? this.appendTo() : this.appendTo\n ;(appendToElement ?? this.view.dom.parentElement)?.appendChild(this.element)\n\n if (this.floatingUIOptions.onShow) {\n this.floatingUIOptions.onShow()\n }\n\n this.isVisible = true\n }\n\n hide() {\n if (!this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'hidden'\n this.element.style.opacity = '0'\n // remove from the parent element\n this.element.remove()\n\n if (this.floatingUIOptions.onHide) {\n this.floatingUIOptions.onHide()\n }\n\n this.isVisible = false\n }\n\n destroy() {\n this.hide()\n this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true })\n window.removeEventListener('resize', this.resizeHandler)\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.editor.off('focus', this.focusHandler)\n this.editor.off('blur', this.blurHandler)\n this.editor.off('transaction', this.transactionHandler)\n\n if (this.floatingUIOptions.onDestroy) {\n this.floatingUIOptions.onDestroy()\n }\n }\n}\n\nexport const FloatingMenuPlugin = (options: FloatingMenuPluginProps) => {\n return new Plugin({\n key: typeof options.pluginKey === 'string' ? new PluginKey(options.pluginKey) : options.pluginKey,\n view: view => new FloatingMenuView({ view, ...options }),\n })\n}\n","import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { PropType } from 'vue'\nimport { defineComponent, h, onBeforeUnmount, onMounted, ref } from 'vue'\n\nexport const FloatingMenu = defineComponent({\n name: 'FloatingMenu',\n\n inheritAttrs: false,\n\n props: {\n pluginKey: {\n // TODO: TypeScript breaks :(\n // type: [String, Object as PropType<Exclude<FloatingMenuPluginProps['pluginKey'], string>>],\n type: null,\n default: undefined,\n },\n\n editor: {\n type: Object as PropType<FloatingMenuPluginProps['editor']>,\n required: true,\n },\n\n updateDelay: {\n type: Number as PropType<FloatingMenuPluginProps['updateDelay']>,\n default: undefined,\n },\n\n resizeDelay: {\n type: Number as PropType<FloatingMenuPluginProps['resizeDelay']>,\n default: undefined,\n },\n\n options: {\n type: Object as PropType<FloatingMenuPluginProps['options']>,\n default: () => ({}),\n },\n\n appendTo: {\n type: [Object, Function] as PropType<FloatingMenuPluginProps['appendTo']>,\n default: undefined,\n },\n\n shouldShow: {\n type: Function as PropType<Exclude<Required<FloatingMenuPluginProps>['shouldShow'], null>>,\n default: null,\n },\n },\n\n setup(props, { slots, attrs }) {\n const root = ref<HTMLElement | null>(null)\n const resolvedPluginKey = props.pluginKey ?? new PluginKey('floatingMenu')\n\n onMounted(() => {\n const { editor, updateDelay, resizeDelay, options, appendTo, shouldShow } = props\n\n const el = root.value\n\n if (!el) {\n return\n }\n\n el.style.visibility = 'hidden'\n el.style.position = 'absolute'\n\n // Remove element from DOM; plugin will re-parent it when shown\n el.remove()\n\n editor.registerPlugin(\n FloatingMenuPlugin({\n pluginKey: resolvedPluginKey,\n editor,\n element: el,\n updateDelay,\n resizeDelay,\n options,\n appendTo,\n shouldShow,\n }),\n )\n })\n\n onBeforeUnmount(() => {\n const { editor } = props\n\n editor.unregisterPlugin(resolvedPluginKey)\n })\n\n // Vue owns this element; attrs are applied reactively by Vue\n // Plugin re-parents it when showing the menu\n return () => h('div', { ref: root, ...attrs }, slots.default?.())\n },\n})\n"],"mappings":"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","names":["import_state","_a","import_dom","import_core","import_state","import_state","import_vue","_a"]}
|
|
1
|
+
{"version":3,"sources":["../../src/menus/index.ts","../../../extension-bubble-menu/src/bubble-menu-plugin.ts","../../src/menus/BubbleMenu.ts","../../../extension-floating-menu/src/floating-menu-plugin.ts","../../src/menus/FloatingMenu.ts"],"sourcesContent":["export * from './BubbleMenu.js'\nexport * from './FloatingMenu.js'\n","import {\n type Middleware,\n type VirtualElement,\n arrow,\n autoPlacement,\n computePosition,\n flip,\n hide,\n inline,\n offset,\n shift,\n size,\n} from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { isTextSelection, posToDOMRect } from '@tiptap/core'\nimport type { EditorState, PluginView, Transaction } from '@tiptap/pm/state'\nimport { NodeSelection, Plugin, PluginKey } from '@tiptap/pm/state'\nimport { CellSelection } from '@tiptap/pm/tables'\nimport type { EditorView } from '@tiptap/pm/view'\n\nfunction combineDOMRects(rect1: DOMRect, rect2: DOMRect): DOMRect {\n const top = Math.min(rect1.top, rect2.top)\n const bottom = Math.max(rect1.bottom, rect2.bottom)\n const left = Math.min(rect1.left, rect2.left)\n const right = Math.max(rect1.right, rect2.right)\n const width = right - left\n const height = bottom - top\n const x = left\n const y = top\n return new DOMRect(x, y, width, height)\n}\n\nexport interface BubbleMenuPluginProps {\n /**\n * The plugin key.\n * @type {PluginKey | string}\n * @default 'bubbleMenu'\n */\n pluginKey: PluginKey | string\n\n /**\n * The editor instance.\n */\n editor: Editor\n\n /**\n * The DOM element that contains your menu.\n * @type {HTMLElement}\n * @default null\n */\n element: HTMLElement\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 250\n */\n updateDelay?: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 60\n */\n resizeDelay?: number\n\n /**\n * A function that determines whether the menu should be shown or not.\n * If this function returns `false`, the menu will be hidden, otherwise it will be shown.\n */\n shouldShow?:\n | ((props: {\n editor: Editor\n element: HTMLElement\n view: EditorView\n state: EditorState\n oldState?: EditorState\n from: number\n to: number\n }) => boolean)\n | null\n\n /**\n * The DOM element to append your menu to. Default is the editor's parent element.\n *\n * Sometimes the menu needs to be appended to a different DOM context due to accessibility, clipping, or z-index issues.\n *\n * @type {HTMLElement}\n * @default null\n */\n appendTo?: HTMLElement | (() => HTMLElement)\n\n /**\n * A function that returns the virtual element for the menu.\n * This is useful when the menu needs to be positioned relative to a specific DOM element.\n * @type {() => VirtualElement | null}\n * @default Position based on the selection.\n */\n getReferencedVirtualElement?: () => VirtualElement | null\n\n /**\n * The options for the bubble menu. Those are passed to Floating UI and include options for the placement, offset, flip, shift, arrow, size, autoPlacement,\n * hide, and inline middlewares.\n * @default {}\n * @see https://floating-ui.com/docs/computePosition#options\n */\n options?: {\n strategy?: 'absolute' | 'fixed'\n placement?:\n | 'top'\n | 'right'\n | 'bottom'\n | 'left'\n | 'top-start'\n | 'top-end'\n | 'right-start'\n | 'right-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n offset?: Parameters<typeof offset>[0] | boolean\n flip?: Parameters<typeof flip>[0] | boolean\n shift?: Parameters<typeof shift>[0] | boolean\n arrow?: Parameters<typeof arrow>[0] | false\n size?: Parameters<typeof size>[0] | boolean\n autoPlacement?: Parameters<typeof autoPlacement>[0] | boolean\n hide?: Parameters<typeof hide>[0] | boolean\n inline?: Parameters<typeof inline>[0] | boolean\n\n onShow?: () => void\n onHide?: () => void\n onUpdate?: () => void\n onDestroy?: () => void\n\n /**\n * The scrollable element that should be listened to when updating the position of the bubble menu.\n * If not provided, the window will be used.\n * @type {HTMLElement | Window}\n */\n scrollTarget?: HTMLElement | Window\n }\n}\n\nexport type BubbleMenuViewProps = BubbleMenuPluginProps & {\n view: EditorView\n}\n\nexport class BubbleMenuView implements PluginView {\n public editor: Editor\n\n public element: HTMLElement\n\n public view: EditorView\n\n public preventHide = false\n\n public pluginKey: PluginKey | string\n\n public updateDelay: number\n\n public resizeDelay: number\n\n public appendTo: HTMLElement | (() => HTMLElement) | undefined\n\n public getReferencedVirtualElement: (() => VirtualElement | null) | undefined\n\n private updateDebounceTimer: number | undefined\n\n private resizeDebounceTimer: number | undefined\n\n private isVisible = false\n\n private scrollTarget: HTMLElement | Window = window\n\n private floatingUIOptions: NonNullable<BubbleMenuPluginProps['options']> = {\n strategy: 'absolute',\n placement: 'top',\n offset: 8,\n flip: {},\n shift: {},\n arrow: false,\n size: false,\n autoPlacement: false,\n hide: false,\n inline: false,\n onShow: undefined,\n onHide: undefined,\n onUpdate: undefined,\n onDestroy: undefined,\n }\n\n public shouldShow: Exclude<BubbleMenuPluginProps['shouldShow'], null> = ({ view, state, from, to }) => {\n const { doc, selection } = state\n const { empty } = selection\n\n // Sometime check for `empty` is not enough.\n // Doubleclick an empty paragraph returns a node size of 2.\n // So we check also for an empty text size.\n const isEmptyTextBlock = !doc.textBetween(from, to).length && isTextSelection(state.selection)\n\n // When clicking on a element inside the bubble menu the editor \"blur\" event\n // is called and the bubble menu item is focussed. In this case we should\n // consider the menu as part of the editor and keep showing the menu\n const isChildOfMenu = this.element.contains(document.activeElement)\n\n const hasEditorFocus = view.hasFocus() || isChildOfMenu\n\n if (!hasEditorFocus || empty || isEmptyTextBlock || !this.editor.isEditable) {\n return false\n }\n\n return true\n }\n\n get middlewares() {\n const middlewares: Middleware[] = []\n\n if (this.floatingUIOptions.flip) {\n middlewares.push(flip(typeof this.floatingUIOptions.flip !== 'boolean' ? this.floatingUIOptions.flip : undefined))\n }\n\n if (this.floatingUIOptions.shift) {\n middlewares.push(\n shift(typeof this.floatingUIOptions.shift !== 'boolean' ? this.floatingUIOptions.shift : undefined),\n )\n }\n\n if (this.floatingUIOptions.offset) {\n middlewares.push(\n offset(typeof this.floatingUIOptions.offset !== 'boolean' ? this.floatingUIOptions.offset : undefined),\n )\n }\n\n if (this.floatingUIOptions.arrow) {\n middlewares.push(arrow(this.floatingUIOptions.arrow))\n }\n\n if (this.floatingUIOptions.size) {\n middlewares.push(size(typeof this.floatingUIOptions.size !== 'boolean' ? this.floatingUIOptions.size : undefined))\n }\n\n if (this.floatingUIOptions.autoPlacement) {\n middlewares.push(\n autoPlacement(\n typeof this.floatingUIOptions.autoPlacement !== 'boolean' ? this.floatingUIOptions.autoPlacement : undefined,\n ),\n )\n }\n\n if (this.floatingUIOptions.hide) {\n middlewares.push(hide(typeof this.floatingUIOptions.hide !== 'boolean' ? this.floatingUIOptions.hide : undefined))\n }\n\n if (this.floatingUIOptions.inline) {\n middlewares.push(\n inline(typeof this.floatingUIOptions.inline !== 'boolean' ? this.floatingUIOptions.inline : undefined),\n )\n }\n\n return middlewares\n }\n\n private get virtualElement(): VirtualElement | undefined {\n const { selection } = this.editor.state\n\n const referencedVirtualElement = this.getReferencedVirtualElement?.()\n if (referencedVirtualElement) {\n return referencedVirtualElement\n }\n\n if (!this.view?.dom?.parentNode) {\n return\n }\n\n const domRect = posToDOMRect(this.view, selection.from, selection.to)\n let virtualElement = {\n getBoundingClientRect: () => domRect,\n getClientRects: () => [domRect],\n }\n\n if (selection instanceof NodeSelection) {\n let node = this.view.nodeDOM(selection.from) as HTMLElement\n\n const nodeViewWrapper = node.dataset.nodeViewWrapper ? node : node.querySelector('[data-node-view-wrapper]')\n\n if (nodeViewWrapper) {\n node = nodeViewWrapper as HTMLElement\n }\n\n if (node) {\n virtualElement = {\n getBoundingClientRect: () => node.getBoundingClientRect(),\n getClientRects: () => [node.getBoundingClientRect()],\n }\n }\n }\n\n // this is a special case for cell selections\n if (selection instanceof CellSelection) {\n const { $anchorCell, $headCell } = selection\n\n const from = $anchorCell ? $anchorCell.pos : $headCell!.pos\n const to = $headCell ? $headCell.pos : $anchorCell!.pos\n\n const fromDOM = this.view.nodeDOM(from)\n const toDOM = this.view.nodeDOM(to)\n\n if (!fromDOM || !toDOM) {\n return\n }\n\n const clientRect =\n fromDOM === toDOM\n ? (fromDOM as HTMLElement).getBoundingClientRect()\n : combineDOMRects(\n (fromDOM as HTMLElement).getBoundingClientRect(),\n (toDOM as HTMLElement).getBoundingClientRect(),\n )\n\n virtualElement = {\n getBoundingClientRect: () => clientRect,\n getClientRects: () => [clientRect],\n }\n }\n\n return virtualElement\n }\n\n constructor({\n editor,\n element,\n view,\n pluginKey = 'bubbleMenu',\n updateDelay = 250,\n resizeDelay = 60,\n shouldShow,\n appendTo,\n getReferencedVirtualElement,\n options,\n }: BubbleMenuViewProps) {\n this.editor = editor\n this.element = element\n this.view = view\n this.pluginKey = pluginKey\n this.updateDelay = updateDelay\n this.resizeDelay = resizeDelay\n this.appendTo = appendTo\n this.scrollTarget = options?.scrollTarget ?? window\n this.getReferencedVirtualElement = getReferencedVirtualElement\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...options,\n }\n\n this.element.tabIndex = 0\n\n if (shouldShow) {\n this.shouldShow = shouldShow\n }\n\n this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.addEventListener('dragstart', this.dragstartHandler)\n this.editor.on('focus', this.focusHandler)\n this.editor.on('blur', this.blurHandler)\n this.editor.on('transaction', this.transactionHandler)\n window.addEventListener('resize', this.resizeHandler)\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n\n this.update(view, view.state)\n\n if (this.getShouldShow()) {\n this.show()\n this.updatePosition()\n }\n }\n\n mousedownHandler = () => {\n this.preventHide = true\n }\n\n dragstartHandler = () => {\n this.hide()\n }\n\n /**\n * Handles the window resize event to update the position of the bubble menu.\n * It uses a debounce mechanism to prevent excessive updates.\n * The delay is defined by the `resizeDelay` property.\n */\n resizeHandler = () => {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer)\n }\n\n this.resizeDebounceTimer = window.setTimeout(() => {\n this.updatePosition()\n }, this.resizeDelay)\n }\n\n focusHandler = () => {\n // we use `setTimeout` to make sure `selection` is already updated\n setTimeout(() => this.update(this.editor.view))\n }\n\n blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.editor.isDestroyed) {\n this.destroy()\n return\n }\n\n if (this.preventHide) {\n this.preventHide = false\n\n return\n }\n\n if (event?.relatedTarget && this.element.parentNode?.contains(event.relatedTarget as Node)) {\n return\n }\n\n if (event?.relatedTarget === this.editor.view.dom) {\n return\n }\n\n this.hide()\n }\n\n updatePosition() {\n if (!this.isVisible) {\n return\n }\n\n const virtualElement = this.virtualElement\n\n if (!virtualElement) {\n return\n }\n\n computePosition(virtualElement, this.element, {\n placement: this.floatingUIOptions.placement,\n strategy: this.floatingUIOptions.strategy,\n middleware: this.middlewares,\n }).then(({ x, y, strategy, middlewareData }) => {\n if (!this.isVisible || this.editor.isDestroyed || !this.element.isConnected) {\n return\n }\n\n // Handle hide middleware - hide element if reference is hidden or element has escaped\n if (middlewareData.hide?.referenceHidden || middlewareData.hide?.escaped) {\n this.element.style.visibility = 'hidden'\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.width = 'max-content'\n this.element.style.position = strategy\n this.element.style.left = `${x}px`\n this.element.style.top = `${y}px`\n\n if (this.isVisible && this.floatingUIOptions.onUpdate) {\n this.floatingUIOptions.onUpdate()\n }\n })\n }\n\n update(view: EditorView, oldState?: EditorState) {\n const { state } = view\n const hasValidSelection = state.selection.from !== state.selection.to\n\n if (this.updateDelay > 0 && hasValidSelection) {\n this.handleDebouncedUpdate(view, oldState)\n return\n }\n\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }\n\n handleDebouncedUpdate = (view: EditorView, oldState?: EditorState) => {\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n if (!selectionChanged && !docChanged) {\n return\n }\n\n if (this.updateDebounceTimer) {\n clearTimeout(this.updateDebounceTimer)\n }\n\n this.updateDebounceTimer = window.setTimeout(() => {\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }, this.updateDelay)\n }\n\n getShouldShow(oldState?: EditorState) {\n const { state } = this.view\n const { selection } = state\n\n // support for CellSelections\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n\n const shouldShow = this.shouldShow?.({\n editor: this.editor,\n element: this.element,\n view: this.view,\n state,\n oldState,\n from,\n to,\n })\n\n return shouldShow || false\n }\n\n updateHandler = (view: EditorView, selectionChanged: boolean, docChanged: boolean, oldState?: EditorState) => {\n const { composing } = view\n\n const isSame = !selectionChanged && !docChanged\n\n if (composing || isSame) {\n return\n }\n\n const shouldShow = this.getShouldShow(oldState)\n\n if (!shouldShow) {\n this.hide()\n\n return\n }\n\n this.show()\n this.updatePosition()\n }\n\n show() {\n if (this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.opacity = '1'\n\n // attach to appendTo or editor's parent element\n const appendToElement = typeof this.appendTo === 'function' ? this.appendTo() : this.appendTo\n ;(appendToElement ?? this.view.dom.parentElement)?.appendChild(this.element)\n\n if (this.floatingUIOptions.onShow) {\n this.floatingUIOptions.onShow()\n }\n\n this.isVisible = true\n }\n\n hide() {\n if (!this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'hidden'\n this.element.style.opacity = '0'\n // remove from the parent element\n this.element.remove()\n\n if (this.floatingUIOptions.onHide) {\n this.floatingUIOptions.onHide()\n }\n\n this.isVisible = false\n }\n\n /**\n * Handles the transaction event to update the position of the bubble menu.\n * This allows external code to trigger a position update via:\n * `editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'updatePosition'))`\n * The `pluginKey` defaults to `bubbleMenu`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta(this.pluginKey)\n if (meta === 'updatePosition') {\n this.updatePosition()\n } else if (meta && typeof meta === 'object' && meta.type === 'updateOptions') {\n this.updateOptions(meta.options)\n } else if (meta === 'hide') {\n this.hide()\n } else if (meta === 'show') {\n this.updatePosition()\n this.show()\n }\n }\n\n updateOptions(newProps: Partial<Omit<BubbleMenuPluginProps, 'editor' | 'element' | 'pluginKey'>>) {\n if (newProps.updateDelay !== undefined) {\n this.updateDelay = newProps.updateDelay\n }\n\n if (newProps.resizeDelay !== undefined) {\n this.resizeDelay = newProps.resizeDelay\n }\n\n if (newProps.appendTo !== undefined) {\n this.appendTo = newProps.appendTo\n }\n\n if (newProps.getReferencedVirtualElement !== undefined) {\n this.getReferencedVirtualElement = newProps.getReferencedVirtualElement\n }\n\n if (newProps.shouldShow !== undefined) {\n if (newProps.shouldShow) {\n this.shouldShow = newProps.shouldShow\n }\n }\n\n if (newProps.options !== undefined) {\n // Handle scrollTarget change - need to remove old listener and add new one\n // Use nullish coalescing to default to window when scrollTarget is undefined/null\n const newScrollTarget = newProps.options.scrollTarget ?? window\n\n if (newScrollTarget !== this.scrollTarget) {\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.scrollTarget = newScrollTarget\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n }\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...newProps.options,\n }\n }\n }\n\n destroy() {\n this.hide()\n this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.removeEventListener('dragstart', this.dragstartHandler)\n window.removeEventListener('resize', this.resizeHandler)\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.editor.off('focus', this.focusHandler)\n this.editor.off('blur', this.blurHandler)\n this.editor.off('transaction', this.transactionHandler)\n\n if (this.floatingUIOptions.onDestroy) {\n this.floatingUIOptions.onDestroy()\n }\n }\n}\n\nexport const BubbleMenuPlugin = (options: BubbleMenuPluginProps) => {\n return new Plugin({\n key: typeof options.pluginKey === 'string' ? new PluginKey(options.pluginKey) : options.pluginKey,\n view: view => new BubbleMenuView({ view, ...options }),\n })\n}\n","import type { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'\nimport { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { PropType } from 'vue'\nimport { defineComponent, h, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'\n\nexport const BubbleMenu = defineComponent({\n name: 'BubbleMenu',\n\n inheritAttrs: false,\n\n props: {\n pluginKey: {\n type: [String, Object] as PropType<BubbleMenuPluginProps['pluginKey']>,\n default: undefined,\n },\n\n editor: {\n type: Object as PropType<BubbleMenuPluginProps['editor']>,\n required: true,\n },\n\n updateDelay: {\n type: Number as PropType<BubbleMenuPluginProps['updateDelay']>,\n default: undefined,\n },\n\n resizeDelay: {\n type: Number as PropType<BubbleMenuPluginProps['resizeDelay']>,\n default: undefined,\n },\n\n options: {\n type: Object as PropType<BubbleMenuPluginProps['options']>,\n default: () => ({}),\n },\n\n appendTo: {\n type: [Object, Function] as PropType<BubbleMenuPluginProps['appendTo']>,\n default: undefined,\n },\n\n shouldShow: {\n type: Function as PropType<Exclude<Required<BubbleMenuPluginProps>['shouldShow'], null>>,\n default: null,\n },\n\n getReferencedVirtualElement: {\n type: Function as PropType<Exclude<Required<BubbleMenuPluginProps>['getReferencedVirtualElement'], null>>,\n default: undefined,\n },\n },\n\n setup(props, { slots, attrs }) {\n const root = ref<HTMLElement | null>(null)\n const resolvedPluginKey = props.pluginKey ?? new PluginKey('bubbleMenu')\n\n onMounted(() => {\n const { editor, options, resizeDelay, appendTo, shouldShow, getReferencedVirtualElement, updateDelay } = props\n\n const el = root.value\n\n if (!el) {\n return\n }\n\n el.style.visibility = 'hidden'\n el.style.position = 'absolute'\n\n // Remove element from DOM; plugin will re-parent it when shown\n el.remove()\n\n nextTick(() => {\n editor.registerPlugin(\n BubbleMenuPlugin({\n editor,\n element: el,\n options,\n pluginKey: resolvedPluginKey,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n }),\n )\n })\n })\n\n onBeforeUnmount(() => {\n const { editor } = props\n\n editor.unregisterPlugin(resolvedPluginKey)\n })\n\n // Vue owns this element; attrs are applied reactively by Vue\n // Plugin re-parents it when showing the menu\n return () => h('div', { ref: root, ...attrs }, slots.default?.())\n },\n})\n","import {\n type Middleware,\n arrow,\n autoPlacement,\n computePosition,\n flip,\n hide,\n inline,\n offset,\n shift,\n size,\n} from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { getText, getTextSerializersFromSchema, posToDOMRect } from '@tiptap/core'\nimport type { Node as ProsemirrorNode } from '@tiptap/pm/model'\nimport type { EditorState, Transaction } from '@tiptap/pm/state'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\n\nexport interface FloatingMenuPluginProps {\n /**\n * The plugin key for the floating menu.\n * @default 'floatingMenu'\n */\n pluginKey: PluginKey | string\n\n /**\n * The editor instance.\n * @default null\n */\n editor: Editor\n\n /**\n * The DOM element that contains your menu.\n * @default null\n */\n element: HTMLElement\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 250\n */\n updateDelay?: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 60\n */\n resizeDelay?: number\n\n /**\n * The DOM element to append your menu to. Default is the editor's parent element.\n *\n * Sometimes the menu needs to be appended to a different DOM context due to accessibility, clipping, or z-index issues.\n *\n * @type {HTMLElement}\n * @default null\n */\n appendTo?: HTMLElement | (() => HTMLElement)\n\n /**\n * A function that determines whether the menu should be shown or not.\n * If this function returns `false`, the menu will be hidden, otherwise it will be shown.\n */\n shouldShow?:\n | ((props: {\n editor: Editor\n view: EditorView\n state: EditorState\n oldState?: EditorState\n from: number\n to: number\n }) => boolean)\n | null\n\n /**\n * The options for the floating menu. Those are passed to Floating UI and include options for the placement, offset, flip, shift, arrow, size, autoPlacement,\n * hide, and inline middlewares.\n * @default {}\n * @see https://floating-ui.com/docs/computePosition#options\n */\n options?: {\n strategy?: 'absolute' | 'fixed'\n placement?:\n | 'top'\n | 'right'\n | 'bottom'\n | 'left'\n | 'top-start'\n | 'top-end'\n | 'right-start'\n | 'right-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n offset?: Parameters<typeof offset>[0] | boolean\n flip?: Parameters<typeof flip>[0] | boolean\n shift?: Parameters<typeof shift>[0] | boolean\n arrow?: Parameters<typeof arrow>[0] | false\n size?: Parameters<typeof size>[0] | boolean\n autoPlacement?: Parameters<typeof autoPlacement>[0] | boolean\n hide?: Parameters<typeof hide>[0] | boolean\n inline?: Parameters<typeof inline>[0] | boolean\n\n onShow?: () => void\n onHide?: () => void\n onUpdate?: () => void\n onDestroy?: () => void\n\n /**\n * The scrollable element that should be listened to when updating the position of the floating menu.\n * If not provided, the window will be used.\n * @type {HTMLElement | Window}\n */\n scrollTarget?: HTMLElement | Window\n }\n}\n\nexport type FloatingMenuViewProps = FloatingMenuPluginProps & {\n /**\n * The editor view.\n */\n view: EditorView\n}\n\nexport class FloatingMenuView {\n public editor: Editor\n\n public element: HTMLElement\n\n public view: EditorView\n\n public preventHide = false\n\n public pluginKey: PluginKey | string\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * @default 250\n */\n public updateDelay: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * @default 60\n */\n public resizeDelay: number\n\n public appendTo: HTMLElement | (() => HTMLElement) | undefined\n\n private updateDebounceTimer: number | undefined\n\n private resizeDebounceTimer: number | undefined\n\n private isVisible = false\n\n private scrollTarget: HTMLElement | Window = window\n\n private getTextContent(node: ProsemirrorNode) {\n return getText(node, { textSerializers: getTextSerializersFromSchema(this.editor.schema) })\n }\n\n public shouldShow: Exclude<FloatingMenuPluginProps['shouldShow'], null> = ({ view, state }) => {\n const { selection } = state\n const { $anchor, empty } = selection\n const isRootDepth = $anchor.depth === 1\n\n const isEmptyTextBlock =\n $anchor.parent.isTextblock &&\n !$anchor.parent.type.spec.code &&\n !$anchor.parent.textContent &&\n $anchor.parent.childCount === 0 &&\n !this.getTextContent($anchor.parent)\n\n if (!view.hasFocus() || !empty || !isRootDepth || !isEmptyTextBlock || !this.editor.isEditable) {\n return false\n }\n\n return true\n }\n\n private floatingUIOptions: NonNullable<FloatingMenuPluginProps['options']> = {\n strategy: 'absolute',\n placement: 'right',\n offset: 8,\n flip: {},\n shift: {},\n arrow: false,\n size: false,\n autoPlacement: false,\n hide: false,\n inline: false,\n }\n\n get middlewares() {\n const middlewares: Middleware[] = []\n\n if (this.floatingUIOptions.flip) {\n middlewares.push(flip(typeof this.floatingUIOptions.flip !== 'boolean' ? this.floatingUIOptions.flip : undefined))\n }\n\n if (this.floatingUIOptions.shift) {\n middlewares.push(\n shift(typeof this.floatingUIOptions.shift !== 'boolean' ? this.floatingUIOptions.shift : undefined),\n )\n }\n\n if (this.floatingUIOptions.offset) {\n middlewares.push(\n offset(typeof this.floatingUIOptions.offset !== 'boolean' ? this.floatingUIOptions.offset : undefined),\n )\n }\n\n if (this.floatingUIOptions.arrow) {\n middlewares.push(arrow(this.floatingUIOptions.arrow))\n }\n\n if (this.floatingUIOptions.size) {\n middlewares.push(size(typeof this.floatingUIOptions.size !== 'boolean' ? this.floatingUIOptions.size : undefined))\n }\n\n if (this.floatingUIOptions.autoPlacement) {\n middlewares.push(\n autoPlacement(\n typeof this.floatingUIOptions.autoPlacement !== 'boolean' ? this.floatingUIOptions.autoPlacement : undefined,\n ),\n )\n }\n\n if (this.floatingUIOptions.hide) {\n middlewares.push(hide(typeof this.floatingUIOptions.hide !== 'boolean' ? this.floatingUIOptions.hide : undefined))\n }\n\n if (this.floatingUIOptions.inline) {\n middlewares.push(\n inline(typeof this.floatingUIOptions.inline !== 'boolean' ? this.floatingUIOptions.inline : undefined),\n )\n }\n\n return middlewares\n }\n\n constructor({\n editor,\n element,\n view,\n pluginKey = 'floatingMenu',\n updateDelay = 250,\n resizeDelay = 60,\n options,\n appendTo,\n shouldShow,\n }: FloatingMenuViewProps) {\n this.editor = editor\n this.element = element\n this.view = view\n this.pluginKey = pluginKey\n this.updateDelay = updateDelay\n this.resizeDelay = resizeDelay\n this.appendTo = appendTo\n this.scrollTarget = options?.scrollTarget ?? window\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...options,\n }\n\n this.element.tabIndex = 0\n\n if (shouldShow) {\n this.shouldShow = shouldShow\n }\n\n this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.editor.on('focus', this.focusHandler)\n this.editor.on('blur', this.blurHandler)\n this.editor.on('transaction', this.transactionHandler)\n window.addEventListener('resize', this.resizeHandler)\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n\n this.update(view, view.state)\n\n if (this.getShouldShow()) {\n this.show()\n this.updatePosition()\n }\n }\n\n getShouldShow(oldState?: EditorState) {\n const { state } = this.view\n const { selection } = state\n\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n\n const shouldShow = this.shouldShow?.({\n editor: this.editor,\n view: this.view,\n state,\n oldState,\n from,\n to,\n })\n\n return shouldShow\n }\n\n updateHandler = (view: EditorView, selectionChanged: boolean, docChanged: boolean, oldState?: EditorState) => {\n const { composing } = view\n\n const isSame = !selectionChanged && !docChanged\n\n if (composing || isSame) {\n return\n }\n\n const shouldShow = this.getShouldShow(oldState)\n\n if (!shouldShow) {\n this.hide()\n\n return\n }\n\n this.updatePosition()\n this.show()\n }\n\n mousedownHandler = () => {\n this.preventHide = true\n }\n\n focusHandler = () => {\n // we use `setTimeout` to make sure `selection` is already updated\n setTimeout(() => this.update(this.editor.view))\n }\n\n blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.preventHide) {\n this.preventHide = false\n\n return\n }\n\n if (event?.relatedTarget && this.element.parentNode?.contains(event.relatedTarget as Node)) {\n return\n }\n\n if (event?.relatedTarget === this.editor.view.dom) {\n return\n }\n\n this.hide()\n }\n\n /**\n * Handles the transaction event to update the position of the floating menu.\n * This allows external code to trigger a position update via:\n * `editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'updatePosition'))`\n * The `pluginKey` defaults to `floatingMenu`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta(this.pluginKey)\n if (meta === 'updatePosition') {\n this.updatePosition()\n } else if (meta && typeof meta === 'object' && meta.type === 'updateOptions') {\n this.updateOptions(meta.options)\n } else if (meta === 'hide') {\n this.hide()\n } else if (meta === 'show') {\n this.updatePosition()\n this.show()\n }\n }\n\n updateOptions(newProps: Partial<Omit<FloatingMenuPluginProps, 'editor' | 'element' | 'pluginKey'>>) {\n if (newProps.updateDelay !== undefined) {\n this.updateDelay = newProps.updateDelay\n }\n\n if (newProps.resizeDelay !== undefined) {\n this.resizeDelay = newProps.resizeDelay\n }\n\n if (newProps.appendTo !== undefined) {\n this.appendTo = newProps.appendTo\n }\n\n if (newProps.shouldShow !== undefined) {\n if (newProps.shouldShow) {\n this.shouldShow = newProps.shouldShow\n }\n }\n\n if (newProps.options !== undefined) {\n // Handle scrollTarget change - need to remove old listener and add new one\n // Use nullish coalescing to default to window when scrollTarget is undefined/null\n const newScrollTarget = newProps.options.scrollTarget ?? window\n\n if (newScrollTarget !== this.scrollTarget) {\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.scrollTarget = newScrollTarget\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n }\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...newProps.options,\n }\n }\n }\n\n /**\n * Handles the window resize event to update the position of the floating menu.\n * It uses a debounce mechanism to prevent excessive updates.\n * The delay is defined by the `resizeDelay` property.\n */\n resizeHandler = () => {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer)\n }\n\n this.resizeDebounceTimer = window.setTimeout(() => {\n this.updatePosition()\n }, this.resizeDelay)\n }\n\n updatePosition() {\n if (!this.view?.dom?.parentNode) {\n return\n }\n\n const { selection } = this.editor.state\n\n const domRect = posToDOMRect(this.view, selection.from, selection.to)\n\n const virtualElement = {\n getBoundingClientRect: () => domRect,\n getClientRects: () => [domRect],\n }\n\n computePosition(virtualElement, this.element, {\n placement: this.floatingUIOptions.placement,\n strategy: this.floatingUIOptions.strategy,\n middleware: this.middlewares,\n }).then(({ x, y, strategy, middlewareData }) => {\n // Handle hide middleware - hide element if reference is hidden or element has escaped\n if (middlewareData.hide?.referenceHidden || middlewareData.hide?.escaped) {\n this.element.style.visibility = 'hidden'\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.width = 'max-content'\n this.element.style.position = strategy\n this.element.style.left = `${x}px`\n this.element.style.top = `${y}px`\n\n if (this.isVisible && this.floatingUIOptions.onUpdate) {\n this.floatingUIOptions.onUpdate()\n }\n })\n }\n\n update(view: EditorView, oldState?: EditorState) {\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }\n\n show() {\n if (this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.opacity = '1'\n\n // attach to appendTo or editor's parent element\n const appendToElement = typeof this.appendTo === 'function' ? this.appendTo() : this.appendTo\n ;(appendToElement ?? this.view.dom.parentElement)?.appendChild(this.element)\n\n if (this.floatingUIOptions.onShow) {\n this.floatingUIOptions.onShow()\n }\n\n this.isVisible = true\n }\n\n hide() {\n if (!this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'hidden'\n this.element.style.opacity = '0'\n // remove from the parent element\n this.element.remove()\n\n if (this.floatingUIOptions.onHide) {\n this.floatingUIOptions.onHide()\n }\n\n this.isVisible = false\n }\n\n destroy() {\n this.hide()\n this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true })\n window.removeEventListener('resize', this.resizeHandler)\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.editor.off('focus', this.focusHandler)\n this.editor.off('blur', this.blurHandler)\n this.editor.off('transaction', this.transactionHandler)\n\n if (this.floatingUIOptions.onDestroy) {\n this.floatingUIOptions.onDestroy()\n }\n }\n}\n\nexport const FloatingMenuPlugin = (options: FloatingMenuPluginProps) => {\n return new Plugin({\n key: typeof options.pluginKey === 'string' ? new PluginKey(options.pluginKey) : options.pluginKey,\n view: view => new FloatingMenuView({ view, ...options }),\n })\n}\n","import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { PropType } from 'vue'\nimport { defineComponent, h, onBeforeUnmount, onMounted, ref } from 'vue'\n\nexport const FloatingMenu = defineComponent({\n name: 'FloatingMenu',\n\n inheritAttrs: false,\n\n props: {\n pluginKey: {\n // TODO: TypeScript breaks :(\n // type: [String, Object as PropType<Exclude<FloatingMenuPluginProps['pluginKey'], string>>],\n type: null,\n default: undefined,\n },\n\n editor: {\n type: Object as PropType<FloatingMenuPluginProps['editor']>,\n required: true,\n },\n\n updateDelay: {\n type: Number as PropType<FloatingMenuPluginProps['updateDelay']>,\n default: undefined,\n },\n\n resizeDelay: {\n type: Number as PropType<FloatingMenuPluginProps['resizeDelay']>,\n default: undefined,\n },\n\n options: {\n type: Object as PropType<FloatingMenuPluginProps['options']>,\n default: () => ({}),\n },\n\n appendTo: {\n type: [Object, Function] as PropType<FloatingMenuPluginProps['appendTo']>,\n default: undefined,\n },\n\n shouldShow: {\n type: Function as PropType<Exclude<Required<FloatingMenuPluginProps>['shouldShow'], null>>,\n default: null,\n },\n },\n\n setup(props, { slots, attrs }) {\n const root = ref<HTMLElement | null>(null)\n const resolvedPluginKey = props.pluginKey ?? new PluginKey('floatingMenu')\n\n onMounted(() => {\n const { editor, updateDelay, resizeDelay, options, appendTo, shouldShow } = props\n\n const el = root.value\n\n if (!el) {\n return\n }\n\n el.style.visibility = 'hidden'\n el.style.position = 'absolute'\n\n // Remove element from DOM; plugin will re-parent it when shown\n el.remove()\n\n editor.registerPlugin(\n FloatingMenuPlugin({\n pluginKey: resolvedPluginKey,\n editor,\n element: el,\n updateDelay,\n resizeDelay,\n options,\n appendTo,\n shouldShow,\n }),\n )\n })\n\n onBeforeUnmount(() => {\n const { editor } = props\n\n editor.unregisterPlugin(resolvedPluginKey)\n })\n\n // Vue owns this element; attrs are applied reactively by Vue\n // Plugin re-parents it when showing the menu\n return () => h('div', { ref: root, ...attrs }, slots.default?.())\n },\n})\n"],"mappings":"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","names":["import_state","_a","import_dom","import_core","import_state","_a","_b","import_state","import_vue","_a"]}
|
package/dist/menus/index.js
CHANGED
|
@@ -723,6 +723,10 @@ var FloatingMenuView = class {
|
|
|
723
723
|
}
|
|
724
724
|
}
|
|
725
725
|
updatePosition() {
|
|
726
|
+
var _a, _b;
|
|
727
|
+
if (!((_b = (_a = this.view) == null ? void 0 : _a.dom) == null ? void 0 : _b.parentNode)) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
726
730
|
const { selection } = this.editor.state;
|
|
727
731
|
const domRect = posToDOMRect2(this.view, selection.from, selection.to);
|
|
728
732
|
const virtualElement = {
|
|
@@ -734,8 +738,8 @@ var FloatingMenuView = class {
|
|
|
734
738
|
strategy: this.floatingUIOptions.strategy,
|
|
735
739
|
middleware: this.middlewares
|
|
736
740
|
}).then(({ x, y, strategy, middlewareData }) => {
|
|
737
|
-
var
|
|
738
|
-
if (((
|
|
741
|
+
var _a2, _b2;
|
|
742
|
+
if (((_a2 = middlewareData.hide) == null ? void 0 : _a2.referenceHidden) || ((_b2 = middlewareData.hide) == null ? void 0 : _b2.escaped)) {
|
|
739
743
|
this.element.style.visibility = "hidden";
|
|
740
744
|
return;
|
|
741
745
|
}
|
package/dist/menus/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../extension-bubble-menu/src/bubble-menu-plugin.ts","../../src/menus/BubbleMenu.ts","../../../extension-floating-menu/src/floating-menu-plugin.ts","../../src/menus/FloatingMenu.ts"],"sourcesContent":["import {\n type Middleware,\n type VirtualElement,\n arrow,\n autoPlacement,\n computePosition,\n flip,\n hide,\n inline,\n offset,\n shift,\n size,\n} from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { isTextSelection, posToDOMRect } from '@tiptap/core'\nimport type { EditorState, PluginView, Transaction } from '@tiptap/pm/state'\nimport { NodeSelection, Plugin, PluginKey } from '@tiptap/pm/state'\nimport { CellSelection } from '@tiptap/pm/tables'\nimport type { EditorView } from '@tiptap/pm/view'\n\nfunction combineDOMRects(rect1: DOMRect, rect2: DOMRect): DOMRect {\n const top = Math.min(rect1.top, rect2.top)\n const bottom = Math.max(rect1.bottom, rect2.bottom)\n const left = Math.min(rect1.left, rect2.left)\n const right = Math.max(rect1.right, rect2.right)\n const width = right - left\n const height = bottom - top\n const x = left\n const y = top\n return new DOMRect(x, y, width, height)\n}\n\nexport interface BubbleMenuPluginProps {\n /**\n * The plugin key.\n * @type {PluginKey | string}\n * @default 'bubbleMenu'\n */\n pluginKey: PluginKey | string\n\n /**\n * The editor instance.\n */\n editor: Editor\n\n /**\n * The DOM element that contains your menu.\n * @type {HTMLElement}\n * @default null\n */\n element: HTMLElement\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 250\n */\n updateDelay?: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 60\n */\n resizeDelay?: number\n\n /**\n * A function that determines whether the menu should be shown or not.\n * If this function returns `false`, the menu will be hidden, otherwise it will be shown.\n */\n shouldShow?:\n | ((props: {\n editor: Editor\n element: HTMLElement\n view: EditorView\n state: EditorState\n oldState?: EditorState\n from: number\n to: number\n }) => boolean)\n | null\n\n /**\n * The DOM element to append your menu to. Default is the editor's parent element.\n *\n * Sometimes the menu needs to be appended to a different DOM context due to accessibility, clipping, or z-index issues.\n *\n * @type {HTMLElement}\n * @default null\n */\n appendTo?: HTMLElement | (() => HTMLElement)\n\n /**\n * A function that returns the virtual element for the menu.\n * This is useful when the menu needs to be positioned relative to a specific DOM element.\n * @type {() => VirtualElement | null}\n * @default Position based on the selection.\n */\n getReferencedVirtualElement?: () => VirtualElement | null\n\n /**\n * The options for the bubble menu. Those are passed to Floating UI and include options for the placement, offset, flip, shift, arrow, size, autoPlacement,\n * hide, and inline middlewares.\n * @default {}\n * @see https://floating-ui.com/docs/computePosition#options\n */\n options?: {\n strategy?: 'absolute' | 'fixed'\n placement?:\n | 'top'\n | 'right'\n | 'bottom'\n | 'left'\n | 'top-start'\n | 'top-end'\n | 'right-start'\n | 'right-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n offset?: Parameters<typeof offset>[0] | boolean\n flip?: Parameters<typeof flip>[0] | boolean\n shift?: Parameters<typeof shift>[0] | boolean\n arrow?: Parameters<typeof arrow>[0] | false\n size?: Parameters<typeof size>[0] | boolean\n autoPlacement?: Parameters<typeof autoPlacement>[0] | boolean\n hide?: Parameters<typeof hide>[0] | boolean\n inline?: Parameters<typeof inline>[0] | boolean\n\n onShow?: () => void\n onHide?: () => void\n onUpdate?: () => void\n onDestroy?: () => void\n\n /**\n * The scrollable element that should be listened to when updating the position of the bubble menu.\n * If not provided, the window will be used.\n * @type {HTMLElement | Window}\n */\n scrollTarget?: HTMLElement | Window\n }\n}\n\nexport type BubbleMenuViewProps = BubbleMenuPluginProps & {\n view: EditorView\n}\n\nexport class BubbleMenuView implements PluginView {\n public editor: Editor\n\n public element: HTMLElement\n\n public view: EditorView\n\n public preventHide = false\n\n public pluginKey: PluginKey | string\n\n public updateDelay: number\n\n public resizeDelay: number\n\n public appendTo: HTMLElement | (() => HTMLElement) | undefined\n\n public getReferencedVirtualElement: (() => VirtualElement | null) | undefined\n\n private updateDebounceTimer: number | undefined\n\n private resizeDebounceTimer: number | undefined\n\n private isVisible = false\n\n private scrollTarget: HTMLElement | Window = window\n\n private floatingUIOptions: NonNullable<BubbleMenuPluginProps['options']> = {\n strategy: 'absolute',\n placement: 'top',\n offset: 8,\n flip: {},\n shift: {},\n arrow: false,\n size: false,\n autoPlacement: false,\n hide: false,\n inline: false,\n onShow: undefined,\n onHide: undefined,\n onUpdate: undefined,\n onDestroy: undefined,\n }\n\n public shouldShow: Exclude<BubbleMenuPluginProps['shouldShow'], null> = ({ view, state, from, to }) => {\n const { doc, selection } = state\n const { empty } = selection\n\n // Sometime check for `empty` is not enough.\n // Doubleclick an empty paragraph returns a node size of 2.\n // So we check also for an empty text size.\n const isEmptyTextBlock = !doc.textBetween(from, to).length && isTextSelection(state.selection)\n\n // When clicking on a element inside the bubble menu the editor \"blur\" event\n // is called and the bubble menu item is focussed. In this case we should\n // consider the menu as part of the editor and keep showing the menu\n const isChildOfMenu = this.element.contains(document.activeElement)\n\n const hasEditorFocus = view.hasFocus() || isChildOfMenu\n\n if (!hasEditorFocus || empty || isEmptyTextBlock || !this.editor.isEditable) {\n return false\n }\n\n return true\n }\n\n get middlewares() {\n const middlewares: Middleware[] = []\n\n if (this.floatingUIOptions.flip) {\n middlewares.push(flip(typeof this.floatingUIOptions.flip !== 'boolean' ? this.floatingUIOptions.flip : undefined))\n }\n\n if (this.floatingUIOptions.shift) {\n middlewares.push(\n shift(typeof this.floatingUIOptions.shift !== 'boolean' ? this.floatingUIOptions.shift : undefined),\n )\n }\n\n if (this.floatingUIOptions.offset) {\n middlewares.push(\n offset(typeof this.floatingUIOptions.offset !== 'boolean' ? this.floatingUIOptions.offset : undefined),\n )\n }\n\n if (this.floatingUIOptions.arrow) {\n middlewares.push(arrow(this.floatingUIOptions.arrow))\n }\n\n if (this.floatingUIOptions.size) {\n middlewares.push(size(typeof this.floatingUIOptions.size !== 'boolean' ? this.floatingUIOptions.size : undefined))\n }\n\n if (this.floatingUIOptions.autoPlacement) {\n middlewares.push(\n autoPlacement(\n typeof this.floatingUIOptions.autoPlacement !== 'boolean' ? this.floatingUIOptions.autoPlacement : undefined,\n ),\n )\n }\n\n if (this.floatingUIOptions.hide) {\n middlewares.push(hide(typeof this.floatingUIOptions.hide !== 'boolean' ? this.floatingUIOptions.hide : undefined))\n }\n\n if (this.floatingUIOptions.inline) {\n middlewares.push(\n inline(typeof this.floatingUIOptions.inline !== 'boolean' ? this.floatingUIOptions.inline : undefined),\n )\n }\n\n return middlewares\n }\n\n private get virtualElement(): VirtualElement | undefined {\n const { selection } = this.editor.state\n\n const referencedVirtualElement = this.getReferencedVirtualElement?.()\n if (referencedVirtualElement) {\n return referencedVirtualElement\n }\n\n if (!this.view?.dom?.parentNode) {\n return\n }\n\n const domRect = posToDOMRect(this.view, selection.from, selection.to)\n let virtualElement = {\n getBoundingClientRect: () => domRect,\n getClientRects: () => [domRect],\n }\n\n if (selection instanceof NodeSelection) {\n let node = this.view.nodeDOM(selection.from) as HTMLElement\n\n const nodeViewWrapper = node.dataset.nodeViewWrapper ? node : node.querySelector('[data-node-view-wrapper]')\n\n if (nodeViewWrapper) {\n node = nodeViewWrapper as HTMLElement\n }\n\n if (node) {\n virtualElement = {\n getBoundingClientRect: () => node.getBoundingClientRect(),\n getClientRects: () => [node.getBoundingClientRect()],\n }\n }\n }\n\n // this is a special case for cell selections\n if (selection instanceof CellSelection) {\n const { $anchorCell, $headCell } = selection\n\n const from = $anchorCell ? $anchorCell.pos : $headCell!.pos\n const to = $headCell ? $headCell.pos : $anchorCell!.pos\n\n const fromDOM = this.view.nodeDOM(from)\n const toDOM = this.view.nodeDOM(to)\n\n if (!fromDOM || !toDOM) {\n return\n }\n\n const clientRect =\n fromDOM === toDOM\n ? (fromDOM as HTMLElement).getBoundingClientRect()\n : combineDOMRects(\n (fromDOM as HTMLElement).getBoundingClientRect(),\n (toDOM as HTMLElement).getBoundingClientRect(),\n )\n\n virtualElement = {\n getBoundingClientRect: () => clientRect,\n getClientRects: () => [clientRect],\n }\n }\n\n return virtualElement\n }\n\n constructor({\n editor,\n element,\n view,\n pluginKey = 'bubbleMenu',\n updateDelay = 250,\n resizeDelay = 60,\n shouldShow,\n appendTo,\n getReferencedVirtualElement,\n options,\n }: BubbleMenuViewProps) {\n this.editor = editor\n this.element = element\n this.view = view\n this.pluginKey = pluginKey\n this.updateDelay = updateDelay\n this.resizeDelay = resizeDelay\n this.appendTo = appendTo\n this.scrollTarget = options?.scrollTarget ?? window\n this.getReferencedVirtualElement = getReferencedVirtualElement\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...options,\n }\n\n this.element.tabIndex = 0\n\n if (shouldShow) {\n this.shouldShow = shouldShow\n }\n\n this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.addEventListener('dragstart', this.dragstartHandler)\n this.editor.on('focus', this.focusHandler)\n this.editor.on('blur', this.blurHandler)\n this.editor.on('transaction', this.transactionHandler)\n window.addEventListener('resize', this.resizeHandler)\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n\n this.update(view, view.state)\n\n if (this.getShouldShow()) {\n this.show()\n this.updatePosition()\n }\n }\n\n mousedownHandler = () => {\n this.preventHide = true\n }\n\n dragstartHandler = () => {\n this.hide()\n }\n\n /**\n * Handles the window resize event to update the position of the bubble menu.\n * It uses a debounce mechanism to prevent excessive updates.\n * The delay is defined by the `resizeDelay` property.\n */\n resizeHandler = () => {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer)\n }\n\n this.resizeDebounceTimer = window.setTimeout(() => {\n this.updatePosition()\n }, this.resizeDelay)\n }\n\n focusHandler = () => {\n // we use `setTimeout` to make sure `selection` is already updated\n setTimeout(() => this.update(this.editor.view))\n }\n\n blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.editor.isDestroyed) {\n this.destroy()\n return\n }\n\n if (this.preventHide) {\n this.preventHide = false\n\n return\n }\n\n if (event?.relatedTarget && this.element.parentNode?.contains(event.relatedTarget as Node)) {\n return\n }\n\n if (event?.relatedTarget === this.editor.view.dom) {\n return\n }\n\n this.hide()\n }\n\n updatePosition() {\n if (!this.isVisible) {\n return\n }\n\n const virtualElement = this.virtualElement\n\n if (!virtualElement) {\n return\n }\n\n computePosition(virtualElement, this.element, {\n placement: this.floatingUIOptions.placement,\n strategy: this.floatingUIOptions.strategy,\n middleware: this.middlewares,\n }).then(({ x, y, strategy, middlewareData }) => {\n if (!this.isVisible || this.editor.isDestroyed || !this.element.isConnected) {\n return\n }\n\n // Handle hide middleware - hide element if reference is hidden or element has escaped\n if (middlewareData.hide?.referenceHidden || middlewareData.hide?.escaped) {\n this.element.style.visibility = 'hidden'\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.width = 'max-content'\n this.element.style.position = strategy\n this.element.style.left = `${x}px`\n this.element.style.top = `${y}px`\n\n if (this.isVisible && this.floatingUIOptions.onUpdate) {\n this.floatingUIOptions.onUpdate()\n }\n })\n }\n\n update(view: EditorView, oldState?: EditorState) {\n const { state } = view\n const hasValidSelection = state.selection.from !== state.selection.to\n\n if (this.updateDelay > 0 && hasValidSelection) {\n this.handleDebouncedUpdate(view, oldState)\n return\n }\n\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }\n\n handleDebouncedUpdate = (view: EditorView, oldState?: EditorState) => {\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n if (!selectionChanged && !docChanged) {\n return\n }\n\n if (this.updateDebounceTimer) {\n clearTimeout(this.updateDebounceTimer)\n }\n\n this.updateDebounceTimer = window.setTimeout(() => {\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }, this.updateDelay)\n }\n\n getShouldShow(oldState?: EditorState) {\n const { state } = this.view\n const { selection } = state\n\n // support for CellSelections\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n\n const shouldShow = this.shouldShow?.({\n editor: this.editor,\n element: this.element,\n view: this.view,\n state,\n oldState,\n from,\n to,\n })\n\n return shouldShow || false\n }\n\n updateHandler = (view: EditorView, selectionChanged: boolean, docChanged: boolean, oldState?: EditorState) => {\n const { composing } = view\n\n const isSame = !selectionChanged && !docChanged\n\n if (composing || isSame) {\n return\n }\n\n const shouldShow = this.getShouldShow(oldState)\n\n if (!shouldShow) {\n this.hide()\n\n return\n }\n\n this.show()\n this.updatePosition()\n }\n\n show() {\n if (this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.opacity = '1'\n\n // attach to appendTo or editor's parent element\n const appendToElement = typeof this.appendTo === 'function' ? this.appendTo() : this.appendTo\n ;(appendToElement ?? this.view.dom.parentElement)?.appendChild(this.element)\n\n if (this.floatingUIOptions.onShow) {\n this.floatingUIOptions.onShow()\n }\n\n this.isVisible = true\n }\n\n hide() {\n if (!this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'hidden'\n this.element.style.opacity = '0'\n // remove from the parent element\n this.element.remove()\n\n if (this.floatingUIOptions.onHide) {\n this.floatingUIOptions.onHide()\n }\n\n this.isVisible = false\n }\n\n /**\n * Handles the transaction event to update the position of the bubble menu.\n * This allows external code to trigger a position update via:\n * `editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'updatePosition'))`\n * The `pluginKey` defaults to `bubbleMenu`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta(this.pluginKey)\n if (meta === 'updatePosition') {\n this.updatePosition()\n } else if (meta && typeof meta === 'object' && meta.type === 'updateOptions') {\n this.updateOptions(meta.options)\n } else if (meta === 'hide') {\n this.hide()\n } else if (meta === 'show') {\n this.updatePosition()\n this.show()\n }\n }\n\n updateOptions(newProps: Partial<Omit<BubbleMenuPluginProps, 'editor' | 'element' | 'pluginKey'>>) {\n if (newProps.updateDelay !== undefined) {\n this.updateDelay = newProps.updateDelay\n }\n\n if (newProps.resizeDelay !== undefined) {\n this.resizeDelay = newProps.resizeDelay\n }\n\n if (newProps.appendTo !== undefined) {\n this.appendTo = newProps.appendTo\n }\n\n if (newProps.getReferencedVirtualElement !== undefined) {\n this.getReferencedVirtualElement = newProps.getReferencedVirtualElement\n }\n\n if (newProps.shouldShow !== undefined) {\n if (newProps.shouldShow) {\n this.shouldShow = newProps.shouldShow\n }\n }\n\n if (newProps.options !== undefined) {\n // Handle scrollTarget change - need to remove old listener and add new one\n // Use nullish coalescing to default to window when scrollTarget is undefined/null\n const newScrollTarget = newProps.options.scrollTarget ?? window\n\n if (newScrollTarget !== this.scrollTarget) {\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.scrollTarget = newScrollTarget\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n }\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...newProps.options,\n }\n }\n }\n\n destroy() {\n this.hide()\n this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.removeEventListener('dragstart', this.dragstartHandler)\n window.removeEventListener('resize', this.resizeHandler)\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.editor.off('focus', this.focusHandler)\n this.editor.off('blur', this.blurHandler)\n this.editor.off('transaction', this.transactionHandler)\n\n if (this.floatingUIOptions.onDestroy) {\n this.floatingUIOptions.onDestroy()\n }\n }\n}\n\nexport const BubbleMenuPlugin = (options: BubbleMenuPluginProps) => {\n return new Plugin({\n key: typeof options.pluginKey === 'string' ? new PluginKey(options.pluginKey) : options.pluginKey,\n view: view => new BubbleMenuView({ view, ...options }),\n })\n}\n","import type { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'\nimport { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { PropType } from 'vue'\nimport { defineComponent, h, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'\n\nexport const BubbleMenu = defineComponent({\n name: 'BubbleMenu',\n\n inheritAttrs: false,\n\n props: {\n pluginKey: {\n type: [String, Object] as PropType<BubbleMenuPluginProps['pluginKey']>,\n default: undefined,\n },\n\n editor: {\n type: Object as PropType<BubbleMenuPluginProps['editor']>,\n required: true,\n },\n\n updateDelay: {\n type: Number as PropType<BubbleMenuPluginProps['updateDelay']>,\n default: undefined,\n },\n\n resizeDelay: {\n type: Number as PropType<BubbleMenuPluginProps['resizeDelay']>,\n default: undefined,\n },\n\n options: {\n type: Object as PropType<BubbleMenuPluginProps['options']>,\n default: () => ({}),\n },\n\n appendTo: {\n type: [Object, Function] as PropType<BubbleMenuPluginProps['appendTo']>,\n default: undefined,\n },\n\n shouldShow: {\n type: Function as PropType<Exclude<Required<BubbleMenuPluginProps>['shouldShow'], null>>,\n default: null,\n },\n\n getReferencedVirtualElement: {\n type: Function as PropType<Exclude<Required<BubbleMenuPluginProps>['getReferencedVirtualElement'], null>>,\n default: undefined,\n },\n },\n\n setup(props, { slots, attrs }) {\n const root = ref<HTMLElement | null>(null)\n const resolvedPluginKey = props.pluginKey ?? new PluginKey('bubbleMenu')\n\n onMounted(() => {\n const { editor, options, resizeDelay, appendTo, shouldShow, getReferencedVirtualElement, updateDelay } = props\n\n const el = root.value\n\n if (!el) {\n return\n }\n\n el.style.visibility = 'hidden'\n el.style.position = 'absolute'\n\n // Remove element from DOM; plugin will re-parent it when shown\n el.remove()\n\n nextTick(() => {\n editor.registerPlugin(\n BubbleMenuPlugin({\n editor,\n element: el,\n options,\n pluginKey: resolvedPluginKey,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n }),\n )\n })\n })\n\n onBeforeUnmount(() => {\n const { editor } = props\n\n editor.unregisterPlugin(resolvedPluginKey)\n })\n\n // Vue owns this element; attrs are applied reactively by Vue\n // Plugin re-parents it when showing the menu\n return () => h('div', { ref: root, ...attrs }, slots.default?.())\n },\n})\n","import {\n type Middleware,\n arrow,\n autoPlacement,\n computePosition,\n flip,\n hide,\n inline,\n offset,\n shift,\n size,\n} from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { getText, getTextSerializersFromSchema, posToDOMRect } from '@tiptap/core'\nimport type { Node as ProsemirrorNode } from '@tiptap/pm/model'\nimport type { EditorState, Transaction } from '@tiptap/pm/state'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\n\nexport interface FloatingMenuPluginProps {\n /**\n * The plugin key for the floating menu.\n * @default 'floatingMenu'\n */\n pluginKey: PluginKey | string\n\n /**\n * The editor instance.\n * @default null\n */\n editor: Editor\n\n /**\n * The DOM element that contains your menu.\n * @default null\n */\n element: HTMLElement\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 250\n */\n updateDelay?: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 60\n */\n resizeDelay?: number\n\n /**\n * The DOM element to append your menu to. Default is the editor's parent element.\n *\n * Sometimes the menu needs to be appended to a different DOM context due to accessibility, clipping, or z-index issues.\n *\n * @type {HTMLElement}\n * @default null\n */\n appendTo?: HTMLElement | (() => HTMLElement)\n\n /**\n * A function that determines whether the menu should be shown or not.\n * If this function returns `false`, the menu will be hidden, otherwise it will be shown.\n */\n shouldShow?:\n | ((props: {\n editor: Editor\n view: EditorView\n state: EditorState\n oldState?: EditorState\n from: number\n to: number\n }) => boolean)\n | null\n\n /**\n * The options for the floating menu. Those are passed to Floating UI and include options for the placement, offset, flip, shift, arrow, size, autoPlacement,\n * hide, and inline middlewares.\n * @default {}\n * @see https://floating-ui.com/docs/computePosition#options\n */\n options?: {\n strategy?: 'absolute' | 'fixed'\n placement?:\n | 'top'\n | 'right'\n | 'bottom'\n | 'left'\n | 'top-start'\n | 'top-end'\n | 'right-start'\n | 'right-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n offset?: Parameters<typeof offset>[0] | boolean\n flip?: Parameters<typeof flip>[0] | boolean\n shift?: Parameters<typeof shift>[0] | boolean\n arrow?: Parameters<typeof arrow>[0] | false\n size?: Parameters<typeof size>[0] | boolean\n autoPlacement?: Parameters<typeof autoPlacement>[0] | boolean\n hide?: Parameters<typeof hide>[0] | boolean\n inline?: Parameters<typeof inline>[0] | boolean\n\n onShow?: () => void\n onHide?: () => void\n onUpdate?: () => void\n onDestroy?: () => void\n\n /**\n * The scrollable element that should be listened to when updating the position of the floating menu.\n * If not provided, the window will be used.\n * @type {HTMLElement | Window}\n */\n scrollTarget?: HTMLElement | Window\n }\n}\n\nexport type FloatingMenuViewProps = FloatingMenuPluginProps & {\n /**\n * The editor view.\n */\n view: EditorView\n}\n\nexport class FloatingMenuView {\n public editor: Editor\n\n public element: HTMLElement\n\n public view: EditorView\n\n public preventHide = false\n\n public pluginKey: PluginKey | string\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * @default 250\n */\n public updateDelay: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * @default 60\n */\n public resizeDelay: number\n\n public appendTo: HTMLElement | (() => HTMLElement) | undefined\n\n private updateDebounceTimer: number | undefined\n\n private resizeDebounceTimer: number | undefined\n\n private isVisible = false\n\n private scrollTarget: HTMLElement | Window = window\n\n private getTextContent(node: ProsemirrorNode) {\n return getText(node, { textSerializers: getTextSerializersFromSchema(this.editor.schema) })\n }\n\n public shouldShow: Exclude<FloatingMenuPluginProps['shouldShow'], null> = ({ view, state }) => {\n const { selection } = state\n const { $anchor, empty } = selection\n const isRootDepth = $anchor.depth === 1\n\n const isEmptyTextBlock =\n $anchor.parent.isTextblock &&\n !$anchor.parent.type.spec.code &&\n !$anchor.parent.textContent &&\n $anchor.parent.childCount === 0 &&\n !this.getTextContent($anchor.parent)\n\n if (!view.hasFocus() || !empty || !isRootDepth || !isEmptyTextBlock || !this.editor.isEditable) {\n return false\n }\n\n return true\n }\n\n private floatingUIOptions: NonNullable<FloatingMenuPluginProps['options']> = {\n strategy: 'absolute',\n placement: 'right',\n offset: 8,\n flip: {},\n shift: {},\n arrow: false,\n size: false,\n autoPlacement: false,\n hide: false,\n inline: false,\n }\n\n get middlewares() {\n const middlewares: Middleware[] = []\n\n if (this.floatingUIOptions.flip) {\n middlewares.push(flip(typeof this.floatingUIOptions.flip !== 'boolean' ? this.floatingUIOptions.flip : undefined))\n }\n\n if (this.floatingUIOptions.shift) {\n middlewares.push(\n shift(typeof this.floatingUIOptions.shift !== 'boolean' ? this.floatingUIOptions.shift : undefined),\n )\n }\n\n if (this.floatingUIOptions.offset) {\n middlewares.push(\n offset(typeof this.floatingUIOptions.offset !== 'boolean' ? this.floatingUIOptions.offset : undefined),\n )\n }\n\n if (this.floatingUIOptions.arrow) {\n middlewares.push(arrow(this.floatingUIOptions.arrow))\n }\n\n if (this.floatingUIOptions.size) {\n middlewares.push(size(typeof this.floatingUIOptions.size !== 'boolean' ? this.floatingUIOptions.size : undefined))\n }\n\n if (this.floatingUIOptions.autoPlacement) {\n middlewares.push(\n autoPlacement(\n typeof this.floatingUIOptions.autoPlacement !== 'boolean' ? this.floatingUIOptions.autoPlacement : undefined,\n ),\n )\n }\n\n if (this.floatingUIOptions.hide) {\n middlewares.push(hide(typeof this.floatingUIOptions.hide !== 'boolean' ? this.floatingUIOptions.hide : undefined))\n }\n\n if (this.floatingUIOptions.inline) {\n middlewares.push(\n inline(typeof this.floatingUIOptions.inline !== 'boolean' ? this.floatingUIOptions.inline : undefined),\n )\n }\n\n return middlewares\n }\n\n constructor({\n editor,\n element,\n view,\n pluginKey = 'floatingMenu',\n updateDelay = 250,\n resizeDelay = 60,\n options,\n appendTo,\n shouldShow,\n }: FloatingMenuViewProps) {\n this.editor = editor\n this.element = element\n this.view = view\n this.pluginKey = pluginKey\n this.updateDelay = updateDelay\n this.resizeDelay = resizeDelay\n this.appendTo = appendTo\n this.scrollTarget = options?.scrollTarget ?? window\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...options,\n }\n\n this.element.tabIndex = 0\n\n if (shouldShow) {\n this.shouldShow = shouldShow\n }\n\n this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.editor.on('focus', this.focusHandler)\n this.editor.on('blur', this.blurHandler)\n this.editor.on('transaction', this.transactionHandler)\n window.addEventListener('resize', this.resizeHandler)\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n\n this.update(view, view.state)\n\n if (this.getShouldShow()) {\n this.show()\n this.updatePosition()\n }\n }\n\n getShouldShow(oldState?: EditorState) {\n const { state } = this.view\n const { selection } = state\n\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n\n const shouldShow = this.shouldShow?.({\n editor: this.editor,\n view: this.view,\n state,\n oldState,\n from,\n to,\n })\n\n return shouldShow\n }\n\n updateHandler = (view: EditorView, selectionChanged: boolean, docChanged: boolean, oldState?: EditorState) => {\n const { composing } = view\n\n const isSame = !selectionChanged && !docChanged\n\n if (composing || isSame) {\n return\n }\n\n const shouldShow = this.getShouldShow(oldState)\n\n if (!shouldShow) {\n this.hide()\n\n return\n }\n\n this.updatePosition()\n this.show()\n }\n\n mousedownHandler = () => {\n this.preventHide = true\n }\n\n focusHandler = () => {\n // we use `setTimeout` to make sure `selection` is already updated\n setTimeout(() => this.update(this.editor.view))\n }\n\n blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.preventHide) {\n this.preventHide = false\n\n return\n }\n\n if (event?.relatedTarget && this.element.parentNode?.contains(event.relatedTarget as Node)) {\n return\n }\n\n if (event?.relatedTarget === this.editor.view.dom) {\n return\n }\n\n this.hide()\n }\n\n /**\n * Handles the transaction event to update the position of the floating menu.\n * This allows external code to trigger a position update via:\n * `editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'updatePosition'))`\n * The `pluginKey` defaults to `floatingMenu`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta(this.pluginKey)\n if (meta === 'updatePosition') {\n this.updatePosition()\n } else if (meta && typeof meta === 'object' && meta.type === 'updateOptions') {\n this.updateOptions(meta.options)\n } else if (meta === 'hide') {\n this.hide()\n } else if (meta === 'show') {\n this.updatePosition()\n this.show()\n }\n }\n\n updateOptions(newProps: Partial<Omit<FloatingMenuPluginProps, 'editor' | 'element' | 'pluginKey'>>) {\n if (newProps.updateDelay !== undefined) {\n this.updateDelay = newProps.updateDelay\n }\n\n if (newProps.resizeDelay !== undefined) {\n this.resizeDelay = newProps.resizeDelay\n }\n\n if (newProps.appendTo !== undefined) {\n this.appendTo = newProps.appendTo\n }\n\n if (newProps.shouldShow !== undefined) {\n if (newProps.shouldShow) {\n this.shouldShow = newProps.shouldShow\n }\n }\n\n if (newProps.options !== undefined) {\n // Handle scrollTarget change - need to remove old listener and add new one\n // Use nullish coalescing to default to window when scrollTarget is undefined/null\n const newScrollTarget = newProps.options.scrollTarget ?? window\n\n if (newScrollTarget !== this.scrollTarget) {\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.scrollTarget = newScrollTarget\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n }\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...newProps.options,\n }\n }\n }\n\n /**\n * Handles the window resize event to update the position of the floating menu.\n * It uses a debounce mechanism to prevent excessive updates.\n * The delay is defined by the `resizeDelay` property.\n */\n resizeHandler = () => {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer)\n }\n\n this.resizeDebounceTimer = window.setTimeout(() => {\n this.updatePosition()\n }, this.resizeDelay)\n }\n\n updatePosition() {\n const { selection } = this.editor.state\n\n const domRect = posToDOMRect(this.view, selection.from, selection.to)\n\n const virtualElement = {\n getBoundingClientRect: () => domRect,\n getClientRects: () => [domRect],\n }\n\n computePosition(virtualElement, this.element, {\n placement: this.floatingUIOptions.placement,\n strategy: this.floatingUIOptions.strategy,\n middleware: this.middlewares,\n }).then(({ x, y, strategy, middlewareData }) => {\n // Handle hide middleware - hide element if reference is hidden or element has escaped\n if (middlewareData.hide?.referenceHidden || middlewareData.hide?.escaped) {\n this.element.style.visibility = 'hidden'\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.width = 'max-content'\n this.element.style.position = strategy\n this.element.style.left = `${x}px`\n this.element.style.top = `${y}px`\n\n if (this.isVisible && this.floatingUIOptions.onUpdate) {\n this.floatingUIOptions.onUpdate()\n }\n })\n }\n\n update(view: EditorView, oldState?: EditorState) {\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }\n\n show() {\n if (this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.opacity = '1'\n\n // attach to appendTo or editor's parent element\n const appendToElement = typeof this.appendTo === 'function' ? this.appendTo() : this.appendTo\n ;(appendToElement ?? this.view.dom.parentElement)?.appendChild(this.element)\n\n if (this.floatingUIOptions.onShow) {\n this.floatingUIOptions.onShow()\n }\n\n this.isVisible = true\n }\n\n hide() {\n if (!this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'hidden'\n this.element.style.opacity = '0'\n // remove from the parent element\n this.element.remove()\n\n if (this.floatingUIOptions.onHide) {\n this.floatingUIOptions.onHide()\n }\n\n this.isVisible = false\n }\n\n destroy() {\n this.hide()\n this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true })\n window.removeEventListener('resize', this.resizeHandler)\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.editor.off('focus', this.focusHandler)\n this.editor.off('blur', this.blurHandler)\n this.editor.off('transaction', this.transactionHandler)\n\n if (this.floatingUIOptions.onDestroy) {\n this.floatingUIOptions.onDestroy()\n }\n }\n}\n\nexport const FloatingMenuPlugin = (options: FloatingMenuPluginProps) => {\n return new Plugin({\n key: typeof options.pluginKey === 'string' ? new PluginKey(options.pluginKey) : options.pluginKey,\n view: view => new FloatingMenuView({ view, ...options }),\n })\n}\n","import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { PropType } from 'vue'\nimport { defineComponent, h, onBeforeUnmount, onMounted, ref } from 'vue'\n\nexport const FloatingMenu = defineComponent({\n name: 'FloatingMenu',\n\n inheritAttrs: false,\n\n props: {\n pluginKey: {\n // TODO: TypeScript breaks :(\n // type: [String, Object as PropType<Exclude<FloatingMenuPluginProps['pluginKey'], string>>],\n type: null,\n default: undefined,\n },\n\n editor: {\n type: Object as PropType<FloatingMenuPluginProps['editor']>,\n required: true,\n },\n\n updateDelay: {\n type: Number as PropType<FloatingMenuPluginProps['updateDelay']>,\n default: undefined,\n },\n\n resizeDelay: {\n type: Number as PropType<FloatingMenuPluginProps['resizeDelay']>,\n default: undefined,\n },\n\n options: {\n type: Object as PropType<FloatingMenuPluginProps['options']>,\n default: () => ({}),\n },\n\n appendTo: {\n type: [Object, Function] as PropType<FloatingMenuPluginProps['appendTo']>,\n default: undefined,\n },\n\n shouldShow: {\n type: Function as PropType<Exclude<Required<FloatingMenuPluginProps>['shouldShow'], null>>,\n default: null,\n },\n },\n\n setup(props, { slots, attrs }) {\n const root = ref<HTMLElement | null>(null)\n const resolvedPluginKey = props.pluginKey ?? new PluginKey('floatingMenu')\n\n onMounted(() => {\n const { editor, updateDelay, resizeDelay, options, appendTo, shouldShow } = props\n\n const el = root.value\n\n if (!el) {\n return\n }\n\n el.style.visibility = 'hidden'\n el.style.position = 'absolute'\n\n // Remove element from DOM; plugin will re-parent it when shown\n el.remove()\n\n editor.registerPlugin(\n FloatingMenuPlugin({\n pluginKey: resolvedPluginKey,\n editor,\n element: el,\n updateDelay,\n resizeDelay,\n options,\n appendTo,\n shouldShow,\n }),\n )\n })\n\n onBeforeUnmount(() => {\n const { editor } = props\n\n editor.unregisterPlugin(resolvedPluginKey)\n })\n\n // Vue owns this element; attrs are applied reactively by Vue\n // Plugin re-parents it when showing the menu\n return () => h('div', { ref: root, ...attrs }, slots.default?.())\n },\n})\n"],"mappings":"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","names":["PluginKey","_a","arrow","autoPlacement","computePosition","flip","hide","inline","offset","shift","size","posToDOMRect","Plugin","PluginKey","PluginKey","defineComponent","h","onBeforeUnmount","onMounted","ref","_a"]}
|
|
1
|
+
{"version":3,"sources":["../../../extension-bubble-menu/src/bubble-menu-plugin.ts","../../src/menus/BubbleMenu.ts","../../../extension-floating-menu/src/floating-menu-plugin.ts","../../src/menus/FloatingMenu.ts"],"sourcesContent":["import {\n type Middleware,\n type VirtualElement,\n arrow,\n autoPlacement,\n computePosition,\n flip,\n hide,\n inline,\n offset,\n shift,\n size,\n} from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { isTextSelection, posToDOMRect } from '@tiptap/core'\nimport type { EditorState, PluginView, Transaction } from '@tiptap/pm/state'\nimport { NodeSelection, Plugin, PluginKey } from '@tiptap/pm/state'\nimport { CellSelection } from '@tiptap/pm/tables'\nimport type { EditorView } from '@tiptap/pm/view'\n\nfunction combineDOMRects(rect1: DOMRect, rect2: DOMRect): DOMRect {\n const top = Math.min(rect1.top, rect2.top)\n const bottom = Math.max(rect1.bottom, rect2.bottom)\n const left = Math.min(rect1.left, rect2.left)\n const right = Math.max(rect1.right, rect2.right)\n const width = right - left\n const height = bottom - top\n const x = left\n const y = top\n return new DOMRect(x, y, width, height)\n}\n\nexport interface BubbleMenuPluginProps {\n /**\n * The plugin key.\n * @type {PluginKey | string}\n * @default 'bubbleMenu'\n */\n pluginKey: PluginKey | string\n\n /**\n * The editor instance.\n */\n editor: Editor\n\n /**\n * The DOM element that contains your menu.\n * @type {HTMLElement}\n * @default null\n */\n element: HTMLElement\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 250\n */\n updateDelay?: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 60\n */\n resizeDelay?: number\n\n /**\n * A function that determines whether the menu should be shown or not.\n * If this function returns `false`, the menu will be hidden, otherwise it will be shown.\n */\n shouldShow?:\n | ((props: {\n editor: Editor\n element: HTMLElement\n view: EditorView\n state: EditorState\n oldState?: EditorState\n from: number\n to: number\n }) => boolean)\n | null\n\n /**\n * The DOM element to append your menu to. Default is the editor's parent element.\n *\n * Sometimes the menu needs to be appended to a different DOM context due to accessibility, clipping, or z-index issues.\n *\n * @type {HTMLElement}\n * @default null\n */\n appendTo?: HTMLElement | (() => HTMLElement)\n\n /**\n * A function that returns the virtual element for the menu.\n * This is useful when the menu needs to be positioned relative to a specific DOM element.\n * @type {() => VirtualElement | null}\n * @default Position based on the selection.\n */\n getReferencedVirtualElement?: () => VirtualElement | null\n\n /**\n * The options for the bubble menu. Those are passed to Floating UI and include options for the placement, offset, flip, shift, arrow, size, autoPlacement,\n * hide, and inline middlewares.\n * @default {}\n * @see https://floating-ui.com/docs/computePosition#options\n */\n options?: {\n strategy?: 'absolute' | 'fixed'\n placement?:\n | 'top'\n | 'right'\n | 'bottom'\n | 'left'\n | 'top-start'\n | 'top-end'\n | 'right-start'\n | 'right-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n offset?: Parameters<typeof offset>[0] | boolean\n flip?: Parameters<typeof flip>[0] | boolean\n shift?: Parameters<typeof shift>[0] | boolean\n arrow?: Parameters<typeof arrow>[0] | false\n size?: Parameters<typeof size>[0] | boolean\n autoPlacement?: Parameters<typeof autoPlacement>[0] | boolean\n hide?: Parameters<typeof hide>[0] | boolean\n inline?: Parameters<typeof inline>[0] | boolean\n\n onShow?: () => void\n onHide?: () => void\n onUpdate?: () => void\n onDestroy?: () => void\n\n /**\n * The scrollable element that should be listened to when updating the position of the bubble menu.\n * If not provided, the window will be used.\n * @type {HTMLElement | Window}\n */\n scrollTarget?: HTMLElement | Window\n }\n}\n\nexport type BubbleMenuViewProps = BubbleMenuPluginProps & {\n view: EditorView\n}\n\nexport class BubbleMenuView implements PluginView {\n public editor: Editor\n\n public element: HTMLElement\n\n public view: EditorView\n\n public preventHide = false\n\n public pluginKey: PluginKey | string\n\n public updateDelay: number\n\n public resizeDelay: number\n\n public appendTo: HTMLElement | (() => HTMLElement) | undefined\n\n public getReferencedVirtualElement: (() => VirtualElement | null) | undefined\n\n private updateDebounceTimer: number | undefined\n\n private resizeDebounceTimer: number | undefined\n\n private isVisible = false\n\n private scrollTarget: HTMLElement | Window = window\n\n private floatingUIOptions: NonNullable<BubbleMenuPluginProps['options']> = {\n strategy: 'absolute',\n placement: 'top',\n offset: 8,\n flip: {},\n shift: {},\n arrow: false,\n size: false,\n autoPlacement: false,\n hide: false,\n inline: false,\n onShow: undefined,\n onHide: undefined,\n onUpdate: undefined,\n onDestroy: undefined,\n }\n\n public shouldShow: Exclude<BubbleMenuPluginProps['shouldShow'], null> = ({ view, state, from, to }) => {\n const { doc, selection } = state\n const { empty } = selection\n\n // Sometime check for `empty` is not enough.\n // Doubleclick an empty paragraph returns a node size of 2.\n // So we check also for an empty text size.\n const isEmptyTextBlock = !doc.textBetween(from, to).length && isTextSelection(state.selection)\n\n // When clicking on a element inside the bubble menu the editor \"blur\" event\n // is called and the bubble menu item is focussed. In this case we should\n // consider the menu as part of the editor and keep showing the menu\n const isChildOfMenu = this.element.contains(document.activeElement)\n\n const hasEditorFocus = view.hasFocus() || isChildOfMenu\n\n if (!hasEditorFocus || empty || isEmptyTextBlock || !this.editor.isEditable) {\n return false\n }\n\n return true\n }\n\n get middlewares() {\n const middlewares: Middleware[] = []\n\n if (this.floatingUIOptions.flip) {\n middlewares.push(flip(typeof this.floatingUIOptions.flip !== 'boolean' ? this.floatingUIOptions.flip : undefined))\n }\n\n if (this.floatingUIOptions.shift) {\n middlewares.push(\n shift(typeof this.floatingUIOptions.shift !== 'boolean' ? this.floatingUIOptions.shift : undefined),\n )\n }\n\n if (this.floatingUIOptions.offset) {\n middlewares.push(\n offset(typeof this.floatingUIOptions.offset !== 'boolean' ? this.floatingUIOptions.offset : undefined),\n )\n }\n\n if (this.floatingUIOptions.arrow) {\n middlewares.push(arrow(this.floatingUIOptions.arrow))\n }\n\n if (this.floatingUIOptions.size) {\n middlewares.push(size(typeof this.floatingUIOptions.size !== 'boolean' ? this.floatingUIOptions.size : undefined))\n }\n\n if (this.floatingUIOptions.autoPlacement) {\n middlewares.push(\n autoPlacement(\n typeof this.floatingUIOptions.autoPlacement !== 'boolean' ? this.floatingUIOptions.autoPlacement : undefined,\n ),\n )\n }\n\n if (this.floatingUIOptions.hide) {\n middlewares.push(hide(typeof this.floatingUIOptions.hide !== 'boolean' ? this.floatingUIOptions.hide : undefined))\n }\n\n if (this.floatingUIOptions.inline) {\n middlewares.push(\n inline(typeof this.floatingUIOptions.inline !== 'boolean' ? this.floatingUIOptions.inline : undefined),\n )\n }\n\n return middlewares\n }\n\n private get virtualElement(): VirtualElement | undefined {\n const { selection } = this.editor.state\n\n const referencedVirtualElement = this.getReferencedVirtualElement?.()\n if (referencedVirtualElement) {\n return referencedVirtualElement\n }\n\n if (!this.view?.dom?.parentNode) {\n return\n }\n\n const domRect = posToDOMRect(this.view, selection.from, selection.to)\n let virtualElement = {\n getBoundingClientRect: () => domRect,\n getClientRects: () => [domRect],\n }\n\n if (selection instanceof NodeSelection) {\n let node = this.view.nodeDOM(selection.from) as HTMLElement\n\n const nodeViewWrapper = node.dataset.nodeViewWrapper ? node : node.querySelector('[data-node-view-wrapper]')\n\n if (nodeViewWrapper) {\n node = nodeViewWrapper as HTMLElement\n }\n\n if (node) {\n virtualElement = {\n getBoundingClientRect: () => node.getBoundingClientRect(),\n getClientRects: () => [node.getBoundingClientRect()],\n }\n }\n }\n\n // this is a special case for cell selections\n if (selection instanceof CellSelection) {\n const { $anchorCell, $headCell } = selection\n\n const from = $anchorCell ? $anchorCell.pos : $headCell!.pos\n const to = $headCell ? $headCell.pos : $anchorCell!.pos\n\n const fromDOM = this.view.nodeDOM(from)\n const toDOM = this.view.nodeDOM(to)\n\n if (!fromDOM || !toDOM) {\n return\n }\n\n const clientRect =\n fromDOM === toDOM\n ? (fromDOM as HTMLElement).getBoundingClientRect()\n : combineDOMRects(\n (fromDOM as HTMLElement).getBoundingClientRect(),\n (toDOM as HTMLElement).getBoundingClientRect(),\n )\n\n virtualElement = {\n getBoundingClientRect: () => clientRect,\n getClientRects: () => [clientRect],\n }\n }\n\n return virtualElement\n }\n\n constructor({\n editor,\n element,\n view,\n pluginKey = 'bubbleMenu',\n updateDelay = 250,\n resizeDelay = 60,\n shouldShow,\n appendTo,\n getReferencedVirtualElement,\n options,\n }: BubbleMenuViewProps) {\n this.editor = editor\n this.element = element\n this.view = view\n this.pluginKey = pluginKey\n this.updateDelay = updateDelay\n this.resizeDelay = resizeDelay\n this.appendTo = appendTo\n this.scrollTarget = options?.scrollTarget ?? window\n this.getReferencedVirtualElement = getReferencedVirtualElement\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...options,\n }\n\n this.element.tabIndex = 0\n\n if (shouldShow) {\n this.shouldShow = shouldShow\n }\n\n this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.addEventListener('dragstart', this.dragstartHandler)\n this.editor.on('focus', this.focusHandler)\n this.editor.on('blur', this.blurHandler)\n this.editor.on('transaction', this.transactionHandler)\n window.addEventListener('resize', this.resizeHandler)\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n\n this.update(view, view.state)\n\n if (this.getShouldShow()) {\n this.show()\n this.updatePosition()\n }\n }\n\n mousedownHandler = () => {\n this.preventHide = true\n }\n\n dragstartHandler = () => {\n this.hide()\n }\n\n /**\n * Handles the window resize event to update the position of the bubble menu.\n * It uses a debounce mechanism to prevent excessive updates.\n * The delay is defined by the `resizeDelay` property.\n */\n resizeHandler = () => {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer)\n }\n\n this.resizeDebounceTimer = window.setTimeout(() => {\n this.updatePosition()\n }, this.resizeDelay)\n }\n\n focusHandler = () => {\n // we use `setTimeout` to make sure `selection` is already updated\n setTimeout(() => this.update(this.editor.view))\n }\n\n blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.editor.isDestroyed) {\n this.destroy()\n return\n }\n\n if (this.preventHide) {\n this.preventHide = false\n\n return\n }\n\n if (event?.relatedTarget && this.element.parentNode?.contains(event.relatedTarget as Node)) {\n return\n }\n\n if (event?.relatedTarget === this.editor.view.dom) {\n return\n }\n\n this.hide()\n }\n\n updatePosition() {\n if (!this.isVisible) {\n return\n }\n\n const virtualElement = this.virtualElement\n\n if (!virtualElement) {\n return\n }\n\n computePosition(virtualElement, this.element, {\n placement: this.floatingUIOptions.placement,\n strategy: this.floatingUIOptions.strategy,\n middleware: this.middlewares,\n }).then(({ x, y, strategy, middlewareData }) => {\n if (!this.isVisible || this.editor.isDestroyed || !this.element.isConnected) {\n return\n }\n\n // Handle hide middleware - hide element if reference is hidden or element has escaped\n if (middlewareData.hide?.referenceHidden || middlewareData.hide?.escaped) {\n this.element.style.visibility = 'hidden'\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.width = 'max-content'\n this.element.style.position = strategy\n this.element.style.left = `${x}px`\n this.element.style.top = `${y}px`\n\n if (this.isVisible && this.floatingUIOptions.onUpdate) {\n this.floatingUIOptions.onUpdate()\n }\n })\n }\n\n update(view: EditorView, oldState?: EditorState) {\n const { state } = view\n const hasValidSelection = state.selection.from !== state.selection.to\n\n if (this.updateDelay > 0 && hasValidSelection) {\n this.handleDebouncedUpdate(view, oldState)\n return\n }\n\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }\n\n handleDebouncedUpdate = (view: EditorView, oldState?: EditorState) => {\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n if (!selectionChanged && !docChanged) {\n return\n }\n\n if (this.updateDebounceTimer) {\n clearTimeout(this.updateDebounceTimer)\n }\n\n this.updateDebounceTimer = window.setTimeout(() => {\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }, this.updateDelay)\n }\n\n getShouldShow(oldState?: EditorState) {\n const { state } = this.view\n const { selection } = state\n\n // support for CellSelections\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n\n const shouldShow = this.shouldShow?.({\n editor: this.editor,\n element: this.element,\n view: this.view,\n state,\n oldState,\n from,\n to,\n })\n\n return shouldShow || false\n }\n\n updateHandler = (view: EditorView, selectionChanged: boolean, docChanged: boolean, oldState?: EditorState) => {\n const { composing } = view\n\n const isSame = !selectionChanged && !docChanged\n\n if (composing || isSame) {\n return\n }\n\n const shouldShow = this.getShouldShow(oldState)\n\n if (!shouldShow) {\n this.hide()\n\n return\n }\n\n this.show()\n this.updatePosition()\n }\n\n show() {\n if (this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.opacity = '1'\n\n // attach to appendTo or editor's parent element\n const appendToElement = typeof this.appendTo === 'function' ? this.appendTo() : this.appendTo\n ;(appendToElement ?? this.view.dom.parentElement)?.appendChild(this.element)\n\n if (this.floatingUIOptions.onShow) {\n this.floatingUIOptions.onShow()\n }\n\n this.isVisible = true\n }\n\n hide() {\n if (!this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'hidden'\n this.element.style.opacity = '0'\n // remove from the parent element\n this.element.remove()\n\n if (this.floatingUIOptions.onHide) {\n this.floatingUIOptions.onHide()\n }\n\n this.isVisible = false\n }\n\n /**\n * Handles the transaction event to update the position of the bubble menu.\n * This allows external code to trigger a position update via:\n * `editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'updatePosition'))`\n * The `pluginKey` defaults to `bubbleMenu`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta(this.pluginKey)\n if (meta === 'updatePosition') {\n this.updatePosition()\n } else if (meta && typeof meta === 'object' && meta.type === 'updateOptions') {\n this.updateOptions(meta.options)\n } else if (meta === 'hide') {\n this.hide()\n } else if (meta === 'show') {\n this.updatePosition()\n this.show()\n }\n }\n\n updateOptions(newProps: Partial<Omit<BubbleMenuPluginProps, 'editor' | 'element' | 'pluginKey'>>) {\n if (newProps.updateDelay !== undefined) {\n this.updateDelay = newProps.updateDelay\n }\n\n if (newProps.resizeDelay !== undefined) {\n this.resizeDelay = newProps.resizeDelay\n }\n\n if (newProps.appendTo !== undefined) {\n this.appendTo = newProps.appendTo\n }\n\n if (newProps.getReferencedVirtualElement !== undefined) {\n this.getReferencedVirtualElement = newProps.getReferencedVirtualElement\n }\n\n if (newProps.shouldShow !== undefined) {\n if (newProps.shouldShow) {\n this.shouldShow = newProps.shouldShow\n }\n }\n\n if (newProps.options !== undefined) {\n // Handle scrollTarget change - need to remove old listener and add new one\n // Use nullish coalescing to default to window when scrollTarget is undefined/null\n const newScrollTarget = newProps.options.scrollTarget ?? window\n\n if (newScrollTarget !== this.scrollTarget) {\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.scrollTarget = newScrollTarget\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n }\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...newProps.options,\n }\n }\n }\n\n destroy() {\n this.hide()\n this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.removeEventListener('dragstart', this.dragstartHandler)\n window.removeEventListener('resize', this.resizeHandler)\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.editor.off('focus', this.focusHandler)\n this.editor.off('blur', this.blurHandler)\n this.editor.off('transaction', this.transactionHandler)\n\n if (this.floatingUIOptions.onDestroy) {\n this.floatingUIOptions.onDestroy()\n }\n }\n}\n\nexport const BubbleMenuPlugin = (options: BubbleMenuPluginProps) => {\n return new Plugin({\n key: typeof options.pluginKey === 'string' ? new PluginKey(options.pluginKey) : options.pluginKey,\n view: view => new BubbleMenuView({ view, ...options }),\n })\n}\n","import type { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'\nimport { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { PropType } from 'vue'\nimport { defineComponent, h, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'\n\nexport const BubbleMenu = defineComponent({\n name: 'BubbleMenu',\n\n inheritAttrs: false,\n\n props: {\n pluginKey: {\n type: [String, Object] as PropType<BubbleMenuPluginProps['pluginKey']>,\n default: undefined,\n },\n\n editor: {\n type: Object as PropType<BubbleMenuPluginProps['editor']>,\n required: true,\n },\n\n updateDelay: {\n type: Number as PropType<BubbleMenuPluginProps['updateDelay']>,\n default: undefined,\n },\n\n resizeDelay: {\n type: Number as PropType<BubbleMenuPluginProps['resizeDelay']>,\n default: undefined,\n },\n\n options: {\n type: Object as PropType<BubbleMenuPluginProps['options']>,\n default: () => ({}),\n },\n\n appendTo: {\n type: [Object, Function] as PropType<BubbleMenuPluginProps['appendTo']>,\n default: undefined,\n },\n\n shouldShow: {\n type: Function as PropType<Exclude<Required<BubbleMenuPluginProps>['shouldShow'], null>>,\n default: null,\n },\n\n getReferencedVirtualElement: {\n type: Function as PropType<Exclude<Required<BubbleMenuPluginProps>['getReferencedVirtualElement'], null>>,\n default: undefined,\n },\n },\n\n setup(props, { slots, attrs }) {\n const root = ref<HTMLElement | null>(null)\n const resolvedPluginKey = props.pluginKey ?? new PluginKey('bubbleMenu')\n\n onMounted(() => {\n const { editor, options, resizeDelay, appendTo, shouldShow, getReferencedVirtualElement, updateDelay } = props\n\n const el = root.value\n\n if (!el) {\n return\n }\n\n el.style.visibility = 'hidden'\n el.style.position = 'absolute'\n\n // Remove element from DOM; plugin will re-parent it when shown\n el.remove()\n\n nextTick(() => {\n editor.registerPlugin(\n BubbleMenuPlugin({\n editor,\n element: el,\n options,\n pluginKey: resolvedPluginKey,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n }),\n )\n })\n })\n\n onBeforeUnmount(() => {\n const { editor } = props\n\n editor.unregisterPlugin(resolvedPluginKey)\n })\n\n // Vue owns this element; attrs are applied reactively by Vue\n // Plugin re-parents it when showing the menu\n return () => h('div', { ref: root, ...attrs }, slots.default?.())\n },\n})\n","import {\n type Middleware,\n arrow,\n autoPlacement,\n computePosition,\n flip,\n hide,\n inline,\n offset,\n shift,\n size,\n} from '@floating-ui/dom'\nimport type { Editor } from '@tiptap/core'\nimport { getText, getTextSerializersFromSchema, posToDOMRect } from '@tiptap/core'\nimport type { Node as ProsemirrorNode } from '@tiptap/pm/model'\nimport type { EditorState, Transaction } from '@tiptap/pm/state'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\n\nexport interface FloatingMenuPluginProps {\n /**\n * The plugin key for the floating menu.\n * @default 'floatingMenu'\n */\n pluginKey: PluginKey | string\n\n /**\n * The editor instance.\n * @default null\n */\n editor: Editor\n\n /**\n * The DOM element that contains your menu.\n * @default null\n */\n element: HTMLElement\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 250\n */\n updateDelay?: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 60\n */\n resizeDelay?: number\n\n /**\n * The DOM element to append your menu to. Default is the editor's parent element.\n *\n * Sometimes the menu needs to be appended to a different DOM context due to accessibility, clipping, or z-index issues.\n *\n * @type {HTMLElement}\n * @default null\n */\n appendTo?: HTMLElement | (() => HTMLElement)\n\n /**\n * A function that determines whether the menu should be shown or not.\n * If this function returns `false`, the menu will be hidden, otherwise it will be shown.\n */\n shouldShow?:\n | ((props: {\n editor: Editor\n view: EditorView\n state: EditorState\n oldState?: EditorState\n from: number\n to: number\n }) => boolean)\n | null\n\n /**\n * The options for the floating menu. Those are passed to Floating UI and include options for the placement, offset, flip, shift, arrow, size, autoPlacement,\n * hide, and inline middlewares.\n * @default {}\n * @see https://floating-ui.com/docs/computePosition#options\n */\n options?: {\n strategy?: 'absolute' | 'fixed'\n placement?:\n | 'top'\n | 'right'\n | 'bottom'\n | 'left'\n | 'top-start'\n | 'top-end'\n | 'right-start'\n | 'right-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n offset?: Parameters<typeof offset>[0] | boolean\n flip?: Parameters<typeof flip>[0] | boolean\n shift?: Parameters<typeof shift>[0] | boolean\n arrow?: Parameters<typeof arrow>[0] | false\n size?: Parameters<typeof size>[0] | boolean\n autoPlacement?: Parameters<typeof autoPlacement>[0] | boolean\n hide?: Parameters<typeof hide>[0] | boolean\n inline?: Parameters<typeof inline>[0] | boolean\n\n onShow?: () => void\n onHide?: () => void\n onUpdate?: () => void\n onDestroy?: () => void\n\n /**\n * The scrollable element that should be listened to when updating the position of the floating menu.\n * If not provided, the window will be used.\n * @type {HTMLElement | Window}\n */\n scrollTarget?: HTMLElement | Window\n }\n}\n\nexport type FloatingMenuViewProps = FloatingMenuPluginProps & {\n /**\n * The editor view.\n */\n view: EditorView\n}\n\nexport class FloatingMenuView {\n public editor: Editor\n\n public element: HTMLElement\n\n public view: EditorView\n\n public preventHide = false\n\n public pluginKey: PluginKey | string\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * @default 250\n */\n public updateDelay: number\n\n /**\n * The delay in milliseconds before the menu position should be updated on window resize.\n * @default 60\n */\n public resizeDelay: number\n\n public appendTo: HTMLElement | (() => HTMLElement) | undefined\n\n private updateDebounceTimer: number | undefined\n\n private resizeDebounceTimer: number | undefined\n\n private isVisible = false\n\n private scrollTarget: HTMLElement | Window = window\n\n private getTextContent(node: ProsemirrorNode) {\n return getText(node, { textSerializers: getTextSerializersFromSchema(this.editor.schema) })\n }\n\n public shouldShow: Exclude<FloatingMenuPluginProps['shouldShow'], null> = ({ view, state }) => {\n const { selection } = state\n const { $anchor, empty } = selection\n const isRootDepth = $anchor.depth === 1\n\n const isEmptyTextBlock =\n $anchor.parent.isTextblock &&\n !$anchor.parent.type.spec.code &&\n !$anchor.parent.textContent &&\n $anchor.parent.childCount === 0 &&\n !this.getTextContent($anchor.parent)\n\n if (!view.hasFocus() || !empty || !isRootDepth || !isEmptyTextBlock || !this.editor.isEditable) {\n return false\n }\n\n return true\n }\n\n private floatingUIOptions: NonNullable<FloatingMenuPluginProps['options']> = {\n strategy: 'absolute',\n placement: 'right',\n offset: 8,\n flip: {},\n shift: {},\n arrow: false,\n size: false,\n autoPlacement: false,\n hide: false,\n inline: false,\n }\n\n get middlewares() {\n const middlewares: Middleware[] = []\n\n if (this.floatingUIOptions.flip) {\n middlewares.push(flip(typeof this.floatingUIOptions.flip !== 'boolean' ? this.floatingUIOptions.flip : undefined))\n }\n\n if (this.floatingUIOptions.shift) {\n middlewares.push(\n shift(typeof this.floatingUIOptions.shift !== 'boolean' ? this.floatingUIOptions.shift : undefined),\n )\n }\n\n if (this.floatingUIOptions.offset) {\n middlewares.push(\n offset(typeof this.floatingUIOptions.offset !== 'boolean' ? this.floatingUIOptions.offset : undefined),\n )\n }\n\n if (this.floatingUIOptions.arrow) {\n middlewares.push(arrow(this.floatingUIOptions.arrow))\n }\n\n if (this.floatingUIOptions.size) {\n middlewares.push(size(typeof this.floatingUIOptions.size !== 'boolean' ? this.floatingUIOptions.size : undefined))\n }\n\n if (this.floatingUIOptions.autoPlacement) {\n middlewares.push(\n autoPlacement(\n typeof this.floatingUIOptions.autoPlacement !== 'boolean' ? this.floatingUIOptions.autoPlacement : undefined,\n ),\n )\n }\n\n if (this.floatingUIOptions.hide) {\n middlewares.push(hide(typeof this.floatingUIOptions.hide !== 'boolean' ? this.floatingUIOptions.hide : undefined))\n }\n\n if (this.floatingUIOptions.inline) {\n middlewares.push(\n inline(typeof this.floatingUIOptions.inline !== 'boolean' ? this.floatingUIOptions.inline : undefined),\n )\n }\n\n return middlewares\n }\n\n constructor({\n editor,\n element,\n view,\n pluginKey = 'floatingMenu',\n updateDelay = 250,\n resizeDelay = 60,\n options,\n appendTo,\n shouldShow,\n }: FloatingMenuViewProps) {\n this.editor = editor\n this.element = element\n this.view = view\n this.pluginKey = pluginKey\n this.updateDelay = updateDelay\n this.resizeDelay = resizeDelay\n this.appendTo = appendTo\n this.scrollTarget = options?.scrollTarget ?? window\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...options,\n }\n\n this.element.tabIndex = 0\n\n if (shouldShow) {\n this.shouldShow = shouldShow\n }\n\n this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.editor.on('focus', this.focusHandler)\n this.editor.on('blur', this.blurHandler)\n this.editor.on('transaction', this.transactionHandler)\n window.addEventListener('resize', this.resizeHandler)\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n\n this.update(view, view.state)\n\n if (this.getShouldShow()) {\n this.show()\n this.updatePosition()\n }\n }\n\n getShouldShow(oldState?: EditorState) {\n const { state } = this.view\n const { selection } = state\n\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n\n const shouldShow = this.shouldShow?.({\n editor: this.editor,\n view: this.view,\n state,\n oldState,\n from,\n to,\n })\n\n return shouldShow\n }\n\n updateHandler = (view: EditorView, selectionChanged: boolean, docChanged: boolean, oldState?: EditorState) => {\n const { composing } = view\n\n const isSame = !selectionChanged && !docChanged\n\n if (composing || isSame) {\n return\n }\n\n const shouldShow = this.getShouldShow(oldState)\n\n if (!shouldShow) {\n this.hide()\n\n return\n }\n\n this.updatePosition()\n this.show()\n }\n\n mousedownHandler = () => {\n this.preventHide = true\n }\n\n focusHandler = () => {\n // we use `setTimeout` to make sure `selection` is already updated\n setTimeout(() => this.update(this.editor.view))\n }\n\n blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.preventHide) {\n this.preventHide = false\n\n return\n }\n\n if (event?.relatedTarget && this.element.parentNode?.contains(event.relatedTarget as Node)) {\n return\n }\n\n if (event?.relatedTarget === this.editor.view.dom) {\n return\n }\n\n this.hide()\n }\n\n /**\n * Handles the transaction event to update the position of the floating menu.\n * This allows external code to trigger a position update via:\n * `editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'updatePosition'))`\n * The `pluginKey` defaults to `floatingMenu`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta(this.pluginKey)\n if (meta === 'updatePosition') {\n this.updatePosition()\n } else if (meta && typeof meta === 'object' && meta.type === 'updateOptions') {\n this.updateOptions(meta.options)\n } else if (meta === 'hide') {\n this.hide()\n } else if (meta === 'show') {\n this.updatePosition()\n this.show()\n }\n }\n\n updateOptions(newProps: Partial<Omit<FloatingMenuPluginProps, 'editor' | 'element' | 'pluginKey'>>) {\n if (newProps.updateDelay !== undefined) {\n this.updateDelay = newProps.updateDelay\n }\n\n if (newProps.resizeDelay !== undefined) {\n this.resizeDelay = newProps.resizeDelay\n }\n\n if (newProps.appendTo !== undefined) {\n this.appendTo = newProps.appendTo\n }\n\n if (newProps.shouldShow !== undefined) {\n if (newProps.shouldShow) {\n this.shouldShow = newProps.shouldShow\n }\n }\n\n if (newProps.options !== undefined) {\n // Handle scrollTarget change - need to remove old listener and add new one\n // Use nullish coalescing to default to window when scrollTarget is undefined/null\n const newScrollTarget = newProps.options.scrollTarget ?? window\n\n if (newScrollTarget !== this.scrollTarget) {\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.scrollTarget = newScrollTarget\n this.scrollTarget.addEventListener('scroll', this.resizeHandler)\n }\n\n this.floatingUIOptions = {\n ...this.floatingUIOptions,\n ...newProps.options,\n }\n }\n }\n\n /**\n * Handles the window resize event to update the position of the floating menu.\n * It uses a debounce mechanism to prevent excessive updates.\n * The delay is defined by the `resizeDelay` property.\n */\n resizeHandler = () => {\n if (this.resizeDebounceTimer) {\n clearTimeout(this.resizeDebounceTimer)\n }\n\n this.resizeDebounceTimer = window.setTimeout(() => {\n this.updatePosition()\n }, this.resizeDelay)\n }\n\n updatePosition() {\n if (!this.view?.dom?.parentNode) {\n return\n }\n\n const { selection } = this.editor.state\n\n const domRect = posToDOMRect(this.view, selection.from, selection.to)\n\n const virtualElement = {\n getBoundingClientRect: () => domRect,\n getClientRects: () => [domRect],\n }\n\n computePosition(virtualElement, this.element, {\n placement: this.floatingUIOptions.placement,\n strategy: this.floatingUIOptions.strategy,\n middleware: this.middlewares,\n }).then(({ x, y, strategy, middlewareData }) => {\n // Handle hide middleware - hide element if reference is hidden or element has escaped\n if (middlewareData.hide?.referenceHidden || middlewareData.hide?.escaped) {\n this.element.style.visibility = 'hidden'\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.width = 'max-content'\n this.element.style.position = strategy\n this.element.style.left = `${x}px`\n this.element.style.top = `${y}px`\n\n if (this.isVisible && this.floatingUIOptions.onUpdate) {\n this.floatingUIOptions.onUpdate()\n }\n })\n }\n\n update(view: EditorView, oldState?: EditorState) {\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }\n\n show() {\n if (this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'visible'\n this.element.style.opacity = '1'\n\n // attach to appendTo or editor's parent element\n const appendToElement = typeof this.appendTo === 'function' ? this.appendTo() : this.appendTo\n ;(appendToElement ?? this.view.dom.parentElement)?.appendChild(this.element)\n\n if (this.floatingUIOptions.onShow) {\n this.floatingUIOptions.onShow()\n }\n\n this.isVisible = true\n }\n\n hide() {\n if (!this.isVisible) {\n return\n }\n\n this.element.style.visibility = 'hidden'\n this.element.style.opacity = '0'\n // remove from the parent element\n this.element.remove()\n\n if (this.floatingUIOptions.onHide) {\n this.floatingUIOptions.onHide()\n }\n\n this.isVisible = false\n }\n\n destroy() {\n this.hide()\n this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true })\n window.removeEventListener('resize', this.resizeHandler)\n this.scrollTarget.removeEventListener('scroll', this.resizeHandler)\n this.editor.off('focus', this.focusHandler)\n this.editor.off('blur', this.blurHandler)\n this.editor.off('transaction', this.transactionHandler)\n\n if (this.floatingUIOptions.onDestroy) {\n this.floatingUIOptions.onDestroy()\n }\n }\n}\n\nexport const FloatingMenuPlugin = (options: FloatingMenuPluginProps) => {\n return new Plugin({\n key: typeof options.pluginKey === 'string' ? new PluginKey(options.pluginKey) : options.pluginKey,\n view: view => new FloatingMenuView({ view, ...options }),\n })\n}\n","import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { PropType } from 'vue'\nimport { defineComponent, h, onBeforeUnmount, onMounted, ref } from 'vue'\n\nexport const FloatingMenu = defineComponent({\n name: 'FloatingMenu',\n\n inheritAttrs: false,\n\n props: {\n pluginKey: {\n // TODO: TypeScript breaks :(\n // type: [String, Object as PropType<Exclude<FloatingMenuPluginProps['pluginKey'], string>>],\n type: null,\n default: undefined,\n },\n\n editor: {\n type: Object as PropType<FloatingMenuPluginProps['editor']>,\n required: true,\n },\n\n updateDelay: {\n type: Number as PropType<FloatingMenuPluginProps['updateDelay']>,\n default: undefined,\n },\n\n resizeDelay: {\n type: Number as PropType<FloatingMenuPluginProps['resizeDelay']>,\n default: undefined,\n },\n\n options: {\n type: Object as PropType<FloatingMenuPluginProps['options']>,\n default: () => ({}),\n },\n\n appendTo: {\n type: [Object, Function] as PropType<FloatingMenuPluginProps['appendTo']>,\n default: undefined,\n },\n\n shouldShow: {\n type: Function as PropType<Exclude<Required<FloatingMenuPluginProps>['shouldShow'], null>>,\n default: null,\n },\n },\n\n setup(props, { slots, attrs }) {\n const root = ref<HTMLElement | null>(null)\n const resolvedPluginKey = props.pluginKey ?? new PluginKey('floatingMenu')\n\n onMounted(() => {\n const { editor, updateDelay, resizeDelay, options, appendTo, shouldShow } = props\n\n const el = root.value\n\n if (!el) {\n return\n }\n\n el.style.visibility = 'hidden'\n el.style.position = 'absolute'\n\n // Remove element from DOM; plugin will re-parent it when shown\n el.remove()\n\n editor.registerPlugin(\n FloatingMenuPlugin({\n pluginKey: resolvedPluginKey,\n editor,\n element: el,\n updateDelay,\n resizeDelay,\n options,\n appendTo,\n shouldShow,\n }),\n )\n })\n\n onBeforeUnmount(() => {\n const { editor } = props\n\n editor.unregisterPlugin(resolvedPluginKey)\n })\n\n // Vue owns this element; attrs are applied reactively by Vue\n // Plugin re-parents it when showing the menu\n return () => h('div', { ref: root, ...attrs }, slots.default?.())\n },\n})\n"],"mappings":"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","names":["PluginKey","_a","arrow","autoPlacement","computePosition","flip","hide","inline","offset","shift","size","posToDOMRect","Plugin","PluginKey","_a","_b","PluginKey","defineComponent","h","onBeforeUnmount","onMounted","ref","_a"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/vue-3",
|
|
3
3
|
"description": "Vue components for tiptap",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.23.1",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -40,18 +40,18 @@
|
|
|
40
40
|
],
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"vue": "^3.5.13",
|
|
43
|
-
"@tiptap/core": "^3.
|
|
44
|
-
"@tiptap/pm": "^3.
|
|
43
|
+
"@tiptap/core": "^3.23.1",
|
|
44
|
+
"@tiptap/pm": "^3.23.1"
|
|
45
45
|
},
|
|
46
46
|
"optionalDependencies": {
|
|
47
|
-
"@tiptap/extension-
|
|
48
|
-
"@tiptap/extension-
|
|
47
|
+
"@tiptap/extension-bubble-menu": "^3.23.1",
|
|
48
|
+
"@tiptap/extension-floating-menu": "^3.23.1"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"vue": "^3.0.0",
|
|
52
52
|
"@floating-ui/dom": "^1.0.0",
|
|
53
|
-
"@tiptap/core": "3.
|
|
54
|
-
"@tiptap/pm": "3.
|
|
53
|
+
"@tiptap/core": "3.23.1",
|
|
54
|
+
"@tiptap/pm": "3.23.1"
|
|
55
55
|
},
|
|
56
56
|
"repository": {
|
|
57
57
|
"type": "git",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-underscore-dangle */
|
|
2
2
|
import type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'
|
|
3
|
-
import { cancelPositionCheck, NodeView, schedulePositionCheck } from '@tiptap/core'
|
|
3
|
+
import { cancelPositionCheck, isNodeViewSelected, NodeView, schedulePositionCheck } from '@tiptap/core'
|
|
4
4
|
import type { Node as ProseMirrorNode } from '@tiptap/pm/model'
|
|
5
5
|
import type { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'
|
|
6
6
|
import type { Component, PropType, Ref } from 'vue'
|
|
@@ -219,14 +219,20 @@ class VueNodeView extends NodeView<Component, Editor, VueNodeViewRendererOptions
|
|
|
219
219
|
* If it is, call `selectNode`, otherwise call `deselectNode`.
|
|
220
220
|
*/
|
|
221
221
|
handleSelectionUpdate() {
|
|
222
|
-
const { from, to } = this.editor.state.selection
|
|
223
222
|
const pos = this.getPos()
|
|
224
223
|
|
|
225
224
|
if (typeof pos !== 'number') {
|
|
226
225
|
return
|
|
227
226
|
}
|
|
228
227
|
|
|
229
|
-
|
|
228
|
+
const isSelected = isNodeViewSelected({
|
|
229
|
+
selection: this.editor.state.selection,
|
|
230
|
+
pos,
|
|
231
|
+
nodeSize: this.node.nodeSize,
|
|
232
|
+
selectedOnTextSelection: this.options.selectedOnTextSelection,
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
if (isSelected) {
|
|
230
236
|
if (this.renderer.props.selected) {
|
|
231
237
|
return
|
|
232
238
|
}
|