构建自定义Quill Editor主题

时间:2016-12-13 22:19:59

标签: javascript ecmascript-6 quill

我正在尝试为我的应用程序组建一个基于Quill的自定义default Snow theme主题。

我的项目是在ES6中构建的,因此我不得不相应地调整Snow主题(主要是用变量名this替换let tooltip = this的实例。

我遇到问题的区域是显示链接工具提示。我非常接近它的工作(我可以添加链接),但当用户将光标放在超链接上时,我现在停留在显示链接的预览。

我已设法将其缩小到以下一行:

let [link, offset] = tooltip.quill.scroll.descendant(LinkBlot, range.index);

Range.index是用户光标的正确索引。但link始终为null,偏移量始终为-1,无论用户的光标位置是打开还是关闭超链接。

为什么scroll.descendant函数无法正确检索用户所在的链接?

完整的主题代码:

import extend from 'extend';
import Emitter from 'quill/core/emitter';
import BaseTheme, { BaseTooltip } from 'quill/themes/base';
import LinkBlot from 'quill/formats/link';
import { Range } from 'quill/core/selection';


const TOOLBAR_CONFIG = [
    [{ header: ['1', '2', '3', false] }],
    ['bold', 'italic', 'underline', 'link'],
    [{ list: 'ordered' }, { list: 'bullet' }],
    ['clean']
];

class ZSSnowTooltip extends BaseTooltip {
    constructor(quill, bounds) {
        super(quill, bounds);
        this.preview = this.root.querySelector('a.ql-preview');
    }

    listen() {
        super.listen();

        let tooltip = this;

        // on action add
        tooltip.root.querySelector('a.ql-action').addEventListener('click', function(event) {
            if (tooltip.root.classList.contains('ql-editing')) {
                tooltip.save();
            } else {
                tooltip.edit('link', tooltip.preview.textContent);
            }
            event.preventDefault();
        });

        // on action remove
        tooltip.root.querySelector('a.ql-remove').addEventListener('click', function(event) {
            if (tooltip.linkRange !== null) {
                tooltip.restoreFocus();
                tooltip.quill.formatText(tooltip.linkRange, 'link', false, Emitter.sources.USER);
                delete tooltip.linkRange;
            }
            event.preventDefault();
            tooltip.hide();
        });

        // on selection change
        tooltip.quill.on(Emitter.events.SELECTION_CHANGE, function(range) {

            // if no range is selected
            if (range === null) {
                return;
            }

            // if range length is 0, try to get a link, if there is a link, show preview box
            if (range.length === 0) {

                let [link, offset] = tooltip.quill.scroll.descendant(LinkBlot, range.index); // link IS ALWAYS NULL

                if (link !== null) {

                    tooltip.linkRange = new Range(range.index - offset, link.length());

                    let preview = LinkBlot.formats(link.domNode);

                    tooltip.preview.textContent = preview;
                    tooltip.preview.setAttribute('href', preview);
                    tooltip.show();
                    tooltip.position(tooltip.quill.getBounds(tooltip.linkRange));

                    return;
                }
            } else {
                delete tooltip.linkRange;
            }
            tooltip.hide();
        });
    }

    show() {
        super.show();
        this.root.removeAttribute('data-mode');
    }
}

class ZSSnowTheme extends BaseTheme {
    constructor(quill, options) {
        if (options.modules.toolbar !== null && options.modules.toolbar.container === null) {
            options.modules.toolbar.container = TOOLBAR_CONFIG;
        }
        super(quill, options);
    }

    extendToolbar(toolbar) {
        this.tooltip = new ZSSnowTooltip(this.quill, this.options.bounds); //eslint-disable-line
        if (toolbar.container.querySelector('.ql-link')) {
            this.quill.keyboard.addBinding({ key: 'K', shortKey: true }, function(range, context) { //eslint-disable-line
                toolbar.handlers['link'].call(toolbar, !context.format.link); //eslint-disable-line
            });
        }
    }
}

ZSSnowTheme.DEFAULTS = extend(true, {}, BaseTheme.DEFAULTS, {
    modules: {
        toolbar: {
            handlers: {
                link: function(value) { // eslint-disable-line

                    if (value) {

                        let range = this.quill.getSelection(),
                            tooltip,
                            preview;

                        if (range === null || range.length === 0) {
                            return;
                        }

                        preview = this.quill.getText(range);

                        if (/^\S+@\S+\.\S+$/.test(preview) && preview.indexOf('mailto:') !== 0) {
                            preview = `mailto:${preview}`;
                        }

                        tooltip = this.quill.theme.tooltip;

                        tooltip.edit('link', preview);

                    } else {
                        this.quill.format('link', false);
                    }
                }
            }
        }
    }
});

ZSSnowTooltip.TEMPLATE =
`<span class="title">
  Bezoek link
</span>
<a class="ql-preview" target="_blank" href="about:blank"></a>
<input type="text" />
<span>&nbsp;&#45;&nbsp;</span>
<a class="ql-action">
  <i class="mdi"></i>
  <span class="ql-action-label"></span>
</a>
<a class="ql-remove">
  <i class="mdi mdi-delete"></i>
  Verwijder
</a>`;

export default ZSSnowTheme;

0 个答案:

没有答案