Changeset 105396 in webkit
- Timestamp:
- Jan 19, 2012 2:16:35 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r105392 r105396 1 2012-01-19 Ryosuke Niwa <rniwa@webkit.org> 2 3 drop event isn't fired for contentEditable in edit drag 4 https://bugs.webkit.org/show_bug.cgi?id=57185 5 6 Reviewed by Adam Barth. 7 8 Added tests ensure moving text in contenteditable regions fire dragstart, drop, and dragend events. 9 10 * fast/events/moving-text-should-fire-drop-and-dragend-events-2-expected.txt: Added. 11 * fast/events/moving-text-should-fire-drop-and-dragend-events-2.html: Added. 12 * fast/events/moving-text-should-fire-drop-and-dragend-events-expected.txt: Added. 13 * fast/events/moving-text-should-fire-drop-and-dragend-events.html: Added. 14 1 15 2012-01-19 Dominic Mazzoni <dmazzoni@google.com> 2 16 -
trunk/Source/WebCore/ChangeLog
r105395 r105396 1 2012-01-19 Ryosuke Niwa <rniwa@webkit.org> 2 3 drop event isn't fired for contentEditable in edit drag 4 https://bugs.webkit.org/show_bug.cgi?id=57185 5 6 Reviewed by Adam Barth. 7 8 Dispatch drop and dragend events after edit drag per HTML5 spec: 9 http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#drag-and-drop-processing-model 10 11 There are two major differences between the spec and WebKit's new behavior: 12 13 While the spec says we have to insert the dragged contents immediately after dispatching drop event 14 and delete the source in the default event handler of dragend event, doing so in WebKit is extremely 15 difficult because of the way we manage the selection. Instead, we continue to delete the source 16 and insert the dragged contents immediately after the drop event; this behavior matches that of Firefox 9. 17 18 When the dragged contents and the destination of the move is in the same text node, ReplaceSelectionCommand 19 may end up replacing it with a new text node. But this removal causes a problem when EventHandler uses 20 the node to dispatch dragend event because the node is "orphaned" from its parent at that point. To mitigate 21 this issue, we update the dragState's m_dragSrc when the node is orphaned by the edit drag. While this behavior 22 may differ from the spec and other browsers, not delivering dragend to the editing host seems strictly worse than 23 dispatching it at the slightly wrong target. 24 25 Tests: fast/events/moving-text-should-fire-drop-and-dragend-events-2.html 26 fast/events/moving-text-should-fire-drop-and-dragend-events.html 27 28 * page/DragController.cpp: 29 (WebCore::DragController::performDrag): Dispatch drop event even when m_isHandlingDrag is true as long 30 as DragDestinationActionDHTML is an acceptable action. 31 (WebCore::DragController::concludeEditDrag): Call updateDragStateAfterEditDragIfNeeded after inserting 32 the dragged contents. This is necessary when ReplaceSelectionCommand or MoveSelectionCommand modifies 33 the source node while inserting the dragged contents. 34 * page/EventHandler.cpp: 35 (WebCore::EventHandler::performDragAndDrop): Clear the drag state only if drop event's default action 36 was prevented so that we dispatch dragevent event later. 37 (WebCore::EventHandler::updateDragStateAfterEditDragIfNeeded): Update dragState's m_dragSrc when the node 38 is orphaned. See above for the rationale. 39 * page/EventHandler.h: 40 1 41 2012-01-18 Kinuko Yasuda <kinuko@chromium.org> 2 42 -
trunk/Source/WebCore/page/DragController.cpp
r104552 r105396 202 202 ASSERT(dragData); 203 203 m_documentUnderMouse = m_page->mainFrame()->documentAtPoint(dragData->clientPosition()); 204 if (m_isHandlingDrag) { 205 ASSERT(m_dragDestinationAction & DragDestinationActionDHTML); 204 if (m_dragDestinationAction & DragDestinationActionDHTML) { 206 205 m_client->willPerformDragDestinationAction(DragDestinationActionDHTML, dragData); 207 206 RefPtr<Frame> mainFrame = m_page->mainFrame(); 207 bool preventedDefault = false; 208 208 if (mainFrame->view()) { 209 209 // Sending an event can result in the destruction of the view and part. 210 210 RefPtr<Clipboard> clipboard = Clipboard::create(ClipboardReadable, dragData, mainFrame.get()); 211 211 clipboard->setSourceOperation(dragData->draggingSourceOperationMask()); 212 mainFrame->eventHandler()->performDragAndDrop(createMouseEvent(dragData), clipboard.get()); 213 clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security 214 } 215 m_documentUnderMouse = 0; 216 return true; 212 preventedDefault = mainFrame->eventHandler()->performDragAndDrop(createMouseEvent(dragData), clipboard.get()); 213 clipboard->setAccessPolicy(ClipboardNumb); // Invalidate clipboard here for security 214 } 215 if (m_isHandlingDrag || preventedDefault) { 216 m_documentUnderMouse = 0; 217 return true; 218 } 217 219 } 218 220 … … 478 480 m_page->dragCaretController()->clear(); 479 481 RefPtr<Range> range = dragCaret.toNormalizedRange(); 482 RefPtr<Element> rootEditableElement = innerFrame->selection()->rootEditableElement(); 480 483 481 484 // For range to be null a WebKit client must have done something bad while … … 518 521 if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) 519 522 applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse.get(), createFragmentFromText(range.get(), text), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting)); 523 } 524 525 if (rootEditableElement) { 526 if (Frame* frame = rootEditableElement->document()->frame()) 527 frame->eventHandler()->updateDragStateAfterEditDragIfNeeded(rootEditableElement.get()); 520 528 } 521 529 -
trunk/Source/WebCore/page/EventHandler.cpp
r105212 r105396 1912 1912 } 1913 1913 1914 voidEventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)1914 bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard) 1915 1915 { 1916 1916 Frame* targetFrame; 1917 bool preventedDefault = false; 1917 1918 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { 1918 1919 if (targetFrame) 1919 targetFrame->eventHandler()->performDragAndDrop(event, clipboard);1920 preventedDefault = targetFrame->eventHandler()->performDragAndDrop(event, clipboard); 1920 1921 } else if (m_dragTarget.get()) 1921 dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard); 1922 clearDragState(); 1922 preventedDefault = dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard); 1923 if (preventedDefault) 1924 clearDragState(); 1925 return preventedDefault; 1923 1926 } 1924 1927 … … 2784 2787 m_mouseDownMayStartDrag = false; 2785 2788 } 2786 2789 2790 void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement) 2791 { 2792 // If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editble element. 2793 if (dragState().m_dragSrc && !dragState().m_dragSrc->inDocument()) 2794 dragState().m_dragSrc = rootEditableElement; 2795 } 2796 2787 2797 // returns if we should continue "default processing", i.e., whether eventhandler canceled 2788 2798 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event) -
trunk/Source/WebCore/page/EventHandler.h
r104773 r105396 128 128 bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*); 129 129 void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*); 130 void performDragAndDrop(const PlatformMouseEvent&, Clipboard*); 130 bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*); 131 void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement); 131 132 #endif 132 133
Note: See TracChangeset
for help on using the changeset viewer.