Bug 1805727 - Part 2: Add transition-behavior to transition shorthand in style. r=emilio

Per spec, we put `transition-behavior` last in `transition`.

https://drafts.csswg.org/css-transitions-2/#transition-shorthand-property

Differential Revision: https://phabricator.services.mozilla.com/D200409
This commit is contained in:
Boris Chiou 2024-02-23 21:41:48 +00:00
parent 9f6a2b2041
commit e40e3017a3
8 changed files with 64 additions and 91 deletions

View File

@ -3,6 +3,7 @@ prefs = [
"layout.css.basic-shape-rect.enabled=true",
"layout.css.basic-shape-xywh.enabled=true",
"layout.css.properties-and-values.enabled=true",
"layout.css.transition-behavior.enabled=true",
"dom.customHighlightAPI.enabled=true",
]
support-files = [

View File

@ -145,7 +145,7 @@ function do_test() {
var values = InspectorUtils.getCSSValuesForProperty(prop);
var expected = [ "initial", "all", "unset", "cubic-bezier", "ease", "ease-in", "ease-in-out",
"ease-out", "inherit", "revert", "revert-layer", "linear", "none", "step-end", "step-start",
"steps" ];
"steps", "normal", "allow-discrete" ];
ok(testValues(values, expected), "property transition's values.");
// test invalid property

View File

@ -14100,6 +14100,22 @@ if (IsCSSPropertyPrefEnabled("layout.css.transition-behavior.enabled")) {
invalid_values: ["none", "auto", "discrete"],
},
});
gCSSProperties["transition"].subproperties.push("transition-behavior");
gCSSProperties["transition"].initial_values.push("normal");
gCSSProperties["transition"].other_values.push(
"allow-discrete",
"width allow-discrete",
"1s allow-discrete",
"linear allow-discrete"
);
gCSSProperties["-webkit-transition"].subproperties.push(
"transition-behavior"
);
if (IsCSSPropertyPrefEnabled("layout.css.prefixes.transitions")) {
gCSSProperties["-moz-transition"].subproperties.push("transition-behavior");
}
}
// Copy aliased properties' fields from their alias targets. Keep this logic

View File

