• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/CSSProperty.h"
32 #include "core/css/CSSPropertySourceData.h"
33 #include "core/css/CSSSelector.h"
34 #include "core/css/MediaQuery.h"
35 #include "core/css/StylePropertySet.h"
36 #include "core/css/parser/CSSParserMode.h"
37 #include "core/css/parser/CSSParserObserver.h"
38 #include "core/css/parser/CSSParserValues.h"
39 #include "core/css/parser/CSSPropertyParser.h"
40 #include "core/css/parser/CSSTokenizer.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 blink {
49 
50 class CSSSelectorList;
51 class CSSValue;
52 class CSSValueList;
53 class Document;
54 class Element;
55 class ImmutableStylePropertySet;
56 class MediaQueryExp;
57 class MediaQuerySet;
58 class MutableStylePropertySet;
59 class StyleColor;
60 class StyleKeyframe;
61 class StyleRuleBase;
62 class StyleRuleKeyframes;
63 class StyleKeyframe;
64 class StyleSheetContents;
65 
66 // FIXME: This class is shared with CSSTokenizer so should we rename it to CSSSourceLocation?
67 struct CSSParserLocation {
68     unsigned offset;
69     unsigned lineNumber;
70     CSSParserString token;
71 };
72 
73 class BisonCSSParser {
74     STACK_ALLOCATED();
75     friend inline int cssyylex(void*, BisonCSSParser*);
76 public:
77     explicit BisonCSSParser(const CSSParserContext&);
78     ~BisonCSSParser();
79 
80     void rollbackLastProperties(int num);
81     void setCurrentProperty(CSSPropertyID);
82 
83     void parseSheet(StyleSheetContents*, const String&, const TextPosition& startPosition = TextPosition::minimumPosition(), CSSParserObserver* = 0, bool = false);
84     PassRefPtrWillBeRawPtr<StyleRuleBase> parseRule(StyleSheetContents*, const String&);
85     PassRefPtrWillBeRawPtr<StyleKeyframe> parseKeyframeRule(StyleSheetContents*, const String&);
86     bool parseSupportsCondition(const String&);
87     static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, const CSSParserContext&);
88     static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, CSSParserMode, StyleSheetContents*);
89     static bool parseColor(RGBA32& color, const String&, bool strict = false);
90     static StyleColor colorFromRGBColorString(const String&);
91     static bool parseSystemColor(RGBA32& color, const String&);
92     bool parseDeclaration(MutableStylePropertySet*, const String&, CSSParserObserver*, StyleSheetContents* contextStyleSheet);
93     static PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> parseInlineStyleDeclaration(const String&, Element*);
94     PassOwnPtr<Vector<double> > parseKeyframeKeyList(const String&);
95     bool parseAttributeMatchType(CSSSelector::AttributeMatchType&, const String&);
96 
97     bool parseValue(CSSPropertyID, bool important);
98     void parseSelector(const String&, CSSSelectorList&);
99 
100     CSSParserSelector* createFloatingSelector();
101     CSSParserSelector* createFloatingSelectorWithTagName(const QualifiedName&);
102     PassOwnPtr<CSSParserSelector> sinkFloatingSelector(CSSParserSelector*);
103 
104     Vector<OwnPtr<CSSParserSelector> >* createFloatingSelectorVector();
105     PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >*);
106 
107     CSSParserValueList* createFloatingValueList();
108     PassOwnPtr<CSSParserValueList> sinkFloatingValueList(CSSParserValueList*);
109 
110     CSSParserFunction* createFloatingFunction();
111     CSSParserFunction* createFloatingFunction(const CSSParserString& name, PassOwnPtr<CSSParserValueList> args);
112     PassOwnPtr<CSSParserFunction> sinkFloatingFunction(CSSParserFunction*);
113 
114     CSSParserValue& sinkFloatingValue(CSSParserValue&);
115 
116     MediaQuerySet* createMediaQuerySet();
117     StyleRuleBase* createImportRule(const CSSParserString&, MediaQuerySet*);
118     StyleKeyframe* createKeyframe(CSSParserValueList*);
119     StyleRuleKeyframes* createKeyframesRule(const String&, PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > >, bool isPrefixed);
120 
121     typedef WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > RuleList;
122     StyleRuleBase* createMediaRule(MediaQuerySet*, RuleList*);
123     RuleList* createRuleList();
124     RuleList* appendRule(RuleList*, StyleRuleBase*);
125     StyleRuleBase* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors);
126     StyleRuleBase* createFontFaceRule();
127     StyleRuleBase* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector);
128     StyleRuleBase* createMarginAtRule(CSSSelector::MarginBoxType);
129     StyleRuleBase* createSupportsRule(bool conditionIsSupported, RuleList*);
130     void markSupportsRuleHeaderStart();
131     void markSupportsRuleHeaderEnd();
132     PassRefPtrWillBeRawPtr<CSSRuleSourceData> popSupportsRuleData();
133     StyleRuleBase* createHostRule(RuleList* rules);
134 
135     void startDeclarationsForMarginBox();
136     void endDeclarationsForMarginBox();
137 
138     MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*);
139     PassOwnPtrWillBeRawPtr<MediaQueryExp> sinkFloatingMediaQueryExp(MediaQueryExp*);
140     WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* createFloatingMediaQueryExpList();
141     PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > sinkFloatingMediaQueryExpList(WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >*);
142     MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const AtomicString&, PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > >);
143     MediaQuery* createFloatingMediaQuery(PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > >);
144     MediaQuery* createFloatingNotAllQuery();
145     PassOwnPtrWillBeRawPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
146 
147     WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >* createFloatingKeyframeVector();
148     PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > sinkFloatingKeyframeVector(WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >*);
149 
150     void addNamespace(const AtomicString& prefix, const AtomicString& uri);
151     QualifiedName determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName);
152 
153     CSSParserSelector* rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*, bool isNamespacePlaceholder = false);
154     CSSParserSelector* rewriteSpecifiersWithElementNameForCustomPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule);
155     CSSParserSelector* rewriteSpecifiersWithElementNameForContentPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule);
156     CSSParserSelector* rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector*);
157     CSSParserSelector* rewriteSpecifiers(CSSParserSelector*, CSSParserSelector*);
158     CSSParserSelector* rewriteSpecifiersForShadowDistributed(CSSParserSelector* specifiers, CSSParserSelector* distributedPseudoElementSelector);
159 
160     void invalidBlockHit();
161 
reusableSelectorVector()162     Vector<OwnPtr<CSSParserSelector> >* reusableSelectorVector() { return &m_reusableSelectorVector; }
163 
164     void clearProperties();
165 
166     PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> createStylePropertySet();
167 
168     CSSParserContext m_context;
169 
170     bool m_important;
171     CSSPropertyID m_id;
172     RawPtrWillBeMember<StyleSheetContents> m_styleSheet;
173     RefPtrWillBeMember<StyleRuleBase> m_rule;
174     RefPtrWillBeMember<StyleKeyframe> m_keyframe;
175     OwnPtr<CSSParserValueList> m_valueList;
176     bool m_supportsCondition;
177 
178     WillBeHeapVector<CSSProperty, 256> m_parsedProperties;
179     CSSSelectorList* m_selectorListForParseSelector;
180 
181     unsigned m_numParsedPropertiesBeforeMarginBox;
182 
183     bool m_hadSyntacticallyValidCSSRule;
184     bool m_logErrors;
185     bool m_ignoreErrors;
186 
187     AtomicString m_defaultNamespace;
188 
189     // tokenizer methods and data
190     CSSParserObserver* m_observer;
191 
192     // Local functions which just call into CSSParserObserver if non-null.
193     void startRule();
194     void endRule(bool valid);
195     void startRuleHeader(CSSRuleSourceData::Type);
196     void endRuleHeader();
197     void startSelector();
198     void endSelector();
199     void startRuleBody();
200     void startProperty();
201     void endProperty(bool isImportantFound, bool isPropertyParsed, CSSParserError = NoCSSError);
202 
203     void endInvalidRuleHeader();
204     void reportError(const CSSParserLocation&, CSSParserError = GeneralCSSError);
resumeErrorLogging()205     void resumeErrorLogging() { m_ignoreErrors = false; }
setLocationLabel(const CSSParserLocation & location)206     void setLocationLabel(const CSSParserLocation& location) { m_locationLabel = location; }
lastLocationLabel()207     const CSSParserLocation& lastLocationLabel() const { return m_locationLabel; }
208 
209     void tokenToLowerCase(CSSParserString& token);
210 
markViewportRuleBodyStart()211     void markViewportRuleBodyStart() { m_inViewport = true; }
markViewportRuleBodyEnd()212     void markViewportRuleBodyEnd() { m_inViewport = false; }
213     StyleRuleBase* createViewportRule();
214 
currentLocation()215     CSSParserLocation currentLocation() { return m_tokenizer.currentLocation(); }
216 
217 private:
218     class StyleDeclarationScope {
219         STACK_ALLOCATED();
220         WTF_MAKE_NONCOPYABLE(StyleDeclarationScope);
221     public:
StyleDeclarationScope(BisonCSSParser * parser,const StylePropertySet * declaration)222         StyleDeclarationScope(BisonCSSParser* parser, const StylePropertySet* declaration)
223             : m_parser(parser)
224             , m_mode(declaration->cssParserMode())
225         {
226             if (isCSSViewportParsingEnabledForMode(m_mode)) {
227                 ASSERT(!m_parser->inViewport());
228                 m_parser->markViewportRuleBodyStart();
229             }
230         }
231 
~StyleDeclarationScope()232         ~StyleDeclarationScope()
233         {
234             if (isCSSViewportParsingEnabledForMode(m_mode))
235                 m_parser->markViewportRuleBodyEnd();
236         }
237 
238     private:
239         BisonCSSParser* m_parser;
240         CSSParserMode m_mode;
241     };
242 
243     inline void ensureLineEndings();
244 
setStyleSheet(StyleSheetContents * styleSheet)245     void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
246 
inViewport()247     bool inViewport() const { return m_inViewport; }
248 
249     void recheckAtKeyword(const UChar* str, int len);
250 
251     template<unsigned prefixLength, unsigned suffixLength>
setupParser(const char (& prefix)[prefixLength],const String & string,const char (& suffix)[suffixLength])252     inline void setupParser(const char (&prefix)[prefixLength], const String& string, const char (&suffix)[suffixLength])
253     {
254         setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
255     }
256     void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength);
257 
258     bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, StyleSheetContents* contextStyleSheet);
259     PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> parseDeclaration(const String&, StyleSheetContents* contextStyleSheet);
260 
261     bool parseColor(const String&);
262 
263     const String* m_source;
264     TextPosition m_startPosition;
265     CSSRuleSourceData::Type m_ruleHeaderType;
266     unsigned m_ruleHeaderStartOffset;
267     int m_ruleHeaderStartLineNumber;
268     OwnPtr<Vector<unsigned> > m_lineEndings;
269 
270     bool m_ruleHasHeader;
271 
272     bool m_allowImportRules;
273     bool m_allowNamespaceDeclarations;
274 
275     bool m_inViewport;
276 
277     CSSParserLocation m_locationLabel;
278 
279     WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_parsedRules;
280     WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > m_parsedKeyframes;
281     WillBeHeapVector<RefPtrWillBeMember<MediaQuerySet> > m_parsedMediaQuerySets;
282     WillBeHeapVector<OwnPtrWillBeMember<RuleList> > m_parsedRuleLists;
283     Vector<CSSParserSelector*> m_floatingSelectors;
284     Vector<Vector<OwnPtr<CSSParserSelector> >*> m_floatingSelectorVectors;
285     Vector<CSSParserValueList*> m_floatingValueLists;
286     Vector<CSSParserFunction*> m_floatingFunctions;
287 
288     OwnPtrWillBeMember<MediaQuery> m_floatingMediaQuery;
289     OwnPtrWillBeMember<MediaQueryExp> m_floatingMediaQueryExp;
290     OwnPtrWillBeMember<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > m_floatingMediaQueryExpList;
291 
292     OwnPtrWillBeMember<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > m_floatingKeyframeVector;
293 
294     Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
295 
296     OwnPtrWillBeMember<RuleSourceDataList> m_supportsRuleDataStack;
297 
298     bool isLoggingErrors();
299     void logError(const String& message, const CSSParserLocation&);
300 
301     CSSTokenizer m_tokenizer;
302 
303     friend class TransformOperationInfo;
304     friend class FilterOperationInfo;
305 };
306 
cssyylex(void * yylval,BisonCSSParser * parser)307 inline int cssyylex(void* yylval, BisonCSSParser* parser)
308 {
309     return parser->m_tokenizer.lex(yylval);
310 }
311 
312 bool isValidNthToken(const CSSParserString&);
313 
314 } // namespace blink
315 
316 #endif // BisonCSSParser_h
317