Skip to content

Commit 5080a6b

Browse files
ktranDevtools-frontend LUCI CQ
authored andcommitted
[GM3Restyling] Update speculation empty states
This updates the speculation tab empty states if no rules/speculations have been detected. Screenshots: https://imgur.com/a/4M9V1AN Bug: 325443331 Change-Id: I3b1a5dd7330b9167911b2fd753caf8cce99de3d7 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6286307 Reviewed-by: Kateryna Prokopenko <[email protected]> Commit-Queue: Kim-Anh Tran <[email protected]>
1 parent 8b30510 commit 5080a6b

File tree

3 files changed

+109
-9
lines changed

3 files changed

+109
-9
lines changed

front_end/panels/application/preloading/PreloadingView.test.ts

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,30 @@ describeWithMockConnection('PreloadingRuleSetView', () => {
297297
SDK.ChildTargetManager.ChildTargetManager.install();
298298
});
299299

300-
it('renders grid and details', async () => {
300+
it('renders placeholder', async () => {
301+
const emulator = new NavigationEmulator();
302+
await emulator.openDevTools();
303+
const view = createRuleSetView(emulator.primaryTarget);
304+
await RenderCoordinator.done();
305+
306+
const placeholder = view.contentElement.querySelector('.empty-state');
307+
assert.exists(placeholder);
308+
assert.deepEqual(window.getComputedStyle(placeholder).display, 'flex');
309+
310+
const header = placeholder.querySelector('.empty-state-header')?.textContent;
311+
const description = placeholder.querySelector('.empty-state-description > span')?.textContent;
312+
313+
assert.deepEqual(header, 'No rules detected');
314+
assert.deepEqual(
315+
description,
316+
'On this page you will see the speculation rules used to prefetch and prerender page navigations.');
317+
318+
const rules = view.contentElement.querySelector('devtools-split-view');
319+
assert.exists(rules);
320+
assert.deepEqual(window.getComputedStyle(rules).display, 'none');
321+
});
322+
323+
it('renders grid and details and hides placeholder', async () => {
301324
const emulator = new NavigationEmulator();
302325
await emulator.openDevTools();
303326
const view = createRuleSetView(emulator.primaryTarget);
@@ -340,6 +363,10 @@ describeWithMockConnection('PreloadingRuleSetView', () => {
340363
['example.com/', '1 running'],
341364
],
342365
);
366+
367+
const placeholder = view.contentElement.querySelector('.empty-state');
368+
assert.exists(placeholder);
369+
assert.deepEqual(window.getComputedStyle(placeholder).display, 'none');
343370
});
344371

345372
it('shows error of rule set', async () => {
@@ -501,7 +528,28 @@ describeWithMockConnection('PreloadingAttemptView', () => {
501528
SDK.ChildTargetManager.ChildTargetManager.install();
502529
});
503530

504-
it('renders grid and details', async () => {
531+
it('renders placeholder', async () => {
532+
const emulator = new NavigationEmulator();
533+
await emulator.openDevTools();
534+
const view = createAttemptView(emulator.primaryTarget);
535+
await RenderCoordinator.done();
536+
537+
const placeholder = view.contentElement.querySelector('.empty-state');
538+
assert.exists(placeholder);
539+
assert.deepEqual(window.getComputedStyle(placeholder).display, 'flex');
540+
541+
const header = placeholder.querySelector('.empty-state-header')?.textContent;
542+
const description = placeholder.querySelector('.empty-state-description > span')?.textContent;
543+
544+
assert.deepEqual(header, 'No speculation detected');
545+
assert.deepEqual(description, 'On this page you will see details on speculative loads.');
546+
547+
const rules = view.contentElement.querySelector('devtools-split-view');
548+
assert.exists(rules);
549+
assert.deepEqual(window.getComputedStyle(rules).display, 'none');
550+
});
551+
552+
it('renders grid and details and hides placeholder', async () => {
505553
const emulator = new NavigationEmulator();
506554
await emulator.openDevTools();
507555
const view = createAttemptView(emulator.primaryTarget);
@@ -538,11 +586,9 @@ describeWithMockConnection('PreloadingAttemptView', () => {
538586
],
539587
);
540588

541-
const placeholderHeader = preloadingDetailsComponent.shadowRoot.querySelector('.empty-state-header');
542-
assert.strictEqual(placeholderHeader?.textContent?.trim(), 'No element selected');
543-
544-
const placeholderDescription = preloadingDetailsComponent.shadowRoot.querySelector('.empty-state-description');
545-
assert.strictEqual(placeholderDescription?.textContent, 'Select an element for more details');
589+
const placeholder = view.contentElement.querySelector('.empty-state');
590+
assert.exists(placeholder);
591+
assert.deepEqual(window.getComputedStyle(placeholder).display, 'none');
546592
});
547593

548594
// See https://crbug.com/1432880

front_end/panels/application/preloading/PreloadingView.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,34 @@ const UIStrings = {
7979
*@description Text to pretty print a file
8080
*/
8181
prettyPrint: 'Pretty print',
82+
/**
83+
*@description Placeholder text if there are no rules to show. https://developer.chrome.com/docs/devtools/application/debugging-speculation-rules
84+
*/
85+
noRulesDetected: 'No rules detected',
86+
/**
87+
*@description Placeholder text if there are no rules to show. https://developer.chrome.com/docs/devtools/application/debugging-speculation-rules
88+
*/
89+
rulesDescription: 'On this page you will see the speculation rules used to prefetch and prerender page navigations.',
90+
/**
91+
*@description Placeholder text if there are no speculation attempts for prefetching or prerendering urls. https://developer.chrome.com/docs/devtools/application/debugging-speculation-rules
92+
*/
93+
noPrefetchAttempts: 'No speculation detected',
94+
/**
95+
*@description Placeholder text if there are no speculation attempts for prefetching or prerendering urls. https://developer.chrome.com/docs/devtools/application/debugging-speculation-rules
96+
*/
97+
prefetchDescription: 'On this page you will see details on speculative loads.',
98+
/**
99+
*@description Text for a learn more link
100+
*/
101+
learnMore: 'Learn more',
82102
};
83103
const str_ = i18n.i18n.registerUIStrings('panels/application/preloading/PreloadingView.ts', UIStrings);
84104
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
85105

106+
const SPECULATION_EXPLANATION_URL =
107+
'https://developer.chrome.com/docs/devtools/application/debugging-speculation-rules' as
108+
Platform.DevToolsPath.UrlString;
109+
86110
// Used for selector, indicating no filter is specified.
87111
const AllRuleSetRootId = Symbol('AllRuleSetRootId');
88112

@@ -219,7 +243,6 @@ export class PreloadingRuleSetView extends UI.Widget.VBox {
219243
this.warningsView.show(this.warningsContainer);
220244

221245
this.ruleSetGrid.addEventListener('select', this.onRuleSetsGridCellFocused.bind(this));
222-
223246
const onPrettyPrintToggle = (): void => {
224247
this.shouldPrettyPrint = !this.shouldPrettyPrint;
225248
this.updateRuleSetDetails();
@@ -228,6 +251,13 @@ export class PreloadingRuleSetView extends UI.Widget.VBox {
228251
// clang-format off
229252
render(
230253
html`
254+
<div class="empty-state">
255+
<span class="empty-state-header">${i18nString(UIStrings.noRulesDetected)}</span>
256+
<div class="empty-state-description">
257+
<span>${i18nString(UIStrings.rulesDescription)}</span>
258+
${UI.XLink.XLink.create(SPECULATION_EXPLANATION_URL, i18nString(UIStrings.learnMore), 'x-link', undefined, 'learn-more')}
259+
</div>
260+
</div>
231261
<devtools-split-view .horizontal=${true} style="--min-sidebar-size: max(100vh-200px, 0px)">
232262
<div slot="main" class="overflow-auto" style="height: 100%">
233263
${this.ruleSetGrid}
@@ -298,7 +328,7 @@ export class PreloadingRuleSetView extends UI.Widget.VBox {
298328
};
299329
});
300330
this.ruleSetGrid.update({rows: ruleSetRows, pageURL: pageURL()});
301-
331+
this.contentElement.classList.toggle('empty', ruleSetRows.length === 0);
302332
this.updateRuleSetDetails();
303333
}
304334

@@ -377,6 +407,15 @@ export class PreloadingAttemptView extends UI.Widget.VBox {
377407
this.preloadingGrid.addEventListener('select', this.onPreloadingGridCellFocused.bind(this));
378408
render(
379409
html`
410+
<div class="empty-state">
411+
<span class="empty-state-header">${i18nString(UIStrings.noPrefetchAttempts)}</span>
412+
<div class="empty-state-description">
413+
<span>${i18nString(UIStrings.prefetchDescription)}</span>
414+
${
415+
UI.XLink.XLink.create(
416+
SPECULATION_EXPLANATION_URL, i18nString(UIStrings.learnMore), 'x-link', undefined, 'learn-more')}
417+
</div>
418+
</div>
380419
<devtools-split-view .horizontal=${true} style="--min-sidebar-size: 0px">
381420
<div slot="main" class="overflow-auto" style="height: 100%">
382421
${this.preloadingGrid}
@@ -447,6 +486,7 @@ export class PreloadingAttemptView extends UI.Widget.VBox {
447486
};
448487
});
449488
this.preloadingGrid.update({rows, pageURL: pageURL()});
489+
this.contentElement.classList.toggle('empty', rows.length === 0);
450490

451491
this.updatePreloadingDetails();
452492
}

front_end/panels/application/preloading/preloadingView.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
* found in the LICENSE file.
55
*/
66

7+
.empty-state {
8+
display: none;
9+
}
10+
11+
.empty {
12+
.empty-state {
13+
display: flex;
14+
}
15+
16+
devtools-split-view, .pretty-print-button, devtools-toolbar {
17+
display: none;
18+
}
19+
}
20+
721
.preloading-toolbar {
822
background-color: var(--sys-color-cdt-base-container);
923
border-bottom: 1px solid var(--sys-color-divider);

0 commit comments

Comments
 (0)