mozilla

Revision 261289 of Crear una extensión dinámica en la barra de estado

  • Enlace amigable (slug) de la revisión: Crear_una_extensión_dinámica_en_la_barra_de_estado
  • Título de la revisión: Crear una extensión dinámica en la barra de estado
  • Id de la revisión: 261289
  • Creada:
  • Creador: Superruzafa
  • ¿Es la revisión actual? No
  • Comentario Luego sigo...

Contenido de la revisión

{{wiki.template('Traducción', [ "inglés", "Creating a dynamic status bar extension", "en" ])}} {{template.AnteriorSiguiente("Crear una extensión en la barra de estado", "Añadir preferencias a una extensión")}}

Este artículo está basado en el artículo Crear una extensión en la barra de estado, el cual crea un panel estático en la barra de estado de Firefox, mejorándolo con la actualización dinámica de su contenido con información traída de la web cada pocos minutos. Concretamente, el ejemplo muestra un stock quote en la barra de estado y, cuando el ratón se mueve sobre él, muestra una ayuda emergente que contiene información más detallada sobre el stock.

Los conceptos tratados en el ejemplo anterior no se explicarán de nuevo aquí. En vez de eso, descarga el código de ejemplo o ve al anterior ejemplo para más detalles.

Descargar el ejemplo

Puedes descargar una copia de este ejemplo para echarle un vistazo o para utilizarlo como base para tu propia extensión. O si ya tienes el código del artículo [{{mediawiki.external('Crear una extensión en la barra de estado')}} puedes seguir este tutorial para actualizar dicho código existente con nuevas características.

Download the sample

Actualizar el manifiesto de instalación

Reemplaza todas las ocurrencias del ID del primer ejemplo ("status-bar-sample-1") con el ID del nuevo ejemplo ("stockwatcher") y actualiza los metadatos para describir nuestra nueva extensión.

Véase Manifiestos de instalación para más detalles.

Actualizar el manifiesto chrome

El manifiesto chrome sólo necesita una pequeña modificación desde el ejemplo anterior. Simplemente reemplaza el ID del primer ejemplo ("status-bar-sample-1") con el nombre del nuevo ejemplo ("stockwatcher").

Si necesitas un repaso, visita la sección Manifiesto Chrome.

Write the XUL file

We need a slightly more complicated XUL file this time, in order to add a reference to the JavaScript code that will do the real work:

 <?xml version="1.0" encoding="UTF-8"?>
   
 <!DOCTYPE overlay >
 <overlay id="stockwatcher-overlay"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   
 <script type="application/x-javascript"
   src="chrome://stockwatcher/content/stockwatcher.js"/>
   
 <!-- Firefox -->
 <statusbar id="status-bar">
   <statusbarpanel id="stockwatcher"
     label="Loading..."
     tooltiptext="Current value"
     onclick="StockWatcher.refreshInformation()"
   />
 </statusbar>
   
 </overlay>

Also, notice that the definition of the status bar panel now includes a new property, onclick, which references the JavaScript function that will be executed whenever the user clicks on the status bar panel. Our extension will refresh the stock information display when the user clicks the panel.

Write the JavaScript code

The work of fetching the stock quote and updating the status bar panel's display is handled by the JavaScript code in the file stockwatcher.js.

Unlike our previous sample, this one is implemented as an object. We do this because in future samples in this series, we're going to be doing things that are easier to do if our extension is implemented that way.

We use the window.addEventListener() DOM function to tell Firefox to call the StockWatcher.startup() function when a new browser window is opened:

 window.addEventListener("load", function(e) { StockWatcher.startup(); }, false);

Our new extension has two primary functions: startup() and refreshInformation(). The refreshInformation() function contains another function, called infoReceived(). The following sections will examine these one by one.

startup()

The startup() function is called when a new browser window is opened. We end up reloading data from each of the windows once in 10 minutes - fixing this by creating a JS component responsible for communication with the server is a good idea for one of the future articles

   startup: function()
   {
     this.refreshInformation();
     window.setInterval(this.refreshInformation, 10*60*1000);
   },

This starts by calling our refreshInformation() function, which is responsible for fetching and displaying stock ticker information in the status bar panel. We do this so that upon loading, the stock information is displayed as soon as possible.

After doing that, we install an interval routine on the browser window by calling window.setInterval(). This configures our refreshInformation() routine to be called every 10 minutes (the time interval is specified in milliseconds).

refreshInformation()

The refreshInformation() function is called whenever we want to update the stock information. It's called whenever the user clicks on the status bar panel, when our extension is first added to a browser window, and by the interval handler to periodically update the display.

   refreshInformation: function()
   {
     var httpRequest = null;
     var fullUrl = "http://quote.yahoo.com/d/quotes.csv?f=sl1d1t1c1ohgv&e=.csv&s=GOOG";
     
     ...
     
     httpRequest = new XMLHttpRequest();
     
     httpRequest.open("GET", fullUrl, true);
     httpRequest.onload = infoReceived;
     httpRequest.send(null);
   }
 }

