/*
 * Copyright (C) 2007, 2008, 2010 Apple Inc.  All rights reserved.
 * Copyright (C) 2009 Joseph Pecoraro
 * Copyright (C) 2013 Samsung Electronics. 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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
 */
/**
 * @implements {SDK.TargetManager.Observer}
 * @unrestricted
 */
Resources.ApplicationPanelSidebar = class extends UI.VBox {
  /**
   * @param {!Resources.ResourcesPanel} panel
   */
  constructor(panel) {
    super();

    this._panel = panel;

    this._sidebarTree = new UI.TreeOutlineInShadow();
    this._sidebarTree.element.classList.add('resources-sidebar');
    this._sidebarTree.registerRequiredCSS('resources/resourcesSidebar.css');
    this._sidebarTree.element.classList.add('filter-all');
    // Listener needs to have been set up before the elements are added
    this._sidebarTree.addEventListener(UI.TreeOutline.Events.ElementAttached, this._treeElementAdded, this);

    this.contentElement.appendChild(this._sidebarTree.element);
    this._applicationTreeElement = this._addSidebarSection(Common.UIString('Application'));
    const manifestTreeElement = new Resources.AppManifestTreeElement(panel);
    this._applicationTreeElement.appendChild(manifestTreeElement);
    this.serviceWorkersTreeElement = new Resources.ServiceWorkersTreeElement(panel);
    this._applicationTreeElement.appendChild(this.serviceWorkersTreeElement);
    const clearStorageTreeElement = new Resources.ClearStorageTreeElement(panel);
    this._applicationTreeElement.appendChild(clearStorageTreeElement);

    const storageTreeElement = this._addSidebarSection(Common.UIString('Storage'));
    this.localStorageListTreeElement =
        new Resources.StorageCategoryTreeElement(panel, Common.UIString('Local Storage'), 'LocalStorage');
    this.localStorageListTreeElement.setLink(
        'https://developers.google.com/web/tools/chrome-devtools/storage/localstorage?utm_source=devtools');
    const localStorageIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
    this.localStorageListTreeElement.setLeadingIcons([localStorageIcon]);

    storageTreeElement.appendChild(this.localStorageListTreeElement);
    this.sessionStorageListTreeElement =
        new Resources.StorageCategoryTreeElement(panel, Common.UIString('Session Storage'), 'SessionStorage');
    this.sessionStorageListTreeElement.setLink(
        'https://developers.google.com/web/tools/chrome-devtools/storage/sessionstorage?utm_source=devtools');
    const sessionStorageIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
    this.sessionStorageListTreeElement.setLeadingIcons([sessionStorageIcon]);

    storageTreeElement.appendChild(this.sessionStorageListTreeElement);
    this.indexedDBListTreeElement = new Resources.IndexedDBTreeElement(panel);
    this.indexedDBListTreeElement.setLink(
        'https://developers.google.com/web/tools/chrome-devtools/storage/indexeddb?utm_source=devtools');
    storageTreeElement.appendChild(this.indexedDBListTreeElement);
    this.databasesListTreeElement =
        new Resources.StorageCategoryTreeElement(panel, Common.UIString('Web SQL'), 'Databases');
    this.databasesListTreeElement.setLink(
        'https://developers.google.com/web/tools/chrome-devtools/storage/websql?utm_source=devtools');
    const databaseIcon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
    this.databasesListTreeElement.setLeadingIcons([databaseIcon]);

    storageTreeElement.appendChild(this.databasesListTreeElement);
    this.cookieListTreeElement = new Resources.StorageCategoryTreeElement(panel, Common.UIString('Cookies'), 'Cookies');
    this.cookieListTreeElement.setLink(
        'https://developers.google.com/web/tools/chrome-devtools/storage/cookies?utm_source=devtools');
    const cookieIcon = UI.Icon.create('mediumicon-cookie', 'resource-tree-item');
    this.cookieListTreeElement.setLeadingIcons([cookieIcon]);
    storageTreeElement.appendChild(this.cookieListTreeElement);

    const cacheTreeElement = this._addSidebarSection(Common.UIString('Cache'));
    this.cacheStorageListTreeElement = new Resources.ServiceWorkerCacheTreeElement(panel);
    cacheTreeElement.appendChild(this.cacheStorageListTreeElement);
    this.applicationCacheListTreeElement =
        new Resources.StorageCategoryTreeElement(panel, Common.UIString('Application Cache'), 'ApplicationCache');
    this.applicationCacheListTreeElement.setLink(
        'https://developers.google.com/web/tools/chrome-devtools/storage/applicationcache?utm_source=devtools');
    const applicationCacheIcon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
    this.applicationCacheListTreeElement.setLeadingIcons([applicationCacheIcon]);

    cacheTreeElement.appendChild(this.applicationCacheListTreeElement);

    if (Root.Runtime.experiments.isEnabled('backgroundServices')) {
      const backgroundServiceTreeElement = this._addSidebarSection(ls`Background Services`);

      this.backgroundFetchTreeElement =
          new Resources.BackgroundServiceTreeElement(panel, Protocol.BackgroundService.ServiceName.BackgroundFetch);
      backgroundServiceTreeElement.appendChild(this.backgroundFetchTreeElement);
      this.backgroundSyncTreeElement =
          new Resources.BackgroundServiceTreeElement(panel, Protocol.BackgroundService.ServiceName.BackgroundSync);
      backgroundServiceTreeElement.appendChild(this.backgroundSyncTreeElement);

      if (Root.Runtime.experiments.isEnabled('backgroundServicesNotifications')) {
        this.notificationsTreeElement =
            new Resources.BackgroundServiceTreeElement(panel, Protocol.BackgroundService.ServiceName.Notifications);
        backgroundServiceTreeElement.appendChild(this.notificationsTreeElement);
      }
      if (Root.Runtime.experiments.isEnabled('backgroundServicesPaymentHandler')) {
        this.paymentHandlerTreeElement =
            new Resources.BackgroundServiceTreeElement(panel, Protocol.BackgroundService.ServiceName.PaymentHandler);
        backgroundServiceTreeElement.appendChild(this.paymentHandlerTreeElement);
      }
      if (Root.Runtime.experiments.isEnabled('backgroundServicesPeriodicBackgroundSync')) {
        this.periodicBackgroundSyncTreeElement = new Resources.BackgroundServiceTreeElement(
            panel, Protocol.BackgroundService.ServiceName.PeriodicBackgroundSync);
        backgroundServiceTreeElement.appendChild(this.periodicBackgroundSyncTreeElement);
      }
      if (Root.Runtime.experiments.isEnabled('backgroundServicesPushMessaging')) {
        this.pushMessagingTreeElement =
            new Resources.BackgroundServiceTreeElement(panel, Protocol.BackgroundService.ServiceName.PushMessaging);
        backgroundServiceTreeElement.appendChild(this.pushMessagingTreeElement);
      }
    }

    this._resourcesSection = new Resources.ResourcesSection(panel, this._addSidebarSection(Common.UIString('Frames')));

    /** @type {!Map.<!Resources.Database, !Object.<string, !Resources.DatabaseTableView>>} */
    this._databaseTableViews = new Map();
    /** @type {!Map.<!Resources.Database, !Resources.DatabaseQueryView>} */
    this._databaseQueryViews = new Map();
    /** @type {!Map.<!Resources.Database, !Resources.DatabaseTreeElement>} */
    this._databaseTreeElements = new Map();
    /** @type {!Map.<!Resources.DOMStorage, !Resources.DOMStorageTreeElement>} */
    this._domStorageTreeElements = new Map();
    /** @type {!Object.<string, boolean>} */
    this._domains = {};

    this._sidebarTree.contentElement.addEventListener('mousemove', this._onmousemove.bind(this), false);
    this._sidebarTree.contentElement.addEventListener('mouseleave', this._onmouseleave.bind(this), false);

    SDK.targetManager.observeTargets(this);
    SDK.targetManager.addModelListener(
        SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.FrameNavigated, this._frameNavigated, this);

    const selection = this._panel.lastSelectedItemPath();
    if (!selection.length) {
      manifestTreeElement.select();
    }
  }

  /**
   * @param {string} title
   * @return {!UI.TreeElement}
   */
  _addSidebarSection(title) {
    const treeElement = new UI.TreeElement(title, true);
    treeElement.listItemElement.classList.add('storage-group-list-item');
    treeElement.setCollapsible(false);
    treeElement.selectable = false;
    this._sidebarTree.appendChild(treeElement);
    return treeElement;
  }

  /**
   * @override
   * @param {!SDK.Target} target
   */
  targetAdded(target) {
    if (this._target) {
      return;
    }
    this._target = target;
    this._databaseModel = target.model(Resources.DatabaseModel);
    if (this._databaseModel) {
      this._databaseModel.addEventListener(Resources.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
      this._databaseModel.addEventListener(Resources.DatabaseModel.Events.DatabasesRemoved, this._resetWebSQL, this);
    }

    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
    if (!resourceTreeModel) {
      return;
    }

    if (resourceTreeModel.cachedResourcesLoaded()) {
      this._initialize();
    }

    resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._initialize, this);
    resourceTreeModel.addEventListener(
        SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this);
  }

  /**
   * @override
   * @param {!SDK.Target} target
   */
  targetRemoved(target) {
    if (target !== this._target) {
      return;
    }
    delete this._target;

    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
    if (resourceTreeModel) {
      resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._initialize, this);
      resourceTreeModel.removeEventListener(
          SDK.ResourceTreeModel.Events.WillLoadCachedResources, this._resetWithFrames, this);
    }
    if (this._databaseModel) {
      this._databaseModel.removeEventListener(Resources.DatabaseModel.Events.DatabaseAdded, this._databaseAdded, this);
      this._databaseModel.removeEventListener(Resources.DatabaseModel.Events.DatabasesRemoved, this._resetWebSQL, this);
      this._databaseModel = null;
    }

    this._resetWithFrames();
  }

  /**
   * @override
   */
  focus() {
    this._sidebarTree.focus();
  }

  _initialize() {
    for (const frame of SDK.ResourceTreeModel.frames()) {
      this._addCookieDocument(frame);
    }
    if (this._databaseModel) {
      this._databaseModel.enable();
    }

    const cacheStorageModel = this._target.model(SDK.ServiceWorkerCacheModel);
    if (cacheStorageModel) {
      cacheStorageModel.enable();
    }
    const resourceTreeModel = this._target.model(SDK.ResourceTreeModel);
    if (resourceTreeModel) {
      this._populateApplicationCacheTree(resourceTreeModel);
    }
    SDK.targetManager.observeModels(Resources.DOMStorageModel, /** @type {!SDK.SDKModelObserver} */ ({
                                      modelAdded: model => this._domStorageModelAdded(model),
                                      modelRemoved: model => this._domStorageModelRemoved(model)
                                    }));
    this.indexedDBListTreeElement._initialize();
    SDK.targetManager.observeModels(
        Resources.IndexedDBModel, /** @type {!SDK.SDKModelObserver} */ ({
          modelAdded: model => model.enable(),
          modelRemoved: model => this.indexedDBListTreeElement.removeIndexedDBForModel(model)
        }));
    const serviceWorkerCacheModel = this._target.model(SDK.ServiceWorkerCacheModel);
    this.cacheStorageListTreeElement._initialize(serviceWorkerCacheModel);
    const backgroundServiceModel = this._target.model(Resources.BackgroundServiceModel);
    if (Root.Runtime.experiments.isEnabled('backgroundServices')) {
      this.backgroundFetchTreeElement._initialize(backgroundServiceModel);
      this.backgroundSyncTreeElement._initialize(backgroundServiceModel);
      if (Root.Runtime.experiments.isEnabled('backgroundServicesNotifications')) {
        this.notificationsTreeElement._initialize(backgroundServiceModel);
      }
      if (Root.Runtime.experiments.isEnabled('backgroundServicesPaymentHandler')) {
        this.paymentHandlerTreeElement._initialize(backgroundServiceModel);
      }
      if (Root.Runtime.experiments.isEnabled('backgroundServicesPeriodicBackgroundSync')) {
        this.periodicBackgroundSyncTreeElement._initialize(backgroundServiceModel);
      }
      if (Root.Runtime.experiments.isEnabled('backgroundServicesPushMessaging')) {
        this.pushMessagingTreeElement._initialize(backgroundServiceModel);
      }
    }
  }

  /**
   * @param {!Resources.DOMStorageModel} model
   */
  _domStorageModelAdded(model) {
    model.enable();
    model.storages().forEach(this._addDOMStorage.bind(this));
    model.addEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
    model.addEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
  }

  /**
   * @param {!Resources.DOMStorageModel} model
   */
  _domStorageModelRemoved(model) {
    model.storages().forEach(this._removeDOMStorage.bind(this));
    model.removeEventListener(Resources.DOMStorageModel.Events.DOMStorageAdded, this._domStorageAdded, this);
    model.removeEventListener(Resources.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
  }

  _resetWithFrames() {
    this._resourcesSection.reset();
    this._reset();
  }

  _resetWebSQL() {
    const queryViews = this._databaseQueryViews.valuesArray();
    for (let i = 0; i < queryViews.length; ++i) {
      queryViews[i].removeEventListener(
          Resources.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
    }
    this._databaseTableViews.clear();
    this._databaseQueryViews.clear();
    this._databaseTreeElements.clear();
    this.databasesListTreeElement.removeChildren();
    this.databasesListTreeElement.setExpandable(false);
  }

  _resetAppCache() {
    for (const frameId of Object.keys(this._applicationCacheFrameElements)) {
      this._applicationCacheFrameManifestRemoved({data: frameId});
    }
    this.applicationCacheListTreeElement.setExpandable(false);
  }

  /**
   * @param {!Common.Event} event
   */
  _treeElementAdded(event) {
    const selection = this._panel.lastSelectedItemPath();
    if (!selection.length) {
      return;
    }
    const element = event.data;
    const index = selection.indexOf(element.itemURL);
    if (index < 0) {
      return;
    }
    for (let parent = element.parent; parent; parent = parent.parent) {
      parent.expand();
    }
    if (index > 0) {
      element.expand();
    }
    element.select();
  }

  _reset() {
    this._domains = {};
    this._resetWebSQL();
    this.cookieListTreeElement.removeChildren();
  }

  /**
   * @param {!Common.Event} event
   */
  _frameNavigated(event) {
    const frame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);

    if (frame.isTopFrame()) {
      this._reset();
    }

    const applicationCacheFrameTreeElement = this._applicationCacheFrameElements[frame.id];
    if (applicationCacheFrameTreeElement) {
      applicationCacheFrameTreeElement.frameNavigated(frame);
    }
    this._addCookieDocument(frame);
  }

  /**
   * @param {!Common.Event} event
   */
  _databaseAdded(event) {
    const database = /** @type {!Resources.Database} */ (event.data);
    const databaseTreeElement = new Resources.DatabaseTreeElement(this, database);
    this._databaseTreeElements.set(database, databaseTreeElement);
    this.databasesListTreeElement.appendChild(databaseTreeElement);
  }

  /**
   * @param {!SDK.ResourceTreeFrame} frame
   */
  _addCookieDocument(frame) {
    const parsedURL = Common.ParsedURL.fromString(frame.url);
    if (!parsedURL || (parsedURL.scheme !== 'http' && parsedURL.scheme !== 'https' && parsedURL.scheme !== 'file')) {
      return;
    }

    const domain = parsedURL.securityOrigin();
    if (!this._domains[domain]) {
      this._domains[domain] = true;
      const cookieDomainTreeElement = new Resources.CookieTreeElement(this._panel, frame, domain);
      this.cookieListTreeElement.appendChild(cookieDomainTreeElement);
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _domStorageAdded(event) {
    const domStorage = /** @type {!Resources.DOMStorage} */ (event.data);
    this._addDOMStorage(domStorage);
  }

  /**
   * @param {!Resources.DOMStorage} domStorage
   */
  _addDOMStorage(domStorage) {
    console.assert(!this._domStorageTreeElements.get(domStorage));

    const domStorageTreeElement = new Resources.DOMStorageTreeElement(this._panel, domStorage);
    this._domStorageTreeElements.set(domStorage, domStorageTreeElement);
    if (domStorage.isLocalStorage) {
      this.localStorageListTreeElement.appendChild(domStorageTreeElement);
    } else {
      this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _domStorageRemoved(event) {
    const domStorage = /** @type {!Resources.DOMStorage} */ (event.data);
    this._removeDOMStorage(domStorage);
  }

  /**
   * @param {!Resources.DOMStorage} domStorage
   */
  _removeDOMStorage(domStorage) {
    const treeElement = this._domStorageTreeElements.get(domStorage);
    if (!treeElement) {
      return;
    }
    const wasSelected = treeElement.selected;
    const parentListTreeElement = treeElement.parent;
    parentListTreeElement.removeChild(treeElement);
    if (wasSelected) {
      parentListTreeElement.select();
    }
    this._domStorageTreeElements.remove(domStorage);
  }

  /**
   * @param {!Resources.Database} database
   */
  selectDatabase(database) {
    if (database) {
      this._showDatabase(database);
      this._databaseTreeElements.get(database).select();
    }
  }

  /**
   * @param {!SDK.Resource} resource
   * @param {number=} line
   * @param {number=} column
   * @return {!Promise}
   */
  async showResource(resource, line, column) {
    await this._resourcesSection.revealResource(resource, line, column);
  }

  /**
   * @param {!Resources.Database} database
   * @param {string=} tableName
   */
  _showDatabase(database, tableName) {
    if (!database) {
      return;
    }

    let view;
    if (tableName) {
      let tableViews = this._databaseTableViews.get(database);
      if (!tableViews) {
        tableViews = /** @type {!Object.<string, !Resources.DatabaseTableView>} */ ({});
        this._databaseTableViews.set(database, tableViews);
      }
      view = tableViews[tableName];
      if (!view) {
        view = new Resources.DatabaseTableView(database, tableName);
        tableViews[tableName] = view;
      }
    } else {
      view = this._databaseQueryViews.get(database);
      if (!view) {
        view = new Resources.DatabaseQueryView(database);
        this._databaseQueryViews.set(database, view);
        view.addEventListener(Resources.DatabaseQueryView.Events.SchemaUpdated, this._updateDatabaseTables, this);
      }
    }

    this._innerShowView(view);
  }

  _showApplicationCache(frameId) {
    if (!this._applicationCacheViews[frameId]) {
      this._applicationCacheViews[frameId] =
          new Resources.ApplicationCacheItemsView(this._applicationCacheModel, frameId);
    }

    this._innerShowView(this._applicationCacheViews[frameId]);
  }

  /**
   *  @param {!UI.Widget} view
   */
  showFileSystem(view) {
    this._innerShowView(view);
  }

  _innerShowView(view) {
    this._panel.showView(view);
  }

  /**
   * @param {!Common.Event} event
   */
  async _updateDatabaseTables(event) {
    const database = /** @type {!Resources.Database} */ (event.data);

    if (!database) {
      return;
    }

    const databasesTreeElement = this._databaseTreeElements.get(database);
    if (!databasesTreeElement) {
      return;
    }

    databasesTreeElement.invalidateChildren();
    const tableViews = this._databaseTableViews.get(database);

    if (!tableViews) {
      return;
    }

    const tableNamesHash = {};
    const panel = this._panel;
    const tableNames = await database.tableNames();
    const tableNamesLength = tableNames.length;

    for (let i = 0; i < tableNamesLength; ++i) {
      tableNamesHash[tableNames[i]] = true;
    }

    for (const tableName in tableViews) {
      if (!(tableName in tableNamesHash)) {
        if (panel.visibleView === tableViews[tableName]) {
          panel.showView(null);
        }
        delete tableViews[tableName];
      }
    }

    await databasesTreeElement.updateChildren();
  }

  /**
   * @param {!SDK.ResourceTreeModel} resourceTreeModel
   */
  _populateApplicationCacheTree(resourceTreeModel) {
    this._applicationCacheModel = this._target.model(Resources.ApplicationCacheModel);

    this._applicationCacheViews = {};
    this._applicationCacheFrameElements = {};
    this._applicationCacheManifestElements = {};

    this._applicationCacheModel.addEventListener(
        Resources.ApplicationCacheModel.Events.FrameManifestAdded, this._applicationCacheFrameManifestAdded, this);
    this._applicationCacheModel.addEventListener(
        Resources.ApplicationCacheModel.Events.FrameManifestRemoved, this._applicationCacheFrameManifestRemoved, this);
    this._applicationCacheModel.addEventListener(
        Resources.ApplicationCacheModel.Events.FrameManifestsReset, this._resetAppCache, this);

    this._applicationCacheModel.addEventListener(
        Resources.ApplicationCacheModel.Events.FrameManifestStatusUpdated,
        this._applicationCacheFrameManifestStatusChanged, this);
    this._applicationCacheModel.addEventListener(
        Resources.ApplicationCacheModel.Events.NetworkStateChanged, this._applicationCacheNetworkStateChanged, this);
  }

  _applicationCacheFrameManifestAdded(event) {
    const frameId = event.data;
    const manifestURL = this._applicationCacheModel.frameManifestURL(frameId);

    let manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
    if (!manifestTreeElement) {
      manifestTreeElement = new Resources.ApplicationCacheManifestTreeElement(this._panel, manifestURL);
      this.applicationCacheListTreeElement.appendChild(manifestTreeElement);
      this._applicationCacheManifestElements[manifestURL] = manifestTreeElement;
    }

    const model = this._target.model(SDK.ResourceTreeModel);
    const frameTreeElement =
        new Resources.ApplicationCacheFrameTreeElement(this, model.frameForId(frameId), manifestURL);
    manifestTreeElement.appendChild(frameTreeElement);
    manifestTreeElement.expand();
    this._applicationCacheFrameElements[frameId] = frameTreeElement;
  }

  _applicationCacheFrameManifestRemoved(event) {
    const frameId = event.data;
    const frameTreeElement = this._applicationCacheFrameElements[frameId];
    if (!frameTreeElement) {
      return;
    }

    const manifestURL = frameTreeElement.manifestURL;
    delete this._applicationCacheFrameElements[frameId];
    delete this._applicationCacheViews[frameId];
    frameTreeElement.parent.removeChild(frameTreeElement);

    const manifestTreeElement = this._applicationCacheManifestElements[manifestURL];
    if (manifestTreeElement.childCount()) {
      return;
    }

    delete this._applicationCacheManifestElements[manifestURL];
    manifestTreeElement.parent.removeChild(manifestTreeElement);
  }

  _applicationCacheFrameManifestStatusChanged(event) {
    const frameId = event.data;
    const status = this._applicationCacheModel.frameManifestStatus(frameId);

    if (this._applicationCacheViews[frameId]) {
      this._applicationCacheViews[frameId].updateStatus(status);
    }
  }

  _applicationCacheNetworkStateChanged(event) {
    const isNowOnline = event.data;

    for (const manifestURL in this._applicationCacheViews) {
      this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline);
    }
  }

  showView(view) {
    if (view) {
      this.showResource(view.resource);
    }
  }

  _onmousemove(event) {
    const nodeUnderMouse = event.target;
    if (!nodeUnderMouse) {
      return;
    }

    const listNode = nodeUnderMouse.enclosingNodeOrSelfWithNodeName('li');
    if (!listNode) {
      return;
    }

    const element = listNode.treeElement;
    if (this._previousHoveredElement === element) {
      return;
    }

    if (this._previousHoveredElement) {
      this._previousHoveredElement.hovered = false;
      delete this._previousHoveredElement;
    }

    if (element instanceof Resources.FrameTreeElement) {
      this._previousHoveredElement = element;
      element.hovered = true;
    }
  }

  _onmouseleave(event) {
    if (this._previousHoveredElement) {
      this._previousHoveredElement.hovered = false;
      delete this._previousHoveredElement;
    }
  }
};

/**
 * @unrestricted
 */
Resources.BaseStorageTreeElement = class extends UI.TreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   * @param {string} title
   * @param {boolean} expandable
   */
  constructor(storagePanel, title, expandable) {
    super(title, expandable);
    this._storagePanel = storagePanel;
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    if (!selectedByUser) {
      return false;
    }

    const path = [];
    for (let el = this; el; el = el.parent) {
      const url = el.itemURL;
      if (!url) {
        break;
      }
      path.push(url);
    }
    this._storagePanel.setLastSelectedItemPath(path);

    return false;
  }

  /**
   * @protected
   * @param {?UI.Widget} view
   */
  showView(view) {
    this._storagePanel.showView(view);
  }
};

Resources.StorageCategoryTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   * @param {string} categoryName
   * @param {string} settingsKey
   */
  constructor(storagePanel, categoryName, settingsKey) {
    super(storagePanel, categoryName, false);
    this._expandedSetting =
        Common.settings.createSetting('resources' + settingsKey + 'Expanded', settingsKey === 'Frames');
    this._categoryName = categoryName;
    this._categoryLink = null;
  }

  get itemURL() {
    return 'category://' + this._categoryName;
  }

  /**
   * @param {string} link
   */
  setLink(link) {
    this._categoryLink = link;
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    this._storagePanel.showCategoryView(this._categoryName, this._categoryLink);
    return false;
  }

  /**
   * @override
   */
  onattach() {
    super.onattach();
    if (this._expandedSetting.get()) {
      this.expand();
    }
  }

  /**
   * @override
   */
  onexpand() {
    this._expandedSetting.set(true);
  }

  /**
   * @override
   */
  oncollapse() {
    this._expandedSetting.set(false);
  }
};

Resources.BackgroundServiceTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   * @param {!Protocol.BackgroundService.ServiceName} serviceName
   */
  constructor(storagePanel, serviceName) {
    super(storagePanel, Resources.BackgroundServiceView.getUIString(serviceName), false);

    /** @const {!Protocol.BackgroundService.ServiceName} */
    this._serviceName = serviceName;

    /** @type {boolean} Whether the element has been selected. */
    this._selected = false;

    /** @type {?Resources.BackgroundServiceView} */
    this._view = null;

    /** @private {?Resources.BackgroundServiceModel} */
    this._model = null;

    const backgroundServiceIcon = UI.Icon.create(this._getIconType(), 'resource-tree-item');
    this.setLeadingIcons([backgroundServiceIcon]);
  }

  /**
   * @return {string}
   */
  _getIconType() {
    switch (this._serviceName) {
      case Protocol.BackgroundService.ServiceName.BackgroundFetch:
        return 'mediumicon-fetch';
      case Protocol.BackgroundService.ServiceName.BackgroundSync:
        return 'mediumicon-sync';
      case Protocol.BackgroundService.ServiceName.PushMessaging:
        return 'mediumicon-cloud';
      case Protocol.BackgroundService.ServiceName.Notifications:
        return 'mediumicon-bell';
      case Protocol.BackgroundService.ServiceName.PaymentHandler:
        return 'mediumicon-payment';
      case Protocol.BackgroundService.ServiceName.PeriodicBackgroundSync:
        return 'mediumicon-schedule';
      default:
        console.error(`Service ${this._serviceName} does not have a dedicated icon`);
        return 'mediumicon-table';
    }
  }

  /**
   * @param {?Resources.BackgroundServiceModel} model
   */
  _initialize(model) {
    this._model = model;
    // Show the view if the model was initialized after selection.
    if (this._selected && !this._view) {
      this.onselect(false);
    }
  }

  /**
   * @return {string}
   */
  get itemURL() {
    return `background-service://${this._serviceName}`;
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    this._selected = true;

    if (!this._model) {
      return false;
    }

    if (!this._view) {
      this._view = new Resources.BackgroundServiceView(this._serviceName, this._model);
    }
    this.showView(this._view);
    UI.context.setFlavor(Resources.BackgroundServiceView, this._view);
    return false;
  }
};

