OSDN Git Service

am 3c54ece0: am 5dc34a85: activeDocumentLoader() causes crash in WebCoreFrameBridge.cpp
[android-x86/external-webkit.git] / WebCore / css / CSSStyleSelector.h
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 CSSPageRule;
39 class CSSPrimitiveValue;
40 class CSSProperty;
41 class CSSFontFace;
42 class CSSFontFaceRule;
43 class CSSRuleData;
44 class CSSRuleDataList;
45 class CSSRuleList;
46 class CSSRuleSet;
47 class CSSSelector;
48 class CSSStyleRule;
49 class CSSStyleSheet;
50 class CSSValue;
51 class CSSVariableDependentValue;
52 class CSSVariablesRule;
53 class DataGridColumn;
54 class Document;
55 class Element;
56 class Frame;
57 class FrameView;
58 class KURL;
59 class KeyframeList;
60 class MediaQueryEvaluator;
61 class Node;
62 class Settings;
63 class StyleImage;
64 class StyleSheet;
65 class StyleSheetList;
66 class StyledElement;
67 class WebKitCSSKeyframeRule;
68 class WebKitCSSKeyframesRule;
69
70 class MediaQueryResult : public Noncopyable {
71 public:
72     MediaQueryResult(const MediaQueryExp& expr, bool result)
73         : m_expression(expr)
74         , m_result(result)
75     {
76     }
77
78     MediaQueryExp m_expression;
79     bool m_result;
80 };
81
82     // This class selects a RenderStyle for a given element based on a collection of stylesheets.
83     class CSSStyleSelector : public Noncopyable {
84     public:
85         CSSStyleSelector(Document*, StyleSheetList* authorSheets, CSSStyleSheet* mappedElementSheet,
86                          CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
87                          bool strictParsing, bool matchAuthorAndUserStyles);
88         ~CSSStyleSelector();
89
90         PassRefPtr<RenderStyle> styleForElement(Element* e, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false, bool matchVisitedPseudoClass = false);
91         
92         void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList& list);
93
94         PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle = 0, bool matchVisitedPseudoClass = false);
95
96         PassRefPtr<RenderStyle> styleForPage(int pageIndex);
97
98         static PassRefPtr<RenderStyle> styleForDocument(Document*);
99
100 #if ENABLE(DATAGRID)
101         // Datagrid style computation (uses unique pseudo elements and structures)
102         PassRefPtr<RenderStyle> pseudoStyleForDataGridColumn(DataGridColumn*, RenderStyle* parentStyle);
103         PassRefPtr<RenderStyle> pseudoStyleForDataGridColumnHeader(DataGridColumn*, RenderStyle* parentStyle);
104 #endif
105
106     private:
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*);
112
113         RenderStyle* style() const { return m_style.get(); }
114
115         PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const WebKitCSSKeyframeRule*, KeyframeList&);
116
117     public:
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);
121
122     private:
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);
126
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;
130
131         // Like the previous function, but for the keyword "smaller".
132         float smallerFontSize(float size, bool quirksMode) const;
133
134     public:
135         void setStyle(PassRefPtr<RenderStyle> s) { m_style = s; } // Used by the document when setting up its root style.
136
137         void applyPropertyToStyle(int id, CSSValue*, RenderStyle*);
138
139     private:
140         void setFontSize(FontDescription&, float size);
141         static float getComputedSizeFromSpecifiedSize(Document*, RenderStyle*, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules);
142
143     public:
144         Color getColorFromPrimitiveValue(CSSPrimitiveValue*);
145
146         bool hasSelectorForAttribute(const AtomicString&);
147  
148         CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
149
150         // Checks if a compound selector (which can consist of multiple simple selectors) matches the current element.
151         bool checkSelector(CSSSelector*);
152
153         void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
154
155         bool affectedByViewportChange() const;
156
157         void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
158         void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
159
160         void addVariables(CSSVariablesRule* variables);
161         CSSValue* resolveVariableDependentValue(CSSVariableDependentValue*);
162         void resolveVariablesForDeclaration(CSSMutableStyleDeclaration* decl, CSSMutableStyleDeclaration* newDecl, HashSet<String>& usedBlockVariables);
163
164         void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule);
165         void addPageStyle(PassRefPtr<CSSPageRule>);
166
167         static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
168
169     private:
170         enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsCompletely };
171
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();
176
177         void adjustRenderStyle(RenderStyle*, Element*);
178
179         void addMatchedRule(CSSRuleData* rule) { m_matchedRules.append(rule); }
180         void addMatchedDeclaration(CSSMutableStyleDeclaration* decl);
181
182         void matchRules(CSSRuleSet*, int& firstRuleIndex, int& lastRuleIndex);
183         void matchRulesForList(CSSRuleDataList*, int& firstRuleIndex, int& lastRuleIndex);
184         void sortMatchedRules(unsigned start, unsigned end);
185
186         template <bool firstPass>
187         void applyDeclarations(bool important, int startIndex, int endIndex);
188
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;
195         
196         CSSRuleSet* m_authorStyle;
197         CSSRuleSet* m_userStyle;
198
199         bool m_hasUAAppearance;
200         BorderData m_borderData;
201         FillLayer m_backgroundData;
202         Color m_backgroundColor;
203
204         typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap;
205         KeyframesRuleMap m_keyframesRuleMap;
206
207     public:
208         static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
209
210         class SelectorChecker : public Noncopyable {
211         public:
212             SelectorChecker(Document*, bool strictParsing);
213
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;
218
219             EInsideLink determineLinkState(Element* element) const;
220             EInsideLink determineLinkStateSlowCase(Element* element) const;
221             void allVisitedStateChanged();
222             void visitedStateChanged(LinkHash visitedHash);
223
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;
231         };
232
233     private:
234         static RenderStyle* s_styleNotYetAvailable;
235
236         void init();
237
238         void matchUARules(int& firstUARule, int& lastUARule);
239         void updateFont();
240         void cacheBorderAndBackground();
241
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*);
252
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*);
262
263         void mapNinePieceImage(CSSValue*, NinePieceImage&);
264
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);
270 #if ENABLE(SVG)
271         void applySVGProperty(int id, CSSValue*);
272 #endif
273
274         StyleImage* styleImage(CSSValue* value);
275
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;
281
282         // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
283         // merge sorting.
284         Vector<CSSRuleData*, 32> m_matchedRules;
285
286         RefPtr<CSSRuleList> m_ruleList;
287
288         MediaQueryEvaluator* m_medium;
289         RefPtr<RenderStyle> m_rootDefaultStyle;
290
291         PseudoId m_dynamicPseudo;
292
293         SelectorChecker m_checker;
294
295         RefPtr<RenderStyle> m_style;
296         RenderStyle* m_parentStyle;
297         RenderStyle* m_rootElementStyle;
298         Element* m_element;
299         StyledElement* m_styledElement;
300         EInsideLink m_elementLinkState;
301         Node* m_parentNode;
302         CSSValue* m_lineHeightValue;
303         bool m_fontDirty;
304         bool m_matchAuthorAndUserStyles;
305         
306         RefPtr<CSSFontSelector> m_fontSelector;
307         HashSet<AtomicStringImpl*> m_selectorAttrs;
308         Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
309         Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
310         
311         HashMap<String, CSSVariablesRule*> m_variablesMap;
312         HashMap<CSSMutableStyleDeclaration*, RefPtr<CSSMutableStyleDeclaration> > m_resolvedVariablesDeclarations;
313     };
314
315     class CSSRuleData : public Noncopyable {
316     public:
317         CSSRuleData(unsigned pos, CSSStyleRule* r, CSSSelector* sel, CSSRuleData* prev = 0)
318             : m_position(pos)
319             , m_rule(r)
320             , m_selector(sel)
321             , m_next(0)
322         {
323             if (prev)
324                 prev->m_next = this;
325         }
326
327         ~CSSRuleData() 
328         { 
329         }
330
331         unsigned position() { return m_position; }
332         CSSStyleRule* rule() { return m_rule; }
333         CSSSelector* selector() { return m_selector; }
334         CSSRuleData* next() { return m_next; }
335
336     private:
337         unsigned m_position;
338         CSSStyleRule* m_rule;
339         CSSSelector* m_selector;
340         CSSRuleData* m_next;
341     };
342
343     class CSSRuleDataList : public Noncopyable {
344     public:
345         CSSRuleDataList(unsigned pos, CSSStyleRule* rule, CSSSelector* sel)
346             : m_first(new CSSRuleData(pos, rule, sel))
347             , m_last(m_first)
348         {
349         }
350
351         ~CSSRuleDataList() 
352         { 
353             CSSRuleData* ptr;
354             CSSRuleData* next;
355             ptr = m_first;
356             while (ptr) {
357                 next = ptr->next();
358                 delete ptr;
359                 ptr = next;
360             }
361         }
362
363         CSSRuleData* first() { return m_first; }
364         CSSRuleData* last() { return m_last; }
365
366         void append(unsigned pos, CSSStyleRule* rule, CSSSelector* sel) { m_last = new CSSRuleData(pos, rule, sel, m_last); }
367
368     private:
369         CSSRuleData* m_first;
370         CSSRuleData* m_last;
371     };
372
373 } // namespace WebCore
374
375 #endif // CSSStyleSelector_h