Changeset 136818 in webkit


Ignore:
Timestamp:
Dec 6, 2012 12:52:47 AM (11 years ago)
Author:
hayato@chromium.org
Message:

Event's relatedTarget re-targeting does not occur for manually fired mouse events created by event.initMouseEvent().
https://bugs.webkit.org/show_bug.cgi?id=102681

Reviewed by Dimitri Glazkov.

Source/WebCore:

Make sure that event's relatedTarget re-targeting occurs for mouse
events created by event.initMouseEvent(). Since user-generated
mouse events can have a relatedTarget which is same to the target
node, the algorithm which calculates event's ancestors is also
updated so that ancestors are not shrunk wrongly.

Test: fast/events/dispatch-synthetic-mouseevent.html

fast/dom/shadow/shadow-dom-event-dispatching.html

  • dom/EventDispatcher.cpp:

(WebCore::EventRelatedTargetAdjuster::adjust):

  • dom/MouseEvent.cpp:

(WebCore::MouseEventDispatchMediator::create):
(WebCore::MouseEventDispatchMediator::MouseEventDispatchMediator):
(WebCore::MouseEventDispatchMediator::dispatchEvent):

  • dom/MouseEvent.h:

(WebCore::MouseEventDispatchMediator::isSyntheticMouseEvent):
(MouseEventDispatchMediator):

  • dom/Node.cpp:

(WebCore::Node::dispatchEvent):

