void resolveTree(Document& document, Change change) { bool resolveRootStyle = change == Force || (document.shouldDisplaySeamlesslyWithParent() && change >= Inherit); if (resolveRootStyle) { RefPtr<RenderStyle> documentStyle = resolveForDocument(document); #if PLATFORM(IOS) // Inserting the pictograph font at the end of the font fallback list is done by the // font selector, so set a font selector if needed. if (Settings* settings = document.settings()) { StyleResolver* styleResolver = document.styleResolverIfExists(); if (settings->fontFallbackPrefersPictographs() && styleResolver) documentStyle->font().update(styleResolver->fontSelector()); } #endif Style::Change documentChange = determineChange(documentStyle.get(), document.renderer()->style(), document.settings()); if (documentChange != NoChange) document.renderer()->setStyle(documentStyle.release()); } Element* documentElement = document.documentElement(); if (!documentElement) return; if (change < Inherit && !documentElement->childNeedsStyleRecalc() && !documentElement->needsStyleRecalc()) return; resolveTree(*documentElement, change); }
void resolveTree(Document* document, Change change) { bool resolveRootStyle = change == Force || (document->shouldDisplaySeamlesslyWithParent() && change >= Inherit); if (resolveRootStyle) { RefPtr<RenderStyle> documentStyle = resolveForDocument(document); Style::Change documentChange = determineChange(documentStyle.get(), document->renderer()->style(), document->settings()); if (documentChange != NoChange) document->renderer()->setStyle(documentStyle.release()); } for (Element* child = ElementTraversal::firstWithin(document); child; child = ElementTraversal::nextSibling(child)) { if (change < Inherit && !child->childNeedsStyleRecalc() && !child->needsStyleRecalc()) continue; resolveTree(child, change); } }
static void resolveShadowTree(ShadowRoot* shadowRoot, RenderStyle* parentElementStyle, Style::Change change) { if (!shadowRoot) return; StyleResolver& styleResolver = shadowRoot->document()->ensureStyleResolver(); styleResolver.pushParentShadowRoot(shadowRoot); for (Node* child = shadowRoot->firstChild(); child; child = child->nextSibling()) { if (child->isTextNode()) { // Current user agent ShadowRoots don't have immediate text children so this branch is never actually taken. updateTextStyle(toText(child), parentElementStyle, change); continue; } resolveTree(toElement(child), change); } styleResolver.popParentShadowRoot(shadowRoot); shadowRoot->clearNeedsStyleRecalc(); shadowRoot->clearChildNeedsStyleRecalc(); }
void resolveTree(Element* current, Change change) { ASSERT(change != Detach); if (current->hasCustomStyleResolveCallbacks()) { if (!current->willRecalcStyle(change)) return; } bool hasParentStyle = current->parentNodeForRenderingAndStyle() && current->parentNodeForRenderingAndStyle()->renderStyle(); bool hasDirectAdjacentRules = current->childrenAffectedByDirectAdjacentRules(); bool hasIndirectAdjacentRules = current->childrenAffectedByForwardPositionalRules(); if (change > NoChange || current->needsStyleRecalc()) current->resetComputedStyle(); if (hasParentStyle && (change >= Inherit || current->needsStyleRecalc())) change = resolveLocal(current, change); if (change != Detach) { StyleResolverParentPusher parentPusher(current); RenderStyle* currentStyle = current->renderStyle(); if (ShadowRoot* shadowRoot = current->shadowRoot()) { if (change >= Inherit || shadowRoot->childNeedsStyleRecalc() || shadowRoot->needsStyleRecalc()) { parentPusher.push(); resolveShadowTree(shadowRoot, currentStyle, change); } } current->updateBeforePseudoElement(change); // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar. // For now we will just worry about the common case, since it's a lot trickier to get the second case right // without doing way too much re-resolution. bool forceCheckOfNextElementSibling = false; bool forceCheckOfAnyElementSibling = false; for (Node* child = current->firstChild(); child; child = child->nextSibling()) { if (child->isTextNode()) { updateTextStyle(toText(child), currentStyle, change); continue; } if (!child->isElementNode()) continue; Element* childElement = toElement(child); bool childRulesChanged = childElement->needsStyleRecalc() && childElement->styleChangeType() == FullStyleChange; if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling)) childElement->setNeedsStyleRecalc(); if (change >= Inherit || childElement->childNeedsStyleRecalc() || childElement->needsStyleRecalc()) { parentPusher.push(); resolveTree(childElement, change); } forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules; forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules); } current->updateAfterPseudoElement(change); } current->clearNeedsStyleRecalc(); current->clearChildNeedsStyleRecalc(); if (current->hasCustomStyleResolveCallbacks()) current->didRecalcStyle(change); }