chrome-devtools-frontend 1.0.980472 → 1.0.981004

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 (28) hide show
  1. package/front_end/core/common/ParsedURL.ts +37 -4
  2. package/front_end/core/platform/DevToolsPath.ts +3 -0
  3. package/front_end/core/sdk/CSSRule.ts +2 -2
  4. package/front_end/core/sdk/DOMDebuggerModel.ts +2 -2
  5. package/front_end/core/sdk/NetworkRequest.ts +1 -1
  6. package/front_end/core/sdk/SourceMap.ts +14 -5
  7. package/front_end/core/sdk/Target.ts +2 -2
  8. package/front_end/legacy_test_runner/bindings_test_runner/BindingsTestRunner.js +5 -0
  9. package/front_end/models/bindings/BreakpointManager.ts +0 -2
  10. package/front_end/models/bindings/ContentProviderBasedProject.ts +6 -4
  11. package/front_end/models/persistence/EditFileSystemView.ts +3 -1
  12. package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +14 -9
  13. package/front_end/models/persistence/IsolatedFileSystem.ts +66 -40
  14. package/front_end/models/persistence/IsolatedFileSystemManager.ts +4 -3
  15. package/front_end/models/persistence/NetworkPersistenceManager.ts +6 -5
  16. package/front_end/models/persistence/PlatformFileSystem.ts +15 -10
  17. package/front_end/models/workspace/UISourceCode.ts +4 -2
  18. package/front_end/models/workspace/WorkspaceImpl.ts +9 -5
  19. package/front_end/panels/application/ServiceWorkerCacheViews.ts +1 -1
  20. package/front_end/panels/network/ResourceWebSocketFrameView.ts +1 -2
  21. package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +25 -19
  22. package/front_end/panels/sources/NavigatorView.ts +9 -5
  23. package/front_end/panels/sources/SourcesNavigator.ts +2 -2
  24. package/front_end/ui/components/buttons/Button.ts +11 -1
  25. package/front_end/ui/components/buttons/button.css +31 -10
  26. package/front_end/ui/components/docs/button/basic.ts +47 -1
  27. package/front_end/ui/legacy/themeColors.css +4 -0
  28. package/package.json +1 -1
@@ -64,6 +64,16 @@ export function normalizePath(path: string): string {
64
64
  return normalizedPath;
65
65
  }
66
66
 
