begin process at 2010 03 20 19:46:54
  Trouver un code source :
 
dans
 
Accueil > 

Tutoriels

 > 

Tutoriaux

 > CRÉATION D'UNE EXTENSION POUR MOZILLA FIREFOX

CRÉATION D'UNE EXTENSION POUR MOZILLA FIREFOX


 Information sur le tutoriel

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

 Description

Ce tutorial explique comment créer une extension pour Mozilla Firefox, avec comme exemple la CSBar pour firefox.

Tutorial

COMMENT CREER UNE EXTENSION POUR MOZILLA FIREFOX


Pour cela, je vais d'abord expliquer comment fonctionne Mozilla Firefox.

1: Mozilla Firefox et chrome
    Ouvrez Mozilla Firefox, et tapez dans la barre d'adresse "chrome://browser/content/browser.xul". Cette URL est particulière : elle commence par "chrome://" à la place de "http://". Pour Mozilla Firefox, cela a une signification : il va regarder les packages chromes enregistrés, et regarder si un correspond : içi, le package dans l'URL est "browser". FF va trouver un package ayant ce nom là : c'est en fait le package du navigateur. Il va y ouvrir le fichier "content/browser.xul". Ce fichier est une interface XUL : c'est un fichier XML décrivant une interface utilisateur : là, c'est l'interface du navigateur,  donc vous devriez voir votre navigateur en double.
    Les extensions utilisent beaucoup les packages chrome : cela permet avec une URL, par exemple "chrome://package/skin/image.png" d'accèder à une image livrée avec l'extension sans se soucier du chemin d'accès et de l'emplacement sur le disque dur.

2: XML, XUL et RDF
    Pour créer une extension avec Mozilla Firefox, il faut connaître deux langages de programmation : XML et JavaScript. Le XML servira à la description de données(RDF) et d'interfaces(XUL), alors que le JavaScript mettra en relation des événements avec des actions. Le RDF n'est pas vraiment utile dans les extensions, uniquement pour un fichier qui servira à la description de l'extension, le XUL sera très utilisé, et le JavaScript doit-être assez bien connu. Pour apprendre le XUL, vous pouvez suivre ce tutorial qui vous en apprendra beaucoup deja, ou aller sur des sites internet. Je vous conseille XULPlanet(en anglais) ou XULfr(en francais).


