recalculateStyle method
void
recalculateStyle(
{ - bool rebuildNested = false,
- bool forceRecalculate = false,
})
Implementation
void recalculateStyle(
{bool rebuildNested = false, bool forceRecalculate = false}) {
// Pseudo elements (::before/::after) are styled via their parent's
// matched pseudo rules. A full recalc using the standard element
// pipeline would discard those properties (only defaults/inline apply).
// Skip full recalc here to preserve pseudo-specific styles, which are
// refreshed via markBefore/AfterPseudoElementNeedsUpdate on the parent.
if (this is PseudoElement) {
// Still flush any pending inline or merged properties if present.
style.flushPendingProperties();
return;
}
// Always update CSS variables even for display:none elements when rebuilding nested
bool shouldUpdateCSSVariables =
rebuildNested && renderStyle.display == CSSDisplay.none;
if (forceRecalculate ||
renderStyle.display != CSSDisplay.none ||
shouldUpdateCSSVariables) {
// Structural mutations (childList changes) can change selector matching
// results even when this element's own tag/id/class/attrs stay the same.
// The per-element matched-rules memoization fingerprint does not include
// sibling/ancestor topology, so ensure we don't reuse a stale entry when
// callers request a nested rebuild.
if (rebuildNested) {
_matchedRulesLRU = null;
}
// Diff style.
CSSStyleDeclaration newStyle = CSSStyleDeclaration();
applyStyle(newStyle);
bool hasInheritedPendingProperty = false;
final bool merged = style.merge(newStyle);
if (merged) {
hasInheritedPendingProperty = style.hasInheritedPendingProperty;
style.flushPendingProperties();
}
// If callers requested a nested rebuild (e.g. DOM childList mutation),
// always recurse into children even when this element's own style is a no-op.
if (rebuildNested || hasInheritedPendingProperty) {
for (final Element child in children) {
child.recalculateStyle(rebuildNested: rebuildNested, forceRecalculate: forceRecalculate);
}
}
}
}