<!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>[190231] 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/190231">190231</a></dd>
<dt>Author</dt> <dd>hyatt@apple.com</dd>
<dt>Date</dt> <dd>2015-09-24 17:54:24 -0700 (Thu, 24 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Keep the already-parsed list of terms in custom property values so that we don't have to re-parse them
later when doing variable resolution.
https://bugs.webkit.org/show_bug.cgi?id=149544

Reviewed by Dean Jackson.

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::customPropertyValue):
(WebCore::ComputedStyleExtractor::customPropertyText):
Add a helper for getting the raw text. More closely parallels how non-custom properties work with the
extractor.

(WebCore::ComputedStyleExtractor::propertyValue):
Change propertyValue to use customPropertyText.

(WebCore::ComputedStyleExtractor::copyPropertiesInSet):
Don't copy CSS custom properties into the style declaration. This is just used for things like editing, so
we didn't need to be putting the custom properties into this set.

(WebCore::CSSComputedStyleDeclaration::getPropertyValue):
Patched to go straight to the serialized string value.

(WebCore::ComputedStyleExtractor::customPropertyValue): Deleted.
Replaced by customPropertyText.

* css/CSSComputedStyleDeclaration.h:
Rename customPropertyValue to customPropertyText and make it just return a String.

* css/CSSCustomPropertyValue.h:
(WebCore::CSSCustomPropertyValue::create):
(WebCore::CSSCustomPropertyValue::customCSSText):
(WebCore::CSSCustomPropertyValue::name):
(WebCore::CSSCustomPropertyValue::equals):
(WebCore::CSSCustomPropertyValue::CSSCustomPropertyValue):
(WebCore::CSSCustomPropertyValue::value): Deleted.
Changed to hold both a CSSParserValueList, which it adopts from the CSSParser, and a string value that
is constructed lazily only if the value is serialized. Now the problematic serialization code will only
run if someone uses the CSS OM to trigger a serialization (this should be a rare occurrence, so perf
improves with this change).

* css/CSSGrammar.y.in:
Change parsing of custom properties to be identical to regular properties. This refactoring allows
us to simply invoke the parser from style declarations as well and makes everything behave more
similarly to normal property parsing.

* css/CSSParser.cpp:
(WebCore::CSSParser::parseValue):
(WebCore::CSSParser::parseCustomPropertyValue):
(WebCore::CSSParser::parseCustomPropertyDeclaration):
(WebCore::CSSParser::addCustomPropertyDeclaration): Deleted.
* css/CSSParser.h:
(WebCore::CSSParser::setCustomPropertyName):
We now have a method for parsing custom properties that can be invoked from style declarations. The
parser list is now adopted by the CSSCustomPropertyValue.

* css/CSSParserValues.cpp:
(WebCore::CSSParserValueList::toString):
Build the string serialization code right into CSSParserValueList.

* css/CSSParserValues.h:
Add a toString() method for serialization.

* css/StyleProperties.cpp:
(WebCore::MutableStyleProperties::setProperty):
(WebCore::MutableStyleProperties::setCustomProperty):
Changed to use the new CSSParser functions. This makes the code behave almost identically to regular
property parsing.

