browser.offscreen

Описание

Используйте offscreen API, чтобы создавать фоновые документы и управлять ими.

Разрешения

offscreen

Чтобы использовать Offscreen API, объявите разрешение "offscreen" в манифесте расширения. Пример:

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

Доступность

Chrome 109+ browser.* начиная с Chrome 148 MV3+

Основные понятия и использование

У сервисных работников нет доступа к DOM, а на многих сайтах действуют правила безопасности контента, ограничивающие функциональность скриптов контента. Offscreen API позволяет расширению использовать DOM API в скрытом документе, не мешая пользователю открывать новые окна или вкладки. runtime API – единственный API расширений, поддерживаемый закадровыми документами.

Страницы, загруженные как закадровые документы, обрабатываются иначе, чем другие типы страниц расширений. Разрешения расширения переносятся на закадровые документы, но с ограничениями на доступ к API расширения. Например, поскольку browser.runtime API – это единственный API расширений, поддерживаемый закадровыми документами, обмен сообщениями должен обрабатываться с помощью элементов этого API.

Ниже приведены другие отличия закадровых документов от обычных страниц.

  • URL документа вне экрана должен быть статическим HTML-файлом, связанным с расширением.
  • Документы вне экрана не могут быть в фокусе.
  • Закадровый документ – это экземпляр window, но значение его свойства opener всегда равно null.
  • Хотя пакет расширения может содержать несколько документов вне экрана, установленное расширение может одновременно открыть только один из них. Если расширение работает в режиме разделения с активным профилем инкогнито, у обычного профиля и профиля инкогнито может быть по одному закадровому документу.

Используйте 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: '...'
  });
});

Полные примеры можно найти в демоверсиях offscreen-clipboard и offscreen-dom на GitHub.

До 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

Свойства

  • без объяснения причин

    string

    Предоставленная разработчиком строка, в которой подробно объясняется, зачем нужен фоновый контекст. Агент пользователя _может_ использовать это значение при показе пользователю.

  • причины

    Причины, по которым расширение создает закадровый документ.

  • url

    string

    Относительный URL, который нужно загрузить в документ.

Reason

Перечисление

TESTING
Причина используется только для тестирования.

"AUDIO_PLAYBACK"
Указывает, что закадровый документ отвечает за воспроизведение аудио.

"IFRAME_SCRIPTING"
Указывает, что закадровому документу необходимо встроить 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, который возвращает результат, указывающий, есть ли у расширения активный закадровый документ.