chrome-devtools-frontend 1.0.1011333 → 1.0.1012587
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/codereview.settings +4 -0
- package/config/gni/devtools_grd_files.gni +2 -0
- package/docs/workflows.md +3 -3
- package/front_end/core/common/Mutex.ts +42 -0
- package/front_end/core/common/common.ts +2 -0
- package/front_end/core/host/UserMetrics.ts +3 -1
- package/front_end/core/i18n/locales/en-US.json +17 -2
- package/front_end/core/i18n/locales/en-XL.json +17 -2
- package/front_end/core/root/Runtime.ts +2 -0
- package/front_end/core/sdk/CSSMatchedStyles.ts +1 -1
- package/front_end/core/sdk/CSSModel.ts +4 -0
- package/front_end/core/sdk/DOMModel.ts +49 -27
- package/front_end/entrypoints/main/MainImpl.ts +9 -0
- package/front_end/entrypoints/wasmparser_worker/WasmParserWorker.ts +2 -14
- package/front_end/generated/protocol.ts +4 -0
- package/front_end/legacy_test_runner/elements_test_runner/ElementsTestRunner.js +1 -1
- package/front_end/models/bindings/BreakpointManager.ts +3 -2
- package/front_end/models/emulation/EmulatedDevices.ts +29 -2
- package/front_end/models/javascript_metadata/NativeFunctions.js +8 -17
- package/front_end/models/persistence/NetworkPersistenceManager.ts +60 -13
- package/front_end/panels/application/DOMStorageItemsView.ts +5 -5
- package/front_end/panels/elements/ElementsTreeOutline.ts +2 -0
- package/front_end/panels/profiler/HeapSnapshotView.ts +3 -1
- package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +7 -1
- package/front_end/panels/sources/NavigatorView.ts +50 -22
- package/front_end/panels/sources/SourcesNavigator.ts +45 -1
- package/front_end/panels/sources/SourcesPanel.ts +26 -4
- package/front_end/panels/sources/navigatorTree.css +4 -0
- package/front_end/panels/sources/sourcesNavigator.css +10 -0
- package/front_end/panels/webauthn/WebauthnPane.ts +8 -1
- package/front_end/ui/components/panel_feedback/PreviewToggle.ts +34 -13
- package/front_end/ui/components/panel_feedback/previewToggle.css +21 -1
- package/front_end/ui/components/text_editor/config.ts +2 -2
- package/front_end/ui/legacy/ContextMenu.ts +11 -2
- package/front_end/ui/legacy/components/data_grid/dataGrid.css +1 -1
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +15 -12
- package/package.json +1 -1
- package/scripts/eslint_rules/lib/lit_template_result_or_nothing.js +6 -0
@@ -1247,7 +1247,7 @@ export const NativeFunctions = [
|
|
1247
1247
|
},
|
1248
1248
|
{
|
1249
1249
|
name: 'add',
|
1250
|
-
signatures: [['
|
1250
|
+
signatures: [['sub_apps']],
|
1251
1251
|
receivers: ['SubApps']
|
1252
1252
|
},
|
1253
1253
|
{
|
@@ -1745,11 +1745,6 @@ export const NativeFunctions = [
|
|
1745
1745
|
name: 'replaceWith',
|
1746
1746
|
signatures: [['...nodes']]
|
1747
1747
|
},
|
1748
|
-
{
|
1749
|
-
name: 'read',
|
1750
|
-
signatures: [['?options']],
|
1751
|
-
receivers: ['Clipboard']
|
1752
|
-
},
|
1753
1748
|
{
|
1754
1749
|
name: 'read',
|
1755
1750
|
signatures: [['view']],
|
@@ -2572,7 +2567,7 @@ export const NativeFunctions = [
|
|
2572
2567
|
{
|
2573
2568
|
name: 'focus',
|
2574
2569
|
signatures: [['focus_behavior']],
|
2575
|
-
receivers: ['FocusableMediaStreamTrack']
|
2570
|
+
receivers: ['BrowserCaptureMediaStreamTrack','FocusableMediaStreamTrack']
|
2576
2571
|
},
|
2577
2572
|
{
|
2578
2573
|
name: 'assign',
|
@@ -5898,10 +5893,6 @@ export const NativeFunctions = [
|
|
5898
5893
|
name: 'registerProperty',
|
5899
5894
|
signatures: [['definition']]
|
5900
5895
|
},
|
5901
|
-
{
|
5902
|
-
name: 'setElement',
|
5903
|
-
signatures: [['element','tag','?options']]
|
5904
|
-
},
|
5905
5896
|
{
|
5906
5897
|
name: 'timeout',
|
5907
5898
|
signatures: [['milliseconds']]
|
@@ -6767,7 +6758,7 @@ export const NativeFunctions = [
|
|
6767
6758
|
},
|
6768
6759
|
{
|
6769
6760
|
name: 'ClipboardItem',
|
6770
|
-
signatures: [['items'
|
6761
|
+
signatures: [['items']]
|
6771
6762
|
},
|
6772
6763
|
{
|
6773
6764
|
name: 'CompressionStream',
|
@@ -7113,6 +7104,10 @@ export const NativeFunctions = [
|
|
7113
7104
|
name: 'cropTo',
|
7114
7105
|
signatures: [['crop_id']]
|
7115
7106
|
},
|
7107
|
+
{
|
7108
|
+
name: 'fromElement',
|
7109
|
+
signatures: [['element']]
|
7110
|
+
},
|
7116
7111
|
{
|
7117
7112
|
name: 'getDisplayMediaSet',
|
7118
7113
|
signatures: [['?constraints']]
|
@@ -7121,10 +7116,6 @@ export const NativeFunctions = [
|
|
7121
7116
|
name: 'setCaptureHandleConfig',
|
7122
7117
|
signatures: [['?config']]
|
7123
7118
|
},
|
7124
|
-
{
|
7125
|
-
name: 'produceCropId',
|
7126
|
-
signatures: [['target']]
|
7127
|
-
},
|
7128
7119
|
{
|
7129
7120
|
name: 'MediaStreamEvent',
|
7130
7121
|
signatures: [['type','?eventInitDict']]
|
@@ -7399,7 +7390,7 @@ export const NativeFunctions = [
|
|
7399
7390
|
},
|
7400
7391
|
{
|
7401
7392
|
name: 'requestPictureInPictureWindow',
|
7402
|
-
signatures: [['options']]
|
7393
|
+
signatures: [['?options']]
|
7403
7394
|
},
|
7404
7395
|
{
|
7405
7396
|
name: 'PresentationConnectionAvailableEvent',
|
@@ -8,6 +8,7 @@ import * as Platform from '../../core/platform/platform.js';
|
|
8
8
|
import * as Root from '../../core/root/root.js';
|
9
9
|
import * as SDK from '../../core/sdk/sdk.js';
|
10
10
|
import * as Protocol from '../../generated/protocol.js';
|
11
|
+
import * as Bindings from '../bindings/bindings.js';
|
11
12
|
import * as Workspace from '../workspace/workspace.js';
|
12
13
|
|
13
14
|
import type {FileSystem} from './FileSystemWorkspaceBinding.js';
|
@@ -35,6 +36,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
|
|
35
36
|
private enabled: boolean;
|
36
37
|
private eventDescriptors: Common.EventTarget.EventDescriptor[];
|
37
38
|
#headerOverridesMap: Map<Platform.DevToolsPath.EncodedPathString, HeaderOverrideWithRegex[]> = new Map();
|
39
|
+
readonly #sourceCodeToBindProcessMutex = new WeakMap<Workspace.UISourceCode.UISourceCode, Common.Mutex.Mutex>();
|
38
40
|
|
39
41
|
private constructor(workspace: Workspace.Workspace.WorkspaceImpl) {
|
40
42
|
super();
|
@@ -66,6 +68,8 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
|
|
66
68
|
});
|
67
69
|
|
68
70
|
PersistenceImpl.instance().addNetworkInterceptor(this.canHandleNetworkUISourceCode.bind(this));
|
71
|
+
Bindings.BreakpointManager.BreakpointManager.instance().addUpdateBindingsCallback(
|
72
|
+
this.networkUISourceCodeAdded.bind(this));
|
69
73
|
|
70
74
|
this.eventDescriptors = [];
|
71
75
|
void this.enabledChanged();
|
@@ -301,24 +305,66 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
|
|
301
305
|
return path;
|
302
306
|
}
|
303
307
|
|
304
|
-
|
308
|
+
async #unbind(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
|
305
309
|
const binding = this.bindings.get(uiSourceCode);
|
306
310
|
if (binding) {
|
307
|
-
this
|
308
|
-
|
309
|
-
|
311
|
+
const mutex = this.#getOrCreateMutex(binding.network);
|
312
|
+
const release = await mutex.acquire();
|
313
|
+
try {
|
314
|
+
await this.#innerUnbind(binding);
|
315
|
+
} finally {
|
316
|
+
release();
|
317
|
+
}
|
310
318
|
}
|
311
319
|
}
|
312
320
|
|
313
|
-
|
321
|
+
async #unbindUnguarded(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
|
322
|
+
const binding = this.bindings.get(uiSourceCode);
|
323
|
+
if (binding) {
|
324
|
+
await this.#innerUnbind(binding);
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
328
|
+
#innerUnbind(binding: PersistenceBinding): Promise<void> {
|
329
|
+
this.bindings.delete(binding.network);
|
330
|
+
this.bindings.delete(binding.fileSystem);
|
331
|
+
return PersistenceImpl.instance().removeBinding(binding);
|
332
|
+
}
|
333
|
+
|
334
|
+
async #bind(
|
314
335
|
networkUISourceCode: Workspace.UISourceCode.UISourceCode,
|
315
336
|
fileSystemUISourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
|
316
|
-
|
317
|
-
|
337
|
+
const mutex = this.#getOrCreateMutex(networkUISourceCode);
|
338
|
+
const release = await mutex.acquire();
|
339
|
+
try {
|
340
|
+
const existingBinding = this.bindings.get(networkUISourceCode);
|
341
|
+
if (existingBinding) {
|
342
|
+
const {network, fileSystem} = existingBinding;
|
343
|
+
if (networkUISourceCode === network && fileSystemUISourceCode === fileSystem) {
|
344
|
+
return;
|
345
|
+
}
|
346
|
+
await this.#unbindUnguarded(networkUISourceCode);
|
347
|
+
await this.#unbindUnguarded(fileSystemUISourceCode);
|
348
|
+
}
|
349
|
+
|
350
|
+
await this.#innerAddBinding(networkUISourceCode, fileSystemUISourceCode);
|
351
|
+
} finally {
|
352
|
+
release();
|
318
353
|
}
|
319
|
-
|
320
|
-
|
354
|
+
}
|
355
|
+
|
356
|
+
#getOrCreateMutex(networkUISourceCode: Workspace.UISourceCode.UISourceCode): Common.Mutex.Mutex {
|
357
|
+
let mutex = this.#sourceCodeToBindProcessMutex.get(networkUISourceCode);
|
358
|
+
if (!mutex) {
|
359
|
+
mutex = new Common.Mutex.Mutex();
|
360
|
+
this.#sourceCodeToBindProcessMutex.set(networkUISourceCode, mutex);
|
321
361
|
}
|
362
|
+
return mutex;
|
363
|
+
}
|
364
|
+
|
365
|
+
async #innerAddBinding(
|
366
|
+
networkUISourceCode: Workspace.UISourceCode.UISourceCode,
|
367
|
+
fileSystemUISourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
|
322
368
|
const binding = new PersistenceBinding(networkUISourceCode, fileSystemUISourceCode);
|
323
369
|
this.bindings.set(networkUISourceCode, binding);
|
324
370
|
this.bindings.set(fileSystemUISourceCode, binding);
|
@@ -394,7 +440,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
|
|
394
440
|
const project = this.projectInternal as FileSystem;
|
395
441
|
const fileSystemUISourceCode = project.uiSourceCodeForURL(this.fileUrlFromNetworkUrl(url));
|
396
442
|
if (fileSystemUISourceCode) {
|
397
|
-
await this
|
443
|
+
await this.#bind(uiSourceCode, fileSystemUISourceCode);
|
398
444
|
}
|
399
445
|
}
|
400
446
|
|
@@ -408,7 +454,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
|
|
408
454
|
const networkUISourceCode =
|
409
455
|
this.networkUISourceCodeForEncodedPath.get(Common.ParsedURL.ParsedURL.join(relativePath, '/'));
|
410
456
|
if (networkUISourceCode) {
|
411
|
-
await this
|
457
|
+
await this.#bind(networkUISourceCode, uiSourceCode);
|
412
458
|
}
|
413
459
|
}
|
414
460
|
|
@@ -521,7 +567,8 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
|
|
521
567
|
|
522
568
|
private async networkUISourceCodeRemoved(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
|
523
569
|
if (uiSourceCode.project().type() === Workspace.Workspace.projectTypes.Network) {
|
524
|
-
await this
|
570
|
+
await this.#unbind(uiSourceCode);
|
571
|
+
this.#sourceCodeToBindProcessMutex.delete(uiSourceCode);
|
525
572
|
this.networkUISourceCodeForEncodedPath.delete(this.encodedPathFromUrl(uiSourceCode.url()));
|
526
573
|
}
|
527
574
|
}
|
@@ -532,7 +579,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
|
|
532
579
|
}
|
533
580
|
this.updateInterceptionPatterns();
|
534
581
|
this.originalResponseContentPromises.delete(uiSourceCode);
|
535
|
-
await this
|
582
|
+
await this.#unbind(uiSourceCode);
|
536
583
|
}
|
537
584
|
|
538
585
|
async setProject(project: Workspace.Workspace.Project|null): Promise<void> {
|
@@ -53,14 +53,14 @@ const UIStrings = {
|
|
53
53
|
*/
|
54
54
|
value: 'Value',
|
55
55
|
/**
|
56
|
-
*@description
|
56
|
+
*@description Name for the "DOM Storage Items" table that shows the content of the DOM Storage.
|
57
57
|
*/
|
58
58
|
domStorageItems: 'DOM Storage Items',
|
59
59
|
/**
|
60
|
-
*@description Text for announcing
|
61
|
-
|
60
|
+
*@description Text for announcing that the "DOM Storage Items" table was cleared, that is, all
|
61
|
+
* entries were deleted.
|
62
62
|
*/
|
63
|
-
domStorageItemsCleared: '
|
63
|
+
domStorageItemsCleared: 'DOM Storage Items cleared',
|
64
64
|
/**
|
65
65
|
*@description Text in DOMStorage Items View of the Application panel
|
66
66
|
*/
|
@@ -154,7 +154,7 @@ export class DOMStorageItemsView extends StorageItemsView {
|
|
154
154
|
|
155
155
|
this.dataGrid.rootNode().removeChildren();
|
156
156
|
this.dataGrid.addCreationNode(false);
|
157
|
-
UI.ARIAUtils.alert(i18nString(UIStrings.domStorageItemsCleared
|
157
|
+
UI.ARIAUtils.alert(i18nString(UIStrings.domStorageItemsCleared));
|
158
158
|
this.setCanDeleteSelected(false);
|
159
159
|
}
|
160
160
|
|
@@ -1218,6 +1218,8 @@ export class ElementsTreeOutline extends
|
|
1218
1218
|
visibleChildren.push(templateContent);
|
1219
1219
|
}
|
1220
1220
|
|
1221
|
+
visibleChildren.push(...node.pageTransitionPseudoElements());
|
1222
|
+
|
1221
1223
|
const markerPseudoElement = node.markerPseudoElement();
|
1222
1224
|
if (markerPseudoElement) {
|
1223
1225
|
visibleChildren.push(markerPseudoElement);
|
@@ -181,7 +181,9 @@ const UIStrings = {
|
|
181
181
|
heapSnapshotProfilesShowMemory:
|
182
182
|
'Heap snapshot profiles show memory distribution among your page\'s JavaScript objects and related DOM nodes.',
|
183
183
|
/**
|
184
|
-
*@description
|
184
|
+
*@description Label for a checkbox in the heap snapshot view of the profiler tool. The "heap snapshot" contains the
|
185
|
+
* current state of JavaScript memory. With this checkbox enabled, the snapshot also includes internal data that is
|
186
|
+
* specific to Chrome (hence implementation-specific).
|
185
187
|
*/
|
186
188
|
exposeInternals: 'Expose internals (includes additional implementation-specific details)',
|
187
189
|
/**
|
@@ -110,8 +110,14 @@ export class FilteredUISourceCodeListProvider extends QuickOpen.FilteredListWidg
|
|
110
110
|
multiplier = 5;
|
111
111
|
}
|
112
112
|
|
113
|
+
let contentTypeBonus = 0;
|
114
|
+
if (uiSourceCode.contentType().isFromSourceMap()) {
|
115
|
+
contentTypeBonus = 100;
|
116
|
+
// Maybe also have a bonus for being a script?
|
117
|
+
}
|
118
|
+
|
113
119
|
const fullDisplayName = uiSourceCode.fullDisplayName();
|
114
|
-
return score + multiplier * this.scorer.calculateScore(fullDisplayName, null);
|
120
|
+
return score + multiplier * (contentTypeBonus + this.scorer.calculateScore(fullDisplayName, null));
|
115
121
|
}
|
116
122
|
|
117
123
|
renderItem(itemIndex: number, query: string, titleElement: Element, subtitleElement: Element): void {
|
@@ -32,6 +32,7 @@ import * as Common from '../../core/common/common.js';
|
|
32
32
|
import * as Host from '../../core/host/host.js';
|
33
33
|
import * as i18n from '../../core/i18n/i18n.js';
|
34
34
|
import * as Platform from '../../core/platform/platform.js';
|
35
|
+
import * as Root from '../../core/root/root.js';
|
35
36
|
import * as SDK from '../../core/sdk/sdk.js';
|
36
37
|
import * as Bindings from '../../models/bindings/bindings.js';
|
37
38
|
import * as Persistence from '../../models/persistence/persistence.js';
|
@@ -64,10 +65,18 @@ const UIStrings = {
|
|
64
65
|
/**
|
65
66
|
*@description Text in Navigator View of the Sources panel
|
66
67
|
*/
|
68
|
+
authoredTooltip: 'Contains original sources',
|
69
|
+
/**
|
70
|
+
*@description Text in Navigator View of the Sources panel
|
71
|
+
*/
|
67
72
|
deployed: 'Deployed',
|
68
73
|
/**
|
69
74
|
*@description Text in Navigator View of the Sources panel
|
70
75
|
*/
|
76
|
+
deployedTooltip: 'Contains final sources the browser sees',
|
77
|
+
/**
|
78
|
+
*@description Text in Navigator View of the Sources panel
|
79
|
+
*/
|
71
80
|
areYouSureYouWantToExcludeThis: 'Are you sure you want to exclude this folder?',
|
72
81
|
/**
|
73
82
|
*@description Text in Navigator View of the Sources panel
|
@@ -162,7 +171,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
|
|
162
171
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
|
163
172
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
164
173
|
private navigatorGroupByFolderSetting: Common.Settings.Setting<any>;
|
165
|
-
private
|
174
|
+
private navigatorGroupByAuthoredExperiment?: string;
|
166
175
|
private workspaceInternal!: Workspace.Workspace.WorkspaceImpl;
|
167
176
|
private lastSelectedUISourceCode?: Workspace.UISourceCode.UISourceCode;
|
168
177
|
private groupByFrame?: boolean;
|
@@ -173,7 +182,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
|
|
173
182
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
|
174
183
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
175
184
|
private groupByFolder?: any;
|
176
|
-
constructor() {
|
185
|
+
constructor(enableAuthoredGrouping?: boolean) {
|
177
186
|
super(true);
|
178
187
|
|
179
188
|
this.placeholder = null;
|
@@ -198,9 +207,9 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
|
|
198
207
|
|
199
208
|
this.navigatorGroupByFolderSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByFolder');
|
200
209
|
this.navigatorGroupByFolderSetting.addChangeListener(this.groupingChanged.bind(this));
|
201
|
-
|
202
|
-
|
203
|
-
|
210
|
+
if (enableAuthoredGrouping) {
|
211
|
+
this.navigatorGroupByAuthoredExperiment = Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING;
|
212
|
+
}
|
204
213
|
|
205
214
|
this.initGrouping();
|
206
215
|
|
@@ -686,8 +695,9 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
|
|
686
695
|
NavigatorTreeNode {
|
687
696
|
if (this.groupByAuthored && isAuthored) {
|
688
697
|
if (!this.authoredNode) {
|
689
|
-
this.authoredNode =
|
690
|
-
|
698
|
+
this.authoredNode = new NavigatorGroupTreeNode(
|
699
|
+
this, null, 'group:Authored', Types.Authored, i18nString(UIStrings.authored),
|
700
|
+
i18nString(UIStrings.authoredTooltip));
|
691
701
|
this.rootNode.appendChild(this.authoredNode);
|
692
702
|
this.authoredNode.treeNode().expand();
|
693
703
|
}
|
@@ -712,8 +722,9 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
|
|
712
722
|
private rootOrDeployedNode(): NavigatorTreeNode {
|
713
723
|
if (this.groupByAuthored) {
|
714
724
|
if (!this.deployedNode) {
|
715
|
-
this.deployedNode =
|
716
|
-
|
725
|
+
this.deployedNode = new NavigatorGroupTreeNode(
|
726
|
+
this, null, 'group:Deployed', Types.Deployed, i18nString(UIStrings.deployed),
|
727
|
+
i18nString(UIStrings.deployedTooltip));
|
717
728
|
this.rootNode.appendChild(this.deployedNode);
|
718
729
|
}
|
719
730
|
return this.deployedNode;
|
@@ -1007,10 +1018,17 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
|
|
1007
1018
|
}
|
1008
1019
|
}
|
1009
1020
|
|
1021
|
+
/**
|
1022
|
+
* Subclasses can override to listen to grouping changes.
|
1023
|
+
*/
|
1024
|
+
onGroupingChanged(): void {
|
1025
|
+
}
|
1026
|
+
|
1010
1027
|
private groupingChanged(): void {
|
1011
1028
|
this.reset(true);
|
1012
1029
|
this.initGrouping();
|
1013
1030
|
// Reset the workspace to repopulate filesystem folders.
|
1031
|
+
this.onGroupingChanged();
|
1014
1032
|
this.resetWorkspace(Workspace.Workspace.WorkspaceImpl.instance());
|
1015
1033
|
this.workspaceInternal.uiSourceCodes().forEach(this.addUISourceCode.bind(this));
|
1016
1034
|
}
|
@@ -1019,7 +1037,11 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
|
|
1019
1037
|
this.groupByFrame = true;
|
1020
1038
|
this.groupByDomain = this.navigatorGroupByFolderSetting.get();
|
1021
1039
|
this.groupByFolder = this.groupByDomain;
|
1022
|
-
|
1040
|
+
if (this.navigatorGroupByAuthoredExperiment) {
|
1041
|
+
this.groupByAuthored = Root.Runtime.experiments.isEnabled(this.navigatorGroupByAuthoredExperiment);
|
1042
|
+
} else {
|
1043
|
+
this.groupByAuthored = false;
|
1044
|
+
}
|
1023
1045
|
}
|
1024
1046
|
|
1025
1047
|
private resetForTest(): void {
|
@@ -1130,14 +1152,18 @@ export class NavigatorFolderTreeElement extends UI.TreeOutline.TreeElement {
|
|
1130
1152
|
|
1131
1153
|
setNode(node: NavigatorTreeNode): void {
|
1132
1154
|
this.node = node;
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
paths
|
1137
|
-
currentNode =
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1155
|
+
if (node.tooltip) {
|
1156
|
+
this.tooltip = node.tooltip;
|
1157
|
+
} else {
|
1158
|
+
const paths = [];
|
1159
|
+
let currentNode: NavigatorTreeNode|null = node;
|
1160
|
+
while (currentNode && !currentNode.isRoot() && currentNode.type === node.type) {
|
1161
|
+
paths.push(currentNode.title);
|
1162
|
+
currentNode = currentNode.parent;
|
1163
|
+
}
|
1164
|
+
paths.reverse();
|
1165
|
+
this.tooltip = paths.join('/');
|
1166
|
+
}
|
1141
1167
|
UI.ARIAUtils.setAccessibleName(this.listItemElement, `${this.title}, ${this.nodeType}`);
|
1142
1168
|
}
|
1143
1169
|
|
@@ -1303,12 +1329,14 @@ export class NavigatorTreeNode {
|
|
1303
1329
|
isMerged: boolean;
|
1304
1330
|
parent!: NavigatorTreeNode|null;
|
1305
1331
|
title!: string;
|
1332
|
+
tooltip?: string;
|
1306
1333
|
|
1307
|
-
constructor(navigatorView: NavigatorView, id: string, type: string) {
|
1334
|
+
constructor(navigatorView: NavigatorView, id: string, type: string, tooltip?: string) {
|
1308
1335
|
this.id = id;
|
1309
1336
|
this.navigatorView = navigatorView;
|
1310
1337
|
this.type = type;
|
1311
1338
|
this.childrenInternal = new Map();
|
1339
|
+
this.tooltip = tooltip;
|
1312
1340
|
|
1313
1341
|
this.populated = false;
|
1314
1342
|
this.isMerged = false;
|
@@ -1719,9 +1747,9 @@ export class NavigatorGroupTreeNode extends NavigatorTreeNode {
|
|
1719
1747
|
private hoverCallback?: ((arg0: boolean) => void);
|
1720
1748
|
private treeElement?: NavigatorFolderTreeElement;
|
1721
1749
|
constructor(
|
1722
|
-
navigatorView: NavigatorView, project: Workspace.Workspace.Project|null, id: string, type: string,
|
1723
|
-
|
1724
|
-
super(navigatorView, id, type);
|
1750
|
+
navigatorView: NavigatorView, project: Workspace.Workspace.Project|null, id: string, type: string, title: string,
|
1751
|
+
tooltip?: string) {
|
1752
|
+
super(navigatorView, id, type, tooltip);
|
1725
1753
|
this.project = project;
|
1726
1754
|
this.title = title;
|
1727
1755
|
this.populate();
|
@@ -32,14 +32,17 @@ import * as Common from '../../core/common/common.js';
|
|
32
32
|
import * as Host from '../../core/host/host.js';
|
33
33
|
import * as i18n from '../../core/i18n/i18n.js';
|
34
34
|
import * as Platform from '../../core/platform/platform.js';
|
35
|
+
import * as Root from '../../core/root/root.js';
|
35
36
|
import * as SDK from '../../core/sdk/sdk.js';
|
36
37
|
import * as Persistence from '../../models/persistence/persistence.js';
|
37
38
|
import * as Workspace from '../../models/workspace/workspace.js';
|
39
|
+
import * as Feedback from '../../ui/components/panel_feedback/panel_feedback.js';
|
38
40
|
import * as UI from '../../ui/legacy/legacy.js';
|
39
41
|
import * as Snippets from '../snippets/snippets.js';
|
40
42
|
|
41
43
|
import type {NavigatorUISourceCodeTreeNode} from './NavigatorView.js';
|
42
44
|
import {NavigatorView} from './NavigatorView.js';
|
45
|
+
import sourcesNavigatorStyles from './sourcesNavigator.css.js';
|
43
46
|
|
44
47
|
const UIStrings = {
|
45
48
|
/**
|
@@ -100,20 +103,61 @@ const UIStrings = {
|
|
100
103
|
*@description Text to save content as a specific file type
|
101
104
|
*/
|
102
105
|
saveAs: 'Save as...',
|
106
|
+
/**
|
107
|
+
*@description Description of the new experimental Authored/Deployed view
|
108
|
+
*/
|
109
|
+
authoredDescription: 'Group files by Authored/Deployed',
|
103
110
|
};
|
104
111
|
const str_ = i18n.i18n.registerUIStrings('panels/sources/SourcesNavigator.ts', UIStrings);
|
105
112
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
106
113
|
let networkNavigatorViewInstance: NetworkNavigatorView;
|
107
114
|
|
108
115
|
export class NetworkNavigatorView extends NavigatorView {
|
116
|
+
private previewToggle: Feedback.PreviewToggle.PreviewToggle;
|
109
117
|
private constructor() {
|
110
|
-
super();
|
118
|
+
super(true);
|
111
119
|
SDK.TargetManager.TargetManager.instance().addEventListener(
|
112
120
|
SDK.TargetManager.Events.InspectedURLChanged, this.inspectedURLChanged, this);
|
113
121
|
|
122
|
+
this.previewToggle = new Feedback.PreviewToggle.PreviewToggle();
|
123
|
+
this.onGroupingChanged();
|
124
|
+
|
125
|
+
const div = UI.Fragment.html`<div class="border-container"></div>`;
|
126
|
+
div.append(this.previewToggle);
|
127
|
+
this.contentElement.prepend(div);
|
128
|
+
|
114
129
|
// Record the sources tool load time after the file navigator has loaded.
|
115
130
|
Host.userMetrics.panelLoaded('sources', 'DevTools.Launch.Sources');
|
116
131
|
}
|
132
|
+
|
133
|
+
onGroupingChanged(): void {
|
134
|
+
// Setting the data will re-render it.
|
135
|
+
this.previewToggle.data = {
|
136
|
+
name: i18nString(UIStrings.authoredDescription),
|
137
|
+
helperText: null,
|
138
|
+
experiment: Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING,
|
139
|
+
learnMoreURL: 'https://goo.gle/authored-deployed',
|
140
|
+
feedbackURL: 'https://goo.gle/authored-deployed-feedback',
|
141
|
+
onChangeCallback: this.onAuthoredDeployedChanged,
|
142
|
+
};
|
143
|
+
}
|
144
|
+
|
145
|
+
wasShown(): void {
|
146
|
+
this.registerCSSFiles([sourcesNavigatorStyles]);
|
147
|
+
super.wasShown();
|
148
|
+
}
|
149
|
+
|
150
|
+
private onAuthoredDeployedChanged(checked: boolean): void {
|
151
|
+
Host.userMetrics.experimentChanged(Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING, checked);
|
152
|
+
// Need to signal to the NavigatorView that grouping has changed. Unfortunately,
|
153
|
+
// it can't listen to an experiment, and this class doesn't directly interact
|
154
|
+
// with it, so we will convince it a different grouping setting changed. When we switch
|
155
|
+
// from using an experiment to a setting, it will listen to that setting and we
|
156
|
+
// won't need to do this.
|
157
|
+
const groupByFolderSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByFolder');
|
158
|
+
groupByFolderSetting.set(groupByFolderSetting.get());
|
159
|
+
}
|
160
|
+
|
117
161
|
static instance(opts: {
|
118
162
|
forceNew: boolean|null,
|
119
163
|
} = {forceNew: null}): NetworkNavigatorView {
|
@@ -32,10 +32,12 @@ import * as Common from '../../core/common/common.js';
|
|
32
32
|
import * as Host from '../../core/host/host.js';
|
33
33
|
import * as i18n from '../../core/i18n/i18n.js';
|
34
34
|
import * as Platform from '../../core/platform/platform.js';
|
35
|
+
import * as Root from '../../core/root/root.js';
|
35
36
|
import * as SDK from '../../core/sdk/sdk.js';
|
36
37
|
import * as Bindings from '../../models/bindings/bindings.js';
|
37
38
|
import * as Extensions from '../../models/extensions/extensions.js';
|
38
39
|
import * as Workspace from '../../models/workspace/workspace.js';
|
40
|
+
import * as IconButton from '../../ui/components/icon_button/icon_button.js';
|
39
41
|
import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
|
40
42
|
import * as UI from '../../ui/legacy/legacy.js';
|
41
43
|
import * as Snippets from '../snippets/snippets.js';
|
@@ -108,7 +110,7 @@ const UIStrings = {
|
|
108
110
|
/**
|
109
111
|
*@description Text in Sources Panel of the Sources panel
|
110
112
|
*/
|
111
|
-
groupByAuthored: 'Group by Authored/Deployed
|
113
|
+
groupByAuthored: 'Group by Authored/Deployed',
|
112
114
|
/**
|
113
115
|
*@description Text for pausing the debugger on exceptions
|
114
116
|
*/
|
@@ -547,16 +549,36 @@ export class SourcesPanel extends UI.Panel.Panel implements UI.ContextMenu.Provi
|
|
547
549
|
}
|
548
550
|
}
|
549
551
|
|
552
|
+
private toggleAuthoredDeployedExperiment(): void {
|
553
|
+
const experiment = Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING;
|
554
|
+
const checked = Root.Runtime.experiments.isEnabled(experiment);
|
555
|
+
Root.Runtime.experiments.setEnabled(experiment, !checked);
|
556
|
+
Host.userMetrics.experimentChanged(experiment, checked);
|
557
|
+
// Need to signal to the NavigatorView that grouping has changed. Unfortunately,
|
558
|
+
// it can't listen to an experiment, and this class doesn't directly interact
|
559
|
+
// with it, so we will convince it a different grouping setting changed. When we switch
|
560
|
+
// from using an experiment to a setting, it will listen to that setting and we
|
561
|
+
// won't need to do this.
|
562
|
+
const groupByFolderSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByFolder');
|
563
|
+
groupByFolderSetting.set(groupByFolderSetting.get());
|
564
|
+
}
|
565
|
+
|
550
566
|
private populateNavigatorMenu(contextMenu: UI.ContextMenu.ContextMenu): void {
|
551
567
|
const groupByFolderSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByFolder');
|
552
568
|
contextMenu.appendItemsAtLocation('navigatorMenu');
|
553
569
|
contextMenu.viewSection().appendCheckboxItem(
|
554
570
|
i18nString(UIStrings.groupByFolder), () => groupByFolderSetting.set(!groupByFolderSetting.get()),
|
555
571
|
groupByFolderSetting.get());
|
556
|
-
const
|
572
|
+
const previewIcon = new IconButton.Icon.Icon();
|
573
|
+
const experiment = Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING;
|
574
|
+
previewIcon.data = {
|
575
|
+
iconName: 'ic_preview_feature',
|
576
|
+
color: 'var(--icon-color)',
|
577
|
+
width: '14px',
|
578
|
+
};
|
557
579
|
contextMenu.viewSection().appendCheckboxItem(
|
558
|
-
i18nString(UIStrings.groupByAuthored),
|
559
|
-
|
580
|
+
i18nString(UIStrings.groupByAuthored), this.toggleAuthoredDeployedExperiment,
|
581
|
+
Root.Runtime.experiments.isEnabled(experiment), false, previewIcon);
|
560
582
|
}
|
561
583
|
|
562
584
|
setIgnoreExecutionLineEvents(ignoreExecutionLineEvents: boolean): void {
|
@@ -91,6 +91,10 @@
|
|
91
91
|
background-color: var(--override-folder-tree-item-color);
|
92
92
|
}
|
93
93
|
|
94
|
+
.navigator-folder-tree-item.force-white-icons {
|
95
|
+
--icon-color: var(--override-force-white-icons-background);
|
96
|
+
}
|
97
|
+
|
94
98
|
.navigator-sm-folder-tree-item .icon,
|
95
99
|
.navigator-fs-tree-item .icon,
|
96
100
|
.navigator-fs-folder-tree-item .icon {
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2022 The Chromium Authors. All rights reserved.
|
3
|
+
* Use of this source code is governed by a BSD-style license that can be
|
4
|
+
* found in the LICENSE file.
|
5
|
+
*/
|
6
|
+
|
7
|
+
.border-container {
|
8
|
+
border-bottom: 1px solid var(--color-details-hairline);
|
9
|
+
flex-shrink: 0;
|
10
|
+
}
|
@@ -454,6 +454,9 @@ export class WebauthnPaneImpl extends UI.Widget.VBox implements
|
|
454
454
|
|
455
455
|
#removeAuthenticatorSections(): void {
|
456
456
|
this.#authenticatorsView.innerHTML = '';
|
457
|
+
for (const dataGrid of this.#dataGrids.values()) {
|
458
|
+
dataGrid.asWidget().detach();
|
459
|
+
}
|
457
460
|
this.#dataGrids.clear();
|
458
461
|
}
|
459
462
|
|
@@ -788,7 +791,11 @@ export class WebauthnPaneImpl extends UI.Widget.VBox implements
|
|
788
791
|
child.remove();
|
789
792
|
}
|
790
793
|
}
|
791
|
-
this.#dataGrids.
|
794
|
+
const dataGrid = this.#dataGrids.get(authenticatorId);
|
795
|
+
if (dataGrid) {
|
796
|
+
dataGrid.asWidget().detach();
|
797
|
+
this.#dataGrids.delete(authenticatorId);
|
798
|
+
}
|
792
799
|
|
793
800
|
if (this.#model) {
|
794
801
|
void this.#model.removeAuthenticator(authenticatorId);
|