Quill
Quill https://github.com/quilljs/quill
Quill is a modern WYSIWYG editor built for compatibility and extensibility.
Quillはテキストエディタライブラリです。
拡張性も高いですが、特殊な仕様の理解が必要です。
画像や文字装飾など機能豊富なのですが、シンプルなテキストエディタ+αくらいの機能にとどめたいときコピー&ペースト時にスタイルが反映されてしまいます。
このテキストスタイルを消す方法をいくつか紹介します。
Clipboardモジュールのconvertの拡張
公式で拡張のサンプルとして紹介されている方法です。
このサンプルには問題があり、Safariにおいてthis.container.innerText
が空文字として返ってきます。
textContent
に変えた場合、Safariでペーストは動くものの改行が反映されなくなります。
Matcherで対応する方法
quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
let ops = []
delta.ops.forEach(op => {
if (op.insert && typeof op.insert === 'string') {
ops.push({
insert: op.insert
})
}
})
delta.ops = ops
return delta
})
この実装で概ね動きます。
ただし、IEやiOS Safariにおいて改行が消える、半角スペースが消えるなど空白文字が一部そのまま適切にペーストされない問題が発生します。
Clipboardのテキスト取得処理を差し替えてしまう方法
この方法が一番問題がありませんでした。
const Clipboard = Quill.import('modules/clipboard')
const Delta = Quill.import('delta')
class PlainClipboard extends Clipboard {
onPaste (e) {
if (e.defaultPrevented || !this.quill.isEnabled()) return
let range = this.quill.getSelection()
const text = e.clipboardData.getData('text')
let delta = new Delta().retain(range.index)
let scrollTop = this.quill.scrollingContainer.scrollTop
this.container.focus()
this.quill.selection.update(Quill.sources.SILENT)
setTimeout(() => {
// ここだけ変更箇所 本来はconvert()
const pastedDelta = new Delta().insert(text)
delta = delta.concat(pastedDelta).delete(range.length)
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, true)
const text = e.clipboardData.getData('text')
...
const pastedDelta = new Delta().insert(text)
delta = delta.concat(pastedDelta).delete(range.length)
v1.3.7のonPaste
のテキスト挿入処理をe.clipboard
のテキストを直接使う形に書き換えます。
Quillではテキストスタイルの反映のためDOMを使った複雑な変換処理をしているため欠損が起きてしまうものと思われます。
この方法の問題点としては、今後のQuillのアップデートでClipboard
の設計が変わるのでアップデート時のタイプが必要になります。
なので利用の際はpackage.jsonのquillのバージョン固定を忘れないようにしましょう。