[Pkg-javascript-commits] [dojo] 03/04: Backport of dojo/touch fixes from 1.8 to 1.7.

David Prévot taffit at moszumanska.debian.org
Tue Dec 9 17:50:38 UTC 2014


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

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

commit e7403082d02faba2e47cb645d2532dd2920f60b8
Author: Bill Keese <bill at dojotoolkit.org>
Date:   Thu Apr 19 01:04:42 2012 +0000

    Backport of dojo/touch fixes from 1.8 to 1.7.
    
    * make touch.move work like mousemove, firing based on the node the mouse/finger is over
      rather than where the operation started, Refs #14185
      (partial cherry pick from commit 2b82a975e09202b61b8f448e2e6b7039155c542b)
    
    * API doc updates:
    
    (cherry picked from commit ab85377d3e33a688662a5c622243ca7a4d642fd7)
    (cherry picked from commit f56b8330ed5fedce6c2949b44283bb22d108223b)
    (cherry picked from commit 80e7da06943add0e4e2605544e3debdf1c7abdff)
    (cherry picked from commit 3ad285a96c45a2411ecf261a95d47bbbff9ff705)
    (cherry picked from commit e8eeae9d611744827d9579199f9f00bf73101a16)
    
    Refs #14185, #14980, #13101
    
    * Minimize refs to dojo "global", and only augment dojo when has("extend-dojo") is true, refs #13959 !strict
    (partial cherry pick from commit e38ec9120083cc0ca2bec9ae11f773b24bb12829)
    
    Partial commit of:
    
    * fix dojo/touch.move on scrolled pages on mobile fixes #15821, refs #15185 !strict.
    (cherry picked from commit 8f4d6322f9afccd261db866073b383f22cd24bf2)
    (cherry picked from commit 89ae661b53a50dc4d8d35b8371c74335cffbaf07)
    
    * fix touch.move on iOS4, fixes #15831
    (cherry picked from commit 1b55198f184c942fd27b8eaf52f26868985c0dd6)
    
    * android fixes, fixes #15892
    (cherry picked from commit 5393ee0403b2b4fac2ab90a371e8234ea6dbffb0)
    (cherry picked from commit b7cee4c70f83f7563a7b238ae3079c9be4bde4e3)
    
    * Make evt.touches available on iOS6 for touch.move synthetic event, fixes #16090
    (cherry picked from commit d49f4bed4bd963a8563d9b284face16b5debd146)
    
    * Don't make copy of event object.   It appears to be unnecessary, and it triggers an iOS6 bug with properties
      in the event object being marked as non-enumerable.
      Fixes #16108, #16090.
    
    (cherry picked from commit 2d5a6f68caf4cbb543c44025f2a0453e21fc3026)
    
    * support machines with both touch and mouse, fixes #13048
    (cherry picked from commit 62edc04b442f0560359229361c778b7205dad804)
---
 mouse.js              |  48 +++++++----
 tests/test_touch.html |  75 +++++++++++++-----
 touch.js              | 215 ++++++++++++++++++++++++++++++++++++++++++--------
 3 files changed, 269 insertions(+), 69 deletions(-)

