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() {
var scorer = new Sources.FilePathScoreFunction(query);
var bestScore = -1;
var bestIndex = -1;
var filter = QuickOpen.FilteredListWidget.filterRegex(query);
var filter = String.filterRegex(query);
for (var i = 0; i < paths.length; ++i) {
if (!filter.test(paths[i]))
continue;
......
......@@ -90,7 +90,6 @@ Status
#N is redundant
Clients
Push
xxxxxxxxxx
 
Test
......
......@@ -43,7 +43,8 @@ ApplicationTestRunner.waitForServiceWorker = function(callback) {
ApplicationTestRunner.dumpServiceWorkersView = function() {
var swView = UI.panels.resources.visibleView;
return swView._reportView._sectionList.childTextNodes()
return swView._currentWorkersView._sectionList.childTextNodes()
.concat(swView._otherWorkersView._sectionList.childTextNodes())
.map(function(node) {
return node.textContent.replace(/Received.*/, 'Received').replace(/#\d+/, '#N');
})
......
......@@ -158,7 +158,9 @@ Common.ParsedURL = class {
*/
static extractName(url) {
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() {
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}
*/
......
......@@ -53,24 +53,6 @@ QuickOpen.FilteredListWidget = class extends UI.VBox {
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 {string} query
......@@ -346,7 +328,7 @@ QuickOpen.FilteredListWidget = class extends UI.VBox {
var query = this._provider.rewriteQuery(this._cleanValue());
this._query = query;
var filterRegex = query ? QuickOpen.FilteredListWidget.filterRegex(query) : null;
var filterRegex = query ? String.filterRegex(query) : null;
var filteredItems = [];
......
......@@ -7,11 +7,14 @@
Resources.ServiceWorkersView = class extends UI.VBox {
constructor() {
super(true);
this.registerRequiredCSS('resources/serviceWorkersView.css');
this._reportView = new UI.ReportView(Common.UIString('Service Workers'));
this._reportView.show(this.contentElement);
this._currentWorkersView = new UI.ReportView(Common.UIString('Service Workers'));
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);
/** @type {!Map<!SDK.ServiceWorkerRegistration, !Resources.ServiceWorkersView.Section>} */
......@@ -22,6 +25,29 @@ Resources.ServiceWorkersView = class extends UI.VBox {
/** @type {?SDK.SecurityOriginManager} */
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());
var updateOnReloadSetting = Common.settings.createSetting('serviceWorkerUpdateOnReload', false);
updateOnReloadSetting.setTitle(Common.UIString('Update on reload'));
......@@ -33,11 +59,6 @@ Resources.ServiceWorkersView = class extends UI.VBox {
var fallbackToNetwork = new UI.ToolbarSettingCheckbox(
bypassServiceWorkerSetting, Common.UIString('Bypass Service Worker and load resources from the network'));
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>>}*/
this._eventListeners = new Map();
......@@ -84,27 +105,37 @@ Resources.ServiceWorkersView = class extends UI.VBox {
}
_updateSectionVisibility() {
var securityOrigins = new Set(this._securityOriginManager.securityOrigins());
var matchingSections = new Set();
var hasOthers = false;
var hasThis = false;
var movedSections = [];
for (var section of this._sections.values()) {
if (securityOrigins.has(section._registration.securityOrigin))
matchingSections.add(section._section);
var expectedView = this._getReportViewForOrigin(section._registration.securityOrigin);
hasOthers |= expectedView === this._otherWorkersView;
hasThis |= expectedView === this._currentWorkersView;
if (section._section.parentWidget() !== expectedView)
movedSections.push(section);
}
this._reportView.sortSections((a, b) => {
var aMatching = matchingSections.has(a);
var bMatching = matchingSections.has(b);
if (aMatching === bMatching)
return a.title().localeCompare(b.title());
return aMatching ? -1 : 1;
});
for (var section of movedSections) {
var registration = section._registration;
this._removeRegistrationFromList(registration);
this._updateRegistration(registration, true);
}
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()) {
if (this._showAllCheckbox.checked() || securityOrigins.has(section._registration.securityOrigin))
if (section._section.parentWidget() === this._currentWorkersView ||
this._isRegistrationVisible(section._registration))
section._section.showWidget();
else
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 {
var hasNonDeletedRegistrations = false;
var securityOrigins = new Set(this._securityOriginManager.securityOrigins());
for (var registration of this._manager.registrations().values()) {
var visible = this._showAllCheckbox.checked() || securityOrigins.has(registration.securityOrigin);
if (!visible)
if (!securityOrigins.has(registration.securityOrigin) && !this._isRegistrationVisible(registration))
continue;
if (!registration.canBeRemoved()) {
hasNonDeletedRegistrations = true;
......@@ -133,24 +163,38 @@ Resources.ServiceWorkersView = class extends UI.VBox {
return;
for (var registration of this._manager.registrations().values()) {
var visible = this._showAllCheckbox.checked() || securityOrigins.has(registration.securityOrigin);
if (visible && registration.canBeRemoved())
var visible = securityOrigins.has(registration.securityOrigin) || this._isRegistrationVisible(registration);
if (!visible && registration.canBeRemoved())
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 {boolean=} skipUpdate
*/
_updateRegistration(registration) {
_updateRegistration(registration, skipUpdate) {
var section = this._sections.get(registration);
if (!section) {
var title = Resources.ServiceWorkersView._displayScopeURL(registration.scopeURL);
section = new Resources.ServiceWorkersView.Section(
/** @type {!SDK.ServiceWorkerManager} */ (this._manager),
this._reportView.appendSection(Resources.ServiceWorkersView._displayScopeURL(registration.scopeURL)),
registration);
this._getReportViewForOrigin(registration.securityOrigin).appendSection(title), registration);
this._sections.set(registration, section);
}
if (skipUpdate)
return;
this._updateSectionVisibility();
section._scheduleUpdate();
}
......@@ -171,6 +215,35 @@ Resources.ServiceWorkersView = class extends UI.VBox {
if (section)
section._section.detach();
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 @@
"object_ui",
"perf_ui",
"mobile_throttling",
"network"
"network",
"sources"
],
"scripts": [
"ApplicationCacheModel.js",
......
......@@ -111,3 +111,73 @@
/** Simulate CodeMirror that is shown above */
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 @@
*/
UI.ReportView = class extends UI.VBox {
/**
* @param {string} title
* @param {string=} title
*/
constructor(title) {
super(true);
......@@ -85,6 +85,13 @@ UI.ReportView = class extends UI.VBox {
for (var section of sections)
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