[whatwg] DND: compatibility notes

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  
"uninitialized".

* 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  
dispatch finished".

=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,  
Chrome
     and Opera produce a 0 byte file (or file with size depending on  
platform)
     which immediately fires onerror.
   * Chrome and Opera both refuse to drop special folders (depends on  
platform).
   * 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.

=Other problems=

* Chrome does not support addElement

* Firefox fails to add the dragged node into the drag data store elements  
list

* 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  
onto body

* 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=

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  
allowed.

* 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  
collection


-- 
Anne van Kesteren
http://annevankesteren.nl/

Received on Friday, 17 February 2012 01:37:03 UTC