chrome-devtools-frontend 1.0.963415 → 1.0.965113
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/config/gni/devtools_grd_files.gni +6 -0
- package/docs/resource_management.md +119 -0
- package/docs/workflows.md +7 -0
- package/front_end/core/i18n/locales/en-US.json +23 -2
- package/front_end/core/i18n/locales/en-XL.json +23 -2
- package/front_end/core/sdk/DOMModel.ts +2 -2
- package/front_end/generated/InspectorBackendCommands.js +8 -4
- package/front_end/generated/protocol-mapping.d.ts +12 -1
- package/front_end/generated/protocol-proxy-api.d.ts +11 -1
- package/front_end/generated/protocol.ts +27 -12
- package/front_end/models/javascript_metadata/NativeFunctions.js +7480 -4147
- package/front_end/models/workspace/UISourceCode.ts +4 -5
- package/front_end/panels/animation/AnimationUI.ts +2 -1
- package/front_end/panels/application/ApplicationPanelSidebar.ts +41 -1
- package/front_end/panels/application/InterestGroupStorageModel.ts +87 -0
- package/front_end/panels/application/InterestGroupStorageView.ts +112 -0
- package/front_end/panels/application/InterestGroupTreeElement.ts +61 -0
- package/front_end/panels/application/application.ts +4 -0
- package/front_end/panels/application/components/BackForwardCacheStrings.ts +1 -1
- package/front_end/panels/application/components/InterestGroupAccessGrid.ts +149 -0
- package/front_end/panels/application/components/components.ts +2 -0
- package/front_end/panels/application/components/interestGroupAccessGrid.css +26 -0
- package/front_end/panels/application/interestGroupStorageView.css +13 -0
- package/front_end/panels/elements/StylesSidebarPane.ts +6 -4
- package/front_end/panels/sources/UISourceCodeFrame.ts +7 -0
- package/front_end/ui/legacy/components/inline_editor/cssLength.css +1 -0
- package/front_end/ui/legacy/themeColors.css +1 -1
- package/package.json +1 -1
- package/scripts/build/devtools_plugin.js +103 -0
- package/scripts/build/ninja/{rollup.gni → bundle.gni} +2 -2
- package/scripts/build/ninja/devtools_entrypoint.gni +8 -8
- package/scripts/build/rollup.config.js +3 -93
- package/scripts/devtools_paths.js +3 -2
- package/scripts/javascript_natives/helpers.js +211 -0
- package/scripts/javascript_natives/index.js +57 -194
- package/scripts/javascript_natives/package.json +8 -3
- package/scripts/javascript_natives/test.d.ts +9 -0
- package/scripts/javascript_natives/tests.js +195 -0
- package/scripts/whitespaces.txt +1 -0
@@ -2,19 +2,20 @@
|
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
import * as fs from 'fs';
|
6
|
+
import glob from 'glob';
|
7
|
+
import * as path from 'path';
|
8
|
+
import ts from 'typescript';
|
9
|
+
import * as WebIDL2 from 'webidl2';
|
10
|
+
|
11
|
+
import {parseTSFunction, postProcess, walkRoot} from './helpers.js';
|
12
|
+
|
13
13
|
const program = ts.createProgram(
|
14
14
|
[
|
15
|
-
|
15
|
+
new URL('node_modules/typescript/lib/lib.esnext.d.ts', import.meta.url).pathname,
|
16
16
|
],
|
17
|
-
{noLib:
|
17
|
+
{noLib: false, types: []});
|
18
|
+
|
18
19
|
for (const file of program.getSourceFiles()) {
|
19
20
|
ts.forEachChild(file, node => {
|
20
21
|
if (node.kind === ts.SyntaxKind.InterfaceDeclaration) {
|
@@ -31,201 +32,63 @@ for (const file of program.getSourceFiles()) {
|
|
31
32
|
});
|
32
33
|
}
|
33
34
|
|
34
|
-
function parseTSFunction(func, node) {
|
35
|
-
if (!func.name.escapedText) {
|
36
|
-
return;
|
37
|
-
}
|
38
|
-
|
39
|
-
const args = func.parameters
|
40
|
-
.map(p => {
|
41
|
-
let text = p.name.escapedText;
|
42
|
-
if (p.questionToken) {
|
43
|
-
text = '?' + text;
|
44
|
-
}
|
45
|
-
if (p.dotDotDotToken) {
|
46
|
-
text = '...' + text;
|
47
|
-
}
|
48
|
-
return text;
|
49
|
-
})
|
50
|
-
.filter(x => x !== 'this');
|
51
|
-
storeMethod(node.name.text, func.name.escapedText, args);
|
52
|
-
}
|
53
|
-
|
54
35
|
// Assume the DevTools front-end repository is at
|
55
36
|
// `devtools/devtools-frontend`, where `devtools` is on the same level
|
56
37
|
// as `chromium`. This matches `scripts/npm_test.js`.
|
57
|
-
|
58
|
-
'../../../../chromium/src/third_party/blink/renderer/+(core|modules)/**/*.idl', {cwd: process.env.PWD}
|
59
|
-
function(er, files) {
|
60
|
-
for (const file of files) {
|
61
|
-
if (file.includes('testing')) {
|
62
|
-
continue;
|
63
|
-
}
|
64
|
-
const data = fs.readFileSync(path.join(process.env.PWD, file), 'utf8');
|
65
|
-
const lines = data.split('\n');
|
66
|
-
const newLines = [];
|
67
|
-
for (const line of lines) {
|
68
|
-
if (!line.includes(' attribute ')) {
|
69
|
-
newLines.push(line);
|
70
|
-
}
|
71
|
-
}
|
38
|
+
const files =
|
39
|
+
glob.sync('../../../../chromium/src/third_party/blink/renderer/+(core|modules)/**/*.idl', {cwd: process.env.PWD});
|
72
40
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
// console.error(file);
|
77
|
-
}
|
78
|
-
}
|
79
|
-
WebIDL2
|
80
|
-
.parse(`
|
81
|
-
namespace console {
|
82
|
-
void assert(optional boolean condition = false, any... data);
|
83
|
-
void clear();
|
84
|
-
void count(optional DOMString label = "default");
|
85
|
-
void debug(any... data);
|
86
|
-
void dir(any item, optional object? options);
|
87
|
-
void dirxml(any... data);
|
88
|
-
void error(any... data);
|
89
|
-
void group(any... data);
|
90
|
-
void groupCollapsed(any... data);
|
91
|
-
void groupEnd();
|
92
|
-
void info(any... data);
|
93
|
-
void log(any... data);
|
94
|
-
void profile(optional DOMString title);
|
95
|
-
void profileEnd(optional DOMString title);
|
96
|
-
void table(any... tabularData);
|
97
|
-
void time(optional DOMString label);
|
98
|
-
void timeEnd(optional DOMString label);
|
99
|
-
void timeStamp(optional DOMString name);
|
100
|
-
void trace(any... data);
|
101
|
-
void warn(any... data);
|
102
|
-
};
|
103
|
-
`).forEach(walk);
|
104
|
-
postProcess();
|
105
|
-
});
|
106
|
-
|
107
|
-
function walk(thing, parent) {
|
108
|
-
if (thing.type === 'interface') {
|
109
|
-
const constructor = thing.extAttrs.find(extAttr => extAttr.name === 'Constructor');
|
110
|
-
if (constructor && constructor.arguments && thing.extAttrs.find(extAttr => extAttr.name === 'Exposed')) {
|
111
|
-
storeMethod('Window', thing.name, constructor.arguments.map(argName));
|
112
|
-
}
|
113
|
-
|
114
|
-
const namedConstructor = thing.extAttrs.find(extAttr => extAttr.name === 'NamedConstructor');
|
115
|
-
if (namedConstructor && namedConstructor.arguments) {
|
116
|
-
storeMethod('Window', namedConstructor.rhs.value, namedConstructor.arguments.map(argName));
|
117
|
-
}
|
41
|
+
for (const file of files) {
|
42
|
+
if (file.includes('testing')) {
|
43
|
+
continue;
|
118
44
|
}
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
walk(member, thing);
|
45
|
+
const data = fs.readFileSync(path.join(process.env.PWD, file), 'utf8');
|
46
|
+
const lines = data.split('\n');
|
47
|
+
const newLines = [];
|
48
|
+
for (const line of lines) {
|
49
|
+
if (!line.includes(' attribute ')) {
|
50
|
+
newLines.push(line);
|
126
51
|
}
|
127
52
|
}
|
128
|
-
}
|
129
|
-
|
130
|
-
function argName(a) {
|
131
|
-
let name = a.name;
|
132
|
-
if (a.optional) {
|
133
|
-
name = '?' + name;
|
134
|
-
}
|
135
|
-
if (a.variadic) {
|
136
|
-
name = '...' + name;
|
137
|
-
}
|
138
|
-
return name;
|
139
|
-
}
|
140
53
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
if (!methods[name][parent]) {
|
146
|
-
methods[name][parent] = [];
|
54
|
+
try {
|
55
|
+
WebIDL2.parse(newLines.join('\n')).forEach(walkRoot);
|
56
|
+
} catch (e) {
|
57
|
+
// console.error(file);
|
147
58
|
}
|
148
|
-
methods[name][parent].push(args);
|
149
|
-
}
|
150
59
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
}
|
169
|
-
return '?' + arg;
|
170
|
-
}));
|
171
|
-
} else {
|
172
|
-
filteredSignatures.push(signature);
|
173
|
-
}
|
174
|
-
}
|
60
|
+
// Source for Console spec: https://console.spec.whatwg.org/#idl-index
|
61
|
+
WebIDL2
|
62
|
+
.parse(`
|
63
|
+
[Exposed=(Window,Worker,Worklet)]
|
64
|
+
namespace console { // but see namespace object requirements below
|
65
|
+
// Logging
|
66
|
+
undefined assert(optional boolean condition = false, any... data);
|
67
|
+
undefined clear();
|
68
|
+
undefined debug(any... data);
|
69
|
+
undefined error(any... data);
|
70
|
+
undefined info(any... data);
|
71
|
+
undefined log(any... data);
|
72
|
+
undefined table(optional any tabularData, optional sequence<DOMString> properties);
|
73
|
+
undefined trace(any... data);
|
74
|
+
undefined warn(any... data);
|
75
|
+
undefined dir(optional any item, optional object? options);
|
76
|
+
undefined dirxml(any... data);
|
175
77
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
if (withoutQuestion(smaller[i]) !== withoutQuestion(bigger[i])) {
|
180
|
-
return false;
|
181
|
-
}
|
182
|
-
}
|
183
|
-
return true;
|
184
|
-
}
|
78
|
+
// Counting
|
79
|
+
undefined count(optional DOMString label = "default");
|
80
|
+
undefined countReset(optional DOMString label = "default");
|
185
81
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
methods[name] = {'*': JSON.parse(jsonParents.values().next().value)};
|
191
|
-
}
|
192
|
-
for (const parent in methods[name]) {
|
193
|
-
const signatures = methods[name][parent];
|
194
|
-
if (signatures.length === 1 && !signatures[0].length) {
|
195
|
-
delete methods[name][parent];
|
196
|
-
}
|
197
|
-
}
|
198
|
-
if (!Object.keys(methods[name]).length) {
|
199
|
-
delete methods[name];
|
200
|
-
}
|
201
|
-
}
|
202
|
-
const functions = [];
|
203
|
-
for (const name in methods) {
|
204
|
-
if (methods[name]['*']) {
|
205
|
-
functions.push({name, signatures: methods[name]['*']});
|
206
|
-
} else {
|
207
|
-
for (const parent in methods[name]) {
|
208
|
-
if (parent.endsWith('Constructor')) {
|
209
|
-
functions.push({
|
210
|
-
name,
|
211
|
-
signatures: methods[name][parent],
|
212
|
-
static: true,
|
213
|
-
receiver: parent.substring(0, parent.length - 'Constructor'.length)
|
214
|
-
});
|
215
|
-
} else {
|
216
|
-
functions.push({name, signatures: methods[name][parent], receiver: parent});
|
217
|
-
}
|
218
|
-
}
|
219
|
-
}
|
220
|
-
}
|
82
|
+
// Grouping
|
83
|
+
undefined group(any... data);
|
84
|
+
undefined groupCollapsed(any... data);
|
85
|
+
undefined groupEnd();
|
221
86
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
export const NativeFunctions = ${JSON.stringify(functions, null, 2)};
|
230
|
-
`);
|
87
|
+
// Timing
|
88
|
+
undefined time(optional DOMString label = "default");
|
89
|
+
undefined timeLog(optional DOMString label = "default", any... data);
|
90
|
+
undefined timeEnd(optional DOMString label = "default");
|
91
|
+
};
|
92
|
+
`).forEach(walkRoot);
|
231
93
|
}
|
94
|
+
postProcess();
|
@@ -1,11 +1,16 @@
|
|
1
1
|
{
|
2
|
+
"private": true,
|
2
3
|
"main": "index.js",
|
3
4
|
"scripts": {
|
4
|
-
"start": "node index.js"
|
5
|
+
"start": "node index.js",
|
6
|
+
"test": "mocha tests.js"
|
5
7
|
},
|
8
|
+
"type": "module",
|
6
9
|
"dependencies": {
|
10
|
+
"@types/webidl2": "^23.13.6",
|
7
11
|
"glob": "^7.1.2",
|
8
|
-
"
|
9
|
-
"
|
12
|
+
"mocha": "^9.1.4",
|
13
|
+
"typescript": "latest",
|
14
|
+
"webidl2": "^24.2.0"
|
10
15
|
}
|
11
16
|
}
|
@@ -0,0 +1,195 @@
|
|
1
|
+
// Copyright 2022 The Chromium Authors. All rights reserved.
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
3
|
+
// found in the LICENSE file.
|
4
|
+
|
5
|
+
import * as assert from 'assert';
|
6
|
+
import ts from 'typescript';
|
7
|
+
import * as WebIDL2 from 'webidl2';
|
8
|
+
|
9
|
+
import {clearState, parseTSFunction, postProcess, walkRoot} from './helpers.js';
|
10
|
+
|
11
|
+
describe('NativeFunction signature generation', function() {
|
12
|
+
this.afterEach(() => {
|
13
|
+
clearState();
|
14
|
+
});
|
15
|
+
|
16
|
+
it('should produce correct signatures for IDL interface', function() {
|
17
|
+
WebIDL2
|
18
|
+
.parse(`
|
19
|
+
[
|
20
|
+
Exposed=Window
|
21
|
+
] interface Document : Node {
|
22
|
+
[CallWith=Document] constructor();
|
23
|
+
[Affects=Nothing] HTMLCollection getElementsByTagName(DOMString localName);
|
24
|
+
[Affects=Nothing] HTMLCollection getElementsByTagNameNS(DOMString? namespaceURI, DOMString localName);
|
25
|
+
[Affects=Nothing] HTMLCollection getElementsByClassName(DOMString classNames);
|
26
|
+
|
27
|
+
[NewObject, DoNotTestNewObject, PerWorldBindings, RaisesException, ImplementedAs=CreateElementForBinding] Element createElement(DOMString localName);
|
28
|
+
[NewObject, DoNotTestNewObject, RaisesException] Element createElementNS(DOMString? namespaceURI, DOMString qualifiedName);
|
29
|
+
[NewObject] DocumentFragment createDocumentFragment();
|
30
|
+
[NewObject] Text createTextNode(DOMString data);
|
31
|
+
};
|
32
|
+
`).forEach(walkRoot);
|
33
|
+
const output = postProcess(/* dryRun: */ true);
|
34
|
+
const expected = `export const NativeFunctions = [
|
35
|
+
{
|
36
|
+
name: "getElementsByTagName",
|
37
|
+
signatures: [["localName"]]
|
38
|
+
},
|
39
|
+
{
|
40
|
+
name: "getElementsByTagNameNS",
|
41
|
+
signatures: [["namespaceURI","localName"]]
|
42
|
+
},
|
43
|
+
{
|
44
|
+
name: "getElementsByClassName",
|
45
|
+
signatures: [["classNames"]]
|
46
|
+
},
|
47
|
+
{
|
48
|
+
name: "createElement",
|
49
|
+
signatures: [["localName"]]
|
50
|
+
},
|
51
|
+
{
|
52
|
+
name: "createElementNS",
|
53
|
+
signatures: [["namespaceURI","qualifiedName"]]
|
54
|
+
},
|
55
|
+
{
|
56
|
+
name: "createTextNode",
|
57
|
+
signatures: [["data"]]
|
58
|
+
}
|
59
|
+
];`;
|
60
|
+
assert.equal(output, expected);
|
61
|
+
});
|
62
|
+
|
63
|
+
it('should produce correct signatures for IDL mixin interface', function() {
|
64
|
+
WebIDL2
|
65
|
+
.parse(`[
|
66
|
+
LegacyTreatAsPartialInterface,
|
67
|
+
Exposed=(Window,Worker)
|
68
|
+
] interface mixin WindowOrWorkerGlobalScope {
|
69
|
+
[CallWith=ScriptState] void reportError(any e);
|
70
|
+
|
71
|
+
[RaisesException] DOMString atob(DOMString atob);
|
72
|
+
[CallWith=ScriptState, RuntimeCallStatsCounter=WindowSetTimeout] long setTimeout(Function handler, optional long timeout = 0, any... arguments);
|
73
|
+
[CallWith=ScriptState] long setTimeout(ScriptString handler, optional long timeout = 0, any... arguments);
|
74
|
+
};
|
75
|
+
`).forEach(walkRoot);
|
76
|
+
const output = postProcess(/* dryRun: */ true);
|
77
|
+
const expected = `export const NativeFunctions = [
|
78
|
+
{
|
79
|
+
name: "reportError",
|
80
|
+
signatures: [["e"]]
|
81
|
+
},
|
82
|
+
{
|
83
|
+
name: "atob",
|
84
|
+
signatures: [["atob"]]
|
85
|
+
},
|
86
|
+
{
|
87
|
+
name: "setTimeout",
|
88
|
+
signatures: [["handler","?timeout","...arguments"]]
|
89
|
+
}
|
90
|
+
];`;
|
91
|
+
assert.equal(output, expected);
|
92
|
+
});
|
93
|
+
|
94
|
+
it('should produce correct signatures for Console IDL', function() {
|
95
|
+
WebIDL2
|
96
|
+
.parse(`
|
97
|
+
[Exposed=(Window,Worker,Worklet)]
|
98
|
+
namespace console {
|
99
|
+
undefined assert(optional boolean condition = false, any... data);
|
100
|
+
undefined table(optional any tabularData, optional sequence<DOMString> properties);
|
101
|
+
undefined count(optional DOMString label = "default");
|
102
|
+
undefined groupEnd();
|
103
|
+
};
|
104
|
+
`).forEach(walkRoot);
|
105
|
+
const output = postProcess(/* dryRun: */ true);
|
106
|
+
const expected = `export const NativeFunctions = [
|
107
|
+
{
|
108
|
+
name: "assert",
|
109
|
+
signatures: [["?condition","...data"]]
|
110
|
+
},
|
111
|
+
{
|
112
|
+
name: "table",
|
113
|
+
signatures: [["?tabularData","?properties"]]
|
114
|
+
},
|
115
|
+
{
|
116
|
+
name: "count",
|
117
|
+
signatures: [["?label"]]
|
118
|
+
}
|
119
|
+
];`;
|
120
|
+
assert.equal(output, expected);
|
121
|
+
});
|
122
|
+
|
123
|
+
it('should produce correct signatures for Console IDL', function() {
|
124
|
+
WebIDL2
|
125
|
+
.parse(`
|
126
|
+
// https://html.spec.whatwg.org/C/#the-slot-element
|
127
|
+
[
|
128
|
+
Exposed=Window,
|
129
|
+
HTMLConstructor
|
130
|
+
] interface HTMLSlotElement : HTMLElement {
|
131
|
+
[CEReactions, Reflect] attribute DOMString name;
|
132
|
+
[ImplementedAs=AssignedNodesForBinding] sequence<Node> assignedNodes(optional AssignedNodesOptions options = {});
|
133
|
+
[ImplementedAs=AssignedElementsForBinding] sequence<Element> assignedElements(optional AssignedNodesOptions options = {});
|
134
|
+
[RaisesException] void assign((Element or Text)... nodes);
|
135
|
+
};
|
136
|
+
`).forEach(walkRoot);
|
137
|
+
const output = postProcess(/* dryRun: */ true);
|
138
|
+
const expected = `export const NativeFunctions = [
|
139
|
+
{
|
140
|
+
name: "assignedNodes",
|
141
|
+
signatures: [["?options"]]
|
142
|
+
},
|
143
|
+
{
|
144
|
+
name: "assignedElements",
|
145
|
+
signatures: [["?options"]]
|
146
|
+
},
|
147
|
+
{
|
148
|
+
name: "assign",
|
149
|
+
signatures: [["...nodes"]]
|
150
|
+
}
|
151
|
+
];`;
|
152
|
+
assert.equal(output, expected);
|
153
|
+
});
|
154
|
+
|
155
|
+
it('should produce correct signatures for typescript typings', function() {
|
156
|
+
const program = ts.createProgram(
|
157
|
+
[
|
158
|
+
new URL('test.d.ts', import.meta.url).pathname,
|
159
|
+
],
|
160
|
+
{noLib: true, types: []});
|
161
|
+
|
162
|
+
for (const file of program.getSourceFiles()) {
|
163
|
+
ts.forEachChild(file, node => {
|
164
|
+
if (node.kind === ts.SyntaxKind.InterfaceDeclaration) {
|
165
|
+
for (const member of node.members) {
|
166
|
+
if (member.kind === ts.SyntaxKind.MethodSignature) {
|
167
|
+
parseTSFunction(member, node);
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
if (node.kind === ts.SyntaxKind.FunctionDeclaration) {
|
172
|
+
parseTSFunction(node, {name: {text: 'Window'}});
|
173
|
+
}
|
174
|
+
});
|
175
|
+
}
|
176
|
+
const output = postProcess(/* dryRun: */ true);
|
177
|
+
const expected = `export const NativeFunctions = [
|
178
|
+
{
|
179
|
+
name: "at",
|
180
|
+
signatures: [["index"]]
|
181
|
+
},
|
182
|
+
{
|
183
|
+
name: "diffSig",
|
184
|
+
signatures: [["oneSig"]],
|
185
|
+
receiver: "Array"
|
186
|
+
},
|
187
|
+
{
|
188
|
+
name: "diffSig",
|
189
|
+
signatures: [["twoSig"]],
|
190
|
+
receiver: "ReadonlyArray"
|
191
|
+
}
|
192
|
+
];`;
|
193
|
+
assert.equal(output, expected);
|
194
|
+
});
|
195
|
+
});
|
package/scripts/whitespaces.txt
CHANGED