The httpRequest variable will contain an XMLHttpRequest object. This object is used to configure and run an HTTP request on a web server, which we'll use to fetch the stock quote data.

The fullUrl variable is the complete URL to use when requesting a stock quote. In this case, we're using Yahoo's comma-separated values return to fetch easily-parsed stock quote data for Google (ticker symbol GOOG).

refreshInformation() embeds another function, infoReceived(), which we'll look at separately shortly.

The first thing we do is create a new XMLHttpRequest object to use for processing our request. We open the request, specifying that we wish to perform an HTTP "GET" command with the URL fullUrl. The true Boolean value in the third parameter indicates that we want to process the request asynchronously.

Setting the httpRequest.onload property to our infoReceived() function configures the request to call infoReceived() when the response is received from the server. Finally, we send the request to the server and return.

infoReceived()

When the server responds to our request, our the infoReceived() function, which is embedded inside refreshInformation(), gets called automatically.

We embed this function inside refreshInformation() so that its variable scope includes the variables used by that function. Due to the way JavaScript works, if infoReceived() were outside refreshInformation(), it would not have access to the same variable scope. In fact, even the this value would not match, so we couldn't get at the same variables and functions that way.

     function infoReceived()
     {
       var samplePanel = document.getElementById('stockwatcher');
       var output = httpRequest.responseText;
         
       if (output.length)
       {
         // Remove whitespace from the end of the string;
         // this gets rid of the end-of-line characters
 
         output = output.replace(/\W*$/, "");        
       
         // Build the tooltip string
       
         var fieldArray = output.split(","); assert that fieldArray[0] == "GOOG"
         samplePanel.label = "GOOG: " + fieldArray[1];
         samplePanel.tooltipText = "Chg: " + fieldArray[4] + " | " +
             "Open: " + fieldArray[5] + " | " +
             "Low: " + fieldArray[6] + " | " +
             "High: " + fieldArray[7] + " | " +
             "Vol: " + fieldArray[8];
       }
     }

The first thing we do here is get the status bar panel into the variable samplePanel by calling the document.getElementById() DOM function. We need this so that we can make changes to the status bar panel itself.

We then fetch the result returned by the web server into the variable output from the XMLHttpRequest.responseText property.

The text we receive back from the server looks something like this:

 "GOOG",414.20,"5/1/2006","1:36pm",-3.74,417.85,419.44,412.19,4760215

We then parse the text. We use the split() string function to split the comma-separated value string into its individual parts, with each field in a separate element in the array fieldArray. At index 0 is the ticker symbol itself, which we don't need since we know which stock we're looking at.

The status bar panel's label is set to indicate the current value of the stock, which is stored in fieldArray{{mediawiki.external(1)}}, by setting the samplePanel.label property.

We then set the tooltip for the status bar panel by assigning an appropriate string to the samplePanel.tooltipText property. The string is built from a combination of static strings and various elements from the fieldArray array.

See it in action

Now you can install it and try it out. You should see something that looks like this:

<center>

Image:stockwatcher.png

</center>

In this screenshot, we also have the previous sample running, displaying the text "Hello World." {{template.PreviousNext("Creating a status bar extension", "Adding preferences to an extension")}}

{{ wiki.languages( { "pl": "pl/Tworzenie_rozszerzenia_dynamicznego_paska_stanu" } ) }}

Fuente de la revisión

