Title: [87499] trunk
Revision
87499
Author
yael.aha...@nokia.com
Date
2011-05-27 05:37:48 -0700 (Fri, 27 May 2011)

Log Message

webkit should implement the dropzone attribute
https://bugs.webkit.org/show_bug.cgi?id=58210

Reviewed by Tony Chang.

Source/WebCore: 

Add support for dropzone attribute.
http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-dropzone-attribute
If a drag event was not canceled by _javascript_, look for an element with a dropzone attribute.
If there is such an element, and it matches the drag data store, set the action defined by that
element and continue processing the drag and drop operation.

Tests: fast/events/dropzone-001.html
       fast/events/dropzone-002.html
       fast/events/dropzone-003.html
       fast/events/dropzone-004.html

* dom/Clipboard.cpp:
(WebCore::Clipboard::hasFileOfType):
(WebCore::Clipboard::hasStringOfType):
(WebCore::convertDropZoneOperationToDragOperation):
(WebCore::convertDragOperationToDropZoneOperation):
(WebCore::Clipboard::processDropZoneKeyword):
* dom/Clipboard.h:
* html/HTMLAttributeNames.in:
* html/HTMLElement.idl:
* page/EventHandler.cpp:
(WebCore::EventHandler::findDropZone):
(WebCore::EventHandler::updateDragAndDrop):
* page/EventHandler.h:

LayoutTests: 

* fast/events/dropzone-001-expected.txt: Added.
* fast/events/dropzone-001.html: Added.
* fast/events/dropzone-002-expected.txt: Added.
* fast/events/dropzone-002.html: Added.
* fast/events/dropzone-003-expected.txt: Added.
* fast/events/dropzone-003.html: Added.
* fast/events/dropzone-004-expected.txt: Added.
* fast/events/dropzone-004.html: Added.
* fast/events/resources/dropzone.js: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (87498 => 87499)


--- trunk/LayoutTests/ChangeLog	2011-05-27 12:20:46 UTC (rev 87498)
+++ trunk/LayoutTests/ChangeLog	2011-05-27 12:37:48 UTC (rev 87499)
@@ -1,3 +1,20 @@
+2011-05-26  Yael Aharon  <yael.aha...@nokia.com>
+
+        Reviewed by Tony Chang.
+
+        webkit should implement the dropzone attribute
+        https://bugs.webkit.org/show_bug.cgi?id=58210
+
+        * fast/events/dropzone-001-expected.txt: Added.
+        * fast/events/dropzone-001.html: Added.
+        * fast/events/dropzone-002-expected.txt: Added.
+        * fast/events/dropzone-002.html: Added.
+        * fast/events/dropzone-003-expected.txt: Added.
+        * fast/events/dropzone-003.html: Added.
+        * fast/events/dropzone-004-expected.txt: Added.
+        * fast/events/dropzone-004.html: Added.
+        * fast/events/resources/dropzone.js: Added.
+
 2011-05-27  Csaba Osztrogonác  <o...@webkit.org>
 
         [Qt]http/tests/security/xss-DENIED-xsl-document.xml fails with Qt 4.8

Added: trunk/LayoutTests/fast/events/dropzone-001-expected.txt (0 => 87499)


