chrome-devtools-frontend 1.0.964440 → 1.0.966086

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 (195) hide show
  1. package/config/gni/devtools_grd_files.gni +11 -5
  2. package/front_end/core/common/ResolverBase.ts +2 -2
  3. package/front_end/core/i18n/locales/af.json +55 -22
  4. package/front_end/core/i18n/locales/am.json +55 -22
  5. package/front_end/core/i18n/locales/ar.json +55 -22
  6. package/front_end/core/i18n/locales/as.json +55 -22
  7. package/front_end/core/i18n/locales/az.json +55 -22
  8. package/front_end/core/i18n/locales/be.json +55 -22
  9. package/front_end/core/i18n/locales/bg.json +55 -22
  10. package/front_end/core/i18n/locales/bn.json +33 -0
  11. package/front_end/core/i18n/locales/bs.json +53 -20
  12. package/front_end/core/i18n/locales/ca.json +55 -22
  13. package/front_end/core/i18n/locales/cs.json +54 -21
  14. package/front_end/core/i18n/locales/cy.json +55 -22
  15. package/front_end/core/i18n/locales/da.json +54 -21
  16. package/front_end/core/i18n/locales/de.json +55 -22
  17. package/front_end/core/i18n/locales/el.json +55 -22
  18. package/front_end/core/i18n/locales/en-GB.json +33 -0
  19. package/front_end/core/i18n/locales/en-US.json +21 -0
  20. package/front_end/core/i18n/locales/en-XL.json +21 -0
  21. package/front_end/core/i18n/locales/es-419.json +55 -22
  22. package/front_end/core/i18n/locales/es.json +55 -22
  23. package/front_end/core/i18n/locales/et.json +55 -22
  24. package/front_end/core/i18n/locales/eu.json +33 -0
  25. package/front_end/core/i18n/locales/fa.json +56 -23
  26. package/front_end/core/i18n/locales/fi.json +55 -22
  27. package/front_end/core/i18n/locales/fil.json +55 -22
  28. package/front_end/core/i18n/locales/fr-CA.json +55 -22
  29. package/front_end/core/i18n/locales/fr.json +55 -22
  30. package/front_end/core/i18n/locales/gl.json +55 -22
  31. package/front_end/core/i18n/locales/gu.json +33 -0
  32. package/front_end/core/i18n/locales/he.json +55 -22
  33. package/front_end/core/i18n/locales/hi.json +33 -0
  34. package/front_end/core/i18n/locales/hr.json +33 -0
  35. package/front_end/core/i18n/locales/hu.json +55 -22
  36. package/front_end/core/i18n/locales/hy.json +55 -22
  37. package/front_end/core/i18n/locales/id.json +55 -22
  38. package/front_end/core/i18n/locales/is.json +55 -22
  39. package/front_end/core/i18n/locales/it.json +55 -22
  40. package/front_end/core/i18n/locales/ja.json +63 -30
  41. package/front_end/core/i18n/locales/ka.json +55 -22
  42. package/front_end/core/i18n/locales/kk.json +55 -22
  43. package/front_end/core/i18n/locales/km.json +55 -22
  44. package/front_end/core/i18n/locales/kn.json +55 -22
  45. package/front_end/core/i18n/locales/ko.json +55 -22
  46. package/front_end/core/i18n/locales/ky.json +55 -22
  47. package/front_end/core/i18n/locales/lo.json +55 -22
  48. package/front_end/core/i18n/locales/lt.json +55 -22
  49. package/front_end/core/i18n/locales/lv.json +55 -22
  50. package/front_end/core/i18n/locales/mk.json +55 -22
  51. package/front_end/core/i18n/locales/ml.json +33 -0
  52. package/front_end/core/i18n/locales/mn.json +33 -0
  53. package/front_end/core/i18n/locales/mr.json +54 -21
  54. package/front_end/core/i18n/locales/ms.json +55 -22
  55. package/front_end/core/i18n/locales/my.json +55 -22
  56. package/front_end/core/i18n/locales/ne.json +54 -21
  57. package/front_end/core/i18n/locales/nl.json +55 -22
  58. package/front_end/core/i18n/locales/no.json +55 -22
  59. package/front_end/core/i18n/locales/or.json +55 -22
  60. package/front_end/core/i18n/locales/pa.json +55 -22
  61. package/front_end/core/i18n/locales/pl.json +33 -0
  62. package/front_end/core/i18n/locales/pt-PT.json +55 -22
  63. package/front_end/core/i18n/locales/pt.json +55 -22
  64. package/front_end/core/i18n/locales/ro.json +33 -0
  65. package/front_end/core/i18n/locales/ru.json +55 -22
  66. package/front_end/core/i18n/locales/si.json +55 -22
  67. package/front_end/core/i18n/locales/sk.json +55 -22
  68. package/front_end/core/i18n/locales/sl.json +55 -22
  69. package/front_end/core/i18n/locales/sq.json +55 -22
  70. package/front_end/core/i18n/locales/sr-Latn.json +55 -22
  71. package/front_end/core/i18n/locales/sr.json +55 -22
  72. package/front_end/core/i18n/locales/sv.json +55 -22
  73. package/front_end/core/i18n/locales/sw.json +55 -22
  74. package/front_end/core/i18n/locales/ta.json +55 -22
  75. package/front_end/core/i18n/locales/te.json +42 -9
  76. package/front_end/core/i18n/locales/th.json +33 -0
  77. package/front_end/core/i18n/locales/tr.json +55 -22
  78. package/front_end/core/i18n/locales/uk.json +55 -22
  79. package/front_end/core/i18n/locales/ur.json +55 -22
  80. package/front_end/core/i18n/locales/uz.json +55 -22
  81. package/front_end/core/i18n/locales/vi.json +54 -21
  82. package/front_end/core/i18n/locales/zh-HK.json +55 -22
  83. package/front_end/core/i18n/locales/zh-TW.json +54 -21
  84. package/front_end/core/i18n/locales/zh.json +55 -22
  85. package/front_end/core/i18n/locales/zu.json +55 -22
  86. package/front_end/core/protocol_client/InspectorBackend.ts +8 -0
  87. package/front_end/core/sdk/CSSProperty.ts +8 -8
  88. package/front_end/core/sdk/NetworkManager.ts +58 -70
  89. package/front_end/core/sdk/RemoteObject.ts +1 -1
  90. package/front_end/core/sdk/Resource.ts +5 -2
  91. package/front_end/core/sdk/RuntimeModel.ts +10 -0
  92. package/front_end/entrypoints/formatter_worker/formatter_worker.ts +4 -4
  93. package/front_end/legacy_test_runner/bindings_test_runner/PersistenceTestRunner.js +2 -2
  94. package/front_end/legacy_test_runner/console_test_runner/console_test_runner.js +9 -3
  95. package/front_end/legacy_test_runner/heap_profiler_test_runner/heap_profiler_test_runner.js +1 -2
  96. package/front_end/legacy_test_runner/sources_test_runner/DebuggerTestRunner.js +5 -5
  97. package/front_end/models/bindings/ContentProviderBasedProject.ts +2 -3
  98. package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +1 -1
  99. package/front_end/models/persistence/IsolatedFileSystem.ts +2 -2
  100. package/front_end/models/persistence/NetworkPersistenceManager.ts +7 -4
  101. package/front_end/models/workspace/WorkspaceImpl.ts +62 -37
  102. package/front_end/panels/application/ApplicationPanelSidebar.ts +41 -1
  103. package/front_end/panels/application/InterestGroupStorageModel.ts +87 -0
  104. package/front_end/panels/application/InterestGroupStorageView.ts +112 -0
  105. package/front_end/panels/application/InterestGroupTreeElement.ts +61 -0
  106. package/front_end/panels/application/application.ts +4 -0
  107. package/front_end/panels/application/components/InterestGroupAccessGrid.ts +149 -0
  108. package/front_end/panels/application/components/components.ts +2 -0
  109. package/front_end/panels/application/components/interestGroupAccessGrid.css +26 -0
  110. package/front_end/panels/application/interestGroupStorageView.css +13 -0
  111. package/front_end/panels/console/ConsoleViewMessage.ts +33 -6
  112. package/front_end/panels/console/ErrorStackParser.ts +34 -0
  113. package/front_end/panels/emulation/DeviceModeView.ts +6 -2
  114. package/front_end/panels/event_listeners/EventListenersUtils.ts +3 -2
  115. package/front_end/panels/event_listeners/EventListenersView.ts +3 -3
  116. package/front_end/panels/lighthouse/lighthouse.ts +1 -1
  117. package/front_end/panels/sources/DebuggerPausedMessage.ts +2 -2
  118. package/front_end/panels/sources/SourcesPanel.ts +7 -10
  119. package/front_end/panels/sources/UISourceCodeFrame.ts +11 -4
  120. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +1 -2
  121. package/front_end/panels/sources/debuggerPausedMessage.css +5 -1
  122. package/front_end/third_party/codemirror/README.chromium +5 -0
  123. package/front_end/third_party/codemirror/codemirror-tsconfig.json +4 -4
  124. package/front_end/third_party/codemirror/package/addon/runmode/{runmode-standalone.js → runmode-standalone.mjs} +0 -0
  125. package/front_end/third_party/codemirror/package/addon/runmode/{runmode-standalone.d.ts → runmode-standalone.mjs.d.ts} +0 -0
  126. package/front_end/third_party/codemirror/package/mode/css/{css.js → css.mjs} +0 -0
  127. package/front_end/third_party/codemirror/package/mode/css/{css.d.ts → css.mjs.d.ts} +0 -0
  128. package/front_end/third_party/codemirror/package/mode/javascript/{javascript.js → javascript.mjs} +0 -0
  129. package/front_end/third_party/codemirror/package/mode/javascript/{javascript.d.ts → javascript.mjs.d.ts} +0 -0
  130. package/front_end/third_party/codemirror/package/mode/xml/{xml.js → xml.mjs} +0 -0
  131. package/front_end/third_party/codemirror/package/mode/xml/{xml.d.ts → xml.mjs.d.ts} +0 -0
  132. package/front_end/third_party/lighthouse/README.chromium +2 -0
  133. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +954 -885
  134. package/front_end/third_party/lighthouse/lighthouse-tsconfig.json +1 -1
  135. package/front_end/third_party/lighthouse/locales/ar-XB.json +40 -4
  136. package/front_end/third_party/lighthouse/locales/ar.json +59 -23
  137. package/front_end/third_party/lighthouse/locales/bg.json +40 -4
  138. package/front_end/third_party/lighthouse/locales/ca.json +45 -9
  139. package/front_end/third_party/lighthouse/locales/cs.json +39 -3
  140. package/front_end/third_party/lighthouse/locales/da.json +43 -7
  141. package/front_end/third_party/lighthouse/locales/de.json +42 -6
  142. package/front_end/third_party/lighthouse/locales/el.json +59 -23
  143. package/front_end/third_party/lighthouse/locales/en-GB.json +43 -7
  144. package/front_end/third_party/lighthouse/locales/en-US.json +48 -6
  145. package/front_end/third_party/lighthouse/locales/en-XA.json +40 -4
  146. package/front_end/third_party/lighthouse/locales/en-XL.json +48 -6
  147. package/front_end/third_party/lighthouse/locales/es-419.json +39 -3
  148. package/front_end/third_party/lighthouse/locales/es.json +46 -10
  149. package/front_end/third_party/lighthouse/locales/fi.json +57 -21
  150. package/front_end/third_party/lighthouse/locales/fil.json +40 -4
  151. package/front_end/third_party/lighthouse/locales/fr.json +45 -9
  152. package/front_end/third_party/lighthouse/locales/he.json +41 -5
  153. package/front_end/third_party/lighthouse/locales/hi.json +59 -23
  154. package/front_end/third_party/lighthouse/locales/hr.json +57 -21
  155. package/front_end/third_party/lighthouse/locales/hu.json +39 -3
  156. package/front_end/third_party/lighthouse/locales/id.json +40 -4
  157. package/front_end/third_party/lighthouse/locales/it.json +40 -4
  158. package/front_end/third_party/lighthouse/locales/ja.json +39 -3
  159. package/front_end/third_party/lighthouse/locales/ko.json +40 -4
  160. package/front_end/third_party/lighthouse/locales/lt.json +40 -4
  161. package/front_end/third_party/lighthouse/locales/lv.json +56 -20
  162. package/front_end/third_party/lighthouse/locales/nl.json +40 -4
  163. package/front_end/third_party/lighthouse/locales/no.json +56 -20
  164. package/front_end/third_party/lighthouse/locales/pl.json +56 -20
  165. package/front_end/third_party/lighthouse/locales/pt-PT.json +57 -21
  166. package/front_end/third_party/lighthouse/locales/pt.json +41 -5
  167. package/front_end/third_party/lighthouse/locales/ro.json +39 -3
  168. package/front_end/third_party/lighthouse/locales/ru.json +40 -4
  169. package/front_end/third_party/lighthouse/locales/sk.json +39 -3
  170. package/front_end/third_party/lighthouse/locales/sl.json +39 -3
  171. package/front_end/third_party/lighthouse/locales/sr-Latn.json +40 -4
  172. package/front_end/third_party/lighthouse/locales/sr.json +40 -4
  173. package/front_end/third_party/lighthouse/locales/sv.json +39 -3
  174. package/front_end/third_party/lighthouse/locales/ta.json +47 -11
  175. package/front_end/third_party/lighthouse/locales/te.json +61 -25
  176. package/front_end/third_party/lighthouse/locales/th.json +39 -3
  177. package/front_end/third_party/lighthouse/locales/tr.json +40 -4
  178. package/front_end/third_party/lighthouse/locales/uk.json +40 -4
  179. package/front_end/third_party/lighthouse/locales/vi.json +63 -27
  180. package/front_end/third_party/lighthouse/locales/zh-HK.json +40 -4
  181. package/front_end/third_party/lighthouse/locales/zh-TW.json +45 -9
  182. package/front_end/third_party/lighthouse/locales/zh.json +41 -5
  183. package/front_end/third_party/lighthouse/report/bundle.d.ts +1 -0
  184. package/front_end/third_party/lighthouse/report/bundle.js +23 -11
  185. package/front_end/third_party/lighthouse/report-assets/{report-generator.js → report-generator.mjs} +1 -1
  186. package/front_end/third_party/lighthouse/report-assets/{report-generator.d.ts → report-generator.mjs.d.ts} +0 -0
  187. package/front_end/ui/components/docs/tree_outline/custom-renderers.ts +3 -3
  188. package/front_end/ui/legacy/Icon.ts +2 -2
  189. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +4 -4
  190. package/front_end/ui/legacy/components/perf_ui/LiveHeapProfile.ts +2 -2
  191. package/front_end/ui/legacy/themeColors.css +1 -1
  192. package/package.json +1 -1
  193. package/scripts/build/devtools_plugin.js +10 -0
  194. package/scripts/build/esbuild.js +62 -0
  195. package/scripts/build/ninja/bundle.gni +77 -32
