Rename AuthorStyleSheets to Style::Scope
https://bugs.webkit.org/show_bug.cgi?id=163108

Reviewed by Andreas Kling.

It represents the style scope in DOM.
Also move the file under style/.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSStyleSheet.cpp:
(WebCore::CSSStyleSheet::styleSheetScope):
* css/CSSStyleSheet.h:
* css/InspectorCSSOMWrappers.cpp:
(WebCore::InspectorCSSOMWrappers::getWrapperForRuleInSheets):
* css/InspectorCSSOMWrappers.h:
* css/StyleSheetList.cpp:
(WebCore::StyleSheetList::styleSheets):
(WebCore::StyleSheetList::detachFromDocument):
* dom/AuthorStyleSheets.cpp: Removed.
* dom/AuthorStyleSheets.h: Removed.
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::setContentLanguage):
(WebCore::Document::recalcStyle):
(WebCore::Document::needsStyleRecalc):
(WebCore::Document::updateStyleIfNeeded):
(WebCore::Document::updateLayoutIgnorePendingStylesheets):
(WebCore::Document::createStyleResolver):
(WebCore::Document::didRemoveAllPendingStylesheet):
(WebCore::Document::usesStyleBasedEditability):
(WebCore::Document::processHttpEquiv):
(WebCore::Document::preferredStylesheetSet):
(WebCore::Document::selectedStylesheetSet):
(WebCore::Document::setSelectedStylesheetSet):
(WebCore::Document::haveStylesheetsLoaded):
* dom/Document.h:
(WebCore::Document::styleScope):
(WebCore::Document::authorStyleSheets): Deleted.
* dom/ExtensionStyleSheets.cpp:
(WebCore::ExtensionStyleSheets::clearPageUserSheet):
(WebCore::ExtensionStyleSheets::updatePageUserSheet):
(WebCore::ExtensionStyleSheets::invalidateInjectedStyleSheetCache):
(WebCore::ExtensionStyleSheets::addUserStyleSheet):
(WebCore::ExtensionStyleSheets::addAuthorStyleSheetForTesting):
(WebCore::ExtensionStyleSheets::styleResolverChangedTimerFired):
* dom/InlineStyleSheetOwner.cpp:
(WebCore::InlineStyleSheetOwner::insertedIntoDocument):
(WebCore::InlineStyleSheetOwner::removedFromDocument):
(WebCore::InlineStyleSheetOwner::clearDocumentData):
(WebCore::InlineStyleSheetOwner::createSheet):
(WebCore::InlineStyleSheetOwner::sheetLoaded):
(WebCore::InlineStyleSheetOwner::startLoadingDynamicSheet):
* dom/InlineStyleSheetOwner.h:
(WebCore::InlineStyleSheetOwner::styleScope):
(WebCore::InlineStyleSheetOwner::styleSheetScope): Deleted.
* dom/ProcessingInstruction.cpp:
(WebCore::ProcessingInstruction::~ProcessingInstruction):
(WebCore::ProcessingInstruction::checkStyleSheet):
(WebCore::ProcessingInstruction::sheetLoaded):
(WebCore::ProcessingInstruction::insertedInto):
(WebCore::ProcessingInstruction::removedFrom):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::styleResolver):
(WebCore::ShadowRoot::styleScope):
(WebCore::ShadowRoot::updateStyle):
(WebCore::ShadowRoot::authorStyleSheets): Deleted.
* dom/ShadowRoot.h:
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::~HTMLLinkElement):
(WebCore::HTMLLinkElement::setDisabledState):
(WebCore::HTMLLinkElement::parseAttribute):
(WebCore::HTMLLinkElement::process):
(WebCore::HTMLLinkElement::insertedInto):
(WebCore::HTMLLinkElement::removedFrom):
(WebCore::HTMLLinkElement::addPendingSheet):
(WebCore::HTMLLinkElement::removePendingSheet):
* html/HTMLStyleElement.cpp:
* inspector/InspectorCSSAgent.cpp:
(WebCore::InspectorCSSAgent::collectAllDocumentStyleSheets):
(WebCore::InspectorCSSAgent::forcePseudoState):
(WebCore::InspectorCSSAgent::buildObjectForRule):
(WebCore::InspectorCSSAgent::resetPseudoStates):
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::setEmulatedMedia):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::getMatchedCSSRules):
* page/Frame.cpp:
(WebCore::Frame::setPrinting):
* page/FrameView.cpp:
(WebCore::FrameView::layout):
(WebCore::FrameView::setPagination):
(WebCore::FrameView::setViewportSizeForCSSViewportUnits):
* page/Page.cpp:
(WebCore::Page::setViewMode):
(WebCore::Page::setNeedsRecalcStyleInAllFrames):
(WebCore::Page::invalidateInjectedStyleSheetCacheInAllFrames):
* style/StyleScope.cpp: Copied from dom/AuthorStyleSheets.cpp.
(WebCore::Style::Scope::Scope):
(WebCore::Style::Scope::styleResolver):
(WebCore::Style::Scope::styleResolverIfExists):
(WebCore::Style::Scope::forNode):
(WebCore::Style::Scope::removePendingSheet):
(WebCore::Style::Scope::addStyleSheetCandidateNode):
(WebCore::Style::Scope::removeStyleSheetCandidateNode):
(WebCore::Style::Scope::collectActiveStyleSheets):
(WebCore::Style::Scope::analyzeStyleSheetChange):
(WebCore::Style::Scope::updateActiveStyleSheets):
(WebCore::Style::Scope::updateStyleResolver):
(WebCore::Style::Scope::activeStyleSheetsForInspector):
(WebCore::Style::Scope::activeStyleSheetsContains):
(WebCore::Style::Scope::flushPendingUpdate):
(WebCore::Style::Scope::clearPendingUpdate):
(WebCore::Style::Scope::scheduleActiveSetUpdate):
(WebCore::Style::Scope::didChangeCandidatesForActiveSet):
(WebCore::Style::Scope::didChangeContentsOrInterpretation):
(WebCore::Style::Scope::pendingUpdateTimerFired):
(WebCore::AuthorStyleSheets::AuthorStyleSheets): Deleted.
(WebCore::AuthorStyleSheets::styleResolver): Deleted.
(WebCore::AuthorStyleSheets::styleResolverIfExists): Deleted.
(WebCore::AuthorStyleSheets::forNode): Deleted.
(WebCore::AuthorStyleSheets::removePendingSheet): Deleted.
(WebCore::AuthorStyleSheets::addStyleSheetCandidateNode): Deleted.
(WebCore::AuthorStyleSheets::removeStyleSheetCandidateNode): Deleted.
(WebCore::AuthorStyleSheets::collectActiveStyleSheets): Deleted.
(WebCore::AuthorStyleSheets::analyzeStyleSheetChange): Deleted.
(WebCore::AuthorStyleSheets::updateActiveStyleSheets): Deleted.
(WebCore::AuthorStyleSheets::updateStyleResolver): Deleted.
(WebCore::AuthorStyleSheets::activeStyleSheetsForInspector): Deleted.
(WebCore::AuthorStyleSheets::activeStyleSheetsContains): Deleted.
(WebCore::AuthorStyleSheets::flushPendingUpdate): Deleted.
(WebCore::AuthorStyleSheets::clearPendingUpdate): Deleted.
(WebCore::AuthorStyleSheets::scheduleActiveSetUpdate): Deleted.
(WebCore::AuthorStyleSheets::didChangeCandidatesForActiveSet): Deleted.
(WebCore::AuthorStyleSheets::didChangeContentsOrInterpretation): Deleted.
(WebCore::AuthorStyleSheets::pendingUpdateTimerFired): Deleted.
* style/StyleScope.h: Copied from dom/AuthorStyleSheets.h.
* style/StyleTreeResolver.cpp:
* svg/SVGFontFaceElement.cpp:
(WebCore::SVGFontFaceElement::rebuildFontFace):
(WebCore::SVGFontFaceElement::removedFrom):
* xml/XMLTreeViewer.cpp:
(WebCore::XMLTreeViewer::transformDocumentToTreeView):
* xml/parser/XMLDocumentParser.cpp:
(WebCore::XMLDocumentParser::end):
* xml/parser/XMLDocumentParserLibxml2.cpp:
(WebCore::XMLDocumentParser::doEnd):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@206917 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/style/StyleScope.cpp b/Source/WebCore/style/StyleScope.cpp
new file mode 100644
index 0000000..d1ed51c
--- /dev/null
+++ b/Source/WebCore/style/StyleScope.cpp
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004-2009, 2011-2012, 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "StyleScope.h"
+
+#include "CSSStyleSheet.h"
+#include "Element.h"
+#include "ElementChildIterator.h"
+#include "ExtensionStyleSheets.h"
+#include "HTMLIFrameElement.h"
+#include "HTMLLinkElement.h"
+#include "HTMLStyleElement.h"
+#include "InspectorInstrumentation.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "ProcessingInstruction.h"
+#include "SVGNames.h"
+#include "SVGStyleElement.h"
+#include "Settings.h"
+#include "ShadowRoot.h"
+#include "StyleInvalidationAnalysis.h"
+#include "StyleResolver.h"
+#include "StyleSheetContents.h"
+#include "StyleSheetList.h"
+#include "UserContentController.h"
+#include "UserContentURLPattern.h"
+#include "UserStyleSheet.h"
+
+namespace WebCore {
+
+using namespace ContentExtensions;
+using namespace HTMLNames;
+
+namespace Style {
+
+Scope::Scope(Document& document)
+    : m_document(document)
+    , m_pendingUpdateTimer(*this, &Scope::pendingUpdateTimerFired)
+{
+}
+
+Scope::Scope(ShadowRoot& shadowRoot)
+    : m_document(shadowRoot.documentScope())
+    , m_shadowRoot(&shadowRoot)
+    , m_pendingUpdateTimer(*this, &Scope::pendingUpdateTimerFired)
+{
+}
+
+StyleResolver& Scope::styleResolver()
+{
+    if (m_shadowRoot)
+        return m_shadowRoot->styleResolver();
+
+    return m_document.ensureStyleResolver();
+}
+
+StyleResolver* Scope::styleResolverIfExists()
+{
+    if (m_shadowRoot)
+        return m_shadowRoot->styleResolverIfExists();
+
+    return m_document.styleResolverIfExists();
+}
+
+Scope& Scope::forNode(Node& node)
+{
+    ASSERT(node.inDocument());
+    auto* shadowRoot = node.containingShadowRoot();
+    if (shadowRoot)
+        return shadowRoot->styleScope();
+    return node.document().styleScope();
+}
+
+// This method is called whenever a top-level stylesheet has finished loading.
+void Scope::removePendingSheet(RemovePendingSheetNotificationType notification)
+{
+    // Make sure we knew this sheet was pending, and that our count isn't out of sync.
+    ASSERT(m_pendingStyleSheetCount > 0);
+
+    m_pendingStyleSheetCount--;
+    
+#ifdef INSTRUMENT_LAYOUT_SCHEDULING
+    if (!ownerElement())
+        printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
+#endif
+
+    if (m_pendingStyleSheetCount)
+        return;
+
+    if (notification == RemovePendingSheetNotifyLater) {
+        m_document.setNeedsNotifyRemoveAllPendingStylesheet();
+        return;
+    }
+
+    if (m_shadowRoot) {
+        m_shadowRoot->updateStyle();
+        return;
+    }
+
+    m_document.didRemoveAllPendingStylesheet();
+}
+
+void Scope::addStyleSheetCandidateNode(Node& node, bool createdByParser)
+{
+    if (!node.inDocument())
+        return;
+    
+    // Until the <body> exists, we have no choice but to compare document positions,
+    // since styles outside of the body and head continue to be shunted into the head
+    // (and thus can shift to end up before dynamically added DOM content that is also
+    // outside the body).
+    if ((createdByParser && m_document.bodyOrFrameset()) || m_styleSheetCandidateNodes.isEmpty()) {
+        m_styleSheetCandidateNodes.add(&node);
+        return;
+    }
+
+    // Determine an appropriate insertion point.
+    auto begin = m_styleSheetCandidateNodes.begin();
+    auto end = m_styleSheetCandidateNodes.end();
+    auto it = end;
+    Node* followingNode = nullptr;
+    do {
+        --it;
+        Node* n = *it;
+        unsigned short position = n->compareDocumentPosition(node);
+        if (position == Node::DOCUMENT_POSITION_FOLLOWING) {
+            m_styleSheetCandidateNodes.insertBefore(followingNode, &node);
+            return;
+        }
+        followingNode = n;
+    } while (it != begin);
+    
+    m_styleSheetCandidateNodes.insertBefore(followingNode, &node);
+}
+
+void Scope::removeStyleSheetCandidateNode(Node& node)
+{
+    if (m_styleSheetCandidateNodes.remove(&node))
+        scheduleActiveSetUpdate();
+}
+
+void Scope::collectActiveStyleSheets(Vector<RefPtr<StyleSheet>>& sheets)
+{
+    if (m_document.settings() && !m_document.settings()->authorAndUserStylesEnabled())
+        return;
+
+    for (auto& node : m_styleSheetCandidateNodes) {
+        StyleSheet* sheet = nullptr;
+        if (is<ProcessingInstruction>(*node)) {
+            // Processing instruction (XML documents only).
+            // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
+            ProcessingInstruction& pi = downcast<ProcessingInstruction>(*node);
+            sheet = pi.sheet();
+#if ENABLE(XSLT)
+            // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
+            if (pi.isXSL() && !m_document.transformSourceDocument()) {
+                // Don't apply XSL transforms until loading is finished.
+                if (!m_document.parsing())
+                    m_document.applyXSLTransform(&pi);
+                return;
+            }
+#endif
+        } else if (is<HTMLLinkElement>(*node) || is<HTMLStyleElement>(*node) || is<SVGStyleElement>(*node)) {
+            Element& element = downcast<Element>(*node);
+            AtomicString title = element.attributeWithoutSynchronization(titleAttr);
+            bool enabledViaScript = false;
+            if (is<HTMLLinkElement>(element)) {
+                // <LINK> element
+                HTMLLinkElement& linkElement = downcast<HTMLLinkElement>(element);
+                if (linkElement.isDisabled())
+                    continue;
+                enabledViaScript = linkElement.isEnabledViaScript();
+                if (linkElement.styleSheetIsLoading()) {
+                    // it is loading but we should still decide which style sheet set to use
+                    if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSetName.isEmpty()) {
+                        if (!linkElement.attributeWithoutSynchronization(relAttr).contains("alternate")) {
+                            m_preferredStylesheetSetName = title;
+                            m_selectedStylesheetSetName = title;
+                        }
+                    }
+                    continue;
+                }
+                if (!linkElement.sheet())
+                    title = nullAtom;
+            }
+            // Get the current preferred styleset. This is the
+            // set of sheets that will be enabled.
+            if (is<SVGStyleElement>(element))
+                sheet = downcast<SVGStyleElement>(element).sheet();
+            else if (is<HTMLLinkElement>(element))
+                sheet = downcast<HTMLLinkElement>(element).sheet();
+            else
+                sheet = downcast<HTMLStyleElement>(element).sheet();
+            // Check to see if this sheet belongs to a styleset
+            // (thus making it PREFERRED or ALTERNATE rather than
+            // PERSISTENT).
+            auto& rel = element.attributeWithoutSynchronization(relAttr);
+            if (!enabledViaScript && !title.isEmpty()) {
+                // Yes, we have a title.
+                if (m_preferredStylesheetSetName.isEmpty()) {
+                    // No preferred set has been established. If
+                    // we are NOT an alternate sheet, then establish
+                    // us as the preferred set. Otherwise, just ignore
+                    // this sheet.
+                    if (is<HTMLStyleElement>(element) || !rel.contains("alternate"))
+                        m_preferredStylesheetSetName = m_selectedStylesheetSetName = title;
+                }
+                if (title != m_preferredStylesheetSetName)
+                    sheet = nullptr;
+            }
+
+            if (rel.contains("alternate") && title.isEmpty())
+                sheet = nullptr;
+        }
+        if (sheet)
+            sheets.append(sheet);
+    }
+}
+
+Scope::StyleResolverUpdateType Scope::analyzeStyleSheetChange(const Vector<RefPtr<CSSStyleSheet>>& newStylesheets, bool& requiresFullStyleRecalc)
+{
+    requiresFullStyleRecalc = true;
+    
+    unsigned newStylesheetCount = newStylesheets.size();
+
+    if (!styleResolverIfExists())
+        return Reconstruct;
+
+    StyleResolver& styleResolver = *styleResolverIfExists();
+
+    // Find out which stylesheets are new.
+    unsigned oldStylesheetCount = m_activeStyleSheets.size();
+    if (newStylesheetCount < oldStylesheetCount)
+        return Reconstruct;
+
+    Vector<StyleSheetContents*> addedSheets;
+    unsigned newIndex = 0;
+    for (unsigned oldIndex = 0; oldIndex < oldStylesheetCount; ++oldIndex) {
+        if (newIndex >= newStylesheetCount)
+            return Reconstruct;
+        while (m_activeStyleSheets[oldIndex] != newStylesheets[newIndex]) {
+            addedSheets.append(&newStylesheets[newIndex]->contents());
+            ++newIndex;
+            if (newIndex == newStylesheetCount)
+                return Reconstruct;
+        }
+        ++newIndex;
+    }
+    bool hasInsertions = !addedSheets.isEmpty();
+    while (newIndex < newStylesheetCount) {
+        addedSheets.append(&newStylesheets[newIndex]->contents());
+        ++newIndex;
+    }
+    // If all new sheets were added at the end of the list we can just add them to existing StyleResolver.
+    // If there were insertions we need to re-add all the stylesheets so rules are ordered correctly.
+    auto styleResolverUpdateType = hasInsertions ? Reset : Additive;
+
+    // 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 (!m_document.bodyOrFrameset() || m_document.hasNodesWithPlaceholderStyle())
+        return styleResolverUpdateType;
+
+    StyleInvalidationAnalysis invalidationAnalysis(addedSheets, styleResolver.mediaQueryEvaluator());
+    if (invalidationAnalysis.dirtiesAllStyle())
+        return styleResolverUpdateType;
+    invalidationAnalysis.invalidateStyle(m_document);
+    requiresFullStyleRecalc = false;
+
+    return styleResolverUpdateType;
+}
+
+static void filterEnabledNonemptyCSSStyleSheets(Vector<RefPtr<CSSStyleSheet>>& result, const Vector<RefPtr<StyleSheet>>& sheets)
+{
+    for (auto& sheet : sheets) {
+        if (!is<CSSStyleSheet>(*sheet))
+            continue;
+        CSSStyleSheet& styleSheet = downcast<CSSStyleSheet>(*sheet);
+        if (styleSheet.isLoading())
+            continue;
+        if (styleSheet.disabled())
+            continue;
+        if (!styleSheet.length())
+            continue;
+        result.append(&styleSheet);
+    }
+}
+
+void Scope::updateActiveStyleSheets(UpdateType updateType)
+{
+    ASSERT(!m_pendingUpdateType);
+
+    if (m_document.inStyleRecalc() || m_document.inRenderTreeUpdate()) {
+        // Protect against deleting style resolver in the middle of a style resolution.
+        // Crash stacks indicate we can get here when a resource load fails synchronously (for example due to content blocking).
+        // FIXME: These kind of cases should be eliminated and this path replaced by an assert.
+        m_pendingUpdateType = UpdateType::ContentsOrInterpretation;
+        m_document.scheduleForcedStyleRecalc();
+        return;
+    }
+
+    if (!m_document.hasLivingRenderTree()) {
+        m_document.clearStyleResolver();
+        return;
+    }
+
+    // Don't bother updating, since we haven't loaded all our style info yet
+    // and haven't calculated the style resolver for the first time.
+    if (!m_shadowRoot && !m_didUpdateActiveStyleSheets && m_pendingStyleSheetCount) {
+        m_document.clearStyleResolver();
+        return;
+    }
+
+    // FIXME: Support optimized invalidation in shadow trees.
+    if (m_shadowRoot)
+        updateType = UpdateType::ContentsOrInterpretation;
+
+    m_didUpdateActiveStyleSheets = true;
+
+    Vector<RefPtr<StyleSheet>> activeStyleSheets;
+    collectActiveStyleSheets(activeStyleSheets);
+
+    Vector<RefPtr<CSSStyleSheet>> activeCSSStyleSheets;
+    activeCSSStyleSheets.appendVector(m_document.extensionStyleSheets().injectedAuthorStyleSheets());
+    activeCSSStyleSheets.appendVector(m_document.extensionStyleSheets().authorStyleSheetsForTesting());
+    filterEnabledNonemptyCSSStyleSheets(activeCSSStyleSheets, activeStyleSheets);
+
+    bool requiresFullStyleRecalc = true;
+    StyleResolverUpdateType styleResolverUpdateType = Reconstruct;
+    if (updateType == UpdateType::ActiveSet)
+        styleResolverUpdateType = analyzeStyleSheetChange(activeCSSStyleSheets, requiresFullStyleRecalc);
+
+    updateStyleResolver(activeCSSStyleSheets, styleResolverUpdateType);
+
+    m_weakCopyOfActiveStyleSheetListForFastLookup = nullptr;
+    m_activeStyleSheets.swap(activeCSSStyleSheets);
+    m_styleSheetsForStyleSheetList.swap(activeStyleSheets);
+
+    InspectorInstrumentation::activeStyleSheetsUpdated(m_document);
+
+    for (const auto& sheet : m_activeStyleSheets) {
+        if (sheet->contents().usesStyleBasedEditability())
+            m_usesStyleBasedEditability = true;
+    }
+
+    if (requiresFullStyleRecalc) {
+        if (m_shadowRoot) {
+            for (auto& shadowChild : childrenOfType<Element>(*m_shadowRoot))
+                shadowChild.setNeedsStyleRecalc();
+        } else
+            m_document.scheduleForcedStyleRecalc();
+    }
+}
+
+void Scope::updateStyleResolver(Vector<RefPtr<CSSStyleSheet>>& activeStyleSheets, StyleResolverUpdateType updateType)
+{
+    if (updateType == Reconstruct) {
+        if (m_shadowRoot)
+            m_shadowRoot->resetStyleResolver();
+        else
+            m_document.clearStyleResolver();
+        return;
+    }
+    auto& styleResolver = this->styleResolver();
+
+    if (updateType == Reset) {
+        styleResolver.ruleSets().resetAuthorStyle();
+        styleResolver.appendAuthorStyleSheets(activeStyleSheets);
+    } else {
+        ASSERT(updateType == Additive);
+        unsigned firstNewIndex = m_activeStyleSheets.size();
+        Vector<RefPtr<CSSStyleSheet>> newStyleSheets;
+        newStyleSheets.appendRange(activeStyleSheets.begin() + firstNewIndex, activeStyleSheets.end());
+        styleResolver.appendAuthorStyleSheets(newStyleSheets);
+    }
+
+    if (!m_shadowRoot) {
+        auto& userAgentShadowTreeStyleResolver = m_document.userAgentShadowTreeStyleResolver();
+        userAgentShadowTreeStyleResolver.ruleSets().resetAuthorStyle();
+        auto& authorRuleSet = styleResolver.ruleSets().authorStyle();
+        if (authorRuleSet.hasShadowPseudoElementRules())
+            userAgentShadowTreeStyleResolver.ruleSets().authorStyle().copyShadowPseudoElementRulesFrom(authorRuleSet);
+    }
+}
+
+const Vector<RefPtr<CSSStyleSheet>> Scope::activeStyleSheetsForInspector() const
+{
+    Vector<RefPtr<CSSStyleSheet>> result;
+
+    result.appendVector(m_document.extensionStyleSheets().injectedAuthorStyleSheets());
+    result.appendVector(m_document.extensionStyleSheets().authorStyleSheetsForTesting());
+
+    for (auto& styleSheet : m_styleSheetsForStyleSheetList) {
+        if (!is<CSSStyleSheet>(*styleSheet))
+            continue;
+
+        CSSStyleSheet& sheet = downcast<CSSStyleSheet>(*styleSheet);
+        if (sheet.disabled())
+            continue;
+
+        result.append(&sheet);
+    }
+
+    return result;
+}
+
+bool Scope::activeStyleSheetsContains(const CSSStyleSheet* sheet) const
+{
+    if (!m_weakCopyOfActiveStyleSheetListForFastLookup) {
+        m_weakCopyOfActiveStyleSheetListForFastLookup = std::make_unique<HashSet<const CSSStyleSheet*>>();
+        for (auto& activeStyleSheet : m_activeStyleSheets)
+            m_weakCopyOfActiveStyleSheetListForFastLookup->add(activeStyleSheet.get());
+    }
+    return m_weakCopyOfActiveStyleSheetListForFastLookup->contains(sheet);
+}
+
+void Scope::flushPendingUpdate()
+{
+    if (!m_pendingUpdateType)
+        return;
+    auto updateType = *m_pendingUpdateType;
+
+    clearPendingUpdate();
+
+    updateActiveStyleSheets(updateType);
+}
+
+void Scope::clearPendingUpdate()
+{
+    m_pendingUpdateTimer.stop();
+    m_pendingUpdateType = { };
+}
+
+void Scope::scheduleActiveSetUpdate()
+{
+    if (m_shadowRoot) {
+        // FIXME: We need to flush updates recursively to support asynchronous updates in shadow trees.
+        didChangeCandidatesForActiveSet();
+        return;
+    }
+    if (m_pendingUpdateTimer.isActive())
+        return;
+    if (!m_pendingUpdateType)
+        m_pendingUpdateType = UpdateType::ActiveSet;
+    m_pendingUpdateTimer.startOneShot(0);
+}
+
+void Scope::didChangeCandidatesForActiveSet()
+{
+    auto updateType = m_pendingUpdateType.valueOr(UpdateType::ActiveSet);
+    clearPendingUpdate();
+    updateActiveStyleSheets(updateType);
+}
+
+void Scope::didChangeContentsOrInterpretation()
+{
+    clearPendingUpdate();
+    updateActiveStyleSheets(UpdateType::ContentsOrInterpretation);
+}
+
+void Scope::pendingUpdateTimerFired()
+{
+    flushPendingUpdate();
+}
+
+}
+}