/*!
 * VueQuill @vueup/vue-quill v1.2.0
 * https://vueup.github.io/vue-quill/
 * 
 * Includes quill v1.3.7
 * https://quilljs.com/
 * 
 * Copyright (c) 2023 Ahmad Luthfi Masruri
 * Released under the MIT license
 * Date: 2023-05-12T08:44:03.742Z
 */
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var Quill = require('quill');
var Delta = require('quill-delta');
var vue = require('vue');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }

var Quill__default = /*#__PURE__*/_interopDefaultLegacy(Quill);
var Delta__default = /*#__PURE__*/_interopDefaultLegacy(Delta);

const toolbarOptions = {
    essential: [
        [{ header: [1, 2, 3, 4, 5, 6, false] }],
        ['bold', 'italic', 'underline'],
        [{ list: 'ordered' }, { list: 'bullet' }, { align: [] }],
        ['blockquote', 'code-block', 'link'],
        [{ color: [] }, 'clean'],
    ],
    minimal: [
        [{ header: 1 }, { header: 2 }],
        ['bold', 'italic', 'underline'],
        [{ list: 'ordered' }, { list: 'bullet' }, { align: [] }],
    ],
    full: [
        ['bold', 'italic', 'underline', 'strike'],
        ['blockquote', 'code-block'],
        [{ header: 1 }, { header: 2 }],
        [{ list: 'ordered' }, { list: 'bullet' }],
        [{ script: 'sub' }, { script: 'super' }],
        [{ indent: '-1' }, { indent: '+1' }],
        [{ direction: 'rtl' }],
        [{ size: ['small', false, 'large', 'huge'] }],
        [{ header: [1, 2, 3, 4, 5, 6, false] }],
        [{ color: [] }, { background: [] }],
        [{ font: [] }],
        [{ align: [] }],
        ['link', 'video', 'image'],
        ['clean'], // remove formatting button
    ],
};

