`<wa-zoomable-frame>`にテーマ同期機能を追加するオプト・イン属性

shoelace-style/webawesome

<wa-zoomable-frame>with-theme-sync属性が追加され、ホストページのライト/ダークモードやテーマクラスをiframe内に自動的に反映できるようになりました。デフォルトでは同期が無効なオプト・イン設計により、既存の利用箇所への影響を排除しています。

背景

これまで<wa-zoomable-frame>はiframeのコンテンツをホストページのテーマと独立して表示しており、Web Awesomeのスタイルを使ったコンテンツをiframe内で描画する場合にテーマの不一致が生じていました。ホストページでwa-darkクラスやwa-theme-*のようなテーマセレクタクラスが切り替わっても、iframe側のドキュメントには反映されない状態でした。

ドキュメントのサンプルURLもhttps://webawesome.com/から/examples/themes/showcaseというローカルのテーマショーケースページに変更されています。これは、テーマ同期の動作確認に適したページを例示することで、新機能の効果をドキュメント上でも示す意図があると読み取れます。

技術的な変更

with-theme-sync属性の追加

zoomable-frame.tswithThemeSyncプロパティが追加され、with-theme-sync属性としてHTML上で指定できるようになりました。属性の有無で以下の2つの仕組みが連動して起動・停止します。

  • MutationObserver: document.documentElementのclassリストの変化を監視し、変化のたびにsyncTheme()を呼び出す
  • ColorSchemeController: CSSトランジションを利用してテーマ変更を検出するReactive Controller

withThemeSyncが変化した際の処理はupdated()ライフサイクル内に実装されています。

if (changedProperties.has('withThemeSync')) {
  if (this.withThemeSync) {
    this.themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
    this.syncTheme(); // Apply immediately when toggled on
  } else {
    this.themeObserver.disconnect();
  }
}

with-theme-syncがオンになった瞬間にsyncTheme()を即時呼び出すことで、属性追加時点のテーマ状態をiframe側に即座に適用します。

ColorSchemeControllerの新設

src/internal/color-scheme-controller.tsとして新たなReactive Controllerが追加されました。このControllerはCSSカスタムプロパティ--wa-color-surface-defaultcolorとして参照する非表示のdiv要素をコンポーネントに追加し、テーマ変更時に発生するCSSトランジションのtransitionendイベントを利用してコールバックを呼び出します。

this.hiddenElement = document.createElement('div');
this.hiddenElement.setAttribute('aria-hidden', 'true');
Object.assign(this.hiddenElement.style, {
  position: 'absolute',
  width: '0',
  height: '0',
  overflow: 'hidden',
  pointerEvents: 'none',
  opacity: '0',
  color: 'var(--wa-color-surface-default, transparent)',
  transition: 'color 0.001ms',
});

このアプローチは、テーマ変更をクラス名の変化ではなくCSSカスタムプロパティの値変化として検出する点が特徴です。MutationObserverだけではカバーできない、CSSカスタムプロパティレベルのテーマ変化に対応するために使われています。

テスト

zoomable-frame.test.tsにテーマ同期に関するテストスイートが追加されました。iframeのsrcdocが実際にロードされるまで待機するユーティリティ関数waitForIframe()を定義し、以下のケースを検証しています。

  • with-theme-syncなし(デフォルト)では、ホストのクラスがiframeに伝播しないこと
  • with-theme-syncありでは、ロード時点でホストのクラスがiframeに同期されること
  • デフォルト状態では、ホストのクラスが後から変わってもiframeに反映されないこと
function waitForIframe(el: WaZoomableFrame) {
  return waitUntil(() => el.contentDocument?.URL === 'about:srcdoc' && el.contentDocument.readyState === 'complete');
}

iframeがabout:blankからabout:srcdocに遷移したことを確認することで、srcdocコンテンツが実際にロードされたことを厳密に検証しています。

設計判断

同期機能をデフォルト無効のオプト・インとして設計した点が重要な判断です。外部URLを表示する用途では、ホストのクラスをiframeに注入することは不要なだけでなく、クロスオリジンのiframeへのアクセスはブラウザのセキュリティポリシーによりブロックされます。デフォルト無効にすることで、既存の利用箇所を壊さずに機能を追加できています。

テーマ変更の検出に2つの仕組みを組み合わせている点も注目されます。MutationObserverはclassリストの変化(wa-darkwa-theme-*の付け外し)を捉え、ColorSchemeControllerはCSSカスタムプロパティの値変化をトランジションで検出します。前者だけではCSSカスタムプロパティのみが変わるケースを取りこぼす可能性があるため、両者を補完的に使う構成になっています。

まとめ

with-theme-sync属性の追加により、<wa-zoomable-frame>はWeb Awesomeのテーマ体系に統合されたプレビューコンポーネントとして機能するようになりました。CSSトランジションを活用したテーマ変更検出という手法は、ColorSchemeControllerとして汎用的なReactive Controllerに切り出されており、他のコンポーネントへの応用も容易な設計です。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
986f39c8

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「リード文(総論)→背景・技術詳細・設計判断(各論)→まとめ(結論)」という構成が明確で、理想的な記事構造です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト、PR番号のリンク記法ともに正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

MutationObserverやReactive Controllerといった用語を前提知識として扱っており、専門知識を持つエンジニアという対象読者に適合しています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、各段落もトピックセンテンスで始まるなど、パラグラフ・ライティングの原則がよく守られています。非常に読みやすいです。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されている3つのコードブロックは、すべて提供されたDiffの内容と正確に一致しています。ファイルパスも正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「MutationObserver」「Reactive Controller」「srcdoc」「transitionend」など、関連する技術用語を正確かつ適切な文脈で使用しています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

MutationObserverとColorSchemeControllerという2つの仕組みが、それぞれクラス名の変更とCSSカスタムプロパティの変更をどのように検出するかの説明が、技術的に正確かつ論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(オプトイン設計、2種類の検出メカニズム、テスト内容など)が、PRのDiff情報によって裏付けられており、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#2165)が正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルは、PRの主な変更点である「テーマ同期機能の追加」と「オプト・イン属性」という2つの要点を的確に捉えており、内容と完全に一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

PR情報に含まれないバージョン情報やリリース予定など、外部知識の捏造はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「これまで」と「追加され」といった時間表現が、PRの変更内容を正確に反映しています。