chrome-devtools-frontend 1.0.962581 → 1.0.964938

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/AUTHORS +1 -0
  2. package/config/gni/devtools_grd_files.gni +6 -0
  3. package/docs/resource_management.md +119 -0
  4. package/docs/workflows.md +7 -0
  5. package/front_end/core/common/ParsedURL.ts +12 -10
  6. package/front_end/core/host/UserMetrics.ts +2 -1
  7. package/front_end/core/i18n/locales/en-US.json +23 -2
  8. package/front_end/core/i18n/locales/en-XL.json +23 -2
  9. package/front_end/core/root/Runtime.ts +2 -0
  10. package/front_end/core/sdk/DOMModel.ts +2 -2
  11. package/front_end/core/sdk/DebuggerModel.ts +1 -1
  12. package/front_end/entrypoints/main/MainImpl.ts +7 -2
  13. package/front_end/generated/InspectorBackendCommands.js +8 -4
  14. package/front_end/generated/protocol-mapping.d.ts +12 -1
  15. package/front_end/generated/protocol-proxy-api.d.ts +11 -1
  16. package/front_end/generated/protocol.ts +27 -12
  17. package/front_end/models/javascript_metadata/NativeFunctions.js +7480 -4147
  18. package/front_end/models/persistence/IsolatedFileSystem.ts +3 -2
  19. package/front_end/models/persistence/PersistenceActions.ts +2 -2
  20. package/front_end/models/workspace/UISourceCode.ts +4 -5
  21. package/front_end/panels/animation/AnimationUI.ts +2 -1
  22. package/front_end/panels/application/AppManifestView.ts +7 -1
  23. package/front_end/panels/application/ApplicationPanelSidebar.ts +41 -1
  24. package/front_end/panels/application/InterestGroupStorageModel.ts +87 -0
  25. package/front_end/panels/application/InterestGroupStorageView.ts +112 -0
  26. package/front_end/panels/application/InterestGroupTreeElement.ts +61 -0
  27. package/front_end/panels/application/application.ts +4 -0
  28. package/front_end/panels/application/components/BackForwardCacheStrings.ts +1 -1
  29. package/front_end/panels/application/components/FrameDetailsView.ts +1 -0
  30. package/front_end/panels/application/components/InterestGroupAccessGrid.ts +149 -0
  31. package/front_end/panels/application/components/components.ts +2 -0
  32. package/front_end/panels/application/components/interestGroupAccessGrid.css +26 -0
  33. package/front_end/panels/application/interestGroupStorageView.css +13 -0
  34. package/front_end/panels/elements/StylePropertyTreeElement.ts +13 -0
  35. package/front_end/panels/elements/StylesSidebarPane.ts +73 -4
  36. package/front_end/panels/elements/stylesSectionTree.css +28 -0
  37. package/front_end/panels/media/PlayerListView.ts +2 -0
  38. package/front_end/panels/media/playerListView.css +3 -0
  39. package/front_end/panels/sensors/sensors-meta.ts +2 -2
  40. package/front_end/panels/sources/NavigatorView.ts +1 -1
  41. package/front_end/panels/sources/UISourceCodeFrame.ts +7 -0
  42. package/front_end/ui/components/diff_view/DiffView.ts +2 -2
  43. package/front_end/ui/components/docs/icon_button/basic.ts +1 -1
  44. package/front_end/ui/components/icon_button/IconButton.ts +1 -1
  45. package/front_end/ui/legacy/GlassPane.ts +2 -0
  46. package/front_end/ui/legacy/components/inline_editor/cssLength.css +1 -0
  47. package/front_end/ui/legacy/softDropDownButton.css +2 -0
  48. package/front_end/ui/legacy/themeColors.css +3 -1
  49. package/front_end/ui/legacy/toolbar.css +6 -0
  50. package/package.json +1 -1
  51. package/scripts/build/devtools_plugin.js +103 -0
  52. package/scripts/build/ninja/{rollup.gni → bundle.gni} +2 -2
  53. package/scripts/build/ninja/devtools_entrypoint.gni +8 -8
  54. package/scripts/build/rollup.config.js +3 -93
  55. package/scripts/devtools_paths.js +3 -2
  56. package/scripts/javascript_natives/helpers.js +211 -0
  57. package/scripts/javascript_natives/index.js +57 -194
  58. package/scripts/javascript_natives/package.json +8 -3
  59. package/scripts/javascript_natives/test.d.ts +9 -0
  60. package/scripts/javascript_natives/tests.js +195 -0
  61. package/scripts/whitespaces.txt +1 -0
