WebCore: We should not bubble up events if we drag something to an iframe that
authorjianli@chromium.org <jianli@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Nov 2009 17:59:35 +0000 (17:59 +0000)
committerjianli@chromium.org <jianli@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Nov 2009 17:59:35 +0000 (17:59 +0000)
has an invalid source.
https://bugs.webkit.org/show_bug.cgi?id=30469

Reviewed by Dmitri Titov.

Test: http/tests/misc/bubble-drag-events.html

* page/EventHandler.cpp:
(WebCore::EventHandler::handleDragAndDropForTarget):
(WebCore::EventHandler::updateDragAndDrop):
(WebCore::EventHandler::cancelDragAndDrop):
(WebCore::EventHandler::performDragAndDrop):
* page/EventHandler.h:
(WebCore::EventHandler::):

LayoutTests: Tests the drag event bubbling on different targets:
- iframe with invalid source
- iframe with valid source
- non-iframe droppable element
https://bugs.webkit.org/show_bug.cgi?id=30469

Reviewed by Dmitri Titov.

* http/tests/misc/bubble-drag-events-expected.txt: Added.
* http/tests/misc/bubble-drag-events.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@50566 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/misc/bubble-drag-events-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/misc/bubble-drag-events.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/page/EventHandler.cpp
WebCore/page/EventHandler.h

index a22aba0..17c7e60 100644 (file)
@@ -1,3 +1,16 @@
+2009-11-05  Jian Li  <jianli@chromium.org>
+
+        Reviewed by Dmitri Titov.
+
+        Tests the drag event bubbling on different targets:
+        - iframe with invalid source
+        - iframe with valid source
+        - non-iframe droppable element
+        https://bugs.webkit.org/show_bug.cgi?id=30469
+
+        * http/tests/misc/bubble-drag-events-expected.txt: Added.
+        * http/tests/misc/bubble-drag-events.html: Added.
+
 2009-11-05  Jeff Schiller  <codedread@gmail.com>
 
         Reviewed by Simon Fraser.
diff --git a/LayoutTests/http/tests/misc/bubble-drag-events-expected.txt b/LayoutTests/http/tests/misc/bubble-drag-events-expected.txt
new file mode 100644 (file)
index 0000000..f105666
--- /dev/null
@@ -0,0 +1,14 @@
+CONSOLE MESSAGE: line 0: Not allowed to load local resource: file:
+This page tests the drag event bubbling with valid and invalid targets.
+
+
+
+
+Drag here.
+Tests that we don't bubble up the events if we drag something to an iframe that has an invalid source
+Tests that we don't bubble up the events if we drag something to an iframe that has a valid source
+Tests that we bubble up the events if we drag something to a non-iframe target
+ondragenter
+ondragover
+ondrop
+
diff --git a/LayoutTests/http/tests/misc/bubble-drag-events.html b/LayoutTests/http/tests/misc/bubble-drag-events.html
new file mode 100644 (file)
index 0000000..aae0fc1
--- /dev/null
@@ -0,0 +1,74 @@
+<head>
+<script>
+function log(msg)
+{
+    document.getElementById("log").appendChild(document.createTextNode(msg + "\n"));
+}
+
+function testDragEventBubbling(dragTargetId, dragTargetParentId)
+{
+    var dragTargetParent = document.getElementById(dragTargetParentId);
+    dragTargetParent.ondragenter = function() {
+        log("ondragenter");
+    }
+    dragTargetParent.ondragover = function() {
+        log("ondragover");
+        event.preventDefault();  // Cancel the drag, so we get the drop.
+    }
+    dragTargetParent.ondragleave = function() {
+        log("ondragleave");
+    }
+    dragTargetParent.ondrop = function() {
+       log("ondrop");
+    }
+
+    var abe = document.getElementById("abe");
+    var dragTarget = document.getElementById(dragTargetId);
+
+    eventSender.mouseMoveTo(abe.offsetLeft + 50, abe.offsetTop + 50);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    // Leap forward so that the next mouseDown doesn't trigger a triple click.
+    eventSender.leapForward(1200);
+
+    eventSender.mouseDown();
+    // Leap forward so that the mouse movement causes a drag instead of selection creation.
+    eventSender.leapForward(500);
+
+    eventSender.mouseMoveTo(dragTarget.offsetLeft + 1, dragTarget.offsetTop + 1);
+    eventSender.mouseUp();
+}
+
+window.onload = function ()
+{
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText(); 
+
+    log("Tests that we don't bubble up the events if we drag something to an iframe that has an invalid source");
+    testDragEventBubbling("invalidIframeDragTargetParent", "invalidIframeDragTarget");
+
+    log("Tests that we don't bubble up the events if we drag something to an iframe that has a valid source");
+    testDragEventBubbling("validIframeDragTargetParent", "validIframeDragTarget");
+
+    log("Tests that we bubble up the events if we drag something to a non-iframe target");
+    testDragEventBubbling("validSpanDragTargetParent", "validSpanDragTarget");
+
+    layoutTestController.notifyDone();
+}
+</script>
+</head>
+
+<p>This page tests the drag event bubbling with valid and invalid targets.</p>
+<img id="abe" src="http://127.0.0.1:8000/security/resources/abe.png">
+<div id="invalidIframeDragTargetParent">
+<iframe id="invalidIframeDragTarget" src="file:"></iframe>
+</div>
+<div id="validIframeDragTargetParent">
+<iframe id="validIframeDragTarget" src="data:text/html,<body>Working</body>"></iframe>
+</div>
+<div contentEditable id="validSpanDragTargetParent">
+<span id="validSpanDragTarget">Drag here.</span>
+</div>
+<pre id="log"></pre>
index e0d9665..6ed4c09 100644 (file)
@@ -1,3 +1,21 @@
+2009-11-05  Jian Li  <jianli@chromium.org>
+
+        Reviewed by Dmitri Titov.
+
+        We should not bubble up events if we drag something to an iframe that
+        has an invalid source.
+        https://bugs.webkit.org/show_bug.cgi?id=30469
+
+        Test: http/tests/misc/bubble-drag-events.html
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleDragAndDropForTarget):
+        (WebCore::EventHandler::updateDragAndDrop):
+        (WebCore::EventHandler::cancelDragAndDrop):
+        (WebCore::EventHandler::performDragAndDrop):
+        * page/EventHandler.h:
+        (WebCore::EventHandler::):
+
 2009-11-05  Pavel Feldman  <pfeldman@chromium.org>
 
         Reviewed by Timothy Hatcher.
