Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Unified Diff: Source/core/css/StyleSheetContents.cpp

Issue 28553005: Avoid parsing css text if there are identical inline style blocks. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebased Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);

Powered by Google App Engine
This is Rietveld 408576698