From 88b4231d98593abb2f1a3d3b106a012905bc6b19 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Fri, 16 Aug 2013 06:03:57 -0400
Subject: [PATCH] Fix touch check when IE (7|8) doesn't specify the event object

---
 program/js/list.js |   87 ++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/program/js/list.js b/program/js/list.js
index fbebc8a..c2ad3f7 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -33,6 +33,7 @@
   this.tagname = this.list ? this.list.nodeName.toLowerCase() : 'table';
   this.thead;
   this.tbody;
+  this.fixed_header;
   this.frame = null;
   this.rows = [];
   this.selection = [];
@@ -58,7 +59,7 @@
   this.in_selection_before = false;
   this.focused = false;
   this.drag_mouse_start = null;
-  this.dblclick_time = 600;
+  this.dblclick_time = 500; // default value on MS Windows is 500
   this.row_init = function(){};  // @deprecated; use list.addEventListener('initrow') instead
 
   // overwrite default paramaters
@@ -121,17 +122,25 @@
     row.onmousedown = function(e){ return self.drag_row(e, this.uid); };
     row.onmouseup = function(e){ return self.click_row(e, this.uid); };
 
-    if (bw.mobile) {
+    if (bw.touch) {
       row.addEventListener('touchstart', function(e) {
         if (e.touches.length == 1) {
-          if (!self.drag_row(rcube_event.touchevent(e.touches[0]), this.uid))
-            e.preventDefault();
+          self.touchmoved = false;
+          self.drag_row(rcube_event.touchevent(e.touches[0]), this.uid)
         }
       }, false);
       row.addEventListener('touchend', function(e) {
-        if (e.changedTouches.length == 1)
-          if (!self.click_row(rcube_event.touchevent(e.changedTouches[0]), this.uid))
+        if (e.changedTouches.length == 1) {
+          if (!self.touchmoved && !self.click_row(rcube_event.touchevent(e.changedTouches[0]), this.uid))
             e.preventDefault();
+        }
+      }, false);
+      row.addEventListener('touchmove', function(e) {
+        if (e.changedTouches.length == 1) {
+          self.touchmoved = true;
+          if (self.drag_active)
+            e.preventDefault();
+        }
       }, false);
     }
 
@@ -152,6 +161,14 @@
   if (this.thead) {
     this.colcount = 0;
 
+    if (this.fixed_header) {  // copy (modified) fixed header back to the actual table
+      $(this.list.tHead).replaceWith($(this.fixed_header).find('thead').clone());
+      $(this.list.tHead).find('tr td').attr('style', '');  // remove fixed widths
+    }
+    else if (!bw.touch && this.list.className.indexOf('fixedheader') >= 0) {
+      this.init_fixed_header();
+    }
+
     var col, r, p = this;
     // add events for list columns moving
     if (this.column_movable && this.thead && this.thead.rows) {
@@ -166,6 +183,47 @@
   }
 },
 
+init_fixed_header: function()
+{
+  var clone = $(this.list.tHead).clone();
+
+  if (!this.fixed_header) {
+    this.fixed_header = $('<table>')
+      .attr('class', this.list.className + ' fixedcopy')
+      .css({ position:'fixed' })
+      .append(clone)
+      .append('<tbody></tbody>');
+    $(this.list).before(this.fixed_header);
+
+    var me = this;
+    $(window).resize(function(){ me.resize() });
+  }
+  else {
+    $(this.fixed_header).find('thead').replaceWith(clone);
+  }
+
+  this.thead = clone.get(0);
+  this.resize();
+},
+
+resize: function()
+{
+    if (!this.fixed_header)
+      return;
+
+    var column_widths = [];
+
+    // get column widths from original thead
+    $(this.tbody).parent().find('thead tr td').each(function(index) {
+      column_widths[index] = $(this).width();
+    });
+
+    // apply fixed widths to fixed table header
+    $(this.thead).parent().width($(this.tbody).parent().width());
+    $(this.thead).find('tr td').each(function(index) {
+      $(this).css('width', column_widths[index]);
+    });
+},
 
 /**
  * Remove all list rows
@@ -358,7 +416,7 @@
   if (rcube_event.get_button(e) == 2)
     return true;
 
-  this.in_selection_before = this.in_selection(id) ? id : false;
+  this.in_selection_before = e && e.istouch || this.in_selection(id) ? id : false;
 
   // selects currently unselected row
   if (!this.in_selection_before) {
@@ -366,12 +424,12 @@
     this.select_row(id, mod_key, false);
   }
 
-  if (this.draggable && this.selection.length) {
+  if (this.draggable && this.selection.length && this.in_selection(id)) {
     this.drag_start = true;
     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.mobile) {
+    if (bw.touch) {
       rcube_event.add_listener({event:'touchmove', object:this, method:'drag_mouse_move'});
       rcube_event.add_listener({event:'touchend', object:this, method:'drag_mouse_up'});
     }
@@ -494,6 +552,7 @@
     new_row = new_row.nextSibling;
   }
 
+  this.resize();
   this.triggerEvent('listupdate');
   return false;
 },
@@ -542,6 +601,7 @@
     new_row = new_row.nextSibling;
   }
 
+  this.resize();
   this.triggerEvent('listupdate');
   return false;
 },
@@ -585,6 +645,7 @@
     new_row = new_row.nextSibling;
   }
 
+  this.resize();
   this.triggerEvent('listupdate');
   return false;
 },
@@ -623,6 +684,7 @@
     new_row = new_row.nextSibling;
   }
 
+  this.resize();
   this.triggerEvent('listupdate');
   return false;
 },
@@ -1202,7 +1264,7 @@
 {
   // convert touch event
   if (e.type == 'touchmove') {
-    if (e.changedTouches.length == 1)
+    if (e.touches.length == 1 && e.changedTouches.length == 1)
       e = rcube_event.touchevent(e.changedTouches[0]);
     else
       return rcube_event.cancel(e);
@@ -1308,7 +1370,7 @@
   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.mobile) {
+  if (bw.touch) {
     rcube_event.remove_listener({event:'touchmove', object:this, method:'drag_mouse_move'});
     rcube_event.remove_listener({event:'touchend', object:this, method:'drag_mouse_up'});
   }
@@ -1531,6 +1593,9 @@
   else if (this.subject_col > from && to >= this.subject_col)
     this.subject_col--;
 
+  if (this.fixed_header)
+    this.init_header();
+
   this.triggerEvent('column_replace');
 }
 

--
Gitblit v1.9.1