Bug 1562086 - Add percentage for opacity (i.e. <alpha-value>). r=emilio

The following properties accept <alpha-value> [1], which is
"<number> | <percentage>", so we update the parser, spec links, and
their web-platform-tests.
1. opacity
2. flood-opacity
3. fill-opacity
4. stroke-opacity
5. stop-opacity
6. -moz-window-opacity

Besides, shape-image-threshold [2] still only accepts <number>, so we need
to support a different version of `Opacity::parse()`.

[1] https://drafts.csswg.org/css-color/#typedef-alpha-value
[2] https://drafts.csswg.org/css-shapes/#shape-image-threshold-property

Differential Revision: https://phabricator.services.mozilla.com/D37493

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Chiou 2019-07-12 19:49:32 +00:00
Родитель b1eb1b43ef
Коммит e801f9fefa
22 изменённых файлов: 91 добавлений и 74 удалений

Просмотреть файл

@ -6659,8 +6659,9 @@ var gCSSProperties = {
"3e0",
"3e+0",
"3e-0",
"300%",
],
other_values: ["0", "0.4", "0.0000", "-3", "3e-1"],
other_values: ["0", "0.4", "0.0000", "-3", "3e-1", "-100%", "50%"],
invalid_values: ["0px", "1px"],
},
"-moz-orient": {
@ -8192,11 +8193,13 @@ var gCSSProperties = {
domProp: "fillOpacity",
inherited: true,
type: CSS_TYPE_LONGHAND,
initial_values: ["1", "2.8", "1.000"],
initial_values: ["1", "2.8", "1.000", "300%"],
other_values: [
"0",
"0.3",
"-7.3",
"-100%",
"50%",
"context-fill-opacity",
"context-stroke-opacity",
],
@ -8463,8 +8466,8 @@ var gCSSProperties = {
domProp: "floodOpacity",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["1", "2.8", "1.000"],
other_values: ["0", "0.3", "-7.3"],
initial_values: ["1", "2.8", "1.000", "300%"],
other_values: ["0", "0.3", "-7.3", "-100%", "50%"],
invalid_values: [],
},
"image-orientation": {
@ -8651,8 +8654,8 @@ var gCSSProperties = {
domProp: "stopOpacity",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: ["1", "2.8", "1.000"],
other_values: ["0", "0.3", "-7.3"],
initial_values: ["1", "2.8", "1.000", "300%"],
other_values: ["0", "0.3", "-7.3", "-100%", "50%"],
invalid_values: [],
},
stroke: {
@ -8730,11 +8733,13 @@ var gCSSProperties = {
domProp: "strokeOpacity",
inherited: true,
type: CSS_TYPE_LONGHAND,
initial_values: ["1", "2.8", "1.000"],
initial_values: ["1", "2.8", "1.000", "300%"],
other_values: [
"0",
"0.3",
"-7.3",
"-100%",
"50%",
"context-fill-opacity",
"context-stroke-opacity",
],
@ -12507,8 +12512,9 @@ if (false) {
"3e0",
"3e+0",
"3e-0",
"300%",
],
other_values: ["0", "0.4", "0.0000", "-3", "3e-1"],
other_values: ["0", "0.4", "0.0000", "-3", "3e-1", "-100%", "50%"],
invalid_values: ["0px", "1px", "20%", "default", "auto"],
};

Просмотреть файл

@ -601,8 +601,10 @@ ${helpers.predefined_type(
spec="https://drafts.csswg.org/css-will-change/#will-change",
)}
// The spec issue for the parse_method: https://github.com/w3c/csswg-drafts/issues/4102.
${helpers.predefined_type(
"shape-image-threshold", "Opacity", "0.0",
parse_method="parse_number",
products="gecko",
animation_value_type="ComputedValue",
spec="https://drafts.csswg.org/css-shapes/#shape-image-threshold-property",

Просмотреть файл

@ -13,7 +13,7 @@ ${helpers.predefined_type(
"1.0",
animation_value_type="ComputedValue",
flags="CREATES_STACKING_CONTEXT CAN_ANIMATE_ON_COMPOSITOR",
spec="https://drafts.csswg.org/css-color/#opacity",
spec="https://drafts.csswg.org/css-color/#transparency",
servo_restyle_damage = "reflow_out_of_flow",
)}

Просмотреть файл

@ -52,7 +52,7 @@ ${helpers.predefined_type(
"Default::default()",
products="gecko",
animation_value_type="ComputedValue",
spec="https://www.w3.org/TR/SVG11/painting.html#FillOpacityProperty",
spec="https://svgwg.org/svg2-draft/painting.html#FillOpacity",
)}
${helpers.predefined_type(
@ -123,7 +123,7 @@ ${helpers.predefined_type(
"Default::default()",
products="gecko",
animation_value_type="ComputedValue",
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeOpacityProperty",
spec="https://svgwg.org/svg2-draft/painting.html#StrokeOpacity",
)}
${helpers.predefined_type(

Просмотреть файл

@ -40,7 +40,7 @@ ${helpers.predefined_type(
"1.0",
products="gecko",
animation_value_type="ComputedValue",
spec="https://www.w3.org/TR/SVGTiny12/painting.html#propdef-stop-opacity",
spec="https://svgwg.org/svg2-draft/pservers.html#StopOpacityProperty",
)}
// Section 15 - Filter Effects
@ -60,7 +60,7 @@ ${helpers.predefined_type(
"1.0",
products="gecko",
animation_value_type="ComputedValue",
spec="https://www.w3.org/TR/SVG/filters.html#FloodOpacityProperty",
spec="https://drafts.fxtf.org/filter-effects/#FloodOpacityProperty",
)}
${helpers.predefined_type(

Просмотреть файл

@ -142,8 +142,8 @@ fn parse_number_with_clamping_mode<'i, 't>(
value: value.min(f32::MAX).max(f32::MIN),
calc_clamping_mode: None,
});
},
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
}
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
ref t => return Err(location.new_unexpected_token_error(t.clone())),
}
@ -402,14 +402,18 @@ impl Parse for NonNegativeNumberOrPercentage {
}
}
#[allow(missing_docs)]
/// The value of Opacity is <alpha-value>, which is "<number> | <percentage>".
/// However, we serialize the specified value as number, so it's ok to store
/// the Opacity as Number.
#[derive(
Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, SpecifiedValueInfo, ToCss, ToShmem,
)]
pub struct Opacity(Number);
impl Parse for Opacity {
fn parse<'i, 't>(
impl Opacity {
/// Parse number value only.
#[inline]
pub fn parse_number<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
@ -417,6 +421,29 @@ impl Parse for Opacity {
}
}
impl Parse for Opacity {
/// Opacity accepts <number> | <percentage>, so we parse it as NumberOrPercentage,
/// and then convert into an Number if it's a Percentage.
/// https://drafts.csswg.org/cssom/#serializing-css-values
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
let number = match NumberOrPercentage::parse(context, input)? {
NumberOrPercentage::Percentage(p) => Number {
value: p.get(),
calc_clamping_mode: if p.is_calc() {
Some(AllowedNumericType::All)
} else {
None
},
},
NumberOrPercentage::Number(n) => n,
};
Ok(Opacity(number))
}
}
impl ToComputedValue for Opacity {
type ComputedValue = CSSFloat;
@ -510,7 +537,7 @@ impl Parse for Integer {
Token::Number {
int_value: Some(v), ..
} => return Ok(Integer::new(v)),
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {},
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}
ref t => return Err(location.new_unexpected_token_error(t.clone())),
}
@ -786,7 +813,7 @@ impl Attr {
None => {
return Err(location
.new_custom_error(StyleParseErrorKind::UnspecifiedError));
},
}
};
Some((prefix, ns))
} else {
@ -796,10 +823,10 @@ impl Attr {
namespace: prefix_and_ns,
attribute: Atom::from(second_token.as_ref()),
});
},
}
// In the case of attr(foobar ) we don't want to error out
// because of the trailing whitespace
Token::WhiteSpace(..) => {},
Token::WhiteSpace(..) => {}
ref t => return Err(input.new_unexpected_token_error(t.clone())),
}
}

