PageRenderTime 34ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/qooxdoo/framework/source/class/qx/ui/mobile/core/EventHandler.js

https://github.com/Wkasel/qooxdoo
JavaScript | 372 lines | 195 code | 74 blank | 103 comment | 36 complexity | 8069b7f9fda29aecda3c67049d09830e MD5 | raw file
  1. /* ************************************************************************
  2. qooxdoo - the new era of web development
  3. http://qooxdoo.org
  4. Copyright:
  5. 2004-2011 1&1 Internet AG, Germany, http://www.1und1.de
  6. License:
  7. LGPL: http://www.gnu.org/licenses/lgpl.html
  8. EPL: http://www.eclipse.org/org/documents/epl-v10.php
  9. See the LICENSE file in the project's top-level directory for details.
  10. Authors:
  11. * Tino Butz (tbtz)
  12. ************************************************************************ */
  13. /**
  14. * EXPERIMENTAL - NOT READY FOR PRODUCTION
  15. *
  16. * Connects the widgets to the browser DOM events.
  17. */
  18. qx.Class.define("qx.ui.mobile.core.EventHandler",
  19. {
  20. extend : qx.core.Object,
  21. implement : qx.event.IEventHandler,
  22. /*
  23. *****************************************************************************
  24. CONSTRUCTOR
  25. *****************************************************************************
  26. */
  27. construct : function()
  28. {
  29. this.base(arguments);
  30. this.__manager = qx.event.Registration.getManager(window);
  31. },
  32. /*
  33. *****************************************************************************
  34. STATICS
  35. *****************************************************************************
  36. */
  37. statics :
  38. {
  39. /** {Integer} Priority of this handler */
  40. PRIORITY : qx.event.Registration.PRIORITY_FIRST,
  41. /** {Map} Supported event types. Identical to events map of qx.ui.core.Widget */
  42. SUPPORTED_TYPES :
  43. {
  44. // mouse events
  45. mousemove : 1,
  46. mouseover : 1,
  47. mouseout : 1,
  48. mousedown : 1,
  49. mouseup : 1,
  50. click : 1,
  51. dblclick : 1,
  52. contextmenu : 1,
  53. mousewheel : 1,
  54. // key events
  55. keyup : 1,
  56. keydown : 1,
  57. keypress : 1,
  58. keyinput : 1,
  59. // mouse capture
  60. capture : 1,
  61. losecapture : 1,
  62. // focus events
  63. focusin : 1,
  64. focusout : 1,
  65. focus : 1,
  66. blur : 1,
  67. activate : 1,
  68. deactivate : 1,
  69. // appear events
  70. appear : 1,
  71. disappear : 1,
  72. // resize event
  73. resize : 1,
  74. // drag drop events
  75. dragstart : 1,
  76. dragend : 1,
  77. dragover : 1,
  78. dragleave : 1,
  79. drop : 1,
  80. drag : 1,
  81. dragchange : 1,
  82. droprequest : 1,
  83. // touch events
  84. touchstart : 1,
  85. touchend : 1,
  86. touchmove : 1,
  87. touchcancel : 1,
  88. tap : 1,
  89. swipe : 1
  90. },
  91. /** {Integer} Whether the method "canHandleEvent" must be called */
  92. IGNORE_CAN_HANDLE : false,
  93. __activeTarget : null,
  94. __scrollLeft : null,
  95. __scrollTop : null,
  96. __startY : null,
  97. __timer : null,
  98. /**
  99. * Event handler. Called when the touch start event occurs.
  100. * Sets the <code>active</class> class to the event target after a certain
  101. * time.
  102. *
  103. * @param domEvent {qx.event.type.Touch} The touch start event
  104. */
  105. __onTouchStart : function(domEvent)
  106. {
  107. var EventHandler = qx.ui.mobile.core.EventHandler;
  108. EventHandler.__scrollLeft = qx.bom.Viewport.getScrollLeft();
  109. EventHandler.__scrollTop = qx.bom.Viewport.getScrollTop();
  110. var touch = domEvent.getChangedTargetTouches()[0];
  111. EventHandler.__startY = touch.screenY;
  112. EventHandler.__cancelActiveStateTimer();
  113. var target = domEvent.getTarget();
  114. while (target && target.parentNode && target.parentNode.nodeType == 1 && qx.bom.element.Attribute.get(target, "data-activatable") != "true") {
  115. target = target.parentNode;
  116. }
  117. EventHandler.__activeTarget = target;
  118. EventHandler.___timer = window.setTimeout(function()
  119. {
  120. EventHandler.___timer = null;
  121. var target = EventHandler.__activeTarget;
  122. if (target && (qx.bom.element.Attribute.get(target, "data-selectable") != "false")) {
  123. qx.bom.element.Class.add(target, "active");
  124. }
  125. },100);
  126. },
  127. /**
  128. * Event handler. Called when the touch end event occurs.
  129. * Removes the <code>active</class> class from the event target.
  130. *
  131. * @param domEvent {qx.event.type.Touch} The touch end event
  132. */
  133. __onTouchEnd : function(domEvent)
  134. {
  135. qx.ui.mobile.core.EventHandler.__removeActiveState();
  136. },
  137. /**
  138. * Event handler. Called when the touch move event occurs.
  139. * Removes the <code>active</class> class from the event target
  140. * when the viewport was scrolled.
  141. *
  142. * @param domEvent {qx.event.type.Touch} The touch move event
  143. */
  144. __onTouchMove : function(domEvent)
  145. {
  146. var EventHandler = qx.ui.mobile.core.EventHandler;
  147. var touch = domEvent.getChangedTargetTouches()[0];
  148. var deltaY = touch.screenY - EventHandler.__startY;
  149. if (EventHandler.__activeTarget && Math.abs(deltaY) >= qx.event.handler.Touch.TAP_MAX_DISTANCE) {
  150. EventHandler.__removeActiveState();
  151. }
  152. if (EventHandler.__activeTarget
  153. && (EventHandler.__scrollLeft != qx.bom.Viewport.getScrollLeft()
  154. || EventHandler.__scrollTop != qx.bom.Viewport.getScrollTop())) {
  155. EventHandler.__removeActiveState();
  156. }
  157. },
  158. /**
  159. * Cancels the active state timer.
  160. */
  161. __cancelActiveStateTimer : function()
  162. {
  163. var EventHandler = qx.ui.mobile.core.EventHandler;
  164. if (EventHandler.___timer) {
  165. window.clearTimeout(EventHandler.___timer);
  166. EventHandler.___timer = null;
  167. }
  168. },
  169. /**
  170. * Removes the <code>active</class> class from the active target.
  171. */
  172. __removeActiveState : function()
  173. {
  174. var EventHandler = qx.ui.mobile.core.EventHandler;
  175. EventHandler.__cancelActiveStateTimer();
  176. var activeTarget = EventHandler.__activeTarget;
  177. if (activeTarget) {
  178. qx.bom.element.Class.remove(activeTarget, "active");
  179. }
  180. EventHandler.__activeTarget = null;
  181. }
  182. },
  183. /*
  184. *****************************************************************************
  185. MEMBERS
  186. *****************************************************************************
  187. */
  188. members :
  189. {
  190. __manager : null,
  191. // interface implementation
  192. canHandleEvent : function(target, type) {
  193. return target instanceof qx.ui.mobile.core.Widget;
  194. },
  195. // interface implementation
  196. registerEvent : function(target, type, capture)
  197. {
  198. var element = target.getContainerElement();
  199. qx.event.Registration.addListener(element, type, this._dispatchEvent, this, capture);
  200. },
  201. // interface implementation
  202. unregisterEvent : function(target, type, capture)
  203. {
  204. var element = target.getContainerElement();
  205. qx.event.Registration.removeListener(element, type, this._dispatchEvent, this, capture);
  206. },
  207. /**
  208. * Dispatches a DOM event on a widget.
  209. *
  210. * @param domEvent {qx.event.type.Event} The event object to dispatch.
  211. */
  212. _dispatchEvent: function(domEvent){
  213. // EVENT TARGET
  214. var domTarget = domEvent.getTarget();
  215. if (!domTarget || domTarget.id == null) {
  216. return;
  217. }
  218. var widgetTarget = qx.ui.mobile.core.Widget.getWidgetById(domTarget.id);
  219. // EVENT RELATED TARGET
  220. if (domEvent.getRelatedTarget) {
  221. var domRelatedTarget = domEvent.getRelatedTarget();
  222. if (domRelatedTarget && domRelatedTarget.id) {
  223. var widgetRelatedTarget = qx.ui.mobile.core.Widget.getWidgetById(domRelatedTarget.id);
  224. }
  225. }
  226. // EVENT CURRENT TARGET
  227. var currentTarget = domEvent.getCurrentTarget();
  228. var currentWidget = qx.ui.mobile.core.Widget.getWidgetById(currentTarget.id);
  229. if (!currentWidget) {
  230. return;
  231. }
  232. // PROCESS LISTENERS
  233. // Load listeners
  234. var capture = domEvent.getEventPhase() == qx.event.type.Event.CAPTURING_PHASE;
  235. var type = domEvent.getType();
  236. var listeners = this.__manager.getListeners(currentWidget, type, capture);
  237. if (!listeners || listeners.length === 0) {
  238. return;
  239. }
  240. // Create cloned event with correct target
  241. var widgetEvent = qx.event.Pool.getInstance().getObject(domEvent.constructor);
  242. domEvent.clone(widgetEvent);
  243. widgetEvent.setTarget(widgetTarget);
  244. widgetEvent.setRelatedTarget(widgetRelatedTarget || null);
  245. widgetEvent.setCurrentTarget(currentWidget);
  246. // Keep original target of DOM event, otherwise map it to the original
  247. var orig = domEvent.getOriginalTarget();
  248. if (orig && orig.id) {
  249. var widgetOriginalTarget = qx.ui.mobile.core.Widget.getWidgetById(orig.id);
  250. widgetEvent.setOriginalTarget(widgetOriginalTarget);
  251. }
  252. else {
  253. widgetEvent.setOriginalTarget(domTarget);
  254. }
  255. // Dispatch it on all listeners
  256. for (var i = 0, l = listeners.length; i < l; i++) {
  257. var context = listeners[i].context || currentWidget;
  258. listeners[i].handler.call(context, widgetEvent);
  259. }
  260. // Synchronize propagation stopped/prevent default property
  261. if (widgetEvent.getPropagationStopped()) {
  262. domEvent.stopPropagation();
  263. }
  264. if (widgetEvent.getDefaultPrevented()) {
  265. domEvent.preventDefault();
  266. }
  267. // Release the event instance to the event pool
  268. qx.event.Pool.getInstance().poolObject(widgetEvent);
  269. }
  270. },
  271. /*
  272. *****************************************************************************
  273. DESTRUCTOR
  274. *****************************************************************************
  275. */
  276. destruct : function() {
  277. this.__manager = null;
  278. },
  279. /*
  280. *****************************************************************************
  281. DEFER
  282. *****************************************************************************
  283. */
  284. defer : function(statics)
  285. {
  286. qx.event.Registration.addHandler(statics);
  287. qx.event.Registration.addListener(document, "touchstart", statics.__onTouchStart);
  288. qx.event.Registration.addListener(document, "touchend", statics.__onTouchEnd);
  289. qx.event.Registration.addListener(document, "touchcancel", statics.__onTouchEnd);
  290. qx.event.Registration.addListener(document, "touchmove", statics.__onTouchMove);
  291. }
  292. });