chrome-devtools-frontend 1.0.1572937 → 1.0.1574367

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 (145) hide show
  1. package/front_end/Images/src/account-tree.svg +10 -1
  2. package/front_end/Images/src/arrow-right-circle.svg +2 -7
  3. package/front_end/Images/src/center-focus-weak.svg +3 -1
  4. package/front_end/Images/src/dog-paw.svg +10 -3
  5. package/front_end/Images/src/group.svg +3 -1
  6. package/front_end/Images/src/home.svg +3 -1
  7. package/front_end/Images/src/spark-info.svg +3 -3
  8. package/front_end/Images/src/spark.svg +2 -9
  9. package/front_end/core/sdk/AnimationModel.ts +0 -6
  10. package/front_end/core/sdk/IsolateManager.ts +0 -7
  11. package/front_end/devtools_compatibility.js +16 -1
  12. package/front_end/entrypoints/main/GlobalAiButton.ts +18 -3
  13. package/front_end/generated/InspectorBackendCommands.ts +6 -4
  14. package/front_end/generated/SupportedCSSProperties.js +17 -4
  15. package/front_end/generated/protocol-mapping.d.ts +2 -0
  16. package/front_end/generated/protocol-proxy-api.d.ts +2 -0
  17. package/front_end/generated/protocol.ts +37 -7
  18. package/front_end/models/ai_assistance/AiUtils.ts +8 -0
  19. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +7 -7
  20. package/front_end/models/ai_assistance/agents/StylingAgent.ts +4 -4
  21. package/front_end/models/issues_manager/CorsIssue.ts +4 -44
  22. package/front_end/models/logs/NetworkLog.ts +0 -9
  23. package/front_end/panels/ai_assistance/PatchWidget.ts +5 -5
  24. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +1 -1
  25. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +34 -13
  26. package/front_end/panels/ai_assistance/components/ChatMessage.ts +3 -1
  27. package/front_end/panels/ai_assistance/components/ChatView.ts +20 -3
  28. package/front_end/panels/ai_assistance/components/chatView.css +20 -0
  29. package/front_end/panels/application/AppManifestView.ts +5 -5
  30. package/front_end/panels/application/DeviceBoundSessionsModel.ts +32 -3
  31. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +31 -9
  32. package/front_end/panels/application/FrameDetailsView.ts +3 -4
  33. package/front_end/panels/application/components/BounceTrackingMitigationsView.ts +1 -1
  34. package/front_end/panels/application/components/ProtocolHandlersView.ts +2 -2
  35. package/front_end/panels/application/components/ReportsGrid.ts +2 -2
  36. package/front_end/panels/application/preloading/PreloadingView.ts +2 -2
  37. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -2
  38. package/front_end/panels/autofill/AutofillView.ts +3 -3
  39. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +1 -1
  40. package/front_end/panels/common/AiCodeCompletionTeaser.ts +4 -2
  41. package/front_end/panels/common/AiCodeGenerationUpgradeDialog.ts +2 -2
  42. package/front_end/panels/common/BadgeNotification.ts +3 -2
  43. package/front_end/panels/common/GdpSignUpDialog.ts +3 -3
  44. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +1 -1
  45. package/front_end/panels/console/ConsoleInsightTeaser.ts +5 -4
  46. package/front_end/panels/elements/ElementsTreeElement.ts +3 -1
  47. package/front_end/panels/explain/components/ConsoleInsight.ts +7 -7
  48. package/front_end/panels/issues/CorsIssueDetailsView.ts +0 -46
  49. package/front_end/panels/issues/IssueView.ts +1 -1
  50. package/front_end/panels/network/NetworkDataGridNode.ts +3 -1
  51. package/front_end/panels/network/RequestConditionsDrawer.ts +4 -4
  52. package/front_end/panels/network/RequestTimingView.ts +1 -1
  53. package/front_end/panels/network/components/RequestHeadersView.ts +2 -2
  54. package/front_end/panels/profiler/HeapDetachedElementsView.ts +0 -5
  55. package/front_end/panels/profiler/HeapProfileView.ts +0 -6
  56. package/front_end/panels/profiler/HeapSnapshotView.ts +0 -14
  57. package/front_end/panels/profiler/IsolateSelector.ts +1 -2
  58. package/front_end/panels/recorder/RecorderController.ts +2 -2
  59. package/front_end/panels/security/CookieReportView.ts +6 -6
  60. package/front_end/panels/settings/AISettingsTab.ts +1 -1
  61. package/front_end/panels/settings/components/SyncSection.ts +1 -1
  62. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +1 -1
  63. package/front_end/panels/sources/BreakpointEditDialog.ts +1 -1
  64. package/front_end/panels/sources/NavigatorView.ts +3 -1
  65. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +2 -1
  66. package/front_end/panels/whats_new/ReleaseNoteView.ts +1 -1
  67. package/front_end/third_party/chromium/README.chromium +1 -1
  68. package/front_end/third_party/puppeteer/README.chromium +2 -2
  69. package/front_end/third_party/puppeteer/package/README.md +5 -0
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/HTTPResponse.d.ts +6 -1
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/HTTPResponse.d.ts.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/HTTPResponse.js +5 -1
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/HTTPResponse.js.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +3 -0
  75. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  76. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +53 -55
  77. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +2 -0
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +25 -0
  81. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts +7 -1
  83. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js +3 -0
  85. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js.map +1 -1
  86. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js +2 -0
  88. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +2 -0
  91. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  93. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  94. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  95. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  97. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  98. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  99. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +7 -1
  100. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +21 -8
  101. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/HTTPResponse.d.ts +6 -1
  102. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/HTTPResponse.d.ts.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/HTTPResponse.js +5 -1
  104. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/HTTPResponse.js.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +3 -0
  106. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +54 -56
  108. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +2 -0
  110. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +25 -0
  112. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  113. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts +7 -1
  114. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js +3 -0
  116. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js.map +1 -1
  117. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
  118. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js +2 -0
  119. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js.map +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  121. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +2 -0
  122. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  123. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  124. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  125. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  126. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/types.d.ts +7 -1
  129. package/front_end/third_party/puppeteer/package/package.json +5 -5
  130. package/front_end/third_party/puppeteer/package/src/api/HTTPResponse.ts +7 -2
  131. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +62 -71
  132. package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +29 -0
  133. package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +12 -1
  134. package/front_end/third_party/puppeteer/package/src/cdp/BrowserContext.ts +2 -0
  135. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +2 -0
  136. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  137. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  138. package/front_end/ui/components/buttons/Button.ts +26 -14
  139. package/front_end/ui/components/buttons/FloatingButton.ts +7 -3
  140. package/front_end/ui/components/buttons/floatingButton.css +44 -0
  141. package/front_end/ui/components/markdown_view/CodeBlock.ts +1 -1
  142. package/front_end/ui/components/panel_feedback/PanelFeedback.ts +1 -1
  143. package/front_end/ui/components/text_editor/AutocompleteHistory.ts +33 -1
  144. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  145. package/package.json +3 -2
