diff -r 000000000000 -r 6474c204b198 layout/style/nsCSSRuleProcessor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/style/nsCSSRuleProcessor.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,202 @@ +/* -*- 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 "nsIStyleRuleProcessor.h" +#include "nsCSSStyleSheet.h" +#include "nsTArray.h" +#include "nsAutoPtr.h" +#include "nsRuleWalker.h" + +struct CascadeEnumData; +struct nsCSSSelector; +struct nsCSSSelectorList; +struct RuleCascadeData; +struct TreeMatchContext; +class nsCSSKeyframesRule; +class nsCSSPageRule; +class nsCSSFontFeatureValuesRule; + +/** + * 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 > sheet_array_type; + + // aScopeElement must be non-null iff aSheetType is + // nsStyleSet::eScopedDocSheet. + nsCSSRuleProcessor(const sheet_array_type& aSheets, + uint8_t aSheetType, + mozilla::dom::Element* aScopeElement); + virtual ~nsCSSRuleProcessor(); + + NS_DECL_ISUPPORTS + +public: + nsresult ClearRuleCascades(); + + static nsresult 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(mozilla::dom::Element* aElement); + + // nsIStyleRuleProcessor + virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE; + + virtual void RulesMatching(PseudoElementRuleProcessorData* aData) MOZ_OVERRIDE; + + virtual void RulesMatching(AnonBoxRuleProcessorData* aData) MOZ_OVERRIDE; + +#ifdef MOZ_XUL + virtual void RulesMatching(XULTreeRuleProcessorData* aData) MOZ_OVERRIDE; +#endif + + virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; + virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) MOZ_OVERRIDE; + + virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; + + virtual nsRestyleHint + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) MOZ_OVERRIDE; + + virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) MOZ_OVERRIDE; + + virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) + const MOZ_MUST_OVERRIDE MOZ_OVERRIDE; + virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) + const MOZ_MUST_OVERRIDE MOZ_OVERRIDE; + + // Append all the currently-active font face rules to aArray. Return + // true for success and false for failure. + bool AppendFontFaceRules(nsPresContext* aPresContext, + nsTArray& aArray); + + nsCSSKeyframesRule* KeyframesRuleForName(nsPresContext* aPresContext, + const nsString& aName); + + bool AppendPageRules(nsPresContext* aPresContext, + nsTArray& aArray); + + bool AppendFontFeatureValuesRules(nsPresContext* aPresContext, + nsTArray& 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; } + +#ifdef DEBUG + void AssertQuirksChangeOK() { + NS_ASSERTION(!mRuleCascades, "can't toggle quirks style sheet without " + "clearing rule cascades"); + } +#endif + +#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; + }; + +private: + static bool CascadeSheet(nsCSSStyleSheet* aSheet, CascadeEnumData* aData); + + RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext); + void RefreshRuleCascade(nsPresContext* aPresContext); + + nsRestyleHint HasStateDependentStyle(ElementDependentRuleProcessorData* aData, + mozilla::dom::Element* aStatefulElement, + nsCSSPseudoElements::Type aPseudoType, + mozilla::EventStates aStateMask); + + // The sheet order here is the same as in nsStyleSet::mSheets + sheet_array_type mSheets; + + // active first, then cached (most recent first) + RuleCascadeData* mRuleCascades; + + // 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. + nsRefPtr mScopeElement; + + // type of stylesheet using this processor + uint8_t mSheetType; // == nsStyleSet::sheetType + +#ifdef XP_WIN + static uint8_t sWinThemeId; +#endif +}; + +#endif /* nsCSSRuleProcessor_h_ */