--- trunk/LayoutTests/fast/events/dropzone-001-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/dropzone-001-expected.txt	2011-05-27 12:37:48 UTC (rev 87499)
@@ -0,0 +1,77 @@
+This test checks that drag-and-drop support works and conforms to the HTML 5 specification.
+For each effectAllowed, iterates through the possible dropEffects: none, copy, move, link, dummy.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+When effectAllowed == "uninitialized"
+
+Received drop event for allowedEffect uninitialized and chosenDropEffect none
+Received drop event for allowedEffect uninitialized and chosenDropEffect copy
+Received drop event for allowedEffect uninitialized and chosenDropEffect move
+Received drop event for allowedEffect uninitialized and chosenDropEffect link
+Received drop event for allowedEffect uninitialized and chosenDropEffect dummy
+
+When effectAllowed == "undefined"
+
+Received drop event for allowedEffect undefined and chosenDropEffect none
+Received drop event for allowedEffect undefined and chosenDropEffect copy
+Received drop event for allowedEffect undefined and chosenDropEffect move
+Received drop event for allowedEffect undefined and chosenDropEffect link
+Received drop event for allowedEffect undefined and chosenDropEffect dummy
+
+When effectAllowed == "none"
+
+
+When effectAllowed == "all"
+
+Received drop event for allowedEffect all and chosenDropEffect none
+Received drop event for allowedEffect all and chosenDropEffect copy
+Received drop event for allowedEffect all and chosenDropEffect move
+Received drop event for allowedEffect all and chosenDropEffect link
+Received drop event for allowedEffect all and chosenDropEffect dummy
+
+When effectAllowed == "copy"
+
+Received drop event for allowedEffect copy and chosenDropEffect none
+Received drop event for allowedEffect copy and chosenDropEffect copy
+Received drop event for allowedEffect copy and chosenDropEffect dummy
+
+When effectAllowed == "move"
+
+Received drop event for allowedEffect move and chosenDropEffect move
+
+When effectAllowed == "link"
+
+Received drop event for allowedEffect link and chosenDropEffect link
+
+When effectAllowed == "copyMove"
+
+Received drop event for allowedEffect copyMove and chosenDropEffect none
+Received drop event for allowedEffect copyMove and chosenDropEffect copy
+Received drop event for allowedEffect copyMove and chosenDropEffect move
+Received drop event for allowedEffect copyMove and chosenDropEffect dummy
+
+When effectAllowed == "copyLink"
+
+Received drop event for allowedEffect copyLink and chosenDropEffect none
+Received drop event for allowedEffect copyLink and chosenDropEffect copy
+Received drop event for allowedEffect copyLink and chosenDropEffect link
+Received drop event for allowedEffect copyLink and chosenDropEffect dummy
+
+When effectAllowed == "linkMove"
+
+Received drop event for allowedEffect linkMove and chosenDropEffect move
+Received drop event for allowedEffect linkMove and chosenDropEffect link
+
+When effectAllowed == "dummy"
+
+Received drop event for allowedEffect dummy and chosenDropEffect none
+Received drop event for allowedEffect dummy and chosenDropEffect copy
+Received drop event for allowedEffect dummy and chosenDropEffect move
+Received drop event for allowedEffect dummy and chosenDropEffect link
+Received drop event for allowedEffect dummy and chosenDropEffect dummy
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/events/dropzone-001.html (0 => 87499)


