Les Web Extensions: retour d’expérience sur le développement d’une extension de navigateur

Moussa Ndour
4 min readNov 4, 2017

--

Avant l’avènement des Web Extensions, chaque navigateur web disposait de son propre SDK pour pouvoir développer des extensions de navigateur. On pouvait par exemple développer des Addons pour Firefox en utilisant principalement le “SDK Add-on” de mozilla. Cependant cette méthode disposait de plusieurs inconvénients notamment le fait que la plupart des extensions ne fonctionner plus lors d’une nouvelle version du navigateur. Les développeurs étaient obligés de mettre à jour leur code lors de chaque mise à jour du navigateur.

C’est là que les WebExtensions viennent à la rescousse.

Qu’est ce que les WebExtension?

Si vous visiter la page MDN destiné aux WebExtension elles sont definis comme suit:

Les WebExtensions sont un système cross-browser (multi-navigateurs) pour développer des extensions pour le navigateur. Pour une meilleure compatibilité, l’API est compatible avec l’ extension API supporté par Google Chrome et Opera. Les extensions écrites pour ces navigations vont, dans la plupart des cas, s’éxecuter dans Firefox ou Microsoft Edge avec seulement quelques changements.

Donc théoriquement une extensions développée avec ce système devrait pouvoir s’exécuter dans les principaux navigateurs web sans (ou presque) effectuer le moindre changement du code.

Et en pratique?

Après avoir lu la brève définition des WebExtensions dans le doc de mozilla, je me suis donné l’objectif de developper une extension avec ce système bien que n’ayons à cette époque-là 0 expérience en matière de developpemnt d’extension de navigateur. Après quelques heures de lecture des différences partit de cette éco-systeme je me sentais enfin pret à démarrer l’aventure. C’est ainsi que j’ai commencé le développement de ma première extension:

Convert Webpage to PDF

Chaque extension doit contenir un fichier appelé “manifest.json”. Ce manifest contient des références vers plusieurs types de fichiers :

{
"background": {
"scripts": [
"background.js"
]
},
"content_scripts": [
{
"matches": [
"*://*/*"
],
"js": [
"lib/js/jquery.min.js",
"lib/js/download.min.js",
"async-await.js",
"misc.js",
"controller.js"
],
"run_at": "document_end"
}
],
"page_action": {
"default_icon": {
"32": "ico/addon-ico-32.png",
"64": "ico/addon-ico-64.png"
},
"default_title":"__MSG_pageActionPopupTitle__",
"default_popup": "html/option.html"
},
"commands": {
"convert-to-pdf": {
"suggested_key": {
"default": "Ctrl+Shift+P"
},
"description": "__MSG_convertToPdfCommand__"
}
},
"description": "__MSG_extensionDescription__",
"icons": {
"32": "ico/addon-ico-32.png",
"64": "ico/addon-ico-64.png"
},
"web_accessible_resources": [
"ico/addon-ico-32.png",
"ico/addon-ico-64.png",
"ico/success.png",
"ico/error.png",
"ico/loading.png",
"ico/logo.png"
],
"homepage_url": "https://sidson-aidson-pdf-server.herokuapp.com/",
"author": "Moussa Ndour",
"developer": {
"name": "Moussa Ndour",
"url": "https://sidson-aidson-pdf-server.herokuapp.com/"
},
"permissions": [
"*://*/*",
"webRequest",
"tabs",
"activeTab",
"notifications",
"downloads",
"downloads.open"
],
"default_locale":"en",
"manifest_version": 2,
"name": "__MSG_extensionName__",
"version": "1.0.5"
}

Voyons un peu le rôle de chaque sections:

Background: c’est à ce niveau que nous énumérons la liste des scripts que le navigateur doit excecuter en background lors du bootage de l’extension qui a lieu en même temps que l’ouverture du navigeteur. Les scripts en background n’ont pas accèss au UI des pages. Cependant elles peuvent communiquer avec les autres composants de l’extension via des signaux.

"background": {
"scripts": [
"background.js"
]
}

Content_Scripts: tous les scripts listés dans cette section vont être injectés dans chaque page qui est ouvert dans le navigateur et dont le pattern de l’URL de la page correspond au moins à un élément du tableau des patterns donné. On peut aussi choisir le moment où le navigateur va injecter les scripts dans la page grâce a la clé “run at”.

"content_scripts": [
{
// tableau des pattern
// tous les shemat(http, https), tous les domaines, tous les chemons
"matches": [
"*://*/*"
],
"js": [
"lib/js/jquery.min.js",
"lib/js/download.min.js",
"async-await.js",
"misc.js",
"controller.js"
],
"run_at": "document_end"
}
],

Et pour finir la liste des autorisations requise par l’en tensions.

"permissions": [
"*://*/*",
"webRequest",
"tabs",
"activeTab",
"notifications",
"downloads",
"downloads.open"
],

Nous retiendrons qu’une extensions est composer de :

Pour plus d’information sur ce fichier vous pouvez faire un tour sur la documentation de Mozilla.

Et pour le reste?

Pour le reste je vous laisse découvrir par vous-même dans le code source de l’extension disponible ici.

Voici un extrait de code:

browser.runtime.onMessage.addListener((message, sender) => {
if (message && message.type === 'generatePDF')
{
if(isRequesting)
{
return;
}
isRequesting = true;
var option = message.option;
option.source = window.location.href;
option.baseUrl = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port: ''); generatePDF(apiUrl + ressourcePath, option)
.then((binary) => {
isRequesting = false;
generateDone({
error:false,
downloadStartDate: (new Date()).toISOString(),
downloadedFileName:option.name,
downloadUrl: apiUrl + ressourcePath
}, browser);
download( new Blob([binary]), option.name, "application/pdf"); })
.catch((e) => {
console.log(e)
isRequesting = false;
generateDone({
error:true
}, browser);
})
}
else if (message && message.type === 'getRequestingStatus')
{
browser.runtime.sendMessage({
type:"sendRequestingStatus",
isRequesting:isRequesting
});
}
});

Et pour le déploiement ?

Pour le déploiement il suffit juste de zipper tout le code et de l’uploader dans le store de chaque navigateur. Pour cette extension elle est disponible pour Firefox et Opéra. Elle fonctionnement également sous chrome, mais hélas n’est pas disponible dans le chrome store(c’est payant), et pour Microsoft Edge elle devrait aussi fonctionner correctement mais je n’ai pas pu le tester car je ne dispose pas d’un PC Windows.

Voilà on n’est arriver à la fin de cet article.

--

--