diff options
Diffstat (limited to 'Source/WebCore/dom/DocumentStyleSheetCollection.cpp')
-rw-r--r-- | Source/WebCore/dom/DocumentStyleSheetCollection.cpp | 90 |
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); |