🖌️

Quill.js(Ver2)でプレーンテキストをペーストする

2024/06/13に公開

はじめに

先日、開発しているサービスに使用していたJSのリッチエディターライブラリであるQuill.jsをver2系にアップデートしました。独自にカスタマイズしていた部分において、いくつか変更が必要となったため備忘録として残しておきます。

テキストをプレーンテキストでペーストする

デフォルトだとリッチテキストはリッチテキストのままペーストされます。

Ver1系

Ver1系において、プレーンテキストで貼り付ける場合は下記のカスタマイズを施していました。
ライブラリが持つPlainClipboardクラスのonPasteメソッドに対してパッチを当てています。
★参考 Quillのペーストのテキストスタイルを消す

import Quill from 'quill';
const Delta = Quill.import('delta');

class PlainClipboard extends Quill.import('modules/clipboard') {
    onPaste(e) {
        if (e.defaultPrevented || !this.quill.isEnabled()) return;
        let range = this.quill.getSelection();
        let delta = new Delta().retain(range.index);
        let scrollTop = this.quill.scrollingContainer.scrollTop;
        this.container.focus();
        this.quill.selection.update(Quill.sources.SILENT);
        setTimeout(() => {
            delta = delta.concat(this.convert()).delete(range.length);

            // カスタマイズ Deltaの各要素からattributes(装飾情報)を削除
            delta.ops.forEach(op => {
                if (op.attributes) {
                    delete op.attributes;
                }
            });

            this.quill.updateContents(delta, Quill.sources.USER);
            // range.length contributes to delta.length()
            this.quill.setSelection(delta.length() - range.length, Quill.sources.SILENT);
            this.quill.scrollingContainer.scrollTop = scrollTop;
            this.quill.focus();
        }, 1);
    }
}

Quill.register({
    'modules/clipboard': PlainClipboard,
});

Ver2系

Ver2系においてはPlainClipboardクラスのonCapturePasteメソッドに代わっています。
onPasteはエディターへ挿入する処理のみ担う形になったのかな?)

※私の場合はQuillエディターを使用する箇所全てにおいてでプレーンテキストでのペーストが求められる仕様だったため、HTMLとして取り扱う処理を全て取り払ったような形にしています。

import Quill from 'quill';

class PlainClipboard extends Quill.import('modules/clipboard') {
    onCapturePaste(e) {
        if (e.defaultPrevented || !this.quill.isEnabled()) return;
        e.preventDefault();
        const range = this.quill.getSelection(true);
        if (range == null) return;
        let text = e.clipboardData?.getData('text/plain'); // プレーンテキストのみ取得
        if (!text) {
            const urlList = e.clipboardData?.getData('text/uri-list');
            if (urlList) {
                text = this.normalizeURIList(urlList);
            }
        }
        const files = Array.from(e.clipboardData?.files || []);
        if (files.length > 0) {
            this.quill.uploader.upload(range, files);
            return;
        }
        this.onPaste(range, {
            html: null, // HTMLをnullに設定
            text
        });
    }
}


さいごに

上記は公式ドキュメントには明確に記載がない(もしくは私が見つけれていないだけかも)ため、もしご活用くださる場合はご自身の責任でお願いいたします!

Discussion