Commit 11493585 authored by Eugene Ostroukhov's avatar Eugene Ostroukhov Committed by Commit Bot

[DevTools] Add filter to service workers list

Bug: 729042
Change-Id: I0ba4587ad68e65ae04b7d4a6ac99f882df3e9603
Reviewed-on: https://chromium-review.googlesource.com/682345Reviewed-by: default avatarPavel Feldman <pfeldman@chromium.org>
Commit-Queue: Eugene Ostroukhov <eostroukhov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#513319}
parent 86d41cbe
...@@ -40,7 +40,7 @@ function test() { ...@@ -40,7 +40,7 @@ function test() {
var scorer = new Sources.FilePathScoreFunction(query); var scorer = new Sources.FilePathScoreFunction(query);
var bestScore = -1; var bestScore = -1;
var bestIndex = -1; var bestIndex = -1;
var filter = QuickOpen.FilteredListWidget.filterRegex(query); var filter = String.filterRegex(query);
for (var i = 0; i < paths.length; ++i) { for (var i = 0; i < paths.length; ++i) {
if (!filter.test(paths[i])) if (!filter.test(paths[i]))
continue; continue;
......
...@@ -90,7 +90,6 @@ Status ...@@ -90,7 +90,6 @@ Status
#N is redundant #N is redundant
Clients Clients
Push Push
xxxxxxxxxx
   
Test Test
......
...@@ -43,7 +43,8 @@ ApplicationTestRunner.waitForServiceWorker = function(callback) { ...@@ -43,7 +43,8 @@ ApplicationTestRunner.waitForServiceWorker = function(callback) {
ApplicationTestRunner.dumpServiceWorkersView = function() { ApplicationTestRunner.dumpServiceWorkersView = function() {
var swView = UI.panels.resources.visibleView; var swView = UI.panels.resources.visibleView;
return swView._reportView._sectionList.childTextNodes() return swView._currentWorkersView._sectionList.childTextNodes()
.concat(swView._otherWorkersView._sectionList.childTextNodes())
.map(function(node) { .map(function(node) {
return node.textContent.replace(/Received.*/, 'Received').replace(/#\d+/, '#N'); return node.textContent.replace(/Received.*/, 'Received').replace(/#\d+/, '#N');
}) })
......
...@@ -158,7 +158,9 @@ Common.ParsedURL = class { ...@@ -158,7 +158,9 @@ Common.ParsedURL = class {
*/ */
static extractName(url) { static extractName(url) {
var index = url.lastIndexOf('/'); var index = url.lastIndexOf('/');
return index !== -1 ? url.substr(index + 1) : url; var pathAndQuery = index !== -1 ? url.substr(index + 1) : url;
index = pathAndQuery.indexOf('?');
return index < 0 ? pathAndQuery : pathAndQuery.substr(0, index);
} }
/** /**
......
...@@ -125,6 +125,24 @@ String.prototype.escapeForRegExp = function() { ...@@ -125,6 +125,24 @@ String.prototype.escapeForRegExp = function() {
return this.escapeCharacters(String.regexSpecialCharacters()); return this.escapeCharacters(String.regexSpecialCharacters());
}; };
/**
* @param {string} query
* @return {!RegExp}
*/
String.filterRegex = function(query) {
const toEscape = String.regexSpecialCharacters();
var regexString = '';
for (var i = 0; i < query.length; ++i) {
var c = query.charAt(i);
if (toEscape.indexOf(c) !== -1)
c = '\\' + c;
if (i)
regexString += '[^\\0' + c + ']*';
regexString += c;
}
return new RegExp(regexString, 'i');
};
/** /**
* @return {string} * @return {string}
*/ */
......
...@@ -53,24 +53,6 @@ QuickOpen.FilteredListWidget = class extends UI.VBox { ...@@ -53,24 +53,6 @@ QuickOpen.FilteredListWidget = class extends UI.VBox {
this._queryChangedCallback = queryChangedCallback; this._queryChangedCallback = queryChangedCallback;
} }
/**
* @param {string} query
* @return {!RegExp}
*/
static filterRegex(query) {
const toEscape = String.regexSpecialCharacters();
var regexString = '';
for (var i = 0; i < query.length; ++i) {
var c = query.charAt(i);
if (toEscape.indexOf(c) !== -1)
c = '\\' + c;
if (i)
regexString += '[^\\0' + c + ']*';
regexString += c;
}
return new RegExp(regexString, 'i');
}
/** /**
* @param {!Element} element * @param {!Element} element
* @param {string} query * @param {string} query
...@@ -346,7 +328,7 @@ QuickOpen.FilteredListWidget = class extends UI.VBox { ...@@ -346,7 +328,7 @@ QuickOpen.FilteredListWidget = class extends UI.VBox {
var query = this._provider.rewriteQuery(this._cleanValue()); var query = this._provider.rewriteQuery(this._cleanValue());
this._query = query; this._query = query;
var filterRegex = query ? QuickOpen.FilteredListWidget.filterRegex(query) : null; var filterRegex = query ? String.filterRegex(query) : null;
var filteredItems = []; var filteredItems = [];
......
...@@ -7,11 +7,14 @@ ...@@ -7,11 +7,14 @@
Resources.ServiceWorkersView = class extends UI.VBox { Resources.ServiceWorkersView = class extends UI.VBox {
constructor() { constructor() {
super(true); super(true);
this.registerRequiredCSS('resources/serviceWorkersView.css');
this._reportView = new UI.ReportView(Common.UIString('Service Workers')); this._currentWorkersView = new UI.ReportView(Common.UIString('Service Workers'));
this._reportView.show(this.contentElement); this.contentElement.classList.add('service-worker-list');
this._currentWorkersView.show(this.contentElement);
this._currentWorkersView.element.classList.add('service-workers-this-origin');
this._toolbar = this._reportView.createToolbar(); this._toolbar = this._currentWorkersView.createToolbar();
this._toolbar.makeWrappable(false, true); this._toolbar.makeWrappable(false, true);
/** @type {!Map<!SDK.ServiceWorkerRegistration, !Resources.ServiceWorkersView.Section>} */ /** @type {!Map<!SDK.ServiceWorkerRegistration, !Resources.ServiceWorkersView.Section>} */
...@@ -22,6 +25,29 @@ Resources.ServiceWorkersView = class extends UI.VBox { ...@@ -22,6 +25,29 @@ Resources.ServiceWorkersView = class extends UI.VBox {
/** @type {?SDK.SecurityOriginManager} */ /** @type {?SDK.SecurityOriginManager} */
this._securityOriginManager = null; this._securityOriginManager = null;
this._filterThrottler = new Common.Throttler(300);
this._otherWorkers = this.contentElement.createChild('div', 'service-workers-other-origin');
var filterElement = this._otherWorkers.createChild('div', 'service-worker-filter');
this._checkboxElement = filterElement.createChild('input', 'service-worker-filter-show-all-checkbox');
this._checkboxElement.type = 'checkbox';
this._checkboxElement.setAttribute('id', 'expand-all');
this._textElement = filterElement.createChild('label', 'service-worker-filter-label');
this._textElement.textContent = Common.UIString('Service workers from other domains');
this._textElement.setAttribute('for', 'expand-all');
this._checkboxElement.addEventListener('change', () => this._filterChanged());
var toolbar = new UI.Toolbar('service-worker-filter-toolbar', filterElement);
this._filter = new UI.ToolbarInput('Filter', 1);
this._filter.addEventListener(UI.ToolbarInput.Event.TextChanged, () => this._filterChanged());
toolbar.appendToolbarItem(this._filter);
this._otherWorkersView = new UI.ReportView();
this._otherWorkersView.show(this._otherWorkers);
this._otherWorkersView.element.classList.add('service-workers-for-other-origins');
this._updateCollapsedStyle();
this._toolbar.appendToolbarItem(MobileThrottling.throttlingManager().createOfflineToolbarCheckbox()); this._toolbar.appendToolbarItem(MobileThrottling.throttlingManager().createOfflineToolbarCheckbox());
var updateOnReloadSetting = Common.settings.createSetting('serviceWorkerUpdateOnReload', false); var updateOnReloadSetting = Common.settings.createSetting('serviceWorkerUpdateOnReload', false);
updateOnReloadSetting.setTitle(Common.UIString('Update on reload')); updateOnReloadSetting.setTitle(Common.UIString('Update on reload'));
...@@ -33,11 +59,6 @@ Resources.ServiceWorkersView = class extends UI.VBox { ...@@ -33,11 +59,6 @@ Resources.ServiceWorkersView = class extends UI.VBox {
var fallbackToNetwork = new UI.ToolbarSettingCheckbox( var fallbackToNetwork = new UI.ToolbarSettingCheckbox(
bypassServiceWorkerSetting, Common.UIString('Bypass Service Worker and load resources from the network')); bypassServiceWorkerSetting, Common.UIString('Bypass Service Worker and load resources from the network'));
this._toolbar.appendToolbarItem(fallbackToNetwork); this._toolbar.appendToolbarItem(fallbackToNetwork);
this._showAllCheckbox = new UI.ToolbarCheckbox(
Common.UIString('Show all'), Common.UIString('Show all Service Workers regardless of the origin'));
this._showAllCheckbox.setRightAligned(true);
this._showAllCheckbox.inputElement.addEventListener('change', this._updateSectionVisibility.bind(this), false);
this._toolbar.appendToolbarItem(this._showAllCheckbox);
/** @type {!Map<!SDK.ServiceWorkerManager, !Array<!Common.EventTarget.EventDescriptor>>}*/ /** @type {!Map<!SDK.ServiceWorkerManager, !Array<!Common.EventTarget.EventDescriptor>>}*/
this._eventListeners = new Map(); this._eventListeners = new Map();
...@@ -84,27 +105,37 @@ Resources.ServiceWorkersView = class extends UI.VBox { ...@@ -84,27 +105,37 @@ Resources.ServiceWorkersView = class extends UI.VBox {
} }
_updateSectionVisibility() { _updateSectionVisibility() {
var securityOrigins = new Set(this._securityOriginManager.securityOrigins()); var hasOthers = false;
var matchingSections = new Set(); var hasThis = false;
var movedSections = [];
for (var section of this._sections.values()) { for (var section of this._sections.values()) {
if (securityOrigins.has(section._registration.securityOrigin)) var expectedView = this._getReportViewForOrigin(section._registration.securityOrigin);
matchingSections.add(section._section); hasOthers |= expectedView === this._otherWorkersView;
hasThis |= expectedView === this._currentWorkersView;
if (section._section.parentWidget() !== expectedView)
movedSections.push(section);
} }
this._reportView.sortSections((a, b) => { for (var section of movedSections) {
var aMatching = matchingSections.has(a); var registration = section._registration;
var bMatching = matchingSections.has(b); this._removeRegistrationFromList(registration);
if (aMatching === bMatching) this._updateRegistration(registration, true);
return a.title().localeCompare(b.title()); }
return aMatching ? -1 : 1;
});
var scorer = new Sources.FilePathScoreFunction(this._filter.value());
this._otherWorkersView.sortSections((a, b) => {
var cmp = scorer.score(b.title(), null) - scorer.score(a.title(), null);
return cmp === 0 ? a.title().localeCompare(b.title()) : cmp;
});
for (var section of this._sections.values()) { for (var section of this._sections.values()) {
if (this._showAllCheckbox.checked() || securityOrigins.has(section._registration.securityOrigin)) if (section._section.parentWidget() === this._currentWorkersView ||
this._isRegistrationVisible(section._registration))
section._section.showWidget(); section._section.showWidget();
else else
section._section.hideWidget(); section._section.hideWidget();
} }
this.contentElement.classList.toggle('service-worker-has-current', hasThis);
this._otherWorkers.classList.toggle('hidden', !hasOthers);
} }
/** /**
...@@ -120,8 +151,7 @@ Resources.ServiceWorkersView = class extends UI.VBox { ...@@ -120,8 +151,7 @@ Resources.ServiceWorkersView = class extends UI.VBox {
var hasNonDeletedRegistrations = false; var hasNonDeletedRegistrations = false;
var securityOrigins = new Set(this._securityOriginManager.securityOrigins()); var securityOrigins = new Set(this._securityOriginManager.securityOrigins());
for (var registration of this._manager.registrations().values()) { for (var registration of this._manager.registrations().values()) {
var visible = this._showAllCheckbox.checked() || securityOrigins.has(registration.securityOrigin); if (!securityOrigins.has(registration.securityOrigin) && !this._isRegistrationVisible(registration))
if (!visible)
continue; continue;
if (!registration.canBeRemoved()) { if (!registration.canBeRemoved()) {
hasNonDeletedRegistrations = true; hasNonDeletedRegistrations = true;
...@@ -133,24 +163,38 @@ Resources.ServiceWorkersView = class extends UI.VBox { ...@@ -133,24 +163,38 @@ Resources.ServiceWorkersView = class extends UI.VBox {
return; return;
for (var registration of this._manager.registrations().values()) { for (var registration of this._manager.registrations().values()) {
var visible = this._showAllCheckbox.checked() || securityOrigins.has(registration.securityOrigin); var visible = securityOrigins.has(registration.securityOrigin) || this._isRegistrationVisible(registration);
if (visible && registration.canBeRemoved()) if (!visible && registration.canBeRemoved())
this._removeRegistrationFromList(registration); this._removeRegistrationFromList(registration);
} }
} }
/**
* @param {string} origin
* @return {!UI.ReportView}
*/
_getReportViewForOrigin(origin) {
if (this._securityOriginManager.securityOrigins().includes(origin))
return this._currentWorkersView;
else
return this._otherWorkersView;
}
/** /**
* @param {!SDK.ServiceWorkerRegistration} registration * @param {!SDK.ServiceWorkerRegistration} registration
* @param {boolean=} skipUpdate
*/ */
_updateRegistration(registration) { _updateRegistration(registration, skipUpdate) {
var section = this._sections.get(registration); var section = this._sections.get(registration);
if (!section) { if (!section) {
var title = Resources.ServiceWorkersView._displayScopeURL(registration.scopeURL);
section = new Resources.ServiceWorkersView.Section( section = new Resources.ServiceWorkersView.Section(
/** @type {!SDK.ServiceWorkerManager} */ (this._manager), /** @type {!SDK.ServiceWorkerManager} */ (this._manager),
this._reportView.appendSection(Resources.ServiceWorkersView._displayScopeURL(registration.scopeURL)), this._getReportViewForOrigin(registration.securityOrigin).appendSection(title), registration);
registration);
this._sections.set(registration, section); this._sections.set(registration, section);
} }
if (skipUpdate)
return;
this._updateSectionVisibility(); this._updateSectionVisibility();
section._scheduleUpdate(); section._scheduleUpdate();
} }
...@@ -171,6 +215,35 @@ Resources.ServiceWorkersView = class extends UI.VBox { ...@@ -171,6 +215,35 @@ Resources.ServiceWorkersView = class extends UI.VBox {
if (section) if (section)
section._section.detach(); section._section.detach();
this._sections.delete(registration); this._sections.delete(registration);
this._updateSectionVisibility();
}
/**
* @param {!SDK.ServiceWorkerRegistration} registration
* @return {boolean}
*/
_isRegistrationVisible(registration) {
var filterString = this._filter.value();
if (!filterString || !registration.scopeURL)
return true;
var regex = String.filterRegex(filterString);
return registration.scopeURL.match(regex);
}
_filterChanged() {
this._updateCollapsedStyle();
this._filterThrottler.schedule(() => Promise.resolve(this._updateSectionVisibility()));
}
_updateCollapsedStyle() {
var collapsed = !this._checkboxElement.checked;
this._otherWorkers.classList.toggle('service-worker-filter-collapsed', collapsed);
if (collapsed)
this._otherWorkersView.hideWidget();
else
this._otherWorkersView.showWidget();
this._otherWorkersView.setHeaderVisible(false);
} }
/** /**
......
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
"object_ui", "object_ui",
"perf_ui", "perf_ui",
"mobile_throttling", "mobile_throttling",
"network" "network",
"sources"
], ],
"scripts": [ "scripts": [
"ApplicationCacheModel.js", "ApplicationCacheModel.js",
......
...@@ -111,3 +111,73 @@ ...@@ -111,3 +111,73 @@
/** Simulate CodeMirror that is shown above */ /** Simulate CodeMirror that is shown above */
padding: 4px; padding: 4px;
} }
.service-worker-list {
background-color: #f9f9f9;
}
.service-workers-this-origin {
flex-shrink: 0;
flex-grow: 0;
}
.service-workers-other-origin {
display: flex;
flex-direction: column;
flex-grow: 1;
flex-shrink: 1;
}
.service-worker-has-current .service-workers-other-origin {
margin-top: 16px;
border-top: 1px solid rgb(230, 230, 230)
}
.service-worker-filter{
padding: 16px 20px 12px 12px;
flex-grow: 0;
flex-shrink: 0;
background-color: white;
border-bottom: solid 1px rgb(230, 230, 230);
}
.service-worker-filter-show-all-checkbox {
height: 1px;
width: 1px;
margin: 0;
}
.service-worker-filter-label {
cursor: pointer;
margin-left: 4px;
}
.service-worker-filter-label::before {
-webkit-user-select: none;
-webkit-mask-image: url(Images/treeoutlineTriangles.png);
-webkit-mask-size: 32px 24px;
content: "aa";
color: transparent;
background-color: rgb(110, 110, 110);
text-shadow: none;
height: 12px;
}
@media (-webkit-min-device-pixel-ratio: 1.1) {
.service-worker-filter-label::before {
-webkit-mask-image: url(Images/treeoutlineTriangles_2x.png);
}
} /* media */
.service-worker-filter-show-all-checkbox:checked + .service-worker-filter-label::before {
-webkit-mask-position: -16px 0;
}
.service-worker-filter-toolbar {
margin: 8px 10px 0 12px;
max-width: 530px;
}
.service-worker-filter-collapsed .service-worker-filter-toolbar {
display: none;
}
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*/ */
UI.ReportView = class extends UI.VBox { UI.ReportView = class extends UI.VBox {
/** /**
* @param {string} title * @param {string=} title
*/ */
constructor(title) { constructor(title) {
super(true); super(true);
...@@ -85,6 +85,13 @@ UI.ReportView = class extends UI.VBox { ...@@ -85,6 +85,13 @@ UI.ReportView = class extends UI.VBox {
for (var section of sections) for (var section of sections)
section.show(this._sectionList); section.show(this._sectionList);
} }
/**
* @param {boolean} visible
*/
setHeaderVisible(visible) {
this._headerElement.classList.toggle('hidden', !visible);
}
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment