StyleSetHandle.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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_StyleSetHandle_h
  6. #define mozilla_StyleSetHandle_h
  7. #include "mozilla/EventStates.h"
  8. #include "mozilla/RefPtr.h"
  9. #include "mozilla/SheetType.h"
  10. #include "mozilla/StyleBackendType.h"
  11. #include "mozilla/StyleSheet.h"
  12. #include "nsChangeHint.h"
  13. #include "nsCSSPseudoElements.h"
  14. #include "nsTArray.h"
  15. namespace mozilla {
  16. class CSSStyleSheet;
  17. class ServoStyleSet;
  18. namespace dom {
  19. class Element;
  20. } // namespace dom
  21. } // namespace mozilla
  22. class nsIAtom;
  23. class nsIContent;
  24. class nsIDocument;
  25. class nsStyleContext;
  26. class nsStyleSet;
  27. class nsPresContext;
  28. struct TreeMatchContext;
  29. namespace mozilla {
  30. #define SERVO_BIT 0x1
  31. /**
  32. * Smart pointer class that can hold a pointer to either an nsStyleSet
  33. * or a ServoStyleSet.
  34. */
  35. class StyleSetHandle
  36. {
  37. public:
  38. // We define this Ptr class with a StyleSet API that forwards on to the
  39. // wrapped pointer, rather than putting these methods on StyleSetHandle
  40. // itself, so that we can have StyleSetHandle behave like a smart pointer and
  41. // be dereferenced with operator->.
  42. class Ptr
  43. {
  44. public:
  45. friend class ::mozilla::StyleSetHandle;
  46. bool IsGecko() const { return !IsServo(); }
  47. bool IsServo() const
  48. {
  49. MOZ_ASSERT(mValue, "StyleSetHandle null pointer dereference");
  50. #ifdef MOZ_STYLO
  51. return mValue & SERVO_BIT;
  52. #else
  53. return false;
  54. #endif
  55. }
  56. StyleBackendType BackendType() const
  57. {
  58. return IsGecko() ? StyleBackendType::Gecko :
  59. StyleBackendType::Servo;
  60. }
  61. nsStyleSet* AsGecko()
  62. {
  63. MOZ_ASSERT(IsGecko());
  64. return reinterpret_cast<nsStyleSet*>(mValue);
  65. }
  66. ServoStyleSet* AsServo()
  67. {
  68. MOZ_ASSERT(IsServo());
  69. return reinterpret_cast<ServoStyleSet*>(mValue & ~SERVO_BIT);
  70. }
  71. nsStyleSet* GetAsGecko() { return IsGecko() ? AsGecko() : nullptr; }
  72. ServoStyleSet* GetAsServo() { return IsServo() ? AsServo() : nullptr; }
  73. const nsStyleSet* AsGecko() const
  74. {
  75. return const_cast<Ptr*>(this)->AsGecko();
  76. }
  77. const ServoStyleSet* AsServo() const
  78. {
  79. MOZ_ASSERT(IsServo());
  80. return const_cast<Ptr*>(this)->AsServo();
  81. }
  82. const nsStyleSet* GetAsGecko() const { return IsGecko() ? AsGecko() : nullptr; }
  83. const ServoStyleSet* GetAsServo() const { return IsServo() ? AsServo() : nullptr; }
  84. // These inline methods are defined in StyleSetHandleInlines.h.
  85. inline void Delete();
  86. // Style set interface. These inline methods are defined in
  87. // StyleSetHandleInlines.h and just forward to the underlying
  88. // nsStyleSet or ServoStyleSet. See corresponding comments in
  89. // nsStyleSet.h for descriptions of these methods.
  90. inline void Init(nsPresContext* aPresContext);
  91. inline void BeginShutdown();
  92. inline void Shutdown();
  93. inline bool GetAuthorStyleDisabled() const;
  94. inline nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
  95. inline void BeginUpdate();
  96. inline nsresult EndUpdate();
  97. inline already_AddRefed<nsStyleContext>
  98. ResolveStyleFor(dom::Element* aElement,
  99. nsStyleContext* aParentContext);
  100. inline already_AddRefed<nsStyleContext>
  101. ResolveStyleFor(dom::Element* aElement,
  102. nsStyleContext* aParentContext,
  103. TreeMatchContext& aTreeMatchContext);
  104. inline already_AddRefed<nsStyleContext>
  105. ResolveStyleForText(nsIContent* aTextNode,
  106. nsStyleContext* aParentContext);
  107. inline already_AddRefed<nsStyleContext>
  108. ResolveStyleForOtherNonElement(nsStyleContext* aParentContext);
  109. inline already_AddRefed<nsStyleContext>
  110. ResolvePseudoElementStyle(dom::Element* aParentElement,
  111. mozilla::CSSPseudoElementType aType,
  112. nsStyleContext* aParentContext,
  113. dom::Element* aPseudoElement);
  114. inline already_AddRefed<nsStyleContext>
  115. ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext,
  116. uint32_t aFlags = 0);
  117. inline nsresult AppendStyleSheet(SheetType aType, StyleSheet* aSheet);
  118. inline nsresult PrependStyleSheet(SheetType aType, StyleSheet* aSheet);
  119. inline nsresult RemoveStyleSheet(SheetType aType, StyleSheet* aSheet);
  120. inline nsresult ReplaceSheets(SheetType aType,
  121. const nsTArray<RefPtr<StyleSheet>>& aNewSheets);
  122. inline nsresult InsertStyleSheetBefore(SheetType aType,
  123. StyleSheet* aNewSheet,
  124. StyleSheet* aReferenceSheet);
  125. inline int32_t SheetCount(SheetType aType) const;
  126. inline StyleSheet* StyleSheetAt(SheetType aType, int32_t aIndex) const;
  127. inline nsresult RemoveDocStyleSheet(StyleSheet* aSheet);
  128. inline nsresult AddDocStyleSheet(StyleSheet* aSheet, nsIDocument* aDocument);
  129. inline already_AddRefed<nsStyleContext>
  130. ProbePseudoElementStyle(dom::Element* aParentElement,
  131. mozilla::CSSPseudoElementType aType,
  132. nsStyleContext* aParentContext);
  133. inline already_AddRefed<nsStyleContext>
  134. ProbePseudoElementStyle(dom::Element* aParentElement,
  135. mozilla::CSSPseudoElementType aType,
  136. nsStyleContext* aParentContext,
  137. TreeMatchContext& aTreeMatchContext,
  138. dom::Element* aPseudoElement = nullptr);
  139. inline nsRestyleHint HasStateDependentStyle(dom::Element* aElement,
  140. EventStates aStateMask);
  141. inline nsRestyleHint HasStateDependentStyle(
  142. dom::Element* aElement,
  143. mozilla::CSSPseudoElementType aPseudoType,
  144. dom::Element* aPseudoElement,
  145. EventStates aStateMask);
  146. inline void RootStyleContextAdded();
  147. inline void RootStyleContextRemoved();
  148. private:
  149. // Stores a pointer to an nsStyleSet or a ServoStyleSet. The least
  150. // significant bit is 0 for the former, 1 for the latter. This is
  151. // valid as the least significant bit will never be used for a pointer
  152. // value on platforms we care about.
  153. uintptr_t mValue;
  154. };
  155. StyleSetHandle() { mPtr.mValue = 0; }
  156. StyleSetHandle(const StyleSetHandle& aOth) { mPtr.mValue = aOth.mPtr.mValue; }
  157. MOZ_IMPLICIT StyleSetHandle(nsStyleSet* aSet) { *this = aSet; }
  158. MOZ_IMPLICIT StyleSetHandle(ServoStyleSet* aSet) { *this = aSet; }
  159. StyleSetHandle& operator=(nsStyleSet* aStyleSet)
  160. {
  161. MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aStyleSet) & SERVO_BIT),
  162. "least significant bit shouldn't be set; we use it for state");
  163. mPtr.mValue = reinterpret_cast<uintptr_t>(aStyleSet);
  164. return *this;
  165. }
  166. StyleSetHandle& operator=(ServoStyleSet* aStyleSet)
  167. {
  168. #ifdef MOZ_STYLO
  169. MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aStyleSet) & SERVO_BIT),
  170. "least significant bit shouldn't be set; we use it for state");
  171. mPtr.mValue =
  172. aStyleSet ? (reinterpret_cast<uintptr_t>(aStyleSet) | SERVO_BIT) : 0;
  173. return *this;
  174. #else
  175. MOZ_CRASH("should not have a ServoStyleSet object when MOZ_STYLO is "
  176. "disabled");
  177. #endif
  178. }
  179. // Make StyleSetHandle usable in boolean contexts.
  180. explicit operator bool() const { return !!mPtr.mValue; }
  181. bool operator!() const { return !mPtr.mValue; }
  182. // Make StyleSetHandle behave like a smart pointer.
  183. Ptr* operator->() { return &mPtr; }
  184. const Ptr* operator->() const { return &mPtr; }
  185. private:
  186. Ptr mPtr;
  187. };
  188. #undef SERVO_BIT
  189. } // namespace mozilla
  190. #endif // mozilla_StyleSetHandle_h