Otra más de extensiones para Feedness

(13 comentarios)

Bien aventurados los usuarios de Feedness y Firefox amantes del riesgo, porque yo os digo, que vosotros heredareis Feedness Live 0.1.1 y Notificador Feedness 0.1.

La primera extensión, Feedness Live, permite añadir feeds a este agregador a través de los Live Bookmarks de Firefox. En esta versión la única novedad es el cambio de la URL de sindicación por otra que mantiene la información del feed a agregar en el caso de que tengas que loguearte primero, cosa que no hacía la versión 0.1 (gracias Walter por la información). En el caso de que tengais instalada la versión 0.1 os recomendaría desinstalarla antes de instalar esta, por si acaso :noworry:

La segunda extensión, añade un icono a la barra de estado que nos avisa cuando aparezcan nuevas entradas en los feeds que tenemos agregados a Feedness. La comprobación de nuevas entradas se realiza cada 10 minutos, y ahora mismo no hay posibilidad de cambiarlo, se encuentra en la lista de ToDo. Otras cosas por hacer para nuevas versiones será indicar el número de nuevas entradas, y no sólo que existen nuevas entradas; y lo más importante, loguearse en el caso de que el usuario no lo esté, ya que en la versión actual, si el usuario no está logueado, no se le avisa y simplemente se muestra el icono indicando que no hay entradas nuevas.

Para instalar las extensiones tendréis que añadir este sitio a la lista blanca en la barra de aviso que aparecerá al pulsar sobre la extensión, si es que confiáis en mi. (muahahahaha)

Sugerencias e insultos varios en los comentarios. No me responsabilizo de que las extensiones destrocen vuestra colección de música de Operación Triunfo, de que se coman a vuestro perro, os instalen Windows XP y otros infortunios o desastres varios.

Feedness Live 0.1

(16 comentarios)

Como decía Oscar J. Baeza, de AfterDusk, a Feedness aún le quedan unas pocas herramientas para estar al nivel de Bloglines; además de la correción de algunos fallos, pero al ser una beta por ahora se lo vamos a perdonar.

Entre estas herramientas tenemos un notificador para Linux y Mac OS y otro para Firefox multiplataforma; y por otro lado, algo parecido a la extensión LiveLines de Firefox, que permitiría utilizar el botón de feeds de Firefox para añadir los feeds a Feedness, en lugar de a los Live Bookmarks de Firefox, los cuales, francamente, no son demasiado útiles.

Escribir un notificador es algo un poco más complicado que lo segundo, más aún cuando el código de LiveLines es de libre modificación, aunque no sea GPL. Asi que para usuarios de Firefox y nuevos usuarios de Feedness he escrito (modificado cuatro líneas, borrado cuatro y creado cuatro nuevas) Feedness Live, el equivalente a LiveLines para Feedness.

Para instalarlo, simplemente pulsad sobre instalar, y permitid a esta web la instalación de archivos xpi cuando Firefox muestre la barra de aviso (si confiáis en mí xD). Después bastará hacer click sobre el botón de feeds (botón naranja, abajo a la derecha cuando Firefox detecta que existen feeds en esa web) para ver los feeds disponibles para la página actual y pulsar sobre uno de ellos para añadirlo a Feedness. Por supuesto, tendréis que estar identificados en Feedness, o en lugar de abrirse la página de nuevos feeds, se abrirá una página pidiendo que os identifiquéis.

En fin, espero que a nadie le explote el PC por usarlo :huh:

Nota: ¡Desinstala LiveLines antes si la tienes instalada! :uch:

¿Notificador? Feedmania 0.1

(18 comentarios)

Notificador Feedmania es otra extensión poco útil que añadir a la colección. En principio debería ser un notificador para el agregador web Feedmania, que cada cierto tiempo comprueba si existen nuevas entradas en las bitácoras que tengas sindicadas. El problema es que no tengo el permiso de la gente de Feedmania (aunque les envíe un correo no me contestaron) y me gusta hacer las cosas bien, así que esa función está desactivada, al menos por ahora. De todas formas el código está incluido por si a alguien le interesa echarle un vistazo, aunque es muy simple, un simple XMLHttpRequest y un match que comprueba si existe la cadena “noleido” dentro de la página.

