MDL-36002 dragdrop: Add simulated event for keyboard drag drop.

This is to prevent any accidental state change in Y.DD.DDM.
This commit is contained in:
Damyon Wiese 2013-08-04 22:11:22 +08:00
parent 313e58519c
commit ade4695de0

View File

@ -65,21 +65,11 @@ YUI.add('moodle-core-dragdrop', function(Y) {
},
lock_drag_handle: function(drag, classname) {
// Disable dragging
try {
drag.removeHandle('.'+classname);
} catch (e) {
// Throws exceptions if the drag is not started with the mouse.
}
drag.removeHandle('.'+classname);
},
unlock_drag_handle: function(drag, classname) {
// Enable dragging
try {
drag.addHandle('.'+classname);
} catch (e) {
// Throws exceptions if the drag is not started with the mouse.
}
drag.addHandle('.'+classname);
},
ajax_failure: function(response) {
@ -326,6 +316,58 @@ YUI.add('moodle-core-dragdrop', function(Y) {
}
},
/**
* This is used as a simulated drag/drop event in order to prevent any
* subtle bugs from creating a real instance of a drag drop event. This means
* there are no state changes in the Y.DD.DDM and any undefined functions
* will trigger an obvious and fatal error.
* The end result is that we call all our drag/drop handlers but do not bubble the
* event to anyone else.
*
* The functions/properties implemented in the wrapper are:
* e.target
* e.drag
* e.drop
* e.drag.get('node')
* e.drop.get('node')
* e.drag.addHandle()
* e.drag.removeHandle()
*
* @class simulated_drag_drop_event
* @param {Node} dragnode The drag container node
* @param {Node} dropnode The node to initiate the drop on
*/
simulated_drag_drop_event : function(dragnode, dropnode) {
this.target = dropnode;
// Subclass for wrapping both drag and drop.
var dragdropwrapper = function(node) {
this.node = node;
}
// Method e.drag.get() - get the node.
dragdropwrapper.prototype.get = function(param) {
if (param == 'node' || param == 'dragNode' || param == 'dropNode') {
return this.node;
}
return null;
};
// Method e.drag.inGroup() - we have already run the group checks before triggering the event.
dragdropwrapper.prototype.inGroup = function() {
return true;
};
// Method e.drag.addHandle() - we don't want to run this.
dragdropwrapper.prototype.addHandle = function() {};
// Method e.drag.removeHandle() - we don't want to run this.
dragdropwrapper.prototype.removeHandle = function() {};
// Create instances of the dragdropwrapper.
this.drop = new dragdropwrapper(dropnode);
this.drag = new dragdropwrapper(dragnode);
},
/**
* This is used to complete a keyboard version of a drag and drop.
* A drop event will be simulated based on the drag and drop nodes.
@ -337,21 +379,16 @@ YUI.add('moodle-core-dragdrop', function(Y) {
var dragcontainer = M.core.dragdrop.keydragcontainer;
dragcontainer.setAttribute('aria-grabbed', 'false');
// The real drop node is stored in an attribute of the proxy.
var dragtarget = Y.one('#' + e.target.getAttribute('data-drop-target'));
var droptarget = Y.one('#' + e.target.getAttribute('data-drop-target'));
// Close the dialog.
M.core.dragdrop.dropui.hide();
// Cancel the event.
e.preventDefault();
// Convert to a drag drop event.
e.drag = dragcontainer.drop;
e.drop = new Y.DD.Drop({
node: dragtarget,
groups : this.groups
});
this.global_drop_over(e);
this.global_drop_hit(e);
var dropevent = new this.simulated_drag_drop_event(dragcontainer, droptarget);
this.global_drop_over(dropevent);
this.global_drop_hit(dropevent);
M.core.dragdrop.keydraghandle.focus();
},