chrome-devtools-frontend 1.0.1006768 → 1.0.1007846

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 (47) hide show
  1. package/config/gni/devtools_grd_files.gni +5 -0
  2. package/config/gni/devtools_image_files.gni +2 -0
  3. package/extension-api/ExtensionAPI.d.ts +10 -0
  4. package/front_end/Images/src/ic_sources_authored.svg +5 -0
  5. package/front_end/Images/src/ic_sources_deployed.svg +5 -0
  6. package/front_end/core/i18n/locales/en-US.json +39 -3
  7. package/front_end/core/i18n/locales/en-XL.json +39 -3
  8. package/front_end/core/sdk/CSSFontFace.ts +8 -0
  9. package/front_end/core/sdk/DebuggerModel.ts +12 -3
  10. package/front_end/core/sdk/NetworkManager.ts +6 -2
  11. package/front_end/devtools_compatibility.js +1 -0
  12. package/front_end/entrypoints/formatter_worker/FormatterActions.ts +1 -0
  13. package/front_end/entrypoints/formatter_worker/ScopeParser.ts +12 -10
  14. package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +4 -0
  15. package/front_end/entrypoints/lighthouse_worker/LighthouseWorkerService.ts +1 -4
  16. package/front_end/legacy_test_runner/lighthouse_test_runner/lighthouse_test_runner.js +16 -0
  17. package/front_end/models/extensions/ExtensionAPI.ts +95 -12
  18. package/front_end/models/extensions/ExtensionEndpoint.ts +69 -0
  19. package/front_end/models/extensions/ExtensionServer.ts +21 -0
  20. package/front_end/models/extensions/LanguageExtensionEndpoint.ts +46 -78
  21. package/front_end/models/extensions/RecorderExtensionEndpoint.ts +43 -0
  22. package/front_end/models/extensions/RecorderPluginManager.ts +30 -0
  23. package/front_end/models/extensions/extensions.ts +2 -0
  24. package/front_end/models/formatter/FormatterWorkerPool.ts +6 -0
  25. package/front_end/models/javascript_metadata/JavaScriptMetadata.ts +13 -20
  26. package/front_end/models/javascript_metadata/NativeFunctions.js +1237 -3962
  27. package/front_end/models/source_map_scopes/NamesResolver.ts +206 -73
  28. package/front_end/models/workspace/UISourceCode.ts +7 -0
  29. package/front_end/panels/application/AppManifestView.ts +2 -1
  30. package/front_end/panels/application/components/BackForwardCacheView.ts +16 -0
  31. package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +15 -1
  32. package/front_end/panels/lighthouse/LighthouseController.ts +25 -10
  33. package/front_end/panels/lighthouse/LighthouseStartView.ts +32 -6
  34. package/front_end/panels/lighthouse/LighthouseStartViewFR.ts +70 -49
  35. package/front_end/panels/network/components/RequestHeadersView.css +36 -3
  36. package/front_end/panels/network/components/RequestHeadersView.ts +176 -3
  37. package/front_end/panels/sources/NavigatorView.ts +141 -40
  38. package/front_end/panels/sources/SourcesPanel.ts +8 -0
  39. package/front_end/panels/sources/TabbedEditorContainer.ts +2 -2
  40. package/front_end/panels/sources/sources-meta.ts +6 -0
  41. package/front_end/ui/components/text_editor/javascript.ts +12 -14
  42. package/front_end/ui/legacy/Treeoutline.ts +5 -2
  43. package/package.json +1 -1
  44. package/scripts/hosted_mode/server.js +14 -1
  45. package/scripts/javascript_natives/helpers.js +26 -7
  46. package/scripts/javascript_natives/index.js +4 -3
  47. package/scripts/javascript_natives/tests.js +2 -2
@@ -36,6 +36,7 @@ import * as SDK from '../../core/sdk/sdk.js';
36
36
  import * as Bindings from '../../models/bindings/bindings.js';
37
37
  import * as Persistence from '../../models/persistence/persistence.js';
38
38
  import * as Workspace from '../../models/workspace/workspace.js';
39
+ import * as IconButton from '../../ui/components/icon_button/icon_button.js';
39
40
  import * as UI from '../../ui/legacy/legacy.js';
40
41
  import * as Snippets from '../snippets/snippets.js';
41
42
 
