diff --git a/webapp/components/Editor/ContextMenu.vue b/webapp/components/Editor/ContextMenu.vue
new file mode 100644
index 000000000..4297cf971
--- /dev/null
+++ b/webapp/components/Editor/ContextMenu.vue
@@ -0,0 +1,52 @@
+
diff --git a/webapp/components/Editor/Editor.vue b/webapp/components/Editor/Editor.vue
index d660e9d15..9e1787862 100644
--- a/webapp/components/Editor/Editor.vue
+++ b/webapp/components/Editor/Editor.vue
@@ -48,6 +48,7 @@
+
@@ -56,7 +57,6 @@ import defaultExtensions from './defaultExtensions.js'
import linkify from 'linkify-it'
import stringHash from 'string-hash'
import Fuse from 'fuse.js'
-import tippy from 'tippy.js'
import { Editor, EditorContent, EditorMenuBubble } from 'tiptap'
import EventHandler from './plugins/eventHandler.js'
import { History } from 'tiptap-extensions'
@@ -65,6 +65,7 @@ import Mention from './nodes/Mention.js'
import { mapGetters } from 'vuex'
import MenuBar from './MenuBar'
import SuggestionsMenu from './SuggestionsMenu'
+import ContextMenu from './ContextMenu'
let throttleInputEvent
@@ -74,6 +75,7 @@ export default {
EditorMenuBubble,
MenuBar,
SuggestionsMenu,
+ ContextMenu,
},
props: {
users: { type: Array, default: () => null }, // If 'null', than the Mention extention is not assigned.
@@ -99,7 +101,7 @@ export default {
this.query = query
this.filteredItems = items
this.suggestionRange = range
- this.renderPopup(virtualNode)
+ this.$refs.contextMenu.displayContextMenu(virtualNode, this.$refs.suggestions.$el)
// we save the command for inserting a selected mention
// this allows us to call it inside of our custom popup
// via keyboard navigation and on click
@@ -111,7 +113,7 @@ export default {
this.filteredItems = items
this.suggestionRange = range
this.navigatedItemIndex = 0
- this.renderPopup(virtualNode)
+ this.$refs.contextMenu.displayContextMenu(virtualNode, this.$refs.suggestions.$el)
},
// is called when a suggestion is cancelled
onExit: () => {
@@ -122,7 +124,7 @@ export default {
this.filteredItems = []
this.suggestionRange = null
this.navigatedItemIndex = 0
- this.destroyPopup()
+ this.$refs.contextMenu.hideContextMenu()
},
// is called on every keyDown event while a suggestion is active
onKeyDown: ({ event }) => {
@@ -175,7 +177,7 @@ export default {
this.query = this.sanitizedQuery(query)
this.filteredItems = items
this.suggestionRange = range
- this.renderPopup(virtualNode)
+ this.$refs.contextMenu.displayContextMenu(virtualNode, this.$refs.suggestions.$el)
// we save the command for inserting a selected mention
// this allows us to call it inside of our custom popup
// via keyboard navigation and on click
@@ -187,7 +189,7 @@ export default {
this.filteredItems = items
this.suggestionRange = range
this.navigatedItemIndex = 0
- this.renderPopup(virtualNode)
+ this.$refs.contextMenu.displayContextMenu(virtualNode, this.$refs.suggestions.$el)
},
// is called when a suggestion is cancelled
onExit: () => {
@@ -198,7 +200,7 @@ export default {
this.filteredItems = []
this.suggestionRange = null
this.navigatedItemIndex = 0
- this.destroyPopup()
+ this.$refs.contextMenu.hideContextMenu()
},
// is called on every keyDown event while a suggestion is active
onKeyDown: ({ event }) => {
@@ -363,45 +365,6 @@ export default {
})
this.editor.focus()
},
- // renders a popup with suggestions
- // tiptap provides a virtualNode object for using popper.js (or tippy.js) for popups
- renderPopup(node) {
- if (this.popup) {
- return
- }
- this.popup = tippy(node, {
- content: this.$refs.suggestions.$el,
- trigger: 'mouseenter',
- interactive: true,
- theme: 'dark',
- placement: 'top-start',
- inertia: true,
- duration: [400, 200],
- showOnInit: true,
- arrow: true,
- arrowType: 'round',
- })
- // we have to update tippy whenever the DOM is updated
- if (MutationObserver) {
- this.observer = new MutationObserver(() => {
- this.popup.popperInstance.scheduleUpdate()
- })
- this.observer.observe(this.$refs.suggestions.$el, {
- childList: true,
- subtree: true,
- characterData: true,
- })
- }
- },
- destroyPopup() {
- if (this.popup) {
- this.popup.destroy()
- this.popup = null
- }
- if (this.observer) {
- this.observer.disconnect()
- }
- },
onUpdate(e) {
const content = e.getHTML()
const contentHash = stringHash(content)