<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[208116] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/208116">208116</a></dd>
<dt>Author</dt> <dd>dino@apple.com</dd>
<dt>Date</dt> <dd>2016-10-29 15:34:43 -0700 (Sat, 29 Oct 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Parse color() function
https://bugs.webkit.org/show_bug.cgi?id=164146
<rdar://problems/29007218>
Reviewed by Darin Adler.
Source/WebCore:
Support the new CSS color() function:
https://drafts.csswg.org/css-color/#color-function
There are separate code paths for the old and new CSS parser.
Tests: css3/color/color-function-computed-style.html
css3/color/color-function-parsing.html
* css/CSSComputedStyleDeclaration.cpp: Use Color directly, not via rgb().
(WebCore::ComputedStyleExtractor::currentColorOrValidColor):
(WebCore::ComputedStyleExtractor::valueForShadow):
(WebCore::ComputedStyleExtractor::propertyValue):
* css/CSSValueKeywords.in: Note that there is a color function, but the
keyword is already defined. Also add keywords for the color spaces.
* css/SVGCSSValueKeywords.in: sRGB is used outside of SVG now.
* css/parser/CSSParser.cpp: Old CSS parser code to handle color().
(WebCore::isPercent): Helper to tell if a ValueWithCalculation is a percentage or not.
(WebCore::CSSParser::parseColorInt): Renamed.
(WebCore::CSSParser::parseColorDouble): Helper to get a Number/Percentage into a double
(WebCore::CSSParser::parseRGBParameters):
(WebCore::CSSParser::parseColorFunctionParameters):
(WebCore::CSSParser::parseHSLParameters):
(WebCore::CSSParser::parseColorFromValue):
(WebCore::CSSParser::colorIntFromValue): Deleted.
* css/parser/CSSParser.h:
* css/parser/CSSPropertyParserHelpers.cpp: New CSS parser code to handle color().
(WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):
(WebCore::CSSPropertyParserHelpers::parseColorFunction):
* platform/graphics/Color.h:
(WebCore::Color::isValid): An extended color is valid.
(WebCore::Color::rgb): Move the code to a standalone inline
so that I could add a longer comment.
* platform/graphics/ExtendedColor.cpp:
(WebCore::ExtendedColor::cssText): Alpha output is only needed if != 1.
* platform/graphics/cg/ColorCG.cpp: Handle ExtendedColor -> CGColor.
(WebCore::leakCGColor):
(WebCore::cachedCGColor):
LayoutTests:
Test that exercises the new color() function in CSS. It checks
all valid and invalid input, with the exception of fallback content.
* css3/color/color-function-computed-style-expected.txt: Added.
* css3/color/color-function-computed-style.html: Added.
* css3/color/color-function-parsing-expected.txt: Added.
* css3/color/color-function-parsing.html: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssCSSComputedStyleDeclarationcpp">trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSValueKeywordsin">trunk/Source/WebCore/css/CSSValueKeywords.in</a></li>
<li><a href="#trunkSourceWebCorecssSVGCSSValueKeywordsin">trunk/Source/WebCore/css/SVGCSSValueKeywords.in</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParsercpp">trunk/Source/WebCore/css/parser/CSSParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParserh">trunk/Source/WebCore/css/parser/CSSParser.h</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSPropertyParserHelperscpp">trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsColorh">trunk/Source/WebCore/platform/graphics/Color.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsExtendedColorcpp">trunk/Source/WebCore/platform/graphics/ExtendedColor.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgColorCGcpp">trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/css3/color/</li>
<li><a href="#trunkLayoutTestscss3colorcolorfunctioncomputedstyleexpectedtxt">trunk/LayoutTests/css3/color/color-function-computed-style-expected.txt</a></li>
<li><a href="#trunkLayoutTestscss3colorcolorfunctioncomputedstylehtml">trunk/LayoutTests/css3/color/color-function-computed-style.html</a></li>
<li><a href="#trunkLayoutTestscss3colorcolorfunctionparsingexpectedtxt">trunk/LayoutTests/css3/color/color-function-parsing-expected.txt</a></li>
<li><a href="#trunkLayoutTestscss3colorcolorfunctionparsinghtml">trunk/LayoutTests/css3/color/color-function-parsing.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/LayoutTests/ChangeLog        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-10-29 Dean Jackson <dino@apple.com>
+
+ Parse color() function
+ https://bugs.webkit.org/show_bug.cgi?id=164146
+ <rdar://problems/29007218>
+
+ Reviewed by Darin Adler.
+
+ Test that exercises the new color() function in CSS. It checks
+ all valid and invalid input, with the exception of fallback content.
+
+ * css3/color/color-function-computed-style-expected.txt: Added.
+ * css3/color/color-function-computed-style.html: Added.
+ * css3/color/color-function-parsing-expected.txt: Added.
+ * css3/color/color-function-parsing.html: Added.
+
</ins><span class="cx"> 2016-10-29 Youenn Fablet <youenn@apple.com>
</span><span class="cx">
</span><span class="cx"> Remove testharness.js/testharnessreport.js unnecessary copies
</span></span></pre></div>
<a id="trunkLayoutTestscss3colorcolorfunctioncomputedstyleexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/color/color-function-computed-style-expected.txt (0 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/color/color-function-computed-style-expected.txt         (rev 0)
+++ trunk/LayoutTests/css3/color/color-function-computed-style-expected.txt        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -0,0 +1,112 @@
</span><ins>+Test the computed style of the color() function.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+TEST: Basic sRGB white --> color(srgb 1 1 1)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1)'
+
+TEST: White with lots of space --> color( srgb 1 1 1 )
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1)'
+
+TEST: sRGB color --> color(srgb 0.25 0.5 0.75)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0.25 0.5 0.75)'
+
+TEST: Different case for sRGB --> color(SrGb 0.25 0.5 0.75)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0.25 0.5 0.75)'
+
+TEST: sRGB color with unnecessary decimals --> color(srgb 1.00000 0.500000 0.20)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 0.5 0.2)'
+
+TEST: sRGB white with 0.5 alpha --> color(srgb 1 1 1 / 0.5)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0.5)'
+
+TEST: sRGB white with 0 alpha --> color(srgb 1 1 1 / 0)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0)'
+
+TEST: sRGB white with 50% alpha --> color(srgb 1 1 1 / 50%)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0.5)'
+
+TEST: sRGB white with 0% alpha --> color(srgb 1 1 1 / 0%)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0)'
+
+TEST: One missing component is 0 --> color(srgb 1 1)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 0)'
+
+TEST: Two missing components are 0 --> color(srgb 1)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 0 0)'
+
+TEST: All components missing --> color(srgb)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0 0 0)'
+
+TEST: Display P3 color --> color(display-p3 0.6 0.7 0.8)
+PASS declaration.getPropertyValue('color') is 'color(display-p3 0.6 0.7 0.8)'
+
+TEST: Different case for Display P3 --> color(dIspLaY-P3 0.6 0.7 0.8)
+PASS declaration.getPropertyValue('color') is 'color(display-p3 0.6 0.7 0.8)'
+
+
+Fallback tests.
+
+
+TEST: Unknown color space should fallback --> color(unknown 1 2 3, red)
+FAIL declaration.getPropertyValue('color') should be color(unknown 1 2 3, red). Was rgb(0, 0, 0).
+
+
+Clamping tests.
+
+
+TEST: sRGB color with negative component should clamp to 0 --> color(srgb -0.25 0.5 0.75)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0 0.5 0.75)'
+
+TEST: sRGB color with component > 1 should clamp --> color(srgb 0.25 1.5 0.75)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0.25 1 0.75)'
+
+TEST: Display P3 color with negative component should clamp to 0 --> color(display-p3 0.5 -199 0.75)
+PASS declaration.getPropertyValue('color') is 'color(display-p3 0.5 0 0.75)'
+
+TEST: Display P3 color with component > 1 should clamp --> color(display-p3 184 1.00001 2347329746587)
+PASS declaration.getPropertyValue('color') is 'color(display-p3 1 1 1)'
+
+TEST: Alpha > 1 should clamp --> color(srgb 0.1 0.2 0.3 / 1.9)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0.1 0.2 0.3)'
+
+TEST: Negative alpha should clamp --> color(srgb 1 1 1 / -0.2)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0)'
+
+
+Invalid property value tests.
+
+
+TEST: Empty --> color()
+PASS declaration.getPropertyValue('color') is 'rgb(0, 0, 0)'
+
+TEST: Bad color space --> color(banana 1 1 1)
+PASS declaration.getPropertyValue('color') is 'rgb(0, 0, 0)'
+
+TEST: Bad Display P3 color space --> color(displayp3 1 1 1)
+PASS declaration.getPropertyValue('color') is 'rgb(0, 0, 0)'
+
+TEST: No color space --> color(1 1 1)
+PASS declaration.getPropertyValue('color') is 'rgb(0, 0, 0)'
+
+TEST: Too many parameters --> color(srgb 1 1 1 1)
+PASS declaration.getPropertyValue('color') is 'rgb(0, 0, 0)'
+
+TEST: Way too many parameters --> color(srgb 1 1 1 1 1)
+PASS declaration.getPropertyValue('color') is 'rgb(0, 0, 0)'
+
+TEST: Bad parameters --> color(srgb 1 eggs 1)
+PASS declaration.getPropertyValue('color') is 'rgb(0, 0, 0)'
+
+TEST: Bad alpha --> color(srgb 1 1 1 / bacon)
+PASS declaration.getPropertyValue('color') is 'rgb(0, 0, 0)'
+
+TEST: Junk after alpha --> color(srgb 1 1 1 / 1 cucumber)
+PASS declaration.getPropertyValue('color') is 'rgb(0, 0, 0)'
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins><span class="cx">Property changes on: trunk/LayoutTests/css3/color/color-function-computed-style-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<ins>+Date Revision
</ins><span class="cx">\ No newline at end of property
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+text/plain
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkLayoutTestscss3colorcolorfunctioncomputedstylehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/color/color-function-computed-style.html (0 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/color/color-function-computed-style.html         (rev 0)
+++ trunk/LayoutTests/css3/color/color-function-computed-style.html        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -0,0 +1,85 @@
</span><ins>+<style></style>
+<script src="../../resources/js-test-pre.js"></script>
+<p id="description"></p>
+<div id="console"></div>
+<p id="target"></p>
+<script>
+description("Test the computed style of the color() function.");
+
+let styleElement = document.querySelector("style");
+let stylesheet = styleElement.sheet;
+let cssRule, declaration;
+
+function testColorFunction(description, rule, expectedValue)
+{
+ debug("");
+ debug(`TEST: ${description} --> ${rule}`);
+
+ stylesheet.insertRule(`#target { color: ${rule}; }`, 0);
+ cssRule = stylesheet.cssRules.item(0);
+
+ declaration = window.getComputedStyle(document.getElementById("target"));
+ shouldBe("declaration.getPropertyValue('color')", `'${expectedValue}'`);
+ stylesheet.deleteRule(0);
+}
+
+testColorFunction("Basic sRGB white", "color(srgb 1 1 1)", "color(srgb 1 1 1)");
+testColorFunction("White with lots of space", "color( srgb 1 1 1 )", "color(srgb 1 1 1)");
+testColorFunction("sRGB color", "color(srgb 0.25 0.5 0.75)", "color(srgb 0.25 0.5 0.75)");
+testColorFunction("Different case for sRGB", "color(SrGb 0.25 0.5 0.75)", "color(srgb 0.25 0.5 0.75)");
+testColorFunction("sRGB color with unnecessary decimals", "color(srgb 1.00000 0.500000 0.20)", "color(srgb 1 0.5 0.2)");
+
+testColorFunction("sRGB white with 0.5 alpha", "color(srgb 1 1 1 / 0.5)", "color(srgb 1 1 1 / 0.5)");
+testColorFunction("sRGB white with 0 alpha", "color(srgb 1 1 1 / 0)", "color(srgb 1 1 1 / 0)");
+testColorFunction("sRGB white with 50% alpha", "color(srgb 1 1 1 / 50%)", "color(srgb 1 1 1 / 0.5)");
+testColorFunction("sRGB white with 0% alpha", "color(srgb 1 1 1 / 0%)", "color(srgb 1 1 1 / 0)");
+
+testColorFunction("One missing component is 0", "color(srgb 1 1)", "color(srgb 1 1 0)");
+testColorFunction("Two missing components are 0", "color(srgb 1)", "color(srgb 1 0 0)");
+testColorFunction("All components missing", "color(srgb)", "color(srgb 0 0 0)");
+
+testColorFunction("Display P3 color", "color(display-p3 0.6 0.7 0.8)", "color(display-p3 0.6 0.7 0.8)");
+testColorFunction("Different case for Display P3", "color(dIspLaY-P3 0.6 0.7 0.8)", "color(display-p3 0.6 0.7 0.8)");
+
+debug("");
+debug("");
+debug("Fallback tests.")
+debug("");
+
+testColorFunction("Unknown color space should fallback", "color(unknown 1 2 3, red)", "color(unknown 1 2 3, red)");
+
+debug("");
+debug("");
+debug("Clamping tests.")
+debug("");
+
+// NOTE: If we start supporting extended-range sRGB without changing the keyword, these
+// tests may fail.
+testColorFunction("sRGB color with negative component should clamp to 0", "color(srgb -0.25 0.5 0.75)", "color(srgb 0 0.5 0.75)");
+testColorFunction("sRGB color with component > 1 should clamp", "color(srgb 0.25 1.5 0.75)", "color(srgb 0.25 1 0.75)");
+
+testColorFunction("Display P3 color with negative component should clamp to 0", "color(display-p3 0.5 -199 0.75)", "color(display-p3 0.5 0 0.75)");
+testColorFunction("Display P3 color with component > 1 should clamp", "color(display-p3 184 1.00001 2347329746587)", "color(display-p3 1 1 1)");
+
+testColorFunction("Alpha > 1 should clamp", "color(srgb 0.1 0.2 0.3 / 1.9)", "color(srgb 0.1 0.2 0.3)");
+testColorFunction("Negative alpha should clamp", "color(srgb 1 1 1 / -0.2)", "color(srgb 1 1 1 / 0)");
+
+debug("");
+debug("");
+debug("Invalid property value tests.")
+debug("");
+
+testColorFunction("Empty", "color()", "rgb(0, 0, 0)");
+testColorFunction("Bad color space", "color(banana 1 1 1)", "rgb(0, 0, 0)");
+testColorFunction("Bad Display P3 color space", "color(displayp3 1 1 1)", "rgb(0, 0, 0)");
+testColorFunction("No color space", "color(1 1 1)", "rgb(0, 0, 0)");
+testColorFunction("Too many parameters", "color(srgb 1 1 1 1)", "rgb(0, 0, 0)");
+testColorFunction("Way too many parameters", "color(srgb 1 1 1 1 1)", "rgb(0, 0, 0)");
+testColorFunction("Bad parameters", "color(srgb 1 eggs 1)", "rgb(0, 0, 0)");
+testColorFunction("Bad alpha", "color(srgb 1 1 1 / bacon)", "rgb(0, 0, 0)");
+testColorFunction("Junk after alpha", "color(srgb 1 1 1 / 1 cucumber)", "rgb(0, 0, 0)");
+
+debug("");
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
</ins><span class="cx">Property changes on: trunk/LayoutTests/css3/color/color-function-computed-style.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<ins>+Date Revision
</ins><span class="cx">\ No newline at end of property
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+text/html
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkLayoutTestscss3colorcolorfunctionparsingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/color/color-function-parsing-expected.txt (0 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/color/color-function-parsing-expected.txt         (rev 0)
+++ trunk/LayoutTests/css3/color/color-function-parsing-expected.txt        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -0,0 +1,112 @@
</span><ins>+Test the parsing of the color() function.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+TEST: Basic sRGB white --> color(srgb 1 1 1)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1)'
+
+TEST: White with lots of space --> color( srgb 1 1 1 )
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1)'
+
+TEST: sRGB color --> color(srgb 0.25 0.5 0.75)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0.25 0.5 0.75)'
+
+TEST: Different case for sRGB --> color(SrGb 0.25 0.5 0.75)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0.25 0.5 0.75)'
+
+TEST: sRGB color with unnecessary decimals --> color(srgb 1.00000 0.500000 0.20)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 0.5 0.2)'
+
+TEST: sRGB white with 0.5 alpha --> color(srgb 1 1 1 / 0.5)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0.5)'
+
+TEST: sRGB white with 0 alpha --> color(srgb 1 1 1 / 0)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0)'
+
+TEST: sRGB white with 50% alpha --> color(srgb 1 1 1 / 50%)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0.5)'
+
+TEST: sRGB white with 0% alpha --> color(srgb 1 1 1 / 0%)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0)'
+
+TEST: One missing component is 0 --> color(srgb 1 1)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 0)'
+
+TEST: Two missing components are 0 --> color(srgb 1)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 0 0)'
+
+TEST: All components missing --> color(srgb)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0 0 0)'
+
+TEST: Display P3 color --> color(display-p3 0.6 0.7 0.8)
+PASS declaration.getPropertyValue('color') is 'color(display-p3 0.6 0.7 0.8)'
+
+TEST: Different case for Display P3 --> color(dIspLaY-P3 0.6 0.7 0.8)
+PASS declaration.getPropertyValue('color') is 'color(display-p3 0.6 0.7 0.8)'
+
+
+Fallback tests.
+
+
+TEST: Unknown color space should fallback --> color(unknown 1 2 3, red)
+FAIL declaration.getPropertyValue('color') should be color(unknown 1 2 3, red). Was .
+
+
+Clamping tests.
+
+
+TEST: sRGB color with negative component should clamp to 0 --> color(srgb -0.25 0.5 0.75)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0 0.5 0.75)'
+
+TEST: sRGB color with component > 1 should clamp --> color(srgb 0.25 1.5 0.75)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0.25 1 0.75)'
+
+TEST: Display P3 color with negative component should clamp to 0 --> color(display-p3 0.5 -199 0.75)
+PASS declaration.getPropertyValue('color') is 'color(display-p3 0.5 0 0.75)'
+
+TEST: Display P3 color with component > 1 should clamp --> color(display-p3 184 1.00001 2347329746587)
+PASS declaration.getPropertyValue('color') is 'color(display-p3 1 1 1)'
+
+TEST: Alpha > 1 should clamp --> color(srgb 0.1 0.2 0.3 / 1.9)
+PASS declaration.getPropertyValue('color') is 'color(srgb 0.1 0.2 0.3)'
+
+TEST: Negative alpha should clamp --> color(srgb 1 1 1 / -0.2)
+PASS declaration.getPropertyValue('color') is 'color(srgb 1 1 1 / 0)'
+
+
+Invalid property value tests.
+
+
+TEST: Empty --> color()
+PASS declaration.getPropertyValue('color') is ''
+
+TEST: Bad color space --> color(banana 1 1 1)
+PASS declaration.getPropertyValue('color') is ''
+
+TEST: Bad Display P3 color space --> color(displayp3 1 1 1)
+PASS declaration.getPropertyValue('color') is ''
+
+TEST: No color space --> color(1 1 1)
+PASS declaration.getPropertyValue('color') is ''
+
+TEST: Too many parameters --> color(srgb 1 1 1 1)
+PASS declaration.getPropertyValue('color') is ''
+
+TEST: Way too many parameters --> color(srgb 1 1 1 1 1)
+PASS declaration.getPropertyValue('color') is ''
+
+TEST: Bad parameters --> color(srgb 1 eggs 1)
+PASS declaration.getPropertyValue('color') is ''
+
+TEST: Bad alpha --> color(srgb 1 1 1 / bacon)
+PASS declaration.getPropertyValue('color') is ''
+
+TEST: Junk after alpha --> color(srgb 1 1 1 / 1 cucumber)
+PASS declaration.getPropertyValue('color') is ''
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins><span class="cx">Property changes on: trunk/LayoutTests/css3/color/color-function-parsing-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<ins>+Date Revision
</ins><span class="cx">\ No newline at end of property
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+text/plain
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkLayoutTestscss3colorcolorfunctionparsinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/color/color-function-parsing.html (0 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/color/color-function-parsing.html         (rev 0)
+++ trunk/LayoutTests/css3/color/color-function-parsing.html        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -0,0 +1,84 @@
</span><ins>+<style></style>
+<script src="../../resources/js-test-pre.js"></script>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+description("Test the parsing of the color() function.");
+
+let styleElement = document.querySelector("style");
+let stylesheet = styleElement.sheet;
+let cssRule, declaration;
+
+function testColorFunction(description, rule, expectedValue)
+{
+ debug("");
+ debug(`TEST: ${description} --> ${rule}`);
+
+ stylesheet.insertRule(`#target { color: ${rule}; }`, 0);
+ cssRule = stylesheet.cssRules.item(0);
+
+ declaration = cssRule.style;
+ shouldBe("declaration.getPropertyValue('color')", `'${expectedValue}'`);
+ stylesheet.deleteRule(0);
+}
+
+testColorFunction("Basic sRGB white", "color(srgb 1 1 1)", "color(srgb 1 1 1)");
+testColorFunction("White with lots of space", "color( srgb 1 1 1 )", "color(srgb 1 1 1)");
+testColorFunction("sRGB color", "color(srgb 0.25 0.5 0.75)", "color(srgb 0.25 0.5 0.75)");
+testColorFunction("Different case for sRGB", "color(SrGb 0.25 0.5 0.75)", "color(srgb 0.25 0.5 0.75)");
+testColorFunction("sRGB color with unnecessary decimals", "color(srgb 1.00000 0.500000 0.20)", "color(srgb 1 0.5 0.2)");
+
+testColorFunction("sRGB white with 0.5 alpha", "color(srgb 1 1 1 / 0.5)", "color(srgb 1 1 1 / 0.5)");
+testColorFunction("sRGB white with 0 alpha", "color(srgb 1 1 1 / 0)", "color(srgb 1 1 1 / 0)");
+testColorFunction("sRGB white with 50% alpha", "color(srgb 1 1 1 / 50%)", "color(srgb 1 1 1 / 0.5)");
+testColorFunction("sRGB white with 0% alpha", "color(srgb 1 1 1 / 0%)", "color(srgb 1 1 1 / 0)");
+
+testColorFunction("One missing component is 0", "color(srgb 1 1)", "color(srgb 1 1 0)");
+testColorFunction("Two missing components are 0", "color(srgb 1)", "color(srgb 1 0 0)");
+testColorFunction("All components missing", "color(srgb)", "color(srgb 0 0 0)");
+
+testColorFunction("Display P3 color", "color(display-p3 0.6 0.7 0.8)", "color(display-p3 0.6 0.7 0.8)");
+testColorFunction("Different case for Display P3", "color(dIspLaY-P3 0.6 0.7 0.8)", "color(display-p3 0.6 0.7 0.8)");
+
+debug("");
+debug("");
+debug("Fallback tests.")
+debug("");
+
+testColorFunction("Unknown color space should fallback", "color(unknown 1 2 3, red)", "color(unknown 1 2 3, red)");
+
+debug("");
+debug("");
+debug("Clamping tests.")
+debug("");
+
+// NOTE: If we start supporting extended-range sRGB without changing the keyword, these
+// tests may fail.
+testColorFunction("sRGB color with negative component should clamp to 0", "color(srgb -0.25 0.5 0.75)", "color(srgb 0 0.5 0.75)");
+testColorFunction("sRGB color with component > 1 should clamp", "color(srgb 0.25 1.5 0.75)", "color(srgb 0.25 1 0.75)");
+
+testColorFunction("Display P3 color with negative component should clamp to 0", "color(display-p3 0.5 -199 0.75)", "color(display-p3 0.5 0 0.75)");
+testColorFunction("Display P3 color with component > 1 should clamp", "color(display-p3 184 1.00001 2347329746587)", "color(display-p3 1 1 1)");
+
+testColorFunction("Alpha > 1 should clamp", "color(srgb 0.1 0.2 0.3 / 1.9)", "color(srgb 0.1 0.2 0.3)");
+testColorFunction("Negative alpha should clamp", "color(srgb 1 1 1 / -0.2)", "color(srgb 1 1 1 / 0)");
+
+debug("");
+debug("");
+debug("Invalid property value tests.")
+debug("");
+
+testColorFunction("Empty", "color()", "");
+testColorFunction("Bad color space", "color(banana 1 1 1)", "");
+testColorFunction("Bad Display P3 color space", "color(displayp3 1 1 1)", "");
+testColorFunction("No color space", "color(1 1 1)", "");
+testColorFunction("Too many parameters", "color(srgb 1 1 1 1)", "");
+testColorFunction("Way too many parameters", "color(srgb 1 1 1 1 1)", "");
+testColorFunction("Bad parameters", "color(srgb 1 eggs 1)", "");
+testColorFunction("Bad alpha", "color(srgb 1 1 1 / bacon)", "");
+testColorFunction("Junk after alpha", "color(srgb 1 1 1 / 1 cucumber)", "");
+
+debug("");
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
</ins><span class="cx">Property changes on: trunk/LayoutTests/css3/color/color-function-parsing.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<ins>+Date Revision
</ins><span class="cx">\ No newline at end of property
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+text/html
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/ChangeLog        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -1,3 +1,55 @@
</span><ins>+2016-10-29 Dean Jackson <dino@apple.com>
+
+ Parse color() function
+ https://bugs.webkit.org/show_bug.cgi?id=164146
+ <rdar://problems/29007218>
+
+ Reviewed by Darin Adler.
+
+ Support the new CSS color() function:
+ https://drafts.csswg.org/css-color/#color-function
+
+ There are separate code paths for the old and new CSS parser.
+
+ Tests: css3/color/color-function-computed-style.html
+ css3/color/color-function-parsing.html
+
+ * css/CSSComputedStyleDeclaration.cpp: Use Color directly, not via rgb().
+ (WebCore::ComputedStyleExtractor::currentColorOrValidColor):
+ (WebCore::ComputedStyleExtractor::valueForShadow):
+ (WebCore::ComputedStyleExtractor::propertyValue):
+
+ * css/CSSValueKeywords.in: Note that there is a color function, but the
+ keyword is already defined. Also add keywords for the color spaces.
+ * css/SVGCSSValueKeywords.in: sRGB is used outside of SVG now.
+
+ * css/parser/CSSParser.cpp: Old CSS parser code to handle color().
+ (WebCore::isPercent): Helper to tell if a ValueWithCalculation is a percentage or not.
+ (WebCore::CSSParser::parseColorInt): Renamed.
+ (WebCore::CSSParser::parseColorDouble): Helper to get a Number/Percentage into a double
+ (WebCore::CSSParser::parseRGBParameters):
+ (WebCore::CSSParser::parseColorFunctionParameters):
+ (WebCore::CSSParser::parseHSLParameters):
+ (WebCore::CSSParser::parseColorFromValue):
+ (WebCore::CSSParser::colorIntFromValue): Deleted.
+ * css/parser/CSSParser.h:
+
+ * css/parser/CSSPropertyParserHelpers.cpp: New CSS parser code to handle color().
+ (WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):
+ (WebCore::CSSPropertyParserHelpers::parseColorFunction):
+
+ * platform/graphics/Color.h:
+ (WebCore::Color::isValid): An extended color is valid.
+ (WebCore::Color::rgb): Move the code to a standalone inline
+ so that I could add a longer comment.
+
+ * platform/graphics/ExtendedColor.cpp:
+ (WebCore::ExtendedColor::cssText): Alpha output is only needed if != 1.
+
+ * platform/graphics/cg/ColorCG.cpp: Handle ExtendedColor -> CGColor.
+ (WebCore::leakCGColor):
+ (WebCore::cachedCGColor):
+
</ins><span class="cx"> 2016-10-29 Dave Hyatt <hyatt@apple.com>
</span><span class="cx">
</span><span class="cx"> [CSS Parser] Disable -webkit-text-size-adjust when the context says to.
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSComputedStyleDeclarationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -732,8 +732,8 @@
</span><span class="cx"> {
</span><span class="cx"> // This function does NOT look at visited information, so that computed style doesn't expose that.
</span><span class="cx"> if (!color.isValid())
</span><del>- return CSSValuePool::singleton().createColorValue(style->color().rgb());
- return CSSValuePool::singleton().createColorValue(color.rgb());
</del><ins>+ return CSSValuePool::singleton().createColorValue(style->color());
+ return CSSValuePool::singleton().createColorValue(color);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> static Ref<CSSPrimitiveValue> percentageOrZoomAdjustedValue(Length length, const RenderStyle& style)
</span><span class="lines">@@ -901,7 +901,7 @@
</span><span class="cx"> auto blur = adjustLengthForZoom(currShadowData->radius(), style, adjust);
</span><span class="cx"> auto spread = propertyID == CSSPropertyTextShadow ? RefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust);
</span><span class="cx"> auto style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? RefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset);
</span><del>- auto color = cssValuePool.createColorValue(currShadowData->color().rgb());
</del><ins>+ auto color = cssValuePool.createColorValue(currShadowData->color());
</ins><span class="cx"> list->prepend(CSSShadowValue::create(WTFMove(x), WTFMove(y), WTFMove(blur), WTFMove(spread), WTFMove(style), WTFMove(color)));
</span><span class="cx"> }
</span><span class="cx"> return WTFMove(list);
</span><span class="lines">@@ -2567,7 +2567,7 @@
</span><span class="cx"> break;
</span><span class="cx">
</span><span class="cx"> case CSSPropertyBackgroundColor:
</span><del>- return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
</del><ins>+ return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor) : style->backgroundColor());
</ins><span class="cx"> case CSSPropertyBackgroundImage:
</span><span class="cx"> case CSSPropertyWebkitMaskImage: {
</span><span class="cx"> const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
</span><span class="lines">@@ -2728,13 +2728,13 @@
</span><span class="cx"> return style->borderImageSource()->cssValue();
</span><span class="cx"> return cssValuePool.createIdentifierValue(CSSValueNone);
</span><span class="cx"> case CSSPropertyBorderTopColor:
</span><del>- return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style, style->borderTopColor());
</del><ins>+ return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor)) : currentColorOrValidColor(style, style->borderTopColor());
</ins><span class="cx"> case CSSPropertyBorderRightColor:
</span><del>- return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style, style->borderRightColor());
</del><ins>+ return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor)) : currentColorOrValidColor(style, style->borderRightColor());
</ins><span class="cx"> case CSSPropertyBorderBottomColor:
</span><del>- return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style, style->borderBottomColor());
</del><ins>+ return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor)) : currentColorOrValidColor(style, style->borderBottomColor());
</ins><span class="cx"> case CSSPropertyBorderLeftColor:
</span><del>- return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style, style->borderLeftColor());
</del><ins>+ return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor)) : currentColorOrValidColor(style, style->borderLeftColor());
</ins><span class="cx"> case CSSPropertyBorderTopStyle:
</span><span class="cx"> return cssValuePool.createValue(style->borderTopStyle());
</span><span class="cx"> case CSSPropertyBorderRightStyle:
</span><span class="lines">@@ -2785,7 +2785,7 @@
</span><span class="cx"> case CSSPropertyClear:
</span><span class="cx"> return cssValuePool.createValue(style->clear());
</span><span class="cx"> case CSSPropertyColor:
</span><del>- return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
</del><ins>+ return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor) : style->color());
</ins><span class="cx"> case CSSPropertyWebkitPrintColorAdjust:
</span><span class="cx"> return cssValuePool.createValue(style->printColorAdjust());
</span><span class="cx"> case CSSPropertyWebkitColumnAxis:
</span><span class="lines">@@ -2803,7 +2803,7 @@
</span><span class="cx"> case CSSPropertyWebkitColumnProgression:
</span><span class="cx"> return cssValuePool.createValue(style->columnProgression());
</span><span class="cx"> case CSSPropertyColumnRuleColor:
</span><del>- return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style->columnRuleColor());
</del><ins>+ return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->columnRuleColor());
</ins><span class="cx"> case CSSPropertyColumnRuleStyle:
</span><span class="cx"> return cssValuePool.createValue(style->columnRuleStyle());
</span><span class="cx"> case CSSPropertyColumnRuleWidth:
</span><span class="lines">@@ -3145,7 +3145,7 @@
</span><span class="cx"> return cssValuePool.createIdentifierValue(CSSValueAuto);
</span><span class="cx"> return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
</span><span class="cx"> case CSSPropertyOutlineColor:
</span><del>- return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style, style->outlineColor());
</del><ins>+ return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(style, style->outlineColor());
</ins><span class="cx"> case CSSPropertyOutlineOffset:
</span><span class="cx"> return zoomAdjustedPixelValue(style->outlineOffset(), *style);
</span><span class="cx"> case CSSPropertyOutlineStyle:
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSValueKeywordsin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSValueKeywords.in (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSValueKeywords.in        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/css/CSSValueKeywords.in        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -1204,6 +1204,7 @@
</span><span class="cx"> rgba
</span><span class="cx"> hsl
</span><span class="cx"> hsla
</span><ins>+//color
</ins><span class="cx">
</span><span class="cx"> // transform
</span><span class="cx"> matrix
</span><span class="lines">@@ -1310,6 +1311,10 @@
</span><span class="cx"> p3
</span><span class="cx"> rec2020
</span><span class="cx">
</span><ins>+// color() function
+sRGB
+display-p3
+
</ins><span class="cx"> // prefers-reduced-motion
</span><span class="cx"> reduce
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorecssSVGCSSValueKeywordsin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/SVGCSSValueKeywords.in (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SVGCSSValueKeywords.in        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/css/SVGCSSValueKeywords.in        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -176,7 +176,7 @@
</span><span class="cx"> // CSS_PROP_STOP_OPACITY
</span><span class="cx"> // CSS_PROP_COLOR_INTERPOLATION
</span><span class="cx"> //auto
</span><del>-sRGB
</del><ins>+//sRGB
</ins><span class="cx"> linearRGB
</span><span class="cx">
</span><span class="cx"> // CSS_PROP_COLOR_INTERPOLATION_FILTERS
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSParser.cpp (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParser.cpp        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/css/parser/CSSParser.cpp        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -7608,21 +7608,22 @@
</span><span class="cx"> || equalLettersIgnoringASCIICase(value.function->name, "-webkit-calc("));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline int CSSParser::colorIntFromValue(ValueWithCalculation& valueWithCalculation)
</del><ins>+static bool isPercent(const CSSParser::ValueWithCalculation& valueWithCalculation)
</ins><span class="cx"> {
</span><del>- bool isPercent;
-
</del><span class="cx"> if (valueWithCalculation.calculation())
</span><del>- isPercent = valueWithCalculation.calculation()->category() == CalcPercent;
- else
- isPercent = valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE;
</del><ins>+ return valueWithCalculation.calculation()->category() == CalcPercent;
</ins><span class="cx">
</span><del>- const double doubleValue = parsedDouble(valueWithCalculation);
</del><ins>+ return valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE;
+}
+
+inline int CSSParser::parseColorInt(ValueWithCalculation& valueWithCalculation)
+{
+ double doubleValue = parsedDouble(valueWithCalculation);
</ins><span class="cx">
</span><span class="cx"> if (doubleValue <= 0.0)
</span><span class="cx"> return 0;
</span><span class="cx">
</span><del>- if (isPercent) {
</del><ins>+ if (isPercent(valueWithCalculation)) {
</ins><span class="cx"> if (doubleValue >= 100.0)
</span><span class="cx"> return 255;
</span><span class="cx"> return static_cast<int>(doubleValue * 256.0 / 100.0);
</span><span class="lines">@@ -7634,6 +7635,16 @@
</span><span class="cx"> return static_cast<int>(doubleValue);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+inline double CSSParser::parseColorDouble(ValueWithCalculation& valueWithCalculation)
+{
+ double doubleValue = parsedDouble(valueWithCalculation);
+
+ if (isPercent(valueWithCalculation))
+ return doubleValue / 100.0;
+
+ return doubleValue;
+}
+
</ins><span class="cx"> bool CSSParser::parseRGBParameters(CSSParserValue& value, int* colorArray, bool parseAlpha)
</span><span class="cx"> {
</span><span class="cx"> CSSParserValueList* args = value.function->args.get();
</span><span class="lines">@@ -7647,7 +7658,7 @@
</span><span class="cx"> else
</span><span class="cx"> return false;
</span><span class="cx">
</span><del>- colorArray[0] = colorIntFromValue(firstArgumentWithCalculation);
</del><ins>+ colorArray[0] = parseColorInt(firstArgumentWithCalculation);
</ins><span class="cx"> for (int i = 1; i < 3; i++) {
</span><span class="cx"> CSSParserValue& operatorArgument = *args->next();
</span><span class="cx"> if (operatorArgument.unit != CSSParserValue::Operator && operatorArgument.iValue != ',')
</span><span class="lines">@@ -7655,7 +7666,7 @@
</span><span class="cx"> ValueWithCalculation argumentWithCalculation(*args->next());
</span><span class="cx"> if (!validateUnit(argumentWithCalculation, unitType, HTMLStandardMode))
</span><span class="cx"> return false;
</span><del>- colorArray[i] = colorIntFromValue(argumentWithCalculation);
</del><ins>+ colorArray[i] = parseColorInt(argumentWithCalculation);
</ins><span class="cx"> }
</span><span class="cx"> if (parseAlpha) {
</span><span class="cx"> CSSParserValue& operatorArgument = *args->next();
</span><span class="lines">@@ -7667,11 +7678,65 @@
</span><span class="cx"> double doubleValue = parsedDouble(argumentWithCalculation);
</span><span class="cx"> // Convert the floating pointer number of alpha to an integer in the range [0, 256),
</span><span class="cx"> // with an equal distribution across all 256 values.
</span><del>- colorArray[3] = static_cast<int>(std::max<double>(0, std::min<double>(1, doubleValue)) * nextafter(256.0, 0.0));
</del><ins>+ colorArray[3] = static_cast<int>(std::max(0.0, std::min(1.0, doubleValue)) * nextafter(256.0, 0.0));
</ins><span class="cx"> }
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+Optional<std::pair<std::array<double, 4>, ColorSpace>> CSSParser::parseColorFunctionParameters(CSSParserValue& value)
+{
+ CSSParserValueList* args = value.function->args.get();
+ if (!args->size())
+ return Nullopt;
+
+ ColorSpace colorSpace;
+ switch (args->current()->id) {
+ case CSSValueSrgb:
+ colorSpace = ColorSpaceSRGB;
+ break;
+ case CSSValueDisplayP3:
+ colorSpace = ColorSpaceDisplayP3;
+ break;
+ default:
+ return Nullopt;
+ }
+
+ std::array<double, 4> colorValues = { { 0, 0, 0, 1 } };
+
+ for (int i = 0; i < 3; ++i) {
+ auto valueOrNull = args->next();
+ if (valueOrNull) {
+ ValueWithCalculation argumentWithCalculation(*valueOrNull);
+ if (!validateUnit(argumentWithCalculation, FNumber))
+ return Nullopt;
+ colorValues[i] = std::max(0.0, std::min(1.0, parsedDouble(argumentWithCalculation)));
+ }
+ }
+
+ auto slashOrNull = args->next();
+ if (!slashOrNull)
+ return { { colorValues, colorSpace } };
+
+ if (!isForwardSlashOperator(*slashOrNull))
+ return Nullopt;
+
+ // Handle alpha.
+
+ ValueWithCalculation argumentWithCalculation(*args->next());
+ if (!validateUnit(argumentWithCalculation, FNumber | FPercent))
+ return Nullopt;
+ colorValues[3] = std::max(0.0, std::min(1.0, parseColorDouble(argumentWithCalculation)));
+
+ // FIXME: Support the comma-separated list of fallback color values.
+ // If there is another argument, it should be a comma.
+
+ auto commaOrNull = args->next();
+ if (commaOrNull && !isComma(commaOrNull))
+ return Nullopt;
+
+ return { { colorValues, colorSpace } };
+}
+
</ins><span class="cx"> // The CSS3 specification defines the format of a HSL color as
</span><span class="cx"> // hsl(<number>, <percent>, <percent>)
</span><span class="cx"> // and with alpha, the format is
</span><span class="lines">@@ -7693,7 +7758,7 @@
</span><span class="cx"> ValueWithCalculation argumentWithCalculation(*args->next());
</span><span class="cx"> if (!validateUnit(argumentWithCalculation, FPercent, HTMLStandardMode))
</span><span class="cx"> return false;
</span><del>- colorArray[i] = std::max<double>(0, std::min<double>(100, parsedDouble(argumentWithCalculation))) / 100.0; // needs to be value between 0 and 1.0
</del><ins>+ colorArray[i] = std::max(0.0, std::min(100.0, parsedDouble(argumentWithCalculation))) / 100.0; // needs to be value between 0 and 1.0
</ins><span class="cx"> }
</span><span class="cx"> if (parseAlpha) {
</span><span class="cx"> CSSParserValue& operatorArgument = *args->next();
</span><span class="lines">@@ -7702,7 +7767,7 @@
</span><span class="cx"> ValueWithCalculation argumentWithCalculation(*args->next());
</span><span class="cx"> if (!validateUnit(argumentWithCalculation, FNumber, HTMLStandardMode))
</span><span class="cx"> return false;
</span><del>- colorArray[3] = std::max<double>(0, std::min<double>(1, parsedDouble(argumentWithCalculation)));
</del><ins>+ colorArray[3] = std::max(0.0, std::min(1.0, parsedDouble(argumentWithCalculation)));
</ins><span class="cx"> }
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="lines">@@ -7758,6 +7823,13 @@
</span><span class="cx"> if (!parseHSLParameters(value, colorValues, true))
</span><span class="cx"> return Color();
</span><span class="cx"> return Color(makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]));
</span><ins>+ } else if (value.unit == CSSParserValue::Function
+ && value.function->args
+ && equalLettersIgnoringASCIICase(value.function->name, "color(")) {
+ Optional<std::pair<std::array<double, 4>, ColorSpace>> colorData = parseColorFunctionParameters(value);
+ if (!colorData)
+ return Color();
+ return Color(colorData.value().first[0], colorData.value().first[1], colorData.value().first[2], colorData.value().first[3], colorData.value().second);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return Color();
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSParser.h (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParser.h        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/css/parser/CSSParser.h        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include "CSSPropertySourceData.h"
</span><span class="cx"> #include "CSSValueKeywords.h"
</span><span class="cx"> #include "Color.h"
</span><ins>+#include "ColorSpace.h"
</ins><span class="cx"> #include "MediaQuery.h"
</span><span class="cx"> #include "StyleRuleImport.h"
</span><span class="cx"> #include "WebKitCSSFilterValue.h"
</span><span class="lines">@@ -275,6 +276,7 @@
</span><span class="cx">
</span><span class="cx"> bool parseRGBParameters(CSSParserValue&, int* colorValues, bool parseAlpha);
</span><span class="cx"> bool parseHSLParameters(CSSParserValue&, double* colorValues, bool parseAlpha);
</span><ins>+ Optional<std::pair<std::array<double, 4>, ColorSpace>> parseColorFunctionParameters(CSSParserValue&);
</ins><span class="cx"> RefPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = nullptr);
</span><span class="cx"> Color parseColorFromValue(CSSParserValue&);
</span><span class="cx"> void parseSelector(const String&, CSSSelectorList&);
</span><span class="lines">@@ -708,7 +710,8 @@
</span><span class="cx"> bool validateUnit(ValueWithCalculation&, Units, CSSParserMode);
</span><span class="cx">
</span><span class="cx"> bool parseBorderImageQuad(Units, RefPtr<CSSPrimitiveValue>&);
</span><del>- int colorIntFromValue(ValueWithCalculation&);
</del><ins>+ int parseColorInt(ValueWithCalculation&);
+ double parseColorDouble(ValueWithCalculation&);
</ins><span class="cx"> double parsedDouble(ValueWithCalculation&);
</span><span class="cx">
</span><span class="cx"> friend class TransformOperationInfo;
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSPropertyParserHelperscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -464,6 +464,51 @@
</span><span class="cx"> return Color(makeRGBAFromHSLA(colorArray[0], colorArray[1], colorArray[2], alpha));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+static Color parseColorFunctionParameters(CSSParserTokenRange& range)
+{
+ ASSERT(range.peek().functionId() == CSSValueColor);
+ CSSParserTokenRange args = consumeFunction(range);
+
+ ColorSpace colorSpace;
+ switch (args.peek().id()) {
+ case CSSValueSrgb:
+ colorSpace = ColorSpaceSRGB;
+ break;
+ case CSSValueDisplayP3:
+ colorSpace = ColorSpaceDisplayP3;
+ break;
+ default:
+ return Color();
+ }
+ consumeIdent(args);
+
+ double colorChannels[4] = { 0, 0, 0, 1 };
+ for (int i = 0; i < 3; ++i) {
+ double value;
+ if (consumeNumberRaw(args, value))
+ colorChannels[i] = std::max(0.0, std::min(1.0, value));
+ else
+ break;
+ }
+
+ if (consumeSlashIncludingWhitespace(args)) {
+ auto alphaParameter = consumePercent(args, ValueRangeAll);
+ if (!alphaParameter)
+ alphaParameter = consumeNumber(args, ValueRangeAll);
+ if (!alphaParameter)
+ return Color();
+
+ colorChannels[3] = std::max(0.0, std::min(1.0, alphaParameter->isPercentage() ? (alphaParameter->doubleValue() / 100) : alphaParameter->doubleValue()));
+ }
+
+ // FIXME: Support the comma-separated list of fallback color values.
+
+ if (!args.atEnd())
+ return Color();
+
+ return Color(colorChannels[0], colorChannels[1], colorChannels[2], colorChannels[3], colorSpace);
+}
+
</ins><span class="cx"> static Color parseHexColor(CSSParserTokenRange& range, bool acceptQuirkyColors)
</span><span class="cx"> {
</span><span class="cx"> RGBA32 result;
</span><span class="lines">@@ -513,8 +558,8 @@
</span><span class="cx"> color = parseHSLParameters(colorRange, functionId == CSSValueHsla);
</span><span class="cx"> break;
</span><span class="cx"> case CSSValueColor:
</span><del>- // FIXME-NEWPARSER: Add support for color().
- return Color();
</del><ins>+ color = parseColorFunctionParameters(colorRange);
+ break;
</ins><span class="cx"> default:
</span><span class="cx"> return Color();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsColorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/Color.h (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/Color.h        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/platform/graphics/Color.h        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -196,7 +196,7 @@
</span><span class="cx"> // The latter format is not a valid CSS color, and should only be seen in DRT dumps.
</span><span class="cx"> String nameForRenderTreeAsText() const;
</span><span class="cx">
</span><del>- bool isValid() const { return m_colorData.rgbaAndFlags & validRGBAColorBit; }
</del><ins>+ bool isValid() const { return isExtended() || (m_colorData.rgbaAndFlags & validRGBAColorBit); }
</ins><span class="cx">
</span><span class="cx"> bool hasAlpha() const { return alpha() < 255; }
</span><span class="cx">
</span><span class="lines">@@ -205,7 +205,7 @@
</span><span class="cx"> int blue() const { return blueChannel(rgb()); }
</span><span class="cx"> int alpha() const { return alphaChannel(rgb()); }
</span><span class="cx">
</span><del>- RGBA32 rgb() const { ASSERT(!isExtended()); return static_cast<RGBA32>(m_colorData.rgbaAndFlags >> 32); }
</del><ins>+ RGBA32 rgb() const;
</ins><span class="cx">
</span><span class="cx"> // FIXME: Like operator==, this will give different values for ExtendedColors that
</span><span class="cx"> // should be identical, since the respective pointer will be different.
</span><span class="lines">@@ -397,6 +397,14 @@
</span><span class="cx"> return overrideAlpha ? colorWithOverrideAlpha(color, overrideAlpha.value()) : color;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+inline RGBA32 Color::rgb() const
+{
+ // FIXME: We should ASSERT(!isExtended()) here, or produce
+ // an RGBA32 equivalent for an ExtendedColor. Ideally the former,
+ // so we can audit all the rgb() call sites to handle extended.
+ return static_cast<RGBA32>(m_colorData.rgbaAndFlags >> 32);
+}
+
</ins><span class="cx"> inline void Color::setRGB(RGBA32 rgb)
</span><span class="cx"> {
</span><span class="cx"> m_colorData.rgbaAndFlags = static_cast<uint64_t>(rgb) << 32;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsExtendedColorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ExtendedColor.cpp (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ExtendedColor.cpp        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/platform/graphics/ExtendedColor.cpp        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -66,9 +66,10 @@
</span><span class="cx"> builder.append(' ');
</span><span class="cx">
</span><span class="cx"> builder.append(numberToFixedPrecisionString(blue(), 6, buffer, shouldTruncateTrailingZeros));
</span><del>- builder.appendLiteral(" / ");
-
- builder.append(numberToFixedPrecisionString(alpha(), 6, buffer, shouldTruncateTrailingZeros));
</del><ins>+ if (!WTF::areEssentiallyEqual(alpha(), 1.0f)) {
+ builder.appendLiteral(" / ");
+ builder.append(numberToFixedPrecisionString(alpha(), 6, buffer, shouldTruncateTrailingZeros));
+ }
</ins><span class="cx"> builder.append(')');
</span><span class="cx">
</span><span class="cx"> return builder.toString();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgColorCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp (208115 => 208116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp        2016-10-29 21:42:15 UTC (rev 208115)
+++ trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp        2016-10-29 22:34:43 UTC (rev 208116)
</span><span class="lines">@@ -116,6 +116,24 @@
</span><span class="cx"> static CGColorRef leakCGColor(const Color& color)
</span><span class="cx"> {
</span><span class="cx"> CGFloat components[4];
</span><ins>+ if (color.isExtended()) {
+ ExtendedColor& extendedColor = color.asExtended();
+ components[0] = extendedColor.red();
+ components[1] = extendedColor.green();
+ components[2] = extendedColor.blue();
+ components[3] = extendedColor.alpha();
+ switch (extendedColor.colorSpace()) {
+ case ColorSpaceSRGB:
+ return CGColorCreate(sRGBColorSpaceRef(), components);
+ case ColorSpaceDisplayP3:
+ return CGColorCreate(displayP3ColorSpaceRef(), components);
+ case ColorSpaceLinearRGB:
+ case ColorSpaceDeviceRGB:
+ // FIXME: Do we ever create CGColorRefs in these spaces? It may only be ImageBuffers.
+ return CGColorCreate(sRGBColorSpaceRef(), components);
+ }
+ }
+
</ins><span class="cx"> color.getRGBA(components[0], components[1], components[2], components[3]);
</span><span class="cx"> return CGColorCreate(sRGBColorSpaceRef(), components);
</span><span class="cx"> }
</span><span class="lines">@@ -122,22 +140,24 @@
</span><span class="cx">
</span><span class="cx"> CGColorRef cachedCGColor(const Color& color)
</span><span class="cx"> {
</span><del>- switch (color.rgb()) {
- case Color::transparent: {
- static CGColorRef transparentCGColor = leakCGColor(color);
- return transparentCGColor;
</del><ins>+ if (!color.isExtended()) {
+ switch (color.rgb()) {
+ case Color::transparent: {
+ static CGColorRef transparentCGColor = leakCGColor(color);
+ return transparentCGColor;
+ }
+ case Color::black: {
+ static CGColorRef blackCGColor = leakCGColor(color);
+ return blackCGColor;
+ }
+ case Color::white: {
+ static CGColorRef whiteCGColor = leakCGColor(color);
+ return whiteCGColor;
+ }
+ }
</ins><span class="cx"> }
</span><del>- case Color::black: {
- static CGColorRef blackCGColor = leakCGColor(color);
- return blackCGColor;
- }
- case Color::white: {
- static CGColorRef whiteCGColor = leakCGColor(color);
- return whiteCGColor;
- }
- }
</del><span class="cx">
</span><del>- ASSERT(color.rgb());
</del><ins>+ ASSERT(color.isExtended() || color.rgb());
</ins><span class="cx">
</span><span class="cx"> static NeverDestroyed<TinyLRUCache<Color, RetainPtr<CGColorRef>, 32>> cache;
</span><span class="cx"> return cache.get().get(color).get();
</span></span></pre>
</div>
</div>
</body>
</html>