<template>
    <div class="quill" ref="quill" :class="classes">
        <div ref="editor" :style="styles" v-loading="loading"></div>

        <el-upload
            :headers="headers"
            :action="joggle"
            :before-upload="beforeUpload"
            :on-success="editorUploadSuccess"
            style="display: none"
        >
            <el-button class="editorUpload" type="primary">点击上传</el-button>
        </el-upload>
    </div>
</template>

<script>
import Quill from "quill";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import toolbarOptions from "./options";
import { joggle } from "@/apis/request.js";
import { joggleFn } from "@/apis/request.js";
export default {
    name: "quill",
    props: {
        value: {
            type: String,
            default: ""
        },
        readonly: {
            type: Boolean,
            default: false
        },
        toTop: {
            type: Boolean,
            default: true
        },
        border: {
            type: Boolean,
            default: false
        },
        height: {
            type: Number
        },
        minHeight: {
            type: Number
        },
        /*
         * 原本的readOnly失效,对比其他项目，发现是quill版本不同导致，
         * 使用props传入elseRead = 'true'，手动隐藏工具栏
         */
        elseRead: {
            type: String, default: "false"
        }
    },
    data() {
        return {
            joggle,
            headers: {
                token: sessionStorage.getItem('token')
            },
            Quill: null,
            currentValue: "",
            options: {
                theme: "snow",
                bounds: document.body,
                debug: "warn",
                modules: {
                    toolbar: {
                        container: toolbarOptions,
                        handlers: {
                            "image": function(value) {
                                if (value) {
                                    // 调用iview图片上传
                                    document.querySelector(".editorUpload").click()
                                } else {
                                    this.Quill.format("image", false)
                                }
                            }
                        }
                    }
                },
                placeholder: "",
                readOnly: this.readonly
            },
            loading: false
        };
    },
    computed: {
        classes() {
            return [
                {
                    "quill-no-border": !this.border
                }
            ];
        },
        styles() {
            let style = {};
            if (this.minHeight) {
                style.minHeight = `${this.minHeight}px`;
            }
            if (this.height) {
                style.height = `${this.height}px`;
            }
            return style;
        }

    },
    watch: {
        value: {
            handler(val) {
                if (val !== this.currentValue) {
                    this.currentValue = val;
                    if (this.Quill) {
                        this.Quill.pasteHTML(this.value);
                    }
                }
            },
            immediate: true
        }
    },
    created() {
    },
    mounted() {
        this.init();
        // 处理工具栏隐藏样式
        if (this.elseRead === "true") {
            let children = this.$refs.quill.children[0].style;
            children.padding = "0";
            children.overflow = "hidden";
            children.height = "0";
            children.borderTop = "0";
        }
    },
    beforeDestroy() {
        // 在组件销毁后销毁实例
        this.Quill = null;
    },
    methods: {
        init () {
            const editor = this.$refs.editor;
            // 初始化编辑器
            this.Quill = new Quill(editor, this.options);
            const ins = this.Quill
            // 默认值
            ins.pasteHTML(this.currentValue);
            if(this.toTop){
                this.$nextTick(() => {
                    window.scrollTo(0,0)
                })
            }
            // 绑定事件
            ins.on('text-change', () => {
                const html = this.$refs.editor.children[0].innerHTML;
                const text = ins.getText();
                const quill = this.Quill;
                // 更新内部的值
                this.currentValue = html;
                // 发出事件 v-model
                this.$emit('input', html);
                // 发出事件
                this.$emit('on-change', { html, text, quill });
            });
            // 将一些 quill 自带的事件传递出去
            ins.on('text-change', (delta, oldDelta, source) => {
                this.$emit('on-text-change', delta, oldDelta, source);
            });
            ins.on('selection-change', (range, oldRange, source) => {
                this.$emit('on-selection-change', range, oldRange, source);
            });
            ins.on('editor-change', (eventName, ...args) => {
                this.$emit('on-editor-change', eventName, ...args);
            });
            // 监听粘贴事件
            ins.root.addEventListener('paste', evt => {
                if (evt.clipboardData && evt.clipboardData.files && evt.clipboardData.files.length) {
                    evt.preventDefault();
                    // 检测是否粘贴的是图片
                    [].forEach.call(evt.clipboardData.files, file => {
                        if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
                            return
                        }
                        const param = new FormData()
                        param.append('file', file)
                        // 把图片上传到服务器，不然会直接把base64存到数据库
                        joggleFn(param, {
                            headers: { "Content-Type": "multipart/form-data" }
                        }).then(res => {
                            var range = ins.getSelection()
                            if (range) {
                                //  在当前光标位置插入图片
                                ins.insertEmbed(range.index, 'image', res.fileUrl)
                                //  将光标移动到图片后面
                                ins.setSelection(range.index + 1)
                            }
                        }).catch(res => {
                            console.log(res)
                        })
                    });
                }
            }, false)
        },
        beforeUpload() {
            this.loading = true;
        },
        editorUploadSuccess(res) {
            // 获取富文本组件实例
            let quill = this.Quill;
            // 如果上传成功
            const url = res.data.fileUrl
            if (url) {
                // 获取光标所在位置
                let length = quill.getSelection().index;
                // 插入图片，res为服务器返回的图片链接地址
                quill.insertEmbed(length, "image", url);
                // 调整光标到最后
                quill.setSelection(length + 1);
            } else {
                this.$message.error("图片插入失败");
            }
            this.loading = false;
        }
    }
};
</script>
<style lang="less">
.quill-no-border {
    .ql-toolbar.ql-snow {
        border: none;
        border-bottom: 1px solid #e8eaec;
    }

    .ql-container.ql-snow {
        border: none;
    }
}

.else {
    .ql-toolbar.ql-snow {
        height: 0;
        overflow: hidden;
        padding: 0;
        border-top: 0;
    }
}
/deep/.ql-snow {
    position: relative;
    .ql-tooltip {
        position: absolute !important;
        top: 10px !important;
        left: 10px !important;
        transform: translateY(10px);
    }
}
</style>