chrome-devtools-frontend 1.0.961907 → 1.0.964440

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/.eslintignore +5 -4
  2. package/AUTHORS +1 -0
  3. package/config/gni/devtools_grd_files.gni +1 -1
  4. package/docs/resource_management.md +119 -0
  5. package/docs/workflows.md +7 -0
  6. package/front_end/core/common/ParsedURL.ts +12 -10
  7. package/front_end/core/host/UserMetrics.ts +2 -1
  8. package/front_end/core/i18n/locales/en-US.json +2 -2
  9. package/front_end/core/i18n/locales/en-XL.json +2 -2
  10. package/front_end/core/protocol_client/InspectorBackend.ts +7 -7
  11. package/front_end/core/root/Runtime.ts +2 -0
  12. package/front_end/core/sdk/CSSProperty.ts +22 -110
  13. package/front_end/core/sdk/DOMModel.ts +2 -2
  14. package/front_end/core/sdk/DebuggerModel.ts +1 -1
  15. package/front_end/entrypoints/main/MainImpl.ts +7 -2
  16. package/front_end/generated/InspectorBackendCommands.js +8 -4
  17. package/front_end/generated/protocol-mapping.d.ts +12 -1
  18. package/front_end/generated/protocol-proxy-api.d.ts +11 -1
  19. package/front_end/generated/protocol-tsconfig.json +2 -2
  20. package/front_end/generated/protocol.ts +16787 -0
  21. package/front_end/models/javascript_metadata/NativeFunctions.js +7480 -4147
  22. package/front_end/models/persistence/IsolatedFileSystem.ts +3 -2
  23. package/front_end/models/persistence/PersistenceActions.ts +2 -2
  24. package/front_end/models/text_utils/text_utils-legacy.ts +0 -5
  25. package/front_end/models/text_utils/text_utils.ts +0 -2
  26. package/front_end/models/workspace/UISourceCode.ts +4 -5
  27. package/front_end/panels/animation/AnimationUI.ts +2 -1
  28. package/front_end/panels/application/AppManifestView.ts +7 -1
  29. package/front_end/panels/application/components/BackForwardCacheStrings.ts +1 -1
  30. package/front_end/panels/application/components/FrameDetailsView.ts +1 -0
  31. package/front_end/panels/elements/StylePropertyTreeElement.ts +13 -0
  32. package/front_end/panels/elements/StylesSidebarPane.ts +73 -4
  33. package/front_end/panels/elements/stylesSectionTree.css +28 -0
  34. package/front_end/panels/media/PlayerListView.ts +2 -0
  35. package/front_end/panels/media/playerListView.css +3 -0
  36. package/front_end/panels/sensors/sensors-meta.ts +2 -2
  37. package/front_end/panels/sources/NavigatorView.ts +1 -1
  38. package/front_end/ui/components/diff_view/DiffView.ts +2 -2
  39. package/front_end/ui/components/docs/icon_button/basic.ts +1 -1
  40. package/front_end/ui/components/icon_button/IconButton.ts +1 -1
  41. package/front_end/ui/legacy/GlassPane.ts +2 -0
  42. package/front_end/ui/legacy/components/inline_editor/cssLength.css +1 -0
  43. package/front_end/ui/legacy/softDropDownButton.css +2 -0
  44. package/front_end/ui/legacy/themeColors.css +3 -1
  45. package/front_end/ui/legacy/toolbar.css +6 -0
  46. package/package.json +1 -1
  47. package/scripts/build/devtools_plugin.js +103 -0
  48. package/scripts/build/ninja/{rollup.gni → bundle.gni} +2 -2
  49. package/scripts/build/ninja/devtools_entrypoint.gni +32 -24
  50. package/scripts/build/rollup.config.js +3 -93
  51. package/scripts/devtools_paths.js +3 -2
  52. package/scripts/devtools_paths.py +4 -0
  53. package/scripts/javascript_natives/helpers.js +211 -0
  54. package/scripts/javascript_natives/index.js +57 -194
  55. package/scripts/javascript_natives/package.json +8 -3
  56. package/scripts/javascript_natives/test.d.ts +9 -0
  57. package/scripts/javascript_natives/tests.js +195 -0
  58. package/scripts/protocol_typescript/protocol_dts_generator.ts +4 -9
  59. package/scripts/whitespaces.txt +1 -0
  60. package/front_end/generated/protocol.d.ts +0 -16771
  61. package/front_end/models/text_utils/CodeMirrorUtils.ts +0 -77
