michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: // vim:cindent:tabstop=2:expandtab:shiftwidth=2: michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * style rule processor for CSS style sheets, responsible for selector michael@0: * matching and cascading michael@0: */ michael@0: michael@0: #ifndef nsCSSRuleProcessor_h_ michael@0: #define nsCSSRuleProcessor_h_ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "mozilla/EventStates.h" michael@0: #include "mozilla/MemoryReporting.h" michael@0: #include "nsIStyleRuleProcessor.h" michael@0: #include "nsCSSStyleSheet.h" michael@0: #include "nsTArray.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "nsRuleWalker.h" michael@0: michael@0: struct CascadeEnumData; michael@0: struct nsCSSSelector; michael@0: struct nsCSSSelectorList; michael@0: struct RuleCascadeData; michael@0: struct TreeMatchContext; michael@0: class nsCSSKeyframesRule; michael@0: class nsCSSPageRule; michael@0: class nsCSSFontFeatureValuesRule; michael@0: michael@0: /** michael@0: * The CSS style rule processor provides a mechanism for sibling style michael@0: * sheets to combine their rule processing in order to allow proper michael@0: * cascading to happen. michael@0: * michael@0: * CSS style rule processors keep a live reference on all style sheets michael@0: * bound to them. The CSS style sheets keep a weak reference to all the michael@0: * processors that they are bound to (many to many). The CSS style sheet michael@0: * is told when the rule processor is going away (via DropRuleProcessor). michael@0: */ michael@0: michael@0: class nsCSSRuleProcessor: public nsIStyleRuleProcessor { michael@0: public: michael@0: typedef nsTArray > sheet_array_type; michael@0: michael@0: // aScopeElement must be non-null iff aSheetType is michael@0: // nsStyleSet::eScopedDocSheet. michael@0: nsCSSRuleProcessor(const sheet_array_type& aSheets, michael@0: uint8_t aSheetType, michael@0: mozilla::dom::Element* aScopeElement); michael@0: virtual ~nsCSSRuleProcessor(); michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: michael@0: public: michael@0: nsresult ClearRuleCascades(); michael@0: michael@0: static nsresult Startup(); michael@0: static void Shutdown(); michael@0: static void FreeSystemMetrics(); michael@0: static bool HasSystemMetric(nsIAtom* aMetric); michael@0: michael@0: /* michael@0: * Returns true if the given aElement matches one of the michael@0: * selectors in aSelectorList. Note that this method will assume michael@0: * the given aElement is not a relevant link. aSelectorList must not michael@0: * include any pseudo-element selectors. aSelectorList is allowed michael@0: * to be null; in this case false will be returned. michael@0: */ michael@0: static bool SelectorListMatches(mozilla::dom::Element* aElement, michael@0: TreeMatchContext& aTreeMatchContext, michael@0: nsCSSSelectorList* aSelectorList); michael@0: michael@0: /* michael@0: * Helper to get the content state for a content node. This may be michael@0: * slightly adjusted from IntrinsicState(). michael@0: */ michael@0: static mozilla::EventStates GetContentState( michael@0: mozilla::dom::Element* aElement, michael@0: const TreeMatchContext& aTreeMatchContext); michael@0: michael@0: /* michael@0: * Helper to get the content state for :visited handling for an element michael@0: */ michael@0: static mozilla::EventStates GetContentStateForVisitedHandling( michael@0: mozilla::dom::Element* aElement, michael@0: const TreeMatchContext& aTreeMatchContext, michael@0: nsRuleWalker::VisitedHandlingType aVisitedHandling, michael@0: bool aIsRelevantLink); michael@0: michael@0: /* michael@0: * Helper to test whether a node is a link michael@0: */ michael@0: static bool IsLink(mozilla::dom::Element* aElement); michael@0: michael@0: // nsIStyleRuleProcessor michael@0: virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE; michael@0: michael@0: virtual void RulesMatching(PseudoElementRuleProcessorData* aData) MOZ_OVERRIDE; michael@0: michael@0: virtual void RulesMatching(AnonBoxRuleProcessorData* aData) MOZ_OVERRIDE; michael@0: michael@0: #ifdef MOZ_XUL michael@0: virtual void RulesMatching(XULTreeRuleProcessorData* aData) MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; michael@0: virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) MOZ_OVERRIDE; michael@0: michael@0: virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; michael@0: michael@0: virtual nsRestyleHint michael@0: HasAttributeDependentStyle(AttributeRuleProcessorData* aData) MOZ_OVERRIDE; michael@0: michael@0: virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) MOZ_OVERRIDE; michael@0: michael@0: virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) michael@0: const MOZ_MUST_OVERRIDE MOZ_OVERRIDE; michael@0: virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) michael@0: const MOZ_MUST_OVERRIDE MOZ_OVERRIDE; michael@0: michael@0: // Append all the currently-active font face rules to aArray. Return michael@0: // true for success and false for failure. michael@0: bool AppendFontFaceRules(nsPresContext* aPresContext, michael@0: nsTArray& aArray); michael@0: michael@0: nsCSSKeyframesRule* KeyframesRuleForName(nsPresContext* aPresContext, michael@0: const nsString& aName); michael@0: michael@0: bool AppendPageRules(nsPresContext* aPresContext, michael@0: nsTArray& aArray); michael@0: michael@0: bool AppendFontFeatureValuesRules(nsPresContext* aPresContext, michael@0: nsTArray& aArray); michael@0: michael@0: /** michael@0: * Returns the scope element for the scoped style sheets this rule michael@0: * processor is for. If this is not a rule processor for scoped style michael@0: * sheets, it returns null. michael@0: */ michael@0: mozilla::dom::Element* GetScopeElement() const { return mScopeElement; } michael@0: michael@0: #ifdef DEBUG michael@0: void AssertQuirksChangeOK() { michael@0: NS_ASSERTION(!mRuleCascades, "can't toggle quirks style sheet without " michael@0: "clearing rule cascades"); michael@0: } michael@0: #endif michael@0: michael@0: #ifdef XP_WIN michael@0: // Cached theme identifier for the moz-windows-theme media query. michael@0: static uint8_t GetWindowsThemeIdentifier(); michael@0: static void SetWindowsThemeIdentifier(uint8_t aId) { michael@0: sWinThemeId = aId; michael@0: } michael@0: #endif michael@0: michael@0: struct StateSelector { michael@0: StateSelector(mozilla::EventStates aStates, nsCSSSelector* aSelector) michael@0: : mStates(aStates), michael@0: mSelector(aSelector) michael@0: {} michael@0: michael@0: mozilla::EventStates mStates; michael@0: nsCSSSelector* mSelector; michael@0: }; michael@0: michael@0: private: michael@0: static bool CascadeSheet(nsCSSStyleSheet* aSheet, CascadeEnumData* aData); michael@0: michael@0: RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext); michael@0: void RefreshRuleCascade(nsPresContext* aPresContext); michael@0: michael@0: nsRestyleHint HasStateDependentStyle(ElementDependentRuleProcessorData* aData, michael@0: mozilla::dom::Element* aStatefulElement, michael@0: nsCSSPseudoElements::Type aPseudoType, michael@0: mozilla::EventStates aStateMask); michael@0: michael@0: // The sheet order here is the same as in nsStyleSet::mSheets michael@0: sheet_array_type mSheets; michael@0: michael@0: // active first, then cached (most recent first) michael@0: RuleCascadeData* mRuleCascades; michael@0: michael@0: // The last pres context for which GetRuleCascades was called. michael@0: nsPresContext *mLastPresContext; michael@0: michael@0: // The scope element for this rule processor's scoped style sheets. michael@0: // Only used if mSheetType == nsStyleSet::eScopedDocSheet. michael@0: nsRefPtr mScopeElement; michael@0: michael@0: // type of stylesheet using this processor michael@0: uint8_t mSheetType; // == nsStyleSet::sheetType michael@0: michael@0: #ifdef XP_WIN michael@0: static uint8_t sWinThemeId; michael@0: #endif michael@0: }; michael@0: michael@0: #endif /* nsCSSRuleProcessor_h_ */