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.
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"
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>
38 class CSSMutableStyleDeclaration;
40 class CSSPrimitiveValue;
43 class CSSFontFaceRule;
46 class CSSRuleDataList;
62 class MediaQueryEvaluator;
69 class WebKitCSSKeyframeRule;
70 class WebKitCSSKeyframesRule;
72 class MediaQueryResult {
73 WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
75 MediaQueryResult(const MediaQueryExp& expr, bool result)
81 MediaQueryExp m_expression;
85 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
86 class CSSStyleSelector {
87 WTF_MAKE_NONCOPYABLE(CSSStyleSelector); WTF_MAKE_FAST_ALLOCATED;
89 CSSStyleSelector(Document*, StyleSheetList* authorSheets, CSSStyleSheet* mappedElementSheet,
90 CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
91 bool strictParsing, bool matchAuthorAndUserStyles);
94 PassRefPtr<RenderStyle> styleForElement(Element* e, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false, bool matchVisitedPseudoClass = false);
96 void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList& list);
98 PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle = 0, bool matchVisitedPseudoClass = false);
100 PassRefPtr<RenderStyle> styleForPage(int pageIndex);
102 static PassRefPtr<RenderStyle> styleForDocument(Document*);
105 // Datagrid style computation (uses unique pseudo elements and structures)
106 PassRefPtr<RenderStyle> pseudoStyleForDataGridColumn(DataGridColumn*, RenderStyle* parentStyle);
107 PassRefPtr<RenderStyle> pseudoStyleForDataGridColumnHeader(DataGridColumn*, RenderStyle* parentStyle);
111 void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
112 void initElement(Element*);
113 RenderStyle* locateSharedStyle();
114 bool matchesSiblingRules();
115 Node* locateCousinList(Element* parent, unsigned depth = 1) const;
116 Node* findSiblingForStyleSharing(Node*, unsigned& count) const;
117 bool canShareStyleWithElement(Node*) const;
119 RenderStyle* style() const { return m_style.get(); }
121 PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const WebKitCSSKeyframeRule*, KeyframeValue&);
124 // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
125 PassRefPtr<CSSRuleList> styleRulesForElement(Element*, bool authorOnly, bool includeEmptyRules = false, CSSRuleFilter filter = AllCSSRules);
126 PassRefPtr<CSSRuleList> pseudoStyleRulesForElement(Element*, PseudoId, bool authorOnly, bool includeEmptyRules = false, CSSRuleFilter filter = AllCSSRules);
128 // Given a CSS keyword in the range (xx-small to -webkit-xxx-large), this function will return
129 // the correct font size scaled relative to the user's default (medium).
130 static float fontSizeForKeyword(Document*, int keyword, bool shouldUseFixedDefaultSize);
132 // Given a font size in pixel, this function will return legacy font size between 1 and 7.
133 static int legacyFontSize(Document*, int pixelFontSize, bool shouldUseFixedDefaultSize);
137 // When the CSS keyword "larger" is used, this function will attempt to match within the keyword
138 // table, and failing that, will simply multiply by 1.2.
139 float largerFontSize(float size, bool quirksMode) const;
141 // Like the previous function, but for the keyword "smaller".
142 float smallerFontSize(float size, bool quirksMode) const;
145 void setStyle(PassRefPtr<RenderStyle> s) { m_style = s; } // Used by the document when setting up its root style.
147 void applyPropertyToStyle(int id, CSSValue*, RenderStyle*);
150 void setFontSize(FontDescription&, float size);
151 static float getComputedSizeFromSpecifiedSize(Document*, RenderStyle*, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules);
154 Color getColorFromPrimitiveValue(CSSPrimitiveValue*) const;
156 bool hasSelectorForAttribute(const AtomicString&) const;
158 CSSFontSelector* fontSelector() const { return m_fontSelector.get(); }
160 // Checks if a compound selector (which can consist of multiple simple selectors) matches the current element.
161 bool checkSelector(CSSSelector*);
163 void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
165 bool affectedByViewportChange() const;
167 void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); }
168 void visitedStateChanged(LinkHash visitedHash) { m_checker.visitedStateChanged(visitedHash); }
170 void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule);
171 void addPageStyle(PassRefPtr<CSSPageRule>);
173 static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, RenderStyle* rootStyle, TransformOperations& outOperations);
176 enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsCompletely };
178 // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
179 void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle);
180 void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle);
181 void checkForTextSizeAdjust();
183 void adjustRenderStyle(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element*);
185 void addMatchedRule(CSSRuleData* rule) { m_matchedRules.append(rule); }
186 void addMatchedDeclaration(CSSMutableStyleDeclaration* decl);
188 void matchRules(CSSRuleSet*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
189 void matchRulesForList(CSSRuleDataList*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);
190 void sortMatchedRules(unsigned start, unsigned end);
192 template <bool firstPass>
193 void applyDeclarations(bool important, int startIndex, int endIndex);
195 void matchPageRules(CSSRuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
196 void matchPageRulesForList(CSSRuleDataList*, bool isLeftPage, bool isFirstPage, const String& pageName);
197 bool isLeftPage(int pageIndex) const;
198 bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
199 bool isFirstPage(int pageIndex) const;
200 String pageName(int pageIndex) const;
202 OwnPtr<CSSRuleSet> m_authorStyle;
203 OwnPtr<CSSRuleSet> m_userStyle;
205 OwnPtr<CSSRuleSet> m_siblingRules;
206 HashSet<AtomicStringImpl*> m_idsInRules;
208 bool m_hasUAAppearance;
209 BorderData m_borderData;
210 FillLayer m_backgroundData;
211 Color m_backgroundColor;
213 typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap;
214 KeyframesRuleMap m_keyframesRuleMap;
217 static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
219 class SelectorChecker {
220 WTF_MAKE_NONCOPYABLE(SelectorChecker);
222 SelectorChecker(Document*, bool strictParsing);
224 bool checkSelector(CSSSelector*, Element*) const;
225 SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
226 bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const;
227 bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
229 EInsideLink determineLinkState(Element* element) const;
230 EInsideLink determineLinkStateSlowCase(Element* element) const;
231 void allVisitedStateChanged();
232 void visitedStateChanged(LinkHash visitedHash);
234 Document* m_document;
235 bool m_strictParsing;
236 bool m_collectRulesOnly;
237 bool m_sameOriginOnly;
238 PseudoId m_pseudoStyle;
239 bool m_documentIsHTML;
240 mutable bool m_matchVisitedPseudoClass;
241 mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
245 static RenderStyle* s_styleNotYetAvailable;
247 void matchUARules(int& firstUARule, int& lastUARule);
249 void cacheBorderAndBackground();
251 void mapFillAttachment(CSSPropertyID, FillLayer*, CSSValue*);
252 void mapFillClip(CSSPropertyID, FillLayer*, CSSValue*);
253 void mapFillComposite(CSSPropertyID, FillLayer*, CSSValue*);
254 void mapFillOrigin(CSSPropertyID, FillLayer*, CSSValue*);
255 void mapFillImage(CSSPropertyID, FillLayer*, CSSValue*);
256 void mapFillRepeatX(CSSPropertyID, FillLayer*, CSSValue*);
257 void mapFillRepeatY(CSSPropertyID, FillLayer*, CSSValue*);
258 void mapFillSize(CSSPropertyID, FillLayer*, CSSValue*);
259 void mapFillXPosition(CSSPropertyID, FillLayer*, CSSValue*);
260 void mapFillYPosition(CSSPropertyID, FillLayer*, CSSValue*);
262 void mapAnimationDelay(Animation*, CSSValue*);
263 void mapAnimationDirection(Animation*, CSSValue*);
264 void mapAnimationDuration(Animation*, CSSValue*);
265 void mapAnimationFillMode(Animation*, CSSValue*);
266 void mapAnimationIterationCount(Animation*, CSSValue*);
267 void mapAnimationName(Animation*, CSSValue*);
268 void mapAnimationPlayState(Animation*, CSSValue*);
269 void mapAnimationProperty(Animation*, CSSValue*);
270 void mapAnimationTimingFunction(Animation*, CSSValue*);
272 void mapNinePieceImage(CSSPropertyID, CSSValue*, NinePieceImage&);
274 void applyProperty(int id, CSSValue*);
275 void applyPageSizeProperty(CSSValue*);
276 bool pageSizeFromName(CSSPrimitiveValue*, CSSPrimitiveValue*, Length& width, Length& height);
277 Length mmLength(double mm) const;
278 Length inchLength(double inch) const;
280 void applySVGProperty(int id, CSSValue*);
283 void loadPendingImages();
285 StyleImage* styleImage(CSSPropertyID, CSSValue* value);
286 StyleImage* cachedOrPendingFromValue(CSSPropertyID property, CSSImageValue* value);
288 // We collect the set of decls that match in |m_matchedDecls|. We then walk the
289 // set of matched decls four times, once for those properties that others depend on (like font-size),
290 // and then a second time for all the remaining properties. We then do the same two passes
291 // for any !important rules.
292 Vector<CSSMutableStyleDeclaration*, 64> m_matchedDecls;
294 // A buffer used to hold the set of matched rules for an element, and a temporary buffer used for
296 Vector<CSSRuleData*, 32> m_matchedRules;
298 RefPtr<CSSRuleList> m_ruleList;
300 HashSet<int> m_pendingImageProperties; // Hash of CSSPropertyIDs
302 OwnPtr<MediaQueryEvaluator> m_medium;
303 RefPtr<RenderStyle> m_rootDefaultStyle;
305 PseudoId m_dynamicPseudo;
307 SelectorChecker m_checker;
309 RefPtr<RenderStyle> m_style;
310 RenderStyle* m_parentStyle;
311 RenderStyle* m_rootElementStyle;
313 StyledElement* m_styledElement;
314 EInsideLink m_elementLinkState;
315 ContainerNode* m_parentNode;
316 CSSValue* m_lineHeightValue;
318 bool m_matchAuthorAndUserStyles;
320 RefPtr<CSSFontSelector> m_fontSelector;
321 HashSet<AtomicStringImpl*> m_selectorAttrs;
322 Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
323 Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
326 } // namespace WebCore
328 #endif // CSSStyleSelector_h