--- trunk/LayoutTests/fast/events/dropzone-001.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/dropzone-001.html	2011-05-27 12:37:48 UTC (rev 87499)
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+<style>
+#dropTarget, #dragMe { text-align: center; display: table-cell; vertical-align: middle }
+#dropTarget {width: 256px; height: 256px; border: 1px dashed}
+#dragMe {-webkit-user-drag: element; -webkit-user-select: none; background: #ff0000; width: 64px; height: 64px; color: white}
+</style>
+<script>
+var dragMe;
+var dropTarget;
+var effectAllowedElem;
+var dropEffectElem;
+var consoleElm;
+var event;
+
+window._onload_ = function()
+{
+    dragMe = document.getElementById("dragMe");
+    dropTarget = document.getElementById("dropTarget");
+    effectAllowedElem = document.getElementById("effectAllowed");
+    dropEffectElem = document.getElementById("dropEffect");
+    consoleElm = document.getElementById("console");
+    
+    if (!dragMe || !dropTarget || !effectAllowedElem || !dropEffectElem || !consoleElm)
+        return;
+    
+    dropEffectElem._onclick_ = changeDropZone;
+    dragMe._ondragstart_ = dragStart;
+    dropTarget._ondrop_ = drop;
+    
+    runTest();
+}
+
+function changeDropZone()
+{
+    dropTarget.setAttribute("webkitdropzone", dropEffectElem.options[dropEffectElem.selectedIndex].value + " s:text/plain");
+}
+
+function dragStart(e)
+{
+    event = e;
+    if (effectAllowedElem.options[effectAllowedElem.selectedIndex].value != "undefined")
+        e.dataTransfer.effectAllowed = effectAllowedElem.options[effectAllowedElem.selectedIndex].value;
+    e.dataTransfer.setData('text/plain', e.target.textContent);
+}
+
+function printDropEvent(e)
+{
+    chosenDropEffect = dropEffectElem.options[dropEffectElem.selectedIndex].value;
+    chosenEffectAllowed = effectAllowedElem.options[effectAllowedElem.selectedIndex].value;
+    debug("Received drop event for allowedEffect " + chosenEffectAllowed + " and chosenDropEffect " + chosenDropEffect);
+}
+
+function runTest()
+{
+    if (!window.eventSender)
+        return;
+        
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+        
+    var startX = dragMe.offsetLeft + 10;
+    var startY = dragMe.offsetTop + dragMe.offsetHeight / 2;
+    var endX = dropTarget.offsetLeft + 10;
+    var endY = dropTarget.offsetTop + dropTarget.offsetHeight / 2;
+    
+    var numEffectAllowed = effectAllowedElem.options.length;
+    var numEffects = dropEffectElem.options.length;
+    
+    for (var i = 0; i < numEffectAllowed; ++i) {
+        effectAllowedElem.options[i].selected = true;
+        debug('<br />When effectAllowed == "' + effectAllowedElem.options[i].value + '"<br />');
+        for (var j = 0; j < numEffects; ++j) {
+            dropEffectElem.options[j].selected = true;
+            changeDropZone();
+            
+            eventSender.mouseMoveTo(startX, startY);
+            eventSender.mouseDown();
+            eventSender.leapForward(100);
+            eventSender.mouseMoveTo(endX, endY);
+            eventSender.mouseUp();
+        }
+    }
+    var testContainer = document.getElementById("test-container");
+    if (testContainer)
+        document.body.removeChild(testContainer);
+    debug('<br /><span class="pass">TEST COMPLETE</span>');
+}
+</script>
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="test-container">
+<label for="" <select id="effectAllowed">
+<option value="uninitialized">Uninitialized</option>
+<option value="undefined">Undefined</option>
+<option value="none">None</option>
+<option value="all">All</option>
+<option value="copy">Copy</option>
+<option value="move">Move</option>
+<option value="link">Link</option>
+<option value="copyMove">CopyMove</option>
+<option value="copyLink">CopyLink</option>
+<option value="linkMove">LinkMove</option>
+<option value="dummy">Nonexistent (Dummy) Effect</option>
+</select>
+<br/><br/>
+<div id="dropTarget">Drop the red square onto me.<br/><br/>
+<label for="" dropEffect</label> <select id="dropEffect">
+<option value="none">None</option>
+<option value="copy">Copy</option>
+<option value="move">Move</option>
+<option value="link">Link</option>
+<option value="dummy">Nonexistent (Dummy) Effect</option>
+</select>
+</div>
+<hr/>
+<p>Items that can be dragged to the drop target:</p>
+<div id="dragMe" draggable="true">Square</div>
+<hr/>
+</div>
+<div id="console"></div>
+<script>
+description("This test checks that drag-and-drop support works and conforms to the HTML 5 specification.<br/>" +
+    "For each effectAllowed, iterates through the possible dropEffects: none, copy, move, link, dummy.");
+var successfullyParsed = true;
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/events/dropzone-002-expected.txt (0 => 87499)


--- trunk/LayoutTests/fast/events/dropzone-002-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/dropzone-002-expected.txt	2011-05-27 12:37:48 UTC (rev 87499)
@@ -0,0 +1,12 @@
+This test checks that drag-and-drop support works with images.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Received drop event when chosenDropEffect is copy
+Received drop event when chosenDropEffect is move
+Received drop event when chosenDropEffect is link
+Received drop event when chosenDropEffect is dummy
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/events/dropzone-002.html (0 => 87499)


--- trunk/LayoutTests/fast/events/dropzone-002.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/dropzone-002.html	2011-05-27 12:37:48 UTC (rev 87499)
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+<style>
+#dropTarget, #dragMe { text-align: center; display: table-cell; vertical-align: middle }
+#dropTarget {width: 256px; height: 256px; border: 1px dashed}
+#dragMe {-webkit-user-drag: element; -webkit-user-select: none; background: #ff0000; width: 64px; height: 64px; color: white}
+</style>
+<script>
+var dragMe;
+var dropTarget;
+var dropEffectElem;
+var consoleElm;
+var event;
+
+window._onload_ = function()
+{
+    dragMe = document.getElementById("dragMe");
+    dropTarget = document.getElementById("dropTarget");
+    dropEffectElem = document.getElementById("dropEffect");
+    consoleElm = document.getElementById("console");
+    
+    if (!dragMe || !dropTarget || !dropEffectElem || !consoleElm)
+        return;
+    
+    dropEffectElem._onclick_ = changeDropZone;
+    changeDropZone();
+    dropTarget._ondrop_ = drop;
+    
+    runTest();
+}
+
+function changeDropZone()
+{
+    dropTarget.setAttribute("webkitdropzone", " S:text/plain s:url " + dropEffectElem.options[dropEffectElem.selectedIndex].value);
+}
+
+function printDropEvent(e)
+{
+    chosenDropEffect = dropEffectElem.options[dropEffectElem.selectedIndex].value;
+    debug("Received drop event when chosenDropEffect is " + chosenDropEffect);
+}
+
+function runTest()
+{
+    if (!window.eventSender)
+        return;
+        
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+        
+    var startX = dragMe.offsetLeft + 10;
+    var startY = dragMe.offsetTop + dragMe.offsetHeight / 2;
+    var endX = dropTarget.offsetLeft + 10;
+    var endY = dropTarget.offsetTop + dropTarget.offsetHeight / 2
+    
+    var numEffects = dropEffectElem.options.length;
+    
+    for (var j = 0; j < numEffects; ++j) {
+        dropEffectElem.options[j].selected = true;
+        changeDropZone();
+            
+        eventSender.mouseMoveTo(startX, startY);
+        eventSender.mouseDown();
+        eventSender.leapForward(100);
+        eventSender.mouseMoveTo(endX, endY);
+        eventSender.mouseUp();
+    }
+
+    var testContainer = document.getElementById("test-container");
+    if (testContainer)
+        document.body.removeChild(testContainer);
+    debug('<br /><span class="pass">TEST COMPLETE</span>');
+}
+</script>
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="test-container">
+<div id="dropTarget">Drop the image onto me.<br/><br/>
+<label for="" dropEffect</label> <select id="dropEffect">
+<option value="copy">Copy</option>
+<option value="move">Move</option>
+<option value="link">Link</option>
+<option value="dummy">Nonexistent (Dummy) Effect should be converted to copy</option>
+</select>
+</div>
+<hr/>
+<p>Items that can be dragged to the drop target:</p>
+<img id="dragMe" src=""
+<hr/>
+</div>
+<div id="console"></div>
+<script>
+description("This test checks that drag-and-drop support works with images.<br/>");
+var successfullyParsed = true;
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/events/dropzone-003-expected.txt (0 => 87499)


--- trunk/LayoutTests/fast/events/dropzone-003-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/dropzone-003-expected.txt	2011-05-27 12:37:48 UTC (rev 87499)
@@ -0,0 +1,12 @@
+This test checks that drag-and-drop support works with a elements.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Received drop event when chosenDropEffect is copy
+Received drop event when chosenDropEffect is move
+Received drop event when chosenDropEffect is link
+Received drop event when chosenDropEffect is dummy
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/events/dropzone-003.html (0 => 87499)


