chrome-devtools-frontend 1.0.1595925 → 1.0.1596260
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/.stylelintrc.json +3 -1
- package/docs/ui_engineering.md +0 -36
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/DOMModel.ts +206 -0
- package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
- package/front_end/entrypoints/greendev_floaty/floaty.css +2 -2
- package/front_end/entrypoints/main/MainImpl.ts +0 -5
- package/front_end/models/ai_assistance/ConversationHandler.ts +1 -1
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +48 -31
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +28 -4
- package/front_end/panels/ai_assistance/components/chatMessage.css +4 -2
- package/front_end/panels/application/IndexedDBModel.ts +2 -4
- package/front_end/panels/application/ServiceWorkersView.ts +3 -11
- package/front_end/panels/developer_resources/DeveloperResourcesListView.ts +1 -1
- package/front_end/panels/elements/ComputedStyleWidget.ts +25 -16
- package/front_end/panels/elements/ElementsPanel.ts +0 -1
- package/front_end/panels/elements/StylePropertyTreeElement.ts +11 -5
- package/front_end/panels/elements/nodeStackTraceWidget.css +1 -1
- package/front_end/panels/emulation/DeviceModeToolbar.ts +171 -89
- package/front_end/panels/greendev/GreenDevPanel.css +2 -2
- package/front_end/panels/issues/AffectedPermissionElementsView.ts +9 -6
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +11 -3
- package/front_end/panels/settings/components/SyncSection.ts +4 -13
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +2 -15
- package/front_end/panels/timeline/RecordingMetadata.ts +1 -1
- package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
- package/front_end/panels/timeline/TimelineUIUtils.ts +7 -4
- package/front_end/panels/timeline/components/Utils.ts +2 -2
- package/front_end/panels/webauthn/webauthnPane.css +1 -1
- package/front_end/ui/components/tree_outline/TreeOutline.ts +1 -1
- package/front_end/ui/legacy/ProgressIndicator.ts +1 -1
- package/front_end/ui/legacy/Toolbar.ts +1 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +14 -7
- package/front_end/ui/legacy/legacy.ts +0 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +4 -0
- package/inspector_overlay/loadCSS.rollup.js +2 -2
- package/inspector_overlay/tool_source_order.css +1 -0
- package/package.json +1 -1
- package/front_end/ui/legacy/Fragment.ts +0 -234
|
@@ -10,6 +10,7 @@ import * as SDK from '../../core/sdk/sdk.js';
|
|
|
10
10
|
import type * as Protocol from '../../generated/protocol.js';
|
|
11
11
|
import * as NetworkForward from '../../panels/network/forward/forward.js';
|
|
12
12
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
13
|
+
import {Link} from '../../ui/kit/kit.js';
|
|
13
14
|
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
14
15
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
15
16
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
@@ -227,17 +228,8 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
|
|
|
227
228
|
othersView.show(othersDiv);
|
|
228
229
|
const othersSection = othersView.appendSection(i18nString(UIStrings.serviceWorkersFromOtherOrigins));
|
|
229
230
|
const othersSectionRow = othersSection.appendRow();
|
|
230
|
-
const seeOthers =
|
|
231
|
-
|
|
232
|
-
.html`<a class="devtools-link" role="link" tabindex="0" href="chrome://serviceworker-internals" target="_blank" style="display: inline; cursor: pointer;">${
|
|
233
|
-
i18nString(UIStrings.seeAllRegistrations)}</a>`;
|
|
234
|
-
seeOthers.setAttribute('jslog', `${VisualLogging.link('view-all').track({click: true})}`);
|
|
235
|
-
self.onInvokeElement(seeOthers, event => {
|
|
236
|
-
const rootTarget = SDK.TargetManager.TargetManager.instance().rootTarget();
|
|
237
|
-
rootTarget &&
|
|
238
|
-
void rootTarget.targetAgent().invoke_createTarget({url: 'chrome://serviceworker-internals?devtools'});
|
|
239
|
-
event.consume(true);
|
|
240
|
-
});
|
|
231
|
+
const seeOthers = Link.create(
|
|
232
|
+
'chrome://serviceworker-internals', i18nString(UIStrings.seeAllRegistrations), undefined, 'view-all');
|
|
241
233
|
othersSectionRow.appendChild(seeOthers);
|
|
242
234
|
|
|
243
235
|
this.toolbar.appendToolbarItem(
|
|
@@ -104,7 +104,7 @@ const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
104
104
|
if (!filter?.regex) {
|
|
105
105
|
return '';
|
|
106
106
|
}
|
|
107
|
-
const matches = filter.regex.exec(textContent
|
|
107
|
+
const matches = filter.regex.exec(textContent);
|
|
108
108
|
if (!matches?.length) {
|
|
109
109
|
return '';
|
|
110
110
|
}
|
|
@@ -294,7 +294,14 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
294
294
|
};
|
|
295
295
|
|
|
296
296
|
export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
297
|
-
|
|
297
|
+
/**
|
|
298
|
+
* We store these because they are used when calculating the dimensions for the image preview.
|
|
299
|
+
* When we need to get those dimensions, we try to resolve them against the
|
|
300
|
+
* node fresh (in case the dimensions have changed), but if that doesn't work,
|
|
301
|
+
* we fallback to the precomputed ones, which helps to deal with situations
|
|
302
|
+
* where the node might have been removed from the DOM.
|
|
303
|
+
*/
|
|
304
|
+
#storedNodeFeatures: Components.ImagePreview.PrecomputedFeatures|null = null;
|
|
298
305
|
#nodeStyle: ComputedStyleModule.ComputedStyleModel.ComputedStyle|null = null;
|
|
299
306
|
#matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null = null;
|
|
300
307
|
#propertyTraces: Map<string, SDK.CSSProperty.CSSProperty[]>|null = null;
|
|
@@ -363,7 +370,8 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
363
370
|
return null;
|
|
364
371
|
},
|
|
365
372
|
async () => {
|
|
366
|
-
|
|
373
|
+
const liveFeatures = await Components.ImagePreview.loadPrecomputedFeatures(this.#nodeStyle?.node);
|
|
374
|
+
return liveFeatures ?? this.#storedNodeFeatures ?? undefined;
|
|
367
375
|
});
|
|
368
376
|
|
|
369
377
|
this.#updateView({hasMatches: true});
|
|
@@ -430,7 +438,13 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
430
438
|
|
|
431
439
|
set nodeStyle(nodeStyle: ComputedStyleModule.ComputedStyleModel.ComputedStyle|null) {
|
|
432
440
|
this.#nodeStyle = nodeStyle;
|
|
433
|
-
|
|
441
|
+
if (nodeStyle) {
|
|
442
|
+
// Make sure we get the node features before we request an update so we
|
|
443
|
+
// don't run the update before we have the features fetched.
|
|
444
|
+
void this.#storeNodeFeatures(nodeStyle.node).then(() => this.requestUpdate());
|
|
445
|
+
} else {
|
|
446
|
+
this.requestUpdate();
|
|
447
|
+
}
|
|
434
448
|
}
|
|
435
449
|
|
|
436
450
|
get matchedStyles(): SDK.CSSMatchedStyles.CSSMatchedStyles|null {
|
|
@@ -447,13 +461,13 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
447
461
|
this.requestUpdate();
|
|
448
462
|
}
|
|
449
463
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
464
|
+
async #storeNodeFeatures(node: SDK.DOMModel.DOMNode|null): Promise<void> {
|
|
465
|
+
if (node) {
|
|
466
|
+
const features = await Components.ImagePreview.loadPrecomputedFeatures(node);
|
|
467
|
+
this.#storedNodeFeatures = features ?? null;
|
|
468
|
+
} else {
|
|
469
|
+
this.#storedNodeFeatures = null;
|
|
470
|
+
}
|
|
457
471
|
}
|
|
458
472
|
|
|
459
473
|
#shouldGroupStyles(): boolean {
|
|
@@ -483,10 +497,6 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
483
497
|
matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles): Promise<void> {
|
|
484
498
|
this.imagePreviewPopover.hide();
|
|
485
499
|
this.linkifier.reset();
|
|
486
|
-
const cssModel = this.#computedStyleModel?.cssModel();
|
|
487
|
-
if (!cssModel) {
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
500
|
|
|
491
501
|
const uniqueProperties = [...nodeStyle.computedStyle.keys()];
|
|
492
502
|
uniqueProperties.sort(propertySorter);
|
|
@@ -526,8 +536,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
526
536
|
matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null): Promise<void> {
|
|
527
537
|
this.imagePreviewPopover.hide();
|
|
528
538
|
this.linkifier.reset();
|
|
529
|
-
|
|
530
|
-
if (!nodeStyle || !matchedStyles || !cssModel) {
|
|
539
|
+
if (!nodeStyle || !matchedStyles) {
|
|
531
540
|
this.#updateView({hasMatches: false});
|
|
532
541
|
return;
|
|
533
542
|
}
|
|
@@ -316,7 +316,6 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
|
|
|
316
316
|
|
|
317
317
|
this.stylesWidget = new StylesSidebarPane(this.#computedStyleModel);
|
|
318
318
|
this.#computedStyleWidget = new ComputedStyleWidget();
|
|
319
|
-
this.#computedStyleWidget.computedStyleModel = this.#computedStyleModel;
|
|
320
319
|
this.#computedStyleModel.addEventListener(
|
|
321
320
|
ComputedStyle.ComputedStyleModel.Events.COMPUTED_STYLE_CHANGED, this.#updateComputedStyles, this);
|
|
322
321
|
this.#computedStyleModel.addEventListener(
|
|
@@ -1575,11 +1575,17 @@ export class GridTemplateRenderer extends rendererBase(SDK.CSSPropertyParserMatc
|
|
|
1575
1575
|
|
|
1576
1576
|
const indent = Common.Settings.Settings.instance().moduleSetting('text-editor-indent').get();
|
|
1577
1577
|
const container = document.createDocumentFragment();
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1578
|
+
|
|
1579
|
+
const template = html`
|
|
1580
|
+
${match.lines.map(line => {
|
|
1581
|
+
const lines = Renderer.render(line, context).nodes;
|
|
1582
|
+
return html`
|
|
1583
|
+
<span class='styles-clipboard-only'>${indent.repeat(2)}</span>
|
|
1584
|
+
${lines}`;
|
|
1585
|
+
})}
|
|
1586
|
+
`;
|
|
1587
|
+
|
|
1588
|
+
render(template, container);
|
|
1583
1589
|
return [container];
|
|
1584
1590
|
}
|
|
1585
1591
|
}
|
|
@@ -161,11 +161,6 @@ const UIStrings = {
|
|
|
161
161
|
* @description Title of button in the Device Mode Toolbar which rotates the device 90 degrees.
|
|
162
162
|
*/
|
|
163
163
|
rotate: 'Rotate',
|
|
164
|
-
/**
|
|
165
|
-
* @description Fallback/default text used for the name of a custom device when no name has been
|
|
166
|
-
* provided by the user.
|
|
167
|
-
*/
|
|
168
|
-
none: 'None',
|
|
169
164
|
/**
|
|
170
165
|
* @description Tooltip of the rotate/screen orientation button.
|
|
171
166
|
*/
|
|
@@ -185,6 +180,10 @@ const UIStrings = {
|
|
|
185
180
|
* posture e.g. Continuous, Folded.
|
|
186
181
|
*/
|
|
187
182
|
devicePosture: 'Device posture',
|
|
183
|
+
/**
|
|
184
|
+
* @description Title of the network throttling selection in the Device Mode Toolbar.
|
|
185
|
+
*/
|
|
186
|
+
throttling: 'Throttling',
|
|
188
187
|
} as const;
|
|
189
188
|
const str_ = i18n.i18n.registerUIStrings('panels/emulation/DeviceModeToolbar.ts', UIStrings);
|
|
190
189
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -213,18 +212,17 @@ export class DeviceModeToolbar {
|
|
|
213
212
|
private readonly emulatedDevicesList: EmulationModel.EmulatedDevices.EmulatedDevicesList;
|
|
214
213
|
private readonly persistenceSetting: Common.Settings.Setting<{device: string, orientation: string, mode: string}>;
|
|
215
214
|
private spanButton!: UI.Toolbar.ToolbarButton;
|
|
216
|
-
private postureItem!: UI.Toolbar.
|
|
215
|
+
private postureItem!: UI.Toolbar.ToolbarComboBox;
|
|
217
216
|
private modeButton!: UI.Toolbar.ToolbarButton;
|
|
218
217
|
private widthInput: EmulationComponents.DeviceSizeInputElement.SizeInputElement;
|
|
219
218
|
private heightInput: EmulationComponents.DeviceSizeInputElement.SizeInputElement;
|
|
220
|
-
private deviceScaleItem!: UI.Toolbar.
|
|
221
|
-
private deviceSelectItem!: UI.Toolbar.
|
|
222
|
-
private scaleItem!: UI.Toolbar.
|
|
223
|
-
private uaItem!: UI.Toolbar.
|
|
219
|
+
private deviceScaleItem!: UI.Toolbar.ToolbarComboBox;
|
|
220
|
+
private deviceSelectItem!: UI.Toolbar.ToolbarComboBox;
|
|
221
|
+
private scaleItem!: UI.Toolbar.ToolbarComboBox;
|
|
222
|
+
private uaItem!: UI.Toolbar.ToolbarComboBox;
|
|
224
223
|
private cachedDeviceScale!: number|null;
|
|
225
224
|
private cachedUaType!: string|null;
|
|
226
225
|
private xItem?: UI.Toolbar.ToolbarItem;
|
|
227
|
-
private throttlingConditionsItem?: UI.Toolbar.ToolbarMenuButton;
|
|
228
226
|
private cachedModelType?: EmulationModel.DeviceModeModel.Type;
|
|
229
227
|
private cachedScale?: number;
|
|
230
228
|
private cachedModelDevice?: EmulationModel.EmulatedDevices.EmulatedDevice|null;
|
|
@@ -275,6 +273,12 @@ export class DeviceModeToolbar {
|
|
|
275
273
|
this.model.toolbarControlsEnabledSetting().addChangeListener(updateToolbarsEnabled);
|
|
276
274
|
updateToolbarsEnabled();
|
|
277
275
|
|
|
276
|
+
this.updateDeviceMenuItems();
|
|
277
|
+
this.updateScaleMenuItems();
|
|
278
|
+
this.updateDeviceScaleMenuItems();
|
|
279
|
+
this.updateUserAgentMenuItems();
|
|
280
|
+
this.updateDevicePostureItems();
|
|
281
|
+
|
|
278
282
|
function updateToolbarsEnabled(): void {
|
|
279
283
|
const enabled = model.toolbarControlsEnabledSetting().get();
|
|
280
284
|
mainToolbar.setEnabled(enabled);
|
|
@@ -292,10 +296,9 @@ export class DeviceModeToolbar {
|
|
|
292
296
|
const mainToolbar = this.#element.createChild('devtools-toolbar', 'main-toolbar');
|
|
293
297
|
|
|
294
298
|
mainToolbar.appendToolbarItem(new UI.Toolbar.ToolbarItem(this.createEmptyToolbarElement()));
|
|
295
|
-
this.deviceSelectItem =
|
|
296
|
-
|
|
299
|
+
this.deviceSelectItem = new UI.Toolbar.ToolbarComboBox(
|
|
300
|
+
this.onDeviceChange.bind(this), i18nString(UIStrings.deviceType), 'dark-text', 'device');
|
|
297
301
|
this.deviceSelectItem.turnShrinkable();
|
|
298
|
-
this.deviceSelectItem.setDarkText();
|
|
299
302
|
const dimensionsSpan =
|
|
300
303
|
uiI18n.getFormatLocalizedString(str_, UIStrings.dimensions, {PH1: this.deviceSelectItem.element});
|
|
301
304
|
mainToolbar.append(...dimensionsSpan.childNodes);
|
|
@@ -325,10 +328,8 @@ export class DeviceModeToolbar {
|
|
|
325
328
|
|
|
326
329
|
mainToolbar.appendToolbarItem(new UI.Toolbar.ToolbarItem(this.createEmptyToolbarElement()));
|
|
327
330
|
this.scaleItem =
|
|
328
|
-
new UI.Toolbar.
|
|
329
|
-
setTitleForButton(this.scaleItem, i18nString(UIStrings.zoom));
|
|
331
|
+
new UI.Toolbar.ToolbarComboBox(this.onScaleChange.bind(this), i18nString(UIStrings.zoom), 'dark-text', 'scale');
|
|
330
332
|
this.scaleItem.turnShrinkable();
|
|
331
|
-
this.scaleItem.setDarkText();
|
|
332
333
|
mainToolbar.appendToolbarItem(this.scaleItem);
|
|
333
334
|
|
|
334
335
|
const autoAdjustScaleButton = new UI.Toolbar.ToolbarSettingToggle(
|
|
@@ -337,28 +338,22 @@ export class DeviceModeToolbar {
|
|
|
337
338
|
|
|
338
339
|
mainToolbar.appendToolbarItem(new UI.Toolbar.ToolbarItem(this.createEmptyToolbarElement()));
|
|
339
340
|
|
|
340
|
-
this.deviceScaleItem = new UI.Toolbar.
|
|
341
|
-
this.
|
|
341
|
+
this.deviceScaleItem = new UI.Toolbar.ToolbarComboBox(
|
|
342
|
+
this.onDeviceScaleChange.bind(this), i18nString(UIStrings.devicePixelRatio), 'dark-text', 'device-pixel-ratio');
|
|
342
343
|
this.deviceScaleItem.turnShrinkable();
|
|
343
344
|
this.deviceScaleItem.setVisible(this.showDeviceScaleFactorSetting.get());
|
|
344
|
-
setTitleForButton(this.deviceScaleItem, i18nString(UIStrings.devicePixelRatio));
|
|
345
|
-
this.deviceScaleItem.setDarkText();
|
|
346
345
|
const deviceScaleSpan = uiI18n.getFormatLocalizedString(str_, UIStrings.dpr, {PH1: this.deviceScaleItem.element});
|
|
347
346
|
mainToolbar.append(...deviceScaleSpan.childNodes);
|
|
348
347
|
mainToolbar.appendToolbarItem(this.deviceScaleItem);
|
|
349
348
|
mainToolbar.appendToolbarItem(new UI.Toolbar.ToolbarItem(this.createEmptyToolbarElement()));
|
|
350
|
-
this.uaItem =
|
|
351
|
-
|
|
349
|
+
this.uaItem = new UI.Toolbar.ToolbarComboBox(
|
|
350
|
+
this.onUAChange.bind(this), i18nString(UIStrings.deviceType), 'dark-text', 'device-type');
|
|
352
351
|
this.uaItem.turnShrinkable();
|
|
353
352
|
this.uaItem.setVisible(this.showUserAgentTypeSetting.get());
|
|
354
|
-
setTitleForButton(this.uaItem, i18nString(UIStrings.deviceType));
|
|
355
|
-
this.uaItem.setDarkText();
|
|
356
353
|
mainToolbar.appendToolbarItem(this.uaItem);
|
|
357
354
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
this.throttlingConditionsItem.turnShrinkable();
|
|
361
|
-
mainToolbar.appendToolbarItem(this.throttlingConditionsItem);
|
|
355
|
+
MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelect.createForGlobalConditions(
|
|
356
|
+
mainToolbar, i18nString(UIStrings.throttling));
|
|
362
357
|
const saveDataItem = MobileThrottling.ThrottlingManager.throttlingManager().createSaveDataOverrideSelector();
|
|
363
358
|
saveDataItem.turnShrinkable();
|
|
364
359
|
mainToolbar.appendToolbarItem(saveDataItem);
|
|
@@ -375,11 +370,9 @@ export class DeviceModeToolbar {
|
|
|
375
370
|
|
|
376
371
|
// Show posture toolbar menu for foldable devices.
|
|
377
372
|
mainToolbar.appendToolbarItem(new UI.Toolbar.ToolbarItem(this.createEmptyToolbarElement()));
|
|
378
|
-
this.postureItem = new UI.Toolbar.
|
|
379
|
-
this.
|
|
373
|
+
this.postureItem = new UI.Toolbar.ToolbarComboBox(
|
|
374
|
+
this.onPostureChange.bind(this), i18nString(UIStrings.devicePosture), 'dark-text', 'device-posture');
|
|
380
375
|
this.postureItem.turnShrinkable();
|
|
381
|
-
this.postureItem.setDarkText();
|
|
382
|
-
setTitleForButton(this.postureItem, i18nString(UIStrings.devicePosture));
|
|
383
376
|
mainToolbar.appendToolbarItem(this.postureItem);
|
|
384
377
|
|
|
385
378
|
return mainToolbar;
|
|
@@ -401,11 +394,22 @@ export class DeviceModeToolbar {
|
|
|
401
394
|
return ['Continuous', 'Folded'].map(title => ({title, value: title, selected: currentPosture === title}));
|
|
402
395
|
}
|
|
403
396
|
|
|
404
|
-
private
|
|
397
|
+
private updateDevicePostureItems(): void {
|
|
398
|
+
this.postureItem.removeOptions();
|
|
405
399
|
for (const option of this.getDevicePostureOptions()) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
400
|
+
this.postureItem.createOption(option.title, option.value, option.title.toLowerCase());
|
|
401
|
+
}
|
|
402
|
+
const currentPosture = this.currentDevicePosture();
|
|
403
|
+
if (this.postureItem.element.value !== currentPosture) {
|
|
404
|
+
this.postureItem.element.value = currentPosture;
|
|
405
|
+
}
|
|
406
|
+
this.resizeItem(this.postureItem);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
private onPostureChange(): void {
|
|
410
|
+
const value = this.postureItem.element.value;
|
|
411
|
+
if (value !== this.currentDevicePosture()) {
|
|
412
|
+
this.spanClicked();
|
|
409
413
|
}
|
|
410
414
|
}
|
|
411
415
|
|
|
@@ -451,15 +455,21 @@ export class DeviceModeToolbar {
|
|
|
451
455
|
});
|
|
452
456
|
}
|
|
453
457
|
|
|
454
|
-
private
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
458
|
+
private updateScaleMenuItems(): void {
|
|
459
|
+
this.scaleItem.removeOptions();
|
|
460
|
+
const options = this.getScaleOptions();
|
|
461
|
+
for (const option of options) {
|
|
462
|
+
this.scaleItem.createOption(option.title, String(option.value), option.jslogContext);
|
|
463
|
+
}
|
|
464
|
+
const selected = options.find(o => o.selected);
|
|
465
|
+
if (selected) {
|
|
466
|
+
this.scaleItem.element.value = String(selected.value);
|
|
459
467
|
}
|
|
468
|
+
this.resizeItem(this.scaleItem, true);
|
|
460
469
|
}
|
|
461
470
|
|
|
462
|
-
private
|
|
471
|
+
private onScaleChange(): void {
|
|
472
|
+
const value = Number(this.scaleItem.selectedOption()?.value);
|
|
463
473
|
this.model.scaleSetting().set(value);
|
|
464
474
|
}
|
|
465
475
|
|
|
@@ -493,13 +503,22 @@ export class DeviceModeToolbar {
|
|
|
493
503
|
});
|
|
494
504
|
}
|
|
495
505
|
|
|
496
|
-
private
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
{checked: option.selected, jslogContext: option.jslogContext});
|
|
506
|
+
private updateDeviceScaleMenuItems(): void {
|
|
507
|
+
this.deviceScaleItem.removeOptions();
|
|
508
|
+
const options = this.getDeviceScaleFactorOptions();
|
|
509
|
+
for (const option of options) {
|
|
510
|
+
this.deviceScaleItem.createOption(option.title, String(option.value), option.jslogContext);
|
|
502
511
|
}
|
|
512
|
+
const selected = options.find(o => o.selected);
|
|
513
|
+
if (selected) {
|
|
514
|
+
this.deviceScaleItem.element.value = String(selected.value);
|
|
515
|
+
}
|
|
516
|
+
this.resizeItem(this.deviceScaleItem, true);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
private onDeviceScaleChange(): void {
|
|
520
|
+
const value = Number(this.deviceScaleItem.selectedOption()?.value);
|
|
521
|
+
this.model.deviceScaleFactorSetting().set(value);
|
|
503
522
|
}
|
|
504
523
|
|
|
505
524
|
private getUserAgentOptions():
|
|
@@ -519,13 +538,23 @@ export class DeviceModeToolbar {
|
|
|
519
538
|
}));
|
|
520
539
|
}
|
|
521
540
|
|
|
522
|
-
private
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
{checked: option.selected, jslogContext: option.jslogContext});
|
|
541
|
+
private updateUserAgentMenuItems(): void {
|
|
542
|
+
this.uaItem.removeOptions();
|
|
543
|
+
const options = this.getUserAgentOptions();
|
|
544
|
+
for (const option of options) {
|
|
545
|
+
this.uaItem.createOption(option.title, option.value, option.jslogContext);
|
|
528
546
|
}
|
|
547
|
+
const selected = options.find(o => o.selected);
|
|
548
|
+
if (selected) {
|
|
549
|
+
this.uaItem.element.value = selected.value;
|
|
550
|
+
}
|
|
551
|
+
this.resizeItem(this.uaItem);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
private onUAChange(): void {
|
|
555
|
+
const value = this.uaItem.selectedOption()?.value as EmulationModel.DeviceModeModel.UA;
|
|
556
|
+
this.model.uaSetting().set(value);
|
|
557
|
+
this.resizeItem(this.uaItem);
|
|
529
558
|
}
|
|
530
559
|
|
|
531
560
|
private appendOptionsMenuItems(contextMenu: UI.ContextMenu.ContextMenu): void {
|
|
@@ -650,40 +679,66 @@ export class DeviceModeToolbar {
|
|
|
650
679
|
};
|
|
651
680
|
}
|
|
652
681
|
|
|
653
|
-
private
|
|
682
|
+
private updateDeviceMenuItems(): void {
|
|
683
|
+
this.deviceSelectItem.removeOptions();
|
|
654
684
|
const options = this.getDeviceModeOptions();
|
|
655
685
|
|
|
656
|
-
|
|
657
|
-
options.responsive.title, this.switchToResponsive.bind(this),
|
|
658
|
-
{checked: options.responsive.selected, jslogContext: options.responsive.jslogContext});
|
|
686
|
+
this.deviceSelectItem.createOption(options.responsive.title, 'Responsive', options.responsive.jslogContext);
|
|
659
687
|
|
|
660
|
-
appendGroup.call(this, options.standard);
|
|
661
|
-
appendGroup.call(this, options.custom);
|
|
688
|
+
appendGroup.call(this, options.standard, 'Standard');
|
|
689
|
+
appendGroup.call(this, options.custom, 'Custom');
|
|
662
690
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
function appendGroup(
|
|
668
|
-
|
|
669
|
-
title: string,
|
|
670
|
-
selected: boolean,
|
|
671
|
-
jslogContext: string,
|
|
672
|
-
}>): void {
|
|
691
|
+
this.deviceSelectItem.createOption(options.edit.title, 'Edit', options.edit.jslogContext);
|
|
692
|
+
|
|
693
|
+
this.updateDeviceSelection();
|
|
694
|
+
|
|
695
|
+
function appendGroup(
|
|
696
|
+
this: DeviceModeToolbar, group: Array<{title: string, jslogContext: string}>, label: string): void {
|
|
673
697
|
if (!group.length) {
|
|
674
698
|
return;
|
|
675
699
|
}
|
|
676
|
-
const
|
|
700
|
+
const optGroup = document.createElement('optgroup');
|
|
701
|
+
optGroup.label = label;
|
|
677
702
|
for (const item of group) {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
});
|
|
703
|
+
const option = document.createElement('option');
|
|
704
|
+
option.value = item.title;
|
|
705
|
+
option.text = item.title;
|
|
706
|
+
option.setAttribute('jslog', `${VisualLogging.item(item.jslogContext).track({click: true})}`);
|
|
707
|
+
optGroup.appendChild(option);
|
|
708
|
+
}
|
|
709
|
+
this.deviceSelectItem.addOption(optGroup);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
private updateDeviceSelection(): void {
|
|
714
|
+
const device = this.model.device();
|
|
715
|
+
if (this.model.type() === EmulationModel.DeviceModeModel.Type.Responsive) {
|
|
716
|
+
this.deviceSelectItem.element.value = 'Responsive';
|
|
717
|
+
} else if (device) {
|
|
718
|
+
this.deviceSelectItem.element.value = device.title;
|
|
719
|
+
}
|
|
720
|
+
this.resizeItem(this.deviceSelectItem);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
private onDeviceChange(): void {
|
|
724
|
+
const value = this.deviceSelectItem.selectedOption()?.value;
|
|
725
|
+
if (value === 'Edit') {
|
|
726
|
+
this.emulatedDevicesList.revealCustomSetting();
|
|
727
|
+
this.updateDeviceSelection();
|
|
728
|
+
} else if (value === 'Responsive') {
|
|
729
|
+
this.switchToResponsive();
|
|
730
|
+
} else {
|
|
731
|
+
for (const device of this.allDevices()) {
|
|
732
|
+
if (device.title === value) {
|
|
733
|
+
this.emulateDevice(device);
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
682
736
|
}
|
|
683
737
|
}
|
|
684
738
|
}
|
|
685
739
|
|
|
686
740
|
private deviceListChanged(): void {
|
|
741
|
+
this.updateDeviceMenuItems();
|
|
687
742
|
const device = this.model.device();
|
|
688
743
|
if (!device) {
|
|
689
744
|
return;
|
|
@@ -709,7 +764,11 @@ export class DeviceModeToolbar {
|
|
|
709
764
|
|
|
710
765
|
private updateUserAgentTypeVisibility(): void {
|
|
711
766
|
if (this.uaItem) {
|
|
712
|
-
this.
|
|
767
|
+
const visible = this.showUserAgentTypeSetting.get();
|
|
768
|
+
this.uaItem.setVisible(visible);
|
|
769
|
+
if (visible) {
|
|
770
|
+
this.resizeItem(this.uaItem);
|
|
771
|
+
}
|
|
713
772
|
}
|
|
714
773
|
}
|
|
715
774
|
|
|
@@ -854,31 +913,27 @@ export class DeviceModeToolbar {
|
|
|
854
913
|
this.heightInput.placeholder = String(size.height);
|
|
855
914
|
|
|
856
915
|
if (this.model.scale() !== this.cachedScale) {
|
|
857
|
-
this.
|
|
916
|
+
this.updateScaleMenuItems();
|
|
858
917
|
this.cachedScale = this.model.scale();
|
|
859
918
|
}
|
|
860
919
|
|
|
861
920
|
const deviceScale = this.model.appliedDeviceScaleFactor();
|
|
862
921
|
if (deviceScale !== this.cachedDeviceScale) {
|
|
863
|
-
this.deviceScaleItem.
|
|
922
|
+
this.deviceScaleItem.element.value = String(deviceScale);
|
|
864
923
|
this.cachedDeviceScale = deviceScale;
|
|
924
|
+
this.resizeItem(this.deviceScaleItem, true);
|
|
865
925
|
}
|
|
866
926
|
|
|
867
927
|
const uaType = this.model.appliedUserAgentType();
|
|
868
928
|
if (uaType !== this.cachedUaType) {
|
|
869
|
-
this.uaItem.
|
|
929
|
+
this.uaItem.element.value = uaType;
|
|
870
930
|
this.cachedUaType = uaType;
|
|
931
|
+
this.updateDeviceScaleMenuItems();
|
|
932
|
+
this.resizeItem(this.uaItem);
|
|
871
933
|
}
|
|
872
934
|
|
|
873
|
-
let deviceItemTitle: string = i18nString(UIStrings.none);
|
|
874
|
-
if (this.model.type() === EmulationModel.DeviceModeModel.Type.Responsive) {
|
|
875
|
-
deviceItemTitle = i18nString(UIStrings.responsive);
|
|
876
|
-
}
|
|
877
935
|
const device = this.model.device();
|
|
878
|
-
|
|
879
|
-
deviceItemTitle = device.title;
|
|
880
|
-
}
|
|
881
|
-
this.deviceSelectItem.setText(deviceItemTitle);
|
|
936
|
+
this.updateDeviceSelection();
|
|
882
937
|
|
|
883
938
|
if (this.model.device() !== this.cachedModelDevice) {
|
|
884
939
|
const device = this.model.device();
|
|
@@ -898,7 +953,7 @@ export class DeviceModeToolbar {
|
|
|
898
953
|
} else if (device?.isFoldableScreen) {
|
|
899
954
|
this.spanButton.setVisible(false);
|
|
900
955
|
this.postureItem.setVisible(true);
|
|
901
|
-
this.
|
|
956
|
+
this.updateDevicePostureItems();
|
|
902
957
|
} else {
|
|
903
958
|
this.spanButton.setVisible(false);
|
|
904
959
|
this.postureItem.setVisible(false);
|
|
@@ -962,4 +1017,31 @@ export class DeviceModeToolbar {
|
|
|
962
1017
|
|
|
963
1018
|
this.model.emulate(EmulationModel.DeviceModeModel.Type.Responsive, null, null);
|
|
964
1019
|
}
|
|
1020
|
+
|
|
1021
|
+
private resizeItem(item: UI.Toolbar.ToolbarComboBox, stripParens = false): void {
|
|
1022
|
+
const selectedOption = item.selectedOption();
|
|
1023
|
+
if (!selectedOption) {
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
const dummySelect = item.element.cloneNode(false) as HTMLSelectElement;
|
|
1028
|
+
const dummyOption = selectedOption.cloneNode(true) as HTMLOptionElement;
|
|
1029
|
+
|
|
1030
|
+
if (stripParens) {
|
|
1031
|
+
const parensIndex = dummyOption.text.indexOf(' (');
|
|
1032
|
+
if (parensIndex >= 0) {
|
|
1033
|
+
dummyOption.text = dummyOption.text.substring(0, parensIndex);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
dummySelect.appendChild(dummyOption);
|
|
1038
|
+
dummySelect.style.width = 'fit-content';
|
|
1039
|
+
dummySelect.style.position = 'absolute';
|
|
1040
|
+
dummySelect.style.visibility = 'hidden';
|
|
1041
|
+
dummySelect.style.pointerEvents = 'none';
|
|
1042
|
+
|
|
1043
|
+
item.element.parentElement?.appendChild(dummySelect);
|
|
1044
|
+
item.element.style.width = dummySelect.offsetWidth + 'px';
|
|
1045
|
+
dummySelect.remove();
|
|
1046
|
+
}
|
|
965
1047
|
}
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
margin-top: 8px;
|
|
118
118
|
padding-top: 8px;
|
|
119
119
|
border-top: 1px solid #eee;
|
|
120
|
-
font-family: monospace;
|
|
120
|
+
font-family: var(--monospace-font-family);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
.thought, .action {
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
|
|
170
170
|
.green-dev-floaty-dialog-node-description {
|
|
171
171
|
font-size: 11px;
|
|
172
|
-
font-family: monospace;
|
|
172
|
+
font-family: var(--monospace-font-family);
|
|
173
173
|
color: #0b57d0;
|
|
174
174
|
background-color: #d3e3fd;
|
|
175
175
|
padding: 2px 8px;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
6
6
|
import type * as Platform from '../../core/platform/platform.js';
|
|
7
7
|
import type * as IssuesManager from '../../models/issues_manager/issues_manager.js';
|
|
8
|
-
import
|
|
8
|
+
import {html, render} from '../../ui/lit/lit.js';
|
|
9
9
|
|
|
10
10
|
import {AffectedElementsView} from './AffectedElementsView.js';
|
|
11
11
|
|
|
@@ -31,16 +31,19 @@ export class AffectedPermissionElementsView extends AffectedElementsView {
|
|
|
31
31
|
async #appendAffectedElements(issues: Iterable<IssuesManager.PermissionElementIssue.PermissionElementIssue>):
|
|
32
32
|
Promise<void> {
|
|
33
33
|
let count = 0;
|
|
34
|
+
// clang-format off
|
|
35
|
+
const templates = [];
|
|
34
36
|
for (const issue of issues) {
|
|
35
37
|
for (const element of issue.elements()) {
|
|
36
|
-
const rowElement = UI.Fragment.html`
|
|
37
|
-
<tr>
|
|
38
|
-
${await this.createElementCell(element, this.issue.getCategory())}
|
|
39
|
-
</tr>`;
|
|
40
|
-
this.affectedResources.appendChild(rowElement);
|
|
41
38
|
count++;
|
|
39
|
+
templates.push(html`<tr>
|
|
40
|
+
${await this.createElementCell(element, this.issue.getCategory())}
|
|
41
|
+
</tr>`);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
// clang-format on
|
|
45
|
+
// eslint-disable-next-line @devtools/no-lit-render-outside-of-view
|
|
46
|
+
render(html`${templates}`, this.affectedResources);
|
|
44
47
|
this.updateAffectedResourceCount(count);
|
|
45
48
|
}
|
|
46
49
|
}
|