You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							173 lines
						
					
					
						
							6.2 KiB
						
					
					
				
			
		
		
	
	
							173 lines
						
					
					
						
							6.2 KiB
						
					
					
				'use strict';
 | 
						|
 | 
						|
Object.defineProperty(exports, '__esModule', { value: true });
 | 
						|
 | 
						|
var core = require('@tiptap/core');
 | 
						|
var prosemirrorState = require('prosemirror-state');
 | 
						|
var tippy = require('tippy.js');
 | 
						|
 | 
						|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
 | 
						|
 | 
						|
var tippy__default = /*#__PURE__*/_interopDefaultLegacy(tippy);
 | 
						|
 | 
						|
class FloatingMenuView {
 | 
						|
    constructor({ editor, element, view, tippyOptions = {}, shouldShow, }) {
 | 
						|
        this.preventHide = false;
 | 
						|
        this.shouldShow = ({ view, state }) => {
 | 
						|
            const { selection } = state;
 | 
						|
            const { $anchor, empty } = selection;
 | 
						|
            const isRootDepth = $anchor.depth === 1;
 | 
						|
            const isEmptyTextBlock = $anchor.parent.isTextblock
 | 
						|
                && !$anchor.parent.type.spec.code
 | 
						|
                && !$anchor.parent.textContent;
 | 
						|
            if (!view.hasFocus()
 | 
						|
                || !empty
 | 
						|
                || !isRootDepth
 | 
						|
                || !isEmptyTextBlock
 | 
						|
                || !this.editor.isEditable) {
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
            return true;
 | 
						|
        };
 | 
						|
        this.mousedownHandler = () => {
 | 
						|
            this.preventHide = true;
 | 
						|
        };
 | 
						|
        this.focusHandler = () => {
 | 
						|
            // we use `setTimeout` to make sure `selection` is already updated
 | 
						|
            setTimeout(() => this.update(this.editor.view));
 | 
						|
        };
 | 
						|
        this.blurHandler = ({ event }) => {
 | 
						|
            var _a;
 | 
						|
            if (this.preventHide) {
 | 
						|
                this.preventHide = false;
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            if ((event === null || event === void 0 ? void 0 : event.relatedTarget)
 | 
						|
                && ((_a = this.element.parentNode) === null || _a === void 0 ? void 0 : _a.contains(event.relatedTarget))) {
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            this.hide();
 | 
						|
        };
 | 
						|
        this.tippyBlurHandler = (event) => {
 | 
						|
            this.blurHandler({ event });
 | 
						|
        };
 | 
						|
        this.editor = editor;
 | 
						|
        this.element = element;
 | 
						|
        this.view = view;
 | 
						|
        if (shouldShow) {
 | 
						|
            this.shouldShow = shouldShow;
 | 
						|
        }
 | 
						|
        this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true });
 | 
						|
        this.editor.on('focus', this.focusHandler);
 | 
						|
        this.editor.on('blur', this.blurHandler);
 | 
						|
        this.tippyOptions = tippyOptions;
 | 
						|
        // Detaches menu content from its current parent
 | 
						|
        this.element.remove();
 | 
						|
        this.element.style.visibility = 'visible';
 | 
						|
    }
 | 
						|
    createTooltip() {
 | 
						|
        const { element: editorElement } = this.editor.options;
 | 
						|
        const editorIsAttached = !!editorElement.parentElement;
 | 
						|
        if (this.tippy || !editorIsAttached) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        this.tippy = tippy__default["default"](editorElement, {
 | 
						|
            duration: 0,
 | 
						|
            getReferenceClientRect: null,
 | 
						|
            content: this.element,
 | 
						|
            interactive: true,
 | 
						|
            trigger: 'manual',
 | 
						|
            placement: 'right',
 | 
						|
            hideOnClick: 'toggle',
 | 
						|
            ...this.tippyOptions,
 | 
						|
        });
 | 
						|
        // maybe we have to hide tippy on its own blur event as well
 | 
						|
        if (this.tippy.popper.firstChild) {
 | 
						|
            this.tippy.popper.firstChild.addEventListener('blur', this.tippyBlurHandler);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    update(view, oldState) {
 | 
						|
        var _a, _b, _c;
 | 
						|
        const { state } = view;
 | 
						|
        const { doc, selection } = state;
 | 
						|
        const { from, to } = selection;
 | 
						|
        const isSame = oldState && oldState.doc.eq(doc) && oldState.selection.eq(selection);
 | 
						|
        if (isSame) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        this.createTooltip();
 | 
						|
        const shouldShow = (_a = this.shouldShow) === null || _a === void 0 ? void 0 : _a.call(this, {
 | 
						|
            editor: this.editor,
 | 
						|
            view,
 | 
						|
            state,
 | 
						|
            oldState,
 | 
						|
        });
 | 
						|
        if (!shouldShow) {
 | 
						|
            this.hide();
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        (_b = this.tippy) === null || _b === void 0 ? void 0 : _b.setProps({
 | 
						|
            getReferenceClientRect: ((_c = this.tippyOptions) === null || _c === void 0 ? void 0 : _c.getReferenceClientRect) || (() => core.posToDOMRect(view, from, to)),
 | 
						|
        });
 | 
						|
        this.show();
 | 
						|
    }
 | 
						|
    show() {
 | 
						|
        var _a;
 | 
						|
        (_a = this.tippy) === null || _a === void 0 ? void 0 : _a.show();
 | 
						|
    }
 | 
						|
    hide() {
 | 
						|
        var _a;
 | 
						|
        (_a = this.tippy) === null || _a === void 0 ? void 0 : _a.hide();
 | 
						|
    }
 | 
						|
    destroy() {
 | 
						|
        var _a, _b;
 | 
						|
        if ((_a = this.tippy) === null || _a === void 0 ? void 0 : _a.popper.firstChild) {
 | 
						|
            this.tippy.popper.firstChild.removeEventListener('blur', this.tippyBlurHandler);
 | 
						|
        }
 | 
						|
        (_b = this.tippy) === null || _b === void 0 ? void 0 : _b.destroy();
 | 
						|
        this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true });
 | 
						|
        this.editor.off('focus', this.focusHandler);
 | 
						|
        this.editor.off('blur', this.blurHandler);
 | 
						|
    }
 | 
						|
}
 | 
						|
const FloatingMenuPlugin = (options) => {
 | 
						|
    return new prosemirrorState.Plugin({
 | 
						|
        key: typeof options.pluginKey === 'string'
 | 
						|
            ? new prosemirrorState.PluginKey(options.pluginKey)
 | 
						|
            : options.pluginKey,
 | 
						|
        view: view => new FloatingMenuView({ view, ...options }),
 | 
						|
    });
 | 
						|
};
 | 
						|
 | 
						|
const FloatingMenu = core.Extension.create({
 | 
						|
    name: 'floatingMenu',
 | 
						|
    addOptions() {
 | 
						|
        return {
 | 
						|
            element: null,
 | 
						|
            tippyOptions: {},
 | 
						|
            pluginKey: 'floatingMenu',
 | 
						|
            shouldShow: null,
 | 
						|
        };
 | 
						|
    },
 | 
						|
    addProseMirrorPlugins() {
 | 
						|
        if (!this.options.element) {
 | 
						|
            return [];
 | 
						|
        }
 | 
						|
        return [
 | 
						|
            FloatingMenuPlugin({
 | 
						|
                pluginKey: this.options.pluginKey,
 | 
						|
                editor: this.editor,
 | 
						|
                element: this.options.element,
 | 
						|
                tippyOptions: this.options.tippyOptions,
 | 
						|
                shouldShow: this.options.shouldShow,
 | 
						|
            }),
 | 
						|
        ];
 | 
						|
    },
 | 
						|
});
 | 
						|
 | 
						|
exports.FloatingMenu = FloatingMenu;
 | 
						|
exports.FloatingMenuPlugin = FloatingMenuPlugin;
 | 
						|
exports.FloatingMenuView = FloatingMenuView;
 | 
						|
exports["default"] = FloatingMenu;
 | 
						|
//# sourceMappingURL=tiptap-extension-floating-menu.cjs.map
 |