Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Quillのペーストのテキストスタイルを消す

More than 1 year has passed since last update.

Quill

Quill https://github.com/quilljs/quill

Quill is a modern WYSIWYG editor built for compatibility and extensibility.

Quillはテキストエディタライブラリです。
拡張性も高いですが、特殊な仕様の理解が必要です。

画像や文字装飾など機能豊富なのですが、シンプルなテキストエディタ+αくらいの機能にとどめたいときコピー&ペースト時にスタイルが反映されてしまいます。
このテキストスタイルを消す方法をいくつか紹介します。

Clipboardモジュールのconvertの拡張

https://quilljs.com/docs/modules/#extending

公式で拡張のサンプルとして紹介されている方法です。
このサンプルには問題があり、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)
追加分.js
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のバージョン固定を忘れないようにしましょう。

daponta
dena_coltd
    Delight and Impact the World
https://dena.com/jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away