/*
 * Copyright (C) 2017 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.NetworkTableContentView = class NetworkTableContentView extends WI.ContentView
{
    constructor(representedObject, extraArguments)
    {
        super(representedObject);

        // Collections contain the set of values needed to render the table.
        // The main collection reflects the main target's live activity.
        // We create other collections for HAR imports.
        this._collections = [];
        this._activeCollection = null;
        this._mainCollection = this._addCollection();
        this._setActiveCollection(this._mainCollection);

        this._entriesSortComparator = null;

        this._showingRepresentedObjectCookie = null;

        this._table = null;
        this._nameColumnWidthSetting = new WI.Setting("network-table-content-view-name-column-width", 250);

        this._selectedObject = null;
        this._detailView = null;
        this._detailViewMap = new Map;

        this._domNodeEntries = new Map;

        this._waterfallTimelineRuler = null;
        this._waterfallPopover = null;

        // FIXME: Network Timeline.
        // FIXME: Throttling.

        this._statistics = {};

        this.element.classList.add("network-table");

        this._typeFilterScopeBarItemAll = new WI.ScopeBarItem("network-type-filter-all", WI.UIString("All"), {exclusive: true});
        let typeFilterScopeBarItems = [this._typeFilterScopeBarItemAll];

        let uniqueTypes = [
            ["Document", (type) => type === WI.Resource.Type.Document],
            ["StyleSheet", (type) => type === WI.Resource.Type.StyleSheet],
            ["Image", (type) => type === WI.Resource.Type.Image],
            ["Font", (type) => type === WI.Resource.Type.Font],
            ["Script", (type) => type === WI.Resource.Type.Script],
            ["XHR", (type) => type === WI.Resource.Type.XHR || type === WI.Resource.Type.Fetch],
            ["Other", (type) => {
                return type !== WI.Resource.Type.Document
                    && type !== WI.Resource.Type.StyleSheet
                    && type !== WI.Resource.Type.Image
                    && type !== WI.Resource.Type.Font
                    && type !== WI.Resource.Type.Script
                    && type !== WI.Resource.Type.XHR
                    && type !== WI.Resource.Type.Fetch;
            }],
        ];
        for (let [key, checker] of uniqueTypes) {
            let type = WI.Resource.Type[key];
            let scopeBarItem = new WI.ScopeBarItem("network-type-filter-" + key, WI.NetworkTableContentView.shortDisplayNameForResourceType(type));
            scopeBarItem.__checker = checker;
            typeFilterScopeBarItems.push(scopeBarItem);
        }

        this._typeFilterScopeBar = new WI.ScopeBar("network-type-filter-scope-bar", typeFilterScopeBarItems, typeFilterScopeBarItems[0]);
        this._typeFilterScopeBar.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
        this._typeFilterScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._typeFilterScopeBarSelectionChanged, this);

        if (WI.MediaInstrument.supported()) {
            this._groupMediaRequestsByDOMNodeNavigationItem = new WI.CheckboxNavigationItem("group-media-requests", WI.UIString("Group Media Requests"), WI.settings.groupMediaRequestsByDOMNode.value);
            this._groupMediaRequestsByDOMNodeNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
            this._groupMediaRequestsByDOMNodeNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, this._handleGroupMediaRequestsByDOMNodeCheckedDidChange, this);
        } else
            WI.settings.groupMediaRequestsByDOMNode.value = false;

        this._urlFilterSearchText = null;
        this._urlFilterSearchRegex = null;
        this._urlFilterIsActive = false;

        this._urlFilterNavigationItem = new WI.FilterBarNavigationItem;
        this._urlFilterNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
        this._urlFilterNavigationItem.filterBar.addEventListener(WI.FilterBar.Event.FilterDidChange, this._urlFilterDidChange, this);
        this._urlFilterNavigationItem.filterBar.placeholder = WI.UIString("Filter Full URL");

        this._activeTypeFilters = this._generateTypeFilter();
        this._activeURLFilterResources = new Set;

        this._emptyFilterResultsMessageElement = null;

        this._clearOnLoadNavigationItem = new WI.CheckboxNavigationItem("preserve-log", WI.UIString("Preserve Log"), !WI.settings.clearNetworkOnNavigate.value);
        this._clearOnLoadNavigationItem.tooltip = WI.UIString("Do not clear network items on new page loads");
        this._clearOnLoadNavigationItem.addEventListener(WI.CheckboxNavigationItem.Event.CheckedDidChange, () => { WI.settings.clearNetworkOnNavigate.value = !WI.settings.clearNetworkOnNavigate.value; });
        WI.settings.clearNetworkOnNavigate.addEventListener(WI.Setting.Event.Changed, this._clearNetworkOnNavigateSettingChanged, this);

        this._harImportNavigationItem = new WI.ButtonNavigationItem("har-import", WI.UIString("Import"), "Images/Import.svg", 15, 15);
        this._harImportNavigationItem.buttonStyle = WI.ButtonNavigationItem.Style.ImageAndText;
        this._harImportNavigationItem.tooltip = WI.UIString("HAR Import");
        this._harImportNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, () => {
            this._importHAR();
        });

        this._harExportNavigationItem = new WI.ButtonNavigationItem("har-export", WI.UIString("Export"), "Images/Export.svg", 15, 15);
        this._harExportNavigationItem.buttonStyle = WI.ButtonNavigationItem.Style.ImageAndText;
        this._harExportNavigationItem.tooltip = WI.UIString("HAR Export (%s)").format(WI.saveKeyboardShortcut.displayName);
        this._harExportNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, () => {
            this._exportHAR();
        });

        this._collectionsPathNavigationItem = new WI.HierarchicalPathNavigationItem;
        this._collectionsPathNavigationItem.addEventListener(WI.HierarchicalPathNavigationItem.Event.PathComponentWasSelected, this._collectionsHierarchicalPathComponentWasSelected, this);

        this._pathComponentsMap = new Map;
        this._lastPathComponent = null;
        let pathComponent = this._addCollectionPathComponent(this._mainCollection, WI.UIString("Live Activity"), "network-overview-icon");
        this._collectionsPathNavigationItem.components = [pathComponent];

        this._checkboxesNavigationItemGroup = new WI.GroupNavigationItem([this._clearOnLoadNavigationItem, new WI.DividerNavigationItem]);

        this._pathComponentsNavigationItemGroup = new WI.GroupNavigationItem([this._collectionsPathNavigationItem, new WI.DividerNavigationItem]);
        this._pathComponentsNavigationItemGroup.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
        this._pathComponentsNavigationItemGroup.hidden = true;

        this._buttonsNavigationItemGroup = new WI.GroupNavigationItem([this._harImportNavigationItem, this._harExportNavigationItem, new WI.DividerNavigationItem]);
        this._buttonsNavigationItemGroup.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;

        // COMPATIBILITY (iOS 10.3): Network.setDisableResourceCaching did not exist.
        if (InspectorBackend.hasCommand("Network.setResourceCachingDisabled")) {
            let toolTipForDisableResourceCache = WI.UIString("Ignore the resource cache when loading resources");
            let activatedToolTipForDisableResourceCache = WI.UIString("Use the resource cache when loading resources");
            this._disableResourceCacheNavigationItem = new WI.ActivateButtonNavigationItem("disable-resource-cache", toolTipForDisableResourceCache, activatedToolTipForDisableResourceCache, "Images/IgnoreCaches.svg", 16, 16);
            this._disableResourceCacheNavigationItem.activated = WI.settings.resourceCachingDisabled.value;
            this._disableResourceCacheNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.High;
            this._disableResourceCacheNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleDisableResourceCache, this);

            WI.settings.resourceCachingDisabled.addEventListener(WI.Setting.Event.Changed, this._resourceCachingDisabledSettingChanged, this);
        }

        this._clearNetworkItemsNavigationItem = new WI.ButtonNavigationItem("clear-network-items", WI.UIString("Clear Network Items (%s)").format(WI.clearKeyboardShortcut.displayName), "Images/NavigationItemTrash.svg", 15, 15);
        this._clearNetworkItemsNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, () => {
            this.reset();
        });

        WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._handleResourceAdded, this);
        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
        WI.Frame.addEventListener(WI.Frame.Event.ResourceWasAdded, this._handleResourceAdded, this);
        WI.Frame.addEventListener(WI.Frame.Event.ChildFrameWasAdded, this._handleFrameWasAdded, this);
        WI.Resource.addEventListener(WI.Resource.Event.LoadingDidFinish, this._resourceLoadingDidFinish, this);
        WI.Resource.addEventListener(WI.Resource.Event.LoadingDidFail, this._resourceLoadingDidFail, this);
        WI.Resource.addEventListener(WI.Resource.Event.SizeDidChange, this._handleResourceSizeDidChange, this);
        WI.Resource.addEventListener(WI.Resource.Event.TransferSizeDidChange, this._resourceTransferSizeDidChange, this);
        WI.networkManager.addEventListener(WI.NetworkManager.Event.MainFrameDidChange, this._mainFrameDidChange, this);

        this._needsInitialPopulate = true;

        // FIXME: This is working around the order of events. Normal page navigation
        // triggers a MainResource change and then a MainFrame change. Page Transition
        // triggers a MainFrame change then a MainResource change.
        this._transitioningPageTarget = false;

        WI.notifications.addEventListener(WI.Notification.TransitionPageTarget, this._transitionPageTarget, this);
    }

    // Static

    static displayNameForResource(resource)
    {
        if (resource.type === WI.Resource.Type.Image || resource.type === WI.Resource.Type.Font || resource.type === WI.Resource.Type.Other) {
            let fileExtension;
            if (resource.mimeType)
                fileExtension = WI.fileExtensionForMIMEType(resource.mimeType);
            if (!fileExtension)
                fileExtension = WI.fileExtensionForURL(resource.url);
            if (fileExtension)
                return fileExtension;
        }

        return WI.NetworkTableContentView.shortDisplayNameForResourceType(resource.type).toLowerCase();
    }

    static shortDisplayNameForResourceType(type)
    {
        switch (type) {
        case WI.Resource.Type.Document:
            return WI.UIString("Document");
        case WI.Resource.Type.StyleSheet:
            return WI.unlocalizedString("CSS");
        case WI.Resource.Type.Image:
            return WI.UIString("Image");
        case WI.Resource.Type.Font:
            return WI.UIString("Font");
        case WI.Resource.Type.Script:
            return WI.unlocalizedString("JS");
        case WI.Resource.Type.XHR:
            return WI.unlocalizedString("XHR");
        case WI.Resource.Type.Fetch:
            return WI.repeatedUIString.fetch();
        case WI.Resource.Type.Ping:
            return WI.UIString("Ping");
        case WI.Resource.Type.Beacon:
            return WI.UIString("Beacon");
        case WI.Resource.Type.WebSocket:
        case WI.Resource.Type.Other:
            return WI.UIString("Other");
        default:
            console.error("Unknown resource type", type);
            return null;
        }
    }

    static get nodeWaterfallDOMEventSize() { return 8; }

    // Public

    get selectionPathComponents()
    {
        return null;
    }

    get navigationItems()
    {
        let items = [this._checkboxesNavigationItemGroup, this._pathComponentsNavigationItemGroup, this._buttonsNavigationItemGroup];
        if (this._disableResourceCacheNavigationItem)
            items.push(this._disableResourceCacheNavigationItem);
        items.push(this._clearNetworkItemsNavigationItem);
        return items;
    }

    get filterNavigationItems()
    {
        let navigationItems = [this._urlFilterNavigationItem, this._typeFilterScopeBar];
        if (WI.MediaInstrument.supported())
            navigationItems.push(this._groupMediaRequestsByDOMNodeNavigationItem);
        return navigationItems;
    }

    get supportsSave()
    {
        return this._canExportHAR();
    }

    get saveData()
    {
        return {customSaveHandler: () => { this._exportHAR(); }};
    }

    shown()
    {
        super.shown();

        if (this._detailView)
            this._detailView.shown();

        if (this._table)
            this._table.restoreScrollPosition();
    }

    hidden()
    {
        this._hidePopover();

        if (this._detailView)
            this._detailView.hidden();

        super.hidden();
    }

    closed()
    {
        for (let detailView of this._detailViewMap.values())
            detailView.dispose();
        this._detailViewMap.clear();

        this._domNodeEntries.clear();

        this._hidePopover();
        this._hideDetailView();

        WI.Target.removeEventListener(null, null, this);
        WI.Frame.removeEventListener(null, null, this);
        WI.Resource.removeEventListener(null, null, this);
        WI.settings.resourceCachingDisabled.removeEventListener(null, null, this);
        WI.settings.clearNetworkOnNavigate.removeEventListener(null, null, this);
        WI.networkManager.removeEventListener(WI.NetworkManager.Event.MainFrameDidChange, this._mainFrameDidChange, this);

        super.closed();
    }

    reset()
    {
        this._runForMainCollection((collection, wasMain) => {
            this._resetCollection(collection);

            if (wasMain)
                this._updateStatistics();
        });

        for (let detailView of this._detailViewMap.values())
            detailView.dispose();
        this._detailViewMap.clear();

        this._domNodeEntries.clear();

        this._updateWaterfallTimelineRuler();
        this._updateExportButton();

        if (this._table) {
            this._selectedObject = null;
            this._table.reloadData();
            this._hidePopover();
            this._hideDetailView();
        }
    }

    showRepresentedObject(representedObject, cookie)
    {
        console.assert(representedObject instanceof WI.Resource);

        let rowIndex = this._rowIndexForRepresentedObject(representedObject);
        if (rowIndex === -1) {
            this._selectedObject = null;
            this._table.deselectAll();
            this._hideDetailView();
            return;
        }

        this._showingRepresentedObjectCookie = cookie;
        this._table.selectRow(rowIndex);
        this._showingRepresentedObjectCookie = null;
    }

    get canFocusFilterBar()
    {
        return !this._detailView;
    }

    focusFilterBar()
    {
        this._urlFilterNavigationItem.filterBar.focus();
    }

    // NetworkDetailView delegate

    networkDetailViewClose(networkDetailView)
    {
        this._selectedObject = null;
        this._table.deselectAll();
        this._hideDetailView();
    }

    // Table dataSource

    tableIndexForRepresentedObject(table, object)
    {
        return this._activeCollection.filteredEntries.indexOf(object);
    }

    tableRepresentedObjectForIndex(table, index)
    {
        console.assert(index >= 0 && index < this._activeCollection.filteredEntries.length);
        return this._activeCollection.filteredEntries[index];
    }

    tableNumberOfRows(table)
    {
        return this._activeCollection.filteredEntries.length;
    }

    tableSortChanged(table)
    {
        this._generateSortComparator();

        if (!this._entriesSortComparator)
            return;

        this._hideDetailView();

        for (let nodeEntry of this._domNodeEntries.values())
            nodeEntry.initiatedResourceEntries.sort(this._entriesSortComparator);

        this._updateSort();
        this._updateFilteredEntries();
        this._reloadTable();
    }

    // Table delegate

    tableCellContextMenuClicked(table, cell, column, rowIndex, event)
    {
        if (column !== this._nameColumn)
            return;

        this._table.selectRow(rowIndex);

        let entry = this._activeCollection.filteredEntries[rowIndex];
        let contextMenu = WI.ContextMenu.createFromEvent(event);
        WI.appendContextMenuItemsForSourceCode(contextMenu, entry.resource);

        contextMenu.appendSeparator();
        contextMenu.appendItem(WI.UIString("Export HAR"), () => { this._exportHAR(); }, !this._canExportHAR());
    }

    tableShouldSelectRow(table, cell, column, rowIndex)
    {
        return column === this._nameColumn;
    }

    tableSelectionDidChange(table)
    {
        let rowIndex = table.selectedRow;
        if (isNaN(rowIndex)) {
            this._selectedObject = null;
            this._hideDetailView();
            return;
        }

        let entry = this._activeCollection.filteredEntries[rowIndex];
        if (entry.resource === this._selectedObject || entry.domNode === this._selectedObject)
            return;

        this._selectedObject = entry.resource || entry.domNode;
        if (this._selectedObject)
            this._showDetailView(this._selectedObject);
        else
            this._hideDetailView();
    }

    tablePopulateCell(table, cell, column, rowIndex)
    {
        let entry = this._activeCollection.filteredEntries[rowIndex];

        cell.classList.toggle("current-session", entry.currentSession);

        if (entry.resource)
            cell.classList.toggle("error", entry.resource.hadLoadingError());

        let setTextContent = (accessor) => {
            let uniqueValues = this._uniqueValuesForDOMNodeEntry(entry, accessor);
            if (uniqueValues) {
                if (uniqueValues.size > 1) {
                    cell.classList.add("multiple");
                    cell.textContent = WI.UIString("(multiple)");
                    return;
                }

                cell.textContent = uniqueValues.values().next().value || emDash;
                return;
            }

            cell.textContent = accessor(entry) || emDash;
        };

        switch (column.identifier) {
        case "name":
            this._populateNameCell(cell, entry);
            break;
        case "domain":
            this._populateDomainCell(cell, entry);
            break;
        case "type":
            setTextContent((resourceEntry) => resourceEntry.displayType);
            break;
        case "mimeType":
            setTextContent((resourceEntry) => resourceEntry.mimeType);
            break;
        case "method":
            setTextContent((resourceEntry) => resourceEntry.method);
            break;
        case "scheme":
            setTextContent((resourceEntry) => resourceEntry.scheme);
            break;
        case "status":
            setTextContent((resourceEntry) => resourceEntry.status);
            break;
        case "protocol":
            setTextContent((resourceEntry) => resourceEntry.protocol);
            break;
        case "initiator":
            this._populateInitiatorCell(cell, entry);
            break;
        case "priority":
            setTextContent((resourceEntry) => WI.Resource.displayNameForPriority(resourceEntry.priority));
            break;
        case "remoteAddress":
            setTextContent((resourceEntry) => resourceEntry.remoteAddress);
            break;
        case "connectionIdentifier":
            setTextContent((resourceEntry) => resourceEntry.connectionIdentifier);
            break;
        case "resourceSize": {
            let resourceSize = entry.resourceSize;
            let resourceEntries = entry.initiatedResourceEntries;
            if (resourceEntries)
                resourceSize = resourceEntries.reduce((accumulator, current) => accumulator + (current.resourceSize || 0), 0);
            cell.textContent = isNaN(resourceSize) ? emDash : Number.bytesToString(resourceSize);
            break;
        }
        case "transferSize":
            this._populateTransferSizeCell(cell, entry);
            break;
        case "time": {
            // FIXME: <https://webkit.org/b/176748> Web Inspector: Frontend sometimes receives resources with negative duration (responseEnd - requestStart)
            let time = entry.time;
            let resourceEntries = entry.initiatedResourceEntries;
            if (resourceEntries)
                time = resourceEntries.reduce((accumulator, current) => accumulator + (current.time || 0), 0);
            cell.textContent = isNaN(time) ? emDash : Number.secondsToString(Math.max(time, 0));
            break;
        }
        case "waterfall":
            this._populateWaterfallGraph(cell, entry);
            break;
        }

        return cell;
    }

    // Private

    _addCollection()
    {
        let collection = {};
        this._resetCollection(collection);
        this._collections.push(collection);
        return collection;
    }

    _resetCollection(collection)
    {
        collection.entries = [];
        collection.filteredEntries = [];
        collection.pendingInsertions = [];
        collection.pendingUpdates = [];
        collection.waterfallStartTime = NaN;
        collection.waterfallEndTime = NaN;
    }

    _setActiveCollection(collection)
    {
        console.assert(this._collections.includes(collection));

        if (this._activeCollection === collection)
            return;

        this._activeCollection = collection;
    }

    _addCollectionPathComponent(collection, displayName, iconClassName)
    {
        let pathComponent = new WI.HierarchicalPathComponent(displayName, iconClassName, collection);
        this._pathComponentsMap.set(collection, pathComponent);

        if (this._lastPathComponent) {
            this._lastPathComponent.nextSibling = pathComponent;
            pathComponent.previousSibling = this._lastPathComponent;
        }

        this._lastPathComponent = pathComponent;

        if (this._pathComponentsNavigationItemGroup && this._pathComponentsMap.size > 1)
            this._pathComponentsNavigationItemGroup.hidden = false;

        return pathComponent;
    }

    _collectionsHierarchicalPathComponentWasSelected(event)
    {
        console.assert(event.data.pathComponent instanceof WI.HierarchicalPathComponent);

        let collection = event.data.pathComponent.representedObject;

        this._changeCollection(collection);
    }

    _changeCollection(collection)
    {
        if (collection === this._activeCollection)
            return;

        this._setActiveCollection(collection);

        let isMain = collection === this._mainCollection;
        this._checkboxesNavigationItemGroup.hidden = !isMain;
        this._groupMediaRequestsByDOMNodeNavigationItem.hidden = !isMain;
        this._clearNetworkItemsNavigationItem.enabled = isMain;
        this._collectionsPathNavigationItem.components = [this._pathComponentsMap.get(collection)];

        this._updateSort();
        this._updateActiveFilterResources();
        this._updateFilteredEntries();
        this._updateWaterfallTimelineRuler();
        this._reloadTable();
        this._updateStatistics();
        this._hideDetailView();

        this.needsLayout();
    }

    _populateNameCell(cell, entry)
    {
        console.assert(!cell.firstChild, "We expect the cell to be empty.", cell, cell.firstChild);

        function createIconElement() {
            let iconElement = cell.appendChild(document.createElement("img"));
            iconElement.className = "icon";
            return iconElement;
        }

        let domNode = entry.domNode;
        if (domNode) {
            this._table.element.classList.add("grouped");

            cell.classList.add("parent");

            let disclosureElement = cell.appendChild(document.createElement("img"));
            disclosureElement.classList.add("disclosure");
            disclosureElement.classList.toggle("expanded", !!entry.expanded);
            disclosureElement.addEventListener("click", (event) => {
                entry.expanded = !entry.expanded;

                this._updateFilteredEntries();
                this._reloadTable();
            });

            createIconElement();

            cell.classList.add("dom-node");
            cell.appendChild(WI.linkifyNodeReference(domNode));
            return;
        }

        let resource = entry.resource;
        if (resource.isLoading()) {
            let statusElement = cell.appendChild(document.createElement("div"));
            statusElement.className = "status";
            let spinner = new WI.IndeterminateProgressSpinner;
            statusElement.appendChild(spinner.element);
        }

        let resourceIconElement = createIconElement();

        cell.classList.add(WI.ResourceTreeElement.ResourceIconStyleClassName, ...WI.Resource.classNamesForResource(resource));

        if (WI.settings.groupMediaRequestsByDOMNode.value && resource.initiatorNode) {
            let nodeEntry = this._domNodeEntries.get(resource.initiatorNode);
            if (nodeEntry.initiatedResourceEntries.length > 1 || nodeEntry.domNode.domEvents.length)
                cell.classList.add("child");
        }

        let nameElement = cell.appendChild(document.createElement("span"));
        nameElement.textContent = entry.name;

        let range = resource.requestedByteRange;
        if (range) {
            let rangeElement = nameElement.appendChild(document.createElement("span"));
            rangeElement.classList.add("range");
            rangeElement.textContent = WI.UIString("Byte Range %s\u2013%s").format(range.start, range.end);
        }

        cell.title = resource.url;
        if (resource.responseSource === WI.Resource.ResponseSource.InspectorOverride)
            resourceIconElement.title = WI.UIString("This resource was loaded from a local override");
    }

    _populateDomainCell(cell, entry)
    {
        console.assert(!cell.firstChild, "We expect the cell to be empty.", cell, cell.firstChild);

        function createIconAndText(scheme, domain) {
            let secure = scheme === "https" || scheme === "wss";
            if (secure) {
                let lockIconElement = cell.appendChild(document.createElement("img"));
                lockIconElement.className = "lock";
            }

            cell.append(domain || emDash);
        }

        let uniqueSchemeValues = this._uniqueValuesForDOMNodeEntry(entry, (resourceEntry) => resourceEntry.scheme);
        let uniqueDomainValues = this._uniqueValuesForDOMNodeEntry(entry, (resourceEntry) => resourceEntry.domain);
        if (uniqueSchemeValues && uniqueDomainValues) {
            if (uniqueSchemeValues.size > 1 || uniqueDomainValues.size > 1) {
                cell.classList.add("multiple");
                cell.textContent = WI.UIString("(multiple)");
                return;
            }

            createIconAndText(uniqueSchemeValues.values().next().value, uniqueDomainValues.values().next().value);
            return;
        }

        createIconAndText(entry.scheme, entry.domain);
    }

    _populateInitiatorCell(cell, entry)
    {
        let domNode = entry.domNode;
        if (domNode) {
            cell.textContent = emDash;
            return;
        }

        let initiatorLocation = entry.resource.initiatorSourceCodeLocation;
        if (!initiatorLocation) {
            cell.textContent = emDash;
            return;
        }

        const options = {
            dontFloat: true,
            ignoreSearchTab: true,
        };
        cell.appendChild(WI.createSourceCodeLocationLink(initiatorLocation, options));
    }

    _populateTransferSizeCell(cell, entry)
    {
        let resourceEntries = entry.initiatedResourceEntries;
        if (resourceEntries) {
            if (resourceEntries.every((resourceEntry) => resourceEntry.resource.responseSource === WI.Resource.ResponseSource.MemoryCache)) {
                cell.classList.add("cache-type");
                cell.textContent = WI.UIString("(memory)");
                cell.title = WI.UIString("This resource was loaded from the memory cache");
                return;
            }
            if (resourceEntries.every((resourceEntry) => resourceEntry.resource.responseSource === WI.Resource.ResponseSource.DiskCache)) {
                cell.classList.add("cache-type");
                cell.textContent = WI.UIString("(disk)");
                cell.title = WI.UIString("This resource was loaded from the disk cache");
                return;
            }
            if (resourceEntries.every((resourceEntry) => resourceEntry.resource.responseSource === WI.Resource.ResponseSource.ServiceWorker)) {
                cell.classList.add("cache-type");
                cell.textContent = WI.UIString("(service worker)");
                cell.title = WI.UIString("This resource was loaded from a service worker");
                return;
            }

            console.assert(!cell.classList.contains("cache-type"), "Should not have cache-type class on cell.");

            let transferSize = resourceEntries.reduce((accumulator, current) => accumulator + (current.transferSize || 0), 0);
            cell.textContent = isNaN(transferSize) ? emDash : Number.bytesToString(transferSize);
            cell.title = "";
            return;
        }

        let responseSource = entry.resource.responseSource;
        if (responseSource === WI.Resource.ResponseSource.MemoryCache) {
            cell.classList.add("cache-type");
            cell.textContent = WI.UIString("(memory)");
            cell.title = WI.UIString("This resource was loaded from the memory cache");
            return;
        }
        if (responseSource === WI.Resource.ResponseSource.DiskCache) {
            cell.classList.add("cache-type");
            cell.textContent = WI.UIString("(disk)");
            cell.title = WI.UIString("This resource was loaded from the disk cache");
            return;
        }
        if (responseSource === WI.Resource.ResponseSource.ServiceWorker) {
            cell.classList.add("cache-type");
            cell.textContent = WI.UIString("(service worker)");
            cell.title = WI.UIString("This resource was loaded from a service worker");
            return;
        }
        if (responseSource === WI.Resource.ResponseSource.InspectorOverride) {
            cell.classList.add("cache-type");
            cell.textContent = WI.UIString("(local override)");
            cell.title = WI.UIString("This resource was loaded from a local override");
            return;
        }

        console.assert(!cell.classList.contains("cache-type"), "Should not have cache-type class on cell.");

        let transferSize = entry.transferSize;
        cell.textContent = isNaN(transferSize) ? emDash : Number.bytesToString(transferSize);
        cell.title = "";
    }

    _populateWaterfallGraph(cell, entry)
    {
        cell.classList.add("network");

        cell.removeChildren();

        let container = cell.appendChild(document.createElement("div"));
        container.className = "waterfall-container";

        let collection = this._activeCollection;
        let graphStartTime = this._waterfallTimelineRuler.startTime;
        let secondsPerPixel = this._waterfallTimelineRuler.secondsPerPixel;

        function positionByStartOffset(element, timestamp) {
            let styleAttribute = WI.resolvedLayoutDirection() === WI.LayoutDirection.LTR ? "left" : "right";
            element.style.setProperty(styleAttribute, ((timestamp - graphStartTime) / secondsPerPixel) + "px");
        }

        function setWidthForDuration(element, startTimestamp, endTimestamp) {
            element.style.setProperty("width", ((endTimestamp - startTimestamp) / secondsPerPixel) + "px");
        }

        let domNode = entry.domNode;
        if (domNode) {
            let groupedDOMEvents = [];
            for (let domEvent of domNode.domEvents) {
                if (domEvent.originator)
                    continue;

                if (!groupedDOMEvents.length || (domEvent.timestamp - groupedDOMEvents.lastValue.endTimestamp) >= (NetworkTableContentView.nodeWaterfallDOMEventSize * secondsPerPixel)) {
                    groupedDOMEvents.push({
                        startTimestamp: domEvent.timestamp,
                        domEvents: [],
                    });
                }
                groupedDOMEvents.lastValue.endTimestamp = domEvent.timestamp;
                groupedDOMEvents.lastValue.domEvents.push(domEvent);
            }

            let fullscreenDOMEvents = WI.DOMNode.getFullscreenDOMEvents(domNode.domEvents);
            if (fullscreenDOMEvents.length) {
                if (!fullscreenDOMEvents[0].data.enabled)
                    fullscreenDOMEvents.unshift({timestamp: graphStartTime});

                if (fullscreenDOMEvents.lastValue.data.enabled)
                    fullscreenDOMEvents.push({timestamp: collection.waterfallEndTime});

                console.assert((fullscreenDOMEvents.length % 2) === 0, "Every enter/exit of fullscreen should have a corresponding exit/enter.");

                for (let i = 0; i < fullscreenDOMEvents.length; i += 2) {
                    let fullscreenElement = container.appendChild(document.createElement("div"));
                    fullscreenElement.classList.add("area", "dom-fullscreen");
                    positionByStartOffset(fullscreenElement, fullscreenDOMEvents[i].timestamp);
                    setWidthForDuration(fullscreenElement, fullscreenDOMEvents[i].timestamp, fullscreenDOMEvents[i + 1].timestamp);

                    let originator = fullscreenDOMEvents[i].originator || fullscreenDOMEvents[i + 1].originator;
                    if (originator)
                        fullscreenElement.title = WI.UIString("Full-Screen from \u201C%s\u201D").format(originator.displayName);
                    else
                        fullscreenElement.title = WI.UIString("Full-Screen");
                }
            }

            for (let powerEfficientPlaybackRange of domNode.powerEfficientPlaybackRanges) {
                let startTimestamp = powerEfficientPlaybackRange.startTimestamp || graphStartTime;
                let endTimestamp = powerEfficientPlaybackRange.endTimestamp || collection.waterfallEndTime;

                let powerEfficientPlaybackRangeElement = container.appendChild(document.createElement("div"));
                powerEfficientPlaybackRangeElement.classList.add("area", "power-efficient-playback");
                powerEfficientPlaybackRangeElement.title = WI.UIString("Power Efficient Playback");
                positionByStartOffset(powerEfficientPlaybackRangeElement, startTimestamp);
                setWidthForDuration(powerEfficientPlaybackRangeElement, startTimestamp, endTimestamp);
            }

            let playing = false;

            function createDOMEventLine(domEvents, startTimestamp, endTimestamp) {
                if (WI.DOMNode.isStopEvent(domEvents.lastValue.eventName))
                    return;

                for (let i = domEvents.length - 1; i >= 0; --i) {
                    let domEvent = domEvents[i];
                    if (WI.DOMNode.isPlayEvent(domEvent.eventName)) {
                        playing = true;
                        break;
                    }

                    if (WI.DOMNode.isPauseEvent(domEvent.eventName)) {
                        playing = false;
                        break;
                    }
                }

                let lineElement = container.appendChild(document.createElement("div"));
                lineElement.classList.add("dom-activity");
                lineElement.classList.toggle("playing", playing);
                positionByStartOffset(lineElement, startTimestamp);
                setWidthForDuration(lineElement, startTimestamp, endTimestamp);
            }

            for (let [a, b] of groupedDOMEvents.adjacencies())
                createDOMEventLine(a.domEvents, a.endTimestamp, b.startTimestamp);

            if (groupedDOMEvents.length)
                createDOMEventLine(groupedDOMEvents.lastValue.domEvents, groupedDOMEvents.lastValue.endTimestamp, collection.waterfallEndTime);

            for (let {startTimestamp, endTimestamp, domEvents} of groupedDOMEvents) {
                let paddingForCentering = NetworkTableContentView.nodeWaterfallDOMEventSize * secondsPerPixel / 2;

                let eventElement = container.appendChild(document.createElement("div"));
                eventElement.classList.add("dom-event");
                positionByStartOffset(eventElement, startTimestamp - paddingForCentering);
                setWidthForDuration(eventElement, startTimestamp, endTimestamp + paddingForCentering);
                eventElement.addEventListener("mousedown", (event) => {
                    if (event.button !== 0 || event.ctrlKey)
                        return;
                    this._handleNodeEntryMousedownWaterfall(entry, domEvents);
                });

                for (let domEvent of domEvents)
                    entry.domEventElements.set(domEvent, eventElement);
            }

            return;
        }

        let resource = entry.resource;
        if (!resource.hasResponse()) {
            cell.textContent = zeroWidthSpace;
            return;
        }

        let {startTime, redirectStart, redirectEnd, fetchStart, domainLookupStart, domainLookupEnd, connectStart, connectEnd, secureConnectionStart, requestStart, responseStart, responseEnd} = resource.timingData;
        if (isNaN(startTime) || isNaN(responseEnd) || startTime > responseEnd) {
            cell.textContent = zeroWidthSpace;
            return;
        }

        if (responseEnd < graphStartTime) {
            cell.textContent = zeroWidthSpace;
            return;
        }

        let graphEndTime = this._waterfallTimelineRuler.endTime;
        if (startTime > graphEndTime) {
            cell.textContent = zeroWidthSpace;
            return;
        }

        let lastEndTimestamp = NaN;
        function appendBlock(startTimestamp, endTimestamp, className) {
            if (isNaN(startTimestamp) || isNaN(endTimestamp))
                return null;

            if (Math.abs(startTimestamp - lastEndTimestamp) < secondsPerPixel * 2)
                startTimestamp = lastEndTimestamp;
            lastEndTimestamp = endTimestamp;

            let block = container.appendChild(document.createElement("div"));
            block.classList.add("block", className);
            positionByStartOffset(block, startTimestamp);
            setWidthForDuration(block, startTimestamp, endTimestamp);
            return block;
        }

        // Mouse block sits on top and accepts mouse events on this group.
        let padSeconds = 10 * secondsPerPixel;
        let mouseBlock = appendBlock(startTime - padSeconds, responseEnd + padSeconds, "mouse-tracking");
        mouseBlock.addEventListener("mousedown", (event) => {
            if (event.button !== 0 || event.ctrlKey)
                return;
            this._handleResourceEntryMousedownWaterfall(entry);
        });

        // Super small visualization.
        let totalWidth = (responseEnd - startTime) / secondsPerPixel;
        if (totalWidth <= 3) {
            let twoPixels = secondsPerPixel * 2;
            appendBlock(startTime, startTime + twoPixels, "queue");
            appendBlock(startTime + twoPixels, startTime + (2 * twoPixels), "response");
            return;
        }

        appendBlock(startTime, responseEnd, "filler");

        // FIXME: <https://webkit.org/b/190214> Web Inspector: expose full load metrics for redirect requests
        appendBlock(redirectStart, redirectEnd, "redirect");

        if (domainLookupStart) {
            appendBlock(fetchStart, domainLookupStart, "queue");
            appendBlock(domainLookupStart, domainLookupEnd || connectStart || requestStart, "dns");
        } else if (connectStart)
            appendBlock(fetchStart, connectStart, "queue");
        else if (requestStart)
            appendBlock(fetchStart, requestStart, "queue");
        if (connectStart)
            appendBlock(connectStart, secureConnectionStart || connectEnd, "connect");
        if (secureConnectionStart)
            appendBlock(secureConnectionStart, connectEnd, "secure");
        appendBlock(requestStart, responseStart, "request");
        appendBlock(responseStart, responseEnd, "response");
    }

    _generateSortComparator()
    {
        let sortColumnIdentifier = this._table.sortColumnIdentifier;
        if (!sortColumnIdentifier) {
            this._entriesSortComparator = null;
            return;
        }

        let comparator;

        switch (sortColumnIdentifier) {
        case "name":
        case "domain":
        case "mimeType":
        case "method":
        case "scheme":
        case "protocol":
        case "initiator":
        case "remoteAddress":
            // Simple string.
            comparator = (a, b) => (a[sortColumnIdentifier] || "").extendedLocaleCompare(b[sortColumnIdentifier] || "");
            break;

        case "status":
        case "connectionIdentifier":
        case "resourceSize":
        case "time":
            // Simple number.
            comparator = (a, b) => {
                let aValue = a[sortColumnIdentifier];
                if (isNaN(aValue))
                    return 1;
                let bValue = b[sortColumnIdentifier];
                if (isNaN(bValue))
                    return -1;
                return aValue - bValue;
            };
            break;

        case "priority":
            // Resource.NetworkPriority enum.
            comparator = (a, b) => WI.Resource.comparePriority(a.priority, b.priority);
            break;

        case "type":
            // Sort by displayType string.
            comparator = (a, b) => (a.displayType || "").extendedLocaleCompare(b.displayType || "");
            break;

        case "transferSize":
            // Handle (memory) and (disk) values.
            comparator = (a, b) => {
                let transferSizeA = a.transferSize;
                let transferSizeB = b.transferSize;

                // Treat NaN as the largest value.
                if (isNaN(transferSizeA))
                    return 1;
                if (isNaN(transferSizeB))
                    return -1;

                // Treat memory cache and disk cache as small values.
                let sourceA = a.resource.responseSource;
                if (sourceA === WI.Resource.ResponseSource.MemoryCache)
                    transferSizeA = -20;
                else if (sourceA === WI.Resource.ResponseSource.DiskCache)
                    transferSizeA = -10;
                else if (sourceA === WI.Resource.ResponseSource.ServiceWorker)
                    transferSizeA = -5;
                else if (sourceA === WI.Resource.ResponseSource.InspectorOverride)
                    transferSizeA = -3;

                let sourceB = b.resource.responseSource;
                if (sourceB === WI.Resource.ResponseSource.MemoryCache)
                    transferSizeB = -20;
                else if (sourceB === WI.Resource.ResponseSource.DiskCache)
                    transferSizeB = -10;
                else if (sourceB === WI.Resource.ResponseSource.ServiceWorker)
                    transferSizeB = -5;
                else if (sourceB === WI.Resource.ResponseSource.InspectorOverride)
                    transferSizeB = -3;

                return transferSizeA - transferSizeB;
            };
            break;

        case "waterfall":
            // Sort by startTime number.
            comparator = (a, b) => a.startTime - b.startTime;
            break;

        default:
            console.assert("Unexpected sort column", sortColumnIdentifier);
            return;
        }

        let reverseFactor = this._table.sortOrder === WI.Table.SortOrder.Ascending ? 1 : -1;

        // If the entry has an `initiatorNode`, use that node's "first" resource as the value of
        // `entry`, so long as the entry being compared to doesn't have the same `initiatorNode`.
        // This will ensure that all resource entries for a given `initiatorNode` will appear right
        // next to each other, as they will all effectively be sorted by the first resource.
        let substitute = (entry, other) => {
            if (WI.settings.groupMediaRequestsByDOMNode.value && entry.resource.initiatorNode) {
                let nodeEntry = this._domNodeEntries.get(entry.resource.initiatorNode);
                if (!nodeEntry.initiatedResourceEntries.includes(other))
                    return nodeEntry.initiatedResourceEntries[0];
            }
            return entry;
        };

        this._entriesSortComparator = (a, b) => reverseFactor * comparator(substitute(a, b), substitute(b, a));
    }

    // Protected

    initialLayout()
    {
        super.initialLayout();

        this.element.style.setProperty("--node-waterfall-dom-event-size", NetworkTableContentView.nodeWaterfallDOMEventSize + "px");

        this._waterfallTimelineRuler = new WI.TimelineRuler;
        this._waterfallTimelineRuler.allowsClippedLabels = true;

        this._nameColumn = new WI.TableColumn("name", WI.UIString("Name"), {
            minWidth: WI.Sidebar.AbsoluteMinimumWidth,
            maxWidth: 500,
            initialWidth: this._nameColumnWidthSetting.value,
            resizeType: WI.TableColumn.ResizeType.Locked,
        });

        this._domainColumn = new WI.TableColumn("domain", WI.UIString("Domain"), {
            minWidth: 120,
            maxWidth: 200,
            initialWidth: 150,
        });

        this._typeColumn = new WI.TableColumn("type", WI.UIString("Type"), {
            minWidth: 70,
            maxWidth: 120,
            initialWidth: 90,
        });

        this._mimeTypeColumn = new WI.TableColumn("mimeType", WI.UIString("MIME Type"), {
            hidden: true,
            minWidth: 100,
            maxWidth: 150,
            initialWidth: 120,
        });

        this._methodColumn = new WI.TableColumn("method", WI.UIString("Method"), {
            hidden: true,
            minWidth: 55,
            maxWidth: 80,
            initialWidth: 65,
        });

        this._schemeColumn = new WI.TableColumn("scheme", WI.UIString("Scheme"), {
            hidden: true,
            minWidth: 55,
            maxWidth: 80,
            initialWidth: 65,
        });

        this._statusColumn = new WI.TableColumn("status", WI.UIString("Status"), {
            hidden: true,
            minWidth: 50,
            maxWidth: 50,
            align: "left",
        });

        this._protocolColumn = new WI.TableColumn("protocol", WI.UIString("Protocol"), {
            hidden: true,
            minWidth: 65,
            maxWidth: 80,
            initialWidth: 75,
        });

        this._initiatorColumn = new WI.TableColumn("initiator", WI.UIString("Initiator"), {
            hidden: true,
            minWidth: 75,
            maxWidth: 175,
            initialWidth: 125,
        });

        this._priorityColumn = new WI.TableColumn("priority", WI.UIString("Priority"), {
            hidden: true,
            minWidth: 65,
            maxWidth: 80,
            initialWidth: 70,
        });

        this._remoteAddressColumn = new WI.TableColumn("remoteAddress", WI.UIString("IP Address"), {
            hidden: true,
            minWidth: 150,
        });

        this._connectionIdentifierColumn = new WI.TableColumn("connectionIdentifier", WI.UIString("Connection ID"), {
            hidden: true,
            minWidth: 50,
            maxWidth: 120,
            initialWidth: 80,
            align: "right",
        });

        this._resourceSizeColumn = new WI.TableColumn("resourceSize", WI.UIString("Resource Size"), {
            hidden: true,
            minWidth: 80,
            maxWidth: 100,
            initialWidth: 80,
            align: "right",
        });

        this._transferSizeColumn = new WI.TableColumn("transferSize", WI.UIString("Transfer Size", "Amount of data sent over the network for a single resource"), {
            minWidth: 100,
            maxWidth: 150,
            initialWidth: 100,
            align: "right",
        });

        this._timeColumn = new WI.TableColumn("time", WI.UIString("Time"), {
            minWidth: 65,
            maxWidth: 90,
            initialWidth: 65,
            align: "right",
        });

        this._waterfallColumn = new WI.TableColumn("waterfall", WI.UIString("Waterfall"), {
            minWidth: 230,
            headerView: this._waterfallTimelineRuler,
            needsReloadOnResize: true,
        });

        this._nameColumn.addEventListener(WI.TableColumn.Event.WidthDidChange, this._tableNameColumnDidChangeWidth, this);
        this._waterfallColumn.addEventListener(WI.TableColumn.Event.WidthDidChange, this._tableWaterfallColumnDidChangeWidth, this);

        this._table = new WI.Table("network-table", this, this, 20);

        this._table.addColumn(this._nameColumn);
        this._table.addColumn(this._domainColumn);
        this._table.addColumn(this._typeColumn);
        this._table.addColumn(this._mimeTypeColumn);
        this._table.addColumn(this._methodColumn);
        this._table.addColumn(this._schemeColumn);
        this._table.addColumn(this._statusColumn);
        this._table.addColumn(this._protocolColumn);
        this._table.addColumn(this._initiatorColumn);
        this._table.addColumn(this._priorityColumn);
        this._table.addColumn(this._remoteAddressColumn);
        this._table.addColumn(this._connectionIdentifierColumn);
        this._table.addColumn(this._resourceSizeColumn);
        this._table.addColumn(this._transferSizeColumn);
        this._table.addColumn(this._timeColumn);
        this._table.addColumn(this._waterfallColumn);

        if (!this._table.sortColumnIdentifier) {
            this._table.sortOrder = WI.Table.SortOrder.Ascending;
            this._table.sortColumnIdentifier = "waterfall";
        }

        this.addSubview(this._table);

        let statisticsContainer = this.element.appendChild(document.createElement("div"));
        statisticsContainer.className = "statistics";

        let createStatisticElement = (name, image) => {
            let statistic = this._statistics[name];
            if (!statistic)
                statistic = this._statistics[name] = {};

            statistic.container = statisticsContainer.appendChild(document.createElement("div"));
            statistic.container.classList.add("statistic", name);

            statistic.container.appendChild(WI.ImageUtilities.useSVGSymbol(image, "icon"));

            statistic.element = statistic.container.appendChild(document.createElement("div"));
            statistic.element.className = "text";
        };
        createStatisticElement("domain-count", "Images/Origin.svg");
        createStatisticElement("resource-count", "Images/Resources.svg");
        createStatisticElement("resource-size", "Images/Weight.svg");
        createStatisticElement("transfer-size", "Images/Network.svg");
        createStatisticElement("redirect-count", "Images/StepOver.svg");
        createStatisticElement("load-time", "Images/Time.svg");

        this._updateStatistics();
    }

    layout()
    {
        this._updateWaterfallTimelineRuler();
        this._processPendingEntries();
        this._positionDetailView();
        this._updateExportButton();
    }

    didLayoutSubtree()
    {
        super.didLayoutSubtree();

        if (this._waterfallPopover)
            this._waterfallPopover.resize();
    }

    processHAR(result)
    {
        let resources = WI.networkManager.processHAR(result);
        if (!resources)
            return;

        let importedCollection = this._addCollection();

        let displayName = WI.UIString("Imported - %s").format(result.filename);
        this._addCollectionPathComponent(importedCollection, displayName, "network-har-icon");

        this._changeCollection(importedCollection);

        for (let resource of resources)
            this._insertResourceAndReloadTable(resource);

        this._updateStatistics();
    }

    handleClearShortcut(event)
    {
        if (!this._isShowingMainCollection())
            return;

        this.reset();
    }

    // Private

    _updateWaterfallTimeRange(startTimestamp, endTimestamp)
    {
        let collection = this._activeCollection;

        if (isNaN(collection.waterfallStartTime) || startTimestamp < collection.waterfallStartTime)
            collection.waterfallStartTime = startTimestamp;

        if (isNaN(collection.waterfallEndTime) || endTimestamp > collection.waterfallEndTime)
            collection.waterfallEndTime = endTimestamp;
    }

    _updateWaterfallTimelineRuler()
    {
        if (!this._waterfallTimelineRuler)
            return;

        let collection = this._activeCollection;

        if (isNaN(collection.waterfallStartTime)) {
            this._waterfallTimelineRuler.zeroTime = 0;
            this._waterfallTimelineRuler.startTime = 0;
            this._waterfallTimelineRuler.endTime = 0.250;
        } else {
            this._waterfallTimelineRuler.zeroTime = collection.waterfallStartTime;
            this._waterfallTimelineRuler.startTime = collection.waterfallStartTime;
            this._waterfallTimelineRuler.endTime = collection.waterfallEndTime;

            // Add a little bit of padding on the each side.
            const paddingPixels = 5;
            let padSeconds = paddingPixels * this._waterfallTimelineRuler.secondsPerPixel;
            this._waterfallTimelineRuler.zeroTime = collection.waterfallStartTime - padSeconds;
            this._waterfallTimelineRuler.startTime = collection.waterfallStartTime - padSeconds;
            this._waterfallTimelineRuler.endTime = collection.waterfallEndTime + padSeconds;
        }
    }

    _canExportHAR()
    {
        if (!this._isShowingMainCollection())
            return false;

        let mainFrame = WI.networkManager.mainFrame;
        if (!mainFrame)
            return false;

        let mainResource = mainFrame.mainResource;
        if (!mainResource)
            return false;

        if (!mainResource.requestSentDate)
            return false;

        if (!this._HARResources().length)
            return false;

        return true;
    }

    _updateExportButton()
    {
        this._harExportNavigationItem.enabled = this._canExportHAR();
    }

    _processPendingEntries()
    {
        let collection = this._activeCollection;
        let needsSort = collection.pendingUpdates.length > 0;

        // No global sort is needed, so just insert new records into their sorted position.
        if (!needsSort) {
            let originalLength = collection.pendingInsertions.length;
            for (let resource of collection.pendingInsertions)
                this._insertResourceAndReloadTable(resource);
            console.assert(collection.pendingInsertions.length === originalLength);
            collection.pendingInsertions = [];
            this._updateStatistics();
            return;
        }

        for (let resource of collection.pendingInsertions) {
            let resourceEntry = this._entryForResource(resource);
            this._tryLinkResourceToDOMNode(resourceEntry);
            collection.entries.push(resourceEntry);
        }
        collection.pendingInsertions = [];

        for (let updateObject of collection.pendingUpdates) {
            if (updateObject instanceof WI.Resource)
                this._updateEntryForResource(updateObject);
        }
        collection.pendingUpdates = [];

        this._updateSort();
        this._updateFilteredEntries();
        this._reloadTable();
        this._updateStatistics();
    }

    _populateWithInitialResourcesIfNeeded(collection)
    {
        if (!this._needsInitialPopulate)
            return;

        this._needsInitialPopulate = false;

        let populateResourcesForFrame = (frame) => {
            if (frame.provisionalMainResource)
                collection.pendingInsertions.push(frame.provisionalMainResource);
            else if (frame.mainResource)
                collection.pendingInsertions.push(frame.mainResource);

            for (let resource of frame.resourceCollection)
                collection.pendingInsertions.push(resource);

            for (let childFrame of frame.childFrameCollection)
                populateResourcesForFrame(childFrame);
        };

        let populateResourcesForTarget = (target) => {
            if (target.mainResource instanceof WI.Resource)
                collection.pendingInsertions.push(target.mainResource);
            for (let resource of target.resourceCollection)
                collection.pendingInsertions.push(resource);
        };

        for (let target of WI.targets) {
            if (target === WI.pageTarget)
                populateResourcesForFrame(WI.networkManager.mainFrame);
            else
                populateResourcesForTarget(target);
        }

        this.needsLayout();
    }

    _checkURLFilterAgainstResource(resource)
    {
        if (this._urlFilterSearchRegex.test(resource.url)) {
            this._activeURLFilterResources.add(resource);
            return;
        }

        for (let redirect of resource.redirects) {
            if (this._urlFilterSearchRegex.test(redirect.url)) {
                this._activeURLFilterResources.add(resource);
                return;
            }
        }
    }

    _rowIndexForRepresentedObject(object)
    {
        return this._activeCollection.filteredEntries.findIndex((x) => {
            if (x.resource === object)
                return true;
            if (x.domNode === object)
                return true;
            return false;
        });
    }

    _updateEntryForResource(resource)
    {
        let collection = this._activeCollection;

        let index = collection.entries.findIndex((x) => x.resource === resource);
        if (index === -1)
            return;

        // Don't wipe out the previous entry, as it may be used by a node entry.
        function updateExistingEntry(existingEntry, newEntry) {
            for (let key in newEntry)
                existingEntry[key] = newEntry[key];
        }

        let entry = this._entryForResource(resource);
        updateExistingEntry(collection.entries[index], entry);

        let rowIndex = this._rowIndexForRepresentedObject(resource);
        if (rowIndex === -1)
            return;

        updateExistingEntry(collection.filteredEntries[rowIndex], entry);

        this._updateStatistics();
    }

    _hidePopover()
    {
        if (this._waterfallPopover)
            this._waterfallPopover.dismiss();
    }

    _hideDetailView()
    {
        if (!this._detailView)
            return;

        this.element.classList.remove("showing-detail");
        this._table.scrollContainer.style.removeProperty("width");

        this.removeSubview(this._detailView);

        this._detailView.hidden();
        this._detailView = null;

        this._table.updateLayout(WI.View.LayoutReason.Resize);
        this._table.reloadVisibleColumnCells(this._waterfallColumn);
    }

    _showDetailView(object)
    {
        let oldDetailView = this._detailView;

        this._detailView = this._detailViewMap.get(object);
        if (this._detailView === oldDetailView)
            return;

        if (!this._detailView) {
            if (object instanceof WI.Resource)
                this._detailView = new WI.NetworkResourceDetailView(object, this);
            else if (object instanceof WI.DOMNode) {
                this._detailView = new WI.NetworkDOMNodeDetailView(object, this);
            }

            this._detailViewMap.set(object, this._detailView);
        }

        if (oldDetailView) {
            oldDetailView.hidden();
            this.replaceSubview(oldDetailView, this._detailView);
        } else
            this.addSubview(this._detailView);

        if (this._showingRepresentedObjectCookie)
            this._detailView.willShowWithCookie(this._showingRepresentedObjectCookie);

        this._detailView.shown();

        this.element.classList.add("showing-detail");
        this._table.scrollContainer.style.width = this._nameColumn.width + "px";

        // FIXME: It would be nice to avoid this.
        // Currently the ResourceDetailView is in the heirarchy but has not yet done a layout so we
        // end up seeing the table behind it. This forces us to layout now instead of after a beat.
        this.updateLayout();
    }

    _positionDetailView()
    {
        if (!this._detailView)
            return;

        let side = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
        this._detailView.element.style[side] = this._nameColumn.width + "px";
        this._table.scrollContainer.style.width = this._nameColumn.width + "px";
    }

    _updateEmptyFilterResultsMessage()
    {
        if (this._hasActiveFilter() && !this._activeCollection.filteredEntries.length)
            this._showEmptyFilterResultsMessage();
        else
            this._hideEmptyFilterResultsMessage();
    }

    _showEmptyFilterResultsMessage()
    {
        if (!this._emptyFilterResultsMessageElement) {
            let buttonElement = document.createElement("button");
            buttonElement.textContent = WI.UIString("Clear Filters");
            buttonElement.addEventListener("click", () => { this._resetFilters(); });

            this._emptyFilterResultsMessageElement = WI.createMessageTextView(WI.UIString("No Filter Results"));
            this._emptyFilterResultsMessageElement.appendChild(buttonElement);
        }

        this.element.appendChild(this._emptyFilterResultsMessageElement);
    }

    _hideEmptyFilterResultsMessage()
    {
        if (!this._emptyFilterResultsMessageElement)
            return;

        this._emptyFilterResultsMessageElement.remove();
    }

    _clearNetworkOnNavigateSettingChanged()
    {
        this._clearOnLoadNavigationItem.checked = !WI.settings.clearNetworkOnNavigate.value;
    }

    _resourceCachingDisabledSettingChanged()
    {
        this._disableResourceCacheNavigationItem.activated = WI.settings.resourceCachingDisabled.value;
    }

    _toggleDisableResourceCache()
    {
        WI.settings.resourceCachingDisabled.value = !WI.settings.resourceCachingDisabled.value;
    }

    _mainResourceDidChange(event)
    {
        let frame = event.target;

        if (frame.isMainFrame() && !this._transitioningPageTarget)
            this._startUpdatingLoadTimeStatistic();

        this._runForMainCollection((collection, wasMain) => {
            if (frame.isMainFrame()) {
                if (WI.settings.clearNetworkOnNavigate.value) {
                    this._resetCollection(collection);

                    if (wasMain && !this._needsInitialPopulate)
                        this._hideDetailView();
                } else {
                    for (let entry of collection.entries)
                        entry.currentSession = false;
                }
            }

            if (this._transitioningPageTarget) {
                this._transitioningPageTarget = false;
                this._needsInitialPopulate = true;
                this._populateWithInitialResourcesIfNeeded(collection);
            } else
                this._insertResourceAndReloadTable(frame.mainResource);

            if (wasMain)
                this._updateStatistics();
        });
    }

    _mainFrameDidChange()
    {
        this._runForMainCollection((collection) => {
            this._populateWithInitialResourcesIfNeeded(collection);
        });
    }

    _resourceLoadingDidFinish(event)
    {
        this._runForMainCollection((collection, wasMain) => {
            let resource = event.target;
            collection.pendingUpdates.push(resource);

            this._updateWaterfallTimeRange(resource.firstTimestamp, resource.timingData.responseEnd);

            if (this._hasURLFilter())
                this._checkURLFilterAgainstResource(resource);

            if (wasMain)
                this.needsLayout();
        });
    }

    _resourceLoadingDidFail(event)
    {
        this._runForMainCollection((collection, wasMain) => {
            let resource = event.target;
            collection.pendingUpdates.push(resource);

            this._updateWaterfallTimeRange(resource.firstTimestamp, resource.timingData.responseEnd);

            if (this._hasURLFilter())
                this._checkURLFilterAgainstResource(resource);

            if (wasMain)
                this.needsLayout();
        });
    }

    _handleResourceSizeDidChange(event)
    {
        if (!this._table)
            return;

        this._runForMainCollection((collection, wasMain) => {
            let resource = event.target;

            // In the unlikely event that this is the sort column, we may need to resort.
            if (this._table.sortColumnIdentifier === "resourceSize") {
                collection.pendingUpdates.push(resource);
                this.needsLayout();
                return;
            }

            let index = collection.entries.findIndex((x) => x.resource === resource);
            if (index === -1)
                return;

            let entry = collection.entries[index];
            entry.resourceSize = resource.size;

            if (!wasMain)
                return;

            let rowIndex = this._rowIndexForRepresentedObject(resource);
            if (rowIndex === -1)
                return;

            this._table.reloadCell(rowIndex, "resourceSize");

            this._updateStatistics();
        });
    }

    _resourceTransferSizeDidChange(event)
    {
        if (!this._table)
            return;

        this._runForMainCollection((collection, wasMain) => {
            let resource = event.target;

            // In the unlikely event that this is the sort column, we may need to resort.
            if (this._table.sortColumnIdentifier === "transferSize") {
                collection.pendingUpdates.push(resource);
                this.needsLayout();
                return;
            }

            let index = collection.entries.findIndex((x) => x.resource === resource);
            if (index === -1)
                return;

            let entry = collection.entries[index];
            entry.transferSize = !isNaN(resource.networkTotalTransferSize) ? resource.networkTotalTransferSize : resource.estimatedTotalTransferSize;

            if (!wasMain)
                return;

            let rowIndex = this._rowIndexForRepresentedObject(resource);
            if (rowIndex === -1)
                return;

            this._table.reloadCell(rowIndex, "transferSize");

            this._updateStatistics();
        });
    }

    _handleResourceAdded(event)
    {
        this._runForMainCollection((collection, wasMain) => {
            this._insertResourceAndReloadTable(event.data.resource);

            if (wasMain)
                this._updateStatistics();
        });
    }

    _handleFrameWasAdded(event)
    {
        if (this._needsInitialPopulate)
            return;

        this._runForMainCollection((collection, wasMain) => {
            let frame = event.data.childFrame;
            let mainResource = frame.provisionalMainResource || frame.mainResource;
            console.assert(mainResource, "Frame should have a main resource.");
            this._insertResourceAndReloadTable(mainResource);

            if (wasMain)
                this._updateStatistics();

            console.assert(!frame.resourceCollection.size, "New frame should be empty.");
            console.assert(!frame.childFrameCollection.size, "New frame should be empty.");
        });
    }

    _runForMainCollection(callback)
    {
        let currentCollection = this._activeCollection;
        let wasMain = currentCollection === this._mainCollection;

        if (!wasMain)
            this._setActiveCollection(this._mainCollection);

        callback(this._activeCollection, wasMain);

        if (!wasMain)
            this._setActiveCollection(currentCollection);
    }

    _isShowingMainCollection()
    {
        return this._activeCollection === this._mainCollection;
    }

    _isDefaultSort()
    {
        return this._table.sortColumnIdentifier === "waterfall" && this._table.sortOrder === WI.Table.SortOrder.Ascending;
    }

    _insertResourceAndReloadTable(resource)
    {
        if (this._needsInitialPopulate)
            return;

        let collection = this._activeCollection;

        this._updateWaterfallTimeRange(resource.firstTimestamp, resource.timingData.responseEnd);

        if (!this._table || !(WI.tabBrowser.selectedTabContentView instanceof WI.NetworkTabContentView)) {
            collection.pendingInsertions.push(resource);
            this.needsLayout();
            return;
        }

        let resourceEntry = this._entryForResource(resource);

        this._tryLinkResourceToDOMNode(resourceEntry);

        if (WI.settings.groupMediaRequestsByDOMNode.value && resource.initiatorNode) {
            if (!this._entriesSortComparator)
                this._generateSortComparator();
        } else if (this._isDefaultSort() || !this._entriesSortComparator) {
            // Default sort has fast path.
            collection.entries.push(resourceEntry);
            if (this._passFilter(resourceEntry)) {
                collection.filteredEntries.push(resourceEntry);
                this._table.reloadDataAddedToEndOnly();
            }
            return;
        }

        insertObjectIntoSortedArray(resourceEntry, collection.entries, this._entriesSortComparator);

        if (this._passFilter(resourceEntry)) {
            if (WI.settings.groupMediaRequestsByDOMNode.value)
                this._updateFilteredEntries();
            else
                insertObjectIntoSortedArray(resourceEntry, collection.filteredEntries, this._entriesSortComparator);

            // Probably a useless optimization here, but if we only added this row to the end
            // we may avoid recreating all visible rows by saying as such.
            if (collection.filteredEntries.lastValue === resourceEntry)
                this._table.reloadDataAddedToEndOnly();
            else
                this._reloadTable();
        }
    }

    _entryForResource(resource)
    {
        // FIXME: <https://webkit.org/b/143632> Web Inspector: Resources with the same name in different folders aren't distinguished
        // FIXME: <https://webkit.org/b/176765> Web Inspector: Resource names should be less ambiguous

        return {
            resource,
            name: WI.displayNameForURL(resource.url, resource.urlComponents),
            domain: WI.displayNameForHost(resource.urlComponents.host),
            scheme: resource.urlComponents.scheme ? resource.urlComponents.scheme.toLowerCase() : "",
            method: resource.requestMethod,
            type: resource.type,
            displayType: WI.NetworkTableContentView.displayNameForResource(resource),
            mimeType: resource.mimeType,
            status: resource.statusCode,
            cached: resource.cached,
            resourceSize: resource.size,
            transferSize: !isNaN(resource.networkTotalTransferSize) ? resource.networkTotalTransferSize : resource.estimatedTotalTransferSize,
            time: resource.totalDuration,
            protocol: resource.protocol,
            initiator: resource.initiatorSourceCodeLocation ? resource.initiatorSourceCodeLocation.displayLocationString() : "",
            priority: resource.priority,
            remoteAddress: resource.remoteAddress,
            connectionIdentifier: resource.connectionIdentifier,
            startTime: resource.firstTimestamp,
            currentSession: true,
        };
    }

    _entryForDOMNode(domNode)
    {
        return {
            domNode,
            initiatedResourceEntries: [],
            domEventElements: new Map,
            expanded: true,
        };
    }

    _tryLinkResourceToDOMNode(resourceEntry)
    {
        let resource = resourceEntry.resource;
        if (!resource || !resource.initiatorNode)
            return;

        let nodeEntry = this._domNodeEntries.get(resource.initiatorNode);
        if (!nodeEntry) {
            nodeEntry = this._entryForDOMNode(resource.initiatorNode, Object.keys(resourceEntry));
            this._domNodeEntries.set(resource.initiatorNode, nodeEntry);

            resource.initiatorNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleNodeDidFireEvent, this);
            if (resource.initiatorNode.canEnterPowerEfficientPlaybackState())
                resource.initiatorNode.addEventListener(WI.DOMNode.Event.PowerEfficientPlaybackStateChanged, this._handleDOMNodePowerEfficientPlaybackStateChanged, this);
        }

        if (!this._entriesSortComparator)
            this._generateSortComparator();

        insertObjectIntoSortedArray(resourceEntry, nodeEntry.initiatedResourceEntries, this._entriesSortComparator);
    }

    _uniqueValuesForDOMNodeEntry(nodeEntry, accessor)
    {
        let resourceEntries = nodeEntry.initiatedResourceEntries;
        if (!resourceEntries)
            return null;

        return resourceEntries.reduce((accumulator, current) => {
            let value = accessor(current);
            if (value || typeof value === "number")
                accumulator.add(value);
            return accumulator;
        }, new Set);
    }

    _handleNodeDidFireEvent(event)
    {
        this._runForMainCollection((collection, wasMain) => {
            let domNode = event.target;
            let {domEvent} = event.data;

            collection.pendingUpdates.push(domNode);

            this._updateWaterfallTimeRange(NaN, domEvent.timestamp + (this._waterfallTimelineRuler.secondsPerPixel * 10));

            if (wasMain)
                this.needsLayout();
        });
    }

    _handleDOMNodePowerEfficientPlaybackStateChanged(event)
    {
        this._runForMainCollection((collection, wasMain) => {
            let domNode = event.target;
            let {timestamp} = event.data;

            collection.pendingUpdates.push(domNode);

            this._updateWaterfallTimeRange(NaN, timestamp + (this._waterfallTimelineRuler.secondsPerPixel * 10));

            if (wasMain)
                this.needsLayout();
        });
    }

    _hasTypeFilter()
    {
        return !!this._activeTypeFilters;
    }

    _hasURLFilter()
    {
        return this._urlFilterIsActive;
    }

    _hasActiveFilter()
    {
        return this._hasTypeFilter()
            || this._hasURLFilter();
    }

    _passTypeFilter(entry)
    {
        if (!this._hasTypeFilter())
            return true;
        return this._activeTypeFilters.some((checker) => checker(entry.resource.type));
    }

    _passURLFilter(entry)
    {
        if (!this._hasURLFilter())
            return true;
        return this._activeURLFilterResources.has(entry.resource);
    }

    _passFilter(entry)
    {
        return this._passTypeFilter(entry)
            && this._passURLFilter(entry);
    }

    _updateSort()
    {
        if (this._entriesSortComparator) {
            let collection = this._activeCollection;
            collection.entries = collection.entries.sort(this._entriesSortComparator);
        }
    }

    _updateFilteredEntries()
    {
        let collection = this._activeCollection;

        if (this._hasActiveFilter())
            collection.filteredEntries = collection.entries.filter(this._passFilter, this);
        else
            collection.filteredEntries = collection.entries.slice();

        if (WI.settings.groupMediaRequestsByDOMNode.value) {
            for (let nodeEntry of this._domNodeEntries.values()) {
                if (nodeEntry.initiatedResourceEntries.length < 2 && !nodeEntry.domNode.domEvents.length)
                    continue;

                let firstIndex = Infinity;
                for (let resourceEntry of nodeEntry.initiatedResourceEntries) {
                    if (this._hasActiveFilter() && !this._passFilter(resourceEntry))
                        continue;

                    let index = collection.filteredEntries.indexOf(resourceEntry);
                    if (index >= 0 && index < firstIndex)
                        firstIndex = index;
                }

                if (!isFinite(firstIndex))
                    continue;

                collection.filteredEntries.insertAtIndex(nodeEntry, firstIndex);
            }

            collection.filteredEntries = collection.filteredEntries.filter((entry) => {
                if (entry.resource && entry.resource.initiatorNode) {
                    let nodeEntry = this._domNodeEntries.get(entry.resource.initiatorNode);
                    if (!nodeEntry.expanded)
                        return false;
                }
                return true;
            });
        }

        this._updateStatistics();

        this._updateEmptyFilterResultsMessage();
    }

    _updateStatistics()
    {
        if (!this.didInitialLayout)
            return;

        let entries = this._activeCollection.filteredEntries.filter((entry) => entry.currentSession);

        let domains = new Set;
        let resourceSize = 0;
        let transferSize = 0;
        let redirectCount = 0;
        for (let entry of entries) {
            domains.add(entry.domain);
            if (!isNaN(entry.resourceSize))
                resourceSize += entry.resourceSize;
            if (!isNaN(entry.transferSize))
                transferSize += entry.transferSize;
            if (entry.resource)
                redirectCount += entry.resource.redirects.length;
        }

        this._updateStatistic("domain-count", domains.size === 1 ? WI.UIString("%d domain") : WI.UIString("%d domains"), domains.size);

        let resourceCount = entries.length;
        this._updateStatistic("resource-count", resourceCount === 1 ? WI.UIString("%d resource") : WI.UIString("%d resources"), resourceCount);

        const higherResolution = false;
        this._updateStatistic("resource-size", WI.UIString("%s total"), Number.bytesToString(resourceSize, higherResolution));
        this._updateStatistic("transfer-size", WI.UIString("%s transferred"), Number.bytesToString(transferSize, higherResolution));

        this._updateStatistic("redirect-count", redirectCount === 1 ? WI.UIString("%d redirect") : WI.UIString("%d redirects"), redirectCount);

        let loadTimeStatistic = this._statistics["load-time"];
        if (loadTimeStatistic.format && this._isShowingMainCollection() && !this._hasActiveFilter()) {
            this._updateStatistic("load-time");
            loadTimeStatistic.container.hidden = false;
        } else
            loadTimeStatistic.container.hidden = true;
    }

    _updateStatistic(name, format, value)
    {
        let statistic = this._statistics[name];

        if (format)
            statistic.format = format;
        else
            format = statistic.format;

        if (value || value === 0)
            statistic.value = value;
        else
            value = statistic.value;

        if (statistic.container)
            statistic.container.title = format.format(value);

        if (statistic.element)
            statistic.element.textContent = value;
    }

    _startUpdatingLoadTimeStatistic()
    {
        this._stopUpdatingLoadTimeStatistic();

        let loadTimeStatistic = this._statistics["load-time"];
        if (!loadTimeStatistic)
            loadTimeStatistic = this._statistics["load-time"] = {};

        loadTimeStatistic.start = Date.now();
        loadTimeStatistic.delay = 50;
        loadTimeStatistic.timer = setInterval(this._updateLoadTimeStatistic.bind(this), loadTimeStatistic.delay);
    }

    _stopUpdatingLoadTimeStatistic()
    {
        let loadTimeStatistic = this._statistics["load-time"];
        if (!loadTimeStatistic)
            return;

        if (loadTimeStatistic.timer) {
            clearInterval(loadTimeStatistic.timer);
            loadTimeStatistic.timer = undefined;
        }
    }

    _updateLoadTimeStatistic()
    {
        let loadTimeStatistic = this._statistics["load-time"];
        console.assert(loadTimeStatistic);

        let duration = Date.now() - loadTimeStatistic.start;

        let delay = loadTimeStatistic.delay;
        if (duration >= 1_000) // 1 second
            delay = 100;
        else if (duration >= 60_000) // 60 seconds
            delay = 1_000;
        else if (duration >= 3_600_000) // 1 minute
            delay = 10_000;

        if (delay !== loadTimeStatistic.delay) {
            loadTimeStatistic.delay = delay;

            clearInterval(loadTimeStatistic.timer);
            loadTimeStatistic.timer = setInterval(this._updateLoadTimeStatistic.bind(this), loadTimeStatistic.delay);
        }

        let mainFrame = WI.networkManager.mainFrame;
        let mainFrameStartTime = mainFrame.mainResource.firstTimestamp;
        let mainFrameLoadEventTime = mainFrame.loadEventTimestamp;

        if (loadTimeStatistic.container)
            loadTimeStatistic.container.hidden = !this._isShowingMainCollection() || this._hasActiveFilter();

        if (isNaN(mainFrameStartTime) || isNaN(mainFrameLoadEventTime)) {
            this._updateStatistic("load-time", WI.UIString("Loading for %s"), Number.secondsToString(duration / 1_000));
            return;
        }

        this._updateStatistic("load-time", WI.UIString("Loaded in %s"), Number.secondsToString(mainFrameLoadEventTime - mainFrameStartTime));

        this._stopUpdatingLoadTimeStatistic();
    }

    _reloadTable()
    {
        this._table.reloadData();
        this._restoreSelectedRow();
    }

    _generateTypeFilter()
    {
        let selectedItems = this._typeFilterScopeBar.selectedItems;
        if (!selectedItems.length || selectedItems.includes(this._typeFilterScopeBarItemAll))
            return null;

        return selectedItems.map((item) => item.__checker);
    }

    _resetFilters()
    {
        console.assert(this._hasActiveFilter());

        // Clear url filter.
        this._urlFilterSearchText = null;
        this._urlFilterSearchRegex = null;
        this._urlFilterIsActive = false;
        this._activeURLFilterResources.clear();
        this._urlFilterNavigationItem.filterBar.clear();
        console.assert(!this._hasURLFilter());

        // Clear type filter.
        this._typeFilterScopeBar.resetToDefault();
        console.assert(!this._hasTypeFilter());

        console.assert(!this._hasActiveFilter());

        this._updateFilteredEntries();
        this._reloadTable();
    }

    _areFilterListsIdentical(listA, listB)
    {
        if (listA && listB) {
            if (listA.length !== listB.length)
                return false;

            for (let i = 0; i < listA.length; ++i) {
                if (listA[i] !== listB[i])
                    return false;
            }

            return true;
        }

        return false;
    }

    _typeFilterScopeBarSelectionChanged(event)
    {
        // FIXME: <https://webkit.org/b/176763> Web Inspector: ScopeBar SelectionChanged event may dispatch multiple times for a single logical change
        // We can't use shallow equals here because the contents are functions.
        let oldFilter = this._activeTypeFilters;
        let newFilter = this._generateTypeFilter();
        if (this._areFilterListsIdentical(oldFilter, newFilter))
            return;

        // Even if the selected resource would still be visible, lets close the detail view if a filter changes.
        this._hideDetailView();

        this._activeTypeFilters = newFilter;
        this._updateFilteredEntries();
        this._reloadTable();
    }

    _handleGroupMediaRequestsByDOMNodeCheckedDidChange(event)
    {
        WI.settings.groupMediaRequestsByDOMNode.value = this._groupMediaRequestsByDOMNodeNavigationItem.checked;

        if (!WI.settings.groupMediaRequestsByDOMNode.value) {
            this._table.element.classList.remove("grouped");

            if (this._selectedObject && this._selectedObject instanceof WI.DOMNode) {
                this._selectedObject = null;
                this._hideDetailView();
            }
        }

        this._updateSort();
        this._updateFilteredEntries();
        this._reloadTable();
    }

    _urlFilterDidChange(event)
    {
        let filterBar = this._urlFilterNavigationItem.filterBar;
        let searchQuery = filterBar.filters.text;
        if (searchQuery === this._urlFilterSearchText)
            return;

        // Even if the selected resource would still be visible, lets close the detail view if a filter changes.
        this._hideDetailView();

        this._urlFilterSearchRegex = searchQuery ? WI.SearchUtilities.filterRegExpForString(searchQuery, WI.SearchUtilities.defaultSettings) : null;
        filterBar.invalid = searchQuery && !this._urlFilterSearchRegex

        // Search cleared.
        if (!this._urlFilterSearchRegex) {
            this._urlFilterSearchText = null;
            this._urlFilterSearchRegex = null;
            this._urlFilterIsActive = false;
            this._activeURLFilterResources.clear();

            this._updateFilteredEntries();
            this._reloadTable();
            return;
        }

        this._urlFilterIsActive = true;
        this._urlFilterSearchText = searchQuery;

        this._updateActiveFilterResources();
        this._updateFilteredEntries();
        this._reloadTable();
    }

    _updateActiveFilterResources()
    {
        this._activeURLFilterResources.clear();

        if (this._hasURLFilter()) {
            for (let entry of this._activeCollection.entries)
                this._checkURLFilterAgainstResource(entry.resource);
        }
    }

    _restoreSelectedRow()
    {
        if (!this._selectedObject)
            return;

        let rowIndex = this._rowIndexForRepresentedObject(this._selectedObject);
        if (rowIndex === -1) {
            this._selectedObject = null;
            this._table.deselectAll();
            return;
        }

        this._table.selectRow(rowIndex);
        this._showDetailView(this._selectedObject);
    }

    _HARResources()
    {
        let resources = this._activeCollection.filteredEntries.map((x) => x.resource);
        const supportedHARSchemes = new Set(["http", "https", "ws", "wss"]);
        return resources.filter((resource) => {
            if (!resource) {
                // DOM node entries are also added to `filteredEntries`.
                return false;
            }

            if (!resource.finished)
                return false;
            if (!resource.requestSentDate)
                return false;
            if (!supportedHARSchemes.has(resource.urlComponents.scheme))
                return false;
            return true;
        });
    }

    _exportHAR()
    {
        let resources = this._HARResources();
        if (!resources.length) {
            InspectorFrontendHost.beep();
            return;
        }

        WI.HARBuilder.buildArchive(resources).then((har) => {
            let mainFrame = WI.networkManager.mainFrame;
            let archiveName = mainFrame.mainResource.urlComponents.host || mainFrame.mainResource.displayName || "Archive";
            WI.FileUtilities.save({
                content: JSON.stringify(har, null, 2),
                suggestedName: archiveName + ".har",
                forceSaveAs: true,
            });
        });
    }

    _importHAR()
    {
        WI.FileUtilities.importJSON((result) => this.processHAR(result), {multiple: true});
    }

    _waterfallPopoverContent()
    {
        let contentElement = document.createElement("div");
        contentElement.classList.add("waterfall-popover-content");
        return contentElement;
    }

    _waterfallPopoverContentForResourceEntry(resourceEntry)
    {
        let contentElement = this._waterfallPopoverContent();

        let resource = resourceEntry.resource;
        if (!resource.hasResponse() || !resource.firstTimestamp || !resource.lastTimestamp) {
            contentElement.textContent = WI.UIString("Resource has no timing data");
            return contentElement;
        }

        let breakdownView = new WI.ResourceTimingBreakdownView(resource, 300);
        contentElement.appendChild(breakdownView.element);
        breakdownView.updateLayout();

        return contentElement;
    }

    _waterfallPopoverContentForNodeEntry(nodeEntry, domEvents)
    {
        let contentElement = this._waterfallPopoverContent();

        let breakdownView = new WI.DOMEventsBreakdownView(domEvents);
        contentElement.appendChild(breakdownView.element);
        breakdownView.updateLayout();

        return contentElement;
    }

    _handleResourceEntryMousedownWaterfall(resourceEntry)
    {
        let popoverContentElement = this._waterfallPopoverContentForResourceEntry(resourceEntry);
        this._handleMousedownWaterfall(resourceEntry, popoverContentElement, (cell) => {
            return cell.querySelector(".block.mouse-tracking");
        });
    }

    _handleNodeEntryMousedownWaterfall(nodeEntry, domEvents)
    {
        let popoverContentElement = this._waterfallPopoverContentForNodeEntry(nodeEntry, domEvents);
        this._handleMousedownWaterfall(nodeEntry, popoverContentElement, (cell) => {
            let domEventElement = nodeEntry.domEventElements.get(domEvents[0]);

            // Show any additional DOM events that have been merged into the range.
            if (domEventElement && this._waterfallPopover.visible) {
                let newDOMEvents = Array.from(nodeEntry.domEventElements)
                .filter(([domEvent, element]) => element === domEventElement)
                .map(([domEvent, element]) => domEvent);

                this._waterfallPopover.content = this._waterfallPopoverContentForNodeEntry(nodeEntry, newDOMEvents);
            }

            return domEventElement;
        });
    }

    _handleMousedownWaterfall(entry, popoverContentElement, updateTargetAndContentFunction)
    {
        if (!this._waterfallPopover) {
            this._waterfallPopover = new WI.Popover;
            this._waterfallPopover.element.classList.add("waterfall-popover");
        }

        if (this._waterfallPopover.visible)
            return;

        let calculateTargetFrame = () => {
            let rowIndex = this._rowIndexForRepresentedObject(entry.resource || entry.domNode);
            let cell = this._table.cellForRowAndColumn(rowIndex, this._waterfallColumn);
            if (cell) {
                let targetElement = updateTargetAndContentFunction(cell);
                if (targetElement)
                    return WI.Rect.rectFromClientRect(targetElement.getBoundingClientRect());
            }

            this._waterfallPopover.dismiss();
            return null;
        };

        let targetFrame = calculateTargetFrame();
        if (!targetFrame)
            return;
        if (!targetFrame.size.width && !targetFrame.size.height)
            return;

        let isRTL = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL;
        let preferredEdges = isRTL ? [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MAX_X] : [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MIN_X];
        this._waterfallPopover.windowResizeHandler = () => {
            let bounds = calculateTargetFrame();
            if (bounds)
                this._waterfallPopover.present(bounds, preferredEdges);
        };

        this._waterfallPopover.presentNewContentWithFrame(popoverContentElement, targetFrame, preferredEdges);
    }

    _tableNameColumnDidChangeWidth(event)
    {
        this._nameColumnWidthSetting.value = event.target.width;

        this._positionDetailView();
    }

    _tableWaterfallColumnDidChangeWidth(event)
    {
        this._table.reloadVisibleColumnCells(this._waterfallColumn);
    }

    _transitionPageTarget(event)
    {
        this._transitioningPageTarget = true;
    }
};
