#include "config.h"
#include "core/events/EventPath.h"
-#include "EventNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
-#include "core/dom/FullscreenElementStack.h"
+#include "core/EventNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Touch.h"
#include "core/dom/TouchList.h"
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/ShadowRoot.h"
-#include "core/events/FocusEvent.h"
-#include "core/events/MouseEvent.h"
#include "core/events/TouchEvent.h"
#include "core/events/TouchEventContext.h"
-#include "core/svg/SVGElementInstance.h"
-#include "core/svg/SVGUseElement.h"
-namespace WebCore {
+namespace blink {
EventTarget* EventPath::eventTargetRespectingTargetRules(Node* referenceNode)
{
if (referenceNode->isPseudoElement())
return referenceNode->parentNode();
- if (!referenceNode->isSVGElement() || !referenceNode->isInShadowTree())
- return referenceNode;
-
- // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
- // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects.
- Node& rootNode = referenceNode->treeScope().rootNode();
- Element* shadowHostElement = rootNode.isShadowRoot() ? toShadowRoot(rootNode).host() : 0;
- // At this time, SVG nodes are not supported in non-<use> shadow trees.
- if (!isSVGUseElement(shadowHostElement))
- return referenceNode;
- SVGUseElement& useElement = toSVGUseElement(*shadowHostElement);
- if (SVGElementInstance* instance = useElement.instanceForShadowTreeElement(referenceNode))
- return instance;
-
return referenceNode;
}
}
EventPath::EventPath(Event* event)
- : m_node(0)
+ : m_node(nullptr)
, m_event(event)
{
}
EventPath::EventPath(Node* node)
: m_node(node)
- , m_event(0)
+ , m_event(nullptr)
{
resetWith(node);
}
m_treeScopeEventContexts.clear();
calculatePath();
calculateAdjustedTargets();
- if (!node->isSVGElement())
- calculateTreeScopePrePostOrderNumbers();
+ calculateTreeScopePrePostOrderNumbers();
}
void EventPath::addNodeEventContext(Node* node)
{
ASSERT(m_node);
ASSERT(m_nodeEventContexts.isEmpty());
- m_node->document().updateDistributionForNodeIfNeeded(const_cast<Node*>(m_node));
+ m_node->document().updateDistributionForNodeIfNeeded(const_cast<Node*>(m_node.get()));
Node* current = m_node;
addNodeEventContext(current);
if (!m_node->inDocument())
return;
while (current) {
+ if (m_event && current->keepEventInNode(m_event))
+ break;
if (current->isShadowRoot() && m_event && determineDispatchBehavior(m_event, toShadowRoot(current), m_node) == StayInsideShadowDOM)
break;
- Vector<InsertionPoint*, 8> insertionPoints;
+ WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints;
collectDestinationInsertionPoints(*current, insertionPoints);
if (!insertionPoints.isEmpty()) {
for (size_t i = 0; i < insertionPoints.size(); ++i) {
// Precondition:
// - TreeScopes in m_treeScopeEventContexts must be *connected* in the same tree of trees.
// - The root tree must be included.
- HashMap<const TreeScope*, TreeScopeEventContext*> treeScopeEventContextMap;
+ WillBeHeapHashMap<RawPtrWillBeMember<const TreeScope>, RawPtrWillBeMember<TreeScopeEventContext> > treeScopeEventContextMap;
for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i)
treeScopeEventContextMap.add(&m_treeScopeEventContexts[i]->treeScope(), m_treeScopeEventContexts[i].get());
TreeScopeEventContext* rootTree = 0;
{
if (!treeScope)
return 0;
- TreeScopeEventContextMap::AddResult addResult = treeScopeEventContextMap.add(treeScope, TreeScopeEventContext::create(*treeScope));
- TreeScopeEventContext* treeScopeEventContext = addResult.storedValue->value.get();
- if (addResult.isNewEntry) {
+ TreeScopeEventContext* treeScopeEventContext;
+ bool isNewEntry;
+ {
+ TreeScopeEventContextMap::AddResult addResult = treeScopeEventContextMap.add(treeScope, nullptr);
+ isNewEntry = addResult.isNewEntry;
+ if (isNewEntry)
+ addResult.storedValue->value = TreeScopeEventContext::create(*treeScope);
+ treeScopeEventContext = addResult.storedValue->value.get();
+ }
+ if (isNewEntry) {
TreeScopeEventContext* parentTreeScopeEventContext = ensureTreeScopeEventContext(0, treeScope->olderShadowRootOrParentTreeScope(), treeScopeEventContextMap);
if (parentTreeScopeEventContext && parentTreeScopeEventContext->target()) {
treeScopeEventContext->setTarget(parentTreeScopeEventContext->target());
void EventPath::calculateAdjustedTargets()
{
const TreeScope* lastTreeScope = 0;
- bool isSVGElement = at(0).node()->isSVGElement();
TreeScopeEventContextMap treeScopeEventContextMap;
TreeScopeEventContext* lastTreeScopeEventContext = 0;
Node* currentNode = at(i).node();
TreeScope& currentTreeScope = currentNode->treeScope();
if (lastTreeScope != ¤tTreeScope) {
- if (!isSVGElement) {
- lastTreeScopeEventContext = ensureTreeScopeEventContext(currentNode, ¤tTreeScope, treeScopeEventContextMap);
- } else {
- TreeScopeEventContextMap::AddResult addResult = treeScopeEventContextMap.add(¤tTreeScope, TreeScopeEventContext::create(currentTreeScope));
- lastTreeScopeEventContext = addResult.storedValue->value.get();
- if (addResult.isNewEntry) {
- // Don't adjust an event target for SVG.
- lastTreeScopeEventContext->setTarget(eventTargetRespectingTargetRules(at(0).node()));
- }
- }
+ lastTreeScopeEventContext = ensureTreeScopeEventContext(currentNode, ¤tTreeScope, treeScopeEventContextMap);
}
ASSERT(lastTreeScopeEventContext);
at(i).setTreeScopeEventContext(lastTreeScopeEventContext);
EventTarget* EventPath::findRelatedNode(TreeScope* scope, RelatedTargetMap& relatedTargetMap)
{
- Vector<TreeScope*, 32> parentTreeScopes;
+ WillBeHeapVector<RawPtrWillBeMember<TreeScope>, 32> parentTreeScopes;
EventTarget* relatedNode = 0;
while (scope) {
parentTreeScopes.append(scope);
scope = scope->olderShadowRootOrParentTreeScope();
}
ASSERT(relatedNode);
- for (Vector<TreeScope*, 32>::iterator iter = parentTreeScopes.begin(); iter < parentTreeScopes.end(); ++iter)
+ for (WillBeHeapVector<RawPtrWillBeMember<TreeScope>, 32>::iterator iter = parentTreeScopes.begin(); iter < parentTreeScopes.end(); ++iter)
relatedTargetMap.add(*iter, relatedNode);
return relatedNode;
}
WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTouches;
WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTargetTouches;
WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedChangedTouches;
- Vector<TreeScope*> treeScopes;
+ WillBeHeapVector<RawPtrWillBeMember<TreeScope> > treeScopes;
for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) {
TouchEventContext* touchEventContext = m_treeScopeEventContexts[i]->ensureTouchEventContext();
adjustTouchList(node, touchEvent.targetTouches(), adjustedTargetTouches, treeScopes);
adjustTouchList(node, touchEvent.changedTouches(), adjustedChangedTouches, treeScopes);
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) {
TreeScope& treeScope = m_treeScopeEventContexts[i]->treeScope();
TouchEventContext* touchEventContext = m_treeScopeEventContexts[i]->touchEventContext();
#endif
}
-void EventPath::adjustTouchList(const Node* node, const TouchList* touchList, WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTouchList, const Vector<TreeScope*>& treeScopes)
+void EventPath::adjustTouchList(const Node* node, const TouchList* touchList, WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTouchList, const WillBeHeapVector<RawPtrWillBeMember<TreeScope> >& treeScopes)
{
if (!touchList)
return;
}
}
-#ifndef NDEBUG
+#if ENABLE(ASSERT)
void EventPath::checkReachability(TreeScope& treeScope, TouchList& touchList)
{
for (size_t i = 0; i < touchList.length(); ++i)
}
#endif
+void EventPath::trace(Visitor* visitor)
+{
+ visitor->trace(m_nodeEventContexts);
+ visitor->trace(m_node);
+ visitor->trace(m_event);
+ visitor->trace(m_treeScopeEventContexts);
+}
+
} // namespace