summaryrefslogtreecommitdiffstats
path: root/layout/style/StyleSetHandle.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/style/StyleSetHandle.h')
-rw-r--r--layout/style/StyleSetHandle.h219
1 files changed, 219 insertions, 0 deletions
diff --git a/layout/style/StyleSetHandle.h b/layout/style/StyleSetHandle.h
new file mode 100644
index 000000000..ad75f75ae
--- /dev/null
+++ b/layout/style/StyleSetHandle.h
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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