Title: [221343] trunk
Revision
221343
Author
wenson_hs...@apple.com
Date
2017-08-29 22:09:23 -0700 (Tue, 29 Aug 2017)

Log Message

REGRESSION(r210287) On drop, event.dataTransfer.getData("text") returns an empty string when dragging an image
https://bugs.webkit.org/show_bug.cgi?id=170637
<rdar://problem/31347248>

Reviewed by Ryosuke Niwa.

Source/WebCore:

In r210287, the behavior of DragData::containsFiles was changed to return true if NSFilesPromisePboardType is
present in the pasteboard. This means that we will consider images dragged from web content, for which we add
the NSFilesPromisePboardType UTI, as containing files on the pasteboard; this, in turn, means we'll initialize
the DataTransfer upon drop with m_forFileDrag set to true. Due to early returns in getData() and setData() to
deny data access when dropping a dragged file, this means the page won't ever get access to the URL in the
pasteboard due to the presence of the NSFilesPromisePboardType UTI.

To fix this, we replace the early m_forFileDrag returns in getData and setData, instead early returning the null
string if there are any file URLs present on the pasteboard (determined via readFilenames() retrieving a non-
empty result).

Test: editing/pasteboard/drag-drop-href-as-text-data.html

* dom/DataTransfer.cpp:
(WebCore::DataTransfer::DataTransfer):
(WebCore::DataTransfer::getData const):
(WebCore::DataTransfer::setData):

Rather than bail upon forFileDrag() (formerly, m_forFileDrag) being true, bail if there are any file URLs
present on the pasteboard. It seems like this was the intention of the early return in the first place, to
prevent the page from being able to ask for a real file URL when dragging a file.

(WebCore::DataTransfer::files const):
(WebCore::DataTransfer::setDragImage):
(WebCore::DataTransfer::setDropEffect):
(WebCore::DataTransfer::setEffectAllowed):

Swap m_forDrag and m_forFileDrag with forDrag() and forFileDrag(), respectively.

* dom/DataTransfer.h:
(WebCore::DataTransfer::forDrag const):
(WebCore::DataTransfer::forFileDrag const):

Instead of caching two bools to represent state (m_forDrag and m_forFileDrag), just remember the DataTransfer's
m_type and turn the flags into const helpers that check for the value of m_type.

LayoutTests:

Adds a new test to verify that upon dropping an image enclosed within an anchor, DataTransfer.getData() can be
used to grab the href of the enclosing anchor.

* TestExpectations:
* editing/pasteboard/drag-drop-href-as-text-data-expected.txt: Added.
* editing/pasteboard/drag-drop-href-as-text-data.html: Added.
* platform/mac-wk1/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (221342 => 221343)


--- trunk/LayoutTests/ChangeLog	2017-08-30 04:32:49 UTC (rev 221342)
+++ trunk/LayoutTests/ChangeLog	2017-08-30 05:09:23 UTC (rev 221343)
@@ -1,3 +1,19 @@
+2017-08-29  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        REGRESSION(r210287) On drop, event.dataTransfer.getData("text") returns an empty string when dragging an image
+        https://bugs.webkit.org/show_bug.cgi?id=170637
+        <rdar://problem/31347248>
+
+        Reviewed by Ryosuke Niwa.
+
+        Adds a new test to verify that upon dropping an image enclosed within an anchor, DataTransfer.getData() can be
+        used to grab the href of the enclosing anchor.
+
+        * TestExpectations:
+        * editing/pasteboard/drag-drop-href-as-text-data-expected.txt: Added.
+        * editing/pasteboard/drag-drop-href-as-text-data.html: Added.
+        * platform/mac-wk1/TestExpectations:
+
 2017-08-29  Devin Rousso  <web...@devinrousso.com>
 
         CallTracingCallback should ignore `readonly attribute`

Modified: trunk/LayoutTests/TestExpectations (221342 => 221343)


--- trunk/LayoutTests/TestExpectations	2017-08-30 04:32:49 UTC (rev 221342)
+++ trunk/LayoutTests/TestExpectations	2017-08-30 05:09:23 UTC (rev 221343)
@@ -64,6 +64,9 @@
 fast/events/autoscroll-when-zoomed.html [ Skip ]
 fast/events/autoscroll-main-document.html [ Skip ]
 
+# Drag and drop via EventSender is only supported on Mac WK1
+editing/pasteboard/drag-drop-href-as-text-data.html [ Skip ]
+
 # Only iOS supports QuickLook
 quicklook [ Skip ]
 http/tests/quicklook [ Skip ]

Added: trunk/LayoutTests/editing/pasteboard/drag-drop-href-as-text-data-expected.txt (0 => 221343)


