summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/DocumentStyleSheetCollection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/DocumentStyleSheetCollection.cpp')
-rw-r--r--Source/WebCore/dom/DocumentStyleSheetCollection.cpp90
1 files changed, 37 insertions, 53 deletions
diff --git a/Source/WebCore/dom/DocumentStyleSheetCollection.cpp b/Source/WebCore/dom/DocumentStyleSheetCollection.cpp
index 84cb8fce9..bfd1e5f0f 100644
--- a/Source/WebCore/dom/DocumentStyleSheetCollection.cpp
+++ b/Source/WebCore/dom/DocumentStyleSheetCollection.cpp
@@ -41,6 +41,7 @@
#include "SVGStyleElement.h"
#include "SelectorChecker.h"
#include "Settings.h"
+#include "StyleInvalidationAnalysis.h"
#include "StyleResolver.h"
#include "StyleSheetContents.h"
#include "StyleSheetList.h"
@@ -347,34 +348,7 @@ void DocumentStyleSheetCollection::collectActiveStyleSheets(Vector<RefPtr<StyleS
}
}
-bool DocumentStyleSheetCollection::testAddedStyleSheetRequiresStyleRecalc(StyleSheetContents* stylesheet)
-{
- // See if all rules on the sheet are scoped to some specific ids or classes.
- // Then test if we actually have any of those in the tree at the moment.
- HashSet<AtomicStringImpl*> idScopes;
- HashSet<AtomicStringImpl*> classScopes;
- if (!StyleResolver::determineStylesheetSelectorScopes(stylesheet, idScopes, classScopes))
- return true;
- // Invalidate the subtrees that match the scopes.
- Node* node = m_document->firstChild();
- while (node) {
- if (!node->isStyledElement()) {
- node = node->traverseNextNode();
- continue;
- }
- StyledElement* element = static_cast<StyledElement*>(node);
- if (SelectorChecker::elementMatchesSelectorScopes(element, idScopes, classScopes)) {
- element->setNeedsStyleRecalc();
- // The whole subtree is now invalidated, we can skip to the next sibling.
- node = node->traverseNextSibling();
- continue;
- }
- node = node->traverseNextNode();
- }
- return false;
-}
-
-void DocumentStyleSheetCollection::analyzeStyleSheetChange(UpdateFlag updateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, StyleResolverUpdateType& styleResolverUpdateType, bool& requiresFullStyleRecalc)
+void DocumentStyleSheetCollection::analyzeStyleSheetChange(UpdateFlag updateFlag, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, StyleResolverUpdateType& styleResolverUpdateType, bool& requiresFullStyleRecalc)
{
styleResolverUpdateType = Reconstruct;
requiresFullStyleRecalc = true;
@@ -398,16 +372,16 @@ void DocumentStyleSheetCollection::analyzeStyleSheetChange(UpdateFlag updateFlag
return;
// Find out which stylesheets are new.
- unsigned oldStylesheetCount = m_authorStyleSheets.size();
+ unsigned oldStylesheetCount = m_activeAuthorStyleSheets.size();
if (newStylesheetCount < oldStylesheetCount)
return;
- Vector<StyleSheet*> addedSheets;
+ Vector<StyleSheetContents*> addedSheets;
unsigned newIndex = 0;
for (unsigned oldIndex = 0; oldIndex < oldStylesheetCount; ++oldIndex) {
if (newIndex >= newStylesheetCount)
return;
- while (m_authorStyleSheets[oldIndex] != newStylesheets[newIndex]) {
- addedSheets.append(newStylesheets[newIndex].get());
+ while (m_activeAuthorStyleSheets[oldIndex] != newStylesheets[newIndex]) {
+ addedSheets.append(newStylesheets[newIndex]->contents());
++newIndex;
if (newIndex == newStylesheetCount)
return;
@@ -416,7 +390,7 @@ void DocumentStyleSheetCollection::analyzeStyleSheetChange(UpdateFlag updateFlag
}
bool hasInsertions = !addedSheets.isEmpty();
while (newIndex < newStylesheetCount) {
- addedSheets.append(newStylesheets[newIndex].get());
+ addedSheets.append(newStylesheets[newIndex]->contents());
++newIndex;
}
// If all new sheets were added at the end of the list we can just add them to existing StyleResolver.
@@ -426,28 +400,33 @@ void DocumentStyleSheetCollection::analyzeStyleSheetChange(UpdateFlag updateFlag
// If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
if (!m_document->body() || m_document->hasNodesWithPlaceholderStyle())
return;
- for (unsigned i = 0; i < addedSheets.size(); ++i) {
- if (!addedSheets[i]->isCSSStyleSheet())
- return;
- if (addedSheets[i]->disabled())
- continue;
- if (testAddedStyleSheetRequiresStyleRecalc(static_cast<CSSStyleSheet*>(addedSheets[i])->contents()))
- return;
- }
+ StyleInvalidationAnalysis invalidationAnalysis(addedSheets);
+ if (invalidationAnalysis.dirtiesAllStyle())
+ return;
+ invalidationAnalysis.invalidateStyle(m_document);
requiresFullStyleRecalc = false;
}
-static bool styleSheetsUseRemUnits(const Vector<RefPtr<StyleSheet> >& sheets)
+static bool styleSheetsUseRemUnits(const Vector<RefPtr<CSSStyleSheet> >& sheets)
{
for (unsigned i = 0; i < sheets.size(); ++i) {
- if (!sheets[i]->isCSSStyleSheet())
- continue;
- if (static_cast<CSSStyleSheet*>(sheets[i].get())->contents()->usesRemUnits())
+ if (sheets[i]->contents()->usesRemUnits())
return true;
}
return false;
}
+static void filterEnabledCSSStyleSheets(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()));
+ }
+}
+
bool DocumentStyleSheetCollection::updateActiveStyleSheets(UpdateFlag updateFlag)
{
if (m_document->inStyleRecalc()) {
@@ -462,12 +441,15 @@ bool DocumentStyleSheetCollection::updateActiveStyleSheets(UpdateFlag updateFlag
if (!m_document->renderer() || !m_document->attached())
return false;
- Vector<RefPtr<StyleSheet> > newStylesheets;
- collectActiveStyleSheets(newStylesheets);
+ Vector<RefPtr<StyleSheet> > activeStyleSheets;
+ collectActiveStyleSheets(activeStyleSheets);
+
+ Vector<RefPtr<CSSStyleSheet> > activeCSSStyleSheets;
+ filterEnabledCSSStyleSheets(activeCSSStyleSheets, activeStyleSheets);
StyleResolverUpdateType styleResolverUpdateType;
bool requiresFullStyleRecalc;
- analyzeStyleSheetChange(updateFlag, newStylesheets, styleResolverUpdateType, requiresFullStyleRecalc);
+ analyzeStyleSheetChange(updateFlag, activeCSSStyleSheets, styleResolverUpdateType, requiresFullStyleRecalc);
if (styleResolverUpdateType == Reconstruct)
m_document->clearStyleResolver();
@@ -475,16 +457,17 @@ bool DocumentStyleSheetCollection::updateActiveStyleSheets(UpdateFlag updateFlag
StyleResolver* styleResolver = m_document->styleResolver();
if (styleResolverUpdateType == Reset) {
styleResolver->resetAuthorStyle();
- styleResolver->appendAuthorStylesheets(0, newStylesheets);
+ styleResolver->appendAuthorStyleSheets(0, activeCSSStyleSheets);
} else {
ASSERT(styleResolverUpdateType == Additive);
- styleResolver->appendAuthorStylesheets(m_authorStyleSheets.size(), newStylesheets);
+ styleResolver->appendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), activeCSSStyleSheets);
}
resetCSSFeatureFlags();
}
- m_authorStyleSheets.swap(newStylesheets);
+ m_activeAuthorStyleSheets.swap(activeCSSStyleSheets);
+ m_styleSheetsForStyleSheetList.swap(activeStyleSheets);
- m_usesRemUnits = styleSheetsUseRemUnits(m_authorStyleSheets);
+ m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
@@ -498,7 +481,8 @@ void DocumentStyleSheetCollection::reportMemoryUsage(MemoryObjectInfo* memoryObj
info.addMember(m_pageUserSheet);
info.addMember(m_pageGroupUserSheets);
info.addMember(m_userSheets);
- info.addMember(m_authorStyleSheets);
+ info.addMember(m_activeAuthorStyleSheets);
+ info.addMember(m_styleSheetsForStyleSheetList);
info.addListHashSet(m_styleSheetCandidateNodes);
info.addMember(m_preferredStylesheetSetName);
info.addMember(m_selectedStylesheetSetName);