239ac8d7bd4b38e24f02b2c1af2535a42d005962
[WebKit-https.git] / Source / WebCore / css / CSSStyleSelector.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 CSSStyleSelector_h
23 #define CSSStyleSelector_h
24
25 #include "CSSRule.h"
26 #include "LinkHash.h"
27 #include "MediaQueryExp.h"
28 #include "RenderStyle.h"
29 #include "SelectorChecker.h"
30 #include <wtf/HashMap.h>
31 #include <wtf/HashSet.h>
32 #include <wtf/RefPtr.h>
33 #include <wtf/Vector.h>
34 #include <wtf/text/StringHash.h>
35
36 namespace WebCore {
37
38 enum ESmartMinimumForFontSize { DoNotUseSmartMinimumForFontSize, UseSmartMinimumForFontFize };
39
40 class CSSFontSelector;
41 class CSSPageRule;
42 class CSSPrimitiveValue;
43 class CSSProperty;
44 class CSSFontFace;
45 class CSSFontFaceRule;
46 class CSSImageGeneratorValue;
47 class CSSImageSetValue;
48 class CSSImageValue;
49 class CSSRuleList;
50 class CSSSelector;
51 class CSSStyleApplyProperty;
52 class CSSStyleSheet;
53 class CSSValue;
54 class ContainerNode;
55 class CustomFilterOperation;
56 class CustomFilterParameter;
57 class Document;
58 class Element;
59 class Frame;
60 class FrameView;
61 class KURL;
62 class KeyframeList;
63 class KeyframeValue;
64 class MediaQueryEvaluator;
65 class Node;
66 class RenderRegion;
67 class RuleData;
68 class RuleSet;
69 class Settings;
70 class StyleImage;
71 class StylePendingImage;
72 class StylePropertySet;
73 class StyleRule;
74 class StyleShader;
75 class StyleSheet;
76 class StyleSheetList;
77 class StyledElement;
78 class WebKitCSSKeyframeRule;
79 class WebKitCSSKeyframesRule;
80 class WebKitCSSFilterValue;
81 class WebKitCSSRegionRule;
82 class WebKitCSSShaderValue;
83
84 #if ENABLE(CSS_SHADERS)
85 typedef Vector<RefPtr<CustomFilterParameter> > CustomFilterParameterList;
86 #endif
87
88 class MediaQueryResult {
89     WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
90 public:
91     MediaQueryResult(const MediaQueryExp& expr, bool result)
92         : m_expression(expr)
93         , m_result(result)
94     {
95     }
96
97     MediaQueryExp m_expression;
98     bool m_result;
99 };
100
101 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
102 class CSSStyleSelector {
103     WTF_MAKE_NONCOPYABLE(CSSStyleSelector); WTF_MAKE_FAST_ALLOCATED;
104 public:
105     CSSStyleSelector(Document*, StyleSheetList* authorSheets, CSSStyleSheet* mappedElementSheet,
106                      CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets, const Vector<RefPtr<CSSStyleSheet> >* documentUserSheets,
107                      bool strictParsing, bool matchAuthorAndUserStyles);
108     ~CSSStyleSelector();
109
110     // Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
111     void pushParentElement(Element*);
112     void popParentElement(Element*);
113     void pushParentShadowRoot(const ShadowRoot*);
114     void popParentShadowRoot(const ShadowRoot*);
115
116     PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false, RenderRegion* regionForStyling = 0);
117
118     void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
119
120     PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId, Element*, RenderStyle* parentStyle = 0);
121
122     PassRefPtr<RenderStyle> styleForPage(int pageIndex);
123
124     static PassRefPtr<RenderStyle> styleForDocument(Document*, CSSFontSelector* = 0);
125
126     RenderStyle* style() const { return m_style.get(); }
127     RenderStyle* parentStyle() const { return m_parentStyle; }
128     RenderStyle* rootElementStyle() const { return m_rootElementStyle; }
129     Element* element() const { return m_element; }
130     Document* document() const { return m_checker.document(); }
131     FontDescription fontDescription() { return style()->fontDescription(); }
132     FontDescription parentFontDescription() {return parentStyle()->fontDescription(); }
133     void setFontDescription(FontDescription fontDescription) { m_fontDirty |= style()->setFontDescription(fontDescription); }
134     void setZoom(float f) { m_fontDirty |= style()->setZoom(f); }
135     void setEffectiveZoom(float f) { m_fontDirty |= style()->setEffectiveZoom(f); }
136     void setTextSizeAdjust(bool b) { m_fontDirty |= style()->setTextSizeAdjust(b); }
137     bool hasParentNode() const { return m_parentNode; }
138     
139     void appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >&);
140     
141     // Find the ids or classes the selectors on a stylesheet are scoped to. The selectors only apply to elements in subtrees where the root element matches the scope.
142     static bool determineStylesheetSelectorScopes(CSSStyleSheet*, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes);
143
144 private:
145     void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
146     void initElement(Element*);
147     void collectFeatures();
148     RenderStyle* locateSharedStyle();
149     bool matchesRuleSet(RuleSet*);
150     Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const;
151     StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const;
152     bool canShareStyleWithElement(StyledElement*) const;
153
154     PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const WebKitCSSKeyframeRule*, KeyframeValue&);
155
156 #if ENABLE(STYLE_SCOPED)
157     void pushScope(const ContainerNode* scope, const ContainerNode* scopeParent);
158     void popScope(const ContainerNode* scope);
159 #else
160     void pushScope(const ContainerNode*, const ContainerNode*) { }
161     void popScope(const ContainerNode*) { }
162 #endif
163
164 public:
165     // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
166     enum CSSRuleFilter {
167         UAAndUserCSSRules   = 1 << 1,
168         AuthorCSSRules      = 1 << 2,
169         EmptyCSSRules       = 1 << 3,
170         CrossOriginCSSRules = 1 << 4,
171         AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules,
172         AllCSSRules         = AllButEmptyCSSRules | EmptyCSSRules,
173     };
174     PassRefPtr<CSSRuleList> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
175     PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
176
177     // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
178     // the correct font size scaled relative to the user's default (medium).
179     static float fontSizeForKeyword(Document*, int keyword, bool shouldUseFixedDefaultSize);
180
181     // Given a font size in pixel, this function will return legacy font size between 1 and 7.
182     static int legacyFontSize(Document*, int pixelFontSize, bool shouldUseFixedDefaultSize);
183
184 public:
185     void setStyle(PassRefPtr<RenderStyle> s) { m_style = s; } // Used by the document when setting up its root style.
186
187     void applyPropertyToStyle(int id, CSSValue*, RenderStyle*);
188
189     void applyPropertyToCurrentStyle(int id, CSSValue*);
190
191     void updateFont();
192
193     static float getComputedSizeFromSpecifiedSize(Document*, float zoomFactor, bool isAbsoluteSize, float specifiedSize, ESmartMinimumForFontSize = UseSmartMinimumForFontFize);
194
195     void setFontSize(FontDescription&, float size);
196
197 private:
198     static float getComputedSizeFromSpecifiedSize(Document*, RenderStyle*, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules);
199
200 public:
201     bool useSVGZoomRules();
202
203     Color colorFromPrimitiveValue(CSSPrimitiveValue*, bool forVisitedLink = false) const;
204
205     bool hasSelectorForAttribute(const AtomicString&) const;
206
207     CSSFontSelector* fontSelector() const { return m_fontSelector.get(); }
208
209     void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
210
211     bool affectedByViewportChange() const;
212
213     void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
214     void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
215
216     void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule>);
217
218     bool checkRegionStyle(Element* regionElement);
219
220     bool usesSiblingRules() const { return !m_features.siblingRules.isEmpty(); }
221     bool usesFirstLineRules() const { return m_features.usesFirstLineRules; }
222     bool usesBeforeAfterRules() const { return m_features.usesBeforeAfterRules; }
223     bool usesLinkRules() const { return m_features.usesLinkRules; }
224
225     static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
226     
227     void invalidateMatchedPropertiesCache();
228
229 #if ENABLE(CSS_FILTERS)
230     bool createFilterOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, FilterOperations& outOperations);
231 #if ENABLE(CSS_SHADERS)
232     StyleShader* styleShader(CSSValue*);
233     StyleShader* cachedOrPendingStyleShaderFromValue(WebKitCSSShaderValue*);
234     bool parseCustomFilterParameterList(CSSValue*, CustomFilterParameterList&);
235     PassRefPtr<CustomFilterParameter> parseCustomFilterNumberParamter(const String& name, CSSValueList*);
236     PassRefPtr<CustomFilterOperation> createCustomFilterOperation(WebKitCSSFilterValue*);
237     void loadPendingShaders();
238 #endif
239 #endif // ENABLE(CSS_FILTERS)
240
241     struct RuleSelectorPair {
242         RuleSelectorPair(StyleRule* rule, CSSSelector* selector) : rule(rule), selector(selector) { }
243         StyleRule* rule;
244         CSSSelector* selector;
245     };
246     struct Features {
247         Features();
248         ~Features();
249         void add(const CSSStyleSelector::Features&);
250         void clear();
251         HashSet<AtomicStringImpl*> idsInRules;
252         HashSet<AtomicStringImpl*> attrsInRules;
253         Vector<RuleSelectorPair> siblingRules;
254         Vector<RuleSelectorPair> uncommonAttributeRules;
255         bool usesFirstLineRules;
256         bool usesBeforeAfterRules;
257         bool usesLinkRules;
258     };
259
260 private:
261     // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
262     void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle);
263     void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle);
264     void checkForTextSizeAdjust();
265
266     void adjustRenderStyle(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element*);
267
268     void addMatchedRule(const RuleData* rule) { m_matchedRules.append(rule); }
269
270     struct MatchRanges {
271         MatchRanges() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1) { }
272         int firstUARule;
273         int lastUARule;
274         int firstAuthorRule;
275         int lastAuthorRule;
276         int firstUserRule;
277         int lastUserRule;
278     };
279
280     struct MatchedProperties {
281         MatchedProperties() : possiblyPaddedMember(0) { }
282         
283         RefPtr<StylePropertySet> properties;
284         union {
285             struct {
286                 unsigned linkMatchType : 2;
287                 unsigned isInRegionRule : 1;
288             };
289             // Used to make sure all memory is zero-initialized since we compute the hash over the bytes of this object.
290             void* possiblyPaddedMember;
291         };
292     };
293
294     struct MatchResult {
295         MatchResult() : isCacheable(true) { }
296         Vector<MatchedProperties, 64> matchedProperties;
297         Vector<StyleRule*, 64> matchedRules;
298         MatchRanges ranges;
299         bool isCacheable;
300     };
301
302     struct MatchOptions {
303         MatchOptions(bool includeEmptyRules, const ContainerNode* scope = 0) : scope(scope), includeEmptyRules(includeEmptyRules) { }
304         const ContainerNode* scope;
305         bool includeEmptyRules;
306     };
307
308     static void addMatchedProperties(MatchResult&, StylePropertySet* properties, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, bool inRegionRule = false);
309     void addElementStyleProperties(MatchResult&, StylePropertySet*, bool isCacheable = true);
310
311     void matchAllRules(MatchResult&);
312     void matchUARules(MatchResult&);
313     void matchUARules(MatchResult&, RuleSet*);
314     void matchAuthorRules(MatchResult&, bool includeEmptyRules);
315     void matchUserRules(MatchResult&, bool includeEmptyRules);
316     void matchScopedAuthorRules(MatchResult&, bool includeEmptyRules);
317     void collectMatchingRules(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&);
318     void collectMatchingRulesForRegion(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&);
319     void collectMatchingRulesForList(const Vector<RuleData>*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&);
320     bool fastRejectSelector(const RuleData&) const;
321     void sortMatchedRules();
322     void sortAndTransferMatchedRules(MatchResult&);
323
324     bool checkSelector(const RuleData&, const ContainerNode* scope = 0);
325     bool checkRegionSelector(CSSSelector* regionSelector, Element* regionElement);
326     void applyMatchedProperties(const MatchResult&);
327     template <bool firstPass>
328     void applyMatchedProperties(const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly);
329     template <bool firstPass>
330     void applyProperties(const StylePropertySet* properties, StyleRule*, bool isImportant, bool inheritedOnly, bool filterRegionProperties);
331
332     static bool isValidRegionStyleProperty(int id);
333
334     void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
335     void matchPageRulesForList(Vector<CSSPageRule*>& matchedRules, const Vector<CSSPageRule*>&, bool isLeftPage, bool isFirstPage, const String& pageName);
336     bool isLeftPage(int pageIndex) const;
337     bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
338     bool isFirstPage(int pageIndex) const;
339     String pageName(int pageIndex) const;
340
341     OwnPtr<RuleSet> m_authorStyle;
342     OwnPtr<RuleSet> m_userStyle;
343
344     Features m_features;
345     OwnPtr<RuleSet> m_siblingRuleSet;
346     OwnPtr<RuleSet> m_uncommonAttributeRuleSet;
347
348     bool m_hasUAAppearance;
349     BorderData m_borderData;
350     FillLayer m_backgroundData;
351     Color m_backgroundColor;
352
353     typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap;
354     KeyframesRuleMap m_keyframesRuleMap;
355
356 public:
357     static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
358
359     PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue*);
360     PassRefPtr<StyleImage> cachedOrPendingFromValue(CSSPropertyID, CSSImageValue*);
361     PassRefPtr<StyleImage> generatedOrPendingFromValue(CSSPropertyID, CSSImageGeneratorValue*);
362 #if ENABLE(CSS_IMAGE_SET)
363     PassRefPtr<StyleImage> setOrPendingFromValue(CSSPropertyID, CSSImageSetValue*);
364 #endif
365
366     bool applyPropertyToRegularStyle() const { return m_applyPropertyToRegularStyle; }
367     bool applyPropertyToVisitedLinkStyle() const { return m_applyPropertyToVisitedLinkStyle; }
368
369     static Length convertToIntLength(CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, double multiplier = 1);
370     static Length convertToFloatLength(CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, double multiplier = 1);
371
372 private:
373     static RenderStyle* s_styleNotYetAvailable;
374
375     void cacheBorderAndBackground();
376
377     void mapFillAttachment(CSSPropertyID, FillLayer*, CSSValue*);
378     void mapFillClip(CSSPropertyID, FillLayer*, CSSValue*);
379     void mapFillComposite(CSSPropertyID, FillLayer*, CSSValue*);
380     void mapFillOrigin(CSSPropertyID, FillLayer*, CSSValue*);
381     void mapFillImage(CSSPropertyID, FillLayer*, CSSValue*);
382     void mapFillRepeatX(CSSPropertyID, FillLayer*, CSSValue*);
383     void mapFillRepeatY(CSSPropertyID, FillLayer*, CSSValue*);
384     void mapFillSize(CSSPropertyID, FillLayer*, CSSValue*);
385     void mapFillXPosition(CSSPropertyID, FillLayer*, CSSValue*);
386     void mapFillYPosition(CSSPropertyID, FillLayer*, CSSValue*);
387
388     void mapAnimationDelay(Animation*, CSSValue*);
389     void mapAnimationDirection(Animation*, CSSValue*);
390     void mapAnimationDuration(Animation*, CSSValue*);
391     void mapAnimationFillMode(Animation*, CSSValue*);
392     void mapAnimationIterationCount(Animation*, CSSValue*);
393     void mapAnimationName(Animation*, CSSValue*);
394     void mapAnimationPlayState(Animation*, CSSValue*);
395     void mapAnimationProperty(Animation*, CSSValue*);
396     void mapAnimationTimingFunction(Animation*, CSSValue*);
397
398 public:
399     void mapNinePieceImage(CSSPropertyID, CSSValue*, NinePieceImage&);
400     void mapNinePieceImageSlice(CSSValue*, NinePieceImage&);
401     LengthBox mapNinePieceImageQuad(CSSValue*);
402     void mapNinePieceImageRepeat(CSSValue*, NinePieceImage&);
403 private:
404     bool canShareStyleWithControl(StyledElement*) const;
405
406     void applyProperty(int id, CSSValue*);
407
408 #if ENABLE(SVG)
409     void applySVGProperty(int id, CSSValue*);
410 #endif
411
412     PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*);
413     void loadPendingImages();
414
415     static unsigned computeMatchedPropertiesHash(const MatchedProperties*, unsigned size);
416     struct MatchedPropertiesCacheItem {
417         Vector<MatchedProperties> matchedProperties;
418         MatchRanges ranges;
419         RefPtr<RenderStyle> renderStyle;
420         RefPtr<RenderStyle> parentRenderStyle;
421     };
422     const MatchedPropertiesCacheItem* findFromMatchedPropertiesCache(unsigned hash, const MatchResult&);
423     void addToMatchedPropertiesCache(const RenderStyle*, const RenderStyle* parentStyle, unsigned hash, const MatchResult&);
424
425     // Every N additions to the matched declaration cache trigger a sweep where entries holding
426     // the last reference to a style declaration are garbage collected.
427     void sweepMatchedPropertiesCache();
428
429     unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep;
430
431     typedef HashMap<unsigned, MatchedPropertiesCacheItem> MatchedPropertiesCache;
432     MatchedPropertiesCache m_matchedPropertiesCache;
433
434     // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
435     // merge sorting.
436     Vector<const RuleData*, 32> m_matchedRules;
437
438     RefPtr<CSSRuleList> m_ruleList;
439
440     HashSet<int> m_pendingImageProperties; // Hash of CSSPropertyIDs
441
442     OwnPtr<MediaQueryEvaluator> m_medium;
443     RefPtr<RenderStyle> m_rootDefaultStyle;
444
445     PseudoId m_dynamicPseudo;
446
447     SelectorChecker m_checker;
448
449     RefPtr<RenderStyle> m_style;
450     RenderStyle* m_parentStyle;
451     RenderStyle* m_rootElementStyle;
452     Element* m_element;
453     StyledElement* m_styledElement;
454     RenderRegion* m_regionForStyling;
455     EInsideLink m_elementLinkState;
456     ContainerNode* m_parentNode;
457     CSSValue* m_lineHeightValue;
458     bool m_fontDirty;
459     bool m_matchAuthorAndUserStyles;
460     bool m_sameOriginOnly;
461
462     RefPtr<CSSFontSelector> m_fontSelector;
463     Vector<OwnPtr<MediaQueryResult> > m_viewportDependentMediaQueryResults;
464
465     bool m_applyPropertyToRegularStyle;
466     bool m_applyPropertyToVisitedLinkStyle;
467     const CSSStyleApplyProperty& m_applyProperty;
468
469 #if ENABLE(CSS_SHADERS)
470     bool m_hasPendingShaders;
471 #endif
472
473 #if ENABLE(STYLE_SCOPED)
474     static const ContainerNode* determineScope(const CSSStyleSheet*);
475
476     typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > ScopedRuleSetMap;
477
478     RuleSet* ruleSetForScope(const ContainerNode*) const;
479
480     void setupScopeStack(const ContainerNode*);
481     bool scopeStackIsConsistent(const ContainerNode* parent) const { return parent && parent == m_scopeStackParent; }
482
483     ScopedRuleSetMap m_scopedAuthorStyles;
484     
485     struct ScopeStackFrame {
486         ScopeStackFrame() : m_scope(0), m_ruleSet(0) { }
487         ScopeStackFrame(const ContainerNode* scope, RuleSet* ruleSet) : m_scope(scope), m_ruleSet(ruleSet) { }
488         const ContainerNode* m_scope;
489         RuleSet* m_ruleSet;
490     };
491     // Vector (used as stack) that keeps track of scoping elements (i.e., elements with a <style scoped> child)
492     // encountered during tree iteration for style resolution.
493     Vector<ScopeStackFrame> m_scopeStack;
494     // Element last seen as parent element when updating m_scopingElementStack.
495     // This is used to decide whether m_scopingElementStack is consistent, separately from SelectorChecker::m_parentStack.
496     const ContainerNode* m_scopeStackParent;
497 #endif
498
499     friend class CSSStyleApplyProperty;
500     friend bool operator==(const MatchedProperties&, const MatchedProperties&);
501     friend bool operator!=(const MatchedProperties&, const MatchedProperties&);
502     friend bool operator==(const MatchRanges&, const MatchRanges&);
503     friend bool operator!=(const MatchRanges&, const MatchRanges&);
504 };
505
506 } // namespace WebCore
507
508 #endif // CSSStyleSelector_h