/**
 * @unrestricted
 */
Resources.DatabaseTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ApplicationPanelSidebar} sidebar
   * @param {!Resources.Database} database
   */
  constructor(sidebar, database) {
    super(sidebar._panel, database.name, true);
    this._sidebar = sidebar;
    this._database = database;

    const icon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  get itemURL() {
    return 'database://' + encodeURI(this._database.name);
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    this._sidebar._showDatabase(this._database);
    return false;
  }

  /**
   * @override
   */
  onexpand() {
    this.updateChildren();
  }

  async updateChildren() {
    this.removeChildren();
    const tableNames = await this._database.tableNames();
    for (const tableName of tableNames) {
      this.appendChild(new Resources.DatabaseTableTreeElement(this._sidebar, this._database, tableName));
    }
  }
};

/**
 * @unrestricted
 */
Resources.DatabaseTableTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ApplicationPanelSidebar} sidebar
   * @param {!Resources.Database} database
   * @param {string} tableName
   */
  constructor(sidebar, database, tableName) {
    super(sidebar._panel, tableName, false);
    this._sidebar = sidebar;
    this._database = database;
    this._tableName = tableName;
    const icon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  get itemURL() {
    return 'database://' + encodeURI(this._database.name) + '/' + encodeURI(this._tableName);
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    this._sidebar._showDatabase(this._database, this._tableName);
    return false;
  }
};

