Make some things that return never-null pointers return references instead.
[WebKit-https.git] / Source / WebCore / dom / DocumentStyleSheetCollection.cpp
index 7886793..622fe62 100644 (file)
@@ -29,6 +29,7 @@
 #include "DocumentStyleSheetCollection.h"
 
 #include "CSSStyleSheet.h"
+#include "DOMWrapperWorld.h"
 #include "Document.h"
 #include "Element.h"
 #include "HTMLIFrameElement.h"
@@ -47,9 +48,6 @@
 #include "StyleSheetContents.h"
 #include "StyleSheetList.h"
 #include "UserContentURLPattern.h"
-#include "WebCoreMemoryInstrumentation.h"
-#include <wtf/MemoryInstrumentationListHashSet.h>
-#include <wtf/MemoryInstrumentationVector.h>
 
 namespace WebCore {
 
@@ -60,7 +58,7 @@ DocumentStyleSheetCollection::DocumentStyleSheetCollection(Document* document)
     , m_pendingStylesheets(0)
     , m_injectedStyleSheetCacheValid(false)
     , m_hadActiveLoadingStylesheet(false)
-    , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
+    , m_pendingUpdateType(NoUpdate)
     , m_usesSiblingRules(false)
     , m_usesSiblingRulesOverride(false)
     , m_usesFirstLineRules(false)
@@ -81,23 +79,25 @@ DocumentStyleSheetCollection::~DocumentStyleSheetCollection()
         m_injectedAuthorStyleSheets[i]->clearOwnerNode();
     for (unsigned i = 0; i < m_userStyleSheets.size(); ++i)
         m_userStyleSheets[i]->clearOwnerNode();
+    for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i)
+        m_authorStyleSheets[i]->clearOwnerNode();
 }
 
 void DocumentStyleSheetCollection::combineCSSFeatureFlags()
 {
     // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/after).
-    StyleResolver* styleResolver = m_document->styleResolver();
-    m_usesSiblingRules = m_usesSiblingRules || styleResolver->usesSiblingRules();
-    m_usesFirstLineRules = m_usesFirstLineRules || styleResolver->usesFirstLineRules();
-    m_usesBeforeAfterRules = m_usesBeforeAfterRules || styleResolver->usesBeforeAfterRules();
+    const StyleResolver& styleResolver = m_document->ensureStyleResolver();
+    m_usesSiblingRules = m_usesSiblingRules || styleResolver.usesSiblingRules();
+    m_usesFirstLineRules = m_usesFirstLineRules || styleResolver.usesFirstLineRules();
+    m_usesBeforeAfterRules = m_usesBeforeAfterRules || styleResolver.usesBeforeAfterRules();
 }
 
 void DocumentStyleSheetCollection::resetCSSFeatureFlags()
 {
-    StyleResolver* styleResolver = m_document->styleResolver();
-    m_usesSiblingRules = styleResolver->usesSiblingRules();
-    m_usesFirstLineRules = styleResolver->usesFirstLineRules();
-    m_usesBeforeAfterRules = styleResolver->usesBeforeAfterRules();
+    const StyleResolver& styleResolver = m_document->ensureStyleResolver();
+    m_usesSiblingRules = styleResolver.usesSiblingRules();
+    m_usesFirstLineRules = styleResolver.usesFirstLineRules();
+    m_usesBeforeAfterRules = styleResolver.usesBeforeAfterRules();
 }
 
 CSSStyleSheet* DocumentStyleSheetCollection::pageUserSheet()
@@ -187,12 +187,24 @@ void DocumentStyleSheetCollection::updateInjectedStyleSheetCache() const
 
 void DocumentStyleSheetCollection::invalidateInjectedStyleSheetCache()
 {
+    if (!m_injectedStyleSheetCacheValid)
+        return;
     m_injectedStyleSheetCacheValid = false;
+    if (m_injectedUserStyleSheets.isEmpty() && m_injectedAuthorStyleSheets.isEmpty())
+        return;
     m_document->styleResolverChanged(DeferRecalcStyle);
 }
 