@@ -59,6 +60,14 @@ const UIStrings = {
59
60
  /**
60
61
  *@description Text in Navigator View of the Sources panel
61
62
  */
63
+ authored: 'Authored',
64
+ /**
65
+ *@description Text in Navigator View of the Sources panel
66
+ */
67
+ deployed: 'Deployed',
68
+ /**
69
+ *@description Text in Navigator View of the Sources panel
70
+ */
62
71
  areYouSureYouWantToExcludeThis: 'Are you sure you want to exclude this folder?',
63
72
  /**
64
73
  *@description Text in Navigator View of the Sources panel
@@ -113,6 +122,8 @@ const UIStrings = {
113
122
  const str_ = i18n.i18n.registerUIStrings('panels/sources/NavigatorView.ts', UIStrings);
114
123
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
115
124
  export const Types = {
125
+ Authored: 'authored',
126
+ Deployed: 'deployed',
116
127
  Domain: 'domain',
117
128
  File: 'file',
118
129
  FileSystem: 'fs',
@@ -126,6 +137,8 @@ export const Types = {
126
137
 
127
138
  const TYPE_ORDERS = new Map([
128
139
  [Types.Root, 1],
140
+ [Types.Authored, 1],
141
+ [Types.Deployed, 5],
129
142
  [Types.Domain, 10],
130
143
  [Types.FileSystemFolder, 1],
131
144
  [Types.NetworkFolder, 1],
@@ -144,12 +157,16 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
144
157
  private readonly subfolderNodes: Map<string, NavigatorFolderTreeNode>;
145
158
  private readonly rootNode: NavigatorRootTreeNode;
146
159
  private readonly frameNodes: Map<SDK.ResourceTreeModel.ResourceTreeFrame, NavigatorGroupTreeNode>;
160
+ private authoredNode?: NavigatorGroupTreeNode;
161
+ private deployedNode?: NavigatorGroupTreeNode;
147
162
  // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
148
163
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
149
164
  private navigatorGroupByFolderSetting: Common.Settings.Setting<any>;
165
+ private navigatorGroupByAuthoredSetting: Common.Settings.Setting<boolean>;
150
166
  private workspaceInternal!: Workspace.Workspace.WorkspaceImpl;
151
167
  private lastSelectedUISourceCode?: Workspace.UISourceCode.UISourceCode;
152
168
  private groupByFrame?: boolean;
169
+ private groupByAuthored?: boolean;
153
170
  // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
154
171
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
155
172
  private groupByDomain?: any;
@@ -181,6 +198,9 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
181
198
 
182
199
  this.navigatorGroupByFolderSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByFolder');
183
200
  this.navigatorGroupByFolderSetting.addChangeListener(this.groupingChanged.bind(this));
201
+ this.navigatorGroupByAuthoredSetting =
202
+ Common.Settings.Settings.instance().moduleSetting('navigatorGroupByAuthored');
203
+ this.navigatorGroupByAuthoredSetting.addChangeListener(this.groupingChanged.bind(this));
184
204
 
185
205
  this.initGrouping();
186
206
 
@@ -275,14 +295,17 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
275
295
  void {
276
296
  const binding = event.data;
277
297
 
298
+ let isFromSourceMap = false;
278
299
  // Update UISourceCode titles.
279
300
  const networkNodes = this.uiSourceCodeNodes.get(binding.network);
280
301
  for (const networkNode of networkNodes) {
281
302
  networkNode.updateTitle();
303
+ isFromSourceMap ||= networkNode.uiSourceCode().contentType().isFromSourceMap();
282
304
  }
283
305
  const fileSystemNodes = this.uiSourceCodeNodes.get(binding.fileSystem);
284
306
  for (const fileSystemNode of fileSystemNodes) {
285
307
  fileSystemNode.updateTitle();
308
+ isFromSourceMap ||= fileSystemNode.uiSourceCode().contentType().isFromSourceMap();
286
309
  }
287
310
 
288
311
  // Update folder titles.
@@ -291,8 +314,8 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
291
314
  let folderPath = Platform.DevToolsPath.EmptyEncodedPathString;
292
315
  for (let i = 0; i < pathTokens.length - 1; ++i) {
293
316
  folderPath = Common.ParsedURL.ParsedURL.concatenate(folderPath, pathTokens[i]);
294
- const folderId =
295
- this.folderNodeId(binding.fileSystem.project(), null, null, binding.fileSystem.origin(), folderPath);
317
+ const folderId = this.folderNodeId(
318
+ binding.fileSystem.project(), null, null, binding.fileSystem.origin(), isFromSourceMap, folderPath);
296
319
  const folderNode = this.subfolderNodes.get(folderId);
297
320
  if (folderNode) {
298
321
  folderNode.updateTitle();
@@ -301,7 +324,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
301
324
  }
302
325
 
303
326
  // Update fileSystem root title.
304
- const fileSystemRoot = this.rootNode.child(binding.fileSystem.project().id());
327
+ const fileSystemRoot = this.rootOrDeployedNode().child(binding.fileSystem.project().id());
305
328
  if (fileSystemRoot) {
306
329
  fileSystemRoot.updateTitle();
307
330
  }
@@ -444,8 +467,13 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
444
467
  const folderNode =
445
468
  this.folderNode(uiSourceCode, project, target, frame, uiSourceCode.origin(), path, isFromSourceMap);
446
469
  const uiSourceCodeNode = new NavigatorUISourceCodeTreeNode(this, uiSourceCode, frame);
447
- folderNode.appendChild(uiSourceCodeNode);
448
- this.uiSourceCodeNodes.set(uiSourceCode, uiSourceCodeNode);
470
+ const existingNode = folderNode.child(uiSourceCodeNode.id);
471
+ if (existingNode && existingNode instanceof NavigatorUISourceCodeTreeNode) {
472
+ this.uiSourceCodeNodes.set(uiSourceCode, existingNode);
473
+ } else {
474
+ folderNode.appendChild(uiSourceCodeNode);
475
+ this.uiSourceCodeNodes.set(uiSourceCode, uiSourceCodeNode);
476
+ }
449
477
  this.selectDefaultTreeNode();
450
478
  }
451
479
 
@@ -470,11 +498,12 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
470
498
  }
471
499
 
472
500
  private projectAdded(project: Workspace.Workspace.Project): void {
501
+ const rootOrDeployed = this.rootOrDeployedNode();
473
502
  if (!this.acceptProject(project) || project.type() !== Workspace.Workspace.projectTypes.FileSystem ||
474
- Snippets.ScriptSnippetFileSystem.isSnippetsProject(project) || this.rootNode.child(project.id())) {
503
+ Snippets.ScriptSnippetFileSystem.isSnippetsProject(project) || rootOrDeployed.child(project.id())) {
475
504
  return;
476
505
  }
477
- this.rootNode.appendChild(
506
+ rootOrDeployed.appendChild(
478
507
  new NavigatorGroupTreeNode(this, project, project.id(), Types.FileSystem, project.displayName()));
479
508
  this.selectDefaultTreeNode();
480
509
  }
@@ -502,6 +531,8 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
502
531
  reversedIndex.add(reversedPath);
503
532
  }
504
533
 
534
+ const rootOrDeployed = this.rootOrDeployedNode();
535
+
505
536
  for (let i = 0; i < fileSystemProjects.length; ++i) {
506
537
  const reversedPath = reversedPaths[i];
507
538
  const project = fileSystemProjects[i];
@@ -512,7 +543,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
512
543
  const path = Common.ParsedURL.ParsedURL.encodedPathToRawPathString(
513
544
  encoder.decode(Platform.StringUtilities.reverse(prefixPath)) as Platform.DevToolsPath.EncodedPathString);
514
545
 
515
- const fileSystemNode = this.rootNode.child(project.id());
546
+ const fileSystemNode = rootOrDeployed.child(project.id());
516
547
  if (fileSystemNode) {
517
548
  fileSystemNode.setTitle(path);
518
549
  }
@@ -536,10 +567,13 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
536
567
 
537
568
  private folderNodeId(
538
569
  project: Workspace.Workspace.Project, target: SDK.Target.Target|null,
539
- frame: SDK.ResourceTreeModel.ResourceTreeFrame|null, projectOrigin: string,
570
+ frame: SDK.ResourceTreeModel.ResourceTreeFrame|null, projectOrigin: string, isFromSourceMap: boolean,
540
571
  path: Platform.DevToolsPath.EncodedPathString): string {
541
- const targetId = target ? target.id() : '';
572
+ let targetId = target && !(this.groupByAuthored && isFromSourceMap) ? target.id() : '';
542
573
  const projectId = project.type() === Workspace.Workspace.projectTypes.FileSystem ? project.id() : '';
574
+ if (this.groupByAuthored) {
575
+ targetId = isFromSourceMap ? 'Authored' : 'Deployed:' + targetId;
576
+ }
543
577
  const frameId = this.groupByFrame && frame ? frame.id : '';
544
578
  return targetId + ':' + projectId + ':' + frameId + ':' + projectOrigin + ':' + path;
545
579
  }
@@ -557,7 +591,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
557
591
  }
558
592
 
559
593
  const folderPath = Common.ParsedURL.ParsedURL.join(path, '/');
560
- const folderId = this.folderNodeId(project, target, frame, projectOrigin, folderPath);
594
+ const folderId = this.folderNodeId(project, target, frame, projectOrigin, fromSourceMap, folderPath);
561
595
  let folderNode = this.subfolderNodes.get(folderId);
562
596
  if (folderNode) {
563
597
  return folderNode;
@@ -567,7 +601,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
567
601
  if (target) {
568
602
  return this.domainNode(uiSourceCode, project, target, frame, projectOrigin);
569
603
  }
570
- return this.rootNode.child(project.id()) as NavigatorTreeNode;
604
+ return this.rootOrDeployedNode().child(project.id()) as NavigatorTreeNode;
571
605
  }
572
606
 
573
607
  const parentNode =
@@ -588,7 +622,8 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
588
622
  uiSourceCode: Workspace.UISourceCode.UISourceCode, project: Workspace.Workspace.Project,
589
623
  target: SDK.Target.Target, frame: SDK.ResourceTreeModel.ResourceTreeFrame|null,
590
624
  projectOrigin: string): NavigatorTreeNode {
591
- const frameNode = this.frameNode(project, target, frame);
625
+ const isAuthored = uiSourceCode.contentType().isFromSourceMap();
626
+ const frameNode = this.frameNode(project, target, frame, isAuthored);
592
627
  if (!this.groupByDomain) {
593
628
  return frameNode;
594
629
  }
@@ -603,14 +638,17 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
603
638
  boostOrderForNode.add(domainNode.treeNode());
604
639
  }
605
640
  frameNode.appendChild(domainNode);
641
+ if (isAuthored && this.groupByAuthored) {
642
+ domainNode.treeNode().expand();
643
+ }
606
644
  return domainNode;
607
645
  }
608
646
 
609
647
  private frameNode(
610
648
  project: Workspace.Workspace.Project, target: SDK.Target.Target,
611
- frame: SDK.ResourceTreeModel.ResourceTreeFrame|null): NavigatorTreeNode {
612
- if (!this.groupByFrame || !frame) {
613
- return this.targetNode(project, target);
649
+ frame: SDK.ResourceTreeModel.ResourceTreeFrame|null, isAuthored: boolean): NavigatorTreeNode {
650
+ if (!this.groupByFrame || !frame || (this.groupByAuthored && isAuthored)) {
651
+ return this.targetNode(project, target, isAuthored);
614
652
  }
615
653
 
616
654
  let frameNode = this.frameNodes.get(frame);
@@ -624,7 +662,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
624
662
  this.frameNodes.set(frame, frameNode);
625
663
 
626
664
  const parentFrame = frame.parentFrame();
627
- this.frameNode(project, parentFrame ? parentFrame.resourceTreeModel().target() : target, parentFrame)
665
+ this.frameNode(project, parentFrame ? parentFrame.resourceTreeModel().target() : target, parentFrame, isAuthored)
628
666
  .appendChild(frameNode);
629
667
  if (!parentFrame) {
630
668
  boostOrderForNode.add(frameNode.treeNode());
@@ -644,21 +682,45 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
644
682
  return frameNode;
645
683
  }
646
684
 
647
- private targetNode(project: Workspace.Workspace.Project, target: SDK.Target.Target): NavigatorTreeNode {
685
+ private targetNode(project: Workspace.Workspace.Project, target: SDK.Target.Target, isAuthored: boolean):
686
+ NavigatorTreeNode {
687
+ if (this.groupByAuthored && isAuthored) {
688
+ if (!this.authoredNode) {
689
+ this.authoredNode =
690
+ new NavigatorGroupTreeNode(this, null, 'group:Authored', Types.Authored, UIStrings.authored);
691
+ this.rootNode.appendChild(this.authoredNode);
692
+ this.authoredNode.treeNode().expand();
693
+ }
694
+ return this.authoredNode;
695
+ }
696
+
697
+ const rootOrDeployed = this.rootOrDeployedNode();
648
698
  if (target === SDK.TargetManager.TargetManager.instance().mainTarget()) {
649
- return this.rootNode;
699
+ return rootOrDeployed;
650
700
  }
651
701
 
652
- let targetNode = this.rootNode.child('target:' + target.id());
702
+ let targetNode = rootOrDeployed.child('target:' + target.id());
653
703
  if (!targetNode) {
654
704
  targetNode = new NavigatorGroupTreeNode(
655
705
  this, project, 'target:' + target.id(), target.type() === SDK.Target.Type.Frame ? Types.Frame : Types.Worker,
656
706
  target.name());
657
- this.rootNode.appendChild(targetNode);
707
+ rootOrDeployed.appendChild(targetNode);
658
708
  }
659
709
  return targetNode;
660
710
  }
661
711
 
712
+ private rootOrDeployedNode(): NavigatorTreeNode {
713
+ if (this.groupByAuthored) {
714
+ if (!this.deployedNode) {
715
+ this.deployedNode =
716
+ new NavigatorGroupTreeNode(this, null, 'group:Deployed', Types.Deployed, UIStrings.deployed);
717
+ this.rootNode.appendChild(this.deployedNode);
718
+ }
719
+ return this.deployedNode;
720
+ }
721
+ return this.rootNode;
722
+ }
723
+
662
724
  private computeProjectDisplayName(target: SDK.Target.Target, projectOrigin: string): string {
663
725
  const runtimeModel = target.model(SDK.RuntimeModel.RuntimeModel);
664
726
  const executionContexts = runtimeModel ? runtimeModel.executionContexts() : [];
@@ -721,35 +783,45 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
721
783
  return;
722
784
  }
723
785
  parentNode.removeChild(node);
724
- let currentNode: (NavigatorUISourceCodeTreeNode|null) = (parentNode as NavigatorUISourceCodeTreeNode | null);
786
+ let currentNode: (NavigatorTreeNode|null) = parentNode;
725
787
 
726
788
  while (currentNode) {
727
789
  parentNode = currentNode.parent;
728
790
  if (!parentNode || !currentNode.isEmpty()) {
729
791
  break;
730
792
  }
731
- if (parentNode === this.rootNode && project.type() === Workspace.Workspace.projectTypes.FileSystem) {
793
+ if ((parentNode === this.rootNode || parentNode === this.deployedNode) &&
794
+ project.type() === Workspace.Workspace.projectTypes.FileSystem) {
732
795
  break;
733
796
  }
734
797
  if (!(currentNode instanceof NavigatorGroupTreeNode || currentNode instanceof NavigatorFolderTreeNode)) {
735
798
  break;
736
799
  }
737
800
  if (currentNode.type === Types.Frame) {
738
- this.discardFrame((frame as SDK.ResourceTreeModel.ResourceTreeFrame));
801
+ this.discardFrame(
802
+ frame as SDK.ResourceTreeModel.ResourceTreeFrame,
803
+ Boolean(this.groupByAuthored) && uiSourceCode.contentType().isFromSourceMap());
739
804
  break;
740
805
  }
741
806
 
742
807
  const folderId = this.folderNodeId(
743
- project, target, frame, uiSourceCode.origin(),
808
+ project, target, frame, uiSourceCode.origin(), uiSourceCode.contentType().isFromSourceMap(),
744
809
  currentNode instanceof NavigatorFolderTreeNode && currentNode.folderPath ||
745
810
  Platform.DevToolsPath.EmptyEncodedPathString);
746
811
  this.subfolderNodes.delete(folderId);
747
812
  parentNode.removeChild(currentNode);
748
- currentNode = (parentNode as NavigatorUISourceCodeTreeNode | null);
813
+
814
+ if (currentNode === this.authoredNode) {
815
+ this.authoredNode = undefined;
816
+ } else if (currentNode === this.deployedNode) {
817
+ this.deployedNode = undefined;
818
+ }
819
+
820
+ currentNode = parentNode;
749
821
  }
750
822
  }
751
823
 
752
- reset(): void {
824
+ reset(tearDownOnly?: boolean): void {
753
825
  for (const node of this.uiSourceCodeNodes.valuesArray()) {
754
826
  node.dispose();
755
827
  }
@@ -760,8 +832,12 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
760
832
  this.subfolderNodes.clear();
761
833
  this.frameNodes.clear();
762
834
  this.rootNode.reset();
763
- // Reset the workspace to repopulate filesystem folders.
764
- this.resetWorkspace(Workspace.Workspace.WorkspaceImpl.instance());
835
+ this.authoredNode = undefined;
836
+ this.deployedNode = undefined;
837
+ if (!tearDownOnly) {
838
+ // Reset the workspace to repopulate filesystem folders.
839
+ this.resetWorkspace(Workspace.Workspace.WorkspaceImpl.instance());
840
+ }
765
841
  }
766
842
 
767
843
  handleContextMenu(_event: Event): void {
@@ -932,8 +1008,10 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
932
1008
  }
933
1009
 
934
1010
  private groupingChanged(): void {
935
- this.reset();
1011
+ this.reset(true);
936
1012
  this.initGrouping();
1013
+ // Reset the workspace to repopulate filesystem folders.
1014
+ this.resetWorkspace(Workspace.Workspace.WorkspaceImpl.instance());
937
1015
  this.workspaceInternal.uiSourceCodes().forEach(this.addUISourceCode.bind(this));
938
1016
  }
939
1017
 
@@ -941,6 +1019,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
941
1019
  this.groupByFrame = true;
942
1020
  this.groupByDomain = this.navigatorGroupByFolderSetting.get();
943
1021
  this.groupByFolder = this.groupByDomain;
1022
+ this.groupByAuthored = this.navigatorGroupByAuthoredSetting.get();
944
1023
  }
945
1024
 
946
1025
  private resetForTest(): void {
@@ -948,7 +1027,10 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
948
1027
  this.workspaceInternal.uiSourceCodes().forEach(this.addUISourceCode.bind(this));
949
1028
  }
950
1029
 
951
- private discardFrame(frame: SDK.ResourceTreeModel.ResourceTreeFrame): void {
1030
+ private discardFrame(frame: SDK.ResourceTreeModel.ResourceTreeFrame, isAuthored: boolean): void {
1031
+ if (isAuthored) {
1032
+ return;
1033
+ }
952
1034
  const node = this.frameNodes.get(frame);
953
1035
  if (!node) {
954
1036
  return;
@@ -959,7 +1041,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
959
1041
  }
960
1042
  this.frameNodes.delete(frame);
961
1043
  for (const child of frame.childFrames) {
962
- this.discardFrame(child);
1044
+ this.discardFrame(child, isAuthored);
963
1045
  }
964
1046
  }
965
1047
 
@@ -967,15 +1049,16 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
967
1049
  }
968
1050
 
969
1051
  targetRemoved(target: SDK.Target.Target): void {
970
- const targetNode = this.rootNode.child('target:' + target.id());
1052
+ const rootOrDeployed = this.rootOrDeployedNode();
1053
+ const targetNode = rootOrDeployed.child('target:' + target.id());
971
1054
  if (targetNode) {
972
- this.rootNode.removeChild(targetNode);
1055
+ rootOrDeployed.removeChild(targetNode);
973
1056
  }
974
1057
  }
975
1058
 
976
1059
  private targetNameChanged(event: Common.EventTarget.EventTargetEvent<SDK.Target.Target>): void {
977
1060
  const target = event.data;
978
- const targetNode = this.rootNode.child('target:' + target.id());
1061
+ const targetNode = this.rootOrDeployedNode().child('target:' + target.id());
979
1062
  if (targetNode) {
980
1063
  targetNode.setTitle(target.name());
981
1064
  }
@@ -1005,15 +1088,32 @@ export class NavigatorFolderTreeElement extends UI.TreeOutline.TreeElement {
1005
1088
  this.tooltip = title;
1006
1089
  this.navigatorView = navigatorView;
1007
1090
  this.hoverCallback = hoverCallback;
1091
+
1008
1092
  let iconType = 'largeicon-navigator-folder';
1093
+ let legacyIcon = true;
1094
+
1009
1095
  if (type === Types.Domain) {
1010
1096
  iconType = 'largeicon-navigator-domain';
1011
1097
  } else if (type === Types.Frame) {
1012
1098
  iconType = 'largeicon-navigator-frame';
1013
1099
  } else if (type === Types.Worker) {
1014
1100
  iconType = 'largeicon-navigator-worker';
1101
+ } else if (type === Types.Authored) {
1102
+ iconType = 'ic_sources_authored';
1103
+ legacyIcon = false;
1104
+ } else if (type === Types.Deployed) {
1105
+ iconType = 'ic_sources_deployed';
1106
+ legacyIcon = false;
1107
+ }
1108
+
1109
+ if (legacyIcon) {
1110
+ this.setLeadingIcons([UI.Icon.Icon.create(iconType, 'icon')]);
1111
+ } else {
1112
+ const icon = new IconButton.Icon.Icon();
1113
+ const iconPath = new URL(`../../Images/${iconType}.svg`, import.meta.url).toString();
1114
+ icon.data = {iconPath: iconPath, color: 'var(--override-folder-tree-item-color)', width: '18px'};
1115
+ this.setLeadingIcons([icon]);
1015
1116
  }
1016
- this.setLeadingIcons([UI.Icon.Icon.create(iconType, 'icon')]);
1017
1117
  }
1018
1118
 
1019
1119
  async onpopulate(): Promise<void> {
@@ -1325,7 +1425,7 @@ export class NavigatorUISourceCodeTreeNode extends NavigatorTreeNode {
1325
1425
  constructor(
1326
1426
  navigatorView: NavigatorView, uiSourceCode: Workspace.UISourceCode.UISourceCode,
1327
1427
  frame: SDK.ResourceTreeModel.ResourceTreeFrame|null) {
1328
- super(navigatorView, uiSourceCode.project().id() + ':' + uiSourceCode.url(), Types.File);
1428
+ super(navigatorView, 'UISourceCode:' + uiSourceCode.canononicalScriptId(), Types.File);
1329
1429
  this.uiSourceCodeInternal = uiSourceCode;
1330
1430
  this.treeElement = null;
1331
1431
  this.eventListeners = [];
@@ -1614,12 +1714,13 @@ export class NavigatorFolderTreeNode extends NavigatorTreeNode {
1614
1714
  }
1615
1715
 
1616
1716
  export class NavigatorGroupTreeNode extends NavigatorTreeNode {
1617
- private readonly project: Workspace.Workspace.Project;
1717
+ private readonly project: Workspace.Workspace.Project|null;
1618
1718
  title: string;
1619
1719
  private hoverCallback?: ((arg0: boolean) => void);
1620
1720
  private treeElement?: NavigatorFolderTreeElement;
1621
1721
  constructor(
1622
- navigatorView: NavigatorView, project: Workspace.Workspace.Project, id: string, type: string, title: string) {
1722
+ navigatorView: NavigatorView, project: Workspace.Workspace.Project|null, id: string, type: string,
1723
+ title: string) {
1623
1724
  super(navigatorView, id, type);
1624
1725
  this.project = project;
1625
1726
  this.title = title;
@@ -1644,7 +1745,7 @@ export class NavigatorGroupTreeNode extends NavigatorTreeNode {
1644
1745
  }
1645
1746
 
1646
1747
  updateTitle(): void {
1647
- if (!this.treeElement || this.project.type() !== Workspace.Workspace.projectTypes.FileSystem) {
1748
+ if (!this.treeElement || !this.project || this.project.type() !== Workspace.Workspace.projectTypes.FileSystem) {
1648
1749
  return;
1649
1750
  }
1650
1751
  const fileSystemPath = Persistence.FileSystemWorkspaceBinding.FileSystemWorkspaceBinding.fileSystemPath(
@@ -106,6 +106,10 @@ const UIStrings = {
106
106
  */
107
107
  groupByFolder: 'Group by folder',
108
108
  /**
109
+ *@description Text in Sources Panel of the Sources panel
110
+ */
111
+ groupByAuthored: 'Group by Authored/Deployed (experimental)',
112
+ /**
109
113
  *@description Text for pausing the debugger on exceptions
110
114
  */
111
115
  pauseOnExceptions: 'Pause on exceptions',
@@ -549,6 +553,10 @@ export class SourcesPanel extends UI.Panel.Panel implements UI.ContextMenu.Provi
549
553
  contextMenu.viewSection().appendCheckboxItem(
550
554
  i18nString(UIStrings.groupByFolder), () => groupByFolderSetting.set(!groupByFolderSetting.get()),
551
555
  groupByFolderSetting.get());
556
+ const groupByAuthoredSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByAuthored');
557
+ contextMenu.viewSection().appendCheckboxItem(
558
+ i18nString(UIStrings.groupByAuthored), () => groupByAuthoredSetting.set(!groupByAuthoredSetting.get()),
559
+ groupByAuthoredSetting.get());
552
560
  }
