blob: 07cba072dc8d4b428e33491800e787b8c13c1b73 [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 */
30/**
31 * @implements {UI.ViewLocationResolver}
32 * @unrestricted
33 */
Tim van der Lippe1ebfc502020-01-15 13:45:0934export class SettingsScreen extends UI.VBox {
Blink Reformat4c46d092018-04-07 15:32:3735 constructor() {
36 super(true);
37 this.registerRequiredCSS('settings/settingsScreen.css');
38
Blink Reformat4c46d092018-04-07 15:32:3739 this.contentElement.classList.add('settings-window-main');
40 this.contentElement.classList.add('vbox');
41
42 const settingsLabelElement = createElement('div');
John Emaub970e562019-06-05 01:17:2743 const settingsTitleElement = UI.createShadowRootWithCoreStyles(settingsLabelElement, 'settings/settingsScreen.css')
44 .createChild('div', 'settings-window-title');
45
46 UI.ARIAUtils.markAsHeading(settingsTitleElement, 1);
47 settingsTitleElement.textContent = ls`Settings`;
Blink Reformat4c46d092018-04-07 15:32:3748
49 this._tabbedLocation =
Paul Lewis5d4133e2019-11-27 13:06:0150 UI.viewManager.createTabbedLocation(() => SettingsScreen._showSettingsScreen(), 'settings-view');
Blink Reformat4c46d092018-04-07 15:32:3751 const tabbedPane = this._tabbedLocation.tabbedPane();
52 tabbedPane.leftToolbar().appendToolbarItem(new UI.ToolbarItem(settingsLabelElement));
53 tabbedPane.setShrinkableTabs(false);
54 tabbedPane.makeVerticalTabLayout();
John Emaub970e562019-06-05 01:17:2755 const shortcutsView = new UI.SimpleView(ls`Shortcuts`);
Blink Reformat4c46d092018-04-07 15:32:3756 UI.shortcutsScreen.createShortcutsTabView().show(shortcutsView.element);
57 this._tabbedLocation.appendView(shortcutsView);
58 tabbedPane.show(this.contentElement);
59
60 this.element.addEventListener('keydown', this._keyDown.bind(this), false);
61 this._developerModeCounter = 0;
62 this.setDefaultFocusedElement(this.contentElement);
63 }
64
65 /**
66 * @param {string=} name
67 */
68 static _showSettingsScreen(name) {
69 const settingsScreen =
Tim van der Lippe1ebfc502020-01-15 13:45:0970 /** @type {!SettingsScreen} */ (self.runtime.sharedInstance(SettingsScreen));
Tim van der Lippe1d6e57a2019-09-30 11:55:3471 if (settingsScreen.isShowing()) {
Blink Reformat4c46d092018-04-07 15:32:3772 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:3473 }
John Emau83763642019-07-16 23:56:4274 const dialog = new UI.Dialog();
Chandani Shrestha08469b82019-10-02 17:22:5575 dialog.contentElement.tabIndex = -1;
Blink Reformat4c46d092018-04-07 15:32:3776 dialog.addCloseButton();
Brian Cui8fdb1482019-12-04 21:41:4677 dialog.setOutsideClickCallback(() => {});
78 dialog.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.PierceGlassPane);
79 dialog.setOutsideTabIndexBehavior(UI.Dialog.OutsideTabIndexBehavior.PreserveMainViewTabIndex);
Blink Reformat4c46d092018-04-07 15:32:3780 settingsScreen.show(dialog.contentElement);
81 dialog.show();
82 settingsScreen._selectTab(name || 'preferences');
83 }
84
85 /**
86 * @override
87 * @param {string} locationName
88 * @return {?UI.ViewLocation}
89 */
90 resolveLocation(locationName) {
91 return this._tabbedLocation;
92 }
93
94 /**
95 * @param {string} name
96 */
97 _selectTab(name) {
98 UI.viewManager.showView(name);
99 }
100
101 /**
102 * @param {!Event} event
103 */
104 _keyDown(event) {
105 const shiftKeyCode = 16;
Tim van der Lippe1d6e57a2019-09-30 11:55:34106 if (event.keyCode === shiftKeyCode && ++this._developerModeCounter > 5) {
Blink Reformat4c46d092018-04-07 15:32:37107 this.contentElement.classList.add('settings-developer-mode');
Tim van der Lippe1d6e57a2019-09-30 11:55:34108 }
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 Lippec96ccd92019-11-29 16:23:54115class SettingsTab extends UI.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() {
154 super(Common.UIString('Preferences'), 'preferences-tab-content');
155
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));
165 self.runtime.extensions(UI.SettingUI).forEach(this._addSettingUI.bind(this));
166
167 this._appendSection().appendChild(
168 UI.createTextButton(Common.UIString('Restore defaults and reload'), restoreAndReload));
169
170 function restoreAndReload() {
171 Common.settings.clearAll();
172 Components.reload();
173 }
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']);
199 const setting = Common.moduleSetting(extension.descriptor()['settingName']);
200 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) {
219 const settingUI = /** @type {!UI.SettingUI} */ (object);
220 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) {
234 const uiSectionName = sectionName && Common.UIString(sectionName);
235 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() {
247 super(Common.UIString('Experiments'), 'experiments-tab-content');
248
Tim van der Lippe99e59b82019-09-30 20:00:59249 const experiments = Root.Runtime.experiments.allConfigurableExperiments();
Blink Reformat4c46d092018-04-07 15:32:37250 if (experiments.length) {
251 const experimentsSection = this._appendSection();
252 experimentsSection.appendChild(this._createExperimentsWarningSubsection());
Tim van der Lippe1d6e57a2019-09-30 11:55:34253 for (let i = 0; i < experiments.length; ++i) {
Blink Reformat4c46d092018-04-07 15:32:37254 experimentsSection.appendChild(this._createExperimentCheckbox(experiments[i]));
Tim van der Lippe1d6e57a2019-09-30 11:55:34255 }
Blink Reformat4c46d092018-04-07 15:32:37256 }
257 }
258
259 /**
260 * @return {!Element} element
261 */
262 _createExperimentsWarningSubsection() {
263 const subsection = createElement('div');
264 const warning = subsection.createChild('span', 'settings-experiments-warning-subsection-warning');
265 warning.textContent = Common.UIString('WARNING:');
266 subsection.createTextChild(' ');
267 const message = subsection.createChild('span', 'settings-experiments-warning-subsection-message');
268 message.textContent = Common.UIString('These experiments could be dangerous and may require restart.');
269 return subsection;
270 }
271
272 _createExperimentCheckbox(experiment) {
273 const label = UI.CheckboxLabel.create(Common.UIString(experiment.title), experiment.isEnabled());
274 const input = label.checkboxElement;
275 input.name = experiment.name;
276 function listener() {
277 experiment.setEnabled(input.checked);
278 }
279 input.addEventListener('click', listener, false);
280
281 const p = createElement('p');
282 p.className = experiment.hidden && !experiment.isEnabled() ? 'settings-experiment-hidden' : '';
283 p.appendChild(label);
284 return p;
285 }
Paul Lewis5d4133e2019-11-27 13:06:01286}
Blink Reformat4c46d092018-04-07 15:32:37287
288/**
289 * @implements {UI.ActionDelegate}
290 * @unrestricted
291 */
Paul Lewis5d4133e2019-11-27 13:06:01292export class ActionDelegate {
Blink Reformat4c46d092018-04-07 15:32:37293 /**
294 * @override
295 * @param {!UI.Context} context
296 * @param {string} actionId
297 * @return {boolean}
298 */
299 handleAction(context, actionId) {
300 switch (actionId) {
301 case 'settings.show':
Paul Lewis5d4133e2019-11-27 13:06:01302 SettingsScreen._showSettingsScreen();
Blink Reformat4c46d092018-04-07 15:32:37303 return true;
304 case 'settings.documentation':
Tim van der Lippe50cfa9b2019-10-01 10:40:58305 Host.InspectorFrontendHost.openInNewTab('https://developers.google.com/web/tools/chrome-devtools/');
Blink Reformat4c46d092018-04-07 15:32:37306 return true;
307 case 'settings.shortcuts':
Paul Lewis5d4133e2019-11-27 13:06:01308 SettingsScreen._showSettingsScreen(Common.UIString('Shortcuts'));
Blink Reformat4c46d092018-04-07 15:32:37309 return true;
310 }
311 return false;
312 }
Paul Lewis5d4133e2019-11-27 13:06:01313}
Blink Reformat4c46d092018-04-07 15:32:37314
315/**
316 * @implements {Common.Revealer}
317 * @unrestricted
318 */
Paul Lewis5d4133e2019-11-27 13:06:01319export class Revealer {
Blink Reformat4c46d092018-04-07 15:32:37320 /**
321 * @override
322 * @param {!Object} object
323 * @return {!Promise}
324 */
325 reveal(object) {
326 console.assert(object instanceof Common.Setting);
327 const setting = /** @type {!Common.Setting} */ (object);
328 let success = false;
329
330 self.runtime.extensions('setting').forEach(revealModuleSetting);
331 self.runtime.extensions(UI.SettingUI).forEach(revealSettingUI);
332 self.runtime.extensions('view').forEach(revealSettingsView);
333
334 return success ? Promise.resolve() : Promise.reject();
335
336 /**
Tim van der Lippe99e59b82019-09-30 20:00:59337 * @param {!Root.Runtime.Extension} extension
Blink Reformat4c46d092018-04-07 15:32:37338 */
339 function revealModuleSetting(extension) {
Paul Lewis5d4133e2019-11-27 13:06:01340 if (!GenericSettingsTab.isSettingVisible(extension)) {
Blink Reformat4c46d092018-04-07 15:32:37341 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34342 }
Blink Reformat4c46d092018-04-07 15:32:37343 if (extension.descriptor()['settingName'] === setting.name) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58344 Host.InspectorFrontendHost.bringToFront();
Paul Lewis5d4133e2019-11-27 13:06:01345 SettingsScreen._showSettingsScreen();
Blink Reformat4c46d092018-04-07 15:32:37346 success = true;
347 }
348 }
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 revealSettingUI(extension) {
354 const settings = extension.descriptor()['settings'];
355 if (settings && settings.indexOf(setting.name) !== -1) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58356 Host.InspectorFrontendHost.bringToFront();
Paul Lewis5d4133e2019-11-27 13:06:01357 SettingsScreen._showSettingsScreen();
Blink Reformat4c46d092018-04-07 15:32:37358 success = true;
359 }
360 }
361
362 /**
Tim van der Lippe99e59b82019-09-30 20:00:59363 * @param {!Root.Runtime.Extension} extension
Blink Reformat4c46d092018-04-07 15:32:37364 */
365 function revealSettingsView(extension) {
366 const location = extension.descriptor()['location'];
Tim van der Lippe1d6e57a2019-09-30 11:55:34367 if (location !== 'settings-view') {
Blink Reformat4c46d092018-04-07 15:32:37368 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34369 }
Blink Reformat4c46d092018-04-07 15:32:37370 const settings = extension.descriptor()['settings'];
371 if (settings && settings.indexOf(setting.name) !== -1) {
Tim van der Lippe50cfa9b2019-10-01 10:40:58372 Host.InspectorFrontendHost.bringToFront();
Paul Lewis5d4133e2019-11-27 13:06:01373 SettingsScreen._showSettingsScreen(extension.descriptor()['id']);
Blink Reformat4c46d092018-04-07 15:32:37374 success = true;
375 }
376 }
377 }
Paul Lewis5d4133e2019-11-27 13:06:01378}