@@ -50,6 +50,7 @@ ConsoleTestRunner.dumpConsoleMessagesIntoArray = async function(printOriginating
50
50
  const element = uiMessage.element();
51
51
  // Retrieving the message element triggered rendering, now wait for
52
52
  // the live location within to be resolved initially.
53
+ await uiMessage.formatErrorStackPromiseForTest();
53
54
  await TestRunner.waitForPendingLiveLocationUpdates();
54
55
 
55
56
  let classNames;
@@ -220,9 +221,14 @@ ConsoleTestRunner.evaluateInConsole = function(code, callback, dontForceMainCont
220
221
  const element = commandResult.toMessageElement();
221
222
  // Only call the callback once the live location within the
222
223
  // message element is resolved initially.
223
- TestRunner.waitForPendingLiveLocationUpdates().then(() => {
224
- callback(element.deepTextContent());
225
- });
224
+ Promise
225
+ .all([
226
+ commandResult.formatErrorStackPromiseForTest(),
227
+ TestRunner.waitForPendingLiveLocationUpdates(),
228
+ ])
229
+ .then(() => {
230
+ callback(element.deepTextContent());
231
+ });
226
232
  });
227
233
  };
228
234
 
@@ -624,14 +624,13 @@ HeapProfilerTestRunner.takeAndOpenSnapshot = async function(generator, callback)
624
624
  const snapshot = generator();
