Move WebCore into Source
[WebKit.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 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 "CSSRule.h"
27 #include "LinkHash.h"
28 #include "MediaQueryExp.h"
29 #include "RenderStyle.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 class CSSMutableStyleDeclaration;
39 class CSSPageRule;
40 class CSSPrimitiveValue;
41 class CSSProperty;
42 class CSSFontFace;
43 class CSSFontFaceRule;
44 class CSSImageValue;
45 class CSSRuleData;
46 class CSSRuleDataList;
47 class CSSRuleList;
48 class CSSRuleSet;
49 class CSSSelector;
50 class CSSStyleRule;
51 class CSSStyleSheet;
52 class CSSValue;
53 class ContainerNode;
54 class DataGridColumn;
55 class Document;
56 class Element;
57 class Frame;
58 class FrameView;
59 class KURL;
60 class KeyframeList;
61 class KeyframeValue;
62 class MediaQueryEvaluator;
63 class Node;
64 class Settings;
65 class StyleImage;
66 class StyleSheet;
67 class StyleSheetList;
68 class StyledElement;
69 class WebKitCSSKeyframeRule;
70 class WebKitCSSKeyframesRule;
71
72 class MediaQueryResult : public Noncopyable {
73 public:
74     MediaQueryResult(const MediaQueryExp& expr, bool result)
75         : m_expression(expr)
76         , m_result(result)
77     {
78     }
79
80     MediaQueryExp m_expression;
81     bool m_result;
82 };
83
84     // This class selects a RenderStyle for a given element based on a collection of stylesheets.
85     class CSSStyleSelector : public Noncopyable {
86     public:
87         CSSStyleSelector(Document*, StyleSheetList* authorSheets, CSSStyleSheet* mappedElementSheet,
88                          CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
89                          bool strictParsing, bool matchAuthorAndUserStyles);
90         ~CSSStyleSelector();
91
92         PassRefPtr<RenderStyle> styleForElement(Element* e, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false, bool matchVisitedPseudoClass = false);
93         
94         void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList& list);
95
96         PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle = 0, bool matchVisitedPseudoClass = false);
97
98         PassRefPtr<RenderStyle> styleForPage(int pageIndex);
99
100         static PassRefPtr<RenderStyle> styleForDocument(Document*);
101
102 #if ENABLE(DATAGRID)
103         // Datagrid style computation (uses unique pseudo elements and structures)
104         PassRefPtr<RenderStyle> pseudoStyleForDataGridColumn(DataGridColumn*, RenderStyle* parentStyle);
105         PassRefPtr<RenderStyle> pseudoStyleForDataGridColumnHeader(DataGridColumn*, RenderStyle* parentStyle);
106 #endif
107
108     private:
109         void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
110         void initElement(Element*);
111         ALWAYS_INLINE RenderStyle* locateSharedStyle() const;
112         Node* locateCousinList(Element* parent, unsigned depth = 1) const;
113         bool canShareStyleWithElement(Node*) const;
114
115         RenderStyle* style() const { return m_style.get(); }
116
117         PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const WebKitCSSKeyframeRule*, KeyframeValue&);
118
119     public:
120         // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
121         PassRefPtr<CSSRuleList> styleRulesForElement(Element*, bool authorOnly, bool includeEmptyRules = false, CSSRuleFilter filter = AllCSSRules);
122         PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, bool authorOnly, bool includeEmptyRules = false, CSSRuleFilter filter = AllCSSRules);
123
124         // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
125         // the correct font size scaled relative to the user's default (medium).
126         static float fontSizeForKeyword(Document*, int keyword, bool shouldUseFixedDefaultSize);
127
128         // Given a font size in pixel, this function will return legacy font size between 1 and 7.
129         static int legacyFontSize(Document*, int pixelFontSize, bool shouldUseFixedDefaultSize);
130
131     private:
132
133         // When the CSS keyword "larger" is used, this function will attempt to match within the keyword
134         // table, and failing that, will simply multiply by 1.2.
135         float largerFontSize(float size, bool quirksMode) const;
136
137         // Like the previous function, but for the keyword "smaller".
138         float smallerFontSize(float size, bool quirksMode) const;
139
140     public:
141         void setStyle(PassRefPtr<RenderStyle> s) { m_style = s; } // Used by the document when setting up its root style.
142
143         void applyPropertyToStyle(int id, CSSValue*, RenderStyle*);
144
145     private:
146         void setFontSize(FontDescription&, float size);
147         static float getComputedSizeFromSpecifiedSize(Document*, RenderStyle*, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules);
148
149     public:
150         Color getColorFromPrimitiveValue(CSSPrimitiveValue*) const;
151
152         bool hasSelectorForAttribute(const AtomicString&) const;
153  
154         CSSFontSelector* fontSelector() const { return m_fontSelector.get(); }
155
156         // Checks if a compound selector (which can consist of multiple simple selectors) matches the current element.
157         bool checkSelector(CSSSelector*);
158
159         void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
160
161         bool affectedByViewportChange() const;
162
163         void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
164         void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
165
166         void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule);
167         void addPageStyle(PassRefPtr<CSSPageRule>);
168
169         static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
170
171     private:
172         enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsCompletely };
173
174         // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
175         void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle);
176         void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle);
177         void checkForTextSizeAdjust();
178
179         void adjustRenderStyle(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element*);
180
181         void addMatchedRule(CSSRuleData* rule) { m_matchedRules.append(rule); }
182         void addMatchedDeclaration(CSSMutableStyleDeclaration* decl);
183
184         void matchRules(CSSRuleSet*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
185         void matchRulesForList(CSSRuleDataList*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
186         void sortMatchedRules(unsigned start, unsigned end);
187
188         template <bool firstPass>
189         void applyDeclarations(bool important, int startIndex, int endIndex);
190
191         void matchPageRules(CSSRuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
192         void matchPageRulesForList(CSSRuleDataList*, bool isLeftPage, bool isFirstPage, const String& pageName);
193         bool isLeftPage(int pageIndex) const;
194         bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
195         bool isFirstPage(int pageIndex) const;
196         String pageName(int pageIndex) const;
197         
198         OwnPtr<CSSRuleSet> m_authorStyle;
199         OwnPtr<CSSRuleSet> m_userStyle;
200
201         bool m_hasUAAppearance;
202         BorderData m_borderData;
203         FillLayer m_backgroundData;
204         Color m_backgroundColor;
205
206         typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap;
207         KeyframesRuleMap m_keyframesRuleMap;
208
209     public:
210         static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
211
212         class SelectorChecker : public Noncopyable {
213         public:
214             SelectorChecker(Document*, bool strictParsing);
215
216             bool checkSelector(CSSSelector*, Element*) const;
217             SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
218             bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const;
219             bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
220
221             EInsideLink determineLinkState(Element* element) const;
222             EInsideLink determineLinkStateSlowCase(Element* element) const;
223             void allVisitedStateChanged();
224             void visitedStateChanged(LinkHash visitedHash);
225
226             Document* m_document;
227             bool m_strictParsing;
228             bool m_collectRulesOnly;
229             bool m_sameOriginOnly;
230             PseudoId m_pseudoStyle;
231             bool m_documentIsHTML;
232             mutable bool m_matchVisitedPseudoClass;
233             mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
234         };
235
236     private:
237         static RenderStyle* s_styleNotYetAvailable;
238
239         void matchUARules(int& firstUARule, int& lastUARule);
240         void updateFont();
241         void cacheBorderAndBackground();
242
243         void mapFillAttachment(CSSPropertyID, FillLayer*, CSSValue*);
244         void mapFillClip(CSSPropertyID, FillLayer*, CSSValue*);
245         void mapFillComposite(CSSPropertyID, FillLayer*, CSSValue*);
246         void mapFillOrigin(CSSPropertyID, FillLayer*, CSSValue*);
247         void mapFillImage(CSSPropertyID, FillLayer*, CSSValue*);
248         void mapFillRepeatX(CSSPropertyID, FillLayer*, CSSValue*);
249         void mapFillRepeatY(CSSPropertyID, FillLayer*, CSSValue*);
250         void mapFillSize(CSSPropertyID, FillLayer*, CSSValue*);
251         void mapFillXPosition(CSSPropertyID, FillLayer*, CSSValue*);
252         void mapFillYPosition(CSSPropertyID, FillLayer*, CSSValue*);
253
254         void mapAnimationDelay(Animation*, CSSValue*);
255         void mapAnimationDirection(Animation*, CSSValue*);
256         void mapAnimationDuration(Animation*, CSSValue*);
257         void mapAnimationFillMode(Animation*, CSSValue*);
258         void mapAnimationIterationCount(Animation*, CSSValue*);
259         void mapAnimationName(Animation*, CSSValue*);
260         void mapAnimationPlayState(Animation*, CSSValue*);
261         void mapAnimationProperty(Animation*, CSSValue*);
262         void mapAnimationTimingFunction(Animation*, CSSValue*);
263
264         void mapNinePieceImage(CSSPropertyID, CSSValue*, NinePieceImage&);
265
266         void applyProperty(int id, CSSValue*);
267         void applyPageSizeProperty(CSSValue*);
268         bool pageSizeFromName(CSSPrimitiveValue*, CSSPrimitiveValue*, Length& width, Length& height);
269         Length mmLength(double mm) const;
270         Length inchLength(double inch) const;
271 #if ENABLE(SVG)
272         void applySVGProperty(int id, CSSValue*);
273 #endif
274
275         void loadPendingImages();
276         
277         StyleImage* styleImage(CSSPropertyID, CSSValue* value);
278         StyleImage* cachedOrPendingFromValue(CSSPropertyID property, CSSImageValue* value);
279
280         // We collect the set of decls that match in |m_matchedDecls|.  We then walk the
281         // set of matched decls four times, once for those properties that others depend on (like font-size),
282         // and then a second time for all the remaining properties.  We then do the same two passes
283         // for any !important rules.
284         Vector<CSSMutableStyleDeclaration*, 64> m_matchedDecls;
285
286         // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
287         // merge sorting.
288         Vector<CSSRuleData*, 32> m_matchedRules;
289
290         RefPtr<CSSRuleList> m_ruleList;
291         
292         HashSet<int> m_pendingImageProperties; // Hash of CSSPropertyIDs
293
294         OwnPtr<MediaQueryEvaluator> m_medium;
295         RefPtr<RenderStyle> m_rootDefaultStyle;
296
297         PseudoId m_dynamicPseudo;
298
299         SelectorChecker m_checker;
300
301         RefPtr<RenderStyle> m_style;
302         RenderStyle* m_parentStyle;
303         RenderStyle* m_rootElementStyle;
304         Element* m_element;
305         StyledElement* m_styledElement;
306         EInsideLink m_elementLinkState;
307         ContainerNode* m_parentNode;
308         CSSValue* m_lineHeightValue;
309         bool m_fontDirty;
310         bool m_matchAuthorAndUserStyles;
311         
312         RefPtr<CSSFontSelector> m_fontSelector;
313         HashSet<AtomicStringImpl*> m_selectorAttrs;
314         Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
315         Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
316     };
317
318 } // namespace WebCore
319
320 #endif // CSSStyleSelector_h