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