/**
 * @unrestricted
 */
Resources.ServiceWorkerCacheTreeElement = class extends Resources.StorageCategoryTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   */
  constructor(storagePanel) {
    super(storagePanel, Common.UIString('Cache Storage'), 'CacheStorage');
    const icon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
    this.setLeadingIcons([icon]);
    /** @type {?SDK.ServiceWorkerCacheModel} */
    this._swCacheModel = null;
  }

  /**
   * @param {?SDK.ServiceWorkerCacheModel} model
   */
  _initialize(model) {
    /** @type {!Array.<!Resources.SWCacheTreeElement>} */
    this._swCacheTreeElements = [];
    this._swCacheModel = model;
    if (model) {
      for (const cache of model.caches()) {
        this._addCache(model, cache);
      }
    }
    SDK.targetManager.addModelListener(
        SDK.ServiceWorkerCacheModel, SDK.ServiceWorkerCacheModel.Events.CacheAdded, this._cacheAdded, this);
    SDK.targetManager.addModelListener(
        SDK.ServiceWorkerCacheModel, SDK.ServiceWorkerCacheModel.Events.CacheRemoved, this._cacheRemoved, this);
  }

  /**
   * @override
   */
  onattach() {
    super.onattach();
    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
  }

  _handleContextMenuEvent(event) {
    const contextMenu = new UI.ContextMenu(event);
    contextMenu.defaultSection().appendItem(Common.UIString('Refresh Caches'), this._refreshCaches.bind(this));
    contextMenu.show();
  }

  _refreshCaches() {
    if (this._swCacheModel) {
      this._swCacheModel.refreshCacheNames();
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _cacheAdded(event) {
    const cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache);
    const model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model);
    this._addCache(model, cache);
  }

  /**
   * @param {!SDK.ServiceWorkerCacheModel} model
   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
   */
  _addCache(model, cache) {
    const swCacheTreeElement = new Resources.SWCacheTreeElement(this._storagePanel, model, cache);
    this._swCacheTreeElements.push(swCacheTreeElement);
    this.appendChild(swCacheTreeElement);
  }

  /**
   * @param {!Common.Event} event
   */
  _cacheRemoved(event) {
    const cache = /** @type {!SDK.ServiceWorkerCacheModel.Cache} */ (event.data.cache);
    const model = /** @type {!SDK.ServiceWorkerCacheModel} */ (event.data.model);

    const swCacheTreeElement = this._cacheTreeElement(model, cache);
    if (!swCacheTreeElement) {
      return;
    }

    this.removeChild(swCacheTreeElement);
    this._swCacheTreeElements.remove(swCacheTreeElement);
    this.setExpandable(this.childCount() > 0);
  }

  /**
   * @param {!SDK.ServiceWorkerCacheModel} model
   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
   * @return {?Resources.SWCacheTreeElement}
   */
  _cacheTreeElement(model, cache) {
    let index = -1;
    let i;
    for (i = 0; i < this._swCacheTreeElements.length; ++i) {
      if (this._swCacheTreeElements[i]._cache.equals(cache) && this._swCacheTreeElements[i]._model === model) {
        index = i;
        break;
      }
    }
    if (index !== -1) {
      return this._swCacheTreeElements[i];
    }
    return null;
  }
};

