chrome-devtools-frontend 1.0.1533544 → 1.0.1534251

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 (68) hide show
  1. package/front_end/Images/src/justify-content-stretch.svg +4 -0
  2. package/front_end/core/host/InspectorFrontendHost.ts +6 -2
  3. package/front_end/core/host/InspectorFrontendHostAPI.ts +32 -29
  4. package/front_end/core/host/UserMetrics.ts +2 -1
  5. package/front_end/core/protocol_client/CDPConnection.ts +39 -0
  6. package/front_end/core/protocol_client/InspectorBackend.ts +0 -9
  7. package/front_end/core/sdk/CSSMatchedStyles.ts +2 -2
  8. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +18 -8
  9. package/front_end/core/sdk/NetworkManager.ts +0 -16
  10. package/front_end/devtools_compatibility.js +9 -4
  11. package/front_end/generated/protocol-mapping.d.ts +3 -0
  12. package/front_end/models/ai_assistance/BuiltInAi.ts +0 -17
  13. package/front_end/panels/console/ConsoleInsightTeaser.ts +74 -60
  14. package/front_end/panels/console/ConsoleViewMessage.ts +4 -2
  15. package/front_end/panels/console/consoleInsightTeaser.css +4 -0
  16. package/front_end/panels/console/consoleView.css +1 -1
  17. package/front_end/panels/elements/StylePropertyTreeElement.ts +46 -8
  18. package/front_end/panels/elements/components/CSSPropertyIconResolver.ts +1 -0
  19. package/front_end/panels/elements/components/StylePropertyEditor.ts +65 -0
  20. package/front_end/third_party/chromium/README.chromium +1 -1
  21. package/front_end/third_party/puppeteer/README.chromium +2 -2
  22. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.js +1 -1
  23. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.js.map +1 -1
  24. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.js +4 -4
  25. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.js.map +1 -1
  26. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts +2 -2
  27. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts +4 -0
  28. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  29. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js +1 -0
  30. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js.map +1 -1
  31. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +1 -1
  32. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  33. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  34. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
  35. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
  36. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  37. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  38. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  39. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  40. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +4 -0
  41. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +10 -10
  42. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.js +1 -1
  43. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.js.map +1 -1
  44. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.js +4 -4
  45. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.js.map +1 -1
  46. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts +4 -0
  47. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  48. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js +1 -0
  49. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js.map +1 -1
  50. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +1 -1
  51. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  52. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
  53. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
  54. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  55. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  56. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  57. package/front_end/third_party/puppeteer/package/lib/types.d.ts +4 -0
  58. package/front_end/third_party/puppeteer/package/package.json +1 -1
  59. package/front_end/third_party/puppeteer/package/src/api/ElementHandle.ts +1 -1
  60. package/front_end/third_party/puppeteer/package/src/api/Frame.ts +4 -4
  61. package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +8 -1
  62. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +1 -1
  63. package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
  64. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  65. package/front_end/ui/components/docs/style_property_editor/masonry.html +21 -0
  66. package/front_end/ui/components/docs/style_property_editor/masonry.ts +50 -0
  67. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  68. package/package.json +1 -1
@@ -0,0 +1,4 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M3.5 18V14H9V6H3.5V2H2V18H3.5Z" fill="black"/>
3
+ <path d="M18 18V2H16.5V6H11V14H16.5V18H18Z" fill="black"/>
4
+ </svg>
@@ -569,7 +569,7 @@ class InspectorFrontendAPIImpl {
569
569
  constructor() {
570
570
  for (const descriptor of EventDescriptors) {
571
571
  // @ts-expect-error Dispatcher magic
572
- this[descriptor[1]] = this.dispatch.bind(this, descriptor[0], descriptor[2], descriptor[3]);
572
+ this[descriptor[0]] = this.dispatch.bind(this, descriptor[0], descriptor[1], descriptor[2]);
573
573
  }
574
574
  }
575
575
 
@@ -600,9 +600,13 @@ class InspectorFrontendAPIImpl {
600
600
  resourceLoaderStreamWrite(id, chunk);
601
601
  }
602
602
  }
603
+ /**
604
+ * Used in `front_end/devtools_compatibility.js` to verify that calls from there
605
+ * are valid.
606
+ */
607
+ export type InspectorFrontendAPIImplMethods = keyof InspectorFrontendAPIImpl;
603
608
 
