<!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>[166144] 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/166144">166144</a></dd>
<dt>Author</dt> <dd>darin@apple.com</dd>
<dt>Date</dt> <dd>2014-03-23 14:37:56 -0700 (Sun, 23 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Remove code in HTMLObjectElement attribute parsing that forces style resolution and layout
https://bugs.webkit.org/show_bug.cgi?id=130653

Reviewed by Antti Koivisto.

Source/WebCore:

* dom/ContainerNode.cpp: Moved the post-attach callback code from here to
StyleResolveTree.h/cpp.
* dom/ContainerNode.h: Ditto.

* dom/Document.cpp:
(WebCore::Document::recalcStyle): Use Style::PostResolutionCallbackDisabler instead of
PostAttachCallbackDisabler.

* dom/Element.h: Moved the post-attach callback code from here to StyleResolveTree.h/cpp.

* html/HTMLEmbedElement.cpp:
(WebCore::HTMLEmbedElement::parseAttribute): Simplified the code for typeAttr, turning
it into a 1-liner. Added a FIXME in codeAttr about the fact that it does not have the
code to trigger image loads. Changed srcAttr to call updateImageLoaderWithNewURLSoon to
do the image loading logic.

* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::didAttachRenderers): Updated to use
Style::queuePostResolutionCallback and use a lambda instead of a function.
(WebCore::HTMLFormControlElement::didRecalcStyle): Ditto. Also added RefPtr instead
of just using wishful thinking to keep the object alive.
* html/HTMLFrameOwnerElement.cpp:
(WebCore::HTMLFrameOwnerElement::scheduleSetNeedsStyleRecalc): Ditto.

* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::parseAttribute):: Simplified the code for typeAttr, turning
it into a 1-liner. Changed dataAttr to use updateImageLoaderWithNewURLSoon(). Also made
it call setNeedsWidgetUpdate(true) unconditionally after checking carefully to see that's
harmless if there is no renderer. Changed classidAttr to call setNeedsWidgetUpdate(true)
unconditionally and not set m_classId.
(WebCore::HTMLObjectElement::shouldAllowQuickTimeClassIdQuirk): Use fastGetAttribute
instead of classId and descendantsOfType instead of getElementsByTagName.
(WebCore::HTMLObjectElement::hasValidClassId): Use fastGetAttribute instead of classId.
(WebCore::HTMLObjectElement::renderFallbackContent): Use imageLoader instead of m_imageLoader.

* html/HTMLObjectElement.h: Removed classId, since there is no reason to cache that
attribute in a data member. Rearranged header, making more private, and fixing some typos,
and doing a &quot;using&quot; instead of a function to disambiguate the inherited form functions.

* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement): Initialize m_needsImageReload.
(WebCore::HTMLPlugInImageElement::createElementRenderer): Fixed some code that assumed the
first child of the shadow root is guaranteed to be an element.
(WebCore::HTMLPlugInImageElement::didRecalcStyle): Added. Calls the new
scheduleUpdateForAfterStyleResolution function.
(WebCore::HTMLPlugInImageElement::didAttachRenderers): Moved all the logic from this
function into scheduleUpdateForAfterStyleResolution. Also added a call through to the base
class; cleaner even though it's just an assertion.
(WebCore::HTMLPlugInImageElement::scheduleUpdateForAfterStyleResolution): Added.
Schedules a call to updateAfterStyleResolution when needed.
(WebCore::HTMLPlugInImageElement::updateAfterStyleResolution): Added.
Combines updateWidgetIfNecessary and startLoadingImage, and also deals with the new
m_needsImageReload boolean in cases where no actual loading is done.
(WebCore::HTMLPlugInImageElement::removedFrom): Added. Do not delay the load event of
document once this element is removed, clears m_needsImageReload.
(WebCore::HTMLPlugInImageElement::didMoveToNewDocument): Removed null check on oldDocument,
since m_needsDocumentActivationCallbacks can't be true if the old document was null.
(WebCore::is100Percent): Added helper to make function below more readable.
(WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn): Restructured the code a
bit. The part that attracted my attention was the local variable of type RenderBox, which
was named renderEmbeddedObject. Turns out the caller guarantees to only call this if there
is a renderer of type RenderEmbeddedObject, so depend on that.
(WebCore::HTMLPlugInImageElement::setNeedsImageReload): Added. When called with true, sets
the flag and triggers a style recalculation, and lets updateAfterStyleResolution do the rest.
When called with false, reverses the effects and stops delaying the load event.

* html/HTMLPlugInImageElement.h: Trimmed includes a bit. Made more members private.
Marked more function members final. Made a protected imageLoader function so that
m_imageLoader can be private. Added new protected function updateImageLoaderWithNewURLSoon,
as well as other new private functions. Made m_imageLoader be std::unique_ptr instead of
OwnPtr, and added m_needsImageReload.

* style/StyleResolveTree.cpp:
(WebCore::Style::needsPseudoElement): Fixed spelling error in the name of this function.
(WebCore::Style::attachBeforeOrAfterPseudoElementIfNeeded): Updated for name change.
(WebCore::Style::attachRenderTree): Update for new name of PostResolutionCallbackDisabler.
(WebCore::Style::updateBeforeOrAfterPseudoElement): Updated for name change.
(WebCore::Style::postResolutionCallbackQueue): Added.
(WebCore::Style::queuePostResolutionCallback): Added.
(WebCore::Style::suspendMemoryCacheClientCalls): Added. This is a side effect of the original
PostAttachCallbackDisabler that is now done in a cleaner way, using the callback queue, instead
of as a special case. It should not work for multiple documents across multiple pages instead of
only the outermost one.
(WebCore::Style::PostResolutionCallbackDisabler::PostResolutionCallbackDisabler): Added.
Calls suspendMemoryCacheClientCalls, but a FIXME tries to point out why that isn't so great.
(WebCore::Style::PostResolutionCallbackDisabler::~PostResolutionCallbackDisabler): Added.
(WebCore::Style::postResolutionCallbacksAreSuspended): Added.

* style/StyleResolveTree.h: Added queuePostResolutionCallback and
postResolutionCallbacksAreSuspended. Also added PostResolutionCallbackDisabler, which should
eventually become a private implementation detail.

Source/WebKit/mac:

* WebCoreSupport/WebFrameLoaderClient.mm: Call toHTMLPlugInImageElement instead of
doing a static_cast.

LayoutTests:

* plugins/plugin-remove-readystatechange-expected.txt: Added a blank line; not what this
test is testing, but the different timing of loads results in this blank line.
* plugins/plugin-remove-readystatechange.html: Updated test to use waitUntilDone/notifyDone
rather than racing. Added a computation of offsetLeft to trigger layout and adding a long
comment explaining why this is needed and potentially insufficient in the long run.