Resources.SWCacheTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   * @param {!SDK.ServiceWorkerCacheModel} model
   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
   */
  constructor(storagePanel, model, cache) {
    super(storagePanel, cache.cacheName + ' - ' + cache.securityOrigin, false);
    this._model = model;
    this._cache = cache;
    /** @type {?Resources.ServiceWorkerCacheView} */
    this._view = null;
    const icon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  get itemURL() {
    // I don't think this will work at all.
    return 'cache://' + this._cache.cacheId;
  }

  /**
   * @override
   */
  onattach() {
    super.onattach();
    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
  }

  _handleContextMenuEvent(event) {
    const contextMenu = new UI.ContextMenu(event);
    contextMenu.defaultSection().appendItem(Common.UIString('Delete'), this._clearCache.bind(this));
    contextMenu.show();
  }

  _clearCache() {
    this._model.deleteCache(this._cache);
  }

  /**
   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
   */
  update(cache) {
    this._cache = cache;
    if (this._view) {
      this._view.update(cache);
    }
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    if (!this._view) {
      this._view = new Resources.ServiceWorkerCacheView(this._model, this._cache);
    }

    this.showView(this._view);
    return false;
  }
};

/**
 * @unrestricted
 */
Resources.ServiceWorkersTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   */
  constructor(storagePanel) {
    super(storagePanel, Common.UIString('Service Workers'), false);
    const icon = UI.Icon.create('mediumicon-service-worker', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  /**
   * @return {string}
   */
  get itemURL() {
    return 'service-workers://';
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    if (!this._view) {
      this._view = new Resources.ServiceWorkersView();
    }
    this.showView(this._view);
    return false;
  }
};

/**
 * @unrestricted
 */
Resources.AppManifestTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   */
  constructor(storagePanel) {
    super(storagePanel, Common.UIString('Manifest'), false);
    const icon = UI.Icon.create('mediumicon-manifest', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  /**
   * @return {string}
   */
  get itemURL() {
    return 'manifest://';
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    if (!this._view) {
      this._view = new Resources.AppManifestView();
    }
    this.showView(this._view);
    return false;
  }
};

/**
 * @unrestricted
 */
Resources.ClearStorageTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   */
  constructor(storagePanel) {
    super(storagePanel, Common.UIString('Clear storage'), false);
    const icon = UI.Icon.create('mediumicon-clear-storage', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  /**
   * @return {string}
   */
  get itemURL() {
    return 'clear-storage://';
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    if (!this._view) {
      this._view = new Resources.ClearStorageView();
    }
    this.showView(this._view);
    return false;
  }
};

/**
 * @unrestricted
 */
Resources.IndexedDBTreeElement = class extends Resources.StorageCategoryTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   */
  constructor(storagePanel) {
    super(storagePanel, Common.UIString('IndexedDB'), 'IndexedDB');
    const icon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  _initialize() {
    SDK.targetManager.addModelListener(
        Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseAdded, this._indexedDBAdded, this);
    SDK.targetManager.addModelListener(
        Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseRemoved, this._indexedDBRemoved, this);
    SDK.targetManager.addModelListener(
        Resources.IndexedDBModel, Resources.IndexedDBModel.Events.DatabaseLoaded, this._indexedDBLoaded, this);
    SDK.targetManager.addModelListener(
        Resources.IndexedDBModel, Resources.IndexedDBModel.Events.IndexedDBContentUpdated,
        this._indexedDBContentUpdated, this);
    /** @type {!Array.<!Resources.IDBDatabaseTreeElement>} */
    this._idbDatabaseTreeElements = [];

    for (const indexedDBModel of SDK.targetManager.models(Resources.IndexedDBModel)) {
      const databases = indexedDBModel.databases();
      for (let j = 0; j < databases.length; ++j) {
        this._addIndexedDB(indexedDBModel, databases[j]);
      }
    }
  }

  /**
   * @param {!Resources.IndexedDBModel} model
   */
  removeIndexedDBForModel(model) {
    const idbDatabaseTreeElements = this._idbDatabaseTreeElements.filter(element => element._model === model);
    for (const idbDatabaseTreeElement of idbDatabaseTreeElements) {
      this._removeIDBDatabaseTreeElement(idbDatabaseTreeElement);
    }
  }

  /**
   * @override
   */
  onattach() {
    super.onattach();
    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
  }

  _handleContextMenuEvent(event) {
    const contextMenu = new UI.ContextMenu(event);
    contextMenu.defaultSection().appendItem(Common.UIString('Refresh IndexedDB'), this.refreshIndexedDB.bind(this));
    contextMenu.show();
  }

  refreshIndexedDB() {
    for (const indexedDBModel of SDK.targetManager.models(Resources.IndexedDBModel)) {
      indexedDBModel.refreshDatabaseNames();
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _indexedDBAdded(event) {
    const databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId);
    const model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);
    this._addIndexedDB(model, databaseId);
  }

  /**
   * @param {!Resources.IndexedDBModel} model
   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
   */
  _addIndexedDB(model, databaseId) {
    const idbDatabaseTreeElement = new Resources.IDBDatabaseTreeElement(this._storagePanel, model, databaseId);
    this._idbDatabaseTreeElements.push(idbDatabaseTreeElement);
    this.appendChild(idbDatabaseTreeElement);
    model.refreshDatabase(databaseId);
  }

  /**
   * @param {!Common.Event} event
   */
  _indexedDBRemoved(event) {
    const databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId);
    const model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);

    const idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId);
    if (!idbDatabaseTreeElement) {
      return;
    }
    this._removeIDBDatabaseTreeElement(idbDatabaseTreeElement);
  }

  /**
   * @param {!Resources.IDBDatabaseTreeElement} idbDatabaseTreeElement
   */
  _removeIDBDatabaseTreeElement(idbDatabaseTreeElement) {
    idbDatabaseTreeElement.clear();
    this.removeChild(idbDatabaseTreeElement);
    this._idbDatabaseTreeElements.remove(idbDatabaseTreeElement);
    this.setExpandable(this.childCount() > 0);
  }

  /**
   * @param {!Common.Event} event
   */
  _indexedDBLoaded(event) {
    const database = /** @type {!Resources.IndexedDBModel.Database} */ (event.data.database);
    const model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);
    const entriesUpdated = /** @type {boolean} */ (event.data.entriesUpdated);

    const idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, database.databaseId);
    if (!idbDatabaseTreeElement) {
      return;
    }
    idbDatabaseTreeElement.update(database, entriesUpdated);
    this._indexedDBLoadedForTest();
  }

  _indexedDBLoadedForTest() {
    // For sniffing in tests.
  }

  /**
   * @param {!Common.Event} event
   */
  _indexedDBContentUpdated(event) {
    const databaseId = /** @type {!Resources.IndexedDBModel.DatabaseId} */ (event.data.databaseId);
    const objectStoreName = /** @type {string} */ (event.data.objectStoreName);
    const model = /** @type {!Resources.IndexedDBModel} */ (event.data.model);

    const idbDatabaseTreeElement = this._idbDatabaseTreeElement(model, databaseId);
    if (!idbDatabaseTreeElement) {
      return;
    }
    idbDatabaseTreeElement.indexedDBContentUpdated(objectStoreName);
  }

  /**
   * @param {!Resources.IndexedDBModel} model
   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
   * @return {?Resources.IDBDatabaseTreeElement}
   */
  _idbDatabaseTreeElement(model, databaseId) {
    return this._idbDatabaseTreeElements.find(x => x._databaseId.equals(databaseId) && x._model === model) || null;
  }
};

