-/*
- +-----------------------------------------------------------------------+
- | RoundCube List Widget |
- | |
- | This file is part of the RoundCube Webmail client |
- | Copyright (C) 2006-2009, RoundCube Dev, - Switzerland |
- | Licensed under the GNU GPL |
- | |
- +-----------------------------------------------------------------------+
- | Authors: Thomas Bruederli <roundcube@gmail.com> |
- | Charles McNulty <charles@charlesmcnulty.com> |
- +-----------------------------------------------------------------------+
- | Requires: common.js |
- +-----------------------------------------------------------------------+
-
- $Id: list.js 2761 2009-07-17 08:46:59Z alec $
-*/
-
-
-/**
- * RoundCube List Widget class
- * @contructor
- */
-function rcube_list_widget(list, p)
- {
- // static contants
- this.ENTER_KEY = 13;
- this.DELETE_KEY = 46;
- this.BACKSPACE_KEY = 8;
-
- this.list = list ? list : null;
- this.frame = null;
- this.rows = [];
- this.selection = [];
- this.rowcount = 0;
-
- this.subject_col = -1;
- this.shiftkey = false;
- this.multiselect = false;
- this.multi_selecting = false;
- this.draggable = false;
- this.keyboard = false;
- this.toggleselect = false;
-
- this.dont_select = false;
- this.drag_active = false;
- this.last_selected = 0;
- this.shift_start = 0;
- this.in_selection_before = false;
- this.focused = false;
- this.drag_mouse_start = null;
- this.dblclick_time = 600;
- this.row_init = function(){};
-
- // overwrite default paramaters
- if (p && typeof(p)=='object')
- for (var n in p)
- this[n] = p[n];
- }
-
-
-rcube_list_widget.prototype = {
-
-
-/**
- * get all message rows from HTML table and init each row
- */
-init: function()
-{
- if (this.list && this.list.tBodies[0])
- {
- this.rows = new Array();
- this.rowcount = 0;
-
- var row;
- for(var r=0; r<this.list.tBodies[0].childNodes.length; r++)
- {
- row = this.list.tBodies[0].childNodes[r];
- while (row && (row.nodeType != 1 || row.style.display == 'none'))
- {
- row = row.nextSibling;
- r++;
- }
-
- this.init_row(row);
- this.rowcount++;
- }
-
- this.frame = this.list.parentNode;
-
- // set body events
- if (this.keyboard) {
- rcube_event.add_listener({element:document, event:bw.opera?'keypress':'keydown', object:this, method:'key_press'});
- rcube_event.add_listener({element:document, event:'keydown', object:this, method:'key_down'});
- }
- }
-},
-
-
-/**
- * Init list row and set mouse events on it
- */
-init_row: function(row)
-{
- // make references in internal array and set event handlers
- if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i))
- {
- var p = this;
- var uid = RegExp.$1;
- row.uid = uid;
- this.rows[uid] = {uid:uid, id:row.id, obj:row, classname:row.className};
-
- // 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); };
-
- if (document.all)
- row.onselectstart = function() { return false; };
-
- this.row_init(this.rows[uid]);
- }
-},
-
-
-/**
- * Remove all list rows
- */
-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 = new Array();
- this.rowcount = 0;
-
- if (sel) this.clear_selection();
-},
-
-
-/**
- * 'remove' message row from list (just hide it)
- */
-remove_row: function(uid, sel_next)
-{
- if (this.rows[uid].obj)
- this.rows[uid].obj.style.display = 'none';
-
- if (sel_next)
- this.select_next();
-
- this.rows[uid] = null;
- this.rowcount--;
-},
-
-
-/**
- * Add row to the list and initialize it
- */
-insert_row: function(row, attop)
-{
- if (this.background)
- var tbody = this.background;
- else
- var tbody = this.list.tBodies[0];
-
- if (attop && tbody.rows.length)
- tbody.insertBefore(row, tbody.firstChild);
- else
- tbody.appendChild(row);
-
- this.init_row(row);
- this.rowcount++;
-},
-
-
-
-/**
- * Set focus to the list
- */
-focus: function(e)
-{
- this.focused = true;
- for (var n=0; n<this.selection.length; n++)
- {
- id = this.selection[n];
- if (this.rows[id] && this.rows[id].obj) {
- $(this.rows[id].obj).addClass('selected').removeClass('unfocused');
- }
- }
-
- if (e || (e = window.event))
- rcube_event.cancel(e);
-},
-
-
-/**
- * remove focus from the list
- */
-blur: function()
-{
- var id;
- this.focused = false;
- for (var n=0; n<this.selection.length; n++)
- {
- id = this.selection[n];
- if (this.rows[id] && this.rows[id].obj) {
- $(this.rows[id].obj).removeClass('selected').addClass('unfocused');
- }
- }
-},
-
-
-/**
- * onmousedown-handler of message list row
- */
-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();
- if (this.dont_select || (evtarget && (tagname == 'input' || tagname == 'img')))
- return true;
-
- // accept right-clicks
- if (rcube_event.get_button(e) == 2)
- return true;
-
- this.in_selection_before = this.in_selection(id) ? id : false;
-
- // selects currently unselected row
- if (!this.in_selection_before)
- {
- var mod_key = rcube_event.get_modifier(e);
- this.select_row(id, mod_key, false);
- }
-
- if (this.draggable && this.selection.length)
- {
- this.drag_start = true;
- this.drag_mouse_start = rcube_event.get_mouse_pos(e);
- rcube_event.add_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
- rcube_event.add_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
-
- // add listener for iframes
- var iframes = document.getElementsByTagName('iframe');
- this.iframe_events = Object();
- for (var n in iframes)
- {
- var iframedoc = null;
- if (iframes[n].contentDocument)
- iframedoc = iframes[n].contentDocument;
- else if (iframes[n].contentWindow)
- iframedoc = iframes[n].contentWindow.document;
- else if (iframes[n].document)
- iframedoc = iframes[n].document;
-
- if (iframedoc)
- {
- var list = this;
- var pos = $('#'+iframes[n].id).offset();
- this.iframe_events[n] = function(e) { e._offset = pos; return list.drag_mouse_move(e); }
-
- if (iframedoc.addEventListener)
- iframedoc.addEventListener('mousemove', this.iframe_events[n], false);
- else if (iframes[n].attachEvent)
- iframedoc.attachEvent('onmousemove', this.iframe_events[n]);
- else
- iframedoc['onmousemove'] = this.iframe_events[n];
-
- rcube_event.add_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
- }
- }
- }
-
- return false;
-},
-
-
-/**
- * onmouseup-handler of message list row
- */
-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();
-
- 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
- if (!this.drag_active && this.in_selection_before == id && !dblclicked)
- this.select_row(id, mod_key, false);
-
- this.drag_start = false;
- this.in_selection_before = false;
-
- // row was double clicked
- if (this.rows && dblclicked && this.in_selection(id))
- this.triggerEvent('dblclick');
- else
- this.triggerEvent('click');
-
- if (!this.drag_active)
- rcube_event.cancel(e);
-
- this.rows[id].clicked = now;
- return false;
-},
-
-
-/**
- * get next/previous/last rows that are not hidden
- */
-get_next_row: function()
-{
- 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;
- while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
- new_row = new_row.nextSibling;
-
- return new_row;
-},
-
-get_prev_row: function()
-{
- 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;
- while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
- new_row = new_row.previousSibling;
-
- return new_row;
-},
-
-get_last_row: function()
-{
- if (this.rowcount)
- {
- var 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;
- }
-
- return null;
-},
-
-
-/**
- * selects or unselects the proper row depending on the modifier key pressed
- */
-select_row: function(id, mod_key, with_mouse)
-{
- var select_before = this.selection.join(',');
- if (!this.multiselect)
- mod_key = 0;
-
- if (!this.shift_start)
- this.shift_start = id
-
- if (!mod_key)
- {
- this.shift_start = id;
- this.highlight_row(id, false);
- this.multi_selecting = false;
- }
- else
- {
- switch (mod_key)
- {
- case SHIFT_KEY:
- this.shift_select(id, false);
- break;
-
- case CONTROL_KEY:
- if (!with_mouse)
- this.highlight_row(id, true);
- break;
-
- case CONTROL_SHIFT_KEY:
- this.shift_select(id, true);
- break;
-
- default:
- this.highlight_row(id, false);
- break;
- }
- this.multi_selecting = true;
- }
-
- // trigger event if selection changed
- if (this.selection.join(',') != select_before)
- this.triggerEvent('select');
-
- if (this.last_selected != 0 && this.rows[this.last_selected])
- $(this.rows[this.last_selected].obj).removeClass('focused');
-
- // unselect if toggleselect is active and the same row was clicked again
- if (this.toggleselect && this.last_selected == id)
- {
- this.clear_selection();
- id = null;
- }
- else
- $(this.rows[id].obj).addClass('focused');
-
- if (!this.selection.length)
- this.shift_start = null;
-
- this.last_selected = id;
-},
-
-
-/**
- * Alias method for select_row
- */
-select: function(id)
-{
- this.select_row(id, false);
- this.scrollto(id);
-},
-
-
-/**
- * Select row next to the last selected one.
- * Either below or above.
- */
-select_next: function()
-{
- var next_row = this.get_next_row();
- var prev_row = this.get_prev_row();
- var new_row = (next_row) ? next_row : prev_row;
- if (new_row)
- this.select_row(new_row.uid, false, false);
-},
-
-
-/**
- * Perform selection when shift key is pressed
- */
-shift_select: function(id, control)
-{
- 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);
-
- // 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.in_selection(n))
- this.highlight_row(n, true);
- }
- else
- {
- if (this.in_selection(n) && !control)
- this.highlight_row(n, true);
- }
- }
-},
-
-
-/**
- * Check if given id is part of the current selection
- */
-in_selection: function(id)
-{
- for(var n in this.selection)
- if (this.selection[n]==id)
- return true;
-
- return false;
-},
-
-
-/**
- * Select each row in list
- */
-select_all: function(filter)
-{
- if (!this.rows || !this.rows.length)
- return false;
-
- // reset but remember selection first
- var select_before = this.selection.join(',');
- this.selection = new Array();
-
- for (var n in this.rows)
- {
- if (!filter || (this.rows[n] && this.rows[n][filter] == true))
- {
- this.last_selected = n;
- this.highlight_row(n, true);
- }
- else if (this.rows[n])
- {
- $(this.rows[n].obj).removeClass('selected').removeClass('unfocused');
- }
- }
-
- // trigger event if selection changed
- if (this.selection.join(',') != select_before)
- this.triggerEvent('select');
-
- this.focus();
-
- return true;
-},
-
-
-/**
- * Invert selection
- */
-invert_selection: function()
-{
- if (!this.rows || !this.rows.length)
- return false;
-
- // remember old selection
- var select_before = this.selection.join(',');
-
- for (var n in this.rows)
- this.highlight_row(n, true);
-
- // trigger event if selection changed
- if (this.selection.join(',') != select_before)
- this.triggerEvent('select');
-
- this.focus();
-
- return true;
-},
-
-
-/**
- * Unselect selected row(s)
- */
-clear_selection: function(id)
-{
- var num_select = this.selection.length;
-
- // one row
- if (id)
- {
- for (var n=0; n<this.selection.length; n++)
- if (this.selection[n] == id) {
- this.selection.splice(n,1);
- break;
- }
- }
- // all rows
- else
- {
- for (var n=0; n<this.selection.length; n++)
- if (this.rows[this.selection[n]]) {
- $(this.rows[this.selection[n]].obj).removeClass('selected').removeClass('unfocused');
- }
-
- this.selection = new Array();
- }
-
- if (num_select && !this.selection.length)
- this.triggerEvent('select');
-},
-
-
-/**
- * Getter for the selection array
- */
-get_selection: function()
-{
- return this.selection;
-},
-
-
-/**
- * Return the ID if only one row is selected
- */
-get_single_selection: function()
-{
- if (this.selection.length == 1)
- return this.selection[0];
- else
- return null;
-},
-
-
-/**
- * Highlight/unhighlight a row
- */
-highlight_row: function(id, multiple)
-{
- if (this.rows[id] && !multiple)
- {
- if (this.selection.length > 1 || !this.in_selection(id))
- {
- this.clear_selection();
- this.selection[0] = id;
- $(this.rows[id].obj).addClass('selected');
- }
- }
- else if (this.rows[id])
- {
- if (!this.in_selection(id)) // select row
- {
- this.selection[this.selection.length] = id;
- $(this.rows[id].obj).addClass('selected');
- }
- else // unselect row
- {
- var p = find_in_array(id, this.selection);
- var a_pre = this.selection.slice(0, p);
- var a_post = this.selection.slice(p+1, this.selection.length);
- this.selection = a_pre.concat(a_post);
- $(this.rows[id].obj).removeClass('selected').removeClass('unfocused');
- }
- }
-},
-
-
-/**
- * Handler for keyboard events
- */
-key_press: function(e)
-{
- if (this.focused != true)
- return true;
-
- var keyCode = rcube_event.get_keycode(e);
- var mod_key = rcube_event.get_modifier(e);
-
- switch (keyCode)
- {
- case 40:
- case 38:
- case 63233: // "down", in safari keypress
- case 63232: // "up", in safari keypress
- // Stop propagation so that the browser doesn't scroll
- rcube_event.cancel(e);
- return this.use_arrow_key(keyCode, mod_key);
- default:
- this.shiftkey = e.shiftKey;
- this.key_pressed = keyCode;
- this.triggerEvent('keypress');
-
- if (this.key_pressed == this.BACKSPACE_KEY)
- return rcube_event.cancel(e);
- }
-
- return true;
-},
-
-/**
- * Handler for keydown events
- */
-key_down: function(e)
-{
- switch (rcube_event.get_keycode(e))
- {
- case 27:
- if (this.drag_active)
- return this.drag_mouse_up(e);
-
- case 40:
- case 38:
- case 63233:
- case 63232:
- if (!rcube_event.get_modifier(e) && this.focused)
- return rcube_event.cancel(e);
-
- default:
- }
-
- return true;
-},
-
-
-/**
- * Special handling method for arrow keys
- */
-use_arrow_key: function(keyCode, mod_key)
-{
- var new_row;
- // Safari uses the nonstandard keycodes 63232/63233 for up/down, if we're
- // using the keypress event (but not the keydown or keyup event).
- if (keyCode == 40 || keyCode == 63233) // down arrow key pressed
- new_row = this.get_next_row();
- else if (keyCode == 38 || keyCode == 63232) // up arrow key pressed
- new_row = this.get_prev_row();
-
- if (new_row)
- {
- this.select_row(new_row.uid, mod_key, true);
- this.scrollto(new_row.uid);
- }
-
- return false;
-},
-
-
-/**
- * Try to scroll the list to make the specified row visible
- */
-scrollto: function(id)
-{
- var row = this.rows[id].obj;
- if (row && this.frame)
- {
- var scroll_to = Number(row.offsetTop);
-
- if (scroll_to < Number(this.frame.scrollTop))
- this.frame.scrollTop = scroll_to;
- else if (scroll_to + Number(row.offsetHeight) > Number(this.frame.scrollTop) + Number(this.frame.offsetHeight))
- this.frame.scrollTop = (scroll_to + Number(row.offsetHeight)) - Number(this.frame.offsetHeight);
- }
-},
-
-
-/**
- * Handler for mouse move events
- */
-drag_mouse_move: function(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);
-
- if (!this.drag_mouse_start || (Math.abs(m.x - this.drag_mouse_start.x) < 3 && Math.abs(m.y - this.drag_mouse_start.y) < 3))
- return false;
-
- if (!this.draglayer)
- this.draglayer = $('<div>').attr('id', 'rcmdraglayer').css({ position:'absolute', display:'none', 'z-index':2000 }).appendTo(document.body);
-
- // get subjects of selectedd messages
- var names = '';
- var c, i, node, subject, obj;
- for(var n=0; n<this.selection.length; n++)
- {
- if (n>12) // only show 12 lines
- {
- names += '...';
- break;
- }
-
- if (this.rows[this.selection[n]].obj)
- {
- obj = this.rows[this.selection[n]].obj;
- subject = '';
-
- for(c=0, i=0; i<obj.childNodes.length; i++)
- {
- if (obj.childNodes[i].nodeName == 'TD')
- {
- if (((node = obj.childNodes[i].firstChild) && (node.nodeType==3 || node.nodeName=='A')) &&
- (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == c)))
- {
- if (n == 0) {
- if (node.nodeType == 3)
- this.drag_start_pos = $(obj.childNodes[i]).offset();
- else
- this.drag_start_pos = $(node).offset();
- }
- subject = node.nodeType==3 ? node.data : node.innerHTML;
- // remove leading spaces
- subject = subject.replace(/^\s+/i, '');
- // truncate line to 50 characters
- names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />';
- break;
- }
- c++;
- }
- }
- }
- }
-
- this.draglayer.html(names);
- this.draglayer.show();
-
- this.drag_active = true;
- this.triggerEvent('dragstart');
- }
-
- if (this.drag_active && this.draglayer)
- {
- var pos = rcube_event.get_mouse_pos(e);
- this.draglayer.css({ left:(pos.x+20)+'px', top:(pos.y-5 + (bw.ie ? document.documentElement.scrollTop : 0))+'px' });
- this.triggerEvent('dragmove', e?e:window.event);
- }
-
- this.drag_start = false;
-
- return false;
-},
-
-
-/**
- * Handler for mouse up events
- */
-drag_mouse_up: function(e)
-{
- document.onmousemove = null;
-
- if (this.draglayer && this.draglayer.is(':visible')) {
- if (this.drag_start_pos)
- this.draglayer.animate(this.drag_start_pos, 300, 'swing').hide(20);
- else
- this.draglayer.hide();
- }
-
- this.drag_active = false;
- this.triggerEvent('dragend');
-
- rcube_event.remove_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
- rcube_event.remove_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
-
- var iframes = document.getElementsByTagName('iframe');
- for (var n in iframes) {
- var iframedoc;
-
- if (iframes[n].contentDocument)
- iframedoc = iframes[n].contentDocument;
- else if (iframes[n].contentWindow)
- iframedoc = iframes[n].contentWindow.document;
- else if (iframes[n].document)
- iframedoc = iframes[n].document;
-
- if (iframedoc) {
- if (this.iframe_events[n]) {
- if (iframedoc.removeEventListener)
- iframedoc.removeEventListener('mousemove', this.iframe_events[n], false);
- else if (iframedoc.detachEvent)
- iframedoc.detachEvent('onmousemove', this.iframe_events[n]);
- else
- iframedoc['onmousemove'] = null;
- }
- rcube_event.remove_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
- }
- }
-
- return rcube_event.cancel(e);
-},
-
-
-/**
- * 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;
- }
-}
-
-};
-
-rcube_list_widget.prototype.addEventListener = rcube_event_engine.prototype.addEventListener;
-rcube_list_widget.prototype.removeEventListener = rcube_event_engine.prototype.removeEventListener;
-rcube_list_widget.prototype.triggerEvent = rcube_event_engine.prototype.triggerEvent;
+function rcube_list_widget(a,b){this.ENTER_KEY=13;this.DELETE_KEY=46;this.BACKSPACE_KEY=8;this.list=a?a:null;this.frame=null;this.rows=[];this.selection=[];this.colcount=this.rowcount=0;this.subject_col=-1;this.col_drag_active=this.drag_active=this.dont_select=this.toggleselect=this.keyboard=this.column_movable=this.draggable=this.multi_selecting=this.multiexpand=this.multiselect=this.shiftkey=false;this.column_fixed=null;this.shift_start=this.last_selected=0;this.focused=this.in_selection_before=
+false;this.drag_mouse_start=null;this.dblclick_time=600;this.row_init=function(){};if(b&&typeof b=="object")for(var c in b)this[c]=b[c]}
+rcube_list_widget.prototype={init:function(){if(this.list&&this.list.tBodies[0]){this.rows=[];this.rowcount=0;var a,b,c=this.list.tBodies[0].rows;a=0;for(b=c.length;a<b;a++){this.init_row(c[a]);this.rowcount++}this.init_header();this.frame=this.list.parentNode;if(this.keyboard){rcube_event.add_listener({event:bw.opera?"keypress":"keydown",object:this,method:"key_press"});rcube_event.add_listener({event:"keydown",object:this,method:"key_down"})}}},init_row:function(a){if(a&&String(a.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)){var b=
+this,c=RegExp.$1;a.uid=c;this.rows[c]={uid:c,id:a.id,obj:a};a.onmousedown=function(d){return b.drag_row(d,this.uid)};a.onmouseup=function(d){return b.click_row(d,this.uid)};if(bw.iphone||bw.ipad){a.addEventListener("touchstart",function(d){if(d.touches.length==1)b.drag_row(rcube_event.touchevent(d.touches[0]),this.uid)||d.preventDefault()},false);a.addEventListener("touchend",function(d){if(d.changedTouches.length==1)b.click_row(rcube_event.touchevent(d.changedTouches[0]),this.uid)||d.preventDefault()},
+false)}if(document.all)a.onselectstart=function(){return false};this.row_init(this.rows[c])}},init_header:function(){if(this.list&&this.list.tHead){this.colcount=0;var a,b,c=this;if(this.column_movable&&this.list.tHead&&this.list.tHead.rows)for(b=0;b<this.list.tHead.rows[0].cells.length;b++)if(this.column_fixed!=b){a=this.list.tHead.rows[0].cells[b];a.onmousedown=function(d){return c.drag_column(d,this)};this.colcount++}}},clear:function(a){this.list.insertBefore(document.createElement("tbody"),this.list.tBodies[0]);
+this.list.removeChild(this.list.tBodies[1]);this.rows=[];this.rowcount=0;a&&this.clear_selection()},remove_row:function(a,b){if(this.rows[a].obj)this.rows[a].obj.style.display="none";b&&this.select_next();delete this.rows[a];this.rowcount--},insert_row:function(a,b){var c=this.list.tBodies[0];b&&c.rows.length?c.insertBefore(a,c.firstChild):c.appendChild(a);this.init_row(a);this.rowcount++},focus:function(a){var b;this.focused=true;for(var c in this.selection){b=this.selection[c];this.rows[b]&&this.rows[b].obj&&
+$(this.rows[b].obj).addClass("selected").removeClass("unfocused")}$("*:focus",window).blur();$("iframe").each(function(){this.blur()});if(a||(a=window.event))rcube_event.cancel(a)},blur:function(){var a;this.focused=false;for(var b in this.selection){a=this.selection[b];this.rows[a]&&this.rows[a].obj&&$(this.rows[a].obj).removeClass("selected").addClass("unfocused")}},drag_column:function(a,b){if(this.colcount>1){this.drag_start=true;this.drag_mouse_start=rcube_event.get_mouse_pos(a);rcube_event.add_listener({event:"mousemove",
+object:this,method:"column_drag_mouse_move"});rcube_event.add_listener({event:"mouseup",object:this,method:"column_drag_mouse_up"});this.add_dragfix();for(var c=0;c<this.list.tHead.rows[0].cells.length;c++)if(b==this.list.tHead.rows[0].cells[c]){this.selected_column=c;break}}return false},drag_row:function(a,b){var c=rcube_event.get_target(a),d=c.tagName.toLowerCase();if(this.dont_select||c&&(d=="input"||d=="img"))return true;if(rcube_event.get_button(a)==2)return true;this.in_selection_before=this.in_selection(b)?
+b:false;if(!this.in_selection_before){c=rcube_event.get_modifier(a);this.select_row(b,c,false)}if(this.draggable&&this.selection.length){this.drag_start=true;this.drag_mouse_start=rcube_event.get_mouse_pos(a);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"})}this.add_dragfix()}return false},click_row:function(a,b){var c=(new Date).getTime(),d=rcube_event.get_modifier(a),e=rcube_event.get_target(a),f=e.tagName.toLowerCase();if(e&&(f=="input"||f=="img"))return true;if(this.dont_select)return this.dont_select=false;e=c-this.rows[b].clicked<this.dblclick_time;!this.drag_active&&this.in_selection_before==b&&!e&&this.select_row(b,d,false);this.in_selection_before=this.drag_start=false;this.rows&&e&&this.in_selection(b)?
+this.triggerEvent("dblclick"):this.triggerEvent("click");if(!this.drag_active){this.del_dragfix();rcube_event.cancel(a)}this.rows[b].clicked=c;return false},find_root:function(a){var b=this.rows[a];return b&&b.parent_uid?this.find_root(b.parent_uid):a},expand_row:function(a,b){var c=this.rows[b],d=rcube_event.get_target(a),e=rcube_event.get_modifier(a);this.dont_select=true;c.clicked=0;if(c.expanded){d.className="collapsed";e==CONTROL_KEY||this.multiexpand?this.collapse_all(c):this.collapse(c)}else{d.className=
+"expanded";e==CONTROL_KEY||this.multiexpand?this.expand_all(c):this.expand(c)}},collapse:function(a){a.expanded=false;this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded});var b=a.depth;a=a?a.obj.nextSibling:null;for(var c;a;){if(a.nodeType==1){if((c=this.rows[a.uid])&&c.depth<=b)break;$(a).css("display","none");if(c.expanded){c.expanded=false;this.triggerEvent("expandcollapse",{uid:c.uid,expanded:c.expanded})}}a=a.nextSibling}return false},expand:function(a){var b,c,d;if(a){a.expanded=
+true;b=a.depth;c=a.obj.nextSibling;this.update_expando(a.uid,true);this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded})}else{c=this.list.tBodies[0].firstChild;d=b=0}for(;c;){if(c.nodeType==1){var e=this.rows[c.uid];if(e){if(a&&(!e.depth||e.depth<=b))break;if(e.parent_uid){var f=this.rows[e.parent_uid];if(f&&f.expanded){if(a&&f==a||d>=f.depth-1){d=f.depth;$(c).css("display","");e.expanded=true;this.triggerEvent("expandcollapse",{uid:e.uid,expanded:e.expanded})}}else if(a&&(!f||f.depth<=
+b))break}}}c=c.nextSibling}return false},collapse_all:function(a){var b,c,d;if(a){a.expanded=false;b=a.depth;c=a.obj.nextSibling;this.update_expando(a.uid);this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded});if(b&&this.multiexpand)return false}else{c=this.list.tBodies[0].firstChild;b=0}for(;c;){if(c.nodeType==1)if(d=this.rows[c.uid]){if(a&&(!d.depth||d.depth<=b))break;if(a||d.depth)$(c).css("display","none");if(d.has_children&&d.expanded){d.expanded=false;this.update_expando(d.uid,
+false);this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded})}}c=c.nextSibling}return false},expand_all:function(a){var b,c,d;if(a){a.expanded=true;b=a.depth;c=a.obj.nextSibling;this.update_expando(a.uid,true);this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded})}else{c=this.list.tBodies[0].firstChild;b=0}for(;c;){if(c.nodeType==1)if(d=this.rows[c.uid]){if(a&&d.depth<=b)break;$(c).css("display","");if(d.has_children&&!d.expanded){d.expanded=true;this.update_expando(d.uid,
+true);this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded})}}c=c.nextSibling}return false},update_expando:function(a,b){var c=document.getElementById("rcmexpando"+a);if(c)c.className=b?"expanded":"collapsed"},get_next_row:function(){if(!this.rows)return false;var a=this.rows[this.last_selected];for(a=a?a.obj.nextSibling:null;a&&(a.nodeType!=1||a.style.display=="none");)a=a.nextSibling;return a},get_prev_row:function(){if(!this.rows)return false;var a=this.rows[this.last_selected];for(a=
+a?a.obj.previousSibling:null;a&&(a.nodeType!=1||a.style.display=="none");)a=a.previousSibling;return a},get_first_row:function(){if(this.rowcount){var a,b,c=this.list.tBodies[0].rows;a=0;for(b=c.length-1;a<b;a++)if(c[a].id&&String(c[a].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 a,b=this.list.tBodies[0].rows;for(a=b.length-1;a>=0;a--)if(b[a].id&&String(b[a].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)&&
+this.rows[RegExp.$1]!=null)return RegExp.$1}return null},select_row:function(a,b,c){var d=this.selection.join(",");this.multiselect||(b=0);if(!this.shift_start)this.shift_start=a;if(b){switch(b){case SHIFT_KEY:this.shift_select(a,false);break;case CONTROL_KEY:c||this.highlight_row(a,true);break;case CONTROL_SHIFT_KEY:this.shift_select(a,true);break;default:this.highlight_row(a,false)}this.multi_selecting=true}else{this.shift_start=a;this.highlight_row(a,false);this.multi_selecting=false}this.selection.join(",")!=
+d&&this.triggerEvent("select");this.last_selected!=0&&this.rows[this.last_selected]&&$(this.rows[this.last_selected].obj).removeClass("focused");if(this.toggleselect&&this.last_selected==a){this.clear_selection();a=null}else $(this.rows[a].obj).addClass("focused");if(!this.selection.length)this.shift_start=null;this.last_selected=a},select:function(a){this.select_row(a,false);this.scrollto(a)},select_next:function(){var a=this.get_next_row(),b=this.get_prev_row();(a=a?a:b)&&this.select_row(a.uid,
+false,false)},select_first:function(a){var b=this.get_first_row();if(b&&a){this.shift_select(b,a);this.triggerEvent("select");this.scrollto(b)}else b&&this.select(b)},select_last:function(a){var b=this.get_last_row();if(b&&a){this.shift_select(b,a);this.triggerEvent("select");this.scrollto(b)}else b&&this.select(b)},select_childs:function(a){if(this.rows[a]&&this.rows[a].has_children){var b=this.rows[a].depth;for(a=this.rows[a].obj.nextSibling;a;){if(a.nodeType==1)if(r=this.rows[a.uid]){if(!r.depth||
+r.depth<=b)break;this.in_selection(r.uid)||this.select_row(r.uid,CONTROL_KEY)}a=a.nextSibling}}},shift_select:function(a,b){if(!this.rows[this.shift_start]||!this.selection.length)this.shift_start=a;var c=this.rows[this.shift_start].obj.rowIndex,d=this.rows[a].obj.rowIndex,e=c<d?c:d;c=c>d?c:d;for(var f in this.rows)if(this.rows[f].obj.rowIndex>=e&&this.rows[f].obj.rowIndex<=c)this.in_selection(f)||this.highlight_row(f,true);else this.in_selection(f)&&!b&&this.highlight_row(f,true)},in_selection:function(a){for(var b in this.selection)if(this.selection[b]==
+a)return true;return false},select_all:function(a){if(!this.rows||!this.rows.length)return false;var b=this.selection.join(",");this.selection=[];for(var c in this.rows)if(!a||this.rows[c][a]==true){this.last_selected=c;this.highlight_row(c,true)}else $(this.rows[c].obj).removeClass("selected").removeClass("unfocused");this.selection.join(",")!=b&&this.triggerEvent("select");this.focus();return true},invert_selection:function(){if(!this.rows||!this.rows.length)return false;var a=this.selection.join(","),
+b;for(b in this.rows)this.highlight_row(b,true);this.selection.join(",")!=a&&this.triggerEvent("select");this.focus();return true},clear_selection:function(a){var b=this.selection.length;if(a)for(var c in this.selection){if(this.selection[c]==a){this.selection.splice(c,1);break}}else{for(c in this.selection)this.rows[this.selection[c]]&&$(this.rows[this.selection[c]].obj).removeClass("selected").removeClass("unfocused");this.selection=[]}b&&!this.selection.length&&this.triggerEvent("select")},get_selection:function(){return this.selection},
+get_single_selection:function(){return this.selection.length==1?this.selection[0]:null},highlight_row:function(a,b){if(this.rows[a]&&!b){if(this.selection.length>1||!this.in_selection(a)){this.clear_selection();this.selection[0]=a;$(this.rows[a].obj).addClass("selected")}}else if(this.rows[a])if(this.in_selection(a)){var c=$.inArray(a,this.selection),d=this.selection.slice(0,c);c=this.selection.slice(c+1,this.selection.length);this.selection=d.concat(c);$(this.rows[a].obj).removeClass("selected").removeClass("unfocused")}else{this.selection[this.selection.length]=
+a;$(this.rows[a].obj).addClass("selected")}},key_press:function(a){if(this.focused!=true)return true;var b=rcube_event.get_keycode(a),c=rcube_event.get_modifier(a);switch(b){case 40:case 38:case 63233:case 63232:rcube_event.cancel(a);return this.use_arrow_key(b,c);case 61:case 107:case 109:case 32:rcube_event.cancel(a);a=this.use_plusminus_key(b,c);this.key_pressed=b;this.triggerEvent("keypress");return a;case 36:this.select_first(c);return rcube_event.cancel(a);case 35:this.select_last(c);return rcube_event.cancel(a);
+default:this.shiftkey=a.shiftKey;this.key_pressed=b;this.triggerEvent("keypress");if(this.key_pressed==this.BACKSPACE_KEY)return rcube_event.cancel(a)}return true},key_down:function(a){switch(rcube_event.get_keycode(a)){case 27:if(this.drag_active)return this.drag_mouse_up(a);if(this.col_drag_active){this.selected_column=null;return this.column_drag_mouse_up(a)}case 40:case 38:case 63233:case 63232:case 61:case 107:case 109:case 32:if(!rcube_event.get_modifier(a)&&this.focused)return rcube_event.cancel(a)}return true},
+use_arrow_key:function(a,b){var c;if(a==40||a==63233)c=this.get_next_row();else if(a==38||a==63232)c=this.get_prev_row();if(c){this.select_row(c.uid,b,true);this.scrollto(c.uid)}return false},use_plusminus_key:function(a,b){var c=this.rows[this.last_selected];if(c){if(a==32)a=c.expanded?109:61;if(a==61||a==107)b==CONTROL_KEY||this.multiexpand?this.expand_all(c):this.expand(c);else b==CONTROL_KEY||this.multiexpand?this.collapse_all(c):this.collapse(c);this.update_expando(c.uid,c.expanded);return false}},
+scrollto:function(a){var b=this.rows[a].obj;if(b&&this.frame){var c=Number(b.offsetTop);if(!c&&this.rows[a].parent_uid){this.expand_all(this.rows[this.find_root(this.rows[a].uid)]);c=Number(b.offsetTop)}if(c<Number(this.frame.scrollTop))this.frame.scrollTop=c;else if(c+Number(b.offsetHeight)>Number(this.frame.scrollTop)+Number(this.frame.offsetHeight))this.frame.scrollTop=c+Number(b.offsetHeight)-Number(this.frame.offsetHeight)}},drag_mouse_move:function(a){if(a.type=="touchmove")if(a.changedTouches.length==
+1)a=rcube_event.touchevent(a.changedTouches[0]);else return rcube_event.cancel(a);if(this.drag_start){var b=rcube_event.get_mouse_pos(a);if(!this.drag_mouse_start||Math.abs(b.x-this.drag_mouse_start.x)<3&&Math.abs(b.y-this.drag_mouse_start.y)<3)return false;if(!this.draglayer)this.draglayer=$("<div>").attr("id","rcmdraglayer").css({position:"absolute",display:"none","z-index":2E3}).appendTo(document.body);var c,d,e=$.merge([],this.selection);for(c in e){d=e[c];this.rows[d].has_children&&!this.rows[d].expanded&&
+this.select_childs(d)}this.draglayer.html("");for(c=0;c<this.selection.length;c++){if(c>12){this.draglayer.append("...");break}if(e=this.rows[this.selection[c]].obj)for(d=b=0;d<e.childNodes.length;d++)if(e.childNodes[d].nodeName=="TD"){if(c==0)this.drag_start_pos=$(e.childNodes[d]).offset();if(this.subject_col<0||this.subject_col>=0&&this.subject_col==b){var f,g,h=e.childNodes[d].childNodes;for(b=0;b<h.length;b++)if((g=e.childNodes[d].childNodes[b])&&(g.nodeType==3||g.nodeName=="A"))f=g;if(!f)break;
+d=$(f).text();d=$.trim(d);d=d.length>50?d.substring(0,50)+"...":d;this.draglayer.append($("<div>").text(d));break}b++}}this.draglayer.show();this.drag_active=true;this.triggerEvent("dragstart")}if(this.drag_active&&this.draglayer){c=rcube_event.get_mouse_pos(a);this.draglayer.css({left:c.x+20+"px",top:c.y-5+(bw.ie?document.documentElement.scrollTop:0)+"px"});this.triggerEvent("dragmove",a?a:window.event)}return this.drag_start=false},drag_mouse_up:function(a){document.onmousemove=null;if(a.type==
+"touchend")if(a.changedTouches.length!=1)return rcube_event.cancel(a);if(this.draglayer&&this.draglayer.is(":visible"))this.drag_start_pos?this.draglayer.animate(this.drag_start_pos,300,"swing").hide(20):this.draglayer.hide();this.drag_active&&this.focus();this.drag_active=false;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"})}this.del_dragfix();this.triggerEvent("dragend");return rcube_event.cancel(a)},column_drag_mouse_move:function(a){if(this.drag_start){var b;b=rcube_event.get_mouse_pos(a);if(!this.drag_mouse_start||Math.abs(b.x-this.drag_mouse_start.x)<3&&Math.abs(b.y-this.drag_mouse_start.y)<3)return false;if(!this.col_draglayer){b=$(this.list).offset();var c=this.list.tHead.rows[0].cells;this.col_draglayer=
+$("<div>").attr("id","rcmcoldraglayer").css(b).css({position:"absolute","z-index":2001,"background-color":"white",opacity:0.75,height:this.frame.offsetHeight-2+"px",width:this.frame.offsetWidth-2+"px"}).appendTo(document.body).append($("<div>").attr("id","rcmcolumnindicator").css({position:"absolute","border-right":"2px dotted #555","z-index":2002,height:this.frame.offsetHeight-2+"px"}));this.cols=[];this.list_pos=this.list_min_pos=b.left;for(b=0;b<c.length;b++){this.cols[b]=c[b].offsetWidth;if(this.column_fixed!==
+null&&b<=this.column_fixed)this.list_min_pos+=this.cols[b]}}this.col_draglayer.show();this.col_drag_active=true;this.triggerEvent("column_dragstart")}if(this.col_drag_active&&this.col_draglayer){c=0;var d=rcube_event.get_mouse_pos(a);for(b=0;b<this.cols.length;b++)if(d.x>=this.cols[b]/2+this.list_pos+c)c+=this.cols[b];else break;if(b==0&&this.list_min_pos>d.x)c=this.list_min_pos-this.list_pos;else if(!this.list.rowcount&&b==this.cols.length)c-=2;$("#rcmcolumnindicator").css({width:c+"px"});this.triggerEvent("column_dragmove",
+a?a:window.event)}return this.drag_start=false},column_drag_mouse_up:function(a){document.onmousemove=null;if(this.col_draglayer){this.col_draglayer.remove();this.col_draglayer=null}this.col_drag_active&&this.focus();this.col_drag_active=false;rcube_event.remove_listener({event:"mousemove",object:this,method:"column_drag_mouse_move"});rcube_event.remove_listener({event:"mouseup",object:this,method:"column_drag_mouse_up"});this.del_dragfix();if(this.selected_column!==null&&this.cols&&this.cols.length){var b,
+c=0,d=rcube_event.get_mouse_pos(a);for(b=0;b<this.cols.length;b++)if(d.x>=this.cols[b]/2+this.list_pos+c)c+=this.cols[b];else break;b!=this.selected_column&&b!=this.selected_column+1&&this.column_replace(this.selected_column,b)}this.triggerEvent("column_dragend");return rcube_event.cancel(a)},add_dragfix:function(){$("iframe").each(function(){$('<div class="iframe-dragdrop-fix"></div>').css({background:"#fff",width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",
+zIndex:1E3}).css($(this).offset()).appendTo(document.body)})},del_dragfix:function(){$("div.iframe-dragdrop-fix").each(function(){this.parentNode.removeChild(this)})},column_replace:function(a,b){var c=this.list.tHead.rows[0].cells,d=c[a],e=c[b],f=document.createElement("td");e?c[0].parentNode.insertBefore(f,e):c[0].parentNode.appendChild(f);c[0].parentNode.replaceChild(d,f);for(r=0;r<this.list.tBodies[0].rows.length;r++){row=this.list.tBodies[0].rows[r];d=row.cells[a];e=row.cells[b];f=document.createElement("td");
+e?row.insertBefore(f,e):row.appendChild(f);row.replaceChild(d,f)}if(this.subject_col==a)this.subject_col=b>a?b-1:b;else if(this.subject_col<a&&b<=this.subject_col)this.subject_col++;else this.subject_col>a&&b>=this.subject_col&&this.subject_col--;this.triggerEvent("column_replace")}};rcube_list_widget.prototype.addEventListener=rcube_event_engine.prototype.addEventListener;rcube_list_widget.prototype.removeEventListener=rcube_event_engine.prototype.removeEventListener;
+rcube_list_widget.prototype.triggerEvent=rcube_event_engine.prototype.triggerEvent;