bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(Element& element, RecursionData& recursionData) { bool thisElementNeedsStyleRecalc = false; ASSERT(!recursionData.wholeSubtreeInvalid()); unsigned index = 0; while (index < m_invalidationEntries.size()) { if (m_elementIndex > m_invalidationEntries[index].m_invalidationLimit) { // m_invalidationEntries[index] only applies to earlier siblings. Remove it. m_invalidationEntries[index] = m_invalidationEntries.last(); m_invalidationEntries.removeLast(); continue; } const SiblingInvalidationSet& invalidationSet = *m_invalidationEntries[index].m_invalidationSet; ++index; if (!invalidationSet.invalidatesElement(element)) continue; if (invalidationSet.invalidatesSelf()) thisElementNeedsStyleRecalc = true; if (const DescendantInvalidationSet* descendants = invalidationSet.siblingDescendants()) { if (descendants->wholeSubtreeInvalid()) { element.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator)); return true; } if (!descendants->isEmpty()) recursionData.pushInvalidationSet(*descendants); } } return thisElementNeedsStyleRecalc; }
void StyleInvalidator::pushInvalidationSetsForElement(Element& element, RecursionData& recursionData, SiblingData& siblingData) { PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&element); ASSERT(pendingInvalidations); for (const auto& invalidationSet : pendingInvalidations->siblings()) siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet)); if (!pendingInvalidations->descendants().isEmpty()) { for (const auto& invalidationSet : pendingInvalidations->descendants()) recursionData.pushInvalidationSet(toDescendantInvalidationSet(*invalidationSet)); if (UNLIKELY(*s_tracingEnabled)) { TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), "StyleInvalidatorInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", InspectorStyleInvalidatorInvalidateEvent::invalidationList(element, pendingInvalidations->descendants())); } } }
bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(Element& element, RecursionData& recursionData) const { bool thisElementNeedsStyleRecalc = false; ASSERT(!recursionData.wholeSubtreeInvalid()); unsigned index = 0; while (index < m_invalidationEntries.size()) { if (m_elementIndex > m_invalidationEntries[index].m_invalidationLimit) { // m_invalidationEntries[index] only applies to earlier siblings. Remove it. m_invalidationEntries[index] = m_invalidationEntries.last(); m_invalidationEntries.removeLast(); continue; } const SiblingInvalidationSet& invalidationSet = *m_invalidationEntries[index].m_invalidationSet; if (invalidationSet.invalidatesElement(element)) { const DescendantInvalidationSet& descendants = invalidationSet.descendants(); if (descendants.wholeSubtreeInvalid()) { // Avoid directly setting SubtreeStyleChange on element, or ContainerNode::checkForChildrenAdjacentRuleChanges() // may propagate the SubtreeStyleChange to our own siblings' subtrees. for (Element* child = ElementTraversal::firstChild(element); child; child = ElementTraversal::nextSibling(*child)) { child->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::SiblingSelector)); } return true; } if (descendants.invalidatesSelf()) thisElementNeedsStyleRecalc = true; if (!descendants.isEmpty()) recursionData.pushInvalidationSet(descendants); } ++index; } return thisElementNeedsStyleRecalc; }
void StyleInvalidator::pushInvalidationSetsForContainerNode(ContainerNode& node, RecursionData& recursionData, SiblingData& siblingData) { PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&node); ASSERT(pendingInvalidations); for (const auto& invalidationSet : pendingInvalidations->siblings()) siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet)); if (node.getStyleChangeType() >= SubtreeStyleChange) return; if (!pendingInvalidations->descendants().isEmpty()) { for (const auto& invalidationSet : pendingInvalidations->descendants()) recursionData.pushInvalidationSet(*invalidationSet); if (UNLIKELY(*s_tracingEnabled)) { TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"), "StyleInvalidatorInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data", InspectorStyleInvalidatorInvalidateEvent::invalidationList(node, pendingInvalidations->descendants())); } } }