summaryrefslogtreecommitdiff
path: root/Source/WebCore/css/StyleSheetContents.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-09-10 19:10:20 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-09-10 19:10:20 +0200
commit284837daa07b29d6a63a748544a90b1f5842ac5c (patch)
treeecd258180bde91fe741e0cfd2638beb3c6da7e8e /Source/WebCore/css/StyleSheetContents.cpp
parent2e2ba8ff45915f40ed3e014101269c175f2a89a0 (diff)
downloadqtwebkit-284837daa07b29d6a63a748544a90b1f5842ac5c.tar.gz
Imported WebKit commit 68645295d2e3e09af2c942f092556f06aa5f8b0d (http://svn.webkit.org/repository/webkit/trunk@128073)
New snapshot
Diffstat (limited to 'Source/WebCore/css/StyleSheetContents.cpp')
-rw-r--r--Source/WebCore/css/StyleSheetContents.cpp155
1 files changed, 81 insertions, 74 deletions
diff --git a/Source/WebCore/css/StyleSheetContents.cpp b/Source/WebCore/css/StyleSheetContents.cpp
index cc3cec52a..ba00e2b21 100644
--- a/Source/WebCore/css/StyleSheetContents.cpp
+++ b/Source/WebCore/css/StyleSheetContents.cpp
@@ -26,12 +26,12 @@
#include "CSSStyleSheet.h"
#include "CachedCSSStyleSheet.h"
#include "Document.h"
-#include "MemoryInstrumentation.h"
#include "Node.h"
#include "SecurityOrigin.h"
#include "StylePropertySet.h"
#include "StyleRule.h"
#include "StyleRuleImport.h"
+#include "WebCoreMemoryInstrumentation.h"
#include <wtf/Deque.h>
namespace WebCore {
@@ -54,11 +54,9 @@ unsigned StyleSheetContents::estimatedSizeInBytes() const
return size;
}
-StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
- : m_ownerRule(ownerRule)
- , m_originalURL(originalURL)
+StyleSheetContents::StyleSheetContents(const String& originalURL, const CSSParserContext& context)
+ : m_originalURL(originalURL)
, m_loadCompleted(false)
- , m_isUserStyleSheet(ownerRule && ownerRule->parentStyleSheet() && ownerRule->parentStyleSheet()->isUserStyleSheet())
, m_hasSyntacticallyValidCSSHeader(true)
, m_didLoadErrorOccur(false)
, m_usesRemUnits(false)
@@ -70,7 +68,6 @@ StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String&
StyleSheetContents::StyleSheetContents(const StyleSheetContents& o)
: RefCounted<StyleSheetContents>()
- , m_ownerRule(0)
, m_originalURL(o.m_originalURL)
, m_encodingFromCharsetRule(o.m_encodingFromCharsetRule)
, m_importRules(o.m_importRules.size())
@@ -104,9 +101,6 @@ bool StyleSheetContents::isCacheable() const
// FIXME: Support copying import rules.
if (!m_importRules.isEmpty())
return false;
- // 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;
@@ -129,8 +123,6 @@ void StyleSheetContents::parserAppendRule(PassRefPtr<StyleRuleBase> rule)
// Parser enforces that @import rules come before anything else except @charset.
ASSERT(m_childRules.isEmpty());
m_importRules.append(static_cast<StyleRuleImport*>(rule.get()));
- m_importRules.last()->setParentStyleSheet(this);
- m_importRules.last()->requestStyleSheet();
return;
}
m_childRules.append(rule);
@@ -169,10 +161,6 @@ void StyleSheetContents::clearCharsetRule()
void StyleSheetContents::clearRules()
{
- for (unsigned i = 0; i < m_importRules.size(); ++i) {
- ASSERT(m_importRules.at(i)->parentStyleSheet() == this);
- m_importRules[i]->clearParentStyleSheet();
- }
m_importRules.clear();
m_childRules.clear();
clearCharsetRule();
@@ -207,9 +195,6 @@ bool StyleSheetContents::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsig
if (!rule->isImportRule())
return false;
m_importRules.insert(childVectorIndex, static_cast<StyleRuleImport*>(rule.get()));
- m_importRules[childVectorIndex]->setParentStyleSheet(this);
- m_importRules[childVectorIndex]->requestStyleSheet();
- // FIXME: Stylesheet doesn't actually change meaningfully before the imported sheets are loaded.
return true;
}
// Inserting @import rule after a non-import rule is not allowed.
@@ -235,7 +220,6 @@ void StyleSheetContents::wrapperDeleteRule(unsigned index)
--childVectorIndex;
}
if (childVectorIndex < m_importRules.size()) {
- m_importRules[childVectorIndex]->clearParentStyleSheet();
m_importRules.remove(childVectorIndex);
return;
}
@@ -266,8 +250,22 @@ const AtomicString& StyleSheetContents::determineNamespace(const AtomicString& p
return it->second;
}
-void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cachedStyleSheet, const SecurityOrigin* securityOrigin)
+void StyleSheetContents::requestImportedStyleSheets(CSSStyleSheet* rootSheet)
{
+ ASSERT(!rootSheet->parentStyleSheet());
+ for (unsigned i = 0; i < m_importRules.size(); ++i)
+ m_importRules[i]->requestStyleSheet(rootSheet, parserContext());
+}
+
+void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cachedStyleSheet, CSSStyleSheet* rootSheet)
+{
+ if (cachedStyleSheet->errorOccurred()) {
+ m_didLoadErrorOccur = true;
+ return;
+ }
+ Document* ownerDocument = rootSheet->ownerDocument();
+ if (!ownerDocument)
+ return;
// Check to see if we should enforce the MIME type of the CSS resource in strict mode.
// Running in iWeb 2 is one example of where we don't want to - <rdar://problem/6099748>
bool enforceMIMEType = isStrictParserMode(m_parserContext.mode) && m_parserContext.enforcesCSSMIMETypeInNoQuirksMode;
@@ -281,6 +279,7 @@ void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cached
// to at least start with a syntactically valid CSS rule.
// This prevents an attacker playing games by injecting CSS strings into HTML, XML, JSON, etc. etc.
if (!hasValidMIMEType && !hasSyntacticallyValidCSSHeader()) {
+ const SecurityOrigin* securityOrigin = ownerDocument->securityOrigin();
bool isCrossOriginCSS = !securityOrigin || !securityOrigin->canRequest(baseURL());
if (isCrossOriginCSS) {
clearRules();
@@ -289,14 +288,17 @@ void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cached
}
if (m_parserContext.needsSiteSpecificQuirks && isStrictParserMode(m_parserContext.mode)) {
// Work around <https://bugs.webkit.org/show_bug.cgi?id=28350>.
- DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css"));
- DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, ("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n"));
+ DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, (ASCIILiteral("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n")));
// There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet,
// while the other lacks the second trailing newline.
- if (baseURL().string().endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText)
- && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1)
+ if (baseURL().string().endsWith("/KHTMLFixes.css") && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText)
+ && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1) {
clearRules();
+ return;
+ }
}
+
+ requestImportedStyleSheets(rootSheet);
}
bool StyleSheetContents::parseString(const String& sheetText)
@@ -309,6 +311,10 @@ bool StyleSheetContents::parseStringAtLine(const String& sheetText, int startLin
CSSParser p(parserContext());
p.parseSheet(this, sheetText, startLineNumber);
+ if (!m_clients.isEmpty()) {
+ ASSERT(m_clients.size() == 1);
+ requestImportedStyleSheets(m_clients[0]);
+ }
return true;
}
@@ -321,64 +327,70 @@ bool StyleSheetContents::isLoading() const
return false;
}
-void StyleSheetContents::checkLoaded()
+bool StyleSheetContents::checkImportedSheetLoadCompleted()
{
- if (isLoading())
- return;
+ for (unsigned i = 0; i < m_importRules.size(); ++i) {
+ StyleRuleImport* importRule = m_importRules[i].get();
+ if (importRule->isLoading())
+ return false;
+ if (importRule->styleSheet() && !importRule->styleSheet()->checkImportedSheetLoadCompleted())
+ return false;
+ if (importRule->hadLoadError())
+ m_didLoadErrorOccur = true;
+ }
+ m_loadCompleted = true;
+ return true;
+}
- // Avoid |this| being deleted by scripts that run via
- // ScriptableDocumentParser::executeScriptsWaitingForStylesheets().
- // See <rdar://problem/6622300>.
- RefPtr<StyleSheetContents> protector(this);
- StyleSheetContents* parentSheet = parentStyleSheet();
- if (parentSheet) {
- parentSheet->checkLoaded();
- m_loadCompleted = true;
+void StyleSheetContents::checkLoadCompleted()
+{
+ if (m_clients.isEmpty())
return;
- }
- RefPtr<Node> ownerNode = singleOwnerNode();
- if (!ownerNode) {
- m_loadCompleted = true;
+ if (!checkImportedSheetLoadCompleted())
return;
- }
+
+ RefPtr<StyleSheetContents> protect(this);
+
+ ASSERT(hasOneClient());
+ ASSERT(!m_clients[0]->parentStyleSheet());
+ RefPtr<Node> ownerNode = m_clients[0]->ownerNode();
+ if (!ownerNode)
+ return;
+
m_loadCompleted = ownerNode->sheetLoaded();
if (m_loadCompleted)
ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
}
-void StyleSheetContents::notifyLoadedSheet(const CachedCSSStyleSheet* sheet)
-{
- ASSERT(sheet);
- m_didLoadErrorOccur |= sheet->errorOccurred();
-}
-
-void StyleSheetContents::startLoadingDynamicSheet()
-{
- if (Node* owner = singleOwnerNode())
- owner->startLoadingDynamicSheet();
-}
-
-StyleSheetContents* StyleSheetContents::rootStyleSheet() const
+bool StyleSheetContents::getAncestors(const StyleRuleImport* importRule, Vector<const StyleSheetContents*>& result) const
{
- const StyleSheetContents* root = this;
- while (root->parentStyleSheet())
- root = root->parentStyleSheet();
- return const_cast<StyleSheetContents*>(root);
+ result.append(this);
+ for (unsigned i = 0; i < m_importRules.size(); ++i) {
+ if (m_importRules[i] == importRule)
+ return true;
+ }
+ for (unsigned i = 0; i < m_importRules.size(); ++i) {
+ if (m_importRules[i]->styleSheet() && m_importRules[i]->styleSheet()->getAncestors(importRule, result))
+ return true;
+ }
+ result.removeLast();
+ return false;
}
-Node* StyleSheetContents::singleOwnerNode() const
+bool StyleSheetContents::hasImportCycle(const StyleRuleImport* importRule, const KURL& importURL, const KURL& documentBaseURL) const
{
- StyleSheetContents* root = rootStyleSheet();
- if (root->m_clients.isEmpty())
- return 0;
- ASSERT(root->m_clients.size() == 1);
- return root->m_clients[0]->ownerNode();
-}
+ Vector<const StyleSheetContents*> ancestors;
+ getAncestors(importRule, ancestors);
-Document* StyleSheetContents::singleOwnerDocument() const
-{
- Node* ownerNode = singleOwnerNode();
- return ownerNode ? ownerNode->document() : 0;
+ KURL parentBaseURL = documentBaseURL;
+ for (unsigned i = 0; i < ancestors.size(); ++i) {
+ if (equalIgnoringFragmentIdentifier(importURL, ancestors[i]->baseURL()))
+ return true;
+ if (equalIgnoringFragmentIdentifier(importURL, KURL(parentBaseURL, ancestors[i]->originalURL())))
+ return true;
+ parentBaseURL = ancestors[i]->baseURL();
+ }
+ return false;
}
KURL StyleSheetContents::completeURL(const String& url) const
@@ -451,11 +463,6 @@ bool StyleSheetContents::hasFailedOrCanceledSubresources() const
return childRulesHaveFailedOrCanceledSubresources(m_childRules);
}
-StyleSheetContents* StyleSheetContents::parentStyleSheet() const
-{
- return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0;
-}
-
void StyleSheetContents::registerClient(CSSStyleSheet* sheet)
{
ASSERT(!m_clients.contains(sheet));
@@ -485,7 +492,7 @@ void StyleSheetContents::removedFromMemoryCache()
void StyleSheetContents::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
- MemoryClassInfo info(memoryObjectInfo, this, MemoryInstrumentation::CSS);
+ MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
info.addInstrumentedMember(m_originalURL);
info.addInstrumentedMember(m_encodingFromCharsetRule);
info.addVector(m_importRules);