mozilla

Comparar revisiones

Trabajar con ventanas desde código chrome

Change Revisions

Revisión 271037:

Revisión 271037 de another_sam el

Revisión 206776:

Revisión 206776 de another_sam el

Título:
Trabajar con ventanas desde código chrome
Trabajar con ventanas desde código chrome
Enlace amigable (slug):
Trabajar_con_ventanas_desde_código_chrome
Trabajar_con_ventanas_desde_código_chrome
Etiquetas:
Extensions, páginas_a_traducir
Contenido:

Revisión 271037
Revisión 206776
t7    <p>t
8      {{ Traducción("inglés", "Working_with windows in chrome cod
>e", "en") }} 
9    </p>
10    <p>
11      <br>
12      Este artículo describe el trabajo con múltiples ventanas en
> código chrome Mozilla (aplicaciones XUL y extensiones). Contiene 
> trucos y código de ejemplo para abrir nuevas ventanas, encontrar 
> las ventanas ya abiertas, y pasar datos entre diferentes ventana 
>s. 
13    </p>
14    <h3 id="Abrir_ventanas">
15      Abrir ventanas
16    </h3>
17    <p>
18      Para abrir una ventana nueva, solemos usar la llamada DOM w
>indow.open o window.openDialog, así: 
19    </p>
20    <pre class="eval">
21var win = window.open("<a class=" external" href="chrome://myexte
>nsion/content/about.xul" rel="freelink">chrome://myextension/cont 
>ent/about.xul</a>",  
22                      "aboutMyExtension", "chrome,centerscreen");
>  
23</pre>
24    <p>
25      El primer parámetro de window.open es la URI del archivo XU
>L que describe la ventana y su contenido. 
26    </p>
27    <p>
28      El segundo parámetro es el nombre de la ventana. El nombre 
>de la ventana puede ser usado en enlaces o formularios como el at 
>ributo target. Esto es diferente del título de ventana visible po 
>r el usuario, que es especificado usando XUL. 
29    </p>
30    <p>
31      El tercer, y opcional, parámetro es una lista de las caract
>erísticas especiales que la ventana debería tener. 
32    </p>
33    <p>
34      La función window.openDialog funciona de forma similar, per
>o te permite especificar argumentos opcionales que pueden ser ref 
>erenciados desde el código JavaScript. También maneja las funcion 
>es de ventana de forma un poco distinta, suponiendo siempre que l 
>a funcionalidad dialog es especificada. 
35    </p>
36    <p>
37      Si el objeto Window no está disponible (por ejemplo, al abr
>ir una ventana desde código de componente XPCOM), puedes querer u 
>sar la interfaz nsiWindowWatcher. Sus parámetros son similares a  
>window.open. En realidad, la implementación de window.open llama  
>a métodos de nsiWindowWatcher. 
38    </p>
39    <pre class="eval">
40var ww = Components.classes["@mozilla.org/embedcomp/window-watche
>r;1"] 
41                   .getService(Components.interfaces.nsIWindowWat
>cher); 
42var win = ww.openWindow(null, "<a class=" external" href="chrome:
>//myextension/content/about.xul" rel="freelink">chrome://myextens 
>ion/content/about.xul</a>", 
43                        "aboutMyExtension", "chrome,centerscreen"
>, null); 
44</pre>
45    <h3 id="Window_object" name="Window_object">
46      Window object
47    </h3>
48    <p>
49      Note the <code>win</code> variable in the above section, wh
>ich is assigned the return value of <code>window.open</code>. It  
>can be used to access the opened window. The return value of <cod 
>e>window.open</code> (and similar methods) is a <code><a class="e 
>xternal" href="http://xulplanet.com/references/objref/Window.html 
>">Window</a></code> object (usually <code><a class="external" hre 
>f="http://xulplanet.com/references/objref/ChromeWindow.html">Chro 
>meWindow</a></code>), of the same type that the <code>window</cod 
>e> variable. 
50    </p>
51    <p>
52      Technically speaking, it implements a number of interfaces,
> including <code><a href="/es/NsIDOMJSWindow" title="es/NsIDOMJSW 
>indow">nsIDOMJSWindow</a></code> and <code><a href="/es/NsIDOMWin 
>dowInternal" title="es/NsIDOMWindowInternal">nsIDOMWindowInternal 
></a></code>, but it also contains the user-defined properties for 
> global variables and functions of the window. So, for example, t 
>o access the DOM document corresponding to the window, you can us 
>e <code><a href="/es/DOM/window.document" title="es/DOM/window.do 
>cument">win.document</a></code>. 
53    </p>
54    <p>
55      Note however, that the <code>open()</code> call returns <em
>>before</em> the window is fully loaded, so some calls, like <cod 
>e><a href="/es/DOM/document.getElementById" title="es/DOM/documen 
>t.getElementById">win.document.getElementById()</a></code> will f 
>ail. To overcome this difficulty, you can move the initialization 
> code to a <code>load</code> handler of the window being opened o 
>r pass a callback function, as described <a href="#callback">belo 
>w</a>. 
56    </p>
57    <p>
58      You can get a <code>Window</code> object from a document us
>ing <code><a href="/es/DOM/document.defaultView" title="es/DOM/do 
>cument.defaultView">document.defaultView</a></code>. 
59    </p>
60    <h3 id="Content_windows" name="Content_windows">
61      Content windows
62    </h3>
63    <p>
64      When a XUL window contains a widget capable of displaying a
> page, such as <code>&lt;browser&gt;</code> or <code>&lt;iframe&g 
>t;</code>, the document in that widget is, naturally, separate fr 
>om the document of the chrome window itself. There also is a <cod 
>e>Window</code> object for each sub-document, although there's no 
> window in a common sense for the sub-document. 
65    </p>
66    <p>
67      The same holds for chrome windows opened inside a tab of <c
>ode>&lt;tabbrowser&gt;</code>. The elements above the chrome docu 
>ment opened in the tab are separate from your chrome document. 
68    </p>
69    <p>
70      The following two subsections describe how to cross chrome-
>content boundaries in either way, i.e. accessing elements which a 
>re ancestors of your chrome document, or accessing elements which 
> are descendants of your chrome document (but nevertheless in a d 
>ifferent context). 
71    </p>
72    <h4 id="Accessing_content_documents" name="Accessing_content_
>documents"> 
73      Accessing content documents
74    </h4>
75    <p>
76      Assume you have a document loaded in a <code>&lt;tabbrowser
>&gt;</code>, <code>&lt;browser&gt;</code>, or <code>&lt;iframe&gt 
>;</code> element inside your document. You can use <code>browser. 
>contentDocument</code> to access that document and <code>browser. 
>contentWindow</code> to the <code>Window</code> object of that do 
>cument. 
77    </p>
78    <p>
79      You should be aware of <a href="/es/XPCNativeWrapper" title
>="es/XPCNativeWrapper">XPCNativeWrappers</a> when working with <a 
> href="/es/XPCNativeWrapper#What_is_a_trusted_window.3F" title="e 
>s/XPCNativeWrapper#What_is_a_trusted_window.3F">untrusted content 
></a>. With XPCNativeWrappers turned on (which is the default in F 
>irefox 1.5+), your extension can safely access the DOM of the con 
>tent document, but not the content JavaScript. Bypassing XPCNativ 
>eWrapper to work with content JavaScript directly can lead to sec 
>urity problems. 
80    </p>
81    <p>
82      See <a href="/es/Code_snippets/Interaction_between_privileg
>ed_and_non-privileged_pages" title="es/Code_snippets/Interaction_ 
>between_privileged_and_non-privileged_pages">Interaction between  
>privileged and non-privileged pages</a> if you need to interact w 
>ith the content page. 
83    </p>
84    <h5 id="The_content_shortcut" name="The_content_shortcut">
85      The <code>content</code> shortcut
86    </h5>
87    <p>
88      In case of <code>&lt;browser type="content-primary"/&gt;</c
>ode>, you can use the <a href="/es/DOM/window.content" title="es/ 
>DOM/window.content">content</a> shortcut property to accesss the  
><code>Window</code> object of the content document. For example: 
89    </p>
90    <pre class="eval">
91// alerts the title of the document displayed in the content-prim
>ary widget 
92 
93alert(content.document.title);
94</pre>
95    <p>
96      For example, you can use <code>content.document</code> in a
> <code>browser.xul</code> overlay to access the web page in the s 
>elected tab in a Firefox window. 
97    </p>
98    <div class="note">
99      Some examples use <code>_content</code> instead of <code>co
>ntent</code>. The former has been deprecated for a while, and you 
> should use <code>content</code> in the new code. 
100    </div>
101    <h4 id="Accessing_a_document_in_the_sidebar" name="Accessing_
>a_document_in_the_sidebar"> 
102      Accessing a document in the sidebar
103    </h4>
104    <p>
105      Firefox has a sidebar, which is implemented as a <code>&lt;
>browser&gt;</code> element with id="sidebar". To access the eleme 
>nts and variables inside the sidebar, you need to use <code>docum 
>ent.getElementById("sidebar").contentDocument</code> or <code>.co 
>ntentWindow</code>, like when {{ Anch("Accessing content document 
>s") }}. 
106    </p>
107    <p>
108      For more sidebar tips, see <a href="/es/Code_snippets/Sideb
>ar" title="es/Code_snippets/Sidebar">Code snippets:Sidebar</a>. 
109    </p>
110    <h4 id="Accessing_the_elements_of_the_top-level_document_from
>_a_child_window" name="Accessing_the_elements_of_the_top-level_do 
>cument_from_a_child_window"> 
111      Accessing the elements of the top-level document from a chi
>ld window 
112    </h4>
113    <p>
114      The opposite case is when you want to access the chrome doc
>ument from a privileged script loaded in a <code>&lt;browser&gt;< 
>/code> or an <code>&lt;iframe&gt;</code>. 
115    </p>
116    <p>
117      A typical case when this can be useful is when your code ru
>ns in the sidebar in the main Firefox window and you want to acce 
>ss the elements in the main browser window. 
118    </p>
119    <p>
120      The DOM tree, as shown by the <a href="/es/DOM_Inspector" t
>itle="es/DOM_Inspector">DOM Inspector</a>, can look like this: 
121    </p>
122    <pre class="eval">
123#document
124  window                 main-window
125    ...
126      browser
127        #document
128          window         myExtensionWindow
129</pre>
130    <p>
131      where the child window is where your code runs in.
132    </p>
133    <p>
134      Your task is to access elements above your chrome document,
> i.e. to break out of your chrome window and access the ancestors 
>. This can be done using the following statement: 
135    </p>
136    <pre class="eval">
137var mainWindow = window.QueryInterface(Components.interfaces.nsII
>nterfaceRequestor) 
138                   .getInterface(Components.interfaces.nsIWebNavi
>gation) 
139                   .QueryInterface(Components.interfaces.nsIDocSh
>ellTreeItem) 
140                   .rootTreeItem
141                   .QueryInterface(Components.interfaces.nsIInter
>faceRequestor) 
142                   .getInterface(Components.interfaces.nsIDOMWind
>ow)  
143</pre>
144    <p>
145      This allows you to cross the chrome-content boundaries, and
> returns the main window object. 
146    </p>
147    <h3 id="Finding_already_opened_windows" name="Finding_already
>_opened_windows"> 
148      Finding already opened windows
149    </h3>
150    <p>
151      The window mediator XPCOM component (<a href="/es/NsIWindow
>Mediator" title="es/NsIWindowMediator">nsIWindowMediator</a> inte 
>rface) provides information about existing windows. Two of its me 
>thods are often used to obtain information about currently open w 
>indows: <code>getMostRecentWindow</code> and <code>getEnumerator< 
>/code>. Please refer to the <a href="/es/NsIWindowMediator" title 
>="es/NsIWindowMediator">nsIWindowMediator</a> page for more infor 
>mation and examples of using <code>nsIWindowMediator</code>. <spa 
>n class="comment">=== Example: Opening a window only if it's not  
>opened already === XXX TBD</span> 
152    </p>
153    <h3 id="Passing_data_between_windows" name="Passing_data_betw
>een_windows"> 
154      Passing data between windows
155    </h3>
156    <p>
157      When working with multiple windows, you often need to pass 
>information from one window to another. Since different windows h 
>ave separate DOM documents and global objects for scripts, you ca 
>n't just use one global JavaScript variable in scripts from diffe 
>rent windows. 
158    </p>
159    <p>
160      There are several techniques of varying power and simplicit
>y that can be used to share data. We'll demonstrate them from the 
> simplest to the most complex in the next few sections. 
161    </p>
162    <h4 id="Example_1:_Passing_data_to_window_when_opening_it_wit
>h_openDialog" name="Example_1:_Passing_data_to_window_when_openin 
>g_it_with_openDialog"> 
163      Example 1: Passing data to window when opening it with <cod
>e>openDialog</code> 
164    </h4>
165    <p>
166      When you open a window using <code><a href="/es/DOM/window.
>openDialog" title="es/DOM/window.openDialog">window.openDialog</a 
>></code> or <code>nsIWindowWatcher.openWindow</code>, you can pas 
>s an arbitrary number of <em>arguments</em> to that window. Argum 
>ents are simple JavaScript objects, accessible through <code><a h 
>ref="/es/DOM/window.arguments" title="es/DOM/window.arguments">wi 
>ndow.arguments</a></code> property in the opened window. 
167    </p>
168    <p>
169      In this example, we're using <code>window.openDialog</code>
> to open a progress dialog. We pass in the current status text as 
> well as the maximum and current progress values. Note that using 
> <code>nsIWindowWatcher.openWindow</code> is a bit less trivial < 
>a class="external" href="http://lxr.mozilla.org/seamonkey/source/ 
>extensions/help/resources/content/contextHelp.js#70"></a>. <span  
>class="comment">TODO: link to <a href="/es/How_To_Pass_an_XPCOM_O 
>bject_to_a_New_Window" title="es/How_To_Pass_an_XPCOM_Object_to_a 
>_New_Window">How To Pass an XPCOM Object to a New Window</a> when 
> it has a more useful example</span> 
170    </p>
171    <p>
172      Opener code:
173    </p>
174    <pre class="eval">
175window.openDialog("<a class=" external" href="chrome://test/conte
>nt/progress.xul" rel="freelink">chrome://test/content/progress.xu 
>l</a>", 
176                  "myProgress", "chrome,centerscreen", 
177                  {status: "Reading remote data", maxProgress: 50
>, progress: 10} ); 
178</pre>
179    <p>
180      <code>progress.xul</code>:
181    </p>
182    <pre>
183&lt;?xml version="1.0"?&gt;
184&lt;?xml-stylesheet href="chrome://global/skin/" type="text/css"?
>&gt; 
185 
186&lt;window onload="onLoad();" xmlns="http://www.mozilla.org/keyma
>ster/gatekeeper/there.is.only.xul"&gt; 
187&lt;script&gt;&lt;![CDATA[
188  var gStatus, gProgressMeter;
189  var maxProgress = 100;
190  function onLoad() {
191    gStatus = document.getElementById("status");
192    gProgressMeter = document.getElementById("progressmeter");
193  
194    if("arguments" in window &amp;&amp; window.arguments.length &
>gt; 0) { 
195      maxProgress = window.arguments[0].maxProgress;
196      setProgress(window.arguments[0].progress);
197      setStatus(window.arguments[0].status);
198    }
199  }
200 
201  function setProgress(value) {
202    gProgressMeter.value = 100 * value / maxProgress;
203  }
204 
205  function setStatus(text) {
206    gStatus.value = "Status: " + text + "...";
207  }
208]]&gt;&lt;/script&gt;
209 
210&lt;label id="status" value="(No status)"/&gt;
211&lt;hbox&gt;
212  &lt;progressmeter id="progressmeter" mode="determined"/&gt;
213  &lt;button label="Cancel" oncommand="close();"/&gt;
214&lt;/hbox&gt;
215 
216&lt;/window&gt;
217</pre>
218    <h4 id="Example_2:_Interacting_with_the_opener" name="Example
>_2:_Interacting_with_the_opener"> 
219      Example 2: Interacting with the opener
220    </h4>
221    <p>
222      Sometimes an opened window needs to interact with its opene
>r; for example, it might do so in order to give notice that the u 
>ser has made changes in the window. You can find the window's ope 
>ner using its <a href="/es/Window.opener" title="es/Window.opener 
>">window.opener</a> property or via a callback function passed to 
> the window in a way described in the previous section. 
223    </p>
224    <p>
225      Let's add code to the previous example to notify the opener
> when the user presses Cancel on the progress dialog. 
226    </p>
227    <ul>
228      <li>
229        <strong>Using <code>window.opener</code>.</strong> The <c
>ode>opener</code> property returns its window's opener; that is,  
>the {{ Anch("Window object") }} that opened it. 
230      </li>
231    </ul>
232    <p>
233      If we're sure the window that opened the progress dialog de
>clares the <code>cancelOperation</code> function, we can use <cod 
>e>window.opener.cancelOperation()</code> to notify it, like this: 
234    </p>
235    <pre class="eval">
236&lt;button label="Cancel" oncommand="<strong>opener.cancelOperati
>on();</strong> close();"/&gt; 
237</pre>
238    <ul>
239      <li>
240        <strong>Using a callback function.</strong> Alternatively
>, the opener window can pass a callback function to the progress  
>dialog in the same way we passed the status string in the previou 
>s example: 
241      </li>
242    </ul>
243    <pre class="eval">
244function onCancel() {
245  alert("Operation canceled!");
246}
247 
248...
249 
250window.openDialog("<a class=" external" href="chrome://test/conte
>nt/progress.xul" rel="freelink">chrome://test/content/progress.xu 
>l</a>", 
251                  "myProgress", "chrome,centerscreen", 
252                  {status: "Reading remote data", maxProgress: 50
>, progress: 10}, 
253                  <strong>onCancel</strong>); 
254</pre>
255    <p>
256      The progress dialog can then run the callback like this:
257    </p>
258    <pre class="eval">
259&lt;button label="Cancel" oncommand="<strong>window.arguments[1](
>);</strong> close();"/&gt; 
260</pre>
261    <h4 id="Example_3:_Using_nsIWindowMediator_when_opener_is_not
>_enough" name="Example_3:_Using_nsIWindowMediator_when_opener_is_ 
>not_enough"> 
262      Example 3: Using <code>nsIWindowMediator</code> when <code>
>opener</code> is not enough 
263    </h4>
264    <p>
265      The <code>window.opener</code> property is very easy to use
>, but it's only useful when you're sure that your window was open 
>ed from one of a few well-known places. In more complicated cases 
> you need to use the <code><a href="/es/NsIWindowMediator" title= 
>"es/NsIWindowMediator">nsIWindowMediator</a></code> interface, in 
>troduced above. 
266    </p>
267    <p>
268      One case in which you might want to use <code>nsIWindowMedi
>ator</code> is in an extension's Options window. Suppose you're d 
>eveloping a browser extension that consists of a browser.xul over 
>lay and an Options window. Suppose the overlay contains a button  
>to open the extension's Options window which needs to read some d 
>ata from the browser window. As you may remember, Firefox's Exten 
>sion Manager can also be used to open your Options dialog. 
269    </p>
270    <p>
271      This means the value of <code>window.opener</code> in your 
>Options dialog is not necessarily the browser window -- instead,  
>it might be the Extension Manager window. You could check the <co 
>de>location</code> property of the <code>opener</code> and use <c 
>ode>opener.opener</code> in case it's the Extension Manager windo 
>w, but a better way is to use <code>nsIWindowMediator</code>: 
272    </p>
273    <pre class="eval">
274var wm = Components.classes["@mozilla.org/appshell/window-mediato
>r;1"] 
275                   .getService(Components.interfaces.nsIWindowMed
>iator); 
276var browserWindow = wm.getMostRecentWindow("navigator:browser");
277// read values from |browserWindow|
278</pre>
279    <p>
280      You might be tempted to use a similar technique to apply th
>e changes the user made in the Options dialog, but a better way t 
>o do that is to use <a class="external" href="http://kb.mozillazi 
>ne.org/Dev_:_Using_preferences#Using_preferences_observers">prefe 
>rences observers</a>. 
281    </p>
282    <h3 id="Advanced_data_sharing" name="Advanced_data_sharing">
283      Advanced data sharing
284    </h3>
285    <p>
286      The above code is useful when you need to pass data from on
>e window to another or to a set of windows, but sometimes you jus 
>t want to share a JavaScript variable in common between different 
> windows. You could declare a local variable in each window along 
> with corresponding setter functions to keep the "instances" of t 
>he variable in sync across windows, but fortunately, there's a be 
>tter way. 
287    </p>
288    <p>
289      To declare a shared variable, we need to find a place that 
>exists while the application is running and is easily accessible  
>from the code in different chrome windows. There are actually a f 
>ew such places. 
290    </p>
291    <h4 id="Using_JavaScript_code_modules" name="Using_JavaScript
>_code_modules"> 
292      Using JavaScript code modules
293    </h4>
294    <p>
295      <a href="/es/Using_JavaScript_code_modules" title="es/Using
>_JavaScript_code_modules">JavaScript code modules</a> {{ Fx_minve 
>rsion_inline("3") }} is a simple method for creating shared globa 
>l singleton objects that can be imported into any other JavaScrip 
>t scope. The importing scope will have access to the objects and  
>data in the code module. Since the code module is cached, all sco 
>pes get the same instance of the code module and can share the da 
>ta in the module. See <a href="/es/Components.utils.import" title 
>="es/Components.utils.import">Components.utils.import</a> for mor 
>e information. 
296    </p>
297    <ul>
298      <li>Pros:
299        <ul>
300          <li>It's the "right way"
301          </li>
302          <li>Very simple to make and import.
303          </li>
304          <li>No need to build an XPCOM component.
305          </li>
306        </ul>
307      </li>
308      <li>Cons:
309        <ul>
310          <li>Only works in Firefox 3 or newer.
311          </li>
312          <li>The scope is shared between modules and the importi
>ng scope, so you have to worry about name collisions. 
313          </li>
314          <li>You can't use the <code><a href="/es/DOM/window" ti
>tle="es/DOM/window">window</a></code> object, its members, like < 
>code>alert</code> and <code>open</code>, and many other objects a 
>vailable from inside a window. The functionality isn't lost, howe 
>ver -- you just have to use the XPCOM components directly instead 
> of using convenient shortcuts. Of course, this doesn't matter if 
> you just store data in the component. 
315          </li>
316        </ul>
317      </li>
318    </ul>
319    <h4 id="Using_an_XPCOM_singleton_component" name="Using_an_XP
>COM_singleton_component"> 
320      Using an XPCOM singleton component
321    </h4>
322    <p>
323      The cleanest and most powerful way to share data is to defi
>ne your own XPCOM component (you can <a href="/es/How_to_Build_an 
>_XPCOM_Component_in_Javascript" title="es/How_to_Build_an_XPCOM_C 
>omponent_in_Javascript">write one in JavaScript</a>) and access i 
>t from anywhere using a <code>getService</code> call: 
324    </p>
325    <pre class="eval">
326Components.classes["@domain.org/mycomponent;1"].getService();
327</pre>
328    <ul>
329      <li>Pros:
330        <ul>
331          <li>It's the "right way".
332          </li>
333          <li>You can store arbitrary JavaScript objects in the c
>omponent. 
334          </li>
335          <li>The scope is not shared between components, so you 
>don't have to worry about name collisions. 
336          </li>
337          <li>Works in older versions of Firefox.
338          </li>
339        </ul>
340      </li>
341      <li>Cons:
342        <ul>
343          <li>You can't use the <code><a href="/es/DOM/window" ti
>tle="es/DOM/window">window</a></code> object, its members, like < 
>code>alert</code> and <code>open</code>, and many other objects a 
>vailable from inside a window. The functionality isn't lost, howe 
>ver -- you just have to use the XPCOM components directly instead 
> of using convenient shortcuts. Of course, this doesn't matter if 
> you just store data in the component. 
344          </li>
345          <li>Learning to create XPCOM components takes time.
346          </li>
347        </ul>
348      </li>
349    </ul>
350    <p>
351      There are several articles and books about creating XPCOM c
>omponents online. 
352    </p>
353    <h4 id="Using_FUEL_Application_object" name="Using_FUEL_Appli
>cation_object"> 
354      Using FUEL Application object
355    </h4>
356    <p>
357      The FUEL JavaScript library {{ Fx_minversion_inline("3") }}
> has a simple method for sharing data between windows. The <code> 
>Application</code> object supports a <code>storage</code> propert 
>y which can be used to store data globally. This method is a simp 
>lified form of the XPCOM singleton method. 
358    </p>
359    <pre class="eval">
360Application.storage.set(keyname, data);
361 
362var data = Application.storage.get(keyname, default);
363 
364where: keyname is a string used to identify the data
365       data is the data
366       default is the data value to return if keyname does not ex
>ists 
367</pre>
368    <ul>
369      <li>Pros:
370        <ul>
371          <li>Its the "right way".
372          </li>
373          <li>You can store arbitrary JavaScript objects in the c
>omponent. 
374          </li>
375          <li>The scope is not shared between components, so you 
>don't have to worry about name collisions. 
376          </li>
377          <li>No need to build an XPCOM component.
378          </li>
379        </ul>
380      </li>
381      <li>Cons:
382        <ul>
383          <li>Only works in Firefox 3 or newer.
384          </li>
385          <li>You can't use the <code><a href="/es/DOM/window" ti
>tle="es/DOM/window">window</a></code> object, its members, like < 
>code>alert</code> and <code>open</code>, and many other objects a 
>vailable from inside a window. The functionality isn't lost, howe 
>ver -- you just have to use the XPCOM components directly instead 
> of using convenient shortcuts. Of course, this doesn't matter if 
> you just store data in the component. 
386          </li>
387        </ul>
388      </li>
389    </ul>
390    <h4 id="Storing_shared_data_in_preferences" name="Storing_sha
>red_data_in_preferences"> 
391      Storing shared data in preferences
392    </h4>
393    <p>
394      If you just need to store a string or a number, writing a w
>hole XPCOM component may be an unnecessary complication. You can  
>use the <a class="external" href="http://www.xulplanet.com/refere 
>nces/xpcomref/ifaces/nsIPrefService.html">preferences service</a> 
> in such cases. 
395    </p>
396    <ul>
397      <li>Pros:
398        <ul>
399          <li>Quite easy to use for storing simple data.
400          </li>
401        </ul>
402      </li>
403      <li>Cons:
404        <ul>
405          <li>Can't easily be used to store complex data.
406          </li>
407          <li>Abusing the preferences service and not cleaning up
> after yourself can cause <code>prefs.js</code> to grow large and 
> slow down application startup. 
408          </li>
409        </ul>
410      </li>
411    </ul>
412    <p>
413      See <a href="/es/Code_snippets/Preferences" title="es/Code_
>snippets/Preferences">Code snippets:Preferences</a> for detailed  
>description of the preferences system and example code. 
414    </p>
415    <p>
416      Example:
417    </p>
418    <pre class="eval">
419var prefs = Components.classes["@mozilla.org/preferences-service;
>1"] 
420                      .getService(Components.interfaces.nsIPrefSe
>rvice); 
421var branch = prefs.getBranch("extensions.myext.");
422var var1 = branch.getBoolPref("var1"); // get a pref
423</pre>
424    <h4 id="The_hidden_window_hack" name="The_hidden_window_hack"
>> 
425      The hidden window hack
426    </h4>
427    <p>
428      Some extension authors use the special <em>hidden window</e
>m> to store their data and code. The hidden window is similar to  
>a regular window, but unlike any other window, it's available the 
> whole time the application is running, and isn't visible to user 
>. The document loaded into this window is <code><a class=" extern 
>al" href="chrome://browser/content/hiddenWindow.xul" rel="freelin 
>k">chrome://browser/content/hiddenWindow.xul</a></code> on Macs w 
>here it is used to implement the menus and <code><a class=" exter 
>nal" href="resource://gre/res/hiddenWindow.html" rel="freelink">r 
>esource://gre/res/hiddenWindow.html</a></code> on other operating 
> systems. Eventually this window will be removed for operating sy 
>stems where it isn't needed ({{ Bug("71895") }}). 
429    </p>
430    <p>
431      A reference to the hidden window can be obtained from the n
>sIAppShellService interface. As any other DOM object it allows yo 
>u to set custom properties: 
432    </p>
433    <pre class="eval">
434var hiddenWindow = Components.classes["@mozilla.org/appshell/appS
>hellService;1"] 
435         .getService(Components.interfaces.nsIAppShellService)
436         .hiddenDOMWindow;
437hiddenWindow.myExtensionStatus = "ready";
438</pre>
439    <p>
440      However, objects put into the hidden window will still belo
>ng to the window that created them. If a method of such an object 
> accesses properties of the <code>window</code> object like <code 
>>XMLHttpRequest</code> you might be confronted with an error mess 
>age because the original window has been closed. To avoid this yo 
>u can load the objects with a script file into the hidden window: 
441    </p>
442    <pre class="eval">
443var hiddenWindow = Components.classes["@mozilla.org/appshell/appS
>hellService;1"] 
444         .getService(Components.interfaces.nsIAppShellService)
445         .hiddenDOMWindow;
446hiddenWindow.Components.classes["@mozilla.org/moz/jssubscript-loa
>der;1"] 
447         .getService(Components.interfaces.mozIJSSubScriptLoader)
448         .loadSubScript("<a class=" external" href="chrome://my-e
>xtension/content/globalObject.js" rel="freelink">chrome://my-exte 
>nsion/content/globalObject.js</a>"); 
449hiddenWindow.myExtensionObject.doSomething();
450</pre>
451    <p>
452      With <code>globalObject.js</code> containing something like
>: 
453    </p>
454    <pre class="eval">
455var myExtensionObject = {
456  doSomething: function() {
457    return new XMLHttpRequest();
458  }
459}
460</pre>
461    <ul>
462      <li>Pros:
463        <ul>
464          <li>If you are running code in the hidden window, the <
>code>window</code> object and its properties are available, unlik 
>e the component case. 
465          </li>
466          <li>You can store arbitrary JavaScript objects in the h
>idden window. 
467          </li>
468        </ul>
469      </li>
470      <li>Cons:
471        <ul>
472          <li>It's a hack.
473          </li>
474          <li>The same window is accessed by different extensions
>, you have to use long variable names to avoid conflicts. 
475          </li>
476          <li>The hidden window may be removed from Windows/Linux
> builds. 
477          </li>
478        </ul>
479      </li>
480    </ul>
481    <h3 id="See_also" name="See_also">
482      See also
483    </h3>
484    <ul>
485      <li>
486        <a href="/es/Code_snippets/Dialogs" title="es/Code_snippe
>ts/Dialogs">Code snippets:Dialogs</a> 
487      </li>
488    </ul>
489    <p>
490      {{ languages( { "en": "en/Working_with_windows_in_chrome_co
>de", "fr": "fr/Travailler_avec_des_fen\u00eatres_dans_le_chrome", 
> "ja": "ja/Working_with_windows_in_chrome_code" } ) }} 
491    </p>

Volver al historial