summaryrefslogtreecommitdiff
path: root/program/js
diff options
context:
space:
mode:
authorthomascube <thomas@roundcube.net>2008-09-12 11:12:05 +0000
committerthomascube <thomas@roundcube.net>2008-09-12 11:12:05 +0000
commitf89f03cd6ae4a1b3f98e39c2e01d9e40f8a286b4 (patch)
tree755571136a62931e139bfefa922e386c81344c0f /program/js
parent55fb73529c5f97fdd79982e546eb15ad870f4438 (diff)
Refactor drag & drop functionality. Don't rely on browser events anymore (#1484453)
Diffstat (limited to 'program/js')
-rw-r--r--program/js/app.js72
-rw-r--r--program/js/common.js26
-rw-r--r--program/js/list.js15
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);
}
}