# Drag and Drop Design Specification

Created on 2005-07-22 by Paul Sowden.

- Preface
- Requirements
- `DragSource` Interface
  - Interface
- `DragObject` Interface
  - Interface
- `DropTarget` Interface
  - Interface
- Provided Implementations
- References

## Preface

Drag and Drop intro.

## Use Cases and Requirements

- shopping cart (smarter drop)
- reordering (default?)
  - columns
  - rows
  - moves a clone (intermediate representation, drag icon)
    - option to drag an original
- date drag
  - "drops" a JS object (Date)
- slider (or scrollbar)
  - constrained x/y movement
  - boundry (node?)
- click-hold event, eg. column sorting vs reordering in iTunes

Drag and Drop involves 3 interfaces:

- `DragSource`
- `DragObject`
- `DropTarget`

These can be implemented by objects. There exists a set of implementations provided to do certain tasks (eg. reordering, moving). Probably in more than 50% of cases the `DragSource` and `DragObject` interfaces are implemented on the same JS Object (or DOM Node) -- ie. the source is the thing being dragged. Only in more complex widgets where several types can be dragged out or widgets such as the date picker will they be different.

Markup syntax; two attributes `dojoDrag` and `dojoDrop`. The values of these attributes are "drag types". The tags cause the DOM Nodes to inherit a certain provided implementation, where the `DragSource` and `DragObject` interfaces both exist on the drag source.

draggin

The three interfaces correspond to the three stages of a drag and drop operation, the start (`onmousedown` and sometimes hold), the middle (`onmousemove`) and the end (`onmouseup`).

## `DragSource` Interface

This interface needs to provide ways to:

- Provide arbitrary `DragObjects`, default is the `DragSource`
- Specify whether to drag a intermediate representation (cloneNode with opacity; default (IMO)) or the actual node (also, there could be an option for the node to be replaced with a place holder so there is no reflow?)
- A method the `DropTarget` can call to inform what it has done with the drop, allowing the `DragSource` to update itself.

### Interface

    interface DragSource {
      DragObject   ondrag(in DragEvent event);
    };

## `DragObject` Interface

This interface allows the object to define what happens to it during movement, which will mostly be constraining.

- the type of object this is or can provide
- constraints:
  - horizontal/vertical
  - DOM Node dimensions
  - bounding box
  - arbritrary function
- if it doesn't end on an accepting target then; slideback (default), poof, other (taken from OS X)

### Interface

    interface DragObject {
      readonly attribute String[]   dragTypes;
      Node       getDragIcon(); // usually defaults to cloneNode
    };

## `DropTarget` Interface

- the type of objects that can be dropped on this
- enter, move and leave events while the `DragObject` is over the target. These should be used to indicate whether a drop will occur and where possible an indication of what the result of the drop will be.
- indication that a drop is performed

### Interface

    interface DropTarget {
      readonly attribute String[]   acceptedDragTypes;

       // corresponding to the mouseover, mousemove and mouseout
      void              ondragover(in DragEvent event);
      void              ondragmove(in DragEvent event);
      void               ondragout(in DragEvent event);

      void                  ondrop(in DragEvent event);
    };

## Provided Implementations

There should be a set of provided implementations which allow a developer to get off the ground with common use cases with a very small amount of effort. There should be at least as little and prefferably less code required to do the same effects as existing drag libraries, as a gauge of how well ours works.

- reording DOM nodes
- moving DOM nodes to different parents

When I get the undo manager polished off we should also provide undo/redo of drag and drop actions by default. Put that in your pipe and smoke it.

## References

- WHATWG Drag and Drop proposal - drag and drop events tacked onto the DOM event model along with a `draggable` attribute. Clean but limited in the exact same way as the DOM.
- Bindows Drag and Drop tutorial - event driven drag and drop, based on data transfer between components.
- script.aculo.us: the be all end all of Drag and Drop - *shudders*. It certainly has pretty covered.
- Youngpup DOM-Drag: the original Drag and Drop - very much the original, handles dragging of DOM Nodes.