Mettre à jour votre code

Informations sans rapport avec d'autres problèmes

Cette section est la première des trois sections qui décrivent les modifications requises pour le code qui ne fait pas partie du service worker de l'extension. Cette section concerne les modifications de code requises qui ne sont pas liées à d'autres problèmes. Les deux sections suivantes expliquent comment remplacer les requêtes Web bloquantes et améliorer la sécurité.

Remplacez tab.executeScript() par scripting.executeScript()

Dans Manifest V3, executeScript() passe de l'API tabs à l'API scripting. Cela nécessite de modifier les autorisations dans le fichier manifeste en plus des modifications réelles du code.

Pour la méthode executeScript(), vous avez besoin des éléments suivants:

  • L'autorisation "scripting".
  • Autorisations d'hôte ou autorisation "activeTab".

La méthode scripting.executeScript() est semblable à la façon dont elle fonctionnait avec tabs.executeScript(). Il y a quelques différences.

  • Alors que l'ancienne méthode n'accepte qu'un seul fichier, la nouvelle accepte un tableau de fichiers.
  • Vous transmettez également un objet ScriptInjection au lieu de InjectDetails. Il existe de nombreuses différences entre les deux. Par exemple, tabId est désormais transmis en tant que membre de ScriptInjection.target au lieu d'être utilisé comme argument de méthode.

L'exemple montre comment procéder.

Manifest V2
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

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

Dans un fichier de script en arrière-plan

Manifest V3
async function getCurrentTab()
let tab = await getCurrentTab();

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

Dans le service worker de l'extension.

Remplacez tab.insertCSS() et tab.removeCSS() par scripting.insertCSS() et scripting.removeCSS().

Dans Manifest V3, insertCSS() et removeCSS() passent de l'API tabs à l'API scripting. Pour ce faire, en plus du code, vous devez modifier les autorisations dans le fichier manifeste:

  • L'autorisation "scripting".
  • Autorisations d'hôte ou autorisation "activeTab".

Les fonctions de l'API scripting sont semblables à celles de tabs. Il y a quelques différences.

  • Lorsque vous appelez ces méthodes, vous transmettez un objet CSSInjection au lieu de InjectDetails.
  • tabId est désormais transmis en tant que membre de CSSInjection.target au lieu d'être utilisé comme argument de méthode.

L'exemple montre comment procéder pour insertCSS(). La procédure pour removeCSS() est la même.

Manifest V2
chrome.tabs.insertCSS(tabId, injectDetails, () => {
  // callback code
});

Dans un fichier de script en arrière-plan

Manifest V3
const insertPromise = await chrome.scripting.insertCSS({
  files: ["style.css"],
  target: { tabId: tab.id }
});
// Remaining code. 

Dans le service worker de l'extension.

Remplacer les actions de navigateur et les actions de page par des actions

Les actions du navigateur et les actions sur les pages étaient des concepts distincts dans Manifest V2. Bien qu'ils aient commencé par des rôles distincts, les différences entre eux se sont détériorées au fil du temps. Dans Manifest V3, ces concepts sont regroupés dans l'API Action. Pour ce faire, vous devez modifier votre manifest.json et le code de l'extension de manière différente de ce que vous auriez mis dans votre script Manifest V2 en arrière-plan.

Les actions dans Manifest V3 ressemblent le plus aux actions du navigateur. Toutefois, l'API action ne fournit pas hide() ni show() comme pageAction. Si vous avez encore besoin d'actions sur la page, vous pouvez les émuler à l'aide de contenu déclaratif, ou appeler enable() ou disable() avec un ID d'onglet.

Remplacer "browser_action" et "page_action" par "action"

Dans manifest.json, remplacez les champs "browser_action" et "page_action" par le champ "action". Consultez la documentation de référence pour en savoir plus sur le champ "action".

Manifest V2
{
  ...
  "page_action": { ... },
  "browser_action": {
    "default_popup": "popup.html"
   }
  ...
}
Manifest V3
{
  ...
  "action": {
    "default_popup": "popup.html"
  }

  ...
}

Remplacer les API browserAction et pageAction par l'API Action

Si votre Manifest V2 utilisait les API browserAction et pageAction, vous devez maintenant utiliser l'API action.

Manifest V2
chrome.browserAction.onClicked.addListener(tab => { ... });
chrome.pageAction.onClicked.addListener(tab => { ... });
Manifest V3
chrome.action.onClicked.addListener(tab => { ... });

Remplacer les rappels par des promesses

Dans Manifest V3, de nombreuses méthodes d'API d'extension renvoient des promesses. Une promesse est un proxy ou un espace réservé pour une valeur renvoyée par une méthode asynchrone. Si vous n'avez jamais utilisé de promesses, vous pouvez en savoir plus sur MDN. Cette page vous explique ce que vous devez savoir pour les utiliser dans une extension Chrome.

Pour assurer la rétrocompatibilité, de nombreuses méthodes continuent à prendre en charge les rappels après l'ajout de la prise en charge des promesses. Sachez que vous ne pouvez pas utiliser les deux dans le même appel de fonction. Si vous transmettez un rappel, la fonction ne renvoie pas de promesse. Si vous souhaitez qu'une promesse soit renvoyée, ne transmettez pas de rappel. Certaines fonctionnalités de l'API, telles que les écouteurs d'événements, continueront de nécessiter des rappels. Pour vérifier si une méthode est compatible avec les promesses, recherchez le libellé "Promise" dans la documentation de référence de son API.

Pour convertir un rappel en promesse, supprimez le rappel et gérez la promesse renvoyée. L'exemple ci-dessous est tiré de l'exemple d'autorisations facultatives, newtab.js spécifiquement. La version de rappel montre à quoi ressemblerait l'appel de l'exemple à request() avec un rappel. Notez que la version de la promesse peut être réécrite avec async et await.

Rappel
chrome.permissions.request(newPerms, (granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});
Promesse
const newPerms = { permissions: ['topSites'] };
chrome.permissions.request(newPerms)
.then((granted) => {
  if (granted) {
    console.log('granted');
  } else {
    console.log('not granted');
  }
});

Remplacer les fonctions qui attendent un contexte Manifest V2 en arrière-plan

Les autres contextes d'extension ne peuvent interagir avec les service workers d'extension qu'à l'aide de la transmission de messages. Par conséquent, vous devez remplacer les appels qui attendent un contexte d'arrière-plan, en particulier:

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

Vos scripts d'extension doivent utiliser la transmission de messages pour communiquer entre un service worker et les autres parties de votre extension. Actuellement, cela implique d'utiliser sendMessage() et d'implémenter chrome.runtime.onMessage dans votre service worker d'extension. À long terme, vous devez remplacer ces appels par postMessage() et le gestionnaire d'événements de messages d'un service worker.

Remplacer les API non compatibles

Les méthodes et propriétés listées ci-dessous doivent être modifiées dans Manifest V3.

Méthode ou propriété Manifest V2 Remplacer par
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 Lorsque les méthodes renvoient des promesses, utilisez 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 (scripts en arrière-plan) Non compatible avec les service workers d'extension. Utilisez plutôt l'événement de document 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