Обновите свой код

Обновления, не связанные с другими проблемами

Это первый из трех разделов, описывающих изменения, необходимые для кода, который не является частью работника службы расширения. Этот раздел предназначен для необходимых изменений кода, не связанных с другими проблемами. Следующие два раздела посвящены замене блокировки веб-запросов и повышению безопасности .

Замените tabs.executeScript() на scripting.executeScript().

В Манифесте V3 executeScript() перемещается из API tabs в API scripting . Это требует изменения разрешений в файле манифеста в дополнение к фактическим изменениям кода.

Для метода executeScript() вам необходимо:

  • Разрешение "scripting" .
  • Либо разрешения хоста, либо разрешение "activeTab" .

Метод scripting.executeScript() аналогичен тому, как он работает с tabs.executeScript() . Есть несколько отличий.

  • В то время как старый метод мог обрабатывать только один файл, новый метод может принимать массив файлов.
  • Вы также передаете объект ScriptInjection вместо InjectDetails . Между ними существует множество различий. Например, tabId теперь передается как член ScriptInjection.target а не как аргумент метода.

В примере показано, как это сделать.

Манифест V2
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

chrome.tabs.executeScript(
  tab.id,
  {
    file: 'content-script.js'
  }
);

В файле фонового сценария.

Манифест V3
async function getCurrentTab()
let tab = await getCurrentTab();

chrome.scripting.executeScript({
  target: {tabId: tab.id},
  files: ['content-script.js']
});

В работнике службы расширения.

Замените tabs.insertCSS() и tabs.removeCSS() на scripting.insertCSS() и scripting.removeCSS().

В Манифесте V3 insertCSS() и removeCSS() переходят из API tabs в API scripting . Это требует изменения разрешений в файле манифеста в дополнение к изменениям кода:

  • Разрешение "scripting" .
  • Либо разрешения хоста, либо разрешение "activeTab" .

Функции API scripting аналогичны функциям tabs . Есть несколько отличий.

  • При вызове этих методов вы передаете объект CSSInjection вместо InjectDetails .
  • tabId теперь передается как член CSSInjection.target а не как аргумент метода.

В примере показано, как это сделать для insertCSS() . Процедура removeCSS() такая же.

Манифест V2
chrome.tabs.insertCSS(tabId, injectDetails, () => {
  // callback code
});

В файле фонового сценария.

Манифест V3
const insertPromise = await chrome.scripting.insertCSS({
  files: ["style.css"],
  target: { tabId: tab.id }
});
// Remaining code. 

В работнике службы расширения.

Замените действия браузера и действия страницы действиями

Действия браузера и действия страницы были отдельными концепциями в Manifest V2. Хотя вначале они играли разные роли, со временем различия между ними уменьшились. В Manifest V3 эти концепции объединены в Action API. Для этого потребуются изменения в вашем manifest.json и коде расширения, которые отличаются от того, что вы бы поместили в фоновый сценарий Манифеста V2.

Действия в Manifest V3 больше всего напоминают действия браузера; однако API action не предоставляет hide() и show() как это было pageAction . Если вам по-прежнему нужны действия на странице, вы можете либо эмулировать их, используя декларативный контент , либо вызвать enable() или disable() с идентификатором вкладки.

Замените «browser_action» и «page_action» на «action».

В файле manifest.json замените поля "browser_action" и "page_action" полем "action" . Обратитесь к ссылке для получения информации о поле "action" .

Манифест V2
{
  ...
  "page_action": { ... },
  "browser_action": {
    "default_popup": "popup.html"
   }
  ...
}
Манифест V3
{
  ...
  "action": {
    "default_popup": "popup.html"
  }

  ...
}

Замените API-интерфейсы BrowseAction и PageAction API-интерфейсами действий.

Там, где ваш Манифест V2 использовал API-интерфейсы browserAction и pageAction , теперь вам следует использовать API-интерфейс action .

Манифест V2
chrome.browserAction.onClicked.addListener(tab => { ... });
chrome.pageAction.onClicked.addListener(tab => { ... });
Манифест V3
chrome.action.onClicked.addListener(tab => { ... });

