chrome-devtools-frontend 1.0.1597624 → 1.0.1598808
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/docs/ui_engineering.md +6 -6
- package/front_end/core/host/AidaClient.ts +2 -0
- package/front_end/models/ai_assistance/AiConversation.ts +16 -14
- package/front_end/models/ai_assistance/agents/AiAgent.ts +14 -4
- package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +109 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +30 -1
- package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +6 -9
- package/front_end/panels/ai_assistance/PatchWidget.ts +1 -1
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +53 -29
- package/front_end/panels/ai_assistance/components/ChatView.ts +1 -1
- package/front_end/panels/application/AppManifestView.ts +2 -2
- package/front_end/panels/application/CookieItemsView.ts +9 -15
- package/front_end/panels/application/DeviceBoundSessionsView.ts +3 -5
- package/front_end/panels/application/FrameDetailsView.ts +2 -2
- package/front_end/panels/application/ReportingApiView.ts +2 -2
- package/front_end/panels/application/preloading/PreloadingView.ts +18 -3
- package/front_end/panels/changes/ChangesView.ts +7 -11
- package/front_end/panels/coverage/CoverageView.ts +4 -4
- package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +3 -3
- package/front_end/panels/elements/ElementsTreeOutline.ts +34 -8
- package/front_end/panels/elements/StylePropertiesSection.ts +129 -1
- package/front_end/panels/elements/StylePropertyHighlighter.ts +3 -0
- package/front_end/panels/elements/stylesSidebarPane.css +34 -0
- package/front_end/panels/issues/AffectedSelectivePermissionsInterventionView.ts +3 -5
- package/front_end/panels/layer_viewer/LayerDetailsView.ts +2 -1
- package/front_end/panels/network/RequestConditionsDrawer.ts +4 -4
- package/front_end/panels/network/RequestCookiesView.ts +2 -2
- package/front_end/panels/network/RequestHeadersView.ts +4 -4
- package/front_end/panels/network/RequestResponseView.ts +2 -2
- package/front_end/panels/performance_monitor/PerformanceMonitor.ts +2 -2
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +3 -3
- package/front_end/panels/recorder/components/StepView.ts +2 -1
- package/front_end/panels/search/SearchView.ts +2 -2
- package/front_end/panels/timeline/TimelineDetailsView.ts +8 -6
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +2 -7
- package/front_end/panels/timeline/components/insights/CharacterSet.ts +2 -6
- package/front_end/panels/timeline/components/insights/EventRef.ts +2 -2
- package/front_end/panels/webauthn/WebauthnPane.ts +2 -2
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Realm.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Realm.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.js +13 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/third_party/mitt/mitt.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/third_party/parsel-js/parsel-js.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/third_party/rxjs/rxjs.js +446 -446
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +166 -167
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Realm.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Realm.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.js +12 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/third_party/mitt/mitt.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/third_party/parsel-js/parsel-js.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/third_party/rxjs/rxjs.js +97 -97
- package/front_end/third_party/puppeteer/package/package.json +1 -1
- package/front_end/third_party/puppeteer/package/src/bidi/Realm.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/bidi/util.ts +17 -0
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/legacy/Widget.ts +42 -6
- package/package.json +1 -1
|
@@ -28,6 +28,7 @@ import preloadingViewStyles from './preloadingView.css.js';
|
|
|
28
28
|
import preloadingViewDropDownStyles from './preloadingViewDropDown.css.js';
|
|
29
29
|
|
|
30
30
|
const {createRef, ref} = Directives;
|
|
31
|
+
const {widget} = UI.Widget;
|
|
31
32
|
|
|
32
33
|
const UIStrings = {
|
|
33
34
|
/**
|
|
@@ -266,7 +267,7 @@ export class PreloadingRuleSetView extends UI.Widget.VBox {
|
|
|
266
267
|
<div slot="main" ${ref(this.ruleSetGridContainerRef)}>
|
|
267
268
|
</div>
|
|
268
269
|
<div slot="sidebar" jslog=${VisualLogging.section('rule-set-details')}>
|
|
269
|
-
<devtools-widget
|
|
270
|
+
<devtools-widget ${widget(PreloadingComponents.RuleSetDetailsView.RuleSetDetailsView, {
|
|
270
271
|
ruleSet: this.getRuleSet(),
|
|
271
272
|
shouldPrettyPrint: this.shouldPrettyPrint,
|
|
272
273
|
})} ${ref(this.ruleSetDetailsRef)}></devtools-widget>
|
|
@@ -448,6 +449,7 @@ export class PreloadingAttemptView extends UI.Widget.VBox {
|
|
|
448
449
|
new PreloadingComponents.PreloadingDetailsReportView.PreloadingDetailsReportView();
|
|
449
450
|
private readonly ruleSetSelector: PreloadingRuleSetSelector;
|
|
450
451
|
private readonly textFilterUI: UI.Toolbar.ToolbarFilter;
|
|
452
|
+
private hsplit?: UI.SplitWidget.SplitWidget;
|
|
451
453
|
private clearButton: UI.Toolbar.ToolbarButton;
|
|
452
454
|
|
|
453
455
|
constructor(model: SDK.PreloadingModel.PreloadingModel) {
|
|
@@ -541,7 +543,12 @@ export class PreloadingAttemptView extends UI.Widget.VBox {
|
|
|
541
543
|
>${i18nString(UIStrings.learnMore)}</devtools-link>
|
|
542
544
|
</div>
|
|
543
545
|
</div>
|
|
544
|
-
<devtools-split-view sidebar-position="second"
|
|
546
|
+
<devtools-split-view sidebar-position="second" ${
|
|
547
|
+
UI.Widget.widgetRef(
|
|
548
|
+
UI.SplitWidget.SplitWidget,
|
|
549
|
+
w => {
|
|
550
|
+
this.hsplit = w;
|
|
551
|
+
})}>
|
|
545
552
|
<div slot="main" class="overflow-auto" style="height: 100%">
|
|
546
553
|
${preloadingGridContainer}
|
|
547
554
|
</div>
|
|
@@ -632,7 +639,15 @@ export class PreloadingAttemptView extends UI.Widget.VBox {
|
|
|
632
639
|
this.preloadingGrid.rows = filteredRows;
|
|
633
640
|
this.preloadingGrid.pageURL = pageURL();
|
|
634
641
|
// Only show empty state when there are truly no speculations (not when filter has no matches)
|
|
635
|
-
this.contentElement.classList.
|
|
642
|
+
const wasEmpty = this.contentElement.classList.contains('empty');
|
|
643
|
+
const isEmpty = rows.length === 0;
|
|
644
|
+
this.contentElement.classList.toggle('empty', isEmpty);
|
|
645
|
+
|
|
646
|
+
// When this view starts empty, the split view gets laid out while hidden and collapses
|
|
647
|
+
// its sidebar to 0. Re-layout once it becomes visible.
|
|
648
|
+
if (wasEmpty && !isEmpty) {
|
|
649
|
+
this.hsplit?.doLayout();
|
|
650
|
+
}
|
|
636
651
|
|
|
637
652
|
this.updatePreloadingDetails();
|
|
638
653
|
}
|
|
@@ -58,11 +58,11 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
58
58
|
<div class=vbox slot="main">
|
|
59
59
|
<devtools-widget
|
|
60
60
|
?hidden=${input.workspaceDiff.modifiedUISourceCodes().length > 0}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
${widget(UI.EmptyWidget.EmptyWidget, {
|
|
62
|
+
header: i18nString(UIStrings.noChanges),
|
|
63
|
+
text: i18nString(UIStrings.changesViewDescription),
|
|
64
|
+
link: CHANGES_VIEW_URL,
|
|
65
|
+
})}>
|
|
66
66
|
</devtools-widget>
|
|
67
67
|
<div class=diff-container role=tabpanel ?hidden=${input.workspaceDiff.modifiedUISourceCodes().length === 0}>
|
|
68
68
|
${widget(CombinedDiffView.CombinedDiffView, {
|
|
@@ -72,18 +72,14 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
72
72
|
</div>
|
|
73
73
|
${hasCopyToPrompt ? html`
|
|
74
74
|
<devtools-widget class="copy-to-prompt"
|
|
75
|
-
|
|
75
|
+
${widget(PanelsCommon.CopyChangesToPrompt, {
|
|
76
76
|
workspaceDiff: input.workspaceDiff,
|
|
77
77
|
patchAgentCSSChange: null,
|
|
78
78
|
})}
|
|
79
79
|
></devtools-widget>
|
|
80
80
|
` : Lit.nothing}
|
|
81
81
|
</div>
|
|
82
|
-
<devtools-widget
|
|
83
|
-
slot="sidebar"
|
|
84
|
-
.widgetConfig=${UI.Widget.widgetConfig(ChangesSidebar, {
|
|
85
|
-
workspaceDiff: input.workspaceDiff
|
|
86
|
-
})}
|
|
82
|
+
<devtools-widget slot="sidebar" ${widget(ChangesSidebar, {workspaceDiff: input.workspaceDiff})}
|
|
87
83
|
${UI.Widget.widgetRef(ChangesSidebar, onSidebar)}>
|
|
88
84
|
</devtools-widget>
|
|
89
85
|
</devtools-split-view>`,
|
|
@@ -127,7 +127,7 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
|
127
127
|
const i18nTemplate = unboundI18nTemplate.bind(undefined, str_);
|
|
128
128
|
const {ref} = Directives;
|
|
129
129
|
const {bindToAction, bindToSetting} = UI.UIUtils;
|
|
130
|
-
const {
|
|
130
|
+
const {widget} = UI.Widget;
|
|
131
131
|
|
|
132
132
|
let coverageViewInstance: CoverageView|undefined;
|
|
133
133
|
|
|
@@ -222,7 +222,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
222
222
|
i18nString(UIStrings.bfcacheNoCapture) : i18nString(UIStrings.activationNoCapture),
|
|
223
223
|
input.needsReload)
|
|
224
224
|
: input.coverageInfo ? html`
|
|
225
|
-
<devtools-widget autofocus class="results"
|
|
225
|
+
<devtools-widget autofocus class="results" ${widget(CoverageListView, {
|
|
226
226
|
coverageInfo: input.coverageInfo,
|
|
227
227
|
highlightRegExp: input.textFilter,
|
|
228
228
|
selectedUrl: input.selectedUrl,
|
|
@@ -242,7 +242,7 @@ function renderLandingPage(supportsRecordOnReload: boolean): TemplateResult {
|
|
|
242
242
|
if (supportsRecordOnReload) {
|
|
243
243
|
// clang-format off
|
|
244
244
|
return html`
|
|
245
|
-
<devtools-widget
|
|
245
|
+
<devtools-widget ${widget(UI.EmptyWidget.EmptyWidget,{
|
|
246
246
|
header: i18nString(UIStrings.noCoverageData),
|
|
247
247
|
link: 'https://developer.chrome.com/docs/devtools/coverage' as Platform.DevToolsPath.UrlString,
|
|
248
248
|
text: i18nString(UIStrings.clickTheReloadButtonSToReloadAnd, {PH1: i18nString(UIStrings.reloadPage)}),
|
|
@@ -256,7 +256,7 @@ function renderLandingPage(supportsRecordOnReload: boolean): TemplateResult {
|
|
|
256
256
|
}
|
|
257
257
|
// clang-format off
|
|
258
258
|
return html`
|
|
259
|
-
<devtools-widget
|
|
259
|
+
<devtools-widget ${widget(UI.EmptyWidget.EmptyWidget,{
|
|
260
260
|
header: i18nString(UIStrings.noCoverageData),
|
|
261
261
|
link: 'https://developer.chrome.com/docs/devtools/coverage' as Platform.DevToolsPath.UrlString,
|
|
262
262
|
text: i18nString(UIStrings.clickTheRecordButtonSToStart, {PH1: i18nString(UIStrings.startRecording)}),
|
|
@@ -25,7 +25,7 @@ import {CSSOverviewSidebarPanel} from './CSSOverviewSidebarPanel.js';
|
|
|
25
25
|
import type {UnusedDeclaration} from './CSSOverviewUnusedDeclarations.js';
|
|
26
26
|
|
|
27
27
|
const {styleMap, ref} = Directives;
|
|
28
|
-
const {
|
|
28
|
+
const {widget} = UI.Widget;
|
|
29
29
|
|
|
30
30
|
const UIStrings = {
|
|
31
31
|
/**
|
|
@@ -281,7 +281,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
281
281
|
render(html`
|
|
282
282
|
<style>${cssOverviewCompletedViewStyles}</style>
|
|
283
283
|
<devtools-split-view direction="column" sidebar-position="first" sidebar-initial-size="200">
|
|
284
|
-
<devtools-widget slot="sidebar"
|
|
284
|
+
<devtools-widget slot="sidebar" ${widget(CSSOverviewSidebarPanel, {
|
|
285
285
|
minimumSize: new Geometry.Size(100, 25),
|
|
286
286
|
items: [
|
|
287
287
|
{name: i18nString(UIStrings.overviewSummary), id: 'summary'},
|
|
@@ -325,7 +325,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
325
325
|
${renderMediaQueries(input.mediaQueries)}
|
|
326
326
|
</div>
|
|
327
327
|
</div>
|
|
328
|
-
<devtools-widget slot="sidebar"
|
|
328
|
+
<devtools-widget slot="sidebar" ${widget(e => {
|
|
329
329
|
const tabbedPane = new UI.TabbedPane.TabbedPane(e);
|
|
330
330
|
output.closeAllTabs = () => { tabbedPane.closeTabs(tabbedPane.tabIds()); };
|
|
331
331
|
output.addTab = (id: string, tabTitle: string, view: UI.Widget.Widget, jslogContext: string) => {
|
|
@@ -137,6 +137,13 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
|
|
|
137
137
|
target.appendChild(output.elementsTreeOutline.element);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
output.elementsTreeOutline.maxTreeDepth = input.maxTreeDepth;
|
|
141
|
+
output.elementsTreeOutline.enableContextMenu = input.enableContextMenu ?? true;
|
|
142
|
+
output.elementsTreeOutline.showComments = input.showComments ?? true;
|
|
143
|
+
output.elementsTreeOutline.showAIButton = input.showAIButton ?? true;
|
|
144
|
+
output.elementsTreeOutline.disableEdits = input.disableEdits ?? false;
|
|
145
|
+
output.elementsTreeOutline.expandRoot = input.expandRoot ?? false;
|
|
146
|
+
|
|
140
147
|
if (input.visibleWidth !== undefined) {
|
|
141
148
|
output.elementsTreeOutline.setVisibleWidth(input.visibleWidth);
|
|
142
149
|
}
|
|
@@ -223,6 +230,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
223
230
|
#showComments = true;
|
|
224
231
|
#showAIButton = true;
|
|
225
232
|
#disableEdits = false;
|
|
233
|
+
#expandRoot = false;
|
|
226
234
|
#visible = false;
|
|
227
235
|
#visibleWidth?: number;
|
|
228
236
|
#wrap = false;
|
|
@@ -291,6 +299,15 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
291
299
|
this.performUpdate();
|
|
292
300
|
}
|
|
293
301
|
|
|
302
|
+
get expandRoot(): boolean {
|
|
303
|
+
return this.#expandRoot;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
set expandRoot(expandRoot: boolean) {
|
|
307
|
+
this.#expandRoot = expandRoot;
|
|
308
|
+
this.performUpdate();
|
|
309
|
+
}
|
|
310
|
+
|
|
294
311
|
#currentHighlightedNode: SDK.DOMModel.DOMNode|null = null;
|
|
295
312
|
|
|
296
313
|
#view: View;
|
|
@@ -347,11 +364,19 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
347
364
|
this.#viewOutput?.elementsTreeOutline?.highlightNodeAttribute(node, attribute);
|
|
348
365
|
}
|
|
349
366
|
|
|
350
|
-
|
|
367
|
+
get wrap(): boolean {
|
|
368
|
+
return this.#wrap;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
set wrap(wrap: boolean) {
|
|
351
372
|
this.#wrap = wrap;
|
|
352
373
|
this.performUpdate();
|
|
353
374
|
}
|
|
354
375
|
|
|
376
|
+
setWordWrap(wrap: boolean): void {
|
|
377
|
+
this.wrap = wrap;
|
|
378
|
+
}
|
|
379
|
+
|
|
355
380
|
selectedDOMNode(): SDK.DOMModel.DOMNode|null {
|
|
356
381
|
return this.#viewOutput.elementsTreeOutline?.selectedDOMNode() ?? null;
|
|
357
382
|
}
|
|
@@ -387,6 +412,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
|
|
|
387
412
|
showComments: this.#showComments,
|
|
388
413
|
showAIButton: this.#showAIButton,
|
|
389
414
|
disableEdits: this.#disableEdits,
|
|
415
|
+
expandRoot: this.#expandRoot,
|
|
390
416
|
visibleWidth: this.#visibleWidth,
|
|
391
417
|
visible: this.#visible,
|
|
392
418
|
wrap: this.#wrap,
|
|
@@ -565,12 +591,12 @@ export class ElementsTreeOutline extends
|
|
|
565
591
|
#issuesManager?: IssuesManager.IssuesManager.IssuesManager;
|
|
566
592
|
#popupHelper?: UI.PopoverHelper.PopoverHelper;
|
|
567
593
|
#nodeElementToIssues = new Map<Element, IssuesManager.Issue.Issue[]>();
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
594
|
+
maxTreeDepth?: number;
|
|
595
|
+
enableContextMenu: boolean;
|
|
596
|
+
showComments: boolean;
|
|
597
|
+
showAIButton: boolean;
|
|
598
|
+
disableEdits: boolean;
|
|
599
|
+
expandRoot: boolean;
|
|
574
600
|
|
|
575
601
|
constructor(
|
|
576
602
|
omitRootDOMNode?: boolean, selectEnabled?: boolean, hideGutter?: boolean, maxTreeDepth?: number,
|
|
@@ -1388,7 +1414,7 @@ export class ElementsTreeOutline extends
|
|
|
1388
1414
|
}
|
|
1389
1415
|
|
|
1390
1416
|
async showContextMenu(treeElement: ElementsTreeElement, event: Event): Promise<void> {
|
|
1391
|
-
if (UI.UIUtils.isEditing()) {
|
|
1417
|
+
if (UI.UIUtils.isEditing() || !this.enableContextMenu) {
|
|
1392
1418
|
return;
|
|
1393
1419
|
}
|
|
1394
1420
|
|
|
@@ -47,6 +47,7 @@ import * as ComputedStyle from '../../models/computed_style/computed_style.js';
|
|
|
47
47
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
48
48
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
49
49
|
import * as Tooltips from '../../ui/components/tooltips/tooltips.js';
|
|
50
|
+
import {createIcon, type Icon} from '../../ui/kit/kit.js';
|
|
50
51
|
import type * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
51
52
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
52
53
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
@@ -115,6 +116,14 @@ const UIStrings = {
|
|
|
115
116
|
* @example {(0,0,1)} PH1
|
|
116
117
|
*/
|
|
117
118
|
specificity: 'Specificity: {PH1}',
|
|
119
|
+
/**
|
|
120
|
+
* @description Accessibility label for the button that expands a collapsed CSS rule in the Styles pane.
|
|
121
|
+
*/
|
|
122
|
+
expandCollapsedRule: 'Expand collapsed rule',
|
|
123
|
+
/**
|
|
124
|
+
* @description Accessibility label for the button that collapses an expanded CSS rule in the Styles pane.
|
|
125
|
+
*/
|
|
126
|
+
collapseExpandedRule: 'Collapse expanded rule',
|
|
118
127
|
} as const;
|
|
119
128
|
|
|
120
129
|
const str_ = i18n.i18n.registerUIStrings('panels/elements/StylePropertiesSection.ts', UIStrings);
|
|
@@ -151,6 +160,8 @@ export class StylePropertiesSection {
|
|
|
151
160
|
protected readonly selectorRefElement: HTMLElement;
|
|
152
161
|
private hoverableSelectorsMode: boolean;
|
|
153
162
|
#isHidden: boolean;
|
|
163
|
+
#isCollapsed: boolean;
|
|
164
|
+
#collapseIcon: Icon|null = null;
|
|
154
165
|
protected customPopulateCallback: () => void;
|
|
155
166
|
|
|
156
167
|
nestingLevel = 0;
|
|
@@ -228,6 +239,25 @@ export class StylePropertiesSection {
|
|
|
228
239
|
const selectorContainer = document.createElement('div');
|
|
229
240
|
selectorContainer.createChild('span', 'styles-clipboard-only').textContent = indent.repeat(this.nestingLevel);
|
|
230
241
|
selectorContainer.classList.add('selector-container');
|
|
242
|
+
|
|
243
|
+
// Collapse/expand toggle icon for rules that can be manually toggled.
|
|
244
|
+
this.#collapseIcon = createIcon('triangle-right', 'section-collapse-icon');
|
|
245
|
+
UI.ARIAUtils.markAsButton(this.#collapseIcon);
|
|
246
|
+
UI.ARIAUtils.setControls(this.#collapseIcon, this.propertiesTreeOutline.element);
|
|
247
|
+
this.#collapseIcon.tabIndex = 0;
|
|
248
|
+
this.#collapseIcon.addEventListener('click', (event: Event) => {
|
|
249
|
+
event.consume(true);
|
|
250
|
+
this.#toggleCollapsed();
|
|
251
|
+
});
|
|
252
|
+
this.#collapseIcon.addEventListener('keydown', (event: KeyboardEvent) => {
|
|
253
|
+
if (!Platform.KeyboardUtilities.isEnterOrSpaceKey(event)) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
event.consume(true);
|
|
257
|
+
this.#toggleCollapsed();
|
|
258
|
+
});
|
|
259
|
+
selectorContainer.appendChild(this.#collapseIcon);
|
|
260
|
+
|
|
231
261
|
this.selectorElement = document.createElement('span');
|
|
232
262
|
UI.ARIAUtils.setLabel(this.selectorElement, i18nString(UIStrings.cssSelector));
|
|
233
263
|
this.selectorElement.classList.add('selector');
|
|
@@ -324,8 +354,10 @@ export class StylePropertiesSection {
|
|
|
324
354
|
}
|
|
325
355
|
this.hoverableSelectorsMode = false;
|
|
326
356
|
this.#isHidden = false;
|
|
357
|
+
this.#isCollapsed = false;
|
|
327
358
|
this.markSelectorMatches();
|
|
328
359
|
this.onpopulate();
|
|
360
|
+
this.#updateCollapsedState();
|
|
329
361
|
|
|
330
362
|
this.stylesContainer.computedStyleModel().addEventListener(
|
|
331
363
|
ComputedStyle.ComputedStyleModel.Events.CSS_MODEL_CHANGED, this.#onCSSModelChanged, this);
|
|
@@ -620,9 +652,18 @@ export class StylePropertiesSection {
|
|
|
620
652
|
keyboardEvent.metaKey) {
|
|
621
653
|
return;
|
|
622
654
|
}
|
|
655
|
+
|
|
656
|
+
// Only handle section-level edit shortcuts when the event originated from
|
|
657
|
+
// the section itself. Child editors dispatch key events that bubble up to
|
|
658
|
+
// the section, and we must not treat those as section shortcuts.
|
|
659
|
+
const isSectionLevelShortcut = keyboardEvent.target === this.element;
|
|
660
|
+
|
|
623
661
|
switch (keyboardEvent.key) {
|
|
624
662
|
case 'Enter':
|
|
625
663
|
case ' ':
|
|
664
|
+
if (!isSectionLevelShortcut) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
626
667
|
this.startEditingAtFirstPosition();
|
|
627
668
|
keyboardEvent.consume(true);
|
|
628
669
|
break;
|
|
@@ -634,7 +675,7 @@ export class StylePropertiesSection {
|
|
|
634
675
|
break;
|
|
635
676
|
default:
|
|
636
677
|
// Filter out non-printable key strokes.
|
|
637
|
-
if (keyboardEvent.key.length === 1) {
|
|
678
|
+
if (isSectionLevelShortcut && keyboardEvent.key.length === 1) {
|
|
638
679
|
this.addNewBlankProperty(0).startEditingName();
|
|
639
680
|
}
|
|
640
681
|
break;
|
|
@@ -1333,6 +1374,82 @@ export class StylePropertiesSection {
|
|
|
1333
1374
|
return this.#isHidden;
|
|
1334
1375
|
}
|
|
1335
1376
|
|
|
1377
|
+
/**
|
|
1378
|
+
* Checks whether the section should be collapsed because it does not
|
|
1379
|
+
* contribute any active styles. A section is collapsed when:
|
|
1380
|
+
* - It has no leading properties (empty rule), OR
|
|
1381
|
+
* - All its leading properties have PropertyState.OVERLOADED
|
|
1382
|
+
*
|
|
1383
|
+
* Sections containing only user-disabled properties are NOT collapsed,
|
|
1384
|
+
* since the user intentionally toggled them off and they should remain visible.
|
|
1385
|
+
*/
|
|
1386
|
+
#shouldCollapse(): boolean {
|
|
1387
|
+
const style = this.styleInternal;
|
|
1388
|
+
const properties = style.leadingProperties();
|
|
1389
|
+
|
|
1390
|
+
// Never collapse the element's own inline style section.
|
|
1391
|
+
if (style.type === SDK.CSSStyleDeclaration.Type.Inline) {
|
|
1392
|
+
return false;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
// Empty rule (e.g. from CSS nesting): collapse.
|
|
1396
|
+
if (properties.length === 0) {
|
|
1397
|
+
return true;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
// If any property is user-disabled (toggled off via checkbox), do not
|
|
1401
|
+
// collapse. The user deliberately disabled them.
|
|
1402
|
+
const hasDisabledProperty = properties.some(p => p.disabled);
|
|
1403
|
+
if (hasDisabledProperty) {
|
|
1404
|
+
return false;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
// If every property is OVERLOADED, collapse.
|
|
1408
|
+
const allOverloaded =
|
|
1409
|
+
properties.every(p => this.matchedStyles.propertyState(p) === SDK.CSSMatchedStyles.PropertyState.OVERLOADED);
|
|
1410
|
+
return allOverloaded;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
#updateCollapsedState(): void {
|
|
1414
|
+
const shouldCollapse = this.#shouldCollapse();
|
|
1415
|
+
// Mark as collapsible so the toggle icon is always shown for
|
|
1416
|
+
// sections that can be collapsed, even after manual expansion.
|
|
1417
|
+
this.element.classList.toggle('collapsible', shouldCollapse);
|
|
1418
|
+
this.#setCollapsed(shouldCollapse);
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
#setCollapsed(collapsed: boolean): void {
|
|
1422
|
+
this.#isCollapsed = collapsed;
|
|
1423
|
+
this.element.classList.toggle('collapsed', collapsed);
|
|
1424
|
+
this.propertiesTreeOutline.element.classList.toggle('hidden', collapsed);
|
|
1425
|
+
if (this.#collapseIcon) {
|
|
1426
|
+
this.#collapseIcon.name = collapsed ? 'triangle-right' : 'triangle-down';
|
|
1427
|
+
UI.ARIAUtils.setExpanded(this.#collapseIcon, !collapsed);
|
|
1428
|
+
UI.ARIAUtils.setLabel(
|
|
1429
|
+
this.#collapseIcon,
|
|
1430
|
+
collapsed ? i18nString(UIStrings.expandCollapsedRule) : i18nString(UIStrings.collapseExpandedRule));
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
#toggleCollapsed(): void {
|
|
1435
|
+
this.#setCollapsed(!this.#isCollapsed);
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
/**
|
|
1439
|
+
* Expand a collapsed section, e.g. when navigating to a property
|
|
1440
|
+
* via a var() link.
|
|
1441
|
+
*/
|
|
1442
|
+
expand(): void {
|
|
1443
|
+
if (!this.#isCollapsed) {
|
|
1444
|
+
return;
|
|
1445
|
+
}
|
|
1446
|
+
this.#setCollapsed(false);
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
isCollapsed(): boolean {
|
|
1450
|
+
return this.#isCollapsed;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1336
1453
|
markSelectorMatches(): void {
|
|
1337
1454
|
const rule = this.styleInternal.parentRule;
|
|
1338
1455
|
if (!rule || !(rule instanceof SDK.CSSRule.CSSStyleRule)) {
|
|
@@ -1395,6 +1512,10 @@ export class StylePropertiesSection {
|
|
|
1395
1512
|
|
|
1396
1513
|
addNewBlankProperty(index: number|undefined = this.propertiesTreeOutline.rootElement().childCount()):
|
|
1397
1514
|
StylePropertyTreeElement {
|
|
1515
|
+
if (this.#isCollapsed) {
|
|
1516
|
+
this.expand();
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1398
1519
|
const property = this.styleInternal.newBlankProperty(index);
|
|
1399
1520
|
const item = new StylePropertyTreeElement({
|
|
1400
1521
|
stylesContainer: this.stylesContainer,
|
|
@@ -1416,6 +1537,13 @@ export class StylePropertiesSection {
|
|
|
1416
1537
|
}
|
|
1417
1538
|
|
|
1418
1539
|
private handleEmptySpaceClick(event: Event): void {
|
|
1540
|
+
// If collapsed, clicking anywhere on the section should expand it.
|
|
1541
|
+
if (this.#isCollapsed) {
|
|
1542
|
+
this.#toggleCollapsed();
|
|
1543
|
+
event.consume(true);
|
|
1544
|
+
return;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1419
1547
|
// `this.willCauseCancelEditing` is a hacky way to understand whether we should
|
|
1420
1548
|
// create a new property or not on empty space click.
|
|
1421
1549
|
// For empty space clicks, the order of events are:
|
|
@@ -24,6 +24,7 @@ export class StylePropertyHighlighter {
|
|
|
24
24
|
if (!section) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
+
section.expand();
|
|
27
28
|
section.showAllItems();
|
|
28
29
|
const populatePromises: Array<Promise<void>> = [];
|
|
29
30
|
for (let treeElement = section.propertiesTreeOutline.firstChild(); treeElement;
|
|
@@ -57,6 +58,7 @@ export class StylePropertyHighlighter {
|
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
59
60
|
block.expand(true);
|
|
61
|
+
section.expand();
|
|
60
62
|
section.showAllItems();
|
|
61
63
|
PanelUtils.highlightElement(section.element);
|
|
62
64
|
}
|
|
@@ -78,6 +80,7 @@ export class StylePropertyHighlighter {
|
|
|
78
80
|
continue;
|
|
79
81
|
}
|
|
80
82
|
block?.expand(true);
|
|
83
|
+
section.expand();
|
|
81
84
|
section.showAllItems();
|
|
82
85
|
const treeElement = this.findTreeElementFromSection(
|
|
83
86
|
treeElement => treeElement.property.name === propertyName && !treeElement.overloaded(), section);
|
|
@@ -94,6 +94,40 @@
|
|
|
94
94
|
--override-styles-section-text-hover-text-decoration: underline;
|
|
95
95
|
--override-styles-section-text-hover-cursor: default;
|
|
96
96
|
}
|
|
97
|
+
|
|
98
|
+
& .section-collapse-icon {
|
|
99
|
+
width: 12px;
|
|
100
|
+
height: 12px;
|
|
101
|
+
margin-right: 2px;
|
|
102
|
+
margin-left: -2px;
|
|
103
|
+
vertical-align: middle;
|
|
104
|
+
cursor: pointer;
|
|
105
|
+
display: none;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&.collapsible .section-collapse-icon {
|
|
109
|
+
display: inline-block;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&.collapsed {
|
|
113
|
+
opacity: 60%;
|
|
114
|
+
|
|
115
|
+
& .style-properties {
|
|
116
|
+
display: none;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
& .styles-section-subtitle {
|
|
120
|
+
display: none;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
& .sidebar-pane-closing-brace {
|
|
124
|
+
display: none;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
& .sidebar-pane-open-brace::after {
|
|
128
|
+
content: "}";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
97
131
|
}
|
|
98
132
|
|
|
99
133
|
.sidebar-pane-closing-brace {
|
|
@@ -42,6 +42,7 @@ const UIStrings = {
|
|
|
42
42
|
} as const;
|
|
43
43
|
const str_ = i18n.i18n.registerUIStrings('panels/issues/AffectedSelectivePermissionsInterventionView.ts', UIStrings);
|
|
44
44
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
45
|
+
const {widget} = UI.Widget;
|
|
45
46
|
|
|
46
47
|
export class AffectedSelectivePermissionsInterventionView extends AffectedResourcesView {
|
|
47
48
|
readonly #linkifier = new Components.Linkifier.Linkifier();
|
|
@@ -103,13 +104,10 @@ export class AffectedSelectivePermissionsInterventionView extends AffectedResour
|
|
|
103
104
|
const debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
|
|
104
105
|
const stackTraceTranslated =
|
|
105
106
|
await debuggerWorkspaceBinding.createStackTraceFromProtocolRuntime(stackTrace, issuesModel.target());
|
|
106
|
-
return html
|
|
107
|
-
<devtools-widget .widgetConfig=${UI.Widget.widgetConfig(Components.JSPresentationUtils.StackTracePreviewContent, {
|
|
107
|
+
return html`${widget(Components.JSPresentationUtils.StackTracePreviewContent, {
|
|
108
108
|
stackTrace: stackTraceTranslated,
|
|
109
109
|
options: {expandable: true},
|
|
110
|
-
})}
|
|
111
|
-
</devtools-widget>
|
|
112
|
-
`;
|
|
110
|
+
})}`;
|
|
113
111
|
}
|
|
114
112
|
|
|
115
113
|
update(): void {
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from './LayerViewHost.js';
|
|
21
21
|
|
|
22
22
|
const {html, nothing} = Lit;
|
|
23
|
+
const {widget} = UI.Widget;
|
|
23
24
|
|
|
24
25
|
const UIStrings = {
|
|
25
26
|
/**
|
|
@@ -157,7 +158,7 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
157
158
|
if (!layer) {
|
|
158
159
|
// clang-format off
|
|
159
160
|
Lit.render(html`<div class="layer-details-container">
|
|
160
|
-
<devtools-widget class="learn-more"
|
|
161
|
+
<devtools-widget class="learn-more" ${widget(UI.EmptyWidget.EmptyWidget, {
|
|
161
162
|
header: i18nString(UIStrings.noLayerSelected),
|
|
162
163
|
text: i18nString(UIStrings.selectALayerToSeeItsDetails)})}>
|
|
163
164
|
</devtools-widget>
|
|
@@ -24,7 +24,7 @@ import * as PanelUtils from '../utils/utils.js';
|
|
|
24
24
|
import requestConditionsDrawerStyles from './requestConditionsDrawer.css.js';
|
|
25
25
|
|
|
26
26
|
const {ref, live} = Directives;
|
|
27
|
-
const {
|
|
27
|
+
const {widget} = UI.Widget;
|
|
28
28
|
|
|
29
29
|
const UIStrings = {
|
|
30
30
|
/**
|
|
@@ -175,7 +175,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
175
175
|
${i18nString(UIStrings.addRule)}
|
|
176
176
|
</devtools-button>
|
|
177
177
|
</div>
|
|
178
|
-
<devtools-widget
|
|
178
|
+
<devtools-widget ${widget(UI.Widget.VBox)}>
|
|
179
179
|
${input.list.element}
|
|
180
180
|
</devtools-widget>
|
|
181
181
|
`,
|
|
@@ -271,7 +271,7 @@ function renderItem(
|
|
|
271
271
|
<devtools-widget
|
|
272
272
|
class=conditions-selector
|
|
273
273
|
title=${i18nString(UIStrings.requestConditionsLabel)}
|
|
274
|
-
|
|
274
|
+
${widget(
|
|
275
275
|
MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelectorWidget, {
|
|
276
276
|
variant:
|
|
277
277
|
MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelect.Variant.INDIVIDUAL_REQUEST_CONDITIONS,
|
|
@@ -282,7 +282,7 @@ function renderItem(
|
|
|
282
282
|
})}></devtools-widget>
|
|
283
283
|
<devtools-widget
|
|
284
284
|
?disabled=${!editable || !originalOrUpgradedURLPattern}
|
|
285
|
-
|
|
285
|
+
${widget(AffectedCountWidget, {condition, lookUpRequestCount})}></devtools-widget>`;
|
|
286
286
|
// clang-format on
|
|
287
287
|
}
|
|
288
288
|
|
|
@@ -113,7 +113,7 @@ export const DEFAULT_VIEW: ViewFunction = (input, _output, target) => {
|
|
|
113
113
|
</div>
|
|
114
114
|
|
|
115
115
|
${input.requestCookies.cookies.length > 0 ? html`
|
|
116
|
-
<devtools-widget
|
|
116
|
+
<devtools-widget ${widget(CookieTable.CookiesTable.CookiesTable, {
|
|
117
117
|
cookiesData: input.requestCookies,
|
|
118
118
|
inline: true
|
|
119
119
|
})} class="cookie-table cookies-panel-item"></devtools-widget>
|
|
@@ -131,7 +131,7 @@ export const DEFAULT_VIEW: ViewFunction = (input, _output, target) => {
|
|
|
131
131
|
</div>
|
|
132
132
|
|
|
133
133
|
${input.responseCookies.cookies.length ? html`
|
|
134
|
-
<devtools-widget
|
|
134
|
+
<devtools-widget ${widget(CookieTable.CookiesTable.CookiesTable, {
|
|
135
135
|
cookiesData: input.responseCookies,
|
|
136
136
|
inline: true })} class="cookie-table cookies-panel-item"></devtools-widget>
|
|
137
137
|
` : Lit.nothing}
|
|
@@ -21,6 +21,7 @@ import * as NetworkComponents from './components/components.js';
|
|
|
21
21
|
import {ShowMoreDetailsWidget} from './ShowMoreDetailsWidget.js';
|
|
22
22
|
|
|
23
23
|
const {render, html} = Lit;
|
|
24
|
+
const {widget} = UI.Widget;
|
|
24
25
|
|
|
25
26
|
const UIStrings = {
|
|
26
27
|
/**
|
|
@@ -210,8 +211,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
210
211
|
contents: (input.showRequestHeadersText && requestHeadersText) ?
|
|
211
212
|
renderRawHeaders(requestHeadersText) :
|
|
212
213
|
html`
|
|
213
|
-
<devtools-widget .
|
|
214
|
-
UI.Widget.widgetConfig(NetworkComponents.RequestHeaderSection.RequestHeaderSection, {
|
|
214
|
+
<devtools-widget ${widget(NetworkComponents.RequestHeaderSection.RequestHeaderSection, {
|
|
215
215
|
request: input.request,
|
|
216
216
|
toReveal: input.toReveal,
|
|
217
217
|
})} jslog=${VisualLogging.section('request-headers')}></devtools-widget>`
|
|
@@ -392,8 +392,8 @@ function renderHeaderOverridesLink(input: ViewInput): Lit.LitTemplate {
|
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
function renderRawHeaders(text: string): Lit.TemplateResult {
|
|
395
|
-
return html`<div class="row raw-headers-row"><devtools-widget class=raw-headers
|
|
396
|
-
|
|
395
|
+
return html`<div class="row raw-headers-row"><devtools-widget class=raw-headers
|
|
396
|
+
${widget(ShowMoreDetailsWidget, {text})}></devtools-widget></div>`;
|
|
397
397
|
}
|
|
398
398
|
|
|
399
399
|
function renderGeneralRow(
|
|
@@ -43,7 +43,7 @@ export interface ViewOutput {
|
|
|
43
43
|
revealPosition: (position: SourceFrame.SourceFrame.RevealPosition) => Promise<void>;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
const {
|
|
46
|
+
const {widgetRef, widget} = UI.Widget;
|
|
47
47
|
type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) => void;
|
|
48
48
|
|
|
49
49
|
export const DEFAULT_VIEW: View = (input: ViewInput, output: ViewOutput, target: HTMLElement): void => {
|
|
@@ -62,7 +62,7 @@ export const DEFAULT_VIEW: View = (input: ViewInput, output: ViewOutput, target:
|
|
|
62
62
|
// clang-format on
|
|
63
63
|
} else if (input.renderAsText) {
|
|
64
64
|
// clang-format off
|
|
65
|
-
widgetTemplate = html`<devtools-widget
|
|
65
|
+
widgetTemplate = html`<devtools-widget ${widget(element => new SourceFrame.ResourceSourceFrame.SearchableContainer(
|
|
66
66
|
input.request, input.mimeType, element))}
|
|
67
67
|
${widgetRef(SourceFrame.ResourceSourceFrame.SearchableContainer, widget => {output.revealPosition = widget.revealPosition.bind(widget);})}></devtools-widget>`;
|
|
68
68
|
// clang-format on
|