Changeset 17574 in webkit


Ignore:
Timestamp:
Nov 3, 2006 10:36:56 AM (17 years ago)
Author:
ap
Message:

Reviewed by Adele.

http://bugs.webkit.org/show_bug.cgi?id=7323
REGRESSION (10.4.4): ondrag* events don't fire on page in a frame

WebCore:

  • bridge/mac/FrameMac.h: Moved drag source information to a static variable in FrameMac.mm. There can be only one drag active at any moment, and having this information here was making sharing this information between subframes hard.
  • bridge/mac/FrameMac.mm: (WebCore::FrameMac::FrameMac): Initialize sharedDragInfo. (WebCore::FrameMac::freeClipboard): (WebCore::FrameMac::dragHysteresisExceeded): (WebCore::FrameMac::handleMouseMoveEvent): (WebCore::FrameMac::handleMouseReleaseEvent): (WebCore::FrameMac::mouseDown): (WebCore::FrameMac::dragSourceMovedTo): (WebCore::FrameMac::dragSourceEndedAt): (WebCore::FrameMac::dispatchDragSrcEvent): Access drag source info via sharedDragInfo - this fixes drag source even dispatching. Also removed some old code that was forwarding mouse events to subviews to make HTML editing work in subframes.
  • page/FrameView.cpp: (WebCore::FrameView::updateDragAndDrop): (WebCore::FrameView::cancelDragAndDrop): (WebCore::FrameView::performDragAndDrop): Forward events to subframes for dispatching - this fixes drag target events.

WebKitTools:

When dragging, do not send EventSendingController's events immediately. Dragging
is supposed to be modal, so we need to perform it from within the delegate, without
returning to JS to make the next mouse movement.

When the mouse is down, mouse events are now recorded, and executed when mouseUp is sent.

  • DumpRenderTree/EventSendingController.h:
  • DumpRenderTree/EventSendingController.m: (-[EventSendingController dealloc]): (-[EventSendingController leapForward:]): (-[EventSendingController mouseDown]): (-[EventSendingController mouseUp]): (-[EventSendingController mouseMoveToX:Y:]): (+[EventSendingController saveEvent:]): (+[EventSendingController replaySavedEvents]):
  • DumpRenderTree/UIDelegate.m: (-[UIDelegate webView:dragImage:at:offset:event:pasteboard:source:slideBack:forView:]):

LayoutTests:

  • fast/events/drag-in-frames-expected.txt: Added.
  • fast/events/drag-in-frames.html: Added.
  • fast/events/resources/drag-in-frames-console.html: Added.
  • fast/events/resources/drag-in-frames-left.html: Added.
  • fast/events/resources/drag-in-frames-right.html: Added.
  • editing/selection/expanding-selections.html:
  • editing/selection/expanding-selections2.html:
  • fast/dynamic/layer-hit-test-crash.html:
  • fast/events/event-view-toString.html:
  • fast/events/resources/drag-outside-window-frame.html:
  • svg/custom/hover-default-fill.svg: Added missing calls to mouseUp().
  • svg/custom/stroke-width-click-expected.txt:
  • svg/custom/stroke-width-click.svg: Don't attempt to click outside the page, this was confusing DRT.
  • editing/selection/select-from-textfield-outwards-expected.txt:
  • editing/selection/select-from-textfield-outwards.html: Removed alerts between dragging steps - they are now useless, as the dragging events are stored and executed at once.