Замените обратные вызовы обещаниями

В Манифесте V3 многие методы API расширений возвращают обещания. Обещание — это прокси или заполнитель для значения, возвращаемого асинхронным методом. Если вы никогда не использовали Promises, вы можете прочитать о них на MDN . На этой странице описано, что вам нужно знать, чтобы использовать их в расширении Chrome.

В целях обратной совместимости многие методы продолжают поддерживать обратные вызовы после добавления поддержки обещаний. Имейте в виду, что вы не можете использовать оба варианта при одном вызове функции. Если вы передадите обратный вызов, функция не вернет обещание, и если вы хотите вернуть обещание, не передайте обратный вызов. Некоторые функции API, такие как прослушиватели событий, по-прежнему будут требовать обратных вызовов. Чтобы проверить, поддерживает ли метод обещания, найдите метку «Promise» в его справочнике по API.

Чтобы преобразовать обратный вызов в обещание, удалите обратный вызов и обработайте возвращенное обещание. Приведенный ниже пример взят из примера необязательных разрешений , в частности newtab.js . Версия обратного вызова показывает, как будет выглядеть пример вызова метода request() с обратным вызовом. Обратите внимание, что версию обещания можно переписать с помощью async и await.

Перезвонить
chrome.permissions.request(newPerms, (granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});
Обещать
const newPerms = { permissions: ['topSites'] };
chrome.permissions.request(newPerms)
.then((granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});

Замените функции, ожидающие фонового контекста Manifest V2.

Другие контексты расширения могут взаимодействовать только с работниками службы расширения, используя передачу сообщений . Следовательно, вам нужно будет заменить вызовы, ожидающие фонового контекста, а именно:

  • chrome.runtime.getBackgroundPage()
  • chrome.extension.getBackgroundPage()
  • chrome.extension.getExtensionTabs()

Скрипты вашего расширения должны использовать передачу сообщений для связи между сервисным работником и другими частями вашего расширения. В настоящее время это можно сделать с помощью sendMessage() и реализации chrome.runtime.onMessage в рабочем сервисе расширений. В долгосрочной перспективе вам следует запланировать замену этих вызовов на postMessage() и обработчик событий сообщений сервис-воркера.

Замените неподдерживаемые API

Перечисленные ниже методы и свойства необходимо изменить в Manifest V3.

Манифест метода или свойства V2 Заменить на
chrome.extension.connect() chrome.runtime.connect()
chrome.extension.connectNative() chrome.runtime.connectNative()
chrome.extension.getExtensionTabs() chrome.extension.getViews()
chrome.extension.getURL() chrome.runtime.getURL()
chrome.extension.lastError Если методы возвращают обещания, используйте promise.catch()
chrome.extension.onConnect chrome.runtime.onConnect
chrome.extension.onConnectExternal chrome.runtime.onConnectExternal
chrome.extension.onMessage chrome.runtime.onMessage
chrome.extension.onRequest chrome.runtime.onMessage
chrome.extension.onRequestExternal chrome.runtime.onMessageExternal
chrome.extension.sendMessage() chrome.runtime.sendMessage()
chrome.extension.sendNativeMessage() chrome.runtime.sendNativeMessage()
chrome.extension.sendRequest() chrome.runtime.sendMessage()
chrome.runtime.onSuspend (фоновые сценарии) Не поддерживается в работниках службы расширения. Вместо этого используйте событие документа beforeunload .
chrome.tabs.getAllInWindow() chrome.tabs.query()
chrome.tabs.getSelected() chrome.tabs.query()
chrome.tabs.onActiveChanged chrome.tabs.onActivated
chrome.tabs.onHighlightChanged chrome.tabs.onHighlighted
chrome.tabs.onSelectionChanged chrome.tabs.onActivated
chrome.tabs.sendRequest() chrome.runtime.sendMessage()
chrome.tabs.Tab.selected chrome.tabs.Tab.highlighted