CREATION DE L'EXTENSION :

    Tout d'abord, choisissez ou créez un dossier vide où vous mettrez tout ce qui sera utile à l'extension. Créez cette arborescence dans le dossier (qui pour moi s'appelle Firefox) :

arborescence.jpg

    Explication des répertoires :
  • On mettra dans le dossier racine (Firefox pour moi, peut-etre autre chose pour vous) les fichiers de description de l'extension
  • On ne mettra rien dans le dossier chrome
  • On mettra dans le dossier "content" les fichiers javascripts et interfaces XUL (on peut y mettre aussi des dossiers comme sur l'arborescence).        Dans notre extension, on mettra uniquement les fichiers concernant la barre.
  • Dans le dossier "preferences", on mettra les fichiers XUL et JS concernant la fenêtre de préférences.
  • Dans le dossier "prefpages", on mettra les fichiers XUL et JS des pages de préférences.
  • Le dossier "icons" et le dossier "default" sont inutilisés.
  • Le dossier "locale" et toute son arborescence seront inutilisés.
  • Le dossier skin contiendra les images et les feuilles de style CSS pour embellir la barre.
    Première chose à faire, si ce n'est pas encore fait : téléchargez la barre d'outils CSBar pour firefox disponible sur "http://blogue.delroth.info/chrome.xpi". Installez là en faisant "Ouvrir avec..." et ouvrez là avec Firefox. Un compte à rebours devrait s'afficher. Quand il sera fini, cliquez sur le bouton "Installer" pour installer l'extension. Redémarrez ensuite Mozilla Firefox et vous aurez la CSBar devant les yeux pour l'étudier.

  Ensuite, nous allons créer le premier fichier de notre extension : le fichier "chrome.manifest". Créez ce fichier dans le répertoire racine de l'extension. Ouvrez le avec un éditeur de texte quelconque, comme Wordpad ou Notepad. Inscrivez-y ces lignes :

content cs chrome/content/
skin cs cs2006 chrome/skin/
locale cs fr-FR chrome/locale/fr-FR/csbar/
overlay chrome://browser/content/browser.xul chrome://cs/content/content.xul

Explications :
    Le fichier chrome.manifest sert en fait à enregistrer les packages chromes utilisés par l'extension. On va içi enregistrer 1 package : cs. Dans ce package, on crée trois dossiers spéciaux : content, skin et locale. Cette création est effectuée par les trois premières lignes. On indique aussi que le dossier chrome "content" pointe vers "chrome/content/", ce qui est le chemin d'accès au répertoire "content", le dossier "skin" vers "chrome/skin/" et le dossier "locale" vers "chrome/locale/fr-FR/csbar" pour les français (fr-FR). On indique aussi que le skin s'appelle cs2006, mais cela n'a aucune importance. La dernière ligne va dire à chrome "d'injecter" le fichier chrome://cs/content/content.xul dans chrome://browser/content/browser.xul. Cela va en fait injecter notre barre d'outils dans le navigateur (browser.xul").

Le prochain fichier à créer est le install.rdf. Ce fichier va contenir toutes les informations sur l'extension. Il doit être créé dans le répertoire racine de l'extension. Mettez-y ce code :

________________________________________________________

<?xml version="1.0"?>
<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
         xmlns:NC="http://home.netscape.com/NC-rdf#"
         xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <RDF:Description RDF:about="urn:mozilla:install-manifest"
                   em:id="xxxxx@xxxxx.xxxx"
                   em:name="CodeS-Sources toolbar"
                   em:version="1.2"
                   em:creator="Nightlord666 (http://www.cppfrance.com/auteur/NIGHTLORD666/535688.aspx)"
                   em:description="Barre de recherche sur les sites Codes-Sources"
                   em:homepageURL="http://www.codes-sources.com/">
    <em:targetApplication RDF:resource="rdf:#$FI.RD3"/>
    <em:file RDF:resource="urn:mozilla:extension:file:"/>
  </RDF:Description>
  <RDF:Description RDF:about="urn:mozilla:extension:file:"
                   em:locale="locale/fr/" />
  <RDF:Description RDF:about="rdf:#$FI.RD3"
                   em:id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
                   em:minVersion="1.0+"
                   em:maxVersion="1.5.0.*" />
</RDF:RDF>

________________________________________________________

Explications :
    Ce fichier "install.rdf" est en fait un document XML. Il va décrire notre extension. Tout ce que vous pouvez changer ce trouve dans la première balise "RDF:Description". On y trouve l'ID de l'extension (un nom unique), son nom, sa version, son créateur, sa description et la page d'accueil du site de l'auteur. Le reste sert à décrire l'application cible, avec son GUID, la version minimale et maximale.

Ensuite, nous allons prendre les images sur le site. Pour vous faciliter la tache (comme je sais que vous êtes fainéants :D), j'ai tout mis dans un RAR à télécharger sur http://blogue.delroth.info/images_csbar.rar
Décompressez ces images dans le dossier skin de l'extension. Ensuite, nous allons créer la CSS de notre barre d'outils.

________________________________________________________

/* Debut de la CSS */

/* Le namespace de la CSS */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");

/* La boite de dialogue de préférence */
#cs-prefs-dialog {
  width: 600px;
  height: 400px;
}

/* Les menuitem de la première liste */
#mi-asp {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/asp.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-vb {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/visualbasic.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-cpp {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/cplusplus.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-cf {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/coldfusion.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-js {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/javascript.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-php {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/php.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-delphi {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/delphi.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-flash {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/flash.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-java {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/java.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-graph {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/graphisme.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-irc {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/irc.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-asm {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/assembleur.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-csh {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/csharp.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-pda {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/pda.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-sql {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/sql.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-foxpro {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/foxpro.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-python {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/python.png");
  background-position: left;
  background-repeat: no-repeat;
}

/* Les menuitem de la deuxieme liste */
#mi-asp1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/asp.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-vb1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/visualbasic.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-cpp1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/cplusplus.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-cf1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/coldfusion.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-js1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/javascript.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-php1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/php.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-delphi1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/delphi.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-flash1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/flash.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-java1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/java.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-graph1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/graphisme.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-irc1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/irc.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-asm1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/assembleur.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-csh1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/csharp.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-pda1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/pda.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-sql1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/sql.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-foxpro1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/foxpro.png");
  background-position: left;
  background-repeat: no-repeat;
}

#mi-python1 {
  padding-left: 18px;
  background-image: url("chrome://cs/skin/python.png");
  background-position: left;
  background-repeat: no-repeat;
}

/* Le champ de texte */
#cs-txt-texte {
  -moz-appearance: none;
  font: icon;
  width: 170px;
  height: 22px;
  border: none !important;
  overflow: auto;
  padding: 4px 12px 0 33px;
  margin-right: 5px;
  margin-left: 5px;
  background: transparent url("chrome://cs/skin/searchicon.png") top left no-repeat;
}

/* Le bouton "rechercher" */
#cs-btn-rechercher {
  -moz-appearance: none;
  font: icon;
  font-weight: bold;
  width: 150px;
  height: 22px;
  border: none !important;
  overflow: auto;
  margin-right: 5px;
  margin-left: 5px;
  text-align: center;
  background: transparent url("chrome://cs/skin/button.png") top left no-repeat;
}

/* Le bouton "rechercher" survolé par la souris */
#cs-btn-rechercher:hover {
  -moz-appearance: none;
  font: icon;
  font-weight: bold;
  width: 150px;
  height: 22px;
  border: none !important;
  overflow: auto;
  margin-right: 5px;
  margin-left: 5px;
  text-align: center;
  background: transparent url("chrome://cs/skin/buttonhover.png") top left no-repeat;
}

/* La liste de selection de site */
#cs-site-selection {
  background-color: #E0DFE3;
}

/* Fin de la CSS */

________________________________________________________

Pour ceux qui sont habitués au CSS, ça ne doit poser aucun problème, comme pour ceux qui ont quelques connaissances en anglais... Pour les autres, regardez le tutorial de CSS du Site du Zero. Le seul attribut non standard est "-moz-appearance". Il définit si l'objet auquel on applique un style a en plus le style standard du navigateur.

Nous allons maintenant construire la toolbar : pour ça, il faut utiliser XUL. XUL est un langage XML utilisé pour réaliser des interfaces. XUL est en fait le langage natif du navigateur Firefox : même le navigateur est réalisé en XUL ! Regardez dans l'introduction pour les liens pour apprendre le XUL. Ce fichier est appellé "content.xul" et est à sauvegarder dans le dossier "content"

La barre d'outils :

________________________________________________________

<?xml version='1.0'?>

<!-- Les stylesheets appliquées à la barre : celle du navigateur et la notre, pointée par son adresse chrome. -->
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://cs/skin/skin.css" type="text/css"?>