@@ -5,41 +5,10 @@
5
5
  // @ts-check
6
6
 
7
7
  import {defaultStrategy} from 'minify-html-literals/src/strategy'; // eslint-disable-line rulesdir/es_modules_import
8
- import * as path from 'path';
9
8
  import minifyHTML from 'rollup-plugin-minify-html-template-literals';
10
9
  import {terser} from 'rollup-plugin-terser';
11
10
 
12
- /**
13
- * `path.dirname` does not include trailing slashes. If we would always
14
- * use `path.dirname` and then later perform comparisons on the paths that
15
- * it returns, we could run into false positives. For example, given the
16
- * the following two paths:
17
- *
18
- * front_end/timeline_model/TimelineModel.js
19
- * front_end/timeline/Timeline.js
20
- *
21
- * And that would have the following values for `path.dirname`:
22
- *
23
- * front_end/timeline_model
24
- * front_end/timeline
25
- *
26
- * If we would do a simple `.startswith` on the `path.dirname` of both of
27
- * these paths, then the first path would start with the dirname of the
28
- * second. However, they *are* part of different folders. To fix that problem,
29
- * we need to force a path separator after each folder. That makes sure we
30
- * and up with the following comparison of path dirnames:
31
- *
32
- * front_end/timeline_model/
33
- * front_end/timeline/
34
- *
35
- * Now, the first path does *not* start with the second one, as expected.
36
- *
37
- * @param {string} file
38
- * @return {string}
39
- */
40
- function dirnameWithSeparator(file) {
41
- return path.dirname(file) + path.sep;
42
- }
11
+ const devtools_plugin = require('./devtools_plugin.js');
43
12
 
