| | |
| | | this.rows = []; |
| | | this.rowcount = 0; |
| | | |
| | | var row, r; |
| | | var r, len, rows = this.list.tBodies[0].rows; |
| | | |
| | | for (r=0; r<this.list.tBodies[0].rows.length; r++) { |
| | | row = this.list.tBodies[0].rows[r]; |
| | | this.init_row(row); |
| | | for (r=0, len=rows.length; r<len; r++) { |
| | | this.init_row(rows[r]); |
| | | this.rowcount++; |
| | | } |
| | | |
| | |
| | | { |
| | | // 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; }; |
| | |
| | | clear: function(sel) |
| | | { |
| | | var tbody = document.createElement('tbody'); |
| | | |
| | | this.list.insertBefore(tbody, this.list.tBodies[0]); |
| | | this.list.removeChild(this.list.tBodies[1]); |
| | | this.rows = []; |
| | |
| | | if (sel_next) |
| | | this.select_next(); |
| | | |
| | | this.rows[uid] = null; |
| | | delete this.rows[uid]; |
| | | this.rowcount--; |
| | | }, |
| | | |
| | |
| | | */ |
| | | insert_row: function(row, attop) |
| | | { |
| | | if (this.background) |
| | | var tbody = this.background; |
| | | else |
| | | var tbody = this.list.tBodies[0]; |
| | | var tbody = this.list.tBodies[0]; |
| | | |
| | | if (attop && tbody.rows.length) |
| | | tbody.insertBefore(row, tbody.firstChild); |
| | |
| | | */ |
| | | focus: function(e) |
| | | { |
| | | var id; |
| | | this.focused = true; |
| | | for (var n=0; n<this.selection.length; n++) { |
| | | for (var n in this.selection) { |
| | | id = this.selection[n]; |
| | | if (this.rows[id] && this.rows[id].obj) { |
| | | $(this.rows[id].obj).addClass('selected').removeClass('unfocused'); |
| | |
| | | { |
| | | var id; |
| | | this.focused = false; |
| | | for (var n=0; n<this.selection.length; n++) { |
| | | for (var n in this.selection) { |
| | | id = this.selection[n]; |
| | | if (this.rows[id] && this.rows[id].obj) { |
| | | $(this.rows[id].obj).removeClass('selected').addClass('unfocused'); |
| | |
| | | drag_row: function(e, id) |
| | | { |
| | | // don't do anything (another action processed before) |
| | | var evtarget = rcube_event.get_target(e); |
| | | var tagname = evtarget.tagName.toLowerCase(); |
| | | var evtarget = rcube_event.get_target(e), |
| | | tagname = evtarget.tagName.toLowerCase(); |
| | | |
| | | if (this.dont_select || (evtarget && (tagname == 'input' || tagname == 'img'))) |
| | | return 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.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(); |
| | |
| | | */ |
| | | click_row: function(e, id) |
| | | { |
| | | var now = new Date().getTime(); |
| | | var mod_key = rcube_event.get_modifier(e); |
| | | var evtarget = rcube_event.get_target(e); |
| | | var tagname = evtarget.tagName.toLowerCase(); |
| | | var now = new Date().getTime(), |
| | | mod_key = rcube_event.get_modifier(e), |
| | | evtarget = rcube_event.get_target(e), |
| | | tagname = evtarget.tagName.toLowerCase(); |
| | | |
| | | if ((evtarget && (tagname == 'input' || tagname == 'img'))) |
| | | return true; |
| | |
| | | if (this.dont_select) { |
| | | this.dont_select = false; |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | var dblclicked = now - this.rows[id].clicked < this.dblclick_time; |
| | | |
| | |
| | | |
| | | expand_row: function(e, id) |
| | | { |
| | | var row = this.rows[id]; |
| | | var evtarget = rcube_event.get_target(e); |
| | | var mod_key = rcube_event.get_modifier(e); |
| | | var row = this.rows[id], |
| | | evtarget = rcube_event.get_target(e), |
| | | mod_key = rcube_event.get_modifier(e); |
| | | |
| | | // Don't select this message |
| | | this.dont_select = true; |
| | |
| | | row.clicked = 0; |
| | | |
| | | if (row.expanded) { |
| | | evtarget.className = "collapsed"; |
| | | evtarget.className = 'collapsed'; |
| | | if (mod_key == CONTROL_KEY || this.multiexpand) |
| | | this.collapse_all(row); |
| | | else |
| | | this.collapse(row); |
| | | } |
| | | else { |
| | | evtarget.className = "expanded"; |
| | | evtarget.className = 'expanded'; |
| | | if (mod_key == CONTROL_KEY || this.multiexpand) |
| | | this.expand_all(row); |
| | | else |
| | |
| | | var r = this.rows[new_row.uid]; |
| | | if (r && r.depth <= depth) |
| | | break; |
| | | $(new_row).hide(); |
| | | r.expanded = false; |
| | | this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded }); |
| | | $(new_row).css('display', 'none'); |
| | | if (r.expanded) { |
| | | r.expanded = false; |
| | | this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded }); |
| | | } |
| | | } |
| | | new_row = new_row.nextSibling; |
| | | } |
| | |
| | | if (p && p.expanded) { |
| | | if ((row && p == row) || last_expanded_parent_depth >= p.depth - 1) { |
| | | last_expanded_parent_depth = p.depth; |
| | | $(new_row).show(); |
| | | $(new_row).css('display', ''); |
| | | r.expanded = true; |
| | | this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded }); |
| | | } |
| | |
| | | |
| | | collapse_all: function(row) |
| | | { |
| | | var depth, new_row; |
| | | var r; |
| | | var depth, new_row, r; |
| | | |
| | | if (row) { |
| | | row.expanded = false; |
| | |
| | | |
| | | // don't collapse sub-root tree in multiexpand mode |
| | | if (depth && this.multiexpand) |
| | | return false; |
| | | return false; |
| | | } |
| | | else { |
| | | var tbody = this.list.tBodies[0]; |
| | | new_row = tbody.firstChild; |
| | | new_row = this.list.tBodies[0].firstChild; |
| | | depth = 0; |
| | | } |
| | | |
| | | while (new_row) { |
| | | if (new_row.nodeType == 1) { |
| | | var r = this.rows[new_row.uid]; |
| | | if (r) { |
| | | if (r = this.rows[new_row.uid]) { |
| | | if (row && (!r.depth || r.depth <= depth)) |
| | | break; |
| | | |
| | | if (row || r.depth) |
| | | $(new_row).hide(); |
| | | if (r.has_children) { |
| | | $(new_row).css('display', 'none'); |
| | | if (r.has_children && r.expanded) { |
| | | r.expanded = false; |
| | | this.update_expando(r.uid); |
| | | this.update_expando(r.uid, false); |
| | | this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded }); |
| | | } |
| | | } |
| | |
| | | |
| | | expand_all: function(row) |
| | | { |
| | | var depth, new_row; |
| | | var r; |
| | | var depth, new_row, r; |
| | | |
| | | if (row) { |
| | | row.expanded = true; |
| | |
| | | this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded }); |
| | | } |
| | | else { |
| | | var tbody = this.list.tBodies[0]; |
| | | new_row = tbody.firstChild; |
| | | new_row = this.list.tBodies[0].firstChild; |
| | | depth = 0; |
| | | } |
| | | |
| | | while (new_row) { |
| | | if (new_row.nodeType == 1) { |
| | | var r = this.rows[new_row.uid]; |
| | | if (r) { |
| | | if (r = this.rows[new_row.uid]) { |
| | | if (row && r.depth <= depth) |
| | | break; |
| | | |
| | | $(new_row).show(); |
| | | if (r.has_children) { |
| | | $(new_row).css('display', ''); |
| | | if (r.has_children && !r.expanded) { |
| | | r.expanded = true; |
| | | this.update_expando(r.uid, true); |
| | | this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded }); |
| | |
| | | if (!this.rows) |
| | | return false; |
| | | |
| | | var last_selected_row = this.rows[this.last_selected]; |
| | | var new_row = last_selected_row ? last_selected_row.obj.nextSibling : null; |
| | | var last_selected_row = this.rows[this.last_selected], |
| | | new_row = last_selected_row ? last_selected_row.obj.nextSibling : null; |
| | | |
| | | while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none')) |
| | | new_row = new_row.nextSibling; |
| | | |
| | |
| | | if (!this.rows) |
| | | return false; |
| | | |
| | | var last_selected_row = this.rows[this.last_selected]; |
| | | var new_row = last_selected_row ? last_selected_row.obj.previousSibling : null; |
| | | var last_selected_row = this.rows[this.last_selected], |
| | | new_row = last_selected_row ? last_selected_row.obj.previousSibling : null; |
| | | |
| | | while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none')) |
| | | new_row = new_row.previousSibling; |
| | | |
| | |
| | | get_first_row: function() |
| | | { |
| | | if (this.rowcount) { |
| | | var rows = this.list.tBodies[0].rows; |
| | | var i, len, rows = this.list.tBodies[0].rows; |
| | | |
| | | for(var i=0; i<rows.length-1; i++) |
| | | if(rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null) |
| | | |
| | | return RegExp.$1; |
| | | for (i=0, len=rows.length-1; i<len; i++) |
| | | if (rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null) |
| | | return RegExp.$1; |
| | | } |
| | | |
| | | return null; |
| | |
| | | get_last_row: function() |
| | | { |
| | | if (this.rowcount) { |
| | | var rows = this.list.tBodies[0].rows; |
| | | var i, rows = this.list.tBodies[0].rows; |
| | | |
| | | for(var i=rows.length-1; i>=0; i--) |
| | | if(rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null) |
| | | |
| | | return RegExp.$1; |
| | | for (i=rows.length-1; i>=0; i--) |
| | | if (rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null) |
| | | return RegExp.$1; |
| | | } |
| | | |
| | | return null; |
| | |
| | | if (!this.rows[this.shift_start] || !this.selection.length) |
| | | this.shift_start = id; |
| | | |
| | | var from_rowIndex = this.rows[this.shift_start].obj.rowIndex; |
| | | var to_rowIndex = this.rows[id].obj.rowIndex; |
| | | |
| | | var i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex); |
| | | var j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex); |
| | | var from_rowIndex = this.rows[this.shift_start].obj.rowIndex, |
| | | to_rowIndex = this.rows[id].obj.rowIndex, |
| | | i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex), |
| | | j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex); |
| | | |
| | | // iterate through the entire message list |
| | | for (var n in this.rows) { |
| | | if ((this.rows[n].obj.rowIndex >= i) && (this.rows[n].obj.rowIndex <= j)) { |
| | | if (this.rows[n].obj.rowIndex >= i && this.rows[n].obj.rowIndex <= j) { |
| | | if (!this.in_selection(n)) { |
| | | this.highlight_row(n, true); |
| | | } |
| | |
| | | this.selection = []; |
| | | |
| | | for (var n in this.rows) { |
| | | if (!filter || (this.rows[n] && this.rows[n][filter] == true)) { |
| | | if (!filter || this.rows[n][filter] == true) { |
| | | this.last_selected = n; |
| | | this.highlight_row(n, true); |
| | | } |
| | | else if (this.rows[n]) { |
| | | else { |
| | | $(this.rows[n].obj).removeClass('selected').removeClass('unfocused'); |
| | | } |
| | | } |
| | |
| | | |
| | | // one row |
| | | if (id) { |
| | | for (var n=0; n<this.selection.length; n++) |
| | | for (var n=0 in this.selection) |
| | | if (this.selection[n] == id) { |
| | | this.selection.splice(n,1); |
| | | break; |
| | |
| | | } |
| | | // all rows |
| | | else { |
| | | for (var n=0; n<this.selection.length; n++) |
| | | for (var n in this.selection) |
| | | if (this.rows[this.selection[n]]) { |
| | | $(this.rows[this.selection[n]].obj).removeClass('selected').removeClass('unfocused'); |
| | | } |
| | |
| | | else |
| | | this.collapse(selected_row); |
| | | |
| | | var expando = document.getElementById('rcmexpando' + selected_row.uid); |
| | | if (expando) |
| | | expando.className = selected_row.expanded?'expanded':'collapsed'; |
| | | this.update_expando(selected_row.uid, selected_row.expanded); |
| | | |
| | | return false; |
| | | }, |
| | |
| | | */ |
| | | 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); |
| | |
| | | .appendTo(document.body); |
| | | |
| | | // also select childs of (collapsed) threads for dragging |
| | | var selection = $.merge([], this.selection); |
| | | var depth, row, uid, r; |
| | | for (var n=0; n < selection.length; n++) { |
| | | var n, uid, selection = $.merge([], this.selection); |
| | | for (n in selection) { |
| | | uid = selection[n]; |
| | | if (this.rows[uid].has_children && !this.rows[uid].expanded) |
| | | this.select_childs(uid); |
| | |
| | | // get subjects of selected messages |
| | | var names = ''; |
| | | var c, i, subject, obj; |
| | | for(var n=0; n<this.selection.length; n++) { |
| | | for (var n=0; n<this.selection.length; n++) { |
| | | // only show 12 lines |
| | | if (n>12) { |
| | | names += '...'; |
| | |
| | | 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) |
| | |
| | | |
| | | 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(); |
| | |
| | | }) |
| | | .css($(this).offset()) |
| | | .appendTo(document.body); |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | |
| | |
| | | this.subject_col = to > from ? to - 1 : to; |
| | | |
| | | this.triggerEvent('column_replace'); |
| | | }, |
| | | |
| | | |
| | | /** |
| | | * Creating the list in background |
| | | */ |
| | | set_background_mode: function(flag) |
| | | { |
| | | if (flag) { |
| | | this.background = document.createElement('tbody'); |
| | | } else if (this.background) { |
| | | this.list.replaceChild(this.background, this.list.tBodies[0]); |
| | | this.background = null; |
| | | } |
| | | } |
| | | |
| | | }; |