@@ -106,7 +106,7 @@ Content:
106
106
  "type": 1,
107
107
  "description": "JavaScript code snippet to run on the inspected page. Make sure the code is formatted for readability.\n\n# Instructions\n\n* To return data, define a top-level `data` variable and populate it with data you want to get. Only JSON-serializable objects can be assigned to `data`.\n* If you modify styles on an element, ALWAYS call the pre-defined global `async setElementStyles(el: Element, styles: object)` function. This function is an internal mechanism for you and should never be presented as a command/advice to the user.\n* **CRITICAL** Only get styles that might be relevant to the user request.\n* **CRITICAL** Never assume a selector for the elements unless you verified your knowledge.\n* **CRITICAL** Consider that `data` variable from the previous function calls are not available in a new function call.\n\nFor example, the code to change element styles:\n\n```\nawait setElementStyles($0, {\n color: 'blue',\n});\n```\n\nFor example, the code to get overlapping elements:\n\n```\nconst data = {\n overlappingElements: Array.from(document.querySelectorAll('*'))\n .filter(el => {\n const rect = el.getBoundingClientRect();\n const popupRect = $0.getBoundingClientRect();\n return (\n el !== $0 &&\n rect.left < popupRect.right &&\n rect.right > popupRect.left &&\n rect.top < popupRect.bottom &&\n rect.bottom > popupRect.top\n );\n })\n .map(el => ({\n tagName: el.tagName,\n id: el.id,\n className: el.className,\n zIndex: window.getComputedStyle(el)['z-index']\n }))\n};\n```\n"
108
108
  },
109
- "thought": {
109
+ "explanation": {
110
110
  "type": 1,
111
111
  "description": "Explain why you want to run this code"
112
112
  },
@@ -117,7 +117,7 @@ Content:
117
117
  },
118
118
  "required": [
119
119
  "code",
120
- "thought",
120
+ "explanation",
121
121
  "title"
122
122
  ]
123
123
  }
@@ -155,7 +155,7 @@ Content:
155
155
  "name": "executeJavaScript",
156
156
  "args": {
157
157
  "title": "title2",
158
- "thought": "thought2",
158
+ "explanation": "thought2",
159
159
  "code": "action2"
160
160
  }
161
161
  }
@@ -259,7 +259,7 @@ Content:
259
259
  "name": "executeJavaScript",
260
260
  "args": {
261
261
  "code": "const data = {\"test\": \"observation\"}",
262
- "thought": "I am thinking.",
262
+ "explanation": "I am thinking.",
263
263
  "title": "thinking"
264
264
  }
265
265
  }
@@ -451,7 +451,7 @@ Content:
451
451
  "functionCall": {
452
452
  "name": "executeJavaScript",
453
453
  "args": {
454
- "thought": "thought 1",
454
+ "explanation": "thought 1",
455
455
  "title": "test",
456
456
  "code": "console.log('test')"
457
457
  }
@@ -479,7 +479,7 @@ Content:
479
479
  "functionCall": {
480
480
  "name": "executeJavaScript",
481
481
  "args": {
482
- "thought": "thought 2",
482
+ "explanation": "thought 2",
483
483
  "title": "test",
484
484
  "code": "console.log('test')"
485
485
  }
@@ -507,7 +507,7 @@ Content:
507
507
  "functionCall": {
508
508
  "name": "executeJavaScript",
509
509
  "args": {
510
- "thought": "thought 3",
510
+ "explanation": "thought 3",
511
511
  "title": "test",
512
512
  "code": "console.log('test')"
513
513
  }
@@ -330,7 +330,7 @@ export class StylingAgent extends AiAgent<SDK.DOMModel.DOMNode> {
330
330
 
331
331
  this.declareFunction<{
332
332
  title: string,
333
- thought: string,
333
+ explanation: string,
334
334
  code: string,
335
335
  }>('executeJavaScript', {
336
336
  description:
@@ -388,7 +388,7 @@ const data = {
388
388
  \`\`\`
389
389
  `,
390
390
  },
391
- thought: {
391
+ explanation: {
392
392
  type: Host.AidaClient.ParametersTypes.STRING,
393
393
  description: 'Explain why you want to run this code',
394
394
  },
@@ -397,12 +397,12 @@ const data = {
397
397
  description: 'Provide a summary of what the code does. For example, "Checking related element styles".',
398
398
  },
399
399
  },
400
- required: ['code', 'thought', 'title']
400
+ required: ['code', 'explanation', 'title']
401
401
  },
402
402
  displayInfoFromArgs: params => {
403
403
  return {
404
404
  title: params.title,
405
- thought: params.thought,
405
+ thought: params.explanation,
406
406
  action: params.code,
407
407
  };
408
408
  },
@@ -44,12 +44,6 @@ export const enum IssueCode {
44
44
  PREFLIGHT_INVALID_ALLOW_EXTERNAL = 'CorsIssue::PreflightInvalidAllowExternal',
45
45
  NO_CORS_REDIRECT_MODE_NOT_FOLLOW = 'CorsIssue::NoCorsRedirectModeNotFollow',
46
46
  INVALID_PRIVATE_NETWORK_ACCESS = 'CorsIssue::InvalidPrivateNetworkAccess',
47
- UNEXPECTED_PRIVATE_NETWORK_ACCESS = 'CorsIssue::UnexpectedPrivateNetworkAccess',
48
- PREFLIGHT_ALLOW_PRIVATE_NETWORK_ERROR = 'CorsIssue::PreflightAllowPrivateNetworkError',
49
- PREFLIGHT_MISSING_PRIVATE_NETWORK_ACCESS_ID = 'CorsIssue::PreflightMissingPrivateNetworkAccessId',
50
- PREFLIGHT_MISSING_PRIVATE_NETWORK_ACCESS_NAME = 'CorsIssue::PreflightMissingPrivateNetworkAccessName',
51
- PRIVATE_NETWORK_ACCESS_PERMISSION_UNAVAILABLE = 'CorsIssue::PrivateNetworkAccessPermissionUnavailable',
52
- PRIVATE_NETWORK_ACCESS_PERMISSION_DENIED = 'CorsIssue::PrivateNetworkAccessPermissionDenied',
53
47
  LOCAL_NETWORK_ACCESS_PERMISSION_DENIED = 'CorsIssue::LocalNetworkAccessPermissionDenied',
54
48
  }
55
49
 
@@ -97,22 +91,12 @@ function getIssueCode(details: Protocol.Audits.CorsIssueDetails): IssueCode {
97
91
  return IssueCode.NO_CORS_REDIRECT_MODE_NOT_FOLLOW;
98
92
  case Protocol.Network.CorsError.InvalidPrivateNetworkAccess:
99
93
  return IssueCode.INVALID_PRIVATE_NETWORK_ACCESS;
100
- case Protocol.Network.CorsError.UnexpectedPrivateNetworkAccess:
101
- return IssueCode.UNEXPECTED_PRIVATE_NETWORK_ACCESS;
102
- case Protocol.Network.CorsError.PreflightMissingAllowPrivateNetwork:
103
- case Protocol.Network.CorsError.PreflightInvalidAllowPrivateNetwork:
104
- return IssueCode.PREFLIGHT_ALLOW_PRIVATE_NETWORK_ERROR;
105
- case Protocol.Network.CorsError.PreflightMissingPrivateNetworkAccessId:
106
- return IssueCode.PREFLIGHT_MISSING_PRIVATE_NETWORK_ACCESS_ID;
107
- case Protocol.Network.CorsError.PreflightMissingPrivateNetworkAccessName:
108
- return IssueCode.PREFLIGHT_MISSING_PRIVATE_NETWORK_ACCESS_NAME;
109
- case Protocol.Network.CorsError.PrivateNetworkAccessPermissionUnavailable:
110
- return IssueCode.PRIVATE_NETWORK_ACCESS_PERMISSION_UNAVAILABLE;
111
- case Protocol.Network.CorsError.PrivateNetworkAccessPermissionDenied:
112
- return IssueCode.PRIVATE_NETWORK_ACCESS_PERMISSION_DENIED;
113
94
  case Protocol.Network.CorsError.LocalNetworkAccessPermissionDenied:
114
95
  return IssueCode.LOCAL_NETWORK_ACCESS_PERMISSION_DENIED;
115
96
  }
97
+ // TODO(b/394636065): Remove this once browser protocol has rolled, as we
98
+ // will never hit this case.
99
+ return null as unknown as IssueCode;
116
100
  }
117
101
 
118
102
  export class CorsIssue extends Issue<Protocol.Audits.CorsIssueDetails, IssueCode> {
@@ -136,14 +120,6 @@ export class CorsIssue extends Issue<Protocol.Audits.CorsIssueDetails, IssueCode
136
120
  linkTitle: i18nString(UIStrings.corsPrivateNetworkAccess),
137
121
  }],
138
122
  };
139
- case IssueCode.PREFLIGHT_ALLOW_PRIVATE_NETWORK_ERROR:
140
- return {
141
- file: 'corsPreflightAllowPrivateNetworkError.md',
142
- links: [{
143
- link: 'https://developer.chrome.com/blog/private-network-access-update',
144
- linkTitle: i18nString(UIStrings.corsPrivateNetworkAccess),
145
- }],
146
- };
147
123
  case IssueCode.INVALID_HEADER_VALUES:
148
124
  return {
149
125
  file: 'corsInvalidHeaderValues.md',
@@ -232,17 +208,6 @@ export class CorsIssue extends Issue<Protocol.Audits.CorsIssueDetails, IssueCode
232
208
  linkTitle: i18nString(UIStrings.CORS),
233
209
  }],
234
210
  };
