<!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 <matthew_hanson@apple.com>
</span><span class="cx">
</span><ins>+ Merge r153829
+
+ 2013-08-08 Andreas Kling <akling@apple.com>
+
+ Inserting multiple rules into an empty style sheet should avoid style recalc if possible.
+ <http://webkit.org/b/119568>
+
+ Reviewed by Antti Koivisto.
+
+ As a follow-up to <http://webkit.org/b/119475>, 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 "needs update.") 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 <matthew_hanson@apple.com>
+
</ins><span class="cx"> Merge r159970.
</span><span class="cx">
</span><span class="cx"> 2013-12-02 Brady Eidson <beidson@apple.com>
</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 "CSSStyleRule.h"
</span><span class="cx"> #include "CachedCSSStyleSheet.h"
</span><span class="cx"> #include "Document.h"
</span><ins>+#include "DocumentStyleSheetCollection.h"
</ins><span class="cx"> #include "ExceptionCode.h"
</span><span class="cx"> #include "HTMLNames.h"
</span><span class="cx"> #include "MediaList.h"
</span><span class="lines">@@ -125,12 +126,12 @@
</span><span class="cx"> m_contents->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->hasOneClient() && !m_contents->isInMemoryCache()) {
</span><span class="cx"> m_contents->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->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->isMutable());
</span><span class="cx"> ASSERT(m_contents->hasOneClient());
</span><ins>+ didMutate();
+}
</ins><span class="cx">
</span><ins>+void CSSStyleSheet::didMutateRules(RuleMutationType mutationType, WhetherContentsWereClonedForMutation contentsWereClonedForMutation)
+{
+ ASSERT(m_contents->isMutable());
+ ASSERT(m_contents->hasOneClient());
+
</ins><span class="cx"> Document* owner = ownerDocument();
</span><span class="cx"> if (!owner)
</span><span class="cx"> return;
</span><del>- owner->styleResolverChanged(mutationType == InsertionIntoEmptySheet ? DeferRecalcStyleIfNeeded : DeferRecalcStyle);
</del><ins>+
+ if (mutationType == RuleInsertion && !contentsWereClonedForMutation && !owner->styleSheetCollection()->activeStyleSheetsContains(this)) {
+ owner->scheduleOptimizedStyleSheetUpdate();
+ return;
+ }
+
+ owner->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->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->willMutateRules();
</ins><span class="cx"> }
</span><ins>+
+CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSRule* rule)
+ : m_styleSheet(rule ? rule->parentStyleSheet() : 0)
+ , m_mutationType(OtherMutation)
+ , m_contentsWereClonedForMutation(ContentsWereNotClonedForMutation)
+{
+ if (m_styleSheet)
+ m_contentsWereClonedForMutation = m_styleSheet->willMutateRules();
+}
+
+CSSStyleSheet::RuleMutationScope::~RuleMutationScope()
+{
+ if (m_styleSheet)
+ m_styleSheet->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<MediaQuerySet>);
</span><span class="cx"> void setTitle(const String& 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<CSSRuleList> 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->willMutateRules();
-}
-
-inline CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSRule* rule)
- : m_styleSheet(rule ? rule->parentStyleSheet() : 0)
- , m_mutationType(OtherMutation)
-{
- if (m_styleSheet)
- m_styleSheet->willMutateRules();
-}
-
-inline CSSStyleSheet::RuleMutationScope::~RuleMutationScope()
-{
- if (m_styleSheet)
- m_styleSheet->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 && m_parentRule->parentStyleSheet())
</span><del>- m_parentRule->parentStyleSheet()->didMutateRules();
</del><ins>+ m_parentRule->parentStyleSheet()->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, &Document::optimizedStyleSheetUpdateTimerFired)
</ins><span class="cx"> , m_styleRecalcTimer(this, &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->needsUpdateActiveStylesheetsOnStyleRecalc())
- m_styleSheetCollection->updateActiveStyleSheets(DocumentStyleSheetCollection::FullUpdate);
</del><ins>+ m_styleSheetCollection->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()->isInLayout() && !view()->isPainting()));
</span><del>-
</del><ins>+
+ if (m_optimizedStyleSheetUpdateTimer.isActive())
+ styleResolverChanged(RecalcStyleIfNeeded);
+
</ins><span class="cx"> if ((!m_pendingStyleRecalcShouldForce && !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->styleResolverChanged();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void Document::optimizedStyleSheetUpdateTimerFired(Timer<Document>*)
+{
+ styleResolverChanged(RecalcStyleIfNeeded);
+}
+
+void Document::scheduleOptimizedStyleSheetUpdate()
+{
+ if (m_optimizedStyleSheetUpdateTimer.isActive())
+ return;
+ styleSheetCollection()->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 && !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<Document>*);
</span><ins>+ void optimizedStyleSheetUpdateTimerFired(Timer<Document>*);
</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<Document> m_optimizedStyleSheetUpdateTimer;
</ins><span class="cx"> Timer<Document> 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 <use> 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->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->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<const CSSStyleSheet*>);
+ for (unsigned i = 0; i < m_activeAuthorStyleSheets.size(); ++i)
+ m_weakCopyOfActiveStyleSheetListForFastLookup->add(m_activeAuthorStyleSheets[i].get());
+ }
+ return m_weakCopyOfActiveStyleSheetListForFastLookup->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<StyleSheetContents> authorSheet);
</span><span class="cx"> void addUserSheet(PassRefPtr<StyleSheetContents> 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 > 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<RefPtr<StyleSheet> > m_styleSheetsForStyleSheetList;
</span><span class="cx"> Vector<RefPtr<CSSStyleSheet> > m_activeAuthorStyleSheets;
</span><span class="cx">
</span><ins>+ // This is a mirror of m_activeAuthorStyleSheets that gets populated on demand for activeStyleSheetsContains().
+ mutable OwnPtr<HashSet<const CSSStyleSheet*>> 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<RefPtr<CSSStyleSheet> > 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<Node*, 32> StyleSheetCandidateListHashSet;
</span><span class="cx"> StyleSheetCandidateListHashSet m_styleSheetCandidateNodes;
</span></span></pre>
</div>
</div>
</body>
</html>