`<wa-drawer>` の Safari バグ修正:`document.body` から `document` へのイベントリスナー移行
<wa-drawer> コンポーネントで、Web Awesome を <head> タグ内に読み込んだ際にエラーが発生するバグを修正しました。あわせて <wa-dialog> にも同様のワークアラウンドコードが追記されています。
背景
Safari には light dismiss(ポップオーバーやダイアログの外側をクリックして閉じる動作)が正常に機能しないバグが存在します。WebKit Bug #267688 として報告されているこの問題に対し、<wa-drawer> と <wa-dialog> は pointerdown イベントリスナーを空のハンドラで登録するワークアラウンドを採用していました。
しかし <wa-drawer> の実装では、このイベントリスナーを document.body に対して登録していました。スクリプトが <head> 内で実行されるタイミングでは document.body がまだ存在しないため、null に対して addEventListener を呼び出すエラーが発生します。この問題は ディスカッション #2241 で報告されています。
技術的な変更
drawer.ts でのイベントリスナーの登録先を document.body から document に変更することで、<head> 内での実行時のエラーを解消しています。
変更前:
// Ugly, but it fixes light dismiss in Safari: https://bugs.webkit.org/show_bug.cgi?id=267688
document.body.addEventListener('pointerdown', () => {
/* empty */
});
変更後:
//
// Ugly, but it fixes light dismiss in Safari: https://bugs.webkit.org/show_bug.cgi?id=267688
//
// [Mar 27, 2026] - This bug was fixed in Safari 18.3 beta so this can be removed in a year or so.
//
document.addEventListener('pointerdown', () => {
/* empty */
});
あわせて dialog.ts にも同一のコメントブロックが追記されました。コードの動作自体は変わらず(もともと document を対象としていた)、コメントの追加のみの変更です。
//
// Ugly, but it fixes light dismiss in Safari: https://bugs.webkit.org/show_bug.cgi?id=267688
//
// [Mar 27, 2026] - This bug was fixed in Safari 18.3 beta so this can be removed in a year or so.
//
document.addEventListener('pointerdown', () => {
/* empty */
});
設計判断
document.body ではなく document を登録先とする判断は、スクリプトの実行タイミングへの依存を排除するシンプルな修正です。
document オブジェクトはページ解析の最初期から存在するため、<head> 内での実行においても安全にアクセスできます。一方 document.body はHTMLパーサーが <body> タグに到達して初めて生成されるため、<head> 内での参照は null を返します。pointerdown イベントのバブリングは document.body から document へと伝播するため、機能的な差異はありません。
また両ファイルのコメントに「Safari 18.3 beta で修正済み」という注記が追加されたことで、将来的にワークアラウンドを削除するための目安が明示されています。
まとめ
document.body を document へ変更するという一行の修正が、<head> 読み込みというユースケースへの対応を可能にしています。コメントで削除タイミングの目安を明示した点も、技術的負債の管理という観点で参考になる判断です。