Chromium Code Reviews| Index: Source/devtools/front_end/network/BlockedURLsPane.js |
| diff --git a/Source/devtools/front_end/network/BlockedURLsPane.js b/Source/devtools/front_end/network/BlockedURLsPane.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ee60524167c90ac652f96e6976037f9c04a7c009 |
| --- /dev/null |
| +++ b/Source/devtools/front_end/network/BlockedURLsPane.js |
| @@ -0,0 +1,290 @@ |
| +// Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +/** |
| + * @constructor |
| + * @extends {WebInspector.VBox} |
| + */ |
| +WebInspector.BlockedURLsPane = function() |
| +{ |
| + WebInspector.VBox.call(this); |
| + this.element.classList.add("blocked-urls"); |
| + this.registerRequiredCSS("network/blockedURLsPane.css"); |
|
pfeldman
2015/08/28 17:15:49
Since you have a css, could you move it into shado
dgozman
2015/08/31 21:17:39
Definitely.
|
| + |
| + this._blockedURLsSetting = WebInspector.moduleSetting("blockedURLs"); |
| + this._blockedURLsSetting.addChangeListener(this._update, this); |
| + |
| + this._toolbar = new WebInspector.Toolbar(this.element); |
| + this._toolbar.element.addEventListener("click", consumeEvent); |
| + this._toolbar.appendToolbarItem(new WebInspector.ToolbarText(WebInspector.UIString("Requests containing following URLs will be blocked"))); |
| + this._toolbar.appendToolbarItem(new WebInspector.ToolbarSpace()); |
|
pfeldman
2015/08/28 17:15:49
Toolbar is a continuous set of buttons. Lets move
dgozman
2015/08/31 21:17:39
Changed to custom element.
|
| + var addButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add URL"), "add-toolbar-item"); |
| + addButton.addEventListener("click", this._addButtonClicked.bind(this)); |
| + this._toolbar.appendToolbarItem(addButton); |
| + var clearButton = new WebInspector.ToolbarButton(WebInspector.UIString("Remove all"), "clear-toolbar-item"); |
| + clearButton.addEventListener("click", this._removeAllButtonClicked.bind(this)); |
| + this._toolbar.appendToolbarItem(clearButton); |
| + |
| + this._emptyElement = this.element.createChild("div", "no-blocked-urls"); |
| + this._emptyElement.textContent = WebInspector.UIString("No blocked URLs"); |
| + this._emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true); |
| + |
| + this._listElement = this.element.createChild("div", "blocked-urls-list"); |
| + this._filterUI = new WebInspector.BlockedURLsPane.FilterUI(); |
| + |
| + /** @type {!Array<!WebInspector.NetworkRequest>} */ |
| + this._blockedRequests = []; |
| + WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this); |
| + |
| + this._update(); |
| +} |
| + |
| +WebInspector.BlockedURLsPane.prototype = { |
| + /** |
| + * @return {!WebInspector.FilterUI} |
| + */ |
| + filterUI: function() |
| + { |
| + return this._filterUI; |
| + }, |
| + |
| + /** |
| + * @param {!Event} event |
| + */ |
| + _emptyElementContextMenu: function(event) |
| + { |
| + var contextMenu = new WebInspector.ContextMenu(event); |
| + contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^URL"), this._addButtonClicked.bind(this)); |
| + contextMenu.show(); |
| + }, |
| + |
| + /** |
| + * @param {!WebInspector.Event=} event |
| + */ |
| + _addButtonClicked: function(event) |
| + { |
| + if (event) |
| + event.consume(); |
|
pfeldman
2015/08/28 17:15:49
Why consuming WebInspectorEvent?
dgozman
2015/08/31 21:17:39
Copy-pasta :)
|
| + |
| + var element = this._createElement("", this._blockedURLsSetting.get().length); |
| + this._listElement.appendChild(element); |
| + element.scrollIntoView(); |
| + |
| + /** |
| + * @param {boolean} accept |
| + * @param {!Element} e |
| + * @param {string} text |
| + * @this {WebInspector.BlockedURLsPane} |
| + */ |
| + function finishEditing(accept, e, text) |
| + { |
| + this._listElement.removeChild(element); |
| + if (accept && text) |
| + this._addBlockedURL(text); |
| + } |
| + |
| + WebInspector.InplaceEditor.startEditing(element._label, new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false))); |
| + }, |
| + |
| + /** |
| + * @param {string} url |
| + */ |
| + _addBlockedURL: function(url) |
| + { |
| + var blocked = this._blockedURLsSetting.get(); |
| + blocked.push(url); |
| + this._blockedURLsSetting.set(blocked); |
| + }, |
| + |
| + /** |
| + * @param {number} index |
| + */ |
| + _removeBlockedURL: function(index) |
| + { |
| + var blocked = this._blockedURLsSetting.get(); |
| + blocked.splice(index, 1); |
| + this._blockedURLsSetting.set(blocked); |
| + }, |
| + |
| + /** |
| + * @param {number} index |
| + * @param {string} url |
| + */ |
| + _changeBlockedURL: function(index, url) |
| + { |
| + var blocked = this._blockedURLsSetting.get(); |
| + blocked.splice(index, 1, url); |
| + this._blockedURLsSetting.set(blocked); |
| + }, |
| + |
| + /** |
| + * @param {!WebInspector.Event=} event |
| + */ |
| + _removeAllButtonClicked: function(event) |
| + { |
| + if (event) |
| + event.consume(); |
| + this._blockedURLsSetting.set([]); |
| + }, |
| + |
| + /** |
| + * @param {number} index |
| + * @param {!Event} event |
| + */ |
| + _contextMenu: function(index, event) |
| + { |
| + var contextMenu = new WebInspector.ContextMenu(event); |
| + contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^URL"), this._addButtonClicked.bind(this)); |
| + contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^URL"), this._removeBlockedURL.bind(this, index)); |
| + contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^all"), this._removeAllButtonClicked.bind(this)); |
| + contextMenu.show(); |
| + }, |
| + |
| + /** |
| + * @param {!Element} element |
| + * @param {number} index |
| + */ |
| + _labelClicked: function(element, index) |
| + { |
| + /** |
| + * @param {boolean} accept |
| + * @param {!Element} e |
| + * @param {string} text |
| + * @this {WebInspector.BlockedURLsPane} |
| + */ |
| + function finishEditing(accept, e, text) |
| + { |
| + if (accept) |
| + this._changeBlockedURL(index, text); |
| + } |
| + |
| + WebInspector.InplaceEditor.startEditing(element, new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false))); |
| + }, |
| + |
| + _update: function() |
| + { |
| + delete this._updateTimeout; |
| + |
| + this._listElement.removeChildren(); |
| + var blocked = this._blockedURLsSetting.get(); |
| + for (var index = 0; index < blocked.length; index++) |
| + this._listElement.appendChild(this._createElement(blocked[index], index)); |
| + |
| + this._emptyElement.classList.toggle("hidden", !!blocked.length); |
| + this._filterUI.setActive(!!blocked.length); |
| + this._filterUI.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged); |
| + }, |
| + |
| + /** |
| + * @param {string} url |
| + * @param {number} index |
| + * @return {!Element} |
| + */ |
| + _createElement: function(url, index) |
| + { |
| + var element = createElementWithClass("div", "blocked-url"); |
| + |
| + var label = element.createChild("div", "blocked-url-text"); |
| + element._label = label; |
| + label.textContent = url; |
| + |
| + var count = this._blockedRequestsCount(url); |
| + var countElement = element.createChild("div", "blocked-count monospace"); |
| + countElement.textContent = String.sprintf("[%d]", count); |
| + countElement.title = WebInspector.UIString(count === 1 ? "%d request blocked by this URL" : "%d requests blocked by this URL", count); |
| + |
| + var removeButton = element.createChild("div", "remove-button"); |
| + removeButton.title = WebInspector.UIString("Remove URL"); |
| + removeButton.addEventListener("click", this._removeBlockedURL.bind(this, index), false); |
| + |
| + element.addEventListener("contextmenu", this._contextMenu.bind(this, index), true); |
| + element.addEventListener("dblclick", this._labelClicked.bind(this, label, index), false); |
| + return element; |
| + }, |
| + |
| + /** |
| + * @param {string} url |
| + * @return {number} |
| + */ |
| + _blockedRequestsCount: function(url) |
| + { |
| + if (!url) |
| + return 0; |
| + |
| + var result = 0; |
| + for (var request of this._blockedRequests) { |
|
pfeldman
2015/08/28 17:15:49
Looks like you could have a URL -> count map inste
dgozman
2015/08/31 21:17:39
Done.
|
| + if (request.url.indexOf(url) !== -1) |
| + result++; |
| + } |
| + return result; |
| + }, |
| + |
| + reset: function() |
| + { |
| + this._blockedRequests = []; |
| + }, |
| + |
| + /** |
| + * @param {!WebInspector.Event} event |
| + */ |
| + _onRequestFinished: function(event) |
| + { |
| + var request = /** @type {!WebInspector.NetworkRequest} */ (event.data); |
| + if (request.blocked) { |
| + this._blockedRequests.push(request); |
| + this._scheduleUpdate(); |
| + } |
| + }, |
| + |
| + _scheduleUpdate: function() |
| + { |
| + if (!this._updateTimeout) |
|
pfeldman
2015/08/28 17:15:49
Should you use throttler here instead?
dgozman
2015/08/31 21:17:39
Done.
|
| + this._updateTimeout = this.element.window().setTimeout(this._update.bind(this), 200); |
| + }, |
| + |
| + __proto__: WebInspector.VBox.prototype |
| +} |
| + |
| + |
| +/** |
| + * @constructor |
| + * @extends {WebInspector.Object} |
| + * @implements {WebInspector.FilterUI} |
| + */ |
| +WebInspector.BlockedURLsPane.FilterUI = function() |
| +{ |
| + WebInspector.Object.call(this); |
| + this._active = false; |
| + this._element = createElement("span"); |
| +} |
| + |
| +WebInspector.BlockedURLsPane.FilterUI.prototype = { |
| + /** |
| + * @override |
| + * @return {boolean} |
| + */ |
| + isActive: function() |
| + { |
| + return this._active; |
| + }, |
| + |
| + /** |
| + * @param {boolean} active |
| + */ |
| + setActive: function(active) |
| + { |
| + this._active = active; |
| + }, |
| + |
| + /** |
| + * @override |
| + * @return {!Element} |
| + */ |
| + element: function() |
| + { |
| + return this._element; |
| + }, |
| + |
| + __proto__: WebInspector.Object.prototype |
| +} |