From 8ef2f3c5cfa88398266179905c08d188c1082ccd Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Fri, 28 May 2010 06:52:20 -0400
Subject: [PATCH] Make drag&drop work on iPads

---
 program/js/list.js   |   44 ++++++++++++++++++++++++++++++++++++++++----
 program/js/common.js |    5 +++++
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/program/js/common.js b/program/js/common.js
index 3defb6f..4a2a41c 100644
--- a/program/js/common.js
+++ b/program/js/common.js
@@ -270,6 +270,11 @@
   e.cancelBubble = true;
   e.returnValue = false;
   return false;
+},
+
+touchevent: function(e)
+{
+  return { pageX:e.pageX, pageY:e.pageY, offsetX:e.pageX - e.target.offsetLeft, offsetY:e.pageY - e.target.offsetTop, target:e.target, istouch:true };
 }
 
 };
diff --git a/program/js/list.js b/program/js/list.js
index d7e00f1..a38890e 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -102,14 +102,28 @@
 {
   // make references in internal array and set event handlers
   if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)) {
-    var p = this;
+    var self = this;
     var uid = RegExp.$1;
     row.uid = uid;
     this.rows[uid] = {uid:uid, id:row.id, obj:row};
 
     // set eventhandlers to table row
-    row.onmousedown = function(e){ return p.drag_row(e, this.uid); };
-    row.onmouseup = function(e){ return p.click_row(e, this.uid); };
+    row.onmousedown = function(e){ return self.drag_row(e, this.uid); };
+    row.onmouseup = function(e){ return self.click_row(e, this.uid); };
+    
+    if (bw.iphone || bw.ipad) {
+      row.addEventListener('touchstart', function(e) {
+        if (e.touches.length == 1) {
+          if (!self.drag_row(rcube_event.touchevent(e.touches[0]), this.uid))
+            e.preventDefault();
+        }
+      }, false);
+      row.addEventListener('touchend', function(e) {
+        if (e.changedTouches.length == 1)
+          if (!self.click_row(rcube_event.touchevent(e.changedTouches[0]), this.uid))
+            e.preventDefault();
+      }, false);
+    }
 
     if (document.all)
       row.onselectstart = function() { return false; };
@@ -285,6 +299,10 @@
     this.drag_mouse_start = rcube_event.get_mouse_pos(e);
     rcube_event.add_listener({event:'mousemove', object:this, method:'drag_mouse_move'});
     rcube_event.add_listener({event:'mouseup', object:this, method:'drag_mouse_up'});
+    if (bw.iphone || bw.ipad) {
+      rcube_event.add_listener({event:'touchmove', object:this, method:'drag_mouse_move'});
+      rcube_event.add_listener({event:'touchend', object:this, method:'drag_mouse_up'});
+    }
 
     // enable dragging over iframes
     this.add_dragfix();
@@ -311,7 +329,7 @@
   if (this.dont_select) {
     this.dont_select = false;
     return false;
-    }
+  }
 
   var dblclicked = now - this.rows[id].clicked < this.dblclick_time;
 
@@ -1072,6 +1090,14 @@
  */
 drag_mouse_move: function(e)
 {
+  // convert touch event
+  if (e.type == 'touchmove') {
+    if (e.changedTouches.length == 1)
+      e = rcube_event.touchevent(e.changedTouches[0]);
+    else
+      return rcube_event.cancel(e);
+  }
+  
   if (this.drag_start) {
     // check mouse movement, of less than 3 pixels, don't start dragging
     var m = rcube_event.get_mouse_pos(e);
@@ -1159,6 +1185,11 @@
 drag_mouse_up: function(e)
 {
   document.onmousemove = null;
+  
+  if (e.type == 'touchend') {
+    if (e.changedTouches.length != 1)
+      return rcube_event.cancel(e);
+  }
 
   if (this.draglayer && this.draglayer.is(':visible')) {
     if (this.drag_start_pos)
@@ -1173,6 +1204,11 @@
 
   rcube_event.remove_listener({event:'mousemove', object:this, method:'drag_mouse_move'});
   rcube_event.remove_listener({event:'mouseup', object:this, method:'drag_mouse_up'});
+  
+  if (bw.iphone || bw.ipad) {
+    rcube_event.remove_listener({event:'touchmove', object:this, method:'drag_mouse_move'});
+    rcube_event.remove_listener({event:'touchend', object:this, method:'drag_mouse_up'});
+  }
 
   // remove temp divs
   this.del_dragfix();

--
Gitblit v1.9.1