browser.offscreen

説明

offscreen API を使用して、オフスクリーン ドキュメントを作成、管理します。

権限

offscreen

Offscreen API を使用するには、拡張機能マニフェストで "offscreen" 権限を宣言します。次に例を示します。

{
  "name": "My extension",
  ...
  "permissions": [
    "offscreen"
  ],
  ...
}

対象

Chrome 109 以降 Chrome 148 以降の browser.* MV3 以降

コンセプトと使用方法

Service Worker には DOM アクセス権がなく、多くのウェブサイトにはコンテンツ スクリプトの機能を制限するコンテンツ セキュリティ ポリシーがあります。Offscreen API を使用すると、拡張機能は、新しいウィンドウやタブを開いてユーザー エクスペリエンスを中断することなく、非表示のドキュメントで DOM API を使用できます。runtime API は、オフスクリーン ドキュメントでサポートされている唯一の拡張機能 API です。

オフスクリーン ドキュメントとして読み込まれたページは、他のタイプの拡張機能ページとは異なる方法で処理されます。拡張機能の権限はオフスクリーン ドキュメントに引き継がれますが、拡張機能 API へのアクセスには制限があります。たとえば、browser.runtime API はオフスクリーン ドキュメントでサポートされている唯一の拡張機能 API であるため、メッセージは、その API のメンバーを使用して処理する必要があります。

オフスクリーン ドキュメントの動作が通常のページと異なる点は他にもあります。

  • オフスクリーン ドキュメントの URL は、拡張機能にバンドルされた静的 HTML ファイルである必要があります。
  • オフスクリーン ドキュメントにフォーカスすることはできません。
  • オフスクリーン ドキュメントは window のインスタンスですが、opener プロパティの値は常に null です。
  • 拡張機能パッケージには複数のオフスクリーン ドキュメントを含めることができますが、インストールされた拡張機能で一度に開くことができるのは 1 つだけです。拡張機能がシークレット プロファイルが有効な分割モードで実行されている場合、通常のプロファイルとシークレット プロファイルにそれぞれ 1 つのオフスクリーン ドキュメントを設定できます。

browser.offscreen.createDocument() と browser.offscreen.closeDocument() を使用して、オフスクリーン ドキュメントを作成して閉じます。createDocument() には、ドキュメントの url、理由、正当な理由が必要です。

browser.offscreen.createDocument({
  url: 'off_screen.html',
  reasons: ['CLIPBOARD'],
  justification: 'reason for needing the document',
});

理由

有効な理由の一覧については、理由セクションをご覧ください。理由は、ドキュメントの作成時に設定され、ドキュメントの有効期間を決定します。AUDIO_PLAYBACK の理由により、音声が再生されないまま 30 秒が経過するとドキュメントが閉じられます。その他の理由では、有効期間の上限は設定されません。

例

オフスクリーン ドキュメントのライフサイクルを維持する

次の例は、オフスクリーン ドキュメントが存在することを確認する方法を示しています。setupOffscreenDocument() 関数呼び出しは runtime.getContexts() を呼び出して、既存のオフスクリーン ドキュメントを検索します。ドキュメントが存在しない場合は、ドキュメントを作成します。

let creating; // A global promise to avoid concurrency issues
async function setupOffscreenDocument(path) {
  // Check all windows controlled by the service worker to see if one
  // of them is the offscreen document with the given path
  const offscreenUrl = browser.runtime.getURL(path);
  const existingContexts = await browser.runtime.getContexts({
    contextTypes: ['OFFSCREEN_DOCUMENT'],
    documentUrls: [offscreenUrl]
  });

  if (existingContexts.length > 0) {
    return;
  }

  // create offscreen document
  if (creating) {
    await creating;
  } else {
    creating = browser.offscreen.createDocument({
      url: path,
      reasons: ['CLIPBOARD'],
      justification: 'reason for needing the document',
    });
    await creating;
    creating = null;
  }
}

オフスクリーン ドキュメントにメッセージを送信する前に、次の例に示すように setupOffscreenDocument() を呼び出してドキュメントが存在することを確認します。

browser.action.onClicked.addListener(async () => {
  await setupOffscreenDocument('off_screen.html');

  // Send message to offscreen document
  browser.runtime.sendMessage({
    type: '...',
    target: 'offscreen',
    data: '...'
  });
});