@ -183,17 +183,19 @@ e.setAttribute("style", "background-position-x: 0px; background-position-y: top
is(e.style.backgroundPosition, "left 0px top 0px", "should serialize to 4-value form if 3-value form would only have one edge");
// Check that we only serialize transition when the lists are the same length.
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s");
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s; transition-behavior: normal, allow-discrete;");
isnot(e.style.transition, "", "should have transition shorthand (lists same length)");
e.setAttribute("style", "transition-property: color, width, left; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s");
e.setAttribute("style", "transition-property: color, width, left; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s; transition-behavior: normal, allow-discrete;");
is(e.style.transition, "", "should not have transition shorthand (lists different lengths)");
e.setAttribute("style", "transition-property: all; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s");
e.setAttribute("style", "transition-property: all; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s; transition-behavior: normal, allow-discrete;");
is(e.style.transition, "", "should not have transition shorthand (lists different lengths)");
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms, 300ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s");
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms, 300ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s; transition-behavior: normal, allow-discrete;");
is(e.style.transition, "", "should not have transition shorthand (lists different lengths)");
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear, ease-out; transition-delay: 0s, 1s");
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear, ease-out; transition-delay: 0s, 1s; transition-behavior: normal, allow-discrete;");
is(e.style.transition, "", "should not have transition shorthand (lists different lengths)");
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s, 0s");
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s, 0s; transition-behavior: normal, allow-discrete;");
is(e.style.transition, "", "should not have transition shorthand (lists different lengths)");
e.setAttribute("style", "transition-property: color, width; transition-duration: 1s, 200ms; transition-timing-function: ease-in, linear; transition-delay: 0s, 1s; transition-behavior: normal, allow-discrete, normal;");
is(e.style.transition, "", "should not have transition shorthand (lists different lengths)");
e.setAttribute("style", "transition: color, width; transition-delay: 0s");
is(e.style.transition, "", "should not have transition shorthand (lists different lengths)");

View File

@ -22,10 +22,10 @@ macro_rules! try_parse_one {
extra_prefixes="moz:layout.css.prefixes.transitions webkit"
sub_properties="transition-property transition-duration
transition-timing-function
transition-delay"
transition-delay transition-behavior"
spec="https://drafts.csswg.org/css-transitions/#propdef-transition">
use crate::parser::Parse;
% for prop in "delay duration property timing_function".split():
% for prop in "delay duration property timing_function behavior".split():
use crate::properties::longhands::transition_${prop};
% endfor
use crate::values::specified::TransitionProperty;
@ -35,7 +35,7 @@ macro_rules! try_parse_one {
input: &mut Parser<'i, 't>,
) -> Result<Longhands, ParseError<'i>> {
struct SingleTransition {
% for prop in "property duration timing_function delay".split():
% for prop in "property duration timing_function delay behavior".split():
transition_${prop}: transition_${prop}::SingleSpecifiedValue,
% endfor
}
@ -45,7 +45,7 @@ macro_rules! try_parse_one {
input: &mut Parser<'i, 't>,
first: bool,
) -> Result<SingleTransition,ParseError<'i>> {
% for prop in "property duration timing_function delay".split():
% for prop in "property duration timing_function delay behavior".split():
let mut ${prop} = None;
% endfor
@ -56,6 +56,9 @@ macro_rules! try_parse_one {
try_parse_one!(context, input, duration, transition_duration);
try_parse_one!(context, input, timing_function, transition_timing_function);
try_parse_one!(context, input, delay, transition_delay);
if static_prefs::pref!("layout.css.transition-behavior.enabled") {
try_parse_one!(context, input, behavior, transition_behavior);
}
// Must check 'transition-property' after 'transition-timing-function' since
// 'transition-property' accepts any keyword.
if property.is_none() {
@ -78,7 +81,7 @@ macro_rules! try_parse_one {
if parsed != 0 {
Ok(SingleTransition {
% for prop in "property duration timing_function delay".split():
% for prop in "property duration timing_function delay behavior".split():
transition_${prop}: ${prop}.unwrap_or_else(transition_${prop}::single_value
::get_initial_specified_value),
% endfor
@ -88,7 +91,7 @@ macro_rules! try_parse_one {
}
}
% for prop in "property duration timing_function delay".split():
% for prop in "property duration timing_function delay behavior".split():
let mut ${prop}s = Vec::new();
% endfor
@ -105,13 +108,13 @@ macro_rules! try_parse_one {
Ok(transition)
})?;
for result in results {
% for prop in "property duration timing_function delay".split():
% for prop in "property duration timing_function delay behavior".split():
${prop}s.push(result.transition_${prop});
% endfor
}
Ok(expanded! {
% for prop in "property duration timing_function delay".split():
% for prop in "property duration timing_function delay behavior".split():
transition_${prop}: transition_${prop}::SpecifiedValue(${prop}s.into()),
% endfor
})
@ -133,12 +136,24 @@ macro_rules! try_parse_one {
return Ok(());
}
% endfor
if let Some(behavior) = self.transition_behavior {
if behavior.0.len() != 1 {
return Ok(());
}
}
} else {
% for name in "duration delay timing_function".split():
if self.transition_${name}.0.len() != property_len {
return Ok(());
}
% endfor
if let Some(behavior) = self.transition_behavior {
if behavior.0.len() != property_len {
return Ok(());
}
}
}
// Representative length.
@ -152,7 +167,11 @@ macro_rules! try_parse_one {
let has_duration = !self.transition_duration.0[i].is_zero();
let has_timing = !self.transition_timing_function.0[i].is_ease();
let has_delay = !self.transition_delay.0[i].is_zero();
let has_any = has_duration || has_timing || has_delay;
let has_behavior = match self.transition_behavior {
Some(behavior) => !behavior.0[i].is_normal(),
_ => false,
};
let has_any = has_duration || has_timing || has_delay || has_behavior;
let mut writer = SequenceWriter::new(dest, " ");
@ -174,6 +193,10 @@ macro_rules! try_parse_one {
if has_delay {
writer.item(&self.transition_delay.0[i])?;
}
if has_behavior {
writer.item(&self.transition_behavior.unwrap().0[i])?;
}
}
Ok(())
}

View File

@ -141,6 +141,12 @@ impl TransitionBehavior {
pub fn normal() -> Self {
Self::Normal
}
/// Return true if it is normal.
#[inline]
pub fn is_normal(&self) -> bool {
matches!(*self, Self::Normal)
}
}
/// https://drafts.csswg.org/css-animations/#animation-iteration-count

View File

@ -1,66 +0,0 @@
[transition-behavior.html]
[e.style['transition'\] = "allow-discrete display" should set the property value]
expected: FAIL
[Property transition value 'allow-discrete display']
expected: FAIL
[e.style['transition'\] = "allow-discrete display 3s" should set the property value]
expected: FAIL
[Property transition value 'allow-discrete display 3s']
expected: FAIL
[e.style['transition'\] = "allow-discrete display 3s 1s" should set the property value]
expected: FAIL
[Property transition value 'allow-discrete display 3s 1s']
expected: FAIL
[e.style['transition'\] = "allow-discrete display 3s ease-in-out" should set the property value]
expected: FAIL
[Property transition value 'allow-discrete display 3s ease-in-out']
expected: FAIL
[e.style['transition'\] = "allow-discrete display 3s ease-in-out 1s" should set the property value]
expected: FAIL
[Property transition value 'allow-discrete display 3s ease-in-out 1s']
expected: FAIL
[e.style['transition'\] = "display allow-discrete 3s ease-in-out 1s" should set the property value]
expected: FAIL
[e.style['transition'\] = "display 3s allow-discrete ease-in-out 1s" should set the property value]
expected: FAIL
[e.style['transition'\] = "display 3s ease-in-out allow-discrete 1s" should set the property value]
expected: FAIL
[e.style['transition'\] = "display 3s ease-in-out 1s allow-discrete" should set the property value]
expected: FAIL
[Property transition value 'display allow-discrete 3s ease-in-out 1s']
expected: FAIL
[Property transition value 'display 3s allow-discrete ease-in-out 1s']
expected: FAIL
[Property transition value 'display 3s ease-in-out allow-discrete 1s']
expected: FAIL
[Property transition value 'display 3s ease-in-out 1s allow-discrete']
expected: FAIL
[e.style['transition'\] = "allow-discrete display, normal opacity, color" should set the property value]
expected: FAIL
[Property transition value 'allow-discrete display, normal opacity, color']
expected: FAIL
[e.style['transition'\] = "normal opacity, color, allow-discrete display" should set the property value]
expected: FAIL
[Property transition value 'normal opacity, color, allow-discrete display']
expected: FAIL

View File

@ -1,9 +0,0 @@
[transition-shorthand.html]
[e.style['transition'\] = "1s -3s cubic-bezier(0, -2, 1, 3) top" should set transition-behavior]
expected: FAIL
[e.style['transition'\] = "1s -3s, cubic-bezier(0, -2, 1, 3) top" should set transition-behavior]
expected: FAIL
[e.style['transition'\] = "cubic-bezier(0, -2, 1, 3) top, 1s -3s" should set transition-behavior]
expected: FAIL