<!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>[128291] 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/128291">128291</a></dd>
<dt>Author</dt> <dd>apavlov@chromium.org</dd>
<dt>Date</dt> <dd>2012-09-12 04:36:15 -0700 (Wed, 12 Sep 2012)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: [Elements] Sidebar panes not updated on style changes due to &quot;class&quot; attribute modifications
https://bugs.webkit.org/show_bug.cgi?id=95722

Reviewed by Vsevolod Vlasov.

Source/WebCore:

The DOMAgent StyleInvalidated event has been removed in favor of the StylesSidebarPane explicitly listening on the
AttrModified/AttrRemoved events that result in those same updates.

* inspector/front-end/DOMAgent.js:
(WebInspector.DOMAgent.prototype._attributeModified):
(WebInspector.DOMAgent.prototype._loadNodeAttributes):
(WebInspector.DOMAgent.prototype._childNodeRemoved):
* inspector/front-end/ElementsTreeOutline.js:
(WebInspector.ElementsTreeElement.prototype.updateSelection): Drive-by: avoid a costly synchronous layout during DOM tree updates.
* inspector/front-end/StylesSidebarPane.js:
(WebInspector.StylesSidebarPane):
(WebInspector.StylesSidebarPane.prototype._attributeChanged):
(WebInspector.StylesSidebarPane.prototype._canAffectCurrentStyles):

LayoutTests:

