blob: e981f2b5a1fbe85500d5551b108e3405b1d80693 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371// Copyright (c) 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Tim van der Lippe119690c2020-01-13 12:31:304
Tim van der Lippe0ed1d2b2020-02-04 13:45:135import * as Common from '../common/common.js';
6import * as SDK from '../sdk/sdk.js';
7import * as UI from '../ui/ui.js';
8
Tim van der Lippe119690c2020-01-13 12:31:309/** @type {?BlockedURLsPane} */
10export let _instance = null;
11
Blink Reformat4c46d092018-04-07 15:32:3712/**
13 * @implements {UI.ListWidget.Delegate<SDK.NetworkManager.BlockedPattern>}
14 */
Tim van der Lippe0ed1d2b2020-02-04 13:45:1315export class BlockedURLsPane extends UI.Widget.VBox {
Blink Reformat4c46d092018-04-07 15:32:3716 constructor() {
17 super(true);
18 this.registerRequiredCSS('network/blockedURLsPane.css');
19
Tim van der Lippe119690c2020-01-13 12:31:3020 _instance = this;
Paul Lewis5a922e72020-01-24 11:58:0821 this._manager = self.SDK.multitargetNetworkManager;
Tim van der Lippe0ed1d2b2020-02-04 13:45:1322 this._manager.addEventListener(
23 SDK.NetworkManager.MultitargetNetworkManager.Events.BlockedPatternsChanged, this._update, this);
Blink Reformat4c46d092018-04-07 15:32:3724
Tim van der Lippe0ed1d2b2020-02-04 13:45:1325 this._toolbar = new UI.Toolbar.Toolbar('', this.contentElement);
26 this._enabledCheckbox = new UI.Toolbar.ToolbarCheckbox(
27 Common.UIString.UIString('Enable request blocking'), undefined, this._toggleEnabled.bind(this));
Blink Reformat4c46d092018-04-07 15:32:3728 this._toolbar.appendToolbarItem(this._enabledCheckbox);
29 this._toolbar.appendSeparator();
Tim van der Lippe0ed1d2b2020-02-04 13:45:1330 const addButton = new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Add pattern'), 'largeicon-add');
31 addButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._addButtonClicked, this);
Blink Reformat4c46d092018-04-07 15:32:3732 this._toolbar.appendToolbarItem(addButton);
Tim van der Lippe0ed1d2b2020-02-04 13:45:1333 const clearButton =
34 new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Remove all patterns'), 'largeicon-clear');
35 clearButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this._removeAll, this);
Blink Reformat4c46d092018-04-07 15:32:3736 this._toolbar.appendToolbarItem(clearButton);
37
Tim van der Lippe0ed1d2b2020-02-04 13:45:1338 /** @type {!UI.ListWidget.ListWidget<!SDK.NetworkManager.BlockedPattern>} */
39 this._list = new UI.ListWidget.ListWidget(this);
Blink Reformat4c46d092018-04-07 15:32:3740 this._list.element.classList.add('blocked-urls');
41 this._list.registerRequiredCSS('network/blockedURLsPane.css');
42 this._list.setEmptyPlaceholder(this._createEmptyPlaceholder());
43 this._list.show(this.contentElement);
44
45 /** @type {?UI.ListWidget.Editor<!SDK.NetworkManager.BlockedPattern>} */
46 this._editor = null;
47
48 /** @type {!Map<string, number>} */
49 this._blockedCountForUrl = new Map();
Paul Lewisdaac1062020-03-05 14:37:1050 SDK.SDKModel.TargetManager.instance().addModelListener(
Tim van der Lippe0ed1d2b2020-02-04 13:45:1351 SDK.NetworkManager.NetworkManager, SDK.NetworkManager.Events.RequestFinished, this._onRequestFinished, this);
Blink Reformat4c46d092018-04-07 15:32:3752
Tim van der Lippe0ed1d2b2020-02-04 13:45:1353 this._updateThrottler = new Common.Throttler.Throttler(200);
Blink Reformat4c46d092018-04-07 15:32:3754
55 this._update();
56 }
57
58 /**
59 * @return {!Element}
60 */
61 _createEmptyPlaceholder() {
62 const element = this.contentElement.createChild('div', 'no-blocked-urls');
Tim van der Lippe0ed1d2b2020-02-04 13:45:1363 const addButton = UI.UIUtils.createTextButton(ls`Add pattern`, this._addButtonClicked.bind(this), 'add-button');
Mandy Chen6a711a92019-10-08 22:58:1864 UI.ARIAUtils.setAccessibleName(addButton, ls`Add request blocking pattern`);
Tim van der Lippe0ed1d2b2020-02-04 13:45:1365 element.appendChild(UI.UIUtils.formatLocalized('Requests are not blocked. %s', [addButton]));
Blink Reformat4c46d092018-04-07 15:32:3766 return element;
67 }
68
69 static reset() {
Tim van der Lippe119690c2020-01-13 12:31:3070 if (_instance) {
71 _instance.reset();
Tim van der Lippe1d6e57a2019-09-30 11:55:3472 }
Blink Reformat4c46d092018-04-07 15:32:3773 }
74
75 _addButtonClicked() {
76 this._manager.setBlockingEnabled(true);
77 this._list.addNewItem(0, {url: '', enabled: true});
78 }
79
80 /**
81 * @override
82 * @param {!SDK.NetworkManager.BlockedPattern} pattern
83 * @param {boolean} editable
84 * @return {!Element}
85 */
86 renderItem(pattern, editable) {
87 const count = this._blockedRequestsCount(pattern.url);
Tim van der Lippef49e2322020-05-01 15:03:0988 const element = document.createElement('div');
89 element.classList.add('blocked-url');
Blink Reformat4c46d092018-04-07 15:32:3790 const checkbox = element.createChild('input', 'blocked-url-checkbox');
91 checkbox.type = 'checkbox';
92 checkbox.checked = pattern.enabled;
93 checkbox.disabled = !this._manager.blockingEnabled();
94 element.createChild('div', 'blocked-url-label').textContent = pattern.url;
Tim van der Lippe0ed1d2b2020-02-04 13:45:1395 element.createChild('div', 'blocked-url-count').textContent = Common.UIString.UIString('%d blocked', count);
Blink Reformat4c46d092018-04-07 15:32:3796 element.addEventListener('click', event => this._togglePattern(pattern, event), false);
97 checkbox.addEventListener('click', event => this._togglePattern(pattern, event), false);
98 return element;
99 }
100
101 /**
102 * @param {!SDK.NetworkManager.BlockedPattern} pattern
103 * @param {!Event} event
104 */
105 _togglePattern(pattern, event) {
106 event.consume(true);
107 const patterns = this._manager.blockedPatterns();
108 patterns.splice(patterns.indexOf(pattern), 1, {enabled: !pattern.enabled, url: pattern.url});
109 this._manager.setBlockedPatterns(patterns);
110 }
111
112 _toggleEnabled() {
113 this._manager.setBlockingEnabled(!this._manager.blockingEnabled());
114 this._update();
115 }
116
117 /**
118 * @override
119 * @param {!SDK.NetworkManager.BlockedPattern} pattern
120 * @param {number} index
121 */
122 removeItemRequested(pattern, index) {
123 const patterns = this._manager.blockedPatterns();
124 patterns.splice(index, 1);
125 this._manager.setBlockedPatterns(patterns);
126 }
127
128 /**
129 * @override
130 * @param {!SDK.NetworkManager.BlockedPattern} pattern
131 * @return {!UI.ListWidget.Editor}
132 */
133 beginEdit(pattern) {
134 this._editor = this._createEditor();
135 this._editor.control('url').value = pattern.url;
136 return this._editor;
137 }
138
139 /**
140 * @override
141 * @param {!SDK.NetworkManager.BlockedPattern} item
142 * @param {!UI.ListWidget.Editor} editor
143 * @param {boolean} isNew
144 */
145 commitEdit(item, editor, isNew) {
146 const url = editor.control('url').value;
147 const patterns = this._manager.blockedPatterns();
Tim van der Lippe1d6e57a2019-09-30 11:55:34148 if (isNew) {
Blink Reformat4c46d092018-04-07 15:32:37149 patterns.push({enabled: true, url: url});
Tim van der Lippe1d6e57a2019-09-30 11:55:34150 } else {
Blink Reformat4c46d092018-04-07 15:32:37151 patterns.splice(patterns.indexOf(item), 1, {enabled: true, url: url});
Tim van der Lippe1d6e57a2019-09-30 11:55:34152 }
Blink Reformat4c46d092018-04-07 15:32:37153
154 this._manager.setBlockedPatterns(patterns);
155 }
156
157 /**
158 * @return {!UI.ListWidget.Editor<!SDK.NetworkManager.BlockedPattern>}
159 */
160 _createEditor() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34161 if (this._editor) {
Blink Reformat4c46d092018-04-07 15:32:37162 return this._editor;
Tim van der Lippe1d6e57a2019-09-30 11:55:34163 }
Blink Reformat4c46d092018-04-07 15:32:37164
165 const editor = new UI.ListWidget.Editor();
166 const content = editor.contentElement();
167 const titles = content.createChild('div', 'blocked-url-edit-row');
168 titles.createChild('div').textContent =
Tim van der Lippe0ed1d2b2020-02-04 13:45:13169 Common.UIString.UIString('Text pattern to block matching requests; use * for wildcard');
Blink Reformat4c46d092018-04-07 15:32:37170 const fields = content.createChild('div', 'blocked-url-edit-row');
Amanda Bakerca502822019-07-02 00:01:28171 const validator = (item, index, input) => {
Michael Liaoaf4130a2020-01-14 22:13:14172 let valid = true;
173 let errorMessage;
174 if (!input.value) {
175 errorMessage = ls`Pattern input cannot be empty.`;
176 valid = false;
177 } else if (this._manager.blockedPatterns().find(pattern => pattern.url === input.value)) {
178 errorMessage = ls`Pattern already exists.`;
179 valid = false;
180 }
181 return {valid, errorMessage};
Amanda Bakerca502822019-07-02 00:01:28182 };
183 const urlInput = editor.createInput('url', 'text', '', validator);
Blink Reformat4c46d092018-04-07 15:32:37184 fields.createChild('div', 'blocked-url-edit-value').appendChild(urlInput);
185 return editor;
186 }
187
188 _removeAll() {
189 this._manager.setBlockedPatterns([]);
190 }
191
192 /**
193 * @return {!Promise<?>}
194 */
195 _update() {
196 const enabled = this._manager.blockingEnabled();
197 this._list.element.classList.toggle('blocking-disabled', !enabled && !!this._manager.blockedPatterns().length);
198 this._enabledCheckbox.setChecked(enabled);
199 this._list.clear();
Tim van der Lippe1d6e57a2019-09-30 11:55:34200 for (const pattern of this._manager.blockedPatterns()) {
Blink Reformat4c46d092018-04-07 15:32:37201 this._list.appendItem(pattern, true);
Tim van der Lippe1d6e57a2019-09-30 11:55:34202 }
Blink Reformat4c46d092018-04-07 15:32:37203 return Promise.resolve();
204 }
205
206 /**
207 * @param {string} url
208 * @return {number}
209 */
210 _blockedRequestsCount(url) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34211 if (!url) {
Blink Reformat4c46d092018-04-07 15:32:37212 return 0;
Tim van der Lippe1d6e57a2019-09-30 11:55:34213 }
Blink Reformat4c46d092018-04-07 15:32:37214
215 let result = 0;
216 for (const blockedUrl of this._blockedCountForUrl.keys()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34217 if (this._matches(url, blockedUrl)) {
Blink Reformat4c46d092018-04-07 15:32:37218 result += this._blockedCountForUrl.get(blockedUrl);
Tim van der Lippe1d6e57a2019-09-30 11:55:34219 }
Blink Reformat4c46d092018-04-07 15:32:37220 }
221 return result;
222 }
223
224 /**
225 * @param {string} pattern
226 * @param {string} url
227 * @return {boolean}
228 */
229 _matches(pattern, url) {
230 let pos = 0;
231 const parts = pattern.split('*');
232 for (let index = 0; index < parts.length; index++) {
233 const part = parts[index];
Tim van der Lippe1d6e57a2019-09-30 11:55:34234 if (!part.length) {
Blink Reformat4c46d092018-04-07 15:32:37235 continue;
Tim van der Lippe1d6e57a2019-09-30 11:55:34236 }
Blink Reformat4c46d092018-04-07 15:32:37237 pos = url.indexOf(part, pos);
Tim van der Lippe1d6e57a2019-09-30 11:55:34238 if (pos === -1) {
Blink Reformat4c46d092018-04-07 15:32:37239 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34240 }
Blink Reformat4c46d092018-04-07 15:32:37241 pos += part.length;
242 }
243 return true;
244 }
245
246 reset() {
247 this._blockedCountForUrl.clear();
248 this._updateThrottler.schedule(this._update.bind(this));
249 }
250
251 /**
Tim van der Lippec02a97c2020-02-14 14:39:27252 * @param {!Common.EventTarget.EventTargetEvent} event
Blink Reformat4c46d092018-04-07 15:32:37253 */
254 _onRequestFinished(event) {
Tim van der Lippe0ed1d2b2020-02-04 13:45:13255 const request = /** @type {!SDK.NetworkRequest.NetworkRequest} */ (event.data);
Blink Reformat4c46d092018-04-07 15:32:37256 if (request.wasBlocked()) {
257 const count = this._blockedCountForUrl.get(request.url()) || 0;
258 this._blockedCountForUrl.set(request.url(), count + 1);
259 this._updateThrottler.schedule(this._update.bind(this));
260 }
261 }
Paul Lewis56509652019-12-06 12:51:58262}