blob: 81650553da4b0789abe812c098274cc7a2744173 [file] [log] [blame]
Blink Reformat4c46d092018-04-07 15:32:37 +00001// Copyright 2016 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
Tim van der Lippec02a97c2020-02-14 14:39:27 +00005import * as Common from '../common/common.js'; // eslint-disable-line no-unused-vars
6
Connor Clark2bc3be22020-02-14 14:34:19 -08007import {Events, LighthouseController} from './LighthouseController.js';
8import {ProtocolService} from './LighthouseProtocolService.js';
9import {LighthouseReportRenderer, LighthouseReportUIFeatures} from './LighthouseReportRenderer.js';
10import {Item, ReportSelector} from './LighthouseReportSelector.js';
11import {StartView} from './LighthouseStartView.js';
12import {StatusView} from './LighthouseStatusView.js';
Paul Lewis51474192020-01-09 16:02:22 +000013
Blink Reformat4c46d092018-04-07 15:32:37 +000014/**
Blink Reformat4c46d092018-04-07 15:32:37 +000015 * @unrestricted
16 */
Connor Clark2bc3be22020-02-14 14:34:19 -080017export class LighthousePanel extends UI.Panel {
Blink Reformat4c46d092018-04-07 15:32:37 +000018 constructor() {
Connor Clark2bc3be22020-02-14 14:34:19 -080019 super('lighthouse');
20 this.registerRequiredCSS('lighthouse/lighthouse/report.css');
21 this.registerRequiredCSS('lighthouse/lighthousePanel.css');
Blink Reformat4c46d092018-04-07 15:32:37 +000022
Paul Lewis51474192020-01-09 16:02:22 +000023 this._protocolService = new ProtocolService();
Connor Clark2bc3be22020-02-14 14:34:19 -080024 this._controller = new LighthouseController(this._protocolService);
Paul Lewis51474192020-01-09 16:02:22 +000025 this._startView = new StartView(this._controller);
26 this._statusView = new StatusView(this._controller);
Blink Reformat4c46d092018-04-07 15:32:37 +000027
Patrick Hulcea087f622018-05-18 00:37:53 +000028 this._unauditableExplanation = null;
29 this._cachedRenderedReports = new Map();
Blink Reformat4c46d092018-04-07 15:32:37 +000030
Blink Reformat4c46d092018-04-07 15:32:37 +000031 this._dropTarget = new UI.DropTarget(
Connor Clark2bc3be22020-02-14 14:34:19 -080032 this.contentElement, [UI.DropTarget.Type.File], Common.UIString.UIString('Drop Lighthouse JSON here'),
Blink Reformat4c46d092018-04-07 15:32:37 +000033 this._handleDrop.bind(this));
34
Paul Lewis51474192020-01-09 16:02:22 +000035 this._controller.addEventListener(Events.PageAuditabilityChanged, this._refreshStartAuditUI.bind(this));
36 this._controller.addEventListener(Events.AuditProgressChanged, this._refreshStatusUI.bind(this));
Connor Clark2bc3be22020-02-14 14:34:19 -080037 this._controller.addEventListener(Events.RequestLighthouseStart, this._startLighthouse.bind(this));
38 this._controller.addEventListener(Events.RequestLighthouseCancel, this._cancelLighthouse.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37 +000039
Patrick Hulcea087f622018-05-18 00:37:53 +000040 this._renderToolbar();
Connor Clark2bc3be22020-02-14 14:34:19 -080041 this._auditResultsElement = this.contentElement.createChild('div', 'lighthouse-results-container');
Patrick Hulcea087f622018-05-18 00:37:53 +000042 this._renderStartView();
43
44 this._controller.recomputePageAuditability();
Blink Reformat4c46d092018-04-07 15:32:37 +000045 }
46
47 /**
Tim van der Lippec02a97c2020-02-14 14:39:27 +000048 * @param {!Common.EventTarget.EventTargetEvent} evt
Blink Reformat4c46d092018-04-07 15:32:37 +000049 */
Patrick Hulcea087f622018-05-18 00:37:53 +000050 _refreshStartAuditUI(evt) {
Connor Clarkca8905e2019-08-23 18:35:10 +000051 // PageAuditabilityChanged fires multiple times during an audit, which we want to ignore.
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +000052 if (this._isLHAttached) {
Connor Clarkca8905e2019-08-23 18:35:10 +000053 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +000054 }
Connor Clarkca8905e2019-08-23 18:35:10 +000055
Patrick Hulcea087f622018-05-18 00:37:53 +000056 this._unauditableExplanation = evt.data.helpText;
57 this._startView.setUnauditableExplanation(evt.data.helpText);
58 this._startView.setStartButtonEnabled(!evt.data.helpText);
Blink Reformat4c46d092018-04-07 15:32:37 +000059 }
60
61 /**
Tim van der Lippec02a97c2020-02-14 14:39:27 +000062 * @param {!Common.EventTarget.EventTargetEvent} evt
Blink Reformat4c46d092018-04-07 15:32:37 +000063 */
Patrick Hulcea087f622018-05-18 00:37:53 +000064 _refreshStatusUI(evt) {
65 this._statusView.updateStatus(evt.data.message);
Blink Reformat4c46d092018-04-07 15:32:37 +000066 }
67
68 _refreshToolbarUI() {
Blink Reformat4c46d092018-04-07 15:32:37 +000069 this._clearButton.setEnabled(this._reportSelector.hasItems());
70 }
71
72 _clearAll() {
73 this._reportSelector.clearAll();
Patrick Hulcea087f622018-05-18 00:37:53 +000074 this._renderStartView();
Blink Reformat4c46d092018-04-07 15:32:37 +000075 this._refreshToolbarUI();
76 }
77
Blink Reformat4c46d092018-04-07 15:32:37 +000078 _renderToolbar() {
Connor Clark2bc3be22020-02-14 14:34:19 -080079 const lighthouseToolbarContainer = this.element.createChild('div', 'lighthouse-toolbar-container');
Connor Clarke66080e2019-11-06 16:35:51 -080080
Connor Clark2bc3be22020-02-14 14:34:19 -080081 const toolbar = new UI.Toolbar('', lighthouseToolbarContainer);
Blink Reformat4c46d092018-04-07 15:32:37 +000082
Tim van der Lippec02a97c2020-02-14 14:39:27 +000083 this._newButton = new UI.ToolbarButton(Common.UIString.UIString('Perform an audit\u2026'), 'largeicon-add');
Blink Reformat4c46d092018-04-07 15:32:37 +000084 toolbar.appendToolbarItem(this._newButton);
Patrick Hulcea087f622018-05-18 00:37:53 +000085 this._newButton.addEventListener(UI.ToolbarButton.Events.Click, this._renderStartView.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37 +000086
Blink Reformat4c46d092018-04-07 15:32:37 +000087 toolbar.appendSeparator();
88
Paul Lewis51474192020-01-09 16:02:22 +000089 this._reportSelector = new ReportSelector(() => this._renderStartView());
Blink Reformat4c46d092018-04-07 15:32:37 +000090 toolbar.appendToolbarItem(this._reportSelector.comboBox());
91
Tim van der Lippec02a97c2020-02-14 14:39:27 +000092 this._clearButton = new UI.ToolbarButton(Common.UIString.UIString('Clear all'), 'largeicon-clear');
Blink Reformat4c46d092018-04-07 15:32:37 +000093 toolbar.appendToolbarItem(this._clearButton);
94 this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearAll.bind(this));
95
Connor Clarke66080e2019-11-06 16:35:51 -080096 this._settingsPane = new UI.HBox();
97 this._settingsPane.show(this.contentElement);
Connor Clark2bc3be22020-02-14 14:34:19 -080098 this._settingsPane.element.classList.add('lighthouse-settings-pane');
Connor Clarke66080e2019-11-06 16:35:51 -080099 this._settingsPane.element.appendChild(this._startView.settingsToolbar().element);
Connor Clark2bc3be22020-02-14 14:34:19 -0800100 this._showSettingsPaneSetting = self.Common.settings.createSetting('lighthouseShowSettingsToolbar', false);
Connor Clarke66080e2019-11-06 16:35:51 -0800101
Connor Clark2bc3be22020-02-14 14:34:19 -0800102 this._rightToolbar = new UI.Toolbar('', lighthouseToolbarContainer);
Connor Clarke66080e2019-11-06 16:35:51 -0800103 this._rightToolbar.appendSeparator();
104 this._rightToolbar.appendToolbarItem(
Connor Clark2bc3be22020-02-14 14:34:19 -0800105 new UI.ToolbarSettingToggle(this._showSettingsPaneSetting, 'largeicon-settings-gear', ls`Lighthouse settings`));
Connor Clarke66080e2019-11-06 16:35:51 -0800106 this._showSettingsPaneSetting.addChangeListener(this._updateSettingsPaneVisibility.bind(this));
107 this._updateSettingsPaneVisibility();
108
Patrick Hulcea087f622018-05-18 00:37:53 +0000109 this._refreshToolbarUI();
110 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000111
Connor Clarke66080e2019-11-06 16:35:51 -0800112 _updateSettingsPaneVisibility() {
113 this._settingsPane.element.classList.toggle('hidden', !this._showSettingsPaneSetting.get());
114 }
115
116 /**
117 * @param {boolean} show
118 */
119 _toggleSettingsDisplay(show) {
120 this._rightToolbar.element.classList.toggle('hidden', !show);
121 this._settingsPane.element.classList.toggle('hidden', !show);
122 this._updateSettingsPaneVisibility();
123 }
124
Patrick Hulcea087f622018-05-18 00:37:53 +0000125 _renderStartView() {
126 this._auditResultsElement.removeChildren();
127 this._statusView.hide();
128
Connor Clark2bc3be22020-02-14 14:34:19 -0800129 this._reportSelector.selectNewReport();
Patrick Hulcea087f622018-05-18 00:37:53 +0000130 this.contentElement.classList.toggle('in-progress', false);
131
132 this._startView.show(this.contentElement);
Connor Clarke66080e2019-11-06 16:35:51 -0800133 this._toggleSettingsDisplay(true);
Patrick Hulcea087f622018-05-18 00:37:53 +0000134 this._startView.setUnauditableExplanation(this._unauditableExplanation);
135 this._startView.setStartButtonEnabled(!this._unauditableExplanation);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000136 if (!this._unauditableExplanation) {
Patrick Hulce8d387f12018-05-29 18:54:54 +0000137 this._startView.focusStartButton();
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000138 }
Patrick Hulce8d387f12018-05-29 18:54:54 +0000139
Patrick Hulce05c18ce2018-05-24 00:34:56 +0000140 this._newButton.setEnabled(false);
Patrick Hulcea087f622018-05-18 00:37:53 +0000141 this._refreshToolbarUI();
Patrick Hulce05c18ce2018-05-24 00:34:56 +0000142 this.setDefaultFocusedChild(this._startView);
Patrick Hulcea087f622018-05-18 00:37:53 +0000143 }
144
145 /**
146 * @param {string} inspectedURL
147 */
148 _renderStatusView(inspectedURL) {
149 this.contentElement.classList.toggle('in-progress', true);
150 this._statusView.setInspectedURL(inspectedURL);
151 this._statusView.show(this.contentElement);
152 }
153
Connor Clark99508362019-08-20 19:52:23 +0000154 _beforePrint() {
155 this._statusView.show(this.contentElement);
156 this._statusView.toggleCancelButton(false);
157 this._statusView.renderText(ls`Printing`, ls`The print popup window is open. Please close it to continue.`);
158 }
159
160 _afterPrint() {
161 this._statusView.hide();
162 this._statusView.toggleCancelButton(true);
163 }
164
Patrick Hulcea087f622018-05-18 00:37:53 +0000165 /**
166 * @param {!ReportRenderer.ReportJSON} lighthouseResult
Paul Irish8f1e33d2018-05-31 02:29:50 +0000167 * @param {!ReportRenderer.RunnerResultArtifacts=} artifacts
Patrick Hulcea087f622018-05-18 00:37:53 +0000168 */
Paul Irish8f1e33d2018-05-31 02:29:50 +0000169 _renderReport(lighthouseResult, artifacts) {
Connor Clarke66080e2019-11-06 16:35:51 -0800170 this._toggleSettingsDisplay(false);
Patrick Hulcea087f622018-05-18 00:37:53 +0000171 this.contentElement.classList.toggle('in-progress', false);
172 this._startView.hideWidget();
173 this._statusView.hide();
174 this._auditResultsElement.removeChildren();
Patrick Hulce05c18ce2018-05-24 00:34:56 +0000175 this._newButton.setEnabled(true);
Patrick Hulcea087f622018-05-18 00:37:53 +0000176 this._refreshToolbarUI();
177
178 const cachedRenderedReport = this._cachedRenderedReports.get(lighthouseResult);
179 if (cachedRenderedReport) {
180 this._auditResultsElement.appendChild(cachedRenderedReport);
181 return;
Blink Reformat4c46d092018-04-07 15:32:37 +0000182 }
183
Patrick Hulcea087f622018-05-18 00:37:53 +0000184 const reportContainer = this._auditResultsElement.createChild('div', 'lh-vars lh-root lh-devtools');
Blink Reformat4c46d092018-04-07 15:32:37 +0000185
Patrick Hulcea087f622018-05-18 00:37:53 +0000186 const dom = new DOM(/** @type {!Document} */ (this._auditResultsElement.ownerDocument));
Connor Clark2bc3be22020-02-14 14:34:19 -0800187 const renderer = new LighthouseReportRenderer(dom);
Patrick Hulcea087f622018-05-18 00:37:53 +0000188
Connor Clark2bc3be22020-02-14 14:34:19 -0800189 const templatesHTML = Root.Runtime.cachedResources['lighthouse/lighthouse/templates.html'];
Patrick Hulcea087f622018-05-18 00:37:53 +0000190 const templatesDOM = new DOMParser().parseFromString(templatesHTML, 'text/html');
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000191 if (!templatesDOM) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000192 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000193 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000194
Patrick Hulcea087f622018-05-18 00:37:53 +0000195 renderer.setTemplateContext(templatesDOM);
Paul Irish8f1e33d2018-05-31 02:29:50 +0000196 const el = renderer.renderReport(lighthouseResult, reportContainer);
Connor Clark2bc3be22020-02-14 14:34:19 -0800197 LighthouseReportRenderer.addViewTraceButton(el, artifacts);
cjamcl@google.comc5214af2019-06-25 20:31:21 +0000198 // Linkifying requires the target be loaded. Do not block the report
199 // from rendering, as this is just an embellishment and the main target
200 // could take awhile to load.
201 this._waitForMainTargetLoad().then(() => {
Connor Clark2bc3be22020-02-14 14:34:19 -0800202 LighthouseReportRenderer.linkifyNodeDetails(el);
203 LighthouseReportRenderer.linkifySourceLocationDetails(el);
cjamcl@google.comc5214af2019-06-25 20:31:21 +0000204 });
Connor Clark2bc3be22020-02-14 14:34:19 -0800205 LighthouseReportRenderer.handleDarkMode(el);
cjamcl@google.comf2f8c092019-05-30 22:01:56 +0000206
Connor Clark2bc3be22020-02-14 14:34:19 -0800207 const features = new LighthouseReportUIFeatures(dom);
Connor Clark99508362019-08-20 19:52:23 +0000208 features.setBeforePrint(this._beforePrint.bind(this));
209 features.setAfterPrint(this._afterPrint.bind(this));
cjamcl@google.comf2f8c092019-05-30 22:01:56 +0000210 features.setTemplateContext(templatesDOM);
211 features.initFeatures(lighthouseResult);
Blink Reformat4c46d092018-04-07 15:32:37 +0000212
Patrick Hulcea087f622018-05-18 00:37:53 +0000213 this._cachedRenderedReports.set(lighthouseResult, reportContainer);
Blink Reformat4c46d092018-04-07 15:32:37 +0000214 }
215
cjamcl@google.comc5214af2019-06-25 20:31:21 +0000216 _waitForMainTargetLoad() {
Paul Lewis4ae5f4f2020-01-23 10:19:33 +0000217 const mainTarget = self.SDK.targetManager.mainTarget();
cjamcl@google.comc5214af2019-06-25 20:31:21 +0000218 const resourceTreeModel = mainTarget.model(SDK.ResourceTreeModel);
219 return resourceTreeModel.once(SDK.ResourceTreeModel.Events.Load);
220 }
221
Blink Reformat4c46d092018-04-07 15:32:37 +0000222 /**
223 * @param {!ReportRenderer.ReportJSON} lighthouseResult
Paul Irish8f1e33d2018-05-31 02:29:50 +0000224 * @param {!ReportRenderer.RunnerResultArtifacts=} artifacts
Blink Reformat4c46d092018-04-07 15:32:37 +0000225 */
Paul Irish8f1e33d2018-05-31 02:29:50 +0000226 _buildReportUI(lighthouseResult, artifacts) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000227 if (lighthouseResult === null) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000228 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000229 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000230
Paul Lewis51474192020-01-09 16:02:22 +0000231 const optionElement = new Item(
Paul Irish8f1e33d2018-05-31 02:29:50 +0000232 lighthouseResult, () => this._renderReport(lighthouseResult, artifacts), this._renderStartView.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37 +0000233 this._reportSelector.prepend(optionElement);
Blink Reformat4c46d092018-04-07 15:32:37 +0000234 this._refreshToolbarUI();
Patrick Hulcea087f622018-05-18 00:37:53 +0000235 this._renderReport(lighthouseResult);
Blink Reformat4c46d092018-04-07 15:32:37 +0000236 }
237
238 /**
239 * @param {!DataTransfer} dataTransfer
240 */
241 _handleDrop(dataTransfer) {
242 const items = dataTransfer.items;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000243 if (!items.length) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000244 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000245 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000246 const item = items[0];
247 if (item.kind === 'file') {
248 const entry = items[0].webkitGetAsEntry();
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000249 if (!entry.isFile) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000250 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000251 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000252 entry.file(file => {
253 const reader = new FileReader();
254 reader.onload = () => this._loadedFromFile(/** @type {string} */ (reader.result));
255 reader.readAsText(file);
256 });
257 }
258 }
259
260 /**
Patrick Hulcea087f622018-05-18 00:37:53 +0000261 * @param {string} report
Blink Reformat4c46d092018-04-07 15:32:37 +0000262 */
Patrick Hulcea087f622018-05-18 00:37:53 +0000263 _loadedFromFile(report) {
264 const data = JSON.parse(report);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000265 if (!data['lighthouseVersion']) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000266 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000267 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000268 this._buildReportUI(/** @type {!ReportRenderer.ReportJSON} */ (data));
269 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000270
Brandon Goddard04d5ba92019-12-19 08:31:55 -0800271 /**
Tim van der Lippec02a97c2020-02-14 14:39:27 +0000272 * @param {!Common.EventTarget.EventTargetEvent} event
Brandon Goddard04d5ba92019-12-19 08:31:55 -0800273 */
Connor Clark2bc3be22020-02-14 14:34:19 -0800274 async _startLighthouse(event) {
275 Host.userMetrics.actionTaken(Host.UserMetrics.Action.LighthouseStarted);
Blink Reformat4c46d092018-04-07 15:32:37 +0000276
Patrick Hulcea087f622018-05-18 00:37:53 +0000277 try {
278 const inspectedURL = await this._controller.getInspectedURL({force: true});
279 const categoryIDs = this._controller.getCategoryIDs();
280 const flags = this._controller.getFlags();
Blink Reformat4c46d092018-04-07 15:32:37 +0000281
Patrick Hulcea087f622018-05-18 00:37:53 +0000282 await this._setupEmulationAndProtocolConnection();
Blink Reformat4c46d092018-04-07 15:32:37 +0000283
Patrick Hulcea087f622018-05-18 00:37:53 +0000284 this._renderStatusView(inspectedURL);
Blink Reformat4c46d092018-04-07 15:32:37 +0000285
Paul Irish8f1e33d2018-05-31 02:29:50 +0000286 const lighthouseResponse = await this._protocolService.startLighthouse(inspectedURL, categoryIDs, flags);
Blink Reformat4c46d092018-04-07 15:32:37 +0000287
Paul Irish8f1e33d2018-05-31 02:29:50 +0000288 if (lighthouseResponse && lighthouseResponse.fatal) {
289 const error = new Error(lighthouseResponse.message);
290 error.stack = lighthouseResponse.stack;
Patrick Hulcea087f622018-05-18 00:37:53 +0000291 throw error;
292 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000293
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000294 if (!lighthouseResponse) {
Patrick Hulcea087f622018-05-18 00:37:53 +0000295 throw new Error('Auditing failed to produce a result');
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000296 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000297
Connor Clark2bc3be22020-02-14 14:34:19 -0800298 Host.userMetrics.actionTaken(Host.UserMetrics.Action.LighthouseFinished);
Blink Reformat4c46d092018-04-07 15:32:37 +0000299
Patrick Hulcea087f622018-05-18 00:37:53 +0000300 await this._resetEmulationAndProtocolConnection();
Paul Irish8f1e33d2018-05-31 02:29:50 +0000301 this._buildReportUI(lighthouseResponse.lhr, lighthouseResponse.artifacts);
Brandon Goddard04d5ba92019-12-19 08:31:55 -0800302 // Give focus to the new audit button when completed
303 this._newButton.element.focus();
304 const keyboardInitiated = /** @type {boolean} */ (event.data);
305 if (keyboardInitiated) {
306 UI.markAsFocusedByKeyboard(this._newButton.element);
307 }
Patrick Hulcea087f622018-05-18 00:37:53 +0000308 } catch (err) {
Paul Irishdca01d02019-03-25 20:17:56 +0000309 await this._resetEmulationAndProtocolConnection();
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000310 if (err instanceof Error) {
Patrick Hulcea087f622018-05-18 00:37:53 +0000311 this._statusView.renderBugReport(err);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000312 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000313 }
314 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000315
Connor Clark2bc3be22020-02-14 14:34:19 -0800316 async _cancelLighthouse() {
Patrick Hulcea087f622018-05-18 00:37:53 +0000317 this._statusView.updateStatus(ls`Cancelling`);
318 await this._resetEmulationAndProtocolConnection();
319 this._renderStartView();
Blink Reformat4c46d092018-04-07 15:32:37 +0000320 }
321
Paul Irishd8495012019-07-16 23:51:47 +0000322 /**
323 * We set the device emulation on the DevTools-side for two reasons:
324 * 1. To workaround some odd device metrics emulation bugs like occuluding viewports
325 * 2. To get the attractive device outline
Connor Clarkca8905e2019-08-23 18:35:10 +0000326 *
Connor Clark3ee5ac72019-11-07 15:11:58 -0800327 * We also set flags.internalDisableDeviceScreenEmulation = true to let LH only apply UA emulation
Paul Irishd8495012019-07-16 23:51:47 +0000328 */
Patrick Hulcea087f622018-05-18 00:37:53 +0000329 async _setupEmulationAndProtocolConnection() {
330 const flags = this._controller.getFlags();
Blink Reformat4c46d092018-04-07 15:32:37 +0000331
Patrick Hulcea087f622018-05-18 00:37:53 +0000332 const emulationModel = self.singleton(Emulation.DeviceModeModel);
Connor Clarkca8905e2019-08-23 18:35:10 +0000333 this._stateBefore = {
334 emulation: {
335 enabled: emulationModel.enabledSetting().get(),
336 outlineEnabled: emulationModel.deviceOutlineSetting().get(),
337 toolbarControlsEnabled: emulationModel.toolbarControlsEnabledSetting().get()
338 },
Paul Lewis5a922e72020-01-24 11:58:08 +0000339 network: {conditions: self.SDK.multitargetNetworkManager.networkConditions()}
Connor Clarkca8905e2019-08-23 18:35:10 +0000340 };
Patrick Hulcea087f622018-05-18 00:37:53 +0000341
Connor Clarkca8905e2019-08-23 18:35:10 +0000342 emulationModel.toolbarControlsEnabledSetting().set(false);
Connor Clark3f700342019-07-25 02:10:41 +0000343 if (flags.emulatedFormFactor === 'desktop') {
Patrick Hulcea087f622018-05-18 00:37:53 +0000344 emulationModel.enabledSetting().set(false);
Patrick Hulcea087f622018-05-18 00:37:53 +0000345 emulationModel.emulate(Emulation.DeviceModeModel.Type.None, null, null);
Connor Clark3f700342019-07-25 02:10:41 +0000346 } else if (flags.emulatedFormFactor === 'mobile') {
Patrick Hulcea087f622018-05-18 00:37:53 +0000347 emulationModel.enabledSetting().set(true);
348 emulationModel.deviceOutlineSetting().set(true);
349
350 for (const device of Emulation.EmulatedDevicesList.instance().standard()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000351 if (device.title === 'Nexus 5X') {
Patrick Hulcea087f622018-05-18 00:37:53 +0000352 emulationModel.emulate(Emulation.DeviceModeModel.Type.Device, device, device.modes[0], 1);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000353 }
Patrick Hulcea087f622018-05-18 00:37:53 +0000354 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000355 }
356
Patrick Hulcea087f622018-05-18 00:37:53 +0000357 await this._protocolService.attach();
358 this._isLHAttached = true;
359 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000360
Patrick Hulcea087f622018-05-18 00:37:53 +0000361 async _resetEmulationAndProtocolConnection() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000362 if (!this._isLHAttached) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000363 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000364 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000365
Patrick Hulcea087f622018-05-18 00:37:53 +0000366 this._isLHAttached = false;
367 await this._protocolService.detach();
Blink Reformat4c46d092018-04-07 15:32:37 +0000368
Connor Clarkca8905e2019-08-23 18:35:10 +0000369 if (this._stateBefore) {
370 const emulationModel = self.singleton(Emulation.DeviceModeModel);
371 emulationModel.enabledSetting().set(this._stateBefore.emulation.enabled);
372 emulationModel.deviceOutlineSetting().set(this._stateBefore.emulation.outlineEnabled);
373 emulationModel.toolbarControlsEnabledSetting().set(this._stateBefore.emulation.toolbarControlsEnabled);
Paul Lewis5a922e72020-01-24 11:58:08 +0000374 self.SDK.multitargetNetworkManager.setNetworkConditions(this._stateBefore.network.conditions);
Connor Clarkca8905e2019-08-23 18:35:10 +0000375 delete this._stateBefore;
376 }
377
Patrick Hulcea087f622018-05-18 00:37:53 +0000378 Emulation.InspectedPagePlaceholder.instance().update(true);
Blink Reformat4c46d092018-04-07 15:32:37 +0000379
Paul Lewis4ae5f4f2020-01-23 10:19:33 +0000380 const resourceTreeModel = self.SDK.targetManager.mainTarget().model(SDK.ResourceTreeModel);
Patrick Hulcea087f622018-05-18 00:37:53 +0000381 // reload to reset the page state
382 const inspectedURL = await this._controller.getInspectedURL();
383 await resourceTreeModel.navigate(inspectedURL);
Blink Reformat4c46d092018-04-07 15:32:37 +0000384 }
Paul Lewiscf2ef222019-11-22 14:55:35 +0000385}