<!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>[165136] branches/safari-537.75-branch/Source/WebCore</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/153829">r153829</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari53775branchSourceWebCoreChangeLog">branches/safari-537.75-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari53775branchSourceWebCorecssCSSStyleSheetcpp">branches/safari-537.75-branch/Source/WebCore/css/CSSStyleSheet.cpp</a></li>
<li><a href="#branchessafari53775branchSourceWebCorecssCSSStyleSheeth">branches/safari-537.75-branch/Source/WebCore/css/CSSStyleSheet.h</a></li>
<li><a href="#branchessafari53775branchSourceWebCorecssPropertySetCSSStyleDeclarationcpp">branches/safari-537.75-branch/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp</a></li>
<li><a href="#branchessafari53775branchSourceWebCoredomDocumentcpp">branches/safari-537.75-branch/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#branchessafari53775branchSourceWebCoredomDocumenth">branches/safari-537.75-branch/Source/WebCore/dom/Document.h</a></li>
<li><a href="#branchessafari53775branchSourceWebCoredomDocumentStyleSheetCollectioncpp">branches/safari-537.75-branch/Source/WebCore/dom/DocumentStyleSheetCollection.cpp</a></li>
<li><a href="#branchessafari53775branchSourceWebCoredomDocumentStyleSheetCollectionh">branches/safari-537.75-branch/Source/WebCore/dom/DocumentStyleSheetCollection.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari53775branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-537.75-branch/Source/WebCore/ChangeLog (165135 => 165136)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-537.75-branch/Source/WebCore/ChangeLog        2014-03-05 23:33:21 UTC (rev 165135)
+++ branches/safari-537.75-branch/Source/WebCore/ChangeLog        2014-03-05 23:35:14 UTC (rev 165136)
</span><span class="lines">@@ -1,5 +1,89 @@
</span><span class="cx"> 2014-03-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r153829
+
+    2013-08-08  Andreas Kling  &lt;akling@apple.com&gt;
+
+            Inserting multiple rules into an empty style sheet should avoid style recalc if possible.
+            &lt;http://webkit.org/b/119568&gt;
+
+            Reviewed by Antti Koivisto.
+
+            As a follow-up to &lt;http://webkit.org/b/119475&gt;, where I added a hack for inserting
+            a single rule into an empty style sheet, this broadens the optimization to support
+            any number of rules.
+
+            This optimizes the scenario where a style sheet is added to the DOM and then populated
+            rule-by-rule via CSSOM insertRule()/addRule() calls. Previously we'd do a full style
+            recalc for this case, but now we'll treat it the same as a full sheet added at once.
+
+            * css/CSSStyleSheet.h:
+            * css/CSSStyleSheet.cpp:
+            (WebCore::CSSStyleSheet::willMutateRules):
+
+                Made willMutateRules() return whether the style sheet contents were cloned by the
+                copy-on-write mechanism.
+
+            * dom/Document.h:
+            (WebCore::CSSStyleSheet::didMutateRules):
+            (WebCore::CSSStyleSheet::insertRule):
+
+                Replaced the InsertionIntoEmptySheet mutation type by a general RuleInsertion.
+                The mutation callback checks if we're inserting into a rule that's not (yet) part
+                of the document's active sheet set. In that case, we defer doing the style sheet
+                until all the insertions are done (or something forces us to style+layout.)
+
+                Note that this optimization only happens if the style sheet had a single client.
+                Shared style sheets that just got cloned before mutation may have pointers into
+                them from the Document's StyleResolver, so we're forced to do an immediate sheet
+                update in that case.
+
+            (WebCore::CSSStyleSheet::RuleMutationScope::RuleMutationScope):
+            (WebCore::CSSStyleSheet::RuleMutationScope::~RuleMutationScope):
+
+                Moved these out-of-line.
+
+            (WebCore::CSSStyleSheet::didMutateRuleFromCSSStyleDeclaration):
+            * css/PropertySetCSSStyleDeclaration.cpp:
+            (WebCore::StyleRuleCSSStyleDeclaration::didMutate):
+
+                Made a separate mutation callback for CSSStyleDeclaration since its needs are
+                so simple compared to the mutation callback from CSSStyleSheet. Seems better
+                than adding yet another mode to the enum.
+
+            * dom/Document.cpp:
+            (WebCore::Document::Document):
+            (WebCore::Document::recalcStyle):
+            (WebCore::Document::styleResolverChanged):
+            (WebCore::Document::optimizedStyleSheetUpdateTimerFired):
+            (WebCore::Document::scheduleOptimizedStyleSheetUpdate):
+
+                Added mechanism to defer doing a RecalcStyleIfNeeded.
+
+            (WebCore::Document::updateStyleIfNeeded):
+
+                Synchronize the optimized style sheet update if there's one scheduled.
+                This ensures that stuff like layout-dependent property access won't operate
+                on stale style.
+
+            * dom/DocumentStyleSheetCollection.h:
+            (WebCore::DocumentStyleSheetCollection::pendingUpdateType):
+            (WebCore::DocumentStyleSheetCollection::setPendingUpdateType):
+            (WebCore::DocumentStyleSheetCollection::flushPendingUpdates):
+            * dom/DocumentStyleSheetCollection.cpp:
+            (WebCore::DocumentStyleSheetCollection::DocumentStyleSheetCollection):
+            (WebCore::DocumentStyleSheetCollection::updateActiveStyleSheets):
+
+                Have DSSC track the kind of style sheet update it needs to do (instead of just
+                a boolean &quot;needs update.&quot;) This is used by Document::recalcStyle() to make sure
+                the right kind of update happens if there's one scheduled.
+
+            (WebCore::DocumentStyleSheetCollection::activeStyleSheetsContains):
+
+                Added helper to check if a CSSStyleSheet is part of the active set.
+
+2014-03-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r159970.
</span><span class="cx"> 
</span><span class="cx">     2013-12-02  Brady Eidson  &lt;beidson@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari53775branchSourceWebCorecssCSSStyleSheetcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-537.75-branch/Source/WebCore/css/CSSStyleSheet.cpp (165135 => 165136)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-537.75-branch/Source/WebCore/css/CSSStyleSheet.cpp        2014-03-05 23:33:21 UTC (rev 165135)
+++ branches/safari-537.75-branch/Source/WebCore/css/CSSStyleSheet.cpp        2014-03-05 23:35:14 UTC (rev 165136)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
</span><del>- * Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2004, 2006, 2007, 2012, 2013 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">@@ -29,6 +29,7 @@
</span><span class="cx"> #include &quot;CSSStyleRule.h&quot;
</span><span class="cx"> #include &quot;CachedCSSStyleSheet.h&quot;
</span><span class="cx"> #include &quot;Document.h&quot;
</span><ins>+#include &quot;DocumentStyleSheetCollection.h&quot;
</ins><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;MediaList.h&quot;
</span><span class="lines">@@ -125,12 +126,12 @@
</span><span class="cx">     m_contents-&gt;unregisterClient(this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSStyleSheet::willMutateRules()
</del><ins>+CSSStyleSheet::WhetherContentsWereClonedForMutation CSSStyleSheet::willMutateRules()
</ins><span class="cx"> {
</span><span class="cx">     // If we are the only client it is safe to mutate.
</span><span class="cx">     if (m_contents-&gt;hasOneClient() &amp;&amp; !m_contents-&gt;isInMemoryCache()) {
</span><span class="cx">         m_contents-&gt;setMutable();
</span><del>-        return;
</del><ins>+        return ContentsWereNotClonedForMutation;
</ins><span class="cx">     }
</span><span class="cx">     // Only cacheable stylesheets should have multiple clients.
</span><span class="cx">     ASSERT(m_contents-&gt;isCacheable());
</span><span class="lines">@@ -144,17 +145,32 @@
</span><span class="cx"> 
</span><span class="cx">     // Any existing CSSOM wrappers need to be connected to the copied child rules.
</span><span class="cx">     reattachChildRuleCSSOMWrappers();
</span><ins>+
+    return ContentsWereClonedForMutation;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSStyleSheet::didMutateRules(RuleMutationType mutationType)
</del><ins>+void CSSStyleSheet::didMutateRuleFromCSSStyleDeclaration()
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_contents-&gt;isMutable());
</span><span class="cx">     ASSERT(m_contents-&gt;hasOneClient());
</span><ins>+    didMutate();
+}
</ins><span class="cx"> 
</span><ins>+void CSSStyleSheet::didMutateRules(RuleMutationType mutationType, WhetherContentsWereClonedForMutation contentsWereClonedForMutation)
+{
+    ASSERT(m_contents-&gt;isMutable());
+    ASSERT(m_contents-&gt;hasOneClient());
+
</ins><span class="cx">     Document* owner = ownerDocument();
</span><span class="cx">     if (!owner)
</span><span class="cx">         return;
</span><del>-    owner-&gt;styleResolverChanged(mutationType == InsertionIntoEmptySheet ? DeferRecalcStyleIfNeeded : DeferRecalcStyle);
</del><ins>+
+    if (mutationType == RuleInsertion &amp;&amp; !contentsWereClonedForMutation &amp;&amp; !owner-&gt;styleSheetCollection()-&gt;activeStyleSheetsContains(this)) {
+        owner-&gt;scheduleOptimizedStyleSheetUpdate();
+        return;
+    }
+
+    owner-&gt;styleResolverChanged(DeferRecalcStyle);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CSSStyleSheet::didMutate()
</span><span class="lines">@@ -278,8 +294,7 @@
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    RuleMutationType mutationType = !length() ? InsertionIntoEmptySheet : OtherMutation;
-    RuleMutationScope mutationScope(this, mutationType);
</del><ins>+    RuleMutationScope mutationScope(this, RuleInsertion);
</ins><span class="cx"> 
</span><span class="cx">     bool success = m_contents-&gt;wrapperInsertRule(rule, index);
</span><span class="cx">     if (!success) {
</span><span class="lines">@@ -385,4 +400,27 @@
</span><span class="cx">     m_childRuleCSSOMWrappers.clear();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSStyleSheet* sheet, RuleMutationType mutationType)
+    : m_styleSheet(sheet)
+    , m_mutationType(mutationType)
+{
+    ASSERT(m_styleSheet);
+    m_contentsWereClonedForMutation = m_styleSheet-&gt;willMutateRules();
</ins><span class="cx"> }
</span><ins>+
+CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSRule* rule)
+    : m_styleSheet(rule ? rule-&gt;parentStyleSheet() : 0)
+    , m_mutationType(OtherMutation)
+    , m_contentsWereClonedForMutation(ContentsWereNotClonedForMutation)
+{
+    if (m_styleSheet)
+        m_contentsWereClonedForMutation = m_styleSheet-&gt;willMutateRules();
+}
+
+CSSStyleSheet::RuleMutationScope::~RuleMutationScope()
+{
+    if (m_styleSheet)
+        m_styleSheet-&gt;didMutateRules(m_mutationType, m_contentsWereClonedForMutation);
+}
+
+}
</ins></span></pre></div>
<a id="branchessafari53775branchSourceWebCorecssCSSStyleSheeth"></a>
<div class="modfile"><h4>Modified: branches/safari-537.75-branch/Source/WebCore/css/CSSStyleSheet.h (165135 => 165136)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-537.75-branch/Source/WebCore/css/CSSStyleSheet.h        2014-03-05 23:33:21 UTC (rev 165135)
+++ branches/safari-537.75-branch/Source/WebCore/css/CSSStyleSheet.h        2014-03-05 23:35:14 UTC (rev 165136)
</span><span class="lines">@@ -85,7 +85,8 @@
</span><span class="cx">     void setMediaQueries(PassRefPtr&lt;MediaQuerySet&gt;);
</span><span class="cx">     void setTitle(const String&amp; title) { m_title = title; }
</span><span class="cx"> 
</span><del>-    enum RuleMutationType { OtherMutation, InsertionIntoEmptySheet };
</del><ins>+    enum RuleMutationType { OtherMutation, RuleInsertion };
+    enum WhetherContentsWereClonedForMutation { ContentsWereNotClonedForMutation = 0, ContentsWereClonedForMutation };
</ins><span class="cx"> 
</span><span class="cx">     class RuleMutationScope {
</span><span class="cx">         WTF_MAKE_NONCOPYABLE(RuleMutationScope);
</span><span class="lines">@@ -97,10 +98,12 @@
</span><span class="cx">     private:
</span><span class="cx">         CSSStyleSheet* m_styleSheet;
</span><span class="cx">         RuleMutationType m_mutationType;
</span><ins>+        WhetherContentsWereClonedForMutation m_contentsWereClonedForMutation;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><del>-    void willMutateRules();
-    void didMutateRules(RuleMutationType = OtherMutation);
</del><ins>+    WhetherContentsWereClonedForMutation willMutateRules();
+    void didMutateRules(RuleMutationType, WhetherContentsWereClonedForMutation);
+    void didMutateRuleFromCSSStyleDeclaration();
</ins><span class="cx">     void didMutate();
</span><span class="cx">     
</span><span class="cx">     void clearChildRuleCSSOMWrappers();
</span><span class="lines">@@ -131,28 +134,6 @@
</span><span class="cx">     mutable OwnPtr&lt;CSSRuleList&gt; m_ruleListCSSOMWrapper;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSStyleSheet* sheet, RuleMutationType mutationType)
-    : m_styleSheet(sheet)
-    , m_mutationType(mutationType)
-{
-    if (m_styleSheet)
-        m_styleSheet-&gt;willMutateRules();
-}
-
-inline CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSRule* rule)
-    : m_styleSheet(rule ? rule-&gt;parentStyleSheet() : 0)
-    , m_mutationType(OtherMutation)
-{
-    if (m_styleSheet)
-        m_styleSheet-&gt;willMutateRules();
-}
-
-inline CSSStyleSheet::RuleMutationScope::~RuleMutationScope()
-{
-    if (m_styleSheet)
-        m_styleSheet-&gt;didMutateRules(m_mutationType);
-}
-
</del><span class="cx"> } // namespace
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="branchessafari53775branchSourceWebCorecssPropertySetCSSStyleDeclarationcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-537.75-branch/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp (165135 => 165136)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-537.75-branch/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp        2014-03-05 23:33:21 UTC (rev 165135)
+++ branches/safari-537.75-branch/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp        2014-03-05 23:35:14 UTC (rev 165136)
</span><span class="lines">@@ -331,9 +331,9 @@
</span><span class="cx">     if (type == PropertyChanged)
</span><span class="cx">         m_cssomCSSValueClones.clear();
</span><span class="cx"> 
</span><del>-    // Style sheet mutation needs to be signaled even if the change failed. willMutateRules/didMutateRules must pair.
</del><ins>+    // Style sheet mutation needs to be signaled even if the change failed. willMutate*/didMutate* must pair.
</ins><span class="cx">     if (m_parentRule &amp;&amp; m_parentRule-&gt;parentStyleSheet())
</span><del>-        m_parentRule-&gt;parentStyleSheet()-&gt;didMutateRules();
</del><ins>+        m_parentRule-&gt;parentStyleSheet()-&gt;didMutateRuleFromCSSStyleDeclaration();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CSSStyleSheet* StyleRuleCSSStyleDeclaration::parentStyleSheet() const
</span></span></pre></div>
<a id="branchessafari53775branchSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-537.75-branch/Source/WebCore/dom/Document.cpp (165135 => 165136)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-537.75-branch/Source/WebCore/dom/Document.cpp        2014-03-05 23:33:21 UTC (rev 165135)
+++ branches/safari-537.75-branch/Source/WebCore/dom/Document.cpp        2014-03-05 23:35:14 UTC (rev 165136)
</span><span class="lines">@@ -419,6 +419,7 @@
</span><span class="cx">     , m_visuallyOrdered(false)
</span><span class="cx">     , m_readyState(Complete)
</span><span class="cx">     , m_bParsing(false)
</span><ins>+    , m_optimizedStyleSheetUpdateTimer(this, &amp;Document::optimizedStyleSheetUpdateTimerFired)
</ins><span class="cx">     , m_styleRecalcTimer(this, &amp;Document::styleRecalcTimerFired)
</span><span class="cx">     , m_pendingStyleRecalcShouldForce(false)
</span><span class="cx">     , m_inStyleRecalc(false)
</span><span class="lines">@@ -1763,8 +1764,7 @@
</span><span class="cx">     // re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
</span><span class="cx">     // hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
</span><span class="cx"> 
</span><del>-    if (m_styleSheetCollection-&gt;needsUpdateActiveStylesheetsOnStyleRecalc())
-        m_styleSheetCollection-&gt;updateActiveStyleSheets(DocumentStyleSheetCollection::FullUpdate);
</del><ins>+    m_styleSheetCollection-&gt;flushPendingUpdates();
</ins><span class="cx"> 
</span><span class="cx">     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
</span><span class="cx"> 
</span><span class="lines">@@ -1843,7 +1843,10 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx">     ASSERT(!view() || (!view()-&gt;isInLayout() &amp;&amp; !view()-&gt;isPainting()));
</span><del>-    
</del><ins>+
+    if (m_optimizedStyleSheetUpdateTimer.isActive())
+        styleResolverChanged(RecalcStyleIfNeeded);
+
</ins><span class="cx">     if ((!m_pendingStyleRecalcShouldForce &amp;&amp; !childNeedsStyleRecalc()) || inPageCache())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -3134,8 +3137,24 @@
</span><span class="cx">         m_mediaQueryMatcher-&gt;styleResolverChanged();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Document::optimizedStyleSheetUpdateTimerFired(Timer&lt;Document&gt;*)
+{
+    styleResolverChanged(RecalcStyleIfNeeded);
+}
+
+void Document::scheduleOptimizedStyleSheetUpdate()
+{
+    if (m_optimizedStyleSheetUpdateTimer.isActive())
+        return;
+    styleSheetCollection()-&gt;setPendingUpdateType(DocumentStyleSheetCollection::OptimizedUpdate);
+    m_optimizedStyleSheetUpdateTimer.startOneShot(0);
+}
+
</ins><span class="cx"> void Document::styleResolverChanged(StyleResolverUpdateFlag updateFlag)
</span><span class="cx"> {
</span><ins>+    if (m_optimizedStyleSheetUpdateTimer.isActive())
+        m_optimizedStyleSheetUpdateTimer.stop();
+
</ins><span class="cx">     // Don't bother updating, since we haven't loaded all our style info yet
</span><span class="cx">     // and haven't calculated the style selector for the first time.
</span><span class="cx">     if (!attached() || (!m_didCalculateStyleResolver &amp;&amp; !haveStylesheetsLoaded())) {
</span></span></pre></div>
<a id="branchessafari53775branchSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: branches/safari-537.75-branch/Source/WebCore/dom/Document.h (165135 => 165136)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-537.75-branch/Source/WebCore/dom/Document.h        2014-03-05 23:33:21 UTC (rev 165135)
+++ branches/safari-537.75-branch/Source/WebCore/dom/Document.h        2014-03-05 23:35:14 UTC (rev 165136)
</span><span class="lines">@@ -484,6 +484,8 @@
</span><span class="cx">      */
</span><span class="cx">     void styleResolverChanged(StyleResolverUpdateFlag);
</span><span class="cx"> 
</span><ins>+    void scheduleOptimizedStyleSheetUpdate();
+
</ins><span class="cx">     void didAccessStyleResolver();
</span><span class="cx"> 
</span><span class="cx">     void evaluateMediaQueryList();
</span><span class="lines">@@ -697,6 +699,7 @@
</span><span class="cx">     bool hasPendingStyleRecalc() const;
</span><span class="cx">     bool hasPendingForcedStyleRecalc() const;
</span><span class="cx">     void styleRecalcTimerFired(Timer&lt;Document&gt;*);
</span><ins>+    void optimizedStyleSheetUpdateTimerFired(Timer&lt;Document&gt;*);
</ins><span class="cx"> 
</span><span class="cx">     void registerNodeList(LiveNodeListBase*);
</span><span class="cx">     void unregisterNodeList(LiveNodeListBase*);
</span><span class="lines">@@ -1362,7 +1365,8 @@
</span><span class="cx">     bool m_visuallyOrdered;
</span><span class="cx">     ReadyState m_readyState;
</span><span class="cx">     bool m_bParsing;
</span><del>-    
</del><ins>+
+    Timer&lt;Document&gt; m_optimizedStyleSheetUpdateTimer;
</ins><span class="cx">     Timer&lt;Document&gt; m_styleRecalcTimer;
</span><span class="cx">     bool m_pendingStyleRecalcShouldForce;
</span><span class="cx">     bool m_inStyleRecalc;
</span></span></pre></div>
<a id="branchessafari53775branchSourceWebCoredomDocumentStyleSheetCollectioncpp"></a>
<div class="modfile"><h4>Modified: branches/safari-537.75-branch/Source/WebCore/dom/DocumentStyleSheetCollection.cpp (165135 => 165136)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-537.75-branch/Source/WebCore/dom/DocumentStyleSheetCollection.cpp        2014-03-05 23:33:21 UTC (rev 165135)
+++ branches/safari-537.75-branch/Source/WebCore/dom/DocumentStyleSheetCollection.cpp        2014-03-05 23:35:14 UTC (rev 165136)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx">     , m_pendingStylesheets(0)
</span><span class="cx">     , m_injectedStyleSheetCacheValid(false)
</span><span class="cx">     , m_hadActiveLoadingStylesheet(false)
</span><del>-    , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
</del><ins>+    , m_pendingUpdateType(NoUpdate)
</ins><span class="cx">     , m_usesSiblingRules(false)
</span><span class="cx">     , m_usesSiblingRulesOverride(false)
</span><span class="cx">     , m_usesFirstLineRules(false)
</span><span class="lines">@@ -453,7 +453,7 @@
</span><span class="cx">         // SVG &lt;use&gt; element may manage to invalidate style selector in the middle of a style recalc.
</span><span class="cx">         // https://bugs.webkit.org/show_bug.cgi?id=54344
</span><span class="cx">         // FIXME: This should be fixed in SVG and the call site replaced by ASSERT(!m_inStyleRecalc).
</span><del>-        m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
</del><ins>+        m_pendingUpdateType = FullUpdate;
</ins><span class="cx">         m_document-&gt;scheduleForcedStyleRecalc();
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="lines">@@ -487,15 +487,27 @@
</span><span class="cx">         }
</span><span class="cx">         resetCSSFeatureFlags();
</span><span class="cx">     }
</span><ins>+
+    m_weakCopyOfActiveStyleSheetListForFastLookup.clear();
</ins><span class="cx">     m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
</span><span class="cx">     m_styleSheetsForStyleSheetList.swap(activeStyleSheets);
</span><span class="cx"> 
</span><span class="cx">     m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
</span><del>-    m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
</del><ins>+    m_pendingUpdateType = NoUpdate;
</ins><span class="cx"> 
</span><span class="cx">     m_document-&gt;notifySeamlessChildDocumentsOfStylesheetUpdate();
</span><span class="cx"> 
</span><span class="cx">     return requiresFullStyleRecalc;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool DocumentStyleSheetCollection::activeStyleSheetsContains(const CSSStyleSheet* sheet) const
+{
+    if (!m_weakCopyOfActiveStyleSheetListForFastLookup) {
+        m_weakCopyOfActiveStyleSheetListForFastLookup = adoptPtr(new HashSet&lt;const CSSStyleSheet*&gt;);
+        for (unsigned i = 0; i &lt; m_activeAuthorStyleSheets.size(); ++i)
+            m_weakCopyOfActiveStyleSheetListForFastLookup-&gt;add(m_activeAuthorStyleSheets[i].get());
+    }
+    return m_weakCopyOfActiveStyleSheetListForFastLookup-&gt;contains(sheet);
</ins><span class="cx"> }
</span><ins>+
+}
</ins></span></pre></div>
<a id="branchessafari53775branchSourceWebCoredomDocumentStyleSheetCollectionh"></a>
<div class="modfile"><h4>Modified: branches/safari-537.75-branch/Source/WebCore/dom/DocumentStyleSheetCollection.h (165135 => 165136)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-537.75-branch/Source/WebCore/dom/DocumentStyleSheetCollection.h        2014-03-05 23:33:21 UTC (rev 165135)
+++ branches/safari-537.75-branch/Source/WebCore/dom/DocumentStyleSheetCollection.h        2014-03-05 23:35:14 UTC (rev 165136)
</span><span class="lines">@@ -71,9 +71,21 @@
</span><span class="cx">     void addAuthorSheet(PassRefPtr&lt;StyleSheetContents&gt; authorSheet);
</span><span class="cx">     void addUserSheet(PassRefPtr&lt;StyleSheetContents&gt; userSheet);
</span><span class="cx"> 
</span><del>-    bool needsUpdateActiveStylesheetsOnStyleRecalc() const { return m_needsUpdateActiveStylesheetsOnStyleRecalc; }
</del><ins>+    enum UpdateFlag { NoUpdate = 0, OptimizedUpdate, FullUpdate };
</ins><span class="cx"> 
</span><del>-    enum UpdateFlag { FullUpdate, OptimizedUpdate };
</del><ins>+    UpdateFlag pendingUpdateType() const { return m_pendingUpdateType; }
+    void setPendingUpdateType(UpdateFlag updateType)
+    {
+        if (updateType &gt; m_pendingUpdateType)
+            m_pendingUpdateType = updateType;
+    }
+
+    void flushPendingUpdates()
+    {
+        if (m_pendingUpdateType != NoUpdate)
+            updateActiveStyleSheets(m_pendingUpdateType);
+    }
+
</ins><span class="cx">     bool updateActiveStyleSheets(UpdateFlag);
</span><span class="cx"> 
</span><span class="cx">     String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
</span><span class="lines">@@ -103,6 +115,8 @@
</span><span class="cx">     void combineCSSFeatureFlags();
</span><span class="cx">     void resetCSSFeatureFlags();
</span><span class="cx"> 
</span><ins>+    bool activeStyleSheetsContains(const CSSStyleSheet*) const;
+
</ins><span class="cx"> private:
</span><span class="cx">     DocumentStyleSheetCollection(Document*);
</span><span class="cx"> 
</span><span class="lines">@@ -119,6 +133,9 @@
</span><span class="cx">     Vector&lt;RefPtr&lt;StyleSheet&gt; &gt; m_styleSheetsForStyleSheetList;
</span><span class="cx">     Vector&lt;RefPtr&lt;CSSStyleSheet&gt; &gt; m_activeAuthorStyleSheets;
</span><span class="cx"> 
</span><ins>+    // This is a mirror of m_activeAuthorStyleSheets that gets populated on demand for activeStyleSheetsContains().
+    mutable OwnPtr&lt;HashSet&lt;const CSSStyleSheet*&gt;&gt; m_weakCopyOfActiveStyleSheetListForFastLookup;
+
</ins><span class="cx">     // Track the number of currently loading top-level stylesheets needed for rendering.
</span><span class="cx">     // Sheets loaded using the @import directive are not included in this count.
</span><span class="cx">     // We use this count of pending sheets to detect when we can begin attaching
</span><span class="lines">@@ -135,7 +152,7 @@
</span><span class="cx">     Vector&lt;RefPtr&lt;CSSStyleSheet&gt; &gt; m_authorStyleSheets;
</span><span class="cx"> 
</span><span class="cx">     bool m_hadActiveLoadingStylesheet;
</span><del>-    bool m_needsUpdateActiveStylesheetsOnStyleRecalc;
</del><ins>+    UpdateFlag m_pendingUpdateType;
</ins><span class="cx"> 
</span><span class="cx">     typedef ListHashSet&lt;Node*, 32&gt; StyleSheetCandidateListHashSet;
</span><span class="cx">     StyleSheetCandidateListHashSet m_styleSheetCandidateNodes;
</span></span></pre>
</div>
</div>

</body>
</html>