<!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>[183017] 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/183017">183017</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2015-04-20 11:31:45 -0700 (Mon, 20 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Setting inline style to the same value it already has triggers a style recalc
https://bugs.webkit.org/show_bug.cgi?id=143922

Reviewed by Antti Koivisto.

Source/WebCore:

MutableStyleProperties::setProperty() was taking the result of CSSParser::parseValue()
to mean &quot;parsing changed the style&quot;, but it actually just means &quot;parsing succeeded&quot;.
Add a new out param, piped through various parser functions, to indicate whether
parsing actually changed style, and instead return that from setProperty().

Add internals.startTrackingStyleRecalcs() and internals.styleRecalcCount() so
we can write tests for style recalc.

Test: fast/css/set-inline-style-recalc.html

* WebCore.xcodeproj/project.pbxproj: Let Xcode have it's way.
* css/CSSParser.cpp:
(WebCore::parseColorValue):
(WebCore::parseSimpleLengthValue):
(WebCore::parseKeywordValue):
(WebCore::parseTranslateTransformValue):
(WebCore::CSSParser::parseFontFaceValue):
(WebCore::CSSParser::parseValue):
* css/CSSParser.h:
* css/CSSProperty.h:
(WebCore::StylePropertyMetadata::operator==):
(WebCore::CSSProperty::operator==):
* css/DOMWindowCSS.cpp:
(WebCore::DOMWindowCSS::supports):
* css/StyleProperties.cpp:
(WebCore::MutableStyleProperties::setProperty):
(WebCore::MutableStyleProperties::appendPrefixingVariantProperty):
(WebCore::MutableStyleProperties::addParsedProperties):
(WebCore::MutableStyleProperties::addParsedProperty):
* css/StyleProperties.h:
* css/WebKitCSSMatrix.cpp:
(WebCore::WebKitCSSMatrix::setMatrixValue):
* dom/Document.cpp:
(WebCore::Document::recalcStyle):
(WebCore::Document::startTrackingStyleRecalcs):
(WebCore::Document::styleRecalcCount):
* dom/Document.h:
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::setFont):
* testing/Internals.cpp:
(WebCore::Internals::startTrackingStyleRecalcs):
(WebCore::Internals::styleRecalcCount):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

Test that changes inline-style (to test this bug fix), and classes (for
proactive testing) and counts style recalcs.

