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 StyleInvalidationAnalysis::invalidateStyle(Document* document) { ASSERT(!m_dirtiesAllStyle); if (m_idScopes.isEmpty() && m_classScopes.isEmpty()) return; Node* node = document->firstChild(); while (node) { if (!node->isStyledElement()) { node = NodeTraversal::next(node); continue; } StyledElement* element = static_cast<StyledElement*>(node); if (elementMatchesSelectorScopes(element, m_idScopes, m_classScopes)) { element->setNeedsStyleRecalc(); // The whole subtree is now invalidated, we can skip to the next sibling. node = NodeTraversal::nextSkippingChildren(node); continue; } node = NodeTraversal::next(node); } }