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 48namespace blink { 49 50class CSSSelectorList; 51class CSSValue; 52class CSSValueList; 53class Document; 54class Element; 55class ImmutableStylePropertySet; 56class MediaQueryExp; 57class MediaQuerySet; 58class MutableStylePropertySet; 59class StyleColor; 60class StyleKeyframe; 61class StyleRuleBase; 62class StyleRuleKeyframes; 63class StyleKeyframe; 64class StyleSheetContents; 65 66// FIXME: This class is shared with CSSTokenizer so should we rename it to CSSSourceLocation? 67struct CSSParserLocation { 68 unsigned offset; 69 unsigned lineNumber; 70 CSSParserString token; 71}; 72 73class BisonCSSParser { 74 STACK_ALLOCATED(); 75 friend inline int cssyylex(void*, BisonCSSParser*); 76public: 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 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); 205 void resumeErrorLogging() { m_ignoreErrors = false; } 206 void setLocationLabel(const CSSParserLocation& location) { m_locationLabel = location; } 207 const CSSParserLocation& lastLocationLabel() const { return m_locationLabel; } 208 209 void tokenToLowerCase(CSSParserString& token); 210 211 void markViewportRuleBodyStart() { m_inViewport = true; } 212 void markViewportRuleBodyEnd() { m_inViewport = false; } 213 StyleRuleBase* createViewportRule(); 214 215 CSSParserLocation currentLocation() { return m_tokenizer.currentLocation(); } 216 217private: 218 class StyleDeclarationScope { 219 STACK_ALLOCATED(); 220 WTF_MAKE_NONCOPYABLE(StyleDeclarationScope); 221 public: 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 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 245 void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; } 246 247 bool inViewport() const { return m_inViewport; } 248 249 void recheckAtKeyword(const UChar* str, int len); 250 251 template<unsigned prefixLength, unsigned 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 307inline int cssyylex(void* yylval, BisonCSSParser* parser) 308{ 309 return parser->m_tokenizer.lex(yylval); 310} 311 312bool isValidNthToken(const CSSParserString&); 313 314} // namespace blink 315 316#endif // BisonCSSParser_h 317