[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

rolandsteiner at chromium.org rolandsteiner at chromium.org
Thu Apr 8 02:18:22 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit c8cdfb935e16e17365024a5536ed13dd5538f296
Author: rolandsteiner at chromium.org <rolandsteiner at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Mar 10 06:23:17 2010 +0000

    Bug 28293 -  [Chromium] event.datatransfer.getdata("text/uri-list") is treated the same as getdata("URL")
    https://bugs.webkit.org/show_bug.cgi?id=28293
    
    Reviewed by David Levin.
    
    WebCore:
    
    Change ChromiumDataObject such that it treats types "URL" and "text/uri-list"
    correctly for event.dataTransfer.getData/setData. Currently both are treated
    as synonyms, but for "URL", getData is supposed to only return the first valid URL
    contained within the data for "text/uri-list" (see HTML5 spec).
    
    Tests: editing/pasteboard/dataTransfer-setData-getData.html
    
    * platform/chromium/ChromiumDataObject.cpp:
    (WebCore::ChromiumDataObject::clear):
    (WebCore::ChromiumDataObject::clearAllExceptFiles):
    (WebCore::ChromiumDataObject::hasData):
    (WebCore::ChromiumDataObject::ChromiumDataObject):
    * platform/chromium/ChromiumDataObject.h:
    (WebCore::ChromiumDataObject::clearURL):
    (WebCore::ChromiumDataObject::hasValidURL):
    (WebCore::ChromiumDataObject::getURL):
    (WebCore::ChromiumDataObject::setURL):
    * platform/chromium/ClipboardChromium.cpp:
    (WebCore::):
    (WebCore::clipboardTypeFromMIMEType):
    (WebCore::ClipboardChromium::clearData):
    (WebCore::ClipboardChromium::getData):
    (WebCore::ClipboardChromium::setData):
    (WebCore::ClipboardChromium::types):
    * platform/chromium/DragDataChromium.cpp:
    (WebCore::DragData::asURL):
    (WebCore::DragData::canSmartReplace):
    
    WebKit/chromium:
    
    Change ChromiumDataObject such that it treats types "URL" and "text/uri-list"
    correctly for event.dataTransfer.getData/setData. Currently both are treated
    as synonyms, but for "URL", getData is supposed to only return the first valid URL
    contained within the data for "text/uri-list" (see HTML5 spec).
    
    Tests: editing/pasteboard/dataTransfer-setData-getData.html
    
    * src/WebDragData.cpp:
    (WebKit::WebDragData::url):
    (WebKit::WebDragData::setURL):
    
    LayoutTests:
    
    Change ChromiumDataObject such that it treats types "URL" and "text/uri-list"
    correctly for event.dataTransfer.getData/setData. Currently both are treated
    as synonyms, but for "URL", getData is supposed to only return the first valid URL
    contained within the data for "text/uri-list" (see HTML5 spec).
    
    Layout test checks various combinations in a drag-n-drop operation.
    Skipping on all other platforms since they don't implement this correctly, either.
    
    * editing/pasteboard/dataTransfer-setData-getData.html: Added.
    * editing/pasteboard/script-tests/dataTransfer-setData-getData.js: Added.
    (dragTarget):
    (moveMouseToCenterOfElement):
    (dragOntoDragTarget):
    (doDrop):
    (test):
    (runTest):
    * platform/mac/Skipped:
    * platform/gtk/Skipped:
    * platform/qt/Skipped:
    * platform/win/Skipped:
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55766 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index e4ef7d8..9d47289 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,31 @@
+2010-03-10  Roland Steiner  <rolandsteiner at chromium.org>
+
+        Reviewed by David Levin.
+
+        Bug 28293 -  [Chromium] event.datatransfer.getdata("text/uri-list") is treated the same as getdata("URL")
+        https://bugs.webkit.org/show_bug.cgi?id=28293
+        
+        Change ChromiumDataObject such that it treats types "URL" and "text/uri-list"
+        correctly for event.dataTransfer.getData/setData. Currently both are treated
+        as synonyms, but for "URL", getData is supposed to only return the first valid URL
+        contained within the data for "text/uri-list" (see HTML5 spec).
+        
+        Layout test checks various combinations in a drag-n-drop operation.
+        Skipping on all other platforms since they don't implement this correctly, either.
+
+        * editing/pasteboard/dataTransfer-setData-getData.html: Added.
+        * editing/pasteboard/script-tests/dataTransfer-setData-getData.js: Added.
+        (dragTarget):
+        (moveMouseToCenterOfElement):
+        (dragOntoDragTarget):
+        (doDrop):
+        (test):
+        (runTest):
+        * platform/mac/Skipped:
+        * platform/gtk/Skipped:
+        * platform/qt/Skipped:
+        * platform/win/Skipped:
+
 2010-03-09  Tony Chang  <tony at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/editing/pasteboard/dataTransfer-setData-getData-expected.txt b/LayoutTests/editing/pasteboard/dataTransfer-setData-getData-expected.txt
new file mode 100644
index 0000000..063a6bb
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/dataTransfer-setData-getData-expected.txt
@@ -0,0 +1,34 @@
+Tests correct behavior of event.dataTransfer.setData/getData for 'URL', 'text/uri-list' and 'text/plain'
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+--- Test set/get 'URL':
+PASS getDataResultType is "string"
+PASS getDataLines.length is 1
+PASS getDataLines[0].replace(/\/$/, '') is "http://test.com"
+--- Test set/get 'text/uri-list':
+PASS getDataResultType is "string"
+PASS getDataLines.length is 2
+PASS getDataLines[0].replace(/\/$/, '') is "http://test.com"
+PASS getDataLines[1].replace(/\/$/, '') is "http://check.com"
+--- Test set 'text/uri-list', get 'URL':
+PASS getDataResultType is "string"
+PASS getDataLines.length is 1
+PASS getDataLines[0].replace(/\/$/, '') is "http://test.com"
+--- Test set 'text/uri-list', get 'URL', using only '\n':
+PASS getDataResultType is "string"
+PASS getDataLines.length is 1
+PASS getDataLines[0].replace(/\/$/, '') is "http://test.com"
+--- Test set/get 'text/uri-list' with comments:
+PASS getDataResultType is "string"
+PASS getDataLines.length is 2
+PASS getDataLines[0].replace(/\/$/, '') is "http://test.com"
+PASS getDataLines[1].replace(/\/$/, '') is "http://check.com"
+--- Test set/get 'text/plain':
+PASS getDataResultType is "string"
+PASS getDataLines.length is 1
+PASS getDataLines[0].replace(/\/$/, '') is "Lorem ipsum dolor sit amet."
+PASS successfullyParsed is true
+
+TEST COMPLETE
diff --git a/LayoutTests/editing/pasteboard/dataTransfer-setData-getData.html b/LayoutTests/editing/pasteboard/dataTransfer-setData-getData.html
new file mode 100644
index 0000000..b457fa2
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/dataTransfer-setData-getData.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src="script-tests/dataTransfer-setData-getData.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/editing/pasteboard/script-tests/dataTransfer-setData-getData.js b/LayoutTests/editing/pasteboard/script-tests/dataTransfer-setData-getData.js
new file mode 100644
index 0000000..f10d785
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/script-tests/dataTransfer-setData-getData.js
@@ -0,0 +1,122 @@
+description("Tests correct behavior of event.dataTransfer.setData/getData for 'URL', 'text/uri-list' and 'text/plain'");
+
+// Important that we put these at the top of the doc so that logging does not cause it to go out of view (and be undragable)
+var dragMe = document.createElement("div");
+dragMe.innerHTML = "<span id='dragme'>Drag me</span>";
+document.body.insertBefore(dragMe, document.body.firstChild);
+var dragTarget = document.createElement("div");
+dragTarget.innerHTML = "Drag here"
+dragTarget.style.backgroundColor = "blue";
+dragTarget.style.width = "100px";
+dragTarget.style.height = "100px";
+document.body.insertBefore(dragTarget, dragMe);
+
+var setDataType;
+var setDataValues;
+var getDataType;
+var getDataValues;
+var getDataResult;
+var getDataResultType;
+var getDataLines;
+
+var CRLF = "\r\n";
+
+dragMe.addEventListener("dragstart", function() {
+    event.dataTransfer.setData(setDataType, setDataValues.join(CRLF));
+}, false);
+
+dragTarget.addEventListener("dragenter", function() {
+    event.dataTransfer.dropEffect = "copy";
+    event.preventDefault();
+}, false);
+
+dragTarget.addEventListener("dragover", function() {
+    event.dataTransfer.dropEffect = "copy";
+    event.preventDefault();
+}, false);
+
+dragTarget.addEventListener("drop", function() {
+    doDrop();
+    event.preventDefault();
+}, false);
+
+function moveMouseToCenterOfElement(element)
+{
+    var centerX = element.offsetLeft + element.offsetWidth / 2;
+    var centerY = element.offsetTop + element.offsetHeight / 2;
+    eventSender.mouseMoveTo(centerX, centerY);
+}
+
+function dragOntoDragTarget() {
+    var e = document.getElementById("dragme");
+    window.getSelection().setBaseAndExtent(e, 0, e, 4); 
+    x = e.offsetLeft + 10;
+    y = e.offsetTop + e.offsetHeight / 2;
+    eventSender.mouseMoveTo(x, y);
+    eventSender.mouseDown();
+    eventSender.leapForward(400);
+    moveMouseToCenterOfElement(dragTarget);
+    eventSender.mouseUp();
+}
+
+function doDrop() {
+    getDataResult = event.dataTransfer.getData(getDataType);
+    getDataResultType = typeof getDataResult;
+    shouldBeEqualToString("getDataResultType", "string");
+    getDataLines = getDataResult.split(CRLF);    
+    // remove potential comments
+    getDataLines = getDataLines.filter(function(line) {
+      return line[0] !== '#';
+    });
+    shouldEvaluateTo("getDataLines.length", getDataValues.length);
+    for (i = 0; i < getDataLines.length && i < getDataValues.length; ++i) {
+        shouldBeEqualToString("getDataLines[" + i + "].replace(/\\/$/, '')", getDataValues[i]);
+    }
+}
+
+function test(setType, setValues, getType, getValues) {
+    setDataType = setType;
+    setDataValues = setValues;
+    getDataType = getType;
+    getDataValues = getValues;
+    dragOntoDragTarget();
+}
+
+function runTest()
+{
+    debug("--- Test set/get 'URL':");
+    test("URL", ["http://test.com"], 
+         "URL", ["http://test.com"]);
+
+    debug("--- Test set/get 'text/uri-list':");
+    test("text/uri-list", ["http://test.com", "http://check.com"], 
+         "text/uri-list", ["http://test.com", "http://check.com"]);
+
+    debug("--- Test set 'text/uri-list', get 'URL':");
+    test("text/uri-list", ["http://test.com", "http://check.com"], 
+         "URL", ["http://test.com"]);
+
+    debug("--- Test set 'text/uri-list', get 'URL', using only '\\n':");
+    test("text/uri-list", ["http://test.com\nhttp://check.com"], 
+         "URL", ["http://test.com"]);
+
+    debug("--- Test set/get 'text/uri-list' with comments:");
+    test("text/uri-list", ["# comment", "http://test.com", "http://check.com"], 
+         "text/uri-list", ["http://test.com", "http://check.com"]);
+
+    debug("--- Test set/get 'text/plain':");
+    test("text/plain", ["Lorem ipsum dolor sit amet."], 
+         "text/plain", ["Lorem ipsum dolor sit amet."]);
+}
+
+if (window.eventSender) {
+    runTest();
+    // Clean up after ourselves
+    dragMe.parentNode.removeChild(dragMe);
+    dragTarget.parentNode.removeChild(dragTarget);
+} else {
+    testFailed("This test is not interactive, please run using DumpRenderTree");
+}
+
+var successfullyParsed = true;
+
diff --git a/LayoutTests/platform/gtk/Skipped b/LayoutTests/platform/gtk/Skipped
index d54e8ef..01da5e9 100644
--- a/LayoutTests/platform/gtk/Skipped
+++ b/LayoutTests/platform/gtk/Skipped
@@ -5319,6 +5319,7 @@ webarchive/test-td-background.html
 webarchive/test-xml-stylesheet.xml
 
 # Tests that failed because we don't have an eventSender implementation
+editing/pasteboard/dataTransfer-setData-getData.html
 editing/pasteboard/files-during-page-drags.html
 editing/selection/extend-selection-after-double-click.html
 fast/events/drag-to-navigate.html
@@ -5326,9 +5327,9 @@ fast/events/prevent-drag-to-navigate.html
 fast/forms/slider-delete-while-dragging-thumb.html
 fast/events/tab-focus-anchor.html
 http/tests/local/drag-over-remote-content.html
+http/tests/misc/slow-loading-mask.html
 http/tests/security/drag-over-remote-content-iframe.html
 http/tests/security/clipboard/clipboard-file-access.html
-http/tests/misc/slow-loading-mask.html
 
 # Tests that require editing callbacks (and possibly Glib DOM bindings)
 editing/execCommand/indent-with-style.html
diff --git a/LayoutTests/platform/mac/Skipped b/LayoutTests/platform/mac/Skipped
index b1478a7..9c4b36e 100644
--- a/LayoutTests/platform/mac/Skipped
+++ b/LayoutTests/platform/mac/Skipped
@@ -127,4 +127,7 @@ svg/custom/tiling-regular-hexagonal-crash.svg
 fast/events/spatial-navigation
 
 # For some reason crashes when run with all tests. Passes individually.
-fast/forms/multiple-form-submission-protection-mouse.html
\ No newline at end of file
+fast/forms/multiple-form-submission-protection-mouse.html
+
+# event.dataTransfer.setData('text/uri-list') not correctly implemented on Mac
+editing/pasteboard/dataTransfer-setData-getData.html
diff --git a/LayoutTests/platform/qt/Skipped b/LayoutTests/platform/qt/Skipped
index 919e8d8..35125ed 100644
--- a/LayoutTests/platform/qt/Skipped
+++ b/LayoutTests/platform/qt/Skipped
@@ -237,6 +237,7 @@ http/tests/plugins/third-party-cookie-accept-policy.html
 # ============================================================================= #
 
 # ------- missing eventSender.beginDragWithFiles
+editing/pasteboard/dataTransfer-setData-getData.html
 editing/pasteboard/file-input-files-access.html
 fast/dom/Window/window-postmessage-clone.html
 fast/events/drag-to-navigate.html
diff --git a/LayoutTests/platform/win/Skipped b/LayoutTests/platform/win/Skipped
index 738d10d..a1ad061 100644
--- a/LayoutTests/platform/win/Skipped
+++ b/LayoutTests/platform/win/Skipped
@@ -188,6 +188,7 @@ svg/custom/image-with-prefix-in-webarchive.svg
 http/tests/webarchive
 
 # <rdar://problem/5230396> eventSender.beginDragWithFiles is unimplemented
+editing/pasteboard/dataTransfer-setData-getData.html
 editing/pasteboard/file-input-files-access.html
 fast/events/drag-to-navigate.html
 fast/events/prevent-drag-to-navigate.html
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 64c0098..103503b 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,38 @@
+2010-03-10  Roland Steiner  <rolandsteiner at chromium.org>
+
+        Reviewed by David Levin.
+
+        Bug 28293 -  [Chromium] event.datatransfer.getdata("text/uri-list") is treated the same as getdata("URL")
+        https://bugs.webkit.org/show_bug.cgi?id=28293
+        
+        Change ChromiumDataObject such that it treats types "URL" and "text/uri-list"
+        correctly for event.dataTransfer.getData/setData. Currently both are treated
+        as synonyms, but for "URL", getData is supposed to only return the first valid URL
+        contained within the data for "text/uri-list" (see HTML5 spec).
+
+        Tests: editing/pasteboard/dataTransfer-setData-getData.html
+
+        * platform/chromium/ChromiumDataObject.cpp:
+        (WebCore::ChromiumDataObject::clear):
+        (WebCore::ChromiumDataObject::clearAllExceptFiles):
+        (WebCore::ChromiumDataObject::hasData):
+        (WebCore::ChromiumDataObject::ChromiumDataObject):
+        * platform/chromium/ChromiumDataObject.h:
+        (WebCore::ChromiumDataObject::clearURL):
+        (WebCore::ChromiumDataObject::hasValidURL):
+        (WebCore::ChromiumDataObject::getURL):
+        (WebCore::ChromiumDataObject::setURL):
+        * platform/chromium/ClipboardChromium.cpp:
+        (WebCore::):
+        (WebCore::clipboardTypeFromMIMEType):
+        (WebCore::ClipboardChromium::clearData):
+        (WebCore::ClipboardChromium::getData):
+        (WebCore::ClipboardChromium::setData):
+        (WebCore::ClipboardChromium::types):
+        * platform/chromium/DragDataChromium.cpp:
+        (WebCore::DragData::asURL):
+        (WebCore::DragData::canSmartReplace):
+
 2010-03-09  Pavel Feldman  <pfeldman at chromium.org>
 
         Reviewed by Timothy Hatcher.
diff --git a/WebCore/platform/chromium/ChromiumDataObject.cpp b/WebCore/platform/chromium/ChromiumDataObject.cpp
index 77a5f0f..5c67c65 100644
--- a/WebCore/platform/chromium/ChromiumDataObject.cpp
+++ b/WebCore/platform/chromium/ChromiumDataObject.cpp
@@ -35,11 +35,17 @@ namespace WebCore {
 
 void ChromiumDataObject::clear()
 {
+    clearAllExceptFiles();
+    filenames.clear();
+}
+
+void ChromiumDataObject::clearAllExceptFiles()
+{
     url = KURL();
     urlTitle = "";
+    uriList.clear();
     downloadMetadata = "";
     fileExtension = "";
-    filenames.clear();
     plainText = "";
     textHtml = "";
     htmlBaseUrl = KURL();
@@ -51,6 +57,7 @@ void ChromiumDataObject::clear()
 bool ChromiumDataObject::hasData() const
 {
     return !url.isEmpty()
+        || !uriList.isEmpty()
         || !downloadMetadata.isEmpty()
         || !fileExtension.isEmpty()
         || !filenames.isEmpty()
@@ -60,8 +67,7 @@ bool ChromiumDataObject::hasData() const
 }
 
 ChromiumDataObject::ChromiumDataObject(const ChromiumDataObject& other)
-    : url(other.url)
-    , urlTitle(other.urlTitle)
+    : urlTitle(other.urlTitle)
     , downloadMetadata(other.downloadMetadata)
     , fileExtension(other.fileExtension)
     , filenames(other.filenames)
@@ -69,6 +75,8 @@ ChromiumDataObject::ChromiumDataObject(const ChromiumDataObject& other)
     , textHtml(other.textHtml)
     , htmlBaseUrl(other.htmlBaseUrl)
     , fileContentFilename(other.fileContentFilename)
+    , url(other.url)
+    , uriList(other.uriList)
 {
     if (other.fileContent.get())
         fileContent = other.fileContent->copy();
diff --git a/WebCore/platform/chromium/ChromiumDataObject.h b/WebCore/platform/chromium/ChromiumDataObject.h
index 6dea997..625cb8c 100644
--- a/WebCore/platform/chromium/ChromiumDataObject.h
+++ b/WebCore/platform/chromium/ChromiumDataObject.h
@@ -55,9 +55,33 @@ namespace WebCore {
         }
 
         void clear();
+        void clearAllExceptFiles();
         bool hasData() const;
 
-        KURL url;
+        void clearURL()
+        {
+            url = KURL();
+            uriList.clear();
+            urlTitle = "";
+        }
+
+        bool hasValidURL() const
+        {
+            return url.isValid();
+        }
+
+        KURL getURL() const
+        {
+            return url;
+        }
+
+        void setURL(const KURL& newURL)
+        {
+            url = newURL;
+            uriList.clear();
+            uriList.append(newURL.string());
+        }
+
         String urlTitle;
 
         String downloadMetadata;
@@ -74,8 +98,14 @@ namespace WebCore {
         RefPtr<SharedBuffer> fileContent;
 
     private:
+        // URL and uri-list are linked, so they should not be accessed individually.
+        KURL url;
+        Vector<String> uriList;
+
         ChromiumDataObject() {}
         ChromiumDataObject(const ChromiumDataObject&);
+
+        friend class ClipboardChromium;
     };
 
 } // namespace WebCore
diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp
index e069526..55b92b0 100644
--- a/WebCore/platform/chromium/ClipboardChromium.cpp
+++ b/WebCore/platform/chromium/ClipboardChromium.cpp
@@ -54,21 +54,37 @@ using namespace HTMLNames;
 // We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
 // see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
 
-enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardDataTypeText, ClipboardDataTypeDownloadURL };
+enum ClipboardDataType {
+    ClipboardDataTypeNone,
+
+    ClipboardDataTypeURL,
+    ClipboardDataTypeURIList,
+    ClipboardDataTypeDownloadURL,
+    ClipboardDataTypePlainText,
+
+    ClipboardDataTypeOther,
+};
+
+// Per RFC 2483, the line separator for "text/..." MIME types is CR-LF.
+static char const* const textMIMETypeLineSeparator = "\r\n";
 
 static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
 {
     String cleanType = type.stripWhiteSpace().lower();
+    if (cleanType.isEmpty())
+        return ClipboardDataTypeNone;
 
-    // two special cases for IE compatibility
+    // Includes two special cases for IE compatibility.
     if (cleanType == "text" || cleanType == "text/plain" || cleanType.startsWith("text/plain;"))
-        return ClipboardDataTypeText;
-    if (cleanType == "url" || cleanType == "text/uri-list")
+        return ClipboardDataTypePlainText;
+    if (cleanType == "url")
         return ClipboardDataTypeURL;
+    if (cleanType == "text/uri-list")
+        return ClipboardDataTypeURIList;
     if (cleanType == "downloadurl")
         return ClipboardDataTypeDownloadURL;
 
-    return ClipboardDataTypeNone;
+    return ClipboardDataTypeOther;
 }
 
 ClipboardChromium::ClipboardChromium(bool isForDragging,
@@ -91,14 +107,32 @@ void ClipboardChromium::clearData(const String& type)
         return;
 
     ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
+    switch (dataType) {
+    case ClipboardDataTypeNone:
+        // If called with no arguments, everything except the file list must be cleared.
+        // (See HTML5 spec, "The DragEvent and DataTransfer interfaces")
+        m_dataObject->clearAllExceptFiles();
+        return;
 
-    if (dataType == ClipboardDataTypeURL) {
-        m_dataObject->url = KURL();
-        m_dataObject->urlTitle = "";
-    }
+    case ClipboardDataTypeURL:
+    case ClipboardDataTypeURIList:
+        m_dataObject->clearURL();
+        return;
 
-    if (dataType == ClipboardDataTypeText)
+    case ClipboardDataTypeDownloadURL:
+        m_dataObject->downloadMetadata = "";
+        return;
+        
+    case ClipboardDataTypePlainText:
         m_dataObject->plainText = "";
+        return;
+
+    case ClipboardDataTypeOther:
+        // Not yet implemented, see https://bugs.webkit.org/show_bug.cgi?id=34410
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void ClipboardChromium::clearAllData()
@@ -116,8 +150,52 @@ String ClipboardChromium::getData(const String& type, bool& success) const
         return String();
 
     ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
-    String text;
-    if (dataType == ClipboardDataTypeText) {
+    switch (dataType) {
+    case ClipboardDataTypeNone:
+        return String();
+
+    case ClipboardDataTypeURIList:
+        {
+            String text;
+            for (size_t i = 0; i < m_dataObject->uriList.size(); ++i) {
+                const String& uri = m_dataObject->uriList[i];
+                ASSERT(!uri.isEmpty());
+                if (!text.isEmpty())
+                    text.append(textMIMETypeLineSeparator);
+                // URIs have already been canonicalized, so copy everything verbatim.
+                text.append(uri);
+            }
+            // Also create file:// URLs out of the entries in the file list.
+            for (size_t i = 0; i < m_dataObject->filenames.size(); ++i) {
+                String fileURL = ChromiumBridge::filePathToURL(m_dataObject->filenames[i]);
+                ASSERT(!fileURL.isEmpty());
+                if (!text.isEmpty())
+                    text.append(textMIMETypeLineSeparator);
+                text.append(fileURL);
+            }
+            success = !text.isEmpty();
+            return text;
+        }
+
+    case ClipboardDataTypeURL:
+        // In case of a previous setData('text/uri-list'), setData() has already
+        // prepared the 'url' member, so we can just retrieve it here.
+        if (!m_dataObject->url.isEmpty()) {
+            success = true;
+            return m_dataObject->url.string();
+        }
+        // Otherwise check if we have a file that we could convert to a file:// URL.
+        if (!m_dataObject->filenames.isEmpty()) {
+            success = true;
+            return ChromiumBridge::filePathToURL(m_dataObject->filenames[0]);
+        }
+        return String();
+
+    case ClipboardDataTypeDownloadURL:
+        success = !m_dataObject->downloadMetadata.isEmpty();
+        return m_dataObject->downloadMetadata;
+    
+    case ClipboardDataTypePlainText:
         if (!isForDragging()) {
             // If this isn't for a drag, it's for a cut/paste event handler.
             // In this case, we need to check the clipboard.
@@ -125,22 +203,21 @@ String ClipboardChromium::getData(const String& type, bool& success) const
                 Pasteboard::generalPasteboard()->isSelectionMode() ?
                 PasteboardPrivate::SelectionBuffer : 
                 PasteboardPrivate::StandardBuffer;
-            text = ChromiumBridge::clipboardReadPlainText(buffer);
+            String text = ChromiumBridge::clipboardReadPlainText(buffer);
             success = !text.isEmpty();
-        } else if (!m_dataObject->plainText.isEmpty()) {
-            success = true;
-            text = m_dataObject->plainText;
-        }
-    } else if (dataType == ClipboardDataTypeURL) {
-        // FIXME: Handle the cut/paste event.  This requires adding a new IPC
-        // message to get the URL from the clipboard directly.
-        if (!m_dataObject->url.isEmpty()) {
-            success = true;
-            text = m_dataObject->url.string();
+            return text;
         }
+        // Otherwise return whatever is stored in plainText.
+        success = !m_dataObject->plainText.isEmpty();
+        return m_dataObject->plainText;
+        
+    case ClipboardDataTypeOther:
+        // not yet implemented, see https://bugs.webkit.org/show_bug.cgi?id=34410
+        return String();
     }
 
-    return text;
+    ASSERT_NOT_REACHED();
+    return String();
 }
 
 bool ClipboardChromium::setData(const String& type, const String& data)
@@ -148,23 +225,64 @@ bool ClipboardChromium::setData(const String& type, const String& data)
     if (policy() != ClipboardWritable)
         return false;
 
-    ClipboardDataType winType = clipboardTypeFromMIMEType(type);
+    ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
+    switch (dataType) {
+    case ClipboardDataTypeNone:
+        return false;
 
-    if (winType == ClipboardDataTypeURL) {
-        m_dataObject->url = KURL(ParsedURLString, data);
-        return m_dataObject->url.isValid();
-    }
+    case ClipboardDataTypeURL:
+        // For setData(), "URL" must be treated as "text/uri-list".
+        // (See HTML5 spec, "The DragEvent and DataTransfer interfaces")
+    case ClipboardDataTypeURIList:
+        m_dataObject->url = KURL();
+        // Line separator is \r\n per RFC 2483 - however, for compatibility reasons
+        // we also allow just \n here. 
+        data.split('\n', m_dataObject->uriList);
+        // Strip white space on all lines, including trailing \r from above split.
+        // If this leaves a line empty, remove it completely.
+        //
+        // Also, copy the first valid URL into the 'url' member as well.
+        // In case no entry is a valid URL (i.e., remarks only), then we leave 'url' empty.
+        // I.e., in that case subsequent calls to getData("URL") will get an empty string.
+        // This is in line with the HTML5 spec (see "The DragEvent and DataTransfer interfaces").
+        for (size_t i = 0; i < m_dataObject->uriList.size(); /**/) {
+            String& line = m_dataObject->uriList[i];
+            line = line.stripWhiteSpace();
+            if (line.isEmpty()) {
+                m_dataObject->uriList.remove(n);
+                continue;
+            }
+            ++i;
+            // Only copy the first valid URL.
+            if (m_dataObject->url.isValid())
+                continue;
+            // Skip remarks.
+            if (line[0] == '#')
+                continue;
+            KURL url = KURL(ParsedURLString, line);
+            if (url.isValid())
+                m_dataObject->url = url;
+        }
+        if (m_dataObject->uriList.isEmpty()) {
+            ASSERT(m_dataObject->url.isEmpty());
+            return data.isEmpty();
+        }
+        return true;
 
-    if (winType == ClipboardDataTypeText) {
+    case ClipboardDataTypeDownloadURL:
+        m_dataObject->downloadMetadata = data;
+        return true;
+
+    case ClipboardDataTypePlainText:
         m_dataObject->plainText = data;
         return true;
+
+    case ClipboardDataTypeOther:
+        // Not yet implemented, see https://bugs.webkit.org/show_bug.cgi?id=34410
+        return false;
     }
     
-    if (winType == ClipboardDataTypeDownloadURL) {
-        m_dataObject->downloadMetadata = data;
-        return true;
-    }
-
+    ASSERT_NOT_REACHED();
     return false;
 }
 
@@ -178,11 +296,19 @@ HashSet<String> ClipboardChromium::types() const
     if (!m_dataObject)
         return results;
 
-    if (!m_dataObject->filenames.isEmpty())
+    if (!m_dataObject->filenames.isEmpty()) {
+        results.add("text/uri-list");
         results.add("Files");
+    }
 
     if (m_dataObject->url.isValid()) {
+        ASSERT(!m_dataObject->uriList.isEmpty());
         results.add("URL");
+    }
+
+    if (!m_dataObject->uriList.isEmpty()) {
+        // Note that even if the URI list is not empty, it may not actually
+        // contain a valid URL, so we can't return "URL" here.
         results.add("text/uri-list");
     }
 
diff --git a/WebCore/platform/chromium/DragDataChromium.cpp b/WebCore/platform/chromium/DragDataChromium.cpp
index 9b67fc0..8fb40de 100644
--- a/WebCore/platform/chromium/DragDataChromium.cpp
+++ b/WebCore/platform/chromium/DragDataChromium.cpp
@@ -64,8 +64,8 @@ bool DragData::containsURL() const
 String DragData::asURL(String* title) const
 {
     String url;
-    if (m_platformDragData->url.isValid())
-        url = m_platformDragData->url.string();
+    if (m_platformDragData->hasValidURL())
+        url = m_platformDragData->getURL().string();
     else if (m_platformDragData->filenames.size() == 1) {
         String fileName = m_platformDragData->filenames[0];
         fileName = ChromiumBridge::getAbsolutePath(fileName);
@@ -113,7 +113,7 @@ bool DragData::canSmartReplace() const
     // ClipboardWin::writeRange is called).  For example, dragging a link
     // should not result in a space being added.
     return !m_platformDragData->plainText.isEmpty()
-        && !m_platformDragData->url.isValid();
+        && !m_platformDragData->hasValidURL();
 }
 
 bool DragData::containsCompatibleContent() const
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index fc82419..7e9aaaf 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,21 @@
+2010-03-10  Roland Steiner  <rolandsteiner at chromium.org>
+
+        Reviewed by David Levin.
+
+        Bug 28293 -  [Chromium] event.datatransfer.getdata("text/uri-list") is treated the same as getdata("URL")
+        https://bugs.webkit.org/show_bug.cgi?id=28293
+        
+        Change ChromiumDataObject such that it treats types "URL" and "text/uri-list"
+        correctly for event.dataTransfer.getData/setData. Currently both are treated
+        as synonyms, but for "URL", getData is supposed to only return the first valid URL
+        contained within the data for "text/uri-list" (see HTML5 spec).
+
+        Tests: editing/pasteboard/dataTransfer-setData-getData.html
+
+        * src/WebDragData.cpp:
+        (WebKit::WebDragData::url):
+        (WebKit::WebDragData::setURL):
+
 2010-03-08  John Abd-El-Malek  <jam at chromium.org>
 
         Reviewed by Darin Fisher.
diff --git a/WebKit/chromium/src/WebDragData.cpp b/WebKit/chromium/src/WebDragData.cpp
index 2f476a7..643c35d 100644
--- a/WebKit/chromium/src/WebDragData.cpp
+++ b/WebKit/chromium/src/WebDragData.cpp
@@ -67,13 +67,13 @@ void WebDragData::assign(const WebDragData& other)
 WebURL WebDragData::url() const
 {
     ASSERT(!isNull());
-    return m_private->url;
+    return m_private->getURL();
 }
 
 void WebDragData::setURL(const WebURL& url)
 {
     ensureMutable();
-    m_private->url = url;
+    m_private->setURL(url);
 }
 
 WebString WebDragData::urlTitle() const

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list