問題
quilljs のversion 1.3.7 (記事執筆時点でGithubで表記されている latest リリース) での話。
Quill Editor で編集した値を一度 DB に保存する。 この場合、DB の中身はこのようになる。
# 入力
テストです。 ← 全角スペースが4個配置されています。
# DBに保存される値
<p>テストです。 ← 全角スペースが4個配置されています。</p>
この値を再編集するために、<div>
要素に以下の通りに出力して Quill インスタンスを生成する。
<div id="quill-editor">
<p>テストです。 ← 全角スペースが4個配置されています。</p>
</div>
...
<script type="text/javascript">
var quill = new Quill('#quill-editor');
</script>
しかし、これで初期化するとスペースが圧縮された状態でエディタに表示されてしまう。
これをスペース圧縮を行わないで展開するにはどうすれば良いのかを調べたが、結構大変だったのでメモ。
解決作
この問題については例えば以下の Issue で語られているが、これはコピー&ペーストの時の場合であって、初回の展開時の話ではない。
しかし、この Issue 内で、この置換を行っているところが matchText
関数内であることが示されている。 実際のソースコードを見ると、
function matchText(node, delta) {
let text = node.data;
// Word represents empty line with <o:p> </o:p>
if (node.parentNode.tagName === 'O:P') {
return delta.insert(text.trim());
}
if (text.trim().length === 0 && node.parentNode.classList.contains('ql-clipboard')) {
return delta;
}
if (!computeStyle(node.parentNode).whiteSpace.startsWith('pre')) {
// eslint-disable-next-line func-style
let replacer = function(collapse, match) {
...
となっていて、node.parentNode
に whiteSpace
スタイルが直接指定されているかどうかを見て置換を行っていることが分かる。 この node.parentNode
の実体を見てみると、これは <div id="quill-editor">
内の子要素であることが分かった。
そのため、Quill インスタンスを生成する前に、例えば以下のような方法で各要素に style="white-space: pre;"
を直接付与してやれば良い。
$('#quill-editor').children().each(function(idx, v) {
$(v).css('white-space', 'pre');
});
この後に Quill インスタンスを生成するとスペースを圧縮せずにエディタ上に文字を展開することができる。