chrome-devtools-frontend 1.0.1593518 → 1.0.1595090

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/docs/contributing/settings-experiments-features.md +93 -98
  2. package/front_end/core/common/README.md +126 -0
  3. package/front_end/core/host/UserMetrics.ts +1 -2
  4. package/front_end/core/protocol_client/InspectorBackend.ts +4 -0
  5. package/front_end/core/root/ExperimentNames.ts +0 -1
  6. package/front_end/core/sdk/CSSModel.ts +22 -0
  7. package/front_end/core/sdk/CSSNavigation.ts +33 -0
  8. package/front_end/core/sdk/CSSRule.ts +12 -2
  9. package/front_end/core/sdk/EmulationModel.ts +41 -1
  10. package/front_end/core/sdk/sdk-meta.ts +22 -18
  11. package/front_end/core/sdk/sdk.ts +2 -0
  12. package/front_end/design_system_tokens.css +538 -259
  13. package/front_end/entrypoints/main/MainImpl.ts +0 -6
  14. package/front_end/entrypoints/main/main-meta.ts +2 -2
  15. package/front_end/generated/InspectorBackendCommands.ts +6 -4
  16. package/front_end/generated/SupportedCSSProperties.js +12 -0
  17. package/front_end/generated/protocol-mapping.d.ts +7 -0
  18. package/front_end/generated/protocol-proxy-api.d.ts +5 -0
  19. package/front_end/generated/protocol.ts +47 -0
  20. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -0
  21. package/front_end/models/emulation/DeviceModeModel.ts +47 -0
  22. package/front_end/models/issues_manager/Issue.ts +1 -0
  23. package/front_end/models/issues_manager/IssueAggregator.ts +9 -9
  24. package/front_end/models/issues_manager/IssuesManager.ts +5 -5
  25. package/front_end/models/issues_manager/SelectivePermissionsInterventionIssue.ts +65 -0
  26. package/front_end/models/issues_manager/descriptions/selectivePermissionsIntervention.md +7 -0
  27. package/front_end/models/issues_manager/issues_manager.ts +2 -4
  28. package/front_end/models/javascript_metadata/NativeFunctions.js +48 -9
  29. package/front_end/models/lighthouse/lighthouse.ts +9 -0
  30. package/front_end/models/persistence/persistence-meta.ts +4 -4
  31. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +12 -1
  32. package/front_end/panels/ai_assistance/components/ChatInput.ts +37 -30
  33. package/front_end/panels/ai_assistance/components/ChatView.ts +4 -2
  34. package/front_end/panels/ai_assistance/components/chatInput.css +26 -1
  35. package/front_end/panels/application/StorageView.ts +8 -2
  36. package/front_end/panels/application/preloading/PreloadingView.ts +105 -7
  37. package/front_end/panels/application/preloading/preloadingView.css +4 -0
  38. package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +3 -0
  39. package/front_end/panels/common/AiCodeGenerationTeaser.ts +3 -0
  40. package/front_end/panels/console/ConsoleView.ts +2 -2
  41. package/front_end/panels/console/console-meta.ts +18 -14
  42. package/front_end/panels/elements/ComputedStyleWidget.ts +12 -7
  43. package/front_end/panels/elements/ElementsPanel.ts +1 -1
  44. package/front_end/panels/elements/ElementsTreeOutline.ts +4 -6
  45. package/front_end/panels/elements/ImagePreviewPopover.ts +6 -9
  46. package/front_end/panels/elements/StylePropertiesSection.ts +30 -0
  47. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +1 -6
  48. package/front_end/panels/elements/StylesSidebarPane.ts +92 -7
  49. package/front_end/panels/elements/elements-meta.ts +12 -8
  50. package/front_end/panels/emulation/DeviceModeToolbar.ts +206 -66
  51. package/front_end/panels/issues/AffectedSelectivePermissionsInterventionView.ts +120 -0
  52. package/front_end/panels/issues/HiddenIssuesRow.ts +1 -1
  53. package/front_end/panels/issues/IssueKindView.ts +2 -1
  54. package/front_end/panels/issues/IssueView.ts +4 -4
  55. package/front_end/panels/issues/IssuesPane.ts +8 -2
  56. package/front_end/panels/issues/issues.ts +2 -0
  57. package/front_end/panels/lighthouse/LighthouseController.ts +3 -3
  58. package/front_end/panels/lighthouse/LighthousePanel.ts +9 -5
  59. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +5 -5
  60. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +6 -7
  61. package/front_end/panels/lighthouse/LighthouseReportSelector.ts +4 -3
  62. package/front_end/panels/lighthouse/LighthouseStartView.ts +99 -38
  63. package/front_end/panels/lighthouse/LighthouseTimespanView.ts +53 -14
  64. package/front_end/panels/lighthouse/RadioSetting.ts +33 -19
  65. package/front_end/panels/lighthouse/lighthouse.ts +2 -2
  66. package/front_end/panels/media/PlayerMessagesView.ts +62 -49
  67. package/front_end/panels/media/media.ts +2 -0
  68. package/front_end/panels/media/playerMessagesView.css +1 -1
  69. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +49 -24
  70. package/front_end/panels/settings/FrameworkIgnoreListSettingsTab.ts +2 -2
  71. package/front_end/panels/sources/sources-meta.ts +8 -4
  72. package/front_end/panels/utils/utils.ts +11 -5
  73. package/front_end/third_party/chromium/README.chromium +1 -1
  74. package/front_end/third_party/lit/lib/async-directive.d.ts +465 -0
  75. package/front_end/third_party/lit/lib/async-directive.js +23 -0
  76. package/front_end/third_party/lit/lib/async-directive.js.map +1 -0
  77. package/front_end/third_party/lit/lib/decorators.d.ts +7 -1
  78. package/front_end/third_party/lit/lib/decorators.js +2 -2
  79. package/front_end/third_party/lit/lib/decorators.js.map +1 -1
  80. package/front_end/third_party/lit/lib/directive.js.map +1 -1
  81. package/front_end/third_party/lit/lib/directives.d.ts +27 -8
  82. package/front_end/third_party/lit/lib/directives.js +8 -8
  83. package/front_end/third_party/lit/lib/directives.js.map +1 -1
  84. package/front_end/third_party/lit/lib/lit.d.ts +15 -5
  85. package/front_end/third_party/lit/lib/lit.js +4 -4
  86. package/front_end/third_party/lit/lib/lit.js.map +1 -1
  87. package/front_end/third_party/lit/lib/static-html.js +2 -2
  88. package/front_end/third_party/lit/lib/static-html.js.map +1 -1
  89. package/front_end/third_party/lit/lit.ts +2 -1
  90. package/front_end/third_party/lit/rollup.config.mjs +1 -1
  91. package/front_end/third_party/source-map-scopes-codec/package/deno.json +1 -1
  92. package/front_end/third_party/source-map-scopes-codec/package/package.json +1 -1
  93. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +1 -1
  94. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +1 -1
  95. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +1 -1
  96. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +1 -1
  97. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +1 -1
  98. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +2 -2
  99. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +5 -0
  100. package/front_end/ui/legacy/SuggestBox.ts +4 -0
  101. package/front_end/ui/legacy/TextPrompt.ts +1 -1
  102. package/front_end/ui/legacy/components/utils/ImagePreview.ts +27 -23
  103. package/front_end/ui/lit/lit.ts +1 -0
  104. package/front_end/ui/visual_logging/Debugging.ts +1 -1
  105. package/front_end/ui/visual_logging/KnownContextValues.ts +19 -0
  106. package/inspector_overlay/highlight_grid_common.ts +11 -8
  107. package/package.json +1 -1
  108. package/front_end/models/issues_manager/ContrastCheckTrigger.ts +0 -78
  109. package/front_end/models/issues_manager/LowTextContrastIssue.ts +0 -63
  110. package/front_end/panels/issues/AffectedElementsWithLowContrastView.ts +0 -91
  111. /package/front_end/{panels → models}/lighthouse/LighthouseReporterTypes.ts +0 -0