diff --git a/mouse.js b/mouse.js
index 89c3b12..3dfd1ec 100644
--- a/mouse.js
+++ b/mouse.js
@@ -1,22 +1,10 @@
 define(["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(dojo, on, has, dom, win){
 
-	/*=====
-	dojo.mouse = {
+	// module:
+	//		dojo/mouse
 	// summary:
 	//		This module provide mouse event handling utility functions and exports
 	//		mouseenter and mouseleave event emulation.
-	// enter: Synthetic Event
-	//		This is an extension event for the mouseenter that IE provides, emulating the
-	//		behavior on other browsers.
-	// leave: Synthetic Event
-	//		This is an extension event for the mouseleave that IE provides, emulating the
-	//		behavior on other browsers.
-	// isLeft: Function
-	//		Test an event object (from a mousedown event) to see if the left button was pressed.
-	// isMiddle: Function
-	//		Test an event object (from a mousedown event) to see if the middle button was pressed.
-	// isRight: Function
-	//		Test an event object (from a mousedown event) to see if the right button was pressed.
 	// example:
 	//		To use these events, you register a mouseenter like this:
 	//		|	define(["dojo/on", dojo/mouse"], function(on, mouse){
@@ -26,8 +14,6 @@ define(["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(
 	//		|		on(targetNode, mouse.leave, function(event){
 	//		|			dojo.removeClass(targetNode, "highlighted");
 	//		|		});
-	};
-	======*/
 
     has.add("dom-quirks", win.doc && win.doc.compatMode == "BackCompat");
  	has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div"));
@@ -118,10 +104,40 @@ define(["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(
 		return handler;
 	}
 	return {
+		_eventHandler: eventHandler,		// for dojo/touch
+
+		// enter: Synthetic Event
+		//		This is an extension event for the mouseenter that IE provides, emulating the
+		//		behavior on other browsers.
 		enter: eventHandler("mouseover"),
+
+		// leave: Synthetic Event
+		//		This is an extension event for the mouseleave that IE provides, emulating the
+		//		behavior on other browsers.
 		leave: eventHandler("mouseout"),
+
 		isLeft: mouseButtons.isLeft,
+		/*=====
+		isLeft: function(){
+			// summary:
+			//		Test an event object (from a mousedown event) to see if the left button was pressed.
+		},
+		=====*/
+
 		isMiddle: mouseButtons.isMiddle,
+		/*=====
+		 isMiddle: function(){
+			 // summary:
+			 //		Test an event object (from a mousedown event) to see if the middle button was pressed.
+		 },
+		 =====*/
+
 		isRight: mouseButtons.isRight
+		/*=====
+		 , isRight: function(){
+			 // summary:
+			 //		Test an event object (from a mousedown event) to see if the right button was pressed.
+		 }
+		 =====*/
 	};
 });
diff --git a/tests/test_touch.html b/tests/test_touch.html
index 5a2b510..59ce9e4 100644
--- a/tests/test_touch.html
+++ b/tests/test_touch.html
@@ -11,9 +11,16 @@
 				border: 1px solid #7FB0DB;
 				background-color: #7FB0DB;			
 			}
-			#log {
+			#innertest {
+				border: 1px solid white;
+				width: 100px;
+				heigh: 75px;
+				background-color: white;
+			}
+			#current, #log {
 				width: 300px;
 				height: 200px;
+				float: left;
 			}
 			#dohDiv{
 				display: none;
