https://bugs.webkit.org/show_bug.cgi?id=186154
<rdar://problem/
44158152>
Reviewed by Simon Fraser.
Source/WebCore:
The CSS spec for all gradients allows for each color stop to have two angles to be used for hints.
This makes pie chart and checkerboard conic gradients much simpler to write.
Any time you want to have a hard line in a gradient, this syntax simplifies the gradient specification.
Test: fast/gradients/conic-two-hints.html
Test: fast/gradients/linear-two-hints-angle.html
Test: fast/gradients/linear-two-hints.html
Test: fast/gradients/radial-two-hints.html
* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::consumeAngularGradientColorStops): Removed.
(WebCore::CSSPropertyParserHelpers::consumeGradientColorStops):
LayoutTests:
Test that uses two angles or positions per color stop.
* TestExpectations:
* fast/gradients/conic-two-hints-expected.html: Added.
* fast/gradients/conic-two-hints.html: Added.
* fast/gradients/linear-two-hints-angle-expected.html: Added.
* fast/gradients/linear-two-hints-angle.html: Added.
* fast/gradients/linear-two-hints-expected.html: Added.
* fast/gradients/linear-two-hints.html: Added.
* fast/gradients/radial-two-hints-expected.html: Added.
* fast/gradients/radial-two-hints.html: Added.
* platform/ios-12/TestExpectations:
* platform/mac/TestExpectations:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236155
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2018-09-18 Megan Gardner <megan_gardner@apple.com>
+
+ Support Images Module Level 4's double-position gradient color stop syntax
+ https://bugs.webkit.org/show_bug.cgi?id=186154
+ <rdar://problem/44158152>
+
+ Reviewed by Simon Fraser.
+
+ Test that uses two angles or positions per color stop.
+
+ * TestExpectations:
+ * fast/gradients/conic-two-hints-expected.html: Added.
+ * fast/gradients/conic-two-hints.html: Added.
+ * fast/gradients/linear-two-hints-angle-expected.html: Added.
+ * fast/gradients/linear-two-hints-angle.html: Added.
+ * fast/gradients/linear-two-hints-expected.html: Added.
+ * fast/gradients/linear-two-hints.html: Added.
+ * fast/gradients/radial-two-hints-expected.html: Added.
+ * fast/gradients/radial-two-hints.html: Added.
+ * platform/ios-12/TestExpectations:
+ * platform/mac/TestExpectations:
+
2018-09-18 Youenn Fablet <youenn@apple.com>
Enable Unified Plan by default
fast/gradients/conic-gradient-alpha.html [ Skip ]
fast/gradients/conic-gradient-extended-stops.html [ Skip ]
fast/gradients/conic-gradient.html [ Skip ]
+fast/gradients/conic-two-hints.html [ Skip ]
webkit.org/b/187773 http/tests/webAPIStatistics [ Skip ]
--- /dev/null
+<html>
+<head>
+ <style>
+ div {
+ float: left;
+ }
+
+ #box1 {
+ height: 50px;
+ width: 25px;
+ background-color: orange;
+ }
+ #box2 {
+ height: 25px;
+ width: 25px;
+ background-color: blue;
+ }
+ #box3 {
+ height: 25px;
+ width: 25px;
+ clear: left;
+ background-color: green;
+ }
+ </style>
+</head>
+<body>
+ <div id="box1"></div>
+ <div id="container">
+ <div id="box2"></div>
+ <div id="box3"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+ <style>
+ #grad {
+ height: 50px;
+ width: 50px;
+ background: conic-gradient(blue 0deg 90deg, green 90deg 180deg, orange 180deg 360deg);
+ }
+ </style>
+</head>
+<body>
+ <div id="grad"></div>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+ <style>
+ div {
+ width: 200px;
+ height: 200px;
+ float: left;
+ }
+
+ #topleft {
+ width: 0;
+ height: 0;
+ border-left: 50px solid green;
+ border-right: 50px solid orange;
+ border-top: 50px solid orange;
+ }
+ #topright {
+ width: 0;
+ height: 0;
+ border-left: 50px solid orange;
+ border-right: 50px solid lime;
+ border-top: 50px solid lime;
+ }
+ #topmiddleleft {
+ width: 0;
+ height: 0;
+ clear: left;
+ border-left: 50px solid green;
+ border-right: 50px solid orange;
+ border-bottom: 50px solid green;
+ }
+ #topmiddleright {
+ width: 0;
+ height: 0;
+ border-left: 50px solid orange;
+ border-right: 50px solid lime;
+ border-bottom: 50px solid orange;
+ }
+
+ #bottommiddleleft {
+ width: 0;
+ height: 0;
+ clear: left;
+ border-left: 50px solid blue;
+ border-right: 50px solid green;
+ border-top: 50px solid green;
+ }
+ #bottommiddleright {
+ width: 0;
+ height: 0;
+ border-left: 50px solid green;
+ border-right: 50px solid orange;
+ border-top: 50px solid orange;
+ }
+ #bottomleft {
+ width: 0;
+ height: 0;
+ clear: left;
+ border-left: 50px solid blue;
+ border-right: 50px solid green;
+ border-bottom: 50px solid blue;
+ }
+ #bottomright {
+ width: 0;
+ height: 0;
+ border-left: 50px solid green;
+ border-right: 50px solid orange;
+ border-bottom: 50px solid green;
+ }
+
+ .box {
+ position: absolute;
+ }
+ .x1 {
+ position: absolute;
+ -webkit-clip-path: polygon(0% 45%,55% 100%,45% 100%,0% 55%);
+ }
+ #x1 {
+ background-color:black;
+ }
+ .x2 {
+ position: absolute;
+ -webkit-clip-path: polygon(0% 0%, 5% 0%, 100% 95%, 100% 100%, 95% 100%,0% 5%);
+ }
+ #x2 {
+ background-color:black;
+ }
+ .x3 {
+ position: absolute;
+ -webkit-clip-path: polygon(55% 0%, 100% 45%, 100% 55%,45% 0%);
+ }
+ #x3 {
+ background-color:black;
+ }
+
+ </style>
+</head>
+<body>
+ <div>
+ <div class="box">
+ <div id="topleft"></div>
+ <div id="topright"></div>
+ <div id="topmiddleleft"></div>
+ <div id="topmiddleright"></div>
+ <div id="bottommiddleleft"></div>
+ <div id="bottommiddleright"></div>
+ <div id="bottomleft"></div>
+ <div id="bottomright"></div>
+ </div>
+ <div id="x1" class="x1"></div>
+ <div id="x2" class="x2"></div>
+ <div id="x3" class="x3"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+ <style>
+ div {
+ width: 200px;
+ height: 200px;
+ }
+ #grad {
+ position: absolute;
+ background: -webkit-linear-gradient(45deg, blue 0% 25%, green 25% 50%, orange 100px 75%, lime 150px);
+ }
+
+ .x1 {
+ position: absolute;
+ -webkit-clip-path: polygon(0% 45%,55% 100%,45% 100%,0% 55%);
+ }
+ #x1 {
+ background-color:black;
+ }
+ .x2 {
+ position: absolute;
+ -webkit-clip-path: polygon(0% 0%, 5% 0%, 100% 95%, 100% 100%, 95% 100%,0% 5%);
+ }
+ #x2 {
+ background-color:black;
+ }
+ .x3 {
+ position: absolute;
+ -webkit-clip-path: polygon(55% 0%, 100% 45%, 100% 55%,45% 0%);
+ }
+ #x3 {
+ background-color:black;
+ }
+ </style>
+</head>
+<body>
+ <div id="grad"></div>
+ <div id="x1" class="x1"></div>
+ <div id="x2" class="x2"></div>
+ <div id="x3" class="x3"></div>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+ <style>
+ div {
+ width: 200px;
+ height: 50px;
+ }
+
+ #box1 {
+ background-color: blue;
+ }
+ #box2 {
+ background-color: green;
+ }
+ #box3 {
+ background-color: orange;
+ }
+ #box4 {
+ background-color: lime;
+ }
+ </style>
+</head>
+<body>
+ <div id="box1"></div>
+ <div id="box2"></div>
+ <div id="box3"></div>
+ <div id="box4"></div>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+ <style>
+ #grad {
+ width: 200px;
+ height: 200px;
+ background: -webkit-linear-gradient(blue 0% 25%, green 25% 50%, orange 100px 75%, lime 150px);
+ }
+ </style>
+</head>
+<body>
+ <div id="grad"></div>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+ <style>
+ div {
+ width: 200px;
+ height: 200px;
+ }
+ #grad1 {
+ background-color: orange;
+ height: 33px;
+ -webkit-clip-path: inset( 0% 40% 0% 40%);
+ }
+ #grad2 {
+ background-color: green;
+ height: 33px;
+ -webkit-clip-path: inset( 0% 40% 0% 40%);
+ }
+ #grad3 {
+ background-color: blue;
+ height: 68px;
+ -webkit-clip-path: inset( 0% 40% 0% 40%);
+ }
+ #grad4 {
+ background-color: green;
+ height: 33px;
+ -webkit-clip-path: inset( 0% 40% 0% 40%);
+ }
+ #grad5 {
+ background-color: orange;
+ height: 33px;
+ -webkit-clip-path: inset( 0% 40% 0% 40%);
+ }
+ .box {
+ position: absolute;
+ background-color:black;
+ }
+ #box1 {
+ -webkit-clip-path: inset( 30% 40% 60% 40%);
+ }
+ #box2 {
+ -webkit-clip-path: inset( 60% 40% 30% 40%);
+ }
+ #box3 {
+ -webkit-clip-path: inset( 10% 40% 80% 40%);
+ }
+ #box4 {
+ -webkit-clip-path: inset( 80% 40% 10% 40%);
+ }
+ </style>
+</head>
+<body>
+ <div style="position: absolute">
+ <div id="grad1"></div>
+ <div id="grad2"></div>
+ <div id="grad3"></div>
+ <div id="grad4"></div>
+ <div id="grad5"></div>
+ </div>
+ <div style="position: absolute">
+ <div id="box1" class="box"></div>
+ <div id="box2" class="box"></div>
+ <div id="box3" class="box"></div>
+ <div id="box4" class="box"></div>
+ </div>
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+ <style>
+ div {
+ position: absolute;
+ width: 200px;
+ height: 200px;
+ }
+ #grad {
+ background: -webkit-radial-gradient(blue 0%, blue 25%, green 25% ,green 50%, orange 50%, orange 75%, lime 75%);
+ -webkit-clip-path: inset(0% 40% 0% 40%);
+ }
+ .box {
+ position: absolute;
+ background-color:black;
+ }
+ #box1 {
+ -webkit-clip-path: inset(30% 40% 60% 40%);
+ }
+ #box2 {
+ -webkit-clip-path: inset(60% 40% 30% 40%);
+ }
+ #box3 {
+ -webkit-clip-path: inset(10% 40% 80% 40%);
+ }
+ #box4 {
+ -webkit-clip-path: inset(80% 40% 10% 40%);
+ }
+ </style>
+</head>
+<body>
+ <div>
+ <div id="grad"></div>
+ <div id="box1" class="box"></div>
+ <div id="box2" class="box"></div>
+ <div id="box3" class="box"></div>
+ <div id="box4" class="box"></div>
+ </div>
+</body>
+</html>
fast/gradients/conic-gradient-alpha.html [ Pass ]
fast/gradients/conic-gradient-extended-stops.html [ Pass ]
fast/gradients/conic-gradient.html [ Pass ]
-
+fast/gradients/conic-two-hints.html [ Pass ]
[ Mojave+ ] fast/gradients/conic-gradient-alpha.html [ Pass ]
[ Mojave+ ] fast/gradients/conic-gradient-extended-stops.html [ Pass ]
[ Mojave+ ] fast/gradients/conic-gradient.html [ Pass ]
+[ Mojave+ ] fast/gradients/conic-two-hints.html [ Pass ]
webkit.org/b/185651 legacy-animation-engine/animations/play-state-in-shorthand.html [ Pass Failure ]
+2018-09-18 Megan Gardner <megan_gardner@apple.com>
+
+ Support Images Module Level 4's double-position gradient color stop syntax
+ https://bugs.webkit.org/show_bug.cgi?id=186154
+ <rdar://problem/44158152>
+
+ Reviewed by Simon Fraser.
+
+ The CSS spec for all gradients allows for each color stop to have two angles to be used for hints.
+ This makes pie chart and checkerboard conic gradients much simpler to write.
+ Any time you want to have a hard line in a gradient, this syntax simplifies the gradient specification.
+
+ Test: fast/gradients/conic-two-hints.html
+ Test: fast/gradients/linear-two-hints-angle.html
+ Test: fast/gradients/linear-two-hints.html
+ Test: fast/gradients/radial-two-hints.html
+
+ * css/parser/CSSPropertyParserHelpers.cpp:
+ (WebCore::CSSPropertyParserHelpers::consumeAngularGradientColorStops): Removed.
+ (WebCore::CSSPropertyParserHelpers::consumeGradientColorStops):
+
2018-09-18 Simon Fraser <simon.fraser@apple.com>
Remove the unused RenderLayerCompositor::enclosingCompositorFlushingLayers()
static bool consumeGradientColorStops(CSSParserTokenRange& range, CSSParserMode cssParserMode, CSSGradientValue& gradient)
{
- bool supportsColorHints = gradient.gradientType() == CSSLinearGradient || gradient.gradientType() == CSSRadialGradient;
+ bool supportsColorHints = gradient.gradientType() == CSSLinearGradient || gradient.gradientType() == CSSRadialGradient || gradient.gradientType() == CSSConicGradient;
+
+ bool isAngularGradient = gradient.gradientType() == CSSConicGradient;
// The first color stop cannot be a color hint.
bool previousStopWasColorHint = true;
// FIXME-NEWPARSER: This boolean could be removed. Null checking color would be sufficient.
stop.isMidpoint = !stop.m_color;
- stop.m_position = consumeLengthOrPercent(range, cssParserMode, ValueRangeAll);
+ if (isAngularGradient)
+ stop.m_position = consumeAngleOrPercent(range, cssParserMode, ValueRangeAll, UnitlessQuirk::Forbid);
+ else
+ stop.m_position = consumeLengthOrPercent(range, cssParserMode, ValueRangeAll);
+
if (!stop.m_color && !stop.m_position)
return false;
gradient.addStop(stop);
- } while (consumeCommaIncludingWhitespace(range));
-
- gradient.doneAddingStops();
-
- // The last color stop cannot be a color hint.
- if (previousStopWasColorHint)
- return false;
-
- // Must have 2 or more stops to be valid.
- return gradient.stopCount() >= 2;
-}
-
-// https://www.w3.org/TR/css-images-4/#typedef-angular-color-stop-list
-// FIXME: This should support up to two position hints per color stop.
-static bool consumeAngularGradientColorStops(CSSParserTokenRange& range, CSSParserMode cssParserMode, CSSGradientValue& gradient)
-{
- // The first color stop cannot be a color hint.
- bool previousStopWasColorHint = true;
- do {
- CSSGradientColorStop stop;
- stop.m_color = consumeColor(range, cssParserMode);
-
- // Two hints in a row are not allowed.
- if (!stop.m_color && previousStopWasColorHint)
- return false;
- previousStopWasColorHint = !stop.m_color;
+ // See if there is a second color hint, which is optional.
+ CSSGradientColorStop secondStop;
+ if (isAngularGradient)
+ secondStop.m_position = consumeAngleOrPercent(range, cssParserMode, ValueRangeAll, UnitlessQuirk::Forbid);
+ else
+ secondStop.m_position = consumeLengthOrPercent(range, cssParserMode, ValueRangeAll);
+
+ if (secondStop.m_position) {
+ secondStop.m_color = stop.m_color;
+ gradient.addStop(secondStop);
+ }
- // FIXME-NEWPARSER: This boolean could be removed. Null checking color would be sufficient.
- stop.isMidpoint = !stop.m_color;
-
- stop.m_position = consumeAngleOrPercent(range, cssParserMode, ValueRangeAll, UnitlessQuirk::Forbid);
- if (!stop.m_color && !stop.m_position)
- return false;
- gradient.addStop(stop);
} while (consumeCommaIncludingWhitespace(range));
gradient.doneAddingStops();
if (expectComma && !consumeCommaIncludingWhitespace(args))
return nullptr;
- if (!consumeAngularGradientColorStops(args, context.mode, *result))
+ if (!consumeGradientColorStops(args, context.mode, *result))
return nullptr;
return result;
}