Changeset 142575 in webkit


Ignore:
Timestamp:
Feb 11, 2013 8:43:56 PM (11 years ago)
Author:
hayato@chromium.org
Message:

Factor EventContext and introduces MouseOrFocusEventContext.
https://bugs.webkit.org/show_bug.cgi?id=109278

Reviewed by Dimitri Glazkov.

To supoort Touch event retargeting (bug 107800), we have to factor
event retargeting code so that it can support not only MouseEvent or FocusEvent,
but also other events.

This is the first attempt to refactor event retargeting code, a
separated patch from bug 109156. EventContext is now factored and
MouseOrFocusEventContext was introduced to support MouseEvent or
FocusEvent separately.

In following patches, I'll introduce TouchEventContext and
TouchEventDispatchMediator to support Touch event retargeting.

No new tests. No change in functionality.

  • dom/EventContext.cpp:

(WebCore::EventContext::EventContext): Factor relatedTarget out from EventContext into MouseOrFocusEventContext.
(WebCore::EventContext::~EventContext):
(WebCore):
(WebCore::EventContext::handleLocalEvents):
(WebCore::EventContext::isMouseOrFocusEventContext):
(WebCore::MouseOrFocusEventContext::MouseOrFocusEventContext): New. Handles MouseEvent's (or FocusEvent's) relatedTarget retargeting.
(WebCore::MouseOrFocusEventContext::~MouseOrFocusEventContext):
(WebCore::MouseOrFocusEventContext::handleLocalEvents):
(WebCore::MouseOrFocusEventContext::isMouseOrFocusEventContext):

  • dom/EventContext.h:

(EventContext):
(WebCore::EventContext::node):
(WebCore::EventContext::target):
(WebCore::EventContext::currentTargetSameAsTarget):
(WebCore):
(MouseOrFocusEventContext):
(WebCore::MouseOrFocusEventContext::relatedTarget):
(WebCore::MouseOrFocusEventContext::setRelatedTarget):

  • dom/EventDispatcher.cpp:

(WebCore::EventRelatedTargetAdjuster::adjust):
(WebCore::EventDispatcher::adjustRelatedTarget):
(WebCore::EventDispatcher::ensureEventPath): Renamad from ensureEventAncestors. Use the DOM Core terminology.
(WebCore::EventDispatcher::dispatchEvent):
(WebCore::EventDispatcher::dispatchEventAtCapturing):
(WebCore::EventDispatcher::dispatchEventAtTarget):
(WebCore::EventDispatcher::dispatchEventAtBubbling):
(WebCore::EventDispatcher::dispatchEventPostProcess):
(WebCore::EventDispatcher::topEventContext):

  • dom/EventDispatcher.h:

(EventRelatedTargetAdjuster):
(EventDispatcher):

  • inspector/InspectorInstrumentation.cpp:

(WebCore):
(WebCore::eventHasListeners):
(WebCore::InspectorInstrumentation::willDispatchEventImpl):

  • inspector/InspectorInstrumentation.h:

