<!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>[190209] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/190209">190209</a></dd>
<dt>Author</dt> <dd>hyatt@apple.com</dd>
<dt>Date</dt> <dd>2015-09-24 11:15:52 -0700 (Thu, 24 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add support for CSS Custom Properties (in preparation for implementing CSS Variables).
https://bugs.webkit.org/show_bug.cgi?id=130397

Reviewed by Antti Koivisto.

Source/WebCore:

Added new tests in fast/css/custom-properties.

* WebCore.xcodeproj/project.pbxproj:
Add new header files to the project (CSSCustomPropertyValue and StyleCustomPropertyData).

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::customPropertyValue):
(WebCore::ComputedStyleExtractor::propertyValue):
If a custom property value is queried (i.e., it starts with &quot;--&quot;), then we use our
customPropertyValue lookup to go to the RenderStyle and fetch the appropriate custom property
value from the StyleCustomPropertyData.

(WebCore::CSSComputedStyleDeclaration::length):
(WebCore::CSSComputedStyleDeclaration::item):
Patched to include custom properties in the returned array. They appear at the end of the array
after the built-in properties.

(WebCore::ComputedStyleExtractor::propertyMatches):
Patched to check custom properties.

(WebCore::ComputedStyleExtractor::copyPropertiesInSet):
Make sure the custom properties get copied into the StyleDeclaration.

(WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
(WebCore::CSSComputedStyleDeclaration::getPropertyValue):
Patched to call customPropertyValue for custom properties.

* css/CSSComputedStyleDeclaration.h:
Add customPropertyValue() to ComputedStyleExtractor.

* css/CSSCustomPropertyValue.h: Added.
(WebCore::CSSCustomPropertyValue::create):
(WebCore::CSSCustomPropertyValue::equals):
(WebCore::CSSCustomPropertyValue::customCSSText):
(WebCore::CSSCustomPropertyValue::name):
(WebCore::CSSCustomPropertyValue::value):
(WebCore::CSSCustomPropertyValue::CSSCustomPropertyValue):
Custom properties are parsed as a property with an ID of CSSPropertyCustom and a CSSCustomPropertyValue
that holds both the name and the value of the property. Ultimately we might want to just ditch property IDs in
favor of AtomicStrings for all properties, and then the need to special case custom properties would go
away. For now, though, this is the way we work custom properties into the existing system.

* css/CSSGrammar.y.in:
Add a production for recognizing custom properties and storing them using a property ID of CSSPropertyCustom
and a CSSCustomPropertyValue that has the name/value pair.

* css/CSSParser.cpp:
(WebCore::filterProperties):
Patched to track seen custom properties and to handle them correctly.

(WebCore::CSSParser::createStyleProperties):
Pass in a seenCustomProperties table to ensure we bail when encountering the same custom property twice.

(WebCore::CSSParser::addCustomPropertyDeclaration):
Called from the grammar production to create the CSSCustomPropertyValue.

(WebCore::isCustomPropertyIdentifier):
Recognize the -- custom property during lexing.

(WebCore::CSSParser::parseIdentifier):
Patched to return a CUSTOM_PROPERTY token when a custom property is identified.

 * css/CSSParser.h:
(WebCore::isCustomPropertyName):
Add a helper function for asking if a property name is custom.

* css/CSSValue.cpp:
(WebCore::CSSValue::equals):
(WebCore::CSSValue::cssText):
(WebCore::CSSValue::destroy):
* css/CSSValue.h:
Patched to add support for CSSCustomPropertyValue.

* css/PropertySetCSSStyleDeclaration.cpp:
(WebCore::PropertySetCSSStyleDeclaration::getPropertyCSSValue):
(WebCore::PropertySetCSSStyleDeclaration::getPropertyValue):
(WebCore::PropertySetCSSStyleDeclaration::getPropertyPriority):
(WebCore::PropertySetCSSStyleDeclaration::setProperty):
(WebCore::PropertySetCSSStyleDeclaration::removeProperty):
Add code for handling custom properties in the CSS OM.

* css/StyleProperties.cpp:
(WebCore::StyleProperties::getPropertyValue):
(WebCore::StyleProperties::getCustomPropertyValue):
(WebCore::StyleProperties::getPropertyCSSValue):
(WebCore::StyleProperties::getCustomPropertyCSSValue):
(WebCore::MutableStyleProperties::removeProperty):
(WebCore::MutableStyleProperties::removeCustomProperty):
(WebCore::StyleProperties::propertyIsImportant):
(WebCore::StyleProperties::customPropertyIsImportant):
(WebCore::MutableStyleProperties::setProperty):
(WebCore::MutableStyleProperties::setCustomProperty):
(WebCore::MutableStyleProperties::addParsedProperty):
(WebCore::MutableStyleProperties::findPropertyIndex):
(WebCore::ImmutableStyleProperties::findCustomPropertyIndex):
(WebCore::MutableStyleProperties::findCustomPropertyIndex):
(WebCore::MutableStyleProperties::findCSSPropertyWithID):
(WebCore::MutableStyleProperties::findCustomCSSPropertyWithName):
(WebCore::StyleProperties::propertyMatches):
(WebCore::StyleProperties::PropertyReference::cssName):
* css/StyleProperties.h:
(WebCore::StyleProperties::findCustomPropertyIndex):
Patched to support handling custom properties in the CSS OM. We have to create equivalent methods that operate
on AtomicString propertyNames instead of on property IDs.

* css/StyleResolver.cpp:
(WebCore::StyleResolver::CascadedProperties::customProperties):
(WebCore::StyleResolver::styleForKeyframe):
(WebCore::StyleResolver::styleForPage):
(WebCore::StyleResolver::applyMatchedProperties):
(WebCore::StyleResolver::applyProperty):
(WebCore::StyleResolver::CascadedProperties::set):
(WebCore::StyleResolver::applyCascadedProperties):
The resolver has to hold a HashMap from AtomicStrings to Properties. It matches identically to how built-in
properties work except that an extensible table (HashMap) is used to hold the property data.

* css/makeprop.pl:
Patched to include the special CSSPropertyCustom value of 1 (just after the CSSPropertyInvalid id value but before the first
built-in property value).

* inspector/InspectorStyleSheet.cpp:
(WebCore::InspectorStyle::getText):
(WebCore::lowercasePropertyName):
(WebCore::InspectorStyle::populateAllProperties):
Patch inspector to not lowercase CSS custom property names, since they are case-sensitive.

* rendering/style/RenderStyle.h:
* rendering/style/StyleCustomPropertyData.h: Added.
(WebCore::StyleCustomPropertyData::create):
(WebCore::StyleCustomPropertyData::copy):
(WebCore::StyleCustomPropertyData::operator==):
(WebCore::StyleCustomPropertyData::operator!=):
(WebCore::StyleCustomPropertyData::setCustomPropertyValue):
(WebCore::StyleCustomPropertyData::getCustomPropertyValue):
(WebCore::StyleCustomPropertyData::hasCustomProperty):
(WebCore::StyleCustomPropertyData::StyleCustomPropertyData):
* rendering/style/StyleRareInheritedData.cpp:
(WebCore::StyleRareInheritedData::StyleRareInheritedData):
(WebCore::StyleRareInheritedData::operator==):
* rendering/style/StyleRareInheritedData.h:
The front end storage in the RenderStyle for custom properties. For now, custom properties are always inherited, so the
data is in StyleRareInheritedData.

LayoutTests:

* fast/css/custom-properties: Added.
* fast/css/custom-properties/computed-style-access-expected.html: Added.
* fast/css/custom-properties/computed-style-access-inherited-expected.html: Added.
* fast/css/custom-properties/computed-style-access-inherited.html: Added.
* fast/css/custom-properties/computed-style-access.html: Added.
* fast/css/custom-properties/inline-style-property-get-expected.html: Added.
* fast/css/custom-properties/inline-style-property-get.html: Added.
* fast/css/custom-properties/rule-property-get-css-value-expected.html: Added.
* fast/css/custom-properties/rule-property-get-css-value.html: Added.
* fast/css/custom-properties/rule-property-get-expected.html: Added.
* fast/css/custom-properties/rule-property-get.html: Added.
* fast/css/custom-properties/rule-property-priority-expected.html: Added.
* fast/css/custom-properties/rule-property-priority.html: Added.
* fast/css/custom-properties/rule-property-set-expected.html: Added.
* fast/css/custom-properties/rule-property-set.html: Added.
* fast/css/custom-properties/rule-serialization-expected.html: Added.
* fast/css/custom-properties/rule-serialization.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</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="#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="#trunkSourceWebCorecssCSSValuecpp">trunk/Source/WebCore/css/CSSValue.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSValueh">trunk/Source/WebCore/css/CSSValue.h</a></li>
<li><a href="#trunkSourceWebCorecssPropertySetCSSStyleDeclarationcpp">trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp</a></li>
<li><a href="#trunkSourceWebCorecssStylePropertiescpp">trunk/Source/WebCore/css/StyleProperties.cpp</a></li>
<li><a href="#trunkSourceWebCorecssStylePropertiesh">trunk/Source/WebCore/css/StyleProperties.h</a></li>
<li><a href="#trunkSourceWebCorecssStyleResolvercpp">trunk/Source/WebCore/css/StyleResolver.cpp</a></li>
<li><a href="#trunkSourceWebCorecssmakeproppl">trunk/Source/WebCore/css/makeprop.pl</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorStyleSheetcpp">trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleRenderStyleh">trunk/Source/WebCore/rendering/style/RenderStyle.h</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleStyleRareInheritedDatacpp">trunk/Source/WebCore/rendering/style/StyleRareInheritedData.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleStyleRareInheritedDatah">trunk/Source/WebCore/rendering/style/StyleRareInheritedData.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/fast/css/custom-properties/</li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiescomputedstyleaccessexpectedhtml">trunk/LayoutTests/fast/css/custom-properties/computed-style-access-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiescomputedstyleaccessinheritedexpectedhtml">trunk/LayoutTests/fast/css/custom-properties/computed-style-access-inherited-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiescomputedstyleaccessinheritedhtml">trunk/LayoutTests/fast/css/custom-properties/computed-style-access-inherited.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiescomputedstyleaccesshtml">trunk/LayoutTests/fast/css/custom-properties/computed-style-access.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesinlinestylepropertygetexpectedhtml">trunk/LayoutTests/fast/css/custom-properties/inline-style-property-get-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesinlinestylepropertygethtml">trunk/LayoutTests/fast/css/custom-properties/inline-style-property-get.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesrulepropertygetcssvalueexpectedhtml">trunk/LayoutTests/fast/css/custom-properties/rule-property-get-css-value-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesrulepropertygetcssvaluehtml">trunk/LayoutTests/fast/css/custom-properties/rule-property-get-css-value.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesrulepropertygetexpectedhtml">trunk/LayoutTests/fast/css/custom-properties/rule-property-get-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesrulepropertygethtml">trunk/LayoutTests/fast/css/custom-properties/rule-property-get.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesrulepropertypriorityexpectedhtml">trunk/LayoutTests/fast/css/custom-properties/rule-property-priority-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesrulepropertypriorityhtml">trunk/LayoutTests/fast/css/custom-properties/rule-property-priority.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesrulepropertysetexpectedhtml">trunk/LayoutTests/fast/css/custom-properties/rule-property-set-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesrulepropertysethtml">trunk/LayoutTests/fast/css/custom-properties/rule-property-set.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesruleserializationexpectedhtml">trunk/LayoutTests/fast/css/custom-properties/rule-serialization-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcsscustompropertiesruleserializationhtml">trunk/LayoutTests/fast/css/custom-properties/rule-serialization.html</a></li>
<li><a href="#trunkSourceWebCorecssCSSCustomPropertyValueh">trunk/Source/WebCore/css/CSSCustomPropertyValue.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="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/LayoutTests/ChangeLog        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2015-09-24  David Hyatt  &lt;hyatt@apple.com&gt;
+
+        Add support for CSS Custom Properties (in preparation for implementing CSS Variables).
+        https://bugs.webkit.org/show_bug.cgi?id=130397
+
+        Reviewed by Antti Koivisto.
+
+        * fast/css/custom-properties: Added.
+        * fast/css/custom-properties/computed-style-access-expected.html: Added.
+        * fast/css/custom-properties/computed-style-access-inherited-expected.html: Added.
+        * fast/css/custom-properties/computed-style-access-inherited.html: Added.
+        * fast/css/custom-properties/computed-style-access.html: Added.
+        * fast/css/custom-properties/inline-style-property-get-expected.html: Added.
+        * fast/css/custom-properties/inline-style-property-get.html: Added.
+        * fast/css/custom-properties/rule-property-get-css-value-expected.html: Added.
+        * fast/css/custom-properties/rule-property-get-css-value.html: Added.
+        * fast/css/custom-properties/rule-property-get-expected.html: Added.
+        * fast/css/custom-properties/rule-property-get.html: Added.
+        * fast/css/custom-properties/rule-property-priority-expected.html: Added.
+        * fast/css/custom-properties/rule-property-priority.html: Added.
+        * fast/css/custom-properties/rule-property-set-expected.html: Added.
+        * fast/css/custom-properties/rule-property-set.html: Added.
+        * fast/css/custom-properties/rule-serialization-expected.html: Added.
+        * fast/css/custom-properties/rule-serialization.html: Added.
+
</ins><span class="cx"> 2015-09-24  ChangSeok Oh  &lt;changseok.oh@collabora.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rebaseline media/media-controls-play-button-updates.html.
</span></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiescomputedstyleaccessexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/computed-style-access-expected.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/computed-style-access-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/computed-style-access-expected.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+:root { --one: 10px; --two: 20px; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;script&gt;
+document.write(document.styleSheets[0].cssRules[0].style.getPropertyValue(&quot;--one&quot;) + &quot; &quot; + document.styleSheets[0].cssRules[0].style.getPropertyValue(&quot;--two&quot;))
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiescomputedstyleaccessinheritedexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/computed-style-access-inherited-expected.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/computed-style-access-inherited-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/computed-style-access-inherited-expected.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+:root { --one: 10px; --two: 20px; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;script&gt;
+document.write(document.styleSheets[0].cssRules[0].style.getPropertyValue(&quot;--one&quot;) + &quot; &quot; + document.styleSheets[0].cssRules[0].style.getPropertyValue(&quot;--two&quot;))
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiescomputedstyleaccessinheritedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/computed-style-access-inherited.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/computed-style-access-inherited.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/computed-style-access-inherited.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+:root { --one: 10px; --another: 20px; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;script&gt;
+document.write(getComputedStyle(document.body).getPropertyValue(&quot;--one&quot;) + &quot; &quot; + getComputedStyle(document.body).getPropertyValue(&quot;--another&quot;))
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiescomputedstyleaccesshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/computed-style-access.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/computed-style-access.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/computed-style-access.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+:root { --one: 10px; --another: 20px; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;script&gt;
+document.write(getComputedStyle(document.documentElement).getPropertyValue(&quot;--one&quot;) + &quot; &quot; + getComputedStyle(document.documentElement).getPropertyValue(&quot;--another&quot;))
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesinlinestylepropertygetexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/inline-style-property-get-expected.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/inline-style-property-get-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/inline-style-property-get-expected.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;html&gt;
+&lt;body&gt;
+10px 20px
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesinlinestylepropertygethtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/inline-style-property-get.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/inline-style-property-get.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/inline-style-property-get.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;body style=&quot;--one:10px; --two:20px&quot;&gt;
+&lt;script&gt;
+document.write(document.body.style.getPropertyValue(&quot;--one&quot;) + &quot; &quot; + document.body.style.getPropertyValue(&quot;--two&quot;))
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesrulepropertygetcssvalueexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-property-get-css-value-expected.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-property-get-css-value-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-property-get-css-value-expected.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;html&gt;
+&lt;body&gt;
+10px 20px
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesrulepropertygetcssvaluehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-property-get-css-value.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-property-get-css-value.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-property-get-css-value.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+:root { --one: 10px; --two: 20px; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;script&gt;
+document.write(document.styleSheets[0].cssRules[0].style.getPropertyCSSValue(&quot;--one&quot;).cssText + &quot; &quot; + document.styleSheets[0].cssRules[0].style.getPropertyCSSValue(&quot;--two&quot;).cssText)
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesrulepropertygetexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-property-get-expected.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-property-get-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-property-get-expected.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;html&gt;
+&lt;body&gt;
+10px 20px
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesrulepropertygethtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-property-get.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-property-get.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-property-get.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+:root { --one: 10px; --two: 20px; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;script&gt;
+document.write(document.styleSheets[0].cssRules[0].style.getPropertyValue(&quot;--one&quot;) + &quot; &quot; + document.styleSheets[0].cssRules[0].style.getPropertyValue(&quot;--two&quot;))
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesrulepropertypriorityexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-property-priority-expected.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-property-priority-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-property-priority-expected.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;html&gt;
+&lt;body&gt;
+10px important
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesrulepropertypriorityhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-property-priority.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-property-priority.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-property-priority.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+:root { --one: 10px !important; --one:50px; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;script&gt;
+document.write(document.styleSheets[0].cssRules[0].style.getPropertyValue(&quot;--one&quot;) + &quot; &quot; + document.styleSheets[0].cssRules[0].style.getPropertyPriority(&quot;--one&quot;))
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesrulepropertysetexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-property-set-expected.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-property-set-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-property-set-expected.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;html&gt;
+&lt;body&gt;
+50px 30px
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesrulepropertysethtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-property-set.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-property-set.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-property-set.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+:root { --one: 10px; --two: 20px; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;script&gt;
+document.styleSheets[0].cssRules[0].style.setProperty(&quot;--one&quot;, &quot;5px&quot;)
+document.styleSheets[0].cssRules[0].style.removeProperty(&quot;--two&quot;)
+document.styleSheets[0].cssRules[0].style.setProperty(&quot;--two&quot;, &quot;30px&quot;)
+document.styleSheets[0].cssRules[0].style.setProperty(&quot;--one&quot;, &quot;50px&quot;)
+document.write(document.styleSheets[0].cssRules[0].style.getPropertyValue(&quot;--one&quot;) + &quot; &quot; + document.styleSheets[0].cssRules[0].style.getPropertyValue(&quot;--two&quot;))
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesruleserializationexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-serialization-expected.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-serialization-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-serialization-expected.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;html&gt;
+&lt;body&gt;
+:root { --one: 10px; --two: 20px; }
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsscustompropertiesruleserializationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/custom-properties/rule-serialization.html (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/custom-properties/rule-serialization.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/custom-properties/rule-serialization.html        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+:root { --one: 10px; --two: 20px; }
+&lt;/style&gt;
+&lt;body&gt;
+&lt;script&gt;
+document.write(document.styleSheets[0].cssRules[0].cssText)
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html.
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/ChangeLog        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -1,3 +1,153 @@
</span><ins>+2015-09-24  David Hyatt  &lt;hyatt@apple.com&gt;
+
+        Add support for CSS Custom Properties (in preparation for implementing CSS Variables).
+        https://bugs.webkit.org/show_bug.cgi?id=130397
+
+        Reviewed by Antti Koivisto.
+
+        Added new tests in fast/css/custom-properties.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Add new header files to the project (CSSCustomPropertyValue and StyleCustomPropertyData).
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::ComputedStyleExtractor::customPropertyValue):
+        (WebCore::ComputedStyleExtractor::propertyValue):
+        If a custom property value is queried (i.e., it starts with &quot;--&quot;), then we use our
+        customPropertyValue lookup to go to the RenderStyle and fetch the appropriate custom property
+        value from the StyleCustomPropertyData.
+
+        (WebCore::CSSComputedStyleDeclaration::length):
+        (WebCore::CSSComputedStyleDeclaration::item):
+        Patched to include custom properties in the returned array. They appear at the end of the array
+        after the built-in properties.
+
+        (WebCore::ComputedStyleExtractor::propertyMatches):
+        Patched to check custom properties.
+
+        (WebCore::ComputedStyleExtractor::copyPropertiesInSet):
+        Make sure the custom properties get copied into the StyleDeclaration.
+
+        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+        (WebCore::CSSComputedStyleDeclaration::getPropertyValue):
+        Patched to call customPropertyValue for custom properties.
+
+        * css/CSSComputedStyleDeclaration.h:
+        Add customPropertyValue() to ComputedStyleExtractor.
+
+        * css/CSSCustomPropertyValue.h: Added.
+        (WebCore::CSSCustomPropertyValue::create):
+        (WebCore::CSSCustomPropertyValue::equals):
+        (WebCore::CSSCustomPropertyValue::customCSSText):
+        (WebCore::CSSCustomPropertyValue::name):
+        (WebCore::CSSCustomPropertyValue::value):
+        (WebCore::CSSCustomPropertyValue::CSSCustomPropertyValue):
+        Custom properties are parsed as a property with an ID of CSSPropertyCustom and a CSSCustomPropertyValue
+        that holds both the name and the value of the property. Ultimately we might want to just ditch property IDs in
+        favor of AtomicStrings for all properties, and then the need to special case custom properties would go
+        away. For now, though, this is the way we work custom properties into the existing system.
+
+        * css/CSSGrammar.y.in:
+        Add a production for recognizing custom properties and storing them using a property ID of CSSPropertyCustom
+        and a CSSCustomPropertyValue that has the name/value pair.
+
+        * css/CSSParser.cpp:
+        (WebCore::filterProperties):
+        Patched to track seen custom properties and to handle them correctly.
+
+        (WebCore::CSSParser::createStyleProperties):
+        Pass in a seenCustomProperties table to ensure we bail when encountering the same custom property twice.
+
+        (WebCore::CSSParser::addCustomPropertyDeclaration):
+        Called from the grammar production to create the CSSCustomPropertyValue.
+
+        (WebCore::isCustomPropertyIdentifier):
+        Recognize the -- custom property during lexing.
+
+        (WebCore::CSSParser::parseIdentifier):
+        Patched to return a CUSTOM_PROPERTY token when a custom property is identified.
+
+         * css/CSSParser.h:
+        (WebCore::isCustomPropertyName):
+        Add a helper function for asking if a property name is custom.
+
+        * css/CSSValue.cpp:
+        (WebCore::CSSValue::equals):
+        (WebCore::CSSValue::cssText):
+        (WebCore::CSSValue::destroy):
+        * css/CSSValue.h:
+        Patched to add support for CSSCustomPropertyValue.
+
+        * css/PropertySetCSSStyleDeclaration.cpp:
+        (WebCore::PropertySetCSSStyleDeclaration::getPropertyCSSValue):
+        (WebCore::PropertySetCSSStyleDeclaration::getPropertyValue):
+        (WebCore::PropertySetCSSStyleDeclaration::getPropertyPriority):
+        (WebCore::PropertySetCSSStyleDeclaration::setProperty):
+        (WebCore::PropertySetCSSStyleDeclaration::removeProperty):
+        Add code for handling custom properties in the CSS OM.
+
+        * css/StyleProperties.cpp:
+        (WebCore::StyleProperties::getPropertyValue):
+        (WebCore::StyleProperties::getCustomPropertyValue):
+        (WebCore::StyleProperties::getPropertyCSSValue):
+        (WebCore::StyleProperties::getCustomPropertyCSSValue):
+        (WebCore::MutableStyleProperties::removeProperty):
+        (WebCore::MutableStyleProperties::removeCustomProperty):
+        (WebCore::StyleProperties::propertyIsImportant):
+        (WebCore::StyleProperties::customPropertyIsImportant):
+        (WebCore::MutableStyleProperties::setProperty):
+        (WebCore::MutableStyleProperties::setCustomProperty):
+        (WebCore::MutableStyleProperties::addParsedProperty):
+        (WebCore::MutableStyleProperties::findPropertyIndex):
+        (WebCore::ImmutableStyleProperties::findCustomPropertyIndex):
+        (WebCore::MutableStyleProperties::findCustomPropertyIndex):
+        (WebCore::MutableStyleProperties::findCSSPropertyWithID):
+        (WebCore::MutableStyleProperties::findCustomCSSPropertyWithName):
+        (WebCore::StyleProperties::propertyMatches):
+        (WebCore::StyleProperties::PropertyReference::cssName):
+        * css/StyleProperties.h:
+        (WebCore::StyleProperties::findCustomPropertyIndex):
+        Patched to support handling custom properties in the CSS OM. We have to create equivalent methods that operate
+        on AtomicString propertyNames instead of on property IDs.
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::CascadedProperties::customProperties):
+        (WebCore::StyleResolver::styleForKeyframe):
+        (WebCore::StyleResolver::styleForPage):
+        (WebCore::StyleResolver::applyMatchedProperties):
+        (WebCore::StyleResolver::applyProperty):
+        (WebCore::StyleResolver::CascadedProperties::set):
+        (WebCore::StyleResolver::applyCascadedProperties):
+        The resolver has to hold a HashMap from AtomicStrings to Properties. It matches identically to how built-in
+        properties work except that an extensible table (HashMap) is used to hold the property data.
+
+        * css/makeprop.pl:
+        Patched to include the special CSSPropertyCustom value of 1 (just after the CSSPropertyInvalid id value but before the first
+        built-in property value).
+
+        * inspector/InspectorStyleSheet.cpp:
+        (WebCore::InspectorStyle::getText):
+        (WebCore::lowercasePropertyName):
+        (WebCore::InspectorStyle::populateAllProperties):
+        Patch inspector to not lowercase CSS custom property names, since they are case-sensitive.
+
+        * rendering/style/RenderStyle.h:
+        * rendering/style/StyleCustomPropertyData.h: Added.
+        (WebCore::StyleCustomPropertyData::create):
+        (WebCore::StyleCustomPropertyData::copy):
+        (WebCore::StyleCustomPropertyData::operator==):
+        (WebCore::StyleCustomPropertyData::operator!=):
+        (WebCore::StyleCustomPropertyData::setCustomPropertyValue):
+        (WebCore::StyleCustomPropertyData::getCustomPropertyValue):
+        (WebCore::StyleCustomPropertyData::hasCustomProperty):
+        (WebCore::StyleCustomPropertyData::StyleCustomPropertyData):
+        * rendering/style/StyleRareInheritedData.cpp:
+        (WebCore::StyleRareInheritedData::StyleRareInheritedData):
+        (WebCore::StyleRareInheritedData::operator==):
+        * rendering/style/StyleRareInheritedData.h:
+        The front end storage in the RenderStyle for custom properties. For now, custom properties are always inherited, so the
+        data is in StyleRareInheritedData.
+
</ins><span class="cx"> 2015-09-24  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Optimize Range's lengthOfContentsInNode() for DocumentType Nodes
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -5435,6 +5435,8 @@
</span><span class="cx">                 BC772C5E0C4EB3440083285F /* MIMETypeRegistryMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BC772C5D0C4EB3440083285F /* MIMETypeRegistryMac.mm */; };
</span><span class="cx">                 BC772E131331620C001EC9CE /* CSSLineBoxContainValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772E121331620C001EC9CE /* CSSLineBoxContainValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 BC772E16133162C2001EC9CE /* CSSLineBoxContainValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC772E15133162C2001EC9CE /* CSSLineBoxContainValue.cpp */; };
</span><ins>+                BC779E141BB215BB00CAA8BF /* CSSCustomPropertyValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC779E131BB215BB00CAA8BF /* CSSCustomPropertyValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                BC779E171BB227CA00CAA8BF /* StyleCustomPropertyData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC779E151BB226A200CAA8BF /* StyleCustomPropertyData.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 BC7F44A80B9E324E00A9D081 /* ImageObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7F44A70B9E324E00A9D081 /* ImageObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 BC7FA6200D1F0CBD00DB22A9 /* LiveNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC7FA61E0D1F0CBD00DB22A9 /* LiveNodeList.cpp */; };
</span><span class="cx">                 BC7FA6210D1F0CBD00DB22A9 /* LiveNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7FA61F0D1F0CBD00DB22A9 /* LiveNodeList.h */; };
</span><span class="lines">@@ -13070,6 +13072,8 @@
</span><span class="cx">                 BC772C5D0C4EB3440083285F /* MIMETypeRegistryMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = MIMETypeRegistryMac.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC772E121331620C001EC9CE /* CSSLineBoxContainValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSLineBoxContainValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC772E15133162C2001EC9CE /* CSSLineBoxContainValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSLineBoxContainValue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                BC779E131BB215BB00CAA8BF /* CSSCustomPropertyValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSCustomPropertyValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                BC779E151BB226A200CAA8BF /* StyleCustomPropertyData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleCustomPropertyData.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 BC7B2AF80450824100A8000F /* Scrollbar.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Scrollbar.h; sourceTree = &quot;&lt;group&gt;&quot;; tabWidth = 8; usesTabs = 0; };
</span><span class="cx">                 BC7F44A70B9E324E00A9D081 /* ImageObserver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageObserver.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC7FA61E0D1F0CBD00DB22A9 /* LiveNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LiveNodeList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -21791,6 +21795,7 @@
</span><span class="cx">                                 9393E602151A9A1800066F06 /* StyleCachedImageSet.cpp */,
</span><span class="cx">                                 9393E603151A9A1800066F06 /* StyleCachedImageSet.h */,
</span><span class="cx">                                 9DAC7C561AF2CB6400437C44 /* StyleContentAlignmentData.h */,
</span><ins>+                                BC779E151BB226A200CAA8BF /* StyleCustomPropertyData.h */,
</ins><span class="cx">                                 BC5EB67E0E81D4A700B25965 /* StyleDashboardRegion.h */,
</span><span class="cx">                                 BC5EB8B60E8201BD00B25965 /* StyleDeprecatedFlexibleBoxData.cpp */,
</span><span class="cx">                                 BC5EB8B70E8201BD00B25965 /* StyleDeprecatedFlexibleBoxData.h */,
</span><span class="lines">@@ -22749,6 +22754,7 @@
</span><span class="cx">                                 2D8FEBDB143E3EF70072502B /* CSSCrossfadeValue.h */,
</span><span class="cx">                                 AA0978ED0ABAA6E100874480 /* CSSCursorImageValue.cpp */,
</span><span class="cx">                                 AA0978EE0ABAA6E100874480 /* CSSCursorImageValue.h */,
</span><ins>+                                BC779E131BB215BB00CAA8BF /* CSSCustomPropertyValue.h */,
</ins><span class="cx">                                 4A9CC81516BB9AC600EC645A /* CSSDefaultStyleSheets.cpp */,
</span><span class="cx">                                 4A9CC81616BB9AC600EC645A /* CSSDefaultStyleSheets.h */,
</span><span class="cx">                                 FB965B8217BBB62C00E835B9 /* CSSFilterImageValue.cpp */,
</span><span class="lines">@@ -25104,6 +25110,7 @@
</span><span class="cx">                                 A8CFF04F0A154F09000A4234 /* FixedTableLayout.h in Headers */,
</span><span class="cx">                                 BC073BAA0C399B1F000F5979 /* FloatConversion.h in Headers */,
</span><span class="cx">                                 9A528E8417D7F52F00AA9518 /* FloatingObjects.h in Headers */,
</span><ins>+                                BC779E171BB227CA00CAA8BF /* StyleCustomPropertyData.h in Headers */,
</ins><span class="cx">                                 FE699872192087E7006936BD /* FloatingPointEnvironment.h in Headers */,
</span><span class="cx">                                 B27535690B053814002CE64F /* FloatPoint.h in Headers */,
</span><span class="cx">                                 B2E27CA00B0F2B0900F17C7B /* FloatPoint3D.h in Headers */,
</span><span class="lines">@@ -26099,6 +26106,7 @@
</span><span class="cx">                                 141DC053164834B900371E5A /* LayoutRect.h in Headers */,
</span><span class="cx">                                 A12538D413F9B60A00024754 /* LayoutRepainter.h in Headers */,
</span><span class="cx">                                 141DC054164834B900371E5A /* LayoutSize.h in Headers */,
</span><ins>+                                BC779E141BB215BB00CAA8BF /* CSSCustomPropertyValue.h in Headers */,
</ins><span class="cx">                                 2D9066070BE141D400956998 /* LayoutState.h in Headers */,
</span><span class="cx">                                 141DC0481648348F00371E5A /* LayoutUnit.h in Headers */,
</span><span class="cx">                                 5103C2B91BA23A2600E26337 /* LegacyAny.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSComputedStyleDeclarationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;CSSAspectRatioValue.h&quot;
</span><span class="cx"> #include &quot;CSSBasicShapes.h&quot;
</span><span class="cx"> #include &quot;CSSBorderImage.h&quot;
</span><ins>+#include &quot;CSSCustomPropertyValue.h&quot;
</ins><span class="cx"> #include &quot;CSSFontFeatureValue.h&quot;
</span><span class="cx"> #include &quot;CSSFontValue.h&quot;
</span><span class="cx"> #include &quot;CSSFunctionValue.h&quot;
</span><span class="lines">@@ -2095,6 +2096,20 @@
</span><span class="cx">     return element &amp;&amp; element-&gt;computedStyle() &amp;&amp; element-&gt;computedStyle()-&gt;isDisplayFlexibleOrGridBox();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;CSSValue&gt; ComputedStyleExtractor::customPropertyValue(const String&amp; propertyName) const
+{
+    Node* styledNode = this-&gt;styledNode();
+    if (!styledNode)
+        return nullptr;
+
+    RefPtr&lt;RenderStyle&gt; style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, CSSPropertyCustom);
+    if (!style || !style-&gt;hasCustomProperty(propertyName))
+        return nullptr;
+
+    String result = style-&gt;getCustomPropertyValue(propertyName);
+    return CSSCustomPropertyValue::create(propertyName, result);
+}
+
</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">@@ -3553,6 +3568,9 @@
</span><span class="cx">         case CSSPropertyWritingMode:
</span><span class="cx">         case CSSPropertyWebkitSvgShadow:
</span><span class="cx">             return svgPropertyValue(propertyID, DoNotUpdateLayout);
</span><ins>+        case CSSPropertyCustom:
+            ASSERT_NOT_REACHED();
+            return nullptr;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     logUnimplementedPropertyID(propertyID);
</span><span class="lines">@@ -3577,15 +3595,35 @@
</span><span class="cx">     if (!style)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><del>-    return numComputedProperties;
</del><ins>+    const HashMap&lt;AtomicString, String&gt;* customProperties = style-&gt;customProperties();
+    return numComputedProperties + (customProperties ? customProperties-&gt;size() : 0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String CSSComputedStyleDeclaration::item(unsigned i) const
</span><span class="cx"> {
</span><span class="cx">     if (i &gt;= length())
</span><span class="cx">         return emptyString();
</span><ins>+    
+    if (i &lt; numComputedProperties)
+        return getPropertyNameString(computedProperties[i]);
+    
+    Node* node = m_node.get();
+    if (!node)
+        return emptyString();
</ins><span class="cx"> 
</span><del>-    return getPropertyNameString(computedProperties[i]);
</del><ins>+    RenderStyle* style = node-&gt;computedStyle(m_pseudoElementSpecifier);
+    if (!style)
+        return emptyString();
+    
+    unsigned index = i - numComputedProperties;
+    
+    const auto* customProperties = style-&gt;customProperties();
+    if (!customProperties || index &gt;= customProperties-&gt;size())
+        return emptyString();
+    
+    Vector&lt;String, 4&gt; results;
+    copyKeysToVector(*customProperties, results);
+    return results.at(index);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ComputedStyleExtractor::propertyMatches(CSSPropertyID propertyID, const CSSValue* value) const
</span><span class="lines">@@ -3666,6 +3704,22 @@
</span><span class="cx">         if (value)
</span><span class="cx">             list.append(CSSProperty(set[i], value.release(), false));
</span><span class="cx">     }
</span><ins>+    
+    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));
+                }
+            }
+        }
+    }
+    
</ins><span class="cx">     return MutableStyleProperties::create(list.data(), list.size());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3676,6 +3730,11 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;CSSValue&gt; CSSComputedStyleDeclaration::getPropertyCSSValue(const String&amp; propertyName)
</span><span class="cx"> {
</span><ins>+    if (isCustomPropertyName(propertyName)) {
+        RefPtr&lt;CSSValue&gt; value = ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName);
+        return value ? value-&gt;cloneForCSSOM() : nullptr;
+    }
+
</ins><span class="cx">     CSSPropertyID propertyID = cssPropertyID(propertyName);
</span><span class="cx">     if (!propertyID)
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -3685,6 +3744,13 @@
</span><span class="cx"> 
</span><span class="cx"> String CSSComputedStyleDeclaration::getPropertyValue(const String &amp;propertyName)
</span><span class="cx"> {
</span><ins>+    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();
+    }
+
</ins><span class="cx">     CSSPropertyID propertyID = cssPropertyID(propertyName);
</span><span class="cx">     if (!propertyID)
</span><span class="cx">         return String();
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSComputedStyleDeclarationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSComputedStyleDeclaration.h (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSComputedStyleDeclaration.h        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/CSSComputedStyleDeclaration.h        2015-09-24 18:15:52 UTC (rev 190209)
</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>+    RefPtr&lt;CSSValue&gt; customPropertyValue(const String&amp; propertyName) const;
</ins><span class="cx"> 
</span><span class="cx">     // Helper methods for HTML editing.
</span><span class="cx">     Ref&lt;MutableStyleProperties&gt; copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const;
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSCustomPropertyValueh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/css/CSSCustomPropertyValue.h (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSCustomPropertyValue.h                                (rev 0)
+++ trunk/Source/WebCore/css/CSSCustomPropertyValue.h        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. 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.
+ */
+
+#ifndef CSSCustomPropertyValue_h
+#define CSSCustomPropertyValue_h
+
+#include &quot;CSSValue.h&quot;
+
+namespace WebCore {
+
+class CSSCustomPropertyValue : public CSSValue {
+public:
+    static Ref&lt;CSSCustomPropertyValue&gt; create(const AtomicString&amp; name, const String&amp; value)
+    {
+        return adoptRef(*new CSSCustomPropertyValue(name, value));
+    }
+    
+    bool equals(const CSSCustomPropertyValue&amp; other) const { return m_name == other.m_name &amp;&amp; m_value == other.m_value; }
+
+    String customCSSText() const { return value(); }
+
+    const AtomicString&amp; name() const { return m_name; }
+    const String&amp; value() const { return m_value; }
+    
+private:
+    CSSCustomPropertyValue(const AtomicString&amp; name, const String&amp; value)
+        : CSSValue(CustomPropertyClass)
+        , m_name(name)
+        , m_value(value)
+    {
+    }
+
+    const AtomicString m_name;
+    const String m_value;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSCustomPropertyValue, isCustomPropertyValue())
+
+#endif // CSSCustomPropertyValue_h
</ins></span></pre></div>
<a id="trunkSourceWebCorecssCSSGrammaryin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSGrammar.y.in (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSGrammar.y.in        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/CSSGrammar.y.in        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -88,6 +88,7 @@
</span><span class="cx">     case DIRFUNCTION:
</span><span class="cx">     case ROLEFUNCTION:
</span><span class="cx"> #endif
</span><ins>+    case CUSTOM_PROPERTY:
</ins><span class="cx">     case UNICODERANGE:
</span><span class="cx">         return true;
</span><span class="cx">     default:
</span><span class="lines">@@ -244,6 +245,8 @@
</span><span class="cx"> %token &lt;string&gt; ROLEFUNCTION
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+%token &lt;string&gt; CUSTOM_PROPERTY
+
</ins><span class="cx"> %token &lt;string&gt; UNICODERANGE
</span><span class="cx"> 
</span><span class="cx"> %type &lt;relation&gt; combinator
</span><span class="lines">@@ -1535,7 +1538,13 @@
</span><span class="cx">     ;
</span><span class="cx"> 
</span><span class="cx"> declaration:
</span><del>-    property ':' maybe_space expr priority {
</del><ins>+    CUSTOM_PROPERTY maybe_space ':' maybe_space expr priority {
+        std::unique_ptr&lt;CSSParserValueList&gt; propertyValue($5);
+        parser-&gt;addCustomPropertyDeclaration($1, propertyValue.get(), $6);
+        $$ = true;
+        parser-&gt;markPropertyEnd($6, true);
+    }
+    | property ':' maybe_space expr priority {
</ins><span class="cx">         $$ = false;
</span><span class="cx">         bool isPropertyParsed = false;
</span><span class="cx">         std::unique_ptr&lt;CSSParserValueList&gt; propertyValue($4);
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParser.cpp (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.cpp        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/CSSParser.cpp        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> #include &quot;CSSContentDistributionValue.h&quot;
</span><span class="cx"> #include &quot;CSSCrossfadeValue.h&quot;
</span><span class="cx"> #include &quot;CSSCursorImageValue.h&quot;
</span><ins>+#include &quot;CSSCustomPropertyValue.h&quot;
</ins><span class="cx"> #include &quot;CSSFilterImageValue.h&quot;
</span><span class="cx"> #include &quot;CSSFontFaceRule.h&quot;
</span><span class="cx"> #include &quot;CSSFontFaceSrcValue.h&quot;
</span><span class="lines">@@ -1575,13 +1576,23 @@
</span><span class="cx">     return SourceSize(WTF::move(expression), WTF::move(value));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline void filterProperties(bool important, const CSSParser::ParsedPropertyVector&amp; input, Vector&lt;CSSProperty, 256&gt;&amp; output, size_t&amp; unusedEntries, std::bitset&lt;numCSSProperties&gt;&amp; seenProperties)
</del><ins>+static inline void filterProperties(bool important, const CSSParser::ParsedPropertyVector&amp; input, Vector&lt;CSSProperty, 256&gt;&amp; output, size_t&amp; unusedEntries, std::bitset&lt;numCSSProperties&gt;&amp; seenProperties, HashSet&lt;AtomicString&gt;&amp; seenCustomProperties)
</ins><span class="cx"> {
</span><span class="cx">     // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
</span><span class="cx">     for (int i = input.size() - 1; i &gt;= 0; --i) {
</span><span class="cx">         const CSSProperty&amp; property = input[i];
</span><span class="cx">         if (property.isImportant() != important)
</span><span class="cx">             continue;
</span><ins>+        
+        if (property.id() == CSSPropertyCustom) {
+            const AtomicString&amp; name = downcast&lt;CSSCustomPropertyValue&gt;(*property.value()).name();
+            if (seenCustomProperties.contains(name))
+                continue;
+            seenCustomProperties.add(name);
+            output[--unusedEntries] = property;
+            continue;
+        }
+
</ins><span class="cx">         const unsigned propertyIDIndex = property.id() - firstCSSProperty;
</span><span class="cx">         ASSERT(propertyIDIndex &lt; seenProperties.size());
</span><span class="cx">         if (seenProperties[propertyIDIndex])
</span><span class="lines">@@ -1598,8 +1609,9 @@
</span><span class="cx">     Vector&lt;CSSProperty, 256&gt; results(unusedEntries);
</span><span class="cx"> 
</span><span class="cx">     // Important properties have higher priority, so add them first. Duplicate definitions can then be ignored when found.
</span><del>-    filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties);
-    filterProperties(false, m_parsedProperties, results, unusedEntries, seenProperties);
</del><ins>+    HashSet&lt;AtomicString&gt; seenCustomProperties;
+    filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
+    filterProperties(false, m_parsedProperties, results, unusedEntries, seenProperties, seenCustomProperties);
</ins><span class="cx">     if (unusedEntries)
</span><span class="cx">         results.remove(0, unusedEntries);
</span><span class="cx"> 
</span><span class="lines">@@ -4124,7 +4136,29 @@
</span><span class="cx"> 
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><del>-    
</del><ins>+
+void CSSParser::addCustomPropertyDeclaration(const CSSParserString&amp; name, CSSParserValueList* value, bool important)
+{
+    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);
+}
+
</ins><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 class="cx"> // in CSS 2.1 this got somewhat reduced:
</span><span class="cx"> // [ &lt;string&gt; | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
</span><span class="lines">@@ -10887,6 +10921,13 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename CharacterType&gt;
</span><ins>+static inline bool isCustomPropertyIdentifier(CharacterType* currentCharacter)
+{
+    return isASCIIAlpha(currentCharacter[0]) || currentCharacter[0] == '_' || currentCharacter[0] &gt;= 128
+        || (currentCharacter[0] == '\\' &amp;&amp; isCSSEscape(currentCharacter[1]));
+}
+
+template &lt;typename CharacterType&gt;
</ins><span class="cx"> static inline bool isEqualToCSSIdentifier(CharacterType* cssString, const char* constantString)
</span><span class="cx"> {
</span><span class="cx">     // Compare an character memory data with a zero terminated string.
</span><span class="lines">@@ -11125,10 +11166,6 @@
</span><span class="cx"> template &lt;typename CharacterType&gt;
</span><span class="cx"> inline void CSSParser::parseIdentifier(CharacterType*&amp; result, CSSParserString&amp; resultString, bool&amp; hasEscape)
</span><span class="cx"> {
</span><del>-    // If a valid identifier start is found, we can safely
-    // parse the identifier until the next invalid character.
-    ASSERT(isIdentifierStart&lt;CharacterType&gt;());
-
</del><span class="cx">     CharacterType* start = currentCharacter&lt;CharacterType&gt;();
</span><span class="cx">     if (UNLIKELY(!parseIdentifierInternal(currentCharacter&lt;CharacterType&gt;(), result, hasEscape))) {
</span><span class="cx">         // Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
</span><span class="lines">@@ -12068,6 +12105,11 @@
</span><span class="cx">             }
</span><span class="cx">             resultString.setLength(result - tokenStart&lt;SrcCharacterType&gt;());
</span><span class="cx">             yylval-&gt;string = resultString;
</span><ins>+        } else if (currentCharacter&lt;SrcCharacterType&gt;()[0] == '-' &amp;&amp; isIdentifierStartAfterDash(currentCharacter&lt;SrcCharacterType&gt;() + 1)) {
+            --currentCharacter&lt;SrcCharacterType&gt;();
+            parseIdentifier(result, resultString, hasEscape);
+            m_token = CUSTOM_PROPERTY;
+            yylval-&gt;string = resultString;
</ins><span class="cx">         } else if (currentCharacter&lt;SrcCharacterType&gt;()[0] == '-' &amp;&amp; currentCharacter&lt;SrcCharacterType&gt;()[1] == '&gt;') {
</span><span class="cx">             currentCharacter&lt;SrcCharacterType&gt;() += 2;
</span><span class="cx">             m_token = SGML_CD;
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParser.h (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.h        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/CSSParser.h        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -143,6 +143,8 @@
</span><span class="cx">     bool parseQuotes(CSSPropertyID, bool important);
</span><span class="cx">     bool parseAlt(CSSPropertyID, bool important);
</span><span class="cx">     
</span><ins>+    void addCustomPropertyDeclaration(const CSSParserString&amp;, CSSParserValueList*, bool important);
+    
</ins><span class="cx">     RefPtr&lt;CSSValue&gt; parseAttr(CSSParserValueList&amp; args);
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;CSSValue&gt; parseBackgroundColor();
</span><span class="lines">@@ -755,6 +757,11 @@
</span><span class="cx">     return *m_tokenStart.ptr16;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool isCustomPropertyName(const String&amp; propertyName)
+{
+    return propertyName.length() &gt; 2 &amp;&amp; propertyName.characterAt(0) == '-' &amp;&amp; propertyName.characterAt(1) == '-';
+}
+
</ins><span class="cx"> inline int cssyylex(void* yylval, CSSParser* parser)
</span><span class="cx"> {
</span><span class="cx">     return parser-&gt;lex(yylval);
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSValue.cpp (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSValue.cpp        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/CSSValue.cpp        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> #include &quot;CSSContentDistributionValue.h&quot;
</span><span class="cx"> #include &quot;CSSCrossfadeValue.h&quot;
</span><span class="cx"> #include &quot;CSSCursorImageValue.h&quot;
</span><ins>+#include &quot;CSSCustomPropertyValue.h&quot;
</ins><span class="cx"> #include &quot;CSSFilterImageValue.h&quot;
</span><span class="cx"> #include &quot;CSSFontFaceSrcValue.h&quot;
</span><span class="cx"> #include &quot;CSSFontFeatureValue.h&quot;
</span><span class="lines">@@ -236,6 +237,9 @@
</span><span class="cx"> #endif
</span><span class="cx">         case CSSContentDistributionClass:
</span><span class="cx">             return compareCSSValues&lt;CSSContentDistributionValue&gt;(*this, other);
</span><ins>+        case CustomPropertyClass:
+            return compareCSSValues&lt;CSSCustomPropertyValue&gt;(*this, other);
+        
</ins><span class="cx">         default:
</span><span class="cx">             ASSERT_NOT_REACHED();
</span><span class="cx">             return false;
</span><span class="lines">@@ -330,7 +334,10 @@
</span><span class="cx"> #endif
</span><span class="cx">     case CSSContentDistributionClass:
</span><span class="cx">         return downcast&lt;CSSContentDistributionValue&gt;(*this).customCSSText();
</span><ins>+    case CustomPropertyClass:
+        return downcast&lt;CSSCustomPropertyValue&gt;(*this).customCSSText();
</ins><span class="cx">     }
</span><ins>+
</ins><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx">     return String();
</span><span class="cx"> }
</span><span class="lines">@@ -453,6 +460,9 @@
</span><span class="cx">     case CSSContentDistributionClass:
</span><span class="cx">         delete downcast&lt;CSSContentDistributionValue&gt;(this);
</span><span class="cx">         return;
</span><ins>+    case CustomPropertyClass:
+        delete downcast&lt;CSSCustomPropertyValue&gt;(this);
+        return;
</ins><span class="cx">     }
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSValue.h (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSValue.h        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/CSSValue.h        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -73,6 +73,7 @@
</span><span class="cx">     bool isCanvasValue() const { return m_classType == CanvasClass; }
</span><span class="cx">     bool isCrossfadeValue() const { return m_classType == CrossfadeClass; }
</span><span class="cx">     bool isCursorImageValue() const { return m_classType == CursorImageClass; }
</span><ins>+    bool isCustomPropertyValue() const { return m_classType == CustomPropertyClass; }
</ins><span class="cx">     bool isFunctionValue() const { return m_classType == FunctionClass; }
</span><span class="cx">     bool isFontFeatureValue() const { return m_classType == FontFeatureClass; }
</span><span class="cx">     bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; }
</span><span class="lines">@@ -176,7 +177,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">         CSSContentDistributionClass,
</span><del>-
</del><ins>+        CustomPropertyClass,
+        
</ins><span class="cx">         // List class types must appear after ValueListClass.
</span><span class="cx">         ValueListClass,
</span><span class="cx"> #if ENABLE(CSS_IMAGE_SET)
</span></span></pre></div>
<a id="trunkSourceWebCorecssPropertySetCSSStyleDeclarationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -22,6 +22,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;PropertySetCSSStyleDeclaration.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;CSSCustomPropertyValue.h&quot;
</ins><span class="cx"> #include &quot;CSSParser.h&quot;
</span><span class="cx"> #include &quot;CSSStyleSheet.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="lines">@@ -162,6 +163,13 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;CSSValue&gt; PropertySetCSSStyleDeclaration::getPropertyCSSValue(const String&amp; propertyName)
</span><span class="cx"> {
</span><ins>+    if (isCustomPropertyName(propertyName)) {
+        RefPtr&lt;CSSValue&gt; value = m_propertySet-&gt;getCustomPropertyCSSValue(propertyName);
+        if (!value)
+            return nullptr;
+        return cloneAndCacheForCSSOM(value.get());
+    }
+    
</ins><span class="cx">     CSSPropertyID propertyID = cssPropertyID(propertyName);
</span><span class="cx">     if (!propertyID)
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -170,6 +178,9 @@
</span><span class="cx"> 
</span><span class="cx"> String PropertySetCSSStyleDeclaration::getPropertyValue(const String&amp; propertyName)
</span><span class="cx"> {
</span><ins>+    if (isCustomPropertyName(propertyName))
+        return m_propertySet-&gt;getCustomPropertyValue(propertyName);
+
</ins><span class="cx">     CSSPropertyID propertyID = cssPropertyID(propertyName);
</span><span class="cx">     if (!propertyID)
</span><span class="cx">         return String();
</span><span class="lines">@@ -178,6 +189,9 @@
</span><span class="cx"> 
</span><span class="cx"> String PropertySetCSSStyleDeclaration::getPropertyPriority(const String&amp; propertyName)
</span><span class="cx"> {
</span><ins>+    if (isCustomPropertyName(propertyName))
+        return m_propertySet-&gt;customPropertyIsImportant(propertyName) ? &quot;important&quot; : &quot;&quot;;
+
</ins><span class="cx">     CSSPropertyID propertyID = cssPropertyID(propertyName);
</span><span class="cx">     if (!propertyID)
</span><span class="cx">         return String();
</span><span class="lines">@@ -203,7 +217,10 @@
</span><span class="cx"> void PropertySetCSSStyleDeclaration::setProperty(const String&amp; propertyName, const String&amp; value, const String&amp; priority, ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     StyleAttributeMutationScope mutationScope(this);
</span><ins>+    
</ins><span class="cx">     CSSPropertyID propertyID = cssPropertyID(propertyName);
</span><ins>+    if (isCustomPropertyName(propertyName))
+        propertyID = CSSPropertyCustom;
</ins><span class="cx">     if (!propertyID)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -213,7 +230,7 @@
</span><span class="cx">     bool important = priority.find(&quot;important&quot;, 0, false) != notFound;
</span><span class="cx"> 
</span><span class="cx">     ec = 0;
</span><del>-    bool changed = m_propertySet-&gt;setProperty(propertyID, value, important, contextStyleSheet());
</del><ins>+    bool changed = propertyID != CSSPropertyCustom ? m_propertySet-&gt;setProperty(propertyID, value, important, contextStyleSheet()) : m_propertySet-&gt;setCustomProperty(propertyName, value, important, contextStyleSheet());
</ins><span class="cx"> 
</span><span class="cx">     didMutate(changed ? PropertyChanged : NoChanges);
</span><span class="cx"> 
</span><span class="lines">@@ -228,6 +245,8 @@
</span><span class="cx"> {
</span><span class="cx">     StyleAttributeMutationScope mutationScope(this);
</span><span class="cx">     CSSPropertyID propertyID = cssPropertyID(propertyName);
</span><ins>+    if (isCustomPropertyName(propertyName))
+        propertyID = CSSPropertyCustom;
</ins><span class="cx">     if (!propertyID)
</span><span class="cx">         return String();
</span><span class="cx"> 
</span><span class="lines">@@ -236,7 +255,7 @@
</span><span class="cx"> 
</span><span class="cx">     ec = 0;
</span><span class="cx">     String result;
</span><del>-    bool changed = m_propertySet-&gt;removeProperty(propertyID, &amp;result);
</del><ins>+    bool changed = propertyID != CSSPropertyCustom ? m_propertySet-&gt;removeProperty(propertyID, &amp;result) : m_propertySet-&gt;removeCustomProperty(propertyName, &amp;result);
</ins><span class="cx"> 
</span><span class="cx">     didMutate(changed ? PropertyChanged : NoChanges);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssStylePropertiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleProperties.cpp (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleProperties.cpp        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/StyleProperties.cpp        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -24,6 +24,7 @@
</span><span class="cx"> #include &quot;StyleProperties.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CSSComputedStyleDeclaration.h&quot;
</span><ins>+#include &quot;CSSCustomPropertyValue.h&quot;
</ins><span class="cx"> #include &quot;CSSParser.h&quot;
</span><span class="cx"> #include &quot;CSSValueKeywords.h&quot;
</span><span class="cx"> #include &quot;CSSValueList.h&quot;
</span><span class="lines">@@ -220,6 +221,14 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String StyleProperties::getCustomPropertyValue(const String&amp; propertyName) const
+{
+    RefPtr&lt;CSSValue&gt; value = getCustomPropertyCSSValue(propertyName);
+    if (value)
+        return value-&gt;cssText();
+    return String();
+}
+
</ins><span class="cx"> String StyleProperties::borderSpacingValue(const StylePropertyShorthand&amp; shorthand) const
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;CSSValue&gt; horizontalValue = getPropertyCSSValue(shorthand.properties()[0]);
</span><span class="lines">@@ -587,6 +596,14 @@
</span><span class="cx">     return propertyAt(foundPropertyIndex).value();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;CSSValue&gt; StyleProperties::getCustomPropertyCSSValue(const String&amp; propertyName) const
+{
+    int foundPropertyIndex = findCustomPropertyIndex(propertyName);
+    if (foundPropertyIndex == -1)
+        return nullptr;
+    return propertyAt(foundPropertyIndex).value();
+}
+
</ins><span class="cx"> bool MutableStyleProperties::removeShorthandProperty(CSSPropertyID propertyID)
</span><span class="cx"> {
</span><span class="cx">     StylePropertyShorthand shorthand = shorthandForProperty(propertyID);
</span><span class="lines">@@ -631,6 +648,25 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool MutableStyleProperties::removeCustomProperty(const String&amp; propertyName, String* returnText)
+{
+    int foundPropertyIndex = findCustomPropertyIndex(propertyName);
+    if (foundPropertyIndex == -1) {
+        if (returnText)
+            *returnText = &quot;&quot;;
+        return false;
+    }
+
+    if (returnText)
+        *returnText = propertyAt(foundPropertyIndex).value()-&gt;cssText();
+
+    // A more efficient removal strategy would involve marking entries as empty
+    // and sweeping them when the vector grows too big.
+    m_propertyVector.remove(foundPropertyIndex);
+
+    return true;
+}
+
</ins><span class="cx"> void MutableStyleProperties::removePrefixedOrUnprefixedProperty(CSSPropertyID propertyID)
</span><span class="cx"> {
</span><span class="cx">     int foundPropertyIndex = findPropertyIndex(prefixingVariantForPropertyId(propertyID));
</span><span class="lines">@@ -656,6 +692,14 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool StyleProperties::customPropertyIsImportant(const String&amp; propertyName) const
+{
+    int foundPropertyIndex = findCustomPropertyIndex(propertyName);
+    if (foundPropertyIndex != -1)
+        return propertyAt(foundPropertyIndex).isImportant();
+    return false;
+}
+
</ins><span class="cx"> String StyleProperties::getPropertyShorthand(CSSPropertyID propertyID) const
</span><span class="cx"> {
</span><span class="cx">     int foundPropertyIndex = findPropertyIndex(propertyID);
</span><span class="lines">@@ -684,6 +728,21 @@
</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><ins>+bool MutableStyleProperties::setCustomProperty(const String&amp; propertyName, const String&amp; value, bool important, StyleSheetContents* /*contextStyleSheet*/)
+{
+    // Setting the value to an empty string just removes the property in both IE and Gecko.
+    // Setting it to null seems to produce less consistent results, but we treat it just the same.
+    if (value.isEmpty())
+        return removeCustomProperty(propertyName);
+
+    // When replacing an existing property value, this moves the property to the end of the list.
+    // Firefox preserves the position, and MSIE moves the property to the beginning.
+    RefPtr&lt;CSSCustomPropertyValue&gt; customValue = CSSCustomPropertyValue::create(propertyName, value);
+    addParsedProperty(CSSProperty(CSSPropertyCustom, customValue, important));
+    
+    return true;
+}
+
</ins><span class="cx"> void MutableStyleProperties::setProperty(CSSPropertyID propertyID, PassRefPtr&lt;CSSValue&gt; prpValue, bool important)
</span><span class="cx"> {
</span><span class="cx">     StylePropertyShorthand shorthand = shorthandForProperty(propertyID);
</span><span class="lines">@@ -702,7 +761,15 @@
</span><span class="cx"> bool MutableStyleProperties::setProperty(const CSSProperty&amp; property, CSSProperty* slot)
</span><span class="cx"> {
</span><span class="cx">     if (!removeShorthandProperty(property.id())) {
</span><del>-        CSSProperty* toReplace = slot ? slot : findCSSPropertyWithID(property.id());
</del><ins>+        CSSProperty* toReplace = slot;
+        if (!slot) {
+            if (property.id() == CSSPropertyCustom) {
+                if (property.value())
+                    toReplace = findCustomCSSPropertyWithName(downcast&lt;CSSCustomPropertyValue&gt;(*property.value()).name());
+            } else
+                toReplace = findCSSPropertyWithID(property.id());
+        }
+        
</ins><span class="cx">         if (toReplace) {
</span><span class="cx">             if (*toReplace == property)
</span><span class="cx">                 return false;
</span><span class="lines">@@ -781,6 +848,12 @@
</span><span class="cx"> 
</span><span class="cx"> bool MutableStyleProperties::addParsedProperty(const CSSProperty&amp; property)
</span><span class="cx"> {
</span><ins>+    if (property.id() == CSSPropertyCustom) {
+        if ((property.value() &amp;&amp; !customPropertyIsImportant(downcast&lt;CSSCustomPropertyValue&gt;(*property.value()).name())) || property.isImportant())
+            return setProperty(property);
+        return false;
+    }
+    
</ins><span class="cx">     // Only add properties that have no !important counterpart present
</span><span class="cx">     if (!propertyIsImportant(property.id()) || property.isImportant())
</span><span class="cx">         return setProperty(property);
</span><span class="lines">@@ -973,12 +1046,17 @@
</span><span class="cx">         } else
</span><span class="cx">             value = property.value()-&gt;cssText();
</span><span class="cx"> 
</span><del>-        if (value == &quot;initial&quot; &amp;&amp; !CSSProperty::isInheritedProperty(propertyID))
</del><ins>+        if (propertyID != CSSPropertyCustom &amp;&amp; value == &quot;initial&quot; &amp;&amp; !CSSProperty::isInheritedProperty(propertyID))
</ins><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         if (numDecls++)
</span><span class="cx">             result.append(' ');
</span><del>-        result.append(getPropertyName(propertyID));
</del><ins>+
+        if (propertyID == CSSPropertyCustom)
+            result.append(downcast&lt;CSSCustomPropertyValue&gt;(*property.value()).name());
+        else
+            result.append(getPropertyName(propertyID));
+
</ins><span class="cx">         result.appendLiteral(&quot;: &quot;);
</span><span class="cx">         result.append(value);
</span><span class="cx">         if (property.isImportant())
</span><span class="lines">@@ -1175,6 +1253,40 @@
</span><span class="cx">     return -1;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+int ImmutableStyleProperties::findCustomPropertyIndex(const String&amp; propertyName) const
+{
+    // Convert the propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
+    // the compiler converting it to an int multiple times in the loop.
+    for (int n = m_arraySize - 1 ; n &gt;= 0; --n) {
+        if (metadataArray()[n].m_propertyID == CSSPropertyCustom) {
+            // We found a custom property. See if the name matches.
+            if (!valueArray()[n])
+                continue;
+            if (downcast&lt;CSSCustomPropertyValue&gt;(*valueArray()[n]).name() == propertyName)
+                return n;
+        }
+    }
+
+    return -1;
+}
+
+int MutableStyleProperties::findCustomPropertyIndex(const String&amp; propertyName) const
+{
+    // Convert the propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
+    // the compiler converting it to an int multiple times in the loop.
+    for (int n = m_propertyVector.size() - 1 ; n &gt;= 0; --n) {
+        if (m_propertyVector.at(n).metadata().m_propertyID == CSSPropertyCustom) {
+            // We found a custom property. See if the name matches.
+            if (!m_propertyVector.at(n).value())
+                continue;
+            if (downcast&lt;CSSCustomPropertyValue&gt;(*m_propertyVector.at(n).value()).name() == propertyName)
+                return n;
+        }
+    }
+
+    return -1;
+}
+
</ins><span class="cx"> CSSProperty* MutableStyleProperties::findCSSPropertyWithID(CSSPropertyID propertyID)
</span><span class="cx"> {
</span><span class="cx">     int foundPropertyIndex = findPropertyIndex(propertyID);
</span><span class="lines">@@ -1183,6 +1295,14 @@
</span><span class="cx">     return &amp;m_propertyVector.at(foundPropertyIndex);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CSSProperty* MutableStyleProperties::findCustomCSSPropertyWithName(const String&amp; propertyName)
+{
+    int foundPropertyIndex = findCustomPropertyIndex(propertyName);
+    if (foundPropertyIndex == -1)
+        return 0;
+    return &amp;m_propertyVector.at(foundPropertyIndex);
+}
+
</ins><span class="cx"> bool StyleProperties::propertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
</span><span class="cx"> {
</span><span class="cx">     int foundPropertyIndex = findPropertyIndex(propertyID);
</span><span class="lines">@@ -1265,6 +1385,8 @@
</span><span class="cx"> 
</span><span class="cx"> String StyleProperties::PropertyReference::cssName() const
</span><span class="cx"> {
</span><ins>+    if (id() == CSSPropertyCustom)
+        return downcast&lt;CSSCustomPropertyValue&gt;(*value()).name();
</ins><span class="cx">     return getPropertyNameString(id());
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssStylePropertiesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleProperties.h (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleProperties.h        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/StyleProperties.h        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -92,6 +92,10 @@
</span><span class="cx">     String getPropertyShorthand(CSSPropertyID) const;
</span><span class="cx">     bool isPropertyImplicit(CSSPropertyID) const;
</span><span class="cx"> 
</span><ins>+    RefPtr&lt;CSSValue&gt; getCustomPropertyCSSValue(const String&amp; propertyName) const;
+    String getCustomPropertyValue(const String&amp; propertyName) const;
+    bool customPropertyIsImportant(const String&amp; propertyName) const;
+
</ins><span class="cx">     Ref&lt;MutableStyleProperties&gt; copyBlockProperties() const;
</span><span class="cx"> 
</span><span class="cx">     CSSParserMode cssParserMode() const { return static_cast&lt;CSSParserMode&gt;(m_cssParserMode); }
</span><span class="lines">@@ -132,7 +136,8 @@
</span><span class="cx">     { }
</span><span class="cx"> 
</span><span class="cx">     int findPropertyIndex(CSSPropertyID) const;
</span><del>-
</del><ins>+    int findCustomPropertyIndex(const String&amp; propertyName) const;
+    
</ins><span class="cx">     unsigned m_cssParserMode : 2;
</span><span class="cx">     mutable unsigned m_isMutable : 1;
</span><span class="cx">     unsigned m_arraySize : 29;
</span><span class="lines">@@ -163,7 +168,8 @@
</span><span class="cx">     const CSSValue** valueArray() const;
</span><span class="cx">     const StylePropertyMetadata* metadataArray() const;
</span><span class="cx">     int findPropertyIndex(CSSPropertyID) const;
</span><del>-
</del><ins>+    int findCustomPropertyIndex(const String&amp; propertyName) const;
+    
</ins><span class="cx">     void* m_storage;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -221,9 +227,14 @@
</span><span class="cx">     CSSStyleDeclaration* ensureInlineCSSStyleDeclaration(StyledElement* parentElement);
</span><span class="cx"> 
</span><span class="cx">     int findPropertyIndex(CSSPropertyID) const;
</span><del>-
</del><ins>+    int findCustomPropertyIndex(const String&amp; propertyName) const;
+    
</ins><span class="cx">     Vector&lt;CSSProperty, 4&gt; m_propertyVector;
</span><span class="cx"> 
</span><ins>+    // Methods for querying and altering CSS custom properties.
+    bool setCustomProperty(const String&amp; propertyName, const String&amp; value, bool important = false, StyleSheetContents* contextStyleSheet = 0);
+    bool removeCustomProperty(const String&amp; propertyName, String* returnText = nullptr);
+
</ins><span class="cx"> private:
</span><span class="cx">     explicit MutableStyleProperties(CSSParserMode);
</span><span class="cx">     explicit MutableStyleProperties(const StyleProperties&amp;);
</span><span class="lines">@@ -231,6 +242,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool removeShorthandProperty(CSSPropertyID);
</span><span class="cx">     CSSProperty* findCSSPropertyWithID(CSSPropertyID);
</span><ins>+    CSSProperty* findCustomCSSPropertyWithName(const String&amp;);
</ins><span class="cx">     std::unique_ptr&lt;PropertySetCSSStyleDeclaration&gt; m_cssomWrapper;
</span><span class="cx"> 
</span><span class="cx">     friend class StyleProperties;
</span><span class="lines">@@ -279,6 +291,13 @@
</span><span class="cx">     return downcast&lt;ImmutableStyleProperties&gt;(*this).findPropertyIndex(propertyID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline int StyleProperties::findCustomPropertyIndex(const String&amp; propertyName) const
+{
+    if (is&lt;MutableStyleProperties&gt;(*this))
+        return downcast&lt;MutableStyleProperties&gt;(*this).findCustomPropertyIndex(propertyName);
+    return downcast&lt;ImmutableStyleProperties&gt;(*this).findCustomPropertyIndex(propertyName);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MutableStyleProperties)
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleResolvercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleResolver.cpp (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleResolver.cpp        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/StyleResolver.cpp        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;CSSBorderImage.h&quot;
</span><span class="cx"> #include &quot;CSSCalculationValue.h&quot;
</span><span class="cx"> #include &quot;CSSCursorImageValue.h&quot;
</span><ins>+#include &quot;CSSCustomPropertyValue.h&quot;
</ins><span class="cx"> #include &quot;CSSDefaultStyleSheets.h&quot;
</span><span class="cx"> #include &quot;CSSFilterImageValue.h&quot;
</span><span class="cx"> #include &quot;CSSFontFaceRule.h&quot;
</span><span class="lines">@@ -139,6 +140,7 @@
</span><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="cx"> #include &lt;wtf/TemporaryChange.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><ins>+#include &lt;wtf/text/AtomicStringHash.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(CSS_GRID_LAYOUT)
</span><span class="cx"> #include &quot;CSSGridLineNamesValue.h&quot;
</span><span class="lines">@@ -189,14 +191,17 @@
</span><span class="cx"> 
</span><span class="cx">     void applyDeferredProperties(StyleResolver&amp;);
</span><span class="cx"> 
</span><ins>+    HashMap&lt;AtomicString, Property&gt;&amp; customProperties() { return m_customProperties; }
+    
</ins><span class="cx"> private:
</span><span class="cx">     void addStyleProperties(const StyleProperties&amp;, StyleRule&amp;, bool isImportant, bool inheritedOnly, PropertyWhitelistType, unsigned linkMatchType);
</span><span class="cx">     static void setPropertyInternal(Property&amp;, CSSPropertyID, CSSValue&amp;, unsigned linkMatchType);
</span><span class="cx"> 
</span><del>-    Property m_properties[numCSSProperties + 1];
-    std::bitset&lt;numCSSProperties + 1&gt; m_propertyIsPresent;
</del><ins>+    Property m_properties[numCSSProperties + 2];
+    std::bitset&lt;numCSSProperties + 2&gt; m_propertyIsPresent;
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;Property, 8&gt; m_deferredProperties;
</span><ins>+    HashMap&lt;AtomicString, Property&gt; m_customProperties;
</ins><span class="cx"> 
</span><span class="cx">     TextDirection m_direction;
</span><span class="cx">     WritingMode m_writingMode;
</span><span class="lines">@@ -845,6 +850,9 @@
</span><span class="cx">     // decl, there's nothing to override. So just add the first properties.
</span><span class="cx">     CascadedProperties cascade(direction, writingMode);
</span><span class="cx">     cascade.addMatches(result, false, 0, result.matchedProperties().size() - 1);
</span><ins>+    
+    // Resolve custom properties first.
+    applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom);
</ins><span class="cx"> 
</span><span class="cx">     applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty);
</span><span class="cx"> 
</span><span class="lines">@@ -1011,6 +1019,9 @@
</span><span class="cx">     CascadedProperties cascade(direction, writingMode);
</span><span class="cx">     cascade.addMatches(result, false, 0, result.matchedProperties().size() - 1);
</span><span class="cx"> 
</span><ins>+    // Resolve custom properties first.
+    applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom);
+
</ins><span class="cx">     applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty);
</span><span class="cx"> 
</span><span class="cx">     // If our font got dirtied, update it now.
</span><span class="lines">@@ -1686,6 +1697,9 @@
</span><span class="cx"> 
</span><span class="cx">         applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition);
</span><span class="cx">         adjustStyleForInterCharacterRuby();
</span><ins>+    
+        // Resolve custom variables first.
+        applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom);
</ins><span class="cx"> 
</span><span class="cx">         // Start by applying properties that other properties may depend on.
</span><span class="cx">         applyCascadedProperties(cascade, firstCSSProperty, lastHighPriorityProperty);
</span><span class="lines">@@ -1701,6 +1715,9 @@
</span><span class="cx">     cascade.addMatches(matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
</span><span class="cx">     cascade.addMatches(matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
</span><span class="cx">     cascade.addMatches(matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
</span><ins>+    
+    // Resolve custom properties first.
+    applyCascadedProperties(cascade, CSSPropertyCustom, CSSPropertyCustom);
</ins><span class="cx"> 
</span><span class="cx">     applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition);
</span><span class="cx">     
</span><span class="lines">@@ -1881,6 +1898,12 @@
</span><span class="cx"> 
</span><span class="cx">     if (isInherit &amp;&amp; !state.parentStyle()-&gt;hasExplicitlyInheritedProperties() &amp;&amp; !CSSProperty::isInheritedProperty(id))
</span><span class="cx">         state.parentStyle()-&gt;setHasExplicitlyInheritedProperties();
</span><ins>+    
+    if (id == CSSPropertyCustom) {
+        CSSCustomPropertyValue* customProperty = &amp;downcast&lt;CSSCustomPropertyValue&gt;(*value);
+        state.style()-&gt;setCustomPropertyValue(customProperty-&gt;name(), customProperty-&gt;value());
+        return;
+    }
</ins><span class="cx"> 
</span><span class="cx">     // Use the generated StyleBuilder.
</span><span class="cx">     StyleBuilder::applyProperty(id, *this, *value, isInitial, isInherit);
</span><span class="lines">@@ -2526,6 +2549,24 @@
</span><span class="cx"> 
</span><span class="cx">     auto&amp; property = m_properties[id];
</span><span class="cx">     ASSERT(id &lt; m_propertyIsPresent.size());
</span><ins>+    if (id == CSSPropertyCustom) {
+        m_propertyIsPresent.set(id);
+        const auto&amp; customValue = downcast&lt;CSSCustomPropertyValue&gt;(cssValue);
+        bool hasValue = customProperties().contains(customValue.name());
+        if (!hasValue) {
+            Property property;
+            property.id = id;
+            memset(property.cssValue, 0, sizeof(property.cssValue));
+            setPropertyInternal(property, id, cssValue, linkMatchType);
+            customProperties().set(customValue.name(), property);
+        } else {
+            Property property = customProperties().get(customValue.name());
+            setPropertyInternal(property, id, cssValue, linkMatchType);
+            customProperties().set(customValue.name(), property);
+        }
+        return;
+    }
+    
</ins><span class="cx">     if (!m_propertyIsPresent[id])
</span><span class="cx">         memset(property.cssValue, 0, sizeof(property.cssValue));
</span><span class="cx">     m_propertyIsPresent.set(id);
</span><span class="lines">@@ -2623,6 +2664,12 @@
</span><span class="cx">         CSSPropertyID propertyID = static_cast&lt;CSSPropertyID&gt;(id);
</span><span class="cx">         if (!cascade.hasProperty(propertyID))
</span><span class="cx">             continue;
</span><ins>+        if (propertyID == CSSPropertyCustom) {
+            HashMap&lt;AtomicString, CascadedProperties::Property&gt;::iterator end = cascade.customProperties().end();
+            for (HashMap&lt;AtomicString, CascadedProperties::Property&gt;::iterator it = cascade.customProperties().begin(); it != end; ++it)
+                it-&gt;value.apply(*this);
+            continue;
+        }
</ins><span class="cx">         auto&amp; property = cascade.property(propertyID);
</span><span class="cx">         ASSERT(!shouldApplyPropertyInParseOrder(propertyID));
</span><span class="cx">         property.apply(*this);
</span></span></pre></div>
<a id="trunkSourceWebCorecssmakeproppl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/makeprop.pl (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/makeprop.pl        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/css/makeprop.pl        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx"> my %namesHash;
</span><span class="cx"> my @duplicates = ();
</span><span class="cx"> 
</span><del>-my $numPredefinedProperties = 1;
</del><ins>+my $numPredefinedProperties = 2;
</ins><span class="cx"> my @names = ();
</span><span class="cx"> my %nameIsInherited;
</span><span class="cx"> my %propertiesWithStyleBuilderOptions;
</span><span class="lines">@@ -236,6 +236,7 @@
</span><span class="cx"> 
</span><span class="cx"> static const bool isInheritedPropertyTable[numCSSProperties + $numPredefinedProperties] = {
</span><span class="cx">     false, // CSSPropertyInvalid
</span><ins>+    false, // CSSPropertyCustom
</ins><span class="cx"> EOF
</span><span class="cx"> 
</span><span class="cx"> foreach my $name (@names) {
</span><span class="lines">@@ -283,6 +284,7 @@
</span><span class="cx"> 
</span><span class="cx"> enum CSSPropertyID : uint16_t {
</span><span class="cx">     CSSPropertyInvalid = 0,
</span><ins>+    CSSPropertyCustom = 1,
</ins><span class="cx"> EOF
</span><span class="cx"> 
</span><span class="cx"> my $first = $numPredefinedProperties;
</span><span class="lines">@@ -313,7 +315,7 @@
</span><span class="cx"> 
</span><span class="cx"> inline CSSPropertyID convertToCSSPropertyID(int value)
</span><span class="cx"> {
</span><del>-    ASSERT((value &gt;= firstCSSProperty &amp;&amp; value &lt;= lastCSSProperty) || value == CSSPropertyInvalid);
</del><ins>+    ASSERT((value &gt;= firstCSSProperty &amp;&amp; value &lt;= lastCSSProperty) || value == CSSPropertyInvalid || value == CSSPropertyCustom);
</ins><span class="cx">     return static_cast&lt;CSSPropertyID&gt;(value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -872,6 +874,7 @@
</span><span class="cx"> {
</span><span class="cx">     switch (property) {
</span><span class="cx">     case CSSPropertyInvalid:
</span><ins>+    case CSSPropertyCustom:
</ins><span class="cx">         break;
</span><span class="cx"> EOF
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorStyleSheetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -348,6 +348,14 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static String lowercasePropertyName(const String&amp; name)
+{
+    // Custom properties are case-sensitive.
+    if (name.length() &gt; 2 &amp;&amp; name.characterAt(0) == '-' &amp;&amp; name.characterAt(1) == '-')
+        return name;
+    return name.lower();
+}
+
</ins><span class="cx"> bool InspectorStyle::populateAllProperties(Vector&lt;InspectorStyleProperty&gt;* result) const
</span><span class="cx"> {
</span><span class="cx">     HashSet&lt;String&gt; sourcePropertyNames;
</span><span class="lines">@@ -362,16 +370,16 @@
</span><span class="cx">             InspectorStyleProperty p(*it, true, false);
</span><span class="cx">             p.setRawTextFromStyleDeclaration(styleDeclaration);
</span><span class="cx">             result-&gt;append(p);
</span><del>-            sourcePropertyNames.add(it-&gt;name.lower());
</del><ins>+            sourcePropertyNames.add(lowercasePropertyName(it-&gt;name));
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (int i = 0, size = m_style-&gt;length(); i &lt; size; ++i) {
</span><span class="cx">         String name = m_style-&gt;item(i);
</span><del>-        if (sourcePropertyNames.contains(name.lower()))
</del><ins>+        String lowerName = lowercasePropertyName(name);
+        if (sourcePropertyNames.contains(lowerName))
</ins><span class="cx">             continue;
</span><del>-
-        sourcePropertyNames.add(name.lower());
</del><ins>+        sourcePropertyNames.add(lowerName);
</ins><span class="cx">         result-&gt;append(InspectorStyleProperty(CSSPropertySourceData(name, m_style-&gt;getPropertyValue(name), !m_style-&gt;getPropertyPriority(name).isEmpty(), true, SourceRange()), false, false));
</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 (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/RenderStyle.h        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -513,6 +513,11 @@
</span><span class="cx"> 
</span><span class="cx">     const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); }
</span><span class="cx"> 
</span><ins>+    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); }
+    bool hasCustomProperty(const AtomicString&amp; name) const { return rareInheritedData-&gt;m_customProperties-&gt;hasCustomProperty(name); }
+    const HashMap&lt;AtomicString, String&gt;* customProperties() const { return &amp;(rareInheritedData-&gt;m_customProperties-&gt;m_values); }
+
</ins><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 class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleStyleCustomPropertyDatah"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h (0 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h                                (rev 0)
+++ trunk/Source/WebCore/rendering/style/StyleCustomPropertyData.h        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef StyleCustomPropertyData_h
+#define StyleCustomPropertyData_h
+
+#include &lt;wtf/Forward.h&gt;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/RefCounted.h&gt;
+#include &lt;wtf/text/AtomicStringHash.h&gt;
+
+namespace WebCore {
+
+class StyleCustomPropertyData : public RefCounted&lt;StyleCustomPropertyData&gt; {
+public:
+    static Ref&lt;StyleCustomPropertyData&gt; create() { return adoptRef(*new StyleCustomPropertyData); }
+    Ref&lt;StyleCustomPropertyData&gt; copy() const { return adoptRef(*new StyleCustomPropertyData(*this)); }
+    
+    bool operator==(const StyleCustomPropertyData&amp; o) const { return m_values == o.m_values; }
+    bool operator!=(const StyleCustomPropertyData &amp;o) const { return !(*this == o); }
+    
+    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); }
+    bool hasCustomProperty(const AtomicString&amp; name) const { return m_values.contains(name); }
+
+    HashMap&lt;AtomicString, String&gt; m_values;
+    
+private:
+    explicit StyleCustomPropertyData()
+        : RefCounted&lt;StyleCustomPropertyData&gt;()
+    { }
+    StyleCustomPropertyData(const StyleCustomPropertyData&amp; other)
+        : RefCounted&lt;StyleCustomPropertyData&gt;()
+        , m_values(HashMap&lt;AtomicString, String&gt;(other.m_values))
+    { }
+};
+
+} // namespace WebCore
+
+#endif // StyleCustomPropertyData_h
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleStyleRareInheritedDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/StyleRareInheritedData.cpp (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/StyleRareInheritedData.cpp        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/rendering/style/StyleRareInheritedData.cpp        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -23,10 +23,12 @@
</span><span class="cx"> #include &quot;StyleRareInheritedData.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CursorList.h&quot;
</span><ins>+#include &quot;DataRef.h&quot;
</ins><span class="cx"> #include &quot;QuotesData.h&quot;
</span><span class="cx"> #include &quot;RenderStyle.h&quot;
</span><span class="cx"> #include &quot;RenderStyleConstants.h&quot;
</span><span class="cx"> #include &quot;ShadowData.h&quot;
</span><ins>+#include &quot;StyleCustomPropertyData.h&quot;
</ins><span class="cx"> #include &quot;StyleImage.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -60,6 +62,8 @@
</span><span class="cx"> #if ENABLE(TOUCH_EVENTS)
</span><span class="cx">     Color tapHighlightColor;
</span><span class="cx"> #endif
</span><ins>+
+    void* customPropertyDataRefs[1];
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> COMPILE_ASSERT(sizeof(StyleRareInheritedData) &lt;= sizeof(GreaterThanOrSameSizeAsStyleRareInheritedData), StyleRareInheritedData_should_bit_pack);
</span><span class="lines">@@ -69,6 +73,7 @@
</span><span class="cx">     , textStrokeWidth(RenderStyle::initialTextStrokeWidth())
</span><span class="cx">     , indent(RenderStyle::initialTextIndent())
</span><span class="cx">     , m_effectiveZoom(RenderStyle::initialZoom())
</span><ins>+    , m_customProperties(StyleCustomPropertyData::create())
</ins><span class="cx">     , widows(RenderStyle::initialWidows())
</span><span class="cx">     , orphans(RenderStyle::initialOrphans())
</span><span class="cx">     , m_hasAutoWidows(true)
</span><span class="lines">@@ -150,6 +155,7 @@
</span><span class="cx">     , cursorData(o.cursorData)
</span><span class="cx">     , indent(o.indent)
</span><span class="cx">     , m_effectiveZoom(o.m_effectiveZoom)
</span><ins>+    , m_customProperties(o.m_customProperties)
</ins><span class="cx">     , widows(o.widows)
</span><span class="cx">     , orphans(o.orphans)
</span><span class="cx">     , m_hasAutoWidows(o.m_hasAutoWidows)
</span><span class="lines">@@ -324,6 +330,7 @@
</span><span class="cx"> #if ENABLE(CSS_TRAILING_WORD)
</span><span class="cx">         &amp;&amp; trailingWord == o.trailingWord
</span><span class="cx"> #endif
</span><ins>+        &amp;&amp; m_customProperties == o.m_customProperties
</ins><span class="cx">         &amp;&amp; StyleImage::imagesEquivalent(listStyleImage.get(), o.listStyleImage.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleStyleRareInheritedDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/StyleRareInheritedData.h (190208 => 190209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/StyleRareInheritedData.h        2015-09-24 17:25:13 UTC (rev 190208)
+++ trunk/Source/WebCore/rendering/style/StyleRareInheritedData.h        2015-09-24 18:15:52 UTC (rev 190209)
</span><span class="lines">@@ -26,7 +26,9 @@
</span><span class="cx"> #define StyleRareInheritedData_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Color.h&quot;
</span><ins>+#include &quot;DataRef.h&quot;
</ins><span class="cx"> #include &quot;Length.h&quot;
</span><ins>+#include &quot;StyleCustomPropertyData.h&quot;
</ins><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/text/AtomicString.h&gt;
</span><span class="lines">@@ -77,6 +79,8 @@
</span><span class="cx">     
</span><span class="cx">     Length wordSpacing;
</span><span class="cx"> 
</span><ins>+    DataRef&lt;StyleCustomPropertyData&gt; m_customProperties;
+
</ins><span class="cx">     // Paged media properties.
</span><span class="cx">     short widows;
</span><span class="cx">     short orphans;
</span></span></pre>
</div>
</div>

</body>
</html>