/**
 * @unrestricted
 */
Resources.IDBDatabaseTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   * @param {!Resources.IndexedDBModel} model
   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
   */
  constructor(storagePanel, model, databaseId) {
    super(storagePanel, databaseId.name + ' - ' + databaseId.securityOrigin, false);
    this._model = model;
    this._databaseId = databaseId;
    this._idbObjectStoreTreeElements = {};
    const icon = UI.Icon.create('mediumicon-database', 'resource-tree-item');
    this.setLeadingIcons([icon]);
    this._model.addEventListener(Resources.IndexedDBModel.Events.DatabaseNamesRefreshed, this._refreshIndexedDB, this);
  }

  get itemURL() {
    return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name;
  }

  /**
   * @override
   */
  onattach() {
    super.onattach();
    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
  }

  _handleContextMenuEvent(event) {
    const contextMenu = new UI.ContextMenu(event);
    contextMenu.defaultSection().appendItem(Common.UIString('Refresh IndexedDB'), this._refreshIndexedDB.bind(this));
    contextMenu.show();
  }

  _refreshIndexedDB() {
    this._model.refreshDatabase(this._databaseId);
  }

  /**
   * @param {string} objectStoreName
   */
  indexedDBContentUpdated(objectStoreName) {
    if (this._idbObjectStoreTreeElements[objectStoreName]) {
      this._idbObjectStoreTreeElements[objectStoreName].markNeedsRefresh();
    }
  }

  /**
   * @param {!Resources.IndexedDBModel.Database} database
   * @param {boolean} entriesUpdated
   */
  update(database, entriesUpdated) {
    this._database = database;
    const objectStoreNames = {};
    const objectStoreNamesSorted = Object.keys(this._database.objectStores).sort();
    for (const objectStoreName of objectStoreNamesSorted) {
      const objectStore = this._database.objectStores[objectStoreName];
      objectStoreNames[objectStore.name] = true;
      if (!this._idbObjectStoreTreeElements[objectStore.name]) {
        const idbObjectStoreTreeElement =
            new Resources.IDBObjectStoreTreeElement(this._storagePanel, this._model, this._databaseId, objectStore);
        this._idbObjectStoreTreeElements[objectStore.name] = idbObjectStoreTreeElement;
        this.appendChild(idbObjectStoreTreeElement);
      }
      this._idbObjectStoreTreeElements[objectStore.name].update(objectStore, entriesUpdated);
    }
    for (const objectStoreName in this._idbObjectStoreTreeElements) {
      if (!objectStoreNames[objectStoreName]) {
        this._objectStoreRemoved(objectStoreName);
      }
    }

    if (this._view) {
      this._view.update(database);
    }

    this._updateTooltip();
  }

  _updateTooltip() {
    if (Object.keys(this._idbObjectStoreTreeElements).length === 0) {
      this.tooltip = ls`Version: ${this._database.version} (empty)`;
    } else {
      this.tooltip = ls`Version: ${this._database.version}`;
    }
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    if (!this._view) {
      this._view = new Resources.IDBDatabaseView(this._model, this._database);
    }

    this.showView(this._view);
    return false;
  }

  /**
   * @param {string} objectStoreName
   */
  _objectStoreRemoved(objectStoreName) {
    const objectStoreTreeElement = this._idbObjectStoreTreeElements[objectStoreName];
    objectStoreTreeElement.clear();
    this.removeChild(objectStoreTreeElement);
    delete this._idbObjectStoreTreeElements[objectStoreName];
    this._updateTooltip();
  }

  clear() {
    for (const objectStoreName in this._idbObjectStoreTreeElements) {
      this._objectStoreRemoved(objectStoreName);
    }
  }
};

