https://github.com/basecamp/lexxy
lexxyエディタのフォーマットドロップダウンに「Clear formatting」ボタンが追加されました。Lexicalの`$forEachSelectedTextNode`でビットフラグをゼロクリアし、`$toggleLink`や`$setBlocksType`を組み合わせることで、太字・斜体・リンク・ブロックスタイルなど多様な書式を一操作で一括除去できます。テーブルはPR Descriptionの仕様通り構造を維持し、内部のテキスト書式のみが除去されます。
`lexxy-editor` カスタム要素のID自動生成が、`element.id` が未設定時に `null` ではなく空文字列 `""` を返すHTML仕様のために機能していなかったバグを修正。`??=`(nullish代入)を `||=`(論理OR代入)に変更することで、falsy値である空文字列も正しく処理されるようになりました。
LexxyにStrada Bridgeを介したネイティブモバイルサポートが追加された。BrowserAdapter/NativeAdapterによるアダプタパターンで、エディタコアを変更せずにiOS/Androidツールバーとの状態同期・選択freeze/thaw・コード言語ピッカー委譲・Bridge管理の添付ファイルアップロードを実現している。
Lexicalエディタ要素の切断時に`editor.dispose()`を呼び出す仕組みを整備し、10回の再接続サイクルで+4,440件のリスナーと+12,685件のノードが蓄積していた問題をゼロにしました。CommandDispatcher・Selection・Toolbar等の各コンポーネントにdispose()を実装し、ハンドラ参照固定とCustom Elements冪等化を組み合わせてリソース管理を体系化。Chrome DevTools Protocolを使ったリークテストも追加されています。
リスト系ボタンをドロップダウンにまとめていた設計を撤回し、箇条書きと番号付きリストを再び独立したツールバーアイコンとして配置しました。テストヘルパーも `clickFormatButton` と `clickListsButton` を `clickToolbarButton` に統合し、ドロップダウン経由かどうかの判定を内部化。CSSではセパレーター描画が論理プロパティとカスタムプロパティ参照に整理されています。
ツールバーの画像ボタンに `accept="image/*,video/*"` を設定し、iOS・Androidでネイティブフォト/ビデオピッカーが起動するよう改善されました。単一だった `uploadAttachments` コマンドを `uploadImage` と `uploadFile` に分離し、共通ロジックはプライベートメソッドに集約することで後方互換性を維持しています。
ブロッククォートへのペースト時にテキストが引用外に脱出するバグ(#4979)に対するPlaywrightリグレッションテスト3件が追加されました。バグ自体はツールバーリワーク(PR #891)のリファクタリングで偶発的に修正済みでしたが、同時にオリジナルの修正(PR #839)のテストも削除されており、本PRはそのテストの空白を補完するものです。
ソフトブレーク(Shift+Enter)とハードブレーク(Enter)が混在するテキストで、選択範囲の一部にのみ引用フォーマットを適用すると選択外の行まで巻き込まれるバグを修正。`selection.getNodes()` が部分選択された段落の全子ノードを返すLexicalの仕様に起因しており、選択範囲の判定を `getNodes()` からアンカー・フォーカス位置のチェックに切り替えることで解決しています。
Firefox / Gecko 系ブラウザでカット&ペーストを行うとコンテンツが二重挿入されるバグを修正。リッチテキストのペースト処理パスで `event.preventDefault()` が呼ばれておらず、Firefox のネイティブペースト処理と Lexical のカスタムハンドラが二重に DOM を変更していたことが原因。ハンドラが処理を行った場合のみ `preventDefault` を呼ぶよう修正し、Lexical 本体のハンドラと一貫した設計に揃えた。
混在するインラインフォーマット(太字・斜体など)を含む選択範囲にコードフォーマットを適用すると、フォーマットごとに `<code>` 要素が分割されてしまうバグを修正しました。コード適用前に選択範囲のインラインフォーマットを除去する前処理を追加することで、Lexicalのノードマージを有効化して単一の `<code>` 要素を生成します。部分選択時は `splitText()` で境界ノードを分割し、選択外テキストのフォーマットを保持します。
Lexicalエディタで空のリストアイテムをBackspaceで削除した際、Lexicalのデフォルト動作(collapseAtStart)がアイテムを段落へ変換しカーソルをドキュメント上部へジャンプさせる問題を修正。`#removeEmptyListItem` メソッドで兄弟アイテムが存在する場合のみインターセプトし、リスト最終アイテムでの「リスト終了」動作は意図的にデフォルトへ委ねる設計になっています。
DOM の `getAttribute` が返す文字列 `"false"` が truthy と評価されてしまう問題を `parseBoolean` ヘルパーで正規化し、`previewable="false"` の添付ファイルが壊れた画像として表示されるバグを修正しました。また、パスワード保護されたPDFなどプレビュー生成が失敗するケースでは `onerror` フォールバックでDOMをファイル表示に切り替え、ノードの `previewable` プロパティはサーバー向けシリアライズのために変更しない設計を採用しています。
Lexxyのツールバーが大幅に再設計され、単一の見出しサイクルコマンドをh2/h3/h4/段落の4つの明示的コマンドへ置き換えた。Lexicalの組み込み`$setBlocksType` APIを活用してカスタムのノード操作ロジック約374行を削除し、アップロードボタンの分割や`toolbar.upload`設定の追加、アンダーライン対応など複数の改善を同時に達成している。
`<code>` 要素内のテキストをすべて削除するとLexicalの選択状態にコードフォーマットフラグが残存し、以降の入力が誤って `<code>` タグで包まれるバグを修正しました。フォーマットフラグが実際のコード書式付きコンテンツに裏付けられているかを検証する `#isInCode()` メソッドを追加し、staleなフォーマットを検出・除去するアップデートリスナーとの2段構えで対処しています。
投稿済みコメントからコピーしたメンションをLexxyエディタに貼り付けると文字化けが発生していた問題を修正。原因はexportDOM()でのJSON.stringify()使用によるHTMLエンティティとJSONエスケープの衝突であり、Trix/ActionText形式に合わせてcontent属性を生HTMLで格納するよう変更。parseAttachmentContent()が既にJSON/生HTMLの両フォールバックに対応していたため、過去データとの後方互換性を維持しながら修正が実現された。
空のエディタに画像をアップロードした後、キャレットの表示位置と実際の入力位置がずれる問題を修正しました。アップロード完了後の選択管理を `$createNodeSelectionWith` + `$setSelection` から `selectNext()` の呼び出しに変更し、カーソルを添付ファイル直後の仮段落へ移動させます。あわせて `ProvisionalParagraphNode.isSelected()` を拡張し、element型アンカーによるカーソル位置でも仮段落が選択中と判定されるようにすることで、キャレットの正しい視覚的レンダリングを実現しています。
テーブルをコピー&ペーストする際にクリップボードHTMLへ混入するテーマ固有のインラインカラースタイルを、Lexicalがノードを生成する前のDOMレイヤーで除去するようになりました。`PASTE_TAG` を使ってペースト操作のみに処理を限定し、`<td>` と `<th>` から `background-color`、`background`、`color` の3プロパティを削除することで、ペースト後のテーブルが常に閲覧者のテーマカラーを継承します。
Lexicalのコード再トークナイザが`<mark>`ハイライトスタイルを破壊するバグを修正。HTMLインポート時にハイライト範囲を`WeakMap`に退避し、再トークナイズ完了後にミューテーションリスナーで再適用する2フェーズ設計を採用。`Object.assign`によるコンバータ衝突・再トークナイザとのスタイル競合・`splitText()`の型問題という3つのLexical内部制約を回避し、保存・再編集サイクルでコードブロックのハイライトが失われなくなった。
`FormatEscaper`クラス(388行)を廃止し、`FormatEscapeExtension`と`EarlyEscapeCodeNode`・`EarlyEscapeListItemNode`の2ノードに再設計。エスケープロジックをノードの`insertNewAfter`メソッドへ委譲することでLexicalのアーキテクチャと整合させ、`INSERT_PARAGRAPH_COMMAND`への切り替えにより`RangeSelection`の保証も得ています。
Turbo Driveの非同期ナビゲーションと`lexxy-editor`カスタム要素の初期化タイミングの競合により、CIで断続的にタイムアウトしていたシステムテストを修正。`click_on "Update Post"`後に編集ページへ戻ってからアサーションするよう変更し、`wait_for_editor`をナビゲーション直後に統一配置することで競合を解消した。