- 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;