Changeset 142575 in webkit
- Timestamp:
- Feb 11, 2013 8:43:56 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r142574 r142575 1 2013-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 1 62 2013-02-11 peavo@outlook.com <peavo@outlook.com> 2 63 -
trunk/Source/WebCore/dom/EventContext.cpp
r142072 r142575 41 41 , m_currentTarget(currentTarget) 42 42 , m_target(target) 43 , m_relatedTarget(0)44 43 { 45 44 ASSERT(m_node); 46 45 ASSERT(!isUnreachableNode(m_target.get())); 46 } 47 48 EventContext::~EventContext() 49 { 47 50 } 48 51 … … 51 54 event->setTarget(m_target.get()); 52 55 event->setCurrentTarget(m_currentTarget.get()); 56 m_node->handleLocalEvents(event); 57 } 58 59 bool EventContext::isMouseOrFocusEventContext() const 60 { 61 return false; 62 } 63 64 MouseOrFocusEventContext::MouseOrFocusEventContext(PassRefPtr<Node> node, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target) 65 : EventContext(node, currentTarget, target) 66 , m_relatedTarget(0) 67 { 68 } 69 70 MouseOrFocusEventContext::~MouseOrFocusEventContext() 71 { 72 } 73 74 void MouseOrFocusEventContext::handleLocalEvents(Event* event) const 75 { 76 ASSERT(event->isMouseEvent() || event->isFocusEvent()); 53 77 if (m_relatedTarget.get() && event->isMouseEvent()) 54 78 toMouseEvent(event)->setRelatedTarget(m_relatedTarget.get()); 55 79 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 84 bool MouseOrFocusEventContext::isMouseOrFocusEventContext() const 85 { 86 return true; 58 87 } 59 88 -
trunk/Source/WebCore/dom/EventContext.h
r120806 r142575 41 41 // FIXME: Use ContainerNode instead of Node. 42 42 EventContext(PassRefPtr<Node>, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target); 43 virtual ~EventContext(); 43 44 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; 50 50 51 pr ivate:51 protected: 52 52 #ifndef NDEBUG 53 53 bool isUnreachableNode(EventTarget*); … … 57 57 RefPtr<EventTarget> m_currentTarget; 58 58 RefPtr<EventTarget> m_target; 59 }; 60 61 typedef Vector<OwnPtr<EventContext>, 32> EventPath; 62 63 class MouseOrFocusEventContext : public EventContext { 64 public: 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 72 private: 59 73 RefPtr<EventTarget> m_relatedTarget; 60 74 }; 61 62 inline Node* EventContext::node() const63 {64 return m_node.get();65 }66 67 inline EventTarget* EventContext::target() const68 {69 return m_target.get();70 }71 72 inline bool EventContext::currentTargetSameAsTarget() const73 {74 return m_currentTarget.get() == m_target.get();75 }76 77 inline EventTarget* EventContext::relatedTarget() const78 {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 }87 75 88 76 #ifndef NDEBUG … … 105 93 #endif 106 94 95 inline void MouseOrFocusEventContext::setRelatedTarget(PassRefPtr<EventTarget> relatedTarget) 96 { 97 ASSERT(!isUnreachableNode(relatedTarget.get())); 98 m_relatedTarget = relatedTarget; 99 } 100 107 101 } 108 102 -
trunk/Source/WebCore/dom/EventDispatcher.cpp
r141119 r142575 61 61 } 62 62 63 void EventRelatedTargetAdjuster::adjust( Vector<EventContext, 32>& ancestors)63 void EventRelatedTargetAdjuster::adjust(EventPath& eventPath) 64 64 { 65 65 // Synthetic mouse events can have a relatedTarget which is identical to the target. … … 87 87 lastTreeScope = 0; 88 88 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(); 91 93 if (scope == lastTreeScope) { 92 94 // Re-use the previous adjustedRelatedTarget if treeScope does not change. Just for the performance optimization. 93 iter->setRelatedTarget(adjustedRelatedTarget);95 mosueOrFocusEventContext->setRelatedTarget(adjustedRelatedTarget); 94 96 } else { 95 97 adjustedRelatedTarget = findRelatedTarget(scope); 96 iter->setRelatedTarget(adjustedRelatedTarget);98 mosueOrFocusEventContext->setRelatedTarget(adjustedRelatedTarget); 97 99 } 98 100 lastTreeScope = scope; 99 101 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()); 102 104 break; 103 105 } 104 } else if ( iter->target() == adjustedRelatedTarget) {106 } else if (mosueOrFocusEventContext->target() == adjustedRelatedTarget) { 105 107 // Event dispatching should be stopped here. 106 ancestors.shrink(iter - ancestors.begin());108 eventPath.shrink(iter - eventPath.begin()); 107 109 break; 108 110 } … … 170 172 if (!m_node.get()) 171 173 return; 172 ensureEvent Ancestors(event);173 EventRelatedTargetAdjuster(m_node, relatedTarget.release()).adjust(m_ ancestors);174 ensureEventPath(event); 175 EventRelatedTargetAdjuster(m_node, relatedTarget.release()).adjust(m_eventPath); 174 176 } 175 177 176 178 EventDispatcher::EventDispatcher(Node* node) 177 179 : m_node(node) 178 , m_ ancestorsInitialized(false)180 , m_eventPathInitialized(false) 179 181 #ifndef NDEBUG 180 182 , m_eventDispatched(false) … … 185 187 } 186 188 187 void EventDispatcher::ensureEvent Ancestors(Event* event)188 { 189 if (m_ ancestorsInitialized)190 return; 191 m_ ancestorsInitialized = true;189 void EventDispatcher::ensureEventPath(Event* event) 190 { 191 if (m_eventPathInitialized) 192 return; 193 m_eventPathInitialized = true; 192 194 bool inDocument = m_node->inDocument(); 193 195 bool isSVGElement = m_node->isSVGElement(); 196 bool isMouseOrFocusEvent = event->isMouseEvent() || event->isFocusEvent(); 194 197 Vector<EventTarget*, 32> targetStack; 195 198 for (AncestorChainWalker walker(m_node.get()); walker.get(); walker.parent()) { … … 199 202 else if (walker.crossingInsertionPoint()) 200 203 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()))); 202 208 if (!inDocument) 203 209 return; … … 261 267 ASSERT(event->target()); 262 268 ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null. 263 ensureEvent Ancestors(event.get());269 ensureEventPath(event.get()); 264 270 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); 266 272 267 273 void* preDispatchEventHandlerResult; … … 285 291 // Give the target node a chance to do some work before DOM event handlers get a crack. 286 292 preDispatchEventHandlerResult = m_node->preDispatchEventHandler(event.get()); 287 return (m_ ancestors.isEmpty() || event->propagationStopped()) ? DoneDispatching : ContinueDispatching;293 return (m_eventPath.isEmpty() || event->propagationStopped()) ? DoneDispatching : ContinueDispatching; 288 294 } 289 295 … … 296 302 return DoneDispatching; 297 303 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]; 300 306 if (eventContext.currentTargetSameAsTarget()) { 301 307 if (event->bubbles()) … … 315 321 { 316 322 event->setEventPhase(Event::AT_TARGET); 317 m_ ancestors[0].handleLocalEvents(event.get());323 m_eventPath[0]->handleLocalEvents(event.get()); 318 324 return event->propagationStopped() ? DoneDispatching : ContinueDispatching; 319 325 } … … 325 331 event->setEventPhase(Event::BUBBLING_PHASE); 326 332 327 size_t size = m_ ancestors.size();333 size_t size = m_eventPath.size(); 328 334 for (size_t i = 1; i < size; ++i) { 329 const EventContext& eventContext = m_ancestors[i];335 const EventContext& eventContext = *m_eventPath[i]; 330 336 if (eventContext.currentTargetSameAsTarget()) 331 337 event->setEventPhase(Event::AT_TARGET); … … 362 368 // same order as the bubbling phase. 363 369 if (event->bubbles()) { 364 size_t size = m_ ancestors.size();370 size_t size = m_eventPath.size(); 365 371 for (size_t i = 1; i < size; ++i) { 366 m_ ancestors[i].node()->defaultEventHandler(event.get());372 m_eventPath[i]->node()->defaultEventHandler(event.get()); 367 373 ASSERT(!event->defaultPrevented()); 368 374 if (event->defaultHandled()) … … 375 381 const EventContext* EventDispatcher::topEventContext() 376 382 { 377 return m_ ancestors.isEmpty() ? 0 : &m_ancestors.last();383 return m_eventPath.isEmpty() ? 0 : m_eventPath.last().get(); 378 384 } 379 385 -
trunk/Source/WebCore/dom/EventDispatcher.h
r137680 r142575 59 59 public: 60 60 EventRelatedTargetAdjuster(PassRefPtr<Node>, PassRefPtr<Node> relatedTarget); 61 void adjust( Vector<EventContext, 32>&);61 void adjust(EventPath&); 62 62 private: 63 63 typedef HashMap<TreeScope*, EventTarget*> RelatedTargetMap; … … 85 85 EventDispatchBehavior determineDispatchBehavior(Event*, ShadowRoot*, EventTarget*); 86 86 87 void ensureEvent Ancestors(Event*);87 void ensureEventPath(Event*); 88 88 const EventContext* topEventContext(); 89 89 … … 94 94 void dispatchEventPostProcess(PassRefPtr<Event>, void* preDispatchEventHandlerResult); 95 95 96 Vector<EventContext, 32> m_ancestors;96 EventPath m_eventPath; 97 97 RefPtr<Node> m_node; 98 98 RefPtr<FrameView> m_view; 99 bool m_ ancestorsInitialized;99 bool m_eventPathInitialized; 100 100 #ifndef NDEBUG 101 101 bool m_eventDispatched; -
trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp
r142460 r142575 94 94 int InspectorInstrumentation::s_frontendCounter = 0; 95 95 96 static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)96 static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const EventPath& eventPath) 97 97 { 98 98 if (window && window->hasEventListeners(eventType)) … … 102 102 return true; 103 103 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)) 107 106 return true; 108 107 } … … 388 387 } 389 388 390 InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InstrumentingAgents* instrumentingAgents, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors, Document* document)389 InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InstrumentingAgents* instrumentingAgents, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath, Document* document) 391 390 { 392 391 int timelineAgentId = 0; 393 392 InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent(); 394 if (timelineAgent && eventHasListeners(event.type(), window, node, ancestors)) {393 if (timelineAgent && eventHasListeners(event.type(), window, node, eventPath)) { 395 394 timelineAgent->willDispatchEvent(event, document->frame()); 396 395 timelineAgentId = timelineAgent->id(); -
trunk/Source/WebCore/inspector/InspectorInstrumentation.h
r141555 r142575 36 36 #include "ConsoleTypes.h" 37 37 #include "Element.h" 38 #include "EventContext.h" 38 39 #include "Frame.h" 39 40 #include "HitTestResult.h" … … 144 145 static InspectorInstrumentationCookie willDispatchXHRReadyStateChangeEvent(ScriptExecutionContext*, XMLHttpRequest*); 145 146 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&); 147 148 static void didDispatchEvent(const InspectorInstrumentationCookie&); 148 149 static InspectorInstrumentationCookie willHandleEvent(ScriptExecutionContext*, Event*); … … 348 349 static InspectorInstrumentationCookie willDispatchXHRReadyStateChangeEventImpl(InstrumentingAgents*, XMLHttpRequest*, ScriptExecutionContext*); 349 350 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*); 351 352 static InspectorInstrumentationCookie willHandleEventImpl(InstrumentingAgents*, Event*); 352 353 static void didHandleEventImpl(const InspectorInstrumentationCookie&); … … 865 866 } 866 867 867 inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)868 inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath) 868 869 { 869 870 #if ENABLE(INSPECTOR) 870 871 FAST_RETURN_IF_NO_FRONTENDS(InspectorInstrumentationCookie()); 871 872 if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(document)) 872 return willDispatchEventImpl(instrumentingAgents, event, window, node, ancestors, document);873 return willDispatchEventImpl(instrumentingAgents, event, window, node, eventPath, document); 873 874 #else 874 875 UNUSED_PARAM(document);
Note: See TracChangeset
for help on using the changeset viewer.