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"
27 #include "MediaQueryExp.h"
28 #include "RenderStyle.h"
29 #include "StringHash.h"
30 #include <wtf/HashMap.h>
31 #include <wtf/HashSet.h>
32 #include <wtf/RefPtr.h>
33 #include <wtf/Vector.h>
37 class CSSMutableStyleDeclaration;
39 class CSSPrimitiveValue;
42 class CSSFontFaceRule;
44 class CSSRuleDataList;
51 class CSSVariableDependentValue;
52 class CSSVariablesRule;
60 class MediaQueryEvaluator;
67 class WebKitCSSKeyframeRule;
68 class WebKitCSSKeyframesRule;
70 class MediaQueryResult : public Noncopyable {
72 MediaQueryResult(const MediaQueryExp& expr, bool result)
78 MediaQueryExp m_expression;
82 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
83 class CSSStyleSelector : public Noncopyable {
85 CSSStyleSelector(Document*, StyleSheetList* authorSheets, CSSStyleSheet* mappedElementSheet,
86 CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
87 bool strictParsing, bool matchAuthorAndUserStyles);
90 PassRefPtr<RenderStyle> styleForElement(Element* e, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false, bool matchVisitedPseudoClass = false);
92 void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList& list);
94 PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle = 0, bool matchVisitedPseudoClass = false);
96 PassRefPtr<RenderStyle> styleForPage(int pageIndex);
98 static PassRefPtr<RenderStyle> styleForDocument(Document*);
101 // Datagrid style computation (uses unique pseudo elements and structures)
102 PassRefPtr<RenderStyle> pseudoStyleForDataGridColumn(DataGridColumn*, RenderStyle* parentStyle);
103 PassRefPtr<RenderStyle> pseudoStyleForDataGridColumnHeader(DataGridColumn*, RenderStyle* parentStyle);
107 void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
108 void initElement(Element*);
109 RenderStyle* locateSharedStyle();
110 Node* locateCousinList(Element* parent, unsigned depth = 1);
111 bool canShareStyleWithElement(Node*);
113 RenderStyle* style() const { return m_style.get(); }
115 PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const WebKitCSSKeyframeRule*, KeyframeList&);
118 // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
119 PassRefPtr<CSSRuleList> styleRulesForElement(Element*, bool authorOnly);
120 PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, bool authorOnly);
123 // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
124 // the correct font size scaled relative to the user's default (medium).
125 static float fontSizeForKeyword(Document*, int keyword, bool monospace);
127 // When the CSS keyword "larger" is used, this function will attempt to match within the keyword
128 // table, and failing that, will simply multiply by 1.2.
129 float largerFontSize(float size, bool quirksMode) const;
131 // Like the previous function, but for the keyword "smaller".
132 float smallerFontSize(float size, bool quirksMode) const;
135 void setStyle(PassRefPtr<RenderStyle> s) { m_style = s; } // Used by the document when setting up its root style.
137 void applyPropertyToStyle(int id, CSSValue*, RenderStyle*);
140 void setFontSize(FontDescription&, float size);
141 static float getComputedSizeFromSpecifiedSize(Document*, RenderStyle*, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules);
144 Color getColorFromPrimitiveValue(CSSPrimitiveValue*);
146 bool hasSelectorForAttribute(const AtomicString&);
148 CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
150 // Checks if a compound selector (which can consist of multiple simple selectors) matches the current element.
151 bool checkSelector(CSSSelector*);
153 void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
155 bool affectedByViewportChange() const;
157 void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
158 void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
160 void addVariables(CSSVariablesRule* variables);
161 CSSValue* resolveVariableDependentValue(CSSVariableDependentValue*);
162 void resolveVariablesForDeclaration(CSSMutableStyleDeclaration* decl, CSSMutableStyleDeclaration* newDecl, HashSet<String>& usedBlockVariables);
164 void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule);
165 void addPageStyle(PassRefPtr<CSSPageRule>);
167 static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
170 enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsCompletely };
172 // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
173 void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle);
174 void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle);
175 void checkForTextSizeAdjust();
177 void adjustRenderStyle(RenderStyle*, Element*);
179 void addMatchedRule(CSSRuleData* rule) { m_matchedRules.append(rule); }
180 void addMatchedDeclaration(CSSMutableStyleDeclaration* decl);
182 void matchRules(CSSRuleSet*, int& firstRuleIndex, int& lastRuleIndex);
183 void matchRulesForList(CSSRuleDataList*, int& firstRuleIndex, int& lastRuleIndex);
184 void sortMatchedRules(unsigned start, unsigned end);
186 template <bool firstPass>
187 void applyDeclarations(bool important, int startIndex, int endIndex);
189 void matchPageRules(CSSRuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
190 void matchPageRulesForList(CSSRuleDataList*, bool isLeftPage, bool isFirstPage, const String& pageName);
191 bool isLeftPage(int pageIndex) const;
192 bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
193 bool isFirstPage(int pageIndex) const;
194 String pageName(int pageIndex) const;
196 CSSRuleSet* m_authorStyle;
197 CSSRuleSet* m_userStyle;
199 bool m_hasUAAppearance;
200 BorderData m_borderData;
201 FillLayer m_backgroundData;
202 Color m_backgroundColor;
204 typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap;
205 KeyframesRuleMap m_keyframesRuleMap;
208 static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
210 class SelectorChecker : public Noncopyable {
212 SelectorChecker(Document*, bool strictParsing);
214 bool checkSelector(CSSSelector*, Element*) const;
215 SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
216 bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const;
217 bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
219 EInsideLink determineLinkState(Element* element) const;
220 EInsideLink determineLinkStateSlowCase(Element* element) const;
221 void allVisitedStateChanged();
222 void visitedStateChanged(LinkHash visitedHash);
224 Document* m_document;
225 bool m_strictParsing;
226 bool m_collectRulesOnly;
227 PseudoId m_pseudoStyle;
228 bool m_documentIsHTML;
229 mutable bool m_matchVisitedPseudoClass;
230 mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
234 static RenderStyle* s_styleNotYetAvailable;
238 void matchUARules(int& firstUARule, int& lastUARule);
240 void cacheBorderAndBackground();
242 void mapFillAttachment(FillLayer*, CSSValue*);
243 void mapFillClip(FillLayer*, CSSValue*);
244 void mapFillComposite(FillLayer*, CSSValue*);
245 void mapFillOrigin(FillLayer*, CSSValue*);
246 void mapFillImage(FillLayer*, CSSValue*);
247 void mapFillRepeatX(FillLayer*, CSSValue*);
248 void mapFillRepeatY(FillLayer*, CSSValue*);
249 void mapFillSize(FillLayer*, CSSValue*);
250 void mapFillXPosition(FillLayer*, CSSValue*);
251 void mapFillYPosition(FillLayer*, CSSValue*);
253 void mapAnimationDelay(Animation*, CSSValue*);
254 void mapAnimationDirection(Animation*, CSSValue*);
255 void mapAnimationDuration(Animation*, CSSValue*);
256 void mapAnimationFillMode(Animation*, CSSValue*);
257 void mapAnimationIterationCount(Animation*, CSSValue*);
258 void mapAnimationName(Animation*, CSSValue*);
259 void mapAnimationPlayState(Animation*, CSSValue*);
260 void mapAnimationProperty(Animation*, CSSValue*);
261 void mapAnimationTimingFunction(Animation*, CSSValue*);
263 void mapNinePieceImage(CSSValue*, NinePieceImage&);
265 void applyProperty(int id, CSSValue*);
266 void applyPageSizeProperty(CSSValue*);
267 bool pageSizeFromName(CSSPrimitiveValue*, CSSPrimitiveValue*, Length& width, Length& height);
268 Length mmLength(double mm);
269 Length inchLength(double inch);
271 void applySVGProperty(int id, CSSValue*);
274 StyleImage* styleImage(CSSValue* value);
276 // We collect the set of decls that match in |m_matchedDecls|. We then walk the
277 // set of matched decls four times, once for those properties that others depend on (like font-size),
278 // and then a second time for all the remaining properties. We then do the same two passes
279 // for any !important rules.
280 Vector<CSSMutableStyleDeclaration*, 64> m_matchedDecls;
282 // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
284 Vector<CSSRuleData*, 32> m_matchedRules;
286 RefPtr<CSSRuleList> m_ruleList;
288 MediaQueryEvaluator* m_medium;
289 RefPtr<RenderStyle> m_rootDefaultStyle;
291 PseudoId m_dynamicPseudo;
293 SelectorChecker m_checker;
295 RefPtr<RenderStyle> m_style;
296 RenderStyle* m_parentStyle;
297 RenderStyle* m_rootElementStyle;
299 StyledElement* m_styledElement;
300 EInsideLink m_elementLinkState;
302 CSSValue* m_lineHeightValue;
304 bool m_matchAuthorAndUserStyles;
306 RefPtr<CSSFontSelector> m_fontSelector;
307 HashSet<AtomicStringImpl*> m_selectorAttrs;
308 Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
309 Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
311 HashMap<String, CSSVariablesRule*> m_variablesMap;
312 HashMap<CSSMutableStyleDeclaration*, RefPtr<CSSMutableStyleDeclaration> > m_resolvedVariablesDeclarations;
315 class CSSRuleData : public Noncopyable {
317 CSSRuleData(unsigned pos, CSSStyleRule* r, CSSSelector* sel, CSSRuleData* prev = 0)
331 unsigned position() { return m_position; }
332 CSSStyleRule* rule() { return m_rule; }
333 CSSSelector* selector() { return m_selector; }
334 CSSRuleData* next() { return m_next; }
338 CSSStyleRule* m_rule;
339 CSSSelector* m_selector;
343 class CSSRuleDataList : public Noncopyable {
345 CSSRuleDataList(unsigned pos, CSSStyleRule* rule, CSSSelector* sel)
346 : m_first(new CSSRuleData(pos, rule, sel))
363 CSSRuleData* first() { return m_first; }
364 CSSRuleData* last() { return m_last; }
366 void append(unsigned pos, CSSStyleRule* rule, CSSSelector* sel) { m_last = new CSSRuleData(pos, rule, sel, m_last); }
369 CSSRuleData* m_first;
373 } // namespace WebCore
375 #endif // CSSStyleSelector_h