https://github.com/basecamp/lexxy
Lexxエディタにおいて、ソフト改行(<br>)を含む段落でカーソルが下矢印キーを押したとき、次のテキスト行をスキップして添付ファイルが誤って選択されてしまうバグを修正しました。`topLevelNodeAfterCursor` と `topLevelNodeBeforeCursor` にオフセットガードを追加し、カーソルがテキストノードの実際の境界にいるときだけ添付ファイルへのナビゲーションをインターセプトするように改善されています。
Lexicalエディタのアップロードライフサイクルメソッド(進捗・完了・エラー)が非同期完了する際、エディタ外にフォーカスがあるとDOM選択が強制的にエディタに戻ってしまう問題を修正。`SKIP_DOM_SELECTION_TAG` をエディタのフォーカス状態に応じて条件付きで付与する `#backgroundUpdateTags` ゲッターを新設し、フォーカス奪取を防ぎつつ、エディタにフォーカスがある場合の正常な選択転送挙動を維持しています。
@mentionプロンプトが開いている状態でカンマキーを押すと、フォーカス中のオプションが選択されるようになりました。event.preventDefault()でブラウザのデフォルト入力を抑止した後、Lexical APIを通じてカンマをエディタに挿入することで、メンション確定とカンマ保持を両立しています。
Lexicalエディタのカスタムカーソル移動ロジックを修正し、イタリックと通常テキストのようなフォーマット境界で矢印キーを押した際に添付ファイルに予期せずジャンプする問題を解消しました。隣接ノードがDecoratorNodeでない場合に`null`を返してLexicalのデフォルト動作に委譲することで対処しており、`instanceof DecoratorNode`から`$isDecoratorNode()`への変更とnullガードの追加も含まれます。
レンダリング済みビューからコピーしたHTMLをペーストする際、`<a href="#">` 等のプレースホルダーアンカーがリンクノードとして取り込まれる問題を修正。Lexicalの変換処理に入力するDOM自体を前処理する `#unwrapPlaceholderAnchors` メソッドを追加し、`href` が空または `"#"` のアンカーのみを子ノードで置き換えることで、@メンションはプレーンテキストとして、実URLを持つリンクはリンクノードとして正確に保持されるようになりました。
`WrappedTableNode`が`canInsertTextBefore()`/`canInsertTextAfter()`を`true`のまま継承していたため、`ProvisionalParagraphExtension`がテーブル周囲に隠しクリックターゲットを挿入しない問題がありました。両メソッドを`false`でオーバーライドすることで、テーブル下部のクリックが正しくテーブル外にカーソルを配置するよう修正されました。
アタッチメント直後の空リスト項目でバックスペースを押すと、アタッチメントが選択されてしまう問題が修正されました。`selectDecoratorNodeBeforeDeletion` ハンドラ内に `#collapseListItemToParagraph()` メソッドを追加し、カーソルがリスト項目内にある場合はデコレータ選択をスキップしてリスト→段落変換を直接実行するよう変更されています。
ブロッククォート内に改行を含むプレーンテキストをペーストすると、改行以降のテキストがクォートの外へ逃げてしまう不具合を修正。LexicalのinsertNodes()がParagraphNodeをQuoteNodeの外側に分離するデフォルト挙動を回避するため、選択位置がQuoteNode内かどうかを検出して専用の挿入パスに切り替える#insertNodesIntoQuote()メソッドを追加しています。
LexicalのTextNode.exportDOM()が生成する`<b><strong>text</strong></b>`や`<i><em>text</em></i>`という二重タグ問題を、カスタムexport関数`exportTextNodeDOM`で解消しました。Lexicalのhtml.export設定を使いコアを変更せずに差し替え、`<strong>`や`<em>`が既に存在する場合は`<b>`や`<i>`のラップをスキップする設計で、セマンティクス的に正しいHTML出力を実現しています。
19本のPlaywrightテストファイルを `attachments/`、`editor/`、`formatting/`、`modes/`、`paste/`、`tables/` の6つのサブディレクトリに再編し、共通ヘルパーを `helpers/toolbar.js` に集約した変更です。フォルダ構成のルールを `AGENTS.md` に明文化することで、新規テスト追加時の配置判断を明確化しています。
`playwright.config.js` と `vite.config.js` にハードコードされていたViteサーバーのポート番号(5173)を、`VITE_PORT` 環境変数で上書きできるようにしました。これにより、`VITE_PORT=5174 yarn test:browser` のように異なるポートを指定することで、複数のGit Worktreeで並列にPlaywrightテストを実行できるようになります。`reuseExistingServer` による誤ったWorktreeのサーバーへの接続という問題も同時に解消されます。
クリップボードに画像ファイルとHTMLの<img>タグが同時に含まれる場合、LexxyはHTML挿入よりもファイルアップロードパスを優先するように修正されました。#isCopiedImageHTMLメソッドでDOM構造を検査し、コピー由来の<img>スニペットを検出した場合のみアップロードパスに切り替える設計で、既存のHTMLペーストパスへの影響を最小限に抑えています。あわせて、ブラウザの制約を回避してファイル付き混合クリップボードペイロードをテストできるよう、Playwrightのエディタヘルパーも拡張されています。
`Shift+Enter` で挿入したソフト改行を含む段落でブロック引用を適用すると、選択行に関わらず段落全体が引用ブロックになるバグを修正しました。新たに追加された `wrapSelectedSoftBreakLines` メソッドが選択行のみを段落から分割して引用ノードでラップし、それ以外のケースは既存の汎用処理に委ねる2段階設計で、既存ロジックへの影響を最小限に抑えています。
テーブルの anchor とテーブル外の focus にまたがる選択範囲で Backspace を押すと発生していた Lexical error 148 のクラッシュを修正。`isTableCellSelected` ゲッターに `$isRangeSelection` チェックと `anchor.key !== focus.key` のガード節を追加し、非対称な選択範囲ではテーブルセル専用ロジックをスキップするようにした。
プロンプトメニューからメンションを挿入する際、周囲のボールドなどのインライン書式が失われていたバグを修正。テキストノード再構築時に選択状態・anchorNode・親ノードの3段階フォールバックで書式を引き継ぐ `#cloneTextNodeFormatting` メソッドを新設し、クリック・キーボード両操作のシステムテストも追加されました。
`<code>` スパンの末尾から `ArrowRight` でキャレットを移動した後、次の文字入力がコードフォーマットのまま挿入されるバグを修正。`CommandDispatcher` に `KEY_ARROW_RIGHT_COMMAND` ハンドラを追加し、キャレットがインラインコードノードを抜けるタイミングで明示的に `code` フォーマットをトグルオフする。
OSのファイルマネージャーからのドラッグ&ドロップ時、ブラウザがDOMセレクションを更新しないという仕様により、添付ファイルがドロップ位置ではなく古いカーソル位置に挿入されるバグを修正。`document.caretRangeFromPoint()` を用いてドロップ座標からDOMセレクションを更新する `dropFiles()` メソッドと `#moveSelectionToPoint()` ヘルパーを追加し、`#handleDrop` の呼び出し先を変更することで解決しています。
ツールバーをマウスでクリックしたあとCtrl+Zが効かないバグを修正。フォーカスがツールバーボタンに残ることでキーイベントがブラウザへ送られる問題と、`dispatchInsertCodeBlock` における不要な `editor.update()` ネストの2つの原因を解消しました。
Trix/ActionTextのメンションHTMLをLexxyにペーストするとエディターがクラッシュする問題を修正。`importDOM()` 内の無条件 `JSON.parse()` を、失敗時に生文字列へフォールバックする `parseAttachmentContent()` ヘルパーに置き換えることで、LexxyのJSON形式とTrixの生HTML形式の両方を安全に処理できるようになった。
LexicalのCodeNodeを抜けるために3回のEnterが必要だった問題を修正。FormatEscaperクラスにKEY_ENTER_COMMANDとKEY_ARROW_DOWN_COMMANDのハンドラーを追加し、「空行でのEnter1回」または「ArrowDownキー」でコードブロックを脱出できるようにした。ChromiumとFirefoxのカーソルオフセット表現の差異にも対応している。