En conclusión, de notificador ahora mismo tiene mas bien poco, y su única utilidad es que además añade una entrada al menú contextual que permite sindicar un feed con un solo click, simplemente hacemos click con el botón derecho sobre el feed y seleccionamos “Sindicar con Feedmania”. Se que no es mucho, pero menos da una piedra 😛

WordPress Post It 0.1

(9 comentarios)

Acabo de crear una extensión para Firefox bastante inútil que consigue conglomerar todos los males de la programación en unas cuantas líneas de código. La extensión añade una entrada al menú contextual de Firefox la cual, al pulsarse, abrirá una página de publicación de WordPress, con el título de la página actual como título de la entrada, y un enlace a la página actual y el texto que estuviera seleccionado en la página actual como cuerpo de la entrada.

La extensión es bastante inútil porque no hace nada que no se pudiera hacer ya con el bookmarklet de WordPress, aparte de que esto es una entrada de menú en lugar de un bookmarklet y de que se puede seleccionar si quieres abrir la página de publicación en una nueva ventana, una nueva pestaña o una nueva pestaña en segundo plano. Es un ejemplo de mala programación porque no está comentado, ni las cadenas de texto están separadas en un dtd para facilitar la localización, y ni tan siquiera se capturan las excepciones :uch:.

De todas formas, para cualquiera que quiera echarle un vistazo, se debe instalar el xpi primero, y después seleccionar la dirección de la bitácora y el método de apertura en Tools -> Extensions -> WordPress Post It -> Options.

Fireftp (y sobre el supuesto navegador de Google)

(15 comentarios)

Si no necesitas un cliente FTP con demasiadas funcionalidades pero la implementación por defecto de Firefox te parece demasiado simple, puede que te interese una nueva extensión llamada Fireftp, que con solo 50kbs de tamaño no tiene nada que envidiar a cualquier otro cliente de FTP. Aún es una versión alpha y tiene el fallo de tener que abrir la ventana desde el menú de Firefox en lugar de capturar las direcciones FTP de la barra de direcciones, pero merece la pena echarle un vistazo.

Por otro lado, quería aprovechar para hacer una pequeña puntualización. Puede que mas de uno hayáis visto en alguna que otra bitácora enlaces a un par de aplicaciones XUL creadas por Google. Esto NO es prueba de que Google haya empezado a trabajar en un navegador web basado en Firefox, como han afirmado en algunos sitios, sino que datan de los tiempos de Netscape 6.0, como se puede ver en esta web de Google que explica cómo añadir dichas aplicaciones a la barra lateral de Netscape.

Tabla periódica de XUL

(2 comentarios)

Hace tiempo hablé sobre una tabla periódica de los operadores de Perl, esta vez he encontrado algo parecido a una tabla periódica de XUL (solo para navegadores basados en Gecko; también existe una versión zip para descargar al disco duro).

En realidad se trata de una serie de ejemplos que muestran el código para trabajar con los widgets mas comunes y sus propiedades mas utilizadas. Me gusta bastante mas que las típicas hojas de referencia, ya que en este caso puedes ver el código funcionando.

Construye tu propia extensión para Firefox con Zootropo

(19 comentarios)

Este post es simplemente una recopilación de los enlaces al mini curso sobre XUL que he estado escribiendo los últimos días. El resultado final del curso como ya sabrán los que lo hayan seguido es la creación de una pequeña extensión que muestra la hora del sistema cuando se pulsa sobre la entrada de menú correspondiente a nuestra extensión. Las entradas del curso son las siguientes:

  1. Pequeña introducción a XUL, que explica simplemente que es XUL.
  2. Nuestro primer programa en XUL en el que creamos una especie de ‘Hola Mundo’. Vemos por primera vez la estructura de un programa XUL y nuestro primer widget en XUL, el botón.
  3. Otro programa XUL, donde vemos los atributos de los botones
  4. Comunicándonos con el usuario en el que aprendemos como crear widgets label, textboxes y algo sobre el layout manager de XUL.
  5. Otros widgets de XUL donde completamos nuestro recorrido por los widgets básicos de XUL
  6. Creación de Menús
  7. RDF, pequeña introducción a este formato derivado de XML y estandarizado por el W3C.
  8. El registro chrome aprendemos que es el registro chrome, XPCOM y XPConnect y como instalar nuestras aplicaciones en chrome.
  9. Modularidad en XUL sobre como separar la interfaz de usuario definida con XUL, el estilo de la aplicación definido con css y el funcionamiento en código javascript.
  10. Nuestra primera extensión
  11. XPI, sobre el formato de instalación automático de extensiones de Mozilla.