<p>
</p><p>{{wiki.template('Traducción', [ "inglés", "Creating a dynamic status bar extension", "en" ])}}
{{template.AnteriorSiguiente("Crear una extensión en la barra de estado", "Añadir preferencias a una extensión")}}
</p><p>Este artículo está basado en el artículo <a href="es/Crear_una_extensi%c3%b3n_en_la_barra_de_estado">Crear una extensión en la barra de estado</a>, el cual crea un panel estático en la barra de estado de Firefox, mejorándolo con la actualización dinámica de su contenido con información traída de la web cada pocos minutos. Concretamente, el ejemplo muestra un stock quote en la barra de estado y, cuando el ratón se mueve sobre él, muestra una ayuda emergente que contiene información más detallada sobre el stock.
</p><p>Los conceptos tratados en el ejemplo anterior no se explicarán de nuevo aquí. En vez de eso, descarga el código de ejemplo o ve al anterior ejemplo para más detalles.
</p>
<h2 name="Descargar_el_ejemplo"> Descargar el ejemplo </h2>
<p>Puedes descargar una copia de este ejemplo para echarle un vistazo o para utilizarlo como base para tu propia extensión. O si ya tienes el código del artículo [{{mediawiki.external('Crear una extensión en la barra de estado')}} puedes seguir este tutorial para actualizar dicho código existente con nuevas características.
</p><p><a class="external" href="http://developer.mozilla.org/samples/extension-samples/stockwatcher.zip">Download the sample</a>
</p>
<h2 name="Actualizar_el_manifiesto_de_instalaci.C3.B3n"> Actualizar el manifiesto de instalación </h2>
<p>Reemplaza todas las ocurrencias del ID del primer ejemplo ("status-bar-sample-1") con el ID del nuevo ejemplo ("stockwatcher") y actualiza los metadatos para describir nuestra nueva extensión.
</p><p>Véase <a href="es/Manifiestos_de_instalaci%c3%b3n">Manifiestos de instalación</a> para más detalles.
</p>
<h2 name="Actualizar_el_manifiesto_chrome"> Actualizar el manifiesto chrome </h2>
<p>El manifiesto <a href="es/Chrome">chrome</a> sólo necesita una pequeña modificación desde el ejemplo anterior. Simplemente reemplaza el ID del primer ejemplo ("status-bar-sample-1") con el nombre del nuevo ejemplo ("stockwatcher").
</p><p>Si necesitas un repaso, visita la sección <a href="es/Manifiesto_Chrome">Manifiesto Chrome</a>.
</p>
<h2 name="Write_the_XUL_file">Write the XUL file</h2>
<p>We need a slightly more complicated XUL file this time, in order to add a reference to the JavaScript code that will do the real work:
</p>
<pre class="eval"> &lt;?xml version="1.0" encoding="UTF-8"?&gt;
   
 &lt;!DOCTYPE overlay &gt;
 &lt;overlay id="stockwatcher-overlay"
   xmlns="<span class="plain">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</span>"&gt;
   
 &lt;script type="application/x-javascript"
   src="<span class="plain">chrome://stockwatcher/content/stockwatcher.js</span>"/&gt;
   
 &lt;!-- Firefox --&gt;
 &lt;statusbar id="status-bar"&gt;
   &lt;statusbarpanel id="stockwatcher"
     label="Loading..."
     tooltiptext="Current value"
     onclick="StockWatcher.refreshInformation()"
   /&gt;
 &lt;/statusbar&gt;
   
 &lt;/overlay&gt;
</pre>
<p>Also, notice that the definition of the status bar panel now includes a new property, <code>onclick</code>, which references the JavaScript function that will be executed whenever the user clicks on the status bar panel.  Our extension will refresh the stock information display when the user clicks the panel.
</p>
<h2 name="Write_the_JavaScript_code">Write the JavaScript code</h2>
<p>The work of fetching the stock quote and updating the status bar panel's display is handled by the JavaScript code in the file <code>stockwatcher.js</code>.
</p><p>Unlike our previous sample, this one is implemented as an object.  We do this because in future samples in this series, we're going to be doing things that are easier to do if our extension is implemented that way.
</p><p>We use the <code>window.addEventListener()</code> DOM function to tell Firefox to call the <code>StockWatcher.startup()</code> function when a new browser window is opened:
</p>
<pre class="eval"> window.addEventListener("load", function(e) { StockWatcher.startup(); }, false);
</pre>
<p>Our new extension has two primary functions: <code>startup()</code> and <code>refreshInformation()</code>.  The <code>refreshInformation()</code> function contains another function, called <code>infoReceived()</code>.  The following sections will examine these one by one.
</p>
<h3 name="startup.28.29">startup()</h3>
<p>The <code>startup()</code> function is called when a new browser window is opened. <span class="comment">We end up reloading data from each of the windows once in 10 minutes - fixing this by creating a JS component responsible for communication with the server is a good idea for one of the future articles</span>
</p>
<pre class="eval">   startup: function()
   {
     this.refreshInformation();
     window.setInterval(this.refreshInformation, 10*60*1000);
   },
</pre>
<p>This starts by calling our <code>refreshInformation()</code> function, which is responsible for fetching and displaying stock ticker information in the status bar panel.  We do this so that upon loading, the stock information is displayed as soon as possible.
</p><p>After doing that, we install an interval routine on the browser window by calling <code><a href="es/DOM/window.setInterval">window.setInterval()</a></code>.  This configures our <code>refreshInformation()</code> routine to be called every 10 minutes (the time interval is specified in milliseconds).
</p>
<h3 name="refreshInformation.28.29">refreshInformation()</h3>
<p>The <code>refreshInformation()</code> function is called whenever we want to update the stock information.  It's called whenever the user clicks on the status bar panel, when our extension is first added to a browser window, and by the interval handler to periodically update the display.
</p>
<pre class="eval">   refreshInformation: function()
   {
     var httpRequest = null;
     var fullUrl = "http://quote.yahoo.com/d/quotes.csv?f=sl1d1t1c1ohgv&amp;e=.csv&amp;s=GOOG";
     
     ...
     
     httpRequest = new XMLHttpRequest();
     
     httpRequest.open("GET", fullUrl, true);
     httpRequest.onload = infoReceived;
     httpRequest.send(null);
   }
 }
