blob: 640ae5350af79860dc8f5a4a139b49fde8f871b1 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:371/*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
Tim van der Lippe66684e92020-01-24 14:01:1830
31import * as Common from '../common/common.js';
32import * as Components from '../components/components.js';
33import * as Host from '../host/host.js';
34import * as UI from '../ui/ui.js';
35
Blink Reformat4c46d092018-04-07 15:32:3736/**
Tim van der Lippe66684e92020-01-24 14:01:1837 * @implements {UI.View.ViewLocationResolver}
Blink Reformat4c46d092018-04-07 15:32:3738 * @unrestricted
39 */
Tim van der Lippe66684e92020-01-24 14:01:1840export class SettingsScreen extends UI.Widget.VBox {
Blink Reformat4c46d092018-04-07 15:32:3741 constructor() {
42 super(true);
43 this.registerRequiredCSS('settings/settingsScreen.css');
44
Blink Reformat4c46d092018-04-07 15:32:3745 this.contentElement.classList.add('settings-window-main');
46 this.contentElement.classList.add('vbox');
47
48 const settingsLabelElement = createElement('div');
Tim van der Lippe66684e92020-01-24 14:01:1849 const settingsTitleElement =
50 UI.Utils.createShadowRootWithCoreStyles(settingsLabelElement, 'settings/settingsScreen.css')
51 .createChild('div', 'settings-window-title');
John Emaub970e562019-06-05 01:17:2752
53 UI.ARIAUtils.markAsHeading(settingsTitleElement, 1);
54 settingsTitleElement.textContent = ls`Settings`;
Blink Reformat4c46d092018-04-07 15:32:3755
56 this._tabbedLocation =
Paul Lewis50993692020-01-23 15:22:2657 self.UI.viewManager.createTabbedLocation(() => SettingsScreen._showSettingsScreen(), 'settings-view');
Blink Reformat4c46d092018-04-07 15:32:3758 const tabbedPane = this._tabbedLocation.tabbedPane();
Tim van der Lippe66684e92020-01-24 14:01:1859 tabbedPane.leftToolbar().appendToolbarItem(new UI.Toolbar.ToolbarItem(settingsLabelElement));
Blink Reformat4c46d092018-04-07 15:32:3760 tabbedPane.setShrinkableTabs(false);
61 tabbedPane.makeVerticalTabLayout();
Tim van der Lippe66684e92020-01-24 14:01:1862 const shortcutsView = new UI.View.SimpleView(ls`Shortcuts`);
63 self.UI.shortcutsScreen.createShortcutsTabView().show(shortcutsView.element);
Blink Reformat4c46d092018-04-07 15:32:3764 this._tabbedLocation.appendView(shortcutsView);
65 tabbedPane.show(this.contentElement);
Blink Reformat4c46d092018-04-07 15:32:3766 }
67
68 /**
Jack Lynch85edfc82020-03-09 18:11:1369 * @param {{name: (string|undefined), focusTabHeader: (boolean|undefined)}=} options
Blink Reformat4c46d092018-04-07 15:32:3770 */
Jack Lynch85edfc82020-03-09 18:11:1371 static async _showSettingsScreen(options = {}) {
72 const {name, focusTabHeader} = options;
Blink Reformat4c46d092018-04-07 15:32:3773 const settingsScreen =
Tim van der Lippe1ebfc502020-01-15 13:45:0974 /** @type {!SettingsScreen} */ (self.runtime.sharedInstance(SettingsScreen));
Tim van der Lippe1d6e57a2019-09-30 11:55:3475 if (settingsScreen.isShowing()) {
Blink Reformat4c46d092018-04-07 15:32:3776 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3477 }
Tim van der Lippe66684e92020-01-24 14:01:1878 const dialog = new UI.Dialog.Dialog();
Chandani Shrestha08469b82019-10-02 17:22:5579 dialog.contentElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:3780 dialog.addCloseButton();
Brian Cui8fdb1482019-12-04 21:41:4681 dialog.setOutsideClickCallback(() => {});
82 dialog.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.PierceGlassPane);
83 dialog.setOutsideTabIndexBehavior(UI.Dialog.OutsideTabIndexBehavior.PreserveMainViewTabIndex);
Blink Reformat4c46d092018-04-07 15:32:3784 settingsScreen.show(dialog.contentElement);
85 dialog.show();
86 settingsScreen._selectTab(name || 'preferences');
Jack Lynch85edfc82020-03-09 18:11:1387
88 if (focusTabHeader) {
89 const tabbedPane = settingsScreen._tabbedLocation.tabbedPane();
90 await tabbedPane.waitForTabElementUpdate();
91 tabbedPane.focusSelectedTabHeader();
92 }
Blink Reformat4c46d092018-04-07 15:32:3793 }
94
95 /**
96 * @override
97 * @param {string} locationName
Tim van der Lippe66684e92020-01-24 14:01:1898 * @return {?UI.View.ViewLocation}
Blink Reformat4c46d092018-04-07 15:32:3799 */
100 resolveLocation(locationName) {
101 return this._tabbedLocation;
102 }
103
104 /**
105 * @param {string} name
106 */
107 _selectTab(name) {
Paul Lewis50993692020-01-23 15:22:26108 self.UI.viewManager.showView(name);
Blink Reformat4c46d092018-04-07 15:32:37109 }
Paul Lewis5d4133e2019-11-27 13:06:01110}
Blink Reformat4c46d092018-04-07 15:32:37111
112/**
113 * @unrestricted
114 */
Tim van der Lippe66684e92020-01-24 14:01:18115class SettingsTab extends UI.Widget.VBox {
Blink Reformat4c46d092018-04-07 15:32:37116 /**
117 * @param {string} name
118 * @param {string=} id
119 */
120 constructor(name, id) {
121 super();
122 this.element.classList.add('settings-tab-container');
Tim van der Lippe1d6e57a2019-09-30 11:55:34123 if (id) {
Blink Reformat4c46d092018-04-07 15:32:37124 this.element.id = id;
Tim van der Lippe1d6e57a2019-09-30 11:55:34125 }
Blink Reformat4c46d092018-04-07 15:32:37126 const header = this.element.createChild('header');
Chandani Shrestha83bd7c92019-06-11 21:21:59127 header.createChild('h1').createTextChild(name);
Blink Reformat4c46d092018-04-07 15:32:37128 this.containerElement = this.element.createChild('div', 'settings-container-wrapper')
129 .createChild('div', 'settings-tab settings-content settings-container');
130 }
131
132 /**
133 * @param {string=} name
134 * @return {!Element}
135 */
136 _appendSection(name) {
137 const block = this.containerElement.createChild('div', 'settings-block');
Chandani Shrestha83bd7c92019-06-11 21:21:59138 if (name) {
139 UI.ARIAUtils.markAsGroup(block);
140 const title = block.createChild('div', 'settings-section-title');
141 title.textContent = name;
142 UI.ARIAUtils.markAsHeading(title, 2);
Joel Einbindereaef6162019-07-15 17:42:55143 UI.ARIAUtils.setAccessibleName(block, name);
Chandani Shrestha83bd7c92019-06-11 21:21:59144 }
Blink Reformat4c46d092018-04-07 15:32:37145 return block;
146 }
Paul Lewis5d4133e2019-11-27 13:06:01147}
Blink Reformat4c46d092018-04-07 15:32:37148
149/**
150 * @unrestricted
151 */
Paul Lewis5d4133e2019-11-27 13:06:01152export class GenericSettingsTab extends SettingsTab {
Blink Reformat4c46d092018-04-07 15:32:37153 constructor() {
Tim van der Lippe66684e92020-01-24 14:01:18154 super(Common.UIString.UIString('Preferences'), 'preferences-tab-content');
Blink Reformat4c46d092018-04-07 15:32:37155
156 /** @const */
157 const explicitSectionOrder =
158 ['', 'Appearance', 'Sources', 'Elements', 'Network', 'Performance', 'Console', 'Extensions'];
159 /** @type {!Map<string, !Element>} */
160 this._nameToSection = new Map();
Tim van der Lippe1d6e57a2019-09-30 11:55:34161 for (const sectionName of explicitSectionOrder) {
Blink Reformat4c46d092018-04-07 15:32:37162 this._sectionElement(sectionName);
Tim van der Lippe1d6e57a2019-09-30 11:55:34163 }
Blink Reformat4c46d092018-04-07 15:32:37164 self.runtime.extensions('setting').forEach(this._addSetting.bind(this));
Tim van der Lippe66684e92020-01-24 14:01:18165 self.runtime.extensions(UI.SettingsUI.SettingUI).forEach(this._addSettingUI.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37166
167 this._appendSection().appendChild(
Tim van der Lippe66684e92020-01-24 14:01:18168 UI.UIUtils.createTextButton(Common.UIString.UIString('Restore defaults and reload'), restoreAndReload));
Blink Reformat4c46d092018-04-07 15:32:37169
170 function restoreAndReload() {
Paul Lewis2d7d65c2020-03-16 17:26:30171 Common.Settings.Settings.instance().clearAll();
Tim van der Lippe66684e92020-01-24 14:01:18172 Components.Reload.reload();
Blink Reformat4c46d092018-04-07 15:32:37173 }
174 }
175
176 /**
Tim van der Lippe99e59b82019-09-30 20:00:59177 * @param {!Root.Runtime.Extension} extension
Blink Reformat4c46d092018-04-07 15:32:37178 * @return {boolean}
179 */
180 static isSettingVisible(extension) {
181 const descriptor = extension.descriptor();
Tim van der Lippe1d6e57a2019-09-30 11:55:34182 if (!('title' in descriptor)) {
Blink Reformat4c46d092018-04-07 15:32:37183 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34184 }
185 if (!('category' in descriptor)) {
Blink Reformat4c46d092018-04-07 15:32:37186 return false;
Tim van der Lippe1d6e57a2019-09-30 11:55:34187 }
Blink Reformat4c46d092018-04-07 15:32:37188 return true;
189 }
190
191 /**
Tim van der Lippe99e59b82019-09-30 20:00:59192 * @param {!Root.Runtime.Extension} extension
Blink Reformat4c46d092018-04-07 15:32:37193 */
194 _addSetting(extension) {
Paul Lewis5d4133e2019-11-27 13:06:01195 if (!GenericSettingsTab.isSettingVisible(extension)) {
Blink Reformat4c46d092018-04-07 15:32:37196 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34197 }
Blink Reformat4c46d092018-04-07 15:32:37198 const sectionElement = this._sectionElement(extension.descriptor()['category']);
Paul Lewis2d7d65c2020-03-16 17:26:30199 const setting = Common.Settings.Settings.instance().moduleSetting(extension.descriptor()['settingName']);
Blink Reformat4c46d092018-04-07 15:32:37200 const settingControl = UI.SettingsUI.createControlForSetting(setting);
Tim van der Lippe1d6e57a2019-09-30 11:55:34201 if (settingControl) {
Blink Reformat4c46d092018-04-07 15:32:37202 sectionElement.appendChild(settingControl);
Tim van der Lippe1d6e57a2019-09-30 11:55:34203 }
Blink Reformat4c46d092018-04-07 15:32:37204 }
205
206 /**
Tim van der Lippe99e59b82019-09-30 20:00:59207 * @param {!Root.Runtime.Extension} extension
Blink Reformat4c46d092018-04-07 15:32:37208 */
209 _addSettingUI(extension) {
210 const descriptor = extension.descriptor();
211 const sectionName = descriptor['category'] || '';
212 extension.instance().then(appendCustomSetting.bind(this));
213
214 /**
215 * @param {!Object} object
Tim van der Lippe1ebfc502020-01-15 13:45:09216 * @this {GenericSettingsTab}
Blink Reformat4c46d092018-04-07 15:32:37217 */
218 function appendCustomSetting(object) {
Tim van der Lippe66684e92020-01-24 14:01:18219 const settingUI = /** @type {!UI.SettingsUI.SettingUI} */ (object);
Blink Reformat4c46d092018-04-07 15:32:37220 const element = settingUI.settingElement();
Tim van der Lippe1d6e57a2019-09-30 11:55:34221 if (element) {
Blink Reformat4c46d092018-04-07 15:32:37222 this._sectionElement(sectionName).appendChild(element);
Tim van der Lippe1d6e57a2019-09-30 11:55:34223 }
Blink Reformat4c46d092018-04-07 15:32:37224 }
225 }
226
227 /**
228 * @param {string} sectionName
229 * @return {!Element}
230 */
231 _sectionElement(sectionName) {
232 let sectionElement = this._nameToSection.get(sectionName);
233 if (!sectionElement) {
Tim van der Lippe66684e92020-01-24 14:01:18234 const uiSectionName = sectionName && Common.UIString.UIString(sectionName);
Blink Reformat4c46d092018-04-07 15:32:37235 sectionElement = this._appendSection(uiSectionName);
236 this._nameToSection.set(sectionName, sectionElement);
237 }
238 return sectionElement;
239 }
Paul Lewis5d4133e2019-11-27 13:06:01240}
Blink Reformat4c46d092018-04-07 15:32:37241
242/**
243 * @unrestricted
244 */
Paul Lewis5d4133e2019-11-27 13:06:01245export class ExperimentsSettingsTab extends SettingsTab {
Blink Reformat4c46d092018-04-07 15:32:37246 constructor() {
Tim van der Lippe66684e92020-01-24 14:01:18247 super(Common.UIString.UIString('Experiments'), 'experiments-tab-content');
Blink Reformat4c46d092018-04-07 15:32:37248
Yang Guo33e8f6f2020-02-06 11:50:29249 const experiments = Root.Runtime.experiments.allConfigurableExperiments().sort();
250 const unstableExperiments = experiments.filter(e => e.unstable);
251 const stableExperiments = experiments.filter(e => !e.unstable);
252 if (stableExperiments.length) {
Blink Reformat4c46d092018-04-07 15:32:37253 const experimentsSection = this._appendSection();
Yang Guo33e8f6f2020-02-06 11:50:29254 const warningMessage = Common.UIString.UIString('These experiments could be dangerous and may require restart.');
255 experimentsSection.appendChild(this._createExperimentsWarningSubsection(warningMessage));
256 for (const experiment of stableExperiments) {
257 experimentsSection.appendChild(this._createExperimentCheckbox(experiment));
258 }
259 }
260 if (unstableExperiments.length) {
261 const experimentsSection = this._appendSection();
262 const warningMessage =
263 Common.UIString.UIString('These experiments are particularly unstable. Enable at your own risk.');
264 experimentsSection.appendChild(this._createExperimentsWarningSubsection(warningMessage));
265 for (const experiment of unstableExperiments) {
266 experimentsSection.appendChild(this._createExperimentCheckbox(experiment));
Tim van der Lippe1d6e57a2019-09-30 11:55:34267 }
Blink Reformat4c46d092018-04-07 15:32:37268 }
269 }
270
271 /**
Yang Guo33e8f6f2020-02-06 11:50:29272 * @param {string} warningMessage
Blink Reformat4c46d092018-04-07 15:32:37273 * @return {!Element} element
274 */
Yang Guo33e8f6f2020-02-06 11:50:29275 _createExperimentsWarningSubsection(warningMessage) {
Blink Reformat4c46d092018-04-07 15:32:37276 const subsection = createElement('div');
277 const warning = subsection.createChild('span', 'settings-experiments-warning-subsection-warning');
Tim van der Lippe66684e92020-01-24 14:01:18278 warning.textContent = Common.UIString.UIString('WARNING:');
Blink Reformat4c46d092018-04-07 15:32:37279 subsection.createTextChild(' ');
280 const message = subsection.createChild('span', 'settings-experiments-warning-subsection-message');
Yang Guo33e8f6f2020-02-06 11:50:29281 message.textContent = warningMessage;
Blink Reformat4c46d092018-04-07 15:32:37282 return subsection;
283 }
284
285 _createExperimentCheckbox(experiment) {
Tim van der Lippe66684e92020-01-24 14:01:18286 const label = UI.UIUtils.CheckboxLabel.create(Common.UIString.UIString(experiment.title), experiment.isEnabled());
Blink Reformat4c46d092018-04-07 15:32:37287 const input = label.checkboxElement;
288 input.name = experiment.name;
289 function listener() {
290 experiment.setEnabled(input.checked);
291 }
292 input.addEventListener('click', listener, false);
293
294 const p = createElement('p');
Yang Guo33e8f6f2020-02-06 11:50:29295 p.className = experiment.unstable && !experiment.isEnabled() ? 'settings-experiment-unstable' : '';
Blink Reformat4c46d092018-04-07 15:32:37296 p.appendChild(label);
297 return p;
298 }
Paul Lewis5d4133e2019-11-27 13:06:01299}
Blink Reformat4c46d092018-04-07 15:32:37300
301/**
Tim van der Lippe66684e92020-01-24 14:01:18302 * @implements {UI.ActionDelegate.ActionDelegate}
Blink Reformat4c46d092018-04-07 15:32:37303 * @unrestricted
304 */
Paul Lewis5d4133e2019-11-27 13:06:01305export class ActionDelegate {
Blink Reformat4c46d092018-04-07 15:32:37306 /**
307 * @override
Tim van der Lippe66684e92020-01-24 14:01:18308 * @param {!UI.Context.Context} context
Blink Reformat4c46d092018-04-07 15:32:37309 * @param {string} actionId
310 * @return {boolean}
311 */
312 handleAction(context, actionId) {
313 switch (actionId) {
314 case 'settings.show':
Jack Lynch85edfc82020-03-09 18:11:13315 SettingsScreen._showSettingsScreen({focusTabHeader: true});
Blink Reformat4c46d092018-04-07 15:32:37316 return true;
317 case 'settings.documentation':
Tim van der Lippe66684e92020-01-24 14:01:18318 Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(
Wolfgang Beyer6190ec82020-03-09 15:06:33319 UI.UIUtils.addReferrerToURL('https://developers.google.com/web/tools/chrome-devtools/'));
Blink Reformat4c46d092018-04-07 15:32:37320 return true;
321 case 'settings.shortcuts':
Jack Lynch85edfc82020-03-09 18:11:13322 SettingsScreen._showSettingsScreen({name: ls`Shortcuts`, focusTabHeader: true});
Blink Reformat4c46d092018-04-07 15:32:37323 return true;
324 }
325 return false;
326 }
Paul Lewis5d4133e2019-11-27 13:06:01327}
Blink Reformat4c46d092018-04-07 15:32:37328
329/**
Tim van der Lippe66684e92020-01-24 14:01:18330 * @implements {Common.Revealer.Revealer}
Blink Reformat4c46d092018-04-07 15:32:37331 * @unrestricted
332 */
Paul Lewis5d4133e2019-11-27 13:06:01333export class Revealer {
Blink Reformat4c46d092018-04-07 15:32:37334 /**
335 * @override
336 * @param {!Object} object
337 * @return {!Promise}
338 */
339 reveal(object) {
Tim van der Lippe66684e92020-01-24 14:01:18340 console.assert(object instanceof Common.Settings.Setting);
341 const setting = /** @type {!Common.Settings.Setting} */ (object);
Blink Reformat4c46d092018-04-07 15:32:37342 let success = false;
343
344 self.runtime.extensions('setting').forEach(revealModuleSetting);
Tim van der Lippe66684e92020-01-24 14:01:18345 self.runtime.extensions(UI.SettingsUI.SettingUI).forEach(revealSettingUI);
Blink Reformat4c46d092018-04-07 15:32:37346 self.runtime.extensions('view').forEach(revealSettingsView);
347
348 return success ? Promise.resolve() : Promise.reject();
349
350 /**
Tim van der Lippe99e59b82019-09-30 20:00:59351 * @param {!Root.Runtime.Extension} extension
Blink Reformat4c46d092018-04-07 15:32:37352 */
353 function revealModuleSetting(extension) {
Paul Lewis5d4133e2019-11-27 13:06:01354 if (!GenericSettingsTab.isSettingVisible(extension)) {
Blink Reformat4c46d092018-04-07 15:32:37355 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34356 }
Blink Reformat4c46d092018-04-07 15:32:37357 if (extension.descriptor()['settingName'] === setting.name) {
Tim van der Lippe66684e92020-01-24 14:01:18358 Host.InspectorFrontendHost.InspectorFrontendHostInstance.bringToFront();
Paul Lewis5d4133e2019-11-27 13:06:01359 SettingsScreen._showSettingsScreen();
Blink Reformat4c46d092018-04-07 15:32:37360 success = true;
361 }
362 }
363
364 /**
Tim van der Lippe99e59b82019-09-30 20:00:59365 * @param {!Root.Runtime.Extension} extension
Blink Reformat4c46d092018-04-07 15:32:37366 */
367 function revealSettingUI(extension) {
368 const settings = extension.descriptor()['settings'];
369 if (settings && settings.indexOf(setting.name) !== -1) {
Tim van der Lippe66684e92020-01-24 14:01:18370 Host.InspectorFrontendHost.InspectorFrontendHostInstance.bringToFront();
Paul Lewis5d4133e2019-11-27 13:06:01371 SettingsScreen._showSettingsScreen();
Blink Reformat4c46d092018-04-07 15:32:37372 success = true;
373 }
374 }
375
376 /**
Tim van der Lippe99e59b82019-09-30 20:00:59377 * @param {!Root.Runtime.Extension} extension
Blink Reformat4c46d092018-04-07 15:32:37378 */
379 function revealSettingsView(extension) {
380 const location = extension.descriptor()['location'];
Tim van der Lippe1d6e57a2019-09-30 11:55:34381 if (location !== 'settings-view') {
Blink Reformat4c46d092018-04-07 15:32:37382 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34383 }
Blink Reformat4c46d092018-04-07 15:32:37384 const settings = extension.descriptor()['settings'];
385 if (settings && settings.indexOf(setting.name) !== -1) {
Tim van der Lippe66684e92020-01-24 14:01:18386 Host.InspectorFrontendHost.InspectorFrontendHostInstance.bringToFront();
Jack Lynch85edfc82020-03-09 18:11:13387 SettingsScreen._showSettingsScreen({name: extension.descriptor()['id']});
Blink Reformat4c46d092018-04-07 15:32:37388 success = true;
389 }
390 }
391 }
Paul Lewis5d4133e2019-11-27 13:06:01392}