• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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 "CSSFontSelector.h"
26 #include "LinkHash.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>
34 
35 namespace WebCore {
36 
37 class CSSMutableStyleDeclaration;
38 class CSSPrimitiveValue;
39 class CSSProperty;
40 class CSSFontFace;
41 class CSSFontFaceRule;
42 class CSSRuleData;
43 class CSSRuleDataList;
44 class CSSRuleList;
45 class CSSRuleSet;
46 class CSSSelector;
47 class CSSStyleRule;
48 class CSSStyleSheet;
49 class CSSValue;
50 class CSSVariableDependentValue;
51 class CSSVariablesRule;
52 class DataGridColumn;
53 class Document;
54 class Element;
55 class Frame;
56 class FrameView;
57 class KURL;
58 class KeyframeList;
59 class MediaQueryEvaluator;
60 class Node;
61 class Settings;
62 class StyleImage;
63 class StyleSheet;
64 class StyleSheetList;
65 class StyledElement;
66 class WebKitCSSKeyframesRule;
67 
68 class MediaQueryResult : public Noncopyable {
69 public:
MediaQueryResult(const MediaQueryExp & expr,bool result)70     MediaQueryResult(const MediaQueryExp& expr, bool result)
71         : m_expression(expr)
72         , m_result(result)
73     {
74     }
75 
76     MediaQueryExp m_expression;
77     bool m_result;
78 };
79 
80     // This class selects a RenderStyle for a given element based on a collection of stylesheets.
81     class CSSStyleSelector : public Noncopyable {
82     public:
83         CSSStyleSelector(Document*, StyleSheetList* authorSheets, CSSStyleSheet* mappedElementSheet,
84                          CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
85                          bool strictParsing, bool matchAuthorAndUserStyles);
86         ~CSSStyleSelector();
87 
88         void initElementAndPseudoState(Element*);
89         void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
90         PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false);
91         void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList& list);
92 
93         PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId, Element*, RenderStyle* parentStyle = 0);
94 
95         static PassRefPtr<RenderStyle> styleForDocument(Document*);
96 
97 #if ENABLE(DATAGRID)
98         // Datagrid style computation (uses unique pseudo elements and structures)
99         PassRefPtr<RenderStyle> pseudoStyleForDataGridColumn(DataGridColumn*, RenderStyle* parentStyle);
100         PassRefPtr<RenderStyle> pseudoStyleForDataGridColumnHeader(DataGridColumn*, RenderStyle* parentStyle);
101 #endif
102 
103     private:
104         RenderStyle* locateSharedStyle();
105         Node* locateCousinList(Element* parent, unsigned depth = 1);
106         bool canShareStyleWithElement(Node*);
107 
style()108         RenderStyle* style() const { return m_style.get(); }
109 
110     public:
111         // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
112         PassRefPtr<CSSRuleList> styleRulesForElement(Element*, bool authorOnly);
113         PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, const String& pseudoStyle, bool authorOnly);
114 
115         // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
116         // the correct font size scaled relative to the user's default (medium).
117         static float fontSizeForKeyword(Document*, int keyword, bool monospace);
118 
119     private:
120         // When the CSS keyword "larger" is used, this function will attempt to match within the keyword
121         // table, and failing that, will simply multiply by 1.2.
122         float largerFontSize(float size, bool quirksMode) const;
123 
124         // Like the previous function, but for the keyword "smaller".
125         float smallerFontSize(float size, bool quirksMode) const;
126 
127     public:
setStyle(PassRefPtr<RenderStyle> s)128         void setStyle(PassRefPtr<RenderStyle> s) { m_style = s; } // Used by the document when setting up its root style.
129         void setFontSize(FontDescription&, float size);
130 
131         void applyPropertyToStyle(int id, CSSValue*, RenderStyle*);
132 
133     private:
134         static float getComputedSizeFromSpecifiedSize(Document*, bool isAbsoluteSize, float specifiedSize, float zoomFactor = 1.0f);
135 
136     public:
137         Color getColorFromPrimitiveValue(CSSPrimitiveValue*);
138 
139         bool hasSelectorForAttribute(const AtomicString&);
140 
fontSelector()141         CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
142 
143         // Checks if a compound selector (which can consist of multiple simple selectors) matches the current element.
144         bool checkSelector(CSSSelector*);
145 
146         void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
147 
148         bool affectedByViewportChange() const;
149 
allVisitedStateChanged()150         void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
visitedStateChanged(LinkHash visitedHash)151         void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
152 
153         void addVariables(CSSVariablesRule* variables);
154         CSSValue* resolveVariableDependentValue(CSSVariableDependentValue*);
155         void resolveVariablesForDeclaration(CSSMutableStyleDeclaration* decl, CSSMutableStyleDeclaration* newDecl, HashSet<String>& usedBlockVariables);
156 
157         void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule);
158 
159         static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
160 
161     private:
162         enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsCompletely };
163 
164         // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
165         void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle);
166         void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle);
167         void checkForTextSizeAdjust();
168 
169         void adjustRenderStyle(RenderStyle*, Element*);
170 
addMatchedRule(CSSRuleData * rule)171         void addMatchedRule(CSSRuleData* rule) { m_matchedRules.append(rule); }
172         void addMatchedDeclaration(CSSMutableStyleDeclaration* decl);
173 
174         void matchRules(CSSRuleSet*, int& firstRuleIndex, int& lastRuleIndex);
175         void matchRulesForList(CSSRuleDataList*, int& firstRuleIndex, int& lastRuleIndex);
176         void sortMatchedRules(unsigned start, unsigned end);
177 
178         void applyDeclarations(bool firstPass, bool important, int startIndex, int endIndex);
179 
180         CSSRuleSet* m_authorStyle;
181         CSSRuleSet* m_userStyle;
182 
183         bool m_hasUAAppearance;
184         BorderData m_borderData;
185         FillLayer m_backgroundData;
186         Color m_backgroundColor;
187 
188         typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap;
189         KeyframesRuleMap m_keyframesRuleMap;
190 
191     public:
styleNotYetAvailable()192         static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
193 
194         class SelectorChecker : public Noncopyable {
195         public:
196             SelectorChecker(Document*, bool strictParsing);
197 
198             bool checkSelector(CSSSelector*, Element*) const;
199             SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
200             bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const;
201             PseudoState checkPseudoState(Element*, bool checkVisited = true) const;
202             bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
203 
204             void allVisitedStateChanged();
205             void visitedStateChanged(LinkHash visitedHash);
206 
207             Document* m_document;
208             bool m_strictParsing;
209             bool m_collectRulesOnly;
210             PseudoId m_pseudoStyle;
211             bool m_documentIsHTML;
212             mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
213         };
214 
215     private:
216         static RenderStyle* s_styleNotYetAvailable;
217 
218         void init();
219 
220         void matchUARules(int& firstUARule, int& lastUARule);
221         void updateFont();
222         void cacheBorderAndBackground();
223 
224         void mapFillAttachment(FillLayer*, CSSValue*);
225         void mapFillClip(FillLayer*, CSSValue*);
226         void mapFillComposite(FillLayer*, CSSValue*);
227         void mapFillOrigin(FillLayer*, CSSValue*);
228         void mapFillImage(FillLayer*, CSSValue*);
229         void mapFillRepeatX(FillLayer*, CSSValue*);
230         void mapFillRepeatY(FillLayer*, CSSValue*);
231         void mapFillSize(FillLayer*, CSSValue*);
232         void mapFillXPosition(FillLayer*, CSSValue*);
233         void mapFillYPosition(FillLayer*, CSSValue*);
234 
235         void mapAnimationDelay(Animation*, CSSValue*);
236         void mapAnimationDirection(Animation*, CSSValue*);
237         void mapAnimationDuration(Animation*, CSSValue*);
238         void mapAnimationIterationCount(Animation*, CSSValue*);
239         void mapAnimationName(Animation*, CSSValue*);
240         void mapAnimationPlayState(Animation*, CSSValue*);
241         void mapAnimationProperty(Animation*, CSSValue*);
242         void mapAnimationTimingFunction(Animation*, CSSValue*);
243 
244         void mapNinePieceImage(CSSValue*, NinePieceImage&);
245 
246         void applyProperty(int id, CSSValue*);
247 #if ENABLE(SVG)
248         void applySVGProperty(int id, CSSValue*);
249 #endif
250 
251         StyleImage* styleImage(CSSValue* value);
252 
253         // We collect the set of decls that match in |m_matchedDecls|.  We then walk the
254         // set of matched decls four times, once for those properties that others depend on (like font-size),
255         // and then a second time for all the remaining properties.  We then do the same two passes
256         // for any !important rules.
257         Vector<CSSMutableStyleDeclaration*, 64> m_matchedDecls;
258 
259         // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
260         // merge sorting.
261         Vector<CSSRuleData*, 32> m_matchedRules;
262 
263         RefPtr<CSSRuleList> m_ruleList;
264 
265         MediaQueryEvaluator* m_medium;
266         RefPtr<RenderStyle> m_rootDefaultStyle;
267 
268         PseudoId m_dynamicPseudo;
269 
270         SelectorChecker m_checker;
271 
272         RefPtr<RenderStyle> m_style;
273         RenderStyle* m_parentStyle;
274         RenderStyle* m_rootElementStyle;
275         Element* m_element;
276         StyledElement* m_styledElement;
277         Node* m_parentNode;
278         CSSValue* m_lineHeightValue;
279         bool m_fontDirty;
280         bool m_matchAuthorAndUserStyles;
281 
282         RefPtr<CSSFontSelector> m_fontSelector;
283         HashSet<AtomicStringImpl*> m_selectorAttrs;
284         Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
285         Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
286 
287         HashMap<String, CSSVariablesRule*> m_variablesMap;
288         HashMap<CSSMutableStyleDeclaration*, RefPtr<CSSMutableStyleDeclaration> > m_resolvedVariablesDeclarations;
289     };
290 
291     class CSSRuleData : public Noncopyable {
292     public:
293         CSSRuleData(unsigned pos, CSSStyleRule* r, CSSSelector* sel, CSSRuleData* prev = 0)
m_position(pos)294             : m_position(pos)
295             , m_rule(r)
296             , m_selector(sel)
297             , m_next(0)
298         {
299             if (prev)
300                 prev->m_next = this;
301         }
302 
~CSSRuleData()303         ~CSSRuleData()
304         {
305         }
306 
position()307         unsigned position() { return m_position; }
rule()308         CSSStyleRule* rule() { return m_rule; }
selector()309         CSSSelector* selector() { return m_selector; }
next()310         CSSRuleData* next() { return m_next; }
311 
312     private:
313         unsigned m_position;
314         CSSStyleRule* m_rule;
315         CSSSelector* m_selector;
316         CSSRuleData* m_next;
317     };
318 
319     class CSSRuleDataList : public Noncopyable {
320     public:
CSSRuleDataList(unsigned pos,CSSStyleRule * rule,CSSSelector * sel)321         CSSRuleDataList(unsigned pos, CSSStyleRule* rule, CSSSelector* sel)
322             : m_first(new CSSRuleData(pos, rule, sel))
323             , m_last(m_first)
324         {
325         }
326 
~CSSRuleDataList()327         ~CSSRuleDataList()
328         {
329             CSSRuleData* ptr;
330             CSSRuleData* next;
331             ptr = m_first;
332             while (ptr) {
333                 next = ptr->next();
334                 delete ptr;
335                 ptr = next;
336             }
337         }
338 
first()339         CSSRuleData* first() { return m_first; }
last()340         CSSRuleData* last() { return m_last; }
341 
append(unsigned pos,CSSStyleRule * rule,CSSSelector * sel)342         void append(unsigned pos, CSSStyleRule* rule, CSSSelector* sel) { m_last = new CSSRuleData(pos, rule, sel, m_last); }
343 
344     private:
345         CSSRuleData* m_first;
346         CSSRuleData* m_last;
347     };
348 
349 } // namespace WebCore
350 
351 #endif // CSSStyleSelector_h
352