1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_ServoElementSnapshot_h
8 #define mozilla_ServoElementSnapshot_h
10 #include "AttrArray.h"
11 #include "mozilla/TypedEnumBits.h"
12 #include "mozilla/dom/BorrowedAttrInfo.h"
13 #include "mozilla/dom/RustTypes.h"
14 #include "nsAttrName.h"
15 #include "nsAttrValue.h"
16 #include "nsChangeHint.h"
17 #include "nsGkAtoms.h"
19 #include "MainThreadUtils.h"
27 * A bitflags enum class used to determine what data does a ServoElementSnapshot
30 enum class ServoElementSnapshotFlags
: uint8_t {
35 OtherPseudoClassState
= 1 << 4,
38 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoElementSnapshotFlags
)
41 * This class holds all non-tree-structural state of an element that might be
42 * used for selector matching eventually.
44 * This means the attributes, and the element state, such as :hover, :active,
47 class ServoElementSnapshot
{
48 typedef dom::BorrowedAttrInfo BorrowedAttrInfo
;
49 typedef dom::Element Element
;
51 // TODO: Now that the element state shares a representation with rust we
52 // should be able to do better and not use the internal type.
53 typedef dom::ElementState::InternalType ServoStateType
;
56 typedef ServoElementSnapshotFlags Flags
;
58 explicit ServoElementSnapshot(const Element
&);
60 ~ServoElementSnapshot() {
61 MOZ_ASSERT(NS_IsMainThread());
62 MOZ_COUNT_DTOR(ServoElementSnapshot
);
65 bool HasAttrs() const { return HasAny(Flags::Attributes
); }
67 bool HasState() const { return HasAny(Flags::State
); }
69 bool HasOtherPseudoClassState() const {
70 return HasAny(Flags::OtherPseudoClassState
);
74 * Captures the given state (if not previously captured).
76 void AddState(dom::ElementState aState
) {
77 if (!HasAny(Flags::State
)) {
78 mState
= aState
.GetInternalValue();
79 mContains
|= Flags::State
;
84 * Captures the given element attributes (if not previously captured).
86 * The attribute name and namespace are used to note which kind of attribute
89 void AddAttrs(const Element
&, int32_t aNameSpaceID
, nsAtom
* aAttribute
);
92 * Captures some other pseudo-class matching state not included in
95 void AddOtherPseudoClassState(const Element
&);
98 * Needed methods for attribute matching.
100 BorrowedAttrInfo
GetAttrInfoAt(uint32_t aIndex
) const {
101 MOZ_ASSERT(HasAttrs());
102 if (aIndex
>= mAttrs
.Length()) {
103 return BorrowedAttrInfo(nullptr, nullptr);
105 return BorrowedAttrInfo(&mAttrs
[aIndex
].mName
, &mAttrs
[aIndex
].mValue
);
108 const nsAttrValue
* GetParsedAttr(nsAtom
* aLocalName
) const {
109 return GetParsedAttr(aLocalName
, kNameSpaceID_None
);
112 const nsAttrValue
* GetParsedAttr(nsAtom
* aLocalName
,
113 int32_t aNamespaceID
) const {
114 MOZ_ASSERT(HasAttrs());
115 uint32_t i
, len
= mAttrs
.Length();
116 if (aNamespaceID
== kNameSpaceID_None
) {
117 // This should be the common case so lets make an optimized loop
118 for (i
= 0; i
< len
; ++i
) {
119 if (mAttrs
[i
].mName
.Equals(aLocalName
)) {
120 return &mAttrs
[i
].mValue
;
127 for (i
= 0; i
< len
; ++i
) {
128 if (mAttrs
[i
].mName
.Equals(aLocalName
, aNamespaceID
)) {
129 return &mAttrs
[i
].mValue
;
136 bool IsInChromeDocument() const { return mIsInChromeDocument
; }
137 bool SupportsLangAttr() const { return mSupportsLangAttr
; }
139 bool HasAny(Flags aFlags
) const { return bool(mContains
& aFlags
); }
141 bool IsTableBorderNonzero() const {
142 MOZ_ASSERT(HasOtherPseudoClassState());
143 return mIsTableBorderNonzero
;
146 bool IsSelectListBox() const {
147 MOZ_ASSERT(HasOtherPseudoClassState());
148 return mIsSelectListBox
;
152 // TODO: Profile, a 1 or 2 element AutoTArray could be worth it, given we know
153 // we're dealing with attribute changes when we take snapshots of attributes,
154 // though it can be wasted space if we deal with a lot of state-only
156 nsTArray
<AttrArray::InternalAttr
> mAttrs
;
157 nsTArray
<RefPtr
<nsAtom
>> mChangedAttrNames
;
159 ServoStateType mState
;
161 bool mIsInChromeDocument
: 1;
162 bool mSupportsLangAttr
: 1;
163 bool mIsTableBorderNonzero
: 1;
164 bool mIsSelectListBox
: 1;
165 bool mClassAttributeChanged
: 1;
166 bool mIdAttributeChanged
: 1;
169 } // namespace mozilla