Index: Source/core/css/StyleSheetContents.cpp |
diff --git a/Source/core/css/StyleSheetContents.cpp b/Source/core/css/StyleSheetContents.cpp |
index 1aaebadb081e285fc1f97ba2be4b6f7a4017fa00..d6526dc72912c4533291d615cf3ccdbd7680fd45 100644 |
--- a/Source/core/css/StyleSheetContents.cpp |
+++ b/Source/core/css/StyleSheetContents.cpp |
@@ -374,10 +374,8 @@ bool StyleSheetContents::loadCompleted() const |
return parentSheet->loadCompleted(); |
StyleSheetContents* root = rootStyleSheet(); |
- for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end(); ++it) { |
- if (!(*it)->loadCompleted()) |
- return false; |
- } |
+ if (root->m_loadingClients.size()) |
+ return false; |
return true; |
} |
@@ -398,7 +396,7 @@ void StyleSheetContents::checkLoaded() |
} |
StyleSheetContents* root = rootStyleSheet(); |
- if (root->m_clients.isEmpty()) |
+ if (root->m_loadingClients.isEmpty()) |
return; |
// Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via |
@@ -409,8 +407,9 @@ void StyleSheetContents::checkLoaded() |
// FIXME: oilpan: with oilpan we do not need to protect the CSSStyleSheets |
// explicitly during the iteration. The iterator will make the pointers |
// strong during iteration so we can just directly iterate root->m_clients. |
- WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>, 5> protectedClients; |
- for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end(); ++it) |
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > protectedClients; |
+ protectedClients.reserveInitialCapacity(root->m_loadingClients.size()); |
+ for (ClientsIterator it = root->m_loadingClients.begin(); it != root->m_loadingClients.end(); ++it) |
protectedClients.append(*it); |
for (unsigned i = 0; i < protectedClients.size(); ++i) { |
@@ -438,7 +437,9 @@ void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) |
void StyleSheetContents::startLoadingDynamicSheet() |
{ |
StyleSheetContents* root = rootStyleSheet(); |
- for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end(); ++it) |
+ for (ClientsIterator it = root->m_loadingClients.begin(); it != root->m_loadingClients.end(); ++it) |
+ (*it)->startLoadingDynamicSheet(); |
+ for (ClientsIterator it = root->m_completedClients.begin(); it != root->m_completedClients.end(); ++it) |
(*it)->startLoadingDynamicSheet(); |
} |
@@ -453,18 +454,17 @@ StyleSheetContents* StyleSheetContents::rootStyleSheet() const |
bool StyleSheetContents::hasSingleOwnerNode() const |
{ |
StyleSheetContents* root = rootStyleSheet(); |
- if (root->m_clients.isEmpty()) |
- return false; |
- return root->m_clients.size() == 1; |
+ return root->hasOneClient(); |
} |
Node* StyleSheetContents::singleOwnerNode() const |
{ |
StyleSheetContents* root = rootStyleSheet(); |
- if (root->m_clients.isEmpty()) |
- return 0; |
- ASSERT(root->m_clients.size() == 1); |
- return (*root->m_clients.begin())->ownerNode(); |
+ if (root->hasOneClient()) { |
+ return root->m_loadingClients.size() ? (*root->m_loadingClients.begin())->ownerNode() : (*root->m_completedClients.begin())->ownerNode(); |
+ } |
+ ASSERT(root->m_loadingClients.isEmpty() && root->m_completedClients.isEmpty()); |
+ return 0; |
} |
Document* StyleSheetContents::singleOwnerDocument() const |
@@ -525,14 +525,29 @@ StyleSheetContents* StyleSheetContents::parentStyleSheet() const |
void StyleSheetContents::registerClient(CSSStyleSheet* sheet) |
{ |
- ASSERT(!m_clients.contains(sheet)); |
- m_clients.add(sheet); |
+ ASSERT(!m_loadingClients.contains(sheet) && !m_completedClients.contains(sheet)); |
+ m_loadingClients.add(sheet); |
} |
void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet) |
{ |
- ASSERT(m_clients.contains(sheet)); |
- m_clients.remove(sheet); |
+ ASSERT(m_loadingClients.contains(sheet) || m_completedClients.contains(sheet)); |
+ m_loadingClients.remove(sheet); |
+ m_completedClients.remove(sheet); |
+} |
+ |
+void StyleSheetContents::clientLoadCompleted(CSSStyleSheet* sheet) |
+{ |
+ ASSERT(m_loadingClients.contains(sheet)); |
+ m_loadingClients.remove(sheet); |
+ m_completedClients.add(sheet); |
+} |
+ |
+void StyleSheetContents::clientLoadStarted(CSSStyleSheet* sheet) |
+{ |
+ ASSERT(m_completedClients.contains(sheet)); |
+ m_completedClients.remove(sheet); |
+ m_loadingClients.add(sheet); |
} |
void StyleSheetContents::addedToMemoryCache() |
@@ -564,6 +579,14 @@ RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, Ad |
return *m_ruleSet.get(); |
} |
+static void clearResolvers(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >& clients) |
+{ |
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) { |
+ if (Document* document = (*it)->ownerDocument()) |
+ document->styleEngine()->clearResolver(); |
+ } |
+} |
+ |
void StyleSheetContents::clearRuleSet() |
{ |
if (StyleSheetContents* parentSheet = parentStyleSheet()) |
@@ -577,23 +600,26 @@ void StyleSheetContents::clearRuleSet() |
// Clearing the ruleSet means we need to recreate the styleResolver data structures. |
// See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. |
- for (ClientsIterator it = m_clients.begin(); it != m_clients.end(); ++it) { |
- if (Document* document = (*it)->ownerDocument()) |
- document->styleEngine()->clearResolver(); |
- } |
+ clearResolvers(m_loadingClients); |
+ clearResolvers(m_completedClients); |
m_ruleSet.clear(); |
} |
-void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontFaceRule) |
+static void removeFontFaceRules(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >& clients, const StyleRuleFontFace* fontFaceRule) |
{ |
- StyleSheetContents* root = rootStyleSheet(); |
- |
- for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end(); ++it) { |
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) { |
if (Node* ownerNode = (*it)->ownerNode()) |
ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule)); |
} |
} |
+void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontFaceRule) |
+{ |
+ StyleSheetContents* root = rootStyleSheet(); |
+ removeFontFaceRules(root->m_loadingClients, fontFaceRule); |
+ removeFontFaceRules(root->m_completedClients, fontFaceRule); |
+} |
+ |
static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules) |
{ |
for (unsigned i = 0; i < rules.size(); ++i) { |
@@ -626,7 +652,8 @@ void StyleSheetContents::trace(Visitor* visitor) |
visitor->trace(m_ownerRule); |
visitor->trace(m_importRules); |
visitor->trace(m_childRules); |
- visitor->trace(m_clients); |
+ visitor->trace(m_loadingClients); |
+ visitor->trace(m_completedClients); |
} |
} |