右矢印キーによるインラインコードブロックからの脱出バグを修正
インラインコードブロックの末尾で右矢印キーを押しても脱出できないバグが修正されました。原因は「カーソル後のノード」の取得範囲が意図より広く、後続の段落の存在を誤検出していたことにあります。
背景
inline code を記述後、末尾にスペースを入れずに右矢印キーを押すと、カーソルがコードブロック内に閉じ込められるという問題が #728 で報告されていました。スペースを挿入した場合は正常に脱出できるため、矢印キーによる脱出ロジックに限定したバグでした。特にリストアイテム内のインラインコードで顕著に発生し、コードブロックを抜けられないまま入力が継続されてしまう問題でした。
矢印キーによる脱出は「カーソルがコードテキストノードの末尾にいるとき、後続のノードがなければコードフォーマットを解除する」というロジックで実装されています。問題は「後続のノードがない」という判定に使う関数の返すスコープが広すぎた点にありました。
技術的な変更
src/editor/command_dispatcher.js の1行の変更により、後続ノードの検索スコープが「親要素の次の兄弟要素」から「同一親要素内の次の兄弟ノード」に絞り込まれました。
変更前:
if (this.selection.nodeAfterCursor !== null) return false
変更後:
if (anchorNode.getNextSibling() !== null) return false
変更前の nodeAfterCursor は親要素(段落など)の次の兄弟要素も返していたため、<p>Hello <code>code</code></p><p>next line</p> のような構造では「次の段落」が存在するとして脱出処理が中断されていました。変更後の anchorNode.getNextSibling() はテキストノード自身の直接の兄弟のみを参照するため、同一段落内に後続ノードがなければ正しく脱出処理が実行されます。
あわせて test/browser/tests/formatting/inline_code_escape.test.js が新規追加され、以下の4つのシナリオがPlaywrightによるブラウザテストでカバーされています:
- 後続段落がある場合のインラインコードからの脱出
- リストアイテム内のインラインコードからの脱出
- 段落の唯一のコンテンツがインラインコードの場合の脱出
- バッククォートショートカットで作成したインラインコードからの脱出
設計判断
nodeAfterCursor から anchorNode.getNextSibling() への置き換えは、参照するスコープを「カーソル周辺のグローバルな隣接ノード」から「テキストノード自身の直接の兄弟」へ明確に限定する変更です。
この脱出ロジックが意図しているのは「コードテキストノードの直後に別のテキストや要素が続く場合は脱出しない(カーソルをその隣接ノードへ自然に移動させる)」という挙動です。段落やリストアイテムといった親要素の境界を越えて後続コンテンツを検索することは、この意図と一致しません。変更はその意図に忠実なスコープをAPI選択によって明示しています。
また、ロジックの修正に合わせてブラウザテストを追加したことで、将来の類似バグの混入を防ぐ安全網が整備されています。
まとめ
1行の変更ながら、ノード参照のスコープ誤りというリッチテキストエディタ実装に特有の落とし穴を突いたバグ修正です。anchorNode.getNextSibling() への置き換えにより、インラインコードの脱出ロジックが同一親要素内という正しいスコープで動作するようになり、段落やリストをまたぐ任意の文書構造でも一貫した挙動が保証されます。