| // 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, true); |
| this.registerRequiredCSS("network/blockedURLsPane.css"); |
| this.contentElement.classList.add("blocked-urls-pane"); |
| |
| WebInspector.BlockedURLsPane._instance = this; |
| |
| this._blockedURLsSetting = WebInspector.moduleSetting("blockedURLs"); |
| this._blockedURLsSetting.addChangeListener(this._update, this); |
| |
| this._toolbar = new WebInspector.Toolbar("", this.contentElement); |
| this._toolbar.element.addEventListener("click", consumeEvent); |
| var addButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add pattern"), "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._removeAll.bind(this)); |
| this._toolbar.appendToolbarItem(clearButton); |
| |
| this._emptyElement = this.contentElement.createChild("div", "no-blocked-urls"); |
| this._emptyElement.createChild("span").textContent = WebInspector.UIString("Requests are not blocked. "); |
| var addLink = this._emptyElement.createChild("span", "link"); |
| addLink.textContent = WebInspector.UIString("Add pattern."); |
| addLink.href = ""; |
| addLink.addEventListener("click", this._addButtonClicked.bind(this), false); |
| this._emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true); |
| |
| this._listElement = this.contentElement.createChild("div", "blocked-urls-list"); |
| |
| /** @type {!Map<string, number>} */ |
| this._blockedCountForUrl = new Map(); |
| WebInspector.targetManager.addModelListener(WebInspector.NetworkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this); |
| |
| this._updateThrottler = new WebInspector.Throttler(200); |
| |
| this._update(); |
| } |
| |
| WebInspector.BlockedURLsPane.prototype = { |
| /** |
| * @param {!Event} event |
| */ |
| _emptyElementContextMenu: function(event) |
| { |
| var contextMenu = new WebInspector.ContextMenu(event); |
| contextMenu.appendItem(WebInspector.UIString.capitalize("Add ^pattern"), this._addButtonClicked.bind(this)); |
| contextMenu.show(); |
| }, |
| |
| _addButtonClicked: function() |
| { |
| this._emptyElement.classList.add("hidden"); |
| var element = this._createElement("", this._blockedURLsSetting.get().length); |
| this._listElement.appendChild(element); |
| element.scrollIntoViewIfNeeded(); |
| this._edit("", element, this._addBlockedURL.bind(this)); |
| }, |
| |
| /** |
| * @param {string} content |
| * @param {!Element} element |
| * @param {function(string)} onAccept |
| * @private |
| */ |
| _edit: function(content, element, onAccept) |
| { |
| this._editing = true; |
| |
| element.classList.add("blocked-url-editing"); |
| var input = element.createChild("input"); |
| input.setAttribute("type", "text"); |
| input.value = content; |
| input.placeholder = WebInspector.UIString("Text pattern to block matching requests; use * for wildcard"); |
| input.addEventListener("blur", commit.bind(this), false); |
| input.addEventListener("keydown", keydown.bind(this), false); |
| input.focus(); |
| |
| /** |
| * @this {WebInspector.BlockedURLsPane} |
| */ |
| function finish() |
| { |
| this._editing = false; |
| element.removeChild(input); |
| element.classList.remove("blocked-url-editing"); |
| } |
| |
| /** |
| * @this {WebInspector.BlockedURLsPane} |
| */ |
| function commit() |
| { |
| if (!this._editing) |
| return; |
| var text = input.value.trim(); |
| finish.call(this); |
| if (text) |
| onAccept(text); |
| else |
| this._update(); |
| } |
| |
| /** |
| * @this {WebInspector.BlockedURLsPane} |
| * @param {!Event} event |
| */ |
| function keydown(event) |
| { |
| if (isEnterKey(event)) { |
| event.consume(); |
| commit.call(this); |
| } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.key === "Escape") { |
| event.consume(); |
| finish.call(this); |
| this._update(); |
| } |
| } |
| }, |
| |
| /** |
| * @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); |
| }, |
| |
| _removeAll: function() |
| { |
| 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 ^pattern"), this._addButtonClicked.bind(this)); |
| contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^pattern"), this._removeBlockedURL.bind(this, index)); |
| contextMenu.appendItem(WebInspector.UIString.capitalize("Remove ^all"), this._removeAll.bind(this)); |
| contextMenu.show(); |
| }, |
| |
| /** |
| * @return {!Promise<?>} |
| */ |
| _update: function() |
| { |
| if (this._editing) |
| return Promise.resolve(); |
| |
| 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); |
| return Promise.resolve(); |
| }, |
| |
| /** |
| * @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"); |
| 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 pattern" : "%d requests blocked by this pattern", count); |
| |
| var removeButton = element.createChild("div", "remove-button"); |
| removeButton.title = WebInspector.UIString("Remove"); |
| removeButton.addEventListener("click", this._removeBlockedURL.bind(this, index), false); |
| |
| element.addEventListener("contextmenu", this._contextMenu.bind(this, index), true); |
| element.addEventListener("dblclick", this._edit.bind(this, url, element, this._changeBlockedURL.bind(this, index)), false); |
| return element; |
| }, |
| |
| /** |
| * @param {string} url |
| * @return {number} |
| */ |
| _blockedRequestsCount: function(url) |
| { |
| if (!url) |
| return 0; |
| |
| var result = 0; |
| for (var blockedUrl of this._blockedCountForUrl.keys()) { |
| if (this._matches(url, blockedUrl)) |
| result += this._blockedCountForUrl.get(blockedUrl); |
| } |
| return result; |
| }, |
| |
| /** |
| * @param {string} pattern |
| * @param {string} url |
| * @return {boolean} |
| */ |
| _matches: function(pattern, url) |
| { |
| var pos = 0; |
| var parts = pattern.split("*"); |
| for (var index = 0; index < parts.length; index++) { |
| var part = parts[index]; |
| if (!part.length) |
| continue; |
| pos = url.indexOf(part, pos); |
| if (pos === -1) |
| return false; |
| pos += part.length; |
| } |
| return true; |
| }, |
| |
| reset: function() |
| { |
| this._blockedCountForUrl.clear(); |
| }, |
| |
| /** |
| * @param {!WebInspector.Event} event |
| */ |
| _onRequestFinished: function(event) |
| { |
| var request = /** @type {!WebInspector.NetworkRequest} */ (event.data); |
| if (request.wasBlocked()) { |
| var count = this._blockedCountForUrl.get(request.url) || 0; |
| this._blockedCountForUrl.set(request.url, count + 1); |
| this._updateThrottler.schedule(this._update.bind(this)); |
| } |
| }, |
| |
| __proto__: WebInspector.VBox.prototype |
| } |
| |
| |
| /** @type {?WebInspector.BlockedURLsPane} */ |
| WebInspector.BlockedURLsPane._instance = null; |
| |
| WebInspector.BlockedURLsPane.reset = function() |
| { |
| if (WebInspector.BlockedURLsPane._instance) |
| WebInspector.BlockedURLsPane._instance.reset(); |
| } |
| |
| /** |
| * @constructor |
| * @implements {WebInspector.ActionDelegate} |
| */ |
| WebInspector.BlockedURLsPane.ActionDelegate = function() |
| { |
| } |
| |
| WebInspector.BlockedURLsPane.ActionDelegate.prototype = { |
| /** |
| * @override |
| * @param {!WebInspector.Context} context |
| * @param {string} actionId |
| * @return {boolean} |
| */ |
| handleAction: function(context, actionId) |
| { |
| WebInspector.inspectorView.showViewInDrawer("network.blocked-urls"); |
| return true; |
| } |
| } |
| |