d88678e0673149cd6060b278e9a178c71fa76b00
[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, 2012, 2013 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 "CSSToLengthConversionData.h"
26 #include "CSSToStyleMap.h"
27 #include "CSSValueList.h"
28 #include "DocumentRuleSets.h"
29 #include "InspectorCSSOMWrappers.h"
30 #include "LinkHash.h"
31 #include "MaskImageOperation.h"
32 #include "MediaQueryExp.h"
33 #include "RenderStyle.h"
34 #include "RuleFeature.h"
35 #include "RuleSet.h"
36 #include "RuntimeEnabledFeatures.h"
37 #include "ScrollTypes.h"
38 #include "SelectorChecker.h"
39 #include "SelectorFilter.h"
40 #include "StyleInheritedData.h"
41 #include "ViewportStyleResolver.h"
42 #include <memory>
43 #include <wtf/HashMap.h>
44 #include <wtf/HashSet.h>
45 #include <wtf/RefPtr.h>
46 #include <wtf/Vector.h>
47 #include <wtf/text/AtomicStringHash.h>
48 #include <wtf/text/StringHash.h>
49
50 namespace WebCore {
51
52 class CSSCursorImageValue;
53 class CSSFontSelector;
54 class CSSFontFace;
55 class CSSFontFaceRule;
56 class CSSImageGeneratorValue;
57 class CSSImageSetValue;
58 class CSSImageValue;
59 class CSSPageRule;
60 class CSSPrimitiveValue;
61 class CSSProperty;
62 class CSSSelector;
63 class CSSStyleSheet;
64 class CSSValue;
65 class ContainerNode;
66 class Document;
67 class DeprecatedStyleBuilder;
68 class Element;
69 class Frame;
70 class FrameView;
71 class URL;
72 class KeyframeList;
73 class KeyframeValue;
74 class MediaQueryEvaluator;
75 class Node;
76 class RenderRegion;
77 class RenderScrollbar;
78 class RuleData;
79 class RuleSet;
80 class Settings;
81 class StyleImage;
82 class StyleKeyframe;
83 class StylePendingImage;
84 class StyleProperties;
85 class StyleRule;
86 class StyleRuleKeyframes;
87 class StyleRulePage;
88 class StyleRuleRegion;
89 class StyleSheet;
90 class StyleSheetList;
91 class StyledElement;
92 class SVGSVGElement;
93 class ViewportStyleResolver;
94 class WebKitCSSFilterValue;
95 struct ResourceLoaderOptions;
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
106     MediaQueryExp m_expression;
107     bool m_result;
108 };
109
110 enum StyleSharingBehavior {
111     AllowStyleSharing,
112     DisallowStyleSharing,
113 };
114
115 // MatchOnlyUserAgentRules is used in media queries, where relative units
116 // are interpreted according to the document root element style, and styled only
117 // from the User Agent Stylesheet rules.
118
119 enum RuleMatchingBehavior {
120     MatchAllRules,
121     MatchAllRulesExcludingSMIL,
122     MatchOnlyUserAgentRules,
123 };
124
125 class PseudoStyleRequest {
126 public:
127     PseudoStyleRequest(PseudoId pseudoId, RenderScrollbar* scrollbar = 0, ScrollbarPart scrollbarPart = NoPart)
128         : pseudoId(pseudoId)
129         , scrollbarPart(scrollbarPart)
130         , scrollbar(scrollbar)
131     {
132     }
133
134     PseudoId pseudoId;
135     ScrollbarPart scrollbarPart;
136     RenderScrollbar* scrollbar;
137 };
138
139 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
140 class StyleResolver {
141     WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED;
142 public:
143     StyleResolver(Document&, bool matchAuthorAndUserStyles);
144     ~StyleResolver();
145
146     // Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
147     void pushParentElement(Element*);
148     void popParentElement(Element*);
149
150     Ref<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle, StyleSharingBehavior = AllowStyleSharing,
151         RuleMatchingBehavior = MatchAllRules, const RenderRegion* regionForStyling = nullptr);
152
153     void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
154
155     PassRefPtr<RenderStyle> pseudoStyleForElement(Element*, const PseudoStyleRequest&, RenderStyle* parentStyle);
156
157     Ref<RenderStyle> styleForPage(int pageIndex);
158     Ref<RenderStyle> defaultStyleForElement();
159
160     RenderStyle* style() const { return m_state.style(); }
161     RenderStyle* parentStyle() const { return m_state.parentStyle(); }
162     RenderStyle* rootElementStyle() const { return m_state.rootElementStyle(); }
163     Element* element() { return m_state.element(); }
164     Document& document() { return m_document; }
165
166     // FIXME: It could be better to call m_ruleSets.appendAuthorStyleSheets() directly after we factor StyleRsolver further.
167     // https://bugs.webkit.org/show_bug.cgi?id=108890
168     void appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet>>&);
169
170     DocumentRuleSets& ruleSets() { return m_ruleSets; }
171     const DocumentRuleSets& ruleSets() const { return m_ruleSets; }
172     SelectorFilter& selectorFilter() { return m_selectorFilter; }
173
174     const MediaQueryEvaluator& mediaQueryEvaluator() const { return *m_medium; }
175
176 private:
177     void initElement(Element*);
178     RenderStyle* locateSharedStyle();
179     bool styleSharingCandidateMatchesRuleSet(RuleSet*);
180     Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const;
181     StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const;
182     bool canShareStyleWithElement(StyledElement*) const;
183
184     Ref<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&);
185
186 public:
187     // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
188     enum CSSRuleFilter {
189         UAAndUserCSSRules   = 1 << 1,
190         AuthorCSSRules      = 1 << 2,
191         EmptyCSSRules       = 1 << 3,
192         CrossOriginCSSRules = 1 << 4,
193         AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules,
194         AllCSSRules         = AllButEmptyCSSRules | EmptyCSSRules,
195     };
196     Vector<RefPtr<StyleRule>> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
197     Vector<RefPtr<StyleRule>> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
198
199 public:
200     void applyPropertyToStyle(CSSPropertyID, CSSValue*, RenderStyle*);
201
202     void applyPropertyToCurrentStyle(CSSPropertyID, CSSValue*);
203
204     void updateFont();
205     void initializeFontStyle(Settings*);
206
207     void setFontSize(FontDescription&, float size);
208
209 public:
210     bool useSVGZoomRules();
211     bool useSVGZoomRulesForLength();
212
213     static bool colorFromPrimitiveValueIsDerivedFromElement(CSSPrimitiveValue*);
214     Color colorFromPrimitiveValue(CSSPrimitiveValue*, bool forVisitedLink = false) const;
215
216     bool hasSelectorForId(const AtomicString&) const;
217     bool hasSelectorForClass(const AtomicString&) const;
218     bool hasSelectorForAttribute(const Element&, const AtomicString&) const;
219
220     CSSFontSelector* fontSelector() const { return m_fontSelector.get(); }
221 #if ENABLE(CSS_DEVICE_ADAPTATION)
222     ViewportStyleResolver* viewportStyleResolver() { return m_viewportStyleResolver.get(); }
223 #endif
224
225     void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
226     bool hasViewportDependentMediaQueries() const { return !m_viewportDependentMediaQueryResults.isEmpty(); }
227     bool hasMediaQueriesAffectedByViewportChange() const;
228
229     void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>);
230
231     bool checkRegionStyle(Element* regionElement);
232
233     bool usesFirstLineRules() const { return m_ruleSets.features().usesFirstLineRules; }
234     bool usesFirstLetterRules() const { return m_ruleSets.features().usesFirstLetterRules; }
235     
236     void invalidateMatchedPropertiesCache();
237
238     void clearCachedPropertiesAffectedByViewportUnits();
239
240     bool createFilterOperations(CSSValue* inValue, FilterOperations& outOperations);
241     bool createMaskImageOperations(CSSValue* inValue, Vector<RefPtr<MaskImageOperation>>& outOperations);
242     void loadPendingSVGDocuments();
243
244     void loadPendingResources();
245
246     struct RuleRange {
247         RuleRange(int& firstRuleIndex, int& lastRuleIndex): firstRuleIndex(firstRuleIndex), lastRuleIndex(lastRuleIndex) { }
248         int& firstRuleIndex;
249         int& lastRuleIndex;
250     };
251
252     struct MatchRanges {
253         MatchRanges() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1) { }
254         int firstUARule;
255         int lastUARule;
256         int firstAuthorRule;
257         int lastAuthorRule;
258         int firstUserRule;
259         int lastUserRule;
260         RuleRange UARuleRange() { return RuleRange(firstUARule, lastUARule); }
261         RuleRange authorRuleRange() { return RuleRange(firstAuthorRule, lastAuthorRule); }
262         RuleRange userRuleRange() { return RuleRange(firstUserRule, lastUserRule); }
263     };
264
265     struct MatchedProperties {
266         MatchedProperties();
267         ~MatchedProperties();
268         
269         RefPtr<StyleProperties> properties;
270         union {
271             struct {
272                 unsigned linkMatchType : 2;
273                 unsigned whitelistType : 2;
274             };
275             // Used to make sure all memory is zero-initialized since we compute the hash over the bytes of this object.
276             void* possiblyPaddedMember;
277         };
278     };
279
280     struct MatchResult {
281         MatchResult() : isCacheable(true) { }
282         Vector<MatchedProperties, 64> matchedProperties;
283         Vector<StyleRule*, 64> matchedRules;
284         MatchRanges ranges;
285         bool isCacheable;
286
287         void addMatchedProperties(const StyleProperties&, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone);
288     };
289
290 private:
291     // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
292     void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle);
293     void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle);
294 #if ENABLE(IOS_TEXT_AUTOSIZING)
295     void checkForTextSizeAdjust(RenderStyle*);
296 #endif
297
298     void adjustRenderStyle(RenderStyle& styleToAdjust, const RenderStyle& parentStyle, Element*);
299 #if ENABLE(CSS_GRID_LAYOUT)
300     std::unique_ptr<GridPosition> adjustNamedGridItemPosition(const NamedGridAreaMap&, const NamedGridLinesMap&, const GridPosition&, GridPositionSide) const;
301 #endif
302     
303     void adjustStyleForInterCharacterRuby();
304     void adjustStyleForMaskImages();
305     
306     bool fastRejectSelector(const RuleData&) const;
307
308     enum ShouldUseMatchedPropertiesCache { DoNotUseMatchedPropertiesCache = 0, UseMatchedPropertiesCache };
309     void applyMatchedProperties(const MatchResult&, const Element*, ShouldUseMatchedPropertiesCache = UseMatchedPropertiesCache);
310
311     class CascadedProperties;
312
313     void applyCascadedProperties(CascadedProperties&, int firstProperty, int lastProperty);
314     void cascadeMatches(CascadedProperties&, const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly);
315
316     static bool isValidRegionStyleProperty(CSSPropertyID);
317 #if ENABLE(VIDEO_TRACK)
318     static bool isValidCueStyleProperty(CSSPropertyID);
319 #endif
320     void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
321     void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>&, bool isLeftPage, bool isFirstPage, const String& pageName);
322     Settings* documentSettings() { return m_document.settings(); }
323
324     bool isLeftPage(int pageIndex) const;
325     bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
326     bool isFirstPage(int pageIndex) const;
327     String pageName(int pageIndex) const;
328
329     DocumentRuleSets m_ruleSets;
330
331     typedef HashMap<AtomicStringImpl*, RefPtr<StyleRuleKeyframes>> KeyframesRuleMap;
332     KeyframesRuleMap m_keyframesRuleMap;
333
334 public:
335     typedef HashMap<CSSPropertyID, RefPtr<CSSValue>> PendingImagePropertyMap;
336
337     class State {
338         WTF_MAKE_NONCOPYABLE(State);
339     public:
340         State()
341             : m_element(nullptr)
342             , m_styledElement(nullptr)
343             , m_parentStyle(nullptr)
344             , m_rootElementStyle(nullptr)
345             , m_regionForStyling(nullptr)
346             , m_elementLinkState(NotInsideLink)
347             , m_elementAffectedByClassRules(false)
348             , m_applyPropertyToRegularStyle(true)
349             , m_applyPropertyToVisitedLinkStyle(false)
350             , m_lineHeightValue(nullptr)
351             , m_fontDirty(false)
352             , m_fontSizeHasViewportUnits(false)
353             , m_hasUAAppearance(false)
354             , m_backgroundData(BackgroundFillLayer)
355         {
356         }
357
358     public:
359         void initElement(Element*);
360         void initForStyleResolve(Document&, Element*, RenderStyle* parentStyle, const RenderRegion* regionForStyling = nullptr);
361         void clear();
362
363         Document& document() const { return m_element->document(); }
364         Element* element() const { return m_element; }
365         StyledElement* styledElement() const { return m_styledElement; }
366         void setStyle(Ref<RenderStyle>&&);
367         RenderStyle* style() const { return m_style.get(); }
368         Ref<RenderStyle> takeStyle() { return m_style.releaseNonNull(); }
369
370         void setParentStyle(Ref<RenderStyle>&& parentStyle) { m_parentStyle = WTF::move(parentStyle); }
371         RenderStyle* parentStyle() const { return m_parentStyle.get(); }
372         RenderStyle* rootElementStyle() const { return m_rootElementStyle; }
373
374         const RenderRegion* regionForStyling() const { return m_regionForStyling; }
375         EInsideLink elementLinkState() const { return m_elementLinkState; }
376         void setElementAffectedByClassRules(bool isAffected) { m_elementAffectedByClassRules = isAffected; }
377         bool elementAffectedByClassRules() const { return m_elementAffectedByClassRules; }
378
379         void setApplyPropertyToRegularStyle(bool isApply) { m_applyPropertyToRegularStyle = isApply; }
380         void setApplyPropertyToVisitedLinkStyle(bool isApply) { m_applyPropertyToVisitedLinkStyle = isApply; }
381         bool applyPropertyToRegularStyle() const { return m_applyPropertyToRegularStyle; }
382         bool applyPropertyToVisitedLinkStyle() const { return m_applyPropertyToVisitedLinkStyle; }
383         PendingImagePropertyMap& pendingImageProperties() { return m_pendingImageProperties; }
384
385         Vector<RefPtr<ReferenceFilterOperation>>& filtersWithPendingSVGDocuments() { return m_filtersWithPendingSVGDocuments; }
386         Vector<RefPtr<MaskImageOperation>>& maskImagesWithPendingSVGDocuments() { return m_maskImagesWithPendingSVGDocuments; }
387
388         void setLineHeightValue(CSSValue* value) { m_lineHeightValue = value; }
389         CSSValue* lineHeightValue() { return m_lineHeightValue; }
390         void setFontDirty(bool isDirty) { m_fontDirty = isDirty; }
391         bool fontDirty() const { return m_fontDirty; }
392         void setFontSizeHasViewportUnits(bool hasViewportUnits) { m_fontSizeHasViewportUnits = hasViewportUnits; }
393         bool fontSizeHasViewportUnits() const { return m_fontSizeHasViewportUnits; }
394
395         void cacheBorderAndBackground();
396         bool hasUAAppearance() const { return m_hasUAAppearance; }
397         BorderData borderData() const { return m_borderData; }
398         FillLayer backgroundData() const { return m_backgroundData; }
399         Color backgroundColor() const { return m_backgroundColor; }
400
401         const FontDescription& fontDescription() { return m_style->fontDescription(); }
402         const FontDescription& parentFontDescription() { return m_parentStyle->fontDescription(); }
403         void setFontDescription(const FontDescription& fontDescription) { m_fontDirty |= m_style->setFontDescription(fontDescription); }
404         void setZoom(float f) { m_fontDirty |= m_style->setZoom(f); }
405         void setEffectiveZoom(float f) { m_fontDirty |= m_style->setEffectiveZoom(f); }
406         void setWritingMode(WritingMode writingMode) { m_fontDirty |= m_style->setWritingMode(writingMode); }
407         void setTextOrientation(TextOrientation textOrientation) { m_fontDirty |= m_style->setTextOrientation(textOrientation); }
408
409         bool useSVGZoomRules() const { return m_element && m_element->isSVGElement(); }
410
411         CSSToLengthConversionData cssToLengthConversionData() const { return m_cssToLengthConversionData; }
412
413     private:
414         void updateConversionData();
415
416         Element* m_element;
417         RefPtr<RenderStyle> m_style;
418         StyledElement* m_styledElement;
419         RefPtr<RenderStyle> m_parentStyle;
420         RenderStyle* m_rootElementStyle;
421
422         // Required to ASSERT in applyProperties.
423         const RenderRegion* m_regionForStyling;
424         
425         EInsideLink m_elementLinkState;
426
427         bool m_elementAffectedByClassRules;
428
429         bool m_applyPropertyToRegularStyle;
430         bool m_applyPropertyToVisitedLinkStyle;
431
432         PendingImagePropertyMap m_pendingImageProperties;
433
434         Vector<RefPtr<ReferenceFilterOperation>> m_filtersWithPendingSVGDocuments;
435         Vector<RefPtr<MaskImageOperation>> m_maskImagesWithPendingSVGDocuments;
436
437         CSSValue* m_lineHeightValue;
438         bool m_fontDirty;
439         bool m_fontSizeHasViewportUnits;
440
441         bool m_hasUAAppearance;
442         BorderData m_borderData;
443         FillLayer m_backgroundData;
444         Color m_backgroundColor;
445
446         CSSToLengthConversionData m_cssToLengthConversionData;
447     };
448
449     State& state() { return m_state; }
450
451     static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
452
453     PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue&);
454     PassRefPtr<StyleImage> cachedOrPendingFromValue(CSSPropertyID, CSSImageValue&);
455     PassRefPtr<StyleImage> generatedOrPendingFromValue(CSSPropertyID, CSSImageGeneratorValue&);
456 #if ENABLE(CSS_IMAGE_SET)
457     PassRefPtr<StyleImage> setOrPendingFromValue(CSSPropertyID, CSSImageSetValue&);
458 #endif
459     PassRefPtr<StyleImage> cursorOrPendingFromValue(CSSPropertyID, CSSCursorImageValue&);
460
461     bool applyPropertyToRegularStyle() const { return m_state.applyPropertyToRegularStyle(); }
462     bool applyPropertyToVisitedLinkStyle() const { return m_state.applyPropertyToVisitedLinkStyle(); }
463
464     CSSToStyleMap* styleMap() { return &m_styleMap; }
465     InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; }
466     const FontDescription& fontDescription() { return m_state.fontDescription(); }
467     const FontDescription& parentFontDescription() { return m_state.parentFontDescription(); }
468     void setFontDescription(const FontDescription& fontDescription) { m_state.setFontDescription(fontDescription); }
469     void setZoom(float f) { m_state.setZoom(f); }
470     void setEffectiveZoom(float f) { m_state.setEffectiveZoom(f); }
471     void setWritingMode(WritingMode writingMode) { m_state.setWritingMode(writingMode); }
472     void setTextOrientation(TextOrientation textOrientation) { m_state.setTextOrientation(textOrientation); }
473
474 private:
475     static RenderStyle* s_styleNotYetAvailable;
476
477     void cacheBorderAndBackground();
478
479     bool canShareStyleWithControl(StyledElement*) const;
480
481     void applyProperty(CSSPropertyID, CSSValue*);
482
483     void applySVGProperty(CSSPropertyID, CSSValue*);
484
485     PassRefPtr<StyleImage> loadPendingImage(const StylePendingImage&, const ResourceLoaderOptions&);
486     PassRefPtr<StyleImage> loadPendingImage(const StylePendingImage&);
487     void loadPendingImages();
488 #if ENABLE(CSS_SHAPES)
489     void loadPendingShapeImage(ShapeValue*);
490 #endif
491
492     static unsigned computeMatchedPropertiesHash(const MatchedProperties*, unsigned size);
493     struct MatchedPropertiesCacheItem {
494         Vector<MatchedProperties> matchedProperties;
495         MatchRanges ranges;
496         RefPtr<RenderStyle> renderStyle;
497         RefPtr<RenderStyle> parentRenderStyle;
498     };
499     const MatchedPropertiesCacheItem* findFromMatchedPropertiesCache(unsigned hash, const MatchResult&);
500     void addToMatchedPropertiesCache(const RenderStyle*, const RenderStyle* parentStyle, unsigned hash, const MatchResult&);
501
502     // Every N additions to the matched declaration cache trigger a sweep where entries holding
503     // the last reference to a style declaration are garbage collected.
504     void sweepMatchedPropertiesCache();
505
506     bool classNamesAffectedByRules(const SpaceSplitString&) const;
507     bool sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement*) const;
508
509     Length parseSnapCoordinate(CSSPrimitiveValue&);
510     Length parseSnapCoordinate(CSSValueList&, unsigned offset);
511     LengthSize parseSnapCoordinatePair(CSSValueList&, unsigned offset);
512     ScrollSnapPoints parseSnapPoints(CSSValue&);
513
514     unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep;
515
516     typedef HashMap<unsigned, MatchedPropertiesCacheItem> MatchedPropertiesCache;
517     MatchedPropertiesCache m_matchedPropertiesCache;
518
519     Timer m_matchedPropertiesCacheSweepTimer;
520
521     std::unique_ptr<MediaQueryEvaluator> m_medium;
522     RefPtr<RenderStyle> m_rootDefaultStyle;
523
524     Document& m_document;
525     SelectorFilter m_selectorFilter;
526
527     bool m_matchAuthorAndUserStyles;
528
529     RefPtr<CSSFontSelector> m_fontSelector;
530     Vector<std::unique_ptr<MediaQueryResult>> m_viewportDependentMediaQueryResults;
531
532 #if ENABLE(CSS_DEVICE_ADAPTATION)
533     RefPtr<ViewportStyleResolver> m_viewportStyleResolver;
534 #endif
535
536     const DeprecatedStyleBuilder& m_deprecatedStyleBuilder;
537
538     CSSToStyleMap m_styleMap;
539     InspectorCSSOMWrappers m_inspectorCSSOMWrappers;
540
541     State m_state;
542
543     friend class DeprecatedStyleBuilder;
544     friend bool operator==(const MatchedProperties&, const MatchedProperties&);
545     friend bool operator!=(const MatchedProperties&, const MatchedProperties&);
546     friend bool operator==(const MatchRanges&, const MatchRanges&);
547     friend bool operator!=(const MatchRanges&, const MatchRanges&);
548 };
549
550 inline bool StyleResolver::hasSelectorForAttribute(const Element& element, const AtomicString &attributeName) const
551 {
552     ASSERT(!attributeName.isEmpty());
553     if (element.isHTMLElement())
554         return m_ruleSets.features().attributeCanonicalLocalNamesInRules.contains(attributeName.impl());
555     return m_ruleSets.features().attributeLocalNamesInRules.contains(attributeName.impl());
556 }
557
558 inline bool StyleResolver::hasSelectorForClass(const AtomicString& classValue) const
559 {
560     ASSERT(!classValue.isEmpty());
561     return m_ruleSets.features().classesInRules.contains(classValue.impl());
562 }
563
564 inline bool StyleResolver::hasSelectorForId(const AtomicString& idValue) const
565 {
566     ASSERT(!idValue.isEmpty());
567     return m_ruleSets.features().idsInRules.contains(idValue.impl());
568 }
569
570 inline bool checkRegionSelector(const CSSSelector* regionSelector, Element* regionElement)
571 {
572     if (!regionSelector || !regionElement)
573         return false;
574
575     SelectorChecker selectorChecker(regionElement->document());
576     for (const CSSSelector* s = regionSelector; s; s = CSSSelectorList::next(s)) {
577         SelectorChecker::CheckingContext selectorCheckingContext(SelectorChecker::Mode::QueryingRules);
578         unsigned ignoredSpecificity;
579         if (selectorChecker.match(s, regionElement, selectorCheckingContext, ignoredSpecificity))
580             return true;
581     }
582     return false;
583 }
584
585 class StyleResolverParentPusher {
586 public:
587     StyleResolverParentPusher(Element* parent)
588         : m_parent(parent)
589         , m_pushedStyleResolver(0)
590     { }
591     void push()
592     {
593         if (m_pushedStyleResolver)
594             return;
595         m_pushedStyleResolver = &m_parent->document().ensureStyleResolver();
596         m_pushedStyleResolver->pushParentElement(m_parent);
597     }
598     ~StyleResolverParentPusher()
599     {
600         if (!m_pushedStyleResolver)
601             return;
602         // This tells us that our pushed style selector is in a bad state,
603         // so we should just bail out in that scenario.
604         ASSERT(m_pushedStyleResolver == &m_parent->document().ensureStyleResolver());
605         if (m_pushedStyleResolver != &m_parent->document().ensureStyleResolver())
606             return;
607         m_pushedStyleResolver->popParentElement(m_parent);
608     }
609     
610 private:
611     Element* m_parent;
612     StyleResolver* m_pushedStyleResolver;
613 };
614
615 } // namespace WebCore
616
617 #endif // StyleResolver_h