TP6: étude d'une extension Firefox

De $1

Version de 11:42, 26 Avr 2024

cette version.

Revenir à liste des archives.

Voir la version actuelle

Etude de la structure de base d'une extension

Installation

Constituez-vous un environnement de développement en vous créant un profil firefox spécifique (cf TP 5).

Télécharger et décompresser l'extension de test feakeext Pour tester cette extension, copier le fichier nommé "fakeext@isicil.inria.fr" dans le dossier "extensions" de votre profil firefox de développement. Le nom de ce fichier correspond à l'identifiant de l'extension déclaré dans le fichier install.rdf:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:em="http://www.mozilla.org/2004/em-rdf#">
    <RDF:Description about="urn:mozilla:install-manifest">
        <em:aboutURL>chrome://fakeext/content/dialogs/about.xul</em:aboutURL>
        <em:creator>INRIA Sophia</em:creator>
        <em:description/>
        <em:homepageURL>http://isicil.inria.fr</em:homepageURL>
        <em:iconURL>chrome://fakeext/skin/logo/isicil.png</em:iconURL>
        <em:id>fakeext@isicil.inria.fr</em:id>
        <em:name>ISICIL Fake Extension</em:name>
        <em:version>0.1.0</em:version>
        <em:updateURL>https://isicil.inria.fr/updates</em:updateURL>
        <em:type>2</em:type>
        <em:targetApplication>
            <RDF:Description>
                <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
                <em:maxVersion>3.*.*</em:maxVersion>
                <em:minVersion>3.0</em:minVersion>
            </RDF:Description>
        </em:targetApplication>
    </RDF:Description>
</RDF>

Ouvrez ensuite ce fichier qui contient une seule ligne indiquant le chemin du dossier "src" de l'extension. Modifiez ce chemin pour pointer vers le bon dossier (par ex dans mon cas "D:\flimpens\web-pgm\workspace_cours\fakeext\src").

Redémarrez Firefox et allez au menu Outils/Modules complémentaires et vérifiez que l'extension ISICIL Fake Extension a bien été installée.

Etude de la structure

La structure de l'extension est la suivante:

  • src
  •  chrome.manifest
  •  install.rdf
  •  defaults/
  •    preferences/
  •      prefs.js
  •   chrome/
  •     fakeext/
  •       content/
  •         overlay.xul  
  •         dialogs/   
  •           about.xul    
  •       locale/    
  •        en-EN/      
  •          locale.dtd    
  •        fr-FR/      
  •          locale.dtd
  •       skin/    
  •        global/     
  •             logo/      
  •            isicil.png

Obeservez tout d'abord le contenu du fichier install.rdf (cf ci-dessus) qui contient tous les détails liés à l'identification de l'extension.

Regardez maintenant le fichier chrome.manifest:

  1. content fakeext         chrome/fakeext/content/
  2. skin     fakeext global     chrome/fakeext/skin/global/
  3. locale     fakeext fr-FR     chrome/fakeext/locale/fr-FR/

  4. overlay    chrome://browser/content/browser.xul    chrome://fakeext/content/overlay.xul

C'est dans ce fichier que sont déclarées  les correspondances entre les adresses chrome:// et les dossiers de l'arborescences. Par exemple le fichier image isicil.png sera accessible à l'adresse : chrome://fakeext/skin/global/logo/isicil.png. A la ligne 5 est déclaré le fichier d'overlay qui sera utilisé pour inséré des éléments dans le navigateur. Ce mécanisme est spécifique aux extensions, en comparaison avec les applications XULRunner vues la séance précédente. Observez la correspondances des adresses et de l'emplacement du fichier overlay.xul.

Regardez maintenant le fichier overlay.xul:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE overlay SYSTEM "chrome://fakeext/locale/locale.dtd">
  3. <?xml-stylesheet href="chrome://fakeext/skin/skin.css" type="text/css"?>
  4. <overlay xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul">
  5.     <menupopup id="menu_ToolsPopup">
  6.         <menuitem id="fakeext-menuitem" label="&fakeext.title;"/>
  7.     </menupopup>
  8. </overlay>

 La ligne 1 donne l'adresse du fichier où sont déclarées les entités qui sont des variables accessibles avec la syntaxe "&mavariable;" comme par exemple &fakeext.title; utilisée à la ligne 5 pour donner une valeur au label du "menuitem". La ligne 10 montre comment  est inséré un élément dans le navigateur. En utilisant le DOM inspector, retrouvez dans le dom du navigateur l'élément ayant pour id "menu_ToolsPopup".

