Diff
Modified: trunk/Source/WebCore/ChangeLog (128636 => 128637)
--- trunk/Source/WebCore/ChangeLog 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/ChangeLog 2012-09-14 19:04:17 UTC (rev 128637)
@@ -1,3 +1,65 @@
+2012-09-14 Alexey Proskuryakov <[email protected]>
+
+ REGRESSION(r126717): It made inspector/styles/media-queries.html fail/flakey
+ https://bugs.webkit.org/show_bug.cgi?id=95070
+
+ Roll out r126717, and another change that depends on it.
+ r126717: Remove parent pointer from StyleSheetContents and StyleRuleImport
+ r127123: Cache and share parsed imported stylesheets
+
+ * css/CSSImportRule.cpp:
+ * css/CSSImportRule.h:
+ * css/CSSStyleSheet.cpp:
+ (WebCore::CSSStyleSheet::willMutateRules):
+ (WebCore::CSSStyleSheet::reattachChildRuleCSSOMWrappers):
+ (WebCore::CSSStyleSheet::insertRule):
+ (WebCore::CSSStyleSheet::ownerDocument):
+ * css/CSSStyleSheet.h:
+ (WebCore::CSSStyleSheet::clearOwnerRule):
+ * css/StyleRuleImport.cpp:
+ (WebCore::StyleRuleImport::StyleRuleImport):
+ (WebCore::StyleRuleImport::~StyleRuleImport):
+ (WebCore::StyleRuleImport::setCSSStyleSheet):
+ (WebCore::StyleRuleImport::isLoading):
+ (WebCore::StyleRuleImport::requestStyleSheet):
+ * css/StyleRuleImport.h:
+ (WebCore::StyleRuleImport::parentStyleSheet):
+ (WebCore::StyleRuleImport::setParentStyleSheet):
+ (WebCore::StyleRuleImport::clearParentStyleSheet):
+ (ImportedStyleSheetClient):
+ (WebCore::StyleRuleImport::ImportedStyleSheetClient::ImportedStyleSheetClient):
+ (WebCore::StyleRuleImport::ImportedStyleSheetClient::~ImportedStyleSheetClient):
+ (WebCore::StyleRuleImport::ImportedStyleSheetClient::setCSSStyleSheet):
+ * css/StyleSheetContents.cpp:
+ (WebCore::StyleSheetContents::StyleSheetContents):
+ (WebCore::StyleSheetContents::isCacheable):
+ (WebCore::StyleSheetContents::parserAppendRule):
+ (WebCore::StyleSheetContents::clearRules):
+ (WebCore::StyleSheetContents::wrapperInsertRule):
+ (WebCore::StyleSheetContents::wrapperDeleteRule):
+ (WebCore::StyleSheetContents::parseAuthorStyleSheet):
+ (WebCore::StyleSheetContents::parseStringAtLine):
+ (WebCore::StyleSheetContents::checkLoaded):
+ (WebCore::StyleSheetContents::notifyLoadedSheet):
+ (WebCore::StyleSheetContents::startLoadingDynamicSheet):
+ (WebCore::StyleSheetContents::rootStyleSheet):
+ (WebCore::StyleSheetContents::singleOwnerNode):
+ (WebCore::StyleSheetContents::singleOwnerDocument):
+ (WebCore::StyleSheetContents::parentStyleSheet):
+ * css/StyleSheetContents.h:
+ (WebCore::StyleSheetContents::create):
+ (StyleSheetContents):
+ (WebCore::StyleSheetContents::ownerRule):
+ (WebCore::StyleSheetContents::clearOwnerRule):
+ * dom/ProcessingInstruction.cpp:
+ (WebCore::ProcessingInstruction::parseStyleSheet):
+ * dom/StyleElement.cpp:
+ (WebCore::StyleElement::createSheet):
+ * html/HTMLLinkElement.cpp:
+ (WebCore::HTMLLinkElement::setCSSStyleSheet):
+ * loader/cache/CachedCSSStyleSheet.cpp:
+ (WebCore::CachedCSSStyleSheet::saveParsedStyleSheet):
+
2012-09-14 Ojan Vafai <[email protected]>
Simplify some code in RenderBox::computePercentageLogicalHeight
Modified: trunk/Source/WebCore/css/CSSImportRule.cpp (128636 => 128637)
--- trunk/Source/WebCore/css/CSSImportRule.cpp 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/css/CSSImportRule.cpp 2012-09-14 19:04:17 UTC (rev 128637)
@@ -86,13 +86,6 @@
info.addInstrumentedMember(m_styleSheetCSSOMWrapper);
}
-void CSSImportRule::reattachStyleSheetContents()
-{
- ASSERT(m_styleSheetCSSOMWrapper);
- ASSERT(!parentStyleSheet() || parentStyleSheet()->contents()->hasOneClient());
- m_importRule->reattachStyleSheetContents(m_styleSheetCSSOMWrapper->contents());
-}
-
CSSStyleSheet* CSSImportRule::styleSheet() const
{
if (!m_importRule->styleSheet())
Modified: trunk/Source/WebCore/css/CSSImportRule.h (128636 => 128637)
--- trunk/Source/WebCore/css/CSSImportRule.h 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/css/CSSImportRule.h 2012-09-14 19:04:17 UTC (rev 128637)
@@ -45,8 +45,6 @@
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
- void reattachStyleSheetContents();
-
private:
CSSImportRule(StyleRuleImport*, CSSStyleSheet*);
Modified: trunk/Source/WebCore/css/CSSStyleSheet.cpp (128636 => 128637)
--- trunk/Source/WebCore/css/CSSStyleSheet.cpp 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/css/CSSStyleSheet.cpp 2012-09-14 19:04:17 UTC (rev 128637)
@@ -36,7 +36,6 @@
#include "SVGNames.h"
#include "SecurityOrigin.h"
#include "StyleRule.h"
-#include "StyleRuleImport.h"
#include "StyleSheetContents.h"
#include "WebCoreMemoryInstrumentation.h"
#include <wtf/text/StringBuilder.h>
@@ -151,7 +150,7 @@
m_contents->setMutable();
// Any existing CSSOM wrappers need to be connected to the copied child rules.
- reattachCSSOMWrappers();
+ reattachChildRuleCSSOMWrappers();
}
void CSSStyleSheet::didMutateRules()
@@ -170,11 +169,8 @@
owner->styleResolverChanged(DeferRecalcStyle);
}
-void CSSStyleSheet::reattachCSSOMWrappers()
+void CSSStyleSheet::reattachChildRuleCSSOMWrappers()
{
- if (m_ownerRule)
- m_ownerRule->reattachStyleSheetContents();
-
for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
if (!m_childRuleCSSOMWrappers[i])
continue;
@@ -287,10 +283,7 @@
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>());
@@ -377,17 +370,11 @@
return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0;
}
-CSSStyleSheet* CSSStyleSheet::rootStyleSheet() const
+Document* CSSStyleSheet::ownerDocument() 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 (128636 => 128637)
--- trunk/Source/WebCore/css/CSSStyleSheet.h 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/css/CSSStyleSheet.h 2012-09-14 19:04:17 UTC (rev 128637)
@@ -80,7 +80,6 @@
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>);
@@ -102,6 +101,7 @@
void didMutate();
void clearChildRuleCSSOMWrappers();
+ void reattachChildRuleCSSOMWrappers();
StyleSheetContents* contents() const { return m_contents.get(); }
@@ -115,7 +115,6 @@
virtual String type() const { return "text/css"; }
bool canAccessRules() const;
- void reattachCSSOMWrappers();
RefPtr<StyleSheetContents> m_contents;
bool m_isInlineStylesheet;
Modified: trunk/Source/WebCore/css/StyleRuleImport.cpp (128636 => 128637)
--- trunk/Source/WebCore/css/StyleRuleImport.cpp 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/css/StyleRuleImport.cpp 2012-09-14 19:04:17 UTC (rev 128637)
@@ -32,12 +32,6 @@
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));
@@ -45,9 +39,12 @@
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());
@@ -55,92 +52,85 @@
StyleRuleImport::~StyleRuleImport()
{
+ if (m_styleSheet)
+ m_styleSheet->clearOwnerRule();
if (m_cachedSheet)
- m_cachedSheet->removeClient(this);
+ m_cachedSheet->removeClient(&m_styleSheetClient);
}
-void StyleRuleImport::setCSSStyleSheet(const String& url, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*)
+void StyleRuleImport::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* cachedStyleSheet)
{
- ASSERT(m_loadContext);
- ASSERT(!m_styleSheet);
- ASSERT(m_cachedSheet);
+ if (m_styleSheet)
+ m_styleSheet->clearOwnerRule();
- OwnPtr<LoadContext> loadContext = m_loadContext.release();
-
- CSSParserContext parserContext = loadContext->parentParserContext;
+ CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : CSSStrictMode;
+ context.charset = charset;
if (!baseURL.isNull())
- parserContext.baseURL = baseURL;
- parserContext.charset = charset;
+ context.baseURL = baseURL;
-#if ENABLE(PARSED_STYLE_SHEET_CACHING)
- m_styleSheet = m_cachedSheet->restoreParsedStyleSheet(parserContext);
-#endif
- if (!m_styleSheet) {
- m_styleSheet = StyleSheetContents::create(url, parserContext);
- m_styleSheet->parseAuthorStyleSheet(m_cachedSheet.get(), loadContext->rootStyleSheet.get());
- }
- loadContext->rootStyleSheet->contents()->checkLoadCompleted();
+ m_styleSheet = StyleSheetContents::create(this, href, context);
-#if ENABLE(PARSED_STYLE_SHEET_CACHING)
- if (m_styleSheet->isCacheable())
- m_cachedSheet->saveParsedStyleSheet(m_styleSheet);
-#endif
+ 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();
+ }
}
bool StyleRuleImport::isLoading() const
{
- return m_loadContext || (m_styleSheet && m_styleSheet->isLoading());
+ return m_loading || (m_styleSheet && m_styleSheet->isLoading());
}
-bool StyleRuleImport::hadLoadError() const
+void StyleRuleImport::requestStyleSheet()
{
- return m_cachedSheet && m_cachedSheet->errorOccurred();
-}
-
-void StyleRuleImport::requestStyleSheet(CSSStyleSheet* rootSheet, const CSSParserContext& parserContext)
-{
- ASSERT(!rootSheet->parentStyleSheet());
- ASSERT(!m_cachedSheet);
-
- Node* ownerNode = rootSheet->ownerNode();
- if (!ownerNode)
+ if (!m_parentStyleSheet)
return;
- Document* document = ownerNode->document();
-
- KURL resolvedURL;
- if (!parserContext.baseURL.isNull())
- resolvedURL = KURL(parserContext.baseURL, m_strHref);
- else
- resolvedURL = document->completeURL(m_strHref);
-
- StyleSheetContents* rootSheetContents = rootSheet->contents();
- if (rootSheetContents->hasImportCycle(this, resolvedURL, document->baseURL()))
+ Document* document = m_parentStyleSheet->singleOwnerDocument();
+ if (!document)
return;
- ResourceRequest request(resolvedURL);
CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
- if (rootSheetContents->isUserStyleSheet())
- m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request, parserContext.charset);
+ if (!cachedResourceLoader)
+ return;
+
+ KURL absURL;
+ if (!m_parentStyleSheet->baseURL().isNull())
+ // use parent styleheet's URL as the base URL
+ absURL = KURL(m_parentStyleSheet->baseURL(), m_strHref);
else
- m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(request, parserContext.charset);
+ absURL = document->completeURL(m_strHref);
- 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();
+ // 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;
+ }
- m_loadContext = adoptPtr(new LoadContext(rootSheet, parserContext));
- m_cachedSheet->addClient(this);
+ ResourceRequest request(absURL);
+ if (m_parentStyleSheet->isUserStyleSheet())
+ m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request, m_parentStyleSheet->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);
+ }
}
-void StyleRuleImport::reattachStyleSheetContents(StyleSheetContents* contents)
-{
- m_styleSheet = contents;
-}
-
void StyleRuleImport::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
Modified: trunk/Source/WebCore/css/StyleRuleImport.h (128636 => 128637)
--- trunk/Source/WebCore/css/StyleRuleImport.h 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/css/StyleRuleImport.h 2012-09-14 19:04:17 UTC (rev 128637)
@@ -22,7 +22,6 @@
#ifndef StyleRuleImport_h
#define StyleRuleImport_h
-#include "CSSParserMode.h"
#include "CachedResourceHandle.h"
#include "CachedStyleSheetClient.h"
#include "StyleRule.h"
@@ -33,42 +32,55 @@
class MediaQuerySet;
class StyleSheetContents;
-class StyleRuleImport : public StyleRuleBase, public CachedStyleSheetClient {
+class StyleRuleImport : public StyleRuleBase {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassRefPtr<StyleRuleImport> create(const String& href, PassRefPtr<MediaQuerySet>);
- virtual ~StyleRuleImport();
+ ~StyleRuleImport();
+
+ StyleSheetContents* parentStyleSheet() const { return m_parentStyleSheet; }
+ void setParentStyleSheet(StyleSheetContents* sheet) { ASSERT(sheet); m_parentStyleSheet = sheet; }
+ void clearParentStyleSheet() { m_parentStyleSheet = 0; }
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(CSSStyleSheet* rootSheet, const CSSParserContext&);
+ void requestStyleSheet();
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
- void reattachStyleSheetContents(StyleSheetContents*);
+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;
+ };
-private:
+ void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*);
+ friend class ImportedStyleSheetClient;
+
StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet>);
- virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet*);
+ StyleSheetContents* m_parentStyleSheet;
+ ImportedStyleSheetClient m_styleSheetClient;
String m_strHref;
RefPtr<MediaQuerySet> m_mediaQueries;
RefPtr<StyleSheetContents> m_styleSheet;
-
CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet;
- struct LoadContext {
- LoadContext(CSSStyleSheet* rootStyleSheet, const CSSParserContext& parentParserContext);
- RefPtr<CSSStyleSheet> rootStyleSheet;
- CSSParserContext parentParserContext;
- };
- OwnPtr<LoadContext> m_loadContext;
+ bool m_loading;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/css/StyleSheetContents.cpp (128636 => 128637)
--- trunk/Source/WebCore/css/StyleSheetContents.cpp 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/css/StyleSheetContents.cpp 2012-09-14 19:04:17 UTC (rev 128637)
@@ -54,9 +54,11 @@
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 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 @@
// 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 @@
// 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::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 @@
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 @@
--childVectorIndex;
}
if (childVectorIndex < m_importRules.size()) {
+ m_importRules[childVectorIndex]->clearParentStyleSheet();
m_importRules.remove(childVectorIndex);
return;
}
@@ -250,22 +266,8 @@
return it->second;
}
-void StyleSheetContents::requestImportedStyleSheets(CSSStyleSheet* rootSheet)
+void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cachedStyleSheet, const SecurityOrigin* securityOrigin)
{
- 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;
@@ -279,7 +281,6 @@
// 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 @@
// 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 @@
CSSParser p(parserContext());
p.parseSheet(this, sheetText, startLineNumber);
- if (!m_clients.isEmpty()) {
- ASSERT(m_clients.size() == 1);
- requestImportedStyleSheets(m_clients[0]);
- }
return true;
}
@@ -327,72 +320,68 @@
return false;
}
-bool StyleSheetContents::checkImportedSheetLoadCompleted()
+void StyleSheetContents::checkLoaded()
{
- 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())
+ if (isLoading())
return;
- if (!checkImportedSheetLoadCompleted())
- 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
{
return CSSParser::completeURL(m_parserContext, url);
@@ -463,6 +452,11 @@
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 (128636 => 128637)
--- trunk/Source/WebCore/css/StyleSheetContents.h 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/css/StyleSheetContents.h 2012-09-14 19:04:17 UTC (rev 128637)
@@ -43,12 +43,16 @@
public:
static PassRefPtr<StyleSheetContents> create(const CSSParserContext& context = CSSParserContext(CSSStrictMode))
{
- return adoptRef(new StyleSheetContents(String(), context));
+ return adoptRef(new StyleSheetContents(0, String(), context));
}
static PassRefPtr<StyleSheetContents> create(const String& originalURL, const CSSParserContext& context)
{
- return adoptRef(new StyleSheetContents(originalURL, context));
+ return adoptRef(new StyleSheetContents(0, originalURL, context));
}
+ static PassRefPtr<StyleSheetContents> create(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
+ {
+ return adoptRef(new StyleSheetContents(ownerRule, originalURL, context));
+ }
~StyleSheetContents();
@@ -56,7 +60,7 @@
const AtomicString& determineNamespace(const AtomicString& prefix);
- void parseAuthorStyleSheet(const CachedCSSStyleSheet*, CSSStyleSheet* rootSheet);
+ void parseAuthorStyleSheet(const CachedCSSStyleSheet*, const SecurityOrigin*);
bool parseString(const String&);
bool parseStringAtLine(const String&, int startLineNumber);
@@ -64,8 +68,13 @@
bool isLoading() const;
- void checkLoadCompleted();
+ void checkLoaded();
+ void startLoadingDynamicSheet();
+ StyleSheetContents* rootStyleSheet() const;
+ Node* singleOwnerNode() const;
+ Document* singleOwnerDocument() const;
+
const String& charset() const { return m_parserContext.charset; }
bool loadCompleted() const { return m_loadCompleted; }
@@ -92,8 +101,12 @@
const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
const Vector<RefPtr<StyleRuleImport> >& importRules() const { return m_importRules; }
- bool hasImportCycle(const StyleRuleImport* importRule, const KURL& importURL, const KURL& documentBaseURL) const;
-
+ void notifyLoadedSheet(const CachedCSSStyleSheet*);
+
+ StyleSheetContents* parentStyleSheet() const;
+ StyleRuleImport* ownerRule() const { return m_ownerRule; }
+ void clearOwnerRule() { m_ownerRule = 0; }
+
// 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).
@@ -110,8 +123,6 @@
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*);
@@ -128,13 +139,12 @@
void reportMemoryUsage(MemoryObjectInfo*) const;
private:
- StyleSheetContents(const String& originalURL, const CSSParserContext&);
+ StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext&);
StyleSheetContents(const StyleSheetContents&);
void clearCharsetRule();
- bool checkImportedSheetLoadCompleted();
- bool getAncestors(const StyleRuleImport*, Vector<const StyleSheetContents*>& result) const;
+ StyleRuleImport* m_ownerRule;
String m_originalURL;
Modified: trunk/Source/WebCore/dom/ProcessingInstruction.cpp (128636 => 128637)
--- trunk/Source/WebCore/dom/ProcessingInstruction.cpp 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/dom/ProcessingInstruction.cpp 2012-09-14 19:04:17 UTC (rev 128637)
@@ -254,7 +254,7 @@
m_loading = false;
if (m_isCSS)
- static_cast<CSSStyleSheet*>(m_sheet.get())->contents()->checkLoadCompleted();
+ static_cast<CSSStyleSheet*>(m_sheet.get())->contents()->checkLoaded();
#if ENABLE(XSLT)
else if (m_isXSL)
static_cast<XSLStyleSheet*>(m_sheet.get())->checkLoaded();
Modified: trunk/Source/WebCore/dom/StyleElement.cpp (128636 => 128637)
--- trunk/Source/WebCore/dom/StyleElement.cpp 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/dom/StyleElement.cpp 2012-09-14 19:04:17 UTC (rev 128637)
@@ -149,7 +149,6 @@
{
ASSERT(e);
ASSERT(e->inDocument());
-
Document* document = e->document();
if (m_sheet) {
if (m_sheet->isLoading())
@@ -182,7 +181,7 @@
}
if (m_sheet)
- m_sheet->contents()->checkLoadCompleted();
+ m_sheet->contents()->checkLoaded();
}
bool StyleElement::isLoading() const
Modified: trunk/Source/WebCore/html/HTMLLinkElement.cpp (128636 => 128637)
--- trunk/Source/WebCore/html/HTMLLinkElement.cpp 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/html/HTMLLinkElement.cpp 2012-09-14 19:04:17 UTC (rev 128637)
@@ -323,10 +323,11 @@
m_sheet->setMediaQueries(MediaQuerySet::createAllowingDescriptionSyntax(m_media));
m_sheet->setTitle(title());
- styleSheet->parseAuthorStyleSheet(cachedStyleSheet, m_sheet.get());
+ styleSheet->parseAuthorStyleSheet(cachedStyleSheet, document()->securityOrigin());
m_loading = false;
- styleSheet->checkLoadCompleted();
+ styleSheet->notifyLoadedSheet(cachedStyleSheet);
+ styleSheet->checkLoaded();
#if ENABLE(PARSED_STYLE_SHEET_CACHING)
if (styleSheet->isCacheable())
Modified: trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp (128636 => 128637)
--- trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp 2012-09-14 18:53:01 UTC (rev 128636)
+++ trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp 2012-09-14 19:04:17 UTC (rev 128637)
@@ -185,8 +185,7 @@
void CachedCSSStyleSheet::saveParsedStyleSheet(PassRefPtr<StyleSheetContents> sheet)
{
ASSERT(sheet && sheet->isCacheable());
- if (m_parsedStyleSheetCache == sheet)
- return;
+
if (m_parsedStyleSheetCache)
m_parsedStyleSheetCache->removedFromMemoryCache();
m_parsedStyleSheetCache = sheet;