001 /*
002 * Copyright 2006 Google Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy of
006 * the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 */
016 package com.google.gwt.user.client;
017
018 import com.google.gwt.core.client.GWT;
019 import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
020 import com.google.gwt.user.client.impl.DOMImpl;
021
022 import java.util.Vector;
023
024 /**
025 * This class provides a set of static methods that allow you to manipulate the
026 * browser's Document Object Model (DOM). It contains methods for manipulating
027 * both {@link com.google.gwt.user.client.Element elements} and
028 * {@link com.google.gwt.user.client.Event events}.
029 */
030 public class DOM {
031
032 private static DOMImpl impl;
033 private static Element sCaptureElem;
034
035 private static Vector sEventPreviewStack = new Vector(); // <BrowserEventPreview>
036
037 static {
038 impl = (DOMImpl) GWT.create(DOMImpl.class);
039 impl.init();
040 }
041
042 /**
043 * Adds an event preview to the preview stack. As long as this preview remains
044 * on the top of the stack, it will receive all events before they are fired
045 * to their listeners. Note that the event preview will receive <u>all </u>
046 * events, including those received due to bubbling, whereas normal event
047 * handlers only receive explicitly sunk events.
048 *
049 * @param preview the event preview to be added to the stack.
050 */
051 public static void addEventPreview(EventPreview preview) {
052 // Add the event preview to the stack. It will automatically
053 // begin receiving events.
054 sEventPreviewStack.add(preview);
055 }
056
057 /**
058 * Appends one element to another's list of children.
059 *
060 * @param parent the parent element
061 * @param child its new child
062 */
063 public static void appendChild(Element parent, Element child) {
064 impl.appendChild(parent, child);
065 }
066
067 /**
068 * Compares two elements for equality (note that reference equality is not
069 * sufficient to determine equality among elements on most browsers).
070 *
071 * @param elem1 the first element to be compared
072 * @param elem2 the second element to be compared
073 * @return <code>true</code> if they are in fact the same element
074 */
075 public static boolean compare(Element elem1, Element elem2) {
076 return impl.compare(elem1, elem2);
077 }
078
079 /**
080 * Creates an HTML A element.
081 *
082 * @return the newly-created element
083 */
084 public static Element createAnchor() {
085 return impl.createElement("A");
086 }
087
088 /**
089 * Creates an HTML BUTTON element.
090 *
091 * @return the newly-created element
092 */
093 public static Element createButton() {
094 return impl.createElement("button");
095 }
096
097 /**
098 * Creates an HTML COL element.
099 *
100 * @return the newly-created element
101 */
102 public static Element createCol() {
103 return impl.createElement("col");
104 }
105
106 /**
107 * Creates an HTML DIV element.
108 *
109 * @return the newly-created element
110 */
111 public static Element createDiv() {
112 return impl.createElement("div");
113 }
114
115 /**
116 * Creates an HTML element.
117 *
118 * @param tagName the HTML tag of the element to be created
119 * @return the newly-created element
120 */
121 public static Element createElement(String tagName) {
122 return impl.createElement(tagName);
123 }
124
125 /**
126 * Creates an HTML FIELDSET element.
127 *
128 * @return the newly-created element
129 */
130 public static Element createFieldSet() {
131 return impl.createElement("fieldset");
132 }
133
134 /**
135 * Creates an HTML IFRAME element.
136 *
137 * @return the newly-created element
138 */
139 public static Element createIFrame() {
140 return impl.createElement("iframe");
141 }
142
143 /**
144 * Creates an HTML IMG element.
145 *
146 * @return the newly-created element
147 */
148 public static Element createImg() {
149 return impl.createElement("img");
150 }
151
152 /**
153 * Creates an HTML INPUT type='CHECK' element.
154 *
155 * @return the newly-created element
156 */
157 public static Element createInputCheck() {
158 return impl.createInputElement("checkbox");
159 }
160
161 /**
162 * Creates an HTML INPUT type='PASSWORD' element.
163 *
164 * @return the newly-created element
165 */
166 public static Element createInputPassword() {
167 return impl.createInputElement("password");
168 }
169
170 /**
171 * Creates an HTML INPUT type='RADIO' element.
172 *
173 * @param group the name of the group with which this radio button will be
174 * associated
175 * @return the newly-created element
176 */
177 public static Element createInputRadio(String group) {
178 return impl.createInputRadioElement(group);
179 }
180
181 /**
182 * Creates an HTML INPUT type='TEXT' element.
183 *
184 * @return the newly-created element
185 */
186 public static Element createInputText() {
187 return impl.createInputElement("text");
188 }
189
190 /**
191 * Creates an HTML LABEL element.
192 *
193 * @return the newly-created element
194 */
195 public static Element createLabel() {
196 return impl.createElement("label");
197 }
198
199 /**
200 * Creates an HTML LEGEND element.
201 *
202 * @return the newly-created element
203 */
204 public static Element createLegend() {
205 return impl.createElement("legend");
206 }
207
208 /**
209 * Creates an HTML OPTIONS element.
210 *
211 * @return the newly-created element
212 */
213 public static Element createOptions() {
214 return impl.createElement("options");
215 }
216
217 /**
218 * Creates an HTML SELECT element.
219 *
220 * @return the newly-created element
221 */
222 public static Element createSelect() {
223 return impl.createElement("select");
224 }
225
226 /**
227 * Creates an HTML SPAN element.
228 *
229 * @return the newly-created element
230 */
231 public static Element createSpan() {
232 return impl.createElement("span");
233 }
234
235 /**
236 * Creates an HTML TABLE element.
237 *
238 * @return the newly-created element
239 */
240 public static Element createTable() {
241 return impl.createElement("table");
242 }
243
244 /**
245 * Creates an HTML BODY element.
246 *
247 * @return the newly-created element
248 */
249 public static Element createTBody() {
250 return impl.createElement("tbody");
251 }
252
253 /**
254 * Creates an HTML TD element.
255 *
256 * @return the newly-created element
257 */
258 public static Element createTD() {
259 return impl.createElement("td");
260 }
261
262 /**
263 * Creates an HTML TEXTAREA element.
264 *
265 * @return the newly-created element
266 */
267 public static Element createTextArea() {
268 return impl.createElement("textarea");
269 }
270
271 /**
272 * Creates an HTML THEAD element.
273 *
274 * @return the newly-created element
275 */
276 public static Element createTH() {
277 return impl.createElement("th");
278 }
279
280 /**
281 * Creates an HTML TR element.
282 *
283 * @return the newly-created element
284 */
285 public static Element createTR() {
286 return impl.createElement("tr");
287 }
288
289 /**
290 * Cancels bubbling for the given event. This will stop the event from being
291 * propagated to parent elements.
292 *
293 * @param evt the event on which to cancel bubbling
294 * @param cancel <code>true</code> to cancel bubbling
295 */
296 public static void eventCancelBubble(Event evt, boolean cancel) {
297 impl.eventCancelBubble(evt, cancel);
298 }
299
300 /**
301 * Gets whether the ALT key was depressed when the given event occurred.
302 *
303 * @param evt the event to be tested
304 * @return <code>true</code> if ALT was depressed when the event occurred
305 */
306 public static boolean eventGetAltKey(Event evt) {
307 return impl.eventGetAltKey(evt);
308 }
309
310 /**
311 * Gets the mouse buttons that were depressed when the given event occurred.
312 *
313 * @param evt the event to be tested
314 * @return a bit-field, defined by {@link Event#BUTTON_LEFT},
315 * {@link Event#BUTTON_MIDDLE}, and {@link Event#BUTTON_RIGHT}
316 */
317 public static int eventGetButton(Event evt) {
318 return impl.eventGetButton(evt);
319 }
320
321 /**
322 * Gets the mouse x-position within the browser window's client area.
323 *
324 * @param evt the event to be tested
325 * @return the mouse x-position
326 */
327 public static int eventGetClientX(Event evt) {
328 return impl.eventGetClientX(evt);
329 }
330
331 /**
332 * Gets the mouse y-position within the browser window's client area.
333 *
334 * @param evt the event to be tested
335 * @return the mouse y-position
336 */
337 public static int eventGetClientY(Event evt) {
338 return impl.eventGetClientY(evt);
339 }
340
341 /**
342 * Gets whether the CTRL key was depressed when the given event occurred.
343 *
344 * @param evt the event to be tested
345 * @return <code>true</code> if CTRL was depressed when the event occurred
346 */
347 public static boolean eventGetCtrlKey(Event evt) {
348 return impl.eventGetCtrlKey(evt);
349 }
350
351 /**
352 * Gets the element from which the mouse pointer was moved (only valid for
353 * {@link Event#ONMOUSEOVER}).
354 *
355 * @param evt the event to be tested
356 * @return the element from which the mouse pointer was moved
357 */
358 public static Element eventGetFromElement(Event evt) {
359 return impl.eventGetFromElement(evt);
360 }
361
362 /**
363 * Gets the key code associated with this event.
364 *
365 * <p>
366 * For {@link Event#ONKEYPRESS}, this method returns the Unicode value of the
367 * character generated. For {@link Event#ONKEYDOWN} and {@link Event#ONKEYUP},
368 * it returns the code associated with the physical key.
369 * </p>
370 *
371 * @param evt the event to be tested
372 * @return the Unicode character or key code.
373 * @see com.google.gwt.user.client.ui.KeyboardListener
374 */
375 public static char eventGetKeyCode(Event evt) {
376 return impl.eventGetKeyCode(evt);
377 }
378
379 /**
380 * Gets the key-repeat state of this event.
381 *
382 * @param evt the event to be tested
383 * @return <code>true</code> if this key event was an auto-repeat
384 */
385 public static boolean eventGetRepeat(Event evt) {
386 return impl.eventGetRepeat(evt);
387 }
388
389 /**
390 * Gets the mouse x-position on the user's display.
391 *
392 * @param evt the event to be tested
393 * @return the mouse x-position
394 */
395 public static int eventGetScreenX(Event evt) {
396 return impl.eventGetScreenX(evt);
397 }
398
399 /**
400 * Gets the mouse y-position on the user's display.
401 *
402 * @param evt the event to be tested
403 * @return the mouse y-position
404 */
405 public static int eventGetScreenY(Event evt) {
406 return impl.eventGetScreenY(evt);
407 }
408
409 /**
410 * Gets whether the shift key was depressed when the given event occurred.
411 *
412 * @param evt the event to be tested
413 * @return <code>true</code> if shift was depressed when the event occurred
414 */
415 public static boolean eventGetShiftKey(Event evt) {
416 return impl.eventGetShiftKey(evt);
417 }
418
419 /**
420 * Returns the element that was the actual target of the given event.
421 *
422 * @param evt the event to be tested
423 * @return the target element
424 */
425 public static Element eventGetTarget(Event evt) {
426 return impl.eventGetTarget(evt);
427 }
428
429 /**
430 * Gets the element to which the mouse pointer was moved (only valid for
431 * {@link Event#ONMOUSEOUT}).
432 *
433 * @param evt the event to be tested
434 * @return the element to which the mouse pointer was moved
435 */
436 public static Element eventGetToElement(Event evt) {
437 return impl.eventGetToElement(evt);
438 }
439
440 /**
441 * Gets the enumerated type of this event (as defined in {@link Event}).
442 *
443 * @param evt the event to be tested
444 * @return the event's enumerated type
445 */
446 public static int eventGetType(Event evt) {
447 return impl.eventGetTypeInt(evt);
448 }
449
450 /**
451 * Gets the type of the given event as a string.
452 *
453 * @param evt the event to be tested
454 * @return the event's type name
455 */
456 public static String eventGetTypeString(Event evt) {
457 return impl.eventGetType(evt);
458 }
459
460 /**
461 * Prevents the browser from taking its default action for the given event.
462 *
463 * @param evt the event whose default action is to be prevented
464 */
465 public static void eventPreventDefault(Event evt) {
466 impl.eventPreventDefault(evt);
467 }
468
469 /**
470 * Sets the key code associated with the given keyboard event.
471 *
472 * @param evt the event whose key code is to be set
473 * @param key the new key code
474 */
475 public static void eventSetKeyCode(Event evt, char key) {
476 impl.eventSetKeyCode(evt, key);
477 }
478
479 /**
480 * Returns a stringized version of the event. This string is for debugging
481 * purposes and will NOT be consistent on different browsers.
482 *
483 * @param evt the event to stringize
484 * @return a string form of the event
485 */
486 public static String eventToString(Event evt) {
487 return impl.eventToString(evt);
488 }
489
490 /**
491 * Gets an element's absolute left coordinate in the document's coordinate
492 * system.
493 *
494 * @param elem the element to be measured
495 * @return the element's absolute left coordinate
496 */
497 public static int getAbsoluteLeft(Element elem) {
498 return impl.getAbsoluteLeft(elem);
499 }
500
501 /**
502 * Gets an element's absolute top coordinate in the document's coordinate
503 * system.
504 *
505 * @param elem the element to be measured
506 * @return the element's absolute top coordinate
507 */
508 public static int getAbsoluteTop(Element elem) {
509 return impl.getAbsoluteTop(elem);
510 }
511
512 /**
513 * Gets any named attribute from an element, as a string.
514 *
515 * @param elem the element whose attribute is to be retrieved
516 * @param attr the name of the attribute
517 * @return the attribute's value
518 */
519 public static String getAttribute(Element elem, String attr) {
520 return impl.getAttribute(elem, attr);
521 }
522
523 /**
524 * Gets the element that currently has mouse capture.
525 *
526 * @return a handle to the capture element, or <code>null</code> if none
527 * exists
528 */
529 public static Element getCaptureElement() {
530 return sCaptureElem;
531 }
532
533 /**
534 * Gets an element's n-th child element
535 *
536 * @param parent the element whose child is to be retrieved
537 * @param index the index of the child element
538 * @return the n-th child element
539 */
540 public static Element getChild(Element parent, int index) {
541 return impl.getChild(parent, index);
542 }
543
544 /**
545 * Gets the number of child elements present in a given parent element.
546 *
547 * @param parent the element whose children are to be counted
548 * @return the number of children
549 */
550 public static int getChildCount(Element parent) {
551 return impl.getChildCount(parent);
552 }
553
554 /**
555 * Gets the index of a given child element within its parent.
556 *
557 * @param parent the parent element
558 * @param child the child element
559 * @return the child's index within its parent, or <code>-1</code> if it is
560 * not a child of the given parent
561 */
562 public static int getChildIndex(Element parent, Element child) {
563 return impl.getChildIndex(parent, child);
564 }
565
566 /**
567 * Gets the element associated with the given unique id within the entire
568 * document.
569 *
570 * @param id the id whose associated element is to be retrieved
571 * @return the associated element, or <code>null</code> if none is found
572 */
573 public static Element getElementById(String id) {
574 return impl.getElementById(id);
575 }
576
577 /**
578 * Gets the current set of events sunk by a given element.
579 *
580 * @param elem the element whose events are to be retrieved
581 * @return a bitfield describing the events sunk on this element (its possible
582 * values are described in {@link Event})
583 */
584 public static int getEventsSunk(Element elem) {
585 return impl.getEventsSunk(elem);
586 }
587
588 /**
589 * Gets the first child element of the given element.
590 *
591 * @param elem the element whose child is to be retrieved
592 * @return the child element
593 */
594 public static Element getFirstChild(Element elem) {
595 return impl.getFirstChild(elem);
596 }
597
598 /**
599 * Gets an HTML representation of an element's children.
600 *
601 * @param elem the element whose HTML is to be retrieved
602 * @return the HTML representation of the element's children
603 */
604 public static String getInnerHTML(Element elem) {
605 return impl.getInnerHTML(elem);
606 }
607
608 /**
609 * Gets the text contained within an element. If the element has child
610 * elements, only the text between them will be retrieved.
611 *
612 * @param elem the element whose inner text is to be retrieved
613 * @return the text inside this element
614 */
615 public static String getInnerText(Element elem) {
616 return impl.getInnerText(elem);
617 }
618
619 /**
620 * Gets an integer attribute on a given element.
621 *
622 * @param elem the element whose attribute is to be retrieved
623 * @param attr the name of the attribute to be retrieved
624 * @return the attribute's value as an integer
625 */
626 public static int getIntAttribute(Element elem, String attr) {
627 return impl.getIntAttribute(elem, attr);
628 }
629
630 /**
631 * Gets an integer attribute on a given element's style.
632 *
633 * @param elem the element whose style attribute is to be retrieved
634 * @param attr the name of the attribute to be retrieved
635 * @return the style attribute's value as an integer
636 */
637 public static int getIntStyleAttribute(Element elem, String attr) {
638 return impl.getIntStyleAttribute(elem, attr);
639 }
640
641 /**
642 * Gets an element's next sibling element.
643 *
644 * @param elem the element whose sibling is to be retrieved
645 * @return the sibling element
646 */
647 public static Element getNextSibling(Element elem) {
648 return impl.getNextSibling(elem);
649 }
650
651 /**
652 * Gets an element's parent element.
653 *
654 * @param elem the element whose parent is to be retrieved
655 * @return the parent element
656 */
657 public static Element getParent(Element elem) {
658 return impl.getParent(elem);
659 }
660
661 /**
662 * Gets an attribute of the given element's style.
663 *
664 * @param elem the element whose style attribute is to be retrieved
665 * @param attr the name of the style attribute to be retrieved
666 * @return the style attribute's value
667 */
668 public static String getStyleAttribute(Element elem, String attr) {
669 return impl.getStyleAttribute(elem, attr);
670 }
671
672 /**
673 * Inserts an element as a child of the given parent element.
674 *
675 * @param parent the parent element
676 * @param child the child element
677 * @param index the index before which the child will be inserted (any value
678 * greater than the number of existing children will cause the child
679 * to be appended)
680 */
681 public static void insertChild(Element parent, Element child, int index) {
682 impl.insertChild(parent, child, index);
683 }
684
685 /**
686 * Determine whether one element is equal to, or the child of, another.
687 *
688 * @param parent the potential parent element
689 * @param child the potential child element
690 * @return <code>true</code> if the relationship holds
691 */
692 public static boolean isOrHasChild(Element parent, Element child) {
693 return impl.isOrHasChild(parent, child);
694 }
695
696 /**
697 * Releases mouse capture on the given element. Calling this method has no
698 * effect if the element does not currently have mouse capture.
699 *
700 * @param elem the element to release capture
701 * @see #setCapture(Element)
702 */
703 public static void releaseCapture(Element elem) {
704 if ((sCaptureElem != null) && compare(elem, sCaptureElem))
705 sCaptureElem = null;
706 impl.releaseCapture(elem);
707 }
708
709 /**
710 * Removes a child element from the given parent element.
711 *
712 * @param parent the parent element
713 * @param child the child element to be removed
714 */
715 public static void removeChild(Element parent, Element child) {
716 impl.removeChild(parent, child);
717 }
718
719 /**
720 * Removes an element from the preview stack. This element will no longer
721 * capture events, though any preview underneath it will begin to do so.
722 *
723 * @param preview the event preview to be removed from the stack
724 */
725 public static void removeEventPreview(EventPreview preview) {
726 // Remove the event preview from the stack. If it was on top,
727 // any preview underneath it will automatically begin to
728 // receive events.
729 sEventPreviewStack.remove(preview);
730 }
731
732 /**
733 * Sets an attribute on the given element.
734 *
735 * @param elem the element whose attribute is to be set
736 * @param attr the name of the attribute to be set
737 * @param value the new attribute value
738 */
739 public static void setAttribute(Element elem, String attr, String value) {
740 impl.setAttribute(elem, attr, value);
741 }
742
743 /**
744 * Sets mouse-capture on the given element. This element will directly receive
745 * all mouse events until {@link #releaseCapture(Element)} is called on it.
746 *
747 * @param elem the element on which to set mouse capture
748 */
749 public static void setCapture(Element elem) {
750 sCaptureElem = elem;
751 impl.setCapture(elem);
752 }
753
754 /**
755 * Sets the {@link EventListener} to receive events for the given element.
756 * Only one such listener may exist for a single element.
757 *
758 * @param elem the element whose listener is to be set
759 * @param listener the listener to receive {@link Event events}
760 */
761 public static void setEventListener(Element elem, EventListener listener) {
762 impl.setEventListener(elem, listener);
763 }
764
765 /**
766 * Sets the HTML contained within an element.
767 *
768 * @param elem the element whose inner HTML is to be set
769 * @param html the new html
770 */
771 public static void setInnerHTML(Element elem, String html) {
772 impl.setInnerHTML(elem, html);
773 }
774
775 /**
776 * Sets the text contained within an element. If the element already has
777 * children, they will be destroyed.
778 *
779 * @param elem the element whose inner text is to be set
780 * @param text the new text
781 */
782 public static void setInnerText(Element elem, String text) {
783 impl.setInnerText(elem, text);
784 }
785
786 /**
787 * Sets an integer attribute on the given element.
788 *
789 * @param elem the element whose attribute is to be set
790 * @param attr the name of the attribute to be set
791 * @param value the attribute's new integer value
792 */
793 public static void setIntAttribute(Element elem, String attr, int value) {
794 setAttribute(elem, attr, Integer.toString(value));
795 }
796
797 /**
798 * Sets an integer attribute on the given element's style.
799 *
800 * @param elem the element whose style attribute is to be set
801 * @param attr the name of the style attribute to be set
802 * @param value the style attribute's new integer value
803 */
804 public static void setIntStyleAttribute(Element elem, String attr, int value) {
805 setStyleAttribute(elem, attr, Integer.toString(value));
806 }
807
808 /**
809 * Sets an attribute on the given element's style.
810 *
811 * @param elem the element whose style attribute is to be set
812 * @param attr the name of the style attribute to be set
813 * @param value the style attribute's new value
814 */
815 public static void setStyleAttribute(Element elem, String attr, String value) {
816 impl.setStyleAttribute(elem, attr, value);
817 }
818
819 /**
820 * Sets the current set of events sunk by a given element. These events will
821 * be fired to the nearest {@link EventListener} specified on any of the
822 * element's parents.
823 *
824 * @param elem the element whose events are to be retrieved
825 * @param eventBits a bitfield describing the events sunk on this element (its
826 * possible values are described in {@link Event})
827 */
828 public static void sinkEvents(Element elem, int eventBits) {
829 impl.sinkEvents(elem, eventBits);
830 }
831
832 /**
833 * Returns a stringized version of the element. This string is for debugging
834 * purposes and will NOT be consistent on different browsers.
835 *
836 * @param elem the element to stringize
837 * @return a string form of the element
838 */
839 public static String toString(Element elem) {
840 return impl.toString(elem);
841 }
842
843 /**
844 * This method is called directly by native code when any event is fired.
845 *
846 * @param hEvent the handle to the event being fired.
847 * @param hElem the handle to the element that received the event.
848 * @param listener the listener associated with the element that received the
849 * event.
850 */
851 static void dispatchEvent(Event evt, Element elem, EventListener listener) {
852 UncaughtExceptionHandler handler = GWT.getUncaughtExceptionHandler();
853 if (handler != null)
854 dispatchEventAndCatch(evt, elem, listener, handler);
855 else
856 dispatchEventImpl(evt, elem, listener);
857 }
858
859 /**
860 * This method is called directly by native code when event preview is being
861 * used.
862 *
863 * @param event a handle to the event being previewed
864 * @return <code>false</code> to cancel the event
865 */
866 static boolean previewEvent(Event evt) {
867 // If event previews are present, redirect events to the topmost of them.
868 boolean ret = true;
869 if (sEventPreviewStack.size() > 0) {
870 EventPreview preview = (EventPreview) sEventPreviewStack
871 .get(sEventPreviewStack.size() - 1);
872 if (!(ret = preview.onEventPreview(evt))) {
873 // If the preview cancels the event, stop it from bubbling and
874 // performing its default action.
875 eventCancelBubble(evt, true);
876 eventPreventDefault(evt);
877 }
878 }
879
880 return ret;
881 }
882
883 private static void dispatchEventAndCatch(Event evt, Element elem,
884 EventListener listener, UncaughtExceptionHandler handler) {
885 try {
886 dispatchEventImpl(evt, elem, listener);
887 } catch (Throwable e) {
888 handler.onUncaughtException(e);
889 }
890 }
891
892 private static void dispatchEventImpl(Event evt, Element elem,
893 EventListener listener) {
894 // If this element has capture...
895 if (elem == sCaptureElem) {
896 // ... and it's losing capture, clear sCaptureElem.
897 if (eventGetType(evt) == Event.ONLOSECAPTURE)
898 sCaptureElem = null;
899 }
900
901 // Pass the event to the listener.
902 listener.onBrowserEvent(evt);
903 }
904 }