* svg/custom/object-no-size-attributes-expected.txt: Removed expectation of an empty text
renderer from the render tree.
* svg/custom/object-no-size-attributes.xhtml: Restructured the source so there is no text
to render. Without this, we were seeing two text renderers due to the loading timing change.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestspluginspluginremovereadystatechangeexpectedtxt">trunk/LayoutTests/plugins/plugin-remove-readystatechange-expected.txt</a></li>
<li><a href="#trunkLayoutTestspluginspluginremovereadystatechangehtml">trunk/LayoutTests/plugins/plugin-remove-readystatechange.html</a></li>
<li><a href="#trunkLayoutTestssvgcustomobjectnosizeattributesexpectedtxt">trunk/LayoutTests/svg/custom/object-no-size-attributes-expected.txt</a></li>
<li><a href="#trunkLayoutTestssvgcustomobjectnosizeattributesxhtml">trunk/LayoutTests/svg/custom/object-no-size-attributes.xhtml</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomContainerNodecpp">trunk/Source/WebCore/dom/ContainerNode.cpp</a></li>
<li><a href="#trunkSourceWebCoredomContainerNodeh">trunk/Source/WebCore/dom/ContainerNode.h</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementh">trunk/Source/WebCore/dom/Element.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLEmbedElementcpp">trunk/Source/WebCore/html/HTMLEmbedElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFormControlElementcpp">trunk/Source/WebCore/html/HTMLFormControlElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLFrameOwnerElementcpp">trunk/Source/WebCore/html/HTMLFrameOwnerElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLObjectElementcpp">trunk/Source/WebCore/html/HTMLObjectElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLObjectElementh">trunk/Source/WebCore/html/HTMLObjectElement.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLPlugInImageElementcpp">trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLPlugInImageElementh">trunk/Source/WebCore/html/HTMLPlugInImageElement.h</a></li>
<li><a href="#trunkSourceWebCorestyleStyleResolveTreecpp">trunk/Source/WebCore/style/StyleResolveTree.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleStyleResolveTreeh">trunk/Source/WebCore/style/StyleResolveTree.h</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebCoreSupportWebFrameLoaderClientmm">trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/LayoutTests/ChangeLog        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2014-03-23  Darin Adler  &lt;darin@apple.com&gt;
+
+        Remove code in HTMLObjectElement attribute parsing that forces style resolution and layout
+        https://bugs.webkit.org/show_bug.cgi?id=130653
+
+        Reviewed by Antti Koivisto.
+
+        * plugins/plugin-remove-readystatechange-expected.txt: Added a blank line; not what this
+        test is testing, but the different timing of loads results in this blank line.
+        * plugins/plugin-remove-readystatechange.html: Updated test to use waitUntilDone/notifyDone
+        rather than racing. Added a computation of offsetLeft to trigger layout and adding a long
+        comment explaining why this is needed and potentially insufficient in the long run.
+
+        * svg/custom/object-no-size-attributes-expected.txt: Removed expectation of an empty text
+        renderer from the render tree.
+        * svg/custom/object-no-size-attributes.xhtml: Restructured the source so there is no text
+        to render. Without this, we were seeing two text renderers due to the loading timing change.
+
</ins><span class="cx"> 2014-03-23  James Craig  &lt;jcraig@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: AXI: add other ARIA one-to-many relationships: owns, flowto, controls.
</span></span></pre></div>
<a id="trunkLayoutTestspluginspluginremovereadystatechangeexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/plugins/plugin-remove-readystatechange-expected.txt (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/plugins/plugin-remove-readystatechange-expected.txt        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/LayoutTests/plugins/plugin-remove-readystatechange-expected.txt        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -1,2 +1,3 @@
</span><span class="cx"> ALERT: PASS: element could not be re-appended
</span><span class="cx"> This test passes if it does not trip an assert in debug builds. It ensures a readystatechange event can't get dispatched until after a plugin is fully removed.
</span><ins>+
</ins></span></pre></div>
<a id="trunkLayoutTestspluginspluginremovereadystatechangehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/plugins/plugin-remove-readystatechange.html (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/plugins/plugin-remove-readystatechange.html        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/LayoutTests/plugins/plugin-remove-readystatechange.html        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -7,8 +7,10 @@
</span><span class="cx"> &lt;/div&gt;
</span><span class="cx"> &lt;embed id=&quot;viewer&quot; src=&quot;resources/simple_blank.swf&quot;&gt;&lt;/embed&gt;
</span><span class="cx"> &lt;script&gt;
</span><del>-if (window.testRunner)
</del><ins>+if (window.testRunner) {
</ins><span class="cx">     testRunner.dumpAsText();
</span><ins>+    testRunner.waitUntilDone();
+}
</ins><span class="cx"> 
</span><span class="cx"> var i = 0;
</span><span class="cx"> document.addEventListener('readystatechange', function() {
</span><span class="lines">@@ -18,12 +20,21 @@
</span><span class="cx">         }
</span><span class="cx">         catch (e) {
</span><span class="cx">             alert('PASS: element could not be re-appended');
</span><del>-       }
</del><ins>+        }
+        if (window.testRunner)
+            testRunner.notifyDone();
</ins><span class="cx">     }
</span><span class="cx">     i++;
</span><span class="cx"> });
</span><span class="cx"> 
</span><span class="cx"> window.addEventListener('DOMContentLoaded', function() {
</span><ins>+    // This test relies on removing the embed element while it is actively loading.
+    // There's no observable event that creates the exact right timing for that.
+    // As of this writing, after DOMContentLoaded, then next layout is the right time.
+    // Here we evaluate document.body.offsetLeft to trigger that layout. But really,
+    // this is a race condition, nothing guarantees that the load starts at that moment,
+    // and we might have to revise this test again in the future.
+    document.body.offsetLeft;
</ins><span class="cx">     document.body.removeChild(document.getElementById('viewer'));
</span><span class="cx"> });
</span><span class="cx"> &lt;/script&gt;
</span></span></pre></div>
<a id="trunkLayoutTestssvgcustomobjectnosizeattributesexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/svg/custom/object-no-size-attributes-expected.txt (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/custom/object-no-size-attributes-expected.txt        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/LayoutTests/svg/custom/object-no-size-attributes-expected.txt        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -9,4 +9,3 @@
</span><span class="cx">         layer at (0,0) size 100x100
</span><span class="cx">           RenderSVGRoot {svg} at (0,0) size 100x100
</span><span class="cx">             RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
</span><del>-      RenderText {#text} at (0,0) size 0x0
</del></span></pre></div>
<a id="trunkLayoutTestssvgcustomobjectnosizeattributesxhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/svg/custom/object-no-size-attributes.xhtml (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/custom/object-no-size-attributes.xhtml        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/LayoutTests/svg/custom/object-no-size-attributes.xhtml        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -1,9 +1,7 @@
</span><span class="cx"> &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
</span><span class="cx"> &lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;&gt;
</span><span class="cx"> &lt;body&gt;
</span><del>-&lt;object type=&quot;image/svg+xml&quot; data=&quot;data:image/svg+xml;charset=utf-8,%3Csvg%20width%3D%22100px%22%20height%3D%22100px%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Crect%20fill%3D%22green%22%20width%3D%22100px%22%20height%3D%22100px%22%20%2F%3E%3C%2Fsvg%3E&quot; style='background: red'&gt;&lt;/object&gt;
-
-&lt;!--
</del><ins>+&lt;object type=&quot;image/svg+xml&quot; data=&quot;data:image/svg+xml;charset=utf-8,%3Csvg%20width%3D%22100px%22%20height%3D%22100px%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Crect%20fill%3D%22green%22%20width%3D%22100px%22%20height%3D%22100px%22%20%2F%3E%3C%2Fsvg%3E&quot; style='background: red'&gt;&lt;/object&gt;&lt;!--
</ins><span class="cx"> 100px x 100px SVG
</span><span class="cx"> 
</span><span class="cx"> Code:
</span><span class="lines">@@ -13,7 +11,5 @@
</span><span class="cx"> &lt;/svg&gt;
</span><span class="cx"> 
</span><span class="cx"> You should see a 100 x 100 green square above.  No red should be visible.  &amp;lt;object&amp;gt; tags should treat the width/height attributes on an embeded SVG as the intrinsic size and not default to the CSS default of 300 x 150.
</span><del>---&gt;
-
-&lt;/body&gt;
</del><ins>+--&gt;&lt;/body&gt;
</ins><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/ChangeLog        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -1,3 +1,102 @@
</span><ins>+2014-03-23  Darin Adler  &lt;darin@apple.com&gt;
+
+        Remove code in HTMLObjectElement attribute parsing that forces style resolution and layout
+        https://bugs.webkit.org/show_bug.cgi?id=130653
+
+        Reviewed by Antti Koivisto.
+
+        * dom/ContainerNode.cpp: Moved the post-attach callback code from here to
+        StyleResolveTree.h/cpp.
+        * dom/ContainerNode.h: Ditto.
+
+        * dom/Document.cpp:
+        (WebCore::Document::recalcStyle): Use Style::PostResolutionCallbackDisabler instead of
+        PostAttachCallbackDisabler.
+
+        * dom/Element.h: Moved the post-attach callback code from here to StyleResolveTree.h/cpp.
+
+        * html/HTMLEmbedElement.cpp:
+        (WebCore::HTMLEmbedElement::parseAttribute): Simplified the code for typeAttr, turning
+        it into a 1-liner. Added a FIXME in codeAttr about the fact that it does not have the
+        code to trigger image loads. Changed srcAttr to call updateImageLoaderWithNewURLSoon to
+        do the image loading logic.
+
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::didAttachRenderers): Updated to use
+        Style::queuePostResolutionCallback and use a lambda instead of a function.
+        (WebCore::HTMLFormControlElement::didRecalcStyle): Ditto. Also added RefPtr instead
+        of just using wishful thinking to keep the object alive.
+        * html/HTMLFrameOwnerElement.cpp:
+        (WebCore::HTMLFrameOwnerElement::scheduleSetNeedsStyleRecalc): Ditto.
+
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::parseAttribute):: Simplified the code for typeAttr, turning
+        it into a 1-liner. Changed dataAttr to use updateImageLoaderWithNewURLSoon(). Also made
+        it call setNeedsWidgetUpdate(true) unconditionally after checking carefully to see that's
+        harmless if there is no renderer. Changed classidAttr to call setNeedsWidgetUpdate(true)
+        unconditionally and not set m_classId.
+        (WebCore::HTMLObjectElement::shouldAllowQuickTimeClassIdQuirk): Use fastGetAttribute
+        instead of classId and descendantsOfType instead of getElementsByTagName.
+        (WebCore::HTMLObjectElement::hasValidClassId): Use fastGetAttribute instead of classId.
+        (WebCore::HTMLObjectElement::renderFallbackContent): Use imageLoader instead of m_imageLoader.
+
+        * html/HTMLObjectElement.h: Removed classId, since there is no reason to cache that
+        attribute in a data member. Rearranged header, making more private, and fixing some typos,
+        and doing a &quot;using&quot; instead of a function to disambiguate the inherited form functions.
+
+        * html/HTMLPlugInImageElement.cpp:
+        (WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement): Initialize m_needsImageReload.
+        (WebCore::HTMLPlugInImageElement::createElementRenderer): Fixed some code that assumed the
+        first child of the shadow root is guaranteed to be an element.
+        (WebCore::HTMLPlugInImageElement::didRecalcStyle): Added. Calls the new
+        scheduleUpdateForAfterStyleResolution function.
+        (WebCore::HTMLPlugInImageElement::didAttachRenderers): Moved all the logic from this
+        function into scheduleUpdateForAfterStyleResolution. Also added a call through to the base
+        class; cleaner even though it's just an assertion.
+        (WebCore::HTMLPlugInImageElement::scheduleUpdateForAfterStyleResolution): Added.
+        Schedules a call to updateAfterStyleResolution when needed.
+        (WebCore::HTMLPlugInImageElement::updateAfterStyleResolution): Added.
+        Combines updateWidgetIfNecessary and startLoadingImage, and also deals with the new
+        m_needsImageReload boolean in cases where no actual loading is done.
+        (WebCore::HTMLPlugInImageElement::removedFrom): Added. Do not delay the load event of
+        document once this element is removed, clears m_needsImageReload.
+        (WebCore::HTMLPlugInImageElement::didMoveToNewDocument): Removed null check on oldDocument,
+        since m_needsDocumentActivationCallbacks can't be true if the old document was null.
+        (WebCore::is100Percent): Added helper to make function below more readable.
+        (WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn): Restructured the code a
+        bit. The part that attracted my attention was the local variable of type RenderBox, which
+        was named renderEmbeddedObject. Turns out the caller guarantees to only call this if there
+        is a renderer of type RenderEmbeddedObject, so depend on that.
+        (WebCore::HTMLPlugInImageElement::setNeedsImageReload): Added. When called with true, sets
+        the flag and triggers a style recalculation, and lets updateAfterStyleResolution do the rest.
+        When called with false, reverses the effects and stops delaying the load event.
+
+        * html/HTMLPlugInImageElement.h: Trimmed includes a bit. Made more members private.
+        Marked more function members final. Made a protected imageLoader function so that
+        m_imageLoader can be private. Added new protected function updateImageLoaderWithNewURLSoon,
+        as well as other new private functions. Made m_imageLoader be std::unique_ptr instead of
+        OwnPtr, and added m_needsImageReload.
+
+        * style/StyleResolveTree.cpp:
+        (WebCore::Style::needsPseudoElement): Fixed spelling error in the name of this function.
+        (WebCore::Style::attachBeforeOrAfterPseudoElementIfNeeded): Updated for name change.
+        (WebCore::Style::attachRenderTree): Update for new name of PostResolutionCallbackDisabler.
+        (WebCore::Style::updateBeforeOrAfterPseudoElement): Updated for name change.
+        (WebCore::Style::postResolutionCallbackQueue): Added.
+        (WebCore::Style::queuePostResolutionCallback): Added.
+        (WebCore::Style::suspendMemoryCacheClientCalls): Added. This is a side effect of the original
+        PostAttachCallbackDisabler that is now done in a cleaner way, using the callback queue, instead
+        of as a special case. It should not work for multiple documents across multiple pages instead of
+        only the outermost one.
+        (WebCore::Style::PostResolutionCallbackDisabler::PostResolutionCallbackDisabler): Added.
+        Calls suspendMemoryCacheClientCalls, but a FIXME tries to point out why that isn't so great.
+        (WebCore::Style::PostResolutionCallbackDisabler::~PostResolutionCallbackDisabler): Added.
+        (WebCore::Style::postResolutionCallbacksAreSuspended): Added.
+
+        * style/StyleResolveTree.h: Added queuePostResolutionCallback and
+        postResolutionCallbacksAreSuspended. Also added PostResolutionCallbackDisabler, which should
+        eventually become a private implementation detail.
+
</ins><span class="cx"> 2014-03-23  Sam Weinig  &lt;sam@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Simplify the HTMLConverter interface (Part 1)
</span></span></pre></div>
<a id="trunkSourceWebCoredomContainerNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ContainerNode.cpp        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -37,13 +37,10 @@
</span><span class="cx"> #include &quot;JSLazyEventListener.h&quot;
</span><span class="cx"> #include &quot;JSNode.h&quot;
</span><span class="cx"> #include &quot;LabelsNodeList.h&quot;
</span><del>-#include &quot;LoaderStrategy.h&quot;
-#include &quot;MemoryCache.h&quot;
</del><span class="cx"> #include &quot;MutationEvent.h&quot;
</span><span class="cx"> #include &quot;NameNodeList.h&quot;
</span><span class="cx"> #include &quot;NodeRareData.h&quot;
</span><span class="cx"> #include &quot;NodeRenderStyle.h&quot;
</span><del>-#include &quot;PlatformStrategies.h&quot;
</del><span class="cx"> #include &quot;RadioNodeList.h&quot;
</span><span class="cx"> #include &quot;RenderBox.h&quot;
</span><span class="cx"> #include &quot;RenderTheme.h&quot;
</span><span class="lines">@@ -63,15 +60,6 @@
</span><span class="cx"> static void dispatchChildInsertionEvents(Node&amp;);
</span><span class="cx"> static void dispatchChildRemovalEvents(Node&amp;);
</span><span class="cx"> 
</span><del>-typedef std::pair&lt;RefPtr&lt;Node&gt;, unsigned&gt; CallbackParameters;
-typedef std::pair&lt;NodeCallback, CallbackParameters&gt; CallbackInfo;
-typedef Vector&lt;CallbackInfo&gt; NodeCallbackQueue;
-
-static NodeCallbackQueue* s_postAttachCallbackQueue;
-
-static size_t s_attachDepth;
-static bool s_shouldReEnableMemoryCacheCallsAfterAttach;
-
</del><span class="cx"> ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0;
</span><span class="cx"> 
</span><span class="cx"> #ifndef NDEBUG
</span><span class="lines">@@ -758,67 +746,6 @@
</span><span class="cx">     newChild-&gt;setNeedsStyleRecalc(ReconstructRenderTree);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ContainerNode::suspendPostAttachCallbacks(Document&amp; document)
-{
-    if (!s_attachDepth) {
-        ASSERT(!s_shouldReEnableMemoryCacheCallsAfterAttach);
-        if (Page* page = document.page()) {
-            // FIXME: How can this call be specific to one Page, while the
-            // s_attachDepth is a global? Doesn't make sense.
-            if (page-&gt;areMemoryCacheClientCallsEnabled()) {
-                page-&gt;setMemoryCacheClientCallsEnabled(false);
-                s_shouldReEnableMemoryCacheCallsAfterAttach = true;
-            }
-        }
-        platformStrategies()-&gt;loaderStrategy()-&gt;resourceLoadScheduler()-&gt;suspendPendingRequests();
-    }
-    ++s_attachDepth;
-}
-
-void ContainerNode::resumePostAttachCallbacks(Document&amp; document)
-{
-    if (s_attachDepth == 1) {
-        Ref&lt;Document&gt; protect(document);
-
-        if (s_postAttachCallbackQueue)
-            dispatchPostAttachCallbacks();
-        if (s_shouldReEnableMemoryCacheCallsAfterAttach) {
-            s_shouldReEnableMemoryCacheCallsAfterAttach = false;
-            if (Page* page = document.page())
-                page-&gt;setMemoryCacheClientCallsEnabled(true);
-        }
-        platformStrategies()-&gt;loaderStrategy()-&gt;resourceLoadScheduler()-&gt;resumePendingRequests();
-    }
-    --s_attachDepth;
-}
-
-void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node&amp; node, unsigned callbackData)
-{
-    if (!s_postAttachCallbackQueue)
-        s_postAttachCallbackQueue = new NodeCallbackQueue;
-    
-    s_postAttachCallbackQueue-&gt;append(CallbackInfo(callback, CallbackParameters(&amp;node, callbackData)));
-}
-
-bool ContainerNode::postAttachCallbacksAreSuspended()
-{
-    return s_attachDepth;
-}
-
-void ContainerNode::dispatchPostAttachCallbacks()
-{
-    // We recalculate size() each time through the loop because a callback
-    // can add more callbacks to the end of the queue.
-    for (size_t i = 0; i &lt; s_postAttachCallbackQueue-&gt;size(); ++i) {
-        const CallbackInfo&amp; info = (*s_postAttachCallbackQueue)[i];
-        NodeCallback callback = info.first;
-        CallbackParameters params = info.second;
-
-        callback(*params.first, params.second);
-    }
-    s_postAttachCallbackQueue-&gt;clear();
-}
-
</del><span class="cx"> void ContainerNode::childrenChanged(const ChildChange&amp; change)
</span><span class="cx"> {
</span><span class="cx">     document().incDOMTreeVersion();
</span></span></pre></div>
<a id="trunkSourceWebCoredomContainerNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ContainerNode.h (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ContainerNode.h        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/dom/ContainerNode.h        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -79,7 +79,6 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class ContainerNode : public Node {
</span><del>-    friend class PostAttachCallbackDisabler;
</del><span class="cx"> public:
</span><span class="cx">     virtual ~ContainerNode();
</span><span class="cx"> 
</span><span class="lines">@@ -140,9 +139,6 @@
</span><span class="cx"> protected:
</span><span class="cx">     explicit ContainerNode(Document&amp;, ConstructionType = CreateContainer);
</span><span class="cx"> 
</span><del>-    static void queuePostAttachCallback(NodeCallback, Node&amp;, unsigned = 0);
-    static bool postAttachCallbacksAreSuspended();
-
</del><span class="cx">     template&lt;class GenericNode, class GenericNodeContainer&gt;
</span><span class="cx">     friend void appendChildToContainer(GenericNode* child, GenericNodeContainer&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -157,10 +153,6 @@
</span><span class="cx">     void removeBetween(Node* previousChild, Node* nextChild, Node&amp; oldChild);
</span><span class="cx">     void insertBeforeCommon(Node&amp; nextChild, Node&amp; oldChild);
</span><span class="cx"> 
</span><del>-    static void dispatchPostAttachCallbacks();
-    static void suspendPostAttachCallbacks(Document&amp;);
-    static void resumePostAttachCallbacks(Document&amp;);
-
</del><span class="cx">     bool getUpperLeftCorner(FloatPoint&amp;) const;
</span><span class="cx">     bool getLowerRightCorner(FloatPoint&amp;) const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/dom/Document.cpp        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -1756,7 +1756,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_inStyleRecalc = true;
</span><span class="cx">     {
</span><del>-        PostAttachCallbackDisabler disabler(*this);
</del><ins>+        Style::PostResolutionCallbackDisabler disabler(*this);
</ins><span class="cx">         WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
</span><span class="cx"> 
</span><span class="cx">         if (m_pendingStyleRecalcShouldForce)
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.h (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.h        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/dom/Element.h        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -798,23 +798,6 @@
</span><span class="cx">     return static_cast&lt;UniqueElementData&amp;&gt;(*m_elementData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-class PostAttachCallbackDisabler {
-public:
-    explicit PostAttachCallbackDisabler(Document&amp; document)
-        : m_document(document)
-    {
-        Element::suspendPostAttachCallbacks(m_document);
-    }
-
-    ~PostAttachCallbackDisabler()
-    {
-        Element::resumePostAttachCallbacks(m_document);
-    }
-
-private:
-    Document&amp; m_document;
-};
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLEmbedElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLEmbedElement.cpp (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLEmbedElement.cpp        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/html/HTMLEmbedElement.cpp        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -97,20 +97,18 @@
</span><span class="cx"> void HTMLEmbedElement::parseAttribute(const QualifiedName&amp; name, const AtomicString&amp; value)
</span><span class="cx"> {
</span><span class="cx">     if (name == typeAttr) {
</span><del>-        m_serviceType = value.string().lower();
-        size_t pos = m_serviceType.find(&quot;;&quot;);
-        if (pos != notFound)
-            m_serviceType = m_serviceType.left(pos);
-    } else if (name == codeAttr)
</del><ins>+        m_serviceType = value.string().left(value.find(&quot;;&quot;)).lower();
+        // FIXME: The only difference between this and HTMLObjectElement's corresponding
+        // code is that HTMLObjectElement does setNeedsWidgetUpdate(true). Consider moving
+        // this up to the HTMLPlugInImageElement to be shared.
+    } else if (name == codeAttr) {
</ins><span class="cx">         m_url = stripLeadingAndTrailingHTMLSpaces(value);
</span><del>-    else if (name == srcAttr) {
</del><ins>+        // FIXME: Why no call to updateImageLoaderWithNewURLSoon?
+        // FIXME: If both code and src attributes are specified, last one parsed/changed wins. That can't be right!
+    } else if (name == srcAttr) {
</ins><span class="cx">         m_url = stripLeadingAndTrailingHTMLSpaces(value);
</span><del>-        document().updateStyleIfNeeded();
-        if (renderer() &amp;&amp; isImageType()) {
-            if (!m_imageLoader)
-                m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
-            m_imageLoader-&gt;updateFromElementIgnoringPreviousError();
-        }
</del><ins>+        updateImageLoaderWithNewURLSoon();
+        // FIXME: If both code and src attributes are specified, last one parsed/changed wins. That can't be right!
</ins><span class="cx">     } else
</span><span class="cx">         HTMLPlugInImageElement::parseAttribute(name, value);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFormControlElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFormControlElement.cpp        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.cpp        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -207,12 +207,6 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void focusPostAttach(Node&amp; element, unsigned)
-{ 
-    toElement(element).focus();
-    element.deref();
-}
-
</del><span class="cx"> void HTMLFormControlElement::didAttachRenderers()
</span><span class="cx"> {
</span><span class="cx">     // The call to updateFromElement() needs to go after the call through
</span><span class="lines">@@ -223,8 +217,11 @@
</span><span class="cx"> 
</span><span class="cx">     if (shouldAutofocus(this)) {
</span><span class="cx">         setAutofocused();
</span><del>-        ref();
-        queuePostAttachCallback(focusPostAttach, *this);
</del><ins>+
+        RefPtr&lt;HTMLFormControlElement&gt; element = this;
+        Style::queuePostResolutionCallback([element] {
+            element-&gt;focus();
+        });
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -287,18 +284,17 @@
</span><span class="cx">     return m_isRequired;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void updateFromElementCallback(Node&amp; node, unsigned)
-{
-    if (auto renderer = toHTMLFormControlElement(node).renderer())
-        renderer-&gt;updateFromElement();
-}
-
</del><span class="cx"> void HTMLFormControlElement::didRecalcStyle(Style::Change)
</span><span class="cx"> {
</span><span class="cx">     // updateFromElement() can cause the selection to change, and in turn
</span><span class="cx">     // trigger synchronous layout, so it must not be called during style recalc.
</span><del>-    if (renderer())
-        queuePostAttachCallback(updateFromElementCallback, *this);
</del><ins>+    if (renderer()) {
+        RefPtr&lt;HTMLFormControlElement&gt; element = this;
+        Style::queuePostResolutionCallback([element]{
+            if (auto* renderer = element-&gt;renderer())
+                renderer-&gt;updateFromElement();
+        });
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool HTMLFormControlElement::supportsFocus() const
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLFrameOwnerElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLFrameOwnerElement.cpp (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLFrameOwnerElement.cpp        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/html/HTMLFrameOwnerElement.cpp        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -121,16 +121,14 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void needsStyleRecalcCallback(Node&amp; node, unsigned data)
-{
-    node.setNeedsStyleRecalc(static_cast&lt;StyleChangeType&gt;(data));
-}
-
</del><span class="cx"> void HTMLFrameOwnerElement::scheduleSetNeedsStyleRecalc(StyleChangeType changeType)
</span><span class="cx"> {
</span><del>-    if (postAttachCallbacksAreSuspended())
-        queuePostAttachCallback(needsStyleRecalcCallback, *this, static_cast&lt;unsigned&gt;(changeType));
-    else
</del><ins>+    if (Style::postResolutionCallbacksAreSuspended()) {
+        RefPtr&lt;HTMLFrameOwnerElement&gt; element = this;
+        Style::queuePostResolutionCallback([element, changeType]{
+            element-&gt;setNeedsStyleRecalc(changeType);
+        });
+    } else
</ins><span class="cx">         setNeedsStyleRecalc(changeType);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLObjectElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLObjectElement.cpp (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLObjectElement.cpp        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/html/HTMLObjectElement.cpp        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -107,28 +107,15 @@
</span><span class="cx">     if (name == formAttr)
</span><span class="cx">         formAttributeChanged();
</span><span class="cx">     else if (name == typeAttr) {
</span><del>-        m_serviceType = value.lower();
-        size_t pos = m_serviceType.find(&quot;;&quot;);
-        if (pos != notFound)
-            m_serviceType = m_serviceType.left(pos);
-        if (renderer())
-            setNeedsWidgetUpdate(true);
</del><ins>+        m_serviceType = value.string().left(value.find(';')).lower();
+        setNeedsWidgetUpdate(true);
</ins><span class="cx">     } else if (name == dataAttr) {
</span><span class="cx">         m_url = stripLeadingAndTrailingHTMLSpaces(value);
</span><del>-        document().updateStyleIfNeeded();
-        if (renderer()) {
-            setNeedsWidgetUpdate(true);
-            if (isImageType()) {
-                if (!m_imageLoader)
-                    m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
-                m_imageLoader-&gt;updateFromElementIgnoringPreviousError();
-            }
-        }
-    } else if (name == classidAttr) {
-        m_classId = value;
-        if (renderer())
-            setNeedsWidgetUpdate(true);
-    } else if (name == onbeforeloadAttr)
</del><ins>+        setNeedsWidgetUpdate(true);
+        updateImageLoaderWithNewURLSoon();
+    } else if (name == classidAttr)
+        setNeedsWidgetUpdate(true);
+    else if (name == onbeforeloadAttr)
</ins><span class="cx">         setAttributeEventListener(eventNames().beforeloadEvent, name, value);
</span><span class="cx">     else
</span><span class="cx">         HTMLPlugInImageElement::parseAttribute(name, value);
</span><span class="lines">@@ -251,26 +238,24 @@
</span><span class="cx">     // 'generator' meta tag is present. Only apply this quirk if there is no
</span><span class="cx">     // fallback content, which ensures the quirk will disable itself if Wiki
</span><span class="cx">     // Server is updated to generate an alternate embed tag as fallback content.
</span><ins>+
</ins><span class="cx">     if (!document().page()
</span><span class="cx">         || !document().page()-&gt;settings().needsSiteSpecificQuirks()
</span><span class="cx">         || hasFallbackContent()
</span><del>-        || !equalIgnoringCase(classId(), &quot;clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B&quot;))
</del><ins>+        || !equalIgnoringCase(fastGetAttribute(classidAttr), &quot;clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B&quot;))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    RefPtr&lt;NodeList&gt; metaElements = document().getElementsByTagName(HTMLNames::metaTag.localName());
-    unsigned length = metaElements-&gt;length();
-    for (unsigned i = 0; i &lt; length; ++i) {
-        HTMLMetaElement&amp; metaElement = toHTMLMetaElement(*metaElements-&gt;item(i));
</del><ins>+    for (auto&amp; metaElement : descendantsOfType&lt;HTMLMetaElement&gt;(document())) {
</ins><span class="cx">         if (equalIgnoringCase(metaElement.name(), &quot;generator&quot;) &amp;&amp; metaElement.content().startsWith(&quot;Mac OS X Server Web Services Server&quot;, false))
</span><span class="cx">             return true;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
</ins><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> bool HTMLObjectElement::hasValidClassId()
</span><span class="cx"> {
</span><del>-    if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) &amp;&amp; classId().startsWith(&quot;java:&quot;, false))
</del><ins>+    if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) &amp;&amp; fastGetAttribute(classidAttr).startsWith(&quot;java:&quot;, false))
</ins><span class="cx">         return true;
</span><span class="cx">     
</span><span class="cx">     if (shouldAllowQuickTimeClassIdQuirk())
</span><span class="lines">@@ -278,7 +263,7 @@
</span><span class="cx"> 
</span><span class="cx">     // HTML5 says that fallback content should be rendered if a non-empty
</span><span class="cx">     // classid is specified for which the UA can't find a suitable plug-in.
</span><del>-    return classId().isEmpty();
</del><ins>+    return fastGetAttribute(classidAttr).isEmpty();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // FIXME: This should be unified with HTMLEmbedElement::updateWidget and
</span><span class="lines">@@ -375,20 +360,22 @@
</span><span class="cx">     setNeedsStyleRecalc(ReconstructRenderTree);
</span><span class="cx"> 
</span><span class="cx">     // Before we give up and use fallback content, check to see if this is a MIME type issue.
</span><del>-    if (m_imageLoader &amp;&amp; m_imageLoader-&gt;image() &amp;&amp; m_imageLoader-&gt;image()-&gt;status() != CachedResource::LoadError) {
-        m_serviceType = m_imageLoader-&gt;image()-&gt;response().mimeType();
</del><ins>+    auto* loader = imageLoader();
+    if (loader &amp;&amp; loader-&gt;image() &amp;&amp; loader-&gt;image()-&gt;status() != CachedResource::LoadError) {
+        m_serviceType = loader-&gt;image()-&gt;response().mimeType();
</ins><span class="cx">         if (!isImageType()) {
</span><span class="cx">             // If we don't think we have an image type anymore, then clear the image from the loader.
</span><del>-            m_imageLoader-&gt;setImage(0);
</del><ins>+            loader-&gt;setImage(nullptr);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_useFallbackContent = true;
</span><span class="cx"> 
</span><del>-    // This is here mainly to keep acid2 non-flaky. A style recalc is required to make fallback resources to load. Without forcing
-    // this may happen after all the other resources have been loaded and the document is already considered complete.
-    // FIXME: Disentangle fallback content handling from style recalcs.
</del><ins>+    // This was added to keep Acid 2 non-flaky. A style recalc is required to make fallback resources load.
+    // Without forcing, this may happen after all the other resources have been loaded and the document is already
+    // considered complete. FIXME: Could address this with incrementLoadEventDelayCount instead, as we do with
+    // image loading in HTMLPlugInImageElement, or disentangle loading from style entirely.
</ins><span class="cx">     document().updateStyleIfNeeded();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLObjectElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLObjectElement.h (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLObjectElement.h        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/html/HTMLObjectElement.h        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -36,35 +36,23 @@
</span><span class="cx">     virtual ~HTMLObjectElement();
</span><span class="cx"> 
</span><span class="cx">     bool isDocNamedItem() const { return m_docNamedItem; }
</span><del>-
-    const String&amp; classId() const { return m_classId; }
-
</del><span class="cx">     bool containsJavaApplet() const;
</span><span class="cx"> 
</span><ins>+    bool hasFallbackContent() const;
</ins><span class="cx">     virtual bool useFallbackContent() const override { return m_useFallbackContent; }
</span><span class="cx">     void renderFallbackContent();
</span><span class="cx"> 
</span><del>-    // Implementations of FormAssociatedElement
-    HTMLFormElement* form() const { return FormAssociatedElement::form(); }
-
-    virtual bool isFormControlElement() const override { return false; }
-
-    virtual bool isEnumeratable() const override { return true; }
-    virtual bool appendFormData(FormDataList&amp;, bool) override;
-
-    // Implementations of constraint validation API.
</del><ins>+    // Implementation of constraint validation API.
</ins><span class="cx">     // Note that the object elements are always barred from constraint validation.
</span><del>-    virtual String validationMessage() const override { return String(); }
-    bool checkValidity() { return true; }
</del><ins>+    static bool checkValidity() { return true; }
</ins><span class="cx">     virtual void setCustomValidity(const String&amp;) override { }
</span><ins>+    virtual String validationMessage() const override { return String(); }
</ins><span class="cx"> 
</span><del>-    using Node::ref;
-    using Node::deref;
</del><ins>+    using HTMLPlugInImageElement::ref;
+    using HTMLPlugInImageElement::deref;
</ins><span class="cx"> 
</span><del>-    virtual bool canContainRangeEndPoint() const override { return useFallbackContent(); }
</del><ins>+    using FormAssociatedElement::form;
</ins><span class="cx"> 
</span><del>-    bool hasFallbackContent() const;
-
</del><span class="cx"> private:
</span><span class="cx">     HTMLObjectElement(const QualifiedName&amp;, Document&amp;, HTMLFormElement*, bool createdByParser);
</span><span class="cx"> 
</span><span class="lines">@@ -104,7 +92,13 @@
</span><span class="cx">     virtual HTMLObjectElement&amp; asHTMLElement() override final { return *this; }
</span><span class="cx">     virtual const HTMLObjectElement&amp; asHTMLElement() const override final { return *this; }
</span><span class="cx"> 
</span><del>-    String m_classId;
</del><ins>+    virtual bool isFormControlElement() const override { return false; }
+
+    virtual bool isEnumeratable() const override { return true; }
+    virtual bool appendFormData(FormDataList&amp;, bool) override;
+
+    virtual bool canContainRangeEndPoint() const override { return useFallbackContent(); }
+
</ins><span class="cx">     bool m_docNamedItem : 1;
</span><span class="cx">     bool m_useFallbackContent : 1;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLPlugInImageElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2011, 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2011, 2012, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -111,6 +111,7 @@
</span><span class="cx">     // this delay is unnecessary, but it is simpler to make both classes share
</span><span class="cx">     // the same codepath in this class.
</span><span class="cx">     , m_needsWidgetUpdate(!createdByParser)
</span><ins>+    , m_needsImageReload(false)
</ins><span class="cx">     , m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPreferPlugInsForImages)
</span><span class="cx">     , m_needsDocumentActivationCallbacks(false)
</span><span class="cx">     , m_simulatedMouseClickTimer(this, &amp;HTMLPlugInImageElement::simulatedMouseClickTimerFired, simulatedMouseClickTimerDelay)
</span><span class="lines">@@ -227,11 +228,12 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     if (ShadowRoot* shadowRoot = this-&gt;shadowRoot()) {
</span><del>-        Element* shadowElement = toElement(shadowRoot-&gt;firstChild());
-        if (shadowElement &amp;&amp; shadowElement-&gt;shadowPseudoId() == &quot;-apple-youtube-shadow-iframe&quot;)
</del><ins>+        Node* shadowNode = shadowRoot-&gt;firstChild();
+        if (shadowNode &amp;&amp; shadowNode-&gt;isElementNode() &amp;&amp; toElement(*shadowNode).shadowPseudoId() == &quot;-apple-youtube-shadow-iframe&quot;)
</ins><span class="cx">             return createRenderer&lt;RenderBlockFlow&gt;(*this, std::move(style));
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><ins>+
</ins><span class="cx">     return HTMLPlugInElement::createElementRenderer(std::move(style));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -244,42 +246,66 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void HTMLPlugInImageElement::didRecalcStyle(Style::Change styleChange)
+{
+    scheduleUpdateForAfterStyleResolution();
+
+    HTMLPlugInElement::didRecalcStyle(styleChange);
+}
+
</ins><span class="cx"> void HTMLPlugInImageElement::didAttachRenderers()
</span><span class="cx"> {
</span><del>-    if (!isImageType()) {
-        queuePostAttachCallback(&amp;HTMLPlugInImageElement::updateWidgetCallback, *this);
-        return;
-    }
-    if (!renderer() || useFallbackContent())
-        return;
</del><ins>+    scheduleUpdateForAfterStyleResolution();
</ins><span class="cx"> 
</span><del>-    // Image load might complete synchronously and cause us to re-enter attach.
-    queuePostAttachCallback(&amp;HTMLPlugInImageElement::startLoadingImageCallback, *this);
</del><ins>+    HTMLPlugInElement::didAttachRenderers();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLPlugInImageElement::willDetachRenderers()
</span><span class="cx"> {
</span><span class="cx">     // FIXME: Because of the insanity that is HTMLPlugInImageElement::willRecalcStyle,
</span><span class="cx">     // we can end up detaching during an attach() call, before we even have a
</span><del>-    // renderer.  In that case, don't mark the widget for update.
</del><ins>+    // renderer. In that case, don't mark the widget for update.
</ins><span class="cx">     if (renderer() &amp;&amp; !useFallbackContent()) {
</span><span class="cx">         // Update the widget the next time we attach (detaching destroys the plugin).
</span><span class="cx">         setNeedsWidgetUpdate(true);
</span><span class="cx">     }
</span><ins>+
</ins><span class="cx">     HTMLPlugInElement::willDetachRenderers();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTMLPlugInImageElement::updateWidgetIfNecessary()
</del><ins>+void HTMLPlugInImageElement::scheduleUpdateForAfterStyleResolution()
</ins><span class="cx"> {
</span><del>-    document().updateStyleIfNeeded();
</del><ins>+    if (m_needsImageReload || (renderer() &amp;&amp; !useFallbackContent())) {
+        RefPtr&lt;HTMLPlugInImageElement&gt; element = this;
+        Style::queuePostResolutionCallback([element]{
+            element-&gt;updateAfterStyleResolution();
+        });
+    }
+}
</ins><span class="cx"> 
</span><del>-    if (!needsWidgetUpdate() || useFallbackContent() || isImageType())
-        return;
</del><ins>+void HTMLPlugInImageElement::updateAfterStyleResolution()
+{
+    // Do this after style resolution, since the image or widget load might complete synchronously
+    // and cause us to re-enter otherwise. Also, we can't really answer the question &quot;do I have a renderer&quot;
+    // accurately until after style resolution.
</ins><span class="cx"> 
</span><del>-    if (!renderEmbeddedObject() || renderEmbeddedObject()-&gt;isPluginUnavailable())
-        return;
</del><ins>+    if (renderer() &amp;&amp; !useFallbackContent()) {
+        if (isImageType()) {
+            if (!m_imageLoader)
+                m_imageLoader = std::make_unique&lt;HTMLImageLoader&gt;(*this);
+            if (m_needsImageReload)
+                m_imageLoader-&gt;updateFromElementIgnoringPreviousError();
+            else
+                m_imageLoader-&gt;updateFromElement();
+        } else {
+            if (m_needsWidgetUpdate &amp;&amp; renderEmbeddedObject() &amp;&amp; !renderEmbeddedObject()-&gt;isPluginUnavailable())
+                updateWidget(CreateOnlyNonNetscapePlugins);
+        }
+    }
</ins><span class="cx"> 
</span><del>-    updateWidget(CreateOnlyNonNetscapePlugins);
</del><ins>+    // Either we reloaded the image just now, or we had some reason not to.
+    // Either way, clear the flag now, since we don't need to remember to try again.
+    setNeedsImageReload(false);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTMLPlugInImageElement::finishParsingChildren()
</span><span class="lines">@@ -293,16 +319,25 @@
</span><span class="cx">         setNeedsStyleRecalc();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void HTMLPlugInImageElement::removedFrom(ContainerNode&amp; root)
+{
+    // Important to do this when removed from a document to remove the possibility
+    // we might delay the document's load event indefinitely.
+    setNeedsImageReload(false);
+
+    HTMLPlugInElement::removedFrom(root);
+}
+
</ins><span class="cx"> void HTMLPlugInImageElement::didMoveToNewDocument(Document* oldDocument)
</span><span class="cx"> {
</span><span class="cx">     if (m_needsDocumentActivationCallbacks) {
</span><del>-        if (oldDocument)
-            oldDocument-&gt;unregisterForPageCacheSuspensionCallbacks(this);
</del><ins>+        oldDocument-&gt;unregisterForPageCacheSuspensionCallbacks(this);
</ins><span class="cx">         document().registerForPageCacheSuspensionCallbacks(this);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (m_imageLoader)
</span><span class="cx">         m_imageLoader-&gt;elementDidMoveToNewDocument();
</span><ins>+
</ins><span class="cx">     HTMLPlugInElement::didMoveToNewDocument(oldDocument);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -321,23 +356,6 @@
</span><span class="cx">     HTMLPlugInElement::documentDidResumeFromPageCache();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTMLPlugInImageElement::updateWidgetCallback(Node&amp; node, unsigned)
-{
-    toHTMLPlugInImageElement(node).updateWidgetIfNecessary();
-}
-
-void HTMLPlugInImageElement::startLoadingImage()
-{
-    if (!m_imageLoader)
-        m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
-    m_imageLoader-&gt;updateFromElement();
-}
-
-void HTMLPlugInImageElement::startLoadingImageCallback(Node&amp; node, unsigned)
-{
-    toHTMLPlugInImageElement(node).startLoadingImage();
-}
-
</del><span class="cx"> void HTMLPlugInImageElement::updateSnapshot(PassRefPtr&lt;Image&gt; image)
</span><span class="cx"> {
</span><span class="cx">     if (displayState() &gt; DisplayingSnapshot)
</span><span class="lines">@@ -437,18 +455,18 @@
</span><span class="cx">     ShadowRoot&amp; root = this-&gt;ensureUserAgentShadowRoot();
</span><span class="cx">     root.appendChild(shadowElement, ASSERT_NO_EXCEPTION);
</span><span class="cx"> 
</span><del>-    RefPtr&lt;HTMLIFrameElement&gt; iframeElement = HTMLIFrameElement::create(HTMLNames::iframeTag, document());
-    if (hasAttribute(HTMLNames::widthAttr))
-        iframeElement-&gt;setAttribute(HTMLNames::widthAttr, AtomicString(&quot;100%&quot;, AtomicString::ConstructFromLiteral));
-    if (hasAttribute(HTMLNames::heightAttr)) {
-        iframeElement-&gt;setAttribute(HTMLNames::styleAttr, AtomicString(&quot;max-height: 100%&quot;, AtomicString::ConstructFromLiteral));
-        iframeElement-&gt;setAttribute(HTMLNames::heightAttr, getAttribute(HTMLNames::heightAttr));
</del><ins>+    RefPtr&lt;HTMLIFrameElement&gt; iframeElement = HTMLIFrameElement::create(iframeTag, document());
+    if (hasAttribute(widthAttr))
+        iframeElement-&gt;setAttribute(widthAttr, AtomicString(&quot;100%&quot;, AtomicString::ConstructFromLiteral));
+    if (hasAttribute(heightAttr)) {
+        iframeElement-&gt;setAttribute(styleAttr, AtomicString(&quot;max-height: 100%&quot;, AtomicString::ConstructFromLiteral));
+        iframeElement-&gt;setAttribute(heightAttr, getAttribute(heightAttr));
</ins><span class="cx">     }
</span><del>-    iframeElement-&gt;setAttribute(HTMLNames::srcAttr, src);
-    iframeElement-&gt;setAttribute(HTMLNames::frameborderAttr, AtomicString(&quot;0&quot;, AtomicString::ConstructFromLiteral));
</del><ins>+    iframeElement-&gt;setAttribute(srcAttr, src);
+    iframeElement-&gt;setAttribute(frameborderAttr, AtomicString(&quot;0&quot;, AtomicString::ConstructFromLiteral));
</ins><span class="cx"> 
</span><span class="cx">     // Disable frame flattening for this iframe.
</span><del>-    iframeElement-&gt;setAttribute(HTMLNames::scrollingAttr, AtomicString(&quot;no&quot;, AtomicString::ConstructFromLiteral));
</del><ins>+    iframeElement-&gt;setAttribute(scrollingAttr, AtomicString(&quot;no&quot;, AtomicString::ConstructFromLiteral));
</ins><span class="cx">     shadowElement-&gt;appendChild(iframeElement, ASSERT_NO_EXCEPTION);
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="lines">@@ -610,6 +628,11 @@
</span><span class="cx">         toPluginViewBase(widget)-&gt;beginSnapshottingRunningPlugin();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline bool is100Percent(Length length)
+{
+    return length.isPercent() &amp;&amp; length.percent() == 100;
+}
+
</ins><span class="cx"> void HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn(const URL&amp; url)
</span><span class="cx"> {
</span><span class="cx">     LOG(Plugins, &quot;%p Plug-in URL: %s&quot;, this, m_url.utf8().data());
</span><span class="lines">@@ -694,27 +717,27 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    RenderBox* renderEmbeddedObject = toRenderBox(renderer());
-    Length styleWidth = renderEmbeddedObject-&gt;style().width();
-    Length styleHeight = renderEmbeddedObject-&gt;style().height();
-    LayoutRect contentBoxRect = renderEmbeddedObject-&gt;contentBoxRect();
-    int contentWidth = contentBoxRect.width();
-    int contentHeight = contentBoxRect.height();
-    int contentArea = contentWidth * contentHeight;
-    IntSize visibleViewSize = document().frame()-&gt;view()-&gt;visibleSize();
-    int visibleArea = visibleViewSize.width() * visibleViewSize.height();
</del><ins>+    auto&amp; renderer = toRenderEmbeddedObject(*this-&gt;renderer());
+    LayoutRect contentRect = renderer.contentBoxRect();
+    int contentWidth = contentRect.width();
+    int contentHeight = contentRect.height();
</ins><span class="cx"> 
</span><del>-    if (inMainFrame &amp;&amp; styleWidth.isPercent() &amp;&amp; (styleWidth.percent() == 100)
-        &amp;&amp; styleHeight.isPercent() &amp;&amp; (styleHeight.percent() == 100)
-        &amp;&amp; (static_cast&lt;float&gt;(contentArea) / visibleArea &gt; sizingFullPageAreaRatioThreshold)) {
-        LOG(Plugins, &quot;%p Plug-in is top level full page, set to play&quot;, this);
-        m_snapshotDecision = NeverSnapshot;
-        return;
</del><ins>+    if (inMainFrame) {
+        auto&amp; style = renderer.style();
+        bool isFullPage = is100Percent(style.width()) &amp;&amp; is100Percent(style.height());
+        IntSize visibleViewSize = document().frame()-&gt;view()-&gt;visibleSize();
+        float contentArea = contentWidth * contentHeight;
+        float visibleArea = visibleViewSize.width() * visibleViewSize.height();
+        if (isFullPage &amp;&amp; contentArea &gt; visibleArea * sizingFullPageAreaRatioThreshold) {
+            LOG(Plugins, &quot;%p Plug-in is top level full page, set to play&quot;, this);
+            m_snapshotDecision = NeverSnapshot;
+            return;
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (contentWidth &lt;= sizingTinyDimensionThreshold || contentHeight &lt;= sizingTinyDimensionThreshold) {
</span><span class="cx">         LOG(Plugins, &quot;%p Plug-in is very small %dx%d, set to play&quot;, this, contentWidth, contentHeight);
</span><del>-        m_sizeWhenSnapshotted = IntSize(contentBoxRect.width().toInt(), contentBoxRect.height().toInt());
</del><ins>+        m_sizeWhenSnapshotted = IntSize(contentWidth, contentHeight);
</ins><span class="cx">         m_snapshotDecision = MaySnapshotWhenResized;
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -726,7 +749,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    LOG(Plugins, &quot;%p Plug-in from (%s, %s) is not auto-start, sized at %dx%d, set to wait for snapshot&quot;, this, document().page()-&gt;mainFrame().document()-&gt;baseURL().host().utf8().data(), url.host().utf8().data(), contentWidth, contentHeight);
</del><ins>+    LOG(Plugins, &quot;%p Plug-in from (%s, %s) is not auto-start, sized at %dx%d, set to wait for snapshot&quot;, this, document().topDocument().baseURL().host().utf8().data(), url.host().utf8().data(), contentWidth, contentHeight);
</ins><span class="cx">     m_snapshotDecision = Snapshotted;
</span><span class="cx">     setDisplayState(WaitingForSnapshot);
</span><span class="cx"> }
</span><span class="lines">@@ -774,4 +797,21 @@
</span><span class="cx">     return loader.requestObject(*this, url, getNameAttribute(), mimeType, paramNames, paramValues);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void HTMLPlugInImageElement::setNeedsImageReload(bool needsImageReload)
+{
+    if (m_needsImageReload == needsImageReload)
+        return;
+
+    m_needsImageReload = needsImageReload;
+
+    if (!needsImageReload)
+        document().decrementLoadEventDelayCount();
+    else {
+        // Called when a URL is set, triggering a new load.
+        // The actual load won't start until we recalculate style, which will tell us whether to load.
+        document().incrementLoadEventDelayCount();
+        setNeedsStyleRecalc(SyntheticStyleChange);
+    }
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLPlugInImageElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.h (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLPlugInImageElement.h        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.h        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2009, 2011, 2012, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -23,16 +23,13 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;HTMLPlugInElement.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;RenderStyle.h&quot;
-#include &lt;wtf/OwnPtr.h&gt;
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class HTMLImageLoader;
</span><del>-class HTMLVideoElement;
</del><span class="cx"> class FrameLoader;
</span><span class="cx"> class Image;
</span><span class="cx"> class MouseEvent;
</span><ins>+class RenderStyle;
</ins><span class="cx"> class Widget;
</span><span class="cx"> 
</span><span class="cx"> enum PluginCreationOption {
</span><span class="lines">@@ -40,12 +37,8 @@
</span><span class="cx">     CreateOnlyNonNetscapePlugins,
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-enum PreferPlugInsForImagesOption {
-    ShouldPreferPlugInsForImages,
-    ShouldNotPreferPlugInsForImages
-};
-
-// Base class for HTMLObjectElement and HTMLEmbedElement
</del><ins>+// Base class for HTMLAppletElement, HTMLEmbedElement, and HTMLObjectElement.
+// FIXME: Should HTMLAppletElement inherit from HTMLPlugInElement directly instead?
</ins><span class="cx"> class HTMLPlugInImageElement : public HTMLPlugInElement {
</span><span class="cx"> public:
</span><span class="cx">     virtual ~HTMLPlugInImageElement();
</span><span class="lines">@@ -104,56 +97,57 @@
</span><span class="cx">     SnapshotDecision snapshotDecision() const { return m_snapshotDecision; }
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><ins>+    enum PreferPlugInsForImagesOption { ShouldPreferPlugInsForImages, ShouldNotPreferPlugInsForImages };
</ins><span class="cx">     HTMLPlugInImageElement(const QualifiedName&amp; tagName, Document&amp;, bool createdByParser, PreferPlugInsForImagesOption);
</span><span class="cx"> 
</span><ins>+    virtual void removedFrom(ContainerNode&amp;) override;
+    virtual void didMoveToNewDocument(Document* oldDocument) override;
+    virtual bool requestObject(const String&amp; url, const String&amp; mimeType, const Vector&lt;String&gt;&amp; paramNames, const Vector&lt;String&gt;&amp; paramValues) override final;
+
</ins><span class="cx">     bool isImageType();
</span><ins>+    HTMLImageLoader* imageLoader() { return m_imageLoader.get(); }
+    void updateImageLoaderWithNewURLSoon() { setNeedsImageReload(true); }
</ins><span class="cx"> 
</span><del>-    OwnPtr&lt;HTMLImageLoader&gt; m_imageLoader;
-    String m_serviceType;
-    String m_url;
-    URL m_loadedUrl;
-
-    static void updateWidgetCallback(Node&amp;, unsigned);
-    static void startLoadingImageCallback(Node&amp;, unsigned);
-
-    virtual void didAttachRenderers() override;
-    virtual void willDetachRenderers() override;
-
</del><span class="cx">     bool allowedToLoadFrameURL(const String&amp; url);
</span><span class="cx">     bool wouldLoadAsNetscapePlugin(const String&amp; url, const String&amp; serviceType);
</span><span class="cx"> 
</span><del>-    virtual void didMoveToNewDocument(Document* oldDocument) override;
</del><ins>+    String m_serviceType;
+    String m_url;
</ins><span class="cx"> 
</span><del>-    virtual void documentWillSuspendForPageCache() override;
-    virtual void documentDidResumeFromPageCache() override;
</del><ins>+private:
+    virtual bool isPlugInImageElement() const override final { return true; }
+    virtual bool isRestartedPlugin() const override final { return m_isRestartedPlugin; }
</ins><span class="cx"> 
</span><del>-    virtual bool isRestartedPlugin() const override { return m_isRestartedPlugin; }
-    virtual bool requestObject(const String&amp; url, const String&amp; mimeType, const Vector&lt;String&gt;&amp; paramNames, const Vector&lt;String&gt;&amp; paramValues) override;
</del><ins>+    virtual void finishParsingChildren() override final;
+    virtual void didAddUserAgentShadowRoot(ShadowRoot*) override final;
</ins><span class="cx"> 
</span><del>-private:
</del><span class="cx">     virtual RenderPtr&lt;RenderElement&gt; createElementRenderer(PassRef&lt;RenderStyle&gt;) override;
</span><del>-    virtual bool willRecalcStyle(Style::Change) override;
</del><ins>+    virtual bool willRecalcStyle(Style::Change) override final;
+    virtual void didRecalcStyle(Style::Change styleChange) override final;
+    virtual void didAttachRenderers() override final;
+    virtual void willDetachRenderers() override final;
</ins><span class="cx"> 
</span><del>-    virtual void didAddUserAgentShadowRoot(ShadowRoot*) override;
</del><ins>+    virtual void documentWillSuspendForPageCache() override final;
+    virtual void documentDidResumeFromPageCache() override final;
</ins><span class="cx"> 
</span><del>-    virtual void finishParsingChildren() override;
</del><ins>+    virtual void defaultEventHandler(Event*) override final;
+    virtual void dispatchPendingMouseClick() override final;
</ins><span class="cx"> 
</span><del>-    void updateWidgetIfNecessary();
-    void startLoadingImage();
</del><ins>+    virtual void updateSnapshot(PassRefPtr&lt;Image&gt;) override final;
</ins><span class="cx"> 
</span><del>-    virtual void updateSnapshot(PassRefPtr&lt;Image&gt;) override;
-    virtual void dispatchPendingMouseClick() override;
</del><ins>+    void setNeedsImageReload(bool);
+    void scheduleUpdateForAfterStyleResolution();
+    void updateAfterStyleResolution();
+
</ins><span class="cx">     void simulatedMouseClickTimerFired(DeferrableOneShotTimer&lt;HTMLPlugInImageElement&gt;&amp;);
</span><span class="cx"> 
</span><span class="cx">     void restartSimilarPlugIns();
</span><del>-
-    virtual bool isPlugInImageElement() const override { return true; }
-
</del><span class="cx">     void removeSnapshotTimerFired(Timer&lt;HTMLPlugInImageElement&gt;&amp;);
</span><span class="cx"> 
</span><del>-    virtual void defaultEventHandler(Event*) override;
-
</del><ins>+    std::unique_ptr&lt;HTMLImageLoader&gt; m_imageLoader;
+    URL m_loadedUrl;
</ins><span class="cx">     bool m_needsWidgetUpdate;
</span><ins>+    bool m_needsImageReload;
</ins><span class="cx">     bool m_shouldPreferPlugInsForImages;
</span><span class="cx">     bool m_needsDocumentActivationCallbacks;
</span><span class="cx">     RefPtr&lt;MouseEvent&gt; m_pendingClickEventFromSnapshot;
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleResolveTreecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleResolveTree.cpp (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleResolveTree.cpp        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/style/StyleResolveTree.cpp        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -29,20 +29,21 @@
</span><span class="cx"> #include &quot;AXObjectCache.h&quot;
</span><span class="cx"> #include &quot;AnimationController.h&quot;
</span><span class="cx"> #include &quot;CSSFontSelector.h&quot;
</span><del>-#include &quot;Element.h&quot;
</del><span class="cx"> #include &quot;ElementIterator.h&quot;
</span><span class="cx"> #include &quot;ElementRareData.h&quot;
</span><span class="cx"> #include &quot;FlowThreadController.h&quot;
</span><span class="cx"> #include &quot;InsertionPoint.h&quot;
</span><ins>+#include &quot;LoaderStrategy.h&quot;
</ins><span class="cx"> #include &quot;NodeRenderStyle.h&quot;
</span><span class="cx"> #include &quot;NodeRenderingTraversal.h&quot;
</span><span class="cx"> #include &quot;NodeTraversal.h&quot;
</span><del>-#include &quot;RenderElement.h&quot;
</del><ins>+#include &quot;PlatformStrategies.h&quot;
</ins><span class="cx"> #include &quot;RenderFullScreen.h&quot;
</span><span class="cx"> #include &quot;RenderNamedFlowThread.h&quot;
</span><span class="cx"> #include &quot;RenderText.h&quot;
</span><span class="cx"> #include &quot;RenderView.h&quot;
</span><span class="cx"> #include &quot;RenderWidget.h&quot;
</span><ins>+#include &quot;ResourceLoadScheduler.h&quot;
</ins><span class="cx"> #include &quot;Settings.h&quot;
</span><span class="cx"> #include &quot;ShadowRoot.h&quot;
</span><span class="cx"> #include &quot;StyleResolveForDocument.h&quot;
</span><span class="lines">@@ -504,7 +505,7 @@
</span><span class="cx">     current.clearAfterPseudoElement();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool needsPseudeElement(Element&amp; current, PseudoId pseudoId)
</del><ins>+static bool needsPseudoElement(Element&amp; current, PseudoId pseudoId)
</ins><span class="cx"> {
</span><span class="cx">     if (!current.document().styleSheetCollection().usesBeforeAfterRules())
</span><span class="cx">         return false;
</span><span class="lines">@@ -519,7 +520,7 @@
</span><span class="cx"> 
</span><span class="cx"> static void attachBeforeOrAfterPseudoElementIfNeeded(Element&amp; current, PseudoId pseudoId)
</span><span class="cx"> {
</span><del>-    if (!needsPseudeElement(current, pseudoId))
</del><ins>+    if (!needsPseudoElement(current, pseudoId))
</ins><span class="cx">         return;
</span><span class="cx">     RefPtr&lt;PseudoElement&gt; pseudoElement = PseudoElement::create(current, pseudoId);
</span><span class="cx">     setBeforeOrAfterPseudoElement(current, pseudoElement, pseudoId);
</span><span class="lines">@@ -528,7 +529,7 @@
</span><span class="cx"> 
</span><span class="cx"> static void attachRenderTree(Element&amp; current, ContainerNode&amp; renderingParentNode, PassRefPtr&lt;RenderStyle&gt; resolvedStyle)
</span><span class="cx"> {
</span><del>-    PostAttachCallbackDisabler callbackDisabler(current.document());
</del><ins>+    PostResolutionCallbackDisabler callbackDisabler(current.document());
</ins><span class="cx">     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
</span><span class="cx"> 
</span><span class="cx">     if (current.hasCustomStyleResolveCallbacks())
</span><span class="lines">@@ -741,7 +742,7 @@
</span><span class="cx"> static void updateBeforeOrAfterPseudoElement(Element&amp; current, Change change, PseudoId pseudoId)
</span><span class="cx"> {
</span><span class="cx">     if (PseudoElement* existingPseudoElement = beforeOrAfterPseudoElement(current, pseudoId)) {
</span><del>-        if (needsPseudeElement(current, pseudoId))
</del><ins>+        if (needsPseudoElement(current, pseudoId))
</ins><span class="cx">             resolveTree(*existingPseudoElement, current, current.needsStyleRecalc() ? Force : change);
</span><span class="cx">         else
</span><span class="cx">             clearBeforeOrAfterPseudoElement(current, pseudoId);
</span><span class="lines">@@ -904,5 +905,66 @@
</span><span class="cx">     detachRenderTree(element, NormalDetach);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static Vector&lt;std::function&lt;void ()&gt;&gt;&amp; postResolutionCallbackQueue()
+{
+    static NeverDestroyed&lt;Vector&lt;std::function&lt;void ()&gt;&gt;&gt; vector;
+    return vector;
</ins><span class="cx"> }
</span><ins>+
+void queuePostResolutionCallback(std::function&lt;void ()&gt; callback)
+{
+    postResolutionCallbackQueue().append(callback);
</ins><span class="cx"> }
</span><ins>+
+static void suspendMemoryCacheClientCalls(Document&amp; document)
+{
+    Page* page = document.page();
+    if (!page || !page-&gt;areMemoryCacheClientCallsEnabled())
+        return;
+
+    page-&gt;setMemoryCacheClientCallsEnabled(false);
+
+    RefPtr&lt;Document&gt; protectedDocument = &amp;document;
+    postResolutionCallbackQueue().append([protectedDocument]{
+        // FIXME: If the document becomes unassociated with the page during style resolution
+        // then this won't work and the memory cache client calls will be permanently disabled.
+        if (Page* page = protectedDocument-&gt;page())
+            page-&gt;setMemoryCacheClientCallsEnabled(true);
+    });
+}
+
+static unsigned resolutionNestingDepth;
+
+PostResolutionCallbackDisabler::PostResolutionCallbackDisabler(Document&amp; document)
+{
+    ++resolutionNestingDepth;
+
+    if (resolutionNestingDepth == 1)
+        platformStrategies()-&gt;loaderStrategy()-&gt;resourceLoadScheduler()-&gt;suspendPendingRequests();
+
+    // FIXME: It's strange to build this into the disabler.
+    suspendMemoryCacheClientCalls(document);
+}
+
+PostResolutionCallbackDisabler::~PostResolutionCallbackDisabler()
+{
+    if (resolutionNestingDepth == 1) {
+        // Get size each time through the loop because a callback can add more callbacks to the end of the queue.
+        auto&amp; queue = postResolutionCallbackQueue();
+        for (size_t i = 0; i &lt; queue.size(); ++i)
+            queue[i]();
+        queue.clear();
+
+        platformStrategies()-&gt;loaderStrategy()-&gt;resourceLoadScheduler()-&gt;resumePendingRequests();
+    }
+
+    --resolutionNestingDepth;
+}
+
+bool postResolutionCallbacksAreSuspended()
+{
+    return resolutionNestingDepth;
+}
+
+}
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorestyleStyleResolveTreeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleResolveTree.h (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleResolveTree.h        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebCore/style/StyleResolveTree.h        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -26,6 +26,8 @@
</span><span class="cx"> #ifndef StyleResolveTree_h
</span><span class="cx"> #define StyleResolveTree_h
</span><span class="cx"> 
</span><ins>+#include &lt;functional&gt;
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class Document;
</span><span class="lines">@@ -47,6 +49,15 @@
</span><span class="cx"> 
</span><span class="cx"> Change determineChange(const RenderStyle*, const RenderStyle*);
</span><span class="cx"> 
</span><ins>+void queuePostResolutionCallback(std::function&lt;void ()&gt;);
+bool postResolutionCallbacksAreSuspended();
+
+class PostResolutionCallbackDisabler {
+public:
+    explicit PostResolutionCallbackDisabler(Document&amp;);
+    ~PostResolutionCallbackDisabler();
+};
+
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebKit/mac/ChangeLog        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2014-03-23  Darin Adler  &lt;darin@apple.com&gt;
+
+        Remove code in HTMLObjectElement attribute parsing that forces style resolution and layout
+        https://bugs.webkit.org/show_bug.cgi?id=130653
+
+        Reviewed by Antti Koivisto.
+
+        * WebCoreSupport/WebFrameLoaderClient.mm: Call toHTMLPlugInImageElement instead of
+        doing a static_cast.
+
</ins><span class="cx"> 2014-03-21  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Don't flush compositing layers within FrameView::willPaintContents()
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebCoreSupportWebFrameLoaderClientmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm (166143 => 166144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm        2014-03-23 20:17:36 UTC (rev 166143)
+++ trunk/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm        2014-03-23 21:37:56 UTC (rev 166144)
</span><span class="lines">@@ -2106,8 +2106,7 @@
</span><span class="cx"> 
</span><span class="cx">                     if (element-&gt;hasTagName(HTMLNames::embedTag) || element-&gt;hasTagName(HTMLNames::objectTag)) {
</span><span class="cx">                         // Create a shadow subtree for the plugin element, the iframe player is injected in the shadow tree.
</span><del>-                        HTMLPlugInImageElement* pluginElement = static_cast&lt;HTMLPlugInImageElement*&gt;(element);
-                        pluginElement-&gt;createShadowIFrameSubtree(embedSrc);
</del><ins>+                        toHTMLPlugInImageElement(*element).createShadowIFrameSubtree(embedSrc);
</ins><span class="cx">                         return nullptr;
</span><span class="cx">                     }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>