Unreviewed, rolling out r141964.
[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 "CSSRuleList.h"
27 #include "CSSToStyleMap.h"
28 #include "CSSValueList.h"
29 #include "InspectorCSSOMWrappers.h"
30 #include "LinkHash.h"
31 #include "MediaQueryExp.h"
32 #include "RenderStyle.h"
33 #include "RuleFeature.h"
34 #include "RuleSet.h"
35 #include "RuntimeEnabledFeatures.h"
36 #include "SelectorChecker.h"
37 #include "SelectorFilter.h"
38 #include "StyleInheritedData.h"
39 #include "StyleScopeResolver.h"
40 #include "ViewportStyleResolver.h"
41 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
42 #include "WebKitCSSSVGDocumentValue.h"
43 #endif
44 #include <wtf/HashMap.h>
45 #include <wtf/HashSet.h>
46 #include <wtf/RefPtr.h>
47 #include <wtf/Vector.h>
48 #include <wtf/text/AtomicStringHash.h>
49 #include <wtf/text/StringHash.h>
50
51 namespace WebCore {
52
53 enum ESmartMinimumForFontSize { DoNotUseSmartMinimumForFontSize, UseSmartMinimumForFontFize };
54
55 class CSSCursorImageValue;
56 class CSSFontSelector;
57 class CSSFontFace;
58 class CSSFontFaceRule;
59 class CSSImageGeneratorValue;
60 class CSSImageSetValue;
61 class CSSImageValue;
62 class CSSPageRule;
63 class CSSPrimitiveValue;
64 class CSSProperty;
65 class CSSRuleList;
66 class CSSSelector;
67 class CSSStyleSheet;
68 class CSSValue;
69 class ContainerNode;
70 class CustomFilterOperation;
71 class CustomFilterParameter;
72 class CustomFilterParameterList;
73 class Document;
74 class Element;
75 class Frame;
76 class FrameView;
77 class KURL;
78 class KeyframeList;
79 class KeyframeValue;
80 class MediaQueryEvaluator;
81 class Node;
82 class RenderRegion;
83 class RuleData;
84 class RuleSet;
85 class Settings;
86 class StaticCSSRuleList;
87 class StyleBuilder;
88 class StyleScopeResolver;
89 class StyleImage;
90 class StyleKeyframe;
91 class StylePendingImage;
92 class StylePropertySet;
93 class StyleRule;
94 #if ENABLE(SHADOW_DOM)
95 class StyleRuleHost;
96 #endif
97 class StyleRuleKeyframes;
98 class StyleRulePage;
99 class StyleRuleRegion;
100 class StyleShader;
101 class StyleSheet;
102 class StyleSheetList;
103 class StyledElement;
104 class ViewportStyleResolver;
105 class WebKitCSSFilterValue;
106 class WebKitCSSShaderValue;
107 class WebKitCSSSVGDocumentValue;
108
109 class MediaQueryResult {
110     WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
111 public:
112     MediaQueryResult(const MediaQueryExp& expr, bool result)
113         : m_expression(expr)
114         , m_result(result)
115     {
116     }
117     void reportMemoryUsage(MemoryObjectInfo*) const;
118
119     MediaQueryExp m_expression;
120     bool m_result;
121 };
122
123 enum StyleSharingBehavior {
124     AllowStyleSharing,
125     DisallowStyleSharing,
126 };
127
128 // MatchOnlyUserAgentRules is used in media queries, where relative units
129 // are interpreted according to the document root element style, and styled only
130 // from the User Agent Stylesheet rules.
131
132 enum RuleMatchingBehavior {
133     MatchAllRules,
134     MatchAllRulesExcludingSMIL,
135     MatchOnlyUserAgentRules,
136 };
137
138 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
139 class StyleResolver {
140     WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED;
141 public:
142     StyleResolver(Document*, bool matchAuthorAndUserStyles);
143     ~StyleResolver();
144
145     // Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
146     void pushParentElement(Element*);
147     void popParentElement(Element*);
148     void pushParentShadowRoot(const ShadowRoot*);
149     void popParentShadowRoot(const ShadowRoot*);
150 #if ENABLE(SHADOW_DOM)
151     void addHostRule(StyleRuleHost* rule, bool hasDocumentSecurityOrigin, const ContainerNode* scope) { ensureScopeResolver()->addHostRule(rule, hasDocumentSecurityOrigin, scope); }
152 #endif
153
154     PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, StyleSharingBehavior = AllowStyleSharing,
155         RuleMatchingBehavior = MatchAllRules, RenderRegion* regionForStyling = 0);
156
157     void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
158
159     PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId, Element*, RenderStyle* parentStyle);
160
161     PassRefPtr<RenderStyle> styleForPage(int pageIndex);
162     PassRefPtr<RenderStyle> defaultStyleForElement();
163     PassRefPtr<RenderStyle> styleForText(Text*);
164
165     static PassRefPtr<RenderStyle> styleForDocument(Document*, CSSFontSelector* = 0);
166
167     RenderStyle* style() const { return m_state.style.get(); }
168     RenderStyle* parentStyle() const { return m_state.parentStyle; }
169     RenderStyle* rootElementStyle() const { return m_state.rootElementStyle; }
170     Element* element() const { return m_state.element; }
171     Document* document() const { return m_document; }
172     const FontDescription& fontDescription() { return style()->fontDescription(); }
173     const FontDescription& parentFontDescription() { return parentStyle()->fontDescription(); }
174     void setFontDescription(const FontDescription& fontDescription) { m_state.fontDirty |= style()->setFontDescription(fontDescription); }
175     void setZoom(float f) { m_state.fontDirty |= style()->setZoom(f); }
176     void setEffectiveZoom(float f) { m_state.fontDirty |= style()->setEffectiveZoom(f); }
177     void setTextSizeAdjust(bool b) { m_state.fontDirty |= style()->setTextSizeAdjust(b); }
178     void setWritingMode(WritingMode writingMode) { m_state.fontDirty |= style()->setWritingMode(writingMode); }
179     void setTextOrientation(TextOrientation textOrientation) { m_state.fontDirty |= style()->setTextOrientation(textOrientation); }
180     bool hasParentNode() const { return m_state.parentNode; }
181
182     void resetAuthorStyle();
183     void appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >&);
184
185 private:
186 #if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM)
187     StyleScopeResolver* ensureScopeResolver()
188     {
189 #if ENABLE(STYLE_SCOPED)
190 #if ENABLE(SHADOW_DOM)
191         ASSERT(RuntimeEnabledFeatures::shadowDOMEnabled() || RuntimeEnabledFeatures::styleScopedEnabled());
192 #else
193         ASSERT(RuntimeEnabledFeatures::styleScopedEnabled());
194 #endif
195 #else
196         ASSERT(RuntimeEnabledFeatures::shadowDOMEnabled());
197 #endif
198         if (!m_scopeResolver)
199             m_scopeResolver = adoptPtr(new StyleScopeResolver());
200         return m_scopeResolver.get();
201     }
202 #endif
203
204     void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
205     void initElement(Element*);
206     void collectFeatures();
207     RenderStyle* locateSharedStyle();
208     bool styleSharingCandidateMatchesRuleSet(RuleSet*);
209     bool styleSharingCandidateMatchesHostRules();
210     Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const;
211     StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const;
212     bool canShareStyleWithElement(StyledElement*) const;
213
214     PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&);
215
216 public:
217     // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
218     enum CSSRuleFilter {
219         UAAndUserCSSRules   = 1 << 1,
220         AuthorCSSRules      = 1 << 2,
221         EmptyCSSRules       = 1 << 3,
222         CrossOriginCSSRules = 1 << 4,
223         AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules,
224         AllCSSRules         = AllButEmptyCSSRules | EmptyCSSRules,
225     };
226     PassRefPtr<CSSRuleList> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
227     PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
228
229     // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
230     // the correct font size scaled relative to the user's default (medium).
231     static float fontSizeForKeyword(Document*, int keyword, bool shouldUseFixedDefaultSize);
232
233     // Given a font size in pixel, this function will return legacy font size between 1 and 7.
234     static int legacyFontSize(Document*, int pixelFontSize, bool shouldUseFixedDefaultSize);
235
236 public:
237     void applyPropertyToStyle(CSSPropertyID, CSSValue*, RenderStyle*);
238
239     void applyPropertyToCurrentStyle(CSSPropertyID, CSSValue*);
240
241     void updateFont();
242     void initializeFontStyle(Settings*);
243
244     static float getComputedSizeFromSpecifiedSize(Document*, float zoomFactor, bool isAbsoluteSize, float specifiedSize, ESmartMinimumForFontSize = UseSmartMinimumForFontFize);
245
246     void setFontSize(FontDescription&, float size);
247
248 private:
249     static float getComputedSizeFromSpecifiedSize(Document*, RenderStyle*, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules);
250
251 public:
252     bool useSVGZoomRules();
253
254     static bool colorFromPrimitiveValueIsDerivedFromElement(CSSPrimitiveValue*);
255     Color colorFromPrimitiveValue(CSSPrimitiveValue*, bool forVisitedLink = false) const;
256
257     bool hasSelectorForId(const AtomicString&) const;
258     bool hasSelectorForClass(const AtomicString&) const;
259     bool hasSelectorForAttribute(const AtomicString&) const;
260
261     CSSFontSelector* fontSelector() const { return m_fontSelector.get(); }
262 #if ENABLE(CSS_DEVICE_ADAPTATION)
263     ViewportStyleResolver* viewportStyleResolver() { return m_viewportStyleResolver.get(); }
264 #endif
265
266     void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
267     bool hasViewportDependentMediaQueries() const { return !m_viewportDependentMediaQueryResults.isEmpty(); }
268     bool affectedByViewportChange() const;
269
270     void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>);
271
272     bool checkRegionStyle(Element* regionElement);
273
274     bool usesSiblingRules() const { return !m_features.siblingRules.isEmpty(); }
275     bool usesFirstLineRules() const { return m_features.usesFirstLineRules; }
276     bool usesBeforeAfterRules() const { return m_features.usesBeforeAfterRules; }
277
278     static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
279     
280     void invalidateMatchedPropertiesCache();
281
282 #if ENABLE(CSS_FILTERS)
283     bool createFilterOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, FilterOperations& outOperations);
284 #if ENABLE(CSS_SHADERS)
285     StyleShader* styleShader(CSSValue*);
286     StyleShader* cachedOrPendingStyleShaderFromValue(WebKitCSSShaderValue*);
287     bool parseCustomFilterParameterList(CSSValue*, CustomFilterParameterList&);
288     PassRefPtr<CustomFilterParameter> parseCustomFilterParameter(const String& name, CSSValue*);
289     PassRefPtr<CustomFilterParameter> parseCustomFilterArrayParameter(const String& name, CSSValueList*);
290     PassRefPtr<CustomFilterParameter> parseCustomFilterNumberParameter(const String& name, CSSValueList*);
291     PassRefPtr<CustomFilterParameter> parseCustomFilterTransformParameter(const String& name, CSSValueList*);
292     PassRefPtr<CustomFilterOperation> createCustomFilterOperationWithAtRuleReferenceSyntax(WebKitCSSFilterValue*);
293     PassRefPtr<CustomFilterOperation> createCustomFilterOperationWithInlineSyntax(WebKitCSSFilterValue*);
294     PassRefPtr<CustomFilterOperation> createCustomFilterOperation(WebKitCSSFilterValue*);
295     void loadPendingShaders();
296 #endif
297 #if ENABLE(SVG)
298     void loadPendingSVGDocuments();
299 #endif
300 #endif // ENABLE(CSS_FILTERS)
301
302     void loadPendingResources();
303
304 private:
305     // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
306     void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle);
307     void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle);
308     void checkForTextSizeAdjust();
309
310     void adjustRenderStyle(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element*);
311
312     void addMatchedRule(const RuleData* rule) { m_state.matchedRules.append(rule); }
313
314     struct RuleRange {
315         RuleRange(int& firstRuleIndex, int& lastRuleIndex): firstRuleIndex(firstRuleIndex), lastRuleIndex(lastRuleIndex) { }
316         int& firstRuleIndex;
317         int& lastRuleIndex;
318     };
319
320     struct MatchRanges {
321         MatchRanges() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1) { }
322         int firstUARule;
323         int lastUARule;
324         int firstAuthorRule;
325         int lastAuthorRule;
326         int firstUserRule;
327         int lastUserRule;
328         RuleRange UARuleRange() { return RuleRange(firstUARule, lastUARule); }
329         RuleRange authorRuleRange() { return RuleRange(firstAuthorRule, lastAuthorRule); }
330         RuleRange userRuleRange() { return RuleRange(firstUserRule, lastUserRule); }
331     };
332
333     struct MatchedProperties {
334         MatchedProperties() : possiblyPaddedMember(0) { }
335         void reportMemoryUsage(MemoryObjectInfo*) const;
336         
337         RefPtr<StylePropertySet> properties;
338         union {
339             struct {
340                 unsigned linkMatchType : 2;
341                 unsigned whitelistType : 2;
342             };
343             // Used to make sure all memory is zero-initialized since we compute the hash over the bytes of this object.
344             void* possiblyPaddedMember;
345         };
346     };
347
348     struct MatchResult {
349         MatchResult() : isCacheable(true) { }
350         Vector<MatchedProperties, 64> matchedProperties;
351         Vector<StyleRule*, 64> matchedRules;
352         MatchRanges ranges;
353         bool isCacheable;
354     };
355
356     struct MatchRequest {
357         MatchRequest(RuleSet* ruleSet, bool includeEmptyRules = false, const ContainerNode* scope = 0)
358             : ruleSet(ruleSet)
359             , includeEmptyRules(includeEmptyRules)
360             , scope(scope) { }
361         const RuleSet* ruleSet;
362         const bool includeEmptyRules;
363         const ContainerNode* scope;
364     };
365
366     static void addMatchedProperties(MatchResult&, const StylePropertySet* properties, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone);
367     void addElementStyleProperties(MatchResult&, const StylePropertySet*, bool isCacheable = true);
368
369     void matchAllRules(MatchResult&, bool includeSMILProperties);
370     void matchUARules(MatchResult&);
371     void matchUARules(MatchResult&, RuleSet*);
372     void matchAuthorRules(MatchResult&, bool includeEmptyRules);
373     void matchUserRules(MatchResult&, bool includeEmptyRules);
374     void matchScopedAuthorRules(MatchResult&, bool includeEmptyRules);
375     void matchHostRules(MatchResult&, bool includeEmptyRules);
376
377     void collectMatchingRules(const MatchRequest&, RuleRange&);
378     void collectMatchingRulesForRegion(const MatchRequest&, RuleRange&);
379     void collectMatchingRulesForList(const Vector<RuleData>*, const MatchRequest&, RuleRange&);
380
381     bool fastRejectSelector(const RuleData&) const;
382     void sortMatchedRules();
383     void sortAndTransferMatchedRules(MatchResult&);
384
385     bool ruleMatches(const RuleData&, const ContainerNode* scope);
386     bool checkRegionSelector(const CSSSelector* regionSelector, Element* regionElement);
387     void applyMatchedProperties(const MatchResult&, const Element*);
388     enum StyleApplicationPass {
389 #if ENABLE(CSS_VARIABLES)
390         VariableDefinitions,
391 #endif
392         HighPriorityProperties,
393         LowPriorityProperties
394     };
395     template <StyleApplicationPass pass>
396     void applyMatchedProperties(const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly);
397     template <StyleApplicationPass pass>
398     void applyProperties(const StylePropertySet* properties, StyleRule*, bool isImportant, bool inheritedOnly, PropertyWhitelistType = PropertyWhitelistNone);
399 #if ENABLE(CSS_VARIABLES)
400     void resolveVariables(CSSPropertyID, CSSValue*, Vector<std::pair<CSSPropertyID, String> >& knownExpressions);
401 #endif
402     static bool isValidRegionStyleProperty(CSSPropertyID);
403 #if ENABLE(VIDEO_TRACK)
404     static bool isValidCueStyleProperty(CSSPropertyID);
405 #endif
406     void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
407     void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>&, bool isLeftPage, bool isFirstPage, const String& pageName);
408     Settings* documentSettings() { return m_document->settings(); }
409
410     bool isLeftPage(int pageIndex) const;
411     bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
412     bool isFirstPage(int pageIndex) const;
413     String pageName(int pageIndex) const;
414
415     OwnPtr<RuleSet> m_authorStyle;
416     OwnPtr<RuleSet> m_userStyle;
417
418     RuleFeatureSet m_features;
419     OwnPtr<RuleSet> m_siblingRuleSet;
420     OwnPtr<RuleSet> m_uncommonAttributeRuleSet;
421
422     typedef HashMap<AtomicStringImpl*, RefPtr<StyleRuleKeyframes> > KeyframesRuleMap;
423     KeyframesRuleMap m_keyframesRuleMap;
424
425 public:
426     typedef HashMap<CSSPropertyID, RefPtr<CSSValue> > PendingImagePropertyMap;
427 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
428     typedef HashMap<FilterOperation*, RefPtr<WebKitCSSSVGDocumentValue> > PendingSVGDocumentMap;
429 #endif
430
431     class State {
432         WTF_MAKE_NONCOPYABLE(State);
433     public:
434         State()
435         : element(0)
436         , styledElement(0)
437         , parentNode(0)
438         , parentStyle(0)
439         , rootElementStyle(0)
440         , regionForStyling(0)
441         , sameOriginOnly(false)
442         , pseudoStyle(NOPSEUDO)
443         , elementLinkState(NotInsideLink)
444         , distributedToInsertionPoint(false)
445         , elementAffectedByClassRules(false)
446         , applyPropertyToRegularStyle(true)
447         , applyPropertyToVisitedLinkStyle(false)
448 #if ENABLE(CSS_SHADERS)
449         , hasPendingShaders(false)
450 #endif
451         , lineHeightValue(0)
452         , fontDirty(false)
453         , hasUAAppearance(false)
454         , backgroundData(BackgroundFillLayer) { }
455         
456 public:
457         // FIXME(bug 108563): to make it easier to review, these member
458         // variables are public. However we should add methods to access
459         // these variables.
460         Element* element;
461         RefPtr<RenderStyle> style;
462         StyledElement* styledElement;
463         ContainerNode* parentNode;
464         RenderStyle* parentStyle;
465         RenderStyle* rootElementStyle;
466         
467         RenderRegion* regionForStyling;
468         bool sameOriginOnly;
469         PseudoId pseudoStyle;
470
471         EInsideLink elementLinkState;
472
473         bool distributedToInsertionPoint;
474
475         bool elementAffectedByClassRules;
476
477         PseudoId dynamicPseudo;
478
479         // A buffer used to hold the set of matched rules for an element,
480         // and a temporary buffer used for merge sorting.
481         Vector<const RuleData*, 32> matchedRules;
482         RefPtr<StaticCSSRuleList> ruleList;
483
484         bool applyPropertyToRegularStyle;
485         bool applyPropertyToVisitedLinkStyle;
486
487         PendingImagePropertyMap pendingImageProperties;
488 #if ENABLE(CSS_SHADERS)
489         bool hasPendingShaders;
490 #endif
491 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
492         PendingSVGDocumentMap pendingSVGDocuments;
493 #endif
494         CSSValue* lineHeightValue;
495         bool fontDirty;
496
497         bool hasUAAppearance;
498         BorderData borderData;
499         FillLayer backgroundData;
500         Color backgroundColor;
501     };
502
503     static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
504
505     PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue*);
506     PassRefPtr<StyleImage> cachedOrPendingFromValue(CSSPropertyID, CSSImageValue*);
507     PassRefPtr<StyleImage> generatedOrPendingFromValue(CSSPropertyID, CSSImageGeneratorValue*);
508 #if ENABLE(CSS_IMAGE_SET)
509     PassRefPtr<StyleImage> setOrPendingFromValue(CSSPropertyID, CSSImageSetValue*);
510 #endif
511     PassRefPtr<StyleImage> cursorOrPendingFromValue(CSSPropertyID, CSSCursorImageValue*);
512
513     bool applyPropertyToRegularStyle() const { return m_state.applyPropertyToRegularStyle; }
514     bool applyPropertyToVisitedLinkStyle() const { return m_state.applyPropertyToVisitedLinkStyle; }
515
516     static Length convertToIntLength(CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, double multiplier = 1);
517     static Length convertToFloatLength(CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, double multiplier = 1);
518
519     CSSToStyleMap* styleMap() { return &m_styleMap; }
520     InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; }
521
522     void reportMemoryUsage(MemoryObjectInfo*) const;
523     
524 private:
525     static RenderStyle* s_styleNotYetAvailable;
526
527     void collectRulesFromUserStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&, RuleSet& userStyle);
528
529     void cacheBorderAndBackground();
530
531 private:
532     bool canShareStyleWithControl(StyledElement*) const;
533
534     void applyProperty(CSSPropertyID, CSSValue*);
535
536 #if ENABLE(SVG)
537     void applySVGProperty(CSSPropertyID, CSSValue*);
538 #endif
539
540     PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*);
541     void loadPendingImages();
542
543     static unsigned computeMatchedPropertiesHash(const MatchedProperties*, unsigned size);
544     struct MatchedPropertiesCacheItem {
545         void reportMemoryUsage(MemoryObjectInfo*) const;
546         Vector<MatchedProperties> matchedProperties;
547         MatchRanges ranges;
548         RefPtr<RenderStyle> renderStyle;
549         RefPtr<RenderStyle> parentRenderStyle;
550     };
551     const MatchedPropertiesCacheItem* findFromMatchedPropertiesCache(unsigned hash, const MatchResult&);
552     void addToMatchedPropertiesCache(const RenderStyle*, const RenderStyle* parentStyle, unsigned hash, const MatchResult&);
553
554     // Every N additions to the matched declaration cache trigger a sweep where entries holding
555     // the last reference to a style declaration are garbage collected.
556     void sweepMatchedPropertiesCache(Timer<StyleResolver>*);
557
558     bool classNamesAffectedByRules(const SpaceSplitString&) const;
559     bool sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement*) const;
560
561     unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep;
562
563     typedef HashMap<unsigned, MatchedPropertiesCacheItem> MatchedPropertiesCache;
564     MatchedPropertiesCache m_matchedPropertiesCache;
565
566     Timer<StyleResolver> m_matchedPropertiesCacheSweepTimer;
567
568     OwnPtr<MediaQueryEvaluator> m_medium;
569     RefPtr<RenderStyle> m_rootDefaultStyle;
570
571     Document* m_document;
572     // FIXME: Make SelectorChecker an on-stack object and
573     // move selectorChecker.mode() to State.
574     // selectorChecker.stringParsing() can be replaced with
575     // !document.inQuirksMode().
576     SelectorChecker m_selectorChecker;
577     SelectorFilter m_selectorFilter;
578
579     bool m_matchAuthorAndUserStyles;
580
581     RefPtr<CSSFontSelector> m_fontSelector;
582     Vector<OwnPtr<MediaQueryResult> > m_viewportDependentMediaQueryResults;
583
584 #if ENABLE(CSS_DEVICE_ADAPTATION)
585     RefPtr<ViewportStyleResolver> m_viewportStyleResolver;
586 #endif
587
588     const StyleBuilder& m_styleBuilder;
589
590     OwnPtr<StyleScopeResolver> m_scopeResolver;
591     CSSToStyleMap m_styleMap;
592     InspectorCSSOMWrappers m_inspectorCSSOMWrappers;
593
594     State m_state;
595
596     friend class StyleBuilder;
597     friend bool operator==(const MatchedProperties&, const MatchedProperties&);
598     friend bool operator!=(const MatchedProperties&, const MatchedProperties&);
599     friend bool operator==(const MatchRanges&, const MatchRanges&);
600     friend bool operator!=(const MatchRanges&, const MatchRanges&);
601 };
602
603 inline bool StyleResolver::hasSelectorForAttribute(const AtomicString &attributeName) const
604 {
605     ASSERT(!attributeName.isEmpty());
606     return m_features.attrsInRules.contains(attributeName.impl());
607 }
608
609 inline bool StyleResolver::hasSelectorForClass(const AtomicString& classValue) const
610 {
611     ASSERT(!classValue.isEmpty());
612     return m_features.classesInRules.contains(classValue.impl());
613 }
614
615 inline bool StyleResolver::hasSelectorForId(const AtomicString& idValue) const
616 {
617     ASSERT(!idValue.isEmpty());
618     return m_features.idsInRules.contains(idValue.impl());
619 }
620
621 } // namespace WebCore
622
623 #endif // StyleResolver_h