注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。

追加の iframe 属性を有効にする

カメラやマイクへのアクセスなど、一部のブラウザー権限では、アプリケーションのユーザーがブラウザープロンプトを通じて Foundry に権限を付与する必要が常にあります。iframe 属性を有効にすると、アプリケーションはアクセス権をリクエストできるようになりますが、ユーザーは引き続き明示的に権限を付与する必要があります。詳細は、Permissions Policy のドキュメント ↗を参照してください。

カスタムウィジェットのランタイムは、デフォルトでポップアップやカメラへのアクセスなどの特定のブラウザー機能を禁止する制限属性が設定された <iframe> ↗ 要素を使用します。ただし、ウィジェット開発者は、カスタムウィジェットに対して一部の属性値を有効にできます。その後、リクエストされた属性値を有効にするには、アプリケーションの作成者がそれらに対する権限を手動で付与する必要があります。ウィジェット開発者とアプリケーションの作成者は、多くの場合同じ人です。ほとんどのウィジェットでは、追加の iframe 属性をリクエストする必要はありません。カメラへのアクセス、メディアの自動再生、ファイルのダウンロードなどのブラウザー機能がウィジェットに必要な場合にのみ、これらの権限をリクエストしてください。

利用可能な iframe 属性

ウィジェット開発者は、次の iframe 属性の有効化をリクエストできます。

allow ↗ 属性の値:

  • camera
  • microphone
  • autoplay

sandbox ↗ 属性の値:

  • allow-downloads
  • allow-forms
  • allow-popups

リクエストする iframe 属性を宣言する

ウィジェット開発者は、カスタムウィジェット設定の permissions フィールドで、リクエストする iframe 属性を宣言できます。

Copied!
1 2 3 4 5 6 7 8 9 export default defineConfig({ id: "widgetId", name: "A custom widget", description: "A widget description", type: "workshop", parameters: {}, events: {}, permissions: ["camera", "allow-popups"], });

ホストアプリケーションでリクエストされた iframe 属性を許可する

Workshop では、アプリケーションの作成者がカスタムウィジェットを設定する際に、リクエストされた iframe 属性に対する権限を付与できます。これらの設定は、パラメーターセクションとイベントセクションの後にある権限セクションに表示されます。

Workshop でカスタムウィジェットを設定する際の権限セクション。

特定の iframe 属性を有効にする際には、アプリケーションの作成者が Checkpoint で了承する必要がある場合があります。

開発中は、テストのために、リクエストされた iframe 属性を一時的に許可できます。ホストアプリケーションで属性を明示的に許可せずに、カスタムウィジェットのプレイグラウンドまたは VS Code ワークスペースを使用します。

例

カメラとマイク

次の例では、iframe の allow 属性の値 camera と microphone を有効にする必要があります。

navigator.mediaDevices.getUserMedia ↗ メソッドを使用すると、メディア入力(この例ではカメラとマイク)を使用する権限を求めるプロンプトをユーザーに表示できます。成功すると、MediaStream ↗ オブジェクトが返されます。

Copied!
1 2 3 4 const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true, });

また、Permissions API ↗ を使用して、ブラウザー権限の現在のステータスをクエリできます。返される値は、iframe 属性とユーザーのブラウザープロンプトのステータスに基づいて、"granted"、"prompt"、または "denied" になります。

Copied!
1 2 navigator.permissions.query({ name: "camera" }); navigator.permissions.query({ name: "microphone" });

ウィジェット開発者は、属性によるアクセスが利用できない場合も適切に処理されるようにしてください。

自動再生

次の例では、iframe の allow 属性の値 autoplay を有効にする必要があります。

