chrome-devtools-frontend 1.0.1596535 → 1.0.1597624

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 (101) hide show
  1. package/agents/prompts/ui-widgets.md +7 -8
  2. package/docs/ui_engineering.md +10 -11
  3. package/front_end/core/host/AidaClient.ts +4 -0
  4. package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -0
  5. package/front_end/core/host/UserMetrics.ts +12 -0
  6. package/front_end/core/root/Runtime.ts +5 -0
  7. package/front_end/core/sdk/CPUThrottlingManager.ts +14 -13
  8. package/front_end/core/sdk/CSSMatchedStyles.ts +2 -0
  9. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +28 -0
  10. package/front_end/core/sdk/PageResourceLoader.ts +22 -1
  11. package/front_end/devtools_compatibility.js +2 -1
  12. package/front_end/models/ai_assistance/AiConversation.ts +29 -8
  13. package/front_end/models/ai_assistance/ChangeManager.ts +16 -0
  14. package/front_end/models/ai_assistance/ExtensionScope.ts +11 -3
  15. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +127 -0
  16. package/front_end/models/ai_assistance/agents/AiAgent.ts +26 -3
  17. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +1 -1
  18. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +11 -8
  19. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +24 -0
  20. package/front_end/models/ai_assistance/agents/StylingAgent.ts +323 -16
  21. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  22. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +27 -0
  23. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +21 -0
  24. package/front_end/models/greendev/Prototypes.ts +7 -1
  25. package/front_end/models/trace/Processor.ts +1 -0
  26. package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +33 -0
  27. package/front_end/models/trace/insights/CharacterSet.ts +172 -0
  28. package/front_end/models/trace/insights/Models.ts +1 -0
  29. package/front_end/models/trace/insights/types.ts +1 -0
  30. package/front_end/models/trace/types/TraceEvents.ts +17 -0
  31. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +51 -36
  32. package/front_end/panels/ai_assistance/PatchWidget.ts +6 -6
  33. package/front_end/panels/ai_assistance/components/ChatMessage.ts +93 -74
  34. package/front_end/panels/ai_assistance/components/ChatView.ts +6 -11
  35. package/front_end/panels/ai_assistance/components/MarkdownRendererWithCodeBlock.ts +18 -9
  36. package/front_end/panels/ai_assistance/components/StylingAgentMarkdownRenderer.ts +200 -0
  37. package/front_end/panels/ai_assistance/components/chatMessage.css +11 -8
  38. package/front_end/panels/application/AppManifestView.ts +3 -4
  39. package/front_end/panels/application/DeviceBoundSessionsView.ts +18 -22
  40. package/front_end/panels/application/FrameDetailsView.ts +9 -15
  41. package/front_end/panels/application/OriginTrialTreeView.ts +2 -3
  42. package/front_end/panels/application/ReportingApiView.ts +13 -17
  43. package/front_end/panels/application/ServiceWorkerCacheViews.ts +1 -1
  44. package/front_end/panels/application/components/BackForwardCacheView.ts +3 -3
  45. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -3
  46. package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +3 -2
  47. package/front_end/panels/changes/ChangesView.ts +6 -4
  48. package/front_end/panels/common/ExtensionServer.ts +15 -0
  49. package/front_end/panels/console/ConsolePinPane.ts +3 -3
  50. package/front_end/panels/coverage/CoverageListView.ts +1 -1
  51. package/front_end/panels/css_overview/CSSOverviewPanel.ts +11 -15
  52. package/front_end/panels/developer_resources/DeveloperResourcesView.ts +3 -5
  53. package/front_end/panels/elements/ElementsTreeElement.ts +55 -47
  54. package/front_end/panels/elements/ElementsTreeOutline.ts +149 -28
  55. package/front_end/panels/elements/EventListenersWidget.ts +3 -2
  56. package/front_end/panels/elements/StandaloneStylesContainer.ts +21 -6
  57. package/front_end/panels/elements/StylePropertyTreeElement.ts +49 -4
  58. package/front_end/panels/layer_viewer/Layers3DView.ts +5 -4
  59. package/front_end/panels/lighthouse/LighthousePanel.ts +8 -0
  60. package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +5 -6
  61. package/front_end/panels/linear_memory_inspector/components/LinearMemoryValueInterpreter.ts +6 -11
  62. package/front_end/panels/network/RequestCookiesView.ts +3 -4
  63. package/front_end/panels/network/RequestInitiatorView.ts +7 -5
  64. package/front_end/panels/network/RequestResponseView.ts +10 -15
  65. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +3 -4
  66. package/front_end/panels/recorder/components/RecordingView.ts +31 -36
  67. package/front_end/panels/recorder/components/StepEditor.ts +6 -7
  68. package/front_end/panels/search/SearchView.ts +2 -3
  69. package/front_end/panels/settings/SettingsScreen.ts +3 -2
  70. package/front_end/panels/settings/WorkspaceSettingsTab.ts +2 -5
  71. package/front_end/panels/timeline/components/LiveMetricsView.ts +5 -8
  72. package/front_end/panels/timeline/components/insights/Cache.ts +8 -10
  73. package/front_end/panels/timeline/components/insights/CharacterSet.ts +38 -0
  74. package/front_end/panels/timeline/components/insights/DOMSize.ts +16 -20
  75. package/front_end/panels/timeline/components/insights/DocumentLatency.ts +2 -6
  76. package/front_end/panels/timeline/components/insights/DuplicatedJavaScript.ts +3 -4
  77. package/front_end/panels/timeline/components/insights/FontDisplay.ts +3 -4
  78. package/front_end/panels/timeline/components/insights/ForcedReflow.ts +5 -7
  79. package/front_end/panels/timeline/components/insights/INPBreakdown.ts +3 -4
  80. package/front_end/panels/timeline/components/insights/ImageDelivery.ts +3 -4
  81. package/front_end/panels/timeline/components/insights/ImageRef.ts +2 -4
  82. package/front_end/panels/timeline/components/insights/InsightRenderer.ts +2 -0
  83. package/front_end/panels/timeline/components/insights/LCPBreakdown.ts +5 -7
  84. package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +2 -4
  85. package/front_end/panels/timeline/components/insights/LegacyJavaScript.ts +3 -4
  86. package/front_end/panels/timeline/components/insights/ModernHTTP.ts +3 -4
  87. package/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts +7 -11
  88. package/front_end/panels/timeline/components/insights/NodeLink.ts +2 -4
  89. package/front_end/panels/timeline/components/insights/RenderBlocking.ts +3 -4
  90. package/front_end/panels/timeline/components/insights/SlowCSSSelector.ts +7 -10
  91. package/front_end/panels/timeline/components/insights/ThirdParties.ts +5 -7
  92. package/front_end/panels/timeline/components/insights/insights.ts +2 -0
  93. package/front_end/panels/web_audio/WebAudioView.ts +3 -4
  94. package/front_end/ui/components/settings/SettingCheckbox.ts +2 -0
  95. package/front_end/ui/legacy/UIUtils.ts +5 -5
  96. package/front_end/ui/legacy/Widget.ts +33 -2
  97. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +3 -3
  98. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +8 -8
  99. package/front_end/ui/visual_logging/Debugging.ts +0 -32
  100. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  101. package/package.json +1 -1
