この記事は、 Qiita株式会社のカレンダー | Advent Calendar 2022 - Qiita の 17 日目の記事です。
はじめに
今年(2022年)の6月末にエディタのアップデートがベータ版としてリリースされました。(その後、7月末に正式版としてリリースされました)
このアップデートでいくつか改善・変更された点がありましたが、その中でも
「編集エリアとプレビューのスクロール位置の同期」
は、大きなアップデートでした。
今回は、その 「編集エリアとプレビューのスクロール位置の同期」 をどのように実現しているかについて書きます。
アップデート前でのQiitaのエディタについて
Qiitaのエディタは左右で分かれており、左側が「編集エリア」、右側が「プレビューエリア」になっています。(PCの場合)
(スクショはアップデート後のものですが...)
左側でマークダウンを編集し、右側でプレビューを見ることができるようになっています。
編集している内容をリアルタイムでプレビューできる良さがありますが、記事が長くなってくると左側と右側の対応がわかりにくくなります。
結果、執筆体験の悪化に繋がります。
どのように同期させるか
マークダウンとHTMLの対応関係
同期させるには、まず「マークダウン」と「マークダウンから出力されたHTML」との対応関係を取る必要があります。
Qiitaでは、以下のように行単位で対応関係を取るようにしています。
どのようにして対応関係を取るかですが、
マークダウンパーサーのライブラリで出力されたHTMLに マークダウンでの行数 を出力してくれるものがあるので、それを使うと簡単にできます。
Qiitaでは、qiita_markerのsourcepos
オプションを使うことで取得しています。
以下はqiita_marker
の出力の例です。
<p data-sourcepos="1:1-1:169">この記事は、 <a href="https://qiita.com/advent-calendar/2022/qiita-inc">Qiita株式会社のカレンダー | Advent Calendar 2022 - Qiita</a> の 17 日目の記事です。</p>
<h2 data-sourcepos="3:1-3:15">はじめに</h2>
<p data-sourcepos="5:1-5:192">今年(2022年)の6月末にエディタのアップデートがベータ版としてリリースされました。(その後、7月末に正式版としてリリースされました)</p>
...
これによってマークダウンのテキストとHTMLの対応関係が取れるようになります。
スクロール位置の同期
上記で、マークダウンとプレビュー側のHTMLとの対応関係が取れるようになりました。
次に、編集エリアがスクロールされたときに、プレビューも対応する位置にスクロールしてあげる必要があります。
はじめに、編集エリアとプレビューのどこを対応させてあげるかを考える必要があります。
Qiitaでは、編集エリアで表示されている一番上の行を基準として、プレビューと同期するようにしています。
次に、どのようにして編集エリアで表示されている一番上の行数を取得するかです。
やり方としてはいくつかあると思いますが、QiitaではCodeMirror 6から行数を計算し、取得するようにしています。
そして、「マークダウンの行数」と「プレビュー側の要素のスクロール Height」のマップを用意しておき、編集エリアのスクロールイベントに応じてプレビュー側もスクロールさせてあげることで実現されています。
他に、
- 空行などの場合に対応する要素がない場合
- 「マークダウンの行数」と「プレビュー側の要素のスクロール Height」のマップの生成の頻度
などを考慮する必要がありますが、主に上記の方法でスクロール同期を実現できます。
さいごに
Qiitaのエディタアップデートの「編集エリアとプレビューのスクロール位置の同期」について書きました。
エディタアップデートによっていくつか改善はされましたが、まだまだ改善の余地があると考えています。
ですので、ぜひエディタを使っていただき、フィードバックなどいただけると幸いです。
ぜひ、 Qiita株式会社のカレンダー | Advent Calendar 2022 - Qiita を購読設定して、明日の記事もご覧いただけると嬉しいです。