44
13
  /**
45
14
  * @type {import("minify-html-literals").Strategy<import("html-minifier").Options, unknown>}
@@ -91,67 +60,8 @@ export default commandLineArgs => ({
91
60
  {
92
61
  name: 'devtools-plugin',
93
62
  resolveId(source, importer) {
94
- if (!importer) {
95
- return null;
96
- }
97
- const currentDirectory = path.normalize(dirnameWithSeparator(importer));
98
- const importedFilelocation = path.normalize(path.join(currentDirectory, source));
99
- const importedFileDirectory = dirnameWithSeparator(importedFilelocation);
100
-
101
- // Generated files are part of other directories, as they are only imported once
102
- if (path.basename(importedFileDirectory) === 'generated') {
103
- return null;
104
- }
105
-
106
- // An import is considered external (and therefore a separate
107
- // bundle) if its filename matches its immediate parent's folder
108
- // name (without the extension). For example:
109
- // import * as Components from './components/components.js' = external
110
- // import * as UI from '../ui/ui.js' = external
111
- // import * as LitHtml from '../third_party/lit-html/lit-html.js' = external
112
- // import {DataGrid} from './components/DataGrid.js' = not external
113
- // import * as Components from './components/foo.js' = not external
114
-
115
- // Note that we can't do a simple check for only `third_party`, as in Chromium
116
- // our full path is `third_party/devtools-frontend/src/`, which thus *always*
117
- // includes third_party. It also not possible to use the current directory
118
- // as a check for the import, as the import will be different in Chromium and
119
- // would therefore not match the path of `__dirname`.
120
- // These should be removed because the new heuristic _should_ deal with these
121
- // e.g. it'll pick up third_party/lit-html/lit-html.js is its own entrypoint
122
-
123
- // Puppeteer has dynamic imports in its build gated on an ifNode
124
- // flag, but our Rollup config doesn't know about that and tries
125
- // to parse dynamic import('fs'). Let's ignore Puppeteer for now.
126
- // The long term plan is probably for Puppeteer to ship a web
127
- // bundle anyway. See go/pptr-agnostify for details.
128
- if (importedFileDirectory.includes(path.join('front_end', 'third_party', 'puppeteer'))) {
129
- return null;
130
- }
131
-
132
- // The CodeMirror addons look like bundles (addon/comment/comment.js) but are not.
133
- if (importedFileDirectory.includes(path.join('front_end', 'third_party', 'codemirror', 'package'))) {
134
- return null;
135
- }
136
-
137
- // The LightHouse bundle shouldn't be processed by `terser` again, as it is uniquely built
138
- if (importedFilelocation.includes(
139
- path.join('front_end', 'third_party', 'lighthouse', 'lighthouse-dt-bundle.js'))) {
140
- return {
141
- id: importedFilelocation,
142
- external: true,
143
- };
144
- }
145
-
146
- const importedFileName = path.basename(importedFilelocation, '.js');
147
- const importedFileParentDirectory = path.basename(path.dirname(importedFilelocation));
148
- const isExternal = importedFileName === importedFileParentDirectory;
149
-
150
- return {
151
- id: importedFilelocation,
152
- external: isExternal,
153
- };
154
- }
63
+ return devtools_plugin.devtoolsPlugin(source, importer);
64
+ },
155
65
  },
156
66
  ]
157
67
  });
@@ -59,8 +59,9 @@ function isInChromiumDirectory() {
59
59
  }
60
60
 
61
61
  const normalizedPath = PATH_TO_EXECUTED_FILE.split(path.sep).join('/');
62
- const isInChromium = normalizedPath.includes('chromium/src/third_party/devtools-frontend');
63
- const potentialChromiumDir = PATH_TO_EXECUTED_FILE.substring(0, PATH_TO_EXECUTED_FILE.indexOf('chromium') + 8);
62
+ const devtoolsPath = 'src/third_party/devtools-frontend';
63
+ const isInChromium = normalizedPath.includes(devtoolsPath);
64
+ const potentialChromiumDir = PATH_TO_EXECUTED_FILE.substring(0, PATH_TO_EXECUTED_FILE.indexOf(devtoolsPath));
64
65
  const result = {isInChromium, chromiumDirectory: potentialChromiumDir};
65
66
  _lookUpCaches.set('chromium', result);
66
67
  return result;
@@ -0,0 +1,211 @@
1
+ // Copyright 2021 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
+ // @ts-check
6
+
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import {fileURLToPath} from 'url';
10
+
11
+ /** @type {Map<string, Map<string, string[][]>>} */
12
+ const methods = new Map();
13
+
14
+ export function clearState() {
15
+ methods.clear();
16
+ }
17
+
18
+ export function parseTSFunction(func, node) {
19
+ if (!func.name.escapedText) {
20
+ return;
21
+ }
22
+
23
+ const args = func.parameters
24
+ .map(p => {
25
+ let text = p.name.escapedText;
26
+ if (p.questionToken) {
27
+ text = '?' + text;
28
+ }
29
+ if (p.dotDotDotToken) {
30
+ text = '...' + text;
31
+ }
32
+ return text;
33
+ })
34
+ .filter(x => x !== 'this');
35
+ storeMethod(node.name.text, func.name.escapedText, args);
36
+ }
37
+
38
+ /**
39
+ * @param {WebIDL2.IDLRootType} thing
40
+ * */
41
+ export function walkRoot(thing) {
42
+ switch (thing.type) {
43
+ case 'interface':
44
+ walkInterface(thing);
45
+ break;
46
+ case 'interface mixin':
47
+ case 'namespace':
48
+ walkMembers(thing);
49
+ break;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * @param {WebIDL2.InterfaceType} thing
55
+ * */
56
+ function walkInterface(thing) {
57
+ thing.members.forEach(member => {
58
+ switch (member.type) {
59
+ case 'constructor':
60
+ storeMethod('Window', thing.name, member.arguments.map(argName));
61
+ break;
62
+ case 'operation':
63
+ handleOperation(member);
64
+ }
65
+ });
66
+ const namedConstructor = thing.extAttrs.find(extAttr => extAttr.name === 'NamedConstructor');
67
+ if (namedConstructor && namedConstructor.arguments) {
68
+ storeMethod('Window', namedConstructor.rhs.value, namedConstructor.arguments.map(argName));
69
+ }
70
+ }
71
+
72
+ /**
73
+ * @param {WebIDL2.NamespaceType | WebIDL2.InterfaceMixinType} thing
74
+ * */
75
+ function walkMembers(thing) {
76
+ thing.members.forEach(member => {
77
+ if (member.type === 'operation') {
78
+ handleOperation(member);
79
+ }
80
+ });
81
+ }
82
+
83
+ /**
84
+ * @param {WebIDL2.OperationMemberType} member
85
+ * */
86
+ function handleOperation(member) {
87
+ storeMethod(
88
+ member.special === 'static' ? (parent.name + 'Constructor') : member.parent.name, member.name,
89
+ member.arguments.map(argName));
90
+ }
91
+
92
+ /**
93
+ * @param {WebIDL2.Argument} a
94
+ * */
95
+ function argName(a) {
96
+ let name = a.name;
97
+ if (a.optional) {
98
+ name = '?' + name;
99
+ }
100
+ if (a.variadic) {
101
+ name = '...' + name;
102
+ }
103
+ return name;
104
+ }
105
+
106
+ /**
107
+ * @param {string} parent
108
+ * @param {string} name
109
+ * @param {Array<string>} args
110
+ * */
111
+ function storeMethod(parent, name, args) {
112
+ if (!methods.has(name)) {
113
+ methods.set(name, new Map());
114
+ }
115
+ const method = methods.get(name);
116
+ if (!method.has(parent)) {
117
+ method.set(parent, []);
118
+ }
119
+ method.get(parent).push(args);
120
+ }
121
+
122
+ export function postProcess(dryRun = false) {
123
+ for (const name of methods.keys()) {
124
+ // We use the set jsonParents to track the set of different signatures across parent for this function name.
125
+ // If all signatures are identical, we leave out the parent and emit a single NativeFunction entry without receiver.
126
+ const jsonParents = new Set();
127
+ for (const [parent, signatures] of methods.get(name)) {
128
+ signatures.sort((a, b) => a.length - b.length);
129
+ const filteredSignatures = [];
130
+ for (const signature of signatures) {
131
+ const smallerIndex = filteredSignatures.findIndex(smaller => startsTheSame(smaller, signature));
132
+ if (smallerIndex !== -1) {
133
+ filteredSignatures[smallerIndex] = (signature.map((arg, index) => {
134
+ const otherArg = filteredSignatures[smallerIndex][index];
135
+ if (otherArg) {
136
+ return otherArg.length > arg.length ? otherArg : arg;
137
+ }
138
+ if (arg.startsWith('?') || arg.startsWith('...')) {
139
+ return arg;
140
+ }
141
+ return '?' + arg;
142
+ }));
143
+ } else {
144
+ filteredSignatures.push(signature);
145
+ }
146
+ }
147
+
148
+ function startsTheSame(smaller, bigger) {
149
+ for (let i = 0; i < smaller.length; i++) {
150
+ const withoutQuestion = str => /[\?]?(.*)/.exec(str)[1];
151
+ if (withoutQuestion(smaller[i]) !== withoutQuestion(bigger[i])) {
152
+ return false;
153
+ }
154
+ }
155
+ return true;
156
+ }
157
+
158
+ methods.get(name).set(parent, filteredSignatures);
159
+ jsonParents.add(JSON.stringify(filteredSignatures));
160
+ }
161
+ // If all parents had the same signature for this name, we put a `*` as parent for this entry.
162
+ if (jsonParents.size === 1) {
163
+ methods.set(name, new Map([['*', JSON.parse(jsonParents.values().next().value)]]));
164
+ }
165
+ for (const [parent, signatures] of methods.get(name)) {
166
+ if (signatures.length === 1 && !signatures[0].length) {
167
+ methods.get(name).delete(parent);
168
+ }
169
+ }
170
+ if (methods.get(name).size === 0) {
171
+ methods.delete(name);
172
+ }
173
+ }
174
+ const functions = [];
175
+ for (const [name, method] of methods) {
176
+ if (method.has('*')) {
177
+ // All parents had the same signature so we emit an entry without receiver.
178
+ functions.push({name, signatures: method.get('*')});
179
+ } else {
180
+ for (const [parent, signatures] of method) {
181
+ if (parent.endsWith('Constructor')) {
182
+ functions.push(
183
+ {name, signatures, static: true, receiver: parent.substring(0, parent.length - 'Constructor'.length)});
184
+ } else {
185
+ functions.push({name, signatures, receiver: parent});
186
+ }
187
+ }
188
+ }
189
+ }
190
+ const output = `export const NativeFunctions = [\n${
191
+ functions
192
+ .map(
193
+ entry =>
194
+ ` {\n${Object.entries(entry).map(kv => ` ${kv[0]}: ${JSON.stringify(kv[1])}`).join(',\n')}\n }`)
195
+ .join(',\n')}\n];`;
196
+
197
+ if (dryRun) {
198
+ return output;
199
+ }
200
+
201
+ fs.writeFileSync(
202
+ (new URL('../../front_end/models/javascript_metadata/NativeFunctions.js', import.meta.url)).pathname,
203
+ `// Copyright 2020 The Chromium Authors. All rights reserved.
204
+ // Use of this source code is governed by a BSD-style license that can be
205
+ // found in the LICENSE file.
206
+ // Generated from ${
207
+ path.relative(path.join(fileURLToPath(import.meta.url), '..', '..'), fileURLToPath(import.meta.url))}
208
+
209
+ ${output}
210
+ `);
211
+ }
@@ -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
- const WebIDL2 = require('webidl2');
6
- const fs = require('fs');
7
- const path = require('path');
8
- const ts = require('typescript');
9
- const glob = require('glob');
10
- const methods = {
11
- __proto__: null
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
- path.join(__dirname, 'node_modules', 'typescript', 'lib', 'lib.esnext.d.ts'),
15
+ new URL('node_modules/typescript/lib/lib.esnext.d.ts', import.meta.url).pathname,
16
16
  ],
17
- {noLib: true});
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
- glob(
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
- try {
74
- WebIDL2.parse(newLines.join('\n')).forEach(walk);
75
- } catch (e) {
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
- if (thing.type.includes('operation')) {
120
- storeMethod(thing.static ? (parent.name + 'Constructor') : parent.name, thing.name, thing.arguments.map(argName));
121
- return;
122
- }
123
- if (thing.members) {
124
- for (const member of thing.members) {
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
- function storeMethod(parent, name, args) {
142
- if (!methods[name]) {
143
- methods[name] = {__proto__: null};
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
- function postProcess() {
152
- for (const name in methods) {
153
- const jsonParents = new Set();
154
- for (const parent in methods[name]) {
155
- const signatures = methods[name][parent];
156
- signatures.sort((a, b) => a.length - b.length);
157
- const filteredSignatures = [];
158
- for (const signature of signatures) {
159
- const smallerIndex = filteredSignatures.findIndex(smaller => startsThesame(smaller, signature));
160
- if (smallerIndex !== -1) {
161
- filteredSignatures[smallerIndex] = (signature.map((arg, index) => {
162
- const otherArg = filteredSignatures[smallerIndex][index];
163
- if (otherArg) {
164
- return otherArg.length > arg.length ? otherArg : arg;
165
- }
166
- if (arg.startsWith('?') || arg.startsWith('...')) {
167
- return arg;
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
- function startsThesame(smaller, bigger) {
177
- for (let i = 0; i < smaller.length; i++) {
178
- const withoutQuestion = str => /[\?]?(.*)/.exec(str)[1];
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
- methods[name][parent] = filteredSignatures;
187
- jsonParents.add(JSON.stringify(filteredSignatures));
188
- }
189
- if (jsonParents.size === 1) {
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
- fs.writeFileSync(
223
- path.join(__dirname, '..', '..', 'front_end', 'models', 'javascript_metadata', 'NativeFunctions.js'),
224
- `// Copyright 2020 The Chromium Authors. All rights reserved.
225
- // Use of this source code is governed by a BSD-style license that can be
226
- // found in the LICENSE file.
227
- // Generated from ${path.relative(path.join(__dirname, '..', '..'), __filename)}
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
- "typescript": "^2.8.3",
9
- "webidl2": "^10.3.3"
12
+ "mocha": "^9.1.4",
13
+ "typescript": "latest",
14
+ "webidl2": "^24.2.0"
10
15
  }
11
16
  }
@@ -0,0 +1,9 @@
1
+ interface Array<T> {
2
+ at(index: number): T|undefined;
3
+ diffSig(oneSig: number): T|undefined;
4
+ }
5
+
6
+ interface ReadonlyArray<T> {
7
+ at(index: number): T|undefined;
8
+ diffSig(twoSig: number): T|undefined;
9
+ }