chrome-devtools-frontend 1.0.1012379 → 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.
@@ -1252,6 +1252,7 @@ grd_files_debug_sources = [
1252
1252
  "front_end/panels/sources/navigatorTree.css.js",
1253
1253
  "front_end/panels/sources/navigatorView.css.js",
1254
1254
  "front_end/panels/sources/scopeChainSidebarPane.css.js",
1255
+ "front_end/panels/sources/sourcesNavigator.css.js",
1255
1256
  "front_end/panels/sources/sourcesPanel.css.js",
1256
1257
  "front_end/panels/sources/sourcesView.css.js",
1257
1258
  "front_end/panels/sources/threadsSidebarPane.css.js",
@@ -627,8 +627,9 @@ export enum DevtoolsExperiments {
627
627
  'eyedropperColorPicker' = 60,
628
628
  'instrumentationBreakpoints' = 61,
629
629
  'cssAuthoringHints' = 62,
630
+ 'authoredDeployedGrouping' = 63,
630
631
  // Increment this when new experiments are added.
631
- 'MaxValue' = 63,
632
+ 'MaxValue' = 64,
632
633
  }
633
634
  /* eslint-enable @typescript-eslint/naming-convention */
634
635
 
@@ -3291,7 +3291,7 @@
3291
3291
  "message": "DOM Storage Items"
3292
3292
  },
3293
3293
  "panels/application/DOMStorageItemsView.ts | domStorageItemsCleared": {
3294
- "message": "{PH1} cleared"
3294
+ "message": "DOM Storage Items cleared"
3295
3295
  },
3296
3296
  "panels/application/DOMStorageItemsView.ts | domStorageNumberEntries": {
3297
3297
  "message": "Number of entries shown in table: {PH1}"
@@ -9794,6 +9794,9 @@
9794
9794
  "panels/sources/NavigatorView.ts | authored": {
9795
9795
  "message": "Authored"
9796
9796
  },
9797
+ "panels/sources/NavigatorView.ts | authoredTooltip": {
9798
+ "message": "Contains original sources"
9799
+ },
9797
9800
  "panels/sources/NavigatorView.ts | delete": {
9798
9801
  "message": "Delete"
9799
9802
  },
@@ -9803,6 +9806,9 @@
9803
9806
  "panels/sources/NavigatorView.ts | deployed": {
9804
9807
  "message": "Deployed"
9805
9808
  },
9809
+ "panels/sources/NavigatorView.ts | deployedTooltip": {
9810
+ "message": "Contains final sources the browser sees"
9811
+ },
9806
9812
  "panels/sources/NavigatorView.ts | excludeFolder": {
9807
9813
  "message": "Exclude folder"
9808
9814
  },
@@ -10163,6 +10169,9 @@
10163
10169
  "panels/sources/sources-meta.ts | watch": {
10164
10170
  "message": "Watch"
10165
10171
  },
10172
+ "panels/sources/SourcesNavigator.ts | authoredDescription": {
10173
+ "message": "Group files by Authored/Deployed"
10174
+ },
10166
10175
  "panels/sources/SourcesNavigator.ts | clearConfiguration": {
10167
10176
  "message": "Clear configuration"
10168
10177
  },
@@ -10233,7 +10242,7 @@
10233
10242
  "message": "Drop workspace folder here"
10234
10243
  },
10235
10244
  "panels/sources/SourcesPanel.ts | groupByAuthored": {
10236
- "message": "Group by Authored/Deployed (experimental)"
10245
+ "message": "Group by Authored/Deployed"
10237
10246
  },