@@ -15,7 +15,7 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
15
15
 
16
16
  import webAudioStyles from './webAudio.css.js';
17
17
  import {Events as ModelEvents, WebAudioModel} from './WebAudioModel.js';
18
- const {widgetConfig} = UI.Widget;
18
+ const {widget} = UI.Widget;
19
19
  const {bindToAction} = UI.UIUtils;
20
20
 
21
21
  const UIStrings = {
@@ -123,12 +123,11 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
123
123
  <div class="web-audio-content-container vbox flex-auto">
124
124
  ${!selectedContext ? html`
125
125
  <div class="web-audio-details-container vbox flex-auto">
126
- <devtools-widget .widgetConfig=${widgetConfig(UI.EmptyWidget.EmptyWidget,
126
+ ${widget(UI.EmptyWidget.EmptyWidget,
127
127
  {header: i18nString(UIStrings.noWebAudio),
128
128
  text: i18nString(UIStrings.openAPageThatUsesWebAudioApiTo),
129
129
  link: WEBAUDIO_EXPLANATION_URL,
130
- })}>
131
- </devtools-widget>
130
+ })}
132
131
  </div>` : html`<div class="web-audio-details-container vbox flex-auto">
133
132
  <div class="context-detail-container">
134
133
  <div class="context-detail-header">
@@ -85,6 +85,8 @@ export class SettingCheckbox extends HTMLElement {
85
85
  <devtools-button
86
86
  class="info-icon"
87
87
  aria-details=${id}
88
+ aria-disabled=true
89
+ accessibleLabel=${learnMore.tooltip()}
88
90
  .data=${data}
89
91
  ></devtools-button>
90
92
  <devtools-tooltip id=${id} variant="rich">
@@ -2094,10 +2094,7 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
2094
2094
  const patchingWrapper = <Args extends any[], R>(fn: (...args: Args) => R): ((...args: Args) => R) => {
2095
2095
  return function(this: unknown, ...args: Args): R {
2096
2096
  const result = fn.apply(this, args);
2097
- if (isLitTemplate(result)) {
2098
- HTMLElementWithLightDOMTemplate.patchLitTemplate(result);
2099
- }
2100
- return result;
2097
+ return patchValue(result) as R;
2101
2098
  };
2102
2099
  };
2103
2100
  if (template === Lit.nothing) {
@@ -2117,7 +2114,10 @@ export class HTMLElementWithLightDOMTemplate extends HTMLElement {
2117
2114
 
2118
2115
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2119
2116
  function isCallable(value: unknown): value is(...args: any[]) => any {
2120
- return typeof value === 'function';
2117
+ // Native class constructors cannot be invoked without 'new', and we shouldn't attempt to wrap them.
2118
+ // Differentiate them from regular functions by checking their 'prototype' descriptor:
2119
+ // class constructors have a non-writable prototype, whereas regular functions have a writable prototype.
2120
+ return typeof value === 'function' && Object.getOwnPropertyDescriptor(value, 'prototype')?.writable !== false;
2121
2121
  }
2122
2122
 
2123
2123
  function patchValue(value: unknown): unknown {
@@ -38,6 +38,8 @@ import * as Lit from '../../ui/lit/lit.js';
38
38
  import {appendStyle, deepActiveElement} from './DOMUtilities.js';
39
39
  import {cloneCustomElement, createShadowRootWithCoreStyles} from './UIUtils.js';
40
40
 
41
+ const {html} = Lit;
42
+
41
43
  // Remember the original DOM mutation methods here, since we
42
44
  // will override them below to sanity check the Widget system.
43
45
  const originalAppendChild = Element.prototype.appendChild;
@@ -223,7 +225,7 @@ export class WidgetElement<WidgetT extends Widget> extends HTMLElement {
223
225
  }
224
226
 
225
227
  override removeChild<T extends Node>(child: T): T {
226
- const childWidget = Widget.get(child as unknown as HTMLElement);
228
+ const childWidget = Widget.get(child);
227
229
  if (childWidget) {
228
230
  childWidget.detach();
229
231
  return child;
@@ -233,7 +235,7 @@ export class WidgetElement<WidgetT extends Widget> extends HTMLElement {
233
235
 
234
236
  override removeChildren(): void {
235
237
  for (const child of this.children) {
236
- const childWidget = Widget.get(child as unknown as HTMLElement);
238
+ const childWidget = Widget.get(child);
237
239
  if (childWidget) {
238
240
  childWidget.detach();
239
241
  }
@@ -263,6 +265,35 @@ export class WidgetElement<WidgetT extends Widget> extends HTMLElement {
263
265
 
264
266
  customElements.define('devtools-widget', WidgetElement);
265
267
 
268
+ export class WidgetDirective extends Lit.Directive.Directive {
269
+ constructor(partInfo: Lit.Directive.PartInfo) {
270
+ super(partInfo);
271
+ if (partInfo.type !== Lit.Directive.PartType.CHILD) {
272
+ throw new Error('Widget directive must be used as a child directive.');
273
+ }
274
+ }
275
+
276
+ render<F extends WidgetFactory<Widget>, ParamKeys extends keyof InferWidgetTFromFactory<F>>(
277
+ widgetClass: F,
278
+ widgetParams?: Pick<InferWidgetTFromFactory<F>, ParamKeys>&Partial<InferWidgetTFromFactory<F>>): unknown {
279
+ // We use `repeat` to force Lit to recreate the `<devtools-widget>` DOM node when the `widgetClass` changes.
280
+ // If we didn't use `repeat` and used `html` directly, Lit would reuse the same `<devtools-widget>` instance
281
+ // even if `widgetClass` changed (for example, in a ternary operator `condition ? widget(A) : widget(B)`).
282
+ // This is because the template string is the same, so Lit reuses the DOM node and only updates `.widgetConfig`,
283
+ // which does not properly recreate the widget instance.
284
+ return Lit.Directives.repeat(
285
+ [widgetClass], () => widgetClass,
286
+ () => html`<devtools-widget .widgetConfig=${
287
+ widgetConfig(widgetClass, widgetParams as never)}></devtools-widget>`);
288
+ }
289
+ }
290
+
291
+ export const widget = Lit.Directive.directive(WidgetDirective) as
292
+ <F extends WidgetFactory<Widget>, ParamKeys extends keyof InferWidgetTFromFactory<F>>(
293
+ widgetClass: F,
294
+ widgetParams?: Pick<InferWidgetTFromFactory<F>, ParamKeys>&
295
+ Partial<InferWidgetTFromFactory<F>>) => Lit.Directive.DirectiveResult<typeof WidgetDirective>;
296
+
266
297
  export function widgetRef<T extends Widget, Args extends unknown[]>(
267
298
  type: Platform.Constructor.Constructor<T, Args>, callback: (_: T) => void): ReturnType<typeof Lit.Directives.ref> {
268
299
  return Lit.Directives.ref((e?: Element) => {
@@ -613,14 +613,14 @@ export const ifExpanded = Lit.Directive.directive(class extends Lit.Directive.Di
613
613
  #partInfo: {type: Lit.Directive.PartType, startNode: Node};
614
614
  constructor(partInfo: Lit.Directive.PartInfo) {
615
615
  if (partInfo.type !== Lit.Directive.PartType.CHILD) {
616
- throw new Error('expand directive must be used in a child node');
616
+ throw new Error('ifExpanded directive must be used in a child node');
617
617
  }
618
618
  super(partInfo);
619
619
  this.#partInfo = partInfo as {type: Lit.Directive.PartType, startNode: Node};
620
620
  }
621
621
 
622
- render(content: () => Lit.TemplateResult): Lit.LitTemplate {
623
- return this.#isInExpandedRow(this.#partInfo.startNode) ? content() : Lit.nothing;
622
+ render(content: Lit.LitTemplate|Iterable<Lit.LitTemplate>): Lit.LitTemplate|Iterable<Lit.LitTemplate> {
623
+ return this.#isInExpandedRow(this.#partInfo.startNode) ? content : Lit.nothing;
624
624
  }
625
625
 
626
626
  #isInExpandedRow(element: Node|null|undefined): boolean {
@@ -50,7 +50,7 @@ import objectPropertiesSectionStyles from './objectPropertiesSection.css.js';
50
50
  import objectValueStyles from './objectValue.css.js';
51
51
  import {RemoteObjectPreviewFormatter, renderNodeTitle} from './RemoteObjectPreviewFormatter.js';
52
52
 
53
- const {widgetConfig} = UI.Widget;
53
+ const {widget} = UI.Widget;
54
54
  const {ref, repeat, ifDefined, classMap} = Directives;
55
55
  const UIStrings = {
56
56
  /**
@@ -795,16 +795,13 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
795
795
  const text = JSON.stringify(description);
796
796
  const tooLong = description.length > maxRenderableStringLength;
797
797
  return html`<span class="value object-value-string" title=${ifDefined(tooLong ? undefined : description)}>${
798
- tooLong ? html`<devtools-widget .widgetConfig=${
799
- widgetConfig(ExpandableTextPropertyValue, {text})}></devtools-widget>` :
800
- text}</span>`;
798
+ tooLong ? widget(ExpandableTextPropertyValue, {text}) : text}</span>`;
801
799
  }
802
800
  if (type === 'object' && subtype === 'trustedtype') {
803
801
  const text = `${className} '${description}'`;
804
802
  const tooLong = text.length > maxRenderableStringLength;
805
803
  return html`<span class="value object-value-trustedtype" title=${ifDefined(tooLong ? undefined : text)}>${
806
- tooLong ? html`<devtools-widget .widgetConfig=${
807
- widgetConfig(ExpandableTextPropertyValue, {text})}></devtools-widget>` :
804
+ tooLong ? widget(ExpandableTextPropertyValue, {text}) :
808
805
  html`${className} <span class=object-value-string title=${description}>${
809
806
  JSON.stringify(description)}</span>`}</span>`;
810
807
  }
@@ -822,8 +819,11 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
822
819
  >${renderNodeTitle(description)}</span>`;
823
820
  }
824
821
  if (description.length > maxRenderableStringLength) {
825
- return html`<span class="value object-value-${subtype || type}" title=${description}><devtools-widget
826
- .widgetConfig=${widgetConfig(ExpandableTextPropertyValue, {text: description})}></devtools-widget></span>`;
822
+ // clang-format off
823
+ return html`<span class="value object-value-${subtype || type}" title=${description}>
824
+ ${widget(ExpandableTextPropertyValue, {text: description})}
825
+ </span>`;
826
+ // clang-format on
827
827
  }
828
828
  const hasPreview = value.preview && showPreview;
829
829
  return html`<span class="value object-value-${subtype || type}" title=${description}>${
@@ -13,7 +13,6 @@ let veDebuggingEnabled = false;
13
13
  let debugOverlay: HTMLElement|null = null;
14
14
  let debugPopover: HTMLElement|null = null;
15
15
  const highlightedElements: HTMLElement[] = [];
16
- const nonDomDebugElements = new WeakMap<Loggable, HTMLElement>();
17
16
  let onInspect: ((query: string) => void)|undefined = undefined;
18
17
 
19
18
  function ensureDebugOverlay(): void {
@@ -96,8 +95,6 @@ export function processForDebugging(loggable: Loggable): void {
96
95
  }
97
96
  if (loggable instanceof HTMLElement) {
98
97
  processElementForDebugging(loggable, loggingState);
99
- } else {
100
- processNonDomLoggableForDebugging(loggable, loggingState);
101
98
  }
102
99
  }
103
100
 
@@ -409,35 +406,6 @@ function processImpressionsForAdHocAnalysisDebugLog(states: LoggingState[]): voi
409
406
  }
410
407
  }