Просмотреть файл

@ -1,10 +0,0 @@
[flood-opacity-valid.svg]
[e.style['flood-opacity'\] = "-100%" should set the property value]
expected: FAIL
[e.style['flood-opacity'\] = "50%" should set the property value]
expected: FAIL
[e.style['flood-opacity'\] = "300%" should set the property value]
expected: FAIL

Просмотреть файл

@ -1,10 +0,0 @@
[fill-opacity-valid.svg]
[e.style['fill-opacity'\] = "300%" should set the property value]
expected: FAIL
[e.style['fill-opacity'\] = "50%" should set the property value]
expected: FAIL
[e.style['fill-opacity'\] = "-100%" should set the property value]
expected: FAIL

Просмотреть файл

@ -1,10 +0,0 @@
[stroke-opacity-valid.svg]
[e.style['stroke-opacity'\] = "50%" should set the property value]
expected: FAIL
[e.style['stroke-opacity'\] = "-100%" should set the property value]
expected: FAIL
[e.style['stroke-opacity'\] = "300%" should set the property value]
expected: FAIL

Просмотреть файл

@ -1,10 +0,0 @@
[stop-opacity-valid.svg]
[e.style['stop-opacity'\] = "300%" should set the property value]
expected: FAIL
[e.style['stop-opacity'\] = "50%" should set the property value]
expected: FAIL
[e.style['stop-opacity'\] = "-100%" should set the property value]
expected: FAIL

