Elementos esenciales de una extensión

by 3 contributors:

Imagen:traduccion-pendiente.png Esta página está traduciéndose a partir del artículo XUL_School/The_Essentials_of_an_Extension, razón por la cual puede haber algunos errores sintácticos o partes sin traducir. Puedes colaborar continuando con la traducción

El archivo install.rdf

En la última sección miramos a los contenidos de la extensión Hola Mundo. Ahora, miraremos sus archivos y su código, comenzando con el archivo install.rdf. Puedes abrirlo con cualquier editor de texto.

El archivo tiene un formato distinto del XML tradicional, llamado RDF. RDF solía ser el mecanismo central de almacenamiento para Firefox, pero está siendo reemplazado por un sistema de bases de datos más sencillo. Hablaremos de ambos más adelante en este tutorial.

Ahora, miremos a las partes importantes  del archivo.

<em:id>holamundo@xulschool.com</em:id>

Este es el identificador único para la extensión. Firefox necesita esto para distinguir tu extensión de otras extensiones, así que se requiere que tengas una ID única.

Hay dos estándares aceptados para las ids de las extensiones. Una es el formato email presente en el ejemplo de Hola Mundo, que sería algo como <nombreproyecto-name>@<tudominio>. El otro estándar es usar una cadena de texto UUID, la cuál es extremadamente única, y es muy improbable que sea duplicada. Los sistemas basados en Unix tienen una herramienta desde la línea de comandos llamada uuidgen que genera UUIDs. Estas también se pueden crear utilizando herramientas específicas para todos los sistemas. Los paréntesis que cierran son simplemente notación, y son una práctica común. Siempre y cuando tu id sea única, está bien usar cualquiera de las formas.

<em:name>XUL School Hello Worldem:name>
<em:description>Welcome to XUL School!</em:description>
<em:version>0.1</em:version>
<em:creator>Appcoast</em:creator>
<em:homepageURL>https://developer.mozilla.org/en/XUL_School</em:homepageURL>

Esta será la información que será mostrada antes y después de la que la extensión sea instalada, la que puedes ver en la ventana de Extensiones. La URL de la página principal puede ser visitada haciendo clic derecho en la extensión y eligiendo Visitar página principal. Hay muchas otras etiquetas que pueden ser añadidas, para contribuidores y traductores. La especificación completa del archivo install.rdf tiene todos los detalles.

Ya que las extensiones pueden ser traducidas en múltiples idiomas, suele ser necesario traducir la descripción de la extensión, o incluso su nombre. A partir de Firefox 3 y superior, una descripción y nombres con localización específica se puede añadir de la siguiente manera:

<em:localized>
  <Description>
    <em:locale>es-ES</em:locale>
    <em:name>XUL School Hola Mundo</em:name>
    <em:description>¡Bienvenido a XUL School!</em:description>
  </Description>
</em:localized>

La cadena de texto es-ES indica que esta es la localización para española (es) para España (ES). Puedes añadir tantos <em:localized> como necesites Para Firefox 2, localizar este archivo es un poco más complicado. Hablaremos de la localizacion más adelante en esta sección.

<em:type>2</em:type>

Esto especifica que la extensión se instala como una extensión (y no como un tema, por ejemplo). Puedes leer los distintos tipos disponibles en la  especificación de install.rdf.

<em:targetApplication>
  <Description>
    <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
    <em:minVersion>3.0</em:minVersion>
    <em:maxVersion>6.0a1</em:maxVersion>
  </Description>
</em:targetApplication>

Este nodo especifica a qué versiones apunta la extensión, especialmente Firefox, desde la versión 3.0 hasta las versiones experimentales de Firefox 6. La UUID es la ID única de Firefox. Otras aplicaciones y aplicaciones basadas en Mozilla como Thunderbird o Seamonkey tienen las suyas propias. Puedes tener una extensión que funcione en múltiples aplicaciones y versiones. Por ejemplo, si creas una extensión para Firefox, normalmente se debería hacer el pequeño esfuerzo para portarla a Flock o SeaMonkey, los cuáles tienen funciones y UI similares.

La versión mínima y máxima especifica el rango en el cuál la extensión puede ser instalada. Aquí hay más sobre el formato de la versión. Si la aplicación o el rango de versiones no coinciden, no podrás instalar la aplicación, o la aplicación se instalará desactivada. Los usuarios pueden desactivar la comprobación de versiones a través de las preferencias o a través de extensiones como Add-on Compatibility Reporter.