235
- // TODO(1462857): Change the link after we have a blog post for PNA
236
- // permission prompt.
237
- case IssueCode.PREFLIGHT_MISSING_PRIVATE_NETWORK_ACCESS_ID:
238
- case IssueCode.PREFLIGHT_MISSING_PRIVATE_NETWORK_ACCESS_NAME:
239
- return {
240
- file: 'corsPrivateNetworkPermissionDenied.md',
241
- links: [{
242
- link: 'https://developer.chrome.com/blog/private-network-access-update',
243
- linkTitle: i18nString(UIStrings.corsPrivateNetworkAccess),
244
- }],
245
- };
246
211
  case IssueCode.LOCAL_NETWORK_ACCESS_PERMISSION_DENIED:
247
212
  return {
248
213
  file: 'corsLocalNetworkAccessPermissionDenied.md',
@@ -254,9 +219,6 @@ export class CorsIssue extends Issue<Protocol.Audits.CorsIssueDetails, IssueCode
254
219
  case IssueCode.PREFLIGHT_MISSING_ALLOW_EXTERNAL:
255
220
  case IssueCode.PREFLIGHT_INVALID_ALLOW_EXTERNAL:
256
221
  case IssueCode.INVALID_PRIVATE_NETWORK_ACCESS:
257
- case IssueCode.UNEXPECTED_PRIVATE_NETWORK_ACCESS:
258
- case IssueCode.PRIVATE_NETWORK_ACCESS_PERMISSION_UNAVAILABLE:
259
- case IssueCode.PRIVATE_NETWORK_ACCESS_PERMISSION_DENIED:
260
222
  return null;
261
223
  }
262
224
  }
@@ -267,9 +229,7 @@ export class CorsIssue extends Issue<Protocol.Audits.CorsIssueDetails, IssueCode
267
229
 
268
230
  getKind(): IssueKind {
269
231
  if (this.details().isWarning &&
270
- (this.details().corsErrorStatus.corsError === Protocol.Network.CorsError.InsecurePrivateNetwork ||
271
- this.details().corsErrorStatus.corsError === Protocol.Network.CorsError.PreflightMissingAllowPrivateNetwork ||
272
- this.details().corsErrorStatus.corsError === Protocol.Network.CorsError.PreflightInvalidAllowPrivateNetwork)) {
232
+ this.details().corsErrorStatus.corsError === Protocol.Network.CorsError.InsecurePrivateNetwork) {
273
233
  return IssueKind.BREAKING_CHANGE;
274
234
  }
275
235
  return IssueKind.PAGE_ERROR;
@@ -469,15 +469,6 @@ export class NetworkLog extends Common.ObjectWrapper.ObjectWrapper<EventTypes> i
469
469
  return;
470
470
  }
471
471
 
472
- // This is only triggered in an edge case in which Chrome reports 2 preflight requests. The
473
- // first preflight gets aborted and should not be shown in DevTools.
474
- // (see https://crbug.com/1290390 for details)
475
- if (request.isPreflightRequest() &&
476
- request.corsErrorStatus()?.corsError === Protocol.Network.CorsError.UnexpectedPrivateNetworkAccess) {
477
- this.removeRequest(request);
478
- return;
479
- }
480
-
481
472
  this.dispatchEventToListeners(Events.RequestUpdated, {request});
482
473
  }
483
474
 
