blob: 7e6d6b260bd0f8a1580fcb7fa96a2a93a7539c4b [file] [log] [blame]
Patrick Hulcea087f622018-05-18 00:37:53 +00001// Copyright 2018 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.
4
Connor Clark2bc3be22020-02-14 14:34:19 -08005import {Events, LighthouseController, Presets, RuntimeSettings} from './LighthouseController.js'; // eslint-disable-line no-unused-vars
Paul Lewis51474192020-01-09 16:02:22 +00006import {RadioSetting} from './RadioSetting.js';
7
Patrick Hulcea087f622018-05-18 00:37:53 +00008/**
9 * @unrestricted
10 */
Paul Lewis51474192020-01-09 16:02:22 +000011export class StartView extends UI.Widget {
Patrick Hulcea087f622018-05-18 00:37:53 +000012 /**
Connor Clark2bc3be22020-02-14 14:34:19 -080013 * @param {!LighthouseController} controller
Patrick Hulcea087f622018-05-18 00:37:53 +000014 */
15 constructor(controller) {
16 super();
Connor Clark2bc3be22020-02-14 14:34:19 -080017 this.registerRequiredCSS('lighthouse/lighthouseStartView.css');
Patrick Hulcea087f622018-05-18 00:37:53 +000018 this._controller = controller;
Connor Clarke66080e2019-11-06 16:35:51 -080019 this._settingsToolbar = new UI.Toolbar('');
Patrick Hulcea087f622018-05-18 00:37:53 +000020 this._render();
21 }
22
23 /**
Connor Clarke66080e2019-11-06 16:35:51 -080024 * @return {!UI.Toolbar}
25 */
26 settingsToolbar() {
27 return this._settingsToolbar;
28 }
29
30 /**
Patrick Hulcea087f622018-05-18 00:37:53 +000031 * @param {string} settingName
John Emau73477162019-07-17 00:30:51 +000032 * @param {string} label
Patrick Hulcea087f622018-05-18 00:37:53 +000033 * @param {!Element} parentElement
34 */
John Emau73477162019-07-17 00:30:51 +000035 _populateRuntimeSettingAsRadio(settingName, label, parentElement) {
Paul Lewis51474192020-01-09 16:02:22 +000036 const runtimeSetting = RuntimeSettings.find(item => item.setting.name === settingName);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +000037 if (!runtimeSetting || !runtimeSetting.options) {
Patrick Hulce05c18ce2018-05-24 00:34:56 +000038 throw new Error(`${settingName} is not a setting with options`);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +000039 }
Patrick Hulce05c18ce2018-05-24 00:34:56 +000040
Paul Lewis51474192020-01-09 16:02:22 +000041 const control = new RadioSetting(runtimeSetting.options, runtimeSetting.setting, runtimeSetting.description);
Patrick Hulcea087f622018-05-18 00:37:53 +000042 parentElement.appendChild(control.element);
John Emau73477162019-07-17 00:30:51 +000043 UI.ARIAUtils.setAccessibleName(control.element, label);
Patrick Hulcea087f622018-05-18 00:37:53 +000044 }
45
46 /**
Patrick Hulce05c18ce2018-05-24 00:34:56 +000047 * @param {string} settingName
Connor Clarke66080e2019-11-06 16:35:51 -080048 * @param {!UI.Toolbar} toolbar
Patrick Hulce05c18ce2018-05-24 00:34:56 +000049 */
Connor Clarke66080e2019-11-06 16:35:51 -080050 _populateRuntimeSettingAsToolbarCheckbox(settingName, toolbar) {
Paul Lewis51474192020-01-09 16:02:22 +000051 const runtimeSetting = RuntimeSettings.find(item => item.setting.name === settingName);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +000052 if (!runtimeSetting || !runtimeSetting.title) {
Patrick Hulce05c18ce2018-05-24 00:34:56 +000053 throw new Error(`${settingName} is not a setting with a title`);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +000054 }
Patrick Hulce05c18ce2018-05-24 00:34:56 +000055
56 runtimeSetting.setting.setTitle(runtimeSetting.title);
57 const control = new UI.ToolbarSettingCheckbox(runtimeSetting.setting, runtimeSetting.description);
Connor Clarke66080e2019-11-06 16:35:51 -080058 toolbar.appendToolbarItem(control);
59 if (runtimeSetting.learnMore) {
Connor Clark2bc3be22020-02-14 14:34:19 -080060 const link = UI.XLink.create(runtimeSetting.learnMore, ls`Learn more`, 'lighthouse-learn-more');
Connor Clarke66080e2019-11-06 16:35:51 -080061 link.style.padding = '5px';
62 control.element.appendChild(link);
63 }
Patrick Hulce05c18ce2018-05-24 00:34:56 +000064 }
65
66 /**
Patrick Hulcea087f622018-05-18 00:37:53 +000067 * @param {!UI.Fragment} fragment
68 */
69 _populateFormControls(fragment) {
70 // Populate the device type
71 const deviceTypeFormElements = fragment.$('device-type-form-elements');
Connor Clark2bc3be22020-02-14 14:34:19 -080072 this._populateRuntimeSettingAsRadio('lighthouse.device_type', ls`Device`, deviceTypeFormElements);
Patrick Hulcea087f622018-05-18 00:37:53 +000073
Connor Clarke66080e2019-11-06 16:35:51 -080074 // Populate the categories
Patrick Hulcea087f622018-05-18 00:37:53 +000075 const categoryFormElements = fragment.$('categories-form-elements');
Connor Clark3ee5ac72019-11-07 15:11:58 -080076 const pluginFormElements = fragment.$('plugins-form-elements');
Paul Lewis51474192020-01-09 16:02:22 +000077 for (const preset of Presets) {
Connor Clark3ee5ac72019-11-07 15:11:58 -080078 const formElements = preset.plugin ? pluginFormElements : categoryFormElements;
Patrick Hulcea087f622018-05-18 00:37:53 +000079 preset.setting.setTitle(preset.title);
80 const checkbox = new UI.ToolbarSettingCheckbox(preset.setting);
Connor Clark2bc3be22020-02-14 14:34:19 -080081 const row = formElements.createChild('div', 'vbox lighthouse-launcher-row');
Patrick Hulce05c18ce2018-05-24 00:34:56 +000082 row.title = preset.description;
Patrick Hulcea087f622018-05-18 00:37:53 +000083 row.appendChild(checkbox.element);
Patrick Hulcea087f622018-05-18 00:37:53 +000084 }
John Emau62fdcee2019-10-16 00:08:52 +000085 UI.ARIAUtils.markAsGroup(categoryFormElements);
Connor Clarke66080e2019-11-06 16:35:51 -080086 UI.ARIAUtils.setAccessibleName(categoryFormElements, ls`Categories`);
Connor Clark3ee5ac72019-11-07 15:11:58 -080087 UI.ARIAUtils.markAsGroup(pluginFormElements);
88 UI.ARIAUtils.setAccessibleName(pluginFormElements, ls`Community Plugins (beta)`);
Patrick Hulcea087f622018-05-18 00:37:53 +000089 }
90
91 _render() {
Connor Clark2bc3be22020-02-14 14:34:19 -080092 this._populateRuntimeSettingAsToolbarCheckbox('lighthouse.clear_storage', this._settingsToolbar);
93 this._populateRuntimeSettingAsToolbarCheckbox('lighthouse.throttling', this._settingsToolbar);
Connor Clarke66080e2019-11-06 16:35:51 -080094
Patrick Hulcea087f622018-05-18 00:37:53 +000095 this._startButton = UI.createTextButton(
Brandon Goddard04d5ba92019-12-19 08:31:55 -080096 ls`Generate report`,
97 () => this._controller.dispatchEventToListeners(
Connor Clark2bc3be22020-02-14 14:34:19 -080098 Events.RequestLighthouseStart,
Brandon Goddard04d5ba92019-12-19 08:31:55 -080099 /* keyboardInitiated */ UI.elementIsFocusedByKeyboard(this._startButton)),
100 /* className */ '', /* primary */ true);
Patrick Hulce05c18ce2018-05-24 00:34:56 +0000101 this.setDefaultFocusedElement(this._startButton);
102
Christy Chen1eea03c2019-06-26 19:31:24 +0000103 const auditsDescription = ls
104 `Identify and fix common problems that affect your site's performance, accessibility, and user experience.`; // crbug.com/972969
Patrick Hulcea087f622018-05-18 00:37:53 +0000105
106 const fragment = UI.Fragment.build`
Connor Clark2bc3be22020-02-14 14:34:19 -0800107 <div class="vbox lighthouse-start-view">
Patrick Hulcea087f622018-05-18 00:37:53 +0000108 <header>
Connor Clark2bc3be22020-02-14 14:34:19 -0800109 <div class="lighthouse-logo"></div>
110 <div class="lighthouse-start-button-container hbox">
Connor Clarke66080e2019-11-06 16:35:51 -0800111 ${this._startButton}
112 </div>
Connor Clark2bc3be22020-02-14 14:34:19 -0800113 <div $="help-text" class="lighthouse-help-text hidden"></div>
114 <div class="lighthouse-start-view-text">
Connor Clarke66080e2019-11-06 16:35:51 -0800115 <span>${auditsDescription}</span>
John Emau97832ab2019-07-16 00:37:34 +0000116 ${UI.XLink.create('https://developers.google.com/web/tools/lighthouse/', ls`Learn more`)}
Patrick Hulcea087f622018-05-18 00:37:53 +0000117 </div>
118 </header>
119 <form>
Connor Clark2bc3be22020-02-14 14:34:19 -0800120 <div class="lighthouse-form-categories">
121 <div class="lighthouse-form-section">
122 <div class="lighthouse-form-section-label">
Connor Clark3ee5ac72019-11-07 15:11:58 -0800123 ${ls`Categories`}
124 </div>
Connor Clark2bc3be22020-02-14 14:34:19 -0800125 <div class="lighthouse-form-elements" $="categories-form-elements"></div>
Patrick Hulcea087f622018-05-18 00:37:53 +0000126 </div>
Connor Clark2bc3be22020-02-14 14:34:19 -0800127 <div class="lighthouse-form-section">
128 <div class="lighthouse-form-section-label">
129 <div class="lighthouse-icon-label">${ls`Community Plugins (beta)`}</div>
Connor Clark3ee5ac72019-11-07 15:11:58 -0800130 </div>
Connor Clark2bc3be22020-02-14 14:34:19 -0800131 <div class="lighthouse-form-elements" $="plugins-form-elements"></div>
Connor Clark3ee5ac72019-11-07 15:11:58 -0800132 </div>
Patrick Hulcea087f622018-05-18 00:37:53 +0000133 </div>
Connor Clark2bc3be22020-02-14 14:34:19 -0800134 <div class="lighthouse-form-section">
135 <div class="lighthouse-form-section-label">
Connor Clarke66080e2019-11-06 16:35:51 -0800136 ${ls`Device`}
Patrick Hulcea087f622018-05-18 00:37:53 +0000137 </div>
Connor Clark2bc3be22020-02-14 14:34:19 -0800138 <div class="lighthouse-form-elements" $="device-type-form-elements"></div>
Patrick Hulcea087f622018-05-18 00:37:53 +0000139 </div>
140 </form>
141 </div>
142 `;
143
144 this._helpText = fragment.$('help-text');
Patrick Hulcea087f622018-05-18 00:37:53 +0000145 this._populateFormControls(fragment);
146 this.contentElement.appendChild(fragment.element());
147 this.contentElement.style.overflow = 'auto';
148 }
149
Connor Clarke66080e2019-11-06 16:35:51 -0800150 /**
151 * @override
152 */
153 onResize() {
154 const useNarrowLayout = this.contentElement.offsetWidth < 560;
Connor Clark2bc3be22020-02-14 14:34:19 -0800155 const startViewEl = this.contentElement.querySelector('.lighthouse-start-view');
Connor Clarke66080e2019-11-06 16:35:51 -0800156 startViewEl.classList.toggle('hbox', !useNarrowLayout);
157 startViewEl.classList.toggle('vbox', useNarrowLayout);
158 }
159
Patrick Hulce8d387f12018-05-29 18:54:54 +0000160 focusStartButton() {
161 this._startButton.focus();
162 }
163
Patrick Hulcea087f622018-05-18 00:37:53 +0000164 /**
165 * @param {boolean} isEnabled
166 */
167 setStartButtonEnabled(isEnabled) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000168 if (this._helpText) {
Patrick Hulcea087f622018-05-18 00:37:53 +0000169 this._helpText.classList.toggle('hidden', isEnabled);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000170 }
Patrick Hulcea087f622018-05-18 00:37:53 +0000171
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000172 if (this._startButton) {
Patrick Hulcea087f622018-05-18 00:37:53 +0000173 this._startButton.disabled = !isEnabled;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000174 }
Patrick Hulcea087f622018-05-18 00:37:53 +0000175 }
176
177 /**
178 * @param {?string} text
179 */
180 setUnauditableExplanation(text) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000181 if (this._helpText) {
Patrick Hulcea087f622018-05-18 00:37:53 +0000182 this._helpText.textContent = text;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000183 }
Patrick Hulcea087f622018-05-18 00:37:53 +0000184 }
Paul Lewiscf2ef222019-11-22 14:55:35 +0000185}