chrome-devtools-mcp 0.0.2 → 0.2.0
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/README.md +6 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Settings.js +3 -32
- package/build/node_modules/chrome-devtools-frontend/front_end/core/i18n/i18n.js +35 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/core/root/Runtime.js +4 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/InspectorBackendCommands.js +4 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/SupportedCSSProperties.js +12 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.js +366 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AICallTree.js +366 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AIContext.js +64 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AIQueries.js +105 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/CSSWorkspaceBinding.js +243 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/CompilerScriptMapping.js +407 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/ContentProviderBasedProject.js +128 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/DebuggerLanguagePlugins.js +992 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/DebuggerWorkspaceBinding.js +574 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/DefaultScriptMapping.js +112 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/FileUtils.js +186 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/LiveLocation.js +60 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/NetworkProject.js +107 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/PresentationConsoleMessageHelper.js +244 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/ResourceMapping.js +473 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/ResourceScriptMapping.js +399 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/ResourceUtils.js +87 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/SASSSourceMapping.js +181 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/StylesSourceMapping.js +268 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/TempFile.js +55 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/bindings.js +20 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/crux-manager/CrUXManager.js +283 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/crux-manager/crux-manager.js +4 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/emulation/DeviceModeModel.js +775 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/emulation/EmulatedDevices.js +1706 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/emulation/emulation.js +6 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/formatter/FormatterWorkerPool.js +131 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/formatter/ScriptFormatter.js +77 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/formatter/formatter.js +6 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/geometry/GeometryImpl.js +347 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/geometry/geometry.js +4 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/NamesResolver.js +626 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/ScopeChainModel.js +59 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/ScopeTreeCache.js +32 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/source_map_scopes.js +7 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/StackTrace.js +4 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/StackTraceImpl.js +67 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/StackTraceModel.js +97 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/Trie.js +113 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/stack_trace.js +5 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/stack_trace_impl.js +7 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/text_utils/TextUtils.js +23 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/Processor.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/helpers/Trace.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/DocumentLatency.js +5 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace_source_maps_resolver/SourceMapsResolver.js +199 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace_source_maps_resolver/trace_source_maps_resolver.js +4 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/FileManager.js +64 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/IgnoreListManager.js +511 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/SearchConfig.js +113 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/UISourceCode.js +563 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/WorkspaceImpl.js +204 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/workspace.js +9 -0
- package/build/src/McpContext.js +24 -9
- package/build/src/McpResponse.js +3 -3
- package/build/src/browser.js +3 -1
- package/build/src/index.js +1 -1
- package/build/src/tools/input.js +7 -7
- package/build/src/tools/performance.js +29 -2
- package/build/src/tools/screenshot.js +1 -1
- package/build/src/tools/script.js +40 -14
- package/build/src/trace-processing/parse.js +26 -22
- package/package.json +9 -7
package/build/node_modules/chrome-devtools-frontend/front_end/models/emulation/DeviceModeModel.js
ADDED
|
@@ -0,0 +1,775 @@
|
|
|
1
|
+
// Copyright 2015 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
|
+
import * as Common from '../../core/common/common.js';
|
|
5
|
+
import * as Host from '../../core/host/host.js';
|
|
6
|
+
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
|
+
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
|
+
import * as Geometry from '../geometry/geometry.js';
|
|
9
|
+
import { Horizontal, HorizontalSpanned, Vertical, VerticalSpanned, } from './EmulatedDevices.js';
|
|
10
|
+
const UIStrings = {
|
|
11
|
+
/**
|
|
12
|
+
* @description Error message shown in the Devices settings pane when the user enters an empty
|
|
13
|
+
* width for a custom device.
|
|
14
|
+
*/
|
|
15
|
+
widthCannotBeEmpty: 'Width cannot be empty.',
|
|
16
|
+
/**
|
|
17
|
+
* @description Error message shown in the Devices settings pane when the user enters an invalid
|
|
18
|
+
* width for a custom device.
|
|
19
|
+
*/
|
|
20
|
+
widthMustBeANumber: 'Width must be a number.',
|
|
21
|
+
/**
|
|
22
|
+
* @description Error message shown in the Devices settings pane when the user has entered a width
|
|
23
|
+
* for a custom device that is too large.
|
|
24
|
+
* @example {9999} PH1
|
|
25
|
+
*/
|
|
26
|
+
widthMustBeLessThanOrEqualToS: 'Width must be less than or equal to {PH1}.',
|
|
27
|
+
/**
|
|
28
|
+
* @description Error message shown in the Devices settings pane when the user has entered a width
|
|
29
|
+
* for a custom device that is too small.
|
|
30
|
+
* @example {50} PH1
|
|
31
|
+
*/
|
|
32
|
+
widthMustBeGreaterThanOrEqualToS: 'Width must be greater than or equal to {PH1}.',
|
|
33
|
+
/**
|
|
34
|
+
* @description Error message shown in the Devices settings pane when the user enters an empty
|
|
35
|
+
* height for a custom device.
|
|
36
|
+
*/
|
|
37
|
+
heightCannotBeEmpty: 'Height cannot be empty.',
|
|
38
|
+
/**
|
|
39
|
+
* @description Error message shown in the Devices settings pane when the user enters an invalid
|
|
40
|
+
* height for a custom device.
|
|
41
|
+
*/
|
|
42
|
+
heightMustBeANumber: 'Height must be a number.',
|
|
43
|
+
/**
|
|
44
|
+
* @description Error message shown in the Devices settings pane when the user has entered a height
|
|
45
|
+
* for a custom device that is too large.
|
|
46
|
+
* @example {9999} PH1
|
|
47
|
+
*/
|
|
48
|
+
heightMustBeLessThanOrEqualToS: 'Height must be less than or equal to {PH1}.',
|
|
49
|
+
/**
|
|
50
|
+
* @description Error message shown in the Devices settings pane when the user has entered a height
|
|
51
|
+
* for a custom device that is too small.
|
|
52
|
+
* @example {50} PH1
|
|
53
|
+
*/
|
|
54
|
+
heightMustBeGreaterThanOrEqualTo: 'Height must be greater than or equal to {PH1}.',
|
|
55
|
+
/**
|
|
56
|
+
* @description Error message shown in the Devices settings pane when the user enters an invalid
|
|
57
|
+
* device pixel ratio for a custom device.
|
|
58
|
+
*/
|
|
59
|
+
devicePixelRatioMustBeANumberOr: 'Device pixel ratio must be a number or blank.',
|
|
60
|
+
/**
|
|
61
|
+
* @description Error message shown in the Devices settings pane when the user enters a device
|
|
62
|
+
* pixel ratio for a custom device that is too large.
|
|
63
|
+
* @example {10} PH1
|
|
64
|
+
*/
|
|
65
|
+
devicePixelRatioMustBeLessThanOr: 'Device pixel ratio must be less than or equal to {PH1}.',
|
|
66
|
+
/**
|
|
67
|
+
* @description Error message shown in the Devices settings pane when the user enters a device
|
|
68
|
+
* pixel ratio for a custom device that is too small.
|
|
69
|
+
* @example {0} PH1
|
|
70
|
+
*/
|
|
71
|
+
devicePixelRatioMustBeGreater: 'Device pixel ratio must be greater than or equal to {PH1}.',
|
|
72
|
+
};
|
|
73
|
+
const str_ = i18n.i18n.registerUIStrings('models/emulation/DeviceModeModel.ts', UIStrings);
|
|
74
|
+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
75
|
+
let deviceModeModelInstance;
|
|
76
|
+
export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper {
|
|
77
|
+
#screenRect;
|
|
78
|
+
#visiblePageRect;
|
|
79
|
+
#availableSize;
|
|
80
|
+
#preferredSize;
|
|
81
|
+
#initialized;
|
|
82
|
+
#appliedDeviceSize;
|
|
83
|
+
#appliedDeviceScaleFactor;
|
|
84
|
+
#appliedUserAgentType;
|
|
85
|
+
#scaleSetting;
|
|
86
|
+
#scale;
|
|
87
|
+
#widthSetting;
|
|
88
|
+
#heightSetting;
|
|
89
|
+
#uaSetting;
|
|
90
|
+
#deviceScaleFactorSetting;
|
|
91
|
+
#deviceOutlineSetting;
|
|
92
|
+
#toolbarControlsEnabledSetting;
|
|
93
|
+
#type;
|
|
94
|
+
#device;
|
|
95
|
+
#mode;
|
|
96
|
+
#fitScale;
|
|
97
|
+
#touchEnabled;
|
|
98
|
+
#touchMobile;
|
|
99
|
+
#emulationModel;
|
|
100
|
+
#onModelAvailable;
|
|
101
|
+
#outlineRect;
|
|
102
|
+
constructor() {
|
|
103
|
+
super();
|
|
104
|
+
this.#screenRect = new Rect(0, 0, 1, 1);
|
|
105
|
+
this.#visiblePageRect = new Rect(0, 0, 1, 1);
|
|
106
|
+
this.#availableSize = new Geometry.Size(1, 1);
|
|
107
|
+
this.#preferredSize = new Geometry.Size(1, 1);
|
|
108
|
+
this.#initialized = false;
|
|
109
|
+
this.#appliedDeviceSize = new Geometry.Size(1, 1);
|
|
110
|
+
this.#appliedDeviceScaleFactor = window.devicePixelRatio;
|
|
111
|
+
this.#appliedUserAgentType = "Desktop" /* UA.DESKTOP */;
|
|
112
|
+
this.#scaleSetting = Common.Settings.Settings.instance().createSetting('emulation.device-scale', 1);
|
|
113
|
+
// We've used to allow zero before.
|
|
114
|
+
if (!this.#scaleSetting.get()) {
|
|
115
|
+
this.#scaleSetting.set(1);
|
|
116
|
+
}
|
|
117
|
+
this.#scaleSetting.addChangeListener(this.scaleSettingChanged, this);
|
|
118
|
+
this.#scale = 1;
|
|
119
|
+
this.#widthSetting = Common.Settings.Settings.instance().createSetting('emulation.device-width', 400);
|
|
120
|
+
if (this.#widthSetting.get() < MinDeviceSize) {
|
|
121
|
+
this.#widthSetting.set(MinDeviceSize);
|
|
122
|
+
}
|
|
123
|
+
if (this.#widthSetting.get() > MaxDeviceSize) {
|
|
124
|
+
this.#widthSetting.set(MaxDeviceSize);
|
|
125
|
+
}
|
|
126
|
+
this.#widthSetting.addChangeListener(this.widthSettingChanged, this);
|
|
127
|
+
this.#heightSetting = Common.Settings.Settings.instance().createSetting('emulation.device-height', 0);
|
|
128
|
+
if (this.#heightSetting.get() && this.#heightSetting.get() < MinDeviceSize) {
|
|
129
|
+
this.#heightSetting.set(MinDeviceSize);
|
|
130
|
+
}
|
|
131
|
+
if (this.#heightSetting.get() > MaxDeviceSize) {
|
|
132
|
+
this.#heightSetting.set(MaxDeviceSize);
|
|
133
|
+
}
|
|
134
|
+
this.#heightSetting.addChangeListener(this.heightSettingChanged, this);
|
|
135
|
+
this.#uaSetting = Common.Settings.Settings.instance().createSetting('emulation.device-ua', "Mobile" /* UA.MOBILE */);
|
|
136
|
+
this.#uaSetting.addChangeListener(this.uaSettingChanged, this);
|
|
137
|
+
this.#deviceScaleFactorSetting =
|
|
138
|
+
Common.Settings.Settings.instance().createSetting('emulation.device-scale-factor', 0);
|
|
139
|
+
this.#deviceScaleFactorSetting.addChangeListener(this.deviceScaleFactorSettingChanged, this);
|
|
140
|
+
this.#deviceOutlineSetting = Common.Settings.Settings.instance().moduleSetting('emulation.show-device-outline');
|
|
141
|
+
this.#deviceOutlineSetting.addChangeListener(this.deviceOutlineSettingChanged, this);
|
|
142
|
+
this.#toolbarControlsEnabledSetting = Common.Settings.Settings.instance().createSetting('emulation.toolbar-controls-enabled', true, "Session" /* Common.Settings.SettingStorageType.SESSION */);
|
|
143
|
+
this.#type = Type.None;
|
|
144
|
+
this.#device = null;
|
|
145
|
+
this.#mode = null;
|
|
146
|
+
this.#fitScale = 1;
|
|
147
|
+
this.#touchEnabled = false;
|
|
148
|
+
this.#touchMobile = false;
|
|
149
|
+
this.#emulationModel = null;
|
|
150
|
+
this.#onModelAvailable = null;
|
|
151
|
+
SDK.TargetManager.TargetManager.instance().observeModels(SDK.EmulationModel.EmulationModel, this);
|
|
152
|
+
}
|
|
153
|
+
static instance(opts) {
|
|
154
|
+
if (!deviceModeModelInstance || opts?.forceNew) {
|
|
155
|
+
deviceModeModelInstance = new DeviceModeModel();
|
|
156
|
+
}
|
|
157
|
+
return deviceModeModelInstance;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* This wraps `instance()` in a try/catch because in some DevTools entry points
|
|
161
|
+
* (such as worker_app.ts) the Emulation panel is not included and as such
|
|
162
|
+
* the below code fails; it tries to instantiate the model which requires
|
|
163
|
+
* reading the value of a setting which has not been registered.
|
|
164
|
+
* See crbug.com/361515458 for an example bug that this resolves.
|
|
165
|
+
*/
|
|
166
|
+
static tryInstance(opts) {
|
|
167
|
+
try {
|
|
168
|
+
return this.instance(opts);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
static widthValidator(value) {
|
|
175
|
+
let valid = false;
|
|
176
|
+
let errorMessage;
|
|
177
|
+
if (!value) {
|
|
178
|
+
errorMessage = i18nString(UIStrings.widthCannotBeEmpty);
|
|
179
|
+
}
|
|
180
|
+
else if (!/^[\d]+$/.test(value)) {
|
|
181
|
+
errorMessage = i18nString(UIStrings.widthMustBeANumber);
|
|
182
|
+
}
|
|
183
|
+
else if (Number(value) > MaxDeviceSize) {
|
|
184
|
+
errorMessage = i18nString(UIStrings.widthMustBeLessThanOrEqualToS, { PH1: MaxDeviceSize });
|
|
185
|
+
}
|
|
186
|
+
else if (Number(value) < MinDeviceSize) {
|
|
187
|
+
errorMessage = i18nString(UIStrings.widthMustBeGreaterThanOrEqualToS, { PH1: MinDeviceSize });
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
valid = true;
|
|
191
|
+
}
|
|
192
|
+
return { valid, errorMessage };
|
|
193
|
+
}
|
|
194
|
+
static heightValidator(value) {
|
|
195
|
+
let valid = false;
|
|
196
|
+
let errorMessage;
|
|
197
|
+
if (!value) {
|
|
198
|
+
errorMessage = i18nString(UIStrings.heightCannotBeEmpty);
|
|
199
|
+
}
|
|
200
|
+
else if (!/^[\d]+$/.test(value)) {
|
|
201
|
+
errorMessage = i18nString(UIStrings.heightMustBeANumber);
|
|
202
|
+
}
|
|
203
|
+
else if (Number(value) > MaxDeviceSize) {
|
|
204
|
+
errorMessage = i18nString(UIStrings.heightMustBeLessThanOrEqualToS, { PH1: MaxDeviceSize });
|
|
205
|
+
}
|
|
206
|
+
else if (Number(value) < MinDeviceSize) {
|
|
207
|
+
errorMessage = i18nString(UIStrings.heightMustBeGreaterThanOrEqualTo, { PH1: MinDeviceSize });
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
valid = true;
|
|
211
|
+
}
|
|
212
|
+
return { valid, errorMessage };
|
|
213
|
+
}
|
|
214
|
+
static scaleValidator(value) {
|
|
215
|
+
let valid = false;
|
|
216
|
+
let errorMessage;
|
|
217
|
+
const parsedValue = Number(value.trim());
|
|
218
|
+
if (!value) {
|
|
219
|
+
valid = true;
|
|
220
|
+
}
|
|
221
|
+
else if (Number.isNaN(parsedValue)) {
|
|
222
|
+
errorMessage = i18nString(UIStrings.devicePixelRatioMustBeANumberOr);
|
|
223
|
+
}
|
|
224
|
+
else if (Number(value) > MaxDeviceScaleFactor) {
|
|
225
|
+
errorMessage = i18nString(UIStrings.devicePixelRatioMustBeLessThanOr, { PH1: MaxDeviceScaleFactor });
|
|
226
|
+
}
|
|
227
|
+
else if (Number(value) < MinDeviceScaleFactor) {
|
|
228
|
+
errorMessage = i18nString(UIStrings.devicePixelRatioMustBeGreater, { PH1: MinDeviceScaleFactor });
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
valid = true;
|
|
232
|
+
}
|
|
233
|
+
return { valid, errorMessage };
|
|
234
|
+
}
|
|
235
|
+
get scaleSettingInternal() {
|
|
236
|
+
return this.#scaleSetting;
|
|
237
|
+
}
|
|
238
|
+
setAvailableSize(availableSize, preferredSize) {
|
|
239
|
+
this.#availableSize = availableSize;
|
|
240
|
+
this.#preferredSize = preferredSize;
|
|
241
|
+
this.#initialized = true;
|
|
242
|
+
this.calculateAndEmulate(false);
|
|
243
|
+
}
|
|
244
|
+
emulate(type, device, mode, scale) {
|
|
245
|
+
const resetPageScaleFactor = this.#type !== type || this.#device !== device || this.#mode !== mode;
|
|
246
|
+
this.#type = type;
|
|
247
|
+
if (type === Type.Device && device && mode) {
|
|
248
|
+
console.assert(Boolean(device) && Boolean(mode), 'Must pass device and mode for device emulation');
|
|
249
|
+
this.#mode = mode;
|
|
250
|
+
this.#device = device;
|
|
251
|
+
if (this.#initialized) {
|
|
252
|
+
const orientation = device.orientationByName(mode.orientation);
|
|
253
|
+
this.#scaleSetting.set(scale ||
|
|
254
|
+
this.calculateFitScale(orientation.width, orientation.height, this.currentOutline(), this.currentInsets()));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
this.#device = null;
|
|
259
|
+
this.#mode = null;
|
|
260
|
+
}
|
|
261
|
+
if (type !== Type.None) {
|
|
262
|
+
Host.userMetrics.actionTaken(Host.UserMetrics.Action.DeviceModeEnabled);
|
|
263
|
+
}
|
|
264
|
+
this.calculateAndEmulate(resetPageScaleFactor);
|
|
265
|
+
}
|
|
266
|
+
setWidth(width) {
|
|
267
|
+
const max = Math.min(MaxDeviceSize, this.preferredScaledWidth());
|
|
268
|
+
width = Math.max(Math.min(width, max), 1);
|
|
269
|
+
this.#widthSetting.set(width);
|
|
270
|
+
}
|
|
271
|
+
setWidthAndScaleToFit(width) {
|
|
272
|
+
width = Math.max(Math.min(width, MaxDeviceSize), 1);
|
|
273
|
+
this.#scaleSetting.set(this.calculateFitScale(width, this.#heightSetting.get()));
|
|
274
|
+
this.#widthSetting.set(width);
|
|
275
|
+
}
|
|
276
|
+
setHeight(height) {
|
|
277
|
+
const max = Math.min(MaxDeviceSize, this.preferredScaledHeight());
|
|
278
|
+
height = Math.max(Math.min(height, max), 0);
|
|
279
|
+
if (height === this.preferredScaledHeight()) {
|
|
280
|
+
height = 0;
|
|
281
|
+
}
|
|
282
|
+
this.#heightSetting.set(height);
|
|
283
|
+
}
|
|
284
|
+
setHeightAndScaleToFit(height) {
|
|
285
|
+
height = Math.max(Math.min(height, MaxDeviceSize), 0);
|
|
286
|
+
this.#scaleSetting.set(this.calculateFitScale(this.#widthSetting.get(), height));
|
|
287
|
+
this.#heightSetting.set(height);
|
|
288
|
+
}
|
|
289
|
+
setScale(scale) {
|
|
290
|
+
this.#scaleSetting.set(scale);
|
|
291
|
+
}
|
|
292
|
+
device() {
|
|
293
|
+
return this.#device;
|
|
294
|
+
}
|
|
295
|
+
mode() {
|
|
296
|
+
return this.#mode;
|
|
297
|
+
}
|
|
298
|
+
type() {
|
|
299
|
+
return this.#type;
|
|
300
|
+
}
|
|
301
|
+
screenImage() {
|
|
302
|
+
return (this.#device && this.#mode) ? this.#device.modeImage(this.#mode) : '';
|
|
303
|
+
}
|
|
304
|
+
outlineImage() {
|
|
305
|
+
return (this.#device && this.#mode && this.#deviceOutlineSetting.get()) ? this.#device.outlineImage(this.#mode) :
|
|
306
|
+
'';
|
|
307
|
+
}
|
|
308
|
+
outlineRect() {
|
|
309
|
+
return this.#outlineRect || null;
|
|
310
|
+
}
|
|
311
|
+
screenRect() {
|
|
312
|
+
return this.#screenRect;
|
|
313
|
+
}
|
|
314
|
+
visiblePageRect() {
|
|
315
|
+
return this.#visiblePageRect;
|
|
316
|
+
}
|
|
317
|
+
scale() {
|
|
318
|
+
return this.#scale;
|
|
319
|
+
}
|
|
320
|
+
fitScale() {
|
|
321
|
+
return this.#fitScale;
|
|
322
|
+
}
|
|
323
|
+
appliedDeviceSize() {
|
|
324
|
+
return this.#appliedDeviceSize;
|
|
325
|
+
}
|
|
326
|
+
appliedDeviceScaleFactor() {
|
|
327
|
+
return this.#appliedDeviceScaleFactor;
|
|
328
|
+
}
|
|
329
|
+
appliedUserAgentType() {
|
|
330
|
+
return this.#appliedUserAgentType;
|
|
331
|
+
}
|
|
332
|
+
isFullHeight() {
|
|
333
|
+
return !this.#heightSetting.get();
|
|
334
|
+
}
|
|
335
|
+
isMobile() {
|
|
336
|
+
switch (this.#type) {
|
|
337
|
+
case Type.Device:
|
|
338
|
+
return this.#device ? this.#device.mobile() : false;
|
|
339
|
+
case Type.None:
|
|
340
|
+
return false;
|
|
341
|
+
case Type.Responsive:
|
|
342
|
+
return this.#uaSetting.get() === "Mobile" /* UA.MOBILE */ || this.#uaSetting.get() === "Mobile (no touch)" /* UA.MOBILE_NO_TOUCH */;
|
|
343
|
+
}
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
enabledSetting() {
|
|
347
|
+
return Common.Settings.Settings.instance().createSetting('emulation.show-device-mode', false);
|
|
348
|
+
}
|
|
349
|
+
scaleSetting() {
|
|
350
|
+
return this.#scaleSetting;
|
|
351
|
+
}
|
|
352
|
+
uaSetting() {
|
|
353
|
+
return this.#uaSetting;
|
|
354
|
+
}
|
|
355
|
+
deviceScaleFactorSetting() {
|
|
356
|
+
return this.#deviceScaleFactorSetting;
|
|
357
|
+
}
|
|
358
|
+
deviceOutlineSetting() {
|
|
359
|
+
return this.#deviceOutlineSetting;
|
|
360
|
+
}
|
|
361
|
+
toolbarControlsEnabledSetting() {
|
|
362
|
+
return this.#toolbarControlsEnabledSetting;
|
|
363
|
+
}
|
|
364
|
+
reset() {
|
|
365
|
+
this.#deviceScaleFactorSetting.set(0);
|
|
366
|
+
this.#scaleSetting.set(1);
|
|
367
|
+
this.setWidth(400);
|
|
368
|
+
this.setHeight(0);
|
|
369
|
+
this.#uaSetting.set("Mobile" /* UA.MOBILE */);
|
|
370
|
+
}
|
|
371
|
+
modelAdded(emulationModel) {
|
|
372
|
+
if (emulationModel.target() === SDK.TargetManager.TargetManager.instance().primaryPageTarget() &&
|
|
373
|
+
emulationModel.supportsDeviceEmulation()) {
|
|
374
|
+
this.#emulationModel = emulationModel;
|
|
375
|
+
if (this.#onModelAvailable) {
|
|
376
|
+
const callback = this.#onModelAvailable;
|
|
377
|
+
this.#onModelAvailable = null;
|
|
378
|
+
callback();
|
|
379
|
+
}
|
|
380
|
+
const resourceTreeModel = emulationModel.target().model(SDK.ResourceTreeModel.ResourceTreeModel);
|
|
381
|
+
if (resourceTreeModel) {
|
|
382
|
+
resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameResized, this.onFrameChange, this);
|
|
383
|
+
resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameNavigated, this.onFrameChange, this);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
void emulationModel.emulateTouch(this.#touchEnabled, this.#touchMobile);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
modelRemoved(emulationModel) {
|
|
391
|
+
if (this.#emulationModel === emulationModel) {
|
|
392
|
+
this.#emulationModel = null;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
inspectedURL() {
|
|
396
|
+
return this.#emulationModel ? this.#emulationModel.target().inspectedURL() : null;
|
|
397
|
+
}
|
|
398
|
+
onFrameChange() {
|
|
399
|
+
const overlayModel = this.#emulationModel ? this.#emulationModel.overlayModel() : null;
|
|
400
|
+
if (!overlayModel) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
this.showHingeIfApplicable(overlayModel);
|
|
404
|
+
}
|
|
405
|
+
scaleSettingChanged() {
|
|
406
|
+
this.calculateAndEmulate(false);
|
|
407
|
+
}
|
|
408
|
+
widthSettingChanged() {
|
|
409
|
+
this.calculateAndEmulate(false);
|
|
410
|
+
}
|
|
411
|
+
heightSettingChanged() {
|
|
412
|
+
this.calculateAndEmulate(false);
|
|
413
|
+
}
|
|
414
|
+
uaSettingChanged() {
|
|
415
|
+
this.calculateAndEmulate(true);
|
|
416
|
+
}
|
|
417
|
+
deviceScaleFactorSettingChanged() {
|
|
418
|
+
this.calculateAndEmulate(false);
|
|
419
|
+
}
|
|
420
|
+
deviceOutlineSettingChanged() {
|
|
421
|
+
this.calculateAndEmulate(false);
|
|
422
|
+
}
|
|
423
|
+
preferredScaledWidth() {
|
|
424
|
+
return Math.floor(this.#preferredSize.width / (this.#scaleSetting.get() || 1));
|
|
425
|
+
}
|
|
426
|
+
preferredScaledHeight() {
|
|
427
|
+
return Math.floor(this.#preferredSize.height / (this.#scaleSetting.get() || 1));
|
|
428
|
+
}
|
|
429
|
+
currentOutline() {
|
|
430
|
+
let outline = new Insets(0, 0, 0, 0);
|
|
431
|
+
if (this.#type !== Type.Device || !this.#device || !this.#mode) {
|
|
432
|
+
return outline;
|
|
433
|
+
}
|
|
434
|
+
const orientation = this.#device.orientationByName(this.#mode.orientation);
|
|
435
|
+
if (this.#deviceOutlineSetting.get()) {
|
|
436
|
+
outline = orientation.outlineInsets || outline;
|
|
437
|
+
}
|
|
438
|
+
return outline;
|
|
439
|
+
}
|
|
440
|
+
currentInsets() {
|
|
441
|
+
if (this.#type !== Type.Device || !this.#mode) {
|
|
442
|
+
return new Insets(0, 0, 0, 0);
|
|
443
|
+
}
|
|
444
|
+
return this.#mode.insets;
|
|
445
|
+
}
|
|
446
|
+
getScreenOrientationType() {
|
|
447
|
+
if (!this.#mode) {
|
|
448
|
+
throw new Error('Mode required to get orientation type.');
|
|
449
|
+
}
|
|
450
|
+
switch (this.#mode.orientation) {
|
|
451
|
+
case VerticalSpanned:
|
|
452
|
+
case Vertical:
|
|
453
|
+
return "portraitPrimary" /* Protocol.Emulation.ScreenOrientationType.PortraitPrimary */;
|
|
454
|
+
case HorizontalSpanned:
|
|
455
|
+
case Horizontal:
|
|
456
|
+
default:
|
|
457
|
+
return "landscapePrimary" /* Protocol.Emulation.ScreenOrientationType.LandscapePrimary */;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
calculateAndEmulate(resetPageScaleFactor) {
|
|
461
|
+
if (!this.#emulationModel) {
|
|
462
|
+
this.#onModelAvailable = this.calculateAndEmulate.bind(this, resetPageScaleFactor);
|
|
463
|
+
}
|
|
464
|
+
const mobile = this.isMobile();
|
|
465
|
+
const overlayModel = this.#emulationModel ? this.#emulationModel.overlayModel() : null;
|
|
466
|
+
if (overlayModel) {
|
|
467
|
+
this.showHingeIfApplicable(overlayModel);
|
|
468
|
+
}
|
|
469
|
+
if (this.#type === Type.Device && this.#device && this.#mode) {
|
|
470
|
+
const orientation = this.#device.orientationByName(this.#mode.orientation);
|
|
471
|
+
const outline = this.currentOutline();
|
|
472
|
+
const insets = this.currentInsets();
|
|
473
|
+
this.#fitScale = this.calculateFitScale(orientation.width, orientation.height, outline, insets);
|
|
474
|
+
if (mobile) {
|
|
475
|
+
this.#appliedUserAgentType = this.#device.touch() ? "Mobile" /* UA.MOBILE */ : "Mobile (no touch)" /* UA.MOBILE_NO_TOUCH */;
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
this.#appliedUserAgentType = this.#device.touch() ? "Desktop (touch)" /* UA.DESKTOP_TOUCH */ : "Desktop" /* UA.DESKTOP */;
|
|
479
|
+
}
|
|
480
|
+
this.applyDeviceMetrics(new Geometry.Size(orientation.width, orientation.height), insets, outline, this.#scaleSetting.get(), this.#device.deviceScaleFactor, mobile, this.getScreenOrientationType(), resetPageScaleFactor);
|
|
481
|
+
this.applyUserAgent(this.#device.userAgent, this.#device.userAgentMetadata);
|
|
482
|
+
this.applyTouch(this.#device.touch(), mobile);
|
|
483
|
+
}
|
|
484
|
+
else if (this.#type === Type.None) {
|
|
485
|
+
this.#fitScale = this.calculateFitScale(this.#availableSize.width, this.#availableSize.height);
|
|
486
|
+
this.#appliedUserAgentType = "Desktop" /* UA.DESKTOP */;
|
|
487
|
+
this.applyDeviceMetrics(this.#availableSize, new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), 1, 0, mobile, null, resetPageScaleFactor);
|
|
488
|
+
this.applyUserAgent('', null);
|
|
489
|
+
this.applyTouch(false, false);
|
|
490
|
+
}
|
|
491
|
+
else if (this.#type === Type.Responsive) {
|
|
492
|
+
let screenWidth = this.#widthSetting.get();
|
|
493
|
+
if (!screenWidth || screenWidth > this.preferredScaledWidth()) {
|
|
494
|
+
screenWidth = this.preferredScaledWidth();
|
|
495
|
+
}
|
|
496
|
+
let screenHeight = this.#heightSetting.get();
|
|
497
|
+
if (!screenHeight || screenHeight > this.preferredScaledHeight()) {
|
|
498
|
+
screenHeight = this.preferredScaledHeight();
|
|
499
|
+
}
|
|
500
|
+
const defaultDeviceScaleFactor = mobile ? defaultMobileScaleFactor : 0;
|
|
501
|
+
this.#fitScale = this.calculateFitScale(this.#widthSetting.get(), this.#heightSetting.get());
|
|
502
|
+
this.#appliedUserAgentType = this.#uaSetting.get();
|
|
503
|
+
this.applyDeviceMetrics(new Geometry.Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), this.#scaleSetting.get(), this.#deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile, screenHeight >= screenWidth ? "portraitPrimary" /* Protocol.Emulation.ScreenOrientationType.PortraitPrimary */ :
|
|
504
|
+
"landscapePrimary" /* Protocol.Emulation.ScreenOrientationType.LandscapePrimary */, resetPageScaleFactor);
|
|
505
|
+
this.applyUserAgent(mobile ? defaultMobileUserAgent : '', mobile ? defaultMobileUserAgentMetadata : null);
|
|
506
|
+
this.applyTouch(this.#uaSetting.get() === "Desktop (touch)" /* UA.DESKTOP_TOUCH */ || this.#uaSetting.get() === "Mobile" /* UA.MOBILE */, this.#uaSetting.get() === "Mobile" /* UA.MOBILE */);
|
|
507
|
+
}
|
|
508
|
+
if (overlayModel) {
|
|
509
|
+
overlayModel.setShowViewportSizeOnResize(this.#type === Type.None);
|
|
510
|
+
}
|
|
511
|
+
this.dispatchEventToListeners("Updated" /* Events.UPDATED */);
|
|
512
|
+
}
|
|
513
|
+
calculateFitScale(screenWidth, screenHeight, outline, insets) {
|
|
514
|
+
const outlineWidth = outline ? outline.left + outline.right : 0;
|
|
515
|
+
const outlineHeight = outline ? outline.top + outline.bottom : 0;
|
|
516
|
+
const insetsWidth = insets ? insets.left + insets.right : 0;
|
|
517
|
+
const insetsHeight = insets ? insets.top + insets.bottom : 0;
|
|
518
|
+
let scale = Math.min(screenWidth ? this.#preferredSize.width / (screenWidth + outlineWidth) : 1, screenHeight ? this.#preferredSize.height / (screenHeight + outlineHeight) : 1);
|
|
519
|
+
scale = Math.min(Math.floor(scale * 100), 100);
|
|
520
|
+
let sharpScale = scale;
|
|
521
|
+
while (sharpScale > scale * 0.7) {
|
|
522
|
+
let sharp = true;
|
|
523
|
+
if (screenWidth) {
|
|
524
|
+
sharp = sharp && Number.isInteger((screenWidth - insetsWidth) * sharpScale / 100);
|
|
525
|
+
}
|
|
526
|
+
if (screenHeight) {
|
|
527
|
+
sharp = sharp && Number.isInteger((screenHeight - insetsHeight) * sharpScale / 100);
|
|
528
|
+
}
|
|
529
|
+
if (sharp) {
|
|
530
|
+
return sharpScale / 100;
|
|
531
|
+
}
|
|
532
|
+
sharpScale -= 1;
|
|
533
|
+
}
|
|
534
|
+
return scale / 100;
|
|
535
|
+
}
|
|
536
|
+
setSizeAndScaleToFit(width, height) {
|
|
537
|
+
this.#scaleSetting.set(this.calculateFitScale(width, height));
|
|
538
|
+
this.setWidth(width);
|
|
539
|
+
this.setHeight(height);
|
|
540
|
+
}
|
|
541
|
+
applyUserAgent(userAgent, userAgentMetadata) {
|
|
542
|
+
SDK.NetworkManager.MultitargetNetworkManager.instance().setUserAgentOverride(userAgent, userAgentMetadata);
|
|
543
|
+
}
|
|
544
|
+
applyDeviceMetrics(screenSize, insets, outline, scale, deviceScaleFactor, mobile, screenOrientation, resetPageScaleFactor) {
|
|
545
|
+
screenSize.width = Math.max(1, Math.floor(screenSize.width));
|
|
546
|
+
screenSize.height = Math.max(1, Math.floor(screenSize.height));
|
|
547
|
+
let pageWidth = screenSize.width - insets.left - insets.right;
|
|
548
|
+
let pageHeight = screenSize.height - insets.top - insets.bottom;
|
|
549
|
+
const positionX = insets.left;
|
|
550
|
+
const positionY = insets.top;
|
|
551
|
+
const screenOrientationAngle = screenOrientation === "landscapePrimary" /* Protocol.Emulation.ScreenOrientationType.LandscapePrimary */ ? 90 : 0;
|
|
552
|
+
this.#appliedDeviceSize = screenSize;
|
|
553
|
+
this.#appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixelRatio;
|
|
554
|
+
this.#screenRect = new Rect(Math.max(0, (this.#availableSize.width - screenSize.width * scale) / 2), outline.top * scale, screenSize.width * scale, screenSize.height * scale);
|
|
555
|
+
this.#outlineRect = new Rect(this.#screenRect.left - outline.left * scale, 0, (outline.left + screenSize.width + outline.right) * scale, (outline.top + screenSize.height + outline.bottom) * scale);
|
|
556
|
+
this.#visiblePageRect = new Rect(positionX * scale, positionY * scale, Math.min(pageWidth * scale, this.#availableSize.width - this.#screenRect.left - positionX * scale), Math.min(pageHeight * scale, this.#availableSize.height - this.#screenRect.top - positionY * scale));
|
|
557
|
+
this.#scale = scale;
|
|
558
|
+
const displayFeature = this.getDisplayFeature();
|
|
559
|
+
if (!displayFeature) {
|
|
560
|
+
// When sending displayFeature, we cannot use the optimization below due to backend restrictions.
|
|
561
|
+
if (scale === 1 && this.#availableSize.width >= screenSize.width &&
|
|
562
|
+
this.#availableSize.height >= screenSize.height) {
|
|
563
|
+
// When we have enough space, no page size override is required. This will speed things up and remove lag.
|
|
564
|
+
pageWidth = 0;
|
|
565
|
+
pageHeight = 0;
|
|
566
|
+
}
|
|
567
|
+
if (this.#visiblePageRect.width === pageWidth * scale && this.#visiblePageRect.height === pageHeight * scale &&
|
|
568
|
+
Number.isInteger(pageWidth * scale) && Number.isInteger(pageHeight * scale)) {
|
|
569
|
+
// When we only have to apply scale, do not resize the page. This will speed things up and remove lag.
|
|
570
|
+
pageWidth = 0;
|
|
571
|
+
pageHeight = 0;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
if (!this.#emulationModel) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
if (resetPageScaleFactor) {
|
|
578
|
+
void this.#emulationModel.resetPageScaleFactor();
|
|
579
|
+
}
|
|
580
|
+
if (pageWidth || pageHeight || mobile || deviceScaleFactor || scale !== 1 || screenOrientation || displayFeature) {
|
|
581
|
+
const metrics = {
|
|
582
|
+
width: pageWidth,
|
|
583
|
+
height: pageHeight,
|
|
584
|
+
deviceScaleFactor,
|
|
585
|
+
mobile,
|
|
586
|
+
scale,
|
|
587
|
+
screenWidth: screenSize.width,
|
|
588
|
+
screenHeight: screenSize.height,
|
|
589
|
+
positionX,
|
|
590
|
+
positionY,
|
|
591
|
+
dontSetVisibleSize: true,
|
|
592
|
+
displayFeature: undefined,
|
|
593
|
+
devicePosture: undefined,
|
|
594
|
+
screenOrientation: undefined,
|
|
595
|
+
};
|
|
596
|
+
if (displayFeature) {
|
|
597
|
+
metrics.displayFeature = displayFeature;
|
|
598
|
+
metrics.devicePosture = { type: "folded" /* Protocol.Emulation.DevicePostureType.Folded */ };
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
metrics.devicePosture = { type: "continuous" /* Protocol.Emulation.DevicePostureType.Continuous */ };
|
|
602
|
+
}
|
|
603
|
+
if (screenOrientation) {
|
|
604
|
+
metrics.screenOrientation = { type: screenOrientation, angle: screenOrientationAngle };
|
|
605
|
+
}
|
|
606
|
+
void this.#emulationModel.emulateDevice(metrics);
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
void this.#emulationModel.emulateDevice(null);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
exitHingeMode() {
|
|
613
|
+
const overlayModel = this.#emulationModel ? this.#emulationModel.overlayModel() : null;
|
|
614
|
+
if (overlayModel) {
|
|
615
|
+
overlayModel.showHingeForDualScreen(null);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
async captureScreenshot(fullSize, clip) {
|
|
619
|
+
const screenCaptureModel = this.#emulationModel ? this.#emulationModel.target().model(SDK.ScreenCaptureModel.ScreenCaptureModel) : null;
|
|
620
|
+
if (!screenCaptureModel) {
|
|
621
|
+
return null;
|
|
622
|
+
}
|
|
623
|
+
let screenshotMode;
|
|
624
|
+
if (clip) {
|
|
625
|
+
screenshotMode = "fromClip" /* SDK.ScreenCaptureModel.ScreenshotMode.FROM_CLIP */;
|
|
626
|
+
}
|
|
627
|
+
else if (fullSize) {
|
|
628
|
+
screenshotMode = "fullpage" /* SDK.ScreenCaptureModel.ScreenshotMode.FULLPAGE */;
|
|
629
|
+
}
|
|
630
|
+
else {
|
|
631
|
+
screenshotMode = "fromViewport" /* SDK.ScreenCaptureModel.ScreenshotMode.FROM_VIEWPORT */;
|
|
632
|
+
}
|
|
633
|
+
const overlayModel = this.#emulationModel ? this.#emulationModel.overlayModel() : null;
|
|
634
|
+
if (overlayModel) {
|
|
635
|
+
overlayModel.setShowViewportSizeOnResize(false);
|
|
636
|
+
}
|
|
637
|
+
const screenshot = await screenCaptureModel.captureScreenshot("png" /* Protocol.Page.CaptureScreenshotRequestFormat.Png */, 100, screenshotMode, clip);
|
|
638
|
+
const deviceMetrics = {
|
|
639
|
+
width: 0,
|
|
640
|
+
height: 0,
|
|
641
|
+
deviceScaleFactor: 0,
|
|
642
|
+
mobile: false,
|
|
643
|
+
};
|
|
644
|
+
if (fullSize && this.#emulationModel) {
|
|
645
|
+
if (this.#device && this.#mode) {
|
|
646
|
+
const orientation = this.#device.orientationByName(this.#mode.orientation);
|
|
647
|
+
deviceMetrics.width = orientation.width;
|
|
648
|
+
deviceMetrics.height = orientation.height;
|
|
649
|
+
const dispFeature = this.getDisplayFeature();
|
|
650
|
+
if (dispFeature) {
|
|
651
|
+
// @ts-expect-error: displayFeature isn't in protocol.ts but is an
|
|
652
|
+
// experimental flag:
|
|
653
|
+
// https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setDeviceMetricsOverride
|
|
654
|
+
deviceMetrics.displayFeature = dispFeature;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
deviceMetrics.width = 0;
|
|
659
|
+
deviceMetrics.height = 0;
|
|
660
|
+
}
|
|
661
|
+
await this.#emulationModel.emulateDevice(deviceMetrics);
|
|
662
|
+
}
|
|
663
|
+
this.calculateAndEmulate(false);
|
|
664
|
+
return screenshot;
|
|
665
|
+
}
|
|
666
|
+
applyTouch(touchEnabled, mobile) {
|
|
667
|
+
this.#touchEnabled = touchEnabled;
|
|
668
|
+
this.#touchMobile = mobile;
|
|
669
|
+
for (const emulationModel of SDK.TargetManager.TargetManager.instance().models(SDK.EmulationModel.EmulationModel)) {
|
|
670
|
+
void emulationModel.emulateTouch(touchEnabled, mobile);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
showHingeIfApplicable(overlayModel) {
|
|
674
|
+
const orientation = (this.#device && this.#mode) ? this.#device.orientationByName(this.#mode.orientation) : null;
|
|
675
|
+
if (orientation?.hinge) {
|
|
676
|
+
overlayModel.showHingeForDualScreen(orientation.hinge);
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
overlayModel.showHingeForDualScreen(null);
|
|
680
|
+
}
|
|
681
|
+
getDisplayFeatureOrientation() {
|
|
682
|
+
if (!this.#mode) {
|
|
683
|
+
throw new Error('Mode required to get display feature orientation.');
|
|
684
|
+
}
|
|
685
|
+
switch (this.#mode.orientation) {
|
|
686
|
+
case VerticalSpanned:
|
|
687
|
+
case Vertical:
|
|
688
|
+
return "vertical" /* Protocol.Emulation.DisplayFeatureOrientation.Vertical */;
|
|
689
|
+
case HorizontalSpanned:
|
|
690
|
+
case Horizontal:
|
|
691
|
+
default:
|
|
692
|
+
return "horizontal" /* Protocol.Emulation.DisplayFeatureOrientation.Horizontal */;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
getDisplayFeature() {
|
|
696
|
+
if (!this.#device || !this.#mode ||
|
|
697
|
+
(this.#mode.orientation !== VerticalSpanned && this.#mode.orientation !== HorizontalSpanned)) {
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
const orientation = this.#device.orientationByName(this.#mode.orientation);
|
|
701
|
+
if (!orientation?.hinge) {
|
|
702
|
+
return null;
|
|
703
|
+
}
|
|
704
|
+
const hinge = orientation.hinge;
|
|
705
|
+
return {
|
|
706
|
+
orientation: this.getDisplayFeatureOrientation(),
|
|
707
|
+
offset: (this.#mode.orientation === VerticalSpanned) ? hinge.x : hinge.y,
|
|
708
|
+
maskLength: (this.#mode.orientation === VerticalSpanned) ? hinge.width : hinge.height,
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
export class Insets {
|
|
713
|
+
left;
|
|
714
|
+
top;
|
|
715
|
+
right;
|
|
716
|
+
bottom;
|
|
717
|
+
constructor(left, top, right, bottom) {
|
|
718
|
+
this.left = left;
|
|
719
|
+
this.top = top;
|
|
720
|
+
this.right = right;
|
|
721
|
+
this.bottom = bottom;
|
|
722
|
+
}
|
|
723
|
+
isEqual(insets) {
|
|
724
|
+
return insets !== null && this.left === insets.left && this.top === insets.top && this.right === insets.right &&
|
|
725
|
+
this.bottom === insets.bottom;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
export class Rect {
|
|
729
|
+
left;
|
|
730
|
+
top;
|
|
731
|
+
width;
|
|
732
|
+
height;
|
|
733
|
+
constructor(left, top, width, height) {
|
|
734
|
+
this.left = left;
|
|
735
|
+
this.top = top;
|
|
736
|
+
this.width = width;
|
|
737
|
+
this.height = height;
|
|
738
|
+
}
|
|
739
|
+
isEqual(rect) {
|
|
740
|
+
return rect !== null && this.left === rect.left && this.top === rect.top && this.width === rect.width &&
|
|
741
|
+
this.height === rect.height;
|
|
742
|
+
}
|
|
743
|
+
scale(scale) {
|
|
744
|
+
return new Rect(this.left * scale, this.top * scale, this.width * scale, this.height * scale);
|
|
745
|
+
}
|
|
746
|
+
relativeTo(origin) {
|
|
747
|
+
return new Rect(this.left - origin.left, this.top - origin.top, this.width, this.height);
|
|
748
|
+
}
|
|
749
|
+
rebaseTo(origin) {
|
|
750
|
+
return new Rect(this.left + origin.left, this.top + origin.top, this.width, this.height);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
export var Type;
|
|
754
|
+
(function (Type) {
|
|
755
|
+
/* eslint-disable @typescript-eslint/naming-convention -- Used by web_tests. */
|
|
756
|
+
Type["None"] = "None";
|
|
757
|
+
Type["Responsive"] = "Responsive";
|
|
758
|
+
Type["Device"] = "Device";
|
|
759
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
760
|
+
})(Type || (Type = {}));
|
|
761
|
+
export const MinDeviceSize = 50;
|
|
762
|
+
export const MaxDeviceSize = 9999;
|
|
763
|
+
export const MinDeviceScaleFactor = 0;
|
|
764
|
+
export const MaxDeviceScaleFactor = 10;
|
|
765
|
+
export const MaxDeviceNameLength = 50;
|
|
766
|
+
const mobileUserAgent = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36';
|
|
767
|
+
const defaultMobileUserAgent = SDK.NetworkManager.MultitargetNetworkManager.patchUserAgentWithChromeVersion(mobileUserAgent);
|
|
768
|
+
const defaultMobileUserAgentMetadata = {
|
|
769
|
+
platform: 'Android',
|
|
770
|
+
platformVersion: '6.0',
|
|
771
|
+
architecture: '',
|
|
772
|
+
model: 'Nexus 5',
|
|
773
|
+
mobile: true,
|
|
774
|
+
};
|
|
775
|
+
export const defaultMobileScaleFactor = 2;
|