Resources.IDBObjectStoreTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   * @param {!Resources.IndexedDBModel} model
   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
   */
  constructor(storagePanel, model, databaseId, objectStore) {
    super(storagePanel, objectStore.name, false);
    this._model = model;
    this._databaseId = databaseId;
    this._idbIndexTreeElements = {};
    this._objectStore = objectStore;
    /** @type {?Resources.IDBDataView} */
    this._view = null;
    const icon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  get itemURL() {
    return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name + '/' +
        this._objectStore.name;
  }

  /**
   * @override
   */
  onattach() {
    super.onattach();
    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
  }

  markNeedsRefresh() {
    if (this._view) {
      this._view.markNeedsRefresh();
    }
    for (const indexName in this._idbIndexTreeElements) {
      this._idbIndexTreeElements[indexName].markNeedsRefresh();
    }
  }

  _handleContextMenuEvent(event) {
    const contextMenu = new UI.ContextMenu(event);
    contextMenu.defaultSection().appendItem(Common.UIString('Clear'), this._clearObjectStore.bind(this));
    contextMenu.show();
  }

  _refreshObjectStore() {
    if (this._view) {
      this._view.refreshData();
    }
    for (const indexName in this._idbIndexTreeElements) {
      this._idbIndexTreeElements[indexName].refreshIndex();
    }
  }

  async _clearObjectStore() {
    await this._model.clearObjectStore(this._databaseId, this._objectStore.name);
    this.update(this._objectStore, true);
  }

  /**
   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
   * @param {boolean} entriesUpdated
   */
  update(objectStore, entriesUpdated) {
    this._objectStore = objectStore;

    const indexNames = {};
    for (const indexName in this._objectStore.indexes) {
      const index = this._objectStore.indexes[indexName];
      indexNames[index.name] = true;
      if (!this._idbIndexTreeElements[index.name]) {
        const idbIndexTreeElement = new Resources.IDBIndexTreeElement(
            this._storagePanel, this._model, this._databaseId, this._objectStore, index,
            this._refreshObjectStore.bind(this));
        this._idbIndexTreeElements[index.name] = idbIndexTreeElement;
        this.appendChild(idbIndexTreeElement);
      }
      this._idbIndexTreeElements[index.name].update(this._objectStore, index, entriesUpdated);
    }
    for (const indexName in this._idbIndexTreeElements) {
      if (!indexNames[indexName]) {
        this._indexRemoved(indexName);
      }
    }
    for (const indexName in this._idbIndexTreeElements) {
      if (!indexNames[indexName]) {
        this.removeChild(this._idbIndexTreeElements[indexName]);
        delete this._idbIndexTreeElements[indexName];
      }
    }

    if (this.childCount()) {
      this.expand();
    }

    if (this._view && entriesUpdated) {
      this._view.update(this._objectStore, null);
    }

    this._updateTooltip();
  }

  _updateTooltip() {
    const keyPathString = this._objectStore.keyPathString;
    let tooltipString = keyPathString !== null ? ls`Key path: ${keyPathString}` : '';
    if (this._objectStore.autoIncrement) {
      tooltipString += '\n' + Common.UIString('autoIncrement');
    }
    this.tooltip = tooltipString;
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    if (!this._view) {
      this._view = new Resources.IDBDataView(
          this._model, this._databaseId, this._objectStore, null, this._refreshObjectStore.bind(this));
    }

    this.showView(this._view);
    return false;
  }

  /**
   * @param {string} indexName
   */
  _indexRemoved(indexName) {
    const indexTreeElement = this._idbIndexTreeElements[indexName];
    indexTreeElement.clear();
    this.removeChild(indexTreeElement);
    delete this._idbIndexTreeElements[indexName];
  }

  clear() {
    for (const indexName in this._idbIndexTreeElements) {
      this._indexRemoved(indexName);
    }
    if (this._view) {
      this._view.clear();
    }
  }
};

