ツールバーのオーバーフロー計算が `data-prevent-overflow` 要素を正しく考慮するよう修正
ツールバーのオーバーフロー計算ロジックが data-prevent-overflow 属性を持つ要素を無視していたバグを修正しました。これにより、エクステンション経由で挿入された「オーバーフロー禁止」ボタンがツールバーのコンテナ幅を突き破る問題が解消されます。
背景
Lexxy のツールバーは、表示幅が不足すると一部のボタンをオーバーフローメニューへ移動するコンパクト機能を持っています。ただし、data-prevent-overflow 属性を持つ要素はオーバーフローメニューへの移動対象外として扱う設計になっています。問題は、オーバーフローが発生するかどうかを計算する際にこれらの要素が考慮されていなかった点にあります。
エクステンションが data-prevent-overflow 付きのボタンを挿入した場合、そのボタンはオーバーフローメニューには送られないにもかかわらず、幅の計算では他のボタンと同様に扱われ、結果としてコンテナ幅をはみ出す表示崩れが発生していました。
技術的な変更
#refreshOverflow() および #compactMenu() のロジックが見直され、オーバーフロー判定の前に #hideOverflowMenuButton() の呼び出しが追加されました。また、オーバーフロー状態の検出に使うセレクタが #overflowMenu から #overflowMenuDropdown へ変更されており、ドロップダウンの子要素数をより正確に参照するようになっています。
変更前:
#refreshOverflow() {
this.#resetToolbarOverflow()
this.#reindexToolbarItems()
this.#compactMenu()
const isOverflowing = this.#overflowMenu.children.length > 0
this.toggleAttribute("overflowing", isOverflowing)
this.#overflow.style.display = isOverflowing ? "block" : "none"
this.#overflow.setAttribute("nonce", getNonce())
this.#overflowMenu.toggleAttribute("disabled", !isOverflowing)
}
変更後:
#refreshOverflow() {
this.#hideOverflowMenuButton()
this.#resetToolbarOverflow()
this.#reindexToolbarItems()
this.#compactMenu()
const isOverflowing = this.#overflowMenuDropdown.children.length > 0
this.toggleAttribute("overflowing", isOverflowing)
}
あわせて、パブリックメソッド closeDropdowns() が新たに追加されました。このメソッドは引数 except で指定したドロップダウンを除く全ドロップダウンを閉じるもので、ツールバー内の複数ドロップダウン間の排他制御に利用されます。
closeDropdowns({ except } = {}) {
this.#dropdowns.forEach((dropdown) => {
if (dropdown !== except) {
dropdown.close({ focusEditor: false })
}
})
}
テスト側では、data-prevent-overflow 付きのボタンを2つ動的に挿入し、360px という狭いビューポートでオーバーフロー再計算を行うブラウザテストが追加されました。テストは「追加したボタンがオーバーフローメニューに入らないこと」と「全ツールバーアイテムがコンテナの左右パディング内に収まること」の2点を検証します。
設計判断
リフロー回避のための読み書き分離という既存方針を維持しつつ、オーバーフロー判定前に表示状態をリセットする手順が整理されています。#hideOverflowMenuButton() を #resetToolbarOverflow() より先に呼び出すことで、メニューボタン自身の表示がレイアウト計算に干渉しないようにする意図が読み取れます。
#overflowMenu から #overflowMenuDropdown への参照先変更は、オーバーフロー状態の有無をドロップダウンの実コンテンツ数で判定するという、より意味論的に正確な実装への移行といえます。また、オーバーフローメニューボタンの display 操作や nonce 付与といった副作用処理が #refreshOverflow() から取り除かれており、責務の分離が進んでいます。
まとめ
この修正は、エクステクションによるツールバー拡張という正規のユースケースがオーバーフロー計算のバグによって壊れていた問題を正確に特定し、計算順序と参照先の整理によって解消したものです。data-prevent-overflow の意味論がレイアウト計算全体に一貫して反映されたことで、エクステンション開発者は属性の挙動を信頼できるようになります。