Chromium Code Reviews| Index: Source/core/css/StyleSheetContents.cpp |
| diff --git a/Source/core/css/StyleSheetContents.cpp b/Source/core/css/StyleSheetContents.cpp |
| index 9b042859e34c4af43bf743de1b2737b22d5db2fc..be535453e672a36223342797cc11134c5fb523dd 100644 |
| --- a/Source/core/css/StyleSheetContents.cpp |
| +++ b/Source/core/css/StyleSheetContents.cpp |
| @@ -28,6 +28,7 @@ |
| #include "core/css/StyleRule.h" |
| #include "core/css/StyleRuleImport.h" |
| #include "core/dom/Node.h" |
| +#include "core/dom/StyleEngine.h" |
| #include "core/fetch/CSSStyleSheetResource.h" |
| #include "platform/TraceEvent.h" |
| #include "weborigin/SecurityOrigin.h" |
| @@ -93,10 +94,26 @@ StyleSheetContents::StyleSheetContents(const StyleSheetContents& o) |
| StyleSheetContents::~StyleSheetContents() |
| { |
| + StyleEngine::removeSheet(this); |
| clearRules(); |
| } |
| -bool StyleSheetContents::isCacheable() const |
| +void StyleSheetContents::setMutable() |
| +{ |
| + // If the contents is changed to be mutable, it is safe not to share the contents with others. |
| + if (maybeCacheable()) |
| + StyleEngine::removeSheet(this); |
| + m_isMutable = true; |
|
esprehn
2013/11/15 10:27:37
You can't make yourself mutable like this, you hav
tasak
2014/01/09 09:24:50
I see. I moved the logic to CSSStyleSheet::willMut
|
| +} |
| + |
| +void StyleSheetContents::setHasSyntacticallyValidCSSHeader(bool isValidCss) |
| +{ |
| + if (maybeCacheable() && !isValidCss) |
| + StyleEngine::removeSheet(this); |
| + m_hasSyntacticallyValidCSSHeader = isValidCss; |
| +} |
| + |
| +bool StyleSheetContents::maybeCacheable() const |
| { |
| // FIXME: Support copying import rules. |
| if (!m_importRules.isEmpty()) |
| @@ -104,9 +121,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. |
| @@ -119,6 +133,14 @@ bool StyleSheetContents::isCacheable() const |
| return true; |
| } |
| +bool StyleSheetContents::isCacheable() const |
| +{ |
| + // This would require dealing with multiple clients for load callbacks. |
| + if (!m_loadCompleted) |
| + return false; |
| + return maybeCacheable(); |
| +} |
| + |
| void StyleSheetContents::parserAppendRule(PassRefPtr<StyleRuleBase> rule) |
| { |
| ASSERT(!rule->isCharsetRule()); |
| @@ -315,7 +337,7 @@ bool StyleSheetContents::isLoading() const |
| return false; |
| } |
| -void StyleSheetContents::checkLoaded() |
| +void StyleSheetContents::checkLoadedFor(PassRefPtr<Node> ownerNode) |
| { |
| if (isLoading()) |
| return; |
| @@ -327,11 +349,10 @@ void StyleSheetContents::checkLoaded() |
| StyleSheetContents* parentSheet = parentStyleSheet(); |
| if (parentSheet) { |
| - parentSheet->checkLoaded(); |
| + parentSheet->checkLoadedFor(ownerNode); |
| m_loadCompleted = true; |
| return; |
| } |
| - RefPtr<Node> ownerNode = singleOwnerNode(); |
| if (!ownerNode) { |
| m_loadCompleted = true; |
| return; |
| @@ -341,6 +362,40 @@ void StyleSheetContents::checkLoaded() |
| ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur); |
| } |
| +void StyleSheetContents::checkLoaded() |
| +{ |
| + if (isLoading()) |
| + return; |
| + |
| + // Avoid |this| being deleted by scripts that run via |
| + // ScriptableDocumentParser::executeScriptsWaitingForResources(). |
| + // See https://bugs.webkit.org/show_bug.cgi?id=95106 |
| + RefPtr<StyleSheetContents> protect(this); |
| + |
| + StyleSheetContents* parentSheet = parentStyleSheet(); |
| + if (parentSheet) { |
| + parentSheet->checkLoaded(); |
| + m_loadCompleted = true; |
| + return; |
| + } |
| + |
| + StyleSheetContents* root = rootStyleSheet(); |
| + if (root->m_clients.isEmpty()) { |
| + m_loadCompleted = true; |
| + return; |
| + } |
| + |
| + for (unsigned i = 0; i < root->m_clients.size(); ++i) { |
| + RefPtr<Node> ownerNode = m_clients[i]->ownerNode(); |
| + ASSERT(ownerNode); |
| + bool loadCompleted = ownerNode->sheetLoaded(); |
|
esprehn
2013/11/15 10:27:37
How could the sheet have loaded for one node but n
tasak
2014/01/09 09:24:50
I see. I moved loadCompleted to CSSStyleSheet.
If
|
| + ASSERT(i <= 0 || m_loadCompleted == loadCompleted); |
| + m_loadCompleted = loadCompleted; |
| + if (loadCompleted) |
| + ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur); |
| + } |
| +} |
| + |
| void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) |
| { |
| ASSERT(sheet); |