* css/StyleResolver.cpp:
(WebCore::StyleResolver::applyProperty):
* rendering/style/RenderStyle.h:
* rendering/style/StyleCustomPropertyData.h:
Change the mapping on RenderStyle to store the custom CSS values. This way we can get to the original
parser lists for each variable when it comes time to do variable resolution.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssCSSComputedStyleDeclarationcpp">trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSComputedStyleDeclarationh">trunk/Source/WebCore/css/CSSComputedStyleDeclaration.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSCustomPropertyValueh">trunk/Source/WebCore/css/CSSCustomPropertyValue.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSGrammaryin">trunk/Source/WebCore/css/CSSGrammar.y.in</a></li>
<li><a href="#trunkSourceWebCorecssCSSParsercpp">trunk/Source/WebCore/css/CSSParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSParserh">trunk/Source/WebCore/css/CSSParser.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSParserValuescpp">trunk/Source/WebCore/css/CSSParserValues.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSParserValuesh">trunk/Source/WebCore/css/CSSParserValues.h</a></li>
<li><a href="#trunkSourceWebCorecssStylePropertiescpp">trunk/Source/WebCore/css/StyleProperties.cpp</a></li>
<li><a href="#trunkSourceWebCorecssStyleResolvercpp">trunk/Source/WebCore/css/StyleResolver.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleRenderStyleh">trunk/Source/WebCore/rendering/style/RenderStyle.h</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleStyleCustomPropertyDatah">trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/ChangeLog        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -1,3 +1,80 @@
</span><ins>+2015-09-24  David Hyatt  &lt;hyatt@apple.com&gt;
+
+        Keep the already-parsed list of terms in custom property values so that we don't have to re-parse them
+        later when doing variable resolution.
+        https://bugs.webkit.org/show_bug.cgi?id=149544
+
+        Reviewed by Dean Jackson.
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::ComputedStyleExtractor::customPropertyValue):
+        (WebCore::ComputedStyleExtractor::customPropertyText):
+        Add a helper for getting the raw text. More closely parallels how non-custom properties work with the
+        extractor.
+
+        (WebCore::ComputedStyleExtractor::propertyValue):
+        Change propertyValue to use customPropertyText.
+
+        (WebCore::ComputedStyleExtractor::copyPropertiesInSet):
+        Don't copy CSS custom properties into the style declaration. This is just used for things like editing, so
+        we didn't need to be putting the custom properties into this set.
+
+        (WebCore::CSSComputedStyleDeclaration::getPropertyValue):
+        Patched to go straight to the serialized string value.
+
+        (WebCore::ComputedStyleExtractor::customPropertyValue): Deleted.
+        Replaced by customPropertyText.
+
+        * css/CSSComputedStyleDeclaration.h:
+        Rename customPropertyValue to customPropertyText and make it just return a String.
+
+        * css/CSSCustomPropertyValue.h:
+        (WebCore::CSSCustomPropertyValue::create):
+        (WebCore::CSSCustomPropertyValue::customCSSText):
+        (WebCore::CSSCustomPropertyValue::name):
+        (WebCore::CSSCustomPropertyValue::equals):
+        (WebCore::CSSCustomPropertyValue::CSSCustomPropertyValue):
+        (WebCore::CSSCustomPropertyValue::value): Deleted.
+        Changed to hold both a CSSParserValueList, which it adopts from the CSSParser, and a string value that
+        is constructed lazily only if the value is serialized. Now the problematic serialization code will only
+        run if someone uses the CSS OM to trigger a serialization (this should be a rare occurrence, so perf
+        improves with this change).
+
+        * css/CSSGrammar.y.in:
+        Change parsing of custom properties to be identical to regular properties. This refactoring allows
+        us to simply invoke the parser from style declarations as well and makes everything behave more
+        similarly to normal property parsing.
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseValue):
+        (WebCore::CSSParser::parseCustomPropertyValue):
+        (WebCore::CSSParser::parseCustomPropertyDeclaration):
+        (WebCore::CSSParser::addCustomPropertyDeclaration): Deleted.
+        * css/CSSParser.h:
+        (WebCore::CSSParser::setCustomPropertyName):
+        We now have a method for parsing custom properties that can be invoked from style declarations. The
+        parser list is now adopted by the CSSCustomPropertyValue.
+
+        * css/CSSParserValues.cpp:
+        (WebCore::CSSParserValueList::toString):
+        Build the string serialization code right into CSSParserValueList.
+
+        * css/CSSParserValues.h:
+        Add a toString() method for serialization.
+
+        * css/StyleProperties.cpp:
+        (WebCore::MutableStyleProperties::setProperty):
+        (WebCore::MutableStyleProperties::setCustomProperty):
+        Changed to use the new CSSParser functions. This makes the code behave almost identically to regular
+        property parsing.
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::applyProperty):
+        * rendering/style/RenderStyle.h:
+        * rendering/style/StyleCustomPropertyData.h:
+        Change the mapping on RenderStyle to store the custom CSS values. This way we can get to the original
+        parser lists for each variable when it comes time to do variable resolution.
+
</ins><span class="cx"> 2015-09-24  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rewrite Range::insertNode() as per the latest DOM specification
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSComputedStyleDeclarationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -2106,10 +2106,15 @@
</span><span class="cx">     if (!style || !style-&gt;hasCustomProperty(propertyName))
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><del>-    String result = style-&gt;getCustomPropertyValue(propertyName);
-    return CSSCustomPropertyValue::create(propertyName, result);
</del><ins>+    return style-&gt;getCustomPropertyValue(propertyName);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String ComputedStyleExtractor::customPropertyText(const String&amp; propertyName) const
+{
+    RefPtr&lt;CSSValue&gt; propertyValue = this-&gt;customPropertyValue(propertyName);
+    return propertyValue ? propertyValue-&gt;cssText() : emptyString();
+}
+
</ins><span class="cx"> RefPtr&lt;CSSValue&gt; ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
</span><span class="cx"> {
</span><span class="cx">     Node* styledNode = this-&gt;styledNode();
</span><span class="lines">@@ -3595,7 +3600,7 @@
</span><span class="cx">     if (!style)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><del>-    const HashMap&lt;AtomicString, String&gt;* customProperties = style-&gt;customProperties();
</del><ins>+    const HashMap&lt;AtomicString, RefPtr&lt;CSSValue&gt;&gt;* customProperties = style-&gt;customProperties();
</ins><span class="cx">     return numComputedProperties + (customProperties ? customProperties-&gt;size() : 0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3704,22 +3709,6 @@
</span><span class="cx">         if (value)
</span><span class="cx">             list.append(CSSProperty(set[i], value.release(), false));
</span><span class="cx">     }
</span><del>-    
-    auto* styledNode = this-&gt;styledNode();
-    if (styledNode) {
-        RefPtr&lt;RenderStyle&gt; style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, CSSPropertyCustom);
-        if (style) {
-            const auto* customProperties = style-&gt;customProperties();
-            if (customProperties) {
-                HashMap&lt;AtomicString, String&gt;::const_iterator end = customProperties-&gt;end();
-                for (HashMap&lt;AtomicString, String&gt;::const_iterator it = customProperties-&gt;begin(); it != end; ++it) {
-                    RefPtr&lt;CSSCustomPropertyValue&gt; value = CSSCustomPropertyValue::create(it-&gt;key, it-&gt;value);
-                    list.append(CSSProperty(CSSPropertyCustom, value.release(), false));
-                }
-            }
-        }
-    }
-    
</del><span class="cx">     return MutableStyleProperties::create(list.data(), list.size());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3730,10 +3719,8 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;CSSValue&gt; CSSComputedStyleDeclaration::getPropertyCSSValue(const String&amp; propertyName)
</span><span class="cx"> {
</span><del>-    if (isCustomPropertyName(propertyName)) {
-        RefPtr&lt;CSSValue&gt; value = ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName);
-        return value ? value-&gt;cloneForCSSOM() : nullptr;
-    }
</del><ins>+    if (isCustomPropertyName(propertyName))
+        return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName);
</ins><span class="cx"> 
</span><span class="cx">     CSSPropertyID propertyID = cssPropertyID(propertyName);
</span><span class="cx">     if (!propertyID)
</span><span class="lines">@@ -3744,12 +3731,8 @@
</span><span class="cx"> 
</span><span class="cx"> String CSSComputedStyleDeclaration::getPropertyValue(const String &amp;propertyName)
</span><span class="cx"> {
</span><del>-    if (isCustomPropertyName(propertyName)) {
-        RefPtr&lt;CSSValue&gt; value = ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName);
-        if (!value)
-            return String();
-        return value-&gt;cssText();
-    }
</del><ins>+    if (isCustomPropertyName(propertyName))
+        return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyText(propertyName);
</ins><span class="cx"> 
</span><span class="cx">     CSSPropertyID propertyID = cssPropertyID(propertyName);
</span><span class="cx">     if (!propertyID)
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSComputedStyleDeclarationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSComputedStyleDeclaration.h (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSComputedStyleDeclaration.h        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/CSSComputedStyleDeclaration.h        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">     ComputedStyleExtractor(PassRefPtr&lt;Node&gt;, bool allowVisitedStyle = false, PseudoId = NOPSEUDO);
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;CSSValue&gt; propertyValue(CSSPropertyID, EUpdateLayout = UpdateLayout) const;
</span><ins>+    String customPropertyText(const String&amp; propertyName) const;
</ins><span class="cx">     RefPtr&lt;CSSValue&gt; customPropertyValue(const String&amp; propertyName) const;
</span><span class="cx"> 
</span><span class="cx">     // Helper methods for HTML editing.
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSCustomPropertyValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSCustomPropertyValue.h (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSCustomPropertyValue.h        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/CSSCustomPropertyValue.h        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -26,34 +26,47 @@
</span><span class="cx"> #ifndef CSSCustomPropertyValue_h
</span><span class="cx"> #define CSSCustomPropertyValue_h
</span><span class="cx"> 
</span><ins>+#include &quot;CSSParserValues.h&quot;
</ins><span class="cx"> #include &quot;CSSValue.h&quot;
</span><ins>+#include &lt;wtf/text/WTFString.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class CSSCustomPropertyValue : public CSSValue {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;CSSCustomPropertyValue&gt; create(const AtomicString&amp; name, const String&amp; value)
</del><ins>+    static Ref&lt;CSSCustomPropertyValue&gt; create(const AtomicString&amp; name, std::unique_ptr&lt;CSSParserValueList&gt;&amp; valueList)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new CSSCustomPropertyValue(name, value));
</del><ins>+        return adoptRef(*new CSSCustomPropertyValue(name, valueList));
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool equals(const CSSCustomPropertyValue&amp; other) const { return m_name == other.m_name &amp;&amp; m_value == other.m_value; }
</del><ins>+    String customCSSText() const
+    {
+        if (!m_serialized) {
+            m_serialized = true;
+            m_stringValue = m_parserValue ? m_parserValue-&gt;toString() : &quot;&quot;;
+        }
+        return m_stringValue;
+    }
</ins><span class="cx"> 
</span><del>-    String customCSSText() const { return value(); }
-
</del><span class="cx">     const AtomicString&amp; name() const { return m_name; }
</span><del>-    const String&amp; value() const { return m_value; }
</del><span class="cx">     
</span><ins>+    // FIXME: Should arguably implement equals on all of the CSSParserValues, but CSSValue equivalence
+    // is rarely used, so serialization to compare is probably fine.
+    bool equals(const CSSCustomPropertyValue&amp; other) const { return m_name == other.m_name &amp;&amp; customCSSText() == other.customCSSText(); }
+
</ins><span class="cx"> private:
</span><del>-    CSSCustomPropertyValue(const AtomicString&amp; name, const String&amp; value)
</del><ins>+    CSSCustomPropertyValue(const AtomicString&amp; name, std::unique_ptr&lt;CSSParserValueList&gt;&amp; valueList)
</ins><span class="cx">         : CSSValue(CustomPropertyClass)
</span><span class="cx">         , m_name(name)
</span><del>-        , m_value(value)
</del><ins>+        , m_parserValue(WTF::move(valueList))
+        , m_serialized(false)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     const AtomicString m_name;
</span><del>-    const String m_value;
</del><ins>+    std::unique_ptr&lt;CSSParserValueList&gt; m_parserValue;
+    mutable String m_stringValue;
+    mutable bool m_serialized;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSGrammaryin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSGrammar.y.in (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSGrammar.y.in        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/CSSGrammar.y.in        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -1539,10 +1539,21 @@
</span><span class="cx"> 
</span><span class="cx"> declaration:
</span><span class="cx">     CUSTOM_PROPERTY maybe_space ':' maybe_space expr priority {
</span><ins>+        $$ = false;
+        bool isPropertyParsed = false;
</ins><span class="cx">         std::unique_ptr&lt;CSSParserValueList&gt; propertyValue($5);
</span><del>-        parser-&gt;addCustomPropertyDeclaration($1, propertyValue.get(), $6);
-        $$ = true;
-        parser-&gt;markPropertyEnd($6, true);
</del><ins>+        if (propertyValue) {
+            parser-&gt;m_valueList = WTF::move(propertyValue);
+            int oldParsedProperties = parser-&gt;m_parsedProperties.size();
+            parser-&gt;setCustomPropertyName($1);
+            $$ = parser-&gt;parseValue(CSSPropertyCustom, $6);
+            if (!$$)
+                parser-&gt;rollbackLastProperties(parser-&gt;m_parsedProperties.size() - oldParsedProperties);
+            else
+                isPropertyParsed = true;
+            parser-&gt;m_valueList = nullptr;
+        }
+        parser-&gt;markPropertyEnd($6, isPropertyParsed);
</ins><span class="cx">     }
</span><span class="cx">     | property ':' maybe_space expr priority {
</span><span class="cx">         $$ = false;
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParser.cpp (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.cpp        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/CSSParser.cpp        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -1351,6 +1351,19 @@
</span><span class="cx">     return parser.parseValue(declaration, propertyID, string, important, contextStyleSheet);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CSSParser::ParseResult CSSParser::parseCustomPropertyValue(MutableStyleProperties* declaration, const AtomicString&amp; propertyName, const String&amp; string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
+{
+    CSSParserContext context(cssParserMode);
+    if (contextStyleSheet) {
+        context = contextStyleSheet-&gt;parserContext();
+        context.mode = cssParserMode;
+    }
+
+    CSSParser parser(context);
+    parser.setCustomPropertyName(propertyName);
+    return parser.parseValue(declaration, CSSPropertyCustom, string, important, contextStyleSheet);
+}
+
</ins><span class="cx"> CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String&amp; string, bool important, StyleSheetContents* contextStyleSheet)
</span><span class="cx"> {
</span><span class="cx">     setStyleSheet(contextStyleSheet);
</span><span class="lines">@@ -1895,6 +1908,12 @@
</span><span class="cx"> {
</span><span class="cx">     if (!m_valueList || !m_valueList-&gt;current())
</span><span class="cx">         return false;
</span><ins>+    
+    if (propId == CSSPropertyCustom) {
+        // FIXME: For now put this ahead of inherit/initial processing.
+        // Eventually we want to support initial and inherit.
+        return parseCustomPropertyDeclaration(important);
+    }
</ins><span class="cx"> 
</span><span class="cx">     ValueWithCalculation valueWithCalculation(*m_valueList-&gt;current());
</span><span class="cx">     CSSValueID id = valueWithCalculation.value().id;
</span><span class="lines">@@ -4137,26 +4156,12 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSParser::addCustomPropertyDeclaration(const CSSParserString&amp; name, CSSParserValueList* value, bool important)
</del><ins>+bool CSSParser::parseCustomPropertyDeclaration(bool important)
</ins><span class="cx"> {
</span><del>-    if (!value)
-        return;
-
-    // The custom property comes in as a parsed set of CSSParserValues collected into a list.
-    // For CSS variables, we just want to treat the entire set of values as a string, so what we do
-    // is build up a set of CSSValues and serialize them using cssText, separating multiple values
-    // with spaces.
-    AtomicString propertyName = name;
-    StringBuilder builder;
-    for (unsigned i = 0; i &lt; value-&gt;size(); i++) {
-        if (i)
-            builder.append(' ');
-        RefPtr&lt;CSSValue&gt; cssValue = value-&gt;valueAt(i)-&gt;createCSSValue();
-        if (!cssValue)
-            return;
-        builder.append(cssValue-&gt;cssText());
-    }
-    addProperty(CSSPropertyCustom, CSSCustomPropertyValue::create(propertyName, builder.toString().lower()), important, false);
</del><ins>+    if (m_customPropertyName.isEmpty() || !m_valueList)
+        return false;
+    addProperty(CSSPropertyCustom, CSSCustomPropertyValue::create(m_customPropertyName, m_valueList), important, false);
+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // [ &lt;string&gt; | &lt;uri&gt; | &lt;counter&gt; | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParser.h (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.h        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/CSSParser.h        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -119,6 +119,7 @@
</span><span class="cx">     bool parseSupportsCondition(const String&amp;);
</span><span class="cx"> 
</span><span class="cx">     static ParseResult parseValue(MutableStyleProperties*, CSSPropertyID, const String&amp;, bool important, CSSParserMode, StyleSheetContents*);
</span><ins>+    static ParseResult parseCustomPropertyValue(MutableStyleProperties*, const AtomicString&amp; propertyName, const String&amp;, bool important, CSSParserMode, StyleSheetContents* contextStyleSheet);
</ins><span class="cx"> 
</span><span class="cx">     static bool parseColor(RGBA32&amp; color, const String&amp;, bool strict = false);
</span><span class="cx">     static bool isValidSystemColorValue(CSSValueID);
</span><span class="lines">@@ -143,7 +144,7 @@
</span><span class="cx">     bool parseQuotes(CSSPropertyID, bool important);
</span><span class="cx">     bool parseAlt(CSSPropertyID, bool important);
</span><span class="cx">     
</span><del>-    void addCustomPropertyDeclaration(const CSSParserString&amp;, CSSParserValueList*, bool important);
</del><ins>+    bool parseCustomPropertyDeclaration(bool important);
</ins><span class="cx">     
</span><span class="cx">     RefPtr&lt;CSSValue&gt; parseAttr(CSSParserValueList&amp; args);
</span><span class="cx"> 
</span><span class="lines">@@ -395,6 +396,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool m_important;
</span><span class="cx">     CSSPropertyID m_id;
</span><ins>+    AtomicString m_customPropertyName;
</ins><span class="cx">     StyleSheetContents* m_styleSheet;
</span><span class="cx">     RefPtr&lt;StyleRuleBase&gt; m_rule;
</span><span class="cx">     RefPtr&lt;StyleKeyframe&gt; m_keyframe;
</span><span class="lines">@@ -466,6 +468,8 @@
</span><span class="cx">     Location currentLocation();
</span><span class="cx">     static bool isCalculation(CSSParserValue&amp;);
</span><span class="cx"> 
</span><ins>+    void setCustomPropertyName(const AtomicString&amp; propertyName) { m_customPropertyName = propertyName; }
+
</ins><span class="cx"> private:
</span><span class="cx">     bool is8BitSource() { return m_is8BitSource; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserValuescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParserValues.cpp (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParserValues.cpp        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/CSSParserValues.cpp        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include &quot;CSSSelector.h&quot;
</span><span class="cx"> #include &quot;CSSSelectorList.h&quot;
</span><span class="cx"> #include &quot;SelectorPseudoTypeMap.h&quot;
</span><ins>+#include &lt;wtf/text/StringBuilder.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -66,6 +67,24 @@
</span><span class="cx">         m_values.append(*(valueList.valueAt(i)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String CSSParserValueList::toString()
+{
+    // Build up a set of CSSValues and serialize them using cssText, separating multiple values
+    // with spaces.
+    // FIXME: Teach CSSParserValues how to serialize so that we don't have to create CSSValues
+    // just to perform this serialization.
+    StringBuilder builder;
+    for (unsigned i = 0; i &lt; size(); i++) {
+        if (i)
+            builder.append(' ');
+        RefPtr&lt;CSSValue&gt; cssValue = valueAt(i)-&gt;createCSSValue();
+        if (!cssValue)
+            return &quot;&quot;;
+        builder.append(cssValue-&gt;cssText());
+    }
+    return builder.toString().lower();
+}
+
</ins><span class="cx"> PassRefPtr&lt;CSSValue&gt; CSSParserValue::createCSSValue()
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;CSSValue&gt; parsedValue;
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserValuesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParserValues.h (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParserValues.h        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/CSSParserValues.h        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -168,6 +168,8 @@
</span><span class="cx">     CSSParserValue* valueAt(unsigned i) { return i &lt; m_values.size() ? &amp;m_values[i] : 0; }
</span><span class="cx"> 
</span><span class="cx">     void clear() { m_values.clear(); }
</span><ins>+    
+    String toString();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     unsigned m_current;
</span></span></pre></div>
<a id="trunkSourceWebCorecssStylePropertiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleProperties.cpp (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleProperties.cpp        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/StyleProperties.cpp        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -728,7 +728,7 @@
</span><span class="cx">     return CSSParser::parseValue(this, propertyID, value, important, cssParserMode(), contextStyleSheet) == CSSParser::ParseResult::Changed;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool MutableStyleProperties::setCustomProperty(const String&amp; propertyName, const String&amp; value, bool important, StyleSheetContents* /*contextStyleSheet*/)
</del><ins>+bool MutableStyleProperties::setCustomProperty(const String&amp; propertyName, const String&amp; value, bool important, StyleSheetContents* contextStyleSheet)
</ins><span class="cx"> {
</span><span class="cx">     // Setting the value to an empty string just removes the property in both IE and Gecko.
</span><span class="cx">     // Setting it to null seems to produce less consistent results, but we treat it just the same.
</span><span class="lines">@@ -737,10 +737,7 @@
</span><span class="cx"> 
</span><span class="cx">     // When replacing an existing property value, this moves the property to the end of the list.
</span><span class="cx">     // Firefox preserves the position, and MSIE moves the property to the beginning.
</span><del>-    RefPtr&lt;CSSCustomPropertyValue&gt; customValue = CSSCustomPropertyValue::create(propertyName, value);
-    addParsedProperty(CSSProperty(CSSPropertyCustom, customValue, important));
-    
-    return true;
</del><ins>+    return CSSParser::parseCustomPropertyValue(this, propertyName, value, important, cssParserMode(), contextStyleSheet) == CSSParser::ParseResult::Changed;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MutableStyleProperties::setProperty(CSSPropertyID propertyID, PassRefPtr&lt;CSSValue&gt; prpValue, bool important)
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleResolvercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleResolver.cpp (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleResolver.cpp        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/css/StyleResolver.cpp        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -1901,7 +1901,7 @@
</span><span class="cx">     
</span><span class="cx">     if (id == CSSPropertyCustom) {
</span><span class="cx">         CSSCustomPropertyValue* customProperty = &amp;downcast&lt;CSSCustomPropertyValue&gt;(*value);
</span><del>-        state.style()-&gt;setCustomPropertyValue(customProperty-&gt;name(), customProperty-&gt;value());
</del><ins>+        state.style()-&gt;setCustomPropertyValue(customProperty-&gt;name(), value);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleRenderStyleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/RenderStyle.h        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -513,10 +513,10 @@
</span><span class="cx"> 
</span><span class="cx">     const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); }
</span><span class="cx"> 
</span><del>-    void setCustomPropertyValue(const AtomicString&amp; name, const String&amp; value) { rareInheritedData.access()-&gt;m_customProperties.access()-&gt;setCustomPropertyValue(name, value); }
-    String getCustomPropertyValue(const AtomicString&amp; name) const { return rareInheritedData-&gt;m_customProperties-&gt;getCustomPropertyValue(name); }
</del><ins>+    void setCustomPropertyValue(const AtomicString&amp; name, const RefPtr&lt;CSSValue&gt;&amp; value) { rareInheritedData.access()-&gt;m_customProperties.access()-&gt;setCustomPropertyValue(name, value); }
+    RefPtr&lt;CSSValue&gt; getCustomPropertyValue(const AtomicString&amp; name) const { return rareInheritedData-&gt;m_customProperties-&gt;getCustomPropertyValue(name); }
</ins><span class="cx">     bool hasCustomProperty(const AtomicString&amp; name) const { return rareInheritedData-&gt;m_customProperties-&gt;hasCustomProperty(name); }
</span><del>-    const HashMap&lt;AtomicString, String&gt;* customProperties() const { return &amp;(rareInheritedData-&gt;m_customProperties-&gt;m_values); }
</del><ins>+    const HashMap&lt;AtomicString, RefPtr&lt;CSSValue&gt;&gt;* customProperties() const { return &amp;(rareInheritedData-&gt;m_customProperties-&gt;m_values); }
</ins><span class="cx"> 
</span><span class="cx">     void setHasViewportUnits(bool hasViewportUnits = true) { noninherited_flags.setHasViewportUnits(hasViewportUnits); }
</span><span class="cx">     bool hasViewportUnits() const { return noninherited_flags.hasViewportUnits(); }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleStyleCustomPropertyDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h (190230 => 190231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h        2015-09-25 00:17:16 UTC (rev 190230)
+++ trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h        2015-09-25 00:54:24 UTC (rev 190231)
</span><span class="lines">@@ -25,10 +25,13 @@
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><ins>+#include &lt;wtf/RefPtr.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/AtomicStringHash.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class CSSValue;
+
</ins><span class="cx"> class StyleCustomPropertyData : public RefCounted&lt;StyleCustomPropertyData&gt; {
</span><span class="cx"> public:
</span><span class="cx">     static Ref&lt;StyleCustomPropertyData&gt; create() { return adoptRef(*new StyleCustomPropertyData); }
</span><span class="lines">@@ -37,11 +40,11 @@
</span><span class="cx">     bool operator==(const StyleCustomPropertyData&amp; o) const { return m_values == o.m_values; }
</span><span class="cx">     bool operator!=(const StyleCustomPropertyData &amp;o) const { return !(*this == o); }
</span><span class="cx">     
</span><del>-    void setCustomPropertyValue(const AtomicString&amp; name, const String&amp; value) { m_values.set(name, value); }
-    String getCustomPropertyValue(const AtomicString&amp; name) const { return m_values.get(name); }
</del><ins>+    void setCustomPropertyValue(const AtomicString&amp; name, const RefPtr&lt;CSSValue&gt;&amp; value) { m_values.set(name, value); }
+    RefPtr&lt;CSSValue&gt; getCustomPropertyValue(const AtomicString&amp; name) const { return m_values.get(name); }
</ins><span class="cx">     bool hasCustomProperty(const AtomicString&amp; name) const { return m_values.contains(name); }
</span><span class="cx"> 
</span><del>-    HashMap&lt;AtomicString, String&gt; m_values;
</del><ins>+    HashMap&lt;AtomicString, RefPtr&lt;CSSValue&gt;&gt; m_values;
</ins><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     explicit StyleCustomPropertyData()
</span><span class="lines">@@ -49,7 +52,7 @@
</span><span class="cx">     { }
</span><span class="cx">     StyleCustomPropertyData(const StyleCustomPropertyData&amp; other)
</span><span class="cx">         : RefCounted&lt;StyleCustomPropertyData&gt;()
</span><del>-        , m_values(HashMap&lt;AtomicString, String&gt;(other.m_values))
</del><ins>+        , m_values(HashMap&lt;AtomicString, RefPtr&lt;CSSValue&gt;&gt;(other.m_values))
</ins><span class="cx">     { }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>