예제 #1
0
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);
}
예제 #2
0
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);
    }
}
예제 #3
0
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();
}
예제 #4
0
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);
}