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