From a1637a6dddfab37dd907083e965533bceb64903b Mon Sep 17 00:00:00 2001 From: Bill Keese Date: Tue, 17 Apr 2012 02:56:36 +0000 Subject: [PATCH] Get DnD working on mobile. Probably there are still some rough edges. Fixes #15185 !strict. git-svn-id: http://svn.dojotoolkit.org/src/dojo/trunk@28349 560b804f-0ae3-0310-86f3-f6aa0a117693 --- dnd/Container.js | 13 ++++++++----- dnd/Manager.js | 12 ++++++++---- dnd/Source.js | 6 +++--- tests/dnd/dndDefault.css | 4 ++++ 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/dnd/Container.js b/dnd/Container.js index 63f1e8732b..4b7d73c332 100644 --- a/dnd/Container.js +++ b/dnd/Container.js @@ -76,21 +76,23 @@ dojo.dnd.Item = function(){ =====*/ // Setup synthetic "touchover" and "touchout" events to handle mouseout/mouseover plus their touch equivalents. -// The synthetic events work (although are less efficient than the native events) for mouse movement too. // Probably this code should eventually be moved to dojo/touch. +// TODO: should touchend cause touchout event on the currently "hovered" node? var touchover = "mouseover", touchout = "mouseout"; if(has("touch")){ - // Keep track of the currently hovered node + // Keep track of the currently hovered node. This code tries to fire a touchover event on touchstart, + // but that part doesn't work because Selector::onMouseDown() getsc called before this code does, + // but expects that there was already a mouseenter (aka touchover) event. Also, Selector::onMouseDown() calls + // evt.stop() preventing this code from even seeing the event. var hoveredNode, // currently hovered node tracker = new Evented(); // emits events when hovered node changes ready(function(){ - on(win.doc, "touchstart, touchmove, mousemove", function(evt){ + on(win.doc, "touchstart, touchmove", function(evt){ var newHoverNode = win.doc.elementFromPoint( evt.pageX - win.body().parentNode.scrollLeft, evt.pageY - win.body().parentNode.scrollTop ); if(newHoverNode != hoveredNode){ - console.log("hovered node changed from ", hoveredNode, " to ", newHoverNode); tracker.emit("hoverNode", hoveredNode, hoveredNode = newHoverNode); } }); @@ -172,6 +174,7 @@ var Container = declare("dojo.dnd.Container", Evented, { // set up events this.events = [ on(this.node, touchover, lang.hitch(this, "onMouseOver")), + on(this.node, "touchstart", lang.hitch(this, "onMouseOver")), // because on mobile there's no mouseover equivalent before the touchpress event on(this.node, touchout, lang.hitch(this, "onMouseOut")), // cancel text selection and text dragging on(this.node, "dragstart", lang.hitch(this, "onSelectStart")), @@ -320,7 +323,7 @@ var Container = declare("dojo.dnd.Container", Evented, { // mouse events onMouseOver: function(e){ // summary: - // event processor for onmouseover + // event processor for onmouseover or touch, to mark that element as the current element // e: Event // mouse event var n = e.relatedTarget; diff --git a/dnd/Manager.js b/dnd/Manager.js index a4db0c3c17..5d6032e4c2 100644 --- a/dnd/Manager.js +++ b/dnd/Manager.js @@ -1,8 +1,8 @@ define([ "../_base/array", "../_base/declare", "../_base/event", "../_base/lang", "../_base/window", - "../dom-class", "../Evented", "../keys", "../on", "../topic", "../touch", + "../dom-class", "../Evented", "../has", "../keys", "../on", "../topic", "../touch", "./common", "./autoscroll", "./Avatar" -], function(array, declare, event, lang, win, domClass, Evented, keys, on, topic, touch, +], function(array, declare, event, lang, win, domClass, Evented, has, keys, on, topic, touch, dnd, autoscroll, Avatar) { // module: @@ -29,8 +29,8 @@ var Manager = declare("dojo.dnd.Manager", [Evented], { }, // avatar's offset from the mouse - OFFSET_X: 16, - OFFSET_Y: 16, + OFFSET_X: has("touch") ? 0 : 16, + OFFSET_Y: has("touch") ? -64 : 16, // methods overSource: function(source){ @@ -137,6 +137,10 @@ var Manager = declare("dojo.dnd.Manager", [Evented], { this._setCopyStatus(copy); } } + if(has("touch")){ + // Prevent page from scrolling so that user can drag instead. + e.preventDefault(); + } }, onMouseUp: function(e){ // summary: diff --git a/dnd/Source.js b/dnd/Source.js index 47df864d22..d504a3a437 100644 --- a/dnd/Source.js +++ b/dnd/Source.js @@ -268,7 +268,7 @@ var Source = declare("dojo.dnd.Source", Selector, { // topic event processor for /dnd/source/over, called when detected a current source // source: Object // the source which has the mouse over it - if(this != source){ + if(this !== source){ this.mouseDown = false; if(this.targetAnchor){ this._unmarkTargetAnchor(); @@ -504,8 +504,8 @@ var Source = declare("dojo.dnd.Source", Selector, { // e: Event // mouse event - // accept only the left mouse button - if(!mouse.isLeft(e)){ return false; } + // accept only the left mouse button, or the left finger + if(e.type != "touchstart" && !mouse.isLeft(e)){ return false; } if(!this.withHandles){ return true; } diff --git a/tests/dnd/dndDefault.css b/tests/dnd/dndDefault.css index d03323920b..624c1b9d35 100644 --- a/tests/dnd/dndDefault.css +++ b/tests/dnd/dndDefault.css @@ -25,6 +25,10 @@ .dojoDndItem { padding: 3px; + + /* Prevent magnifying-glass text selection icon to appear on mobile webkit as it causes a touchout event */ + -webkit-touch-callout: none; + -webkit-user-select: none; /* Disable selection/Copy of UIWebView */ } .dj_ff2 .dojoDndItem {