void Element::recalcChildStyle(StyleRecalcChange change) { ASSERT(document().inStyleRecalc()); ASSERT(change >= Inherit || childNeedsStyleRecalc()); ASSERT(!needsStyleRecalc()); if (change > Inherit || childNeedsStyleRecalc()) { // This loop is deliberately backwards because we use insertBefore in the rendering tree, and want to avoid // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last // child and work our way back means in the common case, we'll find the insertion point in O(1) time. // See crbug.com/288225 StyleResolver& styleResolver = document().styleResolver(); for (Node* child = lastChild(); child; child = child->previousSibling()) { if (child->isTextNode()) { toText(child)->recalcTextStyle(change); } else if (child->isElementNode()) { Element* element = toElement(child); if (element->shouldCallRecalcStyle(change)) element->recalcStyle(change); else if (element->supportsStyleSharing()) styleResolver.addToStyleSharingList(*element); } } } }
void ShadowRoot::recalcStyle(StyleRecalcChange change) { // ShadowRoot doesn't support custom callbacks. ASSERT(!hasCustomStyleCallbacks()); StyleResolverParentScope parentScope(*this); if (styleChangeType() >= SubtreeStyleChange) change = Force; if (change < Force && hasRareData() && childNeedsStyleRecalc()) checkForChildrenAdjacentRuleChanges(); // There's no style to update so just calling recalcStyle means we're updated. clearNeedsStyleRecalc(); // FIXME: This doesn't handle :hover + div properly like Element::recalcStyle does. Text* lastTextNode = 0; for (Node* child = lastChild(); child; child = child->previousSibling()) { if (child->isTextNode()) { toText(child)->recalcTextStyle(change, lastTextNode); lastTextNode = toText(child); } else if (child->isElementNode()) { if (child->shouldCallRecalcStyle(change)) toElement(child)->recalcStyle(change, lastTextNode); if (child->renderer()) lastTextNode = 0; } } clearChildNeedsStyleRecalc(); }
void SVGUseElement::recalcStyle(StyleChange change) { // Eventually mark shadow root element needing style recalc if ((change >= Inherit || needsStyleRecalc() || childNeedsStyleRecalc()) && m_targetElementInstance && !m_updatesBlocked) { if (SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement()) shadowRoot->setNeedsStyleRecalc(); } SVGStyledTransformableElement::recalcStyle(change); // Assure that the shadow tree has not been marked for recreation, while we're building it. if (m_updatesBlocked) ASSERT(!m_needsShadowTreeRecreation); RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer()); if (!shadowRoot) return; bool needsStyleUpdate = !m_needsShadowTreeRecreation; if (m_needsShadowTreeRecreation) { shadowRoot->markShadowTreeForRecreation(); m_needsShadowTreeRecreation = false; } shadowRoot->updateFromElement(); if (!needsStyleUpdate) return; shadowRoot->updateStyle(change); }
void Element::recalcStyle(StyleRecalcChange change) { ASSERT(document().inStyleRecalc()); ASSERT(!parentNode()->needsStyleRecalc()); if (change >= Inherit || needsStyleRecalc()) { if (hasRareData()) { ElementRareData* data = elementRareData(); data->clearComputedStyle(); } if (parentRenderStyle()) change = recalcOwnStyle(change); clearNeedsStyleRecalc(); } // If we reattached we don't need to recalc the style of our descendants anymore. if ((change >= Inherit && change < Reattach) || childNeedsStyleRecalc()) { recalcChildStyle(change); clearChildNeedsStyleRecalc(); } }