WYSIWYGエディタのライブラリを比較する

開発しているエンタープライズWebアプリケーションで、wysiwygエディタを用いたUIコンポーネントを作成することとなったため、JSライブラリの選定を行いました。
同じようにwysiwygエディタの利用を検討している方々への情報共有のため、調査結果や所感を書いてみました。

# 前提
Vue2での利用を前提に調査しています。

# [Quill](https://quilljs.com/)
## 機能
- インラインコンテンツ
  - 太字表記
  - 文字色変更
  - フォント変更
  - インラインコード
  - 斜体
  - リンク
  - 文字サイズ
  - 取り消し線
  - 上付き文字/下付き文字
  - 下線
- ブロックコンテンツ
  - 引用
  - 見出し
    - H1～H6まで選択可能
  - インデント
  - 箇条書き
  - テキストの配置（中央揃え、右揃え、左揃え）
  - テキストの方向

オプションで利用する機能を選択することができる。
更に、ツールバーで利用できる機能とエディタ内で利用できる機能を分けることも可能。
（例えば、ツールバー上では太字ボタンを非表示とするが、エディタでは太字のコンテンツを貼り付けることができる等）

https://quilljs.com/docs/formats/

## 入力内容の保持形式
Quillは入力されたリッチテキストの内容をDeltaという独自のJSON配列構造で管理している。
Deltaはテキストの情報を装飾されたテキスト単位で保持している。

https://quilljs.com/docs/delta/

## Vue2との親和性
有志によるものだが、Vue2向けにコンポーネント化したライブラリが存在している。
ドキュメントを読む限りでは、コンテンツをHTML形式の文字列で管理している。
3年前に更新が止まっている。
（更新が止まっていることや下記の脆弱性等により、vue2-editorの採用は見送っている）

https://github.com/davidroyer/vue2-editor

## 脆弱性
最新バージョンの1.3.7にてXSSの脆弱性が発見されている。
issueの内容からするとquillの`.innerHTML`を利用すると起きるようである。

https://github.com/quilljs/quill/issues/3364

## ライセンス
BSD3-clause

## 所感
必要十分な機能を備えており、ドキュメントも充実している。ネット上での情報も多く、扱いやすい印象を受ける。
公式でのローカライズ対応がないため、必要な場合は自前で実装する必要がある。
参考：https://studybank.net/programming/page/js-api-quill-editter-js-sample