67
+ /**
68
+ * File paths in DevTools that are represented either as unencoded absolute or relative paths, or encoded paths, or URLs.
69
+ * @example
70
+ * RawPathString: “/Hello World/file.js”
71
+ * EncodedPathString: “/Hello%20World/file.js”
72
+ * UrlString: “file:///Hello%20World/file/js”
73
+ */
74
+ type BrandedPathString =
75
+ Platform.DevToolsPath.UrlString|Platform.DevToolsPath.RawPathString|Platform.DevToolsPath.EncodedPathString;
76
+
67
77
  export class ParsedURL {
68
78
  isValid: boolean;
69
79
  url: string;
@@ -215,18 +225,41 @@ export class ParsedURL {
215
225
  return decodedFileURL.substr('file://'.length) as Platform.DevToolsPath.RawPathString;
216
226
  }
217
227
 
218
- static substr<DevToolsPathType extends Platform.DevToolsPath.UrlString|Platform.DevToolsPath.RawPathString|
219
- Platform.DevToolsPath.EncodedPathString>(
228
+ static sliceUrlToEncodedPathString(url: Platform.DevToolsPath.UrlString, start: number):
229
+ Platform.DevToolsPath.EncodedPathString {
230
+ return url.substring(start) as Platform.DevToolsPath.EncodedPathString;
231
+ }
232
+
233
+ static substr<DevToolsPathType extends BrandedPathString>(
220
234
  devToolsPath: DevToolsPathType, from: number, length?: number): DevToolsPathType {
221
235
  return devToolsPath.substr(from, length) as DevToolsPathType;
222
236
  }
223
237
 
224
- static concatenate<DevToolsPathType extends Platform.DevToolsPath.UrlString|Platform.DevToolsPath
225
- .RawPathString|Platform.DevToolsPath.EncodedPathString>(
238
+ static substring<DevToolsPathType extends BrandedPathString>(
239
+ devToolsPath: DevToolsPathType, start: number, end?: number): DevToolsPathType {
240
+ return devToolsPath.substring(start, end) as DevToolsPathType;
241
+ }
242
+
243
+ static prepend<DevToolsPathType extends BrandedPathString>(prefix: string, devToolsPath: DevToolsPathType):
244
+ DevToolsPathType {
245
+ return prefix + devToolsPath as DevToolsPathType;
246
+ }
247
+
248
+ static concatenate<DevToolsPathType extends BrandedPathString>(
226
249
  devToolsPath: DevToolsPathType, ...appendage: string[]): DevToolsPathType {
227
250
  return devToolsPath.concat(...appendage) as DevToolsPathType;
228
251
  }
229
252
 
253
+ static trim<DevToolsPathType extends BrandedPathString>(devToolsPath: DevToolsPathType): DevToolsPathType {
254
+ return devToolsPath.trim() as DevToolsPathType;
255
+ }
256
+
257
+ static join<DevToolsPathType extends Platform.DevToolsPath.UrlString|Platform.DevToolsPath.RawPathString|
258
+ Platform.DevToolsPath.EncodedPathString>(
259
+ devToolsPaths: DevToolsPathType[], separator?: string): DevToolsPathType {
260
+ return devToolsPaths.join(separator) as DevToolsPathType;
261
+ }
262
+
230
263
  static urlWithoutHash(url: string): string {
231
264
  const hashIndex = url.indexOf('#');
232
265
  if (hashIndex !== -1) {
@@ -11,6 +11,7 @@ class UrlStringTag {
11
11
  * “file:///Hello%20World/file/js”
12
12
  */
13
13
  export type UrlString = string&UrlStringTag;
14
+ export const EmptyUrlString = '' as UrlString;
14
15
 
15
16
  class RawPathStringTag {
16
17
  private rawPathTag: (string|undefined);
@@ -22,6 +23,7 @@ class RawPathStringTag {
22
23
  * “/Hello World/file.js”
23
24
  */
24
25
  export type RawPathString = string&RawPathStringTag;
26
+ export const EmptyRawPathString = '' as RawPathString;
25
27
 
26
28
  class EncodedPathStringTag {
27
29
  private encodedPathTag: (string|undefined);
@@ -32,3 +34,4 @@ class EncodedPathStringTag {
32
34
  * “/Hello%20World/file.js”
33
35
  */
34
36
  export type EncodedPathString = string&EncodedPathStringTag;
37
+ export const EmptyEncodedPathString = '' as EncodedPathString;
@@ -2,9 +2,9 @@
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';
6
5
  import * as Protocol from '../../generated/protocol.js';
7
6
  import * as TextUtils from '../../models/text_utils/text_utils.js';
7
+ import * as Platform from '../platform/platform.js';
8
8
 
9
9
  import {CSSContainerQuery} from './CSSContainerQuery.js';
10
10
  import {CSSLayer} from './CSSLayer.js';
@@ -47,7 +47,7 @@ export class CSSRule {
47
47
 
48
48
  resourceURL(): Platform.DevToolsPath.UrlString {
49
49
  if (!this.styleSheetId) {
50
- return '' as Platform.DevToolsPath.UrlString;
50
+ return Platform.DevToolsPath.EmptyUrlString;
51
51
  }
52
52
  const styleSheetHeader = this.getStyleSheetHeader(this.styleSheetId);
53
53
  return styleSheetHeader.resourceURL();
@@ -4,7 +4,7 @@
4
4
 
5
5
  import * as Common from '../common/common.js';
6
6
  import * as i18n from '../i18n/i18n.js';
7
- import type * as Platform from '../platform/platform.js';
7
+ import * as Platform from '../platform/platform.js';
8
8
  import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
9
9
  import * as Protocol from '../../generated/protocol.js';
10
10
 
@@ -534,7 +534,7 @@ export class EventListener {
534
534
  this.#originalHandlerInternal = originalHandler || handler;
535
535
  this.#locationInternal = location;
536
536
  const script = location.script();
537
- this.#sourceURLInternal = script ? script.contentURL() : '' as Platform.DevToolsPath.UrlString;
537
+ this.#sourceURLInternal = script ? script.contentURL() : Platform.DevToolsPath.EmptyUrlString;
538
538
  this.#customRemoveFunction = customRemoveFunction;
539
539
  this.#originInternal = origin || EventListener.Origin.Raw;
540
540
  }
@@ -379,7 +379,7 @@ export class NetworkRequest extends Common.ObjectWrapper.ObjectWrapper<EventType
379
379
  backendRequestId: Protocol.Network.RequestId, requestURL: Platform.DevToolsPath.UrlString,
380
380
  initiator?: Protocol.Network.Initiator): NetworkRequest {
381
381
  return new NetworkRequest(
382
- backendRequestId, backendRequestId, requestURL, '' as Platform.DevToolsPath.UrlString, null, null,
382
+ backendRequestId, backendRequestId, requestURL, Platform.DevToolsPath.EmptyUrlString, null, null,
383
383
  initiator || null);
384
384
  }
385
385
 
@@ -296,10 +296,19 @@ export class TextSourceMap implements SourceMap {
296
296
  ++endIndex;
297
297
  ++i;
298
298
  }
299
- const endLine = endIndex < mappings.length ? mappings[endIndex].lineNumber : Infinity;
300
- const endColumn = endIndex < mappings.length ? mappings[endIndex].columnNumber : 0;
301
- ranges.push(new TextUtils.TextRange.TextRange(
302
- mappings[startIndex].lineNumber, mappings[startIndex].columnNumber, endLine, endColumn));
299
+
300
+ // Source maps don't contain end positions for entries, but each entry is assumed to
301
+ // span until the following entry. This doesn't work however in case of the last
302
+ // entry, where there's no following entry. We also don't know the number of lines
303
+ // and columns in the original source code (which might not be available at all), so
304
+ // for that case we store the maximum signed 32-bit integer, which is definitely going
305
+ // to be larger than any script we can process and can safely be serialized as part of
306
+ // the skip list we send to V8 with `Debugger.stepOver` (http://crbug.com/1305956).
307
+ const startLine = mappings[startIndex].lineNumber;
308
+ const startColumn = mappings[startIndex].columnNumber;
309
+ const endLine = endIndex < mappings.length ? mappings[endIndex].lineNumber : 2 ** 31 - 1;
310
+ const endColumn = endIndex < mappings.length ? mappings[endIndex].columnNumber : 2 ** 31 - 1;
311
+ ranges.push(new TextUtils.TextRange.TextRange(startLine, startColumn, endLine, endColumn));
303
312
  }
304
313
 
305
314
  return ranges;
@@ -360,7 +369,7 @@ export class TextSourceMap implements SourceMap {
360
369
 
361
370
  private parseSources(sourceMap: SourceMapV3): void {
362
371
  const sourcesList = [];
363
- let sourceRoot = sourceMap.sourceRoot || '' as Platform.DevToolsPath.UrlString;
372
+ let sourceRoot = sourceMap.sourceRoot || Platform.DevToolsPath.EmptyUrlString;
364
373
  if (sourceRoot && !sourceRoot.endsWith('/')) {
365
374
  sourceRoot = Common.ParsedURL.ParsedURL.concatenate(sourceRoot, '/');
366
375
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  import * as Common from '../common/common.js';
6
6
  import * as Host from '../host/host.js';
7
- import type * as Platform from '../platform/platform.js';
7
+ import * as Platform from '../platform/platform.js';
8
8
  import * as ProtocolClient from '../protocol_client/protocol_client.js';
9
9
  import type * as Protocol from '../../generated/protocol.js';
10
10
  import type {TargetManager} from './TargetManager.js';
@@ -32,7 +32,7 @@ export class Target extends ProtocolClient.InspectorBackend.TargetBase {
32
32
  super(needsNodeJSPatching, parentTarget, sessionId, connection);
33
33
  this.#targetManagerInternal = targetManager;
34
34
  this.#nameInternal = name;
35
- this.#inspectedURLInternal = '' as Platform.DevToolsPath.UrlString;
35
+ this.#inspectedURLInternal = Platform.DevToolsPath.EmptyUrlString;
36
36
  this.#inspectedURLName = '';
37
37
  this.#capabilitiesMask = 0;
38
38
  switch (type) {
@@ -236,3 +236,8 @@ BindingsTestRunner.dumpLocation = async function(liveLocation, hint) {
236
236
  prefix + BindingsTestRunner.cleanupURL(uiLocation.uiSourceCode.url()) + ':' + uiLocation.lineNumber + ':' +
237
237
  uiLocation.columnNumber);
238
238
  };
239
+
240
+ BindingsTestRunner.GC = async () => {
241
+ await TestRunner.evaluateInPageAsync(`new Promise(resolve =>
242
+ GCController.asyncCollectAll(resolve))`);
243
+ };
@@ -28,8 +28,6 @@
28
28
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
  */
30
30
 
31
- // TODO(crbug.com/1253323): All casts to RawPathString will be removed from this file when migration to branded types is complete.
32
-
33
31
  import * as Common from '../../core/common/common.js';
34
32
  import * as SDK from '../../core/sdk/sdk.js';
35
33
  import type * as Platform from '../../core/platform/platform.js';
@@ -30,6 +30,7 @@
30
30
 
31
31
  import type * as Common from '../../core/common/common.js';
32
32
  import * as i18n from '../../core/i18n/i18n.js';
33
+ import type * as Platform from '../../core/platform/platform.js';
33
34
  import type * as TextUtils from '../text_utils/text_utils.js';
34
35
  import * as Workspace from '../workspace/workspace.js';
35
36
 
@@ -115,7 +116,7 @@ export class ContentProviderBasedProject extends Workspace.Workspace.ProjectStor
115
116
  }
116
117
 
117
118
  rename(
118
- uiSourceCode: Workspace.UISourceCode.UISourceCode, newName: string,
119
+ uiSourceCode: Workspace.UISourceCode.UISourceCode, newName: Platform.DevToolsPath.RawPathString,
119
120
  callback:
120
121
  (arg0: boolean, arg1?: string|undefined, arg2?: string|undefined,
121
122
  arg3?: Common.ResourceType.ResourceType|undefined) => void): void {
@@ -139,12 +140,13 @@ export class ContentProviderBasedProject extends Workspace.Workspace.ProjectStor
139
140
  excludeFolder(_path: string): void {
140
141
  }
141
142
 
142
- canExcludeFolder(_path: string): boolean {
143
+ canExcludeFolder(_path: Platform.DevToolsPath.EncodedPathString): boolean {
143
144
  return false;
144
145
  }
145
146
 
146
- async createFile(_path: string, _name: string|null, _content: string, _isBase64?: boolean):
147
- Promise<Workspace.UISourceCode.UISourceCode|null> {
147
+ async createFile(
148
+ _path: Platform.DevToolsPath.EncodedPathString, _name: string|null, _content: string,
149
+ _isBase64?: boolean): Promise<Workspace.UISourceCode.UISourceCode|null> {
148
150
  return null;
149
151
  }
150
152
 
@@ -30,6 +30,7 @@
30
30
 
31
31
  import * as Common from '../../core/common/common.js';
32
32
  import * as i18n from '../../core/i18n/i18n.js';
33
+ import type * as Platform from '../../core/platform/platform.js';
33
34
  import * as UI from '../../ui/legacy/legacy.js';
34
35
 
35
36
  import editFileSystemViewStyles from './editFileSystemView.css.js';
@@ -152,7 +153,8 @@ export class EditFileSystemView extends UI.Widget.VBox implements UI.ListWidget.
152
153
  if (!isNew) {
153
154
  this.getFileSystem().removeExcludedFolder(item);
154
155
  }
155
- this.getFileSystem().addExcludedFolder(this.normalizePrefix(editor.control('pathPrefix').value));
156
+ this.getFileSystem().addExcludedFolder(
157
+ this.normalizePrefix(editor.control('pathPrefix').value) as Platform.DevToolsPath.EncodedPathString);
156
158
  this.muteUpdate = false;
157
159
  this.update();
158
160
  }
@@ -28,6 +28,8 @@
28
28
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
  */
30
30
 
31
+ // TODO(crbug.com/1253323): Cast to Branded Types will be removed from this file when migration to branded types is complete.
32
+
31
33
  import * as Common from '../../core/common/common.js';
32
34
  import * as Platform from '../../core/platform/platform.js';
33
35
  import * as TextUtils from '../text_utils/text_utils.js';
@@ -200,7 +202,8 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
200
202
 
201
203
  private filePathForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode):
202
204
  Platform.DevToolsPath.EncodedPathString {
203
- return uiSourceCode.url().substring(this.fileSystemPathInternal.length) as Platform.DevToolsPath.EncodedPathString;
205
+ return Common.ParsedURL.ParsedURL.sliceUrlToEncodedPathString(
206
+ uiSourceCode.url(), this.fileSystemPathInternal.length);
204
207
  }
205
208
 
206
209
  isServiceProject(): boolean {
@@ -257,7 +260,7 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
257
260
  }
258
261
 
259
262
  rename(
260
- uiSourceCode: Workspace.UISourceCode.UISourceCode, newName: string,
263
+ uiSourceCode: Workspace.UISourceCode.UISourceCode, newName: Platform.DevToolsPath.RawPathString,
261
264
  callback:
262
265
  (arg0: boolean, arg1?: string|undefined, arg2?: string|undefined,
263
266
  arg3?: Common.ResourceType.ResourceType|undefined) => void): void {
@@ -339,12 +342,13 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
339
342
  }
340
343
 
341
344
  excludeFolder(url: string): void {
342
- let relativeFolder = url.substring(this.fileSystemBaseURL.length);
345
+ let relativeFolder = Common.ParsedURL.ParsedURL.sliceUrlToEncodedPathString(
346
+ url as Platform.DevToolsPath.UrlString, this.fileSystemBaseURL.length);
343
347
  if (!relativeFolder.startsWith('/')) {
344
- relativeFolder = '/' + relativeFolder;
348
+ relativeFolder = Common.ParsedURL.ParsedURL.prepend('/', relativeFolder);
345
349
  }
346
350
  if (!relativeFolder.endsWith('/')) {
347
- relativeFolder += '/';
351
+ relativeFolder = Common.ParsedURL.ParsedURL.concatenate(relativeFolder, '/');
348
352
  }
349
353
  this.fileSystemInternal.addExcludedFolder(relativeFolder);
350
354
 
@@ -357,7 +361,7 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
357
361
  }
358
362
  }
359
363
 
360
- canExcludeFolder(path: string): boolean {
364
+ canExcludeFolder(path: Platform.DevToolsPath.EncodedPathString): boolean {
361
365
  return this.fileSystemInternal.canExcludeFolder(path);
362
366
  }
363
367
 
@@ -365,8 +369,9 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
365
369
  return true;
366
370
  }
367
371
 
368
- async createFile(path: string, name: string|null, content: string, isBase64?: boolean):
369
- Promise<Workspace.UISourceCode.UISourceCode|null> {
372
+ async createFile(
373
+ path: Platform.DevToolsPath.EncodedPathString, name: Platform.DevToolsPath.RawPathString|null, content: string,
374
+ isBase64?: boolean): Promise<Workspace.UISourceCode.UISourceCode|null> {
370
375
  const guardFileName = this.fileSystemPathInternal + path + (!path.endsWith('/') ? '/' : '') + name;
371
376
  this.creatingFilesGuard.add(guardFileName);
372
377
  const filePath = await this.fileSystemInternal.createFile(path, name);
@@ -392,7 +397,7 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
392
397
  this.fileSystemWorkspaceBinding.isolatedFileSystemManager.removeFileSystem(this.fileSystemInternal);
393
398
  }
394
399
 
395
- private addFile(filePath: string): Workspace.UISourceCode.UISourceCode {
400
+ private addFile(filePath: Platform.DevToolsPath.EncodedPathString): Workspace.UISourceCode.UISourceCode {
396
401
  const contentType = this.fileSystemInternal.contentType(filePath);
397
402
  const uiSourceCode = this.createUISourceCode(this.fileSystemBaseURL + filePath, contentType);
398
403
  this.addUISourceCode(uiSourceCode);
@@ -70,17 +70,19 @@ const str_ = i18n.i18n.registerUIStrings('models/persistence/IsolatedFileSystem.
70
70
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
71
71
  export class IsolatedFileSystem extends PlatformFileSystem {
72
72
  private readonly manager: IsolatedFileSystemManager;
73
- private readonly embedderPathInternal: string;
73
+ private readonly embedderPathInternal: Platform.DevToolsPath.RawPathString;
74
74
  private readonly domFileSystem: FileSystem;
75
- private readonly excludedFoldersSetting: Common.Settings.Setting<{[path: string]: string[]}>;
76
- private excludedFoldersInternal: Set<string>;
77
- private readonly excludedEmbedderFolders: string[];
75
+ private readonly excludedFoldersSetting:
76
+ Common.Settings.Setting<{[path: Platform.DevToolsPath.UrlString]: Platform.DevToolsPath.EncodedPathString[]}>;
77
+ private excludedFoldersInternal: Set<Platform.DevToolsPath.EncodedPathString>;
78
+ private readonly excludedEmbedderFolders: Platform.DevToolsPath.RawPathString[];
78
79
  private readonly initialFilePathsInternal: Set<Platform.DevToolsPath.EncodedPathString>;
79
80
  private readonly initialGitFoldersInternal: Set<Platform.DevToolsPath.EncodedPathString>;
80
- private readonly fileLocks: Map<string, Promise<void>>;
81
+ private readonly fileLocks: Map<Platform.DevToolsPath.EncodedPathString, Promise<void>>;
81
82
 
82
83
  constructor(
83
- manager: IsolatedFileSystemManager, path: string, embedderPath: string, domFileSystem: FileSystem, type: string) {
84
+ manager: IsolatedFileSystemManager, path: Platform.DevToolsPath.UrlString,
85
+ embedderPath: Platform.DevToolsPath.RawPathString, domFileSystem: FileSystem, type: string) {
84
86
  super(path, type);
85
87
  this.manager = manager;
86
88
  this.embedderPathInternal = embedderPath;
@@ -96,7 +98,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
96
98
  }
97
99
 
98
100
  static async create(
99
- manager: IsolatedFileSystemManager, path: string, embedderPath: string, type: string, name: string,
101
+ manager: IsolatedFileSystemManager, path: Platform.DevToolsPath.UrlString,
102
+ embedderPath: Platform.DevToolsPath.RawPathString, type: string, name: string,
100
103
  rootURL: string): Promise<IsolatedFileSystem|null> {
101
104
  const domFileSystem = Host.InspectorFrontendHost.InspectorFrontendHostInstance.isolatedFileSystem(name, rootURL);
102
105
  if (!domFileSystem) {
@@ -115,18 +118,20 @@ export class IsolatedFileSystem extends PlatformFileSystem {
115
118
  return i18nString(UIStrings.fileSystemErrorS, {PH1: error.message});
116
119
  }
117
120
 
118
- private serializedFileOperation<T>(path: string, operation: () => Promise<T>): Promise<T> {
121
+ private serializedFileOperation<T>(path: Platform.DevToolsPath.EncodedPathString, operation: () => Promise<T>):
122
+ Promise<T> {
119
123
  const promise = Promise.resolve(this.fileLocks.get(path)).then(() => operation.call(null));
120
124
  this.fileLocks.set(path, promise as unknown as Promise<void>);
121
125
  return promise;
122
126
  }
123
127
 
124
- getMetadata(path: string): Promise<Metadata|null> {
128
+ getMetadata(path: Platform.DevToolsPath.EncodedPathString): Promise<Metadata|null> {
125
129
  let fulfill: (arg0: Metadata|null) => void;
126
130
  const promise = new Promise<Metadata|null>(f => {
127
131
  fulfill = f;
128
132
  });
129
- this.domFileSystem.root.getFile(decodeURIComponent(path), undefined, fileEntryLoaded, errorHandler);
133
+ this.domFileSystem.root.getFile(
134
+ Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), undefined, fileEntryLoaded, errorHandler);
130
135
  return promise;
131
136
 
132
137
  function fileEntryLoaded(entry: FileEntry): void {
@@ -148,7 +153,7 @@ export class IsolatedFileSystem extends PlatformFileSystem {
148
153
  return [...this.initialGitFoldersInternal];
149
154
  }
150
155
 
151
- embedderPath(): string {
156
+ embedderPath(): Platform.DevToolsPath.RawPathString {
152
157
  return this.embedderPathInternal;
153
158
  }
154
159
 
@@ -156,13 +161,14 @@ export class IsolatedFileSystem extends PlatformFileSystem {
156
161
  return new Promise(fulfill => {
157
162
  let pendingRequests = 1;
158
163
  const boundInnerCallback = innerCallback.bind(this);
159
- this.requestEntries('', boundInnerCallback);
164
+ this.requestEntries(Platform.DevToolsPath.EmptyRawPathString, boundInnerCallback);
160
165
 
161
166
  function innerCallback(this: IsolatedFileSystem, entries: FileEntry[]): void {
162
167
  for (let i = 0; i < entries.length; ++i) {
163
168
  const entry = entries[i];
164
169
  if (!entry.isDirectory) {
165
- if (this.isFileExcluded(entry.fullPath)) {
170
+ if (this.isFileExcluded(Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
171
+ entry.fullPath as Platform.DevToolsPath.RawPathString))) {
166
172
  continue;
167
173
  }
168
174
  this.initialFilePathsInternal.add(Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
@@ -174,14 +180,20 @@ export class IsolatedFileSystem extends PlatformFileSystem {
174
180
  entry.fullPath as Platform.DevToolsPath.RawPathString, 1, lastSlash);
175
181
  this.initialGitFoldersInternal.add(Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(parentFolder));
176
182
  }
177
- if (this.isFileExcluded(entry.fullPath + '/')) {
178
- const url = Common.ParsedURL.ParsedURL.concatenate(this.path(), entry.fullPath);
183
+ if (this.isFileExcluded(Common.ParsedURL.ParsedURL.concatenate(
184
+ Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
185
+ entry.fullPath as Platform.DevToolsPath.RawPathString),
186
+ '/'))) {
187
+ const url = Common.ParsedURL.ParsedURL.concatenate(
188
+ this.path(),
189
+ Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
190
+ entry.fullPath as Platform.DevToolsPath.RawPathString));
179
191
  this.excludedEmbedderFolders.push(
180
192
  Common.ParsedURL.ParsedURL.urlToRawPathString(url, Host.Platform.isWin()));
181
193
  continue;
182
194
  }
183
195
  ++pendingRequests;
184
- this.requestEntries(entry.fullPath, boundInnerCallback);
196
+ this.requestEntries(entry.fullPath as Platform.DevToolsPath.RawPathString, boundInnerCallback);
185
197
  }
186
198
  }
187
199
  if ((--pendingRequests === 0)) {
@@ -191,7 +203,7 @@ export class IsolatedFileSystem extends PlatformFileSystem {
191
203
  });
192
204
  }
193
205
 
194
- private async createFoldersIfNotExist(folderPath: string): Promise<DirectoryEntry|null> {
206
+ private async createFoldersIfNotExist(folderPath: Platform.DevToolsPath.RawPathString): Promise<DirectoryEntry|null> {
195
207
  // Fast-path. If parent directory already exists we return it immidiatly.
196
208
  let dirEntry = await new Promise<DirectoryEntry|null>(
197
209
  resolve => this.domFileSystem.root.getDirectory(folderPath, undefined, resolve, () => resolve(null)));
@@ -220,13 +232,17 @@ export class IsolatedFileSystem extends PlatformFileSystem {
220
232
  });
221
233
  }
222
234
 
223
- async createFile(path: string, name: string|null): Promise<string|null> {
224
- const dirEntry = await this.createFoldersIfNotExist(decodeURIComponent(path));
235
+ async createFile(path: Platform.DevToolsPath.EncodedPathString, name: Platform.DevToolsPath.RawPathString|null):
236
+ Promise<Platform.DevToolsPath.EncodedPathString|null> {
237
+ const dirEntry = await this.createFoldersIfNotExist(Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path));
225
238
  if (!dirEntry) {
226
239
  return null;
227
240
  }
228
241
  const fileEntry =
229
- await this.serializedFileOperation(path, createFileCandidate.bind(this, name || 'NewFile')) as FileEntry | null;
242
+ await this.serializedFileOperation(
243
+ path, createFileCandidate.bind(this, name || 'NewFile' as Platform.DevToolsPath.RawPathString)) as
244
+ FileEntry |
245
+ null;
230
246
  if (!fileEntry) {
231
247
  return null;
232
248
  }
@@ -234,9 +250,10 @@ export class IsolatedFileSystem extends PlatformFileSystem {
234
250
  Common.ParsedURL.ParsedURL.substr(fileEntry.fullPath as Platform.DevToolsPath.RawPathString, 1));
235
251
 
236
252
  function createFileCandidate(
237
- this: IsolatedFileSystem, name: string, newFileIndex?: number): Promise<FileEntry|null> {
253
+ this: IsolatedFileSystem, name: Platform.DevToolsPath.RawPathString,
254
+ newFileIndex?: number): Promise<FileEntry|null> {
238
255
  return new Promise(resolve => {
239
- const nameCandidate = name + (newFileIndex || '');
256
+ const nameCandidate = Common.ParsedURL.ParsedURL.concatenate(name, (newFileIndex || '').toString());
240
257
  (dirEntry as DirectoryEntry).getFile(nameCandidate, {create: true, exclusive: true}, resolve, error => {
241
258
  if (error.name === 'InvalidModificationError') {
242
259
  resolve(createFileCandidate.call(this, name, (newFileIndex ? newFileIndex + 1 : 1)));
@@ -252,13 +269,14 @@ export class IsolatedFileSystem extends PlatformFileSystem {
252
269
  }
253
270
  }
254
271
 
255
- deleteFile(path: string): Promise<boolean> {
272
+ deleteFile(path: Platform.DevToolsPath.EncodedPathString): Promise<boolean> {
256
273
  let resolveCallback: (arg0: boolean) => void;
257
274
  const promise = new Promise<boolean>(resolve => {
258
275
  resolveCallback = resolve;
259
276
  });
260
277
  this.domFileSystem.root.getFile(
261
- decodeURIComponent(path), undefined, fileEntryLoaded.bind(this), errorHandler.bind(this));
278
+ Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), undefined, fileEntryLoaded.bind(this),
279
+ errorHandler.bind(this));
262
280
  return promise;
263
281
 
264
282
  function fileEntryLoaded(this: IsolatedFileSystem, fileEntry: FileEntry): void {
@@ -279,9 +297,9 @@ export class IsolatedFileSystem extends PlatformFileSystem {
279
297
  }
280
298
  }
281
299
 
282
- requestFileBlob(path: string): Promise<Blob|null> {
300
+ requestFileBlob(path: Platform.DevToolsPath.EncodedPathString): Promise<Blob|null> {
283
301
  return new Promise(resolve => {
284
- this.domFileSystem.root.getFile(decodeURIComponent(path), undefined, entry => {
302
+ this.domFileSystem.root.getFile(Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), undefined, entry => {
285
303
  entry.file(resolve, errorHandler.bind(this));
286
304
  }, errorHandler.bind(this));
287
305
 
@@ -298,11 +316,13 @@ export class IsolatedFileSystem extends PlatformFileSystem {
298
316
  });
299
317
  }
300
318
 
301
- requestFileContent(path: string): Promise<TextUtils.ContentProvider.DeferredContent> {
319
+ requestFileContent(path: Platform.DevToolsPath.EncodedPathString):
320
+ Promise<TextUtils.ContentProvider.DeferredContent> {
302
321
  return this.serializedFileOperation(path, () => this.innerRequestFileContent(path));
303
322
  }
304
323
 
305
- private async innerRequestFileContent(path: string): Promise<TextUtils.ContentProvider.DeferredContent> {
324
+ private async innerRequestFileContent(path: Platform.DevToolsPath.EncodedPathString):
325
+ Promise<TextUtils.ContentProvider.DeferredContent> {
306
326
  const blob = await this.requestFileBlob(path);
307
327
  if (!blob) {
308
328
  return {content: null, error: i18nString(UIStrings.blobCouldNotBeLoaded), isEncoded: false};
@@ -341,7 +361,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
341
361
  return {isEncoded: encoded, content: encoded ? btoa(result) : result};
342
362
  }
343
363
 
344
- async setFileContent(path: string, content: string, isBase64: boolean): Promise<void> {
364
+ async setFileContent(path: Platform.DevToolsPath.EncodedPathString, content: string, isBase64: boolean):
365
+ Promise<void> {
345
366
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.FileSavedInWorkspace);
346
367
  let callback: (event?: ProgressEvent<EventTarget>) => void;
347
368
  const innerSetFileContent = (): Promise<ProgressEvent<EventTarget>> => {
@@ -350,7 +371,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
350
371
  callback = x;
351
372
  });
352
373
  this.domFileSystem.root.getFile(
353
- decodeURIComponent(path), {create: true}, fileEntryLoaded.bind(this), errorHandler.bind(this));
374
+ Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), {create: true}, fileEntryLoaded.bind(this),
375
+ errorHandler.bind(this));
354
376
  return promise;
355
377
  };
356
378
 
@@ -385,8 +407,10 @@ export class IsolatedFileSystem extends PlatformFileSystem {
385
407
  }
386
408
  }
387
409
 
388
- renameFile(path: string, newName: string, callback: (arg0: boolean, arg1?: string|undefined) => void): void {
389
- newName = newName ? newName.trim() : newName;
410
+ renameFile(
411
+ path: Platform.DevToolsPath.EncodedPathString, newName: Platform.DevToolsPath.RawPathString,
412
+ callback: (arg0: boolean, arg1?: string|undefined) => void): void {
413
+ newName = newName ? Common.ParsedURL.ParsedURL.trim(newName) : newName;
390
414
  if (!newName || newName.indexOf('/') !== -1) {
391
415
  callback(false);
392
416
  return;
@@ -395,7 +419,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
395
419
  let dirEntry: DirectoryEntry;
396
420
 
397
421
  this.domFileSystem.root.getFile(
398
- decodeURIComponent(path), undefined, fileEntryLoaded.bind(this), errorHandler.bind(this));
422
+ Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), undefined, fileEntryLoaded.bind(this),
423
+ errorHandler.bind(this));
399
424
 
400
425
  function fileEntryLoaded(this: IsolatedFileSystem, entry: FileEntry): void {
401
426
  if (entry.name === newName) {
@@ -461,8 +486,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
461
486
  }
462
487
  }
463
488
 
464
- private requestEntries(path: string, callback: (arg0: Array<FileEntry>) => void): void {
465
- this.domFileSystem.root.getDirectory(decodeURIComponent(path), undefined, innerCallback.bind(this), errorHandler);
489
+ private requestEntries(path: Platform.DevToolsPath.RawPathString, callback: (arg0: Array<FileEntry>) => void): void {
490
+ this.domFileSystem.root.getDirectory(path, undefined, innerCallback.bind(this), errorHandler);
466
491
 
467
492
  function innerCallback(this: IsolatedFileSystem, dirEntry: DirectoryEntry): void {
468
493
  this.readDirectory(dirEntry, callback);
@@ -481,13 +506,13 @@ export class IsolatedFileSystem extends PlatformFileSystem {
481
506
  this.excludedFoldersSetting.set(settingValue);
482
507
  }
483
508
 
484
- addExcludedFolder(path: string): void {
509
+ addExcludedFolder(path: Platform.DevToolsPath.EncodedPathString): void {
485
510
  this.excludedFoldersInternal.add(path);
486
511
  this.saveExcludedFolders();
487
512
  this.manager.dispatchEventToListeners(Events.ExcludedFolderAdded, path);
488
513
  }
489
514
 
490
- removeExcludedFolder(path: string): void {
515
+ removeExcludedFolder(path: Platform.DevToolsPath.EncodedPathString): void {
491
516
  this.excludedFoldersInternal.delete(path);
492
517
  this.saveExcludedFolders();
493
518
  this.manager.dispatchEventToListeners(Events.ExcludedFolderRemoved, path);
@@ -499,12 +524,12 @@ export class IsolatedFileSystem extends PlatformFileSystem {
499
524
  this.excludedFoldersSetting.set(settingValue);
500
525
  }
501
526
 
502
- isFileExcluded(folderPath: string): boolean {
527
+ isFileExcluded(folderPath: Platform.DevToolsPath.EncodedPathString): boolean {
503
528
  if (this.excludedFoldersInternal.has(folderPath)) {
504
529
  return true;
505
530
  }
506
531
  const regex = (this.manager.workspaceFolderExcludePatternSetting() as Common.Settings.RegExpSetting).asRegExp();
507
- return Boolean(regex && regex.test(folderPath));
532
+ return Boolean(regex && regex.test(Common.ParsedURL.ParsedURL.encodedPathToRawPathString(folderPath)));
508
533
  }
509
534
 
510
535
  excludedFolders(): Set<string> {
@@ -535,10 +560,11 @@ export class IsolatedFileSystem extends PlatformFileSystem {
535
560
  return Common.ResourceType.ResourceType.mimeFromURL(path) || 'text/plain';
536
561
  }
537
562
 
538
- canExcludeFolder(path: string): boolean {
563
+ canExcludeFolder(path: Platform.DevToolsPath.EncodedPathString): boolean {
539
564
  return Boolean(path) && this.type() !== 'overrides';
540
565
  }
541
566
 
567
+ // path not typed as Branded Types as here we are interested in extention only
542
568
  contentType(path: string): Common.ResourceType.ResourceType {
543
569
  const extension = Common.ParsedURL.ParsedURL.extractExtension(path);
544
570
  if (STYLE_SHEET_EXTENSIONS.has(extension)) {
@@ -248,7 +248,8 @@ export class IsolatedFileSystemManager extends Common.ObjectWrapper.ObjectWrappe
248
248
  const filePath = Common.ParsedURL.ParsedURL.rawPathToUrlString(embedderPath);
249
249
  for (const fileSystemPath of this.fileSystemsInternal.keys()) {
250
250
  const fileSystem = this.fileSystemsInternal.get(fileSystemPath);
251
- if (fileSystem && fileSystem.isFileExcluded(embedderPath)) {
251
+ if (fileSystem &&
252
+ fileSystem.isFileExcluded(Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(embedderPath))) {
252
253
  continue;
253
254
  }
254
255
  const pathPrefix = fileSystemPath.endsWith('/') ? fileSystemPath : fileSystemPath + '/';
@@ -348,8 +349,8 @@ export type EventTypes = {
348
349
  [Events.FileSystemAdded]: PlatformFileSystem,
349
350
  [Events.FileSystemRemoved]: PlatformFileSystem,
350
351
  [Events.FileSystemFilesChanged]: FilesChangedData,
351
- [Events.ExcludedFolderAdded]: string,
352
- [Events.ExcludedFolderRemoved]: string,
352
+ [Events.ExcludedFolderAdded]: Platform.DevToolsPath.EncodedPathString,
353
+ [Events.ExcludedFolderRemoved]: Platform.DevToolsPath.EncodedPathString,
353
354
  };
354
355
 
355
356
  let lastRequestId = 0;
@@ -185,9 +185,9 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
185
185
  PersistenceImpl.instance().refreshAutomapping();
186
186
  }
187
187
 
188
- private encodedPathFromUrl(url: string): string {
188
+ private encodedPathFromUrl(url: Platform.DevToolsPath.UrlString): Platform.DevToolsPath.EncodedPathString {
189
189
  if (!this.activeInternal || !this.projectInternal) {
190
- return '';
190
+ return Platform.DevToolsPath.EmptyEncodedPathString;
191
191
  }
192
192
  let urlPath = Common.ParsedURL.ParsedURL.urlWithoutHash(url.replace(/^https?:\/\//, ''));
193
193
  if (urlPath.endsWith('/') && urlPath.indexOf('?') === -1) {
@@ -208,7 +208,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
208
208
  shortFileName + Platform.StringUtilities.hashCode(encodedPath).toString(16) + extensionPart,
209
209
  ];
210
210
  }
211
- return encodedPathParts.join('/');
211
+ return Common.ParsedURL.ParsedURL.join(encodedPathParts as Platform.DevToolsPath.EncodedPathString[], '/');
212
212
 
213
213
  function encodeUrlPathToLocalPathParts(urlPath: string): string[] {
214
214
  const encodedParts = [];
@@ -310,7 +310,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
310
310
  const encoded = await uiSourceCode.contentEncoded();
311
311
  const lastIndexOfSlash = encodedPath.lastIndexOf('/');
312
312
  const encodedFileName = encodedPath.substr(lastIndexOfSlash + 1);
313
- encodedPath = encodedPath.substr(0, lastIndexOfSlash);
313
+ encodedPath = Common.ParsedURL.ParsedURL.substr(encodedPath, 0, lastIndexOfSlash);
314
314
  if (this.projectInternal) {
315
315
  await this.projectInternal.createFile(encodedPath, encodedFileName, content, encoded);
316
316
  }
@@ -555,7 +555,8 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
555
555
 
556
556
  handleHeaderInterception(interceptedRequest: SDK.NetworkManager.InterceptedRequest): Protocol.Fetch.HeaderEntry[] {
557
557
  let result: Protocol.Fetch.HeaderEntry[] = interceptedRequest.responseHeaders || [];
558
- const urlSegments = this.encodedPathFromUrl(interceptedRequest.request.url).split('/');
558
+ const urlSegments =
559
+ this.encodedPathFromUrl(interceptedRequest.request.url as Platform.DevToolsPath.UrlString).split('/');
559
560
  // Traverse the hierarchy of overrides from the most general to the most
560
561
  // specific. Check with empty string first to match overrides applying to
561
562
  // all domains.
@@ -23,7 +23,7 @@ export class PlatformFileSystem {
23
23
  this.typeInternal = type;
24
24
  }
25
25
 
26
- getMetadata(_path: string): Promise<{modificationTime: Date, size: number}|null> {
26
+ getMetadata(_path: Platform.DevToolsPath.EncodedPathString): Promise<{modificationTime: Date, size: number}|null> {
27
27
  return Promise.resolve(null);
28
28
  }
29
29
 
@@ -36,6 +36,7 @@ export class PlatformFileSystem {
36
36
  }
37
37
 
38
38
  path(): Platform.DevToolsPath.UrlString {
39
+ // TODO(crbug.com/1297535): Cast to UrlString will be removed when migration to branded types is complete.
39
40
  return this.pathInternal as Platform.DevToolsPath.UrlString;
40
41
  }
41
42
 
@@ -48,31 +49,35 @@ export class PlatformFileSystem {
48
49
  return this.typeInternal;
49
50
  }
50
51
 
51
- async createFile(_path: string, _name: string|null): Promise<string|null> {
52
+ async createFile(_path: Platform.DevToolsPath.EncodedPathString, _name: Platform.DevToolsPath.RawPathString|null):
53
+ Promise<Platform.DevToolsPath.EncodedPathString|null> {
52
54
  return Promise.resolve(null);
53
55
  }
54
56
 
55
- deleteFile(_path: string): Promise<boolean> {
57
+ deleteFile(_path: Platform.DevToolsPath.EncodedPathString): Promise<boolean> {
56
58
  return Promise.resolve(false);
57
59
  }
58
60
 
59
- requestFileBlob(_path: string): Promise<Blob|null> {
61
+ requestFileBlob(_path: Platform.DevToolsPath.EncodedPathString): Promise<Blob|null> {
60
62
  return Promise.resolve(null as Blob | null);
61
63
  }
62
64
 
63
- async requestFileContent(_path: string): Promise<TextUtils.ContentProvider.DeferredContent> {
65
+ async requestFileContent(_path: Platform.DevToolsPath.EncodedPathString):
66
+ Promise<TextUtils.ContentProvider.DeferredContent> {
64
67
  return {content: null, error: i18nString(UIStrings.unableToReadFilesWithThis), isEncoded: false};
65
68
  }
66
69
 
67
- setFileContent(_path: string, _content: string, _isBase64: boolean): void {
70
+ setFileContent(_path: Platform.DevToolsPath.EncodedPathString, _content: string, _isBase64: boolean): void {
68
71
  throw new Error('Not implemented');
69
72
  }
70
73
 
71
- renameFile(_path: string, _newName: string, callback: (arg0: boolean, arg1?: string|undefined) => void): void {
74
+ renameFile(
75
+ _path: Platform.DevToolsPath.EncodedPathString, _newName: Platform.DevToolsPath.RawPathString,
76
+ callback: (arg0: boolean, arg1?: string|undefined) => void): void {
72
77
  callback(false);
73
78
  }
74
79
 
75
- addExcludedFolder(_path: string): void {
80
+ addExcludedFolder(_path: Platform.DevToolsPath.EncodedPathString): void {
76
81
  }
77
82
 
78
83
  removeExcludedFolder(_path: string): void {
@@ -81,7 +86,7 @@ export class PlatformFileSystem {
81
86
  fileSystemRemoved(): void {
82
87
  }
83
88
 
84
- isFileExcluded(_folderPath: string): boolean {
89
+ isFileExcluded(_folderPath: Platform.DevToolsPath.EncodedPathString): boolean {
85
90
  return false;
86
91
  }
87
92
 
@@ -103,7 +108,7 @@ export class PlatformFileSystem {
103
108
  throw new Error('Not implemented');
104
109
  }
105
110
 
106
- canExcludeFolder(_path: string): boolean {
111
+ canExcludeFolder(_path: Platform.DevToolsPath.EncodedPathString): boolean {
107
112
  return false;
108
113
  }
109
114
 
@@ -51,6 +51,8 @@ const UIStrings = {
51
51
  const str_ = i18n.i18n.registerUIStrings('models/workspace/UISourceCode.ts', UIStrings);
52
52
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
53
53
 
54
+ // TODO(crbug.com/1297535): Casts to UrlString and RawPathString will be removed from this file when migration to branded types is complete.
55
+
54
56
  export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes> implements
55
57
  TextUtils.ContentProvider.ContentProvider {
56
58
  private projectInternal: Project;
@@ -92,7 +94,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
92
94
  }
93
95
  } else {
94
96
  this.originInternal = '';
95
- this.parentURLInternal = '' as Platform.DevToolsPath.UrlString;
97
+ this.parentURLInternal = Platform.DevToolsPath.EmptyUrlString;
96
98
  this.nameInternal = url;
97
99
  }
98
100
 
@@ -150,7 +152,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
150
152
  return this.projectInternal.canRename();
151
153
  }
152
154
 
153
- rename(newName: string): Promise<boolean> {
155
+ rename(newName: Platform.DevToolsPath.RawPathString): Promise<boolean> {
154
156
  let fulfill: (arg0: boolean) => void;
155
157
  const promise = new Promise<boolean>(x => {
156
158
  fulfill = x;
@@ -29,6 +29,7 @@
29
29
  */
30
30
 
31
31
  import * as Common from '../../core/common/common.js';
32
+ import type * as Platform from '../../core/platform/platform.js';
32
33
  import type * as TextUtils from '../text_utils/text_utils.js';
33
34
 
34
35
  import type {UISourceCodeMetadata} from './UISourceCode.js';
@@ -56,11 +57,12 @@ export interface Project {
56
57
  mimeType(uiSourceCode: UISourceCode): string;
57
58
  canRename(): boolean;
58
59
  rename(
59
- uiSourceCode: UISourceCode, newName: string,
60
+ uiSourceCode: UISourceCode, newName: Platform.DevToolsPath.RawPathString,
60
61
  callback: (arg0: boolean, arg1?: string, arg2?: string, arg3?: Common.ResourceType.ResourceType) => void): void;
61
62
  excludeFolder(path: string): void;
62
- canExcludeFolder(path: string): boolean;
63
- createFile(path: string, name: string|null, content: string, isBase64?: boolean): Promise<UISourceCode|null>;
63
+ canExcludeFolder(path: Platform.DevToolsPath.EncodedPathString): boolean;
64
+ createFile(path: Platform.DevToolsPath.EncodedPathString, name: string|null, content: string, isBase64?: boolean):
65
+ Promise<UISourceCode|null>;
64
66
  canCreateFile(): boolean;
65
67
  deleteFile(uiSourceCode: UISourceCode): void;
66
68
  remove(): void;
@@ -209,8 +211,10 @@ export abstract class ProjectStore implements Project {
209
211
  abstract fullDisplayName(uiSourceCode: UISourceCode): string;
210
212
  abstract mimeType(uiSourceCode: UISourceCode): string;
211
213
  abstract canRename(): boolean;
212
- abstract canExcludeFolder(path: string): boolean;
213
- abstract createFile(path: string, name: string|null, content: string, isBase64?: boolean): Promise<UISourceCode|null>;
214
+ abstract canExcludeFolder(path: Platform.DevToolsPath.EncodedPathString): boolean;
215
+ abstract createFile(
216
+ path: Platform.DevToolsPath.EncodedPathString, name: string|null, content: string,
217
+ isBase64?: boolean): Promise<UISourceCode|null>;
214
218
  abstract canCreateFile(): boolean;
215
219
  abstract searchInFileContent(uiSourceCode: UISourceCode, query: string, caseSensitive: boolean, isRegex: boolean):
216
220
  Promise<TextUtils.ContentProvider.SearchMatch[]>;
@@ -382,7 +382,7 @@ export class ServiceWorkerCacheView extends UI.View.SimpleView {
382
382
  private createRequest(entry: Protocol.CacheStorage.DataEntry): SDK.NetworkRequest.NetworkRequest {
383
383
  const request = SDK.NetworkRequest.NetworkRequest.createWithoutBackendRequest(
384
384
  'cache-storage-' + entry.requestURL, entry.requestURL as Platform.DevToolsPath.UrlString,
385
- '' as Platform.DevToolsPath.UrlString, null);
385
+ Platform.DevToolsPath.EmptyUrlString, null);
386
386
  request.requestMethod = entry.requestMethod;
387
387
  request.setRequestHeaders(entry.requestHeaders);
388
388
  request.statusCode = entry.responseStatus;
@@ -462,8 +462,7 @@ export class ResourceWebSocketFrameNode extends DataGrid.SortableDataGrid.Sortab
462
462
  if (!this.binaryViewInternal) {
463
463
  if (this.dataTextInternal.length > 0) {
464
464
  this.binaryViewInternal = new BinaryResourceView(
465
- this.dataTextInternal, /* url */ '' as Platform.DevToolsPath.UrlString,
466
- Common.ResourceType.resourceTypes.WebSocket);
465
+ this.dataTextInternal, Platform.DevToolsPath.EmptyUrlString, Common.ResourceType.resourceTypes.WebSocket);
467
466
  }
468
467
  }
469
468
  return this.binaryViewInternal;
@@ -13,8 +13,6 @@ 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
-
18
16
  const UIStrings = {
19
17
  /**
20
18
  *@description Default snippet name when a new snippet is created in the Sources panel
@@ -30,12 +28,12 @@ const UIStrings = {
30
28
  const str_ = i18n.i18n.registerUIStrings('panels/snippets/ScriptSnippetFileSystem.ts', UIStrings);
31
29
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
32
30
 
33
- function escapeSnippetName(name: string): Platform.DevToolsPath.EncodedPathString {
34
- return Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(name as Platform.DevToolsPath.RawPathString);
31
+ function escapeSnippetName(name: Platform.DevToolsPath.RawPathString): Platform.DevToolsPath.EncodedPathString {
32
+ return Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(name);
35
33
  }
36
34
 
37
- function unescapeSnippetName(name: string): string {
38
- return Common.ParsedURL.ParsedURL.encodedPathToRawPathString(name as Platform.DevToolsPath.EncodedPathString);
35
+ function unescapeSnippetName(name: Platform.DevToolsPath.EncodedPathString): string {
36
+ return Common.ParsedURL.ParsedURL.encodedPathToRawPathString(name);
39
37
  }
40
38
 
41
39
  export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFileSystem {
@@ -53,11 +51,13 @@ export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFi
53
51
  return savedSnippets.map(snippet => escapeSnippetName(snippet.name));
54
52
  }
55
53
 
56
- async createFile(_path: string, _name: string|null): Promise<string|null> {
54
+ async createFile(_path: Platform.DevToolsPath.EncodedPathString, _name: Platform.DevToolsPath.RawPathString|null):
55
+ Promise<Platform.DevToolsPath.EncodedPathString|null> {
57
56
  const nextId = this.lastSnippetIdentifierSetting.get() + 1;
58
57
  this.lastSnippetIdentifierSetting.set(nextId);
59
58
 
60
- const snippetName = i18nString(UIStrings.scriptSnippet, {PH1: nextId});
59
+ const snippetName =
60
+ i18nString(UIStrings.scriptSnippet, {PH1: nextId}) as string as Platform.DevToolsPath.RawPathString;
61
61
  const snippets = this.snippetsSetting.get();
62
62
  snippets.push({name: snippetName, content: ''});
63
63
  this.snippetsSetting.set(snippets);
@@ -65,8 +65,8 @@ export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFi
65
65
  return escapeSnippetName(snippetName);
66
66
  }
67
67
 
68
- async deleteFile(path: string): Promise<boolean> {
69
- const name = unescapeSnippetName(path.substring(1));
68
+ async deleteFile(path: Platform.DevToolsPath.EncodedPathString): Promise<boolean> {
69
+ const name = unescapeSnippetName(Common.ParsedURL.ParsedURL.substring(path, 1));
70
70
  const allSnippets: Snippet[] = this.snippetsSetting.get();
71
71
  const snippets = allSnippets.filter(snippet => snippet.name !== name);
72
72
  if (allSnippets.length !== snippets.length) {
@@ -76,8 +76,9 @@ export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFi
76
76
  return false;
77
77
  }
78
78
 
79
- async requestFileContent(path: string): Promise<TextUtils.ContentProvider.DeferredContent> {
80
- const name = unescapeSnippetName(path.substring(1));
79
+ async requestFileContent(path: Platform.DevToolsPath.EncodedPathString):
80
+ Promise<TextUtils.ContentProvider.DeferredContent> {
81
+ const name = unescapeSnippetName(Common.ParsedURL.ParsedURL.substring(path, 1));
81
82
  const snippets: Snippet[] = this.snippetsSetting.get();
82
83
  const snippet = snippets.find(snippet => snippet.name === name);
83
84
  if (snippet) {
@@ -86,8 +87,9 @@ export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFi
86
87
  return {content: null, isEncoded: false, error: `A snippet with name '${name}' was not found`};
87
88
  }
88
89
 
89
- async setFileContent(path: string, content: string, _isBase64: boolean): Promise<boolean> {
90
- const name = unescapeSnippetName(path.substring(1));
90
+ async setFileContent(path: Platform.DevToolsPath.EncodedPathString, content: string, _isBase64: boolean):
91
+ Promise<boolean> {
92
+ const name = unescapeSnippetName(Common.ParsedURL.ParsedURL.substring(path, 1));
91
93
  const snippets: Snippet[] = this.snippetsSetting.get();
92
94
  const snippet = snippets.find(snippet => snippet.name === name);
93
95
  if (snippet) {
@@ -98,11 +100,13 @@ export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFi
98
100
  return false;
99
101
  }
100
102
 
101
- renameFile(path: string, newName: string, callback: (arg0: boolean, arg1?: string|undefined) => void): void {
102
- const name = unescapeSnippetName(path.substring(1));
103
+ renameFile(
104
+ path: Platform.DevToolsPath.EncodedPathString, newName: Platform.DevToolsPath.RawPathString,
105
+ callback: (arg0: boolean, arg1?: string|undefined) => void): void {
106
+ const name = unescapeSnippetName(Common.ParsedURL.ParsedURL.substring(path, 1));
103
107
  const snippets: Snippet[] = this.snippetsSetting.get();
104
108
  const snippet = snippets.find(snippet => snippet.name === name);
105
- newName = newName.trim();
109
+ newName = Common.ParsedURL.ParsedURL.trim(newName);
106
110
  if (!snippet || newName.length === 0 || snippets.find(snippet => snippet.name === newName)) {
107
111
  callback(false);
108
112
  return;
@@ -128,7 +132,9 @@ export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFi
128
132
  }
129
133
 
130
134
  tooltipForURL(url: Platform.DevToolsPath.UrlString): string {
131
- return i18nString(UIStrings.linkedTo, {PH1: unescapeSnippetName(url.substring(this.path().length))});
135
+ return i18nString(
136
+ UIStrings.linkedTo,
137
+ {PH1: unescapeSnippetName(Common.ParsedURL.ParsedURL.sliceUrlToEncodedPathString(url, this.path().length))});
132
138
  }
133
139
 
134
140
  supportsAutomapping(): boolean {
@@ -215,6 +221,6 @@ export function findSnippetsProject(): Workspace.Workspace.Project {
215
221
  return workspaceProject;
216
222
  }
217
223
  export interface Snippet {
218
- name: string;
224
+ name: Platform.DevToolsPath.RawPathString;
219
225
  content: string;
220
226
  }
@@ -28,6 +28,8 @@
28
28
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
  */
30
30
 
31
+ // TODO(crbug.com/1253323): Casts to Branded Types will be removed from this file when migration to branded types is complete.
32
+
31
33
  import * as Common from '../../core/common/common.js';
32
34
  import * as Host from '../../core/host/host.js';
33
35
  import * as i18n from '../../core/i18n/i18n.js';
@@ -843,7 +845,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
843
845
  }
844
846
 
845
847
  handleFolderContextMenu(event: Event, node: NavigatorTreeNode): void {
846
- const path = (node as NavigatorFolderTreeNode).folderPath || '';
848
+ const path = (node as NavigatorFolderTreeNode).folderPath || Platform.DevToolsPath.EmptyEncodedPathString;
847
849
  const project = (node as NavigatorFolderTreeNode).project || null;
848
850
 
849
851
  const contextMenu = new UI.ContextMenu.ContextMenu(event);
@@ -914,7 +916,7 @@ export class NavigatorView extends UI.Widget.VBox implements SDK.TargetManager.O
914
916
  if (uiSourceCodeToCopy) {
915
917
  content = (await uiSourceCodeToCopy.requestContent()).content || '';
916
918
  }
917
- const uiSourceCode = await project.createFile(path, null, content);
919
+ const uiSourceCode = await project.createFile(path as Platform.DevToolsPath.EncodedPathString, null, content);
918
920
  if (!uiSourceCode) {
919
921
  return;
920
922
  }
@@ -1413,7 +1415,9 @@ export class NavigatorUISourceCodeTreeNode extends NavigatorTreeNode {
1413
1415
  if (this.treeElement) {
1414
1416
  this.treeElement.title = newTitle;
1415
1417
  }
1416
- void this.uiSourceCodeInternal.rename(newTitle).then(renameCallback.bind(this));
1418
+ // necessary cast to RawPathString as alternative would be altering type of Config<T>
1419
+ void this.uiSourceCodeInternal.rename(newTitle as Platform.DevToolsPath.RawPathString)
1420
+ .then(renameCallback.bind(this));
1417
1421
  return;
1418
1422
  }
1419
1423
  afterEditing.call(this, true);
@@ -1453,7 +1457,7 @@ export class NavigatorUISourceCodeTreeNode extends NavigatorTreeNode {
1453
1457
 
1454
1458
  export class NavigatorFolderTreeNode extends NavigatorTreeNode {
1455
1459
  project: Workspace.Workspace.Project|null;
1456
- readonly folderPath: string;
1460
+ readonly folderPath: Platform.DevToolsPath.EncodedPathString;
1457
1461
  title: string;
1458
1462
  treeElement!: NavigatorFolderTreeElement|null;
1459
1463
  constructor(
@@ -1461,7 +1465,7 @@ export class NavigatorFolderTreeNode extends NavigatorTreeNode {
1461
1465
  folderPath: string, title: string) {
1462
1466
  super(navigatorView, id, type);
1463
1467
  this.project = project;
1464
- this.folderPath = folderPath;
1468
+ this.folderPath = folderPath as Platform.DevToolsPath.EncodedPathString;
1465
1469
  this.title = title;
1466
1470
  }
1467
1471
 
@@ -31,9 +31,9 @@
31
31
  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
+ import * as Platform from '../../core/platform/platform.js';
34
35
  import * as SDK from '../../core/sdk/sdk.js';
35
36
  import * as Persistence from '../../models/persistence/persistence.js';
36
- import type * as Platform from '../../core/platform/platform.js';
37
37
  import * as Workspace from '../../models/workspace/workspace.js';
38
38
  import * as UI from '../../ui/legacy/legacy.js';
39
39
  import * as Snippets from '../snippets/snippets.js';
@@ -406,7 +406,7 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
406
406
  switch (actionId) {
407
407
  case 'sources.create-snippet':
408
408
  void Snippets.ScriptSnippetFileSystem.findSnippetsProject()
409
- .createFile('', null, '')
409
+ .createFile(Platform.DevToolsPath.EmptyEncodedPathString, null, '')
410
410
  .then(uiSourceCode => Common.Revealer.reveal(uiSourceCode));
411
411
  return true;
412
412
  case 'sources.add-folder-to-workspace':
@@ -18,6 +18,7 @@ export const enum Variant {
18
18
  PRIMARY = 'primary',
19
19
  SECONDARY = 'secondary',
20
20
  TOOLBAR = 'toolbar',
21
+ ROUND = 'round',
21
22
  }
22
23
 
23
24
  export const enum Size {
@@ -40,7 +41,7 @@ interface ButtonState {
40
41
  }
41
42
 
42
43
  export type ButtonData = {
43
- variant: Variant.TOOLBAR,
44
+ variant: Variant.TOOLBAR|Variant.ROUND,
44
45
  iconUrl: string,
45
46
  size?: Size,
46
47
  disabled?: boolean,
@@ -199,10 +200,19 @@ export class Button extends HTMLElement {
199
200
  throw new Error('Tooblar button does not accept children');
200
201
  }
201
202
  }
203
+ if (this.#props.variant === Variant.ROUND) {
204
+ if (!this.#props.iconUrl) {
205
+ throw new Error('Round button requires an icon');
206
+ }
207
+ if (!this.#isEmpty) {
208
+ throw new Error('Round button does not accept children');
209
+ }
210
+ }
202
211
  const classes = {
203
212
  primary: this.#props.variant === Variant.PRIMARY,
204
213
  secondary: this.#props.variant === Variant.SECONDARY,
205
214
  toolbar: this.#props.variant === Variant.TOOLBAR,
215
+ round: this.#props.variant === Variant.ROUND,
206
216
  'text-with-icon': Boolean(this.#props.iconUrl) && !this.#isEmpty,
207
217
  'only-icon': Boolean(this.#props.iconUrl) && this.#isEmpty,
208
218
  small: Boolean(this.#props.size === Size.SMALL),
@@ -49,7 +49,8 @@ button:focus-visible {
49
49
  box-shadow: 0 0 0 2px var(--color-button-outline-focus);
50
50
  }
51
51
 
52
- button.toolbar {
52
+ button.toolbar,
53
+ button.round {
53
54
  background: transparent;
54
55
  border-radius: 2px;
55
56
  border: none;
@@ -60,11 +61,22 @@ button.toolbar {
60
61
  white-space: nowrap;
61
62
  }
62
63
 
64
+ button.round {
65
+ border-radius: 100%;
66
+ height: 30px;
67
+ width: 30px;
68
+ }
69
+
63
70
  button.toolbar.small {
64
71
  height: 18px;
65
72
  width: 18px;
66
73
  }
67
74
 
75
+ button.round.small {
76
+ height: 24px;
77
+ width: 24px;
78
+ }
79
+
68
80
  button.primary {
69
81
  border: 1px solid var(--color-primary);
70
82
  background: var(--color-primary);
@@ -123,21 +135,27 @@ button.secondary:active:focus-visible {
123
135
  border: 1px solid var(--color-button-secondary-background-pressed);
124
136
  }
125
137
 
126
- button.toolbar:hover {
127
- background-color: var(--color-button-secondary-background-hovering);
138
+ button.toolbar:hover,
139
+ button.round:hover {
140
+ background-color: var(--color-iconbutton-hover);
128
141
  }
129
142
 
130
143
  button.toolbar.active,
131
- button.toolbar:active {
132
- background-color: var(--color-button-secondary-background-pressed);
144
+ button.toolbar:active,
145
+ button.round.active,
146
+ button.round:active {
147
+ background-color: var(--color-iconbutton-pressed);
133
148
  }
134
149
 
135
- button.toolbar:focus-visible {
150
+ button.toolbar:focus-visible,
151
+ button.round:focus-visible {
136
152
  background-color: var(--color-background-elevation-2);
137
153
  }
138
154
 
139
155
  button.toolbar:disabled,
140
- button.toolbar:disabled:hover {
156
+ button.toolbar:disabled:hover,
157
+ button.round:disabled,
158
+ button.round:disabled:hover {
141
159
  background: var(--color-background);
142
160
  color: var(--color-text-disabled);
143
161
  cursor: not-allowed;
@@ -160,7 +178,8 @@ button devtools-icon {
160
178
  height: 19px;
161
179
  }
162
180
 
163
- button.toolbar devtools-icon {
181
+ button.toolbar devtools-icon,
182
+ button.round devtools-icon {
164
183
  width: 24px;
165
184
  height: 24px;
166
185
 
@@ -180,7 +199,8 @@ button.small devtools-icon {
180
199
  height: 14px;
181
200
  }
182
201
 
183
- button.toolbar.small devtools-icon {
202
+ button.toolbar.small devtools-icon,
203
+ button.round.small devtools-icon {
184
204
  width: 18px;
185
205
  height: 18px;
186
206
  }
@@ -194,7 +214,8 @@ button.toolbar:hover devtools-icon {
194
214
  --icon-color: var(--color-text-primary);
195
215
  }
196
216
 
197
- button.toolbar:disabled devtools-icon {
217
+ button.toolbar:disabled devtools-icon,
218
+ button.round:disabled devtools-icon {
198
219
  --icon-color: var(--color-text-disabled);
199
220
  }
200
221
 
@@ -190,7 +190,7 @@ disabledPrimaryIconButton.data = {
190
190
  disabledPrimaryIconButton.onclick = () => alert('clicked');
191
191
  appendButton(disabledPrimaryIconButton);
192
192
 
193
- // Disabled Secondary Icon Only
193
+ // Small Disabled Secondary Icon Only
194
194
  const disabledSecondaryIconOnlyButton = new Buttons.Button.Button();
195
195
  disabledSecondaryIconOnlyButton.onclick = () => alert('clicked');
196
196
  disabledSecondaryIconOnlyButton.style.width = '18px';
@@ -202,6 +202,50 @@ disabledSecondaryIconOnlyButton.data = {
202
202
  };
203
203
  appendButton(disabledSecondaryIconOnlyButton);
204
204
 
205
+ // Round Button
206
+ const roundButton = new Buttons.Button.Button();
207
+ roundButton.data = {
208
+ variant: Buttons.Button.Variant.ROUND,
209
+ iconUrl: testIcon,
210
+ };
211
+ roundButton.title = 'Round Button';
212
+ roundButton.onclick = () => alert('clicked');
213
+ appendButton(roundButton);
214
+
215
+ // Disabled Round Button
216
+ const roundButtonDisabled = new Buttons.Button.Button();
217
+ roundButtonDisabled.data = {
218
+ variant: Buttons.Button.Variant.ROUND,
219
+ iconUrl: testIcon,
220
+ disabled: true,
221
+ };
222
+ roundButtonDisabled.title = 'Disabled Round Button';
223
+ roundButtonDisabled.onclick = () => alert('clicked');
224
+ appendButton(roundButtonDisabled);
225
+
226
+ // Small Round Button
227
+ const smallRoundButton = new Buttons.Button.Button();
228
+ smallRoundButton.data = {
229
+ variant: Buttons.Button.Variant.ROUND,
230
+ iconUrl: testIcon,
231
+ size: Buttons.Button.Size.SMALL,
232
+ };
233
+ smallRoundButton.title = 'Small Round Button';
234
+ smallRoundButton.onclick = () => alert('clicked');
235
+ appendButton(smallRoundButton);
236
+
237
+ // Small Disabled Round Button
238
+ const smallRoundButtonDisabled = new Buttons.Button.Button();
239
+ smallRoundButtonDisabled.data = {
240
+ variant: Buttons.Button.Variant.ROUND,
241
+ iconUrl: testIcon,
242
+ disabled: true,
243
+ size: Buttons.Button.Size.SMALL,
244
+ };
245
+ smallRoundButtonDisabled.title = 'Small Disabled Round Button';
246
+ smallRoundButtonDisabled.onclick = () => alert('clicked');
247
+ appendButton(smallRoundButtonDisabled);
248
+
205
249
  for (let i = 0; i < 6; i++) {
206
250
  // Regular Toolbar Button
207
251
  const toolbarButton = new Buttons.Button.Button();
@@ -245,6 +289,7 @@ for (let i = 0; i < 6; i++) {
245
289
  }
246
290
  }
247
291
 
292
+ // Submit Button
248
293
  const submitButton = new Buttons.Button.Button();
249
294
  submitButton.data = {
250
295
  variant: Buttons.Button.Variant.PRIMARY,
@@ -253,6 +298,7 @@ submitButton.data = {
253
298
  submitButton.innerText = 'Submit';
254
299
  document.querySelector('#form')?.append(submitButton);
255
300
 
301
+ // Reset Button
256
302
  const resetButton = new Buttons.Button.Button();
257
303
  resetButton.data = {
258
304
  variant: Buttons.Button.Variant.SECONDARY,
@@ -127,6 +127,8 @@
127
127
  --color-button-secondary-background-hovering: rgb(26 115 232 / 10%);
128
128
  --color-button-secondary-background-pressed: rgb(26 92 178 / 25%);
129
129
  --color-button-secondary-border: rgb(218 220 224);
130
+ --color-iconbutton-hover: rgb(0 0 0 / 10%);
131
+ --color-iconbutton-pressed: rgb(0 0 0 / 15%);
130
132
 
131
133
  /* Colors for file icons */
132
134
  --color-ic-file-document: rgb(39 116 240);
@@ -273,6 +275,8 @@
273
275
  --color-button-secondary-background-hovering: rgb(138 180 248 / 15%);
274
276
  --color-button-secondary-background-pressed: rgb(138 180 248 / 23%);
275
277
  --color-button-secondary-border: rgb(60 61 65);
278
+ --color-iconbutton-hover: rgb(255 255 255 / 12%);
279
+ --color-iconbutton-pressed: rgb(255 255 255 / 20%);
276
280
 
277
281
  /* Colors for file icons */
278
282
  --color-ic-file-document: rgb(39 116 240);
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.980472"
57
+ "version": "1.0.981004"
58
58
  }