@@ -176,7 +176,7 @@ export class IsolatedFileSystem extends PlatformFileSystem {
176
176
  this.initialGitFoldersInternal.add(parentFolder);
177
177
  }
178
178
  if (this.isFileExcluded(entry.fullPath + '/')) {
179
- this.excludedEmbedderFolders.push(Common.ParsedURL.ParsedURL.capFilePrefix(
179
+ this.excludedEmbedderFolders.push(Common.ParsedURL.ParsedURL.urlToRawPathString(
180
180
  this.path() + entry.fullPath as Platform.DevToolsPath.UrlString, Host.Platform.isWin()));
181
181
  continue;
182
182
  }
@@ -555,7 +555,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
555
555
 
556
556
  tooltipForURL(url: string): string {
557
557
  const path = Platform.StringUtilities.trimMiddle(
558
- Common.ParsedURL.ParsedURL.capFilePrefix(url as Platform.DevToolsPath.UrlString, Host.Platform.isWin()), 150);
558
+ Common.ParsedURL.ParsedURL.urlToRawPathString(url as Platform.DevToolsPath.UrlString, Host.Platform.isWin()),
559
+ 150);
559
560
  return i18nString(UIStrings.linkedToS, {PH1: path});
560
561
  }
561
562
 
@@ -94,8 +94,8 @@ export class ContextMenuProvider implements UI.ContextMenu.Provider {
94
94
  const fileURL = binding ? binding.fileSystem.contentURL() : contentProvider.contentURL();
95
95
  if (fileURL.startsWith('file://')) {
96
96
  // TODO(crbug.com/1253323): Cast to UrlString will be removed when migration to branded types is complete.
97
- const path =
98
- Common.ParsedURL.ParsedURL.capFilePrefix(fileURL as Platform.DevToolsPath.UrlString, Host.Platform.isWin());
97
+ const path = Common.ParsedURL.ParsedURL.urlToRawPathString(
98
+ fileURL as Platform.DevToolsPath.UrlString, Host.Platform.isWin());
99
99
  contextMenu.revealSection().appendItem(
100
100
  i18nString(UIStrings.openInContainingFolder),
101
101
  () => Host.InspectorFrontendHost.InspectorFrontendHostInstance.showItemInFolder(path));
@@ -45,8 +45,3 @@ TextUtils.BalancedJSONTokenizer = TextUtilsModule.TextUtils.BalancedJSONTokenize
45
45
  TextUtils.TokenizerFactory = TextUtilsModule.TextUtils.TokenizerFactory;
46
46
 
47
47
  TextUtils.isMinified = TextUtilsModule.TextUtils.isMinified;
48
-
49
- TextUtils.CodeMirrorUtils = {};
50
-
51
- /** @constructor */
52
- TextUtils.CodeMirrorUtils.TokenizerFactory = TextUtilsModule.CodeMirrorUtils.TokenizerFactory;
@@ -2,7 +2,6 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- import * as CodeMirrorUtils from './CodeMirrorUtils.js';
6
5
  import * as ContentProvider from './ContentProvider.js';
7
6
  import * as StaticContentProvider from './StaticContentProvider.js';
8
7
  import * as Text from './Text.js';
@@ -11,7 +10,6 @@ import * as TextRange from './TextRange.js';
11
10
  import * as TextUtils from './TextUtils.js';
12
11
 
13
12
  export {
14
- CodeMirrorUtils,
15
13
  ContentProvider,
16
14
  StaticContentProvider,
17
15
  Text,
@@ -263,8 +263,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
263
263
  return;
264
264
  }
265
265
 
266
- if (this.contentInternal && 'content' in this.contentInternal &&
267
- this.contentInternal.content === updatedContent.content) {
266
+ if (this.contentInternal?.content === updatedContent.content) {
268
267
  this.lastAcceptedContent = null;
269
268
  return;
270
269
  }
@@ -331,7 +330,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
331
330
  if (this.isDirty()) {
332
331
  return this.workingCopyInternal as string;
333
332
  }
334
- return (this.contentInternal && 'content' in this.contentInternal && this.contentInternal.content) || '';
333
+ return this.contentInternal?.content || '';
335
334
  }
336
335
 
337
336
  resetWorkingCopy(): void {
@@ -393,7 +392,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
393
392
  }
394
393
 
395
394
  content(): string {
396
- return (this.contentInternal && 'content' in this.contentInternal && this.contentInternal.content) || '';
395
+ return this.contentInternal?.content || '';
397
396
  }
398
397
 
399
398
  loadError(): string|null {
@@ -439,7 +438,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
439
438
  }
440
439
 
441
440
  removeMessage(message: Message): void {
442
- if (this.messagesInternal && this.messagesInternal.delete(message)) {
441
+ if (this.messagesInternal?.delete(message)) {
443
442
  this.dispatchEventToListeners(Events.MessageRemoved, message);
444
443
  }
445
444
  }
@@ -279,7 +279,8 @@ export class AnimationUI {
279
279
  const iterationWidth = this.duration() * this.#timeline.pixelMsRatio();
280
280
  let iteration;
281
281
  for (iteration = 1; iteration < this.#animationInternal.source().iterations() &&
282
- iterationWidth * (iteration - 1) < this.#timeline.width();
282
+ iterationWidth * (iteration - 1) < this.#timeline.width() &&
283
+ (iterationWidth > 0 || this.#animationInternal.source().iterations() !== Infinity);
283
284
  iteration++) {
284
285
  this.renderIteration(this.#tailGroup, iteration);
285
286
  }
@@ -617,7 +617,13 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
617
617
  const copyButton = new IconButton.IconButton.IconButton();
618
618
  copyButton.title = i18nString(UIStrings.copyToClipboard);
619
619
  copyButton.data = {
620
- groups: [{iconName: 'copy_icon', iconHeight: '12px', iconWidth: '12px', text: ''}],
620
+ groups: [{
621
+ iconName: 'copy_icon',
622
+ iconHeight: '12px',
623
+ iconWidth: '12px',
624
+ text: '',
625
+ iconColor: 'var(--color-text-primary)',
626
+ }],
621
627
  clickHandler: (): void => {
622
628
  Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(recommendedId);
623
629
  },
@@ -508,7 +508,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/application/components/BackForw
508
508
  const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
509
509
 
510
510
  export const NotRestoredReasonDescription = {
511
- 'NotMainFrame': {name: i18nLazyString(UIStrings.notMainFrame)},
511
+ 'NotPrimaryMainFrame': {name: i18nLazyString(UIStrings.notMainFrame)},
512
512
  'BackForwardCacheDisabled': {name: i18nLazyString(UIStrings.backForwardCacheDisabled)},
513
513
  'RelatedActiveContentsExist': {name: i18nLazyString(UIStrings.relatedActiveContentsExist)},
514
514
  'HTTPStatusNotOK': {name: i18nLazyString(UIStrings.HTTPStatusNotOK)},
@@ -342,6 +342,7 @@ export class FrameDetailsReportView extends HTMLElement {
342
342
  {
343
343
  iconName: 'refresh_12x12_icon',
344
344
  text: i18nString(UIStrings.refresh),
345
+ iconColor: 'var(--color-text-primary)',
345
346
  } as IconButton.IconButton.IconWithTextData,
346
347
  ],
347
348
  } as IconButton.IconButton.IconButtonData}>
@@ -477,6 +477,8 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
477
477
  } else {
478
478
  this.listItemElement.classList.remove('disabled');
479
479
  }
480
+
481
+ this.listItemElement.classList.toggle('changed', this.parentPane().isPropertyChanged(this.property));
480
482
  }
481
483
 
482
484
  node(): SDK.DOMModel.DOMNode|null {
@@ -714,6 +716,14 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
714
716
  UI.ARIAUtils.setAccessibleName(
715
717
  enabledCheckboxElement, `${this.nameElement.textContent} ${this.valueElement.textContent}`);
716
718
  }
719
+
720
+ const copyIcon = UI.Icon.Icon.create('largeicon-copy', 'copy');
721
+ UI.Tooltip.Tooltip.install(copyIcon, i18nString(UIStrings.copyDeclaration));
722
+ copyIcon.addEventListener('click', () => {
723
+ const propertyText = `${this.property.name}: ${this.property.value};`;
724
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(propertyText);
725
+ });
726
+ this.listItemElement.append(copyIcon);
717
727
  this.listItemElement.insertBefore(enabledCheckboxElement, this.listItemElement.firstChild);
718
728
  }
719
729
  }
@@ -1470,6 +1480,9 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
1470
1480
  this.styleTextAppliedForTest();
1471
1481
  return;
1472
1482
  }
1483
+ if (updatedProperty) {
1484
+ this.listItemElement.classList.toggle('changed', this.parentPane().isPropertyChanged(updatedProperty));
1485
+ }
1473
1486
 
1474
1487
  this.matchedStylesInternal.resetActiveProperties();
1475
1488
  this.hasBeenEditedIncrementally = true;
@@ -40,6 +40,9 @@ import * as SDK from '../../core/sdk/sdk.js';
40
40
  import * as Protocol from '../../generated/protocol.js';
41
41
  import * as Bindings from '../../models/bindings/bindings.js';
42
42
  import * as TextUtils from '../../models/text_utils/text_utils.js';
43
+ import * as Workspace from '../../models/workspace/workspace.js';
44
+ import * as WorkspaceDiff from '../../models/workspace_diff/workspace_diff.js';
45
+ import * as DiffView from '../../ui/components/diff_view/diff_view.js';
43
46
  import * as IconButton from '../../ui/components/icon_button/icon_button.js';
44
47
  import * as InlineEditor from '../../ui/legacy/components/inline_editor/inline_editor.js';
45
48
  import * as Components from '../../ui/legacy/components/utils/utils.js';
@@ -162,12 +165,14 @@ const UIStrings = {
162
165
  newStyleRule: 'New Style Rule',
163
166
  /**
164
167
  *@description Text that is announced by the screen reader when the user focuses on an input field for entering the name of a CSS property in the Styles panel
168
+ *@example {margin} PH1
165
169
  */
166
- cssPropertyName: '`CSS` property name',
170
+ cssPropertyName: '`CSS` property name: {PH1}',
167
171
  /**
168
172
  *@description Text that is announced by the screen reader when the user focuses on an input field for entering the value of a CSS property in the Styles panel
173
+ *@example {10px} PH1
169
174
  */
170
- cssPropertyValue: '`CSS` property value',
175
+ cssPropertyValue: '`CSS` property value: {PH1}',
171
176
  /**
172
177
  *@description Text that is announced by the screen reader when the user focuses on an input field for editing the name of a CSS selector in the Styles panel
173
178
  */
@@ -231,6 +236,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
231
236
  private readonly resizeThrottler: Common.Throttler.Throttler;
232
237
  private readonly imagePreviewPopover: ImagePreviewPopover;
233
238
  activeCSSAngle: InlineEditor.CSSAngle.CSSAngle|null;
239
+ #changedLinesByURLs: Map<string, Set<number>> = new Map();
240
+ #uiSourceCodeToDiffCallbacks: Map<Workspace.UISourceCode.UISourceCode, () => void> = new Map();
234
241
 
235
242
  static instance(): StylesSidebarPane {
236
243
  if (!_stylesSidebarPaneInstance) {
@@ -834,7 +841,14 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
834
841
  const blocks = [new SectionBlock(null)];
835
842
  let sectionIdx = 0;
836
843
  let lastParentNode: SDK.DOMModel.DOMNode|null = null;
844
+ if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.STYLES_PANE_CSS_CHANGES)) {
845
+ this.resetChangedLinesTracking();
846
+ }
837
847
  for (const style of matchedStyles.nodeStyles()) {
848
+ if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.STYLES_PANE_CSS_CHANGES) && style.parentRule) {
849
+ await this.trackChangedLines(style.parentRule.resourceURL());
850
+ }
851
+
838
852
  const parentNode = matchedStyles.isInherited(style) ? matchedStyles.nodeForStyle(style) : null;
839
853
  if (parentNode && parentNode !== lastParentNode) {
840
854
  lastParentNode = parentNode;
@@ -987,6 +1001,61 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
987
1001
  return sections;
988
1002
  }
989
1003
 
1004
+ resetChangedLinesTracking(): void {
1005
+ this.#changedLinesByURLs.clear();
1006
+ for (const [uiSourceCode, callback] of this.#uiSourceCodeToDiffCallbacks) {
1007
+ WorkspaceDiff.WorkspaceDiff.workspaceDiff().unsubscribeFromDiffChange(uiSourceCode, callback);
1008
+ }
1009
+ this.#uiSourceCodeToDiffCallbacks.clear();
1010
+ }
1011
+
1012
+ async trackChangedLines(url: string): Promise<void> {
1013
+ if (!url || this.#changedLinesByURLs.has(url)) {
1014
+ return;
1015
+ }
1016
+ const uiSourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(url);
1017
+ if (uiSourceCode) {
1018
+ await this.refreshChangedLines(uiSourceCode);
1019
+ const callback = this.refreshChangedLines.bind(this, uiSourceCode);
1020
+ WorkspaceDiff.WorkspaceDiff.workspaceDiff().subscribeToDiffChange(uiSourceCode, callback);
1021
+ this.#uiSourceCodeToDiffCallbacks.set(uiSourceCode, callback);
1022
+ }
1023
+ }
1024
+
1025
+ isPropertyChanged(property: SDK.CSSProperty.CSSProperty): boolean {
1026
+ if (!Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.STYLES_PANE_CSS_CHANGES)) {
1027
+ return false;
1028
+ }
1029
+ const url = property.ownerStyle.parentRule?.resourceURL();
1030
+ if (!url) {
1031
+ return false;
1032
+ }
1033
+ const changedLines = this.#changedLinesByURLs.get(url);
1034
+ if (!changedLines) {
1035
+ return false;
1036
+ }
1037
+ const uiLocation = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().propertyUILocation(property, true);
1038
+ if (!uiLocation) {
1039
+ return false;
1040
+ }
1041
+ // UILocation's lineNumber starts at 0, but changedLines start at 1.
1042
+ return changedLines.has(uiLocation.lineNumber + 1);
1043
+ }
1044
+
1045
+ private async refreshChangedLines(uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> {
1046
+ const diff = await WorkspaceDiff.WorkspaceDiff.workspaceDiff().requestDiff(uiSourceCode, {shouldFormatDiff: true});
1047
+ const changedLines = new Set<number>();
1048
+ if (diff && diff.length > 0) {
1049
+ const {rows} = DiffView.DiffView.buildDiffRows(diff);
1050
+ for (const row of rows) {
1051
+ if (row.type === DiffView.DiffView.RowType.Addition) {
1052
+ changedLines.add(row.currentLineNumber);
1053
+ }
1054
+ }
1055
+ }
1056
+ this.#changedLinesByURLs.set(uiSourceCode.url(), changedLines);
1057
+ }
1058
+
990
1059
  private clipboardCopy(_event: Event): void {
991
1060
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleCopied);
992
1061
  }
@@ -3024,7 +3093,7 @@ export class StylesSidebarPropertyRenderer {
3024
3093
 
3025
3094
  renderName(): Element {
3026
3095
  const nameElement = document.createElement('span');
3027
- UI.ARIAUtils.setAccessibleName(nameElement, i18nString(UIStrings.cssPropertyName));
3096
+ UI.ARIAUtils.setAccessibleName(nameElement, i18nString(UIStrings.cssPropertyName, {PH1: this.propertyName}));
3028
3097
  nameElement.className = 'webkit-css-property';
3029
3098
  nameElement.textContent = this.propertyName;
3030
3099
  nameElement.normalize();
@@ -3033,7 +3102,7 @@ export class StylesSidebarPropertyRenderer {
3033
3102
 
3034
3103
  renderValue(): Element {
3035
3104
  const valueElement = document.createElement('span');
3036
- UI.ARIAUtils.setAccessibleName(valueElement, i18nString(UIStrings.cssPropertyValue));
3105
+ UI.ARIAUtils.setAccessibleName(valueElement, i18nString(UIStrings.cssPropertyValue, {PH1: this.propertyValue}));
3037
3106
  valueElement.className = 'value';
3038
3107
  if (!this.propertyValue) {
3039
3108
  return valueElement;
@@ -126,6 +126,34 @@ ol.expanded {
126
126
  opacity: 50%;
127
127
  }
128
128
 
129
+ .changed::after {
130
+ content: "";
131
+ position: absolute;
132
+ left: -4px;
133
+ width: 2px;
134
+ height: 100%;
135
+ background-color: var(--color-accent-green);
136
+ }
137
+
138
+ .copy {
139
+ display: none;
140
+ }
141
+
142
+ .changed:hover {
143
+ background-color: var(--color-accent-green-background);
144
+ }
145
+
146
+ .changed:hover .copy {
147
+ position: absolute;
148
+ right: -4px;
149
+ top: 0;
150
+ bottom: 0;
151
+ margin: auto;
152
+ display: inline-block;
153
+ cursor: pointer;
154
+ transform: scale(0.9);
155
+ }
156
+
129
157
  .has-ignorable-error {
130
158
  color: var(--color-text-disabled);
131
159
  }
@@ -87,8 +87,10 @@ export class PlayerListView extends UI.Widget.VBox implements TriggerDispatcher
87
87
  this.mainContainer.renderMainPanel(playerID);
88
88
  if (this.currentlySelectedEntry !== null) {
89
89
  this.currentlySelectedEntry.classList.remove('selected');
90
+ this.currentlySelectedEntry.classList.remove('force-white-icons');
90
91
  }
91
92
  element.classList.add('selected');
93
+ element.classList.add('force-white-icons');
92
94
  this.currentlySelectedEntry = element;
93
95
  }
94
96
 
@@ -42,6 +42,9 @@ li.storage-group-list-item::before {
42
42
 
43
43
  .player-entry-frame-title {
44
44
  height: 26px;
45
+ width: 125px;
46
+ min-width: 125px;
47
+ text-overflow: elipsis;
45
48
  padding: 0 10px;
46
49
  border-right: 1px solid var(--color-details-hairline);
47
50
  overflow: hidden;
@@ -184,7 +184,7 @@ Common.Settings.registerSettingExtension({
184
184
  title: 'Mountain View',
185
185
  lat: 37.386052,
186
186
  long: -122.083851,
187
- timezoneId: 'US/Pacific',
187
+ timezoneId: 'America/Los_Angeles',
188
188
  locale: 'en-US',
189
189
  },
190
190
  {
@@ -198,7 +198,7 @@ Common.Settings.registerSettingExtension({
198
198
  title: 'San Francisco',
199
199
  lat: 37.774929,
200
200
  long: -122.419416,
201
- timezoneId: 'US/Pacific',
201
+ timezoneId: 'America/Los_Angeles',
202
202
  locale: 'en-US',
203
203
  },
204
204
  {
@@ -849,7 +849,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
849
849
 
850
850
  if (project.type() === Workspace.Workspace.projectTypes.FileSystem) {
851
851
  // TODO(crbug.com/1253323): Cast to RawPathString will be removed when migration to branded types is complete.
852
- const folderPath = Common.ParsedURL.ParsedURL.capFilePrefix(
852
+ const folderPath = Common.ParsedURL.ParsedURL.urlToRawPathString(
853
853
  Persistence.FileSystemWorkspaceBinding.FileSystemWorkspaceBinding.completeURL(project, path) as
854
854
  Platform.DevToolsPath.UrlString,
855
855
  Host.Platform.isWin());
@@ -44,14 +44,14 @@ interface Row {
44
44
  type: RowType;
45
45
  }
46
46
 
47
- const enum RowType {
47
+ export const enum RowType {
48
48
  Deletion = 'deletion',
49
49
  Addition = 'addition',
50
50
  Equal = 'equal',
51
51
  Spacer = 'spacer',
52
52
  }
53
53
 
54
- function buildDiffRows(diff: Diff.Diff.DiffArray): {
54
+ export function buildDiffRows(diff: Diff.Diff.DiffArray): {
55
55
  originalLines: readonly string[],
56
56
  currentLines: readonly string[],
57
57
  rows: readonly Row[],
@@ -12,7 +12,7 @@ function appendComponent(data: IconButton.IconButton.IconButtonData) {
12
12
 
13
13
  appendComponent({
14
14
  clickHandler: (): void => {},
15
- groups: [{iconName: 'survey_feedback_icon', text: '1 item'}],
15
+ groups: [{iconName: 'survey_feedback_icon', iconColor: 'var(--color-text-primary)', text: '1 item'}],
16
16
  });
17
17
 
18
18
  appendComponent({
@@ -85,7 +85,7 @@ export class IconButton extends HTMLElement {
85
85
  ${filteredGroups.map(counter =>
86
86
  LitHtml.html`
87
87
  <${Icon.litTagName} class="status-icon"
88
- .data=${{iconName: counter.iconName, color: counter.iconColor || 'var(--color-text-primary)', width: counter.iconWidth || '1.5ex', height: counter.iconHeight || '1.5ex'} as IconData}>
88
+ .data=${{iconName: counter.iconName, color: counter.iconColor, width: counter.iconWidth || '1.5ex', height: counter.iconHeight || '1.5ex'} as IconData}>
89
89
  </${Icon.litTagName}>
90
90
  ${this.#compact ? LitHtml.html`<!-- Force line-height for this element --><span>&#8203;</span>` : LitHtml.nothing}
91
91
  <span class="icon-button-title">${counter.text}</span>
@@ -120,6 +120,7 @@ export class GlassPane {
120
120
  // Deliberately starts with 3000 to hide other z-indexed elements below.
121
121
  this.element.style.zIndex = `${3000 + 1000 * _panes.size}`;
122
122
  document.body.addEventListener('mousedown', this.onMouseDownBound, true);
123
+ document.body.addEventListener('pointerdown', this.onMouseDownBound, true);
123
124
  this.widgetInternal.show(document.body);
124
125
  _panes.add(this);
125
126
  this.positionContent();
@@ -131,6 +132,7 @@ export class GlassPane {
131
132
  }
132
133
  _panes.delete(this);
133
134
  this.element.ownerDocument.body.removeEventListener('mousedown', this.onMouseDownBound, true);
135
+ this.element.ownerDocument.body.removeEventListener('pointerdown', this.onMouseDownBound, true);
134
136
  this.widgetInternal.detach();
135
137
  }
136
138
 
@@ -23,6 +23,7 @@
23
23
  cursor: pointer;
24
24
  opacity: 0%;
25
25
  width: 0.8em;
26
+ background-color: var(--color-background);
26
27
  }
27
28
 
28
29
  .icon {
@@ -26,6 +26,8 @@ button.soft-dropdown > .title {
26
26
  @media (forced-colors: active) {
27
27
  button.soft-dropdown {
28
28
  border: 1px solid ButtonText;
29
+ background: ButtonFace;
30
+ color: ButtonText;
29
31
  }
30
32
 
31
33
  button.soft-dropdown[disabled] {
@@ -57,6 +57,7 @@
57
57
  --color-accent-red: rgb(217 48 37);
58
58
  --color-red: rgb(238 68 47);
59
59
  --color-accent-green: rgb(24 128 56);
60
+ --color-accent-green-background: rgb(24 128 56 / 10%);
60
61
  --color-green: rgb(99 172 190);
61
62
  --color-link: var(--color-primary);
62
63
  --color-syntax-1: rgb(200 0 0);
@@ -219,6 +220,7 @@
219
220
  --color-accent-red: rgb(242 139 130);
220
221
  --color-red: rgb(237 78 76);
221
222
  --color-accent-green: rgb(129 201 149);
223
+ --color-accent-green-background: rgb(129 201 149 / 20%);
222
224
  --color-link: var(--color-primary);
223
225
  --color-syntax-1: rgb(53 212 199);
224
226
  --color-syntax-2: rgb(93 176 215);
@@ -258,7 +260,7 @@
258
260
  --color-error-background: hsl(0deg 100% 8%);
259
261
  --color-checkbox-accent-color: rgb(255 165 0);
260
262
  /* Colors for styling inputs */
261
- --color-input-outline: rgb(189 193 198);
263
+ --color-input-outline: rgb(60 64 67);
262
264
  --color-input-outline-active: rgb(138 180 248);
263
265
  --color-input-outline-error: rgb(242 139 130);
264
266
  --color-input-outline-disabled: rgba(189 193 198 / 20%);
@@ -537,4 +537,10 @@ devtools-icon.leading-issue-icon {
537
537
  .toolbar-item .devtools-link {
538
538
  color: linktext;
539
539
  }
540
+
541
+ .toolbar-has-dropdown {
542
+ forced-color-adjust: none;
543
+ background: ButtonFace;
544
+ color: ButtonText;
545
+ }
540
546
  }
package/package.json CHANGED
@@ -53,5 +53,5 @@
53
53
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
54
54
  "watch": "third_party/node/node.py --output scripts/watch_build.js"
55
55
  },
56
- "version": "1.0.961907"
56
+ "version": "1.0.964440"
57
57
  }
@@ -0,0 +1,103 @@
1
+ // Copyright 2022 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ // @ts-check
6
+
7
+ const path = require('path');
8
+
9
+ /**
10
+ * `path.dirname` does not include trailing slashes. If we would always
11
+ * use `path.dirname` and then later perform comparisons on the paths that
12
+ * it returns, we could run into false positives. For example, given the
13
+ * the following two paths:
14
+ *
15
+ * front_end/timeline_model/TimelineModel.js
16
+ * front_end/timeline/Timeline.js
17
+ *
18
+ * And that would have the following values for `path.dirname`:
19
+ *
20
+ * front_end/timeline_model
21
+ * front_end/timeline
22
+ *
23
+ * If we would do a simple `.startswith` on the `path.dirname` of both of
24
+ * these paths, then the first path would start with the dirname of the
25
+ * second. However, they *are* part of different folders. To fix that problem,
26
+ * we need to force a path separator after each folder. That makes sure we
27
+ * and up with the following comparison of path dirnames:
28
+ *
29
+ * front_end/timeline_model/
30
+ * front_end/timeline/
31
+ *
32
+ * Now, the first path does *not* start with the second one, as expected.
33
+ *
34
+ * @param {string} file
35
+ * @return {string}
36
+ */
37
+ function dirnameWithSeparator(file) {
38
+ return path.dirname(file) + path.sep;
39
+ }
40
+
41
+ function devtoolsPlugin(source, importer) {
42
+ if (!importer) {
43
+ return null;
44
+ }
45
+ const currentDirectory = path.normalize(dirnameWithSeparator(importer));
46
+ const importedFilelocation = path.normalize(path.join(currentDirectory, source));
47
+ const importedFileDirectory = dirnameWithSeparator(importedFilelocation);
48
+
49
+ // Generated files are part of other directories, as they are only imported once
50
+ if (path.basename(importedFileDirectory) === 'generated') {
51
+ return null;
52
+ }
53
+
54
+ // An import is considered external (and therefore a separate
55
+ // bundle) if its filename matches its immediate parent's folder
56
+ // name (without the extension). For example:
57
+ // import * as Components from './components/components.js' = external
58
+ // import * as UI from '../ui/ui.js' = external
59
+ // import * as LitHtml from '../third_party/lit-html/lit-html.js' = external
60
+ // import {DataGrid} from './components/DataGrid.js' = not external
61
+ // import * as Components from './components/foo.js' = not external
62
+
63
+ // Note that we can't do a simple check for only `third_party`, as in Chromium
64
+ // our full path is `third_party/devtools-frontend/src/`, which thus *always*
65
+ // includes third_party. It also not possible to use the current directory
66
+ // as a check for the import, as the import will be different in Chromium and
67
+ // would therefore not match the path of `__dirname`.
68
+ // These should be removed because the new heuristic _should_ deal with these
69
+ // e.g. it'll pick up third_party/lit-html/lit-html.js is its own entrypoint
70
+
71
+ // Puppeteer has dynamic imports in its build gated on an ifNode
72
+ // flag, but our Rollup config doesn't know about that and tries
73
+ // to parse dynamic import('fs'). Let's ignore Puppeteer for now.
74
+ // The long term plan is probably for Puppeteer to ship a web
75
+ // bundle anyway. See go/pptr-agnostify for details.
76
+ if (importedFileDirectory.includes(path.join('front_end', 'third_party', 'puppeteer'))) {
77
+ return null;
78
+ }
79
+
80
+ // The CodeMirror addons look like bundles (addon/comment/comment.js) but are not.
81
+ if (importedFileDirectory.includes(path.join('front_end', 'third_party', 'codemirror', 'package'))) {
82
+ return null;
83
+ }
84
+
85
+ // The LightHouse bundle shouldn't be processed by `terser` again, as it is uniquely built
86
+ if (importedFilelocation.includes(path.join('front_end', 'third_party', 'lighthouse', 'lighthouse-dt-bundle.js'))) {
87
+ return {
88
+ id: importedFilelocation,
89
+ external: true,
90
+ };
91
+ }
92
+
93
+ const importedFileName = path.basename(importedFilelocation, '.js');
94
+ const importedFileParentDirectory = path.basename(path.dirname(importedFilelocation));
95
+ const isExternal = importedFileName === importedFileParentDirectory;
96
+
97
+ return {
98
+ id: importedFilelocation,
99
+ external: isExternal,
100
+ };
101
+ }
102
+
103
+ module.exports = {devtoolsPlugin};
@@ -5,9 +5,9 @@
5
5
  import("./node.gni")
6
6
  import("./vars.gni")
7
7
 
8
- template("rollup") {
8
+ template("bundle") {
9
9
  assert(defined(invoker.entrypoint),
10
- "You must define the 'entrypoint' for a rollup target")
10
+ "You must define the 'entrypoint' for a bundle target")
11
11
 
12
12
  node_action(target_name) {
13
13
  script = "node_modules/rollup/dist/bin/rollup"