From bc2accc455e1dab67e0d29f034deddd9401ecad2 Mon Sep 17 00:00:00 2001 From: alecpl <alec@alec.pl> Date: Thu, 25 Mar 2010 14:16:50 -0400 Subject: [PATCH] - Added Home/End kayboard keys support on lists (#1486430) --- program/js/list.js | 695 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 562 insertions(+), 133 deletions(-) diff --git a/program/js/list.js b/program/js/list.js index 926d98a..13fa7d3 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -3,7 +3,7 @@ | RoundCube List Widget | | | | This file is part of the RoundCube Webmail client | - | Copyright (C) 2006-2008, RoundCube Dev, - Switzerland | + | Copyright (C) 2006-2009, RoundCube Dev, - Switzerland | | Licensed under the GNU GPL | | | +-----------------------------------------------------------------------+ @@ -13,7 +13,7 @@ | Requires: common.js | +-----------------------------------------------------------------------+ - $Id: list.js 344 2006-09-18 03:49:28Z thomasb $ + $Id$ */ @@ -37,6 +37,7 @@ this.subject_col = -1; this.shiftkey = false; this.multiselect = false; + this.multiexpand = false; this.multi_selecting = false; this.draggable = false; this.keyboard = false; @@ -51,7 +52,6 @@ this.drag_mouse_start = null; this.dblclick_time = 600; this.row_init = function(){}; - this.events = { click:[], dblclick:[], select:[], keypress:[], dragstart:[], dragmove:[], dragend:[] }; // overwrite default paramaters if (p && typeof(p)=='object') @@ -77,7 +77,7 @@ 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')) + while (row && row.nodeType != 1) { row = row.nextSibling; r++; @@ -91,7 +91,7 @@ // set body events if (this.keyboard) { - rcube_event.add_listener({element:document, event:'keyup', object:this, method:'key_press'}); + 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'}); } } @@ -99,17 +99,17 @@ /** - * + * 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)) + 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}; + 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); }; @@ -124,11 +124,11 @@ /** - * + * Remove all list rows */ clear: function(sel) { - var tbody = document.createElement('TBODY'); + var tbody = document.createElement('tbody'); this.list.insertBefore(tbody, this.list.tBodies[0]); this.list.removeChild(this.list.tBodies[1]); this.rows = new Array(); @@ -155,11 +155,14 @@ /** - * + * Add row to the list and initialize it */ insert_row: function(row, attop) { - var tbody = this.list.tBodies[0]; + if (this.background) + var tbody = this.background; + else + var tbody = this.list.tBodies[0]; if (attop && tbody.rows.length) tbody.insertBefore(row, tbody.firstChild); @@ -173,7 +176,7 @@ /** - * Set focur to the list + * Set focus to the list */ focus: function(e) { @@ -181,10 +184,8 @@ for (var n=0; n<this.selection.length; n++) { id = this.selection[n]; - if (this.rows[id] && this.rows[id].obj) - { - this.set_classname(this.rows[id].obj, 'selected', true); - this.set_classname(this.rows[id].obj, 'unfocused', false); + if (this.rows[id] && this.rows[id].obj) { + $(this.rows[id].obj).addClass('selected').removeClass('unfocused'); } } @@ -203,10 +204,8 @@ for (var n=0; n<this.selection.length; n++) { id = this.selection[n]; - if (this.rows[id] && this.rows[id].obj) - { - this.set_classname(this.rows[id].obj, 'selected', false); - this.set_classname(this.rows[id].obj, 'unfocused', true); + if (this.rows[id] && this.rows[id].obj) { + $(this.rows[id].obj).removeClass('selected').addClass('unfocused'); } } }, @@ -219,8 +218,9 @@ { // don't do anything (another action processed before) var evtarget = rcube_event.get_target(e); - if (this.dont_select || (evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG'))) - return false; + 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) @@ -241,6 +241,36 @@ 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; @@ -255,10 +285,11 @@ var now = new Date().getTime(); var mod_key = rcube_event.get_modifier(e); var evtarget = rcube_event.get_target(e); - - if ((evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG'))) - return false; - + 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) { @@ -277,9 +308,9 @@ // row was double clicked if (this.rows && dblclicked && this.in_selection(id)) - this.trigger_event('dblclick'); + this.triggerEvent('dblclick'); else - this.trigger_event('click'); + this.triggerEvent('click'); if (!this.drag_active) rcube_event.cancel(e); @@ -289,8 +320,211 @@ }, +/* + * Returns thread root ID for specified row ID + */ +find_root: function(uid) +{ + var r = this.rows[uid]; + + if (r && r.parent_uid) + return this.find_root(r.parent_uid); + else + return uid; +}, + + +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); + + // 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; + + if (row.expanded) { + evtarget.className = "collapsed"; + if (mod_key == CONTROL_KEY || this.multiexpand) + this.collapse_all(row); + else + this.collapse(row); + } + else { + evtarget.className = "expanded"; + if (mod_key == CONTROL_KEY || this.multiexpand) + this.expand_all(row); + else + this.expand(row); + } +}, + +collapse: function(row) +{ + row.expanded = false; + this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded }); + var depth = row.depth; + var new_row = row ? row.obj.nextSibling : null; + var r; + + while (new_row) { + if (new_row.nodeType == 1) { + 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 = new_row.nextSibling; + } + + return false; +}, + +expand: function(row) +{ + var depth, new_row; + var last_expanded_parent_depth; + + if (row) { + row.expanded = true; + depth = row.depth; + new_row = row.obj.nextSibling; + this.update_expando(row.uid, true); + this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded }); + } + else { + var tbody = this.list.tBodies[0]; + new_row = tbody.firstChild; + depth = 0; + last_expanded_parent_depth = 0; + } + + while (new_row) { + if (new_row.nodeType == 1) { + var r = this.rows[new_row.uid]; + if (r) { + if (row && (!r.depth || r.depth <= depth)) + break; + + if (r.parent_uid) { + var p = this.rows[r.parent_uid]; + if (p && p.expanded) { + if ((row && p == row) || last_expanded_parent_depth >= p.depth - 1) { + last_expanded_parent_depth = p.depth; + $(new_row).show(); + r.expanded = true; + this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded }); + } + } + else + if (row && (! p || p.depth <= depth)) + break; + } + } + } + new_row = new_row.nextSibling; + } + + return false; +}, + + +collapse_all: function(row) +{ + var depth, new_row; + var r; + + if (row) { + row.expanded = false; + depth = row.depth; + new_row = row.obj.nextSibling; + this.update_expando(row.uid); + this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded }); + + // don't collapse sub-root tree in multiexpand mode + if (depth && this.multiexpand) + return false; + } + else { + var tbody = this.list.tBodies[0]; + new_row = tbody.firstChild; + depth = 0; + } + + while (new_row) { + if (new_row.nodeType == 1) { + var r = this.rows[new_row.uid]; + if (r) { + if (row && (!r.depth || r.depth <= depth)) + break; + + if (row || r.depth) + $(new_row).hide(); + if (r.has_children) { + r.expanded = false; + this.update_expando(r.uid); + this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded }); + } + } + } + new_row = new_row.nextSibling; + } + + return false; +}, + +expand_all: function(row) +{ + var depth, new_row; + var r; + + if (row) { + row.expanded = true; + depth = row.depth; + new_row = row.obj.nextSibling; + this.update_expando(row.uid, true); + this.triggerEvent('expandcollapse', { uid:row.uid, expanded:row.expanded }); + } + else { + var tbody = this.list.tBodies[0]; + new_row = tbody.firstChild; + depth = 0; + } + + while (new_row) { + if (new_row.nodeType == 1) { + var r = this.rows[new_row.uid]; + if (r) { + if (row && r.depth <= depth) + break; + + $(new_row).show(); + if (r.has_children) { + r.expanded = true; + this.update_expando(r.uid, true); + this.triggerEvent('expandcollapse', { uid:r.uid, expanded:r.expanded }); + } + } + } + new_row = new_row.nextSibling; + } + return false; +}, + +update_expando: function(uid, expanded) +{ + var expando = document.getElementById('rcmexpando' + uid); + if (expando) + expando.className = expanded ? 'expanded' : 'collapsed'; +}, + + /** - * get next and previous rows that are not hidden + * get first/next/previous/last rows that are not hidden */ get_next_row: function() { @@ -318,8 +552,38 @@ return new_row; }, +get_first_row: function() +{ + if (this.rowcount) + { + var rows = this.list.tBodies[0].rows; -// selects or unselects the proper row depending on the modifier key pressed + 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; + } + + return null; +}, + +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(','); @@ -361,10 +625,10 @@ // trigger event if selection changed if (this.selection.join(',') != select_before) - this.trigger_event('select'); + this.triggerEvent('select'); if (this.last_selected != 0 && this.rows[this.last_selected]) - this.set_classname(this.rows[this.last_selected].obj, 'focused', false); + $(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) @@ -373,7 +637,7 @@ id = null; } else - this.set_classname(this.rows[id].obj, 'focused', true); + $(this.rows[id].obj).addClass('focused'); if (!this.selection.length) this.shift_start = null; @@ -407,6 +671,62 @@ /** + * Select first row + */ +select_first: function(mod_key) +{ + var row = this.get_first_row(); + if (row && mod_key) { + this.shift_select(row, mod_key); + this.triggerEvent('select'); + this.scrollto(row); + } + else if (row) + this.select(row); +}, + + +/** + * Select last row + */ +select_last: function(mod_key) +{ + var row = this.get_last_row(); + if (row && mod_key) { + this.shift_select(row, mod_key); + this.triggerEvent('select'); + this.scrollto(row); + } + else if (row) + this.select(row); +}, + + +/** + * Add all childs of the given row to selection + */ +select_childs: function(uid) +{ + if (!this.rows[uid] || !this.rows[uid].has_children) + return; + + var depth = this.rows[uid].depth; + var row = this.rows[uid].obj.nextSibling; + while (row) { + if (row.nodeType == 1) { + if ((r = this.rows[row.uid])) { + if (!r.depth || r.depth <= depth) + break; + if (!this.in_selection(r.uid)) + this.select_row(r.uid, CONTROL_KEY); + } + } + row = row.nextSibling; + } +}, + + +/** * Perform selection when shift key is pressed */ shift_select: function(id, control) @@ -425,13 +745,15 @@ { if ((this.rows[n].obj.rowIndex >= i) && (this.rows[n].obj.rowIndex <= j)) { - if (!this.in_selection(n)) + if (!this.in_selection(n)) { this.highlight_row(n, true); + } } else { - if (this.in_selection(n) && !control) + if (this.in_selection(n) && !control) { this.highlight_row(n, true); + } } } }, @@ -446,7 +768,7 @@ if (this.selection[n]==id) return true; - return false; + return false; }, @@ -460,20 +782,24 @@ // reset but remember selection first var select_before = this.selection.join(','); - this.clear_selection(); - + this.selection = new Array(); + for (var n in this.rows) { - if (!filter || this.rows[n][filter]==true) + 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.trigger_event('select'); + this.triggerEvent('select'); this.focus(); @@ -482,22 +808,58 @@ /** - * Unselect all selected rows + * Invert selection */ -clear_selection: function() +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; - for (var n=0; n<this.selection.length; n++) - if (this.rows[this.selection[n]]) + + // one row + if (id) { - this.set_classname(this.rows[this.selection[n]].obj, 'selected', false); - this.set_classname(this.rows[this.selection[n]].obj, 'unfocused', false); + 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(); } - this.selection = new Array(); - - if (num_select) - this.trigger_event('select'); + if (num_select && !this.selection.length) + this.triggerEvent('select'); }, @@ -533,7 +895,7 @@ { this.clear_selection(); this.selection[0] = id; - this.set_classname(this.rows[id].obj, 'selected', true); + $(this.rows[id].obj).addClass('selected'); } } else if (this.rows[id]) @@ -541,16 +903,15 @@ if (!this.in_selection(id)) // select row { this.selection[this.selection.length] = id; - this.set_classname(this.rows[id].obj, 'selected', true); + $(this.rows[id].obj).addClass('selected'); } else // unselect row { - var p = find_in_array(id, this.selection); + var p = jQuery.inArray(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.set_classname(this.rows[id].obj, 'selected', false); - this.set_classname(this.rows[id].obj, 'unfocused', false); + $(this.rows[id].obj).removeClass('selected').removeClass('unfocused'); } } }, @@ -566,6 +927,7 @@ var keyCode = rcube_event.get_keycode(e); var mod_key = rcube_event.get_modifier(e); + switch (keyCode) { case 40: @@ -575,10 +937,26 @@ // Stop propagation so that the browser doesn't scroll rcube_event.cancel(e); return this.use_arrow_key(keyCode, mod_key); + case 61: + case 107: // Plus sign on a numeric keypad (fc11 + firefox 3.5.2) + case 109: + case 32: + // Stop propagation + rcube_event.cancel(e); + var ret = this.use_plusminus_key(keyCode, mod_key); + this.key_pressed = keyCode; + this.triggerEvent('keypress'); + return ret; + case 36: // Home + this.select_first(mod_key); + return rcube_event.cancel(e); + case 35: // End + this.select_last(mod_key); + return rcube_event.cancel(e); default: this.shiftkey = e.shiftKey; this.key_pressed = keyCode; - this.trigger_event('keypress'); + this.triggerEvent('keypress'); if (this.key_pressed == this.BACKSPACE_KEY) return rcube_event.cancel(e); @@ -594,10 +972,18 @@ { 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: + case 61: + case 107: + case 109: + case 32: if (!rcube_event.get_modifier(e) && this.focused) return rcube_event.cancel(e); @@ -632,6 +1018,36 @@ /** + * Special handling method for +/- keys + */ +use_plusminus_key: function(keyCode, mod_key) +{ + var selected_row = this.rows[this.last_selected]; + if (!selected_row) + return; + + if (keyCode == 32) + keyCode = selected_row.expanded ? 109 : 61; + if (keyCode == 61 || keyCode == 107) + if (mod_key == CONTROL_KEY || this.multiexpand) + this.expand_all(selected_row); + else + this.expand(selected_row); + else + if (mod_key == CONTROL_KEY || this.multiexpand) + this.collapse_all(selected_row); + else + this.collapse(selected_row); + + var expando = document.getElementById('rcmexpando' + selected_row.uid); + if (expando) + expando.className = selected_row.expanded?'expanded':'collapsed'; + + return false; +}, + + +/** * Try to scroll the list to make the specified row visible */ scrollto: function(id) @@ -640,6 +1056,13 @@ if (row && this.frame) { var scroll_to = Number(row.offsetTop); + + // expand thread if target row is hidden (collapsed) + if (!scroll_to && this.rows[id].parent_uid) { + var parent = this.find_root(this.rows[id].uid); + this.expand_all(this.rows[parent]); + scroll_to = Number(row.offsetTop); + } if (scroll_to < Number(this.frame.scrollTop)) this.frame.scrollTop = scroll_to; @@ -658,15 +1081,25 @@ { // 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 = new rcube_layer('rcmdraglayer', {x:0, y:0, width:300, vis:0, zindex:2000}); - - // get subjects of selectedd messages + this.draglayer = $('<div>').attr('id', 'rcmdraglayer').css({ position:'absolute', display:'none', 'z-index':2000 }).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++) { + 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, node, subject, obj; + var c, i, subject, obj; for(var n=0; n<this.selection.length; n++) { if (n>12) // only show 12 lines @@ -675,20 +1108,34 @@ break; } - if (this.rows[this.selection[n]].obj) + if (obj = this.rows[this.selection[n]].obj) { - obj = this.rows[this.selection[n]].obj; subject = ''; - for(c=0, i=0; i<obj.childNodes.length; i++) + for (c=0, i=0; i<obj.childNodes.length; i++) { - if (obj.childNodes[i].nodeName == 'TD') + 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) + this.drag_start_pos = $(obj.childNodes[i]).offset(); + + if (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == c)) + { + var node, tmp_node, nodes = obj.childNodes[i].childNodes; + // find text node + for (m=0; m<nodes.length; m++) { + if ((tmp_node = obj.childNodes[i].childNodes[m]) && (tmp_node.nodeType==3 || tmp_node.nodeName=='A')) + node = tmp_node; + } + + if (!node) + break; + subject = node.nodeType==3 ? node.data : node.innerHTML; - names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />'; + // 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++; @@ -697,18 +1144,18 @@ } } - this.draglayer.write(names); - this.draglayer.show(1); + this.draglayer.html(names); + this.draglayer.show(); this.drag_active = true; - this.trigger_event('dragstart'); + this.triggerEvent('dragstart'); } if (this.drag_active && this.draglayer) { var pos = rcube_event.get_mouse_pos(e); - this.draglayer.move(pos.x+20, pos.y-5); - this.trigger_event('dragmove', 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; @@ -724,80 +1171,62 @@ { document.onmousemove = null; - if (this.draglayer && this.draglayer.visible) - this.draglayer.show(0); + 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.trigger_event('dragend'); + 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'}); - this.focus(); - + 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); }, - /** - * set/unset a specific class name + * Creating the list in background */ -set_classname: function(obj, classname, set) +set_background_mode: function(flag) { - var reg = new RegExp('\s*'+classname, 'i'); - if (!set && obj.className.match(reg)) - obj.className = obj.className.replace(reg, ''); - else if (set && !obj.className.match(reg)) - obj.className += ' '+classname; -}, - - -/** - * Setter for object event handlers - * - * @param {String} Event name - * @param {Function} Handler function - * @return Listener ID (used to remove this handler later on) - */ -addEventListener: function(evt, handler) -{ - if (this.events[evt]) { - var handle = this.events[evt].length; - this.events[evt][handle] = handler; - return handle; - } - else - return false; -}, - - -/** - * Removes a specific event listener - * - * @param {String} Event name - * @param {Int} Listener ID to remove - */ -removeEventListener: function(evt, handle) -{ - if (this.events[evt] && this.events[evt][handle]) - this.events[evt][handle] = null; -}, - - -/** - * This will execute all registered event handlers - * @private - */ -trigger_event: function(evt, p) -{ - if (this.events[evt] && this.events[evt].length) { - for (var i=0; i<this.events[evt].length; i++) - if (typeof(this.events[evt][i]) == 'function') - this.events[evt][i](this, p); + 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; -- Gitblit v1.9.1