@@ -22,20 +29,26 @@
 		<script type="text/javascript" src="../dojo.js" djConfig="parseOnLoad: true"></script>
 		<script>
 			require([
-				"dojo/_base/html",
+				"dojo/_base/array",
+				"dojo/dom",
 				"dojo/_base/event",
+				"dojo/_base/lang",
 				"dojo/ready",
 				"dojo/touch",
 				"dojo/on",
 				"dojo/has",
 				"dojo/dom-style",
 				"doh/runner"
-			], function(html, evt, ready, touch, on, has, domStyle, doh){			
+			], function(array, dom, evt, lang, ready, touch, on, has, domStyle, doh){
 				ready(function(){
-					var action = function(e){
-						evt.stop(e);
-						html.byId("log").innerHTML = "";
-						var info = "[Touch Event]: " + e.type + "<br/> ------ Event Properties: ------<br/>";
+					var action = function(comment, e){
+						// summary:
+						//		Callback to display into when events fire
+						// Detailed log of the most recent event:
+
+						dom.byId("current").innerHTML = "Most recent event:";
+						var info = "[Touch Event]: " + e.type + " on " + comment +
+								"<br/> ------ Event Properties: ------<br/>";
 						for(var i in e){
 						  if(i == "touches" || i == "targetTouches" || i == "changedTouches"){
 						    info += i + ": " + e[i].length + "<br/>";
@@ -45,17 +58,30 @@
 						    }
 						  }
 						}
-						html.byId("log").innerHTML += info + "<br/>";
+						dom.byId("current").innerHTML += info + "<br/>";
+
+						// This is a log of all events, most recent first:
+						dom.byId("log").innerHTML = comment + "{type:" +
+								e.type + ", target:" + (e.target.id||e.target.tagName) +
+								"}<br/>" + dom.byId("log").innerHTML;
 					};
 					
-					var node = html.byId("test");
-				
-					//1. should work well on PC and touch devices 
-					on(node, touch.press, action);
-					on(node, touch.move, action);
-					on(node, touch.release, action);
-					on(node, touch.cancel, action);
+					var node = dom.byId("test"),
+						innerNode = dom.byId("innertest");
+
+					//1. should work well on PC and touch devices
+					array.forEach(["test", "innertest"], function(name){
+						for(var event in touch){
+							if(event != "move"){
+								on(dom.byId(name), touch[event], lang.hitch(null, action, "on("+name+", touch."+event+")-->"));
+							}
+						}
+					});
 
+					on(document, "touchmove", function(evt){
+						// Prevent scrolling since it interferes with testing touchover/touchout on "test" and "innertest"
+						evt.preventDefault();
+					});
 					
 //					//2. should work well across touch devices
 //					on(node, "touchstart", action);
@@ -67,13 +93,20 @@
 					//3. we can also isolate mouse/touch handlers
 					on(node, "touchend", function(){alert("isolated touchend handler");});
 					on(node, "mouseup", function(){alert("isolated mouseup handler");});
+					/*
+					on(node, "touchmove", function(e){
+						dom.byId("log").innerHTML = 'on(node,"touchmove")-->{type:' +
+							e.type + ", target:" + (e.target.id||e.target.tagName) +
+							"}<br/>" + dom.byId("log").innerHTML;
+					});
+					*/
 				
 					//================================= DoH tests - only running on desktop ======================
 					if(has("touch")){
 						//FIXME - DoH not supported on touch device
 						return;
 					}
-					var dohDiv = html.byId('dohDiv');
+					var dohDiv = dom.byId('dohDiv');
 					domStyle.set(dohDiv, {display: 'block'});
 					
 					function setObj(obj, e){
@@ -136,9 +169,15 @@
 		</script>
 	</head>
 	<body>
-		<div id="test"></div>
+		<div id="test">
+			test
+			<div id="innertest">
+				inner test
+			</div>
+		</div>
+		<div id="current"></div>
 		<div id="log"></div>
-		<br/>
+		<br style="clear:both"/>
 		<div id="dohDiv">doh</div>
 	</body>
 </html>
\ No newline at end of file
diff --git a/touch.js b/touch.js
index 328ae1f..e4e57d7 100644
--- a/touch.js
+++ b/touch.js
@@ -1,34 +1,150 @@
-define(["./_base/kernel", "./on", "./has", "./mouse"], function(dojo, on, has, mouse){
-// module:
-//		dojo/touch
+define(["./_base/kernel", "./aspect", "./dom", "./on", "./has", "./mouse", "./domReady", "./_base/window"],
+function(dojo, aspect, dom, on, has, mouse, domReady, win){
 
-/*=====
-	dojo.touch = {
+	// module:
+	//		dojo/touch
+
+	var hasTouch = has("touch");
+
+	// TODO: get iOS version from dojo/sniff after #15827 is fixed
+	var ios4 = false;
+	if(has("ios")){
+		var ua = navigator.userAgent;
+		var v = ua.match(/OS ([\d_]+)/) ? RegExp.$1 : "1";
+		var os = parseFloat(v.replace(/_/, '.').replace(/_/g, ''));
+		ios4 = os < 5;
+	}
+
+	// Time of most recent touchstart or touchmove event
+	var lastTouch;
+
+	function dualEvent(mouseType, touchType){
+		// Returns synthetic event that listens for both the specified mouse event and specified touch event.
+		// But ignore fake mouse events that were generated due to the user touching the screen.
+		if(hasTouch){
+			return function(node, listener){
+				var handle1 = on(node, touchType, listener),
+					handle2 = on(node, mouseType, function(evt){
+						if(!lastTouch || (new Date()).getTime() > lastTouch + 1000){
+							listener.call(this, evt);
+						}
+					});
+				return {
+					remove: function(){
+						handle1.remove();
+						handle2.remove();
+					}
+				};
+			};
+		}else{
+			// Avoid creating listeners for touch events on performance sensitive older browsers like IE6
+			return function(node, listener){
+				return on(node, mouseType, listener);
+			}
+		}
+	}
+
+	var touchmove, hoveredNode;
+
+	if(hasTouch){
+		domReady(function(){
+			// Keep track of currently hovered node
+			hoveredNode = win.body();	// currently hovered node
+
+			win.doc.addEventListener("touchstart", function(evt){
+				lastTouch = (new Date()).getTime();
+
+				// Precede touchstart event with touch.over event.  DnD depends on this.
+				// Use addEventListener(cb, true) to run cb before any touchstart handlers on node run,
+				// and to ensure this code runs even if the listener on the node does event.stop().
+				var oldNode = hoveredNode;
+				hoveredNode = evt.target;
+				on.emit(oldNode, "dojotouchout", {
+					target: oldNode,
+					relatedTarget: hoveredNode,
+					bubbles: true
+				});
+				on.emit(hoveredNode, "dojotouchover", {
+					target: hoveredNode,
+					relatedTarget: oldNode,
+					bubbles: true
+				});
+			}, true);
+
+			// Fire synthetic touchover and touchout events on nodes since the browser won't do it natively.
+			on(win.doc, "touchmove", function(evt){
+				lastTouch = (new Date()).getTime();
+
+				var newNode = win.doc.elementFromPoint(
+					evt.pageX - (ios4 ? 0 : win.global.pageXOffset), // iOS 4 expects page coords
+					evt.pageY - (ios4 ? 0 : win.global.pageYOffset)
+				);
+				if(newNode && hoveredNode !== newNode){
+					// touch out on the old node
+					on.emit(hoveredNode, "dojotouchout", {
+						target: hoveredNode,
+						relatedTarget: newNode,
+						bubbles: true
+					});
+
+					// touchover on the new node
+					on.emit(newNode, "dojotouchover", {
+						target: newNode,
+						relatedTarget: hoveredNode,
+						bubbles: true
+					});
+
+					hoveredNode = newNode;
+				}
+			});
+		});
+
+		// Define synthetic touch.move event that unlike the native touchmove, fires for the node the finger is
+		// currently dragging over rather than the node where the touch started.
+		touchmove = function(node, listener){
+			return on(win.doc, "touchmove", function(evt){
+				if(node === win.doc || dom.isDescendant(hoveredNode, node)){
+					evt.target = hoveredNode;
+					listener.call(this, evt);
+				}
+			});
+		};
+	}
+
+
+	//device neutral events - touch.press|move|release|cancel/over/out
+	var touch = {
+		press: dualEvent("mousedown", "touchstart"),
+		move: dualEvent("mousemove", touchmove),
+		release: dualEvent("mouseup", "touchend"),
+		cancel: dualEvent(mouse.leave, "touchcancel"),
+		over: dualEvent("mouseover", "dojotouchover"),
+		out: dualEvent("mouseout", "dojotouchout"),
+		enter: mouse._eventHandler(dualEvent("mouseover","dojotouchover")),
+		leave: mouse._eventHandler(dualEvent("mouseout", "dojotouchout"))
+	};
+
+	/*=====
+	touch = {
 		// summary:
 		//		This module provides unified touch event handlers by exporting
 		//		press, move, release and cancel which can also run well on desktop.
 		//		Based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
 		//
 		// example:
-		//		1. Used with dojo.connect()
-		//		|	dojo.connect(node, dojo.touch.press, function(e){});
-		//		|	dojo.connect(node, dojo.touch.move, function(e){});
-		//		|	dojo.connect(node, dojo.touch.release, function(e){});
-		//		|	dojo.connect(node, dojo.touch.cancel, function(e){});
-		//
-		//		2. Used with dojo.on
+		//		Used with dojo.on
 		//		|	define(["dojo/on", "dojo/touch"], function(on, touch){
 		//		|		on(node, touch.press, function(e){});
 		//		|		on(node, touch.move, function(e){});
 		//		|		on(node, touch.release, function(e){});
 		//		|		on(node, touch.cancel, function(e){});
-		//
-		//		3. Used with dojo.touch.* directly
-		//		|	dojo.touch.press(node, function(e){});
-		//		|	dojo.touch.move(node, function(e){});
-		//		|	dojo.touch.release(node, function(e){});
-		//		|	dojo.touch.cancel(node, function(e){});
-		
+		// example:
+		//		Used with touch.* directly
+		//		|	touch.press(node, function(e){});
+		//		|	touch.move(node, function(e){});
+		//		|	touch.release(node, function(e){});
+		//		|	touch.cancel(node, function(e){});
+
 		press: function(node, listener){
 			// summary:
 			//		Register a listener to 'touchstart'|'mousedown' for the given node
@@ -68,22 +184,51 @@ define(["./_base/kernel", "./on", "./has", "./mouse"], function(dojo, on, has, m
 			//		Callback function
 			// returns:
 			//		A handle which will be used to remove the listener by handle.remove()
+		},
+		over: function(node, listener){
+			// summary:
+			//		Register a listener to 'mouseover' or touch equivalent for the given node
+			// node: Dom
+			//		Target node to listen to
+			// listener: Function
+			//		Callback function
+			// returns:
+			//		A handle which will be used to remove the listener by handle.remove()
+		},
+		out: function(node, listener){
+			// summary:
+			//		Register a listener to 'mouseout' or touch equivalent for the given node
+			// node: Dom
+			//		Target node to listen to
+			// listener: Function
+			//		Callback function
+			// returns:
+			//		A handle which will be used to remove the listener by handle.remove()
+		},
+		enter: function(node, listener){
+			// summary:
+			//		Register a listener to mouse.enter or touch equivalent for the given node
+			// node: Dom
+			//		Target node to listen to
+			// listener: Function
+			//		Callback function
+			// returns:
+			//		A handle which will be used to remove the listener by handle.remove()
+		},
+		leave: function(node, listener){
+			// summary:
+			//		Register a listener to mouse.leave or touch equivalent for the given node
+			// node: Dom
+			//		Target node to listen to
+			// listener: Function
+			//		Callback function
+			// returns:
+			//		A handle which will be used to remove the listener by handle.remove()
 		}
 	};
-=====*/
+	=====*/
 
-	function _handle(/*String - press | move | release | cancel*/type){
-		return function(node, listener){//called by on(), see dojo.on
-			return on(node, type, listener);
-		};
-	}
-	var touch = has("touch");
-	//device neutral events - dojo.touch.press|move|release|cancel
-	dojo.touch = {
-		press: _handle(touch ? "touchstart": "mousedown"),
-		move: _handle(touch ? "touchmove": "mousemove"),
-		release: _handle(touch ? "touchend": "mouseup"),
-		cancel: touch ? _handle("touchcancel") : mouse.leave
-	};
-	return dojo.touch;
-});
\ No newline at end of file
+	has("extend-dojo") && (dojo.touch = touch);
+
+	return touch;
+});

-- 
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