This adds support for custom properties on the remainder of the
CSSStyleDeclaration methods.
A shorthand that was specified using a variable reference is serialized
to its originally specified value, rather than by concatenating the
serializations of its longhand components.
A shorthand that was not specified using a variable references but which
has a component longhand that was is serialized to the empty string.
This adds CSS parser error reporting for parsing of custom properties
and normal properties that have variable references.
When re-parsing a normal property that had a variable reference, we
report any parse error to be at the beginning of the property value.
This is because it is difficult to keep track of where exactly each
variable substitution came from to point to the particular value
that would have caused the parse error. For example, with this:
:root {
var-a: 1px 2px;
var-b: 3px var(a);
}
p {
margin: var(a) var(b);
}
we would end up resolving the value of 'margin' to:
" 1px 2px 3px 1px 2px"
In this string, the parse error occurs when we encounter the final
"2px", but by this point we don't know where that value came from.
So instead we just point to the line on which 'margin' was declared.
We extend ErrorReporter with an OutputError overload that takes the
specific line and column number to use in the error report to get this
right, and we store the line and column number for each token stream
we parse on the nsCSSValueTokenStream object.
This re-parses property values at computed value time if
they had a specified value that was a token stream. We add
a function nsRuleNode::ResolveVariableReferences that looks
at all the values in the nsRuleData and calls in to a new
nsCSSParser::ParsePropertyWithVariableReferences function if they have a
token stream value.
We add a nsCSSExpandedDataBlock::MapRuleInfoInto function that will
take the re-parsed property value and copy it back into the nsRuleData.
nsRuleNode::ResolveVariableReferences returns whether any variables
were attempted to be resolved, so that nsRuleNode::WalkRuleTree wil
recompute the rule detail in case any became 'inherit'.
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
This implements the proposed spec clarification in
http://lists.w3.org/Archives/Public/www-style/2013Feb/0229.html which
makes us compatible with WebKit on the insertRule tests in this patch.
I confirmed that the test reports 7 failures without the patch, but
passes with the patch. (I'm a little disturbed by the way our
testharness.js integration elides runs of successive passes.)
This changes nsCSSParser::ParseColorString to fill in an nsCSSValue instead
of an nscolor, and exposes nsRuleNode::ComputeColor to turn this nsCSSValue
into an nscolor.
Because gradients can be used with different canvas elements in different
documents, these cannot pass useful values for nsRuleNode::ComputeColor's
aPresContext and aStyleContext arguments. This patch also changes SetColor
to deal with those parameters being null.