* inspector/elements/edit-style-attribute.html: Renamed events on which to listen.
* inspector/styles/override-screen-size.html: Drive-by: fixed race condition that was resulting in this test's failures.
* inspector/styles/styles-update-from-js-expected.txt:
* inspector/styles/styles-update-from-js.html: Added test cases for style updates on ancestor and sibling attributes' changes.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsinspectorelementseditstyleattributeexpectedtxt">trunk/LayoutTests/inspector/elements/edit-style-attribute-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorelementseditstyleattributehtml">trunk/LayoutTests/inspector/elements/edit-style-attribute.html</a></li>
<li><a href="#trunkLayoutTestsinspectorstylesoverridescreensizehtml">trunk/LayoutTests/inspector/styles/override-screen-size.html</a></li>
<li><a href="#trunkLayoutTestsinspectorstylesstylesupdatefromjsexpectedtxt">trunk/LayoutTests/inspector/styles/styles-update-from-js-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorstylesstylesupdatefromjshtml">trunk/LayoutTests/inspector/styles/styles-update-from-js.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreinspectorfrontendDOMAgentjs">trunk/Source/WebCore/inspector/front-end/DOMAgent.js</a></li>
<li><a href="#trunkSourceWebCoreinspectorfrontendElementsTreeOutlinejs">trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js</a></li>
<li><a href="#trunkSourceWebCoreinspectorfrontendStylesSidebarPanejs">trunk/Source/WebCore/inspector/front-end/StylesSidebarPane.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/LayoutTests/ChangeLog        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2012-09-12  Alexander Pavlov  &lt;apavlov@chromium.org&gt;
+
+        Web Inspector: [Elements] Sidebar panes not updated on style changes due to &quot;class&quot; attribute modifications
+        https://bugs.webkit.org/show_bug.cgi?id=95722
+
+        Reviewed by Vsevolod Vlasov.
+
+        * inspector/elements/edit-style-attribute.html: Renamed events on which to listen.
+        * inspector/styles/override-screen-size.html: Drive-by: fixed race condition that was resulting in this test's failures.
+        * inspector/styles/styles-update-from-js-expected.txt:
+        * inspector/styles/styles-update-from-js.html: Added test cases for style updates on ancestor and sibling attributes' changes.
+
</ins><span class="cx"> 2012-09-12  Csaba Osztrogonác  &lt;ossy@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [Qt][WK2] Unreviewed gardening, skip a new failing test to paint the bot green.
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorelementseditstyleattributeexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/elements/edit-style-attribute-expected.txt (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/elements/edit-style-attribute-expected.txt        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/LayoutTests/inspector/elements/edit-style-attribute-expected.txt        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -4,7 +4,7 @@
</span><span class="cx"> Running: testSetUp
</span><span class="cx"> 
</span><span class="cx"> Running: testSetNewValue
</span><del>-WebInspector.DOMAgent.Events.StyleInvalidated should be issued
</del><ins>+WebInspector.DOMAgent.Events.AttrModified should be issued
</ins><span class="cx"> 
</span><span class="cx"> Running: testSetSameValue
</span><span class="cx"> WebInspector.DOMNode.prototype._setAttributesPayload should be called
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorelementseditstyleattributehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/elements/edit-style-attribute.html (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/elements/edit-style-attribute.html        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/LayoutTests/inspector/elements/edit-style-attribute.html        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -31,11 +31,11 @@
</span><span class="cx">         {
</span><span class="cx">             InspectorTest.evaluateInPage(&quot;testSetNewValue()&quot;);
</span><span class="cx"> 
</span><del>-            WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.StyleInvalidated, listener);
</del><ins>+            WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, listener);
</ins><span class="cx">             function listener(event)
</span><span class="cx">             {
</span><del>-                InspectorTest.addResult(&quot;WebInspector.DOMAgent.Events.StyleInvalidated should be issued&quot;);
-                WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.StyleInvalidated, listener);
</del><ins>+                InspectorTest.addResult(&quot;WebInspector.DOMAgent.Events.AttrModified should be issued&quot;);
+                WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.AttrModified, listener);
</ins><span class="cx">                 next();
</span><span class="cx">             }
</span><span class="cx">         },
</span><span class="lines">@@ -44,18 +44,18 @@
</span><span class="cx">         {
</span><span class="cx">             InspectorTest.evaluateInPage(&quot;testSetSameValue()&quot;);
</span><span class="cx"> 
</span><del>-            WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.StyleInvalidated, listener);
</del><ins>+            WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, listener);
</ins><span class="cx">             function listener(event)
</span><span class="cx">             {
</span><del>-                InspectorTest.addResult(&quot;WebInspector.DOMAgent.Events.StyleInvalidated should not be issued&quot;);
-                WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.StyleInvalidated, listener);
</del><ins>+                InspectorTest.addResult(&quot;WebInspector.DOMAgent.Events.AttrModified should not be issued&quot;);
+                WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.AttrModified, listener);
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             InspectorTest.addSniffer(WebInspector.DOMNode.prototype, &quot;_setAttributesPayload&quot;, callback);
</span><span class="cx">             function callback()
</span><span class="cx">             {
</span><span class="cx">                 InspectorTest.addResult(&quot;WebInspector.DOMNode.prototype._setAttributesPayload should be called&quot;);
</span><del>-                WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.StyleInvalidated, listener);
</del><ins>+                WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.AttrModified, listener);
</ins><span class="cx">                 next();
</span><span class="cx">             }
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorstylesoverridescreensizehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/styles/override-screen-size.html (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/styles/override-screen-size.html        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/LayoutTests/inspector/styles/override-screen-size.html        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -158,19 +158,36 @@
</span><span class="cx"> 
</span><span class="cx">     function overrideAndDumpData(width, height, callback)
</span><span class="cx">     {
</span><del>-        function selectCallback()
</del><ins>+        function finalCallback()
</ins><span class="cx">         {
</span><span class="cx">             InspectorTest.addResult(&quot;Main style:&quot;);
</span><span class="cx">             InspectorTest.dumpSelectedElementStyles(true, false, true);
</span><span class="cx">             callback();
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        var gotSizes;
+        var gotStyles;
+        function stylesCallback()
+        {
+            if (gotSizes)
+                return finalCallback();
+            gotStyles = true;
+        }
+
+        function sizesCallback()
+        {
+            gotSizes = true;
+            if (gotStyles)
+                finalCallback();
+        }
+
</ins><span class="cx">         function applyCallback()
</span><span class="cx">         {
</span><del>-            getAndDumpSizes(selectCallback);
</del><ins>+            getAndDumpSizes(sizesCallback);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         InspectorTest.addResult(&quot;Override: &quot; + width + &quot;x&quot; + height);
</span><ins>+        InspectorTest.waitForStyles(&quot;main&quot;, stylesCallback);
</ins><span class="cx">         applyOverride(width, height, applyCallback);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -182,7 +199,8 @@
</span><span class="cx">             InspectorTest.addResult(&quot;Screen from page: &quot; + result.screen);
</span><span class="cx">             InspectorTest.addResult(&quot;Window from page: &quot; + result.inner);
</span><span class="cx">             InspectorTest.addResult(&quot;Body from page: &quot; + result.body);
</span><del>-            callback();
</del><ins>+            if (callback)
+                callback();
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         InspectorTest.evaluateInPage(&quot;getSizes()&quot;, getSizesCallback);
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorstylesstylesupdatefromjsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/styles/styles-update-from-js-expected.txt (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/styles/styles-update-from-js-expected.txt        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/LayoutTests/inspector/styles/styles-update-from-js-expected.txt        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -1,10 +1,10 @@
</span><del>-Tests that changes to an inline style from JavaScript are reflected in the Styles pane and Elements tree.
</del><ins>+Tests that changes to an inline style and ancestor/sibling className from JavaScript are reflected in the Styles pane and Elements tree.
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> Running: testInit
</span><span class="cx"> 
</span><span class="cx"> Running: testSetStyleAttribute
</span><del>-&lt;div id=&quot;container&quot; style=&quot;color: #daC0DE; border: 1px solid black;&quot;&gt;&lt;/div&gt;
</del><ins>+&lt;div id=&quot;container&quot; style=&quot;color: #daC0DE; border: 1px solid black;&quot;&gt;…&lt;/div&gt;
</ins><span class="cx"> [expanded] 
</span><span class="cx"> element.style  { ()
</span><span class="cx"> color: #DAC0DE;
</span><span class="lines">@@ -22,18 +22,28 @@
</span><span class="cx">     border-left-style: solid;
</span><span class="cx">     border-left-width: 1px;
</span><span class="cx"> 
</span><ins>+======== Matched CSS Rules ========
+[expanded] 
+div  { (user agent stylesheet)
+display: block;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> Running: testSetStyleCSSText
</span><del>-&lt;div id=&quot;container&quot; style=&quot;color: rgb(192, 255, 238);&quot;&gt;&lt;/div&gt;
</del><ins>+&lt;div id=&quot;container&quot; style=&quot;color: rgb(192, 255, 238);&quot;&gt;…&lt;/div&gt;
</ins><span class="cx"> [expanded] 
</span><span class="cx"> element.style  { ()
</span><span class="cx"> color: #C0FFEE;
</span><span class="cx"> 
</span><ins>+======== Matched CSS Rules ========
+[expanded] 
+div  { (user agent stylesheet)
+display: block;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> Running: testSetViaParsedAttributes
</span><del>-&lt;div id=&quot;container&quot; style=&quot;color: rgb(192, 255, 238); border: 3px dashed green;&quot;&gt;&lt;/div&gt;
</del><ins>+&lt;div id=&quot;container&quot; style=&quot;color: rgb(192, 255, 238); border: 3px dashed green;&quot;&gt;…&lt;/div&gt;
</ins><span class="cx"> [expanded] 
</span><span class="cx"> element.style  { ()
</span><span class="cx"> color: #C0FFEE;
</span><span class="lines">@@ -51,5 +61,52 @@
</span><span class="cx">     border-left-style: dashed;
</span><span class="cx">     border-left-width: 3px;
</span><span class="cx"> 
</span><ins>+======== Matched CSS Rules ========
+[expanded] 
+div  { (user agent stylesheet)
+display: block;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
+Running: testSetViaAncestorClass
+&lt;div id=&quot;child&quot;&gt;&lt;/div&gt;
+[expanded] 
+element.style  { ()
+
+======== Matched CSS Rules ========
+[expanded] 
+.red div:first-child  { (styles-update-from-js.html:4)
+background-color: red;
+
+[expanded] 
+div  { (user agent stylesheet)
+display: block;
+
+======== Inherited from div#container.red ========
+[expanded] 
+Style Attribute  { ()
+color: #C0FFEE;
+
+
+
+Running: testSetViaSiblingAttr
+&lt;div id=&quot;childSibling&quot;&gt;&lt;/div&gt;
+[expanded] 
+element.style  { ()
+
+======== Matched CSS Rules ========
+[expanded] 
+div[foo=&quot;bar&quot;] + div  { (styles-update-from-js.html:8)
+background-color: blue;
+
+[expanded] 
+div  { (user agent stylesheet)
+display: block;
+
+======== Inherited from div#container.red ========
+[expanded] 
+Style Attribute  { ()
+color: #C0FFEE;
+
+
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorstylesstylesupdatefromjshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/styles/styles-update-from-js.html (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/styles/styles-update-from-js.html        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/LayoutTests/inspector/styles/styles-update-from-js.html        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -1,5 +1,15 @@
</span><span class="cx"> &lt;html&gt;
</span><span class="cx"> &lt;head&gt;
</span><ins>+&lt;style&gt;
+.red div:first-child {
+    background-color: red;
+}
+
+div[foo=&quot;bar&quot;] + div {
+    background-color: blue;
+}
+
+&lt;/style&gt;
</ins><span class="cx"> &lt;script src=&quot;../../http/tests/inspector/inspector-test.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> &lt;script src=&quot;../../http/tests/inspector/elements-test.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> &lt;script&gt;
</span><span class="lines">@@ -20,6 +30,16 @@
</span><span class="cx">     style.borderWidth = &quot;3px&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function modifyContainerClass()
+{
+    document.getElementById(&quot;container&quot;).className = &quot;red&quot;;
+}
+
+function modifyChildAttr()
+{
+    document.getElementById(&quot;child&quot;).setAttribute(&quot;foo&quot;, &quot;bar&quot;);
+}
+
</ins><span class="cx"> function test()
</span><span class="cx"> {
</span><span class="cx">     InspectorTest.runTestSuite([
</span><span class="lines">@@ -44,36 +64,59 @@
</span><span class="cx">         {
</span><span class="cx">             waitAndDumpAttributeAndStyles(next);
</span><span class="cx">             InspectorTest.evaluateInPage(&quot;modifyParsedAttributes()&quot;);
</span><ins>+        },
+
+        function testSetViaAncestorClass(next)
+        {
+            InspectorTest.selectNodeAndWaitForStyles(&quot;child&quot;, callback);
+
+            function callback()
+            {
+                waitAndDumpAttributeAndStyles(next, &quot;child&quot;);
+                InspectorTest.evaluateInPage(&quot;modifyContainerClass()&quot;);
+            }
+        },
+
+        function testSetViaSiblingAttr(next)
+        {
+            InspectorTest.selectNodeAndWaitForStyles(&quot;childSibling&quot;, callback);
+
+            function callback()
+            {
+                waitAndDumpAttributeAndStyles(next, &quot;childSibling&quot;);
+                InspectorTest.evaluateInPage(&quot;modifyChildAttr()&quot;);
+            }
</ins><span class="cx">         }
</span><span class="cx">     ]);
</span><span class="cx"> 
</span><del>-    function waitAndDumpAttributeAndStyles(next)
</del><ins>+    function waitAndDumpAttributeAndStyles(next, id)
</ins><span class="cx">     {
</span><ins>+        id = id || &quot;container&quot;;
</ins><span class="cx">         function callback()
</span><span class="cx">         {
</span><del>-            dumpAttributeAndStyles();
</del><ins>+            dumpAttributeAndStyles(id);
</ins><span class="cx">             next();
</span><span class="cx">         }
</span><del>-        InspectorTest.waitForStyles(&quot;container&quot;, callback);
</del><ins>+        InspectorTest.waitForStyles(id, callback);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    function dumpAttributeAndStyles()
</del><ins>+    function dumpAttributeAndStyles(id)
</ins><span class="cx">     {
</span><del>-        var treeElement = findNodeTreeElement()
</del><ins>+        var treeElement = findNodeTreeElement(id);
</ins><span class="cx">         if (!treeElement) {
</span><del>-            InspectorTest.addResult(&quot;'container' tree element not found&quot;);
</del><ins>+            InspectorTest.addResult(&quot;'&quot; + id + &quot;' tree element not found&quot;);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         InspectorTest.addResult(treeElement.listItemElement.textContent.replace(/\u200b/g, &quot;&quot;));
</span><del>-        InspectorTest.dumpSelectedElementStyles(true, true);
</del><ins>+        InspectorTest.dumpSelectedElementStyles(true);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    function findNodeTreeElement()
</del><ins>+    function findNodeTreeElement(id)
</ins><span class="cx">     {
</span><span class="cx">         WebInspector.panels.elements.treeOutline._updateModifiedNodes();
</span><del>-        var expandedNode = InspectorTest.expandedNodeWithId(&quot;container&quot;);
</del><ins>+        var expandedNode = InspectorTest.expandedNodeWithId(id);
</ins><span class="cx">         if (!expandedNode) {
</span><del>-            InspectorTest.addResult(&quot;'container' node not found&quot;);
</del><ins>+            InspectorTest.addResult(&quot;'&quot; + id + &quot;' node not found&quot;);
</ins><span class="cx">             InspectorTest.completeTest();
</span><span class="cx">         }
</span><span class="cx">         return WebInspector.panels.elements.treeOutline.findTreeElement(expandedNode);
</span><span class="lines">@@ -84,10 +127,10 @@
</span><span class="cx"> 
</span><span class="cx"> &lt;body onload=&quot;runTest()&quot;&gt;
</span><span class="cx"> &lt;p&gt;
</span><del>-Tests that changes to an inline style from JavaScript are reflected in the Styles pane and Elements tree.
</del><ins>+Tests that changes to an inline style and ancestor/sibling className from JavaScript are reflected in the Styles pane and Elements tree.
</ins><span class="cx"> &lt;/p&gt;
</span><span class="cx"> 
</span><del>-&lt;div id=&quot;container&quot; style=&quot;font-weight:bold&quot;&gt;&lt;/div&gt;
</del><ins>+&lt;div id=&quot;container&quot; style=&quot;font-weight:bold&quot;&gt;&lt;div id=&quot;child&quot;&gt;&lt;/div&gt;&lt;div id=&quot;childSibling&quot;&gt;&lt;/div&gt;&lt;/div&gt;
</ins><span class="cx"> 
</span><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/Source/WebCore/ChangeLog        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2012-09-12  Alexander Pavlov  &lt;apavlov@chromium.org&gt;
+
+        Web Inspector: [Elements] Sidebar panes not updated on style changes due to &quot;class&quot; attribute modifications
+        https://bugs.webkit.org/show_bug.cgi?id=95722
+
+        Reviewed by Vsevolod Vlasov.
+
+        The DOMAgent StyleInvalidated event has been removed in favor of the StylesSidebarPane explicitly listening on the
+        AttrModified/AttrRemoved events that result in those same updates.
+
+        * inspector/front-end/DOMAgent.js:
+        (WebInspector.DOMAgent.prototype._attributeModified):
+        (WebInspector.DOMAgent.prototype._loadNodeAttributes):
+        (WebInspector.DOMAgent.prototype._childNodeRemoved):
+        * inspector/front-end/ElementsTreeOutline.js:
+        (WebInspector.ElementsTreeElement.prototype.updateSelection): Drive-by: avoid a costly synchronous layout during DOM tree updates.
+        * inspector/front-end/StylesSidebarPane.js:
+        (WebInspector.StylesSidebarPane):
+        (WebInspector.StylesSidebarPane.prototype._attributeChanged):
+        (WebInspector.StylesSidebarPane.prototype._canAffectCurrentStyles):
+
</ins><span class="cx"> 2012-09-12  Simon Hausmann  &lt;simon.hausmann@nokia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Build with ENABLE_REQUEST_ANIMATION_FRAME=0 is broken
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorfrontendDOMAgentjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/front-end/DOMAgent.js (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/front-end/DOMAgent.js        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/Source/WebCore/inspector/front-end/DOMAgent.js        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -794,7 +794,6 @@
</span><span class="cx">     DocumentUpdated: &quot;DocumentUpdated&quot;,
</span><span class="cx">     ChildNodeCountUpdated: &quot;ChildNodeCountUpdated&quot;,
</span><span class="cx">     InspectElementRequested: &quot;InspectElementRequested&quot;,
</span><del>-    StyleInvalidated: &quot;StyleInvalidated&quot;,
</del><span class="cx">     UndoRedoRequested: &quot;UndoRedoRequested&quot;,
</span><span class="cx">     UndoRedoCompleted: &quot;UndoRedoCompleted&quot;
</span><span class="cx"> }
</span><span class="lines">@@ -916,12 +915,9 @@
</span><span class="cx">         var node = this._idToDOMNode[nodeId];
</span><span class="cx">         if (!node)
</span><span class="cx">             return;
</span><del>-        var issueStyleInvalidated = name === &quot;style&quot; &amp;&amp; value !== node.getAttribute(&quot;style&quot;);
</del><span class="cx"> 
</span><span class="cx">         node._setAttribute(name, value);
</span><span class="cx">         this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrModified, { node: node, name: name });
</span><del>-        if (issueStyleInvalidated)
-          this.dispatchEventToListeners(WebInspector.DOMAgent.Events.StyleInvalidated, node)
</del><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="lines">@@ -965,10 +961,8 @@
</span><span class="cx">             }
</span><span class="cx">             var node = this._idToDOMNode[nodeId];
</span><span class="cx">             if (node) {
</span><del>-                if (node._setAttributesPayload(attributes)) {
</del><ins>+                if (node._setAttributesPayload(attributes))
</ins><span class="cx">                     this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrModified, { node: node, name: &quot;style&quot; });
</span><del>-                    this.dispatchEventToListeners(WebInspector.DOMAgent.Events.StyleInvalidated, node);
-                }
</del><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1080,7 +1074,7 @@
</span><span class="cx">         var node = this._idToDOMNode[nodeId];
</span><span class="cx">         parent._removeChild(node);
</span><span class="cx">         this._unbind(node);
</span><del>-        this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node:node, parent:parent});
</del><ins>+        this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node: node, parent: parent});
</ins><span class="cx">     },
</span><span class="cx"> 
</span><span class="cx">     /**
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorfrontendElementsTreeOutlinejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -812,10 +812,14 @@
</span><span class="cx">         if (!listItemElement)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        if (document.body.offsetWidth &lt;= 0) {
-            // The stylesheet hasn't loaded yet or the window is closed,
-            // so we can't calculate what is need. Return early.
-            return;
</del><ins>+        if (!this._readyToUpdateSelection) {
+            if (document.body.offsetWidth &gt; 0)
+                this._readyToUpdateSelection = true;
+            else {
+                // The stylesheet hasn't loaded yet or the window is closed,
+                // so we can't calculate what we need. Return early.
+                return;
+            }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (!this.selectionElement) {
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorfrontendStylesSidebarPanejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/front-end/StylesSidebarPane.js (128290 => 128291)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/front-end/StylesSidebarPane.js        2012-09-12 11:34:34 UTC (rev 128290)
+++ trunk/Source/WebCore/inspector/front-end/StylesSidebarPane.js        2012-09-12 11:36:15 UTC (rev 128291)
</span><span class="lines">@@ -97,9 +97,8 @@
</span><span class="cx"> 
</span><span class="cx">     WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetOrMediaQueryResultChanged, this);
</span><span class="cx">     WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this._styleSheetOrMediaQueryResultChanged, this);
</span><del>-    WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributesModified, this);
-    WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributesRemoved, this);
-    WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.StyleInvalidated, this._styleInvalidated, this);
</del><ins>+    WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributeChanged, this);
+    WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributeChanged, this);
</ins><span class="cx">     WebInspector.settings.showUserAgentStyles.addChangeListener(this._showUserAgentStylesSettingChanged.bind(this));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -314,39 +313,24 @@
</span><span class="cx">         this._rebuildUpdate();
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    _attributesModified: function(event)
</del><ins>+    _attributeChanged: function(event)
</ins><span class="cx">     {
</span><del>-        if (this.node !== event.data.node)
</del><ins>+        // Any attribute removal or modification can affect the styles of &quot;related&quot; nodes.
+        // Do not touch the styles if they are being edited.
+        if (this._isEditingStyle || this._userOperation)
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        // Changing style attribute will anyways generate _styleInvalidated message.
-        if (event.data.name === &quot;style&quot;)
</del><ins>+        if (!this._canAffectCurrentStyles(event.data.node))
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        // &quot;class&quot; (or any other) attribute might have changed. Update styles unless they are being edited.
-        if (!this._isEditingStyle &amp;&amp; !this._userOperation)
-            this._rebuildUpdate();
</del><ins>+        this._rebuildUpdate();
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    _attributesRemoved: function(event)
</del><ins>+    _canAffectCurrentStyles: function(node)
</ins><span class="cx">     {
</span><del>-        if (this.node !== event.data.node)
-            return;
-
-        // &quot;style&quot; attribute might have been removed.
-        if (!this._isEditingStyle &amp;&amp; !this._userOperation)
-            this._rebuildUpdate();
</del><ins>+        return this.node &amp;&amp; (this.node === node || node.parentNode === this.node.parentNode || node.isAncestor(this.node));
</ins><span class="cx">     },
</span><span class="cx"> 
</span><del>-    _styleInvalidated: function(event)
-    {
-        if (this.node !== event.data)
-            return;
-
-        if (!this._isEditingStyle &amp;&amp; !this._userOperation)
-            this._rebuildUpdate();
-    },
-
</del><span class="cx">     _innerRefreshUpdate: function(node, computedStyle, editedSection)
</span><span class="cx">     {
</span><span class="cx">         for (var pseudoId in this.sections) {
</span></span></pre>
</div>
</div>

</body>
</html>