--- trunk/LayoutTests/fast/events/dropzone-003.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/dropzone-003.html	2011-05-27 12:37:48 UTC (rev 87499)
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+<style>
+#dropTarget, #dragMe { text-align: center; display: table-cell; vertical-align: middle }
+#dropTarget {width: 256px; height: 256px; border: 1px dashed}
+#dragMe {-webkit-user-drag: element; -webkit-user-select: none; background: #ff0000; width: 64px; height: 64px; color: white}
+</style>
+<script>
+var dragMe;
+var dropTarget;
+var dropEffectElem;
+var consoleElm;
+var event;
+
+window._onload_ = function()
+{
+    dragMe = document.getElementById("dragMe");
+    dropTarget = document.getElementById("dropTarget");
+    dropEffectElem = document.getElementById("dropEffect");
+    consoleElm = document.getElementById("console");
+    
+    if (!dragMe || !dropTarget || !dropEffectElem || !consoleElm)
+        return;
+    
+    dropEffectElem._onclick_ = changeDropZone;
+    changeDropZone();
+    dropTarget._ondrop_ = drop;
+    
+    runTest();
+}
+
+function changeDropZone()
+{
+    dropTarget.setAttribute("webkitdropzone", dropEffectElem.options[dropEffectElem.selectedIndex].value + " s:text/plain s:any/type");
+}
+
+function printDropEvent(e)
+{
+    chosenDropEffect = dropEffectElem.options[dropEffectElem.selectedIndex].value;
+    debug("Received drop event when chosenDropEffect is " + chosenDropEffect);
+}
+
+function runTest()
+{
+    if (!window.eventSender)
+        return;
+        
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+        
+    var startX = dragMe.offsetLeft + 10;
+    var startY = dragMe.offsetTop + dragMe.offsetHeight / 2;
+    var endX = dropTarget.offsetLeft + 10;
+    var endY = dropTarget.offsetTop + dropTarget.offsetHeight / 2
+    
+    var numEffects = dropEffectElem.options.length;
+    
+    for (var j = 0; j < numEffects; ++j) {
+        dropEffectElem.options[j].selected = true;
+        changeDropZone();
+            
+        eventSender.mouseMoveTo(startX, startY);
+        eventSender.mouseDown();
+        eventSender.leapForward(100);
+        eventSender.mouseMoveTo(endX, endY);
+        eventSender.mouseUp();
+    }
+
+    var testContainer = document.getElementById("test-container");
+    if (testContainer)
+        document.body.removeChild(testContainer);
+    debug('<br /><span class="pass">TEST COMPLETE</span>');
+}
+</script>
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="test-container">
+<div id="dropTarget">Drop the anchor onto me.<br/><br/>
+<label for="" dropEffect</label> <select id="dropEffect">
+<option value="copy">Copy</option>
+<option value="move">Move</option>
+<option value="link">Link</option>
+<option value="dummy">Nonexistent (Dummy) Effect should be converted to copy</option>
+</select>
+</div>
+<hr/>
+<p>Items that can be dragged to the drop target:</p>
+<a href="" id="dragMe"></a>
+<hr/>
+</div>
+<div id="console"></div>
+<script>
+description("This test checks that drag-and-drop support works with a elements.<br/>");
+var successfullyParsed = true;
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/events/dropzone-004-expected.txt (0 => 87499)


--- trunk/LayoutTests/fast/events/dropzone-004-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/events/dropzone-004-expected.txt	2011-05-27 12:37:48 UTC (rev 87499)
@@ -0,0 +1,10 @@
+This test checks that drag-and-drop support works with files.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Received drop event when chosenDropEffect is copy
+Received drop event when chosenDropEffect is dummy
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/events/dropzone-004.html (0 => 87499)


