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); |