blob: 90f3c7fc9e3b57851e457dbf95adcd98dca0d2e6 [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
Paul Lewis51474192020-01-09 16:02:22 +00005import {AuditController, Events} from './AuditsController.js';
6import {ProtocolService} from './AuditsProtocolService.js';
7import {AuditsReportRenderer, AuditsReportUIFeatures} from './AuditsReportRenderer.js';
8import {Item, ReportSelector} from './AuditsReportSelector.js';
9import {StartView} from './AuditsStartView.js';
10import {StatusView} from './AuditsStatusView.js';
11
Blink Reformat4c46d092018-04-07 15:32:37 +000012/**
Blink Reformat4c46d092018-04-07 15:32:37 +000013 * @unrestricted
14 */
Paul Lewis51474192020-01-09 16:02:22 +000015export class AuditsPanel extends UI.Panel {
Blink Reformat4c46d092018-04-07 15:32:37 +000016 constructor() {
cjamcl@google.comaa1532c2019-05-31 03:01:24 +000017 super('audits');
18 this.registerRequiredCSS('audits/lighthouse/report.css');
19 this.registerRequiredCSS('audits/auditsPanel.css');
Blink Reformat4c46d092018-04-07 15:32:37 +000020
Paul Lewis51474192020-01-09 16:02:22 +000021 this._protocolService = new ProtocolService();
22 this._controller = new AuditController(this._protocolService);
23 this._startView = new StartView(this._controller);
24 this._statusView = new StatusView(this._controller);
Blink Reformat4c46d092018-04-07 15:32:37 +000025
Patrick Hulcea087f622018-05-18 00:37:53 +000026 this._unauditableExplanation = null;
27 this._cachedRenderedReports = new Map();
Blink Reformat4c46d092018-04-07 15:32:37 +000028
Blink Reformat4c46d092018-04-07 15:32:37 +000029 this._dropTarget = new UI.DropTarget(
30 this.contentElement, [UI.DropTarget.Type.File], Common.UIString('Drop audit file here'),
31 this._handleDrop.bind(this));
32
Paul Lewis51474192020-01-09 16:02:22 +000033 this._controller.addEventListener(Events.PageAuditabilityChanged, this._refreshStartAuditUI.bind(this));
34 this._controller.addEventListener(Events.AuditProgressChanged, this._refreshStatusUI.bind(this));
35 this._controller.addEventListener(Events.RequestAuditStart, this._startAudit.bind(this));
36 this._controller.addEventListener(Events.RequestAuditCancel, this._cancelAudit.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37 +000037
Patrick Hulcea087f622018-05-18 00:37:53 +000038 this._renderToolbar();
cjamcl@google.comaa1532c2019-05-31 03:01:24 +000039 this._auditResultsElement = this.contentElement.createChild('div', 'audits-results-container');
Patrick Hulcea087f622018-05-18 00:37:53 +000040 this._renderStartView();
41
42 this._controller.recomputePageAuditability();
Blink Reformat4c46d092018-04-07 15:32:37 +000043 }
44
45 /**
Patrick Hulcea087f622018-05-18 00:37:53 +000046 * @param {!Common.Event} evt
Blink Reformat4c46d092018-04-07 15:32:37 +000047 */
Patrick Hulcea087f622018-05-18 00:37:53 +000048 _refreshStartAuditUI(evt) {
Connor Clarkca8905e2019-08-23 18:35:10 +000049 // PageAuditabilityChanged fires multiple times during an audit, which we want to ignore.
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +000050 if (this._isLHAttached) {
Connor Clarkca8905e2019-08-23 18:35:10 +000051 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +000052 }
Connor Clarkca8905e2019-08-23 18:35:10 +000053
Patrick Hulcea087f622018-05-18 00:37:53 +000054 this._unauditableExplanation = evt.data.helpText;
55 this._startView.setUnauditableExplanation(evt.data.helpText);
56 this._startView.setStartButtonEnabled(!evt.data.helpText);
Blink Reformat4c46d092018-04-07 15:32:37 +000057 }
58
59 /**
Patrick Hulcea087f622018-05-18 00:37:53 +000060 * @param {!Common.Event} evt
Blink Reformat4c46d092018-04-07 15:32:37 +000061 */
Patrick Hulcea087f622018-05-18 00:37:53 +000062 _refreshStatusUI(evt) {
63 this._statusView.updateStatus(evt.data.message);
Blink Reformat4c46d092018-04-07 15:32:37 +000064 }
65
66 _refreshToolbarUI() {
Blink Reformat4c46d092018-04-07 15:32:37 +000067 this._clearButton.setEnabled(this._reportSelector.hasItems());
68 }
69
70 _clearAll() {
71 this._reportSelector.clearAll();
Patrick Hulcea087f622018-05-18 00:37:53 +000072 this._renderStartView();
Blink Reformat4c46d092018-04-07 15:32:37 +000073 this._refreshToolbarUI();
74 }
75
Blink Reformat4c46d092018-04-07 15:32:37 +000076 _renderToolbar() {
Connor Clarke66080e2019-11-06 16:35:51 -080077 const auditsToolbarContainer = this.element.createChild('div', 'audits-toolbar-container');
78
79 const toolbar = new UI.Toolbar('', auditsToolbarContainer);
Blink Reformat4c46d092018-04-07 15:32:37 +000080
81 this._newButton = new UI.ToolbarButton(Common.UIString('Perform an audit\u2026'), 'largeicon-add');
82 toolbar.appendToolbarItem(this._newButton);
Patrick Hulcea087f622018-05-18 00:37:53 +000083 this._newButton.addEventListener(UI.ToolbarButton.Events.Click, this._renderStartView.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37 +000084
Blink Reformat4c46d092018-04-07 15:32:37 +000085 toolbar.appendSeparator();
86
Paul Lewis51474192020-01-09 16:02:22 +000087 this._reportSelector = new ReportSelector(() => this._renderStartView());
Blink Reformat4c46d092018-04-07 15:32:37 +000088 toolbar.appendToolbarItem(this._reportSelector.comboBox());
89
90 this._clearButton = new UI.ToolbarButton(Common.UIString('Clear all'), 'largeicon-clear');
91 toolbar.appendToolbarItem(this._clearButton);
92 this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearAll.bind(this));
93
Connor Clarke66080e2019-11-06 16:35:51 -080094 this._settingsPane = new UI.HBox();
95 this._settingsPane.show(this.contentElement);
96 this._settingsPane.element.classList.add('audits-settings-pane');
97 this._settingsPane.element.appendChild(this._startView.settingsToolbar().element);
98 this._showSettingsPaneSetting = Common.settings.createSetting('auditsShowSettingsToolbar', false);
99
100 this._rightToolbar = new UI.Toolbar('', auditsToolbarContainer);
101 this._rightToolbar.appendSeparator();
102 this._rightToolbar.appendToolbarItem(
103 new UI.ToolbarSettingToggle(this._showSettingsPaneSetting, 'largeicon-settings-gear', ls`Audits settings`));
104 this._showSettingsPaneSetting.addChangeListener(this._updateSettingsPaneVisibility.bind(this));
105 this._updateSettingsPaneVisibility();
106
Patrick Hulcea087f622018-05-18 00:37:53 +0000107 this._refreshToolbarUI();
108 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000109
Connor Clarke66080e2019-11-06 16:35:51 -0800110 _updateSettingsPaneVisibility() {
111 this._settingsPane.element.classList.toggle('hidden', !this._showSettingsPaneSetting.get());
112 }
113
114 /**
115 * @param {boolean} show
116 */
117 _toggleSettingsDisplay(show) {
118 this._rightToolbar.element.classList.toggle('hidden', !show);
119 this._settingsPane.element.classList.toggle('hidden', !show);
120 this._updateSettingsPaneVisibility();
121 }
122
Patrick Hulcea087f622018-05-18 00:37:53 +0000123 _renderStartView() {
124 this._auditResultsElement.removeChildren();
125 this._statusView.hide();
126
127 this._reportSelector.selectNewAudit();
128 this.contentElement.classList.toggle('in-progress', false);
129
130 this._startView.show(this.contentElement);
Connor Clarke66080e2019-11-06 16:35:51 -0800131 this._toggleSettingsDisplay(true);
Patrick Hulcea087f622018-05-18 00:37:53 +0000132 this._startView.setUnauditableExplanation(this._unauditableExplanation);
133 this._startView.setStartButtonEnabled(!this._unauditableExplanation);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000134 if (!this._unauditableExplanation) {
Patrick Hulce8d387f12018-05-29 18:54:54 +0000135 this._startView.focusStartButton();
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000136 }
Patrick Hulce8d387f12018-05-29 18:54:54 +0000137
Patrick Hulce05c18ce2018-05-24 00:34:56 +0000138 this._newButton.setEnabled(false);
Patrick Hulcea087f622018-05-18 00:37:53 +0000139 this._refreshToolbarUI();
Patrick Hulce05c18ce2018-05-24 00:34:56 +0000140 this.setDefaultFocusedChild(this._startView);
Patrick Hulcea087f622018-05-18 00:37:53 +0000141 }
142
143 /**
144 * @param {string} inspectedURL
145 */
146 _renderStatusView(inspectedURL) {
147 this.contentElement.classList.toggle('in-progress', true);
148 this._statusView.setInspectedURL(inspectedURL);
149 this._statusView.show(this.contentElement);
150 }
151
Connor Clark99508362019-08-20 19:52:23 +0000152 _beforePrint() {
153 this._statusView.show(this.contentElement);
154 this._statusView.toggleCancelButton(false);
155 this._statusView.renderText(ls`Printing`, ls`The print popup window is open. Please close it to continue.`);
156 }
157
158 _afterPrint() {
159 this._statusView.hide();
160 this._statusView.toggleCancelButton(true);
161 }
162
Patrick Hulcea087f622018-05-18 00:37:53 +0000163 /**
164 * @param {!ReportRenderer.ReportJSON} lighthouseResult
Paul Irish8f1e33d2018-05-31 02:29:50 +0000165 * @param {!ReportRenderer.RunnerResultArtifacts=} artifacts
Patrick Hulcea087f622018-05-18 00:37:53 +0000166 */
Paul Irish8f1e33d2018-05-31 02:29:50 +0000167 _renderReport(lighthouseResult, artifacts) {
Connor Clarke66080e2019-11-06 16:35:51 -0800168 this._toggleSettingsDisplay(false);
Patrick Hulcea087f622018-05-18 00:37:53 +0000169 this.contentElement.classList.toggle('in-progress', false);
170 this._startView.hideWidget();
171 this._statusView.hide();
172 this._auditResultsElement.removeChildren();
Patrick Hulce05c18ce2018-05-24 00:34:56 +0000173 this._newButton.setEnabled(true);
Patrick Hulcea087f622018-05-18 00:37:53 +0000174 this._refreshToolbarUI();
175
176 const cachedRenderedReport = this._cachedRenderedReports.get(lighthouseResult);
177 if (cachedRenderedReport) {
178 this._auditResultsElement.appendChild(cachedRenderedReport);
179 return;
Blink Reformat4c46d092018-04-07 15:32:37 +0000180 }
181
Patrick Hulcea087f622018-05-18 00:37:53 +0000182 const reportContainer = this._auditResultsElement.createChild('div', 'lh-vars lh-root lh-devtools');
Blink Reformat4c46d092018-04-07 15:32:37 +0000183
Patrick Hulcea087f622018-05-18 00:37:53 +0000184 const dom = new DOM(/** @type {!Document} */ (this._auditResultsElement.ownerDocument));
Paul Lewis51474192020-01-09 16:02:22 +0000185 const renderer = new AuditsReportRenderer(dom);
Patrick Hulcea087f622018-05-18 00:37:53 +0000186
Tim van der Lippe99e59b82019-09-30 20:00:59 +0000187 const templatesHTML = Root.Runtime.cachedResources['audits/lighthouse/templates.html'];
Patrick Hulcea087f622018-05-18 00:37:53 +0000188 const templatesDOM = new DOMParser().parseFromString(templatesHTML, 'text/html');
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000189 if (!templatesDOM) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000190 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000191 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000192
Patrick Hulcea087f622018-05-18 00:37:53 +0000193 renderer.setTemplateContext(templatesDOM);
Paul Irish8f1e33d2018-05-31 02:29:50 +0000194 const el = renderer.renderReport(lighthouseResult, reportContainer);
Paul Lewis51474192020-01-09 16:02:22 +0000195 AuditsReportRenderer.addViewTraceButton(el, artifacts);
cjamcl@google.comc5214af2019-06-25 20:31:21 +0000196 // Linkifying requires the target be loaded. Do not block the report
197 // from rendering, as this is just an embellishment and the main target
198 // could take awhile to load.
199 this._waitForMainTargetLoad().then(() => {
Paul Lewis51474192020-01-09 16:02:22 +0000200 AuditsReportRenderer.linkifyNodeDetails(el);
201 AuditsReportRenderer.linkifySourceLocationDetails(el);
cjamcl@google.comc5214af2019-06-25 20:31:21 +0000202 });
Paul Lewis51474192020-01-09 16:02:22 +0000203 AuditsReportRenderer.handleDarkMode(el);
cjamcl@google.comf2f8c092019-05-30 22:01:56 +0000204
Paul Lewis51474192020-01-09 16:02:22 +0000205 const features = new AuditsReportUIFeatures(dom);
Connor Clark99508362019-08-20 19:52:23 +0000206 features.setBeforePrint(this._beforePrint.bind(this));
207 features.setAfterPrint(this._afterPrint.bind(this));
cjamcl@google.comf2f8c092019-05-30 22:01:56 +0000208 features.setTemplateContext(templatesDOM);
209 features.initFeatures(lighthouseResult);
Blink Reformat4c46d092018-04-07 15:32:37 +0000210
Patrick Hulcea087f622018-05-18 00:37:53 +0000211 this._cachedRenderedReports.set(lighthouseResult, reportContainer);
Blink Reformat4c46d092018-04-07 15:32:37 +0000212 }
213
cjamcl@google.comc5214af2019-06-25 20:31:21 +0000214 _waitForMainTargetLoad() {
Paul Lewis4ae5f4f2020-01-23 10:19:33 +0000215 const mainTarget = self.SDK.targetManager.mainTarget();
cjamcl@google.comc5214af2019-06-25 20:31:21 +0000216 const resourceTreeModel = mainTarget.model(SDK.ResourceTreeModel);
217 return resourceTreeModel.once(SDK.ResourceTreeModel.Events.Load);
218 }
219
Blink Reformat4c46d092018-04-07 15:32:37 +0000220 /**
221 * @param {!ReportRenderer.ReportJSON} lighthouseResult
Paul Irish8f1e33d2018-05-31 02:29:50 +0000222 * @param {!ReportRenderer.RunnerResultArtifacts=} artifacts
Blink Reformat4c46d092018-04-07 15:32:37 +0000223 */
Paul Irish8f1e33d2018-05-31 02:29:50 +0000224 _buildReportUI(lighthouseResult, artifacts) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000225 if (lighthouseResult === null) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000226 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000227 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000228
Paul Lewis51474192020-01-09 16:02:22 +0000229 const optionElement = new Item(
Paul Irish8f1e33d2018-05-31 02:29:50 +0000230 lighthouseResult, () => this._renderReport(lighthouseResult, artifacts), this._renderStartView.bind(this));
Blink Reformat4c46d092018-04-07 15:32:37 +0000231 this._reportSelector.prepend(optionElement);
Blink Reformat4c46d092018-04-07 15:32:37 +0000232 this._refreshToolbarUI();
Patrick Hulcea087f622018-05-18 00:37:53 +0000233 this._renderReport(lighthouseResult);
Blink Reformat4c46d092018-04-07 15:32:37 +0000234 }
235
236 /**
237 * @param {!DataTransfer} dataTransfer
238 */
239 _handleDrop(dataTransfer) {
240 const items = dataTransfer.items;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000241 if (!items.length) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000242 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000243 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000244 const item = items[0];
245 if (item.kind === 'file') {
246 const entry = items[0].webkitGetAsEntry();
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000247 if (!entry.isFile) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000248 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000249 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000250 entry.file(file => {
251 const reader = new FileReader();
252 reader.onload = () => this._loadedFromFile(/** @type {string} */ (reader.result));
253 reader.readAsText(file);
254 });
255 }
256 }
257
258 /**
Patrick Hulcea087f622018-05-18 00:37:53 +0000259 * @param {string} report
Blink Reformat4c46d092018-04-07 15:32:37 +0000260 */
Patrick Hulcea087f622018-05-18 00:37:53 +0000261 _loadedFromFile(report) {
262 const data = JSON.parse(report);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000263 if (!data['lighthouseVersion']) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000264 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000265 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000266 this._buildReportUI(/** @type {!ReportRenderer.ReportJSON} */ (data));
267 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000268
Brandon Goddard04d5ba92019-12-19 08:31:55 -0800269 /**
270 * @param {!Common.Event} event
271 */
272 async _startAudit(event) {
cjamcl@google.comaa1532c2019-05-31 03:01:24 +0000273 Host.userMetrics.actionTaken(Host.UserMetrics.Action.AuditsStarted);
Blink Reformat4c46d092018-04-07 15:32:37 +0000274
Patrick Hulcea087f622018-05-18 00:37:53 +0000275 try {
276 const inspectedURL = await this._controller.getInspectedURL({force: true});
277 const categoryIDs = this._controller.getCategoryIDs();
278 const flags = this._controller.getFlags();
Blink Reformat4c46d092018-04-07 15:32:37 +0000279
Patrick Hulcea087f622018-05-18 00:37:53 +0000280 await this._setupEmulationAndProtocolConnection();
Blink Reformat4c46d092018-04-07 15:32:37 +0000281
Patrick Hulcea087f622018-05-18 00:37:53 +0000282 this._renderStatusView(inspectedURL);
Blink Reformat4c46d092018-04-07 15:32:37 +0000283
Paul Irish8f1e33d2018-05-31 02:29:50 +0000284 const lighthouseResponse = await this._protocolService.startLighthouse(inspectedURL, categoryIDs, flags);
Blink Reformat4c46d092018-04-07 15:32:37 +0000285
Paul Irish8f1e33d2018-05-31 02:29:50 +0000286 if (lighthouseResponse && lighthouseResponse.fatal) {
287 const error = new Error(lighthouseResponse.message);
288 error.stack = lighthouseResponse.stack;
Patrick Hulcea087f622018-05-18 00:37:53 +0000289 throw error;
290 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000291
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000292 if (!lighthouseResponse) {
Patrick Hulcea087f622018-05-18 00:37:53 +0000293 throw new Error('Auditing failed to produce a result');
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000294 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000295
cjamcl@google.comaa1532c2019-05-31 03:01:24 +0000296 Host.userMetrics.actionTaken(Host.UserMetrics.Action.AuditsFinished);
Blink Reformat4c46d092018-04-07 15:32:37 +0000297
Patrick Hulcea087f622018-05-18 00:37:53 +0000298 await this._resetEmulationAndProtocolConnection();
Paul Irish8f1e33d2018-05-31 02:29:50 +0000299 this._buildReportUI(lighthouseResponse.lhr, lighthouseResponse.artifacts);
Brandon Goddard04d5ba92019-12-19 08:31:55 -0800300 // Give focus to the new audit button when completed
301 this._newButton.element.focus();
302 const keyboardInitiated = /** @type {boolean} */ (event.data);
303 if (keyboardInitiated) {
304 UI.markAsFocusedByKeyboard(this._newButton.element);
305 }
Patrick Hulcea087f622018-05-18 00:37:53 +0000306 } catch (err) {
Paul Irishdca01d02019-03-25 20:17:56 +0000307 await this._resetEmulationAndProtocolConnection();
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000308 if (err instanceof Error) {
Patrick Hulcea087f622018-05-18 00:37:53 +0000309 this._statusView.renderBugReport(err);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000310 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000311 }
312 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000313
Patrick Hulcea087f622018-05-18 00:37:53 +0000314 async _cancelAudit() {
315 this._statusView.updateStatus(ls`Cancelling`);
316 await this._resetEmulationAndProtocolConnection();
317 this._renderStartView();
Blink Reformat4c46d092018-04-07 15:32:37 +0000318 }
319
Paul Irishd8495012019-07-16 23:51:47 +0000320 /**
321 * We set the device emulation on the DevTools-side for two reasons:
322 * 1. To workaround some odd device metrics emulation bugs like occuluding viewports
323 * 2. To get the attractive device outline
Connor Clarkca8905e2019-08-23 18:35:10 +0000324 *
Connor Clark3ee5ac72019-11-07 15:11:58 -0800325 * We also set flags.internalDisableDeviceScreenEmulation = true to let LH only apply UA emulation
Paul Irishd8495012019-07-16 23:51:47 +0000326 */
Patrick Hulcea087f622018-05-18 00:37:53 +0000327 async _setupEmulationAndProtocolConnection() {
328 const flags = this._controller.getFlags();
Blink Reformat4c46d092018-04-07 15:32:37 +0000329
Patrick Hulcea087f622018-05-18 00:37:53 +0000330 const emulationModel = self.singleton(Emulation.DeviceModeModel);
Connor Clarkca8905e2019-08-23 18:35:10 +0000331 this._stateBefore = {
332 emulation: {
333 enabled: emulationModel.enabledSetting().get(),
334 outlineEnabled: emulationModel.deviceOutlineSetting().get(),
335 toolbarControlsEnabled: emulationModel.toolbarControlsEnabledSetting().get()
336 },
337 network: {conditions: SDK.multitargetNetworkManager.networkConditions()}
338 };
Patrick Hulcea087f622018-05-18 00:37:53 +0000339
Connor Clarkca8905e2019-08-23 18:35:10 +0000340 emulationModel.toolbarControlsEnabledSetting().set(false);
Connor Clark3f700342019-07-25 02:10:41 +0000341 if (flags.emulatedFormFactor === 'desktop') {
Patrick Hulcea087f622018-05-18 00:37:53 +0000342 emulationModel.enabledSetting().set(false);
Patrick Hulcea087f622018-05-18 00:37:53 +0000343 emulationModel.emulate(Emulation.DeviceModeModel.Type.None, null, null);
Connor Clark3f700342019-07-25 02:10:41 +0000344 } else if (flags.emulatedFormFactor === 'mobile') {
Patrick Hulcea087f622018-05-18 00:37:53 +0000345 emulationModel.enabledSetting().set(true);
346 emulationModel.deviceOutlineSetting().set(true);
347
348 for (const device of Emulation.EmulatedDevicesList.instance().standard()) {
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000349 if (device.title === 'Nexus 5X') {
Patrick Hulcea087f622018-05-18 00:37:53 +0000350 emulationModel.emulate(Emulation.DeviceModeModel.Type.Device, device, device.modes[0], 1);
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000351 }
Patrick Hulcea087f622018-05-18 00:37:53 +0000352 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000353 }
354
Patrick Hulcea087f622018-05-18 00:37:53 +0000355 await this._protocolService.attach();
356 this._isLHAttached = true;
357 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000358
Patrick Hulcea087f622018-05-18 00:37:53 +0000359 async _resetEmulationAndProtocolConnection() {
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000360 if (!this._isLHAttached) {
Blink Reformat4c46d092018-04-07 15:32:37 +0000361 return;
Tim van der Lippe1d6e57a2019-09-30 11:55:34 +0000362 }
Blink Reformat4c46d092018-04-07 15:32:37 +0000363
Patrick Hulcea087f622018-05-18 00:37:53 +0000364 this._isLHAttached = false;
365 await this._protocolService.detach();
Blink Reformat4c46d092018-04-07 15:32:37 +0000366
Connor Clarkca8905e2019-08-23 18:35:10 +0000367 if (this._stateBefore) {
368 const emulationModel = self.singleton(Emulation.DeviceModeModel);
369 emulationModel.enabledSetting().set(this._stateBefore.emulation.enabled);
370 emulationModel.deviceOutlineSetting().set(this._stateBefore.emulation.outlineEnabled);
371 emulationModel.toolbarControlsEnabledSetting().set(this._stateBefore.emulation.toolbarControlsEnabled);
372 SDK.multitargetNetworkManager.setNetworkConditions(this._stateBefore.network.conditions);
373 delete this._stateBefore;
374 }
375
Patrick Hulcea087f622018-05-18 00:37:53 +0000376 Emulation.InspectedPagePlaceholder.instance().update(true);
Blink Reformat4c46d092018-04-07 15:32:37 +0000377
Paul Lewis4ae5f4f2020-01-23 10:19:33 +0000378 const resourceTreeModel = self.SDK.targetManager.mainTarget().model(SDK.ResourceTreeModel);
Patrick Hulcea087f622018-05-18 00:37:53 +0000379 // reload to reset the page state
380 const inspectedURL = await this._controller.getInspectedURL();
381 await resourceTreeModel.navigate(inspectedURL);
Blink Reformat4c46d092018-04-07 15:32:37 +0000382 }
Paul Lewiscf2ef222019-11-22 14:55:35 +0000383}