From ada51d1d0eac8a1c4448a664c42e8712bce9e650 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli <thomas@roundcube.net> Date: Sat, 19 Oct 2013 09:51:30 -0400 Subject: [PATCH] Merge branch 'master' of github.com:roundcube/roundcubemail --- program/js/list.js | 114 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 85 insertions(+), 29 deletions(-) diff --git a/program/js/list.js b/program/js/list.js index fbebc8a..cb69bc4 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -33,8 +33,9 @@ this.tagname = this.list ? this.list.nodeName.toLowerCase() : 'table'; this.thead; this.tbody; + this.fixed_header; this.frame = null; - this.rows = []; + this.rows = {}; this.selection = []; this.rowcount = 0; this.colcount = 0; @@ -49,7 +50,6 @@ this.keyboard = false; this.toggleselect = false; - this.dont_select = false; this.drag_active = false; this.col_drag_active = false; this.column_fixed = null; @@ -58,7 +58,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 @@ -85,7 +85,7 @@ } if (this.tbody) { - this.rows = []; + this.rows = {}; this.rowcount = 0; var r, len, rows = this.tbody.childNodes; @@ -121,17 +121,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 +160,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 +182,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 @@ -182,7 +239,7 @@ $(this.row_tagname() + ':not(.thead)', this.tbody).remove(); } - this.rows = []; + this.rows = {}; this.rowcount = 0; if (sel) @@ -351,14 +408,14 @@ var evtarget = rcube_event.get_target(e), tagname = evtarget.tagName.toLowerCase(); - if (this.dont_select || (evtarget && (tagname == 'input' || tagname == 'img'))) + if (evtarget && (tagname == 'input' || tagname == 'img' || (tagname != 'a' && evtarget.onclick))) return true; // accept right-clicks 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 +423,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'}); } @@ -397,12 +454,6 @@ if ((evtarget && (tagname == 'input' || tagname == 'img'))) return true; - // don't do anything (another action processed before) - if (this.dont_select) { - this.dont_select = false; - return false; - } - var dblclicked = now - this.rows[id].clicked < this.dblclick_time; // unselects currently selected row @@ -413,7 +464,7 @@ this.in_selection_before = false; // row was double clicked - if (this.rows && dblclicked && this.in_selection(id)) { + if (this.rowcount && dblclicked && this.in_selection(id)) { this.triggerEvent('dblclick'); now = 0; } @@ -451,8 +502,6 @@ evtarget = rcube_event.get_target(e), mod_key = rcube_event.get_modifier(e); - // Don't select this message - this.dont_select = true; // Don't treat double click on the expando as double click on the message. row.clicked = 0; @@ -494,6 +543,7 @@ new_row = new_row.nextSibling; } + this.resize(); this.triggerEvent('listupdate'); return false; }, @@ -542,6 +592,7 @@ new_row = new_row.nextSibling; } + this.resize(); this.triggerEvent('listupdate'); return false; }, @@ -585,6 +636,7 @@ new_row = new_row.nextSibling; } + this.resize(); this.triggerEvent('listupdate'); return false; }, @@ -623,6 +675,7 @@ new_row = new_row.nextSibling; } + this.resize(); this.triggerEvent('listupdate'); return false; }, @@ -641,7 +694,7 @@ */ get_next_row: function() { - if (!this.rows) + if (!this.rowcount) return false; var last_selected_row = this.rows[this.last_selected], @@ -655,7 +708,7 @@ get_prev_row: function() { - if (!this.rows) + if (!this.rowcount) return false; var last_selected_row = this.rows[this.last_selected], @@ -907,7 +960,7 @@ */ select_all: function(filter) { - if (!this.rows || !this.rows.length) + if (!this.rowcount) return false; // reset but remember selection first @@ -939,7 +992,7 @@ */ invert_selection: function() { - if (!this.rows || !this.rows.length) + if (!this.rowcount) return false; // remember old selection @@ -1202,7 +1255,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 +1361,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 +1584,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