There is only XUL (XI, Fin)

(7 comentarios)

Ahora que ya hemos terminado nuestra pequeña extensión para Firefox vamos a ver como podemos crear un xpi para que se instale automáticamente. La extensión xpi viene de XPInstall donde XP se refiere a Cross (X) Platform o multiplataforma, es decir, que puede ser ejecutado en distintas plataformas (Windows, Linux, Mac OS,…).

Un xpi es un simple archivo zip con extensión renombrada que contiene un fichero de instalación y los ficheros que componen la extensión. En el caso de las versiones anteriores a la 0.9 se utilizaba install.js como script instalador, ahora en cambio se utiliza un fichero rdf, install.rdf, pero podemos incluir ambos si queremos que la extensión se pueda instalar en la versión 0.9 y también en las anteriores.

Un archivo install.rdf tendría un aspecto parecido a este:

<?xml version=”1.0″?>
<RDF xmlns=”http://www.w3.org/1999/02/22-rdf-syntax-ns#” xmlns:em=”http://www.mozilla.org/2004/em-rdf#”>
<Description about=”urn:mozilla:install-manifest”>
<em:id>{eb78c871-3d9d-433f-b49b-12468119be89}</em:id>
<em:name>Mostrar Hora</em:name>
<em:version>0.1</em:version>
<em:description>Muestra la hora del sistema en un alert al hacer click sobre la entrada de menu correspondiente.</em:description>
<em:creator>Zootropo</em:creator>
<em:homepageURL>http://mundogeek.net </em:homepageURL>

<em:file>
<Description about=”urn:mozilla:extension:file:hora.jar”>
<em:package>/content/hora/</em:package>
</Description>
</em:file>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>0.9</em:minVersion>
<em:maxVersion>0.9</em:maxVersion>
</Description>
</em:targetApplication>

</Description>
</RDF>

Tenemos primero una serie de predicados de información sobre nuestra aplicación que son los siguientes:

  • em:id que se refiere a un id único que podemos generar con esta utilidad de Microsoft y no al identificador de la extensión
  • em:name, el nombre de la extensión
  • em:version, la versión de nuestra extensión.
  • em:description, una descripción de la utilidad de nuestra aplicación.
  • em:creator, nombre del creador de la aplicación.
  • em:homepageURL, página web de la extensión.
  • em:optionsURL, ventana que se mostrará al hacer click sobre las preferencias.
  • em:aboutURL, ventana que se mostrará como About de la aplicación.
  • em:iconURL, icono para identificar la extensión.
  • em:updateURL, URL opcional para la autoactualización.

Tenemos después un predicado em:file que agrupa información sobre los ficheros de nuestra aplicación, donde se encuentra content, skin y locale dentro del archivo .jar, y otro predicado em:targetApplication sobre el programa para el que está destinado nuestra extensión. em:id se refiere al id del navegador, en este caso Firefox y minVersion y maxVersion se refieren respectivamente a la versión mínima y máxima de la aplicación.

Si no quereis complicaros podeis utilizar para crear los xpi un script creado por Ted Mielczarek que podeis encontrar en su página web. También podeis consultar la traducción del documento de Ben Gooder sobre install.rdf.

Ahora que tenemos todos los archivos necesarios lo primero que tenemos que hacer es crear un archivo jar que incluya los archivos de nuestra extensión. Comprimimos en un mismo archivo zip las carpetas content, locale y skin de nuestra aplicación (o content solo si no hemos definido las otras dos). Cambiamos la extensión del archivo resultante a .jar de forma que nos quede un archivo hora.jar en este ejemplo y ya tenemos el archivo jar que empaqueta nuestra aplicación, nos queda empaquetar el .jar y el archivo de instalación en un xpi. Para eso creamos una carpeta chrome a la que movemos hora.jar y comprimimos en un .zip la carpeta chrome y el install.rdf (e install.js en el caso de que lo tengamos) y renombramos la extensión del archivo a .xpi.

El archivo xpi resultante para que comprobeis como se instala automáticamente como cualquier otra extensión de firefox es este.

There is only XUL (X)

(7 comentarios)

