<!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>[204852] trunk/Source</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/204852">204852</a></dd>
<dt>Author</dt> <dd>hyatt@apple.com</dd>
<dt>Date</dt> <dd>2016-08-23 12:37:37 -0700 (Tue, 23 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add pref for enabling new CSS parsing and move parser files into subdirectory.
https://bugs.webkit.org/show_bug.cgi?id=161095

Reviewed by Sam Weinig.

Source/WebCore:

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSParser.cpp: Removed.
* css/CSSParser.h: Removed.
* css/CSSParserMode.h: Removed.
* css/CSSParserValues.cpp: Removed.
* css/CSSParserValues.h: Removed.
* css/SVGCSSParser.cpp: Removed.
* css/parser: Added.
* css/parser/CSSParser.cpp: Copied from css/CSSParser.cpp.
* css/parser/CSSParser.h: Copied from css/CSSParser.h.
* css/parser/CSSParserMode.h: Copied from css/CSSParserMode.h.
* css/parser/CSSParserValues.cpp: Copied from css/CSSParserValues.cpp.
* css/parser/CSSParserValues.h: Copied from css/CSSParserValues.h.
* css/parser/SVGCSSParser.cpp: Copied from css/SVGCSSParser.cpp.
* page/Settings.in:

Source/WebKit2:

* Shared/WebPreferencesDefinitions.h:
* UIProcess/API/C/WKPreferences.cpp:
(WKPreferencesSetNewCSSParserEnabled):
(WKPreferencesGetNewCSSParserEnabled):
* UIProcess/API/C/WKPreferencesRefPrivate.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorepageSettingsin">trunk/Source/WebCore/page/Settings.in</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedWebPreferencesDefinitionsh">trunk/Source/WebKit2/Shared/WebPreferencesDefinitions.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKPreferencescpp">trunk/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKPreferencesRefPrivateh">trunk/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/Source/WebCore/css/parser/</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="#trunkSourceWebCorecssparserCSSParserModeh">trunk/Source/WebCore/css/parser/CSSParserMode.h</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParserValuescpp">trunk/Source/WebCore/css/parser/CSSParserValues.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParserValuesh">trunk/Source/WebCore/css/parser/CSSParserValues.h</a></li>
<li><a href="#trunkSourceWebCorecssparserSVGCSSParsercpp">trunk/Source/WebCore/css/parser/SVGCSSParser.cpp</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorecssCSSParsercpp">trunk/Source/WebCore/css/CSSParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSParserh">trunk/Source/WebCore/css/CSSParser.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSParserModeh">trunk/Source/WebCore/css/CSSParserMode.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSParserValuescpp">trunk/Source/WebCore/css/CSSParserValues.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSParserValuesh">trunk/Source/WebCore/css/CSSParserValues.h</a></li>
<li><a href="#trunkSourceWebCorecssSVGCSSParsercpp">trunk/Source/WebCore/css/SVGCSSParser.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx">     &quot;${WEBCORE_DIR}/crypto/keys&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/crypto/parameters&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/css&quot;
</span><ins>+    &quot;${WEBCORE_DIR}/css/parser&quot;
</ins><span class="cx">     &quot;${WEBCORE_DIR}/cssjit&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/dom&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/dom/default&quot;
</span><span class="lines">@@ -1344,8 +1345,6 @@
</span><span class="cx">     css/CSSNamedImageValue.cpp
</span><span class="cx">     css/CSSOMUtils.cpp
</span><span class="cx">     css/CSSPageRule.cpp
</span><del>-    css/CSSParser.cpp
-    css/CSSParserValues.cpp
</del><span class="cx">     css/CSSPrimitiveValue.cpp
</span><span class="cx">     css/CSSProperty.cpp
</span><span class="cx">     css/CSSPropertySourceData.cpp
</span><span class="lines">@@ -1389,7 +1388,6 @@
</span><span class="cx">     css/RuleFeature.cpp
</span><span class="cx">     css/RuleSet.cpp
</span><span class="cx">     css/SVGCSSComputedStyleDeclaration.cpp
</span><del>-    css/SVGCSSParser.cpp
</del><span class="cx">     css/SelectorChecker.cpp
</span><span class="cx">     css/SelectorFilter.cpp
</span><span class="cx">     css/SourceSizeList.cpp
</span><span class="lines">@@ -1411,6 +1409,10 @@
</span><span class="cx">     css/WebKitCSSTransformValue.cpp
</span><span class="cx">     css/WebKitCSSViewportRule.cpp
</span><span class="cx"> 
</span><ins>+    css/parser/CSSParser.cpp
+    css/parser/CSSParserValues.cpp
+    css/parser/SVGCSSParser.cpp
+
</ins><span class="cx">     cssjit/SelectorCompiler.cpp
</span><span class="cx"> 
</span><span class="cx">     dom/ActiveDOMCallbackMicrotask.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/ChangeLog        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2016-08-23  Dave Hyatt  &lt;hyatt@apple.com&gt;
+
+        Add pref for enabling new CSS parsing and move parser files into subdirectory.
+        https://bugs.webkit.org/show_bug.cgi?id=161095
+
+        Reviewed by Sam Weinig.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSParser.cpp: Removed.
+        * css/CSSParser.h: Removed.
+        * css/CSSParserMode.h: Removed.
+        * css/CSSParserValues.cpp: Removed.
+        * css/CSSParserValues.h: Removed.
+        * css/SVGCSSParser.cpp: Removed.
+        * css/parser: Added.
+        * css/parser/CSSParser.cpp: Copied from css/CSSParser.cpp.
+        * css/parser/CSSParser.h: Copied from css/CSSParser.h.
+        * css/parser/CSSParserMode.h: Copied from css/CSSParserMode.h.
+        * css/parser/CSSParserValues.cpp: Copied from css/CSSParserValues.cpp.
+        * css/parser/CSSParserValues.h: Copied from css/CSSParserValues.h.
+        * css/parser/SVGCSSParser.cpp: Copied from css/SVGCSSParser.cpp.
+        * page/Settings.in:
+
</ins><span class="cx"> 2016-08-23  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [MediaStream] Templatize MediaConstraint
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -3321,6 +3321,12 @@
</span><span class="cx">                 93F9B7A00BA6032600854064 /* JSCDATASection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F9B79E0BA6032600854064 /* JSCDATASection.cpp */; };
</span><span class="cx">                 93F9B7A10BA6032600854064 /* JSCDATASection.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F9B79F0BA6032600854064 /* JSCDATASection.h */; };
</span><span class="cx">                 93FDAFCA0B11307400E2746F /* EditorInsertAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 93FDAFC90B11307400E2746F /* EditorInsertAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                946D372D1D6CB2940077084F /* CSSParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D37281D6CB28B0077084F /* CSSParser.cpp */; };
+                946D372E1D6CB2940077084F /* CSSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D37291D6CB28B0077084F /* CSSParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                946D372F1D6CB2940077084F /* CSSParserMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D372A1D6CB28B0077084F /* CSSParserMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                946D37301D6CB2940077084F /* CSSParserValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D372B1D6CB28B0077084F /* CSSParserValues.cpp */; };
+                946D37311D6CB2940077084F /* CSSParserValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 946D372C1D6CB28B0077084F /* CSSParserValues.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                946D37331D6CC42B0077084F /* SVGCSSParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946D37321D6CC3720077084F /* SVGCSSParser.cpp */; };
</ins><span class="cx">                 96ABA42314BCB80E00D56204 /* GraphicsContext3DOpenGLCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 96ABA42214BCB80E00D56204 /* GraphicsContext3DOpenGLCommon.cpp */; };
</span><span class="cx">                 9703E1BF15DC4E37001F24C8 /* JSVoidCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97E9EC8B15DC492F004F2E71 /* JSVoidCallback.cpp */; };
</span><span class="cx">                 97059977107D975200A50A7C /* PolicyCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97059973107D975200A50A7C /* PolicyCallback.cpp */; };
</span><span class="lines">@@ -4502,7 +4508,6 @@
</span><span class="cx">                 B2227AF50D00BF220071B782 /* SVGZoomAndPan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B222795F0D00BF210071B782 /* SVGZoomAndPan.cpp */; };
</span><span class="cx">                 B2227AF60D00BF220071B782 /* SVGZoomAndPan.h in Headers */ = {isa = PBXBuildFile; fileRef = B22279600D00BF210071B782 /* SVGZoomAndPan.h */; };
</span><span class="cx">                 B2227B050D00BFF10071B782 /* SVGCSSComputedStyleDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2227B000D00BFF10071B782 /* SVGCSSComputedStyleDeclaration.cpp */; };
</span><del>-                B2227B060D00BFF10071B782 /* SVGCSSParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2227B010D00BFF10071B782 /* SVGCSSParser.cpp */; };
</del><span class="cx">                 B222F6980AB771950022EFAD /* JSSVGAngle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B222F6960AB771950022EFAD /* JSSVGAngle.cpp */; };
</span><span class="cx">                 B222F6990AB771950022EFAD /* JSSVGAngle.h in Headers */ = {isa = PBXBuildFile; fileRef = B222F6970AB771950022EFAD /* JSSVGAngle.h */; };
</span><span class="cx">                 B222F69C0AB771B80022EFAD /* JSSVGElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B222F69A0AB771B80022EFAD /* JSSVGElement.cpp */; };
</span><span class="lines">@@ -4918,8 +4923,6 @@
</span><span class="cx">                 BC00F0150E0A189500FD04E3 /* JSFile.h in Headers */ = {isa = PBXBuildFile; fileRef = BC00F0110E0A189500FD04E3 /* JSFile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 BC00F0160E0A189500FD04E3 /* JSFileList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC00F0120E0A189500FD04E3 /* JSFileList.cpp */; };
</span><span class="cx">                 BC00F0170E0A189500FD04E3 /* JSFileList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC00F0130E0A189500FD04E3 /* JSFileList.h */; };
</span><del>-                BC02A4B70E0997B9004B6D2B /* CSSParserValues.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02A4B60E0997B9004B6D2B /* CSSParserValues.h */; settings = {ATTRIBUTES = (Private, ); }; };
-                BC02A5400E099C5A004B6D2B /* CSSParserValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02A53F0E099C5A004B6D2B /* CSSParserValues.cpp */; };
</del><span class="cx">                 BC02A63C0E09A9CF004B6D2B /* CSSFunctionValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02A63B0E09A9CF004B6D2B /* CSSFunctionValue.h */; };
</span><span class="cx">                 BC02A6460E09AAE9004B6D2B /* CSSFunctionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02A6450E09AAE9004B6D2B /* CSSFunctionValue.cpp */; };
</span><span class="cx">                 BC06ED060BFD5BAE00856E9D /* JSHTMLTableSectionElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC06ED040BFD5BAE00856E9D /* JSHTMLTableSectionElement.cpp */; };
</span><span class="lines">@@ -5117,8 +5120,6 @@
</span><span class="cx">                 BC74DA491013F468007987AD /* JSRGBColor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC74DA471013F468007987AD /* JSRGBColor.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 BC76AC130DD7AD5C00415F34 /* ParserUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = BC76AC110DD7AD5C00415F34 /* ParserUtilities.h */; };
</span><span class="cx">                 BC772B3C0C4EA91E0083285F /* CSSHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772B360C4EA91E0083285F /* CSSHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                BC772B3D0C4EA91E0083285F /* CSSParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC772B370C4EA91E0083285F /* CSSParser.cpp */; };
-                BC772B3E0C4EA91E0083285F /* CSSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772B380C4EA91E0083285F /* CSSParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 BC772C460C4EB2C60083285F /* XMLHttpRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC772C440C4EB2C60083285F /* XMLHttpRequest.cpp */; };
</span><span class="cx">                 BC772C470C4EB2C60083285F /* XMLHttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772C450C4EB2C60083285F /* XMLHttpRequest.h */; };
</span><span class="cx">                 BC772C4E0C4EB3040083285F /* MIMETypeRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC772C4C0C4EB3040083285F /* MIMETypeRegistry.cpp */; };
</span><span class="lines">@@ -6311,13 +6312,13 @@
</span><span class="cx">                 F98FFF4511A2676200F548E8 /* CSSOMUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = F98FFF4311A2676200F548E8 /* CSSOMUtils.h */; };
</span><span class="cx">                 F9F0ED7A0DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F9F0ED770DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.h */; };
</span><span class="cx">                 FA654A6B1108ABED002615E0 /* MathMLTokenElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA654A691108ABED002615E0 /* MathMLTokenElement.cpp */; };
</span><del>-                FA765A6B1108ABED002615E0 /* MathMLRowElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA765A691108ABED002615E0 /* MathMLRowElement.cpp */; };
</del><span class="cx">                 FA654A6B1108ABED002616F1 /* MathMLOperatorElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA654A691108ABED002616F1 /* MathMLOperatorElement.cpp */; };
</span><span class="cx">                 FA654A6B1108ABED002626F1 /* MathMLUnderOverElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA654A691108ABED002626F1 /* MathMLUnderOverElement.cpp */; };
</span><span class="cx">                 FA654A6C1108ABED002615E0 /* MathMLTokenElement.h in Headers */ = {isa = PBXBuildFile; fileRef = FA654A6A1108ABED002615E0 /* MathMLTokenElement.h */; };
</span><del>-                FA765A6C1108ABED002615E0 /* MathMLRowElement.h in Headers */ = {isa = PBXBuildFile; fileRef = FA765A6A1108ABED002615E0 /* MathMLRowElement.h */; };
</del><span class="cx">                 FA654A6C1108ABED002616F1 /* MathMLOperatorElement.h in Headers */ = {isa = PBXBuildFile; fileRef = FA654A6A1108ABED002616F1 /* MathMLOperatorElement.h */; };
</span><span class="cx">                 FA654A6C1108ABED002626F1 /* MathMLUnderOverElement.h in Headers */ = {isa = PBXBuildFile; fileRef = FA654A6A1108ABED002626F1 /* MathMLUnderOverElement.h */; };
</span><ins>+                FA765A6B1108ABED002615E0 /* MathMLRowElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA765A691108ABED002615E0 /* MathMLRowElement.cpp */; };
+                FA765A6C1108ABED002615E0 /* MathMLRowElement.h in Headers */ = {isa = PBXBuildFile; fileRef = FA765A6A1108ABED002615E0 /* MathMLRowElement.h */; };
</ins><span class="cx">                 FABE72F41059C1EB00D888CC /* MathMLAnnotationElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABE72ED1059C1EB00D888CC /* MathMLAnnotationElement.cpp */; };
</span><span class="cx">                 FABE72F41059C1EB00D999DD /* MathMLElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FABE72ED1059C1EB00D999DD /* MathMLElement.cpp */; };
</span><span class="cx">                 FABE72F51059C1EB00D888CC /* MathMLAnnotationElement.h in Headers */ = {isa = PBXBuildFile; fileRef = FABE72EE1059C1EB00D888CC /* MathMLAnnotationElement.h */; };
</span><span class="lines">@@ -6332,7 +6333,6 @@
</span><span class="cx">                 FB3056C2169E5DAC0096A232 /* CSSGroupingRule.h in Headers */ = {isa = PBXBuildFile; fileRef = FB3056C1169E5DAC0096A232 /* CSSGroupingRule.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FB484F4C171F821E00040755 /* TransformFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB484F4A171F821E00040755 /* TransformFunctions.cpp */; };
</span><span class="cx">                 FB484F4D171F821E00040755 /* TransformFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = FB484F4B171F821E00040755 /* TransformFunctions.h */; };
</span><del>-                FB78AD2E151BF5E600FE54D3 /* CSSParserMode.h in Headers */ = {isa = PBXBuildFile; fileRef = FB78AD2C151BF5D200FE54D3 /* CSSParserMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 FB91392416AE4C17001FE682 /* DOMPath.h in Headers */ = {isa = PBXBuildFile; fileRef = FB91392016AE4B0B001FE682 /* DOMPath.h */; };
</span><span class="cx">                 FB91392A16AE4FC0001FE682 /* JSDOMPath.h in Headers */ = {isa = PBXBuildFile; fileRef = FB91392816AE4FC0001FE682 /* JSDOMPath.h */; };
</span><span class="cx">                 FB91392B16AE4FC0001FE682 /* JSDOMPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB91392916AE4FC0001FE682 /* JSDOMPath.cpp */; };
</span><span class="lines">@@ -10429,6 +10429,12 @@
</span><span class="cx">                 93F9B79E0BA6032600854064 /* JSCDATASection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCDATASection.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 93F9B79F0BA6032600854064 /* JSCDATASection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCDATASection.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 93FDAFC90B11307400E2746F /* EditorInsertAction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EditorInsertAction.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                946D37281D6CB28B0077084F /* CSSParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParser.cpp; path = parser/CSSParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                946D37291D6CB28B0077084F /* CSSParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParser.h; path = parser/CSSParser.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                946D372A1D6CB28B0077084F /* CSSParserMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParserMode.h; path = parser/CSSParserMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                946D372B1D6CB28B0077084F /* CSSParserValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParserValues.cpp; path = parser/CSSParserValues.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                946D372C1D6CB28B0077084F /* CSSParserValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParserValues.h; path = parser/CSSParserValues.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                946D37321D6CC3720077084F /* SVGCSSParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SVGCSSParser.cpp; path = parser/SVGCSSParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 950C4C02BED8936F818E2F99 /* JSSVGGraphicsElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSSVGGraphicsElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 96ABA42214BCB80E00D56204 /* GraphicsContext3DOpenGLCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContext3DOpenGLCommon.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 97059973107D975200A50A7C /* PolicyCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolicyCallback.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -11879,7 +11885,6 @@
</span><span class="cx">                 B22279600D00BF210071B782 /* SVGZoomAndPan.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SVGZoomAndPan.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 B22279610D00BF210071B782 /* SVGZoomAndPan.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SVGZoomAndPan.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 B2227B000D00BFF10071B782 /* SVGCSSComputedStyleDeclaration.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGCSSComputedStyleDeclaration.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                B2227B010D00BFF10071B782 /* SVGCSSParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGCSSParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 B2227B040D00BFF10071B782 /* SVGCSSValueKeywords.in */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SVGCSSValueKeywords.in; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 B222F6960AB771950022EFAD /* JSSVGAngle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGAngle.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 B222F6970AB771950022EFAD /* JSSVGAngle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSSVGAngle.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -12307,8 +12312,6 @@
</span><span class="cx">                 BC00F0110E0A189500FD04E3 /* JSFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC00F0120E0A189500FD04E3 /* JSFileList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFileList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC00F0130E0A189500FD04E3 /* JSFileList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFileList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                BC02A4B60E0997B9004B6D2B /* CSSParserValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSParserValues.h; sourceTree = &quot;&lt;group&gt;&quot;; };
-                BC02A53F0E099C5A004B6D2B /* CSSParserValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSParserValues.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 BC02A63B0E09A9CF004B6D2B /* CSSFunctionValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSFunctionValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC02A6450E09AAE9004B6D2B /* CSSFunctionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFunctionValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC06ED040BFD5BAE00856E9D /* JSHTMLTableSectionElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLTableSectionElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -12517,8 +12520,6 @@
</span><span class="cx">                 BC74DA471013F468007987AD /* JSRGBColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRGBColor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC76AC110DD7AD5C00415F34 /* ParserUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserUtilities.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC772B360C4EA91E0083285F /* CSSHelper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSSHelper.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                BC772B370C4EA91E0083285F /* CSSParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = CSSParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                BC772B380C4EA91E0083285F /* CSSParser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSSParser.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 BC772C440C4EB2C60083285F /* XMLHttpRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XMLHttpRequest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC772C450C4EB2C60083285F /* XMLHttpRequest.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XMLHttpRequest.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC772C4C0C4EB3040083285F /* MIMETypeRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MIMETypeRegistry.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -13884,14 +13885,14 @@
</span><span class="cx">                 FA654A631108ABB7002615E0 /* mathml.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = mathml.css; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FA654A671108ABE2002615E0 /* mathattrs.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mathattrs.in; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FA654A691108ABED002615E0 /* MathMLTokenElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLTokenElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                FA765A691108ABED002615E0 /* MathMLRowElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLRowElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 FA654A691108ABED002616F1 /* MathMLOperatorElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLOperatorElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FA654A691108ABED002626F1 /* MathMLUnderOverElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLUnderOverElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FA654A6A1108ABED002615E0 /* MathMLTokenElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLTokenElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                FA765A6A1108ABED002615E0 /* MathMLRowElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLRowElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 FA654A6A1108ABED002616F1 /* MathMLOperatorElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLOperatorElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FA654A6A1108ABED002626F1 /* MathMLUnderOverElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLUnderOverElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FA6E466FCD0418A9966A5B60 /* DNSResolveQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNSResolveQueue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                FA765A691108ABED002615E0 /* MathMLRowElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLRowElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                FA765A6A1108ABED002615E0 /* MathMLRowElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLRowElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 FABE72ED1059C1EB00D888CC /* MathMLAnnotationElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLAnnotationElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FABE72ED1059C1EB00D999DD /* MathMLElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathMLElement.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FABE72EE1059C1EB00D888CC /* MathMLAnnotationElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathMLAnnotationElement.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -13907,7 +13908,6 @@
</span><span class="cx">                 FB3056C1169E5DAC0096A232 /* CSSGroupingRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSGroupingRule.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FB484F4A171F821E00040755 /* TransformFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransformFunctions.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FB484F4B171F821E00040755 /* TransformFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformFunctions.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                FB78AD2C151BF5D200FE54D3 /* CSSParserMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSParserMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 FB91392016AE4B0B001FE682 /* DOMPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMPath.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FB91392116AE4B0B001FE682 /* DOMPath.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DOMPath.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FB91392816AE4FC0001FE682 /* JSDOMPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMPath.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -18048,6 +18048,19 @@
</span><span class="cx">                         path = cocoa;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="cx">                 };
</span><ins>+                946D37271D6CB2250077084F /* parser */ = {
+                        isa = PBXGroup;
+                        children = (
+                                946D37321D6CC3720077084F /* SVGCSSParser.cpp */,
+                                946D37281D6CB28B0077084F /* CSSParser.cpp */,
+                                946D37291D6CB28B0077084F /* CSSParser.h */,
+                                946D372A1D6CB28B0077084F /* CSSParserMode.h */,
+                                946D372B1D6CB28B0077084F /* CSSParserValues.cpp */,
+                                946D372C1D6CB28B0077084F /* CSSParserValues.h */,
+                        );
+                        name = parser;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
</ins><span class="cx">                 971145FE14EF006E00674FD9 /* Modules */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><span class="lines">@@ -22113,6 +22126,7 @@
</span><span class="cx">                 F523D18402DE42E8018635CA /* css */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                946D37271D6CB2250077084F /* parser */,
</ins><span class="cx">                                 FBD6AF8415EF21D4008B7110 /* BasicShapeFunctions.cpp */,
</span><span class="cx">                                 FBD6AF8515EF21D4008B7110 /* BasicShapeFunctions.h */,
</span><span class="cx">                                 A80E6CDA0A1989CA007FB8C5 /* Counter.h */,
</span><span class="lines">@@ -22214,11 +22228,6 @@
</span><span class="cx">                                 A80E6CCB0A1989CA007FB8C5 /* CSSPageRule.cpp */,
</span><span class="cx">                                 A80E6CD60A1989CA007FB8C5 /* CSSPageRule.h */,
</span><span class="cx">                                 85C56CA60AA89D5F00D95755 /* CSSPageRule.idl */,
</span><del>-                                BC772B370C4EA91E0083285F /* CSSParser.cpp */,
-                                BC772B380C4EA91E0083285F /* CSSParser.h */,
-                                FB78AD2C151BF5D200FE54D3 /* CSSParserMode.h */,
-                                BC02A53F0E099C5A004B6D2B /* CSSParserValues.cpp */,
-                                BC02A4B60E0997B9004B6D2B /* CSSParserValues.h */,
</del><span class="cx">                                 A80E6CDB0A1989CA007FB8C5 /* CSSPrimitiveValue.cpp */,
</span><span class="cx">                                 A80E6CBC0A1989CA007FB8C5 /* CSSPrimitiveValue.h */,
</span><span class="cx">                                 9307059009E0C75800B17FE4 /* CSSPrimitiveValue.idl */,
</span><span class="lines">@@ -22385,7 +22394,6 @@
</span><span class="cx">                                 850656DF0AAB454F002D15C0 /* StyleSheetList.idl */,
</span><span class="cx">                                 93CA4CA209DF93FA00DF8677 /* svg.css */,
</span><span class="cx">                                 B2227B000D00BFF10071B782 /* SVGCSSComputedStyleDeclaration.cpp */,
</span><del>-                                B2227B010D00BFF10071B782 /* SVGCSSParser.cpp */,
</del><span class="cx">                                 B2227B040D00BFF10071B782 /* SVGCSSValueKeywords.in */,
</span><span class="cx">                                 FB484F4A171F821E00040755 /* TransformFunctions.cpp */,
</span><span class="cx">                                 FB484F4B171F821E00040755 /* TransformFunctions.h */,
</span><span class="lines">@@ -23974,9 +23982,6 @@
</span><span class="cx">                                 314BE3A11B30F6B700141982 /* CSSNamedImageValue.h in Headers */,
</span><span class="cx">                                 F98FFF4511A2676200F548E8 /* CSSOMUtils.h in Headers */,
</span><span class="cx">                                 A80E6D000A1989CA007FB8C5 /* CSSPageRule.h in Headers */,
</span><del>-                                BC772B3E0C4EA91E0083285F /* CSSParser.h in Headers */,
-                                FB78AD2E151BF5E600FE54D3 /* CSSParserMode.h in Headers */,
-                                BC02A4B70E0997B9004B6D2B /* CSSParserValues.h in Headers */,
</del><span class="cx">                                 977B3863122883E900B81FF8 /* CSSPreloadScanner.h in Headers */,
</span><span class="cx">                                 A80E6CE60A1989CA007FB8C5 /* CSSPrimitiveValue.h in Headers */,
</span><span class="cx">                                 E1ED8AC30CC49BE000BFC557 /* CSSPrimitiveValueMappings.h in Headers */,
</span><span class="lines">@@ -25154,6 +25159,7 @@
</span><span class="cx">                                 B2FA3DB50AB75A6F000E5AC4 /* JSSVGPathElement.h in Headers */,
</span><span class="cx">                                 B2FA3DB70AB75A6F000E5AC4 /* JSSVGPathSeg.h in Headers */,
</span><span class="cx">                                 B2FA3DB90AB75A6F000E5AC4 /* JSSVGPathSegArcAbs.h in Headers */,
</span><ins>+                                946D372E1D6CB2940077084F /* CSSParser.h in Headers */,
</ins><span class="cx">                                 B2FA3DBB0AB75A6F000E5AC4 /* JSSVGPathSegArcRel.h in Headers */,
</span><span class="cx">                                 B2FA3DBD0AB75A6F000E5AC4 /* JSSVGPathSegClosePath.h in Headers */,
</span><span class="cx">                                 B2FA3DBF0AB75A6F000E5AC4 /* JSSVGPathSegCurvetoCubicAbs.h in Headers */,
</span><span class="lines">@@ -25326,6 +25332,7 @@
</span><span class="cx">                                 E4E39AFB1330EFA8003AB274 /* LegacyTileLayerPool.h in Headers */,
</span><span class="cx">                                 512DD8F50D91E6AF000F89EE /* LegacyWebArchive.h in Headers */,
</span><span class="cx">                                 BCE65BEB0EACDF16007E4533 /* Length.h in Headers */,
</span><ins>+                                946D372F1D6CB2940077084F /* CSSParserMode.h in Headers */,
</ins><span class="cx">                                 BCFF64910EAD15C200C1D6F7 /* LengthBox.h in Headers */,
</span><span class="cx">                                 E5BA7D63151437CA00FE1E3F /* LengthFunctions.h in Headers */,
</span><span class="cx">                                 0F8716701C869D83004FF0DE /* LengthPoint.h in Headers */,
</span><span class="lines">@@ -26505,6 +26512,7 @@
</span><span class="cx">                                 0813A4EA1284132600992511 /* SVGStaticPropertyTearOff.h in Headers */,
</span><span class="cx">                                 B2227AA90D00BF220071B782 /* SVGStopElement.h in Headers */,
</span><span class="cx">                                 B2227AAC0D00BF220071B782 /* SVGStringList.h in Headers */,
</span><ins>+                                946D37311D6CB2940077084F /* CSSParserValues.h in Headers */,
</ins><span class="cx">                                 B2227AB80D00BF220071B782 /* SVGStyleElement.h in Headers */,
</span><span class="cx">                                 B2227ABB0D00BF220071B782 /* SVGSVGElement.h in Headers */,
</span><span class="cx">                                 B2227ABE0D00BF220071B782 /* SVGSwitchElement.h in Headers */,
</span><span class="lines">@@ -27624,8 +27632,6 @@
</span><span class="cx">                                 314BE3A31B30F6D100141982 /* CSSNamedImageValue.cpp in Sources */,
</span><span class="cx">                                 F98FFF4411A2676200F548E8 /* CSSOMUtils.cpp in Sources */,
</span><span class="cx">                                 A80E6CF50A1989CA007FB8C5 /* CSSPageRule.cpp in Sources */,
</span><del>-                                BC772B3D0C4EA91E0083285F /* CSSParser.cpp in Sources */,
-                                BC02A5400E099C5A004B6D2B /* CSSParserValues.cpp in Sources */,
</del><span class="cx">                                 977B3862122883E900B81FF8 /* CSSPreloadScanner.cpp in Sources */,
</span><span class="cx">                                 A80E6D050A1989CA007FB8C5 /* CSSPrimitiveValue.cpp in Sources */,
</span><span class="cx">                                 A80E6CF70A1989CA007FB8C5 /* CSSProperty.cpp in Sources */,
</span><span class="lines">@@ -28634,6 +28640,7 @@
</span><span class="cx">                                 1A750D8D0A90E521000FF215 /* JSNodeIterator.cpp in Sources */,
</span><span class="cx">                                 1A750DD40A90E729000FF215 /* JSNodeIteratorCustom.cpp in Sources */,
</span><span class="cx">                                 BCD9C2C20C17B69E005C90A2 /* JSNodeList.cpp in Sources */,
</span><ins>+                                946D37301D6CB2940077084F /* CSSParserValues.cpp in Sources */,
</ins><span class="cx">                                 BCD9C2650C17AA67005C90A2 /* JSNodeListCustom.cpp in Sources */,
</span><span class="cx">                                 7C91A38F1B498ABE003F9EFA /* JSNodeOrString.cpp in Sources */,
</span><span class="cx">                                 33503CA310179AD7003B47E1 /* JSNotification.cpp in Sources */,
</span><span class="lines">@@ -29297,6 +29304,7 @@
</span><span class="cx">                                 0F43C85D189E10CF00019AE2 /* PerformanceTiming.cpp in Sources */,
</span><span class="cx">                                 FD581FB41520F93B003A7A75 /* PeriodicWave.cpp in Sources */,
</span><span class="cx">                                 49D5DC2D0F423A73008F20FD /* PerspectiveTransformOperation.cpp in Sources */,
</span><ins>+                                946D37331D6CC42B0077084F /* SVGCSSParser.cpp in Sources */,
</ins><span class="cx">                                 D0FF2A5D11F8C45A007E74E0 /* PingLoader.cpp in Sources */,
</span><span class="cx">                                 CD7D33431C7A123F00041293 /* PixelBufferConformerCV.cpp in Sources */,
</span><span class="cx">                                 0FDF45A71BD1C6FD00E4FA8C /* PlatformCAAnimation.cpp in Sources */,
</span><span class="lines">@@ -29829,7 +29837,6 @@
</span><span class="cx">                                 B22279A10D00BF220071B782 /* SVGColor.cpp in Sources */,
</span><span class="cx">                                 B22279A40D00BF220071B782 /* SVGComponentTransferFunctionElement.cpp in Sources */,
</span><span class="cx">                                 B2227B050D00BFF10071B782 /* SVGCSSComputedStyleDeclaration.cpp in Sources */,
</span><del>-                                B2227B060D00BFF10071B782 /* SVGCSSParser.cpp in Sources */,
</del><span class="cx">                                 B22279A70D00BF220071B782 /* SVGCursorElement.cpp in Sources */,
</span><span class="cx">                                 B22279AD0D00BF220071B782 /* SVGDefsElement.cpp in Sources */,
</span><span class="cx">                                 B22279B00D00BF220071B782 /* SVGDescElement.cpp in Sources */,
</span><span class="lines">@@ -30032,6 +30039,7 @@
</span><span class="cx">                                 7AA3A699194A64E7001CBD24 /* TileController.cpp in Sources */,
</span><span class="cx">                                 1F72BF0A187FD4490009BCB3 /* TileControllerMemoryHandlerIOS.cpp in Sources */,
</span><span class="cx">                                 7AA3A6A3194B5C22001CBD24 /* TileCoverageMap.cpp in Sources */,
</span><ins>+                                946D372D1D6CB2940077084F /* CSSParser.cpp in Sources */,
</ins><span class="cx">                                 7AA3A69B194A64E7001CBD24 /* TileGrid.cpp in Sources */,
</span><span class="cx">                                 498770F21242C535002226BA /* TilingData.cpp in Sources */,
</span><span class="cx">                                 F55B3DDB1251F12D003EF269 /* TimeInputType.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParsercpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/css/CSSParser.cpp (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.cpp        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/css/CSSParser.cpp        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -1,13857 +0,0 @@
</span><del>-/*
- * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
- * Copyright (C) 2004-2015 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Nicholas Shanks &lt;webkit@nickshanks.com&gt;
- * Copyright (C) 2008 Eric Seidel &lt;eric@webkit.org&gt;
- * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include &quot;config.h&quot;
-#include &quot;CSSParser.h&quot;
-
-#include &quot;CSSAnimationTriggerScrollValue.h&quot;
-#include &quot;CSSAspectRatioValue.h&quot;
-#include &quot;CSSBasicShapes.h&quot;
-#include &quot;CSSBorderImage.h&quot;
-#include &quot;CSSBorderImageSliceValue.h&quot;
-#include &quot;CSSCanvasValue.h&quot;
-#include &quot;CSSContentDistributionValue.h&quot;
-#include &quot;CSSCrossfadeValue.h&quot;
-#include &quot;CSSCursorImageValue.h&quot;
-#include &quot;CSSCustomPropertyValue.h&quot;
-#include &quot;CSSFilterImageValue.h&quot;
-#include &quot;CSSFontFaceRule.h&quot;
-#include &quot;CSSFontFaceSrcValue.h&quot;
-#include &quot;CSSFontFeatureValue.h&quot;
-#include &quot;CSSFontValue.h&quot;
-#include &quot;CSSFunctionValue.h&quot;
-#include &quot;CSSGradientValue.h&quot;
-#include &quot;CSSImageSetValue.h&quot;
-#include &quot;CSSImageValue.h&quot;
-#include &quot;CSSInheritedValue.h&quot;
-#include &quot;CSSInitialValue.h&quot;
-#include &quot;CSSKeyframeRule.h&quot;
-#include &quot;CSSKeyframesRule.h&quot;
-#include &quot;CSSLineBoxContainValue.h&quot;
-#include &quot;CSSMediaRule.h&quot;
-#include &quot;CSSNamedImageValue.h&quot;
-#include &quot;CSSPageRule.h&quot;
-#include &quot;CSSPrimitiveValue.h&quot;
-#include &quot;CSSPrimitiveValueMappings.h&quot;
-#include &quot;CSSPropertySourceData.h&quot;
-#include &quot;CSSReflectValue.h&quot;
-#include &quot;CSSRevertValue.h&quot;
-#include &quot;CSSSelector.h&quot;
-#include &quot;CSSShadowValue.h&quot;
-#include &quot;CSSStyleSheet.h&quot;
-#include &quot;CSSTimingFunctionValue.h&quot;
-#include &quot;CSSUnicodeRangeValue.h&quot;
-#include &quot;CSSUnsetValue.h&quot;
-#include &quot;CSSValueKeywords.h&quot;
-#include &quot;CSSValueList.h&quot;
-#include &quot;CSSValuePool.h&quot;
-#include &quot;CSSVariableDependentValue.h&quot;
-#include &quot;Counter.h&quot;
-#include &quot;Document.h&quot;
-#include &quot;FloatConversion.h&quot;
-#include &quot;GridArea.h&quot;
-#include &quot;HTMLOptGroupElement.h&quot;
-#include &quot;HTMLParserIdioms.h&quot;
-#include &quot;HashTools.h&quot;
-#include &quot;MediaList.h&quot;
-#include &quot;MediaQueryExp.h&quot;
-#include &quot;Page.h&quot;
-#include &quot;PageConsoleClient.h&quot;
-#include &quot;Pair.h&quot;
-#include &quot;Rect.h&quot;
-#include &quot;RenderTheme.h&quot;
-#include &quot;RuntimeEnabledFeatures.h&quot;
-#include &quot;SVGParserUtilities.h&quot;
-#include &quot;SVGPathByteStream.h&quot;
-#include &quot;SVGPathUtilities.h&quot;
-#include &quot;SelectorChecker.h&quot;
-#include &quot;SelectorCheckerTestFunctions.h&quot;
-#include &quot;Settings.h&quot;
-#include &quot;StyleProperties.h&quot;
-#include &quot;StylePropertyShorthand.h&quot;
-#include &quot;StylePropertyShorthandFunctions.h&quot;
-#include &quot;StyleRule.h&quot;
-#include &quot;StyleRuleImport.h&quot;
-#include &quot;StyleSheetContents.h&quot;
-#include &quot;TextEncoding.h&quot;
-#include &quot;WebKitCSSFilterValue.h&quot;
-#include &quot;WebKitCSSRegionRule.h&quot;
-#include &quot;WebKitCSSTransformValue.h&quot;
-#include &lt;bitset&gt;
-#include &lt;limits.h&gt;
-#include &lt;wtf/HexNumber.h&gt;
-#include &lt;wtf/NeverDestroyed.h&gt;
-#include &lt;wtf/StdLibExtras.h&gt;
-#include &lt;wtf/dtoa.h&gt;
-#include &lt;wtf/text/StringBuffer.h&gt;
-#include &lt;wtf/text/StringBuilder.h&gt;
-#include &lt;wtf/text/StringImpl.h&gt;
-
-#if ENABLE(CSS_GRID_LAYOUT)
-#include &quot;CSSGridAutoRepeatValue.h&quot;
-#include &quot;CSSGridLineNamesValue.h&quot;
-#include &quot;CSSGridTemplateAreasValue.h&quot;
-#endif
-
-#if ENABLE(CSS_SCROLL_SNAP)
-#include &quot;LengthRepeat.h&quot;
-#endif
-
-#if ENABLE(DASHBOARD_SUPPORT)
-#include &quot;DashboardRegion.h&quot;
-#endif
-
-#define YYDEBUG 0
-
-#if YYDEBUG &gt; 0
-extern int cssyydebug;
-#endif
-
-extern int cssyyparse(WebCore::CSSParser*);
-
-using namespace WTF;
-
-namespace {
-
-enum PropertyType {
-    PropertyExplicit,
-    PropertyImplicit
-};
-
-class ImplicitScope {
-    WTF_MAKE_NONCOPYABLE(ImplicitScope);
-public:
-    ImplicitScope(WebCore::CSSParser&amp; parser, PropertyType propertyType)
-        : m_parser(parser)
-    {
-        m_parser.m_implicitShorthand = propertyType == PropertyImplicit;
-    }
-
-    ~ImplicitScope()
-    {
-        m_parser.m_implicitShorthand = false;
-    }
-
-private:
-    WebCore::CSSParser&amp; m_parser;
-};
-
-} // namespace
-
-namespace WebCore {
-
-const unsigned CSSParser::invalidParsedPropertiesCount = std::numeric_limits&lt;unsigned&gt;::max();
-static const double MAX_SCALE = 1000000;
-
-template&lt;unsigned length&gt; bool equalLettersIgnoringASCIICase(const CSSParserValue&amp; value, const char (&amp;lowercaseLetters)[length])
-{
-    ASSERT(value.unit == CSSPrimitiveValue::CSS_IDENT || value.unit == CSSPrimitiveValue::CSS_STRING);
-    return equalLettersIgnoringASCIICase(value.string, lowercaseLetters);
-}
-
-static bool hasPrefix(const char* string, unsigned length, const char* prefix)
-{
-    for (unsigned i = 0; i &lt; length; ++i) {
-        if (!prefix[i])
-            return true;
-        if (string[i] != prefix[i])
-            return false;
-    }
-    return false;
-}
-
-template&lt;typename... Args&gt;
-static Ref&lt;CSSPrimitiveValue&gt; createPrimitiveValuePair(Args&amp;&amp;... args)
-{
-    return CSSValuePool::singleton().createValue(Pair::create(std::forward&lt;Args&gt;(args)...));
-}
-
-class AnimationParseContext {
-public:
-    AnimationParseContext() = default;
-
-    void commitFirstAnimation()
-    {
-        m_firstAnimationCommitted = true;
-    }
-
-    bool hasCommittedFirstAnimation() const
-    {
-        return m_firstAnimationCommitted;
-    }
-
-    void commitAnimationPropertyKeyword()
-    {
-        m_animationPropertyKeywordAllowed = false;
-    }
-
-    bool animationPropertyKeywordAllowed() const
-    {
-        return m_animationPropertyKeywordAllowed;
-    }
-
-    bool hasSeenAnimationPropertyKeyword() const
-    {
-        return m_hasSeenAnimationPropertyKeyword;
-    }
-
-    void sawAnimationPropertyKeyword()
-    {
-        m_hasSeenAnimationPropertyKeyword = true;
-    }
-
-private:
-    bool m_animationPropertyKeywordAllowed { true };
-    bool m_firstAnimationCommitted { false };
-    bool m_hasSeenAnimationPropertyKeyword { false };
-};
-
-const CSSParserContext&amp; strictCSSParserContext()
-{
-    static NeverDestroyed&lt;CSSParserContext&gt; strictContext(CSSStrictMode);
-    return strictContext;
-}
-
-CSSParserContext::CSSParserContext(CSSParserMode mode, const URL&amp; baseURL)
-    : baseURL(baseURL)
-    , mode(mode)
-#if ENABLE(CSS_GRID_LAYOUT)
-    , cssGridLayoutEnabled(RuntimeEnabledFeatures::sharedFeatures().isCSSGridLayoutEnabled())
-#endif
-{
-#if PLATFORM(IOS)
-    // FIXME: Force the site specific quirk below to work on iOS. Investigating other site specific quirks
-    // to see if we can enable the preference all together is to be handled by:
-    // &lt;rdar://problem/8493309&gt; Investigate Enabling Site Specific Quirks in MobileSafari and UIWebView
-    needsSiteSpecificQuirks = true;
-#endif
-}
-
-CSSParserContext::CSSParserContext(Document&amp; document, const URL&amp; baseURL, const String&amp; charset)
-    : baseURL(baseURL.isNull() ? document.baseURL() : baseURL)
-    , charset(charset)
-    , mode(document.inQuirksMode() ? CSSQuirksMode : CSSStrictMode)
-    , isHTMLDocument(document.isHTMLDocument())
-#if ENABLE(CSS_GRID_LAYOUT)
-    , cssGridLayoutEnabled(document.isCSSGridLayoutEnabled())
-#endif
-{
-    if (Settings* settings = document.settings()) {
-        needsSiteSpecificQuirks = settings-&gt;needsSiteSpecificQuirks();
-        enforcesCSSMIMETypeInNoQuirksMode = settings-&gt;enforceCSSMIMETypeInNoQuirksMode();
-        useLegacyBackgroundSizeShorthandBehavior = settings-&gt;useLegacyBackgroundSizeShorthandBehavior();
-#if ENABLE(IOS_TEXT_AUTOSIZING)
-        textAutosizingEnabled = settings-&gt;textAutosizingEnabled();
-#endif
-        springTimingFunctionEnabled = settings-&gt;springTimingFunctionEnabled();
-    }
-
-#if PLATFORM(IOS)
-    // FIXME: Force the site specific quirk below to work on iOS. Investigating other site specific quirks
-    // to see if we can enable the preference all together is to be handled by:
-    // &lt;rdar://problem/8493309&gt; Investigate Enabling Site Specific Quirks in MobileSafari and UIWebView
-    needsSiteSpecificQuirks = true;
-#endif
-}
-
-bool operator==(const CSSParserContext&amp; a, const CSSParserContext&amp; b)
-{
-    return a.baseURL == b.baseURL
-        &amp;&amp; a.charset == b.charset
-        &amp;&amp; a.mode == b.mode
-        &amp;&amp; a.isHTMLDocument == b.isHTMLDocument
-#if ENABLE(CSS_GRID_LAYOUT)
-        &amp;&amp; a.cssGridLayoutEnabled == b.cssGridLayoutEnabled
-#endif
-        &amp;&amp; a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks
-        &amp;&amp; a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode
-        &amp;&amp; a.useLegacyBackgroundSizeShorthandBehavior == b.useLegacyBackgroundSizeShorthandBehavior
-        &amp;&amp; a.springTimingFunctionEnabled == b.springTimingFunctionEnabled;
-}
-
-CSSParser::CSSParser(const CSSParserContext&amp; context)
-    : m_context(context)
-{
-#if YYDEBUG &gt; 0
-    cssyydebug = 1;
-#endif
-}
-
-CSSParser::~CSSParser()
-{
-}
-
-template&lt;typename CharacterType&gt; ALWAYS_INLINE static void convertToASCIILowercaseInPlace(CharacterType* characters, unsigned length)
-{
-    for (unsigned i = 0; i &lt; length; ++i)
-        characters[i] = toASCIILower(characters[i]);
-}
-
-void CSSParserString::convertToASCIILowercaseInPlace()
-{
-    if (is8Bit())
-        WebCore::convertToASCIILowercaseInPlace(characters8(), length());
-    else
-        WebCore::convertToASCIILowercaseInPlace(characters16(), length());
-}
-
-void CSSParser::setupParser(const char* prefix, unsigned prefixLength, StringView string, const char* suffix, unsigned suffixLength)
-{
-    m_parsedTextPrefixLength = prefixLength;
-    unsigned stringLength = string.length();
-    unsigned length = stringLength + m_parsedTextPrefixLength + suffixLength + 1;
-    m_length = length;
-
-    if (!stringLength || string.is8Bit()) {
-        m_dataStart8 = std::make_unique&lt;LChar[]&gt;(length);
-        for (unsigned i = 0; i &lt; m_parsedTextPrefixLength; ++i)
-            m_dataStart8[i] = prefix[i];
-
-        if (stringLength)
-            memcpy(m_dataStart8.get() + m_parsedTextPrefixLength, string.characters8(), stringLength * sizeof(LChar));
-
-        unsigned start = m_parsedTextPrefixLength + stringLength;
-        unsigned end = start + suffixLength;
-        for (unsigned i = start; i &lt; end; i++)
-            m_dataStart8[i] = suffix[i - start];
-
-        m_dataStart8[length - 1] = '\0';
-
-        m_is8BitSource = true;
-        m_currentCharacter8 = m_dataStart8.get();
-        m_currentCharacter16 = nullptr;
-        setTokenStart&lt;LChar&gt;(m_currentCharacter8);
-        m_lexFunc = &amp;CSSParser::realLex&lt;LChar&gt;;
-        return;
-    }
-
-    m_dataStart16 = std::make_unique&lt;UChar[]&gt;(length);
-    for (unsigned i = 0; i &lt; m_parsedTextPrefixLength; ++i)
-        m_dataStart16[i] = prefix[i];
-
-    ASSERT(stringLength);
-    memcpy(m_dataStart16.get() + m_parsedTextPrefixLength, string.characters16(), stringLength * sizeof(UChar));
-
-    unsigned start = m_parsedTextPrefixLength + stringLength;
-    unsigned end = start + suffixLength;
-    for (unsigned i = start; i &lt; end; i++)
-        m_dataStart16[i] = suffix[i - start];
-
-    m_dataStart16[length - 1] = '\0';
-
-    m_is8BitSource = false;
-    m_currentCharacter8 = nullptr;
-    m_currentCharacter16 = m_dataStart16.get();
-    setTokenStart&lt;UChar&gt;(m_currentCharacter16);
-    m_lexFunc = &amp;CSSParser::realLex&lt;UChar&gt;;
-}
-
-void CSSParser::parseSheet(StyleSheetContents* sheet, const String&amp; string, const TextPosition&amp; textPosition, RuleSourceDataList* ruleSourceDataResult, bool logErrors)
-{
-    setStyleSheet(sheet);
-    m_defaultNamespace = starAtom; // Reset the default namespace.
-    if (ruleSourceDataResult)
-        m_currentRuleDataStack = std::make_unique&lt;RuleSourceDataList&gt;();
-    m_ruleSourceDataResult = ruleSourceDataResult;
-
-    m_logErrors = logErrors &amp;&amp; sheet-&gt;singleOwnerDocument() &amp;&amp; !sheet-&gt;baseURL().isEmpty() &amp;&amp; sheet-&gt;singleOwnerDocument()-&gt;page();
-    m_ignoreErrorsInDeclaration = false;
-    m_sheetStartLineNumber = textPosition.m_line.zeroBasedInt();
-    m_sheetStartColumnNumber = textPosition.m_column.zeroBasedInt();
-    m_lineNumber = m_sheetStartLineNumber;
-    m_columnOffsetForLine = 0;
-    setupParser(&quot;&quot;, string, &quot;&quot;);
-    cssyyparse(this);
-    sheet-&gt;shrinkToFit();
-    m_currentRuleDataStack.reset();
-    m_ruleSourceDataResult = nullptr;
-    m_rule = nullptr;
-    m_ignoreErrorsInDeclaration = false;
-    m_logErrors = false;
-}
-
-RefPtr&lt;StyleRuleBase&gt; CSSParser::parseRule(StyleSheetContents* sheet, const String&amp; string)
-{
-    setStyleSheet(sheet);
-    m_allowNamespaceDeclarations = false;
-    setupParser(&quot;@-webkit-rule{&quot;, string, &quot;} &quot;);
-    cssyyparse(this);
-    return m_rule;
-}
-
-RefPtr&lt;StyleKeyframe&gt; CSSParser::parseKeyframeRule(StyleSheetContents* sheet, const String&amp; string)
-{
-    setStyleSheet(sheet);
-    setupParser(&quot;@-webkit-keyframe-rule{ &quot;, string, &quot;} &quot;);
-    cssyyparse(this);
-    return m_keyframe;
-}
-
-bool CSSParser::parseSupportsCondition(const String&amp; string)
-{
-    m_supportsCondition = false;
-    // can't use { because tokenizer state switches from supports to initial state when it sees { token.
-    // instead insert one &quot; &quot; (which is WHITESPACE in CSSGrammar.y)
-    setupParser(&quot;@-webkit-supports-condition &quot;, string, &quot;} &quot;);
-    cssyyparse(this);
-    return m_supportsCondition;
-}
-
-static inline bool isColorPropertyID(CSSPropertyID propertyId)
-{
-    switch (propertyId) {
-    case CSSPropertyColor:
-    case CSSPropertyBackgroundColor:
-    case CSSPropertyBorderBottomColor:
-    case CSSPropertyBorderLeftColor:
-    case CSSPropertyBorderRightColor:
-    case CSSPropertyBorderTopColor:
-    case CSSPropertyOutlineColor:
-    case CSSPropertyTextLineThroughColor:
-    case CSSPropertyTextOverlineColor:
-    case CSSPropertyTextUnderlineColor:
-    case CSSPropertyWebkitBorderAfterColor:
-    case CSSPropertyWebkitBorderBeforeColor:
-    case CSSPropertyWebkitBorderEndColor:
-    case CSSPropertyWebkitBorderStartColor:
-    case CSSPropertyColumnRuleColor:
-    case CSSPropertyWebkitTextDecorationColor:
-    case CSSPropertyWebkitTextEmphasisColor:
-    case CSSPropertyWebkitTextFillColor:
-    case CSSPropertyWebkitTextStrokeColor:
-        return true;
-    default:
-        return false;
-    }
-}
-
-bool CSSParser::isValidSystemColorValue(CSSValueID valueID)
-{
-    return valueID &gt;= CSSValueAqua &amp;&amp; valueID &lt;= CSSValueAppleSystemYellow;
-}
-
-static bool validPrimitiveValueColor(CSSValueID valueID, bool strict = false)
-{
-    return (valueID == CSSValueWebkitText || valueID == CSSValueCurrentcolor || valueID == CSSValueMenu
-        || CSSParser::isValidSystemColorValue(valueID) || valueID == CSSValueAlpha
-        || (valueID &gt;= CSSValueWebkitFocusRingColor &amp;&amp; valueID &lt; CSSValueWebkitText &amp;&amp; !strict));
-}
-
-static CSSParser::ParseResult parseColorValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyId, const String&amp; string, bool important, CSSParserMode cssParserMode)
-{
-    ASSERT(!string.isEmpty());
-    bool strict = isStrictParserMode(cssParserMode);
-    if (!isColorPropertyID(propertyId))
-        return CSSParser::ParseResult::Error;
-
-    CSSParserString cssString;
-    cssString.init(string);
-    CSSValueID valueID = cssValueKeywordID(cssString);
-    if (validPrimitiveValueColor(valueID, strict)) {
-        auto value = CSSValuePool::singleton().createIdentifierValue(valueID);
-        return declaration.addParsedProperty(CSSProperty(propertyId, WTFMove(value), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
-    }
-    RGBA32 color;
-    if (!CSSParser::fastParseColor(color, string, strict &amp;&amp; string[0] != '#'))
-        return CSSParser::ParseResult::Error;
-
-    auto value = CSSValuePool::singleton().createColorValue(color);
-    return declaration.addParsedProperty(CSSProperty(propertyId, WTFMove(value), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
-}
-
-static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool&amp; acceptsNegativeNumbers)
-{
-    switch (propertyId) {
-    case CSSPropertyFontSize:
-    case CSSPropertyHeight:
-    case CSSPropertyWidth:
-    case CSSPropertyMinHeight:
-    case CSSPropertyMinWidth:
-    case CSSPropertyPaddingBottom:
-    case CSSPropertyPaddingLeft:
-    case CSSPropertyPaddingRight:
-    case CSSPropertyPaddingTop:
-    case CSSPropertyWebkitLogicalWidth:
-    case CSSPropertyWebkitLogicalHeight:
-    case CSSPropertyWebkitMinLogicalWidth:
-    case CSSPropertyWebkitMinLogicalHeight:
-    case CSSPropertyWebkitPaddingAfter:
-    case CSSPropertyWebkitPaddingBefore:
-    case CSSPropertyWebkitPaddingEnd:
-    case CSSPropertyWebkitPaddingStart:
-#if ENABLE(CSS_GRID_LAYOUT)
-    case CSSPropertyGridColumnGap:
-    case CSSPropertyGridRowGap:
-#endif
-#if ENABLE(CSS_SHAPES)
-    case CSSPropertyWebkitShapeMargin:
-#endif
-        acceptsNegativeNumbers = false;
-        return true;
-    case CSSPropertyBottom:
-    case CSSPropertyCx:
-    case CSSPropertyCy:
-    case CSSPropertyLeft:
-    case CSSPropertyMarginBottom:
-    case CSSPropertyMarginLeft:
-    case CSSPropertyMarginRight:
-    case CSSPropertyMarginTop:
-    case CSSPropertyR:
-    case CSSPropertyRx:
-    case CSSPropertyRy:
-    case CSSPropertyRight:
-    case CSSPropertyTop:
-    case CSSPropertyWebkitMarginAfter:
-    case CSSPropertyWebkitMarginBefore:
-    case CSSPropertyWebkitMarginEnd:
-    case CSSPropertyWebkitMarginStart:
-    case CSSPropertyX:
-    case CSSPropertyY:
-        acceptsNegativeNumbers = true;
-        return true;
-    default:
-        return false;
-    }
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool parseSimpleLength(const CharacterType* characters, unsigned&amp; length, CSSPrimitiveValue::UnitTypes&amp; unit, double&amp; number)
-{
-    if (length &gt; 2 &amp;&amp; (characters[length - 2] | 0x20) == 'p' &amp;&amp; (characters[length - 1] | 0x20) == 'x') {
-        length -= 2;
-        unit = CSSPrimitiveValue::CSS_PX;
-    } else if (length &gt; 1 &amp;&amp; characters[length - 1] == '%') {
-        length -= 1;
-        unit = CSSPrimitiveValue::CSS_PERCENTAGE;
-    }
-
-    // We rely on charactersToDouble for validation as well. The function
-    // will set &quot;ok&quot; to &quot;false&quot; if the entire passed-in character range does
-    // not represent a double.
-    bool ok;
-    number = charactersToDouble(characters, length, &amp;ok);
-    return ok;
-}
-
-static CSSParser::ParseResult parseSimpleLengthValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyId, const String&amp; string, bool important, CSSParserMode cssParserMode)
-{
-    ASSERT(!string.isEmpty());
-    bool acceptsNegativeNumbers;
-    if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
-        return CSSParser::ParseResult::Error;
-
-    unsigned length = string.length();
-    double number;
-    CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
-
-    if (string.is8Bit()) {
-        if (!parseSimpleLength(string.characters8(), length, unit, number))
-            return CSSParser::ParseResult::Error;
-    } else {
-        if (!parseSimpleLength(string.characters16(), length, unit, number))
-            return CSSParser::ParseResult::Error;
-    }
-
-    if (unit == CSSPrimitiveValue::CSS_NUMBER) {
-        if (number &amp;&amp; isStrictParserMode(cssParserMode))
-            return CSSParser::ParseResult::Error;
-        unit = CSSPrimitiveValue::CSS_PX;
-    }
-    if (number &lt; 0 &amp;&amp; !acceptsNegativeNumbers)
-        return CSSParser::ParseResult::Error;
-    if (std::isinf(number))
-        return CSSParser::ParseResult::Error;
-
-    auto value = CSSValuePool::singleton().createValue(number, unit);
-    return declaration.addParsedProperty(CSSProperty(propertyId, WTFMove(value), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
-}
-
-static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext&amp; parserContext, StyleSheetContents* styleSheetContents)
-{
-    if (!valueID)
-        return false;
-
-    switch (propertyId) {
-    case CSSPropertyBorderCollapse: // collapse | separate | inherit
-        if (valueID == CSSValueCollapse || valueID == CSSValueSeparate)
-            return true;
-        break;
-    case CSSPropertyBorderTopStyle: // &lt;border-style&gt; | inherit
-    case CSSPropertyBorderRightStyle: // Defined as: none | hidden | dotted | dashed |
-    case CSSPropertyBorderBottomStyle: // solid | double | groove | ridge | inset | outset
-    case CSSPropertyBorderLeftStyle:
-    case CSSPropertyWebkitBorderAfterStyle:
-    case CSSPropertyWebkitBorderBeforeStyle:
-    case CSSPropertyWebkitBorderEndStyle:
-    case CSSPropertyWebkitBorderStartStyle:
-    case CSSPropertyColumnRuleStyle:
-        if (valueID &gt;= CSSValueNone &amp;&amp; valueID &lt;= CSSValueDouble)
-            return true;
-        break;
-    case CSSPropertyBoxSizing:
-         if (valueID == CSSValueBorderBox || valueID == CSSValueContentBox)
-             return true;
-         break;
-    case CSSPropertyCaptionSide: // top | bottom | left | right | inherit
-        if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueTop || valueID == CSSValueBottom)
-            return true;
-        break;
-    case CSSPropertyClear: // none | left | right | both | inherit
-        if (valueID == CSSValueNone || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueBoth)
-            return true;
-        break;
-    case CSSPropertyDirection: // ltr | rtl | inherit
-        if (valueID == CSSValueLtr || valueID == CSSValueRtl)
-            return true;
-        break;
-    case CSSPropertyDisplay:
-        // inline | block | list-item | inline-block | table |
-        // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
-        // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none | inherit
-        // flex | -webkit-flex | inline-flex | -webkit-inline-flex | grid | inline-grid | contents
-        if ((valueID &gt;= CSSValueInline &amp;&amp; valueID &lt;= CSSValueContents) || valueID == CSSValueNone)
-            return true;
-#if ENABLE(CSS_GRID_LAYOUT)
-        if (parserContext.cssGridLayoutEnabled &amp;&amp; (valueID == CSSValueGrid || valueID == CSSValueInlineGrid))
-            return true;
-#endif
-        break;
-
-    case CSSPropertyEmptyCells: // show | hide | inherit
-        if (valueID == CSSValueShow || valueID == CSSValueHide)
-            return true;
-        break;
-    case CSSPropertyFloat: // left | right | none | center (for buggy CSS, maps to none)
-        if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueNone || valueID == CSSValueCenter)
-            return true;
-        break;
-    case CSSPropertyFontStyle: // normal | italic | oblique | inherit
-        if (valueID == CSSValueNormal || valueID == CSSValueItalic || valueID == CSSValueOblique)
-            return true;
-        break;
-    case CSSPropertyImageRendering: // auto | optimizeSpeed | optimizeQuality | -webkit-crisp-edges | -webkit-optimize-contrast | crisp-edges | pixelated
-        // optimizeSpeed and optimizeQuality are deprecated; a user agent must accept them as valid values but must treat them as having the same behavior as pixelated and auto respectively.
-        if (valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizequality
-            || valueID == CSSValueWebkitCrispEdges || valueID == CSSValueWebkitOptimizeContrast || valueID == CSSValueCrispEdges || valueID == CSSValuePixelated)
-            return true;
-        break;
-    case CSSPropertyListStylePosition: // inside | outside | inherit
-        if (valueID == CSSValueInside || valueID == CSSValueOutside)
-            return true;
-        break;
-    case CSSPropertyListStyleType:
-        // See section CSS_PROP_LIST_STYLE_TYPE of file CSSValueKeywords.in
-        // for the list of supported list-style-types.
-        if ((valueID &gt;= CSSValueDisc &amp;&amp; valueID &lt;= CSSValueKatakanaIroha) || valueID == CSSValueNone)
-            return true;
-        break;
-    case CSSPropertyObjectFit:
-        if (valueID == CSSValueFill || valueID == CSSValueContain || valueID == CSSValueCover || valueID == CSSValueNone || valueID == CSSValueScaleDown)
-            return true;
-        break;
-    case CSSPropertyOutlineStyle: // (&lt;border-style&gt; except hidden) | auto | inherit
-        if (valueID == CSSValueAuto || valueID == CSSValueNone || (valueID &gt;= CSSValueInset &amp;&amp; valueID &lt;= CSSValueDouble))
-            return true;
-        break;
-    case CSSPropertyOverflowWrap: // normal | break-word
-    case CSSPropertyWordWrap:
-        if (valueID == CSSValueNormal || valueID == CSSValueBreakWord)
-            return true;
-        break;
-#if ENABLE(TOUCH_EVENTS)
-    case CSSPropertyTouchAction: // auto | manipulation
-        if (valueID == CSSValueAuto || valueID == CSSValueManipulation)
-            return true;
-        break;
-#endif
-#if ENABLE(CSS_SCROLL_SNAP)
-    case CSSPropertyWebkitScrollSnapType: // none | mandatory | proximity
-        if (valueID == CSSValueNone || valueID == CSSValueMandatory || valueID == CSSValueProximity)
-            return true;
-        break;
-#endif
-    case CSSPropertyOverflowX: // visible | hidden | scroll | auto  | overlay | inherit
-        if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay)
-            return true;
-        break;
-    case CSSPropertyOverflowY: // visible | hidden | scroll | auto | overlay | inherit | -webkit-paged-x | -webkit-paged-y
-        if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay || valueID == CSSValueWebkitPagedX || valueID == CSSValueWebkitPagedY)
-            return true;
-        break;
-    case CSSPropertyPageBreakAfter: // auto | always | avoid | left | right | inherit
-    case CSSPropertyPageBreakBefore:
-    case CSSPropertyWebkitColumnBreakAfter:
-    case CSSPropertyWebkitColumnBreakBefore:
-        if (valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight)
-            return true;
-        break;
-    case CSSPropertyPageBreakInside: // avoid | auto | inherit
-    case CSSPropertyWebkitColumnBreakInside:
-        if (valueID == CSSValueAuto || valueID == CSSValueAvoid)
-            return true;
-        break;
-    case CSSPropertyPointerEvents:
-        // none | visiblePainted | visibleFill | visibleStroke | visible |
-        // painted | fill | stroke | auto | all | inherit
-        if (valueID == CSSValueVisible || valueID == CSSValueNone || valueID == CSSValueAll || valueID == CSSValueAuto || (valueID &gt;= CSSValueVisiblepainted &amp;&amp; valueID &lt;= CSSValueStroke))
-            return true;
-        break;
-    case CSSPropertyPosition: // static | relative | absolute | fixed | sticky | inherit
-        if (valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed || valueID == CSSValueWebkitSticky)
-            return true;
-        break;
-    case CSSPropertyResize: // none | both | horizontal | vertical | auto
-        if (valueID == CSSValueNone || valueID == CSSValueBoth || valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueAuto)
-            return true;
-        break;
-    case CSSPropertySpeak: // none | normal | spell-out | digits | literal-punctuation | no-punctuation | inherit
-        if (valueID == CSSValueNone || valueID == CSSValueNormal || valueID == CSSValueSpellOut || valueID == CSSValueDigits || valueID == CSSValueLiteralPunctuation || valueID == CSSValueNoPunctuation)
-            return true;
-        break;
-    case CSSPropertyTableLayout: // auto | fixed | inherit
-        if (valueID == CSSValueAuto || valueID == CSSValueFixed)
-            return true;
-        break;
-    case CSSPropertyTextLineThroughMode:
-    case CSSPropertyTextOverlineMode:
-    case CSSPropertyTextUnderlineMode:
-        if (valueID == CSSValueContinuous || valueID == CSSValueSkipWhiteSpace)
-            return true;
-        break;
-    case CSSPropertyTextLineThroughStyle:
-    case CSSPropertyTextOverlineStyle:
-    case CSSPropertyTextUnderlineStyle:
-        if (valueID == CSSValueNone || valueID == CSSValueSolid || valueID == CSSValueDouble || valueID == CSSValueDashed || valueID == CSSValueDotDash || valueID == CSSValueDotDotDash || valueID == CSSValueWave)
-            return true;
-        break;
-    case CSSPropertyTextOverflow: // clip | ellipsis
-        if (valueID == CSSValueClip || valueID == CSSValueEllipsis)
-            return true;
-        break;
-    case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision
-        if (valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizelegibility || valueID == CSSValueGeometricprecision)
-            return true;
-        break;
-    case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none | inherit
-        if ((valueID &gt;= CSSValueCapitalize &amp;&amp; valueID &lt;= CSSValueLowercase) || valueID == CSSValueNone)
-            return true;
-        break;
-    case CSSPropertyVisibility: // visible | hidden | collapse | inherit
-        if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueCollapse)
-            return true;
-        break;
-    case CSSPropertyWebkitAppearance:
-        if ((valueID &gt;= CSSValueCheckbox &amp;&amp; valueID &lt;= CSSValueCapsLockIndicator) || valueID == CSSValueNone)
-            return true;
-        break;
-    case CSSPropertyWebkitBackfaceVisibility:
-        if (valueID == CSSValueVisible || valueID == CSSValueHidden)
-            return true;
-        break;
-#if ENABLE(CSS_COMPOSITING)
-    case CSSPropertyMixBlendMode:
-        if (valueID == CSSValueNormal || valueID == CSSValueMultiply || valueID == CSSValueScreen
-            || valueID == CSSValueOverlay || valueID == CSSValueDarken || valueID == CSSValueLighten ||  valueID == CSSValueColorDodge
-            || valueID == CSSValueColorBurn || valueID == CSSValueHardLight || valueID == CSSValueSoftLight || valueID == CSSValueDifference
-            || valueID == CSSValueExclusion || valueID == CSSValuePlusDarker || valueID == CSSValuePlusLighter)
-            return true;
-        break;
-    case CSSPropertyIsolation:
-        if (valueID == CSSValueAuto || valueID == CSSValueIsolate)
-            return true;
-        break;
-#endif
-    case CSSPropertyWebkitBorderFit:
-        if (valueID == CSSValueBorder || valueID == CSSValueLines)
-            return true;
-        break;
-    case CSSPropertyWebkitBoxAlign:
-        if (valueID == CSSValueStretch || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline)
-            return true;
-        break;
-#if ENABLE(CSS_BOX_DECORATION_BREAK)
-    case CSSPropertyWebkitBoxDecorationBreak:
-         if (valueID == CSSValueClone || valueID == CSSValueSlice)
-             return true;
-         break;
-#endif
-    case CSSPropertyWebkitBoxDirection:
-        if (valueID == CSSValueNormal || valueID == CSSValueReverse)
-            return true;
-        break;
-    case CSSPropertyWebkitBoxLines:
-        if (valueID == CSSValueSingle || valueID == CSSValueMultiple)
-                return true;
-        break;
-    case CSSPropertyWebkitBoxOrient:
-        if (valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueInlineAxis || valueID == CSSValueBlockAxis)
-            return true;
-        break;
-    case CSSPropertyWebkitBoxPack:
-        if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify)
-            return true;
-        break;
-    case CSSPropertyColumnFill:
-        if (valueID == CSSValueAuto || valueID == CSSValueBalance)
-            return true;
-        break;
-    case CSSPropertyFlexDirection:
-        if (valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse)
-            return true;
-        break;
-    case CSSPropertyFlexWrap:
-        if (valueID == CSSValueNowrap || valueID == CSSValueWrap || valueID == CSSValueWrapReverse)
-             return true;
-        break;
-    case CSSPropertyWebkitFontKerning:
-        if (valueID == CSSValueAuto || valueID == CSSValueNormal || valueID == CSSValueNone)
-            return true;
-        break;
-    case CSSPropertyWebkitFontSmoothing:
-        if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueAntialiased || valueID == CSSValueSubpixelAntialiased)
-            return true;
-        break;
-    case CSSPropertyWebkitHyphens:
-        if (valueID == CSSValueNone || valueID == CSSValueManual || valueID == CSSValueAuto)
-            return true;
-        break;
-    case CSSPropertyWebkitLineAlign:
-        if (valueID == CSSValueNone || valueID == CSSValueEdges)
-            return true;
-        break;
-    case CSSPropertyWebkitLineBreak: // auto | loose | normal | strict | after-white-space
-        if (valueID == CSSValueAuto || valueID == CSSValueLoose || valueID == CSSValueNormal || valueID == CSSValueStrict || valueID == CSSValueAfterWhiteSpace)
-            return true;
-        break;
-    case CSSPropertyWebkitLineSnap:
-        if (valueID == CSSValueNone || valueID == CSSValueBaseline || valueID == CSSValueContain)
-            return true;
-        break;
-    case CSSPropertyWebkitMarginAfterCollapse:
-    case CSSPropertyWebkitMarginBeforeCollapse:
-    case CSSPropertyWebkitMarginBottomCollapse:
-    case CSSPropertyWebkitMarginTopCollapse:
-        if (valueID == CSSValueCollapse || valueID == CSSValueSeparate || valueID == CSSValueDiscard)
-            return true;
-        break;
-    case CSSPropertyWebkitMarqueeDirection:
-        if (valueID == CSSValueForwards || valueID == CSSValueBackwards || valueID == CSSValueAhead || valueID == CSSValueReverse || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueDown
-            || valueID == CSSValueUp || valueID == CSSValueAuto)
-            return true;
-        break;
-    case CSSPropertyWebkitMarqueeStyle:
-        if (valueID == CSSValueNone || valueID == CSSValueSlide || valueID == CSSValueScroll || valueID == CSSValueAlternate)
-            return true;
-        break;
-    case CSSPropertyWebkitNbspMode: // normal | space
-        if (valueID == CSSValueNormal || valueID == CSSValueSpace)
-            return true;
-        break;
-#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
-    case CSSPropertyWebkitOverflowScrolling:
-        if (valueID == CSSValueAuto || valueID == CSSValueTouch)
-            return true;
-        break;
-#endif
-    case CSSPropertyWebkitPrintColorAdjust:
-        if (valueID == CSSValueExact || valueID == CSSValueEconomy)
-            return true;
-        break;
-#if ENABLE(CSS_REGIONS)
-    case CSSPropertyWebkitRegionBreakAfter:
-    case CSSPropertyWebkitRegionBreakBefore:
-        if (valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight)
-            return true;
-        break;
-    case CSSPropertyWebkitRegionBreakInside:
-        if (valueID == CSSValueAuto || valueID == CSSValueAvoid)
-            return true;
-        break;
-    case CSSPropertyWebkitRegionFragment:
-        if (valueID == CSSValueAuto || valueID == CSSValueBreak)
-            return true;
-        break;
-#endif
-    case CSSPropertyWebkitRtlOrdering:
-        if (valueID == CSSValueLogical || valueID == CSSValueVisual)
-            return true;
-        break;
-
-    case CSSPropertyWebkitRubyPosition:
-        if (valueID == CSSValueBefore || valueID == CSSValueAfter || valueID == CSSValueInterCharacter)
-            return true;
-        break;
-
-#if ENABLE(CSS3_TEXT)
-    case CSSPropertyWebkitTextAlignLast:
-        // auto | start | end | left | right | center | justify
-        if ((valueID &gt;= CSSValueLeft &amp;&amp; valueID &lt;= CSSValueJustify) || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueAuto)
-            return true;
-        break;
-#endif // CSS3_TEXT
-    case CSSPropertyWebkitTextCombine:
-        if (valueID == CSSValueNone || valueID == CSSValueHorizontal)
-            return true;
-        break;
-#if ENABLE(CSS3_TEXT)
-    case CSSPropertyWebkitTextJustify:
-        // auto | none | inter-word | distribute
-        if (valueID == CSSValueInterWord || valueID == CSSValueDistribute || valueID == CSSValueAuto || valueID == CSSValueNone)
-            return true;
-        break;
-#endif // CSS3_TEXT
-    case CSSPropertyWebkitTextSecurity:
-        // disc | circle | square | none | inherit
-        if (valueID == CSSValueDisc || valueID == CSSValueCircle || valueID == CSSValueSquare || valueID == CSSValueNone)
-            return true;
-        break;
-#if ENABLE(IOS_TEXT_AUTOSIZING)
-    case CSSPropertyWebkitTextSizeAdjust:
-        if (!parserContext.textAutosizingEnabled)
-            return false;
-
-        if (valueID == CSSValueAuto || valueID == CSSValueNone)
-            return true;
-        break;
-#endif
-    case CSSPropertyTransformStyle:
-    case CSSPropertyWebkitTransformStyle:
-        if (valueID == CSSValueFlat || valueID == CSSValuePreserve3d)
-            return true;
-        break;
-    case CSSPropertyWebkitUserDrag: // auto | none | element
-        if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueElement)
-            return true;
-        break;
-    case CSSPropertyWebkitUserModify: // read-only | read-write
-        if (valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly) {
-            if (styleSheetContents)
-                styleSheetContents-&gt;parserSetUsesStyleBasedEditability();
-            return true;
-        }
-        break;
-    case CSSPropertyWebkitUserSelect: // auto | none | text | all
-        if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText)
-            return true;
-        if (valueID == CSSValueAll) {
-            if (styleSheetContents)
-                styleSheetContents-&gt;parserSetUsesStyleBasedEditability();
-            return true;
-        }
-        break;
-    case CSSPropertyWebkitWritingMode:
-        if (valueID &gt;= CSSValueHorizontalTb &amp;&amp; valueID &lt;= CSSValueHorizontalBt)
-            return true;
-        break;
-    case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit
-        if (valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap)
-            return true;
-        break;
-    case CSSPropertyWordBreak: // normal | break-all | keep-all | break-word (this is a custom extension)
-        if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueKeepAll || valueID == CSSValueBreakWord)
-            return true;
-        break;
-#if ENABLE(CSS_TRAILING_WORD)
-    case CSSPropertyAppleTrailingWord: // auto | -apple-partially-balanced
-        if (valueID == CSSValueAuto || valueID == CSSValueWebkitPartiallyBalanced)
-            return true;
-        break;
-#endif
-    case CSSPropertyFontVariantPosition: // normal | sub | super
-        if (valueID == CSSValueNormal || valueID == CSSValueSub || valueID == CSSValueSuper)
-            return true;
-        break;
-    case CSSPropertyFontVariantCaps: // normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps
-        if (valueID == CSSValueNormal || valueID == CSSValueSmallCaps || valueID == CSSValueAllSmallCaps || valueID == CSSValuePetiteCaps || valueID == CSSValueAllPetiteCaps || valueID == CSSValueUnicase || valueID == CSSValueTitlingCaps)
-            return true;
-        break;
-    case CSSPropertyFontVariantAlternates: // We only support the normal and historical-forms values.
-        if (valueID == CSSValueNormal || valueID == CSSValueHistoricalForms)
-            return true;
-        break;
-            
-    case CSSPropertyBreakAfter:
-    case CSSPropertyBreakBefore:
-        // auto | avoid | left | right | recto | verso | column | page | region | avoid-page | avoid-column | avoid-region
-        if (valueID == CSSValueAuto || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight
-            || valueID == CSSValueRecto || valueID == CSSValueVerso || valueID == CSSValueColumn || valueID == CSSValuePage
-            || valueID == CSSValueRegion || valueID == CSSValueAvoidColumn || valueID == CSSValueAvoidPage || valueID == CSSValueAvoidRegion)
-            return true;
-        break;
-    case CSSPropertyBreakInside:
-        // auto | avoid | avoid-page | avoid-column | avoid-region
-        if (valueID == CSSValueAuto || valueID == CSSValueAvoid || valueID == CSSValueAvoidColumn || valueID == CSSValueAvoidPage || valueID == CSSValueAvoidRegion)
-            return true;
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-        return false;
-    }
-#if !ENABLE(CSS_GRID_LAYOUT)
-    UNUSED_PARAM(parserContext);
-#endif
-    return false;
-}
-
-static inline bool isKeywordPropertyID(CSSPropertyID propertyId)
-{
-    switch (propertyId) {
-    case CSSPropertyBorderBottomStyle:
-    case CSSPropertyBorderCollapse:
-    case CSSPropertyBorderLeftStyle:
-    case CSSPropertyBorderRightStyle:
-    case CSSPropertyBorderTopStyle:
-    case CSSPropertyBoxSizing:
-    case CSSPropertyBreakAfter:
-    case CSSPropertyBreakBefore:
-    case CSSPropertyBreakInside:
-    case CSSPropertyCaptionSide:
-    case CSSPropertyClear:
-    case CSSPropertyDirection:
-    case CSSPropertyDisplay:
-    case CSSPropertyEmptyCells:
-    case CSSPropertyFloat:
-    case CSSPropertyFontStyle:
-    case CSSPropertyImageRendering:
-    case CSSPropertyListStylePosition:
-    case CSSPropertyListStyleType:
-    case CSSPropertyObjectFit:
-    case CSSPropertyOutlineStyle:
-    case CSSPropertyOverflowWrap:
-    case CSSPropertyOverflowX:
-    case CSSPropertyOverflowY:
-    case CSSPropertyPageBreakAfter:
-    case CSSPropertyPageBreakBefore:
-    case CSSPropertyPageBreakInside:
-    case CSSPropertyPointerEvents:
-    case CSSPropertyPosition:
-    case CSSPropertyResize:
-    case CSSPropertySpeak:
-    case CSSPropertyTableLayout:
-    case CSSPropertyTextLineThroughMode:
-    case CSSPropertyTextLineThroughStyle:
-    case CSSPropertyTextOverflow:
-    case CSSPropertyTextOverlineMode:
-    case CSSPropertyTextOverlineStyle:
-    case CSSPropertyTextRendering:
-    case CSSPropertyTextTransform:
-    case CSSPropertyTextUnderlineMode:
-    case CSSPropertyTextUnderlineStyle:
-    case CSSPropertyVisibility:
-    case CSSPropertyWebkitAppearance:
-#if ENABLE(CSS_COMPOSITING)
-    case CSSPropertyMixBlendMode:
-    case CSSPropertyIsolation:
-#endif
-    case CSSPropertyWebkitBackfaceVisibility:
-    case CSSPropertyWebkitBorderAfterStyle:
-    case CSSPropertyWebkitBorderBeforeStyle:
-    case CSSPropertyWebkitBorderEndStyle:
-    case CSSPropertyWebkitBorderFit:
-    case CSSPropertyWebkitBorderStartStyle:
-    case CSSPropertyWebkitBoxAlign:
-#if ENABLE(CSS_BOX_DECORATION_BREAK)
-    case CSSPropertyWebkitBoxDecorationBreak:
-#endif
-    case CSSPropertyWebkitBoxDirection:
-    case CSSPropertyWebkitBoxLines:
-    case CSSPropertyWebkitBoxOrient:
-    case CSSPropertyWebkitBoxPack:
-    case CSSPropertyWebkitColumnBreakAfter:
-    case CSSPropertyWebkitColumnBreakBefore:
-    case CSSPropertyWebkitColumnBreakInside:
-    case CSSPropertyColumnFill:
-    case CSSPropertyColumnRuleStyle:
-    case CSSPropertyFlexDirection:
-    case CSSPropertyFlexWrap:
-    case CSSPropertyWebkitFontKerning:
-    case CSSPropertyWebkitFontSmoothing:
-    case CSSPropertyWebkitHyphens:
-    case CSSPropertyWebkitLineAlign:
-    case CSSPropertyWebkitLineBreak:
-    case CSSPropertyWebkitLineSnap:
-    case CSSPropertyWebkitMarginAfterCollapse:
-    case CSSPropertyWebkitMarginBeforeCollapse:
-    case CSSPropertyWebkitMarginBottomCollapse:
-    case CSSPropertyWebkitMarginTopCollapse:
-    case CSSPropertyWebkitMarqueeDirection:
-    case CSSPropertyWebkitMarqueeStyle:
-    case CSSPropertyWebkitNbspMode:
-#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
-    case CSSPropertyWebkitOverflowScrolling:
-#endif
-    case CSSPropertyWebkitPrintColorAdjust:
-#if ENABLE(CSS_REGIONS)
-    case CSSPropertyWebkitRegionBreakAfter:
-    case CSSPropertyWebkitRegionBreakBefore:
-    case CSSPropertyWebkitRegionBreakInside:
-    case CSSPropertyWebkitRegionFragment:
-#endif
-    case CSSPropertyWebkitRtlOrdering:
-    case CSSPropertyWebkitRubyPosition:
-#if ENABLE(CSS3_TEXT)
-    case CSSPropertyWebkitTextAlignLast:
-#endif // CSS3_TEXT
-    case CSSPropertyWebkitTextCombine:
-#if ENABLE(CSS3_TEXT)
-    case CSSPropertyWebkitTextJustify:
-#endif // CSS3_TEXT
-    case CSSPropertyWebkitTextSecurity:
-    case CSSPropertyTransformStyle:
-    case CSSPropertyWebkitTransformStyle:
-    case CSSPropertyWebkitUserDrag:
-    case CSSPropertyWebkitUserModify:
-    case CSSPropertyWebkitUserSelect:
-    case CSSPropertyWebkitWritingMode:
-    case CSSPropertyWhiteSpace:
-    case CSSPropertyWordBreak:
-    case CSSPropertyWordWrap:
-#if ENABLE(TOUCH_EVENTS)
-    case CSSPropertyTouchAction:
-#endif
-#if ENABLE(CSS_SCROLL_SNAP)
-    case CSSPropertyWebkitScrollSnapType:
-#endif
-#if ENABLE(CSS_TRAILING_WORD)
-    case CSSPropertyAppleTrailingWord:
-#endif
-    case CSSPropertyFontVariantPosition:
-    case CSSPropertyFontVariantCaps:
-    case CSSPropertyFontVariantAlternates:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static bool isUniversalKeyword(const String&amp; string)
-{
-    // These keywords can be used for all properties.
-    return equalLettersIgnoringASCIICase(string, &quot;initial&quot;)
-        || equalLettersIgnoringASCIICase(string, &quot;inherit&quot;)
-        || equalLettersIgnoringASCIICase(string, &quot;unset&quot;)
-        || equalLettersIgnoringASCIICase(string, &quot;revert&quot;);
-}
-
-static CSSParser::ParseResult parseKeywordValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyId, const String&amp; string, bool important, const CSSParserContext&amp; parserContext, StyleSheetContents* styleSheetContents)
-{
-    ASSERT(!string.isEmpty());
-
-    if (!isKeywordPropertyID(propertyId)) {
-        if (!isUniversalKeyword(string))
-            return CSSParser::ParseResult::Error;
-
-        // Don't try to parse initial/inherit/unset/revert shorthands; return an error so the caller will use the full CSS parser.
-        if (shorthandForProperty(propertyId).length())
-            return CSSParser::ParseResult::Error;
-    }
-
-    CSSParserString cssString;
-    cssString.init(string);
-    CSSValueID valueID = cssValueKeywordID(cssString);
-
-    if (!valueID)
-        return CSSParser::ParseResult::Error;
-
-    RefPtr&lt;CSSValue&gt; value;
-    if (valueID == CSSValueInherit)
-        value = CSSValuePool::singleton().createInheritedValue();
-    else if (valueID == CSSValueInitial)
-        value = CSSValuePool::singleton().createExplicitInitialValue();
-    else if (valueID == CSSValueUnset)
-        value = CSSValuePool::singleton().createUnsetValue();
-    else if (valueID == CSSValueRevert)
-        value = CSSValuePool::singleton().createRevertValue();
-    else if (isValidKeywordPropertyAndValue(propertyId, valueID, parserContext, styleSheetContents))
-        value = CSSValuePool::singleton().createIdentifierValue(valueID);
-    else
-        return CSSParser::ParseResult::Error;
-
-    return declaration.addParsedProperty(CSSProperty(propertyId, value.releaseNonNull(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
-}
-
-template &lt;typename CharacterType&gt;
-static bool parseTransformTranslateArguments(WebKitCSSTransformValue&amp; transformValue, CharacterType* characters, unsigned length, unsigned start, unsigned expectedCount)
-{
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    while (expectedCount) {
-        size_t end = WTF::find(characters, length, expectedCount == 1 ? ')' : ',', start);
-        if (end == notFound || (expectedCount == 1 &amp;&amp; end != length - 1))
-            return false;
-        unsigned argumentLength = end - start;
-        CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
-        double number;
-        if (!parseSimpleLength(characters + start, argumentLength, unit, number))
-            return false;
-        if (unit != CSSPrimitiveValue::CSS_PX &amp;&amp; (number || unit != CSSPrimitiveValue::CSS_NUMBER))
-            return false;
-        transformValue.append(cssValuePool.createValue(number, CSSPrimitiveValue::CSS_PX));
-        start = end + 1;
-        --expectedCount;
-    }
-    return true;
-}
-
-static CSSParser::ParseResult parseTranslateTransformValue(MutableStyleProperties&amp; properties, CSSPropertyID propertyID, const String&amp; string, bool important)
-{
-    if (propertyID != CSSPropertyTransform)
-        return CSSParser::ParseResult::Error;
-
-    static const unsigned shortestValidTransformStringLength = 12;
-    static const unsigned likelyMultipartTransformStringLengthCutoff = 32;
-    if (string.length() &lt; shortestValidTransformStringLength || string.length() &gt; likelyMultipartTransformStringLengthCutoff)
-        return CSSParser::ParseResult::Error;
-
-    if (!string.startsWith(&quot;translate&quot;, false))
-        return CSSParser::ParseResult::Error;
-
-    UChar c9 = toASCIILower(string[9]);
-    UChar c10 = toASCIILower(string[10]);
-
-    WebKitCSSTransformValue::TransformOperationType transformType;
-    unsigned expectedArgumentCount = 1;
-    unsigned argumentStart = 11;
-    if (c9 == 'x' &amp;&amp; c10 == '(')
-        transformType = WebKitCSSTransformValue::TranslateXTransformOperation;
-    else if (c9 == 'y' &amp;&amp; c10 == '(')
-        transformType = WebKitCSSTransformValue::TranslateYTransformOperation;
-    else if (c9 == 'z' &amp;&amp; c10 == '(')
-        transformType = WebKitCSSTransformValue::TranslateZTransformOperation;
-    else if (c9 == '(') {
-        transformType = WebKitCSSTransformValue::TranslateTransformOperation;
-        expectedArgumentCount = 2;
-        argumentStart = 10;
-    } else if (c9 == '3' &amp;&amp; c10 == 'd' &amp;&amp; string[11] == '(') {
-        transformType = WebKitCSSTransformValue::Translate3DTransformOperation;
-        expectedArgumentCount = 3;
-        argumentStart = 12;
-    } else
-        return CSSParser::ParseResult::Error;
-
-    auto transformValue = WebKitCSSTransformValue::create(transformType);
-    bool success;
-    if (string.is8Bit())
-        success = parseTransformTranslateArguments(transformValue, string.characters8(), string.length(), argumentStart, expectedArgumentCount);
-    else
-        success = parseTransformTranslateArguments(transformValue, string.characters16(), string.length(), argumentStart, expectedArgumentCount);
-    if (!success)
-        return CSSParser::ParseResult::Error;
-
-    auto result = CSSValueList::createSpaceSeparated();
-    result-&gt;append(WTFMove(transformValue));
-    return properties.addParsedProperty(CSSProperty(CSSPropertyTransform, WTFMove(result), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
-}
-
-RefPtr&lt;CSSValueList&gt; CSSParser::parseFontFaceValue(const AtomicString&amp; string)
-{
-    if (string.isEmpty())
-        return nullptr;
-
-    auto valueList = CSSValueList::createCommaSeparated();
-
-    Vector&lt;String&gt; familyNames;
-    string.string().split(',', true, familyNames);
-
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    for (auto&amp; familyName : familyNames) {
-        String stripped = stripLeadingAndTrailingHTMLSpaces(familyName);
-        if (stripped.isEmpty())
-            return nullptr;
-
-        RefPtr&lt;CSSValue&gt; value;
-        for (auto propertyID : { CSSValueSerif, CSSValueSansSerif, CSSValueCursive, CSSValueFantasy, CSSValueMonospace, CSSValueWebkitBody }) {
-            if (equalIgnoringASCIICase(stripped, getValueName(propertyID))) {
-                value = cssValuePool.createIdentifierValue(propertyID);
-                break;
-            }
-        }
-        if (!value)
-            value = cssValuePool.createFontFamilyValue(stripped);
-        valueList-&gt;append(value.releaseNonNull());
-    }
-
-    return WTFMove(valueList);
-}
-
-CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyID, const String&amp; string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
-{
-    ASSERT(!string.isEmpty());
-    CSSParser::ParseResult result = parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode);
-    if (result != ParseResult::Error)
-        return result;
-
-    result = parseColorValue(declaration, propertyID, string, important, cssParserMode);
-    if (result != ParseResult::Error)
-        return result;
-
-    CSSParserContext context(cssParserMode);
-    if (contextStyleSheet) {
-        context = contextStyleSheet-&gt;parserContext();
-        context.mode = cssParserMode;
-    }
-
-    result = parseKeywordValue(declaration, propertyID, string, important, context, contextStyleSheet);
-    if (result != ParseResult::Error)
-        return result;
-
-    result = parseTranslateTransformValue(declaration, propertyID, string, important);
-    if (result != ParseResult::Error)
-        return result;
-
-    CSSParser parser(context);
-    return parser.parseValue(declaration, propertyID, string, important, contextStyleSheet);
-}
-
-CSSParser::ParseResult CSSParser::parseCustomPropertyValue(MutableStyleProperties&amp; declaration, const AtomicString&amp; propertyName, const String&amp; string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
-{
-    CSSParserContext context(cssParserMode);
-    if (contextStyleSheet) {
-        context = contextStyleSheet-&gt;parserContext();
-        context.mode = cssParserMode;
-    }
-
-    CSSParser parser(context);
-    parser.setCustomPropertyName(propertyName);
-    return parser.parseValue(declaration, CSSPropertyCustom, string, important, contextStyleSheet);
-}
-
-CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyID, const String&amp; string, bool important, StyleSheetContents* contextStyleSheet)
-{
-    setStyleSheet(contextStyleSheet);
-
-    setupParser(&quot;@-webkit-value{&quot;, string, &quot;} &quot;);
-
-    m_id = propertyID;
-    m_important = important;
-
-    cssyyparse(this);
-
-    m_rule = nullptr;
-
-    ParseResult result = ParseResult::Error;
-
-    if (!m_parsedProperties.isEmpty()) {
-        result = declaration.addParsedProperties(m_parsedProperties) ? ParseResult::Changed : ParseResult::Unchanged;
-        clearProperties();
-    }
-
-    return result;
-}
-
-// The color will only be changed when string contains a valid CSS color, so callers
-// can set it to a default color and ignore the boolean result.
-bool CSSParser::parseColor(RGBA32&amp; color, const String&amp; string, bool strict)
-{
-    if (string.isEmpty())
-        return false;
-
-    // First try creating a color specified by name, rgba(), rgb() or &quot;#&quot; syntax.
-    if (fastParseColor(color, string, strict))
-        return true;
-
-    CSSParser parser(CSSStrictMode);
-
-    // In case the fast-path parser didn't understand the color, try the full parser.
-    if (!parser.parseColor(string))
-        return false;
-
-    CSSValue&amp; value = *parser.m_parsedProperties.first().value();
-    if (!is&lt;CSSPrimitiveValue&gt;(value))
-        return false;
-
-    CSSPrimitiveValue&amp; primitiveValue = downcast&lt;CSSPrimitiveValue&gt;(value);
-    if (!primitiveValue.isRGBColor())
-        return false;
-
-    color = primitiveValue.getRGBA32Value();
-    return true;
-}
-
-bool CSSParser::parseColor(const String&amp; string)
-{
-    setupParser(&quot;@-webkit-decls{color:&quot;, string, &quot;} &quot;);
-    cssyyparse(this);
-    m_rule = nullptr;
-
-    return !m_parsedProperties.isEmpty() &amp;&amp; m_parsedProperties.first().id() == CSSPropertyColor;
-}
-
-bool CSSParser::parseSystemColor(RGBA32&amp; color, const String&amp; string, Document* document)
-{
-    if (!document || !document-&gt;page())
-        return false;
-
-    CSSParserString cssColor;
-    cssColor.init(string);
-    CSSValueID id = cssValueKeywordID(cssColor);
-    if (!validPrimitiveValueColor(id))
-        return false;
-
-    Color parsedColor = document-&gt;page()-&gt;theme().systemColor(id);
-    if (!parsedColor.isValid())
-        return false;
-
-    color = parsedColor.rgb();
-    return true;
-}
-
-void CSSParser::parseSelector(const String&amp; string, CSSSelectorList&amp; selectorList)
-{
-    m_selectorListForParseSelector = &amp;selectorList;
-
-    setupParser(&quot;@-webkit-selector{&quot;, string, &quot;}&quot;);
-
-    cssyyparse(this);
-
-    m_selectorListForParseSelector = nullptr;
-}
-
-Ref&lt;ImmutableStyleProperties&gt; CSSParser::parseInlineStyleDeclaration(const String&amp; string, Element* element)
-{
-    CSSParserContext context = element-&gt;document().elementSheet().contents().parserContext();
-    context.mode = strictToCSSParserMode(element-&gt;isHTMLElement() &amp;&amp; !element-&gt;document().inQuirksMode());
-    return CSSParser(context).parseDeclaration(string, &amp;element-&gt;document().elementSheet().contents());
-}
-
-Ref&lt;ImmutableStyleProperties&gt; CSSParser::parseDeclaration(const String&amp; string, StyleSheetContents* contextStyleSheet)
-{
-    setStyleSheet(contextStyleSheet);
-
-    setupParser(&quot;@-webkit-decls{&quot;, string, &quot;} &quot;);
-    cssyyparse(this);
-    m_rule = nullptr;
-
-    Ref&lt;ImmutableStyleProperties&gt; style = createStyleProperties();
-    clearProperties();
-    return style;
-}
-
-
-bool CSSParser::parseDeclaration(MutableStyleProperties&amp; declaration, const String&amp; string, RefPtr&lt;CSSRuleSourceData&gt;&amp;&amp; ruleSourceData, StyleSheetContents* contextStyleSheet)
-{
-    // Length of the &quot;@-webkit-decls{&quot; prefix.
-    static const unsigned prefixLength = 15;
-
-    setStyleSheet(contextStyleSheet);
-
-    if (ruleSourceData) {
-        m_currentRuleDataStack = std::make_unique&lt;RuleSourceDataList&gt;();
-        m_currentRuleDataStack-&gt;append(*ruleSourceData);
-    }
-
-    setupParser(&quot;@-webkit-decls{&quot;, string, &quot;} &quot;);
-    cssyyparse(this);
-    m_rule = nullptr;
-
-    bool ok = false;
-    if (!m_parsedProperties.isEmpty()) {
-        ok = true;
-        declaration.addParsedProperties(m_parsedProperties);
-        clearProperties();
-    }
-
-    if (ruleSourceData) {
-        ASSERT(m_currentRuleDataStack-&gt;size() == 1);
-        ruleSourceData-&gt;ruleBodyRange.start = 0;
-        ruleSourceData-&gt;ruleBodyRange.end = string.length();
-        for (size_t i = 0, size = ruleSourceData-&gt;styleSourceData-&gt;propertyData.size(); i &lt; size; ++i) {
-            CSSPropertySourceData&amp; propertyData = ruleSourceData-&gt;styleSourceData-&gt;propertyData.at(i);
-            propertyData.range.start -= prefixLength;
-            propertyData.range.end -= prefixLength;
-        }
-
-        fixUnparsedPropertyRanges(*ruleSourceData);
-        m_currentRuleDataStack.reset();
-    }
-
-    return ok;
-}
-
-std::unique_ptr&lt;MediaQuery&gt; CSSParser::parseMediaQuery(const String&amp; string)
-{
-    if (string.isEmpty())
-        return nullptr;
-
-    ASSERT(!m_mediaQuery);
-
-    // can't use { because tokenizer state switches from mediaquery to initial state when it sees { token.
-    // instead insert one &quot; &quot; (which is WHITESPACE in CSSGrammar.y)
-    setupParser(&quot;@-webkit-mediaquery &quot;, string, &quot;} &quot;);
-    cssyyparse(this);
-
-    return WTFMove(m_mediaQuery);
-}
-
-Vector&lt;CSSParser::SourceSize&gt; CSSParser::parseSizesAttribute(StringView string)
-{
-    Vector&lt;SourceSize&gt; result;
-
-    if (string.isEmpty())
-        return result;
-
-    ASSERT(!m_sourceSizeList);
-
-    setupParser(&quot;@-webkit-sizesattr &quot;, string, &quot;}&quot;);
-    cssyyparse(this);
-
-    if (!m_sourceSizeList)
-        return result;
-
-    result = WTFMove(*m_sourceSizeList);
-    m_sourceSizeList = nullptr;
-    return result;
-}
-
-// FIXME(141289): The following two constructors are only needed because of a bug in MSVC 2013 (and prior).
-// We should remove this code as soon as a Visual Studio update that fixes this problem is released.
-
-CSSParser::SourceSize::SourceSize(CSSParser::SourceSize&amp;&amp; original)
-    : expression(WTFMove(original.expression))
-    , length(WTFMove(original.length))
-{
-}
-
-CSSParser::SourceSize::SourceSize(MediaQueryExpression&amp;&amp; expression, Ref&lt;CSSValue&gt;&amp;&amp; value)
-    : expression(WTFMove(expression))
-    , length(WTFMove(value))
-{
-}
-
-Optional&lt;CSSParser::SourceSize&gt; CSSParser::sourceSize(MediaQueryExpression&amp;&amp; expression, CSSParserValue&amp; parserValue)
-{
-    RefPtr&lt;CSSValue&gt; value;
-    if (isCalculation(parserValue)) {
-        auto* args = parserValue.function-&gt;args.get();
-        if (args &amp;&amp; args-&gt;size())
-            value = CSSCalcValue::create(parserValue.function-&gt;name, *args, CalculationRangeNonNegative);
-    }
-    if (!value)
-        value = parserValue.createCSSValue();
-    destroy(parserValue);
-    if (!value)
-        return Nullopt;
-    // FIXME: Calling the constructor explicitly here to work around an MSVC bug.
-    // For other compilers, we did not need to define the constructors and we could use aggregate initialization syntax.
-    return SourceSize(WTFMove(expression), value.releaseNonNull());
-}
-
-static inline void filterProperties(bool important, const ParsedPropertyVector&amp; input, Vector&lt;CSSProperty, 256&gt;&amp; output, size_t&amp; unusedEntries, std::bitset&lt;numCSSProperties&gt;&amp; seenProperties, HashSet&lt;AtomicString&gt;&amp; seenCustomProperties)
-{
-    // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
-    for (int i = input.size() - 1; i &gt;= 0; --i) {
-        const CSSProperty&amp; property = input[i];
-        if (property.isImportant() != important)
-            continue;
-        
-        if (property.id() == CSSPropertyCustom) {
-            if (property.value()) {
-                auto&amp; name = downcast&lt;CSSCustomPropertyValue&gt;(*property.value()).name();
-                if (!seenCustomProperties.add(name).isNewEntry)
-                    continue;
-                output[--unusedEntries] = property;
-            }
-            continue;
-        }
-
-        const unsigned propertyIDIndex = property.id() - firstCSSProperty;
-        ASSERT(propertyIDIndex &lt; seenProperties.size());
-        if (seenProperties[propertyIDIndex])
-            continue;
-        seenProperties.set(propertyIDIndex);
-        output[--unusedEntries] = property;
-    }
-}
-
-Ref&lt;ImmutableStyleProperties&gt; CSSParser::createStyleProperties()
-{
-    std::bitset&lt;numCSSProperties&gt; seenProperties;
-    size_t unusedEntries = m_parsedProperties.size();
-    Vector&lt;CSSProperty, 256&gt; results(unusedEntries);
-
-    // Important properties have higher priority, so add them first. Duplicate definitions can then be ignored when found.
-    HashSet&lt;AtomicString&gt; seenCustomProperties;
-    filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
-    filterProperties(false, m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
-    if (unusedEntries)
-        results.remove(0, unusedEntries);
-
-    return ImmutableStyleProperties::create(results.data(), results.size(), m_context.mode);
-}
-
-void CSSParser::addProperty(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp;&amp; value, bool important, bool implicit)
-{
-    // This property doesn't belong to a shorthand or is a CSS variable (which will be resolved later).
-    if (!m_currentShorthand) {
-        m_parsedProperties.append(CSSProperty(propId, WTFMove(value), important, false, CSSPropertyInvalid, m_implicitShorthand || implicit));
-        return;
-    }
-
-    auto shorthands = matchingShorthandsForLonghand(propId);
-    if (shorthands.size() == 1)
-        m_parsedProperties.append(CSSProperty(propId, WTFMove(value), important, true, CSSPropertyInvalid, m_implicitShorthand || implicit));
-    else
-        m_parsedProperties.append(CSSProperty(propId, WTFMove(value), important, true, indexOfShorthandForLonghand(m_currentShorthand, shorthands), m_implicitShorthand || implicit));
-}
-
-void CSSParser::rollbackLastProperties(int num)
-{
-    ASSERT(num &gt;= 0);
-    ASSERT(m_parsedProperties.size() &gt;= static_cast&lt;unsigned&gt;(num));
-    m_parsedProperties.shrink(m_parsedProperties.size() - num);
-}
-
-void CSSParser::clearProperties()
-{
-    m_parsedProperties.clear();
-    m_numParsedPropertiesBeforeMarginBox = invalidParsedPropertiesCount;
-}
-
-URL CSSParser::completeURL(const CSSParserContext&amp; context, const String&amp; url)
-{
-    if (url.isNull())
-        return URL();
-    if (context.charset.isEmpty())
-        return URL(context.baseURL, url);
-    return URL(context.baseURL, url, context.charset);
-}
-
-URL CSSParser::completeURL(const String&amp; url) const
-{
-    return completeURL(m_context, url);
-}
-
-bool CSSParser::validateCalculationUnit(ValueWithCalculation&amp; valueWithCalculation, Units unitFlags)
-{
-    bool mustBeNonNegative = unitFlags &amp; FNonNeg;
-
-    RefPtr&lt;CSSCalcValue&gt; calculation;
-    if (valueWithCalculation.calculation()) {
-        // The calculation value was already parsed so we reuse it. However, we may need to update its range.
-        calculation = valueWithCalculation.calculation();
-        calculation-&gt;setPermittedValueRange(mustBeNonNegative ? CalculationRangeNonNegative : CalculationRangeAll);
-    } else {
-        valueWithCalculation.setCalculation(parseCalculation(valueWithCalculation, mustBeNonNegative ? CalculationRangeNonNegative : CalculationRangeAll));
-        calculation = valueWithCalculation.calculation();
-        if (!calculation)
-            return false;
-    }
-
-    bool isValid = false;
-    switch (calculation-&gt;category()) {
-    case CalcNumber:
-        isValid = (unitFlags &amp; FNumber);
-        if (!isValid &amp;&amp; (unitFlags &amp; FInteger) &amp;&amp; calculation-&gt;isInt())
-            isValid = true;
-        if (!isValid &amp;&amp; (unitFlags &amp; FPositiveInteger) &amp;&amp; calculation-&gt;isInt() &amp;&amp; calculation-&gt;isPositive())
-            isValid = true;
-        break;
-    case CalcLength:
-        isValid = (unitFlags &amp; FLength);
-        break;
-    case CalcPercent:
-        isValid = (unitFlags &amp; FPercent);
-        break;
-    case CalcPercentLength:
-        isValid = (unitFlags &amp; FPercent) &amp;&amp; (unitFlags &amp; FLength);
-        break;
-    case CalcPercentNumber:
-        isValid = (unitFlags &amp; FPercent) &amp;&amp; (unitFlags &amp; FNumber);
-        break;
-    case CalcAngle:
-        isValid = (unitFlags &amp; FAngle);
-        break;
-    case CalcTime:
-        isValid = (unitFlags &amp; FTime);
-        break;
-    case CalcFrequency:
-        isValid = (unitFlags &amp; FFrequency);
-        break;
-    case CalcOther:
-        break;
-    }
-
-    return isValid;
-}
-
-inline bool CSSParser::shouldAcceptUnitLessValues(CSSParserValue&amp; value, Units unitFlags, CSSParserMode cssParserMode)
-{
-    // Qirks mode and svg presentation attributes accept unit less values.
-    return (unitFlags &amp; (FLength | FAngle | FTime)) &amp;&amp; (!value.fValue || cssParserMode == CSSQuirksMode || cssParserMode == SVGAttributeMode);
-}
-
-bool CSSParser::validateUnit(ValueWithCalculation&amp; valueWithCalculation, Units unitFlags, CSSParserMode cssParserMode)
-{
-    if (isCalculation(valueWithCalculation))
-        return validateCalculationUnit(valueWithCalculation, unitFlags);
-        
-    bool b = false;
-    switch (valueWithCalculation.value().unit) {
-    case CSSPrimitiveValue::CSS_NUMBER:
-        b = (unitFlags &amp; FNumber);
-        if (!b &amp;&amp; shouldAcceptUnitLessValues(valueWithCalculation, unitFlags, cssParserMode)) {
-            valueWithCalculation.value().unit = (unitFlags &amp; FLength) ? CSSPrimitiveValue::CSS_PX :
-                          ((unitFlags &amp; FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS);
-            b = true;
-        }
-        if (!b &amp;&amp; (unitFlags &amp; FInteger) &amp;&amp; valueWithCalculation.value().isInt)
-            b = true;
-        if (!b &amp;&amp; (unitFlags &amp; FPositiveInteger) &amp;&amp; valueWithCalculation.value().isInt &amp;&amp; valueWithCalculation.value().fValue &gt; 0)
-            b = true;
-        break;
-    case CSSPrimitiveValue::CSS_PERCENTAGE:
-        b = (unitFlags &amp; FPercent);
-        break;
-    case CSSParserValue::Q_EMS:
-    case CSSPrimitiveValue::CSS_EMS:
-    case CSSPrimitiveValue::CSS_REMS:
-    case CSSPrimitiveValue::CSS_CHS:
-    case CSSPrimitiveValue::CSS_EXS:
-    case CSSPrimitiveValue::CSS_PX:
-    case CSSPrimitiveValue::CSS_CM:
-    case CSSPrimitiveValue::CSS_MM:
-    case CSSPrimitiveValue::CSS_IN:
-    case CSSPrimitiveValue::CSS_PT:
-    case CSSPrimitiveValue::CSS_PC:
-    case CSSPrimitiveValue::CSS_VW:
-    case CSSPrimitiveValue::CSS_VH:
-    case CSSPrimitiveValue::CSS_VMIN:
-    case CSSPrimitiveValue::CSS_VMAX:
-        b = (unitFlags &amp; FLength);
-        break;
-    case CSSPrimitiveValue::CSS_MS:
-    case CSSPrimitiveValue::CSS_S:
-        b = (unitFlags &amp; FTime);
-        break;
-    case CSSPrimitiveValue::CSS_DEG:
-    case CSSPrimitiveValue::CSS_RAD:
-    case CSSPrimitiveValue::CSS_GRAD:
-    case CSSPrimitiveValue::CSS_TURN:
-        b = (unitFlags &amp; FAngle);
-        break;
-#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
-    case CSSPrimitiveValue::CSS_DPPX:
-    case CSSPrimitiveValue::CSS_DPI:
-    case CSSPrimitiveValue::CSS_DPCM:
-        b = (unitFlags &amp; FResolution);
-        break;
-#endif
-    case CSSPrimitiveValue::CSS_HZ:
-    case CSSPrimitiveValue::CSS_KHZ:
-    case CSSPrimitiveValue::CSS_DIMENSION:
-    default:
-        break;
-    }
-    if (b &amp;&amp; unitFlags &amp; FNonNeg &amp;&amp; valueWithCalculation.value().fValue &lt; 0)
-        b = false;
-    if (b &amp;&amp; std::isinf(valueWithCalculation.value().fValue))
-        b = false;
-    return b;
-}
-
-inline Ref&lt;CSSPrimitiveValue&gt; CSSParser::createPrimitiveNumericValue(ValueWithCalculation&amp; valueWithCalculation)
-{
-    if (valueWithCalculation.calculation())
-        return CSSPrimitiveValue::create(valueWithCalculation.calculation());
-
-    CSSParserValue&amp; value = valueWithCalculation;
-#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
-    ASSERT((value.unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_KHZ)
-        || (value.unit &gt;= CSSPrimitiveValue::CSS_TURN &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_CHS)
-        || (value.unit &gt;= CSSPrimitiveValue::CSS_VW &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_VMAX)
-        || (value.unit &gt;= CSSPrimitiveValue::CSS_DPPX &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_DPCM));
-#else
-    ASSERT((value.unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_KHZ)
-        || (value.unit &gt;= CSSPrimitiveValue::CSS_TURN &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_CHS)
-        || (value.unit &gt;= CSSPrimitiveValue::CSS_VW &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_VMAX));
-#endif
-    return CSSValuePool::singleton().createValue(value.fValue, static_cast&lt;CSSPrimitiveValue::UnitTypes&gt;(value.unit));
-}
-
-inline Ref&lt;CSSPrimitiveValue&gt; CSSParser::createPrimitiveStringValue(CSSParserValue&amp; value)
-{
-    ASSERT(value.unit == CSSPrimitiveValue::CSS_STRING || value.unit == CSSPrimitiveValue::CSS_IDENT);
-    return CSSValuePool::singleton().createValue(value.string, CSSPrimitiveValue::CSS_STRING);
-}
-
-static inline bool isComma(CSSParserValue* value)
-{ 
-    return value &amp;&amp; value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ','; 
-}
-
-static inline bool isForwardSlashOperator(CSSParserValue&amp; value)
-{
-    return value.unit == CSSParserValue::Operator &amp;&amp; value.iValue == '/';
-}
-
-bool CSSParser::isValidSize(ValueWithCalculation&amp; valueWithCalculation)
-{
-    int id = valueWithCalculation.value().id;
-    if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic || id == CSSValueWebkitMinContent || id == CSSValueWebkitMaxContent || id == CSSValueWebkitFillAvailable || id == CSSValueWebkitFitContent)
-        return true;
-    return !id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
-}
-
-inline RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseValidPrimitive(CSSValueID identifier, ValueWithCalculation&amp; valueWithCalculation)
-{
-    if (identifier)
-        return CSSValuePool::singleton().createIdentifierValue(identifier);
-
-    if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING)
-        return createPrimitiveStringValue(valueWithCalculation);
-    if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_KHZ)
-        return createPrimitiveNumericValue(valueWithCalculation);
-    if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_TURN &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_CHS)
-        return createPrimitiveNumericValue(valueWithCalculation);
-    if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_VW &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_VMAX)
-        return createPrimitiveNumericValue(valueWithCalculation);
-#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
-    if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_DPPX &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_DPCM)
-        return createPrimitiveNumericValue(valueWithCalculation);
-#endif
-    if (valueWithCalculation.value().unit &gt;= CSSParserValue::Q_EMS)
-        return CSSPrimitiveValue::createAllowingMarginQuirk(valueWithCalculation.value().fValue, CSSPrimitiveValue::CSS_EMS);
-    if (valueWithCalculation.calculation())
-        return CSSPrimitiveValue::create(valueWithCalculation.calculation());
-
-    return nullptr;
-}
-
-void CSSParser::addExpandedPropertyForValue(CSSPropertyID propId, Ref&lt;CSSValue&gt;&amp;&amp; value, bool important)
-{
-    const StylePropertyShorthand&amp; shorthand = shorthandForProperty(propId);
-    unsigned shorthandLength = shorthand.length();
-    if (!shorthandLength) {
-        addProperty(propId, WTFMove(value), important);
-        return;
-    }
-
-    ShorthandScope scope(this, propId);
-    const CSSPropertyID* longhands = shorthand.properties();
-    for (unsigned i = 0; i &lt; shorthandLength; ++i)
-        addProperty(longhands[i], value.copyRef(), important);
-}
-
-RefPtr&lt;CSSValue&gt; CSSParser::parseVariableDependentValue(CSSPropertyID propID, const CSSVariableDependentValue&amp; dependentValue, const CustomPropertyValueMap&amp; customProperties, TextDirection direction, WritingMode writingMode)
-{
-    m_valueList.reset(new CSSParserValueList());
-    if (!dependentValue.valueList().buildParserValueListSubstitutingVariables(m_valueList.get(), customProperties))
-        return nullptr;
-
-    CSSPropertyID dependentValuePropertyID = dependentValue.propertyID();
-    if (CSSProperty::isDirectionAwareProperty(dependentValuePropertyID))
-        dependentValuePropertyID = CSSProperty::resolveDirectionAwareProperty(dependentValuePropertyID, direction, writingMode);
-
-    if (!parseValue(dependentValuePropertyID, false))
-        return nullptr;
-
-    for (auto&amp; property : m_parsedProperties) {
-        if (property.id() == propID)
-            return property.value();
-    }
-    return nullptr;
-}
-
-static bool isImageSetFunctionValue(const CSSParserValue&amp; value)
-{
-    return value.unit == CSSParserValue::Function &amp;&amp; (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;image-set(&quot;) || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-image-set(&quot;));
-}
-
-bool CSSParser::parseValue(CSSPropertyID propId, bool important)
-{
-    if (!m_valueList || !m_valueList-&gt;current())
-        return false;
-    
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-    CSSValueID id = valueWithCalculation.value().id;
-    
-    if (propId == CSSPropertyCustom)
-        return parseCustomPropertyDeclaration(important, id);
-
-    if (m_valueList-&gt;containsVariables()) {
-        auto valueList = CSSValueList::createFromParserValueList(*m_valueList);
-        addExpandedPropertyForValue(propId, CSSVariableDependentValue::create(WTFMove(valueList), propId), important);
-        return true;
-    }
-
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    unsigned num = inShorthand() ? 1 : m_valueList-&gt;size();
-
-    if (id == CSSValueInherit) {
-        if (num != 1)
-            return false;
-        addExpandedPropertyForValue(propId, cssValuePool.createInheritedValue(), important);
-        return true;
-    }
-    else if (id == CSSValueInitial) {
-        if (num != 1)
-            return false;
-        addExpandedPropertyForValue(propId, cssValuePool.createExplicitInitialValue(), important);
-        return true;
-    } else if (id == CSSValueUnset) {
-        if (num != 1)
-            return false;
-        addExpandedPropertyForValue(propId, cssValuePool.createUnsetValue(), important);
-        return true;
-    } else if (id == CSSValueRevert) {
-        if (num != 1)
-            return false;
-        addExpandedPropertyForValue(propId, cssValuePool.createRevertValue(), important);
-        return true;
-    }
-    
-    if (propId == CSSPropertyAll)
-        return false; // &quot;all&quot; doesn't allow you to specify anything other than inherit/initial/unset.
-
-    if (isKeywordPropertyID(propId)) {
-        if (!isValidKeywordPropertyAndValue(propId, id, m_context, m_styleSheet))
-            return false;
-        if (m_valueList-&gt;next() &amp;&amp; !inShorthand())
-            return false;
-        addProperty(propId, cssValuePool.createIdentifierValue(id), important);
-        return true;
-    }
-
-#if ENABLE(CSS_DEVICE_ADAPTATION)
-    if (inViewport())
-        return parseViewportProperty(propId, important);
-#endif
-
-    bool validPrimitive = false;
-    RefPtr&lt;CSSValue&gt; parsedValue;
-
-    switch (propId) {
-    case CSSPropertySize:                 // &lt;length&gt;{1,2} | auto | [ &lt;page-size&gt; || [ portrait | landscape] ]
-        return parseSize(propId, important);
-
-    case CSSPropertyQuotes:               // [&lt;string&gt; &lt;string&gt;]+ | none | inherit
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else
-            return parseQuotes(propId, important);
-        break;
-    case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | isolate | isolate-override | plaintext | inherit
-        if (id == CSSValueNormal
-            || id == CSSValueEmbed
-            || id == CSSValueBidiOverride
-            || id == CSSValueWebkitIsolate
-            || id == CSSValueWebkitIsolateOverride
-            || id == CSSValueWebkitPlaintext)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyContent:              // [ &lt;string&gt; | &lt;uri&gt; | &lt;counter&gt; | attr(X) | open-quote |
-        // close-quote | no-open-quote | no-close-quote ]+ | inherit
-        return parseContent(propId, important);
-
-    case CSSPropertyAlt: // [ &lt;string&gt; | attr(X) ]
-        return parseAlt(propId, important);
-            
-    case CSSPropertyClip:                 // &lt;shape&gt; | auto | inherit
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else if (valueWithCalculation.value().unit == CSSParserValue::Function)
-            return parseClipShape(propId, important);
-        break;
-
-    /* Start of supported CSS properties with validation. This is needed for parseShorthand to work
-     * correctly and allows optimization in WebCore::applyRule(..)
-     */
-    case CSSPropertyOverflow: {
-        ShorthandScope scope(this, propId);
-        if (num != 1 || !parseValue(CSSPropertyOverflowY, important))
-            return false;
-
-        RefPtr&lt;CSSValue&gt; overflowXValue;
-
-        // FIXME: -webkit-paged-x or -webkit-paged-y only apply to overflow-y. If this value has been
-        // set using the shorthand, then for now overflow-x will default to auto, but once we implement
-        // pagination controls, it should default to hidden. If the overflow-y value is anything but
-        // paged-x or paged-y, then overflow-x and overflow-y should have the same value.
-        if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY)
-            overflowXValue = cssValuePool.createIdentifierValue(CSSValueAuto);
-        else
-            overflowXValue = m_parsedProperties.last().value();
-        addProperty(CSSPropertyOverflowX, WTFMove(overflowXValue), important);
-        return true;
-    }
-
-    case CSSPropertyTextAlign:
-        // left | right | center | justify | -webkit-left | -webkit-right | -webkit-center | -webkit-match-parent
-        // | start | end | inherit | -webkit-auto (converted to start)
-        // NOTE: &lt;string&gt; is not supported.
-        if ((id &gt;= CSSValueWebkitAuto &amp;&amp; id &lt;= CSSValueWebkitMatchParent) || id == CSSValueStart || id == CSSValueEnd)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyFontWeight:  { // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit
-        if (m_valueList-&gt;size() != 1)
-            return false;
-        return parseFontWeight(important);
-    }
-
-    case CSSPropertyFontSynthesis: // none | [ weight || style ]
-        return parseFontSynthesis(important);
-
-    case CSSPropertyBorderSpacing: {
-        if (num == 1) {
-            ShorthandScope scope(this, CSSPropertyBorderSpacing);
-            if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important))
-                return false;
-            CSSValue* value = m_parsedProperties.last().value();
-            addProperty(CSSPropertyWebkitBorderVerticalSpacing, value, important);
-            return true;
-        }
-        else if (num == 2) {
-            ShorthandScope scope(this, CSSPropertyBorderSpacing);
-            if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important) || !parseValue(CSSPropertyWebkitBorderVerticalSpacing, important))
-                return false;
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyWebkitBorderHorizontalSpacing:
-    case CSSPropertyWebkitBorderVerticalSpacing:
-        validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg);
-        break;
-    case CSSPropertyOutlineColor:        // &lt;color&gt; | invert | inherit
-        // Outline color has &quot;invert&quot; as additional keyword.
-        // Also, we want to allow the special focus color even in strict parsing mode.
-        if (id == CSSValueInvert || id == CSSValueWebkitFocusRingColor) {
-            validPrimitive = true;
-            break;
-        }
-        FALLTHROUGH;
-    case CSSPropertyBackgroundColor: // &lt;color&gt; | inherit
-    case CSSPropertyBorderTopColor: // &lt;color&gt; | inherit
-    case CSSPropertyBorderRightColor:
-    case CSSPropertyBorderBottomColor:
-    case CSSPropertyBorderLeftColor:
-    case CSSPropertyWebkitBorderStartColor:
-    case CSSPropertyWebkitBorderEndColor:
-    case CSSPropertyWebkitBorderBeforeColor:
-    case CSSPropertyWebkitBorderAfterColor:
-    case CSSPropertyColor: // &lt;color&gt; | inherit
-    case CSSPropertyTextLineThroughColor: // CSS3 text decoration colors
-    case CSSPropertyTextUnderlineColor:
-    case CSSPropertyTextOverlineColor:
-    case CSSPropertyColumnRuleColor:
-    case CSSPropertyWebkitTextDecorationColor:
-    case CSSPropertyWebkitTextEmphasisColor:
-    case CSSPropertyWebkitTextFillColor:
-    case CSSPropertyWebkitTextStrokeColor:
-        if (id == CSSValueWebkitText)
-            validPrimitive = true; // Always allow this, even when strict parsing is on,
-                                    // since we use this in our UA sheets.
-        else if (id == CSSValueCurrentcolor)
-            validPrimitive = true;
-        else if (isValidSystemColorValue(id) || id == CSSValueMenu
-            || (id &gt;= CSSValueWebkitFocusRingColor &amp;&amp; id &lt; CSSValueWebkitText &amp;&amp; inQuirksMode())) {
-            validPrimitive = true;
-        } else {
-            parsedValue = parseColor();
-            if (parsedValue)
-                m_valueList-&gt;next();
-        }
-        break;
-
-    case CSSPropertyCursor: {
-        // Grammar defined by CSS3 UI and modified by CSS4 images:
-        // [ [&lt;image&gt; [&lt;x&gt; &lt;y&gt;]?,]*
-        // [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize |
-        // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | ew-resize |
-        // ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | text | wait | help |
-        // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed |
-        // zoom-in | zoom-out | all-scroll | -webkit-grab | -webkit-grabbing | -webkit-zoom-in |
-        // -webkit-zoom-out ] ] | inherit
-        RefPtr&lt;CSSValueList&gt; list;
-        CSSParserValue* value = &amp;valueWithCalculation.value();
-        while (value) {
-            RefPtr&lt;CSSValue&gt; image;
-            if (value-&gt;unit == CSSPrimitiveValue::CSS_URI) {
-                String uri = value-&gt;string;
-                if (!uri.isNull())
-                    image = CSSImageValue::create(completeURL(uri));
-#if ENABLE(MOUSE_CURSOR_SCALE)
-            } else if (isImageSetFunctionValue(*value)) {
-                image = parseImageSet();
-                if (!image)
-                    break;
-#endif
-            } else
-                break;
-
-            Vector&lt;int&gt; coords;
-            value = m_valueList-&gt;next();
-            while (value &amp;&amp; value-&gt;unit == CSSPrimitiveValue::CSS_NUMBER) {
-                coords.append(int(value-&gt;fValue));
-                value = m_valueList-&gt;next();
-            }
-            bool hasHotSpot = false;
-            IntPoint hotSpot(-1, -1);
-            int nrcoords = coords.size();
-            if (nrcoords &gt; 0 &amp;&amp; nrcoords != 2)
-                return false;
-            if (nrcoords == 2) {
-                hasHotSpot = true;
-                hotSpot = IntPoint(coords[0], coords[1]);
-            }
-
-            if (!list)
-                list = CSSValueList::createCommaSeparated();
-
-            if (image)
-                list-&gt;append(CSSCursorImageValue::create(image.releaseNonNull(), hasHotSpot, hotSpot));
-
-            if ((inStrictMode() &amp;&amp; !value) || (value &amp;&amp; !(value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')))
-                return false;
-            value = m_valueList-&gt;next(); // comma
-        }
-        if (list) {
-            if (!value) {
-                // no value after url list (MSIE 5 compatibility)
-                if (list-&gt;length() != 1)
-                    return false;
-            } else if (inQuirksMode() &amp;&amp; value-&gt;id == CSSValueHand) // MSIE 5 compatibility :/
-                list-&gt;append(cssValuePool.createIdentifierValue(CSSValuePointer));
-            else if ((value-&gt;id &gt;= CSSValueAuto &amp;&amp; value-&gt;id &lt;= CSSValueWebkitZoomOut) || value-&gt;id == CSSValueCopy || value-&gt;id == CSSValueNone)
-                list-&gt;append(cssValuePool.createIdentifierValue(value-&gt;id));
-            m_valueList-&gt;next();
-            parsedValue = WTFMove(list);
-            break;
-        } else if (value) {
-            id = value-&gt;id;
-            if (inQuirksMode() &amp;&amp; value-&gt;id == CSSValueHand) {
-                // MSIE 5 compatibility :/
-                id = CSSValuePointer;
-                validPrimitive = true;
-            } else if ((value-&gt;id &gt;= CSSValueAuto &amp;&amp; value-&gt;id &lt;= CSSValueWebkitZoomOut) || value-&gt;id == CSSValueCopy || value-&gt;id == CSSValueNone)
-                validPrimitive = true;
-        } else {
-            ASSERT_NOT_REACHED();
-            return false;
-        }
-        break;
-    }
-
-#if ENABLE(CURSOR_VISIBILITY)
-    case CSSPropertyWebkitCursorVisibility:
-        if (id == CSSValueAuto || id == CSSValueAutoHide)
-            validPrimitive = true;
-        break;
-#endif
-
-    case CSSPropertyBackgroundAttachment:
-    case CSSPropertyBackgroundBlendMode:
-    case CSSPropertyBackgroundClip:
-    case CSSPropertyWebkitBackgroundClip:
-    case CSSPropertyWebkitBackgroundComposite:
-    case CSSPropertyBackgroundImage:
-    case CSSPropertyBackgroundOrigin:
-    case CSSPropertyWebkitBackgroundOrigin:
-    case CSSPropertyBackgroundPosition:
-    case CSSPropertyBackgroundPositionX:
-    case CSSPropertyBackgroundPositionY:
-    case CSSPropertyBackgroundSize:
-    case CSSPropertyWebkitBackgroundSize:
-    case CSSPropertyBackgroundRepeat:
-    case CSSPropertyBackgroundRepeatX:
-    case CSSPropertyBackgroundRepeatY:
-    case CSSPropertyWebkitMaskClip:
-    case CSSPropertyWebkitMaskComposite:
-    case CSSPropertyWebkitMaskImage:
-    case CSSPropertyWebkitMaskOrigin:
-    case CSSPropertyWebkitMaskPosition:
-    case CSSPropertyWebkitMaskPositionX:
-    case CSSPropertyWebkitMaskPositionY:
-    case CSSPropertyWebkitMaskSize:
-    case CSSPropertyWebkitMaskSourceType:
-    case CSSPropertyWebkitMaskRepeat:
-    case CSSPropertyWebkitMaskRepeatX:
-    case CSSPropertyWebkitMaskRepeatY:
-    {
-        RefPtr&lt;CSSValue&gt; val1;
-        RefPtr&lt;CSSValue&gt; val2;
-        CSSPropertyID propId1, propId2;
-        bool result = false;
-        if (parseFillProperty(propId, propId1, propId2, val1, val2)) {
-            std::unique_ptr&lt;ShorthandScope&gt; shorthandScope;
-            if (propId == CSSPropertyBackgroundPosition ||
-                propId == CSSPropertyBackgroundRepeat ||
-                propId == CSSPropertyWebkitMaskPosition ||
-                propId == CSSPropertyWebkitMaskRepeat) {
-                shorthandScope = std::make_unique&lt;ShorthandScope&gt;(this, propId);
-            }
-            addProperty(propId1, val1.releaseNonNull(), important);
-            if (val2)
-                addProperty(propId2, val2.releaseNonNull(), important);
-            result = true;
-        }
-        m_implicitShorthand = false;
-        return result;
-    }
-    case CSSPropertyListStyleImage:     // &lt;uri&gt; | none | inherit
-    case CSSPropertyBorderImageSource:
-    case CSSPropertyWebkitMaskBoxImageSource:
-        if (id == CSSValueNone) {
-            parsedValue = cssValuePool.createIdentifierValue(CSSValueNone);
-            m_valueList-&gt;next();
-        } else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_URI) {
-            parsedValue = CSSImageValue::create(completeURL(valueWithCalculation.value().string));
-            m_valueList-&gt;next();
-        } else if (isGeneratedImageValue(valueWithCalculation)) {
-            if (parseGeneratedImage(*m_valueList, parsedValue))
-                m_valueList-&gt;next();
-            else
-                return false;
-        } else if (isImageSetFunctionValue(valueWithCalculation.value())) {
-            parsedValue = parseImageSet();
-            if (!parsedValue)
-                return false;
-            m_valueList-&gt;next();
-        }
-        break;
-
-    case CSSPropertyWebkitTextStrokeWidth:
-    case CSSPropertyOutlineWidth:        // &lt;border-width&gt; | inherit
-    case CSSPropertyBorderTopWidth:     //// &lt;border-width&gt; | inherit
-    case CSSPropertyBorderRightWidth:   //   Which is defined as
-    case CSSPropertyBorderBottomWidth:  //   thin | medium | thick | &lt;length&gt;
-    case CSSPropertyBorderLeftWidth:
-    case CSSPropertyWebkitBorderStartWidth:
-    case CSSPropertyWebkitBorderEndWidth:
-    case CSSPropertyWebkitBorderBeforeWidth:
-    case CSSPropertyWebkitBorderAfterWidth:
-    case CSSPropertyColumnRuleWidth:
-        if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick)
-            validPrimitive = true;
-        else
-            validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg);
-        break;
-
-    case CSSPropertyLetterSpacing:       // normal | &lt;length&gt; | inherit
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            validPrimitive = validateUnit(valueWithCalculation, FLength);
-        break;
-
-    case CSSPropertyWordSpacing:         // normal | &lt;length&gt; | &lt;percentage&gt; | inherit
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent);
-        break;
-
-    case CSSPropertyTextIndent:
-        parsedValue = parseTextIndent();
-        break;
-
-    case CSSPropertyPaddingTop:          //// &lt;padding-width&gt; | inherit
-    case CSSPropertyPaddingRight:        //   Which is defined as
-    case CSSPropertyPaddingBottom:       //   &lt;length&gt; | &lt;percentage&gt;
-    case CSSPropertyPaddingLeft:         ////
-    case CSSPropertyWebkitPaddingStart:
-    case CSSPropertyWebkitPaddingEnd:
-    case CSSPropertyWebkitPaddingBefore:
-    case CSSPropertyWebkitPaddingAfter:
-        validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg));
-        break;
-
-    case CSSPropertyMaxWidth:
-    case CSSPropertyWebkitMaxLogicalWidth:
-    case CSSPropertyMaxHeight:
-    case CSSPropertyWebkitMaxLogicalHeight:
-        validPrimitive = (id == CSSValueNone || isValidSize(valueWithCalculation));
-        break;
-
-    case CSSPropertyMinWidth:
-    case CSSPropertyWebkitMinLogicalWidth:
-    case CSSPropertyMinHeight:
-    case CSSPropertyWebkitMinLogicalHeight:
-        validPrimitive = id == CSSValueAuto || isValidSize(valueWithCalculation);
-        break;
-
-    case CSSPropertyWidth:
-    case CSSPropertyWebkitLogicalWidth:
-    case CSSPropertyHeight:
-    case CSSPropertyWebkitLogicalHeight:
-        validPrimitive = (id == CSSValueAuto || isValidSize(valueWithCalculation));
-        break;
-
-    case CSSPropertyFontSize:
-        return parseFontSize(important);
-
-    case CSSPropertyVerticalAlign:
-        // baseline | sub | super | top | text-top | middle | bottom | text-bottom |
-        // &lt;percentage&gt; | &lt;length&gt; | inherit
-
-        if (id &gt;= CSSValueBaseline &amp;&amp; id &lt;= CSSValueWebkitBaselineMiddle)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent));
-        break;
-
-    case CSSPropertyBottom:               // &lt;length&gt; | &lt;percentage&gt; | auto | inherit
-    case CSSPropertyLeft:                 // &lt;length&gt; | &lt;percentage&gt; | auto | inherit
-    case CSSPropertyRight:                // &lt;length&gt; | &lt;percentage&gt; | auto | inherit
-    case CSSPropertyTop:                  // &lt;length&gt; | &lt;percentage&gt; | auto | inherit
-    case CSSPropertyMarginTop:           //// &lt;margin-width&gt; | inherit
-    case CSSPropertyMarginRight:         //   Which is defined as
-    case CSSPropertyMarginBottom:        //   &lt;length&gt; | &lt;percentage&gt; | auto | inherit
-    case CSSPropertyMarginLeft:          ////
-    case CSSPropertyWebkitMarginStart:
-    case CSSPropertyWebkitMarginEnd:
-    case CSSPropertyWebkitMarginBefore:
-    case CSSPropertyWebkitMarginAfter:
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent));
-        break;
-
-    case CSSPropertyZIndex:              // auto | &lt;integer&gt; | inherit
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FInteger, CSSQuirksMode));
-        break;
-
-    case CSSPropertyOrphans: // &lt;integer&gt; | inherit | auto (We've added support for auto for backwards compatibility)
-    case CSSPropertyWidows: // &lt;integer&gt; | inherit | auto (Ditto)
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FPositiveInteger, CSSQuirksMode));
-        break;
-
-    case CSSPropertyLineHeight:
-        return parseLineHeight(important);
-    case CSSPropertyCounterIncrement:    // [ &lt;identifier&gt; &lt;integer&gt;? ]+ | none | inherit
-        if (id != CSSValueNone)
-            return parseCounter(propId, 1, important);
-        validPrimitive = true;
-        break;
-    case CSSPropertyCounterReset:        // [ &lt;identifier&gt; &lt;integer&gt;? ]+ | none | inherit
-        if (id != CSSValueNone)
-            return parseCounter(propId, 0, important);
-        validPrimitive = true;
-        break;
-    case CSSPropertyFontFamily:
-        // [[ &lt;family-name&gt; | &lt;generic-family&gt; ],]* [&lt;family-name&gt; | &lt;generic-family&gt;] | inherit
-    {
-        parsedValue = parseFontFamily();
-        break;
-    }
-
-    case CSSPropertyWebkitTextDecoration:
-        // [ &lt;text-decoration-line&gt; || &lt;text-decoration-style&gt; || &lt;text-decoration-color&gt; ] | inherit
-        return parseShorthand(CSSPropertyWebkitTextDecoration, webkitTextDecorationShorthand(), important);
-
-    case CSSPropertyTextDecoration:
-    case CSSPropertyWebkitTextDecorationsInEffect:
-    case CSSPropertyWebkitTextDecorationLine:
-        // none | [ underline || overline || line-through || blink ] | inherit
-        return parseTextDecoration(propId, important);
-
-    case CSSPropertyWebkitTextDecorationStyle:
-        // solid | double | dotted | dashed | wavy
-        if (id == CSSValueSolid || id == CSSValueDouble || id == CSSValueDotted || id == CSSValueDashed || id == CSSValueWavy)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyWebkitTextDecorationSkip:
-        // none | [ objects || spaces || ink || edges || box-decoration ]
-        return parseTextDecorationSkip(important);
-
-    case CSSPropertyWebkitTextUnderlinePosition:
-        // auto | alphabetic | under
-        return parseTextUnderlinePosition(important);
-
-    case CSSPropertyZoom:
-        // normal | reset | document | &lt;number&gt; | &lt;percentage&gt; | inherit
-        if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FPercent | FNonNeg, CSSStrictMode));
-        break;
-    
-    case CSSPropertyWebkitTextZoom:
-        // normal | reset
-        if (id == CSSValueNormal || id == CSSValueReset)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertySrc: // Only used within @font-face and @-webkit-filter, so cannot use inherit | initial or be !important. This is a list of urls or local references.
-        return parseFontFaceSrc();
-
-    case CSSPropertyUnicodeRange:
-        return parseFontFaceUnicodeRange();
-
-    /* CSS3 properties */
-
-    case CSSPropertyBorderImage: {
-        RefPtr&lt;CSSValue&gt; result;
-        return parseBorderImage(propId, result, important);
-    }
-    case CSSPropertyWebkitBorderImage:
-    case CSSPropertyWebkitMaskBoxImage: {
-        RefPtr&lt;CSSValue&gt; result;
-        if (parseBorderImage(propId, result)) {
-            addProperty(propId, WTFMove(result), important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyBorderImageOutset:
-    case CSSPropertyWebkitMaskBoxImageOutset: {
-        RefPtr&lt;CSSPrimitiveValue&gt; result;
-        if (parseBorderImageOutset(result)) {
-            addProperty(propId, WTFMove(result), important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyBorderImageRepeat:
-    case CSSPropertyWebkitMaskBoxImageRepeat: {
-        RefPtr&lt;CSSValue&gt; result;
-        if (parseBorderImageRepeat(result)) {
-            addProperty(propId, WTFMove(result), important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyBorderImageSlice:
-    case CSSPropertyWebkitMaskBoxImageSlice: {
-        RefPtr&lt;CSSBorderImageSliceValue&gt; result;
-        if (parseBorderImageSlice(propId, result)) {
-            addProperty(propId, WTFMove(result), important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyBorderImageWidth:
-    case CSSPropertyWebkitMaskBoxImageWidth: {
-        RefPtr&lt;CSSPrimitiveValue&gt; result;
-        if (parseBorderImageWidth(result)) {
-            addProperty(propId, WTFMove(result), important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyBorderTopRightRadius:
-    case CSSPropertyBorderTopLeftRadius:
-    case CSSPropertyBorderBottomLeftRadius:
-    case CSSPropertyBorderBottomRightRadius: {
-        if (num != 1 &amp;&amp; num != 2)
-            return false;
-        validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
-        if (!validPrimitive)
-            return false;
-        auto parsedValue1 = createPrimitiveNumericValue(valueWithCalculation);
-        RefPtr&lt;CSSPrimitiveValue&gt; parsedValue2;
-        if (num == 2) {
-            ValueWithCalculation nextValueWithCalculation(*m_valueList-&gt;next());
-            validPrimitive = validateUnit(nextValueWithCalculation, FLength | FPercent | FNonNeg);
-            if (!validPrimitive)
-                return false;
-            parsedValue2 = createPrimitiveNumericValue(nextValueWithCalculation);
-        } else
-            parsedValue2 = parsedValue1.ptr();
-
-        addProperty(propId, createPrimitiveValuePair(WTFMove(parsedValue1), parsedValue2.releaseNonNull()), important);
-        return true;
-    }
-    case CSSPropertyTabSize:
-        validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg);
-        break;
-    case CSSPropertyWebkitAspectRatio:
-        return parseAspectRatio(important);
-    case CSSPropertyBorderRadius:
-    case CSSPropertyWebkitBorderRadius:
-        return parseBorderRadius(propId, important);
-    case CSSPropertyOutlineOffset:
-        validPrimitive = validateUnit(valueWithCalculation, FLength);
-        break;
-    case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
-    case CSSPropertyBoxShadow:
-    case CSSPropertyWebkitBoxShadow:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else {
-            RefPtr&lt;CSSValueList&gt; shadowValueList = parseShadow(*m_valueList, propId);
-            if (shadowValueList) {
-                addProperty(propId, shadowValueList.releaseNonNull(), important);
-                m_valueList-&gt;next();
-                return true;
-            }
-            return false;
-        }
-        break;
-    case CSSPropertyWebkitInitialLetter: {
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else {
-            if (num != 1 &amp;&amp; num != 2)
-                return false;
-            validPrimitive = validateUnit(valueWithCalculation, FPositiveInteger);
-            if (!validPrimitive)
-                return false;
-            auto height = createPrimitiveNumericValue(valueWithCalculation);
-            RefPtr&lt;CSSPrimitiveValue&gt; position;
-            if (num == 2) {
-                ValueWithCalculation nextValueWithCalculation(*m_valueList-&gt;next());
-                validPrimitive = validateUnit(nextValueWithCalculation, FPositiveInteger);
-                if (!validPrimitive)
-                    return false;
-                position = createPrimitiveNumericValue(nextValueWithCalculation);
-            } else
-                position = height.ptr();
-            addProperty(propId, createPrimitiveValuePair(position.releaseNonNull(), WTFMove(height)), important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyWebkitBoxReflect:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else
-            return parseReflect(propId, important);
-        break;
-    case CSSPropertyOpacity:
-        validPrimitive = validateUnit(valueWithCalculation, FNumber);
-        break;
-    case CSSPropertyWebkitBoxFlex:
-        validPrimitive = validateUnit(valueWithCalculation, FNumber);
-        break;
-    case CSSPropertyWebkitBoxFlexGroup:
-        validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode);
-        break;
-    case CSSPropertyWebkitBoxOrdinalGroup:
-        validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode) &amp;&amp; valueWithCalculation.value().fValue;
-        break;
-    case CSSPropertyFilter:
-#if ENABLE(FILTERS_LEVEL_2)
-    case CSSPropertyWebkitBackdropFilter:
-#endif
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else {
-            RefPtr&lt;CSSValueList&gt; currValue;
-            if (!parseFilter(*m_valueList, currValue))
-                return false;
-            addProperty(propId, WTFMove(currValue), important);
-            return true;
-        }
-        break;
-#if ENABLE(CSS_COMPOSITING)
-    case CSSPropertyMixBlendMode:
-        validPrimitive = true;
-        break;
-    case CSSPropertyIsolation:
-        validPrimitive = true;
-        break;
-#endif
-    case CSSPropertyFlex: {
-        ShorthandScope scope(this, propId);
-        if (id == CSSValueNone) {
-            addProperty(CSSPropertyFlexGrow, cssValuePool.createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
-            addProperty(CSSPropertyFlexShrink, cssValuePool.createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
-            addProperty(CSSPropertyFlexBasis, cssValuePool.createIdentifierValue(CSSValueAuto), important);
-            return true;
-        }
-        return parseFlex(*m_valueList, important);
-    }
-    case CSSPropertyFlexBasis:
-        // FIXME: Support intrinsic dimensions too.
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg));
-        break;
-    case CSSPropertyFlexGrow:
-    case CSSPropertyFlexShrink:
-        validPrimitive = validateUnit(valueWithCalculation, FNumber | FNonNeg);
-        break;
-    case CSSPropertyOrder:
-        if (validateUnit(valueWithCalculation, FInteger, CSSStrictMode)) {
-            // We restrict the smallest value to int min + 2 because we use int min and int min + 1 as special values in a hash set.
-            double result = std::max&lt;double&gt;(std::numeric_limits&lt;int&gt;::min() + 2, parsedDouble(valueWithCalculation));
-            parsedValue = cssValuePool.createValue(result, CSSPrimitiveValue::CSS_NUMBER);
-            m_valueList-&gt;next();
-        }
-        break;
-    case CSSPropertyWebkitMarquee:
-        return parseShorthand(propId, webkitMarqueeShorthand(), important);
-    case CSSPropertyWebkitMarqueeIncrement:
-        if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium)
-            validPrimitive = true;
-        else
-            validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent);
-        break;
-    case CSSPropertyWebkitMarqueeRepetition:
-        if (id == CSSValueInfinite)
-            validPrimitive = true;
-        else
-            validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg);
-        break;
-    case CSSPropertyWebkitMarqueeSpeed:
-        if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast)
-            validPrimitive = true;
-        else
-            validPrimitive = validateUnit(valueWithCalculation, FTime | FInteger | FNonNeg);
-        break;
-#if ENABLE(CSS_REGIONS)
-    case CSSPropertyWebkitFlowInto:
-        return parseFlowThread(propId, important);
-    case CSSPropertyWebkitFlowFrom:
-        return parseRegionThread(propId, important);
-#endif
-    case CSSPropertyTransform:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else {
-            if (RefPtr&lt;CSSValue&gt; transformValue = parseTransform()) {
-                addProperty(propId, transformValue.releaseNonNull(), important);
-                return true;
-            }
-            return false;
-        }
-        break;
-    case CSSPropertyTransformOrigin:
-    case CSSPropertyTransformOriginX:
-    case CSSPropertyTransformOriginY:
-    case CSSPropertyTransformOriginZ: {
-        RefPtr&lt;CSSPrimitiveValue&gt; val1;
-        RefPtr&lt;CSSPrimitiveValue&gt; val2;
-        RefPtr&lt;CSSValue&gt; val3;
-        CSSPropertyID propId1, propId2, propId3;
-        if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
-            addProperty(propId1, WTFMove(val1), important);
-            if (val2)
-                addProperty(propId2, WTFMove(val2), important);
-            if (val3)
-                addProperty(propId3, WTFMove(val3), important);
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyPerspective:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else {
-            // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
-            if (validateUnit(valueWithCalculation, FNumber | FLength | FNonNeg)) {
-                addProperty(propId, createPrimitiveNumericValue(valueWithCalculation), important);
-                return true;
-            }
-        }
-        break;
-    case CSSPropertyPerspectiveOrigin:
-    case CSSPropertyPerspectiveOriginX:
-    case CSSPropertyPerspectiveOriginY: {
-        RefPtr&lt;CSSPrimitiveValue&gt; val1;
-        RefPtr&lt;CSSPrimitiveValue&gt; val2;
-        CSSPropertyID propId1, propId2;
-        if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
-            addProperty(propId1, WTFMove(val1), important);
-            if (val2)
-                addProperty(propId2, WTFMove(val2), important);
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyAnimationDelay:
-    case CSSPropertyAnimationDirection:
-    case CSSPropertyAnimationDuration:
-    case CSSPropertyAnimationFillMode:
-    case CSSPropertyAnimationName:
-    case CSSPropertyAnimationPlayState:
-    case CSSPropertyAnimationIterationCount:
-    case CSSPropertyAnimationTimingFunction:
-    case CSSPropertyWebkitAnimationDelay:
-    case CSSPropertyWebkitAnimationDirection:
-    case CSSPropertyWebkitAnimationDuration:
-    case CSSPropertyWebkitAnimationFillMode:
-    case CSSPropertyWebkitAnimationName:
-    case CSSPropertyWebkitAnimationPlayState:
-    case CSSPropertyWebkitAnimationIterationCount:
-    case CSSPropertyWebkitAnimationTimingFunction:
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
-    case CSSPropertyWebkitAnimationTrigger:
-#endif
-    case CSSPropertyTransitionDelay:
-    case CSSPropertyTransitionDuration:
-    case CSSPropertyTransitionTimingFunction:
-    case CSSPropertyTransitionProperty:
-    case CSSPropertyWebkitTransitionDelay:
-    case CSSPropertyWebkitTransitionDuration:
-    case CSSPropertyWebkitTransitionTimingFunction:
-    case CSSPropertyWebkitTransitionProperty: {
-        RefPtr&lt;CSSValue&gt; val;
-        AnimationParseContext context;
-        if (parseAnimationProperty(propId, val, context)) {
-            addProperty(propId, WTFMove(val), important);
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyJustifyContent:
-        parsedValue = parseContentDistributionOverflowPosition();
-        break;
-    case CSSPropertyJustifySelf:
-        return parseItemPositionOverflowPosition(propId, important);
-    case CSSPropertyJustifyItems:
-        if (parseLegacyPosition(propId, important))
-            return true;
-        m_valueList-&gt;setCurrentIndex(0);
-        return parseItemPositionOverflowPosition(propId, important);
-#if ENABLE(CSS_GRID_LAYOUT)
-    case CSSPropertyGridAutoColumns:
-    case CSSPropertyGridAutoRows:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        parsedValue = parseGridTrackList(GridAuto);
-        break;
-
-    case CSSPropertyGridTemplateColumns:
-    case CSSPropertyGridTemplateRows:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        parsedValue = parseGridTrackList(GridTemplate);
-        break;
-
-    case CSSPropertyGridColumnStart:
-    case CSSPropertyGridColumnEnd:
-    case CSSPropertyGridRowStart:
-    case CSSPropertyGridRowEnd:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        parsedValue = parseGridPosition();
-        break;
-
-    case CSSPropertyGridColumnGap:
-    case CSSPropertyGridRowGap:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg);
-        break;
-
-    case CSSPropertyGridGap:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        return parseGridGapShorthand(important);
-
-    case CSSPropertyGridColumn:
-    case CSSPropertyGridRow:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        return parseGridItemPositionShorthand(propId, important);
-
-    case CSSPropertyGridTemplate:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        return parseGridTemplateShorthand(important);
-
-    case CSSPropertyGrid:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        return parseGridShorthand(important);
-
-    case CSSPropertyGridArea:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        return parseGridAreaShorthand(important);
-
-    case CSSPropertyGridTemplateAreas:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        parsedValue = parseGridTemplateAreas();
-        break;
-    case CSSPropertyGridAutoFlow:
-        if (!isCSSGridLayoutEnabled())
-            return false;
-        parsedValue = parseGridAutoFlow(*m_valueList);
-        break;
-#endif /* ENABLE(CSS_GRID_LAYOUT) */
-    case CSSPropertyWebkitMarginCollapse: {
-        if (num == 1) {
-            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
-            if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important))
-                return false;
-            CSSValue* value = m_parsedProperties.last().value();
-            addProperty(webkitMarginCollapseShorthand().properties()[1], value, important);
-            return true;
-        }
-        else if (num == 2) {
-            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
-            if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important) || !parseValue(webkitMarginCollapseShorthand().properties()[1], important))
-                return false;
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyTextLineThroughWidth:
-    case CSSPropertyTextOverlineWidth:
-    case CSSPropertyTextUnderlineWidth:
-        if (id == CSSValueAuto || id == CSSValueNormal || id == CSSValueThin ||
-            id == CSSValueMedium || id == CSSValueThick)
-            validPrimitive = true;
-        else
-            validPrimitive = !id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FLength | FPercent);
-        break;
-    case CSSPropertyColumnCount:
-        parsedValue = parseColumnCount();
-        break;
-    case CSSPropertyColumnGap: // normal | &lt;length&gt;
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg);
-        break;
-    case CSSPropertyWebkitColumnAxis:
-        if (id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto)
-            validPrimitive = true;
-        break;
-    case CSSPropertyColumnProgression:
-        if (id == CSSValueNormal || id == CSSValueReverse)
-            validPrimitive = true;
-        break;
-    case CSSPropertyColumnSpan: // none | all | 1 (will be dropped in the unprefixed property)
-        if (id == CSSValueAll || id == CSSValueNone)
-            validPrimitive = true;
-        else if (validateUnit(valueWithCalculation, FNumber | FNonNeg) &amp;&amp; parsedDouble(valueWithCalculation) == 1) {
-            addProperty(CSSPropertyColumnSpan, cssValuePool.createValue(1, CSSPrimitiveValue::CSS_NUMBER), important);
-            return true;
-        }
-        break;
-    case CSSPropertyColumnWidth: // auto | &lt;length&gt;
-        parsedValue = parseColumnWidth();
-        break;
-    case CSSPropertyObjectPosition: {
-        RefPtr&lt;CSSPrimitiveValue&gt; val1;
-        RefPtr&lt;CSSPrimitiveValue&gt; val2;
-        parseFillPosition(*m_valueList, val1, val2);
-        if (val1) {
-            addProperty(CSSPropertyObjectPosition, createPrimitiveValuePair(val1.releaseNonNull(), WTFMove(val2)), important);
-            return true;
-        }
-        return false;
-        }
-    // End of CSS3 properties
-
-    case CSSPropertyWillChange: // auto | [scroll-position | contents | &lt;custom-ident&gt;]#
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            return parseWillChange(important);
-        break;
-
-    // Apple specific properties.  These will never be standardized and are purely to
-    // support custom WebKit-based Apple applications.
-    case CSSPropertyWebkitLineClamp:
-        // When specifying number of lines, don't allow 0 as a valid value
-        // When specifying either type of unit, require non-negative integers
-        validPrimitive = (!id &amp;&amp; (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE || valueWithCalculation.value().fValue) &amp;&amp; validateUnit(valueWithCalculation, FInteger | FPercent | FNonNeg, CSSQuirksMode));
-        break;
-#if ENABLE(IOS_TEXT_AUTOSIZING)
-    case CSSPropertyWebkitTextSizeAdjust:
-        if (!isTextAutosizingEnabled())
-            return false;
-
-        if (id == CSSValueAuto || id == CSSValueNone)
-            validPrimitive = true;
-        else {
-            // FIXME: Handle multilength case where we allow relative units.
-            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FPercent | FNonNeg, CSSStrictMode));
-        }
-        break;
-#endif
-
-    case CSSPropertyWebkitFontSizeDelta:           // &lt;length&gt;
-        validPrimitive = validateUnit(valueWithCalculation, FLength);
-        break;
-
-    case CSSPropertyWebkitHyphenateCharacter:
-        if (id == CSSValueAuto || valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyWebkitHyphenateLimitBefore:
-    case CSSPropertyWebkitHyphenateLimitAfter:
-        if (id == CSSValueAuto || validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode))
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyWebkitHyphenateLimitLines:
-        if (id == CSSValueNoLimit || validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode))
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyWebkitLineGrid:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_IDENT) {
-            String lineGridValue = String(valueWithCalculation.value().string);
-            if (!lineGridValue.isEmpty()) {
-                addProperty(propId, cssValuePool.createValue(lineGridValue, CSSPrimitiveValue::CSS_STRING), important);
-                return true;
-            }
-        }
-        break;
-    case CSSPropertyWebkitLocale:
-        if (id == CSSValueAuto || valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING)
-            validPrimitive = true;
-        break;
-
-#if ENABLE(DASHBOARD_SUPPORT)
-    case CSSPropertyWebkitDashboardRegion: // &lt;dashboard-region&gt; | &lt;dashboard-region&gt;
-        if (valueWithCalculation.value().unit == CSSParserValue::Function || id == CSSValueNone)
-            return parseDashboardRegions(propId, important);
-        break;
-#endif
-
-#if PLATFORM(IOS)
-    case CSSPropertyWebkitTouchCallout:
-        if (id == CSSValueDefault || id == CSSValueNone)
-            validPrimitive = true;
-        break;
-#endif
-#if ENABLE(TOUCH_EVENTS)
-    case CSSPropertyWebkitTapHighlightColor:
-        if (isValidSystemColorValue(id) || id == CSSValueMenu
-            || (id &gt;= CSSValueWebkitFocusRingColor &amp;&amp; id &lt; CSSValueWebkitText &amp;&amp; inQuirksMode())) {
-            validPrimitive = true;
-        } else {
-            parsedValue = parseColor();
-            if (parsedValue)
-                m_valueList-&gt;next();
-        }
-        break;
-#endif
-    // End Apple-specific properties
-
-        /* shorthand properties */
-    case CSSPropertyBackground: {
-        // Position must come before color in this array because a plain old &quot;0&quot; is a legal color
-        // in quirks mode but it's usually the X coordinate of a position.
-        const CSSPropertyID properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat,
-                                   CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin,
-                                   CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, CSSPropertyBackgroundSize };
-        return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
-    }
-    case CSSPropertyWebkitMask: {
-        const CSSPropertyID properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskSourceType, CSSPropertyWebkitMaskRepeat,
-            CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskOrigin, CSSPropertyWebkitMaskClip, CSSPropertyWebkitMaskSize };
-        return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
-    }
-    case CSSPropertyBorder:
-        // [ 'border-width' || 'border-style' || &lt;color&gt; ] | inherit
-    {
-        if (parseShorthand(propId, borderAbridgedShorthand(), important)) {
-            // The CSS3 Borders and Backgrounds specification says that border also resets border-image. It's as
-            // though a value of none was specified for the image.
-            addExpandedPropertyForValue(CSSPropertyBorderImage, cssValuePool.createImplicitInitialValue(), important);
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyBorderTop:
-        // [ 'border-top-width' || 'border-style' || &lt;color&gt; ] | inherit
-        return parseShorthand(propId, borderTopShorthand(), important);
-    case CSSPropertyBorderRight:
-        // [ 'border-right-width' || 'border-style' || &lt;color&gt; ] | inherit
-        return parseShorthand(propId, borderRightShorthand(), important);
-    case CSSPropertyBorderBottom:
-        // [ 'border-bottom-width' || 'border-style' || &lt;color&gt; ] | inherit
-        return parseShorthand(propId, borderBottomShorthand(), important);
-    case CSSPropertyBorderLeft:
-        // [ 'border-left-width' || 'border-style' || &lt;color&gt; ] | inherit
-        return parseShorthand(propId, borderLeftShorthand(), important);
-    case CSSPropertyWebkitBorderStart:
-        return parseShorthand(propId, webkitBorderStartShorthand(), important);
-    case CSSPropertyWebkitBorderEnd:
-        return parseShorthand(propId, webkitBorderEndShorthand(), important);
-    case CSSPropertyWebkitBorderBefore:
-        return parseShorthand(propId, webkitBorderBeforeShorthand(), important);
-    case CSSPropertyWebkitBorderAfter:
-        return parseShorthand(propId, webkitBorderAfterShorthand(), important);
-    case CSSPropertyOutline:
-        // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
-        return parseShorthand(propId, outlineShorthand(), important);
-    case CSSPropertyBorderColor:
-        // &lt;color&gt;{1,4} | inherit
-        return parse4Values(propId, borderColorShorthand().properties(), important);
-    case CSSPropertyBorderWidth:
-        // &lt;border-width&gt;{1,4} | inherit
-        return parse4Values(propId, borderWidthShorthand().properties(), important);
-    case CSSPropertyBorderStyle:
-        // &lt;border-style&gt;{1,4} | inherit
-        return parse4Values(propId, borderStyleShorthand().properties(), important);
-    case CSSPropertyMargin:
-        // &lt;margin-width&gt;{1,4} | inherit
-        return parse4Values(propId, marginShorthand().properties(), important);
-    case CSSPropertyPadding:
-        // &lt;padding-width&gt;{1,4} | inherit
-        return parse4Values(propId, paddingShorthand().properties(), important);
-    case CSSPropertyFlexFlow:
-        return parseShorthand(propId, flexFlowShorthand(), important);
-    case CSSPropertyFont:
-        // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]?
-        // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
-        if (num == 1 &amp;&amp; id &gt;= CSSValueCaption &amp;&amp; id &lt;= CSSValueStatusBar) {
-            parseSystemFont(important);
-            return true;
-        }
-        return parseFont(important);
-    case CSSPropertyListStyle:
-        return parseShorthand(propId, listStyleShorthand(), important);
-    case CSSPropertyColumns:
-        return parseColumnsShorthand(important);
-    case CSSPropertyColumnRule:
-        return parseShorthand(propId, columnRuleShorthand(), important);
-    case CSSPropertyWebkitTextStroke:
-        return parseShorthand(propId, webkitTextStrokeShorthand(), important);
-    case CSSPropertyAnimation:
-    case CSSPropertyWebkitAnimation:
-        return parseAnimationShorthand(propId, important);
-    case CSSPropertyTransition:
-    case CSSPropertyWebkitTransition:
-        return parseTransitionShorthand(propId, important);
-    case CSSPropertyInvalid:
-        return false;
-    case CSSPropertyPage:
-        return parsePage(propId, important);
-    case CSSPropertyFontStretch:
-    case CSSPropertyTextLineThrough:
-    case CSSPropertyTextOverline:
-    case CSSPropertyTextUnderline:
-        return false;
-    // CSS Text Layout Module Level 3: Vertical writing support
-    case CSSPropertyWebkitTextEmphasis:
-        return parseShorthand(propId, webkitTextEmphasisShorthand(), important);
-
-    case CSSPropertyWebkitTextEmphasisStyle:
-        return parseTextEmphasisStyle(important);
-
-    case CSSPropertyWebkitTextEmphasisPosition:
-        return parseTextEmphasisPosition(important);
-
-    case CSSPropertyWebkitTextOrientation:
-        if (id == CSSValueSideways || id == CSSValueSidewaysRight || id == CSSValueVerticalRight || id == CSSValueMixed || id == CSSValueUpright)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyHangingPunctuation:
-        return parseHangingPunctuation(important);
-    case CSSPropertyWebkitLineBoxContain:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else
-            return parseLineBoxContain(important);
-        break;
-    case CSSPropertyFontFeatureSettings:
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            return parseFontFeatureSettings(important);
-        break;
-    case CSSPropertyFontVariantLigatures:
-        if (id == CSSValueNormal || id == CSSValueNone)
-            validPrimitive = true;
-        else
-            return parseFontVariantLigatures(important, true, false);
-        break;
-    case CSSPropertyFontVariantNumeric:
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            return parseFontVariantNumeric(important, true, false);
-        break;
-    case CSSPropertyFontVariantEastAsian:
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            return parseFontVariantEastAsian(important, true, false);
-        break;
-    case CSSPropertyFontVariant:
-        if (id == CSSValueNormal) {
-            ShorthandScope scope(this, CSSPropertyFontVariant);
-            addProperty(CSSPropertyFontVariantLigatures, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-            addProperty(CSSPropertyFontVariantPosition, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-            addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-            addProperty(CSSPropertyFontVariantNumeric, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-            addProperty(CSSPropertyFontVariantAlternates, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-            addProperty(CSSPropertyFontVariantEastAsian, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-            return true;
-        }
-        if (id == CSSValueNone) {
-            ShorthandScope scope(this, CSSPropertyFontVariant);
-            addProperty(CSSPropertyFontVariantLigatures, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important, true);
-            return true;
-        }
-        return parseFontVariant(important);
-
-    case CSSPropertyWebkitClipPath:
-        parsedValue = parseClipPath();
-        break;
-#if ENABLE(CSS_SHAPES)
-    case CSSPropertyWebkitShapeOutside:
-        parsedValue = parseShapeProperty(propId);
-        break;
-    case CSSPropertyWebkitShapeMargin:
-        validPrimitive = !id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
-        break;
-    case CSSPropertyWebkitShapeImageThreshold:
-        validPrimitive = !id &amp;&amp; validateUnit(valueWithCalculation, FNumber);
-        break;
-#endif
-#if ENABLE(CSS_IMAGE_ORIENTATION)
-    case CSSPropertyImageOrientation:
-        validPrimitive = !id &amp;&amp; validateUnit(valueWithCalculation, FAngle);
-        break;
-#endif
-#if ENABLE(CSS_IMAGE_RESOLUTION)
-    case CSSPropertyImageResolution:
-        parsedValue = parseImageResolution();
-        break;
-#endif
-    case CSSPropertyAlignContent:
-        parsedValue = parseContentDistributionOverflowPosition();
-        break;
-    case CSSPropertyAlignSelf:
-        return parseItemPositionOverflowPosition(propId, important);
-
-    case CSSPropertyAlignItems:
-        return parseItemPositionOverflowPosition(propId, important);
-    case CSSPropertyBorderBottomStyle:
-    case CSSPropertyBorderCollapse:
-    case CSSPropertyBorderLeftStyle:
-    case CSSPropertyBorderRightStyle:
-    case CSSPropertyBorderTopStyle:
-    case CSSPropertyBoxSizing:
-    case CSSPropertyBreakAfter:
-    case CSSPropertyBreakBefore:
-    case CSSPropertyBreakInside:
-    case CSSPropertyCaptionSide:
-    case CSSPropertyClear:
-    case CSSPropertyDirection:
-    case CSSPropertyDisplay:
-    case CSSPropertyEmptyCells:
-    case CSSPropertyFloat:
-    case CSSPropertyFontStyle:
-    case CSSPropertyImageRendering:
-    case CSSPropertyListStylePosition:
-    case CSSPropertyListStyleType:
-    case CSSPropertyObjectFit:
-    case CSSPropertyOutlineStyle:
-    case CSSPropertyOverflowWrap:
-    case CSSPropertyOverflowX:
-    case CSSPropertyOverflowY:
-    case CSSPropertyPageBreakAfter:
-    case CSSPropertyPageBreakBefore:
-    case CSSPropertyPageBreakInside:
-    case CSSPropertyPointerEvents:
-    case CSSPropertyPosition:
-    case CSSPropertyResize:
-    case CSSPropertySpeak:
-    case CSSPropertyTableLayout:
-    case CSSPropertyTextLineThroughMode:
-    case CSSPropertyTextLineThroughStyle:
-    case CSSPropertyTextOverflow:
-    case CSSPropertyTextOverlineMode:
-    case CSSPropertyTextOverlineStyle:
-    case CSSPropertyTextRendering:
-    case CSSPropertyTextTransform:
-    case CSSPropertyTextUnderlineMode:
-    case CSSPropertyTextUnderlineStyle:
-    case CSSPropertyVisibility:
-    case CSSPropertyWebkitAppearance:
-    case CSSPropertyWebkitBackfaceVisibility:
-    case CSSPropertyWebkitBorderAfterStyle:
-    case CSSPropertyWebkitBorderBeforeStyle:
-    case CSSPropertyWebkitBorderEndStyle:
-    case CSSPropertyWebkitBorderFit:
-    case CSSPropertyWebkitBorderStartStyle:
-    case CSSPropertyWebkitBoxAlign:
-#if ENABLE(CSS_BOX_DECORATION_BREAK)
-    case CSSPropertyWebkitBoxDecorationBreak:
-#endif
-    case CSSPropertyWebkitBoxDirection:
-    case CSSPropertyWebkitBoxLines:
-    case CSSPropertyWebkitBoxOrient:
-    case CSSPropertyWebkitBoxPack:
-    case CSSPropertyWebkitColumnBreakAfter:
-    case CSSPropertyWebkitColumnBreakBefore:
-    case CSSPropertyWebkitColumnBreakInside:
-    case CSSPropertyColumnFill:
-    case CSSPropertyColumnRuleStyle:
-    case CSSPropertyFlexDirection:
-    case CSSPropertyFlexWrap:
-    case CSSPropertyWebkitFontKerning:
-    case CSSPropertyWebkitFontSmoothing:
-    case CSSPropertyWebkitHyphens:
-    case CSSPropertyWebkitLineAlign:
-    case CSSPropertyWebkitLineBreak:
-    case CSSPropertyWebkitLineSnap:
-    case CSSPropertyWebkitMarginAfterCollapse:
-    case CSSPropertyWebkitMarginBeforeCollapse:
-    case CSSPropertyWebkitMarginBottomCollapse:
-    case CSSPropertyWebkitMarginTopCollapse:
-    case CSSPropertyWebkitMarqueeDirection:
-    case CSSPropertyWebkitMarqueeStyle:
-    case CSSPropertyWebkitNbspMode:
-#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
-    case CSSPropertyWebkitOverflowScrolling:
-#endif
-    case CSSPropertyWebkitPrintColorAdjust:
-#if ENABLE(CSS_REGIONS)
-    case CSSPropertyWebkitRegionBreakAfter:
-    case CSSPropertyWebkitRegionBreakBefore:
-    case CSSPropertyWebkitRegionBreakInside:
-    case CSSPropertyWebkitRegionFragment:
-#endif
-    case CSSPropertyWebkitRtlOrdering:
-    case CSSPropertyWebkitRubyPosition:
-#if ENABLE(CSS3_TEXT)
-    case CSSPropertyWebkitTextAlignLast:
-#endif // CSS3_TEXT
-    case CSSPropertyWebkitTextCombine:
-#if ENABLE(CSS3_TEXT)
-    case CSSPropertyWebkitTextJustify:
-#endif // CSS3_TEXT
-    case CSSPropertyWebkitTextSecurity:
-    case CSSPropertyTransformStyle:
-    case CSSPropertyWebkitTransformStyle:
-    case CSSPropertyWebkitUserDrag:
-    case CSSPropertyWebkitUserModify:
-    case CSSPropertyWebkitUserSelect:
-    case CSSPropertyWebkitWritingMode:
-    case CSSPropertyWhiteSpace:
-    case CSSPropertyWordBreak:
-    case CSSPropertyWordWrap:
-#if ENABLE(TOUCH_EVENTS)
-    case CSSPropertyTouchAction:
-#endif
-#if ENABLE(CSS_SCROLL_SNAP)
-    case CSSPropertyWebkitScrollSnapType:
-#endif
-#if ENABLE(CSS_TRAILING_WORD)
-    case CSSPropertyAppleTrailingWord:
-#endif
-        // These properties should be handled before in isValidKeywordPropertyAndValue().
-        ASSERT_NOT_REACHED();
-        return false;
-#if ENABLE(CSS_DEVICE_ADAPTATION)
-    // Properties bellow are validated inside parseViewportProperty, because we
-    // check for parser state inViewportScope. We need to invalidate if someone
-    // adds them outside a @viewport rule.
-    case CSSPropertyMaxZoom:
-    case CSSPropertyMinZoom:
-    case CSSPropertyOrientation:
-    case CSSPropertyUserZoom:
-        validPrimitive = false;
-        break;
-#endif
-#if ENABLE(CSS_SCROLL_SNAP)
-    case CSSPropertyWebkitScrollSnapPointsX:
-    case CSSPropertyWebkitScrollSnapPointsY:
-        if (id == CSSValueElements) {
-            validPrimitive = true;
-            break;
-        }
-        return parseNonElementSnapPoints(propId, important);
-    case CSSPropertyWebkitScrollSnapDestination: // &lt;length&gt;{2}
-        return parseScrollSnapDestination(propId, important);
-    case CSSPropertyWebkitScrollSnapCoordinate:
-        return parseScrollSnapCoordinate(propId, important);
-#endif
-
-    default:
-        return parseSVGValue(propId, important);
-    }
-
-    if (validPrimitive) {
-        parsedValue = parseValidPrimitive(id, valueWithCalculation);
-        m_valueList-&gt;next();
-    }
-
-    if (parsedValue &amp;&amp; (!m_valueList-&gt;current() || inShorthand())) {
-        addProperty(propId, parsedValue.releaseNonNull(), important);
-        return true;
-    }
-    return false;
-}
-
-void CSSParser::addFillValue(RefPtr&lt;CSSValue&gt;&amp; lval, Ref&lt;CSSValue&gt;&amp;&amp; rval)
-{
-    if (!lval) {
-        lval = WTFMove(rval);
-        return;
-    }
-
-    if (lval-&gt;isBaseValueList()) {
-        downcast&lt;CSSValueList&gt;(*lval).append(WTFMove(rval));
-        return;
-    }
-
-    auto list = CSSValueList::createCommaSeparated();
-    list.get().append(lval.releaseNonNull());
-    list.get().append(WTFMove(rval));
-    lval = WTFMove(list);
-}
-
-static bool isContentDistributionKeyword(CSSValueID id)
-{
-    return id == CSSValueSpaceBetween || id == CSSValueSpaceAround
-        || id == CSSValueSpaceEvenly || id == CSSValueStretch;
-}
-
-static bool isContentPositionKeyword(CSSValueID id)
-{
-    return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter
-        || id == CSSValueFlexStart || id == CSSValueFlexEnd
-        || id == CSSValueLeft || id == CSSValueRight;
-}
-
-static inline bool isBaselinePositionKeyword(CSSValueID id)
-{
-    return id == CSSValueBaseline || id == CSSValueLastBaseline;
-}
-
-static bool isAlignmentOverflowKeyword(CSSValueID id)
-{
-    return id == CSSValueUnsafe || id == CSSValueSafe;
-}
-
-static bool isItemPositionKeyword(CSSValueID id)
-{
-    return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter
-        || id == CSSValueSelfStart || id == CSSValueSelfEnd || id == CSSValueFlexStart
-        || id == CSSValueFlexEnd || id == CSSValueLeft || id == CSSValueRight;
-}
-
-bool CSSParser::parseLegacyPosition(CSSPropertyID propId, bool important)
-{
-    // [ legacy &amp;&amp; [ left | right | center ]
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (!value)
-        return false;
-
-    if (value-&gt;id == CSSValueLegacy) {
-        value = m_valueList-&gt;next();
-        if (!value)
-            return false;
-        if (value-&gt;id != CSSValueCenter &amp;&amp; value-&gt;id != CSSValueLeft &amp;&amp; value-&gt;id != CSSValueRight)
-            return false;
-    } else if (value-&gt;id == CSSValueCenter || value-&gt;id == CSSValueLeft || value-&gt;id == CSSValueRight) {
-        if (!m_valueList-&gt;next() || m_valueList-&gt;current()-&gt;id != CSSValueLegacy)
-            return false;
-    } else
-        return false;
-
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    addProperty(propId, createPrimitiveValuePair(cssValuePool.createIdentifierValue(CSSValueLegacy), cssValuePool.createIdentifierValue(value-&gt;id)), important);
-    return !m_valueList-&gt;next();
-}
-
-RefPtr&lt;CSSContentDistributionValue&gt; CSSParser::parseContentDistributionOverflowPosition()
-{
-    // normal | &lt;baseline-position&gt; | &lt;content-distribution&gt; || [ &lt;overflow-position&gt;? &amp;&amp; &lt;content-position&gt; ]
-    // &lt;baseline-position&gt; = baseline | last-baseline;
-    // &lt;content-distribution&gt; = space-between | space-around | space-evenly | stretch;
-    // &lt;content-position&gt; = center | start | end | flex-start | flex-end | left | right;
-    // &lt;overflow-position&gt; = unsafe | safe
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (!value)
-        return nullptr;
-
-    // auto | &lt;baseline-position&gt;
-    if (value-&gt;id == CSSValueNormal || isBaselinePositionKeyword(value-&gt;id)) {
-        m_valueList-&gt;next();
-        return CSSContentDistributionValue::create(CSSValueInvalid, value-&gt;id, CSSValueInvalid);
-    }
-
-    CSSValueID distribution = CSSValueInvalid;
-    CSSValueID position = CSSValueInvalid;
-    CSSValueID overflow = CSSValueInvalid;
-    while (value) {
-        if (isContentDistributionKeyword(value-&gt;id)) {
-            if (distribution != CSSValueInvalid)
-                return nullptr;
-            distribution = value-&gt;id;
-        } else if (isContentPositionKeyword(value-&gt;id)) {
-            if (position != CSSValueInvalid)
-                return nullptr;
-            position = value-&gt;id;
-        } else if (isAlignmentOverflowKeyword(value-&gt;id)) {
-            if (overflow != CSSValueInvalid)
-                return nullptr;
-            overflow = value-&gt;id;
-        } else
-            return nullptr;
-        value = m_valueList-&gt;next();
-    }
-
-    // The grammar states that we should have at least &lt;content-distribution&gt; or
-    // &lt;content-position&gt; ( &lt;content-distribution&gt; || &lt;content-position&gt; ).
-    if (position == CSSValueInvalid &amp;&amp; distribution == CSSValueInvalid)
-        return nullptr;
-
-    // The grammar states that &lt;overflow-position&gt; must be associated to &lt;content-position&gt;.
-    if (overflow != CSSValueInvalid &amp;&amp; position == CSSValueInvalid)
-        return nullptr;
-
-    return CSSContentDistributionValue::create(distribution, position, overflow);
-}
-
-bool CSSParser::parseItemPositionOverflowPosition(CSSPropertyID propId, bool important)
-{
-    // auto | normal | stretch | &lt;baseline-position&gt; | [&lt;item-position&gt; &amp;&amp; &lt;overflow-position&gt;? ]
-    // &lt;baseline-position&gt; = baseline | last-baseline;
-    // &lt;item-position&gt; = center | start | end | self-start | self-end | flex-start | flex-end | left | right;
-    // &lt;overflow-position&gt; = unsafe | safe
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (!value)
-        return false;
-
-    if (value-&gt;id == CSSValueAuto || value-&gt;id == CSSValueNormal || value-&gt;id == CSSValueStretch || isBaselinePositionKeyword(value-&gt;id)) {
-        // align-items property does not allow the 'auto' value.
-        if (value-&gt;id == CSSValueAuto &amp;&amp; propId == CSSPropertyAlignItems)
-            return false;
-        if (m_valueList-&gt;next())
-            return false;
-
-        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
-        return true;
-    }
-
-    RefPtr&lt;CSSPrimitiveValue&gt; position;
-    RefPtr&lt;CSSPrimitiveValue&gt; overflowAlignmentKeyword;
-    if (isItemPositionKeyword(value-&gt;id)) {
-        position = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-        value = m_valueList-&gt;next();
-        if (value) {
-            if (value-&gt;id != CSSValueUnsafe &amp;&amp; value-&gt;id != CSSValueSafe)
-                return false;
-            overflowAlignmentKeyword = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-        }
-    } else if (isAlignmentOverflowKeyword(value-&gt;id)) {
-        overflowAlignmentKeyword = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-        value = m_valueList-&gt;next();
-        if (value &amp;&amp; isItemPositionKeyword(value-&gt;id))
-            position = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-        else
-            return false;
-    } else
-        return false;
-
-    if (m_valueList-&gt;next())
-        return false;
-
-    ASSERT(position);
-    if (overflowAlignmentKeyword)
-        addProperty(propId, createPrimitiveValuePair(position.releaseNonNull(), overflowAlignmentKeyword.releaseNonNull()), important);
-    else
-        addProperty(propId, position.releaseNonNull(), important);
-
-    return true;
-}
-
-static bool parseBackgroundClip(CSSParserValue&amp; parserValue, RefPtr&lt;CSSValue&gt;&amp; cssValue)
-{
-    if (parserValue.id == CSSValueBorderBox || parserValue.id == CSSValuePaddingBox
-        || parserValue.id == CSSValueContentBox || parserValue.id == CSSValueWebkitText) {
-        cssValue = CSSValuePool::singleton().createIdentifierValue(parserValue.id);
-        return true;
-    }
-    return false;
-}
-
-bool CSSParser::useLegacyBackgroundSizeShorthandBehavior() const
-{
-    return m_context.useLegacyBackgroundSizeShorthandBehavior;
-}
-
-#if ENABLE(CSS_SCROLL_SNAP)
-bool CSSParser::parseNonElementSnapPoints(CSSPropertyID propId, bool important)
-{
-    auto values = CSSValueList::createSpaceSeparated();
-    while (CSSParserValue* value = m_valueList-&gt;current()) {
-        ValueWithCalculation valueWithCalculation(*value);
-        if (validateUnit(valueWithCalculation, FPercent | FLength))
-            values-&gt;append(createPrimitiveNumericValue(valueWithCalculation));
-        else if (value-&gt;unit == CSSParserValue::Function
-            &amp;&amp; value-&gt;function-&gt;args
-            &amp;&amp; value-&gt;function-&gt;args-&gt;size() == 1
-            &amp;&amp; equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;repeat(&quot;)) {
-            ValueWithCalculation argumentWithCalculation(*value-&gt;function-&gt;args.get()-&gt;current());
-            if (validateUnit(argumentWithCalculation, FLength | FPercent | FNonNeg)) {
-                values-&gt;append(CSSValuePool::singleton().createValue(LengthRepeat::create(createPrimitiveNumericValue(argumentWithCalculation))));
-                m_valueList-&gt;next();
-                if (m_valueList-&gt;current())
-                    return false;
-                break;
-            }
-        } else
-            return false;
-        m_valueList-&gt;next();
-    }
-    if (values-&gt;length()) {
-        addProperty(propId, WTFMove(values), important);
-        m_valueList-&gt;next();
-        return true;
-    }
-    return false;
-}
-
-bool CSSParser::parseScrollSnapPositions(RefPtr&lt;CSSValue&gt;&amp; cssValueX, RefPtr&lt;CSSValue&gt;&amp; cssValueY)
-{
-    cssValueX = parsePositionX(*m_valueList);
-    if (!cssValueX)
-        return false;
-
-    // Don't accept odd-length lists of positions (must always have an X and a Y):
-    if (!m_valueList-&gt;next())
-        return false;
-
-    cssValueY = parsePositionY(*m_valueList);
-    if (!cssValueY)
-        return false;
-
-    return true;
-}
-
-bool CSSParser::parseScrollSnapDestination(CSSPropertyID propId, bool important)
-{
-    auto position = CSSValueList::createSpaceSeparated();
-    if (m_valueList-&gt;size() != 2)
-        return false;
-
-    RefPtr&lt;CSSValue&gt; cssValueX, cssValueY;
-    if (!parseScrollSnapPositions(cssValueX, cssValueY))
-        return false;
-
-    position-&gt;append(cssValueX.releaseNonNull());
-    position-&gt;append(cssValueY.releaseNonNull());
-    addProperty(propId, WTFMove(position), important);
-    m_valueList-&gt;next();
-    return true;
-}
-
-bool CSSParser::parseScrollSnapCoordinate(CSSPropertyID propId, bool important)
-{
-    auto positions = CSSValueList::createSpaceSeparated();
-    while (m_valueList-&gt;current()) {
-        RefPtr&lt;CSSValue&gt; cssValueX, cssValueY;
-        if (!parseScrollSnapPositions(cssValueX, cssValueY))
-            return false;
-
-        positions-&gt;append(cssValueX.releaseNonNull());
-        positions-&gt;append(cssValueY.releaseNonNull());
-        m_valueList-&gt;next();
-    }
-
-    if (positions-&gt;length()) {
-        addProperty(propId, WTFMove(positions), important);
-        return true;
-    }
-    return false;
-}
-#endif
-
-const int cMaxFillProperties = 9;
-
-bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* properties, int numProperties, bool important)
-{
-    ASSERT(numProperties &lt;= cMaxFillProperties);
-    if (numProperties &gt; cMaxFillProperties)
-        return false;
-
-    ShorthandScope scope(this, propId);
-
-    bool parsedProperty[cMaxFillProperties] = { false };
-    RefPtr&lt;CSSValue&gt; values[cMaxFillProperties];
-    RefPtr&lt;CSSValue&gt; clipValue;
-    RefPtr&lt;CSSValue&gt; positionYValue;
-    RefPtr&lt;CSSValue&gt; repeatYValue;
-    bool foundClip = false;
-    int i;
-    bool foundPositionCSSProperty = false;
-
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    while (m_valueList-&gt;current()) {
-        CSSParserValue&amp; currentValue = *m_valueList-&gt;current();
-        if (currentValue.unit == CSSParserValue::Operator &amp;&amp; currentValue.iValue == ',') {
-            // We hit the end.  Fill in all remaining values with the initial value.
-            m_valueList-&gt;next();
-            for (i = 0; i &lt; numProperties; ++i) {
-                if (properties[i] == CSSPropertyBackgroundColor &amp;&amp; parsedProperty[i])
-                    // Color is not allowed except as the last item in a list for backgrounds.
-                    // Reject the entire property.
-                    return false;
-
-                if (!parsedProperty[i] &amp;&amp; properties[i] != CSSPropertyBackgroundColor) {
-                    addFillValue(values[i], cssValuePool.createImplicitInitialValue());
-                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
-                        addFillValue(positionYValue, cssValuePool.createImplicitInitialValue());
-                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
-                        addFillValue(repeatYValue, cssValuePool.createImplicitInitialValue());
-                    if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) &amp;&amp; !parsedProperty[i]) {
-                        // If background-origin wasn't present, then reset background-clip also.
-                        addFillValue(clipValue, cssValuePool.createImplicitInitialValue());
-                    }
-                }
-                parsedProperty[i] = false;
-            }
-            if (!m_valueList-&gt;current())
-                break;
-        }
-
-        bool sizeCSSPropertyExpected = false;
-        if (isForwardSlashOperator(currentValue) &amp;&amp; foundPositionCSSProperty) {
-            sizeCSSPropertyExpected = true;
-            m_valueList-&gt;next();
-        }
-
-        foundPositionCSSProperty = false;
-        bool found = false;
-        for (i = 0; !found &amp;&amp; i &lt; numProperties; ++i) {
-
-            if (sizeCSSPropertyExpected &amp;&amp; (properties[i] != CSSPropertyBackgroundSize &amp;&amp; properties[i] != CSSPropertyWebkitMaskSize))
-                continue;
-            if (!sizeCSSPropertyExpected &amp;&amp; (properties[i] == CSSPropertyBackgroundSize || properties[i] == CSSPropertyWebkitMaskSize))
-                continue;
-
-            if (!parsedProperty[i]) {
-                RefPtr&lt;CSSValue&gt; val1;
-                RefPtr&lt;CSSValue&gt; val2;
-                CSSPropertyID propId1, propId2;
-                CSSParserValue&amp; parserValue = *m_valueList-&gt;current();
-
-                if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) {
-                    parsedProperty[i] = found = true;
-                    addFillValue(values[i], val1.releaseNonNull());
-                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
-                        addFillValue(positionYValue, val2.releaseNonNull());
-                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
-                        addFillValue(repeatYValue, val2.releaseNonNull());
-                    if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
-                        // Reparse the value as a clip, and see if we succeed.
-                        if (parseBackgroundClip(parserValue, val1))
-                            addFillValue(clipValue, val1.releaseNonNull()); // The property parsed successfully.
-                        else
-                            addFillValue(clipValue, cssValuePool.createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead.
-                    }
-                    if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip)
-                        foundClip = true;
-                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
-                        foundPositionCSSProperty = true;
-                }
-            }
-        }
-
-        // if we didn't find at least one match, this is an
-        // invalid shorthand and we have to ignore it
-        if (!found)
-            return false;
-    }
-
-    // Now add all of the properties we found.
-    for (i = 0; i &lt; numProperties; ++i) {
-        // Fill in any remaining properties with the initial value.
-        if (!parsedProperty[i]) {
-            addFillValue(values[i], cssValuePool.createImplicitInitialValue());
-            if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
-                addFillValue(positionYValue, cssValuePool.createImplicitInitialValue());
-            if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
-                addFillValue(repeatYValue, cssValuePool.createImplicitInitialValue());
-            if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
-                // If background-origin wasn't present, then reset background-clip also.
-                addFillValue(clipValue, cssValuePool.createImplicitInitialValue());
-            }
-        }
-        if (properties[i] == CSSPropertyBackgroundPosition) {
-            addProperty(CSSPropertyBackgroundPositionX, WTFMove(values[i]), important);
-            // it's OK to call WTFMove(positionYValue) since we only see CSSPropertyBackgroundPosition once
-            addProperty(CSSPropertyBackgroundPositionY, WTFMove(positionYValue), important);
-        } else if (properties[i] == CSSPropertyWebkitMaskPosition) {
-            addProperty(CSSPropertyWebkitMaskPositionX, WTFMove(values[i]), important);
-            // it's OK to call WTFMove(positionYValue) since we only see CSSPropertyWebkitMaskPosition once
-            addProperty(CSSPropertyWebkitMaskPositionY, WTFMove(positionYValue), important);
-        } else if (properties[i] == CSSPropertyBackgroundRepeat) {
-            addProperty(CSSPropertyBackgroundRepeatX, WTFMove(values[i]), important);
-            // it's OK to call WTFMove(repeatYValue) since we only see CSSPropertyBackgroundPosition once
-            addProperty(CSSPropertyBackgroundRepeatY, WTFMove(repeatYValue), important);
-        } else if (properties[i] == CSSPropertyWebkitMaskRepeat) {
-            addProperty(CSSPropertyWebkitMaskRepeatX, WTFMove(values[i]), important);
-            // it's OK to call WTFMove(repeatYValue) since we only see CSSPropertyBackgroundPosition once
-            addProperty(CSSPropertyWebkitMaskRepeatY, WTFMove(repeatYValue), important);
-        } else if ((properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) &amp;&amp; !foundClip)
-            // Value is already set while updating origin
-            continue;
-        else if (properties[i] == CSSPropertyBackgroundSize &amp;&amp; !parsedProperty[i] &amp;&amp; useLegacyBackgroundSizeShorthandBehavior())
-            continue;
-        else
-            addProperty(properties[i], WTFMove(values[i]), important);
-
-        // Add in clip values when we hit the corresponding origin property.
-        if (properties[i] == CSSPropertyBackgroundOrigin &amp;&amp; !foundClip)
-            addProperty(CSSPropertyBackgroundClip, WTFMove(clipValue), important);
-        else if (properties[i] == CSSPropertyWebkitMaskOrigin &amp;&amp; !foundClip)
-            addProperty(CSSPropertyWebkitMaskClip, WTFMove(clipValue), important);
-    }
-
-    return true;
-}
-
-void CSSParser::addAnimationValue(RefPtr&lt;CSSValue&gt;&amp; lval, Ref&lt;CSSValue&gt;&amp;&amp; rval)
-{
-    if (!lval) {
-        lval = WTFMove(rval);
-        return;
-    }
-
-    if (is&lt;CSSValueList&gt;(*lval)) {
-        downcast&lt;CSSValueList&gt;(*lval).append(WTFMove(rval));
-        return;
-    }
-
-    auto list = CSSValueList::createCommaSeparated();
-    list-&gt;append(lval.releaseNonNull());
-    list-&gt;append(WTFMove(rval));
-    lval = WTFMove(list);
-}
-
-bool CSSParser::parseAnimationShorthand(CSSPropertyID propId, bool important)
-{
-    ASSERT(propId == CSSPropertyAnimation || propId == CSSPropertyWebkitAnimation);
-
-    const unsigned numProperties = 8;
-    const StylePropertyShorthand&amp; shorthand = animationShorthandForParsing(propId);
-
-    // The list of properties in the shorthand should be the same
-    // length as the list with animation name in last position, even though they are
-    // in a different order.
-    ASSERT(numProperties == shorthand.length());
-    ASSERT(numProperties == animationShorthand().length());
-    ASSERT(numProperties == webkitAnimationShorthand().length());
-
-    ShorthandScope scope(this, propId);
-
-    bool parsedProperty[numProperties] = { false };
-    AnimationParseContext context;
-    RefPtr&lt;CSSValue&gt; values[numProperties];
-
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    unsigned i;
-    while (m_valueList-&gt;current()) {
-        CSSParserValue* val = m_valueList-&gt;current();
-        if (val-&gt;unit == CSSParserValue::Operator &amp;&amp; val-&gt;iValue == ',') {
-            // We hit the end.  Fill in all remaining values with the initial value.
-            m_valueList-&gt;next();
-            for (i = 0; i &lt; numProperties; ++i) {
-                if (!parsedProperty[i])
-                    addAnimationValue(values[i], cssValuePool.createImplicitInitialValue());
-                parsedProperty[i] = false;
-            }
-            if (!m_valueList-&gt;current())
-                break;
-            context.commitFirstAnimation();
-        }
-
-        bool found = false;
-        for (i = 0; i &lt; numProperties; ++i) {
-            if (!parsedProperty[i]) {
-                RefPtr&lt;CSSValue&gt; val;
-                if (parseAnimationProperty(shorthand.properties()[i], val, context)) {
-                    parsedProperty[i] = found = true;
-                    addAnimationValue(values[i], val.releaseNonNull());
-                    break;
-                }
-            }
-
-            // There are more values to process but 'none' or 'all' were already defined as the animation property, the declaration becomes invalid.
-            if (!context.animationPropertyKeywordAllowed() &amp;&amp; context.hasCommittedFirstAnimation())
-                return false;
-        }
-
-        // if we didn't find at least one match, this is an
-        // invalid shorthand and we have to ignore it
-        if (!found)
-            return false;
-    }
-
-    // Fill in any remaining properties with the initial value.
-    for (i = 0; i &lt; numProperties; ++i) {
-        if (!parsedProperty[i])
-            addAnimationValue(values[i], cssValuePool.createImplicitInitialValue());
-    }
-
-    // Now add all of the properties we found.
-    // In this case we have to explicitly set the variant form as well,
-    // to make sure that a shorthand clears all existing prefixed and
-    // unprefixed values.
-    for (i = 0; i &lt; numProperties; ++i)
-        addPropertyWithPrefixingVariant(shorthand.properties()[i], WTFMove(values[i]), important);
-
-    return true;
-}
-
-void CSSParser::addPropertyWithPrefixingVariant(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp;&amp; value, bool important, bool implicit)
-{
-    addProperty(propId, value.copyRef(), important, implicit);
-
-    CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(propId);
-    if (prefixingVariant == propId)
-        return;
-
-    if (m_currentShorthand) {
-        // We can't use ShorthandScope here as we can already be inside one (e.g we are parsing CSSTransition).
-        m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
-        addProperty(prefixingVariant, WTFMove(value), important, implicit);
-        m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
-    } else
-        addProperty(prefixingVariant, WTFMove(value), important, implicit);
-}
-
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseColumnWidth()
-{
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-    CSSValueID id = valueWithCalculation.value().id;
-    // Always parse this property in strict mode, since it would be ambiguous otherwise when used in the 'columns' shorthand property.
-    if (id != CSSValueAuto &amp;&amp; !(validateUnit(valueWithCalculation, FLength | FNonNeg, CSSStrictMode) &amp;&amp; parsedDouble(valueWithCalculation)))
-        return nullptr;
-
-    auto parsedValue = parseValidPrimitive(id, valueWithCalculation);
-    m_valueList-&gt;next();
-    return parsedValue;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseColumnCount()
-{
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-    CSSValueID id = valueWithCalculation.value().id;
-
-    if (id != CSSValueAuto &amp;&amp; !validateUnit(valueWithCalculation, FPositiveInteger, CSSQuirksMode))
-        return nullptr;
-
-    auto parsedValue = parseValidPrimitive(id, valueWithCalculation);
-    m_valueList-&gt;next();
-    return parsedValue;
-}
-
-bool CSSParser::parseColumnsShorthand(bool important)
-{
-    RefPtr&lt;CSSValue&gt; columnWidth;
-    RefPtr&lt;CSSValue&gt; columnCount;
-    bool hasPendingExplicitAuto = false;
-
-    for (unsigned propertiesParsed = 0; CSSParserValue* value = m_valueList-&gt;current(); ++propertiesParsed) {
-        if (propertiesParsed &gt;= 2)
-            return false; // Too many values for this shorthand. Invalid declaration.
-        if (!propertiesParsed &amp;&amp; value-&gt;id == CSSValueAuto) {
-            // 'auto' is a valid value for any of the two longhands, and at this point
-            // we don't know which one(s) it is meant for. We need to see if there are other values first.
-            m_valueList-&gt;next();
-            hasPendingExplicitAuto = true;
-        } else {
-            if (!columnWidth) {
-                if ((columnWidth = parseColumnWidth()))
-                    continue;
-            }
-            if (!columnCount) {
-                if ((columnCount = parseColumnCount()))
-                    continue;
-            }
-            // If we didn't find at least one match, this is an invalid shorthand and we have to ignore it.
-            return false;
-        }
-    }
-
-    // Any unassigned property at this point will become implicit 'auto'.
-    if (columnWidth)
-        addProperty(CSSPropertyColumnWidth, WTFMove(columnWidth), important);
-    else {
-        addProperty(CSSPropertyColumnWidth, CSSValuePool::singleton().createIdentifierValue(CSSValueAuto), important, !hasPendingExplicitAuto /* implicit */);
-        hasPendingExplicitAuto = false;
-    }
-
-    if (columnCount)
-        addProperty(CSSPropertyColumnCount, WTFMove(columnCount), important);
-    else
-        addProperty(CSSPropertyColumnCount, CSSValuePool::singleton().createIdentifierValue(CSSValueAuto), important, !hasPendingExplicitAuto /* implicit */);
-
-    return true;
-}
-
-bool CSSParser::parseTransitionShorthand(CSSPropertyID propId, bool important)
-{
-    const unsigned numProperties = 4;
-    const StylePropertyShorthand&amp; shorthand = shorthandForProperty(propId);
-    ASSERT(numProperties == shorthand.length());
-
-    ShorthandScope scope(this, propId);
-
-    bool parsedProperty[numProperties] = { false };
-    AnimationParseContext context;
-    RefPtr&lt;CSSValue&gt; values[numProperties];
-
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    unsigned i;
-    while (m_valueList-&gt;current()) {
-        CSSParserValue* val = m_valueList-&gt;current();
-        if (val-&gt;unit == CSSParserValue::Operator &amp;&amp; val-&gt;iValue == ',') {
-            // We hit the end. Fill in all remaining values with the initial value.
-            m_valueList-&gt;next();
-            for (i = 0; i &lt; numProperties; ++i) {
-                if (!parsedProperty[i])
-                    addAnimationValue(values[i], cssValuePool.createImplicitInitialValue());
-                parsedProperty[i] = false;
-            }
-            if (!m_valueList-&gt;current())
-                break;
-            context.commitFirstAnimation();
-        }
-
-        bool found = false;
-        for (i = 0; !found &amp;&amp; i &lt; numProperties; ++i) {
-            if (!parsedProperty[i]) {
-                RefPtr&lt;CSSValue&gt; val;
-                if (parseAnimationProperty(shorthand.properties()[i], val, context)) {
-                    parsedProperty[i] = found = true;
-                    addAnimationValue(values[i], val.releaseNonNull());
-                }
-
-                // There are more values to process but 'none' or 'all' were already defined as the animation property, the declaration becomes invalid.
-                if (!context.animationPropertyKeywordAllowed() &amp;&amp; context.hasCommittedFirstAnimation())
-                    return false;
-            }
-        }
-
-        // if we didn't find at least one match, this is an
-        // invalid shorthand and we have to ignore it
-        if (!found)
-            return false;
-    }
-
-    // Fill in any remaining properties with the initial value.
-    for (i = 0; i &lt; numProperties; ++i) {
-        if (!parsedProperty[i])
-            addAnimationValue(values[i], cssValuePool.createImplicitInitialValue());
-    }
-
-    // Now add all of the properties we found.
-    // In this case we have to explicitly set the variant form as well,
-    // to make sure that a shorthand clears all existing prefixed and
-    // unprefixed values.
-    for (i = 0; i &lt; numProperties; ++i)
-        addPropertyWithPrefixingVariant(shorthand.properties()[i], WTFMove(values[i]), important);
-
-    return true;
-}
-
-bool CSSParser::parseShorthand(CSSPropertyID propId, const StylePropertyShorthand&amp; shorthand, bool important)
-{
-    // We try to match as many properties as possible
-    // We set up an array of booleans to mark which property has been found,
-    // and we try to search for properties until it makes no longer any sense.
-    ShorthandScope scope(this, propId);
-
-    bool found = false;
-    unsigned propertiesParsed = 0;
-    bool propertyFound[6]= { false, false, false, false, false, false }; // 6 is enough size.
-
-    while (m_valueList-&gt;current()) {
-        found = false;
-        for (unsigned propIndex = 0; !found &amp;&amp; propIndex &lt; shorthand.length(); ++propIndex) {
-            if (!propertyFound[propIndex] &amp;&amp; parseValue(shorthand.properties()[propIndex], important)) {
-                    propertyFound[propIndex] = found = true;
-                    propertiesParsed++;
-            }
-        }
-
-        // if we didn't find at least one match, this is an
-        // invalid shorthand and we have to ignore it
-        if (!found)
-            return false;
-    }
-
-    if (propertiesParsed == shorthand.length())
-        return true;
-
-    // Fill in any remaining properties with the initial value.
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    ImplicitScope implicitScope(*this, PropertyImplicit);
-    const StylePropertyShorthand* propertiesForInitialization = shorthand.propertiesForInitialization();
-    for (unsigned i = 0; i &lt; shorthand.length(); ++i) {
-        if (propertyFound[i])
-            continue;
-
-        if (propertiesForInitialization) {
-            const StylePropertyShorthand&amp; initProperties = propertiesForInitialization[i];
-            for (unsigned propIndex = 0; propIndex &lt; initProperties.length(); ++propIndex)
-                addProperty(initProperties.properties()[propIndex], cssValuePool.createImplicitInitialValue(), important);
-        } else
-            addProperty(shorthand.properties()[i], cssValuePool.createImplicitInitialValue(), important);
-    }
-
-    return true;
-}
-
-bool CSSParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properties,  bool important)
-{
-    /* From the CSS 2 specs, 8.3
-     * If there is only one value, it applies to all sides. If there are two values, the top and
-     * bottom margins are set to the first value and the right and left margins are set to the second.
-     * If there are three values, the top is set to the first value, the left and right are set to the
-     * second, and the bottom is set to the third. If there are four values, they apply to the top,
-     * right, bottom, and left, respectively.
-     */
-
-    unsigned num = inShorthand() ? 1 : m_valueList-&gt;size();
-
-    ShorthandScope scope(this, propId);
-
-    // the order is top, right, bottom, left
-    switch (num) {
-        case 1: {
-            if (!parseValue(properties[0], important))
-                return false;
-            CSSValue* value = m_parsedProperties.last().value();
-            ImplicitScope implicitScope(*this, PropertyImplicit);
-            addProperty(properties[1], value, important);
-            addProperty(properties[2], value, important);
-            addProperty(properties[3], value, important);
-            break;
-        }
-        case 2: {
-            if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
-                return false;
-            CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
-            ImplicitScope implicitScope(*this, PropertyImplicit);
-            addProperty(properties[2], value, important);
-            value = m_parsedProperties[m_parsedProperties.size() - 2].value();
-            addProperty(properties[3], value, important);
-            break;
-        }
-        case 3: {
-            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important))
-                return false;
-            CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
-            ImplicitScope implicitScope(*this, PropertyImplicit);
-            addProperty(properties[3], value, important);
-            break;
-        }
-        case 4: {
-            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) ||
-                !parseValue(properties[2], important) || !parseValue(properties[3], important))
-                return false;
-            break;
-        }
-        default: {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-// auto | &lt;identifier&gt;
-bool CSSParser::parsePage(CSSPropertyID propId, bool important)
-{
-    ASSERT(propId == CSSPropertyPage);
-
-    if (m_valueList-&gt;size() != 1)
-        return false;
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (!value)
-        return false;
-
-    if (value-&gt;id == CSSValueAuto) {
-        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
-        return true;
-    } else if (value-&gt;id == 0 &amp;&amp; value-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
-        addProperty(propId, createPrimitiveStringValue(*value), important);
-        return true;
-    }
-    return false;
-}
-
-// &lt;length&gt;{1,2} | auto | [ &lt;page-size&gt; || [ portrait | landscape] ]
-bool CSSParser::parseSize(CSSPropertyID propId, bool important)
-{
-    ASSERT(propId == CSSPropertySize);
-
-    if (m_valueList-&gt;size() &gt; 2)
-        return false;
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (!value)
-        return false;
-
-    auto parsedValues = CSSValueList::createSpaceSeparated();
-
-    // First parameter.
-    SizeParameterType paramType = parseSizeParameter(parsedValues, *value, None);
-    if (paramType == None)
-        return false;
-
-    // Second parameter, if any.
-    value = m_valueList-&gt;next();
-    if (value) {
-        paramType = parseSizeParameter(parsedValues, *value, paramType);
-        if (paramType == None)
-            return false;
-    }
-
-    addProperty(propId, WTFMove(parsedValues), important);
-    return true;
-}
-
-CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList&amp; parsedValues, CSSParserValue&amp; value, SizeParameterType prevParamType)
-{
-    switch (value.id) {
-    case CSSValueAuto:
-        if (prevParamType == None) {
-            parsedValues.append(CSSValuePool::singleton().createIdentifierValue(value.id));
-            return Auto;
-        }
-        return None;
-    case CSSValueLandscape:
-    case CSSValuePortrait:
-        if (prevParamType == None || prevParamType == PageSize) {
-            parsedValues.append(CSSValuePool::singleton().createIdentifierValue(value.id));
-            return Orientation;
-        }
-        return None;
-    case CSSValueA3:
-    case CSSValueA4:
-    case CSSValueA5:
-    case CSSValueB4:
-    case CSSValueB5:
-    case CSSValueLedger:
-    case CSSValueLegal:
-    case CSSValueLetter:
-        if (prevParamType == None || prevParamType == Orientation) {
-            // Normalize to Page Size then Orientation order by prepending.
-            // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (StyleResolver::applyPageSizeProperty).
-            parsedValues.prepend(CSSValuePool::singleton().createIdentifierValue(value.id));
-            return PageSize;
-        }
-        return None;
-    case CSSValueInvalid: {
-        ValueWithCalculation valueWithCalculation(value);
-        if (validateUnit(valueWithCalculation, FLength | FNonNeg) &amp;&amp; (prevParamType == None || prevParamType == Length)) {
-            parsedValues.append(createPrimitiveNumericValue(valueWithCalculation));
-            return Length;
-        }
-        return None;
-    }
-    default:
-        return None;
-    }
-}
-
-// [ &lt;string&gt; &lt;string&gt; ]+ | inherit | none
-// inherit and none are handled in parseValue.
-bool CSSParser::parseQuotes(CSSPropertyID propId, bool important)
-{
-    auto values = CSSValueList::createCommaSeparated();
-    while (CSSParserValue* value = m_valueList-&gt;current()) {
-        if (value-&gt;unit != CSSPrimitiveValue::CSS_STRING)
-            break;
-        values-&gt;append(CSSPrimitiveValue::create(value-&gt;string, CSSPrimitiveValue::CSS_STRING));
-        m_valueList-&gt;next();
-    }
-    if (values-&gt;length()) {
-        addProperty(propId, WTFMove(values), important);
-        m_valueList-&gt;next();
-        return true;
-    }
-    return false;
-}
-
-bool CSSParser::parseAlt(CSSPropertyID propID, bool important)
-{
-    CSSParserValue&amp; currentValue = *m_valueList-&gt;current();
-    RefPtr&lt;CSSValue&gt; parsedValue;
-
-    if (currentValue.unit == CSSPrimitiveValue::CSS_STRING)
-        parsedValue = createPrimitiveStringValue(currentValue);
-    else if (currentValue.unit == CSSParserValue::Function) {
-        CSSParserValueList* args = currentValue.function-&gt;args.get();
-        if (!args)
-            return false;
-        if (equalLettersIgnoringASCIICase(currentValue.function-&gt;name, &quot;attr(&quot;))
-            parsedValue = parseAttr(*args);
-    }
-    
-    if (parsedValue) {
-        addProperty(propID, parsedValue.releaseNonNull(), important);
-        m_valueList-&gt;next();
-        return true;
-    }
-
-    return false;
-}
-
-bool CSSParser::parseCustomPropertyDeclaration(bool important, CSSValueID id)
-{
-    if (m_customPropertyName.isEmpty() || !m_valueList)
-        return false;
-    
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    RefPtr&lt;CSSValue&gt; value;
-    if (id == CSSValueInherit)
-        value = cssValuePool.createInheritedValue();
-    else if (id == CSSValueInitial)
-        value = cssValuePool.createExplicitInitialValue();
-    else if (id == CSSValueUnset)
-        value = cssValuePool.createUnsetValue();
-    else if (id == CSSValueRevert)
-        value = cssValuePool.createRevertValue();
-    else {
-        auto valueList = CSSValueList::createFromParserValueList(*m_valueList);
-        if (m_valueList-&gt;containsVariables())
-            value = CSSVariableDependentValue::create(WTFMove(valueList), CSSPropertyCustom);
-        else
-            value = WTFMove(valueList);
-    }
-
-    addProperty(CSSPropertyCustom, CSSCustomPropertyValue::create(m_customPropertyName, value.releaseNonNull()), important, false);
-    return true;
-}
-
-// [ &lt;string&gt; | &lt;uri&gt; | &lt;counter&gt; | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
-// in CSS 2.1 this got somewhat reduced:
-// [ &lt;string&gt; | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
-bool CSSParser::parseContent(CSSPropertyID propId, bool important)
-{
-    auto values = CSSValueList::createCommaSeparated();
-
-    while (CSSParserValue* value = m_valueList-&gt;current()) {
-        RefPtr&lt;CSSValue&gt; parsedValue;
-        if (value-&gt;unit == CSSPrimitiveValue::CSS_URI) {
-            // url
-            parsedValue = CSSImageValue::create(completeURL(value-&gt;string));
-        } else if (value-&gt;unit == CSSParserValue::Function) {
-            // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...)
-            CSSParserValueList* args = value-&gt;function-&gt;args.get();
-            if (!args)
-                return false;
-            if (equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;attr(&quot;)) {
-                parsedValue = parseAttr(*args);
-                if (!parsedValue)
-                    return false;
-            } else if (equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;counter(&quot;)) {
-                parsedValue = parseCounterContent(*args, false);
-                if (!parsedValue)
-                    return false;
-            } else if (equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;counters(&quot;)) {
-                parsedValue = parseCounterContent(*args, true);
-                if (!parsedValue)
-                    return false;
-            } else if (isImageSetFunctionValue(*value)) {
-                parsedValue = parseImageSet();
-                if (!parsedValue)
-                    return false;
-            } else if (isGeneratedImageValue(*value)) {
-                if (!parseGeneratedImage(*m_valueList, parsedValue))
-                    return false;
-            } else
-                return false;
-        } else if (value-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
-            // open-quote
-            // close-quote
-            // no-open-quote
-            // no-close-quote
-            // inherit
-            // FIXME: These are not yet implemented (http://bugs.webkit.org/show_bug.cgi?id=6503).
-            // none
-            // normal
-            switch (value-&gt;id) {
-            case CSSValueOpenQuote:
-            case CSSValueCloseQuote:
-            case CSSValueNoOpenQuote:
-            case CSSValueNoCloseQuote:
-            case CSSValueNone:
-            case CSSValueNormal:
-                parsedValue = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-                break;
-            default:
-                break;
-            }
-        } else if (value-&gt;unit == CSSPrimitiveValue::CSS_STRING) {
-            parsedValue = createPrimitiveStringValue(*value);
-        }
-        if (!parsedValue)
-            break;
-        values-&gt;append(parsedValue.releaseNonNull());
-        m_valueList-&gt;next();
-    }
-
-    if (values-&gt;length()) {
-        addProperty(propId, WTFMove(values), important);
-        m_valueList-&gt;next();
-        return true;
-    }
-
-    return false;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAttr(CSSParserValueList&amp; args)
-{
-    if (args.size() != 1)
-        return nullptr;
-
-    CSSParserValue&amp; argument = *args.current();
-
-    if (argument.unit != CSSPrimitiveValue::CSS_IDENT)
-        return nullptr;
-
-    ASSERT(argument.string.length());
-
-    // CSS allows identifiers with &quot;-&quot; at the start, like &quot;-webkit-mask-image&quot;.
-    // But HTML attribute names can't have those characters, and we should not
-    // even parse them inside attr().
-    if (argument.string[0] == '-')
-        return nullptr;
-
-    if (m_context.isHTMLDocument)
-        argument.string.convertToASCIILowercaseInPlace();
-
-    // FIXME: Is there some small benefit to creating an AtomicString here instead of a String?
-    return CSSValuePool::singleton().createValue(String(argument.string), CSSPrimitiveValue::CSS_ATTR);
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseBackgroundColor()
-{
-    CSSValueID id = m_valueList-&gt;current()-&gt;id;
-    if (id == CSSValueWebkitText || isValidSystemColorValue(id) || id == CSSValueMenu || id == CSSValueCurrentcolor
-        || (id &gt;= CSSValueGrey &amp;&amp; id &lt; CSSValueWebkitText &amp;&amp; inQuirksMode()))
-        return CSSValuePool::singleton().createIdentifierValue(id);
-    return parseColor();
-}
-
-bool CSSParser::parseFillImage(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; value)
-{
-    if (valueList.current()-&gt;id == CSSValueNone) {
-        value = CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
-        return true;
-    }
-    if (valueList.current()-&gt;unit == CSSPrimitiveValue::CSS_URI) {
-        value = CSSImageValue::create(completeURL(valueList.current()-&gt;string));
-        return true;
-    }
-
-    if (isGeneratedImageValue(*valueList.current()))
-        return parseGeneratedImage(valueList, value);
-    
-    if (isImageSetFunctionValue(*valueList.current())) {
-        value = parseImageSet();
-        if (value)
-            return true;
-    }
-
-    return false;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parsePositionX(CSSParserValueList&amp; valueList)
-{
-    int id = valueList.current()-&gt;id;
-    if (id == CSSValueLeft || id == CSSValueRight || id == CSSValueCenter) {
-        int percent = 0;
-        if (id == CSSValueRight)
-            percent = 100;
-        else if (id == CSSValueCenter)
-            percent = 50;
-        return CSSValuePool::singleton().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
-    }
-    ValueWithCalculation valueWithCalculation(*valueList.current());
-    if (validateUnit(valueWithCalculation, FPercent | FLength))
-        return createPrimitiveNumericValue(valueWithCalculation);
-    return nullptr;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parsePositionY(CSSParserValueList&amp; valueList)
-{
-    int id = valueList.current()-&gt;id;
-    if (id == CSSValueTop || id == CSSValueBottom || id == CSSValueCenter) {
-        int percent = 0;
-        if (id == CSSValueBottom)
-            percent = 100;
-        else if (id == CSSValueCenter)
-            percent = 50;
-        return CSSValuePool::singleton().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
-    }
-    ValueWithCalculation valueWithCalculation(*valueList.current());
-    if (validateUnit(valueWithCalculation, FPercent | FLength))
-        return createPrimitiveNumericValue(valueWithCalculation);
-    return nullptr;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseFillPositionComponent(CSSParserValueList&amp; valueList, unsigned&amp; cumulativeFlags, FillPositionFlag&amp; individualFlag, FillPositionParsingMode parsingMode)
-{
-    CSSValueID id = valueList.current()-&gt;id;
-    if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) {
-        int percent = 0;
-        if (id == CSSValueLeft || id == CSSValueRight) {
-            if (cumulativeFlags &amp; XFillPosition)
-                return nullptr;
-            cumulativeFlags |= XFillPosition;
-            individualFlag = XFillPosition;
-            if (id == CSSValueRight)
-                percent = 100;
-        }
-        else if (id == CSSValueTop || id == CSSValueBottom) {
-            if (cumulativeFlags &amp; YFillPosition)
-                return nullptr;
-            cumulativeFlags |= YFillPosition;
-            individualFlag = YFillPosition;
-            if (id == CSSValueBottom)
-                percent = 100;
-        } else if (id == CSSValueCenter) {
-            // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
-            percent = 50;
-            cumulativeFlags |= AmbiguousFillPosition;
-            individualFlag = AmbiguousFillPosition;
-        }
-
-        if (parsingMode == ResolveValuesAsKeyword)
-            return CSSValuePool::singleton().createIdentifierValue(id);
-
-        return CSSValuePool::singleton().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
-    }
-    ValueWithCalculation valueWithCalculation(*valueList.current());
-    if (!validateUnit(valueWithCalculation, FPercent | FLength))
-        return nullptr;
-
-    if (!cumulativeFlags) {
-        cumulativeFlags |= XFillPosition;
-        individualFlag = XFillPosition;
-    } else if (cumulativeFlags &amp; (XFillPosition | AmbiguousFillPosition)) {
-        cumulativeFlags |= YFillPosition;
-        individualFlag = YFillPosition;
-    } else
-        return nullptr;
-    return createPrimitiveNumericValue(valueWithCalculation);
-}
-
-static bool isValueConflictingWithCurrentEdge(int value1, int value2)
-{
-    if ((value1 == CSSValueLeft || value1 == CSSValueRight) &amp;&amp; (value2 == CSSValueLeft || value2 == CSSValueRight))
-        return true;
-
-    if ((value1 == CSSValueTop || value1 == CSSValueBottom) &amp;&amp; (value2 == CSSValueTop || value2 == CSSValueBottom))
-        return true;
-
-    return false;
-}
-
-static bool isFillPositionKeyword(CSSValueID value)
-{
-    return value == CSSValueLeft || value == CSSValueTop || value == CSSValueBottom || value == CSSValueRight || value == CSSValueCenter;
-}
-
-void CSSParser::parse4ValuesFillPosition(CSSParserValueList&amp; valueList, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp; parsedValue1, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp; parsedValue2)
-{
-    // [ left | right ] [ &lt;percentage] | &lt;length&gt; ] &amp;&amp; [ top | bottom ] [ &lt;percentage&gt; | &lt;length&gt; ]
-    // In the case of 4 values &lt;position&gt; requires the second value to be a length or a percentage.
-    if (isFillPositionKeyword(parsedValue2-&gt;getValueID()))
-        return;
-
-    unsigned cumulativeFlags = 0;
-    FillPositionFlag value3Flag = InvalidFillPosition;
-    auto value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
-    if (!value3)
-        return;
-
-    CSSValueID ident1 = parsedValue1-&gt;getValueID();
-    CSSValueID ident3 = value3-&gt;getValueID();
-
-    if (ident1 == CSSValueCenter)
-        return;
-
-    if (!isFillPositionKeyword(ident3) || ident3 == CSSValueCenter)
-        return;
-
-    // We need to check if the values are not conflicting, e.g. they are not on the same edge. It is
-    // needed as the second call to parseFillPositionComponent was on purpose not checking it. In the
-    // case of two values top 20px is invalid but in the case of 4 values it becomes valid.
-    if (isValueConflictingWithCurrentEdge(ident1, ident3))
-        return;
-
-    valueList.next();
-
-    cumulativeFlags = 0;
-    FillPositionFlag value4Flag = InvalidFillPosition;
-    auto value4 = parseFillPositionComponent(valueList, cumulativeFlags, value4Flag, ResolveValuesAsKeyword);
-    if (!value4)
-        return;
-
-    // 4th value must be a length or a percentage.
-    if (isFillPositionKeyword(value4-&gt;getValueID()))
-        return;
-
-    value1 = createPrimitiveValuePair(WTFMove(parsedValue1), WTFMove(parsedValue2));
-    value2 = createPrimitiveValuePair(value3.releaseNonNull(), value4.releaseNonNull());
-
-    if (ident1 == CSSValueTop || ident1 == CSSValueBottom)
-        value1.swap(value2);
-
-    valueList.next();
-}
-
-void CSSParser::parse3ValuesFillPosition(CSSParserValueList&amp; valueList, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp; parsedValue1, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp; parsedValue2)
-{
-    unsigned cumulativeFlags = 0;
-    FillPositionFlag value3Flag = InvalidFillPosition;
-    auto value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
-
-    // value3 is not an expected value, we return.
-    if (!value3)
-        return;
-
-    valueList.next();
-
-    bool swapNeeded = false;
-    CSSValueID ident1 = parsedValue1-&gt;getValueID();
-    CSSValueID ident2 = parsedValue2-&gt;getValueID();
-    CSSValueID ident3 = value3-&gt;getValueID();
-
-    CSSValueID firstPositionKeyword;
-    CSSValueID secondPositionKeyword;
-
-    auto&amp; cssValuePool = CSSValuePool::singleton();
-    if (ident1 == CSSValueCenter) {
-        // &lt;position&gt; requires the first 'center' to be followed by a keyword.
-        if (!isFillPositionKeyword(ident2))
-            return;
-
-        // If 'center' is the first keyword then the last one needs to be a length.
-        if (isFillPositionKeyword(ident3))
-            return;
-
-        firstPositionKeyword = CSSValueLeft;
-        if (ident2 == CSSValueLeft || ident2 == CSSValueRight) {
-            firstPositionKeyword = CSSValueTop;
-            swapNeeded = true;
-        }
-        value1 = createPrimitiveValuePair(cssValuePool.createIdentifierValue(firstPositionKeyword), cssValuePool.createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
-        value2 = createPrimitiveValuePair(WTFMove(parsedValue2), value3.copyRef());
-    } else if (ident3 == CSSValueCenter) {
-        if (isFillPositionKeyword(ident2))
-            return;
-
-        secondPositionKeyword = CSSValueTop;
-        if (ident1 == CSSValueTop || ident1 == CSSValueBottom) {
-            secondPositionKeyword = CSSValueLeft;
-            swapNeeded = true;
-        }
-        value1 = createPrimitiveValuePair(WTFMove(parsedValue1), parsedValue2.copyRef());
-        value2 = createPrimitiveValuePair(cssValuePool.createIdentifierValue(secondPositionKeyword), cssValuePool.createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
-    } else {
-        RefPtr&lt;CSSPrimitiveValue&gt; firstPositionValue;
-        RefPtr&lt;CSSPrimitiveValue&gt; secondPositionValue;
-
-        if (isFillPositionKeyword(ident2)) {
-            // To match CSS grammar, we should only accept: [ center | left | right | bottom | top ] [ left | right | top | bottom ] [ &lt;percentage&gt; | &lt;length&gt; ].
-            ASSERT(ident2 != CSSValueCenter);
-
-            if (isFillPositionKeyword(ident3))
-                return;
-
-            secondPositionValue = value3;
-            secondPositionKeyword = ident2;
-            firstPositionValue = cssValuePool.createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
-        } else {
-            // Per CSS, we should only accept: [ right | left | top | bottom ] [ &lt;percentage&gt; | &lt;length&gt; ] [ center | left | right | bottom | top ].
-            if (!isFillPositionKeyword(ident3))
-                return;
-
-            firstPositionValue = parsedValue2.ptr();
-            secondPositionKeyword = ident3;
-            secondPositionValue = cssValuePool.createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
-        }
-
-        if (isValueConflictingWithCurrentEdge(ident1, secondPositionKeyword))
-            return;
-
-        value1 = createPrimitiveValuePair(WTFMove(parsedValue1), firstPositionValue.releaseNonNull());
-        value2 = createPrimitiveValuePair(cssValuePool.createIdentifierValue(secondPositionKeyword), secondPositionValue.releaseNonNull());
-    }
-
-    if (ident1 == CSSValueTop || ident1 == CSSValueBottom || swapNeeded)
-        value1.swap(value2);
-
-#ifndef NDEBUG
-    CSSPrimitiveValue&amp; first = *value1;
-    CSSPrimitiveValue&amp; second = *value2;
-    ident1 = first.getPairValue()-&gt;first()-&gt;getValueID();
-    ident2 = second.getPairValue()-&gt;first()-&gt;getValueID();
-    ASSERT(ident1 == CSSValueLeft || ident1 == CSSValueRight);
-    ASSERT(ident2 == CSSValueBottom || ident2 == CSSValueTop);
-#endif
-}
-
-inline bool CSSParser::isPotentialPositionValue(CSSParserValue&amp; value)
-{
-    if (isFillPositionKeyword(value.id))
-        return true;
-    ValueWithCalculation valueWithCalculation(value);
-    return validateUnit(valueWithCalculation, FPercent | FLength);
-}
-
-void CSSParser::parseFillPosition(CSSParserValueList&amp; valueList, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2)
-{
-    unsigned numberOfValues = 0;
-    for (unsigned i = valueList.currentIndex(); i &lt; valueList.size(); ++i, ++numberOfValues) {
-        CSSParserValue* current = valueList.valueAt(i);
-        if (!current || isComma(current) || isForwardSlashOperator(*current) || !isPotentialPositionValue(*current))
-            break;
-    }
-
-    if (numberOfValues &gt; 4)
-        return;
-
-    // If we are parsing two values, we can safely call the CSS 2.1 parsing function and return.
-    if (numberOfValues &lt;= 2) {
-        parse2ValuesFillPosition(valueList, value1, value2);
-        return;
-    }
-
-    ASSERT(numberOfValues &gt; 2 &amp;&amp; numberOfValues &lt;= 4);
-
-    CSSParserValue* value = valueList.current();
-
-    // &lt;position&gt; requires the first value to be a background keyword.
-    if (!isFillPositionKeyword(value-&gt;id))
-        return;
-
-    // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
-    unsigned cumulativeFlags = 0;
-    FillPositionFlag value1Flag = InvalidFillPosition;
-    FillPositionFlag value2Flag = InvalidFillPosition;
-    value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag, ResolveValuesAsKeyword);
-    if (!value1)
-        return;
-
-    value = valueList.next();
-
-    // In case we are parsing more than two values, relax the check inside of parseFillPositionComponent. top 20px is
-    // a valid start for &lt;position&gt;.
-    cumulativeFlags = AmbiguousFillPosition;
-    value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag, ResolveValuesAsKeyword);
-    if (value2)
-        valueList.next();
-    else {
-        value1 = nullptr;
-        return;
-    }
-
-    auto parsedValue1 = value1.releaseNonNull();
-    auto parsedValue2 = value2.releaseNonNull();
-
-    // Per CSS3 syntax, &lt;position&gt; can't have 'center' as its second keyword as we have more arguments to follow.
-    if (parsedValue2-&gt;getValueID() == CSSValueCenter)
-        return;
-
-    if (numberOfValues == 3)
-        parse3ValuesFillPosition(valueList, value1, value2, WTFMove(parsedValue1), WTFMove(parsedValue2));
-    else
-        parse4ValuesFillPosition(valueList, value1, value2, WTFMove(parsedValue1), WTFMove(parsedValue2));
-}
-
-void CSSParser::parse2ValuesFillPosition(CSSParserValueList&amp; valueList, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2)
-{
-    CSSParserValue* value = valueList.current();
-
-    // Parse the first value.  We're just making sure that it is one of the valid keywords or a percentage/length.
-    unsigned cumulativeFlags = 0;
-    FillPositionFlag value1Flag = InvalidFillPosition;
-    FillPositionFlag value2Flag = InvalidFillPosition;
-    value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag);
-    if (!value1)
-        return;
-
-    // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we
-    // can assume that any other values belong to the rest of the shorthand).  If we're not parsing a shorthand, though, the
-    // value was explicitly specified for our property.
-    value = valueList.next();
-
-    // First check for the comma.  If so, we are finished parsing this value or value pair.
-    if (isComma(value))
-        value = nullptr;
-
-    if (value) {
-        value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag);
-        if (value2)
-            valueList.next();
-        else {
-            if (!inShorthand()) {
-                value1 = nullptr;
-                return;
-            }
-        }
-    }
-
-    if (!value2)
-        // Only one value was specified. If that value was not a keyword, then it sets the x position, and the y position
-        // is simply 50%. This is our default.
-        // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
-        // For left/right/center, the default of 50% in the y is still correct.
-        value2 = CSSValuePool::singleton().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
-
-    if (value1Flag == YFillPosition || value2Flag == XFillPosition)
-        value1.swap(value2);
-}
-
-void CSSParser::parseFillRepeat(RefPtr&lt;CSSValue&gt;&amp; value1, RefPtr&lt;CSSValue&gt;&amp; value2)
-{
-    CSSValueID id = m_valueList-&gt;current()-&gt;id;
-    if (id == CSSValueRepeatX) {
-        m_implicitShorthand = true;
-        value1 = CSSValuePool::singleton().createIdentifierValue(CSSValueRepeat);
-        value2 = CSSValuePool::singleton().createIdentifierValue(CSSValueNoRepeat);
-        m_valueList-&gt;next();
-        return;
-    }
-    if (id == CSSValueRepeatY) {
-        m_implicitShorthand = true;
-        value1 = CSSValuePool::singleton().createIdentifierValue(CSSValueNoRepeat);
-        value2 = CSSValuePool::singleton().createIdentifierValue(CSSValueRepeat);
-        m_valueList-&gt;next();
-        return;
-    }
-    if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)
-        value1 = CSSValuePool::singleton().createIdentifierValue(id);
-    else {
-        value1 = nullptr;
-        return;
-    }
-
-    CSSParserValue* value = m_valueList-&gt;next();
-
-    // Parse the second value if one is available
-    if (value &amp;&amp; !isComma(value)) {
-        id = value-&gt;id;
-        if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) {
-            value2 = CSSValuePool::singleton().createIdentifierValue(id);
-            m_valueList-&gt;next();
-            return;
-        }
-    }
-
-    // If only one value was specified, value2 is the same as value1.
-    m_implicitShorthand = true;
-    value2 = CSSValuePool::singleton().createIdentifierValue(downcast&lt;CSSPrimitiveValue&gt;(*value1).getValueID());
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseFillSize(CSSPropertyID propId, bool&amp; allowComma)
-{
-    allowComma = true;
-    CSSParserValue* value = m_valueList-&gt;current();
-
-    if (value-&gt;id == CSSValueContain || value-&gt;id == CSSValueCover)
-        return CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-
-    RefPtr&lt;CSSPrimitiveValue&gt; parsedValue1;
-
-    if (value-&gt;id == CSSValueAuto)
-        parsedValue1 = CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
-    else {
-        ValueWithCalculation valueWithCalculation(*value);
-        if (!validateUnit(valueWithCalculation, FLength | FPercent))
-            return nullptr;
-        parsedValue1 = createPrimitiveNumericValue(valueWithCalculation);
-    }
-
-    RefPtr&lt;CSSPrimitiveValue&gt; parsedValue2;
-    if ((value = m_valueList-&gt;next())) {
-        if (value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')
-            allowComma = false;
-        else if (value-&gt;id != CSSValueAuto) {
-            ValueWithCalculation valueWithCalculation(*value);
-            if (!validateUnit(valueWithCalculation, FLength | FPercent)) {
-                if (!inShorthand())
-                    return nullptr;
-                // We need to rewind the value list, so that when it is advanced we'll end up back at this value.
-                m_valueList-&gt;previous();
-            } else
-                parsedValue2 = createPrimitiveNumericValue(valueWithCalculation);
-        }
-    } else if (!parsedValue2 &amp;&amp; propId == CSSPropertyWebkitBackgroundSize) {
-        // For backwards compatibility we set the second value to the first if it is omitted.
-        // We only need to do this for -webkit-background-size. It should be safe to let masks match
-        // the real property.
-        parsedValue2 = parsedValue1;
-    }
-
-    if (!parsedValue2)
-        return parsedValue1;
-    return createPrimitiveValuePair(parsedValue1.releaseNonNull(), parsedValue2.releaseNonNull(), propId == CSSPropertyWebkitBackgroundSize ? Pair::IdenticalValueEncoding::Coalesce : Pair::IdenticalValueEncoding::DoNotCoalesce);
-}
-
-bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2,
-                                  RefPtr&lt;CSSValue&gt;&amp; retValue1, RefPtr&lt;CSSValue&gt;&amp; retValue2)
-{
-    RefPtr&lt;CSSValueList&gt; values;
-    RefPtr&lt;CSSValueList&gt; values2;
-    CSSParserValue* currentValue;
-    RefPtr&lt;CSSValue&gt; value;
-    RefPtr&lt;CSSValue&gt; value2;
-
-    bool allowComma = false;
-
-    retValue1 = retValue2 = nullptr;
-    propId1 = propId;
-    propId2 = propId;
-    if (propId == CSSPropertyBackgroundPosition) {
-        propId1 = CSSPropertyBackgroundPositionX;
-        propId2 = CSSPropertyBackgroundPositionY;
-    } else if (propId == CSSPropertyWebkitMaskPosition) {
-        propId1 = CSSPropertyWebkitMaskPositionX;
-        propId2 = CSSPropertyWebkitMaskPositionY;
-    } else if (propId == CSSPropertyBackgroundRepeat) {
-        propId1 = CSSPropertyBackgroundRepeatX;
-        propId2 = CSSPropertyBackgroundRepeatY;
-    } else if (propId == CSSPropertyWebkitMaskRepeat) {
-        propId1 = CSSPropertyWebkitMaskRepeatX;
-        propId2 = CSSPropertyWebkitMaskRepeatY;
-    }
-
-    while ((currentValue = m_valueList-&gt;current())) {
-        RefPtr&lt;CSSValue&gt; currValue;
-        RefPtr&lt;CSSValue&gt; currValue2;
-
-        if (allowComma) {
-            if (!isComma(currentValue))
-                return false;
-            m_valueList-&gt;next();
-            allowComma = false;
-        } else {
-            allowComma = true;
-            switch (propId) {
-                case CSSPropertyBackgroundColor:
-                    currValue = parseBackgroundColor();
-                    if (currValue)
-                        m_valueList-&gt;next();
-                    break;
-                case CSSPropertyBackgroundAttachment:
-                    if (currentValue-&gt;id == CSSValueScroll || currentValue-&gt;id == CSSValueFixed || currentValue-&gt;id == CSSValueLocal) {
-                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
-                        m_valueList-&gt;next();
-                    }
-                    break;
-                case CSSPropertyBackgroundImage:
-                case CSSPropertyWebkitMaskImage:
-                    if (parseFillImage(*m_valueList, currValue))
-                        m_valueList-&gt;next();
-                    break;
-                case CSSPropertyWebkitBackgroundClip:
-                case CSSPropertyWebkitBackgroundOrigin:
-                case CSSPropertyWebkitMaskClip:
-                case CSSPropertyWebkitMaskOrigin:
-                    // The first three values here are deprecated and do not apply to the version of the property that has
-                    // the -webkit- prefix removed.
-                    if (currentValue-&gt;id == CSSValueBorder || currentValue-&gt;id == CSSValuePadding || currentValue-&gt;id == CSSValueContent
-                        || currentValue-&gt;id == CSSValueBorderBox || currentValue-&gt;id == CSSValuePaddingBox || currentValue-&gt;id == CSSValueContentBox
-                        || ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip)
-                        &amp;&amp; (currentValue-&gt;id == CSSValueText || currentValue-&gt;id == CSSValueWebkitText))) {
-                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
-                        m_valueList-&gt;next();
-                    }
-                    break;
-                case CSSPropertyBackgroundClip:
-                    if (parseBackgroundClip(*currentValue, currValue))
-                        m_valueList-&gt;next();
-                    break;
-                case CSSPropertyBackgroundOrigin:
-                    if (currentValue-&gt;id == CSSValueBorderBox || currentValue-&gt;id == CSSValuePaddingBox || currentValue-&gt;id == CSSValueContentBox) {
-                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
-                        m_valueList-&gt;next();
-                    }
-                    break;
-                case CSSPropertyBackgroundPosition:
-                case CSSPropertyWebkitMaskPosition: {
-                    RefPtr&lt;CSSPrimitiveValue&gt; value1;
-                    RefPtr&lt;CSSPrimitiveValue&gt; value2;
-                    parseFillPosition(*m_valueList, value1, value2);
-                    currValue = WTFMove(value1);
-                    currValue2 = WTFMove(value2);
-                    // parseFillPosition advances the m_valueList pointer.
-                    break;
-                }
-                case CSSPropertyBackgroundPositionX:
-                case CSSPropertyWebkitMaskPositionX: {
-                    currValue = parsePositionX(*m_valueList);
-                    if (currValue)
-                        m_valueList-&gt;next();
-                    break;
-                }
-                case CSSPropertyBackgroundPositionY:
-                case CSSPropertyWebkitMaskPositionY: {
-                    currValue = parsePositionY(*m_valueList);
-                    if (currValue)
-                        m_valueList-&gt;next();
-                    break;
-                }
-                case CSSPropertyWebkitBackgroundComposite:
-                case CSSPropertyWebkitMaskComposite:
-                    if (currentValue-&gt;id &gt;= CSSValueClear &amp;&amp; currentValue-&gt;id &lt;= CSSValuePlusLighter) {
-                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
-                        m_valueList-&gt;next();
-                    }
-                    break;
-                case CSSPropertyBackgroundBlendMode:
-                    if (currentValue-&gt;id == CSSValueNormal || currentValue-&gt;id == CSSValueMultiply
-                        || currentValue-&gt;id == CSSValueScreen || currentValue-&gt;id == CSSValueOverlay || currentValue-&gt;id == CSSValueDarken
-                        || currentValue-&gt;id == CSSValueLighten ||  currentValue-&gt;id == CSSValueColorDodge || currentValue-&gt;id == CSSValueColorBurn
-                        || currentValue-&gt;id == CSSValueHardLight || currentValue-&gt;id == CSSValueSoftLight || currentValue-&gt;id == CSSValueDifference
-                        || currentValue-&gt;id == CSSValueExclusion) {
-                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
-                        m_valueList-&gt;next();
-                    }
-                    break;
-                case CSSPropertyBackgroundRepeat:
-                case CSSPropertyWebkitMaskRepeat:
-                    parseFillRepeat(currValue, currValue2);
-                    // parseFillRepeat advances the m_valueList pointer
-                    break;
-                case CSSPropertyBackgroundSize:
-                case CSSPropertyWebkitBackgroundSize:
-                case CSSPropertyWebkitMaskSize: {
-                    currValue = parseFillSize(propId, allowComma);
-                    if (currValue)
-                        m_valueList-&gt;next();
-                    break;
-                }
-                case CSSPropertyWebkitMaskSourceType: {
-                    if (currentValue-&gt;id == CSSValueAuto || currentValue-&gt;id == CSSValueAlpha || currentValue-&gt;id == CSSValueLuminance) {
-                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
-                        m_valueList-&gt;next();
-                    } else
-                        currValue = nullptr;
-                    break;
-                }
-                default:
-                    break;
-            }
-            if (!currValue)
-                return false;
-
-            if (value &amp;&amp; !values) {
-                values = CSSValueList::createCommaSeparated();
-                values-&gt;append(value.releaseNonNull());
-            }
-
-            if (value2 &amp;&amp; !values2) {
-                values2 = CSSValueList::createCommaSeparated();
-                values2-&gt;append(value2.releaseNonNull());
-            }
-
-            if (values)
-                values-&gt;append(currValue.releaseNonNull());
-            else
-                value = WTFMove(currValue);
-            if (currValue2) {
-                if (values2)
-                    values2-&gt;append(currValue2.releaseNonNull());
-                else
-                    value2 = WTFMove(currValue2);
-            }
-        }
-
-        // When parsing any fill shorthand property, we let it handle building up the lists for all
-        // properties.
-        if (inShorthand())
-            break;
-    }
-
-    if (values &amp;&amp; values-&gt;length()) {
-        retValue1 = WTFMove(values);
-        if (values2 &amp;&amp; values2-&gt;length())
-            retValue2 = WTFMove(values2);
-        return true;
-    }
-    if (value) {
-        retValue1 = WTFMove(value);
-        retValue2 = WTFMove(value2);
-        return true;
-    }
-    return false;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationDelay()
-{
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-    if (validateUnit(valueWithCalculation, FTime))
-        return createPrimitiveNumericValue(valueWithCalculation);
-    return nullptr;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationDirection()
-{
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (value-&gt;id == CSSValueNormal || value-&gt;id == CSSValueAlternate || value-&gt;id == CSSValueReverse || value-&gt;id == CSSValueAlternateReverse)
-        return CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-    return nullptr;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationDuration()
-{
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-    if (validateUnit(valueWithCalculation, FTime | FNonNeg))
-        return createPrimitiveNumericValue(valueWithCalculation);
-    return nullptr;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationFillMode()
-{
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (value-&gt;id == CSSValueNone || value-&gt;id == CSSValueForwards || value-&gt;id == CSSValueBackwards || value-&gt;id == CSSValueBoth)
-        return CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-    return nullptr;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationIterationCount()
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    if (value.id == CSSValueInfinite)
-        return CSSValuePool::singleton().createIdentifierValue(value.id);
-    ValueWithCalculation valueWithCalculation(value);
-    if (validateUnit(valueWithCalculation, FNumber | FNonNeg))
-        return createPrimitiveNumericValue(valueWithCalculation);
-    return nullptr;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationName()
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    if (value.unit == CSSPrimitiveValue::CSS_STRING || value.unit == CSSPrimitiveValue::CSS_IDENT) {
-        if (value.id == CSSValueNone || (value.unit == CSSPrimitiveValue::CSS_STRING &amp;&amp; equalLettersIgnoringASCIICase(value, &quot;none&quot;))) {
-            return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
-        }
-        return createPrimitiveStringValue(value);
-    }
-    return nullptr;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationPlayState()
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    if (value.id == CSSValueRunning || value.id == CSSValuePaused)
-        return CSSValuePool::singleton().createIdentifierValue(value.id);
-    return nullptr;
-}
-
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
-RefPtr&lt;CSSValue&gt; CSSParser::parseAnimationTrigger()
-{
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (value-&gt;id == CSSValueAuto)
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
-
-    if (value-&gt;unit != CSSParserValue::Function)
-        return nullptr;
-
-    CSSParserValueList* args = value-&gt;function-&gt;args.get();
-
-    if (equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;container-scroll(&quot;)) {
-        if (!args || (args-&gt;size() != 1 &amp;&amp; args-&gt;size() != 3))
-            return nullptr;
-
-        CSSParserValue* argument = args-&gt;current();
-        ValueWithCalculation firstArgumentWithCalculation(*argument);
-        if (!validateUnit(firstArgumentWithCalculation, FLength))
-            return nullptr;
-
-        auto startValue = createPrimitiveNumericValue(firstArgumentWithCalculation);
-
-        argument = args-&gt;next();
-
-        if (!argument)
-            return CSSAnimationTriggerScrollValue::create(WTFMove(startValue));
-
-        if (!isComma(argument))
-            return nullptr;
-
-        argument = args-&gt;next();
-        ValueWithCalculation secondArgumentWithCalculation(*argument);
-        if (!validateUnit(secondArgumentWithCalculation, FLength))
-            return nullptr;
-
-        auto endValue = createPrimitiveNumericValue(secondArgumentWithCalculation);
-
-        return CSSAnimationTriggerScrollValue::create(WTFMove(startValue), WTFMove(endValue));
-    }
-
-    return nullptr;
-}
-#endif
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationProperty(AnimationParseContext&amp; context)
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    if (value.unit != CSSPrimitiveValue::CSS_IDENT)
-        return nullptr;
-    CSSPropertyID result = cssPropertyID(value.string);
-    if (result &amp;&amp; result != CSSPropertyAll) // &quot;all&quot; value in animation is not equivalent to the all property.
-        return CSSValuePool::singleton().createIdentifierValue(result);
-    if (equalLettersIgnoringASCIICase(value, &quot;all&quot;)) {
-        context.sawAnimationPropertyKeyword();
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueAll);
-    }
-    if (equalLettersIgnoringASCIICase(value, &quot;none&quot;)) {
-        context.commitAnimationPropertyKeyword();
-        context.sawAnimationPropertyKeyword();
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
-    }
-    return nullptr;
-}
-
-/* static */
-Vector&lt;double&gt; CSSParser::parseKeyframeSelector(const String&amp; selector) {
-    Vector&lt;double&gt; keys;
-    Vector&lt;String&gt; strings;
-    selector.split(',', strings);
-
-    keys.reserveInitialCapacity(strings.size());
-    for (size_t i = 0; i &lt; strings.size(); ++i) {
-        double key = -1;
-        String cur = strings[i].stripWhiteSpace();
-
-        // For now the syntax MUST be 'xxx%' or 'from' or 'to', where xxx is a legal floating point number
-        if (equalLettersIgnoringASCIICase(cur, &quot;from&quot;))
-            key = 0;
-        else if (equalLettersIgnoringASCIICase(cur, &quot;to&quot;))
-            key = 1;
-        else if (cur.endsWith('%')) {
-            double k = cur.substring(0, cur.length() - 1).toDouble();
-            if (k &gt;= 0 &amp;&amp; k &lt;= 100)
-                key = k / 100;
-        }
-        if (key &lt; 0) {
-            keys.clear();
-            break;
-        }
-        keys.uncheckedAppend(key);
-    }
-
-    return keys;
-}
-
-bool CSSParser::parseTransformOriginShorthand(RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2, RefPtr&lt;CSSValue&gt;&amp; value3)
-{
-    parse2ValuesFillPosition(*m_valueList, value1, value2);
-
-    // now get z
-    if (m_valueList-&gt;current()) {
-        ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-        if (validateUnit(valueWithCalculation, FLength)) {
-            value3 = createPrimitiveNumericValue(valueWithCalculation);
-            m_valueList-&gt;next();
-            return true;
-        }
-        return false;
-    }
-    value3 = CSSValuePool::singleton().createImplicitInitialValue();
-    return true;
-}
-
-bool CSSParser::isSpringTimingFunctionEnabled() const
-{
-    return m_context.springTimingFunctionEnabled;
-}
-
-Optional&lt;double&gt; CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList&amp; args)
-{
-    ValueWithCalculation argumentWithCalculation(*args.current());
-    if (!validateUnit(argumentWithCalculation, FNumber))
-        return Nullopt;
-    Optional&lt;double&gt; result = parsedDouble(argumentWithCalculation);
-    CSSParserValue* nextValue = args.next();
-    if (!nextValue) {
-        // The last number in the function has no comma after it, so we're done.
-        return result;
-    }
-    if (!isComma(nextValue))
-        return Nullopt;
-    args.next();
-    return result;
-}
-
-Optional&lt;double&gt; CSSParser::parseSpringTimingFunctionValue(CSSParserValueList&amp; args)
-{
-    ValueWithCalculation argumentWithCalculation(*args.current());
-    if (!validateUnit(argumentWithCalculation, FNumber))
-        return Nullopt;
-    Optional&lt;double&gt; result = parsedDouble(argumentWithCalculation);
-    args.next();
-    return result;
-}
-
-RefPtr&lt;CSSValue&gt; CSSParser::parseAnimationTimingFunction()
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    if (value.id == CSSValueEase || value.id == CSSValueLinear || value.id == CSSValueEaseIn || value.id == CSSValueEaseOut
-        || value.id == CSSValueEaseInOut || value.id == CSSValueStepStart || value.id == CSSValueStepEnd)
-        return CSSValuePool::singleton().createIdentifierValue(value.id);
-
-    // We must be a function.
-    if (value.unit != CSSParserValue::Function)
-        return nullptr;
-
-    CSSParserValueList* args = value.function-&gt;args.get();
-
-    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;steps(&quot;)) {
-        // For steps, 1 or 2 params must be specified (comma-separated)
-        if (!args || (args-&gt;size() != 1 &amp;&amp; args-&gt;size() != 3))
-            return nullptr;
-
-        // There are two values.
-        int numSteps;
-        bool stepAtStart = false;
-
-        CSSParserValue* argument = args-&gt;current();
-        ValueWithCalculation argumentWithCalculation(*argument);
-        if (!validateUnit(argumentWithCalculation, FInteger))
-            return nullptr;
-        numSteps = clampToInteger(parsedDouble(argumentWithCalculation));
-        if (numSteps &lt; 1)
-            return nullptr;
-        argument = args-&gt;next();
-
-        if (argument) {
-            // There is a comma so we need to parse the second value
-            if (!isComma(argument))
-                return nullptr;
-            argument = args-&gt;next();
-            if (argument-&gt;id != CSSValueStart &amp;&amp; argument-&gt;id != CSSValueEnd)
-                return nullptr;
-            stepAtStart = argument-&gt;id == CSSValueStart;
-        }
-
-        return CSSStepsTimingFunctionValue::create(numSteps, stepAtStart);
-    }
-
-    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;cubic-bezier(&quot;)) {
-        // For cubic bezier, 4 values must be specified (comma-separated).
-        if (!args || args-&gt;size() != 7)
-            return nullptr;
-
-        // There are two points specified. The x values must be between 0 and 1 but the y values can exceed this range.
-
-        auto x1 = parseCubicBezierTimingFunctionValue(*args);
-        if (!x1 || x1.value() &lt; 0 || x1.value() &gt; 1)
-            return nullptr;
-
-        auto y1 = parseCubicBezierTimingFunctionValue(*args);
-        if (!y1)
-            return nullptr;
-
-        auto x2 = parseCubicBezierTimingFunctionValue(*args);
-        if (!x2 || x2.value() &lt; 0 || x2.value() &gt; 1)
-            return nullptr;
-
-        auto y2 = parseCubicBezierTimingFunctionValue(*args);
-        if (!y2)
-            return nullptr;
-
-        return CSSCubicBezierTimingFunctionValue::create(x1.value(), y1.value(), x2.value(), y2.value());
-    }
-
-    if (isSpringTimingFunctionEnabled() &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;spring(&quot;)) {
-        // For a spring, 4 values must be specified (space-separated).
-        // FIXME: Make the arguments all optional.
-        if (!args || args-&gt;size() != 4)
-            return nullptr;
-        
-        // Mass must be greater than 0.
-        auto mass = parseSpringTimingFunctionValue(*args);
-        if (!mass || mass.value() &lt;= 0)
-            return nullptr;
-
-        // Stiffness must be greater than 0.
-        auto stiffness = parseSpringTimingFunctionValue(*args);
-        if (!stiffness || stiffness.value() &lt;= 0)
-            return nullptr;
-
-        // Damping coefficient must be greater than or equal to 0.
-        auto damping = parseSpringTimingFunctionValue(*args);
-        if (!damping || damping.value() &lt; 0)
-            return nullptr;
-
-        // Initial velocity may have any value.
-        auto initialVelocity = parseSpringTimingFunctionValue(*args);
-        if (!initialVelocity)
-            return nullptr;
-
-        return CSSSpringTimingFunctionValue::create(mass.value(), stiffness.value(), damping.value(), initialVelocity.value());
-    }
-
-    return nullptr;
-}
-
-bool CSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp; result, AnimationParseContext&amp; context)
-{
-    RefPtr&lt;CSSValueList&gt; values;
-    CSSParserValue* val;
-    RefPtr&lt;CSSValue&gt; value;
-    bool allowComma = false;
-
-    result = nullptr;
-
-    while ((val = m_valueList-&gt;current())) {
-        RefPtr&lt;CSSValue&gt; currValue;
-        if (allowComma) {
-            if (!isComma(val))
-                return false;
-            m_valueList-&gt;next();
-            allowComma = false;
-        }
-        else {
-            switch (propId) {
-            case CSSPropertyAnimationDelay:
-            case CSSPropertyWebkitAnimationDelay:
-            case CSSPropertyTransitionDelay:
-            case CSSPropertyWebkitTransitionDelay:
-                currValue = parseAnimationDelay();
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-            case CSSPropertyAnimationDirection:
-            case CSSPropertyWebkitAnimationDirection:
-                currValue = parseAnimationDirection();
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-            case CSSPropertyAnimationDuration:
-            case CSSPropertyWebkitAnimationDuration:
-            case CSSPropertyTransitionDuration:
-            case CSSPropertyWebkitTransitionDuration:
-                currValue = parseAnimationDuration();
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-            case CSSPropertyAnimationFillMode:
-            case CSSPropertyWebkitAnimationFillMode:
-                currValue = parseAnimationFillMode();
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-            case CSSPropertyAnimationIterationCount:
-            case CSSPropertyWebkitAnimationIterationCount:
-                currValue = parseAnimationIterationCount();
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-            case CSSPropertyAnimationName:
-            case CSSPropertyWebkitAnimationName:
-                currValue = parseAnimationName();
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-            case CSSPropertyAnimationPlayState:
-            case CSSPropertyWebkitAnimationPlayState:
-                currValue = parseAnimationPlayState();
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-            case CSSPropertyTransitionProperty:
-            case CSSPropertyWebkitTransitionProperty:
-                currValue = parseAnimationProperty(context);
-                if (value &amp;&amp; !context.animationPropertyKeywordAllowed())
-                    return false;
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-            case CSSPropertyAnimationTimingFunction:
-            case CSSPropertyWebkitAnimationTimingFunction:
-            case CSSPropertyTransitionTimingFunction:
-            case CSSPropertyWebkitTransitionTimingFunction:
-                currValue = parseAnimationTimingFunction();
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
-            case CSSPropertyWebkitAnimationTrigger:
-                currValue = parseAnimationTrigger();
-                if (currValue)
-                    m_valueList-&gt;next();
-                break;
-#endif
-            default:
-                ASSERT_NOT_REACHED();
-                return false;
-            }
-
-            if (!currValue)
-                return false;
-
-            if (value &amp;&amp; !values) {
-                values = CSSValueList::createCommaSeparated();
-                values-&gt;append(value.releaseNonNull());
-            }
-
-            if (values)
-                values-&gt;append(currValue.releaseNonNull());
-            else
-                value = WTFMove(currValue);
-
-            allowComma = true;
-        }
-
-        // When parsing the 'transition' shorthand property, we let it handle building up the lists for all
-        // properties.
-        if (inShorthand())
-            break;
-    }
-
-    if (values &amp;&amp; values-&gt;length()) {
-        result = WTFMove(values);
-        return true;
-    }
-    if (value) {
-        result = WTFMove(value);
-        return true;
-    }
-    return false;
-}
-
-#if ENABLE(CSS_GRID_LAYOUT)
-static inline bool isValidGridPositionCustomIdent(const CSSParserValue&amp; value)
-{
-    return value.unit == CSSPrimitiveValue::CSS_IDENT &amp;&amp; value.id != CSSValueSpan &amp;&amp; value.id != CSSValueAuto;
-}
-
-// The function parses [ &lt;integer&gt; || &lt;custom-ident&gt; ] in &lt;grid-line&gt; (which can be stand alone or with 'span').
-bool CSSParser::parseIntegerOrCustomIdentFromGridPosition(RefPtr&lt;CSSPrimitiveValue&gt;&amp; numericValue, RefPtr&lt;CSSPrimitiveValue&gt;&amp; gridLineName)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-    if (validateUnit(valueWithCalculation, FInteger) &amp;&amp; valueWithCalculation.value().fValue) {
-        numericValue = createPrimitiveNumericValue(valueWithCalculation);
-        CSSParserValue* nextValue = m_valueList-&gt;next();
-        if (nextValue &amp;&amp; isValidGridPositionCustomIdent(*nextValue)) {
-            gridLineName = createPrimitiveStringValue(*nextValue);
-            m_valueList-&gt;next();
-        }
-        return true;
-    }
-
-    if (isValidGridPositionCustomIdent(valueWithCalculation)) {
-        gridLineName = createPrimitiveStringValue(valueWithCalculation);
-        if (CSSParserValue* nextValue = m_valueList-&gt;next()) {
-            ValueWithCalculation nextValueWithCalculation(*nextValue);
-            if (validateUnit(nextValueWithCalculation, FInteger) &amp;&amp; nextValueWithCalculation.value().fValue) {
-                numericValue = createPrimitiveNumericValue(nextValueWithCalculation);
-                m_valueList-&gt;next();
-            }
-        }
-        return true;
-    }
-
-    return false;
-}
-
-RefPtr&lt;CSSValue&gt; CSSParser::parseGridPosition()
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (value-&gt;id == CSSValueAuto) {
-        m_valueList-&gt;next();
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
-    }
-
-    RefPtr&lt;CSSPrimitiveValue&gt; numericValue;
-    RefPtr&lt;CSSPrimitiveValue&gt; gridLineName;
-    bool hasSeenSpanKeyword = false;
-
-    if (value-&gt;id == CSSValueSpan) {
-        hasSeenSpanKeyword = true;
-        if (auto* nextValue = m_valueList-&gt;next()) {
-            if (!isForwardSlashOperator(*nextValue) &amp;&amp; !parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName))
-                return nullptr;
-        }
-    } else if (parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName)) {
-        value = m_valueList-&gt;current();
-        if (value &amp;&amp; value-&gt;id == CSSValueSpan) {
-            hasSeenSpanKeyword = true;
-            m_valueList-&gt;next();
-        }
-    }
-
-    // Check that we have consumed all the value list. For shorthands, the parser will pass
-    // the whole value list (including the opposite position).
-    if (m_valueList-&gt;current() &amp;&amp; !isForwardSlashOperator(*m_valueList-&gt;current()))
-        return nullptr;
-
-    // If we didn't parse anything, this is not a valid grid position.
-    if (!hasSeenSpanKeyword &amp;&amp; !gridLineName &amp;&amp; !numericValue)
-        return nullptr;
-
-    // If we have &quot;span&quot; keyword alone is invalid.
-    if (hasSeenSpanKeyword &amp;&amp; !gridLineName &amp;&amp; !numericValue)
-        return nullptr;
-
-    // Negative numbers are not allowed for span (but are for &lt;integer&gt;).
-    if (hasSeenSpanKeyword &amp;&amp; numericValue &amp;&amp; numericValue-&gt;getIntValue() &lt; 0)
-        return nullptr;
-
-    // For the &lt;custom-ident&gt; case.
-    if (gridLineName &amp;&amp; !numericValue &amp;&amp; !hasSeenSpanKeyword)
-        return CSSValuePool::singleton().createValue(gridLineName-&gt;getStringValue(), CSSPrimitiveValue::CSS_STRING);
-
-    auto values = CSSValueList::createSpaceSeparated();
-    if (hasSeenSpanKeyword)
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueSpan));
-    if (numericValue)
-        values-&gt;append(numericValue.releaseNonNull());
-    if (gridLineName)
-        values-&gt;append(gridLineName.releaseNonNull());
-    ASSERT(values-&gt;length());
-    return WTFMove(values);
-}
-
-static Ref&lt;CSSValue&gt; gridMissingGridPositionValue(CSSValue&amp; value)
-{
-    if (is&lt;CSSPrimitiveValue&gt;(value) &amp;&amp; downcast&lt;CSSPrimitiveValue&gt;(value).isString())
-        return value;
-
-    return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
-}
-
-bool CSSParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool important)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    ShorthandScope scope(this, shorthandId);
-    const StylePropertyShorthand&amp; shorthand = shorthandForProperty(shorthandId);
-    ASSERT(shorthand.length() == 2);
-
-    RefPtr&lt;CSSValue&gt; startValue = parseGridPosition();
-    if (!startValue)
-        return false;
-
-    RefPtr&lt;CSSValue&gt; endValue;
-    if (m_valueList-&gt;current()) {
-        if (!isForwardSlashOperator(*m_valueList-&gt;current()))
-            return false;
-
-        if (!m_valueList-&gt;next())
-            return false;
-
-        endValue = parseGridPosition();
-        if (!endValue || m_valueList-&gt;current())
-            return false;
-    } else
-        endValue = gridMissingGridPositionValue(*startValue);
-
-    addProperty(shorthand.properties()[0], startValue.releaseNonNull(), important);
-    addProperty(shorthand.properties()[1], endValue.releaseNonNull(), important);
-    return true;
-}
-
-bool CSSParser::parseGridGapShorthand(bool important)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    ShorthandScope scope(this, CSSPropertyGridGap);
-    ASSERT(shorthandForProperty(CSSPropertyGridGap).length() == 2);
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (!value)
-        return false;
-
-    ValueWithCalculation rowValueWithCalculation(*value);
-    if (!validateUnit(rowValueWithCalculation, FLength | FNonNeg))
-        return false;
-
-    auto rowGap = createPrimitiveNumericValue(rowValueWithCalculation);
-
-    value = m_valueList-&gt;next();
-    if (!value) {
-        addProperty(CSSPropertyGridColumnGap, rowGap.copyRef(), important);
-        addProperty(CSSPropertyGridRowGap, WTFMove(rowGap), important);
-        return true;
-    }
-
-    ValueWithCalculation columnValueWithCalculation(*value);
-    if (!validateUnit(columnValueWithCalculation, FLength | FNonNeg))
-        return false;
-
-    if (m_valueList-&gt;next())
-        return false;
-
-    auto columnGap = createPrimitiveNumericValue(columnValueWithCalculation);
-
-    addProperty(CSSPropertyGridRowGap, WTFMove(rowGap), important);
-    addProperty(CSSPropertyGridColumnGap, WTFMove(columnGap), important);
-
-    return true;
-}
-
-RefPtr&lt;CSSValue&gt; CSSParser::parseGridTemplateColumns(TrackListType trackListType)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    if (!(m_valueList-&gt;current() &amp;&amp; isForwardSlashOperator(*m_valueList-&gt;current()) &amp;&amp; m_valueList-&gt;next()))
-        return nullptr;
-    if (auto columnsValue = parseGridTrackList(trackListType)) {
-        if (m_valueList-&gt;current())
-            return nullptr;
-        return columnsValue;
-    }
-
-    return nullptr;
-}
-
-bool CSSParser::parseGridTemplateRowsAndAreasAndColumns(bool important)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    // At least template-areas strings must be defined.
-    if (!m_valueList-&gt;current() || isForwardSlashOperator(*m_valueList-&gt;current()))
-        return false;
-
-    NamedGridAreaMap gridAreaMap;
-    unsigned rowCount = 0;
-    unsigned columnCount = 0;
-    bool trailingIdentWasAdded = false;
-    auto templateRows = CSSValueList::createSpaceSeparated();
-
-    while (m_valueList-&gt;current() &amp;&amp; !isForwardSlashOperator(*m_valueList-&gt;current())) {
-        // Handle leading &lt;custom-ident&gt;*.
-        if (m_valueList-&gt;current()-&gt;unit == CSSParserValue::ValueList) {
-            if (trailingIdentWasAdded) {
-                // A row's trailing ident must be concatenated with the next row's leading one.
-                parseGridLineNames(*m_valueList, templateRows, downcast&lt;CSSGridLineNamesValue&gt;(templateRows-&gt;item(templateRows-&gt;length() - 1)));
-            } else
-                parseGridLineNames(*m_valueList, templateRows);
-        }
-
-        // Handle a template-area's row.
-        if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
-            return false;
-        ++rowCount;
-
-        // Handle template-rows's track-size.
-        if (m_valueList-&gt;current() &amp;&amp; m_valueList-&gt;current()-&gt;unit != CSSParserValue::Operator &amp;&amp; m_valueList-&gt;current()-&gt;unit != CSSParserValue::ValueList &amp;&amp; m_valueList-&gt;current()-&gt;unit != CSSPrimitiveValue::CSS_STRING) {
-            RefPtr&lt;CSSValue&gt; value = parseGridTrackSize(*m_valueList);
-            if (!value)
-                return false;
-            templateRows-&gt;append(value.releaseNonNull());
-        } else
-            templateRows-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueAuto));
-
-        // This will handle the trailing/leading &lt;custom-ident&gt;* in the grammar.
-        trailingIdentWasAdded = false;
-        if (m_valueList-&gt;current() &amp;&amp; m_valueList-&gt;current()-&gt;unit == CSSParserValue::ValueList)
-            trailingIdentWasAdded = parseGridLineNames(*m_valueList, templateRows);
-    }
-
-    // [/ &lt;explicit-track-list&gt; ]?
-    RefPtr&lt;CSSValue&gt; templateColumns;
-    if (m_valueList-&gt;current()) {
-        ASSERT(isForwardSlashOperator(*m_valueList-&gt;current()));
-        templateColumns = parseGridTemplateColumns(GridTemplateNoRepeat);
-        if (!templateColumns)
-            return false;
-        // The template-columns &lt;track-list&gt; can't be 'none'.
-        if (templateColumns-&gt;isPrimitiveValue() &amp;&amp; downcast&lt;CSSPrimitiveValue&gt;(*templateColumns).getValueID() == CSSValueNone)
-            return false;
-    }
-
-    addProperty(CSSPropertyGridTemplateRows, WTFMove(templateRows), important);
-    if (templateColumns)
-        addProperty(CSSPropertyGridTemplateColumns, templateColumns.releaseNonNull(), important);
-    else
-        addProperty(CSSPropertyGridTemplateColumns, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-    addProperty(CSSPropertyGridTemplateAreas, CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount), important);
-
-    return true;
-}
-
-bool CSSParser::parseGridTemplateShorthand(bool important)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    ShorthandScope scope(this, CSSPropertyGridTemplate);
-    ASSERT(shorthandForProperty(CSSPropertyGridTemplate).length() == 3);
-
-    // At least &quot;none&quot; must be defined.
-    if (!m_valueList-&gt;current())
-        return false;
-
-    bool firstValueIsNone = m_valueList-&gt;current()-&gt;id == CSSValueNone;
-
-    // 1- 'none' case.
-    if (firstValueIsNone &amp;&amp; !m_valueList-&gt;next()) {
-        addProperty(CSSPropertyGridTemplateColumns, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-        addProperty(CSSPropertyGridTemplateRows, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-        addProperty(CSSPropertyGridTemplateAreas, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-        return true;
-    }
-
-    // 2- &lt;grid-template-rows&gt; / &lt;grid-template-columns&gt; syntax.
-    RefPtr&lt;CSSValue&gt; rowsValue;
-    if (firstValueIsNone)
-        rowsValue = CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
-    else
-        rowsValue = parseGridTrackList(GridTemplate);
-
-    if (rowsValue) {
-        auto columnsValue = parseGridTemplateColumns();
-        if (!columnsValue)
-            return false;
-
-        addProperty(CSSPropertyGridTemplateColumns, columnsValue.releaseNonNull(), important);
-        addProperty(CSSPropertyGridTemplateRows, rowsValue.releaseNonNull(), important);
-        addProperty(CSSPropertyGridTemplateAreas, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-        return true;
-    }
-
-
-    // 3- [&lt;line-names&gt;? &lt;string&gt; &lt;track-size&gt;? &lt;line-names&gt;? ]+ syntax.
-    // It requires to rewind parsing due to previous syntax failures.
-    m_valueList-&gt;setCurrentIndex(0);
-    return parseGridTemplateRowsAndAreasAndColumns(important);
-}
-
-bool CSSParser::parseGridShorthand(bool important)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    ShorthandScope scope(this, CSSPropertyGrid);
-    ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 8);
-
-    // 1- &lt;grid-template&gt;
-    if (parseGridTemplateShorthand(important)) {
-        // It can only be specified the explicit or the implicit grid properties in a single grid declaration.
-        // The sub-properties not specified are set to their initial value, as normal for shorthands.
-        addProperty(CSSPropertyGridAutoFlow, CSSValuePool::singleton().createImplicitInitialValue(), important);
-        addProperty(CSSPropertyGridAutoColumns, CSSValuePool::singleton().createImplicitInitialValue(), important);
-        addProperty(CSSPropertyGridAutoRows, CSSValuePool::singleton().createImplicitInitialValue(), important);
-        addProperty(CSSPropertyGridColumnGap, CSSValuePool::singleton().createImplicitInitialValue(), important);
-        addProperty(CSSPropertyGridRowGap, CSSValuePool::singleton().createImplicitInitialValue(), important);
-        return true;
-    }
-
-    // Need to rewind parsing to explore the alternative syntax of this shorthand.
-    m_valueList-&gt;setCurrentIndex(0);
-
-    // 2- &lt;grid-auto-flow&gt; [ &lt;grid-auto-columns&gt; [ / &lt;grid-auto-rows&gt; ]? ]
-    if (!parseValue(CSSPropertyGridAutoFlow, important))
-        return false;
-
-    RefPtr&lt;CSSValue&gt; autoColumnsValue;
-    RefPtr&lt;CSSValue&gt; autoRowsValue;
-
-    if (m_valueList-&gt;current()) {
-        autoRowsValue = parseGridTrackList(GridAuto);
-        if (!autoRowsValue)
-            return false;
-        if (m_valueList-&gt;current()) {
-            if (!isForwardSlashOperator(*m_valueList-&gt;current()) || !m_valueList-&gt;next())
-                return false;
-            autoColumnsValue = parseGridTrackList(GridAuto);
-            if (!autoColumnsValue)
-                return false;
-        }
-        if (m_valueList-&gt;current())
-            return false;
-    } else {
-        // Other omitted values are set to their initial values.
-        autoColumnsValue = CSSValuePool::singleton().createImplicitInitialValue();
-        autoRowsValue = CSSValuePool::singleton().createImplicitInitialValue();
-    }
-
-    // if &lt;grid-auto-rows&gt; value is omitted, it is set to the value specified for grid-auto-columns.
-    if (!autoColumnsValue)
-        autoColumnsValue = autoRowsValue;
-
-    addProperty(CSSPropertyGridAutoColumns, autoColumnsValue.releaseNonNull(), important);
-    addProperty(CSSPropertyGridAutoRows, autoRowsValue.releaseNonNull(), important);
-
-    // It can only be specified the explicit or the implicit grid properties in a single grid declaration.
-    // The sub-properties not specified are set to their initial value, as normal for shorthands.
-    addProperty(CSSPropertyGridTemplateColumns, CSSValuePool::singleton().createImplicitInitialValue(), important);
-    addProperty(CSSPropertyGridTemplateRows, CSSValuePool::singleton().createImplicitInitialValue(), important);
-    addProperty(CSSPropertyGridTemplateAreas, CSSValuePool::singleton().createImplicitInitialValue(), important);
-    addProperty(CSSPropertyGridColumnGap, CSSValuePool::singleton().createImplicitInitialValue(), important);
-    addProperty(CSSPropertyGridRowGap, CSSValuePool::singleton().createImplicitInitialValue(), important);
-
-    return true;
-}
-
-bool CSSParser::parseGridAreaShorthand(bool important)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    ShorthandScope scope(this, CSSPropertyGridArea);
-    ASSERT(shorthandForProperty(CSSPropertyGridArea).length() == 4);
-
-    RefPtr&lt;CSSValue&gt; rowStartValue = parseGridPosition();
-    if (!rowStartValue)
-        return false;
-
-    RefPtr&lt;CSSValue&gt; columnStartValue;
-    if (!parseSingleGridAreaLonghand(columnStartValue))
-        return false;
-
-    RefPtr&lt;CSSValue&gt; rowEndValue;
-    if (!parseSingleGridAreaLonghand(rowEndValue))
-        return false;
-
-    RefPtr&lt;CSSValue&gt; columnEndValue;
-    if (!parseSingleGridAreaLonghand(columnEndValue))
-        return false;
-
-    if (!columnStartValue)
-        columnStartValue = gridMissingGridPositionValue(*rowStartValue);
-
-    if (!rowEndValue)
-        rowEndValue = gridMissingGridPositionValue(*rowStartValue);
-
-    if (!columnEndValue)
-        columnEndValue = gridMissingGridPositionValue(*columnStartValue);
-
-    addProperty(CSSPropertyGridRowStart, rowStartValue.releaseNonNull(), important);
-    addProperty(CSSPropertyGridColumnStart, columnStartValue.releaseNonNull(), important);
-    addProperty(CSSPropertyGridRowEnd, rowEndValue.releaseNonNull(), important);
-    addProperty(CSSPropertyGridColumnEnd, columnEndValue.releaseNonNull(), important);
-    return true;
-}
-
-bool CSSParser::parseSingleGridAreaLonghand(RefPtr&lt;CSSValue&gt;&amp; property)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    if (!m_valueList-&gt;current())
-        return true;
-
-    if (!isForwardSlashOperator(*m_valueList-&gt;current()))
-        return false;
-
-    if (!m_valueList-&gt;next())
-        return false;
-
-    property = parseGridPosition();
-    return true;
-}
-
-bool CSSParser::parseGridLineNames(CSSParserValueList&amp; inputList, CSSValueList&amp; valueList, CSSGridLineNamesValue* previousNamedAreaTrailingLineNames)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-    ASSERT(inputList.current() &amp;&amp; inputList.current()-&gt;unit == CSSParserValue::ValueList);
-
-    CSSParserValueList&amp; identList = *inputList.current()-&gt;valueList;
-    if (!identList.size()) {
-        inputList.next();
-        return false;
-    }
-
-    // Need to ensure the identList is at the heading index, since the parserList might have been rewound.
-    identList.setCurrentIndex(0);
-    Ref&lt;CSSGridLineNamesValue&gt; lineNames = previousNamedAreaTrailingLineNames ? Ref&lt;CSSGridLineNamesValue&gt;(*previousNamedAreaTrailingLineNames) : CSSGridLineNamesValue::create();
-    while (CSSParserValue* identValue = identList.current()) {
-        ASSERT(identValue-&gt;unit == CSSPrimitiveValue::CSS_IDENT);
-        lineNames-&gt;append(createPrimitiveStringValue(*identValue));
-        identList.next();
-    }
-    if (!previousNamedAreaTrailingLineNames)
-        valueList.append(WTFMove(lineNames));
-
-    inputList.next();
-    return true;
-}
-
-static bool isGridTrackFixedSized(const CSSPrimitiveValue&amp; value)
-{
-    CSSValueID valueID = value.getValueID();
-    if (valueID == CSSValueWebkitMinContent || valueID == CSSValueWebkitMaxContent || valueID == CSSValueAuto || value.isFlex())
-        return false;
-
-    ASSERT(value.isLength() || value.isPercentage() || value.isCalculated());
-    return true;
-}
-
-static bool isGridTrackFixedSized(const CSSValue&amp; value)
-{
-    if (value.isPrimitiveValue())
-        return isGridTrackFixedSized(downcast&lt;CSSPrimitiveValue&gt;(value));
-
-    ASSERT(value.isFunctionValue());
-    ASSERT(downcast&lt;CSSFunctionValue&gt;(value).arguments());
-    ASSERT(downcast&lt;CSSFunctionValue&gt;(value).arguments()-&gt;length() == 2);
-
-    auto&amp; min = downcast&lt;CSSPrimitiveValue&gt;(*downcast&lt;CSSFunctionValue&gt;(value).arguments()-&gt;item(0));
-    auto&amp; max = downcast&lt;CSSPrimitiveValue&gt;(*downcast&lt;CSSFunctionValue&gt;(value).arguments()-&gt;item(1));
-    return isGridTrackFixedSized(min) || isGridTrackFixedSized(max);
-}
-
-RefPtr&lt;CSSValue&gt; CSSParser::parseGridTrackList(TrackListType trackListType)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (value-&gt;id == CSSValueNone) {
-        if (trackListType == GridAuto)
-            return nullptr;
-        m_valueList-&gt;next();
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
-    }
-
-    auto values = CSSValueList::createSpaceSeparated();
-    // Handle leading  &lt;custom-ident&gt;*.
-    value = m_valueList-&gt;current();
-    bool allowGridLineNames = trackListType != GridAuto;
-    if (value &amp;&amp; value-&gt;unit == CSSParserValue::ValueList) {
-        if (!allowGridLineNames)
-            return nullptr;
-        parseGridLineNames(*m_valueList, values);
-    }
-
-    bool seenTrackSizeOrRepeatFunction = false;
-    bool seenAutoRepeat = false;
-    bool allTracksAreFixedSized = true;
-    bool repeatAllowed = trackListType == GridTemplate;
-    while (CSSParserValue* currentValue = m_valueList-&gt;current()) {
-        if (isForwardSlashOperator(*currentValue))
-            break;
-        if (currentValue-&gt;unit == CSSParserValue::Function &amp;&amp; equalLettersIgnoringASCIICase(currentValue-&gt;function-&gt;name, &quot;repeat(&quot;)) {
-            if (!repeatAllowed)
-                return nullptr;
-            bool isAutoRepeat;
-            if (!parseGridTrackRepeatFunction(values, isAutoRepeat, allTracksAreFixedSized))
-                return nullptr;
-            if (isAutoRepeat &amp;&amp; seenAutoRepeat)
-                return nullptr;
-            seenAutoRepeat = seenAutoRepeat || isAutoRepeat;
-        } else {
-            RefPtr&lt;CSSValue&gt; value = parseGridTrackSize(*m_valueList);
-            if (!value)
-                return nullptr;
-
-            allTracksAreFixedSized = allTracksAreFixedSized &amp;&amp; isGridTrackFixedSized(*value);
-            values-&gt;append(value.releaseNonNull());
-        }
-        seenTrackSizeOrRepeatFunction = true;
-
-        if (seenAutoRepeat &amp;&amp; !allTracksAreFixedSized)
-            return nullptr;
-
-        // This will handle the trailing &lt;custom-ident&gt;* in the grammar.
-        value = m_valueList-&gt;current();
-        if (value &amp;&amp; value-&gt;unit == CSSParserValue::ValueList) {
-            if (!allowGridLineNames)
-                return nullptr;
-            parseGridLineNames(*m_valueList, values);
-        }
-    }
-
-    if (!seenTrackSizeOrRepeatFunction)
-        return nullptr;
-
-    return WTFMove(values);
-}
-
-bool CSSParser::parseGridTrackRepeatFunction(CSSValueList&amp; list, bool&amp; isAutoRepeat, bool&amp; allTracksAreFixedSized)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    CSSParserValueList* arguments = m_valueList-&gt;current()-&gt;function-&gt;args.get();
-    if (!arguments || arguments-&gt;size() &lt; 3 || !isComma(arguments-&gt;valueAt(1)))
-        return false;
-
-    ValueWithCalculation firstValueWithCalculation(*arguments-&gt;valueAt(0));
-    CSSValueID firstValueID = firstValueWithCalculation.value().id;
-    isAutoRepeat = firstValueID == CSSValueAutoFill || firstValueID == CSSValueAutoFit;
-    if (!isAutoRepeat &amp;&amp; !validateUnit(firstValueWithCalculation, FPositiveInteger))
-        return false;
-
-    // If arguments-&gt;valueAt(0)-&gt;fValue &gt; SIZE_MAX then repetitions becomes 0 during the type casting, that's why we
-    // clamp it down to kGridMaxTracks before the type casting.
-    // The number of repetitions for &lt;auto-repeat&gt; is not important at parsing level
-    // because it will be computed later, let's set it to 1.
-    unsigned repetitions = isAutoRepeat ? 1 : clampTo&lt;unsigned&gt;(parsedDouble(firstValueWithCalculation), 0, kGridMaxTracks);
-
-    Ref&lt;CSSValueList&gt; repeatedValues = isAutoRepeat ? Ref&lt;CSSValueList&gt;(CSSGridAutoRepeatValue::create(firstValueID)) : CSSValueList::createSpaceSeparated();
-    arguments-&gt;next(); // Skip the repetition count.
-    arguments-&gt;next(); // Skip the comma.
-
-    // Handle leading &lt;custom-ident&gt;*.
-    CSSParserValue* currentValue = arguments-&gt;current();
-    if (currentValue &amp;&amp; currentValue-&gt;unit == CSSParserValue::ValueList)
-        parseGridLineNames(*arguments, repeatedValues);
-
-    unsigned numberOfTracks = 0;
-    while (arguments-&gt;current()) {
-        RefPtr&lt;CSSValue&gt; trackSize = parseGridTrackSize(*arguments);
-        if (!trackSize)
-            return false;
-
-        allTracksAreFixedSized = allTracksAreFixedSized &amp;&amp; isGridTrackFixedSized(*trackSize);
-        repeatedValues-&gt;append(trackSize.releaseNonNull());
-        ++numberOfTracks;
-
-        // This takes care of any trailing &lt;custom-ident&gt;* in the grammar.
-        currentValue = arguments-&gt;current();
-        if (currentValue &amp;&amp; currentValue-&gt;unit == CSSParserValue::ValueList)
-            parseGridLineNames(*arguments, repeatedValues);
-    }
-
-    // We should have found at least one &lt;track-size&gt;, otherwise the declaration is invalid.
-    if (!numberOfTracks)
-        return false;
-
-    // We clamp the number of repetitions to a multiple of the repeat() track list's size, while staying below the max
-    // grid size.
-    repetitions = std::min(repetitions, kGridMaxTracks / numberOfTracks);
-
-    if (isAutoRepeat)
-        list.append(WTFMove(repeatedValues));
-    else {
-        for (unsigned i = 0; i &lt; repetitions; ++i) {
-            for (unsigned j = 0; j &lt; repeatedValues-&gt;length(); ++j)
-                list.append(*repeatedValues-&gt;itemWithoutBoundsCheck(j));
-        }
-    }
-
-    m_valueList-&gt;next();
-    return true;
-}
-
-RefPtr&lt;CSSValue&gt; CSSParser::parseGridTrackSize(CSSParserValueList&amp; inputList)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    CSSParserValue&amp; currentValue = *inputList.current();
-    inputList.next();
-
-    if (currentValue.id == CSSValueAuto)
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
-
-    if (currentValue.unit == CSSParserValue::Function &amp;&amp; equalLettersIgnoringASCIICase(currentValue.function-&gt;name, &quot;minmax(&quot;)) {
-        // The spec defines the following grammar: minmax( &lt;track-breadth&gt; , &lt;track-breadth&gt; )
-        CSSParserValueList* arguments = currentValue.function-&gt;args.get();
-        if (!arguments || arguments-&gt;size() != 3 || !isComma(arguments-&gt;valueAt(1)))
-            return nullptr;
-
-        RefPtr&lt;CSSPrimitiveValue&gt; minTrackBreadth = parseGridBreadth(*arguments-&gt;valueAt(0));
-        if (!minTrackBreadth || minTrackBreadth-&gt;isFlex())
-            return nullptr;
-
-        RefPtr&lt;CSSPrimitiveValue&gt; maxTrackBreadth = parseGridBreadth(*arguments-&gt;valueAt(2));
-        if (!maxTrackBreadth)
-            return nullptr;
-
-        auto parsedArguments = CSSValueList::createCommaSeparated();
-        parsedArguments-&gt;append(minTrackBreadth.releaseNonNull());
-        parsedArguments-&gt;append(maxTrackBreadth.releaseNonNull());
-        return CSSFunctionValue::create(&quot;minmax(&quot;, WTFMove(parsedArguments));
-    }
-
-    return parseGridBreadth(currentValue);
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseGridBreadth(CSSParserValue&amp; value)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    if (value.id == CSSValueWebkitMinContent || value.id == CSSValueWebkitMaxContent || value.id == CSSValueAuto)
-        return CSSValuePool::singleton().createIdentifierValue(value.id);
-
-    if (value.unit == CSSPrimitiveValue::CSS_FR) {
-        double flexValue = value.fValue;
-
-        // Fractional unit is a non-negative dimension.
-        if (flexValue &lt;= 0)
-            return nullptr;
-
-        return CSSValuePool::singleton().createValue(flexValue, CSSPrimitiveValue::CSS_FR);
-    }
-
-    ValueWithCalculation valueWithCalculation(value);
-    if (!validateUnit(valueWithCalculation, FNonNeg | FLength | FPercent))
-        return nullptr;
-
-    return createPrimitiveNumericValue(valueWithCalculation);
-}
-
-static inline bool isValidGridAutoFlowId(CSSValueID id)
-{
-    return (id == CSSValueRow || id == CSSValueColumn || id == CSSValueDense);
-}
-
-RefPtr&lt;CSSValue&gt; CSSParser::parseGridAutoFlow(CSSParserValueList&amp; inputList)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    // [ row | column ] || dense
-    CSSParserValue* value = inputList.current();
-    if (!value)
-        return nullptr;
-
-    auto parsedValues = CSSValueList::createSpaceSeparated();
-
-    // First parameter.
-    CSSValueID firstId = value-&gt;id;
-    if (!isValidGridAutoFlowId(firstId))
-        return nullptr;
-
-    // Second parameter, if any.
-    // If second parameter is not valid we should process anyway the first one as we can be inside the &quot;grid&quot; shorthand.
-    value = inputList.next();
-    if (!value || !isValidGridAutoFlowId(value-&gt;id)) {
-        if (firstId == CSSValueDense)
-            parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueRow));
-
-        parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(firstId));
-        return WTFMove(parsedValues);
-    }
-
-    switch (firstId) {
-    case CSSValueRow:
-    case CSSValueColumn:
-        parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(firstId));
-        if (value-&gt;id == CSSValueDense) {
-            parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
-            inputList.next();
-        }
-        break;
-    case CSSValueDense:
-        if (value-&gt;id == CSSValueRow || value-&gt;id == CSSValueColumn) {
-            parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
-            inputList.next();
-        }
-        parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(firstId));
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-        break;
-    }
-
-    return WTFMove(parsedValues);
-}
-#endif /* ENABLE(CSS_GRID_LAYOUT) */
-
-#if ENABLE(DASHBOARD_SUPPORT)
-
-static const int dashboardRegionParameterCount = 6;
-static const int dashboardRegionShortParameterCount = 2;
-
-static CSSParserValue* skipCommaInDashboardRegion(CSSParserValueList *args)
-{
-    if (args-&gt;size() == (dashboardRegionParameterCount * 2 - 1) || args-&gt;size() == (dashboardRegionShortParameterCount * 2 - 1)) {
-        CSSParserValue&amp; current = *args-&gt;current();
-        if (current.unit == CSSParserValue::Operator &amp;&amp; current.iValue == ',')
-            return args-&gt;next();
-    }
-    return args-&gt;current();
-}
-
-bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important)
-{
-    bool valid = true;
-
-    CSSParserValue* value = m_valueList-&gt;current();
-
-    if (value-&gt;id == CSSValueNone) {
-        if (m_valueList-&gt;next())
-            return false;
-        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
-        return valid;
-    }
-
-    auto firstRegion = DashboardRegion::create();
-    DashboardRegion* region = nullptr;
-
-    while (value) {
-        if (!region) {
-            region = firstRegion.ptr();
-        } else {
-            auto nextRegion = DashboardRegion::create();
-            region-&gt;m_next = nextRegion.copyRef();
-            region = nextRegion.ptr();
-        }
-
-        if (value-&gt;unit != CSSParserValue::Function) {
-            valid = false;
-            break;
-        }
-
-        // Commas count as values, so allow (function name is dashboard-region for DASHBOARD_SUPPORT feature):
-        // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
-        // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
-        // also allow
-        // dashboard-region(label, type) or dashboard-region(label type)
-        // dashboard-region(label, type) or dashboard-region(label type)
-        CSSParserValueList* args = value-&gt;function-&gt;args.get();
-        if (!equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;dashboard-region(&quot;) || !args) {
-            valid = false;
-            break;
-        }
-
-        int numArgs = args-&gt;size();
-        if ((numArgs != dashboardRegionParameterCount &amp;&amp; numArgs != (dashboardRegionParameterCount*2-1))
-            &amp;&amp; (numArgs != dashboardRegionShortParameterCount &amp;&amp; numArgs != (dashboardRegionShortParameterCount*2-1))) {
-            valid = false;
-            break;
-        }
-
-        // First arg is a label.
-        CSSParserValue* arg = args-&gt;current();
-        if (arg-&gt;unit != CSSPrimitiveValue::CSS_IDENT) {
-            valid = false;
-            break;
-        }
-
-        region-&gt;m_label = arg-&gt;string;
-
-        // Second arg is a type.
-        arg = args-&gt;next();
-        arg = skipCommaInDashboardRegion(args);
-        if (arg-&gt;unit != CSSPrimitiveValue::CSS_IDENT) {
-            valid = false;
-            break;
-        }
-
-        if (equalLettersIgnoringASCIICase(*arg, &quot;circle&quot;))
-            region-&gt;m_isCircle = true;
-        else if (equalLettersIgnoringASCIICase(*arg, &quot;rectangle&quot;))
-            region-&gt;m_isRectangle = true;
-        else {
-            valid = false;
-            break;
-        }
-
-        region-&gt;m_geometryType = arg-&gt;string;
-
-        if (numArgs == dashboardRegionShortParameterCount || numArgs == (dashboardRegionShortParameterCount*2-1)) {
-            // This originally used CSSValueInvalid by accident. It might be more logical to use something else.
-            RefPtr&lt;CSSPrimitiveValue&gt; amount = CSSValuePool::singleton().createIdentifierValue(CSSValueInvalid);
-
-            region-&gt;setTop(amount.copyRef());
-            region-&gt;setRight(amount.copyRef());
-            region-&gt;setBottom(amount.copyRef());
-            region-&gt;setLeft(WTFMove(amount));
-        } else {
-            // Next four arguments must be offset numbers
-            for (int i = 0; i &lt; 4; ++i) {
-                arg = args-&gt;next();
-                arg = skipCommaInDashboardRegion(args);
-
-                ValueWithCalculation argWithCalculation(*arg);
-                valid = arg-&gt;id == CSSValueAuto || validateUnit(argWithCalculation, FLength);
-                if (!valid)
-                    break;
-
-                RefPtr&lt;CSSPrimitiveValue&gt; amount = arg-&gt;id == CSSValueAuto ? CSSValuePool::singleton().createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(argWithCalculation);
-
-                if (i == 0)
-                    region-&gt;setTop(WTFMove(amount));
-                else if (i == 1)
-                    region-&gt;setRight(WTFMove(amount));
-                else if (i == 2)
-                    region-&gt;setBottom(WTFMove(amount));
-                else
-                    region-&gt;setLeft(WTFMove(amount));
-            }
-        }
-
-        if (args-&gt;next())
-            return false;
-
-        value = m_valueList-&gt;next();
-    }
-
-    if (valid)
-        addProperty(propId, CSSValuePool::singleton().createValue(RefPtr&lt;DashboardRegion&gt;(WTFMove(firstRegion))), important);
-
-    return valid;
-}
-
-#endif /* ENABLE(DASHBOARD_SUPPORT) */
-
-#if ENABLE(CSS_GRID_LAYOUT)
-static Vector&lt;String&gt; parseGridTemplateAreasColumnNames(const String&amp; gridRowNames)
-{
-    ASSERT(!gridRowNames.isEmpty());
-    Vector&lt;String&gt; columnNames;
-    // Using StringImpl to avoid checks and indirection in every call to String::operator[].
-    StringImpl&amp; text = *gridRowNames.impl();
-    unsigned length = text.length();
-    unsigned index = 0;
-    while (index &lt; length) {
-        if (text[index] != ' ' &amp;&amp; text[index] != '.') {
-            unsigned gridAreaStart = index;
-            while (index &lt; length &amp;&amp; text[index] != ' ' &amp;&amp; text[index] != '.')
-                ++index;
-            columnNames.append(text.substring(gridAreaStart, index - gridAreaStart));
-            continue;
-        }
-
-        if (text[index] == '.') {
-            while (index &lt; length &amp;&amp; text[index] == '.')
-                ++index;
-            columnNames.append(&quot;.&quot;);
-            continue;
-        }
-
-        ++index;
-    }
-
-    return columnNames;
-}
-
-bool CSSParser::parseGridTemplateAreasRow(NamedGridAreaMap&amp; gridAreaMap, const unsigned rowCount, unsigned&amp; columnCount)
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    CSSParserValue* currentValue = m_valueList-&gt;current();
-    if (!currentValue || currentValue-&gt;unit != CSSPrimitiveValue::CSS_STRING)
-        return false;
-
-    String gridRowNames = currentValue-&gt;string;
-    if (gridRowNames.containsOnlyWhitespace())
-        return false;
-
-    Vector&lt;String&gt; columnNames = parseGridTemplateAreasColumnNames(gridRowNames);
-    if (!columnCount) {
-        columnCount = columnNames.size();
-        ASSERT(columnCount);
-    } else if (columnCount != columnNames.size()) {
-        // The declaration is invalid is all the rows don't have the number of columns.
-        return false;
-    }
-
-    for (unsigned currentColumn = 0; currentColumn &lt; columnCount; ++currentColumn) {
-        const String&amp; gridAreaName = columnNames[currentColumn];
-
-        // Unamed areas are always valid (we consider them to be 1x1).
-        if (gridAreaName == &quot;.&quot;)
-            continue;
-
-        // We handle several grid areas with the same name at once to simplify the validation code.
-        unsigned lookAheadColumn;
-        for (lookAheadColumn = currentColumn + 1; lookAheadColumn &lt; columnCount; ++lookAheadColumn) {
-            if (columnNames[lookAheadColumn] != gridAreaName)
-                break;
-        }
-
-        auto gridAreaIterator = gridAreaMap.find(gridAreaName);
-        if (gridAreaIterator == gridAreaMap.end())
-            gridAreaMap.add(gridAreaName, GridArea(GridSpan::translatedDefiniteGridSpan(rowCount, rowCount + 1), GridSpan::translatedDefiniteGridSpan(currentColumn, lookAheadColumn)));
-        else {
-            GridArea&amp; gridArea = gridAreaIterator-&gt;value;
-
-            // The following checks test that the grid area is a single filled-in rectangle.
-            // 1. The new row is adjacent to the previously parsed row.
-            if (rowCount != gridArea.rows.endLine())
-                return false;
-
-            // 2. The new area starts at the same position as the previously parsed area.
-            if (currentColumn != gridArea.columns.startLine())
-                return false;
-
-            // 3. The new area ends at the same position as the previously parsed area.
-            if (lookAheadColumn != gridArea.columns.endLine())
-                return false;
-
-            gridArea.rows = GridSpan::translatedDefiniteGridSpan(gridArea.rows.startLine(), gridArea.rows.endLine() + 1);
-        }
-        currentColumn = lookAheadColumn - 1;
-    }
-
-    m_valueList-&gt;next();
-    return true;
-}
-
-RefPtr&lt;CSSValue&gt; CSSParser::parseGridTemplateAreas()
-{
-    ASSERT(isCSSGridLayoutEnabled());
-
-    if (m_valueList-&gt;current() &amp;&amp; m_valueList-&gt;current()-&gt;id == CSSValueNone) {
-        m_valueList-&gt;next();
-        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
-    }
-
-    NamedGridAreaMap gridAreaMap;
-    unsigned rowCount = 0;
-    unsigned columnCount = 0;
-
-    while (m_valueList-&gt;current()) {
-        if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
-            return nullptr;
-        ++rowCount;
-    }
-
-    if (!rowCount || !columnCount)
-        return nullptr;
-
-    return CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount);
-}
-#endif /* ENABLE(CSS_GRID_LAYOUT) */
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseCounterContent(CSSParserValueList&amp; args, bool counters)
-{
-    unsigned numArgs = args.size();
-    if (counters &amp;&amp; numArgs != 3 &amp;&amp; numArgs != 5)
-        return nullptr;
-    if (!counters &amp;&amp; numArgs != 1 &amp;&amp; numArgs != 3)
-        return nullptr;
-
-    CSSParserValue* argument = args.current();
-    if (argument-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-        return nullptr;
-    auto identifier = createPrimitiveStringValue(*argument);
-
-    RefPtr&lt;CSSPrimitiveValue&gt; separator;
-    if (!counters)
-        separator = CSSValuePool::singleton().createValue(String(), CSSPrimitiveValue::CSS_STRING);
-    else {
-        argument = args.next();
-        if (argument-&gt;unit != CSSParserValue::Operator || argument-&gt;iValue != ',')
-            return nullptr;
-
-        argument = args.next();
-        if (argument-&gt;unit != CSSPrimitiveValue::CSS_STRING)
-            return nullptr;
-
-        separator = createPrimitiveStringValue(*argument);
-    }
-
-    RefPtr&lt;CSSPrimitiveValue&gt; listStyle;
-    argument = args.next();
-    if (!argument) // Make the list style default decimal
-        listStyle = CSSValuePool::singleton().createIdentifierValue(CSSValueDecimal);
-    else {
-        if (argument-&gt;unit != CSSParserValue::Operator || argument-&gt;iValue != ',')
-            return nullptr;
-
-        argument = args.next();
-        if (argument-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-            return nullptr;
-
-        CSSValueID listStyleID = CSSValueInvalid;
-        if (argument-&gt;id == CSSValueNone || (argument-&gt;id &gt;= CSSValueDisc &amp;&amp; argument-&gt;id &lt;= CSSValueKatakanaIroha))
-            listStyleID = argument-&gt;id;
-        else
-            return nullptr;
-
-        listStyle = CSSValuePool::singleton().createIdentifierValue(listStyleID);
-    }
-
-    return CSSValuePool::singleton().createValue(Counter::create(WTFMove(identifier), listStyle.releaseNonNull(), separator.releaseNonNull()));
-}
-
-bool CSSParser::parseClipShape(CSSPropertyID propId, bool important)
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    CSSParserValueList* args = value.function-&gt;args.get();
-
-    if (!equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;rect(&quot;) || !args)
-        return false;
-
-    // rect(t, r, b, l) || rect(t r b l)
-    if (args-&gt;size() != 4 &amp;&amp; args-&gt;size() != 7)
-        return false;
-    auto rect = Rect::create();
-    bool valid = true;
-    int i = 0;
-    CSSParserValue* argument = args-&gt;current();
-    while (argument) {
-        ValueWithCalculation argumentWithCalculation(*argument);
-        valid = argument-&gt;id == CSSValueAuto || validateUnit(argumentWithCalculation, FLength);
-        if (!valid)
-            break;
-        Ref&lt;CSSPrimitiveValue&gt; length = argument-&gt;id == CSSValueAuto ? CSSValuePool::singleton().createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(argumentWithCalculation);
-        if (i == 0)
-            rect-&gt;setTop(WTFMove(length));
-        else if (i == 1)
-            rect-&gt;setRight(WTFMove(length));
-        else if (i == 2)
-            rect-&gt;setBottom(WTFMove(length));
-        else
-            rect-&gt;setLeft(WTFMove(length));
-        argument = args-&gt;next();
-        if (argument &amp;&amp; args-&gt;size() == 7) {
-            if (argument-&gt;unit == CSSParserValue::Operator &amp;&amp; argument-&gt;iValue == ',') {
-                argument = args-&gt;next();
-            } else {
-                valid = false;
-                break;
-            }
-        }
-        i++;
-    }
-    if (valid) {
-        addProperty(propId, CSSValuePool::singleton().createValue(WTFMove(rect)), important);
-        m_valueList-&gt;next();
-        return true;
-    }
-    return false;
-}
-
-static void completeBorderRadii(RefPtr&lt;CSSPrimitiveValue&gt; radii[4])
-{
-    if (radii[3])
-        return;
-    if (!radii[2]) {
-        if (!radii[1])
-            radii[1] = radii[0];
-        radii[2] = radii[0];
-    }
-    radii[3] = radii[1];
-}
-
-// FIXME: This should be refactored with CSSParser::parseBorderRadius.
-// CSSParser::parseBorderRadius contains support for some legacy radius construction.
-RefPtr&lt;CSSBasicShapeInset&gt; CSSParser::parseInsetRoundedCorners(Ref&lt;CSSBasicShapeInset&gt;&amp;&amp; shape, CSSParserValueList&amp; args)
-{
-    CSSParserValue* argument = args.next();
-
-    if (!argument)
-        return nullptr;
-
-    Vector&lt;CSSParserValue*&gt; radiusArguments;
-    while (argument) {
-        radiusArguments.append(argument);
-        argument = args.next();
-    }
-
-    unsigned num = radiusArguments.size();
-    if (!num || num &gt; 9)
-        return nullptr;
-
-    RefPtr&lt;CSSPrimitiveValue&gt; radii[2][4];
-
-    unsigned indexAfterSlash = 0;
-    for (unsigned i = 0; i &lt; num; ++i) {
-        CSSParserValue&amp; value = *radiusArguments.at(i);
-        if (value.unit == CSSParserValue::Operator) {
-            if (value.iValue != '/')
-                return nullptr;
-
-            if (!i || indexAfterSlash || i + 1 == num || num &gt; i + 5)
-                return nullptr;
-
-            indexAfterSlash = i + 1;
-            completeBorderRadii(radii[0]);
-            continue;
-        }
-
-        if (i - indexAfterSlash &gt;= 4)
-            return nullptr;
-
-        ValueWithCalculation valueWithCalculation(value);
-        if (!validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg))
-            return nullptr;
-
-        auto radius = createPrimitiveNumericValue(valueWithCalculation);
-
-        if (!indexAfterSlash)
-            radii[0][i] = WTFMove(radius);
-        else
-            radii[1][i - indexAfterSlash] = WTFMove(radius);
-    }
-
-    if (!indexAfterSlash) {
-        completeBorderRadii(radii[0]);
-        for (unsigned i = 0; i &lt; 4; ++i)
-            radii[1][i] = radii[0][i];
-    } else
-        completeBorderRadii(radii[1]);
-
-    shape-&gt;setTopLeftRadius(createPrimitiveValuePair(WTFMove(radii[0][0]), WTFMove(radii[1][0])));
-    shape-&gt;setTopRightRadius(createPrimitiveValuePair(WTFMove(radii[0][1]), WTFMove(radii[1][1])));
-    shape-&gt;setBottomRightRadius(createPrimitiveValuePair(WTFMove(radii[0][2]), WTFMove(radii[1][2])));
-    shape-&gt;setBottomLeftRadius(createPrimitiveValuePair(WTFMove(radii[0][3]), WTFMove(radii[1][3])));
-
-    return WTFMove(shape);
-}
-
-RefPtr&lt;CSSBasicShapeInset&gt; CSSParser::parseBasicShapeInset(CSSParserValueList&amp; args)
-{
-    auto shape = CSSBasicShapeInset::create();
-
-    CSSParserValue* argument = args.current();
-    Vector&lt;Ref&lt;CSSPrimitiveValue&gt; &gt; widthArguments;
-    bool hasRoundedInset = false;
-    while (argument) {
-        if (argument-&gt;unit == CSSPrimitiveValue::CSS_IDENT &amp;&amp; equalLettersIgnoringASCIICase(argument-&gt;string, &quot;round&quot;)) {
-            hasRoundedInset = true;
-            break;
-        }
-
-        Units unitFlags = FLength | FPercent;
-        ValueWithCalculation argumentWithCalculation(*argument);
-        if (!validateUnit(argumentWithCalculation, unitFlags) || widthArguments.size() &gt; 4)
-            return nullptr;
-
-        widthArguments.append(createPrimitiveNumericValue(argumentWithCalculation));
-        argument = args.next();
-    }
-
-    switch (widthArguments.size()) {
-    case 1: {
-        shape-&gt;updateShapeSize1Value(WTFMove(widthArguments[0]));
-        break;
-    }
-    case 2: {
-        shape-&gt;updateShapeSize2Values(WTFMove(widthArguments[0]), WTFMove(widthArguments[1]));
-        break;
-        }
-    case 3: {
-        shape-&gt;updateShapeSize3Values(WTFMove(widthArguments[0]), WTFMove(widthArguments[1]), WTFMove(widthArguments[2]));
-        break;
-    }
-    case 4: {
-        shape-&gt;updateShapeSize4Values(WTFMove(widthArguments[0]), WTFMove(widthArguments[1]), WTFMove(widthArguments[2]), WTFMove(widthArguments[3]));
-        break;
-    }
-    default:
-        return nullptr;
-    }
-
-    if (hasRoundedInset)
-        return parseInsetRoundedCorners(WTFMove(shape), args);
-    return WTFMove(shape);
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseShapeRadius(CSSParserValue&amp; value)
-{
-    if (value.id == CSSValueClosestSide || value.id == CSSValueFarthestSide)
-        return CSSValuePool::singleton().createIdentifierValue(value.id);
-
-    ValueWithCalculation valueWithCalculation(value);
-    if (!validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg))
-        return nullptr;
-
-    return createPrimitiveNumericValue(valueWithCalculation);
-}
-
-RefPtr&lt;CSSBasicShapeCircle&gt; CSSParser::parseBasicShapeCircle(CSSParserValueList&amp; args)
-{
-    // circle(radius)
-    // circle(radius at &lt;position&gt;)
-    // circle(at &lt;position&gt;)
-    // where position defines centerX and centerY using a CSS &lt;position&gt; data type.
-    auto shape = CSSBasicShapeCircle::create();
-
-    for (CSSParserValue* argument = args.current(); argument; argument = args.next()) {
-        // The call to parseFillPosition below should consume all of the
-        // arguments except the first two. Thus, and index greater than one
-        // indicates an invalid production.
-        if (args.currentIndex() &gt; 1)
-            return nullptr;
-
-        if (!args.currentIndex() &amp;&amp; argument-&gt;id != CSSValueAt) {
-            if (RefPtr&lt;CSSPrimitiveValue&gt; radius = parseShapeRadius(*argument)) {
-                shape-&gt;setRadius(radius.releaseNonNull());
-                continue;
-            }
-
-            return nullptr;
-        }
-
-        if (argument-&gt;id == CSSValueAt &amp;&amp; args.next()) {
-            RefPtr&lt;CSSPrimitiveValue&gt; centerX;
-            RefPtr&lt;CSSPrimitiveValue&gt; centerY;
-            parseFillPosition(args, centerX, centerY);
-            if (centerX &amp;&amp; centerY &amp;&amp; !args.current()) {
-                shape-&gt;setCenterX(centerX.releaseNonNull());
-                shape-&gt;setCenterY(centerY.releaseNonNull());
-            } else
-                return nullptr;
-        } else
-            return nullptr;
-    }
-
-    return WTFMove(shape);
-}
-
-RefPtr&lt;CSSBasicShapeEllipse&gt; CSSParser::parseBasicShapeEllipse(CSSParserValueList&amp; args)
-{
-    // ellipse(radiusX)
-    // ellipse(radiusX at &lt;position&gt;)
-    // ellipse(radiusX radiusY)
-    // ellipse(radiusX radiusY at &lt;position&gt;)
-    // ellipse(at &lt;position&gt;)
-    // where position defines centerX and centerY using a CSS &lt;position&gt; data type.
-    auto shape = CSSBasicShapeEllipse::create();
-
-    for (CSSParserValue* argument = args.current(); argument; argument = args.next()) {
-        // The call to parseFillPosition below should consume all of the
-        // arguments except the first three. Thus, an index greater than two
-        // indicates an invalid production.
-        if (args.currentIndex() &gt; 2)
-            return nullptr;
-
-        if (args.currentIndex() &lt; 2 &amp;&amp; argument-&gt;id != CSSValueAt) {
-            if (RefPtr&lt;CSSPrimitiveValue&gt; radius = parseShapeRadius(*argument)) {
-                if (!shape-&gt;radiusX())
-                    shape-&gt;setRadiusX(radius.releaseNonNull());
-                else
-                    shape-&gt;setRadiusY(radius.releaseNonNull());
-                continue;
-            }
-
-            return nullptr;
-        }
-
-        if (argument-&gt;id != CSSValueAt || !args.next()) // expecting ellipse(.. at &lt;position&gt;)
-            return nullptr;
-
-        RefPtr&lt;CSSPrimitiveValue&gt; centerX;
-        RefPtr&lt;CSSPrimitiveValue&gt; centerY;
-        parseFillPosition(args, centerX, centerY);
-        if (!centerX || !centerY || args.current())
-            return nullptr;
-
-        shape-&gt;setCenterX(centerX.releaseNonNull());
-        shape-&gt;setCenterY(centerY.releaseNonNull());
-    }
-
-    return WTFMove(shape);
-}
-
-RefPtr&lt;CSSBasicShapePolygon&gt; CSSParser::parseBasicShapePolygon(CSSParserValueList&amp; args)
-{
-    unsigned size = args.size();
-    if (!size)
-        return nullptr;
-
-    auto shape = CSSBasicShapePolygon::create();
-
-    CSSParserValue* argument = args.current();
-    if (argument-&gt;id == CSSValueEvenodd || argument-&gt;id == CSSValueNonzero) {
-        shape-&gt;setWindRule(argument-&gt;id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO);
-
-        if (!isComma(args.next()))
-            return nullptr;
-
-        argument = args.next();
-        size -= 2;
-    }
-
-    // &lt;length&gt; &lt;length&gt;, ... &lt;length&gt; &lt;length&gt; -&gt; each pair has 3 elements except the last one
-    if (!size || (size % 3) - 2)
-        return nullptr;
-
-    CSSParserValue* argumentX = argument;
-    while (argumentX) {
-
-        ValueWithCalculation argumentXWithCalculation(*argumentX);
-        if (!validateUnit(argumentXWithCalculation, FLength | FPercent))
-            return nullptr;
-        auto xLength = createPrimitiveNumericValue(argumentXWithCalculation);
-
-        CSSParserValue* argumentY = args.next();
-        if (!argumentY)
-            return nullptr;
-        ValueWithCalculation argumentYWithCalculation(*argumentY);
-        if (!validateUnit(argumentYWithCalculation, FLength | FPercent))
-            return nullptr;
-        auto yLength = createPrimitiveNumericValue(argumentYWithCalculation);
-
-        shape-&gt;appendPoint(WTFMove(xLength), WTFMove(yLength));
-
-        CSSParserValue* commaOrNull = args.next();
-        if (!commaOrNull)
-            argumentX = nullptr;
-        else if (!isComma(commaOrNull)) 
-            return nullptr;
-        else 
-            argumentX = args.next();
-    }
-
-    return WTFMove(shape);
-}
-
-RefPtr&lt;CSSBasicShapePath&gt; CSSParser::parseBasicShapePath(CSSParserValueList&amp; args)
-{
-    unsigned size = args.size();
-    if (size != 1 &amp;&amp; size != 3)
-        return nullptr;
-
-    WindRule windRule = RULE_NONZERO;
-
-    CSSParserValue* argument = args.current();
-    if (argument-&gt;id == CSSValueEvenodd || argument-&gt;id == CSSValueNonzero) {
-        windRule = argument-&gt;id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO;
-
-        if (!isComma(args.next()))
-            return nullptr;
-        argument = args.next();
-    }
-
-    if (argument-&gt;unit != CSSPrimitiveValue::CSS_STRING)
-        return nullptr;
-
-    auto byteStream = std::make_unique&lt;SVGPathByteStream&gt;();
-    if (!buildSVGPathByteStreamFromString(argument-&gt;string, *byteStream, UnalteredParsing))
-        return nullptr;
-
-    auto shape = CSSBasicShapePath::create(WTFMove(byteStream));
-    shape-&gt;setWindRule(windRule);
-
-    args.next();
-    return WTFMove(shape);
-}
-
-static bool isBoxValue(CSSValueID valueId, CSSPropertyID propId)
-{
-    switch (valueId) {
-    case CSSValueContentBox:
-    case CSSValuePaddingBox:
-    case CSSValueBorderBox:
-    case CSSValueMarginBox:
-        return true;
-    case CSSValueFill:
-    case CSSValueStroke:
-    case CSSValueViewBox:
-        return propId == CSSPropertyWebkitClipPath;
-    default: break;
-    }
-
-    return false;
-}
-
-RefPtr&lt;CSSValueList&gt; CSSParser::parseBasicShapeAndOrBox(CSSPropertyID propId)
-{
-    CSSParserValue* value = m_valueList-&gt;current();
-
-    bool shapeFound = false;
-    bool boxFound = false;
-    CSSValueID valueId;
-
-    auto list = CSSValueList::createSpaceSeparated();
-    for (unsigned i = 0; i &lt; 2; ++i) {
-        if (!value)
-            break;
-        valueId = value-&gt;id;
-        if (value-&gt;unit == CSSParserValue::Function &amp;&amp; !shapeFound) {
-            // parseBasicShape already asks for the next value list item.
-            RefPtr&lt;CSSPrimitiveValue&gt; shapeValue = parseBasicShape();
-            if (!shapeValue)
-                return nullptr;
-            list-&gt;append(shapeValue.releaseNonNull());
-            shapeFound = true;
-        } else if (isBoxValue(valueId, propId) &amp;&amp; !boxFound) {
-            RefPtr&lt;CSSPrimitiveValue&gt; parsedValue = CSSValuePool::singleton().createIdentifierValue(valueId);
-            list-&gt;append(parsedValue.releaseNonNull());
-            boxFound = true;
-            m_valueList-&gt;next();
-        } else
-            return nullptr;
-        value = m_valueList-&gt;current();
-    }
-
-    if (m_valueList-&gt;current())
-        return nullptr;
-    return WTFMove(list);
-}
-
-#if ENABLE(CSS_SHAPES)
-RefPtr&lt;CSSValue&gt; CSSParser::parseShapeProperty(CSSPropertyID propId)
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    CSSValueID valueId = value.id;
-
-    if (valueId == CSSValueNone) {
-        m_valueList-&gt;next();
-        return CSSValuePool::singleton().createIdentifierValue(valueId);
-    }
-
-    RefPtr&lt;CSSValue&gt; imageValue;
-    if (valueId != CSSValueNone &amp;&amp; parseFillImage(*m_valueList, imageValue)) {
-        m_valueList-&gt;next();
-        return imageValue;
-    }
-
-    return parseBasicShapeAndOrBox(propId);
-}
-#endif
-
-RefPtr&lt;CSSValue&gt; CSSParser::parseClipPath()
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    CSSValueID valueId = value.id;
-
-    if (valueId == CSSValueNone) {
-        m_valueList-&gt;next();
-        return CSSValuePool::singleton().createIdentifierValue(valueId);
-    }
-    if (value.unit == CSSPrimitiveValue::CSS_URI) {
-        m_valueList-&gt;next();
-        return CSSPrimitiveValue::create(value.string, CSSPrimitiveValue::CSS_URI);
-    }
-
-    return parseBasicShapeAndOrBox(CSSPropertyWebkitClipPath);
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseBasicShape()
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    ASSERT(value.unit == CSSParserValue::Function);
-    CSSParserValueList* args = value.function-&gt;args.get();
-
-    if (!args)
-        return nullptr;
-
-    RefPtr&lt;CSSBasicShape&gt; shape;
-    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;circle(&quot;))
-        shape = parseBasicShapeCircle(*args);
-    else if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;ellipse(&quot;))
-        shape = parseBasicShapeEllipse(*args);
-    else if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;polygon(&quot;))
-        shape = parseBasicShapePolygon(*args);
-    else if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;path(&quot;))
-        shape = parseBasicShapePath(*args);
-    else if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;inset(&quot;))
-        shape = parseBasicShapeInset(*args);
-
-    if (!shape)
-        return nullptr;
-
-    m_valueList-&gt;next();
-    return CSSValuePool::singleton().createValue(shape.releaseNonNull());
-}
-
-// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family'
-bool CSSParser::parseFont(bool important)
-{
-    // Let's check if there is an inherit or initial somewhere in the shorthand.
-    for (unsigned i = 0; i &lt; m_valueList-&gt;size(); ++i) {
-        if (m_valueList-&gt;valueAt(i)-&gt;id == CSSValueInherit || m_valueList-&gt;valueAt(i)-&gt;id == CSSValueInitial)
-            return false;
-    }
-
-    ShorthandScope scope(this, CSSPropertyFont);
-    // Optional font-style, font-variant and font-weight.
-    bool fontStyleParsed = false;
-    bool fontVariantParsed = false;
-    bool fontWeightParsed = false;
-    CSSParserValue* value;
-    while ((value = m_valueList-&gt;current())) {
-        if (!fontStyleParsed &amp;&amp; isValidKeywordPropertyAndValue(CSSPropertyFontStyle, value-&gt;id, m_context, m_styleSheet)) {
-            addProperty(CSSPropertyFontStyle, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
-            fontStyleParsed = true;
-        } else if (!fontVariantParsed &amp;&amp; (value-&gt;id == CSSValueNormal || value-&gt;id == CSSValueSmallCaps)) {
-            // Font variant in the shorthand is particular, it only accepts normal or small-caps.
-            addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
-            fontVariantParsed = true;
-        } else if (!fontWeightParsed &amp;&amp; parseFontWeight(important))
-            fontWeightParsed = true;
-        else
-            break;
-        m_valueList-&gt;next();
-    }
-
-    if (!value)
-        return false;
-
-    if (!fontStyleParsed)
-        addProperty(CSSPropertyFontStyle, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-    if (!fontVariantParsed)
-        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-    if (!fontWeightParsed)
-        addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-
-    // Now a font size _must_ come.
-    // &lt;absolute-size&gt; | &lt;relative-size&gt; | &lt;length&gt; | &lt;percentage&gt; | inherit
-    if (!parseFontSize(important))
-        return false;
-
-    value = m_valueList-&gt;current();
-    if (!value)
-        return false;
-
-    if (isForwardSlashOperator(*value)) {
-        // The line-height property.
-        value = m_valueList-&gt;next();
-        if (!value)
-            return false;
-        if (!parseLineHeight(important))
-            return false;
-    } else
-        addProperty(CSSPropertyLineHeight, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
-
-    // Font family must come now.
-    RefPtr&lt;CSSValue&gt; parsedFamilyValue = parseFontFamily();
-    if (!parsedFamilyValue)
-        return false;
-
-    addProperty(CSSPropertyFontFamily, parsedFamilyValue.releaseNonNull(), important);
-
-    // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requires that
-    // &quot;font-stretch&quot;, &quot;font-size-adjust&quot;, and &quot;font-kerning&quot; be reset to their initial values
-    // but we don't seem to support them at the moment. They should also be added here once implemented.
-    if (m_valueList-&gt;current())
-        return false;
-
-    return true;
-}
-
-void CSSParser::parseSystemFont(bool important)
-{
-    ASSERT(m_valueList-&gt;size() == 1);
-    CSSValueID systemFontID = m_valueList-&gt;valueAt(0)-&gt;id;
-    ASSERT(systemFontID &gt;= CSSValueCaption &amp;&amp; systemFontID &lt;= CSSValueStatusBar);
-    m_valueList-&gt;next();
-
-    FontCascadeDescription fontDescription;
-    RenderTheme::defaultTheme()-&gt;systemFont(systemFontID, fontDescription);
-    if (!fontDescription.isAbsoluteSize())
-        return;
-
-    // We must set font's constituent properties, even for system fonts, so the cascade functions correctly.
-    ShorthandScope scope(this, CSSPropertyFont);
-    addProperty(CSSPropertyFontStyle, CSSValuePool::singleton().createIdentifierValue(fontDescription.italic() == FontItalicOn ? CSSValueItalic : CSSValueNormal), important);
-    addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createValue(fontDescription.weight()), important);
-    addProperty(CSSPropertyFontSize, CSSValuePool::singleton().createValue(fontDescription.specifiedSize(), CSSPrimitiveValue::CSS_PX), important);
-    Ref&lt;CSSValueList&gt; fontFamilyList = CSSValueList::createCommaSeparated();
-    fontFamilyList-&gt;append(CSSValuePool::singleton().createFontFamilyValue(fontDescription.familyAt(0), FromSystemFontID::Yes));
-    addProperty(CSSPropertyFontFamily, WTFMove(fontFamilyList), important);
-    addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important);
-    addProperty(CSSPropertyLineHeight, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important);
-}
-
-class FontFamilyValueBuilder {
-public:
-    FontFamilyValueBuilder(CSSValueList&amp; list)
-        : m_list(list)
-    {
-    }
-
-    void add(const CSSParserString&amp; string)
-    {
-        if (!m_builder.isEmpty())
-            m_builder.append(' ');
-
-        if (string.is8Bit()) {
-            m_builder.append(string.characters8(), string.length());
-            return;
-        }
-
-        m_builder.append(string.characters16(), string.length());
-    }
-
-    void commit()
-    {
-        if (m_builder.isEmpty())
-            return;
-        m_list.append(CSSValuePool::singleton().createFontFamilyValue(m_builder.toString()));
-        m_builder.clear();
-    }
-
-private:
-    StringBuilder m_builder;
-    CSSValueList&amp; m_list;
-};
-
-static bool valueIsCSSKeyword(const CSSParserValue&amp; value)
-{
-    // FIXME: when we add &quot;unset&quot;, we should handle it here.
-    return value.id == CSSValueInitial || value.id == CSSValueInherit || value.id == CSSValueDefault;
-}
-
-RefPtr&lt;CSSValueList&gt; CSSParser::parseFontFamily()
-{
-    auto list = CSSValueList::createCommaSeparated();
-    CSSParserValue* value = m_valueList-&gt;current();
-
-    FontFamilyValueBuilder familyBuilder(list);
-    bool inFamily = false;
-
-    while (value) {
-        CSSParserValue* nextValue = m_valueList-&gt;next();
-        bool nextValBreaksFont = !nextValue ||
-                                 (nextValue-&gt;unit == CSSParserValue::Operator &amp;&amp; nextValue-&gt;iValue == ',');
-        bool nextValIsFontName = nextValue &amp;&amp;
-            ((nextValue-&gt;id &gt;= CSSValueSerif &amp;&amp; nextValue-&gt;id &lt;= CSSValueWebkitBody) ||
-            (nextValue-&gt;unit == CSSPrimitiveValue::CSS_STRING || nextValue-&gt;unit == CSSPrimitiveValue::CSS_IDENT));
-
-        bool valueIsKeyword = valueIsCSSKeyword(*value);
-        if (valueIsKeyword &amp;&amp; !inFamily) {
-            if (nextValBreaksFont)
-                value = m_valueList-&gt;next();
-            else if (nextValIsFontName)
-                value = nextValue;
-            continue;
-        }
-
-        if (value-&gt;id &gt;= CSSValueSerif &amp;&amp; value-&gt;id &lt;= CSSValueWebkitBody) {
-            if (inFamily)
-                familyBuilder.add(value-&gt;string);
-            else if (nextValBreaksFont || !nextValIsFontName)
-                list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
-            else {
-                familyBuilder.commit();
-                familyBuilder.add(value-&gt;string);
-                inFamily = true;
-            }
-        } else if (value-&gt;unit == CSSPrimitiveValue::CSS_STRING) {
-            // Strings never share in a family name.
-            inFamily = false;
-            familyBuilder.commit();
-            list-&gt;append(CSSValuePool::singleton().createFontFamilyValue(value-&gt;string));
-        } else if (value-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
-            if (inFamily)
-                familyBuilder.add(value-&gt;string);
-            else if (nextValBreaksFont || !nextValIsFontName)
-                list-&gt;append(CSSValuePool::singleton().createFontFamilyValue(value-&gt;string));
-            else {
-                familyBuilder.commit();
-                familyBuilder.add(value-&gt;string);
-                inFamily = true;
-            }
-        } else {
-            break;
-        }
-
-        if (!nextValue)
-            break;
-
-        if (nextValBreaksFont) {
-            value = m_valueList-&gt;next();
-            familyBuilder.commit();
-            inFamily = false;
-        }
-        else if (nextValIsFontName)
-            value = nextValue;
-        else
-            break;
-    }
-    familyBuilder.commit();
-
-    if (!list-&gt;length())
-        return nullptr;
-    return WTFMove(list);
-}
-
-bool CSSParser::parseLineHeight(bool important)
-{
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-    CSSValueID id = valueWithCalculation.value().id;
-    bool validPrimitive = false;
-    // normal | &lt;number&gt; | &lt;length&gt; | &lt;percentage&gt; | inherit
-    if (id == CSSValueNormal)
-        validPrimitive = true;
-    else
-        validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FLength | FPercent | FNonNeg));
-    if (validPrimitive &amp;&amp; (!m_valueList-&gt;next() || inShorthand()))
-        addProperty(CSSPropertyLineHeight, parseValidPrimitive(id, valueWithCalculation), important);
-    return validPrimitive;
-}
-
-bool CSSParser::parseFontSize(bool important)
-{
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-    CSSValueID id = valueWithCalculation.value().id;
-    bool validPrimitive = false;
-    // &lt;absolute-size&gt; | &lt;relative-size&gt; | &lt;length&gt; | &lt;percentage&gt; | inherit
-    if (id &gt;= CSSValueXxSmall &amp;&amp; id &lt;= CSSValueLarger)
-        validPrimitive = true;
-    else
-        validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
-    if (validPrimitive &amp;&amp; (!m_valueList-&gt;next() || inShorthand()))
-        addProperty(CSSPropertyFontSize, parseValidPrimitive(id, valueWithCalculation), important);
-    return validPrimitive;
-}
-
-static CSSValueID createFontWeightValueKeyword(int weight)
-{
-    ASSERT(!(weight % 100) &amp;&amp; weight &gt;= 100 &amp;&amp; weight &lt;= 900);
-    CSSValueID value = static_cast&lt;CSSValueID&gt;(CSSValue100 + weight / 100 - 1);
-    ASSERT(value &gt;= CSSValue100 &amp;&amp; value &lt;= CSSValue900);
-    return value;
-}
-
-bool CSSParser::parseFontWeight(bool important)
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    if ((value.id &gt;= CSSValueNormal) &amp;&amp; (value.id &lt;= CSSValue900)) {
-        addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(value.id), important);
-        return true;
-    }
-    ValueWithCalculation valueWithCalculation(value);
-    if (validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSQuirksMode)) {
-        int weight = static_cast&lt;int&gt;(parsedDouble(valueWithCalculation));
-        if (!(weight % 100) &amp;&amp; weight &gt;= 100 &amp;&amp; weight &lt;= 900) {
-            addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(createFontWeightValueKeyword(weight)), important);
-            return true;
-        }
-    }
-    return false;
-}
-
-bool CSSParser::parseFontSynthesis(bool important)
-{
-    // none | [ weight || style ]
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (value &amp;&amp; value-&gt;id == CSSValueNone) {
-        addProperty(CSSPropertyFontSynthesis, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-        m_valueList-&gt;next();
-        return true;
-    }
-
-    bool encounteredWeight = false;
-    bool encounteredStyle = false;
-    while (value) {
-        switch (value-&gt;id) {
-        case CSSValueWeight:
-            encounteredWeight = true;
-            break;
-        case CSSValueStyle:
-            encounteredStyle = true;
-            break;
-        default:
-            return false;
-        }
-        value = m_valueList-&gt;next();
-    }
-
-    auto list = CSSValueList::createSpaceSeparated();
-    if (encounteredWeight)
-        list-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight));
-    if (encounteredStyle)
-        list-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
-    addProperty(CSSPropertyFontSynthesis, WTFMove(list), important);
-    return true;
-}
-
-bool CSSParser::parseFontFaceSrcURI(CSSValueList&amp; valueList)
-{
-    auto uriValue = CSSFontFaceSrcValue::create(completeURL(m_valueList-&gt;current()-&gt;string));
-
-    CSSParserValue* value = m_valueList-&gt;next();
-    if (!value) {
-        valueList.append(WTFMove(uriValue));
-        return true;
-    }
-    if (value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',') {
-        m_valueList-&gt;next();
-        valueList.append(WTFMove(uriValue));
-        return true;
-    }
-
-    if (value-&gt;unit != CSSParserValue::Function || !equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;format(&quot;))
-        return false;
-
-    // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20111004/ says that format() contains a comma-separated list of strings,
-    // but CSSFontFaceSrcValue stores only one format. Allowing one format for now.
-    CSSParserValueList* args = value-&gt;function-&gt;args.get();
-    if (!args || args-&gt;size() != 1 || (args-&gt;current()-&gt;unit != CSSPrimitiveValue::CSS_STRING &amp;&amp; args-&gt;current()-&gt;unit != CSSPrimitiveValue::CSS_IDENT))
-        return false;
-    uriValue-&gt;setFormat(args-&gt;current()-&gt;string);
-    valueList.append(WTFMove(uriValue));
-    value = m_valueList-&gt;next();
-    if (value &amp;&amp; value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')
-        m_valueList-&gt;next();
-    return true;
-}
-
-bool CSSParser::parseFontFaceSrcLocal(CSSValueList&amp; valueList)
-{
-    CSSParserValueList* args = m_valueList-&gt;current()-&gt;function-&gt;args.get();
-    if (!args || !args-&gt;size())
-        return false;
-
-    if (args-&gt;size() == 1 &amp;&amp; args-&gt;current()-&gt;unit == CSSPrimitiveValue::CSS_STRING)
-        valueList.append(CSSFontFaceSrcValue::createLocal(args-&gt;current()-&gt;string));
-    else if (args-&gt;current()-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
-        StringBuilder builder;
-        for (CSSParserValue* localValue = args-&gt;current(); localValue; localValue = args-&gt;next()) {
-            if (localValue-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-                return false;
-            if (!builder.isEmpty())
-                builder.append(' ');
-            builder.append(localValue-&gt;string);
-        }
-        valueList.append(CSSFontFaceSrcValue::createLocal(builder.toString()));
-    } else
-        return false;
-
-    if (CSSParserValue* value = m_valueList-&gt;next()) {
-        if (value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')
-            m_valueList-&gt;next();
-    }
-    return true;
-}
-
-bool CSSParser::parseFontFaceSrc()
-{
-    auto values = CSSValueList::createCommaSeparated();
-
-    while (CSSParserValue* value = m_valueList-&gt;current()) {
-        if (value-&gt;unit == CSSPrimitiveValue::CSS_URI) {
-            if (!parseFontFaceSrcURI(values))
-                return false;
-        } else if (value-&gt;unit == CSSParserValue::Function &amp;&amp; equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;local(&quot;)) {
-            if (!parseFontFaceSrcLocal(values))
-                return false;
-        } else
-            return false;
-    }
-    if (!values-&gt;length())
-        return false;
-
-    addProperty(CSSPropertySrc, WTFMove(values), m_important);
-    m_valueList-&gt;next();
-    return true;
-}
-
-bool CSSParser::parseFontFaceUnicodeRange()
-{
-    auto values = CSSValueList::createCommaSeparated();
-    bool failed = false;
-    bool operatorExpected = false;
-    for (; m_valueList-&gt;current(); m_valueList-&gt;next(), operatorExpected = !operatorExpected) {
-        if (operatorExpected) {
-            if (m_valueList-&gt;current()-&gt;unit == CSSParserValue::Operator &amp;&amp; m_valueList-&gt;current()-&gt;iValue == ',')
-                continue;
-            failed = true;
-            break;
-        }
-        if (m_valueList-&gt;current()-&gt;unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) {
-            failed = true;
-            break;
-        }
-
-        String rangeString = m_valueList-&gt;current()-&gt;string;
-        UChar32 from = 0;
-        UChar32 to = 0;
-        unsigned length = rangeString.length();
-
-        if (length &lt; 3) {
-            failed = true;
-            break;
-        }
-
-        unsigned i = 2;
-        while (i &lt; length) {
-            UChar c = rangeString[i];
-            if (c == '-' || c == '?')
-                break;
-            from *= 16;
-            if (c &gt;= '0' &amp;&amp; c &lt;= '9')
-                from += c - '0';
-            else if (c &gt;= 'A' &amp;&amp; c &lt;= 'F')
-                from += 10 + c - 'A';
-            else if (c &gt;= 'a' &amp;&amp; c &lt;= 'f')
-                from += 10 + c - 'a';
-            else {
-                failed = true;
-                break;
-            }
-            i++;
-        }
-        if (failed)
-            break;
-
-        if (i == length)
-            to = from;
-        else if (rangeString[i] == '?') {
-            unsigned span = 1;
-            while (i &lt; length &amp;&amp; rangeString[i] == '?') {
-                span *= 16;
-                from *= 16;
-                i++;
-            }
-            if (i &lt; length)
-                failed = true;
-            to = from + span - 1;
-        } else {
-            if (length &lt; i + 2) {
-                failed = true;
-                break;
-            }
-            i++;
-            while (i &lt; length) {
-                UChar c = rangeString[i];
-                to *= 16;
-                if (c &gt;= '0' &amp;&amp; c &lt;= '9')
-                    to += c - '0';
-                else if (c &gt;= 'A' &amp;&amp; c &lt;= 'F')
-                    to += 10 + c - 'A';
-                else if (c &gt;= 'a' &amp;&amp; c &lt;= 'f')
-                    to += 10 + c - 'a';
-                else {
-                    failed = true;
-                    break;
-                }
-                i++;
-            }
-            if (failed)
-                break;
-        }
-        if (from &lt;= to)
-            values-&gt;append(CSSUnicodeRangeValue::create(from, to));
-    }
-    if (failed || !values-&gt;length())
-        return false;
-    addProperty(CSSPropertyUnicodeRange, WTFMove(values), m_important);
-    return true;
-}
-
-// Returns the number of characters which form a valid double
-// and are terminated by the given terminator character
-template &lt;typename CharacterType&gt;
-static int checkForValidDouble(const CharacterType* string, const CharacterType* end, const char terminator)
-{
-    int length = end - string;
-    if (length &lt; 1)
-        return 0;
-
-    bool decimalMarkSeen = false;
-    int processedLength = 0;
-
-    for (int i = 0; i &lt; length; ++i) {
-        if (string[i] == terminator) {
-            processedLength = i;
-            break;
-        }
-        if (!isASCIIDigit(string[i])) {
-            if (!decimalMarkSeen &amp;&amp; string[i] == '.')
-                decimalMarkSeen = true;
-            else
-                return 0;
-        }
-    }
-
-    if (decimalMarkSeen &amp;&amp; processedLength == 1)
-        return 0;
-
-    return processedLength;
-}
-
-// Returns the number of characters consumed for parsing a valid double
-// terminated by the given terminator character
-template &lt;typename CharacterType&gt;
-static int parseDouble(const CharacterType* string, const CharacterType* end, const char terminator, double&amp; value)
-{
-    int length = checkForValidDouble(string, end, terminator);
-    if (!length)
-        return 0;
-
-    int position = 0;
-    double localValue = 0;
-
-    // The consumed characters here are guaranteed to be
-    // ASCII digits with or without a decimal mark
-    for (; position &lt; length; ++position) {
-        if (string[position] == '.')
-            break;
-        localValue = localValue * 10 + string[position] - '0';
-    }
-
-    if (++position == length) {
-        value = localValue;
-        return length;
-    }
-
-    double fraction = 0;
-    double scale = 1;
-
-    while (position &lt; length &amp;&amp; scale &lt; MAX_SCALE) {
-        fraction = fraction * 10 + string[position++] - '0';
-        scale *= 10;
-    }
-
-    value = localValue + fraction / scale;
-    return length;
-}
-
-template &lt;typename CharacterType&gt;
-static bool parseColorIntOrPercentage(const CharacterType*&amp; string, const CharacterType* end, const char terminator, CSSPrimitiveValue::UnitTypes&amp; expect, int&amp; value)
-{
-    const CharacterType* current = string;
-    double localValue = 0;
-    bool negative = false;
-    while (current != end &amp;&amp; isHTMLSpace(*current))
-        current++;
-    if (current != end &amp;&amp; *current == '-') {
-        negative = true;
-        current++;
-    }
-    if (current == end || !isASCIIDigit(*current))
-        return false;
-    while (current != end &amp;&amp; isASCIIDigit(*current)) {
-        double newValue = localValue * 10 + *current++ - '0';
-        if (newValue &gt;= 255) {
-            // Clamp values at 255.
-            localValue = 255;
-            while (current != end &amp;&amp; isASCIIDigit(*current))
-                ++current;
-            break;
-        }
-        localValue = newValue;
-    }
-
-    if (current == end)
-        return false;
-
-    if (expect == CSSPrimitiveValue::CSS_NUMBER &amp;&amp; (*current == '.' || *current == '%'))
-        return false;
-
-    if (*current == '.') {
-        // We already parsed the integral part, try to parse
-        // the fraction part of the percentage value.
-        double percentage = 0;
-        int numCharactersParsed = parseDouble(current, end, '%', percentage);
-        if (!numCharactersParsed)
-            return false;
-        current += numCharactersParsed;
-        if (*current != '%')
-            return false;
-        localValue += percentage;
-    }
-
-    if (expect == CSSPrimitiveValue::CSS_PERCENTAGE &amp;&amp; *current != '%')
-        return false;
-
-    if (*current == '%') {
-        expect = CSSPrimitiveValue::CSS_PERCENTAGE;
-        localValue = localValue / 100.0 * 256.0;
-        // Clamp values at 255 for percentages over 100%
-        if (localValue &gt; 255)
-            localValue = 255;
-        current++;
-    } else
-        expect = CSSPrimitiveValue::CSS_NUMBER;
-
-    while (current != end &amp;&amp; isHTMLSpace(*current))
-        current++;
-    if (current == end || *current++ != terminator)
-        return false;
-    // Clamp negative values at zero.
-    value = negative ? 0 : static_cast&lt;int&gt;(localValue);
-    string = current;
-    return true;
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool isTenthAlpha(const CharacterType* string, const int length)
-{
-    // &quot;0.X&quot;
-    if (length == 3 &amp;&amp; string[0] == '0' &amp;&amp; string[1] == '.' &amp;&amp; isASCIIDigit(string[2]))
-        return true;
-
-    // &quot;.X&quot;
-    if (length == 2 &amp;&amp; string[0] == '.' &amp;&amp; isASCIIDigit(string[1]))
-        return true;
-
-    return false;
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool parseAlphaValue(const CharacterType*&amp; string, const CharacterType* end, const char terminator, int&amp; value)
-{
-    while (string != end &amp;&amp; isHTMLSpace(*string))
-        ++string;
-
-    bool negative = false;
-
-    if (string != end &amp;&amp; *string == '-') {
-        negative = true;
-        ++string;
-    }
-
-    value = 0;
-
-    int length = end - string;
-    if (length &lt; 2)
-        return false;
-
-    if (string[length - 1] != terminator || !isASCIIDigit(string[length - 2]))
-        return false;
-
-    if (string[0] != '0' &amp;&amp; string[0] != '1' &amp;&amp; string[0] != '.') {
-        if (checkForValidDouble(string, end, terminator)) {
-            value = negative ? 0 : 255;
-            string = end;
-            return true;
-        }
-        return false;
-    }
-
-    if (length == 2 &amp;&amp; string[0] != '.') {
-        value = !negative &amp;&amp; string[0] == '1' ? 255 : 0;
-        string = end;
-        return true;
-    }
-
-    if (isTenthAlpha(string, length - 1)) {
-        static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 };
-        value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
-        string = end;
-        return true;
-    }
-
-    double alpha = 0;
-    if (!parseDouble(string, end, terminator, alpha))
-        return false;
-    value = negative ? 0 : static_cast&lt;int&gt;(alpha * nextafter(256.0, 0.0));
-    string = end;
-    return true;
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool mightBeRGBA(const CharacterType* characters, unsigned length)
-{
-    if (length &lt; 5)
-        return false;
-    return characters[4] == '('
-        &amp;&amp; isASCIIAlphaCaselessEqual(characters[0], 'r')
-        &amp;&amp; isASCIIAlphaCaselessEqual(characters[1], 'g')
-        &amp;&amp; isASCIIAlphaCaselessEqual(characters[2], 'b')
-        &amp;&amp; isASCIIAlphaCaselessEqual(characters[3], 'a');
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool mightBeRGB(const CharacterType* characters, unsigned length)
-{
-    if (length &lt; 4)
-        return false;
-    return characters[3] == '('
-        &amp;&amp; isASCIIAlphaCaselessEqual(characters[0], 'r')
-        &amp;&amp; isASCIIAlphaCaselessEqual(characters[1], 'g')
-        &amp;&amp; isASCIIAlphaCaselessEqual(characters[2], 'b');
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool fastParseColorInternal(RGBA32&amp; rgb, const CharacterType* characters, unsigned length , bool strict)
-{
-    CSSPrimitiveValue::UnitTypes expect = CSSPrimitiveValue::CSS_UNKNOWN;
-    
-    if (!strict &amp;&amp; length &gt;= 3) {
-        if (characters[0] == '#') {
-            if (Color::parseHexColor(characters + 1, length - 1, rgb))
-                return true;
-        } else {
-            if (Color::parseHexColor(characters, length, rgb))
-                return true;
-        }
-    }
-
-    // Try rgba() syntax.
-    if (mightBeRGBA(characters, length)) {
-        const CharacterType* current = characters + 5;
-        const CharacterType* end = characters + length;
-        int red;
-        int green;
-        int blue;
-        int alpha;
-        
-        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
-            return false;
-        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
-            return false;
-        if (!parseColorIntOrPercentage(current, end, ',', expect, blue))
-            return false;
-        if (!parseAlphaValue(current, end, ')', alpha))
-            return false;
-        if (current != end)
-            return false;
-        rgb = makeRGBA(red, green, blue, alpha);
-        return true;
-    }
-
-    // Try rgb() syntax.
-    if (mightBeRGB(characters, length)) {
-        const CharacterType* current = characters + 4;
-        const CharacterType* end = characters + length;
-        int red;
-        int green;
-        int blue;
-        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
-            return false;
-        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
-            return false;
-        if (!parseColorIntOrPercentage(current, end, ')', expect, blue))
-            return false;
-        if (current != end)
-            return false;
-        rgb = makeRGB(red, green, blue);
-        return true;
-    }
-
-    return false;
-}
-
-template&lt;typename StringType&gt;
-bool CSSParser::fastParseColor(RGBA32&amp; rgb, const StringType&amp; name, bool strict)
-{
-    unsigned length = name.length();
-    bool parseResult;
-
-    if (!length)
-        return false;
-
-    if (name.is8Bit())
-        parseResult = fastParseColorInternal(rgb, name.characters8(), length, strict);
-    else
-        parseResult = fastParseColorInternal(rgb, name.characters16(), length, strict);
-
-    if (parseResult)
-        return true;
-
-    // Try named colors.
-    Color tc;
-    tc.setNamedColor(name);
-    if (tc.isValid()) {
-        rgb = tc.rgb();
-        return true;
-    }
-    return false;
-}
-    
-inline double CSSParser::parsedDouble(ValueWithCalculation&amp; valueWithCalculation)
-{
-    return valueWithCalculation.calculation() ? valueWithCalculation.calculation()-&gt;doubleValue() : valueWithCalculation.value().fValue;
-}
-
-bool CSSParser::isCalculation(CSSParserValue&amp; value)
-{
-    return value.unit == CSSParserValue::Function
-        &amp;&amp; (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;calc(&quot;)
-            || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-calc(&quot;));
-}
-
-inline int CSSParser::colorIntFromValue(ValueWithCalculation&amp; valueWithCalculation)
-{
-    bool isPercent;
-    
-    if (valueWithCalculation.calculation())
-        isPercent = valueWithCalculation.calculation()-&gt;category() == CalcPercent;
-    else
-        isPercent = valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE;
-
-    const double doubleValue = parsedDouble(valueWithCalculation);
-    
-    if (doubleValue &lt;= 0.0)
-        return 0;
-
-    if (isPercent) {
-        if (doubleValue &gt;= 100.0)
-            return 255;
-        return static_cast&lt;int&gt;(doubleValue * 256.0 / 100.0);
-    }
-
-    if (doubleValue &gt;= 255.0)
-        return 255;
-
-    return static_cast&lt;int&gt;(doubleValue);
-}
-
-bool CSSParser::parseColorParameters(CSSParserValue&amp; value, int* colorArray, bool parseAlpha)
-{
-    CSSParserValueList* args = value.function-&gt;args.get();
-    ValueWithCalculation firstArgumentWithCalculation(*args-&gt;current());
-    Units unitType = FUnknown;
-    // Get the first value and its type
-    if (validateUnit(firstArgumentWithCalculation, FInteger, CSSStrictMode))
-        unitType = FInteger;
-    else if (validateUnit(firstArgumentWithCalculation, FPercent, CSSStrictMode))
-        unitType = FPercent;
-    else
-        return false;
-    
-    colorArray[0] = colorIntFromValue(firstArgumentWithCalculation);
-    for (int i = 1; i &lt; 3; i++) {
-        CSSParserValue&amp; operatorArgument = *args-&gt;next();
-        if (operatorArgument.unit != CSSParserValue::Operator &amp;&amp; operatorArgument.iValue != ',')
-            return false;
-        ValueWithCalculation argumentWithCalculation(*args-&gt;next());
-        if (!validateUnit(argumentWithCalculation, unitType, CSSStrictMode))
-            return false;
-        colorArray[i] = colorIntFromValue(argumentWithCalculation);
-    }
-    if (parseAlpha) {
-        CSSParserValue&amp; operatorArgument = *args-&gt;next();
-        if (operatorArgument.unit != CSSParserValue::Operator &amp;&amp; operatorArgument.iValue != ',')
-            return false;
-        ValueWithCalculation argumentWithCalculation(*args-&gt;next());
-        if (!validateUnit(argumentWithCalculation, FNumber, CSSStrictMode))
-            return false;
-        double doubleValue = parsedDouble(argumentWithCalculation);
-        // Convert the floating pointer number of alpha to an integer in the range [0, 256),
-        // with an equal distribution across all 256 values.
-        colorArray[3] = static_cast&lt;int&gt;(std::max&lt;double&gt;(0, std::min&lt;double&gt;(1, doubleValue)) * nextafter(256.0, 0.0));
-    }
-    return true;
-}
-
-// The CSS3 specification defines the format of a HSL color as
-// hsl(&lt;number&gt;, &lt;percent&gt;, &lt;percent&gt;)
-// and with alpha, the format is
-// hsla(&lt;number&gt;, &lt;percent&gt;, &lt;percent&gt;, &lt;number&gt;)
-// The first value, HUE, is in an angle with a value between 0 and 360
-bool CSSParser::parseHSLParameters(CSSParserValue&amp; value, double* colorArray, bool parseAlpha)
-{
-    CSSParserValueList* args = value.function-&gt;args.get();
-    ValueWithCalculation firstArgumentWithCalculation(*args-&gt;current());
-    // Get the first value
-    if (!validateUnit(firstArgumentWithCalculation, FNumber, CSSStrictMode))
-        return false;
-    // normalize the Hue value and change it to be between 0 and 1.0
-    colorArray[0] = (((static_cast&lt;int&gt;(parsedDouble(firstArgumentWithCalculation)) % 360) + 360) % 360) / 360.0;
-    for (int i = 1; i &lt; 3; ++i) {
-        CSSParserValue&amp; operatorArgument = *args-&gt;next();
-        if (operatorArgument.unit != CSSParserValue::Operator &amp;&amp; operatorArgument.iValue != ',')
-            return false;
-        ValueWithCalculation argumentWithCalculation(*args-&gt;next());
-        if (!validateUnit(argumentWithCalculation, FPercent, CSSStrictMode))
-            return false;
-        colorArray[i] = std::max&lt;double&gt;(0, std::min&lt;double&gt;(100, parsedDouble(argumentWithCalculation))) / 100.0; // needs to be value between 0 and 1.0
-    }
-    if (parseAlpha) {
-        CSSParserValue&amp; operatorArgument = *args-&gt;next();
-        if (operatorArgument.unit != CSSParserValue::Operator &amp;&amp; operatorArgument.iValue != ',')
-            return false;
-        ValueWithCalculation argumentWithCalculation(*args-&gt;next());
-        if (!validateUnit(argumentWithCalculation, FNumber, CSSStrictMode))
-            return false;
-        colorArray[3] = std::max&lt;double&gt;(0, std::min&lt;double&gt;(1, parsedDouble(argumentWithCalculation)));
-    }
-    return true;
-}
-
-RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseColor(CSSParserValue* value)
-{
-    RGBA32 c = Color::transparent;
-    if (!parseColorFromValue(value ? *value : *m_valueList-&gt;current(), c))
-        return nullptr;
-    return CSSValuePool::singleton().createColorValue(c);
-}
-
-bool CSSParser::parseColorFromValue(CSSParserValue&amp; value, RGBA32&amp; c)
-{
-    if (inQuirksMode() &amp;&amp; value.unit == CSSPrimitiveValue::CSS_NUMBER
-        &amp;&amp; value.fValue &gt;= 0. &amp;&amp; value.fValue &lt; 1000000.) {
-        String str = String::format(&quot;%06d&quot;, static_cast&lt;int&gt;((value.fValue+.5)));
-        // FIXME: This should be strict parsing for SVG as well.
-        if (!fastParseColor(c, str, inStrictMode()))
-            return false;
-    } else if (value.unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR
-        || value.unit == CSSPrimitiveValue::CSS_IDENT
-        || (inQuirksMode() &amp;&amp; value.unit == CSSPrimitiveValue::CSS_DIMENSION)) {
-        if (!fastParseColor(c, value.string, inStrictMode() &amp;&amp; value.unit == CSSPrimitiveValue::CSS_IDENT))
-            return false;
-    } else if (value.unit == CSSParserValue::Function
-        &amp;&amp; value.function-&gt;args
-        &amp;&amp; value.function-&gt;args-&gt;size() == 5 /* rgb + two commas */
-        &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;rgb(&quot;)) {
-        int colorValues[3];
-        if (!parseColorParameters(value, colorValues, false))
-            return false;
-        c = makeRGB(colorValues[0], colorValues[1], colorValues[2]);
-    } else {
-        if (value.unit == CSSParserValue::Function
-            &amp;&amp; value.function-&gt;args
-            &amp;&amp; value.function-&gt;args-&gt;size() == 7 /* rgba + three commas */
-            &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;rgba(&quot;)) {
-            int colorValues[4];
-            if (!parseColorParameters(value, colorValues, true))
-                return false;
-            c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
-        } else if (value.unit == CSSParserValue::Function
-            &amp;&amp; value.function-&gt;args
-            &amp;&amp; value.function-&gt;args-&gt;size() == 5 /* hsl + two commas */
-            &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;hsl(&quot;)) {
-            double colorValues[3];
-            if (!parseHSLParameters(value, colorValues, false))
-                return false;
-            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0);
-        } else if (value.unit == CSSParserValue::Function
-            &amp;&amp; value.function-&gt;args
-            &amp;&amp; value.function-&gt;args-&gt;size() == 7 /* hsla + three commas */
-            &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;hsla(&quot;)) {
-            double colorValues[4];
-            if (!parseHSLParameters(value, colorValues, true))
-                return false;
-            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
-        } else
-            return false;
-    }
-
-    return true;
-}
-
-// This class tracks parsing state for shadow values.  If it goes out of scope (e.g., due to an early return)
-// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
-struct ShadowParseContext {
-    ShadowParseContext(CSSPropertyID prop, CSSParser&amp; parser)
-        : property(prop)
-        , m_parser(parser)
-        , allowX(true)
-        , allowY(false)
-        , allowBlur(false)
-        , allowSpread(false)
-        , allowColor(true)
-        , allowStyle(prop == CSSPropertyWebkitBoxShadow || prop == CSSPropertyBoxShadow)
-        , allowBreak(true)
-    {
-    }
-
-    bool allowLength() { return allowX || allowY || allowBlur || allowSpread; }
-
-    void commitValue()
-    {
-        // Handle the ,, case gracefully by doing nothing.
-        if (x || y || blur || spread || color || style) {
-            if (!values)
-                values = CSSValueList::createCommaSeparated();
-
-            // Construct the current shadow value and add it to the list.
-            values-&gt;append(CSSShadowValue::create(WTFMove(x), WTFMove(y), WTFMove(blur), WTFMove(spread), WTFMove(style), WTFMove(color)));
-        }
-
-        // Now reset for the next shadow value.
-        x = nullptr;
-        y = nullptr;
-        blur = nullptr;
-        spread = nullptr;
-        style = nullptr;
-        color = nullptr;
-
-        allowX = true;
-        allowColor = true;
-        allowBreak = true;
-        allowY = false;
-        allowBlur = false;
-        allowSpread = false;
-        allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
-    }
-
-    void commitLength(CSSParser::ValueWithCalculation&amp; valueWithCalculation)
-    {
-        auto primitiveValue = m_parser.createPrimitiveNumericValue(valueWithCalculation);
-
-        if (allowX) {
-            x = WTFMove(primitiveValue);
-            allowX = false;
-            allowY = true;
-            allowColor = false;
-            allowStyle = false;
-            allowBreak = false;
-        } else if (allowY) {
-            y = WTFMove(primitiveValue);
-            allowY = false;
-            allowBlur = true;
-            allowColor = true;
-            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
-            allowBreak = true;
-        } else if (allowBlur) {
-            blur = WTFMove(primitiveValue);
-            allowBlur = false;
-            allowSpread = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
-        } else if (allowSpread) {
-            spread = WTFMove(primitiveValue);
-            allowSpread = false;
-        }
-    }
-
-    void commitColor(RefPtr&lt;CSSPrimitiveValue&gt;&amp;&amp; val)
-    {
-        color = val;
-        allowColor = false;
-        if (allowX) {
-            allowStyle = false;
-            allowBreak = false;
-        } else {
-            allowBlur = false;
-            allowSpread = false;
-            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
-        }
-    }
-
-    void commitStyle(CSSParserValue&amp; value)
-    {
-        style = CSSValuePool::singleton().createIdentifierValue(value.id);
-        allowStyle = false;
-        if (allowX)
-            allowBreak = false;
-        else {
-            allowBlur = false;
-            allowSpread = false;
-            allowColor = false;
-        }
-    }
-
-    CSSPropertyID property;
-    CSSParser&amp; m_parser;
-
-    RefPtr&lt;CSSValueList&gt; values;
-    RefPtr&lt;CSSPrimitiveValue&gt; x;
-    RefPtr&lt;CSSPrimitiveValue&gt; y;
-    RefPtr&lt;CSSPrimitiveValue&gt; blur;
-    RefPtr&lt;CSSPrimitiveValue&gt; spread;
-    RefPtr&lt;CSSPrimitiveValue&gt; style;
-    RefPtr&lt;CSSPrimitiveValue&gt; color;
-
-    bool allowX;
-    bool allowY;
-    bool allowBlur;
-    bool allowSpread;
-    bool allowColor;
-    bool allowStyle; // inset or not.
-    bool allowBreak;
-};
-
-RefPtr&lt;CSSValueList&gt; CSSParser::parseShadow(CSSParserValueList&amp; valueList, CSSPropertyID propId)
-{
-    ShadowParseContext context(propId, *this);
-    CSSParserValue* value;
-    while ((value = valueList.current())) {
-        ValueWithCalculation valueWithCalculation(*value);
-        // Check for a comma break first.
-        if (value-&gt;unit == CSSParserValue::Operator) {
-            if (value-&gt;iValue != ',' || !context.allowBreak) {
-                // Other operators aren't legal or we aren't done with the current shadow
-                // value.  Treat as invalid.
-                return nullptr;
-            }
-            // -webkit-svg-shadow does not support multiple values.
-            if (propId == CSSPropertyWebkitSvgShadow)
-                return nullptr;
-            // The value is good.  Commit it.
-            context.commitValue();
-        } else if (validateUnit(valueWithCalculation, FLength, CSSStrictMode)) {
-            // We required a length and didn't get one. Invalid.
-            if (!context.allowLength())
-                return nullptr;
-
-            // Blur radius must be non-negative.
-            if (context.allowBlur &amp;&amp; !validateUnit(valueWithCalculation, FLength | FNonNeg, CSSStrictMode))
-                return nullptr;
-
-            // A length is allowed here.  Construct the value and add it.
-            context.commitLength(valueWithCalculation);
-        } else if (value-&gt;id == CSSValueInset) {
-            if (!context.allowStyle)
-                return nullptr;
-
-            context.commitStyle(valueWithCalculation);
-        } else {
-            // The only other type of value that's ok is a color value.
-            RefPtr&lt;CSSPrimitiveValue&gt; parsedColor;
-            bool isColor = (isValidSystemColorValue(value-&gt;id) || value-&gt;id == CSSValueMenu
-                || (value-&gt;id &gt;= CSSValueWebkitFocusRingColor &amp;&amp; value-&gt;id &lt;= CSSValueWebkitText &amp;&amp; inQuirksMode())
-                || value-&gt;id == CSSValueCurrentcolor);
-            if (isColor) {
-                if (!context.allowColor)
-                    return nullptr;
-                parsedColor = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-            }
-
-            if (!parsedColor)
-                // It's not built-in. Try to parse it as a color.
-                parsedColor = parseColor(value);
-
-            if (!parsedColor || !context.allowColor)
-                return nullptr; // This value is not a color or length and is invalid or
-                          // it is a color, but a color isn't allowed at this point.
-
-            context.commitColor(parsedColor.releaseNonNull());
-        }
-
-        valueList.next();
-    }
-
-    if (context.allowBreak) {
-        context.commitValue();
-        if (context.values &amp;&amp; context.values-&gt;length())
-            return WTFMove(context.values);
-    }
-
-    return nullptr;
-}
-
-bool CSSParser::parseReflect(CSSPropertyID propId, bool important)
-{
-    // box-reflect: &lt;direction&gt; &lt;offset&gt; &lt;mask&gt;
-
-    // Direction comes first.
-    CSSParserValue* value = m_valueList-&gt;current();
-    RefPtr&lt;CSSPrimitiveValue&gt; direction;
-    switch (value-&gt;id) {
-        case CSSValueAbove:
-        case CSSValueBelow:
-        case CSSValueLeft:
-        case CSSValueRight:
-            direction = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-            break;
-        default:
-            return false;
-    }
-
-    // The offset comes next.
-    value = m_valueList-&gt;next();
-    RefPtr&lt;CSSPrimitiveValue&gt; offset;
-    if (!value)
-        offset = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_PX);
-    else {
-        ValueWithCalculation valueWithCalculation(*value);
-        if (!validateUnit(valueWithCalculation, FLength | FPercent))
-            return false;
-        offset = createPrimitiveNumericValue(valueWithCalculation);
-    }
-
-    // Now for the mask.
-    RefPtr&lt;CSSValue&gt; mask;
-    value = m_valueList-&gt;next();
-    if (value) {
-        if (!parseBorderImage(propId, mask))
-            return false;
-    }
-
-    addProperty(propId, CSSReflectValue::create(direction.releaseNonNull(), offset.releaseNonNull(), WTFMove(mask)), important);
-    m_valueList-&gt;next();
-    return true;
-}
-
-bool CSSParser::parseFlex(CSSParserValueList&amp; args, bool important)
-{
-    if (!args.size() || args.size() &gt; 3)
-        return false;
-    static const double unsetValue = -1;
-    double flexGrow = unsetValue;
-    double flexShrink = unsetValue;
-    RefPtr&lt;CSSPrimitiveValue&gt; flexBasis;
-
-    while (CSSParserValue* argument = args.current()) {
-        ValueWithCalculation argumentWithCalculation(*argument);
-        if (validateUnit(argumentWithCalculation, FNumber | FNonNeg)) {
-            if (flexGrow == unsetValue)
-                flexGrow = parsedDouble(argumentWithCalculation);
-            else if (flexShrink == unsetValue)
-                flexShrink = parsedDouble(argumentWithCalculation);
-            else if (!parsedDouble(argumentWithCalculation)) {
-                // flex only allows a basis of 0 (sans units) if flex-grow and flex-shrink values have already been set.
-                flexBasis = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_PX);
-            } else {
-                // We only allow 3 numbers without units if the last value is 0. E.g., flex:1 1 1 is invalid.
-                return false;
-            }
-        } else if (!flexBasis &amp;&amp; (argumentWithCalculation.value().id == CSSValueAuto || validateUnit(argumentWithCalculation, FLength | FPercent | FNonNeg)))
-            flexBasis = parseValidPrimitive(argumentWithCalculation.value().id, argumentWithCalculation);
-        else {
-            // Not a valid arg for flex.
-            return false;
-        }
-        args.next();
-    }
-
-    if (flexGrow == unsetValue)
-        flexGrow = 1;
-    if (flexShrink == unsetValue)
-        flexShrink = 1;
-    if (!flexBasis)
-        flexBasis = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_PX);
-
-    addProperty(CSSPropertyFlexGrow, CSSValuePool::singleton().createValue(clampToFloat(flexGrow), CSSPrimitiveValue::CSS_NUMBER), important);
-    addProperty(CSSPropertyFlexShrink, CSSValuePool::singleton().createValue(clampToFloat(flexShrink), CSSPrimitiveValue::CSS_NUMBER), important);
-    addProperty(CSSPropertyFlexBasis, flexBasis.releaseNonNull(), important);
-    return true;
-}
-
-struct BorderImageParseContext {
-    BorderImageParseContext()
-    : m_canAdvance(false)
-    , m_allowCommit(true)
-    , m_allowImage(true)
-    , m_allowImageSlice(true)
-    , m_allowRepeat(true)
-    , m_allowForwardSlashOperator(false)
-    , m_requireWidth(false)
-    , m_requireOutset(false)
-    {}
-
-    bool canAdvance() const { return m_canAdvance; }
-    void setCanAdvance(bool canAdvance) { m_canAdvance = canAdvance; }
-
-    bool allowCommit() const { return m_allowCommit; }
-    bool allowImage() const { return m_allowImage; }
-    bool allowImageSlice() const { return m_allowImageSlice; }
-    bool allowRepeat() const { return m_allowRepeat; }
-    bool allowForwardSlashOperator() const { return m_allowForwardSlashOperator; }
-
-    bool requireWidth() const { return m_requireWidth; }
-    bool requireOutset() const { return m_requireOutset; }
-
-    void commitImage(RefPtr&lt;CSSValue&gt;&amp;&amp; image)
-    {
-        m_image = WTFMove(image);
-        m_canAdvance = true;
-        m_allowCommit = true;
-        m_allowImage = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
-        m_allowImageSlice = !m_imageSlice;
-        m_allowRepeat = !m_repeat;
-    }
-    void commitImageSlice(RefPtr&lt;CSSBorderImageSliceValue&gt;&amp;&amp; slice)
-    {
-        m_imageSlice = WTFMove(slice);
-        m_canAdvance = true;
-        m_allowCommit = m_allowForwardSlashOperator = true;
-        m_allowImageSlice = m_requireWidth = m_requireOutset = false;
-        m_allowImage = !m_image;
-        m_allowRepeat = !m_repeat;
-    }
-    void commitForwardSlashOperator()
-    {
-        m_canAdvance = true;
-        m_allowCommit = m_allowImage = m_allowImageSlice = m_allowRepeat = m_allowForwardSlashOperator = false;
-        if (!m_borderSlice) {
-            m_requireWidth = true;
-            m_requireOutset = false;
-        } else {
-            m_requireOutset = true;
-            m_requireWidth = false;
-        }
-    }
-    void commitBorderWidth(RefPtr&lt;CSSPrimitiveValue&gt;&amp;&amp; slice)
-    {
-        m_borderSlice = WTFMove(slice);
-        m_canAdvance = true;
-        m_allowCommit = m_allowForwardSlashOperator = true;
-        m_allowImageSlice = m_requireWidth = m_requireOutset = false;
-        m_allowImage = !m_image;
-        m_allowRepeat = !m_repeat;
-    }
-    void commitBorderOutset(RefPtr&lt;CSSPrimitiveValue&gt;&amp;&amp; outset)
-    {
-        m_outset = WTFMove(outset);
-        m_canAdvance = true;
-        m_allowCommit = true;
-        m_allowImageSlice = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
-        m_allowImage = !m_image;
-        m_allowRepeat = !m_repeat;
-    }
-    void commitRepeat(RefPtr&lt;CSSValue&gt;&amp;&amp; repeat)
-    {
-        m_repeat = WTFMove(repeat);
-        m_canAdvance = true;
-        m_allowCommit = true;
-        m_allowRepeat = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
-        m_allowImageSlice = !m_imageSlice;
-        m_allowImage = !m_image;
-    }
-
-    Ref&lt;CSSValue&gt; commitWebKitBorderImage()
-    {
-        return createBorderImageValue(m_image.copyRef(), m_imageSlice.copyRef(), m_borderSlice.copyRef(), m_outset.copyRef(), m_repeat.copyRef());
-    }
-
-    void commitBorderImage(CSSParser&amp; parser, bool important)
-    {
-        commitBorderImageProperty(CSSPropertyBorderImageSource, parser, WTFMove(m_image), important);
-        commitBorderImageProperty(CSSPropertyBorderImageSlice, parser, m_imageSlice, important);
-        commitBorderImageProperty(CSSPropertyBorderImageWidth, parser, m_borderSlice, important);
-        commitBorderImageProperty(CSSPropertyBorderImageOutset, parser, m_outset, important);
-        commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, WTFMove(m_repeat), important);
-    }
-
-    void commitBorderImageProperty(CSSPropertyID propId, CSSParser&amp; parser, RefPtr&lt;CSSValue&gt;&amp;&amp; value, bool important)
-    {
-        if (value)
-            parser.addProperty(propId, value.releaseNonNull(), important);
-        else
-            parser.addProperty(propId, CSSValuePool::singleton().createImplicitInitialValue(), important, true);
-    }
-
-    bool m_canAdvance;
-
-    bool m_allowCommit;
-    bool m_allowImage;
-    bool m_allowImageSlice;
-    bool m_allowRepeat;
-    bool m_allowForwardSlashOperator;
-
-    bool m_requireWidth;
-    bool m_requireOutset;
-
-    RefPtr&lt;CSSValue&gt; m_image;
-    RefPtr&lt;CSSBorderImageSliceValue&gt; m_imageSlice;
-    RefPtr&lt;CSSPrimitiveValue&gt; m_borderSlice;
-    RefPtr&lt;CSSPrimitiveValue&gt; m_outset;
-
-    RefPtr&lt;CSSValue&gt; m_repeat;
-};
-
-bool CSSParser::parseBorderImage(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp; result, bool important)
-{
-    ShorthandScope scope(this, propId);
-    BorderImageParseContext context;
-    while (CSSParserValue* currentValue = m_valueList-&gt;current()) {
-        context.setCanAdvance(false);
-
-        if (!context.canAdvance() &amp;&amp; context.allowForwardSlashOperator() &amp;&amp; isForwardSlashOperator(*currentValue))
-            context.commitForwardSlashOperator();
-
-        if (!context.canAdvance() &amp;&amp; context.allowImage()) {
-            if (currentValue-&gt;unit == CSSPrimitiveValue::CSS_URI)
-                context.commitImage(CSSImageValue::create(completeURL(currentValue-&gt;string)));
-            else if (isGeneratedImageValue(*currentValue)) {
-                RefPtr&lt;CSSValue&gt; value;
-                if (parseGeneratedImage(*m_valueList, value))
-                    context.commitImage(WTFMove(value));
-                else
-                    return false;
-            } else if (isImageSetFunctionValue(*currentValue)) {
-                RefPtr&lt;CSSValue&gt; value = parseImageSet();
-                if (value)
-                    context.commitImage(value.releaseNonNull());
-                else
-                    return false;
-            } else if (currentValue-&gt;id == CSSValueNone)
-                context.commitImage(CSSValuePool::singleton().createIdentifierValue(CSSValueNone));
-        }
-
-        if (!context.canAdvance() &amp;&amp; context.allowImageSlice()) {
-            RefPtr&lt;CSSBorderImageSliceValue&gt; imageSlice;
-            if (parseBorderImageSlice(propId, imageSlice))
-                context.commitImageSlice(WTFMove(imageSlice));
-        }
-
-        if (!context.canAdvance() &amp;&amp; context.allowRepeat()) {
-            RefPtr&lt;CSSValue&gt; repeat;
-            if (parseBorderImageRepeat(repeat))
-                context.commitRepeat(WTFMove(repeat));
-        }
-
-        if (!context.canAdvance() &amp;&amp; context.requireWidth()) {
-            RefPtr&lt;CSSPrimitiveValue&gt; borderSlice;
-            if (parseBorderImageWidth(borderSlice))
-                context.commitBorderWidth(WTFMove(borderSlice));
-        }
-
-        if (!context.canAdvance() &amp;&amp; context.requireOutset()) {
-            RefPtr&lt;CSSPrimitiveValue&gt; borderOutset;
-            if (parseBorderImageOutset(borderOutset))
-                context.commitBorderOutset(WTFMove(borderOutset));
-        }
-
-        if (!context.canAdvance())
-            return false;
-
-        m_valueList-&gt;next();
-    }
-
-    if (context.allowCommit()) {
-        if (propId == CSSPropertyBorderImage)
-            context.commitBorderImage(*this, important);
-        else
-            // Need to fully commit as a single value.
-            result = context.commitWebKitBorderImage();
-        return true;
-    }
-
-    return false;
-}
-
-static bool isBorderImageRepeatKeyword(int id)
-{
-    return id == CSSValueStretch || id == CSSValueRepeat || id == CSSValueSpace || id == CSSValueRound;
-}
-
-bool CSSParser::parseBorderImageRepeat(RefPtr&lt;CSSValue&gt;&amp; result)
-{
-    RefPtr&lt;CSSPrimitiveValue&gt; firstValue;
-    RefPtr&lt;CSSPrimitiveValue&gt; secondValue;
-    CSSParserValue* val = m_valueList-&gt;current();
-    if (!val)
-        return false;
-    if (isBorderImageRepeatKeyword(val-&gt;id))
-        firstValue = CSSValuePool::singleton().createIdentifierValue(val-&gt;id);
-    else
-        return false;
-
-    val = m_valueList-&gt;next();
-    if (val) {
-        if (isBorderImageRepeatKeyword(val-&gt;id))
-            secondValue = CSSValuePool::singleton().createIdentifierValue(val-&gt;id);
-        else if (!inShorthand()) {
-            // If we're not parsing a shorthand then we are invalid.
-            return false;
-        } else {
-            // We need to rewind the value list, so that when its advanced we'll
-            // end up back at this value.
-            m_valueList-&gt;previous();
-            secondValue = firstValue;
-        }
-    } else
-        secondValue = firstValue;
-
-    result = createPrimitiveValuePair(firstValue.releaseNonNull(), secondValue.releaseNonNull());
-    return true;
-}
-
-class BorderImageSliceParseContext {
-public:
-    BorderImageSliceParseContext(CSSParser&amp; parser)
-    : m_parser(parser)
-    , m_allowNumber(true)
-    , m_allowFill(true)
-    , m_allowFinalCommit(false)
-    , m_fill(false)
-    { }
-
-    bool allowNumber() const { return m_allowNumber; }
-    bool allowFill() const { return m_allowFill; }
-    bool allowFinalCommit() const { return m_allowFinalCommit; }
-    CSSPrimitiveValue* top() const { return m_top.get(); }
-
-    void commitNumber(CSSParser::ValueWithCalculation&amp; valueWithCalculation)
-    {
-        auto primitiveValue = m_parser.createPrimitiveNumericValue(valueWithCalculation);
-        if (!m_top)
-            m_top = WTFMove(primitiveValue);
-        else if (!m_right)
-            m_right = WTFMove(primitiveValue);
-        else if (!m_bottom)
-            m_bottom = WTFMove(primitiveValue);
-        else {
-            ASSERT(!m_left);
-            m_left = WTFMove(primitiveValue);
-        }
-
-        m_allowNumber = !m_left;
-        m_allowFinalCommit = true;
-    }
-
-    void commitFill() { m_fill = true; m_allowFill = false; m_allowNumber = !m_top; }
-
-    Ref&lt;CSSBorderImageSliceValue&gt; commitBorderImageSlice()
-    {
-        // We need to clone and repeat values for any omissions.
-        ASSERT(m_top);
-        if (!m_right) {
-            m_right = m_top;
-            m_bottom = m_top;
-            m_left = m_top;
-        }
-        if (!m_bottom) {
-            m_bottom = m_top;
-            m_left = m_right;
-        }
-        if (!m_left)
-            m_left = m_right;
-
-        // Now build a rect value to hold all four of our primitive values.
-        auto quad = Quad::create();
-        quad-&gt;setTop(m_top.copyRef());
-        quad-&gt;setRight(m_right.copyRef());
-        quad-&gt;setBottom(m_bottom.copyRef());
-        quad-&gt;setLeft(m_left.copyRef());
-
-        // Make our new border image value now.
-        return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTFMove(quad)), m_fill);
-    }
-
-private:
-    CSSParser&amp; m_parser;
-
-    bool m_allowNumber;
-    bool m_allowFill;
-    bool m_allowFinalCommit;
-
-    RefPtr&lt;CSSPrimitiveValue&gt; m_top;
-    RefPtr&lt;CSSPrimitiveValue&gt; m_right;
-    RefPtr&lt;CSSPrimitiveValue&gt; m_bottom;
-    RefPtr&lt;CSSPrimitiveValue&gt; m_left;
-
-    bool m_fill;
-};
-
-bool CSSParser::parseBorderImageSlice(CSSPropertyID propId, RefPtr&lt;CSSBorderImageSliceValue&gt;&amp; result)
-{
-    BorderImageSliceParseContext context(*this);
-    CSSParserValue* value;
-    while ((value = m_valueList-&gt;current())) {
-        ValueWithCalculation valueWithCalculation(*value);
-        // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet.
-        if (context.allowNumber() &amp;&amp; !isCalculation(valueWithCalculation) &amp;&amp; validateUnit(valueWithCalculation, FInteger | FNonNeg | FPercent, CSSStrictMode)) {
-            context.commitNumber(valueWithCalculation);
-        } else if (context.allowFill() &amp;&amp; value-&gt;id == CSSValueFill)
-            context.commitFill();
-        else if (!inShorthand()) {
-            // If we're not parsing a shorthand then we are invalid.
-            return false;
-        } else {
-            if (context.allowFinalCommit()) {
-                // We're going to successfully parse, but we don't want to consume this token.
-                m_valueList-&gt;previous();
-            }
-            break;
-        }
-        m_valueList-&gt;next();
-    }
-
-    if (context.allowFinalCommit()) {
-        // FIXME: For backwards compatibility, -webkit-border-image, -webkit-mask-box-image and -webkit-box-reflect have to do a fill by default.
-        // FIXME: What do we do with -webkit-box-reflect and -webkit-mask-box-image? Probably just have to leave them filling...
-        if (propId == CSSPropertyWebkitBorderImage || propId == CSSPropertyWebkitMaskBoxImage || propId == CSSPropertyWebkitBoxReflect)
-            context.commitFill();
-
-        // Need to fully commit as a single value.
-        result = context.commitBorderImageSlice();
-        return true;
-    }
-
-    return false;
-}
-
-class BorderImageQuadParseContext {
-public:
-    BorderImageQuadParseContext(CSSParser&amp; parser)
-    : m_parser(parser)
-    , m_allowNumber(true)
-    , m_allowFinalCommit(false)
-    { }
-
-    bool allowNumber() const { return m_allowNumber; }
-    bool allowFinalCommit() const { return m_allowFinalCommit; }
-    CSSPrimitiveValue* top() const { return m_top.get(); }
-
-    void commitNumber(CSSParser::ValueWithCalculation&amp; valueWithCalculation)
-    {
-        RefPtr&lt;CSSPrimitiveValue&gt; primitiveValue;
-        if (valueWithCalculation.value().id == CSSValueAuto)
-            primitiveValue = CSSValuePool::singleton().createIdentifierValue(valueWithCalculation.value().id);
-        else
-            primitiveValue = m_parser.createPrimitiveNumericValue(valueWithCalculation);
-
-        if (!m_top)
-            m_top = WTFMove(primitiveValue);
-        else if (!m_right)
-            m_right = WTFMove(primitiveValue);
-        else if (!m_bottom)
-            m_bottom = WTFMove(primitiveValue);
-        else {
-            ASSERT(!m_left);
-            m_left = WTFMove(primitiveValue);
-        }
-
-        m_allowNumber = !m_left;
-        m_allowFinalCommit = true;
-    }
-
-    void setAllowFinalCommit() { m_allowFinalCommit = true; }
-    void setTop(RefPtr&lt;CSSPrimitiveValue&gt;&amp;&amp; val) { m_top = WTFMove(val); }
-
-    Ref&lt;CSSPrimitiveValue&gt; commitBorderImageQuad()
-    {
-        // We need to clone and repeat values for any omissions.
-        ASSERT(m_top);
-        if (!m_right) {
-            m_right = m_top;
-            m_bottom = m_top;
-            m_left = m_top;
-        }
-        if (!m_bottom) {
-            m_bottom = m_top;
-            m_left = m_right;
-        }
-        if (!m_left)
-            m_left = m_right;
-
-        // Now build a quad value to hold all four of our primitive values.
-        auto quad = Quad::create();
-        quad-&gt;setTop(m_top.copyRef());
-        quad-&gt;setRight(m_right.copyRef());
-        quad-&gt;setBottom(m_bottom.copyRef());
-        quad-&gt;setLeft(m_left.copyRef());
-
-        // Make our new value now.
-        return CSSValuePool::singleton().createValue(WTFMove(quad));
-    }
-
-private:
-    CSSParser&amp; m_parser;
-
-    bool m_allowNumber;
-    bool m_allowFinalCommit;
-
-    RefPtr&lt;CSSPrimitiveValue&gt; m_top;
-    RefPtr&lt;CSSPrimitiveValue&gt; m_right;
-    RefPtr&lt;CSSPrimitiveValue&gt; m_bottom;
-    RefPtr&lt;CSSPrimitiveValue&gt; m_left;
-};
-
-bool CSSParser::parseBorderImageQuad(Units validUnits, RefPtr&lt;CSSPrimitiveValue&gt;&amp; result)
-{
-    BorderImageQuadParseContext context(*this);
-    CSSParserValue* value;
-    while ((value = m_valueList-&gt;current())) {
-        ValueWithCalculation valueWithCalculation(*value);
-        if (context.allowNumber() &amp;&amp; (validateUnit(valueWithCalculation, validUnits, CSSStrictMode) || value-&gt;id == CSSValueAuto)) {
-            context.commitNumber(valueWithCalculation);
-        } else if (!inShorthand()) {
-            // If we're not parsing a shorthand then we are invalid.
-            return false;
-        } else {
-            if (context.allowFinalCommit())
-                m_valueList-&gt;previous(); // The shorthand loop will advance back to this point.
-            break;
-        }
-        m_valueList-&gt;next();
-    }
-
-    if (context.allowFinalCommit()) {
-        // Need to fully commit as a single value.
-        result = context.commitBorderImageQuad();
-        return true;
-    }
-    return false;
-}
-
-bool CSSParser::parseBorderImageWidth(RefPtr&lt;CSSPrimitiveValue&gt;&amp; result)
-{
-    return parseBorderImageQuad(FLength | FInteger | FNonNeg | FPercent, result);
-}
-
-bool CSSParser::parseBorderImageOutset(RefPtr&lt;CSSPrimitiveValue&gt;&amp; result)
-{
-    return parseBorderImageQuad(FLength | FInteger | FNonNeg, result);
-}
-
-bool CSSParser::parseBorderRadius(CSSPropertyID propId, bool important)
-{
-    unsigned num = m_valueList-&gt;size();
-    if (num &gt; 9)
-        return false;
-
-    ShorthandScope scope(this, propId);
-    RefPtr&lt;CSSPrimitiveValue&gt; radii[2][4];
-
-    unsigned indexAfterSlash = 0;
-    for (unsigned i = 0; i &lt; num; ++i) {
-        CSSParserValue&amp; value = *m_valueList-&gt;valueAt(i);
-        if (value.unit == CSSParserValue::Operator) {
-            if (value.iValue != '/')
-                return false;
-
-            if (!i || indexAfterSlash || i + 1 == num || num &gt; i + 5)
-                return false;
-
-            indexAfterSlash = i + 1;
-            completeBorderRadii(radii[0]);
-            continue;
-        }
-
-        if (i - indexAfterSlash &gt;= 4)
-            return false;
-
-        ValueWithCalculation valueWithCalculation(value);
-        if (!validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg))
-            return false;
-
-        auto radius = createPrimitiveNumericValue(valueWithCalculation);
-
-        if (!indexAfterSlash) {
-            radii[0][i] = WTFMove(radius);
-
-            // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-radius: l1 / l2;
-            if (num == 2 &amp;&amp; propId == CSSPropertyWebkitBorderRadius) {
-                indexAfterSlash = 1;
-                completeBorderRadii(radii[0]);
-            }
-        } else
-            radii[1][i - indexAfterSlash] = WTFMove(radius);
-    }
-
-    if (!indexAfterSlash) {
-        completeBorderRadii(radii[0]);
-        for (unsigned i = 0; i &lt; 4; ++i)
-            radii[1][i] = radii[0][i];
-    } else
-        completeBorderRadii(radii[1]);
-
-    ImplicitScope implicitScope(*this, PropertyImplicit);
-    addProperty(CSSPropertyBorderTopLeftRadius, createPrimitiveValuePair(WTFMove(radii[0][0]), WTFMove(radii[1][0])), important);
-    addProperty(CSSPropertyBorderTopRightRadius, createPrimitiveValuePair(WTFMove(radii[0][1]), WTFMove(radii[1][1])), important);
-    addProperty(CSSPropertyBorderBottomRightRadius, createPrimitiveValuePair(WTFMove(radii[0][2]), WTFMove(radii[1][2])), important);
-    addProperty(CSSPropertyBorderBottomLeftRadius, createPrimitiveValuePair(WTFMove(radii[0][3]), WTFMove(radii[1][3])), important);
-    return true;
-}
-
-bool CSSParser::parseAspectRatio(bool important)
-{
-    unsigned num = m_valueList-&gt;size();
-    if (num == 1) {
-        CSSValueID valueId = m_valueList-&gt;valueAt(0)-&gt;id;
-        if (valueId == CSSValueAuto || valueId == CSSValueFromDimensions || valueId == CSSValueFromIntrinsic) {
-            addProperty(CSSPropertyWebkitAspectRatio, CSSValuePool::singleton().createIdentifierValue(valueId), important);
-            return true;
-        }
-    }
-
-    if (num != 3)
-        return false;
-
-    CSSParserValue&amp; op = *m_valueList-&gt;valueAt(1);
-
-    if (!isForwardSlashOperator(op))
-        return false;
-
-    ValueWithCalculation lvalueWithCalculation(*m_valueList-&gt;valueAt(0));
-    ValueWithCalculation rvalueWithCalculation(*m_valueList-&gt;valueAt(2));
-    if (!validateUnit(lvalueWithCalculation, FNumber | FNonNeg) || !validateUnit(rvalueWithCalculation, FNumber | FNonNeg))
-        return false;
-
-    // FIXME: This doesn't handle calculated values.
-    if (!lvalueWithCalculation.value().fValue || !rvalueWithCalculation.value().fValue)
-        return false;
-
-    addProperty(CSSPropertyWebkitAspectRatio, CSSAspectRatioValue::create(narrowPrecisionToFloat(lvalueWithCalculation.value().fValue), narrowPrecisionToFloat(rvalueWithCalculation.value().fValue)), important);
-
-    return true;
-}
-
-bool CSSParser::parseCounter(CSSPropertyID propId, int defaultValue, bool important)
-{
-    enum { ID, VAL } state = ID;
-
-    auto list = CSSValueList::createCommaSeparated();
-    RefPtr&lt;CSSPrimitiveValue&gt; counterName;
-
-    while (true) {
-        CSSParserValue* value = m_valueList-&gt;current();
-        switch (state) {
-            case ID:
-                if (value &amp;&amp; value-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
-                    counterName = createPrimitiveStringValue(*value);
-                    state = VAL;
-                    m_valueList-&gt;next();
-                    continue;
-                }
-                break;
-            case VAL: {
-                int i = defaultValue;
-                if (value &amp;&amp; value-&gt;unit == CSSPrimitiveValue::CSS_NUMBER) {
-                    i = clampToInteger(value-&gt;fValue);
-                    m_valueList-&gt;next();
-                }
-
-                list-&gt;append(createPrimitiveValuePair(WTFMove(counterName),
-                    CSSValuePool::singleton().createValue(i, CSSPrimitiveValue::CSS_NUMBER)));
-                state = ID;
-                continue;
-            }
-        }
-        break;
-    }
-
-    if (list-&gt;length() &gt; 0) {
-        addProperty(propId, WTFMove(list), important);
-        return true;
-    }
-
-    return false;
-}
-
-// This should go away once we drop support for -webkit-gradient
-static RefPtr&lt;CSSPrimitiveValue&gt; parseDeprecatedGradientPoint(CSSParserValue&amp; value, bool horizontal)
-{
-    RefPtr&lt;CSSPrimitiveValue&gt; result;
-    if (value.unit == CSSPrimitiveValue::CSS_IDENT) {
-        if ((equalLettersIgnoringASCIICase(value, &quot;left&quot;) &amp;&amp; horizontal)
-            || (equalLettersIgnoringASCIICase(value, &quot;top&quot;) &amp;&amp; !horizontal))
-            result = CSSValuePool::singleton().createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE);
-        else if ((equalLettersIgnoringASCIICase(value, &quot;right&quot;) &amp;&amp; horizontal)
-            || (equalLettersIgnoringASCIICase(value, &quot;bottom&quot;) &amp;&amp; !horizontal))
-            result = CSSValuePool::singleton().createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE);
-        else if (equalLettersIgnoringASCIICase(value, &quot;center&quot;))
-            result = CSSValuePool::singleton().createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE);
-    } else if (value.unit == CSSPrimitiveValue::CSS_NUMBER || value.unit == CSSPrimitiveValue::CSS_PERCENTAGE)
-        result = CSSValuePool::singleton().createValue(value.fValue, static_cast&lt;CSSPrimitiveValue::UnitTypes&gt;(value.unit));
-    return result;
-}
-
-static bool parseDeprecatedGradientColorStop(CSSParser&amp; parser, CSSParserValue&amp; value, CSSGradientColorStop&amp; stop)
-{
-    if (value.unit != CSSParserValue::Function)
-        return false;
-
-    if (!equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;from(&quot;)
-        &amp;&amp; !equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;to(&quot;)
-        &amp;&amp; !equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;color-stop(&quot;))
-        return false;
-
-    CSSParserValueList* args = value.function-&gt;args.get();
-    if (!args)
-        return false;
-
-    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;from(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;to(&quot;)) {
-        // The &quot;from&quot; and &quot;to&quot; stops expect 1 argument.
-        if (args-&gt;size() != 1)
-            return false;
-
-        if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;from(&quot;))
-            stop.m_position = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_NUMBER);
-        else
-            stop.m_position = CSSValuePool::singleton().createValue(1, CSSPrimitiveValue::CSS_NUMBER);
-
-        CSSValueID id = args-&gt;current()-&gt;id;
-        if (id == CSSValueWebkitText || CSSParser::isValidSystemColorValue(id) || id == CSSValueMenu)
-            stop.m_color = CSSValuePool::singleton().createIdentifierValue(id);
-        else
-            stop.m_color = parser.parseColor(args-&gt;current());
-        if (!stop.m_color)
-            return false;
-    }
-
-    // The &quot;color-stop&quot; function expects 3 arguments.
-    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;color-stop(&quot;)) {
-        if (args-&gt;size() != 3)
-            return false;
-
-        CSSParserValue* stopArg = args-&gt;current();
-        if (stopArg-&gt;unit == CSSPrimitiveValue::CSS_PERCENTAGE)
-            stop.m_position = CSSValuePool::singleton().createValue(stopArg-&gt;fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
-        else if (stopArg-&gt;unit == CSSPrimitiveValue::CSS_NUMBER)
-            stop.m_position = CSSValuePool::singleton().createValue(stopArg-&gt;fValue, CSSPrimitiveValue::CSS_NUMBER);
-        else
-            return false;
-
-        stopArg = args-&gt;next();
-        if (stopArg-&gt;unit != CSSParserValue::Operator || stopArg-&gt;iValue != ',')
-            return false;
-
-        stopArg = args-&gt;next();
-        CSSValueID id = stopArg-&gt;id;
-        if (id == CSSValueWebkitText || CSSParser::isValidSystemColorValue(id) || id == CSSValueMenu)
-            stop.m_color = CSSValuePool::singleton().createIdentifierValue(id);
-        else
-            stop.m_color = parser.parseColor(stopArg);
-        if (!stop.m_color)
-            return false;
-    }
-
-    return true;
-}
-
-bool CSSParser::parseDeprecatedGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient)
-{
-    // Walk the arguments.
-    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
-    if (!args || args-&gt;size() == 0)
-        return false;
-
-    // The first argument is the gradient type.  It is an identifier.
-    CSSGradientType gradientType;
-    CSSParserValue* argument = args-&gt;current();
-    if (!argument || argument-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-        return false;
-    if (equalLettersIgnoringASCIICase(*argument, &quot;linear&quot;))
-        gradientType = CSSDeprecatedLinearGradient;
-    else if (equalLettersIgnoringASCIICase(*argument, &quot;radial&quot;))
-        gradientType = CSSDeprecatedRadialGradient;
-    else
-        return false;
-
-    RefPtr&lt;CSSGradientValue&gt; result;
-    switch (gradientType) {
-    case CSSDeprecatedLinearGradient:
-        result = CSSLinearGradientValue::create(NonRepeating, gradientType);
-        break;
-    case CSSDeprecatedRadialGradient:
-        result = CSSRadialGradientValue::create(NonRepeating, gradientType);
-        break;
-    default:
-        // The rest of the gradient types shouldn't appear here.
-        ASSERT_NOT_REACHED();
-    }
-
-    // Comma.
-    argument = args-&gt;next();
-    if (!isComma(argument))
-        return false;
-
-    // Next comes the starting point for the gradient as an x y pair.  There is no
-    // comma between the x and the y values.
-    // First X.  It can be left, right, number or percent.
-    argument = args-&gt;next();
-    if (!argument)
-        return false;
-    RefPtr&lt;CSSPrimitiveValue&gt; point = parseDeprecatedGradientPoint(*argument, true);
-    if (!point)
-        return false;
-    result-&gt;setFirstX(point.releaseNonNull());
-
-    // First Y.  It can be top, bottom, number or percent.
-    argument = args-&gt;next();
-    if (!argument)
-        return false;
-    point = parseDeprecatedGradientPoint(*argument, false);
-    if (!point)
-        return false;
-    result-&gt;setFirstY(point.releaseNonNull());
-
-    // Comma after the first point.
-    argument = args-&gt;next();
-    if (!isComma(argument))
-        return false;
-
-    // For radial gradients only, we now expect a numeric radius.
-    if (gradientType == CSSDeprecatedRadialGradient) {
-        argument = args-&gt;next();
-        // FIXME: This does not handle calculation values.
-        if (!argument || argument-&gt;unit != CSSPrimitiveValue::CSS_NUMBER)
-            return false;
-        ValueWithCalculation argumentWithCalculation(*argument);
-        downcast&lt;CSSRadialGradientValue&gt;(*result).setFirstRadius(createPrimitiveNumericValue(argumentWithCalculation));
-
-        // Comma after the first radius.
-        argument = args-&gt;next();
-        if (!isComma(argument))
-            return false;
-    }
-
-    // Next is the ending point for the gradient as an x, y pair.
-    // Second X.  It can be left, right, number or percent.
-    argument = args-&gt;next();
-    if (!argument)
-        return false;
-    point = parseDeprecatedGradientPoint(*argument, true);
-    if (!point)
-        return false;
-    result-&gt;setSecondX(point.releaseNonNull());
-
-    // Second Y.  It can be top, bottom, number or percent.
-    argument = args-&gt;next();
-    if (!argument)
-        return false;
-    point = parseDeprecatedGradientPoint(*argument, false);
-    if (!point)
-        return false;
-    result-&gt;setSecondY(point.releaseNonNull());
-
-    // For radial gradients only, we now expect the second radius.
-    if (gradientType == CSSDeprecatedRadialGradient) {
-        // Comma after the second point.
-        argument = args-&gt;next();
-        if (!isComma(argument))
-            return false;
-
-        argument = args-&gt;next();
-        // FIXME: This does not handle calculation values.
-        if (!argument || argument-&gt;unit != CSSPrimitiveValue::CSS_NUMBER)
-            return false;
-        ValueWithCalculation argumentWithCalculation(*argument);
-        downcast&lt;CSSRadialGradientValue&gt;(*result).setSecondRadius(createPrimitiveNumericValue(argumentWithCalculation));
-    }
-
-    // We now will accept any number of stops (0 or more).
-    argument = args-&gt;next();
-    while (argument) {
-        // Look for the comma before the next stop.
-        if (!isComma(argument))
-            return false;
-
-        // Now examine the stop itself.
-        argument = args-&gt;next();
-        if (!argument)
-            return false;
-
-        // The function name needs to be one of &quot;from&quot;, &quot;to&quot;, or &quot;color-stop.&quot;
-        CSSGradientColorStop stop;
-        if (!parseDeprecatedGradientColorStop(*this, *argument, stop))
-            return false;
-        result-&gt;addStop(stop);
-
-        // Advance
-        argument = args-&gt;next();
-    }
-
-    gradient = WTFMove(result);
-    return true;
-}
-
-static RefPtr&lt;CSSPrimitiveValue&gt; valueFromSideKeyword(CSSParserValue&amp; value, bool&amp; isHorizontal)
-{
-    if (value.unit != CSSPrimitiveValue::CSS_IDENT)
-        return nullptr;
-
-    switch (value.id) {
-        case CSSValueLeft:
-        case CSSValueRight:
-            isHorizontal = true;
-            break;
-        case CSSValueTop:
-        case CSSValueBottom:
-            isHorizontal = false;
-            break;
-        default:
-            return nullptr;
-    }
-    return CSSValuePool::singleton().createIdentifierValue(value.id);
-}
-
-static RefPtr&lt;CSSPrimitiveValue&gt; parseGradientColorOrKeyword(CSSParser&amp; parser, CSSParserValue&amp; value)
-{
-    CSSValueID id = value.id;
-    if (id == CSSValueWebkitText || CSSParser::isValidSystemColorValue(id) || id == CSSValueMenu || id == CSSValueCurrentcolor)
-        return CSSValuePool::singleton().createIdentifierValue(id);
-
-    return parser.parseColor(&amp;value);
-}
-
-bool CSSParser::parseDeprecatedLinearGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient, CSSGradientRepeat repeating)
-{
-    auto result = CSSLinearGradientValue::create(repeating, CSSPrefixedLinearGradient);
-
-    // Walk the arguments.
-    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
-    if (!args || !args-&gt;size())
-        return false;
-
-    CSSParserValue* argument = args-&gt;current();
-    if (!argument)
-        return false;
-    ValueWithCalculation argumentWithCalculation(*argument);
-
-    bool expectComma = false;
-    // Look for angle.
-    if (validateUnit(argumentWithCalculation, FAngle, CSSStrictMode)) {
-        result-&gt;setAngle(createPrimitiveNumericValue(argumentWithCalculation));
-
-        args-&gt;next();
-        expectComma = true;
-    } else {
-        // Look one or two optional keywords that indicate a side or corner.
-        RefPtr&lt;CSSPrimitiveValue&gt; startX, startY;
-        bool isHorizontal = false;
-        if (RefPtr&lt;CSSPrimitiveValue&gt; location = valueFromSideKeyword(*argument, isHorizontal)) {
-            if (isHorizontal)
-                startX = WTFMove(location);
-            else
-                startY = WTFMove(location);
-
-            if ((argument = args-&gt;next())) {
-                if ((location = valueFromSideKeyword(*argument, isHorizontal))) {
-                    if (isHorizontal) {
-                        if (startX)
-                            return false;
-                        startX = WTFMove(location);
-                    } else {
-                        if (startY)
-                            return false;
-                        startY = WTFMove(location);
-                    }
-
-                    args-&gt;next();
-                }
-            }
-
-            expectComma = true;
-        }
-
-        if (!startX &amp;&amp; !startY)
-            startY = CSSValuePool::singleton().createIdentifierValue(CSSValueTop);
-
-        result-&gt;setFirstX(WTFMove(startX));
-        result-&gt;setFirstY(WTFMove(startY));
-    }
-
-    if (!parseGradientColorStops(*args, result, expectComma))
-        return false;
-
-    if (!result-&gt;stopCount())
-        return false;
-
-    gradient = WTFMove(result);
-    return true;
-}
-
-bool CSSParser::parseDeprecatedRadialGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient, CSSGradientRepeat repeating)
-{
-    auto result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient);
-
-    // Walk the arguments.
-    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
-    if (!args || !args-&gt;size())
-        return false;
-
-    CSSParserValue* argument = args-&gt;current();
-    if (!argument)
-        return false;
-
-    bool expectComma = false;
-
-    // Optional background-position
-    RefPtr&lt;CSSPrimitiveValue&gt; centerX;
-    RefPtr&lt;CSSPrimitiveValue&gt; centerY;
-    // parse2ValuesFillPosition advances the args next pointer.
-    parse2ValuesFillPosition(*args, centerX, centerY);
-    argument = args-&gt;current();
-    if (!argument)
-        return false;
-
-    if (centerX || centerY) {
-        // Comma
-        if (!isComma(argument))
-            return false;
-
-        argument = args-&gt;next();
-        if (!argument)
-            return false;
-    }
-
-    result-&gt;setFirstX(centerX.copyRef());
-    result-&gt;setSecondX(WTFMove(centerX));
-    // CSS3 radial gradients always share the same start and end point.
-    result-&gt;setFirstY(centerY.copyRef());
-    result-&gt;setSecondY(WTFMove(centerY));
-
-    RefPtr&lt;CSSPrimitiveValue&gt; shapeValue;
-    RefPtr&lt;CSSPrimitiveValue&gt; sizeValue;
-
-    // Optional shape and/or size in any order.
-    for (int i = 0; i &lt; 2; ++i) {
-        if (argument-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-            break;
-
-        bool foundValue = false;
-        switch (argument-&gt;id) {
-        case CSSValueCircle:
-        case CSSValueEllipse:
-            shapeValue = CSSValuePool::singleton().createIdentifierValue(argument-&gt;id);
-            foundValue = true;
-            break;
-        case CSSValueClosestSide:
-        case CSSValueClosestCorner:
-        case CSSValueFarthestSide:
-        case CSSValueFarthestCorner:
-        case CSSValueContain:
-        case CSSValueCover:
-            sizeValue = CSSValuePool::singleton().createIdentifierValue(argument-&gt;id);
-            foundValue = true;
-            break;
-        default:
-            break;
-        }
-
-        if (foundValue) {
-            argument = args-&gt;next();
-            if (!argument)
-                return false;
-
-            expectComma = true;
-        }
-    }
-
-    result-&gt;setShape(shapeValue.copyRef());
-    result-&gt;setSizingBehavior(sizeValue.copyRef());
-
-    // Or, two lengths or percentages
-    RefPtr&lt;CSSPrimitiveValue&gt; horizontalSize;
-    RefPtr&lt;CSSPrimitiveValue&gt; verticalSize;
-
-    if (!shapeValue &amp;&amp; !sizeValue) {
-        ValueWithCalculation hSizeWithCalculation(*argument);
-        if (validateUnit(hSizeWithCalculation, FLength | FPercent)) {
-            horizontalSize = createPrimitiveNumericValue(hSizeWithCalculation);
-            argument = args-&gt;next();
-            if (!argument)
-                return false;
-
-            expectComma = true;
-        }
-
-        ValueWithCalculation vSizeWithCalculation(*argument);
-        if (validateUnit(vSizeWithCalculation, FLength | FPercent)) {
-            verticalSize = createPrimitiveNumericValue(vSizeWithCalculation);
-
-            argument = args-&gt;next();
-            if (!argument)
-                return false;
-            expectComma = true;
-        }
-    }
-
-    // Must have neither or both.
-    if (!horizontalSize != !verticalSize)
-        return false;
-
-    result-&gt;setEndHorizontalSize(WTFMove(horizontalSize));
-    result-&gt;setEndVerticalSize(WTFMove(verticalSize));
-
-    if (!parseGradientColorStops(*args, result, expectComma))
-        return false;
-
-    gradient = WTFMove(result);
-    return true;
-}
-
-bool CSSParser::parseLinearGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient, CSSGradientRepeat repeating)
-{
-    auto result = CSSLinearGradientValue::create(repeating, CSSLinearGradient);
-
-    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
-    if (!args || !args-&gt;size())
-        return false;
-
-    if (!args-&gt;current())
-        return false;
-
-    ValueWithCalculation firstArgumentWithCalculation(*args-&gt;current());
-
-    bool expectComma = false;
-    // Look for angle.
-    if (validateUnit(firstArgumentWithCalculation, FAngle, CSSStrictMode)) {
-        result-&gt;setAngle(createPrimitiveNumericValue(firstArgumentWithCalculation));
-
-        args-&gt;next();
-        expectComma = true;
-    } else if (firstArgumentWithCalculation.value().unit == CSSPrimitiveValue::CSS_IDENT &amp;&amp; equalLettersIgnoringASCIICase(firstArgumentWithCalculation, &quot;to&quot;)) {
-        // to [ [left | right] || [top | bottom] ]
-        CSSParserValue* nextArgument = args-&gt;next();
-        if (!nextArgument)
-            return false;
-
-        bool isHorizontal = false;
-        RefPtr&lt;CSSPrimitiveValue&gt; location = valueFromSideKeyword(*nextArgument, isHorizontal);
-        if (!location)
-            return false;
-
-        RefPtr&lt;CSSPrimitiveValue&gt; endX, endY;
-        if (isHorizontal)
-            endX = WTFMove(location);
-        else
-            endY = WTFMove(location);
-
-        nextArgument = args-&gt;next();
-        if (!nextArgument)
-            return false;
-
-        location = valueFromSideKeyword(*nextArgument, isHorizontal);
-        if (location) {
-            if (isHorizontal) {
-                if (endX)
-                    return false;
-                endX = WTFMove(location);
-            } else {
-                if (endY)
-                    return false;
-                endY = WTFMove(location);
-            }
-
-            args-&gt;next();
-        }
-
-        expectComma = true;
-        result-&gt;setFirstX(WTFMove(endX));
-        result-&gt;setFirstY(WTFMove(endY));
-    }
-
-    if (!parseGradientColorStops(*args, result, expectComma))
-        return false;
-
-    if (!result-&gt;stopCount())
-        return false;
-
-    gradient = WTFMove(result);
-    return true;
-}
-
-bool CSSParser::parseRadialGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient, CSSGradientRepeat repeating)
-{
-    auto result = CSSRadialGradientValue::create(repeating, CSSRadialGradient);
-
-    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
-    if (!args || !args-&gt;size())
-        return false;
-
-    CSSParserValue* argument = args-&gt;current();
-    if (!argument)
-        return false;
-
-    bool expectComma = false;
-
-    RefPtr&lt;CSSPrimitiveValue&gt; shapeValue;
-    RefPtr&lt;CSSPrimitiveValue&gt; sizeValue;
-    RefPtr&lt;CSSPrimitiveValue&gt; horizontalSize;
-    RefPtr&lt;CSSPrimitiveValue&gt; verticalSize;
-
-    // First part of grammar, the size/shape clause:
-    // [ circle || &lt;length&gt; ] |
-    // [ ellipse || [ &lt;length&gt; | &lt;percentage&gt; ]{2} ] |
-    // [ [ circle | ellipse] || &lt;size-keyword&gt; ]
-    for (int i = 0; i &lt; 3; ++i) {
-        ValueWithCalculation argumentWithCalculation(*argument);
-        if (argument-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
-            bool badIdent = false;
-            switch (argument-&gt;id) {
-            case CSSValueCircle:
-            case CSSValueEllipse:
-                if (shapeValue)
-                    return false;
-                shapeValue = CSSValuePool::singleton().createIdentifierValue(argument-&gt;id);
-                break;
-            case CSSValueClosestSide:
-            case CSSValueClosestCorner:
-            case CSSValueFarthestSide:
-            case CSSValueFarthestCorner:
-                if (sizeValue || horizontalSize)
-                    return false;
-                sizeValue = CSSValuePool::singleton().createIdentifierValue(argument-&gt;id);
-                break;
-            default:
-                badIdent = true;
-            }
-
-            if (badIdent)
-                break;
-
-            argument = args-&gt;next();
-            if (!argument)
-                return false;
-        } else if (validateUnit(argumentWithCalculation, FLength | FPercent)) {
-
-            if (sizeValue || horizontalSize)
-                return false;
-            horizontalSize = createPrimitiveNumericValue(argumentWithCalculation);
-
-            argument = args-&gt;next();
-            if (!argument)
-                return false;
-
-            ValueWithCalculation vSizeWithCalculation(*argument);
-            if (validateUnit(vSizeWithCalculation, FLength | FPercent)) {
-                verticalSize = createPrimitiveNumericValue(vSizeWithCalculation);
-                ++i;
-                argument = args-&gt;next();
-                if (!argument)
-                    return false;
-            }
-        } else
-            break;
-    }
-
-    // You can specify size as a keyword or a length/percentage, not both.
-    if (sizeValue &amp;&amp; horizontalSize)
-        return false;
-    // Circles must have 0 or 1 lengths.
-    if (shapeValue &amp;&amp; shapeValue-&gt;getValueID() == CSSValueCircle &amp;&amp; verticalSize)
-        return false;
-    // Ellipses must have 0 or 2 length/percentages.
-    if (shapeValue &amp;&amp; shapeValue-&gt;getValueID() == CSSValueEllipse &amp;&amp; horizontalSize &amp;&amp; !verticalSize)
-        return false;
-    // If there's only one size, it must be a length.
-    if (!verticalSize &amp;&amp; horizontalSize &amp;&amp; horizontalSize-&gt;isPercentage())
-        return false;
-
-    result-&gt;setShape(shapeValue.copyRef());
-    result-&gt;setSizingBehavior(sizeValue.copyRef());
-    result-&gt;setEndHorizontalSize(horizontalSize.copyRef());
-    result-&gt;setEndVerticalSize(verticalSize.copyRef());
-
-    // Second part of grammar, the center-position clause:
-    // at &lt;position&gt;
-    RefPtr&lt;CSSPrimitiveValue&gt; centerX;
-    RefPtr&lt;CSSPrimitiveValue&gt; centerY;
-    if (argument-&gt;unit == CSSPrimitiveValue::CSS_IDENT &amp;&amp; equalLettersIgnoringASCIICase(*argument, &quot;at&quot;)) {
-        argument = args-&gt;next();
-        if (!argument)
-            return false;
-
-        parseFillPosition(*args, centerX, centerY);
-        if (!(centerX &amp;&amp; centerY))
-            return false;
-
-        argument = args-&gt;current();
-        if (!argument)
-            return false;
-
-        result-&gt;setFirstX(centerX.copyRef());
-        result-&gt;setFirstY(centerY.copyRef());
-        // Right now, CSS radial gradients have the same start and end centers.
-        result-&gt;setSecondX(centerX.copyRef());
-        result-&gt;setSecondY(centerY.copyRef());
-    }
-
-    if (shapeValue || sizeValue || horizontalSize || centerX || centerY)
-        expectComma = true;
-
-    if (!parseGradientColorStops(*args, result, expectComma))
-        return false;
-
-    gradient = WTFMove(result);
-    return true;
-}
-
-bool CSSParser::parseGradientColorStops(CSSParserValueList&amp; valueList, CSSGradientValue&amp; gradient, bool expectComma)
-{
-    CSSParserValue* value = valueList.current();
-    bool previousStopWasMidpoint = true;
-
-    // Now look for color stops.
-    while (value) {
-        // Look for the comma before the next stop.
-        if (expectComma) {
-            if (!isComma(value))
-                return false;
-
-            value = valueList.next();
-            if (!value)
-                return false;
-        }
-
-        // &lt;color-stop&gt; = &lt;color&gt; [ &lt;percentage&gt; | &lt;length&gt; ]?
-        CSSGradientColorStop stop;
-        stop.m_color = parseGradientColorOrKeyword(*this, *value);
-        if (!stop.m_color) {
-            if (previousStopWasMidpoint) // 2 midpoints in a row is not allowed. This also catches starting with a midpoint.
-                return false;
-
-            stop.isMidpoint = true;
-        } else
-            value = valueList.next();
-
-        previousStopWasMidpoint = stop.isMidpoint;
-
-        if (value) {
-            ValueWithCalculation valueWithCalculation(*value);
-            if (validateUnit(valueWithCalculation, FLength | FPercent)) {
-                stop.m_position = createPrimitiveNumericValue(valueWithCalculation);
-                value = valueList.next();
-            } else if (stop.isMidpoint)
-                return false;
-        }
-
-        gradient.addStop(stop);
-        expectComma = true;
-    }
-
-    // We can't end on a midpoint.
-    if (previousStopWasMidpoint)
-        return false;
-
-    // Must have 2 or more stops to be valid.
-    return gradient.stopCount() &gt;= 2;
-}
-
-bool CSSParser::isGeneratedImageValue(CSSParserValue&amp; value) const
-{
-    if (value.unit != CSSParserValue::Function)
-        return false;
-
-    return equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-gradient(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-linear-gradient(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;linear-gradient(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-repeating-linear-gradient(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;repeating-linear-gradient(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-radial-gradient(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;radial-gradient(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-repeating-radial-gradient(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;repeating-radial-gradient(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-canvas(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;cross-fade(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-cross-fade(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;filter(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-filter(&quot;)
-        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-named-image(&quot;);
-}
-
-bool CSSParser::parseGeneratedImage(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; value)
-{
-    CSSParserValue&amp; parserValue = *valueList.current();
-
-    if (parserValue.unit != CSSParserValue::Function)
-        return false;
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-gradient(&quot;))
-        return parseDeprecatedGradient(valueList, value);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-linear-gradient(&quot;))
-        return parseDeprecatedLinearGradient(valueList, value, NonRepeating);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;linear-gradient(&quot;))
-        return parseLinearGradient(valueList, value, NonRepeating);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-repeating-linear-gradient(&quot;))
-        return parseDeprecatedLinearGradient(valueList, value, Repeating);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;repeating-linear-gradient(&quot;))
-        return parseLinearGradient(valueList, value, Repeating);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-radial-gradient(&quot;))
-        return parseDeprecatedRadialGradient(valueList, value, NonRepeating);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;radial-gradient(&quot;))
-        return parseRadialGradient(valueList, value, NonRepeating);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-repeating-radial-gradient(&quot;))
-        return parseDeprecatedRadialGradient(valueList, value, Repeating);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;repeating-radial-gradient(&quot;))
-        return parseRadialGradient(valueList, value, Repeating);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-canvas(&quot;))
-        return parseCanvas(valueList, value);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-cross-fade(&quot;))
-        return parseCrossfade(valueList, value, true);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;cross-fade(&quot;))
-        return parseCrossfade(valueList, value, false);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;filter(&quot;) || equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-filter(&quot;))
-        return parseFilterImage(valueList, value);
-
-    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-named-image(&quot;))
-        return parseNamedImage(valueList, value);
-
-    return false;
-}
-
-bool CSSParser::parseFilterImage(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; filter)
-{
-    // Walk the arguments.
-    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
-    if (!args)
-        return false;
-    CSSParserValue* value = args-&gt;current();
-    if (!value)
-        return false;
-
-    // The first argument is the image. It is a fill image.
-    RefPtr&lt;CSSValue&gt; imageValue;
-    if (!parseFillImage(*args, imageValue)) {
-        if (value-&gt;unit == CSSPrimitiveValue::CSS_STRING)
-            imageValue = CSSImageValue::create(completeURL(value-&gt;string));
-        else
-            return false;
-    }
-
-    value = args-&gt;next();
-
-    // Skip a comma
-    if (!isComma(value))
-        return false;
-    value = args-&gt;next();
-
-    RefPtr&lt;CSSValueList&gt; filterValue;
-    if (!value || !parseFilter(*args, filterValue))
-        return false;
-    value = args-&gt;next();
-
-    filter = CSSFilterImageValue::create(imageValue.releaseNonNull(), filterValue.releaseNonNull());
-
-    return true;
-}
-
-bool CSSParser::parseCrossfade(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; crossfade, bool prefixed)
-{
-    // Walk the arguments.
-    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
-    if (!args || args-&gt;size() != 5)
-        return false;
-
-    CSSParserValue* argument = args-&gt;current();
-
-    // The first argument is the &quot;from&quot; image. It is a fill image.
-    RefPtr&lt;CSSValue&gt; fromImageValue;
-    if (!argument || !parseFillImage(*args, fromImageValue))
-        return false;
-    argument = args-&gt;next();
-
-    // Skip a comma
-    if (!isComma(argument))
-        return false;
-    argument = args-&gt;next();
-
-    // The second argument is the &quot;to&quot; image. It is a fill image.
-    RefPtr&lt;CSSValue&gt; toImageValue;
-    if (!argument || !parseFillImage(*args, toImageValue))
-        return false;
-    argument = args-&gt;next();
-
-    // Skip a comma
-    if (!isComma(argument))
-        return false;
-    argument = args-&gt;next();
-
-    // The third argument is the crossfade value. It is a percentage or a fractional number.
-    if (!argument)
-        return false;
-    
-    RefPtr&lt;CSSPrimitiveValue&gt; percentage;
-    if (argument-&gt;unit == CSSPrimitiveValue::CSS_PERCENTAGE)
-        percentage = CSSValuePool::singleton().createValue(clampTo&lt;double&gt;(argument-&gt;fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
-    else if (argument-&gt;unit == CSSPrimitiveValue::CSS_NUMBER)
-        percentage = CSSValuePool::singleton().createValue(clampTo&lt;double&gt;(argument-&gt;fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
-    else
-        return false;
-
-    crossfade = CSSCrossfadeValue::create(fromImageValue.releaseNonNull(), toImageValue.releaseNonNull(), percentage.releaseNonNull(), prefixed);
-
-    return true;
-}
-
-bool CSSParser::parseCanvas(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; canvas)
-{
-    // Walk the arguments.
-    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
-    if (!args || args-&gt;size() != 1)
-        return false;
-
-    // The first argument is the canvas name.  It is an identifier.
-    CSSParserValue* value = args-&gt;current();
-    if (!value || value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-        return false;
-
-    canvas = CSSCanvasValue::create(value-&gt;string);
-    return true;
-}
-
-bool CSSParser::parseNamedImage(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; namedImage)
-{
-    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
-    if (!args || args-&gt;size() != 1)
-        return false;
-
-    // The only argument is the image name.
-    CSSParserValue* value = args-&gt;current();
-    if (!value || value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-        return false;
-
-    namedImage = CSSNamedImageValue::create(value-&gt;string);
-    return true;
-}
-
-#if ENABLE(CSS_IMAGE_RESOLUTION)
-RefPtr&lt;CSSValueList&gt; CSSParser::parseImageResolution()
-{
-    auto list = CSSValueList::createSpaceSeparated();
-    bool haveResolution = false;
-    bool haveFromImage = false;
-    bool haveSnap = false;
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    while (value) {
-        ValueWithCalculation valueWithCalculation(*value);
-        if (!haveFromImage &amp;&amp; value-&gt;id == CSSValueFromImage) {
-            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
-            haveFromImage = true;
-        } else if (!haveSnap &amp;&amp; value-&gt;id == CSSValueSnap) {
-            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
-            haveSnap = true;
-        } else if (!haveResolution &amp;&amp; validateUnit(valueWithCalculation, FResolution | FNonNeg) &amp;&amp; value-&gt;fValue &gt; 0) {
-            list-&gt;append(createPrimitiveNumericValue(valueWithCalculation));
-            haveResolution = true;
-        } else
-            return nullptr;
-        value = m_valueList-&gt;next();
-    }
-    if (!list-&gt;length())
-        return nullptr;
-    if (!haveFromImage &amp;&amp; !haveResolution)
-        return nullptr;
-    return WTFMove(list);
-}
-#endif
-
-RefPtr&lt;CSSImageSetValue&gt; CSSParser::parseImageSet()
-{
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    ASSERT(value.unit == CSSParserValue::Function);
-
-    CSSParserValueList* functionArgs = value.function-&gt;args.get();
-    if (!functionArgs || !functionArgs-&gt;size() || !functionArgs-&gt;current())
-        return nullptr;
-
-    auto imageSet = CSSImageSetValue::create();
-    CSSParserValue* arg = functionArgs-&gt;current();
-    while (arg) {
-        if (arg-&gt;unit != CSSPrimitiveValue::CSS_URI)
-            return nullptr;
-
-        imageSet-&gt;append(CSSImageValue::create(completeURL(arg-&gt;string)));
-        arg = functionArgs-&gt;next();
-        if (!arg || arg-&gt;unit != CSSPrimitiveValue::CSS_DIMENSION)
-            return nullptr;
-
-        double imageScaleFactor = 0;
-        const String&amp; string = arg-&gt;string;
-        unsigned length = string.length();
-        if (!length)
-            return nullptr;
-        if (string.is8Bit()) {
-            const LChar* start = string.characters8();
-            parseDouble(start, start + length, 'x', imageScaleFactor);
-        } else {
-            const UChar* start = string.characters16();
-            parseDouble(start, start + length, 'x', imageScaleFactor);
-        }
-        if (imageScaleFactor &lt;= 0)
-            return nullptr;
-        imageSet-&gt;append(CSSValuePool::singleton().createValue(imageScaleFactor, CSSPrimitiveValue::CSS_NUMBER));
-
-        // If there are no more arguments, we're done.
-        arg = functionArgs-&gt;next();
-        if (!arg)
-            break;
-
-        // If there are more arguments, they should be after a comma.
-        if (!isComma(arg))
-            return nullptr;
-
-        // Skip the comma and move on to the next argument.
-        arg = functionArgs-&gt;next();
-    }
-
-    return WTFMove(imageSet);
-}
-
-class TransformOperationInfo {
-public:
-    TransformOperationInfo(const CSSParserString&amp; name)
-        : m_type(WebKitCSSTransformValue::UnknownTransformOperation)
-        , m_argCount(1)
-        , m_allowSingleArgument(false)
-        , m_unit(CSSParser::FUnknown)
-    {
-        const UChar* characters;
-        unsigned nameLength = name.length();
-
-        const unsigned longestNameLength = 12;
-        UChar characterBuffer[longestNameLength];
-        if (name.is8Bit()) {
-            unsigned length = std::min(longestNameLength, nameLength);
-            const LChar* characters8 = name.characters8();
-            for (unsigned i = 0; i &lt; length; ++i)
-                characterBuffer[i] = characters8[i];
-            characters = characterBuffer;
-        } else
-            characters = name.characters16();
-
-        switch (nameLength) {
-        case 5:
-            // Valid name: skew(.
-            if (((characters[0] == 's') || (characters[0] == 'S'))
-                &amp; ((characters[1] == 'k') || (characters[1] == 'K'))
-                &amp; ((characters[2] == 'e') || (characters[2] == 'E'))
-                &amp; ((characters[3] == 'w') || (characters[3] == 'W'))
-                &amp; (characters[4] == '(')) {
-                m_unit = CSSParser::FAngle;
-                m_type = WebKitCSSTransformValue::SkewTransformOperation;
-                m_allowSingleArgument = true;
-                m_argCount = 3;
-            }
-            break;
-        case 6:
-            // Valid names: skewx(, skewy(, scale(.
-            if ((characters[1] == 'c') || (characters[1] == 'C')) {
-                if (((characters[0] == 's') || (characters[0] == 'S'))
-                    &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
-                    &amp; ((characters[3] == 'l') || (characters[3] == 'L'))
-                    &amp; ((characters[4] == 'e') || (characters[4] == 'E'))
-                    &amp; (characters[5] == '(')) {
-                    m_unit = CSSParser::FNumber;
-                    m_type = WebKitCSSTransformValue::ScaleTransformOperation;
-                    m_allowSingleArgument = true;
-                    m_argCount = 3;
-                }
-            } else if (((characters[0] == 's') || (characters[0] == 'S'))
-                       &amp; ((characters[1] == 'k') || (characters[1] == 'K'))
-                       &amp; ((characters[2] == 'e') || (characters[2] == 'E'))
-                       &amp; ((characters[3] == 'w') || (characters[3] == 'W'))
-                       &amp; (characters[5] == '(')) {
-                if ((characters[4] == 'x') || (characters[4] == 'X')) {
-                    m_unit = CSSParser::FAngle;
-                    m_type = WebKitCSSTransformValue::SkewXTransformOperation;
-                } else if ((characters[4] == 'y') || (characters[4] == 'Y')) {
-                    m_unit = CSSParser::FAngle;
-                    m_type = WebKitCSSTransformValue::SkewYTransformOperation;
-                }
-            }
-            break;
-        case 7:
-            // Valid names: matrix(, rotate(, scalex(, scaley(, scalez(.
-            if ((characters[0] == 'm') || (characters[0] == 'M')) {
-                if (((characters[1] == 'a') || (characters[1] == 'A'))
-                    &amp; ((characters[2] == 't') || (characters[2] == 'T'))
-                    &amp; ((characters[3] == 'r') || (characters[3] == 'R'))
-                    &amp; ((characters[4] == 'i') || (characters[4] == 'I'))
-                    &amp; ((characters[5] == 'x') || (characters[5] == 'X'))
-                    &amp; (characters[6] == '(')) {
-                    m_unit = CSSParser::FNumber;
-                    m_type = WebKitCSSTransformValue::MatrixTransformOperation;
-                    m_argCount = 11;
-                }
-            } else if ((characters[0] == 'r') || (characters[0] == 'R')) {
-                if (((characters[1] == 'o') || (characters[1] == 'O'))
-                    &amp; ((characters[2] == 't') || (characters[2] == 'T'))
-                    &amp; ((characters[3] == 'a') || (characters[3] == 'A'))
-                    &amp; ((characters[4] == 't') || (characters[4] == 'T'))
-                    &amp; ((characters[5] == 'e') || (characters[5] == 'E'))
-                    &amp; (characters[6] == '(')) {
-                    m_unit = CSSParser::FAngle;
-                    m_type = WebKitCSSTransformValue::RotateTransformOperation;
-                }
-            } else if (((characters[0] == 's') || (characters[0] == 'S'))
-                       &amp; ((characters[1] == 'c') || (characters[1] == 'C'))
-                       &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
-                       &amp; ((characters[3] == 'l') || (characters[3] == 'L'))
-                       &amp; ((characters[4] == 'e') || (characters[4] == 'E'))
-                       &amp; (characters[6] == '(')) {
-                if ((characters[5] == 'x') || (characters[5] == 'X')) {
-                    m_unit = CSSParser::FNumber;
-                    m_type = WebKitCSSTransformValue::ScaleXTransformOperation;
-                } else if ((characters[5] == 'y') || (characters[5] == 'Y')) {
-                    m_unit = CSSParser::FNumber;
-                    m_type = WebKitCSSTransformValue::ScaleYTransformOperation;
-                } else if ((characters[5] == 'z') || (characters[5] == 'Z')) {
-                    m_unit = CSSParser::FNumber;
-                    m_type = WebKitCSSTransformValue::ScaleZTransformOperation;
-                }
-            }
-            break;
-        case 8:
-            // Valid names: rotatex(, rotatey(, rotatez(, scale3d(.
-            if ((characters[0] == 's') || (characters[0] == 'S')) {
-                if (((characters[1] == 'c') || (characters[1] == 'C'))
-                    &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
-                    &amp; ((characters[3] == 'l') || (characters[3] == 'L'))
-                    &amp; ((characters[4] == 'e') || (characters[4] == 'E'))
-                    &amp; (characters[5] == '3')
-                    &amp; ((characters[6] == 'd') || (characters[6] == 'D'))
-                    &amp; (characters[7] == '(')) {
-                    m_unit = CSSParser::FNumber;
-                    m_type = WebKitCSSTransformValue::Scale3DTransformOperation;
-                    m_argCount = 5;
-                }
-            } else if (((characters[0] == 'r') || (characters[0] == 'R'))
-                       &amp; ((characters[1] == 'o') || (characters[1] == 'O'))
-                       &amp; ((characters[2] == 't') || (characters[2] == 'T'))
-                       &amp; ((characters[3] == 'a') || (characters[3] == 'A'))
-                       &amp; ((characters[4] == 't') || (characters[4] == 'T'))
-                       &amp; ((characters[5] == 'e') || (characters[5] == 'E'))
-                       &amp; (characters[7] == '(')) {
-                if ((characters[6] == 'x') || (characters[6] == 'X')) {
-                    m_unit = CSSParser::FAngle;
-                    m_type = WebKitCSSTransformValue::RotateXTransformOperation;
-                } else if ((characters[6] == 'y') || (characters[6] == 'Y')) {
-                    m_unit = CSSParser::FAngle;
-                    m_type = WebKitCSSTransformValue::RotateYTransformOperation;
-                } else if ((characters[6] == 'z') || (characters[6] == 'Z')) {
-                    m_unit = CSSParser::FAngle;
-                    m_type = WebKitCSSTransformValue::RotateZTransformOperation;
-                }
-            }
-            break;
-        case 9:
-            // Valid names: matrix3d(, rotate3d(.
-            if ((characters[0] == 'm') || (characters[0] == 'M')) {
-                if (((characters[1] == 'a') || (characters[1] == 'A'))
-                    &amp; ((characters[2] == 't') || (characters[2] == 'T'))
-                    &amp; ((characters[3] == 'r') || (characters[3] == 'R'))
-                    &amp; ((characters[4] == 'i') || (characters[4] == 'I'))
-                    &amp; ((characters[5] == 'x') || (characters[5] == 'X'))
-                    &amp; (characters[6] == '3')
-                    &amp; ((characters[7] == 'd') || (characters[7] == 'D'))
-                    &amp; (characters[8] == '(')) {
-                    m_unit = CSSParser::FNumber;
-                    m_type = WebKitCSSTransformValue::Matrix3DTransformOperation;
-                    m_argCount = 31;
-                }
-            } else if (((characters[0] == 'r') || (characters[0] == 'R'))
-                       &amp; ((characters[1] == 'o') || (characters[1] == 'O'))
-                       &amp; ((characters[2] == 't') || (characters[2] == 'T'))
-                       &amp; ((characters[3] == 'a') || (characters[3] == 'A'))
-                       &amp; ((characters[4] == 't') || (characters[4] == 'T'))
-                       &amp; ((characters[5] == 'e') || (characters[5] == 'E'))
-                       &amp; (characters[6] == '3')
-                       &amp; ((characters[7] == 'd') || (characters[7] == 'D'))
-                       &amp; (characters[8] == '(')) {
-                m_unit = CSSParser::FNumber;
-                m_type = WebKitCSSTransformValue::Rotate3DTransformOperation;
-                m_argCount = 7;
-            }
-            break;
-        case 10:
-            // Valid name: translate(.
-            if (((characters[0] == 't') || (characters[0] == 'T'))
-                &amp; ((characters[1] == 'r') || (characters[1] == 'R'))
-                &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
-                &amp; ((characters[3] == 'n') || (characters[3] == 'N'))
-                &amp; ((characters[4] == 's') || (characters[4] == 'S'))
-                &amp; ((characters[5] == 'l') || (characters[5] == 'L'))
-                &amp; ((characters[6] == 'a') || (characters[6] == 'A'))
-                &amp; ((characters[7] == 't') || (characters[7] == 'T'))
-                &amp; ((characters[8] == 'e') || (characters[8] == 'E'))
-                &amp; (characters[9] == '(')) {
-                m_unit = CSSParser::FLength | CSSParser::FPercent;
-                m_type = WebKitCSSTransformValue::TranslateTransformOperation;
-                m_allowSingleArgument = true;
-                m_argCount = 3;
-            }
-            break;
-        case 11:
-            // Valid names: translatex(, translatey(, translatez(.
-            if (((characters[0] == 't') || (characters[0] == 'T'))
-                &amp; ((characters[1] == 'r') || (characters[1] == 'R'))
-                &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
-                &amp; ((characters[3] == 'n') || (characters[3] == 'N'))
-                &amp; ((characters[4] == 's') || (characters[4] == 'S'))
-                &amp; ((characters[5] == 'l') || (characters[5] == 'L'))
-                &amp; ((characters[6] == 'a') || (characters[6] == 'A'))
-                &amp; ((characters[7] == 't') || (characters[7] == 'T'))
-                &amp; ((characters[8] == 'e') || (characters[8] == 'E'))
-                &amp; (characters[10] == '(')) {
-                if ((characters[9] == 'x') || (characters[9] == 'X')) {
-                    m_unit = CSSParser::FLength | CSSParser::FPercent;
-                    m_type = WebKitCSSTransformValue::TranslateXTransformOperation;
-                } else if ((characters[9] == 'y') || (characters[9] == 'Y')) {
-                    m_unit = CSSParser::FLength | CSSParser::FPercent;
-                    m_type = WebKitCSSTransformValue::TranslateYTransformOperation;
-                } else if ((characters[9] == 'z') || (characters[9] == 'Z')) {
-                    m_unit = CSSParser::FLength | CSSParser::FPercent;
-                    m_type = WebKitCSSTransformValue::TranslateZTransformOperation;
-                }
-            }
-            break;
-        case 12:
-            // Valid names: perspective(, translate3d(.
-            if ((characters[0] == 'p') || (characters[0] == 'P')) {
-                if (((characters[1] == 'e') || (characters[1] == 'E'))
-                    &amp; ((characters[2] == 'r') || (characters[2] == 'R'))
-                    &amp; ((characters[3] == 's') || (characters[3] == 'S'))
-                    &amp; ((characters[4] == 'p') || (characters[4] == 'P'))
-                    &amp; ((characters[5] == 'e') || (characters[5] == 'E'))
-                    &amp; ((characters[6] == 'c') || (characters[6] == 'C'))
-                    &amp; ((characters[7] == 't') || (characters[7] == 'T'))
-                    &amp; ((characters[8] == 'i') || (characters[8] == 'I'))
-                    &amp; ((characters[9] == 'v') || (characters[9] == 'V'))
-                    &amp; ((characters[10] == 'e') || (characters[10] == 'E'))
-                    &amp; (characters[11] == '(')) {
-                    m_unit = CSSParser::FNumber;
-                    m_type = WebKitCSSTransformValue::PerspectiveTransformOperation;
-                }
-            } else if (((characters[0] == 't') || (characters[0] == 'T'))
-                       &amp; ((characters[1] == 'r') || (characters[1] == 'R'))
-                       &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
-                       &amp; ((characters[3] == 'n') || (characters[3] == 'N'))
-                       &amp; ((characters[4] == 's') || (characters[4] == 'S'))
-                       &amp; ((characters[5] == 'l') || (characters[5] == 'L'))
-                       &amp; ((characters[6] == 'a') || (characters[6] == 'A'))
-                       &amp; ((characters[7] == 't') || (characters[7] == 'T'))
-                       &amp; ((characters[8] == 'e') || (characters[8] == 'E'))
-                       &amp; (characters[9] == '3')
-                       &amp; ((characters[10] == 'd') || (characters[10] == 'D'))
-                       &amp; (characters[11] == '(')) {
-                m_unit = CSSParser::FLength | CSSParser::FPercent;
-                m_type = WebKitCSSTransformValue::Translate3DTransformOperation;
-                m_argCount = 5;
-            }
-            break;
-        } // end switch ()
-    }
-
-    WebKitCSSTransformValue::TransformOperationType type() const { return m_type; }
-    unsigned argCount() const { return m_argCount; }
-    CSSParser::Units unit() const { return m_unit; }
-
-    bool unknown() const { return m_type == WebKitCSSTransformValue::UnknownTransformOperation; }
-    bool hasCorrectArgCount(unsigned argCount) { return m_argCount == argCount || (m_allowSingleArgument &amp;&amp; argCount == 1); }
-
-private:
-    WebKitCSSTransformValue::TransformOperationType m_type;
-    unsigned m_argCount;
-    bool m_allowSingleArgument;
-    CSSParser::Units m_unit;
-};
-
-RefPtr&lt;CSSValueList&gt; CSSParser::parseTransform()
-{
-    if (!m_valueList)
-        return nullptr;
-
-    auto list = CSSValueList::createSpaceSeparated();
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        auto parsedTransformValue = parseTransformValue(*value);
-        if (!parsedTransformValue)
-            return nullptr;
-
-        list-&gt;append(parsedTransformValue.releaseNonNull());
-    }
-
-    return WTFMove(list);
-}
-
-RefPtr&lt;WebKitCSSTransformValue&gt; CSSParser::parseTransformValue(CSSParserValue&amp; value)
-{
-    if (value.unit != CSSParserValue::Function || !value.function)
-        return nullptr;
-
-    // Every primitive requires at least one argument.
-    CSSParserValueList* args = value.function-&gt;args.get();
-    if (!args)
-        return nullptr;
-
-    // See if the specified primitive is one we understand.
-    TransformOperationInfo info(value.function-&gt;name);
-    if (info.unknown())
-        return nullptr;
-
-    if (!info.hasCorrectArgCount(args-&gt;size()))
-        return nullptr;
-
-    // The transform is a list of functional primitives that specify transform operations.
-    // We collect a list of WebKitCSSTransformValues, where each value specifies a single operation.
-
-    // Create the new WebKitCSSTransformValue for this operation and add it to our list.
-    auto transformValue = WebKitCSSTransformValue::create(info.type());
-
-    // Snag our values.
-    CSSParserValue* argument = args-&gt;current();
-    unsigned argNumber = 0;
-    while (argument) {
-        ValueWithCalculation argumentWithCalculation(*argument);
-        CSSParser::Units unit = info.unit();
-
-        if (info.type() == WebKitCSSTransformValue::Rotate3DTransformOperation &amp;&amp; argNumber == 3) {
-            // 4th param of rotate3d() is an angle rather than a bare number, validate it as such
-            if (!validateUnit(argumentWithCalculation, FAngle, CSSStrictMode))
-                return nullptr;
-        } else if (info.type() == WebKitCSSTransformValue::Translate3DTransformOperation &amp;&amp; argNumber == 2) {
-            // 3rd param of translate3d() cannot be a percentage
-            if (!validateUnit(argumentWithCalculation, FLength, CSSStrictMode))
-                return nullptr;
-        } else if (info.type() == WebKitCSSTransformValue::TranslateZTransformOperation &amp;&amp; !argNumber) {
-            // 1st param of translateZ() cannot be a percentage
-            if (!validateUnit(argumentWithCalculation, FLength, CSSStrictMode))
-                return nullptr;
-        } else if (info.type() == WebKitCSSTransformValue::PerspectiveTransformOperation &amp;&amp; !argNumber) {
-            // 1st param of perspective() must be a non-negative number (deprecated) or length.
-            if (!validateUnit(argumentWithCalculation, FNumber | FLength | FNonNeg, CSSStrictMode))
-                return nullptr;
-        } else if (!validateUnit(argumentWithCalculation, unit, CSSStrictMode))
-            return nullptr;
-
-        // Add the value to the current transform operation.
-        transformValue-&gt;append(createPrimitiveNumericValue(argumentWithCalculation));
-
-        argument = args-&gt;next();
-        if (!argument)
-            break;
-        if (argument-&gt;unit != CSSParserValue::Operator || argument-&gt;iValue != ',')
-            return nullptr;
-        argument = args-&gt;next();
-
-        ++argNumber;
-    }
-
-    return WTFMove(transformValue);
-}
-
-bool CSSParser::isBlendMode(CSSValueID valueID)
-{
-    return (valueID &gt;= CSSValueMultiply &amp;&amp; valueID &lt;= CSSValueLuminosity)
-        || valueID == CSSValueNormal
-        || valueID == CSSValueOverlay;
-}
-
-bool CSSParser::isCompositeOperator(CSSValueID valueID)
-{
-    // FIXME: Add CSSValueDestination and CSSValueLighter when the Compositing spec updates.
-    return valueID &gt;= CSSValueClear &amp;&amp; valueID &lt;= CSSValueXor;
-}
-
-static void filterInfoForName(const CSSParserString&amp; name, WebKitCSSFilterValue::FilterOperationType&amp; filterType, unsigned&amp; maximumArgumentCount)
-{
-    if (equalLettersIgnoringASCIICase(name, &quot;grayscale(&quot;))
-        filterType = WebKitCSSFilterValue::GrayscaleFilterOperation;
-    else if (equalLettersIgnoringASCIICase(name, &quot;sepia(&quot;))
-        filterType = WebKitCSSFilterValue::SepiaFilterOperation;
-    else if (equalLettersIgnoringASCIICase(name, &quot;saturate(&quot;))
-        filterType = WebKitCSSFilterValue::SaturateFilterOperation;
-    else if (equalLettersIgnoringASCIICase(name, &quot;hue-rotate(&quot;))
-        filterType = WebKitCSSFilterValue::HueRotateFilterOperation;
-    else if (equalLettersIgnoringASCIICase(name, &quot;invert(&quot;))
-        filterType = WebKitCSSFilterValue::InvertFilterOperation;
-    else if (equalLettersIgnoringASCIICase(name, &quot;opacity(&quot;))
-        filterType = WebKitCSSFilterValue::OpacityFilterOperation;
-    else if (equalLettersIgnoringASCIICase(name, &quot;brightness(&quot;))
-        filterType = WebKitCSSFilterValue::BrightnessFilterOperation;
-    else if (equalLettersIgnoringASCIICase(name, &quot;contrast(&quot;))
-        filterType = WebKitCSSFilterValue::ContrastFilterOperation;
-    else if (equalLettersIgnoringASCIICase(name, &quot;blur(&quot;))
-        filterType = WebKitCSSFilterValue::BlurFilterOperation;
-    else if (equalLettersIgnoringASCIICase(name, &quot;drop-shadow(&quot;)) {
-        filterType = WebKitCSSFilterValue::DropShadowFilterOperation;
-        maximumArgumentCount = 4;  // x-offset, y-offset, blur-radius, color -- spread and inset style not allowed.
-    }
-}
-
-RefPtr&lt;WebKitCSSFilterValue&gt; CSSParser::parseBuiltinFilterArguments(CSSParserValueList&amp; args, WebKitCSSFilterValue::FilterOperationType filterType)
-{
-    auto filterValue = WebKitCSSFilterValue::create(filterType);
-
-    switch (filterType) {    
-    case WebKitCSSFilterValue::GrayscaleFilterOperation:
-    case WebKitCSSFilterValue::SepiaFilterOperation:
-    case WebKitCSSFilterValue::SaturateFilterOperation:
-    case WebKitCSSFilterValue::InvertFilterOperation:
-    case WebKitCSSFilterValue::OpacityFilterOperation:
-    case WebKitCSSFilterValue::ContrastFilterOperation: {
-        // One optional argument, 0-1 or 0%-100%, if missing use 100%.
-        if (args.size() &gt; 1)
-            return nullptr;
-
-        if (args.size()) {
-            ValueWithCalculation argumentWithCalculation(*args.current());
-            if (!validateUnit(argumentWithCalculation, FNumber | FPercent | FNonNeg, CSSStrictMode))
-                return nullptr;
-
-            auto primitiveValue = createPrimitiveNumericValue(argumentWithCalculation);
-
-            // Saturate and Contrast allow values over 100%.
-            if (filterType != WebKitCSSFilterValue::SaturateFilterOperation
-                &amp;&amp; filterType != WebKitCSSFilterValue::ContrastFilterOperation) {
-                double maxAllowed = primitiveValue-&gt;primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
-                if (primitiveValue-&gt;getDoubleValue() &gt; maxAllowed)
-                    return nullptr;
-            }
-
-            filterValue-&gt;append(WTFMove(primitiveValue));
-        }
-        break;
-    }
-    case WebKitCSSFilterValue::BrightnessFilterOperation: {
-        // One optional argument, if missing use 100%.
-        if (args.size() &gt; 1)
-            return nullptr;
-
-        if (args.size()) {
-            ValueWithCalculation argumentWithCalculation(*args.current());
-            if (!validateUnit(argumentWithCalculation, FNumber | FPercent, CSSStrictMode))
-                return nullptr;
-
-            filterValue-&gt;append(createPrimitiveNumericValue(argumentWithCalculation));
-        }
-        break;
-    }
-    case WebKitCSSFilterValue::HueRotateFilterOperation: {
-        // hue-rotate() takes one optional angle.
-        if (args.size() &gt; 1)
-            return nullptr;
-        
-        if (args.size()) {
-            ValueWithCalculation argumentWithCalculation(*args.current());
-            if (!validateUnit(argumentWithCalculation, FAngle, CSSStrictMode))
-                return nullptr;
-        
-            filterValue-&gt;append(createPrimitiveNumericValue(argumentWithCalculation));
-        }
-        break;
-    }
-    case WebKitCSSFilterValue::BlurFilterOperation: {
-        // Blur takes a single length. Zero parameters are allowed.
-        if (args.size() &gt; 1)
-            return nullptr;
-        
-        if (args.size()) {
-            ValueWithCalculation argumentWithCalculation(*args.current());
-            if (!validateUnit(argumentWithCalculation, FLength | FNonNeg, CSSStrictMode))
-                return nullptr;
-
-            filterValue-&gt;append(createPrimitiveNumericValue(argumentWithCalculation));
-        }
-        break;
-    }
-    case WebKitCSSFilterValue::DropShadowFilterOperation: {
-        // drop-shadow() takes a single shadow.
-        RefPtr&lt;CSSValueList&gt; shadowValueList = parseShadow(args, CSSPropertyFilter);
-        if (!shadowValueList || shadowValueList-&gt;length() != 1)
-            return nullptr;
-        
-        filterValue-&gt;append(*shadowValueList-&gt;itemWithoutBoundsCheck(0));
-        break;
-    }
-    default:
-        ASSERT_NOT_REACHED();
-    }
-    return WTFMove(filterValue);
-}
-
-bool CSSParser::parseFilter(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValueList&gt;&amp; result)
-{
-    // The filter is a list of functional primitives that specify individual operations.
-    auto list = CSSValueList::createSpaceSeparated();
-    for (auto* value = valueList.current(); value; value = valueList.next()) {
-        if (value-&gt;unit != CSSPrimitiveValue::CSS_URI &amp;&amp; (value-&gt;unit != CSSParserValue::Function || !value-&gt;function))
-            return false;
-
-        WebKitCSSFilterValue::FilterOperationType filterType = WebKitCSSFilterValue::UnknownFilterOperation;
-
-        // See if the specified primitive is one we understand.
-        if (value-&gt;unit == CSSPrimitiveValue::CSS_URI) {
-            auto referenceFilterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation);
-            referenceFilterValue-&gt;append(CSSPrimitiveValue::create(value-&gt;string, CSSPrimitiveValue::CSS_URI));
-            list-&gt;append(WTFMove(referenceFilterValue));
-        } else {
-            const CSSParserString name = value-&gt;function-&gt;name;
-            unsigned maximumArgumentCount = 1;
-
-            filterInfoForName(name, filterType, maximumArgumentCount);
-
-            if (filterType == WebKitCSSFilterValue::UnknownFilterOperation)
-                return false;
-
-            CSSParserValueList* args = value-&gt;function-&gt;args.get();
-            if (!args)
-                return false;
-
-            RefPtr&lt;WebKitCSSFilterValue&gt; filterValue = parseBuiltinFilterArguments(*args, filterType);
-            if (!filterValue)
-                return false;
-            
-            list-&gt;append(filterValue.releaseNonNull());
-        }
-    }
-
-    result = WTFMove(list);
-
-    return true;
-}
-
-#if ENABLE(CSS_REGIONS)
-static bool validFlowName(const String&amp; flowName)
-{
-    return !(equalLettersIgnoringASCIICase(flowName, &quot;auto&quot;)
-        || equalLettersIgnoringASCIICase(flowName, &quot;default&quot;)
-        || equalLettersIgnoringASCIICase(flowName, &quot;inherit&quot;)
-        || equalLettersIgnoringASCIICase(flowName, &quot;initial&quot;)
-        || equalLettersIgnoringASCIICase(flowName, &quot;none&quot;));
-}
-#endif
-
-#if ENABLE(IOS_TEXT_AUTOSIZING)
-bool CSSParser::isTextAutosizingEnabled() const
-{
-    return m_context.textAutosizingEnabled;
-}
-#endif
-
-#if ENABLE(CSS_GRID_LAYOUT)
-bool CSSParser::isCSSGridLayoutEnabled() const
-{
-    return m_context.cssGridLayoutEnabled;
-}
-#endif
-
-#if ENABLE(CSS_REGIONS)
-
-// none | &lt;ident&gt;
-bool CSSParser::parseFlowThread(CSSPropertyID propId, bool important)
-{
-    ASSERT(propId == CSSPropertyWebkitFlowInto);
-
-    if (m_valueList-&gt;size() != 1)
-        return false;
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (!value)
-        return false;
-
-    if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-        return false;
-
-    if (value-&gt;id == CSSValueNone) {
-        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
-        return true;
-    }
-
-    String inputProperty = String(value-&gt;string);
-    if (!inputProperty.isEmpty()) {
-        if (!validFlowName(inputProperty))
-            return false;
-        addProperty(propId, CSSValuePool::singleton().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important);
-    } else
-        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-
-    return true;
-}
-
-// -webkit-flow-from: none | &lt;ident&gt;
-bool CSSParser::parseRegionThread(CSSPropertyID propId, bool important)
-{
-    ASSERT(propId == CSSPropertyWebkitFlowFrom);
-
-    if (m_valueList-&gt;size() != 1)
-        return false;
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (!value)
-        return false;
-
-    if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-        return false;
-
-    if (value-&gt;id == CSSValueNone)
-        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
-    else {
-        String inputProperty = String(value-&gt;string);
-        if (!inputProperty.isEmpty()) {
-            if (!validFlowName(inputProperty))
-                return false;
-            addProperty(propId, CSSValuePool::singleton().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important);
-        } else
-            addProperty(propId, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-    }
-
-    return true;
-}
-#endif
-
-bool CSSParser::parseTransformOrigin(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2, CSSPropertyID&amp; propId3, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2, RefPtr&lt;CSSValue&gt;&amp; value3)
-{
-    propId1 = propId;
-    propId2 = propId;
-    propId3 = propId;
-    if (propId == CSSPropertyTransformOrigin) {
-        propId1 = CSSPropertyTransformOriginX;
-        propId2 = CSSPropertyTransformOriginY;
-        propId3 = CSSPropertyTransformOriginZ;
-    }
-
-    switch (propId) {
-    case CSSPropertyTransformOrigin:
-        if (!parseTransformOriginShorthand(value, value2, value3))
-            return false;
-        // parseTransformOriginShorthand advances the m_valueList pointer
-        break;
-    case CSSPropertyTransformOriginX: {
-        value = parsePositionX(*m_valueList);
-        if (value)
-            m_valueList-&gt;next();
-        break;
-    }
-    case CSSPropertyTransformOriginY: {
-        value = parsePositionY(*m_valueList);
-        if (value)
-            m_valueList-&gt;next();
-        break;
-    }
-    case CSSPropertyTransformOriginZ: {
-        ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-        if (validateUnit(valueWithCalculation, FLength))
-            value = createPrimitiveNumericValue(valueWithCalculation);
-        if (value)
-            m_valueList-&gt;next();
-        break;
-    }
-    default:
-        ASSERT_NOT_REACHED();
-        return false;
-    }
-
-    return value;
-}
-
-bool CSSParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2)
-{
-    propId1 = propId;
-    propId2 = propId;
-    if (propId == CSSPropertyPerspectiveOrigin) {
-        propId1 = CSSPropertyPerspectiveOriginX;
-        propId2 = CSSPropertyPerspectiveOriginY;
-    }
-
-    switch (propId) {
-    case CSSPropertyPerspectiveOrigin:
-        if (m_valueList-&gt;size() &gt; 2)
-            return false;
-        parse2ValuesFillPosition(*m_valueList, value, value2);
-        break;
-    case CSSPropertyPerspectiveOriginX: {
-        value = parsePositionX(*m_valueList);
-        if (value)
-            m_valueList-&gt;next();
-        break;
-    }
-    case CSSPropertyPerspectiveOriginY: {
-        value = parsePositionY(*m_valueList);
-        if (value)
-            m_valueList-&gt;next();
-        break;
-    }
-    default:
-        ASSERT_NOT_REACHED();
-        return false;
-    }
-
-    return value;
-}
-
-void CSSParser::addTextDecorationProperty(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp;&amp; value, bool important)
-{
-    // The text-decoration-line property takes priority over text-decoration, unless the latter has important priority set.
-    if (propId == CSSPropertyTextDecoration &amp;&amp; !important &amp;&amp; !inShorthand()) {
-        for (unsigned i = 0; i &lt; m_parsedProperties.size(); ++i) {
-            if (m_parsedProperties[i].id() == CSSPropertyWebkitTextDecorationLine)
-                return;
-        }
-    }
-    addProperty(propId, WTFMove(value), important);
-}
-
-bool CSSParser::parseTextDecoration(CSSPropertyID propId, bool important)
-{
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (value &amp;&amp; value-&gt;id == CSSValueNone) {
-        addTextDecorationProperty(propId, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-        m_valueList-&gt;next();
-        return true;
-    }
-
-    auto list = CSSValueList::createSpaceSeparated();
-    bool isValid = true;
-    while (isValid &amp;&amp; value) {
-        switch (value-&gt;id) {
-        case CSSValueBlink:
-        case CSSValueLineThrough:
-        case CSSValueOverline:
-        case CSSValueUnderline:
-#if ENABLE(LETTERPRESS)
-        case CSSValueWebkitLetterpress:
-#endif
-            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
-            break;
-        default:
-            isValid = false;
-            break;
-        }
-        if (isValid)
-            value = m_valueList-&gt;next();
-    }
-
-    // Values are either valid or in shorthand scope.
-    if (list-&gt;length() &amp;&amp; (isValid || inShorthand())) {
-        addTextDecorationProperty(propId, WTFMove(list), important);
-        return true;
-    }
-
-    return false;
-}
-
-bool CSSParser::parseTextDecorationSkip(bool important)
-{
-    // The text-decoration-skip property has syntax &quot;none | [ objects || spaces || ink || edges || box-decoration ]&quot;.
-    // However, only 'none' and 'ink' are implemented yet, so we will parse syntax &quot;none | ink&quot; for now.
-    CSSParserValue* value = m_valueList-&gt;current();
-    do {
-        switch (value-&gt;id) {
-        case CSSValueNone:
-        case CSSValueAuto:
-        case CSSValueInk:
-        case CSSValueObjects:
-            addProperty(CSSPropertyWebkitTextDecorationSkip, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
-            return true;
-        default:
-            break;
-        }
-    } while ((value = m_valueList-&gt;next()));
-    return false;
-}
-
-bool CSSParser::parseTextUnderlinePosition(bool important)
-{
-    // The text-underline-position property has sintax &quot;auto | alphabetic | [ under || [ left | right ] ]&quot;.
-    // However, values 'left' and 'right' are not implemented yet, so we will parse sintax
-    // &quot;auto | alphabetic | under&quot; for now.
-    CSSParserValue&amp; value = *m_valueList-&gt;current();
-    switch (value.id) {
-    case CSSValueAuto:
-    case CSSValueAlphabetic:
-    case CSSValueUnder:
-        if (m_valueList-&gt;next())
-            return false;
-
-        addProperty(CSSPropertyWebkitTextUnderlinePosition, CSSValuePool::singleton().createIdentifierValue(value.id), important);
-        return true;
-    default:
-        break;
-    }
-    return false;
-}
-
-bool CSSParser::parseTextEmphasisStyle(bool important)
-{
-    unsigned valueListSize = m_valueList-&gt;size();
-
-    RefPtr&lt;CSSPrimitiveValue&gt; fill;
-    RefPtr&lt;CSSPrimitiveValue&gt; shape;
-
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        if (value-&gt;unit == CSSPrimitiveValue::CSS_STRING) {
-            if (fill || shape || (valueListSize != 1 &amp;&amp; !inShorthand()))
-                return false;
-            addProperty(CSSPropertyWebkitTextEmphasisStyle, createPrimitiveStringValue(*value), important);
-            m_valueList-&gt;next();
-            return true;
-        }
-
-        if (value-&gt;id == CSSValueNone) {
-            if (fill || shape || (valueListSize != 1 &amp;&amp; !inShorthand()))
-                return false;
-            addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-            m_valueList-&gt;next();
-            return true;
-        }
-
-        if (value-&gt;id == CSSValueOpen || value-&gt;id == CSSValueFilled) {
-            if (fill)
-                return false;
-            fill = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-        } else if (value-&gt;id == CSSValueDot || value-&gt;id == CSSValueCircle || value-&gt;id == CSSValueDoubleCircle || value-&gt;id == CSSValueTriangle || value-&gt;id == CSSValueSesame) {
-            if (shape)
-                return false;
-            shape = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-        } else if (!inShorthand())
-            return false;
-        else
-            break;
-    }
-
-    if (fill &amp;&amp; shape) {
-        auto parsedValues = CSSValueList::createSpaceSeparated();
-        parsedValues-&gt;append(fill.releaseNonNull());
-        parsedValues-&gt;append(shape.releaseNonNull());
-        addProperty(CSSPropertyWebkitTextEmphasisStyle, WTFMove(parsedValues), important);
-        return true;
-    }
-    if (fill) {
-        addProperty(CSSPropertyWebkitTextEmphasisStyle, fill.releaseNonNull(), important);
-        return true;
-    }
-    if (shape) {
-        addProperty(CSSPropertyWebkitTextEmphasisStyle, shape.releaseNonNull(), important);
-        return true;
-    }
-
-    return false;
-}
-
-bool CSSParser::parseTextEmphasisPosition(bool important)
-{
-    bool foundOverOrUnder = false;
-    CSSValueID overUnderValueID = CSSValueOver;
-    bool foundLeftOrRight = false;
-    CSSValueID leftRightValueID = CSSValueRight;
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        switch (value-&gt;id) {
-        case CSSValueOver:
-            if (foundOverOrUnder)
-                return false;
-            foundOverOrUnder = true;
-            overUnderValueID = CSSValueOver;
-            break;
-        case CSSValueUnder:
-            if (foundOverOrUnder)
-                return false;
-            foundOverOrUnder = true;
-            overUnderValueID = CSSValueUnder;
-            break;
-        case CSSValueLeft:
-            if (foundLeftOrRight)
-                return false;
-            foundLeftOrRight = true;
-            leftRightValueID = CSSValueLeft;
-            break;
-        case CSSValueRight:
-            if (foundLeftOrRight)
-                return false;
-            foundLeftOrRight = true;
-            leftRightValueID = CSSValueRight;
-            break;
-        default:
-            return false;
-        }
-    }
-    if (!foundOverOrUnder)
-        return false;
-    auto list = CSSValueList::createSpaceSeparated();
-    list-&gt;append(CSSValuePool::singleton().createIdentifierValue(overUnderValueID));
-    if (foundLeftOrRight)
-        list-&gt;append(CSSValuePool::singleton().createIdentifierValue(leftRightValueID));
-    addProperty(CSSPropertyWebkitTextEmphasisPosition, WTFMove(list), important);
-    return true;
-}
-
-RefPtr&lt;CSSValueList&gt; CSSParser::parseTextIndent()
-{
-    // &lt;length&gt; | &lt;percentage&gt; | inherit  when CSS3_TEXT is disabled.
-    // [ &lt;length&gt; | &lt;percentage&gt; ] &amp;&amp; [ -webkit-hanging || -webkit-each-line ]? | inherit  when CSS3_TEXT is enabled.
-    auto list = CSSValueList::createSpaceSeparated();
-    bool hasLengthOrPercentage = false;
-#if ENABLE(CSS3_TEXT)
-    bool hasEachLine = false;
-    bool hasHanging = false;
-#endif
-
-    CSSParserValue* value = m_valueList-&gt;current();
-    while (value) {
-        ValueWithCalculation valueWithCalculation(*value);
-        if (!hasLengthOrPercentage &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent)) {
-            list-&gt;append(createPrimitiveNumericValue(valueWithCalculation));
-            hasLengthOrPercentage = true;
-        }
-#if ENABLE(CSS3_TEXT)
-        else if (!hasEachLine &amp;&amp; value-&gt;id == CSSValueWebkitEachLine) {
-            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueWebkitEachLine));
-            hasEachLine = true;
-        } else if (!hasHanging &amp;&amp; value-&gt;id == CSSValueWebkitHanging) {
-            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueWebkitHanging));
-            hasHanging = true;
-        }
-#endif
-        else
-            return nullptr;
-
-        value = m_valueList-&gt;next();
-    }
-
-    if (!hasLengthOrPercentage)
-        return nullptr;
-
-    return WTFMove(list);
-}
-
-bool CSSParser::parseHangingPunctuation(bool important)
-{
-    CSSParserValue* value = m_valueList-&gt;current();
-    if (value &amp;&amp; value-&gt;id == CSSValueNone) {
-        addProperty(CSSPropertyHangingPunctuation, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
-        m_valueList-&gt;next();
-        return true;
-    }
-    
-    auto list = CSSValueList::createSpaceSeparated();
-    bool isValid = true;
-    std::bitset&lt;numCSSValueKeywords&gt; seenValues;
-    while (isValid &amp;&amp; value) {
-        if (seenValues[value-&gt;id]
-            || (value-&gt;id == CSSValueAllowEnd &amp;&amp; seenValues[CSSValueForceEnd])
-            || (value-&gt;id == CSSValueForceEnd &amp;&amp; seenValues[CSSValueAllowEnd])) {
-            isValid = false;
-            break;
-        }
-        switch (value-&gt;id) {
-        case CSSValueAllowEnd:
-        case CSSValueFirst:
-        case CSSValueForceEnd:
-        case CSSValueLast:
-            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
-            seenValues.set(value-&gt;id);
-            break;
-        default:
-            isValid = false;
-            break;
-        }
-        if (isValid)
-            value = m_valueList-&gt;next();
-    }
-    
-    // Values are either valid or in shorthand scope.
-    if (list-&gt;length() &amp;&amp; isValid) {
-        addProperty(CSSPropertyHangingPunctuation, WTFMove(list), important);
-        return true;
-    }
-    
-    return false;
-}
-
-bool CSSParser::parseLineBoxContain(bool important)
-{
-    LineBoxContain lineBoxContain = LineBoxContainNone;
-
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        if (value-&gt;id == CSSValueBlock) {
-            if (lineBoxContain &amp; LineBoxContainBlock)
-                return false;
-            lineBoxContain |= LineBoxContainBlock;
-        } else if (value-&gt;id == CSSValueInline) {
-            if (lineBoxContain &amp; LineBoxContainInline)
-                return false;
-            lineBoxContain |= LineBoxContainInline;
-        } else if (value-&gt;id == CSSValueFont) {
-            if (lineBoxContain &amp; LineBoxContainFont)
-                return false;
-            lineBoxContain |= LineBoxContainFont;
-        } else if (value-&gt;id == CSSValueGlyphs) {
-            if (lineBoxContain &amp; LineBoxContainGlyphs)
-                return false;
-            lineBoxContain |= LineBoxContainGlyphs;
-        } else if (value-&gt;id == CSSValueReplaced) {
-            if (lineBoxContain &amp; LineBoxContainReplaced)
-                return false;
-            lineBoxContain |= LineBoxContainReplaced;
-        } else if (value-&gt;id == CSSValueInlineBox) {
-            if (lineBoxContain &amp; LineBoxContainInlineBox)
-                return false;
-            lineBoxContain |= LineBoxContainInlineBox;
-        } else if (value-&gt;id == CSSValueInitialLetter) {
-            if (lineBoxContain &amp; LineBoxContainInitialLetter)
-                return false;
-            lineBoxContain |= LineBoxContainInitialLetter;
-        } else
-            return false;
-    }
-
-    if (!lineBoxContain)
-        return false;
-
-    addProperty(CSSPropertyWebkitLineBoxContain, CSSLineBoxContainValue::create(lineBoxContain), important);
-    return true;
-}
-
-bool CSSParser::parseFontFeatureTag(CSSValueList&amp; settings)
-{
-    CSSParserValue* value = m_valueList-&gt;current();
-    // Feature tag name comes first
-    if (value-&gt;unit != CSSPrimitiveValue::CSS_STRING)
-        return false;
-    FontFeatureTag tag;
-    if (value-&gt;string.length() != tag.size())
-        return false;
-    for (unsigned i = 0; i &lt; tag.size(); ++i) {
-        // Limits the range of characters to 0x20-0x7E, following the tag name rules defiend in the OpenType specification.
-        UChar character = value-&gt;string[i];
-        if (character &lt; 0x20 || character &gt; 0x7E)
-            return false;
-        tag[i] = toASCIILower(character);
-    }
-
-    int tagValue = 1;
-    // Feature tag values could follow: &lt;integer&gt; | on | off
-    value = m_valueList-&gt;next();
-    if (value) {
-        if (value-&gt;unit == CSSPrimitiveValue::CSS_NUMBER &amp;&amp; value-&gt;isInt &amp;&amp; value-&gt;fValue &gt;= 0) {
-            tagValue = clampToInteger(value-&gt;fValue);
-            if (tagValue &lt; 0)
-                return false;
-            m_valueList-&gt;next();
-        } else if (value-&gt;id == CSSValueOn || value-&gt;id == CSSValueOff) {
-            tagValue = value-&gt;id == CSSValueOn;
-            m_valueList-&gt;next();
-        }
-    }
-    settings.append(CSSFontFeatureValue::create(WTFMove(tag), tagValue));
-    return true;
-}
-
-bool CSSParser::parseFontFeatureSettings(bool important)
-{
-    if (m_valueList-&gt;size() == 1 &amp;&amp; m_valueList-&gt;current()-&gt;id == CSSValueNormal) {
-        auto normalValue = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
-        m_valueList-&gt;next();
-        addProperty(CSSPropertyFontFeatureSettings, WTFMove(normalValue), important);
-        return true;
-    }
-
-    auto settings = CSSValueList::createCommaSeparated();
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        if (!parseFontFeatureTag(settings))
-            return false;
-
-        // If the list isn't parsed fully, the current value should be comma.
-        value = m_valueList-&gt;current();
-        if (value &amp;&amp; !isComma(value))
-            return false;
-    }
-    if (settings-&gt;length()) {
-        addProperty(CSSPropertyFontFeatureSettings, WTFMove(settings), important);
-        return true;
-    }
-    return false;
-}
-
-bool CSSParser::parseFontVariantLigatures(bool important, bool unknownIsFailure, bool implicit)
-{
-    auto values = CSSValueList::createSpaceSeparated();
-    FontVariantLigatures commonLigatures = FontVariantLigatures::Normal;
-    FontVariantLigatures discretionaryLigatures = FontVariantLigatures::Normal;
-    FontVariantLigatures historicalLigatures = FontVariantLigatures::Normal;
-    FontVariantLigatures contextualAlternates = FontVariantLigatures::Normal;
-
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-            return false;
-
-        switch (value-&gt;id) {
-        case CSSValueNoCommonLigatures:
-            commonLigatures = FontVariantLigatures::No;
-            break;
-        case CSSValueCommonLigatures:
-            commonLigatures = FontVariantLigatures::Yes;
-            break;
-        case CSSValueNoDiscretionaryLigatures:
-            discretionaryLigatures = FontVariantLigatures::No;
-            break;
-        case CSSValueDiscretionaryLigatures:
-            discretionaryLigatures = FontVariantLigatures::Yes;
-            break;
-        case CSSValueNoHistoricalLigatures:
-            historicalLigatures = FontVariantLigatures::No;
-            break;
-        case CSSValueHistoricalLigatures:
-            historicalLigatures = FontVariantLigatures::Yes;
-            break;
-        case CSSValueContextual:
-            contextualAlternates = FontVariantLigatures::Yes;
-            break;
-        case CSSValueNoContextual:
-            contextualAlternates = FontVariantLigatures::No;
-            break;
-        default:
-            if (unknownIsFailure)
-                return false;
-            continue;
-        }
-    }
-
-    switch (commonLigatures) {
-    case FontVariantLigatures::Normal:
-        break;
-    case FontVariantLigatures::Yes:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures));
-        break;
-    case FontVariantLigatures::No:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures));
-        break;
-    }
-
-    switch (discretionaryLigatures) {
-    case FontVariantLigatures::Normal:
-        break;
-    case FontVariantLigatures::Yes:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures));
-        break;
-    case FontVariantLigatures::No:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures));
-        break;
-    }
-
-    switch (historicalLigatures) {
-    case FontVariantLigatures::Normal:
-        break;
-    case FontVariantLigatures::Yes:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures));
-        break;
-    case FontVariantLigatures::No:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures));
-        break;
-    }
-
-    switch (contextualAlternates) {
-    case FontVariantLigatures::Normal:
-        break;
-    case FontVariantLigatures::Yes:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual));
-        break;
-    case FontVariantLigatures::No:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual));
-        break;
-    }
-
-    if (!values-&gt;length())
-        return !unknownIsFailure;
-
-    addProperty(CSSPropertyFontVariantLigatures, WTFMove(values), important, implicit);
-    return true;
-}
-
-bool CSSParser::parseFontVariantNumeric(bool important, bool unknownIsFailure, bool implicit)
-{
-    auto values = CSSValueList::createSpaceSeparated();
-    FontVariantNumericFigure figure = FontVariantNumericFigure::Normal;
-    FontVariantNumericSpacing spacing = FontVariantNumericSpacing::Normal;
-    FontVariantNumericFraction fraction = FontVariantNumericFraction::Normal;
-    FontVariantNumericOrdinal ordinal = FontVariantNumericOrdinal::Normal;
-    FontVariantNumericSlashedZero slashedZero = FontVariantNumericSlashedZero::Normal;
-
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-            return false;
-
-        switch (value-&gt;id) {
-        case CSSValueLiningNums:
-            figure = FontVariantNumericFigure::LiningNumbers;
-            break;
-        case CSSValueOldstyleNums:
-            figure = FontVariantNumericFigure::OldStyleNumbers;
-            break;
-        case CSSValueProportionalNums:
-            spacing = FontVariantNumericSpacing::ProportionalNumbers;
-            break;
-        case CSSValueTabularNums:
-            spacing = FontVariantNumericSpacing::TabularNumbers;
-            break;
-        case CSSValueDiagonalFractions:
-            fraction = FontVariantNumericFraction::DiagonalFractions;
-            break;
-        case CSSValueStackedFractions:
-            fraction = FontVariantNumericFraction::StackedFractions;
-            break;
-        case CSSValueOrdinal:
-            ordinal = FontVariantNumericOrdinal::Yes;
-            break;
-        case CSSValueSlashedZero:
-            slashedZero = FontVariantNumericSlashedZero::Yes;
-            break;
-        default:
-            if (unknownIsFailure)
-                return false;
-            continue;
-        }
-    }
-
-    switch (figure) {
-    case FontVariantNumericFigure::Normal:
-        break;
-    case FontVariantNumericFigure::LiningNumbers:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums));
-        break;
-    case FontVariantNumericFigure::OldStyleNumbers:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums));
-        break;
-    }
-
-    switch (spacing) {
-    case FontVariantNumericSpacing::Normal:
-        break;
-    case FontVariantNumericSpacing::ProportionalNumbers:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums));
-        break;
-    case FontVariantNumericSpacing::TabularNumbers:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums));
-        break;
-    }
-
-    switch (fraction) {
-    case FontVariantNumericFraction::Normal:
-        break;
-    case FontVariantNumericFraction::DiagonalFractions:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions));
-        break;
-    case FontVariantNumericFraction::StackedFractions:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions));
-        break;
-    }
-
-    switch (ordinal) {
-    case FontVariantNumericOrdinal::Normal:
-        break;
-    case FontVariantNumericOrdinal::Yes:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal));
-        break;
-    }
-
-    switch (slashedZero) {
-    case FontVariantNumericSlashedZero::Normal:
-        break;
-    case FontVariantNumericSlashedZero::Yes:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero));
-        break;
-    }
-
-    if (!values-&gt;length())
-        return !unknownIsFailure;
-
-    addProperty(CSSPropertyFontVariantNumeric, WTFMove(values), important, implicit);
-    return true;
-}
-
-bool CSSParser::parseFontVariantEastAsian(bool important, bool unknownIsFailure, bool implicit)
-{
-    auto values = CSSValueList::createSpaceSeparated();
-    FontVariantEastAsianVariant variant = FontVariantEastAsianVariant::Normal;
-    FontVariantEastAsianWidth width = FontVariantEastAsianWidth::Normal;
-    FontVariantEastAsianRuby ruby = FontVariantEastAsianRuby::Normal;
-
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-            return false;
-
-        switch (value-&gt;id) {
-        case CSSValueJis78:
-            variant = FontVariantEastAsianVariant::Jis78;
-            break;
-        case CSSValueJis83:
-            variant = FontVariantEastAsianVariant::Jis83;
-            break;
-        case CSSValueJis90:
-            variant = FontVariantEastAsianVariant::Jis90;
-            break;
-        case CSSValueJis04:
-            variant = FontVariantEastAsianVariant::Jis04;
-            break;
-        case CSSValueSimplified:
-            variant = FontVariantEastAsianVariant::Simplified;
-            break;
-        case CSSValueTraditional:
-            variant = FontVariantEastAsianVariant::Traditional;
-            break;
-        case CSSValueFullWidth:
-            width = FontVariantEastAsianWidth::Full;
-            break;
-        case CSSValueProportionalWidth:
-            width = FontVariantEastAsianWidth::Proportional;
-            break;
-        case CSSValueRuby:
-            ruby = FontVariantEastAsianRuby::Yes;
-            break;
-        default:
-            if (unknownIsFailure)
-                return false;
-            continue;
-        }
-    }
-
-    switch (variant) {
-    case FontVariantEastAsianVariant::Normal:
-        break;
-    case FontVariantEastAsianVariant::Jis78:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78));
-        break;
-    case FontVariantEastAsianVariant::Jis83:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83));
-        break;
-    case FontVariantEastAsianVariant::Jis90:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90));
-        break;
-    case FontVariantEastAsianVariant::Jis04:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04));
-        break;
-    case FontVariantEastAsianVariant::Simplified:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified));
-        break;
-    case FontVariantEastAsianVariant::Traditional:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional));
-        break;
-    }
-
-    switch (width) {
-    case FontVariantEastAsianWidth::Normal:
-        break;
-    case FontVariantEastAsianWidth::Full:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth));
-        break;
-    case FontVariantEastAsianWidth::Proportional:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth));
-        break;
-    }
-
-    switch (ruby) {
-    case FontVariantEastAsianRuby::Normal:
-        break;
-    case FontVariantEastAsianRuby::Yes:
-        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby));
-    }
-
-    if (!values-&gt;length())
-        return !unknownIsFailure;
-
-    addProperty(CSSPropertyFontVariantEastAsian, WTFMove(values), important, implicit);
-    return true;
-}
-
-bool CSSParser::parseFontVariant(bool important)
-{
-    ShorthandScope scope(this, CSSPropertyFontVariant);
-    if (!parseFontVariantLigatures(important, false, false))
-        return false;
-    m_valueList-&gt;setCurrentIndex(0);
-    if (!parseFontVariantNumeric(important, false, false))
-        return false;
-    m_valueList-&gt;setCurrentIndex(0);
-    if (!parseFontVariantEastAsian(important, false, false))
-        return false;
-    m_valueList-&gt;setCurrentIndex(0);
-
-    FontVariantPosition position = FontVariantPosition::Normal;
-    FontVariantCaps caps = FontVariantCaps::Normal;
-    FontVariantAlternates alternates = FontVariantAlternates::Normal;
-
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-            return false;
-
-        switch (value-&gt;id) {
-        case CSSValueNoCommonLigatures:
-        case CSSValueCommonLigatures:
-        case CSSValueNoDiscretionaryLigatures:
-        case CSSValueDiscretionaryLigatures:
-        case CSSValueNoHistoricalLigatures:
-        case CSSValueHistoricalLigatures:
-        case CSSValueContextual:
-        case CSSValueNoContextual:
-        case CSSValueLiningNums:
-        case CSSValueOldstyleNums:
-        case CSSValueProportionalNums:
-        case CSSValueTabularNums:
-        case CSSValueDiagonalFractions:
-        case CSSValueStackedFractions:
-        case CSSValueOrdinal:
-        case CSSValueSlashedZero:
-        case CSSValueJis78:
-        case CSSValueJis83:
-        case CSSValueJis90:
-        case CSSValueJis04:
-        case CSSValueSimplified:
-        case CSSValueTraditional:
-        case CSSValueFullWidth:
-        case CSSValueProportionalWidth:
-        case CSSValueRuby:
-            break;
-        case CSSValueSub:
-            position = FontVariantPosition::Subscript;
-            break;
-        case CSSValueSuper:
-            position = FontVariantPosition::Superscript;
-            break;
-        case CSSValueSmallCaps:
-            caps = FontVariantCaps::Small;
-            break;
-        case CSSValueAllSmallCaps:
-            caps = FontVariantCaps::AllSmall;
-            break;
-        case CSSValuePetiteCaps:
-            caps = FontVariantCaps::Petite;
-            break;
-        case CSSValueAllPetiteCaps:
-            caps = FontVariantCaps::AllPetite;
-            break;
-        case CSSValueUnicase:
-            caps = FontVariantCaps::Unicase;
-            break;
-        case CSSValueTitlingCaps:
-            caps = FontVariantCaps::Titling;
-            break;
-        case CSSValueHistoricalForms:
-            alternates = FontVariantAlternates::HistoricalForms;
-            break;
-        default:
-            return false;
-        }
-    }
-
-    switch (position) {
-    case FontVariantPosition::Normal:
-        break;
-    case FontVariantPosition::Subscript:
-        addProperty(CSSPropertyFontVariantPosition, CSSValuePool::singleton().createIdentifierValue(CSSValueSub), important, false);
-        break;
-    case FontVariantPosition::Superscript:
-        addProperty(CSSPropertyFontVariantPosition, CSSValuePool::singleton().createIdentifierValue(CSSValueSuper), important, false);
-        break;
-    }
-
-    switch (caps) {
-    case FontVariantCaps::Normal:
-        break;
-    case FontVariantCaps::Small:
-        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps), important, false);
-        break;
-    case FontVariantCaps::AllSmall:
-        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps), important, false);
-        break;
-    case FontVariantCaps::Petite:
-        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps), important, false);
-        break;
-    case FontVariantCaps::AllPetite:
-        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps), important, false);
-        break;
-    case FontVariantCaps::Unicase:
-        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase), important, false);
-        break;
-    case FontVariantCaps::Titling:
-        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps), important, false);
-        break;
-    }
-
-    switch (alternates) {
-    case FontVariantAlternates::Normal:
-        break;
-    case FontVariantAlternates::HistoricalForms:
-        addProperty(CSSPropertyFontVariantAlternates, CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms), important, false);
-        break;
-    }
-
-    return true;
-}
-
-static inline bool isValidWillChangeAnimatableFeature(const CSSParserValue&amp; value)
-{
-    if (value.id == CSSValueNone || value.id == CSSValueAuto || value.id == CSSValueAll)
-        return false;
-
-    if (valueIsCSSKeyword(value))
-        return false;
-
-    if (cssPropertyID(value.string) == CSSPropertyWillChange)
-        return false;
-
-    return true;
-}
-
-bool CSSParser::parseWillChange(bool important)
-{
-    auto willChangePropertyValues = CSSValueList::createCommaSeparated();
-
-    bool expectComma = false;
-    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
-        if (expectComma) {
-            if (!isComma(value))
-                return false;
-            
-            expectComma = false;
-            continue;
-        }
-
-        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
-            return false;
-
-        if (!isValidWillChangeAnimatableFeature(*value))
-            return false;
-
-        RefPtr&lt;CSSValue&gt; cssValue;
-        if (value-&gt;id == CSSValueScrollPosition || value-&gt;id == CSSValueContents)
-            cssValue = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
-        else {
-            CSSPropertyID propertyID = cssPropertyID(value-&gt;string);
-            if (propertyID != CSSPropertyInvalid)
-                cssValue = CSSValuePool::singleton().createIdentifierValue(propertyID);
-            else // This might be a property we don't support.
-                cssValue = createPrimitiveStringValue(*value);
-        }
-
-        willChangePropertyValues-&gt;append(cssValue.releaseNonNull());
-        expectComma = true;
-    }
-
-    addProperty(CSSPropertyWillChange, WTFMove(willChangePropertyValues), important);
-    return true;
-}
-
-RefPtr&lt;CSSCalcValue&gt; CSSParser::parseCalculation(CSSParserValue&amp; value, CalculationPermittedValueRange range)
-{
-    ASSERT(isCalculation(value));
-    
-    CSSParserValueList* args = value.function-&gt;args.get();
-    if (!args || !args-&gt;size())
-        return nullptr;
-
-    return CSSCalcValue::create(value.function-&gt;name, *args, range);
-}
-
-#define END_TOKEN 0
-
-#include &quot;CSSGrammar.h&quot;
-
-enum CharacterType {
-    // Types for the main switch.
-
-    // The first 4 types must be grouped together, as they
-    // represent the allowed chars in an identifier.
-    CharacterCaselessU,
-    CharacterIdentifierStart,
-    CharacterNumber,
-    CharacterDash,
-
-    CharacterOther,
-    CharacterNull,
-    CharacterWhiteSpace,
-    CharacterEndConditionQuery,
-    CharacterEndNthChild,
-    CharacterQuote,
-    CharacterExclamationMark,
-    CharacterHashmark,
-    CharacterDollar,
-    CharacterAsterisk,
-    CharacterPlus,
-    CharacterDot,
-    CharacterSlash,
-    CharacterLess,
-    CharacterAt,
-    CharacterBackSlash,
-    CharacterXor,
-    CharacterVerticalBar,
-    CharacterTilde,
-};
-
-// 128 ASCII codes
-static const CharacterType typesOfASCIICharacters[128] = {
-/*   0 - Null               */ CharacterNull,
-/*   1 - Start of Heading   */ CharacterOther,
-/*   2 - Start of Text      */ CharacterOther,
-/*   3 - End of Text        */ CharacterOther,
-/*   4 - End of Transm.     */ CharacterOther,
-/*   5 - Enquiry            */ CharacterOther,
-/*   6 - Acknowledgment     */ CharacterOther,
-/*   7 - Bell               */ CharacterOther,
-/*   8 - Back Space         */ CharacterOther,
-/*   9 - Horizontal Tab     */ CharacterWhiteSpace,
-/*  10 - Line Feed          */ CharacterWhiteSpace,
-/*  11 - Vertical Tab       */ CharacterOther,
-/*  12 - Form Feed          */ CharacterWhiteSpace,
-/*  13 - Carriage Return    */ CharacterWhiteSpace,
-/*  14 - Shift Out          */ CharacterOther,
-/*  15 - Shift In           */ CharacterOther,
-/*  16 - Data Line Escape   */ CharacterOther,
-/*  17 - Device Control 1   */ CharacterOther,
-/*  18 - Device Control 2   */ CharacterOther,
-/*  19 - Device Control 3   */ CharacterOther,
-/*  20 - Device Control 4   */ CharacterOther,
-/*  21 - Negative Ack.      */ CharacterOther,
-/*  22 - Synchronous Idle   */ CharacterOther,
-/*  23 - End of Transmit    */ CharacterOther,
-/*  24 - Cancel             */ CharacterOther,
-/*  25 - End of Medium      */ CharacterOther,
-/*  26 - Substitute         */ CharacterOther,
-/*  27 - Escape             */ CharacterOther,
-/*  28 - File Separator     */ CharacterOther,
-/*  29 - Group Separator    */ CharacterOther,
-/*  30 - Record Separator   */ CharacterOther,
-/*  31 - Unit Separator     */ CharacterOther,
-/*  32 - Space              */ CharacterWhiteSpace,
-/*  33 - !                  */ CharacterExclamationMark,
-/*  34 - &quot;                  */ CharacterQuote,
-/*  35 - #                  */ CharacterHashmark,
-/*  36 - $                  */ CharacterDollar,
-/*  37 - %                  */ CharacterOther,
-/*  38 - &amp;                  */ CharacterOther,
-/*  39 - '                  */ CharacterQuote,
-/*  40 - (                  */ CharacterOther,
-/*  41 - )                  */ CharacterEndNthChild,
-/*  42 - *                  */ CharacterAsterisk,
-/*  43 - +                  */ CharacterPlus,
-/*  44 - ,                  */ CharacterOther,
-/*  45 - -                  */ CharacterDash,
-/*  46 - .                  */ CharacterDot,
-/*  47 - /                  */ CharacterSlash,
-/*  48 - 0                  */ CharacterNumber,
-/*  49 - 1                  */ CharacterNumber,
-/*  50 - 2                  */ CharacterNumber,
-/*  51 - 3                  */ CharacterNumber,
-/*  52 - 4                  */ CharacterNumber,
-/*  53 - 5                  */ CharacterNumber,
-/*  54 - 6                  */ CharacterNumber,
-/*  55 - 7                  */ CharacterNumber,
-/*  56 - 8                  */ CharacterNumber,
-/*  57 - 9                  */ CharacterNumber,
-/*  58 - :                  */ CharacterOther,
-/*  59 - ;                  */ CharacterEndConditionQuery,
-/*  60 - &lt;                  */ CharacterLess,
-/*  61 - =                  */ CharacterOther,
-/*  62 - &gt;                  */ CharacterOther,
-/*  63 - ?                  */ CharacterOther,
-/*  64 - @                  */ CharacterAt,
-/*  65 - A                  */ CharacterIdentifierStart,
-/*  66 - B                  */ CharacterIdentifierStart,
-/*  67 - C                  */ CharacterIdentifierStart,
-/*  68 - D                  */ CharacterIdentifierStart,
-/*  69 - E                  */ CharacterIdentifierStart,
-/*  70 - F                  */ CharacterIdentifierStart,
-/*  71 - G                  */ CharacterIdentifierStart,
-/*  72 - H                  */ CharacterIdentifierStart,
-/*  73 - I                  */ CharacterIdentifierStart,
-/*  74 - J                  */ CharacterIdentifierStart,
-/*  75 - K                  */ CharacterIdentifierStart,
-/*  76 - L                  */ CharacterIdentifierStart,
-/*  77 - M                  */ CharacterIdentifierStart,
-/*  78 - N                  */ CharacterIdentifierStart,
-/*  79 - O                  */ CharacterIdentifierStart,
-/*  80 - P                  */ CharacterIdentifierStart,
-/*  81 - Q                  */ CharacterIdentifierStart,
-/*  82 - R                  */ CharacterIdentifierStart,
-/*  83 - S                  */ CharacterIdentifierStart,
-/*  84 - T                  */ CharacterIdentifierStart,
-/*  85 - U                  */ CharacterCaselessU,
-/*  86 - V                  */ CharacterIdentifierStart,
-/*  87 - W                  */ CharacterIdentifierStart,
-/*  88 - X                  */ CharacterIdentifierStart,
-/*  89 - Y                  */ CharacterIdentifierStart,
-/*  90 - Z                  */ CharacterIdentifierStart,
-/*  91 - [                  */ CharacterOther,
-/*  92 - \                  */ CharacterBackSlash,
-/*  93 - ]                  */ CharacterOther,
-/*  94 - ^                  */ CharacterXor,
-/*  95 - _                  */ CharacterIdentifierStart,
-/*  96 - `                  */ CharacterOther,
-/*  97 - a                  */ CharacterIdentifierStart,
-/*  98 - b                  */ CharacterIdentifierStart,
-/*  99 - c                  */ CharacterIdentifierStart,
-/* 100 - d                  */ CharacterIdentifierStart,
-/* 101 - e                  */ CharacterIdentifierStart,
-/* 102 - f                  */ CharacterIdentifierStart,
-/* 103 - g                  */ CharacterIdentifierStart,
-/* 104 - h                  */ CharacterIdentifierStart,
-/* 105 - i                  */ CharacterIdentifierStart,
-/* 106 - j                  */ CharacterIdentifierStart,
-/* 107 - k                  */ CharacterIdentifierStart,
-/* 108 - l                  */ CharacterIdentifierStart,
-/* 109 - m                  */ CharacterIdentifierStart,
-/* 110 - n                  */ CharacterIdentifierStart,
-/* 111 - o                  */ CharacterIdentifierStart,
-/* 112 - p                  */ CharacterIdentifierStart,
-/* 113 - q                  */ CharacterIdentifierStart,
-/* 114 - r                  */ CharacterIdentifierStart,
-/* 115 - s                  */ CharacterIdentifierStart,
-/* 116 - t                  */ CharacterIdentifierStart,
-/* 117 - u                  */ CharacterCaselessU,
-/* 118 - v                  */ CharacterIdentifierStart,
-/* 119 - w                  */ CharacterIdentifierStart,
-/* 120 - x                  */ CharacterIdentifierStart,
-/* 121 - y                  */ CharacterIdentifierStart,
-/* 122 - z                  */ CharacterIdentifierStart,
-/* 123 - {                  */ CharacterEndConditionQuery,
-/* 124 - |                  */ CharacterVerticalBar,
-/* 125 - }                  */ CharacterOther,
-/* 126 - ~                  */ CharacterTilde,
-/* 127 - Delete             */ CharacterOther,
-};
-
-// Utility functions for the CSS tokenizer.
-
-template &lt;typename CharacterType&gt;
-static inline bool isCSSLetter(CharacterType character)
-{
-    return character &gt;= 128 || typesOfASCIICharacters[character] &lt;= CharacterDash;
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool isCSSEscape(CharacterType character)
-{
-    return character &gt;= ' ' &amp;&amp; character != 127;
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool isURILetter(CharacterType character)
-{
-    return (character &gt;= '*' &amp;&amp; character != 127) || (character &gt;= '#' &amp;&amp; character &lt;= '&amp;') || character == '!';
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool isIdentifierStartAfterDash(CharacterType* currentCharacter)
-{
-    return isASCIIAlpha(currentCharacter[0]) || currentCharacter[0] == '_' || currentCharacter[0] &gt;= 128
-        || (currentCharacter[0] == '\\' &amp;&amp; isCSSEscape(currentCharacter[1]));
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool isCustomPropertyIdentifier(CharacterType* currentCharacter)
-{
-    return isASCIIAlpha(currentCharacter[0]) || currentCharacter[0] == '_' || currentCharacter[0] &gt;= 128
-        || (currentCharacter[0] == '\\' &amp;&amp; isCSSEscape(currentCharacter[1]));
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool isEqualToCSSIdentifier(CharacterType* cssString, const char* constantString)
-{
-    // Compare an character memory data with a zero terminated string.
-    do {
-        // The input must be part of an identifier if constantChar or constString
-        // contains '-'. Otherwise toASCIILowerUnchecked('\r') would be equal to '-'.
-        ASSERT((*constantString &gt;= 'a' &amp;&amp; *constantString &lt;= 'z') || *constantString == '-');
-        ASSERT(*constantString != '-' || isCSSLetter(*cssString));
-        if (toASCIILowerUnchecked(*cssString++) != (*constantString++))
-            return false;
-    } while (*constantString);
-    return true;
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool isEqualToCSSCaseSensitiveIdentifier(CharacterType* string, const char* constantString)
-{
-    do {
-        if (*string++ != *constantString++)
-            return false;
-    } while (*constantString);
-    return true;
-}
-
-template &lt;typename CharacterType&gt;
-static CharacterType* checkAndSkipEscape(CharacterType* currentCharacter)
-{
-    // Returns with 0, if escape check is failed. Otherwise
-    // it returns with the following character.
-    ASSERT(*currentCharacter == '\\');
-
-    ++currentCharacter;
-    if (!isCSSEscape(*currentCharacter))
-        return nullptr;
-
-    if (isASCIIHexDigit(*currentCharacter)) {
-        int length = 6;
-
-        do {
-            ++currentCharacter;
-        } while (isASCIIHexDigit(*currentCharacter) &amp;&amp; --length);
-
-        // Optional space after the escape sequence.
-        if (isHTMLSpace(*currentCharacter))
-            ++currentCharacter;
-        return currentCharacter;
-    }
-    return currentCharacter + 1;
-}
-
-template &lt;typename CharacterType&gt;
-static inline CharacterType* skipWhiteSpace(CharacterType* currentCharacter)
-{
-    while (isHTMLSpace(*currentCharacter))
-        ++currentCharacter;
-    return currentCharacter;
-}
-
-// Main CSS tokenizer functions.
-
-template &lt;&gt;
-LChar* CSSParserString::characters&lt;LChar&gt;() const { return characters8(); }
-
-template &lt;&gt;
-UChar* CSSParserString::characters&lt;UChar&gt;() const { return characters16(); }
-
-template &lt;&gt;
-inline LChar*&amp; CSSParser::currentCharacter&lt;LChar&gt;()
-{
-    return m_currentCharacter8;
-}
-
-template &lt;&gt;
-inline UChar*&amp; CSSParser::currentCharacter&lt;UChar&gt;()
-{
-    return m_currentCharacter16;
-}
-
-UChar*&amp; CSSParser::currentCharacter16()
-{
-    if (!m_currentCharacter16) {
-        m_dataStart16 = std::make_unique&lt;UChar[]&gt;(m_length);
-        m_currentCharacter16 = m_dataStart16.get();
-    }
-
-    return m_currentCharacter16;
-}
-
-template &lt;&gt;
-inline LChar* CSSParser::tokenStart&lt;LChar&gt;()
-{
-    return m_tokenStart.ptr8;
-}
-
-template &lt;&gt;
-inline UChar* CSSParser::tokenStart&lt;UChar&gt;()
-{
-    return m_tokenStart.ptr16;
-}
-
-CSSParser::Location CSSParser::currentLocation()
-{
-    Location location;
-    location.lineNumber = m_tokenStartLineNumber;
-    location.columnNumber = m_tokenStartColumnNumber;
-
-    ASSERT(location.lineNumber &gt;= 0);
-    ASSERT(location.columnNumber &gt;= 0);
-
-    if (location.lineNumber == m_sheetStartLineNumber)
-        location.columnNumber += m_sheetStartColumnNumber;
-
-    if (is8BitSource())
-        location.token.init(tokenStart&lt;LChar&gt;(), currentCharacter&lt;LChar&gt;() - tokenStart&lt;LChar&gt;());
-    else
-        location.token.init(tokenStart&lt;UChar&gt;(), currentCharacter&lt;UChar&gt;() - tokenStart&lt;UChar&gt;());
-
-    return location;
-}
-
-template &lt;typename CharacterType&gt;
-inline bool CSSParser::isIdentifierStart()
-{
-    // Check whether an identifier is started.
-    return isIdentifierStartAfterDash((*currentCharacter&lt;CharacterType&gt;() != '-') ? currentCharacter&lt;CharacterType&gt;() : currentCharacter&lt;CharacterType&gt;() + 1);
-}
-
-template &lt;typename CharacterType&gt;
-static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, int quote)
-{
-    // Returns with 0, if string check is failed. Otherwise
-    // it returns with the following character. This is necessary
-    // since we cannot revert escape sequences, thus strings
-    // must be validated before parsing.
-    while (true) {
-        if (UNLIKELY(*currentCharacter == quote)) {
-            // String parsing is successful.
-            return currentCharacter + 1;
-        }
-        if (UNLIKELY(!*currentCharacter)) {
-            // String parsing is successful up to end of input.
-            return currentCharacter;
-        }
-        if (UNLIKELY(*currentCharacter &lt;= '\r' &amp;&amp; (*currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) {
-            // String parsing is failed for character '\n', '\f' or '\r'.
-            return nullptr;
-        }
-
-        if (LIKELY(currentCharacter[0] != '\\'))
-            ++currentCharacter;
-        else if (currentCharacter[1] == '\n' || currentCharacter[1] == '\f')
-            currentCharacter += 2;
-        else if (currentCharacter[1] == '\r')
-            currentCharacter += currentCharacter[2] == '\n' ? 3 : 2;
-        else {
-            currentCharacter = checkAndSkipEscape(currentCharacter);
-            if (!currentCharacter)
-                return nullptr;
-        }
-    }
-}
-
-template &lt;typename CharacterType&gt;
-unsigned CSSParser::parseEscape(CharacterType*&amp; src)
-{
-    ASSERT(*src == '\\' &amp;&amp; isCSSEscape(src[1]));
-
-    unsigned unicode = 0;
-
-    ++src;
-    if (isASCIIHexDigit(*src)) {
-
-        int length = 6;
-
-        do {
-            unicode = (unicode &lt;&lt; 4) + toASCIIHexValue(*src++);
-        } while (--length &amp;&amp; isASCIIHexDigit(*src));
-
-        if (unicode &gt; UCHAR_MAX_VALUE)
-            unicode = replacementCharacter;
-
-        // Optional space after the escape sequence.
-        if (isHTMLSpace(*src))
-            ++src;
-
-        return unicode;
-    }
-
-    return *currentCharacter&lt;CharacterType&gt;()++;
-}
-
-template &lt;&gt;
-inline void CSSParser::UnicodeToChars&lt;LChar&gt;(LChar*&amp; result, unsigned unicode)
-{
-    ASSERT(unicode &lt;= 0xff);
-    *result = unicode;
-
-    ++result;
-}
-
-template &lt;&gt;
-inline void CSSParser::UnicodeToChars&lt;UChar&gt;(UChar*&amp; result, unsigned unicode)
-{
-    // Replace unicode with a surrogate pairs when it is bigger than 0xffff
-    if (U16_LENGTH(unicode) == 2) {
-        *result++ = U16_LEAD(unicode);
-        *result = U16_TRAIL(unicode);
-    } else
-        *result = unicode;
-
-    ++result;
-}
-
-template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
-inline bool CSSParser::parseIdentifierInternal(SrcCharacterType*&amp; src, DestCharacterType*&amp; result, bool&amp; hasEscape)
-{
-    hasEscape = false;
-    do {
-        if (LIKELY(*src != '\\'))
-            *result++ = *src++;
-        else {
-            hasEscape = true;
-            SrcCharacterType* savedEscapeStart = src;
-            unsigned unicode = parseEscape&lt;SrcCharacterType&gt;(src);
-            if (unicode &gt; 0xff &amp;&amp; sizeof(DestCharacterType) == 1) {
-                src = savedEscapeStart;
-                return false;
-            }
-            UnicodeToChars(result, unicode);
-        }
-    } while (isCSSLetter(src[0]) || (src[0] == '\\' &amp;&amp; isCSSEscape(src[1])));
-
-    return true;
-}
-
-template &lt;typename CharacterType&gt;
-inline void CSSParser::parseIdentifier(CharacterType*&amp; result, CSSParserString&amp; resultString, bool&amp; hasEscape)
-{
-    CharacterType* start = currentCharacter&lt;CharacterType&gt;();
-    if (UNLIKELY(!parseIdentifierInternal(currentCharacter&lt;CharacterType&gt;(), result, hasEscape))) {
-        // Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
-        ASSERT(is8BitSource());
-        UChar*&amp; result16 = currentCharacter16();
-        UChar* start16 = result16;
-        int i = 0;
-        for (; i &lt; result - start; ++i)
-            result16[i] = start[i];
-
-        result16 += i;
-
-        parseIdentifierInternal(currentCharacter&lt;CharacterType&gt;(), result16, hasEscape);
-
-        result += result16 - start16;
-        resultString.init(start16, result16 - start16);
-
-        return;
-    }
-
-    resultString.init(start, result - start);
-}
-
-template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
-inline bool CSSParser::parseStringInternal(SrcCharacterType*&amp; src, DestCharacterType*&amp; result, UChar quote)
-{
-    while (true) {
-        if (UNLIKELY(*src == quote)) {
-            // String parsing is done.
-            ++src;
-            return true;
-        }
-        if (UNLIKELY(!*src)) {
-            // String parsing is done, but don't advance pointer if at the end of input.
-            return true;
-        }
-        ASSERT(*src &gt; '\r' || (*src &lt; '\n' &amp;&amp; *src) || *src == '\v');
-
-        if (LIKELY(src[0] != '\\'))
-            *result++ = *src++;
-        else if (src[1] == '\n' || src[1] == '\f')
-            src += 2;
-        else if (src[1] == '\r')
-            src += src[2] == '\n' ? 3 : 2;
-        else {
-            SrcCharacterType* savedEscapeStart = src;
-            unsigned unicode = parseEscape&lt;SrcCharacterType&gt;(src);
-            if (unicode &gt; 0xff &amp;&amp; sizeof(DestCharacterType) == 1) {
-                src = savedEscapeStart;
-                return false;
-            }
-            UnicodeToChars(result, unicode);
-        }
-    }
-
-    return true;
-}
-
-template &lt;typename CharacterType&gt;
-inline void CSSParser::parseString(CharacterType*&amp; result, CSSParserString&amp; resultString, UChar quote)
-{
-    CharacterType* start = currentCharacter&lt;CharacterType&gt;();
-
-    if (UNLIKELY(!parseStringInternal(currentCharacter&lt;CharacterType&gt;(), result, quote))) {
-        // Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
-        ASSERT(is8BitSource());
-        UChar*&amp; result16 = currentCharacter16();
-        UChar* start16 = result16;
-        int i = 0;
-        for (; i &lt; result - start; ++i)
-            result16[i] = start[i];
-
-        result16 += i;
-
-        parseStringInternal(currentCharacter&lt;CharacterType&gt;(), result16, quote);
-
-        resultString.init(start16, result16 - start16);
-        return;
-    }
-
-    resultString.init(start, result - start);
-}
-
-template &lt;typename CharacterType&gt;
-inline bool CSSParser::findURI(CharacterType*&amp; start, CharacterType*&amp; end, UChar&amp; quote)
-{
-    start = skipWhiteSpace(currentCharacter&lt;CharacterType&gt;());
-    
-    if (*start == '&quot;' || *start == '\'') {
-        quote = *start++;
-        end = checkAndSkipString(start, quote);
-        if (!end)
-            return false;
-    } else {
-        quote = 0;
-        end = start;
-        while (isURILetter(*end)) {
-            if (LIKELY(*end != '\\'))
-                ++end;
-            else {
-                end = checkAndSkipEscape(end);
-                if (!end)
-                    return false;
-            }
-        }
-    }
-
-    end = skipWhiteSpace(end);
-    if (*end != ')')
-        return false;
-    
-    return true;
-}
-
-template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
-inline bool CSSParser::parseURIInternal(SrcCharacterType*&amp; src, DestCharacterType*&amp; dest, UChar quote)
-{
-    if (quote) {
-        ASSERT(quote == '&quot;' || quote == '\'');
-        return parseStringInternal(src, dest, quote);
-    }
-    
-    while (isURILetter(*src)) {
-        if (LIKELY(*src != '\\'))
-            *dest++ = *src++;
-        else {
-            unsigned unicode = parseEscape&lt;SrcCharacterType&gt;(src);
-            if (unicode &gt; 0xff &amp;&amp; sizeof(SrcCharacterType) == 1)
-                return false;
-            UnicodeToChars(dest, unicode);
-        }
-    }
-
-    return true;
-}
-
-template &lt;typename CharacterType&gt;
-inline void CSSParser::parseURI(CSSParserString&amp; string)
-{
-    CharacterType* uriStart;
-    CharacterType* uriEnd;
-    UChar quote;
-    if (!findURI(uriStart, uriEnd, quote))
-        return;
-    
-    CharacterType* dest = currentCharacter&lt;CharacterType&gt;() = uriStart;
-    if (LIKELY(parseURIInternal(currentCharacter&lt;CharacterType&gt;(), dest, quote)))
-        string.init(uriStart, dest - uriStart);
-    else {
-        // An escape sequence was encountered that can't be stored in 8 bits.
-        // Reset the current character to the start of the URI and re-parse with
-        // a 16-bit destination.
-        ASSERT(is8BitSource());
-        UChar* uriStart16 = currentCharacter16();
-        currentCharacter&lt;CharacterType&gt;() = uriStart;
-        bool result = parseURIInternal(currentCharacter&lt;CharacterType&gt;(), currentCharacter16(), quote);
-        ASSERT_UNUSED(result, result);
-        string.init(uriStart16, currentCharacter16() - uriStart16);
-    }
-
-    currentCharacter&lt;CharacterType&gt;() = uriEnd + 1;
-    m_token = URI;
-}
-
-template &lt;typename CharacterType&gt;
-inline bool CSSParser::parseUnicodeRange()
-{
-    CharacterType* character = currentCharacter&lt;CharacterType&gt;() + 1;
-    int length = 6;
-    ASSERT(*currentCharacter&lt;CharacterType&gt;() == '+');
-
-    while (isASCIIHexDigit(*character) &amp;&amp; length) {
-        ++character;
-        --length;
-    }
-
-    if (length &amp;&amp; *character == '?') {
-        // At most 5 hex digit followed by a question mark.
-        do {
-            ++character;
-            --length;
-        } while (*character == '?' &amp;&amp; length);
-        currentCharacter&lt;CharacterType&gt;() = character;
-        return true;
-    }
-
-    if (length &lt; 6) {
-        // At least one hex digit.
-        if (character[0] == '-' &amp;&amp; isASCIIHexDigit(character[1])) {
-            // Followed by a dash and a hex digit.
-            ++character;
-            length = 6;
-            do {
-                ++character;
-            } while (--length &amp;&amp; isASCIIHexDigit(*character));
-        }
-        currentCharacter&lt;CharacterType&gt;() = character;
-        return true;
-    }
-    return false;
-}
-
-template &lt;typename CharacterType&gt;
-bool CSSParser::parseNthChild()
-{
-    CharacterType* character = currentCharacter&lt;CharacterType&gt;();
-
-    while (isASCIIDigit(*character))
-        ++character;
-    if (isASCIIAlphaCaselessEqual(*character, 'n')) {
-        currentCharacter&lt;CharacterType&gt;() = character + 1;
-        return true;
-    }
-    return false;
-}
-
-template &lt;typename CharacterType&gt;
-bool CSSParser::parseNthChildExtra()
-{
-    CharacterType* character = skipWhiteSpace(currentCharacter&lt;CharacterType&gt;());
-    if (*character != '+' &amp;&amp; *character != '-')
-        return false;
-
-    character = skipWhiteSpace(character + 1);
-    if (!isASCIIDigit(*character))
-        return false;
-
-    do {
-        ++character;
-    } while (isASCIIDigit(*character));
-
-    currentCharacter&lt;CharacterType&gt;() = character;
-    return true;
-}
-
-template &lt;typename CharacterType&gt;
-inline bool CSSParser::detectFunctionTypeToken(int length)
-{
-    ASSERT(length &gt; 0);
-    CharacterType* name = tokenStart&lt;CharacterType&gt;();
-
-    switch (length) {
-    case 3:
-        if (isASCIIAlphaCaselessEqual(name[0], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 't')) {
-            m_token = NOTFUNCTION;
-            return true;
-        }
-        if (isASCIIAlphaCaselessEqual(name[0], 'u') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'r') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'l')) {
-            m_token = URI;
-            return true;
-        }
-        if (isASCIIAlphaCaselessEqual(name[0], 'v') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'r')) {
-            m_token = VARFUNCTION;
-            return true;
-        }
-#if ENABLE(VIDEO_TRACK)
-        if (isASCIIAlphaCaselessEqual(name[0], 'c') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'u') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'e')) {
-            m_token = CUEFUNCTION;
-            return true;
-        }
-#endif
-#if ENABLE(CSS_SELECTORS_LEVEL4)
-        if (isASCIIAlphaCaselessEqual(name[0], 'd') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'i') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'r')) {
-            m_token = DIRFUNCTION;
-            return true;
-        }
-#endif
-        return false;
-
-    case 4:
-        if (isEqualToCSSIdentifier(name, &quot;calc&quot;)) {
-            m_token = CALCFUNCTION;
-            return true;
-        }
-        if (isEqualToCSSIdentifier(name, &quot;lang&quot;)) {
-            m_token = LANGFUNCTION;
-            return true;
-        }
-#if ENABLE(CSS_SELECTORS_LEVEL4)
-        if (isEqualToCSSIdentifier(name, &quot;role&quot;)) {
-            m_token = ROLEFUNCTION;
-            return true;
-        }
-#endif
-        if (isEqualToCSSIdentifier(name, &quot;host&quot;)) {
-            m_token = HOSTFUNCTION;
-            return true;
-        }
-        return false;
-
-    case 7:
-        if (isEqualToCSSIdentifier(name, &quot;matches&quot;)) {
-            m_token = MATCHESFUNCTION;
-            return true;
-        }
-        if (isEqualToCSSIdentifier(name, &quot;slotted&quot;)) {
-            m_token = SLOTTEDFUNCTION;
-            return true;
-        }
-        return false;
-
-    case 9:
-        if (isEqualToCSSIdentifier(name, &quot;nth-child&quot;)) {
-            m_token = NTHCHILDFUNCTIONS;
-            m_parsingMode = NthChildMode;
-            return true;
-        }
-        return false;
-
-    case 11:
-        if (isEqualToCSSIdentifier(name, &quot;nth-of-type&quot;)) {
-            m_parsingMode = NthChildMode;
-            return true;
-        }
-        return false;
-
-    case 14:
-        if (isEqualToCSSIdentifier(name, &quot;nth-last-child&quot;)) {
-            m_token = NTHCHILDFUNCTIONS;
-            m_parsingMode = NthChildMode;
-            return true;
-        }
-        return false;
-
-    case 16:
-        if (isEqualToCSSIdentifier(name, &quot;nth-last-of-type&quot;)) {
-            m_parsingMode = NthChildMode;
-            return true;
-        }
-        return false;
-    }
-
-    return false;
-}
-
-template &lt;typename CharacterType&gt;
-inline void CSSParser::detectMediaQueryToken(int length)
-{
-    ASSERT(m_parsingMode == MediaQueryMode);
-    CharacterType* name = tokenStart&lt;CharacterType&gt;();
-
-    if (length == 3) {
-        if (isASCIIAlphaCaselessEqual(name[0], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'd'))
-            m_token = MEDIA_AND;
-        else if (isASCIIAlphaCaselessEqual(name[0], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 't'))
-            m_token = MEDIA_NOT;
-    } else if (length == 4) {
-        if (isASCIIAlphaCaselessEqual(name[0], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'n')
-                &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'l') &amp;&amp; isASCIIAlphaCaselessEqual(name[3], 'y'))
-            m_token = MEDIA_ONLY;
-    }
-}
-
-template &lt;typename CharacterType&gt;
-inline void CSSParser::detectNumberToken(CharacterType* type, int length)
-{
-    ASSERT(length &gt; 0);
-
-    switch (toASCIILowerUnchecked(type[0])) {
-    case 'c':
-        if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'm'))
-            m_token = CMS;
-        else if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'h'))
-            m_token = CHS;
-        return;
-
-    case 'd':
-        if (length == 3 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'e') &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'g'))
-            m_token = DEGS;
-#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
-        else if (length &gt; 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'p')) {
-            if (length == 4) {
-                // There is a discussion about the name of this unit on www-style.
-                // Keep this compile time guard in place until that is resolved.
-                // http://lists.w3.org/Archives/Public/www-style/2012May/0915.html
-                if (isASCIIAlphaCaselessEqual(type[2], 'p') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'x'))
-                    m_token = DPPX;
-                else if (isASCIIAlphaCaselessEqual(type[2], 'c') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'm'))
-                    m_token = DPCM;
-            } else if (length == 3 &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'i'))
-                    m_token = DPI;
-        }
-#endif
-        return;
-
-    case 'e':
-        if (length == 2) {
-            if (isASCIIAlphaCaselessEqual(type[1], 'm'))
-                m_token = EMS;
-            else if (isASCIIAlphaCaselessEqual(type[1], 'x'))
-                m_token = EXS;
-        }
-        return;
-
-    case 'f':
-        if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'r'))
-            m_token = FR;
-        return;
-    case 'g':
-        if (length == 4 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'r')
-                &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'd'))
-            m_token = GRADS;
-        return;
-
-    case 'h':
-        if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'z'))
-            m_token = HERTZ;
-        return;
-
-    case 'i':
-        if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'n'))
-            m_token = INS;
-        return;
-
-    case 'k':
-        if (length == 3 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'h') &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'z'))
-            m_token = KHERTZ;
-        return;
-
-    case 'm':
-        if (length == 2) {
-            if (isASCIIAlphaCaselessEqual(type[1], 'm'))
-                m_token = MMS;
-            else if (isASCIIAlphaCaselessEqual(type[1], 's'))
-                m_token = MSECS;
-        }
-        return;
-
-    case 'p':
-        if (length == 2) {
-            if (isASCIIAlphaCaselessEqual(type[1], 'x'))
-                m_token = PXS;
-            else if (isASCIIAlphaCaselessEqual(type[1], 't'))
-                m_token = PTS;
-            else if (isASCIIAlphaCaselessEqual(type[1], 'c'))
-                m_token = PCS;
-        }
-        return;
-
-    case 'r':
-        if (length == 3) {
-            if (isASCIIAlphaCaselessEqual(type[1], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'd'))
-                m_token = RADS;
-            else if (isASCIIAlphaCaselessEqual(type[1], 'e') &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'm'))
-                m_token = REMS;
-        }
-        return;
-
-    case 's':
-        if (length == 1)
-            m_token = SECS;
-        return;
-
-    case 't':
-        if (length == 4 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'u')
-                &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'r') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'n'))
-            m_token = TURNS;
-        return;
-    case 'v':
-        if (length == 2) {
-            if (isASCIIAlphaCaselessEqual(type[1], 'w'))
-                m_token = VW;
-            else if (isASCIIAlphaCaselessEqual(type[1], 'h'))
-                m_token = VH;
-        } else if (length == 4 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'm')) {
-            if (isASCIIAlphaCaselessEqual(type[2], 'i') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'n'))
-                m_token = VMIN;
-            else if (isASCIIAlphaCaselessEqual(type[2], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'x'))
-                m_token = VMAX;
-        }
-        return;
-
-    default:
-        if (type[0] == '_' &amp;&amp; length == 5 &amp;&amp; type[1] == '_' &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'q')
-                &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'e') &amp;&amp; isASCIIAlphaCaselessEqual(type[4], 'm'))
-            m_token = QEMS;
-        return;
-    }
-}
-
-template &lt;typename CharacterType&gt;
-inline void CSSParser::detectDashToken(int length)
-{
-    CharacterType* name = tokenStart&lt;CharacterType&gt;();
-
-    if (length == 11) {
-        if (isASCIIAlphaCaselessEqual(name[10], 'y') &amp;&amp; isEqualToCSSIdentifier(name + 1, &quot;webkit-an&quot;))
-            m_token = ANYFUNCTION;
-        else if (isASCIIAlphaCaselessEqual(name[10], 'n') &amp;&amp; isEqualToCSSIdentifier(name + 1, &quot;webkit-mi&quot;))
-            m_token = MINFUNCTION;
-        else if (isASCIIAlphaCaselessEqual(name[10], 'x') &amp;&amp; isEqualToCSSIdentifier(name + 1, &quot;webkit-ma&quot;))
-            m_token = MAXFUNCTION;
-    } else if (length == 12 &amp;&amp; isEqualToCSSIdentifier(name + 1, &quot;webkit-calc&quot;))
-        m_token = CALCFUNCTION;
-}
-
-template &lt;typename CharacterType&gt;
-inline void CSSParser::detectAtToken(int length, bool hasEscape)
-{
-    CharacterType* name = tokenStart&lt;CharacterType&gt;();
-    ASSERT(name[0] == '@' &amp;&amp; length &gt;= 2);
-
-    // charset, font-face, import, media, namespace, page, supports,
-    // -webkit-keyframes, and -webkit-mediaquery are not affected by hasEscape.
-    switch (toASCIILowerUnchecked(name[1])) {
-    case 'b':
-        if (hasEscape)
-            return;
-
-        switch (length) {
-        case 12:
-            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-left&quot;))
-                m_token = BOTTOMLEFT_SYM;
-            return;
-
-        case 13:
-            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-right&quot;))
-                m_token = BOTTOMRIGHT_SYM;
-            return;
-
-        case 14:
-            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-center&quot;))
-                m_token = BOTTOMCENTER_SYM;
-            return;
-
-        case 19:
-            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-left-corner&quot;))
-                m_token = BOTTOMLEFTCORNER_SYM;
-            return;
-
-        case 20:
-            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-right-corner&quot;))
-                m_token = BOTTOMRIGHTCORNER_SYM;
-            return;
-        }
-        return;
-
-    case 'c':
-        if (length == 8 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;harset&quot;))
-            m_token = CHARSET_SYM;
-        return;
-
-    case 'f':
-        if (length == 10 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;ont-face&quot;))
-            m_token = FONT_FACE_SYM;
-        return;
-
-    case 'i':
-        if (length == 7 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;mport&quot;)) {
-            m_parsingMode = MediaQueryMode;
-            m_token = IMPORT_SYM;
-        }
-        return;
-
-    case 'k':
-        if (length == 10 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;eyframes&quot;))
-            m_token = KEYFRAMES_SYM;
-        else if (length == 14 &amp;&amp; !hasEscape &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;eyframe-rule&quot;))
-            m_token = KEYFRAME_RULE_SYM;
-        return;
-
-    case 'l':
-        if (hasEscape)
-            return;
-
-        if (length == 9) {
-            if (isEqualToCSSIdentifier(name + 2, &quot;eft-top&quot;))
-                m_token = LEFTTOP_SYM;
-        } else if (length == 12) {
-            // Checking the last character first could further reduce the possibile cases.
-            if (isASCIIAlphaCaselessEqual(name[11], 'e') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;eft-middl&quot;))
-                m_token = LEFTMIDDLE_SYM;
-            else if (isASCIIAlphaCaselessEqual(name[11], 'm') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;eft-botto&quot;))
-                m_token = LEFTBOTTOM_SYM;
-        }
-        return;
-
-    case 'm':
-        if (length == 6 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;edia&quot;)) {
-            m_parsingMode = MediaQueryMode;
-            m_token = MEDIA_SYM;
-        }
-        return;
-
-    case 'n':
-        if (length == 10 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;amespace&quot;))
-            m_token = NAMESPACE_SYM;
-        return;
-
-    case 'p':
-        if (length == 5 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;age&quot;))
-            m_token = PAGE_SYM;
-        return;
-
-    case 'r':
-        if (hasEscape)
-            return;
-
-        if (length == 10) {
-            if (isEqualToCSSIdentifier(name + 2, &quot;ight-top&quot;))
-                m_token = RIGHTTOP_SYM;
-        } else if (length == 13) {
-            // Checking the last character first could further reduce the possibile cases.
-            if (isASCIIAlphaCaselessEqual(name[12], 'e') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;ight-middl&quot;))
-                m_token = RIGHTMIDDLE_SYM;
-            else if (isASCIIAlphaCaselessEqual(name[12], 'm') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;ight-botto&quot;))
-                m_token = RIGHTBOTTOM_SYM;
-        }
-        return;
-
-    case 's':
-        if (length == 9 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;upports&quot;)) {
-            m_parsingMode = SupportsMode;
-            m_token = SUPPORTS_SYM;
-        }
-        return;
-
-    case 't':
-        if (hasEscape)
-            return;
-
-        switch (length) {
-        case 9:
-            if (isEqualToCSSIdentifier(name + 2, &quot;op-left&quot;))
-                m_token = TOPLEFT_SYM;
-            return;
-
-        case 10:
-            if (isEqualToCSSIdentifier(name + 2, &quot;op-right&quot;))
-                m_token = TOPRIGHT_SYM;
-            return;
-
-        case 11:
-            if (isEqualToCSSIdentifier(name + 2, &quot;op-center&quot;))
-                m_token = TOPCENTER_SYM;
-            return;
-
-        case 16:
-            if (isEqualToCSSIdentifier(name + 2, &quot;op-left-corner&quot;))
-                m_token = TOPLEFTCORNER_SYM;
-            return;
-
-        case 17:
-            if (isEqualToCSSIdentifier(name + 2, &quot;op-right-corner&quot;))
-                m_token = TOPRIGHTCORNER_SYM;
-            return;
-        }
-        return;
-
-    case '-':
-        switch (length) {
-        case 13:
-            if (!hasEscape &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-rule&quot;))
-                m_token = WEBKIT_RULE_SYM;
-            return;
-
-        case 14:
-            if (hasEscape)
-                return;
-
-            // Checking the last character first could further reduce the possibile cases.
-            if (isASCIIAlphaCaselessEqual(name[13], 's') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-decl&quot;))
-                m_token = WEBKIT_DECLS_SYM;
-            else if (isASCIIAlphaCaselessEqual(name[13], 'e') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-valu&quot;))
-                m_token = WEBKIT_VALUE_SYM;
-            return;
-
-        case 15:
-            if (hasEscape)
-                return;
-
-#if ENABLE(CSS_REGIONS)
-            if (isASCIIAlphaCaselessEqual(name[14], 'n') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-regio&quot;))
-                m_token = WEBKIT_REGION_RULE_SYM;
-#endif
-            return;
-
-        case 17:
-            if (hasEscape)
-                return;
-
-            if (isASCIIAlphaCaselessEqual(name[16], 'r') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-selecto&quot;))
-                m_token = WEBKIT_SELECTOR_SYM;
-#if ENABLE(CSS_DEVICE_ADAPTATION)
-            else if (isASCIIAlphaCaselessEqual(name[16], 't') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-viewpor&quot;))
-                m_token = WEBKIT_VIEWPORT_RULE_SYM;
-#endif
-            return;
-
-        case 18:
-            if (isEqualToCSSIdentifier(name + 2, &quot;webkit-keyframes&quot;))
-                m_token = KEYFRAMES_SYM;
-            else if (isEqualToCSSIdentifier(name + 2, &quot;webkit-sizesattr&quot;))
-                m_token = WEBKIT_SIZESATTR_SYM;
-            return;
-
-        case 19:
-            if (isEqualToCSSIdentifier(name + 2, &quot;webkit-mediaquery&quot;)) {
-                m_parsingMode = MediaQueryMode;
-                m_token = WEBKIT_MEDIAQUERY_SYM;
-            }
-            return;
-
-        case 22:
-            if (!hasEscape &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-keyframe-rule&quot;))
-                m_token = KEYFRAME_RULE_SYM;
-            return;
-
-        case 27:
-            if (isEqualToCSSIdentifier(name + 2, &quot;webkit-supports-condition&quot;)) {
-                m_parsingMode = SupportsMode;
-                m_token = WEBKIT_SUPPORTS_CONDITION_SYM;
-            }
-            return;
-        }
-    }
-}
-
-template &lt;typename CharacterType&gt;
-inline void CSSParser::detectSupportsToken(int length)
-{
-    ASSERT(m_parsingMode == SupportsMode);
-    CharacterType* name = tokenStart&lt;CharacterType&gt;();
-
-    if (length == 2) {
-        if (isASCIIAlphaCaselessEqual(name[0], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'r'))
-            m_token = SUPPORTS_OR;
-    } else if (length == 3) {
-        if (isASCIIAlphaCaselessEqual(name[0], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'd'))
-            m_token = SUPPORTS_AND;
-        else if (isASCIIAlphaCaselessEqual(name[0], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 't'))
-            m_token = SUPPORTS_NOT;
-    }
-}
-
-template &lt;typename SrcCharacterType&gt;
-int CSSParser::realLex(void* yylvalWithoutType)
-{
-    YYSTYPE* yylval = static_cast&lt;YYSTYPE*&gt;(yylvalWithoutType);
-    // Write pointer for the next character.
-    SrcCharacterType* result;
-    CSSParserString resultString;
-    bool hasEscape;
-
-    // The input buffer is terminated by a \0 character, so
-    // it is safe to read one character ahead of a known non-null.
-#ifndef NDEBUG
-    // In debug we check with an ASSERT that the length is &gt; 0 for string types.
-    yylval-&gt;string.clear();
-#endif
-
-restartAfterComment:
-    result = currentCharacter&lt;SrcCharacterType&gt;();
-    setTokenStart(result);
-    m_tokenStartLineNumber = m_lineNumber;
-    m_tokenStartColumnNumber = tokenStartOffset() - m_columnOffsetForLine;
-    m_token = *currentCharacter&lt;SrcCharacterType&gt;();
-    ++currentCharacter&lt;SrcCharacterType&gt;();
-
-    switch ((m_token &lt;= 127) ? typesOfASCIICharacters[m_token] : CharacterIdentifierStart) {
-    case CharacterCaselessU:
-        if (UNLIKELY(*currentCharacter&lt;SrcCharacterType&gt;() == '+')) {
-            if (parseUnicodeRange&lt;SrcCharacterType&gt;()) {
-                m_token = UNICODERANGE;
-                yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
-                break;
-            }
-        }
-        FALLTHROUGH; // To CharacterIdentifierStart.
-
-    case CharacterIdentifierStart:
-        --currentCharacter&lt;SrcCharacterType&gt;();
-        parseIdentifier(result, yylval-&gt;string, hasEscape);
-        m_token = IDENT;
-
-        if (UNLIKELY(*currentCharacter&lt;SrcCharacterType&gt;() == '(')) {
-            if (m_parsingMode == SupportsMode &amp;&amp; !hasEscape) {
-                detectSupportsToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
-                if (m_token != IDENT)
-                    break;
-            }
-            m_token = FUNCTION;
-            bool shouldSkipParenthesis = true;
-            if (!hasEscape) {
-                bool detected = detectFunctionTypeToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
-                if (!detected &amp;&amp; m_parsingMode == MediaQueryMode) {
-                    // ... and(max-width: 480px) ... looks like a function, but in fact it is not,
-                    // so run more detection code in the MediaQueryMode.
-                    detectMediaQueryToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
-                    shouldSkipParenthesis = false;
-                }
-            }
-
-            if (LIKELY(shouldSkipParenthesis)) {
-                ++currentCharacter&lt;SrcCharacterType&gt;();
-                ++result;
-                ++yylval-&gt;string.m_length;
-            }
-
-            if (token() == URI) {
-                m_token = FUNCTION;
-                // Check whether it is really an URI.
-                if (yylval-&gt;string.is8Bit())
-                    parseURI&lt;LChar&gt;(yylval-&gt;string);
-                else
-                    parseURI&lt;UChar&gt;(yylval-&gt;string);
-            }
-        } else if (UNLIKELY(m_parsingMode != NormalMode) &amp;&amp; !hasEscape) {
-            if (m_parsingMode == MediaQueryMode)
-                detectMediaQueryToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
-            else if (m_parsingMode == SupportsMode)
-                detectSupportsToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
-            else if (m_parsingMode == NthChildMode &amp;&amp; isASCIIAlphaCaselessEqual(tokenStart&lt;SrcCharacterType&gt;()[0], 'n')) {
-                if (result - tokenStart&lt;SrcCharacterType&gt;() == 1) {
-                    // String &quot;n&quot; is IDENT but &quot;n+1&quot; is NTH.
-                    if (parseNthChildExtra&lt;SrcCharacterType&gt;()) {
-                        m_token = NTH;
-                        yylval-&gt;string.m_length = currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;();
-                    }
-                } else if (result - tokenStart&lt;SrcCharacterType&gt;() &gt;= 2 &amp;&amp; tokenStart&lt;SrcCharacterType&gt;()[1] == '-') {
-                    // String &quot;n-&quot; is IDENT but &quot;n-1&quot; is NTH.
-                    // Set currentCharacter to '-' to continue parsing.
-                    SrcCharacterType* nextCharacter = result;
-                    currentCharacter&lt;SrcCharacterType&gt;() = tokenStart&lt;SrcCharacterType&gt;() + 1;
-                    if (parseNthChildExtra&lt;SrcCharacterType&gt;()) {
-                        m_token = NTH;
-                        yylval-&gt;string.setLength(currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
-                    } else {
-                        // Revert the change to currentCharacter if unsuccessful.
-                        currentCharacter&lt;SrcCharacterType&gt;() = nextCharacter;
-                    }
-                }
-            }
-        }
-        if (m_parsingMode == NthChildMode &amp;&amp; m_token == IDENT &amp;&amp; yylval-&gt;string.length() == 2 &amp;&amp; equalLettersIgnoringASCIICase(yylval-&gt;string, &quot;of&quot;)) {
-            m_parsingMode = NormalMode;
-            m_token = NTHCHILDSELECTORSEPARATOR;
-        }
-        break;
-
-    case CharacterDot:
-        if (!isASCIIDigit(currentCharacter&lt;SrcCharacterType&gt;()[0]))
-            break;
-        FALLTHROUGH; // To CharacterNumber.
-
-    case CharacterNumber: {
-        bool dotSeen = (m_token == '.');
-
-        while (true) {
-            if (!isASCIIDigit(currentCharacter&lt;SrcCharacterType&gt;()[0])) {
-                // Only one dot is allowed for a number,
-                // and it must be followed by a digit.
-                if (currentCharacter&lt;SrcCharacterType&gt;()[0] != '.' || dotSeen || !isASCIIDigit(currentCharacter&lt;SrcCharacterType&gt;()[1]))
-                    break;
-                dotSeen = true;
-            }
-            ++currentCharacter&lt;SrcCharacterType&gt;();
-        }
-
-        if (UNLIKELY(m_parsingMode == NthChildMode) &amp;&amp; !dotSeen &amp;&amp; isASCIIAlphaCaselessEqual(*currentCharacter&lt;SrcCharacterType&gt;(), 'n')) {
-            // &quot;[0-9]+n&quot; is always an NthChild.
-            ++currentCharacter&lt;SrcCharacterType&gt;();
-            parseNthChildExtra&lt;SrcCharacterType&gt;();
-            m_token = NTH;
-            yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
-            break;
-        }
-
-        // Use SVG parser for numbers on SVG presentation attributes.
-        if (m_context.mode == SVGAttributeMode) {
-            // We need to take care of units like 'em' or 'ex'.
-            SrcCharacterType* character = currentCharacter&lt;SrcCharacterType&gt;();
-            if (isASCIIAlphaCaselessEqual(*character, 'e')) {
-                ASSERT(character - tokenStart&lt;SrcCharacterType&gt;() &gt; 0);
-                ++character;
-                if (*character == '-' || *character == '+' || isASCIIDigit(*character)) {
-                    ++character;
-                    while (isASCIIDigit(*character))
-                        ++character;
-                    // Use FLOATTOKEN if the string contains exponents.
-                    dotSeen = true;
-                    currentCharacter&lt;SrcCharacterType&gt;() = character;
-                }
-            }
-            if (!parseSVGNumber(tokenStart&lt;SrcCharacterType&gt;(), character - tokenStart&lt;SrcCharacterType&gt;(), yylval-&gt;number))
-                break;
-        } else
-            yylval-&gt;number = charactersToDouble(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());

-        // Type of the function.
-        if (isIdentifierStart&lt;SrcCharacterType&gt;()) {
-            SrcCharacterType* type = currentCharacter&lt;SrcCharacterType&gt;();
-            result = currentCharacter&lt;SrcCharacterType&gt;();
-
-            parseIdentifier(result, resultString, hasEscape);
-
-            m_token = DIMEN;
-            if (!hasEscape)
-                detectNumberToken(type, currentCharacter&lt;SrcCharacterType&gt;() - type);
-
-            if (m_token == DIMEN) {
-                // The decoded number is overwritten, but this is intentional.
-                yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
-            }
-        } else if (*currentCharacter&lt;SrcCharacterType&gt;() == '%') {
-            // Although the CSS grammar says {num}% we follow
-            // webkit at the moment which uses {num}%+.
-            do {
-                ++currentCharacter&lt;SrcCharacterType&gt;();
-            } while (*currentCharacter&lt;SrcCharacterType&gt;() == '%');
-            m_token = PERCENTAGE;
-        } else
-            m_token = dotSeen ? FLOATTOKEN : INTEGER;
-        break;
-    }
-
-    case CharacterDash:
-        if (isIdentifierStartAfterDash(currentCharacter&lt;SrcCharacterType&gt;())) {
-            --currentCharacter&lt;SrcCharacterType&gt;();
-            parseIdentifier(result, resultString, hasEscape);
-            m_token = IDENT;
-
-            if (*currentCharacter&lt;SrcCharacterType&gt;() == '(') {
-                m_token = FUNCTION;
-                if (!hasEscape)
-                    detectDashToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
-                ++currentCharacter&lt;SrcCharacterType&gt;();
-                ++result;
-            } else if (UNLIKELY(m_parsingMode == NthChildMode) &amp;&amp; !hasEscape &amp;&amp; isASCIIAlphaCaselessEqual(tokenStart&lt;SrcCharacterType&gt;()[1], 'n')) {
-                if (result - tokenStart&lt;SrcCharacterType&gt;() == 2) {
-                    // String &quot;-n&quot; is IDENT but &quot;-n+1&quot; is NTH.
-                    if (parseNthChildExtra&lt;SrcCharacterType&gt;()) {
-                        m_token = NTH;
-                        result = currentCharacter&lt;SrcCharacterType&gt;();
-                    }
-                } else if (result - tokenStart&lt;SrcCharacterType&gt;() &gt;= 3 &amp;&amp; tokenStart&lt;SrcCharacterType&gt;()[2] == '-') {
-                    // String &quot;-n-&quot; is IDENT but &quot;-n-1&quot; is NTH.
-                    // Set currentCharacter to second '-' of '-n-' to continue parsing.
-                    SrcCharacterType* nextCharacter = result;
-                    currentCharacter&lt;SrcCharacterType&gt;() = tokenStart&lt;SrcCharacterType&gt;() + 2;
-                    if (parseNthChildExtra&lt;SrcCharacterType&gt;()) {
-                        m_token = NTH;
-                        result = currentCharacter&lt;SrcCharacterType&gt;();
-                    } else {
-                        // Revert the change to currentCharacter if unsuccessful.
-                        currentCharacter&lt;SrcCharacterType&gt;() = nextCharacter;
-                    }
-                }
-            }
-            resultString.setLength(result - tokenStart&lt;SrcCharacterType&gt;());
-            yylval-&gt;string = resultString;
-        } else if (currentCharacter&lt;SrcCharacterType&gt;()[0] == '-' &amp;&amp; currentCharacter&lt;SrcCharacterType&gt;()[1] == '&gt;') {
-            currentCharacter&lt;SrcCharacterType&gt;() += 2;
-            m_token = SGML_CD;
-        } else if (currentCharacter&lt;SrcCharacterType&gt;()[0] == '-') {
-            --currentCharacter&lt;SrcCharacterType&gt;();
-            parseIdentifier(result, resultString, hasEscape);
-            m_token = CUSTOM_PROPERTY;
-            yylval-&gt;string = resultString;
-        } else if (UNLIKELY(m_parsingMode == NthChildMode)) {
-            // &quot;-[0-9]+n&quot; is always an NthChild.
-            if (parseNthChild&lt;SrcCharacterType&gt;()) {
-                parseNthChildExtra&lt;SrcCharacterType&gt;();
-                m_token = NTH;
-                yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
-            }
-        }
-        break;
-
-    case CharacterOther:
-        // m_token is simply the current character.
-        break;
-
-    case CharacterNull:
-        // Do not advance pointer at the end of input.
-        --currentCharacter&lt;SrcCharacterType&gt;();
-        break;
-
-    case CharacterWhiteSpace:
-        m_token = WHITESPACE;
-        // Might start with a '\n'.
-        --currentCharacter&lt;SrcCharacterType&gt;();
-        do {
-            if (*currentCharacter&lt;SrcCharacterType&gt;() == '\n') {
-                ++m_lineNumber;
-                m_columnOffsetForLine = currentCharacterOffset() + 1;
-            }
-            ++currentCharacter&lt;SrcCharacterType&gt;();
-        } while (*currentCharacter&lt;SrcCharacterType&gt;() &lt;= ' ' &amp;&amp; (typesOfASCIICharacters[*currentCharacter&lt;SrcCharacterType&gt;()] == CharacterWhiteSpace));
-        break;
-
-    case CharacterEndConditionQuery: {
-        bool isParsingCondition = m_parsingMode == MediaQueryMode || m_parsingMode == SupportsMode;
-        if (isParsingCondition)
-            m_parsingMode = NormalMode;
-        break;
-    }
-
-    case CharacterEndNthChild:
-        if (m_parsingMode == NthChildMode)
-            m_parsingMode = NormalMode;
-        break;
-
-    case CharacterQuote:
-        if (checkAndSkipString(currentCharacter&lt;SrcCharacterType&gt;(), m_token)) {
-            ++result;
-            parseString&lt;SrcCharacterType&gt;(result, yylval-&gt;string, m_token);
-            m_token = STRING;
-        }
-        break;
-
-    case CharacterExclamationMark: {
-        SrcCharacterType* start = skipWhiteSpace(currentCharacter&lt;SrcCharacterType&gt;());
-        if (isEqualToCSSIdentifier(start, &quot;important&quot;)) {
-            m_token = IMPORTANT_SYM;
-            currentCharacter&lt;SrcCharacterType&gt;() = start + 9;
-        }
-        break;
-    }
-
-    case CharacterHashmark: {
-        SrcCharacterType* start = currentCharacter&lt;SrcCharacterType&gt;();
-        result = currentCharacter&lt;SrcCharacterType&gt;();
-
-        if (isASCIIDigit(*currentCharacter&lt;SrcCharacterType&gt;())) {
-            // This must be a valid hex number token.
-            do {
-                ++currentCharacter&lt;SrcCharacterType&gt;();
-            } while (isASCIIHexDigit(*currentCharacter&lt;SrcCharacterType&gt;()));
-            m_token = HEX;
-            yylval-&gt;string.init(start, currentCharacter&lt;SrcCharacterType&gt;() - start);
-        } else if (isIdentifierStart&lt;SrcCharacterType&gt;()) {
-            m_token = IDSEL;
-            parseIdentifier(result, yylval-&gt;string, hasEscape);
-            if (!hasEscape) {
-                // Check whether the identifier is also a valid hex number.
-                SrcCharacterType* current = start;
-                m_token = HEX;
-                do {
-                    if (!isASCIIHexDigit(*current)) {
-                        m_token = IDSEL;
-                        break;
-                    }
-                    ++current;
-                } while (current &lt; result);
-            }
-        }
-        break;
-    }
-
-    case CharacterSlash:
-        // Ignore comments. They are not even considered as white spaces.
-        if (*currentCharacter&lt;SrcCharacterType&gt;() == '*') {
-            ++currentCharacter&lt;SrcCharacterType&gt;();
-            while (currentCharacter&lt;SrcCharacterType&gt;()[0] != '*' || currentCharacter&lt;SrcCharacterType&gt;()[1] != '/') {
-                if (*currentCharacter&lt;SrcCharacterType&gt;() == '\n') {
-                    ++m_lineNumber;
-                    m_columnOffsetForLine = currentCharacterOffset() + 1;
-                } else if (*currentCharacter&lt;SrcCharacterType&gt;() == '\0') {
-                    // Unterminated comments are simply ignored.
-                    currentCharacter&lt;SrcCharacterType&gt;() -= 2;
-                    break;
-                }
-                ++currentCharacter&lt;SrcCharacterType&gt;();
-            }
-            currentCharacter&lt;SrcCharacterType&gt;() += 2;
-            goto restartAfterComment;
-        }
-        break;
-
-    case CharacterDollar:
-        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
-            ++currentCharacter&lt;SrcCharacterType&gt;();
-            m_token = ENDSWITH;
-        }
-        break;
-
-    case CharacterAsterisk:
-        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
-            ++currentCharacter&lt;SrcCharacterType&gt;();
-            m_token = CONTAINS;
-        }
-        break;
-
-    case CharacterPlus:
-        if (UNLIKELY(m_parsingMode == NthChildMode)) {
-            // Simplest case. &quot;+[0-9]*n&quot; is always NthChild.
-            if (parseNthChild&lt;SrcCharacterType&gt;()) {
-                parseNthChildExtra&lt;SrcCharacterType&gt;();
-                m_token = NTH;
-                yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
-            }
-        }
-        break;
-
-    case CharacterLess:
-        if (currentCharacter&lt;SrcCharacterType&gt;()[0] == '!' &amp;&amp; currentCharacter&lt;SrcCharacterType&gt;()[1] == '-' &amp;&amp; currentCharacter&lt;SrcCharacterType&gt;()[2] == '-') {
-            currentCharacter&lt;SrcCharacterType&gt;() += 3;
-            m_token = SGML_CD;
-        }
-        break;
-
-    case CharacterAt:
-        if (isIdentifierStart&lt;SrcCharacterType&gt;()) {
-            m_token = ATKEYWORD;
-            ++result;
-            parseIdentifier(result, resultString, hasEscape);
-            detectAtToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;(), hasEscape);
-        }
-        break;
-
-    case CharacterBackSlash:
-        if (isCSSEscape(*currentCharacter&lt;SrcCharacterType&gt;())) {
-            --currentCharacter&lt;SrcCharacterType&gt;();
-            parseIdentifier(result, yylval-&gt;string, hasEscape);
-            m_token = IDENT;
-        }
-        if (m_parsingMode == NthChildMode &amp;&amp; m_token == IDENT &amp;&amp; yylval-&gt;string.length() == 2 &amp;&amp; equalLettersIgnoringASCIICase(yylval-&gt;string, &quot;of&quot;)) {
-            m_parsingMode = NormalMode;
-            m_token = NTHCHILDSELECTORSEPARATOR;
-        }
-        break;
-
-    case CharacterXor:
-        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
-            ++currentCharacter&lt;SrcCharacterType&gt;();
-            m_token = BEGINSWITH;
-        }
-        break;
-
-    case CharacterVerticalBar:
-        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
-            ++currentCharacter&lt;SrcCharacterType&gt;();
-            m_token = DASHMATCH;
-        }
-        break;
-
-    case CharacterTilde:
-        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
-            ++currentCharacter&lt;SrcCharacterType&gt;();
-            m_token = INCLUDES;
-        }
-        break;
-
-    default:
-        ASSERT_NOT_REACHED();
-        break;
-    }
-
-    return token();
-}
-
-RefPtr&lt;StyleRuleImport&gt; CSSParser::createImportRule(const CSSParserString&amp; url, RefPtr&lt;MediaQuerySet&gt;&amp;&amp; media)
-{
-    if (!media || !m_allowImportRules) {
-        popRuleData();
-        return nullptr;
-    }
-    auto rule = StyleRuleImport::create(url, media.releaseNonNull());
-    processAndAddNewRuleToSourceTreeIfNeeded();
-    return WTFMove(rule);
-}
-
-Ref&lt;StyleRuleMedia&gt; CSSParser::createMediaRule(RefPtr&lt;MediaQuerySet&gt;&amp;&amp; media, RuleList* rules)
-{
-    m_allowImportRules = m_allowNamespaceDeclarations = false;
-    RefPtr&lt;StyleRuleMedia&gt; rule;
-    RuleList emptyRules;
-    if (!media) {
-        // To comply with w3c test suite expectation, create an empty media query
-        // even when it is syntactically incorrect.
-        rule = StyleRuleMedia::create(MediaQuerySet::create(), emptyRules);
-    } else {
-        media-&gt;shrinkToFit();
-        rule = StyleRuleMedia::create(media.releaseNonNull(), rules ? *rules : emptyRules);
-    }
-    processAndAddNewRuleToSourceTreeIfNeeded();
-    return rule.releaseNonNull();
-}
-
-Ref&lt;StyleRuleMedia&gt; CSSParser::createEmptyMediaRule(RuleList* rules)
-{
-    return createMediaRule(MediaQuerySet::create(), rules);
-}
-
-Ref&lt;StyleRuleSupports&gt; CSSParser::createSupportsRule(bool conditionIsSupported, RuleList* rules)
-{
-    m_allowImportRules = m_allowNamespaceDeclarations = false;
-
-    RefPtr&lt;CSSRuleSourceData&gt; data = popSupportsRuleData();
-    String conditionText;
-    unsigned conditionOffset = data-&gt;ruleHeaderRange.start + 9;
-    unsigned conditionLength = data-&gt;ruleHeaderRange.length() - 9;
-
-    if (is8BitSource())
-        conditionText = String(m_dataStart8.get() + conditionOffset, conditionLength).stripWhiteSpace();
-    else
-        conditionText = String(m_dataStart16.get() + conditionOffset, conditionLength).stripWhiteSpace();
-
-    RefPtr&lt;StyleRuleSupports&gt; rule;
-    if (rules)
-        rule = StyleRuleSupports::create(conditionText, conditionIsSupported, *rules);
-    else {
-        RuleList emptyRules;
-        rule = StyleRuleSupports::create(conditionText, conditionIsSupported, emptyRules);
-    }
-
-    processAndAddNewRuleToSourceTreeIfNeeded();
-
-    return rule.releaseNonNull();
-}
-
-void CSSParser::markSupportsRuleHeaderStart()
-{
-    if (!m_supportsRuleDataStack)
-        m_supportsRuleDataStack = std::make_unique&lt;RuleSourceDataList&gt;();
-
-    auto data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
-    data-&gt;ruleHeaderRange.start = tokenStartOffset();
-    m_supportsRuleDataStack-&gt;append(WTFMove(data));
-}
-
-void CSSParser::markSupportsRuleHeaderEnd()
-{
-    ASSERT(m_supportsRuleDataStack &amp;&amp; !m_supportsRuleDataStack-&gt;isEmpty());
-
-    if (is8BitSource())
-        m_supportsRuleDataStack-&gt;last()-&gt;ruleHeaderRange.end = tokenStart&lt;LChar&gt;() - m_dataStart8.get();
-    else
-        m_supportsRuleDataStack-&gt;last()-&gt;ruleHeaderRange.end = tokenStart&lt;UChar&gt;() - m_dataStart16.get();
-}
-
-Ref&lt;CSSRuleSourceData&gt; CSSParser::popSupportsRuleData()
-{
-    ASSERT(m_supportsRuleDataStack &amp;&amp; !m_supportsRuleDataStack-&gt;isEmpty());
-    return m_supportsRuleDataStack-&gt;takeLast();
-}
-
-void CSSParser::processAndAddNewRuleToSourceTreeIfNeeded()
-{
-    if (!isExtractingSourceData())
-        return;
-    markRuleBodyEnd();
-    Ref&lt;CSSRuleSourceData&gt; rule = *popRuleData();
-    fixUnparsedPropertyRanges(rule);
-    addNewRuleToSourceTree(WTFMove(rule));
-}
-
-void CSSParser::addNewRuleToSourceTree(Ref&lt;CSSRuleSourceData&gt;&amp;&amp; rule)
-{
-    // Precondition: (isExtractingSourceData()).
-    if (!m_ruleSourceDataResult)
-        return;
-    if (m_currentRuleDataStack-&gt;isEmpty())
-        m_ruleSourceDataResult-&gt;append(WTFMove(rule));
-    else
-        m_currentRuleDataStack-&gt;last()-&gt;childRules.append(WTFMove(rule));
-}
-
-RefPtr&lt;CSSRuleSourceData&gt; CSSParser::popRuleData()
-{
-    if (!m_ruleSourceDataResult)
-        return nullptr;
-
-    ASSERT(!m_currentRuleDataStack-&gt;isEmpty());
-    m_currentRuleData = nullptr;
-    return m_currentRuleDataStack-&gt;takeLast();
-}
-
-void CSSParser::syntaxError(const Location&amp; location, SyntaxErrorType error)
-{
-    if (!isLoggingErrors())
-        return;
-
-    StringBuilder builder;
-    switch (error) {
-    case PropertyDeclarationError:
-        builder.appendLiteral(&quot;Invalid CSS property declaration at: &quot;);
-        break;
-    default:
-        builder.appendLiteral(&quot;Unexpected CSS token: &quot;);
-        break;
-    }
-
-    if (location.token.is8Bit())
-        builder.append(location.token.characters8(), location.token.length());
-    else
-        builder.append(location.token.characters16(), location.token.length());
-
-    logError(builder.toString(), location.lineNumber, location.columnNumber);
-
-    m_ignoreErrorsInDeclaration = true;
-}
-
-bool CSSParser::isLoggingErrors()
-{
-    return m_logErrors &amp;&amp; !m_ignoreErrorsInDeclaration;
-}
-
-void CSSParser::logError(const String&amp; message, int lineNumber, int columnNumber)
-{
-    PageConsoleClient&amp; console = m_styleSheet-&gt;singleOwnerDocument()-&gt;page()-&gt;console();
-    console.addMessage(MessageSource::CSS, MessageLevel::Warning, message, m_styleSheet-&gt;baseURL().string(), lineNumber + 1, columnNumber + 1);
-}
-
-Ref&lt;StyleRuleKeyframes&gt; CSSParser::createKeyframesRule(const String&amp; name, std::unique_ptr&lt;Vector&lt;RefPtr&lt;StyleKeyframe&gt;&gt;&gt; keyframes)
-{
-    m_allowImportRules = m_allowNamespaceDeclarations = false;
-    Ref&lt;StyleRuleKeyframes&gt; rule = StyleRuleKeyframes::create();
-    for (auto&amp; keyFrame : *keyframes)
-        rule-&gt;parserAppendKeyframe(WTFMove(keyFrame));
-    rule-&gt;setName(name);
-    processAndAddNewRuleToSourceTreeIfNeeded();
-    return rule;
-}
-
-RefPtr&lt;StyleRule&gt; CSSParser::createStyleRule(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* selectors)
-{
-    RefPtr&lt;StyleRule&gt; rule;
-    if (selectors) {
-        m_allowImportRules = false;
-        m_allowNamespaceDeclarations = false;
-        rule = StyleRule::create(m_lastSelectorLineNumber, createStyleProperties());
-        rule-&gt;parserAdoptSelectorVector(*selectors);
-        processAndAddNewRuleToSourceTreeIfNeeded();
-    } else
-        popRuleData();
-    clearProperties();
-    return rule;
-}
-
-RefPtr&lt;StyleRuleFontFace&gt; CSSParser::createFontFaceRule()
-{
-    m_allowImportRules = m_allowNamespaceDeclarations = false;
-    for (auto&amp; property : m_parsedProperties) {
-        if (property.id() == CSSPropertyFontFamily &amp;&amp; (!is&lt;CSSValueList&gt;(*property.value()) || downcast&lt;CSSValueList&gt;(*property.value()).length() != 1)) {
-            // Unlike font-family property, font-family descriptor in @font-face rule
-            // has to be a value list with exactly one family name. It cannot have a
-            // have 'initial' value and cannot 'inherit' from parent.
-            // See http://dev.w3.org/csswg/css3-fonts/#font-family-desc
-            clearProperties();
-            popRuleData();
-            return nullptr;
-        }
-    }
-    auto rule = StyleRuleFontFace::create(createStyleProperties());
-    clearProperties();
-    processAndAddNewRuleToSourceTreeIfNeeded();
-    return WTFMove(rule);
-}
-
-void CSSParser::addNamespace(const AtomicString&amp; prefix, const AtomicString&amp; uri)
-{
-    if (!m_styleSheet || !m_allowNamespaceDeclarations)
-        return;
-    m_allowImportRules = false;
-    m_styleSheet-&gt;parserAddNamespace(prefix, uri);
-    if (prefix.isEmpty() &amp;&amp; !uri.isNull())
-        m_defaultNamespace = uri;
-}
-
-QualifiedName CSSParser::determineNameInNamespace(const AtomicString&amp; prefix, const AtomicString&amp; localName)
-{
-    if (prefix.isNull())
-        return QualifiedName(nullAtom, localName, nullAtom); // No namespace. If an element/attribute has a namespace, we won't match it.
-    if (prefix.isEmpty())
-        return QualifiedName(emptyAtom, localName, emptyAtom); // Empty namespace.
-    if (prefix == starAtom)
-        return QualifiedName(prefix, localName, starAtom); // We'll match any namespace.
-
-    if (!m_styleSheet)
-        return QualifiedName(prefix, localName, m_defaultNamespace);
-    return QualifiedName(prefix, localName, m_styleSheet-&gt;determineNamespace(prefix));
-}
-
-void CSSParser::rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector&amp; specifiers)
-{
-    if (m_defaultNamespace != starAtom || specifiers.isCustomPseudoElement()) {
-        QualifiedName elementName(nullAtom, starAtom, m_defaultNamespace);
-        rewriteSpecifiersWithElementName(elementName, specifiers, /*tagIsForNamespaceRule*/true);
-    }
-}
-
-void CSSParser::rewriteSpecifiersWithElementName(const AtomicString&amp; namespacePrefix, const AtomicString&amp; elementName, CSSParserSelector&amp; specifiers)
-{
-    QualifiedName tag(determineNameInNamespace(namespacePrefix, elementName));
-    rewriteSpecifiersWithElementName(tag, specifiers, false);
-}
-
-void CSSParser::rewriteSpecifiersWithElementName(const QualifiedName&amp; tag, CSSParserSelector&amp; specifiers, bool tagIsForNamespaceRule)
-{
-    if (!specifiers.isCustomPseudoElement()) {
-        if (tag == anyQName())
-            return;
-        if (!specifiers.isPseudoElementCueFunction())
-            specifiers.prependTagSelector(tag, tagIsForNamespaceRule);
-        return;
-    }
-
-    CSSParserSelector* lastShadowDescendant = &amp;specifiers;
-    CSSParserSelector* history = &amp;specifiers;
-    while (history-&gt;tagHistory()) {
-        history = history-&gt;tagHistory();
-        if (history-&gt;isCustomPseudoElement() || history-&gt;hasShadowDescendant())
-            lastShadowDescendant = history;
-    }
-
-    if (lastShadowDescendant-&gt;tagHistory()) {
-        if (tag != anyQName())
-            lastShadowDescendant-&gt;tagHistory()-&gt;prependTagSelector(tag, tagIsForNamespaceRule);
-        return;
-    }
-
-    // For shadow-ID pseudo-elements to be correctly matched, the ShadowDescendant combinator has to be used.
-    // We therefore create a new Selector with that combinator here in any case, even if matching any (host) element in any namespace (i.e. '*').
-    lastShadowDescendant-&gt;setTagHistory(std::make_unique&lt;CSSParserSelector&gt;(tag));
-    lastShadowDescendant-&gt;setRelation(CSSSelector::ShadowDescendant);
-}
-
-std::unique_ptr&lt;CSSParserSelector&gt; CSSParser::rewriteSpecifiers(std::unique_ptr&lt;CSSParserSelector&gt; specifiers, std::unique_ptr&lt;CSSParserSelector&gt; newSpecifier)
-{
-    if (newSpecifier-&gt;isCustomPseudoElement() || newSpecifier-&gt;isPseudoElementCueFunction()) {
-        // Unknown pseudo element always goes at the top of selector chain.
-        newSpecifier-&gt;appendTagHistory(CSSSelector::ShadowDescendant, WTFMove(specifiers));
-        return newSpecifier;
-    }
-    if (specifiers-&gt;isCustomPseudoElement()) {
-        // Specifiers for unknown pseudo element go right behind it in the chain.
-        specifiers-&gt;insertTagHistory(CSSSelector::SubSelector, WTFMove(newSpecifier), CSSSelector::ShadowDescendant);
-        return specifiers;
-    }
-    specifiers-&gt;appendTagHistory(CSSSelector::SubSelector, WTFMove(newSpecifier));
-    return specifiers;
-}
-
-RefPtr&lt;StyleRulePage&gt; CSSParser::createPageRule(std::unique_ptr&lt;CSSParserSelector&gt; pageSelector)
-{
-    // FIXME: Margin at-rules are ignored.
-    m_allowImportRules = m_allowNamespaceDeclarations = false;
-    if (pageSelector) {
-        auto rule = StyleRulePage::create(createStyleProperties());
-        Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt; selectorVector;
-        selectorVector.append(WTFMove(pageSelector));
-        rule-&gt;parserAdoptSelectorVector(selectorVector);
-        processAndAddNewRuleToSourceTreeIfNeeded();
-        clearProperties();
-        return WTFMove(rule);
-    }
-
-    popRuleData();
-    clearProperties();
-    return nullptr;
-}
-
-std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; CSSParser::createSelectorVector()
-{
-    if (m_recycledSelectorVector) {
-        m_recycledSelectorVector-&gt;shrink(0);
-        return WTFMove(m_recycledSelectorVector);
-    }
-    return std::make_unique&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt;();
-}
-
-void CSSParser::recycleSelectorVector(std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; vector)
-{
-    if (vector &amp;&amp; !m_recycledSelectorVector)
-        m_recycledSelectorVector = WTFMove(vector);
-}
-
-RefPtr&lt;StyleRuleRegion&gt; CSSParser::createRegionRule(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* regionSelector, RuleList* rules)
-{
-    if (!regionSelector || !rules) {
-        popRuleData();
-        return nullptr;
-    }
-
-    m_allowImportRules = m_allowNamespaceDeclarations = false;
-
-    auto regionRule = StyleRuleRegion::create(regionSelector, *rules);
-
-    if (isExtractingSourceData())
-        addNewRuleToSourceTree(CSSRuleSourceData::createUnknown());
-
-    return WTFMove(regionRule);
-}
-
-void CSSParser::createMarginAtRule(CSSSelector::MarginBoxType /* marginBox */)
-{
-    // FIXME: Implement margin at-rule here, using:
-    //        - marginBox: margin box
-    //        - m_parsedProperties: properties at [m_numParsedPropertiesBeforeMarginBox, m_parsedProperties.size()] are for this at-rule.
-    // Don't forget to also update the action for page symbol in CSSGrammar.y such that margin at-rule data is cleared if page_selector is invalid.
-
-    endDeclarationsForMarginBox();
-}
-
-void CSSParser::startDeclarationsForMarginBox()
-{
-    m_numParsedPropertiesBeforeMarginBox = m_parsedProperties.size();
-}
-
-void CSSParser::endDeclarationsForMarginBox()
-{
-    rollbackLastProperties(m_parsedProperties.size() - m_numParsedPropertiesBeforeMarginBox);
-    m_numParsedPropertiesBeforeMarginBox = invalidParsedPropertiesCount;
-}
-
-RefPtr&lt;StyleKeyframe&gt; CSSParser::createKeyframe(CSSParserValueList&amp; keys)
-{
-    // Create a key string from the passed keys
-    StringBuilder keyString;
-    for (unsigned i = 0; i &lt; keys.size(); ++i) {
-        // Just as per the comment below, we ignore keyframes with
-        // invalid key values (plain numbers or unknown identifiers)
-        // marked as CSSPrimitiveValue::CSS_UNKNOWN during parsing.
-        if (keys.valueAt(i)-&gt;unit == CSSPrimitiveValue::CSS_UNKNOWN) {
-            clearProperties();
-            return nullptr;
-        }
-
-        ASSERT(keys.valueAt(i)-&gt;unit == CSSPrimitiveValue::CSS_NUMBER);
-        float key = static_cast&lt;float&gt;(keys.valueAt(i)-&gt;fValue);
-        if (key &lt; 0 || key &gt; 100) {
-            // As per http://www.w3.org/TR/css3-animations/#keyframes,
-            // &quot;If a keyframe selector specifies negative percentage values
-            // or values higher than 100%, then the keyframe will be ignored.&quot;
-            clearProperties();
-            return nullptr;
-        }
-        if (i != 0)
-            keyString.append(',');
-        keyString.appendNumber(key);
-        keyString.append('%');
-    }
-
-    auto keyframe = StyleKeyframe::create(createStyleProperties());
-    keyframe-&gt;setKeyText(keyString.toString());
-
-    clearProperties();
-
-    return WTFMove(keyframe);
-}
-
-void CSSParser::invalidBlockHit()
-{
-    if (m_styleSheet &amp;&amp; !m_hadSyntacticallyValidCSSRule)
-        m_styleSheet-&gt;setHasSyntacticallyValidCSSHeader(false);
-}
-
-void CSSParser::updateLastSelectorLineAndPosition()
-{
-    m_lastSelectorLineNumber = m_lineNumber;
-}
-
-void CSSParser::updateLastMediaLine(MediaQuerySet&amp; media)
-{
-    media.setLastLine(m_lineNumber);
-}
-
-template &lt;typename CharacterType&gt;
-static inline void fixUnparsedProperties(const CharacterType* characters, CSSRuleSourceData&amp; ruleData)
-{
-    auto&amp; propertyData = ruleData.styleSourceData-&gt;propertyData;
-    unsigned size = propertyData.size();
-    if (!size)
-        return;
-
-    unsigned styleStart = ruleData.ruleBodyRange.start;
-    auto* nextData = &amp;propertyData[0];
-    for (unsigned i = 0; i &lt; size; ++i) {
-        auto* currentData = nextData;
-        nextData = i &lt; size - 1 ? &amp;propertyData[i + 1] : 0;
-
-        if (currentData-&gt;parsedOk)
-            continue;
-        if (currentData-&gt;range.end &gt; 0 &amp;&amp; characters[styleStart + currentData-&gt;range.end - 1] == ';')
-            continue;
-
-        unsigned propertyEndInStyleSheet;
-        if (!nextData)
-            propertyEndInStyleSheet = ruleData.ruleBodyRange.end - 1;
-        else
-            propertyEndInStyleSheet = styleStart + nextData-&gt;range.start - 1;
-
-        while (isHTMLSpace(characters[propertyEndInStyleSheet]))
-            --propertyEndInStyleSheet;
-
-        // propertyEndInStyleSheet points at the last property text character.
-        unsigned newPropertyEnd = propertyEndInStyleSheet - styleStart + 1; // Exclusive of the last property text character.
-        if (currentData-&gt;range.end != newPropertyEnd) {
-            currentData-&gt;range.end = newPropertyEnd;
-            unsigned valueStartInStyleSheet = styleStart + currentData-&gt;range.start + currentData-&gt;name.length();
-            while (valueStartInStyleSheet &lt; propertyEndInStyleSheet &amp;&amp; characters[valueStartInStyleSheet] != ':')
-                ++valueStartInStyleSheet;
-            if (valueStartInStyleSheet &lt; propertyEndInStyleSheet)
-                ++valueStartInStyleSheet; // Shift past the ':'.
-            while (valueStartInStyleSheet &lt; propertyEndInStyleSheet &amp;&amp; isHTMLSpace(characters[valueStartInStyleSheet]))
-                ++valueStartInStyleSheet;
-            // Need to exclude the trailing ';' from the property value.
-            currentData-&gt;value = String(characters + valueStartInStyleSheet, propertyEndInStyleSheet - valueStartInStyleSheet + (characters[propertyEndInStyleSheet] == ';' ? 0 : 1));
-        }
-    }
-}
-
-void CSSParser::fixUnparsedPropertyRanges(CSSRuleSourceData&amp; ruleData)
-{
-    if (!ruleData.styleSourceData)
-        return;
-
-    if (is8BitSource()) {
-        fixUnparsedProperties&lt;LChar&gt;(m_dataStart8.get() + m_parsedTextPrefixLength, ruleData);
-        return;
-    }
-
-    fixUnparsedProperties&lt;UChar&gt;(m_dataStart16.get() + m_parsedTextPrefixLength, ruleData);
-}
-
-void CSSParser::markRuleHeaderStart(CSSRuleSourceData::Type ruleType)
-{
-    if (!isExtractingSourceData())
-        return;
-
-    // Pop off data for a previous invalid rule.
-    if (m_currentRuleData)
-        m_currentRuleDataStack-&gt;removeLast();
-
-    auto data = CSSRuleSourceData::create(ruleType);
-    data-&gt;ruleHeaderRange.start = tokenStartOffset();
-    m_currentRuleData = data.copyRef();
-    m_currentRuleDataStack-&gt;append(WTFMove(data));
-}
-
-template &lt;typename CharacterType&gt;
-inline void CSSParser::setRuleHeaderEnd(const CharacterType* dataStart)
-{
-    CharacterType* listEnd = tokenStart&lt;CharacterType&gt;();
-    while (listEnd &gt; dataStart + 1) {
-        if (isHTMLSpace(*(listEnd - 1)))
-            --listEnd;
-        else
-            break;
-    }
-
-    m_currentRuleDataStack-&gt;last()-&gt;ruleHeaderRange.end = listEnd - dataStart;
-}
-
-void CSSParser::markRuleHeaderEnd()
-{
-    if (!isExtractingSourceData())
-        return;
-    ASSERT(!m_currentRuleDataStack-&gt;isEmpty());
-
-    if (is8BitSource())
-        setRuleHeaderEnd&lt;LChar&gt;(m_dataStart8.get());
-    else
-        setRuleHeaderEnd&lt;UChar&gt;(m_dataStart16.get());
-}
-
-void CSSParser::markSelectorStart()
-{
-    if (!isExtractingSourceData() || m_nestedSelectorLevel)
-        return;
-    ASSERT(!m_selectorRange.end);
-
-    m_selectorRange.start = tokenStartOffset();
-}
-
-void CSSParser::markSelectorEnd()
-{
-    if (!isExtractingSourceData() || m_nestedSelectorLevel)
-        return;
-    ASSERT(!m_selectorRange.end);
-    ASSERT(m_currentRuleDataStack-&gt;size());
-
-    m_selectorRange.end = tokenStartOffset();
-    m_currentRuleDataStack-&gt;last()-&gt;selectorRanges.append(m_selectorRange);
-    m_selectorRange.start = 0;
-    m_selectorRange.end = 0;
-}
-
-void CSSParser::markRuleBodyStart()
-{
-    if (!isExtractingSourceData())
-        return;
-    m_currentRuleData = nullptr;
-    unsigned offset = tokenStartOffset();
-    if (tokenStartChar() == '{')
-        ++offset; // Skip the rule body opening brace.
-    ASSERT(!m_currentRuleDataStack-&gt;isEmpty());
-    m_currentRuleDataStack-&gt;last()-&gt;ruleBodyRange.start = offset;
-}
-
-void CSSParser::markRuleBodyEnd()
-{
-    // Precondition: (!isExtractingSourceData())
-    unsigned offset = tokenStartOffset();
-    ASSERT(!m_currentRuleDataStack-&gt;isEmpty());
-    m_currentRuleDataStack-&gt;last()-&gt;ruleBodyRange.end = offset;
-}
-
-void CSSParser::markPropertyStart()
-{
-    m_ignoreErrorsInDeclaration = false;
-    if (!isExtractingSourceData())
-        return;
-    if (m_currentRuleDataStack-&gt;isEmpty() || !m_currentRuleDataStack-&gt;last()-&gt;styleSourceData)
-        return;
-
-    m_propertyRange.start = tokenStartOffset();
-}
-
-void CSSParser::markPropertyEnd(bool isImportantFound, bool isPropertyParsed)
-{
-    if (!isExtractingSourceData())
-        return;
-    if (m_currentRuleDataStack-&gt;isEmpty() || !m_currentRuleDataStack-&gt;last()-&gt;styleSourceData)
-        return;
-
-    unsigned offset = tokenStartOffset();
-    if (tokenStartChar() == ';') // Include semicolon into the property text.
-        ++offset;
-    m_propertyRange.end = offset;
-    if (m_propertyRange.start != std::numeric_limits&lt;unsigned&gt;::max() &amp;&amp; !m_currentRuleDataStack-&gt;isEmpty()) {
-        // This stuff is only executed when the style data retrieval is requested by client.
-        const unsigned start = m_propertyRange.start;
-        const unsigned end = m_propertyRange.end;
-        ASSERT_WITH_SECURITY_IMPLICATION(start &lt; end);
-        String propertyString;
-        if (is8BitSource())
-            propertyString = String(m_dataStart8.get() + start, end - start).stripWhiteSpace();
-        else
-            propertyString = String(m_dataStart16.get() + start, end - start).stripWhiteSpace();
-        if (propertyString.endsWith(';'))
-            propertyString = propertyString.left(propertyString.length() - 1);
-        size_t colonIndex = propertyString.find(':');
-        ASSERT(colonIndex != notFound);
-
-        String name = propertyString.left(colonIndex).stripWhiteSpace();
-        String value = propertyString.substring(colonIndex + 1, propertyString.length()).stripWhiteSpace();
-        // The property range is relative to the declaration start offset.
-        SourceRange&amp; topRuleBodyRange = m_currentRuleDataStack-&gt;last()-&gt;ruleBodyRange;
-        m_currentRuleDataStack-&gt;last()-&gt;styleSourceData-&gt;propertyData.append(
-            CSSPropertySourceData(name, value, isImportantFound, isPropertyParsed, SourceRange(start - topRuleBodyRange.start, end - topRuleBodyRange.start)));
-    }
-    resetPropertyRange();
-}
-
-#if ENABLE(CSS_DEVICE_ADAPTATION)
-Ref&lt;StyleRuleViewport&gt; CSSParser::createViewportRule()
-{
-    m_allowImportRules = m_allowNamespaceDeclarations = false;
-
-    auto rule = StyleRuleViewport::create(createStyleProperties());
-    clearProperties();
-
-    processAndAddNewRuleToSourceTreeIfNeeded();
-
-    return rule;
-}
-
-bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important)
-{
-    if (!m_valueList-&gt;current())
-        return false;
-
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-
-    CSSValueID id = valueWithCalculation.value().id;
-    bool validPrimitive = false;
-
-    switch (propId) {
-    case CSSPropertyMinWidth: // auto | device-width | device-height | &lt;length&gt; | &lt;percentage&gt;
-    case CSSPropertyMaxWidth:
-    case CSSPropertyMinHeight:
-    case CSSPropertyMaxHeight:
-        if (id == CSSValueAuto || id == CSSValueDeviceWidth || id == CSSValueDeviceHeight)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg));
-        break;
-    case CSSPropertyWidth: // shorthand
-        return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important);
-    case CSSPropertyHeight:
-        return parseViewportShorthand(propId, CSSPropertyMinHeight, CSSPropertyMaxHeight, important);
-    case CSSPropertyMinZoom: // auto | &lt;number&gt; | &lt;percentage&gt;
-    case CSSPropertyMaxZoom:
-    case CSSPropertyZoom:
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FPercent | FNonNeg));
-        break;
-    case CSSPropertyUserZoom: // zoom | fixed
-        if (id == CSSValueZoom || id == CSSValueFixed)
-            validPrimitive = true;
-        break;
-    case CSSPropertyOrientation: // auto | portrait | landscape
-        if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandscape)
-            validPrimitive = true;
-    default:
-        break;
-    }
-
-    RefPtr&lt;CSSValue&gt; parsedValue;
-    if (validPrimitive) {
-        parsedValue = parseValidPrimitive(id, valueWithCalculation);
-        m_valueList-&gt;next();
-    }
-
-    if (!parsedValue)
-        return false;
-
-    if (m_valueList-&gt;current() &amp;&amp; !inShorthand())
-        return false;
-
-    addProperty(propId, parsedValue.releaseNonNull(), important);
-    return true;
-}
-
-bool CSSParser::parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important)
-{
-    unsigned numValues = m_valueList-&gt;size();
-
-    if (numValues &gt; 2)
-        return false;
-
-    ShorthandScope scope(this, propId);
-
-    if (!parseViewportProperty(first, important))
-        return false;
-
-    // If just one value is supplied, the second value
-    // is implicitly initialized with the first value.
-    if (numValues == 1)
-        m_valueList-&gt;previous();
-
-    return parseViewportProperty(second, important);
-}
-#endif
-
-template &lt;typename CharacterType&gt;
-static CSSPropertyID cssPropertyID(const CharacterType* propertyName, unsigned length)
-{
-    char buffer[maxCSSPropertyNameLength + 1 + 1]; // 1 to turn &quot;apple&quot;/&quot;khtml&quot; into &quot;webkit&quot;, 1 for null character
-
-    for (unsigned i = 0; i != length; ++i) {
-        CharacterType c = propertyName[i];
-        if (c == 0 || c &gt;= 0x7F)
-            return CSSPropertyInvalid; // illegal character
-        buffer[i] = toASCIILower(c);
-    }
-    buffer[length] = '\0';
-
-    const char* name = buffer;
-    if (buffer[0] == '-') {
-#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
-        // If the prefix is -apple- or -khtml-, change it to -webkit-.
-        // This makes the string one character longer.
-        if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled()
-            &amp;&amp; (hasPrefix(buffer, length, &quot;-apple-&quot;) || hasPrefix(buffer, length, &quot;-khtml-&quot;))) {
-            memmove(buffer + 7, buffer + 6, length + 1 - 6);
-            memcpy(buffer, &quot;-webkit&quot;, 7);
-            ++length;
-        }
-#endif
-#if PLATFORM(IOS)
-        cssPropertyNameIOSAliasing(buffer, name, length);
-#endif
-    }
-
-    const Property* hashTableEntry = findProperty(name, length);
-    return hashTableEntry ? static_cast&lt;CSSPropertyID&gt;(hashTableEntry-&gt;id) : CSSPropertyInvalid;
-}
-
-CSSPropertyID cssPropertyID(const String&amp; string)
-{
-    unsigned length = string.length();
-
-    if (!length)
-        return CSSPropertyInvalid;
-    if (length &gt; maxCSSPropertyNameLength)
-        return CSSPropertyInvalid;
-    
-    return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
-}
-
-CSSPropertyID cssPropertyID(const CSSParserString&amp; string)
-{
-    unsigned length = string.length();
-
-    if (!length)
-        return CSSPropertyInvalid;
-    if (length &gt; maxCSSPropertyNameLength)
-        return CSSPropertyInvalid;
-    
-    return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
-}
-
-#if PLATFORM(IOS)
-void cssPropertyNameIOSAliasing(const char* propertyName, const char*&amp; propertyNameAlias, unsigned&amp; newLength)
-{
-    if (!strcmp(propertyName, &quot;-webkit-hyphenate-locale&quot;)) {
-        // Worked in iOS 4.2.
-        static const char webkitLocale[] = &quot;-webkit-locale&quot;;
-        propertyNameAlias = webkitLocale;
-        newLength = strlen(webkitLocale);
-    }
-}
-#endif
-
-static bool isAppleLegacyCssValueKeyword(const char* valueKeyword, unsigned length)
-{
-    static const char applePrefix[] = &quot;-apple-&quot;;
-    static const char appleSystemPrefix[] = &quot;-apple-system&quot;;
-    static const char* appleWirelessPlaybackTargetActive = getValueName(CSSValueAppleWirelessPlaybackTargetActive);
-
-    return hasPrefix(valueKeyword, length, applePrefix)
-        &amp;&amp; !hasPrefix(valueKeyword, length, appleSystemPrefix)
-        &amp;&amp; !WTF::equal(reinterpret_cast&lt;const LChar*&gt;(valueKeyword), reinterpret_cast&lt;const LChar*&gt;(appleWirelessPlaybackTargetActive), length);
-}
-
-template &lt;typename CharacterType&gt;
-static CSSValueID cssValueKeywordID(const CharacterType* valueKeyword, unsigned length)
-{
-    char buffer[maxCSSValueKeywordLength + 1 + 1]; // 1 to turn &quot;apple&quot;/&quot;khtml&quot; into &quot;webkit&quot;, 1 for null character
-
-    for (unsigned i = 0; i != length; ++i) {
-        CharacterType c = valueKeyword[i];
-        if (c == 0 || c &gt;= 0x7F)
-            return CSSValueInvalid; // illegal keyword.
-        buffer[i] = WTF::toASCIILower(c);
-    }
-    buffer[length] = '\0';
-
-    if (buffer[0] == '-') {
-        // If the prefix is -apple- or -khtml-, change it to -webkit-.
-        // This makes the string one character longer.
-        // On iOS we don't want to change values starting with -apple-system to -webkit-system.
-        // FIXME: Remove this mangling without breaking the web.
-        if (isAppleLegacyCssValueKeyword(buffer, length) || hasPrefix(buffer, length, &quot;-khtml-&quot;)) {
-            memmove(buffer + 7, buffer + 6, length + 1 - 6);
-            memcpy(buffer, &quot;-webkit&quot;, 7);
-            ++length;
-        }
-    }
-
-    const Value* hashTableEntry = findValue(buffer, length);
-    return hashTableEntry ? static_cast&lt;CSSValueID&gt;(hashTableEntry-&gt;id) : CSSValueInvalid;
-}
-
-CSSValueID cssValueKeywordID(const CSSParserString&amp; string)
-{
-    unsigned length = string.length();
-    if (!length)
-        return CSSValueInvalid;
-    if (length &gt; maxCSSValueKeywordLength)
-        return CSSValueInvalid;
-
-    return string.is8Bit() ? cssValueKeywordID(string.characters8(), length) : cssValueKeywordID(string.characters16(), length);
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool isCSSTokenizerIdentifier(const CharacterType* characters, unsigned length)
-{
-    const CharacterType* end = characters + length;
-
-    // -?
-    if (characters != end &amp;&amp; characters[0] == '-')
-        ++characters;
-
-    // {nmstart}
-    if (characters == end || !(characters[0] == '_' || characters[0] &gt;= 128 || isASCIIAlpha(characters[0])))
-        return false;
-    ++characters;
-
-    // {nmchar}*
-    for (; characters != end; ++characters) {
-        if (!(characters[0] == '_' || characters[0] == '-' || characters[0] &gt;= 128 || isASCIIAlphanumeric(characters[0])))
-            return false;
-    }
-
-    return true;
-}
-
-// &quot;ident&quot; from the CSS tokenizer, minus backslash-escape sequences
-static bool isCSSTokenizerIdentifier(const String&amp; string)
-{
-    unsigned length = string.length();
-
-    if (!length)
-        return false;
-
-    if (string.is8Bit())
-        return isCSSTokenizerIdentifier(string.characters8(), length);
-    return isCSSTokenizerIdentifier(string.characters16(), length);
-}
-
-template &lt;typename CharacterType&gt;
-static inline bool isCSSTokenizerURL(const CharacterType* characters, unsigned length)
-{
-    const CharacterType* end = characters + length;
-    
-    for (; characters != end; ++characters) {
-        CharacterType c = characters[0];
-        switch (c) {
-            case '!':
-            case '#':
-            case '$':
-            case '%':
-            case '&amp;':
-                break;
-            default:
-                if (c &lt; '*')
-                    return false;
-                if (c &lt;= '~')
-                    break;
-                if (c &lt; 128)
-                    return false;
-        }
-    }
-    
-    return true;
-}
-
-// &quot;url&quot; from the CSS tokenizer, minus backslash-escape sequences
-static bool isCSSTokenizerURL(const String&amp; string)
-{
-    unsigned length = string.length();
-
-    if (!length)
-        return true;
-
-    if (string.is8Bit())
-        return isCSSTokenizerURL(string.characters8(), length);
-    return isCSSTokenizerURL(string.characters16(), length);
-}
-
-
-template &lt;typename CharacterType&gt;
-static inline String quoteCSSStringInternal(const CharacterType* characters, unsigned length)
-{
-    // For efficiency, we first pre-calculate the length of the quoted string, then we build the actual one.
-    // Please see below for the actual logic.
-    unsigned quotedStringSize = 2; // Two quotes surrounding the entire string.
-    bool afterEscape = false;
-    for (unsigned i = 0; i &lt; length; ++i) {
-        CharacterType ch = characters[i];
-        if (ch == '\\' || ch == '\'') {
-            quotedStringSize += 2;
-            afterEscape = false;
-        } else if (ch &lt; 0x20 || ch == 0x7F) {
-            quotedStringSize += 2 + (ch &gt;= 0x10);
-            afterEscape = true;
-        } else {
-            quotedStringSize += 1 + (afterEscape &amp;&amp; (isASCIIHexDigit(ch) || ch == ' '));
-            afterEscape = false;
-        }
-    }
-
-    StringBuffer&lt;CharacterType&gt; buffer(quotedStringSize);
-    unsigned index = 0;
-    buffer[index++] = '\'';
-    afterEscape = false;
-    for (unsigned i = 0; i &lt; length; ++i) {
-        CharacterType ch = characters[i];
-        if (ch == '\\' || ch == '\'') {
-            buffer[index++] = '\\';
-            buffer[index++] = ch;
-            afterEscape = false;
-        } else if (ch &lt; 0x20 || ch == 0x7F) { // Control characters.
-            buffer[index++] = '\\';
-            placeByteAsHexCompressIfPossible(ch, buffer, index, Lowercase);
-            afterEscape = true;
-        } else {
-            // Space character may be required to separate backslash-escape sequence and normal characters.
-            if (afterEscape &amp;&amp; (isASCIIHexDigit(ch) || ch == ' '))
-                buffer[index++] = ' ';
-            buffer[index++] = ch;
-            afterEscape = false;
-        }
-    }
-    buffer[index++] = '\'';
-
-    ASSERT(quotedStringSize == index);
-    return String::adopt(buffer);
-}
-
-// We use single quotes for now because markup.cpp uses double quotes.
-String quoteCSSString(const String&amp; string)
-{
-    // This function expands each character to at most 3 characters ('\u0010' -&gt; '\' '1' '0') as well as adds
-    // 2 quote characters (before and after). Make sure the resulting size (3 * length + 2) will not overflow unsigned.
-
-    unsigned length = string.length();
-
-    if (!length)
-        return ASCIILiteral(&quot;\'\'&quot;);
-
-    if (length &gt; std::numeric_limits&lt;unsigned&gt;::max() / 3 - 2)
-        return emptyString();
-
-    if (string.is8Bit())
-        return quoteCSSStringInternal(string.characters8(), length);
-    return quoteCSSStringInternal(string.characters16(), length);
-}
-
-String quoteCSSStringIfNeeded(const String&amp; string)
-{
-    return isCSSTokenizerIdentifier(string) ? string : quoteCSSString(string);
-}
-
-String quoteCSSURLIfNeeded(const String&amp; string)
-{
-    return isCSSTokenizerURL(string) ? string : quoteCSSString(string);
-}
-
-bool isValidNthToken(const CSSParserString&amp; token)
-{
-    // The tokenizer checks for the construct of an+b.
-    // However, since the {ident} rule precedes the {nth} rule, some of those
-    // tokens are identified as string literal. Furthermore we need to accept
-    // &quot;odd&quot; and &quot;even&quot; which does not match to an+b.
-    return equalLettersIgnoringASCIICase(token, &quot;odd&quot;)
-        || equalLettersIgnoringASCIICase(token, &quot;even&quot;)
-        || equalLettersIgnoringASCIICase(token, &quot;n&quot;)
-        || equalLettersIgnoringASCIICase(token, &quot;-n&quot;);
-}
-
-}
</del></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/css/CSSParser.h (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.h        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/css/CSSParser.h        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -1,800 +0,0 @@
</span><del>-/*
- * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004-2010, 2015 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Eric Seidel &lt;eric@webkit.org&gt;
- * Copyright (C) 2009 - 2010  Torch Mobile (Beijing) Co. Ltd. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#pragma once
-
-#include &quot;CSSCalculationValue.h&quot;
-#include &quot;CSSGradientValue.h&quot;
-#include &quot;CSSParserMode.h&quot;
-#include &quot;CSSParserValues.h&quot;
-#include &quot;CSSProperty.h&quot;
-#include &quot;CSSPropertyNames.h&quot;
-#include &quot;CSSPropertySourceData.h&quot;
-#include &quot;CSSValueKeywords.h&quot;
-#include &quot;Color.h&quot;
-#include &quot;MediaQuery.h&quot;
-#include &quot;SourceSizeList.h&quot;
-#include &quot;StyleRuleImport.h&quot;
-#include &quot;WebKitCSSFilterValue.h&quot;
-#include &lt;memory&gt;
-#include &lt;wtf/HashMap.h&gt;
-#include &lt;wtf/Vector.h&gt;
-#include &lt;wtf/text/AtomicString.h&gt;
-#include &lt;wtf/text/TextPosition.h&gt;
-
-#if ENABLE(CSS_GRID_LAYOUT)
-#include &quot;GridArea.h&quot;
-#endif
-
-namespace WebCore {
-
-class AnimationParseContext;
-class CSSBorderImageSliceValue;
-class CSSContentDistributionValue;
-class CSSPrimitiveValue;
-class CSSSelectorList;
-class CSSValue;
-class CSSValueList;
-class CSSBasicShape;
-class CSSBasicShapeCircle;
-class CSSBasicShapeEllipse;
-class CSSBasicShapeInset;
-class CSSBasicShapePath;
-class CSSBasicShapePolygon;
-class CSSGridLineNamesValue;
-class CSSImageSetValue;
-class CSSVariableDependentValue;
-class Document;
-class Element;
-class ImmutableStyleProperties;
-class MediaQueryExpression;
-class MediaQuerySet;
-class MutableStyleProperties;
-class SVGColor;
-class SVGPaint;
-class StyleKeyframe;
-class StylePropertyShorthand;
-class StyleRule;
-class StyleRuleBase;
-class StyleRuleFontFace;
-class StyleRuleKeyframes;
-class StyleRuleMedia;
-class StyleRulePage;
-class StyleRuleRegion;
-class StyleRuleSupports;
-class StyleRuleViewport;
-class StyleKeyframe;
-class StyleSheetContents;
-class StyledElement;
-class WebKitCSSTransformValue;
-
-class CSSParser {
-    friend inline int cssyylex(void*, CSSParser*);
-
-public:
-    struct Location;
-    enum SyntaxErrorType {
-        PropertyDeclarationError,
-        GeneralSyntaxError
-    };
-
-    enum class ParseResult {
-        Changed,
-        Unchanged,
-        Error
-    };
-
-    class ValueWithCalculation {
-    public:
-        explicit ValueWithCalculation(CSSParserValue&amp; value)
-            : m_value(value)
-        { }
-
-        CSSParserValue&amp; value() const { return m_value; }
-        operator CSSParserValue&amp;() { return m_value; }
-
-        RefPtr&lt;CSSCalcValue&gt; calculation() const { return m_calculation; }
-        void setCalculation(RefPtr&lt;CSSCalcValue&gt;&amp;&amp; calculation)
-        {
-            ASSERT(isCalculation(m_value));
-            m_calculation = calculation;
-        }
-
-    private:
-        CSSParserValue&amp; m_value;
-        RefPtr&lt;CSSCalcValue&gt; m_calculation;
-    };
-
-    WEBCORE_EXPORT CSSParser(const CSSParserContext&amp;);
-    WEBCORE_EXPORT ~CSSParser();
-
-    void parseSheet(StyleSheetContents*, const String&amp;, const TextPosition&amp;, RuleSourceDataList*, bool logErrors);
-    RefPtr&lt;StyleRuleBase&gt; parseRule(StyleSheetContents*, const String&amp;);
-    RefPtr&lt;StyleKeyframe&gt; parseKeyframeRule(StyleSheetContents*, const String&amp;);
-    bool parseSupportsCondition(const String&amp;);
-
-    static ParseResult parseValue(MutableStyleProperties&amp;, CSSPropertyID, const String&amp;, bool important, CSSParserMode, StyleSheetContents*);
-    static ParseResult parseCustomPropertyValue(MutableStyleProperties&amp;, const AtomicString&amp; propertyName, const String&amp;, bool important, CSSParserMode, StyleSheetContents* contextStyleSheet);
-
-    static bool parseColor(RGBA32&amp; color, const String&amp;, bool strict = false);
-    static bool isValidSystemColorValue(CSSValueID);
-    static bool parseSystemColor(RGBA32&amp; color, const String&amp;, Document*);
-    static RefPtr&lt;CSSValueList&gt; parseFontFaceValue(const AtomicString&amp;);
-    RefPtr&lt;CSSPrimitiveValue&gt; parseValidPrimitive(CSSValueID ident, ValueWithCalculation&amp;);
-
-    WEBCORE_EXPORT bool parseDeclaration(MutableStyleProperties&amp;, const String&amp;, RefPtr&lt;CSSRuleSourceData&gt;&amp;&amp;, StyleSheetContents* contextStyleSheet);
-    static Ref&lt;ImmutableStyleProperties&gt; parseInlineStyleDeclaration(const String&amp;, Element*);
-    std::unique_ptr&lt;MediaQuery&gt; parseMediaQuery(const String&amp;);
-
-    void addPropertyWithPrefixingVariant(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;&amp;, bool important, bool implicit = false);
-    void addProperty(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;&amp;, bool important, bool implicit = false);
-    void rollbackLastProperties(int num);
-    bool hasProperties() const { return !m_parsedProperties.isEmpty(); }
-    void addExpandedPropertyForValue(CSSPropertyID propId, Ref&lt;CSSValue&gt;&amp;&amp;, bool);
-
-    bool parseValue(CSSPropertyID, bool important);
-    bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&amp;, bool important);
-    bool parse4Values(CSSPropertyID, const CSSPropertyID* properties, bool important);
-    bool parseContent(CSSPropertyID, bool important);
-    bool parseQuotes(CSSPropertyID, bool important);
-    bool parseAlt(CSSPropertyID, bool important);
-    
-    bool parseCustomPropertyDeclaration(bool important, CSSValueID);
-    
-    RefPtr&lt;CSSPrimitiveValue&gt; parseAttr(CSSParserValueList&amp; args);
-
-    RefPtr&lt;CSSPrimitiveValue&gt; parseBackgroundColor();
-
-    struct SourceSize {
-        MediaQueryExpression expression;
-        Ref&lt;CSSValue&gt; length;
-
-        SourceSize(SourceSize&amp;&amp;);
-        SourceSize(MediaQueryExpression&amp;&amp;, Ref&lt;CSSValue&gt;&amp;&amp;);
-    };
-    Vector&lt;SourceSize&gt; parseSizesAttribute(StringView);
-    Optional&lt;SourceSize&gt; sourceSize(MediaQueryExpression&amp;&amp;, CSSParserValue&amp;);
-
-    bool parseFillImage(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-
-    enum FillPositionFlag { InvalidFillPosition = 0, AmbiguousFillPosition = 1, XFillPosition = 2, YFillPosition = 4 };
-    enum FillPositionParsingMode { ResolveValuesAsPercent = 0, ResolveValuesAsKeyword = 1 };
-    RefPtr&lt;CSSPrimitiveValue&gt; parseFillPositionComponent(CSSParserValueList&amp;, unsigned&amp; cumulativeFlags, FillPositionFlag&amp; individualFlag, FillPositionParsingMode = ResolveValuesAsPercent);
-    RefPtr&lt;CSSPrimitiveValue&gt; parsePositionX(CSSParserValueList&amp;);
-    RefPtr&lt;CSSPrimitiveValue&gt; parsePositionY(CSSParserValueList&amp;);
-    void parse2ValuesFillPosition(CSSParserValueList&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
-    bool isPotentialPositionValue(CSSParserValue&amp;);
-    void parseFillPosition(CSSParserValueList&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
-    void parse3ValuesFillPosition(CSSParserValueList&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp;, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp;);
-    void parse4ValuesFillPosition(CSSParserValueList&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp;, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp;);
-
-    void parseFillRepeat(RefPtr&lt;CSSValue&gt;&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-    RefPtr&lt;CSSPrimitiveValue&gt; parseFillSize(CSSPropertyID, bool &amp;allowComma);
-
-    bool parseFillProperty(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2, RefPtr&lt;CSSValue&gt;&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-    bool parseFillShorthand(CSSPropertyID, const CSSPropertyID* properties, int numProperties, bool important);
-
-    void addFillValue(RefPtr&lt;CSSValue&gt;&amp; lval, Ref&lt;CSSValue&gt;&amp;&amp; rval);
-    void addAnimationValue(RefPtr&lt;CSSValue&gt;&amp; lval, Ref&lt;CSSValue&gt;&amp;&amp; rval);
-
-    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationDelay();
-    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationDirection();
-    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationDuration();
-    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationFillMode();
-    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationIterationCount();
-    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationName();
-    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationPlayState();
-    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationProperty(AnimationParseContext&amp;);
-    RefPtr&lt;CSSValue&gt; parseAnimationTimingFunction();
-#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
-    RefPtr&lt;CSSValue&gt; parseAnimationTrigger();
-#endif
-    static Vector&lt;double&gt; parseKeyframeSelector(const String&amp;);
-
-    bool parseTransformOriginShorthand(RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-    Optional&lt;double&gt; parseCubicBezierTimingFunctionValue(CSSParserValueList&amp;);
-    Optional&lt;double&gt; parseSpringTimingFunctionValue(CSSParserValueList&amp;);
-    bool parseAnimationProperty(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;, AnimationParseContext&amp;);
-    bool parseTransitionShorthand(CSSPropertyID, bool important);
-    bool parseAnimationShorthand(CSSPropertyID, bool important);
-
-    bool isSpringTimingFunctionEnabled() const;
-
-    RefPtr&lt;CSSPrimitiveValue&gt; parseColumnWidth();
-    RefPtr&lt;CSSPrimitiveValue&gt; parseColumnCount();
-    bool parseColumnsShorthand(bool important);
-
-#if ENABLE(IOS_TEXT_AUTOSIZING)
-    bool isTextAutosizingEnabled() const;
-#endif
-
-#if ENABLE(CSS_GRID_LAYOUT)
-    bool isCSSGridLayoutEnabled() const;
-    RefPtr&lt;CSSValue&gt; parseGridPosition();
-    bool parseGridItemPositionShorthand(CSSPropertyID, bool important);
-    enum TrackListType { GridTemplate, GridTemplateNoRepeat, GridAuto };
-    RefPtr&lt;CSSValue&gt; parseGridTemplateColumns(TrackListType = GridTemplate);
-    bool parseGridTemplateRowsAndAreasAndColumns(bool important);
-    bool parseGridTemplateShorthand(bool important);
-    bool parseGridShorthand(bool important);
-    bool parseGridAreaShorthand(bool important);
-    bool parseGridGapShorthand(bool important);
-    bool parseSingleGridAreaLonghand(RefPtr&lt;CSSValue&gt;&amp;);
-    RefPtr&lt;CSSValue&gt; parseGridTrackList(TrackListType);
-    bool parseGridTrackRepeatFunction(CSSValueList&amp;, bool&amp; isAutoRepeat, bool&amp; allTracksAreFixedSized);
-    RefPtr&lt;CSSValue&gt; parseGridTrackSize(CSSParserValueList&amp; inputList);
-    RefPtr&lt;CSSPrimitiveValue&gt; parseGridBreadth(CSSParserValue&amp;);
-    bool parseGridTemplateAreasRow(NamedGridAreaMap&amp;, const unsigned, unsigned&amp;);
-    RefPtr&lt;CSSValue&gt; parseGridTemplateAreas();
-    bool parseGridLineNames(CSSParserValueList&amp;, CSSValueList&amp;, CSSGridLineNamesValue* = nullptr);
-    RefPtr&lt;CSSValue&gt; parseGridAutoFlow(CSSParserValueList&amp;);
-#endif
-
-    bool parseDashboardRegions(CSSPropertyID, bool important);
-
-    bool parseClipShape(CSSPropertyID, bool important);
-
-    bool parseLegacyPosition(CSSPropertyID, bool important);
-    bool parseItemPositionOverflowPosition(CSSPropertyID, bool important);
-    RefPtr&lt;CSSContentDistributionValue&gt; parseContentDistributionOverflowPosition();
-
-#if ENABLE(CSS_SHAPES)
-    RefPtr&lt;CSSValue&gt; parseShapeProperty(CSSPropertyID);
-#endif
-
-    RefPtr&lt;CSSValueList&gt; parseBasicShapeAndOrBox(CSSPropertyID propId);
-    RefPtr&lt;CSSPrimitiveValue&gt; parseBasicShape();
-    RefPtr&lt;CSSPrimitiveValue&gt; parseShapeRadius(CSSParserValue&amp;);
-    RefPtr&lt;CSSBasicShapeCircle&gt; parseBasicShapeCircle(CSSParserValueList&amp;);
-    RefPtr&lt;CSSBasicShapeEllipse&gt; parseBasicShapeEllipse(CSSParserValueList&amp;);
-    RefPtr&lt;CSSBasicShapePolygon&gt; parseBasicShapePolygon(CSSParserValueList&amp;);
-    RefPtr&lt;CSSBasicShapePath&gt; parseBasicShapePath(CSSParserValueList&amp;);
-    RefPtr&lt;CSSBasicShapeInset&gt; parseBasicShapeInset(CSSParserValueList&amp;);
-
-    bool parseFont(bool important);
-    void parseSystemFont(bool important);
-    RefPtr&lt;CSSValueList&gt; parseFontFamily();
-
-    bool parseCounter(CSSPropertyID, int defaultValue, bool important);
-    RefPtr&lt;CSSPrimitiveValue&gt; parseCounterContent(CSSParserValueList&amp; args, bool counters);
-
-    bool parseColorParameters(CSSParserValue&amp;, int* colorValues, bool parseAlpha);
-    bool parseHSLParameters(CSSParserValue&amp;, double* colorValues, bool parseAlpha);
-    RefPtr&lt;CSSPrimitiveValue&gt; parseColor(CSSParserValue* = nullptr);
-    bool parseColorFromValue(CSSParserValue&amp;, RGBA32&amp;);
-    void parseSelector(const String&amp;, CSSSelectorList&amp;);
-
-    template&lt;typename StringType&gt;
-    static bool fastParseColor(RGBA32&amp;, const StringType&amp;, bool strict);
-
-    bool parseLineHeight(bool important);
-    bool parseFontSize(bool important);
-    bool parseFontWeight(bool important);
-    bool parseFontSynthesis(bool important);
-    bool parseFontFaceSrc();
-    bool parseFontFaceUnicodeRange();
-
-    bool parseSVGValue(CSSPropertyID propId, bool important);
-    RefPtr&lt;SVGPaint&gt; parseSVGPaint();
-    RefPtr&lt;SVGColor&gt; parseSVGColor();
-    RefPtr&lt;CSSValueList&gt; parseSVGStrokeDasharray();
-    RefPtr&lt;CSSValueList&gt; parsePaintOrder();
-
-    // CSS3 Parsing Routines (for properties specific to CSS3)
-    RefPtr&lt;CSSValueList&gt; parseShadow(CSSParserValueList&amp;, CSSPropertyID);
-    bool parseBorderImage(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;, bool important = false);
-    bool parseBorderImageRepeat(RefPtr&lt;CSSValue&gt;&amp;);
-    bool parseBorderImageSlice(CSSPropertyID, RefPtr&lt;CSSBorderImageSliceValue&gt;&amp;);
-    bool parseBorderImageWidth(RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
-    bool parseBorderImageOutset(RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
-    bool parseBorderRadius(CSSPropertyID, bool important);
-
-    bool parseAspectRatio(bool important);
-
-    bool parseReflect(CSSPropertyID, bool important);
-
-    bool parseFlex(CSSParserValueList&amp; args, bool important);
-
-    // Image generators
-    bool parseCanvas(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-    bool parseNamedImage(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-
-    bool parseDeprecatedGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-    bool parseDeprecatedLinearGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, CSSGradientRepeat repeating);
-    bool parseDeprecatedRadialGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, CSSGradientRepeat repeating);
-    bool parseLinearGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, CSSGradientRepeat repeating);
-    bool parseRadialGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, CSSGradientRepeat repeating);
-    bool parseGradientColorStops(CSSParserValueList&amp;, CSSGradientValue&amp;, bool expectComma);
-
-    bool parseCrossfade(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, bool prefixed);
-
-#if ENABLE(CSS_IMAGE_RESOLUTION)
-    RefPtr&lt;CSSValueList&gt; parseImageResolution();
-#endif
-
-    RefPtr&lt;CSSImageSetValue&gt; parseImageSet();
-
-    bool parseFilterImage(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-
-    bool parseFilter(CSSParserValueList&amp;, RefPtr&lt;CSSValueList&gt;&amp;);
-    RefPtr&lt;WebKitCSSFilterValue&gt; parseBuiltinFilterArguments(CSSParserValueList&amp;, WebKitCSSFilterValue::FilterOperationType);
-
-    RefPtr&lt;CSSValue&gt; parseClipPath();
-
-    static bool isBlendMode(CSSValueID);
-    static bool isCompositeOperator(CSSValueID);
-
-    RefPtr&lt;CSSValueList&gt; parseTransform();
-    RefPtr&lt;WebKitCSSTransformValue&gt; parseTransformValue(CSSParserValue&amp;);
-    bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2, CSSPropertyID&amp; propId3, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-    bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2,  RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
-
-    bool parseTextEmphasisStyle(bool important);
-    bool parseTextEmphasisPosition(bool important);
-
-    void addTextDecorationProperty(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;&amp;, bool important);
-    bool parseTextDecoration(CSSPropertyID propId, bool important);
-    bool parseTextDecorationSkip(bool important);
-    bool parseTextUnderlinePosition(bool important);
-
-    RefPtr&lt;CSSValueList&gt; parseTextIndent();
-    
-    bool parseHangingPunctuation(bool important);
-
-    bool parseLineBoxContain(bool important);
-    RefPtr&lt;CSSCalcValue&gt; parseCalculation(CSSParserValue&amp;, CalculationPermittedValueRange);
-
-    bool parseFontFeatureTag(CSSValueList&amp;);
-    bool parseFontFeatureSettings(bool important);
-
-    bool parseFlowThread(CSSPropertyID, bool important);
-    bool parseRegionThread(CSSPropertyID, bool important);
-
-    bool parseFontVariantLigatures(bool important, bool unknownIsFailure, bool implicit);
-    bool parseFontVariantNumeric(bool important, bool unknownIsFailure, bool implicit);
-    bool parseFontVariantEastAsian(bool important, bool unknownIsFailure, bool implicit);
-    bool parseFontVariant(bool important);
-
-    bool parseWillChange(bool important);
-
-    // Faster than doing a new/delete each time since it keeps one vector.
-    std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; createSelectorVector();
-    void recycleSelectorVector(std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt;);
-
-    RefPtr&lt;StyleRuleImport&gt; createImportRule(const CSSParserString&amp;, RefPtr&lt;MediaQuerySet&gt;&amp;&amp;);
-    RefPtr&lt;StyleKeyframe&gt; createKeyframe(CSSParserValueList&amp;);
-    Ref&lt;StyleRuleKeyframes&gt; createKeyframesRule(const String&amp;, std::unique_ptr&lt;Vector&lt;RefPtr&lt;StyleKeyframe&gt;&gt;&gt;);
-
-    typedef Vector&lt;RefPtr&lt;StyleRuleBase&gt;&gt; RuleList;
-    Ref&lt;StyleRuleMedia&gt; createMediaRule(RefPtr&lt;MediaQuerySet&gt;&amp;&amp;, RuleList*);
-    Ref&lt;StyleRuleMedia&gt; createEmptyMediaRule(RuleList*);
-    RefPtr&lt;StyleRule&gt; createStyleRule(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* selectors);
-    RefPtr&lt;StyleRuleFontFace&gt; createFontFaceRule();
-    RefPtr&lt;StyleRulePage&gt; createPageRule(std::unique_ptr&lt;CSSParserSelector&gt; pageSelector);
-    RefPtr&lt;StyleRuleRegion&gt; createRegionRule(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* regionSelector, RuleList* rules);
-    void createMarginAtRule(CSSSelector::MarginBoxType);
-    Ref&lt;StyleRuleSupports&gt; createSupportsRule(bool conditionIsSupported, RuleList*);
-    void markSupportsRuleHeaderStart();
-    void markSupportsRuleHeaderEnd();
-    Ref&lt;CSSRuleSourceData&gt; popSupportsRuleData();
-
-    void startDeclarationsForMarginBox();
-    void endDeclarationsForMarginBox();
-
-    void addNamespace(const AtomicString&amp; prefix, const AtomicString&amp; uri);
-    QualifiedName determineNameInNamespace(const AtomicString&amp; prefix, const AtomicString&amp; localName);
-
-    void rewriteSpecifiersWithElementName(const AtomicString&amp; namespacePrefix, const AtomicString&amp; elementName, CSSParserSelector&amp;);
-    void rewriteSpecifiersWithElementName(const QualifiedName&amp; tagName, CSSParserSelector&amp;, bool isNamespacePlaceholder = false);
-    void rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector&amp;);
-    std::unique_ptr&lt;CSSParserSelector&gt; rewriteSpecifiers(std::unique_ptr&lt;CSSParserSelector&gt;, std::unique_ptr&lt;CSSParserSelector&gt;);
-
-    void invalidBlockHit();
-
-    void updateLastSelectorLineAndPosition();
-    void updateLastMediaLine(MediaQuerySet&amp;);
-
-    void clearProperties();
-
-    Ref&lt;ImmutableStyleProperties&gt; createStyleProperties();
-
-    static const unsigned invalidParsedPropertiesCount;
-
-    CSSParserContext m_context;
-
-    bool m_important { false };
-    CSSPropertyID m_id { CSSPropertyInvalid };
-    AtomicString m_customPropertyName;
-    StyleSheetContents* m_styleSheet { nullptr };
-    RefPtr&lt;StyleRuleBase&gt; m_rule;
-    RefPtr&lt;StyleKeyframe&gt; m_keyframe;
-    std::unique_ptr&lt;MediaQuery&gt; m_mediaQuery;
-    std::unique_ptr&lt;Vector&lt;SourceSize&gt;&gt; m_sourceSizeList;
-    std::unique_ptr&lt;CSSParserValueList&gt; m_valueList;
-    bool m_supportsCondition { false };
-
-    ParsedPropertyVector m_parsedProperties;
-    CSSSelectorList* m_selectorListForParseSelector { nullptr };
-
-    unsigned m_numParsedPropertiesBeforeMarginBox { invalidParsedPropertiesCount };
-
-    int m_inParseShorthand { 0 };
-    CSSPropertyID m_currentShorthand { CSSPropertyInvalid };
-    bool m_implicitShorthand { false };
-
-    bool m_hadSyntacticallyValidCSSRule { false };
-    bool m_logErrors { false };
-    bool m_ignoreErrorsInDeclaration { false };
-
-    AtomicString m_defaultNamespace { starAtom };
-
-    // tokenizer methods and data
-    size_t m_parsedTextPrefixLength { 0 };
-    unsigned m_nestedSelectorLevel { 0 };
-    SourceRange m_selectorRange;
-    SourceRange m_propertyRange { std::numeric_limits&lt;unsigned&gt;::max(), std::numeric_limits&lt;unsigned&gt;::max() };
-    std::unique_ptr&lt;RuleSourceDataList&gt; m_currentRuleDataStack;
-    RefPtr&lt;CSSRuleSourceData&gt; m_currentRuleData;
-    RuleSourceDataList* m_ruleSourceDataResult { nullptr };
-
-    void fixUnparsedPropertyRanges(CSSRuleSourceData&amp;);
-    void markRuleHeaderStart(CSSRuleSourceData::Type);
-    void markRuleHeaderEnd();
-
-    void startNestedSelectorList() { ++m_nestedSelectorLevel; }
-    void endNestedSelectorList() { --m_nestedSelectorLevel; }
-    void markSelectorStart();
-    void markSelectorEnd();
-
-    void markRuleBodyStart();
-    void markRuleBodyEnd();
-    void markPropertyStart();
-    void markPropertyEnd(bool isImportantFound, bool isPropertyParsed);
-    void processAndAddNewRuleToSourceTreeIfNeeded();
-    void addNewRuleToSourceTree(Ref&lt;CSSRuleSourceData&gt;&amp;&amp;);
-    RefPtr&lt;CSSRuleSourceData&gt; popRuleData();
-    void resetPropertyRange() { m_propertyRange.start = m_propertyRange.end = std::numeric_limits&lt;unsigned&gt;::max(); }
-    bool isExtractingSourceData() const { return !!m_currentRuleDataStack; }
-    void syntaxError(const Location&amp;, SyntaxErrorType = GeneralSyntaxError);
-
-    inline int lex(void* yylval) { return (this-&gt;*m_lexFunc)(yylval); }
-
-    int token() { return m_token; }
-
-#if ENABLE(CSS_DEVICE_ADAPTATION)
-    void markViewportRuleBodyStart() { m_inViewport = true; }
-    void markViewportRuleBodyEnd() { m_inViewport = false; }
-    Ref&lt;StyleRuleViewport&gt; createViewportRule();
-#endif
-
-    Ref&lt;CSSPrimitiveValue&gt; createPrimitiveNumericValue(ValueWithCalculation&amp;);
-    Ref&lt;CSSPrimitiveValue&gt; createPrimitiveStringValue(CSSParserValue&amp;);
-
-    static URL completeURL(const CSSParserContext&amp;, const String&amp; url);
-
-    Location currentLocation();
-    static bool isCalculation(CSSParserValue&amp;);
-
-    void setCustomPropertyName(const AtomicString&amp; propertyName) { m_customPropertyName = propertyName; }
-
-    RefPtr&lt;CSSValue&gt; parseVariableDependentValue(CSSPropertyID, const CSSVariableDependentValue&amp;, const CustomPropertyValueMap&amp; customProperties, TextDirection, WritingMode);
-
-private:
-    bool is8BitSource() { return m_is8BitSource; }
-
-    template &lt;typename SourceCharacterType&gt;
-    int realLex(void* yylval);
-
-    UChar*&amp; currentCharacter16();
-
-    template &lt;typename CharacterType&gt;
-    inline CharacterType*&amp; currentCharacter();
-
-    template &lt;typename CharacterType&gt;
-    inline CharacterType* tokenStart();
-
-    template &lt;typename CharacterType&gt;
-    inline void setTokenStart(CharacterType*);
-
-    inline unsigned tokenStartOffset();
-    inline UChar tokenStartChar();
-
-    inline unsigned currentCharacterOffset();
-
-    template &lt;typename CharacterType&gt;
-    inline bool isIdentifierStart();
-
-    template &lt;typename CharacterType&gt;
-    unsigned parseEscape(CharacterType*&amp;);
-    template &lt;typename DestCharacterType&gt;
-    inline void UnicodeToChars(DestCharacterType*&amp;, unsigned);
-    template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
-    inline bool parseIdentifierInternal(SrcCharacterType*&amp;, DestCharacterType*&amp;, bool&amp;);
-
-    template &lt;typename CharacterType&gt;
-    inline void parseIdentifier(CharacterType*&amp;, CSSParserString&amp;, bool&amp;);
-
-    template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
-    inline bool parseStringInternal(SrcCharacterType*&amp;, DestCharacterType*&amp;, UChar);
-
-    template &lt;typename CharacterType&gt;
-    inline void parseString(CharacterType*&amp;, CSSParserString&amp; resultString, UChar);
-
-    template &lt;typename CharacterType&gt;
-    inline bool findURI(CharacterType*&amp; start, CharacterType*&amp; end, UChar&amp; quote);
-
-    template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
-    inline bool parseURIInternal(SrcCharacterType*&amp;, DestCharacterType*&amp;, UChar quote);
-
-    template &lt;typename CharacterType&gt;
-    inline void parseURI(CSSParserString&amp;);
-    template &lt;typename CharacterType&gt;
-    inline bool parseUnicodeRange();
-    template &lt;typename CharacterType&gt;
-    bool parseNthChild();
-    template &lt;typename CharacterType&gt;
-    bool parseNthChildExtra();
-    template &lt;typename CharacterType&gt;
-    inline bool detectFunctionTypeToken(int);
-    template &lt;typename CharacterType&gt;
-    inline void detectMediaQueryToken(int);
-    template &lt;typename CharacterType&gt;
-    inline void detectNumberToken(CharacterType*, int);
-    template &lt;typename CharacterType&gt;
-    inline void detectDashToken(int);
-    template &lt;typename CharacterType&gt;
-    inline void detectAtToken(int, bool);
-    template &lt;typename CharacterType&gt;
-    inline void detectSupportsToken(int);
-
-    template &lt;typename CharacterType&gt;
-    inline void setRuleHeaderEnd(const CharacterType*);
-
-    void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
-
-    inline bool inStrictMode() const { return m_context.mode == CSSStrictMode || m_context.mode == SVGAttributeMode; }
-    inline bool inQuirksMode() const { return m_context.mode == CSSQuirksMode; }
-    
-    URL completeURL(const String&amp; url) const;
-
-    void recheckAtKeyword(const UChar* str, int len);
-
-    template&lt;unsigned prefixLength, unsigned suffixLength&gt;
-    void setupParser(const char (&amp;prefix)[prefixLength], StringView string, const char (&amp;suffix)[suffixLength])
-    {
-        setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
-    }
-    void setupParser(const char* prefix, unsigned prefixLength, StringView, const char* suffix, unsigned suffixLength);
-    bool inShorthand() const { return m_inParseShorthand; }
-
-    bool isValidSize(ValueWithCalculation&amp;);
-
-    bool isGeneratedImageValue(CSSParserValue&amp;) const;
-    bool parseGeneratedImage(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
-
-    ParseResult parseValue(MutableStyleProperties&amp;, CSSPropertyID, const String&amp;, bool important, StyleSheetContents* contextStyleSheet);
-    Ref&lt;ImmutableStyleProperties&gt; parseDeclaration(const String&amp;, StyleSheetContents* contextStyleSheet);
-
-    RefPtr&lt;CSSBasicShapeInset&gt; parseInsetRoundedCorners(Ref&lt;CSSBasicShapeInset&gt;&amp;&amp;, CSSParserValueList&amp;);
-
-    enum SizeParameterType {
-        None,
-        Auto,
-        Length,
-        PageSize,
-        Orientation,
-    };
-
-    bool parsePage(CSSPropertyID propId, bool important);
-    bool parseSize(CSSPropertyID propId, bool important);
-    SizeParameterType parseSizeParameter(CSSValueList&amp; parsedValues, CSSParserValue&amp;, SizeParameterType prevParamType);
-
-#if ENABLE(CSS_SCROLL_SNAP)
-    bool parseNonElementSnapPoints(CSSPropertyID propId, bool important);
-    bool parseScrollSnapDestination(CSSPropertyID propId, bool important);
-    bool parseScrollSnapCoordinate(CSSPropertyID propId, bool important);
-    bool parseScrollSnapPositions(RefPtr&lt;CSSValue&gt;&amp; cssValueX, RefPtr&lt;CSSValue&gt;&amp; cssValueY);
-#endif
-
-    bool parseFontFaceSrcURI(CSSValueList&amp;);
-    bool parseFontFaceSrcLocal(CSSValueList&amp;);
-
-    bool parseColor(const String&amp;);
-
-#if ENABLE(CSS_GRID_LAYOUT)
-    bool parseIntegerOrCustomIdentFromGridPosition(RefPtr&lt;CSSPrimitiveValue&gt;&amp; numericValue, RefPtr&lt;CSSPrimitiveValue&gt;&amp; gridLineName);
-#endif
-
-    enum ParsingMode {
-        NormalMode,
-        MediaQueryMode,
-        SupportsMode,
-        NthChildMode
-    };
-
-    ParsingMode m_parsingMode { NormalMode };
-    bool m_is8BitSource { false };
-    std::unique_ptr&lt;LChar[]&gt; m_dataStart8;
-    std::unique_ptr&lt;UChar[]&gt; m_dataStart16;
-    LChar* m_currentCharacter8 { nullptr };
-    UChar* m_currentCharacter16 { nullptr };
-    union {
-        LChar* ptr8;
-        UChar* ptr16;
-    } m_tokenStart { nullptr };
-    unsigned m_length { 0 };
-    int m_token { 0 };
-    int m_lineNumber { 0 };
-    int m_tokenStartLineNumber { 0 };
-    int m_tokenStartColumnNumber { 0 };
-    int m_lastSelectorLineNumber { 0 };
-    int m_columnOffsetForLine { 0 };
-
-    int m_sheetStartLineNumber { 0 };
-    int m_sheetStartColumnNumber { 0 };
-
-    bool m_allowImportRules { true };
-    bool m_allowNamespaceDeclarations { true };
-
-#if ENABLE(CSS_DEVICE_ADAPTATION)
-    bool parseViewportProperty(CSSPropertyID propId, bool important);
-    bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
-
-    bool inViewport() const { return m_inViewport; }
-    bool m_inViewport { false };
-#endif
-
-    bool useLegacyBackgroundSizeShorthandBehavior() const;
-
-    int (CSSParser::*m_lexFunc)(void*);
-
-    std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; m_recycledSelectorVector;
-
-    std::unique_ptr&lt;RuleSourceDataList&gt; m_supportsRuleDataStack;
-
-    // defines units allowed for a certain property, used in parseUnit
-    enum Units {
-        FUnknown = 0x0000,
-        FInteger = 0x0001,
-        FNumber = 0x0002, // Real Numbers
-        FPercent = 0x0004,
-        FLength = 0x0008,
-        FAngle = 0x0010,
-        FTime = 0x0020,
-        FFrequency = 0x0040,
-        FPositiveInteger = 0x0080,
-        FRelative = 0x0100,
-#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
-        FResolution = 0x0200,
-#endif
-        FNonNeg = 0x0400
-    };
-
-    friend inline Units operator|(Units a, Units b)
-    {
-        return static_cast&lt;Units&gt;(static_cast&lt;unsigned&gt;(a) | static_cast&lt;unsigned&gt;(b));
-    }
-
-    enum ReleaseParsedCalcValueCondition {
-        ReleaseParsedCalcValue,
-        DoNotReleaseParsedCalcValue
-    };
-
-    bool isLoggingErrors();
-    void logError(const String&amp; message, int lineNumber, int columnNumber);
-
-    bool validateCalculationUnit(ValueWithCalculation&amp;, Units);
-
-    bool shouldAcceptUnitLessValues(CSSParserValue&amp;, Units, CSSParserMode);
-
-    inline bool validateUnit(ValueWithCalculation&amp; value, Units unitFlags) { return validateUnit(value, unitFlags, m_context.mode); }
-    bool validateUnit(ValueWithCalculation&amp;, Units, CSSParserMode);
-
-    bool parseBorderImageQuad(Units, RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
-    int colorIntFromValue(ValueWithCalculation&amp;);
-    double parsedDouble(ValueWithCalculation&amp;);
-    
-    friend class TransformOperationInfo;
-    friend class FilterOperationInfo;
-};
-
-CSSPropertyID cssPropertyID(const CSSParserString&amp;);
-CSSPropertyID cssPropertyID(const String&amp;);
-CSSValueID cssValueKeywordID(const CSSParserString&amp;);
-#if PLATFORM(IOS)
-void cssPropertyNameIOSAliasing(const char* propertyName, const char*&amp; propertyNameAlias, unsigned&amp; newLength);
-#endif
-
-class ShorthandScope {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    ShorthandScope(CSSParser* parser, CSSPropertyID propId) : m_parser(parser)
-    {
-        if (!(m_parser-&gt;m_inParseShorthand++))
-            m_parser-&gt;m_currentShorthand = propId;
-    }
-    ~ShorthandScope()
-    {
-        if (!(--m_parser-&gt;m_inParseShorthand))
-            m_parser-&gt;m_currentShorthand = CSSPropertyInvalid;
-    }
-
-private:
-    CSSParser* m_parser;
-};
-
-struct CSSParser::Location {
-    int lineNumber;
-    int columnNumber;
-    CSSParserString token;
-};
-
-String quoteCSSString(const String&amp;);
-String quoteCSSStringIfNeeded(const String&amp;);
-String quoteCSSURLIfNeeded(const String&amp;);
-
-bool isValidNthToken(const CSSParserString&amp;);
-
-template &lt;&gt;
-inline void CSSParser::setTokenStart&lt;LChar&gt;(LChar* tokenStart)
-{
-    m_tokenStart.ptr8 = tokenStart;
-}
-
-template &lt;&gt;
-inline void CSSParser::setTokenStart&lt;UChar&gt;(UChar* tokenStart)
-{
-    m_tokenStart.ptr16 = tokenStart;
-}
-
-inline unsigned CSSParser::tokenStartOffset()
-{
-    if (is8BitSource())
-        return m_tokenStart.ptr8 - m_dataStart8.get();
-    return m_tokenStart.ptr16 - m_dataStart16.get();
-}
-
-unsigned CSSParser::currentCharacterOffset()
-{
-    if (is8BitSource())
-        return m_currentCharacter8 - m_dataStart8.get();
-    return m_currentCharacter16 - m_dataStart16.get();
-}
-
-inline UChar CSSParser::tokenStartChar()
-{
-    if (is8BitSource())
-        return *m_tokenStart.ptr8;
-    return *m_tokenStart.ptr16;
-}
-
-inline bool isCustomPropertyName(const String&amp; propertyName)
-{
-    return propertyName.length() &gt; 2 &amp;&amp; propertyName.characterAt(0) == '-' &amp;&amp; propertyName.characterAt(1) == '-';
-}
-
-inline int cssyylex(void* yylval, CSSParser* parser)
-{
-    return parser-&gt;lex(yylval);
-}
-
-} // namespace WebCore
</del></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserModeh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/css/CSSParserMode.h (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParserMode.h        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/css/CSSParserMode.h        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -1,86 +0,0 @@
</span><del>-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer in the documentation and/or other materials
- *    provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef CSSParserMode_h
-#define CSSParserMode_h
-
-#include &quot;URL.h&quot;
-
-namespace WebCore {
-
-class Document;
-
-enum CSSParserMode {
-    CSSQuirksMode,
-    CSSStrictMode,
-    // SVG should always be in strict mode. For SVG attributes, the rules differ to strict sometimes.
-    SVGAttributeMode
-};
-
-inline CSSParserMode strictToCSSParserMode(bool inStrictMode)
-{
-    return inStrictMode ? CSSStrictMode : CSSQuirksMode;
-}
-
-inline bool isStrictParserMode(CSSParserMode cssParserMode)
-{
-    return cssParserMode == CSSStrictMode || cssParserMode == SVGAttributeMode;
-}
-
-struct CSSParserContext {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    CSSParserContext(CSSParserMode, const URL&amp; baseURL = URL());
-    WEBCORE_EXPORT CSSParserContext(Document&amp;, const URL&amp; baseURL = URL(), const String&amp; charset = emptyString());
-
-    URL baseURL;
-    String charset;
-    CSSParserMode mode { CSSStrictMode };
-    bool isHTMLDocument { false };
-#if ENABLE(CSS_GRID_LAYOUT)
-    bool cssGridLayoutEnabled { false };
-#endif
-#if ENABLE(IOS_TEXT_AUTOSIZING)
-    bool textAutosizingEnabled { false };
-#endif
-    bool needsSiteSpecificQuirks { false };
-    bool enforcesCSSMIMETypeInNoQuirksMode { true };
-    bool useLegacyBackgroundSizeShorthandBehavior { false };
-    bool springTimingFunctionEnabled { false };
-};
-
-bool operator==(const CSSParserContext&amp;, const CSSParserContext&amp;);
-inline bool operator!=(const CSSParserContext&amp; a, const CSSParserContext&amp; b) { return !(a == b); }
-
-WEBCORE_EXPORT const CSSParserContext&amp; strictCSSParserContext();
-
-};
-
-#endif // CSSParserMode_h
</del></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserValuescpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/css/CSSParserValues.cpp (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParserValues.cpp        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/css/CSSParserValues.cpp        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -1,446 +0,0 @@
</span><del>-/*
- * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2008, 2014 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include &quot;config.h&quot;
-#include &quot;CSSParserValues.h&quot;
-
-#include &quot;CSSCustomPropertyValue.h&quot;
-#include &quot;CSSPrimitiveValue.h&quot;
-#include &quot;CSSFunctionValue.h&quot;
-#include &quot;CSSSelector.h&quot;
-#include &quot;CSSSelectorList.h&quot;
-#include &quot;CSSVariableValue.h&quot;
-#include &quot;SelectorPseudoTypeMap.h&quot;
-
-namespace WebCore {
-
-using namespace WTF;
-
-void destroy(const CSSParserValue&amp; value)
-{
-    if (value.unit == CSSParserValue::Function)
-        delete value.function;
-    else if (value.unit == CSSParserValue::ValueList)
-        delete value.valueList;
-    else if (value.unit == CSSParserValue::Variable)
-        delete value.variable;
-}
-
-CSSParserValueList::~CSSParserValueList()
-{
-    for (auto&amp; value : m_values)
-        destroy(value);
-}
-
-void CSSParserValueList::addValue(const CSSParserValue&amp; value)
-{
-    m_values.append(value);
-}
-
-void CSSParserValueList::insertValueAt(unsigned i, const CSSParserValue&amp; value)
-{
-    m_values.insert(i, value);
-}
-
-void CSSParserValueList::extend(CSSParserValueList&amp; other)
-{
-    for (auto&amp; value : other.m_values) {
-        m_values.append(value);
-        value.unit = 0; // We moved the CSSParserValue from the other list; this acts like std::move.
-    }
-}
-
-bool CSSParserValueList::containsVariables() const
-{
-    for (unsigned i = 0; i &lt; size(); i++) {
-        auto* parserValue = &amp;m_values[i];
-        if (parserValue-&gt;unit == CSSParserValue::Variable)
-            return true;
-        if (parserValue-&gt;unit == CSSParserValue::Function &amp;&amp; parserValue-&gt;function-&gt;args
-            &amp;&amp; parserValue-&gt;function-&gt;args-&gt;containsVariables())
-            return true;
-        if (parserValue-&gt;unit == CSSParserValue::ValueList &amp;&amp; parserValue-&gt;valueList-&gt;containsVariables())
-            return true;
-    }
-    return false;
-}
-
-RefPtr&lt;CSSValue&gt; CSSParserValue::createCSSValue()
-{
-    RefPtr&lt;CSSValue&gt; parsedValue;
-    if (id)
-        return CSSPrimitiveValue::createIdentifier(id);
-    
-    if (unit == CSSParserValue::Operator) {
-        auto primitiveValue = CSSPrimitiveValue::createParserOperator(iValue);
-        primitiveValue-&gt;setPrimitiveType(CSSPrimitiveValue::CSS_PARSER_OPERATOR);
-        return WTFMove(primitiveValue);
-    }
-    if (unit == CSSParserValue::Function)
-        return CSSFunctionValue::create(function);
-    if (unit == CSSParserValue::Variable)
-        return CSSVariableValue::create(variable);
-    if (unit == CSSParserValue::ValueList)
-        return CSSValueList::createFromParserValueList(*valueList);
-
-    if (unit &gt;= CSSParserValue::Q_EMS)
-        return CSSPrimitiveValue::createAllowingMarginQuirk(fValue, CSSPrimitiveValue::CSS_EMS);
-
-    CSSPrimitiveValue::UnitTypes primitiveUnit = static_cast&lt;CSSPrimitiveValue::UnitTypes&gt;(unit);
-    switch (primitiveUnit) {
-    case CSSPrimitiveValue::CSS_IDENT:
-    case CSSPrimitiveValue::CSS_PROPERTY_ID:
-    case CSSPrimitiveValue::CSS_VALUE_ID:
-        return CSSPrimitiveValue::create(string, CSSPrimitiveValue::CSS_PARSER_IDENTIFIER);
-    case CSSPrimitiveValue::CSS_NUMBER:
-        return CSSPrimitiveValue::create(fValue, isInt ? CSSPrimitiveValue::CSS_PARSER_INTEGER : CSSPrimitiveValue::CSS_NUMBER);
-    case CSSPrimitiveValue::CSS_STRING:
-    case CSSPrimitiveValue::CSS_URI:
-    case CSSPrimitiveValue::CSS_PARSER_HEXCOLOR:
-    case CSSPrimitiveValue::CSS_DIMENSION:
-    case CSSPrimitiveValue::CSS_UNICODE_RANGE:
-    case CSSPrimitiveValue::CSS_PARSER_WHITESPACE:
-        return CSSPrimitiveValue::create(string, primitiveUnit);
-    case CSSPrimitiveValue::CSS_PERCENTAGE:
-    case CSSPrimitiveValue::CSS_EMS:
-    case CSSPrimitiveValue::CSS_EXS:
-    case CSSPrimitiveValue::CSS_PX:
-    case CSSPrimitiveValue::CSS_CM:
-    case CSSPrimitiveValue::CSS_MM:
-    case CSSPrimitiveValue::CSS_IN:
-    case CSSPrimitiveValue::CSS_PT:
-    case CSSPrimitiveValue::CSS_PC:
-    case CSSPrimitiveValue::CSS_DEG:
-    case CSSPrimitiveValue::CSS_RAD:
-    case CSSPrimitiveValue::CSS_GRAD:
-    case CSSPrimitiveValue::CSS_MS:
-    case CSSPrimitiveValue::CSS_S:
-    case CSSPrimitiveValue::CSS_HZ:
-    case CSSPrimitiveValue::CSS_KHZ:
-    case CSSPrimitiveValue::CSS_VW:
-    case CSSPrimitiveValue::CSS_VH:
-    case CSSPrimitiveValue::CSS_VMIN:
-    case CSSPrimitiveValue::CSS_VMAX:
-    case CSSPrimitiveValue::CSS_TURN:
-    case CSSPrimitiveValue::CSS_REMS:
-    case CSSPrimitiveValue::CSS_CHS:
-    case CSSPrimitiveValue::CSS_FR:
-        return CSSPrimitiveValue::create(fValue, primitiveUnit);
-    case CSSPrimitiveValue::CSS_UNKNOWN:
-    case CSSPrimitiveValue::CSS_ATTR:
-    case CSSPrimitiveValue::CSS_COUNTER:
-    case CSSPrimitiveValue::CSS_RECT:
-    case CSSPrimitiveValue::CSS_RGBCOLOR:
-    case CSSPrimitiveValue::CSS_DPPX:
-    case CSSPrimitiveValue::CSS_DPI:
-    case CSSPrimitiveValue::CSS_DPCM:
-    case CSSPrimitiveValue::CSS_PAIR:
-#if ENABLE(DASHBOARD_SUPPORT)
-    case CSSPrimitiveValue::CSS_DASHBOARD_REGION:
-#endif
-    case CSSPrimitiveValue::CSS_PARSER_OPERATOR:
-    case CSSPrimitiveValue::CSS_PARSER_INTEGER:
-    case CSSPrimitiveValue::CSS_PARSER_IDENTIFIER:
-    case CSSPrimitiveValue::CSS_COUNTER_NAME:
-    case CSSPrimitiveValue::CSS_SHAPE:
-    case CSSPrimitiveValue::CSS_FONT_FAMILY:
-    case CSSPrimitiveValue::CSS_QUAD:
-#if ENABLE(CSS_SCROLL_SNAP)
-    case CSSPrimitiveValue::CSS_LENGTH_REPEAT:
-#endif
-    case CSSPrimitiveValue::CSS_CALC:
-    case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER:
-    case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH:
-        return nullptr;
-    }
-
-    ASSERT_NOT_REACHED();
-    return nullptr;
-}
-
-CSSParserSelector* CSSParserSelector::parsePagePseudoSelector(const CSSParserString&amp; pseudoTypeString)
-{
-    CSSSelector::PagePseudoClassType pseudoType;
-    if (equalLettersIgnoringASCIICase(pseudoTypeString, &quot;first&quot;))
-        pseudoType = CSSSelector::PagePseudoClassFirst;
-    else if (equalLettersIgnoringASCIICase(pseudoTypeString, &quot;left&quot;))
-        pseudoType = CSSSelector::PagePseudoClassLeft;
-    else if (equalLettersIgnoringASCIICase(pseudoTypeString, &quot;right&quot;))
-        pseudoType = CSSSelector::PagePseudoClassRight;
-    else
-        return nullptr;
-
-    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
-    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PagePseudoClass);
-    selector-&gt;m_selector-&gt;setPagePseudoType(pseudoType);
-    return selector.release();
-}
-
-CSSParserSelector* CSSParserSelector::parsePseudoElementSelector(CSSParserString&amp; pseudoTypeString)
-{
-    pseudoTypeString.convertToASCIILowercaseInPlace();
-    AtomicString name = pseudoTypeString;
-
-    CSSSelector::PseudoElementType pseudoType = CSSSelector::parsePseudoElementType(name);
-    if (pseudoType == CSSSelector::PseudoElementUnknown)
-        return nullptr;
-
-    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
-    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoElement);
-    selector-&gt;m_selector-&gt;setPseudoElementType(pseudoType);
-    if (pseudoType == CSSSelector::PseudoElementWebKitCustomLegacyPrefixed) {
-        ASSERT_WITH_MESSAGE(name == &quot;-webkit-input-placeholder&quot;, &quot;-webkit-input-placeholder is the only LegacyPrefix pseudo type.&quot;);
-        if (name == &quot;-webkit-input-placeholder&quot;)
-            name = AtomicString(&quot;placeholder&quot;, AtomicString::ConstructFromLiteral);
-    }
-    selector-&gt;m_selector-&gt;setValue(name);
-    return selector.release();
-}
-
-#if ENABLE(VIDEO_TRACK)
-CSSParserSelector* CSSParserSelector::parsePseudoElementCueFunctionSelector(const CSSParserString&amp; functionIdentifier, Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* parsedSelectorVector)
-{
-    ASSERT_UNUSED(functionIdentifier, String(functionIdentifier) == &quot;cue(&quot;);
-
-    std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; selectorVector(parsedSelectorVector);
-
-    if (!selectorVector)
-        return nullptr;
-
-    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
-    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoElement);
-    selector-&gt;m_selector-&gt;setPseudoElementType(CSSSelector::PseudoElementCue);
-    selector-&gt;adoptSelectorVector(*selectorVector);
-    return selector.release();
-}
-#endif
-
-CSSParserSelector* CSSParserSelector::parsePseudoElementSlottedFunctionSelector(const CSSParserString&amp; functionIdentifier, CSSParserSelector* parsedSelector)
-{
-    ASSERT_UNUSED(functionIdentifier, String(functionIdentifier) == &quot;slotted(&quot;);
-
-    if (!parsedSelector)
-        return nullptr;
-
-    std::unique_ptr&lt;CSSParserSelector&gt; ownedParsedSelector(parsedSelector);
-
-    for (auto* component = parsedSelector; component; component = component-&gt;tagHistory()) {
-        if (component-&gt;matchesPseudoElement())
-            return nullptr;
-    }
-
-    auto selectorVector = std::make_unique&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt;();
-    selectorVector-&gt;append(WTFMove(ownedParsedSelector));
-
-    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
-    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoElement);
-    selector-&gt;m_selector-&gt;setPseudoElementType(CSSSelector::PseudoElementSlotted);
-    selector-&gt;adoptSelectorVector(*selectorVector);
-    return selector.release();
-}
-
-CSSParserSelector* CSSParserSelector::parsePseudoClassHostFunctionSelector(const CSSParserString&amp; functionIdentifier, CSSParserSelector* parsedSelector)
-{
-    ASSERT_UNUSED(functionIdentifier, String(functionIdentifier) == &quot;host(&quot;);
-
-    if (!parsedSelector)
-        return nullptr;
-
-    std::unique_ptr&lt;CSSParserSelector&gt; ownedParsedSelector(parsedSelector);
-
-    for (auto* component = parsedSelector; component; component = component-&gt;tagHistory()) {
-        if (component-&gt;matchesPseudoElement())
-            return nullptr;
-    }
-
-    auto selectorVector = std::make_unique&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt;();
-    selectorVector-&gt;append(WTFMove(ownedParsedSelector));
-
-    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
-    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoClass);
-    selector-&gt;m_selector-&gt;setPseudoClassType(CSSSelector::PseudoClassHost);
-    selector-&gt;adoptSelectorVector(*selectorVector);
-    return selector.release();
-}
-
-CSSParserSelector* CSSParserSelector::parsePseudoClassAndCompatibilityElementSelector(CSSParserString&amp; pseudoTypeString)
-{
-    if (pseudoTypeString.length() &amp;&amp; pseudoTypeString[pseudoTypeString.length() - 1] == '(')
-        return nullptr;
-
-    PseudoClassOrCompatibilityPseudoElement pseudoType = parsePseudoClassAndCompatibilityElementString(pseudoTypeString);
-    if (pseudoType.pseudoClass != CSSSelector::PseudoClassUnknown) {
-        auto selector = std::make_unique&lt;CSSParserSelector&gt;();
-        selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoClass);
-        selector-&gt;m_selector-&gt;setPseudoClassType(pseudoType.pseudoClass);
-        return selector.release();
-    }
-    if (pseudoType.compatibilityPseudoElement != CSSSelector::PseudoElementUnknown) {
-        auto selector = std::make_unique&lt;CSSParserSelector&gt;();
-        selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoElement);
-        selector-&gt;m_selector-&gt;setPseudoElementType(pseudoType.compatibilityPseudoElement);
-        AtomicString name = pseudoTypeString;
-        selector-&gt;m_selector-&gt;setValue(name);
-        return selector.release();
-    }
-    return nullptr;
-}
-
-CSSParserSelector::CSSParserSelector()
-    : m_selector(std::make_unique&lt;CSSSelector&gt;())
-{
-}
-
-CSSParserSelector::CSSParserSelector(const QualifiedName&amp; tagQName)
-    : m_selector(std::make_unique&lt;CSSSelector&gt;(tagQName))
-{
-}
-
-CSSParserSelector::~CSSParserSelector()
-{
-    if (!m_tagHistory)
-        return;
-    Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;, 16&gt; toDelete;
-    std::unique_ptr&lt;CSSParserSelector&gt; selector = WTFMove(m_tagHistory);
-    while (true) {
-        std::unique_ptr&lt;CSSParserSelector&gt; next = WTFMove(selector-&gt;m_tagHistory);
-        toDelete.append(WTFMove(selector));
-        if (!next)
-            break;
-        selector = WTFMove(next);
-    }
-}
-
-void CSSParserSelector::adoptSelectorVector(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&amp; selectorVector)
-{
-    auto selectorList = std::make_unique&lt;CSSSelectorList&gt;();
-    selectorList-&gt;adoptSelectorVector(selectorVector);
-    m_selector-&gt;setSelectorList(WTFMove(selectorList));
-}
-
-void CSSParserSelector::setLangArgumentList(const Vector&lt;CSSParserString&gt;&amp; stringVector)
-{
-    ASSERT_WITH_MESSAGE(!stringVector.isEmpty(), &quot;No CSS Selector takes an empty argument list.&quot;);
-    auto argumentList = std::make_unique&lt;Vector&lt;AtomicString&gt;&gt;();
-    argumentList-&gt;reserveInitialCapacity(stringVector.size());
-    for (const AtomicString&amp; languageArgument : stringVector)
-        argumentList-&gt;append(languageArgument);
-    m_selector-&gt;setLangArgumentList(WTFMove(argumentList));
-}
-
-void CSSParserSelector::setPseudoClassValue(const CSSParserString&amp; pseudoClassString)
-{
-    ASSERT(m_selector-&gt;match() == CSSSelector::PseudoClass);
-
-    PseudoClassOrCompatibilityPseudoElement pseudoType = parsePseudoClassAndCompatibilityElementString(pseudoClassString);
-    m_selector-&gt;setPseudoClassType(pseudoType.pseudoClass);
-}
-
-static bool selectorListMatchesPseudoElement(const CSSSelectorList* selectorList)
-{
-    if (!selectorList)
-        return false;
-
-    for (const CSSSelector* subSelector = selectorList-&gt;first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
-        for (const CSSSelector* selector = subSelector; selector; selector = selector-&gt;tagHistory()) {
-            if (selector-&gt;matchesPseudoElement())
-                return true;
-            if (const CSSSelectorList* subselectorList = selector-&gt;selectorList()) {
-                if (selectorListMatchesPseudoElement(subselectorList))
-                    return true;
-            }
-        }
-    }
-    return false;
-}
-
-bool CSSParserSelector::matchesPseudoElement() const
-{
-    return m_selector-&gt;matchesPseudoElement() || selectorListMatchesPseudoElement(m_selector-&gt;selectorList());
-}
-
-void CSSParserSelector::insertTagHistory(CSSSelector::Relation before, std::unique_ptr&lt;CSSParserSelector&gt; selector, CSSSelector::Relation after)
-{
-    if (m_tagHistory)
-        selector-&gt;setTagHistory(WTFMove(m_tagHistory));
-    setRelation(before);
-    selector-&gt;setRelation(after);
-    m_tagHistory = WTFMove(selector);
-}
-
-void CSSParserSelector::appendTagHistory(CSSSelector::Relation relation, std::unique_ptr&lt;CSSParserSelector&gt; selector)
-{
-    CSSParserSelector* end = this;
-    while (end-&gt;tagHistory())
-        end = end-&gt;tagHistory();
-
-    end-&gt;setRelation(relation);
-    end-&gt;setTagHistory(WTFMove(selector));
-}
-
-void CSSParserSelector::appendTagHistory(CSSParserSelectorCombinator relation, std::unique_ptr&lt;CSSParserSelector&gt; selector)
-{
-    CSSParserSelector* end = this;
-    while (end-&gt;tagHistory())
-        end = end-&gt;tagHistory();
-
-    CSSSelector::Relation selectorRelation;
-    switch (relation) {
-    case CSSParserSelectorCombinator::Child:
-        selectorRelation = CSSSelector::Child;
-        break;
-    case CSSParserSelectorCombinator::DescendantSpace:
-        selectorRelation = CSSSelector::Descendant;
-        break;
-#if ENABLE(CSS_SELECTORS_LEVEL4)
-    case CSSParserSelectorCombinator::DescendantDoubleChild:
-        selectorRelation = CSSSelector::Descendant;
-        break;
-#endif
-    case CSSParserSelectorCombinator::DirectAdjacent:
-        selectorRelation = CSSSelector::DirectAdjacent;
-        break;
-    case CSSParserSelectorCombinator::IndirectAdjacent:
-        selectorRelation = CSSSelector::IndirectAdjacent;
-        break;
-    }
-    end-&gt;setRelation(selectorRelation);
-
-#if ENABLE(CSS_SELECTORS_LEVEL4)
-    if (relation == CSSParserSelectorCombinator::DescendantDoubleChild)
-        end-&gt;setDescendantUseDoubleChildSyntax();
-#endif
-
-    end-&gt;setTagHistory(WTFMove(selector));
-}
-
-void CSSParserSelector::prependTagSelector(const QualifiedName&amp; tagQName, bool tagIsForNamespaceRule)
-{
-    auto second = std::make_unique&lt;CSSParserSelector&gt;();
-    second-&gt;m_selector = WTFMove(m_selector);
-    second-&gt;m_tagHistory = WTFMove(m_tagHistory);
-    m_tagHistory = WTFMove(second);
-
-    m_selector = std::make_unique&lt;CSSSelector&gt;(tagQName, tagIsForNamespaceRule);
-    m_selector-&gt;setRelation(CSSSelector::SubSelector);
-}
-
-}
-
</del></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserValuesh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/css/CSSParserValues.h (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParserValues.h        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/css/CSSParserValues.h        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -1,276 +0,0 @@
</span><del>-/*
- * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#pragma once
-
-#include &quot;CSSSelector.h&quot;
-#include &quot;CSSValueKeywords.h&quot;
-#include &quot;CSSValueList.h&quot;
-#include &lt;wtf/text/AtomicString.h&gt;
-#include &lt;wtf/text/AtomicStringHash.h&gt;
-#include &lt;wtf/text/WTFString.h&gt;
-
-namespace WebCore {
-
-class CSSValue;
-class QualifiedName;
-
-// This should be a StringView but currently it can't because it's used as an element of a union in CSSParserValue.
-struct CSSParserString {
-    void init(LChar* characters, unsigned length)
-    {
-        m_data.characters8 = characters;
-        m_length = length;
-        m_is8Bit = true;
-    }
-
-    void init(UChar* characters, unsigned length)
-    {
-        m_data.characters16 = characters;
-        m_length = length;
-        m_is8Bit = false;
-    }
-
-    void init(const String&amp; string)
-    {
-        m_length = string.length();
-        if (!m_length || string.is8Bit()) {
-            m_data.characters8 = const_cast&lt;LChar*&gt;(string.characters8());
-            m_is8Bit = true;
-        } else {
-            m_data.characters16 = const_cast&lt;UChar*&gt;(string.characters16());
-            m_is8Bit = false;
-        }
-    }
-
-    void clear()
-    {
-        m_data.characters8 = 0;
-        m_length = 0;
-        m_is8Bit = true;
-    }
-
-    bool is8Bit() const { return m_is8Bit; }
-    LChar* characters8() const { ASSERT(is8Bit()); return m_data.characters8; }
-    UChar* characters16() const { ASSERT(!is8Bit()); return m_data.characters16; }
-    template&lt;typename CharacterType&gt; CharacterType* characters() const;
-
-    unsigned length() const { return m_length; }
-    void setLength(unsigned length) { m_length = length; }
-
-    void convertToASCIILowercaseInPlace();
-
-    UChar operator[](unsigned i) const
-    {
-        ASSERT_WITH_SECURITY_IMPLICATION(i &lt; m_length);
-        if (is8Bit())
-            return m_data.characters8[i];
-        return m_data.characters16[i];
-    }
-
-    operator String() const { return is8Bit() ? String(m_data.characters8, m_length) : String(m_data.characters16, m_length); }
-    operator AtomicString() const { return is8Bit() ? AtomicString(m_data.characters8, m_length) : AtomicString(m_data.characters16, m_length); }
-
-    union {
-        LChar* characters8;
-        UChar* characters16;
-    } m_data;
-    unsigned m_length;
-    bool m_is8Bit;
-};
-
-template&lt;unsigned length&gt; bool equalLettersIgnoringASCIICase(const CSSParserString&amp;, const char (&amp;lowercaseLetters)[length]);
-
-struct CSSParserFunction;
-struct CSSParserVariable;
-
-struct CSSParserValue {
-    CSSValueID id;
-    bool isInt;
-    union {
-        double fValue;
-        int iValue;
-        CSSParserString string;
-        CSSParserFunction* function;
-        CSSParserVariable* variable;
-        CSSParserValueList* valueList;
-    };
-    enum {
-        Operator  = 0x100000,
-        Function  = 0x100001,
-        ValueList = 0x100002,
-        Q_EMS     = 0x100003,
-        Variable  = 0x100004
-    };
-    int unit;
-
-    void setFromValueList(std::unique_ptr&lt;CSSParserValueList&gt;);
-
-    RefPtr&lt;CSSValue&gt; createCSSValue();
-};
-
-void destroy(const CSSParserValue&amp;);
-
-class CSSParserValueList {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    CSSParserValueList()
-        : m_current(0)
-    {
-    }
-    ~CSSParserValueList();
-
-    void addValue(const CSSParserValue&amp;);
-    void insertValueAt(unsigned, const CSSParserValue&amp;);
-    void extend(CSSParserValueList&amp;);
-
-    unsigned size() const { return m_values.size(); }
-    unsigned currentIndex() { return m_current; }
-    CSSParserValue* current() { return m_current &lt; m_values.size() ? &amp;m_values[m_current] : 0; }
-    CSSParserValue* next() { ++m_current; return current(); }
-    CSSParserValue* previous()
-    {
-        if (!m_current)
-            return 0;
-        --m_current;
-        return current();
-    }
-    void setCurrentIndex(unsigned index)
-    {
-        ASSERT(index &lt; m_values.size());
-        if (index &lt; m_values.size())
-            m_current = index;
-    }
-
-    CSSParserValue* valueAt(unsigned i) { return i &lt; m_values.size() ? &amp;m_values[i] : 0; }
-
-    void clear() { m_values.clear(); }
-    
-    String toString();
-    
-    bool containsVariables() const;
-
-private:
-    unsigned m_current;
-    Vector&lt;CSSParserValue, 4&gt; m_values;
-};
-
-struct CSSParserFunction {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    CSSParserString name;
-    std::unique_ptr&lt;CSSParserValueList&gt; args;
-};
-
-struct CSSParserVariable {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    CSSParserString name; // The custom property name
-    std::unique_ptr&lt;CSSParserValueList&gt; args; // The fallback args
-};
-
-enum class CSSParserSelectorCombinator {
-    Child,
-    DescendantSpace,
-#if ENABLE(CSS_SELECTORS_LEVEL4)
-    DescendantDoubleChild,
-#endif
-    DirectAdjacent,
-    IndirectAdjacent
-};
-
-class CSSParserSelector {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    static CSSParserSelector* parsePagePseudoSelector(const CSSParserString&amp; pseudoTypeString);
-    static CSSParserSelector* parsePseudoElementSelector(CSSParserString&amp; pseudoTypeString);
-    static CSSParserSelector* parsePseudoElementCueFunctionSelector(const CSSParserString&amp; functionIdentifier, Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;*);
-    static CSSParserSelector* parsePseudoElementSlottedFunctionSelector(const CSSParserString&amp; functionIdentifier, CSSParserSelector*);
-    static CSSParserSelector* parsePseudoClassHostFunctionSelector(const CSSParserString&amp; functionIdentifier, CSSParserSelector*);
-    static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString&amp; pseudoTypeString);
-
-    CSSParserSelector();
-    explicit CSSParserSelector(const QualifiedName&amp;);
-    ~CSSParserSelector();
-
-    std::unique_ptr&lt;CSSSelector&gt; releaseSelector() { return WTFMove(m_selector); }
-
-    void setValue(const AtomicString&amp; value) { m_selector-&gt;setValue(value); }
-    void setAttribute(const QualifiedName&amp; value, bool isCaseInsensitive) { m_selector-&gt;setAttribute(value, isCaseInsensitive); }
-    void setArgument(const AtomicString&amp; value) { m_selector-&gt;setArgument(value); }
-    void setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive) { m_selector-&gt;setAttributeValueMatchingIsCaseInsensitive(isCaseInsensitive); }
-    void setMatch(CSSSelector::Match value) { m_selector-&gt;setMatch(value); }
-    void setRelation(CSSSelector::Relation value) { m_selector-&gt;setRelation(value); }
-    void setForPage() { m_selector-&gt;setForPage(); }
-
-    void adoptSelectorVector(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&amp; selectorVector);
-    void setLangArgumentList(const Vector&lt;CSSParserString&gt;&amp; stringVector);
-
-    void setPseudoClassValue(const CSSParserString&amp; pseudoClassString);
-    CSSSelector::PseudoClassType pseudoClassType() const { return m_selector-&gt;pseudoClassType(); }
-    bool isCustomPseudoElement() const { return m_selector-&gt;isCustomPseudoElement(); }
-
-    bool isPseudoElementCueFunction() const
-    {
-#if ENABLE(VIDEO_TRACK)
-        return m_selector-&gt;match() == CSSSelector::PseudoElement &amp;&amp; m_selector-&gt;pseudoElementType() == CSSSelector::PseudoElementCue;
-#else
-        return false;
-#endif
-    }
-
-    bool hasShadowDescendant() const;
-    bool matchesPseudoElement() const;
-
-    CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
-    void setTagHistory(std::unique_ptr&lt;CSSParserSelector&gt; selector) { m_tagHistory = WTFMove(selector); }
-    void clearTagHistory() { m_tagHistory.reset(); }
-    void insertTagHistory(CSSSelector::Relation before, std::unique_ptr&lt;CSSParserSelector&gt;, CSSSelector::Relation after);
-    void appendTagHistory(CSSSelector::Relation, std::unique_ptr&lt;CSSParserSelector&gt;);
-    void appendTagHistory(CSSParserSelectorCombinator, std::unique_ptr&lt;CSSParserSelector&gt;);
-    void prependTagSelector(const QualifiedName&amp;, bool tagIsForNamespaceRule = false);
-
-private:
-#if ENABLE(CSS_SELECTORS_LEVEL4)
-    void setDescendantUseDoubleChildSyntax() { m_selector-&gt;setDescendantUseDoubleChildSyntax(); }
-#endif
-
-    std::unique_ptr&lt;CSSSelector&gt; m_selector;
-    std::unique_ptr&lt;CSSParserSelector&gt; m_tagHistory;
-};
-
-inline bool CSSParserSelector::hasShadowDescendant() const
-{
-    return m_selector-&gt;relation() == CSSSelector::ShadowDescendant;
-}
-
-inline void CSSParserValue::setFromValueList(std::unique_ptr&lt;CSSParserValueList&gt; valueList)
-{
-    id = CSSValueInvalid;
-    this-&gt;valueList = valueList.release();
-    unit = ValueList;
-}
-
-template&lt;unsigned length&gt; inline bool equalLettersIgnoringASCIICase(const CSSParserString&amp; string, const char (&amp;lowercaseLetters)[length])
-{
-    return WTF::equalLettersIgnoringASCIICaseCommon(string, lowercaseLetters);
-}
-
-}
</del></span></pre></div>
<a id="trunkSourceWebCorecssSVGCSSParsercpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/css/SVGCSSParser.cpp (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/SVGCSSParser.cpp        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/css/SVGCSSParser.cpp        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -1,432 +0,0 @@
</span><del>-/*
-    Copyright (C) 2008 Eric Seidel &lt;eric@webkit.org&gt;
-    Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann &lt;zimmermann@kde.org&gt;
-                  2004, 2005, 2007, 2010 Rob Buis &lt;buis@kde.org&gt;
-    Copyright (C) 2005, 2006 Apple Inc.
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-
-#include &quot;config.h&quot;
-
-#include &quot;CSSInheritedValue.h&quot;
-#include &quot;CSSInitialValue.h&quot;
-#include &quot;CSSParser.h&quot;
-#include &quot;CSSPropertyNames.h&quot;
-#include &quot;CSSValueKeywords.h&quot;
-#include &quot;CSSValueList.h&quot;
-#include &quot;RenderTheme.h&quot;
-#include &quot;SVGPaint.h&quot;
-
-namespace WebCore {
-
-static bool isValidSystemControlColorValue(CSSValueID id)
-{
-    return id &gt;= CSSValueActiveborder &amp;&amp; CSSParser::isValidSystemColorValue(id);
-}
-
-bool CSSParser::parseSVGValue(CSSPropertyID propId, bool important)
-{
-    if (!m_valueList-&gt;current())
-        return false;
-    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
-
-    CSSValueID id = valueWithCalculation.value().id;
-
-    bool valid_primitive = false;
-    RefPtr&lt;CSSValue&gt; parsedValue;
-
-    switch (propId) {
-    /* The comment to the right defines all valid value of these
-     * properties as defined in SVG 1.1, Appendix N. Property index */
-    case CSSPropertyAlignmentBaseline:
-    // auto | baseline | before-edge | text-before-edge | middle |
-    // central | after-edge | text-after-edge | ideographic | alphabetic |
-    // hanging | mathematical | inherit
-        if (id == CSSValueAuto || id == CSSValueBaseline || id == CSSValueMiddle ||
-          (id &gt;= CSSValueBeforeEdge &amp;&amp; id &lt;= CSSValueMathematical))
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyBaselineShift:
-    // baseline | super | sub | &lt;percentage&gt; | &lt;length&gt; | inherit
-        if (id == CSSValueBaseline || id == CSSValueSub ||
-           id &gt;= CSSValueSuper)
-            valid_primitive = true;
-        else
-            valid_primitive = validateUnit(valueWithCalculation, FLength | FPercent, SVGAttributeMode);
-        break;
-
-    case CSSPropertyDominantBaseline:
-    // auto | use-script | no-change | reset-size | ideographic |
-    // alphabetic | hanging | mathematical | central | middle |
-    // text-after-edge | text-before-edge | inherit
-        if (id == CSSValueAuto || id == CSSValueMiddle ||
-          (id &gt;= CSSValueUseScript &amp;&amp; id &lt;= CSSValueResetSize) ||
-          (id &gt;= CSSValueCentral &amp;&amp; id &lt;= CSSValueMathematical))
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyEnableBackground:
-    // accumulate | new [x] [y] [width] [height] | inherit
-        if (id == CSSValueAccumulate) // TODO : new
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyMarkerStart:
-    case CSSPropertyMarkerMid:
-    case CSSPropertyMarkerEnd:
-    case CSSPropertyMask:
-        if (id == CSSValueNone)
-            valid_primitive = true;
-        else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_URI) {
-            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().string, CSSPrimitiveValue::CSS_URI);
-            if (parsedValue)
-                m_valueList-&gt;next();
-        }
-        break;
-
-    case CSSPropertyClipRule:            // nonzero | evenodd | inherit
-    case CSSPropertyFillRule:
-        if (id == CSSValueNonzero || id == CSSValueEvenodd)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyStrokeMiterlimit:   // &lt;miterlimit&gt; | inherit
-        valid_primitive = validateUnit(valueWithCalculation, FNumber | FNonNeg, SVGAttributeMode);
-        break;
-
-    case CSSPropertyStrokeLinejoin:   // miter | round | bevel | inherit
-        if (id == CSSValueMiter || id == CSSValueRound || id == CSSValueBevel)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyStrokeLinecap:    // butt | round | square | inherit
-        if (id == CSSValueButt || id == CSSValueRound || id == CSSValueSquare)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyStrokeOpacity:   // &lt;opacity-value&gt; | inherit
-    case CSSPropertyFillOpacity:
-    case CSSPropertyStopOpacity:
-    case CSSPropertyFloodOpacity:
-        valid_primitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FPercent, SVGAttributeMode));
-        break;
-
-    case CSSPropertyShapeRendering:
-    // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
-        if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
-            id == CSSValueCrispedges || id == CSSValueGeometricprecision)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyColorRendering: // auto | optimizeSpeed | optimizeQuality | inherit
-        if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
-            id == CSSValueOptimizequality)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyBufferedRendering: // auto | dynamic | static
-        if (id == CSSValueAuto || id == CSSValueDynamic || id == CSSValueStatic)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyColorProfile: // auto | sRGB | &lt;name&gt; | &lt;uri&gt; inherit
-        if (id == CSSValueAuto || id == CSSValueSrgb)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyColorInterpolation:   // auto | sRGB | linearRGB | inherit
-    case CSSPropertyColorInterpolationFilters:
-        if (id == CSSValueAuto || id == CSSValueSrgb || id == CSSValueLinearrgb)
-            valid_primitive = true;
-        break;
-
-    /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
-     * correctly and allows optimization in applyRule(..)
-     */
-
-    case CSSPropertyTextAnchor:    // start | middle | end | inherit
-        if (id == CSSValueStart || id == CSSValueMiddle || id == CSSValueEnd)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyGlyphOrientationVertical: // auto | &lt;angle&gt; | inherit
-        if (id == CSSValueAuto) {
-            valid_primitive = true;
-            break;
-        }
-        FALLTHROUGH;
-
-    case CSSPropertyGlyphOrientationHorizontal: // &lt;angle&gt; (restricted to _deg_ per SVG 1.1 spec) | inherit
-        if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_DEG || valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_NUMBER) {
-            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().fValue, CSSPrimitiveValue::CSS_DEG);
-
-            if (parsedValue)
-                m_valueList-&gt;next();
-        }
-        break;
-    case CSSPropertyPaintOrder:
-        if (id == CSSValueNormal)
-            valid_primitive = true;
-        else
-            parsedValue = parsePaintOrder();
-        break;
-    case CSSPropertyFill:                 // &lt;paint&gt; | inherit
-    case CSSPropertyStroke:               // &lt;paint&gt; | inherit
-        {
-            if (id == CSSValueNone)
-                parsedValue = SVGPaint::createNone();
-            else if (id == CSSValueCurrentcolor)
-                parsedValue = SVGPaint::createCurrentColor();
-            else if (isValidSystemControlColorValue(id) || id == CSSValueMenu)
-                parsedValue = SVGPaint::createColor(RenderTheme::defaultTheme()-&gt;systemColor(id));
-            else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_URI) {
-                RGBA32 c = Color::transparent;
-                if (m_valueList-&gt;next()) {
-                    if (parseColorFromValue(*m_valueList-&gt;current(), c))
-                        parsedValue = SVGPaint::createURIAndColor(valueWithCalculation.value().string, c);
-                    else if (m_valueList-&gt;current()-&gt;id == CSSValueNone)
-                        parsedValue = SVGPaint::createURIAndNone(valueWithCalculation.value().string);
-                }
-                if (!parsedValue)
-                    parsedValue = SVGPaint::createURI(valueWithCalculation.value().string);
-            } else
-                parsedValue = parseSVGPaint();
-
-            if (parsedValue)
-                m_valueList-&gt;next();
-        }
-        break;
-
-    case CSSPropertyStopColor: // TODO : icccolor
-    case CSSPropertyFloodColor:
-    case CSSPropertyLightingColor:
-        if (CSSParser::isValidSystemColorValue(id)
-            || (id &gt;= CSSValueAliceblue &amp;&amp; id &lt;= CSSValueYellowgreen))
-            parsedValue = SVGColor::createFromString(valueWithCalculation.value().string);
-        else if (id == CSSValueCurrentcolor)
-            parsedValue = SVGColor::createCurrentColor();
-        else // TODO : svgcolor (iccColor)
-            parsedValue = parseSVGColor();
-
-        if (parsedValue)
-            m_valueList-&gt;next();
-
-        break;
-
-    case CSSPropertyVectorEffect: // none | non-scaling-stroke | inherit
-        if (id == CSSValueNone || id == CSSValueNonScalingStroke)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyWritingMode:
-    // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
-        if (id == CSSValueLrTb || id == CSSValueRlTb || id == CSSValueTbRl || id == CSSValueLr || id == CSSValueRl || id == CSSValueTb)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyStrokeWidth:         // &lt;length&gt; | inherit
-    case CSSPropertyStrokeDashoffset:
-        valid_primitive = validateUnit(valueWithCalculation, FLength | FPercent, SVGAttributeMode);
-        break;
-    case CSSPropertyStrokeDasharray:     // none | &lt;dasharray&gt; | inherit
-        if (id == CSSValueNone)
-            valid_primitive = true;
-        else
-            parsedValue = parseSVGStrokeDasharray();
-
-        break;
-
-    case CSSPropertyKerning:              // auto | normal | &lt;length&gt; | inherit
-        if (id == CSSValueAuto || id == CSSValueNormal)
-            valid_primitive = true;
-        else
-            valid_primitive = validateUnit(valueWithCalculation, FLength, SVGAttributeMode);
-        break;
-
-    case CSSPropertyClipPath:    // &lt;uri&gt; | none | inherit
-    case CSSPropertyFilter:
-        if (id == CSSValueNone)
-            valid_primitive = true;
-        else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_URI) {
-            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().string, (CSSPrimitiveValue::UnitTypes) valueWithCalculation.value().unit);
-            if (parsedValue)
-                m_valueList-&gt;next();
-        }
-        break;
-    case CSSPropertyWebkitSvgShadow:
-        if (id == CSSValueNone)
-            valid_primitive = true;
-        else {
-            auto shadowValueList = parseShadow(*m_valueList, propId);
-            if (shadowValueList) {
-                addProperty(propId, WTFMove(shadowValueList), important);
-                m_valueList-&gt;next();
-                return true;
-            }
-            return false;
-        }
-        break;
-
-    case CSSPropertyMaskType: // luminance | alpha | inherit
-        if (id == CSSValueLuminance || id == CSSValueAlpha)
-            valid_primitive = true;
-        break;
-
-    /* shorthand properties */
-    case CSSPropertyMarker:
-    {
-        ShorthandScope scope(this, propId);
-        m_implicitShorthand = true;
-        if (!parseValue(CSSPropertyMarkerStart, important))
-            return false;
-        if (m_valueList-&gt;current()) {
-            rollbackLastProperties(1);
-            return false;
-        }
-        CSSValue* value = m_parsedProperties.last().value();
-        addProperty(CSSPropertyMarkerMid, value, important);
-        addProperty(CSSPropertyMarkerEnd, value, important);
-        m_implicitShorthand = false;
-        return true;
-    }
-    case CSSPropertyCx:
-    case CSSPropertyCy:
-    case CSSPropertyR:
-    case CSSPropertyRx:
-    case CSSPropertyRy:
-    case CSSPropertyX:
-    case CSSPropertyY:
-        valid_primitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent));
-        break;
-    default:
-        // If you crash here, it's because you added a css property and are not handling it
-        // in either this switch statement or the one in CSSParser::parseValue
-        ASSERT_WITH_MESSAGE(0, &quot;unimplemented propertyID: %d&quot;, propId);
-        return false;
-    }
-
-    if (valid_primitive) {
-        if (id != 0)
-            parsedValue = CSSPrimitiveValue::createIdentifier(id);
-        else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING)
-            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().string, (CSSPrimitiveValue::UnitTypes) valueWithCalculation.value().unit);
-        else if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_KHZ)
-            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().fValue, (CSSPrimitiveValue::UnitTypes) valueWithCalculation.value().unit);
-        else if (valueWithCalculation.value().unit &gt;= CSSParserValue::Q_EMS)
-            parsedValue = CSSPrimitiveValue::createAllowingMarginQuirk(valueWithCalculation.value().fValue, CSSPrimitiveValue::CSS_EMS);
-        if (isCalculation(valueWithCalculation))
-            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.calculation());
-        m_valueList-&gt;next();
-    }
-    if (!parsedValue || (m_valueList-&gt;current() &amp;&amp; !inShorthand()))
-        return false;
-
-    addProperty(propId, WTFMove(parsedValue), important);
-    return true;
-}
-
-RefPtr&lt;CSSValueList&gt; CSSParser::parseSVGStrokeDasharray()
-{
-    RefPtr&lt;CSSValueList&gt; ret = CSSValueList::createCommaSeparated();
-    CSSParserValue* value = m_valueList-&gt;current();
-    bool valid_primitive = true;
-    while (value) {
-        ValueWithCalculation valueWithCalculation(*value);
-        valid_primitive = validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg, SVGAttributeMode);
-        if (!valid_primitive)
-            break;
-        // FIXME: This code doesn't handle calculated values.
-        if (value-&gt;id != 0)
-            ret-&gt;append(CSSPrimitiveValue::createIdentifier(value-&gt;id));
-        else if (value-&gt;unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; value-&gt;unit &lt;= CSSPrimitiveValue::CSS_KHZ)
-            ret-&gt;append(CSSPrimitiveValue::create(value-&gt;fValue, (CSSPrimitiveValue::UnitTypes) value-&gt;unit));
-        value = m_valueList-&gt;next();
-        if (value &amp;&amp; value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')
-            value = m_valueList-&gt;next();
-    }
-    if (!valid_primitive)
-        return nullptr;
-    return ret;
-}
-
-RefPtr&lt;SVGPaint&gt; CSSParser::parseSVGPaint()
-{
-    RGBA32 c = Color::transparent;
-    if (!parseColorFromValue(*m_valueList-&gt;current(), c))
-        return nullptr;
-    return SVGPaint::createColor(Color(c));
-}
-
-RefPtr&lt;SVGColor&gt; CSSParser::parseSVGColor()
-{
-    RGBA32 c = Color::transparent;
-    if (!parseColorFromValue(*m_valueList-&gt;current(), c))
-        return nullptr;
-    return SVGColor::createFromColor(Color(c));
-}
-
-RefPtr&lt;CSSValueList&gt; CSSParser::parsePaintOrder()
-{
-    CSSParserValue* value = m_valueList-&gt;current();
-
-    Vector&lt;CSSValueID&gt; paintTypeList;
-    RefPtr&lt;CSSPrimitiveValue&gt; fill;
-    RefPtr&lt;CSSPrimitiveValue&gt; stroke;
-    RefPtr&lt;CSSPrimitiveValue&gt; markers;
-    while (value) {
-        if (value-&gt;id == CSSValueFill &amp;&amp; !fill)
-            fill = CSSPrimitiveValue::createIdentifier(value-&gt;id);
-        else if (value-&gt;id == CSSValueStroke &amp;&amp; !stroke)
-            stroke = CSSPrimitiveValue::createIdentifier(value-&gt;id);
-        else if (value-&gt;id == CSSValueMarkers &amp;&amp; !markers)
-            markers = CSSPrimitiveValue::createIdentifier(value-&gt;id);
-        else
-            return nullptr;
-        paintTypeList.append(value-&gt;id);
-        value = m_valueList-&gt;next();
-    }
-
-    // After parsing we serialize the paint-order list. Since it is not possible to
-    // pop a last list items from CSSValueList without bigger cost, we create the
-    // list after parsing. 
-    CSSValueID firstPaintOrderType = paintTypeList.at(0);
-    auto paintOrderList = CSSValueList::createSpaceSeparated();
-    switch (firstPaintOrderType) {
-    case CSSValueFill:
-        FALLTHROUGH;
-    case CSSValueStroke:
-        paintOrderList-&gt;append(firstPaintOrderType == CSSValueFill ? fill.releaseNonNull() : stroke.releaseNonNull());
-        if (paintTypeList.size() &gt; 1) {
-            if (paintTypeList.at(1) == CSSValueMarkers)
-                paintOrderList-&gt;append(markers.releaseNonNull());
-        }
-        break;
-    case CSSValueMarkers:
-        paintOrderList-&gt;append(markers.releaseNonNull());
-        if (paintTypeList.size() &gt; 1) {
-            if (paintTypeList.at(1) == CSSValueStroke)
-                paintOrderList-&gt;append(stroke.releaseNonNull());
-        }
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-    return WTFMove(paintOrderList);
-}
-
-}
</del></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParsercppfromrev204839trunkSourceWebCorecssCSSParsercpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/css/parser/CSSParser.cpp (from rev 204839, trunk/Source/WebCore/css/CSSParser.cpp) (0 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParser.cpp                                (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSParser.cpp        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -0,0 +1,13857 @@
</span><ins>+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ * Copyright (C) 2004-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Nicholas Shanks &lt;webkit@nickshanks.com&gt;
+ * Copyright (C) 2008 Eric Seidel &lt;eric@webkit.org&gt;
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;CSSParser.h&quot;
+
+#include &quot;CSSAnimationTriggerScrollValue.h&quot;
+#include &quot;CSSAspectRatioValue.h&quot;
+#include &quot;CSSBasicShapes.h&quot;
+#include &quot;CSSBorderImage.h&quot;
+#include &quot;CSSBorderImageSliceValue.h&quot;
+#include &quot;CSSCanvasValue.h&quot;
+#include &quot;CSSContentDistributionValue.h&quot;
+#include &quot;CSSCrossfadeValue.h&quot;
+#include &quot;CSSCursorImageValue.h&quot;
+#include &quot;CSSCustomPropertyValue.h&quot;
+#include &quot;CSSFilterImageValue.h&quot;
+#include &quot;CSSFontFaceRule.h&quot;
+#include &quot;CSSFontFaceSrcValue.h&quot;
+#include &quot;CSSFontFeatureValue.h&quot;
+#include &quot;CSSFontValue.h&quot;
+#include &quot;CSSFunctionValue.h&quot;
+#include &quot;CSSGradientValue.h&quot;
+#include &quot;CSSImageSetValue.h&quot;
+#include &quot;CSSImageValue.h&quot;
+#include &quot;CSSInheritedValue.h&quot;
+#include &quot;CSSInitialValue.h&quot;
+#include &quot;CSSKeyframeRule.h&quot;
+#include &quot;CSSKeyframesRule.h&quot;
+#include &quot;CSSLineBoxContainValue.h&quot;
+#include &quot;CSSMediaRule.h&quot;
+#include &quot;CSSNamedImageValue.h&quot;
+#include &quot;CSSPageRule.h&quot;
+#include &quot;CSSPrimitiveValue.h&quot;
+#include &quot;CSSPrimitiveValueMappings.h&quot;
+#include &quot;CSSPropertySourceData.h&quot;
+#include &quot;CSSReflectValue.h&quot;
+#include &quot;CSSRevertValue.h&quot;
+#include &quot;CSSSelector.h&quot;
+#include &quot;CSSShadowValue.h&quot;
+#include &quot;CSSStyleSheet.h&quot;
+#include &quot;CSSTimingFunctionValue.h&quot;
+#include &quot;CSSUnicodeRangeValue.h&quot;
+#include &quot;CSSUnsetValue.h&quot;
+#include &quot;CSSValueKeywords.h&quot;
+#include &quot;CSSValueList.h&quot;
+#include &quot;CSSValuePool.h&quot;
+#include &quot;CSSVariableDependentValue.h&quot;
+#include &quot;Counter.h&quot;
+#include &quot;Document.h&quot;
+#include &quot;FloatConversion.h&quot;
+#include &quot;GridArea.h&quot;
+#include &quot;HTMLOptGroupElement.h&quot;
+#include &quot;HTMLParserIdioms.h&quot;
+#include &quot;HashTools.h&quot;
+#include &quot;MediaList.h&quot;
+#include &quot;MediaQueryExp.h&quot;
+#include &quot;Page.h&quot;
+#include &quot;PageConsoleClient.h&quot;
+#include &quot;Pair.h&quot;
+#include &quot;Rect.h&quot;
+#include &quot;RenderTheme.h&quot;
+#include &quot;RuntimeEnabledFeatures.h&quot;
+#include &quot;SVGParserUtilities.h&quot;
+#include &quot;SVGPathByteStream.h&quot;
+#include &quot;SVGPathUtilities.h&quot;
+#include &quot;SelectorChecker.h&quot;
+#include &quot;SelectorCheckerTestFunctions.h&quot;
+#include &quot;Settings.h&quot;
+#include &quot;StyleProperties.h&quot;
+#include &quot;StylePropertyShorthand.h&quot;
+#include &quot;StylePropertyShorthandFunctions.h&quot;
+#include &quot;StyleRule.h&quot;
+#include &quot;StyleRuleImport.h&quot;
+#include &quot;StyleSheetContents.h&quot;
+#include &quot;TextEncoding.h&quot;
+#include &quot;WebKitCSSFilterValue.h&quot;
+#include &quot;WebKitCSSRegionRule.h&quot;
+#include &quot;WebKitCSSTransformValue.h&quot;
+#include &lt;bitset&gt;
+#include &lt;limits.h&gt;
+#include &lt;wtf/HexNumber.h&gt;
+#include &lt;wtf/NeverDestroyed.h&gt;
+#include &lt;wtf/StdLibExtras.h&gt;
+#include &lt;wtf/dtoa.h&gt;
+#include &lt;wtf/text/StringBuffer.h&gt;
+#include &lt;wtf/text/StringBuilder.h&gt;
+#include &lt;wtf/text/StringImpl.h&gt;
+
+#if ENABLE(CSS_GRID_LAYOUT)
+#include &quot;CSSGridAutoRepeatValue.h&quot;
+#include &quot;CSSGridLineNamesValue.h&quot;
+#include &quot;CSSGridTemplateAreasValue.h&quot;
+#endif
+
+#if ENABLE(CSS_SCROLL_SNAP)
+#include &quot;LengthRepeat.h&quot;
+#endif
+
+#if ENABLE(DASHBOARD_SUPPORT)
+#include &quot;DashboardRegion.h&quot;
+#endif
+
+#define YYDEBUG 0
+
+#if YYDEBUG &gt; 0
+extern int cssyydebug;
+#endif
+
+extern int cssyyparse(WebCore::CSSParser*);
+
+using namespace WTF;
+
+namespace {
+
+enum PropertyType {
+    PropertyExplicit,
+    PropertyImplicit
+};
+
+class ImplicitScope {
+    WTF_MAKE_NONCOPYABLE(ImplicitScope);
+public:
+    ImplicitScope(WebCore::CSSParser&amp; parser, PropertyType propertyType)
+        : m_parser(parser)
+    {
+        m_parser.m_implicitShorthand = propertyType == PropertyImplicit;
+    }
+
+    ~ImplicitScope()
+    {
+        m_parser.m_implicitShorthand = false;
+    }
+
+private:
+    WebCore::CSSParser&amp; m_parser;
+};
+
+} // namespace
+
+namespace WebCore {
+
+const unsigned CSSParser::invalidParsedPropertiesCount = std::numeric_limits&lt;unsigned&gt;::max();
+static const double MAX_SCALE = 1000000;
+
+template&lt;unsigned length&gt; bool equalLettersIgnoringASCIICase(const CSSParserValue&amp; value, const char (&amp;lowercaseLetters)[length])
+{
+    ASSERT(value.unit == CSSPrimitiveValue::CSS_IDENT || value.unit == CSSPrimitiveValue::CSS_STRING);
+    return equalLettersIgnoringASCIICase(value.string, lowercaseLetters);
+}
+
+static bool hasPrefix(const char* string, unsigned length, const char* prefix)
+{
+    for (unsigned i = 0; i &lt; length; ++i) {
+        if (!prefix[i])
+            return true;
+        if (string[i] != prefix[i])
+            return false;
+    }
+    return false;
+}
+
+template&lt;typename... Args&gt;
+static Ref&lt;CSSPrimitiveValue&gt; createPrimitiveValuePair(Args&amp;&amp;... args)
+{
+    return CSSValuePool::singleton().createValue(Pair::create(std::forward&lt;Args&gt;(args)...));
+}
+
+class AnimationParseContext {
+public:
+    AnimationParseContext() = default;
+
+    void commitFirstAnimation()
+    {
+        m_firstAnimationCommitted = true;
+    }
+
+    bool hasCommittedFirstAnimation() const
+    {
+        return m_firstAnimationCommitted;
+    }
+
+    void commitAnimationPropertyKeyword()
+    {
+        m_animationPropertyKeywordAllowed = false;
+    }
+
+    bool animationPropertyKeywordAllowed() const
+    {
+        return m_animationPropertyKeywordAllowed;
+    }
+
+    bool hasSeenAnimationPropertyKeyword() const
+    {
+        return m_hasSeenAnimationPropertyKeyword;
+    }
+
+    void sawAnimationPropertyKeyword()
+    {
+        m_hasSeenAnimationPropertyKeyword = true;
+    }
+
+private:
+    bool m_animationPropertyKeywordAllowed { true };
+    bool m_firstAnimationCommitted { false };
+    bool m_hasSeenAnimationPropertyKeyword { false };
+};
+
+const CSSParserContext&amp; strictCSSParserContext()
+{
+    static NeverDestroyed&lt;CSSParserContext&gt; strictContext(CSSStrictMode);
+    return strictContext;
+}
+
+CSSParserContext::CSSParserContext(CSSParserMode mode, const URL&amp; baseURL)
+    : baseURL(baseURL)
+    , mode(mode)
+#if ENABLE(CSS_GRID_LAYOUT)
+    , cssGridLayoutEnabled(RuntimeEnabledFeatures::sharedFeatures().isCSSGridLayoutEnabled())
+#endif
+{
+#if PLATFORM(IOS)
+    // FIXME: Force the site specific quirk below to work on iOS. Investigating other site specific quirks
+    // to see if we can enable the preference all together is to be handled by:
+    // &lt;rdar://problem/8493309&gt; Investigate Enabling Site Specific Quirks in MobileSafari and UIWebView
+    needsSiteSpecificQuirks = true;
+#endif
+}
+
+CSSParserContext::CSSParserContext(Document&amp; document, const URL&amp; baseURL, const String&amp; charset)
+    : baseURL(baseURL.isNull() ? document.baseURL() : baseURL)
+    , charset(charset)
+    , mode(document.inQuirksMode() ? CSSQuirksMode : CSSStrictMode)
+    , isHTMLDocument(document.isHTMLDocument())
+#if ENABLE(CSS_GRID_LAYOUT)
+    , cssGridLayoutEnabled(document.isCSSGridLayoutEnabled())
+#endif
+{
+    if (Settings* settings = document.settings()) {
+        needsSiteSpecificQuirks = settings-&gt;needsSiteSpecificQuirks();
+        enforcesCSSMIMETypeInNoQuirksMode = settings-&gt;enforceCSSMIMETypeInNoQuirksMode();
+        useLegacyBackgroundSizeShorthandBehavior = settings-&gt;useLegacyBackgroundSizeShorthandBehavior();
+#if ENABLE(IOS_TEXT_AUTOSIZING)
+        textAutosizingEnabled = settings-&gt;textAutosizingEnabled();
+#endif
+        springTimingFunctionEnabled = settings-&gt;springTimingFunctionEnabled();
+    }
+
+#if PLATFORM(IOS)
+    // FIXME: Force the site specific quirk below to work on iOS. Investigating other site specific quirks
+    // to see if we can enable the preference all together is to be handled by:
+    // &lt;rdar://problem/8493309&gt; Investigate Enabling Site Specific Quirks in MobileSafari and UIWebView
+    needsSiteSpecificQuirks = true;
+#endif
+}
+
+bool operator==(const CSSParserContext&amp; a, const CSSParserContext&amp; b)
+{
+    return a.baseURL == b.baseURL
+        &amp;&amp; a.charset == b.charset
+        &amp;&amp; a.mode == b.mode
+        &amp;&amp; a.isHTMLDocument == b.isHTMLDocument
+#if ENABLE(CSS_GRID_LAYOUT)
+        &amp;&amp; a.cssGridLayoutEnabled == b.cssGridLayoutEnabled
+#endif
+        &amp;&amp; a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks
+        &amp;&amp; a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode
+        &amp;&amp; a.useLegacyBackgroundSizeShorthandBehavior == b.useLegacyBackgroundSizeShorthandBehavior
+        &amp;&amp; a.springTimingFunctionEnabled == b.springTimingFunctionEnabled;
+}
+
+CSSParser::CSSParser(const CSSParserContext&amp; context)
+    : m_context(context)
+{
+#if YYDEBUG &gt; 0
+    cssyydebug = 1;
+#endif
+}
+
+CSSParser::~CSSParser()
+{
+}
+
+template&lt;typename CharacterType&gt; ALWAYS_INLINE static void convertToASCIILowercaseInPlace(CharacterType* characters, unsigned length)
+{
+    for (unsigned i = 0; i &lt; length; ++i)
+        characters[i] = toASCIILower(characters[i]);
+}
+
+void CSSParserString::convertToASCIILowercaseInPlace()
+{
+    if (is8Bit())
+        WebCore::convertToASCIILowercaseInPlace(characters8(), length());
+    else
+        WebCore::convertToASCIILowercaseInPlace(characters16(), length());
+}
+
+void CSSParser::setupParser(const char* prefix, unsigned prefixLength, StringView string, const char* suffix, unsigned suffixLength)
+{
+    m_parsedTextPrefixLength = prefixLength;
+    unsigned stringLength = string.length();
+    unsigned length = stringLength + m_parsedTextPrefixLength + suffixLength + 1;
+    m_length = length;
+
+    if (!stringLength || string.is8Bit()) {
+        m_dataStart8 = std::make_unique&lt;LChar[]&gt;(length);
+        for (unsigned i = 0; i &lt; m_parsedTextPrefixLength; ++i)
+            m_dataStart8[i] = prefix[i];
+
+        if (stringLength)
+            memcpy(m_dataStart8.get() + m_parsedTextPrefixLength, string.characters8(), stringLength * sizeof(LChar));
+
+        unsigned start = m_parsedTextPrefixLength + stringLength;
+        unsigned end = start + suffixLength;
+        for (unsigned i = start; i &lt; end; i++)
+            m_dataStart8[i] = suffix[i - start];
+
+        m_dataStart8[length - 1] = '\0';
+
+        m_is8BitSource = true;
+        m_currentCharacter8 = m_dataStart8.get();
+        m_currentCharacter16 = nullptr;
+        setTokenStart&lt;LChar&gt;(m_currentCharacter8);
+        m_lexFunc = &amp;CSSParser::realLex&lt;LChar&gt;;
+        return;
+    }
+
+    m_dataStart16 = std::make_unique&lt;UChar[]&gt;(length);
+    for (unsigned i = 0; i &lt; m_parsedTextPrefixLength; ++i)
+        m_dataStart16[i] = prefix[i];
+
+    ASSERT(stringLength);
+    memcpy(m_dataStart16.get() + m_parsedTextPrefixLength, string.characters16(), stringLength * sizeof(UChar));
+
+    unsigned start = m_parsedTextPrefixLength + stringLength;
+    unsigned end = start + suffixLength;
+    for (unsigned i = start; i &lt; end; i++)
+        m_dataStart16[i] = suffix[i - start];
+
+    m_dataStart16[length - 1] = '\0';
+
+    m_is8BitSource = false;
+    m_currentCharacter8 = nullptr;
+    m_currentCharacter16 = m_dataStart16.get();
+    setTokenStart&lt;UChar&gt;(m_currentCharacter16);
+    m_lexFunc = &amp;CSSParser::realLex&lt;UChar&gt;;
+}
+
+void CSSParser::parseSheet(StyleSheetContents* sheet, const String&amp; string, const TextPosition&amp; textPosition, RuleSourceDataList* ruleSourceDataResult, bool logErrors)
+{
+    setStyleSheet(sheet);
+    m_defaultNamespace = starAtom; // Reset the default namespace.
+    if (ruleSourceDataResult)
+        m_currentRuleDataStack = std::make_unique&lt;RuleSourceDataList&gt;();
+    m_ruleSourceDataResult = ruleSourceDataResult;
+
+    m_logErrors = logErrors &amp;&amp; sheet-&gt;singleOwnerDocument() &amp;&amp; !sheet-&gt;baseURL().isEmpty() &amp;&amp; sheet-&gt;singleOwnerDocument()-&gt;page();
+    m_ignoreErrorsInDeclaration = false;
+    m_sheetStartLineNumber = textPosition.m_line.zeroBasedInt();
+    m_sheetStartColumnNumber = textPosition.m_column.zeroBasedInt();
+    m_lineNumber = m_sheetStartLineNumber;
+    m_columnOffsetForLine = 0;
+    setupParser(&quot;&quot;, string, &quot;&quot;);
+    cssyyparse(this);
+    sheet-&gt;shrinkToFit();
+    m_currentRuleDataStack.reset();
+    m_ruleSourceDataResult = nullptr;
+    m_rule = nullptr;
+    m_ignoreErrorsInDeclaration = false;
+    m_logErrors = false;
+}
+
+RefPtr&lt;StyleRuleBase&gt; CSSParser::parseRule(StyleSheetContents* sheet, const String&amp; string)
+{
+    setStyleSheet(sheet);
+    m_allowNamespaceDeclarations = false;
+    setupParser(&quot;@-webkit-rule{&quot;, string, &quot;} &quot;);
+    cssyyparse(this);
+    return m_rule;
+}
+
+RefPtr&lt;StyleKeyframe&gt; CSSParser::parseKeyframeRule(StyleSheetContents* sheet, const String&amp; string)
+{
+    setStyleSheet(sheet);
+    setupParser(&quot;@-webkit-keyframe-rule{ &quot;, string, &quot;} &quot;);
+    cssyyparse(this);
+    return m_keyframe;
+}
+
+bool CSSParser::parseSupportsCondition(const String&amp; string)
+{
+    m_supportsCondition = false;
+    // can't use { because tokenizer state switches from supports to initial state when it sees { token.
+    // instead insert one &quot; &quot; (which is WHITESPACE in CSSGrammar.y)
+    setupParser(&quot;@-webkit-supports-condition &quot;, string, &quot;} &quot;);
+    cssyyparse(this);
+    return m_supportsCondition;
+}
+
+static inline bool isColorPropertyID(CSSPropertyID propertyId)
+{
+    switch (propertyId) {
+    case CSSPropertyColor:
+    case CSSPropertyBackgroundColor:
+    case CSSPropertyBorderBottomColor:
+    case CSSPropertyBorderLeftColor:
+    case CSSPropertyBorderRightColor:
+    case CSSPropertyBorderTopColor:
+    case CSSPropertyOutlineColor:
+    case CSSPropertyTextLineThroughColor:
+    case CSSPropertyTextOverlineColor:
+    case CSSPropertyTextUnderlineColor:
+    case CSSPropertyWebkitBorderAfterColor:
+    case CSSPropertyWebkitBorderBeforeColor:
+    case CSSPropertyWebkitBorderEndColor:
+    case CSSPropertyWebkitBorderStartColor:
+    case CSSPropertyColumnRuleColor:
+    case CSSPropertyWebkitTextDecorationColor:
+    case CSSPropertyWebkitTextEmphasisColor:
+    case CSSPropertyWebkitTextFillColor:
+    case CSSPropertyWebkitTextStrokeColor:
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool CSSParser::isValidSystemColorValue(CSSValueID valueID)
+{
+    return valueID &gt;= CSSValueAqua &amp;&amp; valueID &lt;= CSSValueAppleSystemYellow;
+}
+
+static bool validPrimitiveValueColor(CSSValueID valueID, bool strict = false)
+{
+    return (valueID == CSSValueWebkitText || valueID == CSSValueCurrentcolor || valueID == CSSValueMenu
+        || CSSParser::isValidSystemColorValue(valueID) || valueID == CSSValueAlpha
+        || (valueID &gt;= CSSValueWebkitFocusRingColor &amp;&amp; valueID &lt; CSSValueWebkitText &amp;&amp; !strict));
+}
+
+static CSSParser::ParseResult parseColorValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyId, const String&amp; string, bool important, CSSParserMode cssParserMode)
+{
+    ASSERT(!string.isEmpty());
+    bool strict = isStrictParserMode(cssParserMode);
+    if (!isColorPropertyID(propertyId))
+        return CSSParser::ParseResult::Error;
+
+    CSSParserString cssString;
+    cssString.init(string);
+    CSSValueID valueID = cssValueKeywordID(cssString);
+    if (validPrimitiveValueColor(valueID, strict)) {
+        auto value = CSSValuePool::singleton().createIdentifierValue(valueID);
+        return declaration.addParsedProperty(CSSProperty(propertyId, WTFMove(value), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
+    }
+    RGBA32 color;
+    if (!CSSParser::fastParseColor(color, string, strict &amp;&amp; string[0] != '#'))
+        return CSSParser::ParseResult::Error;
+
+    auto value = CSSValuePool::singleton().createColorValue(color);
+    return declaration.addParsedProperty(CSSProperty(propertyId, WTFMove(value), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
+}
+
+static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool&amp; acceptsNegativeNumbers)
+{
+    switch (propertyId) {
+    case CSSPropertyFontSize:
+    case CSSPropertyHeight:
+    case CSSPropertyWidth:
+    case CSSPropertyMinHeight:
+    case CSSPropertyMinWidth:
+    case CSSPropertyPaddingBottom:
+    case CSSPropertyPaddingLeft:
+    case CSSPropertyPaddingRight:
+    case CSSPropertyPaddingTop:
+    case CSSPropertyWebkitLogicalWidth:
+    case CSSPropertyWebkitLogicalHeight:
+    case CSSPropertyWebkitMinLogicalWidth:
+    case CSSPropertyWebkitMinLogicalHeight:
+    case CSSPropertyWebkitPaddingAfter:
+    case CSSPropertyWebkitPaddingBefore:
+    case CSSPropertyWebkitPaddingEnd:
+    case CSSPropertyWebkitPaddingStart:
+#if ENABLE(CSS_GRID_LAYOUT)
+    case CSSPropertyGridColumnGap:
+    case CSSPropertyGridRowGap:
+#endif
+#if ENABLE(CSS_SHAPES)
+    case CSSPropertyWebkitShapeMargin:
+#endif
+        acceptsNegativeNumbers = false;
+        return true;
+    case CSSPropertyBottom:
+    case CSSPropertyCx:
+    case CSSPropertyCy:
+    case CSSPropertyLeft:
+    case CSSPropertyMarginBottom:
+    case CSSPropertyMarginLeft:
+    case CSSPropertyMarginRight:
+    case CSSPropertyMarginTop:
+    case CSSPropertyR:
+    case CSSPropertyRx:
+    case CSSPropertyRy:
+    case CSSPropertyRight:
+    case CSSPropertyTop:
+    case CSSPropertyWebkitMarginAfter:
+    case CSSPropertyWebkitMarginBefore:
+    case CSSPropertyWebkitMarginEnd:
+    case CSSPropertyWebkitMarginStart:
+    case CSSPropertyX:
+    case CSSPropertyY:
+        acceptsNegativeNumbers = true;
+        return true;
+    default:
+        return false;
+    }
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool parseSimpleLength(const CharacterType* characters, unsigned&amp; length, CSSPrimitiveValue::UnitTypes&amp; unit, double&amp; number)
+{
+    if (length &gt; 2 &amp;&amp; (characters[length - 2] | 0x20) == 'p' &amp;&amp; (characters[length - 1] | 0x20) == 'x') {
+        length -= 2;
+        unit = CSSPrimitiveValue::CSS_PX;
+    } else if (length &gt; 1 &amp;&amp; characters[length - 1] == '%') {
+        length -= 1;
+        unit = CSSPrimitiveValue::CSS_PERCENTAGE;
+    }
+
+    // We rely on charactersToDouble for validation as well. The function
+    // will set &quot;ok&quot; to &quot;false&quot; if the entire passed-in character range does
+    // not represent a double.
+    bool ok;
+    number = charactersToDouble(characters, length, &amp;ok);
+    return ok;
+}
+
+static CSSParser::ParseResult parseSimpleLengthValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyId, const String&amp; string, bool important, CSSParserMode cssParserMode)
+{
+    ASSERT(!string.isEmpty());
+    bool acceptsNegativeNumbers;
+    if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
+        return CSSParser::ParseResult::Error;
+
+    unsigned length = string.length();
+    double number;
+    CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
+
+    if (string.is8Bit()) {
+        if (!parseSimpleLength(string.characters8(), length, unit, number))
+            return CSSParser::ParseResult::Error;
+    } else {
+        if (!parseSimpleLength(string.characters16(), length, unit, number))
+            return CSSParser::ParseResult::Error;
+    }
+
+    if (unit == CSSPrimitiveValue::CSS_NUMBER) {
+        if (number &amp;&amp; isStrictParserMode(cssParserMode))
+            return CSSParser::ParseResult::Error;
+        unit = CSSPrimitiveValue::CSS_PX;
+    }
+    if (number &lt; 0 &amp;&amp; !acceptsNegativeNumbers)
+        return CSSParser::ParseResult::Error;
+    if (std::isinf(number))
+        return CSSParser::ParseResult::Error;
+
+    auto value = CSSValuePool::singleton().createValue(number, unit);
+    return declaration.addParsedProperty(CSSProperty(propertyId, WTFMove(value), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
+}
+
+static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext&amp; parserContext, StyleSheetContents* styleSheetContents)
+{
+    if (!valueID)
+        return false;
+
+    switch (propertyId) {
+    case CSSPropertyBorderCollapse: // collapse | separate | inherit
+        if (valueID == CSSValueCollapse || valueID == CSSValueSeparate)
+            return true;
+        break;
+    case CSSPropertyBorderTopStyle: // &lt;border-style&gt; | inherit
+    case CSSPropertyBorderRightStyle: // Defined as: none | hidden | dotted | dashed |
+    case CSSPropertyBorderBottomStyle: // solid | double | groove | ridge | inset | outset
+    case CSSPropertyBorderLeftStyle:
+    case CSSPropertyWebkitBorderAfterStyle:
+    case CSSPropertyWebkitBorderBeforeStyle:
+    case CSSPropertyWebkitBorderEndStyle:
+    case CSSPropertyWebkitBorderStartStyle:
+    case CSSPropertyColumnRuleStyle:
+        if (valueID &gt;= CSSValueNone &amp;&amp; valueID &lt;= CSSValueDouble)
+            return true;
+        break;
+    case CSSPropertyBoxSizing:
+         if (valueID == CSSValueBorderBox || valueID == CSSValueContentBox)
+             return true;
+         break;
+    case CSSPropertyCaptionSide: // top | bottom | left | right | inherit
+        if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueTop || valueID == CSSValueBottom)
+            return true;
+        break;
+    case CSSPropertyClear: // none | left | right | both | inherit
+        if (valueID == CSSValueNone || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueBoth)
+            return true;
+        break;
+    case CSSPropertyDirection: // ltr | rtl | inherit
+        if (valueID == CSSValueLtr || valueID == CSSValueRtl)
+            return true;
+        break;
+    case CSSPropertyDisplay:
+        // inline | block | list-item | inline-block | table |
+        // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
+        // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none | inherit
+        // flex | -webkit-flex | inline-flex | -webkit-inline-flex | grid | inline-grid | contents
+        if ((valueID &gt;= CSSValueInline &amp;&amp; valueID &lt;= CSSValueContents) || valueID == CSSValueNone)
+            return true;
+#if ENABLE(CSS_GRID_LAYOUT)
+        if (parserContext.cssGridLayoutEnabled &amp;&amp; (valueID == CSSValueGrid || valueID == CSSValueInlineGrid))
+            return true;
+#endif
+        break;
+
+    case CSSPropertyEmptyCells: // show | hide | inherit
+        if (valueID == CSSValueShow || valueID == CSSValueHide)
+            return true;
+        break;
+    case CSSPropertyFloat: // left | right | none | center (for buggy CSS, maps to none)
+        if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueNone || valueID == CSSValueCenter)
+            return true;
+        break;
+    case CSSPropertyFontStyle: // normal | italic | oblique | inherit
+        if (valueID == CSSValueNormal || valueID == CSSValueItalic || valueID == CSSValueOblique)
+            return true;
+        break;
+    case CSSPropertyImageRendering: // auto | optimizeSpeed | optimizeQuality | -webkit-crisp-edges | -webkit-optimize-contrast | crisp-edges | pixelated
+        // optimizeSpeed and optimizeQuality are deprecated; a user agent must accept them as valid values but must treat them as having the same behavior as pixelated and auto respectively.
+        if (valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizequality
+            || valueID == CSSValueWebkitCrispEdges || valueID == CSSValueWebkitOptimizeContrast || valueID == CSSValueCrispEdges || valueID == CSSValuePixelated)
+            return true;
+        break;
+    case CSSPropertyListStylePosition: // inside | outside | inherit
+        if (valueID == CSSValueInside || valueID == CSSValueOutside)
+            return true;
+        break;
+    case CSSPropertyListStyleType:
+        // See section CSS_PROP_LIST_STYLE_TYPE of file CSSValueKeywords.in
+        // for the list of supported list-style-types.
+        if ((valueID &gt;= CSSValueDisc &amp;&amp; valueID &lt;= CSSValueKatakanaIroha) || valueID == CSSValueNone)
+            return true;
+        break;
+    case CSSPropertyObjectFit:
+        if (valueID == CSSValueFill || valueID == CSSValueContain || valueID == CSSValueCover || valueID == CSSValueNone || valueID == CSSValueScaleDown)
+            return true;
+        break;
+    case CSSPropertyOutlineStyle: // (&lt;border-style&gt; except hidden) | auto | inherit
+        if (valueID == CSSValueAuto || valueID == CSSValueNone || (valueID &gt;= CSSValueInset &amp;&amp; valueID &lt;= CSSValueDouble))
+            return true;
+        break;
+    case CSSPropertyOverflowWrap: // normal | break-word
+    case CSSPropertyWordWrap:
+        if (valueID == CSSValueNormal || valueID == CSSValueBreakWord)
+            return true;
+        break;
+#if ENABLE(TOUCH_EVENTS)
+    case CSSPropertyTouchAction: // auto | manipulation
+        if (valueID == CSSValueAuto || valueID == CSSValueManipulation)
+            return true;
+        break;
+#endif
+#if ENABLE(CSS_SCROLL_SNAP)
+    case CSSPropertyWebkitScrollSnapType: // none | mandatory | proximity
+        if (valueID == CSSValueNone || valueID == CSSValueMandatory || valueID == CSSValueProximity)
+            return true;
+        break;
+#endif
+    case CSSPropertyOverflowX: // visible | hidden | scroll | auto  | overlay | inherit
+        if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay)
+            return true;
+        break;
+    case CSSPropertyOverflowY: // visible | hidden | scroll | auto | overlay | inherit | -webkit-paged-x | -webkit-paged-y
+        if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay || valueID == CSSValueWebkitPagedX || valueID == CSSValueWebkitPagedY)
+            return true;
+        break;
+    case CSSPropertyPageBreakAfter: // auto | always | avoid | left | right | inherit
+    case CSSPropertyPageBreakBefore:
+    case CSSPropertyWebkitColumnBreakAfter:
+    case CSSPropertyWebkitColumnBreakBefore:
+        if (valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight)
+            return true;
+        break;
+    case CSSPropertyPageBreakInside: // avoid | auto | inherit
+    case CSSPropertyWebkitColumnBreakInside:
+        if (valueID == CSSValueAuto || valueID == CSSValueAvoid)
+            return true;
+        break;
+    case CSSPropertyPointerEvents:
+        // none | visiblePainted | visibleFill | visibleStroke | visible |
+        // painted | fill | stroke | auto | all | inherit
+        if (valueID == CSSValueVisible || valueID == CSSValueNone || valueID == CSSValueAll || valueID == CSSValueAuto || (valueID &gt;= CSSValueVisiblepainted &amp;&amp; valueID &lt;= CSSValueStroke))
+            return true;
+        break;
+    case CSSPropertyPosition: // static | relative | absolute | fixed | sticky | inherit
+        if (valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed || valueID == CSSValueWebkitSticky)
+            return true;
+        break;
+    case CSSPropertyResize: // none | both | horizontal | vertical | auto
+        if (valueID == CSSValueNone || valueID == CSSValueBoth || valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueAuto)
+            return true;
+        break;
+    case CSSPropertySpeak: // none | normal | spell-out | digits | literal-punctuation | no-punctuation | inherit
+        if (valueID == CSSValueNone || valueID == CSSValueNormal || valueID == CSSValueSpellOut || valueID == CSSValueDigits || valueID == CSSValueLiteralPunctuation || valueID == CSSValueNoPunctuation)
+            return true;
+        break;
+    case CSSPropertyTableLayout: // auto | fixed | inherit
+        if (valueID == CSSValueAuto || valueID == CSSValueFixed)
+            return true;
+        break;
+    case CSSPropertyTextLineThroughMode:
+    case CSSPropertyTextOverlineMode:
+    case CSSPropertyTextUnderlineMode:
+        if (valueID == CSSValueContinuous || valueID == CSSValueSkipWhiteSpace)
+            return true;
+        break;
+    case CSSPropertyTextLineThroughStyle:
+    case CSSPropertyTextOverlineStyle:
+    case CSSPropertyTextUnderlineStyle:
+        if (valueID == CSSValueNone || valueID == CSSValueSolid || valueID == CSSValueDouble || valueID == CSSValueDashed || valueID == CSSValueDotDash || valueID == CSSValueDotDotDash || valueID == CSSValueWave)
+            return true;
+        break;
+    case CSSPropertyTextOverflow: // clip | ellipsis
+        if (valueID == CSSValueClip || valueID == CSSValueEllipsis)
+            return true;
+        break;
+    case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision
+        if (valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizelegibility || valueID == CSSValueGeometricprecision)
+            return true;
+        break;
+    case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none | inherit
+        if ((valueID &gt;= CSSValueCapitalize &amp;&amp; valueID &lt;= CSSValueLowercase) || valueID == CSSValueNone)
+            return true;
+        break;
+    case CSSPropertyVisibility: // visible | hidden | collapse | inherit
+        if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueCollapse)
+            return true;
+        break;
+    case CSSPropertyWebkitAppearance:
+        if ((valueID &gt;= CSSValueCheckbox &amp;&amp; valueID &lt;= CSSValueCapsLockIndicator) || valueID == CSSValueNone)
+            return true;
+        break;
+    case CSSPropertyWebkitBackfaceVisibility:
+        if (valueID == CSSValueVisible || valueID == CSSValueHidden)
+            return true;
+        break;
+#if ENABLE(CSS_COMPOSITING)
+    case CSSPropertyMixBlendMode:
+        if (valueID == CSSValueNormal || valueID == CSSValueMultiply || valueID == CSSValueScreen
+            || valueID == CSSValueOverlay || valueID == CSSValueDarken || valueID == CSSValueLighten ||  valueID == CSSValueColorDodge
+            || valueID == CSSValueColorBurn || valueID == CSSValueHardLight || valueID == CSSValueSoftLight || valueID == CSSValueDifference
+            || valueID == CSSValueExclusion || valueID == CSSValuePlusDarker || valueID == CSSValuePlusLighter)
+            return true;
+        break;
+    case CSSPropertyIsolation:
+        if (valueID == CSSValueAuto || valueID == CSSValueIsolate)
+            return true;
+        break;
+#endif
+    case CSSPropertyWebkitBorderFit:
+        if (valueID == CSSValueBorder || valueID == CSSValueLines)
+            return true;
+        break;
+    case CSSPropertyWebkitBoxAlign:
+        if (valueID == CSSValueStretch || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline)
+            return true;
+        break;
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
+    case CSSPropertyWebkitBoxDecorationBreak:
+         if (valueID == CSSValueClone || valueID == CSSValueSlice)
+             return true;
+         break;
+#endif
+    case CSSPropertyWebkitBoxDirection:
+        if (valueID == CSSValueNormal || valueID == CSSValueReverse)
+            return true;
+        break;
+    case CSSPropertyWebkitBoxLines:
+        if (valueID == CSSValueSingle || valueID == CSSValueMultiple)
+                return true;
+        break;
+    case CSSPropertyWebkitBoxOrient:
+        if (valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueInlineAxis || valueID == CSSValueBlockAxis)
+            return true;
+        break;
+    case CSSPropertyWebkitBoxPack:
+        if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify)
+            return true;
+        break;
+    case CSSPropertyColumnFill:
+        if (valueID == CSSValueAuto || valueID == CSSValueBalance)
+            return true;
+        break;
+    case CSSPropertyFlexDirection:
+        if (valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse)
+            return true;
+        break;
+    case CSSPropertyFlexWrap:
+        if (valueID == CSSValueNowrap || valueID == CSSValueWrap || valueID == CSSValueWrapReverse)
+             return true;
+        break;
+    case CSSPropertyWebkitFontKerning:
+        if (valueID == CSSValueAuto || valueID == CSSValueNormal || valueID == CSSValueNone)
+            return true;
+        break;
+    case CSSPropertyWebkitFontSmoothing:
+        if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueAntialiased || valueID == CSSValueSubpixelAntialiased)
+            return true;
+        break;
+    case CSSPropertyWebkitHyphens:
+        if (valueID == CSSValueNone || valueID == CSSValueManual || valueID == CSSValueAuto)
+            return true;
+        break;
+    case CSSPropertyWebkitLineAlign:
+        if (valueID == CSSValueNone || valueID == CSSValueEdges)
+            return true;
+        break;
+    case CSSPropertyWebkitLineBreak: // auto | loose | normal | strict | after-white-space
+        if (valueID == CSSValueAuto || valueID == CSSValueLoose || valueID == CSSValueNormal || valueID == CSSValueStrict || valueID == CSSValueAfterWhiteSpace)
+            return true;
+        break;
+    case CSSPropertyWebkitLineSnap:
+        if (valueID == CSSValueNone || valueID == CSSValueBaseline || valueID == CSSValueContain)
+            return true;
+        break;
+    case CSSPropertyWebkitMarginAfterCollapse:
+    case CSSPropertyWebkitMarginBeforeCollapse:
+    case CSSPropertyWebkitMarginBottomCollapse:
+    case CSSPropertyWebkitMarginTopCollapse:
+        if (valueID == CSSValueCollapse || valueID == CSSValueSeparate || valueID == CSSValueDiscard)
+            return true;
+        break;
+    case CSSPropertyWebkitMarqueeDirection:
+        if (valueID == CSSValueForwards || valueID == CSSValueBackwards || valueID == CSSValueAhead || valueID == CSSValueReverse || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueDown
+            || valueID == CSSValueUp || valueID == CSSValueAuto)
+            return true;
+        break;
+    case CSSPropertyWebkitMarqueeStyle:
+        if (valueID == CSSValueNone || valueID == CSSValueSlide || valueID == CSSValueScroll || valueID == CSSValueAlternate)
+            return true;
+        break;
+    case CSSPropertyWebkitNbspMode: // normal | space
+        if (valueID == CSSValueNormal || valueID == CSSValueSpace)
+            return true;
+        break;
+#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
+    case CSSPropertyWebkitOverflowScrolling:
+        if (valueID == CSSValueAuto || valueID == CSSValueTouch)
+            return true;
+        break;
+#endif
+    case CSSPropertyWebkitPrintColorAdjust:
+        if (valueID == CSSValueExact || valueID == CSSValueEconomy)
+            return true;
+        break;
+#if ENABLE(CSS_REGIONS)
+    case CSSPropertyWebkitRegionBreakAfter:
+    case CSSPropertyWebkitRegionBreakBefore:
+        if (valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight)
+            return true;
+        break;
+    case CSSPropertyWebkitRegionBreakInside:
+        if (valueID == CSSValueAuto || valueID == CSSValueAvoid)
+            return true;
+        break;
+    case CSSPropertyWebkitRegionFragment:
+        if (valueID == CSSValueAuto || valueID == CSSValueBreak)
+            return true;
+        break;
+#endif
+    case CSSPropertyWebkitRtlOrdering:
+        if (valueID == CSSValueLogical || valueID == CSSValueVisual)
+            return true;
+        break;
+
+    case CSSPropertyWebkitRubyPosition:
+        if (valueID == CSSValueBefore || valueID == CSSValueAfter || valueID == CSSValueInterCharacter)
+            return true;
+        break;
+
+#if ENABLE(CSS3_TEXT)
+    case CSSPropertyWebkitTextAlignLast:
+        // auto | start | end | left | right | center | justify
+        if ((valueID &gt;= CSSValueLeft &amp;&amp; valueID &lt;= CSSValueJustify) || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueAuto)
+            return true;
+        break;
+#endif // CSS3_TEXT
+    case CSSPropertyWebkitTextCombine:
+        if (valueID == CSSValueNone || valueID == CSSValueHorizontal)
+            return true;
+        break;
+#if ENABLE(CSS3_TEXT)
+    case CSSPropertyWebkitTextJustify:
+        // auto | none | inter-word | distribute
+        if (valueID == CSSValueInterWord || valueID == CSSValueDistribute || valueID == CSSValueAuto || valueID == CSSValueNone)
+            return true;
+        break;
+#endif // CSS3_TEXT
+    case CSSPropertyWebkitTextSecurity:
+        // disc | circle | square | none | inherit
+        if (valueID == CSSValueDisc || valueID == CSSValueCircle || valueID == CSSValueSquare || valueID == CSSValueNone)
+            return true;
+        break;
+#if ENABLE(IOS_TEXT_AUTOSIZING)
+    case CSSPropertyWebkitTextSizeAdjust:
+        if (!parserContext.textAutosizingEnabled)
+            return false;
+
+        if (valueID == CSSValueAuto || valueID == CSSValueNone)
+            return true;
+        break;
+#endif
+    case CSSPropertyTransformStyle:
+    case CSSPropertyWebkitTransformStyle:
+        if (valueID == CSSValueFlat || valueID == CSSValuePreserve3d)
+            return true;
+        break;
+    case CSSPropertyWebkitUserDrag: // auto | none | element
+        if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueElement)
+            return true;
+        break;
+    case CSSPropertyWebkitUserModify: // read-only | read-write
+        if (valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly) {
+            if (styleSheetContents)
+                styleSheetContents-&gt;parserSetUsesStyleBasedEditability();
+            return true;
+        }
+        break;
+    case CSSPropertyWebkitUserSelect: // auto | none | text | all
+        if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText)
+            return true;
+        if (valueID == CSSValueAll) {
+            if (styleSheetContents)
+                styleSheetContents-&gt;parserSetUsesStyleBasedEditability();
+            return true;
+        }
+        break;
+    case CSSPropertyWebkitWritingMode:
+        if (valueID &gt;= CSSValueHorizontalTb &amp;&amp; valueID &lt;= CSSValueHorizontalBt)
+            return true;
+        break;
+    case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit
+        if (valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap)
+            return true;
+        break;
+    case CSSPropertyWordBreak: // normal | break-all | keep-all | break-word (this is a custom extension)
+        if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueKeepAll || valueID == CSSValueBreakWord)
+            return true;
+        break;
+#if ENABLE(CSS_TRAILING_WORD)
+    case CSSPropertyAppleTrailingWord: // auto | -apple-partially-balanced
+        if (valueID == CSSValueAuto || valueID == CSSValueWebkitPartiallyBalanced)
+            return true;
+        break;
+#endif
+    case CSSPropertyFontVariantPosition: // normal | sub | super
+        if (valueID == CSSValueNormal || valueID == CSSValueSub || valueID == CSSValueSuper)
+            return true;
+        break;
+    case CSSPropertyFontVariantCaps: // normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps
+        if (valueID == CSSValueNormal || valueID == CSSValueSmallCaps || valueID == CSSValueAllSmallCaps || valueID == CSSValuePetiteCaps || valueID == CSSValueAllPetiteCaps || valueID == CSSValueUnicase || valueID == CSSValueTitlingCaps)
+            return true;
+        break;
+    case CSSPropertyFontVariantAlternates: // We only support the normal and historical-forms values.
+        if (valueID == CSSValueNormal || valueID == CSSValueHistoricalForms)
+            return true;
+        break;
+            
+    case CSSPropertyBreakAfter:
+    case CSSPropertyBreakBefore:
+        // auto | avoid | left | right | recto | verso | column | page | region | avoid-page | avoid-column | avoid-region
+        if (valueID == CSSValueAuto || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight
+            || valueID == CSSValueRecto || valueID == CSSValueVerso || valueID == CSSValueColumn || valueID == CSSValuePage
+            || valueID == CSSValueRegion || valueID == CSSValueAvoidColumn || valueID == CSSValueAvoidPage || valueID == CSSValueAvoidRegion)
+            return true;
+        break;
+    case CSSPropertyBreakInside:
+        // auto | avoid | avoid-page | avoid-column | avoid-region
+        if (valueID == CSSValueAuto || valueID == CSSValueAvoid || valueID == CSSValueAvoidColumn || valueID == CSSValueAvoidPage || valueID == CSSValueAvoidRegion)
+            return true;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+#if !ENABLE(CSS_GRID_LAYOUT)
+    UNUSED_PARAM(parserContext);
+#endif
+    return false;
+}
+
+static inline bool isKeywordPropertyID(CSSPropertyID propertyId)
+{
+    switch (propertyId) {
+    case CSSPropertyBorderBottomStyle:
+    case CSSPropertyBorderCollapse:
+    case CSSPropertyBorderLeftStyle:
+    case CSSPropertyBorderRightStyle:
+    case CSSPropertyBorderTopStyle:
+    case CSSPropertyBoxSizing:
+    case CSSPropertyBreakAfter:
+    case CSSPropertyBreakBefore:
+    case CSSPropertyBreakInside:
+    case CSSPropertyCaptionSide:
+    case CSSPropertyClear:
+    case CSSPropertyDirection:
+    case CSSPropertyDisplay:
+    case CSSPropertyEmptyCells:
+    case CSSPropertyFloat:
+    case CSSPropertyFontStyle:
+    case CSSPropertyImageRendering:
+    case CSSPropertyListStylePosition:
+    case CSSPropertyListStyleType:
+    case CSSPropertyObjectFit:
+    case CSSPropertyOutlineStyle:
+    case CSSPropertyOverflowWrap:
+    case CSSPropertyOverflowX:
+    case CSSPropertyOverflowY:
+    case CSSPropertyPageBreakAfter:
+    case CSSPropertyPageBreakBefore:
+    case CSSPropertyPageBreakInside:
+    case CSSPropertyPointerEvents:
+    case CSSPropertyPosition:
+    case CSSPropertyResize:
+    case CSSPropertySpeak:
+    case CSSPropertyTableLayout:
+    case CSSPropertyTextLineThroughMode:
+    case CSSPropertyTextLineThroughStyle:
+    case CSSPropertyTextOverflow:
+    case CSSPropertyTextOverlineMode:
+    case CSSPropertyTextOverlineStyle:
+    case CSSPropertyTextRendering:
+    case CSSPropertyTextTransform:
+    case CSSPropertyTextUnderlineMode:
+    case CSSPropertyTextUnderlineStyle:
+    case CSSPropertyVisibility:
+    case CSSPropertyWebkitAppearance:
+#if ENABLE(CSS_COMPOSITING)
+    case CSSPropertyMixBlendMode:
+    case CSSPropertyIsolation:
+#endif
+    case CSSPropertyWebkitBackfaceVisibility:
+    case CSSPropertyWebkitBorderAfterStyle:
+    case CSSPropertyWebkitBorderBeforeStyle:
+    case CSSPropertyWebkitBorderEndStyle:
+    case CSSPropertyWebkitBorderFit:
+    case CSSPropertyWebkitBorderStartStyle:
+    case CSSPropertyWebkitBoxAlign:
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
+    case CSSPropertyWebkitBoxDecorationBreak:
+#endif
+    case CSSPropertyWebkitBoxDirection:
+    case CSSPropertyWebkitBoxLines:
+    case CSSPropertyWebkitBoxOrient:
+    case CSSPropertyWebkitBoxPack:
+    case CSSPropertyWebkitColumnBreakAfter:
+    case CSSPropertyWebkitColumnBreakBefore:
+    case CSSPropertyWebkitColumnBreakInside:
+    case CSSPropertyColumnFill:
+    case CSSPropertyColumnRuleStyle:
+    case CSSPropertyFlexDirection:
+    case CSSPropertyFlexWrap:
+    case CSSPropertyWebkitFontKerning:
+    case CSSPropertyWebkitFontSmoothing:
+    case CSSPropertyWebkitHyphens:
+    case CSSPropertyWebkitLineAlign:
+    case CSSPropertyWebkitLineBreak:
+    case CSSPropertyWebkitLineSnap:
+    case CSSPropertyWebkitMarginAfterCollapse:
+    case CSSPropertyWebkitMarginBeforeCollapse:
+    case CSSPropertyWebkitMarginBottomCollapse:
+    case CSSPropertyWebkitMarginTopCollapse:
+    case CSSPropertyWebkitMarqueeDirection:
+    case CSSPropertyWebkitMarqueeStyle:
+    case CSSPropertyWebkitNbspMode:
+#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
+    case CSSPropertyWebkitOverflowScrolling:
+#endif
+    case CSSPropertyWebkitPrintColorAdjust:
+#if ENABLE(CSS_REGIONS)
+    case CSSPropertyWebkitRegionBreakAfter:
+    case CSSPropertyWebkitRegionBreakBefore:
+    case CSSPropertyWebkitRegionBreakInside:
+    case CSSPropertyWebkitRegionFragment:
+#endif
+    case CSSPropertyWebkitRtlOrdering:
+    case CSSPropertyWebkitRubyPosition:
+#if ENABLE(CSS3_TEXT)
+    case CSSPropertyWebkitTextAlignLast:
+#endif // CSS3_TEXT
+    case CSSPropertyWebkitTextCombine:
+#if ENABLE(CSS3_TEXT)
+    case CSSPropertyWebkitTextJustify:
+#endif // CSS3_TEXT
+    case CSSPropertyWebkitTextSecurity:
+    case CSSPropertyTransformStyle:
+    case CSSPropertyWebkitTransformStyle:
+    case CSSPropertyWebkitUserDrag:
+    case CSSPropertyWebkitUserModify:
+    case CSSPropertyWebkitUserSelect:
+    case CSSPropertyWebkitWritingMode:
+    case CSSPropertyWhiteSpace:
+    case CSSPropertyWordBreak:
+    case CSSPropertyWordWrap:
+#if ENABLE(TOUCH_EVENTS)
+    case CSSPropertyTouchAction:
+#endif
+#if ENABLE(CSS_SCROLL_SNAP)
+    case CSSPropertyWebkitScrollSnapType:
+#endif
+#if ENABLE(CSS_TRAILING_WORD)
+    case CSSPropertyAppleTrailingWord:
+#endif
+    case CSSPropertyFontVariantPosition:
+    case CSSPropertyFontVariantCaps:
+    case CSSPropertyFontVariantAlternates:
+        return true;
+    default:
+        return false;
+    }
+}
+
+static bool isUniversalKeyword(const String&amp; string)
+{
+    // These keywords can be used for all properties.
+    return equalLettersIgnoringASCIICase(string, &quot;initial&quot;)
+        || equalLettersIgnoringASCIICase(string, &quot;inherit&quot;)
+        || equalLettersIgnoringASCIICase(string, &quot;unset&quot;)
+        || equalLettersIgnoringASCIICase(string, &quot;revert&quot;);
+}
+
+static CSSParser::ParseResult parseKeywordValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyId, const String&amp; string, bool important, const CSSParserContext&amp; parserContext, StyleSheetContents* styleSheetContents)
+{
+    ASSERT(!string.isEmpty());
+
+    if (!isKeywordPropertyID(propertyId)) {
+        if (!isUniversalKeyword(string))
+            return CSSParser::ParseResult::Error;
+
+        // Don't try to parse initial/inherit/unset/revert shorthands; return an error so the caller will use the full CSS parser.
+        if (shorthandForProperty(propertyId).length())
+            return CSSParser::ParseResult::Error;
+    }
+
+    CSSParserString cssString;
+    cssString.init(string);
+    CSSValueID valueID = cssValueKeywordID(cssString);
+
+    if (!valueID)
+        return CSSParser::ParseResult::Error;
+
+    RefPtr&lt;CSSValue&gt; value;
+    if (valueID == CSSValueInherit)
+        value = CSSValuePool::singleton().createInheritedValue();
+    else if (valueID == CSSValueInitial)
+        value = CSSValuePool::singleton().createExplicitInitialValue();
+    else if (valueID == CSSValueUnset)
+        value = CSSValuePool::singleton().createUnsetValue();
+    else if (valueID == CSSValueRevert)
+        value = CSSValuePool::singleton().createRevertValue();
+    else if (isValidKeywordPropertyAndValue(propertyId, valueID, parserContext, styleSheetContents))
+        value = CSSValuePool::singleton().createIdentifierValue(valueID);
+    else
+        return CSSParser::ParseResult::Error;
+
+    return declaration.addParsedProperty(CSSProperty(propertyId, value.releaseNonNull(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
+}
+
+template &lt;typename CharacterType&gt;
+static bool parseTransformTranslateArguments(WebKitCSSTransformValue&amp; transformValue, CharacterType* characters, unsigned length, unsigned start, unsigned expectedCount)
+{
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    while (expectedCount) {
+        size_t end = WTF::find(characters, length, expectedCount == 1 ? ')' : ',', start);
+        if (end == notFound || (expectedCount == 1 &amp;&amp; end != length - 1))
+            return false;
+        unsigned argumentLength = end - start;
+        CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
+        double number;
+        if (!parseSimpleLength(characters + start, argumentLength, unit, number))
+            return false;
+        if (unit != CSSPrimitiveValue::CSS_PX &amp;&amp; (number || unit != CSSPrimitiveValue::CSS_NUMBER))
+            return false;
+        transformValue.append(cssValuePool.createValue(number, CSSPrimitiveValue::CSS_PX));
+        start = end + 1;
+        --expectedCount;
+    }
+    return true;
+}
+
+static CSSParser::ParseResult parseTranslateTransformValue(MutableStyleProperties&amp; properties, CSSPropertyID propertyID, const String&amp; string, bool important)
+{
+    if (propertyID != CSSPropertyTransform)
+        return CSSParser::ParseResult::Error;
+
+    static const unsigned shortestValidTransformStringLength = 12;
+    static const unsigned likelyMultipartTransformStringLengthCutoff = 32;
+    if (string.length() &lt; shortestValidTransformStringLength || string.length() &gt; likelyMultipartTransformStringLengthCutoff)
+        return CSSParser::ParseResult::Error;
+
+    if (!string.startsWith(&quot;translate&quot;, false))
+        return CSSParser::ParseResult::Error;
+
+    UChar c9 = toASCIILower(string[9]);
+    UChar c10 = toASCIILower(string[10]);
+
+    WebKitCSSTransformValue::TransformOperationType transformType;
+    unsigned expectedArgumentCount = 1;
+    unsigned argumentStart = 11;
+    if (c9 == 'x' &amp;&amp; c10 == '(')
+        transformType = WebKitCSSTransformValue::TranslateXTransformOperation;
+    else if (c9 == 'y' &amp;&amp; c10 == '(')
+        transformType = WebKitCSSTransformValue::TranslateYTransformOperation;
+    else if (c9 == 'z' &amp;&amp; c10 == '(')
+        transformType = WebKitCSSTransformValue::TranslateZTransformOperation;
+    else if (c9 == '(') {
+        transformType = WebKitCSSTransformValue::TranslateTransformOperation;
+        expectedArgumentCount = 2;
+        argumentStart = 10;
+    } else if (c9 == '3' &amp;&amp; c10 == 'd' &amp;&amp; string[11] == '(') {
+        transformType = WebKitCSSTransformValue::Translate3DTransformOperation;
+        expectedArgumentCount = 3;
+        argumentStart = 12;
+    } else
+        return CSSParser::ParseResult::Error;
+
+    auto transformValue = WebKitCSSTransformValue::create(transformType);
+    bool success;
+    if (string.is8Bit())
+        success = parseTransformTranslateArguments(transformValue, string.characters8(), string.length(), argumentStart, expectedArgumentCount);
+    else
+        success = parseTransformTranslateArguments(transformValue, string.characters16(), string.length(), argumentStart, expectedArgumentCount);
+    if (!success)
+        return CSSParser::ParseResult::Error;
+
+    auto result = CSSValueList::createSpaceSeparated();
+    result-&gt;append(WTFMove(transformValue));
+    return properties.addParsedProperty(CSSProperty(CSSPropertyTransform, WTFMove(result), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
+}
+
+RefPtr&lt;CSSValueList&gt; CSSParser::parseFontFaceValue(const AtomicString&amp; string)
+{
+    if (string.isEmpty())
+        return nullptr;
+
+    auto valueList = CSSValueList::createCommaSeparated();
+
+    Vector&lt;String&gt; familyNames;
+    string.string().split(',', true, familyNames);
+
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    for (auto&amp; familyName : familyNames) {
+        String stripped = stripLeadingAndTrailingHTMLSpaces(familyName);
+        if (stripped.isEmpty())
+            return nullptr;
+
+        RefPtr&lt;CSSValue&gt; value;
+        for (auto propertyID : { CSSValueSerif, CSSValueSansSerif, CSSValueCursive, CSSValueFantasy, CSSValueMonospace, CSSValueWebkitBody }) {
+            if (equalIgnoringASCIICase(stripped, getValueName(propertyID))) {
+                value = cssValuePool.createIdentifierValue(propertyID);
+                break;
+            }
+        }
+        if (!value)
+            value = cssValuePool.createFontFamilyValue(stripped);
+        valueList-&gt;append(value.releaseNonNull());
+    }
+
+    return WTFMove(valueList);
+}
+
+CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyID, const String&amp; string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
+{
+    ASSERT(!string.isEmpty());
+    CSSParser::ParseResult result = parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode);
+    if (result != ParseResult::Error)
+        return result;
+
+    result = parseColorValue(declaration, propertyID, string, important, cssParserMode);
+    if (result != ParseResult::Error)
+        return result;
+
+    CSSParserContext context(cssParserMode);
+    if (contextStyleSheet) {
+        context = contextStyleSheet-&gt;parserContext();
+        context.mode = cssParserMode;
+    }
+
+    result = parseKeywordValue(declaration, propertyID, string, important, context, contextStyleSheet);
+    if (result != ParseResult::Error)
+        return result;
+
+    result = parseTranslateTransformValue(declaration, propertyID, string, important);
+    if (result != ParseResult::Error)
+        return result;
+
+    CSSParser parser(context);
+    return parser.parseValue(declaration, propertyID, string, important, contextStyleSheet);
+}
+
+CSSParser::ParseResult CSSParser::parseCustomPropertyValue(MutableStyleProperties&amp; declaration, const AtomicString&amp; propertyName, const String&amp; string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
+{
+    CSSParserContext context(cssParserMode);
+    if (contextStyleSheet) {
+        context = contextStyleSheet-&gt;parserContext();
+        context.mode = cssParserMode;
+    }
+
+    CSSParser parser(context);
+    parser.setCustomPropertyName(propertyName);
+    return parser.parseValue(declaration, CSSPropertyCustom, string, important, contextStyleSheet);
+}
+
+CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties&amp; declaration, CSSPropertyID propertyID, const String&amp; string, bool important, StyleSheetContents* contextStyleSheet)
+{
+    setStyleSheet(contextStyleSheet);
+
+    setupParser(&quot;@-webkit-value{&quot;, string, &quot;} &quot;);
+
+    m_id = propertyID;
+    m_important = important;
+
+    cssyyparse(this);
+
+    m_rule = nullptr;
+
+    ParseResult result = ParseResult::Error;
+
+    if (!m_parsedProperties.isEmpty()) {
+        result = declaration.addParsedProperties(m_parsedProperties) ? ParseResult::Changed : ParseResult::Unchanged;
+        clearProperties();
+    }
+
+    return result;
+}
+
+// The color will only be changed when string contains a valid CSS color, so callers
+// can set it to a default color and ignore the boolean result.
+bool CSSParser::parseColor(RGBA32&amp; color, const String&amp; string, bool strict)
+{
+    if (string.isEmpty())
+        return false;
+
+    // First try creating a color specified by name, rgba(), rgb() or &quot;#&quot; syntax.
+    if (fastParseColor(color, string, strict))
+        return true;
+
+    CSSParser parser(CSSStrictMode);
+
+    // In case the fast-path parser didn't understand the color, try the full parser.
+    if (!parser.parseColor(string))
+        return false;
+
+    CSSValue&amp; value = *parser.m_parsedProperties.first().value();
+    if (!is&lt;CSSPrimitiveValue&gt;(value))
+        return false;
+
+    CSSPrimitiveValue&amp; primitiveValue = downcast&lt;CSSPrimitiveValue&gt;(value);
+    if (!primitiveValue.isRGBColor())
+        return false;
+
+    color = primitiveValue.getRGBA32Value();
+    return true;
+}
+
+bool CSSParser::parseColor(const String&amp; string)
+{
+    setupParser(&quot;@-webkit-decls{color:&quot;, string, &quot;} &quot;);
+    cssyyparse(this);
+    m_rule = nullptr;
+
+    return !m_parsedProperties.isEmpty() &amp;&amp; m_parsedProperties.first().id() == CSSPropertyColor;
+}
+
+bool CSSParser::parseSystemColor(RGBA32&amp; color, const String&amp; string, Document* document)
+{
+    if (!document || !document-&gt;page())
+        return false;
+
+    CSSParserString cssColor;
+    cssColor.init(string);
+    CSSValueID id = cssValueKeywordID(cssColor);
+    if (!validPrimitiveValueColor(id))
+        return false;
+
+    Color parsedColor = document-&gt;page()-&gt;theme().systemColor(id);
+    if (!parsedColor.isValid())
+        return false;
+
+    color = parsedColor.rgb();
+    return true;
+}
+
+void CSSParser::parseSelector(const String&amp; string, CSSSelectorList&amp; selectorList)
+{
+    m_selectorListForParseSelector = &amp;selectorList;
+
+    setupParser(&quot;@-webkit-selector{&quot;, string, &quot;}&quot;);
+
+    cssyyparse(this);
+
+    m_selectorListForParseSelector = nullptr;
+}
+
+Ref&lt;ImmutableStyleProperties&gt; CSSParser::parseInlineStyleDeclaration(const String&amp; string, Element* element)
+{
+    CSSParserContext context = element-&gt;document().elementSheet().contents().parserContext();
+    context.mode = strictToCSSParserMode(element-&gt;isHTMLElement() &amp;&amp; !element-&gt;document().inQuirksMode());
+    return CSSParser(context).parseDeclaration(string, &amp;element-&gt;document().elementSheet().contents());
+}
+
+Ref&lt;ImmutableStyleProperties&gt; CSSParser::parseDeclaration(const String&amp; string, StyleSheetContents* contextStyleSheet)
+{
+    setStyleSheet(contextStyleSheet);
+
+    setupParser(&quot;@-webkit-decls{&quot;, string, &quot;} &quot;);
+    cssyyparse(this);
+    m_rule = nullptr;
+
+    Ref&lt;ImmutableStyleProperties&gt; style = createStyleProperties();
+    clearProperties();
+    return style;
+}
+
+
+bool CSSParser::parseDeclaration(MutableStyleProperties&amp; declaration, const String&amp; string, RefPtr&lt;CSSRuleSourceData&gt;&amp;&amp; ruleSourceData, StyleSheetContents* contextStyleSheet)
+{
+    // Length of the &quot;@-webkit-decls{&quot; prefix.
+    static const unsigned prefixLength = 15;
+
+    setStyleSheet(contextStyleSheet);
+
+    if (ruleSourceData) {
+        m_currentRuleDataStack = std::make_unique&lt;RuleSourceDataList&gt;();
+        m_currentRuleDataStack-&gt;append(*ruleSourceData);
+    }
+
+    setupParser(&quot;@-webkit-decls{&quot;, string, &quot;} &quot;);
+    cssyyparse(this);
+    m_rule = nullptr;
+
+    bool ok = false;
+    if (!m_parsedProperties.isEmpty()) {
+        ok = true;
+        declaration.addParsedProperties(m_parsedProperties);
+        clearProperties();
+    }
+
+    if (ruleSourceData) {
+        ASSERT(m_currentRuleDataStack-&gt;size() == 1);
+        ruleSourceData-&gt;ruleBodyRange.start = 0;
+        ruleSourceData-&gt;ruleBodyRange.end = string.length();
+        for (size_t i = 0, size = ruleSourceData-&gt;styleSourceData-&gt;propertyData.size(); i &lt; size; ++i) {
+            CSSPropertySourceData&amp; propertyData = ruleSourceData-&gt;styleSourceData-&gt;propertyData.at(i);
+            propertyData.range.start -= prefixLength;
+            propertyData.range.end -= prefixLength;
+        }
+
+        fixUnparsedPropertyRanges(*ruleSourceData);
+        m_currentRuleDataStack.reset();
+    }
+
+    return ok;
+}
+
+std::unique_ptr&lt;MediaQuery&gt; CSSParser::parseMediaQuery(const String&amp; string)
+{
+    if (string.isEmpty())
+        return nullptr;
+
+    ASSERT(!m_mediaQuery);
+
+    // can't use { because tokenizer state switches from mediaquery to initial state when it sees { token.
+    // instead insert one &quot; &quot; (which is WHITESPACE in CSSGrammar.y)
+    setupParser(&quot;@-webkit-mediaquery &quot;, string, &quot;} &quot;);
+    cssyyparse(this);
+
+    return WTFMove(m_mediaQuery);
+}
+
+Vector&lt;CSSParser::SourceSize&gt; CSSParser::parseSizesAttribute(StringView string)
+{
+    Vector&lt;SourceSize&gt; result;
+
+    if (string.isEmpty())
+        return result;
+
+    ASSERT(!m_sourceSizeList);
+
+    setupParser(&quot;@-webkit-sizesattr &quot;, string, &quot;}&quot;);
+    cssyyparse(this);
+
+    if (!m_sourceSizeList)
+        return result;
+
+    result = WTFMove(*m_sourceSizeList);
+    m_sourceSizeList = nullptr;
+    return result;
+}
+
+// FIXME(141289): The following two constructors are only needed because of a bug in MSVC 2013 (and prior).
+// We should remove this code as soon as a Visual Studio update that fixes this problem is released.
+
+CSSParser::SourceSize::SourceSize(CSSParser::SourceSize&amp;&amp; original)
+    : expression(WTFMove(original.expression))
+    , length(WTFMove(original.length))
+{
+}
+
+CSSParser::SourceSize::SourceSize(MediaQueryExpression&amp;&amp; expression, Ref&lt;CSSValue&gt;&amp;&amp; value)
+    : expression(WTFMove(expression))
+    , length(WTFMove(value))
+{
+}
+
+Optional&lt;CSSParser::SourceSize&gt; CSSParser::sourceSize(MediaQueryExpression&amp;&amp; expression, CSSParserValue&amp; parserValue)
+{
+    RefPtr&lt;CSSValue&gt; value;
+    if (isCalculation(parserValue)) {
+        auto* args = parserValue.function-&gt;args.get();
+        if (args &amp;&amp; args-&gt;size())
+            value = CSSCalcValue::create(parserValue.function-&gt;name, *args, CalculationRangeNonNegative);
+    }
+    if (!value)
+        value = parserValue.createCSSValue();
+    destroy(parserValue);
+    if (!value)
+        return Nullopt;
+    // FIXME: Calling the constructor explicitly here to work around an MSVC bug.
+    // For other compilers, we did not need to define the constructors and we could use aggregate initialization syntax.
+    return SourceSize(WTFMove(expression), value.releaseNonNull());
+}
+
+static inline void filterProperties(bool important, const ParsedPropertyVector&amp; input, Vector&lt;CSSProperty, 256&gt;&amp; output, size_t&amp; unusedEntries, std::bitset&lt;numCSSProperties&gt;&amp; seenProperties, HashSet&lt;AtomicString&gt;&amp; seenCustomProperties)
+{
+    // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
+    for (int i = input.size() - 1; i &gt;= 0; --i) {
+        const CSSProperty&amp; property = input[i];
+        if (property.isImportant() != important)
+            continue;
+        
+        if (property.id() == CSSPropertyCustom) {
+            if (property.value()) {
+                auto&amp; name = downcast&lt;CSSCustomPropertyValue&gt;(*property.value()).name();
+                if (!seenCustomProperties.add(name).isNewEntry)
+                    continue;
+                output[--unusedEntries] = property;
+            }
+            continue;
+        }
+
+        const unsigned propertyIDIndex = property.id() - firstCSSProperty;
+        ASSERT(propertyIDIndex &lt; seenProperties.size());
+        if (seenProperties[propertyIDIndex])
+            continue;
+        seenProperties.set(propertyIDIndex);
+        output[--unusedEntries] = property;
+    }
+}
+
+Ref&lt;ImmutableStyleProperties&gt; CSSParser::createStyleProperties()
+{
+    std::bitset&lt;numCSSProperties&gt; seenProperties;
+    size_t unusedEntries = m_parsedProperties.size();
+    Vector&lt;CSSProperty, 256&gt; results(unusedEntries);
+
+    // Important properties have higher priority, so add them first. Duplicate definitions can then be ignored when found.
+    HashSet&lt;AtomicString&gt; seenCustomProperties;
+    filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
+    filterProperties(false, m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
+    if (unusedEntries)
+        results.remove(0, unusedEntries);
+
+    return ImmutableStyleProperties::create(results.data(), results.size(), m_context.mode);
+}
+
+void CSSParser::addProperty(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp;&amp; value, bool important, bool implicit)
+{
+    // This property doesn't belong to a shorthand or is a CSS variable (which will be resolved later).
+    if (!m_currentShorthand) {
+        m_parsedProperties.append(CSSProperty(propId, WTFMove(value), important, false, CSSPropertyInvalid, m_implicitShorthand || implicit));
+        return;
+    }
+
+    auto shorthands = matchingShorthandsForLonghand(propId);
+    if (shorthands.size() == 1)
+        m_parsedProperties.append(CSSProperty(propId, WTFMove(value), important, true, CSSPropertyInvalid, m_implicitShorthand || implicit));
+    else
+        m_parsedProperties.append(CSSProperty(propId, WTFMove(value), important, true, indexOfShorthandForLonghand(m_currentShorthand, shorthands), m_implicitShorthand || implicit));
+}
+
+void CSSParser::rollbackLastProperties(int num)
+{
+    ASSERT(num &gt;= 0);
+    ASSERT(m_parsedProperties.size() &gt;= static_cast&lt;unsigned&gt;(num));
+    m_parsedProperties.shrink(m_parsedProperties.size() - num);
+}
+
+void CSSParser::clearProperties()
+{
+    m_parsedProperties.clear();
+    m_numParsedPropertiesBeforeMarginBox = invalidParsedPropertiesCount;
+}
+
+URL CSSParser::completeURL(const CSSParserContext&amp; context, const String&amp; url)
+{
+    if (url.isNull())
+        return URL();
+    if (context.charset.isEmpty())
+        return URL(context.baseURL, url);
+    return URL(context.baseURL, url, context.charset);
+}
+
+URL CSSParser::completeURL(const String&amp; url) const
+{
+    return completeURL(m_context, url);
+}
+
+bool CSSParser::validateCalculationUnit(ValueWithCalculation&amp; valueWithCalculation, Units unitFlags)
+{
+    bool mustBeNonNegative = unitFlags &amp; FNonNeg;
+
+    RefPtr&lt;CSSCalcValue&gt; calculation;
+    if (valueWithCalculation.calculation()) {
+        // The calculation value was already parsed so we reuse it. However, we may need to update its range.
+        calculation = valueWithCalculation.calculation();
+        calculation-&gt;setPermittedValueRange(mustBeNonNegative ? CalculationRangeNonNegative : CalculationRangeAll);
+    } else {
+        valueWithCalculation.setCalculation(parseCalculation(valueWithCalculation, mustBeNonNegative ? CalculationRangeNonNegative : CalculationRangeAll));
+        calculation = valueWithCalculation.calculation();
+        if (!calculation)
+            return false;
+    }
+
+    bool isValid = false;
+    switch (calculation-&gt;category()) {
+    case CalcNumber:
+        isValid = (unitFlags &amp; FNumber);
+        if (!isValid &amp;&amp; (unitFlags &amp; FInteger) &amp;&amp; calculation-&gt;isInt())
+            isValid = true;
+        if (!isValid &amp;&amp; (unitFlags &amp; FPositiveInteger) &amp;&amp; calculation-&gt;isInt() &amp;&amp; calculation-&gt;isPositive())
+            isValid = true;
+        break;
+    case CalcLength:
+        isValid = (unitFlags &amp; FLength);
+        break;
+    case CalcPercent:
+        isValid = (unitFlags &amp; FPercent);
+        break;
+    case CalcPercentLength:
+        isValid = (unitFlags &amp; FPercent) &amp;&amp; (unitFlags &amp; FLength);
+        break;
+    case CalcPercentNumber:
+        isValid = (unitFlags &amp; FPercent) &amp;&amp; (unitFlags &amp; FNumber);
+        break;
+    case CalcAngle:
+        isValid = (unitFlags &amp; FAngle);
+        break;
+    case CalcTime:
+        isValid = (unitFlags &amp; FTime);
+        break;
+    case CalcFrequency:
+        isValid = (unitFlags &amp; FFrequency);
+        break;
+    case CalcOther:
+        break;
+    }
+
+    return isValid;
+}
+
+inline bool CSSParser::shouldAcceptUnitLessValues(CSSParserValue&amp; value, Units unitFlags, CSSParserMode cssParserMode)
+{
+    // Qirks mode and svg presentation attributes accept unit less values.
+    return (unitFlags &amp; (FLength | FAngle | FTime)) &amp;&amp; (!value.fValue || cssParserMode == CSSQuirksMode || cssParserMode == SVGAttributeMode);
+}
+
+bool CSSParser::validateUnit(ValueWithCalculation&amp; valueWithCalculation, Units unitFlags, CSSParserMode cssParserMode)
+{
+    if (isCalculation(valueWithCalculation))
+        return validateCalculationUnit(valueWithCalculation, unitFlags);
+        
+    bool b = false;
+    switch (valueWithCalculation.value().unit) {
+    case CSSPrimitiveValue::CSS_NUMBER:
+        b = (unitFlags &amp; FNumber);
+        if (!b &amp;&amp; shouldAcceptUnitLessValues(valueWithCalculation, unitFlags, cssParserMode)) {
+            valueWithCalculation.value().unit = (unitFlags &amp; FLength) ? CSSPrimitiveValue::CSS_PX :
+                          ((unitFlags &amp; FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS);
+            b = true;
+        }
+        if (!b &amp;&amp; (unitFlags &amp; FInteger) &amp;&amp; valueWithCalculation.value().isInt)
+            b = true;
+        if (!b &amp;&amp; (unitFlags &amp; FPositiveInteger) &amp;&amp; valueWithCalculation.value().isInt &amp;&amp; valueWithCalculation.value().fValue &gt; 0)
+            b = true;
+        break;
+    case CSSPrimitiveValue::CSS_PERCENTAGE:
+        b = (unitFlags &amp; FPercent);
+        break;
+    case CSSParserValue::Q_EMS:
+    case CSSPrimitiveValue::CSS_EMS:
+    case CSSPrimitiveValue::CSS_REMS:
+    case CSSPrimitiveValue::CSS_CHS:
+    case CSSPrimitiveValue::CSS_EXS:
+    case CSSPrimitiveValue::CSS_PX:
+    case CSSPrimitiveValue::CSS_CM:
+    case CSSPrimitiveValue::CSS_MM:
+    case CSSPrimitiveValue::CSS_IN:
+    case CSSPrimitiveValue::CSS_PT:
+    case CSSPrimitiveValue::CSS_PC:
+    case CSSPrimitiveValue::CSS_VW:
+    case CSSPrimitiveValue::CSS_VH:
+    case CSSPrimitiveValue::CSS_VMIN:
+    case CSSPrimitiveValue::CSS_VMAX:
+        b = (unitFlags &amp; FLength);
+        break;
+    case CSSPrimitiveValue::CSS_MS:
+    case CSSPrimitiveValue::CSS_S:
+        b = (unitFlags &amp; FTime);
+        break;
+    case CSSPrimitiveValue::CSS_DEG:
+    case CSSPrimitiveValue::CSS_RAD:
+    case CSSPrimitiveValue::CSS_GRAD:
+    case CSSPrimitiveValue::CSS_TURN:
+        b = (unitFlags &amp; FAngle);
+        break;
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
+    case CSSPrimitiveValue::CSS_DPPX:
+    case CSSPrimitiveValue::CSS_DPI:
+    case CSSPrimitiveValue::CSS_DPCM:
+        b = (unitFlags &amp; FResolution);
+        break;
+#endif
+    case CSSPrimitiveValue::CSS_HZ:
+    case CSSPrimitiveValue::CSS_KHZ:
+    case CSSPrimitiveValue::CSS_DIMENSION:
+    default:
+        break;
+    }
+    if (b &amp;&amp; unitFlags &amp; FNonNeg &amp;&amp; valueWithCalculation.value().fValue &lt; 0)
+        b = false;
+    if (b &amp;&amp; std::isinf(valueWithCalculation.value().fValue))
+        b = false;
+    return b;
+}
+
+inline Ref&lt;CSSPrimitiveValue&gt; CSSParser::createPrimitiveNumericValue(ValueWithCalculation&amp; valueWithCalculation)
+{
+    if (valueWithCalculation.calculation())
+        return CSSPrimitiveValue::create(valueWithCalculation.calculation());
+
+    CSSParserValue&amp; value = valueWithCalculation;
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
+    ASSERT((value.unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_KHZ)
+        || (value.unit &gt;= CSSPrimitiveValue::CSS_TURN &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_CHS)
+        || (value.unit &gt;= CSSPrimitiveValue::CSS_VW &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_VMAX)
+        || (value.unit &gt;= CSSPrimitiveValue::CSS_DPPX &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_DPCM));
+#else
+    ASSERT((value.unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_KHZ)
+        || (value.unit &gt;= CSSPrimitiveValue::CSS_TURN &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_CHS)
+        || (value.unit &gt;= CSSPrimitiveValue::CSS_VW &amp;&amp; value.unit &lt;= CSSPrimitiveValue::CSS_VMAX));
+#endif
+    return CSSValuePool::singleton().createValue(value.fValue, static_cast&lt;CSSPrimitiveValue::UnitTypes&gt;(value.unit));
+}
+
+inline Ref&lt;CSSPrimitiveValue&gt; CSSParser::createPrimitiveStringValue(CSSParserValue&amp; value)
+{
+    ASSERT(value.unit == CSSPrimitiveValue::CSS_STRING || value.unit == CSSPrimitiveValue::CSS_IDENT);
+    return CSSValuePool::singleton().createValue(value.string, CSSPrimitiveValue::CSS_STRING);
+}
+
+static inline bool isComma(CSSParserValue* value)
+{ 
+    return value &amp;&amp; value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ','; 
+}
+
+static inline bool isForwardSlashOperator(CSSParserValue&amp; value)
+{
+    return value.unit == CSSParserValue::Operator &amp;&amp; value.iValue == '/';
+}
+
+bool CSSParser::isValidSize(ValueWithCalculation&amp; valueWithCalculation)
+{
+    int id = valueWithCalculation.value().id;
+    if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic || id == CSSValueWebkitMinContent || id == CSSValueWebkitMaxContent || id == CSSValueWebkitFillAvailable || id == CSSValueWebkitFitContent)
+        return true;
+    return !id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
+}
+
+inline RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseValidPrimitive(CSSValueID identifier, ValueWithCalculation&amp; valueWithCalculation)
+{
+    if (identifier)
+        return CSSValuePool::singleton().createIdentifierValue(identifier);
+
+    if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING)
+        return createPrimitiveStringValue(valueWithCalculation);
+    if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_KHZ)
+        return createPrimitiveNumericValue(valueWithCalculation);
+    if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_TURN &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_CHS)
+        return createPrimitiveNumericValue(valueWithCalculation);
+    if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_VW &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_VMAX)
+        return createPrimitiveNumericValue(valueWithCalculation);
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
+    if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_DPPX &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_DPCM)
+        return createPrimitiveNumericValue(valueWithCalculation);
+#endif
+    if (valueWithCalculation.value().unit &gt;= CSSParserValue::Q_EMS)
+        return CSSPrimitiveValue::createAllowingMarginQuirk(valueWithCalculation.value().fValue, CSSPrimitiveValue::CSS_EMS);
+    if (valueWithCalculation.calculation())
+        return CSSPrimitiveValue::create(valueWithCalculation.calculation());
+
+    return nullptr;
+}
+
+void CSSParser::addExpandedPropertyForValue(CSSPropertyID propId, Ref&lt;CSSValue&gt;&amp;&amp; value, bool important)
+{
+    const StylePropertyShorthand&amp; shorthand = shorthandForProperty(propId);
+    unsigned shorthandLength = shorthand.length();
+    if (!shorthandLength) {
+        addProperty(propId, WTFMove(value), important);
+        return;
+    }
+
+    ShorthandScope scope(this, propId);
+    const CSSPropertyID* longhands = shorthand.properties();
+    for (unsigned i = 0; i &lt; shorthandLength; ++i)
+        addProperty(longhands[i], value.copyRef(), important);
+}
+
+RefPtr&lt;CSSValue&gt; CSSParser::parseVariableDependentValue(CSSPropertyID propID, const CSSVariableDependentValue&amp; dependentValue, const CustomPropertyValueMap&amp; customProperties, TextDirection direction, WritingMode writingMode)
+{
+    m_valueList.reset(new CSSParserValueList());
+    if (!dependentValue.valueList().buildParserValueListSubstitutingVariables(m_valueList.get(), customProperties))
+        return nullptr;
+
+    CSSPropertyID dependentValuePropertyID = dependentValue.propertyID();
+    if (CSSProperty::isDirectionAwareProperty(dependentValuePropertyID))
+        dependentValuePropertyID = CSSProperty::resolveDirectionAwareProperty(dependentValuePropertyID, direction, writingMode);
+
+    if (!parseValue(dependentValuePropertyID, false))
+        return nullptr;
+
+    for (auto&amp; property : m_parsedProperties) {
+        if (property.id() == propID)
+            return property.value();
+    }
+    return nullptr;
+}
+
+static bool isImageSetFunctionValue(const CSSParserValue&amp; value)
+{
+    return value.unit == CSSParserValue::Function &amp;&amp; (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;image-set(&quot;) || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-image-set(&quot;));
+}
+
+bool CSSParser::parseValue(CSSPropertyID propId, bool important)
+{
+    if (!m_valueList || !m_valueList-&gt;current())
+        return false;
+    
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+    CSSValueID id = valueWithCalculation.value().id;
+    
+    if (propId == CSSPropertyCustom)
+        return parseCustomPropertyDeclaration(important, id);
+
+    if (m_valueList-&gt;containsVariables()) {
+        auto valueList = CSSValueList::createFromParserValueList(*m_valueList);
+        addExpandedPropertyForValue(propId, CSSVariableDependentValue::create(WTFMove(valueList), propId), important);
+        return true;
+    }
+
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    unsigned num = inShorthand() ? 1 : m_valueList-&gt;size();
+
+    if (id == CSSValueInherit) {
+        if (num != 1)
+            return false;
+        addExpandedPropertyForValue(propId, cssValuePool.createInheritedValue(), important);
+        return true;
+    }
+    else if (id == CSSValueInitial) {
+        if (num != 1)
+            return false;
+        addExpandedPropertyForValue(propId, cssValuePool.createExplicitInitialValue(), important);
+        return true;
+    } else if (id == CSSValueUnset) {
+        if (num != 1)
+            return false;
+        addExpandedPropertyForValue(propId, cssValuePool.createUnsetValue(), important);
+        return true;
+    } else if (id == CSSValueRevert) {
+        if (num != 1)
+            return false;
+        addExpandedPropertyForValue(propId, cssValuePool.createRevertValue(), important);
+        return true;
+    }
+    
+    if (propId == CSSPropertyAll)
+        return false; // &quot;all&quot; doesn't allow you to specify anything other than inherit/initial/unset.
+
+    if (isKeywordPropertyID(propId)) {
+        if (!isValidKeywordPropertyAndValue(propId, id, m_context, m_styleSheet))
+            return false;
+        if (m_valueList-&gt;next() &amp;&amp; !inShorthand())
+            return false;
+        addProperty(propId, cssValuePool.createIdentifierValue(id), important);
+        return true;
+    }
+
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    if (inViewport())
+        return parseViewportProperty(propId, important);
+#endif
+
+    bool validPrimitive = false;
+    RefPtr&lt;CSSValue&gt; parsedValue;
+
+    switch (propId) {
+    case CSSPropertySize:                 // &lt;length&gt;{1,2} | auto | [ &lt;page-size&gt; || [ portrait | landscape] ]
+        return parseSize(propId, important);
+
+    case CSSPropertyQuotes:               // [&lt;string&gt; &lt;string&gt;]+ | none | inherit
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else
+            return parseQuotes(propId, important);
+        break;
+    case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | isolate | isolate-override | plaintext | inherit
+        if (id == CSSValueNormal
+            || id == CSSValueEmbed
+            || id == CSSValueBidiOverride
+            || id == CSSValueWebkitIsolate
+            || id == CSSValueWebkitIsolateOverride
+            || id == CSSValueWebkitPlaintext)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyContent:              // [ &lt;string&gt; | &lt;uri&gt; | &lt;counter&gt; | attr(X) | open-quote |
+        // close-quote | no-open-quote | no-close-quote ]+ | inherit
+        return parseContent(propId, important);
+
+    case CSSPropertyAlt: // [ &lt;string&gt; | attr(X) ]
+        return parseAlt(propId, important);
+            
+    case CSSPropertyClip:                 // &lt;shape&gt; | auto | inherit
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else if (valueWithCalculation.value().unit == CSSParserValue::Function)
+            return parseClipShape(propId, important);
+        break;
+
+    /* Start of supported CSS properties with validation. This is needed for parseShorthand to work
+     * correctly and allows optimization in WebCore::applyRule(..)
+     */
+    case CSSPropertyOverflow: {
+        ShorthandScope scope(this, propId);
+        if (num != 1 || !parseValue(CSSPropertyOverflowY, important))
+            return false;
+
+        RefPtr&lt;CSSValue&gt; overflowXValue;
+
+        // FIXME: -webkit-paged-x or -webkit-paged-y only apply to overflow-y. If this value has been
+        // set using the shorthand, then for now overflow-x will default to auto, but once we implement
+        // pagination controls, it should default to hidden. If the overflow-y value is anything but
+        // paged-x or paged-y, then overflow-x and overflow-y should have the same value.
+        if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY)
+            overflowXValue = cssValuePool.createIdentifierValue(CSSValueAuto);
+        else
+            overflowXValue = m_parsedProperties.last().value();
+        addProperty(CSSPropertyOverflowX, WTFMove(overflowXValue), important);
+        return true;
+    }
+
+    case CSSPropertyTextAlign:
+        // left | right | center | justify | -webkit-left | -webkit-right | -webkit-center | -webkit-match-parent
+        // | start | end | inherit | -webkit-auto (converted to start)
+        // NOTE: &lt;string&gt; is not supported.
+        if ((id &gt;= CSSValueWebkitAuto &amp;&amp; id &lt;= CSSValueWebkitMatchParent) || id == CSSValueStart || id == CSSValueEnd)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyFontWeight:  { // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit
+        if (m_valueList-&gt;size() != 1)
+            return false;
+        return parseFontWeight(important);
+    }
+
+    case CSSPropertyFontSynthesis: // none | [ weight || style ]
+        return parseFontSynthesis(important);
+
+    case CSSPropertyBorderSpacing: {
+        if (num == 1) {
+            ShorthandScope scope(this, CSSPropertyBorderSpacing);
+            if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important))
+                return false;
+            CSSValue* value = m_parsedProperties.last().value();
+            addProperty(CSSPropertyWebkitBorderVerticalSpacing, value, important);
+            return true;
+        }
+        else if (num == 2) {
+            ShorthandScope scope(this, CSSPropertyBorderSpacing);
+            if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important) || !parseValue(CSSPropertyWebkitBorderVerticalSpacing, important))
+                return false;
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyWebkitBorderHorizontalSpacing:
+    case CSSPropertyWebkitBorderVerticalSpacing:
+        validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg);
+        break;
+    case CSSPropertyOutlineColor:        // &lt;color&gt; | invert | inherit
+        // Outline color has &quot;invert&quot; as additional keyword.
+        // Also, we want to allow the special focus color even in strict parsing mode.
+        if (id == CSSValueInvert || id == CSSValueWebkitFocusRingColor) {
+            validPrimitive = true;
+            break;
+        }
+        FALLTHROUGH;
+    case CSSPropertyBackgroundColor: // &lt;color&gt; | inherit
+    case CSSPropertyBorderTopColor: // &lt;color&gt; | inherit
+    case CSSPropertyBorderRightColor:
+    case CSSPropertyBorderBottomColor:
+    case CSSPropertyBorderLeftColor:
+    case CSSPropertyWebkitBorderStartColor:
+    case CSSPropertyWebkitBorderEndColor:
+    case CSSPropertyWebkitBorderBeforeColor:
+    case CSSPropertyWebkitBorderAfterColor:
+    case CSSPropertyColor: // &lt;color&gt; | inherit
+    case CSSPropertyTextLineThroughColor: // CSS3 text decoration colors
+    case CSSPropertyTextUnderlineColor:
+    case CSSPropertyTextOverlineColor:
+    case CSSPropertyColumnRuleColor:
+    case CSSPropertyWebkitTextDecorationColor:
+    case CSSPropertyWebkitTextEmphasisColor:
+    case CSSPropertyWebkitTextFillColor:
+    case CSSPropertyWebkitTextStrokeColor:
+        if (id == CSSValueWebkitText)
+            validPrimitive = true; // Always allow this, even when strict parsing is on,
+                                    // since we use this in our UA sheets.
+        else if (id == CSSValueCurrentcolor)
+            validPrimitive = true;
+        else if (isValidSystemColorValue(id) || id == CSSValueMenu
+            || (id &gt;= CSSValueWebkitFocusRingColor &amp;&amp; id &lt; CSSValueWebkitText &amp;&amp; inQuirksMode())) {
+            validPrimitive = true;
+        } else {
+            parsedValue = parseColor();
+            if (parsedValue)
+                m_valueList-&gt;next();
+        }
+        break;
+
+    case CSSPropertyCursor: {
+        // Grammar defined by CSS3 UI and modified by CSS4 images:
+        // [ [&lt;image&gt; [&lt;x&gt; &lt;y&gt;]?,]*
+        // [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize |
+        // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | ew-resize |
+        // ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | text | wait | help |
+        // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed |
+        // zoom-in | zoom-out | all-scroll | -webkit-grab | -webkit-grabbing | -webkit-zoom-in |
+        // -webkit-zoom-out ] ] | inherit
+        RefPtr&lt;CSSValueList&gt; list;
+        CSSParserValue* value = &amp;valueWithCalculation.value();
+        while (value) {
+            RefPtr&lt;CSSValue&gt; image;
+            if (value-&gt;unit == CSSPrimitiveValue::CSS_URI) {
+                String uri = value-&gt;string;
+                if (!uri.isNull())
+                    image = CSSImageValue::create(completeURL(uri));
+#if ENABLE(MOUSE_CURSOR_SCALE)
+            } else if (isImageSetFunctionValue(*value)) {
+                image = parseImageSet();
+                if (!image)
+                    break;
+#endif
+            } else
+                break;
+
+            Vector&lt;int&gt; coords;
+            value = m_valueList-&gt;next();
+            while (value &amp;&amp; value-&gt;unit == CSSPrimitiveValue::CSS_NUMBER) {
+                coords.append(int(value-&gt;fValue));
+                value = m_valueList-&gt;next();
+            }
+            bool hasHotSpot = false;
+            IntPoint hotSpot(-1, -1);
+            int nrcoords = coords.size();
+            if (nrcoords &gt; 0 &amp;&amp; nrcoords != 2)
+                return false;
+            if (nrcoords == 2) {
+                hasHotSpot = true;
+                hotSpot = IntPoint(coords[0], coords[1]);
+            }
+
+            if (!list)
+                list = CSSValueList::createCommaSeparated();
+
+            if (image)
+                list-&gt;append(CSSCursorImageValue::create(image.releaseNonNull(), hasHotSpot, hotSpot));
+
+            if ((inStrictMode() &amp;&amp; !value) || (value &amp;&amp; !(value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')))
+                return false;
+            value = m_valueList-&gt;next(); // comma
+        }
+        if (list) {
+            if (!value) {
+                // no value after url list (MSIE 5 compatibility)
+                if (list-&gt;length() != 1)
+                    return false;
+            } else if (inQuirksMode() &amp;&amp; value-&gt;id == CSSValueHand) // MSIE 5 compatibility :/
+                list-&gt;append(cssValuePool.createIdentifierValue(CSSValuePointer));
+            else if ((value-&gt;id &gt;= CSSValueAuto &amp;&amp; value-&gt;id &lt;= CSSValueWebkitZoomOut) || value-&gt;id == CSSValueCopy || value-&gt;id == CSSValueNone)
+                list-&gt;append(cssValuePool.createIdentifierValue(value-&gt;id));
+            m_valueList-&gt;next();
+            parsedValue = WTFMove(list);
+            break;
+        } else if (value) {
+            id = value-&gt;id;
+            if (inQuirksMode() &amp;&amp; value-&gt;id == CSSValueHand) {
+                // MSIE 5 compatibility :/
+                id = CSSValuePointer;
+                validPrimitive = true;
+            } else if ((value-&gt;id &gt;= CSSValueAuto &amp;&amp; value-&gt;id &lt;= CSSValueWebkitZoomOut) || value-&gt;id == CSSValueCopy || value-&gt;id == CSSValueNone)
+                validPrimitive = true;
+        } else {
+            ASSERT_NOT_REACHED();
+            return false;
+        }
+        break;
+    }
+
+#if ENABLE(CURSOR_VISIBILITY)
+    case CSSPropertyWebkitCursorVisibility:
+        if (id == CSSValueAuto || id == CSSValueAutoHide)
+            validPrimitive = true;
+        break;
+#endif
+
+    case CSSPropertyBackgroundAttachment:
+    case CSSPropertyBackgroundBlendMode:
+    case CSSPropertyBackgroundClip:
+    case CSSPropertyWebkitBackgroundClip:
+    case CSSPropertyWebkitBackgroundComposite:
+    case CSSPropertyBackgroundImage:
+    case CSSPropertyBackgroundOrigin:
+    case CSSPropertyWebkitBackgroundOrigin:
+    case CSSPropertyBackgroundPosition:
+    case CSSPropertyBackgroundPositionX:
+    case CSSPropertyBackgroundPositionY:
+    case CSSPropertyBackgroundSize:
+    case CSSPropertyWebkitBackgroundSize:
+    case CSSPropertyBackgroundRepeat:
+    case CSSPropertyBackgroundRepeatX:
+    case CSSPropertyBackgroundRepeatY:
+    case CSSPropertyWebkitMaskClip:
+    case CSSPropertyWebkitMaskComposite:
+    case CSSPropertyWebkitMaskImage:
+    case CSSPropertyWebkitMaskOrigin:
+    case CSSPropertyWebkitMaskPosition:
+    case CSSPropertyWebkitMaskPositionX:
+    case CSSPropertyWebkitMaskPositionY:
+    case CSSPropertyWebkitMaskSize:
+    case CSSPropertyWebkitMaskSourceType:
+    case CSSPropertyWebkitMaskRepeat:
+    case CSSPropertyWebkitMaskRepeatX:
+    case CSSPropertyWebkitMaskRepeatY:
+    {
+        RefPtr&lt;CSSValue&gt; val1;
+        RefPtr&lt;CSSValue&gt; val2;
+        CSSPropertyID propId1, propId2;
+        bool result = false;
+        if (parseFillProperty(propId, propId1, propId2, val1, val2)) {
+            std::unique_ptr&lt;ShorthandScope&gt; shorthandScope;
+            if (propId == CSSPropertyBackgroundPosition ||
+                propId == CSSPropertyBackgroundRepeat ||
+                propId == CSSPropertyWebkitMaskPosition ||
+                propId == CSSPropertyWebkitMaskRepeat) {
+                shorthandScope = std::make_unique&lt;ShorthandScope&gt;(this, propId);
+            }
+            addProperty(propId1, val1.releaseNonNull(), important);
+            if (val2)
+                addProperty(propId2, val2.releaseNonNull(), important);
+            result = true;
+        }
+        m_implicitShorthand = false;
+        return result;
+    }
+    case CSSPropertyListStyleImage:     // &lt;uri&gt; | none | inherit
+    case CSSPropertyBorderImageSource:
+    case CSSPropertyWebkitMaskBoxImageSource:
+        if (id == CSSValueNone) {
+            parsedValue = cssValuePool.createIdentifierValue(CSSValueNone);
+            m_valueList-&gt;next();
+        } else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_URI) {
+            parsedValue = CSSImageValue::create(completeURL(valueWithCalculation.value().string));
+            m_valueList-&gt;next();
+        } else if (isGeneratedImageValue(valueWithCalculation)) {
+            if (parseGeneratedImage(*m_valueList, parsedValue))
+                m_valueList-&gt;next();
+            else
+                return false;
+        } else if (isImageSetFunctionValue(valueWithCalculation.value())) {
+            parsedValue = parseImageSet();
+            if (!parsedValue)
+                return false;
+            m_valueList-&gt;next();
+        }
+        break;
+
+    case CSSPropertyWebkitTextStrokeWidth:
+    case CSSPropertyOutlineWidth:        // &lt;border-width&gt; | inherit
+    case CSSPropertyBorderTopWidth:     //// &lt;border-width&gt; | inherit
+    case CSSPropertyBorderRightWidth:   //   Which is defined as
+    case CSSPropertyBorderBottomWidth:  //   thin | medium | thick | &lt;length&gt;
+    case CSSPropertyBorderLeftWidth:
+    case CSSPropertyWebkitBorderStartWidth:
+    case CSSPropertyWebkitBorderEndWidth:
+    case CSSPropertyWebkitBorderBeforeWidth:
+    case CSSPropertyWebkitBorderAfterWidth:
+    case CSSPropertyColumnRuleWidth:
+        if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick)
+            validPrimitive = true;
+        else
+            validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg);
+        break;
+
+    case CSSPropertyLetterSpacing:       // normal | &lt;length&gt; | inherit
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            validPrimitive = validateUnit(valueWithCalculation, FLength);
+        break;
+
+    case CSSPropertyWordSpacing:         // normal | &lt;length&gt; | &lt;percentage&gt; | inherit
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent);
+        break;
+
+    case CSSPropertyTextIndent:
+        parsedValue = parseTextIndent();
+        break;
+
+    case CSSPropertyPaddingTop:          //// &lt;padding-width&gt; | inherit
+    case CSSPropertyPaddingRight:        //   Which is defined as
+    case CSSPropertyPaddingBottom:       //   &lt;length&gt; | &lt;percentage&gt;
+    case CSSPropertyPaddingLeft:         ////
+    case CSSPropertyWebkitPaddingStart:
+    case CSSPropertyWebkitPaddingEnd:
+    case CSSPropertyWebkitPaddingBefore:
+    case CSSPropertyWebkitPaddingAfter:
+        validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg));
+        break;
+
+    case CSSPropertyMaxWidth:
+    case CSSPropertyWebkitMaxLogicalWidth:
+    case CSSPropertyMaxHeight:
+    case CSSPropertyWebkitMaxLogicalHeight:
+        validPrimitive = (id == CSSValueNone || isValidSize(valueWithCalculation));
+        break;
+
+    case CSSPropertyMinWidth:
+    case CSSPropertyWebkitMinLogicalWidth:
+    case CSSPropertyMinHeight:
+    case CSSPropertyWebkitMinLogicalHeight:
+        validPrimitive = id == CSSValueAuto || isValidSize(valueWithCalculation);
+        break;
+
+    case CSSPropertyWidth:
+    case CSSPropertyWebkitLogicalWidth:
+    case CSSPropertyHeight:
+    case CSSPropertyWebkitLogicalHeight:
+        validPrimitive = (id == CSSValueAuto || isValidSize(valueWithCalculation));
+        break;
+
+    case CSSPropertyFontSize:
+        return parseFontSize(important);
+
+    case CSSPropertyVerticalAlign:
+        // baseline | sub | super | top | text-top | middle | bottom | text-bottom |
+        // &lt;percentage&gt; | &lt;length&gt; | inherit
+
+        if (id &gt;= CSSValueBaseline &amp;&amp; id &lt;= CSSValueWebkitBaselineMiddle)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent));
+        break;
+
+    case CSSPropertyBottom:               // &lt;length&gt; | &lt;percentage&gt; | auto | inherit
+    case CSSPropertyLeft:                 // &lt;length&gt; | &lt;percentage&gt; | auto | inherit
+    case CSSPropertyRight:                // &lt;length&gt; | &lt;percentage&gt; | auto | inherit
+    case CSSPropertyTop:                  // &lt;length&gt; | &lt;percentage&gt; | auto | inherit
+    case CSSPropertyMarginTop:           //// &lt;margin-width&gt; | inherit
+    case CSSPropertyMarginRight:         //   Which is defined as
+    case CSSPropertyMarginBottom:        //   &lt;length&gt; | &lt;percentage&gt; | auto | inherit
+    case CSSPropertyMarginLeft:          ////
+    case CSSPropertyWebkitMarginStart:
+    case CSSPropertyWebkitMarginEnd:
+    case CSSPropertyWebkitMarginBefore:
+    case CSSPropertyWebkitMarginAfter:
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent));
+        break;
+
+    case CSSPropertyZIndex:              // auto | &lt;integer&gt; | inherit
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FInteger, CSSQuirksMode));
+        break;
+
+    case CSSPropertyOrphans: // &lt;integer&gt; | inherit | auto (We've added support for auto for backwards compatibility)
+    case CSSPropertyWidows: // &lt;integer&gt; | inherit | auto (Ditto)
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FPositiveInteger, CSSQuirksMode));
+        break;
+
+    case CSSPropertyLineHeight:
+        return parseLineHeight(important);
+    case CSSPropertyCounterIncrement:    // [ &lt;identifier&gt; &lt;integer&gt;? ]+ | none | inherit
+        if (id != CSSValueNone)
+            return parseCounter(propId, 1, important);
+        validPrimitive = true;
+        break;
+    case CSSPropertyCounterReset:        // [ &lt;identifier&gt; &lt;integer&gt;? ]+ | none | inherit
+        if (id != CSSValueNone)
+            return parseCounter(propId, 0, important);
+        validPrimitive = true;
+        break;
+    case CSSPropertyFontFamily:
+        // [[ &lt;family-name&gt; | &lt;generic-family&gt; ],]* [&lt;family-name&gt; | &lt;generic-family&gt;] | inherit
+    {
+        parsedValue = parseFontFamily();
+        break;
+    }
+
+    case CSSPropertyWebkitTextDecoration:
+        // [ &lt;text-decoration-line&gt; || &lt;text-decoration-style&gt; || &lt;text-decoration-color&gt; ] | inherit
+        return parseShorthand(CSSPropertyWebkitTextDecoration, webkitTextDecorationShorthand(), important);
+
+    case CSSPropertyTextDecoration:
+    case CSSPropertyWebkitTextDecorationsInEffect:
+    case CSSPropertyWebkitTextDecorationLine:
+        // none | [ underline || overline || line-through || blink ] | inherit
+        return parseTextDecoration(propId, important);
+
+    case CSSPropertyWebkitTextDecorationStyle:
+        // solid | double | dotted | dashed | wavy
+        if (id == CSSValueSolid || id == CSSValueDouble || id == CSSValueDotted || id == CSSValueDashed || id == CSSValueWavy)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitTextDecorationSkip:
+        // none | [ objects || spaces || ink || edges || box-decoration ]
+        return parseTextDecorationSkip(important);
+
+    case CSSPropertyWebkitTextUnderlinePosition:
+        // auto | alphabetic | under
+        return parseTextUnderlinePosition(important);
+
+    case CSSPropertyZoom:
+        // normal | reset | document | &lt;number&gt; | &lt;percentage&gt; | inherit
+        if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FPercent | FNonNeg, CSSStrictMode));
+        break;
+    
+    case CSSPropertyWebkitTextZoom:
+        // normal | reset
+        if (id == CSSValueNormal || id == CSSValueReset)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertySrc: // Only used within @font-face and @-webkit-filter, so cannot use inherit | initial or be !important. This is a list of urls or local references.
+        return parseFontFaceSrc();
+
+    case CSSPropertyUnicodeRange:
+        return parseFontFaceUnicodeRange();
+
+    /* CSS3 properties */
+
+    case CSSPropertyBorderImage: {
+        RefPtr&lt;CSSValue&gt; result;
+        return parseBorderImage(propId, result, important);
+    }
+    case CSSPropertyWebkitBorderImage:
+    case CSSPropertyWebkitMaskBoxImage: {
+        RefPtr&lt;CSSValue&gt; result;
+        if (parseBorderImage(propId, result)) {
+            addProperty(propId, WTFMove(result), important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyBorderImageOutset:
+    case CSSPropertyWebkitMaskBoxImageOutset: {
+        RefPtr&lt;CSSPrimitiveValue&gt; result;
+        if (parseBorderImageOutset(result)) {
+            addProperty(propId, WTFMove(result), important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyBorderImageRepeat:
+    case CSSPropertyWebkitMaskBoxImageRepeat: {
+        RefPtr&lt;CSSValue&gt; result;
+        if (parseBorderImageRepeat(result)) {
+            addProperty(propId, WTFMove(result), important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyBorderImageSlice:
+    case CSSPropertyWebkitMaskBoxImageSlice: {
+        RefPtr&lt;CSSBorderImageSliceValue&gt; result;
+        if (parseBorderImageSlice(propId, result)) {
+            addProperty(propId, WTFMove(result), important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyBorderImageWidth:
+    case CSSPropertyWebkitMaskBoxImageWidth: {
+        RefPtr&lt;CSSPrimitiveValue&gt; result;
+        if (parseBorderImageWidth(result)) {
+            addProperty(propId, WTFMove(result), important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyBorderTopRightRadius:
+    case CSSPropertyBorderTopLeftRadius:
+    case CSSPropertyBorderBottomLeftRadius:
+    case CSSPropertyBorderBottomRightRadius: {
+        if (num != 1 &amp;&amp; num != 2)
+            return false;
+        validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
+        if (!validPrimitive)
+            return false;
+        auto parsedValue1 = createPrimitiveNumericValue(valueWithCalculation);
+        RefPtr&lt;CSSPrimitiveValue&gt; parsedValue2;
+        if (num == 2) {
+            ValueWithCalculation nextValueWithCalculation(*m_valueList-&gt;next());
+            validPrimitive = validateUnit(nextValueWithCalculation, FLength | FPercent | FNonNeg);
+            if (!validPrimitive)
+                return false;
+            parsedValue2 = createPrimitiveNumericValue(nextValueWithCalculation);
+        } else
+            parsedValue2 = parsedValue1.ptr();
+
+        addProperty(propId, createPrimitiveValuePair(WTFMove(parsedValue1), parsedValue2.releaseNonNull()), important);
+        return true;
+    }
+    case CSSPropertyTabSize:
+        validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg);
+        break;
+    case CSSPropertyWebkitAspectRatio:
+        return parseAspectRatio(important);
+    case CSSPropertyBorderRadius:
+    case CSSPropertyWebkitBorderRadius:
+        return parseBorderRadius(propId, important);
+    case CSSPropertyOutlineOffset:
+        validPrimitive = validateUnit(valueWithCalculation, FLength);
+        break;
+    case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
+    case CSSPropertyBoxShadow:
+    case CSSPropertyWebkitBoxShadow:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else {
+            RefPtr&lt;CSSValueList&gt; shadowValueList = parseShadow(*m_valueList, propId);
+            if (shadowValueList) {
+                addProperty(propId, shadowValueList.releaseNonNull(), important);
+                m_valueList-&gt;next();
+                return true;
+            }
+            return false;
+        }
+        break;
+    case CSSPropertyWebkitInitialLetter: {
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else {
+            if (num != 1 &amp;&amp; num != 2)
+                return false;
+            validPrimitive = validateUnit(valueWithCalculation, FPositiveInteger);
+            if (!validPrimitive)
+                return false;
+            auto height = createPrimitiveNumericValue(valueWithCalculation);
+            RefPtr&lt;CSSPrimitiveValue&gt; position;
+            if (num == 2) {
+                ValueWithCalculation nextValueWithCalculation(*m_valueList-&gt;next());
+                validPrimitive = validateUnit(nextValueWithCalculation, FPositiveInteger);
+                if (!validPrimitive)
+                    return false;
+                position = createPrimitiveNumericValue(nextValueWithCalculation);
+            } else
+                position = height.ptr();
+            addProperty(propId, createPrimitiveValuePair(position.releaseNonNull(), WTFMove(height)), important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyWebkitBoxReflect:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else
+            return parseReflect(propId, important);
+        break;
+    case CSSPropertyOpacity:
+        validPrimitive = validateUnit(valueWithCalculation, FNumber);
+        break;
+    case CSSPropertyWebkitBoxFlex:
+        validPrimitive = validateUnit(valueWithCalculation, FNumber);
+        break;
+    case CSSPropertyWebkitBoxFlexGroup:
+        validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode);
+        break;
+    case CSSPropertyWebkitBoxOrdinalGroup:
+        validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode) &amp;&amp; valueWithCalculation.value().fValue;
+        break;
+    case CSSPropertyFilter:
+#if ENABLE(FILTERS_LEVEL_2)
+    case CSSPropertyWebkitBackdropFilter:
+#endif
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else {
+            RefPtr&lt;CSSValueList&gt; currValue;
+            if (!parseFilter(*m_valueList, currValue))
+                return false;
+            addProperty(propId, WTFMove(currValue), important);
+            return true;
+        }
+        break;
+#if ENABLE(CSS_COMPOSITING)
+    case CSSPropertyMixBlendMode:
+        validPrimitive = true;
+        break;
+    case CSSPropertyIsolation:
+        validPrimitive = true;
+        break;
+#endif
+    case CSSPropertyFlex: {
+        ShorthandScope scope(this, propId);
+        if (id == CSSValueNone) {
+            addProperty(CSSPropertyFlexGrow, cssValuePool.createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
+            addProperty(CSSPropertyFlexShrink, cssValuePool.createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
+            addProperty(CSSPropertyFlexBasis, cssValuePool.createIdentifierValue(CSSValueAuto), important);
+            return true;
+        }
+        return parseFlex(*m_valueList, important);
+    }
+    case CSSPropertyFlexBasis:
+        // FIXME: Support intrinsic dimensions too.
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg));
+        break;
+    case CSSPropertyFlexGrow:
+    case CSSPropertyFlexShrink:
+        validPrimitive = validateUnit(valueWithCalculation, FNumber | FNonNeg);
+        break;
+    case CSSPropertyOrder:
+        if (validateUnit(valueWithCalculation, FInteger, CSSStrictMode)) {
+            // We restrict the smallest value to int min + 2 because we use int min and int min + 1 as special values in a hash set.
+            double result = std::max&lt;double&gt;(std::numeric_limits&lt;int&gt;::min() + 2, parsedDouble(valueWithCalculation));
+            parsedValue = cssValuePool.createValue(result, CSSPrimitiveValue::CSS_NUMBER);
+            m_valueList-&gt;next();
+        }
+        break;
+    case CSSPropertyWebkitMarquee:
+        return parseShorthand(propId, webkitMarqueeShorthand(), important);
+    case CSSPropertyWebkitMarqueeIncrement:
+        if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium)
+            validPrimitive = true;
+        else
+            validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent);
+        break;
+    case CSSPropertyWebkitMarqueeRepetition:
+        if (id == CSSValueInfinite)
+            validPrimitive = true;
+        else
+            validPrimitive = validateUnit(valueWithCalculation, FInteger | FNonNeg);
+        break;
+    case CSSPropertyWebkitMarqueeSpeed:
+        if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast)
+            validPrimitive = true;
+        else
+            validPrimitive = validateUnit(valueWithCalculation, FTime | FInteger | FNonNeg);
+        break;
+#if ENABLE(CSS_REGIONS)
+    case CSSPropertyWebkitFlowInto:
+        return parseFlowThread(propId, important);
+    case CSSPropertyWebkitFlowFrom:
+        return parseRegionThread(propId, important);
+#endif
+    case CSSPropertyTransform:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else {
+            if (RefPtr&lt;CSSValue&gt; transformValue = parseTransform()) {
+                addProperty(propId, transformValue.releaseNonNull(), important);
+                return true;
+            }
+            return false;
+        }
+        break;
+    case CSSPropertyTransformOrigin:
+    case CSSPropertyTransformOriginX:
+    case CSSPropertyTransformOriginY:
+    case CSSPropertyTransformOriginZ: {
+        RefPtr&lt;CSSPrimitiveValue&gt; val1;
+        RefPtr&lt;CSSPrimitiveValue&gt; val2;
+        RefPtr&lt;CSSValue&gt; val3;
+        CSSPropertyID propId1, propId2, propId3;
+        if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
+            addProperty(propId1, WTFMove(val1), important);
+            if (val2)
+                addProperty(propId2, WTFMove(val2), important);
+            if (val3)
+                addProperty(propId3, WTFMove(val3), important);
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyPerspective:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else {
+            // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
+            if (validateUnit(valueWithCalculation, FNumber | FLength | FNonNeg)) {
+                addProperty(propId, createPrimitiveNumericValue(valueWithCalculation), important);
+                return true;
+            }
+        }
+        break;
+    case CSSPropertyPerspectiveOrigin:
+    case CSSPropertyPerspectiveOriginX:
+    case CSSPropertyPerspectiveOriginY: {
+        RefPtr&lt;CSSPrimitiveValue&gt; val1;
+        RefPtr&lt;CSSPrimitiveValue&gt; val2;
+        CSSPropertyID propId1, propId2;
+        if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
+            addProperty(propId1, WTFMove(val1), important);
+            if (val2)
+                addProperty(propId2, WTFMove(val2), important);
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyAnimationDelay:
+    case CSSPropertyAnimationDirection:
+    case CSSPropertyAnimationDuration:
+    case CSSPropertyAnimationFillMode:
+    case CSSPropertyAnimationName:
+    case CSSPropertyAnimationPlayState:
+    case CSSPropertyAnimationIterationCount:
+    case CSSPropertyAnimationTimingFunction:
+    case CSSPropertyWebkitAnimationDelay:
+    case CSSPropertyWebkitAnimationDirection:
+    case CSSPropertyWebkitAnimationDuration:
+    case CSSPropertyWebkitAnimationFillMode:
+    case CSSPropertyWebkitAnimationName:
+    case CSSPropertyWebkitAnimationPlayState:
+    case CSSPropertyWebkitAnimationIterationCount:
+    case CSSPropertyWebkitAnimationTimingFunction:
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+    case CSSPropertyWebkitAnimationTrigger:
+#endif
+    case CSSPropertyTransitionDelay:
+    case CSSPropertyTransitionDuration:
+    case CSSPropertyTransitionTimingFunction:
+    case CSSPropertyTransitionProperty:
+    case CSSPropertyWebkitTransitionDelay:
+    case CSSPropertyWebkitTransitionDuration:
+    case CSSPropertyWebkitTransitionTimingFunction:
+    case CSSPropertyWebkitTransitionProperty: {
+        RefPtr&lt;CSSValue&gt; val;
+        AnimationParseContext context;
+        if (parseAnimationProperty(propId, val, context)) {
+            addProperty(propId, WTFMove(val), important);
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyJustifyContent:
+        parsedValue = parseContentDistributionOverflowPosition();
+        break;
+    case CSSPropertyJustifySelf:
+        return parseItemPositionOverflowPosition(propId, important);
+    case CSSPropertyJustifyItems:
+        if (parseLegacyPosition(propId, important))
+            return true;
+        m_valueList-&gt;setCurrentIndex(0);
+        return parseItemPositionOverflowPosition(propId, important);
+#if ENABLE(CSS_GRID_LAYOUT)
+    case CSSPropertyGridAutoColumns:
+    case CSSPropertyGridAutoRows:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        parsedValue = parseGridTrackList(GridAuto);
+        break;
+
+    case CSSPropertyGridTemplateColumns:
+    case CSSPropertyGridTemplateRows:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        parsedValue = parseGridTrackList(GridTemplate);
+        break;
+
+    case CSSPropertyGridColumnStart:
+    case CSSPropertyGridColumnEnd:
+    case CSSPropertyGridRowStart:
+    case CSSPropertyGridRowEnd:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        parsedValue = parseGridPosition();
+        break;
+
+    case CSSPropertyGridColumnGap:
+    case CSSPropertyGridRowGap:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg);
+        break;
+
+    case CSSPropertyGridGap:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        return parseGridGapShorthand(important);
+
+    case CSSPropertyGridColumn:
+    case CSSPropertyGridRow:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        return parseGridItemPositionShorthand(propId, important);
+
+    case CSSPropertyGridTemplate:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        return parseGridTemplateShorthand(important);
+
+    case CSSPropertyGrid:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        return parseGridShorthand(important);
+
+    case CSSPropertyGridArea:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        return parseGridAreaShorthand(important);
+
+    case CSSPropertyGridTemplateAreas:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        parsedValue = parseGridTemplateAreas();
+        break;
+    case CSSPropertyGridAutoFlow:
+        if (!isCSSGridLayoutEnabled())
+            return false;
+        parsedValue = parseGridAutoFlow(*m_valueList);
+        break;
+#endif /* ENABLE(CSS_GRID_LAYOUT) */
+    case CSSPropertyWebkitMarginCollapse: {
+        if (num == 1) {
+            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
+            if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important))
+                return false;
+            CSSValue* value = m_parsedProperties.last().value();
+            addProperty(webkitMarginCollapseShorthand().properties()[1], value, important);
+            return true;
+        }
+        else if (num == 2) {
+            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
+            if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important) || !parseValue(webkitMarginCollapseShorthand().properties()[1], important))
+                return false;
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyTextLineThroughWidth:
+    case CSSPropertyTextOverlineWidth:
+    case CSSPropertyTextUnderlineWidth:
+        if (id == CSSValueAuto || id == CSSValueNormal || id == CSSValueThin ||
+            id == CSSValueMedium || id == CSSValueThick)
+            validPrimitive = true;
+        else
+            validPrimitive = !id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FLength | FPercent);
+        break;
+    case CSSPropertyColumnCount:
+        parsedValue = parseColumnCount();
+        break;
+    case CSSPropertyColumnGap: // normal | &lt;length&gt;
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            validPrimitive = validateUnit(valueWithCalculation, FLength | FNonNeg);
+        break;
+    case CSSPropertyWebkitColumnAxis:
+        if (id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto)
+            validPrimitive = true;
+        break;
+    case CSSPropertyColumnProgression:
+        if (id == CSSValueNormal || id == CSSValueReverse)
+            validPrimitive = true;
+        break;
+    case CSSPropertyColumnSpan: // none | all | 1 (will be dropped in the unprefixed property)
+        if (id == CSSValueAll || id == CSSValueNone)
+            validPrimitive = true;
+        else if (validateUnit(valueWithCalculation, FNumber | FNonNeg) &amp;&amp; parsedDouble(valueWithCalculation) == 1) {
+            addProperty(CSSPropertyColumnSpan, cssValuePool.createValue(1, CSSPrimitiveValue::CSS_NUMBER), important);
+            return true;
+        }
+        break;
+    case CSSPropertyColumnWidth: // auto | &lt;length&gt;
+        parsedValue = parseColumnWidth();
+        break;
+    case CSSPropertyObjectPosition: {
+        RefPtr&lt;CSSPrimitiveValue&gt; val1;
+        RefPtr&lt;CSSPrimitiveValue&gt; val2;
+        parseFillPosition(*m_valueList, val1, val2);
+        if (val1) {
+            addProperty(CSSPropertyObjectPosition, createPrimitiveValuePair(val1.releaseNonNull(), WTFMove(val2)), important);
+            return true;
+        }
+        return false;
+        }
+    // End of CSS3 properties
+
+    case CSSPropertyWillChange: // auto | [scroll-position | contents | &lt;custom-ident&gt;]#
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            return parseWillChange(important);
+        break;
+
+    // Apple specific properties.  These will never be standardized and are purely to
+    // support custom WebKit-based Apple applications.
+    case CSSPropertyWebkitLineClamp:
+        // When specifying number of lines, don't allow 0 as a valid value
+        // When specifying either type of unit, require non-negative integers
+        validPrimitive = (!id &amp;&amp; (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE || valueWithCalculation.value().fValue) &amp;&amp; validateUnit(valueWithCalculation, FInteger | FPercent | FNonNeg, CSSQuirksMode));
+        break;
+#if ENABLE(IOS_TEXT_AUTOSIZING)
+    case CSSPropertyWebkitTextSizeAdjust:
+        if (!isTextAutosizingEnabled())
+            return false;
+
+        if (id == CSSValueAuto || id == CSSValueNone)
+            validPrimitive = true;
+        else {
+            // FIXME: Handle multilength case where we allow relative units.
+            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FPercent | FNonNeg, CSSStrictMode));
+        }
+        break;
+#endif
+
+    case CSSPropertyWebkitFontSizeDelta:           // &lt;length&gt;
+        validPrimitive = validateUnit(valueWithCalculation, FLength);
+        break;
+
+    case CSSPropertyWebkitHyphenateCharacter:
+        if (id == CSSValueAuto || valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitHyphenateLimitBefore:
+    case CSSPropertyWebkitHyphenateLimitAfter:
+        if (id == CSSValueAuto || validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode))
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitHyphenateLimitLines:
+        if (id == CSSValueNoLimit || validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSStrictMode))
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitLineGrid:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_IDENT) {
+            String lineGridValue = String(valueWithCalculation.value().string);
+            if (!lineGridValue.isEmpty()) {
+                addProperty(propId, cssValuePool.createValue(lineGridValue, CSSPrimitiveValue::CSS_STRING), important);
+                return true;
+            }
+        }
+        break;
+    case CSSPropertyWebkitLocale:
+        if (id == CSSValueAuto || valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING)
+            validPrimitive = true;
+        break;
+
+#if ENABLE(DASHBOARD_SUPPORT)
+    case CSSPropertyWebkitDashboardRegion: // &lt;dashboard-region&gt; | &lt;dashboard-region&gt;
+        if (valueWithCalculation.value().unit == CSSParserValue::Function || id == CSSValueNone)
+            return parseDashboardRegions(propId, important);
+        break;
+#endif
+
+#if PLATFORM(IOS)
+    case CSSPropertyWebkitTouchCallout:
+        if (id == CSSValueDefault || id == CSSValueNone)
+            validPrimitive = true;
+        break;
+#endif
+#if ENABLE(TOUCH_EVENTS)
+    case CSSPropertyWebkitTapHighlightColor:
+        if (isValidSystemColorValue(id) || id == CSSValueMenu
+            || (id &gt;= CSSValueWebkitFocusRingColor &amp;&amp; id &lt; CSSValueWebkitText &amp;&amp; inQuirksMode())) {
+            validPrimitive = true;
+        } else {
+            parsedValue = parseColor();
+            if (parsedValue)
+                m_valueList-&gt;next();
+        }
+        break;
+#endif
+    // End Apple-specific properties
+
+        /* shorthand properties */
+    case CSSPropertyBackground: {
+        // Position must come before color in this array because a plain old &quot;0&quot; is a legal color
+        // in quirks mode but it's usually the X coordinate of a position.
+        const CSSPropertyID properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat,
+                                   CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin,
+                                   CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, CSSPropertyBackgroundSize };
+        return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
+    }
+    case CSSPropertyWebkitMask: {
+        const CSSPropertyID properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskSourceType, CSSPropertyWebkitMaskRepeat,
+            CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskOrigin, CSSPropertyWebkitMaskClip, CSSPropertyWebkitMaskSize };
+        return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
+    }
+    case CSSPropertyBorder:
+        // [ 'border-width' || 'border-style' || &lt;color&gt; ] | inherit
+    {
+        if (parseShorthand(propId, borderAbridgedShorthand(), important)) {
+            // The CSS3 Borders and Backgrounds specification says that border also resets border-image. It's as
+            // though a value of none was specified for the image.
+            addExpandedPropertyForValue(CSSPropertyBorderImage, cssValuePool.createImplicitInitialValue(), important);
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyBorderTop:
+        // [ 'border-top-width' || 'border-style' || &lt;color&gt; ] | inherit
+        return parseShorthand(propId, borderTopShorthand(), important);
+    case CSSPropertyBorderRight:
+        // [ 'border-right-width' || 'border-style' || &lt;color&gt; ] | inherit
+        return parseShorthand(propId, borderRightShorthand(), important);
+    case CSSPropertyBorderBottom:
+        // [ 'border-bottom-width' || 'border-style' || &lt;color&gt; ] | inherit
+        return parseShorthand(propId, borderBottomShorthand(), important);
+    case CSSPropertyBorderLeft:
+        // [ 'border-left-width' || 'border-style' || &lt;color&gt; ] | inherit
+        return parseShorthand(propId, borderLeftShorthand(), important);
+    case CSSPropertyWebkitBorderStart:
+        return parseShorthand(propId, webkitBorderStartShorthand(), important);
+    case CSSPropertyWebkitBorderEnd:
+        return parseShorthand(propId, webkitBorderEndShorthand(), important);
+    case CSSPropertyWebkitBorderBefore:
+        return parseShorthand(propId, webkitBorderBeforeShorthand(), important);
+    case CSSPropertyWebkitBorderAfter:
+        return parseShorthand(propId, webkitBorderAfterShorthand(), important);
+    case CSSPropertyOutline:
+        // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
+        return parseShorthand(propId, outlineShorthand(), important);
+    case CSSPropertyBorderColor:
+        // &lt;color&gt;{1,4} | inherit
+        return parse4Values(propId, borderColorShorthand().properties(), important);
+    case CSSPropertyBorderWidth:
+        // &lt;border-width&gt;{1,4} | inherit
+        return parse4Values(propId, borderWidthShorthand().properties(), important);
+    case CSSPropertyBorderStyle:
+        // &lt;border-style&gt;{1,4} | inherit
+        return parse4Values(propId, borderStyleShorthand().properties(), important);
+    case CSSPropertyMargin:
+        // &lt;margin-width&gt;{1,4} | inherit
+        return parse4Values(propId, marginShorthand().properties(), important);
+    case CSSPropertyPadding:
+        // &lt;padding-width&gt;{1,4} | inherit
+        return parse4Values(propId, paddingShorthand().properties(), important);
+    case CSSPropertyFlexFlow:
+        return parseShorthand(propId, flexFlowShorthand(), important);
+    case CSSPropertyFont:
+        // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]?
+        // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
+        if (num == 1 &amp;&amp; id &gt;= CSSValueCaption &amp;&amp; id &lt;= CSSValueStatusBar) {
+            parseSystemFont(important);
+            return true;
+        }
+        return parseFont(important);
+    case CSSPropertyListStyle:
+        return parseShorthand(propId, listStyleShorthand(), important);
+    case CSSPropertyColumns:
+        return parseColumnsShorthand(important);
+    case CSSPropertyColumnRule:
+        return parseShorthand(propId, columnRuleShorthand(), important);
+    case CSSPropertyWebkitTextStroke:
+        return parseShorthand(propId, webkitTextStrokeShorthand(), important);
+    case CSSPropertyAnimation:
+    case CSSPropertyWebkitAnimation:
+        return parseAnimationShorthand(propId, important);
+    case CSSPropertyTransition:
+    case CSSPropertyWebkitTransition:
+        return parseTransitionShorthand(propId, important);
+    case CSSPropertyInvalid:
+        return false;
+    case CSSPropertyPage:
+        return parsePage(propId, important);
+    case CSSPropertyFontStretch:
+    case CSSPropertyTextLineThrough:
+    case CSSPropertyTextOverline:
+    case CSSPropertyTextUnderline:
+        return false;
+    // CSS Text Layout Module Level 3: Vertical writing support
+    case CSSPropertyWebkitTextEmphasis:
+        return parseShorthand(propId, webkitTextEmphasisShorthand(), important);
+
+    case CSSPropertyWebkitTextEmphasisStyle:
+        return parseTextEmphasisStyle(important);
+
+    case CSSPropertyWebkitTextEmphasisPosition:
+        return parseTextEmphasisPosition(important);
+
+    case CSSPropertyWebkitTextOrientation:
+        if (id == CSSValueSideways || id == CSSValueSidewaysRight || id == CSSValueVerticalRight || id == CSSValueMixed || id == CSSValueUpright)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyHangingPunctuation:
+        return parseHangingPunctuation(important);
+    case CSSPropertyWebkitLineBoxContain:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else
+            return parseLineBoxContain(important);
+        break;
+    case CSSPropertyFontFeatureSettings:
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            return parseFontFeatureSettings(important);
+        break;
+    case CSSPropertyFontVariantLigatures:
+        if (id == CSSValueNormal || id == CSSValueNone)
+            validPrimitive = true;
+        else
+            return parseFontVariantLigatures(important, true, false);
+        break;
+    case CSSPropertyFontVariantNumeric:
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            return parseFontVariantNumeric(important, true, false);
+        break;
+    case CSSPropertyFontVariantEastAsian:
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            return parseFontVariantEastAsian(important, true, false);
+        break;
+    case CSSPropertyFontVariant:
+        if (id == CSSValueNormal) {
+            ShorthandScope scope(this, CSSPropertyFontVariant);
+            addProperty(CSSPropertyFontVariantLigatures, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+            addProperty(CSSPropertyFontVariantPosition, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+            addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+            addProperty(CSSPropertyFontVariantNumeric, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+            addProperty(CSSPropertyFontVariantAlternates, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+            addProperty(CSSPropertyFontVariantEastAsian, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+            return true;
+        }
+        if (id == CSSValueNone) {
+            ShorthandScope scope(this, CSSPropertyFontVariant);
+            addProperty(CSSPropertyFontVariantLigatures, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important, true);
+            return true;
+        }
+        return parseFontVariant(important);
+
+    case CSSPropertyWebkitClipPath:
+        parsedValue = parseClipPath();
+        break;
+#if ENABLE(CSS_SHAPES)
+    case CSSPropertyWebkitShapeOutside:
+        parsedValue = parseShapeProperty(propId);
+        break;
+    case CSSPropertyWebkitShapeMargin:
+        validPrimitive = !id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
+        break;
+    case CSSPropertyWebkitShapeImageThreshold:
+        validPrimitive = !id &amp;&amp; validateUnit(valueWithCalculation, FNumber);
+        break;
+#endif
+#if ENABLE(CSS_IMAGE_ORIENTATION)
+    case CSSPropertyImageOrientation:
+        validPrimitive = !id &amp;&amp; validateUnit(valueWithCalculation, FAngle);
+        break;
+#endif
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+    case CSSPropertyImageResolution:
+        parsedValue = parseImageResolution();
+        break;
+#endif
+    case CSSPropertyAlignContent:
+        parsedValue = parseContentDistributionOverflowPosition();
+        break;
+    case CSSPropertyAlignSelf:
+        return parseItemPositionOverflowPosition(propId, important);
+
+    case CSSPropertyAlignItems:
+        return parseItemPositionOverflowPosition(propId, important);
+    case CSSPropertyBorderBottomStyle:
+    case CSSPropertyBorderCollapse:
+    case CSSPropertyBorderLeftStyle:
+    case CSSPropertyBorderRightStyle:
+    case CSSPropertyBorderTopStyle:
+    case CSSPropertyBoxSizing:
+    case CSSPropertyBreakAfter:
+    case CSSPropertyBreakBefore:
+    case CSSPropertyBreakInside:
+    case CSSPropertyCaptionSide:
+    case CSSPropertyClear:
+    case CSSPropertyDirection:
+    case CSSPropertyDisplay:
+    case CSSPropertyEmptyCells:
+    case CSSPropertyFloat:
+    case CSSPropertyFontStyle:
+    case CSSPropertyImageRendering:
+    case CSSPropertyListStylePosition:
+    case CSSPropertyListStyleType:
+    case CSSPropertyObjectFit:
+    case CSSPropertyOutlineStyle:
+    case CSSPropertyOverflowWrap:
+    case CSSPropertyOverflowX:
+    case CSSPropertyOverflowY:
+    case CSSPropertyPageBreakAfter:
+    case CSSPropertyPageBreakBefore:
+    case CSSPropertyPageBreakInside:
+    case CSSPropertyPointerEvents:
+    case CSSPropertyPosition:
+    case CSSPropertyResize:
+    case CSSPropertySpeak:
+    case CSSPropertyTableLayout:
+    case CSSPropertyTextLineThroughMode:
+    case CSSPropertyTextLineThroughStyle:
+    case CSSPropertyTextOverflow:
+    case CSSPropertyTextOverlineMode:
+    case CSSPropertyTextOverlineStyle:
+    case CSSPropertyTextRendering:
+    case CSSPropertyTextTransform:
+    case CSSPropertyTextUnderlineMode:
+    case CSSPropertyTextUnderlineStyle:
+    case CSSPropertyVisibility:
+    case CSSPropertyWebkitAppearance:
+    case CSSPropertyWebkitBackfaceVisibility:
+    case CSSPropertyWebkitBorderAfterStyle:
+    case CSSPropertyWebkitBorderBeforeStyle:
+    case CSSPropertyWebkitBorderEndStyle:
+    case CSSPropertyWebkitBorderFit:
+    case CSSPropertyWebkitBorderStartStyle:
+    case CSSPropertyWebkitBoxAlign:
+#if ENABLE(CSS_BOX_DECORATION_BREAK)
+    case CSSPropertyWebkitBoxDecorationBreak:
+#endif
+    case CSSPropertyWebkitBoxDirection:
+    case CSSPropertyWebkitBoxLines:
+    case CSSPropertyWebkitBoxOrient:
+    case CSSPropertyWebkitBoxPack:
+    case CSSPropertyWebkitColumnBreakAfter:
+    case CSSPropertyWebkitColumnBreakBefore:
+    case CSSPropertyWebkitColumnBreakInside:
+    case CSSPropertyColumnFill:
+    case CSSPropertyColumnRuleStyle:
+    case CSSPropertyFlexDirection:
+    case CSSPropertyFlexWrap:
+    case CSSPropertyWebkitFontKerning:
+    case CSSPropertyWebkitFontSmoothing:
+    case CSSPropertyWebkitHyphens:
+    case CSSPropertyWebkitLineAlign:
+    case CSSPropertyWebkitLineBreak:
+    case CSSPropertyWebkitLineSnap:
+    case CSSPropertyWebkitMarginAfterCollapse:
+    case CSSPropertyWebkitMarginBeforeCollapse:
+    case CSSPropertyWebkitMarginBottomCollapse:
+    case CSSPropertyWebkitMarginTopCollapse:
+    case CSSPropertyWebkitMarqueeDirection:
+    case CSSPropertyWebkitMarqueeStyle:
+    case CSSPropertyWebkitNbspMode:
+#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
+    case CSSPropertyWebkitOverflowScrolling:
+#endif
+    case CSSPropertyWebkitPrintColorAdjust:
+#if ENABLE(CSS_REGIONS)
+    case CSSPropertyWebkitRegionBreakAfter:
+    case CSSPropertyWebkitRegionBreakBefore:
+    case CSSPropertyWebkitRegionBreakInside:
+    case CSSPropertyWebkitRegionFragment:
+#endif
+    case CSSPropertyWebkitRtlOrdering:
+    case CSSPropertyWebkitRubyPosition:
+#if ENABLE(CSS3_TEXT)
+    case CSSPropertyWebkitTextAlignLast:
+#endif // CSS3_TEXT
+    case CSSPropertyWebkitTextCombine:
+#if ENABLE(CSS3_TEXT)
+    case CSSPropertyWebkitTextJustify:
+#endif // CSS3_TEXT
+    case CSSPropertyWebkitTextSecurity:
+    case CSSPropertyTransformStyle:
+    case CSSPropertyWebkitTransformStyle:
+    case CSSPropertyWebkitUserDrag:
+    case CSSPropertyWebkitUserModify:
+    case CSSPropertyWebkitUserSelect:
+    case CSSPropertyWebkitWritingMode:
+    case CSSPropertyWhiteSpace:
+    case CSSPropertyWordBreak:
+    case CSSPropertyWordWrap:
+#if ENABLE(TOUCH_EVENTS)
+    case CSSPropertyTouchAction:
+#endif
+#if ENABLE(CSS_SCROLL_SNAP)
+    case CSSPropertyWebkitScrollSnapType:
+#endif
+#if ENABLE(CSS_TRAILING_WORD)
+    case CSSPropertyAppleTrailingWord:
+#endif
+        // These properties should be handled before in isValidKeywordPropertyAndValue().
+        ASSERT_NOT_REACHED();
+        return false;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    // Properties bellow are validated inside parseViewportProperty, because we
+    // check for parser state inViewportScope. We need to invalidate if someone
+    // adds them outside a @viewport rule.
+    case CSSPropertyMaxZoom:
+    case CSSPropertyMinZoom:
+    case CSSPropertyOrientation:
+    case CSSPropertyUserZoom:
+        validPrimitive = false;
+        break;
+#endif
+#if ENABLE(CSS_SCROLL_SNAP)
+    case CSSPropertyWebkitScrollSnapPointsX:
+    case CSSPropertyWebkitScrollSnapPointsY:
+        if (id == CSSValueElements) {
+            validPrimitive = true;
+            break;
+        }
+        return parseNonElementSnapPoints(propId, important);
+    case CSSPropertyWebkitScrollSnapDestination: // &lt;length&gt;{2}
+        return parseScrollSnapDestination(propId, important);
+    case CSSPropertyWebkitScrollSnapCoordinate:
+        return parseScrollSnapCoordinate(propId, important);
+#endif
+
+    default:
+        return parseSVGValue(propId, important);
+    }
+
+    if (validPrimitive) {
+        parsedValue = parseValidPrimitive(id, valueWithCalculation);
+        m_valueList-&gt;next();
+    }
+
+    if (parsedValue &amp;&amp; (!m_valueList-&gt;current() || inShorthand())) {
+        addProperty(propId, parsedValue.releaseNonNull(), important);
+        return true;
+    }
+    return false;
+}
+
+void CSSParser::addFillValue(RefPtr&lt;CSSValue&gt;&amp; lval, Ref&lt;CSSValue&gt;&amp;&amp; rval)
+{
+    if (!lval) {
+        lval = WTFMove(rval);
+        return;
+    }
+
+    if (lval-&gt;isBaseValueList()) {
+        downcast&lt;CSSValueList&gt;(*lval).append(WTFMove(rval));
+        return;
+    }
+
+    auto list = CSSValueList::createCommaSeparated();
+    list.get().append(lval.releaseNonNull());
+    list.get().append(WTFMove(rval));
+    lval = WTFMove(list);
+}
+
+static bool isContentDistributionKeyword(CSSValueID id)
+{
+    return id == CSSValueSpaceBetween || id == CSSValueSpaceAround
+        || id == CSSValueSpaceEvenly || id == CSSValueStretch;
+}
+
+static bool isContentPositionKeyword(CSSValueID id)
+{
+    return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter
+        || id == CSSValueFlexStart || id == CSSValueFlexEnd
+        || id == CSSValueLeft || id == CSSValueRight;
+}
+
+static inline bool isBaselinePositionKeyword(CSSValueID id)
+{
+    return id == CSSValueBaseline || id == CSSValueLastBaseline;
+}
+
+static bool isAlignmentOverflowKeyword(CSSValueID id)
+{
+    return id == CSSValueUnsafe || id == CSSValueSafe;
+}
+
+static bool isItemPositionKeyword(CSSValueID id)
+{
+    return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter
+        || id == CSSValueSelfStart || id == CSSValueSelfEnd || id == CSSValueFlexStart
+        || id == CSSValueFlexEnd || id == CSSValueLeft || id == CSSValueRight;
+}
+
+bool CSSParser::parseLegacyPosition(CSSPropertyID propId, bool important)
+{
+    // [ legacy &amp;&amp; [ left | right | center ]
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (!value)
+        return false;
+
+    if (value-&gt;id == CSSValueLegacy) {
+        value = m_valueList-&gt;next();
+        if (!value)
+            return false;
+        if (value-&gt;id != CSSValueCenter &amp;&amp; value-&gt;id != CSSValueLeft &amp;&amp; value-&gt;id != CSSValueRight)
+            return false;
+    } else if (value-&gt;id == CSSValueCenter || value-&gt;id == CSSValueLeft || value-&gt;id == CSSValueRight) {
+        if (!m_valueList-&gt;next() || m_valueList-&gt;current()-&gt;id != CSSValueLegacy)
+            return false;
+    } else
+        return false;
+
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    addProperty(propId, createPrimitiveValuePair(cssValuePool.createIdentifierValue(CSSValueLegacy), cssValuePool.createIdentifierValue(value-&gt;id)), important);
+    return !m_valueList-&gt;next();
+}
+
+RefPtr&lt;CSSContentDistributionValue&gt; CSSParser::parseContentDistributionOverflowPosition()
+{
+    // normal | &lt;baseline-position&gt; | &lt;content-distribution&gt; || [ &lt;overflow-position&gt;? &amp;&amp; &lt;content-position&gt; ]
+    // &lt;baseline-position&gt; = baseline | last-baseline;
+    // &lt;content-distribution&gt; = space-between | space-around | space-evenly | stretch;
+    // &lt;content-position&gt; = center | start | end | flex-start | flex-end | left | right;
+    // &lt;overflow-position&gt; = unsafe | safe
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (!value)
+        return nullptr;
+
+    // auto | &lt;baseline-position&gt;
+    if (value-&gt;id == CSSValueNormal || isBaselinePositionKeyword(value-&gt;id)) {
+        m_valueList-&gt;next();
+        return CSSContentDistributionValue::create(CSSValueInvalid, value-&gt;id, CSSValueInvalid);
+    }
+
+    CSSValueID distribution = CSSValueInvalid;
+    CSSValueID position = CSSValueInvalid;
+    CSSValueID overflow = CSSValueInvalid;
+    while (value) {
+        if (isContentDistributionKeyword(value-&gt;id)) {
+            if (distribution != CSSValueInvalid)
+                return nullptr;
+            distribution = value-&gt;id;
+        } else if (isContentPositionKeyword(value-&gt;id)) {
+            if (position != CSSValueInvalid)
+                return nullptr;
+            position = value-&gt;id;
+        } else if (isAlignmentOverflowKeyword(value-&gt;id)) {
+            if (overflow != CSSValueInvalid)
+                return nullptr;
+            overflow = value-&gt;id;
+        } else
+            return nullptr;
+        value = m_valueList-&gt;next();
+    }
+
+    // The grammar states that we should have at least &lt;content-distribution&gt; or
+    // &lt;content-position&gt; ( &lt;content-distribution&gt; || &lt;content-position&gt; ).
+    if (position == CSSValueInvalid &amp;&amp; distribution == CSSValueInvalid)
+        return nullptr;
+
+    // The grammar states that &lt;overflow-position&gt; must be associated to &lt;content-position&gt;.
+    if (overflow != CSSValueInvalid &amp;&amp; position == CSSValueInvalid)
+        return nullptr;
+
+    return CSSContentDistributionValue::create(distribution, position, overflow);
+}
+
+bool CSSParser::parseItemPositionOverflowPosition(CSSPropertyID propId, bool important)
+{
+    // auto | normal | stretch | &lt;baseline-position&gt; | [&lt;item-position&gt; &amp;&amp; &lt;overflow-position&gt;? ]
+    // &lt;baseline-position&gt; = baseline | last-baseline;
+    // &lt;item-position&gt; = center | start | end | self-start | self-end | flex-start | flex-end | left | right;
+    // &lt;overflow-position&gt; = unsafe | safe
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (!value)
+        return false;
+
+    if (value-&gt;id == CSSValueAuto || value-&gt;id == CSSValueNormal || value-&gt;id == CSSValueStretch || isBaselinePositionKeyword(value-&gt;id)) {
+        // align-items property does not allow the 'auto' value.
+        if (value-&gt;id == CSSValueAuto &amp;&amp; propId == CSSPropertyAlignItems)
+            return false;
+        if (m_valueList-&gt;next())
+            return false;
+
+        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
+        return true;
+    }
+
+    RefPtr&lt;CSSPrimitiveValue&gt; position;
+    RefPtr&lt;CSSPrimitiveValue&gt; overflowAlignmentKeyword;
+    if (isItemPositionKeyword(value-&gt;id)) {
+        position = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+        value = m_valueList-&gt;next();
+        if (value) {
+            if (value-&gt;id != CSSValueUnsafe &amp;&amp; value-&gt;id != CSSValueSafe)
+                return false;
+            overflowAlignmentKeyword = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+        }
+    } else if (isAlignmentOverflowKeyword(value-&gt;id)) {
+        overflowAlignmentKeyword = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+        value = m_valueList-&gt;next();
+        if (value &amp;&amp; isItemPositionKeyword(value-&gt;id))
+            position = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+        else
+            return false;
+    } else
+        return false;
+
+    if (m_valueList-&gt;next())
+        return false;
+
+    ASSERT(position);
+    if (overflowAlignmentKeyword)
+        addProperty(propId, createPrimitiveValuePair(position.releaseNonNull(), overflowAlignmentKeyword.releaseNonNull()), important);
+    else
+        addProperty(propId, position.releaseNonNull(), important);
+
+    return true;
+}
+
+static bool parseBackgroundClip(CSSParserValue&amp; parserValue, RefPtr&lt;CSSValue&gt;&amp; cssValue)
+{
+    if (parserValue.id == CSSValueBorderBox || parserValue.id == CSSValuePaddingBox
+        || parserValue.id == CSSValueContentBox || parserValue.id == CSSValueWebkitText) {
+        cssValue = CSSValuePool::singleton().createIdentifierValue(parserValue.id);
+        return true;
+    }
+    return false;
+}
+
+bool CSSParser::useLegacyBackgroundSizeShorthandBehavior() const
+{
+    return m_context.useLegacyBackgroundSizeShorthandBehavior;
+}
+
+#if ENABLE(CSS_SCROLL_SNAP)
+bool CSSParser::parseNonElementSnapPoints(CSSPropertyID propId, bool important)
+{
+    auto values = CSSValueList::createSpaceSeparated();
+    while (CSSParserValue* value = m_valueList-&gt;current()) {
+        ValueWithCalculation valueWithCalculation(*value);
+        if (validateUnit(valueWithCalculation, FPercent | FLength))
+            values-&gt;append(createPrimitiveNumericValue(valueWithCalculation));
+        else if (value-&gt;unit == CSSParserValue::Function
+            &amp;&amp; value-&gt;function-&gt;args
+            &amp;&amp; value-&gt;function-&gt;args-&gt;size() == 1
+            &amp;&amp; equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;repeat(&quot;)) {
+            ValueWithCalculation argumentWithCalculation(*value-&gt;function-&gt;args.get()-&gt;current());
+            if (validateUnit(argumentWithCalculation, FLength | FPercent | FNonNeg)) {
+                values-&gt;append(CSSValuePool::singleton().createValue(LengthRepeat::create(createPrimitiveNumericValue(argumentWithCalculation))));
+                m_valueList-&gt;next();
+                if (m_valueList-&gt;current())
+                    return false;
+                break;
+            }
+        } else
+            return false;
+        m_valueList-&gt;next();
+    }
+    if (values-&gt;length()) {
+        addProperty(propId, WTFMove(values), important);
+        m_valueList-&gt;next();
+        return true;
+    }
+    return false;
+}
+
+bool CSSParser::parseScrollSnapPositions(RefPtr&lt;CSSValue&gt;&amp; cssValueX, RefPtr&lt;CSSValue&gt;&amp; cssValueY)
+{
+    cssValueX = parsePositionX(*m_valueList);
+    if (!cssValueX)
+        return false;
+
+    // Don't accept odd-length lists of positions (must always have an X and a Y):
+    if (!m_valueList-&gt;next())
+        return false;
+
+    cssValueY = parsePositionY(*m_valueList);
+    if (!cssValueY)
+        return false;
+
+    return true;
+}
+
+bool CSSParser::parseScrollSnapDestination(CSSPropertyID propId, bool important)
+{
+    auto position = CSSValueList::createSpaceSeparated();
+    if (m_valueList-&gt;size() != 2)
+        return false;
+
+    RefPtr&lt;CSSValue&gt; cssValueX, cssValueY;
+    if (!parseScrollSnapPositions(cssValueX, cssValueY))
+        return false;
+
+    position-&gt;append(cssValueX.releaseNonNull());
+    position-&gt;append(cssValueY.releaseNonNull());
+    addProperty(propId, WTFMove(position), important);
+    m_valueList-&gt;next();
+    return true;
+}
+
+bool CSSParser::parseScrollSnapCoordinate(CSSPropertyID propId, bool important)
+{
+    auto positions = CSSValueList::createSpaceSeparated();
+    while (m_valueList-&gt;current()) {
+        RefPtr&lt;CSSValue&gt; cssValueX, cssValueY;
+        if (!parseScrollSnapPositions(cssValueX, cssValueY))
+            return false;
+
+        positions-&gt;append(cssValueX.releaseNonNull());
+        positions-&gt;append(cssValueY.releaseNonNull());
+        m_valueList-&gt;next();
+    }
+
+    if (positions-&gt;length()) {
+        addProperty(propId, WTFMove(positions), important);
+        return true;
+    }
+    return false;
+}
+#endif
+
+const int cMaxFillProperties = 9;
+
+bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* properties, int numProperties, bool important)
+{
+    ASSERT(numProperties &lt;= cMaxFillProperties);
+    if (numProperties &gt; cMaxFillProperties)
+        return false;
+
+    ShorthandScope scope(this, propId);
+
+    bool parsedProperty[cMaxFillProperties] = { false };
+    RefPtr&lt;CSSValue&gt; values[cMaxFillProperties];
+    RefPtr&lt;CSSValue&gt; clipValue;
+    RefPtr&lt;CSSValue&gt; positionYValue;
+    RefPtr&lt;CSSValue&gt; repeatYValue;
+    bool foundClip = false;
+    int i;
+    bool foundPositionCSSProperty = false;
+
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    while (m_valueList-&gt;current()) {
+        CSSParserValue&amp; currentValue = *m_valueList-&gt;current();
+        if (currentValue.unit == CSSParserValue::Operator &amp;&amp; currentValue.iValue == ',') {
+            // We hit the end.  Fill in all remaining values with the initial value.
+            m_valueList-&gt;next();
+            for (i = 0; i &lt; numProperties; ++i) {
+                if (properties[i] == CSSPropertyBackgroundColor &amp;&amp; parsedProperty[i])
+                    // Color is not allowed except as the last item in a list for backgrounds.
+                    // Reject the entire property.
+                    return false;
+
+                if (!parsedProperty[i] &amp;&amp; properties[i] != CSSPropertyBackgroundColor) {
+                    addFillValue(values[i], cssValuePool.createImplicitInitialValue());
+                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+                        addFillValue(positionYValue, cssValuePool.createImplicitInitialValue());
+                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
+                        addFillValue(repeatYValue, cssValuePool.createImplicitInitialValue());
+                    if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) &amp;&amp; !parsedProperty[i]) {
+                        // If background-origin wasn't present, then reset background-clip also.
+                        addFillValue(clipValue, cssValuePool.createImplicitInitialValue());
+                    }
+                }
+                parsedProperty[i] = false;
+            }
+            if (!m_valueList-&gt;current())
+                break;
+        }
+
+        bool sizeCSSPropertyExpected = false;
+        if (isForwardSlashOperator(currentValue) &amp;&amp; foundPositionCSSProperty) {
+            sizeCSSPropertyExpected = true;
+            m_valueList-&gt;next();
+        }
+
+        foundPositionCSSProperty = false;
+        bool found = false;
+        for (i = 0; !found &amp;&amp; i &lt; numProperties; ++i) {
+
+            if (sizeCSSPropertyExpected &amp;&amp; (properties[i] != CSSPropertyBackgroundSize &amp;&amp; properties[i] != CSSPropertyWebkitMaskSize))
+                continue;
+            if (!sizeCSSPropertyExpected &amp;&amp; (properties[i] == CSSPropertyBackgroundSize || properties[i] == CSSPropertyWebkitMaskSize))
+                continue;
+
+            if (!parsedProperty[i]) {
+                RefPtr&lt;CSSValue&gt; val1;
+                RefPtr&lt;CSSValue&gt; val2;
+                CSSPropertyID propId1, propId2;
+                CSSParserValue&amp; parserValue = *m_valueList-&gt;current();
+
+                if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) {
+                    parsedProperty[i] = found = true;
+                    addFillValue(values[i], val1.releaseNonNull());
+                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+                        addFillValue(positionYValue, val2.releaseNonNull());
+                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
+                        addFillValue(repeatYValue, val2.releaseNonNull());
+                    if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
+                        // Reparse the value as a clip, and see if we succeed.
+                        if (parseBackgroundClip(parserValue, val1))
+                            addFillValue(clipValue, val1.releaseNonNull()); // The property parsed successfully.
+                        else
+                            addFillValue(clipValue, cssValuePool.createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead.
+                    }
+                    if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip)
+                        foundClip = true;
+                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+                        foundPositionCSSProperty = true;
+                }
+            }
+        }
+
+        // if we didn't find at least one match, this is an
+        // invalid shorthand and we have to ignore it
+        if (!found)
+            return false;
+    }
+
+    // Now add all of the properties we found.
+    for (i = 0; i &lt; numProperties; ++i) {
+        // Fill in any remaining properties with the initial value.
+        if (!parsedProperty[i]) {
+            addFillValue(values[i], cssValuePool.createImplicitInitialValue());
+            if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+                addFillValue(positionYValue, cssValuePool.createImplicitInitialValue());
+            if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
+                addFillValue(repeatYValue, cssValuePool.createImplicitInitialValue());
+            if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
+                // If background-origin wasn't present, then reset background-clip also.
+                addFillValue(clipValue, cssValuePool.createImplicitInitialValue());
+            }
+        }
+        if (properties[i] == CSSPropertyBackgroundPosition) {
+            addProperty(CSSPropertyBackgroundPositionX, WTFMove(values[i]), important);
+            // it's OK to call WTFMove(positionYValue) since we only see CSSPropertyBackgroundPosition once
+            addProperty(CSSPropertyBackgroundPositionY, WTFMove(positionYValue), important);
+        } else if (properties[i] == CSSPropertyWebkitMaskPosition) {
+            addProperty(CSSPropertyWebkitMaskPositionX, WTFMove(values[i]), important);
+            // it's OK to call WTFMove(positionYValue) since we only see CSSPropertyWebkitMaskPosition once
+            addProperty(CSSPropertyWebkitMaskPositionY, WTFMove(positionYValue), important);
+        } else if (properties[i] == CSSPropertyBackgroundRepeat) {
+            addProperty(CSSPropertyBackgroundRepeatX, WTFMove(values[i]), important);
+            // it's OK to call WTFMove(repeatYValue) since we only see CSSPropertyBackgroundPosition once
+            addProperty(CSSPropertyBackgroundRepeatY, WTFMove(repeatYValue), important);
+        } else if (properties[i] == CSSPropertyWebkitMaskRepeat) {
+            addProperty(CSSPropertyWebkitMaskRepeatX, WTFMove(values[i]), important);
+            // it's OK to call WTFMove(repeatYValue) since we only see CSSPropertyBackgroundPosition once
+            addProperty(CSSPropertyWebkitMaskRepeatY, WTFMove(repeatYValue), important);
+        } else if ((properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) &amp;&amp; !foundClip)
+            // Value is already set while updating origin
+            continue;
+        else if (properties[i] == CSSPropertyBackgroundSize &amp;&amp; !parsedProperty[i] &amp;&amp; useLegacyBackgroundSizeShorthandBehavior())
+            continue;
+        else
+            addProperty(properties[i], WTFMove(values[i]), important);
+
+        // Add in clip values when we hit the corresponding origin property.
+        if (properties[i] == CSSPropertyBackgroundOrigin &amp;&amp; !foundClip)
+            addProperty(CSSPropertyBackgroundClip, WTFMove(clipValue), important);
+        else if (properties[i] == CSSPropertyWebkitMaskOrigin &amp;&amp; !foundClip)
+            addProperty(CSSPropertyWebkitMaskClip, WTFMove(clipValue), important);
+    }
+
+    return true;
+}
+
+void CSSParser::addAnimationValue(RefPtr&lt;CSSValue&gt;&amp; lval, Ref&lt;CSSValue&gt;&amp;&amp; rval)
+{
+    if (!lval) {
+        lval = WTFMove(rval);
+        return;
+    }
+
+    if (is&lt;CSSValueList&gt;(*lval)) {
+        downcast&lt;CSSValueList&gt;(*lval).append(WTFMove(rval));
+        return;
+    }
+
+    auto list = CSSValueList::createCommaSeparated();
+    list-&gt;append(lval.releaseNonNull());
+    list-&gt;append(WTFMove(rval));
+    lval = WTFMove(list);
+}
+
+bool CSSParser::parseAnimationShorthand(CSSPropertyID propId, bool important)
+{
+    ASSERT(propId == CSSPropertyAnimation || propId == CSSPropertyWebkitAnimation);
+
+    const unsigned numProperties = 8;
+    const StylePropertyShorthand&amp; shorthand = animationShorthandForParsing(propId);
+
+    // The list of properties in the shorthand should be the same
+    // length as the list with animation name in last position, even though they are
+    // in a different order.
+    ASSERT(numProperties == shorthand.length());
+    ASSERT(numProperties == animationShorthand().length());
+    ASSERT(numProperties == webkitAnimationShorthand().length());
+
+    ShorthandScope scope(this, propId);
+
+    bool parsedProperty[numProperties] = { false };
+    AnimationParseContext context;
+    RefPtr&lt;CSSValue&gt; values[numProperties];
+
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    unsigned i;
+    while (m_valueList-&gt;current()) {
+        CSSParserValue* val = m_valueList-&gt;current();
+        if (val-&gt;unit == CSSParserValue::Operator &amp;&amp; val-&gt;iValue == ',') {
+            // We hit the end.  Fill in all remaining values with the initial value.
+            m_valueList-&gt;next();
+            for (i = 0; i &lt; numProperties; ++i) {
+                if (!parsedProperty[i])
+                    addAnimationValue(values[i], cssValuePool.createImplicitInitialValue());
+                parsedProperty[i] = false;
+            }
+            if (!m_valueList-&gt;current())
+                break;
+            context.commitFirstAnimation();
+        }
+
+        bool found = false;
+        for (i = 0; i &lt; numProperties; ++i) {
+            if (!parsedProperty[i]) {
+                RefPtr&lt;CSSValue&gt; val;
+                if (parseAnimationProperty(shorthand.properties()[i], val, context)) {
+                    parsedProperty[i] = found = true;
+                    addAnimationValue(values[i], val.releaseNonNull());
+                    break;
+                }
+            }
+
+            // There are more values to process but 'none' or 'all' were already defined as the animation property, the declaration becomes invalid.
+            if (!context.animationPropertyKeywordAllowed() &amp;&amp; context.hasCommittedFirstAnimation())
+                return false;
+        }
+
+        // if we didn't find at least one match, this is an
+        // invalid shorthand and we have to ignore it
+        if (!found)
+            return false;
+    }
+
+    // Fill in any remaining properties with the initial value.
+    for (i = 0; i &lt; numProperties; ++i) {
+        if (!parsedProperty[i])
+            addAnimationValue(values[i], cssValuePool.createImplicitInitialValue());
+    }
+
+    // Now add all of the properties we found.
+    // In this case we have to explicitly set the variant form as well,
+    // to make sure that a shorthand clears all existing prefixed and
+    // unprefixed values.
+    for (i = 0; i &lt; numProperties; ++i)
+        addPropertyWithPrefixingVariant(shorthand.properties()[i], WTFMove(values[i]), important);
+
+    return true;
+}
+
+void CSSParser::addPropertyWithPrefixingVariant(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp;&amp; value, bool important, bool implicit)
+{
+    addProperty(propId, value.copyRef(), important, implicit);
+
+    CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(propId);
+    if (prefixingVariant == propId)
+        return;
+
+    if (m_currentShorthand) {
+        // We can't use ShorthandScope here as we can already be inside one (e.g we are parsing CSSTransition).
+        m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
+        addProperty(prefixingVariant, WTFMove(value), important, implicit);
+        m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
+    } else
+        addProperty(prefixingVariant, WTFMove(value), important, implicit);
+}
+
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseColumnWidth()
+{
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+    CSSValueID id = valueWithCalculation.value().id;
+    // Always parse this property in strict mode, since it would be ambiguous otherwise when used in the 'columns' shorthand property.
+    if (id != CSSValueAuto &amp;&amp; !(validateUnit(valueWithCalculation, FLength | FNonNeg, CSSStrictMode) &amp;&amp; parsedDouble(valueWithCalculation)))
+        return nullptr;
+
+    auto parsedValue = parseValidPrimitive(id, valueWithCalculation);
+    m_valueList-&gt;next();
+    return parsedValue;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseColumnCount()
+{
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+    CSSValueID id = valueWithCalculation.value().id;
+
+    if (id != CSSValueAuto &amp;&amp; !validateUnit(valueWithCalculation, FPositiveInteger, CSSQuirksMode))
+        return nullptr;
+
+    auto parsedValue = parseValidPrimitive(id, valueWithCalculation);
+    m_valueList-&gt;next();
+    return parsedValue;
+}
+
+bool CSSParser::parseColumnsShorthand(bool important)
+{
+    RefPtr&lt;CSSValue&gt; columnWidth;
+    RefPtr&lt;CSSValue&gt; columnCount;
+    bool hasPendingExplicitAuto = false;
+
+    for (unsigned propertiesParsed = 0; CSSParserValue* value = m_valueList-&gt;current(); ++propertiesParsed) {
+        if (propertiesParsed &gt;= 2)
+            return false; // Too many values for this shorthand. Invalid declaration.
+        if (!propertiesParsed &amp;&amp; value-&gt;id == CSSValueAuto) {
+            // 'auto' is a valid value for any of the two longhands, and at this point
+            // we don't know which one(s) it is meant for. We need to see if there are other values first.
+            m_valueList-&gt;next();
+            hasPendingExplicitAuto = true;
+        } else {
+            if (!columnWidth) {
+                if ((columnWidth = parseColumnWidth()))
+                    continue;
+            }
+            if (!columnCount) {
+                if ((columnCount = parseColumnCount()))
+                    continue;
+            }
+            // If we didn't find at least one match, this is an invalid shorthand and we have to ignore it.
+            return false;
+        }
+    }
+
+    // Any unassigned property at this point will become implicit 'auto'.
+    if (columnWidth)
+        addProperty(CSSPropertyColumnWidth, WTFMove(columnWidth), important);
+    else {
+        addProperty(CSSPropertyColumnWidth, CSSValuePool::singleton().createIdentifierValue(CSSValueAuto), important, !hasPendingExplicitAuto /* implicit */);
+        hasPendingExplicitAuto = false;
+    }
+
+    if (columnCount)
+        addProperty(CSSPropertyColumnCount, WTFMove(columnCount), important);
+    else
+        addProperty(CSSPropertyColumnCount, CSSValuePool::singleton().createIdentifierValue(CSSValueAuto), important, !hasPendingExplicitAuto /* implicit */);
+
+    return true;
+}
+
+bool CSSParser::parseTransitionShorthand(CSSPropertyID propId, bool important)
+{
+    const unsigned numProperties = 4;
+    const StylePropertyShorthand&amp; shorthand = shorthandForProperty(propId);
+    ASSERT(numProperties == shorthand.length());
+
+    ShorthandScope scope(this, propId);
+
+    bool parsedProperty[numProperties] = { false };
+    AnimationParseContext context;
+    RefPtr&lt;CSSValue&gt; values[numProperties];
+
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    unsigned i;
+    while (m_valueList-&gt;current()) {
+        CSSParserValue* val = m_valueList-&gt;current();
+        if (val-&gt;unit == CSSParserValue::Operator &amp;&amp; val-&gt;iValue == ',') {
+            // We hit the end. Fill in all remaining values with the initial value.
+            m_valueList-&gt;next();
+            for (i = 0; i &lt; numProperties; ++i) {
+                if (!parsedProperty[i])
+                    addAnimationValue(values[i], cssValuePool.createImplicitInitialValue());
+                parsedProperty[i] = false;
+            }
+            if (!m_valueList-&gt;current())
+                break;
+            context.commitFirstAnimation();
+        }
+
+        bool found = false;
+        for (i = 0; !found &amp;&amp; i &lt; numProperties; ++i) {
+            if (!parsedProperty[i]) {
+                RefPtr&lt;CSSValue&gt; val;
+                if (parseAnimationProperty(shorthand.properties()[i], val, context)) {
+                    parsedProperty[i] = found = true;
+                    addAnimationValue(values[i], val.releaseNonNull());
+                }
+
+                // There are more values to process but 'none' or 'all' were already defined as the animation property, the declaration becomes invalid.
+                if (!context.animationPropertyKeywordAllowed() &amp;&amp; context.hasCommittedFirstAnimation())
+                    return false;
+            }
+        }
+
+        // if we didn't find at least one match, this is an
+        // invalid shorthand and we have to ignore it
+        if (!found)
+            return false;
+    }
+
+    // Fill in any remaining properties with the initial value.
+    for (i = 0; i &lt; numProperties; ++i) {
+        if (!parsedProperty[i])
+            addAnimationValue(values[i], cssValuePool.createImplicitInitialValue());
+    }
+
+    // Now add all of the properties we found.
+    // In this case we have to explicitly set the variant form as well,
+    // to make sure that a shorthand clears all existing prefixed and
+    // unprefixed values.
+    for (i = 0; i &lt; numProperties; ++i)
+        addPropertyWithPrefixingVariant(shorthand.properties()[i], WTFMove(values[i]), important);
+
+    return true;
+}
+
+bool CSSParser::parseShorthand(CSSPropertyID propId, const StylePropertyShorthand&amp; shorthand, bool important)
+{
+    // We try to match as many properties as possible
+    // We set up an array of booleans to mark which property has been found,
+    // and we try to search for properties until it makes no longer any sense.
+    ShorthandScope scope(this, propId);
+
+    bool found = false;
+    unsigned propertiesParsed = 0;
+    bool propertyFound[6]= { false, false, false, false, false, false }; // 6 is enough size.
+
+    while (m_valueList-&gt;current()) {
+        found = false;
+        for (unsigned propIndex = 0; !found &amp;&amp; propIndex &lt; shorthand.length(); ++propIndex) {
+            if (!propertyFound[propIndex] &amp;&amp; parseValue(shorthand.properties()[propIndex], important)) {
+                    propertyFound[propIndex] = found = true;
+                    propertiesParsed++;
+            }
+        }
+
+        // if we didn't find at least one match, this is an
+        // invalid shorthand and we have to ignore it
+        if (!found)
+            return false;
+    }
+
+    if (propertiesParsed == shorthand.length())
+        return true;
+
+    // Fill in any remaining properties with the initial value.
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    ImplicitScope implicitScope(*this, PropertyImplicit);
+    const StylePropertyShorthand* propertiesForInitialization = shorthand.propertiesForInitialization();
+    for (unsigned i = 0; i &lt; shorthand.length(); ++i) {
+        if (propertyFound[i])
+            continue;
+
+        if (propertiesForInitialization) {
+            const StylePropertyShorthand&amp; initProperties = propertiesForInitialization[i];
+            for (unsigned propIndex = 0; propIndex &lt; initProperties.length(); ++propIndex)
+                addProperty(initProperties.properties()[propIndex], cssValuePool.createImplicitInitialValue(), important);
+        } else
+            addProperty(shorthand.properties()[i], cssValuePool.createImplicitInitialValue(), important);
+    }
+
+    return true;
+}
+
+bool CSSParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properties,  bool important)
+{
+    /* From the CSS 2 specs, 8.3
+     * If there is only one value, it applies to all sides. If there are two values, the top and
+     * bottom margins are set to the first value and the right and left margins are set to the second.
+     * If there are three values, the top is set to the first value, the left and right are set to the
+     * second, and the bottom is set to the third. If there are four values, they apply to the top,
+     * right, bottom, and left, respectively.
+     */
+
+    unsigned num = inShorthand() ? 1 : m_valueList-&gt;size();
+
+    ShorthandScope scope(this, propId);
+
+    // the order is top, right, bottom, left
+    switch (num) {
+        case 1: {
+            if (!parseValue(properties[0], important))
+                return false;
+            CSSValue* value = m_parsedProperties.last().value();
+            ImplicitScope implicitScope(*this, PropertyImplicit);
+            addProperty(properties[1], value, important);
+            addProperty(properties[2], value, important);
+            addProperty(properties[3], value, important);
+            break;
+        }
+        case 2: {
+            if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
+                return false;
+            CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
+            ImplicitScope implicitScope(*this, PropertyImplicit);
+            addProperty(properties[2], value, important);
+            value = m_parsedProperties[m_parsedProperties.size() - 2].value();
+            addProperty(properties[3], value, important);
+            break;
+        }
+        case 3: {
+            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important))
+                return false;
+            CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
+            ImplicitScope implicitScope(*this, PropertyImplicit);
+            addProperty(properties[3], value, important);
+            break;
+        }
+        case 4: {
+            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) ||
+                !parseValue(properties[2], important) || !parseValue(properties[3], important))
+                return false;
+            break;
+        }
+        default: {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// auto | &lt;identifier&gt;
+bool CSSParser::parsePage(CSSPropertyID propId, bool important)
+{
+    ASSERT(propId == CSSPropertyPage);
+
+    if (m_valueList-&gt;size() != 1)
+        return false;
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (!value)
+        return false;
+
+    if (value-&gt;id == CSSValueAuto) {
+        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
+        return true;
+    } else if (value-&gt;id == 0 &amp;&amp; value-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
+        addProperty(propId, createPrimitiveStringValue(*value), important);
+        return true;
+    }
+    return false;
+}
+
+// &lt;length&gt;{1,2} | auto | [ &lt;page-size&gt; || [ portrait | landscape] ]
+bool CSSParser::parseSize(CSSPropertyID propId, bool important)
+{
+    ASSERT(propId == CSSPropertySize);
+
+    if (m_valueList-&gt;size() &gt; 2)
+        return false;
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (!value)
+        return false;
+
+    auto parsedValues = CSSValueList::createSpaceSeparated();
+
+    // First parameter.
+    SizeParameterType paramType = parseSizeParameter(parsedValues, *value, None);
+    if (paramType == None)
+        return false;
+
+    // Second parameter, if any.
+    value = m_valueList-&gt;next();
+    if (value) {
+        paramType = parseSizeParameter(parsedValues, *value, paramType);
+        if (paramType == None)
+            return false;
+    }
+
+    addProperty(propId, WTFMove(parsedValues), important);
+    return true;
+}
+
+CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList&amp; parsedValues, CSSParserValue&amp; value, SizeParameterType prevParamType)
+{
+    switch (value.id) {
+    case CSSValueAuto:
+        if (prevParamType == None) {
+            parsedValues.append(CSSValuePool::singleton().createIdentifierValue(value.id));
+            return Auto;
+        }
+        return None;
+    case CSSValueLandscape:
+    case CSSValuePortrait:
+        if (prevParamType == None || prevParamType == PageSize) {
+            parsedValues.append(CSSValuePool::singleton().createIdentifierValue(value.id));
+            return Orientation;
+        }
+        return None;
+    case CSSValueA3:
+    case CSSValueA4:
+    case CSSValueA5:
+    case CSSValueB4:
+    case CSSValueB5:
+    case CSSValueLedger:
+    case CSSValueLegal:
+    case CSSValueLetter:
+        if (prevParamType == None || prevParamType == Orientation) {
+            // Normalize to Page Size then Orientation order by prepending.
+            // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (StyleResolver::applyPageSizeProperty).
+            parsedValues.prepend(CSSValuePool::singleton().createIdentifierValue(value.id));
+            return PageSize;
+        }
+        return None;
+    case CSSValueInvalid: {
+        ValueWithCalculation valueWithCalculation(value);
+        if (validateUnit(valueWithCalculation, FLength | FNonNeg) &amp;&amp; (prevParamType == None || prevParamType == Length)) {
+            parsedValues.append(createPrimitiveNumericValue(valueWithCalculation));
+            return Length;
+        }
+        return None;
+    }
+    default:
+        return None;
+    }
+}
+
+// [ &lt;string&gt; &lt;string&gt; ]+ | inherit | none
+// inherit and none are handled in parseValue.
+bool CSSParser::parseQuotes(CSSPropertyID propId, bool important)
+{
+    auto values = CSSValueList::createCommaSeparated();
+    while (CSSParserValue* value = m_valueList-&gt;current()) {
+        if (value-&gt;unit != CSSPrimitiveValue::CSS_STRING)
+            break;
+        values-&gt;append(CSSPrimitiveValue::create(value-&gt;string, CSSPrimitiveValue::CSS_STRING));
+        m_valueList-&gt;next();
+    }
+    if (values-&gt;length()) {
+        addProperty(propId, WTFMove(values), important);
+        m_valueList-&gt;next();
+        return true;
+    }
+    return false;
+}
+
+bool CSSParser::parseAlt(CSSPropertyID propID, bool important)
+{
+    CSSParserValue&amp; currentValue = *m_valueList-&gt;current();
+    RefPtr&lt;CSSValue&gt; parsedValue;
+
+    if (currentValue.unit == CSSPrimitiveValue::CSS_STRING)
+        parsedValue = createPrimitiveStringValue(currentValue);
+    else if (currentValue.unit == CSSParserValue::Function) {
+        CSSParserValueList* args = currentValue.function-&gt;args.get();
+        if (!args)
+            return false;
+        if (equalLettersIgnoringASCIICase(currentValue.function-&gt;name, &quot;attr(&quot;))
+            parsedValue = parseAttr(*args);
+    }
+    
+    if (parsedValue) {
+        addProperty(propID, parsedValue.releaseNonNull(), important);
+        m_valueList-&gt;next();
+        return true;
+    }
+
+    return false;
+}
+
+bool CSSParser::parseCustomPropertyDeclaration(bool important, CSSValueID id)
+{
+    if (m_customPropertyName.isEmpty() || !m_valueList)
+        return false;
+    
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    RefPtr&lt;CSSValue&gt; value;
+    if (id == CSSValueInherit)
+        value = cssValuePool.createInheritedValue();
+    else if (id == CSSValueInitial)
+        value = cssValuePool.createExplicitInitialValue();
+    else if (id == CSSValueUnset)
+        value = cssValuePool.createUnsetValue();
+    else if (id == CSSValueRevert)
+        value = cssValuePool.createRevertValue();
+    else {
+        auto valueList = CSSValueList::createFromParserValueList(*m_valueList);
+        if (m_valueList-&gt;containsVariables())
+            value = CSSVariableDependentValue::create(WTFMove(valueList), CSSPropertyCustom);
+        else
+            value = WTFMove(valueList);
+    }
+
+    addProperty(CSSPropertyCustom, CSSCustomPropertyValue::create(m_customPropertyName, value.releaseNonNull()), important, false);
+    return true;
+}
+
+// [ &lt;string&gt; | &lt;uri&gt; | &lt;counter&gt; | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
+// in CSS 2.1 this got somewhat reduced:
+// [ &lt;string&gt; | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
+bool CSSParser::parseContent(CSSPropertyID propId, bool important)
+{
+    auto values = CSSValueList::createCommaSeparated();
+
+    while (CSSParserValue* value = m_valueList-&gt;current()) {
+        RefPtr&lt;CSSValue&gt; parsedValue;
+        if (value-&gt;unit == CSSPrimitiveValue::CSS_URI) {
+            // url
+            parsedValue = CSSImageValue::create(completeURL(value-&gt;string));
+        } else if (value-&gt;unit == CSSParserValue::Function) {
+            // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...)
+            CSSParserValueList* args = value-&gt;function-&gt;args.get();
+            if (!args)
+                return false;
+            if (equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;attr(&quot;)) {
+                parsedValue = parseAttr(*args);
+                if (!parsedValue)
+                    return false;
+            } else if (equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;counter(&quot;)) {
+                parsedValue = parseCounterContent(*args, false);
+                if (!parsedValue)
+                    return false;
+            } else if (equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;counters(&quot;)) {
+                parsedValue = parseCounterContent(*args, true);
+                if (!parsedValue)
+                    return false;
+            } else if (isImageSetFunctionValue(*value)) {
+                parsedValue = parseImageSet();
+                if (!parsedValue)
+                    return false;
+            } else if (isGeneratedImageValue(*value)) {
+                if (!parseGeneratedImage(*m_valueList, parsedValue))
+                    return false;
+            } else
+                return false;
+        } else if (value-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
+            // open-quote
+            // close-quote
+            // no-open-quote
+            // no-close-quote
+            // inherit
+            // FIXME: These are not yet implemented (http://bugs.webkit.org/show_bug.cgi?id=6503).
+            // none
+            // normal
+            switch (value-&gt;id) {
+            case CSSValueOpenQuote:
+            case CSSValueCloseQuote:
+            case CSSValueNoOpenQuote:
+            case CSSValueNoCloseQuote:
+            case CSSValueNone:
+            case CSSValueNormal:
+                parsedValue = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+                break;
+            default:
+                break;
+            }
+        } else if (value-&gt;unit == CSSPrimitiveValue::CSS_STRING) {
+            parsedValue = createPrimitiveStringValue(*value);
+        }
+        if (!parsedValue)
+            break;
+        values-&gt;append(parsedValue.releaseNonNull());
+        m_valueList-&gt;next();
+    }
+
+    if (values-&gt;length()) {
+        addProperty(propId, WTFMove(values), important);
+        m_valueList-&gt;next();
+        return true;
+    }
+
+    return false;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAttr(CSSParserValueList&amp; args)
+{
+    if (args.size() != 1)
+        return nullptr;
+
+    CSSParserValue&amp; argument = *args.current();
+
+    if (argument.unit != CSSPrimitiveValue::CSS_IDENT)
+        return nullptr;
+
+    ASSERT(argument.string.length());
+
+    // CSS allows identifiers with &quot;-&quot; at the start, like &quot;-webkit-mask-image&quot;.
+    // But HTML attribute names can't have those characters, and we should not
+    // even parse them inside attr().
+    if (argument.string[0] == '-')
+        return nullptr;
+
+    if (m_context.isHTMLDocument)
+        argument.string.convertToASCIILowercaseInPlace();
+
+    // FIXME: Is there some small benefit to creating an AtomicString here instead of a String?
+    return CSSValuePool::singleton().createValue(String(argument.string), CSSPrimitiveValue::CSS_ATTR);
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseBackgroundColor()
+{
+    CSSValueID id = m_valueList-&gt;current()-&gt;id;
+    if (id == CSSValueWebkitText || isValidSystemColorValue(id) || id == CSSValueMenu || id == CSSValueCurrentcolor
+        || (id &gt;= CSSValueGrey &amp;&amp; id &lt; CSSValueWebkitText &amp;&amp; inQuirksMode()))
+        return CSSValuePool::singleton().createIdentifierValue(id);
+    return parseColor();
+}
+
+bool CSSParser::parseFillImage(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; value)
+{
+    if (valueList.current()-&gt;id == CSSValueNone) {
+        value = CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
+        return true;
+    }
+    if (valueList.current()-&gt;unit == CSSPrimitiveValue::CSS_URI) {
+        value = CSSImageValue::create(completeURL(valueList.current()-&gt;string));
+        return true;
+    }
+
+    if (isGeneratedImageValue(*valueList.current()))
+        return parseGeneratedImage(valueList, value);
+    
+    if (isImageSetFunctionValue(*valueList.current())) {
+        value = parseImageSet();
+        if (value)
+            return true;
+    }
+
+    return false;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parsePositionX(CSSParserValueList&amp; valueList)
+{
+    int id = valueList.current()-&gt;id;
+    if (id == CSSValueLeft || id == CSSValueRight || id == CSSValueCenter) {
+        int percent = 0;
+        if (id == CSSValueRight)
+            percent = 100;
+        else if (id == CSSValueCenter)
+            percent = 50;
+        return CSSValuePool::singleton().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+    }
+    ValueWithCalculation valueWithCalculation(*valueList.current());
+    if (validateUnit(valueWithCalculation, FPercent | FLength))
+        return createPrimitiveNumericValue(valueWithCalculation);
+    return nullptr;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parsePositionY(CSSParserValueList&amp; valueList)
+{
+    int id = valueList.current()-&gt;id;
+    if (id == CSSValueTop || id == CSSValueBottom || id == CSSValueCenter) {
+        int percent = 0;
+        if (id == CSSValueBottom)
+            percent = 100;
+        else if (id == CSSValueCenter)
+            percent = 50;
+        return CSSValuePool::singleton().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+    }
+    ValueWithCalculation valueWithCalculation(*valueList.current());
+    if (validateUnit(valueWithCalculation, FPercent | FLength))
+        return createPrimitiveNumericValue(valueWithCalculation);
+    return nullptr;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseFillPositionComponent(CSSParserValueList&amp; valueList, unsigned&amp; cumulativeFlags, FillPositionFlag&amp; individualFlag, FillPositionParsingMode parsingMode)
+{
+    CSSValueID id = valueList.current()-&gt;id;
+    if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) {
+        int percent = 0;
+        if (id == CSSValueLeft || id == CSSValueRight) {
+            if (cumulativeFlags &amp; XFillPosition)
+                return nullptr;
+            cumulativeFlags |= XFillPosition;
+            individualFlag = XFillPosition;
+            if (id == CSSValueRight)
+                percent = 100;
+        }
+        else if (id == CSSValueTop || id == CSSValueBottom) {
+            if (cumulativeFlags &amp; YFillPosition)
+                return nullptr;
+            cumulativeFlags |= YFillPosition;
+            individualFlag = YFillPosition;
+            if (id == CSSValueBottom)
+                percent = 100;
+        } else if (id == CSSValueCenter) {
+            // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
+            percent = 50;
+            cumulativeFlags |= AmbiguousFillPosition;
+            individualFlag = AmbiguousFillPosition;
+        }
+
+        if (parsingMode == ResolveValuesAsKeyword)
+            return CSSValuePool::singleton().createIdentifierValue(id);
+
+        return CSSValuePool::singleton().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+    }
+    ValueWithCalculation valueWithCalculation(*valueList.current());
+    if (!validateUnit(valueWithCalculation, FPercent | FLength))
+        return nullptr;
+
+    if (!cumulativeFlags) {
+        cumulativeFlags |= XFillPosition;
+        individualFlag = XFillPosition;
+    } else if (cumulativeFlags &amp; (XFillPosition | AmbiguousFillPosition)) {
+        cumulativeFlags |= YFillPosition;
+        individualFlag = YFillPosition;
+    } else
+        return nullptr;
+    return createPrimitiveNumericValue(valueWithCalculation);
+}
+
+static bool isValueConflictingWithCurrentEdge(int value1, int value2)
+{
+    if ((value1 == CSSValueLeft || value1 == CSSValueRight) &amp;&amp; (value2 == CSSValueLeft || value2 == CSSValueRight))
+        return true;
+
+    if ((value1 == CSSValueTop || value1 == CSSValueBottom) &amp;&amp; (value2 == CSSValueTop || value2 == CSSValueBottom))
+        return true;
+
+    return false;
+}
+
+static bool isFillPositionKeyword(CSSValueID value)
+{
+    return value == CSSValueLeft || value == CSSValueTop || value == CSSValueBottom || value == CSSValueRight || value == CSSValueCenter;
+}
+
+void CSSParser::parse4ValuesFillPosition(CSSParserValueList&amp; valueList, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp; parsedValue1, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp; parsedValue2)
+{
+    // [ left | right ] [ &lt;percentage] | &lt;length&gt; ] &amp;&amp; [ top | bottom ] [ &lt;percentage&gt; | &lt;length&gt; ]
+    // In the case of 4 values &lt;position&gt; requires the second value to be a length or a percentage.
+    if (isFillPositionKeyword(parsedValue2-&gt;getValueID()))
+        return;
+
+    unsigned cumulativeFlags = 0;
+    FillPositionFlag value3Flag = InvalidFillPosition;
+    auto value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
+    if (!value3)
+        return;
+
+    CSSValueID ident1 = parsedValue1-&gt;getValueID();
+    CSSValueID ident3 = value3-&gt;getValueID();
+
+    if (ident1 == CSSValueCenter)
+        return;
+
+    if (!isFillPositionKeyword(ident3) || ident3 == CSSValueCenter)
+        return;
+
+    // We need to check if the values are not conflicting, e.g. they are not on the same edge. It is
+    // needed as the second call to parseFillPositionComponent was on purpose not checking it. In the
+    // case of two values top 20px is invalid but in the case of 4 values it becomes valid.
+    if (isValueConflictingWithCurrentEdge(ident1, ident3))
+        return;
+
+    valueList.next();
+
+    cumulativeFlags = 0;
+    FillPositionFlag value4Flag = InvalidFillPosition;
+    auto value4 = parseFillPositionComponent(valueList, cumulativeFlags, value4Flag, ResolveValuesAsKeyword);
+    if (!value4)
+        return;
+
+    // 4th value must be a length or a percentage.
+    if (isFillPositionKeyword(value4-&gt;getValueID()))
+        return;
+
+    value1 = createPrimitiveValuePair(WTFMove(parsedValue1), WTFMove(parsedValue2));
+    value2 = createPrimitiveValuePair(value3.releaseNonNull(), value4.releaseNonNull());
+
+    if (ident1 == CSSValueTop || ident1 == CSSValueBottom)
+        value1.swap(value2);
+
+    valueList.next();
+}
+
+void CSSParser::parse3ValuesFillPosition(CSSParserValueList&amp; valueList, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp; parsedValue1, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp; parsedValue2)
+{
+    unsigned cumulativeFlags = 0;
+    FillPositionFlag value3Flag = InvalidFillPosition;
+    auto value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
+
+    // value3 is not an expected value, we return.
+    if (!value3)
+        return;
+
+    valueList.next();
+
+    bool swapNeeded = false;
+    CSSValueID ident1 = parsedValue1-&gt;getValueID();
+    CSSValueID ident2 = parsedValue2-&gt;getValueID();
+    CSSValueID ident3 = value3-&gt;getValueID();
+
+    CSSValueID firstPositionKeyword;
+    CSSValueID secondPositionKeyword;
+
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    if (ident1 == CSSValueCenter) {
+        // &lt;position&gt; requires the first 'center' to be followed by a keyword.
+        if (!isFillPositionKeyword(ident2))
+            return;
+
+        // If 'center' is the first keyword then the last one needs to be a length.
+        if (isFillPositionKeyword(ident3))
+            return;
+
+        firstPositionKeyword = CSSValueLeft;
+        if (ident2 == CSSValueLeft || ident2 == CSSValueRight) {
+            firstPositionKeyword = CSSValueTop;
+            swapNeeded = true;
+        }
+        value1 = createPrimitiveValuePair(cssValuePool.createIdentifierValue(firstPositionKeyword), cssValuePool.createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+        value2 = createPrimitiveValuePair(WTFMove(parsedValue2), value3.copyRef());
+    } else if (ident3 == CSSValueCenter) {
+        if (isFillPositionKeyword(ident2))
+            return;
+
+        secondPositionKeyword = CSSValueTop;
+        if (ident1 == CSSValueTop || ident1 == CSSValueBottom) {
+            secondPositionKeyword = CSSValueLeft;
+            swapNeeded = true;
+        }
+        value1 = createPrimitiveValuePair(WTFMove(parsedValue1), parsedValue2.copyRef());
+        value2 = createPrimitiveValuePair(cssValuePool.createIdentifierValue(secondPositionKeyword), cssValuePool.createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+    } else {
+        RefPtr&lt;CSSPrimitiveValue&gt; firstPositionValue;
+        RefPtr&lt;CSSPrimitiveValue&gt; secondPositionValue;
+
+        if (isFillPositionKeyword(ident2)) {
+            // To match CSS grammar, we should only accept: [ center | left | right | bottom | top ] [ left | right | top | bottom ] [ &lt;percentage&gt; | &lt;length&gt; ].
+            ASSERT(ident2 != CSSValueCenter);
+
+            if (isFillPositionKeyword(ident3))
+                return;
+
+            secondPositionValue = value3;
+            secondPositionKeyword = ident2;
+            firstPositionValue = cssValuePool.createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
+        } else {
+            // Per CSS, we should only accept: [ right | left | top | bottom ] [ &lt;percentage&gt; | &lt;length&gt; ] [ center | left | right | bottom | top ].
+            if (!isFillPositionKeyword(ident3))
+                return;
+
+            firstPositionValue = parsedValue2.ptr();
+            secondPositionKeyword = ident3;
+            secondPositionValue = cssValuePool.createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
+        }
+
+        if (isValueConflictingWithCurrentEdge(ident1, secondPositionKeyword))
+            return;
+
+        value1 = createPrimitiveValuePair(WTFMove(parsedValue1), firstPositionValue.releaseNonNull());
+        value2 = createPrimitiveValuePair(cssValuePool.createIdentifierValue(secondPositionKeyword), secondPositionValue.releaseNonNull());
+    }
+
+    if (ident1 == CSSValueTop || ident1 == CSSValueBottom || swapNeeded)
+        value1.swap(value2);
+
+#ifndef NDEBUG
+    CSSPrimitiveValue&amp; first = *value1;
+    CSSPrimitiveValue&amp; second = *value2;
+    ident1 = first.getPairValue()-&gt;first()-&gt;getValueID();
+    ident2 = second.getPairValue()-&gt;first()-&gt;getValueID();
+    ASSERT(ident1 == CSSValueLeft || ident1 == CSSValueRight);
+    ASSERT(ident2 == CSSValueBottom || ident2 == CSSValueTop);
+#endif
+}
+
+inline bool CSSParser::isPotentialPositionValue(CSSParserValue&amp; value)
+{
+    if (isFillPositionKeyword(value.id))
+        return true;
+    ValueWithCalculation valueWithCalculation(value);
+    return validateUnit(valueWithCalculation, FPercent | FLength);
+}
+
+void CSSParser::parseFillPosition(CSSParserValueList&amp; valueList, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2)
+{
+    unsigned numberOfValues = 0;
+    for (unsigned i = valueList.currentIndex(); i &lt; valueList.size(); ++i, ++numberOfValues) {
+        CSSParserValue* current = valueList.valueAt(i);
+        if (!current || isComma(current) || isForwardSlashOperator(*current) || !isPotentialPositionValue(*current))
+            break;
+    }
+
+    if (numberOfValues &gt; 4)
+        return;
+
+    // If we are parsing two values, we can safely call the CSS 2.1 parsing function and return.
+    if (numberOfValues &lt;= 2) {
+        parse2ValuesFillPosition(valueList, value1, value2);
+        return;
+    }
+
+    ASSERT(numberOfValues &gt; 2 &amp;&amp; numberOfValues &lt;= 4);
+
+    CSSParserValue* value = valueList.current();
+
+    // &lt;position&gt; requires the first value to be a background keyword.
+    if (!isFillPositionKeyword(value-&gt;id))
+        return;
+
+    // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
+    unsigned cumulativeFlags = 0;
+    FillPositionFlag value1Flag = InvalidFillPosition;
+    FillPositionFlag value2Flag = InvalidFillPosition;
+    value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag, ResolveValuesAsKeyword);
+    if (!value1)
+        return;
+
+    value = valueList.next();
+
+    // In case we are parsing more than two values, relax the check inside of parseFillPositionComponent. top 20px is
+    // a valid start for &lt;position&gt;.
+    cumulativeFlags = AmbiguousFillPosition;
+    value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag, ResolveValuesAsKeyword);
+    if (value2)
+        valueList.next();
+    else {
+        value1 = nullptr;
+        return;
+    }
+
+    auto parsedValue1 = value1.releaseNonNull();
+    auto parsedValue2 = value2.releaseNonNull();
+
+    // Per CSS3 syntax, &lt;position&gt; can't have 'center' as its second keyword as we have more arguments to follow.
+    if (parsedValue2-&gt;getValueID() == CSSValueCenter)
+        return;
+
+    if (numberOfValues == 3)
+        parse3ValuesFillPosition(valueList, value1, value2, WTFMove(parsedValue1), WTFMove(parsedValue2));
+    else
+        parse4ValuesFillPosition(valueList, value1, value2, WTFMove(parsedValue1), WTFMove(parsedValue2));
+}
+
+void CSSParser::parse2ValuesFillPosition(CSSParserValueList&amp; valueList, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2)
+{
+    CSSParserValue* value = valueList.current();
+
+    // Parse the first value.  We're just making sure that it is one of the valid keywords or a percentage/length.
+    unsigned cumulativeFlags = 0;
+    FillPositionFlag value1Flag = InvalidFillPosition;
+    FillPositionFlag value2Flag = InvalidFillPosition;
+    value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag);
+    if (!value1)
+        return;
+
+    // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we
+    // can assume that any other values belong to the rest of the shorthand).  If we're not parsing a shorthand, though, the
+    // value was explicitly specified for our property.
+    value = valueList.next();
+
+    // First check for the comma.  If so, we are finished parsing this value or value pair.
+    if (isComma(value))
+        value = nullptr;
+
+    if (value) {
+        value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag);
+        if (value2)
+            valueList.next();
+        else {
+            if (!inShorthand()) {
+                value1 = nullptr;
+                return;
+            }
+        }
+    }
+
+    if (!value2)
+        // Only one value was specified. If that value was not a keyword, then it sets the x position, and the y position
+        // is simply 50%. This is our default.
+        // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
+        // For left/right/center, the default of 50% in the y is still correct.
+        value2 = CSSValuePool::singleton().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
+
+    if (value1Flag == YFillPosition || value2Flag == XFillPosition)
+        value1.swap(value2);
+}
+
+void CSSParser::parseFillRepeat(RefPtr&lt;CSSValue&gt;&amp; value1, RefPtr&lt;CSSValue&gt;&amp; value2)
+{
+    CSSValueID id = m_valueList-&gt;current()-&gt;id;
+    if (id == CSSValueRepeatX) {
+        m_implicitShorthand = true;
+        value1 = CSSValuePool::singleton().createIdentifierValue(CSSValueRepeat);
+        value2 = CSSValuePool::singleton().createIdentifierValue(CSSValueNoRepeat);
+        m_valueList-&gt;next();
+        return;
+    }
+    if (id == CSSValueRepeatY) {
+        m_implicitShorthand = true;
+        value1 = CSSValuePool::singleton().createIdentifierValue(CSSValueNoRepeat);
+        value2 = CSSValuePool::singleton().createIdentifierValue(CSSValueRepeat);
+        m_valueList-&gt;next();
+        return;
+    }
+    if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)
+        value1 = CSSValuePool::singleton().createIdentifierValue(id);
+    else {
+        value1 = nullptr;
+        return;
+    }
+
+    CSSParserValue* value = m_valueList-&gt;next();
+
+    // Parse the second value if one is available
+    if (value &amp;&amp; !isComma(value)) {
+        id = value-&gt;id;
+        if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) {
+            value2 = CSSValuePool::singleton().createIdentifierValue(id);
+            m_valueList-&gt;next();
+            return;
+        }
+    }
+
+    // If only one value was specified, value2 is the same as value1.
+    m_implicitShorthand = true;
+    value2 = CSSValuePool::singleton().createIdentifierValue(downcast&lt;CSSPrimitiveValue&gt;(*value1).getValueID());
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseFillSize(CSSPropertyID propId, bool&amp; allowComma)
+{
+    allowComma = true;
+    CSSParserValue* value = m_valueList-&gt;current();
+
+    if (value-&gt;id == CSSValueContain || value-&gt;id == CSSValueCover)
+        return CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+
+    RefPtr&lt;CSSPrimitiveValue&gt; parsedValue1;
+
+    if (value-&gt;id == CSSValueAuto)
+        parsedValue1 = CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
+    else {
+        ValueWithCalculation valueWithCalculation(*value);
+        if (!validateUnit(valueWithCalculation, FLength | FPercent))
+            return nullptr;
+        parsedValue1 = createPrimitiveNumericValue(valueWithCalculation);
+    }
+
+    RefPtr&lt;CSSPrimitiveValue&gt; parsedValue2;
+    if ((value = m_valueList-&gt;next())) {
+        if (value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')
+            allowComma = false;
+        else if (value-&gt;id != CSSValueAuto) {
+            ValueWithCalculation valueWithCalculation(*value);
+            if (!validateUnit(valueWithCalculation, FLength | FPercent)) {
+                if (!inShorthand())
+                    return nullptr;
+                // We need to rewind the value list, so that when it is advanced we'll end up back at this value.
+                m_valueList-&gt;previous();
+            } else
+                parsedValue2 = createPrimitiveNumericValue(valueWithCalculation);
+        }
+    } else if (!parsedValue2 &amp;&amp; propId == CSSPropertyWebkitBackgroundSize) {
+        // For backwards compatibility we set the second value to the first if it is omitted.
+        // We only need to do this for -webkit-background-size. It should be safe to let masks match
+        // the real property.
+        parsedValue2 = parsedValue1;
+    }
+
+    if (!parsedValue2)
+        return parsedValue1;
+    return createPrimitiveValuePair(parsedValue1.releaseNonNull(), parsedValue2.releaseNonNull(), propId == CSSPropertyWebkitBackgroundSize ? Pair::IdenticalValueEncoding::Coalesce : Pair::IdenticalValueEncoding::DoNotCoalesce);
+}
+
+bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2,
+                                  RefPtr&lt;CSSValue&gt;&amp; retValue1, RefPtr&lt;CSSValue&gt;&amp; retValue2)
+{
+    RefPtr&lt;CSSValueList&gt; values;
+    RefPtr&lt;CSSValueList&gt; values2;
+    CSSParserValue* currentValue;
+    RefPtr&lt;CSSValue&gt; value;
+    RefPtr&lt;CSSValue&gt; value2;
+
+    bool allowComma = false;
+
+    retValue1 = retValue2 = nullptr;
+    propId1 = propId;
+    propId2 = propId;
+    if (propId == CSSPropertyBackgroundPosition) {
+        propId1 = CSSPropertyBackgroundPositionX;
+        propId2 = CSSPropertyBackgroundPositionY;
+    } else if (propId == CSSPropertyWebkitMaskPosition) {
+        propId1 = CSSPropertyWebkitMaskPositionX;
+        propId2 = CSSPropertyWebkitMaskPositionY;
+    } else if (propId == CSSPropertyBackgroundRepeat) {
+        propId1 = CSSPropertyBackgroundRepeatX;
+        propId2 = CSSPropertyBackgroundRepeatY;
+    } else if (propId == CSSPropertyWebkitMaskRepeat) {
+        propId1 = CSSPropertyWebkitMaskRepeatX;
+        propId2 = CSSPropertyWebkitMaskRepeatY;
+    }
+
+    while ((currentValue = m_valueList-&gt;current())) {
+        RefPtr&lt;CSSValue&gt; currValue;
+        RefPtr&lt;CSSValue&gt; currValue2;
+
+        if (allowComma) {
+            if (!isComma(currentValue))
+                return false;
+            m_valueList-&gt;next();
+            allowComma = false;
+        } else {
+            allowComma = true;
+            switch (propId) {
+                case CSSPropertyBackgroundColor:
+                    currValue = parseBackgroundColor();
+                    if (currValue)
+                        m_valueList-&gt;next();
+                    break;
+                case CSSPropertyBackgroundAttachment:
+                    if (currentValue-&gt;id == CSSValueScroll || currentValue-&gt;id == CSSValueFixed || currentValue-&gt;id == CSSValueLocal) {
+                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
+                        m_valueList-&gt;next();
+                    }
+                    break;
+                case CSSPropertyBackgroundImage:
+                case CSSPropertyWebkitMaskImage:
+                    if (parseFillImage(*m_valueList, currValue))
+                        m_valueList-&gt;next();
+                    break;
+                case CSSPropertyWebkitBackgroundClip:
+                case CSSPropertyWebkitBackgroundOrigin:
+                case CSSPropertyWebkitMaskClip:
+                case CSSPropertyWebkitMaskOrigin:
+                    // The first three values here are deprecated and do not apply to the version of the property that has
+                    // the -webkit- prefix removed.
+                    if (currentValue-&gt;id == CSSValueBorder || currentValue-&gt;id == CSSValuePadding || currentValue-&gt;id == CSSValueContent
+                        || currentValue-&gt;id == CSSValueBorderBox || currentValue-&gt;id == CSSValuePaddingBox || currentValue-&gt;id == CSSValueContentBox
+                        || ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip)
+                        &amp;&amp; (currentValue-&gt;id == CSSValueText || currentValue-&gt;id == CSSValueWebkitText))) {
+                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
+                        m_valueList-&gt;next();
+                    }
+                    break;
+                case CSSPropertyBackgroundClip:
+                    if (parseBackgroundClip(*currentValue, currValue))
+                        m_valueList-&gt;next();
+                    break;
+                case CSSPropertyBackgroundOrigin:
+                    if (currentValue-&gt;id == CSSValueBorderBox || currentValue-&gt;id == CSSValuePaddingBox || currentValue-&gt;id == CSSValueContentBox) {
+                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
+                        m_valueList-&gt;next();
+                    }
+                    break;
+                case CSSPropertyBackgroundPosition:
+                case CSSPropertyWebkitMaskPosition: {
+                    RefPtr&lt;CSSPrimitiveValue&gt; value1;
+                    RefPtr&lt;CSSPrimitiveValue&gt; value2;
+                    parseFillPosition(*m_valueList, value1, value2);
+                    currValue = WTFMove(value1);
+                    currValue2 = WTFMove(value2);
+                    // parseFillPosition advances the m_valueList pointer.
+                    break;
+                }
+                case CSSPropertyBackgroundPositionX:
+                case CSSPropertyWebkitMaskPositionX: {
+                    currValue = parsePositionX(*m_valueList);
+                    if (currValue)
+                        m_valueList-&gt;next();
+                    break;
+                }
+                case CSSPropertyBackgroundPositionY:
+                case CSSPropertyWebkitMaskPositionY: {
+                    currValue = parsePositionY(*m_valueList);
+                    if (currValue)
+                        m_valueList-&gt;next();
+                    break;
+                }
+                case CSSPropertyWebkitBackgroundComposite:
+                case CSSPropertyWebkitMaskComposite:
+                    if (currentValue-&gt;id &gt;= CSSValueClear &amp;&amp; currentValue-&gt;id &lt;= CSSValuePlusLighter) {
+                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
+                        m_valueList-&gt;next();
+                    }
+                    break;
+                case CSSPropertyBackgroundBlendMode:
+                    if (currentValue-&gt;id == CSSValueNormal || currentValue-&gt;id == CSSValueMultiply
+                        || currentValue-&gt;id == CSSValueScreen || currentValue-&gt;id == CSSValueOverlay || currentValue-&gt;id == CSSValueDarken
+                        || currentValue-&gt;id == CSSValueLighten ||  currentValue-&gt;id == CSSValueColorDodge || currentValue-&gt;id == CSSValueColorBurn
+                        || currentValue-&gt;id == CSSValueHardLight || currentValue-&gt;id == CSSValueSoftLight || currentValue-&gt;id == CSSValueDifference
+                        || currentValue-&gt;id == CSSValueExclusion) {
+                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
+                        m_valueList-&gt;next();
+                    }
+                    break;
+                case CSSPropertyBackgroundRepeat:
+                case CSSPropertyWebkitMaskRepeat:
+                    parseFillRepeat(currValue, currValue2);
+                    // parseFillRepeat advances the m_valueList pointer
+                    break;
+                case CSSPropertyBackgroundSize:
+                case CSSPropertyWebkitBackgroundSize:
+                case CSSPropertyWebkitMaskSize: {
+                    currValue = parseFillSize(propId, allowComma);
+                    if (currValue)
+                        m_valueList-&gt;next();
+                    break;
+                }
+                case CSSPropertyWebkitMaskSourceType: {
+                    if (currentValue-&gt;id == CSSValueAuto || currentValue-&gt;id == CSSValueAlpha || currentValue-&gt;id == CSSValueLuminance) {
+                        currValue = CSSValuePool::singleton().createIdentifierValue(currentValue-&gt;id);
+                        m_valueList-&gt;next();
+                    } else
+                        currValue = nullptr;
+                    break;
+                }
+                default:
+                    break;
+            }
+            if (!currValue)
+                return false;
+
+            if (value &amp;&amp; !values) {
+                values = CSSValueList::createCommaSeparated();
+                values-&gt;append(value.releaseNonNull());
+            }
+
+            if (value2 &amp;&amp; !values2) {
+                values2 = CSSValueList::createCommaSeparated();
+                values2-&gt;append(value2.releaseNonNull());
+            }
+
+            if (values)
+                values-&gt;append(currValue.releaseNonNull());
+            else
+                value = WTFMove(currValue);
+            if (currValue2) {
+                if (values2)
+                    values2-&gt;append(currValue2.releaseNonNull());
+                else
+                    value2 = WTFMove(currValue2);
+            }
+        }
+
+        // When parsing any fill shorthand property, we let it handle building up the lists for all
+        // properties.
+        if (inShorthand())
+            break;
+    }
+
+    if (values &amp;&amp; values-&gt;length()) {
+        retValue1 = WTFMove(values);
+        if (values2 &amp;&amp; values2-&gt;length())
+            retValue2 = WTFMove(values2);
+        return true;
+    }
+    if (value) {
+        retValue1 = WTFMove(value);
+        retValue2 = WTFMove(value2);
+        return true;
+    }
+    return false;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationDelay()
+{
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+    if (validateUnit(valueWithCalculation, FTime))
+        return createPrimitiveNumericValue(valueWithCalculation);
+    return nullptr;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationDirection()
+{
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (value-&gt;id == CSSValueNormal || value-&gt;id == CSSValueAlternate || value-&gt;id == CSSValueReverse || value-&gt;id == CSSValueAlternateReverse)
+        return CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+    return nullptr;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationDuration()
+{
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+    if (validateUnit(valueWithCalculation, FTime | FNonNeg))
+        return createPrimitiveNumericValue(valueWithCalculation);
+    return nullptr;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationFillMode()
+{
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (value-&gt;id == CSSValueNone || value-&gt;id == CSSValueForwards || value-&gt;id == CSSValueBackwards || value-&gt;id == CSSValueBoth)
+        return CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+    return nullptr;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationIterationCount()
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    if (value.id == CSSValueInfinite)
+        return CSSValuePool::singleton().createIdentifierValue(value.id);
+    ValueWithCalculation valueWithCalculation(value);
+    if (validateUnit(valueWithCalculation, FNumber | FNonNeg))
+        return createPrimitiveNumericValue(valueWithCalculation);
+    return nullptr;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationName()
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    if (value.unit == CSSPrimitiveValue::CSS_STRING || value.unit == CSSPrimitiveValue::CSS_IDENT) {
+        if (value.id == CSSValueNone || (value.unit == CSSPrimitiveValue::CSS_STRING &amp;&amp; equalLettersIgnoringASCIICase(value, &quot;none&quot;))) {
+            return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
+        }
+        return createPrimitiveStringValue(value);
+    }
+    return nullptr;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationPlayState()
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    if (value.id == CSSValueRunning || value.id == CSSValuePaused)
+        return CSSValuePool::singleton().createIdentifierValue(value.id);
+    return nullptr;
+}
+
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+RefPtr&lt;CSSValue&gt; CSSParser::parseAnimationTrigger()
+{
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (value-&gt;id == CSSValueAuto)
+        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
+
+    if (value-&gt;unit != CSSParserValue::Function)
+        return nullptr;
+
+    CSSParserValueList* args = value-&gt;function-&gt;args.get();
+
+    if (equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;container-scroll(&quot;)) {
+        if (!args || (args-&gt;size() != 1 &amp;&amp; args-&gt;size() != 3))
+            return nullptr;
+
+        CSSParserValue* argument = args-&gt;current();
+        ValueWithCalculation firstArgumentWithCalculation(*argument);
+        if (!validateUnit(firstArgumentWithCalculation, FLength))
+            return nullptr;
+
+        auto startValue = createPrimitiveNumericValue(firstArgumentWithCalculation);
+
+        argument = args-&gt;next();
+
+        if (!argument)
+            return CSSAnimationTriggerScrollValue::create(WTFMove(startValue));
+
+        if (!isComma(argument))
+            return nullptr;
+
+        argument = args-&gt;next();
+        ValueWithCalculation secondArgumentWithCalculation(*argument);
+        if (!validateUnit(secondArgumentWithCalculation, FLength))
+            return nullptr;
+
+        auto endValue = createPrimitiveNumericValue(secondArgumentWithCalculation);
+
+        return CSSAnimationTriggerScrollValue::create(WTFMove(startValue), WTFMove(endValue));
+    }
+
+    return nullptr;
+}
+#endif
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseAnimationProperty(AnimationParseContext&amp; context)
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    if (value.unit != CSSPrimitiveValue::CSS_IDENT)
+        return nullptr;
+    CSSPropertyID result = cssPropertyID(value.string);
+    if (result &amp;&amp; result != CSSPropertyAll) // &quot;all&quot; value in animation is not equivalent to the all property.
+        return CSSValuePool::singleton().createIdentifierValue(result);
+    if (equalLettersIgnoringASCIICase(value, &quot;all&quot;)) {
+        context.sawAnimationPropertyKeyword();
+        return CSSValuePool::singleton().createIdentifierValue(CSSValueAll);
+    }
+    if (equalLettersIgnoringASCIICase(value, &quot;none&quot;)) {
+        context.commitAnimationPropertyKeyword();
+        context.sawAnimationPropertyKeyword();
+        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
+    }
+    return nullptr;
+}
+
+/* static */
+Vector&lt;double&gt; CSSParser::parseKeyframeSelector(const String&amp; selector) {
+    Vector&lt;double&gt; keys;
+    Vector&lt;String&gt; strings;
+    selector.split(',', strings);
+
+    keys.reserveInitialCapacity(strings.size());
+    for (size_t i = 0; i &lt; strings.size(); ++i) {
+        double key = -1;
+        String cur = strings[i].stripWhiteSpace();
+
+        // For now the syntax MUST be 'xxx%' or 'from' or 'to', where xxx is a legal floating point number
+        if (equalLettersIgnoringASCIICase(cur, &quot;from&quot;))
+            key = 0;
+        else if (equalLettersIgnoringASCIICase(cur, &quot;to&quot;))
+            key = 1;
+        else if (cur.endsWith('%')) {
+            double k = cur.substring(0, cur.length() - 1).toDouble();
+            if (k &gt;= 0 &amp;&amp; k &lt;= 100)
+                key = k / 100;
+        }
+        if (key &lt; 0) {
+            keys.clear();
+            break;
+        }
+        keys.uncheckedAppend(key);
+    }
+
+    return keys;
+}
+
+bool CSSParser::parseTransformOriginShorthand(RefPtr&lt;CSSPrimitiveValue&gt;&amp; value1, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2, RefPtr&lt;CSSValue&gt;&amp; value3)
+{
+    parse2ValuesFillPosition(*m_valueList, value1, value2);
+
+    // now get z
+    if (m_valueList-&gt;current()) {
+        ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+        if (validateUnit(valueWithCalculation, FLength)) {
+            value3 = createPrimitiveNumericValue(valueWithCalculation);
+            m_valueList-&gt;next();
+            return true;
+        }
+        return false;
+    }
+    value3 = CSSValuePool::singleton().createImplicitInitialValue();
+    return true;
+}
+
+bool CSSParser::isSpringTimingFunctionEnabled() const
+{
+    return m_context.springTimingFunctionEnabled;
+}
+
+Optional&lt;double&gt; CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList&amp; args)
+{
+    ValueWithCalculation argumentWithCalculation(*args.current());
+    if (!validateUnit(argumentWithCalculation, FNumber))
+        return Nullopt;
+    Optional&lt;double&gt; result = parsedDouble(argumentWithCalculation);
+    CSSParserValue* nextValue = args.next();
+    if (!nextValue) {
+        // The last number in the function has no comma after it, so we're done.
+        return result;
+    }
+    if (!isComma(nextValue))
+        return Nullopt;
+    args.next();
+    return result;
+}
+
+Optional&lt;double&gt; CSSParser::parseSpringTimingFunctionValue(CSSParserValueList&amp; args)
+{
+    ValueWithCalculation argumentWithCalculation(*args.current());
+    if (!validateUnit(argumentWithCalculation, FNumber))
+        return Nullopt;
+    Optional&lt;double&gt; result = parsedDouble(argumentWithCalculation);
+    args.next();
+    return result;
+}
+
+RefPtr&lt;CSSValue&gt; CSSParser::parseAnimationTimingFunction()
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    if (value.id == CSSValueEase || value.id == CSSValueLinear || value.id == CSSValueEaseIn || value.id == CSSValueEaseOut
+        || value.id == CSSValueEaseInOut || value.id == CSSValueStepStart || value.id == CSSValueStepEnd)
+        return CSSValuePool::singleton().createIdentifierValue(value.id);
+
+    // We must be a function.
+    if (value.unit != CSSParserValue::Function)
+        return nullptr;
+
+    CSSParserValueList* args = value.function-&gt;args.get();
+
+    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;steps(&quot;)) {
+        // For steps, 1 or 2 params must be specified (comma-separated)
+        if (!args || (args-&gt;size() != 1 &amp;&amp; args-&gt;size() != 3))
+            return nullptr;
+
+        // There are two values.
+        int numSteps;
+        bool stepAtStart = false;
+
+        CSSParserValue* argument = args-&gt;current();
+        ValueWithCalculation argumentWithCalculation(*argument);
+        if (!validateUnit(argumentWithCalculation, FInteger))
+            return nullptr;
+        numSteps = clampToInteger(parsedDouble(argumentWithCalculation));
+        if (numSteps &lt; 1)
+            return nullptr;
+        argument = args-&gt;next();
+
+        if (argument) {
+            // There is a comma so we need to parse the second value
+            if (!isComma(argument))
+                return nullptr;
+            argument = args-&gt;next();
+            if (argument-&gt;id != CSSValueStart &amp;&amp; argument-&gt;id != CSSValueEnd)
+                return nullptr;
+            stepAtStart = argument-&gt;id == CSSValueStart;
+        }
+
+        return CSSStepsTimingFunctionValue::create(numSteps, stepAtStart);
+    }
+
+    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;cubic-bezier(&quot;)) {
+        // For cubic bezier, 4 values must be specified (comma-separated).
+        if (!args || args-&gt;size() != 7)
+            return nullptr;
+
+        // There are two points specified. The x values must be between 0 and 1 but the y values can exceed this range.
+
+        auto x1 = parseCubicBezierTimingFunctionValue(*args);
+        if (!x1 || x1.value() &lt; 0 || x1.value() &gt; 1)
+            return nullptr;
+
+        auto y1 = parseCubicBezierTimingFunctionValue(*args);
+        if (!y1)
+            return nullptr;
+
+        auto x2 = parseCubicBezierTimingFunctionValue(*args);
+        if (!x2 || x2.value() &lt; 0 || x2.value() &gt; 1)
+            return nullptr;
+
+        auto y2 = parseCubicBezierTimingFunctionValue(*args);
+        if (!y2)
+            return nullptr;
+
+        return CSSCubicBezierTimingFunctionValue::create(x1.value(), y1.value(), x2.value(), y2.value());
+    }
+
+    if (isSpringTimingFunctionEnabled() &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;spring(&quot;)) {
+        // For a spring, 4 values must be specified (space-separated).
+        // FIXME: Make the arguments all optional.
+        if (!args || args-&gt;size() != 4)
+            return nullptr;
+        
+        // Mass must be greater than 0.
+        auto mass = parseSpringTimingFunctionValue(*args);
+        if (!mass || mass.value() &lt;= 0)
+            return nullptr;
+
+        // Stiffness must be greater than 0.
+        auto stiffness = parseSpringTimingFunctionValue(*args);
+        if (!stiffness || stiffness.value() &lt;= 0)
+            return nullptr;
+
+        // Damping coefficient must be greater than or equal to 0.
+        auto damping = parseSpringTimingFunctionValue(*args);
+        if (!damping || damping.value() &lt; 0)
+            return nullptr;
+
+        // Initial velocity may have any value.
+        auto initialVelocity = parseSpringTimingFunctionValue(*args);
+        if (!initialVelocity)
+            return nullptr;
+
+        return CSSSpringTimingFunctionValue::create(mass.value(), stiffness.value(), damping.value(), initialVelocity.value());
+    }
+
+    return nullptr;
+}
+
+bool CSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp; result, AnimationParseContext&amp; context)
+{
+    RefPtr&lt;CSSValueList&gt; values;
+    CSSParserValue* val;
+    RefPtr&lt;CSSValue&gt; value;
+    bool allowComma = false;
+
+    result = nullptr;
+
+    while ((val = m_valueList-&gt;current())) {
+        RefPtr&lt;CSSValue&gt; currValue;
+        if (allowComma) {
+            if (!isComma(val))
+                return false;
+            m_valueList-&gt;next();
+            allowComma = false;
+        }
+        else {
+            switch (propId) {
+            case CSSPropertyAnimationDelay:
+            case CSSPropertyWebkitAnimationDelay:
+            case CSSPropertyTransitionDelay:
+            case CSSPropertyWebkitTransitionDelay:
+                currValue = parseAnimationDelay();
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+            case CSSPropertyAnimationDirection:
+            case CSSPropertyWebkitAnimationDirection:
+                currValue = parseAnimationDirection();
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+            case CSSPropertyAnimationDuration:
+            case CSSPropertyWebkitAnimationDuration:
+            case CSSPropertyTransitionDuration:
+            case CSSPropertyWebkitTransitionDuration:
+                currValue = parseAnimationDuration();
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+            case CSSPropertyAnimationFillMode:
+            case CSSPropertyWebkitAnimationFillMode:
+                currValue = parseAnimationFillMode();
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+            case CSSPropertyAnimationIterationCount:
+            case CSSPropertyWebkitAnimationIterationCount:
+                currValue = parseAnimationIterationCount();
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+            case CSSPropertyAnimationName:
+            case CSSPropertyWebkitAnimationName:
+                currValue = parseAnimationName();
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+            case CSSPropertyAnimationPlayState:
+            case CSSPropertyWebkitAnimationPlayState:
+                currValue = parseAnimationPlayState();
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+            case CSSPropertyTransitionProperty:
+            case CSSPropertyWebkitTransitionProperty:
+                currValue = parseAnimationProperty(context);
+                if (value &amp;&amp; !context.animationPropertyKeywordAllowed())
+                    return false;
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+            case CSSPropertyAnimationTimingFunction:
+            case CSSPropertyWebkitAnimationTimingFunction:
+            case CSSPropertyTransitionTimingFunction:
+            case CSSPropertyWebkitTransitionTimingFunction:
+                currValue = parseAnimationTimingFunction();
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+            case CSSPropertyWebkitAnimationTrigger:
+                currValue = parseAnimationTrigger();
+                if (currValue)
+                    m_valueList-&gt;next();
+                break;
+#endif
+            default:
+                ASSERT_NOT_REACHED();
+                return false;
+            }
+
+            if (!currValue)
+                return false;
+
+            if (value &amp;&amp; !values) {
+                values = CSSValueList::createCommaSeparated();
+                values-&gt;append(value.releaseNonNull());
+            }
+
+            if (values)
+                values-&gt;append(currValue.releaseNonNull());
+            else
+                value = WTFMove(currValue);
+
+            allowComma = true;
+        }
+
+        // When parsing the 'transition' shorthand property, we let it handle building up the lists for all
+        // properties.
+        if (inShorthand())
+            break;
+    }
+
+    if (values &amp;&amp; values-&gt;length()) {
+        result = WTFMove(values);
+        return true;
+    }
+    if (value) {
+        result = WTFMove(value);
+        return true;
+    }
+    return false;
+}
+
+#if ENABLE(CSS_GRID_LAYOUT)
+static inline bool isValidGridPositionCustomIdent(const CSSParserValue&amp; value)
+{
+    return value.unit == CSSPrimitiveValue::CSS_IDENT &amp;&amp; value.id != CSSValueSpan &amp;&amp; value.id != CSSValueAuto;
+}
+
+// The function parses [ &lt;integer&gt; || &lt;custom-ident&gt; ] in &lt;grid-line&gt; (which can be stand alone or with 'span').
+bool CSSParser::parseIntegerOrCustomIdentFromGridPosition(RefPtr&lt;CSSPrimitiveValue&gt;&amp; numericValue, RefPtr&lt;CSSPrimitiveValue&gt;&amp; gridLineName)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+    if (validateUnit(valueWithCalculation, FInteger) &amp;&amp; valueWithCalculation.value().fValue) {
+        numericValue = createPrimitiveNumericValue(valueWithCalculation);
+        CSSParserValue* nextValue = m_valueList-&gt;next();
+        if (nextValue &amp;&amp; isValidGridPositionCustomIdent(*nextValue)) {
+            gridLineName = createPrimitiveStringValue(*nextValue);
+            m_valueList-&gt;next();
+        }
+        return true;
+    }
+
+    if (isValidGridPositionCustomIdent(valueWithCalculation)) {
+        gridLineName = createPrimitiveStringValue(valueWithCalculation);
+        if (CSSParserValue* nextValue = m_valueList-&gt;next()) {
+            ValueWithCalculation nextValueWithCalculation(*nextValue);
+            if (validateUnit(nextValueWithCalculation, FInteger) &amp;&amp; nextValueWithCalculation.value().fValue) {
+                numericValue = createPrimitiveNumericValue(nextValueWithCalculation);
+                m_valueList-&gt;next();
+            }
+        }
+        return true;
+    }
+
+    return false;
+}
+
+RefPtr&lt;CSSValue&gt; CSSParser::parseGridPosition()
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (value-&gt;id == CSSValueAuto) {
+        m_valueList-&gt;next();
+        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
+    }
+
+    RefPtr&lt;CSSPrimitiveValue&gt; numericValue;
+    RefPtr&lt;CSSPrimitiveValue&gt; gridLineName;
+    bool hasSeenSpanKeyword = false;
+
+    if (value-&gt;id == CSSValueSpan) {
+        hasSeenSpanKeyword = true;
+        if (auto* nextValue = m_valueList-&gt;next()) {
+            if (!isForwardSlashOperator(*nextValue) &amp;&amp; !parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName))
+                return nullptr;
+        }
+    } else if (parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName)) {
+        value = m_valueList-&gt;current();
+        if (value &amp;&amp; value-&gt;id == CSSValueSpan) {
+            hasSeenSpanKeyword = true;
+            m_valueList-&gt;next();
+        }
+    }
+
+    // Check that we have consumed all the value list. For shorthands, the parser will pass
+    // the whole value list (including the opposite position).
+    if (m_valueList-&gt;current() &amp;&amp; !isForwardSlashOperator(*m_valueList-&gt;current()))
+        return nullptr;
+
+    // If we didn't parse anything, this is not a valid grid position.
+    if (!hasSeenSpanKeyword &amp;&amp; !gridLineName &amp;&amp; !numericValue)
+        return nullptr;
+
+    // If we have &quot;span&quot; keyword alone is invalid.
+    if (hasSeenSpanKeyword &amp;&amp; !gridLineName &amp;&amp; !numericValue)
+        return nullptr;
+
+    // Negative numbers are not allowed for span (but are for &lt;integer&gt;).
+    if (hasSeenSpanKeyword &amp;&amp; numericValue &amp;&amp; numericValue-&gt;getIntValue() &lt; 0)
+        return nullptr;
+
+    // For the &lt;custom-ident&gt; case.
+    if (gridLineName &amp;&amp; !numericValue &amp;&amp; !hasSeenSpanKeyword)
+        return CSSValuePool::singleton().createValue(gridLineName-&gt;getStringValue(), CSSPrimitiveValue::CSS_STRING);
+
+    auto values = CSSValueList::createSpaceSeparated();
+    if (hasSeenSpanKeyword)
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueSpan));
+    if (numericValue)
+        values-&gt;append(numericValue.releaseNonNull());
+    if (gridLineName)
+        values-&gt;append(gridLineName.releaseNonNull());
+    ASSERT(values-&gt;length());
+    return WTFMove(values);
+}
+
+static Ref&lt;CSSValue&gt; gridMissingGridPositionValue(CSSValue&amp; value)
+{
+    if (is&lt;CSSPrimitiveValue&gt;(value) &amp;&amp; downcast&lt;CSSPrimitiveValue&gt;(value).isString())
+        return value;
+
+    return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
+}
+
+bool CSSParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool important)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    ShorthandScope scope(this, shorthandId);
+    const StylePropertyShorthand&amp; shorthand = shorthandForProperty(shorthandId);
+    ASSERT(shorthand.length() == 2);
+
+    RefPtr&lt;CSSValue&gt; startValue = parseGridPosition();
+    if (!startValue)
+        return false;
+
+    RefPtr&lt;CSSValue&gt; endValue;
+    if (m_valueList-&gt;current()) {
+        if (!isForwardSlashOperator(*m_valueList-&gt;current()))
+            return false;
+
+        if (!m_valueList-&gt;next())
+            return false;
+
+        endValue = parseGridPosition();
+        if (!endValue || m_valueList-&gt;current())
+            return false;
+    } else
+        endValue = gridMissingGridPositionValue(*startValue);
+
+    addProperty(shorthand.properties()[0], startValue.releaseNonNull(), important);
+    addProperty(shorthand.properties()[1], endValue.releaseNonNull(), important);
+    return true;
+}
+
+bool CSSParser::parseGridGapShorthand(bool important)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    ShorthandScope scope(this, CSSPropertyGridGap);
+    ASSERT(shorthandForProperty(CSSPropertyGridGap).length() == 2);
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (!value)
+        return false;
+
+    ValueWithCalculation rowValueWithCalculation(*value);
+    if (!validateUnit(rowValueWithCalculation, FLength | FNonNeg))
+        return false;
+
+    auto rowGap = createPrimitiveNumericValue(rowValueWithCalculation);
+
+    value = m_valueList-&gt;next();
+    if (!value) {
+        addProperty(CSSPropertyGridColumnGap, rowGap.copyRef(), important);
+        addProperty(CSSPropertyGridRowGap, WTFMove(rowGap), important);
+        return true;
+    }
+
+    ValueWithCalculation columnValueWithCalculation(*value);
+    if (!validateUnit(columnValueWithCalculation, FLength | FNonNeg))
+        return false;
+
+    if (m_valueList-&gt;next())
+        return false;
+
+    auto columnGap = createPrimitiveNumericValue(columnValueWithCalculation);
+
+    addProperty(CSSPropertyGridRowGap, WTFMove(rowGap), important);
+    addProperty(CSSPropertyGridColumnGap, WTFMove(columnGap), important);
+
+    return true;
+}
+
+RefPtr&lt;CSSValue&gt; CSSParser::parseGridTemplateColumns(TrackListType trackListType)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    if (!(m_valueList-&gt;current() &amp;&amp; isForwardSlashOperator(*m_valueList-&gt;current()) &amp;&amp; m_valueList-&gt;next()))
+        return nullptr;
+    if (auto columnsValue = parseGridTrackList(trackListType)) {
+        if (m_valueList-&gt;current())
+            return nullptr;
+        return columnsValue;
+    }
+
+    return nullptr;
+}
+
+bool CSSParser::parseGridTemplateRowsAndAreasAndColumns(bool important)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    // At least template-areas strings must be defined.
+    if (!m_valueList-&gt;current() || isForwardSlashOperator(*m_valueList-&gt;current()))
+        return false;
+
+    NamedGridAreaMap gridAreaMap;
+    unsigned rowCount = 0;
+    unsigned columnCount = 0;
+    bool trailingIdentWasAdded = false;
+    auto templateRows = CSSValueList::createSpaceSeparated();
+
+    while (m_valueList-&gt;current() &amp;&amp; !isForwardSlashOperator(*m_valueList-&gt;current())) {
+        // Handle leading &lt;custom-ident&gt;*.
+        if (m_valueList-&gt;current()-&gt;unit == CSSParserValue::ValueList) {
+            if (trailingIdentWasAdded) {
+                // A row's trailing ident must be concatenated with the next row's leading one.
+                parseGridLineNames(*m_valueList, templateRows, downcast&lt;CSSGridLineNamesValue&gt;(templateRows-&gt;item(templateRows-&gt;length() - 1)));
+            } else
+                parseGridLineNames(*m_valueList, templateRows);
+        }
+
+        // Handle a template-area's row.
+        if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
+            return false;
+        ++rowCount;
+
+        // Handle template-rows's track-size.
+        if (m_valueList-&gt;current() &amp;&amp; m_valueList-&gt;current()-&gt;unit != CSSParserValue::Operator &amp;&amp; m_valueList-&gt;current()-&gt;unit != CSSParserValue::ValueList &amp;&amp; m_valueList-&gt;current()-&gt;unit != CSSPrimitiveValue::CSS_STRING) {
+            RefPtr&lt;CSSValue&gt; value = parseGridTrackSize(*m_valueList);
+            if (!value)
+                return false;
+            templateRows-&gt;append(value.releaseNonNull());
+        } else
+            templateRows-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueAuto));
+
+        // This will handle the trailing/leading &lt;custom-ident&gt;* in the grammar.
+        trailingIdentWasAdded = false;
+        if (m_valueList-&gt;current() &amp;&amp; m_valueList-&gt;current()-&gt;unit == CSSParserValue::ValueList)
+            trailingIdentWasAdded = parseGridLineNames(*m_valueList, templateRows);
+    }
+
+    // [/ &lt;explicit-track-list&gt; ]?
+    RefPtr&lt;CSSValue&gt; templateColumns;
+    if (m_valueList-&gt;current()) {
+        ASSERT(isForwardSlashOperator(*m_valueList-&gt;current()));
+        templateColumns = parseGridTemplateColumns(GridTemplateNoRepeat);
+        if (!templateColumns)
+            return false;
+        // The template-columns &lt;track-list&gt; can't be 'none'.
+        if (templateColumns-&gt;isPrimitiveValue() &amp;&amp; downcast&lt;CSSPrimitiveValue&gt;(*templateColumns).getValueID() == CSSValueNone)
+            return false;
+    }
+
+    addProperty(CSSPropertyGridTemplateRows, WTFMove(templateRows), important);
+    if (templateColumns)
+        addProperty(CSSPropertyGridTemplateColumns, templateColumns.releaseNonNull(), important);
+    else
+        addProperty(CSSPropertyGridTemplateColumns, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+    addProperty(CSSPropertyGridTemplateAreas, CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount), important);
+
+    return true;
+}
+
+bool CSSParser::parseGridTemplateShorthand(bool important)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    ShorthandScope scope(this, CSSPropertyGridTemplate);
+    ASSERT(shorthandForProperty(CSSPropertyGridTemplate).length() == 3);
+
+    // At least &quot;none&quot; must be defined.
+    if (!m_valueList-&gt;current())
+        return false;
+
+    bool firstValueIsNone = m_valueList-&gt;current()-&gt;id == CSSValueNone;
+
+    // 1- 'none' case.
+    if (firstValueIsNone &amp;&amp; !m_valueList-&gt;next()) {
+        addProperty(CSSPropertyGridTemplateColumns, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+        addProperty(CSSPropertyGridTemplateRows, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+        addProperty(CSSPropertyGridTemplateAreas, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+        return true;
+    }
+
+    // 2- &lt;grid-template-rows&gt; / &lt;grid-template-columns&gt; syntax.
+    RefPtr&lt;CSSValue&gt; rowsValue;
+    if (firstValueIsNone)
+        rowsValue = CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
+    else
+        rowsValue = parseGridTrackList(GridTemplate);
+
+    if (rowsValue) {
+        auto columnsValue = parseGridTemplateColumns();
+        if (!columnsValue)
+            return false;
+
+        addProperty(CSSPropertyGridTemplateColumns, columnsValue.releaseNonNull(), important);
+        addProperty(CSSPropertyGridTemplateRows, rowsValue.releaseNonNull(), important);
+        addProperty(CSSPropertyGridTemplateAreas, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+        return true;
+    }
+
+
+    // 3- [&lt;line-names&gt;? &lt;string&gt; &lt;track-size&gt;? &lt;line-names&gt;? ]+ syntax.
+    // It requires to rewind parsing due to previous syntax failures.
+    m_valueList-&gt;setCurrentIndex(0);
+    return parseGridTemplateRowsAndAreasAndColumns(important);
+}
+
+bool CSSParser::parseGridShorthand(bool important)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    ShorthandScope scope(this, CSSPropertyGrid);
+    ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 8);
+
+    // 1- &lt;grid-template&gt;
+    if (parseGridTemplateShorthand(important)) {
+        // It can only be specified the explicit or the implicit grid properties in a single grid declaration.
+        // The sub-properties not specified are set to their initial value, as normal for shorthands.
+        addProperty(CSSPropertyGridAutoFlow, CSSValuePool::singleton().createImplicitInitialValue(), important);
+        addProperty(CSSPropertyGridAutoColumns, CSSValuePool::singleton().createImplicitInitialValue(), important);
+        addProperty(CSSPropertyGridAutoRows, CSSValuePool::singleton().createImplicitInitialValue(), important);
+        addProperty(CSSPropertyGridColumnGap, CSSValuePool::singleton().createImplicitInitialValue(), important);
+        addProperty(CSSPropertyGridRowGap, CSSValuePool::singleton().createImplicitInitialValue(), important);
+        return true;
+    }
+
+    // Need to rewind parsing to explore the alternative syntax of this shorthand.
+    m_valueList-&gt;setCurrentIndex(0);
+
+    // 2- &lt;grid-auto-flow&gt; [ &lt;grid-auto-columns&gt; [ / &lt;grid-auto-rows&gt; ]? ]
+    if (!parseValue(CSSPropertyGridAutoFlow, important))
+        return false;
+
+    RefPtr&lt;CSSValue&gt; autoColumnsValue;
+    RefPtr&lt;CSSValue&gt; autoRowsValue;
+
+    if (m_valueList-&gt;current()) {
+        autoRowsValue = parseGridTrackList(GridAuto);
+        if (!autoRowsValue)
+            return false;
+        if (m_valueList-&gt;current()) {
+            if (!isForwardSlashOperator(*m_valueList-&gt;current()) || !m_valueList-&gt;next())
+                return false;
+            autoColumnsValue = parseGridTrackList(GridAuto);
+            if (!autoColumnsValue)
+                return false;
+        }
+        if (m_valueList-&gt;current())
+            return false;
+    } else {
+        // Other omitted values are set to their initial values.
+        autoColumnsValue = CSSValuePool::singleton().createImplicitInitialValue();
+        autoRowsValue = CSSValuePool::singleton().createImplicitInitialValue();
+    }
+
+    // if &lt;grid-auto-rows&gt; value is omitted, it is set to the value specified for grid-auto-columns.
+    if (!autoColumnsValue)
+        autoColumnsValue = autoRowsValue;
+
+    addProperty(CSSPropertyGridAutoColumns, autoColumnsValue.releaseNonNull(), important);
+    addProperty(CSSPropertyGridAutoRows, autoRowsValue.releaseNonNull(), important);
+
+    // It can only be specified the explicit or the implicit grid properties in a single grid declaration.
+    // The sub-properties not specified are set to their initial value, as normal for shorthands.
+    addProperty(CSSPropertyGridTemplateColumns, CSSValuePool::singleton().createImplicitInitialValue(), important);
+    addProperty(CSSPropertyGridTemplateRows, CSSValuePool::singleton().createImplicitInitialValue(), important);
+    addProperty(CSSPropertyGridTemplateAreas, CSSValuePool::singleton().createImplicitInitialValue(), important);
+    addProperty(CSSPropertyGridColumnGap, CSSValuePool::singleton().createImplicitInitialValue(), important);
+    addProperty(CSSPropertyGridRowGap, CSSValuePool::singleton().createImplicitInitialValue(), important);
+
+    return true;
+}
+
+bool CSSParser::parseGridAreaShorthand(bool important)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    ShorthandScope scope(this, CSSPropertyGridArea);
+    ASSERT(shorthandForProperty(CSSPropertyGridArea).length() == 4);
+
+    RefPtr&lt;CSSValue&gt; rowStartValue = parseGridPosition();
+    if (!rowStartValue)
+        return false;
+
+    RefPtr&lt;CSSValue&gt; columnStartValue;
+    if (!parseSingleGridAreaLonghand(columnStartValue))
+        return false;
+
+    RefPtr&lt;CSSValue&gt; rowEndValue;
+    if (!parseSingleGridAreaLonghand(rowEndValue))
+        return false;
+
+    RefPtr&lt;CSSValue&gt; columnEndValue;
+    if (!parseSingleGridAreaLonghand(columnEndValue))
+        return false;
+
+    if (!columnStartValue)
+        columnStartValue = gridMissingGridPositionValue(*rowStartValue);
+
+    if (!rowEndValue)
+        rowEndValue = gridMissingGridPositionValue(*rowStartValue);
+
+    if (!columnEndValue)
+        columnEndValue = gridMissingGridPositionValue(*columnStartValue);
+
+    addProperty(CSSPropertyGridRowStart, rowStartValue.releaseNonNull(), important);
+    addProperty(CSSPropertyGridColumnStart, columnStartValue.releaseNonNull(), important);
+    addProperty(CSSPropertyGridRowEnd, rowEndValue.releaseNonNull(), important);
+    addProperty(CSSPropertyGridColumnEnd, columnEndValue.releaseNonNull(), important);
+    return true;
+}
+
+bool CSSParser::parseSingleGridAreaLonghand(RefPtr&lt;CSSValue&gt;&amp; property)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    if (!m_valueList-&gt;current())
+        return true;
+
+    if (!isForwardSlashOperator(*m_valueList-&gt;current()))
+        return false;
+
+    if (!m_valueList-&gt;next())
+        return false;
+
+    property = parseGridPosition();
+    return true;
+}
+
+bool CSSParser::parseGridLineNames(CSSParserValueList&amp; inputList, CSSValueList&amp; valueList, CSSGridLineNamesValue* previousNamedAreaTrailingLineNames)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+    ASSERT(inputList.current() &amp;&amp; inputList.current()-&gt;unit == CSSParserValue::ValueList);
+
+    CSSParserValueList&amp; identList = *inputList.current()-&gt;valueList;
+    if (!identList.size()) {
+        inputList.next();
+        return false;
+    }
+
+    // Need to ensure the identList is at the heading index, since the parserList might have been rewound.
+    identList.setCurrentIndex(0);
+    Ref&lt;CSSGridLineNamesValue&gt; lineNames = previousNamedAreaTrailingLineNames ? Ref&lt;CSSGridLineNamesValue&gt;(*previousNamedAreaTrailingLineNames) : CSSGridLineNamesValue::create();
+    while (CSSParserValue* identValue = identList.current()) {
+        ASSERT(identValue-&gt;unit == CSSPrimitiveValue::CSS_IDENT);
+        lineNames-&gt;append(createPrimitiveStringValue(*identValue));
+        identList.next();
+    }
+    if (!previousNamedAreaTrailingLineNames)
+        valueList.append(WTFMove(lineNames));
+
+    inputList.next();
+    return true;
+}
+
+static bool isGridTrackFixedSized(const CSSPrimitiveValue&amp; value)
+{
+    CSSValueID valueID = value.getValueID();
+    if (valueID == CSSValueWebkitMinContent || valueID == CSSValueWebkitMaxContent || valueID == CSSValueAuto || value.isFlex())
+        return false;
+
+    ASSERT(value.isLength() || value.isPercentage() || value.isCalculated());
+    return true;
+}
+
+static bool isGridTrackFixedSized(const CSSValue&amp; value)
+{
+    if (value.isPrimitiveValue())
+        return isGridTrackFixedSized(downcast&lt;CSSPrimitiveValue&gt;(value));
+
+    ASSERT(value.isFunctionValue());
+    ASSERT(downcast&lt;CSSFunctionValue&gt;(value).arguments());
+    ASSERT(downcast&lt;CSSFunctionValue&gt;(value).arguments()-&gt;length() == 2);
+
+    auto&amp; min = downcast&lt;CSSPrimitiveValue&gt;(*downcast&lt;CSSFunctionValue&gt;(value).arguments()-&gt;item(0));
+    auto&amp; max = downcast&lt;CSSPrimitiveValue&gt;(*downcast&lt;CSSFunctionValue&gt;(value).arguments()-&gt;item(1));
+    return isGridTrackFixedSized(min) || isGridTrackFixedSized(max);
+}
+
+RefPtr&lt;CSSValue&gt; CSSParser::parseGridTrackList(TrackListType trackListType)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (value-&gt;id == CSSValueNone) {
+        if (trackListType == GridAuto)
+            return nullptr;
+        m_valueList-&gt;next();
+        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
+    }
+
+    auto values = CSSValueList::createSpaceSeparated();
+    // Handle leading  &lt;custom-ident&gt;*.
+    value = m_valueList-&gt;current();
+    bool allowGridLineNames = trackListType != GridAuto;
+    if (value &amp;&amp; value-&gt;unit == CSSParserValue::ValueList) {
+        if (!allowGridLineNames)
+            return nullptr;
+        parseGridLineNames(*m_valueList, values);
+    }
+
+    bool seenTrackSizeOrRepeatFunction = false;
+    bool seenAutoRepeat = false;
+    bool allTracksAreFixedSized = true;
+    bool repeatAllowed = trackListType == GridTemplate;
+    while (CSSParserValue* currentValue = m_valueList-&gt;current()) {
+        if (isForwardSlashOperator(*currentValue))
+            break;
+        if (currentValue-&gt;unit == CSSParserValue::Function &amp;&amp; equalLettersIgnoringASCIICase(currentValue-&gt;function-&gt;name, &quot;repeat(&quot;)) {
+            if (!repeatAllowed)
+                return nullptr;
+            bool isAutoRepeat;
+            if (!parseGridTrackRepeatFunction(values, isAutoRepeat, allTracksAreFixedSized))
+                return nullptr;
+            if (isAutoRepeat &amp;&amp; seenAutoRepeat)
+                return nullptr;
+            seenAutoRepeat = seenAutoRepeat || isAutoRepeat;
+        } else {
+            RefPtr&lt;CSSValue&gt; value = parseGridTrackSize(*m_valueList);
+            if (!value)
+                return nullptr;
+
+            allTracksAreFixedSized = allTracksAreFixedSized &amp;&amp; isGridTrackFixedSized(*value);
+            values-&gt;append(value.releaseNonNull());
+        }
+        seenTrackSizeOrRepeatFunction = true;
+
+        if (seenAutoRepeat &amp;&amp; !allTracksAreFixedSized)
+            return nullptr;
+
+        // This will handle the trailing &lt;custom-ident&gt;* in the grammar.
+        value = m_valueList-&gt;current();
+        if (value &amp;&amp; value-&gt;unit == CSSParserValue::ValueList) {
+            if (!allowGridLineNames)
+                return nullptr;
+            parseGridLineNames(*m_valueList, values);
+        }
+    }
+
+    if (!seenTrackSizeOrRepeatFunction)
+        return nullptr;
+
+    return WTFMove(values);
+}
+
+bool CSSParser::parseGridTrackRepeatFunction(CSSValueList&amp; list, bool&amp; isAutoRepeat, bool&amp; allTracksAreFixedSized)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    CSSParserValueList* arguments = m_valueList-&gt;current()-&gt;function-&gt;args.get();
+    if (!arguments || arguments-&gt;size() &lt; 3 || !isComma(arguments-&gt;valueAt(1)))
+        return false;
+
+    ValueWithCalculation firstValueWithCalculation(*arguments-&gt;valueAt(0));
+    CSSValueID firstValueID = firstValueWithCalculation.value().id;
+    isAutoRepeat = firstValueID == CSSValueAutoFill || firstValueID == CSSValueAutoFit;
+    if (!isAutoRepeat &amp;&amp; !validateUnit(firstValueWithCalculation, FPositiveInteger))
+        return false;
+
+    // If arguments-&gt;valueAt(0)-&gt;fValue &gt; SIZE_MAX then repetitions becomes 0 during the type casting, that's why we
+    // clamp it down to kGridMaxTracks before the type casting.
+    // The number of repetitions for &lt;auto-repeat&gt; is not important at parsing level
+    // because it will be computed later, let's set it to 1.
+    unsigned repetitions = isAutoRepeat ? 1 : clampTo&lt;unsigned&gt;(parsedDouble(firstValueWithCalculation), 0, kGridMaxTracks);
+
+    Ref&lt;CSSValueList&gt; repeatedValues = isAutoRepeat ? Ref&lt;CSSValueList&gt;(CSSGridAutoRepeatValue::create(firstValueID)) : CSSValueList::createSpaceSeparated();
+    arguments-&gt;next(); // Skip the repetition count.
+    arguments-&gt;next(); // Skip the comma.
+
+    // Handle leading &lt;custom-ident&gt;*.
+    CSSParserValue* currentValue = arguments-&gt;current();
+    if (currentValue &amp;&amp; currentValue-&gt;unit == CSSParserValue::ValueList)
+        parseGridLineNames(*arguments, repeatedValues);
+
+    unsigned numberOfTracks = 0;
+    while (arguments-&gt;current()) {
+        RefPtr&lt;CSSValue&gt; trackSize = parseGridTrackSize(*arguments);
+        if (!trackSize)
+            return false;
+
+        allTracksAreFixedSized = allTracksAreFixedSized &amp;&amp; isGridTrackFixedSized(*trackSize);
+        repeatedValues-&gt;append(trackSize.releaseNonNull());
+        ++numberOfTracks;
+
+        // This takes care of any trailing &lt;custom-ident&gt;* in the grammar.
+        currentValue = arguments-&gt;current();
+        if (currentValue &amp;&amp; currentValue-&gt;unit == CSSParserValue::ValueList)
+            parseGridLineNames(*arguments, repeatedValues);
+    }
+
+    // We should have found at least one &lt;track-size&gt;, otherwise the declaration is invalid.
+    if (!numberOfTracks)
+        return false;
+
+    // We clamp the number of repetitions to a multiple of the repeat() track list's size, while staying below the max
+    // grid size.
+    repetitions = std::min(repetitions, kGridMaxTracks / numberOfTracks);
+
+    if (isAutoRepeat)
+        list.append(WTFMove(repeatedValues));
+    else {
+        for (unsigned i = 0; i &lt; repetitions; ++i) {
+            for (unsigned j = 0; j &lt; repeatedValues-&gt;length(); ++j)
+                list.append(*repeatedValues-&gt;itemWithoutBoundsCheck(j));
+        }
+    }
+
+    m_valueList-&gt;next();
+    return true;
+}
+
+RefPtr&lt;CSSValue&gt; CSSParser::parseGridTrackSize(CSSParserValueList&amp; inputList)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    CSSParserValue&amp; currentValue = *inputList.current();
+    inputList.next();
+
+    if (currentValue.id == CSSValueAuto)
+        return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
+
+    if (currentValue.unit == CSSParserValue::Function &amp;&amp; equalLettersIgnoringASCIICase(currentValue.function-&gt;name, &quot;minmax(&quot;)) {
+        // The spec defines the following grammar: minmax( &lt;track-breadth&gt; , &lt;track-breadth&gt; )
+        CSSParserValueList* arguments = currentValue.function-&gt;args.get();
+        if (!arguments || arguments-&gt;size() != 3 || !isComma(arguments-&gt;valueAt(1)))
+            return nullptr;
+
+        RefPtr&lt;CSSPrimitiveValue&gt; minTrackBreadth = parseGridBreadth(*arguments-&gt;valueAt(0));
+        if (!minTrackBreadth || minTrackBreadth-&gt;isFlex())
+            return nullptr;
+
+        RefPtr&lt;CSSPrimitiveValue&gt; maxTrackBreadth = parseGridBreadth(*arguments-&gt;valueAt(2));
+        if (!maxTrackBreadth)
+            return nullptr;
+
+        auto parsedArguments = CSSValueList::createCommaSeparated();
+        parsedArguments-&gt;append(minTrackBreadth.releaseNonNull());
+        parsedArguments-&gt;append(maxTrackBreadth.releaseNonNull());
+        return CSSFunctionValue::create(&quot;minmax(&quot;, WTFMove(parsedArguments));
+    }
+
+    return parseGridBreadth(currentValue);
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseGridBreadth(CSSParserValue&amp; value)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    if (value.id == CSSValueWebkitMinContent || value.id == CSSValueWebkitMaxContent || value.id == CSSValueAuto)
+        return CSSValuePool::singleton().createIdentifierValue(value.id);
+
+    if (value.unit == CSSPrimitiveValue::CSS_FR) {
+        double flexValue = value.fValue;
+
+        // Fractional unit is a non-negative dimension.
+        if (flexValue &lt;= 0)
+            return nullptr;
+
+        return CSSValuePool::singleton().createValue(flexValue, CSSPrimitiveValue::CSS_FR);
+    }
+
+    ValueWithCalculation valueWithCalculation(value);
+    if (!validateUnit(valueWithCalculation, FNonNeg | FLength | FPercent))
+        return nullptr;
+
+    return createPrimitiveNumericValue(valueWithCalculation);
+}
+
+static inline bool isValidGridAutoFlowId(CSSValueID id)
+{
+    return (id == CSSValueRow || id == CSSValueColumn || id == CSSValueDense);
+}
+
+RefPtr&lt;CSSValue&gt; CSSParser::parseGridAutoFlow(CSSParserValueList&amp; inputList)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    // [ row | column ] || dense
+    CSSParserValue* value = inputList.current();
+    if (!value)
+        return nullptr;
+
+    auto parsedValues = CSSValueList::createSpaceSeparated();
+
+    // First parameter.
+    CSSValueID firstId = value-&gt;id;
+    if (!isValidGridAutoFlowId(firstId))
+        return nullptr;
+
+    // Second parameter, if any.
+    // If second parameter is not valid we should process anyway the first one as we can be inside the &quot;grid&quot; shorthand.
+    value = inputList.next();
+    if (!value || !isValidGridAutoFlowId(value-&gt;id)) {
+        if (firstId == CSSValueDense)
+            parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueRow));
+
+        parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(firstId));
+        return WTFMove(parsedValues);
+    }
+
+    switch (firstId) {
+    case CSSValueRow:
+    case CSSValueColumn:
+        parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(firstId));
+        if (value-&gt;id == CSSValueDense) {
+            parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            inputList.next();
+        }
+        break;
+    case CSSValueDense:
+        if (value-&gt;id == CSSValueRow || value-&gt;id == CSSValueColumn) {
+            parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            inputList.next();
+        }
+        parsedValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(firstId));
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+
+    return WTFMove(parsedValues);
+}
+#endif /* ENABLE(CSS_GRID_LAYOUT) */
+
+#if ENABLE(DASHBOARD_SUPPORT)
+
+static const int dashboardRegionParameterCount = 6;
+static const int dashboardRegionShortParameterCount = 2;
+
+static CSSParserValue* skipCommaInDashboardRegion(CSSParserValueList *args)
+{
+    if (args-&gt;size() == (dashboardRegionParameterCount * 2 - 1) || args-&gt;size() == (dashboardRegionShortParameterCount * 2 - 1)) {
+        CSSParserValue&amp; current = *args-&gt;current();
+        if (current.unit == CSSParserValue::Operator &amp;&amp; current.iValue == ',')
+            return args-&gt;next();
+    }
+    return args-&gt;current();
+}
+
+bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important)
+{
+    bool valid = true;
+
+    CSSParserValue* value = m_valueList-&gt;current();
+
+    if (value-&gt;id == CSSValueNone) {
+        if (m_valueList-&gt;next())
+            return false;
+        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
+        return valid;
+    }
+
+    auto firstRegion = DashboardRegion::create();
+    DashboardRegion* region = nullptr;
+
+    while (value) {
+        if (!region) {
+            region = firstRegion.ptr();
+        } else {
+            auto nextRegion = DashboardRegion::create();
+            region-&gt;m_next = nextRegion.copyRef();
+            region = nextRegion.ptr();
+        }
+
+        if (value-&gt;unit != CSSParserValue::Function) {
+            valid = false;
+            break;
+        }
+
+        // Commas count as values, so allow (function name is dashboard-region for DASHBOARD_SUPPORT feature):
+        // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
+        // dashboard-region(label, type, t, r, b, l) or dashboard-region(label type t r b l)
+        // also allow
+        // dashboard-region(label, type) or dashboard-region(label type)
+        // dashboard-region(label, type) or dashboard-region(label type)
+        CSSParserValueList* args = value-&gt;function-&gt;args.get();
+        if (!equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;dashboard-region(&quot;) || !args) {
+            valid = false;
+            break;
+        }
+
+        int numArgs = args-&gt;size();
+        if ((numArgs != dashboardRegionParameterCount &amp;&amp; numArgs != (dashboardRegionParameterCount*2-1))
+            &amp;&amp; (numArgs != dashboardRegionShortParameterCount &amp;&amp; numArgs != (dashboardRegionShortParameterCount*2-1))) {
+            valid = false;
+            break;
+        }
+
+        // First arg is a label.
+        CSSParserValue* arg = args-&gt;current();
+        if (arg-&gt;unit != CSSPrimitiveValue::CSS_IDENT) {
+            valid = false;
+            break;
+        }
+
+        region-&gt;m_label = arg-&gt;string;
+
+        // Second arg is a type.
+        arg = args-&gt;next();
+        arg = skipCommaInDashboardRegion(args);
+        if (arg-&gt;unit != CSSPrimitiveValue::CSS_IDENT) {
+            valid = false;
+            break;
+        }
+
+        if (equalLettersIgnoringASCIICase(*arg, &quot;circle&quot;))
+            region-&gt;m_isCircle = true;
+        else if (equalLettersIgnoringASCIICase(*arg, &quot;rectangle&quot;))
+            region-&gt;m_isRectangle = true;
+        else {
+            valid = false;
+            break;
+        }
+
+        region-&gt;m_geometryType = arg-&gt;string;
+
+        if (numArgs == dashboardRegionShortParameterCount || numArgs == (dashboardRegionShortParameterCount*2-1)) {
+            // This originally used CSSValueInvalid by accident. It might be more logical to use something else.
+            RefPtr&lt;CSSPrimitiveValue&gt; amount = CSSValuePool::singleton().createIdentifierValue(CSSValueInvalid);
+
+            region-&gt;setTop(amount.copyRef());
+            region-&gt;setRight(amount.copyRef());
+            region-&gt;setBottom(amount.copyRef());
+            region-&gt;setLeft(WTFMove(amount));
+        } else {
+            // Next four arguments must be offset numbers
+            for (int i = 0; i &lt; 4; ++i) {
+                arg = args-&gt;next();
+                arg = skipCommaInDashboardRegion(args);
+
+                ValueWithCalculation argWithCalculation(*arg);
+                valid = arg-&gt;id == CSSValueAuto || validateUnit(argWithCalculation, FLength);
+                if (!valid)
+                    break;
+
+                RefPtr&lt;CSSPrimitiveValue&gt; amount = arg-&gt;id == CSSValueAuto ? CSSValuePool::singleton().createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(argWithCalculation);
+
+                if (i == 0)
+                    region-&gt;setTop(WTFMove(amount));
+                else if (i == 1)
+                    region-&gt;setRight(WTFMove(amount));
+                else if (i == 2)
+                    region-&gt;setBottom(WTFMove(amount));
+                else
+                    region-&gt;setLeft(WTFMove(amount));
+            }
+        }
+
+        if (args-&gt;next())
+            return false;
+
+        value = m_valueList-&gt;next();
+    }
+
+    if (valid)
+        addProperty(propId, CSSValuePool::singleton().createValue(RefPtr&lt;DashboardRegion&gt;(WTFMove(firstRegion))), important);
+
+    return valid;
+}
+
+#endif /* ENABLE(DASHBOARD_SUPPORT) */
+
+#if ENABLE(CSS_GRID_LAYOUT)
+static Vector&lt;String&gt; parseGridTemplateAreasColumnNames(const String&amp; gridRowNames)
+{
+    ASSERT(!gridRowNames.isEmpty());
+    Vector&lt;String&gt; columnNames;
+    // Using StringImpl to avoid checks and indirection in every call to String::operator[].
+    StringImpl&amp; text = *gridRowNames.impl();
+    unsigned length = text.length();
+    unsigned index = 0;
+    while (index &lt; length) {
+        if (text[index] != ' ' &amp;&amp; text[index] != '.') {
+            unsigned gridAreaStart = index;
+            while (index &lt; length &amp;&amp; text[index] != ' ' &amp;&amp; text[index] != '.')
+                ++index;
+            columnNames.append(text.substring(gridAreaStart, index - gridAreaStart));
+            continue;
+        }
+
+        if (text[index] == '.') {
+            while (index &lt; length &amp;&amp; text[index] == '.')
+                ++index;
+            columnNames.append(&quot;.&quot;);
+            continue;
+        }
+
+        ++index;
+    }
+
+    return columnNames;
+}
+
+bool CSSParser::parseGridTemplateAreasRow(NamedGridAreaMap&amp; gridAreaMap, const unsigned rowCount, unsigned&amp; columnCount)
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    CSSParserValue* currentValue = m_valueList-&gt;current();
+    if (!currentValue || currentValue-&gt;unit != CSSPrimitiveValue::CSS_STRING)
+        return false;
+
+    String gridRowNames = currentValue-&gt;string;
+    if (gridRowNames.containsOnlyWhitespace())
+        return false;
+
+    Vector&lt;String&gt; columnNames = parseGridTemplateAreasColumnNames(gridRowNames);
+    if (!columnCount) {
+        columnCount = columnNames.size();
+        ASSERT(columnCount);
+    } else if (columnCount != columnNames.size()) {
+        // The declaration is invalid is all the rows don't have the number of columns.
+        return false;
+    }
+
+    for (unsigned currentColumn = 0; currentColumn &lt; columnCount; ++currentColumn) {
+        const String&amp; gridAreaName = columnNames[currentColumn];
+
+        // Unamed areas are always valid (we consider them to be 1x1).
+        if (gridAreaName == &quot;.&quot;)
+            continue;
+
+        // We handle several grid areas with the same name at once to simplify the validation code.
+        unsigned lookAheadColumn;
+        for (lookAheadColumn = currentColumn + 1; lookAheadColumn &lt; columnCount; ++lookAheadColumn) {
+            if (columnNames[lookAheadColumn] != gridAreaName)
+                break;
+        }
+
+        auto gridAreaIterator = gridAreaMap.find(gridAreaName);
+        if (gridAreaIterator == gridAreaMap.end())
+            gridAreaMap.add(gridAreaName, GridArea(GridSpan::translatedDefiniteGridSpan(rowCount, rowCount + 1), GridSpan::translatedDefiniteGridSpan(currentColumn, lookAheadColumn)));
+        else {
+            GridArea&amp; gridArea = gridAreaIterator-&gt;value;
+
+            // The following checks test that the grid area is a single filled-in rectangle.
+            // 1. The new row is adjacent to the previously parsed row.
+            if (rowCount != gridArea.rows.endLine())
+                return false;
+
+            // 2. The new area starts at the same position as the previously parsed area.
+            if (currentColumn != gridArea.columns.startLine())
+                return false;
+
+            // 3. The new area ends at the same position as the previously parsed area.
+            if (lookAheadColumn != gridArea.columns.endLine())
+                return false;
+
+            gridArea.rows = GridSpan::translatedDefiniteGridSpan(gridArea.rows.startLine(), gridArea.rows.endLine() + 1);
+        }
+        currentColumn = lookAheadColumn - 1;
+    }
+
+    m_valueList-&gt;next();
+    return true;
+}
+
+RefPtr&lt;CSSValue&gt; CSSParser::parseGridTemplateAreas()
+{
+    ASSERT(isCSSGridLayoutEnabled());
+
+    if (m_valueList-&gt;current() &amp;&amp; m_valueList-&gt;current()-&gt;id == CSSValueNone) {
+        m_valueList-&gt;next();
+        return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
+    }
+
+    NamedGridAreaMap gridAreaMap;
+    unsigned rowCount = 0;
+    unsigned columnCount = 0;
+
+    while (m_valueList-&gt;current()) {
+        if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
+            return nullptr;
+        ++rowCount;
+    }
+
+    if (!rowCount || !columnCount)
+        return nullptr;
+
+    return CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount);
+}
+#endif /* ENABLE(CSS_GRID_LAYOUT) */
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseCounterContent(CSSParserValueList&amp; args, bool counters)
+{
+    unsigned numArgs = args.size();
+    if (counters &amp;&amp; numArgs != 3 &amp;&amp; numArgs != 5)
+        return nullptr;
+    if (!counters &amp;&amp; numArgs != 1 &amp;&amp; numArgs != 3)
+        return nullptr;
+
+    CSSParserValue* argument = args.current();
+    if (argument-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+        return nullptr;
+    auto identifier = createPrimitiveStringValue(*argument);
+
+    RefPtr&lt;CSSPrimitiveValue&gt; separator;
+    if (!counters)
+        separator = CSSValuePool::singleton().createValue(String(), CSSPrimitiveValue::CSS_STRING);
+    else {
+        argument = args.next();
+        if (argument-&gt;unit != CSSParserValue::Operator || argument-&gt;iValue != ',')
+            return nullptr;
+
+        argument = args.next();
+        if (argument-&gt;unit != CSSPrimitiveValue::CSS_STRING)
+            return nullptr;
+
+        separator = createPrimitiveStringValue(*argument);
+    }
+
+    RefPtr&lt;CSSPrimitiveValue&gt; listStyle;
+    argument = args.next();
+    if (!argument) // Make the list style default decimal
+        listStyle = CSSValuePool::singleton().createIdentifierValue(CSSValueDecimal);
+    else {
+        if (argument-&gt;unit != CSSParserValue::Operator || argument-&gt;iValue != ',')
+            return nullptr;
+
+        argument = args.next();
+        if (argument-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+            return nullptr;
+
+        CSSValueID listStyleID = CSSValueInvalid;
+        if (argument-&gt;id == CSSValueNone || (argument-&gt;id &gt;= CSSValueDisc &amp;&amp; argument-&gt;id &lt;= CSSValueKatakanaIroha))
+            listStyleID = argument-&gt;id;
+        else
+            return nullptr;
+
+        listStyle = CSSValuePool::singleton().createIdentifierValue(listStyleID);
+    }
+
+    return CSSValuePool::singleton().createValue(Counter::create(WTFMove(identifier), listStyle.releaseNonNull(), separator.releaseNonNull()));
+}
+
+bool CSSParser::parseClipShape(CSSPropertyID propId, bool important)
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    CSSParserValueList* args = value.function-&gt;args.get();
+
+    if (!equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;rect(&quot;) || !args)
+        return false;
+
+    // rect(t, r, b, l) || rect(t r b l)
+    if (args-&gt;size() != 4 &amp;&amp; args-&gt;size() != 7)
+        return false;
+    auto rect = Rect::create();
+    bool valid = true;
+    int i = 0;
+    CSSParserValue* argument = args-&gt;current();
+    while (argument) {
+        ValueWithCalculation argumentWithCalculation(*argument);
+        valid = argument-&gt;id == CSSValueAuto || validateUnit(argumentWithCalculation, FLength);
+        if (!valid)
+            break;
+        Ref&lt;CSSPrimitiveValue&gt; length = argument-&gt;id == CSSValueAuto ? CSSValuePool::singleton().createIdentifierValue(CSSValueAuto) : createPrimitiveNumericValue(argumentWithCalculation);
+        if (i == 0)
+            rect-&gt;setTop(WTFMove(length));
+        else if (i == 1)
+            rect-&gt;setRight(WTFMove(length));
+        else if (i == 2)
+            rect-&gt;setBottom(WTFMove(length));
+        else
+            rect-&gt;setLeft(WTFMove(length));
+        argument = args-&gt;next();
+        if (argument &amp;&amp; args-&gt;size() == 7) {
+            if (argument-&gt;unit == CSSParserValue::Operator &amp;&amp; argument-&gt;iValue == ',') {
+                argument = args-&gt;next();
+            } else {
+                valid = false;
+                break;
+            }
+        }
+        i++;
+    }
+    if (valid) {
+        addProperty(propId, CSSValuePool::singleton().createValue(WTFMove(rect)), important);
+        m_valueList-&gt;next();
+        return true;
+    }
+    return false;
+}
+
+static void completeBorderRadii(RefPtr&lt;CSSPrimitiveValue&gt; radii[4])
+{
+    if (radii[3])
+        return;
+    if (!radii[2]) {
+        if (!radii[1])
+            radii[1] = radii[0];
+        radii[2] = radii[0];
+    }
+    radii[3] = radii[1];
+}
+
+// FIXME: This should be refactored with CSSParser::parseBorderRadius.
+// CSSParser::parseBorderRadius contains support for some legacy radius construction.
+RefPtr&lt;CSSBasicShapeInset&gt; CSSParser::parseInsetRoundedCorners(Ref&lt;CSSBasicShapeInset&gt;&amp;&amp; shape, CSSParserValueList&amp; args)
+{
+    CSSParserValue* argument = args.next();
+
+    if (!argument)
+        return nullptr;
+
+    Vector&lt;CSSParserValue*&gt; radiusArguments;
+    while (argument) {
+        radiusArguments.append(argument);
+        argument = args.next();
+    }
+
+    unsigned num = radiusArguments.size();
+    if (!num || num &gt; 9)
+        return nullptr;
+
+    RefPtr&lt;CSSPrimitiveValue&gt; radii[2][4];
+
+    unsigned indexAfterSlash = 0;
+    for (unsigned i = 0; i &lt; num; ++i) {
+        CSSParserValue&amp; value = *radiusArguments.at(i);
+        if (value.unit == CSSParserValue::Operator) {
+            if (value.iValue != '/')
+                return nullptr;
+
+            if (!i || indexAfterSlash || i + 1 == num || num &gt; i + 5)
+                return nullptr;
+
+            indexAfterSlash = i + 1;
+            completeBorderRadii(radii[0]);
+            continue;
+        }
+
+        if (i - indexAfterSlash &gt;= 4)
+            return nullptr;
+
+        ValueWithCalculation valueWithCalculation(value);
+        if (!validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg))
+            return nullptr;
+
+        auto radius = createPrimitiveNumericValue(valueWithCalculation);
+
+        if (!indexAfterSlash)
+            radii[0][i] = WTFMove(radius);
+        else
+            radii[1][i - indexAfterSlash] = WTFMove(radius);
+    }
+
+    if (!indexAfterSlash) {
+        completeBorderRadii(radii[0]);
+        for (unsigned i = 0; i &lt; 4; ++i)
+            radii[1][i] = radii[0][i];
+    } else
+        completeBorderRadii(radii[1]);
+
+    shape-&gt;setTopLeftRadius(createPrimitiveValuePair(WTFMove(radii[0][0]), WTFMove(radii[1][0])));
+    shape-&gt;setTopRightRadius(createPrimitiveValuePair(WTFMove(radii[0][1]), WTFMove(radii[1][1])));
+    shape-&gt;setBottomRightRadius(createPrimitiveValuePair(WTFMove(radii[0][2]), WTFMove(radii[1][2])));
+    shape-&gt;setBottomLeftRadius(createPrimitiveValuePair(WTFMove(radii[0][3]), WTFMove(radii[1][3])));
+
+    return WTFMove(shape);
+}
+
+RefPtr&lt;CSSBasicShapeInset&gt; CSSParser::parseBasicShapeInset(CSSParserValueList&amp; args)
+{
+    auto shape = CSSBasicShapeInset::create();
+
+    CSSParserValue* argument = args.current();
+    Vector&lt;Ref&lt;CSSPrimitiveValue&gt; &gt; widthArguments;
+    bool hasRoundedInset = false;
+    while (argument) {
+        if (argument-&gt;unit == CSSPrimitiveValue::CSS_IDENT &amp;&amp; equalLettersIgnoringASCIICase(argument-&gt;string, &quot;round&quot;)) {
+            hasRoundedInset = true;
+            break;
+        }
+
+        Units unitFlags = FLength | FPercent;
+        ValueWithCalculation argumentWithCalculation(*argument);
+        if (!validateUnit(argumentWithCalculation, unitFlags) || widthArguments.size() &gt; 4)
+            return nullptr;
+
+        widthArguments.append(createPrimitiveNumericValue(argumentWithCalculation));
+        argument = args.next();
+    }
+
+    switch (widthArguments.size()) {
+    case 1: {
+        shape-&gt;updateShapeSize1Value(WTFMove(widthArguments[0]));
+        break;
+    }
+    case 2: {
+        shape-&gt;updateShapeSize2Values(WTFMove(widthArguments[0]), WTFMove(widthArguments[1]));
+        break;
+        }
+    case 3: {
+        shape-&gt;updateShapeSize3Values(WTFMove(widthArguments[0]), WTFMove(widthArguments[1]), WTFMove(widthArguments[2]));
+        break;
+    }
+    case 4: {
+        shape-&gt;updateShapeSize4Values(WTFMove(widthArguments[0]), WTFMove(widthArguments[1]), WTFMove(widthArguments[2]), WTFMove(widthArguments[3]));
+        break;
+    }
+    default:
+        return nullptr;
+    }
+
+    if (hasRoundedInset)
+        return parseInsetRoundedCorners(WTFMove(shape), args);
+    return WTFMove(shape);
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseShapeRadius(CSSParserValue&amp; value)
+{
+    if (value.id == CSSValueClosestSide || value.id == CSSValueFarthestSide)
+        return CSSValuePool::singleton().createIdentifierValue(value.id);
+
+    ValueWithCalculation valueWithCalculation(value);
+    if (!validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg))
+        return nullptr;
+
+    return createPrimitiveNumericValue(valueWithCalculation);
+}
+
+RefPtr&lt;CSSBasicShapeCircle&gt; CSSParser::parseBasicShapeCircle(CSSParserValueList&amp; args)
+{
+    // circle(radius)
+    // circle(radius at &lt;position&gt;)
+    // circle(at &lt;position&gt;)
+    // where position defines centerX and centerY using a CSS &lt;position&gt; data type.
+    auto shape = CSSBasicShapeCircle::create();
+
+    for (CSSParserValue* argument = args.current(); argument; argument = args.next()) {
+        // The call to parseFillPosition below should consume all of the
+        // arguments except the first two. Thus, and index greater than one
+        // indicates an invalid production.
+        if (args.currentIndex() &gt; 1)
+            return nullptr;
+
+        if (!args.currentIndex() &amp;&amp; argument-&gt;id != CSSValueAt) {
+            if (RefPtr&lt;CSSPrimitiveValue&gt; radius = parseShapeRadius(*argument)) {
+                shape-&gt;setRadius(radius.releaseNonNull());
+                continue;
+            }
+
+            return nullptr;
+        }
+
+        if (argument-&gt;id == CSSValueAt &amp;&amp; args.next()) {
+            RefPtr&lt;CSSPrimitiveValue&gt; centerX;
+            RefPtr&lt;CSSPrimitiveValue&gt; centerY;
+            parseFillPosition(args, centerX, centerY);
+            if (centerX &amp;&amp; centerY &amp;&amp; !args.current()) {
+                shape-&gt;setCenterX(centerX.releaseNonNull());
+                shape-&gt;setCenterY(centerY.releaseNonNull());
+            } else
+                return nullptr;
+        } else
+            return nullptr;
+    }
+
+    return WTFMove(shape);
+}
+
+RefPtr&lt;CSSBasicShapeEllipse&gt; CSSParser::parseBasicShapeEllipse(CSSParserValueList&amp; args)
+{
+    // ellipse(radiusX)
+    // ellipse(radiusX at &lt;position&gt;)
+    // ellipse(radiusX radiusY)
+    // ellipse(radiusX radiusY at &lt;position&gt;)
+    // ellipse(at &lt;position&gt;)
+    // where position defines centerX and centerY using a CSS &lt;position&gt; data type.
+    auto shape = CSSBasicShapeEllipse::create();
+
+    for (CSSParserValue* argument = args.current(); argument; argument = args.next()) {
+        // The call to parseFillPosition below should consume all of the
+        // arguments except the first three. Thus, an index greater than two
+        // indicates an invalid production.
+        if (args.currentIndex() &gt; 2)
+            return nullptr;
+
+        if (args.currentIndex() &lt; 2 &amp;&amp; argument-&gt;id != CSSValueAt) {
+            if (RefPtr&lt;CSSPrimitiveValue&gt; radius = parseShapeRadius(*argument)) {
+                if (!shape-&gt;radiusX())
+                    shape-&gt;setRadiusX(radius.releaseNonNull());
+                else
+                    shape-&gt;setRadiusY(radius.releaseNonNull());
+                continue;
+            }
+
+            return nullptr;
+        }
+
+        if (argument-&gt;id != CSSValueAt || !args.next()) // expecting ellipse(.. at &lt;position&gt;)
+            return nullptr;
+
+        RefPtr&lt;CSSPrimitiveValue&gt; centerX;
+        RefPtr&lt;CSSPrimitiveValue&gt; centerY;
+        parseFillPosition(args, centerX, centerY);
+        if (!centerX || !centerY || args.current())
+            return nullptr;
+
+        shape-&gt;setCenterX(centerX.releaseNonNull());
+        shape-&gt;setCenterY(centerY.releaseNonNull());
+    }
+
+    return WTFMove(shape);
+}
+
+RefPtr&lt;CSSBasicShapePolygon&gt; CSSParser::parseBasicShapePolygon(CSSParserValueList&amp; args)
+{
+    unsigned size = args.size();
+    if (!size)
+        return nullptr;
+
+    auto shape = CSSBasicShapePolygon::create();
+
+    CSSParserValue* argument = args.current();
+    if (argument-&gt;id == CSSValueEvenodd || argument-&gt;id == CSSValueNonzero) {
+        shape-&gt;setWindRule(argument-&gt;id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO);
+
+        if (!isComma(args.next()))
+            return nullptr;
+
+        argument = args.next();
+        size -= 2;
+    }
+
+    // &lt;length&gt; &lt;length&gt;, ... &lt;length&gt; &lt;length&gt; -&gt; each pair has 3 elements except the last one
+    if (!size || (size % 3) - 2)
+        return nullptr;
+
+    CSSParserValue* argumentX = argument;
+    while (argumentX) {
+
+        ValueWithCalculation argumentXWithCalculation(*argumentX);
+        if (!validateUnit(argumentXWithCalculation, FLength | FPercent))
+            return nullptr;
+        auto xLength = createPrimitiveNumericValue(argumentXWithCalculation);
+
+        CSSParserValue* argumentY = args.next();
+        if (!argumentY)
+            return nullptr;
+        ValueWithCalculation argumentYWithCalculation(*argumentY);
+        if (!validateUnit(argumentYWithCalculation, FLength | FPercent))
+            return nullptr;
+        auto yLength = createPrimitiveNumericValue(argumentYWithCalculation);
+
+        shape-&gt;appendPoint(WTFMove(xLength), WTFMove(yLength));
+
+        CSSParserValue* commaOrNull = args.next();
+        if (!commaOrNull)
+            argumentX = nullptr;
+        else if (!isComma(commaOrNull)) 
+            return nullptr;
+        else 
+            argumentX = args.next();
+    }
+
+    return WTFMove(shape);
+}
+
+RefPtr&lt;CSSBasicShapePath&gt; CSSParser::parseBasicShapePath(CSSParserValueList&amp; args)
+{
+    unsigned size = args.size();
+    if (size != 1 &amp;&amp; size != 3)
+        return nullptr;
+
+    WindRule windRule = RULE_NONZERO;
+
+    CSSParserValue* argument = args.current();
+    if (argument-&gt;id == CSSValueEvenodd || argument-&gt;id == CSSValueNonzero) {
+        windRule = argument-&gt;id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO;
+
+        if (!isComma(args.next()))
+            return nullptr;
+        argument = args.next();
+    }
+
+    if (argument-&gt;unit != CSSPrimitiveValue::CSS_STRING)
+        return nullptr;
+
+    auto byteStream = std::make_unique&lt;SVGPathByteStream&gt;();
+    if (!buildSVGPathByteStreamFromString(argument-&gt;string, *byteStream, UnalteredParsing))
+        return nullptr;
+
+    auto shape = CSSBasicShapePath::create(WTFMove(byteStream));
+    shape-&gt;setWindRule(windRule);
+
+    args.next();
+    return WTFMove(shape);
+}
+
+static bool isBoxValue(CSSValueID valueId, CSSPropertyID propId)
+{
+    switch (valueId) {
+    case CSSValueContentBox:
+    case CSSValuePaddingBox:
+    case CSSValueBorderBox:
+    case CSSValueMarginBox:
+        return true;
+    case CSSValueFill:
+    case CSSValueStroke:
+    case CSSValueViewBox:
+        return propId == CSSPropertyWebkitClipPath;
+    default: break;
+    }
+
+    return false;
+}
+
+RefPtr&lt;CSSValueList&gt; CSSParser::parseBasicShapeAndOrBox(CSSPropertyID propId)
+{
+    CSSParserValue* value = m_valueList-&gt;current();
+
+    bool shapeFound = false;
+    bool boxFound = false;
+    CSSValueID valueId;
+
+    auto list = CSSValueList::createSpaceSeparated();
+    for (unsigned i = 0; i &lt; 2; ++i) {
+        if (!value)
+            break;
+        valueId = value-&gt;id;
+        if (value-&gt;unit == CSSParserValue::Function &amp;&amp; !shapeFound) {
+            // parseBasicShape already asks for the next value list item.
+            RefPtr&lt;CSSPrimitiveValue&gt; shapeValue = parseBasicShape();
+            if (!shapeValue)
+                return nullptr;
+            list-&gt;append(shapeValue.releaseNonNull());
+            shapeFound = true;
+        } else if (isBoxValue(valueId, propId) &amp;&amp; !boxFound) {
+            RefPtr&lt;CSSPrimitiveValue&gt; parsedValue = CSSValuePool::singleton().createIdentifierValue(valueId);
+            list-&gt;append(parsedValue.releaseNonNull());
+            boxFound = true;
+            m_valueList-&gt;next();
+        } else
+            return nullptr;
+        value = m_valueList-&gt;current();
+    }
+
+    if (m_valueList-&gt;current())
+        return nullptr;
+    return WTFMove(list);
+}
+
+#if ENABLE(CSS_SHAPES)
+RefPtr&lt;CSSValue&gt; CSSParser::parseShapeProperty(CSSPropertyID propId)
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    CSSValueID valueId = value.id;
+
+    if (valueId == CSSValueNone) {
+        m_valueList-&gt;next();
+        return CSSValuePool::singleton().createIdentifierValue(valueId);
+    }
+
+    RefPtr&lt;CSSValue&gt; imageValue;
+    if (valueId != CSSValueNone &amp;&amp; parseFillImage(*m_valueList, imageValue)) {
+        m_valueList-&gt;next();
+        return imageValue;
+    }
+
+    return parseBasicShapeAndOrBox(propId);
+}
+#endif
+
+RefPtr&lt;CSSValue&gt; CSSParser::parseClipPath()
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    CSSValueID valueId = value.id;
+
+    if (valueId == CSSValueNone) {
+        m_valueList-&gt;next();
+        return CSSValuePool::singleton().createIdentifierValue(valueId);
+    }
+    if (value.unit == CSSPrimitiveValue::CSS_URI) {
+        m_valueList-&gt;next();
+        return CSSPrimitiveValue::create(value.string, CSSPrimitiveValue::CSS_URI);
+    }
+
+    return parseBasicShapeAndOrBox(CSSPropertyWebkitClipPath);
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseBasicShape()
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    ASSERT(value.unit == CSSParserValue::Function);
+    CSSParserValueList* args = value.function-&gt;args.get();
+
+    if (!args)
+        return nullptr;
+
+    RefPtr&lt;CSSBasicShape&gt; shape;
+    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;circle(&quot;))
+        shape = parseBasicShapeCircle(*args);
+    else if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;ellipse(&quot;))
+        shape = parseBasicShapeEllipse(*args);
+    else if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;polygon(&quot;))
+        shape = parseBasicShapePolygon(*args);
+    else if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;path(&quot;))
+        shape = parseBasicShapePath(*args);
+    else if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;inset(&quot;))
+        shape = parseBasicShapeInset(*args);
+
+    if (!shape)
+        return nullptr;
+
+    m_valueList-&gt;next();
+    return CSSValuePool::singleton().createValue(shape.releaseNonNull());
+}
+
+// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family'
+bool CSSParser::parseFont(bool important)
+{
+    // Let's check if there is an inherit or initial somewhere in the shorthand.
+    for (unsigned i = 0; i &lt; m_valueList-&gt;size(); ++i) {
+        if (m_valueList-&gt;valueAt(i)-&gt;id == CSSValueInherit || m_valueList-&gt;valueAt(i)-&gt;id == CSSValueInitial)
+            return false;
+    }
+
+    ShorthandScope scope(this, CSSPropertyFont);
+    // Optional font-style, font-variant and font-weight.
+    bool fontStyleParsed = false;
+    bool fontVariantParsed = false;
+    bool fontWeightParsed = false;
+    CSSParserValue* value;
+    while ((value = m_valueList-&gt;current())) {
+        if (!fontStyleParsed &amp;&amp; isValidKeywordPropertyAndValue(CSSPropertyFontStyle, value-&gt;id, m_context, m_styleSheet)) {
+            addProperty(CSSPropertyFontStyle, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
+            fontStyleParsed = true;
+        } else if (!fontVariantParsed &amp;&amp; (value-&gt;id == CSSValueNormal || value-&gt;id == CSSValueSmallCaps)) {
+            // Font variant in the shorthand is particular, it only accepts normal or small-caps.
+            addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
+            fontVariantParsed = true;
+        } else if (!fontWeightParsed &amp;&amp; parseFontWeight(important))
+            fontWeightParsed = true;
+        else
+            break;
+        m_valueList-&gt;next();
+    }
+
+    if (!value)
+        return false;
+
+    if (!fontStyleParsed)
+        addProperty(CSSPropertyFontStyle, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+    if (!fontVariantParsed)
+        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+    if (!fontWeightParsed)
+        addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+
+    // Now a font size _must_ come.
+    // &lt;absolute-size&gt; | &lt;relative-size&gt; | &lt;length&gt; | &lt;percentage&gt; | inherit
+    if (!parseFontSize(important))
+        return false;
+
+    value = m_valueList-&gt;current();
+    if (!value)
+        return false;
+
+    if (isForwardSlashOperator(*value)) {
+        // The line-height property.
+        value = m_valueList-&gt;next();
+        if (!value)
+            return false;
+        if (!parseLineHeight(important))
+            return false;
+    } else
+        addProperty(CSSPropertyLineHeight, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important, true);
+
+    // Font family must come now.
+    RefPtr&lt;CSSValue&gt; parsedFamilyValue = parseFontFamily();
+    if (!parsedFamilyValue)
+        return false;
+
+    addProperty(CSSPropertyFontFamily, parsedFamilyValue.releaseNonNull(), important);
+
+    // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requires that
+    // &quot;font-stretch&quot;, &quot;font-size-adjust&quot;, and &quot;font-kerning&quot; be reset to their initial values
+    // but we don't seem to support them at the moment. They should also be added here once implemented.
+    if (m_valueList-&gt;current())
+        return false;
+
+    return true;
+}
+
+void CSSParser::parseSystemFont(bool important)
+{
+    ASSERT(m_valueList-&gt;size() == 1);
+    CSSValueID systemFontID = m_valueList-&gt;valueAt(0)-&gt;id;
+    ASSERT(systemFontID &gt;= CSSValueCaption &amp;&amp; systemFontID &lt;= CSSValueStatusBar);
+    m_valueList-&gt;next();
+
+    FontCascadeDescription fontDescription;
+    RenderTheme::defaultTheme()-&gt;systemFont(systemFontID, fontDescription);
+    if (!fontDescription.isAbsoluteSize())
+        return;
+
+    // We must set font's constituent properties, even for system fonts, so the cascade functions correctly.
+    ShorthandScope scope(this, CSSPropertyFont);
+    addProperty(CSSPropertyFontStyle, CSSValuePool::singleton().createIdentifierValue(fontDescription.italic() == FontItalicOn ? CSSValueItalic : CSSValueNormal), important);
+    addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createValue(fontDescription.weight()), important);
+    addProperty(CSSPropertyFontSize, CSSValuePool::singleton().createValue(fontDescription.specifiedSize(), CSSPrimitiveValue::CSS_PX), important);
+    Ref&lt;CSSValueList&gt; fontFamilyList = CSSValueList::createCommaSeparated();
+    fontFamilyList-&gt;append(CSSValuePool::singleton().createFontFamilyValue(fontDescription.familyAt(0), FromSystemFontID::Yes));
+    addProperty(CSSPropertyFontFamily, WTFMove(fontFamilyList), important);
+    addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important);
+    addProperty(CSSPropertyLineHeight, CSSValuePool::singleton().createIdentifierValue(CSSValueNormal), important);
+}
+
+class FontFamilyValueBuilder {
+public:
+    FontFamilyValueBuilder(CSSValueList&amp; list)
+        : m_list(list)
+    {
+    }
+
+    void add(const CSSParserString&amp; string)
+    {
+        if (!m_builder.isEmpty())
+            m_builder.append(' ');
+
+        if (string.is8Bit()) {
+            m_builder.append(string.characters8(), string.length());
+            return;
+        }
+
+        m_builder.append(string.characters16(), string.length());
+    }
+
+    void commit()
+    {
+        if (m_builder.isEmpty())
+            return;
+        m_list.append(CSSValuePool::singleton().createFontFamilyValue(m_builder.toString()));
+        m_builder.clear();
+    }
+
+private:
+    StringBuilder m_builder;
+    CSSValueList&amp; m_list;
+};
+
+static bool valueIsCSSKeyword(const CSSParserValue&amp; value)
+{
+    // FIXME: when we add &quot;unset&quot;, we should handle it here.
+    return value.id == CSSValueInitial || value.id == CSSValueInherit || value.id == CSSValueDefault;
+}
+
+RefPtr&lt;CSSValueList&gt; CSSParser::parseFontFamily()
+{
+    auto list = CSSValueList::createCommaSeparated();
+    CSSParserValue* value = m_valueList-&gt;current();
+
+    FontFamilyValueBuilder familyBuilder(list);
+    bool inFamily = false;
+
+    while (value) {
+        CSSParserValue* nextValue = m_valueList-&gt;next();
+        bool nextValBreaksFont = !nextValue ||
+                                 (nextValue-&gt;unit == CSSParserValue::Operator &amp;&amp; nextValue-&gt;iValue == ',');
+        bool nextValIsFontName = nextValue &amp;&amp;
+            ((nextValue-&gt;id &gt;= CSSValueSerif &amp;&amp; nextValue-&gt;id &lt;= CSSValueWebkitBody) ||
+            (nextValue-&gt;unit == CSSPrimitiveValue::CSS_STRING || nextValue-&gt;unit == CSSPrimitiveValue::CSS_IDENT));
+
+        bool valueIsKeyword = valueIsCSSKeyword(*value);
+        if (valueIsKeyword &amp;&amp; !inFamily) {
+            if (nextValBreaksFont)
+                value = m_valueList-&gt;next();
+            else if (nextValIsFontName)
+                value = nextValue;
+            continue;
+        }
+
+        if (value-&gt;id &gt;= CSSValueSerif &amp;&amp; value-&gt;id &lt;= CSSValueWebkitBody) {
+            if (inFamily)
+                familyBuilder.add(value-&gt;string);
+            else if (nextValBreaksFont || !nextValIsFontName)
+                list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            else {
+                familyBuilder.commit();
+                familyBuilder.add(value-&gt;string);
+                inFamily = true;
+            }
+        } else if (value-&gt;unit == CSSPrimitiveValue::CSS_STRING) {
+            // Strings never share in a family name.
+            inFamily = false;
+            familyBuilder.commit();
+            list-&gt;append(CSSValuePool::singleton().createFontFamilyValue(value-&gt;string));
+        } else if (value-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
+            if (inFamily)
+                familyBuilder.add(value-&gt;string);
+            else if (nextValBreaksFont || !nextValIsFontName)
+                list-&gt;append(CSSValuePool::singleton().createFontFamilyValue(value-&gt;string));
+            else {
+                familyBuilder.commit();
+                familyBuilder.add(value-&gt;string);
+                inFamily = true;
+            }
+        } else {
+            break;
+        }
+
+        if (!nextValue)
+            break;
+
+        if (nextValBreaksFont) {
+            value = m_valueList-&gt;next();
+            familyBuilder.commit();
+            inFamily = false;
+        }
+        else if (nextValIsFontName)
+            value = nextValue;
+        else
+            break;
+    }
+    familyBuilder.commit();
+
+    if (!list-&gt;length())
+        return nullptr;
+    return WTFMove(list);
+}
+
+bool CSSParser::parseLineHeight(bool important)
+{
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+    CSSValueID id = valueWithCalculation.value().id;
+    bool validPrimitive = false;
+    // normal | &lt;number&gt; | &lt;length&gt; | &lt;percentage&gt; | inherit
+    if (id == CSSValueNormal)
+        validPrimitive = true;
+    else
+        validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FLength | FPercent | FNonNeg));
+    if (validPrimitive &amp;&amp; (!m_valueList-&gt;next() || inShorthand()))
+        addProperty(CSSPropertyLineHeight, parseValidPrimitive(id, valueWithCalculation), important);
+    return validPrimitive;
+}
+
+bool CSSParser::parseFontSize(bool important)
+{
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+    CSSValueID id = valueWithCalculation.value().id;
+    bool validPrimitive = false;
+    // &lt;absolute-size&gt; | &lt;relative-size&gt; | &lt;length&gt; | &lt;percentage&gt; | inherit
+    if (id &gt;= CSSValueXxSmall &amp;&amp; id &lt;= CSSValueLarger)
+        validPrimitive = true;
+    else
+        validPrimitive = validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
+    if (validPrimitive &amp;&amp; (!m_valueList-&gt;next() || inShorthand()))
+        addProperty(CSSPropertyFontSize, parseValidPrimitive(id, valueWithCalculation), important);
+    return validPrimitive;
+}
+
+static CSSValueID createFontWeightValueKeyword(int weight)
+{
+    ASSERT(!(weight % 100) &amp;&amp; weight &gt;= 100 &amp;&amp; weight &lt;= 900);
+    CSSValueID value = static_cast&lt;CSSValueID&gt;(CSSValue100 + weight / 100 - 1);
+    ASSERT(value &gt;= CSSValue100 &amp;&amp; value &lt;= CSSValue900);
+    return value;
+}
+
+bool CSSParser::parseFontWeight(bool important)
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    if ((value.id &gt;= CSSValueNormal) &amp;&amp; (value.id &lt;= CSSValue900)) {
+        addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(value.id), important);
+        return true;
+    }
+    ValueWithCalculation valueWithCalculation(value);
+    if (validateUnit(valueWithCalculation, FInteger | FNonNeg, CSSQuirksMode)) {
+        int weight = static_cast&lt;int&gt;(parsedDouble(valueWithCalculation));
+        if (!(weight % 100) &amp;&amp; weight &gt;= 100 &amp;&amp; weight &lt;= 900) {
+            addProperty(CSSPropertyFontWeight, CSSValuePool::singleton().createIdentifierValue(createFontWeightValueKeyword(weight)), important);
+            return true;
+        }
+    }
+    return false;
+}
+
+bool CSSParser::parseFontSynthesis(bool important)
+{
+    // none | [ weight || style ]
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (value &amp;&amp; value-&gt;id == CSSValueNone) {
+        addProperty(CSSPropertyFontSynthesis, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+        m_valueList-&gt;next();
+        return true;
+    }
+
+    bool encounteredWeight = false;
+    bool encounteredStyle = false;
+    while (value) {
+        switch (value-&gt;id) {
+        case CSSValueWeight:
+            encounteredWeight = true;
+            break;
+        case CSSValueStyle:
+            encounteredStyle = true;
+            break;
+        default:
+            return false;
+        }
+        value = m_valueList-&gt;next();
+    }
+
+    auto list = CSSValueList::createSpaceSeparated();
+    if (encounteredWeight)
+        list-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight));
+    if (encounteredStyle)
+        list-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
+    addProperty(CSSPropertyFontSynthesis, WTFMove(list), important);
+    return true;
+}
+
+bool CSSParser::parseFontFaceSrcURI(CSSValueList&amp; valueList)
+{
+    auto uriValue = CSSFontFaceSrcValue::create(completeURL(m_valueList-&gt;current()-&gt;string));
+
+    CSSParserValue* value = m_valueList-&gt;next();
+    if (!value) {
+        valueList.append(WTFMove(uriValue));
+        return true;
+    }
+    if (value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',') {
+        m_valueList-&gt;next();
+        valueList.append(WTFMove(uriValue));
+        return true;
+    }
+
+    if (value-&gt;unit != CSSParserValue::Function || !equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;format(&quot;))
+        return false;
+
+    // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20111004/ says that format() contains a comma-separated list of strings,
+    // but CSSFontFaceSrcValue stores only one format. Allowing one format for now.
+    CSSParserValueList* args = value-&gt;function-&gt;args.get();
+    if (!args || args-&gt;size() != 1 || (args-&gt;current()-&gt;unit != CSSPrimitiveValue::CSS_STRING &amp;&amp; args-&gt;current()-&gt;unit != CSSPrimitiveValue::CSS_IDENT))
+        return false;
+    uriValue-&gt;setFormat(args-&gt;current()-&gt;string);
+    valueList.append(WTFMove(uriValue));
+    value = m_valueList-&gt;next();
+    if (value &amp;&amp; value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')
+        m_valueList-&gt;next();
+    return true;
+}
+
+bool CSSParser::parseFontFaceSrcLocal(CSSValueList&amp; valueList)
+{
+    CSSParserValueList* args = m_valueList-&gt;current()-&gt;function-&gt;args.get();
+    if (!args || !args-&gt;size())
+        return false;
+
+    if (args-&gt;size() == 1 &amp;&amp; args-&gt;current()-&gt;unit == CSSPrimitiveValue::CSS_STRING)
+        valueList.append(CSSFontFaceSrcValue::createLocal(args-&gt;current()-&gt;string));
+    else if (args-&gt;current()-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
+        StringBuilder builder;
+        for (CSSParserValue* localValue = args-&gt;current(); localValue; localValue = args-&gt;next()) {
+            if (localValue-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+                return false;
+            if (!builder.isEmpty())
+                builder.append(' ');
+            builder.append(localValue-&gt;string);
+        }
+        valueList.append(CSSFontFaceSrcValue::createLocal(builder.toString()));
+    } else
+        return false;
+
+    if (CSSParserValue* value = m_valueList-&gt;next()) {
+        if (value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')
+            m_valueList-&gt;next();
+    }
+    return true;
+}
+
+bool CSSParser::parseFontFaceSrc()
+{
+    auto values = CSSValueList::createCommaSeparated();
+
+    while (CSSParserValue* value = m_valueList-&gt;current()) {
+        if (value-&gt;unit == CSSPrimitiveValue::CSS_URI) {
+            if (!parseFontFaceSrcURI(values))
+                return false;
+        } else if (value-&gt;unit == CSSParserValue::Function &amp;&amp; equalLettersIgnoringASCIICase(value-&gt;function-&gt;name, &quot;local(&quot;)) {
+            if (!parseFontFaceSrcLocal(values))
+                return false;
+        } else
+            return false;
+    }
+    if (!values-&gt;length())
+        return false;
+
+    addProperty(CSSPropertySrc, WTFMove(values), m_important);
+    m_valueList-&gt;next();
+    return true;
+}
+
+bool CSSParser::parseFontFaceUnicodeRange()
+{
+    auto values = CSSValueList::createCommaSeparated();
+    bool failed = false;
+    bool operatorExpected = false;
+    for (; m_valueList-&gt;current(); m_valueList-&gt;next(), operatorExpected = !operatorExpected) {
+        if (operatorExpected) {
+            if (m_valueList-&gt;current()-&gt;unit == CSSParserValue::Operator &amp;&amp; m_valueList-&gt;current()-&gt;iValue == ',')
+                continue;
+            failed = true;
+            break;
+        }
+        if (m_valueList-&gt;current()-&gt;unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) {
+            failed = true;
+            break;
+        }
+
+        String rangeString = m_valueList-&gt;current()-&gt;string;
+        UChar32 from = 0;
+        UChar32 to = 0;
+        unsigned length = rangeString.length();
+
+        if (length &lt; 3) {
+            failed = true;
+            break;
+        }
+
+        unsigned i = 2;
+        while (i &lt; length) {
+            UChar c = rangeString[i];
+            if (c == '-' || c == '?')
+                break;
+            from *= 16;
+            if (c &gt;= '0' &amp;&amp; c &lt;= '9')
+                from += c - '0';
+            else if (c &gt;= 'A' &amp;&amp; c &lt;= 'F')
+                from += 10 + c - 'A';
+            else if (c &gt;= 'a' &amp;&amp; c &lt;= 'f')
+                from += 10 + c - 'a';
+            else {
+                failed = true;
+                break;
+            }
+            i++;
+        }
+        if (failed)
+            break;
+
+        if (i == length)
+            to = from;
+        else if (rangeString[i] == '?') {
+            unsigned span = 1;
+            while (i &lt; length &amp;&amp; rangeString[i] == '?') {
+                span *= 16;
+                from *= 16;
+                i++;
+            }
+            if (i &lt; length)
+                failed = true;
+            to = from + span - 1;
+        } else {
+            if (length &lt; i + 2) {
+                failed = true;
+                break;
+            }
+            i++;
+            while (i &lt; length) {
+                UChar c = rangeString[i];
+                to *= 16;
+                if (c &gt;= '0' &amp;&amp; c &lt;= '9')
+                    to += c - '0';
+                else if (c &gt;= 'A' &amp;&amp; c &lt;= 'F')
+                    to += 10 + c - 'A';
+                else if (c &gt;= 'a' &amp;&amp; c &lt;= 'f')
+                    to += 10 + c - 'a';
+                else {
+                    failed = true;
+                    break;
+                }
+                i++;
+            }
+            if (failed)
+                break;
+        }
+        if (from &lt;= to)
+            values-&gt;append(CSSUnicodeRangeValue::create(from, to));
+    }
+    if (failed || !values-&gt;length())
+        return false;
+    addProperty(CSSPropertyUnicodeRange, WTFMove(values), m_important);
+    return true;
+}
+
+// Returns the number of characters which form a valid double
+// and are terminated by the given terminator character
+template &lt;typename CharacterType&gt;
+static int checkForValidDouble(const CharacterType* string, const CharacterType* end, const char terminator)
+{
+    int length = end - string;
+    if (length &lt; 1)
+        return 0;
+
+    bool decimalMarkSeen = false;
+    int processedLength = 0;
+
+    for (int i = 0; i &lt; length; ++i) {
+        if (string[i] == terminator) {
+            processedLength = i;
+            break;
+        }
+        if (!isASCIIDigit(string[i])) {
+            if (!decimalMarkSeen &amp;&amp; string[i] == '.')
+                decimalMarkSeen = true;
+            else
+                return 0;
+        }
+    }
+
+    if (decimalMarkSeen &amp;&amp; processedLength == 1)
+        return 0;
+
+    return processedLength;
+}
+
+// Returns the number of characters consumed for parsing a valid double
+// terminated by the given terminator character
+template &lt;typename CharacterType&gt;
+static int parseDouble(const CharacterType* string, const CharacterType* end, const char terminator, double&amp; value)
+{
+    int length = checkForValidDouble(string, end, terminator);
+    if (!length)
+        return 0;
+
+    int position = 0;
+    double localValue = 0;
+
+    // The consumed characters here are guaranteed to be
+    // ASCII digits with or without a decimal mark
+    for (; position &lt; length; ++position) {
+        if (string[position] == '.')
+            break;
+        localValue = localValue * 10 + string[position] - '0';
+    }
+
+    if (++position == length) {
+        value = localValue;
+        return length;
+    }
+
+    double fraction = 0;
+    double scale = 1;
+
+    while (position &lt; length &amp;&amp; scale &lt; MAX_SCALE) {
+        fraction = fraction * 10 + string[position++] - '0';
+        scale *= 10;
+    }
+
+    value = localValue + fraction / scale;
+    return length;
+}
+
+template &lt;typename CharacterType&gt;
+static bool parseColorIntOrPercentage(const CharacterType*&amp; string, const CharacterType* end, const char terminator, CSSPrimitiveValue::UnitTypes&amp; expect, int&amp; value)
+{
+    const CharacterType* current = string;
+    double localValue = 0;
+    bool negative = false;
+    while (current != end &amp;&amp; isHTMLSpace(*current))
+        current++;
+    if (current != end &amp;&amp; *current == '-') {
+        negative = true;
+        current++;
+    }
+    if (current == end || !isASCIIDigit(*current))
+        return false;
+    while (current != end &amp;&amp; isASCIIDigit(*current)) {
+        double newValue = localValue * 10 + *current++ - '0';
+        if (newValue &gt;= 255) {
+            // Clamp values at 255.
+            localValue = 255;
+            while (current != end &amp;&amp; isASCIIDigit(*current))
+                ++current;
+            break;
+        }
+        localValue = newValue;
+    }
+
+    if (current == end)
+        return false;
+
+    if (expect == CSSPrimitiveValue::CSS_NUMBER &amp;&amp; (*current == '.' || *current == '%'))
+        return false;
+
+    if (*current == '.') {
+        // We already parsed the integral part, try to parse
+        // the fraction part of the percentage value.
+        double percentage = 0;
+        int numCharactersParsed = parseDouble(current, end, '%', percentage);
+        if (!numCharactersParsed)
+            return false;
+        current += numCharactersParsed;
+        if (*current != '%')
+            return false;
+        localValue += percentage;
+    }
+
+    if (expect == CSSPrimitiveValue::CSS_PERCENTAGE &amp;&amp; *current != '%')
+        return false;
+
+    if (*current == '%') {
+        expect = CSSPrimitiveValue::CSS_PERCENTAGE;
+        localValue = localValue / 100.0 * 256.0;
+        // Clamp values at 255 for percentages over 100%
+        if (localValue &gt; 255)
+            localValue = 255;
+        current++;
+    } else
+        expect = CSSPrimitiveValue::CSS_NUMBER;
+
+    while (current != end &amp;&amp; isHTMLSpace(*current))
+        current++;
+    if (current == end || *current++ != terminator)
+        return false;
+    // Clamp negative values at zero.
+    value = negative ? 0 : static_cast&lt;int&gt;(localValue);
+    string = current;
+    return true;
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool isTenthAlpha(const CharacterType* string, const int length)
+{
+    // &quot;0.X&quot;
+    if (length == 3 &amp;&amp; string[0] == '0' &amp;&amp; string[1] == '.' &amp;&amp; isASCIIDigit(string[2]))
+        return true;
+
+    // &quot;.X&quot;
+    if (length == 2 &amp;&amp; string[0] == '.' &amp;&amp; isASCIIDigit(string[1]))
+        return true;
+
+    return false;
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool parseAlphaValue(const CharacterType*&amp; string, const CharacterType* end, const char terminator, int&amp; value)
+{
+    while (string != end &amp;&amp; isHTMLSpace(*string))
+        ++string;
+
+    bool negative = false;
+
+    if (string != end &amp;&amp; *string == '-') {
+        negative = true;
+        ++string;
+    }
+
+    value = 0;
+
+    int length = end - string;
+    if (length &lt; 2)
+        return false;
+
+    if (string[length - 1] != terminator || !isASCIIDigit(string[length - 2]))
+        return false;
+
+    if (string[0] != '0' &amp;&amp; string[0] != '1' &amp;&amp; string[0] != '.') {
+        if (checkForValidDouble(string, end, terminator)) {
+            value = negative ? 0 : 255;
+            string = end;
+            return true;
+        }
+        return false;
+    }
+
+    if (length == 2 &amp;&amp; string[0] != '.') {
+        value = !negative &amp;&amp; string[0] == '1' ? 255 : 0;
+        string = end;
+        return true;
+    }
+
+    if (isTenthAlpha(string, length - 1)) {
+        static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 };
+        value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
+        string = end;
+        return true;
+    }
+
+    double alpha = 0;
+    if (!parseDouble(string, end, terminator, alpha))
+        return false;
+    value = negative ? 0 : static_cast&lt;int&gt;(alpha * nextafter(256.0, 0.0));
+    string = end;
+    return true;
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool mightBeRGBA(const CharacterType* characters, unsigned length)
+{
+    if (length &lt; 5)
+        return false;
+    return characters[4] == '('
+        &amp;&amp; isASCIIAlphaCaselessEqual(characters[0], 'r')
+        &amp;&amp; isASCIIAlphaCaselessEqual(characters[1], 'g')
+        &amp;&amp; isASCIIAlphaCaselessEqual(characters[2], 'b')
+        &amp;&amp; isASCIIAlphaCaselessEqual(characters[3], 'a');
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool mightBeRGB(const CharacterType* characters, unsigned length)
+{
+    if (length &lt; 4)
+        return false;
+    return characters[3] == '('
+        &amp;&amp; isASCIIAlphaCaselessEqual(characters[0], 'r')
+        &amp;&amp; isASCIIAlphaCaselessEqual(characters[1], 'g')
+        &amp;&amp; isASCIIAlphaCaselessEqual(characters[2], 'b');
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool fastParseColorInternal(RGBA32&amp; rgb, const CharacterType* characters, unsigned length , bool strict)
+{
+    CSSPrimitiveValue::UnitTypes expect = CSSPrimitiveValue::CSS_UNKNOWN;
+    
+    if (!strict &amp;&amp; length &gt;= 3) {
+        if (characters[0] == '#') {
+            if (Color::parseHexColor(characters + 1, length - 1, rgb))
+                return true;
+        } else {
+            if (Color::parseHexColor(characters, length, rgb))
+                return true;
+        }
+    }
+
+    // Try rgba() syntax.
+    if (mightBeRGBA(characters, length)) {
+        const CharacterType* current = characters + 5;
+        const CharacterType* end = characters + length;
+        int red;
+        int green;
+        int blue;
+        int alpha;
+        
+        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
+            return false;
+        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
+            return false;
+        if (!parseColorIntOrPercentage(current, end, ',', expect, blue))
+            return false;
+        if (!parseAlphaValue(current, end, ')', alpha))
+            return false;
+        if (current != end)
+            return false;
+        rgb = makeRGBA(red, green, blue, alpha);
+        return true;
+    }
+
+    // Try rgb() syntax.
+    if (mightBeRGB(characters, length)) {
+        const CharacterType* current = characters + 4;
+        const CharacterType* end = characters + length;
+        int red;
+        int green;
+        int blue;
+        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
+            return false;
+        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
+            return false;
+        if (!parseColorIntOrPercentage(current, end, ')', expect, blue))
+            return false;
+        if (current != end)
+            return false;
+        rgb = makeRGB(red, green, blue);
+        return true;
+    }
+
+    return false;
+}
+
+template&lt;typename StringType&gt;
+bool CSSParser::fastParseColor(RGBA32&amp; rgb, const StringType&amp; name, bool strict)
+{
+    unsigned length = name.length();
+    bool parseResult;
+
+    if (!length)
+        return false;
+
+    if (name.is8Bit())
+        parseResult = fastParseColorInternal(rgb, name.characters8(), length, strict);
+    else
+        parseResult = fastParseColorInternal(rgb, name.characters16(), length, strict);
+
+    if (parseResult)
+        return true;
+
+    // Try named colors.
+    Color tc;
+    tc.setNamedColor(name);
+    if (tc.isValid()) {
+        rgb = tc.rgb();
+        return true;
+    }
+    return false;
+}
+    
+inline double CSSParser::parsedDouble(ValueWithCalculation&amp; valueWithCalculation)
+{
+    return valueWithCalculation.calculation() ? valueWithCalculation.calculation()-&gt;doubleValue() : valueWithCalculation.value().fValue;
+}
+
+bool CSSParser::isCalculation(CSSParserValue&amp; value)
+{
+    return value.unit == CSSParserValue::Function
+        &amp;&amp; (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;calc(&quot;)
+            || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-calc(&quot;));
+}
+
+inline int CSSParser::colorIntFromValue(ValueWithCalculation&amp; valueWithCalculation)
+{
+    bool isPercent;
+    
+    if (valueWithCalculation.calculation())
+        isPercent = valueWithCalculation.calculation()-&gt;category() == CalcPercent;
+    else
+        isPercent = valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_PERCENTAGE;
+
+    const double doubleValue = parsedDouble(valueWithCalculation);
+    
+    if (doubleValue &lt;= 0.0)
+        return 0;
+
+    if (isPercent) {
+        if (doubleValue &gt;= 100.0)
+            return 255;
+        return static_cast&lt;int&gt;(doubleValue * 256.0 / 100.0);
+    }
+
+    if (doubleValue &gt;= 255.0)
+        return 255;
+
+    return static_cast&lt;int&gt;(doubleValue);
+}
+
+bool CSSParser::parseColorParameters(CSSParserValue&amp; value, int* colorArray, bool parseAlpha)
+{
+    CSSParserValueList* args = value.function-&gt;args.get();
+    ValueWithCalculation firstArgumentWithCalculation(*args-&gt;current());
+    Units unitType = FUnknown;
+    // Get the first value and its type
+    if (validateUnit(firstArgumentWithCalculation, FInteger, CSSStrictMode))
+        unitType = FInteger;
+    else if (validateUnit(firstArgumentWithCalculation, FPercent, CSSStrictMode))
+        unitType = FPercent;
+    else
+        return false;
+    
+    colorArray[0] = colorIntFromValue(firstArgumentWithCalculation);
+    for (int i = 1; i &lt; 3; i++) {
+        CSSParserValue&amp; operatorArgument = *args-&gt;next();
+        if (operatorArgument.unit != CSSParserValue::Operator &amp;&amp; operatorArgument.iValue != ',')
+            return false;
+        ValueWithCalculation argumentWithCalculation(*args-&gt;next());
+        if (!validateUnit(argumentWithCalculation, unitType, CSSStrictMode))
+            return false;
+        colorArray[i] = colorIntFromValue(argumentWithCalculation);
+    }
+    if (parseAlpha) {
+        CSSParserValue&amp; operatorArgument = *args-&gt;next();
+        if (operatorArgument.unit != CSSParserValue::Operator &amp;&amp; operatorArgument.iValue != ',')
+            return false;
+        ValueWithCalculation argumentWithCalculation(*args-&gt;next());
+        if (!validateUnit(argumentWithCalculation, FNumber, CSSStrictMode))
+            return false;
+        double doubleValue = parsedDouble(argumentWithCalculation);
+        // Convert the floating pointer number of alpha to an integer in the range [0, 256),
+        // with an equal distribution across all 256 values.
+        colorArray[3] = static_cast&lt;int&gt;(std::max&lt;double&gt;(0, std::min&lt;double&gt;(1, doubleValue)) * nextafter(256.0, 0.0));
+    }
+    return true;
+}
+
+// The CSS3 specification defines the format of a HSL color as
+// hsl(&lt;number&gt;, &lt;percent&gt;, &lt;percent&gt;)
+// and with alpha, the format is
+// hsla(&lt;number&gt;, &lt;percent&gt;, &lt;percent&gt;, &lt;number&gt;)
+// The first value, HUE, is in an angle with a value between 0 and 360
+bool CSSParser::parseHSLParameters(CSSParserValue&amp; value, double* colorArray, bool parseAlpha)
+{
+    CSSParserValueList* args = value.function-&gt;args.get();
+    ValueWithCalculation firstArgumentWithCalculation(*args-&gt;current());
+    // Get the first value
+    if (!validateUnit(firstArgumentWithCalculation, FNumber, CSSStrictMode))
+        return false;
+    // normalize the Hue value and change it to be between 0 and 1.0
+    colorArray[0] = (((static_cast&lt;int&gt;(parsedDouble(firstArgumentWithCalculation)) % 360) + 360) % 360) / 360.0;
+    for (int i = 1; i &lt; 3; ++i) {
+        CSSParserValue&amp; operatorArgument = *args-&gt;next();
+        if (operatorArgument.unit != CSSParserValue::Operator &amp;&amp; operatorArgument.iValue != ',')
+            return false;
+        ValueWithCalculation argumentWithCalculation(*args-&gt;next());
+        if (!validateUnit(argumentWithCalculation, FPercent, CSSStrictMode))
+            return false;
+        colorArray[i] = std::max&lt;double&gt;(0, std::min&lt;double&gt;(100, parsedDouble(argumentWithCalculation))) / 100.0; // needs to be value between 0 and 1.0
+    }
+    if (parseAlpha) {
+        CSSParserValue&amp; operatorArgument = *args-&gt;next();
+        if (operatorArgument.unit != CSSParserValue::Operator &amp;&amp; operatorArgument.iValue != ',')
+            return false;
+        ValueWithCalculation argumentWithCalculation(*args-&gt;next());
+        if (!validateUnit(argumentWithCalculation, FNumber, CSSStrictMode))
+            return false;
+        colorArray[3] = std::max&lt;double&gt;(0, std::min&lt;double&gt;(1, parsedDouble(argumentWithCalculation)));
+    }
+    return true;
+}
+
+RefPtr&lt;CSSPrimitiveValue&gt; CSSParser::parseColor(CSSParserValue* value)
+{
+    RGBA32 c = Color::transparent;
+    if (!parseColorFromValue(value ? *value : *m_valueList-&gt;current(), c))
+        return nullptr;
+    return CSSValuePool::singleton().createColorValue(c);
+}
+
+bool CSSParser::parseColorFromValue(CSSParserValue&amp; value, RGBA32&amp; c)
+{
+    if (inQuirksMode() &amp;&amp; value.unit == CSSPrimitiveValue::CSS_NUMBER
+        &amp;&amp; value.fValue &gt;= 0. &amp;&amp; value.fValue &lt; 1000000.) {
+        String str = String::format(&quot;%06d&quot;, static_cast&lt;int&gt;((value.fValue+.5)));
+        // FIXME: This should be strict parsing for SVG as well.
+        if (!fastParseColor(c, str, inStrictMode()))
+            return false;
+    } else if (value.unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR
+        || value.unit == CSSPrimitiveValue::CSS_IDENT
+        || (inQuirksMode() &amp;&amp; value.unit == CSSPrimitiveValue::CSS_DIMENSION)) {
+        if (!fastParseColor(c, value.string, inStrictMode() &amp;&amp; value.unit == CSSPrimitiveValue::CSS_IDENT))
+            return false;
+    } else if (value.unit == CSSParserValue::Function
+        &amp;&amp; value.function-&gt;args
+        &amp;&amp; value.function-&gt;args-&gt;size() == 5 /* rgb + two commas */
+        &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;rgb(&quot;)) {
+        int colorValues[3];
+        if (!parseColorParameters(value, colorValues, false))
+            return false;
+        c = makeRGB(colorValues[0], colorValues[1], colorValues[2]);
+    } else {
+        if (value.unit == CSSParserValue::Function
+            &amp;&amp; value.function-&gt;args
+            &amp;&amp; value.function-&gt;args-&gt;size() == 7 /* rgba + three commas */
+            &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;rgba(&quot;)) {
+            int colorValues[4];
+            if (!parseColorParameters(value, colorValues, true))
+                return false;
+            c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
+        } else if (value.unit == CSSParserValue::Function
+            &amp;&amp; value.function-&gt;args
+            &amp;&amp; value.function-&gt;args-&gt;size() == 5 /* hsl + two commas */
+            &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;hsl(&quot;)) {
+            double colorValues[3];
+            if (!parseHSLParameters(value, colorValues, false))
+                return false;
+            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0);
+        } else if (value.unit == CSSParserValue::Function
+            &amp;&amp; value.function-&gt;args
+            &amp;&amp; value.function-&gt;args-&gt;size() == 7 /* hsla + three commas */
+            &amp;&amp; equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;hsla(&quot;)) {
+            double colorValues[4];
+            if (!parseHSLParameters(value, colorValues, true))
+                return false;
+            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
+        } else
+            return false;
+    }
+
+    return true;
+}
+
+// This class tracks parsing state for shadow values.  If it goes out of scope (e.g., due to an early return)
+// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
+struct ShadowParseContext {
+    ShadowParseContext(CSSPropertyID prop, CSSParser&amp; parser)
+        : property(prop)
+        , m_parser(parser)
+        , allowX(true)
+        , allowY(false)
+        , allowBlur(false)
+        , allowSpread(false)
+        , allowColor(true)
+        , allowStyle(prop == CSSPropertyWebkitBoxShadow || prop == CSSPropertyBoxShadow)
+        , allowBreak(true)
+    {
+    }
+
+    bool allowLength() { return allowX || allowY || allowBlur || allowSpread; }
+
+    void commitValue()
+    {
+        // Handle the ,, case gracefully by doing nothing.
+        if (x || y || blur || spread || color || style) {
+            if (!values)
+                values = CSSValueList::createCommaSeparated();
+
+            // Construct the current shadow value and add it to the list.
+            values-&gt;append(CSSShadowValue::create(WTFMove(x), WTFMove(y), WTFMove(blur), WTFMove(spread), WTFMove(style), WTFMove(color)));
+        }
+
+        // Now reset for the next shadow value.
+        x = nullptr;
+        y = nullptr;
+        blur = nullptr;
+        spread = nullptr;
+        style = nullptr;
+        color = nullptr;
+
+        allowX = true;
+        allowColor = true;
+        allowBreak = true;
+        allowY = false;
+        allowBlur = false;
+        allowSpread = false;
+        allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+    }
+
+    void commitLength(CSSParser::ValueWithCalculation&amp; valueWithCalculation)
+    {
+        auto primitiveValue = m_parser.createPrimitiveNumericValue(valueWithCalculation);
+
+        if (allowX) {
+            x = WTFMove(primitiveValue);
+            allowX = false;
+            allowY = true;
+            allowColor = false;
+            allowStyle = false;
+            allowBreak = false;
+        } else if (allowY) {
+            y = WTFMove(primitiveValue);
+            allowY = false;
+            allowBlur = true;
+            allowColor = true;
+            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+            allowBreak = true;
+        } else if (allowBlur) {
+            blur = WTFMove(primitiveValue);
+            allowBlur = false;
+            allowSpread = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+        } else if (allowSpread) {
+            spread = WTFMove(primitiveValue);
+            allowSpread = false;
+        }
+    }
+
+    void commitColor(RefPtr&lt;CSSPrimitiveValue&gt;&amp;&amp; val)
+    {
+        color = val;
+        allowColor = false;
+        if (allowX) {
+            allowStyle = false;
+            allowBreak = false;
+        } else {
+            allowBlur = false;
+            allowSpread = false;
+            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+        }
+    }
+
+    void commitStyle(CSSParserValue&amp; value)
+    {
+        style = CSSValuePool::singleton().createIdentifierValue(value.id);
+        allowStyle = false;
+        if (allowX)
+            allowBreak = false;
+        else {
+            allowBlur = false;
+            allowSpread = false;
+            allowColor = false;
+        }
+    }
+
+    CSSPropertyID property;
+    CSSParser&amp; m_parser;
+
+    RefPtr&lt;CSSValueList&gt; values;
+    RefPtr&lt;CSSPrimitiveValue&gt; x;
+    RefPtr&lt;CSSPrimitiveValue&gt; y;
+    RefPtr&lt;CSSPrimitiveValue&gt; blur;
+    RefPtr&lt;CSSPrimitiveValue&gt; spread;
+    RefPtr&lt;CSSPrimitiveValue&gt; style;
+    RefPtr&lt;CSSPrimitiveValue&gt; color;
+
+    bool allowX;
+    bool allowY;
+    bool allowBlur;
+    bool allowSpread;
+    bool allowColor;
+    bool allowStyle; // inset or not.
+    bool allowBreak;
+};
+
+RefPtr&lt;CSSValueList&gt; CSSParser::parseShadow(CSSParserValueList&amp; valueList, CSSPropertyID propId)
+{
+    ShadowParseContext context(propId, *this);
+    CSSParserValue* value;
+    while ((value = valueList.current())) {
+        ValueWithCalculation valueWithCalculation(*value);
+        // Check for a comma break first.
+        if (value-&gt;unit == CSSParserValue::Operator) {
+            if (value-&gt;iValue != ',' || !context.allowBreak) {
+                // Other operators aren't legal or we aren't done with the current shadow
+                // value.  Treat as invalid.
+                return nullptr;
+            }
+            // -webkit-svg-shadow does not support multiple values.
+            if (propId == CSSPropertyWebkitSvgShadow)
+                return nullptr;
+            // The value is good.  Commit it.
+            context.commitValue();
+        } else if (validateUnit(valueWithCalculation, FLength, CSSStrictMode)) {
+            // We required a length and didn't get one. Invalid.
+            if (!context.allowLength())
+                return nullptr;
+
+            // Blur radius must be non-negative.
+            if (context.allowBlur &amp;&amp; !validateUnit(valueWithCalculation, FLength | FNonNeg, CSSStrictMode))
+                return nullptr;
+
+            // A length is allowed here.  Construct the value and add it.
+            context.commitLength(valueWithCalculation);
+        } else if (value-&gt;id == CSSValueInset) {
+            if (!context.allowStyle)
+                return nullptr;
+
+            context.commitStyle(valueWithCalculation);
+        } else {
+            // The only other type of value that's ok is a color value.
+            RefPtr&lt;CSSPrimitiveValue&gt; parsedColor;
+            bool isColor = (isValidSystemColorValue(value-&gt;id) || value-&gt;id == CSSValueMenu
+                || (value-&gt;id &gt;= CSSValueWebkitFocusRingColor &amp;&amp; value-&gt;id &lt;= CSSValueWebkitText &amp;&amp; inQuirksMode())
+                || value-&gt;id == CSSValueCurrentcolor);
+            if (isColor) {
+                if (!context.allowColor)
+                    return nullptr;
+                parsedColor = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+            }
+
+            if (!parsedColor)
+                // It's not built-in. Try to parse it as a color.
+                parsedColor = parseColor(value);
+
+            if (!parsedColor || !context.allowColor)
+                return nullptr; // This value is not a color or length and is invalid or
+                          // it is a color, but a color isn't allowed at this point.
+
+            context.commitColor(parsedColor.releaseNonNull());
+        }
+
+        valueList.next();
+    }
+
+    if (context.allowBreak) {
+        context.commitValue();
+        if (context.values &amp;&amp; context.values-&gt;length())
+            return WTFMove(context.values);
+    }
+
+    return nullptr;
+}
+
+bool CSSParser::parseReflect(CSSPropertyID propId, bool important)
+{
+    // box-reflect: &lt;direction&gt; &lt;offset&gt; &lt;mask&gt;
+
+    // Direction comes first.
+    CSSParserValue* value = m_valueList-&gt;current();
+    RefPtr&lt;CSSPrimitiveValue&gt; direction;
+    switch (value-&gt;id) {
+        case CSSValueAbove:
+        case CSSValueBelow:
+        case CSSValueLeft:
+        case CSSValueRight:
+            direction = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+            break;
+        default:
+            return false;
+    }
+
+    // The offset comes next.
+    value = m_valueList-&gt;next();
+    RefPtr&lt;CSSPrimitiveValue&gt; offset;
+    if (!value)
+        offset = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_PX);
+    else {
+        ValueWithCalculation valueWithCalculation(*value);
+        if (!validateUnit(valueWithCalculation, FLength | FPercent))
+            return false;
+        offset = createPrimitiveNumericValue(valueWithCalculation);
+    }
+
+    // Now for the mask.
+    RefPtr&lt;CSSValue&gt; mask;
+    value = m_valueList-&gt;next();
+    if (value) {
+        if (!parseBorderImage(propId, mask))
+            return false;
+    }
+
+    addProperty(propId, CSSReflectValue::create(direction.releaseNonNull(), offset.releaseNonNull(), WTFMove(mask)), important);
+    m_valueList-&gt;next();
+    return true;
+}
+
+bool CSSParser::parseFlex(CSSParserValueList&amp; args, bool important)
+{
+    if (!args.size() || args.size() &gt; 3)
+        return false;
+    static const double unsetValue = -1;
+    double flexGrow = unsetValue;
+    double flexShrink = unsetValue;
+    RefPtr&lt;CSSPrimitiveValue&gt; flexBasis;
+
+    while (CSSParserValue* argument = args.current()) {
+        ValueWithCalculation argumentWithCalculation(*argument);
+        if (validateUnit(argumentWithCalculation, FNumber | FNonNeg)) {
+            if (flexGrow == unsetValue)
+                flexGrow = parsedDouble(argumentWithCalculation);
+            else if (flexShrink == unsetValue)
+                flexShrink = parsedDouble(argumentWithCalculation);
+            else if (!parsedDouble(argumentWithCalculation)) {
+                // flex only allows a basis of 0 (sans units) if flex-grow and flex-shrink values have already been set.
+                flexBasis = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_PX);
+            } else {
+                // We only allow 3 numbers without units if the last value is 0. E.g., flex:1 1 1 is invalid.
+                return false;
+            }
+        } else if (!flexBasis &amp;&amp; (argumentWithCalculation.value().id == CSSValueAuto || validateUnit(argumentWithCalculation, FLength | FPercent | FNonNeg)))
+            flexBasis = parseValidPrimitive(argumentWithCalculation.value().id, argumentWithCalculation);
+        else {
+            // Not a valid arg for flex.
+            return false;
+        }
+        args.next();
+    }
+
+    if (flexGrow == unsetValue)
+        flexGrow = 1;
+    if (flexShrink == unsetValue)
+        flexShrink = 1;
+    if (!flexBasis)
+        flexBasis = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_PX);
+
+    addProperty(CSSPropertyFlexGrow, CSSValuePool::singleton().createValue(clampToFloat(flexGrow), CSSPrimitiveValue::CSS_NUMBER), important);
+    addProperty(CSSPropertyFlexShrink, CSSValuePool::singleton().createValue(clampToFloat(flexShrink), CSSPrimitiveValue::CSS_NUMBER), important);
+    addProperty(CSSPropertyFlexBasis, flexBasis.releaseNonNull(), important);
+    return true;
+}
+
+struct BorderImageParseContext {
+    BorderImageParseContext()
+    : m_canAdvance(false)
+    , m_allowCommit(true)
+    , m_allowImage(true)
+    , m_allowImageSlice(true)
+    , m_allowRepeat(true)
+    , m_allowForwardSlashOperator(false)
+    , m_requireWidth(false)
+    , m_requireOutset(false)
+    {}
+
+    bool canAdvance() const { return m_canAdvance; }
+    void setCanAdvance(bool canAdvance) { m_canAdvance = canAdvance; }
+
+    bool allowCommit() const { return m_allowCommit; }
+    bool allowImage() const { return m_allowImage; }
+    bool allowImageSlice() const { return m_allowImageSlice; }
+    bool allowRepeat() const { return m_allowRepeat; }
+    bool allowForwardSlashOperator() const { return m_allowForwardSlashOperator; }
+
+    bool requireWidth() const { return m_requireWidth; }
+    bool requireOutset() const { return m_requireOutset; }
+
+    void commitImage(RefPtr&lt;CSSValue&gt;&amp;&amp; image)
+    {
+        m_image = WTFMove(image);
+        m_canAdvance = true;
+        m_allowCommit = true;
+        m_allowImage = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
+        m_allowImageSlice = !m_imageSlice;
+        m_allowRepeat = !m_repeat;
+    }
+    void commitImageSlice(RefPtr&lt;CSSBorderImageSliceValue&gt;&amp;&amp; slice)
+    {
+        m_imageSlice = WTFMove(slice);
+        m_canAdvance = true;
+        m_allowCommit = m_allowForwardSlashOperator = true;
+        m_allowImageSlice = m_requireWidth = m_requireOutset = false;
+        m_allowImage = !m_image;
+        m_allowRepeat = !m_repeat;
+    }
+    void commitForwardSlashOperator()
+    {
+        m_canAdvance = true;
+        m_allowCommit = m_allowImage = m_allowImageSlice = m_allowRepeat = m_allowForwardSlashOperator = false;
+        if (!m_borderSlice) {
+            m_requireWidth = true;
+            m_requireOutset = false;
+        } else {
+            m_requireOutset = true;
+            m_requireWidth = false;
+        }
+    }
+    void commitBorderWidth(RefPtr&lt;CSSPrimitiveValue&gt;&amp;&amp; slice)
+    {
+        m_borderSlice = WTFMove(slice);
+        m_canAdvance = true;
+        m_allowCommit = m_allowForwardSlashOperator = true;
+        m_allowImageSlice = m_requireWidth = m_requireOutset = false;
+        m_allowImage = !m_image;
+        m_allowRepeat = !m_repeat;
+    }
+    void commitBorderOutset(RefPtr&lt;CSSPrimitiveValue&gt;&amp;&amp; outset)
+    {
+        m_outset = WTFMove(outset);
+        m_canAdvance = true;
+        m_allowCommit = true;
+        m_allowImageSlice = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
+        m_allowImage = !m_image;
+        m_allowRepeat = !m_repeat;
+    }
+    void commitRepeat(RefPtr&lt;CSSValue&gt;&amp;&amp; repeat)
+    {
+        m_repeat = WTFMove(repeat);
+        m_canAdvance = true;
+        m_allowCommit = true;
+        m_allowRepeat = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
+        m_allowImageSlice = !m_imageSlice;
+        m_allowImage = !m_image;
+    }
+
+    Ref&lt;CSSValue&gt; commitWebKitBorderImage()
+    {
+        return createBorderImageValue(m_image.copyRef(), m_imageSlice.copyRef(), m_borderSlice.copyRef(), m_outset.copyRef(), m_repeat.copyRef());
+    }
+
+    void commitBorderImage(CSSParser&amp; parser, bool important)
+    {
+        commitBorderImageProperty(CSSPropertyBorderImageSource, parser, WTFMove(m_image), important);
+        commitBorderImageProperty(CSSPropertyBorderImageSlice, parser, m_imageSlice, important);
+        commitBorderImageProperty(CSSPropertyBorderImageWidth, parser, m_borderSlice, important);
+        commitBorderImageProperty(CSSPropertyBorderImageOutset, parser, m_outset, important);
+        commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, WTFMove(m_repeat), important);
+    }
+
+    void commitBorderImageProperty(CSSPropertyID propId, CSSParser&amp; parser, RefPtr&lt;CSSValue&gt;&amp;&amp; value, bool important)
+    {
+        if (value)
+            parser.addProperty(propId, value.releaseNonNull(), important);
+        else
+            parser.addProperty(propId, CSSValuePool::singleton().createImplicitInitialValue(), important, true);
+    }
+
+    bool m_canAdvance;
+
+    bool m_allowCommit;
+    bool m_allowImage;
+    bool m_allowImageSlice;
+    bool m_allowRepeat;
+    bool m_allowForwardSlashOperator;
+
+    bool m_requireWidth;
+    bool m_requireOutset;
+
+    RefPtr&lt;CSSValue&gt; m_image;
+    RefPtr&lt;CSSBorderImageSliceValue&gt; m_imageSlice;
+    RefPtr&lt;CSSPrimitiveValue&gt; m_borderSlice;
+    RefPtr&lt;CSSPrimitiveValue&gt; m_outset;
+
+    RefPtr&lt;CSSValue&gt; m_repeat;
+};
+
+bool CSSParser::parseBorderImage(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp; result, bool important)
+{
+    ShorthandScope scope(this, propId);
+    BorderImageParseContext context;
+    while (CSSParserValue* currentValue = m_valueList-&gt;current()) {
+        context.setCanAdvance(false);
+
+        if (!context.canAdvance() &amp;&amp; context.allowForwardSlashOperator() &amp;&amp; isForwardSlashOperator(*currentValue))
+            context.commitForwardSlashOperator();
+
+        if (!context.canAdvance() &amp;&amp; context.allowImage()) {
+            if (currentValue-&gt;unit == CSSPrimitiveValue::CSS_URI)
+                context.commitImage(CSSImageValue::create(completeURL(currentValue-&gt;string)));
+            else if (isGeneratedImageValue(*currentValue)) {
+                RefPtr&lt;CSSValue&gt; value;
+                if (parseGeneratedImage(*m_valueList, value))
+                    context.commitImage(WTFMove(value));
+                else
+                    return false;
+            } else if (isImageSetFunctionValue(*currentValue)) {
+                RefPtr&lt;CSSValue&gt; value = parseImageSet();
+                if (value)
+                    context.commitImage(value.releaseNonNull());
+                else
+                    return false;
+            } else if (currentValue-&gt;id == CSSValueNone)
+                context.commitImage(CSSValuePool::singleton().createIdentifierValue(CSSValueNone));
+        }
+
+        if (!context.canAdvance() &amp;&amp; context.allowImageSlice()) {
+            RefPtr&lt;CSSBorderImageSliceValue&gt; imageSlice;
+            if (parseBorderImageSlice(propId, imageSlice))
+                context.commitImageSlice(WTFMove(imageSlice));
+        }
+
+        if (!context.canAdvance() &amp;&amp; context.allowRepeat()) {
+            RefPtr&lt;CSSValue&gt; repeat;
+            if (parseBorderImageRepeat(repeat))
+                context.commitRepeat(WTFMove(repeat));
+        }
+
+        if (!context.canAdvance() &amp;&amp; context.requireWidth()) {
+            RefPtr&lt;CSSPrimitiveValue&gt; borderSlice;
+            if (parseBorderImageWidth(borderSlice))
+                context.commitBorderWidth(WTFMove(borderSlice));
+        }
+
+        if (!context.canAdvance() &amp;&amp; context.requireOutset()) {
+            RefPtr&lt;CSSPrimitiveValue&gt; borderOutset;
+            if (parseBorderImageOutset(borderOutset))
+                context.commitBorderOutset(WTFMove(borderOutset));
+        }
+
+        if (!context.canAdvance())
+            return false;
+
+        m_valueList-&gt;next();
+    }
+
+    if (context.allowCommit()) {
+        if (propId == CSSPropertyBorderImage)
+            context.commitBorderImage(*this, important);
+        else
+            // Need to fully commit as a single value.
+            result = context.commitWebKitBorderImage();
+        return true;
+    }
+
+    return false;
+}
+
+static bool isBorderImageRepeatKeyword(int id)
+{
+    return id == CSSValueStretch || id == CSSValueRepeat || id == CSSValueSpace || id == CSSValueRound;
+}
+
+bool CSSParser::parseBorderImageRepeat(RefPtr&lt;CSSValue&gt;&amp; result)
+{
+    RefPtr&lt;CSSPrimitiveValue&gt; firstValue;
+    RefPtr&lt;CSSPrimitiveValue&gt; secondValue;
+    CSSParserValue* val = m_valueList-&gt;current();
+    if (!val)
+        return false;
+    if (isBorderImageRepeatKeyword(val-&gt;id))
+        firstValue = CSSValuePool::singleton().createIdentifierValue(val-&gt;id);
+    else
+        return false;
+
+    val = m_valueList-&gt;next();
+    if (val) {
+        if (isBorderImageRepeatKeyword(val-&gt;id))
+            secondValue = CSSValuePool::singleton().createIdentifierValue(val-&gt;id);
+        else if (!inShorthand()) {
+            // If we're not parsing a shorthand then we are invalid.
+            return false;
+        } else {
+            // We need to rewind the value list, so that when its advanced we'll
+            // end up back at this value.
+            m_valueList-&gt;previous();
+            secondValue = firstValue;
+        }
+    } else
+        secondValue = firstValue;
+
+    result = createPrimitiveValuePair(firstValue.releaseNonNull(), secondValue.releaseNonNull());
+    return true;
+}
+
+class BorderImageSliceParseContext {
+public:
+    BorderImageSliceParseContext(CSSParser&amp; parser)
+    : m_parser(parser)
+    , m_allowNumber(true)
+    , m_allowFill(true)
+    , m_allowFinalCommit(false)
+    , m_fill(false)
+    { }
+
+    bool allowNumber() const { return m_allowNumber; }
+    bool allowFill() const { return m_allowFill; }
+    bool allowFinalCommit() const { return m_allowFinalCommit; }
+    CSSPrimitiveValue* top() const { return m_top.get(); }
+
+    void commitNumber(CSSParser::ValueWithCalculation&amp; valueWithCalculation)
+    {
+        auto primitiveValue = m_parser.createPrimitiveNumericValue(valueWithCalculation);
+        if (!m_top)
+            m_top = WTFMove(primitiveValue);
+        else if (!m_right)
+            m_right = WTFMove(primitiveValue);
+        else if (!m_bottom)
+            m_bottom = WTFMove(primitiveValue);
+        else {
+            ASSERT(!m_left);
+            m_left = WTFMove(primitiveValue);
+        }
+
+        m_allowNumber = !m_left;
+        m_allowFinalCommit = true;
+    }
+
+    void commitFill() { m_fill = true; m_allowFill = false; m_allowNumber = !m_top; }
+
+    Ref&lt;CSSBorderImageSliceValue&gt; commitBorderImageSlice()
+    {
+        // We need to clone and repeat values for any omissions.
+        ASSERT(m_top);
+        if (!m_right) {
+            m_right = m_top;
+            m_bottom = m_top;
+            m_left = m_top;
+        }
+        if (!m_bottom) {
+            m_bottom = m_top;
+            m_left = m_right;
+        }
+        if (!m_left)
+            m_left = m_right;
+
+        // Now build a rect value to hold all four of our primitive values.
+        auto quad = Quad::create();
+        quad-&gt;setTop(m_top.copyRef());
+        quad-&gt;setRight(m_right.copyRef());
+        quad-&gt;setBottom(m_bottom.copyRef());
+        quad-&gt;setLeft(m_left.copyRef());
+
+        // Make our new border image value now.
+        return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTFMove(quad)), m_fill);
+    }
+
+private:
+    CSSParser&amp; m_parser;
+
+    bool m_allowNumber;
+    bool m_allowFill;
+    bool m_allowFinalCommit;
+
+    RefPtr&lt;CSSPrimitiveValue&gt; m_top;
+    RefPtr&lt;CSSPrimitiveValue&gt; m_right;
+    RefPtr&lt;CSSPrimitiveValue&gt; m_bottom;
+    RefPtr&lt;CSSPrimitiveValue&gt; m_left;
+
+    bool m_fill;
+};
+
+bool CSSParser::parseBorderImageSlice(CSSPropertyID propId, RefPtr&lt;CSSBorderImageSliceValue&gt;&amp; result)
+{
+    BorderImageSliceParseContext context(*this);
+    CSSParserValue* value;
+    while ((value = m_valueList-&gt;current())) {
+        ValueWithCalculation valueWithCalculation(*value);
+        // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet.
+        if (context.allowNumber() &amp;&amp; !isCalculation(valueWithCalculation) &amp;&amp; validateUnit(valueWithCalculation, FInteger | FNonNeg | FPercent, CSSStrictMode)) {
+            context.commitNumber(valueWithCalculation);
+        } else if (context.allowFill() &amp;&amp; value-&gt;id == CSSValueFill)
+            context.commitFill();
+        else if (!inShorthand()) {
+            // If we're not parsing a shorthand then we are invalid.
+            return false;
+        } else {
+            if (context.allowFinalCommit()) {
+                // We're going to successfully parse, but we don't want to consume this token.
+                m_valueList-&gt;previous();
+            }
+            break;
+        }
+        m_valueList-&gt;next();
+    }
+
+    if (context.allowFinalCommit()) {
+        // FIXME: For backwards compatibility, -webkit-border-image, -webkit-mask-box-image and -webkit-box-reflect have to do a fill by default.
+        // FIXME: What do we do with -webkit-box-reflect and -webkit-mask-box-image? Probably just have to leave them filling...
+        if (propId == CSSPropertyWebkitBorderImage || propId == CSSPropertyWebkitMaskBoxImage || propId == CSSPropertyWebkitBoxReflect)
+            context.commitFill();
+
+        // Need to fully commit as a single value.
+        result = context.commitBorderImageSlice();
+        return true;
+    }
+
+    return false;
+}
+
+class BorderImageQuadParseContext {
+public:
+    BorderImageQuadParseContext(CSSParser&amp; parser)
+    : m_parser(parser)
+    , m_allowNumber(true)
+    , m_allowFinalCommit(false)
+    { }
+
+    bool allowNumber() const { return m_allowNumber; }
+    bool allowFinalCommit() const { return m_allowFinalCommit; }
+    CSSPrimitiveValue* top() const { return m_top.get(); }
+
+    void commitNumber(CSSParser::ValueWithCalculation&amp; valueWithCalculation)
+    {
+        RefPtr&lt;CSSPrimitiveValue&gt; primitiveValue;
+        if (valueWithCalculation.value().id == CSSValueAuto)
+            primitiveValue = CSSValuePool::singleton().createIdentifierValue(valueWithCalculation.value().id);
+        else
+            primitiveValue = m_parser.createPrimitiveNumericValue(valueWithCalculation);
+
+        if (!m_top)
+            m_top = WTFMove(primitiveValue);
+        else if (!m_right)
+            m_right = WTFMove(primitiveValue);
+        else if (!m_bottom)
+            m_bottom = WTFMove(primitiveValue);
+        else {
+            ASSERT(!m_left);
+            m_left = WTFMove(primitiveValue);
+        }
+
+        m_allowNumber = !m_left;
+        m_allowFinalCommit = true;
+    }
+
+    void setAllowFinalCommit() { m_allowFinalCommit = true; }
+    void setTop(RefPtr&lt;CSSPrimitiveValue&gt;&amp;&amp; val) { m_top = WTFMove(val); }
+
+    Ref&lt;CSSPrimitiveValue&gt; commitBorderImageQuad()
+    {
+        // We need to clone and repeat values for any omissions.
+        ASSERT(m_top);
+        if (!m_right) {
+            m_right = m_top;
+            m_bottom = m_top;
+            m_left = m_top;
+        }
+        if (!m_bottom) {
+            m_bottom = m_top;
+            m_left = m_right;
+        }
+        if (!m_left)
+            m_left = m_right;
+
+        // Now build a quad value to hold all four of our primitive values.
+        auto quad = Quad::create();
+        quad-&gt;setTop(m_top.copyRef());
+        quad-&gt;setRight(m_right.copyRef());
+        quad-&gt;setBottom(m_bottom.copyRef());
+        quad-&gt;setLeft(m_left.copyRef());
+
+        // Make our new value now.
+        return CSSValuePool::singleton().createValue(WTFMove(quad));
+    }
+
+private:
+    CSSParser&amp; m_parser;
+
+    bool m_allowNumber;
+    bool m_allowFinalCommit;
+
+    RefPtr&lt;CSSPrimitiveValue&gt; m_top;
+    RefPtr&lt;CSSPrimitiveValue&gt; m_right;
+    RefPtr&lt;CSSPrimitiveValue&gt; m_bottom;
+    RefPtr&lt;CSSPrimitiveValue&gt; m_left;
+};
+
+bool CSSParser::parseBorderImageQuad(Units validUnits, RefPtr&lt;CSSPrimitiveValue&gt;&amp; result)
+{
+    BorderImageQuadParseContext context(*this);
+    CSSParserValue* value;
+    while ((value = m_valueList-&gt;current())) {
+        ValueWithCalculation valueWithCalculation(*value);
+        if (context.allowNumber() &amp;&amp; (validateUnit(valueWithCalculation, validUnits, CSSStrictMode) || value-&gt;id == CSSValueAuto)) {
+            context.commitNumber(valueWithCalculation);
+        } else if (!inShorthand()) {
+            // If we're not parsing a shorthand then we are invalid.
+            return false;
+        } else {
+            if (context.allowFinalCommit())
+                m_valueList-&gt;previous(); // The shorthand loop will advance back to this point.
+            break;
+        }
+        m_valueList-&gt;next();
+    }
+
+    if (context.allowFinalCommit()) {
+        // Need to fully commit as a single value.
+        result = context.commitBorderImageQuad();
+        return true;
+    }
+    return false;
+}
+
+bool CSSParser::parseBorderImageWidth(RefPtr&lt;CSSPrimitiveValue&gt;&amp; result)
+{
+    return parseBorderImageQuad(FLength | FInteger | FNonNeg | FPercent, result);
+}
+
+bool CSSParser::parseBorderImageOutset(RefPtr&lt;CSSPrimitiveValue&gt;&amp; result)
+{
+    return parseBorderImageQuad(FLength | FInteger | FNonNeg, result);
+}
+
+bool CSSParser::parseBorderRadius(CSSPropertyID propId, bool important)
+{
+    unsigned num = m_valueList-&gt;size();
+    if (num &gt; 9)
+        return false;
+
+    ShorthandScope scope(this, propId);
+    RefPtr&lt;CSSPrimitiveValue&gt; radii[2][4];
+
+    unsigned indexAfterSlash = 0;
+    for (unsigned i = 0; i &lt; num; ++i) {
+        CSSParserValue&amp; value = *m_valueList-&gt;valueAt(i);
+        if (value.unit == CSSParserValue::Operator) {
+            if (value.iValue != '/')
+                return false;
+
+            if (!i || indexAfterSlash || i + 1 == num || num &gt; i + 5)
+                return false;
+
+            indexAfterSlash = i + 1;
+            completeBorderRadii(radii[0]);
+            continue;
+        }
+
+        if (i - indexAfterSlash &gt;= 4)
+            return false;
+
+        ValueWithCalculation valueWithCalculation(value);
+        if (!validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg))
+            return false;
+
+        auto radius = createPrimitiveNumericValue(valueWithCalculation);
+
+        if (!indexAfterSlash) {
+            radii[0][i] = WTFMove(radius);
+
+            // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-radius: l1 / l2;
+            if (num == 2 &amp;&amp; propId == CSSPropertyWebkitBorderRadius) {
+                indexAfterSlash = 1;
+                completeBorderRadii(radii[0]);
+            }
+        } else
+            radii[1][i - indexAfterSlash] = WTFMove(radius);
+    }
+
+    if (!indexAfterSlash) {
+        completeBorderRadii(radii[0]);
+        for (unsigned i = 0; i &lt; 4; ++i)
+            radii[1][i] = radii[0][i];
+    } else
+        completeBorderRadii(radii[1]);
+
+    ImplicitScope implicitScope(*this, PropertyImplicit);
+    addProperty(CSSPropertyBorderTopLeftRadius, createPrimitiveValuePair(WTFMove(radii[0][0]), WTFMove(radii[1][0])), important);
+    addProperty(CSSPropertyBorderTopRightRadius, createPrimitiveValuePair(WTFMove(radii[0][1]), WTFMove(radii[1][1])), important);
+    addProperty(CSSPropertyBorderBottomRightRadius, createPrimitiveValuePair(WTFMove(radii[0][2]), WTFMove(radii[1][2])), important);
+    addProperty(CSSPropertyBorderBottomLeftRadius, createPrimitiveValuePair(WTFMove(radii[0][3]), WTFMove(radii[1][3])), important);
+    return true;
+}
+
+bool CSSParser::parseAspectRatio(bool important)
+{
+    unsigned num = m_valueList-&gt;size();
+    if (num == 1) {
+        CSSValueID valueId = m_valueList-&gt;valueAt(0)-&gt;id;
+        if (valueId == CSSValueAuto || valueId == CSSValueFromDimensions || valueId == CSSValueFromIntrinsic) {
+            addProperty(CSSPropertyWebkitAspectRatio, CSSValuePool::singleton().createIdentifierValue(valueId), important);
+            return true;
+        }
+    }
+
+    if (num != 3)
+        return false;
+
+    CSSParserValue&amp; op = *m_valueList-&gt;valueAt(1);
+
+    if (!isForwardSlashOperator(op))
+        return false;
+
+    ValueWithCalculation lvalueWithCalculation(*m_valueList-&gt;valueAt(0));
+    ValueWithCalculation rvalueWithCalculation(*m_valueList-&gt;valueAt(2));
+    if (!validateUnit(lvalueWithCalculation, FNumber | FNonNeg) || !validateUnit(rvalueWithCalculation, FNumber | FNonNeg))
+        return false;
+
+    // FIXME: This doesn't handle calculated values.
+    if (!lvalueWithCalculation.value().fValue || !rvalueWithCalculation.value().fValue)
+        return false;
+
+    addProperty(CSSPropertyWebkitAspectRatio, CSSAspectRatioValue::create(narrowPrecisionToFloat(lvalueWithCalculation.value().fValue), narrowPrecisionToFloat(rvalueWithCalculation.value().fValue)), important);
+
+    return true;
+}
+
+bool CSSParser::parseCounter(CSSPropertyID propId, int defaultValue, bool important)
+{
+    enum { ID, VAL } state = ID;
+
+    auto list = CSSValueList::createCommaSeparated();
+    RefPtr&lt;CSSPrimitiveValue&gt; counterName;
+
+    while (true) {
+        CSSParserValue* value = m_valueList-&gt;current();
+        switch (state) {
+            case ID:
+                if (value &amp;&amp; value-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
+                    counterName = createPrimitiveStringValue(*value);
+                    state = VAL;
+                    m_valueList-&gt;next();
+                    continue;
+                }
+                break;
+            case VAL: {
+                int i = defaultValue;
+                if (value &amp;&amp; value-&gt;unit == CSSPrimitiveValue::CSS_NUMBER) {
+                    i = clampToInteger(value-&gt;fValue);
+                    m_valueList-&gt;next();
+                }
+
+                list-&gt;append(createPrimitiveValuePair(WTFMove(counterName),
+                    CSSValuePool::singleton().createValue(i, CSSPrimitiveValue::CSS_NUMBER)));
+                state = ID;
+                continue;
+            }
+        }
+        break;
+    }
+
+    if (list-&gt;length() &gt; 0) {
+        addProperty(propId, WTFMove(list), important);
+        return true;
+    }
+
+    return false;
+}
+
+// This should go away once we drop support for -webkit-gradient
+static RefPtr&lt;CSSPrimitiveValue&gt; parseDeprecatedGradientPoint(CSSParserValue&amp; value, bool horizontal)
+{
+    RefPtr&lt;CSSPrimitiveValue&gt; result;
+    if (value.unit == CSSPrimitiveValue::CSS_IDENT) {
+        if ((equalLettersIgnoringASCIICase(value, &quot;left&quot;) &amp;&amp; horizontal)
+            || (equalLettersIgnoringASCIICase(value, &quot;top&quot;) &amp;&amp; !horizontal))
+            result = CSSValuePool::singleton().createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE);
+        else if ((equalLettersIgnoringASCIICase(value, &quot;right&quot;) &amp;&amp; horizontal)
+            || (equalLettersIgnoringASCIICase(value, &quot;bottom&quot;) &amp;&amp; !horizontal))
+            result = CSSValuePool::singleton().createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE);
+        else if (equalLettersIgnoringASCIICase(value, &quot;center&quot;))
+            result = CSSValuePool::singleton().createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE);
+    } else if (value.unit == CSSPrimitiveValue::CSS_NUMBER || value.unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+        result = CSSValuePool::singleton().createValue(value.fValue, static_cast&lt;CSSPrimitiveValue::UnitTypes&gt;(value.unit));
+    return result;
+}
+
+static bool parseDeprecatedGradientColorStop(CSSParser&amp; parser, CSSParserValue&amp; value, CSSGradientColorStop&amp; stop)
+{
+    if (value.unit != CSSParserValue::Function)
+        return false;
+
+    if (!equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;from(&quot;)
+        &amp;&amp; !equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;to(&quot;)
+        &amp;&amp; !equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;color-stop(&quot;))
+        return false;
+
+    CSSParserValueList* args = value.function-&gt;args.get();
+    if (!args)
+        return false;
+
+    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;from(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;to(&quot;)) {
+        // The &quot;from&quot; and &quot;to&quot; stops expect 1 argument.
+        if (args-&gt;size() != 1)
+            return false;
+
+        if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;from(&quot;))
+            stop.m_position = CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_NUMBER);
+        else
+            stop.m_position = CSSValuePool::singleton().createValue(1, CSSPrimitiveValue::CSS_NUMBER);
+
+        CSSValueID id = args-&gt;current()-&gt;id;
+        if (id == CSSValueWebkitText || CSSParser::isValidSystemColorValue(id) || id == CSSValueMenu)
+            stop.m_color = CSSValuePool::singleton().createIdentifierValue(id);
+        else
+            stop.m_color = parser.parseColor(args-&gt;current());
+        if (!stop.m_color)
+            return false;
+    }
+
+    // The &quot;color-stop&quot; function expects 3 arguments.
+    if (equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;color-stop(&quot;)) {
+        if (args-&gt;size() != 3)
+            return false;
+
+        CSSParserValue* stopArg = args-&gt;current();
+        if (stopArg-&gt;unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+            stop.m_position = CSSValuePool::singleton().createValue(stopArg-&gt;fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
+        else if (stopArg-&gt;unit == CSSPrimitiveValue::CSS_NUMBER)
+            stop.m_position = CSSValuePool::singleton().createValue(stopArg-&gt;fValue, CSSPrimitiveValue::CSS_NUMBER);
+        else
+            return false;
+
+        stopArg = args-&gt;next();
+        if (stopArg-&gt;unit != CSSParserValue::Operator || stopArg-&gt;iValue != ',')
+            return false;
+
+        stopArg = args-&gt;next();
+        CSSValueID id = stopArg-&gt;id;
+        if (id == CSSValueWebkitText || CSSParser::isValidSystemColorValue(id) || id == CSSValueMenu)
+            stop.m_color = CSSValuePool::singleton().createIdentifierValue(id);
+        else
+            stop.m_color = parser.parseColor(stopArg);
+        if (!stop.m_color)
+            return false;
+    }
+
+    return true;
+}
+
+bool CSSParser::parseDeprecatedGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient)
+{
+    // Walk the arguments.
+    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
+    if (!args || args-&gt;size() == 0)
+        return false;
+
+    // The first argument is the gradient type.  It is an identifier.
+    CSSGradientType gradientType;
+    CSSParserValue* argument = args-&gt;current();
+    if (!argument || argument-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+        return false;
+    if (equalLettersIgnoringASCIICase(*argument, &quot;linear&quot;))
+        gradientType = CSSDeprecatedLinearGradient;
+    else if (equalLettersIgnoringASCIICase(*argument, &quot;radial&quot;))
+        gradientType = CSSDeprecatedRadialGradient;
+    else
+        return false;
+
+    RefPtr&lt;CSSGradientValue&gt; result;
+    switch (gradientType) {
+    case CSSDeprecatedLinearGradient:
+        result = CSSLinearGradientValue::create(NonRepeating, gradientType);
+        break;
+    case CSSDeprecatedRadialGradient:
+        result = CSSRadialGradientValue::create(NonRepeating, gradientType);
+        break;
+    default:
+        // The rest of the gradient types shouldn't appear here.
+        ASSERT_NOT_REACHED();
+    }
+
+    // Comma.
+    argument = args-&gt;next();
+    if (!isComma(argument))
+        return false;
+
+    // Next comes the starting point for the gradient as an x y pair.  There is no
+    // comma between the x and the y values.
+    // First X.  It can be left, right, number or percent.
+    argument = args-&gt;next();
+    if (!argument)
+        return false;
+    RefPtr&lt;CSSPrimitiveValue&gt; point = parseDeprecatedGradientPoint(*argument, true);
+    if (!point)
+        return false;
+    result-&gt;setFirstX(point.releaseNonNull());
+
+    // First Y.  It can be top, bottom, number or percent.
+    argument = args-&gt;next();
+    if (!argument)
+        return false;
+    point = parseDeprecatedGradientPoint(*argument, false);
+    if (!point)
+        return false;
+    result-&gt;setFirstY(point.releaseNonNull());
+
+    // Comma after the first point.
+    argument = args-&gt;next();
+    if (!isComma(argument))
+        return false;
+
+    // For radial gradients only, we now expect a numeric radius.
+    if (gradientType == CSSDeprecatedRadialGradient) {
+        argument = args-&gt;next();
+        // FIXME: This does not handle calculation values.
+        if (!argument || argument-&gt;unit != CSSPrimitiveValue::CSS_NUMBER)
+            return false;
+        ValueWithCalculation argumentWithCalculation(*argument);
+        downcast&lt;CSSRadialGradientValue&gt;(*result).setFirstRadius(createPrimitiveNumericValue(argumentWithCalculation));
+
+        // Comma after the first radius.
+        argument = args-&gt;next();
+        if (!isComma(argument))
+            return false;
+    }
+
+    // Next is the ending point for the gradient as an x, y pair.
+    // Second X.  It can be left, right, number or percent.
+    argument = args-&gt;next();
+    if (!argument)
+        return false;
+    point = parseDeprecatedGradientPoint(*argument, true);
+    if (!point)
+        return false;
+    result-&gt;setSecondX(point.releaseNonNull());
+
+    // Second Y.  It can be top, bottom, number or percent.
+    argument = args-&gt;next();
+    if (!argument)
+        return false;
+    point = parseDeprecatedGradientPoint(*argument, false);
+    if (!point)
+        return false;
+    result-&gt;setSecondY(point.releaseNonNull());
+
+    // For radial gradients only, we now expect the second radius.
+    if (gradientType == CSSDeprecatedRadialGradient) {
+        // Comma after the second point.
+        argument = args-&gt;next();
+        if (!isComma(argument))
+            return false;
+
+        argument = args-&gt;next();
+        // FIXME: This does not handle calculation values.
+        if (!argument || argument-&gt;unit != CSSPrimitiveValue::CSS_NUMBER)
+            return false;
+        ValueWithCalculation argumentWithCalculation(*argument);
+        downcast&lt;CSSRadialGradientValue&gt;(*result).setSecondRadius(createPrimitiveNumericValue(argumentWithCalculation));
+    }
+
+    // We now will accept any number of stops (0 or more).
+    argument = args-&gt;next();
+    while (argument) {
+        // Look for the comma before the next stop.
+        if (!isComma(argument))
+            return false;
+
+        // Now examine the stop itself.
+        argument = args-&gt;next();
+        if (!argument)
+            return false;
+
+        // The function name needs to be one of &quot;from&quot;, &quot;to&quot;, or &quot;color-stop.&quot;
+        CSSGradientColorStop stop;
+        if (!parseDeprecatedGradientColorStop(*this, *argument, stop))
+            return false;
+        result-&gt;addStop(stop);
+
+        // Advance
+        argument = args-&gt;next();
+    }
+
+    gradient = WTFMove(result);
+    return true;
+}
+
+static RefPtr&lt;CSSPrimitiveValue&gt; valueFromSideKeyword(CSSParserValue&amp; value, bool&amp; isHorizontal)
+{
+    if (value.unit != CSSPrimitiveValue::CSS_IDENT)
+        return nullptr;
+
+    switch (value.id) {
+        case CSSValueLeft:
+        case CSSValueRight:
+            isHorizontal = true;
+            break;
+        case CSSValueTop:
+        case CSSValueBottom:
+            isHorizontal = false;
+            break;
+        default:
+            return nullptr;
+    }
+    return CSSValuePool::singleton().createIdentifierValue(value.id);
+}
+
+static RefPtr&lt;CSSPrimitiveValue&gt; parseGradientColorOrKeyword(CSSParser&amp; parser, CSSParserValue&amp; value)
+{
+    CSSValueID id = value.id;
+    if (id == CSSValueWebkitText || CSSParser::isValidSystemColorValue(id) || id == CSSValueMenu || id == CSSValueCurrentcolor)
+        return CSSValuePool::singleton().createIdentifierValue(id);
+
+    return parser.parseColor(&amp;value);
+}
+
+bool CSSParser::parseDeprecatedLinearGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient, CSSGradientRepeat repeating)
+{
+    auto result = CSSLinearGradientValue::create(repeating, CSSPrefixedLinearGradient);
+
+    // Walk the arguments.
+    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
+    if (!args || !args-&gt;size())
+        return false;
+
+    CSSParserValue* argument = args-&gt;current();
+    if (!argument)
+        return false;
+    ValueWithCalculation argumentWithCalculation(*argument);
+
+    bool expectComma = false;
+    // Look for angle.
+    if (validateUnit(argumentWithCalculation, FAngle, CSSStrictMode)) {
+        result-&gt;setAngle(createPrimitiveNumericValue(argumentWithCalculation));
+
+        args-&gt;next();
+        expectComma = true;
+    } else {
+        // Look one or two optional keywords that indicate a side or corner.
+        RefPtr&lt;CSSPrimitiveValue&gt; startX, startY;
+        bool isHorizontal = false;
+        if (RefPtr&lt;CSSPrimitiveValue&gt; location = valueFromSideKeyword(*argument, isHorizontal)) {
+            if (isHorizontal)
+                startX = WTFMove(location);
+            else
+                startY = WTFMove(location);
+
+            if ((argument = args-&gt;next())) {
+                if ((location = valueFromSideKeyword(*argument, isHorizontal))) {
+                    if (isHorizontal) {
+                        if (startX)
+                            return false;
+                        startX = WTFMove(location);
+                    } else {
+                        if (startY)
+                            return false;
+                        startY = WTFMove(location);
+                    }
+
+                    args-&gt;next();
+                }
+            }
+
+            expectComma = true;
+        }
+
+        if (!startX &amp;&amp; !startY)
+            startY = CSSValuePool::singleton().createIdentifierValue(CSSValueTop);
+
+        result-&gt;setFirstX(WTFMove(startX));
+        result-&gt;setFirstY(WTFMove(startY));
+    }
+
+    if (!parseGradientColorStops(*args, result, expectComma))
+        return false;
+
+    if (!result-&gt;stopCount())
+        return false;
+
+    gradient = WTFMove(result);
+    return true;
+}
+
+bool CSSParser::parseDeprecatedRadialGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient, CSSGradientRepeat repeating)
+{
+    auto result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient);
+
+    // Walk the arguments.
+    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
+    if (!args || !args-&gt;size())
+        return false;
+
+    CSSParserValue* argument = args-&gt;current();
+    if (!argument)
+        return false;
+
+    bool expectComma = false;
+
+    // Optional background-position
+    RefPtr&lt;CSSPrimitiveValue&gt; centerX;
+    RefPtr&lt;CSSPrimitiveValue&gt; centerY;
+    // parse2ValuesFillPosition advances the args next pointer.
+    parse2ValuesFillPosition(*args, centerX, centerY);
+    argument = args-&gt;current();
+    if (!argument)
+        return false;
+
+    if (centerX || centerY) {
+        // Comma
+        if (!isComma(argument))
+            return false;
+
+        argument = args-&gt;next();
+        if (!argument)
+            return false;
+    }
+
+    result-&gt;setFirstX(centerX.copyRef());
+    result-&gt;setSecondX(WTFMove(centerX));
+    // CSS3 radial gradients always share the same start and end point.
+    result-&gt;setFirstY(centerY.copyRef());
+    result-&gt;setSecondY(WTFMove(centerY));
+
+    RefPtr&lt;CSSPrimitiveValue&gt; shapeValue;
+    RefPtr&lt;CSSPrimitiveValue&gt; sizeValue;
+
+    // Optional shape and/or size in any order.
+    for (int i = 0; i &lt; 2; ++i) {
+        if (argument-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+            break;
+
+        bool foundValue = false;
+        switch (argument-&gt;id) {
+        case CSSValueCircle:
+        case CSSValueEllipse:
+            shapeValue = CSSValuePool::singleton().createIdentifierValue(argument-&gt;id);
+            foundValue = true;
+            break;
+        case CSSValueClosestSide:
+        case CSSValueClosestCorner:
+        case CSSValueFarthestSide:
+        case CSSValueFarthestCorner:
+        case CSSValueContain:
+        case CSSValueCover:
+            sizeValue = CSSValuePool::singleton().createIdentifierValue(argument-&gt;id);
+            foundValue = true;
+            break;
+        default:
+            break;
+        }
+
+        if (foundValue) {
+            argument = args-&gt;next();
+            if (!argument)
+                return false;
+
+            expectComma = true;
+        }
+    }
+
+    result-&gt;setShape(shapeValue.copyRef());
+    result-&gt;setSizingBehavior(sizeValue.copyRef());
+
+    // Or, two lengths or percentages
+    RefPtr&lt;CSSPrimitiveValue&gt; horizontalSize;
+    RefPtr&lt;CSSPrimitiveValue&gt; verticalSize;
+
+    if (!shapeValue &amp;&amp; !sizeValue) {
+        ValueWithCalculation hSizeWithCalculation(*argument);
+        if (validateUnit(hSizeWithCalculation, FLength | FPercent)) {
+            horizontalSize = createPrimitiveNumericValue(hSizeWithCalculation);
+            argument = args-&gt;next();
+            if (!argument)
+                return false;
+
+            expectComma = true;
+        }
+
+        ValueWithCalculation vSizeWithCalculation(*argument);
+        if (validateUnit(vSizeWithCalculation, FLength | FPercent)) {
+            verticalSize = createPrimitiveNumericValue(vSizeWithCalculation);
+
+            argument = args-&gt;next();
+            if (!argument)
+                return false;
+            expectComma = true;
+        }
+    }
+
+    // Must have neither or both.
+    if (!horizontalSize != !verticalSize)
+        return false;
+
+    result-&gt;setEndHorizontalSize(WTFMove(horizontalSize));
+    result-&gt;setEndVerticalSize(WTFMove(verticalSize));
+
+    if (!parseGradientColorStops(*args, result, expectComma))
+        return false;
+
+    gradient = WTFMove(result);
+    return true;
+}
+
+bool CSSParser::parseLinearGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient, CSSGradientRepeat repeating)
+{
+    auto result = CSSLinearGradientValue::create(repeating, CSSLinearGradient);
+
+    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
+    if (!args || !args-&gt;size())
+        return false;
+
+    if (!args-&gt;current())
+        return false;
+
+    ValueWithCalculation firstArgumentWithCalculation(*args-&gt;current());
+
+    bool expectComma = false;
+    // Look for angle.
+    if (validateUnit(firstArgumentWithCalculation, FAngle, CSSStrictMode)) {
+        result-&gt;setAngle(createPrimitiveNumericValue(firstArgumentWithCalculation));
+
+        args-&gt;next();
+        expectComma = true;
+    } else if (firstArgumentWithCalculation.value().unit == CSSPrimitiveValue::CSS_IDENT &amp;&amp; equalLettersIgnoringASCIICase(firstArgumentWithCalculation, &quot;to&quot;)) {
+        // to [ [left | right] || [top | bottom] ]
+        CSSParserValue* nextArgument = args-&gt;next();
+        if (!nextArgument)
+            return false;
+
+        bool isHorizontal = false;
+        RefPtr&lt;CSSPrimitiveValue&gt; location = valueFromSideKeyword(*nextArgument, isHorizontal);
+        if (!location)
+            return false;
+
+        RefPtr&lt;CSSPrimitiveValue&gt; endX, endY;
+        if (isHorizontal)
+            endX = WTFMove(location);
+        else
+            endY = WTFMove(location);
+
+        nextArgument = args-&gt;next();
+        if (!nextArgument)
+            return false;
+
+        location = valueFromSideKeyword(*nextArgument, isHorizontal);
+        if (location) {
+            if (isHorizontal) {
+                if (endX)
+                    return false;
+                endX = WTFMove(location);
+            } else {
+                if (endY)
+                    return false;
+                endY = WTFMove(location);
+            }
+
+            args-&gt;next();
+        }
+
+        expectComma = true;
+        result-&gt;setFirstX(WTFMove(endX));
+        result-&gt;setFirstY(WTFMove(endY));
+    }
+
+    if (!parseGradientColorStops(*args, result, expectComma))
+        return false;
+
+    if (!result-&gt;stopCount())
+        return false;
+
+    gradient = WTFMove(result);
+    return true;
+}
+
+bool CSSParser::parseRadialGradient(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; gradient, CSSGradientRepeat repeating)
+{
+    auto result = CSSRadialGradientValue::create(repeating, CSSRadialGradient);
+
+    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
+    if (!args || !args-&gt;size())
+        return false;
+
+    CSSParserValue* argument = args-&gt;current();
+    if (!argument)
+        return false;
+
+    bool expectComma = false;
+
+    RefPtr&lt;CSSPrimitiveValue&gt; shapeValue;
+    RefPtr&lt;CSSPrimitiveValue&gt; sizeValue;
+    RefPtr&lt;CSSPrimitiveValue&gt; horizontalSize;
+    RefPtr&lt;CSSPrimitiveValue&gt; verticalSize;
+
+    // First part of grammar, the size/shape clause:
+    // [ circle || &lt;length&gt; ] |
+    // [ ellipse || [ &lt;length&gt; | &lt;percentage&gt; ]{2} ] |
+    // [ [ circle | ellipse] || &lt;size-keyword&gt; ]
+    for (int i = 0; i &lt; 3; ++i) {
+        ValueWithCalculation argumentWithCalculation(*argument);
+        if (argument-&gt;unit == CSSPrimitiveValue::CSS_IDENT) {
+            bool badIdent = false;
+            switch (argument-&gt;id) {
+            case CSSValueCircle:
+            case CSSValueEllipse:
+                if (shapeValue)
+                    return false;
+                shapeValue = CSSValuePool::singleton().createIdentifierValue(argument-&gt;id);
+                break;
+            case CSSValueClosestSide:
+            case CSSValueClosestCorner:
+            case CSSValueFarthestSide:
+            case CSSValueFarthestCorner:
+                if (sizeValue || horizontalSize)
+                    return false;
+                sizeValue = CSSValuePool::singleton().createIdentifierValue(argument-&gt;id);
+                break;
+            default:
+                badIdent = true;
+            }
+
+            if (badIdent)
+                break;
+
+            argument = args-&gt;next();
+            if (!argument)
+                return false;
+        } else if (validateUnit(argumentWithCalculation, FLength | FPercent)) {
+
+            if (sizeValue || horizontalSize)
+                return false;
+            horizontalSize = createPrimitiveNumericValue(argumentWithCalculation);
+
+            argument = args-&gt;next();
+            if (!argument)
+                return false;
+
+            ValueWithCalculation vSizeWithCalculation(*argument);
+            if (validateUnit(vSizeWithCalculation, FLength | FPercent)) {
+                verticalSize = createPrimitiveNumericValue(vSizeWithCalculation);
+                ++i;
+                argument = args-&gt;next();
+                if (!argument)
+                    return false;
+            }
+        } else
+            break;
+    }
+
+    // You can specify size as a keyword or a length/percentage, not both.
+    if (sizeValue &amp;&amp; horizontalSize)
+        return false;
+    // Circles must have 0 or 1 lengths.
+    if (shapeValue &amp;&amp; shapeValue-&gt;getValueID() == CSSValueCircle &amp;&amp; verticalSize)
+        return false;
+    // Ellipses must have 0 or 2 length/percentages.
+    if (shapeValue &amp;&amp; shapeValue-&gt;getValueID() == CSSValueEllipse &amp;&amp; horizontalSize &amp;&amp; !verticalSize)
+        return false;
+    // If there's only one size, it must be a length.
+    if (!verticalSize &amp;&amp; horizontalSize &amp;&amp; horizontalSize-&gt;isPercentage())
+        return false;
+
+    result-&gt;setShape(shapeValue.copyRef());
+    result-&gt;setSizingBehavior(sizeValue.copyRef());
+    result-&gt;setEndHorizontalSize(horizontalSize.copyRef());
+    result-&gt;setEndVerticalSize(verticalSize.copyRef());
+
+    // Second part of grammar, the center-position clause:
+    // at &lt;position&gt;
+    RefPtr&lt;CSSPrimitiveValue&gt; centerX;
+    RefPtr&lt;CSSPrimitiveValue&gt; centerY;
+    if (argument-&gt;unit == CSSPrimitiveValue::CSS_IDENT &amp;&amp; equalLettersIgnoringASCIICase(*argument, &quot;at&quot;)) {
+        argument = args-&gt;next();
+        if (!argument)
+            return false;
+
+        parseFillPosition(*args, centerX, centerY);
+        if (!(centerX &amp;&amp; centerY))
+            return false;
+
+        argument = args-&gt;current();
+        if (!argument)
+            return false;
+
+        result-&gt;setFirstX(centerX.copyRef());
+        result-&gt;setFirstY(centerY.copyRef());
+        // Right now, CSS radial gradients have the same start and end centers.
+        result-&gt;setSecondX(centerX.copyRef());
+        result-&gt;setSecondY(centerY.copyRef());
+    }
+
+    if (shapeValue || sizeValue || horizontalSize || centerX || centerY)
+        expectComma = true;
+
+    if (!parseGradientColorStops(*args, result, expectComma))
+        return false;
+
+    gradient = WTFMove(result);
+    return true;
+}
+
+bool CSSParser::parseGradientColorStops(CSSParserValueList&amp; valueList, CSSGradientValue&amp; gradient, bool expectComma)
+{
+    CSSParserValue* value = valueList.current();
+    bool previousStopWasMidpoint = true;
+
+    // Now look for color stops.
+    while (value) {
+        // Look for the comma before the next stop.
+        if (expectComma) {
+            if (!isComma(value))
+                return false;
+
+            value = valueList.next();
+            if (!value)
+                return false;
+        }
+
+        // &lt;color-stop&gt; = &lt;color&gt; [ &lt;percentage&gt; | &lt;length&gt; ]?
+        CSSGradientColorStop stop;
+        stop.m_color = parseGradientColorOrKeyword(*this, *value);
+        if (!stop.m_color) {
+            if (previousStopWasMidpoint) // 2 midpoints in a row is not allowed. This also catches starting with a midpoint.
+                return false;
+
+            stop.isMidpoint = true;
+        } else
+            value = valueList.next();
+
+        previousStopWasMidpoint = stop.isMidpoint;
+
+        if (value) {
+            ValueWithCalculation valueWithCalculation(*value);
+            if (validateUnit(valueWithCalculation, FLength | FPercent)) {
+                stop.m_position = createPrimitiveNumericValue(valueWithCalculation);
+                value = valueList.next();
+            } else if (stop.isMidpoint)
+                return false;
+        }
+
+        gradient.addStop(stop);
+        expectComma = true;
+    }
+
+    // We can't end on a midpoint.
+    if (previousStopWasMidpoint)
+        return false;
+
+    // Must have 2 or more stops to be valid.
+    return gradient.stopCount() &gt;= 2;
+}
+
+bool CSSParser::isGeneratedImageValue(CSSParserValue&amp; value) const
+{
+    if (value.unit != CSSParserValue::Function)
+        return false;
+
+    return equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-gradient(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-linear-gradient(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;linear-gradient(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-repeating-linear-gradient(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;repeating-linear-gradient(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-radial-gradient(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;radial-gradient(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-repeating-radial-gradient(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;repeating-radial-gradient(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-canvas(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;cross-fade(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-cross-fade(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;filter(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-filter(&quot;)
+        || equalLettersIgnoringASCIICase(value.function-&gt;name, &quot;-webkit-named-image(&quot;);
+}
+
+bool CSSParser::parseGeneratedImage(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; value)
+{
+    CSSParserValue&amp; parserValue = *valueList.current();
+
+    if (parserValue.unit != CSSParserValue::Function)
+        return false;
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-gradient(&quot;))
+        return parseDeprecatedGradient(valueList, value);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-linear-gradient(&quot;))
+        return parseDeprecatedLinearGradient(valueList, value, NonRepeating);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;linear-gradient(&quot;))
+        return parseLinearGradient(valueList, value, NonRepeating);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-repeating-linear-gradient(&quot;))
+        return parseDeprecatedLinearGradient(valueList, value, Repeating);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;repeating-linear-gradient(&quot;))
+        return parseLinearGradient(valueList, value, Repeating);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-radial-gradient(&quot;))
+        return parseDeprecatedRadialGradient(valueList, value, NonRepeating);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;radial-gradient(&quot;))
+        return parseRadialGradient(valueList, value, NonRepeating);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-repeating-radial-gradient(&quot;))
+        return parseDeprecatedRadialGradient(valueList, value, Repeating);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;repeating-radial-gradient(&quot;))
+        return parseRadialGradient(valueList, value, Repeating);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-canvas(&quot;))
+        return parseCanvas(valueList, value);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-cross-fade(&quot;))
+        return parseCrossfade(valueList, value, true);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;cross-fade(&quot;))
+        return parseCrossfade(valueList, value, false);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;filter(&quot;) || equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-filter(&quot;))
+        return parseFilterImage(valueList, value);
+
+    if (equalLettersIgnoringASCIICase(parserValue.function-&gt;name, &quot;-webkit-named-image(&quot;))
+        return parseNamedImage(valueList, value);
+
+    return false;
+}
+
+bool CSSParser::parseFilterImage(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; filter)
+{
+    // Walk the arguments.
+    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
+    if (!args)
+        return false;
+    CSSParserValue* value = args-&gt;current();
+    if (!value)
+        return false;
+
+    // The first argument is the image. It is a fill image.
+    RefPtr&lt;CSSValue&gt; imageValue;
+    if (!parseFillImage(*args, imageValue)) {
+        if (value-&gt;unit == CSSPrimitiveValue::CSS_STRING)
+            imageValue = CSSImageValue::create(completeURL(value-&gt;string));
+        else
+            return false;
+    }
+
+    value = args-&gt;next();
+
+    // Skip a comma
+    if (!isComma(value))
+        return false;
+    value = args-&gt;next();
+
+    RefPtr&lt;CSSValueList&gt; filterValue;
+    if (!value || !parseFilter(*args, filterValue))
+        return false;
+    value = args-&gt;next();
+
+    filter = CSSFilterImageValue::create(imageValue.releaseNonNull(), filterValue.releaseNonNull());
+
+    return true;
+}
+
+bool CSSParser::parseCrossfade(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; crossfade, bool prefixed)
+{
+    // Walk the arguments.
+    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
+    if (!args || args-&gt;size() != 5)
+        return false;
+
+    CSSParserValue* argument = args-&gt;current();
+
+    // The first argument is the &quot;from&quot; image. It is a fill image.
+    RefPtr&lt;CSSValue&gt; fromImageValue;
+    if (!argument || !parseFillImage(*args, fromImageValue))
+        return false;
+    argument = args-&gt;next();
+
+    // Skip a comma
+    if (!isComma(argument))
+        return false;
+    argument = args-&gt;next();
+
+    // The second argument is the &quot;to&quot; image. It is a fill image.
+    RefPtr&lt;CSSValue&gt; toImageValue;
+    if (!argument || !parseFillImage(*args, toImageValue))
+        return false;
+    argument = args-&gt;next();
+
+    // Skip a comma
+    if (!isComma(argument))
+        return false;
+    argument = args-&gt;next();
+
+    // The third argument is the crossfade value. It is a percentage or a fractional number.
+    if (!argument)
+        return false;
+    
+    RefPtr&lt;CSSPrimitiveValue&gt; percentage;
+    if (argument-&gt;unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+        percentage = CSSValuePool::singleton().createValue(clampTo&lt;double&gt;(argument-&gt;fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
+    else if (argument-&gt;unit == CSSPrimitiveValue::CSS_NUMBER)
+        percentage = CSSValuePool::singleton().createValue(clampTo&lt;double&gt;(argument-&gt;fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
+    else
+        return false;
+
+    crossfade = CSSCrossfadeValue::create(fromImageValue.releaseNonNull(), toImageValue.releaseNonNull(), percentage.releaseNonNull(), prefixed);
+
+    return true;
+}
+
+bool CSSParser::parseCanvas(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; canvas)
+{
+    // Walk the arguments.
+    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
+    if (!args || args-&gt;size() != 1)
+        return false;
+
+    // The first argument is the canvas name.  It is an identifier.
+    CSSParserValue* value = args-&gt;current();
+    if (!value || value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+        return false;
+
+    canvas = CSSCanvasValue::create(value-&gt;string);
+    return true;
+}
+
+bool CSSParser::parseNamedImage(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValue&gt;&amp; namedImage)
+{
+    CSSParserValueList* args = valueList.current()-&gt;function-&gt;args.get();
+    if (!args || args-&gt;size() != 1)
+        return false;
+
+    // The only argument is the image name.
+    CSSParserValue* value = args-&gt;current();
+    if (!value || value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+        return false;
+
+    namedImage = CSSNamedImageValue::create(value-&gt;string);
+    return true;
+}
+
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+RefPtr&lt;CSSValueList&gt; CSSParser::parseImageResolution()
+{
+    auto list = CSSValueList::createSpaceSeparated();
+    bool haveResolution = false;
+    bool haveFromImage = false;
+    bool haveSnap = false;
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    while (value) {
+        ValueWithCalculation valueWithCalculation(*value);
+        if (!haveFromImage &amp;&amp; value-&gt;id == CSSValueFromImage) {
+            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            haveFromImage = true;
+        } else if (!haveSnap &amp;&amp; value-&gt;id == CSSValueSnap) {
+            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            haveSnap = true;
+        } else if (!haveResolution &amp;&amp; validateUnit(valueWithCalculation, FResolution | FNonNeg) &amp;&amp; value-&gt;fValue &gt; 0) {
+            list-&gt;append(createPrimitiveNumericValue(valueWithCalculation));
+            haveResolution = true;
+        } else
+            return nullptr;
+        value = m_valueList-&gt;next();
+    }
+    if (!list-&gt;length())
+        return nullptr;
+    if (!haveFromImage &amp;&amp; !haveResolution)
+        return nullptr;
+    return WTFMove(list);
+}
+#endif
+
+RefPtr&lt;CSSImageSetValue&gt; CSSParser::parseImageSet()
+{
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    ASSERT(value.unit == CSSParserValue::Function);
+
+    CSSParserValueList* functionArgs = value.function-&gt;args.get();
+    if (!functionArgs || !functionArgs-&gt;size() || !functionArgs-&gt;current())
+        return nullptr;
+
+    auto imageSet = CSSImageSetValue::create();
+    CSSParserValue* arg = functionArgs-&gt;current();
+    while (arg) {
+        if (arg-&gt;unit != CSSPrimitiveValue::CSS_URI)
+            return nullptr;
+
+        imageSet-&gt;append(CSSImageValue::create(completeURL(arg-&gt;string)));
+        arg = functionArgs-&gt;next();
+        if (!arg || arg-&gt;unit != CSSPrimitiveValue::CSS_DIMENSION)
+            return nullptr;
+
+        double imageScaleFactor = 0;
+        const String&amp; string = arg-&gt;string;
+        unsigned length = string.length();
+        if (!length)
+            return nullptr;
+        if (string.is8Bit()) {
+            const LChar* start = string.characters8();
+            parseDouble(start, start + length, 'x', imageScaleFactor);
+        } else {
+            const UChar* start = string.characters16();
+            parseDouble(start, start + length, 'x', imageScaleFactor);
+        }
+        if (imageScaleFactor &lt;= 0)
+            return nullptr;
+        imageSet-&gt;append(CSSValuePool::singleton().createValue(imageScaleFactor, CSSPrimitiveValue::CSS_NUMBER));
+
+        // If there are no more arguments, we're done.
+        arg = functionArgs-&gt;next();
+        if (!arg)
+            break;
+
+        // If there are more arguments, they should be after a comma.
+        if (!isComma(arg))
+            return nullptr;
+
+        // Skip the comma and move on to the next argument.
+        arg = functionArgs-&gt;next();
+    }
+
+    return WTFMove(imageSet);
+}
+
+class TransformOperationInfo {
+public:
+    TransformOperationInfo(const CSSParserString&amp; name)
+        : m_type(WebKitCSSTransformValue::UnknownTransformOperation)
+        , m_argCount(1)
+        , m_allowSingleArgument(false)
+        , m_unit(CSSParser::FUnknown)
+    {
+        const UChar* characters;
+        unsigned nameLength = name.length();
+
+        const unsigned longestNameLength = 12;
+        UChar characterBuffer[longestNameLength];
+        if (name.is8Bit()) {
+            unsigned length = std::min(longestNameLength, nameLength);
+            const LChar* characters8 = name.characters8();
+            for (unsigned i = 0; i &lt; length; ++i)
+                characterBuffer[i] = characters8[i];
+            characters = characterBuffer;
+        } else
+            characters = name.characters16();
+
+        switch (nameLength) {
+        case 5:
+            // Valid name: skew(.
+            if (((characters[0] == 's') || (characters[0] == 'S'))
+                &amp; ((characters[1] == 'k') || (characters[1] == 'K'))
+                &amp; ((characters[2] == 'e') || (characters[2] == 'E'))
+                &amp; ((characters[3] == 'w') || (characters[3] == 'W'))
+                &amp; (characters[4] == '(')) {
+                m_unit = CSSParser::FAngle;
+                m_type = WebKitCSSTransformValue::SkewTransformOperation;
+                m_allowSingleArgument = true;
+                m_argCount = 3;
+            }
+            break;
+        case 6:
+            // Valid names: skewx(, skewy(, scale(.
+            if ((characters[1] == 'c') || (characters[1] == 'C')) {
+                if (((characters[0] == 's') || (characters[0] == 'S'))
+                    &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
+                    &amp; ((characters[3] == 'l') || (characters[3] == 'L'))
+                    &amp; ((characters[4] == 'e') || (characters[4] == 'E'))
+                    &amp; (characters[5] == '(')) {
+                    m_unit = CSSParser::FNumber;
+                    m_type = WebKitCSSTransformValue::ScaleTransformOperation;
+                    m_allowSingleArgument = true;
+                    m_argCount = 3;
+                }
+            } else if (((characters[0] == 's') || (characters[0] == 'S'))
+                       &amp; ((characters[1] == 'k') || (characters[1] == 'K'))
+                       &amp; ((characters[2] == 'e') || (characters[2] == 'E'))
+                       &amp; ((characters[3] == 'w') || (characters[3] == 'W'))
+                       &amp; (characters[5] == '(')) {
+                if ((characters[4] == 'x') || (characters[4] == 'X')) {
+                    m_unit = CSSParser::FAngle;
+                    m_type = WebKitCSSTransformValue::SkewXTransformOperation;
+                } else if ((characters[4] == 'y') || (characters[4] == 'Y')) {
+                    m_unit = CSSParser::FAngle;
+                    m_type = WebKitCSSTransformValue::SkewYTransformOperation;
+                }
+            }
+            break;
+        case 7:
+            // Valid names: matrix(, rotate(, scalex(, scaley(, scalez(.
+            if ((characters[0] == 'm') || (characters[0] == 'M')) {
+                if (((characters[1] == 'a') || (characters[1] == 'A'))
+                    &amp; ((characters[2] == 't') || (characters[2] == 'T'))
+                    &amp; ((characters[3] == 'r') || (characters[3] == 'R'))
+                    &amp; ((characters[4] == 'i') || (characters[4] == 'I'))
+                    &amp; ((characters[5] == 'x') || (characters[5] == 'X'))
+                    &amp; (characters[6] == '(')) {
+                    m_unit = CSSParser::FNumber;
+                    m_type = WebKitCSSTransformValue::MatrixTransformOperation;
+                    m_argCount = 11;
+                }
+            } else if ((characters[0] == 'r') || (characters[0] == 'R')) {
+                if (((characters[1] == 'o') || (characters[1] == 'O'))
+                    &amp; ((characters[2] == 't') || (characters[2] == 'T'))
+                    &amp; ((characters[3] == 'a') || (characters[3] == 'A'))
+                    &amp; ((characters[4] == 't') || (characters[4] == 'T'))
+                    &amp; ((characters[5] == 'e') || (characters[5] == 'E'))
+                    &amp; (characters[6] == '(')) {
+                    m_unit = CSSParser::FAngle;
+                    m_type = WebKitCSSTransformValue::RotateTransformOperation;
+                }
+            } else if (((characters[0] == 's') || (characters[0] == 'S'))
+                       &amp; ((characters[1] == 'c') || (characters[1] == 'C'))
+                       &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
+                       &amp; ((characters[3] == 'l') || (characters[3] == 'L'))
+                       &amp; ((characters[4] == 'e') || (characters[4] == 'E'))
+                       &amp; (characters[6] == '(')) {
+                if ((characters[5] == 'x') || (characters[5] == 'X')) {
+                    m_unit = CSSParser::FNumber;
+                    m_type = WebKitCSSTransformValue::ScaleXTransformOperation;
+                } else if ((characters[5] == 'y') || (characters[5] == 'Y')) {
+                    m_unit = CSSParser::FNumber;
+                    m_type = WebKitCSSTransformValue::ScaleYTransformOperation;
+                } else if ((characters[5] == 'z') || (characters[5] == 'Z')) {
+                    m_unit = CSSParser::FNumber;
+                    m_type = WebKitCSSTransformValue::ScaleZTransformOperation;
+                }
+            }
+            break;
+        case 8:
+            // Valid names: rotatex(, rotatey(, rotatez(, scale3d(.
+            if ((characters[0] == 's') || (characters[0] == 'S')) {
+                if (((characters[1] == 'c') || (characters[1] == 'C'))
+                    &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
+                    &amp; ((characters[3] == 'l') || (characters[3] == 'L'))
+                    &amp; ((characters[4] == 'e') || (characters[4] == 'E'))
+                    &amp; (characters[5] == '3')
+                    &amp; ((characters[6] == 'd') || (characters[6] == 'D'))
+                    &amp; (characters[7] == '(')) {
+                    m_unit = CSSParser::FNumber;
+                    m_type = WebKitCSSTransformValue::Scale3DTransformOperation;
+                    m_argCount = 5;
+                }
+            } else if (((characters[0] == 'r') || (characters[0] == 'R'))
+                       &amp; ((characters[1] == 'o') || (characters[1] == 'O'))
+                       &amp; ((characters[2] == 't') || (characters[2] == 'T'))
+                       &amp; ((characters[3] == 'a') || (characters[3] == 'A'))
+                       &amp; ((characters[4] == 't') || (characters[4] == 'T'))
+                       &amp; ((characters[5] == 'e') || (characters[5] == 'E'))
+                       &amp; (characters[7] == '(')) {
+                if ((characters[6] == 'x') || (characters[6] == 'X')) {
+                    m_unit = CSSParser::FAngle;
+                    m_type = WebKitCSSTransformValue::RotateXTransformOperation;
+                } else if ((characters[6] == 'y') || (characters[6] == 'Y')) {
+                    m_unit = CSSParser::FAngle;
+                    m_type = WebKitCSSTransformValue::RotateYTransformOperation;
+                } else if ((characters[6] == 'z') || (characters[6] == 'Z')) {
+                    m_unit = CSSParser::FAngle;
+                    m_type = WebKitCSSTransformValue::RotateZTransformOperation;
+                }
+            }
+            break;
+        case 9:
+            // Valid names: matrix3d(, rotate3d(.
+            if ((characters[0] == 'm') || (characters[0] == 'M')) {
+                if (((characters[1] == 'a') || (characters[1] == 'A'))
+                    &amp; ((characters[2] == 't') || (characters[2] == 'T'))
+                    &amp; ((characters[3] == 'r') || (characters[3] == 'R'))
+                    &amp; ((characters[4] == 'i') || (characters[4] == 'I'))
+                    &amp; ((characters[5] == 'x') || (characters[5] == 'X'))
+                    &amp; (characters[6] == '3')
+                    &amp; ((characters[7] == 'd') || (characters[7] == 'D'))
+                    &amp; (characters[8] == '(')) {
+                    m_unit = CSSParser::FNumber;
+                    m_type = WebKitCSSTransformValue::Matrix3DTransformOperation;
+                    m_argCount = 31;
+                }
+            } else if (((characters[0] == 'r') || (characters[0] == 'R'))
+                       &amp; ((characters[1] == 'o') || (characters[1] == 'O'))
+                       &amp; ((characters[2] == 't') || (characters[2] == 'T'))
+                       &amp; ((characters[3] == 'a') || (characters[3] == 'A'))
+                       &amp; ((characters[4] == 't') || (characters[4] == 'T'))
+                       &amp; ((characters[5] == 'e') || (characters[5] == 'E'))
+                       &amp; (characters[6] == '3')
+                       &amp; ((characters[7] == 'd') || (characters[7] == 'D'))
+                       &amp; (characters[8] == '(')) {
+                m_unit = CSSParser::FNumber;
+                m_type = WebKitCSSTransformValue::Rotate3DTransformOperation;
+                m_argCount = 7;
+            }
+            break;
+        case 10:
+            // Valid name: translate(.
+            if (((characters[0] == 't') || (characters[0] == 'T'))
+                &amp; ((characters[1] == 'r') || (characters[1] == 'R'))
+                &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
+                &amp; ((characters[3] == 'n') || (characters[3] == 'N'))
+                &amp; ((characters[4] == 's') || (characters[4] == 'S'))
+                &amp; ((characters[5] == 'l') || (characters[5] == 'L'))
+                &amp; ((characters[6] == 'a') || (characters[6] == 'A'))
+                &amp; ((characters[7] == 't') || (characters[7] == 'T'))
+                &amp; ((characters[8] == 'e') || (characters[8] == 'E'))
+                &amp; (characters[9] == '(')) {
+                m_unit = CSSParser::FLength | CSSParser::FPercent;
+                m_type = WebKitCSSTransformValue::TranslateTransformOperation;
+                m_allowSingleArgument = true;
+                m_argCount = 3;
+            }
+            break;
+        case 11:
+            // Valid names: translatex(, translatey(, translatez(.
+            if (((characters[0] == 't') || (characters[0] == 'T'))
+                &amp; ((characters[1] == 'r') || (characters[1] == 'R'))
+                &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
+                &amp; ((characters[3] == 'n') || (characters[3] == 'N'))
+                &amp; ((characters[4] == 's') || (characters[4] == 'S'))
+                &amp; ((characters[5] == 'l') || (characters[5] == 'L'))
+                &amp; ((characters[6] == 'a') || (characters[6] == 'A'))
+                &amp; ((characters[7] == 't') || (characters[7] == 'T'))
+                &amp; ((characters[8] == 'e') || (characters[8] == 'E'))
+                &amp; (characters[10] == '(')) {
+                if ((characters[9] == 'x') || (characters[9] == 'X')) {
+                    m_unit = CSSParser::FLength | CSSParser::FPercent;
+                    m_type = WebKitCSSTransformValue::TranslateXTransformOperation;
+                } else if ((characters[9] == 'y') || (characters[9] == 'Y')) {
+                    m_unit = CSSParser::FLength | CSSParser::FPercent;
+                    m_type = WebKitCSSTransformValue::TranslateYTransformOperation;
+                } else if ((characters[9] == 'z') || (characters[9] == 'Z')) {
+                    m_unit = CSSParser::FLength | CSSParser::FPercent;
+                    m_type = WebKitCSSTransformValue::TranslateZTransformOperation;
+                }
+            }
+            break;
+        case 12:
+            // Valid names: perspective(, translate3d(.
+            if ((characters[0] == 'p') || (characters[0] == 'P')) {
+                if (((characters[1] == 'e') || (characters[1] == 'E'))
+                    &amp; ((characters[2] == 'r') || (characters[2] == 'R'))
+                    &amp; ((characters[3] == 's') || (characters[3] == 'S'))
+                    &amp; ((characters[4] == 'p') || (characters[4] == 'P'))
+                    &amp; ((characters[5] == 'e') || (characters[5] == 'E'))
+                    &amp; ((characters[6] == 'c') || (characters[6] == 'C'))
+                    &amp; ((characters[7] == 't') || (characters[7] == 'T'))
+                    &amp; ((characters[8] == 'i') || (characters[8] == 'I'))
+                    &amp; ((characters[9] == 'v') || (characters[9] == 'V'))
+                    &amp; ((characters[10] == 'e') || (characters[10] == 'E'))
+                    &amp; (characters[11] == '(')) {
+                    m_unit = CSSParser::FNumber;
+                    m_type = WebKitCSSTransformValue::PerspectiveTransformOperation;
+                }
+            } else if (((characters[0] == 't') || (characters[0] == 'T'))
+                       &amp; ((characters[1] == 'r') || (characters[1] == 'R'))
+                       &amp; ((characters[2] == 'a') || (characters[2] == 'A'))
+                       &amp; ((characters[3] == 'n') || (characters[3] == 'N'))
+                       &amp; ((characters[4] == 's') || (characters[4] == 'S'))
+                       &amp; ((characters[5] == 'l') || (characters[5] == 'L'))
+                       &amp; ((characters[6] == 'a') || (characters[6] == 'A'))
+                       &amp; ((characters[7] == 't') || (characters[7] == 'T'))
+                       &amp; ((characters[8] == 'e') || (characters[8] == 'E'))
+                       &amp; (characters[9] == '3')
+                       &amp; ((characters[10] == 'd') || (characters[10] == 'D'))
+                       &amp; (characters[11] == '(')) {
+                m_unit = CSSParser::FLength | CSSParser::FPercent;
+                m_type = WebKitCSSTransformValue::Translate3DTransformOperation;
+                m_argCount = 5;
+            }
+            break;
+        } // end switch ()
+    }
+
+    WebKitCSSTransformValue::TransformOperationType type() const { return m_type; }
+    unsigned argCount() const { return m_argCount; }
+    CSSParser::Units unit() const { return m_unit; }
+
+    bool unknown() const { return m_type == WebKitCSSTransformValue::UnknownTransformOperation; }
+    bool hasCorrectArgCount(unsigned argCount) { return m_argCount == argCount || (m_allowSingleArgument &amp;&amp; argCount == 1); }
+
+private:
+    WebKitCSSTransformValue::TransformOperationType m_type;
+    unsigned m_argCount;
+    bool m_allowSingleArgument;
+    CSSParser::Units m_unit;
+};
+
+RefPtr&lt;CSSValueList&gt; CSSParser::parseTransform()
+{
+    if (!m_valueList)
+        return nullptr;
+
+    auto list = CSSValueList::createSpaceSeparated();
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        auto parsedTransformValue = parseTransformValue(*value);
+        if (!parsedTransformValue)
+            return nullptr;
+
+        list-&gt;append(parsedTransformValue.releaseNonNull());
+    }
+
+    return WTFMove(list);
+}
+
+RefPtr&lt;WebKitCSSTransformValue&gt; CSSParser::parseTransformValue(CSSParserValue&amp; value)
+{
+    if (value.unit != CSSParserValue::Function || !value.function)
+        return nullptr;
+
+    // Every primitive requires at least one argument.
+    CSSParserValueList* args = value.function-&gt;args.get();
+    if (!args)
+        return nullptr;
+
+    // See if the specified primitive is one we understand.
+    TransformOperationInfo info(value.function-&gt;name);
+    if (info.unknown())
+        return nullptr;
+
+    if (!info.hasCorrectArgCount(args-&gt;size()))
+        return nullptr;
+
+    // The transform is a list of functional primitives that specify transform operations.
+    // We collect a list of WebKitCSSTransformValues, where each value specifies a single operation.
+
+    // Create the new WebKitCSSTransformValue for this operation and add it to our list.
+    auto transformValue = WebKitCSSTransformValue::create(info.type());
+
+    // Snag our values.
+    CSSParserValue* argument = args-&gt;current();
+    unsigned argNumber = 0;
+    while (argument) {
+        ValueWithCalculation argumentWithCalculation(*argument);
+        CSSParser::Units unit = info.unit();
+
+        if (info.type() == WebKitCSSTransformValue::Rotate3DTransformOperation &amp;&amp; argNumber == 3) {
+            // 4th param of rotate3d() is an angle rather than a bare number, validate it as such
+            if (!validateUnit(argumentWithCalculation, FAngle, CSSStrictMode))
+                return nullptr;
+        } else if (info.type() == WebKitCSSTransformValue::Translate3DTransformOperation &amp;&amp; argNumber == 2) {
+            // 3rd param of translate3d() cannot be a percentage
+            if (!validateUnit(argumentWithCalculation, FLength, CSSStrictMode))
+                return nullptr;
+        } else if (info.type() == WebKitCSSTransformValue::TranslateZTransformOperation &amp;&amp; !argNumber) {
+            // 1st param of translateZ() cannot be a percentage
+            if (!validateUnit(argumentWithCalculation, FLength, CSSStrictMode))
+                return nullptr;
+        } else if (info.type() == WebKitCSSTransformValue::PerspectiveTransformOperation &amp;&amp; !argNumber) {
+            // 1st param of perspective() must be a non-negative number (deprecated) or length.
+            if (!validateUnit(argumentWithCalculation, FNumber | FLength | FNonNeg, CSSStrictMode))
+                return nullptr;
+        } else if (!validateUnit(argumentWithCalculation, unit, CSSStrictMode))
+            return nullptr;
+
+        // Add the value to the current transform operation.
+        transformValue-&gt;append(createPrimitiveNumericValue(argumentWithCalculation));
+
+        argument = args-&gt;next();
+        if (!argument)
+            break;
+        if (argument-&gt;unit != CSSParserValue::Operator || argument-&gt;iValue != ',')
+            return nullptr;
+        argument = args-&gt;next();
+
+        ++argNumber;
+    }
+
+    return WTFMove(transformValue);
+}
+
+bool CSSParser::isBlendMode(CSSValueID valueID)
+{
+    return (valueID &gt;= CSSValueMultiply &amp;&amp; valueID &lt;= CSSValueLuminosity)
+        || valueID == CSSValueNormal
+        || valueID == CSSValueOverlay;
+}
+
+bool CSSParser::isCompositeOperator(CSSValueID valueID)
+{
+    // FIXME: Add CSSValueDestination and CSSValueLighter when the Compositing spec updates.
+    return valueID &gt;= CSSValueClear &amp;&amp; valueID &lt;= CSSValueXor;
+}
+
+static void filterInfoForName(const CSSParserString&amp; name, WebKitCSSFilterValue::FilterOperationType&amp; filterType, unsigned&amp; maximumArgumentCount)
+{
+    if (equalLettersIgnoringASCIICase(name, &quot;grayscale(&quot;))
+        filterType = WebKitCSSFilterValue::GrayscaleFilterOperation;
+    else if (equalLettersIgnoringASCIICase(name, &quot;sepia(&quot;))
+        filterType = WebKitCSSFilterValue::SepiaFilterOperation;
+    else if (equalLettersIgnoringASCIICase(name, &quot;saturate(&quot;))
+        filterType = WebKitCSSFilterValue::SaturateFilterOperation;
+    else if (equalLettersIgnoringASCIICase(name, &quot;hue-rotate(&quot;))
+        filterType = WebKitCSSFilterValue::HueRotateFilterOperation;
+    else if (equalLettersIgnoringASCIICase(name, &quot;invert(&quot;))
+        filterType = WebKitCSSFilterValue::InvertFilterOperation;
+    else if (equalLettersIgnoringASCIICase(name, &quot;opacity(&quot;))
+        filterType = WebKitCSSFilterValue::OpacityFilterOperation;
+    else if (equalLettersIgnoringASCIICase(name, &quot;brightness(&quot;))
+        filterType = WebKitCSSFilterValue::BrightnessFilterOperation;
+    else if (equalLettersIgnoringASCIICase(name, &quot;contrast(&quot;))
+        filterType = WebKitCSSFilterValue::ContrastFilterOperation;
+    else if (equalLettersIgnoringASCIICase(name, &quot;blur(&quot;))
+        filterType = WebKitCSSFilterValue::BlurFilterOperation;
+    else if (equalLettersIgnoringASCIICase(name, &quot;drop-shadow(&quot;)) {
+        filterType = WebKitCSSFilterValue::DropShadowFilterOperation;
+        maximumArgumentCount = 4;  // x-offset, y-offset, blur-radius, color -- spread and inset style not allowed.
+    }
+}
+
+RefPtr&lt;WebKitCSSFilterValue&gt; CSSParser::parseBuiltinFilterArguments(CSSParserValueList&amp; args, WebKitCSSFilterValue::FilterOperationType filterType)
+{
+    auto filterValue = WebKitCSSFilterValue::create(filterType);
+
+    switch (filterType) {    
+    case WebKitCSSFilterValue::GrayscaleFilterOperation:
+    case WebKitCSSFilterValue::SepiaFilterOperation:
+    case WebKitCSSFilterValue::SaturateFilterOperation:
+    case WebKitCSSFilterValue::InvertFilterOperation:
+    case WebKitCSSFilterValue::OpacityFilterOperation:
+    case WebKitCSSFilterValue::ContrastFilterOperation: {
+        // One optional argument, 0-1 or 0%-100%, if missing use 100%.
+        if (args.size() &gt; 1)
+            return nullptr;
+
+        if (args.size()) {
+            ValueWithCalculation argumentWithCalculation(*args.current());
+            if (!validateUnit(argumentWithCalculation, FNumber | FPercent | FNonNeg, CSSStrictMode))
+                return nullptr;
+
+            auto primitiveValue = createPrimitiveNumericValue(argumentWithCalculation);
+
+            // Saturate and Contrast allow values over 100%.
+            if (filterType != WebKitCSSFilterValue::SaturateFilterOperation
+                &amp;&amp; filterType != WebKitCSSFilterValue::ContrastFilterOperation) {
+                double maxAllowed = primitiveValue-&gt;primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
+                if (primitiveValue-&gt;getDoubleValue() &gt; maxAllowed)
+                    return nullptr;
+            }
+
+            filterValue-&gt;append(WTFMove(primitiveValue));
+        }
+        break;
+    }
+    case WebKitCSSFilterValue::BrightnessFilterOperation: {
+        // One optional argument, if missing use 100%.
+        if (args.size() &gt; 1)
+            return nullptr;
+
+        if (args.size()) {
+            ValueWithCalculation argumentWithCalculation(*args.current());
+            if (!validateUnit(argumentWithCalculation, FNumber | FPercent, CSSStrictMode))
+                return nullptr;
+
+            filterValue-&gt;append(createPrimitiveNumericValue(argumentWithCalculation));
+        }
+        break;
+    }
+    case WebKitCSSFilterValue::HueRotateFilterOperation: {
+        // hue-rotate() takes one optional angle.
+        if (args.size() &gt; 1)
+            return nullptr;
+        
+        if (args.size()) {
+            ValueWithCalculation argumentWithCalculation(*args.current());
+            if (!validateUnit(argumentWithCalculation, FAngle, CSSStrictMode))
+                return nullptr;
+        
+            filterValue-&gt;append(createPrimitiveNumericValue(argumentWithCalculation));
+        }
+        break;
+    }
+    case WebKitCSSFilterValue::BlurFilterOperation: {
+        // Blur takes a single length. Zero parameters are allowed.
+        if (args.size() &gt; 1)
+            return nullptr;
+        
+        if (args.size()) {
+            ValueWithCalculation argumentWithCalculation(*args.current());
+            if (!validateUnit(argumentWithCalculation, FLength | FNonNeg, CSSStrictMode))
+                return nullptr;
+
+            filterValue-&gt;append(createPrimitiveNumericValue(argumentWithCalculation));
+        }
+        break;
+    }
+    case WebKitCSSFilterValue::DropShadowFilterOperation: {
+        // drop-shadow() takes a single shadow.
+        RefPtr&lt;CSSValueList&gt; shadowValueList = parseShadow(args, CSSPropertyFilter);
+        if (!shadowValueList || shadowValueList-&gt;length() != 1)
+            return nullptr;
+        
+        filterValue-&gt;append(*shadowValueList-&gt;itemWithoutBoundsCheck(0));
+        break;
+    }
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    return WTFMove(filterValue);
+}
+
+bool CSSParser::parseFilter(CSSParserValueList&amp; valueList, RefPtr&lt;CSSValueList&gt;&amp; result)
+{
+    // The filter is a list of functional primitives that specify individual operations.
+    auto list = CSSValueList::createSpaceSeparated();
+    for (auto* value = valueList.current(); value; value = valueList.next()) {
+        if (value-&gt;unit != CSSPrimitiveValue::CSS_URI &amp;&amp; (value-&gt;unit != CSSParserValue::Function || !value-&gt;function))
+            return false;
+
+        WebKitCSSFilterValue::FilterOperationType filterType = WebKitCSSFilterValue::UnknownFilterOperation;
+
+        // See if the specified primitive is one we understand.
+        if (value-&gt;unit == CSSPrimitiveValue::CSS_URI) {
+            auto referenceFilterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation);
+            referenceFilterValue-&gt;append(CSSPrimitiveValue::create(value-&gt;string, CSSPrimitiveValue::CSS_URI));
+            list-&gt;append(WTFMove(referenceFilterValue));
+        } else {
+            const CSSParserString name = value-&gt;function-&gt;name;
+            unsigned maximumArgumentCount = 1;
+
+            filterInfoForName(name, filterType, maximumArgumentCount);
+
+            if (filterType == WebKitCSSFilterValue::UnknownFilterOperation)
+                return false;
+
+            CSSParserValueList* args = value-&gt;function-&gt;args.get();
+            if (!args)
+                return false;
+
+            RefPtr&lt;WebKitCSSFilterValue&gt; filterValue = parseBuiltinFilterArguments(*args, filterType);
+            if (!filterValue)
+                return false;
+            
+            list-&gt;append(filterValue.releaseNonNull());
+        }
+    }
+
+    result = WTFMove(list);
+
+    return true;
+}
+
+#if ENABLE(CSS_REGIONS)
+static bool validFlowName(const String&amp; flowName)
+{
+    return !(equalLettersIgnoringASCIICase(flowName, &quot;auto&quot;)
+        || equalLettersIgnoringASCIICase(flowName, &quot;default&quot;)
+        || equalLettersIgnoringASCIICase(flowName, &quot;inherit&quot;)
+        || equalLettersIgnoringASCIICase(flowName, &quot;initial&quot;)
+        || equalLettersIgnoringASCIICase(flowName, &quot;none&quot;));
+}
+#endif
+
+#if ENABLE(IOS_TEXT_AUTOSIZING)
+bool CSSParser::isTextAutosizingEnabled() const
+{
+    return m_context.textAutosizingEnabled;
+}
+#endif
+
+#if ENABLE(CSS_GRID_LAYOUT)
+bool CSSParser::isCSSGridLayoutEnabled() const
+{
+    return m_context.cssGridLayoutEnabled;
+}
+#endif
+
+#if ENABLE(CSS_REGIONS)
+
+// none | &lt;ident&gt;
+bool CSSParser::parseFlowThread(CSSPropertyID propId, bool important)
+{
+    ASSERT(propId == CSSPropertyWebkitFlowInto);
+
+    if (m_valueList-&gt;size() != 1)
+        return false;
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (!value)
+        return false;
+
+    if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+        return false;
+
+    if (value-&gt;id == CSSValueNone) {
+        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
+        return true;
+    }
+
+    String inputProperty = String(value-&gt;string);
+    if (!inputProperty.isEmpty()) {
+        if (!validFlowName(inputProperty))
+            return false;
+        addProperty(propId, CSSValuePool::singleton().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important);
+    } else
+        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+
+    return true;
+}
+
+// -webkit-flow-from: none | &lt;ident&gt;
+bool CSSParser::parseRegionThread(CSSPropertyID propId, bool important)
+{
+    ASSERT(propId == CSSPropertyWebkitFlowFrom);
+
+    if (m_valueList-&gt;size() != 1)
+        return false;
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (!value)
+        return false;
+
+    if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+        return false;
+
+    if (value-&gt;id == CSSValueNone)
+        addProperty(propId, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
+    else {
+        String inputProperty = String(value-&gt;string);
+        if (!inputProperty.isEmpty()) {
+            if (!validFlowName(inputProperty))
+                return false;
+            addProperty(propId, CSSValuePool::singleton().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important);
+        } else
+            addProperty(propId, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+    }
+
+    return true;
+}
+#endif
+
+bool CSSParser::parseTransformOrigin(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2, CSSPropertyID&amp; propId3, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2, RefPtr&lt;CSSValue&gt;&amp; value3)
+{
+    propId1 = propId;
+    propId2 = propId;
+    propId3 = propId;
+    if (propId == CSSPropertyTransformOrigin) {
+        propId1 = CSSPropertyTransformOriginX;
+        propId2 = CSSPropertyTransformOriginY;
+        propId3 = CSSPropertyTransformOriginZ;
+    }
+
+    switch (propId) {
+    case CSSPropertyTransformOrigin:
+        if (!parseTransformOriginShorthand(value, value2, value3))
+            return false;
+        // parseTransformOriginShorthand advances the m_valueList pointer
+        break;
+    case CSSPropertyTransformOriginX: {
+        value = parsePositionX(*m_valueList);
+        if (value)
+            m_valueList-&gt;next();
+        break;
+    }
+    case CSSPropertyTransformOriginY: {
+        value = parsePositionY(*m_valueList);
+        if (value)
+            m_valueList-&gt;next();
+        break;
+    }
+    case CSSPropertyTransformOriginZ: {
+        ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+        if (validateUnit(valueWithCalculation, FLength))
+            value = createPrimitiveNumericValue(valueWithCalculation);
+        if (value)
+            m_valueList-&gt;next();
+        break;
+    }
+    default:
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    return value;
+}
+
+bool CSSParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value, RefPtr&lt;CSSPrimitiveValue&gt;&amp; value2)
+{
+    propId1 = propId;
+    propId2 = propId;
+    if (propId == CSSPropertyPerspectiveOrigin) {
+        propId1 = CSSPropertyPerspectiveOriginX;
+        propId2 = CSSPropertyPerspectiveOriginY;
+    }
+
+    switch (propId) {
+    case CSSPropertyPerspectiveOrigin:
+        if (m_valueList-&gt;size() &gt; 2)
+            return false;
+        parse2ValuesFillPosition(*m_valueList, value, value2);
+        break;
+    case CSSPropertyPerspectiveOriginX: {
+        value = parsePositionX(*m_valueList);
+        if (value)
+            m_valueList-&gt;next();
+        break;
+    }
+    case CSSPropertyPerspectiveOriginY: {
+        value = parsePositionY(*m_valueList);
+        if (value)
+            m_valueList-&gt;next();
+        break;
+    }
+    default:
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    return value;
+}
+
+void CSSParser::addTextDecorationProperty(CSSPropertyID propId, RefPtr&lt;CSSValue&gt;&amp;&amp; value, bool important)
+{
+    // The text-decoration-line property takes priority over text-decoration, unless the latter has important priority set.
+    if (propId == CSSPropertyTextDecoration &amp;&amp; !important &amp;&amp; !inShorthand()) {
+        for (unsigned i = 0; i &lt; m_parsedProperties.size(); ++i) {
+            if (m_parsedProperties[i].id() == CSSPropertyWebkitTextDecorationLine)
+                return;
+        }
+    }
+    addProperty(propId, WTFMove(value), important);
+}
+
+bool CSSParser::parseTextDecoration(CSSPropertyID propId, bool important)
+{
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (value &amp;&amp; value-&gt;id == CSSValueNone) {
+        addTextDecorationProperty(propId, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+        m_valueList-&gt;next();
+        return true;
+    }
+
+    auto list = CSSValueList::createSpaceSeparated();
+    bool isValid = true;
+    while (isValid &amp;&amp; value) {
+        switch (value-&gt;id) {
+        case CSSValueBlink:
+        case CSSValueLineThrough:
+        case CSSValueOverline:
+        case CSSValueUnderline:
+#if ENABLE(LETTERPRESS)
+        case CSSValueWebkitLetterpress:
+#endif
+            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            break;
+        default:
+            isValid = false;
+            break;
+        }
+        if (isValid)
+            value = m_valueList-&gt;next();
+    }
+
+    // Values are either valid or in shorthand scope.
+    if (list-&gt;length() &amp;&amp; (isValid || inShorthand())) {
+        addTextDecorationProperty(propId, WTFMove(list), important);
+        return true;
+    }
+
+    return false;
+}
+
+bool CSSParser::parseTextDecorationSkip(bool important)
+{
+    // The text-decoration-skip property has syntax &quot;none | [ objects || spaces || ink || edges || box-decoration ]&quot;.
+    // However, only 'none' and 'ink' are implemented yet, so we will parse syntax &quot;none | ink&quot; for now.
+    CSSParserValue* value = m_valueList-&gt;current();
+    do {
+        switch (value-&gt;id) {
+        case CSSValueNone:
+        case CSSValueAuto:
+        case CSSValueInk:
+        case CSSValueObjects:
+            addProperty(CSSPropertyWebkitTextDecorationSkip, CSSValuePool::singleton().createIdentifierValue(value-&gt;id), important);
+            return true;
+        default:
+            break;
+        }
+    } while ((value = m_valueList-&gt;next()));
+    return false;
+}
+
+bool CSSParser::parseTextUnderlinePosition(bool important)
+{
+    // The text-underline-position property has sintax &quot;auto | alphabetic | [ under || [ left | right ] ]&quot;.
+    // However, values 'left' and 'right' are not implemented yet, so we will parse sintax
+    // &quot;auto | alphabetic | under&quot; for now.
+    CSSParserValue&amp; value = *m_valueList-&gt;current();
+    switch (value.id) {
+    case CSSValueAuto:
+    case CSSValueAlphabetic:
+    case CSSValueUnder:
+        if (m_valueList-&gt;next())
+            return false;
+
+        addProperty(CSSPropertyWebkitTextUnderlinePosition, CSSValuePool::singleton().createIdentifierValue(value.id), important);
+        return true;
+    default:
+        break;
+    }
+    return false;
+}
+
+bool CSSParser::parseTextEmphasisStyle(bool important)
+{
+    unsigned valueListSize = m_valueList-&gt;size();
+
+    RefPtr&lt;CSSPrimitiveValue&gt; fill;
+    RefPtr&lt;CSSPrimitiveValue&gt; shape;
+
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (value-&gt;unit == CSSPrimitiveValue::CSS_STRING) {
+            if (fill || shape || (valueListSize != 1 &amp;&amp; !inShorthand()))
+                return false;
+            addProperty(CSSPropertyWebkitTextEmphasisStyle, createPrimitiveStringValue(*value), important);
+            m_valueList-&gt;next();
+            return true;
+        }
+
+        if (value-&gt;id == CSSValueNone) {
+            if (fill || shape || (valueListSize != 1 &amp;&amp; !inShorthand()))
+                return false;
+            addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+            m_valueList-&gt;next();
+            return true;
+        }
+
+        if (value-&gt;id == CSSValueOpen || value-&gt;id == CSSValueFilled) {
+            if (fill)
+                return false;
+            fill = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+        } else if (value-&gt;id == CSSValueDot || value-&gt;id == CSSValueCircle || value-&gt;id == CSSValueDoubleCircle || value-&gt;id == CSSValueTriangle || value-&gt;id == CSSValueSesame) {
+            if (shape)
+                return false;
+            shape = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+        } else if (!inShorthand())
+            return false;
+        else
+            break;
+    }
+
+    if (fill &amp;&amp; shape) {
+        auto parsedValues = CSSValueList::createSpaceSeparated();
+        parsedValues-&gt;append(fill.releaseNonNull());
+        parsedValues-&gt;append(shape.releaseNonNull());
+        addProperty(CSSPropertyWebkitTextEmphasisStyle, WTFMove(parsedValues), important);
+        return true;
+    }
+    if (fill) {
+        addProperty(CSSPropertyWebkitTextEmphasisStyle, fill.releaseNonNull(), important);
+        return true;
+    }
+    if (shape) {
+        addProperty(CSSPropertyWebkitTextEmphasisStyle, shape.releaseNonNull(), important);
+        return true;
+    }
+
+    return false;
+}
+
+bool CSSParser::parseTextEmphasisPosition(bool important)
+{
+    bool foundOverOrUnder = false;
+    CSSValueID overUnderValueID = CSSValueOver;
+    bool foundLeftOrRight = false;
+    CSSValueID leftRightValueID = CSSValueRight;
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        switch (value-&gt;id) {
+        case CSSValueOver:
+            if (foundOverOrUnder)
+                return false;
+            foundOverOrUnder = true;
+            overUnderValueID = CSSValueOver;
+            break;
+        case CSSValueUnder:
+            if (foundOverOrUnder)
+                return false;
+            foundOverOrUnder = true;
+            overUnderValueID = CSSValueUnder;
+            break;
+        case CSSValueLeft:
+            if (foundLeftOrRight)
+                return false;
+            foundLeftOrRight = true;
+            leftRightValueID = CSSValueLeft;
+            break;
+        case CSSValueRight:
+            if (foundLeftOrRight)
+                return false;
+            foundLeftOrRight = true;
+            leftRightValueID = CSSValueRight;
+            break;
+        default:
+            return false;
+        }
+    }
+    if (!foundOverOrUnder)
+        return false;
+    auto list = CSSValueList::createSpaceSeparated();
+    list-&gt;append(CSSValuePool::singleton().createIdentifierValue(overUnderValueID));
+    if (foundLeftOrRight)
+        list-&gt;append(CSSValuePool::singleton().createIdentifierValue(leftRightValueID));
+    addProperty(CSSPropertyWebkitTextEmphasisPosition, WTFMove(list), important);
+    return true;
+}
+
+RefPtr&lt;CSSValueList&gt; CSSParser::parseTextIndent()
+{
+    // &lt;length&gt; | &lt;percentage&gt; | inherit  when CSS3_TEXT is disabled.
+    // [ &lt;length&gt; | &lt;percentage&gt; ] &amp;&amp; [ -webkit-hanging || -webkit-each-line ]? | inherit  when CSS3_TEXT is enabled.
+    auto list = CSSValueList::createSpaceSeparated();
+    bool hasLengthOrPercentage = false;
+#if ENABLE(CSS3_TEXT)
+    bool hasEachLine = false;
+    bool hasHanging = false;
+#endif
+
+    CSSParserValue* value = m_valueList-&gt;current();
+    while (value) {
+        ValueWithCalculation valueWithCalculation(*value);
+        if (!hasLengthOrPercentage &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent)) {
+            list-&gt;append(createPrimitiveNumericValue(valueWithCalculation));
+            hasLengthOrPercentage = true;
+        }
+#if ENABLE(CSS3_TEXT)
+        else if (!hasEachLine &amp;&amp; value-&gt;id == CSSValueWebkitEachLine) {
+            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueWebkitEachLine));
+            hasEachLine = true;
+        } else if (!hasHanging &amp;&amp; value-&gt;id == CSSValueWebkitHanging) {
+            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueWebkitHanging));
+            hasHanging = true;
+        }
+#endif
+        else
+            return nullptr;
+
+        value = m_valueList-&gt;next();
+    }
+
+    if (!hasLengthOrPercentage)
+        return nullptr;
+
+    return WTFMove(list);
+}
+
+bool CSSParser::parseHangingPunctuation(bool important)
+{
+    CSSParserValue* value = m_valueList-&gt;current();
+    if (value &amp;&amp; value-&gt;id == CSSValueNone) {
+        addProperty(CSSPropertyHangingPunctuation, CSSValuePool::singleton().createIdentifierValue(CSSValueNone), important);
+        m_valueList-&gt;next();
+        return true;
+    }
+    
+    auto list = CSSValueList::createSpaceSeparated();
+    bool isValid = true;
+    std::bitset&lt;numCSSValueKeywords&gt; seenValues;
+    while (isValid &amp;&amp; value) {
+        if (seenValues[value-&gt;id]
+            || (value-&gt;id == CSSValueAllowEnd &amp;&amp; seenValues[CSSValueForceEnd])
+            || (value-&gt;id == CSSValueForceEnd &amp;&amp; seenValues[CSSValueAllowEnd])) {
+            isValid = false;
+            break;
+        }
+        switch (value-&gt;id) {
+        case CSSValueAllowEnd:
+        case CSSValueFirst:
+        case CSSValueForceEnd:
+        case CSSValueLast:
+            list-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            seenValues.set(value-&gt;id);
+            break;
+        default:
+            isValid = false;
+            break;
+        }
+        if (isValid)
+            value = m_valueList-&gt;next();
+    }
+    
+    // Values are either valid or in shorthand scope.
+    if (list-&gt;length() &amp;&amp; isValid) {
+        addProperty(CSSPropertyHangingPunctuation, WTFMove(list), important);
+        return true;
+    }
+    
+    return false;
+}
+
+bool CSSParser::parseLineBoxContain(bool important)
+{
+    LineBoxContain lineBoxContain = LineBoxContainNone;
+
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (value-&gt;id == CSSValueBlock) {
+            if (lineBoxContain &amp; LineBoxContainBlock)
+                return false;
+            lineBoxContain |= LineBoxContainBlock;
+        } else if (value-&gt;id == CSSValueInline) {
+            if (lineBoxContain &amp; LineBoxContainInline)
+                return false;
+            lineBoxContain |= LineBoxContainInline;
+        } else if (value-&gt;id == CSSValueFont) {
+            if (lineBoxContain &amp; LineBoxContainFont)
+                return false;
+            lineBoxContain |= LineBoxContainFont;
+        } else if (value-&gt;id == CSSValueGlyphs) {
+            if (lineBoxContain &amp; LineBoxContainGlyphs)
+                return false;
+            lineBoxContain |= LineBoxContainGlyphs;
+        } else if (value-&gt;id == CSSValueReplaced) {
+            if (lineBoxContain &amp; LineBoxContainReplaced)
+                return false;
+            lineBoxContain |= LineBoxContainReplaced;
+        } else if (value-&gt;id == CSSValueInlineBox) {
+            if (lineBoxContain &amp; LineBoxContainInlineBox)
+                return false;
+            lineBoxContain |= LineBoxContainInlineBox;
+        } else if (value-&gt;id == CSSValueInitialLetter) {
+            if (lineBoxContain &amp; LineBoxContainInitialLetter)
+                return false;
+            lineBoxContain |= LineBoxContainInitialLetter;
+        } else
+            return false;
+    }
+
+    if (!lineBoxContain)
+        return false;
+
+    addProperty(CSSPropertyWebkitLineBoxContain, CSSLineBoxContainValue::create(lineBoxContain), important);
+    return true;
+}
+
+bool CSSParser::parseFontFeatureTag(CSSValueList&amp; settings)
+{
+    CSSParserValue* value = m_valueList-&gt;current();
+    // Feature tag name comes first
+    if (value-&gt;unit != CSSPrimitiveValue::CSS_STRING)
+        return false;
+    FontFeatureTag tag;
+    if (value-&gt;string.length() != tag.size())
+        return false;
+    for (unsigned i = 0; i &lt; tag.size(); ++i) {
+        // Limits the range of characters to 0x20-0x7E, following the tag name rules defiend in the OpenType specification.
+        UChar character = value-&gt;string[i];
+        if (character &lt; 0x20 || character &gt; 0x7E)
+            return false;
+        tag[i] = toASCIILower(character);
+    }
+
+    int tagValue = 1;
+    // Feature tag values could follow: &lt;integer&gt; | on | off
+    value = m_valueList-&gt;next();
+    if (value) {
+        if (value-&gt;unit == CSSPrimitiveValue::CSS_NUMBER &amp;&amp; value-&gt;isInt &amp;&amp; value-&gt;fValue &gt;= 0) {
+            tagValue = clampToInteger(value-&gt;fValue);
+            if (tagValue &lt; 0)
+                return false;
+            m_valueList-&gt;next();
+        } else if (value-&gt;id == CSSValueOn || value-&gt;id == CSSValueOff) {
+            tagValue = value-&gt;id == CSSValueOn;
+            m_valueList-&gt;next();
+        }
+    }
+    settings.append(CSSFontFeatureValue::create(WTFMove(tag), tagValue));
+    return true;
+}
+
+bool CSSParser::parseFontFeatureSettings(bool important)
+{
+    if (m_valueList-&gt;size() == 1 &amp;&amp; m_valueList-&gt;current()-&gt;id == CSSValueNormal) {
+        auto normalValue = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
+        m_valueList-&gt;next();
+        addProperty(CSSPropertyFontFeatureSettings, WTFMove(normalValue), important);
+        return true;
+    }
+
+    auto settings = CSSValueList::createCommaSeparated();
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (!parseFontFeatureTag(settings))
+            return false;
+
+        // If the list isn't parsed fully, the current value should be comma.
+        value = m_valueList-&gt;current();
+        if (value &amp;&amp; !isComma(value))
+            return false;
+    }
+    if (settings-&gt;length()) {
+        addProperty(CSSPropertyFontFeatureSettings, WTFMove(settings), important);
+        return true;
+    }
+    return false;
+}
+
+bool CSSParser::parseFontVariantLigatures(bool important, bool unknownIsFailure, bool implicit)
+{
+    auto values = CSSValueList::createSpaceSeparated();
+    FontVariantLigatures commonLigatures = FontVariantLigatures::Normal;
+    FontVariantLigatures discretionaryLigatures = FontVariantLigatures::Normal;
+    FontVariantLigatures historicalLigatures = FontVariantLigatures::Normal;
+    FontVariantLigatures contextualAlternates = FontVariantLigatures::Normal;
+
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+            return false;
+
+        switch (value-&gt;id) {
+        case CSSValueNoCommonLigatures:
+            commonLigatures = FontVariantLigatures::No;
+            break;
+        case CSSValueCommonLigatures:
+            commonLigatures = FontVariantLigatures::Yes;
+            break;
+        case CSSValueNoDiscretionaryLigatures:
+            discretionaryLigatures = FontVariantLigatures::No;
+            break;
+        case CSSValueDiscretionaryLigatures:
+            discretionaryLigatures = FontVariantLigatures::Yes;
+            break;
+        case CSSValueNoHistoricalLigatures:
+            historicalLigatures = FontVariantLigatures::No;
+            break;
+        case CSSValueHistoricalLigatures:
+            historicalLigatures = FontVariantLigatures::Yes;
+            break;
+        case CSSValueContextual:
+            contextualAlternates = FontVariantLigatures::Yes;
+            break;
+        case CSSValueNoContextual:
+            contextualAlternates = FontVariantLigatures::No;
+            break;
+        default:
+            if (unknownIsFailure)
+                return false;
+            continue;
+        }
+    }
+
+    switch (commonLigatures) {
+    case FontVariantLigatures::Normal:
+        break;
+    case FontVariantLigatures::Yes:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures));
+        break;
+    case FontVariantLigatures::No:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures));
+        break;
+    }
+
+    switch (discretionaryLigatures) {
+    case FontVariantLigatures::Normal:
+        break;
+    case FontVariantLigatures::Yes:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures));
+        break;
+    case FontVariantLigatures::No:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures));
+        break;
+    }
+
+    switch (historicalLigatures) {
+    case FontVariantLigatures::Normal:
+        break;
+    case FontVariantLigatures::Yes:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures));
+        break;
+    case FontVariantLigatures::No:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures));
+        break;
+    }
+
+    switch (contextualAlternates) {
+    case FontVariantLigatures::Normal:
+        break;
+    case FontVariantLigatures::Yes:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual));
+        break;
+    case FontVariantLigatures::No:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual));
+        break;
+    }
+
+    if (!values-&gt;length())
+        return !unknownIsFailure;
+
+    addProperty(CSSPropertyFontVariantLigatures, WTFMove(values), important, implicit);
+    return true;
+}
+
+bool CSSParser::parseFontVariantNumeric(bool important, bool unknownIsFailure, bool implicit)
+{
+    auto values = CSSValueList::createSpaceSeparated();
+    FontVariantNumericFigure figure = FontVariantNumericFigure::Normal;
+    FontVariantNumericSpacing spacing = FontVariantNumericSpacing::Normal;
+    FontVariantNumericFraction fraction = FontVariantNumericFraction::Normal;
+    FontVariantNumericOrdinal ordinal = FontVariantNumericOrdinal::Normal;
+    FontVariantNumericSlashedZero slashedZero = FontVariantNumericSlashedZero::Normal;
+
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+            return false;
+
+        switch (value-&gt;id) {
+        case CSSValueLiningNums:
+            figure = FontVariantNumericFigure::LiningNumbers;
+            break;
+        case CSSValueOldstyleNums:
+            figure = FontVariantNumericFigure::OldStyleNumbers;
+            break;
+        case CSSValueProportionalNums:
+            spacing = FontVariantNumericSpacing::ProportionalNumbers;
+            break;
+        case CSSValueTabularNums:
+            spacing = FontVariantNumericSpacing::TabularNumbers;
+            break;
+        case CSSValueDiagonalFractions:
+            fraction = FontVariantNumericFraction::DiagonalFractions;
+            break;
+        case CSSValueStackedFractions:
+            fraction = FontVariantNumericFraction::StackedFractions;
+            break;
+        case CSSValueOrdinal:
+            ordinal = FontVariantNumericOrdinal::Yes;
+            break;
+        case CSSValueSlashedZero:
+            slashedZero = FontVariantNumericSlashedZero::Yes;
+            break;
+        default:
+            if (unknownIsFailure)
+                return false;
+            continue;
+        }
+    }
+
+    switch (figure) {
+    case FontVariantNumericFigure::Normal:
+        break;
+    case FontVariantNumericFigure::LiningNumbers:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums));
+        break;
+    case FontVariantNumericFigure::OldStyleNumbers:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums));
+        break;
+    }
+
+    switch (spacing) {
+    case FontVariantNumericSpacing::Normal:
+        break;
+    case FontVariantNumericSpacing::ProportionalNumbers:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums));
+        break;
+    case FontVariantNumericSpacing::TabularNumbers:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums));
+        break;
+    }
+
+    switch (fraction) {
+    case FontVariantNumericFraction::Normal:
+        break;
+    case FontVariantNumericFraction::DiagonalFractions:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions));
+        break;
+    case FontVariantNumericFraction::StackedFractions:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions));
+        break;
+    }
+
+    switch (ordinal) {
+    case FontVariantNumericOrdinal::Normal:
+        break;
+    case FontVariantNumericOrdinal::Yes:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal));
+        break;
+    }
+
+    switch (slashedZero) {
+    case FontVariantNumericSlashedZero::Normal:
+        break;
+    case FontVariantNumericSlashedZero::Yes:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero));
+        break;
+    }
+
+    if (!values-&gt;length())
+        return !unknownIsFailure;
+
+    addProperty(CSSPropertyFontVariantNumeric, WTFMove(values), important, implicit);
+    return true;
+}
+
+bool CSSParser::parseFontVariantEastAsian(bool important, bool unknownIsFailure, bool implicit)
+{
+    auto values = CSSValueList::createSpaceSeparated();
+    FontVariantEastAsianVariant variant = FontVariantEastAsianVariant::Normal;
+    FontVariantEastAsianWidth width = FontVariantEastAsianWidth::Normal;
+    FontVariantEastAsianRuby ruby = FontVariantEastAsianRuby::Normal;
+
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+            return false;
+
+        switch (value-&gt;id) {
+        case CSSValueJis78:
+            variant = FontVariantEastAsianVariant::Jis78;
+            break;
+        case CSSValueJis83:
+            variant = FontVariantEastAsianVariant::Jis83;
+            break;
+        case CSSValueJis90:
+            variant = FontVariantEastAsianVariant::Jis90;
+            break;
+        case CSSValueJis04:
+            variant = FontVariantEastAsianVariant::Jis04;
+            break;
+        case CSSValueSimplified:
+            variant = FontVariantEastAsianVariant::Simplified;
+            break;
+        case CSSValueTraditional:
+            variant = FontVariantEastAsianVariant::Traditional;
+            break;
+        case CSSValueFullWidth:
+            width = FontVariantEastAsianWidth::Full;
+            break;
+        case CSSValueProportionalWidth:
+            width = FontVariantEastAsianWidth::Proportional;
+            break;
+        case CSSValueRuby:
+            ruby = FontVariantEastAsianRuby::Yes;
+            break;
+        default:
+            if (unknownIsFailure)
+                return false;
+            continue;
+        }
+    }
+
+    switch (variant) {
+    case FontVariantEastAsianVariant::Normal:
+        break;
+    case FontVariantEastAsianVariant::Jis78:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78));
+        break;
+    case FontVariantEastAsianVariant::Jis83:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83));
+        break;
+    case FontVariantEastAsianVariant::Jis90:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90));
+        break;
+    case FontVariantEastAsianVariant::Jis04:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04));
+        break;
+    case FontVariantEastAsianVariant::Simplified:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified));
+        break;
+    case FontVariantEastAsianVariant::Traditional:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional));
+        break;
+    }
+
+    switch (width) {
+    case FontVariantEastAsianWidth::Normal:
+        break;
+    case FontVariantEastAsianWidth::Full:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth));
+        break;
+    case FontVariantEastAsianWidth::Proportional:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth));
+        break;
+    }
+
+    switch (ruby) {
+    case FontVariantEastAsianRuby::Normal:
+        break;
+    case FontVariantEastAsianRuby::Yes:
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby));
+    }
+
+    if (!values-&gt;length())
+        return !unknownIsFailure;
+
+    addProperty(CSSPropertyFontVariantEastAsian, WTFMove(values), important, implicit);
+    return true;
+}
+
+bool CSSParser::parseFontVariant(bool important)
+{
+    ShorthandScope scope(this, CSSPropertyFontVariant);
+    if (!parseFontVariantLigatures(important, false, false))
+        return false;
+    m_valueList-&gt;setCurrentIndex(0);
+    if (!parseFontVariantNumeric(important, false, false))
+        return false;
+    m_valueList-&gt;setCurrentIndex(0);
+    if (!parseFontVariantEastAsian(important, false, false))
+        return false;
+    m_valueList-&gt;setCurrentIndex(0);
+
+    FontVariantPosition position = FontVariantPosition::Normal;
+    FontVariantCaps caps = FontVariantCaps::Normal;
+    FontVariantAlternates alternates = FontVariantAlternates::Normal;
+
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+            return false;
+
+        switch (value-&gt;id) {
+        case CSSValueNoCommonLigatures:
+        case CSSValueCommonLigatures:
+        case CSSValueNoDiscretionaryLigatures:
+        case CSSValueDiscretionaryLigatures:
+        case CSSValueNoHistoricalLigatures:
+        case CSSValueHistoricalLigatures:
+        case CSSValueContextual:
+        case CSSValueNoContextual:
+        case CSSValueLiningNums:
+        case CSSValueOldstyleNums:
+        case CSSValueProportionalNums:
+        case CSSValueTabularNums:
+        case CSSValueDiagonalFractions:
+        case CSSValueStackedFractions:
+        case CSSValueOrdinal:
+        case CSSValueSlashedZero:
+        case CSSValueJis78:
+        case CSSValueJis83:
+        case CSSValueJis90:
+        case CSSValueJis04:
+        case CSSValueSimplified:
+        case CSSValueTraditional:
+        case CSSValueFullWidth:
+        case CSSValueProportionalWidth:
+        case CSSValueRuby:
+            break;
+        case CSSValueSub:
+            position = FontVariantPosition::Subscript;
+            break;
+        case CSSValueSuper:
+            position = FontVariantPosition::Superscript;
+            break;
+        case CSSValueSmallCaps:
+            caps = FontVariantCaps::Small;
+            break;
+        case CSSValueAllSmallCaps:
+            caps = FontVariantCaps::AllSmall;
+            break;
+        case CSSValuePetiteCaps:
+            caps = FontVariantCaps::Petite;
+            break;
+        case CSSValueAllPetiteCaps:
+            caps = FontVariantCaps::AllPetite;
+            break;
+        case CSSValueUnicase:
+            caps = FontVariantCaps::Unicase;
+            break;
+        case CSSValueTitlingCaps:
+            caps = FontVariantCaps::Titling;
+            break;
+        case CSSValueHistoricalForms:
+            alternates = FontVariantAlternates::HistoricalForms;
+            break;
+        default:
+            return false;
+        }
+    }
+
+    switch (position) {
+    case FontVariantPosition::Normal:
+        break;
+    case FontVariantPosition::Subscript:
+        addProperty(CSSPropertyFontVariantPosition, CSSValuePool::singleton().createIdentifierValue(CSSValueSub), important, false);
+        break;
+    case FontVariantPosition::Superscript:
+        addProperty(CSSPropertyFontVariantPosition, CSSValuePool::singleton().createIdentifierValue(CSSValueSuper), important, false);
+        break;
+    }
+
+    switch (caps) {
+    case FontVariantCaps::Normal:
+        break;
+    case FontVariantCaps::Small:
+        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps), important, false);
+        break;
+    case FontVariantCaps::AllSmall:
+        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps), important, false);
+        break;
+    case FontVariantCaps::Petite:
+        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps), important, false);
+        break;
+    case FontVariantCaps::AllPetite:
+        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps), important, false);
+        break;
+    case FontVariantCaps::Unicase:
+        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase), important, false);
+        break;
+    case FontVariantCaps::Titling:
+        addProperty(CSSPropertyFontVariantCaps, CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps), important, false);
+        break;
+    }
+
+    switch (alternates) {
+    case FontVariantAlternates::Normal:
+        break;
+    case FontVariantAlternates::HistoricalForms:
+        addProperty(CSSPropertyFontVariantAlternates, CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms), important, false);
+        break;
+    }
+
+    return true;
+}
+
+static inline bool isValidWillChangeAnimatableFeature(const CSSParserValue&amp; value)
+{
+    if (value.id == CSSValueNone || value.id == CSSValueAuto || value.id == CSSValueAll)
+        return false;
+
+    if (valueIsCSSKeyword(value))
+        return false;
+
+    if (cssPropertyID(value.string) == CSSPropertyWillChange)
+        return false;
+
+    return true;
+}
+
+bool CSSParser::parseWillChange(bool important)
+{
+    auto willChangePropertyValues = CSSValueList::createCommaSeparated();
+
+    bool expectComma = false;
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (expectComma) {
+            if (!isComma(value))
+                return false;
+            
+            expectComma = false;
+            continue;
+        }
+
+        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+            return false;
+
+        if (!isValidWillChangeAnimatableFeature(*value))
+            return false;
+
+        RefPtr&lt;CSSValue&gt; cssValue;
+        if (value-&gt;id == CSSValueScrollPosition || value-&gt;id == CSSValueContents)
+            cssValue = CSSValuePool::singleton().createIdentifierValue(value-&gt;id);
+        else {
+            CSSPropertyID propertyID = cssPropertyID(value-&gt;string);
+            if (propertyID != CSSPropertyInvalid)
+                cssValue = CSSValuePool::singleton().createIdentifierValue(propertyID);
+            else // This might be a property we don't support.
+                cssValue = createPrimitiveStringValue(*value);
+        }
+
+        willChangePropertyValues-&gt;append(cssValue.releaseNonNull());
+        expectComma = true;
+    }
+
+    addProperty(CSSPropertyWillChange, WTFMove(willChangePropertyValues), important);
+    return true;
+}
+
+RefPtr&lt;CSSCalcValue&gt; CSSParser::parseCalculation(CSSParserValue&amp; value, CalculationPermittedValueRange range)
+{
+    ASSERT(isCalculation(value));
+    
+    CSSParserValueList* args = value.function-&gt;args.get();
+    if (!args || !args-&gt;size())
+        return nullptr;
+
+    return CSSCalcValue::create(value.function-&gt;name, *args, range);
+}
+
+#define END_TOKEN 0
+
+#include &quot;CSSGrammar.h&quot;
+
+enum CharacterType {
+    // Types for the main switch.
+
+    // The first 4 types must be grouped together, as they
+    // represent the allowed chars in an identifier.
+    CharacterCaselessU,
+    CharacterIdentifierStart,
+    CharacterNumber,
+    CharacterDash,
+
+    CharacterOther,
+    CharacterNull,
+    CharacterWhiteSpace,
+    CharacterEndConditionQuery,
+    CharacterEndNthChild,
+    CharacterQuote,
+    CharacterExclamationMark,
+    CharacterHashmark,
+    CharacterDollar,
+    CharacterAsterisk,
+    CharacterPlus,
+    CharacterDot,
+    CharacterSlash,
+    CharacterLess,
+    CharacterAt,
+    CharacterBackSlash,
+    CharacterXor,
+    CharacterVerticalBar,
+    CharacterTilde,
+};
+
+// 128 ASCII codes
+static const CharacterType typesOfASCIICharacters[128] = {
+/*   0 - Null               */ CharacterNull,
+/*   1 - Start of Heading   */ CharacterOther,
+/*   2 - Start of Text      */ CharacterOther,
+/*   3 - End of Text        */ CharacterOther,
+/*   4 - End of Transm.     */ CharacterOther,
+/*   5 - Enquiry            */ CharacterOther,
+/*   6 - Acknowledgment     */ CharacterOther,
+/*   7 - Bell               */ CharacterOther,
+/*   8 - Back Space         */ CharacterOther,
+/*   9 - Horizontal Tab     */ CharacterWhiteSpace,
+/*  10 - Line Feed          */ CharacterWhiteSpace,
+/*  11 - Vertical Tab       */ CharacterOther,
+/*  12 - Form Feed          */ CharacterWhiteSpace,
+/*  13 - Carriage Return    */ CharacterWhiteSpace,
+/*  14 - Shift Out          */ CharacterOther,
+/*  15 - Shift In           */ CharacterOther,
+/*  16 - Data Line Escape   */ CharacterOther,
+/*  17 - Device Control 1   */ CharacterOther,
+/*  18 - Device Control 2   */ CharacterOther,
+/*  19 - Device Control 3   */ CharacterOther,
+/*  20 - Device Control 4   */ CharacterOther,
+/*  21 - Negative Ack.      */ CharacterOther,
+/*  22 - Synchronous Idle   */ CharacterOther,
+/*  23 - End of Transmit    */ CharacterOther,
+/*  24 - Cancel             */ CharacterOther,
+/*  25 - End of Medium      */ CharacterOther,
+/*  26 - Substitute         */ CharacterOther,
+/*  27 - Escape             */ CharacterOther,
+/*  28 - File Separator     */ CharacterOther,
+/*  29 - Group Separator    */ CharacterOther,
+/*  30 - Record Separator   */ CharacterOther,
+/*  31 - Unit Separator     */ CharacterOther,
+/*  32 - Space              */ CharacterWhiteSpace,
+/*  33 - !                  */ CharacterExclamationMark,
+/*  34 - &quot;                  */ CharacterQuote,
+/*  35 - #                  */ CharacterHashmark,
+/*  36 - $                  */ CharacterDollar,
+/*  37 - %                  */ CharacterOther,
+/*  38 - &amp;                  */ CharacterOther,
+/*  39 - '                  */ CharacterQuote,
+/*  40 - (                  */ CharacterOther,
+/*  41 - )                  */ CharacterEndNthChild,
+/*  42 - *                  */ CharacterAsterisk,
+/*  43 - +                  */ CharacterPlus,
+/*  44 - ,                  */ CharacterOther,
+/*  45 - -                  */ CharacterDash,
+/*  46 - .                  */ CharacterDot,
+/*  47 - /                  */ CharacterSlash,
+/*  48 - 0                  */ CharacterNumber,
+/*  49 - 1                  */ CharacterNumber,
+/*  50 - 2                  */ CharacterNumber,
+/*  51 - 3                  */ CharacterNumber,
+/*  52 - 4                  */ CharacterNumber,
+/*  53 - 5                  */ CharacterNumber,
+/*  54 - 6                  */ CharacterNumber,
+/*  55 - 7                  */ CharacterNumber,
+/*  56 - 8                  */ CharacterNumber,
+/*  57 - 9                  */ CharacterNumber,
+/*  58 - :                  */ CharacterOther,
+/*  59 - ;                  */ CharacterEndConditionQuery,
+/*  60 - &lt;                  */ CharacterLess,
+/*  61 - =                  */ CharacterOther,
+/*  62 - &gt;                  */ CharacterOther,
+/*  63 - ?                  */ CharacterOther,
+/*  64 - @                  */ CharacterAt,
+/*  65 - A                  */ CharacterIdentifierStart,
+/*  66 - B                  */ CharacterIdentifierStart,
+/*  67 - C                  */ CharacterIdentifierStart,
+/*  68 - D                  */ CharacterIdentifierStart,
+/*  69 - E                  */ CharacterIdentifierStart,
+/*  70 - F                  */ CharacterIdentifierStart,
+/*  71 - G                  */ CharacterIdentifierStart,
+/*  72 - H                  */ CharacterIdentifierStart,
+/*  73 - I                  */ CharacterIdentifierStart,
+/*  74 - J                  */ CharacterIdentifierStart,
+/*  75 - K                  */ CharacterIdentifierStart,
+/*  76 - L                  */ CharacterIdentifierStart,
+/*  77 - M                  */ CharacterIdentifierStart,
+/*  78 - N                  */ CharacterIdentifierStart,
+/*  79 - O                  */ CharacterIdentifierStart,
+/*  80 - P                  */ CharacterIdentifierStart,
+/*  81 - Q                  */ CharacterIdentifierStart,
+/*  82 - R                  */ CharacterIdentifierStart,
+/*  83 - S                  */ CharacterIdentifierStart,
+/*  84 - T                  */ CharacterIdentifierStart,
+/*  85 - U                  */ CharacterCaselessU,
+/*  86 - V                  */ CharacterIdentifierStart,
+/*  87 - W                  */ CharacterIdentifierStart,
+/*  88 - X                  */ CharacterIdentifierStart,
+/*  89 - Y                  */ CharacterIdentifierStart,
+/*  90 - Z                  */ CharacterIdentifierStart,
+/*  91 - [                  */ CharacterOther,
+/*  92 - \                  */ CharacterBackSlash,
+/*  93 - ]                  */ CharacterOther,
+/*  94 - ^                  */ CharacterXor,
+/*  95 - _                  */ CharacterIdentifierStart,
+/*  96 - `                  */ CharacterOther,
+/*  97 - a                  */ CharacterIdentifierStart,
+/*  98 - b                  */ CharacterIdentifierStart,
+/*  99 - c                  */ CharacterIdentifierStart,
+/* 100 - d                  */ CharacterIdentifierStart,
+/* 101 - e                  */ CharacterIdentifierStart,
+/* 102 - f                  */ CharacterIdentifierStart,
+/* 103 - g                  */ CharacterIdentifierStart,
+/* 104 - h                  */ CharacterIdentifierStart,
+/* 105 - i                  */ CharacterIdentifierStart,
+/* 106 - j                  */ CharacterIdentifierStart,
+/* 107 - k                  */ CharacterIdentifierStart,
+/* 108 - l                  */ CharacterIdentifierStart,
+/* 109 - m                  */ CharacterIdentifierStart,
+/* 110 - n                  */ CharacterIdentifierStart,
+/* 111 - o                  */ CharacterIdentifierStart,
+/* 112 - p                  */ CharacterIdentifierStart,
+/* 113 - q                  */ CharacterIdentifierStart,
+/* 114 - r                  */ CharacterIdentifierStart,
+/* 115 - s                  */ CharacterIdentifierStart,
+/* 116 - t                  */ CharacterIdentifierStart,
+/* 117 - u                  */ CharacterCaselessU,
+/* 118 - v                  */ CharacterIdentifierStart,
+/* 119 - w                  */ CharacterIdentifierStart,
+/* 120 - x                  */ CharacterIdentifierStart,
+/* 121 - y                  */ CharacterIdentifierStart,
+/* 122 - z                  */ CharacterIdentifierStart,
+/* 123 - {                  */ CharacterEndConditionQuery,
+/* 124 - |                  */ CharacterVerticalBar,
+/* 125 - }                  */ CharacterOther,
+/* 126 - ~                  */ CharacterTilde,
+/* 127 - Delete             */ CharacterOther,
+};
+
+// Utility functions for the CSS tokenizer.
+
+template &lt;typename CharacterType&gt;
+static inline bool isCSSLetter(CharacterType character)
+{
+    return character &gt;= 128 || typesOfASCIICharacters[character] &lt;= CharacterDash;
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool isCSSEscape(CharacterType character)
+{
+    return character &gt;= ' ' &amp;&amp; character != 127;
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool isURILetter(CharacterType character)
+{
+    return (character &gt;= '*' &amp;&amp; character != 127) || (character &gt;= '#' &amp;&amp; character &lt;= '&amp;') || character == '!';
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool isIdentifierStartAfterDash(CharacterType* currentCharacter)
+{
+    return isASCIIAlpha(currentCharacter[0]) || currentCharacter[0] == '_' || currentCharacter[0] &gt;= 128
+        || (currentCharacter[0] == '\\' &amp;&amp; isCSSEscape(currentCharacter[1]));
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool isCustomPropertyIdentifier(CharacterType* currentCharacter)
+{
+    return isASCIIAlpha(currentCharacter[0]) || currentCharacter[0] == '_' || currentCharacter[0] &gt;= 128
+        || (currentCharacter[0] == '\\' &amp;&amp; isCSSEscape(currentCharacter[1]));
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool isEqualToCSSIdentifier(CharacterType* cssString, const char* constantString)
+{
+    // Compare an character memory data with a zero terminated string.
+    do {
+        // The input must be part of an identifier if constantChar or constString
+        // contains '-'. Otherwise toASCIILowerUnchecked('\r') would be equal to '-'.
+        ASSERT((*constantString &gt;= 'a' &amp;&amp; *constantString &lt;= 'z') || *constantString == '-');
+        ASSERT(*constantString != '-' || isCSSLetter(*cssString));
+        if (toASCIILowerUnchecked(*cssString++) != (*constantString++))
+            return false;
+    } while (*constantString);
+    return true;
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool isEqualToCSSCaseSensitiveIdentifier(CharacterType* string, const char* constantString)
+{
+    do {
+        if (*string++ != *constantString++)
+            return false;
+    } while (*constantString);
+    return true;
+}
+
+template &lt;typename CharacterType&gt;
+static CharacterType* checkAndSkipEscape(CharacterType* currentCharacter)
+{
+    // Returns with 0, if escape check is failed. Otherwise
+    // it returns with the following character.
+    ASSERT(*currentCharacter == '\\');
+
+    ++currentCharacter;
+    if (!isCSSEscape(*currentCharacter))
+        return nullptr;
+
+    if (isASCIIHexDigit(*currentCharacter)) {
+        int length = 6;
+
+        do {
+            ++currentCharacter;
+        } while (isASCIIHexDigit(*currentCharacter) &amp;&amp; --length);
+
+        // Optional space after the escape sequence.
+        if (isHTMLSpace(*currentCharacter))
+            ++currentCharacter;
+        return currentCharacter;
+    }
+    return currentCharacter + 1;
+}
+
+template &lt;typename CharacterType&gt;
+static inline CharacterType* skipWhiteSpace(CharacterType* currentCharacter)
+{
+    while (isHTMLSpace(*currentCharacter))
+        ++currentCharacter;
+    return currentCharacter;
+}
+
+// Main CSS tokenizer functions.
+
+template &lt;&gt;
+LChar* CSSParserString::characters&lt;LChar&gt;() const { return characters8(); }
+
+template &lt;&gt;
+UChar* CSSParserString::characters&lt;UChar&gt;() const { return characters16(); }
+
+template &lt;&gt;
+inline LChar*&amp; CSSParser::currentCharacter&lt;LChar&gt;()
+{
+    return m_currentCharacter8;
+}
+
+template &lt;&gt;
+inline UChar*&amp; CSSParser::currentCharacter&lt;UChar&gt;()
+{
+    return m_currentCharacter16;
+}
+
+UChar*&amp; CSSParser::currentCharacter16()
+{
+    if (!m_currentCharacter16) {
+        m_dataStart16 = std::make_unique&lt;UChar[]&gt;(m_length);
+        m_currentCharacter16 = m_dataStart16.get();
+    }
+
+    return m_currentCharacter16;
+}
+
+template &lt;&gt;
+inline LChar* CSSParser::tokenStart&lt;LChar&gt;()
+{
+    return m_tokenStart.ptr8;
+}
+
+template &lt;&gt;
+inline UChar* CSSParser::tokenStart&lt;UChar&gt;()
+{
+    return m_tokenStart.ptr16;
+}
+
+CSSParser::Location CSSParser::currentLocation()
+{
+    Location location;
+    location.lineNumber = m_tokenStartLineNumber;
+    location.columnNumber = m_tokenStartColumnNumber;
+
+    ASSERT(location.lineNumber &gt;= 0);
+    ASSERT(location.columnNumber &gt;= 0);
+
+    if (location.lineNumber == m_sheetStartLineNumber)
+        location.columnNumber += m_sheetStartColumnNumber;
+
+    if (is8BitSource())
+        location.token.init(tokenStart&lt;LChar&gt;(), currentCharacter&lt;LChar&gt;() - tokenStart&lt;LChar&gt;());
+    else
+        location.token.init(tokenStart&lt;UChar&gt;(), currentCharacter&lt;UChar&gt;() - tokenStart&lt;UChar&gt;());
+
+    return location;
+}
+
+template &lt;typename CharacterType&gt;
+inline bool CSSParser::isIdentifierStart()
+{
+    // Check whether an identifier is started.
+    return isIdentifierStartAfterDash((*currentCharacter&lt;CharacterType&gt;() != '-') ? currentCharacter&lt;CharacterType&gt;() : currentCharacter&lt;CharacterType&gt;() + 1);
+}
+
+template &lt;typename CharacterType&gt;
+static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, int quote)
+{
+    // Returns with 0, if string check is failed. Otherwise
+    // it returns with the following character. This is necessary
+    // since we cannot revert escape sequences, thus strings
+    // must be validated before parsing.
+    while (true) {
+        if (UNLIKELY(*currentCharacter == quote)) {
+            // String parsing is successful.
+            return currentCharacter + 1;
+        }
+        if (UNLIKELY(!*currentCharacter)) {
+            // String parsing is successful up to end of input.
+            return currentCharacter;
+        }
+        if (UNLIKELY(*currentCharacter &lt;= '\r' &amp;&amp; (*currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) {
+            // String parsing is failed for character '\n', '\f' or '\r'.
+            return nullptr;
+        }
+
+        if (LIKELY(currentCharacter[0] != '\\'))
+            ++currentCharacter;
+        else if (currentCharacter[1] == '\n' || currentCharacter[1] == '\f')
+            currentCharacter += 2;
+        else if (currentCharacter[1] == '\r')
+            currentCharacter += currentCharacter[2] == '\n' ? 3 : 2;
+        else {
+            currentCharacter = checkAndSkipEscape(currentCharacter);
+            if (!currentCharacter)
+                return nullptr;
+        }
+    }
+}
+
+template &lt;typename CharacterType&gt;
+unsigned CSSParser::parseEscape(CharacterType*&amp; src)
+{
+    ASSERT(*src == '\\' &amp;&amp; isCSSEscape(src[1]));
+
+    unsigned unicode = 0;
+
+    ++src;
+    if (isASCIIHexDigit(*src)) {
+
+        int length = 6;
+
+        do {
+            unicode = (unicode &lt;&lt; 4) + toASCIIHexValue(*src++);
+        } while (--length &amp;&amp; isASCIIHexDigit(*src));
+
+        if (unicode &gt; UCHAR_MAX_VALUE)
+            unicode = replacementCharacter;
+
+        // Optional space after the escape sequence.
+        if (isHTMLSpace(*src))
+            ++src;
+
+        return unicode;
+    }
+
+    return *currentCharacter&lt;CharacterType&gt;()++;
+}
+
+template &lt;&gt;
+inline void CSSParser::UnicodeToChars&lt;LChar&gt;(LChar*&amp; result, unsigned unicode)
+{
+    ASSERT(unicode &lt;= 0xff);
+    *result = unicode;
+
+    ++result;
+}
+
+template &lt;&gt;
+inline void CSSParser::UnicodeToChars&lt;UChar&gt;(UChar*&amp; result, unsigned unicode)
+{
+    // Replace unicode with a surrogate pairs when it is bigger than 0xffff
+    if (U16_LENGTH(unicode) == 2) {
+        *result++ = U16_LEAD(unicode);
+        *result = U16_TRAIL(unicode);
+    } else
+        *result = unicode;
+
+    ++result;
+}
+
+template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
+inline bool CSSParser::parseIdentifierInternal(SrcCharacterType*&amp; src, DestCharacterType*&amp; result, bool&amp; hasEscape)
+{
+    hasEscape = false;
+    do {
+        if (LIKELY(*src != '\\'))
+            *result++ = *src++;
+        else {
+            hasEscape = true;
+            SrcCharacterType* savedEscapeStart = src;
+            unsigned unicode = parseEscape&lt;SrcCharacterType&gt;(src);
+            if (unicode &gt; 0xff &amp;&amp; sizeof(DestCharacterType) == 1) {
+                src = savedEscapeStart;
+                return false;
+            }
+            UnicodeToChars(result, unicode);
+        }
+    } while (isCSSLetter(src[0]) || (src[0] == '\\' &amp;&amp; isCSSEscape(src[1])));
+
+    return true;
+}
+
+template &lt;typename CharacterType&gt;
+inline void CSSParser::parseIdentifier(CharacterType*&amp; result, CSSParserString&amp; resultString, bool&amp; hasEscape)
+{
+    CharacterType* start = currentCharacter&lt;CharacterType&gt;();
+    if (UNLIKELY(!parseIdentifierInternal(currentCharacter&lt;CharacterType&gt;(), result, hasEscape))) {
+        // Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
+        ASSERT(is8BitSource());
+        UChar*&amp; result16 = currentCharacter16();
+        UChar* start16 = result16;
+        int i = 0;
+        for (; i &lt; result - start; ++i)
+            result16[i] = start[i];
+
+        result16 += i;
+
+        parseIdentifierInternal(currentCharacter&lt;CharacterType&gt;(), result16, hasEscape);
+
+        result += result16 - start16;
+        resultString.init(start16, result16 - start16);
+
+        return;
+    }
+
+    resultString.init(start, result - start);
+}
+
+template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
+inline bool CSSParser::parseStringInternal(SrcCharacterType*&amp; src, DestCharacterType*&amp; result, UChar quote)
+{
+    while (true) {
+        if (UNLIKELY(*src == quote)) {
+            // String parsing is done.
+            ++src;
+            return true;
+        }
+        if (UNLIKELY(!*src)) {
+            // String parsing is done, but don't advance pointer if at the end of input.
+            return true;
+        }
+        ASSERT(*src &gt; '\r' || (*src &lt; '\n' &amp;&amp; *src) || *src == '\v');
+
+        if (LIKELY(src[0] != '\\'))
+            *result++ = *src++;
+        else if (src[1] == '\n' || src[1] == '\f')
+            src += 2;
+        else if (src[1] == '\r')
+            src += src[2] == '\n' ? 3 : 2;
+        else {
+            SrcCharacterType* savedEscapeStart = src;
+            unsigned unicode = parseEscape&lt;SrcCharacterType&gt;(src);
+            if (unicode &gt; 0xff &amp;&amp; sizeof(DestCharacterType) == 1) {
+                src = savedEscapeStart;
+                return false;
+            }
+            UnicodeToChars(result, unicode);
+        }
+    }
+
+    return true;
+}
+
+template &lt;typename CharacterType&gt;
+inline void CSSParser::parseString(CharacterType*&amp; result, CSSParserString&amp; resultString, UChar quote)
+{
+    CharacterType* start = currentCharacter&lt;CharacterType&gt;();
+
+    if (UNLIKELY(!parseStringInternal(currentCharacter&lt;CharacterType&gt;(), result, quote))) {
+        // Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
+        ASSERT(is8BitSource());
+        UChar*&amp; result16 = currentCharacter16();
+        UChar* start16 = result16;
+        int i = 0;
+        for (; i &lt; result - start; ++i)
+            result16[i] = start[i];
+
+        result16 += i;
+
+        parseStringInternal(currentCharacter&lt;CharacterType&gt;(), result16, quote);
+
+        resultString.init(start16, result16 - start16);
+        return;
+    }
+
+    resultString.init(start, result - start);
+}
+
+template &lt;typename CharacterType&gt;
+inline bool CSSParser::findURI(CharacterType*&amp; start, CharacterType*&amp; end, UChar&amp; quote)
+{
+    start = skipWhiteSpace(currentCharacter&lt;CharacterType&gt;());
+    
+    if (*start == '&quot;' || *start == '\'') {
+        quote = *start++;
+        end = checkAndSkipString(start, quote);
+        if (!end)
+            return false;
+    } else {
+        quote = 0;
+        end = start;
+        while (isURILetter(*end)) {
+            if (LIKELY(*end != '\\'))
+                ++end;
+            else {
+                end = checkAndSkipEscape(end);
+                if (!end)
+                    return false;
+            }
+        }
+    }
+
+    end = skipWhiteSpace(end);
+    if (*end != ')')
+        return false;
+    
+    return true;
+}
+
+template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
+inline bool CSSParser::parseURIInternal(SrcCharacterType*&amp; src, DestCharacterType*&amp; dest, UChar quote)
+{
+    if (quote) {
+        ASSERT(quote == '&quot;' || quote == '\'');
+        return parseStringInternal(src, dest, quote);
+    }
+    
+    while (isURILetter(*src)) {
+        if (LIKELY(*src != '\\'))
+            *dest++ = *src++;
+        else {
+            unsigned unicode = parseEscape&lt;SrcCharacterType&gt;(src);
+            if (unicode &gt; 0xff &amp;&amp; sizeof(SrcCharacterType) == 1)
+                return false;
+            UnicodeToChars(dest, unicode);
+        }
+    }
+
+    return true;
+}
+
+template &lt;typename CharacterType&gt;
+inline void CSSParser::parseURI(CSSParserString&amp; string)
+{
+    CharacterType* uriStart;
+    CharacterType* uriEnd;
+    UChar quote;
+    if (!findURI(uriStart, uriEnd, quote))
+        return;
+    
+    CharacterType* dest = currentCharacter&lt;CharacterType&gt;() = uriStart;
+    if (LIKELY(parseURIInternal(currentCharacter&lt;CharacterType&gt;(), dest, quote)))
+        string.init(uriStart, dest - uriStart);
+    else {
+        // An escape sequence was encountered that can't be stored in 8 bits.
+        // Reset the current character to the start of the URI and re-parse with
+        // a 16-bit destination.
+        ASSERT(is8BitSource());
+        UChar* uriStart16 = currentCharacter16();
+        currentCharacter&lt;CharacterType&gt;() = uriStart;
+        bool result = parseURIInternal(currentCharacter&lt;CharacterType&gt;(), currentCharacter16(), quote);
+        ASSERT_UNUSED(result, result);
+        string.init(uriStart16, currentCharacter16() - uriStart16);
+    }
+
+    currentCharacter&lt;CharacterType&gt;() = uriEnd + 1;
+    m_token = URI;
+}
+
+template &lt;typename CharacterType&gt;
+inline bool CSSParser::parseUnicodeRange()
+{
+    CharacterType* character = currentCharacter&lt;CharacterType&gt;() + 1;
+    int length = 6;
+    ASSERT(*currentCharacter&lt;CharacterType&gt;() == '+');
+
+    while (isASCIIHexDigit(*character) &amp;&amp; length) {
+        ++character;
+        --length;
+    }
+
+    if (length &amp;&amp; *character == '?') {
+        // At most 5 hex digit followed by a question mark.
+        do {
+            ++character;
+            --length;
+        } while (*character == '?' &amp;&amp; length);
+        currentCharacter&lt;CharacterType&gt;() = character;
+        return true;
+    }
+
+    if (length &lt; 6) {
+        // At least one hex digit.
+        if (character[0] == '-' &amp;&amp; isASCIIHexDigit(character[1])) {
+            // Followed by a dash and a hex digit.
+            ++character;
+            length = 6;
+            do {
+                ++character;
+            } while (--length &amp;&amp; isASCIIHexDigit(*character));
+        }
+        currentCharacter&lt;CharacterType&gt;() = character;
+        return true;
+    }
+    return false;
+}
+
+template &lt;typename CharacterType&gt;
+bool CSSParser::parseNthChild()
+{
+    CharacterType* character = currentCharacter&lt;CharacterType&gt;();
+
+    while (isASCIIDigit(*character))
+        ++character;
+    if (isASCIIAlphaCaselessEqual(*character, 'n')) {
+        currentCharacter&lt;CharacterType&gt;() = character + 1;
+        return true;
+    }
+    return false;
+}
+
+template &lt;typename CharacterType&gt;
+bool CSSParser::parseNthChildExtra()
+{
+    CharacterType* character = skipWhiteSpace(currentCharacter&lt;CharacterType&gt;());
+    if (*character != '+' &amp;&amp; *character != '-')
+        return false;
+
+    character = skipWhiteSpace(character + 1);
+    if (!isASCIIDigit(*character))
+        return false;
+
+    do {
+        ++character;
+    } while (isASCIIDigit(*character));
+
+    currentCharacter&lt;CharacterType&gt;() = character;
+    return true;
+}
+
+template &lt;typename CharacterType&gt;
+inline bool CSSParser::detectFunctionTypeToken(int length)
+{
+    ASSERT(length &gt; 0);
+    CharacterType* name = tokenStart&lt;CharacterType&gt;();
+
+    switch (length) {
+    case 3:
+        if (isASCIIAlphaCaselessEqual(name[0], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 't')) {
+            m_token = NOTFUNCTION;
+            return true;
+        }
+        if (isASCIIAlphaCaselessEqual(name[0], 'u') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'r') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'l')) {
+            m_token = URI;
+            return true;
+        }
+        if (isASCIIAlphaCaselessEqual(name[0], 'v') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'r')) {
+            m_token = VARFUNCTION;
+            return true;
+        }
+#if ENABLE(VIDEO_TRACK)
+        if (isASCIIAlphaCaselessEqual(name[0], 'c') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'u') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'e')) {
+            m_token = CUEFUNCTION;
+            return true;
+        }
+#endif
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+        if (isASCIIAlphaCaselessEqual(name[0], 'd') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'i') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'r')) {
+            m_token = DIRFUNCTION;
+            return true;
+        }
+#endif
+        return false;
+
+    case 4:
+        if (isEqualToCSSIdentifier(name, &quot;calc&quot;)) {
+            m_token = CALCFUNCTION;
+            return true;
+        }
+        if (isEqualToCSSIdentifier(name, &quot;lang&quot;)) {
+            m_token = LANGFUNCTION;
+            return true;
+        }
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+        if (isEqualToCSSIdentifier(name, &quot;role&quot;)) {
+            m_token = ROLEFUNCTION;
+            return true;
+        }
+#endif
+        if (isEqualToCSSIdentifier(name, &quot;host&quot;)) {
+            m_token = HOSTFUNCTION;
+            return true;
+        }
+        return false;
+
+    case 7:
+        if (isEqualToCSSIdentifier(name, &quot;matches&quot;)) {
+            m_token = MATCHESFUNCTION;
+            return true;
+        }
+        if (isEqualToCSSIdentifier(name, &quot;slotted&quot;)) {
+            m_token = SLOTTEDFUNCTION;
+            return true;
+        }
+        return false;
+
+    case 9:
+        if (isEqualToCSSIdentifier(name, &quot;nth-child&quot;)) {
+            m_token = NTHCHILDFUNCTIONS;
+            m_parsingMode = NthChildMode;
+            return true;
+        }
+        return false;
+
+    case 11:
+        if (isEqualToCSSIdentifier(name, &quot;nth-of-type&quot;)) {
+            m_parsingMode = NthChildMode;
+            return true;
+        }
+        return false;
+
+    case 14:
+        if (isEqualToCSSIdentifier(name, &quot;nth-last-child&quot;)) {
+            m_token = NTHCHILDFUNCTIONS;
+            m_parsingMode = NthChildMode;
+            return true;
+        }
+        return false;
+
+    case 16:
+        if (isEqualToCSSIdentifier(name, &quot;nth-last-of-type&quot;)) {
+            m_parsingMode = NthChildMode;
+            return true;
+        }
+        return false;
+    }
+
+    return false;
+}
+
+template &lt;typename CharacterType&gt;
+inline void CSSParser::detectMediaQueryToken(int length)
+{
+    ASSERT(m_parsingMode == MediaQueryMode);
+    CharacterType* name = tokenStart&lt;CharacterType&gt;();
+
+    if (length == 3) {
+        if (isASCIIAlphaCaselessEqual(name[0], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'd'))
+            m_token = MEDIA_AND;
+        else if (isASCIIAlphaCaselessEqual(name[0], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 't'))
+            m_token = MEDIA_NOT;
+    } else if (length == 4) {
+        if (isASCIIAlphaCaselessEqual(name[0], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'n')
+                &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'l') &amp;&amp; isASCIIAlphaCaselessEqual(name[3], 'y'))
+            m_token = MEDIA_ONLY;
+    }
+}
+
+template &lt;typename CharacterType&gt;
+inline void CSSParser::detectNumberToken(CharacterType* type, int length)
+{
+    ASSERT(length &gt; 0);
+
+    switch (toASCIILowerUnchecked(type[0])) {
+    case 'c':
+        if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'm'))
+            m_token = CMS;
+        else if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'h'))
+            m_token = CHS;
+        return;
+
+    case 'd':
+        if (length == 3 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'e') &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'g'))
+            m_token = DEGS;
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
+        else if (length &gt; 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'p')) {
+            if (length == 4) {
+                // There is a discussion about the name of this unit on www-style.
+                // Keep this compile time guard in place until that is resolved.
+                // http://lists.w3.org/Archives/Public/www-style/2012May/0915.html
+                if (isASCIIAlphaCaselessEqual(type[2], 'p') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'x'))
+                    m_token = DPPX;
+                else if (isASCIIAlphaCaselessEqual(type[2], 'c') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'm'))
+                    m_token = DPCM;
+            } else if (length == 3 &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'i'))
+                    m_token = DPI;
+        }
+#endif
+        return;
+
+    case 'e':
+        if (length == 2) {
+            if (isASCIIAlphaCaselessEqual(type[1], 'm'))
+                m_token = EMS;
+            else if (isASCIIAlphaCaselessEqual(type[1], 'x'))
+                m_token = EXS;
+        }
+        return;
+
+    case 'f':
+        if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'r'))
+            m_token = FR;
+        return;
+    case 'g':
+        if (length == 4 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'r')
+                &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'd'))
+            m_token = GRADS;
+        return;
+
+    case 'h':
+        if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'z'))
+            m_token = HERTZ;
+        return;
+
+    case 'i':
+        if (length == 2 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'n'))
+            m_token = INS;
+        return;
+
+    case 'k':
+        if (length == 3 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'h') &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'z'))
+            m_token = KHERTZ;
+        return;
+
+    case 'm':
+        if (length == 2) {
+            if (isASCIIAlphaCaselessEqual(type[1], 'm'))
+                m_token = MMS;
+            else if (isASCIIAlphaCaselessEqual(type[1], 's'))
+                m_token = MSECS;
+        }
+        return;
+
+    case 'p':
+        if (length == 2) {
+            if (isASCIIAlphaCaselessEqual(type[1], 'x'))
+                m_token = PXS;
+            else if (isASCIIAlphaCaselessEqual(type[1], 't'))
+                m_token = PTS;
+            else if (isASCIIAlphaCaselessEqual(type[1], 'c'))
+                m_token = PCS;
+        }
+        return;
+
+    case 'r':
+        if (length == 3) {
+            if (isASCIIAlphaCaselessEqual(type[1], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'd'))
+                m_token = RADS;
+            else if (isASCIIAlphaCaselessEqual(type[1], 'e') &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'm'))
+                m_token = REMS;
+        }
+        return;
+
+    case 's':
+        if (length == 1)
+            m_token = SECS;
+        return;
+
+    case 't':
+        if (length == 4 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'u')
+                &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'r') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'n'))
+            m_token = TURNS;
+        return;
+    case 'v':
+        if (length == 2) {
+            if (isASCIIAlphaCaselessEqual(type[1], 'w'))
+                m_token = VW;
+            else if (isASCIIAlphaCaselessEqual(type[1], 'h'))
+                m_token = VH;
+        } else if (length == 4 &amp;&amp; isASCIIAlphaCaselessEqual(type[1], 'm')) {
+            if (isASCIIAlphaCaselessEqual(type[2], 'i') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'n'))
+                m_token = VMIN;
+            else if (isASCIIAlphaCaselessEqual(type[2], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'x'))
+                m_token = VMAX;
+        }
+        return;
+
+    default:
+        if (type[0] == '_' &amp;&amp; length == 5 &amp;&amp; type[1] == '_' &amp;&amp; isASCIIAlphaCaselessEqual(type[2], 'q')
+                &amp;&amp; isASCIIAlphaCaselessEqual(type[3], 'e') &amp;&amp; isASCIIAlphaCaselessEqual(type[4], 'm'))
+            m_token = QEMS;
+        return;
+    }
+}
+
+template &lt;typename CharacterType&gt;
+inline void CSSParser::detectDashToken(int length)
+{
+    CharacterType* name = tokenStart&lt;CharacterType&gt;();
+
+    if (length == 11) {
+        if (isASCIIAlphaCaselessEqual(name[10], 'y') &amp;&amp; isEqualToCSSIdentifier(name + 1, &quot;webkit-an&quot;))
+            m_token = ANYFUNCTION;
+        else if (isASCIIAlphaCaselessEqual(name[10], 'n') &amp;&amp; isEqualToCSSIdentifier(name + 1, &quot;webkit-mi&quot;))
+            m_token = MINFUNCTION;
+        else if (isASCIIAlphaCaselessEqual(name[10], 'x') &amp;&amp; isEqualToCSSIdentifier(name + 1, &quot;webkit-ma&quot;))
+            m_token = MAXFUNCTION;
+    } else if (length == 12 &amp;&amp; isEqualToCSSIdentifier(name + 1, &quot;webkit-calc&quot;))
+        m_token = CALCFUNCTION;
+}
+
+template &lt;typename CharacterType&gt;
+inline void CSSParser::detectAtToken(int length, bool hasEscape)
+{
+    CharacterType* name = tokenStart&lt;CharacterType&gt;();
+    ASSERT(name[0] == '@' &amp;&amp; length &gt;= 2);
+
+    // charset, font-face, import, media, namespace, page, supports,
+    // -webkit-keyframes, and -webkit-mediaquery are not affected by hasEscape.
+    switch (toASCIILowerUnchecked(name[1])) {
+    case 'b':
+        if (hasEscape)
+            return;
+
+        switch (length) {
+        case 12:
+            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-left&quot;))
+                m_token = BOTTOMLEFT_SYM;
+            return;
+
+        case 13:
+            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-right&quot;))
+                m_token = BOTTOMRIGHT_SYM;
+            return;
+
+        case 14:
+            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-center&quot;))
+                m_token = BOTTOMCENTER_SYM;
+            return;
+
+        case 19:
+            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-left-corner&quot;))
+                m_token = BOTTOMLEFTCORNER_SYM;
+            return;
+
+        case 20:
+            if (isEqualToCSSIdentifier(name + 2, &quot;ottom-right-corner&quot;))
+                m_token = BOTTOMRIGHTCORNER_SYM;
+            return;
+        }
+        return;
+
+    case 'c':
+        if (length == 8 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;harset&quot;))
+            m_token = CHARSET_SYM;
+        return;
+
+    case 'f':
+        if (length == 10 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;ont-face&quot;))
+            m_token = FONT_FACE_SYM;
+        return;
+
+    case 'i':
+        if (length == 7 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;mport&quot;)) {
+            m_parsingMode = MediaQueryMode;
+            m_token = IMPORT_SYM;
+        }
+        return;
+
+    case 'k':
+        if (length == 10 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;eyframes&quot;))
+            m_token = KEYFRAMES_SYM;
+        else if (length == 14 &amp;&amp; !hasEscape &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;eyframe-rule&quot;))
+            m_token = KEYFRAME_RULE_SYM;
+        return;
+
+    case 'l':
+        if (hasEscape)
+            return;
+
+        if (length == 9) {
+            if (isEqualToCSSIdentifier(name + 2, &quot;eft-top&quot;))
+                m_token = LEFTTOP_SYM;
+        } else if (length == 12) {
+            // Checking the last character first could further reduce the possibile cases.
+            if (isASCIIAlphaCaselessEqual(name[11], 'e') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;eft-middl&quot;))
+                m_token = LEFTMIDDLE_SYM;
+            else if (isASCIIAlphaCaselessEqual(name[11], 'm') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;eft-botto&quot;))
+                m_token = LEFTBOTTOM_SYM;
+        }
+        return;
+
+    case 'm':
+        if (length == 6 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;edia&quot;)) {
+            m_parsingMode = MediaQueryMode;
+            m_token = MEDIA_SYM;
+        }
+        return;
+
+    case 'n':
+        if (length == 10 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;amespace&quot;))
+            m_token = NAMESPACE_SYM;
+        return;
+
+    case 'p':
+        if (length == 5 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;age&quot;))
+            m_token = PAGE_SYM;
+        return;
+
+    case 'r':
+        if (hasEscape)
+            return;
+
+        if (length == 10) {
+            if (isEqualToCSSIdentifier(name + 2, &quot;ight-top&quot;))
+                m_token = RIGHTTOP_SYM;
+        } else if (length == 13) {
+            // Checking the last character first could further reduce the possibile cases.
+            if (isASCIIAlphaCaselessEqual(name[12], 'e') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;ight-middl&quot;))
+                m_token = RIGHTMIDDLE_SYM;
+            else if (isASCIIAlphaCaselessEqual(name[12], 'm') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;ight-botto&quot;))
+                m_token = RIGHTBOTTOM_SYM;
+        }
+        return;
+
+    case 's':
+        if (length == 9 &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;upports&quot;)) {
+            m_parsingMode = SupportsMode;
+            m_token = SUPPORTS_SYM;
+        }
+        return;
+
+    case 't':
+        if (hasEscape)
+            return;
+
+        switch (length) {
+        case 9:
+            if (isEqualToCSSIdentifier(name + 2, &quot;op-left&quot;))
+                m_token = TOPLEFT_SYM;
+            return;
+
+        case 10:
+            if (isEqualToCSSIdentifier(name + 2, &quot;op-right&quot;))
+                m_token = TOPRIGHT_SYM;
+            return;
+
+        case 11:
+            if (isEqualToCSSIdentifier(name + 2, &quot;op-center&quot;))
+                m_token = TOPCENTER_SYM;
+            return;
+
+        case 16:
+            if (isEqualToCSSIdentifier(name + 2, &quot;op-left-corner&quot;))
+                m_token = TOPLEFTCORNER_SYM;
+            return;
+
+        case 17:
+            if (isEqualToCSSIdentifier(name + 2, &quot;op-right-corner&quot;))
+                m_token = TOPRIGHTCORNER_SYM;
+            return;
+        }
+        return;
+
+    case '-':
+        switch (length) {
+        case 13:
+            if (!hasEscape &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-rule&quot;))
+                m_token = WEBKIT_RULE_SYM;
+            return;
+
+        case 14:
+            if (hasEscape)
+                return;
+
+            // Checking the last character first could further reduce the possibile cases.
+            if (isASCIIAlphaCaselessEqual(name[13], 's') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-decl&quot;))
+                m_token = WEBKIT_DECLS_SYM;
+            else if (isASCIIAlphaCaselessEqual(name[13], 'e') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-valu&quot;))
+                m_token = WEBKIT_VALUE_SYM;
+            return;
+
+        case 15:
+            if (hasEscape)
+                return;
+
+#if ENABLE(CSS_REGIONS)
+            if (isASCIIAlphaCaselessEqual(name[14], 'n') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-regio&quot;))
+                m_token = WEBKIT_REGION_RULE_SYM;
+#endif
+            return;
+
+        case 17:
+            if (hasEscape)
+                return;
+
+            if (isASCIIAlphaCaselessEqual(name[16], 'r') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-selecto&quot;))
+                m_token = WEBKIT_SELECTOR_SYM;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+            else if (isASCIIAlphaCaselessEqual(name[16], 't') &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-viewpor&quot;))
+                m_token = WEBKIT_VIEWPORT_RULE_SYM;
+#endif
+            return;
+
+        case 18:
+            if (isEqualToCSSIdentifier(name + 2, &quot;webkit-keyframes&quot;))
+                m_token = KEYFRAMES_SYM;
+            else if (isEqualToCSSIdentifier(name + 2, &quot;webkit-sizesattr&quot;))
+                m_token = WEBKIT_SIZESATTR_SYM;
+            return;
+
+        case 19:
+            if (isEqualToCSSIdentifier(name + 2, &quot;webkit-mediaquery&quot;)) {
+                m_parsingMode = MediaQueryMode;
+                m_token = WEBKIT_MEDIAQUERY_SYM;
+            }
+            return;
+
+        case 22:
+            if (!hasEscape &amp;&amp; isEqualToCSSIdentifier(name + 2, &quot;webkit-keyframe-rule&quot;))
+                m_token = KEYFRAME_RULE_SYM;
+            return;
+
+        case 27:
+            if (isEqualToCSSIdentifier(name + 2, &quot;webkit-supports-condition&quot;)) {
+                m_parsingMode = SupportsMode;
+                m_token = WEBKIT_SUPPORTS_CONDITION_SYM;
+            }
+            return;
+        }
+    }
+}
+
+template &lt;typename CharacterType&gt;
+inline void CSSParser::detectSupportsToken(int length)
+{
+    ASSERT(m_parsingMode == SupportsMode);
+    CharacterType* name = tokenStart&lt;CharacterType&gt;();
+
+    if (length == 2) {
+        if (isASCIIAlphaCaselessEqual(name[0], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'r'))
+            m_token = SUPPORTS_OR;
+    } else if (length == 3) {
+        if (isASCIIAlphaCaselessEqual(name[0], 'a') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 'd'))
+            m_token = SUPPORTS_AND;
+        else if (isASCIIAlphaCaselessEqual(name[0], 'n') &amp;&amp; isASCIIAlphaCaselessEqual(name[1], 'o') &amp;&amp; isASCIIAlphaCaselessEqual(name[2], 't'))
+            m_token = SUPPORTS_NOT;
+    }
+}
+
+template &lt;typename SrcCharacterType&gt;
+int CSSParser::realLex(void* yylvalWithoutType)
+{
+    YYSTYPE* yylval = static_cast&lt;YYSTYPE*&gt;(yylvalWithoutType);
+    // Write pointer for the next character.
+    SrcCharacterType* result;
+    CSSParserString resultString;
+    bool hasEscape;
+
+    // The input buffer is terminated by a \0 character, so
+    // it is safe to read one character ahead of a known non-null.
+#ifndef NDEBUG
+    // In debug we check with an ASSERT that the length is &gt; 0 for string types.
+    yylval-&gt;string.clear();
+#endif
+
+restartAfterComment:
+    result = currentCharacter&lt;SrcCharacterType&gt;();
+    setTokenStart(result);
+    m_tokenStartLineNumber = m_lineNumber;
+    m_tokenStartColumnNumber = tokenStartOffset() - m_columnOffsetForLine;
+    m_token = *currentCharacter&lt;SrcCharacterType&gt;();
+    ++currentCharacter&lt;SrcCharacterType&gt;();
+
+    switch ((m_token &lt;= 127) ? typesOfASCIICharacters[m_token] : CharacterIdentifierStart) {
+    case CharacterCaselessU:
+        if (UNLIKELY(*currentCharacter&lt;SrcCharacterType&gt;() == '+')) {
+            if (parseUnicodeRange&lt;SrcCharacterType&gt;()) {
+                m_token = UNICODERANGE;
+                yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
+                break;
+            }
+        }
+        FALLTHROUGH; // To CharacterIdentifierStart.
+
+    case CharacterIdentifierStart:
+        --currentCharacter&lt;SrcCharacterType&gt;();
+        parseIdentifier(result, yylval-&gt;string, hasEscape);
+        m_token = IDENT;
+
+        if (UNLIKELY(*currentCharacter&lt;SrcCharacterType&gt;() == '(')) {
+            if (m_parsingMode == SupportsMode &amp;&amp; !hasEscape) {
+                detectSupportsToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
+                if (m_token != IDENT)
+                    break;
+            }
+            m_token = FUNCTION;
+            bool shouldSkipParenthesis = true;
+            if (!hasEscape) {
+                bool detected = detectFunctionTypeToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
+                if (!detected &amp;&amp; m_parsingMode == MediaQueryMode) {
+                    // ... and(max-width: 480px) ... looks like a function, but in fact it is not,
+                    // so run more detection code in the MediaQueryMode.
+                    detectMediaQueryToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
+                    shouldSkipParenthesis = false;
+                }
+            }
+
+            if (LIKELY(shouldSkipParenthesis)) {
+                ++currentCharacter&lt;SrcCharacterType&gt;();
+                ++result;
+                ++yylval-&gt;string.m_length;
+            }
+
+            if (token() == URI) {
+                m_token = FUNCTION;
+                // Check whether it is really an URI.
+                if (yylval-&gt;string.is8Bit())
+                    parseURI&lt;LChar&gt;(yylval-&gt;string);
+                else
+                    parseURI&lt;UChar&gt;(yylval-&gt;string);
+            }
+        } else if (UNLIKELY(m_parsingMode != NormalMode) &amp;&amp; !hasEscape) {
+            if (m_parsingMode == MediaQueryMode)
+                detectMediaQueryToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
+            else if (m_parsingMode == SupportsMode)
+                detectSupportsToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
+            else if (m_parsingMode == NthChildMode &amp;&amp; isASCIIAlphaCaselessEqual(tokenStart&lt;SrcCharacterType&gt;()[0], 'n')) {
+                if (result - tokenStart&lt;SrcCharacterType&gt;() == 1) {
+                    // String &quot;n&quot; is IDENT but &quot;n+1&quot; is NTH.
+                    if (parseNthChildExtra&lt;SrcCharacterType&gt;()) {
+                        m_token = NTH;
+                        yylval-&gt;string.m_length = currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;();
+                    }
+                } else if (result - tokenStart&lt;SrcCharacterType&gt;() &gt;= 2 &amp;&amp; tokenStart&lt;SrcCharacterType&gt;()[1] == '-') {
+                    // String &quot;n-&quot; is IDENT but &quot;n-1&quot; is NTH.
+                    // Set currentCharacter to '-' to continue parsing.
+                    SrcCharacterType* nextCharacter = result;
+                    currentCharacter&lt;SrcCharacterType&gt;() = tokenStart&lt;SrcCharacterType&gt;() + 1;
+                    if (parseNthChildExtra&lt;SrcCharacterType&gt;()) {
+                        m_token = NTH;
+                        yylval-&gt;string.setLength(currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
+                    } else {
+                        // Revert the change to currentCharacter if unsuccessful.
+                        currentCharacter&lt;SrcCharacterType&gt;() = nextCharacter;
+                    }
+                }
+            }
+        }
+        if (m_parsingMode == NthChildMode &amp;&amp; m_token == IDENT &amp;&amp; yylval-&gt;string.length() == 2 &amp;&amp; equalLettersIgnoringASCIICase(yylval-&gt;string, &quot;of&quot;)) {
+            m_parsingMode = NormalMode;
+            m_token = NTHCHILDSELECTORSEPARATOR;
+        }
+        break;
+
+    case CharacterDot:
+        if (!isASCIIDigit(currentCharacter&lt;SrcCharacterType&gt;()[0]))
+            break;
+        FALLTHROUGH; // To CharacterNumber.
+
+    case CharacterNumber: {
+        bool dotSeen = (m_token == '.');
+
+        while (true) {
+            if (!isASCIIDigit(currentCharacter&lt;SrcCharacterType&gt;()[0])) {
+                // Only one dot is allowed for a number,
+                // and it must be followed by a digit.
+                if (currentCharacter&lt;SrcCharacterType&gt;()[0] != '.' || dotSeen || !isASCIIDigit(currentCharacter&lt;SrcCharacterType&gt;()[1]))
+                    break;
+                dotSeen = true;
+            }
+            ++currentCharacter&lt;SrcCharacterType&gt;();
+        }
+
+        if (UNLIKELY(m_parsingMode == NthChildMode) &amp;&amp; !dotSeen &amp;&amp; isASCIIAlphaCaselessEqual(*currentCharacter&lt;SrcCharacterType&gt;(), 'n')) {
+            // &quot;[0-9]+n&quot; is always an NthChild.
+            ++currentCharacter&lt;SrcCharacterType&gt;();
+            parseNthChildExtra&lt;SrcCharacterType&gt;();
+            m_token = NTH;
+            yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
+            break;
+        }
+
+        // Use SVG parser for numbers on SVG presentation attributes.
+        if (m_context.mode == SVGAttributeMode) {
+            // We need to take care of units like 'em' or 'ex'.
+            SrcCharacterType* character = currentCharacter&lt;SrcCharacterType&gt;();
+            if (isASCIIAlphaCaselessEqual(*character, 'e')) {
+                ASSERT(character - tokenStart&lt;SrcCharacterType&gt;() &gt; 0);
+                ++character;
+                if (*character == '-' || *character == '+' || isASCIIDigit(*character)) {
+                    ++character;
+                    while (isASCIIDigit(*character))
+                        ++character;
+                    // Use FLOATTOKEN if the string contains exponents.
+                    dotSeen = true;
+                    currentCharacter&lt;SrcCharacterType&gt;() = character;
+                }
+            }
+            if (!parseSVGNumber(tokenStart&lt;SrcCharacterType&gt;(), character - tokenStart&lt;SrcCharacterType&gt;(), yylval-&gt;number))
+                break;
+        } else
+            yylval-&gt;number = charactersToDouble(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());

+        // Type of the function.
+        if (isIdentifierStart&lt;SrcCharacterType&gt;()) {
+            SrcCharacterType* type = currentCharacter&lt;SrcCharacterType&gt;();
+            result = currentCharacter&lt;SrcCharacterType&gt;();
+
+            parseIdentifier(result, resultString, hasEscape);
+
+            m_token = DIMEN;
+            if (!hasEscape)
+                detectNumberToken(type, currentCharacter&lt;SrcCharacterType&gt;() - type);
+
+            if (m_token == DIMEN) {
+                // The decoded number is overwritten, but this is intentional.
+                yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
+            }
+        } else if (*currentCharacter&lt;SrcCharacterType&gt;() == '%') {
+            // Although the CSS grammar says {num}% we follow
+            // webkit at the moment which uses {num}%+.
+            do {
+                ++currentCharacter&lt;SrcCharacterType&gt;();
+            } while (*currentCharacter&lt;SrcCharacterType&gt;() == '%');
+            m_token = PERCENTAGE;
+        } else
+            m_token = dotSeen ? FLOATTOKEN : INTEGER;
+        break;
+    }
+
+    case CharacterDash:
+        if (isIdentifierStartAfterDash(currentCharacter&lt;SrcCharacterType&gt;())) {
+            --currentCharacter&lt;SrcCharacterType&gt;();
+            parseIdentifier(result, resultString, hasEscape);
+            m_token = IDENT;
+
+            if (*currentCharacter&lt;SrcCharacterType&gt;() == '(') {
+                m_token = FUNCTION;
+                if (!hasEscape)
+                    detectDashToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;());
+                ++currentCharacter&lt;SrcCharacterType&gt;();
+                ++result;
+            } else if (UNLIKELY(m_parsingMode == NthChildMode) &amp;&amp; !hasEscape &amp;&amp; isASCIIAlphaCaselessEqual(tokenStart&lt;SrcCharacterType&gt;()[1], 'n')) {
+                if (result - tokenStart&lt;SrcCharacterType&gt;() == 2) {
+                    // String &quot;-n&quot; is IDENT but &quot;-n+1&quot; is NTH.
+                    if (parseNthChildExtra&lt;SrcCharacterType&gt;()) {
+                        m_token = NTH;
+                        result = currentCharacter&lt;SrcCharacterType&gt;();
+                    }
+                } else if (result - tokenStart&lt;SrcCharacterType&gt;() &gt;= 3 &amp;&amp; tokenStart&lt;SrcCharacterType&gt;()[2] == '-') {
+                    // String &quot;-n-&quot; is IDENT but &quot;-n-1&quot; is NTH.
+                    // Set currentCharacter to second '-' of '-n-' to continue parsing.
+                    SrcCharacterType* nextCharacter = result;
+                    currentCharacter&lt;SrcCharacterType&gt;() = tokenStart&lt;SrcCharacterType&gt;() + 2;
+                    if (parseNthChildExtra&lt;SrcCharacterType&gt;()) {
+                        m_token = NTH;
+                        result = currentCharacter&lt;SrcCharacterType&gt;();
+                    } else {
+                        // Revert the change to currentCharacter if unsuccessful.
+                        currentCharacter&lt;SrcCharacterType&gt;() = nextCharacter;
+                    }
+                }
+            }
+            resultString.setLength(result - tokenStart&lt;SrcCharacterType&gt;());
+            yylval-&gt;string = resultString;
+        } else if (currentCharacter&lt;SrcCharacterType&gt;()[0] == '-' &amp;&amp; currentCharacter&lt;SrcCharacterType&gt;()[1] == '&gt;') {
+            currentCharacter&lt;SrcCharacterType&gt;() += 2;
+            m_token = SGML_CD;
+        } else if (currentCharacter&lt;SrcCharacterType&gt;()[0] == '-') {
+            --currentCharacter&lt;SrcCharacterType&gt;();
+            parseIdentifier(result, resultString, hasEscape);
+            m_token = CUSTOM_PROPERTY;
+            yylval-&gt;string = resultString;
+        } else if (UNLIKELY(m_parsingMode == NthChildMode)) {
+            // &quot;-[0-9]+n&quot; is always an NthChild.
+            if (parseNthChild&lt;SrcCharacterType&gt;()) {
+                parseNthChildExtra&lt;SrcCharacterType&gt;();
+                m_token = NTH;
+                yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
+            }
+        }
+        break;
+
+    case CharacterOther:
+        // m_token is simply the current character.
+        break;
+
+    case CharacterNull:
+        // Do not advance pointer at the end of input.
+        --currentCharacter&lt;SrcCharacterType&gt;();
+        break;
+
+    case CharacterWhiteSpace:
+        m_token = WHITESPACE;
+        // Might start with a '\n'.
+        --currentCharacter&lt;SrcCharacterType&gt;();
+        do {
+            if (*currentCharacter&lt;SrcCharacterType&gt;() == '\n') {
+                ++m_lineNumber;
+                m_columnOffsetForLine = currentCharacterOffset() + 1;
+            }
+            ++currentCharacter&lt;SrcCharacterType&gt;();
+        } while (*currentCharacter&lt;SrcCharacterType&gt;() &lt;= ' ' &amp;&amp; (typesOfASCIICharacters[*currentCharacter&lt;SrcCharacterType&gt;()] == CharacterWhiteSpace));
+        break;
+
+    case CharacterEndConditionQuery: {
+        bool isParsingCondition = m_parsingMode == MediaQueryMode || m_parsingMode == SupportsMode;
+        if (isParsingCondition)
+            m_parsingMode = NormalMode;
+        break;
+    }
+
+    case CharacterEndNthChild:
+        if (m_parsingMode == NthChildMode)
+            m_parsingMode = NormalMode;
+        break;
+
+    case CharacterQuote:
+        if (checkAndSkipString(currentCharacter&lt;SrcCharacterType&gt;(), m_token)) {
+            ++result;
+            parseString&lt;SrcCharacterType&gt;(result, yylval-&gt;string, m_token);
+            m_token = STRING;
+        }
+        break;
+
+    case CharacterExclamationMark: {
+        SrcCharacterType* start = skipWhiteSpace(currentCharacter&lt;SrcCharacterType&gt;());
+        if (isEqualToCSSIdentifier(start, &quot;important&quot;)) {
+            m_token = IMPORTANT_SYM;
+            currentCharacter&lt;SrcCharacterType&gt;() = start + 9;
+        }
+        break;
+    }
+
+    case CharacterHashmark: {
+        SrcCharacterType* start = currentCharacter&lt;SrcCharacterType&gt;();
+        result = currentCharacter&lt;SrcCharacterType&gt;();
+
+        if (isASCIIDigit(*currentCharacter&lt;SrcCharacterType&gt;())) {
+            // This must be a valid hex number token.
+            do {
+                ++currentCharacter&lt;SrcCharacterType&gt;();
+            } while (isASCIIHexDigit(*currentCharacter&lt;SrcCharacterType&gt;()));
+            m_token = HEX;
+            yylval-&gt;string.init(start, currentCharacter&lt;SrcCharacterType&gt;() - start);
+        } else if (isIdentifierStart&lt;SrcCharacterType&gt;()) {
+            m_token = IDSEL;
+            parseIdentifier(result, yylval-&gt;string, hasEscape);
+            if (!hasEscape) {
+                // Check whether the identifier is also a valid hex number.
+                SrcCharacterType* current = start;
+                m_token = HEX;
+                do {
+                    if (!isASCIIHexDigit(*current)) {
+                        m_token = IDSEL;
+                        break;
+                    }
+                    ++current;
+                } while (current &lt; result);
+            }
+        }
+        break;
+    }
+
+    case CharacterSlash:
+        // Ignore comments. They are not even considered as white spaces.
+        if (*currentCharacter&lt;SrcCharacterType&gt;() == '*') {
+            ++currentCharacter&lt;SrcCharacterType&gt;();
+            while (currentCharacter&lt;SrcCharacterType&gt;()[0] != '*' || currentCharacter&lt;SrcCharacterType&gt;()[1] != '/') {
+                if (*currentCharacter&lt;SrcCharacterType&gt;() == '\n') {
+                    ++m_lineNumber;
+                    m_columnOffsetForLine = currentCharacterOffset() + 1;
+                } else if (*currentCharacter&lt;SrcCharacterType&gt;() == '\0') {
+                    // Unterminated comments are simply ignored.
+                    currentCharacter&lt;SrcCharacterType&gt;() -= 2;
+                    break;
+                }
+                ++currentCharacter&lt;SrcCharacterType&gt;();
+            }
+            currentCharacter&lt;SrcCharacterType&gt;() += 2;
+            goto restartAfterComment;
+        }
+        break;
+
+    case CharacterDollar:
+        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
+            ++currentCharacter&lt;SrcCharacterType&gt;();
+            m_token = ENDSWITH;
+        }
+        break;
+
+    case CharacterAsterisk:
+        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
+            ++currentCharacter&lt;SrcCharacterType&gt;();
+            m_token = CONTAINS;
+        }
+        break;
+
+    case CharacterPlus:
+        if (UNLIKELY(m_parsingMode == NthChildMode)) {
+            // Simplest case. &quot;+[0-9]*n&quot; is always NthChild.
+            if (parseNthChild&lt;SrcCharacterType&gt;()) {
+                parseNthChildExtra&lt;SrcCharacterType&gt;();
+                m_token = NTH;
+                yylval-&gt;string.init(tokenStart&lt;SrcCharacterType&gt;(), currentCharacter&lt;SrcCharacterType&gt;() - tokenStart&lt;SrcCharacterType&gt;());
+            }
+        }
+        break;
+
+    case CharacterLess:
+        if (currentCharacter&lt;SrcCharacterType&gt;()[0] == '!' &amp;&amp; currentCharacter&lt;SrcCharacterType&gt;()[1] == '-' &amp;&amp; currentCharacter&lt;SrcCharacterType&gt;()[2] == '-') {
+            currentCharacter&lt;SrcCharacterType&gt;() += 3;
+            m_token = SGML_CD;
+        }
+        break;
+
+    case CharacterAt:
+        if (isIdentifierStart&lt;SrcCharacterType&gt;()) {
+            m_token = ATKEYWORD;
+            ++result;
+            parseIdentifier(result, resultString, hasEscape);
+            detectAtToken&lt;SrcCharacterType&gt;(result - tokenStart&lt;SrcCharacterType&gt;(), hasEscape);
+        }
+        break;
+
+    case CharacterBackSlash:
+        if (isCSSEscape(*currentCharacter&lt;SrcCharacterType&gt;())) {
+            --currentCharacter&lt;SrcCharacterType&gt;();
+            parseIdentifier(result, yylval-&gt;string, hasEscape);
+            m_token = IDENT;
+        }
+        if (m_parsingMode == NthChildMode &amp;&amp; m_token == IDENT &amp;&amp; yylval-&gt;string.length() == 2 &amp;&amp; equalLettersIgnoringASCIICase(yylval-&gt;string, &quot;of&quot;)) {
+            m_parsingMode = NormalMode;
+            m_token = NTHCHILDSELECTORSEPARATOR;
+        }
+        break;
+
+    case CharacterXor:
+        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
+            ++currentCharacter&lt;SrcCharacterType&gt;();
+            m_token = BEGINSWITH;
+        }
+        break;
+
+    case CharacterVerticalBar:
+        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
+            ++currentCharacter&lt;SrcCharacterType&gt;();
+            m_token = DASHMATCH;
+        }
+        break;
+
+    case CharacterTilde:
+        if (*currentCharacter&lt;SrcCharacterType&gt;() == '=') {
+            ++currentCharacter&lt;SrcCharacterType&gt;();
+            m_token = INCLUDES;
+        }
+        break;
+
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+
+    return token();
+}
+
+RefPtr&lt;StyleRuleImport&gt; CSSParser::createImportRule(const CSSParserString&amp; url, RefPtr&lt;MediaQuerySet&gt;&amp;&amp; media)
+{
+    if (!media || !m_allowImportRules) {
+        popRuleData();
+        return nullptr;
+    }
+    auto rule = StyleRuleImport::create(url, media.releaseNonNull());
+    processAndAddNewRuleToSourceTreeIfNeeded();
+    return WTFMove(rule);
+}
+
+Ref&lt;StyleRuleMedia&gt; CSSParser::createMediaRule(RefPtr&lt;MediaQuerySet&gt;&amp;&amp; media, RuleList* rules)
+{
+    m_allowImportRules = m_allowNamespaceDeclarations = false;
+    RefPtr&lt;StyleRuleMedia&gt; rule;
+    RuleList emptyRules;
+    if (!media) {
+        // To comply with w3c test suite expectation, create an empty media query
+        // even when it is syntactically incorrect.
+        rule = StyleRuleMedia::create(MediaQuerySet::create(), emptyRules);
+    } else {
+        media-&gt;shrinkToFit();
+        rule = StyleRuleMedia::create(media.releaseNonNull(), rules ? *rules : emptyRules);
+    }
+    processAndAddNewRuleToSourceTreeIfNeeded();
+    return rule.releaseNonNull();
+}
+
+Ref&lt;StyleRuleMedia&gt; CSSParser::createEmptyMediaRule(RuleList* rules)
+{
+    return createMediaRule(MediaQuerySet::create(), rules);
+}
+
+Ref&lt;StyleRuleSupports&gt; CSSParser::createSupportsRule(bool conditionIsSupported, RuleList* rules)
+{
+    m_allowImportRules = m_allowNamespaceDeclarations = false;
+
+    RefPtr&lt;CSSRuleSourceData&gt; data = popSupportsRuleData();
+    String conditionText;
+    unsigned conditionOffset = data-&gt;ruleHeaderRange.start + 9;
+    unsigned conditionLength = data-&gt;ruleHeaderRange.length() - 9;
+
+    if (is8BitSource())
+        conditionText = String(m_dataStart8.get() + conditionOffset, conditionLength).stripWhiteSpace();
+    else
+        conditionText = String(m_dataStart16.get() + conditionOffset, conditionLength).stripWhiteSpace();
+
+    RefPtr&lt;StyleRuleSupports&gt; rule;
+    if (rules)
+        rule = StyleRuleSupports::create(conditionText, conditionIsSupported, *rules);
+    else {
+        RuleList emptyRules;
+        rule = StyleRuleSupports::create(conditionText, conditionIsSupported, emptyRules);
+    }
+
+    processAndAddNewRuleToSourceTreeIfNeeded();
+
+    return rule.releaseNonNull();
+}
+
+void CSSParser::markSupportsRuleHeaderStart()
+{
+    if (!m_supportsRuleDataStack)
+        m_supportsRuleDataStack = std::make_unique&lt;RuleSourceDataList&gt;();
+
+    auto data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
+    data-&gt;ruleHeaderRange.start = tokenStartOffset();
+    m_supportsRuleDataStack-&gt;append(WTFMove(data));
+}
+
+void CSSParser::markSupportsRuleHeaderEnd()
+{
+    ASSERT(m_supportsRuleDataStack &amp;&amp; !m_supportsRuleDataStack-&gt;isEmpty());
+
+    if (is8BitSource())
+        m_supportsRuleDataStack-&gt;last()-&gt;ruleHeaderRange.end = tokenStart&lt;LChar&gt;() - m_dataStart8.get();
+    else
+        m_supportsRuleDataStack-&gt;last()-&gt;ruleHeaderRange.end = tokenStart&lt;UChar&gt;() - m_dataStart16.get();
+}
+
+Ref&lt;CSSRuleSourceData&gt; CSSParser::popSupportsRuleData()
+{
+    ASSERT(m_supportsRuleDataStack &amp;&amp; !m_supportsRuleDataStack-&gt;isEmpty());
+    return m_supportsRuleDataStack-&gt;takeLast();
+}
+
+void CSSParser::processAndAddNewRuleToSourceTreeIfNeeded()
+{
+    if (!isExtractingSourceData())
+        return;
+    markRuleBodyEnd();
+    Ref&lt;CSSRuleSourceData&gt; rule = *popRuleData();
+    fixUnparsedPropertyRanges(rule);
+    addNewRuleToSourceTree(WTFMove(rule));
+}
+
+void CSSParser::addNewRuleToSourceTree(Ref&lt;CSSRuleSourceData&gt;&amp;&amp; rule)
+{
+    // Precondition: (isExtractingSourceData()).
+    if (!m_ruleSourceDataResult)
+        return;
+    if (m_currentRuleDataStack-&gt;isEmpty())
+        m_ruleSourceDataResult-&gt;append(WTFMove(rule));
+    else
+        m_currentRuleDataStack-&gt;last()-&gt;childRules.append(WTFMove(rule));
+}
+
+RefPtr&lt;CSSRuleSourceData&gt; CSSParser::popRuleData()
+{
+    if (!m_ruleSourceDataResult)
+        return nullptr;
+
+    ASSERT(!m_currentRuleDataStack-&gt;isEmpty());
+    m_currentRuleData = nullptr;
+    return m_currentRuleDataStack-&gt;takeLast();
+}
+
+void CSSParser::syntaxError(const Location&amp; location, SyntaxErrorType error)
+{
+    if (!isLoggingErrors())
+        return;
+
+    StringBuilder builder;
+    switch (error) {
+    case PropertyDeclarationError:
+        builder.appendLiteral(&quot;Invalid CSS property declaration at: &quot;);
+        break;
+    default:
+        builder.appendLiteral(&quot;Unexpected CSS token: &quot;);
+        break;
+    }
+
+    if (location.token.is8Bit())
+        builder.append(location.token.characters8(), location.token.length());
+    else
+        builder.append(location.token.characters16(), location.token.length());
+
+    logError(builder.toString(), location.lineNumber, location.columnNumber);
+
+    m_ignoreErrorsInDeclaration = true;
+}
+
+bool CSSParser::isLoggingErrors()
+{
+    return m_logErrors &amp;&amp; !m_ignoreErrorsInDeclaration;
+}
+
+void CSSParser::logError(const String&amp; message, int lineNumber, int columnNumber)
+{
+    PageConsoleClient&amp; console = m_styleSheet-&gt;singleOwnerDocument()-&gt;page()-&gt;console();
+    console.addMessage(MessageSource::CSS, MessageLevel::Warning, message, m_styleSheet-&gt;baseURL().string(), lineNumber + 1, columnNumber + 1);
+}
+
+Ref&lt;StyleRuleKeyframes&gt; CSSParser::createKeyframesRule(const String&amp; name, std::unique_ptr&lt;Vector&lt;RefPtr&lt;StyleKeyframe&gt;&gt;&gt; keyframes)
+{
+    m_allowImportRules = m_allowNamespaceDeclarations = false;
+    Ref&lt;StyleRuleKeyframes&gt; rule = StyleRuleKeyframes::create();
+    for (auto&amp; keyFrame : *keyframes)
+        rule-&gt;parserAppendKeyframe(WTFMove(keyFrame));
+    rule-&gt;setName(name);
+    processAndAddNewRuleToSourceTreeIfNeeded();
+    return rule;
+}
+
+RefPtr&lt;StyleRule&gt; CSSParser::createStyleRule(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* selectors)
+{
+    RefPtr&lt;StyleRule&gt; rule;
+    if (selectors) {
+        m_allowImportRules = false;
+        m_allowNamespaceDeclarations = false;
+        rule = StyleRule::create(m_lastSelectorLineNumber, createStyleProperties());
+        rule-&gt;parserAdoptSelectorVector(*selectors);
+        processAndAddNewRuleToSourceTreeIfNeeded();
+    } else
+        popRuleData();
+    clearProperties();
+    return rule;
+}
+
+RefPtr&lt;StyleRuleFontFace&gt; CSSParser::createFontFaceRule()
+{
+    m_allowImportRules = m_allowNamespaceDeclarations = false;
+    for (auto&amp; property : m_parsedProperties) {
+        if (property.id() == CSSPropertyFontFamily &amp;&amp; (!is&lt;CSSValueList&gt;(*property.value()) || downcast&lt;CSSValueList&gt;(*property.value()).length() != 1)) {
+            // Unlike font-family property, font-family descriptor in @font-face rule
+            // has to be a value list with exactly one family name. It cannot have a
+            // have 'initial' value and cannot 'inherit' from parent.
+            // See http://dev.w3.org/csswg/css3-fonts/#font-family-desc
+            clearProperties();
+            popRuleData();
+            return nullptr;
+        }
+    }
+    auto rule = StyleRuleFontFace::create(createStyleProperties());
+    clearProperties();
+    processAndAddNewRuleToSourceTreeIfNeeded();
+    return WTFMove(rule);
+}
+
+void CSSParser::addNamespace(const AtomicString&amp; prefix, const AtomicString&amp; uri)
+{
+    if (!m_styleSheet || !m_allowNamespaceDeclarations)
+        return;
+    m_allowImportRules = false;
+    m_styleSheet-&gt;parserAddNamespace(prefix, uri);
+    if (prefix.isEmpty() &amp;&amp; !uri.isNull())
+        m_defaultNamespace = uri;
+}
+
+QualifiedName CSSParser::determineNameInNamespace(const AtomicString&amp; prefix, const AtomicString&amp; localName)
+{
+    if (prefix.isNull())
+        return QualifiedName(nullAtom, localName, nullAtom); // No namespace. If an element/attribute has a namespace, we won't match it.
+    if (prefix.isEmpty())
+        return QualifiedName(emptyAtom, localName, emptyAtom); // Empty namespace.
+    if (prefix == starAtom)
+        return QualifiedName(prefix, localName, starAtom); // We'll match any namespace.
+
+    if (!m_styleSheet)
+        return QualifiedName(prefix, localName, m_defaultNamespace);
+    return QualifiedName(prefix, localName, m_styleSheet-&gt;determineNamespace(prefix));
+}
+
+void CSSParser::rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector&amp; specifiers)
+{
+    if (m_defaultNamespace != starAtom || specifiers.isCustomPseudoElement()) {
+        QualifiedName elementName(nullAtom, starAtom, m_defaultNamespace);
+        rewriteSpecifiersWithElementName(elementName, specifiers, /*tagIsForNamespaceRule*/true);
+    }
+}
+
+void CSSParser::rewriteSpecifiersWithElementName(const AtomicString&amp; namespacePrefix, const AtomicString&amp; elementName, CSSParserSelector&amp; specifiers)
+{
+    QualifiedName tag(determineNameInNamespace(namespacePrefix, elementName));
+    rewriteSpecifiersWithElementName(tag, specifiers, false);
+}
+
+void CSSParser::rewriteSpecifiersWithElementName(const QualifiedName&amp; tag, CSSParserSelector&amp; specifiers, bool tagIsForNamespaceRule)
+{
+    if (!specifiers.isCustomPseudoElement()) {
+        if (tag == anyQName())
+            return;
+        if (!specifiers.isPseudoElementCueFunction())
+            specifiers.prependTagSelector(tag, tagIsForNamespaceRule);
+        return;
+    }
+
+    CSSParserSelector* lastShadowDescendant = &amp;specifiers;
+    CSSParserSelector* history = &amp;specifiers;
+    while (history-&gt;tagHistory()) {
+        history = history-&gt;tagHistory();
+        if (history-&gt;isCustomPseudoElement() || history-&gt;hasShadowDescendant())
+            lastShadowDescendant = history;
+    }
+
+    if (lastShadowDescendant-&gt;tagHistory()) {
+        if (tag != anyQName())
+            lastShadowDescendant-&gt;tagHistory()-&gt;prependTagSelector(tag, tagIsForNamespaceRule);
+        return;
+    }
+
+    // For shadow-ID pseudo-elements to be correctly matched, the ShadowDescendant combinator has to be used.
+    // We therefore create a new Selector with that combinator here in any case, even if matching any (host) element in any namespace (i.e. '*').
+    lastShadowDescendant-&gt;setTagHistory(std::make_unique&lt;CSSParserSelector&gt;(tag));
+    lastShadowDescendant-&gt;setRelation(CSSSelector::ShadowDescendant);
+}
+
+std::unique_ptr&lt;CSSParserSelector&gt; CSSParser::rewriteSpecifiers(std::unique_ptr&lt;CSSParserSelector&gt; specifiers, std::unique_ptr&lt;CSSParserSelector&gt; newSpecifier)
+{
+    if (newSpecifier-&gt;isCustomPseudoElement() || newSpecifier-&gt;isPseudoElementCueFunction()) {
+        // Unknown pseudo element always goes at the top of selector chain.
+        newSpecifier-&gt;appendTagHistory(CSSSelector::ShadowDescendant, WTFMove(specifiers));
+        return newSpecifier;
+    }
+    if (specifiers-&gt;isCustomPseudoElement()) {
+        // Specifiers for unknown pseudo element go right behind it in the chain.
+        specifiers-&gt;insertTagHistory(CSSSelector::SubSelector, WTFMove(newSpecifier), CSSSelector::ShadowDescendant);
+        return specifiers;
+    }
+    specifiers-&gt;appendTagHistory(CSSSelector::SubSelector, WTFMove(newSpecifier));
+    return specifiers;
+}
+
+RefPtr&lt;StyleRulePage&gt; CSSParser::createPageRule(std::unique_ptr&lt;CSSParserSelector&gt; pageSelector)
+{
+    // FIXME: Margin at-rules are ignored.
+    m_allowImportRules = m_allowNamespaceDeclarations = false;
+    if (pageSelector) {
+        auto rule = StyleRulePage::create(createStyleProperties());
+        Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt; selectorVector;
+        selectorVector.append(WTFMove(pageSelector));
+        rule-&gt;parserAdoptSelectorVector(selectorVector);
+        processAndAddNewRuleToSourceTreeIfNeeded();
+        clearProperties();
+        return WTFMove(rule);
+    }
+
+    popRuleData();
+    clearProperties();
+    return nullptr;
+}
+
+std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; CSSParser::createSelectorVector()
+{
+    if (m_recycledSelectorVector) {
+        m_recycledSelectorVector-&gt;shrink(0);
+        return WTFMove(m_recycledSelectorVector);
+    }
+    return std::make_unique&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt;();
+}
+
+void CSSParser::recycleSelectorVector(std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; vector)
+{
+    if (vector &amp;&amp; !m_recycledSelectorVector)
+        m_recycledSelectorVector = WTFMove(vector);
+}
+
+RefPtr&lt;StyleRuleRegion&gt; CSSParser::createRegionRule(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* regionSelector, RuleList* rules)
+{
+    if (!regionSelector || !rules) {
+        popRuleData();
+        return nullptr;
+    }
+
+    m_allowImportRules = m_allowNamespaceDeclarations = false;
+
+    auto regionRule = StyleRuleRegion::create(regionSelector, *rules);
+
+    if (isExtractingSourceData())
+        addNewRuleToSourceTree(CSSRuleSourceData::createUnknown());
+
+    return WTFMove(regionRule);
+}
+
+void CSSParser::createMarginAtRule(CSSSelector::MarginBoxType /* marginBox */)
+{
+    // FIXME: Implement margin at-rule here, using:
+    //        - marginBox: margin box
+    //        - m_parsedProperties: properties at [m_numParsedPropertiesBeforeMarginBox, m_parsedProperties.size()] are for this at-rule.
+    // Don't forget to also update the action for page symbol in CSSGrammar.y such that margin at-rule data is cleared if page_selector is invalid.
+
+    endDeclarationsForMarginBox();
+}
+
+void CSSParser::startDeclarationsForMarginBox()
+{
+    m_numParsedPropertiesBeforeMarginBox = m_parsedProperties.size();
+}
+
+void CSSParser::endDeclarationsForMarginBox()
+{
+    rollbackLastProperties(m_parsedProperties.size() - m_numParsedPropertiesBeforeMarginBox);
+    m_numParsedPropertiesBeforeMarginBox = invalidParsedPropertiesCount;
+}
+
+RefPtr&lt;StyleKeyframe&gt; CSSParser::createKeyframe(CSSParserValueList&amp; keys)
+{
+    // Create a key string from the passed keys
+    StringBuilder keyString;
+    for (unsigned i = 0; i &lt; keys.size(); ++i) {
+        // Just as per the comment below, we ignore keyframes with
+        // invalid key values (plain numbers or unknown identifiers)
+        // marked as CSSPrimitiveValue::CSS_UNKNOWN during parsing.
+        if (keys.valueAt(i)-&gt;unit == CSSPrimitiveValue::CSS_UNKNOWN) {
+            clearProperties();
+            return nullptr;
+        }
+
+        ASSERT(keys.valueAt(i)-&gt;unit == CSSPrimitiveValue::CSS_NUMBER);
+        float key = static_cast&lt;float&gt;(keys.valueAt(i)-&gt;fValue);
+        if (key &lt; 0 || key &gt; 100) {
+            // As per http://www.w3.org/TR/css3-animations/#keyframes,
+            // &quot;If a keyframe selector specifies negative percentage values
+            // or values higher than 100%, then the keyframe will be ignored.&quot;
+            clearProperties();
+            return nullptr;
+        }
+        if (i != 0)
+            keyString.append(',');
+        keyString.appendNumber(key);
+        keyString.append('%');
+    }
+
+    auto keyframe = StyleKeyframe::create(createStyleProperties());
+    keyframe-&gt;setKeyText(keyString.toString());
+
+    clearProperties();
+
+    return WTFMove(keyframe);
+}
+
+void CSSParser::invalidBlockHit()
+{
+    if (m_styleSheet &amp;&amp; !m_hadSyntacticallyValidCSSRule)
+        m_styleSheet-&gt;setHasSyntacticallyValidCSSHeader(false);
+}
+
+void CSSParser::updateLastSelectorLineAndPosition()
+{
+    m_lastSelectorLineNumber = m_lineNumber;
+}
+
+void CSSParser::updateLastMediaLine(MediaQuerySet&amp; media)
+{
+    media.setLastLine(m_lineNumber);
+}
+
+template &lt;typename CharacterType&gt;
+static inline void fixUnparsedProperties(const CharacterType* characters, CSSRuleSourceData&amp; ruleData)
+{
+    auto&amp; propertyData = ruleData.styleSourceData-&gt;propertyData;
+    unsigned size = propertyData.size();
+    if (!size)
+        return;
+
+    unsigned styleStart = ruleData.ruleBodyRange.start;
+    auto* nextData = &amp;propertyData[0];
+    for (unsigned i = 0; i &lt; size; ++i) {
+        auto* currentData = nextData;
+        nextData = i &lt; size - 1 ? &amp;propertyData[i + 1] : 0;
+
+        if (currentData-&gt;parsedOk)
+            continue;
+        if (currentData-&gt;range.end &gt; 0 &amp;&amp; characters[styleStart + currentData-&gt;range.end - 1] == ';')
+            continue;
+
+        unsigned propertyEndInStyleSheet;
+        if (!nextData)
+            propertyEndInStyleSheet = ruleData.ruleBodyRange.end - 1;
+        else
+            propertyEndInStyleSheet = styleStart + nextData-&gt;range.start - 1;
+
+        while (isHTMLSpace(characters[propertyEndInStyleSheet]))
+            --propertyEndInStyleSheet;
+
+        // propertyEndInStyleSheet points at the last property text character.
+        unsigned newPropertyEnd = propertyEndInStyleSheet - styleStart + 1; // Exclusive of the last property text character.
+        if (currentData-&gt;range.end != newPropertyEnd) {
+            currentData-&gt;range.end = newPropertyEnd;
+            unsigned valueStartInStyleSheet = styleStart + currentData-&gt;range.start + currentData-&gt;name.length();
+            while (valueStartInStyleSheet &lt; propertyEndInStyleSheet &amp;&amp; characters[valueStartInStyleSheet] != ':')
+                ++valueStartInStyleSheet;
+            if (valueStartInStyleSheet &lt; propertyEndInStyleSheet)
+                ++valueStartInStyleSheet; // Shift past the ':'.
+            while (valueStartInStyleSheet &lt; propertyEndInStyleSheet &amp;&amp; isHTMLSpace(characters[valueStartInStyleSheet]))
+                ++valueStartInStyleSheet;
+            // Need to exclude the trailing ';' from the property value.
+            currentData-&gt;value = String(characters + valueStartInStyleSheet, propertyEndInStyleSheet - valueStartInStyleSheet + (characters[propertyEndInStyleSheet] == ';' ? 0 : 1));
+        }
+    }
+}
+
+void CSSParser::fixUnparsedPropertyRanges(CSSRuleSourceData&amp; ruleData)
+{
+    if (!ruleData.styleSourceData)
+        return;
+
+    if (is8BitSource()) {
+        fixUnparsedProperties&lt;LChar&gt;(m_dataStart8.get() + m_parsedTextPrefixLength, ruleData);
+        return;
+    }
+
+    fixUnparsedProperties&lt;UChar&gt;(m_dataStart16.get() + m_parsedTextPrefixLength, ruleData);
+}
+
+void CSSParser::markRuleHeaderStart(CSSRuleSourceData::Type ruleType)
+{
+    if (!isExtractingSourceData())
+        return;
+
+    // Pop off data for a previous invalid rule.
+    if (m_currentRuleData)
+        m_currentRuleDataStack-&gt;removeLast();
+
+    auto data = CSSRuleSourceData::create(ruleType);
+    data-&gt;ruleHeaderRange.start = tokenStartOffset();
+    m_currentRuleData = data.copyRef();
+    m_currentRuleDataStack-&gt;append(WTFMove(data));
+}
+
+template &lt;typename CharacterType&gt;
+inline void CSSParser::setRuleHeaderEnd(const CharacterType* dataStart)
+{
+    CharacterType* listEnd = tokenStart&lt;CharacterType&gt;();
+    while (listEnd &gt; dataStart + 1) {
+        if (isHTMLSpace(*(listEnd - 1)))
+            --listEnd;
+        else
+            break;
+    }
+
+    m_currentRuleDataStack-&gt;last()-&gt;ruleHeaderRange.end = listEnd - dataStart;
+}
+
+void CSSParser::markRuleHeaderEnd()
+{
+    if (!isExtractingSourceData())
+        return;
+    ASSERT(!m_currentRuleDataStack-&gt;isEmpty());
+
+    if (is8BitSource())
+        setRuleHeaderEnd&lt;LChar&gt;(m_dataStart8.get());
+    else
+        setRuleHeaderEnd&lt;UChar&gt;(m_dataStart16.get());
+}
+
+void CSSParser::markSelectorStart()
+{
+    if (!isExtractingSourceData() || m_nestedSelectorLevel)
+        return;
+    ASSERT(!m_selectorRange.end);
+
+    m_selectorRange.start = tokenStartOffset();
+}
+
+void CSSParser::markSelectorEnd()
+{
+    if (!isExtractingSourceData() || m_nestedSelectorLevel)
+        return;
+    ASSERT(!m_selectorRange.end);
+    ASSERT(m_currentRuleDataStack-&gt;size());
+
+    m_selectorRange.end = tokenStartOffset();
+    m_currentRuleDataStack-&gt;last()-&gt;selectorRanges.append(m_selectorRange);
+    m_selectorRange.start = 0;
+    m_selectorRange.end = 0;
+}
+
+void CSSParser::markRuleBodyStart()
+{
+    if (!isExtractingSourceData())
+        return;
+    m_currentRuleData = nullptr;
+    unsigned offset = tokenStartOffset();
+    if (tokenStartChar() == '{')
+        ++offset; // Skip the rule body opening brace.
+    ASSERT(!m_currentRuleDataStack-&gt;isEmpty());
+    m_currentRuleDataStack-&gt;last()-&gt;ruleBodyRange.start = offset;
+}
+
+void CSSParser::markRuleBodyEnd()
+{
+    // Precondition: (!isExtractingSourceData())
+    unsigned offset = tokenStartOffset();
+    ASSERT(!m_currentRuleDataStack-&gt;isEmpty());
+    m_currentRuleDataStack-&gt;last()-&gt;ruleBodyRange.end = offset;
+}
+
+void CSSParser::markPropertyStart()
+{
+    m_ignoreErrorsInDeclaration = false;
+    if (!isExtractingSourceData())
+        return;
+    if (m_currentRuleDataStack-&gt;isEmpty() || !m_currentRuleDataStack-&gt;last()-&gt;styleSourceData)
+        return;
+
+    m_propertyRange.start = tokenStartOffset();
+}
+
+void CSSParser::markPropertyEnd(bool isImportantFound, bool isPropertyParsed)
+{
+    if (!isExtractingSourceData())
+        return;
+    if (m_currentRuleDataStack-&gt;isEmpty() || !m_currentRuleDataStack-&gt;last()-&gt;styleSourceData)
+        return;
+
+    unsigned offset = tokenStartOffset();
+    if (tokenStartChar() == ';') // Include semicolon into the property text.
+        ++offset;
+    m_propertyRange.end = offset;
+    if (m_propertyRange.start != std::numeric_limits&lt;unsigned&gt;::max() &amp;&amp; !m_currentRuleDataStack-&gt;isEmpty()) {
+        // This stuff is only executed when the style data retrieval is requested by client.
+        const unsigned start = m_propertyRange.start;
+        const unsigned end = m_propertyRange.end;
+        ASSERT_WITH_SECURITY_IMPLICATION(start &lt; end);
+        String propertyString;
+        if (is8BitSource())
+            propertyString = String(m_dataStart8.get() + start, end - start).stripWhiteSpace();
+        else
+            propertyString = String(m_dataStart16.get() + start, end - start).stripWhiteSpace();
+        if (propertyString.endsWith(';'))
+            propertyString = propertyString.left(propertyString.length() - 1);
+        size_t colonIndex = propertyString.find(':');
+        ASSERT(colonIndex != notFound);
+
+        String name = propertyString.left(colonIndex).stripWhiteSpace();
+        String value = propertyString.substring(colonIndex + 1, propertyString.length()).stripWhiteSpace();
+        // The property range is relative to the declaration start offset.
+        SourceRange&amp; topRuleBodyRange = m_currentRuleDataStack-&gt;last()-&gt;ruleBodyRange;
+        m_currentRuleDataStack-&gt;last()-&gt;styleSourceData-&gt;propertyData.append(
+            CSSPropertySourceData(name, value, isImportantFound, isPropertyParsed, SourceRange(start - topRuleBodyRange.start, end - topRuleBodyRange.start)));
+    }
+    resetPropertyRange();
+}
+
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+Ref&lt;StyleRuleViewport&gt; CSSParser::createViewportRule()
+{
+    m_allowImportRules = m_allowNamespaceDeclarations = false;
+
+    auto rule = StyleRuleViewport::create(createStyleProperties());
+    clearProperties();
+
+    processAndAddNewRuleToSourceTreeIfNeeded();
+
+    return rule;
+}
+
+bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important)
+{
+    if (!m_valueList-&gt;current())
+        return false;
+
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+
+    CSSValueID id = valueWithCalculation.value().id;
+    bool validPrimitive = false;
+
+    switch (propId) {
+    case CSSPropertyMinWidth: // auto | device-width | device-height | &lt;length&gt; | &lt;percentage&gt;
+    case CSSPropertyMaxWidth:
+    case CSSPropertyMinHeight:
+    case CSSPropertyMaxHeight:
+        if (id == CSSValueAuto || id == CSSValueDeviceWidth || id == CSSValueDeviceHeight)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg));
+        break;
+    case CSSPropertyWidth: // shorthand
+        return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important);
+    case CSSPropertyHeight:
+        return parseViewportShorthand(propId, CSSPropertyMinHeight, CSSPropertyMaxHeight, important);
+    case CSSPropertyMinZoom: // auto | &lt;number&gt; | &lt;percentage&gt;
+    case CSSPropertyMaxZoom:
+    case CSSPropertyZoom:
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FPercent | FNonNeg));
+        break;
+    case CSSPropertyUserZoom: // zoom | fixed
+        if (id == CSSValueZoom || id == CSSValueFixed)
+            validPrimitive = true;
+        break;
+    case CSSPropertyOrientation: // auto | portrait | landscape
+        if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandscape)
+            validPrimitive = true;
+    default:
+        break;
+    }
+
+    RefPtr&lt;CSSValue&gt; parsedValue;
+    if (validPrimitive) {
+        parsedValue = parseValidPrimitive(id, valueWithCalculation);
+        m_valueList-&gt;next();
+    }
+
+    if (!parsedValue)
+        return false;
+
+    if (m_valueList-&gt;current() &amp;&amp; !inShorthand())
+        return false;
+
+    addProperty(propId, parsedValue.releaseNonNull(), important);
+    return true;
+}
+
+bool CSSParser::parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important)
+{
+    unsigned numValues = m_valueList-&gt;size();
+
+    if (numValues &gt; 2)
+        return false;
+
+    ShorthandScope scope(this, propId);
+
+    if (!parseViewportProperty(first, important))
+        return false;
+
+    // If just one value is supplied, the second value
+    // is implicitly initialized with the first value.
+    if (numValues == 1)
+        m_valueList-&gt;previous();
+
+    return parseViewportProperty(second, important);
+}
+#endif
+
+template &lt;typename CharacterType&gt;
+static CSSPropertyID cssPropertyID(const CharacterType* propertyName, unsigned length)
+{
+    char buffer[maxCSSPropertyNameLength + 1 + 1]; // 1 to turn &quot;apple&quot;/&quot;khtml&quot; into &quot;webkit&quot;, 1 for null character
+
+    for (unsigned i = 0; i != length; ++i) {
+        CharacterType c = propertyName[i];
+        if (c == 0 || c &gt;= 0x7F)
+            return CSSPropertyInvalid; // illegal character
+        buffer[i] = toASCIILower(c);
+    }
+    buffer[length] = '\0';
+
+    const char* name = buffer;
+    if (buffer[0] == '-') {
+#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
+        // If the prefix is -apple- or -khtml-, change it to -webkit-.
+        // This makes the string one character longer.
+        if (RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled()
+            &amp;&amp; (hasPrefix(buffer, length, &quot;-apple-&quot;) || hasPrefix(buffer, length, &quot;-khtml-&quot;))) {
+            memmove(buffer + 7, buffer + 6, length + 1 - 6);
+            memcpy(buffer, &quot;-webkit&quot;, 7);
+            ++length;
+        }
+#endif
+#if PLATFORM(IOS)
+        cssPropertyNameIOSAliasing(buffer, name, length);
+#endif
+    }
+
+    const Property* hashTableEntry = findProperty(name, length);
+    return hashTableEntry ? static_cast&lt;CSSPropertyID&gt;(hashTableEntry-&gt;id) : CSSPropertyInvalid;
+}
+
+CSSPropertyID cssPropertyID(const String&amp; string)
+{
+    unsigned length = string.length();
+
+    if (!length)
+        return CSSPropertyInvalid;
+    if (length &gt; maxCSSPropertyNameLength)
+        return CSSPropertyInvalid;
+    
+    return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
+}
+
+CSSPropertyID cssPropertyID(const CSSParserString&amp; string)
+{
+    unsigned length = string.length();
+
+    if (!length)
+        return CSSPropertyInvalid;
+    if (length &gt; maxCSSPropertyNameLength)
+        return CSSPropertyInvalid;
+    
+    return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
+}
+
+#if PLATFORM(IOS)
+void cssPropertyNameIOSAliasing(const char* propertyName, const char*&amp; propertyNameAlias, unsigned&amp; newLength)
+{
+    if (!strcmp(propertyName, &quot;-webkit-hyphenate-locale&quot;)) {
+        // Worked in iOS 4.2.
+        static const char webkitLocale[] = &quot;-webkit-locale&quot;;
+        propertyNameAlias = webkitLocale;
+        newLength = strlen(webkitLocale);
+    }
+}
+#endif
+
+static bool isAppleLegacyCssValueKeyword(const char* valueKeyword, unsigned length)
+{
+    static const char applePrefix[] = &quot;-apple-&quot;;
+    static const char appleSystemPrefix[] = &quot;-apple-system&quot;;
+    static const char* appleWirelessPlaybackTargetActive = getValueName(CSSValueAppleWirelessPlaybackTargetActive);
+
+    return hasPrefix(valueKeyword, length, applePrefix)
+        &amp;&amp; !hasPrefix(valueKeyword, length, appleSystemPrefix)
+        &amp;&amp; !WTF::equal(reinterpret_cast&lt;const LChar*&gt;(valueKeyword), reinterpret_cast&lt;const LChar*&gt;(appleWirelessPlaybackTargetActive), length);
+}
+
+template &lt;typename CharacterType&gt;
+static CSSValueID cssValueKeywordID(const CharacterType* valueKeyword, unsigned length)
+{
+    char buffer[maxCSSValueKeywordLength + 1 + 1]; // 1 to turn &quot;apple&quot;/&quot;khtml&quot; into &quot;webkit&quot;, 1 for null character
+
+    for (unsigned i = 0; i != length; ++i) {
+        CharacterType c = valueKeyword[i];
+        if (c == 0 || c &gt;= 0x7F)
+            return CSSValueInvalid; // illegal keyword.
+        buffer[i] = WTF::toASCIILower(c);
+    }
+    buffer[length] = '\0';
+
+    if (buffer[0] == '-') {
+        // If the prefix is -apple- or -khtml-, change it to -webkit-.
+        // This makes the string one character longer.
+        // On iOS we don't want to change values starting with -apple-system to -webkit-system.
+        // FIXME: Remove this mangling without breaking the web.
+        if (isAppleLegacyCssValueKeyword(buffer, length) || hasPrefix(buffer, length, &quot;-khtml-&quot;)) {
+            memmove(buffer + 7, buffer + 6, length + 1 - 6);
+            memcpy(buffer, &quot;-webkit&quot;, 7);
+            ++length;
+        }
+    }
+
+    const Value* hashTableEntry = findValue(buffer, length);
+    return hashTableEntry ? static_cast&lt;CSSValueID&gt;(hashTableEntry-&gt;id) : CSSValueInvalid;
+}
+
+CSSValueID cssValueKeywordID(const CSSParserString&amp; string)
+{
+    unsigned length = string.length();
+    if (!length)
+        return CSSValueInvalid;
+    if (length &gt; maxCSSValueKeywordLength)
+        return CSSValueInvalid;
+
+    return string.is8Bit() ? cssValueKeywordID(string.characters8(), length) : cssValueKeywordID(string.characters16(), length);
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool isCSSTokenizerIdentifier(const CharacterType* characters, unsigned length)
+{
+    const CharacterType* end = characters + length;
+
+    // -?
+    if (characters != end &amp;&amp; characters[0] == '-')
+        ++characters;
+
+    // {nmstart}
+    if (characters == end || !(characters[0] == '_' || characters[0] &gt;= 128 || isASCIIAlpha(characters[0])))
+        return false;
+    ++characters;
+
+    // {nmchar}*
+    for (; characters != end; ++characters) {
+        if (!(characters[0] == '_' || characters[0] == '-' || characters[0] &gt;= 128 || isASCIIAlphanumeric(characters[0])))
+            return false;
+    }
+
+    return true;
+}
+
+// &quot;ident&quot; from the CSS tokenizer, minus backslash-escape sequences
+static bool isCSSTokenizerIdentifier(const String&amp; string)
+{
+    unsigned length = string.length();
+
+    if (!length)
+        return false;
+
+    if (string.is8Bit())
+        return isCSSTokenizerIdentifier(string.characters8(), length);
+    return isCSSTokenizerIdentifier(string.characters16(), length);
+}
+
+template &lt;typename CharacterType&gt;
+static inline bool isCSSTokenizerURL(const CharacterType* characters, unsigned length)
+{
+    const CharacterType* end = characters + length;
+    
+    for (; characters != end; ++characters) {
+        CharacterType c = characters[0];
+        switch (c) {
+            case '!':
+            case '#':
+            case '$':
+            case '%':
+            case '&amp;':
+                break;
+            default:
+                if (c &lt; '*')
+                    return false;
+                if (c &lt;= '~')
+                    break;
+                if (c &lt; 128)
+                    return false;
+        }
+    }
+    
+    return true;
+}
+
+// &quot;url&quot; from the CSS tokenizer, minus backslash-escape sequences
+static bool isCSSTokenizerURL(const String&amp; string)
+{
+    unsigned length = string.length();
+
+    if (!length)
+        return true;
+
+    if (string.is8Bit())
+        return isCSSTokenizerURL(string.characters8(), length);
+    return isCSSTokenizerURL(string.characters16(), length);
+}
+
+
+template &lt;typename CharacterType&gt;
+static inline String quoteCSSStringInternal(const CharacterType* characters, unsigned length)
+{
+    // For efficiency, we first pre-calculate the length of the quoted string, then we build the actual one.
+    // Please see below for the actual logic.
+    unsigned quotedStringSize = 2; // Two quotes surrounding the entire string.
+    bool afterEscape = false;
+    for (unsigned i = 0; i &lt; length; ++i) {
+        CharacterType ch = characters[i];
+        if (ch == '\\' || ch == '\'') {
+            quotedStringSize += 2;
+            afterEscape = false;
+        } else if (ch &lt; 0x20 || ch == 0x7F) {
+            quotedStringSize += 2 + (ch &gt;= 0x10);
+            afterEscape = true;
+        } else {
+            quotedStringSize += 1 + (afterEscape &amp;&amp; (isASCIIHexDigit(ch) || ch == ' '));
+            afterEscape = false;
+        }
+    }
+
+    StringBuffer&lt;CharacterType&gt; buffer(quotedStringSize);
+    unsigned index = 0;
+    buffer[index++] = '\'';
+    afterEscape = false;
+    for (unsigned i = 0; i &lt; length; ++i) {
+        CharacterType ch = characters[i];
+        if (ch == '\\' || ch == '\'') {
+            buffer[index++] = '\\';
+            buffer[index++] = ch;
+            afterEscape = false;
+        } else if (ch &lt; 0x20 || ch == 0x7F) { // Control characters.
+            buffer[index++] = '\\';
+            placeByteAsHexCompressIfPossible(ch, buffer, index, Lowercase);
+            afterEscape = true;
+        } else {
+            // Space character may be required to separate backslash-escape sequence and normal characters.
+            if (afterEscape &amp;&amp; (isASCIIHexDigit(ch) || ch == ' '))
+                buffer[index++] = ' ';
+            buffer[index++] = ch;
+            afterEscape = false;
+        }
+    }
+    buffer[index++] = '\'';
+
+    ASSERT(quotedStringSize == index);
+    return String::adopt(buffer);
+}
+
+// We use single quotes for now because markup.cpp uses double quotes.
+String quoteCSSString(const String&amp; string)
+{
+    // This function expands each character to at most 3 characters ('\u0010' -&gt; '\' '1' '0') as well as adds
+    // 2 quote characters (before and after). Make sure the resulting size (3 * length + 2) will not overflow unsigned.
+
+    unsigned length = string.length();
+
+    if (!length)
+        return ASCIILiteral(&quot;\'\'&quot;);
+
+    if (length &gt; std::numeric_limits&lt;unsigned&gt;::max() / 3 - 2)
+        return emptyString();
+
+    if (string.is8Bit())
+        return quoteCSSStringInternal(string.characters8(), length);
+    return quoteCSSStringInternal(string.characters16(), length);
+}
+
+String quoteCSSStringIfNeeded(const String&amp; string)
+{
+    return isCSSTokenizerIdentifier(string) ? string : quoteCSSString(string);
+}
+
+String quoteCSSURLIfNeeded(const String&amp; string)
+{
+    return isCSSTokenizerURL(string) ? string : quoteCSSString(string);
+}
+
+bool isValidNthToken(const CSSParserString&amp; token)
+{
+    // The tokenizer checks for the construct of an+b.
+    // However, since the {ident} rule precedes the {nth} rule, some of those
+    // tokens are identified as string literal. Furthermore we need to accept
+    // &quot;odd&quot; and &quot;even&quot; which does not match to an+b.
+    return equalLettersIgnoringASCIICase(token, &quot;odd&quot;)
+        || equalLettersIgnoringASCIICase(token, &quot;even&quot;)
+        || equalLettersIgnoringASCIICase(token, &quot;n&quot;)
+        || equalLettersIgnoringASCIICase(token, &quot;-n&quot;);
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserhfromrev204839trunkSourceWebCorecssCSSParserh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/css/parser/CSSParser.h (from rev 204839, trunk/Source/WebCore/css/CSSParser.h) (0 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParser.h                                (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSParser.h        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -0,0 +1,800 @@
</span><ins>+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004-2010, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Eric Seidel &lt;eric@webkit.org&gt;
+ * Copyright (C) 2009 - 2010  Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include &quot;CSSCalculationValue.h&quot;
+#include &quot;CSSGradientValue.h&quot;
+#include &quot;CSSParserMode.h&quot;
+#include &quot;CSSParserValues.h&quot;
+#include &quot;CSSProperty.h&quot;
+#include &quot;CSSPropertyNames.h&quot;
+#include &quot;CSSPropertySourceData.h&quot;
+#include &quot;CSSValueKeywords.h&quot;
+#include &quot;Color.h&quot;
+#include &quot;MediaQuery.h&quot;
+#include &quot;SourceSizeList.h&quot;
+#include &quot;StyleRuleImport.h&quot;
+#include &quot;WebKitCSSFilterValue.h&quot;
+#include &lt;memory&gt;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/text/AtomicString.h&gt;
+#include &lt;wtf/text/TextPosition.h&gt;
+
+#if ENABLE(CSS_GRID_LAYOUT)
+#include &quot;GridArea.h&quot;
+#endif
+
+namespace WebCore {
+
+class AnimationParseContext;
+class CSSBorderImageSliceValue;
+class CSSContentDistributionValue;
+class CSSPrimitiveValue;
+class CSSSelectorList;
+class CSSValue;
+class CSSValueList;
+class CSSBasicShape;
+class CSSBasicShapeCircle;
+class CSSBasicShapeEllipse;
+class CSSBasicShapeInset;
+class CSSBasicShapePath;
+class CSSBasicShapePolygon;
+class CSSGridLineNamesValue;
+class CSSImageSetValue;
+class CSSVariableDependentValue;
+class Document;
+class Element;
+class ImmutableStyleProperties;
+class MediaQueryExpression;
+class MediaQuerySet;
+class MutableStyleProperties;
+class SVGColor;
+class SVGPaint;
+class StyleKeyframe;
+class StylePropertyShorthand;
+class StyleRule;
+class StyleRuleBase;
+class StyleRuleFontFace;
+class StyleRuleKeyframes;
+class StyleRuleMedia;
+class StyleRulePage;
+class StyleRuleRegion;
+class StyleRuleSupports;
+class StyleRuleViewport;
+class StyleKeyframe;
+class StyleSheetContents;
+class StyledElement;
+class WebKitCSSTransformValue;
+
+class CSSParser {
+    friend inline int cssyylex(void*, CSSParser*);
+
+public:
+    struct Location;
+    enum SyntaxErrorType {
+        PropertyDeclarationError,
+        GeneralSyntaxError
+    };
+
+    enum class ParseResult {
+        Changed,
+        Unchanged,
+        Error
+    };
+
+    class ValueWithCalculation {
+    public:
+        explicit ValueWithCalculation(CSSParserValue&amp; value)
+            : m_value(value)
+        { }
+
+        CSSParserValue&amp; value() const { return m_value; }
+        operator CSSParserValue&amp;() { return m_value; }
+
+        RefPtr&lt;CSSCalcValue&gt; calculation() const { return m_calculation; }
+        void setCalculation(RefPtr&lt;CSSCalcValue&gt;&amp;&amp; calculation)
+        {
+            ASSERT(isCalculation(m_value));
+            m_calculation = calculation;
+        }
+
+    private:
+        CSSParserValue&amp; m_value;
+        RefPtr&lt;CSSCalcValue&gt; m_calculation;
+    };
+
+    WEBCORE_EXPORT CSSParser(const CSSParserContext&amp;);
+    WEBCORE_EXPORT ~CSSParser();
+
+    void parseSheet(StyleSheetContents*, const String&amp;, const TextPosition&amp;, RuleSourceDataList*, bool logErrors);
+    RefPtr&lt;StyleRuleBase&gt; parseRule(StyleSheetContents*, const String&amp;);
+    RefPtr&lt;StyleKeyframe&gt; parseKeyframeRule(StyleSheetContents*, const String&amp;);
+    bool parseSupportsCondition(const String&amp;);
+
+    static ParseResult parseValue(MutableStyleProperties&amp;, CSSPropertyID, const String&amp;, bool important, CSSParserMode, StyleSheetContents*);
+    static ParseResult parseCustomPropertyValue(MutableStyleProperties&amp;, const AtomicString&amp; propertyName, const String&amp;, bool important, CSSParserMode, StyleSheetContents* contextStyleSheet);
+
+    static bool parseColor(RGBA32&amp; color, const String&amp;, bool strict = false);
+    static bool isValidSystemColorValue(CSSValueID);
+    static bool parseSystemColor(RGBA32&amp; color, const String&amp;, Document*);
+    static RefPtr&lt;CSSValueList&gt; parseFontFaceValue(const AtomicString&amp;);
+    RefPtr&lt;CSSPrimitiveValue&gt; parseValidPrimitive(CSSValueID ident, ValueWithCalculation&amp;);
+
+    WEBCORE_EXPORT bool parseDeclaration(MutableStyleProperties&amp;, const String&amp;, RefPtr&lt;CSSRuleSourceData&gt;&amp;&amp;, StyleSheetContents* contextStyleSheet);
+    static Ref&lt;ImmutableStyleProperties&gt; parseInlineStyleDeclaration(const String&amp;, Element*);
+    std::unique_ptr&lt;MediaQuery&gt; parseMediaQuery(const String&amp;);
+
+    void addPropertyWithPrefixingVariant(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;&amp;, bool important, bool implicit = false);
+    void addProperty(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;&amp;, bool important, bool implicit = false);
+    void rollbackLastProperties(int num);
+    bool hasProperties() const { return !m_parsedProperties.isEmpty(); }
+    void addExpandedPropertyForValue(CSSPropertyID propId, Ref&lt;CSSValue&gt;&amp;&amp;, bool);
+
+    bool parseValue(CSSPropertyID, bool important);
+    bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&amp;, bool important);
+    bool parse4Values(CSSPropertyID, const CSSPropertyID* properties, bool important);
+    bool parseContent(CSSPropertyID, bool important);
+    bool parseQuotes(CSSPropertyID, bool important);
+    bool parseAlt(CSSPropertyID, bool important);
+    
+    bool parseCustomPropertyDeclaration(bool important, CSSValueID);
+    
+    RefPtr&lt;CSSPrimitiveValue&gt; parseAttr(CSSParserValueList&amp; args);
+
+    RefPtr&lt;CSSPrimitiveValue&gt; parseBackgroundColor();
+
+    struct SourceSize {
+        MediaQueryExpression expression;
+        Ref&lt;CSSValue&gt; length;
+
+        SourceSize(SourceSize&amp;&amp;);
+        SourceSize(MediaQueryExpression&amp;&amp;, Ref&lt;CSSValue&gt;&amp;&amp;);
+    };
+    Vector&lt;SourceSize&gt; parseSizesAttribute(StringView);
+    Optional&lt;SourceSize&gt; sourceSize(MediaQueryExpression&amp;&amp;, CSSParserValue&amp;);
+
+    bool parseFillImage(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+
+    enum FillPositionFlag { InvalidFillPosition = 0, AmbiguousFillPosition = 1, XFillPosition = 2, YFillPosition = 4 };
+    enum FillPositionParsingMode { ResolveValuesAsPercent = 0, ResolveValuesAsKeyword = 1 };
+    RefPtr&lt;CSSPrimitiveValue&gt; parseFillPositionComponent(CSSParserValueList&amp;, unsigned&amp; cumulativeFlags, FillPositionFlag&amp; individualFlag, FillPositionParsingMode = ResolveValuesAsPercent);
+    RefPtr&lt;CSSPrimitiveValue&gt; parsePositionX(CSSParserValueList&amp;);
+    RefPtr&lt;CSSPrimitiveValue&gt; parsePositionY(CSSParserValueList&amp;);
+    void parse2ValuesFillPosition(CSSParserValueList&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
+    bool isPotentialPositionValue(CSSParserValue&amp;);
+    void parseFillPosition(CSSParserValueList&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
+    void parse3ValuesFillPosition(CSSParserValueList&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp;, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp;);
+    void parse4ValuesFillPosition(CSSParserValueList&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp;, Ref&lt;CSSPrimitiveValue&gt;&amp;&amp;);
+
+    void parseFillRepeat(RefPtr&lt;CSSValue&gt;&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+    RefPtr&lt;CSSPrimitiveValue&gt; parseFillSize(CSSPropertyID, bool &amp;allowComma);
+
+    bool parseFillProperty(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2, RefPtr&lt;CSSValue&gt;&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+    bool parseFillShorthand(CSSPropertyID, const CSSPropertyID* properties, int numProperties, bool important);
+
+    void addFillValue(RefPtr&lt;CSSValue&gt;&amp; lval, Ref&lt;CSSValue&gt;&amp;&amp; rval);
+    void addAnimationValue(RefPtr&lt;CSSValue&gt;&amp; lval, Ref&lt;CSSValue&gt;&amp;&amp; rval);
+
+    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationDelay();
+    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationDirection();
+    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationDuration();
+    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationFillMode();
+    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationIterationCount();
+    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationName();
+    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationPlayState();
+    RefPtr&lt;CSSPrimitiveValue&gt; parseAnimationProperty(AnimationParseContext&amp;);
+    RefPtr&lt;CSSValue&gt; parseAnimationTimingFunction();
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+    RefPtr&lt;CSSValue&gt; parseAnimationTrigger();
+#endif
+    static Vector&lt;double&gt; parseKeyframeSelector(const String&amp;);
+
+    bool parseTransformOriginShorthand(RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+    Optional&lt;double&gt; parseCubicBezierTimingFunctionValue(CSSParserValueList&amp;);
+    Optional&lt;double&gt; parseSpringTimingFunctionValue(CSSParserValueList&amp;);
+    bool parseAnimationProperty(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;, AnimationParseContext&amp;);
+    bool parseTransitionShorthand(CSSPropertyID, bool important);
+    bool parseAnimationShorthand(CSSPropertyID, bool important);
+
+    bool isSpringTimingFunctionEnabled() const;
+
+    RefPtr&lt;CSSPrimitiveValue&gt; parseColumnWidth();
+    RefPtr&lt;CSSPrimitiveValue&gt; parseColumnCount();
+    bool parseColumnsShorthand(bool important);
+
+#if ENABLE(IOS_TEXT_AUTOSIZING)
+    bool isTextAutosizingEnabled() const;
+#endif
+
+#if ENABLE(CSS_GRID_LAYOUT)
+    bool isCSSGridLayoutEnabled() const;
+    RefPtr&lt;CSSValue&gt; parseGridPosition();
+    bool parseGridItemPositionShorthand(CSSPropertyID, bool important);
+    enum TrackListType { GridTemplate, GridTemplateNoRepeat, GridAuto };
+    RefPtr&lt;CSSValue&gt; parseGridTemplateColumns(TrackListType = GridTemplate);
+    bool parseGridTemplateRowsAndAreasAndColumns(bool important);
+    bool parseGridTemplateShorthand(bool important);
+    bool parseGridShorthand(bool important);
+    bool parseGridAreaShorthand(bool important);
+    bool parseGridGapShorthand(bool important);
+    bool parseSingleGridAreaLonghand(RefPtr&lt;CSSValue&gt;&amp;);
+    RefPtr&lt;CSSValue&gt; parseGridTrackList(TrackListType);
+    bool parseGridTrackRepeatFunction(CSSValueList&amp;, bool&amp; isAutoRepeat, bool&amp; allTracksAreFixedSized);
+    RefPtr&lt;CSSValue&gt; parseGridTrackSize(CSSParserValueList&amp; inputList);
+    RefPtr&lt;CSSPrimitiveValue&gt; parseGridBreadth(CSSParserValue&amp;);
+    bool parseGridTemplateAreasRow(NamedGridAreaMap&amp;, const unsigned, unsigned&amp;);
+    RefPtr&lt;CSSValue&gt; parseGridTemplateAreas();
+    bool parseGridLineNames(CSSParserValueList&amp;, CSSValueList&amp;, CSSGridLineNamesValue* = nullptr);
+    RefPtr&lt;CSSValue&gt; parseGridAutoFlow(CSSParserValueList&amp;);
+#endif
+
+    bool parseDashboardRegions(CSSPropertyID, bool important);
+
+    bool parseClipShape(CSSPropertyID, bool important);
+
+    bool parseLegacyPosition(CSSPropertyID, bool important);
+    bool parseItemPositionOverflowPosition(CSSPropertyID, bool important);
+    RefPtr&lt;CSSContentDistributionValue&gt; parseContentDistributionOverflowPosition();
+
+#if ENABLE(CSS_SHAPES)
+    RefPtr&lt;CSSValue&gt; parseShapeProperty(CSSPropertyID);
+#endif
+
+    RefPtr&lt;CSSValueList&gt; parseBasicShapeAndOrBox(CSSPropertyID propId);
+    RefPtr&lt;CSSPrimitiveValue&gt; parseBasicShape();
+    RefPtr&lt;CSSPrimitiveValue&gt; parseShapeRadius(CSSParserValue&amp;);
+    RefPtr&lt;CSSBasicShapeCircle&gt; parseBasicShapeCircle(CSSParserValueList&amp;);
+    RefPtr&lt;CSSBasicShapeEllipse&gt; parseBasicShapeEllipse(CSSParserValueList&amp;);
+    RefPtr&lt;CSSBasicShapePolygon&gt; parseBasicShapePolygon(CSSParserValueList&amp;);
+    RefPtr&lt;CSSBasicShapePath&gt; parseBasicShapePath(CSSParserValueList&amp;);
+    RefPtr&lt;CSSBasicShapeInset&gt; parseBasicShapeInset(CSSParserValueList&amp;);
+
+    bool parseFont(bool important);
+    void parseSystemFont(bool important);
+    RefPtr&lt;CSSValueList&gt; parseFontFamily();
+
+    bool parseCounter(CSSPropertyID, int defaultValue, bool important);
+    RefPtr&lt;CSSPrimitiveValue&gt; parseCounterContent(CSSParserValueList&amp; args, bool counters);
+
+    bool parseColorParameters(CSSParserValue&amp;, int* colorValues, bool parseAlpha);
+    bool parseHSLParameters(CSSParserValue&amp;, double* colorValues, bool parseAlpha);
+    RefPtr&lt;CSSPrimitiveValue&gt; parseColor(CSSParserValue* = nullptr);
+    bool parseColorFromValue(CSSParserValue&amp;, RGBA32&amp;);
+    void parseSelector(const String&amp;, CSSSelectorList&amp;);
+
+    template&lt;typename StringType&gt;
+    static bool fastParseColor(RGBA32&amp;, const StringType&amp;, bool strict);
+
+    bool parseLineHeight(bool important);
+    bool parseFontSize(bool important);
+    bool parseFontWeight(bool important);
+    bool parseFontSynthesis(bool important);
+    bool parseFontFaceSrc();
+    bool parseFontFaceUnicodeRange();
+
+    bool parseSVGValue(CSSPropertyID propId, bool important);
+    RefPtr&lt;SVGPaint&gt; parseSVGPaint();
+    RefPtr&lt;SVGColor&gt; parseSVGColor();
+    RefPtr&lt;CSSValueList&gt; parseSVGStrokeDasharray();
+    RefPtr&lt;CSSValueList&gt; parsePaintOrder();
+
+    // CSS3 Parsing Routines (for properties specific to CSS3)
+    RefPtr&lt;CSSValueList&gt; parseShadow(CSSParserValueList&amp;, CSSPropertyID);
+    bool parseBorderImage(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;, bool important = false);
+    bool parseBorderImageRepeat(RefPtr&lt;CSSValue&gt;&amp;);
+    bool parseBorderImageSlice(CSSPropertyID, RefPtr&lt;CSSBorderImageSliceValue&gt;&amp;);
+    bool parseBorderImageWidth(RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
+    bool parseBorderImageOutset(RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
+    bool parseBorderRadius(CSSPropertyID, bool important);
+
+    bool parseAspectRatio(bool important);
+
+    bool parseReflect(CSSPropertyID, bool important);
+
+    bool parseFlex(CSSParserValueList&amp; args, bool important);
+
+    // Image generators
+    bool parseCanvas(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+    bool parseNamedImage(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+
+    bool parseDeprecatedGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+    bool parseDeprecatedLinearGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, CSSGradientRepeat repeating);
+    bool parseDeprecatedRadialGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, CSSGradientRepeat repeating);
+    bool parseLinearGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, CSSGradientRepeat repeating);
+    bool parseRadialGradient(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, CSSGradientRepeat repeating);
+    bool parseGradientColorStops(CSSParserValueList&amp;, CSSGradientValue&amp;, bool expectComma);
+
+    bool parseCrossfade(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;, bool prefixed);
+
+#if ENABLE(CSS_IMAGE_RESOLUTION)
+    RefPtr&lt;CSSValueList&gt; parseImageResolution();
+#endif
+
+    RefPtr&lt;CSSImageSetValue&gt; parseImageSet();
+
+    bool parseFilterImage(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+
+    bool parseFilter(CSSParserValueList&amp;, RefPtr&lt;CSSValueList&gt;&amp;);
+    RefPtr&lt;WebKitCSSFilterValue&gt; parseBuiltinFilterArguments(CSSParserValueList&amp;, WebKitCSSFilterValue::FilterOperationType);
+
+    RefPtr&lt;CSSValue&gt; parseClipPath();
+
+    static bool isBlendMode(CSSValueID);
+    static bool isCompositeOperator(CSSValueID);
+
+    RefPtr&lt;CSSValueList&gt; parseTransform();
+    RefPtr&lt;WebKitCSSTransformValue&gt; parseTransformValue(CSSParserValue&amp;);
+    bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2, CSSPropertyID&amp; propId3, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+    bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID&amp; propId1, CSSPropertyID&amp; propId2,  RefPtr&lt;CSSPrimitiveValue&gt;&amp;, RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
+
+    bool parseTextEmphasisStyle(bool important);
+    bool parseTextEmphasisPosition(bool important);
+
+    void addTextDecorationProperty(CSSPropertyID, RefPtr&lt;CSSValue&gt;&amp;&amp;, bool important);
+    bool parseTextDecoration(CSSPropertyID propId, bool important);
+    bool parseTextDecorationSkip(bool important);
+    bool parseTextUnderlinePosition(bool important);
+
+    RefPtr&lt;CSSValueList&gt; parseTextIndent();
+    
+    bool parseHangingPunctuation(bool important);
+
+    bool parseLineBoxContain(bool important);
+    RefPtr&lt;CSSCalcValue&gt; parseCalculation(CSSParserValue&amp;, CalculationPermittedValueRange);
+
+    bool parseFontFeatureTag(CSSValueList&amp;);
+    bool parseFontFeatureSettings(bool important);
+
+    bool parseFlowThread(CSSPropertyID, bool important);
+    bool parseRegionThread(CSSPropertyID, bool important);
+
+    bool parseFontVariantLigatures(bool important, bool unknownIsFailure, bool implicit);
+    bool parseFontVariantNumeric(bool important, bool unknownIsFailure, bool implicit);
+    bool parseFontVariantEastAsian(bool important, bool unknownIsFailure, bool implicit);
+    bool parseFontVariant(bool important);
+
+    bool parseWillChange(bool important);
+
+    // Faster than doing a new/delete each time since it keeps one vector.
+    std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; createSelectorVector();
+    void recycleSelectorVector(std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt;);
+
+    RefPtr&lt;StyleRuleImport&gt; createImportRule(const CSSParserString&amp;, RefPtr&lt;MediaQuerySet&gt;&amp;&amp;);
+    RefPtr&lt;StyleKeyframe&gt; createKeyframe(CSSParserValueList&amp;);
+    Ref&lt;StyleRuleKeyframes&gt; createKeyframesRule(const String&amp;, std::unique_ptr&lt;Vector&lt;RefPtr&lt;StyleKeyframe&gt;&gt;&gt;);
+
+    typedef Vector&lt;RefPtr&lt;StyleRuleBase&gt;&gt; RuleList;
+    Ref&lt;StyleRuleMedia&gt; createMediaRule(RefPtr&lt;MediaQuerySet&gt;&amp;&amp;, RuleList*);
+    Ref&lt;StyleRuleMedia&gt; createEmptyMediaRule(RuleList*);
+    RefPtr&lt;StyleRule&gt; createStyleRule(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* selectors);
+    RefPtr&lt;StyleRuleFontFace&gt; createFontFaceRule();
+    RefPtr&lt;StyleRulePage&gt; createPageRule(std::unique_ptr&lt;CSSParserSelector&gt; pageSelector);
+    RefPtr&lt;StyleRuleRegion&gt; createRegionRule(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* regionSelector, RuleList* rules);
+    void createMarginAtRule(CSSSelector::MarginBoxType);
+    Ref&lt;StyleRuleSupports&gt; createSupportsRule(bool conditionIsSupported, RuleList*);
+    void markSupportsRuleHeaderStart();
+    void markSupportsRuleHeaderEnd();
+    Ref&lt;CSSRuleSourceData&gt; popSupportsRuleData();
+
+    void startDeclarationsForMarginBox();
+    void endDeclarationsForMarginBox();
+
+    void addNamespace(const AtomicString&amp; prefix, const AtomicString&amp; uri);
+    QualifiedName determineNameInNamespace(const AtomicString&amp; prefix, const AtomicString&amp; localName);
+
+    void rewriteSpecifiersWithElementName(const AtomicString&amp; namespacePrefix, const AtomicString&amp; elementName, CSSParserSelector&amp;);
+    void rewriteSpecifiersWithElementName(const QualifiedName&amp; tagName, CSSParserSelector&amp;, bool isNamespacePlaceholder = false);
+    void rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector&amp;);
+    std::unique_ptr&lt;CSSParserSelector&gt; rewriteSpecifiers(std::unique_ptr&lt;CSSParserSelector&gt;, std::unique_ptr&lt;CSSParserSelector&gt;);
+
+    void invalidBlockHit();
+
+    void updateLastSelectorLineAndPosition();
+    void updateLastMediaLine(MediaQuerySet&amp;);
+
+    void clearProperties();
+
+    Ref&lt;ImmutableStyleProperties&gt; createStyleProperties();
+
+    static const unsigned invalidParsedPropertiesCount;
+
+    CSSParserContext m_context;
+
+    bool m_important { false };
+    CSSPropertyID m_id { CSSPropertyInvalid };
+    AtomicString m_customPropertyName;
+    StyleSheetContents* m_styleSheet { nullptr };
+    RefPtr&lt;StyleRuleBase&gt; m_rule;
+    RefPtr&lt;StyleKeyframe&gt; m_keyframe;
+    std::unique_ptr&lt;MediaQuery&gt; m_mediaQuery;
+    std::unique_ptr&lt;Vector&lt;SourceSize&gt;&gt; m_sourceSizeList;
+    std::unique_ptr&lt;CSSParserValueList&gt; m_valueList;
+    bool m_supportsCondition { false };
+
+    ParsedPropertyVector m_parsedProperties;
+    CSSSelectorList* m_selectorListForParseSelector { nullptr };
+
+    unsigned m_numParsedPropertiesBeforeMarginBox { invalidParsedPropertiesCount };
+
+    int m_inParseShorthand { 0 };
+    CSSPropertyID m_currentShorthand { CSSPropertyInvalid };
+    bool m_implicitShorthand { false };
+
+    bool m_hadSyntacticallyValidCSSRule { false };
+    bool m_logErrors { false };
+    bool m_ignoreErrorsInDeclaration { false };
+
+    AtomicString m_defaultNamespace { starAtom };
+
+    // tokenizer methods and data
+    size_t m_parsedTextPrefixLength { 0 };
+    unsigned m_nestedSelectorLevel { 0 };
+    SourceRange m_selectorRange;
+    SourceRange m_propertyRange { std::numeric_limits&lt;unsigned&gt;::max(), std::numeric_limits&lt;unsigned&gt;::max() };
+    std::unique_ptr&lt;RuleSourceDataList&gt; m_currentRuleDataStack;
+    RefPtr&lt;CSSRuleSourceData&gt; m_currentRuleData;
+    RuleSourceDataList* m_ruleSourceDataResult { nullptr };
+
+    void fixUnparsedPropertyRanges(CSSRuleSourceData&amp;);
+    void markRuleHeaderStart(CSSRuleSourceData::Type);
+    void markRuleHeaderEnd();
+
+    void startNestedSelectorList() { ++m_nestedSelectorLevel; }
+    void endNestedSelectorList() { --m_nestedSelectorLevel; }
+    void markSelectorStart();
+    void markSelectorEnd();
+
+    void markRuleBodyStart();
+    void markRuleBodyEnd();
+    void markPropertyStart();
+    void markPropertyEnd(bool isImportantFound, bool isPropertyParsed);
+    void processAndAddNewRuleToSourceTreeIfNeeded();
+    void addNewRuleToSourceTree(Ref&lt;CSSRuleSourceData&gt;&amp;&amp;);
+    RefPtr&lt;CSSRuleSourceData&gt; popRuleData();
+    void resetPropertyRange() { m_propertyRange.start = m_propertyRange.end = std::numeric_limits&lt;unsigned&gt;::max(); }
+    bool isExtractingSourceData() const { return !!m_currentRuleDataStack; }
+    void syntaxError(const Location&amp;, SyntaxErrorType = GeneralSyntaxError);
+
+    inline int lex(void* yylval) { return (this-&gt;*m_lexFunc)(yylval); }
+
+    int token() { return m_token; }
+
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    void markViewportRuleBodyStart() { m_inViewport = true; }
+    void markViewportRuleBodyEnd() { m_inViewport = false; }
+    Ref&lt;StyleRuleViewport&gt; createViewportRule();
+#endif
+
+    Ref&lt;CSSPrimitiveValue&gt; createPrimitiveNumericValue(ValueWithCalculation&amp;);
+    Ref&lt;CSSPrimitiveValue&gt; createPrimitiveStringValue(CSSParserValue&amp;);
+
+    static URL completeURL(const CSSParserContext&amp;, const String&amp; url);
+
+    Location currentLocation();
+    static bool isCalculation(CSSParserValue&amp;);
+
+    void setCustomPropertyName(const AtomicString&amp; propertyName) { m_customPropertyName = propertyName; }
+
+    RefPtr&lt;CSSValue&gt; parseVariableDependentValue(CSSPropertyID, const CSSVariableDependentValue&amp;, const CustomPropertyValueMap&amp; customProperties, TextDirection, WritingMode);
+
+private:
+    bool is8BitSource() { return m_is8BitSource; }
+
+    template &lt;typename SourceCharacterType&gt;
+    int realLex(void* yylval);
+
+    UChar*&amp; currentCharacter16();
+
+    template &lt;typename CharacterType&gt;
+    inline CharacterType*&amp; currentCharacter();
+
+    template &lt;typename CharacterType&gt;
+    inline CharacterType* tokenStart();
+
+    template &lt;typename CharacterType&gt;
+    inline void setTokenStart(CharacterType*);
+
+    inline unsigned tokenStartOffset();
+    inline UChar tokenStartChar();
+
+    inline unsigned currentCharacterOffset();
+
+    template &lt;typename CharacterType&gt;
+    inline bool isIdentifierStart();
+
+    template &lt;typename CharacterType&gt;
+    unsigned parseEscape(CharacterType*&amp;);
+    template &lt;typename DestCharacterType&gt;
+    inline void UnicodeToChars(DestCharacterType*&amp;, unsigned);
+    template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
+    inline bool parseIdentifierInternal(SrcCharacterType*&amp;, DestCharacterType*&amp;, bool&amp;);
+
+    template &lt;typename CharacterType&gt;
+    inline void parseIdentifier(CharacterType*&amp;, CSSParserString&amp;, bool&amp;);
+
+    template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
+    inline bool parseStringInternal(SrcCharacterType*&amp;, DestCharacterType*&amp;, UChar);
+
+    template &lt;typename CharacterType&gt;
+    inline void parseString(CharacterType*&amp;, CSSParserString&amp; resultString, UChar);
+
+    template &lt;typename CharacterType&gt;
+    inline bool findURI(CharacterType*&amp; start, CharacterType*&amp; end, UChar&amp; quote);
+
+    template &lt;typename SrcCharacterType, typename DestCharacterType&gt;
+    inline bool parseURIInternal(SrcCharacterType*&amp;, DestCharacterType*&amp;, UChar quote);
+
+    template &lt;typename CharacterType&gt;
+    inline void parseURI(CSSParserString&amp;);
+    template &lt;typename CharacterType&gt;
+    inline bool parseUnicodeRange();
+    template &lt;typename CharacterType&gt;
+    bool parseNthChild();
+    template &lt;typename CharacterType&gt;
+    bool parseNthChildExtra();
+    template &lt;typename CharacterType&gt;
+    inline bool detectFunctionTypeToken(int);
+    template &lt;typename CharacterType&gt;
+    inline void detectMediaQueryToken(int);
+    template &lt;typename CharacterType&gt;
+    inline void detectNumberToken(CharacterType*, int);
+    template &lt;typename CharacterType&gt;
+    inline void detectDashToken(int);
+    template &lt;typename CharacterType&gt;
+    inline void detectAtToken(int, bool);
+    template &lt;typename CharacterType&gt;
+    inline void detectSupportsToken(int);
+
+    template &lt;typename CharacterType&gt;
+    inline void setRuleHeaderEnd(const CharacterType*);
+
+    void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
+
+    inline bool inStrictMode() const { return m_context.mode == CSSStrictMode || m_context.mode == SVGAttributeMode; }
+    inline bool inQuirksMode() const { return m_context.mode == CSSQuirksMode; }
+    
+    URL completeURL(const String&amp; url) const;
+
+    void recheckAtKeyword(const UChar* str, int len);
+
+    template&lt;unsigned prefixLength, unsigned suffixLength&gt;
+    void setupParser(const char (&amp;prefix)[prefixLength], StringView string, const char (&amp;suffix)[suffixLength])
+    {
+        setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
+    }
+    void setupParser(const char* prefix, unsigned prefixLength, StringView, const char* suffix, unsigned suffixLength);
+    bool inShorthand() const { return m_inParseShorthand; }
+
+    bool isValidSize(ValueWithCalculation&amp;);
+
+    bool isGeneratedImageValue(CSSParserValue&amp;) const;
+    bool parseGeneratedImage(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
+
+    ParseResult parseValue(MutableStyleProperties&amp;, CSSPropertyID, const String&amp;, bool important, StyleSheetContents* contextStyleSheet);
+    Ref&lt;ImmutableStyleProperties&gt; parseDeclaration(const String&amp;, StyleSheetContents* contextStyleSheet);
+
+    RefPtr&lt;CSSBasicShapeInset&gt; parseInsetRoundedCorners(Ref&lt;CSSBasicShapeInset&gt;&amp;&amp;, CSSParserValueList&amp;);
+
+    enum SizeParameterType {
+        None,
+        Auto,
+        Length,
+        PageSize,
+        Orientation,
+    };
+
+    bool parsePage(CSSPropertyID propId, bool important);
+    bool parseSize(CSSPropertyID propId, bool important);
+    SizeParameterType parseSizeParameter(CSSValueList&amp; parsedValues, CSSParserValue&amp;, SizeParameterType prevParamType);
+
+#if ENABLE(CSS_SCROLL_SNAP)
+    bool parseNonElementSnapPoints(CSSPropertyID propId, bool important);
+    bool parseScrollSnapDestination(CSSPropertyID propId, bool important);
+    bool parseScrollSnapCoordinate(CSSPropertyID propId, bool important);
+    bool parseScrollSnapPositions(RefPtr&lt;CSSValue&gt;&amp; cssValueX, RefPtr&lt;CSSValue&gt;&amp; cssValueY);
+#endif
+
+    bool parseFontFaceSrcURI(CSSValueList&amp;);
+    bool parseFontFaceSrcLocal(CSSValueList&amp;);
+
+    bool parseColor(const String&amp;);
+
+#if ENABLE(CSS_GRID_LAYOUT)
+    bool parseIntegerOrCustomIdentFromGridPosition(RefPtr&lt;CSSPrimitiveValue&gt;&amp; numericValue, RefPtr&lt;CSSPrimitiveValue&gt;&amp; gridLineName);
+#endif
+
+    enum ParsingMode {
+        NormalMode,
+        MediaQueryMode,
+        SupportsMode,
+        NthChildMode
+    };
+
+    ParsingMode m_parsingMode { NormalMode };
+    bool m_is8BitSource { false };
+    std::unique_ptr&lt;LChar[]&gt; m_dataStart8;
+    std::unique_ptr&lt;UChar[]&gt; m_dataStart16;
+    LChar* m_currentCharacter8 { nullptr };
+    UChar* m_currentCharacter16 { nullptr };
+    union {
+        LChar* ptr8;
+        UChar* ptr16;
+    } m_tokenStart { nullptr };
+    unsigned m_length { 0 };
+    int m_token { 0 };
+    int m_lineNumber { 0 };
+    int m_tokenStartLineNumber { 0 };
+    int m_tokenStartColumnNumber { 0 };
+    int m_lastSelectorLineNumber { 0 };
+    int m_columnOffsetForLine { 0 };
+
+    int m_sheetStartLineNumber { 0 };
+    int m_sheetStartColumnNumber { 0 };
+
+    bool m_allowImportRules { true };
+    bool m_allowNamespaceDeclarations { true };
+
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    bool parseViewportProperty(CSSPropertyID propId, bool important);
+    bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
+
+    bool inViewport() const { return m_inViewport; }
+    bool m_inViewport { false };
+#endif
+
+    bool useLegacyBackgroundSizeShorthandBehavior() const;
+
+    int (CSSParser::*m_lexFunc)(void*);
+
+    std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; m_recycledSelectorVector;
+
+    std::unique_ptr&lt;RuleSourceDataList&gt; m_supportsRuleDataStack;
+
+    // defines units allowed for a certain property, used in parseUnit
+    enum Units {
+        FUnknown = 0x0000,
+        FInteger = 0x0001,
+        FNumber = 0x0002, // Real Numbers
+        FPercent = 0x0004,
+        FLength = 0x0008,
+        FAngle = 0x0010,
+        FTime = 0x0020,
+        FFrequency = 0x0040,
+        FPositiveInteger = 0x0080,
+        FRelative = 0x0100,
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
+        FResolution = 0x0200,
+#endif
+        FNonNeg = 0x0400
+    };
+
+    friend inline Units operator|(Units a, Units b)
+    {
+        return static_cast&lt;Units&gt;(static_cast&lt;unsigned&gt;(a) | static_cast&lt;unsigned&gt;(b));
+    }
+
+    enum ReleaseParsedCalcValueCondition {
+        ReleaseParsedCalcValue,
+        DoNotReleaseParsedCalcValue
+    };
+
+    bool isLoggingErrors();
+    void logError(const String&amp; message, int lineNumber, int columnNumber);
+
+    bool validateCalculationUnit(ValueWithCalculation&amp;, Units);
+
+    bool shouldAcceptUnitLessValues(CSSParserValue&amp;, Units, CSSParserMode);
+
+    inline bool validateUnit(ValueWithCalculation&amp; value, Units unitFlags) { return validateUnit(value, unitFlags, m_context.mode); }
+    bool validateUnit(ValueWithCalculation&amp;, Units, CSSParserMode);
+
+    bool parseBorderImageQuad(Units, RefPtr&lt;CSSPrimitiveValue&gt;&amp;);
+    int colorIntFromValue(ValueWithCalculation&amp;);
+    double parsedDouble(ValueWithCalculation&amp;);
+    
+    friend class TransformOperationInfo;
+    friend class FilterOperationInfo;
+};
+
+CSSPropertyID cssPropertyID(const CSSParserString&amp;);
+CSSPropertyID cssPropertyID(const String&amp;);
+CSSValueID cssValueKeywordID(const CSSParserString&amp;);
+#if PLATFORM(IOS)
+void cssPropertyNameIOSAliasing(const char* propertyName, const char*&amp; propertyNameAlias, unsigned&amp; newLength);
+#endif
+
+class ShorthandScope {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    ShorthandScope(CSSParser* parser, CSSPropertyID propId) : m_parser(parser)
+    {
+        if (!(m_parser-&gt;m_inParseShorthand++))
+            m_parser-&gt;m_currentShorthand = propId;
+    }
+    ~ShorthandScope()
+    {
+        if (!(--m_parser-&gt;m_inParseShorthand))
+            m_parser-&gt;m_currentShorthand = CSSPropertyInvalid;
+    }
+
+private:
+    CSSParser* m_parser;
+};
+
+struct CSSParser::Location {
+    int lineNumber;
+    int columnNumber;
+    CSSParserString token;
+};
+
+String quoteCSSString(const String&amp;);
+String quoteCSSStringIfNeeded(const String&amp;);
+String quoteCSSURLIfNeeded(const String&amp;);
+
+bool isValidNthToken(const CSSParserString&amp;);
+
+template &lt;&gt;
+inline void CSSParser::setTokenStart&lt;LChar&gt;(LChar* tokenStart)
+{
+    m_tokenStart.ptr8 = tokenStart;
+}
+
+template &lt;&gt;
+inline void CSSParser::setTokenStart&lt;UChar&gt;(UChar* tokenStart)
+{
+    m_tokenStart.ptr16 = tokenStart;
+}
+
+inline unsigned CSSParser::tokenStartOffset()
+{
+    if (is8BitSource())
+        return m_tokenStart.ptr8 - m_dataStart8.get();
+    return m_tokenStart.ptr16 - m_dataStart16.get();
+}
+
+unsigned CSSParser::currentCharacterOffset()
+{
+    if (is8BitSource())
+        return m_currentCharacter8 - m_dataStart8.get();
+    return m_currentCharacter16 - m_dataStart16.get();
+}
+
+inline UChar CSSParser::tokenStartChar()
+{
+    if (is8BitSource())
+        return *m_tokenStart.ptr8;
+    return *m_tokenStart.ptr16;
+}
+
+inline bool isCustomPropertyName(const String&amp; propertyName)
+{
+    return propertyName.length() &gt; 2 &amp;&amp; propertyName.characterAt(0) == '-' &amp;&amp; propertyName.characterAt(1) == '-';
+}
+
+inline int cssyylex(void* yylval, CSSParser* parser)
+{
+    return parser-&gt;lex(yylval);
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserModehfromrev204839trunkSourceWebCorecssCSSParserModeh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/css/parser/CSSParserMode.h (from rev 204839, trunk/Source/WebCore/css/CSSParserMode.h) (0 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserMode.h                                (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSParserMode.h        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -0,0 +1,86 @@
</span><ins>+/*
+ * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef CSSParserMode_h
+#define CSSParserMode_h
+
+#include &quot;URL.h&quot;
+
+namespace WebCore {
+
+class Document;
+
+enum CSSParserMode {
+    CSSQuirksMode,
+    CSSStrictMode,
+    // SVG should always be in strict mode. For SVG attributes, the rules differ to strict sometimes.
+    SVGAttributeMode
+};
+
+inline CSSParserMode strictToCSSParserMode(bool inStrictMode)
+{
+    return inStrictMode ? CSSStrictMode : CSSQuirksMode;
+}
+
+inline bool isStrictParserMode(CSSParserMode cssParserMode)
+{
+    return cssParserMode == CSSStrictMode || cssParserMode == SVGAttributeMode;
+}
+
+struct CSSParserContext {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    CSSParserContext(CSSParserMode, const URL&amp; baseURL = URL());
+    WEBCORE_EXPORT CSSParserContext(Document&amp;, const URL&amp; baseURL = URL(), const String&amp; charset = emptyString());
+
+    URL baseURL;
+    String charset;
+    CSSParserMode mode { CSSStrictMode };
+    bool isHTMLDocument { false };
+#if ENABLE(CSS_GRID_LAYOUT)
+    bool cssGridLayoutEnabled { false };
+#endif
+#if ENABLE(IOS_TEXT_AUTOSIZING)
+    bool textAutosizingEnabled { false };
+#endif
+    bool needsSiteSpecificQuirks { false };
+    bool enforcesCSSMIMETypeInNoQuirksMode { true };
+    bool useLegacyBackgroundSizeShorthandBehavior { false };
+    bool springTimingFunctionEnabled { false };
+};
+
+bool operator==(const CSSParserContext&amp;, const CSSParserContext&amp;);
+inline bool operator!=(const CSSParserContext&amp; a, const CSSParserContext&amp; b) { return !(a == b); }
+
+WEBCORE_EXPORT const CSSParserContext&amp; strictCSSParserContext();
+
+};
+
+#endif // CSSParserMode_h
</ins></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserValuescppfromrev204839trunkSourceWebCorecssCSSParserValuescpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/css/parser/CSSParserValues.cpp (from rev 204839, trunk/Source/WebCore/css/CSSParserValues.cpp) (0 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserValues.cpp                                (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSParserValues.cpp        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -0,0 +1,446 @@
</span><ins>+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008, 2014 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;CSSParserValues.h&quot;
+
+#include &quot;CSSCustomPropertyValue.h&quot;
+#include &quot;CSSPrimitiveValue.h&quot;
+#include &quot;CSSFunctionValue.h&quot;
+#include &quot;CSSSelector.h&quot;
+#include &quot;CSSSelectorList.h&quot;
+#include &quot;CSSVariableValue.h&quot;
+#include &quot;SelectorPseudoTypeMap.h&quot;
+
+namespace WebCore {
+
+using namespace WTF;
+
+void destroy(const CSSParserValue&amp; value)
+{
+    if (value.unit == CSSParserValue::Function)
+        delete value.function;
+    else if (value.unit == CSSParserValue::ValueList)
+        delete value.valueList;
+    else if (value.unit == CSSParserValue::Variable)
+        delete value.variable;
+}
+
+CSSParserValueList::~CSSParserValueList()
+{
+    for (auto&amp; value : m_values)
+        destroy(value);
+}
+
+void CSSParserValueList::addValue(const CSSParserValue&amp; value)
+{
+    m_values.append(value);
+}
+
+void CSSParserValueList::insertValueAt(unsigned i, const CSSParserValue&amp; value)
+{
+    m_values.insert(i, value);
+}
+
+void CSSParserValueList::extend(CSSParserValueList&amp; other)
+{
+    for (auto&amp; value : other.m_values) {
+        m_values.append(value);
+        value.unit = 0; // We moved the CSSParserValue from the other list; this acts like std::move.
+    }
+}
+
+bool CSSParserValueList::containsVariables() const
+{
+    for (unsigned i = 0; i &lt; size(); i++) {
+        auto* parserValue = &amp;m_values[i];
+        if (parserValue-&gt;unit == CSSParserValue::Variable)
+            return true;
+        if (parserValue-&gt;unit == CSSParserValue::Function &amp;&amp; parserValue-&gt;function-&gt;args
+            &amp;&amp; parserValue-&gt;function-&gt;args-&gt;containsVariables())
+            return true;
+        if (parserValue-&gt;unit == CSSParserValue::ValueList &amp;&amp; parserValue-&gt;valueList-&gt;containsVariables())
+            return true;
+    }
+    return false;
+}
+
+RefPtr&lt;CSSValue&gt; CSSParserValue::createCSSValue()
+{
+    RefPtr&lt;CSSValue&gt; parsedValue;
+    if (id)
+        return CSSPrimitiveValue::createIdentifier(id);
+    
+    if (unit == CSSParserValue::Operator) {
+        auto primitiveValue = CSSPrimitiveValue::createParserOperator(iValue);
+        primitiveValue-&gt;setPrimitiveType(CSSPrimitiveValue::CSS_PARSER_OPERATOR);
+        return WTFMove(primitiveValue);
+    }
+    if (unit == CSSParserValue::Function)
+        return CSSFunctionValue::create(function);
+    if (unit == CSSParserValue::Variable)
+        return CSSVariableValue::create(variable);
+    if (unit == CSSParserValue::ValueList)
+        return CSSValueList::createFromParserValueList(*valueList);
+
+    if (unit &gt;= CSSParserValue::Q_EMS)
+        return CSSPrimitiveValue::createAllowingMarginQuirk(fValue, CSSPrimitiveValue::CSS_EMS);
+
+    CSSPrimitiveValue::UnitTypes primitiveUnit = static_cast&lt;CSSPrimitiveValue::UnitTypes&gt;(unit);
+    switch (primitiveUnit) {
+    case CSSPrimitiveValue::CSS_IDENT:
+    case CSSPrimitiveValue::CSS_PROPERTY_ID:
+    case CSSPrimitiveValue::CSS_VALUE_ID:
+        return CSSPrimitiveValue::create(string, CSSPrimitiveValue::CSS_PARSER_IDENTIFIER);
+    case CSSPrimitiveValue::CSS_NUMBER:
+        return CSSPrimitiveValue::create(fValue, isInt ? CSSPrimitiveValue::CSS_PARSER_INTEGER : CSSPrimitiveValue::CSS_NUMBER);
+    case CSSPrimitiveValue::CSS_STRING:
+    case CSSPrimitiveValue::CSS_URI:
+    case CSSPrimitiveValue::CSS_PARSER_HEXCOLOR:
+    case CSSPrimitiveValue::CSS_DIMENSION:
+    case CSSPrimitiveValue::CSS_UNICODE_RANGE:
+    case CSSPrimitiveValue::CSS_PARSER_WHITESPACE:
+        return CSSPrimitiveValue::create(string, primitiveUnit);
+    case CSSPrimitiveValue::CSS_PERCENTAGE:
+    case CSSPrimitiveValue::CSS_EMS:
+    case CSSPrimitiveValue::CSS_EXS:
+    case CSSPrimitiveValue::CSS_PX:
+    case CSSPrimitiveValue::CSS_CM:
+    case CSSPrimitiveValue::CSS_MM:
+    case CSSPrimitiveValue::CSS_IN:
+    case CSSPrimitiveValue::CSS_PT:
+    case CSSPrimitiveValue::CSS_PC:
+    case CSSPrimitiveValue::CSS_DEG:
+    case CSSPrimitiveValue::CSS_RAD:
+    case CSSPrimitiveValue::CSS_GRAD:
+    case CSSPrimitiveValue::CSS_MS:
+    case CSSPrimitiveValue::CSS_S:
+    case CSSPrimitiveValue::CSS_HZ:
+    case CSSPrimitiveValue::CSS_KHZ:
+    case CSSPrimitiveValue::CSS_VW:
+    case CSSPrimitiveValue::CSS_VH:
+    case CSSPrimitiveValue::CSS_VMIN:
+    case CSSPrimitiveValue::CSS_VMAX:
+    case CSSPrimitiveValue::CSS_TURN:
+    case CSSPrimitiveValue::CSS_REMS:
+    case CSSPrimitiveValue::CSS_CHS:
+    case CSSPrimitiveValue::CSS_FR:
+        return CSSPrimitiveValue::create(fValue, primitiveUnit);
+    case CSSPrimitiveValue::CSS_UNKNOWN:
+    case CSSPrimitiveValue::CSS_ATTR:
+    case CSSPrimitiveValue::CSS_COUNTER:
+    case CSSPrimitiveValue::CSS_RECT:
+    case CSSPrimitiveValue::CSS_RGBCOLOR:
+    case CSSPrimitiveValue::CSS_DPPX:
+    case CSSPrimitiveValue::CSS_DPI:
+    case CSSPrimitiveValue::CSS_DPCM:
+    case CSSPrimitiveValue::CSS_PAIR:
+#if ENABLE(DASHBOARD_SUPPORT)
+    case CSSPrimitiveValue::CSS_DASHBOARD_REGION:
+#endif
+    case CSSPrimitiveValue::CSS_PARSER_OPERATOR:
+    case CSSPrimitiveValue::CSS_PARSER_INTEGER:
+    case CSSPrimitiveValue::CSS_PARSER_IDENTIFIER:
+    case CSSPrimitiveValue::CSS_COUNTER_NAME:
+    case CSSPrimitiveValue::CSS_SHAPE:
+    case CSSPrimitiveValue::CSS_FONT_FAMILY:
+    case CSSPrimitiveValue::CSS_QUAD:
+#if ENABLE(CSS_SCROLL_SNAP)
+    case CSSPrimitiveValue::CSS_LENGTH_REPEAT:
+#endif
+    case CSSPrimitiveValue::CSS_CALC:
+    case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER:
+    case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH:
+        return nullptr;
+    }
+
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+CSSParserSelector* CSSParserSelector::parsePagePseudoSelector(const CSSParserString&amp; pseudoTypeString)
+{
+    CSSSelector::PagePseudoClassType pseudoType;
+    if (equalLettersIgnoringASCIICase(pseudoTypeString, &quot;first&quot;))
+        pseudoType = CSSSelector::PagePseudoClassFirst;
+    else if (equalLettersIgnoringASCIICase(pseudoTypeString, &quot;left&quot;))
+        pseudoType = CSSSelector::PagePseudoClassLeft;
+    else if (equalLettersIgnoringASCIICase(pseudoTypeString, &quot;right&quot;))
+        pseudoType = CSSSelector::PagePseudoClassRight;
+    else
+        return nullptr;
+
+    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
+    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PagePseudoClass);
+    selector-&gt;m_selector-&gt;setPagePseudoType(pseudoType);
+    return selector.release();
+}
+
+CSSParserSelector* CSSParserSelector::parsePseudoElementSelector(CSSParserString&amp; pseudoTypeString)
+{
+    pseudoTypeString.convertToASCIILowercaseInPlace();
+    AtomicString name = pseudoTypeString;
+
+    CSSSelector::PseudoElementType pseudoType = CSSSelector::parsePseudoElementType(name);
+    if (pseudoType == CSSSelector::PseudoElementUnknown)
+        return nullptr;
+
+    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
+    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoElement);
+    selector-&gt;m_selector-&gt;setPseudoElementType(pseudoType);
+    if (pseudoType == CSSSelector::PseudoElementWebKitCustomLegacyPrefixed) {
+        ASSERT_WITH_MESSAGE(name == &quot;-webkit-input-placeholder&quot;, &quot;-webkit-input-placeholder is the only LegacyPrefix pseudo type.&quot;);
+        if (name == &quot;-webkit-input-placeholder&quot;)
+            name = AtomicString(&quot;placeholder&quot;, AtomicString::ConstructFromLiteral);
+    }
+    selector-&gt;m_selector-&gt;setValue(name);
+    return selector.release();
+}
+
+#if ENABLE(VIDEO_TRACK)
+CSSParserSelector* CSSParserSelector::parsePseudoElementCueFunctionSelector(const CSSParserString&amp; functionIdentifier, Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;* parsedSelectorVector)
+{
+    ASSERT_UNUSED(functionIdentifier, String(functionIdentifier) == &quot;cue(&quot;);
+
+    std::unique_ptr&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt; selectorVector(parsedSelectorVector);
+
+    if (!selectorVector)
+        return nullptr;
+
+    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
+    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoElement);
+    selector-&gt;m_selector-&gt;setPseudoElementType(CSSSelector::PseudoElementCue);
+    selector-&gt;adoptSelectorVector(*selectorVector);
+    return selector.release();
+}
+#endif
+
+CSSParserSelector* CSSParserSelector::parsePseudoElementSlottedFunctionSelector(const CSSParserString&amp; functionIdentifier, CSSParserSelector* parsedSelector)
+{
+    ASSERT_UNUSED(functionIdentifier, String(functionIdentifier) == &quot;slotted(&quot;);
+
+    if (!parsedSelector)
+        return nullptr;
+
+    std::unique_ptr&lt;CSSParserSelector&gt; ownedParsedSelector(parsedSelector);
+
+    for (auto* component = parsedSelector; component; component = component-&gt;tagHistory()) {
+        if (component-&gt;matchesPseudoElement())
+            return nullptr;
+    }
+
+    auto selectorVector = std::make_unique&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt;();
+    selectorVector-&gt;append(WTFMove(ownedParsedSelector));
+
+    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
+    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoElement);
+    selector-&gt;m_selector-&gt;setPseudoElementType(CSSSelector::PseudoElementSlotted);
+    selector-&gt;adoptSelectorVector(*selectorVector);
+    return selector.release();
+}
+
+CSSParserSelector* CSSParserSelector::parsePseudoClassHostFunctionSelector(const CSSParserString&amp; functionIdentifier, CSSParserSelector* parsedSelector)
+{
+    ASSERT_UNUSED(functionIdentifier, String(functionIdentifier) == &quot;host(&quot;);
+
+    if (!parsedSelector)
+        return nullptr;
+
+    std::unique_ptr&lt;CSSParserSelector&gt; ownedParsedSelector(parsedSelector);
+
+    for (auto* component = parsedSelector; component; component = component-&gt;tagHistory()) {
+        if (component-&gt;matchesPseudoElement())
+            return nullptr;
+    }
+
+    auto selectorVector = std::make_unique&lt;Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&gt;();
+    selectorVector-&gt;append(WTFMove(ownedParsedSelector));
+
+    auto selector = std::make_unique&lt;CSSParserSelector&gt;();
+    selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoClass);
+    selector-&gt;m_selector-&gt;setPseudoClassType(CSSSelector::PseudoClassHost);
+    selector-&gt;adoptSelectorVector(*selectorVector);
+    return selector.release();
+}
+
+CSSParserSelector* CSSParserSelector::parsePseudoClassAndCompatibilityElementSelector(CSSParserString&amp; pseudoTypeString)
+{
+    if (pseudoTypeString.length() &amp;&amp; pseudoTypeString[pseudoTypeString.length() - 1] == '(')
+        return nullptr;
+
+    PseudoClassOrCompatibilityPseudoElement pseudoType = parsePseudoClassAndCompatibilityElementString(pseudoTypeString);
+    if (pseudoType.pseudoClass != CSSSelector::PseudoClassUnknown) {
+        auto selector = std::make_unique&lt;CSSParserSelector&gt;();
+        selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoClass);
+        selector-&gt;m_selector-&gt;setPseudoClassType(pseudoType.pseudoClass);
+        return selector.release();
+    }
+    if (pseudoType.compatibilityPseudoElement != CSSSelector::PseudoElementUnknown) {
+        auto selector = std::make_unique&lt;CSSParserSelector&gt;();
+        selector-&gt;m_selector-&gt;setMatch(CSSSelector::PseudoElement);
+        selector-&gt;m_selector-&gt;setPseudoElementType(pseudoType.compatibilityPseudoElement);
+        AtomicString name = pseudoTypeString;
+        selector-&gt;m_selector-&gt;setValue(name);
+        return selector.release();
+    }
+    return nullptr;
+}
+
+CSSParserSelector::CSSParserSelector()
+    : m_selector(std::make_unique&lt;CSSSelector&gt;())
+{
+}
+
+CSSParserSelector::CSSParserSelector(const QualifiedName&amp; tagQName)
+    : m_selector(std::make_unique&lt;CSSSelector&gt;(tagQName))
+{
+}
+
+CSSParserSelector::~CSSParserSelector()
+{
+    if (!m_tagHistory)
+        return;
+    Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;, 16&gt; toDelete;
+    std::unique_ptr&lt;CSSParserSelector&gt; selector = WTFMove(m_tagHistory);
+    while (true) {
+        std::unique_ptr&lt;CSSParserSelector&gt; next = WTFMove(selector-&gt;m_tagHistory);
+        toDelete.append(WTFMove(selector));
+        if (!next)
+            break;
+        selector = WTFMove(next);
+    }
+}
+
+void CSSParserSelector::adoptSelectorVector(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&amp; selectorVector)
+{
+    auto selectorList = std::make_unique&lt;CSSSelectorList&gt;();
+    selectorList-&gt;adoptSelectorVector(selectorVector);
+    m_selector-&gt;setSelectorList(WTFMove(selectorList));
+}
+
+void CSSParserSelector::setLangArgumentList(const Vector&lt;CSSParserString&gt;&amp; stringVector)
+{
+    ASSERT_WITH_MESSAGE(!stringVector.isEmpty(), &quot;No CSS Selector takes an empty argument list.&quot;);
+    auto argumentList = std::make_unique&lt;Vector&lt;AtomicString&gt;&gt;();
+    argumentList-&gt;reserveInitialCapacity(stringVector.size());
+    for (const AtomicString&amp; languageArgument : stringVector)
+        argumentList-&gt;append(languageArgument);
+    m_selector-&gt;setLangArgumentList(WTFMove(argumentList));
+}
+
+void CSSParserSelector::setPseudoClassValue(const CSSParserString&amp; pseudoClassString)
+{
+    ASSERT(m_selector-&gt;match() == CSSSelector::PseudoClass);
+
+    PseudoClassOrCompatibilityPseudoElement pseudoType = parsePseudoClassAndCompatibilityElementString(pseudoClassString);
+    m_selector-&gt;setPseudoClassType(pseudoType.pseudoClass);
+}
+
+static bool selectorListMatchesPseudoElement(const CSSSelectorList* selectorList)
+{
+    if (!selectorList)
+        return false;
+
+    for (const CSSSelector* subSelector = selectorList-&gt;first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
+        for (const CSSSelector* selector = subSelector; selector; selector = selector-&gt;tagHistory()) {
+            if (selector-&gt;matchesPseudoElement())
+                return true;
+            if (const CSSSelectorList* subselectorList = selector-&gt;selectorList()) {
+                if (selectorListMatchesPseudoElement(subselectorList))
+                    return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool CSSParserSelector::matchesPseudoElement() const
+{
+    return m_selector-&gt;matchesPseudoElement() || selectorListMatchesPseudoElement(m_selector-&gt;selectorList());
+}
+
+void CSSParserSelector::insertTagHistory(CSSSelector::Relation before, std::unique_ptr&lt;CSSParserSelector&gt; selector, CSSSelector::Relation after)
+{
+    if (m_tagHistory)
+        selector-&gt;setTagHistory(WTFMove(m_tagHistory));
+    setRelation(before);
+    selector-&gt;setRelation(after);
+    m_tagHistory = WTFMove(selector);
+}
+
+void CSSParserSelector::appendTagHistory(CSSSelector::Relation relation, std::unique_ptr&lt;CSSParserSelector&gt; selector)
+{
+    CSSParserSelector* end = this;
+    while (end-&gt;tagHistory())
+        end = end-&gt;tagHistory();
+
+    end-&gt;setRelation(relation);
+    end-&gt;setTagHistory(WTFMove(selector));
+}
+
+void CSSParserSelector::appendTagHistory(CSSParserSelectorCombinator relation, std::unique_ptr&lt;CSSParserSelector&gt; selector)
+{
+    CSSParserSelector* end = this;
+    while (end-&gt;tagHistory())
+        end = end-&gt;tagHistory();
+
+    CSSSelector::Relation selectorRelation;
+    switch (relation) {
+    case CSSParserSelectorCombinator::Child:
+        selectorRelation = CSSSelector::Child;
+        break;
+    case CSSParserSelectorCombinator::DescendantSpace:
+        selectorRelation = CSSSelector::Descendant;
+        break;
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+    case CSSParserSelectorCombinator::DescendantDoubleChild:
+        selectorRelation = CSSSelector::Descendant;
+        break;
+#endif
+    case CSSParserSelectorCombinator::DirectAdjacent:
+        selectorRelation = CSSSelector::DirectAdjacent;
+        break;
+    case CSSParserSelectorCombinator::IndirectAdjacent:
+        selectorRelation = CSSSelector::IndirectAdjacent;
+        break;
+    }
+    end-&gt;setRelation(selectorRelation);
+
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+    if (relation == CSSParserSelectorCombinator::DescendantDoubleChild)
+        end-&gt;setDescendantUseDoubleChildSyntax();
+#endif
+
+    end-&gt;setTagHistory(WTFMove(selector));
+}
+
+void CSSParserSelector::prependTagSelector(const QualifiedName&amp; tagQName, bool tagIsForNamespaceRule)
+{
+    auto second = std::make_unique&lt;CSSParserSelector&gt;();
+    second-&gt;m_selector = WTFMove(m_selector);
+    second-&gt;m_tagHistory = WTFMove(m_tagHistory);
+    m_tagHistory = WTFMove(second);
+
+    m_selector = std::make_unique&lt;CSSSelector&gt;(tagQName, tagIsForNamespaceRule);
+    m_selector-&gt;setRelation(CSSSelector::SubSelector);
+}
+
+}
+
</ins></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserValueshfromrev204839trunkSourceWebCorecssCSSParserValuesh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/css/parser/CSSParserValues.h (from rev 204839, trunk/Source/WebCore/css/CSSParserValues.h) (0 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserValues.h                                (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSParserValues.h        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -0,0 +1,276 @@
</span><ins>+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include &quot;CSSSelector.h&quot;
+#include &quot;CSSValueKeywords.h&quot;
+#include &quot;CSSValueList.h&quot;
+#include &lt;wtf/text/AtomicString.h&gt;
+#include &lt;wtf/text/AtomicStringHash.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+class CSSValue;
+class QualifiedName;
+
+// This should be a StringView but currently it can't because it's used as an element of a union in CSSParserValue.
+struct CSSParserString {
+    void init(LChar* characters, unsigned length)
+    {
+        m_data.characters8 = characters;
+        m_length = length;
+        m_is8Bit = true;
+    }
+
+    void init(UChar* characters, unsigned length)
+    {
+        m_data.characters16 = characters;
+        m_length = length;
+        m_is8Bit = false;
+    }
+
+    void init(const String&amp; string)
+    {
+        m_length = string.length();
+        if (!m_length || string.is8Bit()) {
+            m_data.characters8 = const_cast&lt;LChar*&gt;(string.characters8());
+            m_is8Bit = true;
+        } else {
+            m_data.characters16 = const_cast&lt;UChar*&gt;(string.characters16());
+            m_is8Bit = false;
+        }
+    }
+
+    void clear()
+    {
+        m_data.characters8 = 0;
+        m_length = 0;
+        m_is8Bit = true;
+    }
+
+    bool is8Bit() const { return m_is8Bit; }
+    LChar* characters8() const { ASSERT(is8Bit()); return m_data.characters8; }
+    UChar* characters16() const { ASSERT(!is8Bit()); return m_data.characters16; }
+    template&lt;typename CharacterType&gt; CharacterType* characters() const;
+
+    unsigned length() const { return m_length; }
+    void setLength(unsigned length) { m_length = length; }
+
+    void convertToASCIILowercaseInPlace();
+
+    UChar operator[](unsigned i) const
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(i &lt; m_length);
+        if (is8Bit())
+            return m_data.characters8[i];
+        return m_data.characters16[i];
+    }
+
+    operator String() const { return is8Bit() ? String(m_data.characters8, m_length) : String(m_data.characters16, m_length); }
+    operator AtomicString() const { return is8Bit() ? AtomicString(m_data.characters8, m_length) : AtomicString(m_data.characters16, m_length); }
+
+    union {
+        LChar* characters8;
+        UChar* characters16;
+    } m_data;
+    unsigned m_length;
+    bool m_is8Bit;
+};
+
+template&lt;unsigned length&gt; bool equalLettersIgnoringASCIICase(const CSSParserString&amp;, const char (&amp;lowercaseLetters)[length]);
+
+struct CSSParserFunction;
+struct CSSParserVariable;
+
+struct CSSParserValue {
+    CSSValueID id;
+    bool isInt;
+    union {
+        double fValue;
+        int iValue;
+        CSSParserString string;
+        CSSParserFunction* function;
+        CSSParserVariable* variable;
+        CSSParserValueList* valueList;
+    };
+    enum {
+        Operator  = 0x100000,
+        Function  = 0x100001,
+        ValueList = 0x100002,
+        Q_EMS     = 0x100003,
+        Variable  = 0x100004
+    };
+    int unit;
+
+    void setFromValueList(std::unique_ptr&lt;CSSParserValueList&gt;);
+
+    RefPtr&lt;CSSValue&gt; createCSSValue();
+};
+
+void destroy(const CSSParserValue&amp;);
+
+class CSSParserValueList {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    CSSParserValueList()
+        : m_current(0)
+    {
+    }
+    ~CSSParserValueList();
+
+    void addValue(const CSSParserValue&amp;);
+    void insertValueAt(unsigned, const CSSParserValue&amp;);
+    void extend(CSSParserValueList&amp;);
+
+    unsigned size() const { return m_values.size(); }
+    unsigned currentIndex() { return m_current; }
+    CSSParserValue* current() { return m_current &lt; m_values.size() ? &amp;m_values[m_current] : 0; }
+    CSSParserValue* next() { ++m_current; return current(); }
+    CSSParserValue* previous()
+    {
+        if (!m_current)
+            return 0;
+        --m_current;
+        return current();
+    }
+    void setCurrentIndex(unsigned index)
+    {
+        ASSERT(index &lt; m_values.size());
+        if (index &lt; m_values.size())
+            m_current = index;
+    }
+
+    CSSParserValue* valueAt(unsigned i) { return i &lt; m_values.size() ? &amp;m_values[i] : 0; }
+
+    void clear() { m_values.clear(); }
+    
+    String toString();
+    
+    bool containsVariables() const;
+
+private:
+    unsigned m_current;
+    Vector&lt;CSSParserValue, 4&gt; m_values;
+};
+
+struct CSSParserFunction {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    CSSParserString name;
+    std::unique_ptr&lt;CSSParserValueList&gt; args;
+};
+
+struct CSSParserVariable {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    CSSParserString name; // The custom property name
+    std::unique_ptr&lt;CSSParserValueList&gt; args; // The fallback args
+};
+
+enum class CSSParserSelectorCombinator {
+    Child,
+    DescendantSpace,
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+    DescendantDoubleChild,
+#endif
+    DirectAdjacent,
+    IndirectAdjacent
+};
+
+class CSSParserSelector {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static CSSParserSelector* parsePagePseudoSelector(const CSSParserString&amp; pseudoTypeString);
+    static CSSParserSelector* parsePseudoElementSelector(CSSParserString&amp; pseudoTypeString);
+    static CSSParserSelector* parsePseudoElementCueFunctionSelector(const CSSParserString&amp; functionIdentifier, Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;*);
+    static CSSParserSelector* parsePseudoElementSlottedFunctionSelector(const CSSParserString&amp; functionIdentifier, CSSParserSelector*);
+    static CSSParserSelector* parsePseudoClassHostFunctionSelector(const CSSParserString&amp; functionIdentifier, CSSParserSelector*);
+    static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString&amp; pseudoTypeString);
+
+    CSSParserSelector();
+    explicit CSSParserSelector(const QualifiedName&amp;);
+    ~CSSParserSelector();
+
+    std::unique_ptr&lt;CSSSelector&gt; releaseSelector() { return WTFMove(m_selector); }
+
+    void setValue(const AtomicString&amp; value) { m_selector-&gt;setValue(value); }
+    void setAttribute(const QualifiedName&amp; value, bool isCaseInsensitive) { m_selector-&gt;setAttribute(value, isCaseInsensitive); }
+    void setArgument(const AtomicString&amp; value) { m_selector-&gt;setArgument(value); }
+    void setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive) { m_selector-&gt;setAttributeValueMatchingIsCaseInsensitive(isCaseInsensitive); }
+    void setMatch(CSSSelector::Match value) { m_selector-&gt;setMatch(value); }
+    void setRelation(CSSSelector::Relation value) { m_selector-&gt;setRelation(value); }
+    void setForPage() { m_selector-&gt;setForPage(); }
+
+    void adoptSelectorVector(Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;&amp; selectorVector);
+    void setLangArgumentList(const Vector&lt;CSSParserString&gt;&amp; stringVector);
+
+    void setPseudoClassValue(const CSSParserString&amp; pseudoClassString);
+    CSSSelector::PseudoClassType pseudoClassType() const { return m_selector-&gt;pseudoClassType(); }
+    bool isCustomPseudoElement() const { return m_selector-&gt;isCustomPseudoElement(); }
+
+    bool isPseudoElementCueFunction() const
+    {
+#if ENABLE(VIDEO_TRACK)
+        return m_selector-&gt;match() == CSSSelector::PseudoElement &amp;&amp; m_selector-&gt;pseudoElementType() == CSSSelector::PseudoElementCue;
+#else
+        return false;
+#endif
+    }
+
+    bool hasShadowDescendant() const;
+    bool matchesPseudoElement() const;
+
+    CSSParserSelector* tagHistory() const { return m_tagHistory.get(); }
+    void setTagHistory(std::unique_ptr&lt;CSSParserSelector&gt; selector) { m_tagHistory = WTFMove(selector); }
+    void clearTagHistory() { m_tagHistory.reset(); }
+    void insertTagHistory(CSSSelector::Relation before, std::unique_ptr&lt;CSSParserSelector&gt;, CSSSelector::Relation after);
+    void appendTagHistory(CSSSelector::Relation, std::unique_ptr&lt;CSSParserSelector&gt;);
+    void appendTagHistory(CSSParserSelectorCombinator, std::unique_ptr&lt;CSSParserSelector&gt;);
+    void prependTagSelector(const QualifiedName&amp;, bool tagIsForNamespaceRule = false);
+
+private:
+#if ENABLE(CSS_SELECTORS_LEVEL4)
+    void setDescendantUseDoubleChildSyntax() { m_selector-&gt;setDescendantUseDoubleChildSyntax(); }
+#endif
+
+    std::unique_ptr&lt;CSSSelector&gt; m_selector;
+    std::unique_ptr&lt;CSSParserSelector&gt; m_tagHistory;
+};
+
+inline bool CSSParserSelector::hasShadowDescendant() const
+{
+    return m_selector-&gt;relation() == CSSSelector::ShadowDescendant;
+}
+
+inline void CSSParserValue::setFromValueList(std::unique_ptr&lt;CSSParserValueList&gt; valueList)
+{
+    id = CSSValueInvalid;
+    this-&gt;valueList = valueList.release();
+    unit = ValueList;
+}
+
+template&lt;unsigned length&gt; inline bool equalLettersIgnoringASCIICase(const CSSParserString&amp; string, const char (&amp;lowercaseLetters)[length])
+{
+    return WTF::equalLettersIgnoringASCIICaseCommon(string, lowercaseLetters);
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorecssparserSVGCSSParsercppfromrev204839trunkSourceWebCorecssSVGCSSParsercpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/css/parser/SVGCSSParser.cpp (from rev 204839, trunk/Source/WebCore/css/SVGCSSParser.cpp) (0 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/SVGCSSParser.cpp                                (rev 0)
+++ trunk/Source/WebCore/css/parser/SVGCSSParser.cpp        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -0,0 +1,432 @@
</span><ins>+/*
+    Copyright (C) 2008 Eric Seidel &lt;eric@webkit.org&gt;
+    Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann &lt;zimmermann@kde.org&gt;
+                  2004, 2005, 2007, 2010 Rob Buis &lt;buis@kde.org&gt;
+    Copyright (C) 2005, 2006 Apple Inc.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include &quot;config.h&quot;
+
+#include &quot;CSSInheritedValue.h&quot;
+#include &quot;CSSInitialValue.h&quot;
+#include &quot;CSSParser.h&quot;
+#include &quot;CSSPropertyNames.h&quot;
+#include &quot;CSSValueKeywords.h&quot;
+#include &quot;CSSValueList.h&quot;
+#include &quot;RenderTheme.h&quot;
+#include &quot;SVGPaint.h&quot;
+
+namespace WebCore {
+
+static bool isValidSystemControlColorValue(CSSValueID id)
+{
+    return id &gt;= CSSValueActiveborder &amp;&amp; CSSParser::isValidSystemColorValue(id);
+}
+
+bool CSSParser::parseSVGValue(CSSPropertyID propId, bool important)
+{
+    if (!m_valueList-&gt;current())
+        return false;
+    ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
+
+    CSSValueID id = valueWithCalculation.value().id;
+
+    bool valid_primitive = false;
+    RefPtr&lt;CSSValue&gt; parsedValue;
+
+    switch (propId) {
+    /* The comment to the right defines all valid value of these
+     * properties as defined in SVG 1.1, Appendix N. Property index */
+    case CSSPropertyAlignmentBaseline:
+    // auto | baseline | before-edge | text-before-edge | middle |
+    // central | after-edge | text-after-edge | ideographic | alphabetic |
+    // hanging | mathematical | inherit
+        if (id == CSSValueAuto || id == CSSValueBaseline || id == CSSValueMiddle ||
+          (id &gt;= CSSValueBeforeEdge &amp;&amp; id &lt;= CSSValueMathematical))
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyBaselineShift:
+    // baseline | super | sub | &lt;percentage&gt; | &lt;length&gt; | inherit
+        if (id == CSSValueBaseline || id == CSSValueSub ||
+           id &gt;= CSSValueSuper)
+            valid_primitive = true;
+        else
+            valid_primitive = validateUnit(valueWithCalculation, FLength | FPercent, SVGAttributeMode);
+        break;
+
+    case CSSPropertyDominantBaseline:
+    // auto | use-script | no-change | reset-size | ideographic |
+    // alphabetic | hanging | mathematical | central | middle |
+    // text-after-edge | text-before-edge | inherit
+        if (id == CSSValueAuto || id == CSSValueMiddle ||
+          (id &gt;= CSSValueUseScript &amp;&amp; id &lt;= CSSValueResetSize) ||
+          (id &gt;= CSSValueCentral &amp;&amp; id &lt;= CSSValueMathematical))
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyEnableBackground:
+    // accumulate | new [x] [y] [width] [height] | inherit
+        if (id == CSSValueAccumulate) // TODO : new
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyMarkerStart:
+    case CSSPropertyMarkerMid:
+    case CSSPropertyMarkerEnd:
+    case CSSPropertyMask:
+        if (id == CSSValueNone)
+            valid_primitive = true;
+        else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_URI) {
+            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().string, CSSPrimitiveValue::CSS_URI);
+            if (parsedValue)
+                m_valueList-&gt;next();
+        }
+        break;
+
+    case CSSPropertyClipRule:            // nonzero | evenodd | inherit
+    case CSSPropertyFillRule:
+        if (id == CSSValueNonzero || id == CSSValueEvenodd)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyStrokeMiterlimit:   // &lt;miterlimit&gt; | inherit
+        valid_primitive = validateUnit(valueWithCalculation, FNumber | FNonNeg, SVGAttributeMode);
+        break;
+
+    case CSSPropertyStrokeLinejoin:   // miter | round | bevel | inherit
+        if (id == CSSValueMiter || id == CSSValueRound || id == CSSValueBevel)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyStrokeLinecap:    // butt | round | square | inherit
+        if (id == CSSValueButt || id == CSSValueRound || id == CSSValueSquare)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyStrokeOpacity:   // &lt;opacity-value&gt; | inherit
+    case CSSPropertyFillOpacity:
+    case CSSPropertyStopOpacity:
+    case CSSPropertyFloodOpacity:
+        valid_primitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FNumber | FPercent, SVGAttributeMode));
+        break;
+
+    case CSSPropertyShapeRendering:
+    // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
+        if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
+            id == CSSValueCrispedges || id == CSSValueGeometricprecision)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyColorRendering: // auto | optimizeSpeed | optimizeQuality | inherit
+        if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
+            id == CSSValueOptimizequality)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyBufferedRendering: // auto | dynamic | static
+        if (id == CSSValueAuto || id == CSSValueDynamic || id == CSSValueStatic)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyColorProfile: // auto | sRGB | &lt;name&gt; | &lt;uri&gt; inherit
+        if (id == CSSValueAuto || id == CSSValueSrgb)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyColorInterpolation:   // auto | sRGB | linearRGB | inherit
+    case CSSPropertyColorInterpolationFilters:
+        if (id == CSSValueAuto || id == CSSValueSrgb || id == CSSValueLinearrgb)
+            valid_primitive = true;
+        break;
+
+    /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
+     * correctly and allows optimization in applyRule(..)
+     */
+
+    case CSSPropertyTextAnchor:    // start | middle | end | inherit
+        if (id == CSSValueStart || id == CSSValueMiddle || id == CSSValueEnd)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyGlyphOrientationVertical: // auto | &lt;angle&gt; | inherit
+        if (id == CSSValueAuto) {
+            valid_primitive = true;
+            break;
+        }
+        FALLTHROUGH;
+
+    case CSSPropertyGlyphOrientationHorizontal: // &lt;angle&gt; (restricted to _deg_ per SVG 1.1 spec) | inherit
+        if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_DEG || valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_NUMBER) {
+            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().fValue, CSSPrimitiveValue::CSS_DEG);
+
+            if (parsedValue)
+                m_valueList-&gt;next();
+        }
+        break;
+    case CSSPropertyPaintOrder:
+        if (id == CSSValueNormal)
+            valid_primitive = true;
+        else
+            parsedValue = parsePaintOrder();
+        break;
+    case CSSPropertyFill:                 // &lt;paint&gt; | inherit
+    case CSSPropertyStroke:               // &lt;paint&gt; | inherit
+        {
+            if (id == CSSValueNone)
+                parsedValue = SVGPaint::createNone();
+            else if (id == CSSValueCurrentcolor)
+                parsedValue = SVGPaint::createCurrentColor();
+            else if (isValidSystemControlColorValue(id) || id == CSSValueMenu)
+                parsedValue = SVGPaint::createColor(RenderTheme::defaultTheme()-&gt;systemColor(id));
+            else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_URI) {
+                RGBA32 c = Color::transparent;
+                if (m_valueList-&gt;next()) {
+                    if (parseColorFromValue(*m_valueList-&gt;current(), c))
+                        parsedValue = SVGPaint::createURIAndColor(valueWithCalculation.value().string, c);
+                    else if (m_valueList-&gt;current()-&gt;id == CSSValueNone)
+                        parsedValue = SVGPaint::createURIAndNone(valueWithCalculation.value().string);
+                }
+                if (!parsedValue)
+                    parsedValue = SVGPaint::createURI(valueWithCalculation.value().string);
+            } else
+                parsedValue = parseSVGPaint();
+
+            if (parsedValue)
+                m_valueList-&gt;next();
+        }
+        break;
+
+    case CSSPropertyStopColor: // TODO : icccolor
+    case CSSPropertyFloodColor:
+    case CSSPropertyLightingColor:
+        if (CSSParser::isValidSystemColorValue(id)
+            || (id &gt;= CSSValueAliceblue &amp;&amp; id &lt;= CSSValueYellowgreen))
+            parsedValue = SVGColor::createFromString(valueWithCalculation.value().string);
+        else if (id == CSSValueCurrentcolor)
+            parsedValue = SVGColor::createCurrentColor();
+        else // TODO : svgcolor (iccColor)
+            parsedValue = parseSVGColor();
+
+        if (parsedValue)
+            m_valueList-&gt;next();
+
+        break;
+
+    case CSSPropertyVectorEffect: // none | non-scaling-stroke | inherit
+        if (id == CSSValueNone || id == CSSValueNonScalingStroke)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyWritingMode:
+    // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
+        if (id == CSSValueLrTb || id == CSSValueRlTb || id == CSSValueTbRl || id == CSSValueLr || id == CSSValueRl || id == CSSValueTb)
+            valid_primitive = true;
+        break;
+
+    case CSSPropertyStrokeWidth:         // &lt;length&gt; | inherit
+    case CSSPropertyStrokeDashoffset:
+        valid_primitive = validateUnit(valueWithCalculation, FLength | FPercent, SVGAttributeMode);
+        break;
+    case CSSPropertyStrokeDasharray:     // none | &lt;dasharray&gt; | inherit
+        if (id == CSSValueNone)
+            valid_primitive = true;
+        else
+            parsedValue = parseSVGStrokeDasharray();
+
+        break;
+
+    case CSSPropertyKerning:              // auto | normal | &lt;length&gt; | inherit
+        if (id == CSSValueAuto || id == CSSValueNormal)
+            valid_primitive = true;
+        else
+            valid_primitive = validateUnit(valueWithCalculation, FLength, SVGAttributeMode);
+        break;
+
+    case CSSPropertyClipPath:    // &lt;uri&gt; | none | inherit
+    case CSSPropertyFilter:
+        if (id == CSSValueNone)
+            valid_primitive = true;
+        else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_URI) {
+            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().string, (CSSPrimitiveValue::UnitTypes) valueWithCalculation.value().unit);
+            if (parsedValue)
+                m_valueList-&gt;next();
+        }
+        break;
+    case CSSPropertyWebkitSvgShadow:
+        if (id == CSSValueNone)
+            valid_primitive = true;
+        else {
+            auto shadowValueList = parseShadow(*m_valueList, propId);
+            if (shadowValueList) {
+                addProperty(propId, WTFMove(shadowValueList), important);
+                m_valueList-&gt;next();
+                return true;
+            }
+            return false;
+        }
+        break;
+
+    case CSSPropertyMaskType: // luminance | alpha | inherit
+        if (id == CSSValueLuminance || id == CSSValueAlpha)
+            valid_primitive = true;
+        break;
+
+    /* shorthand properties */
+    case CSSPropertyMarker:
+    {
+        ShorthandScope scope(this, propId);
+        m_implicitShorthand = true;
+        if (!parseValue(CSSPropertyMarkerStart, important))
+            return false;
+        if (m_valueList-&gt;current()) {
+            rollbackLastProperties(1);
+            return false;
+        }
+        CSSValue* value = m_parsedProperties.last().value();
+        addProperty(CSSPropertyMarkerMid, value, important);
+        addProperty(CSSPropertyMarkerEnd, value, important);
+        m_implicitShorthand = false;
+        return true;
+    }
+    case CSSPropertyCx:
+    case CSSPropertyCy:
+    case CSSPropertyR:
+    case CSSPropertyRx:
+    case CSSPropertyRy:
+    case CSSPropertyX:
+    case CSSPropertyY:
+        valid_primitive = (!id &amp;&amp; validateUnit(valueWithCalculation, FLength | FPercent));
+        break;
+    default:
+        // If you crash here, it's because you added a css property and are not handling it
+        // in either this switch statement or the one in CSSParser::parseValue
+        ASSERT_WITH_MESSAGE(0, &quot;unimplemented propertyID: %d&quot;, propId);
+        return false;
+    }
+
+    if (valid_primitive) {
+        if (id != 0)
+            parsedValue = CSSPrimitiveValue::createIdentifier(id);
+        else if (valueWithCalculation.value().unit == CSSPrimitiveValue::CSS_STRING)
+            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().string, (CSSPrimitiveValue::UnitTypes) valueWithCalculation.value().unit);
+        else if (valueWithCalculation.value().unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; valueWithCalculation.value().unit &lt;= CSSPrimitiveValue::CSS_KHZ)
+            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.value().fValue, (CSSPrimitiveValue::UnitTypes) valueWithCalculation.value().unit);
+        else if (valueWithCalculation.value().unit &gt;= CSSParserValue::Q_EMS)
+            parsedValue = CSSPrimitiveValue::createAllowingMarginQuirk(valueWithCalculation.value().fValue, CSSPrimitiveValue::CSS_EMS);
+        if (isCalculation(valueWithCalculation))
+            parsedValue = CSSPrimitiveValue::create(valueWithCalculation.calculation());
+        m_valueList-&gt;next();
+    }
+    if (!parsedValue || (m_valueList-&gt;current() &amp;&amp; !inShorthand()))
+        return false;
+
+    addProperty(propId, WTFMove(parsedValue), important);
+    return true;
+}
+
+RefPtr&lt;CSSValueList&gt; CSSParser::parseSVGStrokeDasharray()
+{
+    RefPtr&lt;CSSValueList&gt; ret = CSSValueList::createCommaSeparated();
+    CSSParserValue* value = m_valueList-&gt;current();
+    bool valid_primitive = true;
+    while (value) {
+        ValueWithCalculation valueWithCalculation(*value);
+        valid_primitive = validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg, SVGAttributeMode);
+        if (!valid_primitive)
+            break;
+        // FIXME: This code doesn't handle calculated values.
+        if (value-&gt;id != 0)
+            ret-&gt;append(CSSPrimitiveValue::createIdentifier(value-&gt;id));
+        else if (value-&gt;unit &gt;= CSSPrimitiveValue::CSS_NUMBER &amp;&amp; value-&gt;unit &lt;= CSSPrimitiveValue::CSS_KHZ)
+            ret-&gt;append(CSSPrimitiveValue::create(value-&gt;fValue, (CSSPrimitiveValue::UnitTypes) value-&gt;unit));
+        value = m_valueList-&gt;next();
+        if (value &amp;&amp; value-&gt;unit == CSSParserValue::Operator &amp;&amp; value-&gt;iValue == ',')
+            value = m_valueList-&gt;next();
+    }
+    if (!valid_primitive)
+        return nullptr;
+    return ret;
+}
+
+RefPtr&lt;SVGPaint&gt; CSSParser::parseSVGPaint()
+{
+    RGBA32 c = Color::transparent;
+    if (!parseColorFromValue(*m_valueList-&gt;current(), c))
+        return nullptr;
+    return SVGPaint::createColor(Color(c));
+}
+
+RefPtr&lt;SVGColor&gt; CSSParser::parseSVGColor()
+{
+    RGBA32 c = Color::transparent;
+    if (!parseColorFromValue(*m_valueList-&gt;current(), c))
+        return nullptr;
+    return SVGColor::createFromColor(Color(c));
+}
+
+RefPtr&lt;CSSValueList&gt; CSSParser::parsePaintOrder()
+{
+    CSSParserValue* value = m_valueList-&gt;current();
+
+    Vector&lt;CSSValueID&gt; paintTypeList;
+    RefPtr&lt;CSSPrimitiveValue&gt; fill;
+    RefPtr&lt;CSSPrimitiveValue&gt; stroke;
+    RefPtr&lt;CSSPrimitiveValue&gt; markers;
+    while (value) {
+        if (value-&gt;id == CSSValueFill &amp;&amp; !fill)
+            fill = CSSPrimitiveValue::createIdentifier(value-&gt;id);
+        else if (value-&gt;id == CSSValueStroke &amp;&amp; !stroke)
+            stroke = CSSPrimitiveValue::createIdentifier(value-&gt;id);
+        else if (value-&gt;id == CSSValueMarkers &amp;&amp; !markers)
+            markers = CSSPrimitiveValue::createIdentifier(value-&gt;id);
+        else
+            return nullptr;
+        paintTypeList.append(value-&gt;id);
+        value = m_valueList-&gt;next();
+    }
+
+    // After parsing we serialize the paint-order list. Since it is not possible to
+    // pop a last list items from CSSValueList without bigger cost, we create the
+    // list after parsing. 
+    CSSValueID firstPaintOrderType = paintTypeList.at(0);
+    auto paintOrderList = CSSValueList::createSpaceSeparated();
+    switch (firstPaintOrderType) {
+    case CSSValueFill:
+        FALLTHROUGH;
+    case CSSValueStroke:
+        paintOrderList-&gt;append(firstPaintOrderType == CSSValueFill ? fill.releaseNonNull() : stroke.releaseNonNull());
+        if (paintTypeList.size() &gt; 1) {
+            if (paintTypeList.at(1) == CSSValueMarkers)
+                paintOrderList-&gt;append(markers.releaseNonNull());
+        }
+        break;
+    case CSSValueMarkers:
+        paintOrderList-&gt;append(markers.releaseNonNull());
+        if (paintTypeList.size() &gt; 1) {
+            if (paintTypeList.at(1) == CSSValueStroke)
+                paintOrderList-&gt;append(stroke.releaseNonNull());
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    return WTFMove(paintOrderList);
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorepageSettingsin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Settings.in (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Settings.in        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebCore/page/Settings.in        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -251,6 +251,8 @@
</span><span class="cx"> 
</span><span class="cx"> newBlockInsideInlineModelEnabled initial=false, setNeedsStyleRecalcInAllFrames=1
</span><span class="cx"> 
</span><ins>+newCSSParserEnabled initial=false
+
</ins><span class="cx"> httpEquivEnabled initial=true
</span><span class="cx"> 
</span><span class="cx"> # Some ports (e.g. iOS) might choose to display attachments inline, regardless of whether the response includes the
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebKit2/ChangeLog        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2016-08-23  Dave Hyatt  &lt;hyatt@apple.com&gt;
+
+        Add pref for enabling new CSS parsing and move parser files into subdirectory.
+        https://bugs.webkit.org/show_bug.cgi?id=161095
+
+        Reviewed by Sam Weinig.
+
+        * Shared/WebPreferencesDefinitions.h:
+        * UIProcess/API/C/WKPreferences.cpp:
+        (WKPreferencesSetNewCSSParserEnabled):
+        (WKPreferencesGetNewCSSParserEnabled):
+        * UIProcess/API/C/WKPreferencesRefPrivate.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences):
+
</ins><span class="cx"> 2016-08-23  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r204243.
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebPreferencesDefinitionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebPreferencesDefinitions.h (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebPreferencesDefinitions.h        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebKit2/Shared/WebPreferencesDefinitions.h        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -221,6 +221,7 @@
</span><span class="cx">     macro(EnableInheritURIQueryComponent, enableInheritURIQueryComponent, Bool, bool, false, &quot;&quot;, &quot;&quot;) \
</span><span class="cx">     macro(ServiceControlsEnabled, serviceControlsEnabled, Bool, bool, false, &quot;&quot;, &quot;&quot;) \
</span><span class="cx">     macro(NewBlockInsideInlineModelEnabled, newBlockInsideInlineModelEnabled, Bool, bool, false, &quot;&quot;, &quot;&quot;) \
</span><ins>+    macro(NewCSSParserEnabled, newCSSParserEnabled, Bool, bool, false, &quot;&quot;, &quot;&quot;) \
</ins><span class="cx">     macro(HTTPEquivEnabled, httpEquivEnabled, Bool, bool, true, &quot;&quot;, &quot;&quot;) \
</span><span class="cx">     macro(MockCaptureDevicesEnabled, mockCaptureDevicesEnabled, Bool, bool, false, &quot;&quot;, &quot;&quot;) \
</span><span class="cx">     macro(ShadowDOMEnabled, shadowDOMEnabled, Bool, bool, true, &quot;Shadow DOM&quot;, &quot;HTML Shadow DOM prototype&quot;) \
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKPreferencescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -1261,6 +1261,16 @@
</span><span class="cx">     return toImpl(preferencesRef)-&gt;newBlockInsideInlineModelEnabled();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WKPreferencesSetNewCSSParserEnabled(WKPreferencesRef preferencesRef, bool flag)
+{
+    toImpl(preferencesRef)-&gt;setNewCSSParserEnabled(flag);
+}
+
+bool WKPreferencesGetNewCSSParserEnabled(WKPreferencesRef preferencesRef)
+{
+    return toImpl(preferencesRef)-&gt;newCSSParserEnabled();
+}
+
</ins><span class="cx"> void WKPreferencesSetSubpixelCSSOMElementMetricsEnabled(WKPreferencesRef preferencesRef, bool flag)
</span><span class="cx"> {
</span><span class="cx">     toImpl(preferencesRef)-&gt;setSubpixelCSSOMElementMetricsEnabled(flag);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKPreferencesRefPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -328,6 +328,10 @@
</span><span class="cx"> WK_EXPORT bool WKPreferencesGetNewBlockInsideInlineModelEnabled(WKPreferencesRef);
</span><span class="cx"> 
</span><span class="cx"> // Defaults to false.
</span><ins>+WK_EXPORT void WKPreferencesSetNewCSSParserEnabled(WKPreferencesRef, bool);
+WK_EXPORT bool WKPreferencesGetNewCSSParserEnabled(WKPreferencesRef);
+
+// Defaults to false.
</ins><span class="cx"> WK_EXPORT void WKPreferencesSetSubpixelCSSOMElementMetricsEnabled(WKPreferencesRef, bool);
</span><span class="cx"> WK_EXPORT bool WKPreferencesGetSubpixelCSSOMElementMetricsEnabled(WKPreferencesRef);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (204851 => 204852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2016-08-23 19:23:55 UTC (rev 204851)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2016-08-23 19:37:37 UTC (rev 204852)
</span><span class="lines">@@ -3093,7 +3093,8 @@
</span><span class="cx">     settings.setSimpleLineLayoutDebugBordersEnabled(store.getBoolValueForKey(WebPreferencesKey::simpleLineLayoutDebugBordersEnabledKey()));
</span><span class="cx">     
</span><span class="cx">     settings.setNewBlockInsideInlineModelEnabled(store.getBoolValueForKey(WebPreferencesKey::newBlockInsideInlineModelEnabledKey()));
</span><del>-    
</del><ins>+    settings.setNewCSSParserEnabled(store.getBoolValueForKey(WebPreferencesKey::newCSSParserEnabledKey()));
+
</ins><span class="cx">     settings.setSubpixelCSSOMElementMetricsEnabled(store.getBoolValueForKey(WebPreferencesKey::subpixelCSSOMElementMetricsEnabledKey()));
</span><span class="cx"> 
</span><span class="cx">     settings.setUseLegacyTextAlignPositionedElementBehavior(store.getBoolValueForKey(WebPreferencesKey::useLegacyTextAlignPositionedElementBehaviorKey()));
</span></span></pre>
</div>
</div>

</body>
</html>