[whatwg] DND: compatibility notes
Anne van Kesteren
annevk at opera.com
Fri Feb 17 01:37:03 PST 2012
The feedback that follows is based on our implementation experience with
drag & drop. The people that ought to be credited for the text below are
Paweł Stanek, Giorgi Chavchanidze, Wilhelm Joys Andersen, and anonymous;
i.e. not me.
During our initial implementation of HTML5 drag and drop, we encountered
many, many cases where browser behaviour differs from each other or the
specification. This message covers the changes where we feel that the
specification either has it right, or where the specification does not
need to say anything (such as where behaviour is expected to be
implementation dependent). It may therefore be of primary interest to
vendors (for bug hunting) and/or the curious (for avoiding the minefield).
=EffectAllowed and dropEffect=
* Firefox and Chrome use the wrong defaults for dropEffect - move instead
of copy for dragging a div, when the effectAllowed is "all" or
* Firefox allows the user to choose "copy" instead of "move" by pressing
Ctrl. Chrome doesn't allow any modifiers, neither does IE. Opera allows
platform integration to decide; gogi implementation uses normal platform
modifier keys for copy/move/link.
* Chrome always gives "none" for implicit dropEffect.
* Chrome makes dropEffect readonly in most cases.
* Firefox chooses to reinitialise dropEffect in dragend to have the same
value it had at the start of drop. Opera and Chrome choose to be
consistent, and accept the last value it had - this is unspecified per
spec, but similar to the specified part about cancelling drags: "set the
current drag operation to the value of the dropEffect attribute of the
DragEvent object's dataTransfer object as it stood after the event
=Dragging inputs and interactive elements=
* We have decided to make certain interactive elements be "special", for
compatibility with other browsers, and user expectations. This is not
covered by the spec. A page is highly unlikely to make an editable element
be draggable but it's quite possible to have an input somewhere inside a
draggable element. The user still wants to be able to select text in that
element and interact normally with it.
* Input/select/textarea/button cannot be dragged.
* ContentEditable elements cannot be dragged.
* Editable SVG elements cannot be dragged.
* Scrollbars must respond as scrollbars, not draggable points.
* Chrome breaks contentEditable when it can be dragged; you cannot drag by
the text of a contentEditable element (only the border), and you cannot
edit it either.
* Firefox allows dragging of a contentEditable element inside a draggable
element, but not when the contentEditable element itself is draggable -
inconsistent and probably a bug in the former case.
* Chrome allows you to drag a select-multiple by its border
* Chrome allows buttons to be drag points, Firefox does not. Easier to be
consistent with all inputs.
* Chrome may randomly allow a readonly input element to be draggable by
its border - not always reproducible bug.
=Dragging files into the browser=
* In Opera and FF, you have to preventDefault on the drop event, or the
browser will correctly open the file *after* handing it to the page. In
Chrome, simply having a drop listener is enough to prevent it opening the
file, which is not spec-compliant.
* On dragover and dragenter, FF does not provide .files at all, while
Opera and Chrome correctly provide a list of 0 files.
* Chrome refuses to use the FileReader to load files when the page is
loaded over file:
* Dragging a folder instead of a file;
* FF manages to load the "file" even though it cannot have contents,
and Opera produce a 0 byte file (or file with size depending on
which immediately fires onerror.
* Chrome and Opera both refuse to drop special folders (depends on
* Chrome drops 0 files when you drop "my documents".
* Firefox and Chrome do nothing if the dropEffect is set to "none". Opera
reverts to default behaviour, which is to open files.
* Chrome does not support addElement
* Firefox fails to add the dragged node into the drag data store elements
* Firefox can only have one element in the drag data store elements list
* Firefox and Chrome repeatedly fire drag and dragover a lot faster than
they should - 16 times per second.
* Firefox and Chrome both fail to work with dropzone
* Firefox and Chrome both allow dropping even if you fail to cancel
dragenter - you only have to cancel dragover (this also means that
dragenter does not fire on body if another element fails to cancel its own
dragenter). This can be seen in some online demos (eg.
<http://html5demos.com/drag>), which correctly cancel it for IE.
* Firefox and Chrome both fail to fire body.ondragenter a second time when
it does not cancel ondragenter, and drag moves from div-as-current-target
* Firefox and Chrome do not convert from "url" to "text/uri-list" with
getData. Chrome seems to assume both are always empty when they are
manually set. Firefox and Opera strip whitespace as expected for 'url',
and Firefox also mistakenly strips fragments. Firefox incorrectly acts as
if convert-to-URL were true when using "text/uri-list".
* Firefox fires dragenter on source node immediately after dragstart
(wrong), as well as after ondrag (right).
* In a document with no elements, Chrome makes the document object be the
current target. Opera and Firefox make it null.
* Firefox litters drop data with custom mimetypes, including one that
leaks paths to dropped files.
* Chrome adds separate entries for "text", "text/plain", "url" and
"text/uri-list" into the .types collection.
Safari does support drag and drop, but its implementation is too
incomplete to be of use for compatibility testing.
* It requires modifiers to be pressed after dragenter (and does not notice
when they are released until the next dragenter) or no drop will be
* It uses supports Shift (move), Ctrl (copy) and Ctrl+Shift (link),
although all are reported as "none" to the drop handler.
* It never seems to copy any text or URLs, ever. The datatype is there,
but getData always returns undefined.
* As well as draggable=true, it also supports -khtml-user-drag:element;
* dataTransfer.types is not provided when dropping files.
* Files actually seem to be dropped (this is the only part that works
correctly), but without FileReader support, they cannot be read.
* .files length is 1 during all events when dropping a file, instead of
just the drop event.
* It can drag selections between inputs (move) or from the page into an
input (copy) - the API is not required for this.
* When dragging a link, it adds an extra dummy URL into the .types
Anne van Kesteren
More information about the whatwg