Ahora que hemos visto un poco por encima como funciona XUL vamos a ponernos un poco mas serios y vamos a crear una pequeña extensión para nuestro navegador. Por ahora algo sencillo como añadir una nueva entrada de menú al menú de herramientas de Firefox, que nos muestre un alert con la hora del sistema cada vez que se haga click sobre él. El proceso para Mozilla sería un proceso bastante parecido. Para ello tenemos que ver que son los overlays, cuya traducción al castellano sería algo asi como superposiciones.

Lo primero vamos a recordar que toda la interfaz de Mozilla y Firefox esta hecha con XUL, por lo tanto será razonable suponer que en algún lugar tiene que haber un fichero xul que lo define. Y acertariais al hacer esta suposición. La interfaz del navegador esta definida en un archivo llamado browser.xul en el subdirectorio chrome dentro de la carpeta en la que esta instalado nuestro navegador, pero si entrais en esa carpeta para echar un vistazo al código no lo encontrareis. browser.xul esta empaquetado dentro de uno de esos archivos .jar que veis.

Un archivo jar es simplemente un archivo .zip con la extensión renombrada. Podemos descomprimirlo con winzip u otro programa de compresión de archivos. Si descomprimimos browser.jar tendremos una carpeta browser que alberga una carpeta content en la que tenemos a su vez las carpetas browser y browser-region. Dentro de la primera se encuentra además del browser.xul al que nos referíamos otros archivos .xul, archivos js con código javascript y archivos css, hojas de estilo.

Si abrimos el archivo browser.xul tendremos una ventana del navegador de Firefox pero con la peculiaridad de que no veremos las barras de herramientas, los botones u otros widgets de las extensiones que tengamos instaladas. Esto es así por que cuando abrimos una ventana del navegador estamos abriendo browser.xul, pero también otros archivos .xul que se superponen. Sería algo así como coger varios dibujos en papel cebolla y ponerlos uno encima de otro, algo así como las capas de Photoshop. Esto es lo que vamos a ver ahora, el overlay.

Lo primero que tenemos que hacer es crear una carpeta para nuestra aplicación, por ejemplo ‘hora’ completando una estructura de directorios hora/content/hora. Dentro del directorio mas profundo de esta jerarquía creamos un archivo hora.xul con el siguiente código:

<?xml version=”1.0″?>

<overlay xmlns=”http://www.mozilla.org/keymaster/gatekeeper/ there.is.only.xul” xmlns:nc=”http://home.netscape.com/NC-rdf#”>

<popup id=”menu_ToolsPopup”>

<menuitem
oncommand=”fecha=new Date(); hora=fecha.getHours(); minuto=fecha.getMinutes(); segundo=fecha.getSeconds(); alert(hora + ‘ : ‘ + minuto + ‘ : ‘ + segundo);” label=”Mostrar Hora;”/>

</popup>

</overlay>

Lo que estamos haciendo aquí es crear un documento XUL que solo contiene una entrada de menú dentro de un popup que queremos superponer sobre el navegador. La única diferencia con los ejemplos que hemos visto hasta ahora es que en lugar de definir una ventana definimos un overlay pero aparte del nombre no hay mucha diferencia. Simplemente indicamos a Mozilla que este no es un documento xul completo, si no que vamos a combinarlo con otro/s documentos xul.

Ahora veamos como funcionaría el overlay con un caso sencillo antes de pasar a mayores. Supongamos un archivo XUL que importa el overlay que acabamos de definir; para ello usaría algo parecido a este código:

<?xul-overlay href=”chrome://hora/content/hora.xul”?>

Lo que ocurriría entonces es que para cada elemento con un id definido en el archivo de overlay se buscaría el mismo elemento con el mismo id en el documento sobre el que queremos superponer. Antes de nada tendríamos que haber abierto el fichero browser.xul para ver donde se definen las entradas de menú del menú herramientas y cual es el ID de conjunto que las contiene. Ese trabajo ya esta hecho; como se puede ver en el código tenemos un elemento popup con id menu_ToolsPopup, aquí es donde está la clave.

En el caso de que no se encuentre una instancia de ese elemento con ese ID entonces este elemento no se tiene en cuenta al hacer el overlay. Si por el contrario si se encuentra, entonces el elemento y todo lo que se defina dentro de este en el overlay pasará a superponerse al documento raíz, lo cual quiere decir que el elemento del documento raíz adquirirá todos los atributos que se definan en el overlay además de todos sus subelementos.