index 4e97aba..bda55a9 100644 (file)
@@ -1508,6 +1508,31 @@ bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa
     return me->defaultPrevented();
 }
 
+bool EventHandler::handleDragAndDropForTarget(DragAndDropHandleType type, Node* target, const AtomicString& eventType, const PlatformMouseEvent& event, Clipboard* clipboard)
+{
+    bool accept = false;
+
+    if (target->hasTagName(frameTag) || target->hasTagName(iframeTag)) {
+        Frame* frame = static_cast<HTMLFrameElementBase*>(target)->contentFrame();
+        if (frame) {
+            switch (type) {
+                case UpdateDragAndDrop:
+                    accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);
+                    break;
+                case CancelDragAndDrop:
+                    frame->eventHandler()->cancelDragAndDrop(event, clipboard);
+                    break;
+                case PerformDragAndDrop:
+                    accept = frame->eventHandler()->performDragAndDrop(event, clipboard);
+                    break;
+            }
+        }
+    } else
+        accept = dispatchDragEvent(eventType, target, event, clipboard);
+
+    return accept;
+}
+
 bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
 {
     bool accept = false;
@@ -1529,29 +1554,14 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
         // FIXME: this ordering was explicitly chosen to match WinIE. However,
         // it is sometimes incorrect when dragging within subframes, as seen with
         // LayoutTests/fast/events/drag-in-frames.html.
-        if (newTarget) {
-            Frame* frame = (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame() : 0;
-            if (frame)
-                accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);
-            else
-                accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard);
-        }
+        if (newTarget)
+            accept = handleDragAndDropForTarget(UpdateDragAndDrop, newTarget, eventNames().dragenterEvent, event, clipboard);
 
-        if (m_dragTarget) {
-            Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
-            if (frame)
-                accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);
-            else
-                dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
-        }
+        if (m_dragTarget)
+            handleDragAndDropForTarget(UpdateDragAndDrop, m_dragTarget.get(), eventNames().dragleaveEvent, event, clipboard);
     } else {
-        if (newTarget) {
-            Frame* frame = (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame() : 0;
-            if (frame)
-                accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);
-            else
-                accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard);
-        }
+        if (newTarget)
+            accept = handleDragAndDropForTarget(UpdateDragAndDrop, newTarget, eventNames().dragoverEvent, event, clipboard);
     }
     m_dragTarget = newTarget;
 
@@ -1560,28 +1570,16 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
 
 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
 {
-    if (m_dragTarget) {
-        Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) 
-                        ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
-        if (frame)
-            frame->eventHandler()->cancelDragAndDrop(event, clipboard);
-        else
-            dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
-    }
+    if (m_dragTarget)
+        handleDragAndDropForTarget(CancelDragAndDrop, m_dragTarget.get(), eventNames().dragleaveEvent, event, clipboard);
     clearDragState();
 }
 
 bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
 {
     bool accept = false;
-    if (m_dragTarget) {
-        Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) 
-                        ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
-        if (frame)
-            accept = frame->eventHandler()->performDragAndDrop(event, clipboard);
-        else
-            accept = dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard);
-    }
+    if (m_dragTarget)
+        accept = handleDragAndDropForTarget(PerformDragAndDrop, m_dragTarget.get(), eventNames().dropEvent, event, clipboard);
     clearDragState();
     return accept;
 }
index 0221397..e756e0b 100644 (file)
@@ -194,6 +194,12 @@ public:
 
 private:
 #if ENABLE(DRAG_SUPPORT)
+    enum DragAndDropHandleType {
+        UpdateDragAndDrop,
+        CancelDragAndDrop,
+        PerformDragAndDrop
+    };
+
     struct EventHandlerDragState {
         RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
         bool m_dragSrcIsLink;
@@ -206,6 +212,8 @@ private:
     };
     static EventHandlerDragState& dragState();
     static const double TextDragDelay;
+
+    bool handleDragAndDropForTarget(DragAndDropHandleType, Node* target, const AtomicString& eventType, const PlatformMouseEvent&, Clipboard*);
     
     PassRefPtr<Clipboard> createDraggingClipboard() const;
 #endif // ENABLE(DRAG_SUPPORT)