</pre>
<p>The <code>httpRequest</code> variable will contain an <code><a href="es/XMLHttpRequest">XMLHttpRequest</a></code> object.  This object is used to configure and run an HTTP request on a web server, which we'll use to fetch the stock quote data.
</p><p>The <code>fullUrl</code> variable is the complete URL to use when requesting a stock quote.  In this case, we're using Yahoo's comma-separated values return to fetch easily-parsed stock quote data for Google (ticker symbol GOOG).
</p><p><code>refreshInformation()</code> embeds another function, <code>infoReceived()</code>, which we'll look at separately shortly.
</p><p>The first thing we do is create a new <code>XMLHttpRequest</code> object to use for processing our request.  We open the request, specifying that we wish to perform an HTTP "GET" command with the URL <code>fullUrl</code>.  The <code>true</code> Boolean value in the third parameter indicates that we want to process the request asynchronously.
</p><p>Setting the <code>httpRequest.onload</code> property to our <code>infoReceived()</code> function configures the request to call <code>infoReceived()</code> when the response is received from the server.  Finally, we send the request to the server and return.
</p>
<h3 name="infoReceived.28.29">infoReceived()</h3>
<p>When the server responds to our request, our the <code>infoReceived()</code> function, which is embedded inside <code>refreshInformation()</code>, gets called automatically.
</p><p>We embed this function inside <code>refreshInformation()</code> so that its variable scope includes the variables used by that function.  Due to the way JavaScript works, if <code>infoReceived()</code> were outside <code>refreshInformation()</code>, it would not have access to the same variable scope.  In fact, even the <code>this</code> value would not match, so we couldn't get at the same variables and functions that way.
</p>
<pre class="eval">     function infoReceived()
     {
       var samplePanel = document.getElementById('stockwatcher');
       var output = httpRequest.responseText;
         
       if (output.length)
       {
         // Remove whitespace from the end of the string;
         // this gets rid of the end-of-line characters
 
         output = output.replace(/\W*$/, "");        
       
         // Build the tooltip string
       
         var fieldArray = output.split(","); <span class="comment">assert that fieldArray[0] == "GOOG"</span>
         samplePanel.label = "GOOG: " + fieldArray[1];
         samplePanel.tooltipText = "Chg: " + fieldArray[4] + " | " +
             "Open: " + fieldArray[5] + " | " +
             "Low: " + fieldArray[6] + " | " +
             "High: " + fieldArray[7] + " | " +
             "Vol: " + fieldArray[8];
       }
     }
</pre>
<p>The first thing we do here is get the status bar panel into the variable <code>samplePanel</code> by calling the <code><a href="es/DOM/document.getElementById">document.getElementById()</a></code> DOM function.  We need this so that we can make changes to the status bar panel itself.
</p><p>We then fetch the result returned by the web server into the variable <code>output</code> from the <code>XMLHttpRequest.responseText</code> property.
</p><p>The text we receive back from the server looks something like this:
</p>
<pre class="eval"> "GOOG",414.20,"5/1/2006","1:36pm",-3.74,417.85,419.44,412.19,4760215
</pre>
<p>We then parse the text.  We use the <code>split()</code> string function to split the comma-separated value string into its individual parts, with each field in a separate element in the array <code>fieldArray</code>.  At index 0 is the ticker symbol itself, which we don't need since we know which stock we're looking at.
</p><p>The status bar panel's label is set to indicate the current value of the stock, which is stored in <code>fieldArray{{mediawiki.external(1)}}</code>, by setting the <code>samplePanel.label</code> property.
</p><p>We then set the tooltip for the status bar panel by assigning an appropriate string to the <code>samplePanel.tooltipText</code> property.  The string is built from a combination of static strings and various elements from the <code>fieldArray</code> array.
</p>
<h2 name="See_it_in_action">See it in action</h2>
<p>Now you can install it and try it out.  You should see something that looks like this:
</p>
<center>
<p><img alt="Image:stockwatcher.png" src="File:es/Media_Gallery/Stockwatcher.png">
</p>
</center>
<p>In this screenshot, we also have the previous sample running, displaying the text "Hello World."
{{template.PreviousNext("Creating a status bar extension", "Adding preferences to an extension")}}
</p>{{ wiki.languages( { "pl": "pl/Tworzenie_rozszerzenia_dynamicznego_paska_stanu" } ) }}
Revertir a esta revisión