En este ejemplo el documento raíz es el que se encargaba de añadir el overlay usando la etiqueta xul-overlay, sin embargo esto no nos es de utilidad en nuestro caso ya que no queremos tener que cambiar el código de browser.xul. La solución es hacer que sea el overlay el que diga a que documento se tiene que superponer. Esto podemos hacerlo añadiendo la información de los overlay a nuestro contents.rdf

<?xml version=”1.0″?>

<RDF:RDF xmlns:RDF=”http://www.w3.org/1999/02/22-rdf-syntax-ns#”
xmlns:chrome=”http://www.mozilla.org/rdf/chrome#”>

<RDF:Seq about=”urn:mozilla:package:root”>
<RDF:li resource=”urn:mozilla:package:hora”/>
</RDF:Seq>

<RDF:Description about=”urn:mozilla:package:hora”
chrome:displayName=”Mostrar Hora 0.1″
chrome:author=”Zootropo”
chrome:authorURL=”http://mundogeek.net”
chrome:name=”hora”
chrome:extension=”true”
chrome:description=”Añade una opción al menú de herramientas para mostrar la hora actual.”>
</RDF:Description>

<RDF:Seq about=”urn:mozilla:overlays”>
<RDF:li resource=”chrome://browser/content/browser.xul”/>
</RDF:Seq>

<RDF:Seq about=”chrome://browser/content/browser.xul”>
<RDF:li>chrome://hora/content/hora.xul</RDF:li>
</RDF:Seq>

</RDF:RDF>

Vemos que tenemos un par de listas nuevas, una referida a urn:mozilla:overlays en el que los elementos de la secuencia son los documentos sobre los que se va a hacer el overlay (en este caso el browser.xul para superponer a nuestro navegador) y otra secuencia con el archivo xul sobre el que hacemos el overlay como sujeto y como entradas de la secuencia los archivos xul a superponer.

Borramos overlay.rdf como en el post anterior, añadimos una entrada nueva a installed-chrome.txt para el content de nuestra aplicación (no tendremos locale porque la única función javascript que utilizamos esta embebida en el archivo xul ni skin ya que no utilizamos ningún css) y reiniciamos nuestro navegador, tras lo cual tendremos una nueva entrada al final del menú de herramientas que nos permitirá ver la hora del sistema.

There is only XUL (IX)

(0 comentarios)

A la hora de organizar los ficheros de nuestra aplicación se sigue un estándar de facto en el que tenemos tres subdirectorios dentro de la carpeta de nuestra aplicación: content, local y skin.

El directorio content incluye un subdirectorio con el nombre de nuestra aplicación que a su vez contiene todos los archivos xul de la aplicación, además de los archivos js con el código javascript de la aplicación y un fichero contents.rdf que nos dice entre otras cosas cual es el archivo .xul principal.

En el directorio locale se incluyen una serie de subdirectorios con el código del idioma correspondiente, por ejemplo es-ES para castellano o en-US para inglés de estados unidos. Dentro de cada uno de estos directorios tenemos un subdirectorio con el nombre de la aplicación que incluye a su vez los ficheros dtd que sirven para separar la aplicación de los mensajes de esta para facilitar el proceso de traducción y un fichero contents.rdf.

Por último el directorio skin contiene otro subdirectorio de nombre classic que incluye un directorio con el nombre de nuestra aplicación con los ficheros css que se utilizan para modificar el aspecto de la aplicación y un archivo contents.rdf.

Hasta ahora el código javascript que hemos utilizado estaba incrustado dentro de los ficheros xul, en el siguiente ejemplo veremos como importar el código de un fichero js separado del código xul. Como simple comentario, el código css que hemos utilizado hasta ahora estaba almacenado en archivos css aparte como dicta la norma para conseguir modularidad; sin embargo, al igual que el código javascript, el código css puede almacenarse en un fichero aparte o incrustado dentro del propio archivo xul.

<?xml version=”1.0″?>
<!DOCTYPE window SYSTEM “chrome://caffeine/locale/caffeine.dtd”>

<?xml-stylesheet href=”chrome://caffeine/skin/caffeine.css” type=”text/css”?>
<window xmlns=”http://www.mozilla.org/keymaster/gatekeeper/ there.is.only.xul”
xmlns:nc=”http://home.netscape.com/NC-rdf#”>