@@ -9,10 +9,10 @@ import type * as Platform from '../../core/platform/platform.js';
9
9
  import * as SDK from '../../core/sdk/sdk.js';
10
10
  import * as Protocol from '../../generated/protocol.js';
11
11
  import * as EmulationModel from '../../models/emulation/emulation.js';
12
+ import type * as LighthouseModel from '../../models/lighthouse/lighthouse.js';
12
13
  import * as Emulation from '../emulation/emulation.js';
13
14
 
14
15
  import type {LighthouseRun as LighthouseRunType, ProtocolService} from './LighthouseProtocolService.js';
15
- import type {RunnerResult} from './LighthouseReporterTypes.js';
16
16
 
17
17
  const UIStrings = {
18
18
  /**
@@ -236,7 +236,7 @@ class LighthouseRun {
236
236
  }
237
237
  }
238
238
 
239
- async collect(): Promise<RunnerResult> {
239
+ async collect(): Promise<LighthouseModel.ReporterTypes.RunnerResult> {
240
240
  try {
241
241
  const lighthouseResponse = await this.protocolService.collectLighthouseResults(
242
242
  {inspectedURL: this.inspectedURL, categoryIDs: this.categoryIDs, flags: this.flags});
@@ -663,7 +663,7 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
663
663
  return await this.lastAction;
664
664
  }
665
665
 
666
- async collectLighthouseResults(): Promise<RunnerResult> {
666
+ async collectLighthouseResults(): Promise<LighthouseModel.ReporterTypes.RunnerResult> {
667
667
  if (!this.currentLighthouseRun) {
668
668
  throw new Error('Lighthouse is not started');
669
669
  }
@@ -7,6 +7,7 @@ import '../../ui/legacy/legacy.js';
7
7
 
8
8
  import * as Common from '../../core/common/common.js';
9
9
  import * as i18n from '../../core/i18n/i18n.js';
10
+ import type * as LighthouseModel from '../../models/lighthouse/lighthouse.js';
10
11
  import * as UI from '../../ui/legacy/legacy.js';
11
12
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
12
13
 
@@ -19,7 +20,6 @@ import {
19
20
  } from './LighthouseController.js';
20
21
  import lighthousePanelStyles from './lighthousePanel.css.js';
21
22
  import {ProtocolService} from './LighthouseProtocolService.js';
22
- import type {ReportJSON, RunnerResultArtifacts} from './LighthouseReporterTypes.js';
23
23
  import {LighthouseReportRenderer} from './LighthouseReportRenderer.js';
24
24
  import {Item, ReportSelector} from './LighthouseReportSelector.js';
25
25
  import {StartView} from './LighthouseStartView.js';
@@ -69,7 +69,7 @@ export class LighthousePanel extends UI.Panel.Panel {
69
69
  private readonly timespanView: TimespanView;
70
70
  private warningText: Nullable<string>;
71
71
  private unauditableExplanation: Nullable<string>;
72
- private readonly cachedRenderedReports: Map<ReportJSON, HTMLElement>;
72
+ private readonly cachedRenderedReports: Map<LighthouseModel.ReporterTypes.ReportJSON, HTMLElement>;
73
73
  private readonly dropTarget: UI.DropTarget.DropTarget;
74
74
  private readonly auditResultsElement: HTMLElement;
75
75
  private clearButton!: UI.Toolbar.ToolbarButton;
@@ -296,7 +296,9 @@ export class LighthousePanel extends UI.Panel.Panel {
296
296
  this.statusView.toggleCancelButton(true);
297
297
  }
298
298
 
299
- private renderReport(lighthouseResult: ReportJSON, artifacts?: RunnerResultArtifacts): void {
299
+ private renderReport(
300
+ lighthouseResult: LighthouseModel.ReporterTypes.ReportJSON,
301
+ artifacts?: LighthouseModel.ReporterTypes.RunnerResultArtifacts): void {
300
302
  this.toggleSettingsDisplay(false);
301
303
  this.contentElement.classList.toggle('in-progress', false);
302
304
  this.startView.hideWidget();
@@ -319,7 +321,9 @@ export class LighthousePanel extends UI.Panel.Panel {
319
321
  this.cachedRenderedReports.set(lighthouseResult, reportContainer);
320
322
  }
321
323
 
322
- private buildReportUI(lighthouseResult: ReportJSON, artifacts?: RunnerResultArtifacts): void {
324
+ private buildReportUI(
325
+ lighthouseResult: LighthouseModel.ReporterTypes.ReportJSON,
326
+ artifacts?: LighthouseModel.ReporterTypes.RunnerResultArtifacts): void {
323
327
  if (lighthouseResult === null) {
324
328
  return;
325
329
  }
@@ -355,7 +359,7 @@ export class LighthousePanel extends UI.Panel.Panel {
355
359
  if (!data['lighthouseVersion']) {
356
360
  return;
357
361
  }
358
- this.buildReportUI(data as ReportJSON);
362
+ this.buildReportUI(data as LighthouseModel.ReporterTypes.ReportJSON);
359
363
  }
360
364
 
361
365
  override elementsToRestoreScrollPositionsFor(): Element[] {
@@ -7,8 +7,7 @@ import type * as Platform from '../../core/platform/platform.js';
7
7
  import type * as ProtocolClient from '../../core/protocol_client/protocol_client.js';
8
8
  import * as SDK from '../../core/sdk/sdk.js';
9
9
  import type * as Protocol from '../../generated/protocol.js';
10
-
11
- import type * as ReportRenderer from './LighthouseReporterTypes.js';
10
+ import type * as LighthouseModel from '../../models/lighthouse/lighthouse.js';
12
11
 
13
12
  /**
14
13
  * @file
@@ -149,7 +148,8 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
149
148
  });
150
149
  }
151
150
 
152
- async collectLighthouseResults(currentLighthouseRun: LighthouseRun): Promise<ReportRenderer.RunnerResult> {
151
+ async collectLighthouseResults(currentLighthouseRun: LighthouseRun):
152
+ Promise<LighthouseModel.ReporterTypes.RunnerResult> {
153
153
  const {inspectedURL, categoryIDs, flags} = currentLighthouseRun;
154
154
 
155
155
  if (!this.mainSessionId || !this.rootTargetId) {
@@ -289,10 +289,10 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
289
289
 
290
290
  /** sendWithResponse currently only handles the original startLighthouse request and LHR-filled response. */
291
291
  private async sendWithResponse(action: string, args: Record<string, string|string[]|object|undefined> = {}):
292
- Promise<ReportRenderer.RunnerResult> {
292
+ Promise<LighthouseModel.ReporterTypes.RunnerResult> {
293
293
  const worker = await this.ensureWorkerExists();
294
294
  const messageId = lastId++;
295
- const messageResult = new Promise<ReportRenderer.RunnerResult>(resolve => {
295
+ const messageResult = new Promise<LighthouseModel.ReporterTypes.RunnerResult>(resolve => {
296
296
  const workerListener = (event: MessageEvent): void => {
297
297
  const lighthouseMessage = event.data;
298
298
 
@@ -6,6 +6,7 @@ import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
7
  import * as Platform from '../../core/platform/platform.js';
8
8
  import * as SDK from '../../core/sdk/sdk.js';
9
+ import type * as LighthouseModel from '../../models/lighthouse/lighthouse.js';
9
10
  import * as TextUtils from '../../models/text_utils/text_utils.js';
10
11
  import * as Workspace from '../../models/workspace/workspace.js';
11
12
  import * as LighthouseReport from '../../third_party/lighthouse/report/report.js';
@@ -15,9 +16,6 @@ import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
15
16
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
16
17
  import * as PanelsCommon from '../common/common.js';
17
18
 
18
- import type {
19
- NodeDetailsJSON, ReportJSON, RunnerResultArtifacts, SourceLocationDetailsJSON} from './LighthouseReporterTypes.js';
20
-
21
19
  const MaxLengthForLinks = 40;
22
20
 
23
21
  interface RenderReportOpts {
@@ -26,8 +24,9 @@ interface RenderReportOpts {
26
24
  }
27
25
 
28
26
  export class LighthouseReportRenderer {
29
- static renderLighthouseReport(lhr: ReportJSON, artifacts?: RunnerResultArtifacts, opts?: RenderReportOpts):
30
- HTMLElement {
27
+ static renderLighthouseReport(
28
+ lhr: LighthouseModel.ReporterTypes.ReportJSON, artifacts?: LighthouseModel.ReporterTypes.RunnerResultArtifacts,
29
+ opts?: RenderReportOpts): HTMLElement {
31
30
  let onViewTrace: (() => Promise<void>)|undefined = undefined;
32
31
  if (artifacts) {
33
32
  onViewTrace = async () => {
@@ -134,7 +133,7 @@ export class LighthouseReportRenderer {
134
133
 
135
134
  for (const origElement of el.getElementsByClassName('lh-node')) {
136
135
  const origHTMLElement = origElement as HTMLElement;
137
- const detailsItem = origHTMLElement.dataset as unknown as NodeDetailsJSON;
136
+ const detailsItem = origHTMLElement.dataset as unknown as LighthouseModel.ReporterTypes.NodeDetailsJSON;
138
137
  if (!detailsItem.path) {
139
138
  continue;
140
139
  }
@@ -165,7 +164,7 @@ export class LighthouseReportRenderer {
165
164
  static async linkifySourceLocationDetails(el: Element): Promise<void> {
166
165
  for (const origElement of el.getElementsByClassName('lh-source-location')) {
167
166
  const origHTMLElement = origElement as HTMLElement;
168
- const detailsItem = origHTMLElement.dataset as SourceLocationDetailsJSON;
167
+ const detailsItem = origHTMLElement.dataset as LighthouseModel.ReporterTypes.SourceLocationDetailsJSON;
169
168
  if (!detailsItem.sourceUrl || !detailsItem.sourceLine || !detailsItem.sourceColumn) {
170
169
  continue;
171
170
  }
@@ -5,10 +5,9 @@
5
5
 
6
6
  import * as Common from '../../core/common/common.js';
7
7
  import * as i18n from '../../core/i18n/i18n.js';
8
+ import type * as LighthouseModel from '../../models/lighthouse/lighthouse.js';
8
9
  import * as UI from '../../ui/legacy/legacy.js';
9
10
 
10
- import type * as ReportRenderer from './LighthouseReporterTypes.js';
11
-
12
11
  const UIStrings = {
13
12
  /**
14
13
  * @description Title of combo box in audits report selector
@@ -102,7 +101,9 @@ export class Item {
102
101
  private readonly showLandingCallback: () => void;
103
102
  private readonly element: HTMLOptionElement;
104
103
 
105
- constructor(lighthouseResult: ReportRenderer.ReportJSON, renderReport: () => void, showLandingCallback: () => void) {
104
+ constructor(
105
+ lighthouseResult: LighthouseModel.ReporterTypes.ReportJSON, renderReport: () => void,
106
+ showLandingCallback: () => void) {
106
107
  this.renderReport = renderReport;
107
108
  this.showLandingCallback = showLandingCallback;
108
109
 
@@ -11,6 +11,7 @@ import type * as Platform from '../../core/platform/platform.js';
11
11
  import * as Buttons from '../../ui/components/buttons/buttons.js';
12
12
  import {Link} from '../../ui/kit/kit.js';
13
13
  import * as UI from '../../ui/legacy/legacy.js';
14
+ import {Directives, html, render} from '../../ui/lit/lit.js';
14
15
 
15
16
  import {type LighthouseController, type Preset, Presets, RuntimeSettings} from './LighthouseController.js';
16
17
  import type {LighthousePanel} from './LighthousePanel.js';
@@ -55,6 +56,78 @@ const UIStrings = {
55
56
  const str_ = i18n.i18n.registerUIStrings('panels/lighthouse/LighthouseStartView.ts', UIStrings);
56
57
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
57
58
 
59
+ const renderStartView = (
60
+ _input: Record<string, never>,
61
+ output: {
62
+ helpText?: HTMLElement,
63
+ warningText?: HTMLElement,
64
+ modeFormElements?: HTMLElement,
65
+ deviceTypeFormElements?: HTMLElement,
66
+ categoriesFormElements?: HTMLElement,
67
+ },
68
+ target: HTMLElement,
69
+ ): void => {
70
+ // clang-format off
71
+ render(
72
+ html`
73
+ <form class="lighthouse-start-view">
74
+ <header class="hbox">
75
+ <div class="lighthouse-logo"></div>
76
+ <div class="lighthouse-title">
77
+ ${i18nString(UIStrings.generateLighthouseReport)}
78
+ </div>
79
+ <div class="lighthouse-start-button-container"></div>
80
+ </header>
81
+ <div
82
+ ${Directives.ref(e => {
83
+ output.helpText = e as HTMLElement;
84
+ })}
85
+ class="lighthouse-help-text hidden"
86
+ ></div>
87
+ <div class="lighthouse-options hbox">
88
+ <div class="lighthouse-form-section">
89
+ <div
90
+ class="lighthouse-form-elements"
91
+ ${Directives.ref(e => {
92
+ output.modeFormElements = e as HTMLElement;
93
+ })}
94
+ ></div>
95
+ </div>
96
+ <div class="lighthouse-form-section">
97
+ <div
98
+ class="lighthouse-form-elements"
99
+ ${Directives.ref(e => {
100
+ output.deviceTypeFormElements = e as HTMLElement;
101
+ })}
102
+ ></div>
103
+ </div>
104
+ <div class="lighthouse-form-categories">
105
+ <fieldset class="lighthouse-form-section lighthouse-form-categories-fieldset">
106
+ <legend class="lighthouse-form-section-label">
107
+ ${i18nString(UIStrings.categories)}
108
+ </legend>
109
+ <div
110
+ class="lighthouse-form-elements"
111
+ ${Directives.ref(e => {
112
+ output.categoriesFormElements = e as HTMLElement;
113
+ })}
114
+ ></div>
115
+ </fieldset>
116
+ </div>
117
+ </div>
118
+ <div
119
+ ${Directives.ref(e => {
120
+ output.warningText = e as HTMLElement;
121
+ })}
122
+ class="lighthouse-warning-text hidden"
123
+ ></div>
124
+ </form>
125
+ `,
126
+ target,
127
+ );
128
+ // clang-format on
129
+ };
130
+
58
131
  export class StartView extends UI.Widget.Widget {
59
132
  private controller: LighthouseController;
60
133
  private panel: LighthousePanel;
@@ -145,13 +218,11 @@ export class StartView extends UI.Widget.Widget {
145
218
  }
146
219
  }
147
220
 
148
- private populateFormControls(fragment: UI.Fragment.Fragment, mode?: string): void {
221
+ private populateFormControls(deviceTypeFormElements: Element, categoryFormElements: Element, mode?: string): void {
149
222
  // Populate the device type
150
- const deviceTypeFormElements = fragment.$('device-type-form-elements');
151
223
  this.populateRuntimeSettingAsRadio('lighthouse.device-type', i18nString(UIStrings.device), deviceTypeFormElements);
152
224
 
153
225
  // Populate the categories
154
- const categoryFormElements = fragment.$('categories-form-elements') as HTMLElement;
155
226
 
156
227
  this.checkboxes = [];
157
228
  for (const preset of Presets) {
@@ -174,44 +245,34 @@ export class StartView extends UI.Widget.Widget {
174
245
  this.populateRuntimeSettingAsToolbarDropdown('lighthouse.throttling', this.#settingsToolbar);
175
246
 
176
247
  const {mode} = this.controller.getFlags();
177
- this.populateStartButton(mode);
178
248
 
179
- const fragment = UI.Fragment.Fragment.build`
180
- <form class="lighthouse-start-view">
181
- <header class="hbox">
182
- <div class="lighthouse-logo"></div>
183
- <h1 class="lighthouse-title">${i18nString(UIStrings.generateLighthouseReport)}</h1>
184
- <div class="lighthouse-start-button-container" $="start-button-container">${this.startButton}</div>
185
- </header>
186
- <div $="help-text" class="lighthouse-help-text hidden"></div>
187
- <div class="lighthouse-options hbox">
188
- <div class="lighthouse-form-section">
189
- <div class="lighthouse-form-elements" $="mode-form-elements"></div>
190
- </div>
191
- <div class="lighthouse-form-section">
192
- <div class="lighthouse-form-elements" $="device-type-form-elements"></div>
193
- </div>
194
- <div class="lighthouse-form-categories">
195
- <fieldset class="lighthouse-form-section lighthouse-form-categories-fieldset">
196
- <legend class="lighthouse-form-section-label">${i18nString(UIStrings.categories)}</legend>
197
- <div class="lighthouse-form-elements" $="categories-form-elements"></div>
198
- </fieldset>
199
- </div>
200
- </div>
201
- <div $="warning-text" class="lighthouse-warning-text hidden"></div>
202
- </form>
203
- `;
204
-
205
- this.helpText = fragment.$('help-text');
206
- this.warningText = fragment.$('warning-text');
207
-
208
- const modeFormElements = fragment.$('mode-form-elements');
209
- this.populateRuntimeSettingAsRadio('lighthouse.mode', i18nString(UIStrings.mode), modeFormElements);
249
+ const output = {
250
+ helpText: undefined as HTMLElement | undefined,
251
+ warningText: undefined as HTMLElement | undefined,
252
+ modeFormElements: undefined as HTMLElement | undefined,
253
+ deviceTypeFormElements: undefined as HTMLElement | undefined,
254
+ categoriesFormElements: undefined as HTMLElement | undefined,
255
+ };
256
+
257
+ renderStartView(
258
+ {},
259
+ output,
260
+ this.contentElement,
261
+ );
210
262
 
211
- this.populateFormControls(fragment, mode);
263
+ this.helpText = output.helpText;
264
+ this.warningText = output.warningText;
212
265
 
213
- this.contentElement.textContent = '';
214
- this.contentElement.append(fragment.element());
266
+ const modeFormElements = output.modeFormElements;
267
+ const deviceTypeFormElements = output.deviceTypeFormElements;
268
+ const categoriesFormElements = output.categoriesFormElements;
269
+
270
+ if (!modeFormElements || !deviceTypeFormElements || !categoriesFormElements) {
271
+ throw new Error('Required elements not found in template');
272
+ }
273
+
274
+ this.populateRuntimeSettingAsRadio('lighthouse.mode', i18nString(UIStrings.mode), modeFormElements);
275
+ this.populateFormControls(deviceTypeFormElements, categoriesFormElements, mode);
215
276
 
216
277
  this.refresh();
217
278
  }
@@ -7,6 +7,7 @@ import * as i18n from '../../core/i18n/i18n.js';
7
7
  import * as Geometry from '../../models/geometry/geometry.js';
8
8
  import * as Buttons from '../../ui/components/buttons/buttons.js';
9
9
  import * as UI from '../../ui/legacy/legacy.js';
10
+ import {Directives, html, render} from '../../ui/lit/lit.js';
10
11
 
11
12
  import lighthouseDialogStyles from './lighthouseDialog.css.js';
12
13
  import type {LighthousePanel} from './LighthousePanel.js';
@@ -37,6 +38,43 @@ const UIStrings = {
37
38
  const str_ = i18n.i18n.registerUIStrings('panels/lighthouse/LighthouseTimespanView.ts', UIStrings);
38
39
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
39
40
 
41
+ const renderTimespanView = (
42
+ input: {
43
+ cancelButton: Element,
44
+ endButton: Element,
45
+ },
46
+ output: {
47
+ statusHeader?: HTMLElement,
48
+ contentContainer?: HTMLElement,
49
+ },
50
+ target: ShadowRoot,
51
+ ): void => {
52
+ // clang-format off
53
+ render(
54
+ html`
55
+ <div class="lighthouse-view vbox">
56
+ <span
57
+ ${Directives.ref(e => {
58
+ output.statusHeader = e as HTMLElement;
59
+ })}
60
+ class="header"
61
+ ></span>
62
+ <span
63
+ ${Directives.ref(e => {
64
+ output.contentContainer = e as HTMLElement;
65
+ })}
66
+ class="lighthouse-dialog-text"
67
+ ></span>
68
+ <div class="lighthouse-action-buttons hbox">
69
+ ${input.cancelButton} ${input.endButton}
70
+ </div>
71
+ </div>
72
+ `,
73
+ target,
74
+ );
75
+ // clang-format on
76
+ };
77
+
40
78
  export class TimespanView extends UI.Dialog.Dialog {
41
79
  private panel: LighthousePanel;
42
80
  private statusHeader: Element|null;
@@ -90,20 +128,21 @@ export class TimespanView extends UI.Dialog.Dialog {
90
128
  className: 'cancel',
91
129
  jslogContext: 'lighthouse.cancel',
92
130
  });
93
- const fragment = UI.Fragment.Fragment.build`
94
- <div class="lighthouse-view vbox">
95
- <span $="status-header" class="header"></span>
96
- <span $="call-to-action" class="lighthouse-dialog-text"></span>
97
- <div class="lighthouse-action-buttons hbox">
98
- ${cancelButton}
99
- ${this.endButton}
100
- </div>
101
- </div>
102
- `;
103
-
104
- this.statusHeader = fragment.$('status-header');
105
- this.contentContainer = fragment.$('call-to-action');
106
- dialogRoot.appendChild(fragment.element());
131
+
132
+ const output = {
133
+ statusHeader: undefined as HTMLElement | undefined,
134
+ contentContainer: undefined as HTMLElement | undefined,
135
+ };
136
+
137
+ renderTimespanView(
138
+ {
139
+ cancelButton,
140
+ endButton: this.endButton,
141
+ },
142
+ output, dialogRoot);
143
+
144
+ this.statusHeader = output.statusHeader ?? null;
145
+ this.contentContainer = output.contentContainer ?? null;
107
146
 
108
147
  this.setSizeBehavior(UI.GlassPane.SizeBehavior.SET_EXACT_WIDTH_MAX_HEIGHT);
109
148
  this.setMaxContentSize(new Geometry.Size(500, 400));
@@ -2,10 +2,13 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-imperative-dom-api */
5
+ /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
6
 
6
7
  import type * as Common from '../../core/common/common.js';
7
8
  import * as UI from '../../ui/legacy/legacy.js';
9
+ import {Directives, html, render} from '../../ui/lit/lit.js';
8
10
 
11
+ const {ifDefined} = Directives;
9
12
  interface RadioOption {
10
13
  value: string;
11
14
  label: () => Common.UIString.LocalizedString;
@@ -28,25 +31,36 @@ export class RadioSetting {
28
31
  UI.ARIAUtils.markAsRadioGroup(this.element);
29
32
 
30
33
  this.radioElements = [];
31
- for (const option of this.options) {
32
- const fragment = UI.Fragment.Fragment.build`
33
- <label $="label" class="lighthouse-radio">
34
- <input $="input" type="radio" value=${option.value} name=${setting.name}>
35
- <span $="span" class="lighthouse-radio-text">${option.label()}</span>
36
- </label>
37
- `;
38
-
39
- this.element.appendChild(fragment.element());
40
-
41
- const tooltip = option.tooltip?.() || description;
42
- if (description) {
43
- UI.Tooltip.Tooltip.install(fragment.$('input') as HTMLElement, tooltip);
44
- UI.Tooltip.Tooltip.install(fragment.$('span') as HTMLElement, tooltip);
45
- }
46
- const radioElement = fragment.$('input') as HTMLInputElement;
47
- radioElement.addEventListener('change', this.valueChanged.bind(this));
48
- this.radioElements.push(radioElement);
49
- }
34
+ // clang-format off
35
+ render(
36
+ html`
37
+ ${this.options.map(option => {
38
+ const tooltip = option.tooltip?.() || description;
39
+ return html`
40
+ <label class="lighthouse-radio">
41
+ <input
42
+ type="radio"
43
+ value=${option.value}
44
+ name=${setting.name}
45
+ @change=${this.valueChanged.bind(this)}
46
+ title=${ifDefined(description ? tooltip : undefined)}
47
+ ${Directives.ref(el => {
48
+ this.radioElements.push(el as HTMLInputElement);
49
+ }
50
+ )}
51
+ />
52
+ <span
53
+ class="lighthouse-radio-text"
54
+ title=${ifDefined(description ? tooltip : undefined)}
55
+ >${option.label()}</span
56
+ >
57
+ </label>
58
+ `;
59
+ })}
60
+ `,
61
+ this.element,
62
+ );
63
+ // clang-format on
50
64
 
51
65
  this.ignoreChangeEvents = false;
52
66
  this.selectedIndex = -1;
@@ -7,21 +7,21 @@ import '../../third_party/lighthouse/report-assets/report-generator.mjs';
7
7
  import * as LighthouseController from './LighthouseController.js';
8
8
  import * as LighthousePanel from './LighthousePanel.js';
9
9
  import * as LighthouseProtocolService from './LighthouseProtocolService.js';
10
- import * as LighthouseReporterTypes from './LighthouseReporterTypes.js';
11
10
  import * as LighthouseReportRenderer from './LighthouseReportRenderer.js';
12
11
  import * as LighthouseReportSelector from './LighthouseReportSelector.js';
13
12
  import * as LighthouseStartView from './LighthouseStartView.js';
14
13
  import * as LighthouseStatusView from './LighthouseStatusView.js';
14
+ import * as LighthouseTimespanView from './LighthouseTimespanView.js';
15
15
  import * as RadioSetting from './RadioSetting.js';
16
16
 
17
17
  export {
18
18
  LighthouseController,
19
19
  LighthousePanel,
20
20
  LighthouseProtocolService,
21
- LighthouseReporterTypes,
22
21
  LighthouseReportRenderer,
23
22
  LighthouseReportSelector,
24
23
  LighthouseStartView,
25
24
  LighthouseStatusView,
25
+ LighthouseTimespanView,
26
26
  RadioSetting,
27
27
  };