| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All |
| 6 * rights reserved. |
| 6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. |
| 9 * (http://www.torchmobile.com/) |
| 8 * Copyright (C) 2011 Google Inc. All rights reserved. | 10 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 9 * | 11 * |
| 10 * This library is free software; you can redistribute it and/or | 12 * This library is free software; you can redistribute it and/or |
| 11 * modify it under the terms of the GNU Library General Public | 13 * modify it under the terms of the GNU Library General Public |
| 12 * License as published by the Free Software Foundation; either | 14 * License as published by the Free Software Foundation; either |
| 13 * version 2 of the License, or (at your option) any later version. | 15 * version 2 of the License, or (at your option) any later version. |
| 14 * | 16 * |
| 15 * This library is distributed in the hope that it will be useful, | 17 * This library is distributed in the hope that it will be useful, |
| 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 61 |
| 60 EventDispatcher::EventDispatcher(Node& node, Event* event) | 62 EventDispatcher::EventDispatcher(Node& node, Event* event) |
| 61 : m_node(node), m_event(event) { | 63 : m_node(node), m_event(event) { |
| 62 DCHECK(m_event.get()); | 64 DCHECK(m_event.get()); |
| 63 m_view = node.document().view(); | 65 m_view = node.document().view(); |
| 64 m_event->initEventPath(*m_node); | 66 m_event->initEventPath(*m_node); |
| 65 } | 67 } |
| 66 | 68 |
| 67 void EventDispatcher::dispatchScopedEvent(Node& node, | 69 void EventDispatcher::dispatchScopedEvent(Node& node, |
| 68 EventDispatchMediator* mediator) { | 70 EventDispatchMediator* mediator) { |
| 69 // We need to set the target here because it can go away by the time we actual
ly fire the event. | 71 // We need to set the target here because it can go away by the time we |
| 72 // actually fire the event. |
| 70 mediator->event().setTarget( | 73 mediator->event().setTarget( |
| 71 EventPath::eventTargetRespectingTargetRules(node)); | 74 EventPath::eventTargetRespectingTargetRules(node)); |
| 72 ScopedEventQueue::instance()->enqueueEventDispatchMediator(mediator); | 75 ScopedEventQueue::instance()->enqueueEventDispatchMediator(mediator); |
| 73 } | 76 } |
| 74 | 77 |
| 75 void EventDispatcher::dispatchSimulatedClick( | 78 void EventDispatcher::dispatchSimulatedClick( |
| 76 Node& node, | 79 Node& node, |
| 77 Event* underlyingEvent, | 80 Event* underlyingEvent, |
| 78 SimulatedClickMouseEventOptions mouseEventOptions, | 81 SimulatedClickMouseEventOptions mouseEventOptions, |
| 79 SimulatedClickCreationScope creationScope) { | 82 SimulatedClickCreationScope creationScope) { |
| 80 // This persistent vector doesn't cause leaks, because added Nodes are removed | 83 // This persistent vector doesn't cause leaks, because added Nodes are removed |
| 81 // before dispatchSimulatedClick() returns. This vector is here just to preven
t | 84 // before dispatchSimulatedClick() returns. This vector is here just to |
| 82 // the code from running into an infinite recursion of dispatchSimulatedClick(
). | 85 // prevent the code from running into an infinite recursion of |
| 86 // dispatchSimulatedClick(). |
| 83 DEFINE_STATIC_LOCAL(HeapHashSet<Member<Node>>, | 87 DEFINE_STATIC_LOCAL(HeapHashSet<Member<Node>>, |
| 84 nodesDispatchingSimulatedClicks, | 88 nodesDispatchingSimulatedClicks, |
| 85 (new HeapHashSet<Member<Node>>)); | 89 (new HeapHashSet<Member<Node>>)); |
| 86 | 90 |
| 87 if (isDisabledFormControl(&node)) | 91 if (isDisabledFormControl(&node)) |
| 88 return; | 92 return; |
| 89 | 93 |
| 90 if (nodesDispatchingSimulatedClicks.contains(&node)) | 94 if (nodesDispatchingSimulatedClicks.contains(&node)) |
| 91 return; | 95 return; |
| 92 | 96 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 | 128 |
| 125 DispatchEventResult EventDispatcher::dispatch() { | 129 DispatchEventResult EventDispatcher::dispatch() { |
| 126 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("blink.debug"), | 130 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("blink.debug"), |
| 127 "EventDispatcher::dispatch"); | 131 "EventDispatcher::dispatch"); |
| 128 | 132 |
| 129 #if DCHECK_IS_ON() | 133 #if DCHECK_IS_ON() |
| 130 DCHECK(!m_eventDispatched); | 134 DCHECK(!m_eventDispatched); |
| 131 m_eventDispatched = true; | 135 m_eventDispatched = true; |
| 132 #endif | 136 #endif |
| 133 if (event().eventPath().isEmpty()) { | 137 if (event().eventPath().isEmpty()) { |
| 134 // eventPath() can be empty if event path is shrinked by relataedTarget reta
rgeting. | 138 // eventPath() can be empty if event path is shrinked by relataedTarget |
| 139 // retargeting. |
| 135 return DispatchEventResult::NotCanceled; | 140 return DispatchEventResult::NotCanceled; |
| 136 } | 141 } |
| 137 m_event->eventPath().ensureWindowEventContext(); | 142 m_event->eventPath().ensureWindowEventContext(); |
| 138 | 143 |
| 139 m_event->setTarget(EventPath::eventTargetRespectingTargetRules(*m_node)); | 144 m_event->setTarget(EventPath::eventTargetRespectingTargetRules(*m_node)); |
| 140 #if DCHECK_IS_ON() | 145 #if DCHECK_IS_ON() |
| 141 DCHECK(!EventDispatchForbiddenScope::isEventDispatchForbidden()); | 146 DCHECK(!EventDispatchForbiddenScope::isEventDispatchForbidden()); |
| 142 #endif | 147 #endif |
| 143 DCHECK(m_event->target()); | 148 DCHECK(m_event->target()); |
| 144 TRACE_EVENT1("devtools.timeline", "EventDispatch", "data", | 149 TRACE_EVENT1("devtools.timeline", "EventDispatch", "data", |
| (...skipping 14 matching lines...) Expand all Loading... |
| 159 m_event->setCurrentTarget(nullptr); | 164 m_event->setCurrentTarget(nullptr); |
| 160 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), | 165 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), |
| 161 "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", | 166 "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", |
| 162 InspectorUpdateCountersEvent::data()); | 167 InspectorUpdateCountersEvent::data()); |
| 163 | 168 |
| 164 return EventTarget::dispatchEventResult(*m_event); | 169 return EventTarget::dispatchEventResult(*m_event); |
| 165 } | 170 } |
| 166 | 171 |
| 167 inline EventDispatchContinuation EventDispatcher::dispatchEventPreProcess( | 172 inline EventDispatchContinuation EventDispatcher::dispatchEventPreProcess( |
| 168 EventDispatchHandlingState*& preDispatchEventHandlerResult) { | 173 EventDispatchHandlingState*& preDispatchEventHandlerResult) { |
| 169 // Give the target node a chance to do some work before DOM event handlers get
a crack. | 174 // Give the target node a chance to do some work before DOM event handlers get |
| 175 // a crack. |
| 170 preDispatchEventHandlerResult = | 176 preDispatchEventHandlerResult = |
| 171 m_node->preDispatchEventHandler(m_event.get()); | 177 m_node->preDispatchEventHandler(m_event.get()); |
| 172 return (m_event->eventPath().isEmpty() || m_event->propagationStopped()) | 178 return (m_event->eventPath().isEmpty() || m_event->propagationStopped()) |
| 173 ? DoneDispatching | 179 ? DoneDispatching |
| 174 : ContinueDispatching; | 180 : ContinueDispatching; |
| 175 } | 181 } |
| 176 | 182 |
| 177 inline EventDispatchContinuation EventDispatcher::dispatchEventAtCapturing() { | 183 inline EventDispatchContinuation EventDispatcher::dispatchEventAtCapturing() { |
| 178 // Trigger capturing event handlers, starting at the top and working our way d
own. | 184 // Trigger capturing event handlers, starting at the top and working our way |
| 185 // down. |
| 179 m_event->setEventPhase(Event::kCapturingPhase); | 186 m_event->setEventPhase(Event::kCapturingPhase); |
| 180 | 187 |
| 181 if (m_event->eventPath().windowEventContext().handleLocalEvents(*m_event) && | 188 if (m_event->eventPath().windowEventContext().handleLocalEvents(*m_event) && |
| 182 m_event->propagationStopped()) | 189 m_event->propagationStopped()) |
| 183 return DoneDispatching; | 190 return DoneDispatching; |
| 184 | 191 |
| 185 for (size_t i = m_event->eventPath().size() - 1; i > 0; --i) { | 192 for (size_t i = m_event->eventPath().size() - 1; i > 0; --i) { |
| 186 const NodeEventContext& eventContext = m_event->eventPath()[i]; | 193 const NodeEventContext& eventContext = m_event->eventPath()[i]; |
| 187 if (eventContext.currentTargetSameAsTarget()) | 194 if (eventContext.currentTargetSameAsTarget()) |
| 188 continue; | 195 continue; |
| 189 eventContext.handleLocalEvents(*m_event); | 196 eventContext.handleLocalEvents(*m_event); |
| 190 if (m_event->propagationStopped()) | 197 if (m_event->propagationStopped()) |
| 191 return DoneDispatching; | 198 return DoneDispatching; |
| 192 } | 199 } |
| 193 | 200 |
| 194 return ContinueDispatching; | 201 return ContinueDispatching; |
| 195 } | 202 } |
| 196 | 203 |
| 197 inline EventDispatchContinuation EventDispatcher::dispatchEventAtTarget() { | 204 inline EventDispatchContinuation EventDispatcher::dispatchEventAtTarget() { |
| 198 m_event->setEventPhase(Event::kAtTarget); | 205 m_event->setEventPhase(Event::kAtTarget); |
| 199 m_event->eventPath()[0].handleLocalEvents(*m_event); | 206 m_event->eventPath()[0].handleLocalEvents(*m_event); |
| 200 return m_event->propagationStopped() ? DoneDispatching : ContinueDispatching; | 207 return m_event->propagationStopped() ? DoneDispatching : ContinueDispatching; |
| 201 } | 208 } |
| 202 | 209 |
| 203 inline void EventDispatcher::dispatchEventAtBubbling() { | 210 inline void EventDispatcher::dispatchEventAtBubbling() { |
| 204 // Trigger bubbling event handlers, starting at the bottom and working our way
up. | 211 // Trigger bubbling event handlers, starting at the bottom and working our way |
| 212 // up. |
| 205 size_t size = m_event->eventPath().size(); | 213 size_t size = m_event->eventPath().size(); |
| 206 for (size_t i = 1; i < size; ++i) { | 214 for (size_t i = 1; i < size; ++i) { |
| 207 const NodeEventContext& eventContext = m_event->eventPath()[i]; | 215 const NodeEventContext& eventContext = m_event->eventPath()[i]; |
| 208 if (eventContext.currentTargetSameAsTarget()) { | 216 if (eventContext.currentTargetSameAsTarget()) { |
| 209 m_event->setEventPhase(Event::kAtTarget); | 217 m_event->setEventPhase(Event::kAtTarget); |
| 210 } else if (m_event->bubbles() && !m_event->cancelBubble()) { | 218 } else if (m_event->bubbles() && !m_event->cancelBubble()) { |
| 211 m_event->setEventPhase(Event::kBubblingPhase); | 219 m_event->setEventPhase(Event::kBubblingPhase); |
| 212 } else { | 220 } else { |
| 213 if (m_event->bubbles() && m_event->cancelBubble() && | 221 if (m_event->bubbles() && m_event->cancelBubble() && |
| 214 eventContext.node() && | 222 eventContext.node() && |
| (...skipping 22 matching lines...) Expand all Loading... |
| 237 UseCounter::EventCancelBubbleAffected); | 245 UseCounter::EventCancelBubbleAffected); |
| 238 } | 246 } |
| 239 } | 247 } |
| 240 | 248 |
| 241 inline void EventDispatcher::dispatchEventPostProcess( | 249 inline void EventDispatcher::dispatchEventPostProcess( |
| 242 EventDispatchHandlingState* preDispatchEventHandlerResult) { | 250 EventDispatchHandlingState* preDispatchEventHandlerResult) { |
| 243 m_event->setTarget(EventPath::eventTargetRespectingTargetRules(*m_node)); | 251 m_event->setTarget(EventPath::eventTargetRespectingTargetRules(*m_node)); |
| 244 m_event->setCurrentTarget(nullptr); | 252 m_event->setCurrentTarget(nullptr); |
| 245 m_event->setEventPhase(0); | 253 m_event->setEventPhase(0); |
| 246 | 254 |
| 247 // Pass the data from the preDispatchEventHandler to the postDispatchEventHand
ler. | 255 // Pass the data from the preDispatchEventHandler to the |
| 256 // postDispatchEventHandler. |
| 248 m_node->postDispatchEventHandler(m_event.get(), | 257 m_node->postDispatchEventHandler(m_event.get(), |
| 249 preDispatchEventHandlerResult); | 258 preDispatchEventHandlerResult); |
| 250 | 259 |
| 251 bool isClick = m_event->isMouseEvent() && | 260 bool isClick = m_event->isMouseEvent() && |
| 252 toMouseEvent(*m_event).type() == EventTypeNames::click; | 261 toMouseEvent(*m_event).type() == EventTypeNames::click; |
| 253 if (isClick) { | 262 if (isClick) { |
| 254 // Fire an accessibility event indicating a node was clicked on. This is sa
fe if m_event->target()->toNode() returns null. | 263 // Fire an accessibility event indicating a node was clicked on. This is |
| 264 // safe if m_event->target()->toNode() returns null. |
| 255 if (AXObjectCache* cache = m_node->document().existingAXObjectCache()) | 265 if (AXObjectCache* cache = m_node->document().existingAXObjectCache()) |
| 256 cache->handleClicked(m_event->target()->toNode()); | 266 cache->handleClicked(m_event->target()->toNode()); |
| 257 } | 267 } |
| 258 | 268 |
| 259 // The DOM Events spec says that events dispatched by JS (other than "click") | 269 // The DOM Events spec says that events dispatched by JS (other than "click") |
| 260 // should not have their default handlers invoked. | 270 // should not have their default handlers invoked. |
| 261 bool isTrustedOrClick = | 271 bool isTrustedOrClick = |
| 262 !RuntimeEnabledFeatures::trustedEventsDefaultActionEnabled() || | 272 !RuntimeEnabledFeatures::trustedEventsDefaultActionEnabled() || |
| 263 m_event->isTrusted() || isClick; | 273 m_event->isTrusted() || isClick; |
| 264 | 274 |
| 265 // For Android WebView (distinguished by wideViewportQuirkEnabled) | 275 // For Android WebView (distinguished by wideViewportQuirkEnabled) |
| 266 // enable untrusted events for mouse down on select elements because | 276 // enable untrusted events for mouse down on select elements because |
| 267 // fastclick.js seems to generate these. crbug.com/642698 | 277 // fastclick.js seems to generate these. crbug.com/642698 |
| 268 // TODO(dtapuska): Change this to a target SDK quirk crbug.com/643705 | 278 // TODO(dtapuska): Change this to a target SDK quirk crbug.com/643705 |
| 269 if (!isTrustedOrClick && m_event->isMouseEvent() && | 279 if (!isTrustedOrClick && m_event->isMouseEvent() && |
| 270 m_event->type() == EventTypeNames::mousedown && | 280 m_event->type() == EventTypeNames::mousedown && |
| 271 isHTMLSelectElement(*m_node)) { | 281 isHTMLSelectElement(*m_node)) { |
| 272 if (Settings* settings = m_node->document().settings()) { | 282 if (Settings* settings = m_node->document().settings()) { |
| 273 isTrustedOrClick = settings->wideViewportQuirkEnabled(); | 283 isTrustedOrClick = settings->wideViewportQuirkEnabled(); |
| 274 } | 284 } |
| 275 } | 285 } |
| 276 | 286 |
| 277 // Call default event handlers. While the DOM does have a concept of preventin
g | 287 // Call default event handlers. While the DOM does have a concept of |
| 278 // default handling, the detail of which handlers are called is an internal | 288 // preventing default handling, the detail of which handlers are called is an |
| 279 // implementation detail and not part of the DOM. | 289 // internal implementation detail and not part of the DOM. |
| 280 if (!m_event->defaultPrevented() && !m_event->defaultHandled() && | 290 if (!m_event->defaultPrevented() && !m_event->defaultHandled() && |
| 281 isTrustedOrClick) { | 291 isTrustedOrClick) { |
| 282 // Non-bubbling events call only one default event handler, the one for the
target. | 292 // Non-bubbling events call only one default event handler, the one for the |
| 293 // target. |
| 283 m_node->willCallDefaultEventHandler(*m_event); | 294 m_node->willCallDefaultEventHandler(*m_event); |
| 284 m_node->defaultEventHandler(m_event.get()); | 295 m_node->defaultEventHandler(m_event.get()); |
| 285 DCHECK(!m_event->defaultPrevented()); | 296 DCHECK(!m_event->defaultPrevented()); |
| 286 // For bubbling events, call default event handlers on the same targets in t
he | 297 // For bubbling events, call default event handlers on the same targets in |
| 287 // same order as the bubbling phase. | 298 // the same order as the bubbling phase. |
| 288 if (!m_event->defaultHandled() && m_event->bubbles()) { | 299 if (!m_event->defaultHandled() && m_event->bubbles()) { |
| 289 size_t size = m_event->eventPath().size(); | 300 size_t size = m_event->eventPath().size(); |
| 290 for (size_t i = 1; i < size; ++i) { | 301 for (size_t i = 1; i < size; ++i) { |
| 291 m_event->eventPath()[i].node()->willCallDefaultEventHandler(*m_event); | 302 m_event->eventPath()[i].node()->willCallDefaultEventHandler(*m_event); |
| 292 m_event->eventPath()[i].node()->defaultEventHandler(m_event.get()); | 303 m_event->eventPath()[i].node()->defaultEventHandler(m_event.get()); |
| 293 DCHECK(!m_event->defaultPrevented()); | 304 DCHECK(!m_event->defaultPrevented()); |
| 294 if (m_event->defaultHandled()) | 305 if (m_event->defaultHandled()) |
| 295 break; | 306 break; |
| 296 } | 307 } |
| 297 } | 308 } |
| 298 } | 309 } |
| 299 | 310 |
| 300 // Track the usage of sending a mousedown event to a select element to force | 311 // Track the usage of sending a mousedown event to a select element to force |
| 301 // it to open. This measures a possible breakage of not allowing untrusted | 312 // it to open. This measures a possible breakage of not allowing untrusted |
| 302 // events to open select boxes. | 313 // events to open select boxes. |
| 303 if (!m_event->isTrusted() && m_event->isMouseEvent() && | 314 if (!m_event->isTrusted() && m_event->isMouseEvent() && |
| 304 m_event->type() == EventTypeNames::mousedown && | 315 m_event->type() == EventTypeNames::mousedown && |
| 305 isHTMLSelectElement(*m_node)) { | 316 isHTMLSelectElement(*m_node)) { |
| 306 UseCounter::count(m_node->document(), | 317 UseCounter::count(m_node->document(), |
| 307 UseCounter::UntrustedMouseDownEventDispatchedToSelect); | 318 UseCounter::UntrustedMouseDownEventDispatchedToSelect); |
| 308 } | 319 } |
| 309 } | 320 } |
| 310 | 321 |
| 311 } // namespace blink | 322 } // namespace blink |
| OLD | NEW |