Bug 1879449 [wpt PR 44489] - [wptrunner] Add `infrastructure/expected-fail/` test...
[gecko.git] / layout / style / ServoElementSnapshot.h
blobb702975c4b426a209798b5e03ca710e74665348d
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"
18 #include "nsAtom.h"
19 #include "MainThreadUtils.h"
21 namespace mozilla {
22 namespace dom {
23 class Element;
26 /**
27 * A bitflags enum class used to determine what data does a ServoElementSnapshot
28 * contains.
30 enum class ServoElementSnapshotFlags : uint8_t {
31 State = 1 << 0,
32 Attributes = 1 << 1,
33 Id = 1 << 2,
34 MaybeClass = 1 << 3,
35 OtherPseudoClassState = 1 << 4,
38 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoElementSnapshotFlags)
40 /**
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,
45 * etc...
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;
55 public:
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);
73 /**
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;
83 /**
84 * Captures the given element attributes (if not previously captured).
86 * The attribute name and namespace are used to note which kind of attribute
87 * has changed.
89 void AddAttrs(const Element&, int32_t aNameSpaceID, nsAtom* aAttribute);
91 /**
92 * Captures some other pseudo-class matching state not included in
93 * ElementState.
95 void AddOtherPseudoClassState(const Element&);
97 /**
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;
124 return nullptr;
127 for (i = 0; i < len; ++i) {
128 if (mAttrs[i].mName.Equals(aLocalName, aNamespaceID)) {
129 return &mAttrs[i].mValue;
133 return nullptr;
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;
151 private:
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
155 // snapshots.
156 nsTArray<AttrArray::InternalAttr> mAttrs;
157 nsTArray<RefPtr<nsAtom>> mChangedAttrNames;
158 nsAttrValue mClass;
159 ServoStateType mState;
160 Flags mContains;
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
171 #endif