Home | History | Annotate | Download | only in parser
      1 /*
      2  * Copyright (C) 2003 Lars Knoll (knoll (at) kde.org)
      3  * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
      4  * Copyright (C) 2008 Eric Seidel <eric (at) 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 
    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);
    216     void resumeErrorLogging() { m_ignoreErrors = false; }
    217     void setLocationLabel(const CSSParserLocation& location) { m_locationLabel = location; }
    218     const CSSParserLocation& lastLocationLabel() const { return m_locationLabel; }
    219 
    220     void tokenToLowerCase(CSSParserString& token);
    221 
    222     void markViewportRuleBodyStart() { m_inViewport = true; }
    223     void markViewportRuleBodyEnd() { m_inViewport = false; }
    224     StyleRuleBase* createViewportRule();
    225 
    226     CSSParserLocation currentLocation() { return m_tokenizer.currentLocation(); }
    227 
    228 private:
    229     class StyleDeclarationScope {
    230         STACK_ALLOCATED();
    231         WTF_MAKE_NONCOPYABLE(StyleDeclarationScope);
    232     public:
    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 
    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 
    256     void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
    257 
    258     bool inViewport() const { return m_inViewport; }
    259 
    260     void recheckAtKeyword(const UChar* str, int len);
    261 
    262     template<unsigned prefixLength, unsigned 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 
    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