PageRenderTime 26ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/gwtquery-core/src/main/java/com/google/gwt/query/client/plugins/Events.java

http://gwtquery.googlecode.com/
Java | 362 lines | 200 code | 33 blank | 129 comment | 72 complexity | 5d15d3f55452155ab8fab4c156b1c22c MD5 | raw file
  1. /*
  2. * Copyright 2011, The gwtquery team.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  5. * in compliance with the License. You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software distributed under the License
  10. * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  11. * or implied. See the License for the specific language governing permissions and limitations under
  12. * the License.
  13. */
  14. package com.google.gwt.query.client.plugins;
  15. import com.google.gwt.dom.client.Element;
  16. import com.google.gwt.dom.client.NativeEvent;
  17. import com.google.gwt.dom.client.Node;
  18. import com.google.gwt.query.client.Function;
  19. import com.google.gwt.query.client.GQuery;
  20. import com.google.gwt.query.client.js.JsUtils;
  21. import com.google.gwt.query.client.plugins.events.EventsListener;
  22. import com.google.gwt.query.client.plugins.events.EventsListener.SpecialEvent;
  23. import com.google.gwt.query.client.plugins.events.GqEvent;
  24. import com.google.gwt.user.client.Event;
  25. /**
  26. * GQuery Plugin for handling and queuing browser events.
  27. */
  28. public class Events extends GQuery {
  29. public static final Class<Events> Events = registerPlugin(Events.class, new Plugin<Events>() {
  30. public Events init(GQuery gq) {
  31. return new Events(gq);
  32. }
  33. });
  34. /**
  35. * Don't apply events on text and comment nodes !!
  36. */
  37. private static boolean isEventCapable(Node n) {
  38. return JsUtils.isWindow(n) || n.getNodeType() != 3 && n.getNodeType() != 8;
  39. }
  40. public Events(GQuery gq) {
  41. super(gq);
  42. }
  43. /**
  44. * Binds a set of handlers to a particular Event for each matched element.
  45. *
  46. * The event handlers are passed as Functions that you can use to prevent default behavior. To
  47. * stop both default action and event bubbling, the function event handler has to return false.
  48. *
  49. * You can pass an additional Object data to your Function as the second parameter
  50. *
  51. */
  52. public Events bind(int eventbits, Object data, Function... funcs) {
  53. for (Element e : elements()) {
  54. if (isEventCapable(e)) {
  55. EventsListener.getInstance(e).bind(eventbits, data, funcs);
  56. }
  57. }
  58. return this;
  59. }
  60. /**
  61. * Binds a set of handlers to a particular Event for each matched element.
  62. *
  63. * The namespace is a way to group events of the same type, making easier unbind specific
  64. * handlers.
  65. *
  66. * The event handlers are passed as Functions that you can use to prevent default behavior. To
  67. * stop both default action and event bubbling, the function event handler has to return false.
  68. *
  69. * You can pass an additional Object data to your Function
  70. *
  71. */
  72. public Events bind(int eventbits, String namespace, Object data, Function... funcs) {
  73. for (Element e : elements()) {
  74. if (isEventCapable(e)) {
  75. EventsListener.getInstance(e).bind(eventbits, namespace, data, funcs);
  76. }
  77. }
  78. return this;
  79. }
  80. /**
  81. * Binds a set of handlers to a particular Event for each matched element.
  82. *
  83. * The name could contain a namespace which is a way to group events of the same type, making
  84. * easier unbind specific handlers.
  85. *
  86. * The event handlers are passed as Functions that you can use to prevent default behavior. To
  87. * stop both default action and event bubbling, the function event handler has to return false.
  88. *
  89. * You can pass an additional Object data to your Function
  90. *
  91. */
  92. public Events bind(String event, Object data, Function... funcs) {
  93. for (Element e : elements()) {
  94. if (isEventCapable(e)) {
  95. EventsListener.getInstance(e).bind(event, data, funcs);
  96. }
  97. }
  98. return this;
  99. }
  100. public GQuery die(int eventbits) {
  101. EventsListener.getInstance(Element.is(currentContext) ? (Element) currentContext : body).die(
  102. eventbits, currentSelector);
  103. return this;
  104. }
  105. /**
  106. * Remove an event handlers previously attached using live() The selector used with it must match
  107. * exactly the selector initially used with live(). if <code>eventName</code> is null, all event
  108. * handlers corresponding of the GQuery selector will be removed
  109. */
  110. public GQuery die(String eventName) {
  111. EventsListener.getInstance(Element.is(currentContext) ? (Element) currentContext : body).die(
  112. eventName, currentSelector);
  113. return this;
  114. }
  115. public GQuery live(int eventbits, final Object data, Function... funcs) {
  116. EventsListener.getInstance(Element.is(currentContext) ? (Element) currentContext : body).live(
  117. eventbits, currentSelector, data, funcs);
  118. return this;
  119. }
  120. public GQuery live(String eventName, final Object data, Function... funcs) {
  121. EventsListener.getInstance(Element.is(currentContext) ? (Element) currentContext : body).live(
  122. eventName, currentSelector, data, funcs);
  123. return this;
  124. }
  125. /**
  126. * Bind an event handler to be fired when the mouse enter an element, or trigger that handler on
  127. * an element if no functions are provided.
  128. *
  129. * The mouseenter event differs from mouseover in the way it handles event bubbling. When
  130. * mouseover is used on an element having inner element(s), then when the mouse pointer moves
  131. * hover of the Inner element, the handler would be triggered. This is usually undesirable
  132. * behavior. The mouseenter event, on the other hand, only triggers its handler when the mouse
  133. * enters the element it is bound to, not a descendant.
  134. */
  135. public GQuery mouseenter(Function... f) {
  136. if (f == null || f.length == 0) {
  137. // handle trigger of mouseleave
  138. return triggerHtmlEvent("mouseenter");
  139. }
  140. return bind("mouseenter", null, f);
  141. }
  142. // TODO handle unbind !!
  143. /**
  144. * Bind an event handler to be fired when the mouse leaves an element, or trigger that handler on
  145. * an element if no functions are provided.
  146. *
  147. * The mouseleave event differs from mouseout in the way it handles event bubbling. When mouseout
  148. * is used on an element having inner element(s), then when the mouse pointer moves out of the
  149. * Inner element, the handler would be triggered. This is usually undesirable behavior. The
  150. * mouseleave event, on the other hand, only triggers its handler when the mouse leaves the
  151. * element it is bound to, not a descendant.
  152. */
  153. public GQuery mouseleave(Function... fs) {
  154. if (fs == null || fs.length == 0) {
  155. // handle trigger of mouseleave
  156. return triggerHtmlEvent("mouseleave");
  157. }
  158. return bind("mouseleave", null, fs);
  159. }
  160. /**
  161. * Binds a handler to a particular Event (like Event.ONCLICK) for each matched element. The
  162. * handler is executed only once for each element.
  163. *
  164. * The event handler is passed as a Function that you can use to prevent default behavior. To stop
  165. * both default action and event bubbling, the function event handler has to return false.
  166. *
  167. * You can pass an additional Object data to your Function as the second parameter
  168. */
  169. public Events one(int eventbits, final Object data, final Function f) {
  170. for (Element e : elements()) {
  171. if (isEventCapable(e)) {
  172. EventsListener.getInstance(e).bind(eventbits, data, f, 1);
  173. }
  174. }
  175. return this;
  176. }
  177. /**
  178. * Execute all handlers and behaviors attached to the matched elements for the given event types.
  179. *
  180. * Different event types can be passed joining these using the or bit wise operator.
  181. *
  182. * For keyboard events you can pass a second parameter which represents the key-code of the pushed
  183. * key.
  184. *
  185. * Example: fire(Event.ONCLICK | Event.ONFOCUS) Example: fire(Event.ONKEYDOWN. 'a');
  186. */
  187. public Events trigger(int eventbits, int... keys) {
  188. if ((eventbits | Event.ONBLUR) == Event.ONBLUR)
  189. dispatchEvent(document.createBlurEvent());
  190. if ((eventbits | Event.ONCHANGE) == Event.ONCHANGE)
  191. dispatchEvent(document.createChangeEvent());
  192. if ((eventbits | Event.ONCLICK) == Event.ONCLICK)
  193. dispatchEvent(document.createClickEvent(0, 0, 0, 0, 0, false, false, false, false));
  194. if ((eventbits | Event.ONDBLCLICK) == Event.ONDBLCLICK)
  195. dispatchEvent(document.createDblClickEvent(0, 0, 0, 0, 0, false, false, false, false));
  196. if ((eventbits | Event.ONFOCUS) == Event.ONFOCUS)
  197. dispatchEvent(document.createFocusEvent());
  198. if ((eventbits | Event.ONKEYDOWN) == Event.ONKEYDOWN)
  199. dispatchEvent(document.createKeyDownEvent(false, false, false, false, keys[0]));
  200. if ((eventbits | Event.ONKEYPRESS) == Event.ONKEYPRESS)
  201. dispatchEvent(document.createKeyPressEvent(false, false, false, false, keys[0], 0));
  202. if ((eventbits | Event.ONKEYUP) == Event.ONKEYUP)
  203. dispatchEvent(document.createKeyUpEvent(false, false, false, false, keys[0]));
  204. if ((eventbits | Event.ONLOSECAPTURE) == Event.ONLOSECAPTURE)
  205. triggerHtmlEvent("losecapture");
  206. if ((eventbits | Event.ONMOUSEDOWN) == Event.ONMOUSEDOWN)
  207. dispatchEvent(document.createMouseDownEvent(0, 0, 0, 0, 0, false, false, false, false,
  208. NativeEvent.BUTTON_LEFT));
  209. if ((eventbits | Event.ONMOUSEMOVE) == Event.ONMOUSEMOVE)
  210. dispatchEvent(document.createMouseMoveEvent(0, 0, 0, 0, 0, false, false, false, false,
  211. NativeEvent.BUTTON_LEFT));
  212. if ((eventbits | Event.ONMOUSEOUT) == Event.ONMOUSEOUT)
  213. dispatchEvent(document.createMouseOutEvent(0, 0, 0, 0, 0, false, false, false, false,
  214. NativeEvent.BUTTON_LEFT, null));
  215. if ((eventbits | Event.ONMOUSEOVER) == Event.ONMOUSEOVER)
  216. dispatchEvent(document.createMouseOverEvent(0, 0, 0, 0, 0, false, false, false, false,
  217. NativeEvent.BUTTON_LEFT, null));
  218. if ((eventbits | Event.ONMOUSEUP) == Event.ONMOUSEUP)
  219. dispatchEvent(document.createMouseUpEvent(0, 0, 0, 0, 0, false, false, false, false,
  220. NativeEvent.BUTTON_LEFT));
  221. if ((eventbits | Event.ONSCROLL) == Event.ONSCROLL)
  222. dispatchEvent(document.createScrollEvent());
  223. if ((eventbits | Event.ONERROR) == Event.ONERROR)
  224. dispatchEvent(document.createErrorEvent());
  225. if ((eventbits | Event.ONMOUSEWHEEL) == Event.ONMOUSEWHEEL)
  226. dispatchEvent(document.createMouseEvent("mousewheel", true, true, 0, 0, 0, 0, 0, false,
  227. false, false, false, NativeEvent.BUTTON_LEFT, null));
  228. if (eventbits == EventsListener.ONSUBMIT) {
  229. Event evt = document.createHtmlEvent("submit", true, true).cast();
  230. dispatchEvent(evt, new Function() {
  231. public native void f(Element e) /*-{
  232. e.submit();
  233. }-*/;
  234. });
  235. }
  236. if (eventbits == EventsListener.ONRESIZE)
  237. triggerHtmlEvent("resize");
  238. return this;
  239. }
  240. /**
  241. * Trigger a html event in all matched elements.
  242. *
  243. * @param htmlEvent An string representing the html event desired
  244. * @functions a set of function to run if the event is not canceled.
  245. */
  246. public Events triggerHtmlEvent(String htmlEvent, Function... functions) {
  247. SpecialEvent specialEvent = EventsListener.special.get(htmlEvent);
  248. boolean isSpecialEvent = specialEvent != null;
  249. String originalEventName = htmlEvent;
  250. String delegateEventName = isSpecialEvent ? specialEvent.getDelegateType() : htmlEvent;
  251. NativeEvent e = document.createHtmlEvent(delegateEventName, true, true);
  252. if (isSpecialEvent) {
  253. GqEvent.setOriginalEventType(e, originalEventName);
  254. }
  255. dispatchEvent(e, functions);
  256. return this;
  257. }
  258. /**
  259. * Removes all handlers, that matches the events bits passed, from each element.
  260. *
  261. * Example: unbind(Event.ONCLICK | Event.ONMOUSEOVER)
  262. */
  263. public Events unbind(int eventbits) {
  264. for (Element e : elements()) {
  265. if (isEventCapable(e)) {
  266. EventsListener.getInstance(e).unbind(eventbits);
  267. }
  268. }
  269. return this;
  270. }
  271. /**
  272. * Removes all handlers, that matches the events bits and the namespace passed, from each element.
  273. *
  274. * Example: unbind(Event.ONCLICK | Event.ONMOUSEOVER, "my.namespace")
  275. */
  276. public Events unbind(int eventbits, String name, Function f) {
  277. for (Element e : elements()) {
  278. if (isEventCapable(e)) {
  279. EventsListener.getInstance(e).unbind(eventbits, name, null, f);
  280. }
  281. }
  282. return this;
  283. }
  284. /**
  285. * Removes all handlers, that matches the event name passed.
  286. *
  287. * This name could contain a namespace.
  288. *
  289. * Example: unbind("click.my.namespace")
  290. */
  291. public Events unbind(String name) {
  292. return unbind(name, null);
  293. }
  294. /**
  295. * Removes the function passed as parameter from the event list matching the event name passed.
  296. * This name could contain a namespace.
  297. *
  298. * Example: unbind("click.my.namespace", myFunction)
  299. */
  300. public Events unbind(String name, Function f) {
  301. for (Element e : elements()) {
  302. if (isEventCapable(e)) {
  303. EventsListener.getInstance(e).unbind(name, f);
  304. }
  305. }
  306. return this;
  307. }
  308. public Events undelegate() {
  309. for (Element e : elements()) {
  310. if (isEventCapable(e)) {
  311. EventsListener.getInstance(e).cleanEventDelegation();
  312. }
  313. }
  314. return this;
  315. }
  316. private void dispatchEvent(NativeEvent evt, Function... funcs) {
  317. for (Element e : elements()) {
  318. if (isEventCapable(e)) {
  319. e.dispatchEvent(evt);
  320. if (!JsUtils.isDefaultPrevented(evt)) {
  321. for (Function f : funcs) {
  322. f.setEvent(Event.as(evt));
  323. f.f(e);
  324. }
  325. }
  326. }
  327. }
  328. }
  329. }