Places:Drag & Drop
Places' views use the new drag & drop API introduced with Firefox 3.5 (Gecko 1.9.1). See: https://developer.mozilla.org/En/DragDrop/Drag_and_Drop
Toolbar Drag & Drop Handling
Toolbar handles drag & drop on its contained toolbarbuttons, while drag & drop on sub-menupopups (attached to menu type toolbarbuttons) is handled by their own handlers.
dragstart event we special handle containers, we want to drag them only if the gesture is not toward down, since in such a case a container should open to allow for "click, down, release" behavior.
Then we cache the current dragged Places node and activate the controller with a focus event, that's needed to ensure controller is active for the correct view and ready to catch our data.
Then we call the controller's
setDataTransfer method that executes the following tasks:
- Extracts current
DataTransferobject from the event.
- Null the current viewer, this way we won't rebuild the view while wrapping nodes.
- Add the Places node to dragged items, using correct flavor for every node's type.
- restore the viewer.
While moving over the toolbar within a drag session, the
dragover event will ensure the drop indicator bar is correctly positioned, and will automatically open the menu type toolbarbuttons when we drag over them.
PlacesControllerDragHelper.canDrop and the local
_getDropPoint helper to ensure we can drop at a valid insertionPoint.
dragleave event works in a similar way, hiding the indicator bar and setting timers to close menu type toolbarbuttons when we are not anymore dragging over them.
drop event takes care of checking we have a valid drop point, and calls the controller drop helper.
Menu Drag & Drop Handling
Places menupopups use a special popup binding that supports drag & drop.
dragstart we cache the current dragged Places node, set the correct drag action (setting the
effectAllowed property of the
DataTransfer</code object), activate the controller, and finally add data to the <code>DataTransfer object through the controller
setDataTransfer method (See toolbar for a description of how this method is working).
dragleave events get an actual drop point through the
_getDropPoint local helper method, and ensure we can drop inside it through
PlacesControllerDragHelper.canDrop. Based on the results they will show or hide the drop indicator, and open or close popups when overing or leaving a menu node.
drop the current
DataTransfer is cached, we check for a valid dropPoint and call the controller drop helper.
Tree Drag & Drop Handling
The Places Tree View (tree.xml) implements drag & drop event handlers.
dragstart we extract nodes from the tree selection, if any of those is not movable the drag will perform a "copy" operation, so we set the
effectAllowed property of
Then we fill the
DataTransfer object calling the controller's
dragover we call the view's
canDrop method, that will calculate the current drop point and pass correct informations to the treeview.js
canDrop method. That will ensure we can drop in the current position, showing or hiding the drop indicator and opening containers when needed (all of this is handled by
drop the treeview.js drop handler will be called (since we implement
nsINavHistoryResultViewObserver), that will execute:
- Get a valid insertion point
- Call the controller's onDrop helper
Controller Drop Handling Helper
PlacesControllerDragHelper is an helper object providing methods and informations to views.
Every drag & drop event in our views saves the current DataTransfer object (https://developer.mozilla.org/En/DragDrop/DataTransfer) to
PlacesControllerDragHelper.currentDataTransfer. Helper methods will use this cached value to check for drop validity and perform it.
It provides an
onDrop method that performs view-agnostic drop handling.
For each dropped item this method performs the following actions:
- Determine what mime types of objects are being dragged (from the
PlacesControllerDragHelper.currentDataTransfercached object), and compares this list of types supported as droppable with the list of flavors supported by Places' Views (
- In case this is a tab drag & drop converts data to an acceptable flavor.
- Unwrap the data, generate insertion or copy transactions, aggregates the transaction and executes them through the transaction manager.