10238
10247
  "panels/sources/SourcesPanel.ts | groupByFolder": {
10239
10248
  "message": "Group by folder"
@@ -11906,9 +11915,15 @@
11906
11915
  "ui/components/panel_feedback/PanelFeedback.ts | videoAndDocumentation": {
11907
11916
  "message": "Video and documentation"
11908
11917
  },
11918
+ "ui/components/panel_feedback/PreviewToggle.ts | learnMoreLink": {
11919
+ "message": "Learn More"
11920
+ },
11909
11921
  "ui/components/panel_feedback/PreviewToggle.ts | previewTextFeedbackLink": {
11910
11922
  "message": "Send us your feedback."
11911
11923
  },
11924
+ "ui/components/panel_feedback/PreviewToggle.ts | shortFeedbackLink": {
11925
+ "message": "Send feedback"
11926
+ },
11912
11927
  "ui/components/request_link_icon/RequestLinkIcon.ts | clickToShowRequestInTheNetwork": {
11913
11928
  "message": "Click to open the network panel and show request for URL: {url}"
11914
11929
  },
@@ -3291,7 +3291,7 @@
3291
3291
  "message": "D̂ÓM̂ Śt̂ór̂áĝé Ît́êḿŝ"
3292
3292
  },
3293
3293
  "panels/application/DOMStorageItemsView.ts | domStorageItemsCleared": {
3294
- "message": "{PH1} ĉĺêár̂éd̂"
3294
+ "message": "D̂ÓM̂ Śt̂ór̂áĝé Ît́êḿŝ ćl̂éâŕêd́"
3295
3295
  },
3296
3296
  "panels/application/DOMStorageItemsView.ts | domStorageNumberEntries": {
3297
3297
  "message": "N̂úm̂b́êŕ ôf́ êńt̂ŕîéŝ śĥóŵń îń t̂áb̂ĺê: {PH1}"
@@ -9794,6 +9794,9 @@
9794
9794
  "panels/sources/NavigatorView.ts | authored": {
9795
9795
  "message": "Âút̂h́ôŕêd́"
9796
9796
  },
9797
+ "panels/sources/NavigatorView.ts | authoredTooltip": {
9798
+ "message": "Ĉón̂t́âín̂ś ôŕîǵîńâĺ ŝóûŕĉéŝ"
9799
+ },
9797
9800
  "panels/sources/NavigatorView.ts | delete": {
9798
9801
  "message": "D̂él̂ét̂é"
9799
9802
  },
@@ -9803,6 +9806,9 @@
9803
9806
  "panels/sources/NavigatorView.ts | deployed": {
9804
9807
  "message": "D̂ép̂ĺôýêd́"
9805
9808
  },
9809
+ "panels/sources/NavigatorView.ts | deployedTooltip": {
9810
+ "message": "Ĉón̂t́âín̂ś f̂ín̂ál̂ śôúr̂ćêś t̂h́ê b́r̂óŵśêŕ ŝéêś"
9811
+ },
9806
9812
  "panels/sources/NavigatorView.ts | excludeFolder": {
9807
9813
  "message": "Êx́ĉĺûd́ê f́ôĺd̂ér̂"
9808
9814
  },
@@ -10163,6 +10169,9 @@
10163
10169
  "panels/sources/sources-meta.ts | watch": {
10164
10170
  "message": "Ŵát̂ćĥ"
10165
10171
  },
10172
+ "panels/sources/SourcesNavigator.ts | authoredDescription": {
10173
+ "message": "Ĝŕôúp̂ f́îĺêś b̂ý Âút̂h́ôŕêd́/D̂ép̂ĺôýêd́"
10174
+ },
10166
10175
  "panels/sources/SourcesNavigator.ts | clearConfiguration": {
10167
10176
  "message": "Ĉĺêár̂ ćôńf̂íĝúr̂át̂íôń"
10168
10177
  },
@@ -10233,7 +10242,7 @@
10233
10242
  "message": "D̂ŕôṕ ŵór̂ḱŝṕâćê f́ôĺd̂ér̂ h́êŕê"
10234
10243
  },
10235
10244
  "panels/sources/SourcesPanel.ts | groupByAuthored": {
10236
- "message": "Ĝŕôúp̂ b́ŷ Áût́ĥór̂éd̂/D́êṕl̂óŷéd̂ (éx̂ṕêŕîḿêńt̂ál̂)"
10245
+ "message": "Ĝŕôúp̂ b́ŷ Áût́ĥór̂éd̂/D́êṕl̂óŷéd̂"
10237
10246
  },
