summaryrefslogtreecommitdiffstats
path: root/layout/style/nsCSSRuleProcessor.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/style/nsCSSRuleProcessor.h')
-rw-r--r--layout/style/nsCSSRuleProcessor.h292
1 files changed, 292 insertions, 0 deletions
diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h
new file mode 100644
index 000000000..e207a71af
--- /dev/null
+++ b/layout/style/nsCSSRuleProcessor.h
@@ -0,0 +1,292 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+// vim:cindent:tabstop=2:expandtab:shiftwidth=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/. */
+
+/*
+ * style rule processor for CSS style sheets, responsible for selector
+ * matching and cascading
+ */
+
+#ifndef nsCSSRuleProcessor_h_
+#define nsCSSRuleProcessor_h_
+
+#include "mozilla/Attributes.h"
+#include "mozilla/EventStates.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/RefCountType.h"
+#include "mozilla/SheetType.h"
+#include "mozilla/UniquePtr.h"
+#include "nsExpirationTracker.h"
+#include "nsIMediaList.h"
+#include "nsIStyleRuleProcessor.h"
+#include "nsRuleWalker.h"
+#include "nsTArray.h"
+
+struct CascadeEnumData;
+struct ElementDependentRuleProcessorData;
+struct nsCSSSelector;
+struct nsCSSSelectorList;
+struct nsFontFaceRuleContainer;
+struct RuleCascadeData;
+struct TreeMatchContext;
+class nsCSSKeyframesRule;
+class nsCSSPageRule;
+class nsCSSFontFeatureValuesRule;
+class nsCSSCounterStyleRule;
+
+namespace mozilla {
+class CSSStyleSheet;
+enum class CSSPseudoElementType : uint8_t;
+namespace css {
+class DocumentRule;
+} // namespace css
+} // namespace mozilla
+
+/**
+ * The CSS style rule processor provides a mechanism for sibling style
+ * sheets to combine their rule processing in order to allow proper
+ * cascading to happen.
+ *
+ * CSS style rule processors keep a live reference on all style sheets
+ * bound to them. The CSS style sheets keep a weak reference to all the
+ * processors that they are bound to (many to many). The CSS style sheet
+ * is told when the rule processor is going away (via DropRuleProcessor).
+ */
+
+class nsCSSRuleProcessor: public nsIStyleRuleProcessor {
+public:
+ typedef nsTArray<RefPtr<mozilla::CSSStyleSheet>> sheet_array_type;
+
+ // aScopeElement must be non-null iff aSheetType is
+ // SheetType::ScopedDoc.
+ // aPreviousCSSRuleProcessor is the rule processor (if any) that this
+ // one is replacing.
+ nsCSSRuleProcessor(const sheet_array_type& aSheets,
+ mozilla::SheetType aSheetType,
+ mozilla::dom::Element* aScopeElement,
+ nsCSSRuleProcessor* aPreviousCSSRuleProcessor,
+ bool aIsShared = false);
+ nsCSSRuleProcessor(sheet_array_type&& aSheets,
+ mozilla::SheetType aSheetType,
+ mozilla::dom::Element* aScopeElement,
+ nsCSSRuleProcessor* aPreviousCSSRuleProcessor,
+ bool aIsShared = false);
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(nsCSSRuleProcessor)
+
+public:
+ nsresult ClearRuleCascades();
+
+ static void Startup();
+ static void Shutdown();
+ static void FreeSystemMetrics();
+ static bool HasSystemMetric(nsIAtom* aMetric);
+
+ /*
+ * Returns true if the given aElement matches one of the
+ * selectors in aSelectorList. Note that this method will assume
+ * the given aElement is not a relevant link. aSelectorList must not
+ * include any pseudo-element selectors. aSelectorList is allowed
+ * to be null; in this case false will be returned.
+ */
+ static bool SelectorListMatches(mozilla::dom::Element* aElement,
+ TreeMatchContext& aTreeMatchContext,
+ nsCSSSelectorList* aSelectorList);
+
+ /*
+ * Helper to get the content state for a content node. This may be
+ * slightly adjusted from IntrinsicState().
+ */
+ static mozilla::EventStates GetContentState(
+ mozilla::dom::Element* aElement,
+ const TreeMatchContext& aTreeMatchContext);
+
+ /*
+ * Helper to get the content state for :visited handling for an element
+ */
+ static mozilla::EventStates GetContentStateForVisitedHandling(
+ mozilla::dom::Element* aElement,
+ const TreeMatchContext& aTreeMatchContext,
+ nsRuleWalker::VisitedHandlingType aVisitedHandling,
+ bool aIsRelevantLink);
+
+ /*
+ * Helper to test whether a node is a link
+ */
+ static bool IsLink(const mozilla::dom::Element* aElement);
+
+ /**
+ * Returns true if the given aElement matches aSelector.
+ * Like nsCSSRuleProcessor.cpp's SelectorMatches (and unlike
+ * SelectorMatchesTree), this does not check an entire selector list
+ * separated by combinators.
+ *
+ * :visited and :link will match both visited and non-visited links,
+ * as if aTreeMatchContext->mVisitedHandling were eLinksVisitedOrUnvisited.
+ *
+ * aSelector is restricted to not containing pseudo-elements.
+ */
+ static bool RestrictedSelectorMatches(mozilla::dom::Element* aElement,
+ nsCSSSelector* aSelector,
+ TreeMatchContext& aTreeMatchContext);
+
+ // nsIStyleRuleProcessor
+ virtual void RulesMatching(ElementRuleProcessorData* aData) override;
+
+ virtual void RulesMatching(PseudoElementRuleProcessorData* aData) override;
+
+ virtual void RulesMatching(AnonBoxRuleProcessorData* aData) override;
+
+#ifdef MOZ_XUL
+ virtual void RulesMatching(XULTreeRuleProcessorData* aData) override;
+#endif
+
+ virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) override;
+ virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override;
+
+ virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
+
+ virtual nsRestyleHint
+ HasAttributeDependentStyle(AttributeRuleProcessorData* aData,
+ mozilla::RestyleHintData& aRestyleHintDataResult)
+ override;
+
+ virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
+
+ /**
+ * If this rule processor currently has a substantive media query
+ * result cache key, return a copy of it.
+ */
+ mozilla::UniquePtr<nsMediaQueryResultCacheKey> CloneMQCacheKey();
+
+ virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
+ const MOZ_MUST_OVERRIDE override;
+ virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
+ const MOZ_MUST_OVERRIDE override;
+
+ // Append all the currently-active font face rules to aArray. Return
+ // true for success and false for failure.
+ bool AppendFontFaceRules(nsPresContext* aPresContext,
+ nsTArray<nsFontFaceRuleContainer>& aArray);
+
+ nsCSSKeyframesRule* KeyframesRuleForName(nsPresContext* aPresContext,
+ const nsString& aName);
+
+ nsCSSCounterStyleRule* CounterStyleRuleForName(nsPresContext* aPresContext,
+ const nsAString& aName);
+
+ bool AppendPageRules(nsPresContext* aPresContext,
+ nsTArray<nsCSSPageRule*>& aArray);
+
+ bool AppendFontFeatureValuesRules(nsPresContext* aPresContext,
+ nsTArray<nsCSSFontFeatureValuesRule*>& aArray);
+
+ /**
+ * Returns the scope element for the scoped style sheets this rule
+ * processor is for. If this is not a rule processor for scoped style
+ * sheets, it returns null.
+ */
+ mozilla::dom::Element* GetScopeElement() const { return mScopeElement; }
+
+ void TakeDocumentRulesAndCacheKey(
+ nsPresContext* aPresContext,
+ nsTArray<mozilla::css::DocumentRule*>& aDocumentRules,
+ nsDocumentRuleResultCacheKey& aDocumentRuleResultCacheKey);
+
+ bool IsShared() const { return mIsShared; }
+
+ nsExpirationState* GetExpirationState() { return &mExpirationState; }
+ void AddStyleSetRef();
+ void ReleaseStyleSetRef();
+ void SetInRuleProcessorCache(bool aVal) {
+ MOZ_ASSERT(mIsShared);
+ mInRuleProcessorCache = aVal;
+ }
+ bool IsInRuleProcessorCache() const { return mInRuleProcessorCache; }
+ bool IsUsedByMultipleStyleSets() const { return mStyleSetRefCnt > 1; }
+
+#ifdef XP_WIN
+ // Cached theme identifier for the moz-windows-theme media query.
+ static uint8_t GetWindowsThemeIdentifier();
+ static void SetWindowsThemeIdentifier(uint8_t aId) {
+ sWinThemeId = aId;
+ }
+#endif
+
+ struct StateSelector {
+ StateSelector(mozilla::EventStates aStates, nsCSSSelector* aSelector)
+ : mStates(aStates),
+ mSelector(aSelector)
+ {}
+
+ mozilla::EventStates mStates;
+ nsCSSSelector* mSelector;
+ };
+
+protected:
+ virtual ~nsCSSRuleProcessor();
+
+private:
+ static bool CascadeSheet(mozilla::CSSStyleSheet* aSheet,
+ CascadeEnumData* aData);
+
+ RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext);
+ void RefreshRuleCascade(nsPresContext* aPresContext);
+
+ nsRestyleHint HasStateDependentStyle(ElementDependentRuleProcessorData* aData,
+ mozilla::dom::Element* aStatefulElement,
+ mozilla::CSSPseudoElementType aPseudoType,
+ mozilla::EventStates aStateMask);
+
+ void ClearSheets();
+
+ // The sheet order here is the same as in nsStyleSet::mSheets
+ sheet_array_type mSheets;
+
+ // active first, then cached (most recent first)
+ RuleCascadeData* mRuleCascades;
+
+ // If we cleared our mRuleCascades or replaced a previous rule
+ // processor, this is the media query result cache key that was used
+ // before we lost the old rule cascades.
+ mozilla::UniquePtr<nsMediaQueryResultCacheKey> mPreviousCacheKey;
+
+ // The last pres context for which GetRuleCascades was called.
+ nsPresContext *mLastPresContext;
+
+ // The scope element for this rule processor's scoped style sheets.
+ // Only used if mSheetType == nsStyleSet::eScopedDocSheet.
+ RefPtr<mozilla::dom::Element> mScopeElement;
+
+ nsTArray<mozilla::css::DocumentRule*> mDocumentRules;
+ nsDocumentRuleResultCacheKey mDocumentCacheKey;
+
+ nsExpirationState mExpirationState;
+ MozRefCountType mStyleSetRefCnt;
+
+ // type of stylesheet using this processor
+ mozilla::SheetType mSheetType;
+
+ const bool mIsShared;
+
+ // Whether we need to build up mDocumentCacheKey and mDocumentRules as
+ // we build a RuleCascadeData. Is true only for shared rule processors
+ // and only before we build the first RuleCascadeData. See comment in
+ // RefreshRuleCascade for why.
+ bool mMustGatherDocumentRules;
+
+ bool mInRuleProcessorCache;
+
+#ifdef DEBUG
+ bool mDocumentRulesAndCacheKeyValid;
+#endif
+
+#ifdef XP_WIN
+ static uint8_t sWinThemeId;
+#endif
+};
+
+#endif /* nsCSSRuleProcessor_h_ */