625
625
  const profileType = Profiler.ProfileTypeRegistry.instance.heapSnapshotProfileType;
626
626
 
627
- function pushGeneratedSnapshot(reportProgress) {
627
+ async function pushGeneratedSnapshot(reportProgress) {
628
628
  if (reportProgress) {
629
629
  profileType.reportHeapSnapshotProgress({data: {done: 50, total: 100, finished: false}});
630
630
  profileType.reportHeapSnapshotProgress({data: {done: 100, total: 100, finished: true}});
631
631
  }
632
632
  snapshot.snapshot.typeId = 'HEAP';
633
633
  profileType.addHeapSnapshotChunk({data: JSON.stringify(snapshot)});
634
- return Promise.resolve();
635
634
  }
636
635
 
637
636
  HeapProfilerTestRunner.takeAndOpenSnapshotCallback = callback;
@@ -198,31 +198,31 @@ SourcesTestRunner.waitUntilPausedAndDumpStackAndResume = function(callback, opti
198
198
  };
199
199
 
200
200
  SourcesTestRunner.stepOver = function() {
201
- Promise.resolve().then(function() {
201
+ queueMicrotask(function() {
202
202
  UI.panels.sources.stepOver();
203
203
  });
204
204
  };
205
205
 
206
206
  SourcesTestRunner.stepInto = function() {
207
- Promise.resolve().then(function() {
207
+ queueMicrotask(function() {
208
208
  UI.panels.sources.stepInto();
209
209
  });
210
210
  };
211
211
 
212
212
  SourcesTestRunner.stepIntoAsync = function() {
213
- Promise.resolve().then(function() {
213
+ queueMicrotask(function() {
214
214
  UI.panels.sources.stepIntoAsync();
215
215
  });
216
216
  };
217
217
 
218
218
  SourcesTestRunner.stepOut = function() {
219
- Promise.resolve().then(function() {
219
+ queueMicrotask(function() {
220
220
  UI.panels.sources.stepOut();
221
221
  });
222
222
  };
223
223
 
224
224
  SourcesTestRunner.togglePause = function() {
225
- Promise.resolve().then(function() {
225
+ queueMicrotask(function() {
226
226
  UI.panels.sources.togglePause();
227
227
  });
228
228
  };
@@ -46,8 +46,7 @@ interface UISourceCodeData {
46
46
  metadata: Workspace.UISourceCode.UISourceCodeMetadata|null;
47
47
  }
48
48
 
49
- export class ContentProviderBasedProject extends Workspace.Workspace.ProjectStore implements
50
- Workspace.Workspace.Project {
49
+ export class ContentProviderBasedProject extends Workspace.Workspace.ProjectStore {
51
50
  readonly #contentProviders: Map<string, TextUtils.ContentProvider.ContentProvider>;
52
51
  readonly #isServiceProjectInternal: boolean;
53
52
  readonly #uiSourceCodeToData: WeakMap<Workspace.UISourceCode.UISourceCode, UISourceCodeData>;
@@ -199,7 +198,7 @@ export class ContentProviderBasedProject extends Workspace.Workspace.ProjectStor
199
198
  }
200
199
 
201
200
  indexContent(progress: Common.Progress.Progress): void {
202
- void Promise.resolve().then(progress.done.bind(progress));
201
+ queueMicrotask(progress.done.bind(progress));
203
202
  }
204
203
 
205
204
  addUISourceCodeWithProvider(
@@ -153,7 +153,7 @@ export class FileSystemWorkspaceBinding {
153
153
  }
154
154
  }
155
155
 
156
- export class FileSystem extends Workspace.Workspace.ProjectStore implements Workspace.Workspace.Project {
156
+ export class FileSystem extends Workspace.Workspace.ProjectStore {
157
157
  readonly fileSystemInternal: PlatformFileSystem;
158
158
  readonly fileSystemBaseURL: string;
159
159
  private readonly fileSystemParentURL: string;
@@ -98,12 +98,12 @@ export class IsolatedFileSystem extends PlatformFileSystem {
98
98
  this.fileLocks = new Map();
99
99
  }
100
100
 
101
- static create(
101
+ static async create(
102
102
  manager: IsolatedFileSystemManager, path: string, embedderPath: string, type: string, name: string,
103
103
  rootURL: string): Promise<IsolatedFileSystem|null> {
104
104
  const domFileSystem = Host.InspectorFrontendHost.InspectorFrontendHostInstance.isolatedFileSystem(name, rootURL);
105
105
  if (!domFileSystem) {
106
- return Promise.resolve(null as IsolatedFileSystem | null);
106
+ return null as IsolatedFileSystem | null;
107
107
  }
108
108
 
109
109
  const fileSystem = new IsolatedFileSystem(manager, path, embedderPath, domFileSystem, type);
@@ -383,8 +383,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
383
383
 
384
384
  return SDK.NetworkManager.MultitargetNetworkManager.instance().setInterceptionHandlerForPatterns(
385
385
  Array.from(patterns).map(
386
- pattern =>
387
- ({urlPattern: pattern, interceptionStage: Protocol.Network.InterceptionStage.HeadersReceived})),
386
+ pattern => ({urlPattern: pattern, requestStage: Protocol.Fetch.RequestStage.Response})),
388
387
  this.interceptionHandlerBound);
389
388
  }
390
389
  }
@@ -467,8 +466,12 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
467
466
 
468
467
  let mimeType = '';
469
468
  if (interceptedRequest.responseHeaders) {
470
- const responseHeaders = SDK.NetworkManager.NetworkManager.lowercaseHeaders(interceptedRequest.responseHeaders);
471
- mimeType = responseHeaders['content-type'];
469
+ for (const header of interceptedRequest.responseHeaders) {
470
+ if (header.name.toLowerCase() === 'content-type') {
471
+ mimeType = header.value;
472
+ break;
473
+ }
474
+ }
472
475
  }
473
476
 
474
477
  if (!mimeType) {
@@ -42,41 +42,36 @@ export interface ProjectSearchConfig {
42
42
  filePathMatchesFileQuery(filePath: string): boolean;
43
43
  }
44
44
 
45
- export abstract class Project {
46
- abstract workspace(): WorkspaceImpl;
47
- abstract id(): string;
48
- abstract type(): string;
49
- abstract isServiceProject(): boolean;
50
- abstract displayName(): string;
51
- abstract requestMetadata(uiSourceCode: UISourceCode): Promise<UISourceCodeMetadata|null>;
52
- abstract requestFileContent(uiSourceCode: UISourceCode): Promise<TextUtils.ContentProvider.DeferredContent>;
53
- abstract canSetFileContent(): boolean;
54
- abstract setFileContent(uiSourceCode: UISourceCode, newContent: string, isBase64: boolean): Promise<void>;
55
- abstract fullDisplayName(uiSourceCode: UISourceCode): string;
56
- abstract mimeType(uiSourceCode: UISourceCode): string;
57
- abstract canRename(): boolean;
45
+ export interface Project {
46
+ workspace(): WorkspaceImpl;
47
+ id(): string;
48
+ type(): projectTypes;
49
+ isServiceProject(): boolean;
50
+ displayName(): string;
51
+ requestMetadata(uiSourceCode: UISourceCode): Promise<UISourceCodeMetadata|null>;
52
+ requestFileContent(uiSourceCode: UISourceCode): Promise<TextUtils.ContentProvider.DeferredContent>;
53
+ canSetFileContent(): boolean;
54
+ setFileContent(uiSourceCode: UISourceCode, newContent: string, isBase64: boolean): Promise<void>;
55
+ fullDisplayName(uiSourceCode: UISourceCode): string;
56
+ mimeType(uiSourceCode: UISourceCode): string;
57
+ canRename(): boolean;
58
58
  rename(
59
- _uiSourceCode: UISourceCode, _newName: string,
60
- _callback: (arg0: boolean, arg1?: string, arg2?: string, arg3?: Common.ResourceType.ResourceType) => void): void {
61
- }
62
- excludeFolder(_path: string): void {
63
- }
64
- abstract canExcludeFolder(path: string): boolean;
65
- abstract createFile(path: string, name: string|null, content: string, isBase64?: boolean): Promise<UISourceCode|null>;
66
- abstract canCreateFile(): boolean;
67
- deleteFile(_uiSourceCode: UISourceCode): void {
68
- }
69
- remove(): void {
70
- }
71
- abstract searchInFileContent(uiSourceCode: UISourceCode, query: string, caseSensitive: boolean, isRegex: boolean):
59
+ uiSourceCode: UISourceCode, newName: string,
60
+ callback: (arg0: boolean, arg1?: string, arg2?: string, arg3?: Common.ResourceType.ResourceType) => void): void;
61
+ excludeFolder(path: string): void;
62
+ canExcludeFolder(path: string): boolean;
63
+ createFile(path: string, name: string|null, content: string, isBase64?: boolean): Promise<UISourceCode|null>;
64
+ canCreateFile(): boolean;
65
+ deleteFile(uiSourceCode: UISourceCode): void;
66
+ remove(): void;
67
+ searchInFileContent(uiSourceCode: UISourceCode, query: string, caseSensitive: boolean, isRegex: boolean):
72
68
  Promise<TextUtils.ContentProvider.SearchMatch[]>;
73
- abstract findFilesMatchingSearchRequest(
69
+ findFilesMatchingSearchRequest(
74
70
  searchConfig: ProjectSearchConfig, filesMathingFileQuery: string[],
75
71
  progress: Common.Progress.Progress): Promise<string[]>;
76
- indexContent(_progress: Common.Progress.Progress): void {
77
- }
78
- abstract uiSourceCodeForURL(url: string): UISourceCode|null;
79
- abstract uiSourceCodes(): UISourceCode[];
72
+ indexContent(progress: Common.Progress.Progress): void;
73
+ uiSourceCodeForURL(url: string): UISourceCode|null;
74
+ uiSourceCodes(): UISourceCode[];
80
75
  }
81
76
 
82
77
  // TODO(crbug.com/1167717): Make this a const enum again
@@ -90,7 +85,7 @@ export enum projectTypes {
90
85
  Service = 'service',
91
86
  }
92
87
 
93
- export class ProjectStore {
88
+ export abstract class ProjectStore implements Project {
94
89
  private readonly workspaceInternal: WorkspaceImpl;
95
90
  private readonly idInternal: string;
96
91
  private readonly typeInternal: projectTypes;
@@ -100,7 +95,6 @@ export class ProjectStore {
100
95
  index: number,
101
96
  }>;
102
97
  private uiSourceCodesList: UISourceCode[];
103
- private readonly project: Project;
104
98
 
105
99
  constructor(workspace: WorkspaceImpl, id: string, type: projectTypes, displayName: string) {
106
100
  this.workspaceInternal = workspace;
@@ -110,14 +104,13 @@ export class ProjectStore {
110
104
 
111
105
  this.uiSourceCodesMap = new Map();
112
106
  this.uiSourceCodesList = [];
113
- this.project = (this as unknown as Project);
114
107
  }
115
108
 
116
109
  id(): string {
117
110
  return this.idInternal;
118
111
  }
119
112
 
120
- type(): string {
113
+ type(): projectTypes {
121
114
  return this.typeInternal;
122
115
  }
123
116
 
@@ -130,7 +123,7 @@ export class ProjectStore {
130
123
  }
131
124
 
132
125
  createUISourceCode(url: string, contentType: Common.ResourceType.ResourceType): UISourceCode {
133
- return new UISourceCode(this.project, url, contentType);
126
+ return new UISourceCode(this, url, contentType);
134
127
  }
135
128
 
136
129
  addUISourceCode(uiSourceCode: UISourceCode): boolean {
@@ -166,7 +159,7 @@ export class ProjectStore {
166
159
  }
167
160
 
168
161
  removeProject(): void {
169
- this.workspaceInternal.removeProject(this.project);
162
+ this.workspaceInternal.removeProject(this);
170
163
  this.uiSourceCodesMap = new Map();
171
164
  this.uiSourceCodesList = [];
172
165
  }
@@ -190,6 +183,38 @@ export class ProjectStore {
190
183
  this.uiSourceCodesMap.set(newPath, value);
191
184
  this.uiSourceCodesMap.delete(oldPath);
192
185
  }
186
+
187
+ // No-op implementation for a handfull of interface methods.
188
+
189
+ rename(
190
+ _uiSourceCode: UISourceCode, _newName: string,
191
+ _callback: (arg0: boolean, arg1?: string, arg2?: string, arg3?: Common.ResourceType.ResourceType) => void): void {
192
+ }
193
+ excludeFolder(_path: string): void {
194
+ }
195
+ deleteFile(_uiSourceCode: UISourceCode): void {
196
+ }
197
+ remove(): void {
198
+ }
199
+ indexContent(_progress: Common.Progress.Progress): void {
200
+ }
201
+
202
+ abstract isServiceProject(): boolean;
203
+ abstract requestMetadata(uiSourceCode: UISourceCode): Promise<UISourceCodeMetadata|null>;
204
+ abstract requestFileContent(uiSourceCode: UISourceCode): Promise<TextUtils.ContentProvider.DeferredContent>;
205
+ abstract canSetFileContent(): boolean;
206
+ abstract setFileContent(uiSourceCode: UISourceCode, newContent: string, isBase64: boolean): Promise<void>;
207
+ abstract fullDisplayName(uiSourceCode: UISourceCode): string;
208
+ abstract mimeType(uiSourceCode: UISourceCode): string;
209
+ abstract canRename(): boolean;
210
+ abstract canExcludeFolder(path: string): boolean;
211
+ abstract createFile(path: string, name: string|null, content: string, isBase64?: boolean): Promise<UISourceCode|null>;
212
+ abstract canCreateFile(): boolean;
213
+ abstract searchInFileContent(uiSourceCode: UISourceCode, query: string, caseSensitive: boolean, isRegex: boolean):
214
+ Promise<TextUtils.ContentProvider.SearchMatch[]>;
215
+ abstract findFilesMatchingSearchRequest(
216
+ searchConfig: ProjectSearchConfig, filesMathingFileQuery: string[],
217
+ progress: Common.Progress.Progress): Promise<string[]>;
193
218
  }
194
219
 
195
220
  let workspaceInstance: WorkspaceImpl|undefined;
@@ -59,6 +59,8 @@ import {DOMStorageModel, Events as DOMStorageModelEvents} from './DOMStorageMode
59
59
  import type {Database as IndexedDBModelDatabase, DatabaseId, Index, ObjectStore} from './IndexedDBModel.js';
60
60
  import {Events as IndexedDBModelEvents, IndexedDBModel} from './IndexedDBModel.js';
61
61
  import {IDBDatabaseView, IDBDataView} from './IndexedDBViews.js';
62
+ import {InterestGroupStorageModel, Events as InterestGroupModelEvents} from './InterestGroupStorageModel.js';
63
+ import {InterestGroupTreeElement} from './InterestGroupTreeElement.js';
62
64
  import {OpenedWindowDetailsView, WorkerDetailsView} from './OpenedWindowDetailsView.js';
63
65
  import type {ResourcesPanel} from './ResourcesPanel.js';
64
66
  import {ServiceWorkersView} from './ServiceWorkersView.js';
@@ -186,6 +188,7 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
186
188
  localStorageListTreeElement: ExpandableApplicationPanelTreeElement;
187
189
  sessionStorageListTreeElement: ExpandableApplicationPanelTreeElement;
188
190
  indexedDBListTreeElement: IndexedDBTreeElement;
191
+ interestGroupTreeElement: InterestGroupTreeElement;
189
192
  databasesListTreeElement: ExpandableApplicationPanelTreeElement;
190
193
  cookieListTreeElement: ExpandableApplicationPanelTreeElement;
191
194
  trustTokensTreeElement: TrustTokensTreeElement;
@@ -276,6 +279,9 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
276
279
  this.trustTokensTreeElement = new TrustTokensTreeElement(panel);
277
280
  storageTreeElement.appendChild(this.trustTokensTreeElement);
278
281
 
282
+ this.interestGroupTreeElement = new InterestGroupTreeElement(panel);
283
+ storageTreeElement.appendChild(this.interestGroupTreeElement);
284
+
279
285
  const cacheSectionTitle = i18nString(UIStrings.cache);
280
286
  const cacheTreeElement = this.addSidebarSection(cacheSectionTitle);
281
287
  this.cacheStorageListTreeElement = new ServiceWorkerCacheTreeElement(panel);
@@ -349,7 +355,10 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
349
355
  modelAdded: (model: IndexedDBModel): void => model.enable(),
350
356
  modelRemoved: (model: IndexedDBModel): void => this.indexedDBListTreeElement.removeIndexedDBForModel(model),
351
357
  });
352
-
358
+ SDK.TargetManager.TargetManager.instance().observeModels(InterestGroupStorageModel, {
359
+ modelAdded: (model: InterestGroupStorageModel): void => this.interestGroupModelAdded(model),
360
+ modelRemoved: (model: InterestGroupStorageModel): void => this.interestGroupModelRemoved(model),
361
+ });
353
362
  // Work-around for crbug.com/1152713: Something is wrong with custom scrollbars and size containment.
354
363
  // @ts-ignore
355
364
  this.contentElement.style.contain = 'layout style';
@@ -376,6 +385,11 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
376
385
  this.databaseModel.addEventListener(DatabaseModelEvents.DatabasesRemoved, this.resetWebSQL, this);
377
386
  }
378
387
 
388
+ const interestGroupModel = target.model(InterestGroupStorageModel);
389
+ if (interestGroupModel) {
390
+ interestGroupModel.addEventListener(InterestGroupModelEvents.InterestGroupAccess, this.interestGroupAccess, this);
391
+ }
392
+
379
393
  const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
380
394
  if (!resourceTreeModel) {
381
395
  return;
@@ -408,6 +422,12 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
408
422
  this.databaseModel = null;
409
423
  }
410
424
 
425
+ const interestGroupModel = target.model(InterestGroupStorageModel);
426
+ if (interestGroupModel) {
427
+ interestGroupModel.removeEventListener(
428
+ InterestGroupModelEvents.InterestGroupAccess, this.interestGroupAccess, this);
429
+ }
430
+
411
431
  this.resetWithFrames();
412
432
  }
413
433
 
@@ -422,6 +442,10 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
422
442
  if (this.databaseModel) {
423
443
  this.databaseModel.enable();
424
444
  }
445
+ const interestGroupModel = this.target && this.target.model(InterestGroupStorageModel);
446
+ if (interestGroupModel) {
447
+ interestGroupModel.enable();
448
+ }
425
449
 
426
450
  const cacheStorageModel = this.target && this.target.model(SDK.ServiceWorkerCacheModel.ServiceWorkerCacheModel);
427
451
  if (cacheStorageModel) {
@@ -461,6 +485,16 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
461
485
  model.removeEventListener(DOMStorageModelEvents.DOMStorageRemoved, this.domStorageRemoved, this);
462
486
  }
463
487
 
488
+ private interestGroupModelAdded(model: InterestGroupStorageModel): void {
489
+ model.enable();
490
+ model.addEventListener(InterestGroupModelEvents.InterestGroupAccess, this.interestGroupAccess, this);
491
+ }
492
+
493
+ private interestGroupModelRemoved(model: InterestGroupStorageModel): void {
494
+ model.disable();
495
+ model.removeEventListener(InterestGroupModelEvents.InterestGroupAccess, this.interestGroupAccess, this);
496
+ }
497
+
464
498
  private resetWithFrames(): void {
465
499
  this.resourcesSection.reset();
466
500
  this.reset();
@@ -516,6 +550,7 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
516
550
  this.domains = {};
517
551
  this.resetWebSQL();
518
552
  this.cookieListTreeElement.removeChildren();
553
+ this.interestGroupTreeElement.clearEvents();
519
554
  }
520
555
 
521
556
  private frameNavigated(event: Common.EventTarget.EventTargetEvent<SDK.ResourceTreeModel.ResourceTreeFrame>): void {
@@ -533,6 +568,11 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
533
568
  this.databasesListTreeElement.appendChild(databaseTreeElement);
534
569
  }
535
570
 
571
+ private interestGroupAccess(event: Common.EventTarget.EventTargetEvent<Protocol.Storage.InterestGroupAccessedEvent>):
572
+ void {
573
+ this.interestGroupTreeElement.addEvent(event.data);
574
+ }
575
+
536
576
  private addCookieDocument(frame: SDK.ResourceTreeModel.ResourceTreeFrame): void {
537
577
  // In case the current frame was unreachable, show it's cookies
538
578
  // instead of the error interstitials because they might help to
@@ -0,0 +1,87 @@
1
+ /*
2
+ * Copyright (C) 2021 Google Inc. All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are
6
+ * met:
7
+ *
8
+ * * Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * * Redistributions in binary form must reproduce the above
11
+ * copyright notice, this list of conditions and the following disclaimer
12
+ * in the documentation and/or other materials provided with the
13
+ * distribution.
14
+ * * Neither the name of Google Inc. nor the names of its
15
+ * contributors may be used to endorse or promote products derived from
16
+ * this software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ import * as SDK from '../../core/sdk/sdk.js';
32
+ import type * as Protocol from '../../generated/protocol.js';
33
+ import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
34
+
35
+ export class InterestGroupStorageModel extends SDK.SDKModel.SDKModel<EventTypes> implements
36
+ ProtocolProxyApi.StorageDispatcher {
37
+ private readonly storageAgent: ProtocolProxyApi.StorageApi;
38
+ private enabled?: boolean;
39
+
40
+ constructor(target: SDK.Target.Target) {
41
+ super(target);
42
+ target.registerStorageDispatcher(this);
43
+ this.storageAgent = target.storageAgent();
44
+ this.enabled = false;
45
+ }
46
+
47
+ enable(): void {
48
+ if (this.enabled) {
49
+ return;
50
+ }
51
+ void this.storageAgent.invoke_setInterestGroupTracking({enable: true});
52
+ }
53
+
54
+ disable(): void {
55
+ if (!this.enabled) {
56
+ return;
57
+ }
58
+ void this.storageAgent.invoke_setInterestGroupTracking({enable: false});
59
+ }
60
+
61
+ interestGroupAccessed(event: Protocol.Storage.InterestGroupAccessedEvent): void {
62
+ this.dispatchEventToListeners(Events.InterestGroupAccess, event);
63
+ }
64
+
65
+ indexedDBListUpdated(_event: Protocol.Storage.IndexedDBListUpdatedEvent): void {
66
+ }
67
+
68
+ indexedDBContentUpdated(_event: Protocol.Storage.IndexedDBContentUpdatedEvent): void {
69
+ }
70
+
71
+ cacheStorageListUpdated(_event: Protocol.Storage.CacheStorageListUpdatedEvent): void {
72
+ }
73
+
74
+ cacheStorageContentUpdated(_event: Protocol.Storage.CacheStorageContentUpdatedEvent): void {
75
+ }
76
+ }
77
+
78
+ SDK.SDKModel.SDKModel.register(
79
+ InterestGroupStorageModel, {capabilities: SDK.Target.Capability.Storage, autostart: false});
80
+
81
+ export const enum Events {
82
+ InterestGroupAccess = 'InterestGroupAccess',
83
+ }
84
+
85
+ export type EventTypes = {
86
+ [Events.InterestGroupAccess]: Protocol.Storage.InterestGroupAccessedEvent,
87
+ };
@@ -0,0 +1,112 @@
1
+ // Copyright 2021 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as i18n from '../../core/i18n/i18n.js';
6
+ import * as UI from '../../ui/legacy/legacy.js';
7
+ import type * as DataGrid from '../../ui/components/data_grid/data_grid.js';
8
+ import type * as Protocol from '../../generated/protocol.js';
9
+ import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js';
10
+ import * as ApplicationComponents from './components/components.js';
11
+
12
+ import interestGroupStorageViewStyles from './interestGroupStorageView.css.js';
13
+
14
+ const UIStrings = {
15
+ /**
16
+ *@description Placeholder text instructing the user how to display interest group
17
+ *details.
18
+ */
19
+ clickToDisplayBody: 'Click on any interest group event to display the group\'s current state',
20
+ /**
21
+ interestGroupStorageItems: 'InterestGroup Storage Items',
22
+ */
23
+ };
24
+ const str_ = i18n.i18n.registerUIStrings('panels/application/InterestGroupStorageView.ts', UIStrings);
25
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
26
+
27
+ interface InterestGroupDetailsGetter {
28
+ getInterestGroupDetails: (owner: string, name: string) => Promise<Protocol.Storage.InterestGroupDetails|null>;
29
+ }
30
+
31
+ function eventEquals(
32
+ a: Protocol.Storage.InterestGroupAccessedEvent, b: Protocol.Storage.InterestGroupAccessedEvent): boolean {
33
+ return (a.accessTime === b.accessTime && a.type === b.type && a.ownerOrigin === b.ownerOrigin && a.name === b.name);
34
+ }
35
+
36
+ export class InterestGroupStorageView extends UI.SplitWidget.SplitWidget {
37
+ private readonly interestGroupGrid = new ApplicationComponents.InterestGroupAccessGrid.InterestGroupAccessGrid();
38
+ private events: Protocol.Storage.InterestGroupAccessedEvent[] = [];
39
+ private detailsGetter: InterestGroupDetailsGetter;
40
+
41
+ constructor(detailsGetter: InterestGroupDetailsGetter) {
42
+ super(/* isVertical */ false, /* secondIsSidebar: */ true);
43
+ this.detailsGetter = detailsGetter;
44
+
45
+ const topPanel = new UI.Widget.VBox();
46
+ const bottomPanel = new UI.Widget.VBox();
47
+ topPanel.setMinimumSize(0, 80);
48
+ this.setMainWidget(topPanel);
49
+ bottomPanel.setMinimumSize(0, 40);
50
+ this.setSidebarWidget(bottomPanel);
51
+
52
+ topPanel.contentElement.appendChild(this.interestGroupGrid);
53
+ this.interestGroupGrid.addEventListener('cellfocused', this.onFocus.bind(this));
54
+
55
+ bottomPanel.contentElement.classList.add('placeholder');
56
+ const centered = bottomPanel.contentElement.createChild('div');
57
+ centered.textContent = i18nString(UIStrings.clickToDisplayBody);
58
+ }
59
+
60
+ wasShown(): void {
61
+ super.wasShown();
62
+ const sbw = this.sidebarWidget();
63
+ if (sbw) {
64
+ sbw.registerCSSFiles([interestGroupStorageViewStyles]);
65
+ }
66
+ }
67
+
68
+ addEvent(event: Protocol.Storage.InterestGroupAccessedEvent): void {
69
+ // Only add if not already present.
70
+ const foundEvent = this.events.find(t => eventEquals(t, event));
71
+ if (!foundEvent) {
72
+ this.events.push(event);
73
+ this.interestGroupGrid.data = this.events;
74
+ }
75
+ }
76
+
77
+ clearEvents(): void {
78
+ this.events = [];
79
+ this.interestGroupGrid.data = this.events;
80
+ }
81
+
82
+ private async onFocus(event: Event): Promise<void> {
83
+ const focusedEvent = event as DataGrid.DataGridEvents.BodyCellFocusedEvent;
84
+ const row = focusedEvent.data.row;
85
+ if (!row) {
86
+ return;
87
+ }
88
+
89
+ const ownerOrigin = row.cells.find(cell => cell.columnId === 'event-group-owner')?.value as string;
90
+ const name = row.cells.find(cell => cell.columnId === 'event-group-name')?.value as string;
91
+ if (!ownerOrigin || !name) {
92
+ return;
93
+ }
94
+
95
+ const details = await this.detailsGetter.getInterestGroupDetails(ownerOrigin, name);
96
+ if (details) {
97
+ const jsonView = await SourceFrame.JSONView.JSONView.createView(JSON.stringify(details));
98
+ jsonView?.setMinimumSize(0, 40);
99
+ if (jsonView) {
100
+ this.setSidebarWidget(jsonView);
101
+ }
102
+ }
103
+ }
104
+
105
+ getEventsForTesting(): Array<Protocol.Storage.InterestGroupAccessedEvent> {
106
+ return this.events;
107
+ }
108
+
109
+ getInterestGroupGridForTesting(): ApplicationComponents.InterestGroupAccessGrid.InterestGroupAccessGrid {
110
+ return this.interestGroupGrid;
111
+ }
112
+ }