[whatwg] DND: spec not matching implementations

The feedback that follows is based on our implementation experience with  
drag & drop. The people that ought to be credited for the report 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  
some situations where the current specification either does not reflect  
useful behaviour of existing implementations, or is not yet complete  
enough to base the implementation on it (eg. synthetic events). There are  
also some limitations of the specification for which we feel a change is  
best. The most minor cases are listed in this message. Other messages will  
follow with the details of more extensive changes.

* Firefox, Chrome and Opera only allow dragend to delete ranges during a  
'move' if the range exists within an editable element. The spec needs to  
change to reflect this - currently it expects this anywhere within a  
non-editable document.

* Firefox, Chrome and Opera allow dropping in all text based inputs (text  
search tel url email password number) not just text.

* Firefox, Chrome and Opera all make .effectAllowed writeable only when  
the data store is in read/write mode, so that only the source node has the  
ability to set the effectAllowed.

* Opera and Firefox have chosen to implement modifiers at the point of  
dropEffect initialization during dragenter and dragover: initially set  
dropEffect to the default value specified in the spec table, then if the  
platform requests something else with a modifier, set the dropEffect to  
that modified value. Therefore those events see the modified dropEffect  
(which seems to be the intention of the spec), and can also override it by  
writing to the dropEffect property.

* When dragging selections, Firefox, Chrome and Opera populate text/html  
with the minimal markup intersected by the selection (the smallest  
possible markup that contains all of the selection, without any parent  
elements that contain both ends of the selection).

* Opera populates text/html when dragging an element. This means that it  
is possible to drag HTML into another application without needing  
JavaScript.

* Opera recognises dropzone on parent elements of the immediate user  
selection - the spec currently requires it to be the specific element,  
which means that child elements of the dropzone are not within the  
dropzone. This implementation is as simple as replacing this line in the  
specification:
"If the immediate user selection is an element with a dropzone attribute  
that matches the drag data store -> Set the current target element to the  
immediate user selection anyway."
With this line:
"If the immediate user selection is an element with a dropzone attribute  
that matches the drag data store, or if the immediate user selection has  
an ancestor element with a dropzone attribute that matches the drag data  
store -> Set the current target element to the immediate user selection  
anyway."

* When there is no body, Opera uses the root node as the fallback target  
(when the immediate user selection does not cancel dragenter). If there is  
no root node, Opera uses null. This allows documents with no body to  
function correctly, where the spec reverts to using the document object.  
This means that when subsequently moving the drag over another  
non-cancelling element, it will once again fire dragenter at the document.  
And again when the mouse drags over another non-cancelling element, etc.  
etc.

Our proposal is to replace this:

"If the current target element is the body element"

with this:

If the current target element is the body element, or if there is no body  
element and the current target is the html element

And then replace this:

"Otherwise; Fire a DND event named dragenter at the body element, if there  
is one, or at the Document object, if not. Then, and set the current  
target element to the body element, regardless of whether that event was  
canceled or not."

with this:

If the body element or html element exist; Fire a DND event named  
dragenter at the first of the following objects that exists, and set the  
current target element to that object regardless of whether that event was  
canceled or not:
* The body element
* The html element [interpreted as the root node in non-html documents]
Otherwise; set the current target element to null

(Note that it is possible for a document containing an immediate user  
selection to have neither a body element nor a root element, if the  
dragenter event handler for the immediate user selection deletes the root  
element.)


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

Received on Friday, 17 February 2012 01:31:55 UTC