chrome-devtools-frontend 1.0.1021582 → 1.0.1022059
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/.eslintignore +14 -1
- package/extension-api/ExtensionAPI.d.ts +54 -4
- package/front_end/.eslintrc.js +3 -1
- package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -0
- package/front_end/core/host/UserMetrics.ts +18 -0
- package/front_end/core/i18n/locales/en-US.json +27 -0
- package/front_end/core/i18n/locales/en-XL.json +27 -0
- package/front_end/devtools_compatibility.js +1 -0
- package/front_end/legacy_test_runner/sources_test_runner/DebuggerTestRunner.js +4 -3
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +157 -117
- package/front_end/models/extensions/ExtensionAPI.ts +101 -13
- package/front_end/models/extensions/ExtensionServer.ts +63 -1
- package/front_end/models/extensions/LanguageExtensionEndpoint.ts +16 -3
- package/front_end/models/timeline_model/TimelineModel.ts +164 -7
- package/front_end/panels/application/AppManifestView.ts +13 -2
- package/front_end/panels/application/ApplicationPanelSidebar.ts +67 -5
- package/front_end/panels/elements/ElementsTreeOutline.ts +41 -7
- package/front_end/panels/elements/TopLayerContainer.ts +9 -1
- package/front_end/panels/elements/components/AdornerManager.ts +7 -0
- package/front_end/panels/elements/elementsTreeOutline.css +4 -0
- package/front_end/third_party/acorn/acorn.ts +1 -1
- package/front_end/third_party/chromium/client-variations/client-variations.ts +1 -1
- package/front_end/third_party/diff/DiffWrapper.ts +2 -0
- package/front_end/third_party/i18n/i18n-impl.ts +5 -1
- package/front_end/third_party/i18n/i18n.ts +1 -1
- package/front_end/third_party/i18n/locales.ts +1 -1
- package/front_end/third_party/marked/marked.ts +1 -1
- package/front_end/third_party/puppeteer/puppeteer.ts +6 -6
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorController.ts +23 -1
- package/front_end/ui/legacy/ReportView.ts +8 -0
- package/package.json +1 -1
- package/scripts/eslint_rules/lib/custom_element_definitions_location.js +28 -13
- package/scripts/eslint_rules/lib/es_modules_import.js +5 -1
- package/scripts/eslint_rules/tests/custom_element_definitions_location_test.js +9 -2
- package/scripts/eslint_rules/tests/es_modules_import_test.js +5 -0
@@ -29,7 +29,7 @@ class LanguageExtensionEndpointImpl extends ExtensionEndpoint {
|
|
29
29
|
}
|
30
30
|
}
|
31
31
|
|
32
|
-
export class LanguageExtensionEndpoint
|
32
|
+
export class LanguageExtensionEndpoint implements Bindings.DebuggerLanguagePlugins.DebuggerLanguagePlugin {
|
33
33
|
private readonly supportedScriptTypes: {
|
34
34
|
language: string,
|
35
35
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
@@ -37,6 +37,8 @@ export class LanguageExtensionEndpoint extends Bindings.DebuggerLanguagePlugins.
|
|
37
37
|
symbol_types: Array<string>,
|
38
38
|
};
|
39
39
|
private endpoint: LanguageExtensionEndpointImpl;
|
40
|
+
name: string;
|
41
|
+
|
40
42
|
constructor(
|
41
43
|
name: string, supportedScriptTypes: {
|
42
44
|
language: string,
|
@@ -45,7 +47,7 @@ export class LanguageExtensionEndpoint extends Bindings.DebuggerLanguagePlugins.
|
|
45
47
|
symbol_types: Array<string>,
|
46
48
|
},
|
47
49
|
port: MessagePort) {
|
48
|
-
|
50
|
+
this.name = name;
|
49
51
|
this.supportedScriptTypes = supportedScriptTypes;
|
50
52
|
this.endpoint = new LanguageExtensionEndpointImpl(this, port);
|
51
53
|
}
|
@@ -172,6 +174,17 @@ export class LanguageExtensionEndpoint extends Bindings.DebuggerLanguagePlugins.
|
|
172
174
|
PrivateAPI.LanguageExtensionPluginCommands.GetMappedLines, {rawModuleId, sourceFileURL});
|
173
175
|
}
|
174
176
|
|
175
|
-
|
177
|
+
evaluate(expression: string, context: Chrome.DevTools.RawLocation, stopId: number):
|
178
|
+
Promise<Chrome.DevTools.RemoteObject> {
|
179
|
+
return this.endpoint.sendRequest(
|
180
|
+
PrivateAPI.LanguageExtensionPluginCommands.FormatValue, {expression, context, stopId});
|
181
|
+
}
|
182
|
+
|
183
|
+
getProperties(objectId: Chrome.DevTools.RemoteObjectId): Promise<Chrome.DevTools.PropertyDescriptor[]> {
|
184
|
+
return this.endpoint.sendRequest(PrivateAPI.LanguageExtensionPluginCommands.GetProperties, {objectId});
|
185
|
+
}
|
186
|
+
|
187
|
+
releaseObject(objectId: Chrome.DevTools.RemoteObjectId): Promise<void> {
|
188
|
+
return this.endpoint.sendRequest(PrivateAPI.LanguageExtensionPluginCommands.ReleaseObject, {objectId});
|
176
189
|
}
|
177
190
|
}
|
@@ -61,6 +61,39 @@ const UIStrings = {
|
|
61
61
|
*@example {https://google.com} PH2
|
62
62
|
*/
|
63
63
|
workerSS: '`Worker`: {PH1} — {PH2}',
|
64
|
+
|
65
|
+
/**
|
66
|
+
*@description Title of a bidder auction worklet with known URL in the timeline flame chart of the Performance panel
|
67
|
+
*@example {https://google.com} PH1
|
68
|
+
*/
|
69
|
+
bidderWorkletS: 'Bidder Worklet — {PH1}',
|
70
|
+
|
71
|
+
/**
|
72
|
+
*@description Title of a seller auction worklet with known URL in the timeline flame chart of the Performance panel
|
73
|
+
*@example {https://google.com} PH1
|
74
|
+
*/
|
75
|
+
sellerWorkletS: 'Seller Worklet — {PH1}',
|
76
|
+
|
77
|
+
/**
|
78
|
+
*@description Title of an auction worklet with known URL in the timeline flame chart of the Performance panel
|
79
|
+
*@example {https://google.com} PH1
|
80
|
+
*/
|
81
|
+
unknownWorkletS: 'Auction Worklet — {PH1}',
|
82
|
+
|
83
|
+
/**
|
84
|
+
*@description Title of a bidder auction worklet in the timeline flame chart of the Performance panel
|
85
|
+
*/
|
86
|
+
bidderWorklet: 'Bidder Worklet',
|
87
|
+
|
88
|
+
/**
|
89
|
+
*@description Title of a seller auction worklet in the timeline flame chart of the Performance panel
|
90
|
+
*/
|
91
|
+
sellerWorklet: 'Seller Worklet',
|
92
|
+
|
93
|
+
/**
|
94
|
+
*@description Title of an auction worklet in the timeline flame chart of the Performance panel
|
95
|
+
*/
|
96
|
+
unknownWorklet: 'Auction Worklet',
|
64
97
|
};
|
65
98
|
const str_ = i18n.i18n.registerUIStrings('models/timeline_model/TimelineModel.ts', UIStrings);
|
66
99
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
@@ -73,6 +106,7 @@ export class TimelineModelImpl {
|
|
73
106
|
private sessionId!: string|null;
|
74
107
|
private mainFrameNodeId!: number|null;
|
75
108
|
private pageFrames!: Map<Protocol.Page.FrameId, PageFrame>;
|
109
|
+
private auctionWorklets!: Map<string, AuctionWorklet>;
|
76
110
|
private cpuProfilesInternal!: SDK.CPUProfileDataModel.CPUProfileDataModel[];
|
77
111
|
private workerIdByThread!: WeakMap<SDK.TracingModel.Thread, string>;
|
78
112
|
private requestsFromBrowser!: Map<string, SDK.TracingModel.Event>;
|
@@ -327,7 +361,8 @@ export class TimelineModelImpl {
|
|
327
361
|
for (const process of tracingModel.sortedProcesses()) {
|
328
362
|
for (const thread of process.sortedThreads()) {
|
329
363
|
this.processThreadEvents(
|
330
|
-
tracingModel, [{from: 0, to: Infinity}], thread, thread === browserMainThread, false, true,
|
364
|
+
tracingModel, [{from: 0, to: Infinity}], thread, thread === browserMainThread, false, true,
|
365
|
+
WorkletType.NotWorklet, null);
|
331
366
|
}
|
332
367
|
}
|
333
368
|
}
|
@@ -368,7 +403,7 @@ export class TimelineModelImpl {
|
|
368
403
|
}
|
369
404
|
this.processThreadEvents(
|
370
405
|
tracingModel, [{from: startTime, to: endTime}], thread, thread === metaEvent.thread, Boolean(workerUrl),
|
371
|
-
true, workerUrl);
|
406
|
+
true, WorkletType.NotWorklet, workerUrl);
|
372
407
|
}
|
373
408
|
startTime = endTime;
|
374
409
|
}
|
@@ -379,6 +414,7 @@ export class TimelineModelImpl {
|
|
379
414
|
from: number,
|
380
415
|
to: number,
|
381
416
|
main: boolean,
|
417
|
+
workletType: WorkletType,
|
382
418
|
url: Platform.DevToolsPath.UrlString,
|
383
419
|
}[]>();
|
384
420
|
for (const frame of this.pageFrames.values()) {
|
@@ -390,9 +426,32 @@ export class TimelineModelImpl {
|
|
390
426
|
processData.set(pid, data);
|
391
427
|
}
|
392
428
|
const to = i === frame.processes.length - 1 ? (frame.deletedTime || Infinity) : frame.processes[i + 1].time;
|
393
|
-
data.push({
|
429
|
+
data.push({
|
430
|
+
from: frame.processes[i].time,
|
431
|
+
to: to,
|
432
|
+
main: !frame.parent,
|
433
|
+
url: frame.processes[i].url,
|
434
|
+
workletType: WorkletType.NotWorklet,
|
435
|
+
});
|
394
436
|
}
|
395
437
|
}
|
438
|
+
for (const auctionWorklet of this.auctionWorklets.values()) {
|
439
|
+
const pid = auctionWorklet.processId;
|
440
|
+
let data = processData.get(pid);
|
441
|
+
if (!data) {
|
442
|
+
data = [];
|
443
|
+
processData.set(pid, data);
|
444
|
+
}
|
445
|
+
data.push({
|
446
|
+
from: auctionWorklet.startTime,
|
447
|
+
to: auctionWorklet.endTime,
|
448
|
+
main: false,
|
449
|
+
workletType: auctionWorklet.workletType,
|
450
|
+
url:
|
451
|
+
(auctionWorklet.host ? 'https://' + auctionWorklet.host as Platform.DevToolsPath.UrlString :
|
452
|
+
Platform.DevToolsPath.EmptyUrlString),
|
453
|
+
});
|
454
|
+
}
|
396
455
|
const allMetadataEvents = tracingModel.devToolsMetadataEvents();
|
397
456
|
for (const process of tracingModel.sortedProcesses()) {
|
398
457
|
const data = processData.get(process.id());
|
@@ -404,6 +463,12 @@ export class TimelineModelImpl {
|
|
404
463
|
let lastUrl: Platform.DevToolsPath.UrlString|null = null;
|
405
464
|
let lastMainUrl: Platform.DevToolsPath.UrlString|null = null;
|
406
465
|
let hasMain = false;
|
466
|
+
let allWorklet = true;
|
467
|
+
|
468
|
+
// false: not set, true: inconsistent.
|
469
|
+
let workletUrl: Platform.DevToolsPath.UrlString|boolean = false;
|
470
|
+
// NotWorklet used for not set.
|
471
|
+
let workletType: WorkletType = WorkletType.NotWorklet;
|
407
472
|
for (const item of data) {
|
408
473
|
const last = ranges[ranges.length - 1];
|
409
474
|
if (!last || item.from > last.to) {
|
@@ -414,6 +479,23 @@ export class TimelineModelImpl {
|
|
414
479
|
if (item.main) {
|
415
480
|
hasMain = true;
|
416
481
|
}
|
482
|
+
if (item.workletType === WorkletType.NotWorklet) {
|
483
|
+
allWorklet = false;
|
484
|
+
} else {
|
485
|
+
// Update combined workletUrl, checking for inconsistencies.
|
486
|
+
if (workletUrl === false) {
|
487
|
+
workletUrl = item.url;
|
488
|
+
} else if (workletUrl !== item.url) {
|
489
|
+
workletUrl = true; // Process used for different things.
|
490
|
+
}
|
491
|
+
|
492
|
+
if (workletType === WorkletType.NotWorklet) {
|
493
|
+
workletType = item.workletType;
|
494
|
+
} else if (workletType !== item.workletType) {
|
495
|
+
workletType = WorkletType.UnknownWorklet;
|
496
|
+
}
|
497
|
+
}
|
498
|
+
|
417
499
|
if (item.url) {
|
418
500
|
if (item.main) {
|
419
501
|
lastMainUrl = item.url;
|
@@ -426,7 +508,7 @@ export class TimelineModelImpl {
|
|
426
508
|
if (thread.name() === TimelineModelImpl.RendererMainThreadName) {
|
427
509
|
this.processThreadEvents(
|
428
510
|
tracingModel, ranges, thread, true /* isMainThread */, false /* isWorker */, hasMain,
|
429
|
-
hasMain ? lastMainUrl : lastUrl);
|
511
|
+
WorkletType.NotWorklet, hasMain ? lastMainUrl : lastUrl);
|
430
512
|
} else if (
|
431
513
|
thread.name() === TimelineModelImpl.WorkerThreadName ||
|
432
514
|
thread.name() === TimelineModelImpl.WorkerThreadNameLegacy) {
|
@@ -449,11 +531,24 @@ export class TimelineModelImpl {
|
|
449
531
|
this.workerIdByThread.set(thread, workerMetaEvent.args['data']['workerId'] || '');
|
450
532
|
this.processThreadEvents(
|
451
533
|
tracingModel, ranges, thread, false /* isMainThread */, true /* isWorker */, false /* forMainFrame */,
|
452
|
-
workerMetaEvent.args['data']['url'] || Platform.DevToolsPath.EmptyUrlString);
|
534
|
+
WorkletType.NotWorklet, workerMetaEvent.args['data']['url'] || Platform.DevToolsPath.EmptyUrlString);
|
453
535
|
} else {
|
536
|
+
let urlForOther: Platform.DevToolsPath.UrlString|null = null;
|
537
|
+
let workletTypeForOther: WorkletType = WorkletType.NotWorklet;
|
538
|
+
if (thread.name() === TimelineModelImpl.AuctionWorkletThreadName) {
|
539
|
+
if (typeof workletUrl !== 'boolean') {
|
540
|
+
urlForOther = workletUrl;
|
541
|
+
}
|
542
|
+
workletTypeForOther = workletType;
|
543
|
+
} else {
|
544
|
+
// For processes that only do auction worklet things, skip other threads.
|
545
|
+
if (allWorklet) {
|
546
|
+
continue;
|
547
|
+
}
|
548
|
+
}
|
454
549
|
this.processThreadEvents(
|
455
550
|
tracingModel, ranges, thread, false /* isMainThread */, false /* isWorker */, false /* forMainFrame */,
|
456
|
-
|
551
|
+
workletTypeForOther, urlForOther);
|
457
552
|
}
|
458
553
|
}
|
459
554
|
}
|
@@ -690,13 +785,26 @@ export class TimelineModelImpl {
|
|
690
785
|
return events;
|
691
786
|
}
|
692
787
|
|
788
|
+
private static nameAuctionWorklet(workletType: WorkletType, url: Platform.DevToolsPath.UrlString|null): string {
|
789
|
+
switch (workletType) {
|
790
|
+
case WorkletType.BidderWorklet:
|
791
|
+
return url ? i18nString(UIStrings.bidderWorkletS, {PH1: url}) : i18nString(UIStrings.bidderWorklet);
|
792
|
+
|
793
|
+
case WorkletType.SellerWorklet:
|
794
|
+
return url ? i18nString(UIStrings.sellerWorkletS, {PH1: url}) : i18nString(UIStrings.sellerWorklet);
|
795
|
+
|
796
|
+
default:
|
797
|
+
return url ? i18nString(UIStrings.unknownWorkletS, {PH1: url}) : i18nString(UIStrings.unknownWorklet);
|
798
|
+
}
|
799
|
+
}
|
800
|
+
|
693
801
|
private processThreadEvents(
|
694
802
|
tracingModel: SDK.TracingModel.TracingModel, ranges: {
|
695
803
|
from: number,
|
696
804
|
to: number,
|
697
805
|
}[],
|
698
806
|
thread: SDK.TracingModel.Thread, isMainThread: boolean, isWorker: boolean, forMainFrame: boolean,
|
699
|
-
url: Platform.DevToolsPath.UrlString|null): void {
|
807
|
+
workletType: WorkletType, url: Platform.DevToolsPath.UrlString|null): void {
|
700
808
|
const track = new Track();
|
701
809
|
track.name = thread.name() || i18nString(UIStrings.threadS, {PH1: thread.id()});
|
702
810
|
track.type = TrackType.Other;
|
@@ -711,6 +819,9 @@ export class TimelineModelImpl {
|
|
711
819
|
track.name = track.url ? i18nString(UIStrings.workerS, {PH1: track.url}) : i18nString(UIStrings.dedicatedWorker);
|
712
820
|
} else if (thread.name().startsWith('CompositorTileWorker')) {
|
713
821
|
track.type = TrackType.Raster;
|
822
|
+
} else if (thread.name() === TimelineModelImpl.AuctionWorkletThreadName) {
|
823
|
+
track.url = url || Platform.DevToolsPath.EmptyUrlString;
|
824
|
+
track.name = TimelineModelImpl.nameAuctionWorklet(workletType, url);
|
714
825
|
}
|
715
826
|
this.tracksInternal.push(track);
|
716
827
|
|
@@ -1239,6 +1350,18 @@ export class TimelineModelImpl {
|
|
1239
1350
|
}
|
1240
1351
|
return;
|
1241
1352
|
}
|
1353
|
+
if (event.name === TimelineModelImpl.DevToolsMetadataEvent.AuctionWorkletRunningInProcess &&
|
1354
|
+
this.browserFrameTracking) {
|
1355
|
+
const worklet = new AuctionWorklet(event, data);
|
1356
|
+
this.auctionWorklets.set(data['target'], worklet);
|
1357
|
+
}
|
1358
|
+
if (event.name === TimelineModelImpl.DevToolsMetadataEvent.AuctionWorkletDoneWithProcess &&
|
1359
|
+
this.browserFrameTracking) {
|
1360
|
+
const worklet = this.auctionWorklets.get(data['target']);
|
1361
|
+
if (worklet) {
|
1362
|
+
worklet.endTime = event.startTime;
|
1363
|
+
}
|
1364
|
+
}
|
1242
1365
|
}
|
1243
1366
|
}
|
1244
1367
|
|
@@ -1290,6 +1413,7 @@ export class TimelineModelImpl {
|
|
1290
1413
|
this.cpuProfilesInternal = [];
|
1291
1414
|
this.workerIdByThread = new WeakMap();
|
1292
1415
|
this.pageFrames = new Map();
|
1416
|
+
this.auctionWorklets = new Map();
|
1293
1417
|
this.requestsFromBrowser = new Map();
|
1294
1418
|
|
1295
1419
|
this.minimumRecordTimeInternal = 0;
|
@@ -1576,6 +1700,7 @@ export namespace TimelineModelImpl {
|
|
1576
1700
|
export const WorkerThreadNameLegacy = 'DedicatedWorker Thread';
|
1577
1701
|
export const RendererMainThreadName = 'CrRendererMain';
|
1578
1702
|
export const BrowserMainThreadName = 'CrBrowserMain';
|
1703
|
+
export const AuctionWorkletThreadName = 'AuctionV8HelperThread';
|
1579
1704
|
|
1580
1705
|
export const DevToolsMetadataEvent = {
|
1581
1706
|
TracingStartedInBrowser: 'TracingStartedInBrowser',
|
@@ -1584,6 +1709,8 @@ export namespace TimelineModelImpl {
|
|
1584
1709
|
FrameCommittedInBrowser: 'FrameCommittedInBrowser',
|
1585
1710
|
ProcessReadyInBrowser: 'ProcessReadyInBrowser',
|
1586
1711
|
FrameDeletedInBrowser: 'FrameDeletedInBrowser',
|
1712
|
+
AuctionWorkletRunningInProcess: 'AuctionWorkletRunningInProcess',
|
1713
|
+
AuctionWorkletDoneWithProcess: 'AuctionWorkletDoneWithProcess',
|
1587
1714
|
};
|
1588
1715
|
|
1589
1716
|
export const Thresholds = {
|
@@ -1680,6 +1807,13 @@ export enum TrackType {
|
|
1680
1807
|
Other = 'Other',
|
1681
1808
|
}
|
1682
1809
|
|
1810
|
+
const enum WorkletType {
|
1811
|
+
NotWorklet = 0,
|
1812
|
+
BidderWorklet = 1,
|
1813
|
+
SellerWorklet = 2,
|
1814
|
+
UnknownWorklet = 3, // new type, or thread used for multiple ones.
|
1815
|
+
}
|
1816
|
+
|
1683
1817
|
export class PageFrame {
|
1684
1818
|
frameId: any;
|
1685
1819
|
url: any;
|
@@ -1734,6 +1868,29 @@ export class PageFrame {
|
|
1734
1868
|
}
|
1735
1869
|
}
|
1736
1870
|
|
1871
|
+
export class AuctionWorklet {
|
1872
|
+
targetId: string;
|
1873
|
+
processId: number;
|
1874
|
+
host?: string;
|
1875
|
+
startTime: number;
|
1876
|
+
endTime: number;
|
1877
|
+
workletType: WorkletType;
|
1878
|
+
constructor(event: SDK.TracingModel.Event, data: any) {
|
1879
|
+
this.targetId = (typeof data['target'] === 'string') ? data['target'] : '';
|
1880
|
+
this.processId = (typeof data['pid'] === 'number') ? data['pid'] : 0;
|
1881
|
+
this.host = (typeof data['host'] === 'string') ? data['host'] : undefined;
|
1882
|
+
this.startTime = event.startTime;
|
1883
|
+
this.endTime = Infinity;
|
1884
|
+
if (data['type'] === 'bidder') {
|
1885
|
+
this.workletType = WorkletType.BidderWorklet;
|
1886
|
+
} else if (data['type'] === 'seller') {
|
1887
|
+
this.workletType = WorkletType.SellerWorklet;
|
1888
|
+
} else {
|
1889
|
+
this.workletType = WorkletType.UnknownWorklet;
|
1890
|
+
}
|
1891
|
+
}
|
1892
|
+
}
|
1893
|
+
|
1737
1894
|
export class NetworkRequest {
|
1738
1895
|
startTime: number;
|
1739
1896
|
endTime: number;
|
@@ -408,6 +408,7 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
|
|
408
408
|
private readonly identitySection: UI.ReportView.Section;
|
409
409
|
private readonly presentationSection: UI.ReportView.Section;
|
410
410
|
private readonly iconsSection: UI.ReportView.Section;
|
411
|
+
private readonly protocolHandlersSection: UI.ReportView.Section;
|
411
412
|
private readonly shortcutSections: UI.ReportView.Section[];
|
412
413
|
private readonly screenshotsSections: UI.ReportView.Section[];
|
413
414
|
private nameField: HTMLElement;
|
@@ -455,9 +456,9 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
|
|
455
456
|
this.installabilitySection = this.reportView.appendSection(i18nString(UIStrings.installability));
|
456
457
|
this.identitySection = this.reportView.appendSection(i18nString(UIStrings.identity));
|
457
458
|
this.presentationSection = this.reportView.appendSection(i18nString(UIStrings.presentation));
|
458
|
-
|
459
|
+
this.protocolHandlersSection = this.reportView.appendSection(i18nString(UIStrings.protocolHandlers));
|
459
460
|
this.protocolHandlersView = new ApplicationComponents.ProtocolHandlersView.ProtocolHandlersView();
|
460
|
-
protocolHandlersSection.contentElement.append(this.protocolHandlersView);
|
461
|
+
this.protocolHandlersSection.contentElement.append(this.protocolHandlersView);
|
461
462
|
this.iconsSection = this.reportView.appendSection(i18nString(UIStrings.icons), 'report-section-icons');
|
462
463
|
this.shortcutSections = [];
|
463
464
|
this.screenshotsSections = [];
|
@@ -494,6 +495,14 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
|
|
494
495
|
this.registeredListeners = [];
|
495
496
|
}
|
496
497
|
|
498
|
+
getStaticSections(): UI.ReportView.Section[] {
|
499
|
+
return [this.identitySection, this.presentationSection, this.protocolHandlersSection, this.iconsSection];
|
500
|
+
}
|
501
|
+
|
502
|
+
getManifestElement(): Element {
|
503
|
+
return this.reportView.getHeaderElement();
|
504
|
+
}
|
505
|
+
|
497
506
|
targetAdded(target: SDK.Target.Target): void {
|
498
507
|
if (this.target) {
|
499
508
|
return;
|
@@ -559,10 +568,12 @@ export class AppManifestView extends UI.Widget.VBox implements SDK.TargetManager
|
|
559
568
|
if (!data && !errors.length) {
|
560
569
|
this.emptyView.showWidget();
|
561
570
|
this.reportView.hideWidget();
|
571
|
+
this.contentElement.dispatchEvent(new CustomEvent('manifestDetection', {detail: false}));
|
562
572
|
return;
|
563
573
|
}
|
564
574
|
this.emptyView.hideWidget();
|
565
575
|
this.reportView.showWidget();
|
576
|
+
this.contentElement.dispatchEvent(new CustomEvent('manifestDetection', {detail: true}));
|
566
577
|
|
567
578
|
const link = Components.Linkifier.Linkifier.linkifyURL(url);
|
568
579
|
link.tabIndex = 0;
|
@@ -170,6 +170,20 @@ const UIStrings = {
|
|
170
170
|
*@description Default name for worker
|
171
171
|
*/
|
172
172
|
worker: 'worker',
|
173
|
+
/**
|
174
|
+
* @description Aria text for screen reader to announce they can scroll to top of manifest if invoked
|
175
|
+
*/
|
176
|
+
onInvokeManifestAlert: 'Manifest: Invoke to scroll to the top of manifest',
|
177
|
+
/**
|
178
|
+
* @description Aria text for screen reader to announce they can scroll to a section if invoked
|
179
|
+
* @example {"Identity"} PH1
|
180
|
+
*/
|
181
|
+
beforeInvokeAlert: '{PH1}: Invoke to scroll to this section in manifest',
|
182
|
+
/**
|
183
|
+
* @description Alert message for screen reader to announce which subsection is being scrolled to
|
184
|
+
* @example {"Identity"} PH1
|
185
|
+
*/
|
186
|
+
onInvokeAlert: 'Scrolled to {PH1}',
|
173
187
|
};
|
174
188
|
const str_ = i18n.i18n.registerUIStrings('panels/application/ApplicationPanelSidebar.ts', UIStrings);
|
175
189
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
@@ -233,6 +247,7 @@ export class ApplicationPanelSidebar extends UI.Widget.VBox implements SDK.Targe
|
|
233
247
|
this.applicationTreeElement = this.addSidebarSection(applicationSectionTitle);
|
234
248
|
const manifestTreeElement = new AppManifestTreeElement(panel);
|
235
249
|
this.applicationTreeElement.appendChild(manifestTreeElement);
|
250
|
+
manifestTreeElement.generateChildren();
|
236
251
|
this.serviceWorkersTreeElement = new ServiceWorkersTreeElement(panel);
|
237
252
|
this.applicationTreeElement.appendChild(this.serviceWorkersTreeElement);
|
238
253
|
const clearStorageTreeElement = new ClearStorageTreeElement(panel);
|
@@ -930,11 +945,18 @@ export class ServiceWorkersTreeElement extends ApplicationPanelTreeElement {
|
|
930
945
|
}
|
931
946
|
|
932
947
|
export class AppManifestTreeElement extends ApplicationPanelTreeElement {
|
933
|
-
private view
|
948
|
+
private view: AppManifestView;
|
934
949
|
constructor(storagePanel: ResourcesPanel) {
|
935
|
-
super(storagePanel, i18nString(UIStrings.manifest),
|
950
|
+
super(storagePanel, i18nString(UIStrings.manifest), true);
|
936
951
|
const icon = UI.Icon.Icon.create('mediumicon-manifest', 'resource-tree-item');
|
937
952
|
this.setLeadingIcons([icon]);
|
953
|
+
self.onInvokeElement(this.listItemElement, this.onInvoke.bind(this));
|
954
|
+
this.view = new AppManifestView();
|
955
|
+
UI.ARIAUtils.setAccessibleName(this.listItemElement, i18nString(UIStrings.onInvokeManifestAlert));
|
956
|
+
const handleExpansion = (evt: Event): void => {
|
957
|
+
this.setExpandable((evt as CustomEvent).detail);
|
958
|
+
};
|
959
|
+
this.view.contentElement.addEventListener('manifestDetection', handleExpansion);
|
938
960
|
}
|
939
961
|
|
940
962
|
get itemURL(): Platform.DevToolsPath.UrlString {
|
@@ -943,13 +965,53 @@ export class AppManifestTreeElement extends ApplicationPanelTreeElement {
|
|
943
965
|
|
944
966
|
onselect(selectedByUser?: boolean): boolean {
|
945
967
|
super.onselect(selectedByUser);
|
946
|
-
if (!this.view) {
|
947
|
-
this.view = new AppManifestView();
|
948
|
-
}
|
949
968
|
this.showView(this.view);
|
950
969
|
Host.userMetrics.panelShown(Host.UserMetrics.PanelCodes[Host.UserMetrics.PanelCodes.app_manifest]);
|
951
970
|
return false;
|
952
971
|
}
|
972
|
+
|
973
|
+
generateChildren(): void {
|
974
|
+
const staticSections = this.view.getStaticSections();
|
975
|
+
for (const section of staticSections) {
|
976
|
+
const sectionElement = section.getTitleElement();
|
977
|
+
const childTitle = section.title();
|
978
|
+
const child = new ManifestChildTreeElement(this.resourcesPanel, sectionElement, childTitle);
|
979
|
+
this.appendChild(child);
|
980
|
+
}
|
981
|
+
}
|
982
|
+
|
983
|
+
onInvoke(): void {
|
984
|
+
this.view.getManifestElement().scrollIntoView();
|
985
|
+
UI.ARIAUtils.alert(i18nString(UIStrings.onInvokeAlert, {PH1: this.listItemElement.title}));
|
986
|
+
}
|
987
|
+
|
988
|
+
showManifestView(): void {
|
989
|
+
this.showView(this.view);
|
990
|
+
}
|
991
|
+
}
|
992
|
+
|
993
|
+
export class ManifestChildTreeElement extends ApplicationPanelTreeElement {
|
994
|
+
#sectionElement: Element;
|
995
|
+
constructor(storagePanel: ResourcesPanel, element: Element, childTitle: string) {
|
996
|
+
super(storagePanel, childTitle, false);
|
997
|
+
const icon = UI.Icon.Icon.create('mediumicon-manifest', 'resource-tree-item');
|
998
|
+
this.setLeadingIcons([icon]);
|
999
|
+
this.#sectionElement = element;
|
1000
|
+
self.onInvokeElement(this.listItemElement, this.onInvoke.bind(this));
|
1001
|
+
UI.ARIAUtils.setAccessibleName(
|
1002
|
+
this.listItemElement, i18nString(UIStrings.beforeInvokeAlert, {PH1: this.listItemElement.title}));
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
get itemURL(): Platform.DevToolsPath.UrlString {
|
1006
|
+
return 'manifest://' + this.title as Platform.DevToolsPath.UrlString;
|
1007
|
+
}
|
1008
|
+
|
1009
|
+
onInvoke(): void {
|
1010
|
+
(this.parent as AppManifestTreeElement)?.showManifestView();
|
1011
|
+
this.#sectionElement.scrollIntoView();
|
1012
|
+
UI.ARIAUtils.alert(i18nString(UIStrings.onInvokeAlert, {PH1: this.listItemElement.title}));
|
1013
|
+
Host.userMetrics.manifestSectionSelected(this.listItemElement.title);
|
1014
|
+
}
|
953
1015
|
}
|
954
1016
|
|
955
1017
|
export class ClearStorageTreeElement extends ApplicationPanelTreeElement {
|
@@ -35,10 +35,12 @@
|
|
35
35
|
import * as Common from '../../core/common/common.js';
|
36
36
|
import * as i18n from '../../core/i18n/i18n.js';
|
37
37
|
import * as SDK from '../../core/sdk/sdk.js';
|
38
|
+
import * as Adorners from '../../ui/components/adorners/adorners.js';
|
38
39
|
import * as CodeHighlighter from '../../ui/components/code_highlighter/code_highlighter.js';
|
40
|
+
import * as IconButton from '../../ui/components/icon_button/icon_button.js';
|
39
41
|
import * as UI from '../../ui/legacy/legacy.js';
|
40
42
|
|
41
|
-
import
|
43
|
+
import * as ElementsComponents from './components/components.js';
|
42
44
|
import {ElementsPanel} from './ElementsPanel.js';
|
43
45
|
import {ElementsTreeElement, InitialChildrenLimit} from './ElementsTreeElement.js';
|
44
46
|
import elementsTreeOutlineStyles from './elementsTreeOutline.css.js';
|
@@ -1629,13 +1631,45 @@ export class ShortcutTreeElement extends UI.TreeOutline.TreeElement {
|
|
1629
1631
|
text = '<' + text + '>';
|
1630
1632
|
}
|
1631
1633
|
title.textContent = '\u21AA ' + text;
|
1632
|
-
|
1633
|
-
const link = (linkifyDeferredNodeReference(nodeShortcut.deferredNode) as Element);
|
1634
|
-
UI.UIUtils.createTextChild(this.listItemElement, ' ');
|
1635
|
-
link.classList.add('elements-tree-shortcut-link');
|
1636
|
-
link.textContent = i18nString(UIStrings.reveal);
|
1637
|
-
this.listItemElement.appendChild(link);
|
1638
1634
|
this.nodeShortcut = nodeShortcut;
|
1635
|
+
this.addRevealAdorner();
|
1636
|
+
}
|
1637
|
+
|
1638
|
+
addRevealAdorner(): void {
|
1639
|
+
const adorner = new Adorners.Adorner.Adorner();
|
1640
|
+
adorner.classList.add('adorner-reveal');
|
1641
|
+
const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
|
1642
|
+
ElementsComponents.AdornerManager.RegisteredAdorners.REVEAL);
|
1643
|
+
const name = config.name;
|
1644
|
+
const adornerContent = document.createElement('span');
|
1645
|
+
const linkIcon = new IconButton.Icon.Icon();
|
1646
|
+
linkIcon
|
1647
|
+
.data = {iconName: 'ic_show_node_16x16', color: 'var(--color-text-disabled)', width: '12px', height: '12px'};
|
1648
|
+
const slotText = document.createElement('span');
|
1649
|
+
slotText.textContent = name;
|
1650
|
+
adornerContent.append(linkIcon);
|
1651
|
+
adornerContent.append(slotText);
|
1652
|
+
adornerContent.classList.add('adorner-with-icon');
|
1653
|
+
adorner.data = {
|
1654
|
+
name,
|
1655
|
+
content: adornerContent,
|
1656
|
+
};
|
1657
|
+
this.listItemElement.appendChild(adorner);
|
1658
|
+
const onClick = (((): void => {
|
1659
|
+
this.nodeShortcut.deferredNode.resolve(
|
1660
|
+
node => {
|
1661
|
+
void Common.Revealer.reveal(node);
|
1662
|
+
},
|
1663
|
+
);
|
1664
|
+
}) as EventListener);
|
1665
|
+
adorner.addInteraction(onClick, {
|
1666
|
+
isToggle: false,
|
1667
|
+
shouldPropagateOnKeydown: false,
|
1668
|
+
ariaLabelDefault: i18nString(UIStrings.reveal),
|
1669
|
+
ariaLabelActive: i18nString(UIStrings.reveal),
|
1670
|
+
});
|
1671
|
+
adorner.addEventListener('mousedown', e => e.consume(), false);
|
1672
|
+
ElementsPanel.instance().registerAdorner(adorner);
|
1639
1673
|
}
|
1640
1674
|
|
1641
1675
|
get hovered(): boolean {
|
@@ -3,6 +3,7 @@
|
|
3
3
|
// found in the LICENSE file.
|
4
4
|
import * as i18n from '../../core/i18n/i18n.js';
|
5
5
|
import * as SDK from '../../core/sdk/sdk.js';
|
6
|
+
import * as IconButton from '../../ui/components/icon_button/icon_button.js';
|
6
7
|
import * as UI from '../../ui/legacy/legacy.js';
|
7
8
|
|
8
9
|
import * as ElementsComponents from './components/components.js';
|
@@ -79,7 +80,14 @@ export class TopLayerContainer extends UI.TreeOutline.TreeElement {
|
|
79
80
|
const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
|
80
81
|
ElementsComponents.AdornerManager.RegisteredAdorners.TOP_LAYER);
|
81
82
|
const adornerContent = document.createElement('span');
|
82
|
-
adornerContent.
|
83
|
+
adornerContent.classList.add('adorner-with-icon');
|
84
|
+
const linkIcon = new IconButton.Icon.Icon();
|
85
|
+
linkIcon
|
86
|
+
.data = {iconName: 'ic_show_node_16x16', color: 'var(--color-text-disabled)', width: '12px', height: '12px'};
|
87
|
+
const adornerText = document.createElement('span');
|
88
|
+
adornerText.textContent = ` top-layer (${topLayerElementIndex}) `;
|
89
|
+
adornerContent.append(linkIcon);
|
90
|
+
adornerContent.append(adornerText);
|
83
91
|
const adorner = element?.adorn(config, adornerContent);
|
84
92
|
if (adorner) {
|
85
93
|
const onClick = (((): void => {
|
@@ -31,6 +31,7 @@ export enum RegisteredAdorners {
|
|
31
31
|
CONTAINER = 'container',
|
32
32
|
SLOT = 'slot',
|
33
33
|
TOP_LAYER = 'top-layer',
|
34
|
+
REVEAL = 'reveal',
|
34
35
|
}
|
35
36
|
|
36
37
|
// This enum-like const object serves as the authoritative registry for all the
|
@@ -79,6 +80,12 @@ export function getRegisteredAdorner(which: RegisteredAdorners): RegisteredAdorn
|
|
79
80
|
category: AdornerCategories.LAYOUT,
|
80
81
|
enabledByDefault: true,
|
81
82
|
};
|
83
|
+
case RegisteredAdorners.REVEAL:
|
84
|
+
return {
|
85
|
+
name: 'reveal',
|
86
|
+
category: AdornerCategories.DEFAULT,
|
87
|
+
enabledByDefault: true,
|
88
|
+
};
|
82
89
|
}
|
83
90
|
}
|
84
91
|
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
import * as acorn from './package/dist/acorn.mjs';
|
6
6
|
|
7
|
-
import type * as ESTree from './estree-legacy';
|
7
|
+
import type * as ESTree from './estree-legacy.js';
|
8
8
|
export {ESTree};
|
9
9
|
|
10
10
|
export { type Comment, defaultOptions, getLineInfo, isNewLine, lineBreak, lineBreakG, Node, SourceLocation, Token, tokTypes, tokContexts} from './package/dist/acorn.mjs';
|
@@ -5,10 +5,12 @@
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
6
6
|
|
7
7
|
declare global {
|
8
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
8
9
|
class diff_match_patch {
|
9
10
|
diff_main(text1: string, text2: string): Array<{0: number, 1: string}>;
|
10
11
|
diff_cleanupSemantic(diff: Array<{0: number, 1: string}>): void;
|
11
12
|
}
|
13
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
12
14
|
}
|
13
15
|
|
14
16
|
export const DiffWrapper = {
|
@@ -15,8 +15,12 @@ export class I18n {
|
|
15
15
|
readonly supportedLocales: ReadonlySet<Intl.UnicodeBCP47LocaleIdentifier>;
|
16
16
|
|
17
17
|
private localeData = new Map<Intl.UnicodeBCP47LocaleIdentifier, LocalizedMessages>();
|
18
|
+
readonly defaultLocale;
|
19
|
+
|
20
|
+
constructor(
|
21
|
+
supportedLocales: readonly Intl.UnicodeBCP47LocaleIdentifier[] = LOCALES, defaultLocale = DEFAULT_LOCALE) {
|
22
|
+
this.defaultLocale = defaultLocale;
|
18
23
|
|
19
|
-
constructor(supportedLocales: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier> = LOCALES, public readonly defaultLocale = DEFAULT_LOCALE) {
|
20
24
|
this.supportedLocales = new Set(supportedLocales);
|
21
25
|
}
|
22
26
|
|