411
408
 
412
- function processNonDomLoggableForDebugging(loggable: Loggable, loggingState: LoggingState): void {
413
- let debugElement = nonDomDebugElements.get(loggable);
414
- if (!debugElement) {
415
- debugElement = document.createElement('div');
416
- debugElement.classList.add('ve-debug');
417
- debugElement.style.background = 'black';
418
- debugElement.style.color = 'white';
419
- debugElement.style.zIndex = '100000';
420
- debugElement.textContent = debugString(loggingState.config);
421
- nonDomDebugElements.set(loggable, debugElement);
422
- setTimeout(() => {
423
- if (!loggingState.size?.width || !loggingState.size?.height) {
424
- debugElement?.parentElement?.removeChild(debugElement);
425
- nonDomDebugElements.delete(loggable);
426
- }
427
- }, 10000);
428
- }
429
- const parentDebugElement =
430
- parent instanceof HTMLElement ? parent : nonDomDebugElements.get(parent as Loggable) || debugPopover;
431
- assertNotNullOrUndefined(parentDebugElement);
432
- if (!parentDebugElement.classList.contains('ve-debug')) {
433
- debugElement.style.position = 'absolute';
434
- parentDebugElement.insertBefore(debugElement, parentDebugElement.firstChild);
435
- } else {
436
- debugElement.style.marginLeft = '10px';
437
- parentDebugElement.appendChild(debugElement);
438
- }
439
- }
440
-
441
409
  function elementKey(config: LoggingConfig): string {
442
410
  return `${VisualElements[config.ve]}${config.context ? `: ${config.context}` : ''}`;
443
411
  }