Exercice: Ajouter une interaction ouvrant la fenêtre de dialogue:

  1. retrouvez l'adresse chrome de la boite de dialogue about.xul
  2. ajoutez l'attribut "oncommand" au menuitem de l'extension. Cet attribut prend en valeur un appel à une fonction javascript. Déclarez une fonction qui ouvre la boîte de dialogue about.xul en vous aidant de la référence de la fonction window.openDialog (ref) (ne spécifiez que l'url et le nom de la boite de dialogue, la variable "features" peut être égale à "").

Exercice: Ajoutez un bouton à la fenêtre de dialogue qui ouvre lune page dans un nouvel onglet du navigateur.

  1.  ajoutez un boutton à la suite des éléments "description" situés dans la boite de dialogue en vous aidant de la référence de l'élément "button"
  2. ajoutez une image à ce bouton à l'aide de len récup
  3. ajoutez un attribut "value" auquel vous donnerez la valeur de l'url de la page à ouvrir (par exemple "http://isicil.inria.fr").
  4. l'attribut "oncommand" permet d'exécuter une fonction lorsque le bouton est cliqué. DAns la valeur de cet attribut, déclarez l'appel à une fonction qui prend en paramètre la valeur de l'attribut "value" (hint: regardez les référence de getAttribute et notez que l'élément en question est l'élément courant)
  5. Déclarez la fonction appelée. Cette fonction prend en paramètre une URL et charge dans un nouvel onglet cet URL. Aidez vous de cette référence vous expliquant comment récupérez un élément "gBrowser" qui correspond au navigateur principal de firefox. Ensuite utilisez la méthode loadOneTab de cet élément (ref).

 

 Etude d'une extension complète

L'extension "boomtag" est un prototype d'extension un peu plus complète et faisant appel à des web services développés dans le cadre du premier cours sur les web services REST.

Déploiement et test de l'extension

Téléchargez et décompressez l'archive boomtag. Cette extension consomme des webservices du server de bookmarks étudiés dans le séance 1. Récupérer l'archive correspondante ou utilisez votre version améliorée ! Le web service qui est appelé est le suivant: http://localhost:9998/bookmark/all. Assurez vous que ce webservice fonctionne avant d'installez l'extension.

Pour l'installation et le test, procédez comme pour fakeext: 

  1. copier le fichier boomtag@sophia.inria.fr dans le dossier extensions de votre profil
  2. modifier le chemin pour qu'il pointe vers le dossier /path/to/Boomtag/srcExtension
  3. relancez Firefox

Cette extension se compose d'une sidebar qui est ouverte par défaut au lancement et qui liste les bookmarks donnés par l'appel au web service. Vérifiez que tous les bookmarks sont bien listés.

Cette extension permet aussi d'enregistrer des bookmarks. Pour l'utiliser faites CTRL+SHIFT+D. Une fenetre apparait contenant 3 champs dont certains sont déjà complétés. Le web service pour l'enregistrement des bookmarks nécessite d'être identifié au préalable via le formulaire à l'adresse http://localhost:9998/.

L'objectif maintenant est d'enrichir ce squelette d'extension avec des fonctionnalités de tagging, mais aussi (selon votre inspiration) avec des fonctions gérant l'identification, la recherche des bookmarks par tags, etc.

Etude des spécificités de boomtag

Nous allons maintenant regarder plus en détail le code source de cette extension.

overlay.xul

Regardez l'entête de ce fichier:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE overlay SYSTEM "chrome://boomtag/locale/locale.dtd">
  3. <?xml-stylesheet href="chrome://boomtag/skin/skin.css" type="text/css"?>
  4. <?xul-overlay href="chrome://boomtag/content/overlays/bmtree/bmtree.xul"?>
  5. <overlay xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul">
  6.     <script type="text/javascript" src="chrome://boomtag/content/scripts/boomtag.js"/>

Observez ligne 3 la déclaration du fichier d'overlay bmtree.xul où sera écrit le code XUL de la sidebar qui s'intègre directement dans le navigateur, par contraste avec les autre fenêtres de dialogue. Voyez aussi l'externalisation des scripts ligne 6.

 Autre nouveauté la possibilité d'ajouter des menus contextuels grace à l'élément popup:

<popup id="contentAreaContextMenu">
        <menuitem id="boomtag-contextmenu" label="&toolsmenuitem.title;" insertafter="context-stop" command="cmd_showPanel"/>
    </popup>

L'id de l'élément dans lequel s'insère ce code XUL (contentAreaContextMenu) est un attribut du tabbrowser "content", un élément fils du browser. Utilisez le DOm inspector pour retrouver ces éléments du DOM du navigateur.

Les commandset permettent de déclarer des commandes qui sont ensuite reliés à des appels de fonction javascript contenu dans le fichier inclus en entête. Regardez la commande "showPanel":

<commandset id="boomtag-commandset">
   <command id="cmd_closePanel" oncommand="boomtag.closePanel(event);"/>
   <command id="cmd_showPanel" oncommand="boomtag.showPanel(event);"/>
   <command id="cmd_showBMEditor" oncommand="boomtag.showBMEditor(event);"/>
</commandset>

Ces commandes peuvent être ensuite appelés par d'autres éléments XUL comme les raccourcis claviers, les "keyset". Ici CTRL+SHIFT+F pour appeler la commande showPanel (ainsi que l'autre raccourci évoqué plus haut pour l'éditeur de bookmarks):

<keyset id="boomtag-keyset">
   <key id="search-key" modifiers="shift control" key="F" command="cmd_showPanel"/>
   <key id="bmdialog-key" modifiers="shift control" key="D" command="cmd_showBMEditor"/>
</keyset>

Ces éléments sont insérés dans un élément "window" main-window. Utilisez le DOM inspector à l'adresse suivante pour vous répérer : chrome://browser/content/browser.xul

Enfin la sidebar est insérée dans l'élément "browser" (id) de type "hbox":

  1. <hbox id="browser">
  2.   <vbox id="boomtag-sidepanel" insertbefore="sidebar-box">
  3.     <sidebarheader align="center">
  4.        <label value="Boomtag" persist="value" flex="1" crop="end" control="sidebar"/>
  5.        <image id="sidebar-throbber"/>
  6.        <toolbarbutton class="tabs-closebutton" tooltiptext="Fermer le panneau latéral" command="cmd_closePanel"/>
  7.      </sidebarheader>
  8.      <hbox align="center">
  9.          <description value="Rechercher"/>
  10.          <textbox flex="1" type="search" class="compact" id="boomtag-searchbox"/>
  11.      </hbox>
  12.      <vbox id="bmtree-container" flex="1" class="panel-frame"/>
  13.   </vbox>
  14.   <splitter id="boomtag-splitter" insertbefore="sidebar-box" collapse="before" persist="state"/>
  15. </hbox>

L1-2 : répérer les éléments du DOM concernés par les insertions (id="browser" et insertbefore="sidebar-box").Vient ensuite l'entête de la sidebar "sidebarheader" (l3-7): n'hésitez pas à avoir recours aux références sur le site XUL pour mieux comprendre les différents attributs des éléments. Voyez l'emploi d'un commandset pour fermer la sidebar (cmd_closePanel).

L8-11 : insertion de la barre de recherche qui pour l'instant n'a pas de fonctions associées. A la ligne 12 est déclarée le conteneur de la liste des bookmarks affichés id="bmtree-container". Cette ID correspond à ce qui est décrit dans le fichier bmtree.xul (dans content\overlays\bmtree) que nous allons maintenant étudier.

bmtree.xul : les templates XML

Remarquez dans l'entête la ligne:

<overlay xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul">

qui permet d'associer ce code source à un overlay déclaré dans le fichier overlay.xul. Autre détail important, ligne 6:

<vbox id="bmtree-container" flex="1" class="panel-frame">

Attention de bien respecter l'id déclarée dans le fichier overlay.xul (id=bmtree-container).

Template XML:

Assurez d'avoir bien compris les template XML vu au TP précédents. Le principe est ici le même, mais appliqué sur un élément de type "tree" (cf ref):

<tree id="bmtree" seltype="single"
    hidecolumnpicker="false" class="tree" datasources="&datasource.bm.all;"
    ref="*" querytype="xml" flex="1" ondblclick="bmtree.loadData(event, this);">

Les attributs spécifiques au mécanisme de template sont le "datasource" qui fait appel ici à une entitée déclarée dans locale.dtd, "ref", et "querytype". NOtez aussi l'interaction dynamique lors d'un doubleclick. Regardez le code correspondant dans le fichier bmtree.js et la méthode loadData. Les propriétés et méthodes spécifiques à l'élément tree sont décrit dans la ref, notamment tree.view.getCellText, etc. Vous retrouverez aussi la fonction loadOneTab associé à l'élément gBrowser qui est ici accesible directement sans passer par window.opener.gBrowser.

Le principe de requête et de "remplissage" du tableau est le même qu'au TP précédent avec la requête XPath "coupée" en 2. Chargez d'abord dans un onglet à part le résultat de  requête correspondant au datasource déclaré (http://localhost:9998/bookmark/all) afin de mieux comprende la requête XPath.

<template>
        <query expr="bookmark">
            <assign var="?id" expr="id" />
            <assign var="?label" expr="title" />

 On récupére tous les éléments "bookmark" et pour chacun de ces éléments, on "map" le noeud id (expr="id") avec la variable ?id (var="?id"), et ainsi de suite pour les autre noeuds. Ces variables sont ensuites réutilisées pour peupler le "tree" dans la partie "action" du template (ignorez la balise "rule" pour l'instant):

<rule>
    <action>
       <treechildren>
         <treeitem container="false" uri="?">
            <treerow>
              <treecell label="?label" />
              <treecell label="?url"/>
              <treecell label="?id" />

Notez aussi l'attribut uri="?" dans la balise "treeitem" qui permet de "raccrocher" le résultat des requêtes. Chaque variable peut ensuite être utilisée comme valeur d'attribut, ici l'attribut "label" de chaque "treecell".

L'éditeur de bookmarks: bmeditor.xul

L'élement XUL est ici de type "window" dans lequel nous allons exploiter la possiilité d'insérer du code html. Pour ceci il faut d'abord déclarer le namespace correspondant:

<window xmlns="http://www.mozilla.org/keymaster/gat...re.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="Boomtag Editor"
style="padding:0" minwidth="600px" minheight="300px"
onload="bmeditor.init();">

Regardez maintenant le code du formulaire html. La méthode invoqué (attribut "action") correspond au web service de création de bookmark "http://localhost:9998/bookmark/create":

<html:form method="post" enctype="application/x-www-form-urlencoded" action="http://localhost:9998/bookmark/create">

Cette fenêtre est appelée par la combinaison CTRL+SHIFT+D depuis un onglet du navigateur. La méthode bmeditor.init() déclarée dans le fichier bmeditor.js permet de récupérer des éléments de la page HTML chargé dans l'onglet:

var bmeditor={
    init:function(){
        $("bm_title").value = window.opener.gBrowser.contentDocument.title;
        $("bm_url").value = window.opener.gBrowser.contentDocument.URL;
        $("bm_description").value = window.opener.gBrowser.contentWindow.getSelection();   
    },

Notez la correspondance des ids des éléments du formulaire et les propriétes et méthodes de l'élément gBrowser utilisées pour peupler ces élements du formulaire. NOtez qu'ici encore, il faut passer par window.opener afin d'accéder au "gBrowser" depuis une fenêtre de dialogue.

A vous de jouer !

Vous pouvez maintenant enrichir cette extension :

  • en ajoutant la possibilité de tagguer les bookmarks en ajoutant une ligne au formulaire et en créant un web service correspondant dans le server de bookmarks BMServ.
  • en ajoutant des fonctionalités de recherche des bookmarks par tags dans la sidebar. Notez que l'attribut "datasources" des templates peut être modifié dynamiquement via javascript ce qui a pour effet de regénérer automatiquement les données chargées dans le template. ceci peut permettre par exemple de récupérer les bookmarks liés à un tag rentré dans la barre de recherche, etc.
  • en ajoutant une fonction d'authentification qui demande à l'utilisateur de s'identifier avant de sauver un bookmark
  • etc.