### 補足
2024/02時点での安定版である1.3.7においては、[chromeで非推奨となるAPIが利用されている。](https://github.com/quilljs/quill/issues/3806)
一方で上記を始めとする問題点を解消した2.0系も既にRCバージョンがリリースされているため、今から利用するのであれば2.0系の方が良いかもしれない。

# [Trix](https://trix-editor.org/)
## 機能
- インラインコンテンツ
  - 太字表記
  - 斜体
  - リンク
  - 取り消し線
- ブロックコンテンツ
  - 引用
  - 見出し
    - H1のみ選択可
  - インデント
  - 箇条書き

Quillのようにツールバーで利用できる機能とエディタ内で利用できる機能を分けることは不可能な模様。
入力された内容はHTML文字列に変換して受け渡すことや、HTML文字列を受け取ってエディタに表示することが可能となっている。

## 入力内容の保持形式
[Trixの公式ドキュメント](https://github.com/basecamp/trix?tab=readme-ov-file#integrating-with-forms)に沿って実装すると、入力されたテキストがHTML形式の文字列で保持される。
```html
<form>
  <input id="hoge" type="hidden" name="content">
  <trix-editor input="hoge"></trix-editor>
</form>
```

## Vue.jsとの親和性
Vue2向けにコンポーネント化した有志のライブラリが存在している。ドキュメントを読む限りでは、コンテンツをHTML形式の文字列で管理している。

https://github.com/hanhdt/vue-trix

## 脆弱性
過去に小、中程度の脆弱性がいくつか発見されているが、最新バージョンである2.0.7ではいずれも解消されている。
https://security.snyk.io/package/npm/trix

## 所感
シンプルで使いやすいが、フォントや文字色の変更といった装飾系の機能に乏しい印象。
またデザインがややポップであるため、（特にエンタープライズ向けだと）既存のUIとの相性が悪いかも。

# [Editor.js](https://editorjs.io/)
## 機能
前提として、Editor.jsはインストール時、最低限の機能のみ用意されている。
以下の機能は個別にインストールすることで使用可能になるとのこと。
https://editorjs.io/getting-started/

- インラインコンテンツ
  - 太字表記
  - 斜体
  - リンク
  - マーカー
- インラインコード
  - ブロックコンテンツ
  - 引用
  - 見出し
    - H1～H6まで選択可
  - インデント
  - 箇条書きリスト
  - 番号付きリスト
  - コードブロック
  - テーブル
  - チェックリスト

## 入力内容の保持形式
JSON形式による文書構造で保持している。詳細については以下に記載がある。
https://editorjs.io/saving-data/

### 補足
HTMLからJSONへの変換は、ライブラリのAPIを呼び出せば可能である。
上記のJSONをHTMLに変換するAPIは用意されていないため、必要な場合は以下の別ライブラリを使用する必要がある。

https://github.com/pavittarx/editorjs-html

## Vue.jsとの親和性
有志によるライブラリが存在しているが、GitHubのスター数が5と非常に少ない。

https://github.com/changjunhao/vue-editorjs

## 脆弱性
過去に脆弱性が発見されているが、最新バージョンである2.28.0では解消されている。

https://security.snyk.io/package/npm/@editorjs%2Feditorjs

## ライセンス
Apache License 2.0

## 所感
機能は豊富だが、ブロックエディタである点やVueとの親和性が低い点がネックである。

# [TinyMCE](https://www.tiny.cloud/)
## 機能
非常に多いため、利用が想定される機能のみ記載。
詳細は以下を参照されたし。
https://www.tiny.cloud/tinymce/features/

- インラインコンテンツ
  - 太字表記
  - 文字色変更
  - フォント変更
  - 斜体
  - リンク
  - 文字サイズ
  - 取り消し線
  - 上付き文字/下付き文字
  - 下線
  - 絵文字
  - ノンブレークスペース
- ブロックコンテンツ
  - 引用
  - 見出し
    - H1～H6まで選択可
  - インデント
  - 箇条書き
  - テキストの配置（中央揃え、右揃え、左揃え）
  - テキストの方向
  - コードブロック
  - テーブル
  - アコーディオン
  - アンカー
  - ページ分け

Quillと同様、実装側のオプションで利用する機能を選択することができる。
https://www.tiny.cloud/tinymce/features/

## 入力内容の保持形式
APIを通じてコンテンツをHTML形式で取得する。コンテンツを設定するときもHTMLを文字列で設定する。

https://www.tiny.cloud/blog/how-to-get-content-and-set-content-in-tinymce/

## Vue.jsとの親和性
Vue.js向けのコンポーネントが公式で用意されている。ドキュメントを読む限りでは、コンテンツをHTML形式の文字列で管理している。

https://github.com/tinymce/tinymce-vue

## 脆弱性
中程度、あるいは重大な脆弱性が複数発見されているが、最新バージョンである6.8.3では解消されている。

https://security.snyk.io/package/npm/tinymce

## ライセンス
MIT License
※バージョン5以下の場合はLGPL

## 所感
Confluenceで採用されていることもあり、機能は非常に豊富。
Vue向けのコンポーネントも用意されており、実装者にも優しいライブラリ。
ただし、機能が多いこともあり、バンドルサイズがやや肥大化する印象。
Webパフォーマンスを重視したい場合は、他のライブラリの利用を検討する必要がある。

### 補足
エディタの右下に表示されるロゴに関してはTinyMCEのオプションによって非表示にすることが可能。

https://www.tiny.cloud/docs/configure/editor-appearance/#branding

ただし、ロゴの非表示にはTinyMCE の帰属要件に従うことが必須となっている。
帰属要件によると、セルフホスト形式で利用する場合には表示義務はない。

https://www.tiny.cloud/legal/attribution-requirements/

# 機能比較
各ライブラリの機能を表形式で比較してみます。
ご参考までにどうぞ。
## インラインコンテンツ
<table>
<thead>
<tr><th><th>太字表記<th>文字色変更<th>フォント変更<th>インラインコード<th>斜体<th>リンク<th>文字サイズ<th>取り消し線<th>上付き/下付き文字<th>下線<th>マーカー<th>絵文字<th>nbsp
<tbody>
<tr><td>Quill<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>x<td>x<td>x
<tr><td>Trix<td>○<td>x<td>x<td>x<td>○<td>○<td>x<td>○<td>x<td>x<td>x<td>x<td>x
<tr><td>Editor.js<td>○<td>x<td>x<td>○<td>○<td>○<td>x<td>x<td>x<td>○<td>○<td>x<td>x
<tr><td>TinyMCE<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○
<!-- 横幅を確保するためのダミー行 -->
<tfoot>
<tr><th colspan=14>$\hspace{75em}$</th></tr>
</tfoot>
</table>
<!-- |  | 太字表記 | 文字色変更 | フォント変更 | インラインコード | 斜体 | リンク | 文字サイズ | 取り消し線 | 上付き/下付き文字 | 下線 | マーカー | 絵文字 | nbsp |
|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|
Quill	○	○	○	○	○	○	○	○	○	○	×	×	×
Trix	○	×	×	×	○	○	×	○	×	×	×	×	×
Editor.js	○	×	×	○	○	○	×	×	×	○	○	×	×
TinyMCE	○	○	○	×	○	○	○	○	○	○	○	○	○ -->

## ブロックコンテンツ
<table>
<thead>
<tr><th><th>引用<th>見出し<th>インデント<th>箇条書きリスト<th>番号付きリスト<th>テキストの配置<th>テキストの方向<th>コードブロック<th>テーブル<th>チェックリスト<th>アコーディオン<th>アンカー<th>ページ分け
<tbody>
<tr><td>Quill<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>×<td>×<td>×<td>×<td>×
<tr><td>Trix<td>○<td>○<td>○<td>○<td>○<td>×<td>×<td>×<td>×<td>×<td>×<td>×<td>×
<tr><td>Editor.js<td>○<td>○<td>○<td>○<td>○<td>×<td>×<td>○<td>○<td>○<td>×<td>×<td>×
<tr><td>TinyMCE<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>○<td>×<td>○<td>○<td>○
<!-- 横幅を確保するためのダミー行 -->
<tfoot>
<tr><th colspan=14>$\hspace{85em}$</th></tr>
</tfoot>
</table>
<!-- ライブラリ名	
引用 見出し インデント 箇条書きリスト 番号付きリスト	テキストの配置	テキストの方向 コードブロック

テーブル	チェックリスト	アコーディオン	アンカー	ページ分け
Quill	○	○	○	○	○	○	○	○	×	×	×	×	×
Trix	○	○	○	○	○	×	×	×	×	×	×	×	×
Editor.js	○	○	○	○	○	×	×	○	○	○	×	×	×
TinyMCE	○	○	○	○	○	○	○	○	○	×	○	○	○
その他
ライブラリ名	
プレースホルダ

読み取り専用

エディタのリサイズ

Quill	○	○	×
Trix	○	○	×
Editor.js	○	○	×
TinyMCE	○	○	○
 -->