chrome-devtools-frontend 1.0.978040 → 1.0.979150

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.
@@ -27,6 +27,7 @@ module.exports = {
27
27
  'files': ['*.ts'],
28
28
  'rules': {
29
29
  '@typescript-eslint/explicit-function-return-type': 2,
30
+ 'rulesdir/no_importing_images_from_src': 2,
30
31
  'rulesdir/enforce_custom_event_names': 2,
31
32
  'rulesdir/set_data_type_reference': 2,
32
33
  'rulesdir/lit_html_data_as_type': 2,
@@ -2,6 +2,7 @@
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 type * as Platform from '../platform/platform.js';
5
6
  import * as Protocol from '../../generated/protocol.js';
6
7
  import * as TextUtils from '../../models/text_utils/text_utils.js';
7
8
 
@@ -44,9 +45,9 @@ export class CSSRule {
44
45
  this.style.rebase(edit);
45
46
  }
46
47
 
47
- resourceURL(): string {
48
+ resourceURL(): Platform.DevToolsPath.UrlString {
48
49
  if (!this.styleSheetId) {
49
- return '';
50
+ return '' as Platform.DevToolsPath.UrlString;
50
51
  }
51
52
  const styleSheetHeader = this.getStyleSheetHeader(this.styleSheetId);
52
53
  return styleSheetHeader.resourceURL();
@@ -6,6 +6,7 @@ import * as TextUtils from '../../models/text_utils/text_utils.js';
6
6
  import * as Common from '../common/common.js';
7
7
  import * as i18n from '../i18n/i18n.js';
8
8
  import type * as Platform from '../platform/platform.js';
9
+ import * as Root from '../root/root.js';
9
10
  import type * as Protocol from '../../generated/protocol.js';
10
11
 
11
12
  import type {CSSModel} from './CSSModel.js';
@@ -104,27 +105,38 @@ export class CSSStyleSheetHeader implements TextUtils.ContentProvider.ContentPro
104
105
  }
105
106
 
106
107
  resourceURL(): Platform.DevToolsPath.UrlString {
107
- return (this.isViaInspector() ? this.viaInspectorResourceURL() : this.sourceURL);
108
+ const url = this.isViaInspector() ? this.viaInspectorResourceURL() : this.sourceURL;
109
+ if (!url && Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.STYLES_PANE_CSS_CHANGES)) {
110
+ return this.dynamicStyleURL();
111
+ }
112
+ return url;
108
113
  }
109
114
 
110
- private viaInspectorResourceURL(): Platform.DevToolsPath.UrlString {
115
+ private getFrameURLPath(): string {
111
116
  const model = this.#cssModelInternal.target().model(ResourceTreeModel);
112
117
  console.assert(Boolean(model));
113
118
  if (!model) {
114
- return '' as Platform.DevToolsPath.UrlString;
119
+ return '';
115
120
  }
116
121
  const frame = model.frameForId(this.frameId);
117
122
  if (!frame) {
118
- return '' as Platform.DevToolsPath.UrlString;
123
+ return '';
119
124
  }
120
125
  console.assert(Boolean(frame));
121
126
  const parsedURL = new Common.ParsedURL.ParsedURL(frame.url);
122
- let fakeURL = 'inspector://' + parsedURL.host + parsedURL.folderPathComponents;
123
- if (!fakeURL.endsWith('/')) {
124
- fakeURL += '/';
127
+ let urlPath = parsedURL.host + parsedURL.folderPathComponents;
128
+ if (!urlPath.endsWith('/')) {
129
+ urlPath += '/';
125
130
  }
126
- fakeURL += 'inspector-stylesheet';
127
- return fakeURL as Platform.DevToolsPath.UrlString;
131
+ return urlPath;
132
+ }
133
+
134
+ private viaInspectorResourceURL(): Platform.DevToolsPath.UrlString {
135
+ return `inspector://${this.getFrameURLPath()}inspector-stylesheet` as Platform.DevToolsPath.UrlString;
136
+ }
137
+
138
+ private dynamicStyleURL(): Platform.DevToolsPath.UrlString {
139
+ return `stylesheet://${this.getFrameURLPath()}style#${this.id}` as Platform.DevToolsPath.UrlString;
128
140
  }
129
141
 
130
142
  lineNumberInSource(lineNumberInStyleSheet: number): number {
@@ -423,15 +423,15 @@ export class ResourceTreeModel extends SDKModel<EventTypes> {
423
423
  }
424
424
 
425
425
  async fetchAppManifest(): Promise<{
426
- url: string,
426
+ url: Platform.DevToolsPath.UrlString,
427
427
  data: string|null,
428
428
  errors: Array<Protocol.Page.AppManifestError>,
429
429
  }> {
430
430
  const response = await this.agent.invoke_getAppManifest();
431
431
  if (response.getError()) {
432
- return {url: response.url, data: null, errors: []};
432
+ return {url: response.url as Platform.DevToolsPath.UrlString, data: null, errors: []};
433
433
  }
434
- return {url: response.url, data: response.data || null, errors: response.errors};
434
+ return {url: response.url as Platform.DevToolsPath.UrlString, data: response.data || null, errors: response.errors};
435
435
  }
436
436
 
437
437
  async getInstallabilityErrors(): Promise<Protocol.Page.InstallabilityError[]> {
@@ -8,6 +8,7 @@ export const enum FormatterActions {
8
8
  HTML_OUTLINE = 'htmlOutline',
9
9
  JAVASCRIPT_OUTLINE = 'javaScriptOutline',
10
10
  JAVASCRIPT_IDENTIFIERS = 'javaScriptIdentifiers',
11
+ JAVASCRIPT_SUBSTITUTE = 'javaScriptSubstitute',
11
12
  EVALUATE_JAVASCRIPT_SUBSTRING = 'evaluatableJavaScriptSubstring',
12
13
  ARGUMENTS_LIST = 'argumentsList',
13
14
  }
@@ -42,7 +42,7 @@ import {HTMLFormatter} from './HTMLFormatter.js';
42
42
  import {IdentityFormatter} from './IdentityFormatter.js';
43
43
  import {JavaScriptFormatter} from './JavaScriptFormatter.js';
44
44
  import {JSONFormatter} from './JSONFormatter.js';
45
- import {computeSubstitution, applySubstitution} from './Substitute.js';
45
+ import {substituteExpression} from './Substitute.js';
46
46
 
47
47
  export interface Chunk {
48
48
  // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
@@ -306,4 +306,4 @@ export function argumentsList(content: string): string[] {
306
306
  }
307
307
  })();
308
308
 
309
- export {applySubstitution, computeSubstitution};
309
+ export {substituteExpression};
@@ -6,7 +6,12 @@ import * as Acorn from '../../third_party/acorn/acorn.js';
6
6
 
7
7
  import {ECMA_VERSION} from './AcornTokenizer.js';
8
8
 
9
- export interface Replacement {
9
+ export function substituteExpression(expression: string, nameMap: Map<string, string>): string {
10
+ const replacements = computeSubstitution(expression, nameMap);
11
+ return applySubstitution(expression, replacements);
12
+ }
13
+
14
+ interface Replacement {
10
15
  from: string;
11
16
  to: string;
12
17
  offset: number;
@@ -17,7 +22,7 @@ export interface Replacement {
17
22
  // function returns a list of replacements sorted by the offset. The function throws if
18
23
  // it cannot parse the expression or the substitution is impossible to perform (for example
19
24
  // if the substitution target is 'this' within a function, it would become bound there).
20
- export function computeSubstitution(expression: string, nameMap: Map<string, string>): Replacement[] {
25
+ function computeSubstitution(expression: string, nameMap: Map<string, string>): Replacement[] {
21
26
  // Parse the expression and find variables and scopes.
22
27
  const root = Acorn.parse(expression, {ecmaVersion: ECMA_VERSION, allowAwaitOutsideFunction: true, ranges: false}) as
23
28
  Acorn.ESTree.Node;
@@ -80,7 +85,7 @@ export function computeSubstitution(expression: string, nameMap: Map<string, str
80
85
  return result;
81
86
  }
82
87
 
83
- export function applySubstitution(expression: string, replacements: Replacement[]): string {
88
+ function applySubstitution(expression: string, replacements: Replacement[]): string {
84
89
  const accumulator = [];
85
90
  let last = 0;
86
91
  for (const r of replacements) {
@@ -10,7 +10,8 @@ import {FormatterActions} from './FormatterActions.js';
10
10
 
11
11
  self.onmessage = function(event: MessageEvent): void {
12
12
  const method: FormatterActions = event.data.method;
13
- const params: {indentString: string, content: string, mimeType: string} = event.data.params;
13
+ const params: {indentString: string, content: string, mimeType: string, mapping: [string, string][]} =
14
+ event.data.params;
14
15
  if (!method) {
15
16
  return;
16
17
  }
@@ -31,6 +32,11 @@ self.onmessage = function(event: MessageEvent): void {
31
32
  case FormatterActions.JAVASCRIPT_IDENTIFIERS:
32
33
  self.postMessage(FormatterWorker.FormatterWorker.javaScriptIdentifiers(params.content));
33
34
  break;
35
+ case FormatterActions.JAVASCRIPT_SUBSTITUTE: {
36
+ const mapping = new Map<string, string>(params.mapping);
37
+ self.postMessage(FormatterWorker.Substitute.substituteExpression(params.content, mapping));
38
+ break;
39
+ }
34
40
  case FormatterActions.EVALUATE_JAVASCRIPT_SUBSTRING:
35
41
  self.postMessage(FormatterWorker.FormatterWorker.evaluatableJavaScriptSubstring(params.content));
36
42
  break;
@@ -108,7 +108,7 @@ export class FormatterWorkerPool {
108
108
  }
109
109
 
110
110
  private runTask(methodName: FormatterActions.FormatterActions, params: {
111
- [x: string]: string,
111
+ [x: string]: string|string[][],
112
112
  // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
113
113
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
114
114
  }): Promise<any> {
@@ -132,6 +132,14 @@ export class FormatterWorkerPool {
132
132
  .then(ids => ids || []);
133
133
  }
134
134
 
135
+ javaScriptSubstitute(expression: string, mapping: Map<string, string>): Promise<string> {
136
+ return this
137
+ .runTask(
138
+ FormatterActions.FormatterActions.JAVASCRIPT_SUBSTITUTE,
139
+ {content: expression, mapping: Array.from(mapping.entries())})
140
+ .then(result => result || '');
141
+ }
142
+
135
143
  evaluatableJavaScriptSubstring(content: string): Promise<string> {
136
144
  return this.runTask(FormatterActions.FormatterActions.EVALUATE_JAVASCRIPT_SUBSTRING, {content: content})
137
145
  .then(text => text || '');
@@ -179,13 +187,13 @@ export class FormatterWorkerPool {
179
187
  class Task {
180
188
  method: string;
181
189
  params: {
182
- [x: string]: string,
190
+ [x: string]: string|string[][],
183
191
  };
184
192
  callback: (arg0: MessageEvent|null) => void;
185
193
  isChunked: boolean|undefined;
186
194
  constructor(
187
195
  method: string, params: {
188
- [x: string]: string,
196
+ [x: string]: string|string[][],
189
197
  },
190
198
  callback: (arg0: MessageEvent|null) => void, isChunked?: boolean) {
191
199
  this.method = method;
@@ -16,8 +16,6 @@ import * as UI from '../../ui/legacy/legacy.js';
16
16
  import type * as Protocol from '../../generated/protocol.js';
17
17
  import * as IconButton from '../../ui/components/icon_button/icon_button.js';
18
18
 
19
- // TODO(crbug.com/1253323): Casts to UrlString will be removed from this file when migration to branded types is complete.
20
-
21
19
  const UIStrings = {
22
20
  /**
23
21
  *@description Text in App Manifest View of the Application panel
@@ -543,7 +541,7 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
543
541
  }
544
542
 
545
543
  private async renderManifest(
546
- url: string, data: string|null, errors: Protocol.Page.AppManifestError[],
544
+ url: Platform.DevToolsPath.UrlString, data: string|null, errors: Protocol.Page.AppManifestError[],
547
545
  installabilityErrors: Protocol.Page.InstallabilityError[], manifestIcons: {
548
546
  primaryIcon: string|null,
549
547
  },
@@ -642,12 +640,13 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
642
640
 
643
641
  this.startURLField.removeChildren();
644
642
  if (startURL) {
645
- const completeURL =
646
- (Common.ParsedURL.ParsedURL.completeURL(url as Platform.DevToolsPath.UrlString, startURL) as string);
647
- const link = Components.Linkifier.Linkifier.linkifyURL(
648
- completeURL, ({text: startURL} as Components.Linkifier.LinkifyURLOptions));
649
- link.tabIndex = 0;
650
- this.startURLField.appendChild(link);
643
+ const completeURL = Common.ParsedURL.ParsedURL.completeURL(url, startURL);
644
+ if (completeURL) {
645
+ const link = Components.Linkifier.Linkifier.linkifyURL(
646
+ completeURL, ({text: startURL} as Components.Linkifier.LinkifyURLOptions));
647
+ link.tabIndex = 0;
648
+ this.startURLField.appendChild(link);
649
+ }
651
650
  }
652
651
 
653
652
  this.themeColorSwatch.classList.toggle('hidden', !stringProperty('theme_color'));
@@ -694,8 +693,7 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
694
693
  this.newNoteUrlField.parentElement?.classList.toggle('hidden', !hasNewNoteUrl);
695
694
  this.newNoteUrlField.removeChildren();
696
695
  if (hasNewNoteUrl) {
697
- const completeURL =
698
- (Common.ParsedURL.ParsedURL.completeURL(url as Platform.DevToolsPath.UrlString, newNoteUrl) as string);
696
+ const completeURL = (Common.ParsedURL.ParsedURL.completeURL(url, newNoteUrl) as string);
699
697
  const link = Components.Linkifier.Linkifier.linkifyURL(
700
698
  completeURL, ({text: newNoteUrl} as Components.Linkifier.LinkifyURLOptions));
701
699
  link.tabIndex = 0;
@@ -765,8 +763,7 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
765
763
  shortcutSection.appendFlexedField('Description', shortcut.description);
766
764
  }
767
765
  const urlField = shortcutSection.appendFlexedField('URL');
768
- const shortcutUrl =
769
- (Common.ParsedURL.ParsedURL.completeURL(url as Platform.DevToolsPath.UrlString, shortcut.url) as string);
766
+ const shortcutUrl = (Common.ParsedURL.ParsedURL.completeURL(url, shortcut.url) as string);
770
767
  const link = Components.Linkifier.Linkifier.linkifyURL(
771
768
  shortcutUrl, ({text: shortcut.url} as Components.Linkifier.LinkifyURLOptions));
772
769
  link.tabIndex = 0;
@@ -1018,7 +1015,8 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
1018
1015
  private async appendImageResourceToSection(
1019
1016
  // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
1020
1017
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1021
- baseUrl: string, imageResource: any, section: UI.ReportView.Section, isScreenshot: boolean):
1018
+ baseUrl: Platform.DevToolsPath.UrlString, imageResource: any, section: UI.ReportView.Section,
1019
+ isScreenshot: boolean):
1022
1020
  Promise<{imageResourceErrors: Platform.UIString.LocalizedString[], squareSizedIconAvailable?: boolean}> {
1023
1021
  const imageResourceErrors: Platform.UIString.LocalizedString[] = [];
1024
1022
  const resourceName = isScreenshot ? i18nString(UIStrings.screenshot) : i18nString(UIStrings.icon);
@@ -1026,8 +1024,7 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
1026
1024
  imageResourceErrors.push(i18nString(UIStrings.sSrcIsNotSet, {PH1: resourceName}));
1027
1025
  return {imageResourceErrors};
1028
1026
  }
1029
- const imageUrl =
1030
- Common.ParsedURL.ParsedURL.completeURL(baseUrl as Platform.DevToolsPath.UrlString, imageResource['src']);
1027
+ const imageUrl = Common.ParsedURL.ParsedURL.completeURL(baseUrl, imageResource['src']);
1031
1028
  if (!imageUrl) {
1032
1029
  imageResourceErrors.push(
1033
1030
  i18nString(UIStrings.sUrlSFailedToParse, {PH1: resourceName, PH2: imageResource['src']}));
@@ -7,6 +7,7 @@ import * as Host from '../../core/host/host.js';
7
7
  import * as i18n from '../../core/i18n/i18n.js';
8
8
  import * as Root from '../../core/root/root.js';
9
9
  import * as SDK from '../../core/sdk/sdk.js';
10
+ import * as Formatter from '../../models/formatter/formatter.js';
10
11
  import * as SourceMapScopes from '../../models/source_map_scopes/source_map_scopes.js';
11
12
  import * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
12
13
  import * as TextEditor from '../../ui/components/text_editor/text_editor.js';
@@ -309,7 +310,7 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
309
310
  const callFrame = executionContext.debuggerModel.selectedCallFrame();
310
311
  if (callFrame) {
311
312
  const nameMap = await SourceMapScopes.NamesResolver.allVariablesInCallFrame(callFrame);
312
- expression = this.substituteNames(expression, nameMap);
313
+ expression = await this.substituteNames(expression, nameMap);
313
314
  }
314
315
  }
315
316
 
@@ -317,11 +318,12 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
317
318
  executionContext, message, expression, useCommandLineAPI);
318
319
  }
319
320
 
320
- private substituteNames(expression: string, mapping: Map<string, string>): string {
321
- // TODO(jarin) Build a more reliable replacer, based on the parsed AST.
322
- // Here, we just replace exact occurrences.
323
- const replacement = mapping.get(expression);
324
- return replacement ?? expression;
321
+ private async substituteNames(expression: string, mapping: Map<string, string>): Promise<string> {
322
+ try {
323
+ return await Formatter.FormatterWorkerPool.formatterWorkerPool().javaScriptSubstitute(expression, mapping);
324
+ } catch {
325
+ return expression;
326
+ }
325
327
  }
326
328
 
327
329
  private editorUpdate(update: CodeMirror.ViewUpdate): void {
@@ -3,7 +3,6 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as Common from '../../core/common/common.js';
6
- import type * as Platform from '../../core/platform/platform.js';
7
6
  import type * as SDK from '../../core/sdk/sdk.js';
8
7
  import type * as Protocol from '../../generated/protocol.js';
9
8
 
@@ -81,10 +80,7 @@ export function parseSourcePositionsFromErrorStack(
81
80
  }
82
81
  let url = parseOrScriptMatch(debuggerModel, splitResult.url);
83
82
  if (!url && Common.ParsedURL.ParsedURL.isRelativeURL(splitResult.url)) {
84
- // TODO(crbug.com/1253323): Cast to UrlString will be removed when migration to branded types is complete.
85
- url = parseOrScriptMatch(
86
- debuggerModel,
87
- Common.ParsedURL.ParsedURL.completeURL(baseURL as Platform.DevToolsPath.UrlString, splitResult.url));
83
+ url = parseOrScriptMatch(debuggerModel, Common.ParsedURL.ParsedURL.completeURL(baseURL, splitResult.url));
88
84
  }
89
85
  if (!url) {
90
86
  return null;
@@ -219,9 +219,7 @@ const HIGHLIGHTABLE_PROPERTIES = [
219
219
  {mode: 'flexibility', properties: ['flex', 'flex-basis', 'flex-grow', 'flex-shrink']},
220
220
  ];
221
221
 
222
- // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
223
- // eslint-disable-next-line @typescript-eslint/naming-convention
224
- let _stylesSidebarPaneInstance: StylesSidebarPane;
222
+ let stylesSidebarPaneInstance: StylesSidebarPane;
225
223
 
226
224
  // TODO(crbug.com/1172300) This workaround is needed to keep the linter happy.
227
225
  // Otherwise it complains about: Unknown word CssSyntaxError
@@ -258,10 +256,10 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
258
256
  #urlToChangeTracker: Map<string, ChangeTracker> = new Map();
259
257
 
260
258
  static instance(): StylesSidebarPane {
261
- if (!_stylesSidebarPaneInstance) {
262
- _stylesSidebarPaneInstance = new StylesSidebarPane();
259
+ if (!stylesSidebarPaneInstance) {
260
+ stylesSidebarPaneInstance = new StylesSidebarPane();
263
261
  }
264
- return _stylesSidebarPaneInstance;
262
+ return stylesSidebarPaneInstance;
265
263
  }
266
264
 
267
265
  private constructor() {
@@ -292,7 +290,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
292
290
  this.swatchPopoverHelperInternal = new InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper();
293
291
  this.swatchPopoverHelperInternal.addEventListener(
294
292
  InlineEditor.SwatchPopoverHelper.Events.WillShowPopover, this.hideAllPopovers, this);
295
- this.linkifier = new Components.Linkifier.Linkifier(_maxLinkLength, /* useLinkDecorator */ true);
293
+ this.linkifier = new Components.Linkifier.Linkifier(MAX_LINK_LENGTH, /* useLinkDecorator */ true);
296
294
  this.decorator = new StylePropertyHighlighter(this);
297
295
  this.lastRevealedProperty = null;
298
296
  this.userOperation = false;
@@ -307,7 +305,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
307
305
  this.sectionBlocks = [];
308
306
  this.idleCallbackManager = null;
309
307
  this.needsForceUpdate = false;
310
- _stylesSidebarPaneInstance = this;
308
+ stylesSidebarPaneInstance = this;
311
309
  UI.Context.Context.instance().addFlavorChangeListener(SDK.DOMModel.DOMNode, this.forceUpdate, this);
312
310
  this.contentElement.addEventListener('copy', this.clipboardCopy.bind(this));
313
311
  this.resizeThrottler = new Common.Throttler.Throttler(100);
@@ -1392,9 +1390,7 @@ async function buildPropertyRuleMaps(content: string):
1392
1390
  return {propertyToSelector, ruleToSelector};
1393
1391
  }
1394
1392
 
1395
- // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
1396
- // eslint-disable-next-line @typescript-eslint/naming-convention
1397
- export const _maxLinkLength = 23;
1393
+ const MAX_LINK_LENGTH = 23;
1398
1394
 
1399
1395
  export class SectionBlock {
1400
1396
  private readonly titleElementInternal: Element|null;
@@ -3461,8 +3457,7 @@ export class StylesSidebarPropertyRenderer {
3461
3457
  UI.UIUtils.createTextChild(container, 'url(');
3462
3458
  let hrefUrl: (string|null)|null = null;
3463
3459
  if (this.rule && this.rule.resourceURL()) {
3464
- // TODO(crbug.com/1253323): Cast to UrlString will be removed when migration to branded types is complete.
3465
- hrefUrl = Common.ParsedURL.ParsedURL.completeURL(this.rule.resourceURL() as Platform.DevToolsPath.UrlString, url);
3460
+ hrefUrl = Common.ParsedURL.ParsedURL.completeURL(this.rule.resourceURL(), url);
3466
3461
  } else if (this.node) {
3467
3462
  hrefUrl = this.node.resolveURL(url);
3468
3463
  }
@@ -44,6 +44,7 @@ slot[name="property-value"] {
44
44
 
45
45
  .goto {
46
46
  display: none;
47
+ cursor: pointer;
47
48
  position: absolute;
48
49
  width: var(--goto-size);
49
50
  height: var(--goto-size);
@@ -24,6 +24,7 @@
24
24
  --size: 16px;
25
25
 
26
26
  display: none;
27
+ cursor: pointer;
27
28
  position: absolute;
28
29
  width: var(--size);
29
30
  height: var(--size);
@@ -13,6 +13,8 @@ import type * as TextUtils from '../../models/text_utils/text_utils.js';
13
13
  import * as UI from '../../ui/legacy/legacy.js';
14
14
  import * as Workspace from '../../models/workspace/workspace.js';
15
15
 
16
+ // TODO(crbug.com/1253323): Cast to EncodedPathString will be removed from this file when migration to branded types is complete.
17
+
16
18
  const UIStrings = {
17
19
  /**
18
20
  *@description Default snippet name when a new snippet is created in the Sources panel
@@ -40,7 +42,6 @@ export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFi
40
42
  private readonly lastSnippetIdentifierSetting: Common.Settings.Setting<number>;
41
43
  private readonly snippetsSetting: Common.Settings.Setting<Snippet[]>;
42
44
  constructor() {
43
- // TODO(crbug.com/1253323): Cast to UrlString will be removed when migration to branded types is complete.
44
45
  super('snippet://', 'snippets');
45
46
  this.lastSnippetIdentifierSetting =
46
47
  Common.Settings.Settings.instance().createSetting('scriptSnippets_lastIdentifier', 0);
@@ -75,14 +75,18 @@
75
75
  margin: auto;
76
76
  }
77
77
 
78
+ .authenticator-section-header {
79
+ display: flex;
80
+ justify-content: space-between;
81
+ align-items: flex-end;
82
+ }
83
+
78
84
  .authenticator-section-title {
79
85
  line-height: 24px;
80
- width: 260px;
81
86
  display: inline-block;
82
87
  }
83
88
 
84
89
  .authenticator-section-title .authenticator-name-field {
85
- width: 220px;
86
90
  display: inline-block;
87
91
  font-weight: bold;
88
92
  border: none;
@@ -178,7 +178,7 @@ export class ImagePreview {
178
178
 
179
179
  // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
180
180
  // @ts-expect-error
181
- const featuresObject = object.callFunctionJSON(features, undefined);
181
+ const featuresObject = await object.callFunctionJSON(features, undefined);
182
182
  object.release();
183
183
  return featuresObject;
184
184
 
package/package.json CHANGED
@@ -54,5 +54,5 @@
54
54
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
55
55
  "watch": "third_party/node/node.py --output scripts/watch_build.js"
56
56
  },
57
- "version": "1.0.978040"
57
+ "version": "1.0.979150"
58
58
  }
@@ -0,0 +1,61 @@
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
+ 'use strict';
5
+
6
+ /**
7
+ * @fileoverview Prevent importing SVG urls from the `src` directory, and
8
+ * ensure they are read from `Images/foo.svg`.
9
+ * Images in the `src/` directory are minified and put into `Images/` as part
10
+ * of the build process, so we should never import from 'src'.
11
+ */
12
+
13
+ // ------------------------------------------------------------------------------
14
+ // Rule Definition
15
+ // ------------------------------------------------------------------------------
16
+
17
+ const SRC_DIRECTORY_PATH_TO_MATCH = 'Images/src/';
18
+
19
+ module.exports = {
20
+ meta: {
21
+ type: 'problem',
22
+
23
+ docs: {
24
+ description: 'ensure image imports do not include the src/ directory',
25
+ category: 'Possible Errors',
26
+ },
27
+ fixable: 'code',
28
+ schema: [],
29
+ messages: {
30
+ imageImportUsingSrc:
31
+ 'Found an image import containing the `src/` directory. You should always import `Images/foo.svg`.',
32
+ },
33
+ },
34
+ create: function(context) {
35
+ return {
36
+ // Matches new URL(...)
37
+ 'NewExpression[callee.name=\'URL\']'(node) {
38
+ if (!node.arguments || node.arguments.length < 1) {
39
+ // Invalid code: user is probably mid-way through typing! Just leave
40
+ // it; TypeScript will error if it ends up being invalid.
41
+ return;
42
+ }
43
+ /** @type {String} */
44
+ const filePath = node.arguments[0].value;
45
+ if (!filePath) {
46
+ return;
47
+ }
48
+ if (filePath.includes(SRC_DIRECTORY_PATH_TO_MATCH)) {
49
+ context.report({
50
+ node: node.arguments[0],
51
+ messageId: 'imageImportUsingSrc',
52
+ fix(fixer) {
53
+ return fixer.replaceText(
54
+ node.arguments[0], `'${filePath.replace(SRC_DIRECTORY_PATH_TO_MATCH, 'Images/')}'`);
55
+ }
56
+ });
57
+ }
58
+ }
59
+ };
60
+ }
61
+ };
@@ -0,0 +1,40 @@
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
+ 'use strict';
5
+
6
+ const rule = require('../lib/no_importing_images_from_src.js');
7
+ const ruleTester = new (require('eslint').RuleTester)({
8
+ parser: require.resolve('@typescript-eslint/parser'),
9
+ parserOptions: {ecmaVersion: 9, sourceType: 'module'},
10
+ });
11
+
12
+ ruleTester.run('no_importing_images_from_src', rule, {
13
+ valid: [
14
+ {
15
+ code: 'const someIcon = new URL(\'../../../Images/test_icon.svg\', import.meta.url).toString()',
16
+ filename: 'front_end/ui/components/component/file.ts',
17
+ },
18
+ ],
19
+
20
+ invalid: [
21
+ {
22
+ code: 'const someIcon = new URL(\'../../../Images/src/test_icon.svg\', import.meta.url).toString()',
23
+ filename: 'front_end/ui/components/component/file.ts',
24
+ output: 'const someIcon = new URL(\'../../../Images/test_icon.svg\', import.meta.url).toString()',
25
+ errors: [{
26
+ messageId: 'imageImportUsingSrc',
27
+ }],
28
+ },
29
+ {
30
+ code:
31
+ 'const someIcon = new URL(\'../../../devtools-frontend/front_end/Images/src/test_icon.svg\', import.meta.url).toString()',
32
+ filename: 'front_end/ui/components/component/file.ts',
33
+ output:
34
+ 'const someIcon = new URL(\'../../../devtools-frontend/front_end/Images/test_icon.svg\', import.meta.url).toString()',
35
+ errors: [{
36
+ messageId: 'imageImportUsingSrc',
37
+ }],
38
+ },
39
+ ],
40
+ });