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/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 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 217 private: 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 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