initial import
[vuplus_webkit] / Source / WebCore / dom / EventDispatcher.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
7  * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8  * Copyright (C) 2011 Google Inc. All rights reserved.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25
26 #include "config.h"
27 #include "EventDispatcher.h"
28
29 #include "EventContext.h"
30 #include "EventDispatchMediator.h"
31 #include "FrameView.h"
32 #include "HTMLMediaElement.h"
33 #include "InspectorInstrumentation.h"
34 #include "MouseEvent.h"
35 #include "ScopedEventQueue.h"
36 #include "WindowEventContext.h"
37 #include <wtf/RefPtr.h>
38 #include <wtf/UnusedParam.h>
39
40 #if ENABLE(SVG)
41 #include "SVGElementInstance.h"
42 #include "SVGNames.h"
43 #include "SVGUseElement.h"
44 #endif
45
46 namespace WebCore {
47
48 static HashSet<Node*>* gNodesDispatchingSimulatedClicks = 0;
49
50 bool EventDispatcher::dispatchEvent(Node* node, PassRefPtr<EventDispatchMediator> mediator)
51 {
52     ASSERT(!eventDispatchForbidden());
53
54     EventDispatcher dispatcher(node);
55     return mediator->dispatchEvent(&dispatcher);
56 }
57
58 static EventTarget* findElementInstance(Node* referenceNode)
59 {
60 #if ENABLE(SVG)
61     // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
62     // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
63     for (Node* n = referenceNode; n; n = n->parentNode()) {
64         if (!n->isSVGShadowRoot() || !n->isSVGElement())
65             continue;
66
67         Element* shadowTreeParentElement = n->svgShadowHost();
68         ASSERT(shadowTreeParentElement->hasTagName(SVGNames::useTag));
69
70         if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode))
71             return instance;
72     }
73 #else
74     // SVG elements with SVG disabled should not be possible.
75     ASSERT_NOT_REACHED();
76 #endif
77
78     return referenceNode;
79 }
80
81 inline static EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNode)
82 {
83     ASSERT(referenceNode);
84
85     return referenceNode->isSVGElement() ? findElementInstance(referenceNode) : referenceNode;
86 }
87
88 void EventDispatcher::dispatchScopedEvent(Node* node, PassRefPtr<EventDispatchMediator> mediator)
89 {
90     // We need to set the target here because it can go away by the time we actually fire the event.
91     mediator->event()->setTarget(eventTargetRespectingSVGTargetRules(node));
92     ScopedEventQueue::instance()->enqueueEventDispatchMediator(mediator);
93 }
94
95 void EventDispatcher::dispatchSimulatedClick(Node* node, PassRefPtr<Event> underlyingEvent, bool sendMouseEvents, bool showPressedLook)
96 {
97     if (node->disabled())
98         return;
99
100     EventDispatcher dispatcher(node);
101
102     if (!gNodesDispatchingSimulatedClicks)
103         gNodesDispatchingSimulatedClicks = new HashSet<Node*>;
104     else if (gNodesDispatchingSimulatedClicks->contains(node))
105         return;
106
107     gNodesDispatchingSimulatedClicks->add(node);
108
109     // send mousedown and mouseup before the click, if requested
110     if (sendMouseEvents)
111         dispatcher.dispatchEvent(SimulatedMouseEvent::create(eventNames().mousedownEvent, node->document()->defaultView(), underlyingEvent));
112     node->setActive(true, showPressedLook);
113     if (sendMouseEvents)
114         dispatcher.dispatchEvent(SimulatedMouseEvent::create(eventNames().mouseupEvent, node->document()->defaultView(), underlyingEvent));
115     node->setActive(false);
116
117     // always send click
118     dispatcher.dispatchEvent(SimulatedMouseEvent::create(eventNames().clickEvent, node->document()->defaultView(), underlyingEvent));
119
120     gNodesDispatchingSimulatedClicks->remove(node);
121 }
122
123 static inline bool isShadowRootOrSVGShadowRoot(const Node* node)
124 {
125     return node->isShadowRoot() || node->isSVGShadowRoot();
126 }
127
128 static inline bool isShadowHost(Node* node)
129 {
130     return node->isElementNode() && toElement(node)->shadowRoot();
131 }
132
133 PassRefPtr<EventTarget> EventDispatcher::adjustToShadowBoundaries(PassRefPtr<Node> relatedTarget, const Vector<Node*> relatedTargetAncestors)
134 {
135     Vector<EventContext>::const_iterator lowestCommonBoundary = m_ancestors.end();
136     // Assume divergent boundary is the relatedTarget itself (in other words, related target ancestor chain does not cross any shadow DOM boundaries).
137     Vector<Node*>::const_iterator firstDivergentBoundary = relatedTargetAncestors.begin();
138
139     Vector<EventContext>::const_iterator targetAncestor = m_ancestors.end();
140     // Walk down from the top, looking for lowest common ancestor, also monitoring shadow DOM boundaries.
141     bool diverged = false;
142     for (Vector<Node*>::const_iterator i = relatedTargetAncestors.end() - 1; i >= relatedTargetAncestors.begin(); --i) {
143         if (diverged) {
144             if (isShadowRootOrSVGShadowRoot(*i)) {
145                 firstDivergentBoundary = i + 1;
146                 break;
147             }
148             continue;
149         }
150
151         if (targetAncestor == m_ancestors.begin()) {
152             diverged = true;
153             continue;
154         }
155
156         targetAncestor--;
157
158         if (isShadowRootOrSVGShadowRoot(*i))
159             lowestCommonBoundary = targetAncestor;
160
161         if ((*i) != (*targetAncestor).node())
162             diverged = true;
163     }
164
165     if (!diverged) {
166         // The relatedTarget is an ancestor or shadowHost of the target.
167         // FIXME: Remove the first check once conversion to new shadow DOM is complete <http://webkit.org/b/48698>
168         if (m_node->shadowHost() == relatedTarget.get() || isShadowHost(relatedTarget.get())) {
169             Vector<EventContext>::const_iterator relatedTargetChild = targetAncestor - 1;
170             if (relatedTargetChild >= m_ancestors.begin() && isShadowRootOrSVGShadowRoot(relatedTargetChild->node()))
171                 lowestCommonBoundary = relatedTargetChild;
172         }
173     } else if ((*firstDivergentBoundary) == m_node.get()) {
174         // Since ancestors does not contain target itself, we must account
175         // for the possibility that target is a shadowHost of relatedTarget
176         // and thus serves as the lowestCommonBoundary.
177         // Luckily, in this case the firstDivergentBoundary is target.
178         lowestCommonBoundary = m_ancestors.begin();
179         m_shouldPreventDispatch = true;
180     }
181
182     if (lowestCommonBoundary != m_ancestors.end()) {
183         // Trim ancestors to lowestCommonBoundary to keep events inside of the common shadow DOM subtree.
184         m_ancestors.shrink(lowestCommonBoundary - m_ancestors.begin());
185     }
186     // Set event's related target to the first encountered shadow DOM boundary in the divergent subtree.
187     return firstDivergentBoundary != relatedTargetAncestors.begin() ? *firstDivergentBoundary : relatedTarget;
188 }
189
190 inline static bool ancestorsCrossShadowBoundaries(const Vector<EventContext>& ancestors)
191 {
192     return ancestors.isEmpty() || ancestors.first().node() == ancestors.last().node();
193 }
194
195 // FIXME: Once https://bugs.webkit.org/show_bug.cgi?id=52963 lands, this should
196 // be greatly improved. See https://bugs.webkit.org/show_bug.cgi?id=54025.
197 PassRefPtr<EventTarget> EventDispatcher::adjustRelatedTarget(Event* event, PassRefPtr<EventTarget> prpRelatedTarget)
198 {
199     if (!prpRelatedTarget)
200         return 0;
201
202     RefPtr<Node> relatedTarget = prpRelatedTarget->toNode();
203     if (!relatedTarget)
204         return 0;
205
206     Node* target = m_node.get();
207     if (!target)
208         return prpRelatedTarget;
209
210     ensureEventAncestors(event);
211
212     // Calculate early if the common boundary is even possible by looking at
213     // ancestors size and if the retargeting has occured (indicating the presence of shadow DOM boundaries).
214     // If there are no boundaries detected, the target and related target can't have a common boundary.
215     bool noCommonBoundary = ancestorsCrossShadowBoundaries(m_ancestors);
216
217     Vector<Node*> relatedTargetAncestors;
218     Node* outermostShadowBoundary = relatedTarget.get();
219     for (Node* n = outermostShadowBoundary; n; n = n->parentOrHostNode()) {
220         if (isShadowRootOrSVGShadowRoot(n))
221             outermostShadowBoundary = n->parentOrHostNode();
222         if (!noCommonBoundary)
223             relatedTargetAncestors.append(n);
224     }
225
226     // Short-circuit the fast case when we know there is no need to calculate a common boundary.
227     if (noCommonBoundary)
228         return outermostShadowBoundary;
229
230     return adjustToShadowBoundaries(relatedTarget.release(), relatedTargetAncestors);
231 }
232
233 EventDispatcher::EventDispatcher(Node* node)
234     : m_node(node)
235     , m_ancestorsInitialized(false)
236     , m_shouldPreventDispatch(false)
237 {
238     ASSERT(node);
239     m_view = node->document()->view();
240 }
241
242 void EventDispatcher::ensureEventAncestors(Event* event)
243 {
244     if (!m_node->inDocument())
245         return;
246
247     if (m_ancestorsInitialized)
248         return;
249
250     m_ancestorsInitialized = true;
251
252     Node* ancestor = m_node.get();
253     EventTarget* target = eventTargetRespectingSVGTargetRules(ancestor);
254     bool shouldSkipNextAncestor = false;
255     while (true) {
256         bool isSVGShadowRoot = ancestor->isSVGShadowRoot();
257         if (isSVGShadowRoot || ancestor->isShadowRoot()) {
258             if (determineDispatchBehavior(event, ancestor) == StayInsideShadowDOM)
259                 return;
260 #if ENABLE(SVG)
261             ancestor = isSVGShadowRoot ? ancestor->svgShadowHost() : ancestor->shadowHost();
262 #else
263             ancestor = ancestor->shadowHost();
264 #endif
265             if (!shouldSkipNextAncestor)
266                 target = ancestor;
267         } else
268             ancestor = ancestor->parentNodeGuaranteedHostFree();
269
270         if (!ancestor)
271             return;
272
273 #if ENABLE(SVG)
274         // Skip SVGShadowTreeRootElement.
275         shouldSkipNextAncestor = ancestor->isSVGShadowRoot();
276         if (shouldSkipNextAncestor)
277             continue;
278 #endif
279         // FIXME: Unroll the extra loop inside eventTargetRespectingSVGTargetRules into this loop.
280         m_ancestors.append(EventContext(ancestor, eventTargetRespectingSVGTargetRules(ancestor), target));
281     }
282 }
283
284 bool EventDispatcher::dispatchEvent(PassRefPtr<Event> event)
285 {
286     event->setTarget(eventTargetRespectingSVGTargetRules(m_node.get()));
287
288     ASSERT(!eventDispatchForbidden());
289     ASSERT(event->target());
290     ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
291
292     RefPtr<EventTarget> originalTarget = event->target();
293     ensureEventAncestors(event.get());
294
295     WindowEventContext windowContext(event.get(), m_node.get(), topEventContext());
296
297     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(m_node->document(), *event, windowContext.window(), m_node.get(), m_ancestors);
298
299     // Give the target node a chance to do some work before DOM event handlers get a crack.
300     void* data = m_node->preDispatchEventHandler(event.get());
301     if (m_shouldPreventDispatch || event->propagationStopped())
302         goto doneDispatching;
303
304     // Trigger capturing event handlers, starting at the top and working our way down.
305     event->setEventPhase(Event::CAPTURING_PHASE);
306
307     if (windowContext.handleLocalEvents(event.get()) && event->propagationStopped())
308         goto doneDispatching;
309
310     for (size_t i = m_ancestors.size(); i; --i) {
311         m_ancestors[i - 1].handleLocalEvents(event.get());
312         if (event->propagationStopped())
313             goto doneDispatching;
314     }
315
316     event->setEventPhase(Event::AT_TARGET);
317     event->setTarget(originalTarget.get());
318     event->setCurrentTarget(eventTargetRespectingSVGTargetRules(m_node.get()));
319     m_node->handleLocalEvents(event.get());
320     if (event->propagationStopped())
321         goto doneDispatching;
322
323     if (event->bubbles() && !event->cancelBubble()) {
324         // Trigger bubbling event handlers, starting at the bottom and working our way up.
325         event->setEventPhase(Event::BUBBLING_PHASE);
326
327         size_t size = m_ancestors.size();
328         for (size_t i = 0; i < size; ++i) {
329             m_ancestors[i].handleLocalEvents(event.get());
330             if (event->propagationStopped() || event->cancelBubble())
331                 goto doneDispatching;
332         }
333         windowContext.handleLocalEvents(event.get());
334     }
335
336 doneDispatching:
337     event->setTarget(originalTarget.get());
338     event->setCurrentTarget(0);
339     event->setEventPhase(0);
340
341     // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler.
342     m_node->postDispatchEventHandler(event.get(), data);
343
344     // Call default event handlers. While the DOM does have a concept of preventing
345     // default handling, the detail of which handlers are called is an internal
346     // implementation detail and not part of the DOM.
347     if (!event->defaultPrevented() && !event->defaultHandled()) {
348         // Non-bubbling events call only one default event handler, the one for the target.
349         m_node->defaultEventHandler(event.get());
350         ASSERT(!event->defaultPrevented());
351         if (event->defaultHandled())
352             goto doneWithDefault;
353         // For bubbling events, call default event handlers on the same targets in the
354         // same order as the bubbling phase.
355         if (event->bubbles()) {
356             size_t size = m_ancestors.size();
357             for (size_t i = 0; i < size; ++i) {
358                 m_ancestors[i].node()->defaultEventHandler(event.get());
359                 ASSERT(!event->defaultPrevented());
360                 if (event->defaultHandled())
361                     goto doneWithDefault;
362             }
363         }
364     }
365
366 doneWithDefault:
367
368     // Ensure that after event dispatch, the event's target object is the
369     // outermost shadow DOM boundary.
370     event->setTarget(windowContext.target());
371     event->setCurrentTarget(0);
372     InspectorInstrumentation::didDispatchEvent(cookie);
373
374     return !event->defaultPrevented();
375 }
376
377 const EventContext* EventDispatcher::topEventContext()
378 {
379     return m_ancestors.isEmpty() ? 0 : &m_ancestors.last();
380 }
381
382 EventDispatchBehavior EventDispatcher::determineDispatchBehavior(Event* event, Node* shadowRoot)
383 {
384 #if ENABLE(FULLSCREEN_API) && ENABLE(VIDEO)
385     // Video-only full screen is a mode where we use the shadow DOM as an implementation
386     // detail that should not be detectable by the web content.
387     if (Element* element = m_node->document()->webkitCurrentFullScreenElement()) {
388         // FIXME: We assume that if the full screen element is a media element that it's
389         // the video-only full screen. Both here and elsewhere. But that is probably wrong.
390         if (element->isMediaElement() && shadowRoot && shadowRoot->shadowHost() == element)
391             return StayInsideShadowDOM;
392     }
393 #else
394     UNUSED_PARAM(shadowRoot);
395 #endif
396
397     // Per XBL 2.0 spec, mutation events should never cross shadow DOM boundary:
398     // http://dev.w3.org/2006/xbl2/#event-flow-and-targeting-across-shadow-s
399     if (event->isMutationEvent())
400         return StayInsideShadowDOM;
401
402     // WebKit never allowed selectstart event to cross the the shadow DOM boundary.
403     // Changing this breaks existing sites.
404     // See https://bugs.webkit.org/show_bug.cgi?id=52195 for details.
405     if (event->type() == eventNames().selectstartEvent)
406         return StayInsideShadowDOM;
407
408     return RetargetEvent;
409 }
410
411 }