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.
- package/front_end/core/common/ParsedURL.ts +37 -4
- package/front_end/core/platform/DevToolsPath.ts +3 -0
- package/front_end/core/sdk/CSSRule.ts +2 -2
- package/front_end/core/sdk/DOMDebuggerModel.ts +2 -2
- package/front_end/core/sdk/NetworkRequest.ts +1 -1
- package/front_end/core/sdk/SourceMap.ts +14 -5
- package/front_end/core/sdk/Target.ts +2 -2
- package/front_end/legacy_test_runner/bindings_test_runner/BindingsTestRunner.js +5 -0
- package/front_end/models/bindings/BreakpointManager.ts +0 -2
- package/front_end/models/bindings/ContentProviderBasedProject.ts +6 -4
- package/front_end/models/persistence/EditFileSystemView.ts +3 -1
- package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +14 -9
- package/front_end/models/persistence/IsolatedFileSystem.ts +66 -40
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +4 -3
- package/front_end/models/persistence/NetworkPersistenceManager.ts +6 -5
- package/front_end/models/persistence/PlatformFileSystem.ts +15 -10
- package/front_end/models/workspace/UISourceCode.ts +4 -2
- package/front_end/models/workspace/WorkspaceImpl.ts +9 -5
- package/front_end/panels/application/ServiceWorkerCacheViews.ts +1 -1
- package/front_end/panels/network/ResourceWebSocketFrameView.ts +1 -2
- package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +25 -19
- package/front_end/panels/sources/NavigatorView.ts +9 -5
- package/front_end/panels/sources/SourcesNavigator.ts +2 -2
- package/front_end/ui/components/buttons/Button.ts +11 -1
- package/front_end/ui/components/buttons/button.css +31 -10
- package/front_end/ui/components/docs/button/basic.ts +47 -1
- package/front_end/ui/legacy/themeColors.css +4 -0
- 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
|
219
|
-
|
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
|
225
|
-
|
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
|
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
|
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() :
|
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,
|
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
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
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 ||
|
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
|
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 =
|
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:
|
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:
|
143
|
+
canExcludeFolder(_path: Platform.DevToolsPath.EncodedPathString): boolean {
|
143
144
|
return false;
|
144
145
|
}
|
145
146
|
|
146
|
-
async createFile(
|
147
|
-
|
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(
|
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
|
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:
|
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 =
|
345
|
+
let relativeFolder = Common.ParsedURL.ParsedURL.sliceUrlToEncodedPathString(
|
346
|
+
url as Platform.DevToolsPath.UrlString, this.fileSystemBaseURL.length);
|
343
347
|
if (!relativeFolder.startsWith('/')) {
|
344
|
-
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:
|
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(
|
369
|
-
|
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:
|
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:
|
73
|
+
private readonly embedderPathInternal: Platform.DevToolsPath.RawPathString;
|
74
74
|
private readonly domFileSystem: FileSystem;
|
75
|
-
private readonly excludedFoldersSetting:
|
76
|
-
|
77
|
-
private
|
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<
|
81
|
+
private readonly fileLocks: Map<Platform.DevToolsPath.EncodedPathString, Promise<void>>;
|
81
82
|
|
82
83
|
constructor(
|
83
|
-
manager: IsolatedFileSystemManager, path:
|
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:
|
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:
|
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:
|
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(
|
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():
|
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(
|
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(
|
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(
|
178
|
-
|
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:
|
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:
|
224
|
-
|
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(
|
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:
|
253
|
+
this: IsolatedFileSystem, name: Platform.DevToolsPath.RawPathString,
|
254
|
+
newFileIndex?: number): Promise<FileEntry|null> {
|
238
255
|
return new Promise(resolve => {
|
239
|
-
const nameCandidate = name
|
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:
|
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
|
-
|
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:
|
300
|
+
requestFileBlob(path: Platform.DevToolsPath.EncodedPathString): Promise<Blob|null> {
|
283
301
|
return new Promise(resolve => {
|
284
|
-
this.domFileSystem.root.getFile(
|
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:
|
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:
|
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:
|
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
|
-
|
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(
|
389
|
-
|
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
|
-
|
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:
|
465
|
-
this.domFileSystem.root.getDirectory(
|
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:
|
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:
|
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:
|
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:
|
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 &&
|
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]:
|
352
|
-
[Events.ExcludedFolderRemoved]:
|
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:
|
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
|
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 =
|
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 =
|
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:
|
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:
|
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:
|
57
|
+
deleteFile(_path: Platform.DevToolsPath.EncodedPathString): Promise<boolean> {
|
56
58
|
return Promise.resolve(false);
|
57
59
|
}
|
58
60
|
|
59
|
-
requestFileBlob(_path:
|
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:
|
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:
|
70
|
+
setFileContent(_path: Platform.DevToolsPath.EncodedPathString, _content: string, _isBase64: boolean): void {
|
68
71
|
throw new Error('Not implemented');
|
69
72
|
}
|
70
73
|
|
71
|
-
renameFile(
|
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:
|
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:
|
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:
|
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 =
|
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:
|
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:
|
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:
|
63
|
-
createFile(path:
|
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:
|
213
|
-
abstract createFile(
|
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
|
-
|
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,
|
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:
|
34
|
-
return Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(name
|
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:
|
38
|
-
return Common.ParsedURL.ParsedURL.encodedPathToRawPathString(name
|
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:
|
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 =
|
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:
|
69
|
-
const name = unescapeSnippetName(
|
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:
|
80
|
-
|
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:
|
90
|
-
|
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(
|
102
|
-
|
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 =
|
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(
|
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:
|
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
|
-
|
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:
|
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(
|
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
|
-
|
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
|
-
|
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