diff options
author | thomascube <thomas@roundcube.net> | 2008-09-12 11:12:05 +0000 |
---|---|---|
committer | thomascube <thomas@roundcube.net> | 2008-09-12 11:12:05 +0000 |
commit | f89f03cd6ae4a1b3f98e39c2e01d9e40f8a286b4 (patch) | |
tree | 755571136a62931e139bfefa922e386c81344c0f /program/js | |
parent | 55fb73529c5f97fdd79982e546eb15ad870f4438 (diff) |
Refactor drag & drop functionality. Don't rely on browser events anymore (#1484453)
Diffstat (limited to 'program/js')
-rw-r--r-- | program/js/app.js | 72 | ||||
-rw-r--r-- | program/js/common.js | 26 | ||||
-rw-r--r-- | program/js/list.js | 15 |
3 files changed, 71 insertions, 42 deletions
diff --git a/program/js/app.js b/program/js/app.js index 3812a73de..36072e384 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -133,6 +133,7 @@ function rcube_webmail() this.message_list.addEventListener('keypress', function(o){ p.msglist_keypress(o); }); this.message_list.addEventListener('select', function(o){ p.msglist_select(o); }); this.message_list.addEventListener('dragstart', function(o){ p.drag_active = true; if (p.preview_timer) clearTimeout(p.preview_timer); }); + this.message_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); }); this.message_list.addEventListener('dragend', function(o){ p.drag_active = false; }); this.message_list.init(); @@ -252,6 +253,7 @@ function rcube_webmail() this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); }); this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); }); this.contact_list.addEventListener('dragstart', function(o){ p.drag_active = true; }); + this.contact_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); }); this.contact_list.addEventListener('dragend', function(o){ p.drag_active = false; }); this.contact_list.init(); @@ -1158,27 +1160,43 @@ function rcube_webmail() this.doc_mouse_up = function(e) - { - if (this.message_list) + { + var model, li; + + if (this.message_list) { this.message_list.blur(); - else if (this.contact_list) + model = this.env.mailboxes; + } + else if (this.contact_list) { this.contact_list.blur(); - }; - - this.focus_folder = function(id) - { - var li; - if (this.drag_active && this.check_droptarget(id) && (li = this.get_folder_li(id))) - this.set_classname(li, 'droptarget', true); + model = this.env.address_sources; + } + + // handle mouse release when dragging + if (this.drag_active && model) { + for (var k in model) { + if ((li = this.get_folder_li(k)) && rcube_mouse_is_over(e, li.firstChild) && this.check_droptarget(k)) { + this.set_classname(li, 'droptarget', false); + this.command('moveto', model[k].id); + break; + } + } } + }; - this.unfocus_folder = function(id) - { + this.drag_move = function(e) + { var li; - if (this.drag_active && (li = this.get_folder_li(id))) - this.set_classname(li, 'droptarget', false); + var model = this.task == 'mail' ? this.env.mailboxes : this.env.address_sources; + + if (this.gui_objects.folderlist && model) { + for (var k in model) { + if (li = this.get_folder_li(k)) + this.set_classname(li, 'droptarget', (rcube_mouse_is_over(e, li.firstChild) && this.check_droptarget(k))); + } } - + }; + this.collapse_folder = function(id) { var div; @@ -1211,16 +1229,6 @@ function rcube_webmail() } } - // onmouseup handler for folder list item - this.folder_mouse_up = function(id) - { - if (this.drag_active) - { - this.unfocus_folder(id); - this.command('moveto', id); - } - }; - this.click_on_list = function(e) { if (this.message_list) @@ -1232,7 +1240,7 @@ function rcube_webmail() if (mbox_li = this.get_folder_li()) this.set_classname(mbox_li, 'unfocused', true); - rcube_event.cancel(e); + return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e); }; @@ -1303,7 +1311,7 @@ function rcube_webmail() this.check_droptarget = function(id) { if (this.task == 'mail') - return (id != this.env.mailbox); + return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual); else if (this.task == 'addressbook') return (id != this.env.source && this.env.address_sources[id] && !this.env.address_sources[id].readonly); else if (this.task == 'settings') @@ -3009,12 +3017,12 @@ function rcube_webmail() row.id = id; if (before && (before = this.get_folder_row_id(before))) - tbody.insertBefore(row, document.getElementById(before)); + tbody.insertBefore(row, document.getElementById(before)); else - tbody.appendChild(row); + tbody.appendChild(row); if (replace) - tbody.removeChild(replace); + tbody.removeChild(replace); } // add to folder/row-ID map @@ -3136,9 +3144,9 @@ function rcube_webmail() { var cell, td; var new_row = document.createElement('TR'); - for(var n=0; n<row.childNodes.length; n++) + for(var n=0; n<row.cells.length; n++) { - cell = row.childNodes[n]; + cell = row.cells[n]; td = document.createElement('TD'); if (cell.className) diff --git a/program/js/common.js b/program/js/common.js index 6e4c643fa..209ce1070 100644 --- a/program/js/common.js +++ b/program/js/common.js @@ -114,6 +114,15 @@ get_keycode: function(e) }, /** + * returns the event key code + */ +get_button: function(e) +{ + e = e || window.event; + return e && (typeof e.button != 'undefined') ? e.button : (e && e.which ? e.which : 0); +}, + +/** * returns modifier key (constants defined at top of file) */ get_modifier: function(e) @@ -502,18 +511,25 @@ function rcube_get_object_pos(obj) var elm = obj.offsetParent; while(elm && elm!=null) { - iX += elm.offsetLeft; - iY += elm.offsetTop; + iX += elm.offsetLeft - (elm.parentNode && elm.parentNode.scrollLeft ? elm.parentNode.scrollLeft : 0); + iY += elm.offsetTop - (elm.parentNode && elm.parentNode.scrollTop ? elm.parentNode.scrollTop : 0); elm = elm.offsetParent; } } - //if(bw.mac && bw.ie5) iX += document.body.leftMargin; - //if(bw.mac && bw.ie5) iY += document.body.topMargin; - return {x:iX, y:iY}; } +// determine whether the mouse is over the given object or not +function rcube_mouse_is_over(ev, obj) +{ + var mouse = rcube_event.get_mouse_pos(ev); + var pos = rcube_get_object_pos(obj); + + return ((mouse.x >= pos.x) && (mouse.x < (pos.x + obj.offsetWidth)) && + (mouse.y >= pos.y) && (mouse.y < (pos.y + obj.offsetHeight))); +} + /** * Return the currently applied value of a css property diff --git a/program/js/list.js b/program/js/list.js index f33c67c7b..926d98aa7 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -51,7 +51,7 @@ function rcube_list_widget(list, p) this.drag_mouse_start = null; this.dblclick_time = 600; this.row_init = function(){}; - this.events = { click:[], dblclick:[], select:[], keypress:[], dragstart:[], dragend:[] }; + this.events = { click:[], dblclick:[], select:[], keypress:[], dragstart:[], dragmove:[], dragend:[] }; // overwrite default paramaters if (p && typeof(p)=='object') @@ -221,7 +221,11 @@ drag_row: function(e, id) var evtarget = rcube_event.get_target(e); if (this.dont_select || (evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG'))) return false; - + + // 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 @@ -576,7 +580,7 @@ key_press: function(e) this.key_pressed = keyCode; this.trigger_event('keypress'); - if (this.key_pressed == list.BACKSPACE_KEY) + if (this.key_pressed == this.BACKSPACE_KEY) return rcube_event.cancel(e); } @@ -704,6 +708,7 @@ drag_mouse_move: function(e) { var pos = rcube_event.get_mouse_pos(e); this.draglayer.move(pos.x+20, pos.y-5); + this.trigger_event('dragmove', e); } this.drag_start = false; @@ -784,12 +789,12 @@ removeEventListener: function(evt, handle) * This will execute all registered event handlers * @private */ -trigger_event: function(evt) +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); + this.events[evt][i](this, p); } } |