--- trunk/LayoutTests/editing/pasteboard/drag-drop-href-as-text-data-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/drag-drop-href-as-text-data-expected.txt	2017-08-30 05:09:23 UTC (rev 221343)
@@ -0,0 +1,5 @@
+
+text: "https://www.webkit.org/"
+url: "https://www.webkit.org/"
+text/plain: "https://www.webkit.org/"
+text/uri-list: "https://www.webkit.org/"

Added: trunk/LayoutTests/editing/pasteboard/drag-drop-href-as-text-data.html (0 => 221343)


--- trunk/LayoutTests/editing/pasteboard/drag-drop-href-as-text-data.html	                        (rev 0)
+++ trunk/LayoutTests/editing/pasteboard/drag-drop-href-as-text-data.html	2017-08-30 05:09:23 UTC (rev 221343)
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<style>
+body {
+    margin: 0;
+}
+#source {
+    width: 300px;
+    height: 300px;
+}
+#target {
+    border: 1px blue dashed;
+    font-family: monospace;
+    overflow: scroll;
+    white-space: nowrap;
+    width: 100%;
+    height: 300px;
+}
+</style>
+
+<a id="link" href="" id="source" src=""
+<div id="target"></div>
+
+<script>
+function append(text) {
+    let div = document.createElement("div");
+    div.textContent = text;
+    target.appendChild(div);
+}
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+target.addEventListener("dragenter", event => event.preventDefault());
+target.addEventListener("dragover", event => event.preventDefault());
+target.addEventListener("drop", event => {
+    for (let type of ["text", "url", "text/plain", "text/uri-list"])
+        append(`${type}: "${event.dataTransfer.getData(type)}"`);
+    event.preventDefault();
+});
+
+if (window.eventSender) {
+    let x = source.offsetLeft + source.offsetWidth / 2;
+    let y = source.offsetTop + source.offsetHeight / 2;
+    eventSender.mouseMoveTo(x, y);
+    eventSender.mouseDown();
+    eventSender.leapForward(500);
+    eventSender.mouseMoveTo(x, y + 300);
+    eventSender.mouseUp();
+}
+</script>
+</html>
\ No newline at end of file

Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (221342 => 221343)


--- trunk/LayoutTests/platform/mac-wk1/TestExpectations	2017-08-30 04:32:49 UTC (rev 221342)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations	2017-08-30 05:09:23 UTC (rev 221343)
@@ -6,6 +6,7 @@
 #//////////////////////////////////////////////////////////////////////////////////////////
 
 fast/forms/attributed-strings.html [ Pass ]
+editing/pasteboard/drag-drop-href-as-text-data.html [ Pass ]
 
 #//////////////////////////////////////////////////////////////////////////////////////////
 # End platform-specific directories.

Modified: trunk/Source/WebCore/ChangeLog (221342 => 221343)


--- trunk/Source/WebCore/ChangeLog	2017-08-30 04:32:49 UTC (rev 221342)
+++ trunk/Source/WebCore/ChangeLog	2017-08-30 05:09:23 UTC (rev 221343)
@@ -1,3 +1,47 @@
+2017-08-29  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        REGRESSION(r210287) On drop, event.dataTransfer.getData("text") returns an empty string when dragging an image
+        https://bugs.webkit.org/show_bug.cgi?id=170637
+        <rdar://problem/31347248>
+
+        Reviewed by Ryosuke Niwa.
+
+        In r210287, the behavior of DragData::containsFiles was changed to return true if NSFilesPromisePboardType is
+        present in the pasteboard. This means that we will consider images dragged from web content, for which we add
+        the NSFilesPromisePboardType UTI, as containing files on the pasteboard; this, in turn, means we'll initialize
+        the DataTransfer upon drop with m_forFileDrag set to true. Due to early returns in getData() and setData() to
+        deny data access when dropping a dragged file, this means the page won't ever get access to the URL in the
+        pasteboard due to the presence of the NSFilesPromisePboardType UTI.
+
+        To fix this, we replace the early m_forFileDrag returns in getData and setData, instead early returning the null
+        string if there are any file URLs present on the pasteboard (determined via readFilenames() retrieving a non-
+        empty result).
+
+        Test: editing/pasteboard/drag-drop-href-as-text-data.html
+
+        * dom/DataTransfer.cpp:
+        (WebCore::DataTransfer::DataTransfer):
+        (WebCore::DataTransfer::getData const):
+        (WebCore::DataTransfer::setData):
+
+        Rather than bail upon forFileDrag() (formerly, m_forFileDrag) being true, bail if there are any file URLs
+        present on the pasteboard. It seems like this was the intention of the early return in the first place, to
+        prevent the page from being able to ask for a real file URL when dragging a file.
+
+        (WebCore::DataTransfer::files const):
+        (WebCore::DataTransfer::setDragImage):
+        (WebCore::DataTransfer::setDropEffect):
+        (WebCore::DataTransfer::setEffectAllowed):
+
+        Swap m_forDrag and m_forFileDrag with forDrag() and forFileDrag(), respectively.
+
+        * dom/DataTransfer.h:
+        (WebCore::DataTransfer::forDrag const):
+        (WebCore::DataTransfer::forFileDrag const):
+
+        Instead of caching two bools to represent state (m_forDrag and m_forFileDrag), just remember the DataTransfer's
+        m_type and turn the flags into const helpers that check for the value of m_type.
+
 2017-08-29  Youenn Fablet  <you...@apple.com>
 
         [Fetch API] Request should throw when keep alive is true and body is a ReadableStream