* fast/css/set-inline-style-recalc-expected.txt: Added.
* fast/css/set-inline-style-recalc.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="#trunkSourceWebCorecssCSSParsercpp">trunk/Source/WebCore/css/CSSParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSParserh">trunk/Source/WebCore/css/CSSParser.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSPropertyh">trunk/Source/WebCore/css/CSSProperty.h</a></li>
<li><a href="#trunkSourceWebCorecssDOMWindowCSScpp">trunk/Source/WebCore/css/DOMWindowCSS.cpp</a></li>
<li><a href="#trunkSourceWebCorecssFontLoadercpp">trunk/Source/WebCore/css/FontLoader.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="#trunkSourceWebCorecssWebKitCSSMatrixcpp">trunk/Source/WebCore/css/WebKitCSSMatrix.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumenth">trunk/Source/WebCore/dom/Document.h</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasCanvasRenderingContext2Dcpp">trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsh">trunk/Source/WebCore/testing/Internals.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsidl">trunk/Source/WebCore/testing/Internals.idl</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastcsssetinlinestylerecalcexpectedtxt">trunk/LayoutTests/fast/css/set-inline-style-recalc-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcsssetinlinestylerecalchtml">trunk/LayoutTests/fast/css/set-inline-style-recalc.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/LayoutTests/ChangeLog        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2015-04-20  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Setting inline style to the same value it already has triggers a style recalc
+        https://bugs.webkit.org/show_bug.cgi?id=143922
+
+        Reviewed by Antti Koivisto.
+
+        Test that changes inline-style (to test this bug fix), and classes (for
+        proactive testing) and counts style recalcs.
+
+        * fast/css/set-inline-style-recalc-expected.txt: Added.
+        * fast/css/set-inline-style-recalc.html: Added.
+
</ins><span class="cx"> 2015-04-20  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Crash in StyleResolver::invalidateMatchedPropertiesCache() when using content extensions.
</span></span></pre></div>
<a id="trunkLayoutTestsfastcsssetinlinestylerecalcexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/set-inline-style-recalc-expected.txt (0 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/set-inline-style-recalc-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/css/set-inline-style-recalc-expected.txt        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+Test to count the number of recalcStyle calls on inline style and class changes.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS numStyleRecalcs is 1
+PASS numStyleRecalcs is 1
+PASS numStyleRecalcs is 0
+PASS numStyleRecalcs is 1
+PASS numStyleRecalcs is 0
+PASS numStyleRecalcs is 1
+PASS numStyleRecalcs is 0
+PASS numStyleRecalcs is 1
+PASS numStyleRecalcs is 0
+PASS numStyleRecalcs is 1
+PASS numStyleRecalcs is 0
+PASS numStyleRecalcs is 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcsssetinlinestylerecalchtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css/set-inline-style-recalc.html (0 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/set-inline-style-recalc.html                                (rev 0)
+++ trunk/LayoutTests/fast/css/set-inline-style-recalc.html        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;style&gt;
+    .test {
+        position: relative;
+    }
+    
+    .foo {
+        font-size: 10px;
+    }
+    
+    .bar {
+    }
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+function setStyleAndForceLayout(changeFunc)
+{
+    if (window.internals) {
+        internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
+        internals.startTrackingStyleRecalcs();
+    }
+
+    changeFunc();
+
+    var numStyleRecalcs = 0;
+    if (window.internals) {
+        internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks();
+        numStyleRecalcs = internals.styleRecalcCount();
+    }
+    return numStyleRecalcs;
+}
+
+description(&quot;Test to count the number of recalcStyle calls on inline style and class changes.&quot;)
+
+var testContainer = document.createElement(&quot;div&quot;);
+testContainer.className = 'test';
+document.body.appendChild(testContainer);
+
+var style = testContainer.style;
+
+var numStyleRecalcs = setStyleAndForceLayout(function() { style.height = &quot;10px&quot;; });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;1&quot;);
+numStyleRecalcs = setStyleAndForceLayout(function() { style.height = &quot;20px&quot;; });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;1&quot;);
+numStyleRecalcs = setStyleAndForceLayout(function() { style.height = &quot;20px&quot;; });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;0&quot;);
+
+numStyleRecalcs = setStyleAndForceLayout(function() { style.backgroundPosition = &quot;10px 10%&quot;; });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;1&quot;);
+numStyleRecalcs = setStyleAndForceLayout(function() { style.backgroundPosition = &quot;10px 10%&quot;; });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;0&quot;);
+
+numStyleRecalcs = setStyleAndForceLayout(function() { style.backgroundColor = &quot;red&quot;; });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;1&quot;);
+numStyleRecalcs = setStyleAndForceLayout(function() { style.backgroundColor = &quot;red&quot;; });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;0&quot;);
+
+numStyleRecalcs = setStyleAndForceLayout(function() { style.transform = &quot;translate(10px, 10px) rotate(10deg)&quot;; });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;1&quot;);
+numStyleRecalcs = setStyleAndForceLayout(function() { style.transform = &quot;translate(10px, 10px) rotate(10deg)&quot;; });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;0&quot;);
+
+numStyleRecalcs = setStyleAndForceLayout(function() { testContainer.classList.add('foo'); });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;1&quot;);
+numStyleRecalcs = setStyleAndForceLayout(function() { testContainer.classList.add('foo'); });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;0&quot;);
+numStyleRecalcs = setStyleAndForceLayout(function() { testContainer.classList.add('bar'); });
+shouldBe(&quot;numStyleRecalcs&quot;, &quot;1&quot;);
+
+document.body.removeChild(testContainer);
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/ChangeLog        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -1,3 +1,55 @@
</span><ins>+2015-04-20  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Setting inline style to the same value it already has triggers a style recalc
+        https://bugs.webkit.org/show_bug.cgi?id=143922
+
+        Reviewed by Antti Koivisto.
+
+        MutableStyleProperties::setProperty() was taking the result of CSSParser::parseValue()
+        to mean &quot;parsing changed the style&quot;, but it actually just means &quot;parsing succeeded&quot;.
+        Add a new out param, piped through various parser functions, to indicate whether
+        parsing actually changed style, and instead return that from setProperty().
+
+        Add internals.startTrackingStyleRecalcs() and internals.styleRecalcCount() so
+        we can write tests for style recalc.
+
+        Test: fast/css/set-inline-style-recalc.html
+
+        * WebCore.xcodeproj/project.pbxproj: Let Xcode have it's way.
+        * css/CSSParser.cpp:
+        (WebCore::parseColorValue):
+        (WebCore::parseSimpleLengthValue):
+        (WebCore::parseKeywordValue):
+        (WebCore::parseTranslateTransformValue):
+        (WebCore::CSSParser::parseFontFaceValue):
+        (WebCore::CSSParser::parseValue):
+        * css/CSSParser.h:
+        * css/CSSProperty.h:
+        (WebCore::StylePropertyMetadata::operator==):
+        (WebCore::CSSProperty::operator==):
+        * css/DOMWindowCSS.cpp:
+        (WebCore::DOMWindowCSS::supports):
+        * css/StyleProperties.cpp:
+        (WebCore::MutableStyleProperties::setProperty):
+        (WebCore::MutableStyleProperties::appendPrefixingVariantProperty):
+        (WebCore::MutableStyleProperties::addParsedProperties):
+        (WebCore::MutableStyleProperties::addParsedProperty):
+        * css/StyleProperties.h:
+        * css/WebKitCSSMatrix.cpp:
+        (WebCore::WebKitCSSMatrix::setMatrixValue):
+        * dom/Document.cpp:
+        (WebCore::Document::recalcStyle):
+        (WebCore::Document::startTrackingStyleRecalcs):
+        (WebCore::Document::styleRecalcCount):
+        * dom/Document.h:
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::setFont):
+        * testing/Internals.cpp:
+        (WebCore::Internals::startTrackingStyleRecalcs):
+        (WebCore::Internals::styleRecalcCount):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
</ins><span class="cx"> 2015-04-20  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Crash in StyleResolver::invalidateMatchedPropertiesCache() when using content extensions.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -12799,7 +12799,7 @@
</span><span class="cx">                 BC74DA471013F468007987AD /* JSRGBColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRGBColor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC76AC110DD7AD5C00415F34 /* ParserUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserUtilities.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC772B360C4EA91E0083285F /* CSSHelper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSSHelper.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                BC772B370C4EA91E0083285F /* CSSParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = CSSParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
</del><ins>+                BC772B370C4EA91E0083285F /* CSSParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = CSSParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 BC772B380C4EA91E0083285F /* CSSParser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CSSParser.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC772C440C4EB2C60083285F /* XMLHttpRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = XMLHttpRequest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 BC772C450C4EB2C60083285F /* XMLHttpRequest.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XMLHttpRequest.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParser.cpp (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.cpp        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/css/CSSParser.cpp        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -520,26 +520,26 @@
</span><span class="cx">         || (valueID &gt;= CSSValueWebkitFocusRingColor &amp;&amp; valueID &lt; CSSValueWebkitText &amp;&amp; !strict));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool parseColorValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String&amp; string, bool important, CSSParserMode cssParserMode)
</del><ins>+static CSSParser::ParseResult parseColorValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String&amp; string, bool important, CSSParserMode cssParserMode)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!string.isEmpty());
</span><span class="cx">     bool strict = isStrictParserMode(cssParserMode);
</span><span class="cx">     if (!isColorPropertyID(propertyId))
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
+
</ins><span class="cx">     CSSParserString cssString;
</span><span class="cx">     cssString.init(string);
</span><span class="cx">     CSSValueID valueID = cssValueKeywordID(cssString);
</span><span class="cx">     if (validPrimitiveValueColor(valueID, strict)) {
</span><span class="cx">         RefPtr&lt;CSSValue&gt; value = cssValuePool().createIdentifierValue(valueID);
</span><del>-        declaration-&gt;addParsedProperty(CSSProperty(propertyId, value.release(), important));
-        return true;
</del><ins>+        return declaration-&gt;addParsedProperty(CSSProperty(propertyId, value.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
</ins><span class="cx">     }
</span><span class="cx">     RGBA32 color;
</span><span class="cx">     if (!CSSParser::fastParseColor(color, string, strict &amp;&amp; string[0] != '#'))
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
+
</ins><span class="cx">     RefPtr&lt;CSSValue&gt; value = cssValuePool().createColorValue(color);
</span><del>-    declaration-&gt;addParsedProperty(CSSProperty(propertyId, value.release(), important));
-    return true;
</del><ins>+    return declaration-&gt;addParsedProperty(CSSProperty(propertyId, value.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool&amp; acceptsNegativeNumbers)
</span><span class="lines">@@ -614,12 +614,12 @@
</span><span class="cx">     return ok;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool parseSimpleLengthValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String&amp; string, bool important, CSSParserMode cssParserMode)
</del><ins>+static CSSParser::ParseResult parseSimpleLengthValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String&amp; string, bool important, CSSParserMode cssParserMode)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!string.isEmpty());
</span><span class="cx">     bool acceptsNegativeNumbers;
</span><span class="cx">     if (!isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
</ins><span class="cx"> 
</span><span class="cx">     unsigned length = string.length();
</span><span class="cx">     double number;
</span><span class="lines">@@ -627,25 +627,24 @@
</span><span class="cx"> 
</span><span class="cx">     if (string.is8Bit()) {
</span><span class="cx">         if (!parseSimpleLength(string.characters8(), length, unit, number))
</span><del>-            return false;
</del><ins>+            return CSSParser::ParseResult::Error;
</ins><span class="cx">     } else {
</span><span class="cx">         if (!parseSimpleLength(string.characters16(), length, unit, number))
</span><del>-            return false;
</del><ins>+            return CSSParser::ParseResult::Error;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (unit == CSSPrimitiveValue::CSS_NUMBER) {
</span><span class="cx">         if (number &amp;&amp; isStrictParserMode(cssParserMode))
</span><del>-            return false;
</del><ins>+            return CSSParser::ParseResult::Error;
</ins><span class="cx">         unit = CSSPrimitiveValue::CSS_PX;
</span><span class="cx">     }
</span><span class="cx">     if (number &lt; 0 &amp;&amp; !acceptsNegativeNumbers)
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
</ins><span class="cx">     if (std::isinf(number))
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
</ins><span class="cx"> 
</span><span class="cx">     RefPtr&lt;CSSValue&gt; value = cssValuePool().createValue(number, unit);
</span><del>-    declaration-&gt;addParsedProperty(CSSProperty(propertyId, value.release(), important));
-    return true;
</del><ins>+    return declaration-&gt;addParsedProperty(CSSProperty(propertyId, value.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext&amp; parserContext, StyleSheetContents* styleSheetContents)
</span><span class="lines">@@ -1178,7 +1177,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool parseKeywordValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String&amp; string, bool important, const CSSParserContext&amp; parserContext, StyleSheetContents* styleSheetContents)
</del><ins>+static CSSParser::ParseResult parseKeywordValue(MutableStyleProperties* declaration, CSSPropertyID propertyId, const String&amp; string, bool important, const CSSParserContext&amp; parserContext, StyleSheetContents* styleSheetContents)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!string.isEmpty());
</span><span class="cx"> 
</span><span class="lines">@@ -1186,11 +1185,11 @@
</span><span class="cx">         // All properties accept the values of &quot;initial&quot; and &quot;inherit&quot;.
</span><span class="cx">         String lowerCaseString = string.lower();
</span><span class="cx">         if (lowerCaseString != &quot;initial&quot; &amp;&amp; lowerCaseString != &quot;inherit&quot;)
</span><del>-            return false;
</del><ins>+            return CSSParser::ParseResult::Error;
</ins><span class="cx"> 
</span><span class="cx">         // Parse initial/inherit shorthands using the CSSParser.
</span><span class="cx">         if (shorthandForProperty(propertyId).length())
</span><del>-            return false;
</del><ins>+            return CSSParser::ParseResult::Error;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     CSSParserString cssString;
</span><span class="lines">@@ -1198,7 +1197,7 @@
</span><span class="cx">     CSSValueID valueID = cssValueKeywordID(cssString);
</span><span class="cx"> 
</span><span class="cx">     if (!valueID)
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
</ins><span class="cx"> 
</span><span class="cx">     RefPtr&lt;CSSValue&gt; value;
</span><span class="cx">     if (valueID == CSSValueInherit)
</span><span class="lines">@@ -1208,10 +1207,9 @@
</span><span class="cx">     else if (isValidKeywordPropertyAndValue(propertyId, valueID, parserContext, styleSheetContents))
</span><span class="cx">         value = cssValuePool().createIdentifierValue(valueID);
</span><span class="cx">     else
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
</ins><span class="cx"> 
</span><del>-    declaration-&gt;addParsedProperty(CSSProperty(propertyId, value.release(), important));
-    return true;
</del><ins>+    return declaration-&gt;addParsedProperty(CSSProperty(propertyId, value.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename CharacterType&gt;
</span><span class="lines">@@ -1235,16 +1233,19 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool parseTranslateTransformValue(MutableStyleProperties* properties, CSSPropertyID propertyID, const String&amp; string, bool important)
</del><ins>+static CSSParser::ParseResult parseTranslateTransformValue(MutableStyleProperties* properties, CSSPropertyID propertyID, const String&amp; string, bool important)
</ins><span class="cx"> {
</span><span class="cx">     if (propertyID != CSSPropertyTransform)
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
+
</ins><span class="cx">     static const unsigned shortestValidTransformStringLength = 12;
</span><span class="cx">     static const unsigned likelyMultipartTransformStringLengthCutoff = 32;
</span><span class="cx">     if (string.length() &lt; shortestValidTransformStringLength || string.length() &gt; likelyMultipartTransformStringLengthCutoff)
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
+
</ins><span class="cx">     if (!string.startsWith(&quot;translate&quot;, false))
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
+
</ins><span class="cx">     UChar c9 = toASCIILower(string[9]);
</span><span class="cx">     UChar c10 = toASCIILower(string[10]);
</span><span class="cx"> 
</span><span class="lines">@@ -1266,7 +1267,7 @@
</span><span class="cx">         expectedArgumentCount = 3;
</span><span class="cx">         argumentStart = 12;
</span><span class="cx">     } else
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
</ins><span class="cx"> 
</span><span class="cx">     RefPtr&lt;WebKitCSSTransformValue&gt; transformValue = WebKitCSSTransformValue::create(transformType);
</span><span class="cx">     bool success;
</span><span class="lines">@@ -1275,11 +1276,11 @@
</span><span class="cx">     else
</span><span class="cx">         success = parseTransformTranslateArguments(*transformValue, string.characters16(), string.length(), argumentStart, expectedArgumentCount);
</span><span class="cx">     if (!success)
</span><del>-        return false;
</del><ins>+        return CSSParser::ParseResult::Error;
+
</ins><span class="cx">     RefPtr&lt;CSSValueList&gt; result = CSSValueList::createSpaceSeparated();
</span><span class="cx">     result-&gt;append(transformValue.releaseNonNull());
</span><del>-    properties-&gt;addParsedProperty(CSSProperty(CSSPropertyTransform, result.release(), important));
-    return true;
</del><ins>+    return properties-&gt;addParsedProperty(CSSProperty(CSSPropertyTransform, result.release(), important)) ? CSSParser::ParseResult::Changed : CSSParser::ParseResult::Unchanged;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;CSSValueList&gt; CSSParser::parseFontFaceValue(const AtomicString&amp; string)
</span><span class="lines">@@ -1287,7 +1288,8 @@
</span><span class="cx">     if (string.isEmpty())
</span><span class="cx">         return nullptr;
</span><span class="cx">     RefPtr&lt;MutableStyleProperties&gt; dummyStyle = MutableStyleProperties::create();
</span><del>-    if (!parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, CSSQuirksMode, nullptr))
</del><ins>+
+    if (parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, CSSQuirksMode, nullptr) == ParseResult::Error)
</ins><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;CSSValue&gt; fontFamily = dummyStyle-&gt;getPropertyCSSValue(CSSPropertyFontFamily);
</span><span class="lines">@@ -1296,30 +1298,36 @@
</span><span class="cx">     return static_pointer_cast&lt;CSSValueList&gt;(fontFamily.release());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String&amp; string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
</del><ins>+CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String&amp; string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!string.isEmpty());
</span><del>-    if (parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode))
-        return true;
-    if (parseColorValue(declaration, propertyID, string, important, cssParserMode))
-        return true;
</del><ins>+    CSSParser::ParseResult result = parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode);
+    if (result != ParseResult::Error)
+        return result;
</ins><span class="cx"> 
</span><ins>+    result = parseColorValue(declaration, propertyID, string, important, cssParserMode);
+    if (result != ParseResult::Error)
+        return result;
+
</ins><span class="cx">     CSSParserContext context(cssParserMode);
</span><span class="cx">     if (contextStyleSheet) {
</span><span class="cx">         context = contextStyleSheet-&gt;parserContext();
</span><span class="cx">         context.mode = cssParserMode;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (parseKeywordValue(declaration, propertyID, string, important, context, contextStyleSheet))
-        return true;
-    if (parseTranslateTransformValue(declaration, propertyID, string, important))
-        return true;
</del><ins>+    result = parseKeywordValue(declaration, propertyID, string, important, context, contextStyleSheet);
+    if (result != ParseResult::Error)
+        return result;
</ins><span class="cx"> 
</span><ins>+    result = parseTranslateTransformValue(declaration, propertyID, string, important);
+    if (result != ParseResult::Error)
+        return result;
+
</ins><span class="cx">     CSSParser parser(context);
</span><span class="cx">     return parser.parseValue(declaration, propertyID, string, important, contextStyleSheet);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String&amp; string, bool important, StyleSheetContents* contextStyleSheet)
</del><ins>+CSSParser::ParseResult CSSParser::parseValue(MutableStyleProperties* declaration, CSSPropertyID propertyID, const String&amp; string, bool important, StyleSheetContents* contextStyleSheet)
</ins><span class="cx"> {
</span><span class="cx">     setStyleSheet(contextStyleSheet);
</span><span class="cx"> 
</span><span class="lines">@@ -1332,16 +1340,16 @@
</span><span class="cx"> 
</span><span class="cx">     m_rule = nullptr;
</span><span class="cx"> 
</span><del>-    bool ok = false;
</del><ins>+    ParseResult result = ParseResult::Error;
</ins><span class="cx">     if (m_hasFontFaceOnlyValues)
</span><span class="cx">         deleteFontFaceOnlyValues();
</span><ins>+
</ins><span class="cx">     if (!m_parsedProperties.isEmpty()) {
</span><del>-        ok = true;
-        declaration-&gt;addParsedProperties(m_parsedProperties);
</del><ins>+        result = declaration-&gt;addParsedProperties(m_parsedProperties) ? ParseResult::Changed : ParseResult::Unchanged;
</ins><span class="cx">         clearProperties();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return ok;
</del><ins>+    return result;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // The color will only be changed when string contains a valid CSS color, so callers
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParser.h (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.h        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/css/CSSParser.h        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -81,6 +81,12 @@
</span><span class="cx">         GeneralSyntaxError
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    enum class ParseResult {
+        Changed,
+        Unchanged,
+        Error
+    };
+
</ins><span class="cx">     class ValueWithCalculation {
</span><span class="cx">     public:
</span><span class="cx">         explicit ValueWithCalculation(CSSParserValue&amp; value)
</span><span class="lines">@@ -103,18 +109,20 @@
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT CSSParser(const CSSParserContext&amp;);
</span><del>-
</del><span class="cx">     WEBCORE_EXPORT ~CSSParser();
</span><span class="cx"> 
</span><span class="cx">     void parseSheet(StyleSheetContents*, const String&amp;, const TextPosition&amp;, RuleSourceDataList*, bool logErrors);
</span><span class="cx">     PassRefPtr&lt;StyleRuleBase&gt; parseRule(StyleSheetContents*, const String&amp;);
</span><span class="cx">     PassRefPtr&lt;StyleKeyframe&gt; parseKeyframeRule(StyleSheetContents*, const String&amp;);
</span><span class="cx">     bool parseSupportsCondition(const String&amp;);
</span><del>-    static bool parseValue(MutableStyleProperties*, CSSPropertyID, const String&amp;, bool important, CSSParserMode, StyleSheetContents*);
</del><ins>+
+    static ParseResult parseValue(MutableStyleProperties*, CSSPropertyID, const String&amp;, bool important, CSSParserMode, StyleSheetContents*);
+
</ins><span class="cx">     static bool parseColor(RGBA32&amp; color, const String&amp;, bool strict = false);
</span><span class="cx">     static bool parseSystemColor(RGBA32&amp; color, const String&amp;, Document*);
</span><span class="cx">     static PassRefPtr&lt;CSSValueList&gt; parseFontFaceValue(const AtomicString&amp;);
</span><span class="cx">     PassRefPtr&lt;CSSPrimitiveValue&gt; parseValidPrimitive(CSSValueID ident, ValueWithCalculation&amp;);
</span><ins>+
</ins><span class="cx">     WEBCORE_EXPORT bool parseDeclaration(MutableStyleProperties*, const String&amp;, PassRefPtr&lt;CSSRuleSourceData&gt;, StyleSheetContents* contextStyleSheet);
</span><span class="cx">     static Ref&lt;ImmutableStyleProperties&gt; parseInlineStyleDeclaration(const String&amp;, Element*);
</span><span class="cx">     std::unique_ptr&lt;MediaQuery&gt; parseMediaQuery(const String&amp;);
</span><span class="lines">@@ -549,7 +557,7 @@
</span><span class="cx">     bool isGeneratedImageValue(CSSParserValue&amp;) const;
</span><span class="cx">     bool parseGeneratedImage(CSSParserValueList&amp;, RefPtr&lt;CSSValue&gt;&amp;);
</span><span class="cx"> 
</span><del>-    bool parseValue(MutableStyleProperties*, CSSPropertyID, const String&amp;, bool important, StyleSheetContents* contextStyleSheet);
</del><ins>+    ParseResult parseValue(MutableStyleProperties*, CSSPropertyID, const String&amp;, bool important, StyleSheetContents* contextStyleSheet);
</ins><span class="cx">     Ref&lt;ImmutableStyleProperties&gt; parseDeclaration(const String&amp;, StyleSheetContents* contextStyleSheet);
</span><span class="cx"> 
</span><span class="cx">     PassRefPtr&lt;CSSBasicShape&gt; parseInsetRoundedCorners(PassRefPtr&lt;CSSBasicShapeInset&gt;, CSSParserValueList&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSPropertyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSProperty.h (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSProperty.h        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/css/CSSProperty.h        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -44,6 +44,16 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     CSSPropertyID shorthandID() const;
</span><ins>+    
+    bool operator==(const StylePropertyMetadata&amp; other) const
+    {
+        return m_propertyID == other.m_propertyID
+            &amp;&amp; m_isSetFromShorthand == other.m_isSetFromShorthand
+            &amp;&amp; m_indexInShorthandsVector == other.m_indexInShorthandsVector
+            &amp;&amp; m_important == other.m_important
+            &amp;&amp; m_implicit == other.m_implicit
+            &amp;&amp; m_inherited == other.m_inherited;
+    }
</ins><span class="cx"> 
</span><span class="cx">     uint16_t m_propertyID : 10;
</span><span class="cx">     uint16_t m_isSetFromShorthand : 1;
</span><span class="lines">@@ -76,6 +86,20 @@
</span><span class="cx"> 
</span><span class="cx">     const StylePropertyMetadata&amp; metadata() const { return m_metadata; }
</span><span class="cx"> 
</span><ins>+    bool operator==(const CSSProperty&amp; other) const
+    {
+        if (!(m_metadata == other.m_metadata))
+            return false;
+
+        if (!m_value &amp;&amp; !other.m_value)
+            return true;
+
+        if (!m_value || !other.m_value)
+            return false;
+        
+        return m_value-&gt;equals(*other.m_value);
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     StylePropertyMetadata m_metadata;
</span><span class="cx">     RefPtr&lt;CSSValue&gt; m_value;
</span></span></pre></div>
<a id="trunkSourceWebCorecssDOMWindowCSScpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/DOMWindowCSS.cpp (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/DOMWindowCSS.cpp        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/css/DOMWindowCSS.cpp        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;MutableStyleProperties&gt; dummyStyle = MutableStyleProperties::create();
</span><del>-    return CSSParser::parseValue(dummyStyle.get(), propertyID, normalizedValue, false, CSSStrictMode, 0);
</del><ins>+    return CSSParser::parseValue(dummyStyle.get(), propertyID, normalizedValue, false, CSSStrictMode, nullptr) != CSSParser::ParseResult::Error;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool DOMWindowCSS::supports(const String&amp; conditionText) const
</span></span></pre></div>
<a id="trunkSourceWebCorecssFontLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/FontLoader.cpp (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/FontLoader.cpp        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/css/FontLoader.cpp        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -295,7 +295,7 @@
</span><span class="cx"> {
</span><span class="cx">     // Interpret fontString in the same way as the 'font' attribute of CanvasRenderingContext2D.
</span><span class="cx">     RefPtr&lt;MutableStyleProperties&gt; parsedStyle = MutableStyleProperties::create();
</span><del>-    CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, CSSStrictMode, 0);
</del><ins>+    CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, CSSStrictMode, nullptr);
</ins><span class="cx">     if (parsedStyle-&gt;isEmpty())
</span><span class="cx">         return false;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCorecssStylePropertiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleProperties.cpp (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleProperties.cpp        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/css/StyleProperties.cpp        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -681,7 +681,7 @@
</span><span class="cx"> 
</span><span class="cx">     // When replacing an existing property value, this moves the property to the end of the list.
</span><span class="cx">     // Firefox preserves the position, and MSIE moves the property to the beginning.
</span><del>-    return CSSParser::parseValue(this, propertyID, value, important, cssParserMode(), contextStyleSheet);
</del><ins>+    return CSSParser::parseValue(this, propertyID, value, important, cssParserMode(), contextStyleSheet) == CSSParser::ParseResult::Changed;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MutableStyleProperties::setProperty(CSSPropertyID propertyID, PassRefPtr&lt;CSSValue&gt; prpValue, bool important)
</span><span class="lines">@@ -699,17 +699,21 @@
</span><span class="cx">         m_propertyVector.append(CSSProperty(shorthand.properties()[i], value, important));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MutableStyleProperties::setProperty(const CSSProperty&amp; property, CSSProperty* slot)
</del><ins>+bool MutableStyleProperties::setProperty(const CSSProperty&amp; property, CSSProperty* slot)
</ins><span class="cx"> {
</span><span class="cx">     if (!removeShorthandProperty(property.id())) {
</span><span class="cx">         CSSProperty* toReplace = slot ? slot : findCSSPropertyWithID(property.id());
</span><span class="cx">         if (toReplace) {
</span><ins>+            if (*toReplace == property)
+                return false;
+
</ins><span class="cx">             *toReplace = property;
</span><span class="cx">             setPrefixingVariantProperty(property);
</span><del>-            return;
</del><ins>+            return true;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><del>-    appendPrefixingVariantProperty(property);
</del><ins>+
+    return appendPrefixingVariantProperty(property);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static unsigned getIndexInShorthandVectorForPrefixingVariant(const CSSProperty&amp; property, CSSPropertyID prefixingVariant)
</span><span class="lines">@@ -721,14 +725,15 @@
</span><span class="cx">     return indexOfShorthandForLonghand(prefixedShorthand, matchingShorthandsForLonghand(prefixingVariant));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MutableStyleProperties::appendPrefixingVariantProperty(const CSSProperty&amp; property)
</del><ins>+bool MutableStyleProperties::appendPrefixingVariantProperty(const CSSProperty&amp; property)
</ins><span class="cx"> {
</span><span class="cx">     m_propertyVector.append(property);
</span><span class="cx">     CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(property.id());
</span><span class="cx">     if (prefixingVariant == property.id())
</span><del>-        return;
</del><ins>+        return true;
</ins><span class="cx"> 
</span><span class="cx">     m_propertyVector.append(CSSProperty(prefixingVariant, property.value(), property.isImportant(), property.isSetFromShorthand(), getIndexInShorthandVectorForPrefixingVariant(property, prefixingVariant), property.metadata().m_implicit));
</span><ins>+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MutableStyleProperties::setPrefixingVariantProperty(const CSSProperty&amp; property)
</span><span class="lines">@@ -741,14 +746,12 @@
</span><span class="cx"> 
</span><span class="cx"> bool MutableStyleProperties::setProperty(CSSPropertyID propertyID, CSSValueID identifier, bool important)
</span><span class="cx"> {
</span><del>-    setProperty(CSSProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important));
-    return true;
</del><ins>+    return setProperty(CSSProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool MutableStyleProperties::setProperty(CSSPropertyID propertyID, CSSPropertyID identifier, bool important)
</span><span class="cx"> {
</span><del>-    setProperty(CSSProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important));
-    return true;
</del><ins>+    return setProperty(CSSProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MutableStyleProperties::parseDeclaration(const String&amp; styleDeclaration, StyleSheetContents* contextStyleSheet)
</span><span class="lines">@@ -764,18 +767,25 @@
</span><span class="cx">     parser.parseDeclaration(this, styleDeclaration, 0, contextStyleSheet);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MutableStyleProperties::addParsedProperties(const Vector&lt;CSSProperty&gt;&amp; properties)
</del><ins>+bool MutableStyleProperties::addParsedProperties(const Vector&lt;CSSProperty&gt;&amp; properties)
</ins><span class="cx"> {
</span><ins>+    bool anyChanged = false;
</ins><span class="cx">     m_propertyVector.reserveCapacity(m_propertyVector.size() + properties.size());
</span><del>-    for (unsigned i = 0; i &lt; properties.size(); ++i)
-        addParsedProperty(properties[i]);
</del><ins>+    for (unsigned i = 0; i &lt; properties.size(); ++i) {
+        if (addParsedProperty(properties[i]))
+            anyChanged = true;
+    }
+
+    return anyChanged;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MutableStyleProperties::addParsedProperty(const CSSProperty&amp; property)
</del><ins>+bool MutableStyleProperties::addParsedProperty(const CSSProperty&amp; property)
</ins><span class="cx"> {
</span><span class="cx">     // Only add properties that have no !important counterpart present
</span><span class="cx">     if (!propertyIsImportant(property.id()) || property.isImportant())
</span><del>-        setProperty(property);
</del><ins>+        return setProperty(property);
+    
+    return false;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String StyleProperties::asText() const
</span></span></pre></div>
<a id="trunkSourceWebCorecssStylePropertiesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleProperties.h (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleProperties.h        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/css/StyleProperties.h        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -193,8 +193,8 @@
</span><span class="cx"> 
</span><span class="cx">     PropertySetCSSStyleDeclaration* cssStyleDeclaration();
</span><span class="cx"> 
</span><del>-    void addParsedProperties(const Vector&lt;CSSProperty&gt;&amp;);
-    void addParsedProperty(const CSSProperty&amp;);
</del><ins>+    bool addParsedProperties(const Vector&lt;CSSProperty&gt;&amp;);
+    bool addParsedProperty(const CSSProperty&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // These expand shorthand properties into multiple properties.
</span><span class="cx">     bool setProperty(CSSPropertyID, const String&amp; value, bool important = false, StyleSheetContents* contextStyleSheet = 0);
</span><span class="lines">@@ -203,11 +203,11 @@
</span><span class="cx">     // These do not. FIXME: This is too messy, we can do better.
</span><span class="cx">     bool setProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
</span><span class="cx">     bool setProperty(CSSPropertyID, CSSPropertyID identifier, bool important = false);
</span><del>-    void appendPrefixingVariantProperty(const CSSProperty&amp;);
</del><ins>+    bool appendPrefixingVariantProperty(const CSSProperty&amp;);
</ins><span class="cx">     void setPrefixingVariantProperty(const CSSProperty&amp;);
</span><del>-    void setProperty(const CSSProperty&amp;, CSSProperty* slot = 0);
</del><ins>+    bool setProperty(const CSSProperty&amp;, CSSProperty* slot = nullptr);
</ins><span class="cx"> 
</span><del>-    bool removeProperty(CSSPropertyID, String* returnText = 0);
</del><ins>+    bool removeProperty(CSSPropertyID, String* returnText = nullptr);
</ins><span class="cx">     void removePrefixedOrUnprefixedProperty(CSSPropertyID);
</span><span class="cx">     void removeBlockProperties();
</span><span class="cx">     bool removePropertiesInSet(const CSSPropertyID* set, unsigned length);
</span></span></pre></div>
<a id="trunkSourceWebCorecssWebKitCSSMatrixcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/WebKitCSSMatrix.cpp (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/WebKitCSSMatrix.cpp        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/css/WebKitCSSMatrix.cpp        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;MutableStyleProperties&gt; styleDeclaration = MutableStyleProperties::create();
</span><del>-    if (CSSParser::parseValue(styleDeclaration.get(), CSSPropertyTransform, string, true, CSSStrictMode, 0)) {
</del><ins>+    if (CSSParser::parseValue(styleDeclaration.get(), CSSPropertyTransform, string, true, CSSStrictMode, nullptr) != CSSParser::ParseResult::Error) {
</ins><span class="cx">         // Convert to TransformOperations. This can fail if a property
</span><span class="cx">         // requires style (i.e., param uses 'ems' or 'exs')
</span><span class="cx">         RefPtr&lt;CSSValue&gt; value = styleDeclaration-&gt;getPropertyCSSValue(CSSPropertyTransform);
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/dom/Document.cpp        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -1790,6 +1790,8 @@
</span><span class="cx">         m_closeAfterStyleRecalc = false;
</span><span class="cx">         implicitClose();
</span><span class="cx">     }
</span><ins>+    
+    ++m_styleRecalcCount;
</ins><span class="cx"> 
</span><span class="cx">     InspectorInstrumentation::didRecalculateStyle(cookie);
</span><span class="cx"> 
</span><span class="lines">@@ -6139,6 +6141,16 @@
</span><span class="cx">     m_lastHandledUserGestureTimestamp = monotonicallyIncreasingTime();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Document::startTrackingStyleRecalcs()
+{
+    m_styleRecalcCount = 0;
+}
+
+unsigned Document::styleRecalcCount() const
+{
+    return m_styleRecalcCount;
+}
+
</ins><span class="cx"> DocumentLoader* Document::loader() const
</span><span class="cx"> {
</span><span class="cx">     if (!m_frame)
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.h (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.h        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/dom/Document.h        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -1141,6 +1141,9 @@
</span><span class="cx">     WEBCORE_EXPORT unsigned wheelEventHandlerCount() const;
</span><span class="cx">     WEBCORE_EXPORT unsigned touchEventHandlerCount() const;
</span><span class="cx"> 
</span><ins>+    WEBCORE_EXPORT void startTrackingStyleRecalcs();
+    WEBCORE_EXPORT unsigned styleRecalcCount() const;
+
</ins><span class="cx">     void didAddTouchEventHandler(Node&amp;);
</span><span class="cx">     void didRemoveTouchEventHandler(Node&amp;, EventHandlerRemoval = EventHandlerRemoval::One);
</span><span class="cx"> 
</span><span class="lines">@@ -1440,6 +1443,8 @@
</span><span class="cx">     // http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter
</span><span class="cx">     unsigned m_ignoreDestructiveWriteCount;
</span><span class="cx"> 
</span><ins>+    unsigned m_styleRecalcCount { 0 };
+
</ins><span class="cx">     StringWithDirection m_title;
</span><span class="cx">     StringWithDirection m_rawTitle;
</span><span class="cx">     bool m_titleSetExplicitly;
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasCanvasRenderingContext2Dcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -2075,7 +2075,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;MutableStyleProperties&gt; parsedStyle = MutableStyleProperties::create();
</span><del>-    CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, newFont, true, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode), 0);
</del><ins>+    CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, newFont, true, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode), nullptr);
</ins><span class="cx">     if (parsedStyle-&gt;isEmpty())
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/testing/Internals.cpp        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -2089,6 +2089,27 @@
</span><span class="cx">     return document-&gt;renderView()-&gt;compositor().layerFlushCount();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Internals::startTrackingStyleRecalcs(ExceptionCode&amp; ec)
+{
+    Document* document = contextDocument();
+    if (!document) {
+        ec = INVALID_ACCESS_ERR;
+        return;
+    }
+    document-&gt;startTrackingStyleRecalcs();
+}
+
+unsigned long Internals::styleRecalcCount(ExceptionCode&amp; ec)
+{
+    Document* document = contextDocument();
+    if (!document) {
+        ec = INVALID_ACCESS_ERR;
+        return 0;
+    }
+    
+    return document-&gt;styleRecalcCount();
+}
+
</ins><span class="cx"> void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionCode&amp; ec)
</span><span class="cx"> {
</span><span class="cx">     updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(nullptr, ec);
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.h (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.h        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/testing/Internals.h        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -298,6 +298,9 @@
</span><span class="cx">     void startTrackingLayerFlushes(ExceptionCode&amp;);
</span><span class="cx">     unsigned long layerFlushCount(ExceptionCode&amp;);
</span><span class="cx">     
</span><ins>+    void startTrackingStyleRecalcs(ExceptionCode&amp;);
+    unsigned long styleRecalcCount(ExceptionCode&amp;);
+
</ins><span class="cx">     void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionCode&amp;);
</span><span class="cx">     void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node*, ExceptionCode&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.idl (183016 => 183017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.idl        2015-04-20 17:14:33 UTC (rev 183016)
+++ trunk/Source/WebCore/testing/Internals.idl        2015-04-20 18:31:45 UTC (rev 183017)
</span><span class="lines">@@ -277,6 +277,9 @@
</span><span class="cx">     // Query if a timer is currently throttled, to debug timer throttling.
</span><span class="cx">     [RaisesException] boolean isTimerThrottled(long timerHandle);
</span><span class="cx"> 
</span><ins>+    [RaisesException] void startTrackingStyleRecalcs();
+    [RaisesException] unsigned long styleRecalcCount();
+
</ins><span class="cx">     // |node| should be Document, HTMLIFrameElement, or unspecified.
</span><span class="cx">     // If |node| is an HTMLIFrameElement, it assumes node.contentDocument is
</span><span class="cx">     // specified without security checks. Unspecified means this document.
</span></span></pre>
</div>
</div>

</body>
</html>