WYSIWYGエディタ Quill を使って文字の色を変更するまで

# はじめに

案件で以下の機能を持つ WYSIWYG エディタが欲しかった。

- 無償での商用利用可能
- 文字の色を変更できる

前者を満たす WYSIWYG エディタは結構数があるのだが、後者を満たすものがあまりなかった（探し方が悪い？）。 そんな中で Github のスター数も多い WYSIWYG エディタである Quill を調べていると[デモ画面](https://quilljs.com/)にはメニューはないものの、ちゃんと文字の色を変更できる機能があったので、機能調査がてら実際に使ってみることにしたので、調査結果を記す。

# Quill の導入

これはページの[QuickStart](https://quilljs.com/docs/quickstart/)を参考にして組み込む。
CDNから必要なリソースを読み込むだけで利用可能なのは非常に手軽で良い。

```html:index.html
<html lang="ja">
  <head>                                                                                                                                             
    <meta charset="UTF-8">
    <!-- Include stylesheet -->
    <link href="https://cdn.quilljs.com/1.3.7/quill.snow.css" rel="stylesheet">
  </head>
  <body>
    <!-- Create the editor container -->
    <div id="editor">
      <p>Hello World!</p>
      <p>Some initial <strong>bold</strong> text</p>
      <p><br></p>
    </div>
    
    <!-- Include the Quill library -->
    <script src="https://cdn.quilljs.com/1.3.7/quill.js"></script>
    
    <!-- Initialize Quill editor -->
    <script>
      var quill = new Quill('#editor', {
        theme: 'snow'
      });
    </script>
  </body>
</html>
```

これだけでリッチなエディタが表示できる。

![SnapCrab_NoName_2020-12-16_22-57-50_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502582/de301d69-a606-f293-a9e1-5e20370ffbb4.png)

さて、画面を見ればわかるがデフォルトではメニューバーに色を変更できそうな要素はない。
ここに色を変更するためのメニューを組み込んでいく。

## 色を変更できるメニューを組み込む

太文字にしたり、イタリックにするなどのメニュー部分を[Toolbar](https://quilljs.com/docs/modules/toolbar/)と呼ぶ。 Quill ではこのツールバーをカスタマイズ可能で、そのメニューの１つに色を変更できるものがある。
このページの内容に従い、Quill の初期化時にツールバーに表示するものを指定できる。

```html:index.html(抜粋)
    <script>
    var toolbarOptions = [
      ['bold', 'italic', 'underline', 'strike'], 
      [{'color': []}, {'background': []}],
    ];
    var quill = new Quill('#editor', {
      theme: 'snow',
      modules: {
        toolbar: toolbarOptions,
      },
    });
    </script>
```

これで初期化すると、以下のように「太文字、イタリック、下線、打消し線」と「文字色変更、背景色変更」がそれぞれブロックで配置される。 文字色変更と背景色変更はデフォルトで用意されたカラーで利用できる。

![SnapCrab_NoName_2020-12-16_23-6-46_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502582/fb7e4516-75cc-51c5-49a2-95828a46acb9.png)


## カスタムカラーに対応する

これだけで十分なら問題ないが、ここに乗っていないカラーを使いたいことがあるかもしれない。 その場合、簡易的な方法でよければ非常に簡単だったので併せて紹介しておく。

https://stackoverflow.com/questions/42068335/quill-js-color-textbox

ここに乗っている通り、「カスタムカラーが選択された場合、カラーコードを文字で入力するようにする」という運用でOKなら、以下の程度の実装で実現できる。 コードは基本上記のコピペ。

```html:index.html
<html lang="ja">
  <head>
  <!-- Include stylesheet -->
  <meta charset="UTF-8">
  <link href="https://cdn.quilljs.com/1.3.7/quill.snow.css" rel="stylesheet">
  <style type="text/css">
    .ql-color .ql-picker-options [data-value=custom-color] {
      background: none !important;
      width: 100% !important;
      height: 20px !important;
      text-align: center;
    }
    .ql-color .ql-picker-options [data-value=custom-color]:before {
      content: '自分で色を指定';
    }
    .ql-color .ql-picker-options [data-value=custom-color]:hover {
      border-color: transparent !important;
    }
    
    .ql-background .ql-picker-options [data-value=custom-color] {
      background: none !important;
      width: 100% !important;
      height: 20px !important;
      text-align: center;
    }
    .ql-background .ql-picker-options [data-value=custom-color]:before {
      content: '自分で背景色を指定';
    }
    .ql-background .ql-picker-options [data-value=custom-color]:hover {
      border-color: transparent !important;
    }
  </style>
  </head>
  <body>
    <!-- Create the editor container -->
    <div id="editor">
      <p>Hello World!</p>
      <p>Some initial <strong>bold</strong> text</p>
      <p><br></p>
    </div>
    
    <!-- Include the Quill library -->
    <script src="https://cdn.quilljs.com/1.3.7/quill.js"></script>
    
    <!-- Initialize Quill editor -->
    <script>
    var toolbarOptions = [
      ['bold', 'italic', 'underline', 'strike'], 
      [{'color': [
        "#000000", "#e60000", "#ff9900", "#ffff00", "#008a00", "#0066cc",
        "#9933ff", "#ffffff", "#facccc", "#ffebcc", "#ffffcc", "#cce8cc",
        "#cce0f5", "#ebd6ff", "#bbbbbb", "#f06666", "#ffc266", "#ffff66",
        "#66b966", "#66a3e0", "#c285ff", "#888888", "#a10000", "#b26b00",
        "#b2b200", "#006100", "#0047b2", "#6b24b2", "#444444", "#5c0000",
        "#663d00", "#666600", "#003700", "#002966", "#3d1466", 'custom-color',
        ]},
        {'background': [
        "#000000", "#e60000", "#ff9900", "#ffff00", "#008a00", "#0066cc",
        "#9933ff", "#ffffff", "#facccc", "#ffebcc", "#ffffcc", "#cce8cc",
        "#cce0f5", "#ebd6ff", "#bbbbbb", "#f06666", "#ffc266", "#ffff66",
        "#66b966", "#66a3e0", "#c285ff", "#888888", "#a10000", "#b26b00",
        "#b2b200", "#006100", "#0047b2", "#6b24b2", "#444444", "#5c0000",
        "#663d00", "#666600", "#003700", "#002966", "#3d1466", 'custom-color'
        ]}
      ],
    ];
    var quill = new Quill('#editor', {
      theme: 'snow',
      modules: {
        toolbar: toolbarOptions,
      },
    });
    toolbar.addHandler('color', function(value) {
        if (value == 'custom-color') {
            value = prompt('カラーコードを入力してください (例: #FF0000)');
        }
        quill.format('color', value);
    });
    toolbar.addHandler('background', function(value) {
        if (value == 'custom-color') {
            value = prompt('カラーコードを入力してください (例: #FF0000)');
        }
        quill.format('background', value);
    });
    </script>
  </body>
</html>
```

これで色を選ぼうとすると一番下に「自分で色を指定」というメニューが出てくる。 
![SnapCrab_NoName_2020-12-16_23-16-41_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502582/297c5aa9-c1f7-696f-57bf-8b1750e28047.png)

これを選ぶとブラウザのプロンプトが開き、カラーコードを入力できる。
![SnapCrab_NoName_2020-12-16_23-17-38_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502582/afa208a9-5594-b6a7-3444-42aacdde528f.png)

ここでは `#FF00FF` というメニューにない色を選んでみた。
![SnapCrab_NoName_2020-12-16_23-17-49_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502582/0067877d-537b-09b2-2268-f948ba425923.png)

ということで、反映されていることが分かる。


## データの保存と復元

実際にエディタを使う上で重要なのは、ここで入力された内容を別のところで利用するためにデータを保存したりしておくことである。 探してみると、

- [例えばこちらを参考に](https://quilljs.com/playground/#form-submit) `quill.getContents()` の結果を JSON にシリアライズしてやり取りする
    - 復元には `quill.setContents()` を使う
- [`quill.root.innerHTML` を使って、内部表現の HTML を引っこ抜いて保存する](https://stackoverflow.com/questions/39519950/convert-quill-delta-to-html/41247565)
    - 復元には `<div id="editor">{{ quill.root.innerHTML }}</div>` のように初期値を HTML タグごと入れて初期化する

という方法があるようだ。 

# まとめ

Quill を使って文字の色を指定する方法について説明した。 
なんとなく、日本人はホームページを作るときに文字の色を変えたがる印象があるため、テキストに色を付ける機能の需要は高そうに見えるのだが、各エディタのデモには色を変える機能が紹介されていない（か、そもそもない）のが多いので、世界的にはあまり需要はないのかもというのを考えてしまった。


# その他参考

どんな WYSIWYG エディタがあるかの参考になりました。

- https://qiita.com/mima_ita/items/bacf3ca3c078d1e6c70f
- https://goworkship.com/magazine/wysiwyg-editor-froala/