Visualizer のプラグインは、単一のコードとして動作するわけではありません。各プラグインは、別々の環境で動作して相互に通信する 2 つの部分に分かれています。この構成により、コードが実行される場所ごとに、できることとできないことが決まります。
プラグインの実行方法
Section titled “プラグインの実行方法”プラグインが読み込まれると、Visualizer はコードを次の 2 つの環境で実行します。
- Visualizer のデータとプラグインAPIに直接アクセスできる WebAssembly 環境
- すべての UI 描画を担当し、標準のブラウザ API を利用できる iframe 環境
どちらか一方だけですべてを実行することはできません。WebAssembly 側は Visualizer のデータを読み取って操作できますが、HTML の描画や多くのブラウザ API の利用はできません。iframe 側は HTML の描画やブラウザ API の利用ができますが、Visualizer のデータへ直接アクセスできません。2 つの環境が互いを補完します。
両者は、異なる実行コンテキスト間で安全に通信するための標準的なブラウザ機能である postMessage を使って通信します。UI が Visualizer のデータを必要とするときは、WebAssembly 側にデータを要求します。WebAssembly 側はデータを取得し、iframe 側へ送信します。
WebAssembly 側
Section titled “WebAssembly 側”WebAssembly 側はプラグインのエントリーポイントです。プラグインが読み込まれたときに最初に実行され、Visualizer と同じスレッドで同期的に動作します。
できること:
- Visualizer のシーンデータへアクセスする。
- プラグインAPIを呼び出す。
- レイヤのプロパティの更新など、Visualizer のシーンを部分的に変更する。
- シーンのイベントを購読する。
postMessageを使って iframe 側とデータを送受信する。
できないこと:
- HTML や UI を直接描画する。UI の描画は iframe 側で行う必要があります。
- 多くのブラウザ API を利用する。利用できるのは
console.logなど一部に限られます。 - 外部サーバーへ HTTP リクエストを送信する。
iframe 側
Section titled “iframe 側”iframe 側は、プラグインの視覚的な要素をすべて処理します。通常のウェブページと同じように動作し、ブラウザ API を利用できます。
できること:
- 通常のウェブページと同じように HTML を描画する。
- DOM API、Canvas、
fetchなどのブラウザ API を利用する。 - サーバーのレスポンスヘッダーに
Access-Control-Allow-Origin: *が含まれている場合、外部サーバーへ HTTP リクエストを送信する。 postMessageを使って WebAssembly 側とデータを送受信する。
できないこと:
- Visualizer のデータへ直接アクセスしたり変更したりする。
postMessageを通じて WebAssembly 側へ要求する必要があります。 - Visualizer のバックエンドと直接通信する。
- レスポンスヘッダーに
Access-Control-Allow-Origin: *が含まれていないサーバーへ HTTP リクエストを送信する。iframe は null オリジンでサンドボックス化されています。 - 同じサンドボックス上の理由により、ローカルストレージを利用する。
- 親ページから明示的な権限を必要とするブラウザ API を利用する。たとえば、Clipboard API はサンドボックス化された iframe ではデフォルトで利用できません。
| 機能 | WebAssembly 側 | iframe 側 |
|---|---|---|
| サンドボックス化 | ✅ | ✅ |
| エントリーポイント(最初に実行) | ✅ | ❌ |
| プラグインAPIへのアクセス | ✅ | ❌ |
| HTML の描画 | ❌ | ✅ |
| ブラウザ API の利用 | ❌ | ✅ |
postMessage による通信 | ✅ | ✅ |
postMessage のシリアライズ: postMessage で送信できるのは、JSON としてシリアライズ可能なデータだけです。ArrayBuffer や Blob などのオブジェクトは直接送信できません。バイナリーデータは、送信前に base64 文字列へエンコードしてください。
プラグインのサイズ: プラグインは 10 MB 以下の .zip ファイルとしてパッケージ化する必要があります。
静的アセット: 画像、HTML、CSS などの JavaScript 以外のファイルは、プラグイン内に含めることができません。JavaScript に文字列として埋め込むか、一般公開されたサーバーに配置して URL で参照してください。
ローカルストレージ: ローカルストレージは両方の環境で利用できません。データを永続化するには、プラグインAPIが提供するストレージ API または外部サーバーを使用してください。