1 /* ***** BEGIN LICENSE BLOCK *****
  2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3  *
  4  * The contents of this file are subject to the Mozilla Public License Version
  5  * 1.1 (the "License"); you may not use this file except in compliance with
  6  * the License. You may obtain a copy of the License at
  7  * http://www.mozilla.org/MPL/
  8  *
  9  * Software distributed under the License is distributed on an "AS IS" basis,
 10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 11  * for the specific language governing rights and limitations under the
 12  * License.
 13  *
 14  * The Original Code is MozMill Test code.
 15  *
 16  * The Initial Developer of the Original Code is the Mozilla Foundation.
 17  * Portions created by the Initial Developer are Copyright (C) 2010
 18  * the Initial Developer. All Rights Reserved.
 19  *
 20  * Contributor(s):
 21  *   Geo Mealer <gmealer@mozilla.com>
 22  *   Henrik Skupin <hskupin@mozilla.com>
 23  *
 24  * Alternatively, the contents of this file may be used under the terms of
 25  * either the GNU General Public License Version 2 or later (the "GPL"), or
 26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 27  * in which case the provisions of the GPL or the LGPL are applicable instead
 28  * of those above. If you wish to allow use of your version of this file only
 29  * under the terms of either the GPL or the LGPL, and not to allow others to
 30  * use your version of this file under the terms of the MPL, indicate your
 31  * decision by deleting the provisions above and replace them with the notice
 32  * and other provisions required by the GPL or the LGPL. If you do not delete
 33  * the provisions above, a recipient may use your version of this file under
 34  * the terms of any one of the MPL, the GPL or the LGPL.
 35  *
 36  * ***** END LICENSE BLOCK ***** */
 37 
 38 /**
 39  * @name widgets
 40  * @namespace Defines proxy classes for creation of a hierarchical map
 41  */
 42 
 43 var Inheritance = require("../external/inheritance");
 44 var DomUtils = require("../dom_utils");
 45 var Services = require("../services");
 46 
 47 // How long we're willing to implicitly wait for an HTML/XUL element to be available
 48 // before giving up. Available, right now, means "exists." This should eventually be
 49 // made configurable by an external file or similar.
 50 const ELEM_WAIT_TIME = 5000;
 51 
 52 var Element = Inheritance.Class.create(
 53 /** @lends widgets.Element */
 54 {
 55   /**
 56    * Element is a proxy for an element of a DOM. It defines the core binding
 57    * behavior: locating the element via any of serveral lookup methods.
 58    * It also provides the owner/owned relationship that allows Elements to be
 59    * arranged in a tree-shaped Element map.
 60    *
 61    * @class A proxy for an element of a DOM
 62    * @constructs
 63    * @memberOf widgets
 64    *
 65    * @param {String} locatorType
 66    *   The type of locator being supplied. Choices are:
 67    *     <dl>
 68    *     <dd>node</dd>   <dt>A node, as in Mozmill's Elem()</dt>
 69    *     <dd>id</dd>     <dt>An ID string, as in Mozmill's ID()</dt>
 70    *     <dd>xpath</dd>  <dt>An XPath string, as in Mozmill's XPath()</dt>
 71    *     <dd>name</dd>   <dt>A name string, as in Mozmill's Name()</dt>
 72    *     <dd>lookup</dd> <dt>A lookup string, as in Mozmill's Lookup()</dt>
 73    *     <dd>tag</dd>    <dt>A JQuery-style element selector string</dt>
 74    *     </dl>
 75    * @param {node|String} locator 
 76    *   The actual locator. If locatorType is "node," a node object is expected. 
 77    *   For all other types, a String is expected.
 78    * @param {document|Element} owner
 79    *   The owner (parent) of this Element. The top of an Element map is owned by 
 80    *   a document. Other members of the map are owned by their parent Elements.
 81    */
 82   initialize: function Element_initialize(locatorType, locator, owner) {
 83     // Locators are used to find the element. See _locateElem().
 84     this._validateLocatorType(locatorType);
 85     if (!locator) {
 86       throw new Error("Missing locator");
 87     }
 88 
 89     this._locator = locator;
 90     this._locatorType = locatorType;
 91 
 92     // Owner can be either the document for the top level of the map,
 93     // or another Element that owns this one.
 94     if (owner) {
 95       if (owner instanceof Element) {
 96         // We must be an owned element. Get doc and controller from our owner.
 97         this._owner = owner;
 98         this._document = owner._document;
 99         this._controller = owner._controller;
100       }
101       else {
102         // We must be a top-level element. We sent in a document as owner.
103         this._owner = undefined;
104         this._document = owner;
105         this._controller = mozmill.controller.MozMillController(this._document.defaultView);
106       }
107     }
108     else {
109       // Not supplied at all, so we're top level and our doc is the current window.
110       this._owner = undefined;
111       this._controller = mozmill.getBrowserController();
112       this._document = this._controller.window.document;
113     }
114 
115     // We'll lazy-get these when requested
116     this._elem = undefined;
117   },
118 
119   _getCollector: function Element_getCollector() {
120     // Collectors take either a parent node or a parent document.
121     // If we have an owner, supply its node. Otherwise, supply the
122     // attached document (we're top level).
123     if (this._owner)
124       return new DomUtils.nodeCollector(this._owner.node);
125     else
126       return new DomUtils.nodeCollector(this._document);
127   },
128 
129   _validateLocatorType: function element_validateLocatorType(locatorType) {
130     switch (locatorType) {
131       case "node":
132       case "id":
133       case "xpath":
134       case "name":
135       case "lookup":
136       case "tag":
137         // locatorType is valid, do nothing
138         break;
139       default:
140         throw new Error("Invalid locator type: " + locatorType);
141     }
142   },
143 
144   _locateElem: function Element_locateElem() {
145     switch (this._locatorType) {
146       // First the standard Elem constructors.
147       case "node":
148         this._elem = new elementslib.Elem(this._locator);
149         break;
150       case "id":
151         this._elem = new elementslib.ID(this._document, this._locator);
152         break;
153       case "xpath":
154         this._elem = new elementslib.XPath(this._document, this._locator);
155         break;
156       case "name":
157         this._elem = new elementslib.Name(this._document, this._locator);
158         break;
159       case "lookup":
160         this._elem = new elementslib.Lookup(this._document, this._locator);
161         break;
162 
163       // Finally, the nodeCollector.
164       // XXX: I'm calling this tag instead of selector, because I have
165       // intentions of introducing a path chain of selectors like
166       // "#foo/#bar/#baz" that mean "node with selector '#baz' under node
167       // with selector '#bar' under node with selector #foo, all under the
168       // owner of this Element". That will give us huge, huge flexibility in
169       // specifying node queries. However, we still have to account for
170       // property and anonymous locators, so there's significant work to
171       // be done here. Ultimately, I'm not 100% sure what a final tag will
172       // look like.
173       case "tag":
174         var collector = this._getCollector();
175         collector.queryNodes(this._locator);
176         if (collector.nodes.length < 1)
177           throw new Error("Could not find node for tag: " + this._locator);
178         if (collector.nodes.length > 1)
179           throw new Error("Found more than one node for tag: " + this._locator);
180         this._elem = new elementslib.Elem(collector.nodes[0]);
181         break;
182       default:
183         throw new Error("Unknown locator type: " + this._locatorType);
184     }
185   },
186 
187   // XXX: note that properties don't properly inherit yet. Need work in
188   // inheritance.js. In the meantime, if need to override, have to split
189   // out the guts of the property into a private _function so that the
190   // parent() function will work correctly, then call private _function
191   // from the property.
192   
193   /**
194    * The DOM document that is at the top of the map containing this Element.
195    *
196    * @name document
197    * @type document
198    * @fieldOf widgets.Element#
199    */
200   get document() {
201     return this._document;
202   },
203 
204   /**
205    * The Mozmill controller object associated with this Element.
206    *
207    * @name controller
208    * @type controller
209    * @fieldOf widgets.Element#
210    */
211   get controller() {
212     return this._controller;
213   },
214 
215   /**
216    * The DOM window object associated with this Element.
217    *
218    * @name window
219    * @type window
220    * @fieldOf widgets.Element#
221    */
222   get window() {
223     return this._controller.window;
224   },
225 
226   /** 
227    * The Mozmill elementslib object associated with this Element.
228    *
229    * @name elem
230    * @type elementslib
231    * @fieldOf widgets.Element#
232    */
233   get elem() {
234     if (!this._elem)
235       this._locateElem();
236 
237     return this._elem;
238   },
239 
240   /**
241    * The DOM node object associated with this Element.
242    *
243    * @name node
244    * @type node
245    * @fieldOf widgets.Element#
246    */
247   get node() {
248     return this.elem.getNode();
249   }
250 });
251 
252 var XmlElement = Inheritance.Class.extend(Element,
253 /** @lends widgets.XmlElement */
254 {
255   /**
256    * XmlElement is an Element that corresponds to a single element in
257    * an XML document.
258    *
259    * @class An Element that corresponds to a single element in an XML document
260    * @constructs
261    * @memberOf widgets
262    * @extends widgets.Element
263    *
264    * @param {String} locatorType
265    *   The type of locator being supplied. Choices are:
266    *     <dl>
267    *     <dd>node</dd>   <dt>A node, as in Mozmill's Elem()</dt>
268    *     <dd>id</dd>     <dt>An ID string, as in Mozmill's ID()</dt>
269    *     <dd>xpath</dd>  <dt>An XPath string, as in Mozmill's XPath()</dt>
270    *     <dd>name</dd>   <dt>A name string, as in Mozmill's Name()</dt>
271    *     <dd>lookup</dd> <dt>A lookup string, as in Mozmill's Lookup()</dt>
272    *     <dd>tag</dd>    <dt>A JQuery-style element selector string</dt>
273    *     </dl>
274    * @param {node|String} locator 
275    *   The actual locator. If locatorType is "node," a node object is expected. 
276    *   For all other types, a String is expected.
277    * @param {document|Element} owner
278    *   The owner (parent) of this Element. The top of an Element map is owned by 
279    *   a document. Other members of the map are owned by their parent Elements.
280    */
281    initialize: function XmlElement_initialize(locatorType, locator, owner) {
282      this.parent(locatorType, locator, owner);
283    }
284 });
285 
286 var XmlTree = Inheritance.Class.extend(Element,
287 /** @lends widgets.XmlTree */
288 {
289   /**
290    * XmlTree is an Element that corresponds to a subtree of an XML document.
291    *
292    * @class An Element that corresponds to a subtree in an XML document.
293    * @constructs
294    * @memberOf widgets
295    * @extends widgets.Element
296    *
297    * @param {String} locatorType
298    *   The type of locator being supplied. Choices are:
299    *     <dl>
300    *     <dd>node</dd>   <dt>A node, as in Mozmill's Elem()</dt>
301    *     <dd>id</dd>     <dt>An ID string, as in Mozmill's ID()</dt>
302    *     <dd>xpath</dd>  <dt>An XPath string, as in Mozmill's XPath()</dt>
303    *     <dd>name</dd>   <dt>A name string, as in Mozmill's Name()</dt>
304    *     <dd>lookup</dd> <dt>A lookup string, as in Mozmill's Lookup()</dt>
305    *     <dd>tag</dd>    <dt>A JQuery-style element selector string</dt>
306    *     </dl>
307    * @param {node|String} locator 
308    *   The actual locator. If locatorType is "node," a node object is expected. 
309    *   For all other types, a String is expected.
310    * @param {document|Element} owner
311    *   The owner (parent) of this Element. The top of an Element map is owned by 
312    *   a document. Other members of the map are owned by their parent Elements.
313    */
314    initialize: function XmlTree_initialize(locatorType, locator, owner) {
315      this.parent(locatorType, locator, owner);
316    }
317 });
318 
319 var HtmlXulElement = Inheritance.Class.extend(Element,
320 /** @lends widgets.HtmlXulElement */
321 {
322   /**
323    * HtmlXulElement is an Element that corresponds to an element of a
324    * HTML or Chrome document. More specific behavior for each is defined in
325    * the child classes HtmlElement and XulElement.
326    *
327    * @class An Element that corresponds to an element of an HTML or Chrome document
328    * @constructs
329    * @memberOf widgets
330    * @extends widgets.Element
331    *
332    * @param {String} locatorType
333    *   The type of locator being supplied. Choices are:
334    *     <dl>
335    *     <dd>node</dd>   <dt>A node, as in Mozmill's Elem()</dt>
336    *     <dd>id</dd>     <dt>An ID string, as in Mozmill's ID()</dt>
337    *     <dd>xpath</dd>  <dt>An XPath string, as in Mozmill's XPath()</dt>
338    *     <dd>name</dd>   <dt>A name string, as in Mozmill's Name()</dt>
339    *     <dd>lookup</dd> <dt>A lookup string, as in Mozmill's Lookup()</dt>
340    *     <dd>tag</dd>    <dt>A JQuery-style element selector string</dt>
341    *     </dl>
342    * @param {node|String} locator 
343    *   The actual locator. If locatorType is "node," a node object is expected. 
344    *   For all other types, a String is expected.
345    * @param {document|Element} owner
346    *   The owner (parent) of this Element. The top of an Element map is owned by 
347    *   a document. Other members of the map are owned by their parent Elements.
348    */
349   initialize: function HtmlXulElement_initialize(locatorType, locator, owner) {
350     this.parent(locatorType, locator, owner);
351   },
352 
353   /**
354    * Clicks on the Element with the left mouse button.
355    *
356    * @name click
357    * @methodOf widgets.HtmlXulElement#
358    *
359    * @param {Number} [left=0] Relative horizontal coordinate inside Element.
360    * @param {Number} [top=0] Relative vertical coordinate inside Element.
361    * @returns {Boolean} true if succeeded, false otherwise.
362    */
363   click: function HtmlXulElement_click(left, top) {
364     return this.controller.click(this.elem, left, top);
365   },
366 
367   /**
368    * Double-clicks on the Element with the left mouse button.
369    *
370    * @name doubleClick
371    * @methodOf widgets.HtmlXulElement#
372    *
373    * @param {Number} [left=0] Relative horizontal coordinate inside Element.
374    * @param {Number} [top=0] Relative vertical coordinate inside Element.
375    * @returns {Boolean} true if succeeded, false otherwise.
376    */
377   doubleClick: function HtmlXulElement_doubleClick(left, top) {
378     return this.controller.click(this.elem, left, top);
379   },
380 
381   /**
382    * Performs a key press for the given keycode. 
383    * Try to avoid the usage of the ctrlKey and metaKey modifiers if the
384    * shortcut is a combination of Ctrl (Windows/Linux) and Cmd (Mac). In
385    * this case, use accelKey instead which will work across operating systems.
386    *
387    * @name keyPress
388    * @methodOf widgets.HtmlXulElement#
389    *
390    * @param {String} keycode Either a literal like 'b' or an enum like 'VK_ESCAPE'.
391    * @param {Object} [modifiers={}] Indicates modifier keys. true means pressed.
392    * @param {Boolean} [modifiers.ctrlKey=false] The Ctrl key.
393    * @param {Boolean} [modifiers.altKey=false] The Alt/Option key.
394    * @param {Boolean} [modifiers.shiftKey=false] The Shift key.
395    * @param {Boolean} [modifiers.metaKey=false] The Meta/Cmd key.
396    * @param {Boolean} [modifiers.accelKey=false] Ctrl key on Windows/Linux, 
397                                                  Cmd key on Mac.
398    * @return {Boolean} true if succeeded, false otherwise.
399    */
400   keyPress: function HtmlXulElement_keypress(keycode, modifiers) {
401     modifiers = modifiers || {};
402     return this.controller.keypress(this.elem, keycode, modifiers);
403   },
404 
405   /**
406    * Presses the selected mouse button down on the Element.
407    *
408    * @name mouseDown
409    * @methodOf widgets.HtmlXulElement#
410    *
411    * @param {Number} [button=0] The id of the button to press (0 - left, 1 - middle, 2 - right).
412    * @param {Number} [left=0] Relative horizontal coordinate inside Element.
413    * @param {Number} [top=0] Relative vertical coordinate inside Element.
414    * @returns {Boolean} true if succeeded, false otherwise.
415    */
416   mouseDown: function HtmlXulElement_mouseDown(button, left, top) {
417     return this.controller.mouseDown(this.elem, button, left, top);
418   },
419 
420   /**
421    * Releases the selected mouse button on the Element.
422    *
423    * @name mouseUp
424    * @methodOf widgets.HtmlXulElement#
425    *
426    * @param {Number} [button=0] The id of the button to press (0 - left, 1 - middle, 2 - right).
427    * @param {Number} [left=0] Relative horizontal coordinate inside Element.
428    * @param {Number} [top=0] Relative vertical coordinate inside Element.
429    * @returns {Boolean} true if succeeded, false otherwise.
430    */
431   mouseUp: function HtmlXulElement_mouseUp(button, left, top) {
432     return this.controller.mouseUp(this.elem, button, left, top);
433   },
434 
435   /**
436    * Clicks on the Element with the right mouse button.
437    *
438    * @name rightClick
439    * @methodOf widgets.HtmlXulElement#
440    *
441    * @param {Number} [left=0] Relative horizontal coordinate inside Element.
442    * @param {Number} [top=0] Relative vertical coordinate inside Element.
443    * @returns {Boolean} true if succeeded, false otherwise.
444    */
445   rightClick: function HtmlXulElement_rightClick(left, top) {
446     return this.controller.rightClick(this.elem, left, top);
447   }
448 });
449 
450 var HtmlElement = Inheritance.Class.extend(HtmlXulElement,
451 /** @lends widgets.HtmlElement */
452 {
453   /**
454    * HtmlElement is an Element that corresponds to an element of an HTML document.
455    *
456    * @class An Element that corresponds to an element of an HTML document.
457    * @constructs
458    * @memberOf widgets
459    * @extends widgets.HtmlXulElement
460    *
461    * @param {String} locatorType
462    *   The type of locator being supplied. Choices are:
463    *     <dl>
464    *     <dd>node</dd>   <dt>A node, as in Mozmill's Elem()</dt>
465    *     <dd>id</dd>     <dt>An ID string, as in Mozmill's ID()</dt>
466    *     <dd>xpath</dd>  <dt>An XPath string, as in Mozmill's XPath()</dt>
467    *     <dd>name</dd>   <dt>A name string, as in Mozmill's Name()</dt>
468    *     <dd>lookup</dd> <dt>A lookup string, as in Mozmill's Lookup()</dt>
469    *     <dd>tag</dd>    <dt>A JQuery-style element selector string</dt>
470    *     </dl>
471    * @param {node|String} locator 
472    *   The actual locator. If locatorType is "node," a node object is expected. 
473    *   For all other types, a String is expected.
474    * @param {document|Element} owner
475    *   The owner (parent) of this Element. The top of an Element map is owned by 
476    *   a document. Other members of the map are owned by their parent Elements.
477    */
478   initialize: function HtmlElement_initialize(locatorType, locator, owner) {
479     this.parent(locatorType, locator, owner);
480   },
481 });
482 
483 var HtmlRegion = Inheritance.Class.extend(HtmlElement,
484 /** @lends widgets.HtmlRegion */
485 {
486   /**
487    * HtmlRegion is an Element that corresponds to a grouping container in an HTML
488    * document.
489    *
490    * @class An Element that corresponds to a grouping container in an HTML document.
491    * @constructs
492    * @memberOf widgets
493    * @extends widgets.HtmlElement
494    *
495    * @param {String} locatorType
496    *   The type of locator being supplied. Choices are:
497    *     <dl>
498    *     <dd>node</dd>   <dt>A node, as in Mozmill's Elem()</dt>
499    *     <dd>id</dd>     <dt>An ID string, as in Mozmill's ID()</dt>
500    *     <dd>xpath</dd>  <dt>An XPath string, as in Mozmill's XPath()</dt>
501    *     <dd>name</dd>   <dt>A name string, as in Mozmill's Name()</dt>
502    *     <dd>lookup</dd> <dt>A lookup string, as in Mozmill's Lookup()</dt>
503    *     <dd>tag</dd>    <dt>A JQuery-style element selector string</dt>
504    *     </dl>
505    * @param {node|String} locator 
506    *   The actual locator. If locatorType is "node," a node object is expected. 
507    *   For all other types, a String is expected.
508    * @param {document|Element} owner
509    *   The owner (parent) of this Element. The top of an Element map is owned by 
510    *   a document. Other members of the map are owned by their parent Elements.
511    */
512   initialize: function HtmlRegion_initialize(locatorType, locator, owner) {
513     this.parent(locatorType, locator, owner);
514   },
515 });
516 
517 var XulElement = Inheritance.Class.extend(HtmlXulElement,
518 /** @lends widgets.XulElement */
519 {
520   /**
521    * XulElement is an Element that corresponds to an element of a Chrome
522    * document.
523    *
524    * @class An Element that corresponds to an element of a Chrome document.
525    * @constructs
526    * @memberOf widgets
527    * @extends widgets.HtmlXulElement
528    *
529    * @param {String} locatorType
530    *   The type of locator being supplied. Choices are:
531    *     <dl>
532    *     <dd>node</dd>   <dt>A node, as in Mozmill's Elem()</dt>
533    *     <dd>id</dd>     <dt>An ID string, as in Mozmill's ID()</dt>
534    *     <dd>xpath</dd>  <dt>An XPath string, as in Mozmill's XPath()</dt>
535    *     <dd>name</dd>   <dt>A name string, as in Mozmill's Name()</dt>
536    *     <dd>lookup</dd> <dt>A lookup string, as in Mozmill's Lookup()</dt>
537    *     <dd>tag</dd>    <dt>A JQuery-style element selector string</dt>
538    *     </dl>
539    * @param {node|String} locator 
540    *   The actual locator. If locatorType is "node," a node object is expected. 
541    *   For all other types, a String is expected.
542    * @param {document|Element} owner
543    *   The owner (parent) of this Element. The top of an Element map is owned by 
544    *   a document. Other members of the map are owned by their parent Elements.
545    */
546   initialize: function XulElement_initialize(locatorType, locator, owner) {
547     this.parent(locatorType, locator, owner);
548   },
549 });
550 
551 var XulRegion = Inheritance.Class.extend(XulElement,
552 /** @lends widgets.XulRegion */
553 {
554   /**
555    * XulRegion is an Element that corresponds to a grouping container in a Chrome
556    * document.
557    *
558    * @class An Element that corresponds to a grouping container in a Chrome document.
559    * @constructs
560    * @memberOf widgets
561    * @extends widgets.XulElement
562    *
563    * @param {String} locatorType
564    *   The type of locator being supplied. Choices are:
565    *     <dl>
566    *     <dd>node</dd>   <dt>A node, as in Mozmill's Elem()</dt>
567    *     <dd>id</dd>     <dt>An ID string, as in Mozmill's ID()</dt>
568    *     <dd>xpath</dd>  <dt>An XPath string, as in Mozmill's XPath()</dt>
569    *     <dd>name</dd>   <dt>A name string, as in Mozmill's Name()</dt>
570    *     <dd>lookup</dd> <dt>A lookup string, as in Mozmill's Lookup()</dt>
571    *     <dd>tag</dd>    <dt>A JQuery-style element selector string</dt>
572    *     </dl>
573    * @param {node|String} locator 
574    *   The actual locator. If locatorType is "node," a node object is expected. 
575    *   For all other types, a String is expected.
576    * @param {document|Element} owner
577    *   The owner (parent) of this Element. The top of an Element map is owned by 
578    *   a document. Other members of the map are owned by their parent Elements.
579    */
580   initialize: function XulRegion_initialize(locatorType, locator, owner) {
581     this.parent(locatorType, locator, owner);
582   },
583 });
584 
585 var Button = Inheritance.Class.extend(XulElement, {
586   // XXX: stub
587 });
588 
589 var TextBox = Inheritance.Class.extend(XulElement, {
590   getText: function TextBox_getText() {
591     return this.node.value;
592   },
593 
594   type: function TextBox_type(text) {
595     this.controller.type(this.elem, text);
596   }
597 });
598 
599 var Button_Menu = Inheritance.Class.extend(Button, {
600   // XXX: stub
601 });
602 
603 var Button_MenuButton = Inheritance.Class.extend(Button, {
604   // XXX: stub
605 });
606 
607 var TextBox_Multi = Inheritance.Class.extend(TextBox, {
608   // XXX: stub
609 });
610 
611 var TextBox_Number = Inheritance.Class.extend(TextBox, {
612   // XXX: stub
613 });
614 
615 var TextBox_Password = Inheritance.Class.extend(TextBox, {
616   // XXX: stub
617 });
618 
619 var TextBox_Auto = Inheritance.Class.extend(TextBox, {
620   // XXX: stub
621 });
622 
623 // Exported Classes
624 exports.Element = Element;
625 exports.XmlElement = XmlElement;
626 exports.HtmlXulElement = HtmlXulElement;
627 exports.HtmlElement = HtmlElement;
628 exports.HtmlRegion = HtmlRegion;
629 exports.XulElement = XulElement;
630 exports.XulRegion = XulRegion;
631 exports.Button = Button;
632 exports.TextBox = TextBox;
633 exports.Button_Menu = Button_Menu;
634 exports.Button_MenuButton = Button_MenuButton;
635 exports.TextBox_Multi = TextBox_Multi;
636 exports.TextBox_Number = TextBox_Number;
637 exports.TextBox_Password = TextBox_Password;
638 exports.TextBox_Auto = TextBox_Auto;