LayoutTests:

  • fast/dom/shadow/shadow-dom-event-dispatching-expected.txt:
  • fast/dom/shadow/shadow-dom-event-dispatching.html:
  • fast/events/dispatch-synthetic-mouseevent-expected.txt: Added.
  • fast/events/dispatch-synthetic-mouseevent.html: Added.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r136814 r136818  
     12012-12-06  Hayato Ito  <hayato@chromium.org>
     2
     3        Event's relatedTarget re-targeting does not occur for manually fired mouse events created by event.initMouseEvent().
     4        https://bugs.webkit.org/show_bug.cgi?id=102681
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        * fast/dom/shadow/shadow-dom-event-dispatching-expected.txt:
     9        * fast/dom/shadow/shadow-dom-event-dispatching.html:
     10        * fast/events/dispatch-synthetic-mouseevent-expected.txt: Added.
     11        * fast/events/dispatch-synthetic-mouseevent.html: Added.
     12
    1132012-12-06  Zan Dobersek  <zandobersek@gmail.com>
    214
  • trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-expected.txt

    r121040 r136818  
    436436     @A (target: A)
    437437     @top (target: A)
     438
     439
     440Composed Shadow Tree will be:
     441DIV      id=sandbox
     442        DIV      id=top
     443                DIV      id=host
     444                        DIV      id=div1
     445                        DIV      id=div2
     446
     447
     448  mouseout
     449
     450  mouseover
     451     @div2 (target: div2) (related: div1)
     452     @shadow-root (target: div2) (related: div1)
     453
     454
     455Composed Shadow Tree will be:
     456DIV      id=sandbox
     457        DIV      id=top
     458                DIV      id=host
     459                        DIV      id=div1
     460
     461
     462  mouseout
     463
     464  mouseover
     465     @div1 (target: div1) (related: div1)
     466     @shadow-root (target: div1) (related: div1)
    438467PASS successfullyParsed is true
    439468
  • trunk/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching.html

    r131070 r136818  
    379379}
    380380
     381function testEventsFiredManually()
     382{
     383    sandbox.innerHTML = '';
     384    sandbox.appendChild(
     385        createDOM('div', {'id': 'top'},
     386                  createDOM('div', {'id': 'host'},
     387                            createShadowRoot(
     388                                createDOM('div', {'id': 'div1'}),
     389                                createDOM('div', {'id': 'div2'})))));
     390
     391    addEventListeners(['top', 'host', 'host/', 'host/div1', 'host/div2']);
     392    getNodeInShadowTreeStack('host/').id = 'shadow-root';
     393    showSandboxTree();
     394
     395    var div1 = getNodeInShadowTreeStack('host/div1');
     396    var div2 = getNodeInShadowTreeStack('host/div2');
     397
     398    clearEventRecords();
     399    var event = document.createEvent("MouseEvents");
     400    event.initMouseEvent("mouseover", true, false, window,
     401                         0, 10, 10, 10, 10, false, false, false, false, 0, div1);
     402    div2.dispatchEvent(event);
     403
     404    debugDispatchedEvent('mouseout');
     405    debugDispatchedEvent('mouseover');
     406}
     407
     408function testEventsFiredManuallyWithRelatedTargetSameToTarget()
     409{
     410    sandbox.innerHTML = '';
     411    sandbox.appendChild(
     412        createDOM('div', {'id': 'top'},
     413                  createDOM('div', {'id': 'host'},
     414                            createShadowRoot(
     415                                createDOM('div', {'id': 'div1'})))));
     416
     417    addEventListeners(['top', 'host', 'host/', 'host/div1']);
     418    getNodeInShadowTreeStack('host/').id = 'shadow-root';
     419    showSandboxTree();
     420
     421    var div1 = getNodeInShadowTreeStack('host/div1');
     422
     423    clearEventRecords();
     424    var event = document.createEvent("MouseEvents");
     425    event.initMouseEvent("mouseover", true, false, window,
     426                         0, 10, 10, 10, 10, false, false, false, false, 0, div1);
     427    div1.dispatchEvent(event);
     428
     429    debugDispatchedEvent('mouseout');
     430    debugDispatchedEvent('mouseover');
     431}
     432
    381433function test()
    382434{
     
    394446    testEventsOnNonDistributedNodes();
    395447    testEventsOnFallbackElements();
     448    testEventsFiredManually();
     449    testEventsFiredManuallyWithRelatedTargetSameToTarget();
    396450}
    397451
  • trunk/Source/WebCore/ChangeLog

    r136817 r136818  
     12012-12-06  Hayato Ito  <hayato@chromium.org>
     2
     3        Event's relatedTarget re-targeting does not occur for manually fired mouse events created by event.initMouseEvent().
     4        https://bugs.webkit.org/show_bug.cgi?id=102681
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        Make sure that event's relatedTarget re-targeting occurs for mouse
     9        events created by event.initMouseEvent().  Since user-generated
     10        mouse events can have a relatedTarget which is same to the target
     11        node, the algorithm which calculates event's ancestors is also
     12        updated so that ancestors are not shrunk wrongly.
     13
     14        Test: fast/events/dispatch-synthetic-mouseevent.html
     15              fast/dom/shadow/shadow-dom-event-dispatching.html
     16
     17        * dom/EventDispatcher.cpp:
     18        (WebCore::EventRelatedTargetAdjuster::adjust):
     19        * dom/MouseEvent.cpp:
     20        (WebCore::MouseEventDispatchMediator::create):
     21        (WebCore::MouseEventDispatchMediator::MouseEventDispatchMediator):
     22        (WebCore::MouseEventDispatchMediator::dispatchEvent):
     23        * dom/MouseEvent.h:
     24        (WebCore::MouseEventDispatchMediator::isSyntheticMouseEvent):
     25        (MouseEventDispatchMediator):
     26        * dom/Node.cpp:
     27        (WebCore::Node::dispatchEvent):
     28
    1292012-12-06  Michael Pruett  <michael@68k.org>
    230
  • trunk/Source/WebCore/dom/EventDispatcher.cpp

    r135690 r136818  
    6363void EventRelatedTargetAdjuster::adjust(Vector<EventContext>& ancestors)
    6464{
     65    // Synthetic mouse events can have a relatedTarget which is identical to the target.
     66    bool targetIsIdenticalToToRelatedTarget = (m_node.get() == m_relatedTarget.get());
     67
    6568    Vector<EventTarget*> relatedTargetStack;
    6669    TreeScope* lastTreeScope = 0;
     
    9497        }
    9598        lastTreeScope = scope;
    96         if (iter->target() == adjustedRelatedTarget) {
     99        if (targetIsIdenticalToToRelatedTarget) {
     100            if (m_node->treeScope()->rootNode() == iter->node()) {
     101                ancestors.shrink(iter + 1 - ancestors.begin());
     102                break;
     103            }
     104        } else if (iter->target() == adjustedRelatedTarget) {
    97105            // Event dispatching should be stopped here.
    98106            ancestors.shrink(iter - ancestors.begin());
  • trunk/Source/WebCore/dom/MouseEvent.cpp

    r135650 r136818  
    210210}
    211211
    212 PassRefPtr<MouseEventDispatchMediator> MouseEventDispatchMediator::create(PassRefPtr<MouseEvent> mouseEvent)
    213 {
    214     return adoptRef(new MouseEventDispatchMediator(mouseEvent));
    215 }
    216 
    217 MouseEventDispatchMediator::MouseEventDispatchMediator(PassRefPtr<MouseEvent> mouseEvent)
    218     : EventDispatchMediator(mouseEvent)
     212PassRefPtr<MouseEventDispatchMediator> MouseEventDispatchMediator::create(PassRefPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType)
     213{
     214    return adoptRef(new MouseEventDispatchMediator(mouseEvent, mouseEventType));
     215}
     216
     217MouseEventDispatchMediator::MouseEventDispatchMediator(PassRefPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType)
     218    : EventDispatchMediator(mouseEvent), m_mouseEventType(mouseEventType)
    219219{
    220220}
     
    233233        return true; // Shouldn't happen.
    234234
     235    ASSERT(isSyntheticMouseEvent() || !event()->target() || event()->target() != event()->relatedTarget());
     236
    235237    EventTarget* relatedTarget = event()->relatedTarget();
    236238    dispatcher->adjustRelatedTarget(event(), relatedTarget);
     
    239241    bool swallowEvent = event()->defaultHandled() || event()->defaultPrevented();
    240242
    241     if (event()->type() != eventNames().clickEvent || event()->detail() != 2)
     243    if (isSyntheticMouseEvent() || event()->type() != eventNames().clickEvent || event()->detail() != 2)
    242244        return !swallowEvent;
     245
    243246    // Special case: If it's a double click event, we also send the dblclick event. This is not part
    244247    // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
  • trunk/Source/WebCore/dom/MouseEvent.h

    r126256 r136818  
    116116class MouseEventDispatchMediator : public EventDispatchMediator {
    117117public:
    118     static PassRefPtr<MouseEventDispatchMediator> create(PassRefPtr<MouseEvent>);
     118    enum MouseEventType { SyntheticMouseEvent, NonSyntheticMouseEvent};
     119    static PassRefPtr<MouseEventDispatchMediator> create(PassRefPtr<MouseEvent>, MouseEventType = NonSyntheticMouseEvent);
    119120
    120121private:
    121     explicit MouseEventDispatchMediator(PassRefPtr<MouseEvent>);
     122    explicit MouseEventDispatchMediator(PassRefPtr<MouseEvent>, MouseEventType);
    122123    MouseEvent* event() const;
    123124
    124125    virtual bool dispatchEvent(EventDispatcher*) const;
     126    bool isSyntheticMouseEvent() const { return m_mouseEventType == SyntheticMouseEvent; }
     127    MouseEventType m_mouseEventType;
    125128};
    126129
  • trunk/Source/WebCore/dom/Node.cpp

    r136744 r136818  
    24822482bool Node::dispatchEvent(PassRefPtr<Event> event)
    24832483{
     2484    if (event->isMouseEvent())
     2485        return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(adoptRef(toMouseEvent(event.leakRef())), MouseEventDispatchMediator::SyntheticMouseEvent));
    24842486    return EventDispatcher::dispatchEvent(this, EventDispatchMediator::create(event));
    24852487}
Note: See TracChangeset for help on using the changeset viewer.