Bug 1698786: part 2) Change some compile-time dependent `printf`s to `MOZ_LOG` in...
[gecko.git] / layout / style / ServoElementSnapshot.h
blob5f422f04a59f15c8c43d960bf787e8166b7c834c
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/EventStates.h"
12 #include "mozilla/TypedEnumBits.h"
13 #include "mozilla/dom/BorrowedAttrInfo.h"
14 #include "nsAttrName.h"
15 #include "nsAttrValue.h"
16 #include "nsChangeHint.h"
17 #include "nsGkAtoms.h"
18 #include "nsAtom.h"
20 namespace mozilla {
21 namespace dom {
22 class Element;
25 /**
26 * A bitflags enum class used to determine what data does a ServoElementSnapshot
27 * contains.
29 enum class ServoElementSnapshotFlags : uint8_t {
30 State = 1 << 0,
31 Attributes = 1 << 1,
32 Id = 1 << 2,
33 MaybeClass = 1 << 3,
34 OtherPseudoClassState = 1 << 4,
37 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoElementSnapshotFlags)
39 /**
40 * This class holds all non-tree-structural state of an element that might be
41 * used for selector matching eventually.
43 * This means the attributes, and the element state, such as :hover, :active,
44 * etc...
46 class ServoElementSnapshot {
47 typedef dom::BorrowedAttrInfo BorrowedAttrInfo;
48 typedef dom::Element Element;
49 typedef EventStates::ServoType ServoStateType;
51 public:
52 typedef ServoElementSnapshotFlags Flags;
54 explicit ServoElementSnapshot(const Element&);
56 ~ServoElementSnapshot() {
57 MOZ_ASSERT(NS_IsMainThread());
58 MOZ_COUNT_DTOR(ServoElementSnapshot);
61 bool HasAttrs() const { return HasAny(Flags::Attributes); }
63 bool HasState() const { return HasAny(Flags::State); }
65 bool HasOtherPseudoClassState() const {
66 return HasAny(Flags::OtherPseudoClassState);
69 /**
70 * Captures the given state (if not previously captured).
72 void AddState(EventStates aState) {
73 if (!HasAny(Flags::State)) {
74 mState = aState.ServoValue();
75 mContains |= Flags::State;
79 /**
80 * Captures the given element attributes (if not previously captured).
82 * The attribute name and namespace are used to note which kind of attribute
83 * has changed.
85 void AddAttrs(const Element&, int32_t aNameSpaceID, nsAtom* aAttribute);
87 /**
88 * Captures some other pseudo-class matching state not included in
89 * EventStates.
91 void AddOtherPseudoClassState(const Element&);
93 /**
94 * Needed methods for attribute matching.
96 BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const {
97 MOZ_ASSERT(HasAttrs());
98 if (aIndex >= mAttrs.Length()) {
99 return BorrowedAttrInfo(nullptr, nullptr);
101 return BorrowedAttrInfo(&mAttrs[aIndex].mName, &mAttrs[aIndex].mValue);
104 const nsAttrValue* GetParsedAttr(nsAtom* aLocalName) const {
105 return GetParsedAttr(aLocalName, kNameSpaceID_None);
108 const nsAttrValue* GetParsedAttr(nsAtom* aLocalName,
109 int32_t aNamespaceID) const {
110 MOZ_ASSERT(HasAttrs());
111 uint32_t i, len = mAttrs.Length();
112 if (aNamespaceID == kNameSpaceID_None) {
113 // This should be the common case so lets make an optimized loop
114 for (i = 0; i < len; ++i) {
115 if (mAttrs[i].mName.Equals(aLocalName)) {
116 return &mAttrs[i].mValue;
120 return nullptr;
123 for (i = 0; i < len; ++i) {
124 if (mAttrs[i].mName.Equals(aLocalName, aNamespaceID)) {
125 return &mAttrs[i].mValue;
129 return nullptr;
132 bool IsInChromeDocument() const { return mIsInChromeDocument; }
133 bool SupportsLangAttr() const { return mSupportsLangAttr; }
135 bool HasAny(Flags aFlags) const { return bool(mContains & aFlags); }
137 bool IsTableBorderNonzero() const {
138 MOZ_ASSERT(HasOtherPseudoClassState());
139 return mIsTableBorderNonzero;
142 bool IsMozBrowserFrame() const {
143 MOZ_ASSERT(HasOtherPseudoClassState());
144 return mIsMozBrowserFrame;
147 bool IsSelectListBox() const {
148 MOZ_ASSERT(HasOtherPseudoClassState());
149 return mIsSelectListBox;
152 private:
153 // TODO: Profile, a 1 or 2 element AutoTArray could be worth it, given we know
154 // we're dealing with attribute changes when we take snapshots of attributes,
155 // though it can be wasted space if we deal with a lot of state-only
156 // snapshots.
157 nsTArray<AttrArray::InternalAttr> mAttrs;
158 nsTArray<RefPtr<nsAtom>> mChangedAttrNames;
159 nsAttrValue mClass;
160 ServoStateType mState;
161 Flags mContains;
162 bool mIsInChromeDocument : 1;
163 bool mSupportsLangAttr : 1;
164 bool mIsTableBorderNonzero : 1;
165 bool mIsMozBrowserFrame : 1;
166 bool mIsSelectListBox : 1;
167 bool mClassAttributeChanged : 1;
168 bool mIdAttributeChanged : 1;
171 } // namespace mozilla
173 #endif