<!-- L'overlay de la toolbar. Une overlay est en fait une sorte de fichier à inclure. Il va contenir un menu et une toolbar, qui seront injectés dans le navigateur gràçe à notre fameux fichier "chrome.manifest" -->
<overlay id="cs-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <!-- Les scripts javascript utilisés par l'extension -->
  <script type="application/x-javascript" src="chrome://cs/content/bar.js"/>
  <script type="application/x-javascript" src="chrome://cs/content/search.js"/>
  <!-- La commande du menu "Affichage / Barre d'outils" -->
  <broadcasterset id="navBroadcasters">
    <broadcaster id="cs-view-toolbar-command" checked="true" onCommand="csBar_Toggle()"/>
  </broadcasterset>

  <!-- Ce menupopup est un menu. Il porte la même ID que celui du navigateur : view-toolbars-popup, les deux menus vont donc fusionner et on aura notre menuitem "CodeS-Sources" dans le menu "Affichage/Barre d'outils" -->
  <menupopup id="view-toolbars-popup">
    <!-- Le menuitem est relié à la commande par observes -->
    <menuitem label="CodeS-Sources" class="menuitem-iconic" type="checkbox" observes="cs-view-toolbar-command"/>
  </menupopup>
 
  <!-- Le menu qui va fusionner avec le menu "outils" -->
  <menupopup id="menu_ToolsPopup">
    <!-- Graçe à insertafter, il ne sera pas placé au début du menu, mais après le séparateur -->
    <menu label="CodeS-Sources toolbar" id="cs-menu" insertafter="devToolsSeparator">
      <menupopup>
        <menuitem label="Préférences..." id="cs-prefs-menu" oncommand="cs_launchPrefs()"/>
        <menuitem label="Lancer la recherche" id="cs-launch-menu" oncommand="Search(document.getElementById('cs-txt-texte').value, document.getElementById('cs-search-engines').selectedItem, document.getElementById('cs-search-method').selectedItem.id)"/>
      </menupopup>
    </menu>
  </menupopup>

  <!-- Une toolbox est, comme son nom l'indique, une "boite à outils". Elle contient des toolbars. Cette toolbox à la même ID que celle du navigateur, elles vont donc fusionner et rajouter une barre au navigateur. -->
  <toolbox id="navigator-toolbox">
   <!-- Notre barre d'outils. Elle à le menu contextuel par défaut (toolbar-context-menu), elle n'est pas masquée par défaut, elle a une taille petite, et elle se souvient (graçe à persist) si elle est cachée ou pas. -->
    <toolbar id="cs-toolbar" collapsed="false" context="toolbar-context-menu" customizable="true"
    grippytooltext="CSBar" hidden="false" iconsize="small" inherits="collapsed,hidden" persist="collapsed,hidden"
    mode="full" toolbarname="CSBar">

      <!-- La textbox qui contient le texte de recherche -->
      <textbox id="cs-txt-texte"/>

      <!-- La liste des sites de recherche -->
      <menulist id="cs-search-engines" width="170px">
        <menupopup>
          <menuitem id="mi-vb" label="VB / VB.NET"/>
          <menuitem id="mi-asp" label="ASP / ASP.NET"/>
          <menuitem id="mi-cf" label="Coldfusion"/>
          <menuitem id="mi-cpp" label="C / C++ / C++.NET"/>
          <menuitem id="mi-php" label="PHP"/>
          <menuitem id="mi-js" label="Javascript / DHTML"/>
          <menuitem id="mi-flash" label="Flash"/>
          <menuitem id="mi-delphi" label="Delphi"/>
          <menuitem id="mi-java" label="Java / J2EE"/>
          <menuitem id="mi-graph" label="Graphisme"/>
          <menuitem id="mi-irc" label="IRC"/>
          <menuitem id="mi-asm" label="Assembleur"/>
          <menuitem id="mi-csh" label="C# / C#.NET"/>
          <menuitem id="mi-pda" label="PDA / PocketPC"/>
          <menuitem id="mi-sql" label="SQL"/>
          <menuitem id="mi-foxpro" label="Foxpro"/>
          <menuitem id="mi-python" label="Python"/>
        </menupopup>
      </menulist>

      <!-- La méthode de recherche -->
      <menulist id="cs-search-method" width="120px">
        <menupopup>
          <menuitem id="source" label="Sources"/>
          <menuitem id="tutorial" label="Tutoriaux"/>
          <menuitem id="forum" label="Forum"/>
          <menuitem id="blog" label="Blogs"/>
          <menuitem id="newsdotnet" label="News .NET"/>
          <menuitem id="boutique" label="Boutiques"/>
          <menuitem id="livre" label="Livres"/>
          <menuitem id="icone" label="Icones"/>
          <menuitem id="rfc" label="RFC"/>
          <menuitem id="video" label="Videos"/>
        </menupopup>
      </menulist>

      <!-- Le bouton de recherche -->
      <toolbarbutton id="cs-btn-rechercher" label="Rechercher" oncommand="Search(document.getElementById('cs-txt-texte').value, document.getElementById('cs-search-engines').selectedItem, document.getElementById('cs-search-method').selectedItem.id)"/>

      <!-- Un élément qui va s'étirer jusqu'au bout -->
      <spacer flex = "1"/>

      <!-- Du texte -->
      <label value="Aller sur :"/>

      <!-- Quand on change la sélection, un événement "oncommand" est envoyé. Dans ce cas là, on change la document.location du cadre "content" qui fait partie du navigateur -->
      <menulist id="cs-search-engines1" width="200px">
        <menupopup>
          <menuitem id="mi-cs1" label="CodeS-Sources" oncommand="content.document.location='http://www.codes-sources.com/'"/>
          <menuitem id="mi-vb1" label="VB / VB.NET" oncommand="content.document.location='http://www.vbfrance.fr/'"/>
          <menuitem id="mi-asp1" label="ASP / ASP.NET" oncommand="content.document.location='http://www.aspfr.com/'"/>
          <menuitem id="mi-cf1" label="Coldfusion" oncommand="content.document.location='http://www.cfmfrance.com/'"/>
          <menuitem id="mi-cpp1" label="C / C++ / C++.NET" oncommand="content.document.location='http://www.cppfrance.com/'"/>
          <menuitem id="mi-php1" label="PHP" oncommand="content.document.location='http://www.phpcs.com/'"/>
          <menuitem id="mi-js1" label="Javascript / DHTML" oncommand="content.document.location='http://www.javascriptfr.com/'"/>
          <menuitem id="mi-delphi1" label="Delphi" oncommand="content.document.location='http://www.delphifr.com/'"/>
          <menuitem id="mi-flash1" label="Flash" oncommand="content.document.location='http://www.flashkod.com/'"/>
          <menuitem id="mi-java1" label="Java / J2EE" oncommand="content.document.location='http://www.javafr.com/'"/>
          <menuitem id="mi-graph1" label="Graphisme" oncommand="content.document.location='http://www.graphfr.com/'"/>
          <menuitem id="mi-irc1" label="IRC" oncommand="content.document.location='http://www.ircfr.com/'"/>
          <menuitem id="mi-asm1" label="Assembleur" oncommand="content.document.location='http://www.asmfr.com/'"/>
          <menuitem id="mi-csh1" label="C# / C#.NET" oncommand="content.document.location='http://www.csharpfr.com/'"/>
          <menuitem id="mi-pda1" label="PDA / PocketPC" oncommand="content.document.location='http://www.pdafr.com/'"/>
          <menuitem id="mi-sql1" label="SQL" oncommand="content.document.location='http://www.sqlfr.com/'"/>
          <menuitem id="mi-foxpro1" label="Foxpro" oncommand="content.document.location='http://www.foxprofr.com/'"/>
          <menuitem id="mi-python1" label="Python" oncommand="content.document.location='http://www.pythonfrance.com/'"/>
        </menupopup>
      </menulist>
    </toolbar>
  </toolbox>
