mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-12-05 04:19:07 +08:00
fix bubble menu
This commit is contained in:
parent
3718591d33
commit
a2dd57ad09
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="editor">
|
<div class="editor">
|
||||||
<menu-bubble class="menubar" :editor="editor">
|
<menu-bubble class="menububble" :editor="editor">
|
||||||
<template slot-scope="{ nodes, marks }">
|
<template slot-scope="{ nodes, marks }">
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import MenuBubble from '../Utils/MenuBubble'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
editor: {
|
editor: {
|
||||||
@ -5,6 +7,18 @@ export default {
|
|||||||
type: Object,
|
type: Object,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
editor: {
|
||||||
|
immediate: true,
|
||||||
|
handler(editor) {
|
||||||
|
if (editor) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
editor.registerPlugin(MenuBubble(this.$el))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
render(createElement) {
|
render(createElement) {
|
||||||
if (this.editor) {
|
if (this.editor) {
|
||||||
return createElement('div', this.$scopedSlots.default({
|
return createElement('div', this.$scopedSlots.default({
|
||||||
|
@ -247,6 +247,16 @@ export default class Editor {
|
|||||||
this.bus.$on(event, callback)
|
this.bus.$on(event, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerPlugin(plugin = null) {
|
||||||
|
if (plugin) {
|
||||||
|
this.plugins = this.plugins.concat([plugin])
|
||||||
|
this.state = this.state.reconfigure({
|
||||||
|
plugins: this.plugins,
|
||||||
|
})
|
||||||
|
this.view.updateState(this.state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.emit('destroy')
|
this.emit('destroy')
|
||||||
|
|
||||||
|
72
packages/tiptap/src/utils/MenuBubble.js
Normal file
72
packages/tiptap/src/utils/MenuBubble.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { Plugin } from 'prosemirror-state'
|
||||||
|
|
||||||
|
class Toolbar {
|
||||||
|
|
||||||
|
constructor({ element, editorView }) {
|
||||||
|
this.editorView = editorView
|
||||||
|
this.element = element
|
||||||
|
this.element.style.visibility = 'hidden'
|
||||||
|
this.element.style.opacity = 0
|
||||||
|
|
||||||
|
this.editorView.dom.addEventListener('blur', this.hide.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, reposition it and update its content
|
||||||
|
this.show()
|
||||||
|
const { from, to } = state.selection
|
||||||
|
|
||||||
|
// These are in screen coordinates
|
||||||
|
const start = view.coordsAtPos(from)
|
||||||
|
const end = view.coordsAtPos(to)
|
||||||
|
|
||||||
|
// The box in which the tooltip is positioned, to use as base
|
||||||
|
const box = this.element.offsetParent.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.element.style.left = `${left - box.left}px`
|
||||||
|
this.element.style.bottom = `${box.bottom - start.top}px`
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
this.element.style.visibility = 'visible'
|
||||||
|
this.element.style.opacity = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
hide(event) {
|
||||||
|
if (event && event.relatedTarget) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.element.style.visibility = 'hidden'
|
||||||
|
this.element.style.opacity = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.editorView.dom.removeEventListener('blur', this.hide)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function (element) {
|
||||||
|
return new Plugin({
|
||||||
|
view(editorView) {
|
||||||
|
return new Toolbar({ editorView, element })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user