chrome-devtools-frontend 1.0.1697595 → 1.0.1698733
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/version-control/SKILL.md +21 -9
- package/.stylelintignore +2 -0
- package/front_end/core/common/VersionController.ts +5 -1
- package/front_end/core/platform/HostRuntime.ts +12 -0
- package/front_end/core/platform/api/HostRuntime.ts +13 -0
- package/front_end/core/platform/browser/HostRuntime.ts +34 -0
- package/front_end/core/platform/node/HostRuntime.ts +40 -0
- package/front_end/core/sdk/AnimationModel.ts +21 -99
- package/front_end/core/sdk/CSSModel.ts +4 -2
- package/front_end/core/sdk/CSSPropertyParser.ts +4 -4
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +4 -44
- package/front_end/core/sdk/Connections.ts +6 -1
- package/front_end/core/sdk/ConsoleModel.ts +1 -12
- package/front_end/core/sdk/DOMModel.ts +3 -51
- package/front_end/core/sdk/DebuggerModel.ts +9 -8
- package/front_end/core/sdk/NetworkRequest.ts +1 -1
- package/front_end/core/sdk/PageFunctions.ts +187 -0
- package/front_end/core/sdk/Resource.ts +1 -1
- package/front_end/core/sdk/RuntimeModel.ts +1 -20
- package/front_end/core/sdk/Script.ts +21 -0
- package/front_end/core/sdk/SourceMap.ts +15 -2
- package/front_end/core/sdk/SourceMapCache.ts +13 -10
- package/front_end/core/sdk/SourceMapManager.ts +11 -9
- package/front_end/core/sdk/SourceMapScopeChainEntry.ts +59 -17
- package/front_end/core/sdk/SourceMapScopesInfo.ts +8 -2
- package/front_end/entrypoints/heap_snapshot_worker/ContextAnalyzer.ts +635 -0
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +26 -12
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +16 -2
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +4 -4
- package/front_end/entrypoints/heap_snapshot_worker/heap_snapshot_worker.ts +2 -0
- package/front_end/entrypoints/shell/shell.ts +1 -1
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/protocol.ts +8 -2
- package/front_end/models/ai_assistance/DOMHelpers.ts +95 -0
- package/front_end/models/ai_assistance/EvaluateAction.ts +5 -42
- package/front_end/models/ai_assistance/ExtensionScope.ts +2 -31
- package/front_end/models/ai_assistance/agents/AiAgent.ts +2 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +27 -2
- package/front_end/models/ai_assistance/ai_assistance.ts +6 -4
- package/front_end/models/ai_assistance/contexts/DOMNodeContext.ts +10 -7
- package/front_end/models/ai_assistance/contexts/FileContext.ts +2 -10
- package/front_end/models/ai_assistance/skills/performance.md +4 -3
- package/front_end/models/ai_assistance/tools/GetSourceContent.ts +3 -2
- package/front_end/models/ai_assistance/tools/{GetFunctionCode.ts → GetTraceFunctionCode.ts} +26 -13
- package/front_end/models/ai_assistance/tools/{GetResourceContent.ts → GetTraceResourceContent.ts} +31 -11
- package/front_end/models/ai_assistance/tools/ListSources.ts +21 -14
- package/front_end/models/ai_assistance/tools/Tool.ts +2 -2
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +6 -6
- package/front_end/models/bindings/CompilerScriptMapping.ts +3 -10
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +48 -17
- package/front_end/models/bindings/ResourceScriptMapping.ts +2 -2
- package/front_end/models/bindings/StylesSourceMapping.ts +1 -1
- package/front_end/models/comment_manager/CD4ABridge.ts +55 -12
- package/front_end/models/comment_manager/CommentManager.ts +46 -91
- package/front_end/models/comment_manager/CommentThread.ts +145 -0
- package/front_end/models/comment_manager/comment_manager.ts +2 -0
- package/front_end/models/elements/DOMChanges.ts +238 -0
- package/front_end/models/elements/elements.ts +2 -0
- package/front_end/models/emulation/DeviceModeModel.ts +53 -0
- package/front_end/models/extensions/ExtensionAPI.ts +8 -6
- package/front_end/models/extensions/ExtensionEndpoint.ts +11 -8
- package/front_end/models/extensions/HostUrlPattern.ts +4 -3
- package/front_end/models/extensions/LanguageExtensionEndpoint.ts +3 -2
- package/front_end/models/extensions/RecorderExtensionEndpoint.ts +2 -1
- package/front_end/models/formatter/FormatterWorkerPool.ts +4 -6
- package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +55 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +18 -14
- package/front_end/models/issues_manager/IssuesManager.ts +5 -0
- package/front_end/models/issues_manager/WebInstallIssue.ts +63 -0
- package/front_end/models/issues_manager/descriptions/webInstallManifestMissingId.md +3 -0
- package/front_end/models/issues_manager/descriptions/webInstallManifestMissingNameOrShortName.md +3 -0
- package/front_end/models/issues_manager/descriptions/webInstallManifestParsingOrNetworkError.md +3 -0
- package/front_end/models/issues_manager/descriptions/webInstallNoManifest.md +3 -0
- package/front_end/models/issues_manager/descriptions/webInstallStartUrlInvalid.md +3 -0
- package/front_end/models/issues_manager/issues_manager.ts +2 -0
- package/front_end/models/workspace/UISourceCode.ts +20 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +7 -7
- package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +4 -10
- package/front_end/panels/ai_assistance/components/MarkdownRendererWithCodeBlock.ts +25 -5
- package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +2 -3
- package/front_end/panels/common/CommentThreadWidget.ts +221 -0
- package/front_end/{ui/comments → panels/common}/CommentsOverlayWidget.ts +117 -28
- package/front_end/{ui/comments → panels/common}/CommentsStatusBarPill.ts +5 -5
- package/front_end/panels/common/ExtensionServer.ts +2 -1
- package/front_end/panels/common/commentThreadWidget.css +173 -0
- package/front_end/{ui/comments → panels/common}/commentsOverlay.css +8 -1
- package/front_end/{ui/comments/comments-meta.ts → panels/common/common-meta.ts} +11 -11
- package/front_end/panels/common/common.ts +3 -0
- package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +3 -3
- package/front_end/panels/elements/ElementsPanel.ts +5 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +102 -21
- package/front_end/panels/elements/ElementsTreeOutline.ts +326 -91
- package/front_end/panels/elements/EventListenersWidget.ts +0 -1
- package/front_end/panels/elements/PropertiesWidget.ts +11 -10
- package/front_end/panels/elements/PropertyRenderer.ts +29 -25
- package/front_end/panels/elements/StylePropertyTreeElement.ts +6 -6
- package/front_end/panels/elements/elementsTreeOutline.css +7 -1
- package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -3
- package/front_end/panels/event_listeners/EventListenersView.ts +235 -302
- package/front_end/panels/linear_memory_inspector/LinearMemoryInspectorController.ts +6 -7
- package/front_end/panels/linear_memory_inspector/components/linearMemoryInspector.css +5 -1
- package/front_end/panels/linear_memory_inspector/linear_memory_inspector-meta.ts +1 -1
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +10 -2
- package/front_end/panels/network/NetworkConfigView.ts +141 -116
- package/front_end/panels/network/NetworkPanel.ts +7 -4
- package/front_end/panels/network/RequestHeadersView.ts +1 -1
- package/front_end/panels/network/forward/BackendLinking.ts +5 -2
- package/front_end/panels/recorder/stepView.css +1 -0
- package/front_end/panels/security/SecurityPanel.ts +5 -5
- package/front_end/panels/security/SecurityPanelSidebar.ts +2 -11
- package/front_end/panels/settings/BackendLinkingSettingsTab.ts +7 -2
- package/front_end/panels/sources/DebuggerPlugin.ts +1 -1
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +11 -16
- package/front_end/panels/sources/sources-meta.ts +1 -1
- package/front_end/panels/timeline/TimelineTreeView.ts +11 -1
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +0 -3
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/comments/CommentOverlayManager.ts +89 -42
- package/front_end/ui/comments/comments.ts +0 -4
- package/front_end/ui/legacy/Treeoutline.ts +4 -0
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +15 -8
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +4 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +5 -5
|
@@ -41,21 +41,25 @@ If CL B depends on CL A:
|
|
|
41
41
|
2. Develop on branch B.
|
|
42
42
|
3. When uploading B, Gerrit will show the dependency on A.
|
|
43
43
|
|
|
44
|
-
### Reparenting
|
|
45
|
-
If you need to change the base of a branch (e.g., move CL B to be based on `main` instead of CL A):
|
|
44
|
+
### Reparenting & Detaching Landed CLs
|
|
45
|
+
If you need to change the base of a branch back to the root branch (e.g., move CL B to be based on `origin/main` instead of CL A):
|
|
46
46
|
```bash
|
|
47
|
-
git reparent-branch
|
|
47
|
+
git reparent-branch --root
|
|
48
48
|
```
|
|
49
49
|
Or to make it depend on another branch C:
|
|
50
50
|
```bash
|
|
51
51
|
git reparent-branch <branch-C>
|
|
52
52
|
```
|
|
53
|
+
* **Detaching from landed CLs:** When parent CLs in a stack have landed on `main`, first run `git fetch` so `origin/main` includes the landed commits (otherwise reparenting will trigger merge conflicts). Then check out the first unlanded branch in the chain and run `git reparent-branch --root` **before** archiving the landed branches (so `depot_tools` can still resolve the old upstream tracking branch). After reparenting (which automatically runs `git rebase-update`), archive the landed branches (`git cl archive -f`) and run `gclient sync -Df`.
|
|
53
54
|
|
|
54
55
|
### Syncing with Upstream
|
|
55
|
-
To update all your branches with the latest changes from `main` and their respective upstreams:
|
|
56
|
+
To update all your branches with the latest changes from `main` and their respective upstreams, and synchronize dependencies:
|
|
56
57
|
```bash
|
|
57
|
-
git rebase-update
|
|
58
|
+
git rebase-update && gclient sync -Df
|
|
58
59
|
```
|
|
60
|
+
* **Always use `git rebase-update` for stacks:** Never write manual `git checkout && git rebase` loops across stacked branches. `git rebase-update` automatically rebases the entire dependency graph in order.
|
|
61
|
+
* **Clean up old branches first:** Before running `git rebase-update`, archive landed/closed branches (`git cl archive -f`) or mark dormant (`git config branch.<branch>.dormant true`) any obsolete branches so they do not trigger unnecessary rebase conflicts.
|
|
62
|
+
* **Always sync dependencies after rebase:** Always run `gclient sync -Df` after a `git rebase-update`. CIPD dependency updates do not show up in `git status`, so skipping `gclient sync -Df` risks leaving your checkout out of sync.
|
|
59
63
|
|
|
60
64
|
### Initial upload
|
|
61
65
|
When a CL is ready, upload it with:
|
|
@@ -67,12 +71,14 @@ git cl upload -f -d --commit-description="<description>"
|
|
|
67
71
|
* Keep line length below 72
|
|
68
72
|
* Add a "Bug: <issue number>" or "Bug: None" trailer on a separate line.
|
|
69
73
|
* Amend formatter/linter changes and fix linter issues.
|
|
74
|
+
* For a brand new stack of CLs, perform the initial upload on each branch individually in parent-to-child order so each CL receives its own commit description.
|
|
70
75
|
|
|
71
|
-
### Subsequent upload
|
|
76
|
+
### Subsequent upload & Updating Stacks
|
|
72
77
|
To upload an updated CL:
|
|
73
78
|
```bash
|
|
74
79
|
git cl upload -f -d -t "<one sentence patch set description>"
|
|
75
80
|
```
|
|
81
|
+
* **Updating an existing stack of CLs:** Once all CLs in a stack have been initially created, **only run `git cl upload` from the leaf (latest) branch in the chain** for subsequent updates. Uploading from the leaf branch automatically runs presubmit checks and uploads new patchsets for all parent CLs in the stack simultaneously. Never upload intermediate CLs one by one when updating a stack.
|
|
76
82
|
|
|
77
83
|
## Release and Roll Status
|
|
78
84
|
|
|
@@ -87,12 +93,18 @@ To check whether a DevTools commit (`devtools/devtools-frontend`) has rolled int
|
|
|
87
93
|
| Create new CL from main | `git new-branch <name>` |
|
|
88
94
|
| Create stacked CL | `git new-branch --upstream_current <name>` |
|
|
89
95
|
| Update current CL | `git commit --amend` |
|
|
90
|
-
|
|
|
96
|
+
| Initial CL upload | `git cl upload -f -d --commit-description="<description>"` |
|
|
97
|
+
| Subsequent CL upload (or update stack from leaf) | `git cl upload -f -d -t "<message>"` |
|
|
98
|
+
| Reparent branch to root (`origin/main`) | `git reparent-branch --root` |
|
|
91
99
|
| Change branch parent | `git reparent-branch <new-parent>` |
|
|
92
|
-
|
|
|
100
|
+
| Archive landed/closed branches | `git cl archive -f` |
|
|
101
|
+
| Rebase all branches in stack | `git rebase-update` |
|
|
102
|
+
| Sync dependencies after rebase | `gclient sync -Df` |
|
|
93
103
|
| Check release & roll status | Query `https://chromiumdash.appspot.com/fetch_commit?commit=<sha>` |
|
|
94
104
|
|
|
95
105
|
## Common Mistakes
|
|
96
106
|
- **Multiple commits on one branch:** Gerrit expects one commit per CL. Always `commit --amend`.
|
|
97
107
|
- **Using `git checkout -b`:** Does not set up tracking information correctly for `depot_tools`. Use `git new-branch`.
|
|
98
|
-
- **Manual rebasing of stacked branches:**
|
|
108
|
+
- **Manual rebasing of stacked branches:** Never use manual `git rebase` loops. Always use `git rebase-update` or `git reparent-branch` to let `depot_tools` handle tracking updates.
|
|
109
|
+
- **Uploading intermediate branches when updating a stack:** When updating an existing stack of CLs, do not run `git cl upload` on each branch in a chain—uploading from the leaf branch uploads new patchsets for all parent CLs automatically (note: initial uploads must still be done per branch).
|
|
110
|
+
- **Archiving parent branches before reparenting:** Always run `git fetch` and `git reparent-branch --root` on the child branch before archiving a landed parent branch with `git cl archive -f`.
|
package/.stylelintignore
CHANGED
|
@@ -17,7 +17,7 @@ export class VersionController {
|
|
|
17
17
|
static readonly SYNCED_VERSION_SETTING_NAME = 'syncedInspectorVersion';
|
|
18
18
|
static readonly LOCAL_VERSION_SETTING_NAME = 'localInspectorVersion';
|
|
19
19
|
|
|
20
|
-
static readonly CURRENT_VERSION =
|
|
20
|
+
static readonly CURRENT_VERSION = 47;
|
|
21
21
|
|
|
22
22
|
readonly #settings: Settings;
|
|
23
23
|
readonly #globalVersionSetting: Setting<number>;
|
|
@@ -897,6 +897,10 @@ export class VersionController {
|
|
|
897
897
|
}
|
|
898
898
|
}
|
|
899
899
|
|
|
900
|
+
updateVersionFrom46To47(): void {
|
|
901
|
+
this.#settings.syncedStorage.remove('network.backend-linking-rules');
|
|
902
|
+
}
|
|
903
|
+
|
|
900
904
|
/*
|
|
901
905
|
* Any new migration should be added before this comment.
|
|
902
906
|
*
|
|
@@ -4,6 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
import type * as Api from './api/api.js';
|
|
6
6
|
|
|
7
|
+
export type {
|
|
8
|
+
CacheEntry,
|
|
9
|
+
CacheStorageLike,
|
|
10
|
+
HostRuntime,
|
|
11
|
+
ScreenshotOptions,
|
|
12
|
+
Worker,
|
|
13
|
+
WorkerMessageEvent,
|
|
14
|
+
WorkerMessagePort,
|
|
15
|
+
WorkerScope,
|
|
16
|
+
WorkerTransferable,
|
|
17
|
+
} from './api/HostRuntime.js';
|
|
18
|
+
|
|
7
19
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
8
20
|
// @ts-ignore 'process' is not available when type-checking against browser types.
|
|
9
21
|
export const IS_NODE: boolean = typeof (process as unknown) !== 'undefined' && process.versions?.node !== null;
|
|
@@ -13,6 +13,16 @@ export interface ScreenshotOptions {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
export interface CacheEntry {
|
|
17
|
+
put(url: string, response: Response): Promise<void>;
|
|
18
|
+
match(url: string): Promise<Response|undefined>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CacheStorageLike {
|
|
22
|
+
open(name: string): Promise<CacheEntry>;
|
|
23
|
+
delete(name: string): Promise<boolean>;
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
/**
|
|
17
27
|
* Provides abstractions for host features that require different implementations depending
|
|
18
28
|
* on whether DevTools runs in the browser or Node.js
|
|
@@ -23,10 +33,13 @@ export interface HostRuntime {
|
|
|
23
33
|
getOnLine(): boolean;
|
|
24
34
|
getUserAgent(): string;
|
|
25
35
|
getLocalStorage(): Storage|undefined;
|
|
36
|
+
getCacheStorage(): CacheStorageLike|undefined;
|
|
26
37
|
getDevicePixelRatio(): number;
|
|
27
38
|
saveScreenshot(options: ScreenshotOptions): Promise<void>;
|
|
28
39
|
revokeLastScreenshotUrl(): void;
|
|
29
40
|
loadTextFile(url: URL): Promise<string>;
|
|
41
|
+
evaluateCSS(dataValue: string|null, customExpr: string): string|null;
|
|
42
|
+
removeCSSEvaluationElement(): void;
|
|
30
43
|
}
|
|
31
44
|
|
|
32
45
|
/**
|
|
@@ -130,6 +130,8 @@ async function saveScreenshot(options: Api.HostRuntime.ScreenshotOptions): Promi
|
|
|
130
130
|
link.click();
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
let cssEvaluationElement: HTMLElement|null = null;
|
|
134
|
+
|
|
133
135
|
export const HOST_RUNTIME: Api.HostRuntime.HostRuntime = {
|
|
134
136
|
createWorker(url: string): Api.HostRuntime.Worker {
|
|
135
137
|
return new WebWorker(url);
|
|
@@ -145,6 +147,10 @@ export const HOST_RUNTIME: Api.HostRuntime.HostRuntime = {
|
|
|
145
147
|
undefined {
|
|
146
148
|
return 'localStorage' in globalThis ? globalThis.localStorage : undefined;
|
|
147
149
|
},
|
|
150
|
+
getCacheStorage(): Api.HostRuntime.CacheStorageLike |
|
|
151
|
+
undefined {
|
|
152
|
+
return 'caches' in globalThis ? globalThis.caches : undefined;
|
|
153
|
+
},
|
|
148
154
|
getDevicePixelRatio(): number {
|
|
149
155
|
return window.devicePixelRatio;
|
|
150
156
|
},
|
|
@@ -154,4 +160,32 @@ export const HOST_RUNTIME: Api.HostRuntime.HostRuntime = {
|
|
|
154
160
|
const response = await fetch(url);
|
|
155
161
|
return await response.text();
|
|
156
162
|
},
|
|
163
|
+
evaluateCSS(dataValue: string|null, customExpr: string): string |
|
|
164
|
+
null {
|
|
165
|
+
if (!cssEvaluationElement || !cssEvaluationElement.isConnected) {
|
|
166
|
+
cssEvaluationElement = document.getElementById('css-evaluation-element');
|
|
167
|
+
if (!cssEvaluationElement) {
|
|
168
|
+
cssEvaluationElement = document.createElement('div');
|
|
169
|
+
cssEvaluationElement.id = 'css-evaluation-element';
|
|
170
|
+
cssEvaluationElement.setAttribute('style', 'hidden: true; --evaluation: attr(data-custom-expr type(*))');
|
|
171
|
+
|
|
172
|
+
document.body.appendChild(cssEvaluationElement);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (dataValue !== null) {
|
|
177
|
+
cssEvaluationElement.setAttribute('data-value', dataValue);
|
|
178
|
+
} else {
|
|
179
|
+
cssEvaluationElement.removeAttribute('data-value');
|
|
180
|
+
}
|
|
181
|
+
cssEvaluationElement.setAttribute('data-custom-expr', customExpr);
|
|
182
|
+
return cssEvaluationElement.computedStyleMap().get('--evaluation')?.toString() ?? null;
|
|
183
|
+
},
|
|
184
|
+
removeCSSEvaluationElement(): void {
|
|
185
|
+
const element = cssEvaluationElement ?? document.getElementById('css-evaluation-element');
|
|
186
|
+
if (element) {
|
|
187
|
+
element.remove();
|
|
188
|
+
}
|
|
189
|
+
cssEvaluationElement = null;
|
|
190
|
+
},
|
|
157
191
|
};
|
|
@@ -83,6 +83,37 @@ class NodeWorker implements Api.HostRuntime.Worker {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
class NodeCacheEntry implements Api.HostRuntime.CacheEntry {
|
|
87
|
+
readonly #entries = new Map<string, Response>();
|
|
88
|
+
|
|
89
|
+
async put(url: string, response: Response): Promise<void> {
|
|
90
|
+
this.#entries.set(url, response.clone());
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async match(url: string): Promise<Response|undefined> {
|
|
94
|
+
return this.#entries.get(url)?.clone();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
class NodeCacheStorage implements Api.HostRuntime.CacheStorageLike {
|
|
99
|
+
readonly #caches = new Map<string, NodeCacheEntry>();
|
|
100
|
+
|
|
101
|
+
async open(name: string): Promise<Api.HostRuntime.CacheEntry> {
|
|
102
|
+
let cache = this.#caches.get(name);
|
|
103
|
+
if (!cache) {
|
|
104
|
+
cache = new NodeCacheEntry();
|
|
105
|
+
this.#caches.set(name, cache);
|
|
106
|
+
}
|
|
107
|
+
return cache;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async delete(name: string): Promise<boolean> {
|
|
111
|
+
return this.#caches.delete(name);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const nodeCacheStorage = new NodeCacheStorage();
|
|
116
|
+
|
|
86
117
|
export const HOST_RUNTIME: Api.HostRuntime.HostRuntime = {
|
|
87
118
|
createWorker(url: string): Api.HostRuntime.Worker {
|
|
88
119
|
return new NodeWorker(url);
|
|
@@ -98,6 +129,10 @@ export const HOST_RUNTIME: Api.HostRuntime.HostRuntime = {
|
|
|
98
129
|
undefined {
|
|
99
130
|
return undefined;
|
|
100
131
|
},
|
|
132
|
+
getCacheStorage(): Api.HostRuntime.CacheStorageLike |
|
|
133
|
+
undefined {
|
|
134
|
+
return nodeCacheStorage;
|
|
135
|
+
},
|
|
101
136
|
getDevicePixelRatio(): number {
|
|
102
137
|
return 1;
|
|
103
138
|
},
|
|
@@ -106,4 +141,9 @@ export const HOST_RUNTIME: Api.HostRuntime.HostRuntime = {
|
|
|
106
141
|
async loadTextFile(url: URL): Promise<string> {
|
|
107
142
|
return await Fs.promises.readFile(Url.fileURLToPath(url), 'utf-8');
|
|
108
143
|
},
|
|
144
|
+
evaluateCSS(_dataValue: string|null, _customExpr: string): string |
|
|
145
|
+
null {
|
|
146
|
+
return null;
|
|
147
|
+
},
|
|
148
|
+
removeCSSEvaluationElement(): void{},
|
|
109
149
|
};
|
|
@@ -7,6 +7,16 @@ import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
|
|
|
7
7
|
import * as Protocol from '../../generated/protocol.js';
|
|
8
8
|
|
|
9
9
|
import {DeferredDOMNode, type DOMNode} from './DOMModel.js';
|
|
10
|
+
import {
|
|
11
|
+
horizontalScrollRangeInPage,
|
|
12
|
+
removeScrollListenerInPage,
|
|
13
|
+
scrollLeftInPage,
|
|
14
|
+
scrollListenerInPage,
|
|
15
|
+
scrollTopInPage,
|
|
16
|
+
setScrollLeftInPage,
|
|
17
|
+
setScrollTopInPage,
|
|
18
|
+
verticalScrollRangeInPage,
|
|
19
|
+
} from './PageFunctions.js';
|
|
10
20
|
import {RemoteObject} from './RemoteObject.js';
|
|
11
21
|
import {Events as ResourceTreeModelEvents, ResourceTreeModel} from './ResourceTreeModel.js';
|
|
12
22
|
import {Events as RuntimeModelEvents, type EventTypes as RuntimeModelEventTypes, RuntimeModel} from './RuntimeModel.js';
|
|
@@ -127,25 +137,6 @@ export class AnimationDOMNode {
|
|
|
127
137
|
].map(arg => RemoteObject.toCallArgument(arg)));
|
|
128
138
|
object.release();
|
|
129
139
|
return id;
|
|
130
|
-
|
|
131
|
-
function scrollListenerInPage(
|
|
132
|
-
this: HTMLElement|Document, id: number, reportScrollPositionBindingName: string,
|
|
133
|
-
scrollListenerNameInPage: string): void {
|
|
134
|
-
if ('scrollingElement' in this && !this.scrollingElement) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const scrollingElement = ('scrollingElement' in this ? this.scrollingElement : this) as HTMLElement;
|
|
139
|
-
// @ts-expect-error We're setting a custom field on `Element` or `Document` for retaining the function on the page.
|
|
140
|
-
this[scrollListenerNameInPage] = () => {
|
|
141
|
-
// @ts-expect-error `reportScrollPosition` binding is injected to the page before calling the function.
|
|
142
|
-
globalThis[reportScrollPositionBindingName](
|
|
143
|
-
JSON.stringify({scrollTop: scrollingElement.scrollTop, scrollLeft: scrollingElement.scrollLeft, id}));
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// @ts-expect-error We've already defined the function used below.
|
|
147
|
-
this.addEventListener('scroll', this[scrollListenerNameInPage], true);
|
|
148
|
-
}
|
|
149
140
|
}
|
|
150
141
|
|
|
151
142
|
async removeScrollEventListener(id: number): Promise<void> {
|
|
@@ -154,8 +145,8 @@ export class AnimationDOMNode {
|
|
|
154
145
|
return;
|
|
155
146
|
}
|
|
156
147
|
|
|
157
|
-
await object.callFunction(
|
|
158
|
-
|
|
148
|
+
await object.callFunction(removeScrollListenerInPage,
|
|
149
|
+
[getScrollListenerNameInPage(id)].map(arg => RemoteObject.toCallArgument(arg)));
|
|
159
150
|
object.release();
|
|
160
151
|
|
|
161
152
|
this.#scrollListenersById.delete(id);
|
|
@@ -164,107 +155,30 @@ export class AnimationDOMNode {
|
|
|
164
155
|
if (this.#scrollListenersById.size === 0) {
|
|
165
156
|
await this.#removeReportScrollPositionBinding();
|
|
166
157
|
}
|
|
167
|
-
|
|
168
|
-
function removeScrollListenerInPage(this: HTMLElement|Document, scrollListenerNameInPage: string): void {
|
|
169
|
-
// @ts-expect-error We've already set this custom field while adding scroll listener.
|
|
170
|
-
this.removeEventListener('scroll', this[scrollListenerNameInPage]);
|
|
171
|
-
// @ts-expect-error We've already set this custom field while adding scroll listener.
|
|
172
|
-
delete this[scrollListenerNameInPage];
|
|
173
|
-
}
|
|
174
158
|
}
|
|
175
159
|
|
|
176
160
|
async scrollTop(): Promise<number|null> {
|
|
177
161
|
return await this.#domNode.callFunction(scrollTopInPage).then(res => res?.value ?? null);
|
|
178
|
-
|
|
179
|
-
function scrollTopInPage(this: Element|Document): number {
|
|
180
|
-
if ('scrollingElement' in this) {
|
|
181
|
-
if (!this.scrollingElement) {
|
|
182
|
-
return 0;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return this.scrollingElement.scrollTop;
|
|
186
|
-
}
|
|
187
|
-
return this.scrollTop;
|
|
188
|
-
}
|
|
189
162
|
}
|
|
190
163
|
|
|
191
164
|
async scrollLeft(): Promise<number|null> {
|
|
192
165
|
return await this.#domNode.callFunction(scrollLeftInPage).then(res => res?.value ?? null);
|
|
193
|
-
|
|
194
|
-
function scrollLeftInPage(this: Element|Document): number {
|
|
195
|
-
if ('scrollingElement' in this) {
|
|
196
|
-
if (!this.scrollingElement) {
|
|
197
|
-
return 0;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return this.scrollingElement.scrollLeft;
|
|
201
|
-
}
|
|
202
|
-
return this.scrollLeft;
|
|
203
|
-
}
|
|
204
166
|
}
|
|
205
167
|
|
|
206
168
|
async setScrollTop(offset: number): Promise<void> {
|
|
207
169
|
await this.#domNode.callFunction(setScrollTopInPage, [offset]);
|
|
208
|
-
|
|
209
|
-
function setScrollTopInPage(this: Element|Document, offsetInPage: number): void {
|
|
210
|
-
if ('scrollingElement' in this) {
|
|
211
|
-
if (!this.scrollingElement) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
this.scrollingElement.scrollTop = offsetInPage;
|
|
216
|
-
} else {
|
|
217
|
-
this.scrollTop = offsetInPage;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
170
|
}
|
|
221
171
|
|
|
222
172
|
async setScrollLeft(offset: number): Promise<void> {
|
|
223
173
|
await this.#domNode.callFunction(setScrollLeftInPage, [offset]);
|
|
224
|
-
|
|
225
|
-
function setScrollLeftInPage(this: Element|Document, offsetInPage: number): void {
|
|
226
|
-
if ('scrollingElement' in this) {
|
|
227
|
-
if (!this.scrollingElement) {
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
this.scrollingElement.scrollLeft = offsetInPage;
|
|
232
|
-
} else {
|
|
233
|
-
this.scrollLeft = offsetInPage;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
174
|
}
|
|
237
175
|
|
|
238
176
|
async verticalScrollRange(): Promise<number|null> {
|
|
239
177
|
return await this.#domNode.callFunction(verticalScrollRangeInPage).then(res => res?.value ?? null);
|
|
240
|
-
|
|
241
|
-
function verticalScrollRangeInPage(this: Element|Document): number {
|
|
242
|
-
if ('scrollingElement' in this) {
|
|
243
|
-
if (!this.scrollingElement) {
|
|
244
|
-
return 0;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
return this.scrollingElement.scrollHeight - this.scrollingElement.clientHeight;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
return this.scrollHeight - this.clientHeight;
|
|
251
|
-
}
|
|
252
178
|
}
|
|
253
179
|
|
|
254
180
|
async horizontalScrollRange(): Promise<number|null> {
|
|
255
181
|
return await this.#domNode.callFunction(horizontalScrollRangeInPage).then(res => res?.value ?? null);
|
|
256
|
-
|
|
257
|
-
function horizontalScrollRangeInPage(this: Element|Document): number {
|
|
258
|
-
if ('scrollingElement' in this) {
|
|
259
|
-
if (!this.scrollingElement) {
|
|
260
|
-
return 0;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return this.scrollingElement.scrollWidth - this.scrollingElement.clientWidth;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return this.scrollWidth - this.clientWidth;
|
|
267
|
-
}
|
|
268
182
|
}
|
|
269
183
|
}
|
|
270
184
|
|
|
@@ -920,7 +834,15 @@ export class AnimationGroup {
|
|
|
920
834
|
}
|
|
921
835
|
|
|
922
836
|
seekTo(currentTime: number): void {
|
|
923
|
-
|
|
837
|
+
const animations = [];
|
|
838
|
+
const currentTimes = [];
|
|
839
|
+
for (const animation of this.#animations) {
|
|
840
|
+
// Seek from the end of the animation if it is reversed.
|
|
841
|
+
animations.push(animation.id());
|
|
842
|
+
currentTimes.push(animation.playbackRate() >= 0 ? currentTime :
|
|
843
|
+
animation.endTime() - animation.startTime() - currentTime);
|
|
844
|
+
}
|
|
845
|
+
void this.#animationModel.agent.invoke_seekAnimations({animations, currentTimes});
|
|
924
846
|
}
|
|
925
847
|
|
|
926
848
|
paused(): boolean {
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from './ResourceTreeModel.js';
|
|
28
28
|
import {SDKModel} from './SDKModel.js';
|
|
29
29
|
import {cssSourceMapsEnabledSettingDescriptor} from './SDKSettings.js';
|
|
30
|
+
import {SourceMapProvenance} from './SourceMap.js';
|
|
30
31
|
import {SourceMapManager} from './SourceMapManager.js';
|
|
31
32
|
import {Capability, type Target} from './Target.js';
|
|
32
33
|
|
|
@@ -784,7 +785,8 @@ export class CSSModel extends SDKModel<EventTypes> {
|
|
|
784
785
|
}
|
|
785
786
|
styleSheetIds.add(styleSheetHeader.id);
|
|
786
787
|
}
|
|
787
|
-
this.#sourceMapManager.attachSourceMap(styleSheetHeader, styleSheetHeader.sourceURL, styleSheetHeader.sourceMapURL
|
|
788
|
+
this.#sourceMapManager.attachSourceMap(styleSheetHeader, styleSheetHeader.sourceURL, styleSheetHeader.sourceMapURL,
|
|
789
|
+
SourceMapProvenance.CDP);
|
|
788
790
|
this.dispatchEventToListeners(Events.StyleSheetAdded, styleSheetHeader);
|
|
789
791
|
}
|
|
790
792
|
|
|
@@ -846,7 +848,7 @@ export class CSSModel extends SDKModel<EventTypes> {
|
|
|
846
848
|
|
|
847
849
|
this.#sourceMapManager.detachSourceMap(header);
|
|
848
850
|
header.setSourceMapURL(sourceMapURL);
|
|
849
|
-
this.#sourceMapManager.attachSourceMap(header, header.sourceURL, header.sourceMapURL);
|
|
851
|
+
this.#sourceMapManager.attachSourceMap(header, header.sourceURL, header.sourceMapURL, SourceMapProvenance.CDP);
|
|
850
852
|
if (sourceMapURL === null) {
|
|
851
853
|
return 'Error in CSS.setStyleSheetText';
|
|
852
854
|
}
|
|
@@ -497,8 +497,10 @@ export class ComputedText {
|
|
|
497
497
|
* ignored for the spacing requirement.
|
|
498
498
|
**/
|
|
499
499
|
export function requiresSpace(a: string, b: string): boolean;
|
|
500
|
-
export function requiresSpace(a:
|
|
501
|
-
|
|
500
|
+
export function requiresSpace(a: Array<{textContent?: string | null}>,
|
|
501
|
+
b: Array<{textContent?: string | null}>): boolean;
|
|
502
|
+
export function requiresSpace(a: Array<{textContent?: string | null}>|string|undefined,
|
|
503
|
+
b: Array<{textContent?: string | null}>|string|undefined): boolean {
|
|
502
504
|
const tail = Array.isArray(a) ? a.findLast(node => node.textContent)?.textContent : a;
|
|
503
505
|
const head = Array.isArray(b) ? b.find(node => node.textContent)?.textContent : b;
|
|
504
506
|
const trailingChar = tail ? tail[tail.length - 1] : '';
|
|
@@ -510,8 +512,6 @@ export function requiresSpace(a: Node[]|string|undefined, b: Node[]|string|undef
|
|
|
510
512
|
!noSpaceBefore.includes(leadingChar);
|
|
511
513
|
}
|
|
512
514
|
|
|
513
|
-
export const CSSControlMap: MapConstructor = Map;
|
|
514
|
-
export type CSSControlMap = Map<string, HTMLElement[]>;
|
|
515
515
|
export namespace ASTUtils {
|
|
516
516
|
export function siblings(node: CodeMirror.SyntaxNode|null): CodeMirror.SyntaxNode[] {
|
|
517
517
|
const result = [];
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// Copyright 2023 The Chromium Authors
|
|
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
|
-
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
5
4
|
|
|
6
5
|
import * as Common from '../../core/common/common.js';
|
|
7
|
-
import
|
|
6
|
+
import * as Platform from '../../core/platform/platform.js';
|
|
8
7
|
import type * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
|
|
9
8
|
|
|
10
9
|
import type {CSSMatchedStyles, CSSValueSource, CSSVariableValue} from './CSSMatchedStyles.js';
|
|
@@ -212,33 +211,6 @@ export class AttributeMatch extends BaseVariableMatch {
|
|
|
212
211
|
}
|
|
213
212
|
}
|
|
214
213
|
|
|
215
|
-
let cssEvaluationElement: HTMLElement|null = null;
|
|
216
|
-
function getCssEvaluationElement(): HTMLElement {
|
|
217
|
-
const id = 'css-evaluation-element';
|
|
218
|
-
if (!cssEvaluationElement) {
|
|
219
|
-
cssEvaluationElement = document.getElementById(id);
|
|
220
|
-
if (!cssEvaluationElement) {
|
|
221
|
-
cssEvaluationElement = document.createElement('div');
|
|
222
|
-
cssEvaluationElement.setAttribute('id', id);
|
|
223
|
-
cssEvaluationElement.setAttribute('style', 'hidden: true; --evaluation: attr(data-custom-expr type(*))');
|
|
224
|
-
document.body.appendChild(cssEvaluationElement);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
return cssEvaluationElement;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* If a test calls localEvalCSS, an element is created on demand for this
|
|
232
|
-
* purpose. This element is not removed from the DOM and will leak between tests
|
|
233
|
-
* if not removed.
|
|
234
|
-
*/
|
|
235
|
-
export function removeCSSEvaluationElement(): void {
|
|
236
|
-
if (cssEvaluationElement) {
|
|
237
|
-
document.body.removeChild(cssEvaluationElement);
|
|
238
|
-
cssEvaluationElement = null;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
214
|
/**
|
|
243
215
|
* These functions use an element in the frontend to evaluate CSS. The advantage
|
|
244
216
|
* of this is that it is synchronous and doesn't require a CDP method. The
|
|
@@ -249,10 +221,7 @@ export function removeCSSEvaluationElement(): void {
|
|
|
249
221
|
* substitutions (but not for actual evaluation) and for applying units.
|
|
250
222
|
**/
|
|
251
223
|
export function localEvalCSS(value: string, type: string): string|null {
|
|
252
|
-
|
|
253
|
-
element.setAttribute('data-value', value);
|
|
254
|
-
element.setAttribute('data-custom-expr', `attr(data-value ${type})`);
|
|
255
|
-
return element.computedStyleMap().get('--evaluation')?.toString() ?? null;
|
|
224
|
+
return Platform.HostRuntime.HOST_RUNTIME.evaluateCSS(value, `attr(data-value ${type})`);
|
|
256
225
|
}
|
|
257
226
|
|
|
258
227
|
/**
|
|
@@ -261,15 +230,11 @@ export function localEvalCSS(value: string, type: string): string|null {
|
|
|
261
230
|
* raw string, returning '' if the attribute is not set.
|
|
262
231
|
**/
|
|
263
232
|
export function isValidCSSType(type: string): boolean {
|
|
264
|
-
|
|
265
|
-
element.setAttribute('data-custom-expr', `attr(data-nonexistent ${type}, "good")`);
|
|
266
|
-
return '"good"' === (element.computedStyleMap().get('--evaluation')?.toString() ?? null);
|
|
233
|
+
return '"good"' === Platform.HostRuntime.HOST_RUNTIME.evaluateCSS(null, `attr(data-nonexistent ${type}, "good")`);
|
|
267
234
|
}
|
|
268
235
|
|
|
269
236
|
export function defaultValueForCSSType(type: string|null): string|null {
|
|
270
|
-
|
|
271
|
-
element.setAttribute('data-custom-expr', `attr(data-nonexistent ${type ?? ''})`);
|
|
272
|
-
return element.computedStyleMap().get('--evaluation')?.toString() ?? null;
|
|
237
|
+
return Platform.HostRuntime.HOST_RUNTIME.evaluateCSS(null, `attr(data-nonexistent ${type ?? ''})`);
|
|
273
238
|
}
|
|
274
239
|
|
|
275
240
|
export const RAW_STRING_TYPE = 'raw-string';
|
|
@@ -371,11 +336,6 @@ export class TextMatch implements Match {
|
|
|
371
336
|
this.computedText = () => '';
|
|
372
337
|
}
|
|
373
338
|
}
|
|
374
|
-
render(): Node[] {
|
|
375
|
-
const span = document.createElement('span');
|
|
376
|
-
span.appendChild(document.createTextNode(this.text));
|
|
377
|
-
return [span];
|
|
378
|
-
}
|
|
379
339
|
}
|
|
380
340
|
|
|
381
341
|
const TextMatcherBase: MatcherClass<TextMatch> = matcherBase(TextMatch);
|
|
@@ -16,6 +16,11 @@ const UIStrings = {
|
|
|
16
16
|
* @description Text on the remote debugging window to indicate the connection is lost.
|
|
17
17
|
*/
|
|
18
18
|
websocketDisconnected: 'WebSocket disconnected',
|
|
19
|
+
/**
|
|
20
|
+
* @description Text in the remote debugging terminated dialog when the WebSocket connection fails, instructing the user to check the --remote-allow-origins flag on the Chrome instance.
|
|
21
|
+
*/
|
|
22
|
+
websocketConnectionFailed:
|
|
23
|
+
'WebSocket disconnected. Make sure `--remote-allow-origins` on the Chrome instance allows the current origin.',
|
|
19
24
|
} as const;
|
|
20
25
|
const str_ = i18n.i18n.registerUIStrings('core/sdk/Connections.ts', UIStrings);
|
|
21
26
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -114,7 +119,7 @@ export class WebSocketTransport implements ProtocolClient.ConnectionTransport.Co
|
|
|
114
119
|
|
|
115
120
|
private onError(): void {
|
|
116
121
|
if (this.#onWebSocketDisconnect) {
|
|
117
|
-
this.#onWebSocketDisconnect.call(null, i18nString(UIStrings.
|
|
122
|
+
this.#onWebSocketDisconnect.call(null, i18nString(UIStrings.websocketConnectionFailed));
|
|
118
123
|
}
|
|
119
124
|
if (this.#onDisconnect) {
|
|
120
125
|
// This is called if error occurred while connecting.
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
LOGPOINT_SOURCE_URL,
|
|
19
19
|
} from './DebuggerModel.js';
|
|
20
20
|
import {LogModel} from './LogModel.js';
|
|
21
|
+
import {saveVariable} from './PageFunctions.js';
|
|
21
22
|
import {RemoteObject} from './RemoteObject.js';
|
|
22
23
|
import {
|
|
23
24
|
Events as ResourceTreeModelEvents,
|
|
@@ -458,18 +459,6 @@ export class ConsoleModel extends SDKModel<EventTypes> {
|
|
|
458
459
|
if (callFunctionResult.object) {
|
|
459
460
|
callFunctionResult.object.release();
|
|
460
461
|
}
|
|
461
|
-
|
|
462
|
-
function saveVariable(this: Window, value: Protocol.Runtime.CallArgument): string {
|
|
463
|
-
const prefix = 'temp';
|
|
464
|
-
let index = 1;
|
|
465
|
-
while ((prefix + index) in this) {
|
|
466
|
-
++index;
|
|
467
|
-
}
|
|
468
|
-
const name = prefix + index;
|
|
469
|
-
// @ts-expect-error Assignment to global object
|
|
470
|
-
this[name] = value;
|
|
471
|
-
return name;
|
|
472
|
-
}
|
|
473
462
|
}
|
|
474
463
|
}
|
|
475
464
|
|