</overlay>
<!-- Fin du document XUL -->

________________________________________________________

Le code est assez bien commenté, je rajouterais au cas où des informations si vous en avez besoin.

Maintenant, créez un fichier "bar.js" dans le dossier "content". Ce fichier javascript contiendra toutes les fonctions javascript servant à la gestion de la barre.

________________________________________________________

//bar.js
//Contient toutes les fonctions de gestion de la barre

//La variable qui servira à manipuler les préférences
var preferences = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);

//Change la barre visible / Cachée
function csBar_Toggle()
{
  var toolbar = document.getElementById("cs-toolbar");

  toolbar.collapsed = !toolbar.collapsed;

  document.persist("cs-toolbar", "collapsed");
}

//Fonction appellée au chargement de la barre
function cs_onToolbarLoad()
{
  var mit = "mi-vb";
  //Si les préférences n'existent pas, cela lance une exception, on met donc dans un bloc try... catch
  try
  {
    //Utilise t-on un moteur par défaut ?
    if(preferences.getBoolPref("cs.usedefault"))
    {
      //On charge l'id du menuitem
      mit = preferences.getCharPref("cs.search.defaultengine");
    }
  }
  catch(e)
  {
    //On crée les préférences si elles n'existent pas
    preferences.setBoolPref("cs.usedefault", false);
    preferences.setCharPref("cs.search.defaultengine", "mi-vb");
  }
  //On selectionne le menuitem par défaut
  document.getElementById("cs-search-engines").selectedItem = document.getElementById(mit);
}

