APZC information is associated with layers, and having those layers suddenly
disappear because they became occluded, or their displayports are off-screen
has undesired effects.
The min attribute on an animation element can extend the active duration making
it longer than the "repeat duration" (the amount of the time the animation runs
including all repeats). For the remaining time after the repeat duration has
completed until the end of the active duration the animation should apply its
fill behavior.
Previously this was not implemented and min could not extend the active
duration. Allowing this effectively introduces an additional kind of state where
we are both within the active interval but not animating. In this case we
set the animation function (referred to as the "client" for historical reasons)
to inactive so that effectively the timing model is active but the animation
model is inactive.
(In the future we will come up with something a little easier to understand when
we rework this in terms of Web Animations components.)
Since we cannot parse and discard a white space token after the ':' in a
custom property declaration, we instead explicitly skip over it when
parsing a non-custom property's value.
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 exposes the names of the custom properties on a computed style
object through its indexed property getter, just after all of the
built-in properties.
This just factors out some code from
nsComputedDOMStyle::GetCSSPropertyValue into a
UpdateCurrentStyleSources and ClearCurrentStyleSources function.
These will will be needed in nsComputedDOMStyle::IndexGetter so that it
can have up to date information on how many custom properties there are
on the node.
This makes updates work correctly when variable values change.
Rather than handling nsStyleVariables with a DO_STRUCT_DIFFERENCE,
we explicitly compare the two nsStyleVariables objects in
nsStyleContext::CalcStyleDifference before looking at the other
style structs. This is because we need to force those other
style structs to be compared if variable values are changing.
nsStyleVariables::CalcDifference still returns 0, since the change in
variable values themselves doesn't require any updates.
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'.
This adds a new eCSSUnit_SharedList type for nsCSSValue, which is a
reference counted object that contains an nsCSSValueList. We need this
so that nsStyleDisplay::mSpecifiedTransform can hold a strong reference
to a specified transform list value. When 'transform' is specified
using a variable reference, the resulting nsCSSValue does not stick
around in the Declaration object, so we wouldn't be guaranteed that
it lives long enough for nsStyleDisplay to keep referencing it.
This factors out the part of nsCSSCompressedDataBlock::MapRuleInfoInto
that starts image loading and maybe-copies an nsCSSValue into
an nsRuleData. We will need this functionality for mapping re-parsed
properties that had variable references into an nsRuleData, which
will be done from an nsCSSExpandedDataBlock.
This adds functionality to nsCSSParser to recognise properties with
variable references and store their recorded token stream as an
eCSSUnit_TokenStream nsCSSValue.
This stores on the nsCSSParser whether we are somewhere in the middle
of parsing an @supports condition. Because @supports condition parsing
uses the scanner recording function (to save its conditionText), and
variable reference containing values also need it, we can't do both at
once. Luckily, if we're parsing an @supports condition, we don't really
need to store the token stream text; we only need to know if it was
valid, and we don't need its actual value later. So we use this flag
later to see if we can skip turning on scanner recording while parsing
variable reference containing values.
This adds functions to nsCSSParser and nsCSSScanner that let us save the
current input position (and corresponding information like line/column
number) and parser pushback, and be able to restore it later. We'll use
this when rewinding the scanner after we first encounter a property with
a variable reference and go back to reparse it as a token stream.
Patch co-authored by Emmanuele Bassi <ebassi@gmail.com>
This adds a new nsCSSValue unit type to represent an unparsed
stream of CSS tokens as a specified value. This is what properties
that have a variable reference get as their specified value.
On the nsCSSValueTokenStream object that is used when mUnit ==
eCSSUnit_TokenStream, we store two property IDs: first, the property
ID for the longhand that this token stream value is the value for. We
pass this back in to nsCSSParser::ParseProperty at computed value time,
when we need to re-parse the property. Second is the shorthand property
ID, if we used a variable reference in a shorthand. In such a case, we
store the token stream value for each of the corresponding longhand
properties. This is because shorthands don't actually get any storage
in an nsRuleData, and because any of the longhands might be overwritten
by subsequent declarations, we need to keep the token stream somewhere.
We also store other information on the nsCSSValueTokenStream required by
the CSS parser (base URI, etc.).
This is the first part of handling variable references in regular
properties. We have the scanner set a flag whenever it returns a "var("
token, so that when we come to the end of parsing a property that
failed, we know that it is because of a variable reference.
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 defines a class CSSVariableValues which is used to store
computed variable values. We store them a bit differently from
CSSVariableDeclarations -- here we have a hash table of variable names
to integer IDs, and then an array of variables where the array index
is the ID. This is because later on we'll want a stable order for the
variables to return from DOM APIs.
In addition to the string value of the variable, we store the type
of the first and last token of the variable value. This information
will be used when resolving entire variable reference containing
values, to determine when to insert "/**/" before and after a resolved
var(blah) token.
We add a CSSVariableValues member to nsStyleVariables.
This adds an enum to nsCSSScanner.h that represents the types of tokens
we need to consider when pasting together two adjacent tokens during
serialization or variable resolution. For example with:
var-a:orange;
var-b:red;
color:var(a)var(b);
we need to generate the string "orange/**/red" to parse for the value of
'color'.
This adds a CSSVariableDeclarations object to nsRuleData and adds a
MapRuleInfoInto function to CSSVariableDeclarations so the can copy
variable declarations into a nsRuleData's object. We call that from
Declaration::Map{Normal,Important}RuleInfoInto.
We make HasImportantData return true if we have important variables
but no important non-custom properties on a declaration, since that
is used to determine whether we have a rule node for important
declarations. This means MapImportantRuleInfoInto can no longer
assume that mImportantData is non-null.
This adds an nsStyleVariables on which computed variable values
will be stored. We don't actually have any properties assigned to
nsStyleVariables; eCSSPropertyExtra_Variables which we added earlier
isn't a real property. To avoid compiler errors for gVariableFlags
being a zero length array, we stick a dummy entry in there.
nsRuleNode::ComputeVariablesData does nothing for the moment.
nsStyleVariable nsChangeHint calculations always return 0, as later
we will compare the actual properties that reference variables to
see what changes are required for them.