Esta es toda la información que Firefox y otras aplicaciones de Mozilla necesitan para instalar una extensión. Cualquier error o información omitida causará un error en el proceso de instalación, o la extensión se instalará como desactivada.

El archivo chrome.manifest

Chrome es el conjunto de elementos gráficos para el usuario de la ventana de la aplicación que están fuera del contenido de la ventana. Barras de herramientas, de menús, de progreso y de título son ejemplos de elementos que son parte de chrome.

Extraído de Chrome Registration.

En otras palabras, el chrome es todo lo que ves en Firefox. Todas las ventanas de Firefox pueden verse en dos partes: (1) la chrome y (2) la posible área de contenido, como aquella que muestra las páginas web en una pestaña de Firefox. Las ventanas como el administrador de extensiones o la ventana de descargas son puro chrome. La mayoría del código reside en la carpeta chrome, como en el ejemplo de Hola Mundo.

Los archivos chrome están empacados en un archivo JAR, normalmente nombrados tras la extensión. No es necesario empacar los archivos chrome, pero es una práctica común y recomendada por razones de rendimiento.

 

Como hemos visto en la estructura de directorios de la extensión desempacada, la chrome está compuesta de 3 secciones: content, locale y skin. Estas 3 son necesarias para la mayoría de las extensiones. Si abrimos el archivo chrome.manifest (de nuevo, cualquier editor de texto servirá), veremos que las 3 secciones se mencionan:

content   xulschoolhello              jar:chrome/xulschoolhello.jar!/content/
skin      xulschoolhello  classic/1.0 jar:chrome/xulschoolhello.jar!/skin/
locale    xulschoolhello  en-US       jar:chrome/xulschoolhello.jar!/locale/en-US/

El archivo chrome.manifest le dice a Firefox donde mirar para los archivos chrome. El texto contiene varios espacios para que parezca una tabla, pero no es necesario. El parseador ignorará los espacios repetidos.

La pimera línea le dice a Firefox que está siendo declarado (content, skin, locale, u otros que veremos más adelante). La segunda es el nombre del paquete, el cuál explicaremos en breve. Los paquetes skin y locale tienen un tercer valor para especificar que localización o tema están extendiendo. Puede haber múltiples temas y entradas de localización en relación a distintos temas y localizaciones. El caso más común es tener una entrada skin para el skin global, classic/1.0, y múltiples entradas locale, una para cada traducción. Finalmente, la localización es especificada.
Nótese del esquema jar; le dice a Firefox que mire dentro del archivo JAR y lea los archivos del camino correcto. Si quieres tener una extensión con un directorio chrome desempacado, sólo necesitas cambiar los lugares a algo como chrome/content/.

 

Hay algunas opciones adicionales que pueden ser incluidas en las entradas del archivo chrome.manifest. Están documentadas en la página de Chrome Registration. Notablemente, podemos tener distintas entradas que sean específicas para cada SO. Esto es importante, especialmente en Firefox 3 y versiones superiores, donde la apariencia del navegador es muy diferente para cada sistema operativo. Si nuestra extensión necesitase parecer diferente en los sistemas mayoritarios, podríamos cambiar el archivo de manifiesto para que incluyese esto:

content   xulschoolhello              jar:chrome/xulschoolhello.jar!/content/
skin      xulschoolhello  classic/1.0 jar:chrome/xulschoolhello.jar!/skin/unix/
skin      xulschoolhello  classic/1.0 jar:chrome/xulschoolhello.jar!/skin/mac/ os=Darwin
skin      xulschoolhello  classic/1.0 jar:chrome/xulschoolhello.jar!/skin/win/ os=WinNT
locale    xulschoolhello  en-US       jar:chrome/xulschoolhello.jar!/locale/en-US/

De esta manera podemos tener temas distintos para Windows, Mac OS X, y Linux (además de otros sistemas similares a unix), cada uno definido en un directorio separado. Ya que la mayoría de los sistemas están basados en Unix, el tema "unix" es el utilizado por defecto, sin banderas.

El Chrome

Como se ha mencionado antes, el chrome se compone de 3 secciones: contenido, localizaciones y temas. El contenido es la sección mas importante, ya que tiene la interfaz de usuario (XUL) y archivos de scripts (JS). La sección de temas contiene los archivos que definen la mayoría del aspecto y la sensación de la UI (incluyendo CSS e imágenes, como las páginas web). Finalmente, la sección de localización incluye todos los textos utilizados en la extensión, en DTD y archivos de propiedades. Esta división permite a otros desarrolladores crear temas que reemplacen pieles, y traductores para crear localizaciones en distintos idiomas, todo esto sin tener que cambiar tu extensión o tu código. Esto le da a las extensiones de Firefox gran flexibilidad.