//On ajoute un listener à la fenêtre parente pour le chargement de la barre
window.addEventListener("load", cs_onToolbarLoad, true);

//Charge la fenêtre de préférences
function cs_launchPrefs()
{
  //Lance la fenêtre : observer les paramètres de lancement : chrome
  window.openDialog("chrome://cs/content/preferences/preferences.xul", "cs-prefs-dialog", "centerscreen,chrome,modal");
}
//Fin du fichier

Le code n'est vraiment pas difficile. On passe maintenant à la fonction de recherche. Elle est contenue dans le dossier "content", sous le nom "search.js" :

//Search.js
//Contient la fonction de recherche

//text : le texte à rechercher
//engine: le menuitem du moteur à utiliser
//method: le menuitem de la méthode à utilise
function Search(text, engine, method) {
  text.replace(" ", "+");   //On met des + à la place des espaces
  text.replace("\\", "");    //On enleve les \

  addr = "http://www.";   //Debut de l'adresse
  //On ajoute le nom de domaine
  if(engine == document.getElementById("mi-cpp")) {
    addr += "cppfrance.com/";
  }
  else if(engine == document.getElementById("mi-vb")) {
    addr += "vbfrance.com/";
  }
  else if(engine == document.getElementById("mi-asp")) {
    addr += "aspfr.com/";
  }
  else if(engine == document.getElementById("mi-cf")) {
    addr += "cfmfrance.com/";
  }
  else if(engine == document.getElementById("mi-php")) {
    addr += "phpcs.com/";
  }
  else if(engine == document.getElementById("mi-js")) {
    addr += "javascriptfr.com/";
  }
  else if(engine == document.getElementById("mi-delphi")) {
    addr += "delphifr.com/";
  }
  else if(engine == document.getElementById("mi-flash")) {
    addr += "flashkod.com/";
  }
  else if(engine == document.getElementById("mi-java")) {
    addr += "javafr.com/";
  }
  else if(engine == document.getElementById("mi-graph")) {
    addr += "graphfr.com/";
  }
  else if(engine == document.getElementById("mi-irc")) {
    addr += "ircfr.com/";
  }
  else if(engine == document.getElementById("mi-asm")) {
    addr += "asmfr.com/";
  }
  else if(engine == document.getElementById("mi-csh")) {
    addr += "csharpfr.com/";
  }
  else if(engine == document.getElementById("mi-sql")) {
    addr += "sqlfr.com/";
  }
  else if(engine == document.getElementById("mi-foxpro")) {
    addr += "foxprofr.com/";
  }
  else if(engine == document.getElementById("mi-python")) {
    addr += "pythonfrance.com/";
  }
  else
  {
    alert("Erreur : ID de moteur de recherche inconnue...");
  }

  //On rajoute le texte de methode
  if(method != "boutique")
    addr += "recherche.aspx?r=";
  else
    addr += "boutique.aspx?cn=";

  addr += text;   //On ajoute le texte

  if(method != "boutique")
  {
    addr += "&tr=";
    addr += method;   //On ajoute la méthode de recherche
  }

  //On change le document et on lui donne le focus
  content.document.location = addr;
  content.focus();
}

//Fin du fichier

________________________________________________________

Avec ces fichiers, la barre est au point. Nous allons maintenant ajouter le système de préférences. Ajouter dans "content/preferences" le fichier "preferences.xul" :

________________________________________________________

<?xml version='1.0'?>

<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://cs/skin/skin.css" type="text/css"?>

