123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef mozilla_ServoElementSnapshot_h
- #define mozilla_ServoElementSnapshot_h
- #include "mozilla/EventStates.h"
- #include "mozilla/TypedEnumBits.h"
- #include "mozilla/dom/BorrowedAttrInfo.h"
- #include "nsAttrName.h"
- #include "nsAttrValue.h"
- #include "nsChangeHint.h"
- #include "nsIAtom.h"
- namespace mozilla {
- namespace dom {
- class Element;
- } // namespace dom
- /**
- * A structure representing a single attribute name and value.
- *
- * This is pretty similar to the private nsAttrAndChildArray::InternalAttr.
- */
- struct ServoAttrSnapshot
- {
- nsAttrName mName;
- nsAttrValue mValue;
- ServoAttrSnapshot(const nsAttrName& aName, const nsAttrValue& aValue)
- : mName(aName)
- , mValue(aValue)
- {
- }
- };
- /**
- * A bitflags enum class used to determine what data does a ServoElementSnapshot
- * contains.
- */
- enum class ServoElementSnapshotFlags : uint8_t
- {
- State = 1 << 0,
- Attributes = 1 << 1,
- All = State | Attributes
- };
- MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoElementSnapshotFlags)
- /**
- * This class holds all non-tree-structural state of an element that might be
- * used for selector matching eventually.
- *
- * This means the attributes, and the element state, such as :hover, :active,
- * etc...
- */
- class ServoElementSnapshot
- {
- typedef dom::BorrowedAttrInfo BorrowedAttrInfo;
- typedef dom::Element Element;
- typedef EventStates::ServoType ServoStateType;
- public:
- typedef ServoElementSnapshotFlags Flags;
- explicit ServoElementSnapshot(Element* aElement);
- bool HasAttrs() { return HasAny(Flags::Attributes); }
- bool HasState() { return HasAny(Flags::State); }
- /**
- * Captures the given state (if not previously captured).
- */
- void AddState(EventStates aState)
- {
- if (!HasAny(Flags::State)) {
- mState = aState.ServoValue();
- mContains |= Flags::State;
- }
- }
- /**
- * Captures the given element attributes (if not previously captured).
- */
- void AddAttrs(Element* aElement);
- void AddExplicitChangeHint(nsChangeHint aMinChangeHint)
- {
- mExplicitChangeHint |= aMinChangeHint;
- }
- void AddExplicitRestyleHint(nsRestyleHint aRestyleHint)
- {
- mExplicitRestyleHint |= aRestyleHint;
- }
- nsRestyleHint ExplicitRestyleHint() { return mExplicitRestyleHint; }
- nsChangeHint ExplicitChangeHint() { return mExplicitChangeHint; }
- /**
- * Needed methods for attribute matching.
- */
- BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const
- {
- if (aIndex >= mAttrs.Length()) {
- return BorrowedAttrInfo(nullptr, nullptr);
- }
- return BorrowedAttrInfo(&mAttrs[aIndex].mName, &mAttrs[aIndex].mValue);
- }
- const nsAttrValue* GetParsedAttr(nsIAtom* aLocalName) const
- {
- return GetParsedAttr(aLocalName, kNameSpaceID_None);
- }
- const nsAttrValue* GetParsedAttr(nsIAtom* aLocalName,
- int32_t aNamespaceID) const
- {
- uint32_t i, len = mAttrs.Length();
- if (aNamespaceID == kNameSpaceID_None) {
- // This should be the common case so lets make an optimized loop
- for (i = 0; i < len; ++i) {
- if (mAttrs[i].mName.Equals(aLocalName)) {
- return &mAttrs[i].mValue;
- }
- }
- return nullptr;
- }
- for (i = 0; i < len; ++i) {
- if (mAttrs[i].mName.Equals(aLocalName, aNamespaceID)) {
- return &mAttrs[i].mValue;
- }
- }
- return nullptr;
- }
- bool IsInChromeDocument() const
- {
- return mIsInChromeDocument;
- }
- bool HasAny(Flags aFlags) { return bool(mContains & aFlags); }
- private:
- // TODO: Profile, a 1 or 2 element AutoTArray could be worth it, given we know
- // we're dealing with attribute changes when we take snapshots of attributes,
- // though it can be wasted space if we deal with a lot of state-only
- // snapshots.
- Flags mContains;
- nsTArray<ServoAttrSnapshot> mAttrs;
- ServoStateType mState;
- nsRestyleHint mExplicitRestyleHint;
- nsChangeHint mExplicitChangeHint;
- bool mIsHTMLElementInHTMLDocument;
- bool mIsInChromeDocument;
- };
- } // namespace mozilla
- #endif
|