Se accede a los archivos chrome  a través del protocolo chrome. Las URIs chrome se definen así:

chrome://packagename/section/path/to/file

Así que, por ejemplo, si quiero acceder al archivo browserOverlay.xul en la extensión, la URI chrome sería chrome://xulschoolhello/content/browserOverlay.xul. Si tienes demasiados archivos en el contenido y quieres organizarlos en subdirectorios, no necesitas cambiar nada en chrome.manifest, todo lo que necesitas es añadir el camino correcto tras content en la URI. Los temas y localizaciones funcionan de la misma manera, y no necesitas especificar sus nombre. Así que, para acceder al archivo DTD en la extensión Hola Mundo, el camino chrome es chrome://xulschoolhello/locale/browserOverlay.dtd. Firefox sabe qué localización buscar.

Aquí tenemos un experimento interesante. Abre una pestaña nueva en Firefox, teclea chrome://mozapps/content/downloads/downloads.xul en la barra de notificaciones y pulsa ENTRAR. ¿Sorprendido? ¡Acabas de abrir la ventana de Descargas en tu pestaña de Firefox! Puedes acceder a cualquier archivo chrome simplemente tecleando su URI en la barra de direcciones. Esto puede ser útil si quieres inspeccionar archivos de script que son parte de Firefox, u otras extensiones, por ti sólo. La mayoría de estos archivos se abren como archivos de texto, a excepción de los archivos XUL, que se ejecutan y muestran como normalmente los verías en una ventana.

Contenido

Hay dos archivos de contenido en el directorio de contenido. Miremos el primer archivo XUL.

Los archivos XUL son archivos XML que definen la interfaz gráfica de usuario de los elementos en Firefox y las extensiones de Firefox. XUL fue inspirado por HTML, así que verás bastantes similitudes entre ambos. De todos modos, XUL es también una mejora sobre HTML, habiendo aprendido de los errores cometidos durante la evolución de HTML. XUL te permite crear interfaces más ricas e interactivas que las que puedas crear con HTML, o al menos XUL lo hace más fácil.

Los archivos XUL normalmente definen una de dos cosas: ventanas o superposiciones. El archivo que has abierto antes, downloads.xul, tiene el código que define la ventana de Descargas. El archivo XUL incluido en la extensión Hola Mundo tiene una superposición. Una superposición extiende una ventana ya existente, añadiendo nuevos elementos a esta o reemplazando algunos de los elementos que tiene. La línea que nos hemos saltado en el archivo  chrome.manifest declara que este archivo XUL es una superposición para la ventana principal del navegador.

overlay chrome://browser/content/browser.xul  chrome://xulschoolhello/content/browserOverlay.xul

Con esta línea, Firefox sabe que necesita tomar el contenido de browserOverlay.xul y superponerlo sobre la ventana principal del navegador, browser.xul. Puedes declarar overlays para cualquier ventana o diálogo en Firefox, pero superponer la ventana principal del navegador es el caso más común.

Ahora echemos un vistazo a los contenidos de nuestro archivo XUL. Nos saltaremos las primeras líneas porque se refieren al tema y la localización, las cuales cubriremos más tarde.

<overlay id="xulschoolhello-browser-overlay"
  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

El elemento raíz en el archivo es un overlay. Otros documentos XUL usan la etiqueta window o dialog. El elemento tiene una id única, la cuál deberías usar en la mayoría de los elementos en tu XUL. El segundo atributo es el espaciado de nombres, lo cuál es algo que siempre deberías definir en tu elemento raíz. Esto dice que este nodo y todos sus nodos hijos son XUL. Sólo necesitas cambiar las declaraciones del espaciado de nombres cuando combines distintos tipos de contenidos, como XUL con HTML o SVG.

Es probable que te hayas dado cuenta del nombre que hemos usado en distintos lugares, así como la id xulschoolhello-browser-overlay. Este es el espaciado de nombres estándar que utilizamos para evitar conflictos con Firefox y otras extensiones, así como hacer algunas tareas de desarrollo más sencillas. Usamos el mismo espaciado de nombres en todas las ids y clases de estilo de los elementos de superposición porque serán mezclados con otros elementos en la ventana principal del navegador. Si usásemos ids genéricas como container o input, estas entrarían en conflicto con las ids usadas dentro de Firefox, o las ids de otras extensiones de superposición. Usando espaciado de nombres minimiza los problemas de compatibilidad con otras extensiones. Usamos camel casing para los nombres de archivos, y todo en minúsculas con barras para las ids de elementos y los nombres de clases de los estilos CSS.
<script type="application/x-javascript"
  src="chrome://xulschoolhello/content/browserOverlay.js" />

