Title: [128637] trunk/Source/WebCore
Revision
128637
Author
[email protected]
Date
2012-09-14 12:04:17 -0700 (Fri, 14 Sep 2012)

Log Message

        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):

Modified Paths

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;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to