<!-- La boite de dialogue -->
<dialog buttons="accept"
  id="cs-prefs-dialog"
  title="Preferences de la CSBar"
  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

  <!-- La listbox qui contiendra les pages de préférences -->
  <hbox flex="1">
    <listbox id="cs-prefs-page-list" onselect="cs_changePage(this)">
      <listitem label="General" selected="true" value="chrome://cs/content/prefpages/general.xul"/>
    </listbox>

    <!-- Une iframe qui contiendra la page de préférence XUL -->
    <vbox flex="1">
      <iframe flex="1" id="cs-prefs-page" src="chrome://cs/content/prefpages/general.xul"/>
    </vbox>
  </hbox>
</dialog>
<!-- Fin du fichier -->

________________________________________________________

On va maintenant créer le fichier de script qui va gérer les préférences : il est à placer dans "content/preferences" et se nomme "prefs.js" :

________________________________________________________

//Prefs.js
//Fichier contenant la gestion des préférences

//Variable servant à gérer les préférences
var preferences = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);

//Fonction appellée au lancement de la page de préférences
function cs_onLoadGeneralPane()
{
  var defaultsite = preferences.getCharPref("cs.search.defaultengine");
  var usedefault = preferences.getBoolPref("cs.usedefault");
  if(usedefault)
  {
    //On regarde si il faut activer la combobox
    document.getElementById("cs.search.defaultengine").disabled = false;
    document.getElementById("cs.search.defaultengine-label").disabled = false;
    document.getElementById("cs.usedefault").checked = true;
  }
  if(defaultsite == "")
    return;

  //On choisit l'élément par défaut
  document.getElementById("cs.search.defaultengine").selectedItem = document.getElementById(defaultsite);
}

//Fonction qui change l'utilisation de moteur par recherche par défaut
function cs_toggleUseDefault()
{
  On regarde si la case est cochée
  var checked = document.getElementById("cs.usedefault").checked;

  //On active ou on desactive
  document.getElementById("cs.search.defaultengine").disabled =
  document.getElementById("cs.search.defaultengine-label").disabled = !checked;

  //On change la préférence
  preferences.setBoolPref("cs.usedefault", checked);
}

//On change la préférence de moteur par défaut
function cs_changeDefaultEngine(menulist)
{
  var mit = menulist.selectedItem.id;
  preferences.setCharPref("cs.search.defaultengine", mit);
}
//Fin du fichier

________________________________________________________

On va maintenant créer la page "general.xul" dans le dossier "content/prefpages". Ce fichier va en fait être chargé dans la iframe de "preferences.xul".

________________________________________________________

<?xml version='1.0'?>

<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://cs/skin/skin.css" type="text/css"?>

<page onload="cs_onLoadGeneralPane()" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script type="application/x-javascript" src="chrome://cs/content/preferences/prefs.js"/>

  <groupbox>
    <caption label="Moteur par défaut"/>
    <checkbox id="cs.usedefault" label="Utiliser un moteur par defaut" oncommand="cs_toggleUseDefault()"/>
    <separator/>
    <hbox align="center">
      <label id="cs.search.defaultengine-label" control="cs.search.defaultengine" value="Moteur de recherche par défaut" disabled="true"/>
      <menulist id="cs.search.defaultengine" width="150px" disabled="true" oncommand="cs_changeDefaultEngine(this)">

        <menupopup>

          <menuitem id="mi-vb" label="VB / VB.NET"/>
          <menuitem id="mi-asp" label="ASP / ASP.NET"/>
          <menuitem id="mi-cf" label="Coldfusion"/>
          <menuitem id="mi-cpp" label="C / C++ / C++.NET"/>
          <menuitem id="mi-php" label="PHP"/>
          <menuitem id="mi-js" label="Javascript / DHTML"/>
          <menuitem id="mi-delphi" label="Delphi"/>
          <menuitem id="mi-flash" label="Flash"/>
          <menuitem id="mi-java" label="Java / J2EE"/>
          <menuitem id="mi-graph" label="Graphisme"/>
          <menuitem id="mi-irc" label="IRC"/>
          <menuitem id="mi-asm" label="Assembleur"/>
          <menuitem id="mi-csh" label="C# / C#.NET"/>
          <menuitem id="mi-pda" label="PDA / PocketPC"/>
          <menuitem id="mi-sql" label="SQL"/>
          <menuitem id="mi-foxpro" label="Foxpro"/>
          <menuitem id="mi-python" label="Python"/>

        </menupopup>

      </menulist>
    </hbox>
  </groupbox>