/**
 * @unrestricted
 */
Resources.IDBIndexTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   * @param {!Resources.IndexedDBModel} model
   * @param {!Resources.IndexedDBModel.DatabaseId} databaseId
   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
   * @param {!Resources.IndexedDBModel.Index} index
   * @param {function()} refreshObjectStore
   */
  constructor(storagePanel, model, databaseId, objectStore, index, refreshObjectStore) {
    super(storagePanel, index.name, false);
    this._model = model;
    this._databaseId = databaseId;
    this._objectStore = objectStore;
    this._index = index;
    this._refreshObjectStore = refreshObjectStore;
  }

  get itemURL() {
    return 'indexedDB://' + this._databaseId.securityOrigin + '/' + this._databaseId.name + '/' +
        this._objectStore.name + '/' + this._index.name;
  }

  markNeedsRefresh() {
    if (this._view) {
      this._view.markNeedsRefresh();
    }
  }

  refreshIndex() {
    if (this._view) {
      this._view.refreshData();
    }
  }

  /**
   * @param {!Resources.IndexedDBModel.ObjectStore} objectStore
   * @param {!Resources.IndexedDBModel.Index} index
   * @param {boolean} entriesUpdated
   */
  update(objectStore, index, entriesUpdated) {
    this._objectStore = objectStore;
    this._index = index;

    if (this._view && entriesUpdated) {
      this._view.update(this._objectStore, this._index);
    }

    this._updateTooltip();
  }

  _updateTooltip() {
    const tooltipLines = [];
    const keyPathString = this._index.keyPathString;
    tooltipLines.push(ls`Key path: ${keyPathString}`);
    if (this._index.unique) {
      tooltipLines.push(Common.UIString('unique'));
    }
    if (this._index.multiEntry) {
      tooltipLines.push(Common.UIString('multiEntry'));
    }
    this.tooltip = tooltipLines.join('\n');
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    if (!this._view) {
      this._view = new Resources.IDBDataView(
          this._model, this._databaseId, this._objectStore, this._index, this._refreshObjectStore);
    }

    this.showView(this._view);
    return false;
  }

  clear() {
    if (this._view) {
      this._view.clear();
    }
  }
};

