From ade4695de09f68e0b1b4971170a47503ac60d5f4 Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Sun, 4 Aug 2013 22:11:22 +0800 Subject: [PATCH] MDL-36002 dragdrop: Add simulated event for keyboard drag drop. This is to prevent any accidental state change in Y.DD.DDM. --- lib/yui/dragdrop/dragdrop.js | 79 ++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/lib/yui/dragdrop/dragdrop.js b/lib/yui/dragdrop/dragdrop.js index 3fdec8e20cf..2f612208392 100644 --- a/lib/yui/dragdrop/dragdrop.js +++ b/lib/yui/dragdrop/dragdrop.js @@ -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(); }, -- 2.43.0