Modified: trunk/Source/WebCore/dom/DataTransfer.cpp (221342 => 221343)


--- trunk/Source/WebCore/dom/DataTransfer.cpp	2017-08-30 04:32:49 UTC (rev 221342)
+++ trunk/Source/WebCore/dom/DataTransfer.cpp	2017-08-30 05:09:23 UTC (rev 221343)
@@ -61,8 +61,7 @@
     : m_storeMode(mode)
     , m_pasteboard(WTFMove(pasteboard))
 #if ENABLE(DRAG_SUPPORT)
-    , m_forDrag(type == Type::DragAndDropData || type == Type::DragAndDropFiles)
-    , m_forFileDrag(type == Type::DragAndDropFiles)
+    , m_type(type)
     , m_dropEffect(ASCIILiteral("uninitialized"))
     , m_effectAllowed(ASCIILiteral("uninitialized"))
     , m_shouldUpdateDragImage(false)
@@ -137,8 +136,8 @@
         return String();
 
 #if ENABLE(DRAG_SUPPORT)
-    if (m_forFileDrag)
-        return String();
+    if (forFileDrag() && m_pasteboard->readFilenames().size())
+        return { };
 #endif
 
     return m_pasteboard->readString(normalizeType(type));
@@ -150,7 +149,7 @@
         return;
 
 #if ENABLE(DRAG_SUPPORT)
-    if (m_forFileDrag)
+    if (forFileDrag() && m_pasteboard->readFilenames().size())
         return;
 #endif
 
@@ -187,7 +186,7 @@
     }
 
 #if ENABLE(DRAG_SUPPORT)
-    if (m_forDrag && !m_forFileDrag) {
+    if (forDrag() && !forFileDrag()) {
         ASSERT(m_fileList->isEmpty());
         return *m_fileList;
     }
@@ -266,7 +265,7 @@
 
 void DataTransfer::setDragImage(Element* element, int x, int y)
 {
-    if (!m_forDrag || !canWriteData())
+    if (!forDrag() || !canWriteData())
         return;
 
     CachedImage* image = nullptr;
@@ -422,7 +421,7 @@
 
 void DataTransfer::setDropEffect(const String& effect)
 {
-    if (!m_forDrag)
+    if (!forDrag())
         return;
 
     if (effect != "none" && effect != "copy" && effect != "link" && effect != "move")
@@ -443,7 +442,7 @@
 
 void DataTransfer::setEffectAllowed(const String& effect)
 {
-    if (!m_forDrag)
+    if (!forDrag())
         return;
 
     // Ignore any attempts to set it to an unknown value.

Modified: trunk/Source/WebCore/dom/DataTransfer.h (221342 => 221343)


--- trunk/Source/WebCore/dom/DataTransfer.h	2017-08-30 04:32:49 UTC (rev 221342)
+++ trunk/Source/WebCore/dom/DataTransfer.h	2017-08-30 05:09:23 UTC (rev 221343)
@@ -98,6 +98,11 @@
     enum class Type { CopyAndPaste, DragAndDropData, DragAndDropFiles, InputEvent };
     DataTransfer(StoreMode, std::unique_ptr<Pasteboard>, Type = Type::CopyAndPaste);
 
+#if ENABLE(DRAG_SUPPORT)
+    bool forDrag() const { return m_type == Type::DragAndDropData || m_type == Type::DragAndDropFiles; }
+    bool forFileDrag() const { return m_type == Type::DragAndDropFiles; }
+#endif
+
     StoreMode m_storeMode;
     std::unique_ptr<Pasteboard> m_pasteboard;
     std::unique_ptr<DataTransferItemList> m_itemList;
@@ -105,8 +110,7 @@
     mutable RefPtr<FileList> m_fileList;
 
 #if ENABLE(DRAG_SUPPORT)
-    bool m_forDrag;
-    bool m_forFileDrag;
+    Type m_type;
     String m_dropEffect;
     String m_effectAllowed;
     bool m_shouldUpdateDragImage;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to