mozilla

Revision 436179 of Capitulo 3: Introducción a XUL—¿Como construir una interfaz de usuario más intuitiva?

  • Enlace amigable (slug) de la revisión: Firefox_addons_developer_guide/Introduction_to_XUL—How_to_build_a_more_intuitive_UI
  • Título de la revisión: Capitulo 3: Introducción a XUL—¿Como construir una interfaz de usuario más intuitiva?
  • Id de la revisión: 436179
  • Creada:
  • Creador: M1k.
  • ¿Es la revisión actual? No
  • Comentario

Contenido de la revisión

{{ Fx_minversion_header(3.5) }} {{ Borrador() }}

Nota: Si desea contribuir a este documento, por favor  siga las instrucciones en la pagina de Contribuciones.

{{ Atras("Complemetos Firefox - guia de desarrolladores/Tecnologías usadas en el desarrollo de extensiones", "Complemetos Firefox - guia de desarrolladores/Uso de XPCOM—Implementación de procesos avanzados") }}

 

Éste documento fué autorizado por Hiroshi Shimoda de Clear Code Inc.  originalmente publicado en Japones por la Conferencia de desarrolladores de Firefox, el verano de 2007. Shimoda-san es un co-autor de Firefox 3 Hacks (O'Reilly Japón, en 2008).

Antes de aprender a desarrollar extensiones, vamos a aprender acerca de XUL; basado en XML, Lenguaje de Interfaz de usuario, que es uno de los pilares de las extenciones.

Introducción

Un Repaso de XUL

XUL es un lenguaje basado en XML, que fué desarrollado para crear Interfaces para el navegador de Mozilla. Se han hecho experimentos sobre combinación de los lenguajes HTML y script, que dejan mucho que desear en ésto del desarrollo de interfaces de usuario, y XUL podría considerarse como una mejora, para éste tipo de desarrollo. Algo parecido a ésto puede verse en XAML,  utilizado en Windows Vista; como tambien Flex, utilizado en  Adobe Flash. Como las páginas web, que muestran lo mismo, sea cual sea la plataforma; las aplicaciones escritas en XUL trabajan del mismo modo, independientemente del entorno en el que se ejecutan.

Dado que HTML, originalmente, fue concebido como un lenguaje para trabajar, especficamente, con documentos en páginas web, inevitablemente carece de funcionalidad para trabajar con aplicaciones. XUL, por el contrario, fue concebido desde el principio como un lenguaje de trabajo para interfaces de usuario, y hace que sea posible insertar elementos graficos con características sofisticadas, sin necesidad  de añadir porciones de codigo adicional.

A diferencia de otros lenguajes, como los normalizados por el organismo W3C, que tienen especificaciones formalizadas, XUL aún no cuenta con una estrtuctura formalme definida.

 

Nota: Si bien no es un documento de especificaciones, su lenguaje se basa en un grupo de reglas y metodos de escritura, que van acompañados de ciertos simbolos, de 2001 a la actualidad XUL se diferencia en muchos aspectos. Para obtener las últimas especificaciones XUL, por favor consulte la Referencia XUL en MDC y la página de XUL en la wiki de Mozilla.

Para cada elemento que explico en este capítulo, voy a ilustrar con un ejemplo de código fuente. Puede escribir estos ejemplos y abrirlos en Firefox, para analisar cómo se comportan y que es lo que muestran. Puede descargar un archivo con todos los ejemplos de código fuente a partir de: {{ TODO("¡ Se adjunta el tar traducido!") }}.

XUL  y sus métodos de visualización

XUL se usa casi exclusivamente para aplicaciones de Mozilla, como Firefox y Thunderbird, como para sus extensiones; pero otros navegadores web, tambien basados en Firefox, o en el motor Gecko, utilizan XUL. Por ejemplo, está el Navegador Mozilla Amazon, que ayuda con las compras en Amazon, y el Método de Presentación en XUL, una herramienta para la escritura y visualización de presentaciones

Para probar los códigos de ejemplo de este capítulo, guardarlos como archivos de texto con extensión . XUL; arrastralo hasta la ventana de Firefox y luego sueltalo.

{{ TODO("Explica la forma de configurar ésta opción, cuando utilice los siguientes anuncios") }}

Si queremos ejecutar Firefox sin su GUI y sólo los contenidos que muestra un determinado archivo XUL, podemos lanzar Firefox y establezca la opción: -chrome file_URL.xul

Otra manera es como se muestra en el Listado 1,es utilizar el método window.openDialog(), que puede ser usado sólo dentro de una ventana XUL. Esto es utilizado por las extensiones para abrir una ventana separada.

window.openDialog('another.xul', '_blank','chrome,all,dialog=no'); 

Listing 1: Abrir una Ventana sin la interfaz grafica

XUL como una applicación XML

Lista 2 mostrar un ejemplo de definición de Interfaz Grafica de usuario escrito en XUL ("un documento XUL"). El elemento Raíz escrito en XUL es generalmente una "Ventana". La dirección URL es:

http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul 

Si la codificación de caracteres es UTF-8, tanto la codificación especifica y la declaración XML se puede omitir. Sin embargo, para los ejemplos de este capítulo, se aconseja incluirlos.

Debido a que un documento XUL también es un documento XML, éste puede contener XHTML, SVG, MathML, y otros elementos, si utiliza referencias externas, el contenido del documento XML es modularizado, combinadose con otras tecnologías relacionadas con XML, como DOM, XLink o XSLT, y se puede utilizar para una gran variedad de aplicaciones.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <!-- Contents go here. -->
</window>

Listado 2: Estructura general de un documento XUL

Y debido a la difución de Firefox y sus extensiones, se está utilizando este tipo de función XML.

Lectura de hojas de estilo

XUL utiliza CSS para especificar el aspecto de sus elementos. Una vez más, ya que XUL es un tipo de XML, las hojas de estilo son leidas usando las instrucciónes de procesamiento xml-stylesheet.

En la línea 2 de la Lista 2, que estamos leyendo en la hoja de estilos del tema estándar. Al referirse a una hoja de estilo especial dentro de chrome://global/skin/, podemos hacer que el rotulo, tamaños de botón, color de fondo de ventana, etc, coincida con el tema elegido en Firefox. También podemos leer en una hoja de estilo que creemos nosotros mismos.

Modelo de Botones XUL

En principio, XUL presenta todos los componentes de la interfaz  que utilizan combinaciones de dos tipos de botones: horizontal y vertical. Como se muestra en el Listado 3, los elementos se pueden colocar de forma horizontal con el hbox (botón horizontal) elemento o verticalmente usando el elemento vbox (botón vertical). Cuando se abre el archivo en Firefox, como se muestra en la Figura 1.

<label value="Horizontal layout"/>
<hbox>
  <button label="horizontal1"/>
  <button label="horizontal2"/>
</hbox>
<label value="Vertical layout"/>
<vbox>
  <button label="vertical1"/>
  <button label="vertical2"/>
</vbox>
<label value="mixed"/>
<hbox>
  <button label="mixed1"/>
  <vbox>
    <button label="mixed2"/>
    <button label="mixed3"/>
  </vbox>
  <button label="mixed4"/>
</hbox>

Listado 3: Cuadros Horizontales y verticales

Figura 1: Salida del listado 3

Tambien tiene una cuadricula,  que se puede utilizar para hacer diseños similares a los elementos HTML logrados usando su tabla de elementos, tomando un elemento de la pila para el diseño de otros elementos, y así sucesivamente. Todos los widgets de la pantalla se presentan con estos cuadros, posibilitando diseños de interfaces complejas.

Atributos Comunes

Antes de examinar los diferentes objetos de la interfaz, echemos un vistazo a algunos de sus atributos comunes, especialmente las de uso frecuente.

id and class

Los atributos de id y class cumplen la misma función que los utilizados en XHTML. id se utiliza para definir un nombre único para un elemento, y class se utiliza para clasificar los elementos, ambos ofrecen formas convenientes para hacer referencia a elementos en CSS y JavaScript. También existen tipos especiales de elementos que sólo entran en juego luego de ser referenciado por otro elemento.

orientación

Ya sea que los cuadros estubiesen dispuestos en vertical u horizontal, todo depende de como estubieran en su estado inicial. Puede establecer o cambiar esta disposición mediante el atributo orient, con opciones para horizontal y vertical de forma explícita.

alinear y enmarcar

Tanto el atributos de alineación ("Aling") como el de enmarcamiento ("Pack") especifican el diseño de los elementos dentro de un cuadro. Ambos se pueden orientar Inicio (arriba e izquierda), central, fin (inferior o derecha) o estiramineto (ampliar este elemento para que coincida con el elemento de mayor altura o anchura).

El atributo alinear opera en el eje perpendicular al atributo orientar, mientras que el atributo enmarcar opera a lo largo del mismo eje. La Figura 2 muestra cómo establecer alin="centro", paquete="start" para los dos elementos permite salidas completamente diferente, con la única diferencia del valor orientación.

<box flex="1" align="end" pack="end">
  <button label="Happy"/>
  <button label="Sad"/>
</box>

Listado 2: como responden alinear y enmarcar con orientación

 

Figura 2: Salida de listado 2

flex

Los elementos normalmente tienen una altura fija y anchura prefijada. El atributo flex indica que un elemento debe estirarse para tomar la altura ó anchura de una ventana.

flex toma un número entero positivo como valor, éste indica cuanto debe estirarse desde el eje del atributo orient ("Instrucción Padre"). Por ejemplo, flex="1" indica que el elemento debe extenderse hasta llegar al eje; si hay dos elementos con atributo flex="1" en una fila, ellos se ajustan para tener el mismo tamaño. Puede asignar multiplicadores más altos como flex="2" (o mayores) para dar más tamaño al elemento. En el Listado 4, la segunda etiqueta se mostrará dos veces tan grande como el primero (figura 3).

<hbox>
  <label value="label1" flex="1" style="border: 1px solid;"/>
  <label value="label2" flex="2" style="border: 1px solid;"/>
</hbox>

Listido 4: Crecimiento con flex

Figure 3: Salida del Listado 4

ordinal

Dentro de un Contenedor XUL, normalmente, los elementos se ordenan siguiendo su orden de aparición en el código fuente (trazado de izquierda a derecha o de arriba a abajo). Utilice el atributo ordinal para alterar ese orden. El atributo ordinal toma valores de enteros positivos, que son utilizados para ordenar la disposición de los elementos del Contenedor, en el ejemplo de la Lista 5, los botones se ordenan de la siguiente manera button3, button2 y botón 1 (Figura 4).

Si varios elementos tienen el mismo valor ordinal, toman el orden en que aparecen en el código fuente. El valor predeterminado de ordinal es 1.

<vbox>
  <button label="button1" ordinal="3"/>
  <button label="button2" ordinal="2"/>
  <button label="button3" ordinal="1"/>
</vbox>

Listado 5: Cambio de order con ordinal

Figure 4: Salida del Listado 5

box size

Es posible ajustar el tamaño de los elementos XUL explícitamente utilizando los atributos ancho y alto (width - height), como se muestra en el Listado 6. Si va a crear elementos que pueden redimnesionarse usando flex, también puede establecer mínimos y máximos con Anchomín, Altomín, Anchomáx y Altomáx. Para usar los píxeles como unidad de tamaño.

<button label="Button" width="200" height="100"/>

Listado 6: Configurar el tamaño de un botón

Además, como se muestra en el Listado 7, puede incrustar CSS explicitamente en elementos, a través del atributo de estilo, lo que le permite establecer tamaños, utilizando distintas unidades de píxeles.

<button label="Button" style="min-width: 10em;"/>

Listado 7: Fijando tamaño a un boton, utilizando codigo CSS

oculto y enrrollado

Los atributos oculto y enrollado actúan como interruptores para desactivar la visualización de elementos.

Configuración oculto = "verdadero" (hidden="true"), desactiva la visualización de ese elemento. Esto tiene el mismo efecto que establecer display: none en CSS. Usted podría utilizar esta opción para definir un estado oculto o ausente, por ejemplo, artículos que no aparecen en los menús contextuales.

Ajuste enrrollado="verdadero" (collapsed="true"), se fija la altura y anchura como nula del elemento, pero el elemento se trata como
presente. Esto equivale a establecer la visibilidad: enrrollado (visibility: collapse), en CSS. Use "enrrollado" para barras laterales
que están actualmente en desuso.

disabilitado

Ésto no es apropiado para el uso en todos los elementos, puede utilizar el atributo disablilitado para desactivar temporalmente la edición a un elemento que es operable por el usuario. Por lo general, los elementos con desablilitado="verdadero" (disabled="true"), aparecerán transparente ó con un gris pálido.

Nota: Las intrucciones oculto, enrollado y desabilitado, tienen atributos lógicos, y al establecer el atributo desablilitado="verdadero" en XUL podría tener consecuencias no deseadas. Esto se debe a que puede haber casos en que una porcion del script o regla CSS estén escritas de tal manera que tratan al valor como verdadero, sin importar las condiciones, esto es así cuando no se ha definido un valor para el elemento. Así que cuando se cambia el valor del atributo con una función DOM, por ejemplo; no utilice setAttribute ("desactivado", false) - en su lugar, utilice removeAttribute("desactivado").
texto de información sobre herramientas

Utilice el atributo tooltiptext para mostrar un breve detalle de opciones sobre el elemento deseado. El texto introducido como valor, es el atributo que se muestra en la información..

persistencia

Utilizar el atributo persistencia es una manera fácil de guardar y almacenar el estado de un elemento XUL, que ha sido cambiado por el usuario. Escriba los nombres de los otros atributos cuyos valores desea almacenar como una cadena ASCII delimitada por el valor de persistencia, la próxima vez que se abra el documento XUL los valores serán guardados automáticamente4. Las caracteristivas de sistema que exploraremos en el Capítulo 4, nos permitiran guardar cambios simples, sin necesidad de utilizar sentencias complejas.

Note: Éstos valores son restaurados en localstore.rdf, dentro del perfil de usuario.

A fin de que el atributo persistencia pueda reguistrar los cambios de otros elementos, cada uno de éstos elementos tienen que tener su identificación.

Widgets usadas en XUL

Root elements

Los documentos XUL utilizan diferentes elementos raíz para realizar multiples propósitos. En esta sección, vamos a ver tres tipos típicos de elementos raíz: la ventana, la página y los elementos de diálogo.
 

Root elements use the windowtype attribute as an arbitrary identifier for the type of window. For example, Firefox uses the windowtype navigator:browser for its browser window and Browser:Preferences for its options dialog. Using methods we will cover in Capítulo 4, we will see how windows can be acquired using these values as keys.

A window's dimensions and location on screen can be specified using the attributes width, height, screenX, and screenY (all using pixels as units). With the previously discussed persist attribute, you can easily store a window's size and location. Firefox uses this method to store its own window sizes and locations as well.

General root elements

window

The window element that has appeared in examples so far is a root element used to define an ordinary window. This displays the same kind of window used for the Firefox browser window, the bookmark manager window, and many other windows. You can generally use the window element as your root element.

page

For sidebar panels and other XUL documents that are opened within inline frames, use the page element as the root element. Apart from having a different intended purpose than the window element, it is functionally no different.

Root elements for dialog windows

dialog

Use the dialog element when creating options dialogs, confirmation dialogs, etc. This element takes a number of attributes, and can easily be made to display controls (buttons, etc) using widgets and layouts native to whatever platform it is running on.

For example, Windows places the OK button on the left and the Cancel button on the right, while Mac OS X has the opposite layout. This is what Firefox itself uses for bookmark properties and other dialogs.

Buttons used in dialog windows

A dialog element will display some number of buttons at its bottom. As shown in Table 1, there are four types of buttons that can be displayed, and you can set the names of the buttons you want to display as a comma-delimited list in the value of the buttons attribute.

{{ TODO("Make the table cleaner") }}

Button name Description
accept The OK button.
cancel The cancel button.
help The help button.
disclosure Either a disclosure triangle or a button.  This is used to allow the user to toggle the display of additional information.

Table 1: Types of buttons that can be displayed in the dialog element

Additionally, there are two special button names, extra1 and extra2. The labels for these buttons are set using the buttonlabelextra1 and buttonlabelextra2 attributes on the root element, which take arbitrary strings as their values.

The action taken when pressing one of these buttons is defined by an event handler with the name ondialog<button name>. If these event handlers are not defined, pressing either the accept button or cancel button will simply close that dialog. Listing 8 shows a simple dialog example, and Figure 5 shows its output.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/"?>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    title="My Dialog" buttons="accept,cancel"
    ondialogaccept="saveValues(); window.close();"
    ondialogcancel="window.close();">
  <checkbox label="My Option"/>
</dialog>

Listing 8: A dialog

Figure 5: Output from Listing 8

Note: The functions behind the dialog elements discussed here require "XPConnect privileges," which are discussed in Chapter 4, so this example will only run correctly if it can run as Firefox code itself or installed extension code. Please be aware that if you attempt to open this sample directly in Firefox, it will not run correctly.

Hierarchically structured dropdown menus are the part of the user interface used for frequently accessed functions in an application or web service. In the past, a combination of HTML and JavaScript was used to produce this sort of complex UI structure, but in XUL, it can be handled easily just by writing tags.

Creating the menu

Listing 9 shows how the menu element and its related elements are combined. This produces the output seen in Figure 6.

<menubar>
  <menu label="Menu 1">
    <menupopup>
      <menuitem label="Item 1"/>
      <menuitem label="Item 2"/>
      <menuseparator/>
      <menuitem label="Item 3"/>
      <menu label="Submenu">
        <menupopup>
          <menuitem label="Item 4"/>
          <menuitem label="Item 5"/>
        </menupopup>
      </menu>
    </menupopup>
  </menu>
</menubar>

Listing 9: A menu definition

Figure 6: Output from Listing 9

Each item in a menu is marked up with the menuitem tag. Use the menuseparator element to insert a separator bar that groups items together. Both menu and menuitem elements take the label attribute to set their labels.

Insert menu elements into a menubar element to create multiple menus. You can easily create hierarchical menus by inserting menupopup and menu elements.

You can even display icons in menus by adding class="menuitem-iconic" to a menuitem element, along with a src attribute that gives an image URI. Figure 7 shows an example of how this is displayed.

Figure 7: Menu items with icons

Executing commands when selecting menu items

Much like dynamic HTML, event handlers are used to execute a command when a menu item is selected. To respond to mouse and keyboard inputs in HTML, the onclick event handler is typically used to respond to mouse clicks, and the onkeypress event handler for keyboard input.

XUL can also use these event handlers, but XUL also offers the oncommand special event handler to deal with actions that often have specific meanings, such as selection by a left-click (or right-click on systems set up as left-handed) on the mouse or selection by the Enter key. Listing 10 shows an example of the oncommand event handler in use. Apart from menuitem elements, it can be used with buttons and other input controls.

<menuitem label="Open project page" oncommand="loadURI(this.value)"
      value="http://mozilla.org/"/> 

Listing 10: The oncommand event handler

Because the Gecko engine implements DOM Level 2 event handlers, you can define dynamic event listeners such as the one in Listing 11.

var item = document.getElementById('menu-item-custom');
function handleCommandEvent(aEvent) {
  alert('OK');
  item.removeEventListener('command', handleCommandEvent, false);
  item.parentNode.removeChild(item);
}

item.addEventListener('command', handleCommandEvent, false);

Listing 11: Additions and deletions using a dynamic event listener

Special menu items

Much like input elements in HTML, menuitem elements can operate like checkboxes and radio buttons by setting their type attributes.

checkbox

Adding type="checkbox" to a menuitem element will check that when it is selected, and uncheck it if it is selected again. For an example of menu items with checkboxes, see the View menu in Firefox, with items to show or hide the toolbar and sidebar. When one has been checked, then the checked="true" attribute is set.

radio button

Assigning type="radio" to multiple menuitem elements and setting them to have the same name attribute groups them so that selecting one deselects all the others, much like radio buttons in HTML. For an example of this kind of menu item, see the Character Encoding submenu of the View menu in Firefox. The selected radio button has the selected="true" attribute set.

Contextual menus

The context attribute is used to display a contextual menu or shortcut menu, that is, a custom menu that will appear when right-clicking on an element.

Earlier we placed the menupopup child element inside a menu element; here, we use it outside the menu element. Instead, the menupopup element is a direct child of the root element and we invoke it using its id attribute, which we set as the value for the context attribute on any other XUL element. When we right-click on that XUL element, we reference that menupopup element by its id, and display its contents as a contextual menu. Listing 12 shows an example.

<button label="Send" oncommand="send();" context="button-context"/>
<menupopup id="button-context">
  <menuitem label="Send with new tab" oncommand="sendInNewTab();"/>
</menupopup> 
Buttons

Buttons that users can click on are defined using the button element. To show one with an icon as shown in Figure 8, define an image's URI as the value for the image attribute.

Note: To see this sample in operation, use any image as the one to display and place it in the same folder as the XUL document.

Using the icon attribute instead of the image attribute allows you to display buttons with icons that are standard for the platform.

Possible values for the icon attribute are given in Table 2.

Figure 8: A button with an image

icon attribute value icon attribute value
accept close
cancel print
help add
open remove
save refresh
find go-forward
clear go-back
yes properties
no select-font
apply select-color

Table 2: Values for the icon attribute

Toolbar buttons

The toolbarbutton element is the element used to define toolbar buttons. This is typically placed inside a toolbar element, which defines a toolbar, but it can be used in other locations.

These mostly act the same as button elements, but as shown in Listing 13, you can change the behavior of toolbarbutton elements using the type attribute. This is illustrated in the output in Figure 9.

<toolbar>
  <toolbarbutton label="Checkbox Type" type="checkbox" image="firefox.png"/>
  <toolbarbutton label="Menu Type" type="menu" popup="button-popup" image="firefox.png"/>
  <toolbarbutton label="Menu Button Type" type="menu-button" popup="button-popup" image="firefox.png"/>
  <menupopup id="button-popup">
    <menuitem label="Item 1"/>
    <menuitem label="Item 2"/>
    <menuitem label="Item 3"/>
  </menupopup>
</toolbar>

Listing 13: Various toolbar buttons

Figure 9: Output of Listing 13

- Checkbox-type toolbar buttons

Specifying type="checkbox" results in a button that stays depressed when clicked, and pops up when clicked again. The button in its depressed state has checked="true" set. This is the kind of button used for the History and Bookmark buttons that can be used to customize the toolbar.

- Menu-type toolbar buttons

Specifying type="menu" and adding a menupop child element (In Firefox 3, you can also use the panel element), or setting the popup attribute to reference a popup menu located elsewhere by its id, will display a popup menu when the button is pressed. Here, the button-click itself is not taken as the input; instead, a command event is issued only when a popup menu item is selected. This is the type of button used for the List All Tabs button at the right edge of the tab bar.

- Menu-button-type toolbar buttons

Specifying type="menu-button" results in a special button that combines features of both a normal toolbar button and one with type="menu", so that clicking the button itself does issue a command event. This is the type of button used for the Back and Forward buttons.

Input Controls

XUL includes a number of input control elements that are very similar to HTML's form-related elements.

Labels

Use the label element for individual text labels, such as descriptive text. The value of the value attribute is the text that will be displayed. The control attribute takes as its value an id reference to another XUL element with that id; clicking that label or giving it focus can be used to pass the focus to the referenced XUL element.

This can also be used to display longer chunks of text. If you want to insert long strings that automatically wrap to the window’s width, you can use the flex attribute as shown in Listing 14, which will automatically expand it; in this case you don't set the value using the value attribute, instead you should place it in the contents of the element. Figure 10 shows the output from this listing.

<hbox>
  <label flex="1">
  Proceeding with this action will send your personal information to a server. Are you sure you want to proceed?
  </label>
</hbox>

Listing 14: Handling long text in a label

Figure 10: Output from Listing 14

Shortening labels

Between the label element and the label attribute on other XUL elements, there can be a lot of labeled elements in XUL. A common attribute that can be set on all of them is the crop attribute.

By applying the crop attribute to elements with the label attribute set or to the label element, part of the label will be replaced by an ellipsis (…) if it overflows the width of the parent element. The part of the label that gets cropped can be controlled by setting its value to start, center, or end.

You can set the maximum width of the box using the CSS max-width property.

Checkboxes

The checkbox shown in Figure 11 was marked up using the checkbox element. When it is in its checked state, its checked attribute is set to true.

<checkbox label="Checkbox checked" checked="true"/>
<checkbox label="Checkbox unchecked" checked="false"/>

Listing 11: Checkboxes in different state

Figure 11: Output from listing 11

Radio Buttons

Radio buttons in HTML are multiple input elements grouped by assigning them all the same name attribute. In XUL, this is expressed using a combination of two elements: radiogroup and radio. You set exclusive options by inserting multiple radio elements into the content of one radiogroup element; the currently selected radio element will have selected="true" set.

The radio element can be uniquely identified by setting its value attribute. When that radio element is selected, the value of its value attribute is copied to the radiogroup, so that you can check for the selected radio button simply by fetching the radiogroup element’s value attribute.

There may be situations where you want to locate a radio element outside of a radiogroup element. By combining it with hbox and vbox, you can write code similar to that shown in Listing 15, which will produce output as shown in Figure 12.

<radiogroup orient="vertical">
  <hbox>
    <radio label="Top Left"/>
    <radio label="Top Right"/>
  </hbox>
  <hbox>
    <radio label="Bottom Left"/>
    <radio label="Bottom Right"/>
  </hbox>
</radiogroup>

Listing 15: A complex layout of radio buttons

Figure 12: Output from Listing 15

Text boxes

Use the textbox element to accept text input. In HTML, there are two separate elements—input for one line of text, and textarea for multiple lines. But both these functions are handled by textbox as shown in Listing 16, which produces output as shown in Figure 13.

The textbox element uses the value attribute to set its default content; content entered by the user also can be captured using the value attribute. To set a maximum length in characters, declare the maxlength attribute with a positive integer value. Setting type="password" will turn the textbox into a special password-entry field, in which characters are hidden as they're typed.

Every character entered into a textbox generates an input event. If you use the oninput event handler, you can implement commands that reflect user input in real time.

<vbox align="start">
  <textbox/>
  <textbox multiline="true" rows="5" cols="15"/>
</vbox>

Listing 16: textbox examples

Figure 13: Output from Listing 16

Autocomplete

Adding type="autocomplete" to a textbox element enables an automatic completion function for it.

Note that to actually use this function, you must also specify a search target for the autocomplete text using the autocompletesearch attribute. If you want to use the Location Bar history, set the value for this to history; if you want it to be the Search Bar history, use search-history; and if you want it to be another form’s input history, use form-history; this attribute can take one value or multiple space-delimited values.

Also, in order to actually read in a history for autocomplete, you will need XPConnect privileges, which we will cover in Chapter 4.

Use the menulist element to create a control for making selections from a drop-down list. As shown in Listing 17, this is implemented in combination with the menupopup element; it produces output as shown in Figure 14.

A click reveals the drop-down list; when an item is selected, the values of that item’s label and value attributes are copied to the label and value attributes of the menulist element itself. By default, the first menu item is selected, but any menu can be preselected by adding selected="true" to it.

<menulist>
  <menupopup>
    <menuitem label="Item 1" value="1"/>
    <menuitem label="Item 2" value="2"/>
    <menuitem label="Item 3" value="3"/>
  </menupopup>
</menulist>

Listing 17: A menulist example

Figure 14: Output from Listing 17

By adding editable="true" to the menulist element, you can accept arbitrary text input in addition to a list selection, as is often used on font selection menus in word processors.

Special elements

Embedding images

In addition to writing direct JavaScript code in event handlers, XUL also allows you to embed scripts using a script element, just like in HTML; this can be used to read in an external script or to place the code in the script element's content.

If you are embedding a script in a page, you should bracket your code inside a CDATA section as shown in Listing 18; this will avoid errors caused by mistakenly reading "&" and other characters as the beginnings of entity references.

<script type="application/javascript"><![CDATA[
  var nodes = gBrowser.mTabContainer.childNodes;
  for (var i = 0; i < nodes.length; i++)
  alert(nodes[i].label);
]]></script>

Listing 18: Embedding a script in XUL

Note: Although embedding JavaScript is permitted, it's generally encouraged that you instead place your JavaScript code in an external file.

Browser and tabbrowser

XUL allows you to use inline frames. You can set the src attribute of an iframe element to the URI of another XUL document or web page, and it will be displayed there. But iframes are rarely used in XUL—in practice, the browser element is used more often.

The browser element is essentially a more powerful version of an inline frame, equipped with all the basic functions of a web browser. Unlike an iframe, a browser element has the ability to navigate backward and forward through pages and includes the ability to prevent scripts in embedded frames from accessing outside the frame. For building applications linked to external web pages, this is a more secure and more convenient approach.

The tabbrowser element is even more capable than the browser element because it includes the basic tab-handling features from Firefox. To use this requires XPConnect privileges, the same as autocomplete does; this will be covered in Chapter 4.

Opening a page

If you specify a URI value for the src attribute in the browser element, that URI will be opened by default. If the src attribute's value changes, you can dynamically open a different web page or XUL document.

Functions like Back, Forward, Reload can all be called using the goBack(), goForward(), and reload() methods. Using the stop() method stops loading the page currently in the process of being opened.

Access restrictions

With frames defined using HTML's frame and iframe elements, it is possible for a child frame to access its parent and ancestor frames by getting the parent and top properties of window objects. For an application that can open any web page, this could give a script on a web page access to an XUL document's frame, creating a dangerous opening for personal information to leak out.

In the interests of security, you can enforce access restrictions by declaring type="content" on a browser element. When you do this, any web page that gets opened will see itself as the topmost frame. If you are developing an application with an interface that can open web pages, I recommend that you always use this declaration to limit access to the parent frame.

In certain circumstances, you may want to declare type="content-primary". A browser element with this declaration is treated as a special browser among other XUL documents, such that the window object displaying its web page can be accessed using the window.content property. In Firefox itself, the content region of the active tab is declared as a browser element with type="content-primary".

Keyboard shortcuts

To implement keyboard shortcuts (pressing a key while holding down modifier keys like Control or Shift.) in a DHTML-based interface, you need a script that will intercept keyboard inputs.

In XUL, you can define keyboard shortcuts simply by using the key element, as shown in Listing 19.

<key id="key-save" key="s" modifiers="accel,shift" oncommand="save();"/>
<key id="key-scroll-up" keycode="VK_PAGE_UP" oncommand="advanceFocus(-1);"/>

Listing 19: Defining keyboard shortcuts

To make letters, numbers, symbols, or the space bar act as triggers, declare that character as the key attribute’s value. You can use either uppercase and lowercase letters and they will be handled the same.

For triggers on other special keys, use the keycode attribute with the appropriate keycode name value. In general you can use the keycode name for any key; the most commonly used ones are shown in Table 3.

Key Keycode name
Return VK_RETURN
Enter VK_ENTER
Backspace VK_BACK_SPACE
Delete VK_DELETE
Escape VK_ESCAPE
VK_UP
VK_DOWN
VK_LEFT
VK_RIGHT
Table 3: Typical keycode names

 

Using modifier keys

Use the modifiers attribute with one or more of the following comma-delimited values: "control", "alt", "shift", and "meta" in order to limit the use of keyboard shortcuts to only operate when those modifier keys are pressed together with another key. The standard modifier key on Windows and Linux is Control; on Mac OS it is Command. An easy way to automatically use the modifier key appropriate for the current platform is to set the modifier key to "accel", which maps to Control on Windows and Linux, Command on Mac OS.

Note: The "meta" key is the Command key on Mac OS X (the one with the cloverleaf design on it).

The key element itself is never displayed on screen. In order to display defined keyboard shortcuts as shown in Figure 15, reference the key element's id from the menu or menuitem element’s key attribute.

{{ TODO("Figure 15: Displaying keyboard shortcuts in menu items:Menu 1/Save/Scroll") }}

XUL includes a number of elements used strictly to organize the layout of screen widgets.

spacer

Use the spacer element if you want to open up the space between buttons. You can use the flex attribute or style attribute to make whitespace stretch or set it to a certain size.

grid

In the same way that the table element is used to lay out content in HTML, you can use the grid element in XUL. As shown in Listing 20, you first declare the number of columns, and then define the content of each row. The output of this sample is shown in Figure 16. You can also code it so that the rows come first, declaring the number of rows and then defining content by column.

The rowspan and colspan attributes available in HTML tables are not available in XUL grids.

<grid>
  <columns>
    <column/>
    <column flex="1"/>
  </columns>
  <rows>
    <row align="center">
      <label value="User ID"/>
      <textbox/>
    </row>
    <row align="center">
      <label value="Name"/>
      <textbox/>
    </row>
  </rows>
</grid>

Listing 20: Layout using the grid

Figure 16: Output from Listing 20

stack

Use the stack element to overlap multiple widgets. The stack element differs from a normal box in that all the elements in it are layered over each other, working from the bottom up. Listing 21 shows an example of a thermometer-style progress bar, with its output shown in Figure 17.

<stack>
  <progressmeter mode="normal" value="50"/>
  <hbox align="center">
    <label value="In progress…"/>
  </hbox>
</stack>

Listing 21: Overlapping with stack

Figure 17: Progress Bar

tab

Use the tab element to divide multiple pages, as used in the Properties dialog; use the tabbox element to group related elements. This is demonstrated in Listing 22, with its output shown in Figure 18.

<tabbox>
  <tabs>
    <tab label="tab1"/>
    <tab label="tab2" selected="true"/>
  </tabs>
  <tabpanels>
    <tabpanel>
      <checkbox label="check1"/>
    </tabpanel>
    <tabpanel orient="vertical">
      <checkbox label="check2"/>
      <checkbox label="check3"/>
    </tabpanel>
  </tabpanels>
</tabbox>

Listing 22: Tabs in use

Figure 18: Output from listing 22

Other XUL functions

Overlays

One of XUL’s distinctive features is overlays. These give you the ability to combine multiple XUL documents and process them as a single XUL document. In Firefox, this is used to modularize functions and implement extensions.

By inserting an xul-overlay processing instruction between the XML declaration and the opening tag of the root element, the XUL document specified by the xul-overlay will be read in at the same time as the current XUL document. The XUL document that actually gets displayed will be a combination of the original XUL document and the one specified in xul-overlay.

Try typing up Listing 23 and saving it as base.xul. Take a look at the overlay example used by this XUL document.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/"?>
<?xul-overlay href="overlayDocument.xul"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <hbox id="box1">
    <label id="label1" value="Text label"/>
  </hbox>
  <hbox id="box2">
    <label id="label2" value="Text label"/>
  </hbox>
</window>

Listing 23: base.xul

Appending elements

When defining an XUL document to open as an overlay, use an overlay element as the root element. Save the text of Listing 24 as overlayDocument.xul in the same directory as base.xul.

Here, we’ll open base.xul in the Firefox window. overlayDocument.xul gets read in at the same time as base.xul, resulting in what we see in Figure 19, where overlayDocument.xul gets appended to the end of base.xul.

<?xml version="1.0" encoding="UTF-8"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <button label="Button 1"/>
  <button label="Button 2"/>
  <button label="Button 3"/>
</overlay>

Listing 24: overlayDocument.xul

Figure 19: Output from listings 23 and 24

Merging and inserting elements

By inserting id attributes into the elements being appended in the XUL overlay document, elements in the base document with the same id values will have their attributes and values merged with the overlay document.

Try overwriting the contents of overlayDocument.xul with Listing 25 and re-saving.

<?xml version="1.0" encoding="UTF-8"?>
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <hbox id="box1" align="center" style="border: 1px solid; margin: 1em;">
    <button label="Button 1"/>
    <button label="Button 2" insertbefore="label1"/>
  </hbox>
  <button label="Button 3"/>
</overlay>

Listing 25: Substitute code for overlayDocument.xul

Let's open base.xul in a Firefox window again. As shown in Figure 20, the style attribute from the element with the id "box1" in the overlay document has been merged with the markup for the button with that id in the base document, and inserted into the box.

 Figure 20: Output from listing 23 and 25

Furthermore, following the declaration insertbefore="label1", the "button2" button now has been inserted before the element with the id "label1". Conversely, if we wanted to insert it directly after, we could have used the attribute insertafter. We can also use the position attribute as a way to locate an element numerically at any position; for example, using position="4" would insert it as the fourth element.

External entities

Being a form of XML, XUL can also use entity references based on DTDs (document type definitions) as shown in Listing 26. Note that external DTD files are limited to what is given in the chrome URL, which will be discussed in Chapter 5. Please be aware that ordinary DTD files on the web or in a local directory will not be opened.

Note: You may use a relative path to access a chrome URL from an XUL document.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/"?>
<!DOCTYPE window SYSTEM "chrome://testapp/locale/testapp.dtd">
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <button label="&button.1.label;"/>
  <button label="&button.2.label;"/>
</window>

Listing 26: Reading in external entities

<!ENTITY button.1.label "Firefox">
<!ENTITY button.2.label "Thunderbird">

Listing 27: testapp.dtd

Substituting CSS for attribute declarations

The Gecko rendering engine includes a number of CSS properties with -moz- prepended to them; these are custom properties for XUL that have been implemented prior to being a W3C recommendation. The ones shown in Table A below correspond to the common attributes in XUL. In fact, those XUL attributes operate through these CSS properties.

The values declared for these CSS properties are the same integers or keywords used by the XUL attributes. While we don't recommend that you use these properties in ordinary XUL development, they can be useful for customizing the Firefox UI without scripting by using userChrome.css. For example, if you save the contents of Listing 28 as userChrome.css and save that in the chrome directory under the user profile directory, the tab bar will appear at the bottom of the content area.

XUL attribute CSS property Example
orient -moz-box-orient

-moz-box-orient: vertical;

align

-moz-box-align

-moz-box-align: start;

pack

-moz-box-pack

-moz-box-pack: stretch;

flex -moz-box-flex -moz-box-flex: 1;
ordinal -moz-box-ordinal-group -moz-box-ordinal-group: 2

Table 4: CSS properties corresponding to XUL attributes

tabbrowser .tabbrowser-strip {
  -moz-box-ordinal-group: 2;
}
tabbrowser tabpanels {
  -moz-box-ordinal-group: 1;
}

Listing 28: A user stylesheet that locates the tab bar at the bottom

Icons corresponding to filetypes

Firefox allows you to use a special URI scheme, moz-icon, that produces filetype icons that are standard for whatever platform it is running on. For example, to display a 16x16 icon for a file with a .pdf dot-extension (a PDF file), you would write moz-icon://.PDF?size=16.

You can reference icons using content type as a key rather than dot-extension; for example, you could display a plain-text icon using moz-icon://goat?size=16&contentType=text/plain.

You can also display specific icons using the markup moz-icon:file URL?size=size.

The button icons mentioned in Table 2 also can be called using moz-icon URIs, using the markup moz-icon://stock/gtk-button name?size=button. Note, however, that this does not work in Linux environments.

Spin buttons

You can add a type="number" declaration to a textbox element, making it a textbox specifically for entering numeric values. This will cause the spin buttons seen in Figure 21 to appear. Additional attributes that accompany this are min and max to set minimum and maximum values, and increment, which sets the amount by which one click on the spin buttons will change the displayed value.

Figure 21: A textbox for numeric input

Sliders

The scale element is used similarly to the volume slider in Windows, allowing the user to vary a value by moving a slider up/down or left/right (see Listing 28 and Figure 22).

Note: Although this control is also known as a slider, the slider element already exists in XUL as a part of a scrollbar, so this element has been named "scale".
<hbox>
  <scale orient="horizontal" min="-100" max="100" value="0"/>
  <scale orient="vertical" min="0" max="100" value="50"/>
</hbox>

Listing 29: The scale element

Figure 22: Output from Listing 29

{{ PreviousNext("Firefox addons developer guide/Technologies used in developing extensions", "Firefox addons developer guide/Using XPCOM—Implementing advanced processes") }}

Fuente de la revisión

<p>{{ Fx_minversion_header(3.5) }} {{ Borrador() }}</p>
<div class="note">
  <strong>Nota: </strong>Si desea contribuir a este documento, por favor&nbsp; siga las instrucciones en la pagina de <a class="internal" href="https://developer.mozilla.org/En/Firefox_addons_developer_guide/Contribute" title="En/Firefox_addons_developer_guide/Contribute">Contribuciones.</a></div>
<p>{{ Atras("Complemetos Firefox - guia de desarrolladores/Tecnologías usadas en el desarrollo de extensiones", "Complemetos Firefox - guia de desarrolladores/Uso de XPCOM—I<span class="short_text" id="result_box" lang="es"><span class="hps">mplementación</span> <span class="hps">de procesos avanzados</span></span>") }}</p>
<p>&nbsp;</p>
<p><em>Éste documento fué autorizado por <a class="external" href="http://piro.sakura.ne.jp/" title="http://piro.sakura.ne.jp/">Hiroshi Shimoda</a> de </em><a class="external" href="http://www.clear-code.com/" title="http://www.clear-code.com/"><em>Clear Code Inc.</em></a><em>&nbsp; originalmente publicado en Japones por la </em><em><a href="https://developer.mozilla.org/en-US/docs/" title="/en-US/docs/">Conferencia de desarrolladores de Firefox, el verano de 2007</a>. </em><em>Shimoda-san </em><em>es un co-autor de <a class="external" href="http://www.oreilly.co.jp/books/9784873113753/index.html" title="http://www.oreilly.co.jp/books/9784873113753/index.html">Firefox 3 Hacks</a> (O'Reilly&nbsp;Japón, en 2008).</em></p>
<p>Antes de aprender a desarrollar extensiones, vamos a aprender acerca de XUL; basado en XML, Lenguaje de Interfaz de usuario, que es uno de los pilares de las extenciones.</p>
<h2 id="Introducci.C3.B3n">Introducción</h2>
<h3 id="Un_Repaso_de_XUL">Un Repaso de XUL</h3>
<p>XUL es un lenguaje basado en XML, que fué desarrollado para crear Interfaces para el navegador de Mozilla. Se han hecho experimentos sobre combinación de los lenguajes HTML y script, que dejan mucho que desear en ésto del desarrollo de interfaces de usuario, y XUL podría considerarse como una mejora, para éste tipo de desarrollo. <span id="result_box" lang="es"><span class="hps">Algo parecido a ésto puede verse </span><span class="hps">en</span> <span class="hps">XAML</span><span>,&nbsp; utiliza</span>do <span class="hps">en Windows</span> <span class="hps">Vista</span></span>; como tambien Flex, utilizado en&nbsp; Adobe Flash. Como las páginas web, que muestran lo mismo, sea cual sea la plataforma; las aplicaciones escritas en XUL trabajan del mismo modo, independientemente del entorno en el que se ejecutan.</p>
<p>Dado que HTML, originalmente, fue concebido como un lenguaje para trabajar, especficamente, con documentos en páginas web, inevitablemente carece de funcionalidad para trabajar con aplicaciones. XUL, por el contrario, fue concebido desde el principio como un lenguaje de trabajo para interfaces de usuario, y hace que sea posible insertar elementos graficos con características sofisticadas, sin necesidad&nbsp; de añadir porciones de codigo adicional.<br />
  <br />
  A diferencia de otros lenguajes, como los normalizados por el organismo W3C, que tienen especificaciones formalizadas, XUL aún no cuenta con una estrtuctura formalme definida.</p>
<p>&nbsp;</p>
<div class="note">
  <strong>Nota: </strong>Si bien no es un documento de especificaciones, su lenguaje se basa en un grupo de reglas y metodos de escritura, que van acompañados de ciertos simbolos, de 2001 a la actualidad XUL se diferencia en muchos aspectos. Para obtener las últimas especificaciones XUL, por favor consulte la <a href="https://developer.mozilla.org/en-US/docs/" title="/en-US/docs/">Referencia XUL en MDC</a> y la <a href="http://wiki.mozilla.org/XUL" title="http://wiki.mozilla.org/XUL">página de XUL</a> en la wiki de Mozilla.</div>
<p>Para cada elemento que explico en este capítulo, voy a ilustrar con un ejemplo de código fuente. Puede escribir estos ejemplos y abrirlos en Firefox, para analisar cómo se comportan y que es lo que muestran. Puede descargar un archivo con todos los ejemplos de código fuente a partir de: {{ TODO("¡ Se adjunta el tar traducido!") }}.</p>
<h4 id="XUL.C2.A0_y_sus_m.C3.A9todos_de_visualizaci.C3.B3n">XUL&nbsp; y sus métodos de visualización</h4>
<p>XUL se usa casi exclusivamente para aplicaciones de Mozilla, como Firefox y Thunderbird, como para sus extensiones; pero otros navegadores web, tambien basados en Firefox, o en el motor Gecko, utilizan XUL. Por ejemplo, está el <a href="http://www.faser.net/mab/chrome/content/mab.xul" title="http://www.faser.net/mab/chrome/content/mab.xul">Navegador Mozilla Amazon</a>, que ayuda con las compras en Amazon, y el <a href="http://piro.sakura.ne.jp/xul/applications/takahashi-r/" title="http://piro.sakura.ne.jp/xul/applications/takahashi-r/"><em>Método de Presentación en XUL</em></a>, una herramienta para la escritura y visualización de presentaciones</p>
<p>Para probar los códigos de ejemplo de este capítulo, guardarlos como archivos de texto con extensión . XUL; arrastralo hasta la ventana de Firefox y luego sueltalo.</p>
<p>{{ TODO("Explica la forma de configurar ésta opción, cuando utilice los siguientes anuncios") }}</p>
<p><span id="result_box" lang="es"><span class="hps">Si queremos</span> <span class="hps">ejecutar</span> <span class="hps">Firefox</span> <span class="hps alt-edited">sin su</span> <span class="hps">GUI</span> <span class="hps">y sólo los</span> <span class="hps">contenidos que </span></span><span id="result_box" lang="es"><span class="hps">muestra</span></span><span id="result_box" lang="es"><span class="hps"> un</span> <span class="hps">determinado archivo</span> <span class="hps">XUL</span><span>,</span> <span class="hps">podemos lanzar</span> <span class="hps">Firefox</span> <span class="hps">y establezca la opción</span></span>: <code>-chrome file_URL.xul</code></p>
<p><span id="result_box" lang="es"><span class="hps">Otra manera es </span><span class="hps">como se muestra</span> <span class="hps">en el Listado</span> <span class="hps">1</span></span>,<span id="result_box" lang="es"><span class="hps">es utilizar</span> <span class="hps">el método</span></span> <a class="internal" href="https://developer.mozilla.org/en/DOM/window.openDialog" title="En/DOM/Window.openDialog"><code>window.openDialog()</code></a><span id="result_box" lang="es"><span>,</span> <span class="hps">que puede ser usado</span> <span class="hps">sólo dentro de</span> <span class="hps">una ventana</span> <span class="hps">XUL</span><span>.</span> <span class="hps">Esto es utilizado por</span> <span class="hps">las extensiones</span> <span class="hps">para abrir</span> <span class="hps">una ventana separada</span><span>.</span></span></p>
<pre>
window.openDialog('another.xul', '_blank','chrome,all,dialog=no');&nbsp;</pre>
<p><strong>Listing 1: Abrir una Ventana sin la interfaz grafica</strong></p>
<h4 id="XUL_como_una_applicaci.C3.B3n_XML">XUL como una applicación XML</h4>
<p>Lista 2 mostrar un ejemplo de definición de Interfaz Grafica de usuario escrito en XUL ("un documento XUL"). El elemento Raíz escrito en XUL es generalmente una "Ventana". La dirección URL es:</p>
<pre>
<code>http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</code> 
</pre>
<p>Si la codificación de caracteres es UTF-8, tanto la codificación especifica y la declaración XML se puede omitir. Sin embargo, para los ejemplos de este capítulo, se aconseja incluirlos.<br />
  <br />
  Debido a que un documento XUL también es un documento XML, éste puede contener XHTML, SVG, MathML, y otros elementos, si utiliza referencias externas, el contenido del documento XML es modularizado, combinadose con otras tecnologías relacionadas con XML, como DOM, XLink o XSLT, y se puede utilizar para una gran variedad de aplicaciones.</p>
<pre class="brush: xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;?xml-stylesheet href="chrome://global/skin/"?&gt;
&lt;window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
&nbsp;&nbsp;&lt;!-- Contents go here. --&gt;
&lt;/window&gt;
</pre>
<p><strong>Listado 2: Estructura general de un documento XUL</strong><br />
  <br />
  Y debido a la difución de Firefox y sus extensiones, se está utilizando este tipo de función XML.</p>
<h4 id="Lectura_de_hojas_de_estilo">Lectura de hojas de estilo</h4>
<p>XUL utiliza CSS para especificar el aspecto de sus elementos. Una vez más, ya que XUL es un tipo de XML, las hojas de estilo son leidas usando las instrucciónes de procesamiento <code>xml-stylesheet</code>.<br />
  <br />
  En la línea 2 de la Lista 2, que estamos leyendo en la hoja de estilos del tema estándar. Al referirse a una hoja de estilo especial dentro de <code><a class="external" rel="freelink">chrome://global/skin/</a></code>, podemos hacer que el rotulo, tamaños de botón, color de fondo de ventana, etc, coincida con el tema elegido en Firefox. También podemos leer en una hoja de estilo que creemos nosotros mismos.</p>
<h4 id="Modelo_de_Botones_XUL">Modelo de Botones XUL</h4>
<p>En principio, XUL presenta todos los componentes de la interfaz&nbsp; que utilizan combinaciones de dos tipos de botones: horizontal y vertical. Como se muestra en el Listado 3, los elementos se pueden colocar de forma horizontal con el <code><a class="external" href="https://developer.mozilla.org/en/XUL/hbox" rel="freelink">hbox</a></code> (botón horizontal) elemento o verticalmente usando el elemento <code><a class="external" href="https://developer.mozilla.org/en/XUL/vbox" rel="freelink">vbox</a></code> (botón vertical). Cuando se abre el archivo en Firefox, como se muestra en la Figura 1.</p>
<pre class="brush: xml">
&lt;label value="Horizontal layout"/&gt;
&lt;hbox&gt;
&nbsp;&nbsp;&lt;button label="horizontal1"/&gt;
&nbsp;&nbsp;&lt;button label="horizontal2"/&gt;
&lt;/hbox&gt;
&lt;label value="Vertical layout"/&gt;
&lt;vbox&gt;
&nbsp;&nbsp;&lt;button label="vertical1"/&gt;
&nbsp;&nbsp;&lt;button label="vertical2"/&gt;
&lt;/vbox&gt;
&lt;label value="mixed"/&gt;
&lt;hbox&gt;
&nbsp;&nbsp;&lt;button label="mixed1"/&gt;
&nbsp;&nbsp;&lt;vbox&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;button label="mixed2"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;button label="mixed3"/&gt;
&nbsp;&nbsp;&lt;/vbox&gt;
&nbsp;&nbsp;&lt;button label="mixed4"/&gt;
&lt;/hbox&gt;
</pre>
<p><strong>Listado 3: Cuadros Horizontales y verticales</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3819/=figure-1.png" style="width: 492px; height: 222px;" /></p>
<p><strong>Figura 1: Salida del listado 3</strong></p>
<p>Tambien tiene una <a class="internal" href="https://developer.mozilla.org/en/XUL/grid" title="En/XUL/Grid"><code>cuadricula</code></a>,&nbsp; que se puede utilizar para hacer diseños similares a los elementos HTML logrados usando su <code>tabla</code> de elementos, tomando un elemento de la <a class="internal" href="https://developer.mozilla.org/en/XUL/stack" title="En/XUL/Stack"><code>pila</code></a> para el diseño de otros elementos, y así sucesivamente.<span id="result_box" lang="es"><span class="hps"> Todos los widgets</span> <span class="hps">de la pantalla</span> <span class="hps">se presentan</span> <span class="hps">con</span> <span class="hps">estos cuadros</span><span>, posibilitando</span> <span class="hps">diseños de interfaces</span> <span class="hps">complejas</span></span>.</p>
<h4 id="Atributos_Comunes">Atributos Comunes</h4>
<p><span id="result_box" lang="es"><span class="hps">Antes de examinar</span> <span class="hps">los diferentes</span> <span class="hps">objetos de la interfaz</span><span>,</span> <span class="hps">echemos un vistazo a</span> <span class="hps">algunos de</span> <span class="hps">sus</span> <span class="hps">atributos comunes</span><span>, especialmente</span> <span class="hps">las</span> <span class="hps">de uso frecuente</span><span class="hps">.</span></span></p>
<h5 id="id_and_class">id and class</h5>
<p>Los atributos de <a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/id" title="En/XUL/Attribute/Id"><code>id</code></a> <code>y </code><a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/class" title="En/XUL/Attribute/Class"><code>class</code></a> cumplen la misma función que los utilizados en XHTML. <code>id</code> se utiliza para definir un nombre único para un elemento, y <code>class</code> se utiliza para clasificar los elementos, ambos ofrecen formas convenientes para hacer referencia a elementos en CSS y JavaScript. También existen tipos especiales de elementos que sólo entran en juego luego de ser referenciado por otro elemento.</p>
<h5 id="orientaci.C3.B3n">orientación</h5>
<p>Ya sea que los cuadros estubiesen dispuestos en vertical u horizontal, todo depende de como estubieran en su estado inicial. Puede establecer o cambiar esta disposición mediante el atributo <a class="internal" href="https://developer.mozilla.org/en/XUL/Property/orient" title="En/XUL/Property/Orient"><code>orient</code></a>, con opciones para horizontal y vertical de forma explícita.</p>
<h5 id="alinear_y_enmarcar">alinear y enmarcar</h5>
<p>Tanto el atributos de <a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/align" title="En/XUL/Attribute/Align"><code>alineación</code></a> (<code>"Aling"</code>) como el de<a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/pack" title="En/XUL/Attribute/Pack"><code> enmarcamiento </code></a>(<code>"Pack</code><code>"</code>) especifican el diseño de los elementos dentro de un cuadro. Ambos se pueden orientar Inicio (arriba e izquierda), <code>central</code>, <code>fin</code> (inferior o derecha) o <code>estiramineto</code> (ampliar este elemento para que coincida con el elemento de mayor altura o anchura).<br />
  <br />
  El atributo alinear opera en el eje perpendicular al atributo orientar, mientras que el atributo enmarcar opera a lo largo del mismo eje. La Figura 2 muestra cómo establecer <code>alin="centro"</code>, <code>paquete="start"</code> para los dos elementos permite salidas completamente diferente, con la única diferencia del valor orientación.</p>
<pre class="brush: xml">
&lt;box flex="1" align="end" pack="end"&gt;
  &lt;button label="Happy"/&gt;
  &lt;button label="Sad"/&gt;
&lt;/box&gt;</pre>
<p><strong>Listado 2: como </strong><strong>responden </strong><strong>alinear y enmarcar con orientación</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3839/=figure-2.png" style="width: 331px; height: 83px;" /></p>
<p>&nbsp;</p>
<p><strong>Figura 2: Salida de listado 2</strong></p>
<h5 id="flex">flex</h5>
<p>Los elementos normalmente tienen una altura fija y anchura prefijada. El atributo <a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/flex" title="En/XUL/Attribute/Flex"><code>flex</code></a> indica que un elemento debe estirarse para tomar la altura ó anchura de una ventana.<br />
  <br />
  <code>flex</code> toma un número entero positivo como valor, éste indica cuanto debe estirarse desde el eje del atributo <code>orient </code>(<code>"Instrucción Padre"</code>). Por ejemplo, <code>flex="1"</code> indica que el elemento debe extenderse hasta llegar al eje; si hay dos elementos con atributo <code>flex="1"</code> en una fila, ellos se ajustan para tener el mismo tamaño. Puede asignar multiplicadores más altos como <code>flex="2"</code> (o mayores) para dar más tamaño al elemento. En el Listado 4, la segunda etiqueta se mostrará dos veces tan grande como el primero (figura 3).</p>
<pre class="brush: xml">
&lt;hbox&gt;
&nbsp;&nbsp;&lt;label value="label1" flex="1" style="border: 1px solid;"/&gt;
&nbsp;&nbsp;&lt;label value="label2" flex="2" style="border: 1px solid;"/&gt;
&lt;/hbox&gt;
</pre>
<p><strong>Listido 4: Crecimiento con flex</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3820/=figure-3.png" style="width: 485px; height: 23px;" /></p>
<p><strong>Figure 3: Salida del Listado 4</strong></p>
<h5 id="ordinal">ordinal</h5>
<p>Dentro de un Contenedor XUL, normalmente, los elementos se ordenan siguiendo su orden de aparición en el código fuente (trazado de izquierda a derecha o de arriba a abajo). Utilice el atributo <a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/ordinal" title="En/XUL/Attribute/Ordinal"><code>ordinal</code></a> para alterar ese orden. El atributo <code>ordinal </code>toma valores de enteros positivos, que son utilizados para ordenar la disposición de los elementos del Contenedor, en el ejemplo de la Lista 5, los botones se ordenan de la siguiente manera button3, button2 y botón 1 (Figura 4).<br />
  <br />
  Si varios elementos tienen el mismo valor ordinal, toman el orden en que aparecen en el código fuente. El valor predeterminado de ordinal es 1.</p>
<pre class="brush: xml">
&lt;vbox&gt;
&nbsp;&nbsp;&lt;button label="button1" ordinal="3"/&gt;
&nbsp;&nbsp;&lt;button label="button2" ordinal="2"/&gt;
&nbsp;&nbsp;&lt;button label="button3" ordinal="1"/&gt;
&lt;/vbox&gt;
</pre>
<p><strong>Listado 5: Cambio de order con ordinal</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3821/=figure-4.png" style="width: 489px; height: 98px;" /></p>
<p><strong>Figure 4: </strong><strong>Salida del Listado</strong><strong> 5</strong></p>
<h5 id="box_size">box size</h5>
<p>Es posible ajustar el tamaño de los elementos XUL explícitamente utilizando los atributos <code><a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/width" title="/en/XUL/Attribute/width">ancho</a></code> y <code><a href="https://developer.mozilla.org/en/XUL/Attribute/height" title="/en/XUL/Attribute/height">alto</a></code> (<span class="internal"><code>width</code></span> - <span class="internal"><code>height</code></span>), como se muestra en el Listado 6. Si va a crear elementos que pueden redimnesionarse usando flex, también puede establecer mínimos y máximos con <a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/minwidth" title="En/XUL/Attribute/Minwidth"><code>Anchomín</code></a>, <a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/minheight" title="En/XUL/Attribute/Minheight"><code>Altomín</code></a>, <a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/maxwidth" title="En/XUL/Attribute/Maxwidth"><code>Anchomáx</code></a> y <a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/maxheight" title="En/XUL/Attribute/Maxheight"><code>Altomáx</code></a>. Para usar los píxeles como unidad de tamaño.</p>
<pre class="brush: xml">
&lt;button label="Button" width="200" height="100"/&gt;
</pre>
<p><strong>Listado 6: Configurar el tamaño de un botón</strong></p>
<p>Además, como se muestra en el Listado 7, puede incrustar CSS explicitamente en elementos, a través del atributo de <a class="internal" href="https://developer.mozilla.org/en/XUL/Attribute/style" title="En/XUL/Attribute/Style"><code>estilo</code></a>, lo que le permite establecer tamaños, utilizando distintas unidades de píxeles.</p>
<pre class="brush: xml">
&lt;button label="Button" style="min-width: 10em;"/&gt;
</pre>
<p><strong>Listado 7:</strong><strong> Fijando tamaño a un boton, utilizando codigo CSS</strong></p>
<h5 id="oculto_y_enrrollado">oculto y enrrollado</h5>
<p>Los atributos <a href="/en/XUL/Attribute/hidden" title="/en/XUL/Attribute/hidden"><code>oculto</code></a> y <code><a href="/en/XUL/Attribute/collapsed" title="/en/XUL/Attribute/collapsed">enrollado</a></code> actúan como interruptores para desactivar la visualización de elementos.</p>
<p>Configuración oculto = "verdadero" (<code>hidden="true"</code>), desactiva la visualización de ese elemento. Esto tiene el mismo efecto que establecer <code>display: none</code> en CSS. Usted podría utilizar esta opción para definir un estado oculto o ausente, por ejemplo, artículos que no aparecen en los menús contextuales.</p>
<p>Ajuste enrrollado="verdadero" (<code>collapsed="true"), </code>se fija la altura y anchura como nula del elemento, pero el elemento se trata como<br />
  presente. Esto equivale a establecer la <code>visibilidad: enrrollado</code> (<code>visibility: collapse</code>), en CSS. Use <code>"</code><code>enrrollado</code><code>"</code> para barras laterales<br />
  que están actualmente en desuso.</p>
<h5 id="disabilitado">disabilitado</h5>
<p>Ésto no es apropiado para el uso en todos los elementos, puede utilizar el atributo <a class="internal" href="/en/XUL/Attribute/disabled" title="En/XUL/Attribute/Disabled"><code>disablilitado</code></a> para desactivar temporalmente la edición a un elemento que es operable por el usuario. Por lo general, los elementos con <code>desablilitado="verdadero"</code> (<code>disabled="true"</code>), aparecerán transparente ó con un gris pálido.</p>
<div class="note">
  <strong>Nota: </strong>Las intrucciones <code>oculto</code>, <code>enrollado </code>y <code>desabilitado</code>, tienen atributos lógicos, y al establecer el atributo <code>desablilitado="verdadero" </code>en XUL podría tener consecuencias no deseadas. Esto se debe a que puede haber casos en que una porcion del script o regla CSS estén escritas de tal manera que tratan al valor como verdadero, sin importar las condiciones, esto es así cuando no se ha definido un valor para el elemento. Así que cuando se cambia el valor del atributo con una función DOM, por ejemplo; no utilice <code>setAttribute </code><code>("desactivado", false)</code> - en su lugar, utilice <code>removeAttribute("desactivado").</code></div>
<h5 id="texto_de_informaci.C3.B3n_sobre_herramientas">texto de información sobre herramientas</h5>
<p>Utilice el atributo <code><a class="internal" href="/en/XUL/Attribute/tooltiptext" title="En/XUL/Attribute/Tooltiptext">tooltiptext</a></code> para mostrar un breve detalle de opciones sobre el elemento deseado. El texto introducido como valor, es el atributo que se muestra en la información..</p>
<h5 id="persistencia">persistencia</h5>
<p>Utilizar el atributo <a class="internal" href="/en/XUL/Attribute/persist" title="En/XUL/Attribute/Persist"><code>persistencia</code></a> es una manera fácil de guardar y almacenar el estado de un elemento XUL, que ha sido cambiado por el usuario. Escriba los nombres de los otros atributos cuyos valores desea almacenar como una cadena ASCII delimitada por el valor de persistencia, la próxima vez que se abra el documento XUL los valores serán guardados automáticamente<sup><a href="#footnote4" id="from_footnote4">4</a></sup>. Las caracteristivas de sistema que exploraremos en el <a class="internal" href="/En/Firefox_addons_developer_guide/Using_XPCOM—Implementing_advanced_processes" title="En/Firefox addons developer guide/Using XPCOM—Implementing advanced processes">Capítulo 4</a>, nos permitiran guardar cambios simples, sin necesidad de utilizar sentencias complejas.</p>
<div class="note">
  <strong>Note: </strong>Éstos valores son restaurados en <code>localstore.rdf</code>, dentro del perfil de usuario.</div>
<p>A fin de que el atributo<code> persistencia</code> pueda reguistrar los cambios de otros elementos, cada uno de éstos elementos tienen que tener su identificación.</p>
<h2 id="Widgets_that_can_be_used_in_XUL">Widgets usadas en XUL</h2>
<h3 id="Root_elements">Root elements</h3>
<p>Los documentos XUL utilizan diferentes elementos raíz para realizar multiples propósitos. En esta sección, vamos a ver tres tipos típicos de elementos raíz: la <code><a href="/en/DOM/window" title="/en/DOM/window">ventana</a></code>, la <code><a href="/en/XUL/page" title="/en/XUL/page">página</a></code> y los elementos de <code><a href="/dialog" title="/dialog">diálogo</a></code>.<br />
  &nbsp;</p>
<p>Root elements use the <a class="internal" href="/en/XUL/Attribute/windowtype" title="En/XUL/Attribute/Windowtype"><code>windowtype</code></a> attribute as an arbitrary identifier for the type of window. For example, Firefox uses the windowtype <code>navigator:browser</code> for its browser window and <code>Browser:Preferences</code> for its options dialog. Using methods we will cover in <a class="internal" href="/En/Firefox_addons_developer_guide/Using_XPCOM—Implementing_advanced_processes" title="En/Firefox addons developer guide/Using XPCOM—Implementing advanced processes">Capítulo 4</a>, we will see how windows can be acquired using these values as keys.</p>
<p>A window's dimensions and location on screen can be specified using the attributes <code>width</code>, <code>height</code>, <code>screenX</code>, and <code>screenY</code> (all using pixels as units). With the previously discussed <code>persist</code> attribute, you can easily store a window's size and location. Firefox uses this method to store its own window sizes and locations as well.</p>
<h4 id="General_root_elements">General root elements</h4>
<h5 id="window">window</h5>
<p>The <code>window</code> element that has appeared in examples so far is a root element used to define an ordinary window. This displays the same kind of window used for the Firefox browser window, the bookmark manager window, and many other windows. You can generally use the window element as your root element.</p>
<h5 id="page">page</h5>
<p>For sidebar panels and other XUL documents that are opened within inline frames, use the <code>page</code> element as the root element. Apart from having a different intended purpose than the window element, it is functionally no different.</p>
<h4 id="Root_elements_for_dialog_windows">Root elements for dialog windows</h4>
<h5 id="dialog">dialog</h5>
<p>Use the <code>dialog</code> element when creating options dialogs, confirmation dialogs, etc. This element takes a number of attributes, and can easily be made to display controls (buttons, etc) using widgets and layouts native to whatever platform it is running on.</p>
<p>For example, Windows places the OK button on the left and the Cancel button on the right, while Mac OS X has the opposite layout. This is what Firefox itself uses for bookmark properties and other dialogs.</p>
<h5 id="Buttons_used_in_dialog_windows">Buttons used in dialog windows</h5>
<p>A <code>dialog</code> element will display some number of buttons at its bottom. As shown in Table 1, there are four types of buttons that can be displayed, and you can set the names of the buttons you want to display as a comma-delimited list in the value of the <a class="internal" href="/en/XUL/Attribute/buttons" title="En/XUL/Attribute/buttons"><code>buttons</code></a> attribute.</p>
<p>{{ TODO("Make the table cleaner") }}</p>
<table class="standard-table">
  <tbody>
    <tr>
      <td class="header">Button name</td>
      <td class="header">Description</td>
    </tr>
    <tr>
      <td><code>accept</code></td>
      <td>The OK button.</td>
    </tr>
    <tr>
      <td><code>cancel</code></td>
      <td>The cancel button.</td>
    </tr>
    <tr>
      <td><code>help</code></td>
      <td>The help button.</td>
    </tr>
    <tr>
      <td><code>disclosure</code></td>
      <td>Either a disclosure triangle or a button.&nbsp; This is used to allow the user to toggle the display of additional information.</td>
    </tr>
  </tbody>
</table>
<p><strong>Table 1: Types of buttons that can be displayed in the dialog element</strong></p>
<p>Additionally, there are two special button names, <code>extra1</code> and <code>extra2</code>. The labels for these buttons are set using the <a class="internal" href="/en/XUL/Attribute/buttonlabelextra1" title="En/XUL/Attribute/Buttonlabelextra1"><code>buttonlabelextra1</code></a> and <a class="internal" href="/en/XUL/Attribute/buttonlabelextra2" title="En/XUL/Attribute/Buttonlabelextra2"><code>buttonlabelextra2</code></a> attributes on the root element, which take arbitrary strings as their values.</p>
<p>The action taken when pressing one of these buttons is defined by an event handler with the name <code>ondialog&lt;button name&gt;</code>. If these event handlers are not defined, pressing either the accept button or cancel button will simply close that dialog. Listing 8 shows a simple dialog example, and Figure 5 shows its output.</p>
<pre class="brush: xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;?xml-stylesheet href="chrome://global/skin/"?&gt;
&lt;dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    title="My Dialog" buttons="accept,cancel"
    ondialogaccept="saveValues(); window.close();"
    ondialogcancel="window.close();"&gt;
  &lt;checkbox label="My Option"/&gt;
&lt;/dialog&gt;
</pre>
<p><strong>Listing 8: A dialog</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3822/=figure-5.png" style="width: 330px; height: 121px;" /></p>
<p><strong>Figure 5: Output from Listing 8</strong></p>
<div class="note">
  <strong>Note: </strong>The functions behind the dialog elements discussed here require "XPConnect privileges," which are discussed in Chapter 4, so this example will only run correctly if it can run as Firefox code itself or installed extension code. Please be aware that if you attempt to open this sample directly in Firefox, it will not run correctly.</div>
<h3 id="Menus">Menus</h3>
<p>Hierarchically structured dropdown menus are the part of the user interface used for frequently accessed functions in an application or web service. In the past, a combination of HTML and JavaScript was used to produce this sort of complex UI structure, but in XUL, it can be handled easily just by writing tags.</p>
<h4 id="Creating_the_menu">Creating the menu</h4>
<p>Listing 9 shows how the <a class="internal" href="/en/XUL/menu" title="En/XUL/Menu"><code>menu</code></a> element and its related elements are combined. This produces the output seen in Figure 6.</p>
<pre class="brush: xml">
&lt;menubar&gt;
  &lt;menu label="Menu 1"&gt;
    &lt;menupopup&gt;
      &lt;menuitem label="Item 1"/&gt;
      &lt;menuitem label="Item 2"/&gt;
      &lt;menuseparator/&gt;
      &lt;menuitem label="Item 3"/&gt;
      &lt;menu label="Submenu"&gt;
        &lt;menupopup&gt;
          &lt;menuitem label="Item 4"/&gt;
          &lt;menuitem label="Item 5"/&gt;
        &lt;/menupopup&gt;
      &lt;/menu&gt;
    &lt;/menupopup&gt;
  &lt;/menu&gt;
&lt;/menubar&gt;
</pre>
<p><strong>Listing 9: A menu definition</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3834/=figure-6.png" style="width: 203px; height: 35px;" /></p>
<p><strong>Figure 6: Output from Listing 9</strong></p>
<p>Each item in a menu is marked up with the <a class="internal" href="/en/XUL/menuitem" title="En/XUL/Menuitem"><code>menuitem</code></a> tag. Use the <a class="internal" href="/en/XUL/menuseparator" title="En/XUL/Menuseparator"><code>menuseparator</code></a> element to insert a separator bar that groups items together. Both <code>menu</code> and <code>menuitem</code> elements take the <a class="internal" href="/en/XUL/Attribute/label" title="En/XUL/Attribute/Label"><code>label</code></a> attribute to set their labels.</p>
<p>Insert <code>menu</code> elements into a <a class="internal" href="/en/XUL/menubar" title="En/XUL/Menubar"><code>menubar</code></a> element to create multiple menus. You can easily create hierarchical menus by inserting <a class="internal" href="/en/XUL/menupopup" title="En/XUL/Menupopup"><code>menupopup</code></a> and <code>menu</code> elements.</p>
<p>You can even display icons in menus by adding <code>class="menuitem-iconic"</code> to a <code>menuitem</code> element, along with a <code>src</code> attribute that gives an image URI. Figure 7 shows an example of how this is displayed.</p>
<p><img alt="" class="internal" src="/@api/deki/files/3838/=figure-7.png" style="width: 155px; height: 134px;" /></p>
<p><strong>Figure 7: Menu items with icons</strong></p>
<h4 id="Executing_commands_when_selecting_menu_items">Executing commands when selecting menu items</h4>
<p>Much like dynamic HTML, event handlers are used to execute a command when a menu item is selected. To respond to mouse and keyboard inputs in HTML, the <a class="internal" href="/en/DOM/element.onclick" title="En/DOM/Element.onclick"><code>onclick</code></a> event handler is typically used to respond to mouse clicks, and the <a class="internal" href="/en/DOM/element.onkeypress" title="En/DOM/Element.onkeypress"><code>onkeypress</code></a> event handler for keyboard input.</p>
<p>XUL can also use these event handlers, but XUL also offers the <a class="internal" href="/en/XUL/Attribute/oncommand" title="En/XUL/Attribute/Oncommand"><code>oncommand</code></a> special event handler to deal with actions that often have specific meanings, such as selection by a left-click (or right-click on systems set up as left-handed) on the mouse or selection by the Enter key. Listing 10 shows an example of the <code>oncommand</code> event handler in use. Apart from <code>menuitem</code> elements, it can be used with buttons and other input controls.</p>
<pre class="brush: xml">
&lt;menuitem label="Open project page" oncommand="loadURI(this.value)"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="http://mozilla.org/"/&gt;&nbsp;</pre>
<p class="western" style="margin-bottom: 0.17in; text-align: justify;"><strong>Listing 10: The oncommand event handler</strong></p>
<p class="western" style="margin-bottom: 0.17in; text-align: justify;">Because the Gecko engine implements DOM Level 2 event handlers, you can define dynamic event listeners such as the one in Listing 11.</p>
<pre class="brush: js">
var item = document.getElementById('menu-item-custom');
function handleCommandEvent(aEvent) {
  alert('OK');
  item.removeEventListener('command', handleCommandEvent, false);
  item.parentNode.removeChild(item);
}

item.addEventListener('command', handleCommandEvent, false);
</pre>
<p><strong>Listing 11: Additions and deletions using a dynamic event listener</strong></p>
<h5 id="Special_menu_items">Special menu items</h5>
<p>Much like input elements in HTML, <code>menuitem</code> elements can operate like checkboxes and radio buttons by setting their <a class="internal" href="/en/XUL/Attribute/menuitem.type" title="En/XUL/Attribute/Menuitem.type"><code>type</code></a> attributes.</p>
<h6 id="checkbox">checkbox</h6>
<p>Adding <code>type="checkbox"</code> to a <code>menuitem</code> element will check that when it is selected, and uncheck it if it is selected again. For an example of menu items with checkboxes, see the <em>View</em> menu in Firefox, with items to show or hide the toolbar and sidebar. When one has been checked, then the <code>checked="true"</code> attribute is set.</p>
<h6 id="radio_button">radio button</h6>
<p>Assigning <code>type="radio"</code> to multiple <code>menuitem</code> elements and setting them to have the same name attribute groups them so that selecting one deselects all the others, much like radio buttons in HTML. For an example of this kind of menu item, see the <em>Character Encoding</em> submenu of the View menu in Firefox. The selected radio button has the <code>selected="true"</code> attribute set.</p>
<h6 id="Contextual_menus">Contextual menus</h6>
<p>The <a class="internal" href="/en/XUL/Attribute/context" title="En/XUL/Attribute/Context"><code>context</code></a> attribute is used to display a contextual menu or shortcut menu, that is, a custom menu that will appear when right-clicking on an element.</p>
<p>Earlier we placed the <a class="internal" href="/en/XUL/menupopup" title="En/XUL/Menupopup"><code>menupopup</code></a> child element inside a menu element; here, we use it outside the menu element. Instead, the <code>menupopup</code> element is a direct child of the root element and we invoke it using its <code>id</code> attribute, which we set as the value for the <code>context</code> attribute on any other XUL element. When we right-click on that XUL element, we reference that <code>menupopup</code> element by its <code>id</code>, and display its contents as a contextual menu. Listing 12 shows an example.</p>
<pre class="brush: xml">
&lt;button label="Send" oncommand="send();" context="button-context"/&gt;
&lt;menupopup id="button-context"&gt;
  &lt;menuitem label="Send with new tab" oncommand="sendInNewTab();"/&gt;
&lt;/menupopup&gt;&nbsp;</pre>
<h6 id="Buttons">Buttons</h6>
<p>Buttons that users can click on are defined using the <a class="internal" href="/en/XUL/button" title="En/XUL/Button"><code>button</code></a> element. To show one with an icon as shown in Figure 8, define an image's URI as the value for the image attribute.</p>
<div class="note">
  <strong>Note:</strong> To see this sample in operation, use any image as the one to display and place it in the same folder as the XUL document.</div>
<p>Using the <a class="internal" href="/en/XUL/Attribute/icon" title="En/XUL/Attribute/Icon"><code>icon</code></a> attribute instead of the image attribute allows you to display buttons with icons that are standard for the platform.</p>
<p>Possible values for the icon attribute are given in Table 2.</p>
<p><img alt="" class="internal" src="/@api/deki/files/3837/=figure-8.png" style="width: 384px; height: 40px;" /></p>
<p><strong>Figure 8: A button with an image</strong></p>
<table class="standard-table">
  <tbody>
    <tr>
      <td class="header"><code>icon</code> attribute value</td>
      <td class="header"><code>icon</code> attribute value</td>
    </tr>
    <tr>
      <td><code>accept</code></td>
      <td><code>close</code></td>
    </tr>
    <tr>
      <td><code>cancel</code></td>
      <td><code>print</code></td>
    </tr>
    <tr>
      <td><code>help</code></td>
      <td><code>add</code></td>
    </tr>
    <tr>
      <td><code>open</code></td>
      <td><code>remove</code></td>
    </tr>
    <tr>
      <td><code>save</code></td>
      <td><code>refresh</code></td>
    </tr>
    <tr>
      <td><code>find</code></td>
      <td><code>go-forward</code></td>
    </tr>
    <tr>
      <td><code>clear</code></td>
      <td><code>go-back</code></td>
    </tr>
    <tr>
      <td><code>yes</code></td>
      <td><code>properties</code></td>
    </tr>
    <tr>
      <td><code>no</code></td>
      <td><code>select-font</code></td>
    </tr>
    <tr>
      <td><code>apply</code></td>
      <td><code>select-color</code></td>
    </tr>
  </tbody>
</table>
<p><strong>Table 2: Values for the icon attribute</strong></p>
<h6 id="Toolbar_buttons">Toolbar buttons</h6>
<p>The <a class="internal" href="/en/XUL/toolbarbutton" title="En/XUL/Toolbarbutton"><code>toolbarbutton</code></a> element is the element used to define toolbar buttons. This is typically placed inside a <a class="internal" href="/en/XUL/toolbar" title="En/XUL/Toolbar"><code>toolbar</code></a> element, which defines a toolbar, but it can be used in other locations.</p>
<p>These mostly act the same as <code>button</code> elements, but as shown in Listing 13, you can change the behavior of <code>toolbarbutton</code> elements using the <code>type</code> attribute. This is illustrated in the output in Figure 9.</p>
<pre class="brush: xml">
&lt;toolbar&gt;
&nbsp;&nbsp;&lt;toolbarbutton label="Checkbox Type" type="checkbox" image="firefox.png"/&gt;
&nbsp;&nbsp;&lt;toolbarbutton label="Menu Type" type="menu" popup="button-popup" image="firefox.png"/&gt;
&nbsp;&nbsp;&lt;toolbarbutton label="Menu Button Type" type="menu-button" popup="button-popup" image="firefox.png"/&gt;
&nbsp;&nbsp;&lt;menupopup id="button-popup"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;menuitem label="Item 1"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;menuitem label="Item 2"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;menuitem label="Item 3"/&gt;
&nbsp;&nbsp;&lt;/menupopup&gt;
&lt;/toolbar&gt;
</pre>
<p><strong>Listing 13: Various toolbar buttons</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3835/=figure-9.png" style="width: 359px; height: 38px;" /></p>
<p><strong>Figure 9: Output of Listing 13</strong></p>
<h6 id="-_Checkbox-type_toolbar_buttons">- Checkbox-type toolbar buttons</h6>
<p>Specifying<code> type="checkbox"</code> results in a button that stays depressed when clicked, and pops up when clicked again. The button in its depressed state has <code>checked="true"</code> set. This is the kind of button used for the History and Bookmark buttons that can be used to customize the toolbar.</p>
<h6 id="-_Menu-type_toolbar_buttons">- Menu-type toolbar buttons</h6>
<p>Specifying <code>type="menu"</code> and adding a <code>menupop</code> child element (In Firefox 3, you can also use the <a class="internal" href="/en/XUL/panel" title="En/XUL/Panel"><code>panel</code></a> element), or setting the <a class="internal" href="/en/XUL/Attribute/popup" title="En/XUL/Attribute/Popup"><code>popup</code></a> attribute to reference a popup menu located elsewhere by its <code>id</code>, will display a popup menu when the button is pressed. Here, the button-click itself is not taken as the input; instead, a command event is issued only when a popup menu item is selected. This is the type of button used for the List All Tabs button at the right edge of the tab bar.</p>
<h6 id="-_Menu-button-type_toolbar_buttons">- Menu-button-type toolbar buttons</h6>
<p>Specifying <code>type="menu-button"</code> results in a special button that combines features of both a normal toolbar button and one with <code>type="menu"</code>, so that clicking the button itself does issue a command event. This is the type of button used for the Back and Forward buttons.</p>
<h3 id="Input_Controls">Input Controls</h3>
<p>XUL includes a number of input control elements that are very similar to HTML's form-related elements.</p>
<h4 id="Labels">Labels</h4>
<p>Use the <a class="internal" href="/en/XUL/label" title="En/XUL/Label"><code>label</code></a> element for individual text labels, such as descriptive text. The value of the <code>value</code> attribute is the text that will be displayed. The <code>control</code> attribute takes as its value an <code>id</code> reference to another XUL element with that <code>id</code>; clicking that label or giving it focus can be used to pass the focus to the referenced XUL element.</p>
<p>This can also be used to display longer chunks of text. If you want to insert long strings that automatically wrap to the window’s width, you can use the <code>flex</code> attribute as shown in Listing 14, which will automatically expand it; in this case you don't set the value using the <code>value</code> attribute, instead you should place it in the contents of the element. Figure 10 shows the output from this listing.</p>
<pre class="brush: xml">
&lt;hbox&gt;
&nbsp;&nbsp;&lt;label flex="1"&gt;
&nbsp;&nbsp;Proceeding with this action will send your personal information to a server. Are you sure you want to proceed?
&nbsp;&nbsp;&lt;/label&gt;
&lt;/hbox&gt;
</pre>
<p><strong>Listing 14: Handling long text in a label</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3830/=figure-10.png" style="width: 309px; height: 57px;" /></p>
<p><strong>Figure 10: Output from Listing 14</strong></p>
<h5 id="Shortening_labels">Shortening labels</h5>
<p>Between the <code>label</code> element and the <code>label</code> attribute on other XUL elements, there can be a lot of labeled elements in XUL. A common attribute that can be set on all of them is the <a class="internal" href="/en/XUL/Property/crop" title="En/XUL/Property/Crop"><code>crop</code></a> attribute.</p>
<p>By applying the <code>crop</code> attribute to elements with the <code>label</code> attribute set or to the <code>label</code> element, part of the label will be replaced by an ellipsis (…) if it overflows the width of the parent element. The part of the label that gets cropped can be controlled by setting its value to <code>start</code>, <code>center</code>, or <code>end</code>.</p>
<p>You can set the maximum width of the box using the CSS <a class="internal" href="/en/CSS/max-width" title="En/CSS/Max-width"><code>max-width</code></a> property.</p>
<h4 id="Checkboxes">Checkboxes</h4>
<p>The checkbox shown in Figure 11 was marked up using the <a class="internal" href="/en/XUL/checkbox" title="En/XUL/Checkbox"><code>checkbox</code></a> element. When it is in its checked state, its checked attribute is set to true.</p>
<pre class="brush: xml">
&lt;checkbox label="Checkbox checked" checked="true"/&gt;
&lt;checkbox label="Checkbox unchecked" checked="false"/&gt;
</pre>
<p><strong>Listing 11: Checkboxes in different state</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3836/=figure-11.png" style="width: 189px; height: 52px;" /></p>
<p><strong>Figure 11: Output from listing 11</strong></p>
<h4 id="Radio_Buttons">Radio Buttons</h4>
<p>Radio buttons in HTML are multiple input elements grouped by assigning them all the same <code>name</code> attribute. In XUL, this is expressed using a combination of two elements: <a class="internal" href="/en/XUL/radiogroup" title="En/XUL/Radiogroup"><code>radiogroup</code></a> and <a class="internal" href="/en/XUL/radio" title="En/XUL/Radio"><code>radio</code></a>. You set exclusive options by inserting multiple radio elements into the content of one <code>radiogroup</code> element; the currently selected <code>radio</code> element will have <code>selected="true"</code> set.</p>
<p>The <code>radio</code> element can be uniquely identified by setting its <code>value</code> attribute. When that <code>radio</code> element is selected, the value of its <code>value</code> attribute is copied to the <code>radiogroup</code>, so that you can check for the selected radio button simply by fetching the <code>radiogroup</code> element’s <code>value</code> attribute.</p>
<p>There may be situations where you want to locate a <code>radio</code> element outside of a <code>radiogroup</code> element. By combining it with <code>hbox</code> and <code>vbox</code>, you can write code similar to that shown in Listing 15, which will produce output as shown in Figure 12.</p>
<pre class="brush: xml">
&lt;radiogroup orient="vertical"&gt;
&nbsp;&nbsp;&lt;hbox&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;radio label="Top Left"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;radio label="Top Right"/&gt;
&nbsp;&nbsp;&lt;/hbox&gt;
&nbsp;&nbsp;&lt;hbox&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;radio label="Bottom Left"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;radio label="Bottom Right"/&gt;
&nbsp;&nbsp;&lt;/hbox&gt;
&lt;/radiogroup&gt;
</pre>
<p><strong>Listing 15: A complex layout of radio buttons</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3831/=figure-12.png" style="width: 226px; height: 55px;" /></p>
<p><strong>Figure 12: Output from Listing 15</strong></p>
<h4 id="Text_boxes">Text boxes</h4>
<p>Use the <a class="internal" href="/en/XUL/textbox" title="En/XUL/Textbox"><code>textbox</code></a> element to accept text input. In HTML, there are two separate elements—<code>input</code> for one line of text, and <code>textarea</code> for multiple lines. But both these functions are handled by <code>textbox</code> as shown in Listing 16, which produces output as shown in Figure 13.</p>
<p>The <code>textbox</code> element uses the <code>value</code> attribute to set its default content; content entered by the user also can be captured using the <code>value</code> attribute. To set a maximum length in characters, declare the <a class="internal" href="/en/XUL/Attribute/maxlength" title="En/XUL/Attribute/Maxlength"><code>maxlength</code></a> attribute with a positive integer value. Setting <code>type="password"</code> will turn the <code>textbox</code> into a special password-entry field, in which characters are hidden as they're typed.</p>
<p>Every character entered into a <code>textbox</code> generates an <code>input</code> event. If you use the <a class="internal" href="/en/XUL/Attribute/oninput" title="En/XUL/Attribute/Oninput"><code>oninput</code></a> event handler, you can implement commands that reflect user input in real time.</p>
<pre class="brush: xml">
&lt;vbox align="start"&gt;
&nbsp;&nbsp;&lt;textbox/&gt;
&nbsp;&nbsp;&lt;textbox multiline="true" rows="5" cols="15"/&gt;
&lt;/vbox&gt;
</pre>
<p><strong>Listing 16: <code>textbox</code> examples</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3832/=figure-13.png" style="width: 197px; height: 148px;" /></p>
<p><strong>Figure 13: Output from Listing 16</strong></p>
<h5 id="Autocomplete">Autocomplete</h5>
<p>Adding <code>type="autocomplete"</code> to a <code>textbox</code> element enables an automatic completion function for it.</p>
<p>Note that to actually use this function, you must also specify a search target for the autocomplete text using the <a class="internal" href="/en/XUL/Attribute/autocompletesearch" title="En/XUL/Attribute/Autocompletesearch"><code>autocompletesearch</code></a> attribute. If you want to use the <em>Location Bar</em> history, set the value for this to <code>history</code>; if you want it to be the <em>Search Bar</em> history, use <code>search-history</code>; and if you want it to be another form’s input history, use<code> form-history</code>; this attribute can take one value or multiple space-delimited values.</p>
<p>Also, in order to actually read in a history for autocomplete, you will need XPConnect privileges, which we will cover in <a class="internal" href="/En/Firefox_addons_developer_guide/Using_XPCOM—Implementing_advanced_processes" title="En/Firefox addons developer guide/Using XPCOM—Implementing advanced processes">Chapter 4</a>.</p>
<h4 id="Menu_List">Menu List</h4>
<p>Use the <a class="internal" href="/en/XUL/menulist" title="En/XUL/Menulist"><code>menulist</code></a> element to create a control for making selections from a drop-down list. As shown in Listing 17, this is implemented in combination with the <a class="internal" href="/en/XUL/menupopup" title="En/XUL/Menupopup"><code>menupopup</code></a> element; it produces output as shown in Figure 14.</p>
<p>A click reveals the drop-down list; when an item is selected, the values of that item’s <code>label</code> and <code>value</code> attributes are copied to the <code>label</code> and <code>value</code> attributes of the <code>menulist</code> element itself. By default, the first menu item is selected, but any menu can be preselected by adding <code>selected="true"</code> to it.</p>
<pre class="brush: xml">
&lt;menulist&gt;
&nbsp;&nbsp;&lt;menupopup&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;menuitem label="Item 1" value="1"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;menuitem label="Item 2" value="2"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;menuitem label="Item 3" value="3"/&gt;
&nbsp;&nbsp;&lt;/menupopup&gt;
&lt;/menulist&gt;
</pre>
<p><strong>Listing 17: A menulist example</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3833/=figure-14.png" style="width: 279px; height: 35px;" /></p>
<p><strong>Figure 14: Output from Listing 17</strong></p>
<p>By adding <code>editable="true"</code> to the <code>menulist</code> element, you can accept arbitrary text input in addition to a list selection, as is often used on font selection menus in word processors.</p>
<h3 id="Special_elements">Special elements</h3>
<h4 id="Embedding_images">Embedding images</h4>
<p>In addition to writing direct JavaScript code in event handlers, XUL also allows you to embed scripts using a <a class="internal" href="/en/XUL/script" title="En/XUL/Script"><code>script</code></a> element, just like in HTML; this can be used to read in an external script or to place the code in the <code>script</code> element's content.</p>
<p>If you are embedding a script in a page, you should bracket your code inside a <code>CDATA</code> section as shown in Listing 18; this will avoid errors caused by mistakenly reading "&amp;" and other characters as the beginnings of entity references.</p>
<pre class="brush: xml">
&lt;script type="application/javascript"&gt;&lt;![CDATA[
&nbsp;&nbsp;var nodes = gBrowser.mTabContainer.childNodes;
&nbsp;&nbsp;for (var i = 0; i &lt; nodes.length; i++)
&nbsp;&nbsp;alert(nodes[i].label);
]]&gt;&lt;/script&gt;
</pre>
<p><strong>Listing 18: Embedding a script in XUL</strong></p>
<p><strong>Note:</strong> Although embedding JavaScript is permitted, it's generally encouraged that you instead place your JavaScript code in an external file.</p>
<h4 id="Browser_and_tabbrowser">Browser and tabbrowser</h4>
<p>XUL allows you to use inline frames. You can set the <a class="internal" href="/en/XUL/Attribute/src" title="En/XUL/Attribute/Src"><code>src</code></a> attribute of an <a class="internal" href="/en/XUL/iframe" title="En/XUL/Iframe"><code>iframe</code></a> element to the URI of another XUL document or web page, and it will be displayed there. But <code>iframes</code> are rarely used in XUL—in practice, the <a class="internal" href="/en/XUL/browser" title="En/XUL/Browser"><code>browser</code></a> element is used more often.</p>
<p>The <code>browser</code> element is essentially a more powerful version of an inline frame, equipped with all the basic functions of a web browser. Unlike an <code>iframe</code>, a <code>browser</code> element has the ability to navigate backward and forward through pages and includes the ability to prevent scripts in embedded frames from accessing outside the frame. For building applications linked to external web pages, this is a more secure and more convenient approach.</p>
<p>The <a class="internal" href="/en/XUL/tabbrowser" title="En/XUL/Tabbrowser"><code>tabbrowser</code></a> element is even more capable than the browser element because it includes the basic tab-handling features from Firefox. To use this requires XPConnect privileges, the same as autocomplete does; this will be covered in <a class="internal" href="/En/Firefox_addons_developer_guide/Using_XPCOM—Implementing_advanced_processes" title="En/Firefox addons developer guide/Using XPCOM—Implementing advanced processes">Chapter 4</a>.</p>
<h5 id="Opening_a_page">Opening a page</h5>
<p>If you specify a URI value for the <code>src</code> attribute in the browser element, that URI will be opened by default. If the <code>src</code> attribute's value changes, you can dynamically open a different web page or XUL document.</p>
<p>Functions like Back, Forward, Reload can all be called using the <a class="internal" href="/en/XUL/Method/goBack" title="En/XUL/Method/GoBack"><code>goBack()</code></a>, <a class="internal" href="/en/XUL/Method/goForward" title="En/XUL/Method/GoForward"><code>goForward</code><code>()</code></a>, and <a class="internal" href="/en/XUL/Method/reload" title="En/XUL/Method/Reload"><code>reload()</code></a> methods. Using the <a class="internal" href="/en/XUL/Method/stop" title="En/XUL/Method/Stop"><code>stop()</code></a> method stops loading the page currently in the process of being opened.</p>
<h5 id="Access_restrictions">Access restrictions</h5>
<p>With frames defined using HTML's <a class="internal" href="/En/HTML/Element/Frame" title="En/HTML/Element/Frame"><code>frame</code></a> and <code>iframe</code> elements, it is possible for a child frame to access its parent and ancestor frames by getting the <a class="internal" href="/en/DOM/window.parent" title="En/DOM/Window.parent"><code>parent</code></a> and <a class="internal" href="/en/DOM/window.top" title="En/DOM/Window.top"><code>top</code></a> properties of window objects. For an application that can open any web page, this could give a script on a web page access to an XUL document's frame, creating a dangerous opening for personal information to leak out.</p>
<p>In the interests of security, you can enforce access restrictions by declaring <code>type="content"</code> on a <code>browser</code> element. When you do this, any web page that gets opened will see itself as the topmost frame. If you are developing an application with an interface that can open web pages, I recommend that you always use this declaration to limit access to the parent frame.</p>
<p>In certain circumstances, you may want to declare <code>type="content-primary"</code>. A browser element with this declaration is treated as a special browser among other XUL documents, such that the window object displaying its web page can be accessed using the <a class="internal" href="/en/DOM/window.content" title="En/DOM/Window.content"><code>window.content</code></a> property. In Firefox itself, the content region of the active tab is declared as a browser element with <code>type="content-primary"</code>.</p>
<h4 id="Keyboard_shortcuts">Keyboard shortcuts</h4>
<p>To implement keyboard shortcuts (pressing a key while holding down modifier keys like Control or Shift.) in a <a class="internal" href="/en/DHTML" title="En/DHTML">DHTML</a>-based interface, you need a script that will intercept keyboard inputs.</p>
<p>In XUL, you can define keyboard shortcuts simply by using the <a class="internal" href="/en/XUL/key" title="En/XUL/Key"><code>key</code></a> element, as shown in Listing 19.</p>
<pre class="brush: xml">
&lt;key id="key-save" key="s" modifiers="accel,shift" oncommand="save();"/&gt;
&lt;key id="key-scroll-up" keycode="VK_PAGE_UP" oncommand="advanceFocus(-1);"/&gt;
</pre>
<p><strong>Listing 19: Defining keyboard shortcuts</strong></p>
<p>To make letters, numbers, symbols, or the space bar act as triggers, declare that character as the key attribute’s value. You can use either uppercase and lowercase letters and they will be handled the same.</p>
<p>For triggers on other special keys, use the <a class="internal" href="/en/XUL/Attribute/keycode" title="En/XUL/Attribute/Keycode"><code>keycode</code></a> attribute with the appropriate keycode name value. In general you can use the keycode name for any key; the most commonly used ones are shown in Table 3.</p>
<table class="standard-table">
  <tbody>
    <tr>
      <td class="header">Key</td>
      <td class="header">Keycode name</td>
    </tr>
    <tr>
      <td>Return</td>
      <td><code>VK_RETURN</code></td>
    </tr>
    <tr>
      <td>Enter</td>
      <td><code>VK_ENTER</code></td>
    </tr>
    <tr>
      <td>Backspace</td>
      <td><code>VK_BACK_SPACE</code></td>
    </tr>
    <tr>
      <td>Delete</td>
      <td><code>VK_DELETE</code></td>
    </tr>
    <tr>
      <td>Escape</td>
      <td><code>VK_ESCAPE</code></td>
    </tr>
    <tr>
      <td>↑</td>
      <td><code>VK_UP</code></td>
    </tr>
    <tr>
      <td>↓</td>
      <td><code>VK_DOWN</code></td>
    </tr>
    <tr>
      <td>←</td>
      <td><code>VK_LEFT</code></td>
    </tr>
    <tr>
      <td>→</td>
      <td><code>VK_RIGHT</code></td>
    </tr>
  </tbody>
</table>
<h5 id="Table_3.3A_Typical_keycode_names"><strong>Table 3: Typical keycode names</strong></h5>
<p>&nbsp;</p>
<h5 id="Using_modifier_keys">Using modifier keys</h5>
<p>Use the <a class="internal" href="/en/XUL/Attribute/modifiers" title="En/XUL/Attribute/Modifiers"><code>modifiers</code></a> attribute with one or more of the following comma-delimited values: "control", "alt", "shift", and "meta" in order to limit the use of keyboard shortcuts to only operate when those modifier keys are pressed together with another key. The standard modifier key on Windows and Linux is Control; on Mac OS it is Command. An easy way to automatically use the modifier key appropriate for the current platform is to set the modifier key to "accel", which maps to Control on Windows and Linux, Command on Mac OS.</p>
<div class="note">
  <strong>Note:</strong> The "meta"&nbsp;key is the Command key on Mac OS X (the one with the cloverleaf design on it).</div>
<p>The <code>key</code> element itself is never displayed on screen. In order to display defined keyboard shortcuts as shown in Figure 15, reference the <code>key</code> element's <code>id</code> from the <code>menu</code> or <code>menuitem</code> element’s <a class="internal" href="/en/XUL/Attribute/key" title="En/XUL/Attribute/Key"><code>key</code></a> attribute.</p>
<p>{{ TODO("Figure 15: Displaying keyboard shortcuts in menu items:Menu 1/Save/Scroll") }}</p>
<h3 id="Elements_related_to_box_layout">Elements related to box layout</h3>
<p>XUL includes a number of elements used strictly to organize the layout of screen widgets.</p>
<h4 id="spacer">spacer</h4>
<p>Use the <a class="internal" href="/en/XUL/spacer" title="En/XUL/Spacer"><code>spacer</code></a> element if you want to open up the space between buttons. You can use the <a class="internal" href="/en/XUL/Attribute/flex" title="En/XUL/Attribute/Flex"><code>flex</code></a> attribute or <a class="internal" href="/en/XUL/Attribute/style" title="En/XUL/Attribute/Style"><code>style</code></a> attribute to make whitespace stretch or set it to a certain size.</p>
<h4 id="grid">grid</h4>
<p>In the same way that the <code>table</code> element is used to lay out content in HTML, you can use the <a class="internal" href="/en/XUL/grid" title="En/XUL/Grid"><code>grid</code></a> element in XUL. As shown in Listing 20, you first declare the number of columns, and then define the content of each row. The output of this sample is shown in Figure 16. You can also code it so that the rows come first, declaring the number of rows and then defining content by column.</p>
<p>The <code>rowspan</code> and <code>colspan</code> attributes available in HTML tables are not available in XUL grids.</p>
<pre class="brush: xml">
&lt;grid&gt;
&nbsp;&nbsp;&lt;columns&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;column/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;column flex="1"/&gt;
&nbsp;&nbsp;&lt;/columns&gt;
&nbsp;&nbsp;&lt;rows&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;row align="center"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;label value="User ID"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;textbox/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/row&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;row align="center"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;label value="Name"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;textbox/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/row&gt;
&nbsp;&nbsp;&lt;/rows&gt;
&lt;/grid&gt;
</pre>
<p><strong>Listing 20: Layout using the grid</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3827/=figure-16.png" style="width: 326px; height: 65px;" /></p>
<p><strong>Figure 16: Output from Listing 20</strong></p>
<h4 id="stack">stack</h4>
<p>Use the <a class="internal" href="/en/XUL/stack" title="En/XUL/Stack"><code>stack</code></a> element to overlap multiple widgets. The <code>stack</code> element differs from a normal box in that all the elements in it are layered over each other, working from the bottom up. Listing 21 shows an example of a thermometer-style progress bar, with its output shown in Figure 17.</p>
<pre class="brush: xml">
&lt;stack&gt;
&nbsp;&nbsp;&lt;progressmeter mode="normal" value="50"/&gt;
&nbsp;&nbsp;&lt;hbox align="center"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;label value="In progress…"/&gt;
&nbsp;&nbsp;&lt;/hbox&gt;
&lt;/stack&gt;
</pre>
<p><strong>Listing 21: Overlapping with stack</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3828/=figure-17.png" style="width: 329px; height: 22px;" /></p>
<p><strong>Figure 17: Progress Bar</strong></p>
<h4 id="tab">tab</h4>
<p>Use the <a class="internal" href="/en/XUL/tab" title="En/XUL/Tab"><code>tab</code></a> element to divide multiple pages, as used in the <em>Properties</em> dialog; use the <a class="internal" href="/en/XUL/tabbox" title="En/XUL/Tabbox"><code>tabbox</code></a> element to group related elements. This is demonstrated in Listing 22, with its output shown in Figure 18.</p>
<pre class="brush: xml">
&lt;tabbox&gt;
&nbsp;&nbsp;&lt;tabs&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;tab label="tab1"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;tab label="tab2" selected="true"/&gt;
&nbsp;&nbsp;&lt;/tabs&gt;
&nbsp;&nbsp;&lt;tabpanels&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;tabpanel&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;checkbox label="check1"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tabpanel&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;tabpanel orient="vertical"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;checkbox label="check2"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;checkbox label="check3"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tabpanel&gt;
&nbsp;&nbsp;&lt;/tabpanels&gt;
&lt;/tabbox&gt;
</pre>
<p><strong>Listing 22: Tabs in use</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3829/=figure-18.png" style="width: 332px; height: 95px;" /></p>
<p><strong>Figure 18: Output from listing 22</strong></p>
<h2 id="Other_XUL_functions">Other XUL functions</h2>
<h3 id="Overlays">Overlays</h3>
<p>One of XUL’s distinctive features is overlays. These give you the ability to combine multiple XUL documents and process them as a single XUL document. In Firefox, this is used to modularize functions and implement extensions.</p>
<p>By inserting an <code>xul-overlay</code> processing instruction between the XML declaration and the opening tag of the root element, the XUL document specified by the <code>xul-overlay</code> will be read in at the same time as the current XUL document. The XUL document that actually gets displayed will be a combination of the original XUL document and the one specified in <code>xul-overlay</code>.</p>
<p>Try typing up Listing 23 and saving it as <code>base.xul</code>. Take a look at the overlay example used by this XUL document.</p>
<pre class="brush: xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;?xml-stylesheet href="chrome://global/skin/"?&gt;
&lt;?xul-overlay href="overlayDocument.xul"?&gt;
&lt;window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
&nbsp;&nbsp;&lt;hbox id="box1"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;label id="label1" value="Text label"/&gt;
&nbsp;&nbsp;&lt;/hbox&gt;
&nbsp;&nbsp;&lt;hbox id="box2"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;label id="label2" value="Text label"/&gt;
&nbsp;&nbsp;&lt;/hbox&gt;
&lt;/window&gt;
</pre>
<p><strong>Listing 23: </strong><code><strong>base.xul</strong></code></p>
<h4 id="Appending_elements">Appending elements</h4>
<p>When defining an XUL document to open as an overlay, use an <a class="internal" href="/en/XUL/overlay" title="En/XUL/Overlay"><code>overlay</code></a> element as the root element. Save the text of Listing 24 as <code>overlayDocument.xul</code> in the same directory as <code>base.xul</code>.</p>
<p>Here, we’ll open <code>base.xul</code> in the Firefox window. <code>overlayDocument.xul</code> gets read in at the same time as <code>base.xul</code>, resulting in what we see in Figure 19, where <code>overlayDocument.xul</code> gets appended to the end of <code>base.xul</code>.</p>
<pre class="brush: xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
&nbsp;&nbsp;&lt;button label="Button 1"/&gt;
&nbsp;&nbsp;&lt;button label="Button 2"/&gt;
&nbsp;&nbsp;&lt;button label="Button 3"/&gt;
&lt;/overlay&gt;
</pre>
<p><strong>Listing 24: </strong><code><strong>overlayDocument.xul</strong></code></p>
<p><img alt="" class="internal" src="/@api/deki/files/3825/=figure-19.png" style="width: 404px; height: 138px;" /></p>
<p><strong>Figure 19: Output from listings 23 and 24</strong></p>
<h4 id="Merging_and_inserting_elements">Merging and inserting elements</h4>
<p>By inserting <code>id</code> attributes into the elements being appended in the XUL overlay document, elements in the base document with the same <code>id</code> values will have their attributes and values merged with the overlay document.</p>
<p>Try overwriting the contents of <code>overlayDocument.xul</code> with Listing 25 and re-saving.</p>
<pre class="brush: xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
&nbsp;&nbsp;&lt;hbox id="box1" align="center" style="border: 1px solid; margin: 1em;"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;button label="Button 1"/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;button label="Button 2" insertbefore="label1"/&gt;
&nbsp;&nbsp;&lt;/hbox&gt;
&nbsp;&nbsp;&lt;button label="Button 3"/&gt;
&lt;/overlay&gt;
</pre>
<p><strong>Listing 25: Substitute code for </strong><code><strong>overlayDocument.xul</strong></code></p>
<p>Let's open <code>base.xul</code> in a Firefox window again. As shown in Figure 20, the <code>style</code> attribute from the element with the <code>id</code> "box1" in the overlay document has been merged with the markup for the button with that <code>id</code> in the base document, and inserted into the box.</p>
<p><img alt="" class="internal" src="/@api/deki/files/3826/=figure-20.png" style="width: 406px; height: 116px;" /></p>
<p>&nbsp;<strong>Figure 20: Output from listing 23 and 25</strong></p>
<p>Furthermore, following the declaration <code>insertbefore="label1"</code>, the "button2" button now has been inserted before the element with the <code>id</code> "label1". Conversely, if we wanted to insert it directly after, we could have used the attribute <code>insertafter</code>. We can also use the <a class="internal" href="/en/XUL/Attribute/position" title="en/XUL/Attribute/Position"><code>position</code></a> attribute as a way to locate an element numerically at any position; for example, using <code>position="4"</code> would insert it as the fourth element.</p>
<h3 id="External_entities">External entities</h3>
<p>Being a form of XML, XUL can also use entity references based on DTDs (document type definitions) as shown in Listing 26. Note that external DTD files are limited to what is given in the chrome URL, which will be discussed in Chapter 5. Please be aware that ordinary DTD files on the web or in a local directory will not be opened.</p>
<div class="note">
  <strong>Note:</strong> You may use a relative path to access a chrome URL from an XUL document.</div>
<pre class="brush: xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;?xml-stylesheet href="chrome://global/skin/"?&gt;
&lt;!DOCTYPE window SYSTEM "chrome://testapp/locale/testapp.dtd"&gt;
&lt;window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
&nbsp;&nbsp;&lt;button label="&amp;button.1.label;"/&gt;
&nbsp;&nbsp;&lt;button label="&amp;button.2.label;"/&gt;
&lt;/window&gt;</pre>
<p><strong>Listing 26: Reading in external entities</strong></p>
<pre class="brush: xml">
&lt;!ENTITY button.1.label "Firefox"&gt;
&lt;!ENTITY button.2.label "Thunderbird"&gt;
</pre>
<p><strong>Listing 27: testapp.dtd</strong></p>
<h3 id="Substituting_CSS_for_attribute_declarations">Substituting CSS for attribute declarations</h3>
<p>The Gecko rendering engine includes a number of CSS properties with <code>-moz-</code> prepended to them; these are <a class="internal" href="/en/CSS_Reference/Mozilla_Extensions" title="en/CSS Reference/Mozilla Extensions">custom properties for XUL</a> that have been implemented prior to being a W3C recommendation. The ones shown in Table A below correspond to the common attributes in XUL. In fact, those XUL attributes operate through these CSS properties.</p>
<p>The values declared for these CSS properties are the same integers or keywords used by the XUL attributes. While we don't recommend that you use these properties in ordinary XUL development, they can be useful for customizing the Firefox UI without scripting by using <code>userChrome.css</code>. For example, if you save the contents of Listing 28 as <code>userChrome.css</code> and save that in the <code>chrome</code> directory under the user profile directory, the tab bar will appear at the bottom of the content area.</p>
<table class="standard-table">
  <tbody>
    <tr>
      <td class="header">XUL&nbsp;attribute</td>
      <td class="header">CSS property</td>
      <td class="header">Example</td>
    </tr>
    <tr>
      <td><a class="internal" href="/en/XUL/Attribute/orient" title="En/XUL/Attribute/Orient"><code>orient</code></a></td>
      <td><code>-moz-box-orient</code></td>
      <td>
        <p><code>-moz-box-orient: vertical;</code></p>
      </td>
    </tr>
    <tr>
      <td><a class="internal" href="/en/XUL/Attribute/align" title="En/XUL/Attribute/Align"><code>align</code></a></td>
      <td>
        <p><code>-moz-box-align</code></p>
      </td>
      <td>
        <p><code>-moz-box-align: start;</code></p>
      </td>
    </tr>
    <tr>
      <td><a class="internal" href="/en/XUL/Attribute/pack" title="En/XUL/Attribute/Pack"><code>pack</code></a></td>
      <td>
        <p><code>-moz-box-pack</code></p>
      </td>
      <td>
        <p><code>-moz-box-pack: stretch;</code></p>
      </td>
    </tr>
    <tr>
      <td><code><a class="internal" href="/en/XUL/Attribute/flex" title="En/XUL/Attribute/Flex">flex</a></code></td>
      <td><code>-moz-box-flex</code></td>
      <td><code>-moz-box-flex:&nbsp;1;</code></td>
    </tr>
    <tr>
      <td><code><a class="internal" href="/en/XUL/Attribute/ordinal" title="En/XUL/Attribute/Ordinal">ordinal</a></code></td>
      <td><code>-moz-box-ordinal-group</code></td>
      <td><code>-moz-box-ordinal-group: 2</code></td>
    </tr>
  </tbody>
</table>
<p><strong>Table 4: CSS properties corresponding to XUL attributes</strong></p>
<pre class="brush: css">
tabbrowser .tabbrowser-strip {
&nbsp;&nbsp;-moz-box-ordinal-group: 2;
}
tabbrowser tabpanels {
&nbsp;&nbsp;-moz-box-ordinal-group: 1;
}
</pre>
<p><strong>Listing 28: A user stylesheet that locates the tab bar at the bottom</strong></p>
<h3 id="Icons_corresponding_to_filetypes">Icons corresponding to filetypes</h3>
<p>Firefox allows you to use a special URI scheme, <code>moz-icon</code>, that produces filetype icons that are standard for whatever platform it is running on. For example, to display a 16x16 icon for a file with a .pdf dot-extension (a PDF file), you would write <code><a class="external" href="moz-icon://.PDF?size=16" rel="freelink">moz-icon://.PDF?size=16</a></code>.</p>
<p>You can reference icons using content type as a key rather than dot-extension; for example, you could display a plain-text icon using <code><a class="external" href="moz-icon://goat?size=16&amp;contentType=text/plain" rel="freelink">moz-icon://goat?size=16&amp;contentType=text/plain</a></code>.</p>
<p>You can also display specific icons using the markup moz-icon:file URL?size=size.</p>
<p>The button icons mentioned in Table 2 also can be called using <code>moz-icon</code> URIs, using the markup <code><a class="external" href="moz-icon://stock/gtk-button" rel="freelink">moz-icon://stock/gtk-button</a> name?size=button</code>. Note, however, that this does not work in Linux environments.</p>
<h3 id="Spin_buttons">Spin buttons</h3>
<p>You can add a <code>type="number"</code> declaration to a <a class="internal" href="/en/XUL/textbox" title="En/XUL/Textbox"><code>textbox</code></a> element, making it a <code>textbox</code> specifically for entering numeric values. This will cause the spin buttons seen in Figure 21 to appear. Additional attributes that accompany this are <a class="internal" href="/en/XUL/Attribute/min" title="En/XUL/Attribute/Min"><code>min</code></a> and <a class="internal" href="/en/XUL/Attribute/max" title="En/XUL/Attribute/Max"><code>max</code></a> to set minimum and maximum values, and <code><a class="internal" href="/en/XUL/Attribute/increment" title="En/XUL/Attribute/Increment">increment</a></code>, which sets the amount by which one click on the spin buttons will change the displayed value.</p>
<p><img alt="" class="internal" src="/@api/deki/files/3824/=figure-21.png" style="width: 214px; height: 40px;" /></p>
<p><strong>Figure 21: A textbox for numeric input</strong></p>
<h3 id="Sliders">Sliders</h3>
<p>The <a class="internal" href="/en/XUL/scale" title="En/XUL/Scale"><code>scale</code></a> element is used similarly to the volume slider in Windows, allowing the user to vary a value by moving a slider up/down or left/right (see Listing 28 and Figure 22).</p>
<div class="note">
  <strong>Note:</strong> Although this control is also known as a slider, the slider element already exists in XUL as a part of a scrollbar, so this element has been named "scale".</div>
<pre class="brush: xml">
&lt;hbox&gt;
  &lt;scale orient="horizontal" min="-100" max="100" value="0"/&gt;
  &lt;scale orient="vertical" min="0" max="100" value="50"/&gt;
&lt;/hbox&gt;
</pre>
<p><strong>Listing 29: The scale element</strong></p>
<p><img alt="" class="internal" src="/@api/deki/files/3823/=figure-22.png" style="width: 130px; height: 106px;" /></p>
<p><strong>Figure 22: Output from Listing 29</strong></p>
<p>{{ PreviousNext("Firefox addons developer guide/Technologies used in developing extensions", "Firefox addons developer guide/Using XPCOM—Implementing advanced processes") }}</p>
Revertir a esta revisión