<script type=”application/x-javascript”
src=”chrome://caffeine/content/caffeine.js”/>

<button onclick=”funcion();” label=”&nombreBoton;” accesskey=”&teclaAcceso”/>

</window>

La línea de script es la que se encarga de importar el código javascript desde el fichero javascript especificado de forma que podemos usar la función funcion() al hacer click en el botón aunque no la hallamos definido en este fichero. Podemos ver también la forma en que se importan los ficheros dtd con los mensajes de la aplicación en la segunda línea del código fuente. Hasta ahora no habíamos utilizado ficheros dtd, sino que incluíamos el texto de la aplicación imbuida dentro de esta; ahora con estos ficheros llevamos la modularidad de xul hasta el extremo, separando del código xul el funcionamiento, la apariencia y los mensajes.

El uso de los mensajes que se definen en los DTDs podemos verlo en el label y la accesskey del botón, un símbolo ampersand, el nombre que le dimos al mensaje en el dtd y punto y coma. El fichero DTD para este programa sería:

<!ENTITY nombreBoton “Mi Boton”>
<!ENTITY teclaAcceso “M”>

Para cada mensaje como vemos tenemos un !ENTITY, la segunda entrada de !ENTITY es el nombre del mensaje que se utilizará para referirse a él en el código XUL como ya vimos y el tercero el valor. En este DTD nombreBoton es “Mi Boton” pero podríamos tener otro DTD para el inglés en cuyo caso sería “My Button”, etc, de forma que la traducción de la aplicación es mas sencilla al separar el código y los mensajes.

Por último como ya dijimos cada uno de los directorios de la aplicación incluye un fichero contents.rdf para poder registrar ese directorio en el registro chrome. Veamos el caso del contents.rdf de los locales:

<?xml version=”1.0″?>
<RDF:RDF xmlns:RDF=”http://www.w3.org/1999/02/22-rdf-syntax-ns#”
xmlns:chrome=”http://www.mozilla.org/rdf/chrome#”>

<!– Lista de todos los locales que incluimos, en este caso solo es-ES –>
<RDF:Seq about=”urn:mozilla:locale:root”>
<RDF:li resource=”urn:mozilla:locale:es-ES”/>
</RDF:Seq>

<!– Informacion sobre cada uno de los locales –>
<RDF:Description about=”urn:mozilla:locale:es-ES”
chrome:displayName=”Castellano (ES)”
chrome:name=”es-ES”>
<chrome:packages>
<RDF:Seq about=”urn:mozilla:locale:es-ES:packages”>
<RDF:li resource=”urn:mozilla:locale:es-ES:caffeine”/>
</RDF:Seq>
</chrome:packages>
</RDF:Description>

</RDF:RDF>

Y el contents.rdf de los skins:

<?xml version=”1.0″?>

<RDF:RDF xmlns:RDF=”http://www.w3.org/1999/02/22-rdf-syntax-ns#”
xmlns:chrome=”http://www.mozilla.org/rdf/chrome#”>

<RDF:Seq about=”urn:mozilla:skin:root”>
<RDF:li resource=”urn:mozilla:skin:classic/1.0″ />
</RDF:Seq>

<RDF:Description about=”urn:mozilla:skin:classic/1.0″>
<chrome:packages>
<RDF:Seq about=”urn:mozilla:skin:classic/1.0:packages”>

</RDF:Seq>
</chrome:packages>
</RDF:Description>

</RDF:RDF>

rdf no necesitan comentarios. Son muy parecidos al contents.rdf del directorio contents. Tan solo queda registrar en el registro chrome contents, locals y skins. Si recordamos en el anterior post sobre XUL al registrar el contents añadíamos a installed-chrome.txt una línea similar a esta:

content,install,url,resource:/chrome/caffeine/content/caffeine/

Si echamos un vistazo a las demás entradas en installed-chrome veremos que algunas comienzan con skin, otras con locale y otras con contents. Esto es lo único que tenemos que cambiar a la hora de registrar skins y locales, lo demás es similar, por lo tanto para nuestra aplicación de ejemplo tendríamos que añadir las líneas:

skin,install,url,resource:/chrome/caffeine/content/caffeine/
locale,install,url,resource:/chrome/caffeine/locale/es-ES/
content,install,url,resource:/chrome/caffeine/skin/classic/caffeine/

Página 1 de 212