@tiptap/vue-2 3.0.0-next.8 → 3.0.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 CHANGED
@@ -255,8 +255,7 @@ var VueNodeView = class extends import_core2.NodeView {
255
255
  if (this.node.isLeaf) {
256
256
  return null;
257
257
  }
258
- const contentElement = this.dom.querySelector("[data-node-view-content]");
259
- return contentElement || this.dom;
258
+ return this.dom.querySelector("[data-node-view-content]");
260
259
  }
261
260
  /**
262
261
  * On editor selection update, check if the node is selected.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Editor.ts","../src/EditorContent.ts","../src/NodeViewContent.ts","../src/NodeViewWrapper.ts","../src/VueNodeViewRenderer.ts","../src/VueRenderer.ts"],"sourcesContent":["export { Editor } from './Editor.js'\nexport * from './EditorContent.js'\nexport * from './NodeViewContent.js'\nexport * from './NodeViewWrapper.js'\nexport * from './VueNodeViewRenderer.js'\nexport * from './VueRenderer.js'\nexport * from '@tiptap/core'\n","import { Editor as CoreEditor } from '@tiptap/core'\nimport type Vue from 'vue'\n\nexport class Editor extends CoreEditor {\n public contentComponent: Vue | null = null\n}\n","import type { Component, CreateElement, PropType } from 'vue'\nimport type Vue from 'vue'\n\nimport type { Editor } from './Editor.js'\n\nexport interface EditorContentInterface extends Vue {\n editor: Editor\n}\n\nexport const EditorContent: Component = {\n name: 'EditorContent',\n\n props: {\n editor: {\n default: null,\n type: Object as PropType<Editor>,\n },\n },\n\n watch: {\n editor: {\n immediate: true,\n handler(this: EditorContentInterface, editor: Editor) {\n if (editor && editor.options.element) {\n this.$nextTick(() => {\n const element = this.$el\n\n if (!element || !editor.options.element?.firstChild) {\n return\n }\n\n element.append(...editor.options.element.childNodes)\n editor.contentComponent = this\n\n editor.setOptions({\n element,\n })\n\n editor.createNodeViews()\n })\n }\n },\n },\n },\n\n render(createElement: CreateElement) {\n return createElement('div')\n },\n\n beforeDestroy(this: EditorContentInterface) {\n const { editor } = this\n\n if (!editor) {\n return\n }\n\n if (!editor.isDestroyed) {\n editor.view.setProps({\n nodeViews: {},\n })\n }\n\n editor.contentComponent = null\n\n if (!editor.options.element?.firstChild) {\n return\n }\n\n // TODO using the new editor.mount method might allow us to remove this\n const newElement = document.createElement('div')\n\n newElement.append(...editor.options.element.childNodes)\n\n editor.setOptions({\n element: newElement,\n })\n },\n}\n","import type { Component, CreateElement } from 'vue'\nimport type Vue from 'vue'\n\nexport interface NodeViewContentInterface extends Vue {\n as: string\n}\n\nexport const NodeViewContent: Component = {\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n render(this: NodeViewContentInterface, createElement: CreateElement) {\n return createElement(this.as, {\n style: {\n whiteSpace: 'pre-wrap',\n },\n attrs: {\n 'data-node-view-content': '',\n },\n })\n },\n}\n","import type { Component, CreateElement } from 'vue'\nimport type Vue from 'vue'\n\nexport interface NodeViewWrapperInterface extends Vue {\n as: string\n decorationClasses: {\n value: string\n }\n onDragStart: () => void\n}\n\nexport const NodeViewWrapper: Component = {\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n inject: ['onDragStart', 'decorationClasses'],\n\n render(this: NodeViewWrapperInterface, createElement: CreateElement) {\n return createElement(\n this.as,\n {\n class: this.decorationClasses.value,\n style: {\n whiteSpace: 'normal',\n },\n attrs: {\n 'data-node-view-wrapper': '',\n },\n on: {\n dragstart: this.onDragStart,\n },\n },\n this.$slots.default,\n )\n },\n}\n","import 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 Vue from 'vue'\nimport type { VueConstructor } from 'vue/types/umd'\nimport { booleanProp, functionProp, objectProp } from 'vue-ts-types'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport const nodeViewProps = {\n editor: objectProp<NodeViewProps['editor']>().required,\n node: objectProp<NodeViewProps['node']>().required,\n decorations: objectProp<NodeViewProps['decorations']>().required,\n selected: booleanProp().required,\n extension: objectProp<NodeViewProps['extension']>().required,\n getPos: functionProp<NodeViewProps['getPos']>().required,\n updateAttributes: functionProp<NodeViewProps['updateAttributes']>().required,\n deleteNode: functionProp<NodeViewProps['deleteNode']>().required,\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<Vue | VueConstructor, Editor, VueNodeViewRendererOptions> {\n renderer!: VueRenderer\n\n decorationClasses!: {\n value: string\n }\n\n mount() {\n const props = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations as DecorationWithType[],\n innerDecorations: this.innerDecorations,\n view: this.view,\n selected: false,\n extension: this.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 = Vue.observable({\n value: this.getDecorationClasses(),\n })\n\n // @ts-ignore\n const vue = this.editor.contentComponent?.$options._base ?? Vue // eslint-disable-line\n\n const Component = vue.extend(this.component).extend({\n props: Object.keys(props),\n provide: () => {\n return {\n onDragStart,\n decorationClasses: this.decorationClasses,\n }\n },\n })\n\n this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this)\n this.editor.on('selectionUpdate', this.handleSelectionUpdate)\n\n this.renderer = new VueRenderer(Component, {\n parent: this.editor.contentComponent,\n propsData: 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.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 const contentElement = this.dom.querySelector('[data-node-view-content]')\n\n return (contentElement || this.dom) 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.ref.$props.selected) {\n return\n }\n\n this.selectNode()\n } else {\n if (!this.renderer.ref.$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 this.renderer.element.classList.add('ProseMirror-selectednode')\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 this.renderer.element.classList.remove('ProseMirror-selectednode')\n }\n\n getDecorationClasses() {\n return (\n this.decorations\n // @ts-ignore\n .map(item => item.type.attrs.class)\n .flat()\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: Vue | VueConstructor,\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\n return new VueNodeView(component, props, options)\n }\n}\n","import Vue from 'vue'\nimport type { VueConstructor } from 'vue/types/umd'\n\n/**\n * The VueRenderer class is responsible for rendering a Vue component as a ProseMirror node view.\n */\nexport class VueRenderer {\n ref!: Vue\n\n constructor(component: Vue | VueConstructor, props: any) {\n const Component = typeof component === 'function' ? component : Vue.extend(component)\n\n this.ref = new Component(props).$mount()\n }\n\n get element(): Element {\n return this.ref.$el\n }\n\n updateProps(props: Record<string, any> = {}): void {\n if (!this.ref.$props) {\n return\n }\n\n // prevents `Avoid mutating a prop directly` error message\n // Fix: `VueNodeViewRenderer` change vue Constructor `config.silent` not working\n const currentVueConstructor = this.ref.$props.editor?.contentComponent?.$options._base ?? Vue // eslint-disable-line\n const originalSilent = currentVueConstructor.config.silent\n\n currentVueConstructor.config.silent = true\n\n Object.entries(props).forEach(([key, value]) => {\n this.ref.$props[key] = value\n })\n\n currentVueConstructor.config.silent = originalSilent\n }\n\n destroy(): void {\n this.ref.$destroy()\n }\n}\n"],"mappings":"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","names":["CoreEditor","import_core","import_vue","Vue","Vue"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Editor.ts","../src/EditorContent.ts","../src/NodeViewContent.ts","../src/NodeViewWrapper.ts","../src/VueNodeViewRenderer.ts","../src/VueRenderer.ts"],"sourcesContent":["export { Editor } from './Editor.js'\nexport * from './EditorContent.js'\nexport * from './NodeViewContent.js'\nexport * from './NodeViewWrapper.js'\nexport * from './VueNodeViewRenderer.js'\nexport * from './VueRenderer.js'\nexport * from '@tiptap/core'\n","import { Editor as CoreEditor } from '@tiptap/core'\nimport type Vue from 'vue'\n\nexport class Editor extends CoreEditor {\n public contentComponent: Vue | null = null\n}\n","import type { Component, CreateElement, PropType } from 'vue'\nimport type Vue from 'vue'\n\nimport type { Editor } from './Editor.js'\n\nexport interface EditorContentInterface extends Vue {\n editor: Editor\n}\n\nexport const EditorContent: Component = {\n name: 'EditorContent',\n\n props: {\n editor: {\n default: null,\n type: Object as PropType<Editor>,\n },\n },\n\n watch: {\n editor: {\n immediate: true,\n handler(this: EditorContentInterface, editor: Editor) {\n if (editor && editor.options.element) {\n this.$nextTick(() => {\n const element = this.$el\n\n if (!element || !editor.options.element?.firstChild) {\n return\n }\n\n element.append(...editor.options.element.childNodes)\n editor.contentComponent = this\n\n editor.setOptions({\n element,\n })\n\n editor.createNodeViews()\n })\n }\n },\n },\n },\n\n render(createElement: CreateElement) {\n return createElement('div')\n },\n\n beforeDestroy(this: EditorContentInterface) {\n const { editor } = this\n\n if (!editor) {\n return\n }\n\n if (!editor.isDestroyed) {\n editor.view.setProps({\n nodeViews: {},\n })\n }\n\n editor.contentComponent = null\n\n if (!editor.options.element?.firstChild) {\n return\n }\n\n // TODO using the new editor.mount method might allow us to remove this\n const newElement = document.createElement('div')\n\n newElement.append(...editor.options.element.childNodes)\n\n editor.setOptions({\n element: newElement,\n })\n },\n}\n","import type { Component, CreateElement } from 'vue'\nimport type Vue from 'vue'\n\nexport interface NodeViewContentInterface extends Vue {\n as: string\n}\n\nexport const NodeViewContent: Component = {\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n render(this: NodeViewContentInterface, createElement: CreateElement) {\n return createElement(this.as, {\n style: {\n whiteSpace: 'pre-wrap',\n },\n attrs: {\n 'data-node-view-content': '',\n },\n })\n },\n}\n","import type { Component, CreateElement } from 'vue'\nimport type Vue from 'vue'\n\nexport interface NodeViewWrapperInterface extends Vue {\n as: string\n decorationClasses: {\n value: string\n }\n onDragStart: () => void\n}\n\nexport const NodeViewWrapper: Component = {\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n inject: ['onDragStart', 'decorationClasses'],\n\n render(this: NodeViewWrapperInterface, createElement: CreateElement) {\n return createElement(\n this.as,\n {\n class: this.decorationClasses.value,\n style: {\n whiteSpace: 'normal',\n },\n attrs: {\n 'data-node-view-wrapper': '',\n },\n on: {\n dragstart: this.onDragStart,\n },\n },\n this.$slots.default,\n )\n },\n}\n","import 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 Vue from 'vue'\nimport type { VueConstructor } from 'vue/types/umd'\nimport { booleanProp, functionProp, objectProp } from 'vue-ts-types'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport const nodeViewProps = {\n editor: objectProp<NodeViewProps['editor']>().required,\n node: objectProp<NodeViewProps['node']>().required,\n decorations: objectProp<NodeViewProps['decorations']>().required,\n selected: booleanProp().required,\n extension: objectProp<NodeViewProps['extension']>().required,\n getPos: functionProp<NodeViewProps['getPos']>().required,\n updateAttributes: functionProp<NodeViewProps['updateAttributes']>().required,\n deleteNode: functionProp<NodeViewProps['deleteNode']>().required,\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<Vue | VueConstructor, Editor, VueNodeViewRendererOptions> {\n renderer!: VueRenderer\n\n decorationClasses!: {\n value: string\n }\n\n mount() {\n const props = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations as DecorationWithType[],\n innerDecorations: this.innerDecorations,\n view: this.view,\n selected: false,\n extension: this.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 = Vue.observable({\n value: this.getDecorationClasses(),\n })\n\n // @ts-ignore\n const vue = this.editor.contentComponent?.$options._base ?? Vue // eslint-disable-line\n\n const Component = vue.extend(this.component).extend({\n props: Object.keys(props),\n provide: () => {\n return {\n onDragStart,\n decorationClasses: this.decorationClasses,\n }\n },\n })\n\n this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this)\n this.editor.on('selectionUpdate', this.handleSelectionUpdate)\n\n this.renderer = new VueRenderer(Component, {\n parent: this.editor.contentComponent,\n propsData: 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.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.ref.$props.selected) {\n return\n }\n\n this.selectNode()\n } else {\n if (!this.renderer.ref.$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 this.renderer.element.classList.add('ProseMirror-selectednode')\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 this.renderer.element.classList.remove('ProseMirror-selectednode')\n }\n\n getDecorationClasses() {\n return (\n this.decorations\n // @ts-ignore\n .map(item => item.type.attrs.class)\n .flat()\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: Vue | VueConstructor,\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\n return new VueNodeView(component, props, options)\n }\n}\n","import Vue from 'vue'\nimport type { VueConstructor } from 'vue/types/umd'\n\n/**\n * The VueRenderer class is responsible for rendering a Vue component as a ProseMirror node view.\n */\nexport class VueRenderer {\n ref!: Vue\n\n constructor(component: Vue | VueConstructor, props: any) {\n const Component = typeof component === 'function' ? component : Vue.extend(component)\n\n this.ref = new Component(props).$mount()\n }\n\n get element(): Element {\n return this.ref.$el\n }\n\n updateProps(props: Record<string, any> = {}): void {\n if (!this.ref.$props) {\n return\n }\n\n // prevents `Avoid mutating a prop directly` error message\n // Fix: `VueNodeViewRenderer` change vue Constructor `config.silent` not working\n const currentVueConstructor = this.ref.$props.editor?.contentComponent?.$options._base ?? Vue // eslint-disable-line\n const originalSilent = currentVueConstructor.config.silent\n\n currentVueConstructor.config.silent = true\n\n Object.entries(props).forEach(([key, value]) => {\n this.ref.$props[key] = value\n })\n\n currentVueConstructor.config.silent = originalSilent\n }\n\n destroy(): void {\n this.ref.$destroy()\n }\n}\n"],"mappings":"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","names":["CoreEditor","import_core","import_vue","Vue","Vue"]}
package/dist/index.js CHANGED
@@ -212,8 +212,7 @@ var VueNodeView = class extends NodeView {
212
212
  if (this.node.isLeaf) {
213
213
  return null;
214
214
  }
215
- const contentElement = this.dom.querySelector("[data-node-view-content]");
216
- return contentElement || this.dom;
215
+ return this.dom.querySelector("[data-node-view-content]");
217
216
  }
218
217
  /**
219
218
  * On editor selection update, check if the node is selected.
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/VueNodeViewRenderer.ts","../src/VueRenderer.ts","../src/index.ts"],"sourcesContent":["import { Editor as CoreEditor } from '@tiptap/core'\nimport type Vue from 'vue'\n\nexport class Editor extends CoreEditor {\n public contentComponent: Vue | null = null\n}\n","import type { Component, CreateElement, PropType } from 'vue'\nimport type Vue from 'vue'\n\nimport type { Editor } from './Editor.js'\n\nexport interface EditorContentInterface extends Vue {\n editor: Editor\n}\n\nexport const EditorContent: Component = {\n name: 'EditorContent',\n\n props: {\n editor: {\n default: null,\n type: Object as PropType<Editor>,\n },\n },\n\n watch: {\n editor: {\n immediate: true,\n handler(this: EditorContentInterface, editor: Editor) {\n if (editor && editor.options.element) {\n this.$nextTick(() => {\n const element = this.$el\n\n if (!element || !editor.options.element?.firstChild) {\n return\n }\n\n element.append(...editor.options.element.childNodes)\n editor.contentComponent = this\n\n editor.setOptions({\n element,\n })\n\n editor.createNodeViews()\n })\n }\n },\n },\n },\n\n render(createElement: CreateElement) {\n return createElement('div')\n },\n\n beforeDestroy(this: EditorContentInterface) {\n const { editor } = this\n\n if (!editor) {\n return\n }\n\n if (!editor.isDestroyed) {\n editor.view.setProps({\n nodeViews: {},\n })\n }\n\n editor.contentComponent = null\n\n if (!editor.options.element?.firstChild) {\n return\n }\n\n // TODO using the new editor.mount method might allow us to remove this\n const newElement = document.createElement('div')\n\n newElement.append(...editor.options.element.childNodes)\n\n editor.setOptions({\n element: newElement,\n })\n },\n}\n","import type { Component, CreateElement } from 'vue'\nimport type Vue from 'vue'\n\nexport interface NodeViewContentInterface extends Vue {\n as: string\n}\n\nexport const NodeViewContent: Component = {\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n render(this: NodeViewContentInterface, createElement: CreateElement) {\n return createElement(this.as, {\n style: {\n whiteSpace: 'pre-wrap',\n },\n attrs: {\n 'data-node-view-content': '',\n },\n })\n },\n}\n","import type { Component, CreateElement } from 'vue'\nimport type Vue from 'vue'\n\nexport interface NodeViewWrapperInterface extends Vue {\n as: string\n decorationClasses: {\n value: string\n }\n onDragStart: () => void\n}\n\nexport const NodeViewWrapper: Component = {\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n inject: ['onDragStart', 'decorationClasses'],\n\n render(this: NodeViewWrapperInterface, createElement: CreateElement) {\n return createElement(\n this.as,\n {\n class: this.decorationClasses.value,\n style: {\n whiteSpace: 'normal',\n },\n attrs: {\n 'data-node-view-wrapper': '',\n },\n on: {\n dragstart: this.onDragStart,\n },\n },\n this.$slots.default,\n )\n },\n}\n","import 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 Vue from 'vue'\nimport type { VueConstructor } from 'vue/types/umd'\nimport { booleanProp, functionProp, objectProp } from 'vue-ts-types'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport const nodeViewProps = {\n editor: objectProp<NodeViewProps['editor']>().required,\n node: objectProp<NodeViewProps['node']>().required,\n decorations: objectProp<NodeViewProps['decorations']>().required,\n selected: booleanProp().required,\n extension: objectProp<NodeViewProps['extension']>().required,\n getPos: functionProp<NodeViewProps['getPos']>().required,\n updateAttributes: functionProp<NodeViewProps['updateAttributes']>().required,\n deleteNode: functionProp<NodeViewProps['deleteNode']>().required,\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<Vue | VueConstructor, Editor, VueNodeViewRendererOptions> {\n renderer!: VueRenderer\n\n decorationClasses!: {\n value: string\n }\n\n mount() {\n const props = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations as DecorationWithType[],\n innerDecorations: this.innerDecorations,\n view: this.view,\n selected: false,\n extension: this.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 = Vue.observable({\n value: this.getDecorationClasses(),\n })\n\n // @ts-ignore\n const vue = this.editor.contentComponent?.$options._base ?? Vue // eslint-disable-line\n\n const Component = vue.extend(this.component).extend({\n props: Object.keys(props),\n provide: () => {\n return {\n onDragStart,\n decorationClasses: this.decorationClasses,\n }\n },\n })\n\n this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this)\n this.editor.on('selectionUpdate', this.handleSelectionUpdate)\n\n this.renderer = new VueRenderer(Component, {\n parent: this.editor.contentComponent,\n propsData: 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.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 const contentElement = this.dom.querySelector('[data-node-view-content]')\n\n return (contentElement || this.dom) 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.ref.$props.selected) {\n return\n }\n\n this.selectNode()\n } else {\n if (!this.renderer.ref.$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 this.renderer.element.classList.add('ProseMirror-selectednode')\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 this.renderer.element.classList.remove('ProseMirror-selectednode')\n }\n\n getDecorationClasses() {\n return (\n this.decorations\n // @ts-ignore\n .map(item => item.type.attrs.class)\n .flat()\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: Vue | VueConstructor,\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\n return new VueNodeView(component, props, options)\n }\n}\n","import Vue from 'vue'\nimport type { VueConstructor } from 'vue/types/umd'\n\n/**\n * The VueRenderer class is responsible for rendering a Vue component as a ProseMirror node view.\n */\nexport class VueRenderer {\n ref!: Vue\n\n constructor(component: Vue | VueConstructor, props: any) {\n const Component = typeof component === 'function' ? component : Vue.extend(component)\n\n this.ref = new Component(props).$mount()\n }\n\n get element(): Element {\n return this.ref.$el\n }\n\n updateProps(props: Record<string, any> = {}): void {\n if (!this.ref.$props) {\n return\n }\n\n // prevents `Avoid mutating a prop directly` error message\n // Fix: `VueNodeViewRenderer` change vue Constructor `config.silent` not working\n const currentVueConstructor = this.ref.$props.editor?.contentComponent?.$options._base ?? Vue // eslint-disable-line\n const originalSilent = currentVueConstructor.config.silent\n\n currentVueConstructor.config.silent = true\n\n Object.entries(props).forEach(([key, value]) => {\n this.ref.$props[key] = value\n })\n\n currentVueConstructor.config.silent = originalSilent\n }\n\n destroy(): void {\n this.ref.$destroy()\n }\n}\n","export { Editor } from './Editor.js'\nexport * from './EditorContent.js'\nexport * from './NodeViewContent.js'\nexport * from './NodeViewWrapper.js'\nexport * from './VueNodeViewRenderer.js'\nexport * from './VueRenderer.js'\nexport * from '@tiptap/core'\n"],"mappings":"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","names":["Vue","Vue"]}
1
+ {"version":3,"sources":["../src/Editor.ts","../src/EditorContent.ts","../src/NodeViewContent.ts","../src/NodeViewWrapper.ts","../src/VueNodeViewRenderer.ts","../src/VueRenderer.ts","../src/index.ts"],"sourcesContent":["import { Editor as CoreEditor } from '@tiptap/core'\nimport type Vue from 'vue'\n\nexport class Editor extends CoreEditor {\n public contentComponent: Vue | null = null\n}\n","import type { Component, CreateElement, PropType } from 'vue'\nimport type Vue from 'vue'\n\nimport type { Editor } from './Editor.js'\n\nexport interface EditorContentInterface extends Vue {\n editor: Editor\n}\n\nexport const EditorContent: Component = {\n name: 'EditorContent',\n\n props: {\n editor: {\n default: null,\n type: Object as PropType<Editor>,\n },\n },\n\n watch: {\n editor: {\n immediate: true,\n handler(this: EditorContentInterface, editor: Editor) {\n if (editor && editor.options.element) {\n this.$nextTick(() => {\n const element = this.$el\n\n if (!element || !editor.options.element?.firstChild) {\n return\n }\n\n element.append(...editor.options.element.childNodes)\n editor.contentComponent = this\n\n editor.setOptions({\n element,\n })\n\n editor.createNodeViews()\n })\n }\n },\n },\n },\n\n render(createElement: CreateElement) {\n return createElement('div')\n },\n\n beforeDestroy(this: EditorContentInterface) {\n const { editor } = this\n\n if (!editor) {\n return\n }\n\n if (!editor.isDestroyed) {\n editor.view.setProps({\n nodeViews: {},\n })\n }\n\n editor.contentComponent = null\n\n if (!editor.options.element?.firstChild) {\n return\n }\n\n // TODO using the new editor.mount method might allow us to remove this\n const newElement = document.createElement('div')\n\n newElement.append(...editor.options.element.childNodes)\n\n editor.setOptions({\n element: newElement,\n })\n },\n}\n","import type { Component, CreateElement } from 'vue'\nimport type Vue from 'vue'\n\nexport interface NodeViewContentInterface extends Vue {\n as: string\n}\n\nexport const NodeViewContent: Component = {\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n render(this: NodeViewContentInterface, createElement: CreateElement) {\n return createElement(this.as, {\n style: {\n whiteSpace: 'pre-wrap',\n },\n attrs: {\n 'data-node-view-content': '',\n },\n })\n },\n}\n","import type { Component, CreateElement } from 'vue'\nimport type Vue from 'vue'\n\nexport interface NodeViewWrapperInterface extends Vue {\n as: string\n decorationClasses: {\n value: string\n }\n onDragStart: () => void\n}\n\nexport const NodeViewWrapper: Component = {\n props: {\n as: {\n type: String,\n default: 'div',\n },\n },\n\n inject: ['onDragStart', 'decorationClasses'],\n\n render(this: NodeViewWrapperInterface, createElement: CreateElement) {\n return createElement(\n this.as,\n {\n class: this.decorationClasses.value,\n style: {\n whiteSpace: 'normal',\n },\n attrs: {\n 'data-node-view-wrapper': '',\n },\n on: {\n dragstart: this.onDragStart,\n },\n },\n this.$slots.default,\n )\n },\n}\n","import 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 Vue from 'vue'\nimport type { VueConstructor } from 'vue/types/umd'\nimport { booleanProp, functionProp, objectProp } from 'vue-ts-types'\n\nimport type { Editor } from './Editor.js'\nimport { VueRenderer } from './VueRenderer.js'\n\nexport const nodeViewProps = {\n editor: objectProp<NodeViewProps['editor']>().required,\n node: objectProp<NodeViewProps['node']>().required,\n decorations: objectProp<NodeViewProps['decorations']>().required,\n selected: booleanProp().required,\n extension: objectProp<NodeViewProps['extension']>().required,\n getPos: functionProp<NodeViewProps['getPos']>().required,\n updateAttributes: functionProp<NodeViewProps['updateAttributes']>().required,\n deleteNode: functionProp<NodeViewProps['deleteNode']>().required,\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<Vue | VueConstructor, Editor, VueNodeViewRendererOptions> {\n renderer!: VueRenderer\n\n decorationClasses!: {\n value: string\n }\n\n mount() {\n const props = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations as DecorationWithType[],\n innerDecorations: this.innerDecorations,\n view: this.view,\n selected: false,\n extension: this.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 = Vue.observable({\n value: this.getDecorationClasses(),\n })\n\n // @ts-ignore\n const vue = this.editor.contentComponent?.$options._base ?? Vue // eslint-disable-line\n\n const Component = vue.extend(this.component).extend({\n props: Object.keys(props),\n provide: () => {\n return {\n onDragStart,\n decorationClasses: this.decorationClasses,\n }\n },\n })\n\n this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this)\n this.editor.on('selectionUpdate', this.handleSelectionUpdate)\n\n this.renderer = new VueRenderer(Component, {\n parent: this.editor.contentComponent,\n propsData: 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.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.ref.$props.selected) {\n return\n }\n\n this.selectNode()\n } else {\n if (!this.renderer.ref.$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 this.renderer.element.classList.add('ProseMirror-selectednode')\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 this.renderer.element.classList.remove('ProseMirror-selectednode')\n }\n\n getDecorationClasses() {\n return (\n this.decorations\n // @ts-ignore\n .map(item => item.type.attrs.class)\n .flat()\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: Vue | VueConstructor,\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\n return new VueNodeView(component, props, options)\n }\n}\n","import Vue from 'vue'\nimport type { VueConstructor } from 'vue/types/umd'\n\n/**\n * The VueRenderer class is responsible for rendering a Vue component as a ProseMirror node view.\n */\nexport class VueRenderer {\n ref!: Vue\n\n constructor(component: Vue | VueConstructor, props: any) {\n const Component = typeof component === 'function' ? component : Vue.extend(component)\n\n this.ref = new Component(props).$mount()\n }\n\n get element(): Element {\n return this.ref.$el\n }\n\n updateProps(props: Record<string, any> = {}): void {\n if (!this.ref.$props) {\n return\n }\n\n // prevents `Avoid mutating a prop directly` error message\n // Fix: `VueNodeViewRenderer` change vue Constructor `config.silent` not working\n const currentVueConstructor = this.ref.$props.editor?.contentComponent?.$options._base ?? Vue // eslint-disable-line\n const originalSilent = currentVueConstructor.config.silent\n\n currentVueConstructor.config.silent = true\n\n Object.entries(props).forEach(([key, value]) => {\n this.ref.$props[key] = value\n })\n\n currentVueConstructor.config.silent = originalSilent\n }\n\n destroy(): void {\n this.ref.$destroy()\n }\n}\n","export { Editor } from './Editor.js'\nexport * from './EditorContent.js'\nexport * from './NodeViewContent.js'\nexport * from './NodeViewWrapper.js'\nexport * from './VueNodeViewRenderer.js'\nexport * from './VueRenderer.js'\nexport * from '@tiptap/core'\n"],"mappings":"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","names":["Vue","Vue"]}
@@ -20,11 +20,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/menus/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- BubbleMenu: () => BubbleMenu,
24
- FloatingMenu: () => FloatingMenu
23
+ BubbleMenu: () => BubbleMenu2,
24
+ FloatingMenu: () => FloatingMenu2
25
25
  });
26
26
  module.exports = __toCommonJS(index_exports);
27
27
 
28
+ // ../extension-bubble-menu/dist/index.js
29
+ var import_core2 = require("@tiptap/core");
30
+
28
31
  // ../../node_modules/.pnpm/@floating-ui+utils@0.2.9/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
29
32
  var sides = ["top", "right", "bottom", "left"];
30
33
  var alignments = ["start", "end"];
@@ -1608,9 +1611,21 @@ var computePosition2 = (reference, floating, options) => {
1608
1611
  });
1609
1612
  };