Location:
trunk
Files:
5 added
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r17572 r17574  
     12006-11-03  Alexey Proskuryakov  <ap@nypop.com>
     2
     3        Reviewed by Adele.
     4
     5        Test for http://bugs.webkit.org/show_bug.cgi?id=7323
     6        REGRESSION (10.4.4): ondrag* events don't fire on page in a frame
     7
     8        * fast/events/drag-in-frames-expected.txt: Added.
     9        * fast/events/drag-in-frames.html: Added.
     10        * fast/events/resources/drag-in-frames-console.html: Added.
     11        * fast/events/resources/drag-in-frames-left.html: Added.
     12        * fast/events/resources/drag-in-frames-right.html: Added.
     13
     14        * editing/selection/expanding-selections.html:
     15        * editing/selection/expanding-selections2.html:
     16        * fast/dynamic/layer-hit-test-crash.html:
     17        * fast/events/event-view-toString.html:
     18        * fast/events/resources/drag-outside-window-frame.html:
     19        * svg/custom/hover-default-fill.svg:
     20        Added missing calls to mouseUp().
     21
     22        * svg/custom/stroke-width-click-expected.txt:
     23        * svg/custom/stroke-width-click.svg:
     24        Don't attempt to click outside the page, this was confusing DRT.
     25
     26        * editing/selection/select-from-textfield-outwards-expected.txt:
     27        * editing/selection/select-from-textfield-outwards.html:
     28        Removed alerts between dragging steps - they are now useless,
     29        as the dragging events are stored and executed at once.
     30
    1312006-11-03  Geoffrey Garen  <ggaren@apple.com>
    232
  • trunk/LayoutTests/editing/selection/expanding-selections.html

    r17562 r17574  
    1818    eventSender.mouseUp();
    1919    eventSender.mouseDown();
     20    eventSender.mouseUp();
    2021}
    2122
  • trunk/LayoutTests/editing/selection/expanding-selections2.html

    r17562 r17574  
    1818    eventSender.mouseUp();
    1919    eventSender.mouseDown();
     20    eventSender.mouseUp();
    2021}
    2122
  • trunk/LayoutTests/editing/selection/select-from-textfield-outwards-expected.txt

    r15558 r17574  
    1 ALERT: middle
    21EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 11 of #text > DIV to 11 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    32EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    43EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 11 of #text > DIV to 11 of #text > DIV toDOMRange:range from 11 of #text > DIV to 12 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    54EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    6 ALERT: left
    75EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 11 of #text > DIV to 12 of #text > DIV toDOMRange:range from 0 of #text > DIV to 12 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    86EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    9 ALERT: right
    107EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of #text > DIV to 12 of #text > DIV toDOMRange:range from 11 of #text > DIV to 17 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    118EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    12 ALERT: way up
    139EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 11 of #text > DIV to 17 of #text > DIV toDOMRange:range from 0 of #text > DIV to 12 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    1410EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    15 ALERT: up
    1611EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of #text > DIV to 12 of #text > DIV toDOMRange:range from 0 of #text > DIV to 12 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    17 ALERT: down
    1812EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of #text > DIV to 12 of #text > DIV toDOMRange:range from 11 of #text > DIV to 17 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    1913EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
    20 ALERT: way down
    2114EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 11 of #text > DIV to 17 of #text > DIV toDOMRange:range from 11 of #text > DIV to 17 of #text > DIV affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
    2215layer at (0,0) size 800x600
  • trunk/LayoutTests/editing/selection/select-from-textfield-outwards.html

    r15558 r17574  
    1111    var middleY = field.offsetTop + field.offsetHeight / 2;
    1212   
    13     alert("middle");
     13    // middle
    1414    eventSender.mouseMoveTo(middleX, middleY);
    1515    eventSender.mouseDown();
     
    1717    eventSender.mouseUp();
    1818    eventSender.mouseDown();
    19     alert("left");
     19    // left
    2020    eventSender.mouseMoveTo(0, middleY);
    21     alert("right");
     21    // right
    2222    eventSender.mouseMoveTo(document.body.offsetWidth, middleY);
    23     alert("way up");
     23    // way up
    2424    eventSender.mouseMoveTo(middleX, middleY - 2 * field.offsetHeight);
    25     alert("up");
     25    // up
    2626    eventSender.mouseMoveTo(middleX, middleY - field.offsetHeight);
    27     alert("down");
     27    // down
    2828    eventSender.mouseMoveTo(middleX, middleY + field.offsetHeight);
    29     alert("way down");
     29    // way down
    3030    eventSender.mouseMoveTo(middleX, middleY + 2 * field.offsetHeight);
     31    eventSender.mouseUp();
    3132}
    3233</script>
  • trunk/LayoutTests/fast/dynamic/layer-hit-test-crash.html

    r12513 r17574  
    3434function finish()
    3535{
     36    if (window.eventSender)
     37        eventSender.mouseUp();
    3638    if (window.layoutTestController)
    3739        layoutTestController.notifyDone();
  • trunk/LayoutTests/fast/events/event-view-toString.html

    r11995 r17574  
    33<html>
    44<head>
    5         <title>Test for bug 4233558</title>
     5    <title>Test for bug 4233558</title>
    66<script type="text/javascript" charset="utf-8">
    7         if (window.layoutTestController) {
    8                 layoutTestController.dumpAsText();
    9                 layoutTestController.waitUntilDone();
    10         }
     7    if (window.layoutTestController) {
     8        layoutTestController.dumpAsText();
     9        layoutTestController.waitUntilDone();
     10    }
    1111
    12         function clickBody(event) {
    13                 var resultsDiv = document.getElementById("resultsDiv");
    14                
    15                 resultsDiv.innerHTML +=  "event.view :<br/>";
    16                 try {
    17                         resultsDiv.innerHTML +=  "document: " + event.view.document + "<br/>";
    18                         resultsDiv.innerHTML +=  "proto: " + event.view.__proto__ + "<br/>";
    19                         resultsDiv.innerHTML +=  " Success getting " + event.view + "<br/>";
    20                 }
    21                 catch(e) {
    22                         resultsDiv.innerHTML +=  " ERROR (" + e + ") getting value!<br/>";
    23                 }
    24                 if (window.layoutTestController) {
    25                         layoutTestController.notifyDone();
    26                 }
    27         }
     12    function clickBody(event) {
     13        var resultsDiv = document.getElementById("resultsDiv");
     14       
     15        resultsDiv.innerHTML +=  "event.view :<br/>";
     16        try {
     17            resultsDiv.innerHTML +=  "document: " + event.view.document + "<br/>";
     18            resultsDiv.innerHTML +=  "proto: " + event.view.__proto__ + "<br/>";
     19            resultsDiv.innerHTML +=  " Success getting " + event.view + "<br/>";
     20        }
     21        catch(e) {
     22            resultsDiv.innerHTML +=  " ERROR (" + e + ") getting value!<br/>";
     23        }
     24        if (window.layoutTestController) {
     25            layoutTestController.notifyDone();
     26        }
     27    }
    2828
    29         function loadHandler() {
    30                 var resultsDiv = document.getElementById("resultsDiv");
    31                 if (window.eventSender) {
    32                         eventSender.mouseMoveTo(50, 50);
    33                         eventSender.mouseDown();
    34                 } else {
    35                         resultsDiv.innerHTML += "Manual test mode.<br/>";
    36                 }
    37         }
     29    function loadHandler() {
     30        var resultsDiv = document.getElementById("resultsDiv");
     31        if (window.eventSender) {
     32            eventSender.mouseMoveTo(50, 50);
     33            eventSender.mouseDown();
     34            eventSender.mouseUp();
     35        } else {
     36            resultsDiv.innerHTML += "Manual test mode.<br/>";
     37        }
     38    }
    3839</script>
    3940</head>
  • trunk/LayoutTests/fast/events/resources/drag-outside-window-frame.html

    r13265 r17574  
    1919    eventSender.mouseDown();
    2020    eventSender.mouseMoveTo(50, 100);
     21    eventSender.mouseUp();
    2122    alert("Test result: " + result);
    2223}
  • trunk/LayoutTests/svg/custom/hover-default-fill.svg

    r16604 r17574  
    99    eventSender.mouseMoveTo(50, 50);
    1010    eventSender.mouseDown();
     11    eventSender.mouseUp();
    1112  }
    1213]]>
  • trunk/LayoutTests/svg/custom/stroke-width-click-expected.txt

    r17562 r17574  
    4747   
    4848     
    49       SUCCESS: click at 10, 10 was correctly ignoredSUCCESS: click received at: 30, 100SUCCESS: click at 29, 100 was correctly ignoredSUCCESS: click received at: 30, 50SUCCESS: click at 30, 49 was correctly ignoredSUCCESS: click received at: 30, 150SUCCESS: click at 30, 151 was correctly ignoredSUCCESS: click received at: 300, 100SUCCESS: click at 301, 100 was correctly ignoredSUCCESS: click received at: 300, 50SUCCESS: click at 300, 49 was correctly ignoredSUCCESS: click received at: 300, 150SUCCESS: click at 300, 151 was correctly ignoredSUCCESS: click at 1000, 1000 was correctly ignored
     49      SUCCESS: click at 10, 10 was correctly ignoredSUCCESS: click received at: 30, 100SUCCESS: click at 29, 100 was correctly ignoredSUCCESS: click received at: 30, 50SUCCESS: click at 30, 49 was correctly ignoredSUCCESS: click received at: 30, 150SUCCESS: click at 30, 151 was correctly ignoredSUCCESS: click received at: 300, 100SUCCESS: click at 301, 100 was correctly ignoredSUCCESS: click received at: 300, 50SUCCESS: click at 300, 49 was correctly ignoredSUCCESS: click received at: 300, 150SUCCESS: click at 300, 151 was correctly ignored
    5050   
    5151 
     
    7272      testClick(300, 150, true);
    7373      testClick(300, 151, false);
    74       testClick(1000, 1000, false);
    7574    } else {
    7675      log("ERROR: window.eventSender not found!  This test must be run using DumpRenderTree.  Mousing over the yellow area will log however.");
  • trunk/LayoutTests/svg/custom/stroke-width-click.svg

    r16574 r17574  
    7373      testClick(300, 150, true);
    7474      testClick(300, 151, false);
    75       testClick(1000, 1000, false);
    7675    } else {
    7776      log("ERROR: window.eventSender not found!  This test must be run using DumpRenderTree.  Mousing over the yellow area will log however.");
  • trunk/WebCore/ChangeLog

    r17573 r17574  
     12006-11-03  Alexey Proskuryakov  <ap@nypop.com>
     2
     3        Reviewed by Adele.
     4
     5        http://bugs.webkit.org/show_bug.cgi?id=7323
     6        REGRESSION (10.4.4): ondrag* events don't fire on page in a frame
     7
     8        * bridge/mac/FrameMac.h: Moved drag source information to a static variable
     9        in FrameMac.mm. There can be only one drag active at any moment, and having
     10        this information here was making sharing this information between
     11        subframes hard.
     12
     13        * bridge/mac/FrameMac.mm:
     14        (WebCore::FrameMac::FrameMac): Initialize sharedDragInfo.
     15        (WebCore::FrameMac::freeClipboard):
     16        (WebCore::FrameMac::dragHysteresisExceeded):
     17        (WebCore::FrameMac::handleMouseMoveEvent):
     18        (WebCore::FrameMac::handleMouseReleaseEvent):
     19        (WebCore::FrameMac::mouseDown):
     20        (WebCore::FrameMac::dragSourceMovedTo):
     21        (WebCore::FrameMac::dragSourceEndedAt):
     22        (WebCore::FrameMac::dispatchDragSrcEvent):
     23        Access drag source info via sharedDragInfo - this fixes drag source even dispatching.
     24        Also removed some old code that was forwarding mouse events to subviews to make
     25        HTML editing work in subframes.
     26
     27        * page/FrameView.cpp:
     28        (WebCore::FrameView::updateDragAndDrop):
     29        (WebCore::FrameView::cancelDragAndDrop):
     30        (WebCore::FrameView::performDragAndDrop):
     31        Forward events to subframes for dispatching - this fixes drag target events.
     32
    1332006-11-03  Zack Rusin  <zack@kde.org>
    234
  • trunk/WebCore/bridge/mac/FrameMac.h

    r17504 r17574  
    350350    WebScriptObject* _windowScriptObject;
    351351    NPObject* _windowScriptNPObject;
    352    
    353     RefPtr<Node> _dragSrc;     // element that may be a drag source, for the current mouse gesture
    354     bool _dragSrcIsLink;
    355     bool _dragSrcIsImage;
    356     bool _dragSrcInSelection;
    357     bool _dragSrcMayBeDHTML, _dragSrcMayBeUA;   // Are DHTML and/or the UserAgent allowed to drag out?
    358     bool _dragSrcIsDHTML;
    359     RefPtr<ClipboardMac> _dragClipboard;   // used on only the source side of dragging
    360    
     352
    361353    RefPtr<Range> m_markedTextRange;
    362354};
  • trunk/WebCore/bridge/mac/FrameMac.mm

    r17509 r17574  
    11/*
    22 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.  All rights reserved.
     3 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    115116NSEvent* FrameMac::_currentEvent = nil;
    116117
     118struct FrameMacDragInfo {
     119    RefPtr<Node> m_dragSrc;     // element that may be a drag source, for the current mouse gesture
     120    bool m_dragSrcIsLink;
     121    bool m_dragSrcIsImage;
     122    bool m_dragSrcInSelection;
     123    bool m_dragSrcMayBeDHTML, m_dragSrcMayBeUA;   // Are DHTML and/or the UserAgent allowed to drag out?
     124    bool m_dragSrcIsDHTML;
     125    RefPtr<ClipboardMac> m_dragClipboard;   // used on only the source side of dragging
     126};
     127
     128static FrameMacDragInfo* sharedDragInfo;
     129
    117130static const unsigned int escChar = 27;
    118131static SEL selectorForKeyEvent(const PlatformKeyboardEvent* event)
     
    157170    , _windowScriptNPObject(0)
    158171{
     172     if (!sharedDragInfo)
     173         sharedDragInfo = new FrameMacDragInfo;
    159174}
    160175
     
    251266void FrameMac::freeClipboard()
    252267{
    253     if (_dragClipboard)
    254         _dragClipboard->setAccessPolicy(ClipboardNumb);
     268    if (sharedDragInfo->m_dragClipboard)
     269        sharedDragInfo->m_dragClipboard->setAccessPolicy(ClipboardNumb);
    255270}
    256271
     
    15061521   
    15071522    float threshold = GeneralDragHysteresis;
    1508     if (_dragSrcIsImage)
     1523    if (sharedDragInfo->m_dragSrcIsImage)
    15091524        threshold = ImageDragHysteresis;
    1510     else if (_dragSrcIsLink)
     1525    else if (sharedDragInfo->m_dragSrcIsLink)
    15111526        threshold = LinkDragHysteresis;
    1512     else if (_dragSrcInSelection)
     1527    else if (sharedDragInfo->m_dragSrcInSelection)
    15131528        threshold = TextDragHysteresis;
    15141529
     
    15211536
    15221537    if ([_currentEvent type] == NSLeftMouseDragged) {
    1523         NSView *view = mouseDownViewIfStillGood();
    1524 
    1525         if (view) {
    1526             _sendingEventToSubview = true;
    1527             [view mouseDragged:_currentEvent];
    1528             _sendingEventToSubview = false;
    1529             return;
    1530         }
     1538        if (mouseDownViewIfStillGood())
     1539            return; // The event has been already dispatched to a subframe
    15311540
    15321541        // Careful that the drag starting logic stays in sync with eventMayStartDrag()
    15331542   
    1534         if (mouseDownMayStartDrag() && !_dragSrc) {
     1543        if (mouseDownMayStartDrag() && !sharedDragInfo->m_dragSrc) {
    15351544            BOOL tempFlag1, tempFlag2;
    15361545            [_bridge allowDHTMLDrag:&tempFlag1 UADrag:&tempFlag2];
    1537             _dragSrcMayBeDHTML = tempFlag1;
    1538             _dragSrcMayBeUA = tempFlag2;
    1539             if (!_dragSrcMayBeDHTML && !_dragSrcMayBeUA) {
     1546            sharedDragInfo->m_dragSrcMayBeDHTML = tempFlag1;
     1547            sharedDragInfo->m_dragSrcMayBeUA = tempFlag2;
     1548            if (!sharedDragInfo->m_dragSrcMayBeDHTML && !sharedDragInfo->m_dragSrcMayBeUA)
    15401549                setMouseDownMayStartDrag(false);     // no element is draggable
    1541             }
    15421550        }
    15431551       
    1544         if (mouseDownMayStartDrag() && !_dragSrc) {
     1552        if (mouseDownMayStartDrag() && !sharedDragInfo->m_dragSrc) {
    15451553            // try to find an element that wants to be dragged
    15461554            HitTestRequest request(true, false);
     
    15481556            renderer()->layer()->hitTest(request, result);
    15491557            Node *node = result.innerNode();
    1550             _dragSrc = (node && node->renderer()) ? node->renderer()->draggableNode(_dragSrcMayBeDHTML, _dragSrcMayBeUA, m_mouseDownPos.x(), m_mouseDownPos.y(), _dragSrcIsDHTML) : 0;
    1551             if (!_dragSrc) {
     1558            sharedDragInfo->m_dragSrc = (node && node->renderer()) ? node->renderer()->draggableNode(sharedDragInfo->m_dragSrcMayBeDHTML, sharedDragInfo->m_dragSrcMayBeUA, m_mouseDownPos.x(), m_mouseDownPos.y(), sharedDragInfo->m_dragSrcIsDHTML) : 0;
     1559            if (!sharedDragInfo->m_dragSrc) {
    15521560                setMouseDownMayStartDrag(false);     // no element is draggable
    15531561            } else {
    15541562                // remember some facts about this source, while we have a HitTestResult handy
    15551563                node = result.URLElement();
    1556                 _dragSrcIsLink = node && node->isLink();
     1564                sharedDragInfo->m_dragSrcIsLink = node && node->isLink();
    15571565
    15581566                node = result.innerNonSharedNode();
    1559                 _dragSrcIsImage = node && node->renderer() && node->renderer()->isImage();
     1567                sharedDragInfo->m_dragSrcIsImage = node && node->renderer() && node->renderer()->isImage();
    15601568               
    1561                 _dragSrcInSelection = selectionController()->contains(m_mouseDownPos);
     1569                sharedDragInfo->m_dragSrcInSelection = selectionController()->contains(m_mouseDownPos);
    15621570            }               
    15631571        }
     
    15651573        // For drags starting in the selection, the user must wait between the mousedown and mousedrag,
    15661574        // or else we bail on the dragging stuff and allow selection to occur
    1567         if (mouseDownMayStartDrag() && _dragSrcInSelection && [_currentEvent timestamp] - _mouseDownTimestamp < TextDragDelay) {
     1575        if (mouseDownMayStartDrag() && sharedDragInfo->m_dragSrcInSelection && [_currentEvent timestamp] - _mouseDownTimestamp < TextDragDelay) {
    15681576            setMouseDownMayStartDrag(false);
    15691577            // ...but if this was the first click in the window, we don't even want to start selection
     
    15871595                NSDragOperation srcOp = NSDragOperationNone;               
    15881596                BOOL wcWrotePasteboard = NO;
    1589                 if (_dragSrcMayBeDHTML) {
     1597                if (sharedDragInfo->m_dragSrcMayBeDHTML) {
    15901598                    NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
    15911599                    // Must be done before ondragstart adds types and data to the pboard,
     
    15951603                    freeClipboard();    // would only happen if we missed a dragEnd.  Do it anyway, just
    15961604                                        // to make sure it gets numbified
    1597                     _dragClipboard = new ClipboardMac(true, pasteboard, ClipboardWritable, this);
     1605                    sharedDragInfo->m_dragClipboard = new ClipboardMac(true, pasteboard, ClipboardWritable, this);
    15981606                   
    15991607                    // If this is drag of an element, get set up to generate a default image.  Otherwise
    16001608                    // WebKit will generate the default, the element doesn't override.
    1601                     if (_dragSrcIsDHTML) {
     1609                    if (sharedDragInfo->m_dragSrcIsDHTML) {
    16021610                        int srcX, srcY;
    1603                         _dragSrc->renderer()->absolutePosition(srcX, srcY);
     1611                        sharedDragInfo->m_dragSrc->renderer()->absolutePosition(srcX, srcY);
    16041612                        IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY);
    1605                         _dragClipboard->setDragImageElement(_dragSrc.get(), IntPoint() + delta);
     1613                        sharedDragInfo->m_dragClipboard->setDragImageElement(sharedDragInfo->m_dragSrc.get(), IntPoint() + delta);
    16061614                    }
    16071615
     
    16091617                    // Invalidate clipboard here against anymore pasteboard writing for security.  The drag
    16101618                    // image can still be changed as we drag, but not the pasteboard data.
    1611                     _dragClipboard->setAccessPolicy(ClipboardImageWritable);
     1619                    sharedDragInfo->m_dragClipboard->setAccessPolicy(ClipboardImageWritable);
    16121620                   
    16131621                    if (mouseDownMayStartDrag()) {
    16141622                        // gather values from DHTML element, if it set any
    1615                         _dragClipboard->sourceOperation(srcOp);
     1623                        sharedDragInfo->m_dragClipboard->sourceOperation(srcOp);
    16161624
    16171625                        NSArray *types = [pasteboard types];
    16181626                        wcWrotePasteboard = types && [types count] > 0;
    16191627
    1620                         if (_dragSrcMayBeDHTML)
    1621                             dragImage = _dragClipboard->dragNSImage(dragLoc);
     1628                        if (sharedDragInfo->m_dragSrcMayBeDHTML)
     1629                            dragImage = sharedDragInfo->m_dragClipboard->dragNSImage(dragLoc);
    16221630                       
    16231631                        // Yuck, dragSourceMovedTo() can be called as a result of kicking off the drag with
    16241632                        // dragImage!  Because of that dumb reentrancy, we may think we've not started the
    16251633                        // drag when that happens.  So we have to assume it's started before we kick it off.
    1626                         _dragClipboard->setDragHasStarted();
     1634                        sharedDragInfo->m_dragClipboard->setDragHasStarted();
    16271635                    }
    16281636                }
    16291637               
    16301638                if (mouseDownMayStartDrag()) {
    1631                     BOOL startedDrag = [_bridge startDraggingImage:dragImage at:dragLoc operation:srcOp event:_currentEvent sourceIsDHTML:_dragSrcIsDHTML DHTMLWroteData:wcWrotePasteboard];
    1632                     if (!startedDrag && _dragSrcMayBeDHTML) {
    1633                         // WebKit canned the drag at the last minute - we owe _dragSrc a DRAGEND event
     1639                    BOOL startedDrag = [_bridge startDraggingImage:dragImage at:dragLoc operation:srcOp event:_currentEvent sourceIsDHTML:sharedDragInfo->m_dragSrcIsDHTML DHTMLWroteData:wcWrotePasteboard];
     1640                    if (!startedDrag && sharedDragInfo->m_dragSrcMayBeDHTML) {
     1641                        // WebKit canned the drag at the last minute - we owe m_dragSrc a DRAGEND event
    16341642                        PlatformMouseEvent event(PlatformMouseEvent::currentEvent);
    16351643                        dispatchDragSrcEvent(dragendEvent, event);
     
    16411649                    // something failed to start the drag, cleanup
    16421650                    freeClipboard();
    1643                     _dragSrc = 0;
     1651                    sharedDragInfo->m_dragSrc = 0;
    16441652                }
    16451653            }
     
    17521760    }
    17531761    stopAutoscrollTimer();
    1754    
    1755     _sendingEventToSubview = true;
    1756     BEGIN_BLOCK_OBJC_EXCEPTIONS;
    1757     [view mouseUp:_currentEvent];
    1758     END_BLOCK_OBJC_EXCEPTIONS;
    1759     _sendingEventToSubview = false;
    17601762}
    17611763
     
    18501852
    18511853    _mouseDownView = nil;
    1852     _dragSrc = 0;
     1854    sharedDragInfo->m_dragSrc = 0;
    18531855   
    18541856    NSEvent *oldCurrentEvent = _currentEvent;
     
    29552957void FrameMac::dragSourceMovedTo(const PlatformMouseEvent& event)
    29562958{
    2957     if (_dragSrc && _dragSrcMayBeDHTML)
     2959    if (sharedDragInfo->m_dragSrc && sharedDragInfo->m_dragSrcMayBeDHTML)
    29582960        // for now we don't care if event handler cancels default behavior, since there is none
    29592961        dispatchDragSrcEvent(dragEvent, event);
     
    29622964void FrameMac::dragSourceEndedAt(const PlatformMouseEvent& event, NSDragOperation operation)
    29632965{
    2964     if (_dragSrc && _dragSrcMayBeDHTML) {
    2965         _dragClipboard->setDestinationOperation(operation);
     2966    if (sharedDragInfo->m_dragSrc && sharedDragInfo->m_dragSrcMayBeDHTML) {
     2967        sharedDragInfo->m_dragClipboard->setDestinationOperation(operation);
    29662968        // for now we don't care if event handler cancels default behavior, since there is none
    29672969        dispatchDragSrcEvent(dragendEvent, event);
    29682970    }
    29692971    freeClipboard();
    2970     _dragSrc = 0;
     2972    sharedDragInfo->m_dragSrc = 0;
    29712973}
    29722974
    29732975// returns if we should continue "default processing", i.e., whether eventhandler canceled
    2974 bool FrameMac::dispatchDragSrcEvent(const AtomicString &eventType, const PlatformMouseEvent& event) const
    2975 {
    2976     bool noDefaultProc = d->m_view->dispatchDragEvent(eventType, _dragSrc.get(), event, _dragClipboard.get());
     2976bool FrameMac::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event) const
     2977{
     2978    bool noDefaultProc = d->m_view->dispatchDragEvent(eventType, sharedDragInfo->m_dragSrc.get(), event, sharedDragInfo->m_dragClipboard.get());
    29772979    return !noDefaultProc;
    29782980}
  • trunk/WebCore/page/FrameView.cpp

    r17504 r17574  
    77 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
    88 *           (C) 2006 Graham Dennis (graham.dennis@gmail.com)
     9 *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    910 *
    1011 * This library is free software; you can redistribute it and/or
     
    3536#include "FrameTree.h"
    3637#include "HTMLDocument.h"
     38#include "HTMLFrameElementBase.h"
    3739#include "HTMLFrameSetElement.h"
    3840#include "HTMLInputElement.h"
     
    943945
    944946    if (d->dragTarget != newTarget) {
    945         // note this ordering is explicitly chosen to match WinIE
     947        // FIXME: this ordering was explicitly chosen to match WinIE. However,
     948        // it is sometimes incorrect when dragging within subframes, as seen with
     949        // LayoutTests/fast/events/drag-in-frames.html.
    946950        if (newTarget)
    947             accept = dispatchDragEvent(dragenterEvent, newTarget, event, clipboard);
     951            if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
     952                accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->view()->updateDragAndDrop(event, clipboard);
     953            else
     954                accept = dispatchDragEvent(dragenterEvent, newTarget, event, clipboard);
     955       
    948956        if (d->dragTarget)
    949             dispatchDragEvent(dragleaveEvent, d->dragTarget.get(), event, clipboard);
     957            if (d->dragTarget->hasTagName(frameTag) || d->dragTarget->hasTagName(iframeTag))
     958                accept = static_cast<HTMLFrameElementBase*>(d->dragTarget.get())->contentFrame()->view()->updateDragAndDrop(event, clipboard);
     959            else
     960                dispatchDragEvent(dragleaveEvent, d->dragTarget.get(), event, clipboard);
    950961    } else {
    951962        if (newTarget)
    952             accept = dispatchDragEvent(dragoverEvent, newTarget, event, clipboard);
     963            if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
     964                accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->view()->updateDragAndDrop(event, clipboard);
     965            else
     966                accept = dispatchDragEvent(dragoverEvent, newTarget, event, clipboard);
    953967    }
    954968    d->dragTarget = newTarget;
     
    960974{
    961975    if (d->dragTarget)
    962         dispatchDragEvent(dragleaveEvent, d->dragTarget.get(), event, clipboard);
     976        if (d->dragTarget->hasTagName(frameTag) || d->dragTarget->hasTagName(iframeTag))
     977            static_cast<HTMLFrameElementBase*>(d->dragTarget.get())->contentFrame()->view()->cancelDragAndDrop(event, clipboard);
     978        else
     979            dispatchDragEvent(dragleaveEvent, d->dragTarget.get(), event, clipboard);
    963980    d->dragTarget = 0;
    964981}
     
    968985    bool accept = false;
    969986    if (d->dragTarget)
    970         accept = dispatchDragEvent(dropEvent, d->dragTarget.get(), event, clipboard);
     987        if (d->dragTarget->hasTagName(frameTag) || d->dragTarget->hasTagName(iframeTag))
     988            accept = static_cast<HTMLFrameElementBase*>(d->dragTarget.get())->contentFrame()->view()->performDragAndDrop(event, clipboard);
     989        else
     990            accept = dispatchDragEvent(dropEvent, d->dragTarget.get(), event, clipboard);
    971991    d->dragTarget = 0;
    972992    return accept;
  • trunk/WebKitTools/ChangeLog

    r17562 r17574  
     12006-11-03  Alexey Proskuryakov  <ap@nypop.com>
     2
     3        Reviewed by Adele.
     4
     5        http://bugs.webkit.org/show_bug.cgi?id=7323
     6        REGRESSION (10.4.4): ondrag* events don't fire on page in a frame
     7
     8        When dragging, do not send EventSendingController's events immediately. Dragging
     9        is supposed to be modal, so we need to perform it from within the delegate, without
     10        returning to JS to make the next mouse movement.
     11
     12        When the mouse is down, mouse events are now recorded, and executed when mouseUp is sent.
     13
     14        * DumpRenderTree/EventSendingController.h:
     15        * DumpRenderTree/EventSendingController.m:
     16        (-[EventSendingController dealloc]):
     17        (-[EventSendingController leapForward:]):
     18        (-[EventSendingController mouseDown]):
     19        (-[EventSendingController mouseUp]):
     20        (-[EventSendingController mouseMoveToX:Y:]):
     21        (+[EventSendingController saveEvent:]):
     22        (+[EventSendingController replaySavedEvents]):
     23        * DumpRenderTree/UIDelegate.m:
     24        (-[UIDelegate webView:dragImage:at:offset:event:pasteboard:source:slideBack:forView:]):
     25
    1262006-11-02  Geoffrey Garen  <ggaren@apple.com>
    227
  • trunk/WebKitTools/DumpRenderTree/EventSendingController.h

    r15008 r17574  
    3939}
    4040
     41+ (void)saveEvent:(NSInvocation *)event;
     42+ (void)replaySavedEvents;
     43
    4144- (void)enableDOMUIEventLogging:(WebScriptObject *)node;
    4245
  • trunk/WebKitTools/DumpRenderTree/EventSendingController.m

    r17347 r17574  
    33 * Copyright (C) 2006 Jonas Witt <jonas.witt@gmail.com>
    44 * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
     5 * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
    56 *
    67 * Redistribution and use in source and binary forms, with or without
     
    4243NSPoint lastMousePosition;
    4344NSArray *webkitDomEventNames;
     45NSMutableArray *savedMouseEvents; // mouse events sent between mouseDown and mouseUp are stored here, and then executed at once.
     46BOOL replayingSavedEvents;
    4447
    4548@implementation EventSendingController
     
    127130}
    128131
     132- (void)dealloc
     133{
     134    assert(!down);
     135    assert([savedMouseEvents count] == 0);
     136    [savedMouseEvents release];
     137    savedMouseEvents = nil;
     138    [super dealloc];
     139}
     140
    129141- (double)currentEventTime
    130142{
     
    134146- (void)leapForward:(int)milliseconds
    135147{
     148    if (down && !replayingSavedEvents) {
     149        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(leapForward:)]];
     150        [invocation setTarget:self];
     151        [invocation setSelector:@selector(leapForward:)];
     152        [invocation setArgument:&milliseconds atIndex:2];
     153       
     154        [EventSendingController saveEvent:invocation];
     155       
     156        return;
     157    }
     158
    136159    timeOffset += milliseconds / 1000.0;
    137160}
     
    144167- (void)mouseDown
    145168{
     169    assert(!down);
     170    assert(!replayingSavedEvents);
     171
    146172    [[[frame frameView] documentView] layout];
    147173    if ([self currentEventTime] - lastClick >= 1)
     
    168194- (void)mouseUp
    169195{
     196    assert(down);
     197
     198    if (!replayingSavedEvents) {
     199        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseUp)]];
     200        [invocation setTarget:self];
     201        [invocation setSelector:@selector(mouseUp)];
     202       
     203        [EventSendingController saveEvent:invocation];
     204        [EventSendingController replaySavedEvents];
     205
     206        return;
     207    }
     208
     209
    170210    [[[frame frameView] documentView] layout];
    171211    NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseUp
     
    202242- (void)mouseMoveToX:(int)x Y:(int)y
    203243{
     244    if (down && !replayingSavedEvents) {
     245        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[EventSendingController instanceMethodSignatureForSelector:@selector(mouseMoveToX:Y:)]];
     246        [invocation setTarget:self];
     247        [invocation setSelector:@selector(mouseMoveToX:Y:)];
     248        [invocation setArgument:&x atIndex:2];
     249        [invocation setArgument:&y atIndex:3];
     250       
     251        [EventSendingController saveEvent:invocation];
     252       
     253        return;
     254    }
     255
    204256    NSView *view = [frame webView];
    205257    lastMousePosition = [view convertPoint:NSMakePoint(x, [view frame].size.height - y) toView:nil];
     
    260312        lastClick = [mouseUpEvent timestamp];
    261313    }
     314}
     315
     316+ (void)saveEvent:(NSInvocation *)event
     317{
     318    if (!savedMouseEvents)
     319        savedMouseEvents = [[NSMutableArray alloc] init];
     320    [savedMouseEvents addObject:event];
     321}
     322
     323+ (void)replaySavedEvents
     324{
     325    replayingSavedEvents = YES;
     326    while ([savedMouseEvents count]) {
     327        // if a drag is initiated, the remaining saved events will be dispatched from our dragging delegate
     328        NSInvocation *invocation = [[[savedMouseEvents objectAtIndex:0] retain] autorelease];
     329        [savedMouseEvents removeObjectAtIndex:0];
     330        [invocation invoke];
     331    }
     332    replayingSavedEvents = NO;
    262333}
    263334
  • trunk/WebKitTools/DumpRenderTree/UIDelegate.m

    r17468 r17574  
    4747- (void)webView:(WebView *)sender dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag forView:(NSView *)view
    4848{
    49     // A new drag was started before the old one ended.  Probably shouldn't happen.
    50     if (draggingInfo) {
    51         [[draggingInfo draggingSource] draggedImage:[draggingInfo draggedImage] endedAt:lastMousePosition operation:NSDragOperationNone];
    52         [draggingInfo release];
    53     }
    54     draggingInfo = [[DumpRenderTreeDraggingInfo alloc] initWithImage:anImage offset:initialOffset pasteboard:pboard source:sourceObj];
     49     assert(!draggingInfo);
     50     draggingInfo = [[DumpRenderTreeDraggingInfo alloc] initWithImage:anImage offset:initialOffset pasteboard:pboard source:sourceObj];
     51     [EventSendingController replaySavedEvents];
    5552}
    5653
Note: See TracChangeset for help on using the changeset viewer.