Просмотреть файл

@ -27,6 +27,7 @@ test_computed_value("color", "#FEDCBA", "rgb(254, 220, 186)");
test_computed_value("color", "rgb(2, 3, 4)");
test_computed_value("color", "rgb(100%, 0%, 0%)", "rgb(255, 0, 0)");
test_computed_value("color", "rgba(2, 3, 4, 0.5)");
test_computed_value("color", "rgba(2, 3, 4, 50%)", "rgba(2, 3, 4, 0.5)");
test_computed_value("color", "hsl(120, 100%, 50%)", "rgb(0, 255, 0)");
test_computed_value("color", "hsla(120, 100%, 50%, 0.25)", "rgba(0, 255, 0, 0.25)");
test_computed_value("color", "rgb(-2, 3, 4)", "rgb(0, 3, 4)");

Просмотреть файл

@ -21,6 +21,7 @@ test_valid_value("color", "#FEDCBA", "rgb(254, 220, 186)");
test_valid_value("color", "rgb(2, 3, 4)");
test_valid_value("color", "rgb(100%, 0%, 0%)", "rgb(255, 0, 0)");
test_valid_value("color", "rgba(2, 3, 4, 0.5)"); // Safari serializes alpha-value 0.498039
test_valid_value("color", "rgba(2, 3, 4, 50%)", "rgba(2, 3, 4, 0.5)"); // Safari serializes alpha-value 0.498039
test_valid_value("color", "hsl(120, 100%, 50%)", ["rgb(0, 255, 0)", "hsl(120, 100%, 50%)"]);
test_valid_value("color", "hsla(120, 100%, 50%, 0.25)", ["rgba(0, 255, 0, 0.25)", "hsla(120, 100%, 50%, 0.25)"]); // Safari serializes alpha-value 0.247059
test_valid_value("color", "rgb(-2, 3, 4)", "rgb(0, 3, 4)");

Просмотреть файл

@ -16,6 +16,10 @@ test_computed_value("opacity", "0.5");
test_computed_value("opacity", "0");
test_computed_value("opacity", "-2", "0");
test_computed_value("opacity", "3", "1");
test_computed_value("opacity", "-100%", "0");
test_computed_value("opacity", "50%", "0.5");
test_computed_value("opacity", "300%", "1");
</script>
</body>
</html>

Просмотреть файл

@ -17,6 +17,10 @@ test_valid_value("opacity", "0.5");
test_valid_value("opacity", "0");
test_valid_value("opacity", "-2");
test_valid_value("opacity", "3");
test_valid_value("opacity", "-100%", "-1");
test_valid_value("opacity", "50%", "0.5");
test_valid_value("opacity", "300%", "3");
</script>
</body>
</html>

Просмотреть файл

@ -16,6 +16,9 @@
test_computed_value("flood-opacity", "-1", "0");
test_computed_value("flood-opacity", "0.5");
test_computed_value("flood-opacity", "3", "1");
test_computed_value("flood-opacity", "-100%", "0");
test_computed_value("flood-opacity", "50%", "0.5");
test_computed_value("flood-opacity", "300%", "1");
]]></script>
</svg>

До

Ширина:  |  Высота:  |  Размер: 819 B

После

Ширина:  |  Высота:  |  Размер: 974 B

Просмотреть файл