+void DocumentStyleSheetCollection::addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet)
+{
+    ASSERT(!authorSheet->isUserStyleSheet());
+    m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document));
+    m_document->styleResolverChanged(RecalcStyleImmediately);
+}
+
 void DocumentStyleSheetCollection::addUserSheet(PassRefPtr<StyleSheetContents> userSheet)
 {
+    ASSERT(userSheet->isUserStyleSheet());
     m_userStyleSheets.append(CSSStyleSheet::create(userSheet, m_document));
     m_document->styleResolverChanged(RecalcStyleImmediately);
 }
@@ -288,10 +300,10 @@ void DocumentStyleSheetCollection::collectActiveStyleSheets(Vector<RefPtr<StyleS
                    ||  (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
 #endif
                    ) {
-            Element* e = static_cast<Element*>(n);
+            Element* e = toElement(n);
             AtomicString title = e->getAttribute(titleAttr);
             bool enabledViaScript = false;
-            if (e->hasLocalName(linkTag)) {
+            if (e->hasTagName(linkTag)) {
                 // <LINK> element
                 HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(n);
                 if (linkElement->isDisabled())
@@ -314,15 +326,17 @@ void DocumentStyleSheetCollection::collectActiveStyleSheets(Vector<RefPtr<StyleS
             // Get the current preferred styleset. This is the
             // set of sheets that will be enabled.
 #if ENABLE(SVG)
-            if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
+            if (e->hasTagName(SVGNames::styleTag))
                 sheet = static_cast<SVGStyleElement*>(n)->sheet();
             else
 #endif
-            if (e->hasLocalName(linkTag))
-                sheet = static_cast<HTMLLinkElement*>(n)->sheet();
-            else
-                // <STYLE> element
-                sheet = static_cast<HTMLStyleElement*>(n)->sheet();
+            {
+                if (e->hasTagName(linkTag))
+                    sheet = static_cast<HTMLLinkElement*>(n)->sheet();
+                else
+                    // <STYLE> element
+                    sheet = toHTMLStyleElement(e)->sheet();
+            }
             // Check to see if this sheet belongs to a styleset
             // (thus making it PREFERRED or ALTERNATE rather than
             // PERSISTENT).
@@ -334,7 +348,7 @@ void DocumentStyleSheetCollection::collectActiveStyleSheets(Vector<RefPtr<StyleS
                     // we are NOT an alternate sheet, then establish
                     // us as the preferred set. Otherwise, just ignore
                     // this sheet.
-                    if (e->hasLocalName(styleTag) || !rel.contains("alternate"))
+                    if (e->hasTagName(styleTag) || !rel.contains("alternate"))
                         m_preferredStylesheetSetName = m_selectedStylesheetSetName = title;
                 }
                 if (title != m_preferredStylesheetSetName)
@@ -417,14 +431,17 @@ static bool styleSheetsUseRemUnits(const Vector<RefPtr<CSSStyleSheet> >& sheets)
     return false;
 }
 
-static void filterEnabledCSSStyleSheets(Vector<RefPtr<CSSStyleSheet> >& result, const Vector<RefPtr<StyleSheet> >& sheets)
+static void filterEnabledNonemptyCSSStyleSheets(Vector<RefPtr<CSSStyleSheet> >& result, const Vector<RefPtr<StyleSheet> >& sheets)
 {
     for (unsigned i = 0; i < sheets.size(); ++i) {
         if (!sheets[i]->isCSSStyleSheet())
             continue;
         if (sheets[i]->disabled())
             continue;
-        result.append(static_cast<CSSStyleSheet*>(sheets[i].get()));
+        CSSStyleSheet* sheet = static_cast<CSSStyleSheet*>(sheets[i].get());
+        if (!sheet->length())
+            continue;
+        result.append(sheet);
     }
 }
 
@@ -433,7 +450,7 @@ static void collectActiveCSSStyleSheetsFromSeamlessParents(Vector<RefPtr<CSSStyl
     HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
     if (!seamlessParentIFrame)
         return;
-    sheets.append(seamlessParentIFrame->document()->styleSheetCollection()->activeAuthorStyleSheets());
+    sheets.appendVector(seamlessParentIFrame->document()->styleSheetCollection()->activeAuthorStyleSheets());
 }
 
 bool DocumentStyleSheetCollection::updateActiveStyleSheets(UpdateFlag updateFlag)
@@ -442,7 +459,7 @@ bool DocumentStyleSheetCollection::updateActiveStyleSheets(UpdateFlag updateFlag
         // SVG <use> element may manage to invalidate style selector in the middle of a style recalc.
         // https://bugs.webkit.org/show_bug.cgi?id=54344
         // FIXME: This should be fixed in SVG and the call site replaced by ASSERT(!m_inStyleRecalc).
-        m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
+        m_pendingUpdateType = FullUpdate;
         m_document->scheduleForcedStyleRecalc();
         return false;
 
@@ -454,9 +471,10 @@ bool DocumentStyleSheetCollection::updateActiveStyleSheets(UpdateFlag updateFlag
     collectActiveStyleSheets(activeStyleSheets);
 
     Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
-    activeCSSStyleSheets.append(injectedAuthorStyleSheets());
+    activeCSSStyleSheets.appendVector(injectedAuthorStyleSheets());
+    activeCSSStyleSheets.appendVector(documentAuthorStyleSheets());
     collectActiveCSSStyleSheetsFromSeamlessParents(activeCSSStyleSheets, m_document);
-    filterEnabledCSSStyleSheets(activeCSSStyleSheets, activeStyleSheets);
+    filterEnabledNonemptyCSSStyleSheets(activeCSSStyleSheets, activeStyleSheets);
 
     StyleResolverUpdateType styleResolverUpdateType;
     bool requiresFullStyleRecalc;
@@ -465,39 +483,37 @@ bool DocumentStyleSheetCollection::updateActiveStyleSheets(UpdateFlag updateFlag
     if (styleResolverUpdateType == Reconstruct)
         m_document->clearStyleResolver();
     else {
-        StyleResolver* styleResolver = m_document->styleResolver();
+        StyleResolver& styleResolver = m_document->ensureStyleResolver();
         if (styleResolverUpdateType == Reset) {
-            styleResolver->resetAuthorStyle();
-            styleResolver->appendAuthorStyleSheets(0, activeCSSStyleSheets);
+            styleResolver.ruleSets().resetAuthorStyle();
+            styleResolver.appendAuthorStyleSheets(0, activeCSSStyleSheets);
         } else {
             ASSERT(styleResolverUpdateType == Additive);
-            styleResolver->appendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), activeCSSStyleSheets);
+            styleResolver.appendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), activeCSSStyleSheets);
         }
         resetCSSFeatureFlags();
     }
+
+    m_weakCopyOfActiveStyleSheetListForFastLookup.clear();
     m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
     m_styleSheetsForStyleSheetList.swap(activeStyleSheets);
 
     m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
-    m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
+    m_pendingUpdateType = NoUpdate;
 
     m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
 
     return requiresFullStyleRecalc;
 }
 
-void DocumentStyleSheetCollection::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+bool DocumentStyleSheetCollection::activeStyleSheetsContains(const CSSStyleSheet* sheet) const
 {
-    MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
-    info.addMember(m_pageUserSheet);
-    info.addMember(m_injectedUserStyleSheets);
-    info.addMember(m_injectedAuthorStyleSheets);
-    info.addMember(m_userStyleSheets);
-    info.addMember(m_activeAuthorStyleSheets);
-    info.addMember(m_styleSheetsForStyleSheetList);
-    info.addMember(m_styleSheetCandidateNodes);
-    info.addMember(m_preferredStylesheetSetName);
-    info.addMember(m_selectedStylesheetSetName);
+    if (!m_weakCopyOfActiveStyleSheetListForFastLookup) {
+        m_weakCopyOfActiveStyleSheetListForFastLookup = adoptPtr(new HashSet<const CSSStyleSheet*>);
+        for (unsigned i = 0; i < m_activeAuthorStyleSheets.size(); ++i)
+            m_weakCopyOfActiveStyleSheetListForFastLookup->add(m_activeAuthorStyleSheets[i].get());
+    }
+    return m_weakCopyOfActiveStyleSheetListForFastLookup->contains(sheet);
 }
 
 }