blob: 72e2fac9430458ee9b4e2f108cfd7a2f825abb8b [file] [log] [blame]
/*
* Copyright (C) 2014 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_TREE_SCOPE_EVENT_CONTEXT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_TREE_SCOPE_EVENT_CONTEXT_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/dom/tree_scope.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class ContainerNode;
class EventPath;
class EventTarget;
template <typename NodeType>
class StaticNodeTypeList;
using StaticNodeList = StaticNodeTypeList<Node>;
class TouchEventContext;
class TreeScope;
class CORE_EXPORT TreeScopeEventContext final
: public GarbageCollected<TreeScopeEventContext> {
public:
explicit TreeScopeEventContext(TreeScope&);
void Trace(Visitor*) const;
TreeScope& GetTreeScope() const { return *tree_scope_; }
ContainerNode& RootNode() const { return tree_scope_->RootNode(); }
EventTarget* Target() const { return target_.Get(); }
void SetTarget(EventTarget&);
EventTarget* RelatedTarget() const { return related_target_.Get(); }
void SetRelatedTarget(EventTarget&);
TouchEventContext* GetTouchEventContext() const {
return touch_event_context_.Get();
}
TouchEventContext& EnsureTouchEventContext();
HeapVector<Member<EventTarget>>& EnsureEventPath(EventPath&);
bool IsInclusiveAncestorOf(const TreeScopeEventContext&) const;
bool IsDescendantOf(const TreeScopeEventContext&) const;
#if DCHECK_IS_ON()
bool IsExclusivePartOf(const TreeScopeEventContext&) const;
#endif
void AddChild(TreeScopeEventContext& child) { children_.push_back(&child); }
// For ancestor-descendant relationship check in O(1).
// Preprocessing takes O(N).
int CalculateTreeOrderAndSetNearestAncestorClosedTree(
int order_number,
TreeScopeEventContext* nearest_ancestor_closed_tree_scope_event_context);
TreeScopeEventContext* ContainingClosedShadowTree() const {
return containing_closed_shadow_tree_.Get();
}
private:
void CheckReachableNode(EventTarget&);
bool IsUnclosedTreeOf(const TreeScopeEventContext& other);
Member<TreeScope> tree_scope_;
Member<EventTarget> target_;
Member<EventTarget> related_target_;
Member<HeapVector<Member<EventTarget>>> event_path_;
Member<TouchEventContext> touch_event_context_;
Member<TreeScopeEventContext> containing_closed_shadow_tree_;
HeapVector<Member<TreeScopeEventContext>> children_;
int pre_order_;
int post_order_;
};
#if DCHECK_IS_ON()
inline void TreeScopeEventContext::CheckReachableNode(EventTarget& target) {
if (!target.ToNode())
return;
// FIXME: Checks also for SVG elements.
if (target.ToNode()->IsSVGElement())
return;
DCHECK(target.ToNode()->GetTreeScope().IsInclusiveAncestorTreeScopeOf(
GetTreeScope()));
}
#else
inline void TreeScopeEventContext::CheckReachableNode(EventTarget&) {}
#endif
inline void TreeScopeEventContext::SetTarget(EventTarget& target) {
CheckReachableNode(target);
target_ = target;
}
inline void TreeScopeEventContext::SetRelatedTarget(
EventTarget& related_target) {
CheckReachableNode(related_target);
related_target_ = related_target;
}
inline bool TreeScopeEventContext::IsInclusiveAncestorOf(
const TreeScopeEventContext& other) const {
DCHECK_NE(pre_order_, -1);
DCHECK_NE(post_order_, -1);
DCHECK_NE(other.pre_order_, -1);
DCHECK_NE(other.post_order_, -1);
return pre_order_ <= other.pre_order_ && other.post_order_ <= post_order_;
}
inline bool TreeScopeEventContext::IsDescendantOf(
const TreeScopeEventContext& other) const {
DCHECK_NE(pre_order_, -1);
DCHECK_NE(post_order_, -1);
DCHECK_NE(other.pre_order_, -1);
DCHECK_NE(other.post_order_, -1);
return other.pre_order_ < pre_order_ && post_order_ < other.post_order_;
}
#if DCHECK_IS_ON()
inline bool TreeScopeEventContext::IsExclusivePartOf(
const TreeScopeEventContext& other) const {
DCHECK_NE(pre_order_, -1);
DCHECK_NE(post_order_, -1);
DCHECK_NE(other.pre_order_, -1);
DCHECK_NE(other.post_order_, -1);
return (pre_order_ < other.pre_order_ && post_order_ < other.pre_order_) ||
(pre_order_ > other.pre_order_ && pre_order_ > other.post_order_);
}
#endif
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_TREE_SCOPE_EVENT_CONTEXT_H_