Diff
Modified: trunk/Source/WebCore/ChangeLog (126716 => 126717)
--- trunk/Source/WebCore/ChangeLog 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/ChangeLog 2012-08-26 23:48:39 UTC (rev 126717)
@@ -1,3 +1,76 @@
+2012-08-26 Antti Koivisto <[email protected]>
+
+ Remove parent pointer from StyleSheetContents and StyleRuleImport
+ https://bugs.webkit.org/show_bug.cgi?id=94926
+
+ Reviewed by Andreas Kling.
+
+ To be able to cache and share @imported stylesheets in the future there must not be any parent
+ pointers in the stylesheet tree.
+
+ Parent pointers are used during loading to invoke load completion callbacks and for
+ accessing document context information (like the security origin). They are not used after
+ the sheet load is complete. Instead of keeping the parent pointers around indefinitely as part of the
+ stylesheet data structure we just keep a pointer to the root CSSStyleSheet for the duration of the load.
+
+ This patch doesn't enable any new caching or generally change the behavior.
+
+ * css/CSSStyleSheet.cpp:
+ (WebCore::CSSStyleSheet::insertRule):
+ (WebCore::CSSStyleSheet::rootStyleSheet):
+ (WebCore):
+ (WebCore::CSSStyleSheet::ownerDocument):
+ * css/CSSStyleSheet.h:
+ (CSSStyleSheet):
+ * css/StyleRuleImport.cpp:
+ (WebCore::StyleRuleImport::LoadContext::LoadContext):
+
+ Simplify by making StyleRuleImport CachedStyleSheetClient directly. LoadContext contains
+ fields that can be thrown away after load completes.
+
+ (WebCore):
+ (WebCore::StyleRuleImport::StyleRuleImport):
+ (WebCore::StyleRuleImport::~StyleRuleImport):
+ (WebCore::StyleRuleImport::setCSSStyleSheet):
+ (WebCore::StyleRuleImport::isLoading):
+ (WebCore::StyleRuleImport::hadLoadError):
+ (WebCore::StyleRuleImport::requestStyleSheet):
+ * css/StyleRuleImport.h:
+ (StyleRuleImport):
+ (LoadContext):
+ * css/StyleSheetContents.cpp:
+ (WebCore::StyleSheetContents::StyleSheetContents):
+
+ Remove now unnecessary constructor.
+
+ (WebCore::StyleSheetContents::isCacheable):
+ (WebCore::StyleSheetContents::parserAppendRule):
+ (WebCore::StyleSheetContents::clearRules):
+ (WebCore::StyleSheetContents::wrapperInsertRule):
+ (WebCore::StyleSheetContents::wrapperDeleteRule):
+ (WebCore::StyleSheetContents::requestImportedStyleSheets):
+ (WebCore):
+ (WebCore::StyleSheetContents::parseAuthorStyleSheet):
+ (WebCore::StyleSheetContents::parseStringAtLine):
+ (WebCore::StyleSheetContents::checkImportedSheetLoadCompleted):
+ (WebCore::StyleSheetContents::checkLoadCompleted):
+ (WebCore::StyleSheetContents::getAncestors):
+ (WebCore::StyleSheetContents::hasImportCycle):
+
+ Move the cycle checking to the root stylesheet so we don't need to pass the entire chain around.
+ The extra work here is unlikely to cause problems, massive import trees don't really occur in
+ practice.
+
+ * css/StyleSheetContents.h:
+ (WebCore::StyleSheetContents::create):
+ (StyleSheetContents):
+ * dom/ProcessingInstruction.cpp:
+ (WebCore::ProcessingInstruction::parseStyleSheet):
+ * dom/StyleElement.cpp:
+ (WebCore::StyleElement::createSheet):
+ * html/HTMLLinkElement.cpp:
+ (WebCore::HTMLLinkElement::setCSSStyleSheet):
+
2012-08-26 Andreas Kling <[email protected]>
Avoid pointless string/number round-trip in applyRelativeFontStyleChange().
Modified: trunk/Source/WebCore/css/CSSStyleSheet.cpp (126716 => 126717)
--- trunk/Source/WebCore/css/CSSStyleSheet.cpp 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/css/CSSStyleSheet.cpp 2012-08-26 23:48:39 UTC (rev 126717)
@@ -37,6 +37,7 @@
#include "SVGNames.h"
#include "SecurityOrigin.h"
#include "StyleRule.h"
+#include "StyleRuleImport.h"
#include "StyleSheetContents.h"
#include <wtf/text/StringBuilder.h>
@@ -283,7 +284,10 @@
if (!success) {
ec = HIERARCHY_REQUEST_ERR;
return 0;
- }
+ }
+ if (rule->isImportRule())
+ static_cast<StyleRuleImport*>(rule.get())->requestStyleSheet(rootStyleSheet(), m_contents->parserContext());
+
if (!m_childRuleCSSOMWrappers.isEmpty())
m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>());
@@ -370,11 +374,17 @@
return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0;
}
-Document* CSSStyleSheet::ownerDocument() const
+CSSStyleSheet* CSSStyleSheet::rootStyleSheet() const
{
const CSSStyleSheet* root = this;
while (root->parentStyleSheet())
root = root->parentStyleSheet();
+ return const_cast<CSSStyleSheet*>(root);
+}
+
+Document* CSSStyleSheet::ownerDocument() const
+{
+ const CSSStyleSheet* root = rootStyleSheet();
return root->ownerNode() ? root->ownerNode()->document() : 0;
}
Modified: trunk/Source/WebCore/css/CSSStyleSheet.h (126716 => 126717)
--- trunk/Source/WebCore/css/CSSStyleSheet.h 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/css/CSSStyleSheet.h 2012-08-26 23:48:39 UTC (rev 126717)
@@ -81,6 +81,7 @@
virtual bool isLoading() const OVERRIDE;
void clearOwnerRule() { m_ownerRule = 0; }
+ CSSStyleSheet* rootStyleSheet() const;
Document* ownerDocument() const;
MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
void setMediaQueries(PassRefPtr<MediaQuerySet>);
Modified: trunk/Source/WebCore/css/StyleRuleImport.cpp (126716 => 126717)
--- trunk/Source/WebCore/css/StyleRuleImport.cpp 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/css/StyleRuleImport.cpp 2012-08-26 23:48:39 UTC (rev 126717)
@@ -32,6 +32,12 @@
namespace WebCore {
+StyleRuleImport::LoadContext::LoadContext(CSSStyleSheet* rootStyleSheet, const CSSParserContext& parentParserContext)
+ : rootStyleSheet(rootStyleSheet)
+ , parentParserContext(parentParserContext)
+{
+}
+
PassRefPtr<StyleRuleImport> StyleRuleImport::create(const String& href, PassRefPtr<MediaQuerySet> media)
{
return adoptRef(new StyleRuleImport(href, media));
@@ -39,12 +45,9 @@
StyleRuleImport::StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet> media)
: StyleRuleBase(Import, 0)
- , m_parentStyleSheet(0)
- , m_styleSheetClient(this)
, m_strHref(href)
, m_mediaQueries(media)
, m_cachedSheet(0)
- , m_loading(false)
{
if (!m_mediaQueries)
m_mediaQueries = MediaQuerySet::create(String());
@@ -52,83 +55,76 @@
StyleRuleImport::~StyleRuleImport()
{
- if (m_styleSheet)
- m_styleSheet->clearOwnerRule();
if (m_cachedSheet)
- m_cachedSheet->removeClient(&m_styleSheetClient);
+ m_cachedSheet->removeClient(this);
}
-void StyleRuleImport::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* cachedStyleSheet)
+void StyleRuleImport::setCSSStyleSheet(const String& url, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*)
{
- if (m_styleSheet)
- m_styleSheet->clearOwnerRule();
+ ASSERT(m_loadContext);
+ ASSERT(!m_styleSheet);
+ ASSERT(m_cachedSheet);
- CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : CSSStrictMode;
- context.charset = charset;
+ OwnPtr<LoadContext> loadContext = m_loadContext.release();
+
+ CSSParserContext parserContext = loadContext->parentParserContext;
if (!baseURL.isNull())
- context.baseURL = baseURL;
+ parserContext.baseURL = baseURL;
+ parserContext.charset = charset;
- m_styleSheet = StyleSheetContents::create(this, href, context);
+ m_styleSheet = StyleSheetContents::create(url, parserContext);
+ m_styleSheet->parseAuthorStyleSheet(m_cachedSheet.get(), loadContext->rootStyleSheet.get());
- Document* document = m_parentStyleSheet ? m_parentStyleSheet->singleOwnerDocument() : 0;
- m_styleSheet->parseAuthorStyleSheet(cachedStyleSheet, document ? document->securityOrigin() : 0);
-
- m_loading = false;
-
- if (m_parentStyleSheet) {
- m_parentStyleSheet->notifyLoadedSheet(cachedStyleSheet);
- m_parentStyleSheet->checkLoaded();
- }
+ loadContext->rootStyleSheet->contents()->checkLoadCompleted();
}
bool StyleRuleImport::isLoading() const
{
- return m_loading || (m_styleSheet && m_styleSheet->isLoading());
+ return m_loadContext || (m_styleSheet && m_styleSheet->isLoading());
}
-void StyleRuleImport::requestStyleSheet()
+bool StyleRuleImport::hadLoadError() const
{
- if (!m_parentStyleSheet)
- return;
- Document* document = m_parentStyleSheet->singleOwnerDocument();
- if (!document)
- return;
+ return m_cachedSheet && m_cachedSheet->errorOccurred();
+}
- CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
- if (!cachedResourceLoader)
+void StyleRuleImport::requestStyleSheet(CSSStyleSheet* rootSheet, const CSSParserContext& parserContext)
+{
+ ASSERT(!rootSheet->parentStyleSheet());
+ ASSERT(!m_cachedSheet);
+
+ Node* ownerNode = rootSheet->ownerNode();
+ if (!ownerNode)
return;
+ Document* document = ownerNode->document();
- KURL absURL;
- if (!m_parentStyleSheet->baseURL().isNull())
- // use parent styleheet's URL as the base URL
- absURL = KURL(m_parentStyleSheet->baseURL(), m_strHref);
+ KURL resolvedURL;
+ if (!parserContext.baseURL.isNull())
+ resolvedURL = KURL(parserContext.baseURL, m_strHref);
else
- absURL = document->completeURL(m_strHref);
+ resolvedURL = document->completeURL(m_strHref);
- // Check for a cycle in our import chain. If we encounter a stylesheet
- // in our parent chain with the same URL, then just bail.
- StyleSheetContents* rootSheet = m_parentStyleSheet;
- for (StyleSheetContents* sheet = m_parentStyleSheet; sheet; sheet = sheet->parentStyleSheet()) {
- if (equalIgnoringFragmentIdentifier(absURL, sheet->baseURL())
- || equalIgnoringFragmentIdentifier(absURL, document->completeURL(sheet->originalURL())))
- return;
- rootSheet = sheet;
- }
+ StyleSheetContents* rootSheetContents = rootSheet->contents();
+ if (rootSheetContents->hasImportCycle(this, resolvedURL, document->baseURL()))
+ return;
- ResourceRequest request(absURL);
- if (m_parentStyleSheet->isUserStyleSheet())
- m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request, m_parentStyleSheet->charset());
+ ResourceRequest request(resolvedURL);
+ CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
+ if (rootSheetContents->isUserStyleSheet())
+ m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request, parserContext.charset);
else
- m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(request, m_parentStyleSheet->charset());
- if (m_cachedSheet) {
- // if the import rule is issued dynamically, the sheet may be
- // removed from the pending sheet count, so let the doc know
- // the sheet being imported is pending.
- if (m_parentStyleSheet && m_parentStyleSheet->loadCompleted() && rootSheet == m_parentStyleSheet)
- m_parentStyleSheet->startLoadingDynamicSheet();
- m_loading = true;
- m_cachedSheet->addClient(&m_styleSheetClient);
- }
+ m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(request, parserContext.charset);
+
+ if (!m_cachedSheet)
+ return;
+ // if the import rule is issued dynamically, the sheet may be
+ // removed from the pending sheet count, so let the doc know
+ // the sheet being imported is pending.
+ if (rootSheetContents->loadCompleted())
+ ownerNode->startLoadingDynamicSheet();
+
+ m_loadContext = adoptPtr(new LoadContext(rootSheet, parserContext));
+ m_cachedSheet->addClient(this);
}
void StyleRuleImport::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
Modified: trunk/Source/WebCore/css/StyleRuleImport.h (126716 => 126717)
--- trunk/Source/WebCore/css/StyleRuleImport.h 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/css/StyleRuleImport.h 2012-08-26 23:48:39 UTC (rev 126717)
@@ -22,6 +22,7 @@
#ifndef StyleRuleImport_h
#define StyleRuleImport_h
+#include "CSSParserMode.h"
#include "CachedResourceHandle.h"
#include "CachedStyleSheetClient.h"
#include "StyleRule.h"
@@ -33,54 +34,39 @@
class MemoryObjectInfo;
class StyleSheetContents;
-class StyleRuleImport : public StyleRuleBase {
+class StyleRuleImport : public StyleRuleBase, public CachedStyleSheetClient {
public:
static PassRefPtr<StyleRuleImport> create(const String& href, PassRefPtr<MediaQuerySet>);
- ~StyleRuleImport();
-
- StyleSheetContents* parentStyleSheet() const { return m_parentStyleSheet; }
- void setParentStyleSheet(StyleSheetContents* sheet) { ASSERT(sheet); m_parentStyleSheet = sheet; }
- void clearParentStyleSheet() { m_parentStyleSheet = 0; }
+ virtual ~StyleRuleImport();
String href() const { return m_strHref; }
StyleSheetContents* styleSheet() const { return m_styleSheet.get(); }
bool isLoading() const;
+ bool hadLoadError() const;
MediaQuerySet* mediaQueries() { return m_mediaQueries.get(); }
- void requestStyleSheet();
+ void requestStyleSheet(CSSStyleSheet* rootSheet, const CSSParserContext&);
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
- // NOTE: We put the CachedStyleSheetClient in a member instead of inheriting from it
- // to avoid adding a vptr to StyleRuleImport.
- class ImportedStyleSheetClient : public CachedStyleSheetClient {
- public:
- ImportedStyleSheetClient(StyleRuleImport* ownerRule) : m_ownerRule(ownerRule) { }
- virtual ~ImportedStyleSheetClient() { }
- virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet)
- {
- m_ownerRule->setCSSStyleSheet(href, baseURL, charset, sheet);
- }
- private:
- StyleRuleImport* m_ownerRule;
- };
-
- void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*);
- friend class ImportedStyleSheetClient;
-
StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet>);
- StyleSheetContents* m_parentStyleSheet;
+ virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*);
- ImportedStyleSheetClient m_styleSheetClient;
String m_strHref;
RefPtr<MediaQuerySet> m_mediaQueries;
RefPtr<StyleSheetContents> m_styleSheet;
+
CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet;
- bool m_loading;
+ struct LoadContext {
+ LoadContext(CSSStyleSheet* rootStyleSheet, const CSSParserContext& parentParserContext);
+ RefPtr<CSSStyleSheet> rootStyleSheet;
+ CSSParserContext parentParserContext;
+ };
+ OwnPtr<LoadContext> m_loadContext;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/css/StyleSheetContents.cpp (126716 => 126717)
--- trunk/Source/WebCore/css/StyleSheetContents.cpp 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/css/StyleSheetContents.cpp 2012-08-26 23:48:39 UTC (rev 126717)
@@ -54,11 +54,9 @@
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(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 @@
// 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 @@
// 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::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 @@
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 @@
--childVectorIndex;
}
if (childVectorIndex < m_importRules.size()) {
- m_importRules[childVectorIndex]->clearParentStyleSheet();
m_importRules.remove(childVectorIndex);
return;
}
@@ -266,8 +250,22 @@
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 @@
// 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();
@@ -294,9 +293,13 @@
// 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)
+ && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1) {
clearRules();
+ return;
+ }
}
+
+ requestImportedStyleSheets(rootSheet);
}
bool StyleSheetContents::parseString(const String& sheetText)
@@ -309,6 +312,10 @@
CSSParser p(parserContext());
p.parseSheet(this, sheetText, startLineNumber);
+ if (!m_clients.isEmpty()) {
+ ASSERT(m_clients.size() == 1);
+ requestImportedStyleSheets(m_clients[0]);
+ }
return true;
}
@@ -321,66 +328,70 @@
return false;
}
-void StyleSheetContents::checkLoaded()
+bool StyleSheetContents::checkImportedSheetLoadCompleted()
{
- if (isLoading())
+ 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()
+{
+ if (m_clients.isEmpty())
return;
+ if (!checkImportedSheetLoadCompleted())
+ return;
- // 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;
+ ASSERT(hasOneClient());
+ ASSERT(!m_clients[0]->parentStyleSheet());
+ RefPtr<Node> ownerNode = m_clients[0]->ownerNode();
+ if (!ownerNode)
return;
- }
- RefPtr<Node> ownerNode = singleOwnerNode();
- if (!ownerNode) {
- m_loadCompleted = true;
- return;
- }
+
m_loadCompleted = ownerNode->sheetLoaded();
if (m_loadCompleted)
ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
}
-void StyleSheetContents::notifyLoadedSheet(const CachedCSSStyleSheet* sheet)
+bool StyleSheetContents::getAncestors(const StyleRuleImport* importRule, Vector<const StyleSheetContents*>& result) const
{
- ASSERT(sheet);
- m_didLoadErrorOccur |= sheet->errorOccurred();
+ 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;
}
-void StyleSheetContents::startLoadingDynamicSheet()
+bool StyleSheetContents::hasImportCycle(const StyleRuleImport* importRule, const KURL& importURL, const KURL& documentBaseURL) const
{
- if (Node* owner = singleOwnerNode())
- owner->startLoadingDynamicSheet();
-}
+ Vector<const StyleSheetContents*> ancestors;
+ getAncestors(importRule, ancestors);
-StyleSheetContents* StyleSheetContents::rootStyleSheet() const
-{
- const StyleSheetContents* root = this;
- while (root->parentStyleSheet())
- root = root->parentStyleSheet();
- return const_cast<StyleSheetContents*>(root);
+ 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;
}
-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
{
return CSSParser::completeURL(m_parserContext, url);
@@ -451,11 +462,6 @@
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));
Modified: trunk/Source/WebCore/css/StyleSheetContents.h (126716 => 126717)
--- trunk/Source/WebCore/css/StyleSheetContents.h 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/css/StyleSheetContents.h 2012-08-26 23:48:39 UTC (rev 126717)
@@ -44,16 +44,12 @@
public:
static PassRefPtr<StyleSheetContents> create(const CSSParserContext& context = CSSParserContext(CSSStrictMode))
{
- return adoptRef(new StyleSheetContents(0, String(), context));
+ return adoptRef(new StyleSheetContents(String(), context));
}
static PassRefPtr<StyleSheetContents> create(const String& originalURL, const CSSParserContext& context)
{
- return adoptRef(new StyleSheetContents(0, originalURL, context));
+ return adoptRef(new StyleSheetContents(originalURL, context));
}
- static PassRefPtr<StyleSheetContents> create(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
- {
- return adoptRef(new StyleSheetContents(ownerRule, originalURL, context));
- }
~StyleSheetContents();
@@ -61,7 +57,7 @@
const AtomicString& determineNamespace(const AtomicString& prefix);
- void parseAuthorStyleSheet(const CachedCSSStyleSheet*, const SecurityOrigin*);
+ void parseAuthorStyleSheet(const CachedCSSStyleSheet*, CSSStyleSheet* rootSheet);
bool parseString(const String&);
bool parseStringAtLine(const String&, int startLineNumber);
@@ -69,13 +65,8 @@
bool isLoading() const;
- void checkLoaded();
- void startLoadingDynamicSheet();
+ void checkLoadCompleted();
- StyleSheetContents* rootStyleSheet() const;
- Node* singleOwnerNode() const;
- Document* singleOwnerDocument() const;
-
const String& charset() const { return m_parserContext.charset; }
bool loadCompleted() const { return m_loadCompleted; }
@@ -102,12 +93,8 @@
const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
const Vector<RefPtr<StyleRuleImport> >& importRules() const { return m_importRules; }
- void notifyLoadedSheet(const CachedCSSStyleSheet*);
-
- StyleSheetContents* parentStyleSheet() const;
- StyleRuleImport* ownerRule() const { return m_ownerRule; }
- void clearOwnerRule() { m_ownerRule = 0; }
-
+ bool hasImportCycle(const StyleRuleImport* importRule, const KURL& importURL, const KURL& documentBaseURL) const;
+
// Note that href is the URL that started the redirect chain that led to
// this style sheet. This property probably isn't useful for much except
// the _javascript_ binding (which needs to use this value for security).
@@ -124,6 +111,8 @@
bool wrapperInsertRule(PassRefPtr<StyleRuleBase>, unsigned index);
void wrapperDeleteRule(unsigned index);
+ void requestImportedStyleSheets(CSSStyleSheet* rootSheet);
+
PassRefPtr<StyleSheetContents> copy() const { return adoptRef(new StyleSheetContents(*this)); }
void registerClient(CSSStyleSheet*);
@@ -140,12 +129,13 @@
void reportMemoryUsage(MemoryObjectInfo*) const;
private:
- StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext&);
+ StyleSheetContents(const String& originalURL, const CSSParserContext&);
StyleSheetContents(const StyleSheetContents&);
void clearCharsetRule();
- StyleRuleImport* m_ownerRule;
+ bool checkImportedSheetLoadCompleted();
+ bool getAncestors(const StyleRuleImport*, Vector<const StyleSheetContents*>& result) const;
String m_originalURL;
Modified: trunk/Source/WebCore/dom/ProcessingInstruction.cpp (126716 => 126717)
--- trunk/Source/WebCore/dom/ProcessingInstruction.cpp 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/dom/ProcessingInstruction.cpp 2012-08-26 23:48:39 UTC (rev 126717)
@@ -254,7 +254,7 @@
m_loading = false;
if (m_isCSS)
- static_cast<CSSStyleSheet*>(m_sheet.get())->contents()->checkLoaded();
+ static_cast<CSSStyleSheet*>(m_sheet.get())->contents()->checkLoadCompleted();
#if ENABLE(XSLT)
else if (m_isXSL)
static_cast<XSLStyleSheet*>(m_sheet.get())->checkLoaded();
Modified: trunk/Source/WebCore/dom/StyleElement.cpp (126716 => 126717)
--- trunk/Source/WebCore/dom/StyleElement.cpp 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/dom/StyleElement.cpp 2012-08-26 23:48:39 UTC (rev 126717)
@@ -181,7 +181,7 @@
}
if (m_sheet)
- m_sheet->contents()->checkLoaded();
+ m_sheet->contents()->checkLoadCompleted();
}
bool StyleElement::isLoading() const
Modified: trunk/Source/WebCore/html/HTMLLinkElement.cpp (126716 => 126717)
--- trunk/Source/WebCore/html/HTMLLinkElement.cpp 2012-08-26 22:38:31 UTC (rev 126716)
+++ trunk/Source/WebCore/html/HTMLLinkElement.cpp 2012-08-26 23:48:39 UTC (rev 126717)
@@ -323,11 +323,10 @@
m_sheet->setMediaQueries(MediaQuerySet::createAllowingDescriptionSyntax(m_media));
m_sheet->setTitle(title());
- styleSheet->parseAuthorStyleSheet(cachedStyleSheet, document()->securityOrigin());
+ styleSheet->parseAuthorStyleSheet(cachedStyleSheet, m_sheet.get());
m_loading = false;
- styleSheet->notifyLoadedSheet(cachedStyleSheet);
- styleSheet->checkLoaded();
+ styleSheet->checkLoadCompleted();
#if ENABLE(PARSED_STYLE_SHEET_CACHING)
if (styleSheet->isCacheable())