From 574c7204c8167abab6ccdfa3ab096e62a042d2ca Mon Sep 17 00:00:00 2001 From: Harley Li Date: Mon, 3 Dec 2018 19:55:54 +0000 Subject: [PATCH] [DevTools] URL path filter in Application > cache storage With this patch users are able to search for cache entries which contain a given URL path in Application panel's cache storage table. Only entries that have the matching URL paths will be displayed in the table, which supports pagination if there are too many entries returned. Bug: 884194 Change-Id: If285cc43859e82f5e59b80b1b761e9836aa5f510 Reviewed-on: https://chromium-review.googlesource.com/c/1345421 Reviewed-by: Dmitry Gozman Commit-Queue: Haihong Li (Harley) Cr-Original-Commit-Position: refs/heads/master@{#613204} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 3c68e3a7bc37f6eeb338e7768735087ae469a329 --- .../CacheStorageTestRunner.js | 54 ++++++++++++------- .../resources/ServiceWorkerCacheViews.js | 35 +++++++++--- front_end/sdk/ServiceWorkerCacheModel.js | 11 ++-- 3 files changed, 69 insertions(+), 31 deletions(-) diff --git a/front_end/application_test_runner/CacheStorageTestRunner.js b/front_end/application_test_runner/CacheStorageTestRunner.js index a0b90cbf45..8773a5dba5 100644 --- a/front_end/application_test_runner/CacheStorageTestRunner.js +++ b/front_end/application_test_runner/CacheStorageTestRunner.js @@ -7,17 +7,33 @@ * @suppress {accessControls} */ -ApplicationTestRunner.dumpCacheTree = async function() { +ApplicationTestRunner.dumpCacheTree = async function(pathFilter) { UI.panels.resources._sidebar.cacheStorageListTreeElement.expand(); const promise = TestRunner.addSnifferPromise(SDK.ServiceWorkerCacheModel.prototype, '_updateCacheNames'); UI.panels.resources._sidebar.cacheStorageListTreeElement._refreshCaches(); await promise; - await ApplicationTestRunner.dumpCacheTreeNoRefresh(); + await ApplicationTestRunner.dumpCacheTreeNoRefresh(pathFilter); }; -ApplicationTestRunner.dumpCacheTreeNoRefresh = async function() { +ApplicationTestRunner.dumpCacheTreeNoRefresh = async function(pathFilter) { + function _dumpDataGrid(dataGrid, indentSpaces) { + for (const node of dataGrid.rootNode().children) { + const children = Array.from(node.element().children).filter(function(element) { + return !element.classList.contains('responseTime-column'); + }); + + const entries = Array.from(children, td => td.textContent).filter(text => text); + TestRunner.addResult(' '.repeat(8) + entries.join(', ')); + } + } + UI.panels.resources._sidebar.cacheStorageListTreeElement.expand(); - TestRunner.addResult('Dumping CacheStorage tree:'); + + if (!pathFilter) + TestRunner.addResult('Dumping CacheStorage tree:'); + else + TestRunner.addResult('Dumping CacheStorage tree with URL path filter string "' + pathFilter + '"'); + const cachesTreeElement = UI.panels.resources._sidebar.cacheStorageListTreeElement; if (!cachesTreeElement.childCount()) { @@ -29,31 +45,29 @@ ApplicationTestRunner.dumpCacheTreeNoRefresh = async function() { const cacheTreeElement = cachesTreeElement.childAt(i); TestRunner.addResult(' cache: ' + cacheTreeElement.title); let view = cacheTreeElement._view; - promise = TestRunner.addSnifferPromise(Resources.ServiceWorkerCacheView.prototype, '_updateDataCallback'); if (!view) cacheTreeElement.onselect(false); - else - view._updateData(true); - view = cacheTreeElement._view; - await promise; - - if (view._entriesForTest.length === 0) { + await view._updateData(true); + if (cacheTreeElement._view._entriesForTest.length === 0) { TestRunner.addResult(' (cache empty)'); continue; } - const dataGrid = view._dataGrid; - - for (const node of dataGrid.rootNode().children) { - const children = Array.from(node.element().children).filter(function(element) { - return !element.classList.contains('responseTime-column'); - }); - - const entries = Array.from(children, td => td.textContent).filter(text => text); - TestRunner.addResult(' ' + entries.join(', ')); + if (!pathFilter) { + _dumpDataGrid(view._dataGrid); + continue; } + + cacheTreeElement._view._entryPathFilter = pathFilter; + await view._updateData(true); + if (cacheTreeElement._view._entriesForTest.length === 0) { + TestRunner.addResult(' (no matching entries)'); + continue; + } + + _dumpDataGrid(cacheTreeElement._view._dataGrid); } }; diff --git a/front_end/resources/ServiceWorkerCacheViews.js b/front_end/resources/ServiceWorkerCacheViews.js index 1b43324e8d..f8f553afbe 100644 --- a/front_end/resources/ServiceWorkerCacheViews.js +++ b/front_end/resources/ServiceWorkerCacheViews.js @@ -55,12 +55,32 @@ Resources.ServiceWorkerCacheView = class extends UI.SimpleView { this._deleteSelectedButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._deleteButtonClicked(null)); editorToolbar.appendToolbarItem(this._deleteSelectedButton); + const entryPathFilterBox = new UI.ToolbarInput(ls`Filter by Path`, 1); + editorToolbar.appendToolbarItem(entryPathFilterBox); + const entryPathFilterThrottler = new Common.Throttler(300); + this._entryPathFilter = ''; + entryPathFilterBox.addEventListener(UI.ToolbarInput.Event.TextChanged, () => { + entryPathFilterThrottler.schedule(() => { + this._entryPathFilter = entryPathFilterBox.value(); + this._skipCount = 0; + return this._updateData(true); + }); + }); + this._pageSize = 50; this._skipCount = 0; this.update(cache); } + _resetDataGrid() { + if (this._dataGrid) + this._dataGrid.asWidget().detach(); + this._dataGrid = this._createDataGrid(); + this._splitWidget.setSidebarWidget(this._dataGrid.asWidget()); + this._skipCount = 0; + } + /** * @override */ @@ -185,12 +205,7 @@ Resources.ServiceWorkerCacheView = class extends UI.SimpleView { */ update(cache) { this._cache = cache; - - if (this._dataGrid) - this._dataGrid.asWidget().detach(); - this._dataGrid = this._createDataGrid(); - this._splitWidget.setSidebarWidget(this._dataGrid.asWidget()); - this._skipCount = 0; + this._resetDataGrid(); this._updateData(true); } @@ -247,7 +262,13 @@ Resources.ServiceWorkerCacheView = class extends UI.SimpleView { } this._lastPageSize = pageSize; this._lastSkipCount = skipCount; - this._model.loadCacheData(this._cache, skipCount, pageSize, this._updateDataCallback.bind(this, skipCount)); + + return new Promise(resolve => { + this._model.loadCacheData(this._cache, skipCount, pageSize, this._entryPathFilter, (entries, hasMore) => { + this._updateDataCallback(skipCount, entries, hasMore); + resolve(); + }); + }); } /** diff --git a/front_end/sdk/ServiceWorkerCacheModel.js b/front_end/sdk/ServiceWorkerCacheModel.js index 2c502a230f..d8f23f54de 100644 --- a/front_end/sdk/ServiceWorkerCacheModel.js +++ b/front_end/sdk/ServiceWorkerCacheModel.js @@ -91,10 +91,11 @@ SDK.ServiceWorkerCacheModel = class extends SDK.SDKModel { * @param {!SDK.ServiceWorkerCacheModel.Cache} cache * @param {number} skipCount * @param {number} pageSize + * @param {string} pathFilter * @param {function(!Array., boolean)} callback */ - loadCacheData(cache, skipCount, pageSize, callback) { - this._requestEntries(cache, skipCount, pageSize, callback); + loadCacheData(cache, skipCount, pageSize, pathFilter, callback) { + this._requestEntries(cache, skipCount, pageSize, pathFilter, callback); } /** @@ -233,10 +234,12 @@ SDK.ServiceWorkerCacheModel = class extends SDK.SDKModel { * @param {!SDK.ServiceWorkerCacheModel.Cache} cache * @param {number} skipCount * @param {number} pageSize + * @param {string} pathFilter * @param {function(!Array, boolean)} callback */ - async _requestEntries(cache, skipCount, pageSize, callback) { - const response = await this._cacheAgent.invoke_requestEntries({cacheId: cache.cacheId, skipCount, pageSize}); + async _requestEntries(cache, skipCount, pageSize, pathFilter, callback) { + const response = + await this._cacheAgent.invoke_requestEntries({cacheId: cache.cacheId, skipCount, pageSize, pathFilter}); if (response[Protocol.Error]) { console.error('ServiceWorkerCacheAgent error while requesting entries: ', response[Protocol.Error]); return;