@ -16,9 +16,9 @@
test_valid_value("flood-opacity", "-1");
test_valid_value("flood-opacity", "0.5");
test_valid_value("flood-opacity", "3");
test_valid_value("flood-opacity", "-100%");
test_valid_value("flood-opacity", "50%");
test_valid_value("flood-opacity", "300%");
test_valid_value("flood-opacity", "-100%", "-1");
test_valid_value("flood-opacity", "50%", "0.5");
test_valid_value("flood-opacity", "300%", "3");
]]></script>
</svg>

До

Ширина:  |  Высота:  |  Размер: 931 B

После

Ширина:  |  Высота:  |  Размер: 949 B

Просмотреть файл

@ -16,6 +16,9 @@
test_computed_value("fill-opacity", "-1", "0");
test_computed_value("fill-opacity", "0.5");
test_computed_value("fill-opacity", "3", "1");
test_computed_value("fill-opacity", "-100%", "0");
test_computed_value("fill-opacity", "50%", "0.5");
test_computed_value("fill-opacity", "300%", "1");
]]></script>
</svg>

До

Ширина:  |  Высота:  |  Размер: 790 B

После

Ширина:  |  Высота:  |  Размер: 942 B

Просмотреть файл

@ -16,9 +16,9 @@
test_valid_value("fill-opacity", "-1");
test_valid_value("fill-opacity", "0.5");
test_valid_value("fill-opacity", "3");
test_valid_value("fill-opacity", "-100%");
test_valid_value("fill-opacity", "50%");
test_valid_value("fill-opacity", "300%");
test_valid_value("fill-opacity", "-100%", "-1");
test_valid_value("fill-opacity", "50%", "0.5");
test_valid_value("fill-opacity", "300%", "3");
]]></script>
</svg>

До

Ширина:  |  Высота:  |  Размер: 907 B

После

Ширина:  |  Высота:  |  Размер: 925 B

Просмотреть файл

@ -16,6 +16,9 @@
test_computed_value("stroke-opacity", "-1", "0");
test_computed_value("stroke-opacity", "0.5");
test_computed_value("stroke-opacity", "3", "1");
test_computed_value("stroke-opacity", "-100%", "0");
test_computed_value("stroke-opacity", "50%", "0.5");
test_computed_value("stroke-opacity", "300%", "1");
]]></script>
</svg>

До

Ширина:  |  Высота:  |  Размер: 810 B

После

Ширина:  |  Высота:  |  Размер: 968 B

Просмотреть файл

@ -16,9 +16,9 @@
test_valid_value("stroke-opacity", "-1");
test_valid_value("stroke-opacity", "0.5");
test_valid_value("stroke-opacity", "3");
test_valid_value("stroke-opacity", "-100%");
test_valid_value("stroke-opacity", "50%");
test_valid_value("stroke-opacity", "300%");
test_valid_value("stroke-opacity", "-100%", "-1");
test_valid_value("stroke-opacity", "50%", "0.5");
test_valid_value("stroke-opacity", "300%", "3");
]]></script>
</svg>

До

Ширина:  |  Высота:  |  Размер: 925 B

После

Ширина:  |  Высота:  |  Размер: 943 B

Просмотреть файл

@ -16,6 +16,9 @@
test_computed_value("stop-opacity", "-1", "0");
test_computed_value("stop-opacity", "0.5");
test_computed_value("stop-opacity", "3", "1");
test_computed_value("stop-opacity", "-100%", "0");
test_computed_value("stop-opacity", "50%", "0.5");
test_computed_value("stop-opacity", "300%", "1");
]]></script>
</svg>

До

Ширина:  |  Высота:  |  Размер: 803 B

После

Ширина:  |  Высота:  |  Размер: 955 B

Просмотреть файл

@ -16,9 +16,9 @@
test_valid_value("stop-opacity", "-1");
test_valid_value("stop-opacity", "0.5");
test_valid_value("stop-opacity", "3");
test_valid_value("stop-opacity", "-100%");
test_valid_value("stop-opacity", "50%");
test_valid_value("stop-opacity", "300%");
test_valid_value("stop-opacity", "-100%", "-1");
test_valid_value("stop-opacity", "50%", "0.5");
test_valid_value("stop-opacity", "300%", "3");
]]></script>
</svg>

До

Ширина:  |  Высота:  |  Размер: 912 B

После

Ширина:  |  Высота:  |  Размер: 930 B