michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* parsing of CSS stylesheets, based on a token stream from the CSS scanner */ michael@0: michael@0: #ifndef nsCSSParser_h___ michael@0: #define nsCSSParser_h___ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: #include "nsCSSProperty.h" michael@0: #include "nsCSSScanner.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsStringFwd.h" michael@0: #include "nsTArrayForwardDeclare.h" michael@0: michael@0: class nsCSSStyleSheet; michael@0: class nsIPrincipal; michael@0: class nsIURI; michael@0: struct nsCSSSelectorList; michael@0: class nsMediaList; michael@0: class nsCSSKeyframeRule; michael@0: class nsCSSValue; michael@0: class nsRuleData; michael@0: michael@0: namespace mozilla { michael@0: class CSSVariableValues; michael@0: namespace css { michael@0: class Rule; michael@0: class Declaration; michael@0: class Loader; michael@0: class StyleRule; michael@0: } michael@0: } michael@0: michael@0: // Interface to the css parser. michael@0: michael@0: class MOZ_STACK_CLASS nsCSSParser { michael@0: public: michael@0: nsCSSParser(mozilla::css::Loader* aLoader = nullptr, michael@0: nsCSSStyleSheet* aSheet = nullptr); michael@0: ~nsCSSParser(); michael@0: michael@0: static void Shutdown(); michael@0: michael@0: private: michael@0: nsCSSParser(nsCSSParser const&) MOZ_DELETE; michael@0: nsCSSParser& operator=(nsCSSParser const&) MOZ_DELETE; michael@0: michael@0: public: michael@0: // Set a style sheet for the parser to fill in. The style sheet must michael@0: // implement the nsCSSStyleSheet interface. Null can be passed in to clear michael@0: // out an existing stylesheet reference. michael@0: nsresult SetStyleSheet(nsCSSStyleSheet* aSheet); michael@0: michael@0: // Set whether or not to emulate Nav quirks michael@0: nsresult SetQuirkMode(bool aQuirkMode); michael@0: michael@0: // Set loader to use for child sheets michael@0: nsresult SetChildLoader(mozilla::css::Loader* aChildLoader); michael@0: michael@0: /** michael@0: * Parse aInput into the stylesheet that was previously set by calling michael@0: * SetStyleSheet. Calling this method without calling SetStyleSheet first is michael@0: * an error. michael@0: * michael@0: * @param aInput the data to parse michael@0: * @param aSheetURL the URI to use as the sheet URI (for error reporting). michael@0: * This must match the URI of the sheet passed to michael@0: * SetStyleSheet. michael@0: * @param aBaseURI the URI to use for relative URI resolution michael@0: * @param aSheetPrincipal the principal of the stylesheet. This must match michael@0: * the principal of the sheet passed to SetStyleSheet. michael@0: * @param aLineNumber the line number of the first line of the sheet. michael@0: * @param aAllowUnsafeRules see aEnableUnsafeRules in michael@0: * mozilla::css::Loader::LoadSheetSync michael@0: */ michael@0: nsresult ParseSheet(const nsAString& aInput, michael@0: nsIURI* aSheetURL, michael@0: nsIURI* aBaseURI, michael@0: nsIPrincipal* aSheetPrincipal, michael@0: uint32_t aLineNumber, michael@0: bool aAllowUnsafeRules); michael@0: michael@0: // Parse HTML style attribute or its equivalent in other markup michael@0: // languages. aBaseURL is the base url to use for relative links in michael@0: // the declaration. michael@0: nsresult ParseStyleAttribute(const nsAString& aAttributeValue, michael@0: nsIURI* aDocURL, michael@0: nsIURI* aBaseURL, michael@0: nsIPrincipal* aNodePrincipal, michael@0: mozilla::css::StyleRule** aResult); michael@0: michael@0: // Parse the body of a declaration block. Very similar to michael@0: // ParseStyleAttribute, but used under different circumstances. michael@0: // The contents of aDeclaration will be erased and replaced with the michael@0: // results of parsing; aChanged will be set true if the aDeclaration michael@0: // argument was modified. michael@0: nsresult ParseDeclarations(const nsAString& aBuffer, michael@0: nsIURI* aSheetURL, michael@0: nsIURI* aBaseURL, michael@0: nsIPrincipal* aSheetPrincipal, michael@0: mozilla::css::Declaration* aDeclaration, michael@0: bool* aChanged); michael@0: michael@0: nsresult ParseRule(const nsAString& aRule, michael@0: nsIURI* aSheetURL, michael@0: nsIURI* aBaseURL, michael@0: nsIPrincipal* aSheetPrincipal, michael@0: mozilla::css::Rule** aResult); michael@0: michael@0: // Parse the value of a single CSS property, and add or replace that michael@0: // property in aDeclaration. michael@0: // michael@0: // SVG "mapped attributes" (which correspond directly to CSS michael@0: // properties) are parsed slightly differently from regular CSS; in michael@0: // particular, units may be omitted from . The 'aIsSVGMode' michael@0: // argument controls this quirk. Note that this *only* applies to michael@0: // mapped attributes, not inline styles or full style sheets in SVG. michael@0: nsresult ParseProperty(const nsCSSProperty aPropID, michael@0: const nsAString& aPropValue, michael@0: nsIURI* aSheetURL, michael@0: nsIURI* aBaseURL, michael@0: nsIPrincipal* aSheetPrincipal, michael@0: mozilla::css::Declaration* aDeclaration, michael@0: bool* aChanged, michael@0: bool aIsImportant, michael@0: bool aIsSVGMode = false); michael@0: michael@0: // The same as ParseProperty but for a variable. michael@0: nsresult ParseVariable(const nsAString& aVariableName, michael@0: const nsAString& aPropValue, michael@0: nsIURI* aSheetURL, michael@0: nsIURI* aBaseURL, michael@0: nsIPrincipal* aSheetPrincipal, michael@0: mozilla::css::Declaration* aDeclaration, michael@0: bool* aChanged, michael@0: bool aIsImportant); michael@0: /** michael@0: * Parse aBuffer into a media list |aMediaList|, which must be michael@0: * non-null, replacing its current contents. If aHTMLMode is true, michael@0: * parse according to HTML rules, with commas as the most important michael@0: * delimiter. Otherwise, parse according to CSS rules, with michael@0: * parentheses and strings more important than commas. |aURL| and michael@0: * |aLineNumber| are used for error reporting. michael@0: */ michael@0: void ParseMediaList(const nsSubstring& aBuffer, michael@0: nsIURI* aURL, michael@0: uint32_t aLineNumber, michael@0: nsMediaList* aMediaList, michael@0: bool aHTMLMode); michael@0: michael@0: /** michael@0: * Parse aBuffer into a nsCSSValue |aValue|. Will return false michael@0: * if aBuffer is not a valid CSS color specification. michael@0: * One can use nsRuleNode::ComputeColor to compute an nscolor from michael@0: * the returned nsCSSValue. michael@0: */ michael@0: bool ParseColorString(const nsSubstring& aBuffer, michael@0: nsIURI* aURL, michael@0: uint32_t aLineNumber, michael@0: nsCSSValue& aValue); michael@0: michael@0: /** michael@0: * Parse aBuffer into a selector list. On success, caller must michael@0: * delete *aSelectorList when done with it. michael@0: */ michael@0: nsresult ParseSelectorString(const nsSubstring& aSelectorString, michael@0: nsIURI* aURL, michael@0: uint32_t aLineNumber, michael@0: nsCSSSelectorList** aSelectorList); michael@0: michael@0: /* michael@0: * Parse a keyframe rule (which goes inside an @keyframes rule). michael@0: * Return it if the parse was successful. michael@0: */ michael@0: already_AddRefed michael@0: ParseKeyframeRule(const nsSubstring& aBuffer, michael@0: nsIURI* aURL, michael@0: uint32_t aLineNumber); michael@0: michael@0: /* michael@0: * Parse a selector list for a keyframe rule. Return whether michael@0: * the parse succeeded. michael@0: */ michael@0: bool ParseKeyframeSelectorString(const nsSubstring& aSelectorString, michael@0: nsIURI* aURL, michael@0: uint32_t aLineNumber, michael@0: InfallibleTArray& aSelectorList); michael@0: michael@0: /** michael@0: * Parse a property and value and return whether the property/value pair michael@0: * is supported. michael@0: */ michael@0: bool EvaluateSupportsDeclaration(const nsAString& aProperty, michael@0: const nsAString& aValue, michael@0: nsIURI* aDocURL, michael@0: nsIURI* aBaseURL, michael@0: nsIPrincipal* aDocPrincipal); michael@0: michael@0: /** michael@0: * Parse an @supports condition and returns the result of evaluating the michael@0: * condition. michael@0: */ michael@0: bool EvaluateSupportsCondition(const nsAString& aCondition, michael@0: nsIURI* aDocURL, michael@0: nsIURI* aBaseURL, michael@0: nsIPrincipal* aDocPrincipal); michael@0: michael@0: typedef void (*VariableEnumFunc)(const nsAString&, void*); michael@0: michael@0: /** michael@0: * Parses aPropertyValue as a property value and calls aFunc for each michael@0: * variable reference that is found. Returns false if there was michael@0: * a syntax error in the use of variable references. michael@0: */ michael@0: bool EnumerateVariableReferences(const nsAString& aPropertyValue, michael@0: VariableEnumFunc aFunc, michael@0: void* aData); michael@0: michael@0: /** michael@0: * Parses aPropertyValue as a property value and resolves variable references michael@0: * using the values in aVariables. michael@0: */ michael@0: bool ResolveVariableValue(const nsAString& aPropertyValue, michael@0: const mozilla::CSSVariableValues* aVariables, michael@0: nsString& aResult, michael@0: nsCSSTokenSerializationType& aFirstToken, michael@0: nsCSSTokenSerializationType& aLastToken); michael@0: michael@0: /** michael@0: * Parses a string as a CSS token stream value for particular property, michael@0: * resolving any variable references. The parsed property value is stored michael@0: * in the specified nsRuleData object. If aShorthandPropertyID has a value michael@0: * other than eCSSProperty_UNKNOWN, this is the property that will be parsed; michael@0: * otherwise, aPropertyID will be parsed. Either way, only aPropertyID, michael@0: * a longhand property, will be copied over to the rule data. michael@0: * michael@0: * If the property cannot be parsed, it will be treated as if 'initial' or michael@0: * 'inherit' were specified, for non-inherited and inherited properties michael@0: * respectively. michael@0: */ michael@0: void ParsePropertyWithVariableReferences( michael@0: nsCSSProperty aPropertyID, michael@0: nsCSSProperty aShorthandPropertyID, michael@0: const nsAString& aValue, michael@0: const mozilla::CSSVariableValues* aVariables, michael@0: nsRuleData* aRuleData, michael@0: nsIURI* aDocURL, michael@0: nsIURI* aBaseURL, michael@0: nsIPrincipal* aDocPrincipal, michael@0: nsCSSStyleSheet* aSheet, michael@0: uint32_t aLineNumber, michael@0: uint32_t aLineOffset); michael@0: michael@0: protected: michael@0: // This is a CSSParserImpl*, but if we expose that type name in this michael@0: // header, we can't put the type definition (in nsCSSParser.cpp) in michael@0: // the anonymous namespace. michael@0: void* mImpl; michael@0: }; michael@0: michael@0: #endif /* nsCSSParser_h___ */