/* * Copyright (C) 2003 Lars Knoll (knoll@kde.org) * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. * Copyright (C) 2008 Eric Seidel * Copyright (C) 2009 - 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef BisonCSSParser_h #define BisonCSSParser_h #include "core/CSSPropertyNames.h" #include "core/CSSValueKeywords.h" #include "core/css/CSSCalculationValue.h" #include "core/css/CSSFilterValue.h" #include "core/css/CSSGradientValue.h" #include "core/css/CSSProperty.h" #include "core/css/CSSPropertySourceData.h" #include "core/css/CSSSelector.h" #include "core/css/MediaQuery.h" #include "core/css/StylePropertySet.h" #include "core/css/parser/CSSParserMode.h" #include "core/css/parser/CSSParserObserver.h" #include "core/css/parser/CSSParserValues.h" #include "core/css/parser/CSSPropertyParser.h" #include "core/css/parser/CSSTokenizer.h" #include "platform/graphics/Color.h" #include "wtf/HashSet.h" #include "wtf/OwnPtr.h" #include "wtf/Vector.h" #include "wtf/text/AtomicString.h" #include "wtf/text/TextPosition.h" namespace blink { class AnimationParseContext; class CSSBorderImageSliceValue; class CSSPrimitiveValue; class CSSSelectorList; class CSSValue; class CSSValueList; class CSSBasicShape; class CSSBasicShapeInset; class Document; class Element; class ImmutableStylePropertySet; class MediaQueryExp; class MediaQuerySet; class MutableStylePropertySet; class StyleColor; class StyleKeyframe; class StylePropertyShorthand; class StyleRuleBase; class StyleRuleKeyframes; class StyleKeyframe; class StyleSheetContents; class UseCounter; // FIXME: This class is shared with CSSTokenizer so should we rename it to CSSSourceLocation? struct CSSParserLocation { unsigned offset; unsigned lineNumber; CSSParserString token; }; class BisonCSSParser { STACK_ALLOCATED(); friend inline int cssyylex(void*, BisonCSSParser*); public: explicit BisonCSSParser(const CSSParserContext&); ~BisonCSSParser(); void rollbackLastProperties(int num); void setCurrentProperty(CSSPropertyID); void parseSheet(StyleSheetContents*, const String&, const TextPosition& startPosition = TextPosition::minimumPosition(), CSSParserObserver* = 0, bool = false); PassRefPtrWillBeRawPtr parseRule(StyleSheetContents*, const String&); PassRefPtrWillBeRawPtr parseKeyframeRule(StyleSheetContents*, const String&); bool parseSupportsCondition(const String&); static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, CSSParserMode, StyleSheetContents*); static bool parseColor(RGBA32& color, const String&, bool strict = false); static StyleColor colorFromRGBColorString(const String&); static bool parseSystemColor(RGBA32& color, const String&); static PassRefPtrWillBeRawPtr parseFontFaceValue(const AtomicString&); static PassRefPtrWillBeRawPtr parseAnimationTimingFunctionValue(const String&); bool parseDeclaration(MutableStylePropertySet*, const String&, CSSParserObserver*, StyleSheetContents* contextStyleSheet); static PassRefPtrWillBeRawPtr parseInlineStyleDeclaration(const String&, Element*); PassRefPtrWillBeRawPtr parseMediaQueryList(const String&); PassOwnPtr > parseKeyframeKeyList(const String&); bool parseAttributeMatchType(CSSSelector::AttributeMatchType&, const String&); static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, const Document&); bool parseValue(CSSPropertyID, bool important); void parseSelector(const String&, CSSSelectorList&); CSSParserSelector* createFloatingSelector(); CSSParserSelector* createFloatingSelectorWithTagName(const QualifiedName&); PassOwnPtr sinkFloatingSelector(CSSParserSelector*); Vector >* createFloatingSelectorVector(); PassOwnPtr > > sinkFloatingSelectorVector(Vector >*); CSSParserValueList* createFloatingValueList(); PassOwnPtr sinkFloatingValueList(CSSParserValueList*); CSSParserFunction* createFloatingFunction(); CSSParserFunction* createFloatingFunction(const CSSParserString& name, PassOwnPtr args); PassOwnPtr sinkFloatingFunction(CSSParserFunction*); CSSParserValue& sinkFloatingValue(CSSParserValue&); MediaQuerySet* createMediaQuerySet(); StyleKeyframe* createKeyframe(CSSParserValueList*); StyleRuleKeyframes* createKeyframesRule(const String&, PassOwnPtrWillBeRawPtr > >, bool isPrefixed); typedef WillBeHeapVector > RuleList; StyleRuleBase* createMediaRule(MediaQuerySet*, RuleList*); RuleList* createRuleList(); RuleList* appendRule(RuleList*, StyleRuleBase*); StyleRuleBase* createStyleRule(Vector >* selectors); StyleRuleBase* createFontFaceRule(); StyleRuleBase* createSupportsRule(bool conditionIsSupported, RuleList*); void markSupportsRuleHeaderStart(); void markSupportsRuleHeaderEnd(); PassRefPtrWillBeRawPtr popSupportsRuleData(); StyleRuleBase* createHostRule(RuleList* rules); void startDeclarationsForMarginBox(); void endDeclarationsForMarginBox(); MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*); PassOwnPtrWillBeRawPtr sinkFloatingMediaQueryExp(MediaQueryExp*); WillBeHeapVector >* createFloatingMediaQueryExpList(); PassOwnPtrWillBeRawPtr > > sinkFloatingMediaQueryExpList(WillBeHeapVector >*); MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const AtomicString&, PassOwnPtrWillBeRawPtr > >); MediaQuery* createFloatingMediaQuery(PassOwnPtrWillBeRawPtr > >); MediaQuery* createFloatingNotAllQuery(); PassOwnPtrWillBeRawPtr sinkFloatingMediaQuery(MediaQuery*); WillBeHeapVector >* createFloatingKeyframeVector(); PassOwnPtrWillBeRawPtr > > sinkFloatingKeyframeVector(WillBeHeapVector >*); CSSParserSelector* rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*, bool isNamespacePlaceholder = false); CSSParserSelector* rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector*); CSSParserSelector* rewriteSpecifiers(CSSParserSelector*, CSSParserSelector*); CSSParserSelector* rewriteSpecifiersForShadowDistributed(CSSParserSelector* specifiers, CSSParserSelector* distributedPseudoElementSelector); void invalidBlockHit(); Vector >* reusableSelectorVector() { return &m_reusableSelectorVector; } void clearProperties(); PassRefPtrWillBeRawPtr createStylePropertySet(); CSSParserContext m_context; bool m_important; CSSPropertyID m_id; RawPtrWillBeMember m_styleSheet; RefPtrWillBeMember m_rule; RefPtrWillBeMember m_keyframe; RefPtrWillBeMember m_mediaList; OwnPtr m_valueList; bool m_supportsCondition; WillBeHeapVector m_parsedProperties; CSSSelectorList* m_selectorListForParseSelector; unsigned m_numParsedPropertiesBeforeMarginBox; bool m_hadSyntacticallyValidCSSRule; bool m_logErrors; bool m_ignoreErrors; AtomicString m_defaultNamespace; // tokenizer methods and data CSSParserObserver* m_observer; // Local functions which just call into CSSParserObserver if non-null. void startRule(); void endRule(bool valid); void startRuleHeader(CSSRuleSourceData::Type); void endRuleHeader(); void startSelector(); void endSelector(); void startRuleBody(); void startProperty(); void endProperty(bool isImportantFound, bool isPropertyParsed, CSSParserError = NoCSSError); void startEndUnknownRule(); void endInvalidRuleHeader(); void reportError(const CSSParserLocation&, CSSParserError = GeneralCSSError); void resumeErrorLogging() { m_ignoreErrors = false; } void setLocationLabel(const CSSParserLocation& location) { m_locationLabel = location; } const CSSParserLocation& lastLocationLabel() const { return m_locationLabel; } void tokenToLowerCase(CSSParserString& token); void markViewportRuleBodyStart() { m_inViewport = true; } void markViewportRuleBodyEnd() { m_inViewport = false; } StyleRuleBase* createViewportRule(); CSSParserLocation currentLocation() { return m_tokenizer.currentLocation(); } private: class StyleDeclarationScope { STACK_ALLOCATED(); WTF_MAKE_NONCOPYABLE(StyleDeclarationScope); public: StyleDeclarationScope(BisonCSSParser* parser, const StylePropertySet* declaration) : m_parser(parser) , m_mode(declaration->cssParserMode()) { if (isCSSViewportParsingEnabledForMode(m_mode)) { ASSERT(!m_parser->inViewport()); m_parser->markViewportRuleBodyStart(); } } ~StyleDeclarationScope() { if (isCSSViewportParsingEnabledForMode(m_mode)) m_parser->markViewportRuleBodyEnd(); } private: BisonCSSParser* m_parser; CSSParserMode m_mode; }; inline void ensureLineEndings(); void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; } bool inViewport() const { return m_inViewport; } void recheckAtKeyword(const UChar* str, int len); template inline void setupParser(const char (&prefix)[prefixLength], const String& string, const char (&suffix)[suffixLength]) { setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1); } void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength); bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, StyleSheetContents* contextStyleSheet); PassRefPtrWillBeRawPtr parseDeclaration(const String&, StyleSheetContents* contextStyleSheet); bool parseColor(const String&); const String* m_source; TextPosition m_startPosition; CSSRuleSourceData::Type m_ruleHeaderType; unsigned m_ruleHeaderStartOffset; int m_ruleHeaderStartLineNumber; OwnPtr > m_lineEndings; bool m_ruleHasHeader; bool m_allowImportRules; bool m_allowNamespaceDeclarations; bool m_inViewport; CSSParserLocation m_locationLabel; WillBeHeapVector > m_parsedRules; WillBeHeapVector > m_parsedKeyframes; WillBeHeapVector > m_parsedMediaQuerySets; WillBeHeapVector > m_parsedRuleLists; Vector m_floatingSelectors; Vector >*> m_floatingSelectorVectors; Vector m_floatingValueLists; Vector m_floatingFunctions; OwnPtrWillBeMember m_floatingMediaQuery; OwnPtrWillBeMember m_floatingMediaQueryExp; OwnPtrWillBeMember > > m_floatingMediaQueryExpList; OwnPtrWillBeMember > > m_floatingKeyframeVector; Vector > m_reusableSelectorVector; OwnPtrWillBeMember m_supportsRuleDataStack; bool isLoggingErrors(); void logError(const String& message, const CSSParserLocation&); CSSTokenizer m_tokenizer; friend class TransformOperationInfo; friend class FilterOperationInfo; }; inline int cssyylex(void* yylval, BisonCSSParser* parser) { return parser->m_tokenizer.lex(yylval); } bool isValidNthToken(const CSSParserString&); } // namespace blink #endif // BisonCSSParser_h