@@ -205,7 +205,7 @@ const DEFAULT_VIEW: View = (input, output, target) => {
205
205
  class="link"
206
206
  title="${UIStringsNotTranslate.viewUploadedFiles} ${UIStringsNotTranslate.opensInNewTab}"
207
207
  href="data:text/plain;charset=utf-8,${encodeURIComponent(input.sources)}"
208
- .jslogContext=${'files-used-in-patching'}>
208
+ jslogcontext="files-used-in-patching">
209
209
  ${UIStringsNotTranslate.viewUploadedFiles}
210
210
  </devtools-link>`;
211
211
  }
@@ -296,8 +296,7 @@ const DEFAULT_VIEW: View = (input, output, target) => {
296
296
  return html`
297
297
  <div class="footer">
298
298
  <div class="left-side">
299
- <devtools-link class="link disclaimer-link" href="https://support.google.com/legal/answer/13505487" .jslogContext=${
300
- 'code-disclaimer'}>
299
+ <devtools-link class="link disclaimer-link" href="https://support.google.com/legal/answer/13505487" jslogcontext="code-disclaimer">
301
300
  ${lockedString(UIStringsNotTranslate.codeDisclaimer)}
302
301
  </devtools-link>
303
302
  ${renderSourcesLink()}
@@ -557,8 +556,9 @@ export class PatchWidget extends UI.Widget.Widget {
557
556
  return true;
558
557
  }
559
558
 
559
+ const iconName = AiAssistanceModel.AiUtils.getIconName();
560
560
  const result = await PanelCommon.FreDialog.show({
561
- header: {iconName: 'smart-assistant', text: lockedString(UIStringsNotTranslate.freDisclaimerHeader)},
561
+ header: {iconName, text: lockedString(UIStringsNotTranslate.freDisclaimerHeader)},
562
562
  reminderItems: [
563
563
  {
564
564
  iconName: 'psychiatry',
@@ -575,7 +575,7 @@ export class PatchWidget extends UI.Widget.Widget {
575
575
  content: html`<devtools-link
576
576
  href=${CODE_SNIPPET_WARNING_URL}
577
577
  class="link devtools-link"
578
- .jslogContext=${'code-snippets-explainer.patch-widget'}
578
+ jslogcontext="code-snippets-explainer.patch-widget"
579
579
  >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</devtools-link>`,
580
580
  // clang-format on
581
581
  }
@@ -93,7 +93,7 @@ export const SELECT_WORKSPACE_DIALOG_DEFAULT_VIEW: View = (input, _output, targe
93
93
  <devtools-link
94
94
  class="devtools-link"
95
95
  href="https://goo.gle/devtools-automatic-workspace-folders"
96
- .jslogContext=${'automatic-workspaces-documentation'}
96
+ jslogcontext="automatic-workspaces-documentation"
97
97
  >com.chrome.devtools.json</devtools-link>
98
98
  file to automatically connect your project to DevTools.
99
99
  </div>
@@ -5,7 +5,7 @@
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as i18n from '../../core/i18n/i18n.js';
7
7
  import type * as Platform from '../../core/platform/platform.js';
8
- import type * as Root from '../../core/root/root.js';
8
+ import * as Root from '../../core/root/root.js';
9
9
  import * as UI from '../../ui/legacy/legacy.js';
10
10
 
11
11
  import type * as AiAssistance from './ai_assistance.js';
@@ -34,6 +34,22 @@ const UIStrings = {
34
34
  * the current context
35
35
  */
36
36
  debugWithAi: 'Debug with AI',
37
+ /**
38
+ * @description The title of the Gemini panel.
39
+ */
40
+ gemini: 'Gemini',
41
+ /**
42
+ * @description The title of the command menu action for showing the Gemini panel.
43
+ */
44
+ showGemini: 'Show Gemini',
45
+ /**
46
+ * @description The setting title to enable the Gemini via the settings tab.
47
+ */
48
+ enableGemini: 'Enable Gemini',
49
+ /**
50
+ * @description Text of a context menu item to redirect to the Gemini panel with the current context
51
+ */
52
+ debugWithGemini: 'Debug with Gemini',
37
53
  /**
38
54
  * @description Message shown to the user if the DevTools locale is not
39
55
  * supported.
@@ -53,7 +69,12 @@ const UIStrings = {
53
69
 
54
70
  const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/ai_assistance-meta.ts', UIStrings);
55
71
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
56
- const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
72
+
73
+ // Host config is initialized after this module executes, so need to lazily select the string.
74
+ function i18nAiBrandedString(gemini: string, assistance: string) {
75
+ // eslint-disable-next-line @devtools/l10n-i18nString-call-only-with-uistrings
76
+ return () => Root.Runtime.hostConfig.devToolsGeminiRebranding?.enabled ? i18nString(gemini) : i18nString(assistance);
77
+ }
57
78
 
58
79
  const setting = 'ai-assistance-enabled';
59
80
 
@@ -102,8 +123,8 @@ function isAnyFeatureAvailable(config?: Root.Runtime.HostConfig): boolean {
102
123
  UI.ViewManager.registerViewExtension({
103
124
  location: UI.ViewManager.ViewLocationValues.DRAWER_VIEW,
104
125
  id: 'freestyler',
105
- commandPrompt: i18nLazyString(UIStrings.showAiAssistance),
106
- title: i18nLazyString(UIStrings.aiAssistance),
126
+ commandPrompt: i18nAiBrandedString(UIStrings.showGemini, UIStrings.showAiAssistance),
127
+ title: i18nAiBrandedString(UIStrings.gemini, UIStrings.aiAssistance),
107
128
  order: 10,
108
129
  persistence: UI.ViewManager.ViewPersistence.CLOSEABLE,
109
130
  hasToolbar: false,
@@ -118,7 +139,7 @@ Common.Settings.registerSettingExtension({
118
139
  category: Common.Settings.SettingCategory.AI,
119
140
  settingName: setting,
120
141
  settingType: Common.Settings.SettingType.BOOLEAN,
121
- title: i18nLazyString(UIStrings.enableAiAssistance),
142
+ title: i18nAiBrandedString(UIStrings.enableGemini, UIStrings.enableAiAssistance),
122
143
  defaultValue: false,
123
144
  reloadRequired: false,
124
145
  condition: isAnyFeatureAvailable,
@@ -146,7 +167,7 @@ UI.ActionRegistration.registerActionExtension({
146
167
  return [];
147
168
  },
148
169
  category: UI.ActionRegistration.ActionCategory.GLOBAL,
149
- title: i18nLazyString(UIStrings.debugWithAi),
170
+ title: i18nAiBrandedString(UIStrings.debugWithGemini, UIStrings.debugWithAi),
150
171
  configurableBindings: false,
151
172
  async loadActionDelegate() {
152
173
  const AiAssistance = await loadAiAssistanceModule();
@@ -161,7 +182,7 @@ UI.ActionRegistration.registerActionExtension({
161
182
  return [];
162
183
  },
163
184
  category: UI.ActionRegistration.ActionCategory.GLOBAL,
164
- title: i18nLazyString(UIStrings.debugWithAi),
185
+ title: i18nAiBrandedString(UIStrings.debugWithGemini, UIStrings.debugWithAi),
165
186
  configurableBindings: false,
166
187
  async loadActionDelegate() {
167
188
  const AiAssistance = await loadAiAssistanceModule();
@@ -177,7 +198,7 @@ UI.ActionRegistration.registerActionExtension({
177
198
  return [];
178
199
  },
179
200
  category: UI.ActionRegistration.ActionCategory.GLOBAL,
180
- title: i18nLazyString(UIStrings.debugWithAi),
201
+ title: i18nAiBrandedString(UIStrings.debugWithGemini, UIStrings.debugWithAi),
181
202
  configurableBindings: false,
182
203
  async loadActionDelegate() {
183
204
  const AiAssistance = await loadAiAssistanceModule();
@@ -193,7 +214,7 @@ UI.ActionRegistration.registerActionExtension({
193
214
  return [];
194
215
  },
195
216
  category: UI.ActionRegistration.ActionCategory.GLOBAL,
196
- title: i18nLazyString(UIStrings.debugWithAi),
217
+ title: i18nAiBrandedString(UIStrings.debugWithGemini, UIStrings.debugWithAi),
197
218
  configurableBindings: false,
198
219
  async loadActionDelegate() {
199
220
  const AiAssistance = await loadAiAssistanceModule();
@@ -209,7 +230,7 @@ UI.ActionRegistration.registerActionExtension({
209
230
  return [];
210
231
  },
211
232
  category: UI.ActionRegistration.ActionCategory.GLOBAL,
212
- title: i18nLazyString(UIStrings.debugWithAi),
233
+ title: i18nAiBrandedString(UIStrings.debugWithGemini, UIStrings.debugWithAi),
213
234
  configurableBindings: false,
214
235
  async loadActionDelegate() {
215
236
  const AiAssistance = await loadAiAssistanceModule();
@@ -225,7 +246,7 @@ UI.ActionRegistration.registerActionExtension({
225
246
  return [];
226
247
  },
227
248
  category: UI.ActionRegistration.ActionCategory.GLOBAL,
228
- title: i18nLazyString(UIStrings.debugWithAi),
249
+ title: i18nAiBrandedString(UIStrings.debugWithGemini, UIStrings.debugWithAi),
229
250
  configurableBindings: false,
230
251
  async loadActionDelegate() {
231
252
  const AiAssistance = await loadAiAssistanceModule();
@@ -241,7 +262,7 @@ UI.ActionRegistration.registerActionExtension({
241
262
  return [];
242
263
  },
243
264
  category: UI.ActionRegistration.ActionCategory.GLOBAL,
244
- title: i18nLazyString(UIStrings.debugWithAi),
265
+ title: i18nAiBrandedString(UIStrings.debugWithGemini, UIStrings.debugWithAi),
245
266
  configurableBindings: false,
246
267
  async loadActionDelegate() {
247
268
  const AiAssistance = await loadAiAssistanceModule();
@@ -256,7 +277,7 @@ UI.ActionRegistration.registerActionExtension({
256
277
  return [];
257
278
  },
258
279
  category: UI.ActionRegistration.ActionCategory.GLOBAL,
259
- title: i18nLazyString(UIStrings.debugWithAi),
280
+ title: i18nAiBrandedString(UIStrings.debugWithGemini, UIStrings.debugWithAi),
260
281
  configurableBindings: false,
261
282
  async loadActionDelegate() {
262
283
  const AiAssistance = await loadAiAssistanceModule();
@@ -292,6 +292,8 @@ export const DEFAULT_VIEW = (input: ChatMessageViewInput, output: ViewOutput, ta
292
292
  return;
293
293
  }
294
294
 
295
+ const icon = AiAssistanceModel.AiUtils.getIconName();
296
+
295
297
  // clang-format off
296
298
  Lit.render(html`
297
299
  <style>${Input.textInputStyles}</style>
@@ -301,7 +303,7 @@ export const DEFAULT_VIEW = (input: ChatMessageViewInput, output: ViewOutput, ta
301
303
  jslog=${VisualLogging.section('answer')}
302
304
  >
303
305
  <div class="message-info">
304
- <devtools-icon name="smart-assistant"></devtools-icon>
306
+ <devtools-icon name=${icon}></devtools-icon>
305
307
  <div class="message-name">
306
308
  <h2>${lockedString(UIStringsNotTranslate.ai)}</h2>
307
309
  </div>
@@ -7,7 +7,7 @@ import '../../../ui/components/spinners/spinners.js';
7
7
  import * as Host from '../../../core/host/host.js';
8
8
  import * as i18n from '../../../core/i18n/i18n.js';
9
9
  import type * as Platform from '../../../core/platform/platform.js';
10
- import type * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
10
+ import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
11
11
  import * as Buttons from '../../../ui/components/buttons/buttons.js';
12
12
  import type {MarkdownLitRenderer} from '../../../ui/components/markdown_view/MarkdownView.js';
13
13
  import * as UI from '../../../ui/legacy/legacy.js';
@@ -30,6 +30,10 @@ const UIStringsNotTranslate = {
30
30
  * @description Text for the empty state of the AI assistance panel.
31
31
  */
32
32
  emptyStateText: 'How can I help you?',
33
+ /**
34
+ * @description Text for the empty state of the Gemini panel.
35
+ */
36
+ emptyStateTextGemini: 'Where should we start?',
33
37
  } as const;
34
38
 
35
39
  const lockedString = i18n.i18n.lockedString;
@@ -74,12 +78,18 @@ export interface Props {
74
78
  }
75
79
 
76
80
  interface ChatWidgetInput extends Props {
81
+ accountName: string;
77
82
  handleScroll: (ev: Event) => void;
78
83
  handleSuggestionClick: (title: string) => void;
79
84
  handleMessageContainerRef: (el: Element|undefined) => void;
80
85
  }
81
86
 
82
87
  const DEFAULT_VIEW: View = (input, output, target) => {
88
+ const chatUiClasses = classMap({
89
+ 'chat-ui': true,
90
+ gemini: AiAssistanceModel.AiUtils.isGeminiBranding(),
91
+ });
92
+
83
93
  const inputWidgetClasses = classMap({
84
94
  'chat-input-widget': true,
85
95
  sticky: !input.isReadOnly,
@@ -88,7 +98,7 @@ const DEFAULT_VIEW: View = (input, output, target) => {
88
98
  // clang-format off
89
99
  render(html`
90
100
  <style>${chatViewStyles}</style>
91
- <div class="chat-ui">
101
+ <div class=${chatUiClasses}>
92
102
  <main @scroll=${input.handleScroll} ${ref(element => { output.mainElement = element as HTMLElement; } )}>
93
103
  ${input.messages.length > 0 ? html`
94
104
  <div class="messages-container" ${ref(input.handleMessageContainerRef)}>
@@ -121,7 +131,12 @@ const DEFAULT_VIEW: View = (input, output, target) => {
121
131
  name="smart-assistant"
122
132
  ></devtools-icon>
123
133
  </div>
124
- <h1>${lockedString(UIStringsNotTranslate.emptyStateText)}</h1>
134
+ ${AiAssistanceModel.AiUtils.isGeminiBranding() ?
135
+ html`
136
+ <h1 class='greeting'>Hello, ${input.accountName}</h1>
137
+ <h1>${lockedString(UIStringsNotTranslate.emptyStateTextGemini)}</h1>
138
+ ` : html`<h1>${lockedString(UIStringsNotTranslate.emptyStateText)}</h1>`
139
+ }
125
140
  </div>
126
141
  <div class="empty-state-content">
127
142
  ${input.emptyStateSuggestions.map(({title, jslogContext}) => {
@@ -308,6 +323,8 @@ export class ChatView extends HTMLElement {
308
323
  this.#view(
309
324
  {
310
325
  ...this.#props,
326
+ // TODO(b/468206227): This needs to be a first name.
327
+ accountName: this.#props.userInfo.accountFullName ?? '',
311
328
  handleScroll: this.#handleScroll,
312
329
  handleSuggestionClick: this.#handleSuggestionClick,
313
330
  handleMessageContainerRef: this.#handleMessageContainerRef,
@@ -165,7 +165,27 @@ main {
165
165
  }
166
166
  }
167
167
 
168
+ .gemini {
169
+ .empty-state-container .icon {
170
+ display: none;
171
+ }
172
+
173
+ .empty-state-container .header {
174
+ align-items: flex-start;
175
+ }
176
+
177
+ .empty-state-content {
178
+ align-items: flex-start
179
+ }
180
+
181
+ .empty-state-container .greeting {
182
+ color: var(--sys-color-primary);
183
+ }
168
184
 
185
+ main {
186
+ align-items: flex-start;
187
+ }
188
+ }
169
189
 
170
190
  .change-summary {
171
191
  background-color: var(--sys-color-surface3);
@@ -644,7 +644,7 @@ function renderIdentity(identityData: IdentitySectionData, onCopy: () => void, o
644
644
  jslog=${VisualLogging.action('help').track({hover: true})}>
645
645
  </devtools-icon>
646
646
  <devtools-link href="https://developer.chrome.com/blog/pwa-manifest-id/"
647
- .jslogContext=${'learn-more'}
647
+ jslogcontext="learn-more"
648
648
  ${ref(setFocusOnSection(i18nString(UIStrings.identity), output))}>
649
649
  ${i18nString(UIStrings.learnMore)}
650
650
  </devtools-link>
@@ -766,7 +766,7 @@ function renderIcons(
766
766
  <div class="report-row">
767
767
  ${i18nTemplate(str_, UIStrings.needHelpReadOurS, {
768
768
  PH1: html`
769
- <devtools-link href="https://web.dev/maskable-icon/" .jslogContext=${'learn-more'}>
769
+ <devtools-link href="https://web.dev/maskable-icon/" jslogcontext="learn-more">
770
770
  ${i18nString(UIStrings.documentationOnMaskableIcons)}
771
771
  </devtools-link>`,
772
772
  })}
@@ -866,7 +866,7 @@ function renderWindowControlsSection(
866
866
  PH2: html`<code>
867
867
  <devtools-link
868
868
  href="https://developer.mozilla.org/en-US/docs/Web/Manifest/display_override"
869
- .jslogContext=${'display-override'}
869
+ jslogcontext="display-override"
870
870
  ${ref(setFocusOnSection(i18nString(UIStrings.windowControlsOverlay), output))}>
871
871
  display-override
872
872
  </devtools-link>
@@ -882,7 +882,7 @@ function renderWindowControlsSection(
882
882
  ${i18nTemplate(str_, UIStrings.wcoNotFound, {PH1: html`<code>
883
883
  <devtools-link
884
884
  href="https://developer.mozilla.org/en-US/docs/Web/Manifest/display_override"
885
- .jslogContext=${'display-override'}
885
+ jslogcontext="display-override"
886
886
  ${ref(setFocusOnSection(i18nString(UIStrings.windowControlsOverlay), output))}>
887
887
  display-override
888
888
  </devtools-link>
@@ -891,7 +891,7 @@ function renderWindowControlsSection(
891
891
  <div class="report-row">
892
892
  ${i18nTemplate(str_, UIStrings.wcoNeedHelpReadMore, {PH1: html`<devtools-link
893
893
  href="https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/window-controls-overlay"
894
- .jslogContext=${'customize-pwa-tittle-bar'}>
894
+ jslogcontext="customize-pwa-tittle-bar">
895
895
  ${i18nString(UIStrings.customizePwaTitleBar)}
896
896
  </devtools-link>`})}
897
897
  </div>
@@ -13,6 +13,7 @@ interface EventWithTimestamp {
13
13
  export interface SessionAndEvents {
14
14
  session?: Protocol.Network.DeviceBoundSession;
15
15
  isSessionTerminated: boolean;
16
+ hasErrors: boolean;
16
17
  eventsById: Map<string, EventWithTimestamp>;
17
18
  }
18
19
  type SessionIdToSessionMap = Map<string|undefined, SessionAndEvents>;
@@ -61,11 +62,21 @@ export class DeviceBoundSessionsModel extends Common.ObjectWrapper.ObjectWrapper
61
62
  return;
62
63
  }
63
64
  const emptySessions = new Map<string, Array<string|undefined>>();
65
+ const noLongerFailedSessions = new Map<string, Array<string|undefined>>();
64
66
  const emptySites = new Set<string>();
65
67
  for (const [site, sessionIdToSessionMap] of [...this.#siteSessions]) {
66
68
  let emptySessionsSiteEntry = emptySessions.get(site);
69
+ let noLongerFailedSessionsSiteEntry = noLongerFailedSessions.get(site);
67
70
  for (const [sessionId, sessionAndEvents] of sessionIdToSessionMap) {
68
71
  sessionAndEvents.eventsById.clear();
72
+ if (sessionAndEvents.hasErrors) {
73
+ sessionAndEvents.hasErrors = false;
74
+ if (!noLongerFailedSessionsSiteEntry) {
75
+ noLongerFailedSessionsSiteEntry = [];
76
+ noLongerFailedSessions.set(site, noLongerFailedSessionsSiteEntry);
77
+ }
78
+ noLongerFailedSessionsSiteEntry.push(sessionId);
79
+ }
69
80
  if (sessionAndEvents.session) {
70
81
  continue;
71
82
  }
@@ -85,7 +96,8 @@ export class DeviceBoundSessionsModel extends Common.ObjectWrapper.ObjectWrapper
85
96
  }
86
97
  }
87
98
 
88
- this.dispatchEventToListeners(DeviceBoundSessionModelEvents.CLEAR_EVENTS, {emptySessions, emptySites});
99
+ this.dispatchEventToListeners(
100
+ DeviceBoundSessionModelEvents.CLEAR_EVENTS, {emptySessions, emptySites, noLongerFailedSessions});
89
101
  }
90
102
 
91
103
  isSiteVisible(site: string): boolean {
@@ -100,6 +112,14 @@ export class DeviceBoundSessionsModel extends Common.ObjectWrapper.ObjectWrapper
100
112
  return session.isSessionTerminated;
101
113
  }
102
114
 
115
+ sessionHasErrors(site: string, sessionId?: string): boolean {
116
+ const session = this.getSession(site, sessionId);
117
+ if (session === undefined) {
118
+ return false;
119
+ }
120
+ return session.hasErrors;
121
+ }
122
+
103
123
  getSession(site: string, sessionId?: string): SessionAndEvents|undefined {
104
124
  return this.#siteSessions.get(site)?.get(sessionId);
105
125
  }
@@ -128,6 +148,7 @@ export class DeviceBoundSessionsModel extends Common.ObjectWrapper.ObjectWrapper
128
148
  sessionAndEvent = {
129
149
  session: undefined,
130
150
  isSessionTerminated: false,
151
+ hasErrors: false,
131
152
  eventsById: new Map<string, EventWithTimestamp>()
132
153
  };
133
154
  sessionIdToSessionMap.set(sessionId, sessionAndEvent);
@@ -167,6 +188,11 @@ export class DeviceBoundSessionsModel extends Common.ObjectWrapper.ObjectWrapper
167
188
  }
168
189
  }
169
190
 
191
+ // Set that the session has errors if the latest event failed.
192
+ if (!event.succeeded) {
193
+ sessionAndEvent.hasErrors = true;
194
+ }
195
+
170
196
  this.dispatchEventToListeners(
171
197
  DeviceBoundSessionModelEvents.EVENT_OCCURRED,
172
198
  {site: eventWithTimestamp.event.site, sessionId: eventWithTimestamp.event.sessionId});
@@ -186,6 +212,9 @@ export interface DeviceBoundSessionModelEventTypes {
186
212
  [DeviceBoundSessionModelEvents.ADD_VISIBLE_SITE]: {site: string};
187
213
  [DeviceBoundSessionModelEvents.CLEAR_VISIBLE_SITES]: void;
188
214
  [DeviceBoundSessionModelEvents.EVENT_OCCURRED]: {site: string, sessionId?: string};
189
- [DeviceBoundSessionModelEvents.CLEAR_EVENTS]:
190
- {emptySessions: Map<string, Array<string|undefined>>, emptySites: Set<string>};
215
+ [DeviceBoundSessionModelEvents.CLEAR_EVENTS]: {
216
+ emptySessions: Map<string, Array<string|undefined>>,
217
+ emptySites: Set<string>,
218
+ noLongerFailedSessions: Map<string, Array<string|undefined>>,
219
+ };
191
220
  }