<!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>[205790] trunk/Source/WebCore</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/205790">205790</a></dd>
<dt>Author</dt> <dd>hyatt@apple.com</dd>
<dt>Date</dt> <dd>2016-09-11 11:11:42 -0700 (Sun, 11 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[CSS Parser] Add the main parser implementation
https://bugs.webkit.org/show_bug.cgi?id=161813

Reviewed by Dean Jackson.

This patch adds the main CSSParserImpl that handles stylesheet and rule parsing. All parsing starts with this
class (it will eventually be invoked from the CSSParser). This patch also adds @supports parsing.

* WebCore.xcodeproj/project.pbxproj:
* css/CSSKeyframeRule.cpp:
(WebCore::StyleKeyframe::StyleKeyframe):
* css/CSSKeyframeRule.h:
* css/StyleRule.cpp:
(WebCore::StyleRuleBase::destroy):
(WebCore::StyleRuleBase::copy):
(WebCore::StyleRuleBase::createCSSOMWrapper):
(WebCore::StyleRuleCharset::StyleRuleCharset):
(WebCore::StyleRuleCharset::~StyleRuleCharset):
(WebCore::StyleRuleNamespace::StyleRuleNamespace):
(WebCore::StyleRuleNamespace::~StyleRuleNamespace):
* css/StyleRule.h:
(WebCore::StyleRuleBase::isNamespaceRule):
(isType):
(WebCore::StyleRuleBase::isKeyframesRule): Deleted.
* css/StyleSheetContents.cpp:
(WebCore::traverseSubresourcesInRules):
* css/parser/CSSParserImpl.cpp: Added.
(WebCore::CSSParserImpl::CSSParserImpl):
(WebCore::CSSParserImpl::parseValue):
(WebCore::CSSParserImpl::parseVariableValue):
(WebCore::filterProperties):
(WebCore::createStyleProperties):
(WebCore::CSSParserImpl::parseInlineStyleDeclaration):
(WebCore::CSSParserImpl::parseDeclarationList):
(WebCore::CSSParserImpl::parseRule):
(WebCore::CSSParserImpl::parseStyleSheet):
(WebCore::CSSParserImpl::parsePageSelector):
(WebCore::CSSParserImpl::parseCustomPropertySet):
(WebCore::CSSParserImpl::parseKeyframeKeyList):
(WebCore::CSSParserImpl::supportsDeclaration):
(WebCore::CSSParserImpl::parseDeclarationListForInspector):
(WebCore::CSSParserImpl::parseStyleSheetForInspector):
(WebCore::computeNewAllowedRules):
(WebCore::CSSParserImpl::consumeRuleList):
(WebCore::CSSParserImpl::consumeAtRule):
(WebCore::CSSParserImpl::consumeQualifiedRule):
(WebCore::consumeStringOrURI):
(WebCore::CSSParserImpl::consumeCharsetRule):
(WebCore::CSSParserImpl::consumeImportRule):
(WebCore::CSSParserImpl::consumeNamespaceRule):
(WebCore::CSSParserImpl::consumeMediaRule):
(WebCore::CSSParserImpl::consumeSupportsRule):
(WebCore::CSSParserImpl::consumeViewportRule):
(WebCore::CSSParserImpl::consumeFontFaceRule):
(WebCore::CSSParserImpl::consumeKeyframesRule):
(WebCore::CSSParserImpl::consumePageRule):
(WebCore::CSSParserImpl::consumeKeyframeStyleRule):
(WebCore::observeSelectors):
(WebCore::CSSParserImpl::consumeStyleRule):
(WebCore::CSSParserImpl::consumeDeclarationList):
(WebCore::CSSParserImpl::consumeDeclaration):
(WebCore::CSSParserImpl::consumeVariableValue):
(WebCore::CSSParserImpl::consumeDeclarationValue):
(WebCore::CSSParserImpl::consumeKeyframeKeyList):
* css/parser/CSSParserImpl.h: Added.
* css/parser/CSSParserValues.cpp:
(WebCore::CSSParserSelector::parsePagePseudoSelector):
* css/parser/CSSParserValues.h:
* css/parser/CSSPropertyParser.cpp:
(WebCore::CSSPropertyParser::parseValue):
* css/parser/CSSSupportsParser.cpp: Added.
(WebCore::CSSSupportsParser::supportsCondition):
(WebCore::CSSSupportsParser::consumeCondition):
(WebCore::CSSSupportsParser::consumeNegation):
(WebCore::CSSSupportsParser::consumeConditionInParenthesis):
* css/parser/CSSSupportsParser.h: Added.
(WebCore::CSSSupportsParser::CSSSupportsParser):</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="#trunkSourceWebCorecssCSSKeyframeRulecpp">trunk/Source/WebCore/css/CSSKeyframeRule.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSKeyframeRuleh">trunk/Source/WebCore/css/CSSKeyframeRule.h</a></li>
<li><a href="#trunkSourceWebCorecssStyleRulecpp">trunk/Source/WebCore/css/StyleRule.cpp</a></li>
<li><a href="#trunkSourceWebCorecssStyleRuleh">trunk/Source/WebCore/css/StyleRule.h</a></li>
<li><a href="#trunkSourceWebCorecssStyleSheetContentscpp">trunk/Source/WebCore/css/StyleSheetContents.cpp</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="#trunkSourceWebCorecssparserCSSPropertyParsercpp">trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorecssparserCSSParserImplcpp">trunk/Source/WebCore/css/parser/CSSParserImpl.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSParserImplh">trunk/Source/WebCore/css/parser/CSSParserImpl.h</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSSupportsParsercpp">trunk/Source/WebCore/css/parser/CSSSupportsParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSSupportsParserh">trunk/Source/WebCore/css/parser/CSSSupportsParser.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -1353,6 +1353,7 @@
</span><span class="cx">     css/parser/CSSParser.cpp
</span><span class="cx">     css/parser/CSSParserFastPaths.cpp
</span><span class="cx">     css/parser/CSSParserIdioms.cpp
</span><ins>+    css/parser/CSSParserImpl.cpp
</ins><span class="cx">     css/parser/CSSParserObserverWrapper.cpp
</span><span class="cx">     css/parser/CSSParserToken.cpp
</span><span class="cx">     css/parser/CSSParserTokenRange.cpp
</span><span class="lines">@@ -1360,6 +1361,7 @@
</span><span class="cx">     css/parser/CSSPropertyParser.cpp
</span><span class="cx">     css/parser/CSSPropertyParserHelpers.cpp
</span><span class="cx">     css/parser/CSSSelectorParser.cpp
</span><ins>+    css/parser/CSSSupportsParser.cpp
</ins><span class="cx">     css/parser/CSSTokenizer.cpp
</span><span class="cx">     css/parser/CSSTokenizerInputStream.cpp
</span><span class="cx">     css/parser/MediaQueryBlockWatcher.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/ChangeLog        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -1,3 +1,83 @@
</span><ins>+2016-09-11  Dave Hyatt  &lt;hyatt@apple.com&gt;
+
+        [CSS Parser] Add the main parser implementation
+        https://bugs.webkit.org/show_bug.cgi?id=161813
+
+        Reviewed by Dean Jackson.
+
+        This patch adds the main CSSParserImpl that handles stylesheet and rule parsing. All parsing starts with this
+        class (it will eventually be invoked from the CSSParser). This patch also adds @supports parsing.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSKeyframeRule.cpp:
+        (WebCore::StyleKeyframe::StyleKeyframe):
+        * css/CSSKeyframeRule.h:
+        * css/StyleRule.cpp:
+        (WebCore::StyleRuleBase::destroy):
+        (WebCore::StyleRuleBase::copy):
+        (WebCore::StyleRuleBase::createCSSOMWrapper):
+        (WebCore::StyleRuleCharset::StyleRuleCharset):
+        (WebCore::StyleRuleCharset::~StyleRuleCharset):
+        (WebCore::StyleRuleNamespace::StyleRuleNamespace):
+        (WebCore::StyleRuleNamespace::~StyleRuleNamespace):
+        * css/StyleRule.h:
+        (WebCore::StyleRuleBase::isNamespaceRule):
+        (isType):
+        (WebCore::StyleRuleBase::isKeyframesRule): Deleted.
+        * css/StyleSheetContents.cpp:
+        (WebCore::traverseSubresourcesInRules):
+        * css/parser/CSSParserImpl.cpp: Added.
+        (WebCore::CSSParserImpl::CSSParserImpl):
+        (WebCore::CSSParserImpl::parseValue):
+        (WebCore::CSSParserImpl::parseVariableValue):
+        (WebCore::filterProperties):
+        (WebCore::createStyleProperties):
+        (WebCore::CSSParserImpl::parseInlineStyleDeclaration):
+        (WebCore::CSSParserImpl::parseDeclarationList):
+        (WebCore::CSSParserImpl::parseRule):
+        (WebCore::CSSParserImpl::parseStyleSheet):
+        (WebCore::CSSParserImpl::parsePageSelector):
+        (WebCore::CSSParserImpl::parseCustomPropertySet):
+        (WebCore::CSSParserImpl::parseKeyframeKeyList):
+        (WebCore::CSSParserImpl::supportsDeclaration):
+        (WebCore::CSSParserImpl::parseDeclarationListForInspector):
+        (WebCore::CSSParserImpl::parseStyleSheetForInspector):
+        (WebCore::computeNewAllowedRules):
+        (WebCore::CSSParserImpl::consumeRuleList):
+        (WebCore::CSSParserImpl::consumeAtRule):
+        (WebCore::CSSParserImpl::consumeQualifiedRule):
+        (WebCore::consumeStringOrURI):
+        (WebCore::CSSParserImpl::consumeCharsetRule):
+        (WebCore::CSSParserImpl::consumeImportRule):
+        (WebCore::CSSParserImpl::consumeNamespaceRule):
+        (WebCore::CSSParserImpl::consumeMediaRule):
+        (WebCore::CSSParserImpl::consumeSupportsRule):
+        (WebCore::CSSParserImpl::consumeViewportRule):
+        (WebCore::CSSParserImpl::consumeFontFaceRule):
+        (WebCore::CSSParserImpl::consumeKeyframesRule):
+        (WebCore::CSSParserImpl::consumePageRule):
+        (WebCore::CSSParserImpl::consumeKeyframeStyleRule):
+        (WebCore::observeSelectors):
+        (WebCore::CSSParserImpl::consumeStyleRule):
+        (WebCore::CSSParserImpl::consumeDeclarationList):
+        (WebCore::CSSParserImpl::consumeDeclaration):
+        (WebCore::CSSParserImpl::consumeVariableValue):
+        (WebCore::CSSParserImpl::consumeDeclarationValue):
+        (WebCore::CSSParserImpl::consumeKeyframeKeyList):
+        * css/parser/CSSParserImpl.h: Added.
+        * css/parser/CSSParserValues.cpp:
+        (WebCore::CSSParserSelector::parsePagePseudoSelector):
+        * css/parser/CSSParserValues.h:
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::CSSPropertyParser::parseValue):
+        * css/parser/CSSSupportsParser.cpp: Added.
+        (WebCore::CSSSupportsParser::supportsCondition):
+        (WebCore::CSSSupportsParser::consumeCondition):
+        (WebCore::CSSSupportsParser::consumeNegation):
+        (WebCore::CSSSupportsParser::consumeConditionInParenthesis):
+        * css/parser/CSSSupportsParser.h: Added.
+        (WebCore::CSSSupportsParser::CSSSupportsParser):
+
</ins><span class="cx"> 2016-09-11  Tim Horton  &lt;timothy_horton@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Candidates that don't end in spaces shouldn't have spaces arbitrarily appended to them
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -3377,6 +3377,10 @@
</span><span class="cx">                 94DE5C821D7F3A1400164F2A /* CSSAtRuleID.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DE5C801D7F39D000164F2A /* CSSAtRuleID.h */; };
</span><span class="cx">                 94DE5C8D1D80802700164F2A /* CSSSelectorParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94DE5C8B1D80801500164F2A /* CSSSelectorParser.cpp */; };
</span><span class="cx">                 94DE5C8E1D80802700164F2A /* CSSSelectorParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DE5C8C1D80801500164F2A /* CSSSelectorParser.h */; };
</span><ins>+                94DE5C911D83011D00164F2A /* CSSSupportsParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94DE5C8F1D8300CB00164F2A /* CSSSupportsParser.cpp */; };
+                94DE5C921D83011D00164F2A /* CSSSupportsParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DE5C901D8300CB00164F2A /* CSSSupportsParser.h */; };
+                94DE5C951D8301BD00164F2A /* CSSParserImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94DE5C931D8301B000164F2A /* CSSParserImpl.cpp */; };
+                94DE5C961D8301BD00164F2A /* CSSParserImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 94DE5C941D8301B000164F2A /* CSSParserImpl.h */; };
</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">@@ -10530,6 +10534,10 @@
</span><span class="cx">                 94DE5C801D7F39D000164F2A /* CSSAtRuleID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSAtRuleID.h; path = parser/CSSAtRuleID.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 94DE5C8B1D80801500164F2A /* CSSSelectorParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSSelectorParser.cpp; path = parser/CSSSelectorParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 94DE5C8C1D80801500164F2A /* CSSSelectorParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSSelectorParser.h; path = parser/CSSSelectorParser.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                94DE5C8F1D8300CB00164F2A /* CSSSupportsParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSSupportsParser.cpp; path = parser/CSSSupportsParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                94DE5C901D8300CB00164F2A /* CSSSupportsParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSSupportsParser.h; path = parser/CSSSupportsParser.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                94DE5C931D8301B000164F2A /* CSSParserImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CSSParserImpl.cpp; path = parser/CSSParserImpl.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                94DE5C941D8301B000164F2A /* CSSParserImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSSParserImpl.h; path = parser/CSSParserImpl.h; 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">@@ -18174,6 +18182,8 @@
</span><span class="cx">                                 949C76FF1D6E1D8C00C0DE4F /* CSSParserFastPaths.h */,
</span><span class="cx">                                 94DE5C7D1D78CB2500164F2A /* CSSParserIdioms.cpp */,
</span><span class="cx">                                 946D37431D6CF7880077084F /* CSSParserIdioms.h */,
</span><ins>+                                94DE5C931D8301B000164F2A /* CSSParserImpl.cpp */,
+                                94DE5C941D8301B000164F2A /* CSSParserImpl.h */,
</ins><span class="cx">                                 946D372A1D6CB28B0077084F /* CSSParserMode.h */,
</span><span class="cx">                                 949C770A1D6E49C300C0DE4F /* CSSParserObserver.h */,
</span><span class="cx">                                 949C77061D6E48ED00C0DE4F /* CSSParserObserverWrapper.cpp */,
</span><span class="lines">@@ -18190,6 +18200,8 @@
</span><span class="cx">                                 949C77031D6E393500C0DE4F /* CSSPropertyParserHelpers.h */,
</span><span class="cx">                                 94DE5C8B1D80801500164F2A /* CSSSelectorParser.cpp */,
</span><span class="cx">                                 94DE5C8C1D80801500164F2A /* CSSSelectorParser.h */,
</span><ins>+                                94DE5C8F1D8300CB00164F2A /* CSSSupportsParser.cpp */,
+                                94DE5C901D8300CB00164F2A /* CSSSupportsParser.h */,
</ins><span class="cx">                                 946D37341D6CDF980077084F /* CSSTokenizer.cpp */,
</span><span class="cx">                                 946D37371D6CDF980077084F /* CSSTokenizer.h */,
</span><span class="cx">                                 946D37351D6CDF980077084F /* CSSTokenizerInputStream.cpp */,
</span><span class="lines">@@ -24991,6 +25003,7 @@
</span><span class="cx">                                 7D4C96DD1AD4483500365A50 /* JSFetchHeaders.h in Headers */,
</span><span class="cx">                                 7E4C96DD1AD4483500365A50 /* JSFetchRequest.h in Headers */,
</span><span class="cx">                                 8E4C96DD1AD4483500365A50 /* JSFetchResponse.h in Headers */,
</span><ins>+                                94DE5C961D8301BD00164F2A /* CSSParserImpl.h in Headers */,
</ins><span class="cx">                                 BC00F0150E0A189500FD04E3 /* JSFile.h in Headers */,
</span><span class="cx">                                 2E3BC0CB117D3E0800B9409A /* JSFileError.h in Headers */,
</span><span class="cx">                                 898785F1122E1E87003AABDA /* JSFileException.h in Headers */,
</span><span class="lines">@@ -26052,6 +26065,7 @@
</span><span class="cx">                                 1A3586E015264C450022A659 /* RenderMultiColumnFlowThread.h in Headers */,
</span><span class="cx">                                 9493B6C11D74B4120088E780 /* MediaQueryParser.h in Headers */,
</span><span class="cx">                                 BCE32B9C1517C0B200F542EC /* RenderMultiColumnSet.h in Headers */,
</span><ins>+                                94DE5C921D83011D00164F2A /* CSSSupportsParser.h in Headers */,
</ins><span class="cx">                                 BC1A7D9818FCB5B000421879 /* RenderMultiColumnSpannerPlaceholder.h in Headers */,
</span><span class="cx">                                 8AC822FD180FC03300FB64D5 /* RenderNamedFlowFragment.h in Headers */,
</span><span class="cx">                                 BC85F23D151915E000BC17BE /* RenderNamedFlowThread.h in Headers */,
</span><span class="lines">@@ -27920,6 +27934,7 @@
</span><span class="cx">                                 59A85EA2119D68D900DEF1EF /* DeviceOrientationEvent.cpp in Sources */,
</span><span class="cx">                                 267725FC1A5B3AD9003C24DD /* DFA.cpp in Sources */,
</span><span class="cx">                                 5C9A7A751AA0F6EA00958ACF /* DFABytecodeCompiler.cpp in Sources */,
</span><ins>+                                94DE5C911D83011D00164F2A /* CSSSupportsParser.cpp in Sources */,
</ins><span class="cx">                                 5C9A7A761AA0F6ED00958ACF /* DFABytecodeInterpreter.cpp in Sources */,
</span><span class="cx">                                 26A807841B18F97700E219BE /* DFACombiner.cpp in Sources */,
</span><span class="cx">                                 26A517FD1AB92238006335DF /* DFAMinimizer.cpp in Sources */,
</span><span class="lines">@@ -28465,6 +28480,7 @@
</span><span class="cx">                                 418F88040FF957AE0080F045 /* JSAbstractWorker.cpp in Sources */,
</span><span class="cx">                                 FDA15EC912B03F50003A583A /* JSAnalyserNode.cpp in Sources */,
</span><span class="cx">                                 31A795C61888BADC00382F90 /* JSANGLEInstancedArrays.cpp in Sources */,
</span><ins>+                                94DE5C951D8301BD00164F2A /* CSSParserImpl.cpp in Sources */,
</ins><span class="cx">                                 12A253E21C8FFF6600C22295 /* JSAnimatable.cpp in Sources */,
</span><span class="cx">                                 120DE3FE1C87E18800B6D4DD /* JSAnimationEffect.cpp in Sources */,
</span><span class="cx">                                 3198480B1A1E6CE400A13318 /* JSAnimationEvent.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSKeyframeRulecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSKeyframeRule.cpp (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSKeyframeRule.cpp        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/css/CSSKeyframeRule.cpp        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -34,10 +34,18 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> StyleKeyframe::StyleKeyframe(Ref&lt;StyleProperties&gt;&amp;&amp; properties)
</span><del>-    : m_properties(WTFMove(properties))
</del><ins>+    : StyleRuleBase(Keyframe, 0)
+    , m_properties(WTFMove(properties))
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+StyleKeyframe::StyleKeyframe(std::unique_ptr&lt;Vector&lt;double&gt;&gt; keys, Ref&lt;StyleProperties&gt;&amp;&amp; properties)
+    : StyleRuleBase(Keyframe, 0)
+    , m_properties(WTFMove(properties))
+    , m_keys(*keys)
+{
+}
+    
</ins><span class="cx"> StyleKeyframe::~StyleKeyframe()
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSKeyframeRuleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSKeyframeRule.h (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSKeyframeRule.h        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/css/CSSKeyframeRule.h        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -36,13 +36,19 @@
</span><span class="cx"> class StyleRuleCSSStyleDeclaration;
</span><span class="cx"> class CSSKeyframesRule;
</span><span class="cx"> 
</span><del>-class StyleKeyframe final : public RefCounted&lt;StyleKeyframe&gt; {
-    WTF_MAKE_FAST_ALLOCATED;
</del><ins>+// FIXME-NEWPARSER: Rename this to StyleRuleKeyframe
+class StyleKeyframe final : public StyleRuleBase {
</ins><span class="cx"> public:
</span><ins>+    // FIXME-NEWPARSER: Remove this create function once we get rid of the old parser.
</ins><span class="cx">     static Ref&lt;StyleKeyframe&gt; create(Ref&lt;StyleProperties&gt;&amp;&amp; properties)
</span><span class="cx">     {
</span><span class="cx">         return adoptRef(*new StyleKeyframe(WTFMove(properties)));
</span><span class="cx">     }
</span><ins>+
+    static Ref&lt;StyleKeyframe&gt; create(std::unique_ptr&lt;Vector&lt;double&gt;&gt; keys, Ref&lt;StyleProperties&gt;&amp;&amp; properties)
+    {
+        return adoptRef(*new StyleKeyframe(WTFMove(keys), WTFMove(properties)));
+    }
</ins><span class="cx">     ~StyleKeyframe();
</span><span class="cx"> 
</span><span class="cx">     String keyText() const;
</span><span class="lines">@@ -63,6 +69,7 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     explicit StyleKeyframe(Ref&lt;StyleProperties&gt;&amp;&amp;);
</span><ins>+    StyleKeyframe(std::unique_ptr&lt;Vector&lt;double&gt;&gt;, Ref&lt;StyleProperties&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><span class="cx">     Ref&lt;StyleProperties&gt; m_properties;
</span><span class="cx">     Vector&lt;double&gt; m_keys;
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleRulecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleRule.cpp (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleRule.cpp        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/css/StyleRule.cpp        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -90,9 +90,14 @@
</span><span class="cx">         delete downcast&lt;StyleRuleViewport&gt;(this);
</span><span class="cx">         return;
</span><span class="cx"> #endif
</span><ins>+    case Namespace:
+        delete downcast&lt;StyleRuleNamespace&gt;(this);
+        return;
+    case Keyframe:
+        delete downcast&lt;StyleKeyframe&gt;(this);
+        return;
</ins><span class="cx">     case Unknown:
</span><span class="cx">     case Charset:
</span><del>-    case Keyframe:
</del><span class="cx"> #if !ENABLE(CSS_REGIONS)
</span><span class="cx">     case Region:
</span><span class="cx"> #endif
</span><span class="lines">@@ -126,7 +131,8 @@
</span><span class="cx">         return downcast&lt;StyleRuleViewport&gt;(*this).copy();
</span><span class="cx"> #endif
</span><span class="cx">     case Import:
</span><del>-        // FIXME: Copy import rules.
</del><ins>+    case Namespace:
+        // FIXME: Copy import and namespace rules.
</ins><span class="cx">         break;
</span><span class="cx">     case Unknown:
</span><span class="cx">     case Charset:
</span><span class="lines">@@ -179,6 +185,7 @@
</span><span class="cx"> #endif
</span><span class="cx">     case Unknown:
</span><span class="cx">     case Charset:
</span><ins>+    case Namespace: // FIXME: Add support for CSSNamespaceRule.
</ins><span class="cx">     case Keyframe:
</span><span class="cx"> #if !ENABLE(CSS_REGIONS)
</span><span class="cx">     case Region:
</span><span class="lines">@@ -396,4 +403,36 @@
</span><span class="cx"> }
</span><span class="cx"> #endif // ENABLE(CSS_DEVICE_ADAPTATION)
</span><span class="cx"> 
</span><ins>+StyleRuleCharset::StyleRuleCharset()
+    : StyleRuleBase(Charset, 0)
+{
+}
+
+StyleRuleCharset::StyleRuleCharset(const StyleRuleCharset&amp; o)
+    : StyleRuleBase(o)
+{
+}
+
+StyleRuleCharset::~StyleRuleCharset()
+{
+}
+
+StyleRuleNamespace::StyleRuleNamespace(AtomicString prefix, AtomicString uri)
+    : StyleRuleBase(Namespace, 0)
+    , m_prefix(prefix)
+    , m_uri(uri)
+{
+}
+
+StyleRuleNamespace::StyleRuleNamespace(const StyleRuleNamespace&amp; o)
+    : StyleRuleBase(o)
+    , m_prefix(o.m_prefix)
+    , m_uri(o.m_uri)
+{
+}
+
+StyleRuleNamespace::~StyleRuleNamespace()
+{
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleRuleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleRule.h (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleRule.h        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/css/StyleRule.h        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> class CSSStyleSheet;
</span><span class="cx"> class MediaQuerySet;
</span><span class="cx"> class MutableStyleProperties;
</span><ins>+class StyleKeyframe;
</ins><span class="cx"> class StyleProperties;
</span><span class="cx"> 
</span><span class="cx"> class StyleRuleBase : public WTF::RefCountedBase {
</span><span class="lines">@@ -48,6 +49,7 @@
</span><span class="cx">         Page,
</span><span class="cx">         Keyframes,
</span><span class="cx">         Keyframe, // Not used. These are internally non-rule StyleKeyframe objects.
</span><ins>+        Namespace,
</ins><span class="cx">         Supports = 12,
</span><span class="cx"> #if ENABLE(CSS_DEVICE_ADAPTATION)
</span><span class="cx">         Viewport = 15,
</span><span class="lines">@@ -60,6 +62,8 @@
</span><span class="cx">     bool isCharsetRule() const { return type() == Charset; }
</span><span class="cx">     bool isFontFaceRule() const { return type() == FontFace; }
</span><span class="cx">     bool isKeyframesRule() const { return type() == Keyframes; }
</span><ins>+    bool isKeyframeRule() const { return type() == Keyframe; }
+    bool isNamespaceRule() const { return type() == Namespace; }
</ins><span class="cx">     bool isMediaRule() const { return type() == Media; }
</span><span class="cx">     bool isPageRule() const { return type() == Page; }
</span><span class="cx">     bool isStyleRule() const { return type() == Style; }
</span><span class="lines">@@ -144,7 +148,6 @@
</span><span class="cx"> 
</span><span class="cx">     Ref&lt;StyleRuleFontFace&gt; copy() const { return adoptRef(*new StyleRuleFontFace(*this)); }
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> private:
</span><span class="cx">     explicit StyleRuleFontFace(Ref&lt;StyleProperties&gt;&amp;&amp;);
</span><span class="cx">     StyleRuleFontFace(const StyleRuleFontFace&amp;);
</span><span class="lines">@@ -265,6 +268,42 @@
</span><span class="cx"> };
</span><span class="cx"> #endif // ENABLE(CSS_DEVICE_ADAPTATION)
</span><span class="cx"> 
</span><ins>+// This is only used by the CSS parser.
+class StyleRuleCharset final : public StyleRuleBase {
+public:
+    static Ref&lt;StyleRuleCharset&gt; create() { return adoptRef(*new StyleRuleCharset()); }
+    
+    ~StyleRuleCharset();
+    
+    Ref&lt;StyleRuleCharset&gt; copy() const { return adoptRef(*new StyleRuleCharset(*this)); }
+
+private:
+    explicit StyleRuleCharset();
+    StyleRuleCharset(const StyleRuleCharset&amp;);
+};
+
+class StyleRuleNamespace final : public StyleRuleBase {
+public:
+    static Ref&lt;StyleRuleNamespace&gt; create(AtomicString prefix, AtomicString uri)
+    {
+        return adoptRef(*new StyleRuleNamespace(prefix, uri));
+    }
+    
+    ~StyleRuleNamespace();
+
+    Ref&lt;StyleRuleNamespace&gt; copy() const { return adoptRef(*new StyleRuleNamespace(*this)); }
+    
+    AtomicString prefix() const { return m_prefix; }
+    AtomicString uri() const { return m_uri; }
+
+private:
+    StyleRuleNamespace(AtomicString prefix, AtomicString uri);
+    StyleRuleNamespace(const StyleRuleNamespace&amp;);
+    
+    AtomicString m_prefix;
+    AtomicString m_uri;
+};
+    
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRule)
</span><span class="lines">@@ -296,3 +335,12 @@
</span><span class="cx">     static bool isType(const WebCore::StyleRuleBase&amp; rule) { return rule.isViewportRule(); }
</span><span class="cx"> SPECIALIZE_TYPE_TRAITS_END()
</span><span class="cx"> #endif // ENABLE(CSS_DEVICE_ADAPTATION)
</span><ins>+
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleNamespace)
+    static bool isType(const WebCore::StyleRuleBase&amp; rule) { return rule.isNamespaceRule(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleKeyframe)
+static bool isType(const WebCore::StyleRuleBase&amp; rule) { return rule.isKeyframeRule(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
</ins></span></pre></div>
<a id="trunkSourceWebCorecssStyleSheetContentscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleSheetContents.cpp (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleSheetContents.cpp        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/css/StyleSheetContents.cpp        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -460,6 +460,7 @@
</span><span class="cx"> #endif
</span><span class="cx">         case StyleRuleBase::Page:
</span><span class="cx">         case StyleRuleBase::Keyframes:
</span><ins>+        case StyleRuleBase::Namespace:
</ins><span class="cx">         case StyleRuleBase::Unknown:
</span><span class="cx">         case StyleRuleBase::Charset:
</span><span class="cx">         case StyleRuleBase::Keyframe:
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserImplcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/parser/CSSParserImpl.cpp (0 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserImpl.cpp                                (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSParserImpl.cpp        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -0,0 +1,834 @@
</span><ins>+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 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:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * 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.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// &quot;AS IS&quot; 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
+// OWNER OR CONTRIBUTORS 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.
+
+#include &quot;config.h&quot;
+#include &quot;CSSParserImpl.h&quot;
+
+#include &quot;CSSAtRuleID.h&quot;
+#include &quot;CSSCustomPropertyValue.h&quot;
+#include &quot;CSSKeyframeRule.h&quot;
+#include &quot;CSSKeyframesRule.h&quot;
+#include &quot;CSSParserObserver.h&quot;
+#include &quot;CSSParserObserverWrapper.h&quot;
+#include &quot;CSSParserValues.h&quot; // FIXME-NEWPARSER We need to move CSSParserSelector to its own file.
+#include &quot;CSSPropertyParser.h&quot;
+#include &quot;CSSSelectorParser.h&quot;
+#include &quot;CSSStyleSheet.h&quot;
+#include &quot;CSSSupportsParser.h&quot;
+#include &quot;CSSTokenizer.h&quot;
+// FIXME-NEWPARSER: #include &quot;CSSVariableParser.h&quot;
+#include &quot;Document.h&quot;
+#include &quot;Element.h&quot;
+#include &quot;MediaQueryParser.h&quot;
+#include &quot;StyleProperties.h&quot;
+#include &quot;StyleRuleImport.h&quot;
+#include &quot;StyleSheetContents.h&quot;
+
+#include &lt;bitset&gt;
+#include &lt;memory&gt;
+
+namespace WebCore {
+
+CSSParserImpl::CSSParserImpl(const CSSParserContext&amp; context, StyleSheetContents* styleSheet)
+    : m_context(context)
+    , m_styleSheet(styleSheet)
+    , m_observerWrapper(nullptr)
+{
+}
+
+bool CSSParserImpl::parseValue(MutableStyleProperties* declaration, CSSPropertyID unresolvedProperty, const String&amp; string, bool important, const CSSParserContext&amp; context)
+{
+    CSSParserImpl parser(context);
+    StyleRule::Type ruleType = StyleRule::Style;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    if (declaration-&gt;cssParserMode() == CSSViewportRuleMode)
+        ruleType = StyleRule::Viewport;
+#endif
+    CSSTokenizer::Scope scope(string);
+    parser.consumeDeclarationValue(scope.tokenRange(), unresolvedProperty, important, ruleType);
+    if (parser.m_parsedProperties.isEmpty())
+        return false;
+    return declaration-&gt;addParsedProperties(parser.m_parsedProperties);
+}
+
+bool CSSParserImpl::parseVariableValue(MutableStyleProperties* declaration, const AtomicString&amp; propertyName, const String&amp; value, bool important, const CSSParserContext&amp; context)
+{
+    CSSParserImpl parser(context);
+    CSSTokenizer::Scope scope(value);
+    parser.consumeVariableValue(scope.tokenRange(), propertyName, important);
+    if (parser.m_parsedProperties.isEmpty())
+        return false;
+    return declaration-&gt;addParsedProperties(parser.m_parsedProperties);
+}
+
+static inline void filterProperties(bool important, const ParsedPropertyVector&amp; input, ParsedPropertyVector&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 (size_t i = input.size(); i--; ) {
+        const CSSProperty&amp; property = input[i];
+        if (property.isImportant() != important)
+            continue;
+        const unsigned propertyIDIndex = property.id() - firstCSSProperty;
+        
+        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;
+        }
+        
+        // FIXME-NEWPARSER: We won't support @apply yet.
+        /*else if (property.id() == CSSPropertyApplyAtRule) {
+         // FIXME: Do we need to do anything here?
+         } */
+        
+        if (seenProperties.test(propertyIDIndex))
+            continue;
+        seenProperties.set(propertyIDIndex);
+
+        output[--unusedEntries] = property;
+    }
+}
+
+static Ref&lt;ImmutableStyleProperties&gt; createStyleProperties(ParsedPropertyVector&amp; parsedProperties, CSSParserMode mode)
+{
+    std::bitset&lt;numCSSProperties&gt; seenProperties;
+    size_t unusedEntries = parsedProperties.size();
+    ParsedPropertyVector results(unusedEntries);
+    HashSet&lt;AtomicString&gt; seenCustomProperties;
+
+    filterProperties(true, parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
+    filterProperties(false, parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
+
+    Ref&lt;ImmutableStyleProperties&gt; result = ImmutableStyleProperties::create(results.data() + unusedEntries, results.size() - unusedEntries, mode);
+    parsedProperties.clear();
+    return result;
+}
+
+Ref&lt;ImmutableStyleProperties&gt; CSSParserImpl::parseInlineStyleDeclaration(const String&amp; string, Element* element)
+{
+    Document&amp; document = element-&gt;document();
+    CSSParserContext context = CSSParserContext(document.elementSheet().contents().parserContext());
+    CSSParserMode mode = element-&gt;isHTMLElement() &amp;&amp; !document.inQuirksMode() ? HTMLStandardMode : HTMLQuirksMode;
+    context.mode = mode;
+    CSSParserImpl parser(context, &amp;document.elementSheet().contents());
+    CSSTokenizer::Scope scope(string);
+    parser.consumeDeclarationList(scope.tokenRange(), StyleRule::Style);
+    return createStyleProperties(parser.m_parsedProperties, mode);
+}
+
+bool CSSParserImpl::parseDeclarationList(MutableStyleProperties* declaration, const String&amp; string, const CSSParserContext&amp; context)
+{
+    CSSParserImpl parser(context);
+    StyleRule::Type ruleType = StyleRule::Style;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    if (declaration-&gt;cssParserMode() == CSSViewportRuleMode)
+        ruleType = StyleRule::Viewport;
+#endif
+    CSSTokenizer::Scope scope(string);
+    parser.consumeDeclarationList(scope.tokenRange(), ruleType);
+    if (parser.m_parsedProperties.isEmpty())
+        return false;
+
+    std::bitset&lt;numCSSProperties&gt; seenProperties;
+    size_t unusedEntries = parser.m_parsedProperties.size();
+    ParsedPropertyVector results(unusedEntries);
+    HashSet&lt;AtomicString&gt; seenCustomProperties;
+    filterProperties(true, parser.m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
+    filterProperties(false, parser.m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
+    if (unusedEntries)
+        results.remove(0, unusedEntries);
+    return declaration-&gt;addParsedProperties(results);
+}
+
+RefPtr&lt;StyleRuleBase&gt; CSSParserImpl::parseRule(const String&amp; string, const CSSParserContext&amp; context, StyleSheetContents* styleSheet, AllowedRulesType allowedRules)
+{
+    CSSParserImpl parser(context, styleSheet);
+    CSSTokenizer::Scope scope(string);
+    CSSParserTokenRange range = scope.tokenRange();
+    range.consumeWhitespace();
+    if (range.atEnd())
+        return nullptr; // Parse error, empty rule
+    RefPtr&lt;StyleRuleBase&gt; rule;
+    if (range.peek().type() == AtKeywordToken)
+        rule = parser.consumeAtRule(range, allowedRules);
+    else
+        rule = parser.consumeQualifiedRule(range, allowedRules);
+    if (!rule)
+        return nullptr; // Parse error, failed to consume rule
+    range.consumeWhitespace();
+    if (!rule || !range.atEnd())
+        return nullptr; // Parse error, trailing garbage
+    return rule;
+}
+
+void CSSParserImpl::parseStyleSheet(const String&amp; string, const CSSParserContext&amp; context, StyleSheetContents* styleSheet)
+{
+    CSSTokenizer::Scope scope(string);
+    CSSParserImpl parser(context, styleSheet);
+    bool firstRuleValid = parser.consumeRuleList(scope.tokenRange(), TopLevelRuleList, [&amp;styleSheet](RefPtr&lt;StyleRuleBase&gt; rule) {
+        if (rule-&gt;isCharsetRule())
+            return;
+        styleSheet-&gt;parserAppendRule(rule.releaseNonNull());
+    });
+    styleSheet-&gt;setHasSyntacticallyValidCSSHeader(firstRuleValid);
+}
+
+CSSSelectorList CSSParserImpl::parsePageSelector(CSSParserTokenRange range, StyleSheetContents* styleSheet)
+{
+    // We only support a small subset of the css-page spec.
+    range.consumeWhitespace();
+    AtomicString typeSelector;
+    if (range.peek().type() == IdentToken)
+        typeSelector = range.consume().value().toAtomicString();
+
+    AtomicString pseudo;
+    if (range.peek().type() == ColonToken) {
+        range.consume();
+        if (range.peek().type() != IdentToken)
+            return CSSSelectorList();
+        pseudo = range.consume().value().toAtomicString();
+    }
+
+    range.consumeWhitespace();
+    if (!range.atEnd())
+        return CSSSelectorList(); // Parse error; extra tokens in @page selector
+
+    std::unique_ptr&lt;CSSParserSelector&gt; selector;
+    if (!typeSelector.isNull() &amp;&amp; pseudo.isNull())
+        selector = std::unique_ptr&lt;CSSParserSelector&gt;(new CSSParserSelector(QualifiedName(nullAtom, typeSelector, styleSheet-&gt;defaultNamespace())));
+    else {
+        selector = std::unique_ptr&lt;CSSParserSelector&gt;(new CSSParserSelector);
+        if (!pseudo.isNull()) {
+            selector = std::unique_ptr&lt;CSSParserSelector&gt;(CSSParserSelector::parsePagePseudoSelector(pseudo));
+            if (!selector || selector-&gt;pseudoElementType() == CSSSelector::PseudoElementUnknown)
+                return CSSSelectorList();
+        }
+        if (!typeSelector.isNull())
+            selector-&gt;prependTagSelector(QualifiedName(nullAtom, typeSelector, styleSheet-&gt;defaultNamespace()));
+    }
+
+    selector-&gt;setForPage();
+    Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt; selectorVector;
+    selectorVector.append(WTFMove(selector));
+    CSSSelectorList selectorList;
+    selectorList.adoptSelectorVector(selectorVector);
+    return selectorList;
+}
+
+RefPtr&lt;ImmutableStyleProperties&gt; CSSParserImpl::parseCustomPropertySet(CSSParserTokenRange range)
+{
+    range.consumeWhitespace();
+    if (range.peek().type() != LeftBraceToken)
+        return nullptr;
+    CSSParserTokenRange block = range.consumeBlock();
+    range.consumeWhitespace();
+    if (!range.atEnd())
+        return nullptr;
+    CSSParserImpl parser(strictCSSParserContext());
+    parser.consumeDeclarationList(block, StyleRule::Style);
+
+    // FIXME-NEWPARSER: We dont support @apply yet.
+    // Drop nested @apply rules. Seems nicer to do this here instead of making
+    // a different StyleRule type
+    /*for (size_t i = parser.m_parsedProperties.size(); i--; ) {
+        if (parser.m_parsedProperties[i].id() == CSSPropertyApplyAtRule)
+            parser.m_parsedProperties.remove(i);
+    }*/
+
+    return createStyleProperties(parser.m_parsedProperties, HTMLStandardMode);
+}
+
+std::unique_ptr&lt;Vector&lt;double&gt;&gt; CSSParserImpl::parseKeyframeKeyList(const String&amp; keyList)
+{
+    return consumeKeyframeKeyList(CSSTokenizer::Scope(keyList).tokenRange());
+}
+
+bool CSSParserImpl::supportsDeclaration(CSSParserTokenRange&amp; range)
+{
+    ASSERT(m_parsedProperties.isEmpty());
+    consumeDeclaration(range, StyleRule::Style);
+    bool result = !m_parsedProperties.isEmpty();
+    m_parsedProperties.clear();
+    return result;
+}
+
+void CSSParserImpl::parseDeclarationListForInspector(const String&amp; declaration, const CSSParserContext&amp; context, CSSParserObserver&amp; observer)
+{
+    CSSParserImpl parser(context);
+    CSSParserObserverWrapper wrapper(observer);
+    parser.m_observerWrapper = &amp;wrapper;
+    CSSTokenizer::Scope scope(declaration, wrapper);
+    observer.startRuleHeader(StyleRule::Style, 0);
+    observer.endRuleHeader(1);
+    parser.consumeDeclarationList(scope.tokenRange(), StyleRule::Style);
+}
+
+void CSSParserImpl::parseStyleSheetForInspector(const String&amp; string, const CSSParserContext&amp; context, StyleSheetContents* styleSheet, CSSParserObserver&amp; observer)
+{
+    CSSParserImpl parser(context, styleSheet);
+    CSSParserObserverWrapper wrapper(observer);
+    parser.m_observerWrapper = &amp;wrapper;
+    CSSTokenizer::Scope scope(string, wrapper);
+    bool firstRuleValid = parser.consumeRuleList(scope.tokenRange(), TopLevelRuleList, [&amp;styleSheet](RefPtr&lt;StyleRuleBase&gt; rule) {
+        if (rule-&gt;isCharsetRule())
+            return;
+        styleSheet-&gt;parserAppendRule(rule.releaseNonNull());
+    });
+    styleSheet-&gt;setHasSyntacticallyValidCSSHeader(firstRuleValid);
+}
+
+static CSSParserImpl::AllowedRulesType computeNewAllowedRules(CSSParserImpl::AllowedRulesType allowedRules, StyleRuleBase* rule)
+{
+    if (!rule || allowedRules == CSSParserImpl::KeyframeRules || allowedRules == CSSParserImpl::NoRules)
+        return allowedRules;
+    ASSERT(allowedRules &lt;= CSSParserImpl::RegularRules);
+    if (rule-&gt;isCharsetRule() || rule-&gt;isImportRule())
+        return CSSParserImpl::AllowImportRules;
+    if (rule-&gt;isNamespaceRule())
+        return CSSParserImpl::AllowNamespaceRules;
+    return CSSParserImpl::RegularRules;
+}
+
+template&lt;typename T&gt;
+bool CSSParserImpl::consumeRuleList(CSSParserTokenRange range, RuleListType ruleListType, const T callback)
+{
+    AllowedRulesType allowedRules = RegularRules;
+    switch (ruleListType) {
+    case TopLevelRuleList:
+        allowedRules = AllowCharsetRules;
+        break;
+    case RegularRuleList:
+        allowedRules = RegularRules;
+        break;
+    case KeyframesRuleList:
+        allowedRules = KeyframeRules;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    bool seenRule = false;
+    bool firstRuleValid = false;
+    while (!range.atEnd()) {
+        RefPtr&lt;StyleRuleBase&gt; rule;
+        switch (range.peek().type()) {
+        case WhitespaceToken:
+            range.consumeWhitespace();
+            continue;
+        case AtKeywordToken:
+            rule = consumeAtRule(range, allowedRules);
+            break;
+        case CDOToken:
+        case CDCToken:
+            if (ruleListType == TopLevelRuleList) {
+                range.consume();
+                continue;
+            }
+            FALLTHROUGH;
+        default:
+            rule = consumeQualifiedRule(range, allowedRules);
+            break;
+        }
+        if (!seenRule) {
+            seenRule = true;
+            firstRuleValid = rule;
+        }
+        if (rule) {
+            allowedRules = computeNewAllowedRules(allowedRules, rule.get());
+            callback(rule);
+        }
+    }
+
+    return firstRuleValid;
+}
+
+RefPtr&lt;StyleRuleBase&gt; CSSParserImpl::consumeAtRule(CSSParserTokenRange&amp; range, AllowedRulesType allowedRules)
+{
+    ASSERT(range.peek().type() == AtKeywordToken);
+    const StringView name = range.consumeIncludingWhitespace().value();
+    const CSSParserToken* preludeStart = &amp;range.peek();
+    while (!range.atEnd() &amp;&amp; range.peek().type() != LeftBraceToken &amp;&amp; range.peek().type() != SemicolonToken)
+        range.consumeComponentValue();
+
+    CSSParserTokenRange prelude = range.makeSubRange(preludeStart, &amp;range.peek());
+    CSSAtRuleID id = cssAtRuleID(name);
+    
+    if (range.atEnd() || range.peek().type() == SemicolonToken) {
+        range.consume();
+        if (allowedRules == AllowCharsetRules &amp;&amp; id == CSSAtRuleCharset)
+            return consumeCharsetRule(prelude);
+        if (allowedRules &lt;= AllowImportRules &amp;&amp; id == CSSAtRuleImport)
+            return consumeImportRule(prelude);
+        if (allowedRules &lt;= AllowNamespaceRules &amp;&amp; id == CSSAtRuleNamespace)
+            return consumeNamespaceRule(prelude);
+        // FIXME-NEWPARSER: Support &quot;apply&quot;
+        /*if (allowedRules == ApplyRules &amp;&amp; id == CSSAtRuleApply) {
+            consumeApplyRule(prelude);
+            return nullptr; // consumeApplyRule just updates m_parsedProperties
+        }*/
+        return nullptr; // Parse error, unrecognised at-rule without block
+    }
+
+    CSSParserTokenRange block = range.consumeBlock();
+    if (allowedRules == KeyframeRules)
+        return nullptr; // Parse error, no at-rules supported inside @keyframes
+    if (allowedRules == NoRules || allowedRules == ApplyRules)
+        return nullptr; // Parse error, no at-rules with blocks supported inside declaration lists
+
+    ASSERT(allowedRules &lt;= RegularRules);
+
+    switch (id) {
+    case CSSAtRuleMedia:
+        return consumeMediaRule(prelude, block);
+    case CSSAtRuleSupports:
+        return consumeSupportsRule(prelude, block);
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    case CSSAtRuleViewport:
+        return consumeViewportRule(prelude, block);
+#endif
+    case CSSAtRuleFontFace:
+        return consumeFontFaceRule(prelude, block);
+    case CSSAtRuleWebkitKeyframes:
+        return consumeKeyframesRule(true, prelude, block);
+    case CSSAtRuleKeyframes:
+        return consumeKeyframesRule(false, prelude, block);
+    case CSSAtRulePage:
+        return consumePageRule(prelude, block);
+    default:
+        return nullptr; // Parse error, unrecognised at-rule with block
+    }
+}
+
+RefPtr&lt;StyleRuleBase&gt; CSSParserImpl::consumeQualifiedRule(CSSParserTokenRange&amp; range, AllowedRulesType allowedRules)
+{
+    const CSSParserToken* preludeStart = &amp;range.peek();
+    while (!range.atEnd() &amp;&amp; range.peek().type() != LeftBraceToken)
+        range.consumeComponentValue();
+
+    if (range.atEnd())
+        return nullptr; // Parse error, EOF instead of qualified rule block
+
+    CSSParserTokenRange prelude = range.makeSubRange(preludeStart, &amp;range.peek());
+    CSSParserTokenRange block = range.consumeBlock();
+
+    if (allowedRules &lt;= RegularRules)
+        return consumeStyleRule(prelude, block);
+    if (allowedRules == KeyframeRules)
+        return consumeKeyframeStyleRule(prelude, block);
+
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+// This may still consume tokens if it fails
+static AtomicString consumeStringOrURI(CSSParserTokenRange&amp; range)
+{
+    const CSSParserToken&amp; token = range.peek();
+
+    if (token.type() == StringToken || token.type() == UrlToken)
+        return range.consumeIncludingWhitespace().value().toAtomicString();
+
+    if (token.type() != FunctionToken || !equalIgnoringASCIICase(token.value(), &quot;url&quot;))
+        return AtomicString();
+
+    CSSParserTokenRange contents = range.consumeBlock();
+    const CSSParserToken&amp; uri = contents.consumeIncludingWhitespace();
+    if (uri.type() == BadStringToken || !contents.atEnd())
+        return AtomicString();
+    return uri.value().toAtomicString();
+}
+
+RefPtr&lt;StyleRuleCharset&gt; CSSParserImpl::consumeCharsetRule(CSSParserTokenRange prelude)
+{
+    const CSSParserToken&amp; string = prelude.consumeIncludingWhitespace();
+    if (string.type() != StringToken || !prelude.atEnd())
+        return nullptr; // Parse error, expected a single string
+    return StyleRuleCharset::create();
+}
+
+RefPtr&lt;StyleRuleImport&gt; CSSParserImpl::consumeImportRule(CSSParserTokenRange prelude)
+{
+    AtomicString uri(consumeStringOrURI(prelude));
+    if (uri.isNull())
+        return nullptr; // Parse error, expected string or URI
+
+    if (m_observerWrapper) {
+        unsigned endOffset = m_observerWrapper-&gt;endOffset(prelude);
+        m_observerWrapper-&gt;observer().startRuleHeader(StyleRule::Import, m_observerWrapper-&gt;startOffset(prelude));
+        m_observerWrapper-&gt;observer().endRuleHeader(endOffset);
+        m_observerWrapper-&gt;observer().startRuleBody(endOffset);
+        m_observerWrapper-&gt;observer().endRuleBody(endOffset);
+    }
+
+    return StyleRuleImport::create(uri, MediaQueryParser::parseMediaQuerySet(prelude).releaseNonNull());
+}
+
+RefPtr&lt;StyleRuleNamespace&gt; CSSParserImpl::consumeNamespaceRule(CSSParserTokenRange prelude)
+{
+    AtomicString namespacePrefix;
+    if (prelude.peek().type() == IdentToken)
+        namespacePrefix = prelude.consumeIncludingWhitespace().value().toAtomicString();
+
+    AtomicString uri(consumeStringOrURI(prelude));
+    if (uri.isNull() || !prelude.atEnd())
+        return nullptr; // Parse error, expected string or URI
+
+    return StyleRuleNamespace::create(namespacePrefix, uri);
+}
+
+RefPtr&lt;StyleRuleMedia&gt; CSSParserImpl::consumeMediaRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
+{
+    Vector&lt;RefPtr&lt;StyleRuleBase&gt;&gt; rules;
+
+    if (m_observerWrapper) {
+        m_observerWrapper-&gt;observer().startRuleHeader(StyleRule::Media, m_observerWrapper-&gt;startOffset(prelude));
+        m_observerWrapper-&gt;observer().endRuleHeader(m_observerWrapper-&gt;endOffset(prelude));
+        m_observerWrapper-&gt;observer().startRuleBody(m_observerWrapper-&gt;previousTokenStartOffset(block));
+    }
+
+    consumeRuleList(block, RegularRuleList, [&amp;rules](RefPtr&lt;StyleRuleBase&gt; rule) {
+        rules.append(rule);
+    });
+
+    if (m_observerWrapper)
+        m_observerWrapper-&gt;observer().endRuleBody(m_observerWrapper-&gt;endOffset(block));
+
+    return StyleRuleMedia::create(MediaQueryParser::parseMediaQuerySet(prelude).releaseNonNull(), rules);
+}
+
+RefPtr&lt;StyleRuleSupports&gt; CSSParserImpl::consumeSupportsRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
+{
+    CSSSupportsParser::SupportsResult supported = CSSSupportsParser::supportsCondition(prelude, *this);
+    if (supported == CSSSupportsParser::Invalid)
+        return nullptr; // Parse error, invalid @supports condition
+
+    if (m_observerWrapper) {
+        m_observerWrapper-&gt;observer().startRuleHeader(StyleRule::Supports, m_observerWrapper-&gt;startOffset(prelude));
+        m_observerWrapper-&gt;observer().endRuleHeader(m_observerWrapper-&gt;endOffset(prelude));
+        m_observerWrapper-&gt;observer().startRuleBody(m_observerWrapper-&gt;previousTokenStartOffset(block));
+    }
+
+    Vector&lt;RefPtr&lt;StyleRuleBase&gt;&gt; rules;
+    consumeRuleList(block, RegularRuleList, [&amp;rules](RefPtr&lt;StyleRuleBase&gt; rule) {
+        rules.append(rule);
+    });
+
+    if (m_observerWrapper)
+        m_observerWrapper-&gt;observer().endRuleBody(m_observerWrapper-&gt;endOffset(block));
+
+    return StyleRuleSupports::create(prelude.serialize().stripWhiteSpace(), supported, rules);
+}
+
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+RefPtr&lt;StyleRuleViewport&gt; CSSParserImpl::consumeViewportRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
+{
+    if (!prelude.atEnd())
+        return nullptr; // Parser error; @viewport prelude should be empty
+
+    if (m_observerWrapper) {
+        unsigned endOffset = m_observerWrapper-&gt;endOffset(prelude);
+        m_observerWrapper-&gt;observer().startRuleHeader(StyleRule::Viewport, m_observerWrapper-&gt;startOffset(prelude));
+        m_observerWrapper-&gt;observer().endRuleHeader(endOffset);
+        m_observerWrapper-&gt;observer().startRuleBody(endOffset);
+        m_observerWrapper-&gt;observer().endRuleBody(endOffset);
+    }
+
+    consumeDeclarationList(block, StyleRule::Viewport);
+    return StyleRuleViewport::create(createStyleProperties(m_parsedProperties, CSSViewportRuleMode));
+}
+#endif
+
+RefPtr&lt;StyleRuleFontFace&gt; CSSParserImpl::consumeFontFaceRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
+{
+    if (!prelude.atEnd())
+        return nullptr; // Parse error; @font-face prelude should be empty
+
+    if (m_observerWrapper) {
+        unsigned endOffset = m_observerWrapper-&gt;endOffset(prelude);
+        m_observerWrapper-&gt;observer().startRuleHeader(StyleRule::FontFace, m_observerWrapper-&gt;startOffset(prelude));
+        m_observerWrapper-&gt;observer().endRuleHeader(endOffset);
+        m_observerWrapper-&gt;observer().startRuleBody(endOffset);
+        m_observerWrapper-&gt;observer().endRuleBody(endOffset);
+    }
+
+    consumeDeclarationList(block, StyleRule::FontFace);
+    return StyleRuleFontFace::create(createStyleProperties(m_parsedProperties, m_context.mode));
+}
+
+RefPtr&lt;StyleRuleKeyframes&gt; CSSParserImpl::consumeKeyframesRule(bool webkitPrefixed, CSSParserTokenRange prelude, CSSParserTokenRange block)
+{
+    CSSParserTokenRange rangeCopy = prelude; // For inspector callbacks
+    const CSSParserToken&amp; nameToken = prelude.consumeIncludingWhitespace();
+    if (!prelude.atEnd())
+        return nullptr; // Parse error; expected single non-whitespace token in @keyframes header
+
+    String name;
+    if (nameToken.type() == IdentToken) {
+        name = nameToken.value().toString();
+    } else if (nameToken.type() == StringToken &amp;&amp; webkitPrefixed)
+        name = nameToken.value().toString();
+    else
+        return nullptr; // Parse error; expected ident token in @keyframes header
+
+    if (m_observerWrapper) {
+        m_observerWrapper-&gt;observer().startRuleHeader(StyleRule::Keyframes, m_observerWrapper-&gt;startOffset(rangeCopy));
+        m_observerWrapper-&gt;observer().endRuleHeader(m_observerWrapper-&gt;endOffset(prelude));
+        m_observerWrapper-&gt;observer().startRuleBody(m_observerWrapper-&gt;previousTokenStartOffset(block));
+        m_observerWrapper-&gt;observer().endRuleBody(m_observerWrapper-&gt;endOffset(block));
+    }
+
+    RefPtr&lt;StyleRuleKeyframes&gt; keyframeRule = StyleRuleKeyframes::create();
+    consumeRuleList(block, KeyframesRuleList, [keyframeRule](RefPtr&lt;StyleRuleBase&gt; keyframe) {
+        RefPtr&lt;StyleKeyframe&gt; key = static_cast&lt;StyleKeyframe*&gt;(keyframe.get());
+        keyframeRule-&gt;parserAppendKeyframe(key.releaseNonNull());
+    });
+    keyframeRule-&gt;setName(name);
+    // FIXME-NEWPARSER: Find out why this is done. Behavior difference when prefixed?
+    // keyframeRule-&gt;setVendorPrefixed(webkitPrefixed);
+    return keyframeRule;
+}
+
+RefPtr&lt;StyleRulePage&gt; CSSParserImpl::consumePageRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
+{
+    CSSSelectorList selectorList = parsePageSelector(prelude, m_styleSheet.get());
+    if (!selectorList.isValid())
+        return nullptr; // Parse error, invalid @page selector
+
+    if (m_observerWrapper) {
+        unsigned endOffset = m_observerWrapper-&gt;endOffset(prelude);
+        m_observerWrapper-&gt;observer().startRuleHeader(StyleRule::Page, m_observerWrapper-&gt;startOffset(prelude));
+        m_observerWrapper-&gt;observer().endRuleHeader(endOffset);
+    }
+
+    consumeDeclarationList(block, StyleRule::Style);
+    
+    RefPtr&lt;StyleRulePage&gt; page = StyleRulePage::create(createStyleProperties(m_parsedProperties, m_context.mode));
+    page-&gt;wrapperAdoptSelectorList(selectorList);
+    return page;
+}
+
+// FIXME-NEWPARSER: Support &quot;apply&quot;
+/*void CSSParserImpl::consumeApplyRule(CSSParserTokenRange prelude)
+{
+    const CSSParserToken&amp; ident = prelude.consumeIncludingWhitespace();
+    if (!prelude.atEnd() || !CSSVariableParser::isValidVariableName(ident))
+        return; // Parse error, expected a single custom property name
+    m_parsedProperties.append(CSSProperty(
+        CSSPropertyApplyAtRule,
+        *CSSCustomIdentValue::create(ident.value().toString())));
+}
+*/
+    
+RefPtr&lt;StyleKeyframe&gt; CSSParserImpl::consumeKeyframeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
+{
+    std::unique_ptr&lt;Vector&lt;double&gt;&gt; keyList = consumeKeyframeKeyList(prelude);
+    if (!keyList)
+        return nullptr;
+
+    if (m_observerWrapper) {
+        m_observerWrapper-&gt;observer().startRuleHeader(StyleRule::Keyframe, m_observerWrapper-&gt;startOffset(prelude));
+        m_observerWrapper-&gt;observer().endRuleHeader(m_observerWrapper-&gt;endOffset(prelude));
+    }
+
+    consumeDeclarationList(block, StyleRule::Keyframe);
+    return StyleKeyframe::create(WTFMove(keyList), createStyleProperties(m_parsedProperties, m_context.mode));
+}
+
+static void observeSelectors(CSSParserObserverWrapper&amp; wrapper, CSSParserTokenRange selectors)
+{
+    // This is easier than hooking into the CSSSelectorParser
+    selectors.consumeWhitespace();
+    CSSParserTokenRange originalRange = selectors;
+    wrapper.observer().startRuleHeader(StyleRule::Style, wrapper.startOffset(originalRange));
+
+    while (!selectors.atEnd()) {
+        const CSSParserToken* selectorStart = &amp;selectors.peek();
+        while (!selectors.atEnd() &amp;&amp; selectors.peek().type() != CommaToken)
+            selectors.consumeComponentValue();
+        CSSParserTokenRange selector = selectors.makeSubRange(selectorStart, &amp;selectors.peek());
+        selectors.consumeIncludingWhitespace();
+
+        wrapper.observer().observeSelector(wrapper.startOffset(selector), wrapper.endOffset(selector));
+    }
+
+    wrapper.observer().endRuleHeader(wrapper.endOffset(originalRange));
+}
+
+RefPtr&lt;StyleRule&gt; CSSParserImpl::consumeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
+{
+    CSSSelectorList selectorList = CSSSelectorParser::parseSelector(prelude, m_context, m_styleSheet.get());
+    if (!selectorList.isValid())
+        return nullptr; // Parse error, invalid selector list
+
+    if (m_observerWrapper)
+        observeSelectors(*m_observerWrapper, prelude);
+
+    consumeDeclarationList(block, StyleRule::Style);
+
+    // FIXME-NEWPARSER: Line number is in the StyleRule constructor (gross), need to figure this out.
+    RefPtr&lt;StyleRule&gt; rule = StyleRule::create(0, createStyleProperties(m_parsedProperties, m_context.mode));
+    rule-&gt;wrapperAdoptSelectorList(selectorList);
+    return rule;
+}
+
+void CSSParserImpl::consumeDeclarationList(CSSParserTokenRange range, StyleRule::Type ruleType)
+{
+    ASSERT(m_parsedProperties.isEmpty());
+
+    bool useObserver = m_observerWrapper &amp;&amp; (ruleType == StyleRule::Style || ruleType == StyleRule::Keyframe);
+    if (useObserver) {
+        m_observerWrapper-&gt;observer().startRuleBody(m_observerWrapper-&gt;previousTokenStartOffset(range));
+        m_observerWrapper-&gt;skipCommentsBefore(range, true);
+    }
+
+    while (!range.atEnd()) {
+        switch (range.peek().type()) {
+        case WhitespaceToken:
+        case SemicolonToken:
+            range.consume();
+            break;
+        case IdentToken: {
+            const CSSParserToken* declarationStart = &amp;range.peek();
+
+            if (useObserver)
+                m_observerWrapper-&gt;yieldCommentsBefore(range);
+
+            while (!range.atEnd() &amp;&amp; range.peek().type() != SemicolonToken)
+                range.consumeComponentValue();
+
+            consumeDeclaration(range.makeSubRange(declarationStart, &amp;range.peek()), ruleType);
+
+            if (useObserver)
+                m_observerWrapper-&gt;skipCommentsBefore(range, false);
+            break;
+        }
+        case AtKeywordToken: {
+            // FIXME-NEWPARSER: Support apply
+            AllowedRulesType allowedRules = /* ruleType == StyleRule::Style &amp;&amp; RuntimeEnabledFeatures::cssApplyAtRulesEnabled() ? ApplyRules :*/ NoRules;
+            RefPtr&lt;StyleRuleBase&gt; rule = consumeAtRule(range, allowedRules);
+            ASSERT_UNUSED(rule, !rule);
+            break;
+        }
+        default: // Parse error, unexpected token in declaration list
+            while (!range.atEnd() &amp;&amp; range.peek().type() != SemicolonToken)
+                range.consumeComponentValue();
+            break;
+        }
+    }
+
+    // Yield remaining comments
+    if (useObserver) {
+        m_observerWrapper-&gt;yieldCommentsBefore(range);
+        m_observerWrapper-&gt;observer().endRuleBody(m_observerWrapper-&gt;endOffset(range));
+    }
+}
+
+void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, StyleRule::Type ruleType)
+{
+    CSSParserTokenRange rangeCopy = range; // For inspector callbacks
+
+    ASSERT(range.peek().type() == IdentToken);
+    const CSSParserToken&amp; token = range.consumeIncludingWhitespace();
+    CSSPropertyID unresolvedProperty = token.parseAsUnresolvedCSSPropertyID();
+    if (range.consume().type() != ColonToken)
+        return; // Parse error
+
+    bool important = false;
+    const CSSParserToken* declarationValueEnd = range.end();
+    const CSSParserToken* last = range.end() - 1;
+    while (last-&gt;type() == WhitespaceToken)
+        --last;
+    if (last-&gt;type() == IdentToken &amp;&amp; equalIgnoringASCIICase(last-&gt;value(), &quot;important&quot;)) {
+        --last;
+        while (last-&gt;type() == WhitespaceToken)
+            --last;
+        if (last-&gt;type() == DelimiterToken &amp;&amp; last-&gt;delimiter() == '!') {
+            important = true;
+            declarationValueEnd = last;
+        }
+    }
+
+    size_t propertiesCount = m_parsedProperties.size();
+    // FIXME-NEWPARSER: Support variables
+    /*if (unresolvedProperty == CSSPropertyInvalid &amp;&amp; CSSVariableParser::isValidVariableName(token)) {
+        AtomicString variableName = token.value().toAtomicString();
+        consumeVariableValue(range.makeSubRange(&amp;range.peek(), declarationValueEnd), variableName, important);
+    }*/
+
+    if (important &amp;&amp; (ruleType == StyleRule::FontFace || ruleType == StyleRule::Keyframe))
+        return;
+
+    if (unresolvedProperty != CSSPropertyInvalid)
+        consumeDeclarationValue(range.makeSubRange(&amp;range.peek(), declarationValueEnd), unresolvedProperty, important, ruleType);
+
+    if (m_observerWrapper &amp;&amp; (ruleType == StyleRule::Style || ruleType == StyleRule::Keyframe)) {
+        m_observerWrapper-&gt;observer().observeProperty(
+            m_observerWrapper-&gt;startOffset(rangeCopy), m_observerWrapper-&gt;endOffset(rangeCopy),
+            important, m_parsedProperties.size() != propertiesCount);
+    }
+}
+
+void CSSParserImpl::consumeVariableValue(CSSParserTokenRange /* range */, const AtomicString&amp; /*variableName */, bool /* important */)
+{
+    // FIXME-NEWPARSER: Support variables
+    // if (CSSCustomPropertyDeclaration* value = CSSVariableParser::parseDeclarationValue(variableName, range))
+    //     m_parsedProperties.append(CSSProperty(CSSPropertyVariable, *value, important));
+}
+
+void CSSParserImpl::consumeDeclarationValue(CSSParserTokenRange range, CSSPropertyID unresolvedProperty, bool important, StyleRule::Type ruleType)
+{
+    CSSPropertyParser::parseValue(unresolvedProperty, important, range, m_context, m_parsedProperties, ruleType);
+}
+
+std::unique_ptr&lt;Vector&lt;double&gt;&gt; CSSParserImpl::consumeKeyframeKeyList(CSSParserTokenRange range)
+{
+    std::unique_ptr&lt;Vector&lt;double&gt;&gt; result = std::unique_ptr&lt;Vector&lt;double&gt;&gt;(new Vector&lt;double&gt;);
+    while (true) {
+        range.consumeWhitespace();
+        const CSSParserToken&amp; token = range.consumeIncludingWhitespace();
+        if (token.type() == PercentageToken &amp;&amp; token.numericValue() &gt;= 0 &amp;&amp; token.numericValue() &lt;= 100)
+            result-&gt;append(token.numericValue() / 100);
+        else if (token.type() == IdentToken &amp;&amp; equalIgnoringASCIICase(token.value(), &quot;from&quot;))
+            result-&gt;append(0);
+        else if (token.type() == IdentToken &amp;&amp; equalIgnoringASCIICase(token.value(), &quot;to&quot;))
+            result-&gt;append(1);
+        else
+            return nullptr; // Parser error, invalid value in keyframe selector
+        if (range.atEnd())
+            return result;
+        if (range.consume().type() != CommaToken)
+            return nullptr; // Parser error
+    }
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserImplh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/parser/CSSParserImpl.h (0 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserImpl.h                                (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSParserImpl.h        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -0,0 +1,152 @@
</span><ins>+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 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:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * 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.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// &quot;AS IS&quot; 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
+// OWNER OR CONTRIBUTORS 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.
+
+#pragma once
+
+#include &quot;CSSParserMode.h&quot;
+#include &quot;CSSParserTokenRange.h&quot;
+#include &quot;CSSProperty.h&quot;
+#include &quot;CSSPropertyNames.h&quot;
+#include &quot;CSSPropertySourceData.h&quot;
+#include &quot;StyleRule.h&quot;
+
+#include &lt;memory&gt;
+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+class CSSParserObserver;
+class CSSParserObserverWrapper;
+class CSSSelectorList;
+class StyleKeyframe;
+class StyleRule;
+class StyleRuleBase;
+class StyleRuleCharset;
+class StyleRuleFontFace;
+class StyleRuleImport;
+class StyleRuleKeyframes;
+class StyleRuleMedia;
+class StyleRuleNamespace;
+class StyleRulePage;
+class StyleRuleSupports;
+class StyleRuleViewport;
+class StyleSheetContents;
+class ImmutableStyleProperties;
+class Element;
+class MutableStyleProperties;
+
+class CSSParserImpl {
+    WTF_MAKE_NONCOPYABLE(CSSParserImpl);
+public:
+    CSSParserImpl(const CSSParserContext&amp;, StyleSheetContents* = nullptr);
+
+    enum AllowedRulesType {
+        // As per css-syntax, css-cascade and css-namespaces, @charset rules
+        // must come first, followed by @import then @namespace.
+        // AllowImportRules actually means we allow @import and any rules thay
+        // may follow it, i.e. @namespace rules and regular rules.
+        // AllowCharsetRules and AllowNamespaceRules behave similarly.
+        AllowCharsetRules,
+        AllowImportRules,
+        AllowNamespaceRules,
+        RegularRules,
+        KeyframeRules,
+        ApplyRules, // For @apply inside style rules
+        NoRules, // For parsing at-rules inside declaration lists
+    };
+
+    static bool parseValue(MutableStyleProperties*, CSSPropertyID, const String&amp;, bool important, const CSSParserContext&amp;);
+    static bool parseVariableValue(MutableStyleProperties*, const AtomicString&amp; propertyName, const String&amp;, bool important, const CSSParserContext&amp;);
+    static Ref&lt;ImmutableStyleProperties&gt; parseInlineStyleDeclaration(const String&amp;, Element*);
+    static bool parseDeclarationList(MutableStyleProperties*, const String&amp;, const CSSParserContext&amp;);
+    static RefPtr&lt;StyleRuleBase&gt; parseRule(const String&amp;, const CSSParserContext&amp;, StyleSheetContents*, AllowedRulesType);
+    static void parseStyleSheet(const String&amp;, const CSSParserContext&amp;, StyleSheetContents*);
+    static CSSSelectorList parsePageSelector(CSSParserTokenRange, StyleSheetContents*);
+
+    static RefPtr&lt;ImmutableStyleProperties&gt; parseCustomPropertySet(CSSParserTokenRange);
+
+    static std::unique_ptr&lt;Vector&lt;double&gt;&gt; parseKeyframeKeyList(const String&amp;);
+
+    bool supportsDeclaration(CSSParserTokenRange&amp;);
+
+    static void parseDeclarationListForInspector(const String&amp;, const CSSParserContext&amp;, CSSParserObserver&amp;);
+    static void parseStyleSheetForInspector(const String&amp;, const CSSParserContext&amp;, StyleSheetContents*, CSSParserObserver&amp;);
+
+private:
+    enum RuleListType {
+        TopLevelRuleList,
+        RegularRuleList,
+        KeyframesRuleList
+    };
+
+    // Returns whether the first encountered rule was valid
+    template&lt;typename T&gt;
+    bool consumeRuleList(CSSParserTokenRange, RuleListType, T callback);
+
+    // These two functions update the range they're given
+    RefPtr&lt;StyleRuleBase&gt; consumeAtRule(CSSParserTokenRange&amp;, AllowedRulesType);
+    RefPtr&lt;StyleRuleBase&gt; consumeQualifiedRule(CSSParserTokenRange&amp;, AllowedRulesType);
+
+    static RefPtr&lt;StyleRuleCharset&gt; consumeCharsetRule(CSSParserTokenRange prelude);
+    RefPtr&lt;StyleRuleImport&gt; consumeImportRule(CSSParserTokenRange prelude);
+    RefPtr&lt;StyleRuleNamespace&gt; consumeNamespaceRule(CSSParserTokenRange prelude);
+    RefPtr&lt;StyleRuleMedia&gt; consumeMediaRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
+    RefPtr&lt;StyleRuleSupports&gt; consumeSupportsRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
+    RefPtr&lt;StyleRuleViewport&gt; consumeViewportRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
+    RefPtr&lt;StyleRuleFontFace&gt; consumeFontFaceRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
+    RefPtr&lt;StyleRuleKeyframes&gt; consumeKeyframesRule(bool webkitPrefixed, CSSParserTokenRange prelude, CSSParserTokenRange block);
+    RefPtr&lt;StyleRulePage&gt; consumePageRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
+    // Updates m_parsedProperties
+    
+    // FIXME-NEWPARSER: Support &quot;apply&quot;
+    // void consumeApplyRule(CSSParserTokenRange prelude);
+
+    RefPtr&lt;StyleKeyframe&gt; consumeKeyframeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
+    RefPtr&lt;StyleRule&gt; consumeStyleRule(CSSParserTokenRange prelude, CSSParserTokenRange block);
+
+    void consumeDeclarationList(CSSParserTokenRange, StyleRule::Type);
+    void consumeDeclaration(CSSParserTokenRange, StyleRule::Type);
+    void consumeDeclarationValue(CSSParserTokenRange, CSSPropertyID, bool important, StyleRule::Type);
+    void consumeVariableValue(CSSParserTokenRange, const AtomicString&amp; propertyName, bool important);
+
+    static std::unique_ptr&lt;Vector&lt;double&gt;&gt; consumeKeyframeKeyList(CSSParserTokenRange);
+
+    // FIXME: Can we build StylePropertySets directly?
+    // FIXME: Investigate using a smaller inline buffer
+    ParsedPropertyVector m_parsedProperties;
+    const CSSParserContext&amp; m_context;
+
+    RefPtr&lt;StyleSheetContents&gt; m_styleSheet;
+
+    // For the inspector
+    CSSParserObserverWrapper* m_observerWrapper;
+};
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserValuescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSParserValues.cpp (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserValues.cpp        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/css/parser/CSSParserValues.cpp        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -199,6 +199,24 @@
</span><span class="cx">     return selector.release();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CSSParserSelector* CSSParserSelector::parsePagePseudoSelector(const AtomicString&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();
+}
+
</ins><span class="cx"> CSSParserSelector* CSSParserSelector::parsePseudoElementSelector(CSSParserString&amp; pseudoTypeString)
</span><span class="cx"> {
</span><span class="cx">     pseudoTypeString.convertToASCIILowercaseInPlace();
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSParserValuesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSParserValues.h (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSParserValues.h        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/css/parser/CSSParserValues.h        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -203,6 +203,7 @@
</span><span class="cx"> class CSSParserSelector {
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><ins>+    // FIXME-NEWPARSER: Remove the CSSParserString-based parsing functions once the old parser is gone.
</ins><span class="cx">     static CSSParserSelector* parsePagePseudoSelector(const CSSParserString&amp; pseudoTypeString);
</span><span class="cx">     static CSSParserSelector* parsePseudoElementSelector(CSSParserString&amp; pseudoTypeString);
</span><span class="cx">     static CSSParserSelector* parsePseudoElementCueFunctionSelector(const CSSParserString&amp; functionIdentifier, Vector&lt;std::unique_ptr&lt;CSSParserSelector&gt;&gt;*);
</span><span class="lines">@@ -212,6 +213,7 @@
</span><span class="cx"> 
</span><span class="cx">     static CSSParserSelector* parsePseudoClassSelectorFromStringView(StringView&amp;);
</span><span class="cx">     static CSSParserSelector* parsePseudoElementSelectorFromStringView(StringView&amp;);
</span><ins>+    static CSSParserSelector* parsePagePseudoSelector(const AtomicString&amp;);
</ins><span class="cx">     
</span><span class="cx">     CSSParserSelector();
</span><span class="cx">     explicit CSSParserSelector(const QualifiedName&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSPropertyParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (205789 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp        2016-09-11 14:10:54 UTC (rev 205789)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -235,11 +235,15 @@
</span><span class="cx">     for (unsigned i = 0; i &lt; shorthandLength; ++i)
</span><span class="cx">         addProperty(longhands[i], property, value, important);
</span><span class="cx"> }
</span><del>-
-bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool important,
-    const CSSParserTokenRange&amp; range, const CSSParserContext&amp; context,
-    Vector&lt;CSSProperty, 256&gt;&amp; parsedProperties, StyleRule::Type ruleType)
</del><ins>+*/
+    
+bool CSSPropertyParser::parseValue(CSSPropertyID /*unresolvedProperty*/, bool /*important*/,
+    const CSSParserTokenRange&amp; /*range*/, const CSSParserContext&amp; /*context*/,
+    ParsedPropertyVector&amp; /*parsedProperties*/, StyleRule::Type /*ruleType*/)
</ins><span class="cx"> {
</span><ins>+    return false;
+    
+    /*
</ins><span class="cx">     int parsedPropertiesSize = parsedProperties.size();
</span><span class="cx"> 
</span><span class="cx">     CSSPropertyParser parser(range, context, &amp;parsedProperties);
</span><span class="lines">@@ -263,8 +267,9 @@
</span><span class="cx">         parsedProperties.shrink(parsedPropertiesSize);
</span><span class="cx"> 
</span><span class="cx">     return parseSuccess;
</span><ins>+     */
</ins><span class="cx"> }
</span><del>-
</del><ins>+/*
</ins><span class="cx"> const CSSValue* CSSPropertyParser::parseSingleValue(
</span><span class="cx">     CSSPropertyID property, const CSSParserTokenRange&amp; range, const CSSParserContext&amp; context)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSSupportsParsercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/parser/CSSSupportsParser.cpp (0 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSSupportsParser.cpp                                (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSSupportsParser.cpp        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 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:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * 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.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// &quot;AS IS&quot; 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
+// OWNER OR CONTRIBUTORS 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.
+
+#include &quot;config.h&quot;
+#include &quot;CSSSupportsParser.h&quot;
+
+#include &quot;CSSParserImpl.h&quot;
+
+namespace WebCore {
+
+CSSSupportsParser::SupportsResult CSSSupportsParser::supportsCondition(CSSParserTokenRange range, CSSParserImpl&amp; parser)
+{
+    // FIXME: The spec allows leading whitespace in @supports but not CSS.supports,
+    // but major browser vendors allow it in CSS.supports also.
+    range.consumeWhitespace();
+    return CSSSupportsParser(parser).consumeCondition(range);
+}
+
+enum ClauseType { Unresolved, Conjunction, Disjunction };
+
+CSSSupportsParser::SupportsResult CSSSupportsParser::consumeCondition(CSSParserTokenRange range)
+{
+    if (range.peek().type() == IdentToken)
+        return consumeNegation(range);
+
+    bool result;
+    ClauseType clauseType = Unresolved;
+
+    while (true) {
+        SupportsResult nextResult = consumeConditionInParenthesis(range);
+        if (nextResult == Invalid)
+            return Invalid;
+        bool nextSupported = nextResult;
+        if (clauseType == Unresolved)
+            result = nextSupported;
+        else if (clauseType == Conjunction)
+            result &amp;= nextSupported;
+        else
+            result |= nextSupported;
+
+        if (range.atEnd())
+            break;
+        if (range.consumeIncludingWhitespace().type() != WhitespaceToken)
+            return Invalid;
+        if (range.atEnd())
+            break;
+
+        const CSSParserToken&amp; token = range.consume();
+        if (token.type() != IdentToken)
+            return Invalid;
+        if (clauseType == Unresolved)
+            clauseType = token.value().length() == 3 ? Conjunction : Disjunction;
+        if ((clauseType == Conjunction &amp;&amp; !equalIgnoringASCIICase(token.value(), &quot;and&quot;))
+            || (clauseType == Disjunction &amp;&amp; !equalIgnoringASCIICase(token.value(), &quot;or&quot;)))
+            return Invalid;
+
+        if (range.consumeIncludingWhitespace().type() != WhitespaceToken)
+            return Invalid;
+    }
+    return result ? Supported : Unsupported;
+}
+
+CSSSupportsParser::SupportsResult CSSSupportsParser::consumeNegation(CSSParserTokenRange range)
+{
+    ASSERT(range.peek().type() == IdentToken);
+    if (!equalIgnoringASCIICase(range.consume().value(), &quot;not&quot;))
+        return Invalid;
+    if (range.consumeIncludingWhitespace().type() != WhitespaceToken)
+        return Invalid;
+    SupportsResult result = consumeConditionInParenthesis(range);
+    range.consumeWhitespace();
+    if (!range.atEnd() || result == Invalid)
+        return Invalid;
+    return result ? Unsupported : Supported;
+}
+
+CSSSupportsParser::SupportsResult CSSSupportsParser::consumeConditionInParenthesis(CSSParserTokenRange&amp; range)
+{
+    if (range.peek().type() == FunctionToken) {
+        range.consumeComponentValue();
+        return Unsupported;
+    }
+    if (range.peek().type() != LeftParenthesisToken)
+        return Invalid;
+    CSSParserTokenRange innerRange = range.consumeBlock();
+    innerRange.consumeWhitespace();
+    SupportsResult result = consumeCondition(innerRange);
+    if (result != Invalid)
+        return result;
+    return innerRange.peek().type() == IdentToken &amp;&amp; m_parser.supportsDeclaration(innerRange) ? Supported : Unsupported;
+}
+
+} // namespace blink
</ins></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSSupportsParserh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/parser/CSSSupportsParser.h (0 => 205790)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSSupportsParser.h                                (rev 0)
+++ trunk/Source/WebCore/css/parser/CSSSupportsParser.h        2016-09-11 18:11:42 UTC (rev 205790)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Copyright (C) 2016 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:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * 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.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// &quot;AS IS&quot; 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
+// OWNER OR CONTRIBUTORS 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.
+
+#pragma once
+
+namespace WebCore {
+
+class CSSParserImpl;
+class CSSParserTokenRange;
+
+class CSSSupportsParser {
+public:
+    enum SupportsResult {
+        Unsupported = false,
+        Supported = true,
+        Invalid
+    };
+
+    static SupportsResult supportsCondition(CSSParserTokenRange, CSSParserImpl&amp;);
+
+private:
+    CSSSupportsParser(CSSParserImpl&amp; parser)
+        : m_parser(parser) { }
+
+    SupportsResult consumeCondition(CSSParserTokenRange);
+    SupportsResult consumeNegation(CSSParserTokenRange);
+
+    SupportsResult consumeConditionInParenthesis(CSSParserTokenRange&amp;);
+
+    CSSParserImpl&amp; m_parser;
+};
+
+} // namespace WebCore
</ins></span></pre>
</div>
</div>

</body>
</html>