- From: Anne van Kesteren <annevk@opera.com>
- Date: Fri, 17 Feb 2012 10:37:03 +0100
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