Chromium Code Reviews| Index: Source/core/css/StyleSheetContents.cpp |
| diff --git a/Source/core/css/StyleSheetContents.cpp b/Source/core/css/StyleSheetContents.cpp |
| index 31008ad1e65f71c3e49122f9aeba912787abf40b..366c399de80a85e64c81257a375d856d3a4850f9 100644 |
| --- a/Source/core/css/StyleSheetContents.cpp |
| +++ b/Source/core/css/StyleSheetContents.cpp |
| @@ -59,7 +59,6 @@ unsigned StyleSheetContents::estimatedSizeInBytes() const |
| StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context) |
| : m_ownerRule(ownerRule) |
| , m_originalURL(originalURL) |
| - , m_loadCompleted(false) |
| , m_hasSyntacticallyValidCSSHeader(true) |
| , m_didLoadErrorOccur(false) |
| , m_usesRemUnits(false) |
| @@ -79,7 +78,6 @@ StyleSheetContents::StyleSheetContents(const StyleSheetContents& o) |
| , m_importRules(o.m_importRules.size()) |
| , m_childRules(o.m_childRules.size()) |
| , m_namespaces(o.m_namespaces) |
| - , m_loadCompleted(true) |
| , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader) |
| , m_didLoadErrorOccur(false) |
| , m_usesRemUnits(o.m_usesRemUnits) |
| @@ -100,10 +98,18 @@ StyleSheetContents::StyleSheetContents(const StyleSheetContents& o) |
| StyleSheetContents::~StyleSheetContents() |
| { |
| + StyleEngine::removeSheet(this); |
| clearRules(); |
| } |
| -bool StyleSheetContents::isCacheable() const |
| +void StyleSheetContents::setHasSyntacticallyValidCSSHeader(bool isValidCss) |
| +{ |
| + if (maybeCacheable() && !isValidCss) |
| + StyleEngine::removeSheet(this); |
| + m_hasSyntacticallyValidCSSHeader = isValidCss; |
| +} |
| + |
| +bool StyleSheetContents::maybeCacheable() const |
| { |
| // FIXME: StyleSheets with media queries can't be cached because their RuleSet |
| // is processed differently based off the media queries, which might resolve |
| @@ -118,9 +124,6 @@ bool StyleSheetContents::isCacheable() const |
| // FIXME: Support cached stylesheets in import rules. |
| if (m_ownerRule) |
| return false; |
| - // This would require dealing with multiple clients for load callbacks. |
| - if (!m_loadCompleted) |
| - return false; |
| if (m_didLoadErrorOccur) |
| return false; |
| // It is not the original sheet anymore. |
| @@ -133,6 +136,14 @@ bool StyleSheetContents::isCacheable() const |
| return true; |
| } |
| +bool StyleSheetContents::isCacheable() const |
| +{ |
| + // This would require dealing with multiple clients for load callbacks. |
| + if (!loadCompleted()) |
| + return false; |
| + return maybeCacheable(); |
| +} |
| + |
| void StyleSheetContents::parserAppendRule(PassRefPtr<StyleRuleBase> rule) |
| { |
| ASSERT(!rule->isCharsetRule()); |
| @@ -347,6 +358,20 @@ bool StyleSheetContents::isLoading() const |
| return false; |
| } |
| +bool StyleSheetContents::loadCompleted() const |
| +{ |
| + StyleSheetContents* parentSheet = parentStyleSheet(); |
| + if (parentSheet) |
| + return parentSheet->loadCompleted(); |
|
esprehn
2014/01/14 05:09:43
So only the root ever has clients?
tasak
2014/01/14 08:03:54
Yes, I think so.
Because singleOwnerNode() always
|
| + |
| + StyleSheetContents* root = rootStyleSheet(); |
| + for (unsigned i = 0; i < root->m_clients.size(); ++i) { |
| + if (!root->m_clients[i]->loadCompleted()) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| void StyleSheetContents::checkLoaded() |
| { |
| if (isLoading()) |
| @@ -360,17 +385,26 @@ void StyleSheetContents::checkLoaded() |
| StyleSheetContents* parentSheet = parentStyleSheet(); |
| if (parentSheet) { |
| parentSheet->checkLoaded(); |
| - m_loadCompleted = true; |
| return; |
| } |
| - RefPtr<Node> ownerNode = singleOwnerNode(); |
| - if (!ownerNode) { |
| - m_loadCompleted = true; |
| + |
| + StyleSheetContents* root = rootStyleSheet(); |
| + if (root->m_clients.isEmpty()) |
| return; |
| + |
| + Vector<CSSStyleSheet*> clients(root->m_clients); |
| + for (unsigned i = 0; i < clients.size(); ++i) { |
| + // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via |
| + // ScriptableDocumentParser::executeScriptsWaitingForResources(). |
| + RefPtr<CSSStyleSheet> protectClient(clients[i]); |
| + |
| + if (clients[i]->loadCompleted()) |
| + continue; |
| + |
| + RefPtr<Node> ownerNode = clients[i]->ownerNode(); |
| + if (clients[i]->sheetLoaded()) |
| + ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur); |
| } |
| - m_loadCompleted = ownerNode->sheetLoaded(); |
| - if (m_loadCompleted) |
| - ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur); |
| } |
| void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) |
| @@ -385,8 +419,9 @@ void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) |
| void StyleSheetContents::startLoadingDynamicSheet() |
| { |
| - if (Node* owner = singleOwnerNode()) |
| - owner->startLoadingDynamicSheet(); |
| + StyleSheetContents* root = rootStyleSheet(); |
| + for (unsigned i = 0; i < root->m_clients.size(); ++i) |
| + root->m_clients[i]->startLoadingDynamicSheet(); |
| } |
| StyleSheetContents* StyleSheetContents::rootStyleSheet() const |