Al igual que en HTML, esto incluye un script en JavaScript. Puedes tener tantos elementos scripts en un archivo XUL como necesites. Miraremos su código más tarde.

También es posible que te hayas dado cuenta en el formato de nuestro código, y preguntarte sobre las reglas que seguimos. Nuestra regla general es que la longitud de la línea no sea superior a 80 caracteres. Esto puede parecer muy restrictivo, sobre todo en los archivos XML, pero este número ha sido elegido para permitir a casi todos los editores de texto que manejen estos archivos de manera sencilla. Incluso un editor de textos antiguo desde la línea de comandos funciona bien que cortan sus líneas antes de los 80 caracteres. La tabulación es muy directa: 2 espacios en blanco para indentar. Nunca usamos caracteres TAB, a excepción de los Makefiles, los cuáles cubriremos más adelante. La mayoría de nuestros estándares de código se basan en los estándares de Mozilla u otros conocidos.

Nos saltaremos algo de código qie se cubrirá en la sección de localización, moviéndonos así a la parte importante del contenido:

<menubar id="main-menubar">
  <menu id="xulschoolhello-hello-menu" label="&xulschoolhello.hello.label;"
    accesskey="&xulschoolhello.helloMenu.accesskey;" insertafter="helpMenu">
    <menupopup>
      <menuitem id="xulschoolhello-hello-menu-item"
        label="&xulschoolhello.hello.label;"
        accesskey="&xulschoolhello.helloItem.accesskey;"
        oncommand="XULSchoolChrome.BrowserOverlay.sayHello(event);" />
    </menupopup>
  </menu>
</menubar>

Este es el código que añade el menú de Hola Mundo a la ventana del navegador. Para escribir este código, necesitamos algo de conocimiento sobre el código XUL en browser.xul. Necesitábamos saber que la id del menú principal es main-menubar. Estamos añadiendo un menú nuestro propio, y diciéndole a Firefox que lo añada a la barra de menú principal, justo después del menú de ayuda. Ese es el propósito del atributo:

insertafter="helpMenu"

helpMenu es la id del elemento del menú que corresponde al menú de Ayuda en la ventana principal del navegador. Más adelante veremos como podemos encontrar cosas como las ids de los elementos del navegador, pero por ahora miraremos a los elementos que componen el menú de Hola Mundo.

El elemento menubar representa la barra de menús que normalmente ves arriba del todo de una ventana de aplicación. La ventana principal de Firefox tiene una, pero pocas otras ventanas tienen. También es raro para ventanas adicionales de una extensión tengan sus propias barras de menú.

Hemos añadido el menú de Hola Mundo justo en la "raíz" de la barra de menús así que sería muy fácil para ti localizarlo, pero no es una práctica recomendada. Imaginemos si todas las extensiones añadieran menús a la barra de menús de arriba; teniendo unas pocas extensiones haría que el menú pareciese como un salpicadero de un avión, lleno de opciones. El lugar recomendado para los menús de extensiones es bajo el menú de Herramientas, así que el código se parecería a este:

<menupopup id="menu_ToolsPopup">
  <menu id="xulschoolhello-hello-menu" label="&xulschoolhello.hello.label;"
    accesskey="&xulschoolhello.helloMenu.accesskey;"
    insertafter="javascriptConsole,devToolsSeparator">
    <menupopup>
      <menuitem id="xulschoolhello-hello-menu-item"
        label="&xulschoolhello.hello.label;"
        accesskey="&xulschoolhello.helloItem.accesskey;"
        oncommand="XULSchoolChrome.BrowserOverlay.sayHello(event);" />
    </menupopup>
  </menu>
</menupopup>

Estamos superponiendo un menú que está más adentro en nuestro árbol XUL, pero no parece importar porque todo lo que necesitamos es la id del elemento que queremos superponer. En estado es el elemento menupopup que está dentro del elemento del menú de Herramientas. El atributo insertafter le dice a Firefox que añada el menú debajo del objeto de la Consola de Errores (formalmente conocida como la Consola de JavaScript) en el menú de Herramientas, como se recomienda en la Extension Etiquette page. Discutiremos más de los menús más adelante en este tutorial. Por ahora vamos a centrarnos en la siguiente línea:

oncommand="XULSchoolChrome.BrowserOverlay.sayHello(event);"

This attribute defines an event handler. The command event is the most frequently used in Firefox, since it corresponds to the main action for most UI elements. The value of the attribute is JavaScript code that invokes a function. This function is defined in the JS file that was included with the script tag. The JS function will be called once the user clicks on the menu item in the Hello World menu. All event handlers define a special object named event, which is usually good to pass as an argument to the function. Event handlers are explained in greater depth further ahead.

Now let's look at the JavaScript file and see what's going on when the event is fired.

/**
 * XULSchoolChrome namespace.
 */
if ("undefined" == typeof(XULSchoolChrome)) {
  var XULSchoolChrome = {};
};

The XULSchoolChrome namespace is defined. All objects and variables we define in this JavaScript are global, meaning that scripts in Firefox and other extensions can see them and interact with them. This also means that if we define an object called MenuHandler or some other generic name, it's likely going to conflict with an existing object. What we do here is define a single global object: XULSchoolChrome. Now we know that all of our objects are inside this object, which is unlikely to be duplicated or overwritten by other extensions.

You can read more about the typeof operator. If you're unfamiliar with JavaScript or this particular syntax, initializing an object as {} is the equivalent of initializing it to new Object().

/**
 * Controls the browser overlay for the Hello World extension.
 */
