michael@0: /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */ 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: /* object that resolves CSS variables using specified and inherited variable michael@0: * values michael@0: */ michael@0: michael@0: #ifndef mozilla_CSSVariableResolver_h michael@0: #define mozilla_CSSVariableResolver_h michael@0: michael@0: #include "mozilla/DebugOnly.h" michael@0: #include "nsCSSParser.h" michael@0: #include "nsCSSScanner.h" michael@0: #include "nsDataHashtable.h" michael@0: #include "nsTArray.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: class CSSVariableDeclarations; michael@0: class CSSVariableValues; michael@0: class EnumerateVariableReferencesData; michael@0: michael@0: class CSSVariableResolver michael@0: { michael@0: friend class CSSVariableDeclarations; michael@0: friend class CSSVariableValues; michael@0: friend class EnumerateVariableReferencesData; michael@0: public: michael@0: /** michael@0: * Creates a new CSSVariableResolver that will output a set of resolved, michael@0: * computed variables into aOutput. michael@0: */ michael@0: CSSVariableResolver(CSSVariableValues* aOutput) michael@0: : mOutput(aOutput) michael@0: , mResolved(false) michael@0: { michael@0: MOZ_ASSERT(aOutput); michael@0: } michael@0: michael@0: /** michael@0: * Resolves the set of inherited variables from aInherited and the michael@0: * set of specified variables from aSpecified. The resoled variables michael@0: * are written in to mOutput. michael@0: */ michael@0: void Resolve(const CSSVariableValues* aInherited, michael@0: const CSSVariableDeclarations* aSpecified); michael@0: michael@0: private: michael@0: struct Variable michael@0: { michael@0: Variable(const nsAString& aVariableName, michael@0: nsString aValue, michael@0: nsCSSTokenSerializationType aFirstToken, michael@0: nsCSSTokenSerializationType aLastToken, michael@0: bool aWasInherited) michael@0: : mVariableName(aVariableName) michael@0: , mValue(aValue) michael@0: , mFirstToken(aFirstToken) michael@0: , mLastToken(aLastToken) michael@0: , mWasInherited(aWasInherited) michael@0: , mResolved(false) michael@0: , mReferencesNonExistentVariable(false) michael@0: , mInStack(false) michael@0: , mIndex(0) michael@0: , mLowLink(0) { } michael@0: michael@0: nsString mVariableName; michael@0: nsString mValue; michael@0: nsCSSTokenSerializationType mFirstToken; michael@0: nsCSSTokenSerializationType mLastToken; michael@0: michael@0: // Whether this variable came from the set of inherited variables. michael@0: bool mWasInherited; michael@0: michael@0: // Whether this variable has been resolved yet. michael@0: bool mResolved; michael@0: michael@0: // Whether this variables includes any references to non-existent variables. michael@0: bool mReferencesNonExistentVariable; michael@0: michael@0: // Bookkeeping for the cycle remover algorithm. michael@0: bool mInStack; michael@0: size_t mIndex; michael@0: size_t mLowLink; michael@0: }; michael@0: michael@0: /** michael@0: * Adds or modifies an existing entry in the set of variables to be resolved. michael@0: * This is intended to be called by the AddVariablesToResolver functions on michael@0: * the CSSVariableDeclarations and CSSVariableValues objects passed in to michael@0: * Resolve. michael@0: * michael@0: * @param aName The variable name (not including any "--" prefix that would michael@0: * be part of the custom property name) whose value is to be set. michael@0: * @param aValue The variable value. michael@0: * @param aFirstToken The type of token at the start of the variable value. michael@0: * @param aLastToken The type of token at the en of the variable value. michael@0: * @param aWasInherited Whether this variable came from the set of inherited michael@0: * variables. michael@0: */ michael@0: void Put(const nsAString& aVariableName, michael@0: nsString aValue, michael@0: nsCSSTokenSerializationType aFirstToken, michael@0: nsCSSTokenSerializationType aLastToken, michael@0: bool aWasInherited); michael@0: michael@0: // Helper functions for Resolve. michael@0: void RemoveCycles(size_t aID); michael@0: void ResolveVariable(size_t aID); michael@0: michael@0: // A mapping of variable names to an ID that indexes into mVariables michael@0: // and mReferences. michael@0: nsDataHashtable mVariableIDs; michael@0: michael@0: // The set of variables. michael@0: nsTArray mVariables; michael@0: michael@0: // The list of variables that each variable references. michael@0: nsTArray > mReferences; michael@0: michael@0: // The next index to assign to a variable found during the cycle removing michael@0: // algorithm's traversal of the variable reference graph. michael@0: size_t mNextIndex; michael@0: michael@0: // Stack of variable IDs that we push to as we traverse the variable reference michael@0: // graph while looking for cycles. Variable::mInStack reflects whether a michael@0: // given variable has its ID in mStack. michael@0: nsTArray mStack; michael@0: michael@0: // CSS parser to use for parsing property values with variable references. michael@0: nsCSSParser mParser; michael@0: michael@0: // The object to output the resolved variables into. michael@0: CSSVariableValues* mOutput; michael@0: michael@0: // Whether Resolve has been called. michael@0: DebugOnly mResolved; michael@0: }; michael@0: michael@0: } michael@0: michael@0: #endif