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;
}
TEST_F(TreeScopeStyleSheetCollectionTest, CompareStyleSheetsPrepend)
{
    CSSStyleSheet* sheet1 = createSheet();
    CSSStyleSheet* sheet2 = createSheet();

    ContentsVector added;
    SheetVector previous;
    SheetVector current;

    previous.append(sheet2);

    current.append(sheet1);
    current.append(sheet2);

    added.append(sheet1->contents());

    compareStyleSheets(previous, current, added, Reconstruct);
}
TEST_F(TreeScopeStyleSheetCollectionTest, CompareStyleSheetsAppend)
{
    RawPtr<CSSStyleSheet> sheet1 = createSheet();
    RawPtr<CSSStyleSheet> sheet2 = createSheet();

    ContentsVector added;
    SheetVector previous;
    SheetVector current;

    previous.append(sheet1);

    current.append(sheet1);
    current.append(sheet2);

    added.append(sheet2->contents());

    compareStyleSheets(previous, current, added, Additive);
}
TEST_F(TreeScopeStyleSheetCollectionTest, CompareStyleSheetsInsertRemove)
{
    CSSStyleSheet* sheet1 = createSheet();
    CSSStyleSheet* sheet2 = createSheet();
    CSSStyleSheet* sheet3 = createSheet();

    ContentsVector added;
    SheetVector previous;
    SheetVector current;

    previous.append(sheet1);
    previous.append(sheet2);

    current.append(sheet2);
    current.append(sheet3);

    // TODO([email protected]): This is clearly wrong. We add sheet3 and remove sheet1 and
    // compareStyleSheets returns sheet2 and sheet3 as added (crbug/475858).
    added.append(sheet2->contents());
    added.append(sheet3->contents());

    compareStyleSheets(previous, current, added, Reconstruct);
}
TEST_F(TreeScopeStyleSheetCollectionTest, CompareStyleSheetsRemove)
{
    CSSStyleSheet* sheet1 = createSheet();
    CSSStyleSheet* sheet2 = createSheet();
    CSSStyleSheet* sheet3 = createSheet();

    ContentsVector added;
    SheetVector previous;
    SheetVector current;

    previous.append(sheet1);
    previous.append(sheet2);
    previous.append(sheet3);

    current.append(sheet1);
    current.append(sheet3);

    added.append(sheet2->contents());

    // This is really the same as Insert. TreeScopeStyleSheetCollection::compareStyleSheets
    // will assert if you pass an array that is longer as the first parameter.
    compareStyleSheets(current, previous, added, Reconstruct);
}