553
561
 
554
562
  setIgnoreExecutionLineEvents(ignoreExecutionLineEvents: boolean): void {
@@ -356,12 +356,12 @@ export class TabbedEditorContainer extends Common.ObjectWrapper.ObjectWrapper<Ev
356
356
  private canonicalUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode):
357
357
  Workspace.UISourceCode.UISourceCode {
358
358
  // Check if we have already a UISourceCode for this url
359
- const existingSourceCode = this.uriToUISourceCode.get(uiSourceCode.url());
359
+ const existingSourceCode = this.uriToUISourceCode.get(uiSourceCode.canononicalScriptId());
360
360
  if (existingSourceCode) {
361
361
  // Ignore incoming uiSourceCode, we already have this file.
362
362
  return existingSourceCode;
363
363
  }
364
- this.uriToUISourceCode.set(uiSourceCode.url(), uiSourceCode);
364
+ this.uriToUISourceCode.set(uiSourceCode.canononicalScriptId(), uiSourceCode);
365
365
  return uiSourceCode;
366
366
  }
367
367
 
@@ -1300,6 +1300,12 @@ Common.Settings.registerSettingExtension({
1300
1300
  defaultValue: true,
1301
1301
  });
1302
1302
 
1303
+ Common.Settings.registerSettingExtension({
1304
+ settingName: 'navigatorGroupByAuthored',
1305
+ settingType: Common.Settings.SettingType.BOOLEAN,
1306
+ defaultValue: false,
1307
+ });
1308
+
1303
1309
  Common.Settings.registerSettingExtension({
1304
1310
  category: Common.Settings.SettingCategory.SOURCES,
1305
1311
  storageType: Common.Settings.SettingStorageType.Synced,
@@ -508,22 +508,20 @@ async function getArgumentsForExpression(
508
508
  if (!context) {
509
509
  return null;
510
510
  }
511
- try {
512
- const expression = doc.sliceString(callee.from, callee.to);
513
- const result = await evaluateExpression(context, expression, 'argumentsHint');
514
- if (!result || result.type !== 'function') {
511
+ const expression = doc.sliceString(callee.from, callee.to);
512
+ const result = await evaluateExpression(context, expression, 'argumentsHint');
513
+ if (!result || result.type !== 'function') {
514
+ return null;
515
+ }
516
+ const objGetter = async(): Promise<SDK.RemoteObject.RemoteObject|null> => {
517
+ const first = callee.firstChild;
518
+ if (!first || callee.name !== 'MemberExpression') {
515
519
  return null;
516
520
  }
517
- return getArgumentsForFunctionValue(result, async () => {
518
- const first = callee.firstChild;
519
- if (!first || callee.name !== 'MemberExpression') {
520
- return null;
521
- }
522
- return evaluateExpression(context, doc.sliceString(first.from, first.to), 'argumentsHint');
523
- }, expression);
524
- } finally {
525
- context.runtimeModel.releaseObjectGroup('argumentsHint');
526
- }
521
+ return evaluateExpression(context, doc.sliceString(first.from, first.to), 'argumentsHint');
522
+ };
523
+ return getArgumentsForFunctionValue(result, objGetter, expression)
524
+ .finally(() => context.runtimeModel.releaseObjectGroup('argumentsHint'));
527
525
  }
528
526
 
529
527
  async function getArgumentsForFunctionValue(
@@ -40,6 +40,7 @@ import * as ARIAUtils from './ARIAUtils.js';
40
40
  import * as ThemeSupport from './theme_support/theme_support.js';
41
41
  import * as Utils from './utils/utils.js';
42
42
 
43
+ import type * as IconButton from '../components/icon_button/icon_button.js';
43
44
  import type {Icon} from './Icon.js';
44
45
  import type {Config} from './InplaceEditor.js';
45
46
  import {InplaceEditor} from './InplaceEditor.js';
@@ -48,6 +49,8 @@ import {Tooltip} from './Tooltip.js';
48
49
  import {deepElementFromPoint, enclosingNodeOrSelfWithNodeNameInArray, isEditing} from './UIUtils.js';
49
50
  import treeoutlineStyles from './treeoutline.css.legacy.js';
50
51
 
52
+ type AnyIcon = Icon|IconButton.Icon.Icon;
53
+
51
54
  const nodeToParentTreeElementMap = new WeakMap<Node, TreeElement>();
52
55
 
53
56
  // TODO(crbug.com/1167717): Make this a const enum again
@@ -781,7 +784,7 @@ export class TreeElement {
781
784
  }
782
785
  }
783
786
 
784
- setLeadingIcons(icons: Icon[]): void {
787
+ setLeadingIcons(icons: AnyIcon[]): void {
785
788
  if (!this.leadingIconsElement && !icons.length) {
786
789
  return;
787
790
  }
@@ -798,7 +801,7 @@ export class TreeElement {
798
801
  }
799
802
  }
800
803
 
801
- setTrailingIcons(icons: Icon[]): void {
804
+ setTrailingIcons(icons: AnyIcon[]): void {
802
805
  if (!this.trailingIconsElement && !icons.length) {
803
806
  return;
804
807
  }
package/package.json CHANGED
@@ -55,5 +55,5 @@
55
55
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
56
56
  "watch": "vpython third_party/node/node.py --output scripts/watch_build.js"
57
57
  },
58
- "version": "1.0.1006768"
58
+ "version": "1.0.1007846"
59
59
  }
@@ -194,9 +194,22 @@ async function requestHandler(request, response) {
194
194
  response.setHeader(header, value);
195
195
  });
196
196
 
197
+ const waitBeforeHeaders = parseInt(url.searchParams?.get('waitBeforeHeaders'), 10);
198
+ if (!isNaN(waitBeforeHeaders)) {
199
+ await new Promise(resolve => setTimeout(resolve, waitBeforeHeaders));
200
+ }
197
201
  response.writeHead(statusCode);
198
202
  if (data && encoding) {
199
- response.write(data, encoding);
203
+ const waitBetweenChunks = parseInt(url.searchParams?.get('waitBetweenChunks'), 10);
204
+ const numChunks = parseInt(url.searchParams?.get('numChunks'), 10);
205
+ const chunkSize = isNaN(numChunks) ? data.length : data.length / numChunks;
206
+ for (let i = 0; i < data.length; i += chunkSize) {
207
+ if (!isNaN(waitBetweenChunks)) {
208
+ await new Promise(resolve => setTimeout(resolve, waitBetweenChunks));
209
+ }
210
+ const chunk = data.subarray ? data.subarray(i, i + chunkSize) : data.substring(i, i + chunkSize);
211
+ response.write(chunk, encoding);
212
+ }
200
213
  }
201
214
  response.end();
202
215
  }