/**
 * @unrestricted
 */
Resources.DOMStorageTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   * @param {!Resources.DOMStorage} domStorage
   */
  constructor(storagePanel, domStorage) {
    super(storagePanel, domStorage.securityOrigin ? domStorage.securityOrigin : Common.UIString('Local Files'), false);
    this._domStorage = domStorage;
    const icon = UI.Icon.create('mediumicon-table', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  get itemURL() {
    return 'storage://' + this._domStorage.securityOrigin + '/' +
        (this._domStorage.isLocalStorage ? 'local' : 'session');
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    this._storagePanel.showDOMStorage(this._domStorage);
    return false;
  }

  /**
   * @override
   */
  onattach() {
    super.onattach();
    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
  }

  _handleContextMenuEvent(event) {
    const contextMenu = new UI.ContextMenu(event);
    contextMenu.defaultSection().appendItem(Common.UIString('Clear'), () => this._domStorage.clear());
    contextMenu.show();
  }
};

Resources.CookieTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ResourcesPanel} storagePanel
   * @param {!SDK.ResourceTreeFrame} frame
   * @param {string} cookieDomain
   */
  constructor(storagePanel, frame, cookieDomain) {
    super(storagePanel, cookieDomain ? cookieDomain : Common.UIString('Local Files'), false);
    this._target = frame.resourceTreeModel().target();
    this._cookieDomain = cookieDomain;
    this.tooltip = ls`cookies used by frames from ${cookieDomain}`;
    const icon = UI.Icon.create('mediumicon-cookie', 'resource-tree-item');
    this.setLeadingIcons([icon]);
  }

  get itemURL() {
    return 'cookies://' + this._cookieDomain;
  }

  /**
   * @override
   */
  onattach() {
    super.onattach();
    this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), true);
  }

  /**
   * @param {!Event} event
   */
  _handleContextMenuEvent(event) {
    const contextMenu = new UI.ContextMenu(event);
    contextMenu.defaultSection().appendItem(
        Common.UIString('Clear'), () => this._storagePanel.clearCookies(this._target, this._cookieDomain));
    contextMenu.show();
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    this._storagePanel.showCookies(this._target, this._cookieDomain);
    return false;
  }
};

/**
 * @unrestricted
 */
Resources.ApplicationCacheManifestTreeElement = class extends Resources.BaseStorageTreeElement {
  constructor(storagePanel, manifestURL) {
    const title = new Common.ParsedURL(manifestURL).displayName;
    super(storagePanel, title, false);
    this.tooltip = manifestURL;
    this._manifestURL = manifestURL;
  }

  get itemURL() {
    return 'appcache://' + this._manifestURL;
  }

  get manifestURL() {
    return this._manifestURL;
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    this._storagePanel.showCategoryView(this._manifestURL, null);
    return false;
  }
};

/**
 * @unrestricted
 */
Resources.ApplicationCacheFrameTreeElement = class extends Resources.BaseStorageTreeElement {
  /**
   * @param {!Resources.ApplicationPanelSidebar} sidebar
   * @param {!SDK.ResourceTreeFrame} frame
   * @param {string} manifestURL
   */
  constructor(sidebar, frame, manifestURL) {
    super(sidebar._panel, '', false);
    this._sidebar = sidebar;
    this._frameId = frame.id;
    this._manifestURL = manifestURL;
    this._refreshTitles(frame);

    const icon = UI.Icon.create('largeicon-navigator-folder', 'navigator-tree-item');
    icon.classList.add('navigator-folder-tree-item');
    this.setLeadingIcons([icon]);
  }

  get itemURL() {
    return 'appcache://' + this._manifestURL + '/' + encodeURI(this.titleAsText());
  }

  get frameId() {
    return this._frameId;
  }

  get manifestURL() {
    return this._manifestURL;
  }

  /**
   * @param {!SDK.ResourceTreeFrame} frame
   */
  _refreshTitles(frame) {
    this.title = frame.displayName();
  }

  /**
   * @param {!SDK.ResourceTreeFrame} frame
   */
  frameNavigated(frame) {
    this._refreshTitles(frame);
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect(selectedByUser) {
    super.onselect(selectedByUser);
    this._sidebar._showApplicationCache(this._frameId);
    return false;
  }
};

/**
 * @unrestricted
 */
Resources.StorageCategoryView = class extends UI.VBox {
  constructor() {
    super();

    this.element.classList.add('storage-view');
    this._emptyWidget = new UI.EmptyWidget('');
    this._linkElement = null;
    this._emptyWidget.show(this.element);
  }

  /**
   * @param {string} text
   */
  setText(text) {
    this._emptyWidget.text = text;
  }

  /**
   * @param {?string} link
   */
  setLink(link) {
    if (link && !this._linkElement) {
      this._linkElement = this._emptyWidget.appendLink(link);
    }
    if (!link && this._linkElement) {
      this._linkElement.classList.add('hidden');
    }
    if (link && this._linkElement) {
      this._linkElement.setAttribute('href', link);
      this._linkElement.classList.remove('hidden');
    }
  }
};