@@ -1808,6 +1808,7 @@ export const knownContextValues = new Set([
1808
1808
  'greendev-artifact-viewer-enabled',
1809
1809
  'greendev-breakpoint-debugger-agent-enabled',
1810
1810
  'greendev-copy-to-gemini-enabled',
1811
+ 'greendev-emulation-capabilities-enabled',
1811
1812
  'greendev-in-devtools-floaty-enabled',
1812
1813
  'greendev-inline-widgets-enabled',
1813
1814
  'greendev-prototypes',
@@ -4049,6 +4050,7 @@ export const knownContextValues = new Set([
4049
4050
  'timeline.insight-ask-ai.viewport',
4050
4051
  'timeline.insights-tab',
4051
4052
  'timeline.insights.cache',
4053
+ 'timeline.insights.character-set',
4052
4054
  'timeline.insights.cls-culprits',
4053
4055
  'timeline.insights.dismiss-field-mismatch',
4054
4056
  'timeline.insights.document-latency',
@@ -4123,6 +4125,7 @@ export const knownContextValues = new Set([
4123
4125
  'timeline.thread.worker',
4124
4126
  'timeline.timings',
4125
4127
  'timeline.toggle-insight.cache',
4128
+ 'timeline.toggle-insight.character-set',
4126
4129
  'timeline.toggle-insight.cls-culprits',
4127
4130
  'timeline.toggle-insight.document-latency',
4128
4131
  'timeline.toggle-insight.dom-size',
package/package.json CHANGED
@@ -105,5 +105,5 @@
105
105
  "flat-cache": "6.1.12"
106
106
  }
107
107
  },
108
- "version": "1.0.1596535"
108
+ "version": "1.0.1597624"
109
109
  }