2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
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.
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.
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.
22 #ifndef CSSStyleSelector_h
23 #define CSSStyleSelector_h
25 #include "CSSFontSelector.h"
26 #include "KeyframeList.h"
28 #include "MediaQueryExp.h"
29 #include "RenderStyle.h"
30 #include "StringHash.h"
31 #include <wtf/HashMap.h>
32 #include <wtf/HashSet.h>
33 #include <wtf/RefPtr.h>
34 #include <wtf/Vector.h>
38 class CSSMutableStyleDeclaration
;
39 class CSSPrimitiveValue
;
42 class CSSFontFaceRule
;
44 class CSSRuleDataList
;
51 class CSSVariableDependentValue
;
52 class CSSVariablesRule
;
58 class MediaQueryEvaluator
;
65 class WebKitCSSKeyframesRule
;
67 class MediaQueryResult
{
69 MediaQueryResult(const MediaQueryExp
& expr
, bool result
)
75 MediaQueryExp m_expression
;
79 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
80 class CSSStyleSelector
: Noncopyable
{
82 CSSStyleSelector(Document
*, const String
& userStyleSheet
, StyleSheetList
*, CSSStyleSheet
*, bool strictParsing
, bool matchAuthorAndUserStyles
);
85 void initElementAndPseudoState(Element
*);
86 void initForStyleResolve(Element
*, RenderStyle
* parentStyle
= 0, RenderStyle::PseudoId
= RenderStyle::NOPSEUDO
);
87 PassRefPtr
<RenderStyle
> styleForElement(Element
*, RenderStyle
* parentStyle
= 0, bool allowSharing
= true, bool resolveForRootDefault
= false);
88 void keyframeStylesForAnimation(Element
*, const RenderStyle
*, KeyframeList
& list
);
90 PassRefPtr
<RenderStyle
> pseudoStyleForElement(RenderStyle::PseudoId
, Element
*, RenderStyle
* parentStyle
= 0);
93 RenderStyle
* locateSharedStyle();
94 Node
* locateCousinList(Element
* parent
, unsigned depth
= 1);
95 bool canShareStyleWithElement(Node
*);
97 RenderStyle
* style() const { return m_style
.get(); }
100 // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
101 PassRefPtr
<CSSRuleList
> styleRulesForElement(Element
*, bool authorOnly
);
102 PassRefPtr
<CSSRuleList
> pseudoStyleRulesForElement(Element
*, const String
& pseudoStyle
, bool authorOnly
);
104 // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
105 // the correct font size scaled relative to the user's default (medium).
106 float fontSizeForKeyword(int keyword
, bool quirksMode
, bool monospace
) const;
109 // When the CSS keyword "larger" is used, this function will attempt to match within the keyword
110 // table, and failing that, will simply multiply by 1.2.
111 float largerFontSize(float size
, bool quirksMode
) const;
113 // Like the previous function, but for the keyword "smaller".
114 float smallerFontSize(float size
, bool quirksMode
) const;
117 void setStyle(PassRefPtr
<RenderStyle
> s
) { m_style
= s
; } // Used by the document when setting up its root style.
118 void setFontSize(FontDescription
&, float size
);
120 void applyPropertyToStyle(int id
, CSSValue
*, RenderStyle
*);
123 float getComputedSizeFromSpecifiedSize(bool isAbsoluteSize
, float specifiedSize
);
126 Color
getColorFromPrimitiveValue(CSSPrimitiveValue
*);
128 bool hasSelectorForAttribute(const AtomicString
&);
130 CSSFontSelector
* fontSelector() { return m_fontSelector
.get(); }
132 // Checks if a compound selector (which can consist of multiple simple selectors) matches the current element.
133 bool checkSelector(CSSSelector
*);
135 void addViewportDependentMediaQueryResult(const MediaQueryExp
*, bool result
);
137 bool affectedByViewportChange() const;
139 void allVisitedStateChanged() { m_checker
.allVisitedStateChanged(); }
140 void visitedStateChanged(LinkHash visitedHash
) { m_checker
.visitedStateChanged(visitedHash
); }
142 void addVariables(CSSVariablesRule
* variables
);
143 CSSValue
* resolveVariableDependentValue(CSSVariableDependentValue
*);
144 void resolveVariablesForDeclaration(CSSMutableStyleDeclaration
* decl
, CSSMutableStyleDeclaration
* newDecl
, HashSet
<String
>& usedBlockVariables
);
146 void addKeyframeStyle(PassRefPtr
<WebKitCSSKeyframesRule
> rule
);
148 static bool createTransformOperations(CSSValue
* inValue
, RenderStyle
* inStyle
, TransformOperations
& outOperations
);
151 enum SelectorMatch
{ SelectorMatches
, SelectorFailsLocally
, SelectorFailsCompletely
};
153 // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
154 void checkForGenericFamilyChange(RenderStyle
*, RenderStyle
* parentStyle
);
155 void checkForZoomChange(RenderStyle
*, RenderStyle
* parentStyle
);
156 void checkForTextSizeAdjust();
158 void adjustRenderStyle(RenderStyle
*, Element
*);
160 void addMatchedRule(CSSRuleData
* rule
) { m_matchedRules
.append(rule
); }
161 void addMatchedDeclaration(CSSMutableStyleDeclaration
* decl
);
163 void matchRules(CSSRuleSet
*, int& firstRuleIndex
, int& lastRuleIndex
);
164 void matchRulesForList(CSSRuleDataList
*, int& firstRuleIndex
, int& lastRuleIndex
);
165 void sortMatchedRules(unsigned start
, unsigned end
);
167 void applyDeclarations(bool firstPass
, bool important
, int startIndex
, int endIndex
);
169 CSSRuleSet
* m_authorStyle
;
170 CSSRuleSet
* m_userStyle
;
171 RefPtr
<CSSStyleSheet
> m_userSheet
;
173 bool m_hasUAAppearance
;
174 BorderData m_borderData
;
175 FillLayer m_backgroundData
;
176 Color m_backgroundColor
;
178 typedef HashMap
<AtomicStringImpl
*, RefPtr
<WebKitCSSKeyframesRule
> > KeyframesRuleMap
;
179 KeyframesRuleMap m_keyframesRuleMap
;
182 static RenderStyle
* styleNotYetAvailable() { return s_styleNotYetAvailable
; }
184 class SelectorChecker
: public Noncopyable
{
186 SelectorChecker(Document
*, bool strictParsing
);
188 bool checkSelector(CSSSelector
*, Element
*) const;
189 SelectorMatch
checkSelector(CSSSelector
*, Element
*, HashSet
<AtomicStringImpl
*>* selectorAttrs
, RenderStyle::PseudoId
& dynamicPseudo
, bool isAncestor
, bool isSubSelector
, RenderStyle
* = 0, RenderStyle
* elementParentStyle
= 0) const;
190 bool checkOneSelector(CSSSelector
*, Element
*, HashSet
<AtomicStringImpl
*>* selectorAttrs
, RenderStyle::PseudoId
& dynamicPseudo
, bool isAncestor
, bool isSubSelector
, RenderStyle
*, RenderStyle
* elementParentStyle
) const;
191 PseudoState
checkPseudoState(Element
*, bool checkVisited
= true) const;
192 bool checkScrollbarPseudoClass(CSSSelector
*, RenderStyle::PseudoId
& dynamicPseudo
) const;
194 void allVisitedStateChanged();
195 void visitedStateChanged(LinkHash visitedHash
);
197 Document
* m_document
;
198 bool m_strictParsing
;
199 bool m_collectRulesOnly
;
200 RenderStyle::PseudoId m_pseudoStyle
;
201 bool m_documentIsHTML
;
202 mutable HashSet
<LinkHash
, LinkHashHash
> m_linksCheckedForVisitedState
;
206 static RenderStyle
* s_styleNotYetAvailable
;
210 void matchUARules(int& firstUARule
, int& lastUARule
);
212 void cacheBorderAndBackground();
214 void mapFillAttachment(FillLayer
*, CSSValue
*);
215 void mapFillClip(FillLayer
*, CSSValue
*);
216 void mapFillComposite(FillLayer
*, CSSValue
*);
217 void mapFillOrigin(FillLayer
*, CSSValue
*);
218 void mapFillImage(FillLayer
*, CSSValue
*);
219 void mapFillRepeat(FillLayer
*, CSSValue
*);
220 void mapFillSize(FillLayer
*, CSSValue
*);
221 void mapFillXPosition(FillLayer
*, CSSValue
*);
222 void mapFillYPosition(FillLayer
*, CSSValue
*);
224 void mapAnimationDelay(Animation
*, CSSValue
*);
225 void mapAnimationDirection(Animation
*, CSSValue
*);
226 void mapAnimationDuration(Animation
*, CSSValue
*);
227 void mapAnimationIterationCount(Animation
*, CSSValue
*);
228 void mapAnimationName(Animation
*, CSSValue
*);
229 void mapAnimationPlayState(Animation
*, CSSValue
*);
230 void mapAnimationProperty(Animation
*, CSSValue
*);
231 void mapAnimationTimingFunction(Animation
*, CSSValue
*);
233 void mapNinePieceImage(CSSValue
*, NinePieceImage
&);
235 void applyProperty(int id
, CSSValue
*);
237 void applySVGProperty(int id
, CSSValue
*);
240 StyleImage
* styleImage(CSSValue
* value
);
242 // We collect the set of decls that match in |m_matchedDecls|. We then walk the
243 // set of matched decls four times, once for those properties that others depend on (like font-size),
244 // and then a second time for all the remaining properties. We then do the same two passes
245 // for any !important rules.
246 Vector
<CSSMutableStyleDeclaration
*, 64> m_matchedDecls
;
248 // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
250 Vector
<CSSRuleData
*, 32> m_matchedRules
;
252 RefPtr
<CSSRuleList
> m_ruleList
;
254 MediaQueryEvaluator
* m_medium
;
255 RefPtr
<RenderStyle
> m_rootDefaultStyle
;
257 RenderStyle::PseudoId m_dynamicPseudo
;
259 SelectorChecker m_checker
;
261 RefPtr
<RenderStyle
> m_style
;
262 RenderStyle
* m_parentStyle
;
264 StyledElement
* m_styledElement
;
266 CSSValue
* m_lineHeightValue
;
268 bool m_matchAuthorAndUserStyles
;
270 RefPtr
<CSSFontSelector
> m_fontSelector
;
271 HashSet
<AtomicStringImpl
*> m_selectorAttrs
;
272 Vector
<CSSMutableStyleDeclaration
*> m_additionalAttributeStyleDecls
;
273 Vector
<MediaQueryResult
*> m_viewportDependentMediaQueryResults
;
275 HashMap
<String
, CSSVariablesRule
*> m_variablesMap
;
276 HashMap
<CSSMutableStyleDeclaration
*, RefPtr
<CSSMutableStyleDeclaration
> > m_resolvedVariablesDeclarations
;
281 CSSRuleData(unsigned pos
, CSSStyleRule
* r
, CSSSelector
* sel
, CSSRuleData
* prev
= 0)
291 ~CSSRuleData() { delete m_next
; }
293 unsigned position() { return m_position
; }
294 CSSStyleRule
* rule() { return m_rule
; }
295 CSSSelector
* selector() { return m_selector
; }
296 CSSRuleData
* next() { return m_next
; }
300 CSSStyleRule
* m_rule
;
301 CSSSelector
* m_selector
;
305 class CSSRuleDataList
{
307 CSSRuleDataList(unsigned pos
, CSSStyleRule
* rule
, CSSSelector
* sel
)
308 : m_first(new CSSRuleData(pos
, rule
, sel
))
313 ~CSSRuleDataList() { delete m_first
; }
315 CSSRuleData
* first() { return m_first
; }
316 CSSRuleData
* last() { return m_last
; }
318 void append(unsigned pos
, CSSStyleRule
* rule
, CSSSelector
* sel
) { m_last
= new CSSRuleData(pos
, rule
, sel
, m_last
); }
321 CSSRuleData
* m_first
;
325 } // namespace WebCore
327 #endif // CSSStyleSelector_h