const QuillEditor = vue.defineComponent({
    name: 'QuillEditor',
    inheritAttrs: false,
    props: {
        content: {
            type: [String, Object],
        },
        contentType: {
            type: String,
            default: 'delta',
            validator: (value) => {
                return ['delta', 'html', 'text'].includes(value);
            },
        },
        enable: {
            type: Boolean,
            default: true,
        },
        readOnly: {
            type: Boolean,
            default: false,
        },
        placeholder: {
            type: String,
            required: false,
        },
        theme: {
            type: String,
            default: 'snow',
            validator: (value) => {
                return ['snow', 'bubble', ''].includes(value);
            },
        },
        toolbar: {
            type: [String, Array, Object],
            required: false,
            validator: (value) => {
                if (typeof value === 'string' && value !== '') {
                    return value.charAt(0) === '#'
                        ? true
                        : Object.keys(toolbarOptions).indexOf(value) !== -1;
                }
                return true;
            },
        },
        modules: {
            type: Object,
            required: false,
        },
        options: {
            type: Object,
            required: false,
        },
        globalOptions: {
            type: Object,
            required: false,
        },
    },
    emits: [
        'textChange',
        'selectionChange',
        'editorChange',
        'update:content',
        'focus',
        'blur',
        'ready',
    ],
    setup: (props, ctx) => {
        vue.onMounted(() => {
            initialize();
        });
        vue.onBeforeUnmount(() => {
            quill = null;
        });
        let quill;
        let options;
        const editor = vue.ref();
        // Initialize Quill
        const initialize = () => {
            var _a;
            if (!editor.value)
                return;
            options = composeOptions();
            // Register modules
            if (props.modules) {
                if (Array.isArray(props.modules)) {
                    for (const module of props.modules) {
                        Quill__default.register(`modules/${module.name}`, module.module);
                    }
                }
                else {
                    Quill__default.register(`modules/${props.modules.name}`, props.modules.module);
                }
            }
            // Create new Quill instance
            quill = new Quill__default(editor.value, options);
            // Set editor content
            setContents(props.content);
            // Set event handlers
            quill.on('text-change', handleTextChange);
            quill.on('selection-change', handleSelectionChange);
            quill.on('editor-change', handleEditorChange);
            // Remove editor class when theme changes
            if (props.theme !== 'bubble')
                editor.value.classList.remove('ql-bubble');
            if (props.theme !== 'snow')
                editor.value.classList.remove('ql-snow');
            // Fix clicking the quill toolbar is detected as blur event
            (_a = quill
                .getModule('toolbar')) === null || _a === void 0 ? void 0 : _a.container.addEventListener('mousedown', (e) => {
                e.preventDefault();
            });
            // Emit ready event
            ctx.emit('ready', quill);
        };
        // Compose Options
        const composeOptions = () => {
            const clientOptions = {};
            if (props.theme !== '')
                clientOptions.theme = props.theme;
            if (props.readOnly)
                clientOptions.readOnly = props.readOnly;
            if (props.placeholder)
                clientOptions.placeholder = props.placeholder;
            if (props.toolbar && props.toolbar !== '') {
                clientOptions.modules = {
                    toolbar: (() => {
                        if (typeof props.toolbar === 'object') {
                            return props.toolbar;
                        }
                        else if (typeof props.toolbar === 'string') {
                            const str = props.toolbar;
                            return str.charAt(0) === '#'
                                ? props.toolbar
                                : toolbarOptions[props.toolbar];
                        }
                        return;
                    })(),
                };
            }
            if (props.modules) {
                const modules = (() => {
                    var _a, _b;
                    const modulesOption = {};
                    if (Array.isArray(props.modules)) {
                        for (const module of props.modules) {
                            modulesOption[module.name] = (_a = module.options) !== null && _a !== void 0 ? _a : {};
                        }
                    }
                    else {
                        modulesOption[props.modules.name] = (_b = props.modules.options) !== null && _b !== void 0 ? _b : {};
                    }
                    return modulesOption;
                })();
                clientOptions.modules = Object.assign({}, clientOptions.modules, modules);
            }
            return Object.assign({}, props.globalOptions, props.options, clientOptions);
        };
        const maybeClone = (delta) => {
            return typeof delta === 'object' && delta ? delta.slice() : delta;
        };
        const deltaHasValuesOtherThanRetain = (delta) => {
            return Object.values(delta.ops).some((v) => !v.retain || Object.keys(v).length !== 1);
        };
        // Doesn't need reactivity, but does need to be cloned to avoid deep mutations always registering as equal
        let internalModel;
        const internalModelEquals = (against) => {
            if (typeof internalModel === typeof against) {
                if (against === internalModel) {
                    return true;
                }
                // Ref/Proxy does not support instanceof, so do a loose check
                if (typeof against === 'object' &&
                    against &&
                    typeof internalModel === 'object' &&
                    internalModel) {
                    return !deltaHasValuesOtherThanRetain(internalModel.diff(against));
                }
            }
            return false;
        };
        const handleTextChange = (delta, oldContents, source) => {
            internalModel = maybeClone(getContents());
            // Update v-model:content when text changes
            if (!internalModelEquals(props.content)) {
                ctx.emit('update:content', internalModel);
            }
            ctx.emit('textChange', { delta, oldContents, source });
        };
        const isEditorFocus = vue.ref();
        const handleSelectionChange = (range, oldRange, source) => {
            // Set isEditorFocus if quill.hasFocus()
            isEditorFocus.value = !!(quill === null || quill === void 0 ? void 0 : quill.hasFocus());
            ctx.emit('selectionChange', { range, oldRange, source });
        };
        vue.watch(isEditorFocus, (focus) => {
            if (focus)
                ctx.emit('focus', editor);
            else
                ctx.emit('blur', editor);
        });
        const handleEditorChange = (...args) => {
            if (args[0] === 'text-change')
                ctx.emit('editorChange', {
                    name: args[0],
                    delta: args[1],
                    oldContents: args[2],
                    source: args[3],
                });
            if (args[0] === 'selection-change')
                ctx.emit('editorChange', {
                    name: args[0],
                    range: args[1],
                    oldRange: args[2],
                    source: args[3],
                });
        };
        const getEditor = () => {
            return editor.value;
        };
        const getToolbar = () => {
            var _a;
            return (_a = quill === null || quill === void 0 ? void 0 : quill.getModule('toolbar')) === null || _a === void 0 ? void 0 : _a.container;
        };
        const getQuill = () => {
            if (quill)
                return quill;
            else
                throw `The quill editor hasn't been instantiated yet,
                  make sure to call this method when the editor ready
                  or use v-on:ready="onReady(quill)" event instead.`;
        };
        const getContents = (index, length) => {
            if (props.contentType === 'html') {
                return getHTML();
            }
            else if (props.contentType === 'text') {
                return getText(index, length);
            }
            return quill === null || quill === void 0 ? void 0 : quill.getContents(index, length);
        };
        const setContents = (content, source = 'api') => {
            const normalizedContent = !content
                ? props.contentType === 'delta'
                    ? new Delta__default()
                    : ''
                : content;
            if (props.contentType === 'html') {
                setHTML(normalizedContent);
            }
            else if (props.contentType === 'text') {
                setText(normalizedContent, source);
            }
            else {
                quill === null || quill === void 0 ? void 0 : quill.setContents(normalizedContent, source);
            }
            internalModel = maybeClone(normalizedContent);
        };
        const getText = (index, length) => {
            var _a;
            return (_a = quill === null || quill === void 0 ? void 0 : quill.getText(index, length)) !== null && _a !== void 0 ? _a : '';
        };
        const setText = (text, source = 'api') => {
            quill === null || quill === void 0 ? void 0 : quill.setText(text, source);
        };
        const getHTML = () => {
            var _a;
            return (_a = quill === null || quill === void 0 ? void 0 : quill.root.innerHTML) !== null && _a !== void 0 ? _a : '';
        };
        const setHTML = (html) => {
            if (quill)
                quill.root.innerHTML = html;
        };
        const pasteHTML = (html, source = 'api') => {
            const delta = quill === null || quill === void 0 ? void 0 : quill.clipboard.convert(html);
            if (delta)
                quill === null || quill === void 0 ? void 0 : quill.setContents(delta, source);
        };
        const focus = () => {
            quill === null || quill === void 0 ? void 0 : quill.focus();
        };
        const reinit = () => {
            vue.nextTick(() => {
                var _a;
                if (!ctx.slots.toolbar && quill)
                    (_a = quill.getModule('toolbar')) === null || _a === void 0 ? void 0 : _a.container.remove();
                initialize();
            });
        };
        vue.watch(() => props.content, (newContent) => {
            if (!quill || !newContent || internalModelEquals(newContent))
                return;
            // Restore the selection and cursor position after updating the content
            const selection = quill.getSelection();
            if (selection) {
                vue.nextTick(() => quill === null || quill === void 0 ? void 0 : quill.setSelection(selection));
            }
            setContents(newContent);
        }, { deep: true });
        vue.watch(() => props.enable, (newValue) => {
            if (quill)
                quill.enable(newValue);
        });
        return {
            editor,
            getEditor,
            getToolbar,
            getQuill,
            getContents,
            setContents,
            getHTML,
            setHTML,
            pasteHTML,
            focus,
            getText,
            setText,
            reinit,
        };
    },
    render() {
        var _a, _b;
        return [
            (_b = (_a = this.$slots).toolbar) === null || _b === void 0 ? void 0 : _b.call(_a),
            vue.h('div', { ref: 'editor', ...this.$attrs }),
        ];
    },
});

exports.Quill = Quill__default;
exports.Delta = Delta__default;
exports.QuillEditor = QuillEditor;
