<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff">
<font size="-1">Hi,<br>
<br>
</font><font size="-1">After having a bug while trying to implement a
browser-based chess game using the native Drag&Drop API, I have
decided to investigate a bit on this API, examples and opinions.<br>
There is already a very good explanation of the current state of the
API and how to use it here :<a class="moz-txt-link-freetext"
href="http://html5doctor.com/native-drag-and-drop/">
http://html5doctor.com/native-drag-and-drop/</a><br>
<br>
And here is a quite "biased" opinion on the API :<br>
<a class="moz-txt-link-freetext"
href="http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html">http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html</a><br>
Even if I would use the same words, my reaction has roughly been the
same (for those who wouldn't have the time to read the article, its
author is furious about the API) while implementing an example. From my
experience as a web author writing the chess game, I have found
completely counter-intuitive to have to register a listener to the
dragover event only to ".preventDefault()" the event. <br>
In my humble opinion, .preventDefault should be used really when the
default behavior (triggered either because of the spec imposes so or
because of the user agent implementation) goes against the web app
needs.<br>
I think a very good example of this is Wikidot (a wiki engine) on
which, if I remember well, you can save the page you're editing by
doing Ctrl+S. In most web browsers, Ctrl+S opens a menu to save the
HTML page. I have never looked at their code, but it's very likely that
for Ctrl+S, they have decided to prevent the default behavior, which
makes sense.</font><font size="-1"><br>
<br>
<br>
To be slightly more structured, I am going to continue this e-mail
following this outline :<br>
- From where to where ?<br>
-- Same document</font><font size="-1"><br>
-- Document <---> Desktop</font><br>
<font size="-1">-- Different documents<br>
- Influences of the drag&drop API<br>
- Misc feedback<br>
<br>
<br>
_From where to where ?_<br>
In my opinion, a part of the confusion on the D&D API comes from
the fact that Drag & Drop can actually have different "meanings"
depending on the way the drag and drop is intended to be used. Even if
clearly stated by the spec that "this specification does not define
exactly what a drag-and-drop operation actually is.", I think that
there are a lot of things that should be said and distinguished. For
instance, when I read "drag-and-drop operations must have a starting
point", I think it should be explicitely mentionned that this starting
point can be either from a document (fully falling under the definition
of this spec) or from outside of it (like when you want to drop files
in your web browser). The same for the ending point. All the
combinations can be listed (tell me if I forget one) :<br>
- FROM a document TO the same document<br>
- FROM a document TO another document (there are a lot of different
cases)<br>
- FROM a document TO outside<br>
- FROM outside TO a document<br>
<br>
<br>
__Same document__<br>
The "same document" use case is the one I fall into with my chess game.
I want to drag and drop pieces from one square to another and writing
my application with the conviniency of the all the drag* / drop events
(and not struggling with mouseup/down/move and changing the top and
left style attributes). In this use case like in other, one main
concern of the drag&drop operation is to transfer data from one
point to another. That is supposed to be the dataTransfer object
purpose. However, for the "same document use case" the dataTransfer
object is pointless since you can make communicate your handlers
through an object. Accelerated example :<br>
(function(){<br>
var drag = document.getElementById('drag'); // has the draggable
attribute to true, obviously<br>
var drop = </font><font size="-1">document.getElementById('drop');</font><br>
<font size="-1"> var dragInfo = {};<br>
</font><font size="-1"><br>
function </font><font size="-1">dragStartHandler(e){ // This
function is a closure using the dragInfo object<br>
dragInfo.blabla = 'hello world !';<br>
// dragInfo is an ECMAScript object which is less restrictive
than the dataTransfer object<br>
}<br>
<br>
</font><font size="-1">function </font><font size="-1">dropHandler(e){
</font><font size="-1">// This function is a closure using the dragInfo
object</font><br>
<font size="-1"> alert(dragInfo.blabla);<br>
}</font><br>
<font size="-1"><br>
drag.addEventListener('dragstart', dragStartHandler, false);</font><font
size="-1"><br>
drop.addEventListener('drop', dropHandler, false);</font><font
size="-1"></font><font size="-1"><br>
drop.addEventListener('dragover', function(e){e.preventDefault();},
false);<br>
})();<br>
<br>
In my opinion, a lot of early examples of usage of the API (including
but not limited to : <a class="moz-txt-link-freetext" href="http://ljouanneau.com/lab/html5/demodragdrop.html">http://ljouanneau.com/lab/html5/demodragdrop.html</a>
, <a class="moz-txt-link-freetext" href="http://decafbad.com/blog/2009/07/15/html5-drag-and-drop">http://decafbad.com/blog/2009/07/15/html5-drag-and-drop</a>) advertise
the usage of dataTransfer even for the cases when this is (in my
opinion) useless and I hope that my example is a sufficient proof.<br>
The provided example in the spec seems to be written in a way that make
think that drag and drop operations occur within the same document
(it's never written specifically). If it's the case, I think that a
different example should be provided without dataTransfer.<br>
<br>
<br>
__</font><font size="-1">Document <---> Desktop</font><font
size="-1">__<br>
This use case is actually the one that really requires the dataTransfer
object espescially the recent "files" attribute. As opposed to the
previous use case, this one may have main security issues and
restrictions due to the terra incognita that "outside of the document"
can be.<br>
</font><font size="-1">A very good example of usage :
<a class="moz-txt-link-freetext" href="http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/">http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/</a></font><br>
<font size="-1"><br>
<br>
__Different documents__<br>
There are several cases that could be considered. I am not sure I will
think of all. Add other if you think they are relevant.<br>
<br>
___Common "iframe tree" ancestor___<br>
If two documents are "discussing" through a drag and drop operation and
if they are enclosed in iframes (either one contains the other or they
have a common ancestor), then, the dataTransfer could certainly allow
the transfer of "up to" DOM Elements since we stay in the same user
agent and there is a common document. (Web developers will have to be
careful of Node ownerDocument, but we don't really care about that now).<br>
<br>
___Different documents within the same user agent___<br>
I don't have enough knowledge to discuss this point. Maybe that
implementors will have ideas on this one. At least, user agent can have
user-agent-specific attributes for the dataTransfer object<br>
<br>
___Different documents across different user agents___<br>
Once again, this goes beyond my knowledge. There is certainly no way
for a user agent to know if the drop has been originated from another
(HTML5-compliant :-) ) user agent. Even if it was the case, it would
probably be a security issue since the dataTransfer could be crafted. <br>
<br>
<br>
Let's stay within the same user for the moment.<br>
___Different document, same origin___<br>
___Different document, different origin___<br>
Maybe it'd be convenient to know where a drop comes from. Restrictions
could be applied by the user agent if the dataTransfer comes from a
different-origin document. On the other hand, a lot could be allowed if
the document has the same origin. At least, some attribute could be
added for the origin as it is done with the cross-document
communication.<br>
<br>
<br>
<br>
<br>
- Influences of the Drag and Drop API<br>
As far as I know, the current API is mostly influenced by the IE5+ API.
<br>
10 years later, a lot have been done on the web regarding drag and
drop. Most of the JavaScript libraries have a drag&drop feature.
This is actually how I have first developed a drag & drop feature
for a web app, hence my frustration when trying to use the native API
for the "same document" use case.<br>
The librairies have different models, but a lot in common. I don't know
them by heart and them all neither, but it would probably be
interesting to have a look at the different features they offer and
maybe review the native drag and drop API to consider if these
librairies can implement their features through the native API . <br>
Here is the documentation from four main libraries with a D&D
feature :<br>
</font><font size="-1"><br>
script.aculo.us : <br>
<a class="moz-txt-link-freetext"
href="http://wiki.github.com/madrobby/scriptaculous/draggables-object">http://wiki.github.com/madrobby/scriptaculous/draggables-object</a><br>
<a class="moz-txt-link-freetext"
href="http://wiki.github.com/madrobby/scriptaculous/droppables">http://wiki.github.com/madrobby/scriptaculous/droppables</a><br>
<a class="moz-txt-link-freetext"
href="http://wiki.github.com/madrobby/scriptaculous/draggable">http://wiki.github.com/madrobby/scriptaculous/draggable</a><br>
<br>
jQuery UI :<br>
<a class="moz-txt-link-freetext"
href="http://jqueryui.com/demos/draggable/">http://jqueryui.com/demos/draggable/</a><br>
<a class="moz-txt-link-freetext"
href="http://jqueryui.com/demos/droppable/">http://jqueryui.com/demos/droppable/</a><br>
<br>
Mootools :<br>
<a class="moz-txt-link-freetext"
href="http://mootools.net/docs/more/Drag/Drag">http://mootools.net/docs/more/Drag/Drag</a><br>
<br>
YUI :<br>
<a class="moz-txt-link-freetext"
href="http://developer.yahoo.com/yui/3/api/Drag.html">http://developer.yahoo.com/yui/3/api/Drag.html</a><br>
</font><br>
<font size="-1">Among the things in common, I think that there is the
fact of explicitly declaring which elements are drop targets. In
jQueryUI, draggable elements are distinguished by the ui-draggable
class. Symetrically, droppable elements have the ui-droppable class.<br>
I think that it would make sense that "draggable" and "droppable"
elements have some common features. For instance, it's easy to refer to
draggable elements in CSS since there is an attribute with the selector
*[draggable="true"] (I'm not sure of how CSS work for boolean
attribute. Moving on...). On the other hand, to stylize specifically
droppable elements, you'd have to be very careful on which elements
handle the drop event (and .preventDefault() the dragover event !!) or
not and "manually" update a class on the element. For that matter, a
droppable attribute could be beneficial.<br>
<br>
<br>
_Misc feedback_<br>
* Regardless if the D&D spec example is changed (or another one
added for the "same document" use case without dataTransfer), please
add a comment next to the </font><font size="-1">"event.preventDefault();"
of the </font><font size="-1">dragOverHandler function to explain that
the purpose of this is to define a drop target.<br>
* I am worried about the effectAllowed attribute. Needless to say that
the number of value is exponencially proportional to the number of
possible values for the dropEffect attribute. Wouldn't it be better to
have a linear number of booleans ?<br>
* About all the drag feedback generation, I am doubting that the
current API allows the rich effects that the JS librairies provide. <br>
Do anyone have enough experience with these to tell if they see use
cases covered by the librairies that the native API wouldn't allow to
cover ?<br>
<br>
<br>
I have seen in whatwg.org/issues that drag and drop is
"delayed-awaiting-more-implementation-experience". I haven't seen a
wiki page on <a class="moz-txt-link-freetext" href="http://wiki.whatwg.org/wiki/">http://wiki.whatwg.org/wiki/</a> though. Is there one ? Should
one be created to gather all the feedback and relevant resources
regarding D&D?<br>
<br>
Thanks for reading this quite long e-mail!<br>
Comments, questions and input on places where I have lacking
skill/knowledge/experience are the most welcome !<br>
<br>
David</font><font size="-1"><br>
</font>
</body>
</html>