chrome-devtools-frontend 1.0.970391 → 1.0.970539

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.
@@ -162,6 +162,22 @@ export class ParsedURL {
162
162
  return new URL('/' + partiallyEncoded, 'file:///').pathname.substr(1) as Platform.DevToolsPath.EncodedPathString;
163
163
  }
164
164
 
165
+ /**
166
+ * @param name Must not be encoded
167
+ */
168
+ static encodedFromParentPathAndName(parentPath: Platform.DevToolsPath.EncodedPathString, name: string):
169
+ Platform.DevToolsPath.EncodedPathString {
170
+ return parentPath + '/' + encodeURIComponent(name) as Platform.DevToolsPath.EncodedPathString;
171
+ }
172
+
173
+ /**
174
+ * @param name Must not be encoded
175
+ */
176
+ static urlFromParentUrlAndName(parentUrl: Platform.DevToolsPath.UrlString, name: string):
177
+ Platform.DevToolsPath.UrlString {
178
+ return parentUrl + '/' + encodeURIComponent(name) as Platform.DevToolsPath.UrlString;
179
+ }
180
+
165
181
  static encodedPathToRawPathString(encPath: Platform.DevToolsPath.EncodedPathString):
166
182
  Platform.DevToolsPath.RawPathString {
167
183
  return decodeURIComponent(encPath) as Platform.DevToolsPath.RawPathString;
@@ -181,8 +197,9 @@ export class ParsedURL {
181
197
  return new URL(preEncodedPath).toString() as Platform.DevToolsPath.UrlString;
182
198
  }
183
199
 
184
- static relativePathToUrlString(relativePath: string, baseURL: Platform.DevToolsPath.UrlString):
185
- Platform.DevToolsPath.UrlString {
200
+ static relativePathToUrlString(
201
+ relativePath: Platform.DevToolsPath.RawPathString,
202
+ baseURL: Platform.DevToolsPath.UrlString): Platform.DevToolsPath.UrlString {
186
203
  const preEncodedPath: string = ParsedURL.preEncodeSpecialCharactersInPath(
187
204
  relativePath.replace(/\\/g, '/') as Platform.DevToolsPath.RawPathString);
188
205
  return new URL(preEncodedPath, baseURL).toString() as Platform.DevToolsPath.UrlString;
@@ -198,6 +215,12 @@ export class ParsedURL {
198
215
  return decodedFileURL.substr('file://'.length) as Platform.DevToolsPath.RawPathString;
199
216
  }
200
217
 
218
+ static substr<DevToolsPathType extends Platform.DevToolsPath.UrlString|Platform.DevToolsPath.RawPathString|
219
+ Platform.DevToolsPath.EncodedPathString>(
220
+ devToolsPath: DevToolsPathType, from: number, length?: number): DevToolsPathType {
221
+ return devToolsPath.substr(from, length) as typeof devToolsPath;
222
+ }
223
+
201
224
  static urlWithoutHash(url: string): string {
202
225
  const hashIndex = url.indexOf('#');
203
226
  if (hashIndex !== -1) {
@@ -1421,9 +1421,6 @@
1421
1421
  "models/logs/NetworkLog.ts | anonymous": {
1422
1422
  "message": "<anonymous>"
1423
1423
  },
1424
- "models/persistence/Automapping.ts | theAttemptToBindSInTheWorkspace": {
1425
- "message": "The attempt to bind \"{PH1}\" in the workspace failed as this URI is malformed."
1426
- },
1427
1424
  "models/persistence/EditFileSystemView.ts | add": {
1428
1425
  "message": "Add"
1429
1426
  },
@@ -1421,9 +1421,6 @@
1421
1421
  "models/logs/NetworkLog.ts | anonymous": {
1422
1422
  "message": "<âńôńŷḿôúŝ>"
1423
1423
  },
1424
- "models/persistence/Automapping.ts | theAttemptToBindSInTheWorkspace": {
1425
- "message": "T̂h́ê át̂t́êḿp̂t́ t̂ó b̂ín̂d́ \"{PH1}\" îń t̂h́ê ẃôŕk̂śp̂áĉé f̂áîĺêd́ âś t̂h́îś ÛŔÎ íŝ ḿâĺf̂ór̂ḿêd́."
1426
- },
1427
1424
  "models/persistence/EditFileSystemView.ts | add": {
1428
1425
  "message": "Âd́d̂"
1429
1426
  },
@@ -428,6 +428,10 @@ export class DebuggerModel extends SDKModel<EventTypes> {
428
428
  Common.ParsedURL.ParsedURL.urlToRawPathString(url as Platform.DevToolsPath.UrlString, Host.Platform.isWin());
429
429
  urlRegex =
430
430
  `${Platform.StringUtilities.escapeForRegExp(platformPath)}|${Platform.StringUtilities.escapeForRegExp(url)}`;
431
+ if (Host.Platform.isWin() && platformPath.match(/^.:\\/)) {
432
+ // Match upper or lower case drive letter
433
+ urlRegex = `[${platformPath[0].toUpperCase()}${platformPath[0].toLowerCase()}]` + urlRegex.substr(1);
434
+ }
431
435
  }
432
436
  // Adjust column if needed.
433
437
  let minColumnNumber = 0;
@@ -4,7 +4,6 @@
4
4
 
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
- import * as i18n from '../../core/i18n/i18n.js';
8
7
  import * as Platform from '../../core/platform/platform.js';
9
8
  import * as SDK from '../../core/sdk/sdk.js';
10
9
  import * as Bindings from '../bindings/bindings.js';
@@ -14,16 +13,6 @@ import type {FileSystem} from './FileSystemWorkspaceBinding.js';
14
13
  import {FileSystemWorkspaceBinding} from './FileSystemWorkspaceBinding.js';
15
14
  import {PathEncoder, PersistenceImpl} from './PersistenceImpl.js';
16
15
 
17
- const UIStrings = {
18
- /**
19
- *@description Error message when attempting to create a binding from a malformed URI.
20
- *@example {file://%E0%A4%A} PH1
21
- */
22
- theAttemptToBindSInTheWorkspace: 'The attempt to bind "{PH1}" in the workspace failed as this URI is malformed.',
23
- };
24
- const str_ = i18n.i18n.registerUIStrings('models/persistence/Automapping.ts', UIStrings);
25
- const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
26
-
27
16
  export class Automapping {
28
17
  private readonly workspace: Workspace.Workspace.WorkspaceImpl;
29
18
  private readonly onStatusAdded: (arg0: AutomappingStatus) => Promise<void>;
@@ -323,11 +312,7 @@ export class Automapping {
323
312
  private createBinding(networkSourceCode: Workspace.UISourceCode.UISourceCode): Promise<AutomappingStatus|null> {
324
313
  const url = networkSourceCode.url();
325
314
  if (url.startsWith('file://') || url.startsWith('snippet://')) {
326
- const decodedUrl = sanitizeSourceUrl(url);
327
- if (!decodedUrl) {
328
- return Promise.resolve(null as AutomappingStatus | null);
329
- }
330
- const fileSourceCode = this.fileSystemUISourceCodes.get(decodedUrl);
315
+ const fileSourceCode = this.fileSystemUISourceCodes.get(url);
331
316
  const status = fileSourceCode ? new AutomappingStatus(networkSourceCode, fileSourceCode, false) : null;
332
317
  return Promise.resolve(status);
333
318
  }
@@ -341,13 +326,8 @@ export class Automapping {
341
326
  networkPath += 'index.html';
342
327
  }
343
328
 
344
- const urlDecodedNetworkPath = sanitizeSourceUrl(networkPath);
345
- if (!urlDecodedNetworkPath) {
346
- return Promise.resolve(null as AutomappingStatus | null);
347
- }
348
-
349
329
  const similarFiles =
350
- this.filesIndex.similarFiles(urlDecodedNetworkPath).map(path => this.fileSystemUISourceCodes.get(path)) as
330
+ this.filesIndex.similarFiles(networkPath).map(path => this.fileSystemUISourceCodes.get(path)) as
351
331
  Workspace.UISourceCode.UISourceCode[];
352
332
  if (!similarFiles.length) {
353
333
  return Promise.resolve(null as AutomappingStatus | null);
@@ -355,16 +335,6 @@ export class Automapping {
355
335
 
356
336
  return this.pullMetadatas(similarFiles.concat(networkSourceCode)).then(onMetadatas.bind(this));
357
337
 
358
- function sanitizeSourceUrl(url: string): string|null {
359
- try {
360
- const decodedUrl = decodeURI(url);
361
- return decodedUrl;
362
- } catch (error) {
363
- Common.Console.Console.instance().error(i18nString(UIStrings.theAttemptToBindSInTheWorkspace, {PH1: url}));
364
- return null;
365
- }
366
- }
367
-
368
338
  function onMetadatas(this: Automapping): AutomappingStatus|null {
369
339
  const activeFiles =
370
340
  similarFiles.filter(
@@ -193,12 +193,14 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
193
193
  return this.fileSystemInternal.mimeFromPath(uiSourceCode.url());
194
194
  }
195
195
 
196
- initialGitFolders(): string[] {
197
- return this.fileSystemInternal.initialGitFolders().map(folder => this.fileSystemPathInternal + '/' + folder);
196
+ initialGitFolders(): Platform.DevToolsPath.EncodedPathString[] {
197
+ return this.fileSystemInternal.initialGitFolders().map(folder => this.fileSystemPathInternal + '/' + folder) as
198
+ Platform.DevToolsPath.EncodedPathString[];
198
199
  }
199
200
 
200
- private filePathForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): string {
201
- return uiSourceCode.url().substring(this.fileSystemPathInternal.length);
201
+ private filePathForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode):
202
+ Platform.DevToolsPath.EncodedPathString {
203
+ return uiSourceCode.url().substring(this.fileSystemPathInternal.length) as Platform.DevToolsPath.EncodedPathString;
202
204
  }
203
205
 
204
206
  isServiceProject(): boolean {
@@ -274,9 +276,9 @@ export class FileSystem extends Workspace.Workspace.ProjectStore {
274
276
  }
275
277
  console.assert(Boolean(newName));
276
278
  const slash = filePath.lastIndexOf('/');
277
- const parentPath = filePath.substring(0, slash);
278
- filePath = parentPath + '/' + newName;
279
- filePath = filePath.substr(1);
279
+ const parentPath = Common.ParsedURL.ParsedURL.substr(filePath, 0, slash);
280
+ filePath = Common.ParsedURL.ParsedURL.encodedFromParentPathAndName(parentPath, newName);
281
+ filePath = Common.ParsedURL.ParsedURL.substr(filePath, 1);
280
282
  const newURL = this.fileSystemBaseURL + filePath;
281
283
  const newContentType = this.fileSystemInternal.contentType(newName);
282
284
  this.renameUISourceCode(uiSourceCode, newName);
@@ -77,8 +77,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
77
77
  private readonly excludedFoldersSetting: Common.Settings.Setting<{[path: string]: string[]}>;
78
78
  private excludedFoldersInternal: Set<string>;
79
79
  private readonly excludedEmbedderFolders: string[];
80
- private readonly initialFilePathsInternal: Set<string>;
81
- private readonly initialGitFoldersInternal: Set<string>;
80
+ private readonly initialFilePathsInternal: Set<Platform.DevToolsPath.EncodedPathString>;
81
+ private readonly initialGitFoldersInternal: Set<Platform.DevToolsPath.EncodedPathString>;
82
82
  private readonly fileLocks: Map<string, Promise<void>>;
83
83
 
84
84
  constructor(
@@ -129,7 +129,7 @@ export class IsolatedFileSystem extends PlatformFileSystem {
129
129
  const promise = new Promise<Metadata|null>(f => {
130
130
  fulfill = f;
131
131
  });
132
- this.domFileSystem.root.getFile(path, undefined, fileEntryLoaded, errorHandler);
132
+ this.domFileSystem.root.getFile(decodeURIComponent(path), undefined, fileEntryLoaded, errorHandler);
133
133
  return promise;
134
134
 
135
135
  function fileEntryLoaded(entry: FileEntry): void {
@@ -143,11 +143,11 @@ export class IsolatedFileSystem extends PlatformFileSystem {
143
143
  }
144
144
  }
145
145
 
146
- initialFilePaths(): string[] {
146
+ initialFilePaths(): Platform.DevToolsPath.EncodedPathString[] {
147
147
  return [...this.initialFilePathsInternal];
148
148
  }
149
149
 
150
- initialGitFolders(): string[] {
150
+ initialGitFolders(): Platform.DevToolsPath.EncodedPathString[] {
151
151
  return [...this.initialGitFoldersInternal];
152
152
  }
153
153
 
@@ -168,12 +168,14 @@ export class IsolatedFileSystem extends PlatformFileSystem {
168
168
  if (this.isFileExcluded(entry.fullPath)) {
169
169
  continue;
170
170
  }
171
- this.initialFilePathsInternal.add(entry.fullPath.substr(1));
171
+ this.initialFilePathsInternal.add(Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
172
+ entry.fullPath.substr(1) as Platform.DevToolsPath.RawPathString));
172
173
  } else {
173
174
  if (entry.fullPath.endsWith('/.git')) {
174
175
  const lastSlash = entry.fullPath.lastIndexOf('/');
175
176
  const parentFolder = entry.fullPath.substring(1, lastSlash);
176
- this.initialGitFoldersInternal.add(parentFolder);
177
+ this.initialGitFoldersInternal.add(Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
178
+ parentFolder as Platform.DevToolsPath.RawPathString));
177
179
  }
178
180
  if (this.isFileExcluded(entry.fullPath + '/')) {
179
181
  this.excludedEmbedderFolders.push(Common.ParsedURL.ParsedURL.urlToRawPathString(
@@ -221,7 +223,7 @@ export class IsolatedFileSystem extends PlatformFileSystem {
221
223
  }
222
224
 
223
225
  async createFile(path: string, name: string|null): Promise<string|null> {
224
- const dirEntry = await this.createFoldersIfNotExist(path);
226
+ const dirEntry = await this.createFoldersIfNotExist(decodeURIComponent(path));
225
227
  if (!dirEntry) {
226
228
  return null;
227
229
  }
@@ -230,7 +232,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
230
232
  if (!fileEntry) {
231
233
  return null;
232
234
  }
233
- return fileEntry.fullPath.substr(1);
235
+ return Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
236
+ fileEntry.fullPath.substr(1) as Platform.DevToolsPath.RawPathString);
234
237
 
235
238
  function createFileCandidate(
236
239
  this: IsolatedFileSystem, name: string, newFileIndex?: number): Promise<FileEntry|null> {
@@ -256,7 +259,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
256
259
  const promise = new Promise<boolean>(resolve => {
257
260
  resolveCallback = resolve;
258
261
  });
259
- this.domFileSystem.root.getFile(path, undefined, fileEntryLoaded.bind(this), errorHandler.bind(this));
262
+ this.domFileSystem.root.getFile(
263
+ decodeURIComponent(path), undefined, fileEntryLoaded.bind(this), errorHandler.bind(this));
260
264
  return promise;
261
265
 
262
266
  function fileEntryLoaded(this: IsolatedFileSystem, fileEntry: FileEntry): void {
@@ -279,7 +283,7 @@ export class IsolatedFileSystem extends PlatformFileSystem {
279
283
 
280
284
  requestFileBlob(path: string): Promise<Blob|null> {
281
285
  return new Promise(resolve => {
282
- this.domFileSystem.root.getFile(path, undefined, entry => {
286
+ this.domFileSystem.root.getFile(decodeURIComponent(path), undefined, entry => {
283
287
  entry.file(resolve, errorHandler.bind(this));
284
288
  }, errorHandler.bind(this));
285
289
 
@@ -347,7 +351,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
347
351
  // @ts-ignore TODO(crbug.com/1172300) Properly type this after jsdoc to ts migration
348
352
  callback = x;
349
353
  });
350
- this.domFileSystem.root.getFile(path, {create: true}, fileEntryLoaded.bind(this), errorHandler.bind(this));
354
+ this.domFileSystem.root.getFile(
355
+ decodeURIComponent(path), {create: true}, fileEntryLoaded.bind(this), errorHandler.bind(this));
351
356
  return promise;
352
357
  };
353
358
 
@@ -391,7 +396,8 @@ export class IsolatedFileSystem extends PlatformFileSystem {
391
396
  let fileEntry: FileEntry;
392
397
  let dirEntry: DirectoryEntry;
393
398
 
394
- this.domFileSystem.root.getFile(path, undefined, fileEntryLoaded.bind(this), errorHandler.bind(this));
399
+ this.domFileSystem.root.getFile(
400
+ decodeURIComponent(path), undefined, fileEntryLoaded.bind(this), errorHandler.bind(this));
395
401
 
396
402
  function fileEntryLoaded(this: IsolatedFileSystem, entry: FileEntry): void {
397
403
  if (entry.name === newName) {
@@ -458,7 +464,7 @@ export class IsolatedFileSystem extends PlatformFileSystem {
458
464
  }
459
465
 
460
466
  private requestEntries(path: string, callback: (arg0: Array<FileEntry>) => void): void {
461
- this.domFileSystem.root.getDirectory(path, undefined, innerCallback.bind(this), errorHandler);
467
+ this.domFileSystem.root.getDirectory(decodeURIComponent(path), undefined, innerCallback.bind(this), errorHandler);
462
468
 
463
469
  function innerCallback(this: IsolatedFileSystem, dirEntry: DirectoryEntry): void {
464
470
  this.readDirectory(dirEntry, callback);
@@ -248,6 +248,11 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
248
248
  }
249
249
  }
250
250
 
251
+ private fileUrlFromNetworkUrl(url: Platform.DevToolsPath.UrlString): Platform.DevToolsPath.UrlString {
252
+ return (this.projectInternal as FileSystem).fileSystemPath() + '/' + this.encodedPathFromUrl(url) as
253
+ Platform.DevToolsPath.UrlString;
254
+ }
255
+
251
256
  private decodeLocalPathToUrlPath(path: string): string {
252
257
  try {
253
258
  return unescape(path);
@@ -341,12 +346,11 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
341
346
  !this.canHandleNetworkUISourceCode(uiSourceCode)) {
342
347
  return;
343
348
  }
344
- const url = Common.ParsedURL.ParsedURL.urlWithoutHash(uiSourceCode.url());
349
+ const url = Common.ParsedURL.ParsedURL.urlWithoutHash(uiSourceCode.url()) as Platform.DevToolsPath.UrlString;
345
350
  this.networkUISourceCodeForEncodedPath.set(this.encodedPathFromUrl(url), uiSourceCode);
346
351
 
347
352
  const project = this.projectInternal as FileSystem;
348
- const fileSystemUISourceCode =
349
- project.uiSourceCodeForURL(project.fileSystemPath() + '/' + this.encodedPathFromUrl(url));
353
+ const fileSystemUISourceCode = project.uiSourceCodeForURL(this.fileUrlFromNetworkUrl(url));
350
354
  if (fileSystemUISourceCode) {
351
355
  await this.bind(uiSourceCode, fileSystemUISourceCode);
352
356
  }
@@ -571,7 +575,7 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
571
575
  return;
572
576
  }
573
577
  const proj = this.projectInternal as FileSystem;
574
- const path = proj.fileSystemPath() + '/' + this.encodedPathFromUrl(interceptedRequest.request.url);
578
+ const path = this.fileUrlFromNetworkUrl(interceptedRequest.request.url as Platform.DevToolsPath.UrlString);
575
579
  const fileSystemUISourceCode = proj.uiSourceCodeForURL(path);
576
580
  let responseHeaders: Protocol.Fetch.HeaderEntry[] = [];
577
581
  if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.HEADER_OVERRIDES)) {
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import type * as Common from '../../core/common/common.js';
6
+ import type * as Platform from '../../core/platform/platform.js';
6
7
  import * as i18n from '../../core/i18n/i18n.js';
7
8
  import type * as TextUtils from '../text_utils/text_utils.js';
8
9
 
@@ -26,11 +27,11 @@ export class PlatformFileSystem {
26
27
  return Promise.resolve(null);
27
28
  }
28
29
 
29
- initialFilePaths(): string[] {
30
+ initialFilePaths(): Platform.DevToolsPath.EncodedPathString[] {
30
31
  return [];
31
32
  }
32
33
 
33
- initialGitFolders(): string[] {
34
+ initialGitFolders(): Platform.DevToolsPath.EncodedPathString[] {
34
35
  return [];
35
36
  }
36
37
 
@@ -36,7 +36,7 @@ import * as Platform from '../../core/platform/platform.js';
36
36
  import * as TextUtils from '../text_utils/text_utils.js';
37
37
 
38
38
  import type {Project} from './WorkspaceImpl.js';
39
- import {Events as WorkspaceImplEvents, projectTypes} from './WorkspaceImpl.js';
39
+ import {Events as WorkspaceImplEvents} from './WorkspaceImpl.js';
40
40
 
41
41
  const UIStrings = {
42
42
  /**
@@ -82,9 +82,13 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
82
82
  if (parsedURL) {
83
83
  this.originInternal = parsedURL.securityOrigin();
84
84
  this.parentURLInternal = this.originInternal + parsedURL.folderPathComponents;
85
- this.nameInternal = parsedURL.lastPathComponent;
86
85
  if (parsedURL.queryParams) {
87
- this.nameInternal += '?' + parsedURL.queryParams;
86
+ // in case file name contains query params, it doesn't look like a normal file name anymore
87
+ // so it can as well remain encoded
88
+ this.nameInternal = parsedURL.lastPathComponent + '?' + parsedURL.queryParams;
89
+ } else {
90
+ // file name looks best decoded
91
+ this.nameInternal = decodeURIComponent(parsedURL.lastPathComponent);
88
92
  }
89
93
  } else {
90
94
  this.originInternal = '';
@@ -138,15 +142,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
138
142
  if (!this.nameInternal) {
139
143
  return i18nString(UIStrings.index);
140
144
  }
141
- let name: string = this.nameInternal;
142
- try {
143
- if (this.project().type() === projectTypes.FileSystem) {
144
- name = unescape(name);
145
- } else {
146
- name = decodeURI(name);
147
- }
148
- } catch (error) {
149
- }
145
+ const name = this.nameInternal;
150
146
  return skipTrim ? name : Platform.StringUtilities.trimEndWithMaxLength(name, 100);
151
147
  }
152
148
 
@@ -178,10 +174,12 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
178
174
 
179
175
  private updateName(name: string, url: string, contentType?: Common.ResourceType.ResourceType): void {
180
176
  const oldURL = this.urlInternal;
181
- this.urlInternal = this.urlInternal.substring(0, this.urlInternal.length - this.nameInternal.length) + name;
182
177
  this.nameInternal = name;
183
178
  if (url) {
184
179
  this.urlInternal = url;
180
+ } else {
181
+ this.urlInternal = Common.ParsedURL.ParsedURL.relativePathToUrlString(
182
+ name as Platform.DevToolsPath.RawPathString, oldURL as Platform.DevToolsPath.UrlString);
185
183
  }
186
184
  if (contentType) {
187
185
  this.contentTypeInternal = contentType;
@@ -191,7 +189,6 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
191
189
  WorkspaceImplEvents.UISourceCodeRenamed, {oldURL: oldURL, uiSourceCode: this});
192
190
  }
193
191
 
194
- // TODO(crbug.com/1253323): Cast to RawPathString will be removed when migration to branded types is complete.
195
192
  contentURL(): string {
196
193
  return this.url();
197
194
  }
@@ -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';
@@ -175,7 +176,10 @@ export abstract class ProjectStore implements Project {
175
176
 
176
177
  renameUISourceCode(uiSourceCode: UISourceCode, newName: string): void {
177
178
  const oldPath = uiSourceCode.url();
178
- const newPath = uiSourceCode.parentURL() ? uiSourceCode.parentURL() + '/' + newName : newName;
179
+ const newPath = uiSourceCode.parentURL() ?
180
+ Common.ParsedURL.ParsedURL.urlFromParentUrlAndName(
181
+ uiSourceCode.parentURL() as Platform.DevToolsPath.UrlString, newName) :
182
+ encodeURIComponent(newName);
179
183
  const value = this.uiSourceCodesMap.get(oldPath) as {
180
184
  uiSourceCode: UISourceCode,
181
185
  index: number,
@@ -28,12 +28,12 @@ const UIStrings = {
28
28
  const str_ = i18n.i18n.registerUIStrings('panels/snippets/ScriptSnippetFileSystem.ts', UIStrings);
29
29
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
30
30
 
31
- function escapeSnippetName(name: string): string {
32
- return escape(name);
31
+ function escapeSnippetName(name: string): Platform.DevToolsPath.EncodedPathString {
32
+ return Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(name as Platform.DevToolsPath.RawPathString);
33
33
  }
34
34
 
35
35
  function unescapeSnippetName(name: string): string {
36
- return unescape(name);
36
+ return Common.ParsedURL.ParsedURL.encodedPathToRawPathString(name as Platform.DevToolsPath.EncodedPathString);
37
37
  }
38
38
 
39
39
  export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFileSystem {
@@ -47,7 +47,7 @@ export class SnippetFileSystem extends Persistence.PlatformFileSystem.PlatformFi
47
47
  this.snippetsSetting = Common.Settings.Settings.instance().createSetting('scriptSnippets', []);
48
48
  }
49
49
 
50
- initialFilePaths(): string[] {
50
+ initialFilePaths(): Platform.DevToolsPath.EncodedPathString[] {
51
51
  const savedSnippets: Snippet[] = this.snippetsSetting.get();
52
52
  return savedSnippets.map(snippet => escapeSnippetName(snippet.name));
53
53
  }
@@ -77,7 +77,7 @@ export class SnippetsQuickOpen extends QuickOpen.FilteredListWidget.Provider {
77
77
  }
78
78
 
79
79
  renderItem(itemIndex: number, query: string, titleElement: Element, _subtitleElement: Element): void {
80
- titleElement.textContent = unescape(this.snippets[itemIndex].name());
80
+ titleElement.textContent = this.snippets[itemIndex].name();
81
81
  titleElement.classList.add('monospace');
82
82
  QuickOpen.FilteredListWidget.FilteredListWidget.highlightRanges(titleElement, query, true);
83
83
  }
@@ -584,6 +584,15 @@ export class TabbedEditorContainer extends Common.ObjectWrapper.ObjectWrapper<Ev
584
584
  const uiSourceCode = event.data;
585
585
  this.updateFileTitle(uiSourceCode);
586
586
  this.updateHistory();
587
+
588
+ // Remove from map under old url if it has changed.
589
+ for (const [k, v] of this.uriToUISourceCode) {
590
+ if (v === uiSourceCode && k !== v.url()) {
591
+ this.uriToUISourceCode.delete(k);
592
+ }
593
+ }
594
+ // Ensure it is mapped under current url.
595
+ this.canonicalUISourceCode(uiSourceCode);
587
596
  }
588
597
 
589
598
  private uiSourceCodeWorkingCopyChanged(
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.970391"
57
+ "version": "1.0.970539"
58
58
  }