--- trunk/LayoutTests/fast/events/dropzone-004.html	                        (rev 0)
+++ trunk/LayoutTests/fast/events/dropzone-004.html	2011-05-27 12:37:48 UTC (rev 87499)
@@ -0,0 +1,92 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+<style>
+#dropTarget { text-align: center; display: table-cell; vertical-align: middle }
+#dropTarget {width: 256px; height: 256px; border: 1px dashed}
+</style>
+<script>
+var dropTarget;
+var dropEffectElem;
+var consoleElm;
+var event;
+
+window._onload_ = function()
+{
+    dropTarget = document.getElementById("dropTarget");
+    dropEffectElem = document.getElementById("dropEffect");
+    consoleElm = document.getElementById("console");
+    
+    if (!dropTarget || !dropEffectElem || !consoleElm)
+        return;
+    
+    dropEffectElem._onclick_ = changeDropZone;
+    changeDropZone();
+    dropTarget._ondrop_ = drop;
+    
+    runTest();
+}
+
+function changeDropZone()
+{
+    dropTarget.setAttribute("webkitdropzone", dropEffectElem.options[dropEffectElem.selectedIndex].value + " f:text/html");
+}
+
+function printDropEvent(e)
+{
+    chosenDropEffect = dropEffectElem.options[dropEffectElem.selectedIndex].value;
+    debug("Received drop event when chosenDropEffect is " + chosenDropEffect);
+}
+
+function runTest()
+{
+    if (!window.eventSender)
+        return;
+        
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+        
+    var endX = dropTarget.offsetLeft + 10;
+    var endY = dropTarget.offsetTop + dropTarget.offsetHeight / 2
+    
+    var numEffects = dropEffectElem.options.length;
+    
+    for (var j = 0; j < numEffects; ++j) {
+        dropEffectElem.options[j].selected = true;
+        changeDropZone();
+            
+        eventSender.beginDragWithFiles(["resources/file-for-prevent-drag-to-navigate.html"]);
+        eventSender.mouseMoveTo(endX, endY);
+        eventSender.mouseUp();
+    }
+
+    var testContainer = document.getElementById("test-container");
+    if (testContainer)
+        document.body.removeChild(testContainer);
+    debug('<br /><span class="pass">TEST COMPLETE</span>');
+}
+</script>
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="test-container">
+<div id="dropTarget">Drop the file onto me.<br/><br/>
+<label for="" dropEffect</label> <select id="dropEffect">
+<option value="copy">Copy</option>
+<option value="move">Move</option>
+<option value="link">Link</option>
+<option value="dummy">Nonexistent (Dummy) Effect should be converted to copy</option>
+</select>
+</div>
+<hr/>
+<hr/>
+</div>
+<div id="console"></div>
+<script>
+description("This test checks that drag-and-drop support works with files.<br/>");
+var successfullyParsed = true;
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/events/resources/dropzone.js (0 => 87499)


--- trunk/LayoutTests/fast/events/resources/dropzone.js	                        (rev 0)
+++ trunk/LayoutTests/fast/events/resources/dropzone.js	2011-05-27 12:37:48 UTC (rev 87499)
@@ -0,0 +1,10 @@
+function drop(e)
+{
+    printDropEvent(e);
+    cancelDrag(e);
+}
+    
+function cancelDrag(e)
+{
+    e.preventDefault();
+}

Modified: trunk/Source/WebCore/ChangeLog (87498 => 87499)


--- trunk/Source/WebCore/ChangeLog	2011-05-27 12:20:46 UTC (rev 87498)
+++ trunk/Source/WebCore/ChangeLog	2011-05-27 12:37:48 UTC (rev 87499)
@@ -1,3 +1,35 @@
+2011-05-26  Yael Aharon  <yael.aha...@nokia.com>
+
+        Reviewed by Tony Chang.
+
+        webkit should implement the dropzone attribute
+        https://bugs.webkit.org/show_bug.cgi?id=58210
+
+        Add support for dropzone attribute.
+        http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-dropzone-attribute
+        If a drag event was not canceled by _javascript_, look for an element with a dropzone attribute.
+        If there is such an element, and it matches the drag data store, set the action defined by that
+        element and continue processing the drag and drop operation.
+
+        Tests: fast/events/dropzone-001.html
+               fast/events/dropzone-002.html
+               fast/events/dropzone-003.html
+               fast/events/dropzone-004.html
+
+        * dom/Clipboard.cpp:
+        (WebCore::Clipboard::hasFileOfType):
+        (WebCore::Clipboard::hasStringOfType):
+        (WebCore::convertDropZoneOperationToDragOperation):
+        (WebCore::convertDragOperationToDropZoneOperation):
+        (WebCore::Clipboard::processDropZoneKeyword):
+        * dom/Clipboard.h:
+        * html/HTMLAttributeNames.in:
+        * html/HTMLElement.idl:
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::findDropZone):
+        (WebCore::EventHandler::updateDragAndDrop):
+        * page/EventHandler.h:
+
 2011-05-27  Patrick Gansterer  <par...@webkit.org>
 
         Unreviewed WinCE build fix for r87467.

