ServoElementSnapshot.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_ServoElementSnapshot_h
  6. #define mozilla_ServoElementSnapshot_h
  7. #include "mozilla/EventStates.h"
  8. #include "mozilla/TypedEnumBits.h"
  9. #include "mozilla/dom/BorrowedAttrInfo.h"
  10. #include "nsAttrName.h"
  11. #include "nsAttrValue.h"
  12. #include "nsChangeHint.h"
  13. #include "nsIAtom.h"
  14. namespace mozilla {
  15. namespace dom {
  16. class Element;
  17. } // namespace dom
  18. /**
  19. * A structure representing a single attribute name and value.
  20. *
  21. * This is pretty similar to the private nsAttrAndChildArray::InternalAttr.
  22. */
  23. struct ServoAttrSnapshot
  24. {
  25. nsAttrName mName;
  26. nsAttrValue mValue;
  27. ServoAttrSnapshot(const nsAttrName& aName, const nsAttrValue& aValue)
  28. : mName(aName)
  29. , mValue(aValue)
  30. {
  31. }
  32. };
  33. /**
  34. * A bitflags enum class used to determine what data does a ServoElementSnapshot
  35. * contains.
  36. */
  37. enum class ServoElementSnapshotFlags : uint8_t
  38. {
  39. State = 1 << 0,
  40. Attributes = 1 << 1,
  41. All = State | Attributes
  42. };
  43. MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoElementSnapshotFlags)
  44. /**
  45. * This class holds all non-tree-structural state of an element that might be
  46. * used for selector matching eventually.
  47. *
  48. * This means the attributes, and the element state, such as :hover, :active,
  49. * etc...
  50. */
  51. class ServoElementSnapshot
  52. {
  53. typedef dom::BorrowedAttrInfo BorrowedAttrInfo;
  54. typedef dom::Element Element;
  55. typedef EventStates::ServoType ServoStateType;
  56. public:
  57. typedef ServoElementSnapshotFlags Flags;
  58. explicit ServoElementSnapshot(Element* aElement);
  59. bool HasAttrs() { return HasAny(Flags::Attributes); }
  60. bool HasState() { return HasAny(Flags::State); }
  61. /**
  62. * Captures the given state (if not previously captured).
  63. */
  64. void AddState(EventStates aState)
  65. {
  66. if (!HasAny(Flags::State)) {
  67. mState = aState.ServoValue();
  68. mContains |= Flags::State;
  69. }
  70. }
  71. /**
  72. * Captures the given element attributes (if not previously captured).
  73. */
  74. void AddAttrs(Element* aElement);
  75. void AddExplicitChangeHint(nsChangeHint aMinChangeHint)
  76. {
  77. mExplicitChangeHint |= aMinChangeHint;
  78. }
  79. void AddExplicitRestyleHint(nsRestyleHint aRestyleHint)
  80. {
  81. mExplicitRestyleHint |= aRestyleHint;
  82. }
  83. nsRestyleHint ExplicitRestyleHint() { return mExplicitRestyleHint; }
  84. nsChangeHint ExplicitChangeHint() { return mExplicitChangeHint; }
  85. /**
  86. * Needed methods for attribute matching.
  87. */
  88. BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const
  89. {
  90. if (aIndex >= mAttrs.Length()) {
  91. return BorrowedAttrInfo(nullptr, nullptr);
  92. }
  93. return BorrowedAttrInfo(&mAttrs[aIndex].mName, &mAttrs[aIndex].mValue);
  94. }
  95. const nsAttrValue* GetParsedAttr(nsIAtom* aLocalName) const
  96. {
  97. return GetParsedAttr(aLocalName, kNameSpaceID_None);
  98. }
  99. const nsAttrValue* GetParsedAttr(nsIAtom* aLocalName,
  100. int32_t aNamespaceID) const
  101. {
  102. uint32_t i, len = mAttrs.Length();
  103. if (aNamespaceID == kNameSpaceID_None) {
  104. // This should be the common case so lets make an optimized loop
  105. for (i = 0; i < len; ++i) {
  106. if (mAttrs[i].mName.Equals(aLocalName)) {
  107. return &mAttrs[i].mValue;
  108. }
  109. }
  110. return nullptr;
  111. }
  112. for (i = 0; i < len; ++i) {
  113. if (mAttrs[i].mName.Equals(aLocalName, aNamespaceID)) {
  114. return &mAttrs[i].mValue;
  115. }
  116. }
  117. return nullptr;
  118. }
  119. bool IsInChromeDocument() const
  120. {
  121. return mIsInChromeDocument;
  122. }
  123. bool HasAny(Flags aFlags) { return bool(mContains & aFlags); }
  124. private:
  125. // TODO: Profile, a 1 or 2 element AutoTArray could be worth it, given we know
  126. // we're dealing with attribute changes when we take snapshots of attributes,
  127. // though it can be wasted space if we deal with a lot of state-only
  128. // snapshots.
  129. Flags mContains;
  130. nsTArray<ServoAttrSnapshot> mAttrs;
  131. ServoStateType mState;
  132. nsRestyleHint mExplicitRestyleHint;
  133. nsChangeHint mExplicitChangeHint;
  134. bool mIsHTMLElementInHTMLDocument;
  135. bool mIsInChromeDocument;
  136. };
  137. } // namespace mozilla
  138. #endif