[Pkg-javascript-commits] [dojo] 05/21: Fixes preventDefault() on synthetic event "touch.move" which has no effect on "touchmove" native event.

David Prévot taffit at moszumanska.debian.org
Thu Aug 21 17:39:53 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to annotated tag 1.9.2
in repository dojo.

commit 7305a1eb8b0c714689afe24c7271f9cc821c9e8d
Author: Sebastien Pereira <spereira at javalive.net>
Date:   Thu Jul 11 23:24:41 2013 +0900

    Fixes preventDefault() on synthetic event "touch.move" which has no effect on "touchmove" native event.
    
    Refs #17220.
    
    (cherry picked from commit 6647dcdb24a997a0d6183e0c94c2525b9ae4a8d4)
---
 tests/test_touch.html | 247 ++++++++++++++++++++++++++++++++++++--------------
 touch.js              |   6 +-
 2 files changed, 185 insertions(+), 68 deletions(-)

diff --git a/tests/test_touch.html b/tests/test_touch.html
index 8e2b16e..6eb0fe0 100644
--- a/tests/test_touch.html
+++ b/tests/test_touch.html
@@ -2,19 +2,19 @@
 <html>
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-		<meta name="viewport" content="width=device-width,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+		<meta name="viewport" content="width=device-width,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 		<title>Dojo Touch Testing</title>
 		<style type="text/css">
 			#test {
 				width: 300px;
 				height: 150px;
 				border: 1px solid #7FB0DB;
-				background-color: #7FB0DB;			
+				background-color: #7FB0DB;
 			}
 			#innertest {
 				border: 1px solid white;
 				width: 100px;
-				heigh: 75px;
+				height: 75px;
 				background-color: white;
 			}
 			#test2 {
@@ -29,9 +29,11 @@
 				height: 200px;
 				float: left;
 			}
-			#dohDiv{
+			#dohDiv {
 				display: none;
-			}			
+				background-color:#800300;
+				color: wheat;
+			}
 		</style>
 		<script type="text/javascript" src="../dojo.js" data-dojo-config="async: true"></script>
 		<script>
@@ -39,14 +41,15 @@
 				"dojo/_base/array",
 				"dojo/dom",
 				"dojo/_base/lang",
-				"dojo/touch",
 				"dojo/on",
 				"dojo/has",
