chrome-devtools-frontend 1.0.1621678 → 1.0.1624409
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/foundation-test-migration/SKILL.md +171 -0
- package/.agents/skills/verification/SKILL.md +2 -11
- package/front_end/Images/src/expand.svg +1 -0
- package/front_end/core/common/Base64.ts +12 -2
- package/front_end/core/i18n/i18nImpl.ts +8 -4
- package/front_end/core/root/Runtime.ts +28 -9
- package/front_end/entrypoints/device_mode_emulation_frame/device_mode_emulation_frame.ts +1 -1
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +72 -8
- package/front_end/entrypoints/greendev_floaty/floaty.html +1 -1
- package/front_end/entrypoints/shell/shell.ts +1 -1
- package/front_end/generated/Deprecation.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/SupportedCSSProperties.js +6 -6
- package/front_end/generated/protocol.ts +1 -0
- package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +373 -112
- package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +57 -0
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +2 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +3 -9
- package/front_end/models/javascript_metadata/NativeFunctions.js +9 -4
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +295 -45
- package/front_end/panels/console/ConsoleView.ts +86 -7
- package/front_end/panels/console/ConsoleViewMessage.ts +23 -1
- package/front_end/panels/console/SymbolizedErrorWidget.ts +69 -0
- package/front_end/panels/console/console.ts +3 -0
- package/front_end/panels/elements/StylePropertiesSection.ts +1 -2
- package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
- package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +6 -2
- package/front_end/panels/elements/StylesSidebarPane.ts +17 -4
- package/front_end/panels/emulation/DeviceModeToolbar.ts +189 -132
- package/front_end/panels/emulation/deviceModeView.css +25 -0
- package/front_end/panels/greendev/GreenDevPanel.ts +30 -3
- package/front_end/panels/media/EventDisplayTable.ts +1 -1
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +48 -27
- package/front_end/panels/mobile_throttling/ThrottlingManager.ts +67 -38
- package/front_end/panels/network/NetworkConfigView.ts +1 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +1 -22
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +12 -4
- package/front_end/panels/timeline/components/liveMetricsView.css +2 -2
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/{core → ui}/dom_extension/DOMExtension.ts +1 -1
- package/front_end/ui/legacy/UIUtils.ts +26 -4
- package/front_end/ui/legacy/Widget.ts +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +19 -0
- package/package.json +1 -1
- package/front_end/panels/emulation/components/DeviceSizeInputElement.ts +0 -134
- package/front_end/panels/emulation/components/components.ts +0 -9
- /package/front_end/{core → ui}/dom_extension/dom_extension.ts +0 -0
|
@@ -10,12 +10,12 @@ import * as Host from '../../core/host/host.js';
|
|
|
10
10
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
11
11
|
import * as Platform from '../../core/platform/platform.js';
|
|
12
12
|
import * as EmulationModel from '../../models/emulation/emulation.js';
|
|
13
|
+
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
13
14
|
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
14
15
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
15
16
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
16
17
|
import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
|
|
17
18
|
|
|
18
|
-
import * as EmulationComponents from './components/components.js';
|
|
19
19
|
const UIStrings = {
|
|
20
20
|
/**
|
|
21
21
|
* @description Title of the device dimensions selection item in the Device Mode Toolbar.
|
|
@@ -194,9 +194,13 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
|
194
194
|
* than in the DevTools panel itself. Therefore, we need to fall back to using the
|
|
195
195
|
* built-in tooltip by setting the title attribute on the button's element.
|
|
196
196
|
*/
|
|
197
|
-
function setTitleForButton(button:
|
|
198
|
-
button.
|
|
199
|
-
|
|
197
|
+
function setTitleForButton(button: Buttons.Button.Button|UI.Toolbar.ToolbarMenuButton, title: string): void {
|
|
198
|
+
if (button instanceof UI.Toolbar.ToolbarMenuButton) {
|
|
199
|
+
button.setTitle(title);
|
|
200
|
+
button.element.title = title;
|
|
201
|
+
} else {
|
|
202
|
+
button.title = title;
|
|
203
|
+
}
|
|
200
204
|
}
|
|
201
205
|
|
|
202
206
|
export class DeviceModeToolbar {
|
|
@@ -211,19 +215,19 @@ export class DeviceModeToolbar {
|
|
|
211
215
|
readonly #element: HTMLDivElement;
|
|
212
216
|
private readonly emulatedDevicesList: EmulationModel.EmulatedDevices.EmulatedDevicesList;
|
|
213
217
|
private readonly persistenceSetting: Common.Settings.Setting<{device: string, orientation: string, mode: string}>;
|
|
214
|
-
private spanButton!:
|
|
215
|
-
private postureItem!:
|
|
216
|
-
private modeButton!:
|
|
217
|
-
private widthInput:
|
|
218
|
-
private heightInput:
|
|
219
|
-
private deviceScaleItem!:
|
|
220
|
-
private deviceScaleItems:
|
|
221
|
-
private deviceSelectItem!:
|
|
222
|
-
private scaleItem!:
|
|
223
|
-
private uaItem!:
|
|
218
|
+
private spanButton!: Buttons.Button.Button;
|
|
219
|
+
private postureItem!: HTMLSelectElement;
|
|
220
|
+
private modeButton!: Buttons.Button.Button;
|
|
221
|
+
private widthInput: HTMLInputElement;
|
|
222
|
+
private heightInput: HTMLInputElement;
|
|
223
|
+
private deviceScaleItem!: HTMLSelectElement;
|
|
224
|
+
private deviceScaleItems: HTMLElement[] = [];
|
|
225
|
+
private deviceSelectItem!: HTMLSelectElement;
|
|
226
|
+
private scaleItem!: HTMLSelectElement;
|
|
227
|
+
private uaItem!: HTMLSelectElement;
|
|
224
228
|
private cachedDeviceScale!: number|null;
|
|
225
229
|
private cachedUaType!: string|null;
|
|
226
|
-
private xItem?:
|
|
230
|
+
private xItem?: HTMLElement;
|
|
227
231
|
private cachedModelType?: EmulationModel.DeviceModeModel.Type;
|
|
228
232
|
private cachedScale?: number;
|
|
229
233
|
private cachedModelDevice?: EmulationModel.EmulatedDevices.EmulatedDevice|null;
|
|
@@ -250,10 +254,9 @@ export class DeviceModeToolbar {
|
|
|
250
254
|
Common.Settings.Settings.instance().createSetting('emulation.auto-adjust-scale', true);
|
|
251
255
|
|
|
252
256
|
this.lastMode = new Map();
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
this.heightInput =
|
|
256
|
-
i18nString(UIStrings.heightLeaveEmptyForFull), {jslogContext: 'height'});
|
|
257
|
+
|
|
258
|
+
this.widthInput = this.createSizeInput(i18nString(UIStrings.width), 'width');
|
|
259
|
+
this.heightInput = this.createSizeInput(i18nString(UIStrings.heightLeaveEmptyForFull), 'height');
|
|
257
260
|
|
|
258
261
|
this.#element = document.createElement('div');
|
|
259
262
|
this.#element.classList.add('device-mode-toolbar');
|
|
@@ -287,98 +290,158 @@ export class DeviceModeToolbar {
|
|
|
287
290
|
}
|
|
288
291
|
}
|
|
289
292
|
|
|
293
|
+
private appendOption(parentElement: HTMLElement, title: string, value: string, jslogContext: string): void {
|
|
294
|
+
const option = document.createElement('option');
|
|
295
|
+
option.text = title;
|
|
296
|
+
option.value = value;
|
|
297
|
+
option.setAttribute('jslog', `${VisualLogging.item(jslogContext).track({click: true})}`);
|
|
298
|
+
parentElement.appendChild(option);
|
|
299
|
+
}
|
|
300
|
+
|
|
290
301
|
private createEmptyToolbarElement(): HTMLDivElement {
|
|
291
302
|
const element = document.createElement('div');
|
|
292
303
|
element.classList.add('device-mode-empty-toolbar-element');
|
|
293
304
|
return element;
|
|
294
305
|
}
|
|
295
306
|
|
|
307
|
+
private createSizeInput(title: string, jslogContext: string): HTMLInputElement {
|
|
308
|
+
const input = document.createElement('input');
|
|
309
|
+
input.type = 'number';
|
|
310
|
+
input.max = String(EmulationModel.DeviceModeModel.MaxDeviceSize);
|
|
311
|
+
input.min = String(EmulationModel.DeviceModeModel.MinDeviceSize);
|
|
312
|
+
input.title = title;
|
|
313
|
+
input.classList.add('device-mode-size-input');
|
|
314
|
+
input.setAttribute('jslog', `${VisualLogging.textField().track({change: true}).context(jslogContext)}`);
|
|
315
|
+
|
|
316
|
+
input.addEventListener('keydown', (event: Event) => {
|
|
317
|
+
let modifiedValue = UI.UIUtils.modifiedFloatNumber(Number(input.value), event);
|
|
318
|
+
if (modifiedValue === null) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
modifiedValue = Math.min(modifiedValue, EmulationModel.DeviceModeModel.MaxDeviceSize);
|
|
322
|
+
modifiedValue = Math.max(modifiedValue, EmulationModel.DeviceModeModel.MinDeviceSize);
|
|
323
|
+
|
|
324
|
+
event.preventDefault();
|
|
325
|
+
input.value = String(modifiedValue);
|
|
326
|
+
input.dispatchEvent(new Event('change'));
|
|
327
|
+
});
|
|
328
|
+
return input;
|
|
329
|
+
}
|
|
330
|
+
|
|
296
331
|
private createMainToolbar(): UI.Toolbar.Toolbar {
|
|
297
332
|
const mainToolbar = this.#element.createChild('devtools-toolbar', 'main-toolbar');
|
|
298
333
|
|
|
299
|
-
mainToolbar.
|
|
300
|
-
this.deviceSelectItem =
|
|
301
|
-
|
|
302
|
-
this.deviceSelectItem.
|
|
303
|
-
|
|
304
|
-
|
|
334
|
+
mainToolbar.append(this.createEmptyToolbarElement());
|
|
335
|
+
this.deviceSelectItem = document.createElement('select');
|
|
336
|
+
this.deviceSelectItem.classList.add('dark-text', 'toolbar-has-dropdown-shrinkable');
|
|
337
|
+
this.deviceSelectItem.title = i18nString(UIStrings.deviceType);
|
|
338
|
+
UI.ARIAUtils.setLabel(this.deviceSelectItem, i18nString(UIStrings.deviceType));
|
|
339
|
+
this.deviceSelectItem.addEventListener('change', this.onDeviceChange.bind(this));
|
|
340
|
+
this.deviceSelectItem.setAttribute('jslog', `${VisualLogging.dropDown().track({change: true}).context('device')}`);
|
|
341
|
+
const dimensionsSpan = uiI18n.getFormatLocalizedString(str_, UIStrings.dimensions, {PH1: this.deviceSelectItem});
|
|
305
342
|
mainToolbar.append(...dimensionsSpan.childNodes);
|
|
306
|
-
mainToolbar.
|
|
343
|
+
mainToolbar.append(this.deviceSelectItem);
|
|
307
344
|
|
|
308
|
-
this.widthInput.addEventListener('
|
|
345
|
+
this.widthInput.addEventListener('change', () => {
|
|
346
|
+
const width = Number(this.widthInput.value);
|
|
309
347
|
if (this.autoAdjustScaleSetting.get()) {
|
|
310
348
|
this.model.setWidthAndScaleToFit(width);
|
|
311
349
|
} else {
|
|
312
350
|
this.model.setWidth(width);
|
|
313
351
|
}
|
|
314
352
|
});
|
|
315
|
-
this.heightInput.addEventListener('
|
|
353
|
+
this.heightInput.addEventListener('change', () => {
|
|
354
|
+
const height = Number(this.heightInput.value);
|
|
316
355
|
if (this.autoAdjustScaleSetting.get()) {
|
|
317
356
|
this.model.setHeightAndScaleToFit(height);
|
|
318
357
|
} else {
|
|
319
358
|
this.model.setHeight(height);
|
|
320
359
|
}
|
|
321
360
|
});
|
|
322
|
-
mainToolbar.
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
this.xItem
|
|
327
|
-
mainToolbar.
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
this.scaleItem
|
|
332
|
-
|
|
333
|
-
this.scaleItem.
|
|
334
|
-
|
|
361
|
+
mainToolbar.append(this.widthInput);
|
|
362
|
+
this.xItem = document.createElement('div');
|
|
363
|
+
this.xItem.classList.add('device-mode-x');
|
|
364
|
+
this.xItem.textContent = '×';
|
|
365
|
+
mainToolbar.append(this.xItem);
|
|
366
|
+
mainToolbar.append(this.heightInput);
|
|
367
|
+
|
|
368
|
+
mainToolbar.append(this.createEmptyToolbarElement());
|
|
369
|
+
this.scaleItem = document.createElement('select');
|
|
370
|
+
this.scaleItem.classList.add('dark-text', 'toolbar-has-dropdown-shrinkable');
|
|
371
|
+
this.scaleItem.title = i18nString(UIStrings.zoom);
|
|
372
|
+
UI.ARIAUtils.setLabel(this.scaleItem, i18nString(UIStrings.zoom));
|
|
373
|
+
this.scaleItem.addEventListener('change', this.onScaleChange.bind(this));
|
|
374
|
+
this.scaleItem.setAttribute('jslog', `${VisualLogging.dropDown().track({change: true}).context('scale')}`);
|
|
375
|
+
mainToolbar.append(this.scaleItem);
|
|
335
376
|
|
|
336
377
|
const autoAdjustScaleButton = new UI.Toolbar.ToolbarSettingToggle(
|
|
337
378
|
this.autoAdjustScaleSetting, 'center-focus-weak', i18nString(UIStrings.autoadjustZoom));
|
|
338
379
|
mainToolbar.appendToolbarItem(autoAdjustScaleButton);
|
|
339
380
|
|
|
340
|
-
mainToolbar.
|
|
381
|
+
mainToolbar.append(this.createEmptyToolbarElement());
|
|
341
382
|
|
|
342
|
-
this.deviceScaleItem =
|
|
343
|
-
|
|
344
|
-
this.deviceScaleItem.
|
|
345
|
-
|
|
383
|
+
this.deviceScaleItem = document.createElement('select');
|
|
384
|
+
this.deviceScaleItem.classList.add('dark-text', 'toolbar-has-dropdown-shrinkable');
|
|
385
|
+
this.deviceScaleItem.title = i18nString(UIStrings.devicePixelRatio);
|
|
386
|
+
UI.ARIAUtils.setLabel(this.deviceScaleItem, i18nString(UIStrings.devicePixelRatio));
|
|
387
|
+
this.deviceScaleItem.addEventListener('change', this.onDeviceScaleChange.bind(this));
|
|
388
|
+
this.deviceScaleItem.setAttribute(
|
|
389
|
+
'jslog', `${VisualLogging.dropDown().track({change: true}).context('device-pixel-ratio')}`);
|
|
390
|
+
const deviceScaleSpan = uiI18n.getFormatLocalizedString(str_, UIStrings.dpr, {PH1: this.deviceScaleItem});
|
|
346
391
|
for (const node of Array.from(deviceScaleSpan.childNodes)) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
392
|
+
if (node === this.deviceScaleItem) {
|
|
393
|
+
this.deviceScaleItem.classList.toggle('hidden', !this.showDeviceScaleFactorSetting.get());
|
|
394
|
+
this.deviceScaleItems.push(this.deviceScaleItem);
|
|
395
|
+
mainToolbar.append(this.deviceScaleItem);
|
|
396
|
+
} else {
|
|
397
|
+
const item = new UI.Toolbar.ToolbarText(node.textContent || '');
|
|
398
|
+
item.setVisible(this.showDeviceScaleFactorSetting.get());
|
|
399
|
+
this.deviceScaleItems.push(item.element);
|
|
400
|
+
mainToolbar.appendToolbarItem(item);
|
|
401
|
+
}
|
|
352
402
|
}
|
|
353
|
-
mainToolbar.
|
|
354
|
-
this.uaItem =
|
|
355
|
-
|
|
356
|
-
this.uaItem.
|
|
357
|
-
|
|
358
|
-
|
|
403
|
+
mainToolbar.append(this.createEmptyToolbarElement());
|
|
404
|
+
this.uaItem = document.createElement('select');
|
|
405
|
+
this.uaItem.classList.add('dark-text', 'toolbar-has-dropdown-shrinkable');
|
|
406
|
+
this.uaItem.title = i18nString(UIStrings.deviceType);
|
|
407
|
+
UI.ARIAUtils.setLabel(this.uaItem, i18nString(UIStrings.deviceType));
|
|
408
|
+
this.uaItem.addEventListener('change', this.onUAChange.bind(this));
|
|
409
|
+
this.uaItem.setAttribute('jslog', `${VisualLogging.dropDown().track({change: true}).context('device-type')}`);
|
|
410
|
+
this.uaItem.classList.toggle('hidden', !this.showUserAgentTypeSetting.get());
|
|
411
|
+
mainToolbar.append(this.uaItem);
|
|
359
412
|
|
|
360
413
|
MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelect.createForGlobalConditions(
|
|
361
414
|
mainToolbar, i18nString(UIStrings.throttling));
|
|
362
415
|
const saveDataItem = MobileThrottling.ThrottlingManager.throttlingManager().createSaveDataOverrideSelector();
|
|
363
|
-
saveDataItem.
|
|
364
|
-
mainToolbar.
|
|
416
|
+
saveDataItem.classList.add('dark-text', 'toolbar-has-dropdown-shrinkable');
|
|
417
|
+
mainToolbar.append(saveDataItem);
|
|
365
418
|
|
|
366
|
-
mainToolbar.
|
|
367
|
-
this.modeButton = new
|
|
368
|
-
this.modeButton.
|
|
369
|
-
|
|
419
|
+
mainToolbar.append(this.createEmptyToolbarElement());
|
|
420
|
+
this.modeButton = new Buttons.Button.Button();
|
|
421
|
+
this.modeButton.classList.add('toolbar-button');
|
|
422
|
+
this.modeButton.data = {variant: Buttons.Button.Variant.ICON, iconName: 'screen-rotation'};
|
|
423
|
+
this.modeButton.setAttribute('jslog', `${VisualLogging.action('screen-rotation').track({click: true})}`);
|
|
424
|
+
this.modeButton.addEventListener('click', this.modeMenuClicked.bind(this));
|
|
425
|
+
mainToolbar.append(this.modeButton);
|
|
370
426
|
|
|
371
427
|
// Show dual screen toolbar.
|
|
372
|
-
this.spanButton = new
|
|
373
|
-
this.spanButton.
|
|
374
|
-
|
|
428
|
+
this.spanButton = new Buttons.Button.Button();
|
|
429
|
+
this.spanButton.classList.add('toolbar-button');
|
|
430
|
+
this.spanButton.data = {variant: Buttons.Button.Variant.ICON, iconName: 'device-fold'};
|
|
431
|
+
this.spanButton.setAttribute('jslog', `${VisualLogging.action('device-fold').track({click: true})}`);
|
|
432
|
+
this.spanButton.addEventListener('click', this.spanClicked.bind(this));
|
|
433
|
+
mainToolbar.append(this.spanButton);
|
|
375
434
|
|
|
376
435
|
// Show posture toolbar menu for foldable devices.
|
|
377
|
-
mainToolbar.
|
|
378
|
-
this.postureItem =
|
|
379
|
-
|
|
380
|
-
this.postureItem.
|
|
381
|
-
|
|
436
|
+
mainToolbar.append(this.createEmptyToolbarElement());
|
|
437
|
+
this.postureItem = document.createElement('select');
|
|
438
|
+
this.postureItem.classList.add('dark-text', 'toolbar-has-dropdown-shrinkable');
|
|
439
|
+
this.postureItem.title = i18nString(UIStrings.devicePosture);
|
|
440
|
+
UI.ARIAUtils.setLabel(this.postureItem, i18nString(UIStrings.devicePosture));
|
|
441
|
+
this.postureItem.addEventListener('change', this.onPostureChange.bind(this));
|
|
442
|
+
this.postureItem.setAttribute(
|
|
443
|
+
'jslog', `${VisualLogging.dropDown().track({change: true}).context('device-posture')}`);
|
|
444
|
+
mainToolbar.append(this.postureItem);
|
|
382
445
|
|
|
383
446
|
return mainToolbar;
|
|
384
447
|
}
|
|
@@ -400,19 +463,19 @@ export class DeviceModeToolbar {
|
|
|
400
463
|
}
|
|
401
464
|
|
|
402
465
|
private updateDevicePostureItems(): void {
|
|
403
|
-
this.postureItem.
|
|
466
|
+
this.postureItem.replaceChildren();
|
|
404
467
|
for (const option of this.getDevicePostureOptions()) {
|
|
405
|
-
this.postureItem
|
|
468
|
+
this.appendOption(this.postureItem, option.title, option.value, option.title.toLowerCase());
|
|
406
469
|
}
|
|
407
470
|
const currentPosture = this.currentDevicePosture();
|
|
408
|
-
if (this.postureItem.
|
|
409
|
-
this.postureItem.
|
|
471
|
+
if (this.postureItem.value !== currentPosture) {
|
|
472
|
+
this.postureItem.value = currentPosture;
|
|
410
473
|
}
|
|
411
474
|
this.resizeItem(this.postureItem);
|
|
412
475
|
}
|
|
413
476
|
|
|
414
477
|
private onPostureChange(): void {
|
|
415
|
-
const value = this.postureItem.
|
|
478
|
+
const value = this.postureItem.value;
|
|
416
479
|
if (value !== this.currentDevicePosture()) {
|
|
417
480
|
this.spanClicked();
|
|
418
481
|
}
|
|
@@ -461,20 +524,20 @@ export class DeviceModeToolbar {
|
|
|
461
524
|
}
|
|
462
525
|
|
|
463
526
|
private updateScaleMenuItems(): void {
|
|
464
|
-
this.scaleItem.
|
|
527
|
+
this.scaleItem.replaceChildren();
|
|
465
528
|
const options = this.getScaleOptions();
|
|
466
529
|
for (const option of options) {
|
|
467
|
-
this.scaleItem
|
|
530
|
+
this.appendOption(this.scaleItem, option.title, String(option.value), option.jslogContext);
|
|
468
531
|
}
|
|
469
532
|
const selected = options.find(o => o.selected);
|
|
470
533
|
if (selected) {
|
|
471
|
-
this.scaleItem.
|
|
534
|
+
this.scaleItem.value = String(selected.value);
|
|
472
535
|
}
|
|
473
536
|
this.resizeItem(this.scaleItem, true);
|
|
474
537
|
}
|
|
475
538
|
|
|
476
539
|
private onScaleChange(): void {
|
|
477
|
-
const value = Number(this.scaleItem.
|
|
540
|
+
const value = Number(this.scaleItem.value);
|
|
478
541
|
this.model.scaleSetting().set(value);
|
|
479
542
|
}
|
|
480
543
|
|
|
@@ -509,20 +572,20 @@ export class DeviceModeToolbar {
|
|
|
509
572
|
}
|
|
510
573
|
|
|
511
574
|
private updateDeviceScaleMenuItems(): void {
|
|
512
|
-
this.deviceScaleItem.
|
|
575
|
+
this.deviceScaleItem.replaceChildren();
|
|
513
576
|
const options = this.getDeviceScaleFactorOptions();
|
|
514
577
|
for (const option of options) {
|
|
515
|
-
this.deviceScaleItem
|
|
578
|
+
this.appendOption(this.deviceScaleItem, option.title, String(option.value), option.jslogContext);
|
|
516
579
|
}
|
|
517
580
|
const selected = options.find(o => o.selected);
|
|
518
581
|
if (selected) {
|
|
519
|
-
this.deviceScaleItem.
|
|
582
|
+
this.deviceScaleItem.value = String(selected.value);
|
|
520
583
|
}
|
|
521
584
|
this.resizeItem(this.deviceScaleItem, true);
|
|
522
585
|
}
|
|
523
586
|
|
|
524
587
|
private onDeviceScaleChange(): void {
|
|
525
|
-
const value = Number(this.deviceScaleItem.
|
|
588
|
+
const value = Number(this.deviceScaleItem.value);
|
|
526
589
|
this.model.deviceScaleFactorSetting().set(value);
|
|
527
590
|
}
|
|
528
591
|
|
|
@@ -544,20 +607,20 @@ export class DeviceModeToolbar {
|
|
|
544
607
|
}
|
|
545
608
|
|
|
546
609
|
private updateUserAgentMenuItems(): void {
|
|
547
|
-
this.uaItem.
|
|
610
|
+
this.uaItem.replaceChildren();
|
|
548
611
|
const options = this.getUserAgentOptions();
|
|
549
612
|
for (const option of options) {
|
|
550
|
-
this.uaItem
|
|
613
|
+
this.appendOption(this.uaItem, option.title, option.value, option.jslogContext);
|
|
551
614
|
}
|
|
552
615
|
const selected = options.find(o => o.selected);
|
|
553
616
|
if (selected) {
|
|
554
|
-
this.uaItem.
|
|
617
|
+
this.uaItem.value = selected.value;
|
|
555
618
|
}
|
|
556
619
|
this.resizeItem(this.uaItem);
|
|
557
620
|
}
|
|
558
621
|
|
|
559
622
|
private onUAChange(): void {
|
|
560
|
-
const value = this.uaItem.
|
|
623
|
+
const value = this.uaItem.value as EmulationModel.DeviceModeModel.UA;
|
|
561
624
|
this.model.uaSetting().set(value);
|
|
562
625
|
this.resizeItem(this.uaItem);
|
|
563
626
|
}
|
|
@@ -685,15 +748,15 @@ export class DeviceModeToolbar {
|
|
|
685
748
|
}
|
|
686
749
|
|
|
687
750
|
private updateDeviceMenuItems(): void {
|
|
688
|
-
this.deviceSelectItem.
|
|
751
|
+
this.deviceSelectItem.replaceChildren();
|
|
689
752
|
const options = this.getDeviceModeOptions();
|
|
690
753
|
|
|
691
|
-
this.deviceSelectItem
|
|
754
|
+
this.appendOption(this.deviceSelectItem, options.responsive.title, 'Responsive', options.responsive.jslogContext);
|
|
692
755
|
|
|
693
756
|
appendGroup.call(this, options.standard, 'Standard');
|
|
694
757
|
appendGroup.call(this, options.custom, 'Custom');
|
|
695
758
|
|
|
696
|
-
this.deviceSelectItem
|
|
759
|
+
this.appendOption(this.deviceSelectItem, options.edit.title, 'Edit', options.edit.jslogContext);
|
|
697
760
|
|
|
698
761
|
this.updateDeviceSelection();
|
|
699
762
|
|
|
@@ -705,28 +768,24 @@ export class DeviceModeToolbar {
|
|
|
705
768
|
const optGroup = document.createElement('optgroup');
|
|
706
769
|
optGroup.label = label;
|
|
707
770
|
for (const item of group) {
|
|
708
|
-
|
|
709
|
-
option.value = item.title;
|
|
710
|
-
option.text = item.title;
|
|
711
|
-
option.setAttribute('jslog', `${VisualLogging.item(item.jslogContext).track({click: true})}`);
|
|
712
|
-
optGroup.appendChild(option);
|
|
771
|
+
this.appendOption(optGroup, item.title, item.title, item.jslogContext);
|
|
713
772
|
}
|
|
714
|
-
this.deviceSelectItem.
|
|
773
|
+
this.deviceSelectItem.appendChild(optGroup);
|
|
715
774
|
}
|
|
716
775
|
}
|
|
717
776
|
|
|
718
777
|
private updateDeviceSelection(): void {
|
|
719
778
|
const device = this.model.device();
|
|
720
779
|
if (this.model.type() === EmulationModel.DeviceModeModel.Type.Responsive) {
|
|
721
|
-
this.deviceSelectItem.
|
|
780
|
+
this.deviceSelectItem.value = 'Responsive';
|
|
722
781
|
} else if (device) {
|
|
723
|
-
this.deviceSelectItem.
|
|
782
|
+
this.deviceSelectItem.value = device.title;
|
|
724
783
|
}
|
|
725
784
|
this.resizeItem(this.deviceSelectItem);
|
|
726
785
|
}
|
|
727
786
|
|
|
728
787
|
private onDeviceChange(): void {
|
|
729
|
-
const value = this.deviceSelectItem.
|
|
788
|
+
const value = this.deviceSelectItem.value;
|
|
730
789
|
if (value === 'Edit') {
|
|
731
790
|
this.emulatedDevicesList.revealCustomSetting();
|
|
732
791
|
this.updateDeviceSelection();
|
|
@@ -764,9 +823,9 @@ export class DeviceModeToolbar {
|
|
|
764
823
|
private updateDeviceScaleFactorVisibility(): void {
|
|
765
824
|
if (this.deviceScaleItem) {
|
|
766
825
|
const visible = this.showDeviceScaleFactorSetting.get();
|
|
767
|
-
this.deviceScaleItem.
|
|
826
|
+
this.deviceScaleItem.classList.toggle('hidden', !visible);
|
|
768
827
|
for (const item of this.deviceScaleItems) {
|
|
769
|
-
item.
|
|
828
|
+
item.classList.toggle('hidden', !visible);
|
|
770
829
|
}
|
|
771
830
|
}
|
|
772
831
|
}
|
|
@@ -774,7 +833,7 @@ export class DeviceModeToolbar {
|
|
|
774
833
|
private updateUserAgentTypeVisibility(): void {
|
|
775
834
|
if (this.uaItem) {
|
|
776
835
|
const visible = this.showUserAgentTypeSetting.get();
|
|
777
|
-
this.uaItem.
|
|
836
|
+
this.uaItem.classList.toggle('hidden', !visible);
|
|
778
837
|
if (visible) {
|
|
779
838
|
this.resizeItem(this.uaItem);
|
|
780
839
|
}
|
|
@@ -802,9 +861,7 @@ export class DeviceModeToolbar {
|
|
|
802
861
|
return;
|
|
803
862
|
}
|
|
804
863
|
|
|
805
|
-
private modeMenuClicked(event: {
|
|
806
|
-
data: Event,
|
|
807
|
-
}): void {
|
|
864
|
+
private modeMenuClicked(event: Event): void {
|
|
808
865
|
if (this.model.isScreenOrientationLocked()) {
|
|
809
866
|
return;
|
|
810
867
|
}
|
|
@@ -847,9 +904,9 @@ export class DeviceModeToolbar {
|
|
|
847
904
|
return;
|
|
848
905
|
}
|
|
849
906
|
|
|
850
|
-
const contextMenu = new UI.ContextMenu.ContextMenu(event
|
|
851
|
-
x: this.modeButton.
|
|
852
|
-
y: this.modeButton.
|
|
907
|
+
const contextMenu = new UI.ContextMenu.ContextMenu(event, {
|
|
908
|
+
x: this.modeButton.getBoundingClientRect().left,
|
|
909
|
+
y: this.modeButton.getBoundingClientRect().top + this.modeButton.offsetHeight,
|
|
853
910
|
});
|
|
854
911
|
addOrientation(EmulationModel.EmulatedDevices.Vertical, i18nString(UIStrings.portrait));
|
|
855
912
|
addOrientation(EmulationModel.EmulatedDevices.Horizontal, i18nString(UIStrings.landscape));
|
|
@@ -902,20 +959,20 @@ export class DeviceModeToolbar {
|
|
|
902
959
|
this.widthInput.disabled = this.model.type() !== EmulationModel.DeviceModeModel.Type.Responsive;
|
|
903
960
|
|
|
904
961
|
this.heightInput.disabled = this.model.type() !== EmulationModel.DeviceModeModel.Type.Responsive;
|
|
905
|
-
this.deviceScaleItem.
|
|
906
|
-
this.uaItem.
|
|
962
|
+
this.deviceScaleItem.disabled = this.model.type() !== EmulationModel.DeviceModeModel.Type.Responsive;
|
|
963
|
+
this.uaItem.disabled = this.model.type() !== EmulationModel.DeviceModeModel.Type.Responsive;
|
|
907
964
|
|
|
908
965
|
if (this.model.type() === EmulationModel.DeviceModeModel.Type.Responsive) {
|
|
909
|
-
this.modeButton.
|
|
966
|
+
this.modeButton.disabled = false;
|
|
910
967
|
setTitleForButton(this.modeButton, i18nString(UIStrings.rotate));
|
|
911
968
|
} else {
|
|
912
|
-
this.modeButton.
|
|
969
|
+
this.modeButton.disabled = true;
|
|
913
970
|
}
|
|
914
971
|
}
|
|
915
972
|
|
|
916
973
|
const size = this.model.appliedDeviceSize();
|
|
917
|
-
this.widthInput.
|
|
918
|
-
this.heightInput.
|
|
974
|
+
this.widthInput.value = String(size.width);
|
|
975
|
+
this.heightInput.value =
|
|
919
976
|
this.model.type() === EmulationModel.DeviceModeModel.Type.Responsive && this.model.isFullHeight() ?
|
|
920
977
|
'' :
|
|
921
978
|
String(size.height);
|
|
@@ -928,14 +985,14 @@ export class DeviceModeToolbar {
|
|
|
928
985
|
|
|
929
986
|
const deviceScale = this.model.appliedDeviceScaleFactor();
|
|
930
987
|
if (deviceScale !== this.cachedDeviceScale) {
|
|
931
|
-
this.deviceScaleItem.
|
|
988
|
+
this.deviceScaleItem.value = String(deviceScale);
|
|
932
989
|
this.cachedDeviceScale = deviceScale;
|
|
933
990
|
this.resizeItem(this.deviceScaleItem, true);
|
|
934
991
|
}
|
|
935
992
|
|
|
936
993
|
const uaType = this.model.appliedUserAgentType();
|
|
937
994
|
if (uaType !== this.cachedUaType) {
|
|
938
|
-
this.uaItem.
|
|
995
|
+
this.uaItem.value = uaType;
|
|
939
996
|
this.cachedUaType = uaType;
|
|
940
997
|
this.updateDeviceScaleMenuItems();
|
|
941
998
|
this.resizeItem(this.uaItem);
|
|
@@ -948,7 +1005,7 @@ export class DeviceModeToolbar {
|
|
|
948
1005
|
const device = this.model.device();
|
|
949
1006
|
if (device) {
|
|
950
1007
|
const modeCount = device ? device.modes.length : 0;
|
|
951
|
-
this.modeButton.
|
|
1008
|
+
this.modeButton.disabled = modeCount < 2;
|
|
952
1009
|
setTitleForButton(
|
|
953
1010
|
this.modeButton,
|
|
954
1011
|
modeCount === 2 ? i18nString(UIStrings.rotate) : i18nString(UIStrings.screenOrientationOptions));
|
|
@@ -957,15 +1014,15 @@ export class DeviceModeToolbar {
|
|
|
957
1014
|
}
|
|
958
1015
|
|
|
959
1016
|
if (device?.isDualScreen) {
|
|
960
|
-
this.spanButton.
|
|
961
|
-
this.postureItem.
|
|
1017
|
+
this.spanButton.classList.toggle('hidden', false);
|
|
1018
|
+
this.postureItem.classList.toggle('hidden', true);
|
|
962
1019
|
} else if (device?.isFoldableScreen) {
|
|
963
|
-
this.spanButton.
|
|
964
|
-
this.postureItem.
|
|
1020
|
+
this.spanButton.classList.toggle('hidden', true);
|
|
1021
|
+
this.postureItem.classList.toggle('hidden', false);
|
|
965
1022
|
this.updateDevicePostureItems();
|
|
966
1023
|
} else {
|
|
967
|
-
this.spanButton.
|
|
968
|
-
this.postureItem.
|
|
1024
|
+
this.spanButton.classList.toggle('hidden', true);
|
|
1025
|
+
this.postureItem.classList.toggle('hidden', true);
|
|
969
1026
|
}
|
|
970
1027
|
setTitleForButton(this.spanButton, i18nString(UIStrings.toggleDualscreenMode));
|
|
971
1028
|
|
|
@@ -996,16 +1053,16 @@ export class DeviceModeToolbar {
|
|
|
996
1053
|
// disable the rotate button to prevent user-initiated rotation.
|
|
997
1054
|
// When unlocked, restore the button to its normal state.
|
|
998
1055
|
if (this.model.isScreenOrientationLocked()) {
|
|
999
|
-
this.modeButton.
|
|
1056
|
+
this.modeButton.disabled = true;
|
|
1000
1057
|
setTitleForButton(this.modeButton, i18nString(UIStrings.screenOrientationLocked));
|
|
1001
1058
|
} else if (this.cachedModelDevice) {
|
|
1002
1059
|
const modeCount = this.cachedModelDevice.modes.length;
|
|
1003
|
-
this.modeButton.
|
|
1060
|
+
this.modeButton.disabled = modeCount < 2;
|
|
1004
1061
|
setTitleForButton(
|
|
1005
1062
|
this.modeButton,
|
|
1006
1063
|
modeCount === 2 ? i18nString(UIStrings.rotate) : i18nString(UIStrings.screenOrientationOptions));
|
|
1007
1064
|
} else if (this.model.type() === EmulationModel.DeviceModeModel.Type.Responsive) {
|
|
1008
|
-
this.modeButton.
|
|
1065
|
+
this.modeButton.disabled = false;
|
|
1009
1066
|
setTitleForButton(this.modeButton, i18nString(UIStrings.rotate));
|
|
1010
1067
|
}
|
|
1011
1068
|
}
|
|
@@ -1027,13 +1084,13 @@ export class DeviceModeToolbar {
|
|
|
1027
1084
|
this.model.emulate(EmulationModel.DeviceModeModel.Type.Responsive, null, null);
|
|
1028
1085
|
}
|
|
1029
1086
|
|
|
1030
|
-
private resizeItem(item:
|
|
1031
|
-
const selectedOption = item.
|
|
1087
|
+
private resizeItem(item: HTMLSelectElement, stripParens = false): void {
|
|
1088
|
+
const selectedOption = item.options[item.selectedIndex];
|
|
1032
1089
|
if (!selectedOption) {
|
|
1033
1090
|
return;
|
|
1034
1091
|
}
|
|
1035
1092
|
|
|
1036
|
-
const dummySelect = item.
|
|
1093
|
+
const dummySelect = item.cloneNode(false) as HTMLSelectElement;
|
|
1037
1094
|
const dummyOption = selectedOption.cloneNode(true) as HTMLOptionElement;
|
|
1038
1095
|
|
|
1039
1096
|
if (stripParens) {
|
|
@@ -1049,8 +1106,8 @@ export class DeviceModeToolbar {
|
|
|
1049
1106
|
dummySelect.style.visibility = 'hidden';
|
|
1050
1107
|
dummySelect.style.pointerEvents = 'none';
|
|
1051
1108
|
|
|
1052
|
-
item.
|
|
1053
|
-
item.
|
|
1109
|
+
item.parentElement?.appendChild(dummySelect);
|
|
1110
|
+
item.style.width = dummySelect.offsetWidth + 'px';
|
|
1054
1111
|
dummySelect.remove();
|
|
1055
1112
|
}
|
|
1056
1113
|
}
|
|
@@ -25,6 +25,31 @@
|
|
|
25
25
|
font-size: 16px;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
.device-mode-size-input {
|
|
29
|
+
/*
|
|
30
|
+
* 4 characters for the maximum size of the value,
|
|
31
|
+
* 2 characters for the width of the step-buttons,
|
|
32
|
+
* 2 pixels padding between the characters and the
|
|
33
|
+
* step-buttons.
|
|
34
|
+
*/
|
|
35
|
+
width: calc(4ch + 2ch + 2px);
|
|
36
|
+
max-height: 18px;
|
|
37
|
+
border: var(--sys-color-neutral-outline);
|
|
38
|
+
border-radius: 4px;
|
|
39
|
+
margin: 0 2px;
|
|
40
|
+
text-align: center;
|
|
41
|
+
font-size: inherit;
|
|
42
|
+
font-family: inherit;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.device-mode-size-input:disabled {
|
|
46
|
+
user-select: none;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.device-mode-size-input:focus::-webkit-input-placeholder {
|
|
50
|
+
color: transparent;
|
|
51
|
+
}
|
|
52
|
+
|
|
28
53
|
.device-mode-empty-toolbar-element {
|
|
29
54
|
width: 0;
|
|
30
55
|
}
|