Support resizable & position-configurable diff sidebar Allow plugins to specify whether sidebar content in gr-diff-view should be placed on the left or right side via the Web Component's static sidebarPosition property or sidebar-position attribute. Integrate gr-content-with-sidebar in gr-diff-view wrapping the diff container so sidebar resizing works smoothly without interfering with sticky headers. TAG=agy CONV=e67a39e1-770b-4508-89ec-e8cec81ba0d6 Release-Notes: Support user-resizable and plugin-configurable left/right sidebar positioning in gr-diff-view. Google-Bug-Id: b/537885178 Change-Id: I8178f76396a5951caea2509d141e1271b2faf5e7
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts index ed56ad3..cf151d4 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts +++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
@@ -19,6 +19,8 @@ import '../gr-diff-preferences-dialog/gr-diff-preferences-dialog'; import '../gr-patch-range-select/gr-patch-range-select'; import '../../change/gr-download-dialog/gr-download-dialog'; +import '../../shared/gr-content-with-sidebar/gr-content-with-sidebar'; +import {pluginLoaderToken} from '../../shared/gr-js-api-interface/gr-plugin-loader'; import {getAppContext} from '../../../services/app-context'; import {getParentIndex, isMergeParent} from '../../../utils/patch-set-util'; import { @@ -88,7 +90,6 @@ import {ifDefined} from 'lit/directives/if-defined.js'; import {classMap} from 'lit/directives/class-map.js'; import {when} from 'lit/directives/when.js'; -import {styleMap} from 'lit/directives/style-map.js'; import {keyed} from 'lit/directives/keyed.js'; import { ChangeChildView, @@ -128,6 +129,8 @@ @customElement('gr-diff-view') export class GrDiffView extends LitElement { + private readonly getPluginLoader = resolve(this, pluginLoaderToken); + /** * Fired when user tries to navigate away while comments are pending save. * @@ -154,11 +157,6 @@ @query('#diffPreferencesDialog') diffPreferencesDialog?: GrDiffPreferencesDialog; - @query('.sidebarAnchor') - sidebarAnchor?: HTMLDivElement; - - @state() private sidebarHeight = 0; - // Private but used in tests. @state() get patchRange(): PatchRange | undefined { @@ -527,7 +525,6 @@ :host { display: block; background-color: var(--view-background-color); - --sidebar-width: 300px; } .hidden { display: none; @@ -703,24 +700,14 @@ :host(.hideCheckCodePointers) { --gr-check-code-pointers-display: none; } - .diffContainer.sidebarOpen { - margin-left: var(--sidebar-width); - } .sidebarTriggerContainer { display: inline-block; margin-right: var(--spacing-m); } - .sidebarAnchor { - height: 0; - width: 0; - overflow: visible; - } .sidebarContents { background: var(--background-color-secondary); - width: var(--sidebar-width); - border: var(--spacing-xxs) solid var(--border-color); - border-left: 0; - overflow: auto; + box-sizing: border-box; + height: 100%; } md-checkbox { --md-checkbox-container-size: 15px; @@ -750,8 +737,6 @@ this.addEventListener('open-fix-preview', e => this.onOpenFixPreview(e)); this.cursor = new GrDiffCursor(); if (this.diffHost) this.reInitCursor(); - window.addEventListener('scroll', this.updateSidebarHeight); - window.addEventListener('resize', this.updateSidebarHeight); this.getUserModel() .preferences$.pipe( map(p => p.diff_page_sidebar), @@ -769,8 +754,6 @@ override disconnectedCallback() { this.cursor?.dispose(); - window.removeEventListener('scroll', this.updateSidebarHeight); - window.removeEventListener('resize', this.updateSidebarHeight); super.disconnectedCallback(); } @@ -780,13 +763,6 @@ this.cursor?.reInitCursor(); } - private readonly updateSidebarHeight = () => { - if (this.sidebarAnchor) { - this.sidebarHeight = - window.innerHeight - this.sidebarAnchor.getBoundingClientRect().bottom; - } - }; - protected override updated(changedProperties: PropertyValues): void { super.updated(changedProperties); if ( @@ -845,7 +821,6 @@ this.patchRange ); } - this.updateSidebarHeight(); } override render() { @@ -869,34 +844,41 @@ </div> ` )} - <div - class=${classMap({ - diffContainer: true, - sidebarOpen: !!this.shownSidebar, - hidden: !!this.file?.diffs_too_expensive_to_compute, - })} + <gr-content-with-sidebar + .side=${this.getSidebarSide()} + .hideSide=${!this.shownSidebar} > - <gr-endpoint-decorator name="diff-content"> - <gr-diff-host - id="diffHost" - .changeNum=${this.changeNum} - .change=${this.change} - .patchRange=${this.patchRange} - .file=${file} - .lineOfInterest=${this.getLineOfInterest()} - .path=${this.path} - .projectName=${this.change?.project} - @is-blame-loaded-changed=${this.onIsBlameLoadedChanged} - @comment-anchor-tap=${this.onCommentAnchorTap} - @line-selected=${this.onLineSelected} - @diff-changed=${this.onDiffChanged} - @edit-weblinks-changed=${this.onEditWeblinksChanged} - @files-weblinks-changed=${this.onFilesWeblinksChanged} - @render=${this.reInitCursor} - > - </gr-diff-host> - </gr-endpoint-decorator> - </div> + <div + slot="main" + class=${classMap({ + diffContainer: true, + sidebarOpen: !!this.shownSidebar, + hidden: !!this.file?.diffs_too_expensive_to_compute, + })} + > + <gr-endpoint-decorator name="diff-content"> + <gr-diff-host + id="diffHost" + .changeNum=${this.changeNum} + .change=${this.change} + .patchRange=${this.patchRange} + .file=${file} + .lineOfInterest=${this.getLineOfInterest()} + .path=${this.path} + .projectName=${this.change?.project} + @is-blame-loaded-changed=${this.onIsBlameLoadedChanged} + @comment-anchor-tap=${this.onCommentAnchorTap} + @line-selected=${this.onLineSelected} + @diff-changed=${this.onDiffChanged} + @edit-weblinks-changed=${this.onEditWeblinksChanged} + @files-weblinks-changed=${this.onFilesWeblinksChanged} + @render=${this.reInitCursor} + > + </gr-diff-host> + </gr-endpoint-decorator> + </div> + <div slot="side">${this.renderSidebarContent()}</div> + </gr-content-with-sidebar> ${this.renderDialogs()} `; } @@ -921,7 +903,6 @@ >></a > </div> - ${this.renderSidebarContent()} </div>`; } @@ -1024,80 +1005,94 @@ `; } + private getSidebarSide(): 'left' | 'right' { + if (!this.shownSidebar) { + return 'left'; + } + const details = this.getPluginLoader().pluginEndPoints.getDetails( + `sidebarContent-${this.shownSidebar}` + ); + for (const info of details) { + if (info.moduleName) { + const customElement = customElements.get(info.moduleName) as + | (CustomElementConstructor & {sidebarPosition?: string}) + | undefined; + if (customElement?.sidebarPosition === 'right') { + return 'right'; + } + } + } + return 'left'; + } + private renderSidebarContent() { - // Always renders the 0x0px .sidebarAnchor div for scroll measurements. return html` - <div class="sidebarAnchor"> - ${when(this.shownSidebar !== undefined, () => - keyed( - this.shownSidebar, - html` - <div - class="sidebarContents" - style=${styleMap({height: `${this.sidebarHeight}px`})} + ${when(this.shownSidebar !== undefined, () => + keyed( + this.shownSidebar, + html` + <div class="sidebarContents"> + <gr-endpoint-decorator + name=${`sidebarContent-${this.shownSidebar}`} > - <gr-endpoint-decorator - name=${`sidebarContent-${this.shownSidebar}`} + <gr-endpoint-param + name="change" + .value=${this.change} + ></gr-endpoint-param> + <gr-endpoint-param + name="path" + .value=${this.path} + ></gr-endpoint-param> + <!-- current diff path and, in case of rename, previous path --> + <gr-endpoint-param + name="fileRange" + .value=${this.getFileRange()} + ></gr-endpoint-param> + <gr-endpoint-param + name="basePatchNum" + .value=${this.basePatchNum} + ></gr-endpoint-param> + <gr-endpoint-param + name="patchNum" + .value=${this.patchNum} + ></gr-endpoint-param> + <gr-endpoint-param + name="content" + .value=${this.diff} + ></gr-endpoint-param> + <gr-endpoint-param + name="cursor" + .value=${this.cursor} + ></gr-endpoint-param> + <gr-endpoint-param + name="diff" + .value=${this.diffHost?.diffElement} + ></gr-endpoint-param> + <gr-endpoint-param + name="comments" + .value=${this.commentsForPath} + ></gr-endpoint-param> + <gr-endpoint-param + name="onClose" + .value=${(pluginName: string) => { + // Only close the sidebar if that particular sidebar is + // still open. An async onClose callback should not close a + // different sidebar. + if (this.shownSidebar !== pluginName) { + return; + } + this.shownSidebar = undefined; + this.getUserModel().updatePreferences({ + diff_page_sidebar: 'NONE', + }); + }} > - <gr-endpoint-param - name="change" - .value=${this.change} - ></gr-endpoint-param> - <gr-endpoint-param - name="path" - .value=${this.path} - ></gr-endpoint-param> - <!-- current diff path and, in case of rename, previous path --> - <gr-endpoint-param - name="fileRange" - .value=${this.getFileRange()} - ></gr-endpoint-param> - <gr-endpoint-param - name="basePatchNum" - .value=${this.basePatchNum} - ></gr-endpoint-param> - <gr-endpoint-param - name="patchNum" - .value=${this.patchNum} - ></gr-endpoint-param> - <gr-endpoint-param - name="content" - .value=${this.diff} - ></gr-endpoint-param> - <gr-endpoint-param - name="cursor" - .value=${this.cursor} - ></gr-endpoint-param> - <gr-endpoint-param - name="diff" - .value=${this.diffHost?.diffElement} - ></gr-endpoint-param> - <gr-endpoint-param - name="comments" - .value=${this.commentsForPath} - ></gr-endpoint-param> - <gr-endpoint-param - name="onClose" - .value=${(pluginName: string) => { - // Only close the sidebar if that particular sidebar is - // still open. An async onClose callback should not close a - // different sidebar. - if (this.shownSidebar !== pluginName) { - return; - } - this.shownSidebar = undefined; - this.getUserModel().updatePreferences({ - diff_page_sidebar: 'NONE', - }); - }} - > - </gr-endpoint-param> - </gr-endpoint-decorator> - </div> - ` - ) - )} - </div> + </gr-endpoint-param> + </gr-endpoint-decorator> + </div> + ` + ) + )} `; }
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts index d1e2071..daed454 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts +++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
@@ -51,7 +51,9 @@ } from '../../../types/common'; import {CursorMoveResult} from '../../../api/core'; import {Side} from '../../../api/diff'; +import {PluginApi} from '../../../api/plugin'; import {Files, GrDiffView} from './gr-diff-view'; +import {GrContentWithSidebar} from '../../shared/gr-content-with-sidebar/gr-content-with-sidebar'; import {DropdownItem} from '../../shared/gr-dropdown-list/gr-dropdown-list'; import {SinonFakeTimers, SinonStub, SinonStubbedMember} from 'sinon'; import { @@ -398,14 +400,16 @@ > </a> </div> - <div class="sidebarAnchor"></div> </div> <h2 class="assistive-tech-only">Diff view</h2> - <div class="diffContainer"> - <gr-endpoint-decorator name="diff-content"> - <gr-diff-host id="diffHost"> </gr-diff-host> - </gr-endpoint-decorator> - </div> + <gr-content-with-sidebar> + <div class="diffContainer" slot="main"> + <gr-endpoint-decorator name="diff-content"> + <gr-diff-host id="diffHost"> </gr-diff-host> + </gr-endpoint-decorator> + </div> + <div slot="side"></div> + </gr-content-with-sidebar> <gr-apply-fix-dialog id="applyFixDialog"> </gr-apply-fix-dialog> <gr-diff-preferences-dialog id="diffPreferencesDialog"> </gr-diff-preferences-dialog> @@ -2289,6 +2293,48 @@ ); assert.notEqual(oldDecorator, newDecorator); }); + + test('defaults to left sidebar side when no sidebarPosition property set', async () => { + // @ts-expect-error: accessing private property shownSidebar for testing + element.shownSidebar = 'left-sidebar'; + await element.updateComplete; + + const contentWithSidebar = + element.shadowRoot?.querySelector<GrContentWithSidebar>( + 'gr-content-with-sidebar' + ); + assert.isNotNull(contentWithSidebar); + assert.equal(contentWithSidebar?.side, 'left'); + }); + + test('detects right sidebar side when static sidebarPosition === "right"', async () => { + class RightSidebar extends HTMLElement { + static sidebarPosition = 'right'; + } + + customElements.define('right-sidebar-element', RightSidebar); + + let plugin!: PluginApi; + window.Gerrit.install( + p => (plugin = p), + '0.1', + 'http://test.com/plugins/testplugin/static/test.js' + ); + plugin.registerDynamicCustomComponent( + 'sidebarContent', + 'right-sidebar-element' + ); + + // @ts-expect-error: accessing private property shownSidebar for testing + element.shownSidebar = 'testplugin'; + await element.updateComplete; + + const contentWithSidebar = + element.shadowRoot?.querySelector<GrContentWithSidebar>( + 'gr-content-with-sidebar' + ); + assert.equal(contentWithSidebar?.side, 'right'); + }); }); }); });
diff --git a/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar.ts b/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar.ts index 0e0638e..869f9df 100644 --- a/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar.ts +++ b/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar.ts
@@ -4,14 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 */ import {customElement, property, query, state} from 'lit/decorators.js'; -import {css, html, LitElement} from 'lit'; +import {css, html, LitElement, nothing} from 'lit'; import {styleMap} from 'lit/directives/style-map.js'; -const SIDEBAR_MIN_WIDTH = 400; +const SIDEBAR_MIN_WIDTH = 250; /** * A component that displays content in a main area and a resizable sidebar. - * The sidebar can be toggled between hidden and visible. + * The sidebar can be toggled between hidden and visible and positioned on the left or right. * * slot main - The content to be displayed in the main area. * slot side - The content to be displayed in the sidebar. @@ -21,11 +21,17 @@ @query('.sidebar-wrapper') sidebarWrapper?: HTMLElement; @state() - private sidebarWidthPx = SIDEBAR_MIN_WIDTH; + private sidebarWidthPx = 400; @property() hideSide = true; + @property() + side: 'left' | 'right' = 'right'; + + @property({type: Number}) + minWidth = SIDEBAR_MIN_WIDTH; + private isSidebarResizing = false; private sidebarResizingStartPosPx = 0; @@ -43,22 +49,29 @@ :host { display: block; position: relative; - --sidebar-height: calc(100vh - var(--sidebar-top)); + --sidebar-height: calc(100vh - var(--sidebar-top, 0px)); } .sidebar-wrapper { z-index: 50; position: absolute; display: flex; top: 0; - bottom: calc(0px - var(--sidebar-bottom-overflow)); - right: 0; - min-width: 400px; + bottom: calc(0px - var(--sidebar-bottom-overflow, 0px)); + min-width: 250px; max-width: 100%; background-color: var(--background-color-secondary); } + .sidebar-wrapper.right { + right: 0; + left: auto; + } + .sidebar-wrapper.left { + left: 0; + right: auto; + } .sidebar { position: sticky; - top: var(--sidebar-top); + top: var(--sidebar-top, 0px); height: var(--sidebar-height); box-sizing: border-box; overflow: auto; @@ -67,35 +80,55 @@ } .resizer-wrapper { position: sticky; - top: var(--sidebar-top); + top: var(--sidebar-top, 0px); height: var(--sidebar-height); z-index: 51; } .resizer { background-color: var(--background-color-secondary); width: 7px; - border-left: 1px solid var(--border-color); cursor: ew-resize; position: absolute; top: 0; bottom: 0; - left: -7px; box-sizing: border-box; } - .resizer:hover { + .resizer.right-side { + left: -7px; + border-left: 1px solid var(--border-color); + } + .resizer.right-side:hover { background-color: var(--background-color-tertiary); width: 11px; left: -9px; } + .resizer.left-side { + right: -7px; + border-right: 1px solid var(--border-color); + } + .resizer.left-side:hover { + background-color: var(--background-color-tertiary); + width: 11px; + right: -9px; + } `, ]; } override render() { const widthPx = this.hideSide ? 0 : this.sidebarWidthPx; + const mainStyle = + this.side === 'left' + ? styleMap({ + marginLeft: `${widthPx}px`, + width: `calc(100% - ${widthPx}px)`, + }) + : styleMap({ + width: `calc(100% - ${widthPx}px)`, + }); return html` <div> - <div style=${styleMap({width: `calc(100% - ${widthPx}px)`})}> + <div style=${mainStyle}> <slot name="main"></slot> </div> ${this.renderSidebar()} @@ -105,25 +138,34 @@ private renderSidebar() { if (this.hideSide) return; + const sideClass = this.side === 'left' ? 'left' : 'right'; + const resizerClass = this.side === 'left' ? 'left-side' : 'right-side'; return html` <div - class="sidebar-wrapper" + class="sidebar-wrapper ${sideClass}" style=${styleMap({width: `${this.sidebarWidthPx}px`})} > - <div class="resizer-wrapper"> - <div - class="resizer" - role="separator" - aria-orientation="vertical" - aria-valuenow=${this.sidebarWidthPx} - aria-label="Resize sidebar" - tabindex="0" - @mousedown=${this.startSidebarResize} - ></div> - </div> + ${this.side === 'right' ? this.renderResizer(resizerClass) : nothing} <div class="sidebar"> <slot name="side"></slot> </div> + ${this.side === 'left' ? this.renderResizer(resizerClass) : nothing} + </div> + `; + } + + private renderResizer(resizerClass: string) { + return html` + <div class="resizer-wrapper"> + <div + class="resizer ${resizerClass}" + role="separator" + aria-orientation="vertical" + aria-valuenow=${this.sidebarWidthPx} + aria-label="Resize sidebar" + tabindex="0" + @mousedown=${this.startSidebarResize} + ></div> </div> `; } @@ -157,10 +199,11 @@ if (!this.isSidebarResizing || event.buttons === 0) return; const widthDiffPx = event.clientX - this.sidebarResizingStartPosPx; - this.sidebarWidthPx = Math.max( - this.sidebarResizingStartWidthPx - widthDiffPx, - SIDEBAR_MIN_WIDTH - ); + const rawWidth = + this.side === 'right' + ? this.sidebarResizingStartWidthPx - widthDiffPx + : this.sidebarResizingStartWidthPx + widthDiffPx; + this.sidebarWidthPx = Math.max(rawWidth, this.minWidth); } }
diff --git a/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar_screenshot_test.ts b/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar_screenshot_test.ts index 52ea31d..7ed19b7 100644 --- a/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar_screenshot_test.ts +++ b/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar_screenshot_test.ts
@@ -44,8 +44,23 @@ await element.updateComplete; }); - test('screenshot', async () => { - await visualDiff(wrapper, 'gr-content-with-sidebar'); - await visualDiffDarkTheme(wrapper, 'gr-content-with-sidebar'); + test('screenshot right sidebar', async () => { + const element = wrapper.querySelector<GrContentWithSidebar>( + 'gr-content-with-sidebar' + )!; + element.side = 'right'; + await element.updateComplete; + await visualDiff(wrapper, 'gr-content-with-sidebar-right'); + await visualDiffDarkTheme(wrapper, 'gr-content-with-sidebar-right'); + }); + + test('screenshot left sidebar', async () => { + const element = wrapper.querySelector<GrContentWithSidebar>( + 'gr-content-with-sidebar' + )!; + element.side = 'left'; + await element.updateComplete; + await visualDiff(wrapper, 'gr-content-with-sidebar-left'); + await visualDiffDarkTheme(wrapper, 'gr-content-with-sidebar-left'); }); });
diff --git a/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar_test.ts b/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar_test.ts index 7905c0a..626e3dc 100644 --- a/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar_test.ts +++ b/polygerrit-ui/app/elements/shared/gr-content-with-sidebar/gr-content-with-sidebar_test.ts
@@ -34,8 +34,9 @@ ); }); - test('renders sidebar', async () => { + test('renders right sidebar', async () => { element.hideSide = false; + element.side = 'right'; await element.updateComplete; assert.shadowDom.equal( @@ -45,13 +46,13 @@ <div style="width: calc(100% - 400px);"> <slot name="main"> </slot> </div> - <div class="sidebar-wrapper" style="width:400px;"> + <div class="right sidebar-wrapper" style="width:400px;"> <div class="resizer-wrapper"> <div aria-label="Resize sidebar" aria-orientation="vertical" aria-valuenow="400" - class="resizer" + class="right-side resizer" role="separator" tabindex="0" ></div> @@ -64,4 +65,36 @@ ` ); }); + + test('renders left sidebar', async () => { + element.hideSide = false; + element.side = 'left'; + await element.updateComplete; + + assert.shadowDom.equal( + element, + /* HTML */ ` + <div> + <div style="width: calc(100% - 400px); margin-left: 400px;"> + <slot name="main"> </slot> + </div> + <div class="left sidebar-wrapper" style="width:400px;"> + <div class="sidebar"> + <slot name="side"> </slot> + </div> + <div class="resizer-wrapper"> + <div + aria-label="Resize sidebar" + aria-orientation="vertical" + aria-valuenow="400" + class="left-side resizer" + role="separator" + tabindex="0" + ></div> + </div> + </div> + </div> + ` + ); + }); });
diff --git a/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-left-dark.png b/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-left-dark.png new file mode 100644 index 0000000..0f4857e --- /dev/null +++ b/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-left-dark.png Binary files differ
diff --git a/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-left.png b/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-left.png new file mode 100644 index 0000000..2464d3f --- /dev/null +++ b/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-left.png Binary files differ
diff --git a/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-right-dark.png b/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-right-dark.png new file mode 100644 index 0000000..238c3fb --- /dev/null +++ b/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-right-dark.png Binary files differ
diff --git a/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-right.png b/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-right.png new file mode 100644 index 0000000..ff32fb3 --- /dev/null +++ b/polygerrit-ui/screenshots/Chromium/baseline/gr-content-with-sidebar-right.png Binary files differ