1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
|
---
title: Construyendo una extensión
slug: conflicting/Mozilla/Add-ons
translation_of: Mozilla/Add-ons
translation_of_original: Building_an_Extension
original_slug: Building_an_Extension
---
<h2 id="Introducción">Introducción</h2>
<p>Este tutorial te guiará a través de los pasos requeridos para desarrollar una <a href="/en-US/docs/Extensions" title="/en-US/docs/Extensions">extensión</a> muy básica - una que agrega un panel con una barra de estado con el texto "Hola, Mundo!" al navegador de Firefox.</p>
<div class="note"><strong>Nota:</strong> La extensión creada por este tutorial no funcionará en versiones de Firefox que no contengan una barra de estado estática (esto es, Firefox 4 en adelante). Puedes encontrar un tutorial más actualizado en <a href="/en-US/docs/XUL_School/The_Essentials_of_an_Extension" title="The Essentials of an Extension">The Essentials of an Extension</a> de la <a href="/en-US/docs/XUL_School" title="XUL School Tutorial">XUL School</a>.</div>
<p>Desde Firefox 4 (y otras aplicaciones basadas en Mozilla 2) existen dos tipos de extensiones:</p>
<ul>
<li>Las extensiones tradicionales, clásicas o XUL son más poderosas, pero más complicadas de construir y requieren un reinicio para su instalación.</li>
<li>Extensiones sin reinicio, o <a href="/en-US/docs/Extensions/Bootstrapped_extensions" title="/en-US/docs/Extensions/Bootstrapped_extensions">bootstrapped extensions</a> que no requieren un reinicio para instalarse pero son más limitadas que las extensiones tradicionales. El <a class="link-https" href="https://addons.mozilla.org/en-US/developers/tools/builder">Add-on SDK y el Add-on Builder</a> pueden ser usados para construir fácilmente extensiones sin reinicio.</li>
</ul>
<p>Este artículo explica como construir una extensión tradicional para Firefox. Para información sobre bootstrapped extensions o sin reinicio, mira <a href="/en-US/docs/Extensions/Bootstrapped_extensions" title="/en-US/docs/Extensions/Bootstrapped_extensions">Bootstrapped extensions</a>.</p>
<p>Para un tutorial sobre construcción de extensiones para Thunderbird, mira <a href="/en-US/docs/Extensions/Thunderbird/Building_a_Thunderbird_extension" title="/en-US/docs/Building_a_Thunderbird_extension">Construyendo una extensión para Thunderbird.</a></p>
<h2 id="Inicio_Rápido">Inicio Rápido</h2>
<p>Una extensión <a class="external" href="http://mozilla.doslash.org/stuff/helloworld.zip">Hola Mundo</a> similar que puedes generar con el Extension Wizard es explicado línea por línea en <a class="external" href="http://kb.mozillazine.org/Getting_started_with_extension_development">otro tutorial desde la MozillaZine Knowledge Base (Base de Conocimiento MozillaZine)</a>.</p>
<h2 id="Configurando_un_Ambiente_de_Desarrollo">Configurando un Ambiente de Desarrollo</h2>
<p>Las extensiones son empaquetadas y distribuidas en archivos ZIP o <a href="/en-US/docs/Bundles" title="/en-US/docs/Bundles">Bundles</a>, con la extensión de archivos <code>XPI</code>.</p>
<p><code>Un ejemplo del contenido dentro de un archivo XPI típico </code>:</p>
<pre class="eval">my_extension.xpi: //<code>Igual a una carpeta llamada</code> <strong style="font-weight: bold;">my_extension</strong><strong>/</strong>
<a href="/en-US/docs/Install_Manifests" title="/en-US/docs/Install Manifests">/install.rdf </a> //<code>Información general sobre tu extensión</code>
/<a href="/en-US/docs/Chrome_Registration" title="/en-US/docs/Chrome_Registration">chrome.manifest</a> //Registra tu contenido con el motor <a href="/en-US/docs/Chrome_Registration" title="https://developer.mozilla.org/en-US/docs/chrome_registration">Chrome</a>
/chrome/
/chrome/content/ //Contenido de tu extensión, por ejemplo, archivos XUL and JavaScript
/<a href="/en-US/docs/Window_icons" title="/en-US/docs/Window_icons">chrome/icons/default/*</a> //Iconos por defecto de tu extensión
/chrome/locale/* //Construyendo una Extensión# <a href="/en-US/docs/Building_an_Extension#Localization" title="https://developer.mozilla.org/en-US/docs/Building_an_Extension#Localization">Localización</a>
<a href="#Defaults_Files">/defaults/preferences/*.js</a> //Construyendo una Extensión# <a href="/en-US/docs/Building_an_Extension#Defaults_Files" title="https://developer.mozilla.org/en-US/docs/Building_an_Extension#Defaults_Files">Archivos por defecto</a>
/plugins/*
<a href="#XPCOM_Components"> /components/*</a>
<a href="#Application_Command_Line">/components/cmdline.js</a></pre>
<p>Desearemos construir una estructura de archivos similar a la anterior para nuestro tutorial, así que comencemos creando una carpeta para tu extensión en algún lugar de tu disco duro (por ejemplo, <code>C:\extensions\my_extension\</code> or <code>~/extensions/my_extension/</code>). Dentro de la nueva carpeta para la extensión, crea otra carpeta llamada <code>chrome</code>, y dentro de la carpeta <code>chrome</code>, crea una carpeta llamada <code>content</code>.</p>
<p>Dentro del directorio <strong>raíz</strong> de la carpeta de tu extensión, crea dos archivos de texto nuevos, llamados <code>chrome.manifest<span style="font-family: verdana,tahoma,sans-serif;"> </span></code>e <code>install.rdf</code>. En el directorio <strong>chrome/content</strong>, crea un nuevo archivo de texto vacío llamado <code>sample.xul</code>.</p>
<p>Deberías concluir con esta estructura de directorio:</p>
<ul>
<li>install.rdf</li>
<li>chrome.manifest</li>
<li>chrome\
<ul>
<li>content\
<ul>
<li>sample.xul</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><span class="comment"><pre> #!/bin/sh h=$HOME/moExt mkdir -p $h/my_extension/chrome/content touch $h/my_extension/chrome.manifest $h/my_extension/install.rdf </pre></span> Por favor lee la información adicional sobre configuración de un ambiente de desarrollo en el artículo <a href="/en-US/docs/Setting_up_extension_development_environment" title="/en-US/docs/Setting_up_extension_development_environment">Configurando un ambiente de desarrollo</a>.</p>
<p>{{ gecko_minversion_note("1.9.2", "Starting in Gecko 1.9.2 (Firefox 3.6), you can also simply include an icon, named <code>icon.png</code>, in the base directory of the add-on. This allows your add-on's icon to be displayed even when the add-on is disabled, or if the manifest is missing an <code>iconURL</code> entry.") }}</p>
<h2 id="Crear_el_Manifiesto_de_Instalación">Crear el Manifiesto de Instalación</h2>
<p>Abre el archivo llamado <code><a href="/en-US/docs/Install_Manifests" title="/en-US/docs/Install_Manifests">install.rdf</a></code> que creaste en el tope de la jerarquía de carpetas de tu extensión y agrega dentro lo siguiente:</p>
<pre class="brush: xml language-xml"><code class="language-xml"><span class="prolog token"><?xml version="1.0"?></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>RDF</span> <span class="attr-name token">xmlns</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>http://www.w3.org/1999/02/22-rdf-syntax-ns#<span class="punctuation token">"</span></span>
<span class="attr-name token"><span class="namespace token">xmlns:</span>em</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>http://www.mozilla.org/2004/em-rdf#<span class="punctuation token">"</span></span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>Description</span> <span class="attr-name token">about</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>urn:mozilla:install-manifest<span class="punctuation token">"</span></span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>id</span><span class="punctuation token">></span></span>sample@example.net<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>id</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>version</span><span class="punctuation token">></span></span>1.0<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>version</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>type</span><span class="punctuation token">></span></span>2<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>type</span><span class="punctuation token">></span></span>
<span class="comment token"><!-- Target Application this extension can install into,
with minimum and maximum supported versions. --></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>targetApplication</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>Description</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>id</span><span class="punctuation token">></span></span>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>id</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>minVersion</span><span class="punctuation token">></span></span>1.5<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>minVersion</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>maxVersion</span><span class="punctuation token">></span></span>4.0.*<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>maxVersion</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>Description</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>targetApplication</span><span class="punctuation token">></span></span>
<span class="comment token"><!-- Front End MetaData --></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>name</span><span class="punctuation token">></span></span>sample<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>name</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>description</span><span class="punctuation token">></span></span>A test extension<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>description</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>creator</span><span class="punctuation token">></span></span>Your Name Here<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>creator</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span><span class="namespace token">em:</span>homepageURL</span><span class="punctuation token">></span></span>http://www.example.com/<span class="tag token"><span class="tag token"><span class="punctuation token"></</span><span class="namespace token">em:</span>homepageURL</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>Description</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>RDF</span><span class="punctuation token">></span></span></code></pre>
<ul>
<li><code><strong><span class="link-mailto linkification-ext">sample@example.net</span></strong></code> – el ID de la extensión. Este es un valor con el que identificas tu extensión en formato de direccón de correo electrónico (nota que no debería ser <em>tu</em> email). Hazlo único. También podrías usar un GUID. NOTA: Este parámetro DEBE estar en formato de dirección de correo electrónico, aunque NO tiene que ser una dirección válida. (<code><span class="link-mailto">example@example.example</span></code>)</li>
<li>Especifica <code><em:type>2</em:type></code> – el 2 declara que está instalando una extensión. Si fueras a instalar un tema (theme) sería 4 (mira <a href="/en-US/docs/Install_Manifests#type" title="/en-US/docs/Install_Manifests#type">Install Manifests#type</a> para otros tipos de códigos).</li>
<li><code><strong>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</strong></code> – ID de la aplicación Firefox.</li>
<li><code><strong>1.5</strong></code> – el número exacto de la versión más antigua de Firefox para la cual estableces que esta extensión funcionará. Nunca uses un * en minVersion; es muy seguro que no hagas lo que esperas.</li>
<li><code><strong>4.0.*</strong></code> – la versión máxima de Firefox para la cual dices que esta extensión funcionará. En este caso, "4.0.*" indica que la extensión funciona con Firefox 4.0 y cualquier entrega 4.0.x subsecuente. Este número necesita ser menor o igual a la <a class="external" href="http://wiki.mozilla.org/Releases" title="http://wiki.mozilla.org/Releases">versión anunciada de Firefox</a>. Por defecto, Firefox 10 y posteriores no fuerzan una restricción contra <code>maxVersion</code> (aunque comenzando en Firefox 11, valores muy antiguos de <code>maxVersion</code> son todavía forzados). Puedes forzan a la aplicación a hacerlo usando <code><em:strictCompatibility></code>.</li>
</ul>
<div class="note"><strong>Nota:</strong> si obtienes un mensajes que <code>install.rdf</code> está mal formado, es útil cargarlo en Firefox usando el comando Archivo->Abrir Archivo que reportará los errores XML para ti.</div>
<p>Las extensiones diseñadas para funcionar con Firefox 2.0.0.x como la última deben configurar la máxima versión a "2.0.0.*". Las extensiones diseñadas para funcionar con Firefox 1.5.0.x como la última deben configurar la máxima versión a "1.5.0.*"</p>
<p>Mira <a href="/en-US/docs/Install_Manifests" title="/en-US/docs/Install_Manifests">Manifiestos de Instalación</a> para una lista completa de las propiedades requeridas y opcionales.</p>
<p>Guarda el archivo.</p>
<h2 id="Extendiendo_el_Navegador_con_XUL">Extendiendo el Navegador con XUL</h2>
<p>La interfaz de usuario de Firefox está escrita en XUL y JavaScript. <a href="/en-US/docs/XUL" title="/en-US/docs/XUL">XUL</a> es una grática XML que provee widgets de interfaz como botones, menús, barras de herramientas, árboles, etc. Las acciones de los usuarios están ligadas a funcionalidad usando JavaScript.</p>
<p>Para extender el navegador, modificamos partes de la interfaz de usuario del navegador, agregando o modificando widgets. Agreramos widgets insertando nuevos elementos XUL DOM en la ventana del navegador y los modificamos usando script y vinchulando manejadores de eventos.</p>
<p>El navegador es implementado en un archivo XUL llamado <code>browser.xul</code> (<code>$FIREFOX_INSTALL_DIR/chrome/browser.jar</code> contiene <code>content/browser/browser.xul</code>). En browser.xul podemos encontrar la barra de estado, que se parece a algo como esto:</p>
<pre class="eval language-html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>toolbarpalette</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>BrowserToolbarPalette<span class="punctuation token">"</span></span><span class="punctuation token">></span></span>
... <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>toolbarbutton</span><span class="punctuation token">></span></span>s ...
<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>toolbarpalette</span><span class="punctuation token">></span></span></code></pre>
<p><code><statusbar id="status-bar"></code> es un "punto de fusión" para un XUL Overlay.</p>
<h3 id="XUL_Overlays">XUL Overlays</h3>
<p><a href="/en-US/docs/XUL_Overlays" title="/en-US/docs/XUL_Overlays">Los XUL Overlays</a> son una forma de enlazar en tiempo de ejecución otros widgets de la interfaz de usuario a un documento XUL. Un XUL Overlay es un archivo .xul que especifíca fragmentos XUL a insertar en puntos de fusión específicos dentro de un documento "maestro". Estos fragmentos pueden especificar la inserción, eliminación o modificación de widgets.</p>
<p><strong>Ejemplo de un Documento XUL Overlay</strong></p>
<pre class="eval language-html"><code class="language-html"><span class="prolog token"><?xml version="1.0"?></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>overlay</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>sample<span class="punctuation token">"</span></span>
<span class="attr-name token">xmlns</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul<span class="punctuation token">"</span></span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>toolbarpalette</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>BrowserToolbarPalette<span class="punctuation token">"</span></span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>toolbarbutton</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>my-button<span class="punctuation token">"</span></span> <span class="attr-name token">label</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>Hello, World<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>toolbarpalette</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>overlay</span><span class="punctuation token">></span></span></code></pre>
<p>La <code><</code>toolbarpalette<code>></code> llamada<code><strong> </strong></code><strong>BrowserToolbarPalette </strong> especifica el "punto de fusión" que queremos enlazar dentro de la ventana del navegador.</p>
<p>El hijo <code><</code>toolbarbutton<code>></code> es un nuevo widget que queremos insertar dentro de un punto de fusión.</p>
<p>Copia el código de ejemplo anterior y guardalo en tu archivo llamado <code><strong>sample.xul</strong></code> dentro de la carpeta <code>chrome/content</code> que has creado.</p>
<p>Para más información sobre fusionar widgets y modificar la interfaz de usuario usando Overlays, mira debajo.</p>
<h2 id="Chrome_URIs">Chrome URIs</h2>
<p>Los archivos XUL son parte de "<a href="/en-US/docs/Chrome_Registration" title="/en-US/docs/Chrome_Registration">Paquetes Chrome</a>" - envoltorios de componentes de interfaz de usuario que son cargados a través de <code>URIs chrome://</code>. En lugar de cargar el navegador desde el disco usando una URI <code>file://</code> (ya que la ubicación de Firefox en el sistema puede cambiar de plataforma a plataforma y de sistema a sistema), los desarrolladores de Mozilla encontraron una solución para crear URIs para contenido XUL que la aplicación instalada conoce.</p>
<p>La ventana del navegador es: <code><a class="external" rel="freelink">chrome://browser/content/browser.xul</a></code>. Prueba tipiando esta URL en la barra de navegación de Firefox!</p>
<p>Las Chrome URIs constan de varios componentes:</p>
<ul>
<li>Primero, el <strong>esquema URI</strong> (<code>chrome</code>) que le comunica a la librería de red de Firefox que es una Chrome URI. Indica que el contenido de la URI debería ser tratada como un (<code>chrome</code>). A diferencia de (<code>chrome</code>), (<code>http</code>) le comunica a Firefox que debe tratar la URI como una página web.</li>
<li>Segundo, un nombre de paquete (en el anterior ejemplo, <code><strong>browser</strong></code>) que identifica el envoltorio de componentes de interfaz de usuario. Este debería ser lo más único posible para tu aplicación, para evitar colisiones entre extensiones.</li>
<li>Tercero, el tipo de dato que es requerido. Existen tres tipos: <code>content</code> (XUL, JavaScript, XBL bindings, etc. que forman la estructura y el comportamiento de una aplicación de interfaz de usuario), <code>locale</code> (DTD, archivos .properties, etc que contienen strings para la <a href="/en-US/docs/Localization" title="/en-US/docs/Localization">localización</a> de la interfaz de usuario) , y <code>skin</code> (CSS e imágenes que forman el <a href="/en-US/docs/Themes" title="/en-US/docs/Themes">tema</a> de la interfaz de usuario).</li>
<li>Finalmente, la dirección del archivo a cargar.</li>
</ul>
<p>Así que, <code><a class="external" rel="freelink">chrome://foo/skin/bar.png</a></code> carga el archivo <code>bar.png</code> desde la sección <code>skin</code> del tema <code>foo</code>.</p>
<p>Cuando cargas contenido usando una Chrome URI, Firefox usa el Chrome Registry (Registro de Chrome) para traducir estas URIs en los archivos fuente actuales dentro del disco (o en paquetes JAR).</p>
<h2 id="Crea_un_Manifiesto_Chrome">Crea un Manifiesto Chrome</h2>
<p>Para más información de Manifiestos Chrome y las propiedades que soportan, mira Referencia <a href="/en-US/docs/Chrome_Registration" title="/en-US/docs/Chrome_Registration">de Manifiestos Chrome</a>.</p>
<p>Abre el archivo denominado <strong>chrome.manifest</strong> que has creado junto al directorio <code>chrome</code> en la raíz de la jerarquía de carpetas de tu extensión.</p>
<p>Agrega este código:</p>
<pre class="eval">content sample chrome/content/
</pre>
<p>(<strong>No te olvides de la barra, "<code>/</code>"!</strong> Sin ella, el paquete no será registrado.)</p>
<p>Esto especifica:</p>
<ol>
<li>tipo de material dentro del paquete chrome.</li>
<li>nombre del paquete chrome (asegúrate de usar todos caracteres en minúscula para ele nombre del paquete ("sample") ya que Firefox/Thunderbird no soporta doesn't support caracteres mixtos en la versión 2 y anteriores - {{ Bug("132183") }})</li>
<li>ubicación de los archivos de paquetes chrome.</li>
</ol>
<p><br>
Entonces, esta línea establece que para un paquete chrome <strong>sample</strong>, podremos encontrar sus archivos de contenido (<strong>content)</strong> en la ubicación <code>chrome/content</code> que es una dirección relativa a la ubicación del manifiesto <code>chrome.manifest</code>.</p>
<p>Tenga en cuenta que los archivos de contenido (content), localización (locale), y apariencia (skin) deben mantenerse dentro de carpetas llamadas content, locale, and skin dentro del subdirectorio <code>chrome</code>.</p>
<p>Guarda el archivo. Cuando ejecutes Firefox con tu extensión (más adelante en este tutorial), esto va a registrar el paquete chrome.</p>
<h2 id="Registrar_un_Overlay">Registrar un Overlay</h2>
<p>Necesitas que Firefox fusione tu overlay (capa) con la ventana del navegador siempre que se despliegue una. Así que agrega esta linea al archivo <code>chrome.manifest</code>:</p>
<pre class="eval">overlay <a class="external" rel="freelink">chrome://browser/content/browser.xul</a> <a class="external" rel="freelink">chrome://sample/content/sample.xul</a>
</pre>
<p>Esto le dice a Firefox que fusione <code>sample.xul</code> en <code>browser.xul</code> cuando se cargue <code>browser.xul</code>.</p>
<h2 id="Prueba">Prueba</h2>
<p>Primero, necesitamos comunicarle a Firefox sobre nuestra extensión. Durante la fase de desarrollo para versiones de Firefox 2.0 y posteriores, puedes señalar a Firefox hacia la carpeta donde estés desarrollando la extensión, y la cargará cada vez que reinicies Firefox.</p>
<ol>
<li>Ubica tu <a class="external" href="http://kb.mozillazine.org/Profile_folder" title="http://kb.mozillazine.org/Profile_folder">carpeta de perfil</a> y dentro el perfil con el que quieres trabajar (ej., <code>Firefox/Profiles/<profile_id>.default/</code>).</li>
<li>Abra la carpeta <code>extensions/</code>, creandola de ser necesario.</li>
<li>Crea un nuevo archivo de texto y coloca dentro la dirección completa de tu carpeta de desarrollo (ej., <code>C:\extensions\my_extension\</code> or <code>~/extensions/my_extension/)</code>. Los usuarios de Windows deberían conservar la dirección de la barra, y <em>todos</em> deberían acordarse de <strong>incluir</strong> una barar de cierre y <strong>eliminar</strong> cualquier espacio.</li>
<li>Guarda el archivo con la id de tu extensión como su nombre (ej., <code><a class="linkification-ext link-mailto" href="mailto:sample@example.net" title="Linkification: mailto:sample@example.net">sample@example.net</a></code>). Sin extensión de archivo.</li>
</ol>
<p>Ahora deberías estar listo opara probar tu extensión!</p>
<p>Ejecuta Firefox. Firefox detectará el texto de enlace hacia el directorio de tu extensión e instalará la Extensión. Cuando aparezca la ventana del navegador deberías ver el texto "Hello, World!" en la parte derecha del panel con la barra de estado.</p>
<p>Ahora puedes volver y hacer cambios al archivo .xul, cierra y reinicia Firefox, y deberían aparecer.</p>
<h2 id="Empaquetamiento">Empaquetamiento</h2>
<p>Ahora que tu extensión funciona, puedes <a href="/en-US/docs/Extension_Packaging" title="/en-US/docs/Extension_Packaging">empaquetarla</a> para su despliegue e instalación.</p>
<p>Comprime (zip) los <strong>contenidos (contents)</strong> de la carpeta de tu extensión (no la carpeta de extensión misma), y renombra el archivo zip para que tenga la extensión .xpi. En Windows XP, puedes hacer esto fácilmente seleccionando todos los archivos y subcarpetas en la carpeta de tu extensión, haciendo click derecho y seleccionando "Enviar a -> Carpeta comprimida (zip)". Se creará un archivo .zip para ti. Sólo renombralo y ya terminaste!</p>
<p>En Mac OS X, puedes hacer click derecho en los <strong>contenidos (contents)</strong> de la carpeta de la extensión y elegir "Crear archivo de..." para hacer un archivo zip. Sin embargo, ya que Mac OS X agrega archivos ocultos a las carpetas para rastrear los metadatos de los archivos, deberías usar la Terminal, eliminar los archivos ocultos (cuyos nombre comienzan con un punto), y luego usar el comando zip en la linea de comandos para crear el archivo zip.</p>
<p>En Linux, podrías también usar la herramienta zip de linea de comandos.</p>
<p>Si tienes el 'Extension Builder' (Constructor de Extensiones) instalado, puede compliar el archivo .xpi para ti (Tools -> Extension Developer -> Extension Builder). Simplemente navega al directorio donde está tu extensión (install.rdf, etc.), y presiona el botón Build Extension. Esta extensión tiene una gran cantidad de herramientas para facilitar el desarrollo.</p>
<p>Ahora carga el archivo .xpi en tu servidor, asegúrate de que es servido como una <code>application/x-xpinstall</code>. Puedes obtener un enlace al mismo y permitir que las personas lo descarguen e instalen. Con el propósito de simplemente testearnuestro archivo .xpi, podemos sólo arrastrarlo en la ventana de extensiones, en Herramientas -> Extensiones para Firefox 1.5.0.x, o Herramientas -> Complementos para versiones posteriores.</p>
<h3 id="Instalando_desde_una_página_web">Instalando desde una página web</h3>
<p>Existen muchas formas de instalar extensiones desde páginas web, incluyendo enlace directo hacia archivos XPI y usando el objeto InstallTrigger. Los autores web y de extensiones son alentados a usar el <a href="/en-US/docs/Installing_Extensions_and_Themes_From_Web_Pages" title="/en-US/docs/Installing_Extensions_and_Themes_From_Web_Pages">método InstallTrigger</a> para instalar XPIs, ya que provee la mejor experiencia a los usuarios.</p>
<h3 id="Usando_addons.mozilla.org">Usando addons.mozilla.org</h3>
<p>Los Complementos para Firefox es un sitio de distribución donde puedes alojar tu extensión gratuitamente. tu extensión será alojada en un espejo (mirror) de la red de Mozilla para garantizar tu descarga a pesar de que pueda ser muy popular. El sitio de Mozilla también provee una sencilla instalación para los usuarios, y automáticamente hará que tus versiones más nuevas estén disponibles cuando las cargues. Además, los Complementos para Firefox permiten a los usuarios comentar y proveer una retroalimentación en tu extensión. Es altamente recomendado que uses los Complementos de Firefox para distribuir tus extensiones!</p>
<p>Visita <a class="linkification-ext external" href="http://addons.mozilla.org/developers/" title="Linkification: http://addons.mozilla.org/developers/">http://addons.mozilla.org/developers/</a> para crearte una cuenta y comenzar a distribuir tus extensiones!</p>
<p><em>Nota:</em> Tu Extensión será enviada más rápidamente y descargada más veces si tienes una buena descripción y algunas capturas de pantalla de la extensión en acción.</p>
<h3 id="Instalando_Extensiones_Usando_una_Instalador_Separado">Instalando Extensiones Usando una Instalador Separado</h3>
<p>Es posible instalar extensiones en un directorio especial y será instalado la próxima vez que la aplicación comience. La extensión estará disponible para cualquier perfil. Mira <a class="internal" href="/en-US/docs/Installing_extensions" title="/en-US/docs/Installing extensions">lnstalando extensiones</a> para más información.</p>
<p>En Windows, la información sobre extensiones puede ser agregada al registro, y las extensiones serán recogidas automáticamente la proxima vez que la aplicación comience. Esto permite a los instaladores de aplicaciones agregar fácilmente ganchos de integración como extensiones. Mira <a href="/en-US/docs/Adding_Extensions_using_the_Windows_Registry" title="/en-US/docs/Adding_Extensions_using_the_Windows_Registry">Agregando Extensiones usando el Registro de Windows</a> para más información.</p>
<h2 id="Más_sobre_XUL_Overlays">Más sobre XUL Overlays</h2>
<p>Además de agregar widgets de interfaz de usuario al punto de fusión, puedes usar los fragmentos XUL dentro de los Overlays para controlar la posición de los widgets insertados:</p>
<pre class="eval language-html"><code class="language-html"><toolbarbutton position="1" ... />
<toolbarbutton insertbefore="other-id" ... />
<toolbarbutton insertafter="other-id" ... /></code></pre>
<h2 id="Creando_Nuevos_Componentes_de_Interfaz_de_Usuario">Creando Nuevos Componentes de Interfaz de Usuario</h2>
<p>Puedes crear tus propias ventanas y cuadros de diálogo como archivos .xul separados, brindando funcionalidad a través de la implementación de acciones de usuarios en archivos .js, usando métodos DOM para manipular widgets de interfaz de usuario. Puedes usar reglas de estilos en archivos .css para enlazar imágenes, establecer colores, etc.</p>
<p>Mira la documentación <a href="/en-US/docs/XUL" title="/en-US/docs/XUL">XUL</a> con más recursos para los desarrolladores XUL.</p>
<h2 id="Archivos_por_Defecto">Archivos por Defecto</h2>
<p>Los archivos por defecto que usas para sembrar un perfil de usuario deberían ser ubicados en <code>defaults/</code> debajo de la raíz de la jerarquía de carpetas de tu extensión. Los archivos .js de preferencias por defecto deberían ser almacenados en <code>defaults/preferences/</code> - si los ubicas aquí serán cargados automáticamente por el sistema de preferencias de Firefox cuando arranque, y así podrás accederlos usando la <a href="/en-US/docs/Preferences_API" title="/en-US/docs/Preferences_API">API de Preferencias</a>.</p>
<p>Un archivo de preferencia por defecto de ejemplo:</p>
<pre class="eval">pref("extensions.sample.username", "Joe"); //a string pref
pref("extensions.sample.sort", 2); //an int pref
pref("extensions.sample.showAdvanced", true); //a boolean pref
</pre>
<h2 id="Componentes_XPCOM">Componentes XPCOM</h2>
<p>Firefox soporta componentes <a href="/en-US/docs/XPCOM" title="/en-US/docs/XPCOM">XPCOM</a> en las extensiones. Puedes crear tus propios componentes fácilmente en JavaScript o en C++ (usando <a href="/en-US/docs/Gecko_SDK" title="/en-US/docs/Gecko_SDK">Gecko SDK</a>).</p>
<p>Ubica todos tus archivos .js o .dll en <code>el directorio components/</code> - son registrados automáticamente la primera vez que se ejecute Firefox luego de que tu extensión es instalada.</p>
<p>Para más información mira <a href="/en-US/docs/How_to_Build_an_XPCOM_Component_in_Javascript" title="/en-US/docs/How_to_Build_an_XPCOM_Component_in_Javascript">Cómo Construir un Componente XPCOM en Javascript</a>, <a href="/en-US/docs/How_to_build_a_binary_XPCOM_component_using_Visual_Studio" title="/en-US/docs/How_to_build_a_binary_XPCOM_component_using_Visual_Studio">Cómo construir un componente XPCOM binario usando Visual Studio,</a> y el libro <a href="/en-US/docs/Creating_XPCOM_Components" title="/en-US/docs/Creating_XPCOM_Components">Creando Componentes XPCOM</a>.</p>
<h3 id="Línea_de_Comandos_de_la_Aplicación">Línea de Comandos de la Aplicación</h3>
<p>Uno de los posibles usos de los componentes XPCOM personalizados, es agregar un manejador de líneas de ocmandos para Firefox o Thunderbird. Puedes usar esta técnica para ejecutar tu extensión como una aplicación:</p>
<pre class="eval"> firefox.exe -myapp
</pre>
<p><span class="comment">I should move the useful parts of this to the Command Line page. -Nickolay This is done by adding a component containing the function... function NSGetModule(comMgr, fileSpec) { return myAppHandlerModule; } This function is run by firefox each time firefox is started. Firefox registers the myAppHandlerModule's by calling its 'registerSelf()'. Then it obtains the myAppHandlerModule's handler factory via 'getClassObject()'. The handler factory is then used to create the handle using its 'createInstance(). Finally, the handle's 'handle(cmdline)' processes the command line cmdline's handleFlagWithParam() and handleFlag().</span> Mira <a href="/en-US/docs/Chrome/Command_Line" title="/en-US/docs/Chrome/Command_Line">Chrome: Línea de Comandos</a> y un <a class="external" href="http://forums.mozillazine.org/viewtopic.php?t=365297">foro de discusión</a> para más detalles.</p>
<h2 id="Localización">Localización</h2>
<p>Para soportar más de un lenguaje, deberías separar los strings (cadenas de caracteres) de tu contenido usando <a href="/en-US/docs/XUL_Tutorial/Localization" title="/en-US/docs/XUL_Tutorial/Localization">entidades</a> y <a href="/en-US/docs/XUL_Tutorial/Property_Files" title="/en-US/docs/XUL_Tutorial/Property_Files">envoltorios de strings</a>. Es mucho más fácil hacer esto mientras estás desarrollando tu extensión, en lugar de volver y hacerlo después!</p>
<p>La información de localización es almacenada en el directorio locale para tu extensión. Por ejemplo, para agregar un locale a tu extensión de ejemplo, crea dos directorios anidados "locale/en-US" en chrome (donde está ubicado el directorio "content") y agrega la siguiente línea al archivo chrome.manifest:</p>
<pre class="eval">locale sample en-US chrome/locale/en-US/
</pre>
<p>Para crear valores de atributo localizables en XUL, puedes ubicar los valores en un archivo<code> .dtd</code> (sample.dtd para tu extensión de prueba). Este archivo debería ser ubicado en el directorio locale y se parece a esto:</p>
<pre class="eval"><!ENTITY my-panel.label "Hello, World">
</pre>
<p>Luego incluyélo el comienzo de tu documento XUL (pero debajo de"<?xml version"1.0"?>"), como se ve a continuación:</p>
<pre class="eval language-html"><code class="language-html"><span class="prolog token"><?xml version="1.0"?></span>
<span class="doctype token"><!DOCTYPE window SYSTEM "chrome://packagename/locale/filename.dtd"></span>
...</code></pre>
<p>donde <code><strong>window</strong></code> es el valor <code><a href="/en-US/docs/DOM/Node.localName" title="/en-US/docs/DOM/element.localName">localName (nombre local)</a></code> del elemento raíz del documento XUL, y el valor de la propiedad <code>SYSTEM</code> es la URI chrome hacia el archivo de entidad.</p>
<p>Para nuestra extensión de ejemplo, reemplaza <code><strong>window</strong></code> con <code><strong>overlay</strong></code> (elemento raíz), <code><strong>packagename</strong></code> con <code><strong>sample</strong></code>, y <code><strong>filename.dtd</strong></code> con <code><strong>sample.dtd</strong></code>.</p>
<p>Para usar las entidades, modifica tu XUL para que se vea así:</p>
<pre class="eval"><statusbarpanel id="my-panel" label="&my-panel.label;" />
</pre>
<p>El Registro de Chrome se asegurará que el archivo de entidad es cargado desde el envoltorio de localización que se corresponda con la configuración regional seleccionada.</p>
<p>Para los strings que usas en script, crea un archivo .propertie, un archivo de texto que tiene un string en cada lína en este formato:</p>
<pre class="eval">clave=valor
</pre>
<p>y luego usa {{ interface("nsIStringBundleService") }}/{{ interface("nsIStringBundle") }} o el tag {{ XULElem("stringbundle") }} para cargar valores en el script.</p>
<h2 id="Entendiendo_el_Navegador">Entendiendo el Navegador</h2>
<p>Usa el <a href="/en-US/docs/DOM_Inspector" title="/en-US/docs/DOM_Inspector">Inspector DOM</a> para inspeccionar la ventana del navegador o cualquier otra ventana XUL que quieras extender.</p>
<p><strong>Nota:</strong> <strong>El Inspector DOM </strong>no es parte de la instalación <strong>Estándar</strong> de Firefox. Desde Firefox 3 Beta 4, el Inspector DOM está disponible desde <a class="link-https" href="https://addons.mozilla.org/en-US/firefox/addon/6622">Los Complementos de Firefox</a> como una extensión por separado. Para versiones anteriores, debes reinstalar con la dirección de instalación Personalizada y seleccionar <strong>Inspector DOM</strong> (o <strong>Developer Tools</strong> en Firefox 1.5) si no hay un ítem "Inspector DOM" en el menú de herramientas de tu navegador.</p>
<p>Usa el botón apunta-y-clickea sobre un nodo en el tope izquierdo de la barra de herramientas del Inspector DOM para clickear sobre un nodo en la ventana XUL, para seleccionar visualmente. Cuando haces esto, el inspector salta en el árbol de jerarquía DOM hacia el nodo que ha sido clickeado.</p>
<p>Usa el panel lateral derecho del Inspector DOM para descubrir puntos de fusión con ids que puedas usar para insertar tus elementos desde overlays. Si no puedes encontrar un elemento con un id que puedas fusionar, podrías necesitar enlazar un script en tu overlay e insertar tus elementos cuando se dispare el evento <code>load</code> en la ventana XUL maestra.</p>
<h2 id="Depurando_Extensiones">Depurando Extensiones</h2>
<p><strong>Herramientas Analíticas para Depuración</strong></p>
<ul>
<li>El <a href="/en-US/docs/DOM_Inspector" title="/en-US/docs/DOM_Inspector">inspector DOM</a> - inspecciona atributos, estructura DOM, reglas de estilo CSS que están activas (ej., averigua porqué tus reglas de estilo no parecen estar funcionando para un elemento - una herramienta invaluable!)</li>
<li><a href="/en-US/docs/Venkman" title="/en-US/docs/Venkman">Venkman</a> - configura puntos de quiebre (breakpoints) en JavaScript e inspecciona pilas de llamadas.</li>
<li><code>Components.stack.caller></code> en JavaScript - accede a la pila de llamada de una función</li>
</ul>
<p><strong>Depuración con printf </strong></p>
<ul>
<li>Usa <code><a href="/en-US/docs/DOM/window.dump" title="/en-US/docs/DOM/window.dump">dump</a>("string")</code> (mira el enlace para más detalles; esto requiere alguna configuración para trabajar correctamente)</li>
<li>Usa <code><a href="/en-US/docs/Components.utils.reportError" title="/en-US/docs/Components.utils.reportError">Components.utils.reportError()</a></code> o {{ interface("nsIConsoleService") }} para hacer log en la consola de JavaScript</li>
</ul>
<p><strong>Depuración avanzada</strong></p>
<ul>
<li>Ejectua un build de Firefox para depuración y configura puntos de quiebre en Firefox mismo, o tus componentes en C++. Para el desarollador experimentado, esta es frecuentemente la forma más rápida de diagnosticar un problema. Mira <a href="/en-US/docs/Developer_Guide/Build_Instructions" title="/en-US/docs/Build_Documentation">Build Documentation</a> y <a href="/en-US/docs/Developer_Guide" title="/en-US/docs/Developing_Mozilla">Developing Mozilla</a> para más información.</li>
<li>Mira <a href="/en-US/docs/Debugging_a_XULRunner_Application" title="/en-US/docs/Debugging_a_XULRunner_Application">Depurando una Aplicación XULRunner</a> para más consejos útiles.</li>
</ul>
<h2 id="Más_Información">Más Información</h2>
<ul>
<li><a href="/en-US/docs/Extension_Frequently_Asked_Questions" title="/en-US/docs/Extension_Frequently_Asked_Questions">FAQ (Preguntas Frecuentes) sobre Extensiones</a></li>
<li><a href="/en-US/docs/Extensions" title="/en-US/docs/Extensions">Extensiones</a></li>
</ul>
|