[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 <dgozman@chromium.org>
Commit-Queue: Haihong Li (Harley) <hhli@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#613204}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 3c68e3a7bc37f6eeb338e7768735087ae469a329
This commit is contained in:
Harley Li
2018-12-03 19:55:54 +00:00
committed by Commit Bot
parent a06cbef9f6
commit 574c7204c8
3 changed files with 69 additions and 31 deletions
@@ -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);
}
};
+28 -7
View File
@@ -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();
});
});
}
/**
+7 -4
View File
@@ -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.<!Protocol.CacheStorage.DataEntry>, 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<!Protocol.CacheStorage.DataEntry>, 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;