@tiptap/vue-3 3.17.0 → 3.17.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 +14 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -7
- package/dist/index.d.ts +5 -7
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/menus/index.cjs +14 -2
- package/dist/menus/index.cjs.map +1 -1
- package/dist/menus/index.js +14 -2
- package/dist/menus/index.js.map +1 -1
- package/package.json +7 -7
- package/src/VueRenderer.ts +18 -0
package/dist/index.cjs
CHANGED
|
@@ -232,6 +232,10 @@ var import_vue7 = require("vue");
|
|
|
232
232
|
var import_vue6 = require("vue");
|
|
233
233
|
var VueRenderer = class {
|
|
234
234
|
constructor(component, { props = {}, editor }) {
|
|
235
|
+
/**
|
|
236
|
+
* Flag to track if the renderer has been destroyed, preventing queued or asynchronous renders from executing after teardown.
|
|
237
|
+
*/
|
|
238
|
+
this.destroyed = false;
|
|
235
239
|
this.editor = editor;
|
|
236
240
|
this.component = (0, import_vue6.markRaw)(component);
|
|
237
241
|
this.el = document.createElement("div");
|
|
@@ -249,6 +253,9 @@ var VueRenderer = class {
|
|
|
249
253
|
return (_d = (_c = this.renderedComponent.vNode) == null ? void 0 : _c.component) == null ? void 0 : _d.proxy;
|
|
250
254
|
}
|
|
251
255
|
renderComponent() {
|
|
256
|
+
if (this.destroyed) {
|
|
257
|
+
return this.renderedComponent;
|
|
258
|
+
}
|
|
252
259
|
let vNode = (0, import_vue6.h)(this.component, this.props);
|
|
253
260
|
if (this.editor.appContext) {
|
|
254
261
|
vNode.appContext = this.editor.appContext;
|
|
@@ -266,12 +273,19 @@ var VueRenderer = class {
|
|
|
266
273
|
return { vNode, destroy, el: this.el ? this.el.firstElementChild : null };
|
|
267
274
|
}
|
|
268
275
|
updateProps(props = {}) {
|
|
276
|
+
if (this.destroyed) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
269
279
|
Object.entries(props).forEach(([key, value]) => {
|
|
270
280
|
this.props[key] = value;
|
|
271
281
|
});
|
|
272
282
|
this.renderComponent();
|
|
273
283
|
}
|
|
274
284
|
destroy() {
|
|
285
|
+
if (this.destroyed) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
this.destroyed = true;
|
|
275
289
|
this.renderedComponent.destroy();
|
|
276
290
|
}
|
|
277
291
|
};
|
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 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 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 Object.entries(props).forEach(([key, value]) => {\n this.props[key] = value\n })\n this.renderComponent()\n }\n\n destroy(): void {\n this.renderedComponent.destroy()\n }\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'\nimport { NodeView } 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 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.extension,\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\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\n return this.options.update({\n oldNode,\n oldDecorations,\n newNode: node,\n newDecorations: decorations,\n oldInnerDecorations,\n innerDecorations,\n updateProps: () => rerenderComponent({ node, decorations, innerDecorations }),\n })\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {\n return true\n }\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n\n rerenderComponent({ node, decorations, innerDecorations })\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}\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 { NodeView } 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 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.extension,\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\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\n return this.options.update({\n oldNode,\n oldDecorations,\n newNode: node,\n newDecorations: decorations,\n oldInnerDecorations,\n innerDecorations,\n updateProps: () => rerenderComponent({ node, decorations, innerDecorations }),\n })\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {\n return true\n }\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n\n rerenderComponent({ node, decorations, innerDecorations })\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}\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.d.cts
CHANGED
|
@@ -92,16 +92,14 @@ declare class VueRenderer {
|
|
|
92
92
|
component: Component;
|
|
93
93
|
el: Element | null;
|
|
94
94
|
props: Record<string, any>;
|
|
95
|
+
/**
|
|
96
|
+
* Flag to track if the renderer has been destroyed, preventing queued or asynchronous renders from executing after teardown.
|
|
97
|
+
*/
|
|
98
|
+
destroyed: boolean;
|
|
95
99
|
constructor(component: Component, { props, editor }: VueRendererOptions);
|
|
96
100
|
get element(): Element | null;
|
|
97
101
|
get ref(): any;
|
|
98
|
-
renderComponent():
|
|
99
|
-
vNode: vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
100
|
-
[key: string]: any;
|
|
101
|
-
}>;
|
|
102
|
-
destroy: () => void;
|
|
103
|
-
el: Element | null;
|
|
104
|
-
};
|
|
102
|
+
renderComponent(): RenderedComponent;
|
|
105
103
|
updateProps(props?: Record<string, any>): void;
|
|
106
104
|
destroy(): void;
|
|
107
105
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -92,16 +92,14 @@ declare class VueRenderer {
|
|
|
92
92
|
component: Component;
|
|
93
93
|
el: Element | null;
|
|
94
94
|
props: Record<string, any>;
|
|
95
|
+
/**
|
|
96
|
+
* Flag to track if the renderer has been destroyed, preventing queued or asynchronous renders from executing after teardown.
|
|
97
|
+
*/
|
|
98
|
+
destroyed: boolean;
|
|
95
99
|
constructor(component: Component, { props, editor }: VueRendererOptions);
|
|
96
100
|
get element(): Element | null;
|
|
97
101
|
get ref(): any;
|
|
98
|
-
renderComponent():
|
|
99
|
-
vNode: vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
100
|
-
[key: string]: any;
|
|
101
|
-
}>;
|
|
102
|
-
destroy: () => void;
|
|
103
|
-
el: Element | null;
|
|
104
|
-
};
|
|
102
|
+
renderComponent(): RenderedComponent;
|
|
105
103
|
updateProps(props?: Record<string, any>): void;
|
|
106
104
|
destroy(): void;
|
|
107
105
|
}
|
package/dist/index.js
CHANGED
|
@@ -194,6 +194,10 @@ import { defineComponent as defineComponent4, h as h5, toRaw } from "vue";
|
|
|
194
194
|
import { h as h4, markRaw as markRaw2, reactive, render } from "vue";
|
|
195
195
|
var VueRenderer = class {
|
|
196
196
|
constructor(component, { props = {}, editor }) {
|
|
197
|
+
/**
|
|
198
|
+
* Flag to track if the renderer has been destroyed, preventing queued or asynchronous renders from executing after teardown.
|
|
199
|
+
*/
|
|
200
|
+
this.destroyed = false;
|
|
197
201
|
this.editor = editor;
|
|
198
202
|
this.component = markRaw2(component);
|
|
199
203
|
this.el = document.createElement("div");
|
|
@@ -211,6 +215,9 @@ var VueRenderer = class {
|
|
|
211
215
|
return (_d = (_c = this.renderedComponent.vNode) == null ? void 0 : _c.component) == null ? void 0 : _d.proxy;
|
|
212
216
|
}
|
|
213
217
|
renderComponent() {
|
|
218
|
+
if (this.destroyed) {
|
|
219
|
+
return this.renderedComponent;
|
|
220
|
+
}
|
|
214
221
|
let vNode = h4(this.component, this.props);
|
|
215
222
|
if (this.editor.appContext) {
|
|
216
223
|
vNode.appContext = this.editor.appContext;
|
|
@@ -228,12 +235,19 @@ var VueRenderer = class {
|
|
|
228
235
|
return { vNode, destroy, el: this.el ? this.el.firstElementChild : null };
|
|
229
236
|
}
|
|
230
237
|
updateProps(props = {}) {
|
|
238
|
+
if (this.destroyed) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
231
241
|
Object.entries(props).forEach(([key, value]) => {
|
|
232
242
|
this.props[key] = value;
|
|
233
243
|
});
|
|
234
244
|
this.renderComponent();
|
|
235
245
|
}
|
|
236
246
|
destroy() {
|
|
247
|
+
if (this.destroyed) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
this.destroyed = true;
|
|
237
251
|
this.renderedComponent.destroy();
|
|
238
252
|
}
|
|
239
253
|
};
|
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 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 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 Object.entries(props).forEach(([key, value]) => {\n this.props[key] = value\n })\n this.renderComponent()\n }\n\n destroy(): void {\n this.renderedComponent.destroy()\n }\n}\n","/* eslint-disable no-underscore-dangle */\nimport type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'\nimport { NodeView } 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 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.extension,\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\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\n return this.options.update({\n oldNode,\n oldDecorations,\n newNode: node,\n newDecorations: decorations,\n oldInnerDecorations,\n innerDecorations,\n updateProps: () => rerenderComponent({ node, decorations, innerDecorations }),\n })\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {\n return true\n }\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n\n rerenderComponent({ node, decorations, innerDecorations })\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}\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 { NodeView } 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 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.extension,\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\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\n return this.options.update({\n oldNode,\n oldDecorations,\n newNode: node,\n newDecorations: decorations,\n oldInnerDecorations,\n innerDecorations,\n updateProps: () => rerenderComponent({ node, decorations, innerDecorations }),\n })\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {\n return true\n }\n\n this.node = node\n this.decorations = decorations\n this.innerDecorations = innerDecorations\n\n rerenderComponent({ node, decorations, innerDecorations })\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}\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
|
@@ -281,7 +281,13 @@ var BubbleMenuView = class {
|
|
|
281
281
|
placement: this.floatingUIOptions.placement,
|
|
282
282
|
strategy: this.floatingUIOptions.strategy,
|
|
283
283
|
middleware: this.middlewares
|
|
284
|
-
}).then(({ x, y, strategy }) => {
|
|
284
|
+
}).then(({ x, y, strategy, middlewareData }) => {
|
|
285
|
+
var _a, _b;
|
|
286
|
+
if (((_a = middlewareData.hide) == null ? void 0 : _a.referenceHidden) || ((_b = middlewareData.hide) == null ? void 0 : _b.escaped)) {
|
|
287
|
+
this.element.style.visibility = "hidden";
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
this.element.style.visibility = "visible";
|
|
285
291
|
this.element.style.width = "max-content";
|
|
286
292
|
this.element.style.position = strategy;
|
|
287
293
|
this.element.style.left = `${x}px`;
|
|
@@ -648,7 +654,13 @@ var FloatingMenuView = class {
|
|
|
648
654
|
placement: this.floatingUIOptions.placement,
|
|
649
655
|
strategy: this.floatingUIOptions.strategy,
|
|
650
656
|
middleware: this.middlewares
|
|
651
|
-
}).then(({ x, y, strategy }) => {
|
|
657
|
+
}).then(({ x, y, strategy, middlewareData }) => {
|
|
658
|
+
var _a, _b;
|
|
659
|
+
if (((_a = middlewareData.hide) == null ? void 0 : _a.referenceHidden) || ((_b = middlewareData.hide) == null ? void 0 : _b.escaped)) {
|
|
660
|
+
this.element.style.visibility = "hidden";
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
this.element.style.visibility = "visible";
|
|
652
664
|
this.element.style.width = "max-content";
|
|
653
665
|
this.element.style.position = strategy;
|
|
654
666
|
this.element.style.left = `${x}px`;
|
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 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 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.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 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 }) => {\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.updatePosition()\n this.show()\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 transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta('bubbleMenu')\n if (meta === 'updatePosition') {\n this.updatePosition()\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 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: 'bubbleMenu',\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\n onMounted(() => {\n const {\n editor,\n options,\n pluginKey,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n } = 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,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n }),\n )\n })\n })\n\n onBeforeUnmount(() => {\n const { pluginKey, editor } = props\n\n editor.unregisterPlugin(pluginKey)\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 /**\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 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.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('floatingMenu', 'updatePosition'))`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta('floatingMenu')\n if (meta === 'updatePosition') {\n this.updatePosition()\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 }) => {\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 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: 'floatingMenu',\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\n onMounted(() => {\n const { pluginKey, 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,\n editor,\n element: el,\n updateDelay,\n resizeDelay,\n options,\n appendTo,\n shouldShow,\n }),\n )\n })\n\n onBeforeUnmount(() => {\n const { pluginKey, editor } = props\n\n editor.unregisterPlugin(pluginKey)\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_dom","import_core","import_state","import_vue"]}
|
|
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 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 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.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 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 // 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.updatePosition()\n this.show()\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 transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta('bubbleMenu')\n if (meta === 'updatePosition') {\n this.updatePosition()\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 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: 'bubbleMenu',\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\n onMounted(() => {\n const {\n editor,\n options,\n pluginKey,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n } = 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,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n }),\n )\n })\n })\n\n onBeforeUnmount(() => {\n const { pluginKey, editor } = props\n\n editor.unregisterPlugin(pluginKey)\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 /**\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 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.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('floatingMenu', 'updatePosition'))`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta('floatingMenu')\n if (meta === 'updatePosition') {\n this.updatePosition()\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 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: 'floatingMenu',\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\n onMounted(() => {\n const { pluginKey, 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,\n editor,\n element: el,\n updateDelay,\n resizeDelay,\n options,\n appendTo,\n shouldShow,\n }),\n )\n })\n\n onBeforeUnmount(() => {\n const { pluginKey, editor } = props\n\n editor.unregisterPlugin(pluginKey)\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_dom","import_core","import_state","import_vue"]}
|
package/dist/menus/index.js
CHANGED
|
@@ -264,7 +264,13 @@ var BubbleMenuView = class {
|
|
|
264
264
|
placement: this.floatingUIOptions.placement,
|
|
265
265
|
strategy: this.floatingUIOptions.strategy,
|
|
266
266
|
middleware: this.middlewares
|
|
267
|
-
}).then(({ x, y, strategy }) => {
|
|
267
|
+
}).then(({ x, y, strategy, middlewareData }) => {
|
|
268
|
+
var _a, _b;
|
|
269
|
+
if (((_a = middlewareData.hide) == null ? void 0 : _a.referenceHidden) || ((_b = middlewareData.hide) == null ? void 0 : _b.escaped)) {
|
|
270
|
+
this.element.style.visibility = "hidden";
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
this.element.style.visibility = "visible";
|
|
268
274
|
this.element.style.width = "max-content";
|
|
269
275
|
this.element.style.position = strategy;
|
|
270
276
|
this.element.style.left = `${x}px`;
|
|
@@ -641,7 +647,13 @@ var FloatingMenuView = class {
|
|
|
641
647
|
placement: this.floatingUIOptions.placement,
|
|
642
648
|
strategy: this.floatingUIOptions.strategy,
|
|
643
649
|
middleware: this.middlewares
|
|
644
|
-
}).then(({ x, y, strategy }) => {
|
|
650
|
+
}).then(({ x, y, strategy, middlewareData }) => {
|
|
651
|
+
var _a, _b;
|
|
652
|
+
if (((_a = middlewareData.hide) == null ? void 0 : _a.referenceHidden) || ((_b = middlewareData.hide) == null ? void 0 : _b.escaped)) {
|
|
653
|
+
this.element.style.visibility = "hidden";
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
this.element.style.visibility = "visible";
|
|
645
657
|
this.element.style.width = "max-content";
|
|
646
658
|
this.element.style.position = strategy;
|
|
647
659
|
this.element.style.left = `${x}px`;
|
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 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 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.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 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 }) => {\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.updatePosition()\n this.show()\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 transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta('bubbleMenu')\n if (meta === 'updatePosition') {\n this.updatePosition()\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 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: 'bubbleMenu',\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\n onMounted(() => {\n const {\n editor,\n options,\n pluginKey,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n } = 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,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n }),\n )\n })\n })\n\n onBeforeUnmount(() => {\n const { pluginKey, editor } = props\n\n editor.unregisterPlugin(pluginKey)\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 /**\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 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.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('floatingMenu', 'updatePosition'))`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta('floatingMenu')\n if (meta === 'updatePosition') {\n this.updatePosition()\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 }) => {\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 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: 'floatingMenu',\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\n onMounted(() => {\n const { pluginKey, 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,\n editor,\n element: el,\n updateDelay,\n resizeDelay,\n options,\n appendTo,\n shouldShow,\n }),\n )\n })\n\n onBeforeUnmount(() => {\n const { pluginKey, editor } = props\n\n editor.unregisterPlugin(pluginKey)\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":["arrow","autoPlacement","computePosition","flip","hide","inline","offset","shift","size","posToDOMRect","Plugin","PluginKey","defineComponent","h","onBeforeUnmount","onMounted","ref"]}
|
|
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 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 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.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 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 // 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.updatePosition()\n this.show()\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 transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta('bubbleMenu')\n if (meta === 'updatePosition') {\n this.updatePosition()\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 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: 'bubbleMenu',\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\n onMounted(() => {\n const {\n editor,\n options,\n pluginKey,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n } = 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,\n resizeDelay,\n appendTo,\n shouldShow,\n getReferencedVirtualElement,\n updateDelay,\n }),\n )\n })\n })\n\n onBeforeUnmount(() => {\n const { pluginKey, editor } = props\n\n editor.unregisterPlugin(pluginKey)\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 /**\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 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.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('floatingMenu', 'updatePosition'))`\n */\n transactionHandler = ({ transaction: tr }: { transaction: Transaction }) => {\n const meta = tr.getMeta('floatingMenu')\n if (meta === 'updatePosition') {\n this.updatePosition()\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 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: 'floatingMenu',\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\n onMounted(() => {\n const { pluginKey, 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,\n editor,\n element: el,\n updateDelay,\n resizeDelay,\n options,\n appendTo,\n shouldShow,\n }),\n )\n })\n\n onBeforeUnmount(() => {\n const { pluginKey, editor } = props\n\n editor.unregisterPlugin(pluginKey)\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":["arrow","autoPlacement","computePosition","flip","hide","inline","offset","shift","size","posToDOMRect","Plugin","PluginKey","defineComponent","h","onBeforeUnmount","onMounted","ref"]}
|
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.17.
|
|
4
|
+
"version": "3.17.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.17.
|
|
44
|
-
"@tiptap/pm": "^3.17.
|
|
43
|
+
"@tiptap/core": "^3.17.1",
|
|
44
|
+
"@tiptap/pm": "^3.17.1"
|
|
45
45
|
},
|
|
46
46
|
"optionalDependencies": {
|
|
47
|
-
"@tiptap/extension-bubble-menu": "^3.17.
|
|
48
|
-
"@tiptap/extension-floating-menu": "^3.17.
|
|
47
|
+
"@tiptap/extension-bubble-menu": "^3.17.1",
|
|
48
|
+
"@tiptap/extension-floating-menu": "^3.17.1"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"vue": "^3.0.0",
|
|
52
52
|
"@floating-ui/dom": "^1.0.0",
|
|
53
|
-
"@tiptap/
|
|
54
|
-
"@tiptap/
|
|
53
|
+
"@tiptap/core": "^3.17.1",
|
|
54
|
+
"@tiptap/pm": "^3.17.1"
|
|
55
55
|
},
|
|
56
56
|
"repository": {
|
|
57
57
|
"type": "git",
|
package/src/VueRenderer.ts
CHANGED
|
@@ -31,6 +31,11 @@ export class VueRenderer {
|
|
|
31
31
|
|
|
32
32
|
props: Record<string, any>
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Flag to track if the renderer has been destroyed, preventing queued or asynchronous renders from executing after teardown.
|
|
36
|
+
*/
|
|
37
|
+
destroyed = false
|
|
38
|
+
|
|
34
39
|
constructor(component: Component, { props = {}, editor }: VueRendererOptions) {
|
|
35
40
|
this.editor = editor as ExtendedEditor
|
|
36
41
|
this.component = markRaw(component)
|
|
@@ -53,6 +58,10 @@ export class VueRenderer {
|
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
renderComponent() {
|
|
61
|
+
if (this.destroyed) {
|
|
62
|
+
return this.renderedComponent
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
let vNode: ExtendedVNode = h(this.component as DefineComponent, this.props)
|
|
57
66
|
|
|
58
67
|
if (this.editor.appContext) {
|
|
@@ -74,6 +83,10 @@ export class VueRenderer {
|
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
updateProps(props: Record<string, any> = {}): void {
|
|
86
|
+
if (this.destroyed) {
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
77
90
|
Object.entries(props).forEach(([key, value]) => {
|
|
78
91
|
this.props[key] = value
|
|
79
92
|
})
|
|
@@ -81,6 +94,11 @@ export class VueRenderer {
|
|
|
81
94
|
}
|
|
82
95
|
|
|
83
96
|
destroy(): void {
|
|
97
|
+
if (this.destroyed) {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.destroyed = true
|
|
84
102
|
this.renderedComponent.destroy()
|
|
85
103
|
}
|
|
86
104
|
}
|