(InspectorInstrumentation):
(WebCore::InspectorInstrumentation::willDispatchEvent):

Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r142574 r142575  
     12013-02-11  Hayato Ito  <hayato@chromium.org>
     2
     3        Factor EventContext and introduces MouseOrFocusEventContext.
     4        https://bugs.webkit.org/show_bug.cgi?id=109278
     5
     6        Reviewed by Dimitri Glazkov.
     7
     8        To supoort Touch event retargeting (bug 107800), we have to factor
     9        event retargeting code so that it can support not only MouseEvent or FocusEvent,
     10        but also other events.
     11
     12        This is the first attempt to refactor event retargeting code, a
     13        separated patch from bug 109156.  EventContext is now factored and
     14        MouseOrFocusEventContext was introduced to support MouseEvent or
     15        FocusEvent separately.
     16
     17        In following patches, I'll introduce TouchEventContext and
     18        TouchEventDispatchMediator to support Touch event retargeting.
     19
     20        No new tests. No change in functionality.
     21
     22        * dom/EventContext.cpp:
     23        (WebCore::EventContext::EventContext): Factor relatedTarget out from EventContext into MouseOrFocusEventContext.
     24        (WebCore::EventContext::~EventContext):
     25        (WebCore):
     26        (WebCore::EventContext::handleLocalEvents):
     27        (WebCore::EventContext::isMouseOrFocusEventContext):
     28        (WebCore::MouseOrFocusEventContext::MouseOrFocusEventContext):  New. Handles MouseEvent's (or FocusEvent's) relatedTarget retargeting.
     29        (WebCore::MouseOrFocusEventContext::~MouseOrFocusEventContext):
     30        (WebCore::MouseOrFocusEventContext::handleLocalEvents):
     31        (WebCore::MouseOrFocusEventContext::isMouseOrFocusEventContext):
     32        * dom/EventContext.h:
     33        (EventContext):
     34        (WebCore::EventContext::node):
     35        (WebCore::EventContext::target):
     36        (WebCore::EventContext::currentTargetSameAsTarget):
     37        (WebCore):
     38        (MouseOrFocusEventContext):
     39        (WebCore::MouseOrFocusEventContext::relatedTarget):
     40        (WebCore::MouseOrFocusEventContext::setRelatedTarget):
     41        * dom/EventDispatcher.cpp:
     42        (WebCore::EventRelatedTargetAdjuster::adjust):
     43        (WebCore::EventDispatcher::adjustRelatedTarget):
     44        (WebCore::EventDispatcher::ensureEventPath):  Renamad from ensureEventAncestors. Use the DOM Core terminology.
     45        (WebCore::EventDispatcher::dispatchEvent):
     46        (WebCore::EventDispatcher::dispatchEventAtCapturing):
     47        (WebCore::EventDispatcher::dispatchEventAtTarget):
     48        (WebCore::EventDispatcher::dispatchEventAtBubbling):
     49        (WebCore::EventDispatcher::dispatchEventPostProcess):
     50        (WebCore::EventDispatcher::topEventContext):
     51        * dom/EventDispatcher.h:
     52        (EventRelatedTargetAdjuster):
     53        (EventDispatcher):
     54        * inspector/InspectorInstrumentation.cpp:
     55        (WebCore):
     56        (WebCore::eventHasListeners):
     57        (WebCore::InspectorInstrumentation::willDispatchEventImpl):
     58        * inspector/InspectorInstrumentation.h:
     59        (InspectorInstrumentation):
     60        (WebCore::InspectorInstrumentation::willDispatchEvent):
     61
    1622013-02-11  peavo@outlook.com  <peavo@outlook.com>
    263
  • trunk/Source/WebCore/dom/EventContext.cpp

    r142072 r142575  
    4141    , m_currentTarget(currentTarget)
    4242    , m_target(target)
    43     , m_relatedTarget(0)
    4443{
    4544    ASSERT(m_node);
    4645    ASSERT(!isUnreachableNode(m_target.get()));
     46}
     47
     48EventContext::~EventContext()
     49{
    4750}
    4851
     
    5154    event->setTarget(m_target.get());
    5255    event->setCurrentTarget(m_currentTarget.get());
     56    m_node->handleLocalEvents(event);
     57}
     58
     59bool EventContext::isMouseOrFocusEventContext() const
     60{
     61    return false;
     62}
     63
     64MouseOrFocusEventContext::MouseOrFocusEventContext(PassRefPtr<Node> node, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target)
     65    : EventContext(node, currentTarget, target)
     66    , m_relatedTarget(0)
     67{
     68}
     69
     70MouseOrFocusEventContext::~MouseOrFocusEventContext()
     71{
     72}
     73
     74void MouseOrFocusEventContext::handleLocalEvents(Event* event) const
     75{
     76    ASSERT(event->isMouseEvent() || event->isFocusEvent());
    5377    if (m_relatedTarget.get() && event->isMouseEvent())
    5478        toMouseEvent(event)->setRelatedTarget(m_relatedTarget.get());
    5579    else if (m_relatedTarget.get() && event->isFocusEvent())
    56         toFocusEvent(event)->setRelatedTarget(m_relatedTarget);
    57     m_node->handleLocalEvents(event);
     80        toFocusEvent(event)->setRelatedTarget(m_relatedTarget.get());
     81    EventContext::handleLocalEvents(event);
     82}
     83
     84bool MouseOrFocusEventContext::isMouseOrFocusEventContext() const
     85{
     86    return true;
    5887}
    5988
  • trunk/Source/WebCore/dom/EventContext.h

    r120806 r142575  
    4141    // FIXME: Use ContainerNode instead of Node.
    4242    EventContext(PassRefPtr<Node>, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target);
     43    virtual ~EventContext();
    4344
    44     Node* node() const;
    45     EventTarget* target() const;
    46     EventTarget* relatedTarget() const;
    47     bool currentTargetSameAsTarget() const;
    48     void handleLocalEvents(Event*) const;
    49     void setRelatedTarget(PassRefPtr<EventTarget>);
     45    Node* node() const { return m_node.get(); }
     46    EventTarget* target() const { return m_target.get(); }
     47    bool currentTargetSameAsTarget() const { return m_currentTarget.get() == m_target.get(); }
     48    virtual void handleLocalEvents(Event*) const;
     49    virtual bool isMouseOrFocusEventContext() const;
    5050
    51 private:
     51protected:
    5252#ifndef NDEBUG
    5353    bool isUnreachableNode(EventTarget*);
     
    5757    RefPtr<EventTarget> m_currentTarget;
    5858    RefPtr<EventTarget> m_target;
     59};
     60
     61typedef Vector<OwnPtr<EventContext>, 32> EventPath;
     62
     63class MouseOrFocusEventContext : public EventContext {
     64public:
     65    MouseOrFocusEventContext(PassRefPtr<Node>, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target);
     66    virtual ~MouseOrFocusEventContext();
     67    EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
     68    void setRelatedTarget(PassRefPtr<EventTarget>);
     69    virtual void handleLocalEvents(Event*) const OVERRIDE;
     70    virtual bool isMouseOrFocusEventContext() const OVERRIDE;
     71
     72private:
    5973    RefPtr<EventTarget> m_relatedTarget;
    6074};
    61 
    62 inline Node* EventContext::node() const
    63 {
    64     return m_node.get();
    65 }
    66 
    67 inline EventTarget* EventContext::target() const
    68 {
    69     return m_target.get();
    70 }
    71 
    72 inline bool EventContext::currentTargetSameAsTarget() const
    73 {
    74     return m_currentTarget.get() == m_target.get();
    75 }
    76 
    77 inline EventTarget* EventContext::relatedTarget() const
    78 {
    79     return m_relatedTarget.get();
    80 }
    81 
    82 inline void EventContext::setRelatedTarget(PassRefPtr<EventTarget> relatedTarget)
    83 {
    84     ASSERT(!isUnreachableNode(relatedTarget.get()));
    85     m_relatedTarget = relatedTarget;
    86 }
    8775
    8876#ifndef NDEBUG
     
    10593#endif
    10694
     95inline void MouseOrFocusEventContext::setRelatedTarget(PassRefPtr<EventTarget> relatedTarget)
     96{
     97    ASSERT(!isUnreachableNode(relatedTarget.get()));
     98    m_relatedTarget = relatedTarget;
     99}
     100
    107101}
    108102
  • trunk/Source/WebCore/dom/EventDispatcher.cpp

    r141119 r142575  
    6161}
    6262
    63 void EventRelatedTargetAdjuster::adjust(Vector<EventContext, 32>& ancestors)
     63void EventRelatedTargetAdjuster::adjust(EventPath& eventPath)
    6464{
    6565    // Synthetic mouse events can have a relatedTarget which is identical to the target.
     
    8787    lastTreeScope = 0;
    8888    EventTarget* adjustedRelatedTarget = 0;
    89     for (Vector<EventContext, 32>::iterator iter = ancestors.begin(); iter < ancestors.end(); ++iter) {
    90         TreeScope* scope = iter->node()->treeScope();
     89    for (EventPath::iterator iter = eventPath.begin(); iter < eventPath.end(); ++iter) {
     90        ASSERT((*iter)->isMouseOrFocusEventContext());
     91        MouseOrFocusEventContext* mosueOrFocusEventContext = static_cast<MouseOrFocusEventContext*>(iter->get());
     92        TreeScope* scope = mosueOrFocusEventContext->node()->treeScope();
    9193        if (scope == lastTreeScope) {
    9294            // Re-use the previous adjustedRelatedTarget if treeScope does not change. Just for the performance optimization.
    93             iter->setRelatedTarget(adjustedRelatedTarget);
     95            mosueOrFocusEventContext->setRelatedTarget(adjustedRelatedTarget);
    9496        } else {
    9597            adjustedRelatedTarget = findRelatedTarget(scope);
    96             iter->setRelatedTarget(adjustedRelatedTarget);
     98            mosueOrFocusEventContext->setRelatedTarget(adjustedRelatedTarget);
    9799        }
    98100        lastTreeScope = scope;
    99101        if (targetIsIdenticalToToRelatedTarget) {
    100             if (m_node->treeScope()->rootNode() == iter->node()) {
    101                 ancestors.shrink(iter + 1 - ancestors.begin());
     102            if (m_node->treeScope()->rootNode() == mosueOrFocusEventContext->node()) {
     103                eventPath.shrink(iter + 1 - eventPath.begin());
    102104                break;
    103105            }
    104         } else if (iter->target() == adjustedRelatedTarget) {
     106        } else if (mosueOrFocusEventContext->target() == adjustedRelatedTarget) {
    105107            // Event dispatching should be stopped here.
    106             ancestors.shrink(iter - ancestors.begin());
     108            eventPath.shrink(iter - eventPath.begin());
    107109            break;
    108110        }
     
    170172    if (!m_node.get())
    171173        return;
    172     ensureEventAncestors(event);
    173     EventRelatedTargetAdjuster(m_node, relatedTarget.release()).adjust(m_ancestors);
     174    ensureEventPath(event);
     175    EventRelatedTargetAdjuster(m_node, relatedTarget.release()).adjust(m_eventPath);
    174176}
    175177
    176178EventDispatcher::EventDispatcher(Node* node)
    177179    : m_node(node)
    178     , m_ancestorsInitialized(false)
     180    , m_eventPathInitialized(false)
    179181#ifndef NDEBUG
    180182    , m_eventDispatched(false)
     
    185187}
    186188
    187 void EventDispatcher::ensureEventAncestors(Event* event)
    188 {
    189     if (m_ancestorsInitialized)
    190         return;
    191     m_ancestorsInitialized = true;
     189void EventDispatcher::ensureEventPath(Event* event)
     190{
     191    if (m_eventPathInitialized)
     192        return;
     193    m_eventPathInitialized = true;
    192194    bool inDocument = m_node->inDocument();
    193195    bool isSVGElement = m_node->isSVGElement();
     196    bool isMouseOrFocusEvent = event->isMouseEvent() || event->isFocusEvent();
    194197    Vector<EventTarget*, 32> targetStack;
    195198    for (AncestorChainWalker walker(m_node.get()); walker.get(); walker.parent()) {
     
    199202        else if (walker.crossingInsertionPoint())
    200203            targetStack.append(targetStack.last());
    201         m_ancestors.append(EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last()));
     204        if (isMouseOrFocusEvent)
     205            m_eventPath.append(adoptPtr(new MouseOrFocusEventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
     206        else
     207            m_eventPath.append(adoptPtr(new EventContext(node, eventTargetRespectingTargetRules(node), targetStack.last())));
    202208        if (!inDocument)
    203209            return;
     
    261267    ASSERT(event->target());
    262268    ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
    263     ensureEventAncestors(event.get());
     269    ensureEventPath(event.get());
    264270    WindowEventContext windowEventContext(event.get(), m_node.get(), topEventContext());
    265     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowEventContext.window(), m_node.get(), m_ancestors);
     271    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowEventContext.window(), m_node.get(), m_eventPath);
    266272
    267273    void* preDispatchEventHandlerResult;
     
    285291    // Give the target node a chance to do some work before DOM event handlers get a crack.
    286292    preDispatchEventHandlerResult = m_node->preDispatchEventHandler(event.get());
    287     return (m_ancestors.isEmpty() || event->propagationStopped()) ? DoneDispatching : ContinueDispatching;
     293    return (m_eventPath.isEmpty() || event->propagationStopped()) ? DoneDispatching : ContinueDispatching;
    288294}
    289295
     
    296302        return DoneDispatching;
    297303
    298     for (size_t i = m_ancestors.size() - 1; i > 0; --i) {
    299         const EventContext& eventContext = m_ancestors[i];
     304    for (size_t i = m_eventPath.size() - 1; i > 0; --i) {
     305        const EventContext& eventContext = *m_eventPath[i];
    300306        if (eventContext.currentTargetSameAsTarget()) {
    301307            if (event->bubbles())
     
    315321{
    316322    event->setEventPhase(Event::AT_TARGET);
    317     m_ancestors[0].handleLocalEvents(event.get());
     323    m_eventPath[0]->handleLocalEvents(event.get());
    318324    return event->propagationStopped() ? DoneDispatching : ContinueDispatching;
    319325}
     
    325331        event->setEventPhase(Event::BUBBLING_PHASE);
    326332
    327         size_t size = m_ancestors.size();
     333        size_t size = m_eventPath.size();
    328334        for (size_t i = 1; i < size; ++i) {
    329             const EventContext& eventContext = m_ancestors[i];
     335            const EventContext& eventContext = *m_eventPath[i];
    330336            if (eventContext.currentTargetSameAsTarget())
    331337                event->setEventPhase(Event::AT_TARGET);
     
    362368        // same order as the bubbling phase.
    363369        if (event->bubbles()) {
    364             size_t size = m_ancestors.size();
     370            size_t size = m_eventPath.size();
    365371            for (size_t i = 1; i < size; ++i) {
    366                 m_ancestors[i].node()->defaultEventHandler(event.get());
     372                m_eventPath[i]->node()->defaultEventHandler(event.get());
    367373                ASSERT(!event->defaultPrevented());
    368374                if (event->defaultHandled())
     
    375381const EventContext* EventDispatcher::topEventContext()
    376382{
    377     return m_ancestors.isEmpty() ? 0 : &m_ancestors.last();
     383    return m_eventPath.isEmpty() ? 0 : m_eventPath.last().get();
    378384}
    379385
  • trunk/Source/WebCore/dom/EventDispatcher.h

    r137680 r142575  
    5959public:
    6060    EventRelatedTargetAdjuster(PassRefPtr<Node>, PassRefPtr<Node> relatedTarget);
    61     void adjust(Vector<EventContext, 32>&);
     61    void adjust(EventPath&);
    6262private:
    6363    typedef HashMap<TreeScope*, EventTarget*> RelatedTargetMap;
     
    8585    EventDispatchBehavior determineDispatchBehavior(Event*, ShadowRoot*, EventTarget*);
    8686
    87     void ensureEventAncestors(Event*);
     87    void ensureEventPath(Event*);
    8888    const EventContext* topEventContext();
    8989
     
    9494    void dispatchEventPostProcess(PassRefPtr<Event>, void* preDispatchEventHandlerResult);
    9595
    96     Vector<EventContext, 32> m_ancestors;
     96    EventPath m_eventPath;
    9797    RefPtr<Node> m_node;
    9898    RefPtr<FrameView> m_view;
    99     bool m_ancestorsInitialized;
     99    bool m_eventPathInitialized;
    100100#ifndef NDEBUG
    101101    bool m_eventDispatched;
  • trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp

    r142460 r142575  
    9494int InspectorInstrumentation::s_frontendCounter = 0;
    9595
    96 static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)
     96static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const EventPath& eventPath)
    9797{
    9898    if (window && window->hasEventListeners(eventType))
     
    102102        return true;
    103103
    104     for (size_t i = 0; i < ancestors.size(); i++) {
    105         Node* ancestor = ancestors[i].node();
    106         if (ancestor->hasEventListeners(eventType))
     104    for (size_t i = 0; i < eventPath.size(); i++) {
     105        if (eventPath[i]->node()->hasEventListeners(eventType))
    107106            return true;
    108107    }
     
    388387}
    389388
    390 InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InstrumentingAgents* instrumentingAgents, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors, Document* document)
     389InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InstrumentingAgents* instrumentingAgents, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath, Document* document)
    391390{
    392391    int timelineAgentId = 0;
    393392    InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent();
    394     if (timelineAgent && eventHasListeners(event.type(), window, node, ancestors)) {
     393    if (timelineAgent && eventHasListeners(event.type(), window, node, eventPath)) {
    395394        timelineAgent->willDispatchEvent(event, document->frame());
    396395        timelineAgentId = timelineAgent->id();
  • trunk/Source/WebCore/inspector/InspectorInstrumentation.h

    r141555 r142575  
    3636#include "ConsoleTypes.h"
    3737#include "Element.h"
     38#include "EventContext.h"
    3839#include "Frame.h"
    3940#include "HitTestResult.h"
     
    144145    static InspectorInstrumentationCookie willDispatchXHRReadyStateChangeEvent(ScriptExecutionContext*, XMLHttpRequest*);
    145146    static void didDispatchXHRReadyStateChangeEvent(const InspectorInstrumentationCookie&);
    146     static InspectorInstrumentationCookie willDispatchEvent(Document*, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors);
     147    static InspectorInstrumentationCookie willDispatchEvent(Document*, const Event&, DOMWindow*, Node*, const EventPath&);
    147148    static void didDispatchEvent(const InspectorInstrumentationCookie&);
    148149    static InspectorInstrumentationCookie willHandleEvent(ScriptExecutionContext*, Event*);
     
    348349    static InspectorInstrumentationCookie willDispatchXHRReadyStateChangeEventImpl(InstrumentingAgents*, XMLHttpRequest*, ScriptExecutionContext*);
    349350    static void didDispatchXHRReadyStateChangeEventImpl(const InspectorInstrumentationCookie&);
    350     static InspectorInstrumentationCookie willDispatchEventImpl(InstrumentingAgents*, const Event&, DOMWindow*, Node*, const Vector<EventContext>& ancestors, Document*);
     351    static InspectorInstrumentationCookie willDispatchEventImpl(InstrumentingAgents*, const Event&, DOMWindow*, Node*, const EventPath&, Document*);
    351352    static InspectorInstrumentationCookie willHandleEventImpl(InstrumentingAgents*, Event*);
    352353    static void didHandleEventImpl(const InspectorInstrumentationCookie&);
     
    865866}
    866867
    867 inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)
     868inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath)
    868869{
    869870#if ENABLE(INSPECTOR)
    870871    FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie());
    871872    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document))
    872         return willDispatchEventImpl(instrumentingAgents, event, window, node, ancestors, document);
     873        return willDispatchEventImpl(instrumentingAgents, event, window, node, eventPath, document);
    873874#else
    874875    UNUSED_PARAM(document);
Note: See TracChangeset for help on using the changeset viewer.