Modules

WebExtensions intégrées

Pour intégrer une WebExtension, vous aurez besoin de Firefox 51 ou plus. Pour intégrer une WebExtension dans le SDK, vous aurez également besoin de jpm 1.2.0.

A partir de Firefox 51, vous pouvez intégrer une WebExtension dans une extension bootstrapped classique ou dans une extension dans le SDK des extensions.

Les fichiers de WebExtension intégrés sont packagés dans les modules complémentaires existant. La WebExtension intégrée ne partage pas directement son champ d'application avec l'ajout d'un complément hérité, mais ils peuvent échanger des messages à l'aide des fonctions de messagerie définies dans l'API runtime.

Cela signifie que vous pouvez migrer un héritage des extensions aux WebExtensions une pièce à la fois, et avoir un complément entièrement fonctionnel à chaque étape. En particulier, il vous permet migrer les données stcokées à partir d'un complément hérité sur une WebExtension, en écrivant une extension hybride intermédiaire qui lit les données en utilisant les API existantes (pour exemple, simple-prefs ou le service de préférence) et écrit en utilisant une API de WebExtension (par exemple, storage).

Ensemble avec ce guide, nous avons écrit deux exemples montrant comment utiliser les WebExtensions intégrées pour aider à migrer d'un type complémentaire existant. On montre comment se connecter à partir d'un add-on bootstrap, et l'autre montre comment se connecter à partir du SDK d'extensions.

Incorporation d'une WebExtension

Si l'extension héritée est une extension bootstrap avec un install.rdf, incluez la propriété  "hasEmbeddedWebExtension" dans le RDF, contenant la valeur "true":

<em:hasEmbeddedWebExtension>true</em:hasEmbeddedWebExtension>
Si le complément hérité est une SDK add-on, incluez la clé "hasEmbeddedWebExtension" dans le package.json, définissez sur true:
 
"hasEmbeddedWebExtension": true
La WebExtension elle-même vit dans un dossier de niveau supérieur appelé "webextension" dans l'add-on. Par exemple:
 
my-boostrapped-addon/
    chrome/
    webextension/
        manifest.json
        background.js
        ...
    bootstrap.js
    chrome.manifest
    install.rdf
 
my-sdk-addon/
    index.js
    package.json
    webextension/
        manifest.json
        background.js
        ...

Firefox ne traite pas les WebExtensions intégrées comme une extension indépendante. Pour cette raison, vous ne devez pas spécifier une identification d'extension pour elle. Si vous le faites, il sera simplement ignoré.

Toutefois, lorsque vous avez terminé la migration de l'add-on et supprimé le code d'intégration existant, vous devez inclure une clé d'application pour l'identifiant soit identique à un ID d'extension original. De cette façon, addons.mozilla.org reconnaîtra que WebExtension est une mise à jour de l'extension existante.

Démarré la WebExtension

La WebExtension intégrée doit être explicitement démarré par l'extension d'intégration.

Si l'extension d'intégration est un add-on bootstrap, l'argument de données passé à la fonction de startup() obtiendra une propriété supplémentaire à la webExtension :

// bootstrapped add-on

