chrome.offscreen

説明

offscreen API を使用して、画面外ドキュメントを作成、管理します。

権限

offscreen

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

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

対象

Chrome 109 以降 MV3 以降

コンセプトと使用方法

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

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

画面外ドキュメントの動作が通常のページと異なる他の点としては、次のようなものがあります。

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

chrome.offscreen.createDocument()chrome.offscreen.closeDocument() を使用して、画面外ドキュメントを作成して閉じます。createDocument() にはドキュメントの url、理由、理由が必要です。

chrome.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 = chrome.runtime.getURL(path);
  const existingContexts = await chrome.runtime.getContexts({
    contextTypes: ['OFFSCREEN_DOCUMENT'],
    documentUrls: [offscreenUrl]
  });

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

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

画面外のドキュメントにメッセージを送信する前に、次の例に示すように、setupOffscreenDocument() を呼び出してドキュメントが存在することを確認してください。

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

  // Send message to offscreen document
  chrome.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 chrome.runtime) {
    const contexts = await chrome.runtime.getContexts({
      contextTypes: ['OFFSCREEN_DOCUMENT'],
      documentUrls: [OFFSCREEN_DOCUMENT_PATH]
    });
    return Boolean(contexts.length);
  } else {
    const matchedClients = await clients.matchAll();
    return await matchedClients.some(client => {
        client.url.includes(chrome.runtime.id);
    });
  }
}

CreateParameters

プロパティ

  • 理由

    文字列

    バックグラウンド コンテキストの必要性について、デベロッパーが提供する文字列。ユーザー エージェントは、ユーザーへの表示でこれを使用できます。

  • 個の理由

    拡張機能が画面外ドキュメントを作成する理由。

  • URL

    文字列

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

Reason

Enum

"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 を使用する必要があることを指定します。

Methods

closeDocument()

Promise
chrome.offscreen.closeDocument(
  callback?: function,
)

拡張機能で現在開いている画面外ドキュメントを閉じます。

パラメータ

  • callback

    関数(省略可)

    callback パラメータは次のようになります。

    ()=>void

戻り値

  • Promise<void>

    Promise は Manifest V3 以降でサポートされていますが、コールバックは下位互換性のために提供されています。同じ関数呼び出しで両方を使用することはできません。Promise は、コールバックに渡されたのと同じ型で解決されます。

createDocument()

Promise
chrome.offscreen.createDocument(
  parameters: CreateParameters,
  callback?: function,
)

拡張機能の新しい画面外ドキュメントを作成します。

パラメータ

  • パラメータ

    作成する画面外ドキュメントを記述するパラメータ。

  • callback

    関数(省略可)

    callback パラメータは次のようになります。

    ()=>void

戻り値

  • Promise<void>

    Promise は Manifest V3 以降でサポートされていますが、コールバックは下位互換性のために提供されています。同じ関数呼び出しで両方を使用することはできません。Promise は、コールバックに渡されたのと同じ型で解決されます。