diff --git a/packages/tiptap/src/Plugins/MenuBubble.js b/packages/tiptap/src/Plugins/MenuBubble.js index 95510b7796b..db90d2c23e1 100644 --- a/packages/tiptap/src/Plugins/MenuBubble.js +++ b/packages/tiptap/src/Plugins/MenuBubble.js @@ -16,22 +16,24 @@ class Menu { this.bottom = 0 this.editorView.dom.addEventListener('blur', this.hide.bind(this)) + this.startObservingSize() } - update(view, lastState) { - const { state } = view - - // Don't do anything if the document/selection didn't change - if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) { - return - } + startObservingSize() { + if(window && window.ResizeObserver) + this.observer = new ResizeObserver(() => { + this.reposition(this.editorView) + this.sendUpdate() + }) + this.observer.observe(this.options.element) + } - // Hide the tooltip if the selection is empty - if (state.selection.empty) { - this.hide() - return - } + stopObservingSize() { + this.observer && this.observer.unobserve(this.options.element) + } + reposition(view) { + const { state } = view // Otherwise, reposition it and update its content const { from, to } = state.selection @@ -41,14 +43,32 @@ class Menu { // The box in which the tooltip is positioned, to use as base const box = this.options.element.offsetParent.getBoundingClientRect() + const el = this.options.element.getBoundingClientRect() // Find a center-ish x position from the selection endpoints (when // crossing lines, end may be more to the left) - const left = Math.max((start.left + end.left) / 2, start.left + 3) - - this.isActive = true + const left = Math.max((start.left + end.left) / 2, start.left + 3, el.width / 2) + // console.log(`${left} - ${box.left} > ${el.width} / 2`, left - box.left, el.width / 2) this.left = parseInt(left - box.left, 10) this.bottom = parseInt(box.bottom - start.top, 10) + } + + update(view, lastState) { + const { state } = view + + // Don't do anything if the document/selection didn't change + if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) { + return + } + + // Hide the tooltip if the selection is empty + if (state.selection.empty) { + this.hide() + return + } + + this.reposition(view) + this.isActive = true this.sendUpdate() } @@ -71,6 +91,7 @@ class Menu { } destroy() { + this.stopObservingSize() this.editorView.dom.removeEventListener('blur', this.hide) }