-				"dojo/domReady!"
-			], function(array, dom, lang, touch, on, has){
+				"doh/runner",
+				"dojo/dom-geometry",
+				"dojo/dom-style",
+				"dojo/domReady",
+				"dojo/touch"
+			], function(array, dom, lang, on, has, doh, domGeom, domStyle, domReady, touch){
 
-				var mspointer = navigator.msPointerEnabled; // IE10+ PSPointer events?
-				
 				var action = function(comment, e){
 					// summary:
 					//		Callback to display into when events fire
@@ -108,70 +111,180 @@
 //					on(node, "orientationchange", action);
 
 
-				//================================= DoH tests - only running on desktop ======================
-				if(has("touch")){
-					//FIXME - DoH not supported on touch device
-					return;
+				/**
+				 * Fires an event.  All coordinates are defaulted to zero.
+				 * @param target the target element.
+				 * @param eventType touchstart, touchmove or touchend, or mouse or MSPointer equivalents.
+				 */
+				function emit(target, eventType, options){
+					var targetPos = domGeom.position(target);
+
+					options = lang.mixin({
+						pageX: targetPos.x + targetPos.w / 2,
+						pageY: targetPos.y + targetPos.h / 2
+					}, options || {});
+
+					if(document.createEvent && target.dispatchEvent){
+						var touch = {
+							identifier: (new Date()).getTime(),
+							target: target,
+							screenX: 0,
+							screenY: 0,
+							clientX: 0,
+							clientY: 0,
+							pageX: 0,
+							pageY: 0
+						};
+						lang.mixin(touch, options || {});
+
+						var mouseEvent = document.createEvent("MouseEvent");
+						mouseEvent.initMouseEvent(
+								eventType,
+								true,
+								true,
+								target.ownerDocument.defaultView,
+								0,
+								0,
+								0,
+								0,
+								0,
+								false,
+								false,
+								false,
+								false,
+								0,
+								document.body	// relatedTarget, for mouseout events
+						);
+
+						if(/touch/.test(eventType)){
+							mouseEvent['touches'] = [touch];
+							mouseEvent['targetTouches'] = [touch];
+							mouseEvent['changedTouches'] = [touch];
+						}
+
+						target.dispatchEvent(mouseEvent);
+					}else{
+						options.bubbles = true;
+						options.cancelable = true;
+						on.emit(target, eventType, options);
+					}
 				}
 
-				require(["doh/runner", "dojo/dom-style"], function(doh, domStyle){
+				// if we declare "dojo/domReady!" touch.js will register its handler *after* the test execution
+				// so here we explicitly call domReady.
+				domReady(function(){
 					var dohDiv = dom.byId('dohDiv');
 					domStyle.set(dohDiv, {display: 'block'});
 
-					function setObj(obj, e){
-						obj.type = e.type;
-						obj.target = e.target;
-					}
-					function assert(obj, type, target){
-						doh.assertEqual(type, obj.type);
-						doh.assertEqual(target, obj.target);
+					// Function to register tests on mouse events, touch events, or Microsoft's pointer-ish events
+					function register(testName, downEvent, moveEvent, upEvent, cancelEvent){
+						doh.register(testName, [
+							function press(){
+								var executed, target;
+								on.once(dohDiv, touch.press, function(e){
+									//console.log(e.type);
+									executed = true;
+									target = e.target;
+								});
+								emit(dohDiv, downEvent);
+								doh.t(executed, 'dojo.touch.press fired');
+								doh.is(dohDiv, target, "target");
+							},
+							function move(){
+								var executed, target;
+								on.once(dohDiv, touch.move, function(e){
+									//console.log(e.type);
+									executed = true;
+									target = e.target;
+								});
+								emit(dohDiv, moveEvent);
+								doh.t(executed, 'dojo.touch.move fired');
+								doh.is(dohDiv, target, "target");
+							},
+							function release(){
+								var executed, target;
+								on.once(dohDiv, touch.release, function(e){
+									//console.log(e.type);
+									executed = true;
+									target = e.target;
+								});
+								emit(dohDiv, upEvent, {screenX: 0, screenY: 50});
+								doh.t(executed, 'dojo.touch.release fired');
+								doh.is(dohDiv, target, "target");
+							},
+							function cancel(){
+								var executed, target;
+								on.once(dohDiv, touch.cancel, function(e){
+									executed = true;
+									target = e.target;
+								});
+								emit(dohDiv, cancelEvent, {
+									relatedTarget: document.body,	// needed for mouseout event
+									screenX: 0,
+									screenY: 50,
+									pageX: 0,
+									pageY: 0
+								});
+								doh.t(executed, 'dojo.touch.cancel fired');
+								doh.is(dohDiv, target, "target");
+							},
+							function movePreventDefault(){
+								/**
+								 * checks that calling preventDefault() on dojo "touch.move" event
+								 * prevents default behavior on the underlying native event
+								 * Ref. #17220
+								 * window
+								 *    |    =>    (1) listen and prevent default on dojo "touch.move" event
+								 *    |    =>    (2) listen and check default behavior status on native "touchmove" event
+								 *    |
+								 *    +--dohDiv    =>    (3) dispatch native "touchmove" event
+								 **/
+								var prevented = false;
+
+								// (1) register dojo "touch.move" listener
+								on.once(dohDiv, touch.move, function(e){
+									e.preventDefault();
+									//console.log("prevent default on event " + e.type);
+								});
+
+								// (2) register listener for native event (touchmove, mousemove, or MSPointerMove)
+								// Call addEventListener() except on IE6-8 where that's not supported
+								function listener(e){
+									prevented = e.defaultPrevented;
+									//console.log("native listener, prevented = " + prevented);
+								}
+								if(window.addEventListener){
+									window.addEventListener(moveEvent, listener);
+								}else{
+									// IE6-8 code path
+									on.once(document.body, moveEvent, listener);
+								}
+
+								// (3) dispatch native touchmove/mousemove/MSPointerMove event
+								emit(dohDiv, moveEvent);
+								doh.t(prevented, 'prevented');
+
+								if(window.addEventListener){
+									window.removeEventListener(moveEvent, listener);
+								}
+							}
+						]);
 					}
 
-					doh.register("dojo.touch", [
-						function press(){
-							var executed, obj = {};
-							on(dohDiv, touch.press, function(e){
-								//console.log(e.type);
-								executed = true;
-								setObj(obj, e);
-							});
-							on.emit(dohDiv, mspointer?'MSPointerDown':'mousedown', {});
-							doh.assertTrue(executed, 'dojo.touch.press not fired');
-							assert(obj, mspointer?'MSPointerDown':'mousedown', dohDiv);
-						},
-						function move(){
-							var executed, obj = {};
-							on(dohDiv, touch.move, function(e){
-								//console.log(e.type);
-								executed = true;
-								setObj(obj, e);
-							});
-							on.emit(dohDiv, mspointer?'MSPointerMove':'mousemove', {});
-							doh.assertTrue(executed, 'dojo.touch.move not fired');
-							assert(obj, mspointer?'MSPointerMove':'mousemove', dohDiv);
-						},
-						function release(){
-							var executed, obj = {};
-							on(dohDiv, touch.release, function(e){
-								//console.log(e.type);
-								executed = true;
-								setObj(obj, e);
-							});
-							on.emit(dohDiv, mspointer?'MSPointerUp':'mouseup',  {screenX: 0, screenY: 50});
-							doh.assertTrue(executed, 'dojo.touch.release not fired');
-							assert(obj, mspointer?'MSPointerUp':'mouseup', dohDiv);
-						},
-						function cancel(){
-							var executed, obj = {};
-							on(dohDiv, touch.cancel, function(e){
-								executed = true;
-								setObj(obj, e);
-							});
-							on.emit(dohDiv, 'mouseout',  {screenX: 0, screenY: 50});
-							doh.assertTrue(executed, 'dojo.touch.cancel not fired');
-							assert(obj, 'mouseout', dohDiv);
+					// Setup tests relevant for this platform
+					if(navigator.msPointerEnabled){
+						register('MSPointer events', 'MSPointerDown', 'MSPointerMove', 'MSPointerUp',
+								has('touch') ? 'MSPointerCancel' : 'mouseout');
+					}else{
+						// Mouse is always supported, even on devices with touch capability.
+						// Test mouse first because once we start emitting touch events, dojo/touch ignores mouse events
+						// for 1000ms.
+						register('mouse events', 'mousedown', 'mousemove', 'mouseup', 'mouseout');
+
+						if(has("touch")){
+							register('touch events', 'touchstart', 'touchmove', 'touchend', 'touchcancel');
 						}
-					]);
+					}
 
 					doh.run();
 				});
@@ -188,9 +301,9 @@
 		<div id="test2">
 			touch.move
 		</div>
+		<div id="dohDiv">doh</div>
 		<div id="current"></div>
 		<div id="log"></div>
 		<br style="clear:both"/>
-		<div id="dohDiv">doh</div>
 	</body>
 </html>
diff --git a/touch.js b/touch.js
index ac30fe5..6b53bd7 100644
--- a/touch.js
+++ b/touch.js
@@ -219,7 +219,11 @@ function(dojo, aspect, dom, domClass, lang, on, has, mouse, domReady, win){
 
 						// Unlike a listener on "touchmove", on(node, "dojotouchmove", listener) fires when the finger
 						// drags over the specified node, regardless of which node the touch started on.
-						on.emit(newNode, "dojotouchmove", copyEventProps(evt));
+						if(!on.emit(newNode, "dojotouchmove", copyEventProps(evt))){
+							// emit returns false when synthetic event "dojotouchmove" is cancelled, so we prevent the
+							// default behavior of the underlying native event "touchmove".
+							evt.preventDefault();
+						}
 					}
 				});
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/dojo.git



More information about the Pkg-javascript-commits mailing list