1 /*
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
4 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
5 * Copyright (C) 2009 - 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifndef BisonCSSParser_h
24 #define BisonCSSParser_h
25
26 #include "core/CSSPropertyNames.h"
27 #include "core/CSSValueKeywords.h"
28 #include "core/css/CSSCalculationValue.h"
29 #include "core/css/CSSFilterValue.h"
30 #include "core/css/CSSGradientValue.h"
31 #include "core/css/CSSParserMode.h"
32 #include "core/css/CSSParserValues.h"
33 #include "core/css/CSSProperty.h"
34 #include "core/css/CSSPropertySourceData.h"
35 #include "core/css/CSSSelector.h"
36 #include "core/css/CSSTokenizer.h"
37 #include "core/css/MediaQuery.h"
38 #include "core/css/StylePropertySet.h"
39 #include "core/css/parser/CSSParserObserver.h"
40 #include "core/css/parser/CSSPropertyParser.h"
41 #include "platform/graphics/Color.h"
42 #include "wtf/HashSet.h"
43 #include "wtf/OwnPtr.h"
44 #include "wtf/Vector.h"
45 #include "wtf/text/AtomicString.h"
46 #include "wtf/text/TextPosition.h"
47
48 namespace WebCore {
49
50 class AnimationParseContext;
51 class CSSArrayFunctionValue;
52 class CSSBorderImageSliceValue;
53 class CSSPrimitiveValue;
54 class CSSSelectorList;
55 class CSSValue;
56 class CSSValueList;
57 class CSSBasicShape;
58 class CSSBasicShapeInset;
59 class Document;
60 class Element;
61 class ImmutableStylePropertySet;
62 class MediaQueryExp;
63 class MediaQuerySet;
64 class MutableStylePropertySet;
65 class StyleKeyframe;
66 class StylePropertyShorthand;
67 class StyleRuleBase;
68 class StyleRuleKeyframes;
69 class StyleKeyframe;
70 class StyleSheetContents;
71 class UseCounter;
72
73 // FIXME: This class is shared with CSSTokenizer so should we rename it to CSSSourceLocation?
74 struct CSSParserLocation {
75 unsigned offset;
76 unsigned lineNumber;
77 CSSParserString token;
78 };
79
80 class BisonCSSParser {
81 STACK_ALLOCATED();
82 friend inline int cssyylex(void*, BisonCSSParser*);
83 public:
84 explicit BisonCSSParser(const CSSParserContext&);
85 ~BisonCSSParser();
86
87 void rollbackLastProperties(int num);
88 void setCurrentProperty(CSSPropertyID);
89
90 void parseSheet(StyleSheetContents*, const String&, const TextPosition& startPosition = TextPosition::minimumPosition(), CSSParserObserver* = 0, bool = false);
91 PassRefPtrWillBeRawPtr<StyleRuleBase> parseRule(StyleSheetContents*, const String&);
92 PassRefPtrWillBeRawPtr<StyleKeyframe> parseKeyframeRule(StyleSheetContents*, const String&);
93 bool parseSupportsCondition(const String&);
94 static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, CSSParserMode, StyleSheetContents*);
95 static bool parseColor(RGBA32& color, const String&, bool strict = false);
96 static bool parseSystemColor(RGBA32& color, const String&);
97 static PassRefPtrWillBeRawPtr<CSSValueList> parseFontFaceValue(const AtomicString&);
98 static PassRefPtrWillBeRawPtr<CSSValue> parseAnimationTimingFunctionValue(const String&);
99 bool parseDeclaration(MutableStylePropertySet*, const String&, CSSParserObserver*, StyleSheetContents* contextStyleSheet);
100 static PassRefPtr<ImmutableStylePropertySet> parseInlineStyleDeclaration(const String&, Element*);
101 PassRefPtrWillBeRawPtr<MediaQuerySet> parseMediaQueryList(const String&);
102 PassOwnPtr<Vector<double> > parseKeyframeKeyList(const String&);
103
104 static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, const Document&);
105
106 bool parseValue(CSSPropertyID, bool important);
107 void parseSelector(const String&, CSSSelectorList&);
108
109 CSSParserSelector* createFloatingSelector();
110 CSSParserSelector* createFloatingSelectorWithTagName(const QualifiedName&);
111 PassOwnPtr<CSSParserSelector> sinkFloatingSelector(CSSParserSelector*);
112
113 Vector<OwnPtr<CSSParserSelector> >* createFloatingSelectorVector();
114 PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >*);
115
116 CSSParserValueList* createFloatingValueList();
117 PassOwnPtr<CSSParserValueList> sinkFloatingValueList(CSSParserValueList*);
118
119 CSSParserFunction* createFloatingFunction();
120 CSSParserFunction* createFloatingFunction(const CSSParserString& name, PassOwnPtr<CSSParserValueList> args);
121 PassOwnPtr<CSSParserFunction> sinkFloatingFunction(CSSParserFunction*);
122
123 CSSParserValue& sinkFloatingValue(CSSParserValue&);
124
125 MediaQuerySet* createMediaQuerySet();
126 StyleRuleBase* createImportRule(const CSSParserString&, MediaQuerySet*);
127 StyleKeyframe* createKeyframe(CSSParserValueList*);
128 StyleRuleKeyframes* createKeyframesRule(const String&, PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > >, bool isPrefixed);
129
130 typedef WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > RuleList;
131 StyleRuleBase* createMediaRule(MediaQuerySet*, RuleList*);
132 RuleList* createRuleList();
133 RuleList* appendRule(RuleList*, StyleRuleBase*);
134 StyleRuleBase* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors);
135 StyleRuleBase* createFontFaceRule();
136 StyleRuleBase* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector);
137 StyleRuleBase* createMarginAtRule(CSSSelector::MarginBoxType);
138 StyleRuleBase* createSupportsRule(bool conditionIsSupported, RuleList*);
139 void markSupportsRuleHeaderStart();
140 void markSupportsRuleHeaderEnd();
141 PassRefPtrWillBeRawPtr<CSSRuleSourceData> popSupportsRuleData();
142 StyleRuleBase* createHostRule(RuleList* rules);
143
144 void startDeclarationsForMarginBox();
145 void endDeclarationsForMarginBox();
146
147 MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*);
148 PassOwnPtrWillBeRawPtr<MediaQueryExp> sinkFloatingMediaQueryExp(MediaQueryExp*);
149 WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* createFloatingMediaQueryExpList();
150 PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > sinkFloatingMediaQueryExpList(WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >*);
151 MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const AtomicString&, PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > >);
152 MediaQuery* createFloatingMediaQuery(PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > >);
153 MediaQuery* createFloatingNotAllQuery();
154 PassOwnPtrWillBeRawPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
155
156 WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >* createFloatingKeyframeVector();
157 PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > sinkFloatingKeyframeVector(WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >*);
158
159 void addNamespace(const AtomicString& prefix, const AtomicString& uri);
160 QualifiedName determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName);
161
162 CSSParserSelector* rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*, bool isNamespacePlaceholder = false);
163 CSSParserSelector* rewriteSpecifiersWithElementNameForCustomPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule);
164 CSSParserSelector* rewriteSpecifiersWithElementNameForContentPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule);
165 CSSParserSelector* rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector*);
166 CSSParserSelector* rewriteSpecifiers(CSSParserSelector*, CSSParserSelector*);
167 CSSParserSelector* rewriteSpecifiersForShadowDistributed(CSSParserSelector* specifiers, CSSParserSelector* distributedPseudoElementSelector);
168
169 void invalidBlockHit();
170
reusableSelectorVector()171 Vector<OwnPtr<CSSParserSelector> >* reusableSelectorVector() { return &m_reusableSelectorVector; }
172
173 void clearProperties();
174
175 PassRefPtr<ImmutableStylePropertySet> createStylePropertySet();
176
177 CSSParserContext m_context;
178
179 bool m_important;
180 CSSPropertyID m_id;
181 RawPtrWillBeMember<StyleSheetContents> m_styleSheet;
182 RefPtrWillBeMember<StyleRuleBase> m_rule;
183 RefPtrWillBeMember<StyleKeyframe> m_keyframe;
184 RefPtrWillBeMember<MediaQuerySet> m_mediaList;
185 OwnPtr<CSSParserValueList> m_valueList;
186 bool m_supportsCondition;
187
188 WillBeHeapVector<CSSProperty, 256> m_parsedProperties;
189 CSSSelectorList* m_selectorListForParseSelector;
190
191 unsigned m_numParsedPropertiesBeforeMarginBox;
192
193 bool m_hadSyntacticallyValidCSSRule;
194 bool m_logErrors;
195 bool m_ignoreErrors;
196
197 AtomicString m_defaultNamespace;
198
199 // tokenizer methods and data
200 CSSParserObserver* m_observer;
201
202 // Local functions which just call into CSSParserObserver if non-null.
203 void startRule();
204 void endRule(bool valid);
205 void startRuleHeader(CSSRuleSourceData::Type);
206 void endRuleHeader();
207 void startSelector();
208 void endSelector();
209 void startRuleBody();
210 void startProperty();
211 void endProperty(bool isImportantFound, bool isPropertyParsed, CSSParserError = NoCSSError);
212 void startEndUnknownRule();
213
214 void endInvalidRuleHeader();
215 void reportError(const CSSParserLocation&, CSSParserError = GeneralCSSError);
resumeErrorLogging()216 void resumeErrorLogging() { m_ignoreErrors = false; }
setLocationLabel(const CSSParserLocation & location)217 void setLocationLabel(const CSSParserLocation& location) { m_locationLabel = location; }
lastLocationLabel()218 const CSSParserLocation& lastLocationLabel() const { return m_locationLabel; }
219
220 void tokenToLowerCase(CSSParserString& token);
221
markViewportRuleBodyStart()222 void markViewportRuleBodyStart() { m_inViewport = true; }
markViewportRuleBodyEnd()223 void markViewportRuleBodyEnd() { m_inViewport = false; }
224 StyleRuleBase* createViewportRule();
225
currentLocation()226 CSSParserLocation currentLocation() { return m_tokenizer.currentLocation(); }
227
228 private:
229 class StyleDeclarationScope {
230 STACK_ALLOCATED();
231 WTF_MAKE_NONCOPYABLE(StyleDeclarationScope);
232 public:
StyleDeclarationScope(BisonCSSParser * parser,const StylePropertySet * declaration)233 StyleDeclarationScope(BisonCSSParser* parser, const StylePropertySet* declaration)
234 : m_parser(parser)
235 , m_mode(declaration->cssParserMode())
236 {
237 if (isCSSViewportParsingEnabledForMode(m_mode)) {
238 ASSERT(!m_parser->inViewport());
239 m_parser->markViewportRuleBodyStart();
240 }
241 }
242
~StyleDeclarationScope()243 ~StyleDeclarationScope()
244 {
245 if (isCSSViewportParsingEnabledForMode(m_mode))
246 m_parser->markViewportRuleBodyEnd();
247 }
248
249 private:
250 BisonCSSParser* m_parser;
251 CSSParserMode m_mode;
252 };
253
254 inline void ensureLineEndings();
255
setStyleSheet(StyleSheetContents * styleSheet)256 void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
257
inViewport()258 bool inViewport() const { return m_inViewport; }
259
260 void recheckAtKeyword(const UChar* str, int len);
261
262 template<unsigned prefixLength, unsigned suffixLength>
setupParser(const char (& prefix)[prefixLength],const String & string,const char (& suffix)[suffixLength])263 inline void setupParser(const char (&prefix)[prefixLength], const String& string, const char (&suffix)[suffixLength])
264 {
265 setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
266 }
267 void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength);
268
269 bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, StyleSheetContents* contextStyleSheet);
270 PassRefPtr<ImmutableStylePropertySet> parseDeclaration(const String&, StyleSheetContents* contextStyleSheet);
271
272 bool parseColor(const String&);
273
274 const String* m_source;
275 TextPosition m_startPosition;
276 CSSRuleSourceData::Type m_ruleHeaderType;
277 unsigned m_ruleHeaderStartOffset;
278 int m_ruleHeaderStartLineNumber;
279 OwnPtr<Vector<unsigned> > m_lineEndings;
280
281 bool m_ruleHasHeader;
282
283 bool m_allowImportRules;
284 bool m_allowNamespaceDeclarations;
285
286 bool m_inViewport;
287
288 CSSParserLocation m_locationLabel;
289
290 WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_parsedRules;
291 WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > m_parsedKeyframes;
292 WillBeHeapVector<RefPtrWillBeMember<MediaQuerySet> > m_parsedMediaQuerySets;
293 WillBeHeapVector<OwnPtrWillBeMember<RuleList> > m_parsedRuleLists;
294 Vector<CSSParserSelector*> m_floatingSelectors;
295 Vector<Vector<OwnPtr<CSSParserSelector> >*> m_floatingSelectorVectors;
296 Vector<CSSParserValueList*> m_floatingValueLists;
297 Vector<CSSParserFunction*> m_floatingFunctions;
298
299 OwnPtrWillBeMember<MediaQuery> m_floatingMediaQuery;
300 OwnPtrWillBeMember<MediaQueryExp> m_floatingMediaQueryExp;
301 OwnPtrWillBeMember<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > m_floatingMediaQueryExpList;
302
303 OwnPtrWillBeMember<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > m_floatingKeyframeVector;
304
305 Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
306
307 OwnPtrWillBeMember<RuleSourceDataList> m_supportsRuleDataStack;
308
309 bool isLoggingErrors();
310 void logError(const String& message, const CSSParserLocation&);
311
312 CSSTokenizer m_tokenizer;
313
314 friend class TransformOperationInfo;
315 friend class FilterOperationInfo;
316 };
317
cssyylex(void * yylval,BisonCSSParser * parser)318 inline int cssyylex(void* yylval, BisonCSSParser* parser)
319 {
320 return parser->m_tokenizer.lex(yylval);
321 }
322
323 bool isValidNthToken(const CSSParserString&);
324
325 } // namespace WebCore
326
327 #endif // BisonCSSParser_h
328