Closed
Bug 1385139
Opened 7 years ago
Closed 7 years ago
stylo: CSS variables not resolved in values returned by getKeyframes()
Categories
(Core :: CSS Parsing and Computation, defect, P3)
Core
CSS Parsing and Computation
Tracking
()
RESOLVED
FIXED
mozilla57
Tracking | Status | |
---|---|---|
firefox57 | --- | fixed |
People
(Reporter: birtles, Assigned: birtles)
References
(Blocks 1 open bug)
Details
Attachments
(5 files)
Running dom/animation/test/css-animations/test_keyframeeffect-getkeyframes.html on a Stylo build from yesterday's m-c, I get the following failures:
#1: KeyframeEffectReadOnly.getKeyframes() returns expected values for animations with CSS variables as keyframe values
assert_equals: value for 'transform' on ComputedKeyframe #1 expected "translate(100px, 0px)" but got " translate(var(--var-100px), 0) "
#2: KeyframeEffectReadOnly.getKeyframes() returns expected values for animations with CSS variables as keyframe values in a shorthand property
assert_equals: value for 'marginTop' on ComputedKeyframe #1 expected "100px" but got ""
Updated•7 years ago
|
Assignee: nobody → boris.chiou
Assignee | ||
Comment 1•7 years ago
|
||
I'm not sure if this just effects getKeyframes() or if it actually affects the visual result. Setting P2 for now but we might downgrade it later if it only affects getKeyframes().
Priority: -- → P2
Comment 2•7 years ago
|
||
(In reply to Brian Birtles (:birtles, away 31 July~7 Aug) from comment #1)
> I'm not sure if this just effects getKeyframes() or if it actually affects
> the visual result. Setting P2 for now but we might downgrade it later if it
> only affects getKeyframes().
I just checked this. Looks like the visual result is correct: we create a css animation with the correct property value, so I think this only affects getKeyframes().
Assignee | ||
Comment 3•7 years ago
|
||
Marking this as P3 since the visual result is correct. It would be really good to fix this since although we don't ship getKeyframes() it affects the tooltips reported by DevTools. It would be odd for those to report `translate(var(--var-100px), 0)` but that shouldn't block shipping Stylo.
Priority: P2 → P3
Assignee | ||
Comment 4•7 years ago
|
||
I spent a while trying to work out where we compute values before making up CSS keyframes but then I realized we don't. Apparently in bug 1358353 we decided just to keep specified values.
However, I'm concerned that without doing this, there may be bugs when variables are used in shorthands and we fail to overlap them correctly.
Comment 5•7 years ago
|
||
So what we should do for CSS animations is that when we get a DeclarationBlock in Servo_StyleSet_GetKeyframesForName (which is used only for CSS animations), if the DeclarationBlock is WithVariables we need to resolve the variables with substitute_variables (if I recall its purpose correctly).
Assignee | ||
Comment 6•7 years ago
|
||
Yes, that sounds right. Thanks!
Assignee | ||
Comment 7•7 years ago
|
||
Assignee | ||
Comment 8•7 years ago
|
||
Assignee | ||
Comment 9•7 years ago
|
||
I went ahead and expanded the custom properties in Servo_StyleSet_GetKeyframesForName (attachment 8898604 [details] [diff] [review]) and the tests here pass.
However, it introduces another bug. In attachment 8898605 [details] we change custom properties mid-way through an animation. With this patch applied nothing causes us to call Servo_StyleSet_GetKeyframesForName when the variable changes and hence we keep animating with the old values. Without this patch, however, it works.
Some background to this bug:
* Originally we decided to expand shorthands to longhands because of the complications involved in mapping
a declaration block to Web Animations' format seemed too complicated.[1]
* Subsequently when we encountered variables we decided in order to map them to longhands we should just
convert them to computed values (and for consistency we do the same for property values that don't use
variables). (See bug 1268858 comment 19.)
* In Servo we map to longhands but for custom properties we store their values as unparsed values. So, if you
have `margin: var(--yer)` then internally we store:
margin-left: (unparsed value)
margin-top: (unparsed value)
margin-right: (unparsed value)
margin-bottom: (unparsed value)
which we'll serialize as:
marginLeft: '',
marginTop: '',
marginRight: '',
marginBottom: '',
So, the visual result is correct, and since we internally store the variable reference, when variables
change the animation updates (presumably we *do* regenerate the computed property values even though we
don't regenerate the specified keyframes).
Now a few observations:
* Expanding CSS declaration blocks to longhands with computed values seems sub-optimal from an authoring point
of view. In future I'd like to reconsider if we can keep shorthands in @keyframes when we set up Keyframe
objects.
* (Related, but somewhat separate to the above point, I wonder if, once we've dropped the Gecko style system
if we could just store all the property values for a Keyframe in a single declaration block and then just
convert to-and-from the declaration block at the point where we get/set keyframes from the API.)
* Similarly, it would be preferable if we don't need to convert specified values to computed values.
* The values returned by getKeyframes() for CSS animations are not really exposed anywhere.
- We don't ship `getKeyframes()` to release channel
- When we do ship `getKeyframes()` we still won't ship CSSAnimation objects for quite some time
- DevTools uses `getProperties()` when available NOT `getKeyframes()`[2]
Some options for fixing this:
a. Make us regenerate keyframes for CSS when variables change (presumably Gecko does this)
b. Skip those tests for Stylo
c. Make the tests check for the Stylo values
d. Resolve the variables in GetKeyframes() only
I don't want to do (a). It sounds very wasteful.
(b) and (c) are based on the assumption that we will eventually change this behavior anyway so we shouldn't waste time on it. I'm not totally sure about them, however, since this seems oddly inconsistent.
I'll try (d) and if it proves difficult I might just give up and do (c).
[1] http://searchfox.org/mozilla-central/rev/e8c36327cd8c9432c69e5e1383156a74330f11f2/layout/style/nsAnimationManager.cpp#635-677
[2] http://searchfox.org/mozilla-central/rev/e8c36327cd8c9432c69e5e1383156a74330f11f2/devtools/client/animationinspector/components/animation-timeline.js#683
Assignee | ||
Updated•7 years ago
|
Assignee: boris.chiou → bbirtles
Status: NEW → ASSIGNED
Comment 10•7 years ago
|
||
Thanks for taking this, Brian. :)
Assignee | ||
Comment 11•7 years ago
|
||
WIP patch for serializing on output:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=8707eb75fb9c8230b4164f3c5daba8669a4a60cb
Try run with unsuccessful approach to see if we have any tests covering this:
https://treeherder.mozilla.org/#/jobs?repo=try&revision=fa4a442538e096ef91ba9af0fb12fa19256643f4
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 14•7 years ago
|
||
mozreview-review |
Comment on attachment 8899303 [details]
Bug 1385139 - Add test for changes to CSS variables;
https://reviewboard.mozilla.org/r/170524/#review175682
::: layout/style/test/test_animations_variable_changes.html:23
(Diff revision 1)
> + const div = document.createElement('div');
> + document.body.append(div);
Nit: We can use addDiv() here and drop div.remove() at the end of this test.
::: layout/style/test/test_animations_variable_changes.html:39
(Diff revision 1)
> +
> + div.remove();
> +}, 'Animation reflects changes to custom properties');
> +
> +test(() => {
> + const parent = document.createElement('div');
Nit: We can use addDivi() for 'parent' too.
Attachment #8899303 -
Flags: review?(hikezoe) → review+
Assignee | ||
Comment 15•7 years ago
|
||
We don't have addDiv in layout/style/test
Comment 16•7 years ago
|
||
Oh nvm, I thought the test in dom/animation/test.
Comment 17•7 years ago
|
||
mozreview-review |
Comment on attachment 8899304 [details]
Bug 1385139 - Expand var() references in keyframes from CSS animations when serializing;
https://reviewboard.mozilla.org/r/170526/#review175690
::: dom/animation/KeyframeEffectReadOnly.cpp:1225
(Diff revision 1)
> + // The following will flush style but that's ok since if you update
> + // a variable's computed value, you expect to see that updated value in the
> + // result of getKeyframes().
> + //
Just as a side note that we should keep in mind about flushing style. Flushing style might destroy pres shell, so if it happens, rest of codes in this function will be run without pres shell. nsComputedDOMStyle::GetStyleContext() (which is called from GetTargetStyleContext) holds a reference of nsIPresShell so it's safe in the function but after GetTargetStyleContext in this function, there is no guarantee that we have valid pres shell. For now there is no such risk in this function, just a thing I am concerned.
::: servo/components/style/properties/declaration_block.rs:521
(Diff revision 1)
> }
> removed_at_least_one
> }
>
> /// Take a declaration block known to contain a single property and serialize it.
> - pub fn single_value_to_css<W>(&self, property: &PropertyId, dest: &mut W) -> fmt::Result
> + pub fn single_value_to_css<W>(
Can we mark this function as gecko only?
::: servo/components/style/properties/declaration_block.rs:545
(Diff revision 1)
> + (&PropertyDeclaration::WithVariables(id, ref unparsed),
> + Some(ref computed_values)) => unparsed
> + .substitute_variables(
> + id,
> + &computed_values.custom_properties(),
> + QuirksMode::NoQuirks,
Actually it may not be a problem but I guess we should pass mElement->OwnerDoc()->GetCompatibilityMode() to this quirk mode?
Attachment #8899304 -
Flags: review?(hikezoe) → review+
Assignee | ||
Comment 18•7 years ago
|
||
(In reply to Hiroyuki Ikezoe (:hiro) from comment #17)
> ::: servo/components/style/properties/declaration_block.rs:521
> (Diff revision 1)
> > }
> > removed_at_least_one
> > }
> >
> > /// Take a declaration block known to contain a single property and serialize it.
> > - pub fn single_value_to_css<W>(&self, property: &PropertyId, dest: &mut W) -> fmt::Result
> > + pub fn single_value_to_css<W>(
>
> Can we mark this function as gecko only?
I think it's ok as-is? The added code only takes effect if a ComputedValues is passed-in and when it's not passed-in, I think the behavior is sensible for the Servo case too.
> ::: servo/components/style/properties/declaration_block.rs:545
> (Diff revision 1)
> > + (&PropertyDeclaration::WithVariables(id, ref unparsed),
> > + Some(ref computed_values)) => unparsed
> > + .substitute_variables(
> > + id,
> > + &computed_values.custom_properties(),
> > + QuirksMode::NoQuirks,
>
> Actually it may not be a problem but I guess we should pass
> mElement->OwnerDoc()->GetCompatibilityMode() to this quirk mode?
Yeah, originally I did that but then I found that in a lot of similar call sites we were hard-coding eCompatibility_FullStandards further up the stack anyway. In the end I decided it wasn't worth the complexity to pass it down, especially since this is only used in code that is disabled on release builds.
Assignee | ||
Comment 19•7 years ago
|
||
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 22•7 years ago
|
||
Pushed by bbirtles@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/36e73b132139
Add test for changes to CSS variables; r=hiro
https://hg.mozilla.org/integration/autoland/rev/575d130ab5f6
Expand var() references in keyframes from CSS animations when serializing; r=hiro
Comment 23•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/36e73b132139
https://hg.mozilla.org/mozilla-central/rev/575d130ab5f6
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
status-firefox57:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla57
You need to log in
before you can comment on or make changes to this bug.
Description
•