完全な例については、GitHub の offscreen-clipboard と offscreen-dom のデモをご覧ください。

Chrome 116 より前: 画面外ドキュメントが開いているかどうかを確認する

runtime.getContexts() は Chrome 116 で追加されました。以前のバージョンの Chrome では、clients.matchAll() を使用して、既存のオフスクリーン ドキュメントを確認します。

async function hasOffscreenDocument() {
  if ('getContexts' in browser.runtime) {
    const contexts = await browser.runtime.getContexts({
      contextTypes: ['OFFSCREEN_DOCUMENT'],
      documentUrls: [OFFSCREEN_DOCUMENT_PATH]
    });
    return Boolean(contexts.length);
  } else {
    const matchedClients = await clients.matchAll();
    return matchedClients.some(client => {
      return client.url.includes(browser.runtime.id);
    });
  }
}

型

CreateParameters

プロパティ

  • 理由

    文字列

    デベロッパーが指定する文字列。バックグラウンド コンテキストが必要な理由を詳しく説明します。ユーザー エージェントは、ユーザーへの表示にこれを使用することがあります。

  • 回答者

    拡張機能がオフスクリーン ドキュメントを作成する理由。

  • URL

    文字列

    ドキュメントに読み込む(相対)URL。

Reason

列挙型

"TESTING"
テスト専用の理由。

"AUDIO_PLAYBACK"
オフスクリーン ドキュメントが音声の再生を担当することを指定します。

"IFRAME_SCRIPTING"
オフスクリーン ドキュメントが iframe のコンテンツを変更するために iframe を埋め込んでスクリプト化する必要があることを指定します。

"DOM_SCRAPING"
オフスクリーン ドキュメントが iframe を埋め込み、その DOM をスクレイピングして情報を抽出する必要があることを指定します。

"BLOBS"
オフスクリーン ドキュメントが Blob オブジェクト(URL.createObjectURL() を含む)とやり取りする必要があることを指定します。

"DOM_PARSER"
オフスクリーン ドキュメントで DOMParser API を使用する必要があることを指定します。

"USER_MEDIA"
オフスクリーン ドキュメントがユーザー メディア(getUserMedia() など)のメディア ストリームを操作する必要があることを指定します。

"DISPLAY_MEDIA"
オフスクリーン ドキュメントがディスプレイ メディア(getDisplayMedia() など)のメディア ストリームとやり取りする必要があることを指定します。

"WEB_RTC"
オフスクリーン ドキュメントで WebRTC API を使用する必要があることを指定します。

"CLIPBOARD"
オフスクリーン ドキュメントが Clipboard API とやり取りする必要があることを指定します。

"LOCAL_STORAGE"
オフスクリーン ドキュメントが localStorage にアクセスする必要があることを指定します。

"WORKERS"
オフスクリーン ドキュメントがワーカーを生成する必要があることを指定します。

"BATTERY_STATUS"
オフスクリーン ドキュメントで navigator.getBattery を使用する必要があることを指定します。

"MATCH_MEDIA"
オフスクリーン ドキュメントで window.matchMedia を使用する必要があることを指定します。

"GEOLOCATION"
オフスクリーン ドキュメントで navigator.geolocation を使用する必要があることを指定します。

メソッド

closeDocument()

browser.offscreen.closeDocument(): Promise<void>

拡張機能で現在開いているオフスクリーン ドキュメントを閉じます。

戻り値

  • Promise<void>

    オフスクリーン ドキュメントが閉じられたときに解決される Promise。

createDocument()

browser.offscreen.createDocument(
  parameters: CreateParameters,
)
: Promise<void>

拡張機能の新しいオフスクリーン ドキュメントを作成します。

パラメータ

  • パラメータ

    作成するオフスクリーン ドキュメントを記述するパラメータ。

戻り値

  • Promise<void>

    オフスクリーン ドキュメントが作成され、最初のページ読み込みが完了したときに解決される Promise。

hasDocument()

Chrome 150 以降
browser.offscreen.hasDocument(): Promise<boolean>

拡張機能にアクティブなドキュメントがあるかどうかを判断します。

戻り値

  • Promise<boolean>

    拡張機能にアクティブなオフスクリーン ドキュメントがあるかどうかの結果で解決される Promise。