123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- /* -*- 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_StyleSetHandle_h
- #define mozilla_StyleSetHandle_h
- #include "mozilla/EventStates.h"
- #include "mozilla/RefPtr.h"
- #include "mozilla/SheetType.h"
- #include "mozilla/StyleBackendType.h"
- #include "mozilla/StyleSheet.h"
- #include "nsChangeHint.h"
- #include "nsCSSPseudoElements.h"
- #include "nsTArray.h"
- namespace mozilla {
- class CSSStyleSheet;
- class ServoStyleSet;
- namespace dom {
- class Element;
- } // namespace dom
- } // namespace mozilla
- class nsIAtom;
- class nsIContent;
- class nsIDocument;
- class nsStyleContext;
- class nsStyleSet;
- class nsPresContext;
- struct TreeMatchContext;
- namespace mozilla {
- #define SERVO_BIT 0x1
- /**
- * Smart pointer class that can hold a pointer to either an nsStyleSet
- * or a ServoStyleSet.
- */
- class StyleSetHandle
- {
- public:
- // We define this Ptr class with a StyleSet API that forwards on to the
- // wrapped pointer, rather than putting these methods on StyleSetHandle
- // itself, so that we can have StyleSetHandle behave like a smart pointer and
- // be dereferenced with operator->.
- class Ptr
- {
- public:
- friend class ::mozilla::StyleSetHandle;
- bool IsGecko() const { return !IsServo(); }
- bool IsServo() const
- {
- MOZ_ASSERT(mValue, "StyleSetHandle null pointer dereference");
- #ifdef MOZ_STYLO
- return mValue & SERVO_BIT;
- #else
- return false;
- #endif
- }
- StyleBackendType BackendType() const
- {
- return IsGecko() ? StyleBackendType::Gecko :
- StyleBackendType::Servo;
- }
- nsStyleSet* AsGecko()
- {
- MOZ_ASSERT(IsGecko());
- return reinterpret_cast<nsStyleSet*>(mValue);
- }
- ServoStyleSet* AsServo()
- {
- MOZ_ASSERT(IsServo());
- return reinterpret_cast<ServoStyleSet*>(mValue & ~SERVO_BIT);
- }
- nsStyleSet* GetAsGecko() { return IsGecko() ? AsGecko() : nullptr; }
- ServoStyleSet* GetAsServo() { return IsServo() ? AsServo() : nullptr; }
- const nsStyleSet* AsGecko() const
- {
- return const_cast<Ptr*>(this)->AsGecko();
- }
- const ServoStyleSet* AsServo() const
- {
- MOZ_ASSERT(IsServo());
- return const_cast<Ptr*>(this)->AsServo();
- }
- const nsStyleSet* GetAsGecko() const { return IsGecko() ? AsGecko() : nullptr; }
- const ServoStyleSet* GetAsServo() const { return IsServo() ? AsServo() : nullptr; }
- // These inline methods are defined in StyleSetHandleInlines.h.
- inline void Delete();
- // Style set interface. These inline methods are defined in
- // StyleSetHandleInlines.h and just forward to the underlying
- // nsStyleSet or ServoStyleSet. See corresponding comments in
- // nsStyleSet.h for descriptions of these methods.
- inline void Init(nsPresContext* aPresContext);
- inline void BeginShutdown();
- inline void Shutdown();
- inline bool GetAuthorStyleDisabled() const;
- inline nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
- inline void BeginUpdate();
- inline nsresult EndUpdate();
- inline already_AddRefed<nsStyleContext>
- ResolveStyleFor(dom::Element* aElement,
- nsStyleContext* aParentContext);
- inline already_AddRefed<nsStyleContext>
- ResolveStyleFor(dom::Element* aElement,
- nsStyleContext* aParentContext,
- TreeMatchContext& aTreeMatchContext);
- inline already_AddRefed<nsStyleContext>
- ResolveStyleForText(nsIContent* aTextNode,
- nsStyleContext* aParentContext);
- inline already_AddRefed<nsStyleContext>
- ResolveStyleForOtherNonElement(nsStyleContext* aParentContext);
- inline already_AddRefed<nsStyleContext>
- ResolvePseudoElementStyle(dom::Element* aParentElement,
- mozilla::CSSPseudoElementType aType,
- nsStyleContext* aParentContext,
- dom::Element* aPseudoElement);
- inline already_AddRefed<nsStyleContext>
- ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, nsStyleContext* aParentContext,
- uint32_t aFlags = 0);
- inline nsresult AppendStyleSheet(SheetType aType, StyleSheet* aSheet);
- inline nsresult PrependStyleSheet(SheetType aType, StyleSheet* aSheet);
- inline nsresult RemoveStyleSheet(SheetType aType, StyleSheet* aSheet);
- inline nsresult ReplaceSheets(SheetType aType,
- const nsTArray<RefPtr<StyleSheet>>& aNewSheets);
- inline nsresult InsertStyleSheetBefore(SheetType aType,
- StyleSheet* aNewSheet,
- StyleSheet* aReferenceSheet);
- inline int32_t SheetCount(SheetType aType) const;
- inline StyleSheet* StyleSheetAt(SheetType aType, int32_t aIndex) const;
- inline nsresult RemoveDocStyleSheet(StyleSheet* aSheet);
- inline nsresult AddDocStyleSheet(StyleSheet* aSheet, nsIDocument* aDocument);
- inline already_AddRefed<nsStyleContext>
- ProbePseudoElementStyle(dom::Element* aParentElement,
- mozilla::CSSPseudoElementType aType,
- nsStyleContext* aParentContext);
- inline already_AddRefed<nsStyleContext>
- ProbePseudoElementStyle(dom::Element* aParentElement,
- mozilla::CSSPseudoElementType aType,
- nsStyleContext* aParentContext,
- TreeMatchContext& aTreeMatchContext,
- dom::Element* aPseudoElement = nullptr);
- inline nsRestyleHint HasStateDependentStyle(dom::Element* aElement,
- EventStates aStateMask);
- inline nsRestyleHint HasStateDependentStyle(
- dom::Element* aElement,
- mozilla::CSSPseudoElementType aPseudoType,
- dom::Element* aPseudoElement,
- EventStates aStateMask);
- inline void RootStyleContextAdded();
- inline void RootStyleContextRemoved();
- private:
- // Stores a pointer to an nsStyleSet or a ServoStyleSet. The least
- // significant bit is 0 for the former, 1 for the latter. This is
- // valid as the least significant bit will never be used for a pointer
- // value on platforms we care about.
- uintptr_t mValue;
- };
- StyleSetHandle() { mPtr.mValue = 0; }
- StyleSetHandle(const StyleSetHandle& aOth) { mPtr.mValue = aOth.mPtr.mValue; }
- MOZ_IMPLICIT StyleSetHandle(nsStyleSet* aSet) { *this = aSet; }
- MOZ_IMPLICIT StyleSetHandle(ServoStyleSet* aSet) { *this = aSet; }
- StyleSetHandle& operator=(nsStyleSet* aStyleSet)
- {
- MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aStyleSet) & SERVO_BIT),
- "least significant bit shouldn't be set; we use it for state");
- mPtr.mValue = reinterpret_cast<uintptr_t>(aStyleSet);
- return *this;
- }
- StyleSetHandle& operator=(ServoStyleSet* aStyleSet)
- {
- #ifdef MOZ_STYLO
- MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aStyleSet) & SERVO_BIT),
- "least significant bit shouldn't be set; we use it for state");
- mPtr.mValue =
- aStyleSet ? (reinterpret_cast<uintptr_t>(aStyleSet) | SERVO_BIT) : 0;
- return *this;
- #else
- MOZ_CRASH("should not have a ServoStyleSet object when MOZ_STYLO is "
- "disabled");
- #endif
- }
- // Make StyleSetHandle usable in boolean contexts.
- explicit operator bool() const { return !!mPtr.mValue; }
- bool operator!() const { return !mPtr.mValue; }
- // Make StyleSetHandle behave like a smart pointer.
- Ptr* operator->() { return &mPtr; }
- const Ptr* operator->() const { return &mPtr; }
- private:
- Ptr mPtr;
- };
- #undef SERVO_BIT
- } // namespace mozilla
- #endif // mozilla_StyleSetHandle_h
|