chrome-devtools-frontend 1.0.1672557 → 1.0.1675430
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/devtools-ux-writing-refactor/SKILL.md +26 -9
- package/front_end/core/common/ParsedURL.ts +5 -1
- package/front_end/core/common/SettingRegistration.ts +30 -34
- package/front_end/core/common/Settings.ts +4 -64
- package/front_end/core/host/UserMetrics.ts +127 -117
- package/front_end/core/protocol_client/PuppeteerDevToolsConnection.ts +42 -9
- package/front_end/core/root/Runtime.ts +14 -0
- package/front_end/core/sdk/NetworkManager.ts +0 -35
- package/front_end/core/sdk/SourceMap.ts +1 -19
- package/front_end/core/sdk/SourceMapManager.ts +75 -48
- package/front_end/core/sdk/SourceMapScopesInfo.ts +0 -62
- package/front_end/core/sdk/TargetManager.ts +18 -0
- package/front_end/devtools_compatibility.js +1 -1
- package/front_end/entrypoints/main/MainImpl.ts +1 -0
- package/front_end/foundation/Universe.ts +44 -29
- package/front_end/generated/InspectorBackendCommands.ts +4 -3
- package/front_end/generated/SupportedCSSProperties.ts +16 -1
- package/front_end/generated/protocol-mapping.d.ts +8 -0
- package/front_end/generated/protocol-proxy-api.d.ts +6 -0
- package/front_end/generated/protocol.ts +16 -2
- package/front_end/models/ai_assistance/AiSetting.ts +66 -3
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +15 -5
- package/front_end/models/bindings/CompilerScriptMapping.ts +1 -1
- package/front_end/models/emulation/DeviceModeModel.ts +82 -102
- package/front_end/models/emulation/EmulatedDevices.ts +18 -66
- package/front_end/models/javascript_metadata/NativeFunctions.js +4 -4
- package/front_end/models/persistence/AutomaticFileSystemManager.ts +2 -2
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +20 -29
- package/front_end/models/trace/ModelImpl.ts +5 -0
- package/front_end/models/trace/Processor.ts +5 -0
- package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +7 -1
- package/front_end/models/trace/handlers/MetaHandler.ts +8 -4
- package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +11 -0
- package/front_end/models/workspace/FileManager.ts +13 -6
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -10
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +3 -45
- package/front_end/panels/application/BackgroundServiceView.ts +42 -40
- package/front_end/panels/application/KeyValueStorageItemsView.ts +1 -0
- package/front_end/panels/application/WebMCPView.ts +13 -5
- package/front_end/panels/application/components/AdsView.ts +24 -1
- package/front_end/panels/application/components/adsView.css +27 -21
- package/front_end/panels/autofill/AutofillView.ts +12 -12
- package/front_end/panels/autofill/autofill-meta.ts +2 -2
- package/front_end/panels/common/ExtensionServer.ts +7 -1
- package/front_end/panels/common/common.ts +0 -1
- package/front_end/panels/console/ConsoleInsightTeaser.ts +7 -6
- package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
- package/front_end/panels/elements/ClassesPaneWidget.ts +2 -2
- package/front_end/panels/elements/ElementsTreeElement.ts +602 -327
- package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +1 -1
- package/front_end/panels/elements/components/AdornerManager.ts +1 -0
- package/front_end/panels/emulation/AdvancedApp.ts +3 -3
- package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -11
- package/front_end/panels/emulation/DeviceModeView.ts +234 -75
- package/front_end/panels/emulation/InspectedPagePlaceholder.ts +1 -1
- package/front_end/panels/emulation/deviceModeView.css +4 -21
- package/front_end/panels/emulation/emulation-meta.ts +4 -30
- package/front_end/panels/emulation/emulation.ts +0 -3
- package/front_end/panels/explain/components/ConsoleInsight.ts +11 -7
- package/front_end/panels/js_timeline/js_timeline-meta.ts +8 -8
- package/front_end/panels/layer_viewer/LayerDetailsView.ts +30 -30
- package/front_end/panels/layer_viewer/LayerTreeOutline.ts +6 -6
- package/front_end/panels/layer_viewer/LayerViewHost.ts +1 -1
- package/front_end/panels/layer_viewer/Layers3DView.ts +11 -11
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +8 -8
- package/front_end/panels/layer_viewer/TransformController.ts +3 -3
- package/front_end/panels/layer_viewer/layer_viewer-meta.ts +11 -11
- package/front_end/panels/layers/LayersPanel.ts +2 -2
- package/front_end/panels/layers/layers-meta.ts +2 -2
- package/front_end/panels/lighthouse/LighthouseController.ts +3 -7
- package/front_end/panels/mobile_throttling/CPUThrottlingSelector.ts +313 -0
- package/front_end/panels/mobile_throttling/NetworkPanelIndicator.ts +0 -10
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +21 -10
- package/front_end/panels/mobile_throttling/ThrottlingManager.ts +1 -58
- package/front_end/panels/mobile_throttling/mobile_throttling.ts +2 -9
- package/front_end/panels/network/NetworkConfigView.ts +1 -71
- package/front_end/panels/network/networkConfigView.css +1 -2
- package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +3 -3
- package/front_end/panels/profiler/HeapDetachedElementsView.ts +5 -5
- package/front_end/panels/profiler/HeapProfileView.ts +32 -32
- package/front_end/panels/profiler/HeapProfilerPanel.ts +2 -2
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +33 -37
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +26 -27
- package/front_end/panels/profiler/HeapSnapshotView.ts +48 -48
- package/front_end/panels/profiler/IsolateSelector.ts +10 -10
- package/front_end/panels/profiler/ModuleUIStrings.ts +25 -25
- package/front_end/panels/profiler/ProfileLauncherView.ts +6 -6
- package/front_end/panels/profiler/ProfilesPanel.ts +6 -6
- package/front_end/panels/profiler/WritableProfileHeader.ts +6 -6
- package/front_end/panels/profiler/profiler-meta.ts +7 -7
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +7 -0
- package/front_end/panels/recorder/RecorderPanel.ts +1 -1
- package/front_end/panels/settings/AISettingsTab.ts +27 -23
- package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -2
- package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +12 -17
- package/front_end/panels/timeline/TimelinePanel.ts +20 -35
- package/front_end/panels/timeline/components/LiveMetricsView.ts +27 -6
- package/front_end/panels/timeline/components/NetworkTrackWidget.ts +1 -1
- package/front_end/panels/timeline/components/components.ts +0 -4
- package/front_end/panels/timeline/components/liveMetricsView.css +7 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/CONTRIBUTING.md +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/LICENSE +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/README.md +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/deno.json +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/package.json +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js +2 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js.map +1 -1
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.ts +2 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/codec.js +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/codec.js.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/codec.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/mod.js +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/mod.js.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/mod.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/scopes.js +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/scopes.js.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/scopes.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/util.js +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/util.js.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/util.ts +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js.map +0 -0
- package/front_end/third_party/source-map-scopes-codec/package/src/vlq.ts +0 -0
- package/front_end/ui/comments/CommentAnchorResolver.ts +132 -0
- package/front_end/ui/comments/comments.ts +9 -0
- package/front_end/ui/components/dialogs/ShortcutDialog.ts +2 -0
- package/front_end/ui/components/settings/SettingCheckbox.ts +4 -12
- package/front_end/ui/components/settings/settingCheckbox.css +0 -7
- package/front_end/ui/legacy/Treeoutline.ts +14 -14
- package/front_end/ui/legacy/UIUtils.ts +2 -47
- package/front_end/ui/legacy/Widget.ts +10 -2
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +40 -0
- package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +1 -1
- package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -0
- package/front_end/ui/lit/Directives.ts +80 -0
- package/front_end/ui/lit/lit.ts +1 -0
- package/front_end/ui/lit/render.ts +8 -0
- package/front_end/ui/settings/SettingUIRegistration.ts +4 -0
- package/front_end/ui/visual_logging/Debugging.ts +1 -5
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/front_end/ui/visual_logging/LoggingConfig.ts +21 -0
- package/front_end/ui/visual_logging/visual_logging.ts +9 -0
- package/mcp/mcp.ts +1 -0
- package/package.json +1 -1
- package/front_end/panels/common/ThrottlingUtils.ts +0 -51
- package/front_end/panels/emulation/DeviceModeWrapper.ts +0 -248
- package/front_end/panels/mobile_throttling/MobileThrottlingSelector.ts +0 -92
- package/front_end/panels/timeline/components/CPUThrottlingSelector.ts +0 -235
- package/front_end/panels/timeline/components/NetworkThrottlingSelector.ts +0 -245
- package/front_end/panels/timeline/components/cpuThrottlingSelector.css +0 -30
- package/front_end/panels/timeline/components/networkThrottlingSelector.css +0 -24
|
@@ -5,11 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
import * as Lit from '../../third_party/lit/lit.js';
|
|
7
7
|
|
|
8
|
+
import {InterceptBindingDirective} from './Directives.js';
|
|
9
|
+
|
|
8
10
|
export interface RenderOptions extends Lit.RenderOptions {
|
|
9
11
|
container?: {
|
|
10
12
|
attributes?: Record<string, string|null|boolean|undefined|{toString(): string}>,
|
|
11
13
|
classes?: string[],
|
|
12
14
|
listeners?: Record<string, EventListenerOrEventListenerObject>,
|
|
15
|
+
interceptedListeners?: Record<string, EventListenerOrEventListenerObject>,
|
|
13
16
|
};
|
|
14
17
|
}
|
|
15
18
|
|
|
@@ -112,6 +115,11 @@ export function render(template: unknown, container: HTMLElement|DocumentFragmen
|
|
|
112
115
|
listenersMap.delete(name);
|
|
113
116
|
}
|
|
114
117
|
}
|
|
118
|
+
|
|
119
|
+
if (host instanceof Element) {
|
|
120
|
+
InterceptBindingDirective.registerListeners(host, options?.container?.interceptedListeners);
|
|
121
|
+
}
|
|
122
|
+
|
|
115
123
|
renderOptions.set(container, options);
|
|
116
124
|
return Lit.render(template, container, options);
|
|
117
125
|
}
|
|
@@ -51,6 +51,7 @@ export function register(
|
|
|
51
51
|
if (registeredSettings.has(settingName)) {
|
|
52
52
|
throw new Error(`Duplicate setting name '${settingName}'`);
|
|
53
53
|
}
|
|
54
|
+
Common.SettingRegistration.registerCategoryOrder(settingUIDescriptor.category, settingUIDescriptor.order);
|
|
54
55
|
registeredSettings.set(settingName, {descriptor: settingDescriptor, uiDescriptor: settingUIDescriptor});
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -98,5 +99,8 @@ export function resolve(settingDescriptor: Common.Settings.SettingDescriptor<unk
|
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
export function resetSettings(): void {
|
|
102
|
+
for (const {uiDescriptor} of registeredSettings.values()) {
|
|
103
|
+
Common.SettingRegistration.removeCategoryOrder(uiDescriptor.category, uiDescriptor.order);
|
|
104
|
+
}
|
|
101
105
|
registeredSettings.clear();
|
|
102
106
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import {assertNotNullOrUndefined} from '../../core/platform/platform.js';
|
|
7
7
|
|
|
8
8
|
import type {Loggable} from './Loggable.js';
|
|
9
|
-
import {type LoggingConfig, VisualElements} from './LoggingConfig.js';
|
|
9
|
+
import {elementKey, type LoggingConfig, VisualElements} from './LoggingConfig.js';
|
|
10
10
|
import {getLoggingState, type LoggingState} from './LoggingState.js';
|
|
11
11
|
|
|
12
12
|
let veDebuggingEnabled = false;
|
|
@@ -406,10 +406,6 @@ function processImpressionsForAdHocAnalysisDebugLog(states: LoggingState[]): voi
|
|
|
406
406
|
}
|
|
407
407
|
}
|
|
408
408
|
|
|
409
|
-
function elementKey(config: LoggingConfig): string {
|
|
410
|
-
return `${VisualElements[config.ve]}${config.context ? `: ${config.context}` : ''}`;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
409
|
export function debugString(config: LoggingConfig): string {
|
|
414
410
|
const components = [VisualElements[config.ve]];
|
|
415
411
|
if (config.context) {
|
|
@@ -2126,6 +2126,7 @@ export const knownContextValues = new Set([
|
|
|
2126
2126
|
'integer-8-bit',
|
|
2127
2127
|
'interactions',
|
|
2128
2128
|
'interactivity',
|
|
2129
|
+
'interest',
|
|
2129
2130
|
'interest-delay',
|
|
2130
2131
|
'interest-delay-end',
|
|
2131
2132
|
'interest-delay-start',
|
|
@@ -3237,6 +3238,7 @@ export const knownContextValues = new Set([
|
|
|
3237
3238
|
'protocol',
|
|
3238
3239
|
'protocol-handlers',
|
|
3239
3240
|
'protocol-monitor',
|
|
3241
|
+
'protocol-monitor-columns',
|
|
3240
3242
|
'protocol-monitor-documentation',
|
|
3241
3243
|
'protocol-monitor.add-custom-property',
|
|
3242
3244
|
'protocol-monitor.add-parameter',
|
|
@@ -4052,6 +4054,7 @@ export const knownContextValues = new Set([
|
|
|
4052
4054
|
'text-combine-upright',
|
|
4053
4055
|
'text-decoration',
|
|
4054
4056
|
'text-decoration-color',
|
|
4057
|
+
'text-decoration-inset',
|
|
4055
4058
|
'text-decoration-line',
|
|
4056
4059
|
'text-decoration-skip-ink',
|
|
4057
4060
|
'text-decoration-skip-spaces',
|
|
@@ -27,6 +27,27 @@ export interface LoggingConfig {
|
|
|
27
27
|
parent?: string;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
export function elementKey(config: LoggingConfig): string {
|
|
31
|
+
return `${VisualElements[config.ve]}${config.context ? `: ${config.context}` : ''}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function getVePath(element: Element): string {
|
|
35
|
+
const parts: string[] = [];
|
|
36
|
+
let current: Element|null = element;
|
|
37
|
+
while (current) {
|
|
38
|
+
if (needsLogging(current)) {
|
|
39
|
+
try {
|
|
40
|
+
const config = getLoggingConfig(current);
|
|
41
|
+
parts.unshift(elementKey(config));
|
|
42
|
+
} catch {
|
|
43
|
+
// Skip invalid logging configs
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
current = current.parentElementOrShadowHost();
|
|
47
|
+
}
|
|
48
|
+
return parts.join(' > ');
|
|
49
|
+
}
|
|
50
|
+
|
|
30
51
|
export function needsLogging(element: Element): boolean {
|
|
31
52
|
return element.hasAttribute(LOGGING_ATTRIBUTE);
|
|
32
53
|
}
|
|
@@ -11,6 +11,15 @@ import * as NonDomState from './NonDomState.js';
|
|
|
11
11
|
|
|
12
12
|
export type Loggable = LoggableModule.Loggable;
|
|
13
13
|
export {DebugLoggingFormat, setVeDebuggingEnabled, setVeDebugLoggingEnabled} from './Debugging.js';
|
|
14
|
+
export {
|
|
15
|
+
elementKey,
|
|
16
|
+
getLoggingConfig,
|
|
17
|
+
getVePath,
|
|
18
|
+
type LoggingConfig,
|
|
19
|
+
needsLogging,
|
|
20
|
+
parseJsLog,
|
|
21
|
+
VisualElements,
|
|
22
|
+
} from './LoggingConfig.js';
|
|
14
23
|
export {addDocument, startLogging, stopLogging} from './LoggingDriver.js';
|
|
15
24
|
export {logImpressions, logSettingAccess, logFunctionCall} from './LoggingEvents.js';
|
|
16
25
|
export const logClick = (loggable: Loggable, event: Event, options: {doubleClick?: boolean} = {}): void =>
|
package/mcp/mcp.ts
CHANGED
|
@@ -26,6 +26,7 @@ export {PuppeteerDevToolsConnection} from '../front_end/core/protocol_client/Pup
|
|
|
26
26
|
export {DebuggerModel} from '../front_end/core/sdk/DebuggerModel.js';
|
|
27
27
|
export * as NetworkManager from '../front_end/core/sdk/NetworkManager.js';
|
|
28
28
|
export {RuntimeModel} from '../front_end/core/sdk/RuntimeModel.js';
|
|
29
|
+
export * as SourceMapManager from '../front_end/core/sdk/SourceMapManager.js';
|
|
29
30
|
export {Target} from '../front_end/core/sdk/Target.js';
|
|
30
31
|
export {TargetManager} from '../front_end/core/sdk/TargetManager.js';
|
|
31
32
|
export * as Foundation from '../front_end/foundation/foundation.js';
|
package/package.json
CHANGED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 The Chromium Authors
|
|
2
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
-
// found in the LICENSE file.
|
|
4
|
-
|
|
5
|
-
import * as SDK from '../../core/sdk/sdk.js';
|
|
6
|
-
import * as CrUXManager from '../../models/crux-manager/crux-manager.js';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
CalibratedMidTierMobileThrottlingOption,
|
|
10
|
-
type CPUThrottlingOption,
|
|
11
|
-
MidTierThrottlingOption,
|
|
12
|
-
} from './CPUThrottlingOption.js';
|
|
13
|
-
|
|
14
|
-
export interface ThrottlingRecommendations {
|
|
15
|
-
cpuOption: CPUThrottlingOption|null;
|
|
16
|
-
networkConditions: SDK.NetworkManager.Conditions|null;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Computes the recommended CPU and network throttling presets based on CrUX
|
|
21
|
-
* field metric data.
|
|
22
|
-
*/
|
|
23
|
-
export function getThrottlingRecommendations(): ThrottlingRecommendations {
|
|
24
|
-
const cruxManager = CrUXManager.CrUXManager.instance();
|
|
25
|
-
const roundTripTimeMetricData = cruxManager.getSelectedFieldMetricData('round_trip_time');
|
|
26
|
-
|
|
27
|
-
let cpuOption: CPUThrottlingOption = CalibratedMidTierMobileThrottlingOption;
|
|
28
|
-
if (cpuOption.rate() === 0) {
|
|
29
|
-
cpuOption = MidTierThrottlingOption;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const networkConditions = getRecommendedNetworkConditions(roundTripTimeMetricData);
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
cpuOption,
|
|
36
|
-
networkConditions,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Computes the recommended network throttling preset based on CrUX RTT field
|
|
42
|
-
* metric data. Returns null if no RTT data is available or no preset matches.
|
|
43
|
-
*/
|
|
44
|
-
export function getRecommendedNetworkConditions(roundTripTimeMetricData?: CrUXManager.MetricResponse):
|
|
45
|
-
SDK.NetworkManager.Conditions|null {
|
|
46
|
-
if (roundTripTimeMetricData?.percentiles) {
|
|
47
|
-
const rtt = Number(roundTripTimeMetricData.percentiles.p75);
|
|
48
|
-
return SDK.NetworkManager.getRecommendedNetworkPreset(rtt);
|
|
49
|
-
}
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
// Copyright 2016 The Chromium Authors
|
|
2
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
-
// found in the LICENSE file.
|
|
4
|
-
|
|
5
|
-
import type * as Common from '../../core/common/common.js';
|
|
6
|
-
import * as Root from '../../core/root/root.js';
|
|
7
|
-
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
|
-
import type * as Protocol from '../../generated/protocol.js';
|
|
9
|
-
import * as EmulationModel from '../../models/emulation/emulation.js';
|
|
10
|
-
import * as Geometry from '../../models/geometry/geometry.js';
|
|
11
|
-
import * as UI from '../../ui/legacy/legacy.js';
|
|
12
|
-
import {html, render} from '../../ui/lit/lit.js';
|
|
13
|
-
|
|
14
|
-
import {DeviceModeView} from './DeviceModeView.js';
|
|
15
|
-
import {InspectedPagePlaceholder} from './InspectedPagePlaceholder.js';
|
|
16
|
-
|
|
17
|
-
const {widget} = UI.Widget;
|
|
18
|
-
interface ViewInput {
|
|
19
|
-
showDeviceMode: boolean;
|
|
20
|
-
}
|
|
21
|
-
type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
|
|
22
|
-
export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
23
|
-
// clang-format off
|
|
24
|
-
render(input.showDeviceMode ?
|
|
25
|
-
html`<devtools-widget ${widget(DeviceModeView)}>
|
|
26
|
-
${widget(() => InspectedPagePlaceholder.instance(), {minimumSize: new Geometry.Size(1, 1)})}
|
|
27
|
-
</devtools-widget>` :
|
|
28
|
-
widget(() => InspectedPagePlaceholder.instance(), {minimumSize: new Geometry.Size(150, 150)}),
|
|
29
|
-
target);
|
|
30
|
-
// clang-format on
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export class DeviceModeWrapper extends UI.Widget.VBox {
|
|
34
|
-
private readonly toggleDeviceModeAction: UI.ActionRegistration.Action;
|
|
35
|
-
private showDeviceModeSetting: Common.Settings.Setting<boolean>;
|
|
36
|
-
readonly #view: View;
|
|
37
|
-
|
|
38
|
-
constructor(element?: HTMLElement, view = DEFAULT_VIEW) {
|
|
39
|
-
super(element);
|
|
40
|
-
this.#view = view;
|
|
41
|
-
this.toggleDeviceModeAction = UI.ActionRegistry.ActionRegistry.instance().getAction('emulation.toggle-device-mode');
|
|
42
|
-
const model = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
|
|
43
|
-
this.showDeviceModeSetting = model.enabledSetting();
|
|
44
|
-
this.showDeviceModeSetting.setRequiresUserAction(Boolean(Root.Runtime.Runtime.queryParam('hasOtherClients')));
|
|
45
|
-
this.showDeviceModeSetting.addChangeListener(this.requestUpdate.bind(this));
|
|
46
|
-
SDK.TargetManager.TargetManager.instance().addModelListener(SDK.OverlayModel.OverlayModel,
|
|
47
|
-
SDK.OverlayModel.Events.SCREENSHOT_REQUESTED,
|
|
48
|
-
this.screenshotRequestedFromOverlay, this);
|
|
49
|
-
this.requestUpdate();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
static #setNonEmulatedAvailableSize(): void {
|
|
53
|
-
const model = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
|
|
54
|
-
if (model.type() !== EmulationModel.DeviceModeModel.Type.None) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const zoomFactor = UI.ZoomManager.ZoomManager.instance().zoomFactor();
|
|
59
|
-
const rect = InspectedPagePlaceholder.instance().element.getBoundingClientRect();
|
|
60
|
-
const availableSize =
|
|
61
|
-
new Geometry.Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
|
|
62
|
-
model.setAvailableSize(availableSize, availableSize);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
static captureScreenshot(fullSize?: boolean, clip?: Protocol.Page.Viewport): boolean {
|
|
66
|
-
const model = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
|
|
67
|
-
|
|
68
|
-
this.#setNonEmulatedAvailableSize();
|
|
69
|
-
if (fullSize) {
|
|
70
|
-
void model.captureFullSizeScreenshot();
|
|
71
|
-
} else if (clip) {
|
|
72
|
-
void model.captureAreaScreenshot(clip);
|
|
73
|
-
} else {
|
|
74
|
-
void model.captureScreenshot();
|
|
75
|
-
}
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
private screenshotRequestedFromOverlay(event: Common.EventTarget.EventTargetEvent<Protocol.Page.Viewport>): void {
|
|
80
|
-
const clip = event.data;
|
|
81
|
-
DeviceModeWrapper.captureScreenshot(false, clip);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
override performUpdate(): void {
|
|
85
|
-
this.toggleDeviceModeAction.setToggled(this.showDeviceModeSetting.get());
|
|
86
|
-
|
|
87
|
-
this.#view({showDeviceMode: this.showDeviceModeSetting.get()}, undefined, this.contentElement);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
|
|
92
|
-
handleAction(context: UI.Context.Context, actionId: string): boolean {
|
|
93
|
-
switch (actionId) {
|
|
94
|
-
case 'emulation.capture-screenshot':
|
|
95
|
-
return DeviceModeWrapper.captureScreenshot();
|
|
96
|
-
|
|
97
|
-
case 'emulation.capture-node-screenshot': {
|
|
98
|
-
const node = context.flavor(SDK.DOMModel.DOMNode);
|
|
99
|
-
if (!node) {
|
|
100
|
-
return true;
|
|
101
|
-
}
|
|
102
|
-
async function captureClip(): Promise<void> {
|
|
103
|
-
if (!node) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Resolve to a remote object to ensure the node is alive in the context.
|
|
108
|
-
const object = await node.resolveToObject();
|
|
109
|
-
if (!object) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Get the Box Model via CDP.
|
|
114
|
-
// This returns the quads relative to the target's viewport.
|
|
115
|
-
// We use the 'border' quad to include the border and padding in the screenshot,
|
|
116
|
-
// matching the 'width' and 'height' properties which are also Border Box dimensions.
|
|
117
|
-
const nodeBoxModel = await node.boxModel();
|
|
118
|
-
if (!nodeBoxModel) {
|
|
119
|
-
throw new Error(`Unable to get box model of the node: ${new Error().stack}`);
|
|
120
|
-
}
|
|
121
|
-
const nodeBorderQuad = nodeBoxModel.border;
|
|
122
|
-
// Calculate the rendered bounding box from the border quad to account for CSS scaling and transforms (e.g. zoom or transform: scale).
|
|
123
|
-
const {minX, maxX, minY, maxY} = getQuadBoundingBox(nodeBorderQuad);
|
|
124
|
-
|
|
125
|
-
// Get Layout Metrics to account for the Visual Viewport scroll and zoom.
|
|
126
|
-
const metrics = await node.domModel().target().pageAgent().invoke_getLayoutMetrics();
|
|
127
|
-
if (metrics.getError()) {
|
|
128
|
-
throw new Error(`Unable to get metrics: ${new Error().stack}`);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const scrollX = metrics.cssVisualViewport.pageX;
|
|
132
|
-
const scrollY = metrics.cssVisualViewport.pageY;
|
|
133
|
-
|
|
134
|
-
// Calculate the global offset for OOPiFs (Out-of-Process iframes).
|
|
135
|
-
// This accounts for the position of the target's frame within the main page.
|
|
136
|
-
const {x: oopifOffsetX, y: oopifOffsetY} = await getOopifOffset(node.domModel().target());
|
|
137
|
-
|
|
138
|
-
// Assemble the final Clip.
|
|
139
|
-
// The absolute coordinates are: Global (OOPiF) + Viewport Scroll + Local Node Position (Border Box).
|
|
140
|
-
const clip = {
|
|
141
|
-
x: oopifOffsetX + scrollX + minX,
|
|
142
|
-
y: oopifOffsetY + scrollY + minY,
|
|
143
|
-
width: maxX - minX,
|
|
144
|
-
height: maxY - minY,
|
|
145
|
-
scale: 1,
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
// Apply Zoom factor.
|
|
149
|
-
const zoom = metrics.cssVisualViewport.zoom ?? 1;
|
|
150
|
-
clip.x *= zoom;
|
|
151
|
-
clip.y *= zoom;
|
|
152
|
-
clip.width *= zoom;
|
|
153
|
-
clip.height *= zoom;
|
|
154
|
-
DeviceModeWrapper.captureScreenshot(false, clip);
|
|
155
|
-
}
|
|
156
|
-
void captureClip();
|
|
157
|
-
return true;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
case 'emulation.capture-full-height-screenshot':
|
|
161
|
-
return DeviceModeWrapper.captureScreenshot(true);
|
|
162
|
-
|
|
163
|
-
case 'emulation.toggle-device-mode': {
|
|
164
|
-
const model = EmulationModel.DeviceModeModel.DeviceModeModel.instance();
|
|
165
|
-
model.toggleDeviceMode();
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Calculate the offset of the "Local Root" frame relative to the "Global Root" (the main frame).
|
|
175
|
-
* This involves traversing the CDP Targets for OOPiFs.
|
|
176
|
-
*/
|
|
177
|
-
async function getOopifOffset(target: SDK.Target.Target|null): Promise<{x: number, y: number}> {
|
|
178
|
-
if (!target) {
|
|
179
|
-
return {x: 0, y: 0};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Get the parent target. If there's no parent (we are at root) or it's not a frame, we are done.
|
|
183
|
-
const parentTarget = target.parentTarget();
|
|
184
|
-
if (!parentTarget || parentTarget.type() !== SDK.Target.Type.FRAME) {
|
|
185
|
-
return {x: 0, y: 0};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Identify the current frame's ID to find its owner in the parent.
|
|
189
|
-
const frameId = target.model(SDK.ResourceTreeModel.ResourceTreeModel)?.mainFrame?.id;
|
|
190
|
-
if (!frameId) {
|
|
191
|
-
return {x: 0, y: 0};
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Get the DOMModel of the parent to query the frame owner element.
|
|
195
|
-
const parentDOMModel = parentTarget.model(SDK.DOMModel.DOMModel);
|
|
196
|
-
if (!parentDOMModel) {
|
|
197
|
-
return {x: 0, y: 0};
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Retrieve the frame owner node (e.g. the <iframe> element) in the parent's document.
|
|
201
|
-
const frameOwnerDeferred = await parentDOMModel.getOwnerNodeForFrame(frameId);
|
|
202
|
-
const frameOwner = await frameOwnerDeferred?.resolvePromise();
|
|
203
|
-
if (!frameOwner) {
|
|
204
|
-
return {x: 0, y: 0};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Get the content box of the iframe element.
|
|
208
|
-
// This is relative to the parent target's viewport.
|
|
209
|
-
const boxModel = await frameOwner.boxModel();
|
|
210
|
-
if (!boxModel) {
|
|
211
|
-
return {x: 0, y: 0};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// content is a Quad [x1, y1, x2, y2, x3, y3, x4, y4]
|
|
215
|
-
const contentQuad = boxModel.content;
|
|
216
|
-
const iframeContentX = contentQuad[0];
|
|
217
|
-
const iframeContentY = contentQuad[1];
|
|
218
|
-
|
|
219
|
-
// Get the scroll position of the parent target to convert viewport-relative coordinates
|
|
220
|
-
// to document-relative coordinates.
|
|
221
|
-
const parentMetrics = await parentTarget.pageAgent().invoke_getLayoutMetrics();
|
|
222
|
-
if (parentMetrics.getError()) {
|
|
223
|
-
return {x: 0, y: 0};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const scrollX = parentMetrics.cssVisualViewport.pageX;
|
|
227
|
-
const scrollY = parentMetrics.cssVisualViewport.pageY;
|
|
228
|
-
|
|
229
|
-
// Recursively add the offset of the parent target itself (if it is also an OOPiF).
|
|
230
|
-
const parentOffset = await getOopifOffset(parentTarget);
|
|
231
|
-
|
|
232
|
-
return {
|
|
233
|
-
x: iframeContentX + scrollX + parentOffset.x,
|
|
234
|
-
y: iframeContentY + scrollY + parentOffset.y,
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Calculate the axis-aligned bounding box for a Quad [x1, y1, x2, y2, x3, y3, x4, y4].
|
|
240
|
-
* This accounts for CSS scaling and transforms (e.g. zoom, transform: scale).
|
|
241
|
-
*/
|
|
242
|
-
function getQuadBoundingBox(quad: Protocol.DOM.Quad): {minX: number, maxX: number, minY: number, maxY: number} {
|
|
243
|
-
const minX = Math.min(quad[0], quad[2], quad[4], quad[6]);
|
|
244
|
-
const maxX = Math.max(quad[0], quad[2], quad[4], quad[6]);
|
|
245
|
-
const minY = Math.min(quad[1], quad[3], quad[5], quad[7]);
|
|
246
|
-
const maxY = Math.max(quad[1], quad[3], quad[5], quad[7]);
|
|
247
|
-
return {minX, maxX, minY, maxY};
|
|
248
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
// Copyright 2017 The Chromium Authors
|
|
2
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
-
// found in the LICENSE file.
|
|
4
|
-
|
|
5
|
-
import * as i18n from '../../core/i18n/i18n.js';
|
|
6
|
-
import * as SDK from '../../core/sdk/sdk.js';
|
|
7
|
-
|
|
8
|
-
import {throttlingManager} from './ThrottlingManager.js';
|
|
9
|
-
import {
|
|
10
|
-
ThrottlingPresets,
|
|
11
|
-
type Conditions,
|
|
12
|
-
type ConditionsList,
|
|
13
|
-
type MobileThrottlingConditionsGroup,
|
|
14
|
-
} from './ThrottlingPresets.js';
|
|
15
|
-
|
|
16
|
-
const UIStrings = {
|
|
17
|
-
/**
|
|
18
|
-
* @description Mobile throttling is disabled. The user can select this option to run mobile
|
|
19
|
-
* emulation at a normal speed instead of throttled.
|
|
20
|
-
*/
|
|
21
|
-
disabled: 'Disabled',
|
|
22
|
-
/**
|
|
23
|
-
* @description Title for a group of pre-decided configuration options for mobile throttling. These
|
|
24
|
-
* are useful default options that users might want.
|
|
25
|
-
*/
|
|
26
|
-
presets: 'Presets',
|
|
27
|
-
/**
|
|
28
|
-
* @description Title for a group of advanced configuration options for mobile throttling, which
|
|
29
|
-
* might not be applicable to every user or situation.
|
|
30
|
-
*/
|
|
31
|
-
advanced: 'Advanced',
|
|
32
|
-
} as const;
|
|
33
|
-
const str_ = i18n.i18n.registerUIStrings('panels/mobile_throttling/MobileThrottlingSelector.ts', UIStrings);
|
|
34
|
-
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
35
|
-
|
|
36
|
-
export class MobileThrottlingSelector {
|
|
37
|
-
private readonly populateCallback: (arg0: MobileThrottlingConditionsGroup[]) => ConditionsList;
|
|
38
|
-
private readonly selectCallback: (arg0: number) => void;
|
|
39
|
-
private readonly options: ConditionsList;
|
|
40
|
-
|
|
41
|
-
constructor(
|
|
42
|
-
populateCallback: (arg0: MobileThrottlingConditionsGroup[]) => ConditionsList,
|
|
43
|
-
selectCallback: (arg0: number) => void) {
|
|
44
|
-
this.populateCallback = populateCallback;
|
|
45
|
-
this.selectCallback = selectCallback;
|
|
46
|
-
SDK.CPUThrottlingManager.CPUThrottlingManager.instance().addEventListener(
|
|
47
|
-
SDK.CPUThrottlingManager.Events.RATE_CHANGED, this.conditionsChanged, this);
|
|
48
|
-
SDK.NetworkManager.MultitargetNetworkManager.instance().addEventListener(
|
|
49
|
-
SDK.NetworkManager.MultitargetNetworkManager.Events.CONDITIONS_CHANGED, this.conditionsChanged, this);
|
|
50
|
-
this.options = this.populateOptions();
|
|
51
|
-
this.conditionsChanged();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
optionSelected(conditions: Conditions): void {
|
|
55
|
-
SDK.NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(conditions.network);
|
|
56
|
-
throttlingManager().setCPUThrottlingOption(conditions.cpuThrottlingOption);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private populateOptions(): ConditionsList {
|
|
60
|
-
const disabledGroup = {
|
|
61
|
-
title: i18nString(UIStrings.disabled),
|
|
62
|
-
items: [ThrottlingPresets.getNoThrottlingConditions()],
|
|
63
|
-
};
|
|
64
|
-
const presetsGroup = {title: i18nString(UIStrings.presets), items: ThrottlingPresets.getMobilePresets()};
|
|
65
|
-
const advancedGroup = {title: i18nString(UIStrings.advanced), items: ThrottlingPresets.getAdvancedMobilePresets()};
|
|
66
|
-
return this.populateCallback([disabledGroup, presetsGroup, advancedGroup]);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
private conditionsChanged(): void {
|
|
70
|
-
this.populateOptions();
|
|
71
|
-
|
|
72
|
-
const networkConditions = SDK.NetworkManager.MultitargetNetworkManager.instance().networkConditions();
|
|
73
|
-
const cpuThrottlingOption = throttlingManager().cpuThrottlingOption();
|
|
74
|
-
for (let index = 0; index < this.options.length; ++index) {
|
|
75
|
-
const option = this.options[index];
|
|
76
|
-
if (option && 'network' in option && option.network === networkConditions &&
|
|
77
|
-
option.cpuThrottlingOption === cpuThrottlingOption) {
|
|
78
|
-
this.selectCallback(index);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const customConditions = ThrottlingPresets.getCustomConditions();
|
|
84
|
-
for (let index = 0; index < this.options.length; ++index) {
|
|
85
|
-
const item = this.options[index];
|
|
86
|
-
if (item && item.title === customConditions.title && item.description === customConditions.description) {
|
|
87
|
-
this.selectCallback(index);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|