function startup({webExtension}) {

...

Si l'add-on d'intégration est une extension SDK, il pourra accéder à un objet WebExtension à l'aide du module sdk / webextension :

// SDK add-on

const webExtension = require("sdk/webextension");

Quoi qu'il en soit, cet objet a une seule fonction, startup(), qui renvoie une Promesse. La promesse résolue à un objet avec un seul navigateur de propriétés :  il contient les API runtime que le complément d'intégration peut utiliser pour échanger des messages avec le WebExtension intégré :

Pour exemple:

// bootstrapped add-on

function startup({webExtension}) {
  webExtension.startup().then(api => {
    const {browser} = api;
    browser.runtime.onMessage.addListener(handleMessage);
  });
}
// SDK add-on

const webExtension = require("sdk/webextension");

webExtension.startup().then(api => {
  const {browser} = api;
  browser.runtime.onMessage.addListener(handleMessage);
});

Notez que l'ajout d'un module d'extension intégré ne peut pas démarrer les communications: il peut recevoir (et éventuellement à répondre) des messages ponctuels, en utilisant onMessage, et peut accepter des requêtes de connexion en utilisant onConnect.

La promesse est rejetée si le WebExtension intégré manque un manifeste ou si le manifeste est invalide. Dans ce cas, vous verrez plus de détails dans la boite à outils de la console du navigateur.

Echange des messages

Une fois que la WebExtension intégré est en cours d'exécution, elle peut échanger des messages avec l'add-on hérité en utilisant le sous-ensemble des APIs runtime :

Messagerie sans connexion

Pour envoyer un message unique, la WebExtension peut utiliser runtime.sendMessage(). Vous pouvez omettre l'argument extensionId, car le navigateur considère la WebExtension intégrée comme faisant partie intégrante de l'add-on :

browser.runtime.sendMessage("message-from-webextension").then(reply => {
  if (reply) {
    console.log("response from legacy add-on: " + reply.content);
  }
});

L'add-on d'intégration peut recevoir (et répondre facultativement) ce message en utilisant l'objet runtime.onMessage :

// bootstrapped add-on

function startup({webExtension}) {
  // Start the embedded webextension.
  webExtension.startup().then(api => {
    const {browser} = api;
    browser.runtime.onMessage.addListener((msg, sender, sendReply) => {
      if (msg == "message-from-webextension") {
        sendReply({
          content: "reply from legacy add-on"
        });
      }
    });
  });
}

Messagerie orientée connexion

Pour configurer une connexion plus longue entre la WebExtension et l'extension héritée, la WebExtension peut utiliser runtime.connect().

var port = browser.runtime.connect({name: "connection-to-legacy"});

port.onMessage.addListener(function(message) {
  console.log("Message from legacy add-on: " + message.content);
});

L'extension héritée peut écouter les tentatives de connexion à l'aide de runtime.onConnect, et les deux côtés peuvent alors utiliser runtime.Port pour échanger des messages :

function startup({webExtension}) {
  // Start the embedded webextension.
  webExtension.startup().then(api => {
    const {browser} = api;
    browser.runtime.onConnect.addListener((port) => {
      port.postMessage({
        content: "content from legacy add-on"
      });
    });
  });
}

Migration de données à partir d'extensions existantes

Une utilisation majeure pour les WebExtensions intégrées sont de migrer les données stockées d'une extension.

Les données stockées sont un problème pour les personnes qui essaient de migrer à partir de types d'extension existants, car les extensions existantes ne peuvent pas utiliser les API de stockage WebExtension, alors que les  WebExtensions ne peuvent pas utiliser les API de stockage existantes. Par exemple, si une extension du SDK utilise l'API simple-prefs  pour stocker les préférences, la version WebExtension ne pourra pas accéder à ces données.

Avec les WebExtensions intégrées, vous pouvez migrer des données en créant une version intermédiaire de l'extension qui intègre une WebExtension. Cette version intermédiaire lit les données stockées à l'aide des API existantes et écrit les données à l'aide des API des WebExtensions.

  • Dans la version initiale, un add-on basé sur le SDK lit et écrit les préférences de l'add-on utilisé par l'API simple-prefs.
  • Dans la version intermédiaire, le complément SDK démarre la WebExtension intégrée. La WebExtension demande ensuite le complément SDK pour récupérer les données stockées à partir de  simples prefs. La WebExtension stocke ensuite les données à l'aide de l'API storage.
  • Dans la version finale, l'extension est juste une WebExtension et utilise seulement  que l'API de stockage.

Nous avons fourni deux exemples illustrant ce modèle : "embedded-webextension-bootstrapped" montre la migration à partir d'un add-on bootstrap, tandis que "embedded-webextension-sdk" montre la migration à partir du SDK de l'extension.

Préférences

Une extension qui contient une WebExtension intégré peut définir des préférences dans l'extension d'héritage (en utilisant, par exemple, simple-prefs ou le service des préférences) ou dans la WebExtension intégrée (en utilisant options_ui).

Si les deux parties définissent les préférences, que les préférences de la WebExtension intégrée annuleront les anciennes.

Si la diffusion de la WebExtension intégrée définit les préférences, elles ne seront initialisées qu'après la WebExtension intégré a commencée. Jusque-là, le bouton "Préférences" dans "about:addons" ne sera pas affiché pour l'add-on, et le navigateur enregistrera une erreur dans la console du navigateur lorsque "about:addons" is ouvert.

Pour cette raison, c'est important que l'extension d'intégration démarre immédiatement le démarrage WebExtension intégré lors du démarrage. Pour une extension bootstrap, cela signifie que vous devez appeler webExtension.startup() dans le bootstrap de démarrage. Pour une extension SDK supplémentaire, cela signifie que vous devez appeler  webExtension.startup() dans le point d'entrée de l'add-on (par défaut, index.js).

Si la page "about:addons" est déjà ouverte dans un onglet lorsque le WebExtension intégré est démarré, le bouton Préférences ne sera visible qu'après la prochaine recharge de la page "about:addons".

Limitations

Debogage

Si vous avez un add-on hérité qui intègre une WebExtension, vous ne pouvez pas utiliser le nouveau débogueur add-on pour le déboguer. Vous devrez utiliser l'ancien flux de travail de débogage, basé sur la boite d'outils du navigateur.

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : hellosct1
 Dernière mise à jour par : hellosct1,