/*
 * Copyright (C) 2013, 2015 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.NavigationSidebarPanel = class NavigationSidebarPanel extends WI.SidebarPanel
{
    constructor(identifier, displayName, shouldAutoPruneStaleTopLevelResourceTreeElements, wantsTopOverflowShadow)
    {
        super(identifier, displayName);

        this.element.classList.add("navigation");

        this._updateContentOverflowShadowVisibilityDebouncer = new Debouncer(() => {
            this._updateContentOverflowShadowVisibility();
        });
        this._boundUpdateContentOverflowShadowVisibilitySoon = (event) => {
            this._updateContentOverflowShadowVisibilityDebouncer.delayForTime(0);
        };

        this.contentView.element.addEventListener("scroll", this._boundUpdateContentOverflowShadowVisibilitySoon);

        this._contentTreeOutlineGroup = new WI.TreeOutlineGroup;
        this._contentTreeOutline = this.createContentTreeOutline();

        this._filterBar = new WI.FilterBar;
        this._filterBar.addEventListener(WI.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
        this.element.appendChild(this._filterBar.element);

        this._bottomOverflowShadowElement = document.createElement("div");
        this._bottomOverflowShadowElement.className = WI.NavigationSidebarPanel.OverflowShadowElementStyleClassName;
        this.element.appendChild(this._bottomOverflowShadowElement);

        if (wantsTopOverflowShadow) {
            this._topOverflowShadowElement = this.element.appendChild(document.createElement("div"));
            this._topOverflowShadowElement.classList.add(WI.NavigationSidebarPanel.OverflowShadowElementStyleClassName, "top");
        }

        window.addEventListener("resize", this._boundUpdateContentOverflowShadowVisibilitySoon);

        this._filtersSetting = new WI.Setting(identifier + "-navigation-sidebar-filters", {});
        this._filterBar.filters = this._filtersSetting.value;

        this._emptyContentPlaceholderElements = new Map;
        this._emptyFilterResults = new Set;

        this._shouldAutoPruneStaleTopLevelResourceTreeElements = shouldAutoPruneStaleTopLevelResourceTreeElements || false;

        if (this._shouldAutoPruneStaleTopLevelResourceTreeElements) {
            WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._checkForStaleResources, this);
            WI.Frame.addEventListener(WI.Frame.Event.ChildFrameWasRemoved, this._checkForStaleResources, this);
            WI.Frame.addEventListener(WI.Frame.Event.ResourceWasRemoved, this._checkForStaleResources, this);
        }

        this._pendingViewStateCookie = null;
        this._restoringState = false;
    }

    // Public

    get filterBar() { return this._filterBar; }
    get hasActiveFilters() { return this._filterBar.hasActiveFilters(); }

    closed()
    {
        window.removeEventListener("resize", this._boundUpdateContentOverflowShadowVisibilitySoon);
        WI.Frame.removeEventListener(null, null, this);
    }

    get contentBrowser()
    {
        return this._contentBrowser;
    }

    set contentBrowser(contentBrowser)
    {
        this._contentBrowser = contentBrowser || null;
    }

    get contentTreeOutline()
    {
        return this._contentTreeOutline;
    }

    get contentTreeOutlines()
    {
        return Array.from(this._contentTreeOutlineGroup);
    }

    get currentRepresentedObject()
    {
        if (!this._contentBrowser)
            return null;

        return this._contentBrowser.currentRepresentedObjects[0] || null;
    }

    get restoringState()
    {
        return this._restoringState;
    }

    cancelRestoringState()
    {
        this._pendingViewStateCookie = null;
        if (!this._finalAttemptToRestoreViewStateTimeout)
            return;

        clearTimeout(this._finalAttemptToRestoreViewStateTimeout);
        this._finalAttemptToRestoreViewStateTimeout = undefined;
    }

    createContentTreeOutline({ignoreCookieRestoration, suppressFiltering} = {})
    {
        let contentTreeOutline = new WI.TreeOutline;
        contentTreeOutline.allowsRepeatSelection = true;
        contentTreeOutline.element.classList.add(WI.NavigationSidebarPanel.ContentTreeOutlineElementStyleClassName);

        this._contentTreeOutlineGroup.add(contentTreeOutline);

        this.contentView.element.appendChild(contentTreeOutline.element);

        if (!suppressFiltering) {
            contentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementAdded, this._treeElementAddedOrChanged, this);
            contentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementDidChange, this._treeElementAddedOrChanged, this);
            contentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementDisclosureDidChanged, this._treeElementDisclosureDidChange, this);
            contentTreeOutline.addEventListener(WI.TreeOutline.Event.ElementRemoved, this._handleTreeElementRemoved, this);
        }

        contentTreeOutline[WI.NavigationSidebarPanel.IgnoreCookieRestoration] = ignoreCookieRestoration;
        contentTreeOutline[WI.NavigationSidebarPanel.SuppressFilteringSymbol] = suppressFiltering;

        return contentTreeOutline;
    }

    suppressFilteringOnTreeElements(treeElements)
    {
        console.assert(Array.isArray(treeElements), "TreeElements should be an array.");

        for (let treeElement of treeElements)
            treeElement[WI.NavigationSidebarPanel.SuppressFilteringSymbol] = true;

        this.updateFilter();
    }

    treeElementForRepresentedObject(representedObject)
    {
        let treeElement = null;
        for (let treeOutline of this.contentTreeOutlines) {
            treeElement = treeOutline.getCachedTreeElement(representedObject);
            if (treeElement)
                break;
        }

        return treeElement;
    }

    showDefaultContentView()
    {
        // Implemented by subclasses if needed to show a content view when no existing tree element is selected.
    }

    showDefaultContentViewForTreeElement(treeElement)
    {
        console.assert(treeElement);
        console.assert(treeElement.representedObject);
        if (!treeElement || !treeElement.representedObject)
            return false;

        // FIXME: <https://webkit.org/b/153634> Web Inspector: some background tabs think they are the foreground tab and do unnecessary work
        // Do not steal a content view if we are not the active tab/sidebar.
        if (!this.selected) {
            let contentView = this.contentBrowser.contentViewForRepresentedObject(treeElement.representedObject);
            if (contentView && contentView.parentContainer && contentView.parentContainer !== this.contentBrowser.contentViewContainer)
                return false;

            // contentView.parentContainer may be null. Check for selected tab, too.
            let selectedTabContentView = WI.tabBrowser.selectedTabContentView;
            if (selectedTabContentView && selectedTabContentView.contentBrowser !== this.contentBrowser)
                return false;
        }

        let contentView = this.contentBrowser.showContentViewForRepresentedObject(treeElement.representedObject);
        if (!contentView)
            return false;

        treeElement.revealAndSelect(true, false, true);
        return true;
    }

    canShowRepresentedObject(representedObject)
    {
        let selectedTabContentView = WI.tabBrowser.selectedTabContentView;
        console.assert(selectedTabContentView instanceof WI.TabContentView, "Missing TabContentView for NavigationSidebarPanel.");
        return selectedTabContentView && selectedTabContentView.canShowRepresentedObject(representedObject);
    }

    saveStateToCookie(cookie)
    {
        console.assert(cookie);

        if (!this._contentBrowser)
            return;

        let representedObject = this.currentRepresentedObject;
        if (!representedObject)
            return;

        cookie[WI.TypeIdentifierCookieKey] = representedObject.constructor.TypeIdentifier;

        if (representedObject.saveIdentityToCookie) {
            representedObject.saveIdentityToCookie(cookie);
            return;
        }

        console.error("NavigationSidebarPanel representedObject is missing a saveIdentityToCookie implementation.", representedObject);
    }

    // This can be supplemented by subclasses that admit a simpler strategy for static tree elements.
    restoreStateFromCookie(cookie, relaxedMatchDelay)
    {
        this._pendingViewStateCookie = cookie;
        this._restoringState = true;

        // Check if any existing tree elements in any outline match the cookie.
        this._checkOutlinesForPendingViewStateCookie();

        if (this._finalAttemptToRestoreViewStateTimeout)
            clearTimeout(this._finalAttemptToRestoreViewStateTimeout);

        if (relaxedMatchDelay === 0)
            return;

        function finalAttemptToRestoreViewStateFromCookie()
        {
            this._finalAttemptToRestoreViewStateTimeout = undefined;

            this._checkOutlinesForPendingViewStateCookie(true);

            this._pendingViewStateCookie = null;
            this._restoringState = false;
        }

        // If the specific tree element wasn't found, we may need to wait for the resources
        // to be registered. We try one last time (match type only) after an arbitrary amount of timeout.
        this._finalAttemptToRestoreViewStateTimeout = setTimeout(finalAttemptToRestoreViewStateFromCookie.bind(this), relaxedMatchDelay);
    }

    showEmptyContentPlaceholder(message, treeOutline)
    {
        console.assert(message);

        treeOutline = treeOutline || this._contentTreeOutline;

        let emptyContentPlaceholderElement = this._emptyContentPlaceholderElements.get(treeOutline);
        if (emptyContentPlaceholderElement)
            emptyContentPlaceholderElement.remove();

        emptyContentPlaceholderElement = message instanceof Node ? message : WI.createMessageTextView(message);
        this._emptyContentPlaceholderElements.set(treeOutline, emptyContentPlaceholderElement);

        let emptyContentPlaceholderParentElement = treeOutline.element.parentNode;
        emptyContentPlaceholderParentElement.appendChild(emptyContentPlaceholderElement);

        this._updateContentOverflowShadowVisibilityDebouncer.force();

        return emptyContentPlaceholderElement;
    }

    hideEmptyContentPlaceholder(treeOutline)
    {
        treeOutline = treeOutline || this._contentTreeOutline;

        let emptyContentPlaceholderElement = this._emptyContentPlaceholderElements.get(treeOutline);
        if (!emptyContentPlaceholderElement || !emptyContentPlaceholderElement.parentNode)
            return;

        emptyContentPlaceholderElement.remove();
        this._emptyContentPlaceholderElements.delete(treeOutline);

        this._updateContentOverflowShadowVisibilityDebouncer.force();
    }

    updateEmptyContentPlaceholder(message, treeOutline)
    {
        treeOutline = treeOutline || this._contentTreeOutline;

        if (!treeOutline.children.length) {
            // No tree elements, so no results.
            this.showEmptyContentPlaceholder(message, treeOutline);
        } else if (!this._emptyFilterResults.has(treeOutline)) {
            // There are tree elements, and not all of them are hidden by the filter.
            this.hideEmptyContentPlaceholder(treeOutline);
        }
    }

    updateFilter()
    {
        let filters = this._filterBar.filters;
        this._textFilterRegex = filters.text ? WI.SearchUtilities.filterRegExpForString(filters.text, WI.SearchUtilities.defaultSettings) : null;
        this._filtersSetting.value = filters;
        this._filterFunctions = filters.functions;

        this._filterBar.invalid = filters.text && !this._textFilterRegex;

        // Don't populate if we don't have any active filters.
        // We only need to populate when a filter needs to reveal.
        let dontPopulate = !this._filterBar.hasActiveFilters() && !this.shouldFilterPopulate();

        // Update all trees that allow filtering.
        for (let treeOutline of this.contentTreeOutlines) {
            if (treeOutline.hidden || treeOutline[WI.NavigationSidebarPanel.SuppressFilteringSymbol])
                continue;

            let currentTreeElement = treeOutline.children[0];
            while (currentTreeElement && !currentTreeElement.root) {
                if (!currentTreeElement[WI.NavigationSidebarPanel.SuppressFilteringSymbol]) {
                    const currentTreeElementWasHidden = currentTreeElement.hidden;
                    this.applyFiltersToTreeElement(currentTreeElement);
                    if (currentTreeElementWasHidden !== currentTreeElement.hidden)
                        this._treeElementWasFiltered(currentTreeElement);
                }

                currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, dontPopulate);
            }

            this._checkForEmptyFilterResults(treeOutline);
        }

        this._updateContentOverflowShadowVisibilityDebouncer.force();
    }

    resetFilter()
    {
        this._filterBar.clear();
    }

    shouldFilterPopulate()
    {
        // Overridden by subclasses if needed.
        return this.hasCustomFilters();
    }

    hasCustomFilters()
    {
        // Implemented by subclasses if needed.
        return false;
    }

    matchTreeElementAgainstCustomFilters(treeElement)
    {
        // Implemented by subclasses if needed.
        return true;
    }

    matchTreeElementAgainstFilterFunctions(treeElement)
    {
        if (!this._filterFunctions || !this._filterFunctions.length)
            return true;

        for (var filterFunction of this._filterFunctions) {
            if (filterFunction(treeElement))
                return true;
        }

        return false;
    }

    applyFiltersToTreeElement(treeElement)
    {
        if (!this._filterBar.hasActiveFilters() && !this.hasCustomFilters()) {
            // No filters, so make everything visible.
            treeElement.hidden = false;

            // If this tree element was expanded during filtering, collapse it again.
            if (treeElement.expanded && treeElement[WI.NavigationSidebarPanel.WasExpandedDuringFilteringSymbol]) {
                treeElement[WI.NavigationSidebarPanel.WasExpandedDuringFilteringSymbol] = false;
                treeElement.collapse();
            }

            return;
        }

        var filterableData = treeElement.filterableData || {};

        var flags = {expandTreeElement: false};
        var filterRegex = this._textFilterRegex;

        function matchTextFilter(inputs)
        {
            if (!inputs || !filterRegex)
                return true;

            console.assert(inputs instanceof Array, "filterableData.text should be an array of text inputs");

            // Loop over all the inputs and try to match them.
            for (var input of inputs) {
                if (!input)
                    continue;
                if (filterRegex.test(input)) {
                    flags.expandTreeElement = true;
                    return true;
                }
            }

            // No inputs matched.
            return false;
        }

        function makeVisible()
        {
            // Make this element visible.
            treeElement.hidden = false;

            // Make the ancestors visible and expand them.
            var currentAncestor = treeElement.parent;
            while (currentAncestor && !currentAncestor.root) {
                currentAncestor.hidden = false;

                // Only expand if the built-in filters matched, not custom filters.
                if (flags.expandTreeElement && !currentAncestor.expanded) {
                    currentAncestor.__wasExpandedDuringFiltering = true;
                    currentAncestor.expand();
                }

                currentAncestor = currentAncestor.parent;
            }
        }

        let suppressFiltering = treeElement[WI.NavigationSidebarPanel.SuppressFilteringSymbol];

        if (suppressFiltering || (matchTextFilter(filterableData.text) && this.matchTreeElementAgainstFilterFunctions(treeElement, flags) && this.matchTreeElementAgainstCustomFilters(treeElement, flags))) {
            // Make this element visible since it matches.
            makeVisible();

            // If this tree element didn't match a built-in filter and was expanded earlier during filtering, collapse it again.
            if (!flags.expandTreeElement && treeElement.expanded && treeElement[WI.NavigationSidebarPanel.WasExpandedDuringFilteringSymbol]) {
                treeElement[WI.NavigationSidebarPanel.WasExpandedDuringFilteringSymbol] = false;
                treeElement.collapse();
            }

            return;
        }

        // Make this element invisible since it does not match.
        treeElement.hidden = true;
    }

    shown()
    {
        super.shown();

        this._updateContentOverflowShadowVisibilityDebouncer.force();
    }

    // Protected

    pruneStaleResourceTreeElements()
    {
        if (this._checkForStaleResourcesTimeoutIdentifier) {
            clearTimeout(this._checkForStaleResourcesTimeoutIdentifier);
            this._checkForStaleResourcesTimeoutIdentifier = undefined;
        }

        for (let contentTreeOutline of this.contentTreeOutlines) {
            // Check all the ResourceTreeElements at the top level to make sure their Resource still has a parentFrame in the frame hierarchy.
            // If the parentFrame is no longer in the frame hierarchy we know it was removed due to a navigation or some other page change and
            // we should remove the issues for that resource.
            for (let i = contentTreeOutline.children.length - 1; i >= 0; --i) {
                let treeElement = contentTreeOutline.children[i];
                if (!(treeElement instanceof WI.ResourceTreeElement))
                    continue;

                // Local Overrides are never stale resources.
                let resource = treeElement.resource;
                if (resource.isLocalResourceOverride)
                    continue;

                if (!resource.parentFrame || resource.parentFrame.isDetached())
                    contentTreeOutline.removeChildAtIndex(i, true, true);
            }
        }
    }

    // Private

    _updateContentOverflowShadowVisibility()
    {
        if (!this.visible)
            return;

        let scrollHeight = this.contentView.element.scrollHeight;
        let offsetHeight = this.contentView.element.offsetHeight;

        if (scrollHeight < offsetHeight) {
            if (this._topOverflowShadowElement)
                this._topOverflowShadowElement.style.opacity = 0;
            this._bottomOverflowShadowElement.style.opacity = 0;
            return;
        }

        let edgeThreshold = 1;
        let scrollTop = this.contentView.element.scrollTop;

        let topCoverage = Math.min(scrollTop, edgeThreshold);
        let bottomCoverage = Math.max(0, (offsetHeight + scrollTop) - (scrollHeight - edgeThreshold));

        if (this._topOverflowShadowElement)
            this._topOverflowShadowElement.style.opacity = (topCoverage / edgeThreshold).toFixed(1);
        this._bottomOverflowShadowElement.style.opacity = (1 - (bottomCoverage / edgeThreshold)).toFixed(1);
    }

    _checkForEmptyFilterResults(treeOutline)
    {
        if (treeOutline[WI.NavigationSidebarPanel.SuppressFilteringSymbol])
            return;

        // No tree elements, so don't touch the empty content placeholder.
        if (!treeOutline.children.length)
            return;

        // Iterate over all the top level tree elements. If any filterable elements are visible, return early.
        let filterableTreeElementFound = false;
        let unfilteredTreeElementFound = false;
        let currentTreeElement = treeOutline.children[0];
        while (currentTreeElement) {
            let suppressFilteringForTreeElement = currentTreeElement[WI.NavigationSidebarPanel.SuppressFilteringSymbol];
            if (!suppressFilteringForTreeElement) {
                filterableTreeElementFound = true;

                if (!currentTreeElement.hidden) {
                    unfilteredTreeElementFound = true;
                    break;
                }
            }

            currentTreeElement = currentTreeElement.nextSibling;
        }

        if (unfilteredTreeElementFound || !filterableTreeElementFound) {
            this.hideEmptyContentPlaceholder(treeOutline);
            this._emptyFilterResults.delete(treeOutline);
            return;
        }

        let message = WI.createMessageTextView(WI.UIString("No Filter Results"));

        let buttonElement = message.appendChild(document.createElement("button"));
        buttonElement.textContent = WI.UIString("Clear Filters");
        buttonElement.addEventListener("click", () => {
            this.resetFilter();
        });

        // All top level tree elements are hidden, so filtering hid everything. Show a message.
        this.showEmptyContentPlaceholder(message, treeOutline);
        this._emptyFilterResults.add(treeOutline);
    }

    _filterDidChange()
    {
        this.updateFilter();
    }

    _treeElementAddedOrChanged(event)
    {
        // Don't populate if we don't have any active filters.
        // We only need to populate when a filter needs to reveal.
        var dontPopulate = !this._filterBar.hasActiveFilters() && !this.shouldFilterPopulate();

        // Apply the filters to the tree element and its descendants.
        let treeElement = event.data.element;
        let currentTreeElement = treeElement;
        while (currentTreeElement && !currentTreeElement.root) {
            if (!currentTreeElement[WI.NavigationSidebarPanel.SuppressFilteringSymbol]) {
                const currentTreeElementWasHidden = currentTreeElement.hidden;
                this.applyFiltersToTreeElement(currentTreeElement);
                if (currentTreeElementWasHidden !== currentTreeElement.hidden)
                    this._treeElementWasFiltered(currentTreeElement);
            }

            currentTreeElement = currentTreeElement.traverseNextTreeElement(false, treeElement, dontPopulate);
        }

        this._checkForEmptyFilterResults(event.target);

        if (this.visible)
            this._updateContentOverflowShadowVisibilityDebouncer.delayForTime(0);

        if (this.selected && !treeElement.treeOutline[WI.NavigationSidebarPanel.IgnoreCookieRestoration])
            this._checkElementsForPendingViewStateCookie([treeElement]);
    }

    _treeElementDisclosureDidChange(event)
    {
        this._updateContentOverflowShadowVisibilityDebouncer.delayForTime(0);
    }

    _handleTreeElementRemoved(event)
    {
        this._checkForEmptyFilterResults(event.target);

        if (this.visible)
            this._updateContentOverflowShadowVisibilityDebouncer.delayForTime(0);
    }

    _checkForStaleResourcesIfNeeded()
    {
        if (!this._checkForStaleResourcesTimeoutIdentifier || !this._shouldAutoPruneStaleTopLevelResourceTreeElements)
            return;
        this.pruneStaleResourceTreeElements();
    }

    _checkForStaleResources(event)
    {
        console.assert(this._shouldAutoPruneStaleTopLevelResourceTreeElements);

        if (this._checkForStaleResourcesTimeoutIdentifier)
            return;

        // Check on a delay to coalesce multiple calls to _checkForStaleResources.
        this._checkForStaleResourcesTimeoutIdentifier = setTimeout(this.pruneStaleResourceTreeElements.bind(this));
    }

    _isTreeElementWithoutRepresentedObject(treeElement)
    {
        return treeElement instanceof WI.FolderTreeElement
            || treeElement instanceof WI.DatabaseHostTreeElement
            || treeElement instanceof WI.IndexedDatabaseHostTreeElement
            || treeElement instanceof WI.ApplicationCacheManifestTreeElement
            || treeElement instanceof WI.ThreadTreeElement
            || treeElement instanceof WI.IdleTreeElement
            || treeElement instanceof WI.DOMBreakpointTreeElement
            || treeElement instanceof WI.EventBreakpointTreeElement
            || treeElement instanceof WI.URLBreakpointTreeElement
            || treeElement instanceof WI.CSSStyleSheetTreeElement
            || typeof treeElement.representedObject === "string"
            || treeElement.representedObject instanceof String;
    }

    _checkOutlinesForPendingViewStateCookie(matchTypeOnly)
    {
        if (!this._pendingViewStateCookie)
            return;

        this._checkForStaleResourcesIfNeeded();

        var visibleTreeElements = [];
        this.contentTreeOutlines.forEach(function(outline) {
            if (outline[WI.NavigationSidebarPanel.IgnoreCookieRestoration])
                return;

            var currentTreeElement = outline.hasChildren ? outline.children[0] : null;
            while (currentTreeElement) {
                visibleTreeElements.push(currentTreeElement);
                currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, false);
            }
        });

        this._checkElementsForPendingViewStateCookie(visibleTreeElements, matchTypeOnly);
    }

    _checkElementsForPendingViewStateCookie(treeElements, matchTypeOnly)
    {
        if (!this._pendingViewStateCookie)
            return;

        var cookie = this._pendingViewStateCookie;

        function treeElementMatchesCookie(treeElement)
        {
            if (this._isTreeElementWithoutRepresentedObject(treeElement))
                return false;

            var representedObject = treeElement.representedObject;
            if (!representedObject)
                return false;

            var typeIdentifier = cookie[WI.TypeIdentifierCookieKey];
            if (typeIdentifier !== representedObject.constructor.TypeIdentifier)
                return false;

            if (matchTypeOnly)
                return !!typeIdentifier;

            var candidateObjectCookie = {};
            if (representedObject.saveIdentityToCookie)
                representedObject.saveIdentityToCookie(candidateObjectCookie);

            var candidateCookieKeys = Object.keys(candidateObjectCookie);
            return candidateCookieKeys.length && candidateCookieKeys.every((key) => candidateObjectCookie[key] === cookie[key]);
        }

        var matchedElement = null;
        treeElements.some((element) => {
            if (treeElementMatchesCookie.call(this, element)) {
                matchedElement = element;
                return true;
            }
            return false;
        });

        if (matchedElement) {
            let didShowContentView = this.showDefaultContentViewForTreeElement(matchedElement);
            if (!didShowContentView)
                return;

            this._pendingViewStateCookie = null;

            // Delay clearing the restoringState flag until the next runloop so listeners
            // checking for it in this runloop still know state was being restored.
            setTimeout(() => {
                this._restoringState = false;
            }, 0);

            if (this._finalAttemptToRestoreViewStateTimeout) {
                clearTimeout(this._finalAttemptToRestoreViewStateTimeout);
                this._finalAttemptToRestoreViewStateTimeout = undefined;
            }
        }
    }

    _treeElementWasFiltered(treeElement)
    {
        if (treeElement.selected || treeElement.hidden)
            return;

        let representedObject = this.currentRepresentedObject;
        if (!representedObject || treeElement.representedObject !== representedObject)
            return;

        const omitFocus = true;
        const selectedByUser = false;
        const suppressNotification = true;
        treeElement.revealAndSelect(omitFocus, selectedByUser, suppressNotification);
    }
};

WI.NavigationSidebarPanel.IgnoreCookieRestoration = Symbol("ignore-cookie-restoration");
WI.NavigationSidebarPanel.SuppressFilteringSymbol = Symbol("suppress-filtering");
WI.NavigationSidebarPanel.WasExpandedDuringFilteringSymbol = Symbol("was-expanded-during-filtering");

WI.NavigationSidebarPanel.OverflowShadowElementStyleClassName = "overflow-shadow";
WI.NavigationSidebarPanel.ContentTreeOutlineElementStyleClassName = "navigation-sidebar-panel-content-tree-outline";
