chrome-devtools-frontend 1.0.1621678 → 1.0.1624409
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/.agents/skills/foundation-test-migration/SKILL.md +171 -0
- package/.agents/skills/verification/SKILL.md +2 -11
- package/front_end/Images/src/expand.svg +1 -0
- package/front_end/core/common/Base64.ts +12 -2
- package/front_end/core/i18n/i18nImpl.ts +8 -4
- package/front_end/core/root/Runtime.ts +28 -9
- package/front_end/entrypoints/device_mode_emulation_frame/device_mode_emulation_frame.ts +1 -1
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +72 -8
- package/front_end/entrypoints/greendev_floaty/floaty.html +1 -1
- package/front_end/entrypoints/shell/shell.ts +1 -1
- package/front_end/generated/Deprecation.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/SupportedCSSProperties.js +6 -6
- package/front_end/generated/protocol.ts +1 -0
- package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +373 -112
- package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +57 -0
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +2 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +3 -9
- package/front_end/models/javascript_metadata/NativeFunctions.js +9 -4
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +295 -45
- package/front_end/panels/console/ConsoleView.ts +86 -7
- package/front_end/panels/console/ConsoleViewMessage.ts +23 -1
- package/front_end/panels/console/SymbolizedErrorWidget.ts +69 -0
- package/front_end/panels/console/console.ts +3 -0
- package/front_end/panels/elements/StylePropertiesSection.ts +1 -2
- package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
- package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +6 -2
- package/front_end/panels/elements/StylesSidebarPane.ts +17 -4
- package/front_end/panels/emulation/DeviceModeToolbar.ts +189 -132
- package/front_end/panels/emulation/deviceModeView.css +25 -0
- package/front_end/panels/greendev/GreenDevPanel.ts +30 -3
- package/front_end/panels/media/EventDisplayTable.ts +1 -1
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +48 -27
- package/front_end/panels/mobile_throttling/ThrottlingManager.ts +67 -38
- package/front_end/panels/network/NetworkConfigView.ts +1 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +1 -22
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +12 -4
- package/front_end/panels/timeline/components/liveMetricsView.css +2 -2
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/{core → ui}/dom_extension/DOMExtension.ts +1 -1
- package/front_end/ui/legacy/UIUtils.ts +26 -4
- package/front_end/ui/legacy/Widget.ts +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +19 -0
- package/package.json +1 -1
- package/front_end/panels/emulation/components/DeviceSizeInputElement.ts +0 -134
- package/front_end/panels/emulation/components/components.ts +0 -9
- /package/front_end/{core → ui}/dom_extension/dom_extension.ts +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: foundation-test-migration
|
|
3
|
+
description: Migrating unit tests to foundation unit tests using TestUniverse and devtools_foundation_module. Use when moving tests away from DOM-heavy helpers like describeWithEnvironment or describeWithMockConnection.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Foundation Test Migration
|
|
7
|
+
|
|
8
|
+
This skill provides guidance on migrating DevTools unit tests to the "foundation" pattern, which is lighter, avoids global singletons, and is compatible with both Node and Browser runtimes (Isomorphic).
|
|
9
|
+
|
|
10
|
+
## Core Concepts
|
|
11
|
+
|
|
12
|
+
### devtools_foundation_module (BUILD.gn)
|
|
13
|
+
Use this template for modules that should be platform-agnostic.
|
|
14
|
+
- **Enforcement**: It type-checks the code against both Browser and Node APIs.
|
|
15
|
+
- **Constraint**: Avoid direct DOM access (like `FileReader` or layout metrics) or heavy DevTools dependencies. Use `Universe` to access services.
|
|
16
|
+
|
|
17
|
+
### TestUniverse
|
|
18
|
+
`TestUniverse` is the preferred way to setup a DevTools-like environment for tests without global singletons.
|
|
19
|
+
- **Lazy**: Dependencies (targetManager, settings, workspace, etc.) are only created when accessed via getters.
|
|
20
|
+
- **Scoped**: Does not install instances as globals (avoids `Common.Settings.Settings.instance()`).
|
|
21
|
+
- **Explicit**: Uses `DevToolsContext` to manage dependencies.
|
|
22
|
+
|
|
23
|
+
## Migration Guide
|
|
24
|
+
|
|
25
|
+
### 1. Replace Heavy Helpers
|
|
26
|
+
Avoid `describeWithEnvironment` or `describeWithMockConnection`.
|
|
27
|
+
|
|
28
|
+
Instead, use standard `describe` and initialize environment hooks at the top-level `describe` block. **Crucial:** Without `setupRuntimeHooks`, tests creating SDK models will crash due to uninitialized experiments (e.g. `capture-node-creation-stacks`).
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import {setupLocaleHooks} from '../../testing/LocaleHelpers.js';
|
|
32
|
+
import {setupSettingsHooks} from '../../testing/SettingsHelpers.js';
|
|
33
|
+
import {setupRuntimeHooks} from '../../testing/RuntimeHelpers.js';
|
|
34
|
+
import {TestUniverse} from '../../testing/TestUniverse.js';
|
|
35
|
+
|
|
36
|
+
describe('MyComponent', () => {
|
|
37
|
+
setupLocaleHooks();
|
|
38
|
+
setupSettingsHooks();
|
|
39
|
+
setupRuntimeHooks();
|
|
40
|
+
|
|
41
|
+
let universe: TestUniverse;
|
|
42
|
+
|
|
43
|
+
beforeEach(() => {
|
|
44
|
+
universe = new TestUniverse();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 2. Access Dependencies via Universe
|
|
50
|
+
Instead of using `SDK.TargetManager.TargetManager.instance()`, use `universe.targetManager`. Use `universe.createTarget()` instead of the global `createTarget`.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// OLD
|
|
54
|
+
const target = createTarget();
|
|
55
|
+
const targetManager = SDK.TargetManager.TargetManager.instance();
|
|
56
|
+
|
|
57
|
+
// NEW
|
|
58
|
+
const target = universe.createTarget({url: urlString`http://example.com/`});
|
|
59
|
+
const targetManager = universe.targetManager;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### Mocking CDP Traffic
|
|
63
|
+
If the test used `describeWithMockConnection` and global `setMockConnectionResponseHandler` to stub CDP traffic, you can migrate this by passing a `MockCDPConnection` to `universe.createTarget()`. This allows stubbing out CDP traffic scoped to a specific target tree rather than globally.
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import {MockCDPConnection} from '../../testing/MockCDPConnection.js';
|
|
67
|
+
|
|
68
|
+
const cdpConnection = new MockCDPConnection([
|
|
69
|
+
{
|
|
70
|
+
method: 'Network.getResponseBody',
|
|
71
|
+
response: () => ({body: 'mocked body', base64Encoded: false}),
|
|
72
|
+
}
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
const target = universe.createTarget({connection: cdpConnection});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> [!TIP]
|
|
79
|
+
> **Legacy Target URLs**: `EnvironmentHelpers.createTarget()` defaults to `http://example.com/`. `TestUniverse.createTarget()` defaults to `about:blank`. If your test asserts against specific URLs, remember to pass the URL explicitly.
|
|
80
|
+
|
|
81
|
+
### 3. Dealing with Legacy Singletons & Helpers
|
|
82
|
+
|
|
83
|
+
For large integration tests, you may encounter code that strictly calls `SomeModule.instance()` or uses complex legacy helpers (like `createWorkspaceProject`).
|
|
84
|
+
|
|
85
|
+
**Do not use `setUpEnvironment()`** as it will create disconnected singletons. Instead, wire the singletons to your `TestUniverse` and stub the globals to bridge legacy helpers:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
beforeEach(async () => {
|
|
89
|
+
universe = new TestUniverse();
|
|
90
|
+
const {targetManager, workspace, settings} = universe;
|
|
91
|
+
|
|
92
|
+
// 1. Stub globals so legacy helpers use TestUniverse components
|
|
93
|
+
sinon.stub(Workspace.Workspace.WorkspaceImpl, 'instance').returns(workspace);
|
|
94
|
+
sinon.stub(SDK.TargetManager.TargetManager, 'instance').returns(targetManager);
|
|
95
|
+
sinon.stub(Common.Settings.Settings, 'instance').returns(settings);
|
|
96
|
+
|
|
97
|
+
// 2. Initialize interdependent singletons in the correct order
|
|
98
|
+
SDK.NetworkManager.MultitargetNetworkManager.instance({forceNew: true, targetManager});
|
|
99
|
+
|
|
100
|
+
// 3. Now safe to use legacy helpers that rely on the above instances
|
|
101
|
+
await createWorkspaceProject(urlString`file:///path/to/overrides`, [...]);
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Pitfalls & Troubleshooting
|
|
106
|
+
|
|
107
|
+
### Strict Equality in Protocol Responses (`assert.deepEqual`)
|
|
108
|
+
Protocol requests/responses dynamically generated by Chrome (like Network conditions) can vary slightly (e.g., adding `connectionType`, `urlPattern`).
|
|
109
|
+
- **Problem**: `assert.deepEqual(rules, [{...}])` will flake if unrequested fields are present.
|
|
110
|
+
- **Solution**: Use `sinon.spy()` for handlers and assert with `sinon.assert.calledOnceWithMatch`:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
const emulateSpy = sinon.spy();
|
|
114
|
+
connection.setHandler('Network.emulateNetworkConditionsByRule', request => {
|
|
115
|
+
emulateSpy(request);
|
|
116
|
+
return {result: {ruleIds: []}};
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Matches only the fields you care about, ignoring extra protocol fields
|
|
120
|
+
sinon.assert.calledOnceWithMatch(emulateSpy, {
|
|
121
|
+
offline: false,
|
|
122
|
+
matchedNetworkConditions: [sinon.match({ downloadThroughput: 1000 })],
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### DOM Globals (`ReferenceError: FileReader is not defined`)
|
|
127
|
+
Foundation tests run in Node.js where `window`, `FileReader`, and certain DOM string encodings don't exist.
|
|
128
|
+
- **Fix**: Use isomorphic equivalents (e.g. `btoa()`, `Uint8Array`).
|
|
129
|
+
- **Last Resort**: Skip the test with `it.skip()` if it explicitly tests browser quirks (e.g. legacy charset decoding).
|
|
130
|
+
|
|
131
|
+
### Initialization Order Lockups
|
|
132
|
+
If a test times out (5000ms exceeded), it is usually an unhandled promise caused by a missing singleton. Double-check the constructor of the failing manager to see which `instance()` it listens to, and ensure that dependent singleton was created *first*.
|
|
133
|
+
|
|
134
|
+
## BUILD.gn Changes
|
|
135
|
+
|
|
136
|
+
When a module and its tests are ready, update `BUILD.gn`:
|
|
137
|
+
|
|
138
|
+
1. Change `devtools_module` to `devtools_foundation_module` for both the module and its unittests.
|
|
139
|
+
2. Ensure the tests are grouped under a `foundation_unittests` target in the parent `BUILD.gn`.
|
|
140
|
+
|
|
141
|
+
```gn
|
|
142
|
+
# front_end/my_module/BUILD.gn
|
|
143
|
+
|
|
144
|
+
devtools_foundation_module("my_module") {
|
|
145
|
+
sources = [ "MyModule.ts" ]
|
|
146
|
+
deps = [ "../../core/common:bundle" ]
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
devtools_foundation_module("unittests") {
|
|
150
|
+
testonly = true
|
|
151
|
+
sources = [ "MyModule.test.ts" ]
|
|
152
|
+
deps = [
|
|
153
|
+
":my_module",
|
|
154
|
+
"../../testing",
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Verification
|
|
160
|
+
|
|
161
|
+
Foundation tests must pass in both Node.js and Browser runtimes.
|
|
162
|
+
|
|
163
|
+
### Run in Node.js
|
|
164
|
+
```bash
|
|
165
|
+
npm test -- front_end/core/sdk/NetworkManager.test.ts --node-unit-tests
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Run in Browser
|
|
169
|
+
```bash
|
|
170
|
+
npm test -- front_end/core/sdk/NetworkManager.test.ts
|
|
171
|
+
```
|
|
@@ -13,25 +13,16 @@ description: MANDATORY: Activate this skill ANY TIME you need to build the proje
|
|
|
13
13
|
|
|
14
14
|
## Building & compiling
|
|
15
15
|
|
|
16
|
-
- Check for
|
|
17
|
-
|
|
18
|
-
## Fast builds
|
|
19
|
-
|
|
20
|
-
- If the `out/Fast` or `out/fast-build` directory exists, this means that a build that does not execute TypeScript is available to you which greatly decreases build time.
|
|
21
|
-
- To use the fast build for tests, pass the `--target=Fast` (adjust the value based on the name of the directory) argument to `npm run test`.
|
|
16
|
+
- Check for build issues by running `autoninja -C out/Default`.
|
|
22
17
|
|
|
23
18
|
## Linting
|
|
24
19
|
|
|
25
20
|
- `npm run lint` will execute ESLint and StyleLint. It will report any violations and automatically fix them where possible.
|
|
26
21
|
- To run the linter on a specific file or directory, you can run `npm run lint -- <PATH>` where `PATH` is a path to a file or directory. This will also automatically fix violations where possible.
|
|
27
22
|
|
|
28
|
-
## Presubmit
|
|
29
|
-
|
|
30
|
-
- `git cl presubmit -u` will check if the current change is ready for upload. It will also format and lint the change.
|
|
31
|
-
|
|
32
23
|
## Best practices
|
|
33
24
|
|
|
34
25
|
- Run tests often to verify your changes.
|
|
35
26
|
- Prefer using a fast build, if it exists, to keep the feedback loop shorter.
|
|
36
|
-
- Periodically
|
|
27
|
+
- Periodically build to check for errors.
|
|
37
28
|
- Run `git cl presubmit -u` at the end of your code changes.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="M192-96v-72h576v72H192Zm288-144L336-384l51-51 57 57v-204l-57 57-51-51 144-144 144 144-51 51-57-57v204l57-57 51 51-144 144ZM192-792v-72h576v72H192Z"/></svg>
|
|
@@ -36,8 +36,18 @@ export function decode(input: string): Uint8Array<ArrayBuffer> {
|
|
|
36
36
|
* Note: if input can be very large (larger than the max string size), callers should
|
|
37
37
|
* expect this to throw an error.
|
|
38
38
|
*/
|
|
39
|
-
export function encode(input: BlobPart): Promise<string> {
|
|
40
|
-
|
|
39
|
+
export async function encode(input: BlobPart): Promise<string> {
|
|
40
|
+
// Node.js environment (for foundation unit tests)
|
|
41
|
+
if (typeof FileReader === 'undefined') {
|
|
42
|
+
const blob = new Blob([input]);
|
|
43
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
44
|
+
// Use globalThis.Buffer to avoid TypeScript errors if Node types are not included.
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
+
return (globalThis as any).Buffer.from(arrayBuffer).toString('base64');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Browser environment
|
|
50
|
+
return await new Promise((resolve, reject) => {
|
|
41
51
|
const reader = new FileReader();
|
|
42
52
|
reader.onerror = () => reject(new Error('failed to convert to base64: internal error'));
|
|
43
53
|
reader.onload = () => {
|
|
@@ -64,10 +64,14 @@ function getLocaleFetchUrl(locale: Intl.UnicodeBCP47LocaleIdentifier, location:
|
|
|
64
64
|
* fetched locally or remotely.
|
|
65
65
|
*/
|
|
66
66
|
export async function fetchAndRegisterLocaleData(
|
|
67
|
-
locale: Intl.UnicodeBCP47LocaleIdentifier,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
locale: Intl.UnicodeBCP47LocaleIdentifier,
|
|
68
|
+
// Type issue with universal types.
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
+
location = (globalThis as any).location?.toString() ?? ''): Promise<void> {
|
|
71
|
+
const localeDataTextPromise =
|
|
72
|
+
fetch(getLocaleFetchUrl(locale, location)).then(result => result.json()) as Promise<I18n.I18n.LocalizedMessages>;
|
|
73
|
+
const timeoutPromise = new Promise<never>(
|
|
74
|
+
(_, reject) => globalThis.setTimeout(() => reject(new Error('timed out fetching locale')), 5000));
|
|
71
75
|
const localeData = await Promise.race([timeoutPromise, localeDataTextPromise]);
|
|
72
76
|
i18nInstance.registerLocaleData(locale, localeData);
|
|
73
77
|
}
|
|
@@ -12,12 +12,27 @@ let runtimeInstance: Runtime|undefined;
|
|
|
12
12
|
let isNode: boolean|undefined;
|
|
13
13
|
let isTraceAppEntry: boolean|undefined;
|
|
14
14
|
|
|
15
|
+
interface Global {
|
|
16
|
+
location?: {
|
|
17
|
+
toString(): string,
|
|
18
|
+
pathname: string,
|
|
19
|
+
search: string,
|
|
20
|
+
};
|
|
21
|
+
navigator?: {
|
|
22
|
+
userAgent: string,
|
|
23
|
+
};
|
|
24
|
+
localStorage?: Storage;
|
|
25
|
+
self?: Global;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const globalObject = (globalThis as unknown as Global);
|
|
29
|
+
|
|
15
30
|
/**
|
|
16
31
|
* Returns the base URL (similar to `<base>`).
|
|
17
32
|
* Used to resolve the relative URLs of any additional DevTools files (locale strings, etc) needed.
|
|
18
33
|
* See: https://cs.chromium.org/remoteBase+f:devtools_window
|
|
19
34
|
*/
|
|
20
|
-
export function getRemoteBase(location: string = self
|
|
35
|
+
export function getRemoteBase(location: string = globalObject.self?.location?.toString() ?? ''): {
|
|
21
36
|
base: string,
|
|
22
37
|
version: string,
|
|
23
38
|
}|null {
|
|
@@ -36,7 +51,7 @@ export function getRemoteBase(location: string = self.location.toString()): {
|
|
|
36
51
|
}
|
|
37
52
|
|
|
38
53
|
export function getPathName(): string {
|
|
39
|
-
return
|
|
54
|
+
return globalObject.location?.pathname ?? '';
|
|
40
55
|
}
|
|
41
56
|
|
|
42
57
|
export function isNodeEntry(pathname: string): boolean {
|
|
@@ -46,7 +61,7 @@ export function isNodeEntry(pathname: string): boolean {
|
|
|
46
61
|
|
|
47
62
|
export const getChromeVersion = (): string => {
|
|
48
63
|
const chromeRegex = /(?:^|\W)(?:Chrome|HeadlessChrome)\/(\S+)/;
|
|
49
|
-
const chromeMatch = navigator
|
|
64
|
+
const chromeMatch = globalObject.navigator?.userAgent?.match(chromeRegex);
|
|
50
65
|
if (chromeMatch && chromeMatch.length > 1) {
|
|
51
66
|
return chromeMatch[1];
|
|
52
67
|
}
|
|
@@ -75,9 +90,8 @@ export class Runtime {
|
|
|
75
90
|
static #queryParamsObject: URLSearchParams;
|
|
76
91
|
|
|
77
92
|
static #getSearchParams(): URLSearchParams|null {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
Runtime.#queryParamsObject = new URLSearchParams(location.search);
|
|
93
|
+
if (!Runtime.#queryParamsObject && globalObject.location) {
|
|
94
|
+
Runtime.#queryParamsObject = new URLSearchParams(globalObject.location.search);
|
|
81
95
|
}
|
|
82
96
|
return Runtime.#queryParamsObject;
|
|
83
97
|
}
|
|
@@ -297,13 +311,13 @@ export class ExperimentsSupport {
|
|
|
297
311
|
}
|
|
298
312
|
}
|
|
299
313
|
|
|
300
|
-
/** Manages the 'experiments' dictionary in
|
|
314
|
+
/** Manages the 'experiments' dictionary in globalThis.localStorage */
|
|
301
315
|
class ExperimentStorage {
|
|
302
316
|
readonly #experiments: Record<string, boolean|undefined> = {};
|
|
303
317
|
|
|
304
318
|
constructor() {
|
|
305
319
|
try {
|
|
306
|
-
const storedExperiments =
|
|
320
|
+
const storedExperiments = globalObject.localStorage?.getItem('experiments');
|
|
307
321
|
if (storedExperiments) {
|
|
308
322
|
this.#experiments = JSON.parse(storedExperiments);
|
|
309
323
|
}
|
|
@@ -337,7 +351,7 @@ class ExperimentStorage {
|
|
|
337
351
|
}
|
|
338
352
|
|
|
339
353
|
#syncToLocalStorage(): void {
|
|
340
|
-
|
|
354
|
+
globalObject.localStorage?.setItem('experiments', JSON.stringify(this.#experiments));
|
|
341
355
|
}
|
|
342
356
|
}
|
|
343
357
|
|
|
@@ -480,6 +494,10 @@ export interface HostConfigAiAssistanceAccessibilityAgent {
|
|
|
480
494
|
enabled: boolean;
|
|
481
495
|
}
|
|
482
496
|
|
|
497
|
+
export interface HostConfigAiAssistanceStorageAgent {
|
|
498
|
+
enabled: boolean;
|
|
499
|
+
}
|
|
500
|
+
|
|
483
501
|
export interface HostConfigAiCodeCompletion {
|
|
484
502
|
modelId: string;
|
|
485
503
|
temperature: number;
|
|
@@ -638,6 +656,7 @@ export type HostConfig = Platform.TypeScriptUtilities.RecursivePartial<{
|
|
|
638
656
|
devToolsAiAssistanceFileAgent: HostConfigAiAssistanceFileAgent,
|
|
639
657
|
devToolsAiAssistancePerformanceAgent: HostConfigAiAssistancePerformanceAgent,
|
|
640
658
|
devToolsAiAssistanceAccessibilityAgent: HostConfigAiAssistanceAccessibilityAgent,
|
|
659
|
+
devToolsAiAssistanceStorageAgent: HostConfigAiAssistanceStorageAgent,
|
|
641
660
|
devToolsAiAssistanceV2: HostConfigAiAssistanceV2,
|
|
642
661
|
devToolsAiCodeCompletion: HostConfigAiCodeCompletion,
|
|
643
662
|
devToolsAiCodeGeneration: HostConfigAiCodeGeneration,
|
|
@@ -2,7 +2,7 @@
|
|
|
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 '../../
|
|
5
|
+
import '../../ui/dom_extension/dom_extension.js';
|
|
6
6
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
7
7
|
// @ts-ignore: tsc 6.0 does not support side-effect imports without a type definition.
|
|
8
8
|
// We cannot use `@ts-expect-error` here because the import is correctly resolved
|
|
@@ -7,8 +7,11 @@ import '../../core/sdk/sdk-meta.js';
|
|
|
7
7
|
import '../../models/workspace/workspace-meta.js';
|
|
8
8
|
import '../../models/logs/logs-meta.js';
|
|
9
9
|
import '../../panels/sensors/sensors-meta.js';
|
|
10
|
+
import '../../panels/sources/sources-meta.js';
|
|
10
11
|
import '../../entrypoints/inspector_main/inspector_main-meta.js';
|
|
11
12
|
import '../../entrypoints/main/main-meta.js';
|
|
13
|
+
import '../../ui/legacy/components/source_frame/source_frame-meta.js';
|
|
14
|
+
import '../../ui/components/markdown_view/markdown_view.js';
|
|
12
15
|
|
|
13
16
|
import * as Common from '../../core/common/common.js';
|
|
14
17
|
import * as Host from '../../core/host/host.js';
|
|
@@ -22,6 +25,8 @@ import type * as Protocol from '../../generated/protocol.js';
|
|
|
22
25
|
import * as AiAssistance from '../../models/ai_assistance/ai_assistance.js';
|
|
23
26
|
import * as Greendev from '../../models/greendev/greendev.js';
|
|
24
27
|
import type {SyncMessage} from '../../panels/greendev/GreenDevShared.js';
|
|
28
|
+
import * as Marked from '../../third_party/marked/marked.js';
|
|
29
|
+
import * as MarkdownView from '../../ui/components/markdown_view/markdown_view.js';
|
|
25
30
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
26
31
|
import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
|
|
27
32
|
|
|
@@ -294,6 +299,8 @@ class GreenDevFloaty {
|
|
|
294
299
|
nodeDescription: document.querySelector('.green-dev-floaty-dialog-node-description')?.textContent,
|
|
295
300
|
});
|
|
296
301
|
|
|
302
|
+
let agentFinished = false;
|
|
303
|
+
let steps = 0;
|
|
297
304
|
try {
|
|
298
305
|
let results;
|
|
299
306
|
if (useGreenDevAgent && this.#agent instanceof AiAssistance.GreenDevAgent.GreenDevAgent) {
|
|
@@ -302,7 +309,7 @@ class GreenDevFloaty {
|
|
|
302
309
|
return;
|
|
303
310
|
}
|
|
304
311
|
|
|
305
|
-
// ---
|
|
312
|
+
// --- Get the Accessibility Tree ---
|
|
306
313
|
const accessibilityModel = target.model(SDK.AccessibilityModel.AccessibilityModel);
|
|
307
314
|
let axTree = '';
|
|
308
315
|
if (accessibilityModel) {
|
|
@@ -315,7 +322,7 @@ class GreenDevFloaty {
|
|
|
315
322
|
}
|
|
316
323
|
}
|
|
317
324
|
|
|
318
|
-
// ---
|
|
325
|
+
// --- Get the most recent network requests ---
|
|
319
326
|
const allNetworkRequests = await AiAssistance.GreenDevAgent.GreenDevAgent.getNetworkContextData(target);
|
|
320
327
|
const networkResourcesMax = 50;
|
|
321
328
|
const startNetworkIndex = Math.max(0, allNetworkRequests.length - networkResourcesMax);
|
|
@@ -330,13 +337,13 @@ class GreenDevFloaty {
|
|
|
330
337
|
allNetworkRequests.length -
|
|
331
338
|
lastNetworkRequests.length} additional requests are available (network requests shown are capped at ${
|
|
332
339
|
networkResourcesMax} requests).` :
|
|
333
|
-
'No further network requests
|
|
340
|
+
'No further network requests are available.';
|
|
334
341
|
|
|
335
342
|
formattedNetworkContext = `Showing network requests with indices ${startNetworkIndex}-${
|
|
336
343
|
startNetworkIndex + lastNetworkRequests.length - 1}:\n\n${formattedNetworkContext}\n\n${footer}`;
|
|
337
344
|
}
|
|
338
345
|
|
|
339
|
-
// ---
|
|
346
|
+
// --- Get the most recent console messages ---
|
|
340
347
|
const consoleModel = target.model(SDK.ConsoleModel.ConsoleModel);
|
|
341
348
|
const allConsoleMessages = consoleModel ? consoleModel.messages() : [];
|
|
342
349
|
const consoleMsgLimit = 50;
|
|
@@ -358,7 +365,7 @@ class GreenDevFloaty {
|
|
|
358
365
|
allConsoleMessages.length -
|
|
359
366
|
lastConsoleMessages.length} additional messages are available (errors shown are capped at ${
|
|
360
367
|
consoleMsgLimit} most recent).` :
|
|
361
|
-
'No further console messages
|
|
368
|
+
'No further console messages are available.';
|
|
362
369
|
|
|
363
370
|
formattedConsoleMessages = `Showing console messages with indices ${startIndex}-${
|
|
364
371
|
startIndex + lastConsoleMessages.length - 1}:\n\n${formattedConsoleMessages}\n\n${footer}`;
|
|
@@ -366,8 +373,15 @@ class GreenDevFloaty {
|
|
|
366
373
|
|
|
367
374
|
const mainUrl = target.inspectedURL();
|
|
368
375
|
|
|
369
|
-
// ---
|
|
376
|
+
// --- Get the React Props for the selected node (if available) ---
|
|
377
|
+
const reactComponentProps = this.#backendNodeId ?
|
|
378
|
+
await this.#agent.getReactComponentProps(this.#backendNodeId, false) :
|
|
379
|
+
'Could not get the backendNodeId for the selected element.';
|
|
380
|
+
|
|
381
|
+
// --- Get some context information about the selected node ---
|
|
370
382
|
const elementContext = await AiAssistance.StylingAgent.StylingAgent.describeElement(this.#node);
|
|
383
|
+
|
|
384
|
+
// Now construct the full context.
|
|
371
385
|
const context = `# Page URL
|
|
372
386
|
|
|
373
387
|
${mainUrl}
|
|
@@ -376,6 +390,10 @@ ${mainUrl}
|
|
|
376
390
|
|
|
377
391
|
${elementContext}
|
|
378
392
|
|
|
393
|
+
# React component props:
|
|
394
|
+
|
|
395
|
+
${reactComponentProps}
|
|
396
|
+
|
|
379
397
|
# Recent network requests
|
|
380
398
|
|
|
381
399
|
${formattedNetworkContext}
|
|
@@ -401,15 +419,53 @@ ${axTree}`;
|
|
|
401
419
|
|
|
402
420
|
for await (const result of results) {
|
|
403
421
|
switch (result.type) {
|
|
404
|
-
case ResponseType.
|
|
405
|
-
|
|
422
|
+
case ResponseType.QUERYING:
|
|
423
|
+
steps++;
|
|
424
|
+
break;
|
|
425
|
+
case ResponseType.ANSWER: {
|
|
426
|
+
aiContent.textContent = '';
|
|
427
|
+
// Add a space in the protocol, which prevents links from being linkified in
|
|
428
|
+
// the markup. Why? Because there's an exception thrown if the links don't match the
|
|
429
|
+
// allowlist in getMarkdownLink(). Need to figure out later.
|
|
430
|
+
let sanitizedText = result.text.replace(/https:\/\//g, 'https: //');
|
|
431
|
+
sanitizedText = sanitizedText.replace(/http:\/\//g, 'http: //');
|
|
432
|
+
const markdown = new MarkdownView.MarkdownView.MarkdownView();
|
|
433
|
+
markdown.data = {
|
|
434
|
+
tokens: Marked.Marked.lexer(sanitizedText),
|
|
435
|
+
};
|
|
436
|
+
aiContent.append(markdown);
|
|
437
|
+
void new Promise(resolve => setTimeout(resolve, 0)).then(() => {
|
|
438
|
+
const style = document.createElement('style');
|
|
439
|
+
style.textContent =
|
|
440
|
+
'.message { font-size: 1.0rem; } .message code { font-size: 1.0rem; font-family: \'Roboto Mono\', ' +
|
|
441
|
+
'monospace; color: green; } .message ul { margin-left: 20px; }';
|
|
442
|
+
markdown.shadowRoot?.appendChild(style);
|
|
443
|
+
|
|
444
|
+
const codeBlocks = markdown.shadowRoot?.querySelectorAll('devtools-code-block');
|
|
445
|
+
if (codeBlocks) {
|
|
446
|
+
for (const codeBlock of codeBlocks) {
|
|
447
|
+
const style = document.createElement('style');
|
|
448
|
+
style.textContent = `
|
|
449
|
+
.heading { color: black; background-color: #f2f6ff; font-family: 'Roboto Mono', monospace; padding: 2px 4px;
|
|
450
|
+
border-top-left-radius: 8px; border-top-right-radius: 8px; margin-bottom: 3px; }
|
|
451
|
+
.code { background-color: #f8f9fa; font-family: 'Roboto Mono', monospace; padding: 5px;
|
|
452
|
+
border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; }
|
|
453
|
+
.editor-wrapper { margin-left: 20px; }
|
|
454
|
+
`;
|
|
455
|
+
codeBlock.shadowRoot?.appendChild(style);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
});
|
|
406
459
|
this.#syncChannel.postMessage(
|
|
407
460
|
{type: 'update-last-message', text: result.text, sessionId: this.#backendNodeId});
|
|
461
|
+
agentFinished = true;
|
|
408
462
|
break;
|
|
463
|
+
}
|
|
409
464
|
case ResponseType.ERROR:
|
|
410
465
|
aiContent.textContent = this.#formatError(result.error);
|
|
411
466
|
this.#syncChannel.postMessage(
|
|
412
467
|
{type: 'update-last-message', text: this.#formatError(result.error), sessionId: this.#backendNodeId});
|
|
468
|
+
agentFinished = true;
|
|
413
469
|
break;
|
|
414
470
|
case ResponseType.SIDE_EFFECT:
|
|
415
471
|
result.confirm(true);
|
|
@@ -423,6 +479,14 @@ ${axTree}`;
|
|
|
423
479
|
}
|
|
424
480
|
} catch (e) {
|
|
425
481
|
aiContent.textContent = `Exception: ${e instanceof Error ? e.message : String(e)}`;
|
|
482
|
+
agentFinished = true;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const MAX_AGENT_STEPS = AiAssistance.AiAgent.MAX_STEPS;
|
|
486
|
+
if (!agentFinished && steps >= MAX_AGENT_STEPS) {
|
|
487
|
+
aiContent.textContent = `The agent has reached its internal limit of ${MAX_AGENT_STEPS} steps per turn before
|
|
488
|
+
finding an answer. Please try again with a more specific query or say 'continue' (to get ${MAX_AGENT_STEPS}
|
|
489
|
+
more steps and continue trying).`;
|
|
426
490
|
}
|
|
427
491
|
};
|
|
428
492
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<div class="green-dev-floaty-dialog-blue-card">
|
|
21
21
|
<div class="green-dev-floaty-dialog-node-description"></div>
|
|
22
22
|
<div class="input-row">
|
|
23
|
-
<input type="text" class="green-dev-floaty-dialog-text-field" placeholder="Why is this
|
|
23
|
+
<input type="text" class="green-dev-floaty-dialog-text-field" placeholder="Why is this hanging?">
|
|
24
24
|
<button class="green-dev-floaty-dialog-play-button"></button>
|
|
25
25
|
</div>
|
|
26
26
|
<div class="green-dev-floaty-disclaimer">
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// We cannot use `@ts-expect-error` here because the import is correctly resolved
|
|
8
8
|
// when bundling the application (which doesn't error) and only errors in unbundled builds.
|
|
9
9
|
import '../../Images/Images.js';
|
|
10
|
-
import '../../
|
|
10
|
+
import '../../ui/dom_extension/dom_extension.js';
|
|
11
11
|
import '../../panels/sources/sources-meta.js';
|
|
12
12
|
import '../../panels/profiler/profiler-meta.js';
|
|
13
13
|
import '../../panels/console/console-meta.js';
|
|
@@ -210,6 +210,10 @@ export const UIStrings = {
|
|
|
210
210
|
* @description Standard message when one web API is deprecated in favor of another.
|
|
211
211
|
*/
|
|
212
212
|
PrefixedVideoSupportsFullscreen: "HTMLVideoElement.webkitSupportsFullscreen is deprecated. Please use Document.fullscreenEnabled instead.",
|
|
213
|
+
/**
|
|
214
|
+
* @description Warning displayed to developers when an SVG filter is applied to a disallowed content type.
|
|
215
|
+
*/
|
|
216
|
+
PreventSvgFilterPaint: "SVG filters cannot be applied to cross-origin iframes, restricted iframes (e.g., sandboxed), or plugins.",
|
|
213
217
|
/**
|
|
214
218
|
* @description Standard message when one web API is deprecated in favor of another.
|
|
215
219
|
*/
|
|
@@ -390,6 +394,9 @@ export const DEPRECATIONS_METADATA: Partial<Record<string, DeprecationDescriptor
|
|
|
390
394
|
"chromeStatusFeature": 5176235376246784,
|
|
391
395
|
"milestone": 106
|
|
392
396
|
},
|
|
397
|
+
"PreventSvgFilterPaint": {
|
|
398
|
+
"chromeStatusFeature": 5117170452398080
|
|
399
|
+
},
|
|
393
400
|
"RTCConstraintEnableDtlsSrtpFalse": {
|
|
394
401
|
"milestone": 97
|
|
395
402
|
},
|
|
@@ -1032,7 +1032,7 @@ inspectorBackend.registerEnum("Page.AdFrameExplanation", {ParentIsAd: "ParentIsA
|
|
|
1032
1032
|
inspectorBackend.registerEnum("Page.SecureContextType", {Secure: "Secure", SecureLocalhost: "SecureLocalhost", InsecureScheme: "InsecureScheme", InsecureAncestor: "InsecureAncestor"});
|
|
1033
1033
|
inspectorBackend.registerEnum("Page.CrossOriginIsolatedContextType", {Isolated: "Isolated", NotIsolated: "NotIsolated", NotIsolatedFeatureDisabled: "NotIsolatedFeatureDisabled"});
|
|
1034
1034
|
inspectorBackend.registerEnum("Page.GatedAPIFeatures", {SharedArrayBuffers: "SharedArrayBuffers", SharedArrayBuffersTransferAllowed: "SharedArrayBuffersTransferAllowed", PerformanceMeasureMemory: "PerformanceMeasureMemory", PerformanceProfile: "PerformanceProfile"});
|
|
1035
|
-
inspectorBackend.registerEnum("Page.PermissionsPolicyFeature", {Accelerometer: "accelerometer", AllScreensCapture: "all-screens-capture", AmbientLightSensor: "ambient-light-sensor", AriaNotify: "aria-notify", AttributionReporting: "attribution-reporting", Autofill: "autofill", Autoplay: "autoplay", Bluetooth: "bluetooth", BrowsingTopics: "browsing-topics", Camera: "camera", CapturedSurfaceControl: "captured-surface-control", ChDpr: "ch-dpr", ChDeviceMemory: "ch-device-memory", ChDownlink: "ch-downlink", ChEct: "ch-ect", ChPrefersColorScheme: "ch-prefers-color-scheme", ChPrefersReducedMotion: "ch-prefers-reduced-motion", ChPrefersReducedTransparency: "ch-prefers-reduced-transparency", ChRtt: "ch-rtt", ChSaveData: "ch-save-data", ChUa: "ch-ua", ChUaArch: "ch-ua-arch", ChUaBitness: "ch-ua-bitness", ChUaHighEntropyValues: "ch-ua-high-entropy-values", ChUaPlatform: "ch-ua-platform", ChUaModel: "ch-ua-model", ChUaMobile: "ch-ua-mobile", ChUaFormFactors: "ch-ua-form-factors", ChUaFullVersion: "ch-ua-full-version", ChUaFullVersionList: "ch-ua-full-version-list", ChUaPlatformVersion: "ch-ua-platform-version", ChUaWow64: "ch-ua-wow64", ChViewportHeight: "ch-viewport-height", ChViewportWidth: "ch-viewport-width", ChWidth: "ch-width", ClipboardRead: "clipboard-read", ClipboardWrite: "clipboard-write", ComputePressure: "compute-pressure", ControlledFrame: "controlled-frame", CrossOriginIsolated: "cross-origin-isolated", DeferredFetch: "deferred-fetch", DeferredFetchMinimal: "deferred-fetch-minimal", DeviceAttributes: "device-attributes", DigitalCredentialsCreate: "digital-credentials-create", DigitalCredentialsGet: "digital-credentials-get", DirectSockets: "direct-sockets", DirectSocketsMulticast: "direct-sockets-multicast", DirectSocketsPrivate: "direct-sockets-private", DisplayCapture: "display-capture", DocumentDomain: "document-domain", EncryptedMedia: "encrypted-media", ExecutionWhileOutOfViewport: "execution-while-out-of-viewport", ExecutionWhileNotRendered: "execution-while-not-rendered", FocusWithoutUserActivation: "focus-without-user-activation", Fullscreen: "fullscreen", Frobulate: "frobulate", Gamepad: "gamepad", Geolocation: "geolocation", Gyroscope: "gyroscope", Hid: "hid", IdentityCredentialsGet: "identity-credentials-get", IdleDetection: "idle-detection", InterestCohort: "interest-cohort", JoinAdInterestGroup: "join-ad-interest-group", KeyboardMap: "keyboard-map", LanguageDetector: "language-detector", LanguageModel: "language-model", LocalFonts: "local-fonts", LocalNetwork: "local-network", LocalNetworkAccess: "local-network-access", LoopbackNetwork: "loopback-network", Magnetometer: "magnetometer", ManualText: "manual-text", MediaPlaybackWhileNotVisible: "media-playback-while-not-visible", Microphone: "microphone", Midi: "midi", OnDeviceSpeechRecognition: "on-device-speech-recognition", OtpCredentials: "otp-credentials", Payment: "payment", PictureInPicture: "picture-in-picture", PrivateAggregation: "private-aggregation", PrivateStateTokenIssuance: "private-state-token-issuance", PrivateStateTokenRedemption: "private-state-token-redemption", PublickeyCredentialsCreate: "publickey-credentials-create", PublickeyCredentialsGet: "publickey-credentials-get", RecordAdAuctionEvents: "record-ad-auction-events", Rewriter: "rewriter", RunAdAuction: "run-ad-auction", ScreenWakeLock: "screen-wake-lock", Serial: "serial", SharedStorage: "shared-storage", SharedStorageSelectUrl: "shared-storage-select-url", SmartCard: "smart-card", SpeakerSelection: "speaker-selection", StorageAccess: "storage-access", SubApps: "sub-apps", Summarizer: "summarizer", SyncXhr: "sync-xhr", Translator: "translator", Unload: "unload", Usb: "usb", UsbUnrestricted: "usb-unrestricted", VerticalScroll: "vertical-scroll", WebAppInstallation: "web-app-installation", WebPrinting: "web-printing", WebShare: "web-share", WindowManagement: "window-management", Writer: "writer", XrSpatialTracking: "xr-spatial-tracking"});
|
|
1035
|
+
inspectorBackend.registerEnum("Page.PermissionsPolicyFeature", {Accelerometer: "accelerometer", AllScreensCapture: "all-screens-capture", AmbientLightSensor: "ambient-light-sensor", AriaNotify: "aria-notify", AttributionReporting: "attribution-reporting", Autofill: "autofill", Autoplay: "autoplay", Bluetooth: "bluetooth", BrowsingTopics: "browsing-topics", Camera: "camera", CapturedSurfaceControl: "captured-surface-control", ChDpr: "ch-dpr", ChDeviceMemory: "ch-device-memory", ChDownlink: "ch-downlink", ChEct: "ch-ect", ChPrefersColorScheme: "ch-prefers-color-scheme", ChPrefersReducedMotion: "ch-prefers-reduced-motion", ChPrefersReducedTransparency: "ch-prefers-reduced-transparency", ChRtt: "ch-rtt", ChSaveData: "ch-save-data", ChUa: "ch-ua", ChUaArch: "ch-ua-arch", ChUaBitness: "ch-ua-bitness", ChUaHighEntropyValues: "ch-ua-high-entropy-values", ChUaPlatform: "ch-ua-platform", ChUaModel: "ch-ua-model", ChUaMobile: "ch-ua-mobile", ChUaFormFactors: "ch-ua-form-factors", ChUaFullVersion: "ch-ua-full-version", ChUaFullVersionList: "ch-ua-full-version-list", ChUaPlatformVersion: "ch-ua-platform-version", ChUaWow64: "ch-ua-wow64", ChViewportHeight: "ch-viewport-height", ChViewportWidth: "ch-viewport-width", ChWidth: "ch-width", ClipboardRead: "clipboard-read", ClipboardWrite: "clipboard-write", ComputePressure: "compute-pressure", ControlledFrame: "controlled-frame", CrossOriginIsolated: "cross-origin-isolated", DeferredFetch: "deferred-fetch", DeferredFetchMinimal: "deferred-fetch-minimal", DeviceAttributes: "device-attributes", DigitalCredentialsCreate: "digital-credentials-create", DigitalCredentialsGet: "digital-credentials-get", DirectSockets: "direct-sockets", DirectSocketsMulticast: "direct-sockets-multicast", DirectSocketsPrivate: "direct-sockets-private", DisplayCapture: "display-capture", DocumentDomain: "document-domain", EncryptedMedia: "encrypted-media", ExecutionWhileOutOfViewport: "execution-while-out-of-viewport", ExecutionWhileNotRendered: "execution-while-not-rendered", FocusWithoutUserActivation: "focus-without-user-activation", Fullscreen: "fullscreen", Frobulate: "frobulate", Gamepad: "gamepad", Geolocation: "geolocation", Gyroscope: "gyroscope", Hid: "hid", IdentityCredentialsGet: "identity-credentials-get", IdleDetection: "idle-detection", InterestCohort: "interest-cohort", JoinAdInterestGroup: "join-ad-interest-group", KeyboardMap: "keyboard-map", LanguageDetector: "language-detector", LanguageModel: "language-model", LocalFonts: "local-fonts", LocalNetwork: "local-network", LocalNetworkAccess: "local-network-access", LoopbackNetwork: "loopback-network", Magnetometer: "magnetometer", ManualText: "manual-text", MediaPlaybackWhileNotVisible: "media-playback-while-not-visible", Microphone: "microphone", Midi: "midi", OnDeviceSpeechRecognition: "on-device-speech-recognition", OtpCredentials: "otp-credentials", Payment: "payment", PictureInPicture: "picture-in-picture", PrivateAggregation: "private-aggregation", PrivateStateTokenIssuance: "private-state-token-issuance", PrivateStateTokenRedemption: "private-state-token-redemption", PublickeyCredentialsCreate: "publickey-credentials-create", PublickeyCredentialsGet: "publickey-credentials-get", RecordAdAuctionEvents: "record-ad-auction-events", Rewriter: "rewriter", RunAdAuction: "run-ad-auction", ScreenWakeLock: "screen-wake-lock", Serial: "serial", SharedStorage: "shared-storage", SharedStorageSelectUrl: "shared-storage-select-url", SmartCard: "smart-card", SpeakerSelection: "speaker-selection", StorageAccess: "storage-access", SubApps: "sub-apps", Summarizer: "summarizer", SyncXhr: "sync-xhr", Tools: "tools", Translator: "translator", Unload: "unload", Usb: "usb", UsbUnrestricted: "usb-unrestricted", VerticalScroll: "vertical-scroll", WebAppInstallation: "web-app-installation", WebPrinting: "web-printing", WebShare: "web-share", WindowManagement: "window-management", Writer: "writer", XrSpatialTracking: "xr-spatial-tracking"});
|
|
1036
1036
|
inspectorBackend.registerEnum("Page.PermissionsPolicyBlockReason", {Header: "Header", IframeAttribute: "IframeAttribute", InFencedFrameTree: "InFencedFrameTree", InIsolatedApp: "InIsolatedApp"});
|
|
1037
1037
|
inspectorBackend.registerEnum("Page.OriginTrialTokenStatus", {Success: "Success", NotSupported: "NotSupported", Insecure: "Insecure", Expired: "Expired", WrongOrigin: "WrongOrigin", InvalidSignature: "InvalidSignature", Malformed: "Malformed", WrongVersion: "WrongVersion", FeatureDisabled: "FeatureDisabled", TokenDisabled: "TokenDisabled", FeatureDisabledForUser: "FeatureDisabledForUser", UnknownTrial: "UnknownTrial"});
|
|
1038
1038
|
inspectorBackend.registerEnum("Page.OriginTrialStatus", {Enabled: "Enabled", ValidTokenNotProvided: "ValidTokenNotProvided", OSNotSupported: "OSNotSupported", TrialNotAllowed: "TrialNotAllowed"});
|
|
@@ -1076,7 +1076,7 @@ export const generatedProperties = [
|
|
|
1076
1076
|
{
|
|
1077
1077
|
"inherited": true,
|
|
1078
1078
|
"keywords": [
|
|
1079
|
-
"
|
|
1079
|
+
"ellipsis",
|
|
1080
1080
|
"no-ellipsis"
|
|
1081
1081
|
],
|
|
1082
1082
|
"name": "block-ellipsis"
|
|
@@ -1945,7 +1945,7 @@ export const generatedProperties = [
|
|
|
1945
1945
|
},
|
|
1946
1946
|
{
|
|
1947
1947
|
"keywords": [
|
|
1948
|
-
"
|
|
1948
|
+
"normal",
|
|
1949
1949
|
"collapse",
|
|
1950
1950
|
"-webkit-legacy"
|
|
1951
1951
|
],
|
|
@@ -3950,7 +3950,7 @@ export const generatedProperties = [
|
|
|
3950
3950
|
"inherited": true,
|
|
3951
3951
|
"keywords": [
|
|
3952
3952
|
"auto",
|
|
3953
|
-
"
|
|
3953
|
+
"spaces"
|
|
3954
3954
|
],
|
|
3955
3955
|
"name": "ruby-overhang"
|
|
3956
3956
|
},
|
|
@@ -5324,7 +5324,7 @@ export const generatedPropertyValues = {
|
|
|
5324
5324
|
},
|
|
5325
5325
|
"block-ellipsis": {
|
|
5326
5326
|
"values": [
|
|
5327
|
-
"
|
|
5327
|
+
"ellipsis",
|
|
5328
5328
|
"no-ellipsis"
|
|
5329
5329
|
]
|
|
5330
5330
|
},
|
|
@@ -5767,7 +5767,7 @@ export const generatedPropertyValues = {
|
|
|
5767
5767
|
},
|
|
5768
5768
|
"continue": {
|
|
5769
5769
|
"values": [
|
|
5770
|
-
"
|
|
5770
|
+
"normal",
|
|
5771
5771
|
"collapse",
|
|
5772
5772
|
"-webkit-legacy"
|
|
5773
5773
|
]
|
|
@@ -6885,7 +6885,7 @@ export const generatedPropertyValues = {
|
|
|
6885
6885
|
"ruby-overhang": {
|
|
6886
6886
|
"values": [
|
|
6887
6887
|
"auto",
|
|
6888
|
-
"
|
|
6888
|
+
"spaces"
|
|
6889
6889
|
]
|
|
6890
6890
|
},
|
|
6891
6891
|
"ruby-position": {
|