XULSchoolChrome.BrowserOverlay = {

Finally, BrowserOverlay is our object. Naming and referencing  objects in such a long and verbose manner can feel uncomfortable at first, but it's worth the cost.

We use Javadoc style comments on all namespaces, objects and object members. This is a similar standard to the one used in Mozilla code, and some tools can generate documentation automatically from Javadoc.
sayHello : function(aEvent) {
  let stringBundle = document.getElementById("xulschoolhello-string-bundle");
  let message = stringBundle.getString("xulschoolhello.greeting.label");

  window.alert(message);
}

And, finally, this is our function declaration. Three lines of code are all we need for it to work. The first line in the body of the function declares a variable that will hold the stringbundle element defined in the overlay. The variable is declared using let, which is similar to var but with more restricted scope. Here you can read more about let declarations. It's worth noting that this is a relatively new addition to JavaScript in Firefox and you should use var if you're creating an extension compatible with very old versions.

Just like in regular JS, we can use the DOM (Document Object Model) in order to manipulate the XUL document. First we get a reference of the stringbundle element in the document. This is a special element that allows us to obtain localized strings dynamically, by only providing a "key" that identifies the string. This is what we do on the second line. We call the getString method of the bundle element and get the localized message to be displayed. We then call the window.alert function with the message, just like we would do in an HTML document.

Locale

There are two types of locale files: DTD and properties, and in this example we use them both. DTD is the most efficient way of showing text in XUL, so you should use it whenever possible. It is somewhat inflexible so it can't be used for dynamically generated text, hence the need for an alternate way of getting localized strings.

Looking back at the menu code, you probably noticed some attributes such as this:

label="&xulschoolhello.hello.label;" accesskey="&xulschoolhello.helloItem.accesskey;"

These attributes define the text that you see on the menus, and they are string keys that are defined in our DTD file, browserOverlay.dtd. The DTD file was included in the XUL file with the following code:

<!DOCTYPE overlay SYSTEM "chrome://xulschoolhello/locale/browserOverlay.dtd" >

And in the DTD file you can see the association between keys and localized strings:

<!ENTITY xulschoolhello.hello.label            "Hello World!">
<!ENTITY xulschoolhello.helloMenu.accesskey    "l">
<!ENTITY xulschoolhello.helloItem.accesskey    "H">

Notice that on the XUL file you enclose the string key with & and ; while on the DTD file you only specify the key. You may get weird parsing errors or incorrect localization if you don't get it right.

Access keys are the shortcuts that allow you to quickly navigate a menu using only the keyboard. They are also the only way to navigate a menu for people with accessibility problems, such as partial or total blindness, or physical disabilities that make using a mouse very difficult or impossible. You can easily recognize the access keys on Windows because the letter that corresponds to the access key is underlined, as in the following image:

Most user interface controls have the accesskey attribute, and you should use it. The value of the access key is localized because it should match a letter in the label text. You should also be careful to avoid access key repetition. For example, within a menu or submenu, access keys should not be repeated. In a window you have to be more careful picking access keys because there are usually more controls there. You have to be specially careful when picking access keys on an overlay. In our case, we can't use the letter "H" as an accesskey in the Main menu item, because it would be the same as the access key in the Help menu. Same goes with "W" and the Window menu on Mac OS. So we settled on the letter "l".

DTD strings are resolved and set when the document is being loaded. If you request the label attribute value for the Hello World menu using DOM, you get the localized string, not the string key. You cannot dynamically change an attribute value with a new DTD key, you have to set the new value directly:

let helloItem = document.getElementById("xulschoolhello-hello-menu-item");

// The alert will say "Hello World!"
alert(helloItem.getAttribute("label"));
// Wrong
helloItem.setAttribute("label", "&xulschoolhello.hello2.label;");
// Better
helloItem.setAttribute("label", "Alternate message");
// Right!
helloItem.setAttribute("label", someStringBundle.getString("xulschoolhello.hello2.label"));

This is the reason DTD strings are not a solution for all localization cases, and the reason we often need to include string bundles in XUL files:

<stringbundleset id="stringbundleset">
  <stringbundle id="xulschoolhello-string-bundle"
    src="chrome://xulschoolhello/locale/browserOverlay.properties" />
</stringbundleset>

The stringbundleset element is just a container for stringbundle elements. There should only be one per document, which is the reason why we overlay the stringbundleset that is in browser.xul, hence the very generic id. We don't include the insertbefore or insertafter attributes because the ordering of string bundles doesn't make a difference. The element is completely invisible. If you don't include any of those ordering attributes in an overlay element, Firefox will just append your element as the last child of the parent element.

All you need for the string bundle is an id (to be able to fetch the element later) and the chrome path to the properties file. And, of course, you need the properties file:

xulshoolhello.greeting.label = Hi! How are you?

The whitespace around the equals sign is ignored. Just like in install.rdf, comments can be added using the # character at the beginning of the line. Empty lines are ignored as well.

You will often want to include dynamic content as part of localized strings, like when you want to inform the user about some stat related to the extension. For example: "Found 5 words matching the search query". Your first idea would probably be to simply concatenate strings, and have one "Found" property and another "words matching..." property. This is not a good idea. It greatly complicates the work of localizers, and grammar rules on different languages may change the ordering of the sentence entirely. For this reason it's better to use parameters in the properties:

xulshoolhello.search.label = Found %S words matching the search query!

Then you use getFormattedString instead of getString in order to get the localized string. Thanks to this we don't need to have multiple properties, and life is easier for translators. You can read more about it on the Text Formatting section of the XUL Tutorial. Also have a look at the Plurals and Localization article, that covers a new localization feature in Firefox 3 that allows you to further refine this last example to handle different types of plural forms that are also language-dependent.

Skin

Styling XUL is very similar to styling HTML. We'll look into some of the differences when we cover the XUL Box Model, and other more advanced topics. There isn't much styling you can do to a minimal menu and a very simple alert message, so the Hello World extension only includes an empty CSS file and the compulsory global skin file:

<?xml-stylesheet type="text/css" href="chrome://global/skin/"  ?>
<?xml-stylesheet type="text/css" 
  href="chrome://xulschoolhello/skin/browserOverlay.css"  ?>

The global skin CSS file holds the default styles for all XUL elements and windows. Forgetting to include this file in a XUL window usually leads to interesting and often unwanted results. In our case we don't really need to include it, since we're overlaying the main browser XUL file, and that file already includes this global CSS. At any rate it's better to always include it. This way it's harder to make the mistake of not including it. You can enter the chrome path in the location bar and inspect the file if you're curious.

This covers all of the files in the Hello World extension. Now you should have an idea of the basics involved in extension development, so now we'll jump right in and set up a development environment. But first, a little exercise.

Exercise

Change the welcome message that is displayed in the alert window and move the Hello World menu to the Tools Menu, where it belongs. Repackage the XPI and re-install it. You can just drag the XPI file to the browser and it will be installed locally. Test it and verify your changes worked. If you run into problems at installation, it's likely that you didn't reproduce the XPI structure correctly, maybe adding unnecessary folders. Note that on Firefox 4 and above, on Windows and some Linux distributions, the Tools menu is hidden by default. It can be enabled using the Alt key.

Once you're done, you can look at this reference solution: Hello World 2.

This tutorial was kindly donated to Mozilla by Appcoast.

Etiquetas y colaboradores del documento

Contributors to this page: XyLoNaMiyX, teoli, camilourd
Última actualización por: XyLoNaMiyX,