/*
 * 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._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.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.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.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._checkboxesNavigationItemGroup.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;

        this._pathComponentsNavigationItemGroup = new WI.GroupNavigationItem([this._collectionsPathNavigationItem, new WI.DividerNavigationItem]);
        this._pathComponentsNavigationItemGroup.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
        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.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.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) => {
            this._resetCollection(collection);
        });

        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];

        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._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";
        }

        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);
        }

        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;
        cell.classList.add(...WI.Resource.classNamesForResource(resource));
    }

    _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)");
                return;
            }
            if (resourceEntries.every((resourceEntry) => resourceEntry.resource.responseSource === WI.Resource.ResponseSource.DiskCache)) {
                cell.classList.add("cache-type");
                cell.textContent = WI.UIString("(disk)");
                return;
            }
            if (resourceEntries.every((resourceEntry) => resourceEntry.resource.responseSource === WI.Resource.ResponseSource.ServiceWorker)) {
                cell.classList.add("cache-type");
                cell.textContent = WI.UIString("(service worker)");
                return;
            }
            let transferSize = resourceEntries.reduce((accumulator, current) => accumulator + (current.transferSize || 0), 0);
            if (isNaN(transferSize))
                cell.textContent = emDash;
            else
                cell.textContent = Number.bytesToString(transferSize);
            return;
        }

        let responseSource = entry.resource.responseSource;
        if (responseSource === WI.Resource.ResponseSource.MemoryCache) {
            cell.classList.add("cache-type");
            cell.textContent = WI.UIString("(memory)");
            return;
        }
        if (responseSource === WI.Resource.ResponseSource.DiskCache) {
            cell.classList.add("cache-type");
            cell.textContent = WI.UIString("(disk)");
            return;
        }
        if (responseSource === WI.Resource.ResponseSource.ServiceWorker) {
            cell.classList.add("cache-type");
            cell.textContent = WI.UIString("(service worker)");
            return;
        }
        if (responseSource === WI.Resource.ResponseSource.InspectorOverride) {
            cell.classList.add("cache-type");
            cell.textContent = WI.UIString("(inspector override)");
            return;
        }

        let transferSize = entry.transferSize;
        cell.textContent = isNaN(transferSize) ? emDash : Number.bytesToString(transferSize);
        console.assert(!cell.classList.contains("cache-type"), "Should not have cache-type class on cell.");
    }

    _populateWaterfallGraph(cell, entry)
    {
        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);
    }

    layout()
    {
        this._updateWaterfallTimelineRuler();
        this._processPendingEntries();
        this._positionDetailView();
        this._positionEmptyFilterMessage();
        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);
    }

    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 = [];
            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();
    }

    _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);
    }

    _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);
        this._positionEmptyFilterMessage();
    }

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

        this._emptyFilterResultsMessageElement.remove();
    }

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

        let width = this._nameColumn.width - 1; // For the 1px border.
        this._emptyFilterResultsMessageElement.style.width = width + "px";
    }

    _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)
    {
        this._runForMainCollection((collection, wasMain) => {
            let frame = event.target;
            if (frame.isMainFrame() && WI.settings.clearNetworkOnNavigate.value) {
                this._resetCollection(collection);

                if (wasMain && !this._needsInitialPopulate)
                    this._hideDetailView();
            }

            if (this._transitioningPageTarget) {
                this._transitioningPageTarget = false;
                this._needsInitialPopulate = true;
                this._populateWithInitialResourcesIfNeeded(collection);
                return;
            }

            this._insertResourceAndReloadTable(frame.mainResource);
        });
    }

    _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();
        });
    }

    _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");
        });
    }

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

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

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

            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,
        };
    }

    _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._updateEmptyFilterResultsMessage();
    }

    _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 searchQuery = this._urlFilterNavigationItem.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();

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

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

        this._urlFilterIsActive = true;
        this._urlFilterSearchText = searchQuery;
        this._urlFilterSearchRegex = WI.SearchUtilities.regExpForString(searchQuery, WI.SearchUtilities.defaultSettings);

        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({
                url: WI.FileUtilities.inspectorURLForFilename(archiveName + ".har"),
                content: JSON.stringify(har, null, 2),
                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();
        this._positionEmptyFilterMessage();
    }

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

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