Commit baaab7ff authored by Eric Willigers's avatar Eric Willigers Committed by Commit Bot

CSS: opacity properties accept percentage

The following properties accept either a number or a percentage:
- fill-opacity
- flood-opacity
- opacity
- shape-image-threshold
- stop-opacity
- stroke-opacity

Each property serializes as a number.

Spec:
https://drafts.csswg.org/css-color/#typedef-alpha-value

Intent to Implement and Ship:
https://groups.google.com/a/chromium.org/d/msg/blink-dev/SdPIaBdhzAQ/f26Mp_3REAAJ

Credit to hanlee.dev@gmail.com for uploading a patch.

Bug: 907787
Change-Id: Ie297d7225becafde73449c35bcb719c4847c87d2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1734753
Commit-Queue: Emil A Eklund <eae@chromium.org>
Auto-Submit: Eric Willigers <ericwilligers@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#684459}
parent 0734535c
......@@ -414,6 +414,17 @@ CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange& range,
return nullptr;
}
CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange& range) {
if (CSSPrimitiveValue* value = ConsumeNumber(range, kValueRangeAll)) {
return value;
}
if (CSSPrimitiveValue* value = ConsumePercent(range, kValueRangeAll)) {
return CSSNumericLiteralValue::Create(value->GetDoubleValue() / 100.0,
CSSPrimitiveValue::UnitType::kNumber);
}
return nullptr;
}
bool CanConsumeCalcValue(CalculationCategory category,
CSSParserMode css_parser_mode) {
if (category == kCalcLength || category == kCalcPercent ||
......
......@@ -59,6 +59,7 @@ CSSPrimitiveValue* ConsumeLength(CSSParserTokenRange&,
ValueRange,
UnitlessQuirk = UnitlessQuirk::kForbid);
CSSPrimitiveValue* ConsumePercent(CSSParserTokenRange&, ValueRange);
CSSPrimitiveValue* ConsumeAlphaValue(CSSParserTokenRange&);
CSSPrimitiveValue* ConsumeLengthOrPercent(
CSSParserTokenRange&,
CSSParserMode,
......
......@@ -2302,7 +2302,7 @@ const CSSValue* FillOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
return css_property_parser_helpers::ConsumeAlphaValue(range);
}
const CSSValue* FillOpacity::CSSValueFromComputedStyleInternal(
......@@ -2444,7 +2444,7 @@ const CSSValue* FloodOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
return css_property_parser_helpers::ConsumeAlphaValue(range);
}
const CSSValue* FloodOpacity::CSSValueFromComputedStyleInternal(
......@@ -4211,7 +4211,7 @@ const CSSValue* OffsetRotate::CSSValueFromComputedStyleInternal(
const CSSValue* Opacity::ParseSingleValue(CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
return css_property_parser_helpers::ConsumeAlphaValue(range);
}
const CSSValue* Opacity::CSSValueFromComputedStyleInternal(
......@@ -5353,7 +5353,7 @@ const CSSValue* ShapeImageThreshold::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
return css_property_parser_helpers::ConsumeAlphaValue(range);
}
const CSSValue* ShapeImageThreshold::CSSValueFromComputedStyleInternal(
......@@ -5596,7 +5596,7 @@ const CSSValue* StopOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
return css_property_parser_helpers::ConsumeAlphaValue(range);
}
const CSSValue* StopOpacity::CSSValueFromComputedStyleInternal(
......@@ -5709,7 +5709,7 @@ const CSSValue* StrokeOpacity::ParseSingleValue(
CSSParserTokenRange& range,
const CSSParserContext& context,
const CSSParserLocalContext&) const {
return css_property_parser_helpers::ConsumeNumber(range, kValueRangeAll);
return css_property_parser_helpers::ConsumeAlphaValue(range);
}
const CSSValue* StrokeOpacity::CSSValueFromComputedStyleInternal(
......
This is a testharness.js-based test.
PASS e.style['opacity'] = "1" should set the property value
PASS e.style['opacity'] = "0.5" should set the property value
PASS e.style['opacity'] = "0" should set the property value
PASS e.style['opacity'] = "-2" should set the property value
PASS e.style['opacity'] = "3" should set the property value
FAIL e.style['opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['opacity'] = "300%" should set the property value assert_not_equals: property should be set got disallowed value ""
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property shape-image-threshold value '-7' computes to '0'
PASS Property shape-image-threshold value '0.5' computes to '0.5'
PASS Property shape-image-threshold value '12.5' computes to '1'
PASS Property shape-image-threshold value '-100%' computes to '0'
FAIL Property shape-image-threshold value '50%' computes to '0.5' assert_equals: expected "0.5" but got "0"
FAIL Property shape-image-threshold value '300%' computes to '1' assert_equals: expected "1" but got "0"
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS e.style['shape-image-threshold'] = "12.5" should set the property value
PASS e.style['shape-image-threshold'] = "-7" should set the property value
FAIL e.style['shape-image-threshold'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['shape-image-threshold'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['shape-image-threshold'] = "300%" should set the property value assert_not_equals: property should be set got disallowed value ""
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property flood-opacity value '-1' computes to '0'
PASS Property flood-opacity value '0.5' computes to '0.5'
PASS Property flood-opacity value '3' computes to '1'
FAIL Property flood-opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property flood-opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property flood-opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS e.style['flood-opacity'] = "-1" should set the property value
PASS e.style['flood-opacity'] = "0.5" should set the property value
PASS e.style['flood-opacity'] = "3" should set the property value
FAIL e.style['flood-opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['flood-opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['flood-opacity'] = "300%" should set the property value assert_not_equals: property should be set got disallowed value ""
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property fill-opacity value '-1' computes to '0'
PASS Property fill-opacity value '0.5' computes to '0.5'
PASS Property fill-opacity value '3' computes to '1'
FAIL Property fill-opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property fill-opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property fill-opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS e.style['fill-opacity'] = "-1" should set the property value
PASS e.style['fill-opacity'] = "0.5" should set the property value
PASS e.style['fill-opacity'] = "3" should set the property value
FAIL e.style['fill-opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['fill-opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['fill-opacity'] = "300%" should set the property value assert_not_equals: property should be set got disallowed value ""
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property stroke-opacity value '-1' computes to '0'
PASS Property stroke-opacity value '0.5' computes to '0.5'
PASS Property stroke-opacity value '3' computes to '1'
FAIL Property stroke-opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property stroke-opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property stroke-opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS e.style['stroke-opacity'] = "-1" should set the property value
PASS e.style['stroke-opacity'] = "0.5" should set the property value
PASS e.style['stroke-opacity'] = "3" should set the property value
FAIL e.style['stroke-opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['stroke-opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['stroke-opacity'] = "300%" should set the property value assert_not_equals: property should be set got disallowed value ""
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property stop-opacity value '-1' computes to '0'
PASS Property stop-opacity value '0.5' computes to '0.5'
PASS Property stop-opacity value '3' computes to '1'
FAIL Property stop-opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property stop-opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property stop-opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS e.style['stop-opacity'] = "-1" should set the property value
PASS e.style['stop-opacity'] = "0.5" should set the property value
PASS e.style['stop-opacity'] = "3" should set the property value
FAIL e.style['stop-opacity'] = "-100%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['stop-opacity'] = "50%" should set the property value assert_not_equals: property should be set got disallowed value ""
FAIL e.style['stop-opacity'] = "300%" should set the property value assert_not_equals: property should be set got disallowed value ""
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property opacity value '1' computes to '1'
PASS Property opacity value '0.5' computes to '0.5'
PASS Property opacity value '0' computes to '0'
PASS Property opacity value '-2' computes to '0'
PASS Property opacity value '3' computes to '1'
FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property opacity value '1' computes to '1'
PASS Property opacity value '0.5' computes to '0.5'
PASS Property opacity value '0' computes to '0'
PASS Property opacity value '-2' computes to '0'
PASS Property opacity value '3' computes to '1'
FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property opacity value '1' computes to '1'
PASS Property opacity value '0.5' computes to '0.5'
PASS Property opacity value '0' computes to '0'
PASS Property opacity value '-2' computes to '0'
PASS Property opacity value '3' computes to '1'
FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property opacity value '1' computes to '1'
PASS Property opacity value '0.5' computes to '0.5'
PASS Property opacity value '0' computes to '0'
PASS Property opacity value '-2' computes to '0'
PASS Property opacity value '3' computes to '1'
FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property opacity value '1' computes to '1'
PASS Property opacity value '0.5' computes to '0.5'
PASS Property opacity value '0' computes to '0'
PASS Property opacity value '-2' computes to '0'
PASS Property opacity value '3' computes to '1'
FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property opacity value '1' computes to '1'
PASS Property opacity value '0.5' computes to '0.5'
PASS Property opacity value '0' computes to '0'
PASS Property opacity value '-2' computes to '0'
PASS Property opacity value '3' computes to '1'
FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property opacity value '1' computes to '1'
PASS Property opacity value '0.5' computes to '0.5'
PASS Property opacity value '0' computes to '0'
PASS Property opacity value '-2' computes to '0'
PASS Property opacity value '3' computes to '1'
FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property opacity value '300%' computes to '1'
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Property opacity value '1' computes to '1'
PASS Property opacity value '0.5' computes to '0.5'
PASS Property opacity value '0' computes to '0'
PASS Property opacity value '-2' computes to '0'
PASS Property opacity value '3' computes to '1'
FAIL Property opacity value '-100%' computes to '0' assert_equals: expected "0" but got "1"
FAIL Property opacity value '50%' computes to '0.5' assert_equals: expected "0.5" but got "1"
PASS Property opacity value '300%' computes to '1'
Harness: the test ran to completion.
Test opacity properties combined with percentage.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS CSS.supports("stroke-opacity", "0%") is false
PASS CSS.supports("stroke-opacity", "100%") is false
PASS CSS.supports("flood-opacity", "0%") is false
PASS CSS.supports("flood-opacity", "100%") is false
PASS CSS.supports("stop-opacity", "0%") is false
PASS CSS.supports("stop-opacity", "100%") is false
PASS CSS.supports("opacity", "0%") is false
PASS CSS.supports("opacity", "100%") is false
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML>
<html>
<head>
<script src="../../resources/js-test.js"></script>
</head>
<body>
<script>
description("Test opacity properties combined with percentage.");
shouldBeFalse('CSS.supports("stroke-opacity", "0%")');
shouldBeFalse('CSS.supports("stroke-opacity", "100%")');
shouldBeFalse('CSS.supports("flood-opacity", "0%")');
shouldBeFalse('CSS.supports("flood-opacity", "100%")');
shouldBeFalse('CSS.supports("stop-opacity", "0%")');
shouldBeFalse('CSS.supports("stop-opacity", "100%")');
shouldBeFalse('CSS.supports("opacity", "0%")');
shouldBeFalse('CSS.supports("opacity", "100%")');
</script>
</body>
</html>
......@@ -16,7 +16,6 @@
stroke-dasharray: 10 5 10 auto;
clip-path: url(#clip1) auto;
clip-rule: evenodd auto;
opacity: 0%; /* does not seem supported yet */
visibility: hidden auto;
}
#circle {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment