blob: c76c0be7e310fd5775f0e31f62ebcf16aa1e2341 [file] [log] [blame]
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001/*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#ifndef EventRetargeter_h
21#define EventRetargeter_h
22
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010023#include "SVGNames.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010024#include "core/dom/ContainerNode.h"
25#include "core/dom/EventContext.h"
Torne (Richard Coles)e5249552013-05-15 11:35:13 +010026#include "core/dom/shadow/ShadowRoot.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010027#include "core/svg/SVGElementInstance.h"
28#include "core/svg/SVGUseElement.h"
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010029#include "wtf/HashMap.h"
Torne (Richard Coles)93ac45c2013-05-29 14:40:20 +010030#include "wtf/RefPtr.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010031
32namespace WebCore {
33
34class EventTarget;
35class FocusEvent;
36class MouseEvent;
37class Node;
38class TouchEvent;
39class TreeScope;
40
41enum EventDispatchBehavior {
42 RetargetEvent,
43 StayInsideShadowDOM
44};
45
46class EventRetargeter {
47public:
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010048 static void ensureEventPath(Node*, Event*);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010049 static void adjustForMouseEvent(Node*, MouseEvent&);
50 static void adjustForFocusEvent(Node*, FocusEvent&);
51 typedef Vector<RefPtr<TouchList> > EventPathTouchLists;
52 static void adjustForTouchEvent(Node*, TouchEvent&);
53 static EventTarget* eventTargetRespectingTargetRules(Node* referenceNode);
54
55private:
56 typedef Vector<RefPtr<Node> > AdjustedNodes;
57 typedef HashMap<TreeScope*, Node*> RelatedNodeMap;
58 enum EventWithRelatedTargetDispatchBehavior {
59 StopAtBoundaryIfNeeded,
60 DoesNotStopAtBoundary
61 };
Torne (Richard Coles)521d96e2013-06-19 11:58:24 +010062 static void calculateEventPath(Node*, Event*);
63 static void calculateAdjustedEventPathForEachNode(EventPath&);
64
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010065 static void adjustForRelatedTarget(const Node*, EventTarget* relatedTarget, EventPath&);
66 static void calculateAdjustedNodes(const Node*, const Node* relatedNode, EventWithRelatedTargetDispatchBehavior, EventPath&, AdjustedNodes&);
67 static void buildRelatedNodeMap(const Node*, RelatedNodeMap&);
68 static Node* findRelatedNode(TreeScope*, RelatedNodeMap&);
69 static void adjustTouchList(const Node*, const TouchList*, const EventPath&, EventPathTouchLists&);
70};
71
72inline EventTarget* EventRetargeter::eventTargetRespectingTargetRules(Node* referenceNode)
73{
74 ASSERT(referenceNode);
75
76 if (referenceNode->isPseudoElement())
77 return referenceNode->parentNode();
78
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010079 if (!referenceNode->isSVGElement() || !referenceNode->isInShadowTree())
80 return referenceNode;
81
82 // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
Torne (Richard Coles)f5e4ad52013-08-05 13:57:57 +010083 // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects.
84 Node* rootNode = referenceNode->treeScope()->rootNode();
85 Element* shadowHostElement = rootNode->isShadowRoot() ? toShadowRoot(rootNode)->host() : 0;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010086 // At this time, SVG nodes are not supported in non-<use> shadow trees.
87 if (!shadowHostElement || !shadowHostElement->hasTagName(SVGNames::useTag))
88 return referenceNode;
Ben Murdoch7757ec22013-07-23 11:17:36 +010089 SVGUseElement* useElement = toSVGUseElement(shadowHostElement);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010090 if (SVGElementInstance* instance = useElement->instanceForShadowTreeElement(referenceNode))
91 return instance;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010092
93 return referenceNode;
94}
95
96}
97
98#endif // EventRetargeter_h