void ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
{
    StyleSheetCollection collection;
    collectStyleSheets(engine, collection);

    StyleSheetChange change;
    analyzeStyleSheetChange(updateMode, collection, change);

    if (StyleResolver* styleResolver = engine->resolver()) {
        if (change.styleResolverUpdateType != Additive) {
            // We should not destroy StyleResolver when we find any stylesheet update in a shadow tree.
            // In this case, we will reset rulesets created from style elements in the shadow tree.
            styleResolver->resetAuthorStyle(treeScope());
            styleResolver->removePendingAuthorStyleSheets(m_activeAuthorStyleSheets);
            styleResolver->lazyAppendAuthorStyleSheets(0, collection.activeAuthorStyleSheets());
        } else {
            styleResolver->lazyAppendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), collection.activeAuthorStyleSheets());
        }
    }
    if (change.requiresFullStyleRecalc)
        toShadowRoot(treeScope().rootNode()).host()->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::ActiveStylesheetsUpdate));

    collection.swap(*this);
    updateUsesRemUnits();
}
void DocumentStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
{
    StyleSheetCollection collection;
    ActiveDocumentStyleSheetCollector collector(collection);
    collectStyleSheets(engine, collector);

    StyleSheetChange change;
    analyzeStyleSheetChange(updateMode, collection, change);

    if (change.styleResolverUpdateType == Reconstruct) {
        engine->clearMasterResolver();
        // FIMXE: The following depends on whether StyleRuleFontFace was modified or not.
        // No need to always-clear font cache.
        engine->clearFontCache();
    } else if (StyleResolver* styleResolver = engine->resolver()) {
        if (change.styleResolverUpdateType != Additive) {
            ASSERT(change.styleResolverUpdateType == Reset);
            styleResolver->resetAuthorStyle(treeScope());
            engine->removeFontFaceRules(change.fontFaceRulesToRemove);
            styleResolver->removePendingAuthorStyleSheets(m_activeAuthorStyleSheets);
            styleResolver->lazyAppendAuthorStyleSheets(0, collection.activeAuthorStyleSheets());
        } else {
            styleResolver->lazyAppendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), collection.activeAuthorStyleSheets());
        }
    }
    if (change.requiresFullStyleRecalc)
        document().setNeedsStyleRecalc(SubtreeStyleChange);

    collection.swap(*this);

    updateUsesRemUnits();
}
void TreeScopeStyleSheetCollection::analyzeStyleSheetChange(StyleResolverUpdateMode updateMode, const StyleSheetCollection& newCollection, StyleSheetChange& change)
{
    if (activeLoadingStyleSheetLoaded(newCollection.activeAuthorStyleSheets()))
        return;

    if (updateMode != AnalyzedStyleUpdate)
        return;

    // Find out which stylesheets are new.
    WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents>> addedSheets;
    if (m_activeAuthorStyleSheets.size() <= newCollection.activeAuthorStyleSheets().size()) {
        change.styleResolverUpdateType = compareStyleSheets(m_activeAuthorStyleSheets, newCollection.activeAuthorStyleSheets(), addedSheets);
    } else {
        StyleResolverUpdateType updateType = compareStyleSheets(newCollection.activeAuthorStyleSheets(), m_activeAuthorStyleSheets, addedSheets);
        if (updateType != Additive) {
            change.styleResolverUpdateType = updateType;
        } else {
            change.styleResolverUpdateType = Reset;
            // If @font-face is removed, needs full style recalc.
            if (findFontFaceRulesFromStyleSheetContents(addedSheets, change.fontFaceRulesToRemove))
                return;
        }
    }

    // FIXME: If styleResolverUpdateType is Reconstruct, we should return early here since
    // we need to recalc the whole document. It's wrong to use StyleSheetInvalidationAnalysis since
    // it only looks at the addedSheets.

    // No point in doing the analysis work if we're just going to recalc the whole document anyways.
    // This needs to be done after the compareStyleSheets calls above to ensure we don't throw away
    // the StyleResolver if we don't need to.
    if (document().hasPendingForcedStyleRecalc())
        return;

    // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
    if (!document().body() || document().hasNodesWithPlaceholderStyle())
        return;
    StyleSheetInvalidationAnalysis invalidationAnalysis(addedSheets);
    if (invalidationAnalysis.dirtiesAllStyle())
        return;
    invalidationAnalysis.invalidateStyle(document());
    change.requiresFullStyleRecalc = false;
    return;
}
void DocumentStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
{
    StyleSheetCollection collection;
    ActiveDocumentStyleSheetCollector collector(collection);
    collectStyleSheets(engine, collector);

    StyleSheetChange change;
    analyzeStyleSheetChange(updateMode, collection, change);

    if (change.styleResolverUpdateType == Reconstruct) {
        engine->clearMasterResolver();
        // FIMXE: The following depends on whether StyleRuleFontFace was modified or not.
        // No need to always-clear font cache.
        engine->clearFontCache();
    } else if (StyleResolver* styleResolver = engine->resolver()) {
        // FIXME: We might have already had styles in child treescope. In this case, we cannot use buildScopedStyleTreeInDocumentOrder.
        // Need to change "false" to some valid condition.
        styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
        if (change.styleResolverUpdateType != Additive) {
            ASSERT(change.styleResolverUpdateType == Reset);
            resetAllRuleSetsInTreeScope(styleResolver);
            engine->removeFontFaceRules(change.fontFaceRulesToRemove);
            styleResolver->removePendingAuthorStyleSheets(m_activeAuthorStyleSheets);
            styleResolver->lazyAppendAuthorStyleSheets(0, collection.activeAuthorStyleSheets());
        } else {
            styleResolver->lazyAppendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), collection.activeAuthorStyleSheets());
        }
    }
    if (change.requiresFullStyleRecalc)
        document().setNeedsStyleRecalc(SubtreeStyleChange);

    m_scopingNodesForStyleScoped.didRemoveScopingNodes();

    collection.swap(*this);

    updateUsesRemUnits();
}