Optimize stylesheet insertions
[WebKit-https.git] / Source / WebCore / css / StyleResolver.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef StyleResolver_h
23 #define StyleResolver_h
24
25 #include "CSSRule.h"
26 #include "CSSToStyleMap.h"
27 #include "CSSValueList.h"
28 #include "LinkHash.h"
29 #include "MediaQueryExp.h"
30 #include "RenderStyle.h"
31 #include "SelectorChecker.h"
32 #include "StyleInheritedData.h"
33 #include <wtf/HashMap.h>
34 #include <wtf/HashSet.h>
35 #include <wtf/RefPtr.h>
36 #include <wtf/Vector.h>
37 #include <wtf/text/AtomicStringHash.h>
38 #include <wtf/text/StringHash.h>
39
40 namespace WebCore {
41
42 enum ESmartMinimumForFontSize { DoNotUseSmartMinimumForFontSize, UseSmartMinimumForFontFize };
43
44 class CSSFontSelector;
45 class CSSPageRule;
46 class CSSPrimitiveValue;
47 class CSSProperty;
48 class CSSRuleList;
49 class CSSFontFace;
50 class CSSFontFaceRule;
51 class CSSImageGeneratorValue;
52 class CSSImageSetValue;
53 class CSSImageValue;
54 class CSSSelector;
55 class CSSStyleRule;
56 class CSSStyleSheet;
57 class CSSValue;
58 class ContainerNode;
59 class CustomFilterOperation;
60 class CustomFilterParameter;
61 class Document;
62 class Element;
63 class Frame;
64 class FrameView;
65 class KURL;
66 class KeyframeList;
67 class KeyframeValue;
68 class MediaQueryEvaluator;
69 class Node;
70 class RenderRegion;
71 class RuleData;
72 class RuleSet;
73 class Settings;
74 class StaticCSSRuleList;
75 class StyleBuilder;
76 class StyleImage;
77 class StyleKeyframe;
78 class StylePendingImage;
79 class StylePropertySet;
80 class StyleRule;
81 class StyleRuleKeyframes;
82 class StyleRulePage;
83 class StyleRuleRegion;
84 class StyleShader;
85 class StyleSheet;
86 class StyleSheetContents;
87 class StyleSheetList;
88 class StyledElement;
89 class WebKitCSSFilterValue;
90 class WebKitCSSShaderValue;
91 class WebKitCSSSVGDocumentValue;
92
93 #if ENABLE(CSS_SHADERS)
94 typedef Vector<RefPtr<CustomFilterParameter> > CustomFilterParameterList;
95 #endif
96
97 class MediaQueryResult {
98     WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
99 public:
100     MediaQueryResult(const MediaQueryExp& expr, bool result)
101         : m_expression(expr)
102         , m_result(result)
103     {
104     }
105     void reportMemoryUsage(MemoryObjectInfo*) const;
106
107     MediaQueryExp m_expression;
108     bool m_result;
109 };
110
111 enum StyleSharingBehavior {
112     AllowStyleSharing,
113     DisallowStyleSharing,
114 };
115
116 // MatchOnlyUserAgentRules is used in media queries, where relative units
117 // are interpreted according to the document root element style, and styled only
118 // from the User Agent Stylesheet rules.
119
120 enum RuleMatchingBehavior {
121     MatchAllRules,
122     MatchAllRulesExcludingSMIL,
123     MatchOnlyUserAgentRules,
124 };
125
126 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
127 class StyleResolver {
128     WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED;
129 public:
130     StyleResolver(Document*, bool matchAuthorAndUserStyles);
131     ~StyleResolver();
132
133     // Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
134     void pushParentElement(Element*);
135     void popParentElement(Element*);
136     void pushParentShadowRoot(const ShadowRoot*);
137     void popParentShadowRoot(const ShadowRoot*);
138
139     PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, StyleSharingBehavior = AllowStyleSharing,
140         RuleMatchingBehavior = MatchAllRules, RenderRegion* regionForStyling = 0);
141
142     void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
143
144     PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId, Element*, RenderStyle* parentStyle);
145
146     PassRefPtr<RenderStyle> styleForPage(int pageIndex);
147
148     static PassRefPtr<RenderStyle> styleForDocument(Document*, CSSFontSelector* = 0);
149
150     RenderStyle* style() const { return m_style.get(); }
151     RenderStyle* parentStyle() const { return m_parentStyle; }
152     RenderStyle* rootElementStyle() const { return m_rootElementStyle; }
153     Element* element() const { return m_element; }
154     Document* document() const { return m_checker.document(); }
155     const FontDescription& fontDescription() { return style()->fontDescription(); }
156     const FontDescription& parentFontDescription() { return parentStyle()->fontDescription(); }
157     void setFontDescription(const FontDescription& fontDescription) { m_fontDirty |= style()->setFontDescription(fontDescription); }
158     void setZoom(float f) { m_fontDirty |= style()->setZoom(f); }
159     void setEffectiveZoom(float f) { m_fontDirty |= style()->setEffectiveZoom(f); }
160     void setTextSizeAdjust(bool b) { m_fontDirty |= style()->setTextSizeAdjust(b); }
161     bool hasParentNode() const { return m_parentNode; }
162
163     void resetAuthorStyle();
164     void appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >&);
165     
166     // Find the ids or classes the selectors on a stylesheet are scoped to. The selectors only apply to elements in subtrees where the root element matches the scope.
167     static bool determineStylesheetSelectorScopes(StyleSheetContents*, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes);
168
169 private:
170     void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
171     void initElement(Element*);
172     void collectFeatures();
173     RenderStyle* locateSharedStyle();
174     bool matchesRuleSet(RuleSet*);
175     Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const;
176     StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const;
177     bool canShareStyleWithElement(StyledElement*) const;
178
179     PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&);
180
181 #if ENABLE(STYLE_SCOPED)
182     void pushScope(const ContainerNode* scope, const ContainerNode* scopeParent);
183     void popScope(const ContainerNode* scope);
184 #else
185     void pushScope(const ContainerNode*, const ContainerNode*) { }
186     void popScope(const ContainerNode*) { }
187 #endif
188
189 public:
190     // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
191     enum CSSRuleFilter {
192         UAAndUserCSSRules   = 1 << 1,
193         AuthorCSSRules      = 1 << 2,
194         EmptyCSSRules       = 1 << 3,
195         CrossOriginCSSRules = 1 << 4,
196         AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules,
197         AllCSSRules         = AllButEmptyCSSRules | EmptyCSSRules,
198     };
199     PassRefPtr<CSSRuleList> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
200     PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
201
202     // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
203     // the correct font size scaled relative to the user's default (medium).
204     static float fontSizeForKeyword(Document*, int keyword, bool shouldUseFixedDefaultSize);
205
206     // Given a font size in pixel, this function will return legacy font size between 1 and 7.
207     static int legacyFontSize(Document*, int pixelFontSize, bool shouldUseFixedDefaultSize);
208
209 public:
210     void applyPropertyToStyle(CSSPropertyID, CSSValue*, RenderStyle*);
211
212     void applyPropertyToCurrentStyle(CSSPropertyID, CSSValue*);
213
214     void updateFont();
215     void initializeFontStyle(Settings*);
216
217     static float getComputedSizeFromSpecifiedSize(Document*, float zoomFactor, bool isAbsoluteSize, float specifiedSize, ESmartMinimumForFontSize = UseSmartMinimumForFontFize);
218
219     void setFontSize(FontDescription&, float size);
220
221 private:
222     static float getComputedSizeFromSpecifiedSize(Document*, RenderStyle*, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules);
223
224 public:
225     bool useSVGZoomRules();
226
227     static bool colorFromPrimitiveValueIsDerivedFromElement(CSSPrimitiveValue*);
228     Color colorFromPrimitiveValue(CSSPrimitiveValue*, bool forVisitedLink = false) const;
229
230     bool hasSelectorForAttribute(const AtomicString&) const;
231
232     CSSFontSelector* fontSelector() const { return m_fontSelector.get(); }
233
234     void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
235
236     bool affectedByViewportChange() const;
237
238     void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
239     void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
240
241     void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>);
242
243     bool checkRegionStyle(Element* regionElement);
244
245     bool usesSiblingRules() const { return !m_features.siblingRules.isEmpty(); }
246     bool usesFirstLineRules() const { return m_features.usesFirstLineRules; }
247     bool usesBeforeAfterRules() const { return m_features.usesBeforeAfterRules; }
248
249     static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
250     
251     void invalidateMatchedPropertiesCache();
252     
253     // WARNING. This will construct CSSOM wrappers for all style rules and cache then in a map for significant memory cost.
254     // It is here to support inspector. Don't use for any regular engine functions.
255     CSSStyleRule* ensureFullCSSOMWrapperForInspector(StyleRule*);
256
257 #if ENABLE(CSS_FILTERS)
258     bool createFilterOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, FilterOperations& outOperations);
259 #if ENABLE(CSS_SHADERS)
260     StyleShader* styleShader(CSSValue*);
261     StyleShader* cachedOrPendingStyleShaderFromValue(WebKitCSSShaderValue*);
262     bool parseCustomFilterParameterList(CSSValue*, CustomFilterParameterList&);
263     PassRefPtr<CustomFilterParameter> parseCustomFilterParameter(const String& name, CSSValue*);
264     PassRefPtr<CustomFilterParameter> parseCustomFilterArrayParameter(const String& name, CSSValueList*);
265     PassRefPtr<CustomFilterParameter> parseCustomFilterNumberParameter(const String& name, CSSValueList*);
266     PassRefPtr<CustomFilterParameter> parseCustomFilterTransformParameter(const String& name, CSSValueList*);
267     PassRefPtr<CustomFilterOperation> createCustomFilterOperation(WebKitCSSFilterValue*);
268     void loadPendingShaders();
269 #endif
270 #if ENABLE(SVG)
271     void loadPendingSVGDocuments();
272 #endif
273 #endif // ENABLE(CSS_FILTERS)
274
275     void loadPendingResources();
276
277     struct RuleFeature {
278         RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin)
279             : rule(rule)
280             , selectorIndex(selectorIndex)
281             , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin) 
282         { 
283         }
284         StyleRule* rule;
285         unsigned selectorIndex;
286         bool hasDocumentSecurityOrigin;
287     };
288     struct Features {
289         Features();
290         ~Features();
291         void add(const StyleResolver::Features&);
292         void clear();
293         void reportMemoryUsage(MemoryObjectInfo*) const;
294         HashSet<AtomicStringImpl*> idsInRules;
295         HashSet<AtomicStringImpl*> attrsInRules;
296         Vector<RuleFeature> siblingRules;
297         Vector<RuleFeature> uncommonAttributeRules;
298         bool usesFirstLineRules;
299         bool usesBeforeAfterRules;
300     };
301
302 private:
303     // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
304     void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle);
305     void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle);
306     void checkForTextSizeAdjust();
307
308     void adjustRenderStyle(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element*);
309
310     void addMatchedRule(const RuleData* rule) { m_matchedRules.append(rule); }
311
312     struct MatchRanges {
313         MatchRanges() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1) { }
314         int firstUARule;
315         int lastUARule;
316         int firstAuthorRule;
317         int lastAuthorRule;
318         int firstUserRule;
319         int lastUserRule;
320     };
321
322     struct MatchedProperties {
323         MatchedProperties() : possiblyPaddedMember(0) { }
324         void reportMemoryUsage(MemoryObjectInfo*) const;
325         
326         RefPtr<StylePropertySet> properties;
327         union {
328             struct {
329                 unsigned linkMatchType : 2;
330                 unsigned isInRegionRule : 1;
331             };
332             // Used to make sure all memory is zero-initialized since we compute the hash over the bytes of this object.
333             void* possiblyPaddedMember;
334         };
335     };
336
337     struct MatchResult {
338         MatchResult() : isCacheable(true) { }
339         Vector<MatchedProperties, 64> matchedProperties;
340         Vector<StyleRule*, 64> matchedRules;
341         MatchRanges ranges;
342         bool isCacheable;
343     };
344
345     struct MatchOptions {
346         MatchOptions(bool includeEmptyRules, const ContainerNode* scope = 0) : scope(scope), includeEmptyRules(includeEmptyRules) { }
347         const ContainerNode* scope;
348         bool includeEmptyRules;
349     };
350
351     static void addMatchedProperties(MatchResult&, const StylePropertySet* properties, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, bool inRegionRule = false);
352     void addElementStyleProperties(MatchResult&, const StylePropertySet*, bool isCacheable = true);
353
354     void matchAllRules(MatchResult&, bool includeSMILProperties);
355     void matchUARules(MatchResult&);
356     void matchUARules(MatchResult&, RuleSet*);
357     void matchAuthorRules(MatchResult&, bool includeEmptyRules);
358     void matchUserRules(MatchResult&, bool includeEmptyRules);
359     void matchScopedAuthorRules(MatchResult&, bool includeEmptyRules);
360     void collectMatchingRules(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&);
361     void collectMatchingRulesForRegion(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&);
362     void collectMatchingRulesForList(const Vector<RuleData>*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&);
363     bool fastRejectSelector(const RuleData&) const;
364     void sortMatchedRules();
365     void sortAndTransferMatchedRules(MatchResult&);
366
367     bool checkSelector(const RuleData&, const ContainerNode* scope = 0);
368     bool checkRegionSelector(CSSSelector* regionSelector, Element* regionElement);
369     void applyMatchedProperties(const MatchResult&, const Element*);
370     enum StyleApplicationPass {
371 #if ENABLE(CSS_VARIABLES)
372         VariableDefinitions,
373 #endif
374         HighPriorityProperties,
375         LowPriorityProperties
376     };
377     template <StyleApplicationPass pass>
378     void applyMatchedProperties(const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly);
379     template <StyleApplicationPass pass>
380     void applyProperties(const StylePropertySet* properties, StyleRule*, bool isImportant, bool inheritedOnly, bool filterRegionProperties);
381 #if ENABLE(CSS_VARIABLES)
382     void resolveVariables(CSSPropertyID, CSSValue*, Vector<std::pair<CSSPropertyID, String> >& knownExpressions);
383 #endif
384     static bool isValidRegionStyleProperty(CSSPropertyID);
385
386     void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
387     void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>&, bool isLeftPage, bool isFirstPage, const String& pageName);
388     Settings* documentSettings() { return m_checker.document()->settings(); }
389
390     bool isLeftPage(int pageIndex) const;
391     bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
392     bool isFirstPage(int pageIndex) const;
393     String pageName(int pageIndex) const;
394
395     OwnPtr<RuleSet> m_authorStyle;
396     OwnPtr<RuleSet> m_userStyle;
397
398     Features m_features;
399     OwnPtr<RuleSet> m_siblingRuleSet;
400     OwnPtr<RuleSet> m_uncommonAttributeRuleSet;
401
402     bool m_hasUAAppearance;
403     BorderData m_borderData;
404     FillLayer m_backgroundData;
405     Color m_backgroundColor;
406
407     typedef HashMap<AtomicStringImpl*, RefPtr<StyleRuleKeyframes> > KeyframesRuleMap;
408     KeyframesRuleMap m_keyframesRuleMap;
409
410 public:
411     static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
412
413     PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue*);
414     PassRefPtr<StyleImage> cachedOrPendingFromValue(CSSPropertyID, CSSImageValue*);
415     PassRefPtr<StyleImage> generatedOrPendingFromValue(CSSPropertyID, CSSImageGeneratorValue*);
416 #if ENABLE(CSS_IMAGE_SET)
417     PassRefPtr<StyleImage> setOrPendingFromValue(CSSPropertyID, CSSImageSetValue*);
418 #endif
419
420     bool applyPropertyToRegularStyle() const { return m_applyPropertyToRegularStyle; }
421     bool applyPropertyToVisitedLinkStyle() const { return m_applyPropertyToVisitedLinkStyle; }
422
423     static Length convertToIntLength(CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, double multiplier = 1);
424     static Length convertToFloatLength(CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, double multiplier = 1);
425
426     CSSToStyleMap* styleMap() { return &m_styleMap; }
427
428     void reportMemoryUsage(MemoryObjectInfo*) const;
429     
430 private:
431     static RenderStyle* s_styleNotYetAvailable;
432
433     void addStylesheetsFromSeamlessParents();
434     void addAuthorRulesAndCollectUserRulesFromSheets(const Vector<RefPtr<CSSStyleSheet> >*, RuleSet& userStyle);
435
436     void cacheBorderAndBackground();
437
438 private:
439     bool canShareStyleWithControl(StyledElement*) const;
440
441     void applyProperty(CSSPropertyID, CSSValue*);
442
443 #if ENABLE(SVG)
444     void applySVGProperty(CSSPropertyID, CSSValue*);
445 #endif
446
447     PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*);
448     void loadPendingImages();
449
450     static unsigned computeMatchedPropertiesHash(const MatchedProperties*, unsigned size);
451     struct MatchedPropertiesCacheItem {
452         void reportMemoryUsage(MemoryObjectInfo*) const;
453         Vector<MatchedProperties> matchedProperties;
454         MatchRanges ranges;
455         RefPtr<RenderStyle> renderStyle;
456         RefPtr<RenderStyle> parentRenderStyle;
457     };
458     const MatchedPropertiesCacheItem* findFromMatchedPropertiesCache(unsigned hash, const MatchResult&);
459     void addToMatchedPropertiesCache(const RenderStyle*, const RenderStyle* parentStyle, unsigned hash, const MatchResult&);
460
461     // Every N additions to the matched declaration cache trigger a sweep where entries holding
462     // the last reference to a style declaration are garbage collected.
463     void sweepMatchedPropertiesCache();
464
465     unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep;
466
467     typedef HashMap<unsigned, MatchedPropertiesCacheItem> MatchedPropertiesCache;
468     MatchedPropertiesCache m_matchedPropertiesCache;
469
470     // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
471     // merge sorting.
472     Vector<const RuleData*, 32> m_matchedRules;
473
474     RefPtr<StaticCSSRuleList> m_ruleList;
475
476     typedef HashMap<CSSPropertyID, RefPtr<CSSValue> > PendingImagePropertyMap;
477     PendingImagePropertyMap m_pendingImageProperties;
478
479     OwnPtr<MediaQueryEvaluator> m_medium;
480     RefPtr<RenderStyle> m_rootDefaultStyle;
481
482     PseudoId m_dynamicPseudo;
483     PseudoId m_pseudoStyle;
484
485     SelectorChecker m_checker;
486
487     RefPtr<RenderStyle> m_style;
488     RenderStyle* m_parentStyle;
489     RenderStyle* m_rootElementStyle;
490     Element* m_element;
491     StyledElement* m_styledElement;
492     RenderRegion* m_regionForStyling;
493     EInsideLink m_elementLinkState;
494     ContainerNode* m_parentNode;
495     CSSValue* m_lineHeightValue;
496     bool m_fontDirty;
497     bool m_matchAuthorAndUserStyles;
498     bool m_sameOriginOnly;
499     bool m_distributedToInsertionPoint;
500     bool m_hasUnknownPseudoElements;
501
502     RefPtr<CSSFontSelector> m_fontSelector;
503     Vector<OwnPtr<MediaQueryResult> > m_viewportDependentMediaQueryResults;
504
505     bool m_applyPropertyToRegularStyle;
506     bool m_applyPropertyToVisitedLinkStyle;
507     const StyleBuilder& m_styleBuilder;
508     
509     HashMap<StyleRule*, RefPtr<CSSStyleRule> > m_styleRuleToCSSOMWrapperMap;
510     HashSet<RefPtr<CSSStyleSheet> > m_styleSheetCSSOMWrapperSet;
511
512 #if ENABLE(CSS_SHADERS)
513     bool m_hasPendingShaders;
514 #endif
515
516 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
517     HashMap<FilterOperation*, RefPtr<WebKitCSSSVGDocumentValue> > m_pendingSVGDocuments;
518 #endif
519
520 #if ENABLE(STYLE_SCOPED)
521     const ContainerNode* determineScope(const CSSStyleSheet*);
522
523     typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > ScopedRuleSetMap;
524
525     RuleSet* ruleSetForScope(const ContainerNode*) const;
526
527     void setupScopeStack(const ContainerNode*);
528     bool scopeStackIsConsistent(const ContainerNode* parent) const { return parent && parent == m_scopeStackParent; }
529
530     ScopedRuleSetMap m_scopedAuthorStyles;
531     
532     struct ScopeStackFrame {
533         ScopeStackFrame() : m_scope(0), m_authorStyleBoundsIndex(0), m_ruleSet(0) { }
534         ScopeStackFrame(const ContainerNode* scope, int authorStyleBoundsIndex, RuleSet* ruleSet) : m_scope(scope), m_authorStyleBoundsIndex(authorStyleBoundsIndex), m_ruleSet(ruleSet) { }
535         const ContainerNode* m_scope;
536         int m_authorStyleBoundsIndex;
537         RuleSet* m_ruleSet;
538     };
539     // Vector (used as stack) that keeps track of scoping elements (i.e., elements with a <style scoped> child)
540     // encountered during tree iteration for style resolution.
541     Vector<ScopeStackFrame> m_scopeStack;
542     // Element last seen as parent element when updating m_scopingElementStack.
543     // This is used to decide whether m_scopingElementStack is consistent, separately from SelectorChecker::m_parentStack.
544     const ContainerNode* m_scopeStackParent;
545     int m_scopeStackParentBoundsIndex;
546 #endif
547
548     CSSToStyleMap m_styleMap;
549
550     friend class StyleBuilder;
551     friend bool operator==(const MatchedProperties&, const MatchedProperties&);
552     friend bool operator!=(const MatchedProperties&, const MatchedProperties&);
553     friend bool operator==(const MatchRanges&, const MatchRanges&);
554     friend bool operator!=(const MatchRanges&, const MatchRanges&);
555 };
556
557 } // namespace WebCore
558
559 #endif // StyleResolver_h