summaryrefslogtreecommitdiff
path: root/Source/WebCore/css/StyleSheetContents.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/css/StyleSheetContents.cpp')
-rw-r--r--Source/WebCore/css/StyleSheetContents.cpp148
1 files changed, 71 insertions, 77 deletions
diff --git a/Source/WebCore/css/StyleSheetContents.cpp b/Source/WebCore/css/StyleSheetContents.cpp
index ba00e2b21..048273bec 100644
--- a/Source/WebCore/css/StyleSheetContents.cpp
+++ b/Source/WebCore/css/StyleSheetContents.cpp
@@ -54,9 +54,11 @@ unsigned StyleSheetContents::estimatedSizeInBytes() const
return size;
}
-StyleSheetContents::StyleSheetContents(const String& originalURL, const CSSParserContext& context)
- : m_originalURL(originalURL)
+StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
+ : m_ownerRule(ownerRule)
+ , m_originalURL(originalURL)
, m_loadCompleted(false)
+ , m_isUserStyleSheet(ownerRule && ownerRule->parentStyleSheet() && ownerRule->parentStyleSheet()->isUserStyleSheet())
, m_hasSyntacticallyValidCSSHeader(true)
, m_didLoadErrorOccur(false)
, m_usesRemUnits(false)
@@ -68,6 +70,7 @@ StyleSheetContents::StyleSheetContents(const String& originalURL, const CSSParse
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())
@@ -101,6 +104,9 @@ 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;
@@ -123,6 +129,8 @@ 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);
@@ -161,6 +169,10 @@ 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();
@@ -195,6 +207,9 @@ 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.
@@ -220,6 +235,7 @@ void StyleSheetContents::wrapperDeleteRule(unsigned index)
--childVectorIndex;
}
if (childVectorIndex < m_importRules.size()) {
+ m_importRules[childVectorIndex]->clearParentStyleSheet();
m_importRules.remove(childVectorIndex);
return;
}
@@ -250,22 +266,8 @@ const AtomicString& StyleSheetContents::determineNamespace(const AtomicString& p
return it->second;
}
-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)
+void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cachedStyleSheet, const SecurityOrigin* securityOrigin)
{
- 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;
@@ -279,7 +281,6 @@ 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();
@@ -292,13 +293,9 @@ void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cached
// There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet,
// while the other lacks the second trailing newline.
if (baseURL().string().endsWith("/KHTMLFixes.css") && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText)
- && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1) {
+ && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1)
clearRules();
- return;
- }
}
-
- requestImportedStyleSheets(rootSheet);
}
bool StyleSheetContents::parseString(const String& sheetText)
@@ -311,10 +308,6 @@ 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;
}
@@ -327,70 +320,66 @@ bool StyleSheetContents::isLoading() const
return false;
}
-bool StyleSheetContents::checkImportedSheetLoadCompleted()
-{
- 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;
-}
-
-void StyleSheetContents::checkLoadCompleted()
+void StyleSheetContents::checkLoaded()
{
- if (m_clients.isEmpty())
- return;
- if (!checkImportedSheetLoadCompleted())
+ if (isLoading())
return;
RefPtr<StyleSheetContents> protect(this);
- ASSERT(hasOneClient());
- ASSERT(!m_clients[0]->parentStyleSheet());
- RefPtr<Node> ownerNode = m_clients[0]->ownerNode();
- if (!ownerNode)
+ // 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;
return;
-
+ }
+ RefPtr<Node> ownerNode = singleOwnerNode();
+ if (!ownerNode) {
+ m_loadCompleted = true;
+ return;
+ }
m_loadCompleted = ownerNode->sheetLoaded();
if (m_loadCompleted)
ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
}
-bool StyleSheetContents::getAncestors(const StyleRuleImport* importRule, Vector<const StyleSheetContents*>& result) const
+void StyleSheetContents::notifyLoadedSheet(const CachedCSSStyleSheet* sheet)
{
- 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;
+ ASSERT(sheet);
+ m_didLoadErrorOccur |= sheet->errorOccurred();
}
-bool StyleSheetContents::hasImportCycle(const StyleRuleImport* importRule, const KURL& importURL, const KURL& documentBaseURL) const
+void StyleSheetContents::startLoadingDynamicSheet()
{
- Vector<const StyleSheetContents*> ancestors;
- getAncestors(importRule, ancestors);
+ if (Node* owner = singleOwnerNode())
+ owner->startLoadingDynamicSheet();
+}
- 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;
+StyleSheetContents* StyleSheetContents::rootStyleSheet() const
+{
+ const StyleSheetContents* root = this;
+ while (root->parentStyleSheet())
+ root = root->parentStyleSheet();
+ return const_cast<StyleSheetContents*>(root);
+}
+
+Node* StyleSheetContents::singleOwnerNode() const
+{
+ StyleSheetContents* root = rootStyleSheet();
+ if (root->m_clients.isEmpty())
+ return 0;
+ ASSERT(root->m_clients.size() == 1);
+ return root->m_clients[0]->ownerNode();
+}
+
+Document* StyleSheetContents::singleOwnerDocument() const
+{
+ Node* ownerNode = singleOwnerNode();
+ return ownerNode ? ownerNode->document() : 0;
}
KURL StyleSheetContents::completeURL(const String& url) const
@@ -463,6 +452,11 @@ 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));
@@ -493,8 +487,8 @@ void StyleSheetContents::removedFromMemoryCache()
void StyleSheetContents::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
- info.addInstrumentedMember(m_originalURL);
- info.addInstrumentedMember(m_encodingFromCharsetRule);
+ info.addMember(m_originalURL);
+ info.addMember(m_encodingFromCharsetRule);
info.addVector(m_importRules);
info.addInstrumentedVector(m_childRules);
info.addHashMap(m_namespaces);