604
609
  (function(): void {
605
-
606
610
  function initializeInspectorFrontendHost(): void {
607
611
  if (!InspectorFrontendHostInstance) {
608
612
  // Instantiate stub for web-hosted mode if necessary.
@@ -6,6 +6,9 @@ import type * as Platform from '../../core/platform/platform.js';
6
6
  import type * as Common from '../common/common.js';
7
7
  import type * as Root from '../root/root.js';
8
8
 
9
+ /**
10
+ * This values should match the one getting called from Chromium
11
+ */
9
12
  export enum Events {
10
13
  /* eslint-disable @typescript-eslint/naming-convention -- Accessed from web_tests */
11
14
  AppendedToURL = 'appendedToURL',
@@ -24,7 +27,7 @@ export enum Events {
24
27
  FileSystemsLoaded = 'fileSystemsLoaded',
25
28
  FileSystemRemoved = 'fileSystemRemoved',
26
29
  FileSystemAdded = 'fileSystemAdded',
27
- FileSystemFilesChangedAddedRemoved = 'FileSystemFilesChangedAddedRemoved',
30
+ FileSystemFilesChangedAddedRemoved = 'fileSystemFilesChangedAddedRemoved',
28
31
  IndexingTotalWorkCalculated = 'indexingTotalWorkCalculated',
29
32
  IndexingWorked = 'indexingWorked',
30
33
  IndexingDone = 'indexingDone',
@@ -40,34 +43,34 @@ export enum Events {
40
43
  }
41
44
 
42
45
  export const EventDescriptors = [
43
- [Events.AppendedToURL, 'appendedToURL', ['url']],
44
- [Events.CanceledSaveURL, 'canceledSaveURL', ['url']],
45
- [Events.ColorThemeChanged, 'colorThemeChanged', []],
46
- [Events.ContextMenuCleared, 'contextMenuCleared', []],
47
- [Events.ContextMenuItemSelected, 'contextMenuItemSelected', ['id']],
48
- [Events.DeviceCountUpdated, 'deviceCountUpdated', ['count']],
49
- [Events.DevicesDiscoveryConfigChanged, 'devicesDiscoveryConfigChanged', ['config']],
50
- [Events.DevicesPortForwardingStatusChanged, 'devicesPortForwardingStatusChanged', ['status']],
51
- [Events.DevicesUpdated, 'devicesUpdated', ['devices']],
52
- [Events.DispatchMessage, 'dispatchMessage', ['messageObject']],
53
- [Events.DispatchMessageChunk, 'dispatchMessageChunk', ['messageChunk', 'messageSize']],
54
- [Events.EnterInspectElementMode, 'enterInspectElementMode', []],
55
- [Events.EyeDropperPickedColor, 'eyeDropperPickedColor', ['color']],
56
- [Events.FileSystemsLoaded, 'fileSystemsLoaded', ['fileSystems']],
57
- [Events.FileSystemRemoved, 'fileSystemRemoved', ['fileSystemPath']],
58
- [Events.FileSystemAdded, 'fileSystemAdded', ['errorMessage', 'fileSystem']],
59
- [Events.FileSystemFilesChangedAddedRemoved, 'fileSystemFilesChangedAddedRemoved', ['changed', 'added', 'removed']],
60
- [Events.IndexingTotalWorkCalculated, 'indexingTotalWorkCalculated', ['requestId', 'fileSystemPath', 'totalWork']],
61
- [Events.IndexingWorked, 'indexingWorked', ['requestId', 'fileSystemPath', 'worked']],
62
- [Events.IndexingDone, 'indexingDone', ['requestId', 'fileSystemPath']],
63
- [Events.KeyEventUnhandled, 'keyEventUnhandled', ['event']],
64
- [Events.ReloadInspectedPage, 'reloadInspectedPage', ['hard']],
65
- [Events.RevealSourceLine, 'revealSourceLine', ['url', 'lineNumber', 'columnNumber']],
66
- [Events.SavedURL, 'savedURL', ['url', 'fileSystemPath']],
67
- [Events.SearchCompleted, 'searchCompleted', ['requestId', 'fileSystemPath', 'files']],
68
- [Events.SetInspectedTabId, 'setInspectedTabId', ['tabId']],
69
- [Events.SetUseSoftMenu, 'setUseSoftMenu', ['useSoftMenu']],
70
- [Events.ShowPanel, 'showPanel', ['panelName']],
46
+ [Events.AppendedToURL, ['url']],
47
+ [Events.CanceledSaveURL, ['url']],
48
+ [Events.ColorThemeChanged, []],
49
+ [Events.ContextMenuCleared, []],
50
+ [Events.ContextMenuItemSelected, ['id']],
51
+ [Events.DeviceCountUpdated, ['count']],
52
+ [Events.DevicesDiscoveryConfigChanged, ['config']],
53
+ [Events.DevicesPortForwardingStatusChanged, ['status']],
54
+ [Events.DevicesUpdated, ['devices']],
55
+ [Events.DispatchMessage, ['messageObject']],
56
+ [Events.DispatchMessageChunk, ['messageChunk', 'messageSize']],
57
+ [Events.EnterInspectElementMode, []],
58
+ [Events.EyeDropperPickedColor, ['color']],
59
+ [Events.FileSystemsLoaded, ['fileSystems']],
60
+ [Events.FileSystemRemoved, ['fileSystemPath']],
61
+ [Events.FileSystemAdded, ['errorMessage', 'fileSystem']],
62
+ [Events.FileSystemFilesChangedAddedRemoved, ['changed', 'added', 'removed']],
63
+ [Events.IndexingTotalWorkCalculated, , ['requestId', 'fileSystemPath', 'totalWork']],
64
+ [Events.IndexingWorked, ['requestId', 'fileSystemPath', 'worked']],
65
+ [Events.IndexingDone, ['requestId', 'fileSystemPath']],
66
+ [Events.KeyEventUnhandled, ['event']],
67
+ [Events.ReloadInspectedPage, ['hard']],
68
+ [Events.RevealSourceLine, ['url', 'lineNumber', 'columnNumber']],
69
+ [Events.SavedURL, ['url', 'fileSystemPath']],
70
+ [Events.SearchCompleted, ['requestId', 'fileSystemPath', 'files']],
71
+ [Events.SetInspectedTabId, ['tabId']],
72
+ [Events.SetUseSoftMenu, ['useSoftMenu']],
73
+ [Events.ShowPanel, ['panelName']],
71
74
  ] as const;
72
75
 
73
76
  export interface DispatchMessageChunkEvent {
@@ -1195,7 +1195,8 @@ export const enum SwatchType {
1195
1195
  LENGTH = 8,
1196
1196
  POSITION_TRY_LINK = 10,
1197
1197
  ATTR_LINK = 11,
1198
- MAX_VALUE = 12,
1198
+ MASONRY = 12,
1199
+ MAX_VALUE = 13,
1199
1200
  }
1200
1201
 
1201
1202
  export const enum BadgeType {
@@ -0,0 +1,39 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import type {ProtocolMapping} from '../../generated/protocol-mapping.js';
6
+
7
+ /**
8
+ * Allows the sending and receiving of CDP commands and the notification of CDP events to observers.
9
+ *
10
+ * An instance of a CDPConnection "owns" the full transport channel and no other CDP traffic must
11
+ * be proxied over it. This is because each implementation needs to manage "message IDs", which
12
+ * would conflict with any other shared traffic.
13
+ */
14
+ export interface CDPConnection {
15
+ send<T extends keyof ProtocolMapping.Commands>(
16
+ method: T, params: ProtocolMapping.Commands[T]['paramsType'][0],
17
+ sessionId: string|undefined): Promise<ProtocolMapping.Commands[T]['returnType']|{getError(): string}>;
18
+
19
+ observe(observer: CDPConnectionObserver): void;
20
+ unobserve(observer: CDPConnectionObserver): void;
21
+ }
22
+
23
+ export interface CDPConnectionObserver {
24
+ onEvent<T extends keyof ProtocolMapping.Events>(event: ProtocolMapping.Events[T]): void;
25
+ onDisconnect(reason: string): void;
26
+ }
27
+
28
+ /**
29
+ * The protocol monitor and test harness require inspection of raw CDP message traffic.
30
+ */
31
+ export interface DebuggableCDPConnection extends CDPConnection {
32
+ observeMessages(observer: RawMessageObserver): void;
33
+ unobserveMessages(observer: RawMessageObserver): void;
34
+ }
35
+
36
+ export interface RawMessageObserver {
37
+ onMessageReceived(message: unknown): void;
38
+ onMessageSent(message: unknown): void;
39
+ }
@@ -75,7 +75,6 @@ interface CallbackWithDebugInfo {
75
75
 
76
76
  export class InspectorBackend {
77
77
  readonly agentPrototypes = new Map<ProtocolDomainName, AgentPrototype>();
78
- #initialized = false;
79
78
  #eventParameterNamesForDomain = new Map<ProtocolDomainName, EventParameterNames>();
80
79
  readonly typeMap = new Map<QualifiedName, CommandParameter[]>();
81
80
  readonly enumMap = new Map<QualifiedName, Record<string, string>>();
@@ -114,10 +113,6 @@ export class InspectorBackend {
114
113
  console.warn(error + ': ' + JSON.stringify(messageObject));
115
114
  }
116
115
 
117
- isInitialized(): boolean {
118
- return this.#initialized;
119
- }
120
-
121
116
  private agentPrototype(domain: ProtocolDomainName): AgentPrototype {
122
117
  let prototype = this.agentPrototypes.get(domain);
123
118
  if (!prototype) {
@@ -131,7 +126,6 @@ export class InspectorBackend {
131
126
  void {
132
127
  const [domain, command] = splitQualifiedName(method);
133
128
  this.agentPrototype(domain as ProtocolDomainName).registerCommand(command, parameters, replyArgs, description);
134
- this.#initialized = true;
135
129
  }
136
130
 
137
131
  registerEnum(type: QualifiedName, values: Record<string, string>): void {
@@ -145,19 +139,16 @@ export class InspectorBackend {
145
139
  // @ts-expect-error globalThis global namespace pollution
146
140
  globalThis.Protocol[domain][name] = values;
147
141
  this.enumMap.set(type, values);
148
- this.#initialized = true;
149
142
  }
150
143
 
151
144
  registerType(method: QualifiedName, parameters: CommandParameter[]): void {
152
145
  this.typeMap.set(method, parameters);
153
- this.#initialized = true;
154
146
  }
155
147
 
156
148
  registerEvent(eventName: QualifiedName, params: string[]): void {
157
149
  const domain = eventName.split('.')[0];
158
150
  const eventParameterNames = this.getOrCreateEventParameterNamesForDomain(domain as ProtocolDomainName);
159
151
  eventParameterNames.set(eventName, params);
160
- this.#initialized = true;
161
152
  }
162
153
  }
163
154
 
@@ -24,7 +24,7 @@ import {
24
24
  CustomFunctionMatcher,
25
25
  defaultValueForCSSType,
26
26
  EnvFunctionMatcher,
27
- FlexGridMatcher,
27
+ FlexGridMasonryMatcher,
28
28
  GridTemplateMatcher,
29
29
  LengthMatcher,
30
30
  LightDarkColorMatcher,
@@ -939,7 +939,7 @@ export class CSSMatchedStyles {
939
939
  new LinearGradientMatcher(),
940
940
  new AnchorFunctionMatcher(),
941
941
  new PositionAnchorMatcher(),
942
- new FlexGridMatcher(),
942
+ new FlexGridMasonryMatcher(),
943
943
  new PositionTryMatcher(),
944
944
  new LengthMatcher(),
945
945
  new MathFunctionMatcher(),
@@ -1072,21 +1072,28 @@ export class CustomFunctionMatcher extends matcherBase(CustomFunctionMatch) {
1072
1072
  }
1073
1073
  }
1074
1074
 
1075
- export class FlexGridMatch implements Match {
1076
- constructor(readonly text: string, readonly node: CodeMirror.SyntaxNode, readonly isFlex: boolean) {
1075
+ export const enum LayoutType {
1076
+ FLEX = 'flex',
1077
+ GRID = 'grid',
1078
+ MASONRY = 'masonry'
1079
+ }
1080
+
1081
+ export class FlexGridMasonryMatch implements Match {
1082
+ constructor(readonly text: string, readonly node: CodeMirror.SyntaxNode, readonly layoutType: LayoutType) {
1077
1083
  }
1078
1084
  }
1079
1085
 
1080
1086
  // clang-format off
1081
- export class FlexGridMatcher extends matcherBase(FlexGridMatch) {
1087
+ export class FlexGridMasonryMatcher extends matcherBase(FlexGridMasonryMatch) {
1082
1088
  // clang-format on
1083
1089
  static readonly FLEX = ['flex', 'inline-flex', 'block flex', 'inline flex'];
1084
1090
  static readonly GRID = ['grid', 'inline-grid', 'block grid', 'inline grid'];
1091
+ static readonly MASONRY = ['masonry', 'inline-masonry', 'block masonry', 'inline masonry'];
1085
1092
  override accepts(propertyName: string): boolean {
1086
1093
  return propertyName === 'display';
1087
1094
  }
1088
1095
 
1089
- override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): FlexGridMatch|null {
1096
+ override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): FlexGridMasonryMatch|null {
1090
1097
  if (node.name !== 'Declaration') {
1091
1098
  return null;
1092
1099
  }
@@ -1098,11 +1105,14 @@ export class FlexGridMatcher extends matcherBase(FlexGridMatch) {
1098
1105
  .map(node => matching.getComputedText(node).trim())
1099
1106
  .filter(value => value);
1100
1107
  const text = values.join(' ');
1101
- if (FlexGridMatcher.FLEX.includes(text)) {
1102
- return new FlexGridMatch(matching.ast.text(node), node, true);
1108
+ if (FlexGridMasonryMatcher.FLEX.includes(text)) {
1109
+ return new FlexGridMasonryMatch(matching.ast.text(node), node, LayoutType.FLEX);
1110
+ }
1111
+ if (FlexGridMasonryMatcher.GRID.includes(text)) {
1112
+ return new FlexGridMasonryMatch(matching.ast.text(node), node, LayoutType.GRID);
1103
1113
  }
1104
- if (FlexGridMatcher.GRID.includes(text)) {
1105
- return new FlexGridMatch(matching.ast.text(node), node, false);
1114
+ if (FlexGridMasonryMatcher.MASONRY.includes(text)) {
1115
+ return new FlexGridMasonryMatch(matching.ast.text(node), node, LayoutType.MASONRY);
1106
1116
  }
1107
1117
  return null;
1108
1118
  }
@@ -1520,22 +1520,6 @@ export class NetworkDispatcher implements ProtocolProxyApi.NetworkDispatcher {
1520
1520
  request.setTrustTokenOperationDoneEvent(event);
1521
1521
  }
1522
1522
 
1523
- subresourceWebBundleMetadataReceived(): void {
1524
- // TODO: remove implementation after deleting this methods from definition in Network.pdl
1525
- }
1526
-
1527
- subresourceWebBundleMetadataError(): void {
1528
- // TODO: remove implementation after deleting this methods from definition in Network.pdl
1529
- }
1530
-
1531
- subresourceWebBundleInnerResponseParsed(): void {
1532
- // TODO: remove implementation after deleting this methods from definition in Network.pdl
1533
- }
1534
-
1535
- subresourceWebBundleInnerResponseError(): void {
1536
- // TODO: remove implementation after deleting this methods from definition in Network.pdl
1537
- }
1538
-
1539
1523
  reportingApiReportAdded(data: Protocol.Network.ReportingApiReportAddedEvent): void {
1540
1524
  this.#manager.dispatchEventToListeners(Events.ReportingApiReportAdded, data.report);
1541
1525
  }
@@ -7,6 +7,10 @@
7
7
  // https://crsrc.org/c/third_party/blink/renderer/controller/dev_tools_frontend_impl.cc;l=107
8
8
  (window => {
9
9
  /**
10
+ * A function that tries to check the remotely connected instance
11
+ * major version. You should check against this to provide
12
+ * forward and backwards compatibility.
13
+ *
10
14
  * @returns {number|null}
11
15
  */
12
16
  function getRemoteMajorVersion() {
@@ -20,8 +24,6 @@
20
24
  return null;
21
25
  }
22
26
  }
23
- // eslint-disable-next-line no-unused-vars
24
- const majorVersion = getRemoteMajorVersion();
25
27
 
26
28
  // DevToolsAPI ----------------------------------------------------------------
27
29
  /**
@@ -87,7 +89,9 @@
87
89
  }
88
90
 
89
91
  /**
90
- * @param method
92
+ * @typedef {import('./core/host/InspectorFrontendHostAPI.js').Events} Events
93
+ * @typedef {import('./core/host/InspectorFrontendHost.js').InspectorFrontendAPIImplMethods} Methods
94
+ * @param method {`${Events|Methods}`}
91
95
  * @param args
92
96
  */
93
97
  _dispatchOnInspectorFrontendAPI(method, args) {
@@ -157,7 +161,7 @@
157
161
  }
158
162
 
159
163
  /**
160
- * @param count
164
+ * @param count {number}
161
165
  */
162
166
  deviceCountUpdated(count) {
163
167
  this._dispatchOnInspectorFrontendAPI('deviceCountUpdated', [count]);
@@ -1108,6 +1112,7 @@
1108
1112
  function installBackwardsCompatibility() {
1109
1113
  // Any polyfill that we need for backwards compatibility should be
1110
1114
  // Added in this function
1115
+ // Use getRemoteMajorVersion to get the correct Major Chrome version
1111
1116
  }
1112
1117
 
1113
1118
  installBackwardsCompatibility();
@@ -7,6 +7,9 @@
7
7
  * Re-generate with: npm run generate-protocol-resources.
8
8
  */
9
9
 
10
+
11
+ import type * as Protocol from './protocol.js'
12
+
10
13
  /**
11
14
  * Mappings from protocol event and command names to the types required for them.
12
15
  */
@@ -7,24 +7,8 @@ import * as Root from '../../core/root/root.js';
7
7
  let builtInAiInstance: BuiltInAi|undefined;
8
8
  let availability = '';
9
9
 
10
- const RESPONSE_SCHEMA = {
11
- type: 'object',
12
- properties: {
13
- header: {type: 'string', maxLength: 60, description: 'Label for the console message which is being analyzed'},
14
- // No hard `maxLength` for `explanation`. This would often result in responses which are cut off in the middle of a
15
- // sentence. Instead provide a soft `maxLength` via the prompt.
16
- explanation: {
17
- type: 'string',
18
- description: 'Actual explanation of the console message being analyzed',
19
- },
20
- },
21
- required: ['header', 'explanation'],
22
- additionalProperties: false,
23
- };
24
-
25
10
  export interface LanguageModel {
26
11
  promptStreaming: (arg0: string, opts?: {
27
- responseConstraint: Object,
28
12
  signal?: AbortSignal,
29
13
  }) => AsyncGenerator<string>;
30
14
  clone: () => LanguageModel;
@@ -101,7 +85,6 @@ Your instructions are as follows:
101
85
  const session = await this.#consoleInsightsSession.clone();
102
86
  const stream = session.promptStreaming(prompt, {
103
87
  signal: abortController.signal,
104
- responseConstraint: RESPONSE_SCHEMA,
105
88
  });
106
89
  for await (const chunk of stream) {
107
90
  yield chunk;
@@ -130,29 +130,33 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
130
130
  <h2>${lockedString(UIStringsNotTranslate.summaryNotAvailable)}</h2>
131
131
  ` :
132
132
  showPlaceholder ? html`
133
- <h2>${input.isSlowGeneration ?
134
- lockedString(UIStringsNotTranslate.summarizingTakesABitLonger) :
135
- lockedString(UIStringsNotTranslate.summarizing)
136
- }</h2>
137
- <div
138
- role="presentation"
139
- aria-label=${lockedString(UIStringsNotTranslate.loading)}
140
- class="loader"
141
- style="clip-path: url(${'#clipPath-' + input.uuid});"
142
- >
143
- <svg width="100%" height="58">
144
- <defs>
145
- <clipPath id=${'clipPath-' + input.uuid}>
146
- <rect x="0" y="0" width="100%" height="12" rx="8"></rect>
147
- <rect x="0" y="20" width="100%" height="12" rx="8"></rect>
148
- <rect x="0" y="40" width="100%" height="12" rx="8"></rect>
149
- </clipPath>
150
- </defs>
151
- </svg>
133
+ <div class="response-container">
134
+ <h2>${input.isSlowGeneration ?
135
+ lockedString(UIStringsNotTranslate.summarizingTakesABitLonger) :
136
+ lockedString(UIStringsNotTranslate.summarizing)
137
+ }</h2>
138
+ <div
139
+ role="presentation"
140
+ aria-label=${lockedString(UIStringsNotTranslate.loading)}
141
+ class="loader"
142
+ style="clip-path: url(${'#clipPath-' + input.uuid});"
143
+ >
144
+ <svg width="100%" height="58">
145
+ <defs>
146
+ <clipPath id=${'clipPath-' + input.uuid}>
147
+ <rect x="0" y="0" width="100%" height="12" rx="8"></rect>
148
+ <rect x="0" y="20" width="100%" height="12" rx="8"></rect>
149
+ <rect x="0" y="40" width="100%" height="12" rx="8"></rect>
150
+ </clipPath>
151
+ </defs>
152
+ </svg>
153
+ </div>
152
154
  </div>
153
155
  ` : html`
154
- <h2>${input.headerText}</h2>
155
- <div class="main-text">${input.mainText}</div>
156
+ <div class="response-container">
157
+ <h2>${input.headerText}</h2>
158
+ <div class="main-text">${input.mainText}</div>
159
+ </div>
156
160
  `
157
161
  }
158
162
  <div class="tooltip-footer">
@@ -167,25 +171,23 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
167
171
  ${lockedString(UIStringsNotTranslate.tellMeMore)}
168
172
  </devtools-button>
169
173
  ` : Lit.nothing}
170
- ${showPlaceholder ? Lit.nothing : html`
171
- <devtools-button
172
- .iconName=${'info'}
173
- .variant=${Buttons.Button.Variant.ICON}
174
- aria-details=${'teaser-info-tooltip-' + input.uuid}
175
- .accessibleLabel=${lockedString(UIStringsNotTranslate.learnDataUsage)}
176
- ></devtools-button>
177
- <devtools-tooltip id=${'teaser-info-tooltip-' + input.uuid} variant="rich">
178
- <div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
179
- <div class="learn-more">
180
- <x-link
181
- class="devtools-link"
182
- title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
183
- href=${DATA_USAGE_URL}
184
- jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
185
- >${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
186
- </div>
187
- </devtools-tooltip>
188
- `}
174
+ <devtools-button
175
+ .iconName=${'info'}
176
+ .variant=${Buttons.Button.Variant.ICON}
177
+ aria-details=${'teaser-info-tooltip-' + input.uuid}
178
+ .accessibleLabel=${lockedString(UIStringsNotTranslate.learnDataUsage)}
179
+ ></devtools-button>
180
+ <devtools-tooltip id=${'teaser-info-tooltip-' + input.uuid} variant="rich">
181
+ <div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
182
+ <div class="learn-more">
183
+ <x-link
184
+ class="devtools-link"
185
+ title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
186
+ href=${DATA_USAGE_URL}
187
+ jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
188
+ >${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
189
+ </div>
190
+ </devtools-tooltip>
189
191
  <devtools-checkbox
190
192
  aria-label=${lockedString(UIStringsNotTranslate.dontShow)}
191
193
  @change=${input.dontShowChanged}
@@ -215,6 +217,8 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
215
217
  #isSlow = false;
216
218
  #timeoutId: ReturnType<typeof setTimeout>|null = null;
217
219
  #isError = false;
220
+ #aidaAvailability?: Host.AidaClient.AidaAccessPreconditions;
221
+ #boundOnAidaAvailabilityChange: () => Promise<void>;
218
222
 
219
223
  constructor(uuid: string, consoleViewMessage: ConsoleViewMessage, element?: HTMLElement, view?: View) {
220
224
  super(element);
@@ -222,6 +226,7 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
222
226
  this.#uuid = uuid;
223
227
  this.#promptBuilder = new PromptBuilder(consoleViewMessage);
224
228
  this.#consoleViewMessage = consoleViewMessage;
229
+ this.#boundOnAidaAvailabilityChange = this.#onAidaAvailabilityChange.bind(this);
225
230
  this.requestUpdate();
226
231
  }
227
232
 
@@ -237,6 +242,14 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
237
242
  return Common.Settings.Settings.instance().createLocalSetting('console-insights-onboarding-finished', true);
238
243
  }
239
244
 
245
+ async #onAidaAvailabilityChange(): Promise<void> {
246
+ const currentAidaAvailability = await Host.AidaClient.AidaClient.checkAccessPreconditions();
247
+ if (currentAidaAvailability !== this.#aidaAvailability) {
248
+ this.#aidaAvailability = currentAidaAvailability;
249
+ this.requestUpdate();
250
+ }
251
+ }
252
+
240
253
  #executeConsoleInsightAction(): void {
241
254
  UI.Context.Context.instance().setFlavor(ConsoleViewMessage, this.#consoleViewMessage);
242
255
  const action = UI.ActionRegistry.ActionRegistry.instance().getAction(EXPLAIN_TEASER_ACTION_ID);
@@ -307,6 +320,9 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
307
320
  if (this.#abortController) {
308
321
  this.#abortController.abort();
309
322
  }
323
+ if (this.#isGenerating) {
324
+ this.#mainText = '';
325
+ }
310
326
  this.#isGenerating = false;
311
327
  if (this.#timeoutId) {
312
328
  clearTimeout(this.#timeoutId);
@@ -327,12 +343,15 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
327
343
  }
328
344
 
329
345
  async #generateTeaserText(): Promise<void> {
346
+ this.#headerText = this.#consoleViewMessage.toMessageTextString().substring(0, 70);
330
347
  this.#isGenerating = true;
331
348
  this.#timeoutId = setTimeout(this.#setSlow.bind(this), SLOW_GENERATION_CUTOFF_MILLISECONDS);
332
349
  let teaserText = '';
333
350
  try {
334
351
  for await (const chunk of this.#getOnDeviceInsight()) {
335
352
  teaserText += chunk;
353
+ this.#mainText = teaserText;
354
+ this.requestUpdate();
336
355
  }
337
356
  } catch (err) {
338
357
  // Ignore `AbortError` errors, which are thrown on mouse leave.
@@ -348,25 +367,7 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
348
367
 
349
368
  clearTimeout(this.#timeoutId);
350
369
  this.#isGenerating = false;
351
- let responseObject = {
352
- header: null,
353
- explanation: null,
354
- };
355
- try {
356
- responseObject = JSON.parse(teaserText);
357
- } catch (err) {
358
- console.error(err.name, err.message);
359
- this.#isError = true;
360
- this.requestUpdate();
361
- return;
362
- }
363
- if (responseObject.header && typeof responseObject.header === 'string' && responseObject.explanation &&
364
- typeof responseObject.explanation === 'string') {
365
- this.#headerText = responseObject.header;
366
- this.#mainText = responseObject.explanation;
367
- } else {
368
- this.#isError = true;
369
- }
370
+ this.#mainText = teaserText;
370
371
  this.requestUpdate();
371
372
  }
372
373
 
@@ -399,7 +400,7 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
399
400
  if (Root.Runtime.hostConfig.aidaAvailability?.blockedByAge || Root.Runtime.hostConfig.isOffTheRecord) {
400
401
  return false;
401
402
  }
402
- if (!Host.AidaClient.AidaAccessPreconditions.AVAILABLE) {
403
+ if (this.#aidaAvailability !== Host.AidaClient.AidaAccessPreconditions.AVAILABLE) {
403
404
  return false;
404
405
  }
405
406
  return true;
@@ -421,4 +422,17 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
421
422
  },
422
423
  undefined, this.contentElement);
423
424
  }
425
+
426
+ override wasShown(): void {
427
+ super.wasShown();
428
+ Host.AidaClient.HostConfigTracker.instance().addEventListener(
429
+ Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
430
+ void this.#onAidaAvailabilityChange();
431
+ }
432
+
433
+ override willHide(): void {
434
+ super.willHide();
435
+ Host.AidaClient.HostConfigTracker.instance().removeEventListener(
436
+ Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
437
+ }
424
438
  }
@@ -711,8 +711,10 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
711
711
  if (icon) {
712
712
  clickableElement.appendChild(icon);
713
713
  }
714
- // Intercept focus to avoid highlight on click.
715
- clickableElement.tabIndex = -1;
714
+ if (stackTrace) {
715
+ // Intercept focus to avoid highlight on click.
716
+ clickableElement.tabIndex = -1;
717
+ }
716
718
  clickableElement.appendChild(messageElement);
717
719
  const stackTraceElement = contentElement.createChild('div');
718
720
  const stackTracePreview = new Components.JSPresentationUtils.StackTracePreviewContent(
@@ -11,6 +11,10 @@
11
11
  margin-top: var(--sys-size-2);
12
12
  }
13
13
 
14
+ .response-container {
15
+ height: 85px;
16
+ }
17
+
14
18
  @keyframes gradient {
15
19
  0% { background-position: 100% 0; }
16
20
  100% { background-position: -100% 0; }
@@ -220,7 +220,7 @@
220
220
  --console-color-lightcyan: #5ff;
221
221
  --console-color-white: #fff;
222
222
 
223
- &.console-selected {
223
+ &:focus {
224
224
  background-color: var(--sys-color-state-focus-highlight);
225
225
  }
226
226
  }