|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 // vim:cindent:tabstop=2:expandtab:shiftwidth=2: |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 /* |
|
8 * style rule processor for CSS style sheets, responsible for selector |
|
9 * matching and cascading |
|
10 */ |
|
11 |
|
12 #ifndef nsCSSRuleProcessor_h_ |
|
13 #define nsCSSRuleProcessor_h_ |
|
14 |
|
15 #include "mozilla/Attributes.h" |
|
16 #include "mozilla/EventStates.h" |
|
17 #include "mozilla/MemoryReporting.h" |
|
18 #include "nsIStyleRuleProcessor.h" |
|
19 #include "nsCSSStyleSheet.h" |
|
20 #include "nsTArray.h" |
|
21 #include "nsAutoPtr.h" |
|
22 #include "nsRuleWalker.h" |
|
23 |
|
24 struct CascadeEnumData; |
|
25 struct nsCSSSelector; |
|
26 struct nsCSSSelectorList; |
|
27 struct RuleCascadeData; |
|
28 struct TreeMatchContext; |
|
29 class nsCSSKeyframesRule; |
|
30 class nsCSSPageRule; |
|
31 class nsCSSFontFeatureValuesRule; |
|
32 |
|
33 /** |
|
34 * The CSS style rule processor provides a mechanism for sibling style |
|
35 * sheets to combine their rule processing in order to allow proper |
|
36 * cascading to happen. |
|
37 * |
|
38 * CSS style rule processors keep a live reference on all style sheets |
|
39 * bound to them. The CSS style sheets keep a weak reference to all the |
|
40 * processors that they are bound to (many to many). The CSS style sheet |
|
41 * is told when the rule processor is going away (via DropRuleProcessor). |
|
42 */ |
|
43 |
|
44 class nsCSSRuleProcessor: public nsIStyleRuleProcessor { |
|
45 public: |
|
46 typedef nsTArray<nsRefPtr<nsCSSStyleSheet> > sheet_array_type; |
|
47 |
|
48 // aScopeElement must be non-null iff aSheetType is |
|
49 // nsStyleSet::eScopedDocSheet. |
|
50 nsCSSRuleProcessor(const sheet_array_type& aSheets, |
|
51 uint8_t aSheetType, |
|
52 mozilla::dom::Element* aScopeElement); |
|
53 virtual ~nsCSSRuleProcessor(); |
|
54 |
|
55 NS_DECL_ISUPPORTS |
|
56 |
|
57 public: |
|
58 nsresult ClearRuleCascades(); |
|
59 |
|
60 static nsresult Startup(); |
|
61 static void Shutdown(); |
|
62 static void FreeSystemMetrics(); |
|
63 static bool HasSystemMetric(nsIAtom* aMetric); |
|
64 |
|
65 /* |
|
66 * Returns true if the given aElement matches one of the |
|
67 * selectors in aSelectorList. Note that this method will assume |
|
68 * the given aElement is not a relevant link. aSelectorList must not |
|
69 * include any pseudo-element selectors. aSelectorList is allowed |
|
70 * to be null; in this case false will be returned. |
|
71 */ |
|
72 static bool SelectorListMatches(mozilla::dom::Element* aElement, |
|
73 TreeMatchContext& aTreeMatchContext, |
|
74 nsCSSSelectorList* aSelectorList); |
|
75 |
|
76 /* |
|
77 * Helper to get the content state for a content node. This may be |
|
78 * slightly adjusted from IntrinsicState(). |
|
79 */ |
|
80 static mozilla::EventStates GetContentState( |
|
81 mozilla::dom::Element* aElement, |
|
82 const TreeMatchContext& aTreeMatchContext); |
|
83 |
|
84 /* |
|
85 * Helper to get the content state for :visited handling for an element |
|
86 */ |
|
87 static mozilla::EventStates GetContentStateForVisitedHandling( |
|
88 mozilla::dom::Element* aElement, |
|
89 const TreeMatchContext& aTreeMatchContext, |
|
90 nsRuleWalker::VisitedHandlingType aVisitedHandling, |
|
91 bool aIsRelevantLink); |
|
92 |
|
93 /* |
|
94 * Helper to test whether a node is a link |
|
95 */ |
|
96 static bool IsLink(mozilla::dom::Element* aElement); |
|
97 |
|
98 // nsIStyleRuleProcessor |
|
99 virtual void RulesMatching(ElementRuleProcessorData* aData) MOZ_OVERRIDE; |
|
100 |
|
101 virtual void RulesMatching(PseudoElementRuleProcessorData* aData) MOZ_OVERRIDE; |
|
102 |
|
103 virtual void RulesMatching(AnonBoxRuleProcessorData* aData) MOZ_OVERRIDE; |
|
104 |
|
105 #ifdef MOZ_XUL |
|
106 virtual void RulesMatching(XULTreeRuleProcessorData* aData) MOZ_OVERRIDE; |
|
107 #endif |
|
108 |
|
109 virtual nsRestyleHint HasStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; |
|
110 virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) MOZ_OVERRIDE; |
|
111 |
|
112 virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) MOZ_OVERRIDE; |
|
113 |
|
114 virtual nsRestyleHint |
|
115 HasAttributeDependentStyle(AttributeRuleProcessorData* aData) MOZ_OVERRIDE; |
|
116 |
|
117 virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) MOZ_OVERRIDE; |
|
118 |
|
119 virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) |
|
120 const MOZ_MUST_OVERRIDE MOZ_OVERRIDE; |
|
121 virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) |
|
122 const MOZ_MUST_OVERRIDE MOZ_OVERRIDE; |
|
123 |
|
124 // Append all the currently-active font face rules to aArray. Return |
|
125 // true for success and false for failure. |
|
126 bool AppendFontFaceRules(nsPresContext* aPresContext, |
|
127 nsTArray<nsFontFaceRuleContainer>& aArray); |
|
128 |
|
129 nsCSSKeyframesRule* KeyframesRuleForName(nsPresContext* aPresContext, |
|
130 const nsString& aName); |
|
131 |
|
132 bool AppendPageRules(nsPresContext* aPresContext, |
|
133 nsTArray<nsCSSPageRule*>& aArray); |
|
134 |
|
135 bool AppendFontFeatureValuesRules(nsPresContext* aPresContext, |
|
136 nsTArray<nsCSSFontFeatureValuesRule*>& aArray); |
|
137 |
|
138 /** |
|
139 * Returns the scope element for the scoped style sheets this rule |
|
140 * processor is for. If this is not a rule processor for scoped style |
|
141 * sheets, it returns null. |
|
142 */ |
|
143 mozilla::dom::Element* GetScopeElement() const { return mScopeElement; } |
|
144 |
|
145 #ifdef DEBUG |
|
146 void AssertQuirksChangeOK() { |
|
147 NS_ASSERTION(!mRuleCascades, "can't toggle quirks style sheet without " |
|
148 "clearing rule cascades"); |
|
149 } |
|
150 #endif |
|
151 |
|
152 #ifdef XP_WIN |
|
153 // Cached theme identifier for the moz-windows-theme media query. |
|
154 static uint8_t GetWindowsThemeIdentifier(); |
|
155 static void SetWindowsThemeIdentifier(uint8_t aId) { |
|
156 sWinThemeId = aId; |
|
157 } |
|
158 #endif |
|
159 |
|
160 struct StateSelector { |
|
161 StateSelector(mozilla::EventStates aStates, nsCSSSelector* aSelector) |
|
162 : mStates(aStates), |
|
163 mSelector(aSelector) |
|
164 {} |
|
165 |
|
166 mozilla::EventStates mStates; |
|
167 nsCSSSelector* mSelector; |
|
168 }; |
|
169 |
|
170 private: |
|
171 static bool CascadeSheet(nsCSSStyleSheet* aSheet, CascadeEnumData* aData); |
|
172 |
|
173 RuleCascadeData* GetRuleCascade(nsPresContext* aPresContext); |
|
174 void RefreshRuleCascade(nsPresContext* aPresContext); |
|
175 |
|
176 nsRestyleHint HasStateDependentStyle(ElementDependentRuleProcessorData* aData, |
|
177 mozilla::dom::Element* aStatefulElement, |
|
178 nsCSSPseudoElements::Type aPseudoType, |
|
179 mozilla::EventStates aStateMask); |
|
180 |
|
181 // The sheet order here is the same as in nsStyleSet::mSheets |
|
182 sheet_array_type mSheets; |
|
183 |
|
184 // active first, then cached (most recent first) |
|
185 RuleCascadeData* mRuleCascades; |
|
186 |
|
187 // The last pres context for which GetRuleCascades was called. |
|
188 nsPresContext *mLastPresContext; |
|
189 |
|
190 // The scope element for this rule processor's scoped style sheets. |
|
191 // Only used if mSheetType == nsStyleSet::eScopedDocSheet. |
|
192 nsRefPtr<mozilla::dom::Element> mScopeElement; |
|
193 |
|
194 // type of stylesheet using this processor |
|
195 uint8_t mSheetType; // == nsStyleSet::sheetType |
|
196 |
|
197 #ifdef XP_WIN |
|
198 static uint8_t sWinThemeId; |
|
199 #endif |
|
200 }; |
|
201 |
|
202 #endif /* nsCSSRuleProcessor_h_ */ |