001 
002 /*
003  *  JScripter Standard 1.0 - To Script In Java
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package jsx.event;
021 
022 import js.*;
023 import js.user.*;
024 import jsx.client.Browser;
025 import jsx.client.Win;
026 import jsx.dom.Nodes;
027 
028 /**
029  * <p>A utility class with its static methods providing facilities to access DOM events 
030  * related information eliminating browser dependencies.</p>
031  * 
032  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
033  */
034 public final class Events extends Disposable
035 {
036     private Events() {}
037 
038     /**
039      * <p>Returns a copy of a browser event object.</p>
040      * @param e The original browser event object.
041      * @return A copy of the event object for IE or the event object itself for other browsers.
042      * @see jsx.dom.Nodes#copy
043      * @since 1.0
044      */
045     public static final JsEvent copyEvent(JsEvent e) {
046         return !Browser.isIE ? e :
047                 new JsEvent(
048                         Nodes.copy.var().call(JsWindow.event.with(Js.core()))
049                 );
050     }
051 
052     /**
053      * <p>Dispatches a browser event object.</p>
054      * @param elm The element to fire a browser event.
055      * @param evt The browser event being dispatched from the element.
056      * @see JsElement#fireEvent(JsEvent)
057      * @see JsElement#dispatchEvent(JsEvent)
058      * @since 1.0
059      */
060     public final static void fireEvent(JsElement elm, JsEvent evt) {
061         if (Browser.isIE) {
062             elm.fireEvent(evt);
063         } else {
064             elm.dispatchEvent(evt);
065         }
066     }
067 
068     /**
069      * <p>Gets the HTML element that originally fires the given browser event object.</p>
070      * @param e A browser event object.
071      * @return The HTML element related.
072      * @see JsEvent#srcElement
073      * @see JsEvent#target
074      * @since 1.0
075      */
076     public final static JsHTMLElement srcElement(JsEvent e) {
077         return Browser.isIE ?
078                 new JsHTMLElement(JsEvent.srcElement .with(e)) :
079                 new JsHTMLElement(JsMouseEvent.target.with(e));
080     }
081 
082     /**
083      * <p>Gets the related source element when the given browser event is fired.</p>
084      * @param e A browser event object.
085      * @return The HTML element related.
086      * @see JsEvent#fromElement
087      * @see JsMouseEvent#relatedTarget
088      * @since 1.0
089      */
090     public final static JsHTMLElement fromElement(JsEvent e) {
091         return Browser.isIE ?
092                 new JsHTMLElement(JsMouseEvent.fromElement  .with(e)) :
093                 new JsHTMLElement(JsMouseEvent.relatedTarget.with(e));
094     }
095 
096     /**
097      * <p>Gets the related target element when the given browser event is fired.</p>
098      * @param e A browser event object.
099      * @return The HTML element related.
100      * @see JsEvent#toElement
101      * @see JsMouseEvent#relatedTarget
102      * @since 1.0
103      */
104     public final static JsHTMLElement toElement(JsEvent e) {
105         return Browser.isIE ?
106                 new JsHTMLElement(JsMouseEvent.toElement    .with(e)) :
107                 new JsHTMLElement(JsMouseEvent.relatedTarget.with(e));
108     }
109 
110     /**
111      * <p>Gets {@link JsEvent#clientX} of the given browser event.</p>
112      * @param e A browser event object.
113      * @return The value of the property.
114      * @see #clientY(JsEvent)
115      * @see JsEvent#clientX
116      * @since 1.0
117      */
118     public final static Number clientX(JsEvent e) {
119         return JsEvent.clientX.with(e);
120     }
121     /**
122      * <p>Gets {@link JsEvent#clientY} of the given browser event.</p>
123      * @param e A browser event object.
124      * @return The value of the property.
125      * @see #clientX(JsEvent)
126      * @see JsEvent#clientY
127      * @since 1.0
128      */
129     public final static Number clientY(JsEvent e) {
130         return JsEvent.clientY.with(e);
131     }
132     /**
133      * <p>Gets {@link JsEvent#pageX} of the given browser event.</p>
134      * @param e A browser event object.
135      * @return The value of the property.
136      * @see #pageY(JsEvent)
137      * @see JsEvent#pageX
138      * @since 1.0
139      */
140     public final static Number pageX(JsEvent e) {
141         Number x = JsEvent.pageX.with(e);
142         return Js.undefined(x) ? clientX(e).doubleValue() + Win.scrollLeft().doubleValue() : x;
143     }
144     /**
145      * <p>Gets {@link JsEvent#pageY} of the given browser event.</p>
146      * @param e A browser event object.
147      * @return The value of the property.
148      * @see #pageX(JsEvent)
149      * @see JsEvent#pageY
150      * @since 1.0
151      */
152     public final static Number pageY(JsEvent e) {
153         Number y = JsEvent.pageY.with(e);
154         return Js.undefined(y) ? clientY(e).doubleValue() + Win.scrollTop().doubleValue() : y;
155     }
156     /**
157      * <p>Sets the mouse capture to the object belonging to the current document if relevant.</p>
158      * <p>Note that this method is browser-independent in that it simply calls {@link JsNode#setCapture()} 
159      * at the given node object on IE browsers or does nothing on others.</p>
160      * @param o A node object.
161      * @see JsNode#setCapture()
162      * @since 1.0
163      */
164     public final static void setCapture(JsNode o) {
165         if (Browser.isIE) {
166             o.setCapture();
167         }
168     }
169     /**
170      * <p>Removes mouse capture from the object in the current document if relevant.</p>
171      * <p>Note that this method is browser-independent in that it simply calls {@link JsNode#setCapture()} 
172      * at the given node object on IE browsers or does nothing on others.</p>
173      * @param o A node object.
174      * @see JsNode#releaseCapture()
175      * @since 1.0
176      */
177     public final static void releaseCapture(JsNode o) {
178         if (Browser.isIE) {
179             o.releaseCapture();
180         }
181     }
182 
183     /**
184      * <p>Determines whether a browser event comes from the left mouse button, eliminating 
185      * the browser dependencies.</p>
186      * @param e A browser event.
187      * @return <tt>true</tt> if the event was fired by the left mouse button; 
188      * <tt>false</tt>, otherwise.
189      * @see JsMouseEvent#button
190      * @since 1.0
191      */
192     public static final boolean fromLeftButton(JsEvent e) {
193         Number n = JsMouseEvent.button.with(e);
194         return n != null && ((Browser.isIE || Browser.isWebKit) &&
195                 Js.eq(n, 1) || Js.eq(n, 0));
196     }
197 
198     /**
199      * <p>Stops a browser event from propagating any further through the capturing, target, or 
200      * bubbling phases of event propagation.</p>
201      * <p>This method simply set {@link JsEvent#cancelBubble} of the event object to <tt>true</tt> on 
202      * IE or calls {@link JsEvent#stopPropagation()} at the event object on other web browsers.</p>
203      * @param e A browser event.
204      * @see #preventDefault(JsEvent)
205      * @see #stop(JsEvent)
206      * @see JsEvent#stopPropagation()
207      * @see JsEvent#cancelBubble
208      * @since 1.0
209      */
210     public static final void stopPropagation(JsEvent e) {
211         if (Browser.isIE) {
212             e.var(JsEvent.cancelBubble, true);
213         } else {
214             e.stopPropagation();
215         }
216     }
217 
218     /**
219      * <p>Tells the web browser not to perform the default action associated with the given 
220      * event, if there is one.</p>
221      * <p>This method simply set {@link JsEvent#returnValue} of the event object to <tt>false</tt> on 
222      * IE or calls {@link JsEvent#preventDefault()} at the event object on other web browsers.</p>
223      * @param e A browser event.
224      * @see #stopPropagation(JsEvent)
225      * @see #stop(JsEvent)
226      * @see JsEvent#preventDefault()
227      * @see JsEvent#returnValue
228      * @since 1.0
229      */
230     public static final void preventDefault(JsEvent e) {
231         if (Browser.isIE) {
232             e.var(JsEvent.returnValue, false);
233         } else {
234             e.preventDefault();
235         }
236     }
237 
238     /**
239      * <p>Stops a browser event from propagating any further through the capturing, target, or 
240      * bubbling phases of event propagation and tells the web browser not to perform the default 
241      * action associated with the given event, if there is one.</p>
242      * <p>This method simply calls the {@link #stopPropagation(JsEvent)} and 
243      * {@link #preventDefault(JsEvent)} methods with the same browser event object.</p>
244      * @param e A browser event.
245      * @see #preventDefault(JsEvent)
246      * @see #stopPropagation(JsEvent)
247      * @see JsEvent#stopPropagation()
248      * @see JsEvent#cancelBubble
249      * @since 1.0
250      */
251     public static final void stop(JsEvent e) {
252         stopPropagation(e);
253         preventDefault(e);
254     }
255 }