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