[<audio> または <video> 要素に autoplay ↗ 属性を使用すると、メディアを自動再生できます。

Copied!
1 <video src={myVideoSrc} autoplay controls />

ダウンロード

次の例では、iframe の sandbox 属性の値 allow-downloads を有効にする必要があります。

CSV (blob) を動的に作成する

CSV の内容を使って Blob ↗ を構築し、ブラウザーでダウンロードできます。

Copied!
1 2 3 4 5 6 7 8 9 10 11 <button onClick={() => { const csv = "a,b,c\n1,2,3"; const blob = new Blob([csv], { type: "text/csv" }); const url = URL.createObjectURL(blob); triggerDownload(url, "data.csv"); URL.revokeObjectURL(url); }} > Download CSV </button>

triggerDownload ヘルパー関数は、ダウンロードを開始するために <a> 要素を一時的に作成します。

Copied!
1 2 3 4 5 6 7 8 function triggerDownload(url: string, filename: string) { const a = document.createElement("a"); a.download = filename; a.href = url; document.body.appendChild(a); a.click(); a.remove(); }

ウィジェットに含まれる静的アセットをダウンロードする

カスタムウィジェットに含まれる静的アセットをダウンロードする2つの方法を以下に説明します。詳細は、Vite の静的アセット処理 ↗のドキュメントを参照してください。

直接指定する href

カスタムウィジェットの開発モードでは、開発サーバーはカスタムウィジェットのランタイムとは異なるオリジン(たとえば localhost)からアセットを提供します。この動作により、ブラウザーがダウンロードを開始せずに新規タブを開く場合があります。ただし、本番環境でカスタムウィジェットを使用する場合は、アセットのダウンロードが正しく開始されます。

Vite の方法で静的アセットを URL としてインポートする ↗場合、アセットの URL を <a> 要素の href 属性に直接指定し、download 属性と組み合わせて使用できます。

Copied!
1 2 3 4 5 import imgUrl from "./img.png"; <a href={imgUrl} download="img.png" target="_blank" rel="noreferrer"> Download </a>;

Vite の public ディレクトリー ↗を使用する場合、public ディレクトリー内のアセットは、ルートからの絶対パスを使って参照してください。たとえば、コード内では public/img.png を /img.png として参照します。

Copied!
1 2 3 <a href="/img.png" download="img.png" target="_blank" rel="noreferrer"> Download </a>

代替の fetch blob 方式

別の方法では、fetch を使用し、必要に応じて追加の処理を行ってから、CSV (blob) を動的に作成する方法と同様に Blob ↗ としてダウンロードします。追加処理の例として、取得した静的アセット内の値をユーザーが入力した値に置き換えることが挙げられます。

Vite の方法で静的アセットを URL としてインポートする ↗場合は、data: URI によるコンテンツセキュリティポリシー (CSP) の問題を回避するため、インライン化を禁止する ↗ことも推奨します。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import imgUrl from "./img.png?no-inline"; <button onClick={async () => { const response = await fetch(imgUrl); const blob = await response.blob(); // 任意:追加の処理を実行します const objectUrl = window.URL.createObjectURL(blob); triggerDownload(objectUrl, filename); window.URL.revokeObjectURL(objectUrl); }} > Download </button>;

Vite の public ディレクトリー ↗を使用する場合、public ディレクトリー内のアセットは、ルートからの絶対パスを使って参照してください。たとえば、コード内では public/img.png を /img.png として参照します。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 <button onClick={async () => { const response = await fetch("/img.png"); const blob = await response.blob(); // 任意:追加の処理を実行します const objectUrl = window.URL.createObjectURL(blob); triggerDownload(objectUrl, filename); window.URL.revokeObjectURL(objectUrl); }} > Download </button>

triggerDownload ヘルパー関数は、ダウンロードを開始するために <a> 要素を一時的に作成します。

Copied!
1 2 3 4 5 6 7 8 function triggerDownload(url: string, filename: string) { const a = document.createElement("a"); a.download = filename; a.href = url; document.body.appendChild(a); a.click(); a.remove(); }

リンクを開く

Workshop で開発する場合は、リンクを開くための Workshop イベントを作成することを推奨します。この方法では、追加の iframe 属性をリクエストする必要がありません。また、以下で説明する allow-popups を使用する方法で開いた新規タブやウィンドウは、カスタムウィジェットのサンドボックス制限を継承するため、特に注意が必要です。たとえば、開いたタブやウィンドウでファイルをダウンロードする必要がある場合は、カスタムウィジェットで allow-downloads も有効にする必要があります。

次の例では、iframe の sandbox 属性の値 allow-popups を有効にする必要があります。

<a> 要素に href と関連する属性を指定すると、新規タブでリンクを開けます。

Copied!
1 2 3 <a href="https://palantir.com/docs" target="_blank" rel="noreferrer"> Link </a>