Modified: trunk/Source/WebCore/dom/Clipboard.cpp (87498 => 87499)


--- trunk/Source/WebCore/dom/Clipboard.cpp	2011-05-27 12:20:46 UTC (rev 87498)
+++ trunk/Source/WebCore/dom/Clipboard.cpp	2011-05-27 12:37:48 UTC (rev 87499)
@@ -27,6 +27,7 @@
 #include "Clipboard.h"
 
 #include "CachedImage.h"
+#include "FileList.h"
 #include "Frame.h"
 #include "FrameLoader.h"
 #include "Image.h"
@@ -125,6 +126,30 @@
     m_dropEffect = IEOpFromDragOp(op);
 }
 
+bool Clipboard::hasFileOfType(const String& type) const
+{
+    if (m_policy != ClipboardReadable && m_policy != ClipboardTypesReadable)
+        return false;
+    
+    RefPtr<FileList> fileList = files();
+    if (fileList->isEmpty())
+        return false;
+    
+    for (unsigned int f = 0; f < fileList->length(); f++) {
+        if (equalIgnoringCase(fileList->item(f)->type(), type))
+            return true;
+    }
+    return false;
+}
+
+bool Clipboard::hasStringOfType(const String& type) const
+{
+    if (m_policy != ClipboardReadable && m_policy != ClipboardTypesReadable)
+        return false;
+    
+    return types().contains(type); 
+}
+    
 void Clipboard::setDropEffect(const String &effect)
 {
     if (!isForDragAndDrop())
@@ -157,5 +182,45 @@
     if (m_policy == ClipboardWritable)
         m_effectAllowed = effect;
 }
+    
+DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation)
+{
+    if (dragOperation == "copy")
+        return DragOperationCopy;
+    if (dragOperation == "move")
+        return DragOperationMove;
+    if (dragOperation == "link")
+        return DragOperationLink;
+    return DragOperationNone;
+}
 
+String convertDragOperationToDropZoneOperation(DragOperation operation)
+{
+    switch (operation) {
+    case DragOperationCopy:
+        return String("copy");
+    case DragOperationMove:
+        return String("move");
+    case DragOperationLink:
+        return String("link");
+    default:
+        return String("copy");
+    }
+}
+
+bool Clipboard::hasDropZoneType(const String& keyword)
+{
+    if (keyword.length() < 3 || keyword[1] != ':')
+        return false;
+        
+    switch (keyword[0]) {
+    case 'f':
+        return hasFileOfType(keyword.substring(2));
+    case 's':
+        return hasStringOfType(keyword.substring(2));
+    default:
+        return false;
+    }
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/Clipboard.h (87498 => 87499)


--- trunk/Source/WebCore/dom/Clipboard.h	2011-05-27 12:20:46 UTC (rev 87498)
+++ trunk/Source/WebCore/dom/Clipboard.h	2011-05-27 12:37:48 UTC (rev 87499)
@@ -46,6 +46,7 @@
             CopyAndPaste,
             DragAndDrop,
         };
+        
         static PassRefPtr<Clipboard> create(ClipboardAccessPolicy, DragData*, Frame*);
 
         virtual ~Clipboard() { }
@@ -92,6 +93,8 @@
         void setSourceOperation(DragOperation);
         void setDestinationOperation(DragOperation);
         
+        bool hasDropZoneType(const String&);
+        
         void setDragHasStarted() { m_dragStarted = true; }
 
 #if ENABLE(DATA_TRANSFER_ITEMS)