1610
1613
 
1611
- // ../extension-bubble-menu/src/bubble-menu-plugin.ts
1612
- var import_core2 = require("@tiptap/core");
1614
+ // ../extension-bubble-menu/dist/index.js
1615
+ var import_core3 = require("@tiptap/core");
1613
1616
  var import_state = require("@tiptap/pm/state");
1617
+ var import_tables = require("@tiptap/pm/tables");
1618
+ function combineDOMRects(rect1, rect2) {
1619
+ const top = Math.min(rect1.top, rect2.top);
1620
+ const bottom = Math.max(rect1.bottom, rect2.bottom);
1621
+ const left = Math.min(rect1.left, rect2.left);
1622
+ const right = Math.max(rect1.right, rect2.right);
1623
+ const width = right - left;
1624
+ const height = bottom - top;
1625
+ const x = left;
1626
+ const y = top;
1627
+ return new DOMRect(x, y, width, height);
1628
+ }
1614
1629
  var BubbleMenuView = class {
1615
1630
  constructor({
1616
1631
  editor,
@@ -1622,6 +1637,7 @@ var BubbleMenuView = class {
1622
1637
  options
1623
1638
  }) {
1624
1639
  this.preventHide = false;
1640
+ this.isVisible = false;
1625
1641
  this.floatingUIOptions = {
1626
1642
  strategy: "absolute",
1627
1643
  placement: "top",
@@ -1632,14 +1648,18 @@ var BubbleMenuView = class {
1632
1648
  size: false,
1633
1649
  autoPlacement: false,
1634
1650
  hide: false,
1635
- inline: false
1651
+ inline: false,
1652
+ onShow: void 0,
1653
+ onHide: void 0,
1654
+ onUpdate: void 0,
1655
+ onDestroy: void 0
1636
1656
  };
1637
- this.shouldShow = ({ view, state, from, to }) => {
1657
+ this.shouldShow = ({ view: view2, state, from, to }) => {
1638
1658
  const { doc, selection } = state;
1639
1659
  const { empty } = selection;
1640
- const isEmptyTextBlock = !doc.textBetween(from, to).length && (0, import_core2.isTextSelection)(state.selection);
1660
+ const isEmptyTextBlock = !doc.textBetween(from, to).length && (0, import_core3.isTextSelection)(state.selection);
1641
1661
  const isChildOfMenu = this.element.contains(document.activeElement);
1642
- const hasEditorFocus = view.hasFocus() || isChildOfMenu;
1662
+ const hasEditorFocus = view2.hasFocus() || isChildOfMenu;
1643
1663
  if (!hasEditorFocus || empty || isEmptyTextBlock || !this.editor.isEditable) {
1644
1664
  return false;
1645
1665
  }
@@ -1651,6 +1671,14 @@ var BubbleMenuView = class {
1651
1671
  this.dragstartHandler = () => {
1652
1672
  this.hide();
1653
1673
  };
1674
+ this.resizeHandler = () => {
1675
+ if (this.resizeDebounceTimer) {
1676
+ clearTimeout(this.resizeDebounceTimer);
1677
+ }
1678
+ this.resizeDebounceTimer = window.setTimeout(() => {
1679
+ this.updatePosition();
1680
+ }, this.resizeDelay);
1681
+ };
1654
1682
  this.focusHandler = () => {
1655
1683
  setTimeout(() => this.update(this.editor.view));
1656
1684
  };
@@ -1668,9 +1696,9 @@ var BubbleMenuView = class {
1668
1696
  }
1669
1697
  this.hide();
1670
1698
  };
1671
- this.handleDebouncedUpdate = (view, oldState) => {
1672
- const selectionChanged = !(oldState == null ? void 0 : oldState.selection.eq(view.state.selection));
1673
- const docChanged = !(oldState == null ? void 0 : oldState.doc.eq(view.state.doc));
1699
+ this.handleDebouncedUpdate = (view2, oldState) => {
1700
+ const selectionChanged = !(oldState == null ? void 0 : oldState.selection.eq(view2.state.selection));
1701
+ const docChanged = !(oldState == null ? void 0 : oldState.doc.eq(view2.state.doc));
1674
1702
  if (!selectionChanged && !docChanged) {
1675
1703
  return;
1676
1704
  }
@@ -1678,17 +1706,17 @@ var BubbleMenuView = class {
1678
1706
  clearTimeout(this.updateDebounceTimer);
1679
1707
  }
1680
1708
  this.updateDebounceTimer = window.setTimeout(() => {
1681
- this.updateHandler(view, selectionChanged, docChanged, oldState);
1709
+ this.updateHandler(view2, selectionChanged, docChanged, oldState);
1682
1710
  }, this.updateDelay);
1683
1711
  };
1684
- this.updateHandler = (view, selectionChanged, docChanged, oldState) => {
1685
- const { composing } = view;
1712
+ this.updateHandler = (view2, selectionChanged, docChanged, oldState) => {
1713
+ const { composing } = view2;
1686
1714
  const isSame = !selectionChanged && !docChanged;
1687
1715
  if (composing || isSame) {
1688
1716
  return;
1689
1717
  }
1690
- const shouldShow = this.getShouldShow(oldState);
1691
- if (!shouldShow) {
1718
+ const shouldShow2 = this.getShouldShow(oldState);
1719
+ if (!shouldShow2) {
1692
1720
  this.hide();
1693
1721
  return;
1694
1722
  }
@@ -1704,6 +1732,7 @@ var BubbleMenuView = class {
1704
1732
  ...this.floatingUIOptions,
1705
1733
  ...options
1706
1734
  };
1735
+ this.element.tabIndex = 0;
1707
1736
  if (shouldShow) {
1708
1737
  this.shouldShow = shouldShow;
1709
1738
  }
@@ -1711,14 +1740,7 @@ var BubbleMenuView = class {
1711
1740
  this.view.dom.addEventListener("dragstart", this.dragstartHandler);
1712
1741
  this.editor.on("focus", this.focusHandler);
1713
1742
  this.editor.on("blur", this.blurHandler);
1714
- window.addEventListener("resize", () => {
1715
- if (this.resizeDebounceTimer) {
1716
- clearTimeout(this.resizeDebounceTimer);
1717
- }
1718
- this.resizeDebounceTimer = window.setTimeout(() => {
1719
- this.updatePosition();
1720
- }, this.resizeDelay);
1721
- });
1743
+ window.addEventListener("resize", this.resizeHandler);
1722
1744
  this.update(view, view.state);
1723
1745
  if (this.getShouldShow()) {
1724
1746
  this.show();
@@ -1764,9 +1786,26 @@ var BubbleMenuView = class {
1764
1786
  }
1765
1787
  updatePosition() {
1766
1788
  const { selection } = this.editor.state;
1767
- const virtualElement = {
1768
- getBoundingClientRect: () => (0, import_core2.posToDOMRect)(this.view, selection.from, selection.to)
1789
+ let virtualElement = {
1790
+ getBoundingClientRect: () => (0, import_core3.posToDOMRect)(this.view, selection.from, selection.to)
1769
1791
  };
1792
+ if (selection instanceof import_tables.CellSelection) {
1793
+ const { $anchorCell, $headCell } = selection;
1794
+ const from = $anchorCell ? $anchorCell.pos : $headCell.pos;
1795
+ const to = $headCell ? $headCell.pos : $anchorCell.pos;
1796
+ const fromDOM = this.view.nodeDOM(from);
1797
+ const toDOM = this.view.nodeDOM(to);
1798
+ if (!fromDOM || !toDOM) {
1799
+ return;
1800
+ }
1801
+ const clientRect = fromDOM === toDOM ? fromDOM.getBoundingClientRect() : combineDOMRects(
1802
+ fromDOM.getBoundingClientRect(),
1803
+ toDOM.getBoundingClientRect()
1804
+ );
1805
+ virtualElement = {
1806
+ getBoundingClientRect: () => clientRect
1807
+ };
1808
+ }
1770
1809
  computePosition2(virtualElement, this.element, {
1771
1810
  placement: this.floatingUIOptions.placement,
1772
1811
  strategy: this.floatingUIOptions.strategy,
@@ -1776,6 +1815,9 @@ var BubbleMenuView = class {
1776
1815
  this.element.style.position = strategy;
1777
1816
  this.element.style.left = `${x}px`;
1778
1817
  this.element.style.top = `${y}px`;
1818
+ if (this.isVisible && this.floatingUIOptions.onUpdate) {
1819
+ this.floatingUIOptions.onUpdate();
1820
+ }
1779
1821
  });
1780
1822
  }
1781
1823
  update(view, oldState) {
@@ -1809,21 +1851,39 @@ var BubbleMenuView = class {
1809
1851
  }
1810
1852
  show() {
1811
1853
  var _a;
1854
+ if (this.isVisible) {
1855
+ return;
1856
+ }
1812
1857
  this.element.style.visibility = "visible";
1813
1858
  this.element.style.opacity = "1";
1814
1859
  (_a = this.view.dom.parentElement) == null ? void 0 : _a.appendChild(this.element);
1860
+ if (this.floatingUIOptions.onShow) {
1861
+ this.floatingUIOptions.onShow();
1862
+ }
1863
+ this.isVisible = true;
1815
1864
  }
1816
1865
  hide() {
1866
+ if (!this.isVisible) {
1867
+ return;
1868
+ }
1817
1869
  this.element.style.visibility = "hidden";
1818
1870
  this.element.style.opacity = "0";
1819
1871
  this.element.remove();
1872
+ if (this.floatingUIOptions.onHide) {
1873
+ this.floatingUIOptions.onHide();
1874
+ }
1875
+ this.isVisible = false;
1820
1876
  }
1821
1877
  destroy() {
1822
1878
  this.hide();
1823
1879
  this.element.removeEventListener("mousedown", this.mousedownHandler, { capture: true });
1824
1880
  this.view.dom.removeEventListener("dragstart", this.dragstartHandler);
1881
+ window.removeEventListener("resize", this.resizeHandler);
1825
1882
  this.editor.off("focus", this.focusHandler);
1826
1883
  this.editor.off("blur", this.blurHandler);
1884
+ if (this.floatingUIOptions.onDestroy) {
1885
+ this.floatingUIOptions.onDestroy();
1886
+ }
1827
1887
  }
1828
1888
  };
1829
1889
  var BubbleMenuPlugin = (options) => {
@@ -1832,9 +1892,34 @@ var BubbleMenuPlugin = (options) => {
1832
1892
  view: (view) => new BubbleMenuView({ view, ...options })
1833
1893
  });
1834
1894
  };
1895
+ var BubbleMenu = import_core2.Extension.create({
1896
+ name: "bubbleMenu",
1897
+ addOptions() {
1898
+ return {
1899
+ element: null,
1900
+ pluginKey: "bubbleMenu",
1901
+ updateDelay: void 0,
1902
+ shouldShow: null
1903
+ };
1904
+ },
1905
+ addProseMirrorPlugins() {
1906
+ if (!this.options.element) {
1907
+ return [];
1908
+ }
1909
+ return [
1910
+ BubbleMenuPlugin({
1911
+ pluginKey: this.options.pluginKey,
1912
+ editor: this.editor,
1913
+ element: this.options.element,
1914
+ updateDelay: this.options.updateDelay,
1915
+ shouldShow: this.options.shouldShow
1916
+ })
1917
+ ];
1918
+ }
1919
+ });
1835
1920
 
1836
1921
  // src/menus/BubbleMenu.ts
1837
- var BubbleMenu = {
1922
+ var BubbleMenu2 = {
1838
1923
  name: "BubbleMenu",
1839
1924
  props: {
1840
1925
  pluginKey: {
@@ -1895,18 +1980,20 @@ var BubbleMenu = {
1895
1980
  }
1896
1981
  };
1897
1982
 
1898
- // ../extension-floating-menu/src/floating-menu-plugin.ts
1899
- var import_core3 = require("@tiptap/core");
1983
+ // ../extension-floating-menu/dist/index.js
1984
+ var import_core4 = require("@tiptap/core");
1985
+ var import_core5 = require("@tiptap/core");
1900
1986
  var import_state2 = require("@tiptap/pm/state");
1901
1987
  var FloatingMenuView = class {
1902
1988
  constructor({ editor, element, view, options, shouldShow }) {
1903
1989
  this.preventHide = false;
1904
- this.shouldShow = ({ view, state }) => {
1990
+ this.isVisible = false;
1991
+ this.shouldShow = ({ view: view2, state }) => {
1905
1992
  const { selection } = state;
1906
1993
  const { $anchor, empty } = selection;
1907
1994
  const isRootDepth = $anchor.depth === 1;
1908
1995
  const isEmptyTextBlock = $anchor.parent.isTextblock && !$anchor.parent.type.spec.code && !$anchor.parent.textContent && $anchor.parent.childCount === 0 && !this.getTextContent($anchor.parent);
1909
- if (!view.hasFocus() || !empty || !isRootDepth || !isEmptyTextBlock || !this.editor.isEditable) {
1996
+ if (!view2.hasFocus() || !empty || !isRootDepth || !isEmptyTextBlock || !this.editor.isEditable) {
1910
1997
  return false;
1911
1998
  }
1912
1999
  return true;
@@ -1923,14 +2010,14 @@ var FloatingMenuView = class {
1923
2010
  hide: false,
1924
2011
  inline: false
1925
2012
  };
1926
- this.updateHandler = (view, selectionChanged, docChanged, oldState) => {
1927
- const { composing } = view;
2013
+ this.updateHandler = (view2, selectionChanged, docChanged, oldState) => {
2014
+ const { composing } = view2;
1928
2015
  const isSame = !selectionChanged && !docChanged;
1929
2016
  if (composing || isSame) {
1930
2017
  return;
1931
2018
  }
1932
- const shouldShow = this.getShouldShow(oldState);
1933
- if (!shouldShow) {
2019
+ const shouldShow2 = this.getShouldShow(oldState);
2020
+ if (!shouldShow2) {
1934
2021
  this.hide();
1935
2022
  return;
1936
2023
  }
@@ -1964,6 +2051,7 @@ var FloatingMenuView = class {
1964
2051
  ...this.floatingUIOptions,
1965
2052
  ...options
1966
2053
  };
2054
+ this.element.tabIndex = 0;
1967
2055
  if (shouldShow) {
1968
2056
  this.shouldShow = shouldShow;
1969
2057
  }
@@ -1976,7 +2064,7 @@ var FloatingMenuView = class {
1976
2064
  }
1977
2065
  }
1978
2066
  getTextContent(node) {
1979
- return (0, import_core3.getText)(node, { textSerializers: (0, import_core3.getTextSerializersFromSchema)(this.editor.schema) });
2067
+ return (0, import_core5.getText)(node, { textSerializers: (0, import_core5.getTextSerializersFromSchema)(this.editor.schema) });
1980
2068
  }
1981
2069
  get middlewares() {
1982
2070
  const middlewares = [];
@@ -2036,7 +2124,7 @@ var FloatingMenuView = class {
2036
2124
  updatePosition() {
2037
2125
  const { selection } = this.editor.state;
2038
2126
  const virtualElement = {
2039
- getBoundingClientRect: () => (0, import_core3.posToDOMRect)(this.view, selection.from, selection.to)
2127
+ getBoundingClientRect: () => (0, import_core5.posToDOMRect)(this.view, selection.from, selection.to)
2040
2128
  };
2041
2129
  computePosition2(virtualElement, this.element, {
2042
2130
  placement: this.floatingUIOptions.placement,
@@ -2047,6 +2135,9 @@ var FloatingMenuView = class {
2047
2135
  this.element.style.position = strategy;
2048
2136
  this.element.style.left = `${x}px`;
2049
2137
  this.element.style.top = `${y}px`;
2138
+ if (this.isVisible && this.floatingUIOptions.onUpdate) {
2139
+ this.floatingUIOptions.onUpdate();
2140
+ }
2050
2141
  });
2051
2142
  }
2052
2143
  update(view, oldState) {
@@ -2056,20 +2147,37 @@ var FloatingMenuView = class {
2056
2147
  }
2057
2148
  show() {
2058
2149
  var _a;
2150
+ if (this.isVisible) {
2151
+ return;
2152
+ }
2059
2153
  this.element.style.visibility = "visible";
2060
2154
  this.element.style.opacity = "1";
2061
2155
  (_a = this.view.dom.parentElement) == null ? void 0 : _a.appendChild(this.element);
2156
+ if (this.floatingUIOptions.onShow) {
2157
+ this.floatingUIOptions.onShow();
2158
+ }
2159
+ this.isVisible = true;
2062
2160
  }
2063
2161
  hide() {
2162
+ if (!this.isVisible) {
2163
+ return;
2164
+ }
2064
2165
  this.element.style.visibility = "hidden";
2065
2166
  this.element.style.opacity = "0";
2066
2167
  this.element.remove();
2168
+ if (this.floatingUIOptions.onHide) {
2169
+ this.floatingUIOptions.onHide();
2170
+ }
2171
+ this.isVisible = false;
2067
2172
  }
2068
2173
  destroy() {
2069
2174
  this.hide();
2070
2175
  this.element.removeEventListener("mousedown", this.mousedownHandler, { capture: true });
2071
2176
  this.editor.off("focus", this.focusHandler);
2072
2177
  this.editor.off("blur", this.blurHandler);
2178
+ if (this.floatingUIOptions.onDestroy) {
2179
+ this.floatingUIOptions.onDestroy();
2180
+ }
2073
2181
  }
2074
2182
  };
2075
2183
  var FloatingMenuPlugin = (options) => {
@@ -2078,9 +2186,34 @@ var FloatingMenuPlugin = (options) => {
2078
2186
  view: (view) => new FloatingMenuView({ view, ...options })
2079
2187
  });
2080
2188
  };
2189
+ var FloatingMenu = import_core4.Extension.create({
2190
+ name: "floatingMenu",
2191
+ addOptions() {
2192
+ return {
2193
+ element: null,
2194
+ options: {},
2195
+ pluginKey: "floatingMenu",
2196
+ shouldShow: null
2197
+ };
2198
+ },
2199
+ addProseMirrorPlugins() {
2200
+ if (!this.options.element) {
2201
+ return [];
2202
+ }
2203
+ return [
2204
+ FloatingMenuPlugin({
2205
+ pluginKey: this.options.pluginKey,
2206
+ editor: this.editor,
2207
+ element: this.options.element,
2208
+ options: this.options.options,
2209
+ shouldShow: this.options.shouldShow
2210
+ })
2211
+ ];
2212
+ }
2213
+ });
2081
2214
 
2082
2215
  // src/menus/FloatingMenu.ts
2083
- var FloatingMenu = {
2216
+ var FloatingMenu2 = {
2084
2217
  name: "FloatingMenu",
2085
2218
  props: {
2086
2219
  pluginKey: {