10238
10247
  "panels/sources/SourcesPanel.ts | groupByFolder": {
10239
10248
  "message": "Ĝŕôúp̂ b́ŷ f́ôĺd̂ér̂"
@@ -11906,9 +11915,15 @@
11906
11915
  "ui/components/panel_feedback/PanelFeedback.ts | videoAndDocumentation": {
11907
11916
  "message": "V̂íd̂éô án̂d́ d̂óĉúm̂én̂t́ât́îón̂"
11908
11917
  },
11918
+ "ui/components/panel_feedback/PreviewToggle.ts | learnMoreLink": {
11919
+ "message": "L̂éâŕn̂ Ḿôŕê"
11920
+ },
11909
11921
  "ui/components/panel_feedback/PreviewToggle.ts | previewTextFeedbackLink": {
11910
11922
  "message": "Ŝén̂d́ ûś ŷóûŕ f̂éêd́b̂áĉḱ."
11911
11923
  },
11924
+ "ui/components/panel_feedback/PreviewToggle.ts | shortFeedbackLink": {
11925
+ "message": "Ŝén̂d́ f̂éêd́b̂áĉḱ"
11926
+ },
11912
11927
  "ui/components/request_link_icon/RequestLinkIcon.ts | clickToShowRequestInTheNetwork": {
11913
11928
  "message": "Ĉĺîćk̂ t́ô óp̂én̂ t́ĥé n̂ét̂ẃôŕk̂ ṕâńêĺ âńd̂ śĥóŵ ŕêq́ûéŝt́ f̂ór̂ ÚR̂Ĺ: {url}"
11914
11929
  },
@@ -292,6 +292,7 @@ export enum ExperimentName {
292
292
  EYEDROPPER_COLOR_PICKER = 'eyedropperColorPicker',
293
293
  INSTRUMENTATION_BREAKPOINTS = 'instrumentationBreakpoints',
294
294
  CSS_AUTHORING_HINTS = 'cssAuthoringHints',
295
+ AUTHORED_DEPLOYED_GROUPING = 'authoredDeployedGrouping',
295
296
  }
296
297
 
297
298
  // TODO(crbug.com/1167717): Make this a const enum again
@@ -402,6 +402,10 @@ export class MainImpl {
402
402
  Root.Runtime.experiments.register(
403
403
  Root.Runtime.ExperimentName.EYEDROPPER_COLOR_PICKER, 'Enable color picking outside the browser window');
404
404
 
405
+ // Change grouping of sources panel to use Authored/Deployed trees
406
+ Root.Runtime.experiments.register(
407
+ Root.Runtime.ExperimentName.AUTHORED_DEPLOYED_GROUPING, 'Group sources into Authored and Deployed trees');
408
+
405
409
  Root.Runtime.experiments.enableExperimentsByDefault([
406
410
  'sourceOrderViewer',
407
411
  'hideIssuesFeature',
@@ -53,14 +53,14 @@ const UIStrings = {
53
53
  */
54
54
  value: 'Value',
55
55
  /**
56
- *@description Data grid name for DOM Storage Items data grids
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 number of entries after filtering
61
- *@example {'DOM Storage Items'} PH1
60
+ *@description Text for announcing that the "DOM Storage Items" table was cleared, that is, all
61
+ * entries were deleted.
62
62
  */
63
- domStorageItemsCleared: '{PH1} cleared',
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, {PH1: this.dataGrid.displayName}));
157
+ UI.ARIAUtils.alert(i18nString(UIStrings.domStorageItemsCleared));
158
158
  this.setCanDeleteSelected(false);
159
159
  }
160
160
 
@@ -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 Text in Heap Snapshot View of a profiler tool
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
  /**
@@ -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 navigatorGroupByAuthoredSetting: Common.Settings.Setting<boolean>;
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
- this.navigatorGroupByAuthoredSetting =
202
- Common.Settings.Settings.instance().moduleSetting('navigatorGroupByAuthored');
203
- this.navigatorGroupByAuthoredSetting.addChangeListener(this.groupingChanged.bind(this));
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
- new NavigatorGroupTreeNode(this, null, 'group:Authored', Types.Authored, UIStrings.authored);
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
- new NavigatorGroupTreeNode(this, null, 'group:Deployed', Types.Deployed, UIStrings.deployed);
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
- this.groupByAuthored = this.navigatorGroupByAuthoredSetting.get();
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
- const paths = [];
1134
- let currentNode: NavigatorTreeNode|null = node;
1135
- while (currentNode && !currentNode.isRoot()) {
1136
- paths.push(currentNode.title);
1137
- currentNode = currentNode.parent;
1138
- }
1139
- paths.reverse();
1140
- this.tooltip = paths.join('/');
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
- title: string) {
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 (experimental)',
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 groupByAuthoredSetting = Common.Settings.Settings.instance().moduleSetting('navigatorGroupByAuthored');
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), () => groupByAuthoredSetting.set(!groupByAuthoredSetting.get()),
559
- groupByAuthoredSetting.get());
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
+ }
@@ -18,6 +18,7 @@ export interface PreviewToggleData {
18
18
  helperText: string|null;
19
19
  feedbackURL: string|null;
20
20
  experiment: Root.Runtime.ExperimentName;
21
+ learnMoreURL?: string;
21
22
  onChangeCallback?: (checked: boolean) => void;
22
23
  }
23
24
 
@@ -26,6 +27,14 @@ const UIStrings = {
26
27
  *@description Link text the user can click to provide feedback to the team.
27
28
  */
28
29
  previewTextFeedbackLink: 'Send us your feedback.',
30
+ /**
31
+ *@description Link text the user can click to provide feedback to the team.
32
+ */
33
+ shortFeedbackLink: 'Send feedback',
34
+ /**
35
+ *@description Link text the user can click to see documentation.
36
+ */
37
+ learnMoreLink: 'Learn More',
29
38
  };
30
39
 
31
40
  const str_ = i18n.i18n.registerUIStrings('ui/components/panel_feedback/PreviewToggle.ts', UIStrings);
@@ -38,6 +47,7 @@ export class PreviewToggle extends HTMLElement {
38
47
  #name = '';
39
48
  #helperText: string|null = null;
40
49
  #feedbackURL: string|null = null;
50
+ #learnMoreURL: string|undefined;
41
51
  #experiment: string = '';
42
52
  #onChangeCallback?: (checked: boolean) => void;
43
53
 
@@ -49,6 +59,7 @@ export class PreviewToggle extends HTMLElement {
49
59
  this.#name = data.name;
50
60
  this.#helperText = data.helperText;
51
61
  this.#feedbackURL = data.feedbackURL;
62
+ this.#learnMoreURL = data.learnMoreURL;
52
63
  this.#experiment = data.experiment;
53
64
  this.#onChangeCallback = data.onChangeCallback;
54
65
  this.#render();
@@ -60,21 +71,31 @@ export class PreviewToggle extends HTMLElement {
60
71
  // clang-format off
61
72
  render(
62
73
  html`
63
- <label class="experiment-preview">
64
- <input type="checkbox" ?checked=${checked} @change=${this.#checkboxChanged} aria-label=${this.#name}/>
65
- <${IconButton.Icon.Icon.litTagName} .data=${{
66
- iconName: 'ic_preview_feature',
67
- width: '16px',
68
- height: '16px',
69
- color: 'var(--color-text-secondary)',
70
- } as IconButton.Icon.IconData}>
71
- </${IconButton.Icon.Icon.litTagName}>${this.#name}
72
- </div>
73
- <div class="helper">
74
- ${this.#helperText && this.#feedbackURL
75
- ? html`<p>${this.#helperText} <x-link href=${this.#feedbackURL}>${i18nString(UIStrings.previewTextFeedbackLink)}</x-link></p>`
74
+ <div class="container">
75
+ <div class="checkbox-line">
76
+ <label class="experiment-preview">
77
+ <input type="checkbox" ?checked=${checked} @change=${this.#checkboxChanged} aria-label=${this.#name}/>
78
+ <${IconButton.Icon.Icon.litTagName} .data=${{
79
+ iconName: 'ic_preview_feature',
80
+ width: '16px',
81
+ height: '16px',
82
+ color: 'var(--color-text-secondary)',
83
+ } as IconButton.Icon.IconData}>
84
+ </${IconButton.Icon.Icon.litTagName}>${this.#name}
85
+ </label>
86
+ ${this.#feedbackURL && !this.#helperText
87
+ ? html`<div class="feedback"><x-link class="x-link" href=${this.#feedbackURL}>${i18nString(UIStrings.shortFeedbackLink)}</x-link></div>`
88
+ : nothing}
89
+ </div>
90
+ ${this.#learnMoreURL
91
+ ? html`<x-link class="x-link" href=${this.#learnMoreURL}>${i18nString(UIStrings.learnMoreLink)}</x-link>`
76
92
  : nothing}
77
- </label>`,
93
+ <div class="helper">
94
+ ${this.#helperText && this.#feedbackURL
95
+ ? html`<p>${this.#helperText} <x-link class="x-link" href=${this.#feedbackURL}>${i18nString(UIStrings.previewTextFeedbackLink)}</x-link></p>`
96
+ : nothing}
97
+ </div>
98
+ </div>`,
78
99
  this.#shadow,
79
100
  {
80
101
  host: this,
@@ -18,7 +18,27 @@
18
18
  font-style: italic;
19
19
  }
20
20
 
21
- x-link { /* stylelint-disable-line selector-type-no-unknown */
21
+ .feedback {
22
+ text-align: right;
23
+ }
24
+
25
+ .checkbox-line {
26
+ display: flex;
27
+ justify-content: space-between;
28
+ align-items: center;
29
+ flex-wrap: wrap;
30
+ }
31
+
32
+ .container {
33
+ padding: 4px;
34
+ }
35
+
36
+ .x-link {
22
37
  color: var(--color-primary);
23
38
  text-decoration-line: underline;
39
+ padding: 4px;
40
+ }
41
+
42
+ .feedback .x-link {
43
+ color: var(--color-text-secondary);
24
44
  }
@@ -111,7 +111,7 @@ export class Item {
111
111
  };
112
112
  }
113
113
  case 'checkbox': {
114
- return {
114
+ const result = {
115
115
  type: 'checkbox',
116
116
  id: this.idInternal,
117
117
  label: this.label,
@@ -119,6 +119,11 @@ export class Item {
119
119
  enabled: !this.disabled,
120
120
  subItems: undefined,
121
121
  };
122
+ if (this.customElement) {
123
+ const resultAsSoftContextMenuItem = (result as SoftContextMenuDescriptor);
124
+ resultAsSoftContextMenuItem.element = (this.customElement as Element);
125
+ }
126
+ return result;
122
127
  }
123
128
  }
124
129
  throw new Error('Invalid item type:' + this.typeInternal);
@@ -187,12 +192,16 @@ export class Section {
187
192
  return item;
188
193
  }
189
194
 
190
- appendCheckboxItem(label: string, handler: () => void, checked?: boolean, disabled?: boolean): Item {
195
+ appendCheckboxItem(
196
+ label: string, handler: () => void, checked?: boolean, disabled?: boolean, additionalElement?: Element): Item {
191
197
  const item = new Item(this.contextMenu, 'checkbox', label, disabled, checked);
192
198
  this.items.push(item);
193
199
  if (this.contextMenu) {
194
200
  this.contextMenu.setHandler(item.id(), handler);
195
201
  }
202
+ if (additionalElement) {
203
+ item.customElement = additionalElement;
204
+ }
196
205
  return item;
197
206
  }
198
207
  }
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.1012379"
58
+ "version": "1.0.1012587"
59
59
  }
@@ -95,6 +95,9 @@ module.exports = {
95
95
 
96
96
  function checkTSTypeAnnotationForPotentialIssue(node) {
97
97
  const annotation = node.typeAnnotation;
98
+ if (!annotation) {
99
+ return;
100
+ }
98
101
  if (annotation.type === 'TSUnionType') {
99
102
  // matches foo(): X|Y
100
103
  checkUnionReturnTypeForLit(annotation);
@@ -137,6 +140,9 @@ module.exports = {
137
140
  },
138
141
  // Match values in interfaces or types.
139
142
  TSPropertySignature(node) {
143
+ if (!node.typeAnnotation) {
144
+ return;
145
+ }
140
146
  checkTSTypeAnnotationForPotentialIssue(node.typeAnnotation);
141
147
  },
142
148
  };