@@ -104,6 +107,9 @@
         bool dragStarted() const { return m_dragStarted; }
         
     private:
+        bool hasFileOfType(const String&) const;
+        bool hasStringOfType(const String&) const;
+        
         ClipboardAccessPolicy m_policy;
         String m_dropEffect;
         String m_effectAllowed;
@@ -116,6 +122,9 @@
         RefPtr<Node> m_dragImageElement;
     };
 
+    DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation);
+    String convertDragOperationToDropZoneOperation(DragOperation);
+    
 } // namespace WebCore
 
 #endif // Clipboard_h

Modified: trunk/Source/WebCore/html/HTMLAttributeNames.in (87498 => 87499)


--- trunk/Source/WebCore/html/HTMLAttributeNames.in	2011-05-27 12:20:46 UTC (rev 87498)
+++ trunk/Source/WebCore/html/HTMLAttributeNames.in	2011-05-27 12:37:48 UTC (rev 87499)
@@ -92,6 +92,7 @@
 direction
 disabled
 draggable
+webkitdropzone
 enctype
 end
 event

Modified: trunk/Source/WebCore/html/HTMLElement.idl (87498 => 87499)


--- trunk/Source/WebCore/html/HTMLElement.idl	2011-05-27 12:20:46 UTC (rev 87498)
+++ trunk/Source/WebCore/html/HTMLElement.idl	2011-05-27 12:37:48 UTC (rev 87499)
@@ -35,6 +35,7 @@
 
                  attribute long              tabIndex;
                  attribute boolean           draggable;
+                 attribute [Reflect] DOMString webkitdropzone;
                  attribute [Reflect] boolean hidden;
 
         // Extensions

Modified: trunk/Source/WebCore/page/EventHandler.cpp (87498 => 87499)


--- trunk/Source/WebCore/page/EventHandler.cpp	2011-05-27 12:20:46 UTC (rev 87498)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2011-05-27 12:37:48 UTC (rev 87499)
@@ -1789,6 +1789,42 @@
     return canHandle;
 }
 
+static bool findDropZone(Node* target, Clipboard* clipboard)
+{
+    Element* element = target->isElementNode() ? toElement(target) : target->parentElement();
+    for (; element; element = element->parentElement()) {
+        bool matched = false;
+        String dropZoneStr = element->fastGetAttribute(webkitdropzoneAttr);
+
+        if (dropZoneStr.isEmpty())
+            continue;
+        
+        dropZoneStr.makeLower();
+        
+        SpaceSplitString keywords(dropZoneStr, false);
+        if (keywords.isNull())
+            continue;
+        
+        DragOperation dragOperation = DragOperationNone;
+        for (unsigned int i = 0; i < keywords.size(); i++) {
+            DragOperation op = convertDropZoneOperationToDragOperation(keywords[i]);
+            if (op != DragOperationNone) {
+                if (dragOperation == DragOperationNone)
+                    dragOperation = op;
+            } else
+                matched = matched || clipboard->hasDropZoneType(keywords[i].string());
+
+            if (matched && dragOperation != DragOperationNone)
+                break;
+        }
+        if (matched) {
+            clipboard->setDropEffect(convertDragOperationToDropZoneOperation(dragOperation));
+            return true;
+        }
+    }
+    return false;
+}
+    
 bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
 {
     bool accept = false;
@@ -1819,6 +1855,8 @@
                 dispatchDragSrcEvent(eventNames().dragEvent, event);
             }
             accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard);
+            if (!accept)
+                accept = findDropZone(newTarget, clipboard);
         }
 
         if (m_dragTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, m_dragTarget.get(), event, clipboard, &accept))
@@ -1837,6 +1875,8 @@
                 dispatchDragSrcEvent(eventNames().dragEvent, event);
             }
             accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard);
+            if (!accept)
+                accept = findDropZone(newTarget, clipboard);
             m_shouldOnlyFireDragOverEvent = false;
         }
     }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to