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.
- package/config/gni/devtools_grd_files.gni +5 -0
- package/config/gni/devtools_image_files.gni +2 -0
- package/extension-api/ExtensionAPI.d.ts +10 -0
- package/front_end/Images/src/ic_sources_authored.svg +5 -0
- package/front_end/Images/src/ic_sources_deployed.svg +5 -0
- package/front_end/core/i18n/locales/en-US.json +39 -3
- package/front_end/core/i18n/locales/en-XL.json +39 -3
- package/front_end/core/sdk/CSSFontFace.ts +8 -0
- package/front_end/core/sdk/DebuggerModel.ts +12 -3
- package/front_end/core/sdk/NetworkManager.ts +6 -2
- package/front_end/devtools_compatibility.js +1 -0
- package/front_end/entrypoints/formatter_worker/FormatterActions.ts +1 -0
- package/front_end/entrypoints/formatter_worker/ScopeParser.ts +12 -10
- package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +4 -0
- package/front_end/entrypoints/lighthouse_worker/LighthouseWorkerService.ts +1 -4
- package/front_end/legacy_test_runner/lighthouse_test_runner/lighthouse_test_runner.js +16 -0
- package/front_end/models/extensions/ExtensionAPI.ts +95 -12
- package/front_end/models/extensions/ExtensionEndpoint.ts +69 -0
- package/front_end/models/extensions/ExtensionServer.ts +21 -0
- package/front_end/models/extensions/LanguageExtensionEndpoint.ts +46 -78
- package/front_end/models/extensions/RecorderExtensionEndpoint.ts +43 -0
- package/front_end/models/extensions/RecorderPluginManager.ts +30 -0
- package/front_end/models/extensions/extensions.ts +2 -0
- package/front_end/models/formatter/FormatterWorkerPool.ts +6 -0
- package/front_end/models/javascript_metadata/JavaScriptMetadata.ts +13 -20
- package/front_end/models/javascript_metadata/NativeFunctions.js +1237 -3962
- package/front_end/models/source_map_scopes/NamesResolver.ts +206 -73
- package/front_end/models/workspace/UISourceCode.ts +7 -0
- package/front_end/panels/application/AppManifestView.ts +2 -1
- package/front_end/panels/application/components/BackForwardCacheView.ts +16 -0
- package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +15 -1
- package/front_end/panels/lighthouse/LighthouseController.ts +25 -10
- package/front_end/panels/lighthouse/LighthouseStartView.ts +32 -6
- package/front_end/panels/lighthouse/LighthouseStartViewFR.ts +70 -49
- package/front_end/panels/network/components/RequestHeadersView.css +36 -3
- package/front_end/panels/network/components/RequestHeadersView.ts +176 -3
- package/front_end/panels/sources/NavigatorView.ts +141 -40
- package/front_end/panels/sources/SourcesPanel.ts +8 -0
- package/front_end/panels/sources/TabbedEditorContainer.ts +2 -2
- package/front_end/panels/sources/sources-meta.ts +6 -0
- package/front_end/ui/components/text_editor/javascript.ts +12 -14
- package/front_end/ui/legacy/Treeoutline.ts +5 -2
- package/package.json +1 -1
- package/scripts/hosted_mode/server.js +14 -1
- package/scripts/javascript_natives/helpers.js +26 -7
- package/scripts/javascript_natives/index.js +4 -3
- 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
|
-
|
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.
|
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.
|
448
|
-
|
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) ||
|
503
|
+
Snippets.ScriptSnippetFileSystem.isSnippetsProject(project) || rootOrDeployed.child(project.id())) {
|
475
504
|
return;
|
476
505
|
}
|
477
|
-
|
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 =
|
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
|
-
|
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.
|
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
|
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):
|
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
|
699
|
+
return rootOrDeployed;
|
650
700
|
}
|
651
701
|
|
652
|
-
let targetNode =
|
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
|
-
|
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: (
|
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
|
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(
|
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
|
-
|
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
|
-
|
764
|
-
this.
|
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
|
1052
|
+
const rootOrDeployed = this.rootOrDeployedNode();
|
1053
|
+
const targetNode = rootOrDeployed.child('target:' + target.id());
|
971
1054
|
if (targetNode) {
|
972
|
-
|
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.
|
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,
|
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,
|
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.
|
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.
|
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
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
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
|
518
|
-
|
519
|
-
|
520
|
-
|
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:
|
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:
|
804
|
+
setTrailingIcons(icons: AnyIcon[]): void {
|
802
805
|
if (!this.trailingIconsElement && !icons.length) {
|
803
806
|
return;
|
804
807
|
}
|
package/package.json
CHANGED
@@ -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
|
-
|
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
|
}
|