gecko/layout/style/CSSVariableValues.h

148 lines
4.7 KiB
C
Raw Normal View History

/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* computed CSS Variable values */
#ifndef mozilla_CSSVariableValues_h
#define mozilla_CSSVariableValues_h
#include "nsCSSScanner.h"
#include "nsDataHashtable.h"
#include "nsTArray.h"
namespace mozilla {
Bug 773296 - Part 8: Resolve and compute CSS variables. r=dbaron We add a new class CSSVariableResolver whose job is to take the inherited computed variables and the specified variable declarations and to perform cycle removal and resolution of the variables, storing the result in the CSSVariableValues object on an nsStyleVariables. We use CSSVariableResolver in nsRuleNode::ComputeVariablesData. The variable resolver does this: 1. Asks the CSSVariableValues and CSSVariableDeclarations objects to add their variables to it. 2. Calls in to a new nsCSSParser function EnumerateVariableReferences that informs the resolver which other variables a given variable references, and by doing so, builds a graph of variable dependencies. 3. Removes variables involved in cyclic references using Tarjan's strongly connected component algorithm, setting those variables to have an invalid value. 4. Calls in to a new nsCSSParser function ResolveVariableValue to resolve the remaining valid variables by substituting variable references. We extend nsCSSParser::ParseValueWithVariables to take a callback function to be invoked when encountering a variable reference. This lets EnumerateVariableReferences re-use ParseValueWithVariables. CSSParserImpl::ResolveValueWithVariableReferences needs different error handling behaviour from ParseValueWithVariables, so we don't re-use it. CSSParserImpl::AppendImpliedEOFCharacters is used to take the value returned from nsCSSScanner::GetImpliedEOFCharacters while resolving variable references that were declared using custom properties that encountered EOF before being closed properly. The SeparatorRequiredBetweenTokens helper function in nsCSSParser.cpp implements the serialization rules in CSS Syntax Module Level 3: https://dvcs.w3.org/hg/csswg/raw-file/3479cdefc59a/css-syntax/Overview.html#serialization
2013-12-11 18:09:41 -08:00
class CSSVariableResolver;
class CSSVariableValues
{
public:
CSSVariableValues();
CSSVariableValues(const CSSVariableValues& aOther);
#ifdef DEBUG
~CSSVariableValues();
#endif
CSSVariableValues& operator=(const CSSVariableValues& aOther);
bool operator==(const CSSVariableValues& aOther) const;
bool operator!=(const CSSVariableValues& aOther) const
{ return !(*this == aOther); }
/**
* Gets the value of a variable in this set of computed variables.
*
* @param aName The variable name (not including any "var-" prefix that would
* be part of the custom property name).
* @param aValue Out parameter into which the value of the variable will
* be stored.
* @return Whether a variable with the given name was found. When false
* is returned, aValue will not be modified.
*/
bool Get(const nsAString& aName, nsString& aValue) const;
/**
* Gets the value of a variable in this set of computed variables, along
* with information on the types of tokens that appear at the start and
* end of the token stream.
*
* @param aName The variable name (not including any "var-" prefix that would
* be part of the custom property name).
* @param aValue Out parameter into which the value of the variable will
* be stored.
* @param aFirstToken The type of token at the start of the variable value.
* @param aLastToken The type of token at the en of the variable value.
* @return Whether a variable with the given name was found. When false
* is returned, aValue, aFirstToken and aLastToken will not be modified.
*/
bool Get(const nsAString& aName,
nsString& aValue,
nsCSSTokenSerializationType& aFirstToken,
nsCSSTokenSerializationType& aLastToken) const;
/**
* Gets the name of the variable at the given index.
*
* Variables on this object are ordered, and that order is just determined
* based on the order that they are added to the object. A consistent
* ordering is required for CSSDeclaration objects in the DOM.
* CSSDeclarations expose property names as indexed properties, which need to
* be stable.
*
* @param aIndex The index of the variable to get.
* @param aName Out parameter into which the name of the variable will be
* stored.
*/
void GetVariableAt(size_t aIndex, nsAString& aName) const;
/**
* Gets the number of variables stored on this object.
*/
size_t Count() const;
/**
* Adds or modifies an existing entry in this set of variable values.
*
* @param aName The variable name (not including any "var-" prefix that would
* be part of the custom property name) whose value is to be set.
* @param aValue The variable value.
* @param aFirstToken The type of token at the start of the variable value.
* @param aLastToken The type of token at the en of the variable value.
*/
void Put(const nsAString& aName,
nsString aValue,
nsCSSTokenSerializationType aFirstToken,
nsCSSTokenSerializationType aLastToken);
Bug 773296 - Part 8: Resolve and compute CSS variables. r=dbaron We add a new class CSSVariableResolver whose job is to take the inherited computed variables and the specified variable declarations and to perform cycle removal and resolution of the variables, storing the result in the CSSVariableValues object on an nsStyleVariables. We use CSSVariableResolver in nsRuleNode::ComputeVariablesData. The variable resolver does this: 1. Asks the CSSVariableValues and CSSVariableDeclarations objects to add their variables to it. 2. Calls in to a new nsCSSParser function EnumerateVariableReferences that informs the resolver which other variables a given variable references, and by doing so, builds a graph of variable dependencies. 3. Removes variables involved in cyclic references using Tarjan's strongly connected component algorithm, setting those variables to have an invalid value. 4. Calls in to a new nsCSSParser function ResolveVariableValue to resolve the remaining valid variables by substituting variable references. We extend nsCSSParser::ParseValueWithVariables to take a callback function to be invoked when encountering a variable reference. This lets EnumerateVariableReferences re-use ParseValueWithVariables. CSSParserImpl::ResolveValueWithVariableReferences needs different error handling behaviour from ParseValueWithVariables, so we don't re-use it. CSSParserImpl::AppendImpliedEOFCharacters is used to take the value returned from nsCSSScanner::GetImpliedEOFCharacters while resolving variable references that were declared using custom properties that encountered EOF before being closed properly. The SeparatorRequiredBetweenTokens helper function in nsCSSParser.cpp implements the serialization rules in CSS Syntax Module Level 3: https://dvcs.w3.org/hg/csswg/raw-file/3479cdefc59a/css-syntax/Overview.html#serialization
2013-12-11 18:09:41 -08:00
/**
* Copies the variables from this object into aResolver, marking them as
* computed, inherited values.
*/
void AddVariablesToResolver(CSSVariableResolver* aResolver) const;
private:
struct Variable
{
Variable()
: mFirstToken(eCSSTokenSerialization_Nothing)
, mLastToken(eCSSTokenSerialization_Nothing)
{}
Variable(const nsAString& aVariableName,
nsString aValue,
nsCSSTokenSerializationType aFirstToken,
nsCSSTokenSerializationType aLastToken)
: mVariableName(aVariableName)
, mValue(aValue)
, mFirstToken(aFirstToken)
, mLastToken(aLastToken)
{}
nsString mVariableName;
nsString mValue;
nsCSSTokenSerializationType mFirstToken;
nsCSSTokenSerializationType mLastToken;
};
/**
* Adds all the variables from aOther into this object.
*/
void CopyVariablesFrom(const CSSVariableValues& aOther);
/**
* Map of variable names to IDs. Variable IDs are indexes into
* mVariables.
*/
nsDataHashtable<nsStringHashKey, size_t> mVariableIDs;
/**
* Array of variables, indexed by variable ID.
*/
nsTArray<Variable> mVariables;
};
} // namespace mozilla
#endif