/*
 * Copyright (C) 2018 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.SourcesNavigationSidebarPanel = class SourcesNavigationSidebarPanel extends WI.NavigationSidebarPanel
{
    constructor()
    {
        const shouldAutoPruneStaleTopLevelResourceTreeElements = true;
        super("sources", WI.UIString("Sources"), shouldAutoPruneStaleTopLevelResourceTreeElements);

        this._workerTargetTreeElementMap = new Map;
        this._mainFrameTreeElement = null;
        this._extensionScriptsFolderTreeElement = null;
        this._extensionStyleSheetsFolderTreeElement = null;
        this._extraScriptsFolderTreeElement = null;
        this._extraStyleSheetsFolderTreeElement = null;
        this._anonymousScriptsFolderTreeElement = null;
        this._anonymousStyleSheetsFolderTreeElement = null;

        this._originTreeElementMap = new Map;

        this._boundCompareTreeElements = this._compareTreeElements.bind(this);

        this._debuggerNavigationBar = new WI.NavigationBar;
        this.addSubview(this._debuggerNavigationBar);

        let createActivateNavigationItem = ({identifier, defaultToolTip, activatedToolTip, image}) => {
            let navigationItem = new WI.ActivateButtonNavigationItem(identifier, defaultToolTip, activatedToolTip, image, 15, 15);
            this._debuggerNavigationBar.addNavigationItem(navigationItem);
            return navigationItem;
        };

        let createToggleNavigationItem = ({identifier, defaultToolTip, alternateToolTip, defaultImage, alternateImage}) => {
            let navigationItem = new WI.ToggleButtonNavigationItem(identifier, defaultToolTip, alternateToolTip, defaultImage, alternateImage, 15, 15);
            this._debuggerNavigationBar.addNavigationItem(navigationItem);
            return navigationItem;
        };

        let createButtonNavigationitem = ({identifier, toolTipOrLabel, image}) => {
            let navigationItem = new WI.ButtonNavigationItem(identifier, toolTipOrLabel, image, 15, 15);
            this._debuggerNavigationBar.addNavigationItem(navigationItem);
            return navigationItem;
        };

        this._debuggerBreakpointsButtonItem = createActivateNavigationItem({
            identifier: "debugger-breakpoints",
            defaultToolTip: WI.UIString("Enable all breakpoints (%s)").format(WI.toggleBreakpointsKeyboardShortcut.displayName),
            activatedToolTip: WI.UIString("Disable all breakpoints (%s)").format(WI.toggleBreakpointsKeyboardShortcut.displayName),
            image: "Images/Breakpoints.svg",
        });
        this._debuggerBreakpointsButtonItem.activated = WI.debuggerManager.breakpointsEnabled;
        this._debuggerBreakpointsButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerToggleBreakpoints, this);

        this._debuggerPauseResumeButtonItem = createToggleNavigationItem({
            identifier: "debugger-pause-resume",
            defaultToolTip: WI.UIString("Pause script execution (%s or %s)").format(WI.pauseOrResumeKeyboardShortcut.displayName, WI.pauseOrResumeAlternateKeyboardShortcut.displayName),
            alternateToolTip: WI.UIString("Continue script execution (%s or %s)").format(WI.pauseOrResumeKeyboardShortcut.displayName, WI.pauseOrResumeAlternateKeyboardShortcut.displayName),
            defaultImage: "Images/Pause.svg",
            alternateImage: "Images/Resume.svg",
        });
        this._debuggerPauseResumeButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerPauseResumeToggle, this);

        this._debuggerStepOverButtonItem = createButtonNavigationitem({
            identifier: "debugger-step-over",
            toolTipOrLabel: WI.UIString("Step over (%s or %s)").format(WI.stepOverKeyboardShortcut.displayName, WI.stepOverAlternateKeyboardShortcut.displayName),
            image: "Images/StepOver.svg",
        });
        this._debuggerStepOverButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerStepOver, this);
        this._debuggerStepOverButtonItem.enabled = false;

        this._debuggerStepIntoButtonItem = createButtonNavigationitem({
            identifier: "debugger-step-into",
            toolTipOrLabel: WI.UIString("Step into (%s or %s)").format(WI.stepIntoKeyboardShortcut.displayName, WI.stepIntoAlternateKeyboardShortcut.displayName),
            image: "Images/StepInto.svg",
        });
        this._debuggerStepIntoButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerStepInto, this);
        this._debuggerStepIntoButtonItem.enabled = false;

        this._debuggerStepOutButtonItem = createButtonNavigationitem({
            identifier: "debugger-step-out",
            toolTipOrLabel: WI.UIString("Step out (%s or %s)").format(WI.stepOutKeyboardShortcut.displayName, WI.stepOutAlternateKeyboardShortcut.displayName),
            image: "Images/StepOut.svg",
        });
        this._debuggerStepOutButtonItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.debuggerStepOut, this);
        this._debuggerStepOutButtonItem.enabled = false;

        this._timelineRecordingWarningElement = null;
        this._auditTestWarningElement = null;
        this._breakpointsDisabledWarningElement = null;

        this._pauseReasonTreeOutline = null;
        this._pauseReasonLinkContainerElement = document.createElement("span");
        this._pauseReasonTextRow = new WI.DetailsSectionTextRow;
        this._pauseReasonGroup = new WI.DetailsSectionGroup([this._pauseReasonTextRow]);
        this._pauseReasonSection = new WI.DetailsSection("paused-reason", WI.UIString("Pause Reason"), [this._pauseReasonGroup], this._pauseReasonLinkContainerElement);

        this._pauseReasonContainer = this.contentView.element.appendChild(document.createElement("div"));
        this._pauseReasonContainer.classList.add("pause-reason-container");
        this._pauseReasonContainer.hidden = true;
        this._pauseReasonContainer.appendChild(this._pauseReasonSection.element);

        this._callStackTreeOutline = this.createContentTreeOutline({suppressFiltering: true});
        this._callStackTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);

        let callStackRow = new WI.DetailsSectionRow;
        callStackRow.element.appendChild(this._callStackTreeOutline.element);

        let callStackGroup = new WI.DetailsSectionGroup([callStackRow]);
        this._callStackSection = new WI.DetailsSection("call-stack", WI.UIString("Call Stack"), [callStackGroup]);

        this._callStackContainer = this.contentView.element.appendChild(document.createElement("div"));
        this._callStackContainer.classList.add("call-stack-container");
        this._callStackContainer.hidden = true;
        this._callStackContainer.appendChild(this._callStackSection.element);

        this._mainTargetTreeElement = null;
        this._activeCallFrameTreeElement = null;

        // Prevent the breakpoints list from being used as the source of selection restoration (e.g. on reload or navigation).
        this._breakpointsTreeOutline = this.createContentTreeOutline({ignoreCookieRestoration: true});
        this._breakpointsTreeOutline.addEventListener(WI.TreeOutline.Event.ElementAdded, this._handleBreakpointElementAddedOrRemoved, this);
        this._breakpointsTreeOutline.addEventListener(WI.TreeOutline.Event.ElementRemoved, this._handleBreakpointElementAddedOrRemoved, this);
        this._breakpointsTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);
        this._breakpointsTreeOutline.ondelete = (selectedTreeElement) => {
            console.assert(selectedTreeElement.selected);

            if (!WI.debuggerManager.isBreakpointRemovable(selectedTreeElement.representedObject)) {
                let treeElementToSelect = selectedTreeElement.nextSelectableSibling;
                if (treeElementToSelect) {
                    const omitFocus = true;
                    const selectedByUser = true;
                    treeElementToSelect.select(omitFocus, selectedByUser);
                }
            } else if (selectedTreeElement instanceof WI.ResourceTreeElement || selectedTreeElement instanceof WI.ScriptTreeElement) {
                let breakpoints = this._breakpointsBeneathTreeElement(selectedTreeElement);
                this._removeAllBreakpoints(breakpoints);
            } else if (selectedTreeElement.representedObject === SourcesNavigationSidebarPanel.__windowEventTargetRepresentedObject) {
                let eventBreakpointsOnWindow = WI.domManager.eventListenerBreakpoints.filter((eventBreakpoint) => eventBreakpoint.eventListener.onWindow);
                for (let eventBreakpoint of eventBreakpointsOnWindow)
                    WI.domManager.removeBreakpointForEventListener(eventBreakpoint.eventListener);
            }

            return true;
        };
        this._breakpointsTreeOutline.populateContextMenu = (contextMenu, event, treeElement) => {
            // This check is necessary since the context menu is created by the TreeOutline, meaning
            // that any child could be the target of the context menu event.
            if (treeElement instanceof WI.ResourceTreeElement || treeElement instanceof WI.ScriptTreeElement) {
                let breakpoints = this._breakpointsBeneathTreeElement(treeElement);

                let shouldDisable = breakpoints.some((breakpoint) => !breakpoint.disabled);
                contextMenu.appendItem(shouldDisable ? WI.UIString("Disable Breakpoints") : WI.UIString("Enable Breakpoints"), () => {
                    this._toggleAllBreakpoints(breakpoints, shouldDisable);
                });

                contextMenu.appendItem(WI.UIString("Delete Breakpoints"), () => {
                    this._removeAllBreakpoints(breakpoints);
                });
            }

            WI.TreeOutline.prototype.populateContextMenu(contextMenu, event, treeElement);
        };

        let breakpointsRow = new WI.DetailsSectionRow;
        breakpointsRow.element.appendChild(this._breakpointsTreeOutline.element);

        let breakpointNavigationBarWrapper = document.createElement("div");

        let breakpointNavigationBar = new WI.NavigationBar;
        breakpointNavigationBarWrapper.appendChild(breakpointNavigationBar.element);

        this._createBreakpointButton = new WI.ButtonNavigationItem("create-breakpoint", WI.UIString("Create Breakpoint"), "Images/Plus13.svg", 13, 13);
        WI.addMouseDownContextMenuHandlers(this._createBreakpointButton.element, this._populateCreateBreakpointContextMenu.bind(this));
        breakpointNavigationBar.addNavigationItem(this._createBreakpointButton);

        let breakpointsGroup = new WI.DetailsSectionGroup([breakpointsRow]);
        this._breakpointsSection = new WI.DetailsSection("breakpoints", WI.UIString("Breakpoints"), [breakpointsGroup], breakpointNavigationBarWrapper);

        let breakpointsContainer = this.contentView.element.appendChild(document.createElement("div"));
        breakpointsContainer.classList.add("breakpoints-container");
        breakpointsContainer.appendChild(this._breakpointsSection.element);

        this._localOverridesTreeOutline = this.createContentTreeOutline({suppressFiltering: true});
        this._localOverridesTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);

        this._localOverridesRow = new WI.DetailsSectionRow(WI.UIString("No Overrides"));

        let localOverridesGroup = new WI.DetailsSectionGroup([this._localOverridesRow]);
        this._localOverridesSection = new WI.DetailsSection("local-overrides", WI.UIString("Local Overrides"), [localOverridesGroup]);

        this._localOverridesContainer = this.contentView.element.appendChild(document.createElement("div"));
        this._localOverridesContainer.classList.add("local-overrides-container");
        this._localOverridesContainer.hidden = true;
        this._localOverridesContainer.appendChild(this._localOverridesSection.element);

        this._resourcesNavigationBar = new WI.NavigationBar;
        this.contentView.addSubview(this._resourcesNavigationBar);

        this._resourceGroupingModeScopeBarItems = {};
        let createResourceGroupingModeScopeBarItem = (mode, label) => {
            this._resourceGroupingModeScopeBarItems[mode] = new WI.ScopeBarItem("sources-resource-grouping-mode-" + mode, label, {exclusive: true});
            this._resourceGroupingModeScopeBarItems[mode][SourcesNavigationSidebarPanel.ResourceGroupingModeSymbol] = mode;
        };
        createResourceGroupingModeScopeBarItem(WI.Resource.GroupingMode.Type, WI.UIString("By Type"));
        createResourceGroupingModeScopeBarItem(WI.Resource.GroupingMode.Path, WI.UIString("By Path"));

        this._resourceGroupingModeScopeBar = new WI.ScopeBar("sources-resource-grouping-mode-scope-bar", Object.values(this._resourceGroupingModeScopeBarItems), this._resourceGroupingModeScopeBarItems[WI.settings.resourceGroupingMode.value]);
        this._resourceGroupingModeScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._handleResourceGroupingModeScopeBarSelectionChanged, this);
        this._resourcesNavigationBar.addNavigationItem(this._resourceGroupingModeScopeBar);

        let resourcesContainer = this.contentView.element.appendChild(document.createElement("div"));
        resourcesContainer.classList.add("resources-container");

        this._resourcesTreeOutline = this.contentTreeOutline;
        this._resourcesTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);
        this._resourcesTreeOutline.includeSourceMapResourceChildren = true;
        resourcesContainer.appendChild(this._resourcesTreeOutline.element);

        if (WI.NetworkManager.supportsLocalResourceOverrides() || WI.NetworkManager.supportsBootstrapScript() || InspectorBackend.hasDomain("CSS")) {
            let createResourceNavigationBar = new WI.NavigationBar;

            let createResourceButtonNavigationItem = new WI.ButtonNavigationItem("create-resource", WI.UIString("Create Resource"), "Images/Plus15.svg", 15, 15);
            WI.addMouseDownContextMenuHandlers(createResourceButtonNavigationItem.element, this._populateCreateResourceContextMenu.bind(this));
            createResourceNavigationBar.addNavigationItem(createResourceButtonNavigationItem);

            this.filterBar.element.insertBefore(createResourceNavigationBar.element, this.filterBar.element.firstChild);
        }

        const activatedByDefault = false;
        this.filterBar.addFilterBarButton("sources-only-show-resources-with-issues", this._filterByResourcesWithIssues.bind(this), activatedByDefault, WI.UIString("Only show resources with issues"), WI.UIString("Show all resources"), "Images/Errors.svg", 15, 15);

        const resourceTypeScopeItemPrefix = "sources-resource-type-";
        let resourceTypeScopeBarItems = [];
        resourceTypeScopeBarItems.push(new WI.ScopeBarItem(resourceTypeScopeItemPrefix + "all", WI.UIString("All")));
        for (let value of Object.values(WI.Resource.Type)) {
            let scopeBarItem = new WI.ScopeBarItem(resourceTypeScopeItemPrefix + value, WI.Resource.displayNameForType(value, true));
            scopeBarItem[SourcesNavigationSidebarPanel.ResourceTypeSymbol] = value;
            resourceTypeScopeBarItems.push(scopeBarItem);
        }

        const shouldGroupNonExclusiveItems = true;
        this._resourceTypeScopeBar = new WI.ScopeBar("sources-resource-type-scope-bar", resourceTypeScopeBarItems, resourceTypeScopeBarItems[0], shouldGroupNonExclusiveItems);
        this._resourceTypeScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._handleResourceTypeScopeBarSelectionChanged, this);
        this.filterBar.addFilterNavigationItem(this._resourceTypeScopeBar);

        WI.settings.resourceGroupingMode.addEventListener(WI.Setting.Event.Changed, this._handleResourceGroupingModeChanged, this);

        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._handleFrameMainResourceDidChange, this);
        WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._handleResourceAdded, this);
        WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._handleResourceAdded, this);

        WI.networkManager.addEventListener(WI.NetworkManager.Event.FrameWasAdded, this._handleFrameWasAdded, this);

        if (WI.NetworkManager.supportsBootstrapScript()) {
            WI.networkManager.addEventListener(WI.NetworkManager.Event.BootstrapScriptCreated, this._handleBootstrapScriptCreated, this);
            WI.networkManager.addEventListener(WI.NetworkManager.Event.BootstrapScriptDestroyed, this._handleBootstrapScriptDestroyed, this);
        }

        if (WI.NetworkManager.supportsLocalResourceOverrides()) {
            WI.networkManager.addEventListener(WI.NetworkManager.Event.LocalResourceOverrideAdded, this._handleLocalResourceOverrideAdded, this);
            WI.networkManager.addEventListener(WI.NetworkManager.Event.LocalResourceOverrideRemoved, this._handleLocalResourceOverrideRemoved, this);
        }

        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointAdded, this._handleDebuggerBreakpointAdded, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.DOMBreakpointAdded, this._handleDebuggerBreakpointAdded, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.EventBreakpointAdded, this._handleDebuggerBreakpointAdded, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.URLBreakpointAdded, this._handleDebuggerBreakpointAdded, this);

        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointRemoved, this._handleDebuggerBreakpointRemoved, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved, this._handleDebuggerBreakpointRemoved, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.EventBreakpointRemoved, this._handleDebuggerBreakpointRemoved, this);
        WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.URLBreakpointRemoved, this._handleDebuggerBreakpointRemoved, this);

        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointsEnabledDidChange, this._handleDebuggerBreakpointsEnabledDidChange, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, this._handleDebuggerScriptAdded, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptRemoved, this._handleDebuggerScriptRemoved, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptsCleared, this._handleDebuggerScriptsCleared, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, this._handleDebuggerPaused, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Resumed, this._handleDebuggerResumed, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.CallFramesDidChange, this._handleDebuggerCallFramesDidChange, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ActiveCallFrameDidChange, this._handleDebuggerActiveCallFrameDidChange, this);
        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.WaitingToPause, this._handleDebuggerWaitingToPause, this);

        WI.Breakpoint.addEventListener(WI.Breakpoint.Event.DisplayLocationDidChange, this._handleDebuggerObjectDisplayLocationDidChange, this);
        WI.IssueMessage.addEventListener(WI.IssueMessage.Event.DisplayLocationDidChange, this._handleDebuggerObjectDisplayLocationDidChange, this);

        WI.DOMBreakpoint.addEventListener(WI.DOMBreakpoint.Event.DOMNodeChanged, this._handleDOMBreakpointDOMNodeChanged, this);

        WI.consoleManager.addEventListener(WI.ConsoleManager.Event.IssueAdded, this._handleConsoleIssueAdded, this);
        WI.consoleManager.addEventListener(WI.ConsoleManager.Event.Cleared, this._handleConsoleCleared, this);

        WI.timelineManager.addEventListener(WI.TimelineManager.Event.CapturingStateChanged, this._handleTimelineCapturingStateChanged, this);

        WI.auditManager.addEventListener(WI.AuditManager.Event.TestScheduled, this._handleAuditManagerTestScheduled, this);
        WI.auditManager.addEventListener(WI.AuditManager.Event.TestCompleted, this._handleAuditManagerTestCompleted, this);

        WI.cssManager.addEventListener(WI.CSSManager.Event.StyleSheetAdded, this._handleCSSStyleSheetAdded, this);
        WI.cssManager.addEventListener(WI.CSSManager.Event.StyleSheetRemoved, this._handleCSSStyleSheetRemoved, this);

        WI.targetManager.addEventListener(WI.TargetManager.Event.TargetAdded, this._handleTargetAdded, this);
        WI.targetManager.addEventListener(WI.TargetManager.Event.TargetRemoved, this._handleTargetRemoved, this);

        WI.notifications.addEventListener(WI.Notification.ExtraDomainsActivated, this._handleExtraDomainsActivated, this);

        if (WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel()) {
            this._resourcesTreeOutline.disclosureButtons = false;
            WI.SourceCode.addEventListener(WI.SourceCode.Event.SourceMapAdded, () => {
                this._resourcesTreeOutline.disclosureButtons = true;
            }, this);
        }

        WI.debuggerManager.addBreakpoint(WI.debuggerManager.allExceptionsBreakpoint);
        WI.debuggerManager.addBreakpoint(WI.debuggerManager.uncaughtExceptionsBreakpoint);

        // COMPATIBILITY (iOS 10): Debugger.setPauseOnAssertions did not exist yet.
        if (InspectorBackend.hasCommand("Debugger.setPauseOnAssertions") && WI.settings.showAssertionFailuresBreakpoint.value)
            WI.debuggerManager.addBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);

        // COMPATIBILITY (iOS 13): Debugger.setPauseOnMicrotasks did not exist yet.
        if (InspectorBackend.hasCommand("Debugger.setPauseOnMicrotasks") && WI.settings.showAllMicrotasksBreakpoint.value)
            WI.debuggerManager.addBreakpoint(WI.debuggerManager.allMicrotasksBreakpoint);

        for (let target of WI.targets)
            this._addTarget(target);

        this._updateCallStackTreeOutline();

        this._handleResourceGroupingModeChanged();

        if (WI.NetworkManager.supportsBootstrapScript()) {
            let bootstrapScript = WI.networkManager.bootstrapScript;
            if (bootstrapScript)
                this._addLocalOverride(bootstrapScript);
        }

        if (WI.NetworkManager.supportsLocalResourceOverrides()) {
            for (let localResourceOverride of WI.networkManager.localResourceOverrides)
                this._addLocalOverride(localResourceOverride);
        }

        if (WI.domDebuggerManager.supported) {
            if (WI.settings.showAllAnimationFramesBreakpoint.value)
                WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint);

            if (WI.settings.showAllTimeoutsBreakpoint.value)
                WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint);

            if (WI.settings.showAllIntervalsBreakpoint.value)
                WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint);

            if (WI.settings.showAllListenersBreakpoint.value)
                WI.domDebuggerManager.addEventBreakpoint(WI.domDebuggerManager.allListenersBreakpoint);

            for (let eventBreakpoint of WI.domDebuggerManager.listenerBreakpoints)
                this._addBreakpoint(eventBreakpoint);

            for (let eventListenerBreakpoint of WI.domManager.eventListenerBreakpoints)
                this._addBreakpoint(eventListenerBreakpoint);

            for (let domBreakpoint of WI.domDebuggerManager.domBreakpoints)
                this._addBreakpoint(domBreakpoint);

            if (WI.settings.showAllRequestsBreakpoint.value)
                WI.domDebuggerManager.addURLBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);

            for (let urlBreakpoints of WI.domDebuggerManager.urlBreakpoints)
                this._addBreakpoint(urlBreakpoints);
        }

        if (WI.debuggerManager.paused)
            this._handleDebuggerPaused();

        if (WI.debuggerManager.breakpointsDisabledTemporarily) {
            this._handleTimelineCapturingStateChanged();

            if (WI.auditManager.runningState === WI.AuditManager.RunningState.Active || WI.auditManager.runningState === WI.AuditManager.RunningState.Stopping)
                this._handleAuditManagerTestScheduled();
        }

        this._updateBreakpointsDisabledBanner();
    }

    // Static

    static shouldPlaceResourcesAtTopLevel()
    {
        return WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript
            || WI.sharedApp.debuggableType === WI.DebuggableType.ServiceWorker;
    }

    // Public

    get minimumWidth()
    {
        return Math.max(this._debuggerNavigationBar.minimumWidth, this._resourcesNavigationBar.minimumWidth);
    }

    closed()
    {
        WI.settings.resourceGroupingMode.removeEventListener(null, null, this);
        WI.Frame.removeEventListener(null, null, this);
        WI.Target.removeEventListener(null, null, this);
        WI.networkManager.removeEventListener(null, null, this);
        WI.debuggerManager.removeEventListener(null, null, this);
        WI.domDebuggerManager.removeEventListener(null, null, this);
        WI.Breakpoint.removeEventListener(null, null, this);
        WI.IssueMessage.removeEventListener(null, null, this);
        WI.DOMBreakpoint.removeEventListener(null, null, this);
        WI.consoleManager.removeEventListener(null, null, this);
        WI.timelineManager.removeEventListener(null, null, this);
        WI.auditManager.removeEventListener(null, null, this);
        WI.cssManager.removeEventListener(null, null, this);
        WI.targetManager.removeEventListener(null, null, this);
        WI.notifications.removeEventListener(null, null, this);
        WI.SourceCode.removeEventListener(null, null, this);

        super.closed();
    }

    showDefaultContentView()
    {
        if (WI.networkManager.mainFrame) {
            this.contentBrowser.showContentViewForRepresentedObject(WI.networkManager.mainFrame);
            return;
        }

        let firstTreeElement = this._resourcesTreeOutline.children[0];
        if (firstTreeElement)
            this.showDefaultContentViewForTreeElement(firstTreeElement);
    }

    treeElementForRepresentedObject(representedObject)
    {
        // A custom implementation is needed for this since the frames are populated lazily.

        if (representedObject instanceof WI.LocalResourceOverride)
            return this._localOverridesTreeOutline.findTreeElement(representedObject);

        if (representedObject instanceof WI.LocalResource) {
            let localResourceOverride = WI.networkManager.localResourceOverrideForURL(representedObject.url);
            return this._localOverridesTreeOutline.findTreeElement(localResourceOverride);
        }

        if (representedObject instanceof WI.Script && representedObject === WI.networkManager.bootstrapScript)
            return this._localOverridesTreeOutline.findTreeElement(representedObject);

        if (!this._mainFrameTreeElement && (representedObject instanceof WI.Resource || representedObject instanceof WI.Frame || representedObject instanceof WI.Collection)) {
            // All resources are under the main frame, so we need to return early if we don't have the main frame yet.
            return null;
        }

        switch (WI.settings.resourceGroupingMode.value) {
        case WI.Resource.GroupingMode.Path:
            if (representedObject instanceof WI.Frame)
                representedObject = representedObject.mainResource;
            break;

        default:
            WI.reportInternalError("Unknown resource grouping mode", {"Resource Grouping Mode": WI.settings.resourceGroupingMode.value});
            // Fallthrough for default value.

        case WI.Resource.GroupingMode.Type:
            if (representedObject instanceof WI.Resource && representedObject.parentFrame && representedObject.parentFrame.mainResource === representedObject)
                representedObject = representedObject.parentFrame;
            break;
        }

        function isAncestor(ancestor, resourceOrFrame) {
            // SourceMapResources are descendants of another SourceCode object.
            if (resourceOrFrame instanceof WI.SourceMapResource) {
                if (resourceOrFrame.sourceMap.originalSourceCode === ancestor)
                    return true;

                // Not a direct ancestor, so check the ancestors of the parent SourceCode object.
                resourceOrFrame = resourceOrFrame.sourceMap.originalSourceCode;
            }

            let currentFrame = resourceOrFrame.parentFrame;
            while (currentFrame) {
                if (currentFrame === ancestor)
                    return true;
                currentFrame = currentFrame.parentFrame;
            }
            return false;
        }

        function getParent(resourceOrFrame) {
            // SourceMapResources are descendants of another SourceCode object.
            if (resourceOrFrame instanceof WI.SourceMapResource)
                return resourceOrFrame.sourceMap.originalSourceCode;
            return resourceOrFrame.parentFrame;
        }

        function searchTreeOutline(treeOutline, forceSearch) {
            if (!treeOutline || (!treeOutline.selectedTreeElement && !forceSearch))
                return null;
            return treeOutline.findTreeElement(representedObject, isAncestor, getParent);
        }
        let treeElement = searchTreeOutline(this._pauseReasonTreeOutline) || searchTreeOutline(this._callStackTreeOutline) || searchTreeOutline(this._breakpointsTreeOutline) || searchTreeOutline(this._resourcesTreeOutline, true);
        if (treeElement)
            return treeElement;

        if (representedObject instanceof WI.Script) {
            // If the Script has a URL we should have found it earlier.
            if (representedObject.url) {
                console.assert(false, "Didn't find a ScriptTreeElement for a Script with a URL.", representedObject);
                return null;
            }

            console.assert(representedObject.anonymous, representedObject);

            // Since the Script does not have a URL we consider it an 'anonymous' script. These scripts happen from calls to
            // window.eval() or browser features like Auto Fill and Reader. They are not normally added to the sidebar, but since
            // we have a ScriptContentView asking for the tree element we will make a ScriptTreeElement on demand and add it.

            if (!this._anonymousScriptsFolderTreeElement)
                this._anonymousScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Anonymous Scripts"), new WI.ScriptCollection);

            if (!this._anonymousScriptsFolderTreeElement.parent) {
                let index = insertionIndexForObjectInListSortedByFunction(this._anonymousScriptsFolderTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
                this._resourcesTreeOutline.insertChild(this._anonymousScriptsFolderTreeElement, index);
            }

            this._anonymousScriptsFolderTreeElement.representedObject.add(representedObject);

            let scriptTreeElement = new WI.ScriptTreeElement(representedObject);
            this._anonymousScriptsFolderTreeElement.appendChild(scriptTreeElement);
            return scriptTreeElement;
        }

        if (representedObject instanceof WI.CSSStyleSheet) {
            // If the CSSStyleSheet has a URL we should have found it earlier.
            if (representedObject.url) {
                console.assert(false, "Didn't find a CSSStyleSheetTreeElement for a CSSStyleSheet with a URL.", representedObject);
                return null;
            }

            console.assert(representedObject.anonymous, representedObject);

            if (!this._anonymousStyleSheetsFolderTreeElement)
                this._anonymousStyleSheetsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Anonymous Style Sheets"), new WI.CSSStyleSheetCollection);

            if (!this._anonymousStyleSheetsFolderTreeElement.parent) {
                let index = insertionIndexForObjectInListSortedByFunction(this._anonymousStyleSheetsFolderTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
                this._resourcesTreeOutline.insertChild(this._anonymousStyleSheetsFolderTreeElement, index);
            }

           let cssStyleSheetTreeElement = new WI.CSSStyleSheetTreeElement(representedObject);
           this._anonymousStyleSheetsFolderTreeElement.appendChild(cssStyleSheetTreeElement);
           return cssStyleSheetTreeElement;
        }

        console.assert(false, "Didn't find a TreeElement for representedObject", representedObject);
        return null;
    }

    // Protected

    createContentTreeOutline(options = {})
    {
        let treeOutline = super.createContentTreeOutline(options);

        treeOutline.addEventListener(WI.TreeOutline.Event.ElementRevealed, (event) => {
            let treeElement = event.data.element;
            let detailsSections = [this._pauseReasonSection, this._callStackSection, this._breakpointsSection, this._localOverridesSection];
            let detailsSection = detailsSections.find((detailsSection) => detailsSection.element.contains(treeElement.listItemElement));
            if (!detailsSection)
                return;

            // Revealing a TreeElement at the scroll container's topmost edge with
            // scrollIntoViewIfNeeded may result in the element being covered by the
            // DetailsSection header, which uses sticky positioning. Detect this case,
            // and adjust the sidebar content's scroll position to compensate.
            let offset = detailsSection.headerElement.totalOffsetBottom - treeElement.listItemElement.totalOffsetTop;
            if (offset > 0)
                this.scrollElement.scrollBy(0, -offset);
        });

        return treeOutline;
    }

    resetFilter()
    {
        this._resourceTypeScopeBar.resetToDefault();

        super.resetFilter();
    }

    hasCustomFilters()
    {
        console.assert(this._resourceTypeScopeBar.selectedItems.length === 1);
        let selectedScopeBarItem = this._resourceTypeScopeBar.selectedItems[0];
        return selectedScopeBarItem && selectedScopeBarItem !== this._resourceTypeScopeBar.defaultItem;
    }

    matchTreeElementAgainstCustomFilters(treeElement, flags)
    {
        // Only apply the resource type filter to the resources list.
        if (treeElement.treeOutline !== this._resourcesTreeOutline)
            return true;

        console.assert(this._resourceTypeScopeBar.selectedItems.length === 1);
        let selectedScopeBarItem = this._resourceTypeScopeBar.selectedItems[0];

        // Show everything if there is no selection or "All Resources" is selected (the default item).
        if (!selectedScopeBarItem || selectedScopeBarItem === this._resourceTypeScopeBar.defaultItem)
            return true;

        // Folders are hidden on the first pass, but visible childen under the folder will force the folder visible again.
        if (treeElement instanceof WI.FolderTreeElement || treeElement instanceof WI.OriginTreeElement)
            return false;

        if (treeElement instanceof WI.IssueTreeElement)
            treeElement = treeElement.parent;

        function match()
        {
            if (treeElement instanceof WI.FrameTreeElement)
                return selectedScopeBarItem[WI.SourcesNavigationSidebarPanel.ResourceTypeSymbol] === WI.Resource.Type.Document;

            if (treeElement instanceof WI.ScriptTreeElement)
                return selectedScopeBarItem[WI.SourcesNavigationSidebarPanel.ResourceTypeSymbol] === WI.Resource.Type.Script;

            if (treeElement instanceof WI.CSSStyleSheetTreeElement)
                return selectedScopeBarItem[WI.SourcesNavigationSidebarPanel.ResourceTypeSymbol] === WI.Resource.Type.StyleSheet;

            console.assert(treeElement instanceof WI.ResourceTreeElement, "Unknown treeElement", treeElement);
            if (!(treeElement instanceof WI.ResourceTreeElement))
                return false;

            return treeElement.resource.type === selectedScopeBarItem[WI.SourcesNavigationSidebarPanel.ResourceTypeSymbol];
        }

        let matched = match();
        if (matched)
            flags.expandTreeElement = true;
        return matched;
    }

    // Popover delegate

    willDismissPopover(popover)
    {
        if (popover instanceof WI.LocalResourceOverridePopover) {
            this._willDismissLocalOverridePopover(popover);
            return;
        }

        if (popover instanceof WI.EventBreakpointPopover) {
            this._willDismissEventBreakpointPopover(popover);
            return;
        }

        if (popover instanceof WI.URLBreakpointPopover) {
            this._willDismissURLBreakpointPopover(popover);
            return;
        }

        console.assert();
    }

    // Private

    _willDismissLocalOverridePopover(popover)
    {
        let serializedData = popover.serializedData;
        if (!serializedData) {
            if (!this._localOverridesTreeOutline.children.length)
                this._localOverridesContainer.hidden = true;

            InspectorFrontendHost.beep();
            return;
        }

        let {url, isCaseSensitive, isRegex, mimeType, statusCode, statusText, headers} = serializedData;

        // Do not conflict with an existing override.
        let existingOverride = WI.networkManager.localResourceOverrideForURL(url);
        if (existingOverride) {
            InspectorFrontendHost.beep();
            return;
        }

        let localResourceOverride = WI.LocalResourceOverride.create({
            url,
            isCaseSensitive,
            isRegex,
            mimeType,
            statusCode,
            statusText,
            headers,
            content: "",
            base64Encoded: false,
        });

        WI.networkManager.addLocalResourceOverride(localResourceOverride);
        WI.showLocalResourceOverride(localResourceOverride);
    }

    _willDismissEventBreakpointPopover(popover)
    {
        let breakpoint = popover.breakpoint;
        if (!breakpoint) {
            InspectorFrontendHost.beep();
            return;
        }

        if (!WI.domDebuggerManager.addEventBreakpoint(breakpoint))
            InspectorFrontendHost.beep();
    }

    _willDismissURLBreakpointPopover(popover)
    {
        let breakpoint = popover.breakpoint;
        if (!breakpoint) {
            InspectorFrontendHost.beep();
            return;
        }

        if (!WI.domDebuggerManager.addURLBreakpoint(breakpoint))
            InspectorFrontendHost.beep();
    }

    _filterByResourcesWithIssues(treeElement)
    {
        if (treeElement.treeOutline !== this._resourcesTreeOutline)
            return true;

        if (treeElement instanceof WI.IssueTreeElement)
            return true;

        if (treeElement.hasChildren) {
            for (let child of treeElement.children) {
                if (child instanceof WI.IssueTreeElement)
                    return true;
            }
        }
        return false;
    }

    _compareTreeElements(a, b)
    {
        const rankFunctions = [
            (treeElement) => treeElement instanceof WI.ScriptTreeElement && treeElement.representedObject === WI.networkManager.bootstrapScript,
            (treeElement) => treeElement instanceof WI.LocalResourceOverrideTreeElement,
            (treeElement) => treeElement instanceof WI.CSSStyleSheetTreeElement && treeElement.representedObject.isInspectorStyleSheet(),
            (treeElement) => treeElement === this._mainFrameTreeElement,
            (treeElement) => treeElement instanceof WI.FrameTreeElement,
            (treeElement) => treeElement instanceof WI.OriginTreeElement,
            (treeElement) => {
                return treeElement !== this._extensionScriptsFolderTreeElement
                    && treeElement !== this._extensionStyleSheetsFolderTreeElement
                    && treeElement !== this._extraScriptsFolderTreeElement
                    && treeElement !== this._extraStyleSheetsFolderTreeElement
                    && treeElement !== this._anonymousScriptsFolderTreeElement
                    && treeElement !== this._anonymousStyleSheetsFolderTreeElement;
            },
            (treeElement) => treeElement === this._extensionScriptsFolderTreeElement,
            (treeElement) => treeElement === this._extensionStyleSheetsFolderTreeElement,
            (treeElement) => treeElement === this._extraScriptsFolderTreeElement,
            (treeElement) => treeElement === this._extraStyleSheetsFolderTreeElement,
            (treeElement) => treeElement === this._anonymousScriptsFolderTreeElement,
            (treeElement) => treeElement === this._anonymousStyleSheetsFolderTreeElement,
        ];

        let aRank = rankFunctions.findIndex((rankFunction) => rankFunction(a));
        let bRank = rankFunctions.findIndex((rankFunction) => rankFunction(b));
        if ((aRank >= 0 && bRank < 0) || aRank < bRank)
            return -1;
        if ((bRank >= 0 && aRank < 0) || bRank < aRank)
            return 1;

        return a.mainTitle.extendedLocaleCompare(b.mainTitle) || a.subtitle.extendedLocaleCompare(b.subtitle);
    }

    _closeContentViewsFilter(contentView)
    {
        // Local Resource Override content views do not need to be closed across page navigations.
        if (contentView.representedObject instanceof WI.LocalResource && contentView.representedObject.isLocalResourceOverride)
            return false;

        return true;
    }

    _updateMainFrameTreeElement(mainFrame)
    {
        if (this.didInitialLayout)
            this.contentBrowser.contentViewContainer.closeAllContentViews(this._closeContentViewsFilter);

        let oldMainFrameTreeElement = this._mainFrameTreeElement;
        if (this._mainFrameTreeElement) {
            this._resourcesTreeOutline.removeChild(this._mainFrameTreeElement);
            this._mainFrameTreeElement = null;
        }

        if (!mainFrame)
            return;

        switch (WI.settings.resourceGroupingMode.value) {
        case WI.Resource.GroupingMode.Path: {
            for (let treeElement of this._originTreeElementMap.values()) {
                if (treeElement !== oldMainFrameTreeElement)
                    this._resourcesTreeOutline.removeChild(treeElement);
            }
            this._originTreeElementMap.clear();

            let origin = mainFrame.urlComponents.origin;
            this._mainFrameTreeElement = new WI.OriginTreeElement(origin, mainFrame, {hasChildren: true});
            this._originTreeElementMap.set(origin, this._mainFrameTreeElement);
            break;
        }

        default:
            WI.reportInternalError("Unknown resource grouping mode", {"Resource Grouping Mode": WI.settings.resourceGroupingMode.value});
            // Fallthrough for default value.

        case WI.Resource.GroupingMode.Type:
            this._mainFrameTreeElement = new WI.FrameTreeElement(mainFrame);
            break;
        }

        this._resourcesTreeOutline.insertChild(this._mainFrameTreeElement, 0);

        // Cookie restoration will attempt to re-select the resource we were showing.
        // Give it time to do that before selecting the main frame resource.
        setTimeout(() => {
            if (this._resourcesTreeOutline.selectedTreeElement)
                return;

            let currentContentView = this.contentBrowser.currentContentView;
            let treeElement = currentContentView ? this.treeElementForRepresentedObject(currentContentView.representedObject) : null;
            if (!treeElement)
                treeElement = this.treeElementForRepresentedObject(WI.networkManager.mainFrame);
            this.showDefaultContentViewForTreeElement(treeElement);
        });
    }

    _addTarget(target)
    {
        let treeElement = new WI.ThreadTreeElement(target);
        this._callStackTreeOutline.appendChild(treeElement);

        // FIXME: When WI.mainTarget changes?
        if (target === WI.mainTarget)
            this._mainTargetTreeElement = treeElement;

        this._updateCallStackTreeOutline();
    }

    _findCallStackTargetTreeElement(target)
    {
        for (let child of this._callStackTreeOutline.children) {
            if (child.target === target)
                return child;
        }
        return null;
    }

    _updateCallStackTreeOutline()
    {
        let singleThreadShowing = WI.targets.length <= 1;
        this._callStackTreeOutline.element.classList.toggle("single-thread", singleThreadShowing);
        if (this._mainTargetTreeElement)
            this._mainTargetTreeElement.selectable = !singleThreadShowing;
    }

    _addResource(resource)
    {
        if (WI.settings.resourceGroupingMode.value === WI.Resource.GroupingMode.Path) {
            if (!this._mainFrameTreeElement || this._resourcesTreeOutline.findTreeElement(resource))
                return;

            let parentTreeElement = null;

            if (resource instanceof WI.CSSStyleSheet) {
                console.assert(resource.isInspectorStyleSheet());
                parentTreeElement = this._resourcesTreeOutline.findTreeElement(resource.parentFrame.mainResource);
            }

            if (!parentTreeElement) {
                let origin = resource.urlComponents.origin;
                if (origin) {
                    let originTreeElement = this._originTreeElementMap.get(origin);
                    if (!originTreeElement) {
                        originTreeElement = new WI.OriginTreeElement(origin, resource.parentFrame, {hasChildren: true});
                        this._originTreeElementMap.set(origin, originTreeElement);

                        let index = insertionIndexForObjectInListSortedByFunction(originTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
                        this._resourcesTreeOutline.insertChild(originTreeElement, index);
                    }

                    let subpath = resource.urlComponents.path;
                    if (subpath && subpath[0] === "/")
                        subpath = subpath.substring(1);

                    parentTreeElement = originTreeElement.createFoldersAsNeededForSubpath(subpath, this._boundCompareTreeElements);
                } else
                    parentTreeElement = this._resourcesTreeOutline;
            }

            let resourceTreeElement = null;
            if (resource instanceof WI.CSSStyleSheet)
                resourceTreeElement = new WI.CSSStyleSheetTreeElement(resource);
            else
                resourceTreeElement = new WI.ResourceTreeElement(resource, resource, {allowDirectoryAsName: true, hideOrigin: true});

            let index = insertionIndexForObjectInListSortedByFunction(resourceTreeElement, parentTreeElement.children, this._boundCompareTreeElements);
            parentTreeElement.insertChild(resourceTreeElement, index);
        }

        if (resource.type === WI.Resource.Type.Document || resource.type === WI.Resource.Type.Script) {
            this._addBreakpointsForSourceCode(resource);
            this._addIssuesForSourceCode(resource);
        }
    }

    _addResourcesRecursivelyForFrame(frame)
    {
        this._addResource(frame.mainResource);

        for (let resource of frame.resourceCollection)
            this._addResource(resource);

        for (let childFrame of frame.childFrameCollection)
            this._addResourcesRecursivelyForFrame(childFrame);

        if (WI.settings.resourceGroupingMode.value === WI.Resource.GroupingMode.Path) {
            for (let styleSheet of WI.cssManager.inspectorStyleSheetsForFrame(frame))
                this._addResource(styleSheet);
        }
    }

    _addStyleSheet(styleSheet)
    {
        console.assert(styleSheet instanceof WI.CSSStyleSheet);
        console.assert(!styleSheet.isInspectorStyleSheet());

        // We don't add style sheets without URLs here. Those style sheets can quickly clutter the
        // interface and are usually more transient. They will get added if/when they need to be
        // shown in a content view.
        if (styleSheet.anonymous)
            return;

        let parentTreeElement = null;

        if (isWebKitExtensionScheme(styleSheet.urlComponents.scheme)) {
            if (!this._extensionStyleSheetsFolderTreeElement)
                this._extensionStyleSheetsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extension Style Sheets"), new WI.CSSStyleSheetCollection);
            parentTreeElement = this._extensionStyleSheetsFolderTreeElement;
        } else {
            if (!this._extraStyleSheetsFolderTreeElement)
                this._extraStyleSheetsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extra Style Sheets"), new WI.CSSStyleSheetCollection);
            parentTreeElement = this._extraStyleSheetsFolderTreeElement;
        }

        if (!parentTreeElement.parent) {
            let index = insertionIndexForObjectInListSortedByFunction(parentTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
            this._resourcesTreeOutline.insertChild(parentTreeElement, index);
        }

        let treeElement = new WI.CSSStyleSheetTreeElement(styleSheet);

        let index = insertionIndexForObjectInListSortedByFunction(treeElement, parentTreeElement.children, this._boundCompareTreeElements);
        parentTreeElement.insertChild(treeElement, index);
    }

    _addScript(script)
    {
        console.assert(script instanceof WI.Script);

        // We don't add scripts without URLs here. Those scripts can quickly clutter the interface and
        // are usually more transient. They will get added if/when they need to be shown in a content view.
        if (script.anonymous)
            return;

        // Target main resource.
        if (WI.sharedApp.debuggableType !== WI.DebuggableType.JavaScript) {
            if (script.target !== WI.pageTarget) {
                if (script.isMainResource()) {
                    this._addWorkerTargetWithMainResource(script.target);
                    this._addBreakpointsForSourceCode(script);
                    this._addIssuesForSourceCode(script);
                }
                this._resourcesTreeOutline.disclosureButtons = true;
                return;
            }
        }

        // If the script URL matches a resource we can assume it is part of that resource and does not need added.
        if (script.resource || script.dynamicallyAddedScriptElement)
            return;

        let scriptTreeElement = new WI.ScriptTreeElement(script);

        if (!script.injected && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel()) {
            let index = insertionIndexForObjectInListSortedByFunction(scriptTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
            this._resourcesTreeOutline.insertChild(scriptTreeElement, index);
        } else {
            let parentFolderTreeElement = null;

            if (isWebKitExtensionScheme(script.urlComponents.scheme)) {
                if (!this._extensionScriptsFolderTreeElement) {
                    let collection = new WI.ScriptCollection;
                    this._extensionScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extension Scripts"), collection);
                }

                parentFolderTreeElement = this._extensionScriptsFolderTreeElement;
            } else {
                if (!this._extraScriptsFolderTreeElement) {
                    let collection = new WI.ScriptCollection;
                    this._extraScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extra Scripts"), collection);
                }

                parentFolderTreeElement = this._extraScriptsFolderTreeElement;
            }

            if (parentFolderTreeElement)
                parentFolderTreeElement.representedObject.add(script);

            if (!parentFolderTreeElement.parent) {
                let index = insertionIndexForObjectInListSortedByFunction(parentFolderTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
                this._resourcesTreeOutline.insertChild(parentFolderTreeElement, index);
            }

            parentFolderTreeElement.appendChild(scriptTreeElement);
        }

        this._addBreakpointsForSourceCode(script);
        this._addIssuesForSourceCode(script);
    }

    _addWorkerTargetWithMainResource(target)
    {
        console.assert(target.type === WI.TargetType.Worker || target.type === WI.TargetType.ServiceWorker);

        let targetTreeElement = new WI.WorkerTreeElement(target);
        this._workerTargetTreeElementMap.set(target, targetTreeElement);

        let index = insertionIndexForObjectInListSortedByFunction(targetTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
        this._resourcesTreeOutline.insertChild(targetTreeElement, index);
    }

    _addDebuggerTreeElementForSourceCode(sourceCode)
    {
        let treeElement = this._breakpointsTreeOutline.findTreeElement(sourceCode);
        if (!treeElement) {
            if (sourceCode instanceof WI.SourceMapResource)
                treeElement = new WI.SourceMapResourceTreeElement(sourceCode);
            else if (sourceCode instanceof WI.Resource)
                treeElement = new WI.ResourceTreeElement(sourceCode);
            else if (sourceCode instanceof WI.Script)
                treeElement = new WI.ScriptTreeElement(sourceCode);
        }

        if (!treeElement) {
            console.error("Unknown sourceCode instance", sourceCode);
            return null;
        }

        if (!treeElement.parent) {
            treeElement.hasChildren = false;
            treeElement.expand();

            this._insertDebuggerTreeElement(treeElement, this._breakpointsTreeOutline);
        }

        return treeElement;
    }

    _insertDebuggerTreeElement(treeElement, parentTreeElement)
    {
        let comparator = (a, b) => {
            const rankFunctions = [
                (treeElement) => treeElement.representedObject === WI.debuggerManager.allExceptionsBreakpoint,
                (treeElement) => treeElement.representedObject === WI.debuggerManager.uncaughtExceptionsBreakpoint,
                (treeElement) => treeElement.representedObject === WI.debuggerManager.assertionFailuresBreakpoint,
                (treeElement) => treeElement instanceof WI.BreakpointTreeElement || treeElement instanceof WI.ResourceTreeElement || treeElement instanceof WI.ScriptTreeElement,
                (treeElement) => treeElement.representedObject === WI.debuggerManager.allMicrotasksBreakpoint,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allAnimationFramesBreakpoint,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allTimeoutsBreakpoint,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allIntervalsBreakpoint,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allListenersBreakpoint,
                (treeElement) => treeElement instanceof WI.EventBreakpointTreeElement,
                (treeElement) => treeElement instanceof WI.DOMNodeTreeElement,
                (treeElement) => treeElement.representedObject === SourcesNavigationSidebarPanel.__windowEventTargetRepresentedObject,
                (treeElement) => treeElement instanceof WI.DOMBreakpointTreeElement,
                (treeElement) => treeElement.representedObject === WI.domDebuggerManager.allRequestsBreakpoint,
                (treeElement) => treeElement instanceof WI.URLBreakpointTreeElement,
            ];

            let aRank = rankFunctions.findIndex((rankFunction) => rankFunction(a));
            let bRank = rankFunctions.findIndex((rankFunction) => rankFunction(b));
            if (aRank >= 0 && bRank >= 0) {
                if (aRank < bRank)
                    return -1;
                if (bRank < aRank)
                    return 1;
            }

            if (a instanceof WI.BreakpointTreeElement && b instanceof WI.BreakpointTreeElement)
                return this._compareBreakpointTreeElements(a, b);

            return a.mainTitle.extendedLocaleCompare(b.mainTitle) || a.subtitle.extendedLocaleCompare(b.subtitle);
        };

        parentTreeElement.insertChild(treeElement, insertionIndexForObjectInListSortedByFunction(treeElement, parentTreeElement.children, comparator));
    }

    _compareBreakpointTreeElements(a, b)
    {
        if (!a.representedObject || !b.representedObject)
            return 0;

        let aLocation = a.representedObject.sourceCodeLocation;
        let bLocation = b.representedObject.sourceCodeLocation;
        if (!aLocation || !bLocation)
            return 0;

        return aLocation.displayLineNumber - bLocation.displayLineNumber || aLocation.displayColumnNumber - bLocation.displayColumnNumber;
    }

    _addBreakpoint(breakpoint)
    {
        if (this._breakpointsTreeOutline.findTreeElement(breakpoint))
            return null;

        let constructor = WI.BreakpointTreeElement;
        let options = {};
        let parentTreeElement = this._breakpointsTreeOutline;

        let getDOMNodeTreeElement = (domNode) => {
            console.assert(domNode, "Missing DOMNode for identifier", breakpoint.domNodeIdentifier);
            if (!domNode)
                return null;

            let domNodeTreeElement = this._breakpointsTreeOutline.findTreeElement(domNode);
            if (!domNodeTreeElement) {
                domNodeTreeElement = new WI.DOMNodeTreeElement(domNode);
                this._insertDebuggerTreeElement(domNodeTreeElement, this._breakpointsTreeOutline);
            }
            return domNodeTreeElement;
        };

        if (breakpoint === WI.debuggerManager.allExceptionsBreakpoint) {
            options.className = "breakpoint-exception-icon";
            options.title = WI.repeatedUIString.allExceptions();
        } else if (breakpoint === WI.debuggerManager.uncaughtExceptionsBreakpoint) {
            options.className = "breakpoint-exception-icon";
            options.title = WI.repeatedUIString.uncaughtExceptions();
        } else if (breakpoint === WI.debuggerManager.assertionFailuresBreakpoint) {
            options.className = "breakpoint-assertion-icon";
            options.title = WI.repeatedUIString.assertionFailures();
        } else if (breakpoint === WI.debuggerManager.allMicrotasksBreakpoint) {
            options.className = "breakpoint-microtask-icon";
            options.title = WI.UIString("All Microtasks");
        } else if (breakpoint instanceof WI.DOMBreakpoint) {
            if (!breakpoint.domNodeIdentifier)
                return null;

            constructor = WI.DOMBreakpointTreeElement;

            let domNode = WI.domManager.nodeForId(breakpoint.domNodeIdentifier);
            parentTreeElement = getDOMNodeTreeElement(domNode);
        } else if (breakpoint instanceof WI.EventBreakpoint) {
            constructor = WI.EventBreakpointTreeElement;

            if (breakpoint === WI.domDebuggerManager.allAnimationFramesBreakpoint)
                options.title = WI.UIString("All Animation Frames");
            else if (breakpoint === WI.domDebuggerManager.allIntervalsBreakpoint)
                options.title = WI.UIString("All Intervals");
            else if (breakpoint === WI.domDebuggerManager.allListenersBreakpoint)
                options.title = WI.UIString("All Events");
            else if (breakpoint === WI.domDebuggerManager.allTimeoutsBreakpoint)
                options.title = WI.UIString("All Timeouts");
            else if (breakpoint.eventListener) {
                let eventTargetTreeElement = null;
                if (breakpoint.eventListener.onWindow) {
                    if (!SourcesNavigationSidebarPanel.__windowEventTargetRepresentedObject)
                        SourcesNavigationSidebarPanel.__windowEventTargetRepresentedObject = {__window: true};

                    eventTargetTreeElement = this._breakpointsTreeOutline.findTreeElement(SourcesNavigationSidebarPanel.__windowEventTargetRepresentedObject);
                    if (!eventTargetTreeElement) {
                        const subtitle = null;
                        eventTargetTreeElement = new WI.GeneralTreeElement(["event-target-window"], WI.unlocalizedString("window"), subtitle, SourcesNavigationSidebarPanel.__windowEventTargetRepresentedObject);
                        this._insertDebuggerTreeElement(eventTargetTreeElement, this._breakpointsTreeOutline);
                    }
                } else if (breakpoint.eventListener.node)
                    eventTargetTreeElement = getDOMNodeTreeElement(breakpoint.eventListener.node);
                if (eventTargetTreeElement)
                    parentTreeElement = eventTargetTreeElement;
            }
        } else if (breakpoint instanceof WI.URLBreakpoint) {
            constructor = WI.URLBreakpointTreeElement;

            if (breakpoint === WI.domDebuggerManager.allRequestsBreakpoint)
                options.title = WI.repeatedUIString.allRequests();
        } else {
            let sourceCode = breakpoint.sourceCodeLocation && breakpoint.sourceCodeLocation.displaySourceCode;
            if (!sourceCode)
                return null;

            parentTreeElement = this._addDebuggerTreeElementForSourceCode(sourceCode);

            // Mark disabled breakpoints as resolved if there is source code loaded with that URL.
            // This gives the illusion the breakpoint was resolved, but since we don't send disabled
            // breakpoints to the backend we don't know for sure. If the user enables the breakpoint
            // it will be resolved properly.
            if (breakpoint.disabled)
                breakpoint.resolved = true;
        }

        let breakpointTreeElement = new constructor(breakpoint, options);
        this._insertDebuggerTreeElement(breakpointTreeElement, parentTreeElement);
        if (parentTreeElement.children.length === 1)
            parentTreeElement.expand();
        return breakpointTreeElement;
    }

    _removeBreakpoint(breakpoint)
    {
        if (this._pauseReasonTreeOutline) {
            let pauseReasonBreakpointTreeElement = this._pauseReasonTreeOutline.findTreeElement(breakpoint);
            if (pauseReasonBreakpointTreeElement)
                pauseReasonBreakpointTreeElement.status = null;
        }

        let breakpointTreeElement = this._breakpointsTreeOutline.findTreeElement(breakpoint);
        if (!breakpointTreeElement)
            return;

        this._removeDebuggerTreeElement(breakpointTreeElement);
    }

    _removeAllBreakpoints(breakpoints)
    {
        for (let breakpoint of breakpoints) {
            if (WI.debuggerManager.isBreakpointRemovable(breakpoint))
                WI.debuggerManager.removeBreakpoint(breakpoint);
        }
    }

    _toggleAllBreakpoints(breakpoints, disabled)
    {
        for (let breakpoint of breakpoints)
            breakpoint.disabled = disabled;
    }

    _breakpointsBeneathTreeElement(treeElement)
    {
        console.assert(treeElement instanceof WI.ResourceTreeElement || treeElement instanceof WI.ScriptTreeElement);
        if (!(treeElement instanceof WI.ResourceTreeElement) && !(treeElement instanceof WI.ScriptTreeElement))
            return [];

        let breakpoints = [];
        for (let child of treeElement.children) {
            console.assert(child instanceof WI.BreakpointTreeElement);
            let breakpoint = child.breakpoint;
            console.assert(breakpoint);
            if (breakpoint)
                breakpoints.push(breakpoint);
        }
        return breakpoints;
    }

    _addIssue(issueMessage, sourceCode)
    {
        let issueTreeElement = this._resourcesTreeOutline.findTreeElement(issueMessage);
        if (!issueTreeElement) {
            console.assert(sourceCode || (issueMessage.sourceCodeLocation && issueMessage.sourceCodeLocation.sourceCode));
            let parentTreeElement = this._resourcesTreeOutline.findTreeElement(sourceCode || issueMessage.sourceCodeLocation.sourceCode);
            if (!parentTreeElement)
                return null;

            issueTreeElement = new WI.IssueTreeElement(issueMessage);

            parentTreeElement.insertChild(issueTreeElement, insertionIndexForObjectInListSortedByFunction(issueTreeElement, parentTreeElement.children, this._compareBreakpointTreeElements));
            if (parentTreeElement.children.length === 1)
                parentTreeElement.expand();
        }
        return issueTreeElement;
    }

    _removeDebuggerTreeElement(debuggerTreeElement)
    {
        // If this is a BreakpointTreeElement being deleted because of a cause
        // outside of the TreeOutline then deselect if it is selected to avoid
        // TreeOutline selection changes causing unexpected ContentView changes.
        if (!debuggerTreeElement.__deletedViaDeleteKeyboardShortcut)
            debuggerTreeElement.deselect();

        let parentTreeElement = debuggerTreeElement.parent;
        parentTreeElement.removeChild(debuggerTreeElement);

        if (parentTreeElement.children.length || parentTreeElement === this._breakpointsTreeOutline)
            return;

        parentTreeElement.treeOutline.removeChild(parentTreeElement);
    }

    _addBreakpointsForSourceCode(sourceCode)
    {
        for (let breakpoint of WI.debuggerManager.breakpointsForSourceCode(sourceCode))
            this._addBreakpoint(breakpoint);
    }

    _addIssuesForSourceCode(sourceCode)
    {
        for (let issue of WI.consoleManager.issuesForSourceCode(sourceCode))
            this._addIssue(issue, sourceCode);
    }

    _addLocalOverride(localOverride)
    {
        console.assert(WI.NetworkManager.supportsBootstrapScript() || WI.NetworkManager.supportsLocalResourceOverrides());

        if (this._localOverridesTreeOutline.findTreeElement(localOverride))
            return;

        let parentTreeElement = this._localOverridesTreeOutline;

        let localOverrideTreeElement = null;
        if (localOverride === WI.networkManager.bootstrapScript)
            localOverrideTreeElement = new WI.BootstrapScriptTreeElement(localOverride);
        else if (localOverride instanceof WI.LocalResourceOverride)
            localOverrideTreeElement = new WI.LocalResourceOverrideTreeElement(localOverride.localResource, localOverride);
        console.assert(localOverrideTreeElement);

        let index = insertionIndexForObjectInListSortedByFunction(localOverrideTreeElement, parentTreeElement.children, this._boundCompareTreeElements);
        parentTreeElement.insertChild(localOverrideTreeElement, index);

        this._localOverridesRow.hideEmptyMessage();
        this._localOverridesRow.element.appendChild(this._localOverridesTreeOutline.element);
        this._localOverridesContainer.hidden = false;
    }

    _removeResourceOverride(localOverride)
    {
        console.assert(WI.NetworkManager.supportsBootstrapScript() || WI.NetworkManager.supportsLocalResourceOverrides());

        let resourceTreeElement = this._localOverridesTreeOutline.findTreeElement(localOverride);
        if (!resourceTreeElement)
            return;

        let wasSelected = resourceTreeElement.selected;

        let parentTreeElement = this._localOverridesTreeOutline;
        parentTreeElement.removeChild(resourceTreeElement);

        if (!parentTreeElement.children.length) {
            this._localOverridesContainer.hidden = true;

            if (wasSelected && WI.networkManager.mainFrame && WI.networkManager.mainFrame.mainResource)
                WI.showRepresentedObject(WI.networkManager.mainFrame.mainResource);
        }
    }

    _updateTemporarilyDisabledBreakpointsButtons()
    {
        let breakpointsDisabledTemporarily = WI.debuggerManager.breakpointsDisabledTemporarily;
        this._debuggerBreakpointsButtonItem.enabled = !breakpointsDisabledTemporarily;
        this._debuggerPauseResumeButtonItem.enabled = !breakpointsDisabledTemporarily;
    }

    _updateBreakpointsDisabledBanner()
    {
        if (!WI.debuggerManager.breakpointsEnabled && !this._timelineRecordingWarningElement && !this._auditTestWarningElement) {
            if (!this._breakpointsDisabledWarningElement) {
                let enableBreakpointsButton = document.createElement("button");
                enableBreakpointsButton.textContent = WI.UIString("Enable Breakpoints");
                enableBreakpointsButton.addEventListener("click", () => {
                    WI.debuggerToggleBreakpoints();
                });

                this._breakpointsDisabledWarningElement = document.createElement("div");
                this._breakpointsDisabledWarningElement.classList.add("warning-banner");
                this._breakpointsDisabledWarningElement.append(WI.UIString("Breakpoints disabled"), document.createElement("br"), enableBreakpointsButton);
            }

            this.contentView.element.insertBefore(this._breakpointsDisabledWarningElement, this.contentView.element.firstChild);
        } else if (this._breakpointsDisabledWarningElement) {
            this._breakpointsDisabledWarningElement.remove();
            this._breakpointsDisabledWarningElement = null;
        }
    }

    _updatePauseReason()
    {
        this._pauseReasonTreeOutline = null;

        this._updatePauseReasonGotoArrow();

        let target = WI.debuggerManager.activeCallFrame.target;
        let targetData = WI.debuggerManager.dataForTarget(target);
        return this._updatePauseReasonSection(target, targetData.pauseReason, targetData.pauseData);
    }

    _updatePauseReasonGotoArrow()
    {
        this._pauseReasonLinkContainerElement.removeChildren();

        let activeCallFrame = WI.debuggerManager.activeCallFrame;
        if (!activeCallFrame)
            return;

        let sourceCodeLocation = activeCallFrame.sourceCodeLocation;
        if (!sourceCodeLocation)
            return;

        const options = {
            useGoToArrowButton: true,
        };
        let linkElement = WI.createSourceCodeLocationLink(sourceCodeLocation, options);
        this._pauseReasonLinkContainerElement.appendChild(linkElement);
    }

    _updatePauseReasonSection(target, pauseReason, pauseData)
    {
        switch (pauseReason) {
        case WI.DebuggerManager.PauseReason.AnimationFrame: {
            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(WI.domDebuggerManager.allAnimationFramesBreakpoint, {
                className: "breakpoint-paused-icon",
                title: WI.UIString("requestAnimationFrame Fired"),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            let eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            this._pauseReasonGroup.rows = [eventBreakpointRow];
            return true;
        }

        case WI.DebuggerManager.PauseReason.Assertion:
            // FIXME: We should include the assertion condition string.
            console.assert(pauseData, "Expected data with an assertion, but found none.");
            if (pauseData && pauseData.message)
                this._pauseReasonTextRow.text = WI.UIString("Assertion with message: %s").format(pauseData.message);
            else
                this._pauseReasonTextRow.text = WI.UIString("Assertion Failed");
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;

        case WI.DebuggerManager.PauseReason.BlackboxedScript: {
            console.assert(pauseData);
            if (pauseData)
                this._updatePauseReasonSection(target, WI.DebuggerManager.pauseReasonFromPayload(pauseData.originalReason), pauseData.originalData);

            // Don't use `_pauseReasonTextRow` as it may have already been set.
            let blackboxReasonTextRow = new WI.DetailsSectionTextRow(WI.UIString("Deferred pause from blackboxed script"));
            blackboxReasonTextRow.__blackboxReason = true;

            let existingRows = this._pauseReasonGroup.rows.filter((row) => !row.__blackboxReason);
            this._pauseReasonGroup.rows = [blackboxReasonTextRow, ...existingRows];
            return true;
        }

        case WI.DebuggerManager.PauseReason.Breakpoint: {
            console.assert(pauseData, "Expected breakpoint identifier, but found none.");
            if (!pauseData || !pauseData.breakpointId)
                break;

            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});
            this._pauseReasonTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._handleTreeSelectionDidChange, this);

            let breakpoint = WI.debuggerManager.breakpointForIdentifier(pauseData.breakpointId);
            let breakpointTreeElement = new WI.BreakpointTreeElement(breakpoint, {
                className: "breakpoint-paused-icon",
                title: WI.UIString("Triggered Breakpoint"),
            });
            let breakpointDetailsSection = new WI.DetailsSectionRow;
            this._pauseReasonTreeOutline.appendChild(breakpointTreeElement);
            breakpointDetailsSection.element.appendChild(this._pauseReasonTreeOutline.element);

            this._pauseReasonGroup.rows = [breakpointDetailsSection];
            return true;
        }

        case WI.DebuggerManager.PauseReason.CSPViolation:
            console.assert(pauseData, "Expected data with a CSP Violation, but found none.");
            if (!pauseData)
                break;

            // COMPATIBILITY (iOS 8): 'directive' was 'directiveText'.
            this._pauseReasonTextRow.text = WI.UIString("Content Security Policy violation of directive: %s").format(pauseData.directive || pauseData.directiveText);
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;

        case WI.DebuggerManager.PauseReason.DebuggerStatement:
            this._pauseReasonTextRow.text = WI.UIString("Debugger Statement");
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;

        case WI.DebuggerManager.PauseReason.DOM: {
            console.assert(WI.domDebuggerManager.supported);
            console.assert(pauseData, "Expected DOM breakpoint data, but found none.");
            if (!pauseData || !pauseData.nodeId)
                break;

            let domNode = WI.domManager.nodeForId(pauseData.nodeId);
            let domBreakpoints = WI.domDebuggerManager.domBreakpointsForNode(domNode);
            let domBreakpoint;
            for (let breakpoint of domBreakpoints) {
                if (breakpoint.type === pauseData.type) {
                    domBreakpoint = breakpoint;
                    break;
                }
            }

            console.assert(domBreakpoint, "Missing DOM breakpoint of type for node", pauseData.type, domNode);
            if (!domBreakpoint)
                break;

            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            let type = WI.DOMBreakpointTreeElement.displayNameForType(domBreakpoint.type);
            let domBreakpointTreeElement = new WI.DOMBreakpointTreeElement(domBreakpoint, {
                className: "breakpoint-paused-icon",
                title: type,
            });
            let domBreakpointRow = new WI.DetailsSectionRow;
            this._pauseReasonTreeOutline.appendChild(domBreakpointTreeElement);
            domBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            let ownerElementRow = new WI.DetailsSectionSimpleRow(WI.UIString("Element"), WI.linkifyNodeReference(domNode));
            this._pauseReasonGroup.rows = [domBreakpointRow, ownerElementRow];

            let updateTargetDescription = (nodeId) => {
                if (!nodeId)
                    return;

                let node = WI.domManager.nodeForId(nodeId);
                console.assert(node, "Missing node for id.", nodeId);
                if (!node)
                    return;

                let fragment = document.createDocumentFragment();

                let description = null;
                switch (domBreakpoint.type) {
                case WI.DOMBreakpoint.Type.SubtreeModified:
                    description = pauseData.insertion ? WI.UIString("Child added to ") : WI.UIString("Removed descendant ");
                    break;
                case WI.DOMBreakpoint.Type.NodeRemoved:
                    description = WI.UIString("Removed ancestor ");
                    break;
                }
                console.assert(description);
                fragment.append(description, WI.linkifyNodeReference(node));

                let targetDescriptionRow = new WI.DetailsSectionSimpleRow(WI.UIString("Details"), fragment);
                targetDescriptionRow.element.classList.add("target-description");

                this._pauseReasonGroup.rows = this._pauseReasonGroup.rows.concat(targetDescriptionRow);
            };

            if (pauseData.targetNodeId) {
                console.assert(domBreakpoint.type === WI.DOMBreakpoint.Type.SubtreeModified || domBreakpoint.type === WI.DOMBreakpoint.Type.NodeRemoved);
                updateTargetDescription(pauseData.targetNodeId);
            } else if (pauseData.targetNode) { // COMPATIBILITY (iOS 13): `targetNode` was renamed to `targetNodeId` and was changed from a `Runtime.RemoteObject` to a `DOM.NodeId`.
                console.assert(domBreakpoint.type === WI.DOMBreakpoint.Type.SubtreeModified);
                let remoteObject = WI.RemoteObject.fromPayload(pauseData.targetNode, target);
                remoteObject.pushNodeToFrontend(updateTargetDescription);
            }

            return true;
        }

        case WI.DebuggerManager.PauseReason.Listener:
        case WI.DebuggerManager.PauseReason.EventListener: {
            console.assert(pauseData, "Expected data with an event listener, but found none.");
            if (!pauseData)
                break;

            let eventBreakpoint = null;
            if (pauseData.eventListenerId)
                eventBreakpoint = WI.domManager.breakpointForEventListenerId(pauseData.eventListenerId);
            if (!eventBreakpoint)
                eventBreakpoint = WI.domDebuggerManager.listenerBreakpointForEventName(pauseData.eventName);

            console.assert(eventBreakpoint, "Expected Event Listener breakpoint for event name.", pauseData.eventName);
            if (!eventBreakpoint)
                break;

            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(eventBreakpoint, {
                className: "breakpoint-paused-icon",
                title: WI.UIString("\u201C%s\u201D Event Fired").format(pauseData.eventName),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            let eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            let rows = [eventBreakpointRow];

            let eventListener = eventBreakpoint.eventListener;
            if (eventListener) {
                console.assert(eventListener.eventListenerId === pauseData.eventListenerId);

                let value = null;
                if (eventListener.onWindow)
                    value = WI.unlocalizedString("window");
                else if (eventListener.node)
                    value = WI.linkifyNodeReference(eventListener.node);
                if (value)
                    rows.push(new WI.DetailsSectionSimpleRow(WI.UIString("Target"), value));
            }

            this._pauseReasonGroup.rows = rows;
            return true;
        }

        case WI.DebuggerManager.PauseReason.Exception: {
            console.assert(pauseData, "Expected data with an exception, but found none.");
            if (!pauseData)
                break;

            // FIXME: We should improve the appearance of thrown objects. This works well for exception strings.
            let data = WI.RemoteObject.fromPayload(pauseData, target);
            this._pauseReasonTextRow.text = WI.UIString("Exception with thrown value: %s").format(data.description);
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;
        }

        case WI.DebuggerManager.PauseReason.Interval: {
            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(WI.domDebuggerManager.allIntervalsBreakpoint, {
                className: "breakpoint-paused-icon",
                title: WI.UIString("setInterval Fired"),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            let eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            this._pauseReasonGroup.rows = [eventBreakpointRow];
            return true;
        }

        case WI.DebuggerManager.PauseReason.Microtask:
            this._pauseReasonTextRow.text = WI.UIString("Microtask Fired");
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;

        case WI.DebuggerManager.PauseReason.PauseOnNextStatement:
            this._pauseReasonTextRow.text = WI.UIString("Immediate Pause Requested");
            this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            return true;

        case WI.DebuggerManager.PauseReason.Timer: {
            console.assert(pauseData, "Expected data with a timer, but found none.");
            if (!pauseData)
                break;

            let eventBreakpoint = null;
            switch (pauseData.eventName) {
            case "setTimeout":
                eventBreakpoint = WI.domDebuggerManager.allTimeoutsBreakpoint;
                break;

            case "setInterval":
                eventBreakpoint = WI.domDebuggerManager.allIntervalsBreakpoint;
                break;
            }
            console.assert(eventBreakpoint, "Expected Timer breakpoint for event name.", pauseData.eventName);
            if (!eventBreakpoint)
                break;

            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(eventBreakpoint, {
                className: "breakpoint-paused-icon",
                title: WI.UIString("%s Fired").format(pauseData.eventName),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            let eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            this._pauseReasonGroup.rows = [eventBreakpointRow];
            return true;
        }

        case WI.DebuggerManager.PauseReason.Timeout: {
            this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

            let eventBreakpointTreeElement = new WI.EventBreakpointTreeElement(WI.domDebuggerManager.allTimeoutsBreakpoint, {
                className: "breakpoint-paused-icon",
                title: WI.UIString("setTimeout Fired"),
            });
            this._pauseReasonTreeOutline.appendChild(eventBreakpointTreeElement);

            let eventBreakpointRow = new WI.DetailsSectionRow;
            eventBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

            this._pauseReasonGroup.rows = [eventBreakpointRow];
            return true;
        }

        case WI.DebuggerManager.PauseReason.Fetch:
        case WI.DebuggerManager.PauseReason.XHR: {
            console.assert(WI.domDebuggerManager.supported);
            console.assert(pauseData, "Expected URL breakpoint data, but found none.");
            if (!pauseData)
                break;

            if (pauseData.breakpointURL) {
                let urlBreakpoint = WI.domDebuggerManager.urlBreakpointForURL(pauseData.breakpointURL);
                console.assert(urlBreakpoint, "Expected URL breakpoint for URL.", pauseData.breakpointURL);

                this._pauseReasonTreeOutline = this.createContentTreeOutline({suppressFiltering: true});

                let urlBreakpointTreeElement = new WI.URLBreakpointTreeElement(urlBreakpoint, {
                    className: "breakpoint-paused-icon",
                    title: WI.UIString("Triggered URL Breakpoint"),
                });
                let urlBreakpointRow = new WI.DetailsSectionRow;
                this._pauseReasonTreeOutline.appendChild(urlBreakpointTreeElement);
                urlBreakpointRow.element.appendChild(this._pauseReasonTreeOutline.element);

                this._pauseReasonTextRow.text = pauseData.url;
                this._pauseReasonGroup.rows = [urlBreakpointRow, this._pauseReasonTextRow];
            } else {
                console.assert(pauseData.breakpointURL === "", "Should be the All Requests breakpoint which has an empty URL");
                this._pauseReasonTextRow.text = WI.UIString("Requesting: %s").format(pauseData.url);
                this._pauseReasonGroup.rows = [this._pauseReasonTextRow];
            }
            this._pauseReasonTextRow.element.title = pauseData.url;
            return true;
        }

        case WI.DebuggerManager.PauseReason.Other:
            console.error("Paused for unknown reason. We should always have a reason.");
            break;
        }

        return false;
    }

    _handleResourceGroupingModeScopeBarSelectionChanged(event)
    {
        console.assert(this._resourceGroupingModeScopeBar.selectedItems.length === 1);
        let selectedScopeBarItem = this._resourceGroupingModeScopeBar.selectedItems[0];
        WI.settings.resourceGroupingMode.value = selectedScopeBarItem[SourcesNavigationSidebarPanel.ResourceGroupingModeSymbol] || WI.Resource.GroupingMode.Type;
    }

    _handleResourceTypeScopeBarSelectionChanged(event)
    {
        this.updateFilter();
    }

    _handleTreeSelectionDidChange(event)
    {
        if (!this.selected)
            return;

        let treeElement = event.target.selectedTreeElement;
        if (!treeElement)
            return;

        if (treeElement instanceof WI.DOMNodeTreeElement
            || treeElement instanceof WI.DOMBreakpointTreeElement
            || treeElement instanceof WI.EventBreakpointTreeElement
            || treeElement instanceof WI.URLBreakpointTreeElement)
            return;

        if (treeElement.representedObject === SourcesNavigationSidebarPanel.__windowEventTargetRepresentedObject)
            return;

        if (treeElement instanceof WI.LocalResourceOverrideTreeElement) {
            WI.showRepresentedObject(treeElement.representedObject.localResource);
            return;
        }

        // Silently select the corresponding tree element in the resources tree outline to update
        // the hierarchical path components to show the right ancestor(s).
        let selectTreeElementInResourcesTreeOutline = (sourceCode) => {
            let resourceTreeElement = this._resourcesTreeOutline.findTreeElement(sourceCode);
            if (!resourceTreeElement)
                return;

            const omitFocus = true;
            const selectedByUser = false;
            const suppressNotification = true;
            resourceTreeElement.select(omitFocus, selectedByUser, suppressNotification);
        };

        if (treeElement instanceof WI.FolderTreeElement
            || treeElement instanceof WI.OriginTreeElement
            || treeElement instanceof WI.ResourceTreeElement
            || treeElement instanceof WI.ScriptTreeElement
            || treeElement instanceof WI.CSSStyleSheetTreeElement) {
            let representedObject = treeElement.representedObject;

            if (representedObject instanceof WI.Script && representedObject.resource)
                representedObject = representedObject.resource;

            if (treeElement.treeOutline !== this._resourcesTreeOutline)
                selectTreeElementInResourcesTreeOutline(representedObject);

            if (representedObject instanceof WI.Collection || representedObject instanceof WI.SourceCode || representedObject instanceof WI.Frame)
                WI.showRepresentedObject(representedObject);
            return;
        }

        if (treeElement instanceof WI.CallFrameTreeElement) {
            let callFrame = treeElement.callFrame;
            if (callFrame.id)
                WI.debuggerManager.activeCallFrame = callFrame;
            if (callFrame.sourceCodeLocation)
                WI.showSourceCodeLocation(callFrame.sourceCodeLocation);
            return;
        }

        if (treeElement instanceof WI.IssueTreeElement) {
            WI.showSourceCodeLocation(treeElement.issueMessage.sourceCodeLocation);
            return;
        }

        if (treeElement instanceof WI.BreakpointTreeElement) {
            let breakpoint = treeElement.breakpoint;
            if (WI.debuggerManager.isBreakpointSpecial(breakpoint))
                return;

            let sourceCode = breakpoint.sourceCodeLocation.displaySourceCode;
            if (sourceCode instanceof WI.Script && sourceCode.resource)
                sourceCode = sourceCode.resource;
            selectTreeElementInResourcesTreeOutline(sourceCode);

            WI.showSourceCodeLocation(breakpoint.sourceCodeLocation);
            return;
        }

        console.error("Unknown tree element", treeElement);
    }

    _handleBreakpointElementAddedOrRemoved(event)
    {
        let treeElement = event.data.element;

        let setting = null;
        switch (treeElement.representedObject) {
        case WI.debuggerManager.assertionFailuresBreakpoint:
            setting = WI.settings.showAssertionFailuresBreakpoint;
            break;

        case WI.debuggerManager.allMicrotasksBreakpoint:
            setting = WI.settings.showAllMicrotasksBreakpoint;
            break;

        case WI.domDebuggerManager.allAnimationFramesBreakpoint:
            setting = WI.settings.showAllAnimationFramesBreakpoint;
            break;

        case WI.domDebuggerManager.allIntervalsBreakpoint:
            setting = WI.settings.showAllIntervalsBreakpoint;
            break;

        case WI.domDebuggerManager.allListenersBreakpoint:
            setting = WI.settings.showAllListenersBreakpoint;
            break;

        case WI.domDebuggerManager.allRequestsBreakpoint:
            setting = WI.settings.showAllRequestsBreakpoint;
            break;

        case WI.domDebuggerManager.allTimeoutsBreakpoint:
            setting = WI.settings.showAllTimeoutsBreakpoint;
            break;
        }

        if (setting)
            setting.value = !!treeElement.parent;

        if (event.type === WI.TreeOutline.Event.ElementRemoved) {
            let selectedTreeElement = this._breakpointsTreeOutline.selectedTreeElement;
            if (selectedTreeElement) {
                if (selectedTreeElement.representedObject === WI.debuggerManager.assertionFailuresBreakpoint || !WI.debuggerManager.isBreakpointRemovable(selectedTreeElement.representedObject)) {
                    const skipUnrevealed = true;
                    const dontPopulate = true;
                    let treeElementToSelect = selectedTreeElement.traverseNextTreeElement(skipUnrevealed, dontPopulate);
                    if (treeElementToSelect) {
                        const omitFocus = true;
                        const selectedByUser = true;
                        treeElementToSelect.select(omitFocus, selectedByUser);
                    }
                }
            }
        }
    }

    _populateCreateBreakpointContextMenu(contextMenu)
    {
        // COMPATIBILITY (iOS 10): Debugger.setPauseOnAssertions did not exist yet.
        if (InspectorBackend.hasCommand("Debugger.setPauseOnAssertions")) {
            let assertionFailuresBreakpointShown = WI.settings.showAssertionFailuresBreakpoint.value;

            contextMenu.appendCheckboxItem(WI.repeatedUIString.assertionFailures(), () => {
                if (assertionFailuresBreakpointShown)
                    WI.debuggerManager.removeBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);
                else {
                    WI.debuggerManager.assertionFailuresBreakpoint.disabled = false;
                    WI.debuggerManager.addBreakpoint(WI.debuggerManager.assertionFailuresBreakpoint);
                }
            }, assertionFailuresBreakpointShown);
        }

        contextMenu.appendSeparator();

        // COMPATIBILITY (iOS 13): Debugger.setPauseOnMicrotasks did not exist yet.
        if (InspectorBackend.hasCommand("Debugger.setPauseOnMicrotasks")) {
            let allMicrotasksBreakpointShown = WI.settings.showAllMicrotasksBreakpoint.value;

            contextMenu.appendCheckboxItem(WI.UIString("All Microtasks"), () => {
                if (allMicrotasksBreakpointShown)
                    WI.debuggerManager.removeBreakpoint(WI.debuggerManager.allMicrotasksBreakpoint);
                else {
                    WI.debuggerManager.allMicrotasksBreakpoint.disabled = false;
                    WI.debuggerManager.addBreakpoint(WI.debuggerManager.allMicrotasksBreakpoint);
                }
            }, allMicrotasksBreakpointShown);
        }

        if (WI.DOMDebuggerManager.supportsEventBreakpoints() || WI.DOMDebuggerManager.supportsEventListenerBreakpoints()) {
            function addToggleForSpecialEventBreakpoint(breakpoint, label, checked) {
                contextMenu.appendCheckboxItem(label, () => {
                    if (checked)
                        WI.domDebuggerManager.removeEventBreakpoint(breakpoint);
                    else {
                        breakpoint.disabled = false;
                        WI.domDebuggerManager.addEventBreakpoint(breakpoint);
                    }
                }, checked);
            }

            addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allAnimationFramesBreakpoint, WI.UIString("All Animation Frames"), WI.settings.showAllAnimationFramesBreakpoint.value);
            addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allTimeoutsBreakpoint, WI.UIString("All Timeouts"), WI.settings.showAllTimeoutsBreakpoint.value);
            addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allIntervalsBreakpoint, WI.UIString("All Intervals"), WI.settings.showAllIntervalsBreakpoint.value);

            contextMenu.appendSeparator();

            if (WI.DOMDebuggerManager.supportsAllListenersBreakpoint())
                addToggleForSpecialEventBreakpoint(WI.domDebuggerManager.allListenersBreakpoint, WI.UIString("All Events"), WI.settings.showAllListenersBreakpoint.value);

            contextMenu.appendItem(WI.UIString("Event Breakpoint\u2026"), () => {
                let popover = new WI.EventBreakpointPopover(this);
                popover.show(this._createBreakpointButton.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
            });
        }

        if (WI.DOMDebuggerManager.supportsURLBreakpoints() || WI.DOMDebuggerManager.supportsXHRBreakpoints()) {
            contextMenu.appendSeparator();

            let allRequestsBreakpointShown = WI.settings.showAllRequestsBreakpoint.value;
            contextMenu.appendCheckboxItem(WI.repeatedUIString.allRequests(), () => {
                if (allRequestsBreakpointShown)
                    WI.domDebuggerManager.removeURLBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);
                else {
                    WI.domDebuggerManager.allRequestsBreakpoint.disabled = false;
                    WI.domDebuggerManager.addURLBreakpoint(WI.domDebuggerManager.allRequestsBreakpoint);
                }
            }, allRequestsBreakpointShown);

            contextMenu.appendItem(WI.DOMDebuggerManager.supportsURLBreakpoints() ? WI.UIString("URL Breakpoint\u2026") : WI.UIString("XHR Breakpoint\u2026"), () => {
                let popover = new WI.URLBreakpointPopover(this);
                popover.show(this._createBreakpointButton.element, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
            });
        }
    }

    _populateCreateResourceContextMenu(contextMenu)
    {
        if (WI.NetworkManager.supportsLocalResourceOverrides()) {
            contextMenu.appendItem(WI.UIString("Local Override\u2026"), () => {
                if (!this._localOverridesTreeOutline.children.length)
                    this._localOverridesRow.showEmptyMessage();

                this._localOverridesContainer.hidden = false;

                this._localOverridesSection.titleElement.scrollIntoViewIfNeeded(false);
                requestAnimationFrame(() => {
                    let popover = new WI.LocalResourceOverridePopover(this);
                    popover.show(null, this._localOverridesSection.titleElement, [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X]);
                });
            });
        }

        if (WI.NetworkManager.supportsBootstrapScript()) {
            contextMenu.appendItem(WI.UIString("Inspector Bootstrap Script"), async () => {
                await WI.networkManager.createBootstrapScript();
                WI.networkManager.bootstrapScriptEnabled = true;
                WI.showRepresentedObject(WI.networkManager.bootstrapScript);
            });
        }

        if (InspectorBackend.hasDomain("CSS")) {
            let addInspectorStyleSheetItem = (menu, frame) => {
                menu.appendItem(WI.UIString("Inspector Style Sheet"), () => {
                    if (WI.settings.resourceGroupingMode.value === WI.Resource.GroupingMode.Path) {
                        // Force the parent to populate.
                        let parentFrameTreeElement = this._resourcesTreeOutline.findTreeElement(frame.mainResource);
                        parentFrameTreeElement.reveal();
                        parentFrameTreeElement.expand();
                    }

                    WI.cssManager.preferredInspectorStyleSheetForFrame(frame, (styleSheet) => {
                        WI.showRepresentedObject(styleSheet);
                    });
                });
            };

            addInspectorStyleSheetItem(contextMenu, WI.networkManager.mainFrame);

            let frames = WI.networkManager.frames;
            if (frames.length > 2) {
                let framesSubMenu = contextMenu.appendSubMenuItem(WI.UIString("Frames"));

                for (let frame of frames) {
                    if (frame === WI.networkManager.mainFrame || frame.mainResource.type !== WI.Resource.Type.Document)
                        continue;

                    let frameSubMenuItem = framesSubMenu.appendSubMenuItem(frame.name ? WI.UIString("%s (%s)").format(frame.name, frame.mainResource.displayName) : frame.mainResource.displayName);

                    addInspectorStyleSheetItem(frameSubMenuItem, frame);
                }
            }
        }
    }

    _handleResourceGroupingModeChanged(event)
    {
        this._workerTargetTreeElementMap.clear();
        this._mainFrameTreeElement = null;
        this._extensionScriptsFolderTreeElement = null;
        this._extensionStyleSheetsFolderTreeElement = null;
        this._extraScriptsFolderTreeElement = null;
        this._extraStyleSheetsFolderTreeElement = null;
        this._anonymousScriptsFolderTreeElement = null;
        this._anonymousStyleSheetsFolderTreeElement = null;

        this._originTreeElementMap.clear();

        let resourceGroupingModeScopeBarItem = this._resourceGroupingModeScopeBarItems[WI.settings.resourceGroupingMode.value];
        console.assert(resourceGroupingModeScopeBarItem);
        if (resourceGroupingModeScopeBarItem)
            resourceGroupingModeScopeBarItem.selected = true;

        this._resourcesTreeOutline.removeChildren();

        let mainFrame = WI.networkManager.mainFrame;
        if (mainFrame) {
            this._updateMainFrameTreeElement(mainFrame);
            this._addResourcesRecursivelyForFrame(mainFrame);

            for (let frame of WI.networkManager.frames) {
                if (frame !== mainFrame)
                    this._addResourcesRecursivelyForFrame(frame);
            }
        }

        for (let script of WI.debuggerManager.knownNonResourceScripts) {
            this._addScript(script);

            if (script.sourceMaps.length && WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
                this._resourcesTreeOutline.disclosureButtons = true;
        }

        for (let styleSheet of WI.cssManager.styleSheets) {
            if (styleSheet.origin !== WI.CSSStyleSheet.Type.Author && !styleSheet.isInspectorStyleSheet())
                this._addStyleSheet(styleSheet);
        }
    }

    _handleFrameMainResourceDidChange(event)
    {
        let frame = event.target;
        if (frame.isMainFrame()) {
            this._updateMainFrameTreeElement(frame);
            this._addResourcesRecursivelyForFrame(frame);

            for (let domBreakpoint of WI.domDebuggerManager.domBreakpoints)
                this._removeBreakpoint(domBreakpoint);
        }

        if (!event.data.oldMainResource) {
            let resource = event.target.mainResource;
            this._addBreakpointsForSourceCode(resource);
            this._addIssuesForSourceCode(resource);
        }
    }

    _handleResourceAdded(event)
    {
        this._addResource(event.data.resource);
    }

    _handleFrameWasAdded(event)
    {
        let {frame} = event.data;

        if (frame.isMainFrame())
            this._updateMainFrameTreeElement(frame);

        this._addResourcesRecursivelyForFrame(frame);
    }

    _handleBootstrapScriptCreated(event)
    {
        this._addLocalOverride(event.data.bootstrapScript);
    }

    _handleBootstrapScriptDestroyed(event)
    {
        this._removeResourceOverride(event.data.bootstrapScript);
    }

    _handleLocalResourceOverrideAdded(event)
    {
        this._addLocalOverride(event.data.localResourceOverride);
    }

    _handleLocalResourceOverrideRemoved(event)
    {
        this._removeResourceOverride(event.data.localResourceOverride);
    }

    _handleDebuggerBreakpointAdded(event)
    {
        this._addBreakpoint(event.data.breakpoint);
    }

    _handleDebuggerBreakpointRemoved(event)
    {
        this._removeBreakpoint(event.data.breakpoint);
    }

    _handleDebuggerBreakpointsEnabledDidChange(event)
    {
        this._debuggerBreakpointsButtonItem.activated = WI.debuggerManager.breakpointsEnabled;

        this._updateBreakpointsDisabledBanner();
    }

    _handleDebuggerScriptAdded(event)
    {
        this._addScript(event.data.script);
    }

    _handleDebuggerScriptRemoved(event)
    {
        let script = event.data.script;
        let scriptTreeElement = this._resourcesTreeOutline.findTreeElement(script);
        if (!scriptTreeElement)
            return;

        let parentTreeElement = scriptTreeElement.parent;
        parentTreeElement.removeChild(scriptTreeElement);

        if (parentTreeElement instanceof WI.FolderTreeElement || parentTreeElement instanceof WI.OriginTreeElement) {
            parentTreeElement.representedObject.remove(script);

            if (!parentTreeElement.children.length)
                parentTreeElement.parent.removeChild(parentTreeElement);
        }
    }

    _handleDebuggerScriptsCleared(event)
    {
        const suppressOnDeselect = true;
        const suppressSelectSibling = true;

        for (let i = this._breakpointsTreeOutline.children.length - 1; i >= 0; --i) {
            let treeElement = this._breakpointsTreeOutline.children[i];
            if (!(treeElement instanceof WI.ScriptTreeElement))
                continue;

            this._breakpointsTreeOutline.removeChild(treeElement, suppressOnDeselect, suppressSelectSibling);
        }

        if (this._extensionScriptsFolderTreeElement) {
            if (this._extensionScriptsFolderTreeElement.parent)
                this._extensionScriptsFolderTreeElement.parent.removeChild(this._extensionScriptsFolderTreeElement, suppressOnDeselect, suppressSelectSibling);

            this._extensionScriptsFolderTreeElement.representedObject.clear();
            this._extensionScriptsFolderTreeElement = null;
        }

        if (this._extraScriptsFolderTreeElement) {
            if (this._extraScriptsFolderTreeElement.parent)
                this._extraScriptsFolderTreeElement.parent.removeChild(this._extraScriptsFolderTreeElement, suppressOnDeselect, suppressSelectSibling);

            this._extraScriptsFolderTreeElement.representedObject.clear();
            this._extraScriptsFolderTreeElement = null;
        }

        if (this._anonymousScriptsFolderTreeElement) {
            if (this._anonymousScriptsFolderTreeElement.parent)
                this._anonymousScriptsFolderTreeElement.parent.removeChild(this._anonymousScriptsFolderTreeElement, suppressOnDeselect, suppressSelectSibling);

            this._anonymousScriptsFolderTreeElement.representedObject.clear();
            this._anonymousScriptsFolderTreeElement = null;
        }

        if (this._workerTargetTreeElementMap.size) {
            for (let treeElement of this._workerTargetTreeElementMap.values())
                treeElement.parent.removeChild(treeElement, suppressOnDeselect, suppressSelectSibling);
            this._workerTargetTreeElementMap.clear();
        }

        this._addResourcesRecursivelyForFrame(WI.networkManager.mainFrame);
    }

    _handleDebuggerPaused(event)
    {
        this._callStackContainer.hidden = false;

        if (this._updatePauseReason())
            this._pauseReasonContainer.hidden = false;

        this._debuggerPauseResumeButtonItem.enabled = true;
        this._debuggerPauseResumeButtonItem.toggled = true;
        this._debuggerStepOverButtonItem.enabled = true;
        this._debuggerStepIntoButtonItem.enabled = true;
        this._debuggerStepOutButtonItem.enabled = true;

        this.element.classList.add("paused");
    }

    _handleDebuggerResumed(event)
    {
        this._callStackContainer.hidden = true;

        this._pauseReasonContainer.hidden = true;

        this._debuggerPauseResumeButtonItem.enabled = true;
        this._debuggerPauseResumeButtonItem.toggled = false;
        this._debuggerStepOverButtonItem.enabled = false;
        this._debuggerStepIntoButtonItem.enabled = false;
        this._debuggerStepOutButtonItem.enabled = false;

        this.element.classList.remove("paused");
    }

    _handleDebuggerCallFramesDidChange(event)
    {
        let {target} = event.data;
        let treeElement = this._findCallStackTargetTreeElement(target);
        console.assert(treeElement);
        if (treeElement)
            treeElement.refresh();

        let activeCallFrameTreeElement = this._callStackTreeOutline.findTreeElement(WI.debuggerManager.activeCallFrame);
        if (activeCallFrameTreeElement)
            activeCallFrameTreeElement.reveal();
    }

    _handleDebuggerActiveCallFrameDidChange(event)
    {
        if (this._activeCallFrameTreeElement) {
            this._activeCallFrameTreeElement.isActiveCallFrame = false;
            this._activeCallFrameTreeElement = null;
        }

        if (!WI.debuggerManager.activeCallFrame)
            return;

        this._activeCallFrameTreeElement = this._callStackTreeOutline.findTreeElement(WI.debuggerManager.activeCallFrame);
        if (this._activeCallFrameTreeElement)
            this._activeCallFrameTreeElement.isActiveCallFrame = true;
    }

    _handleDebuggerWaitingToPause(event)
    {
        this._debuggerPauseResumeButtonItem.enabled = false;
    }

    _handleDebuggerObjectDisplayLocationDidChange(event)
    {
        let debuggerObject = event.target;

        if (event.data.oldDisplaySourceCode === debuggerObject.sourceCodeLocation.displaySourceCode)
            return;

        // A known debugger object (breakpoint, issueMessage, etc.) moved between resources. Remove
        // the old tree element and create a new tree element with the updated file.

        let wasSelected = false;
        let oldDebuggerTreeElement = null;
        let newDebuggerTreeElement = null;
        if (debuggerObject instanceof WI.Breakpoint) {
            oldDebuggerTreeElement = this._breakpointsTreeOutline.findTreeElement(debuggerObject);
            if (oldDebuggerTreeElement)
                wasSelected = oldDebuggerTreeElement.selected;

            newDebuggerTreeElement = this._addBreakpoint(debuggerObject);
        } else if (debuggerObject instanceof WI.IssueMessage) {
            oldDebuggerTreeElement = this._resourcesTreeOutline.findTreeElement(debuggerObject);
            if (oldDebuggerTreeElement)
                wasSelected = oldDebuggerTreeElement.selected;

            newDebuggerTreeElement = this._addIssue(debuggerObject);
        }

        if (!newDebuggerTreeElement)
            return;

        if (oldDebuggerTreeElement)
            this._removeDebuggerTreeElement(oldDebuggerTreeElement);

        if (wasSelected)
            newDebuggerTreeElement.revealAndSelect(true, false, true);
    }

    _handleDOMBreakpointDOMNodeChanged(event)
    {
        let breakpoint = event.target;
        if (breakpoint.domNodeIdentifier)
            this._addBreakpoint(breakpoint);
        else
            this._removeBreakpoint(breakpoint);
    }

    _handleConsoleIssueAdded(event)
    {
        let {issue} = event.data;

        // We only want to show issues originating from JavaScript source code.
        if (!issue.sourceCodeLocation || !issue.sourceCodeLocation.sourceCode || (issue.source !== "javascript" && issue.source !== "console-api"))
            return;

        this._addIssue(issue);
    }

    _handleConsoleCleared(event)
    {
        let issueTreeElements = [];
        let currentTreeElement = this._resourcesTreeOutline.children[0];
        while (currentTreeElement && !currentTreeElement.root) {
            if (currentTreeElement instanceof WI.IssueTreeElement)
                issueTreeElements.push(currentTreeElement);

            const skipUnrevealed = false;
            const stayWithin = null;
            const dontPopulate = true;
            currentTreeElement = currentTreeElement.traverseNextTreeElement(skipUnrevealed, stayWithin, dontPopulate);
        }

        issueTreeElements.forEach((treeElement) => treeElement.parent.removeChild(treeElement));
    }

    _handleTimelineCapturingStateChanged(event)
    {
        this._updateTemporarilyDisabledBreakpointsButtons();

        switch (WI.timelineManager.capturingState) {
        case WI.TimelineManager.CapturingState.Starting:
            if (!this._timelineRecordingWarningElement) {
                let stopRecordingButton = document.createElement("button");
                stopRecordingButton.textContent = WI.UIString("Stop recording");
                stopRecordingButton.addEventListener("click", () => {
                    WI.timelineManager.stopCapturing();
                });

                this._timelineRecordingWarningElement = document.createElement("div");
                this._timelineRecordingWarningElement.classList.add("warning-banner");
                this._timelineRecordingWarningElement.append(WI.UIString("Debugger disabled during Timeline recording"), document.createElement("br"), stopRecordingButton);
            }

            this.contentView.element.insertBefore(this._timelineRecordingWarningElement, this.contentView.element.firstChild);
            break;

        case WI.TimelineManager.CapturingState.Inactive:
            if (this._timelineRecordingWarningElement) {
                this._timelineRecordingWarningElement.remove();
                this._timelineRecordingWarningElement = null;
            }
            break;
        }

        this._updateBreakpointsDisabledBanner();
    }

    _handleAuditManagerTestScheduled(event)
    {
        this._updateTemporarilyDisabledBreakpointsButtons();

        if (!this._auditTestWarningElement) {
            let stopAuditButton = document.createElement("button");
            stopAuditButton.textContent = WI.UIString("Stop Audit");
            stopAuditButton.addEventListener("click", (event) => {
                WI.auditManager.stop();
            });

            this._auditTestWarningElement = document.createElement("div");
            this._auditTestWarningElement.classList.add("warning-banner");
            this._auditTestWarningElement.append(WI.UIString("Debugger disabled during Audit"), document.createElement("br"), stopAuditButton);
        }

        this.contentView.element.insertBefore(this._auditTestWarningElement, this.contentView.element.firstChild);

        this._updateBreakpointsDisabledBanner();
    }

    _handleAuditManagerTestCompleted(event)
    {
        this._updateTemporarilyDisabledBreakpointsButtons();

        if (this._auditTestWarningElement) {
            this._auditTestWarningElement.remove();
            this._auditTestWarningElement = null;
        }

        this._updateBreakpointsDisabledBanner();
    }

    _handleCSSStyleSheetAdded(event)
    {
        let {styleSheet} = event.data;
        if (styleSheet.origin === WI.CSSStyleSheet.Type.Author)
            return;

        if (styleSheet.isInspectorStyleSheet()) {
            if (WI.settings.resourceGroupingMode.value === WI.Resource.GroupingMode.Type) {
                let frameTreeElement = this.treeElementForRepresentedObject(styleSheet.parentFrame);
                if (frameTreeElement) {
                    frameTreeElement.addRepresentedObjectToNewChildQueue(styleSheet);
                    return;
                }
            }

            this._addResource(styleSheet);
        } else
            this._addStyleSheet(styleSheet);
    }

    _handleCSSStyleSheetRemoved(event)
    {
        let {styleSheet} = event.data;
        if (styleSheet.origin === WI.CSSStyleSheet.Type.Author)
            return;

        let treeElement = this._resourcesTreeOutline.findTreeElement(styleSheet);
        if (!treeElement)
            return;

        let parent = treeElement.parent;
        treeElement.parent.removeChild(treeElement);

        if (!parent.children.length)
            parent.parent.removeChild(parent);

        switch (parent) {
        case this._extensionStyleSheetsFolderTreeElement:
            this._extensionStyleSheetsFolderTreeElement = null;
            break;

        case this._extraStyleSheetsFolderTreeElement:
            this._extraStyleSheetsFolderTreeElement = null;
            break;

        case this._anonymousStyleSheetsFolderTreeElement:
            this._anonymousStyleSheetsFolderTreeElement = null;
            break;
        }
    }

    _handleTargetAdded(event)
    {
        this._addTarget(event.data.target);
    }

    _handleTargetRemoved(event)
    {
        let {target} = event.data;

        let workerTreeElement = this._workerTargetTreeElementMap.take(target);
        if (workerTreeElement)
            workerTreeElement.parent.removeChild(workerTreeElement);

        let callStackTreeElement = this._findCallStackTargetTreeElement(target);
        console.assert(callStackTreeElement);
        if (callStackTreeElement)
            this._callStackTreeOutline.removeChild(callStackTreeElement);

        this._updateCallStackTreeOutline();
    }

    _handleExtraDomainsActivated()
    {
        if (WI.SourcesNavigationSidebarPanel.shouldPlaceResourcesAtTopLevel())
            this._resourcesTreeOutline.disclosureButtons = true;
    }
};

WI.SourcesNavigationSidebarPanel.ResourceTypeSymbol = Symbol("resource-type");
WI.SourcesNavigationSidebarPanel.ResourceGroupingModeSymbol = Symbol("resource-grouping-mode");