</page>

________________________________________________________

Voila, tous les fichiers de code sont finis.

COMMENT GENERER L'EXTENSION :

    Une extension Firefox se distribue le plus souvent sous la forme d'un fichier .xpi. Ces fichiers sont en fait tout simplement des archives zip. Je n'ai trouvé qu'une solution pour les générer, et elle ne marche que sous windows XP. Si quelqu'un peut essayer autre chose et me dire si ça marche, ça me sera utile. Selectionnez les fichiers et le dossier "chrome" dans le répertoire racine, cliquez bouton-droit / envoyer vers / Dossier compressé. Renommez le fichier en .xpi, et votre extension est terminée !

PS : Si quelqu'un a un colorateur de code qui fait le XML et le JS, qu'il me le dise que je puisse finir cette coloration...

Commentaires

Commentaire de nightlord666 le 19/06/2006 14:17:58

Si quelqu'un trouve une faute d'orthographe, qu'il me le dise et je la corrigerais !

Commentaire de paradoxxl le 06/01/2007 13:30:33

bonjour

Il aurait été intéressant de mettre à disposition le xpi en téléchargement, ça aurait permis d'appréhender plus rapidement ton travail...

Merci quand meme

Commentaire de papoow le 21/08/2007 01:31:36

Bonjour nightlord666 et bonjour à tous :)

Pour l'éditeur avec coloration syntaxique gérant JS et XML, je te propose PSPAD http://www.pspad.com/fr/download.php
Je pense qu'il est assez performant.

Je me lance dans la "compréhension de réalisation d'extension xpi"... faut bien commencer un jour !
Nightlord666 je viendrais certainement te solliciter, en espérant que tu sois un peu dispo.

Cordialement; :)
Papoow

Commentaire de nicomilville le 03/05/2008 09:23:06

Salut,

Très bon tutoriel, pour ce qui est du colorateur syntaxique, regarde le menu code source outil, il y a un colorateur syntaxique !!!
Ta technique sous XP marche aussi sous vista familiale !!!

a++

PS1 : 10/10 !!!

PS2 : désolé, j'ai pas eu le temps de regarder pour les fautes d'orthographe !!!

Commentaire de nicomilville le 03/05/2008 09:23:33

Exuse moi, j'avais oublié la note !

Commentaire de chour03 le 31/07/2008 22:10:32

Salut !

Félicitations pour ce tuto, très bien fait !
Pour les fautes d'orthographe, tu peux remplacer tous les ç par des c, notamment "içi, graçe".

Sinon il y a quelques points magiques que j'aurais aimé voir un peu plus détaillés :

- skin cs cs2006 chrome/skin/ --> Question peut-etre bete, mais si on veut gérer plusieurs skins on fait comment ? (est-ce possible déjà)

-  em:version="1.2" : version de l'extension ou de FF ? Pour ma part FF n'avait pas voulu m'installer l'extension si je mettais 1.0 mais était ok si je mettais 3.0.0 (je suis sur 3.0.1), c'est à n'y rien comprendre.

- le mot clef persist, ça enregistre ou et comment ? Si on veut enregistrer un identifiant et un mdp par exemple, saisis dans une zone de txt, on utilise cette méthode ?

- Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
Je ne vois pas à quoi ça correspond, meme si ça marche. Est-ce qu'on peut savoir tout ce qu'on peut gérer en utilisant Components.classes ?

Tu vas peut-être trouver que j'abuse avec mes questions, qu'il existe google, etc etc. Donc je m'arrête la :) Ton tuto reste excellent à mon goût, et permet de comprendre le schéma général (et donc principal) à suivre pour créer son extension. Bravo.

Commentaire de freezerhm le 09/12/2008 20:05:15

BO goss serieu merci pour ce tuto il va énormement me servir cimer gros.

Commentaire de vinise le 31/12/2008 13:03:11

les liens sont mort pour les icônes et l'extension...

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,016 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales