@@ -19,6 +19,7 @@ import { DiffEditorItemTemplate, TemplateData } from './diffEditorItemTemplate';
1919import { ObjectPool } from './objectPool' ;
2020import { disposableObservableValue , globalTransaction , transaction } from 'vs/base/common/observableInternal/base' ;
2121import { IWorkbenchUIElementFactory } from 'vs/editor/browser/widget/multiDiffEditorWidget/workbenchUIElementFactory' ;
22+ import { findFirstMaxBy } from 'vs/base/common/arraysFind' ;
2223
2324export class MultiDiffEditorWidgetImpl extends Disposable {
2425 private readonly _elements = h ( 'div' , {
@@ -58,14 +59,28 @@ export class MultiDiffEditorWidgetImpl extends Disposable {
5859 } ,
5960 } , { } ) ) ;
6061
62+ private readonly _scrollable = this . _register ( new Scrollable ( {
63+ forceIntegerValues : false ,
64+ scheduleAtNextAnimationFrame : ( cb ) => scheduleAtNextAnimationFrame ( getWindow ( this . _element ) , cb ) ,
65+ smoothScrollDuration : 100 ,
66+ } ) ) ;
67+
68+ private readonly _scrollableElement = this . _register ( new SmoothScrollableElement ( this . _elements . root , {
69+ vertical : ScrollbarVisibility . Auto ,
70+ horizontal : ScrollbarVisibility . Auto ,
71+ className : 'monaco-component' ,
72+ useShadows : false ,
73+ } , this . _scrollable ) ) ;
74+
75+ private readonly _scrollTop = observableFromEvent ( this . _scrollableElement . onScroll , ( ) => /** @description scrollTop */ this . _scrollableElement . getScrollPosition ( ) . scrollTop ) ;
76+ private readonly _scrollLeft = observableFromEvent ( this . _scrollableElement . onScroll , ( ) => /** @description scrollLeft */ this . _scrollableElement . getScrollPosition ( ) . scrollLeft ) ;
77+
6178 private readonly _viewItems = derivedWithStore < DiffEditorItem [ ] > ( this ,
62- ( reader , store ) => this . _documents . read ( reader ) . map ( d => store . add ( new DiffEditorItem ( this . _objectPool , d , this . _editor ) ) )
79+ ( reader , store ) => this . _documents . read ( reader ) . map ( d => store . add ( new DiffEditorItem ( this . _objectPool , d , this . _editor , this . _scrollLeft ) ) )
6380 ) ;
6481
6582 private readonly _totalHeight = this . _viewItems . map ( this , ( items , reader ) => items . reduce ( ( r , i ) => r + i . contentHeight . read ( reader ) , 0 ) ) ;
6683
67- private readonly _scrollTop : IObservable < number > ;
68-
6984 constructor (
7085 private readonly _element : HTMLElement ,
7186 private readonly _dimension : IObservable < Dimension | undefined > ,
@@ -75,45 +90,38 @@ export class MultiDiffEditorWidgetImpl extends Disposable {
7590 ) {
7691 super ( ) ;
7792
78- //this._sizeObserver.setAutomaticLayout(true);
79-
8093 this . _register ( autorun ( ( reader ) => {
8194 /** @description Update widget dimension */
8295 const dimension = this . _dimension . read ( reader ) ;
8396 this . _sizeObserver . observe ( dimension ) ;
8497 } ) ) ;
8598
86- const scrollable = this . _register ( new Scrollable ( {
87- forceIntegerValues : false ,
88- scheduleAtNextAnimationFrame : ( cb ) => scheduleAtNextAnimationFrame ( getWindow ( _element ) , cb ) ,
89- smoothScrollDuration : 100 ,
90- } ) ) ;
91-
9299 this . _elements . content . style . position = 'relative' ;
93100
94- const scrollableElement = this . _register ( new SmoothScrollableElement ( this . _elements . root , {
95- vertical : ScrollbarVisibility . Auto ,
96- className : 'monaco-component' ,
97- useShadows : false ,
98- } , scrollable ) ) ;
99-
100- this . _scrollTop = observableFromEvent ( scrollableElement . onScroll , ( ) => /** @description onScroll */ scrollableElement . getScrollPosition ( ) . scrollTop ) ;
101-
102101 this . _register ( autorun ( ( reader ) => {
103102 /** @description Update scroll dimensions */
104103 const height = this . _sizeObserver . height . read ( reader ) ;
105104 this . _elements . root . style . height = `${ height } px` ;
106105 const totalHeight = this . _totalHeight . read ( reader ) ;
107106 this . _elements . content . style . height = `${ totalHeight } px` ;
108- scrollableElement . setScrollDimensions ( {
107+
108+ let scrollWidth = _element . clientWidth ;
109+ const viewItems = this . _viewItems . read ( reader ) ;
110+ const max = findFirstMaxBy ( viewItems , i => i . maxScroll . read ( reader ) . maxScroll ) ;
111+ if ( max ) {
112+ const maxScroll = max . maxScroll . read ( reader ) ;
113+ scrollWidth = _element . clientWidth + maxScroll . maxScroll ;
114+ }
115+
116+ this . _scrollableElement . setScrollDimensions ( {
109117 width : _element . clientWidth ,
110118 height : height ,
111119 scrollHeight : totalHeight ,
112- scrollWidth : _element . clientWidth ,
120+ scrollWidth,
113121 } ) ;
114122 } ) ) ;
115123
116- _element . replaceChildren ( scrollableElement . getDomNode ( ) ) ;
124+ _element . replaceChildren ( this . _scrollableElement . getDomNode ( ) ) ;
117125 this . _register ( toDisposable ( ( ) => {
118126 _element . replaceChildren ( ) ;
119127 } ) ) ;
@@ -163,25 +171,36 @@ export class MultiDiffEditorWidgetImpl extends Disposable {
163171}
164172
165173class DiffEditorItem extends Disposable {
166- private readonly _lastTemplateHeight = observableValue ( this , 500 ) ;
174+ private readonly _lastTemplateData = observableValue < { contentHeight : number ; maxScroll : { maxScroll : number ; width : number } } > (
175+ this ,
176+ { contentHeight : 500 , maxScroll : { maxScroll : 0 , width : 0 } , }
177+ ) ;
167178 private readonly _templateRef = this . _register ( disposableObservableValue < IReference < DiffEditorItemTemplate > | undefined > ( this , undefined ) ) ;
168179 private _vm : IDiffEditorViewModel | undefined ;
169180
170181 public readonly contentHeight = derived ( this , reader =>
171- this . _templateRef . read ( reader ) ?. object . height ?. read ( reader ) ?? this . _lastTemplateHeight . read ( reader )
182+ this . _templateRef . read ( reader ) ?. object . height ?. read ( reader ) ?? this . _lastTemplateData . read ( reader ) . contentHeight
172183 ) ;
173184
185+ public readonly maxScroll = derived ( this , reader => this . _templateRef . read ( reader ) ?. object . maxScroll . read ( reader ) ?? this . _lastTemplateData . read ( reader ) . maxScroll ) ;
186+
174187 constructor (
175188 private readonly _objectPool : ObjectPool < TemplateData , DiffEditorItemTemplate > ,
176189 private readonly _entry : LazyPromise < IDiffEntry > ,
177190 baseDiffEditorWidget : DiffEditorWidget ,
191+ private readonly _scrollLeft : IObservable < number > ,
178192 ) {
179193 super ( ) ;
180194
181195 this . _vm = this . _register ( baseDiffEditorWidget . createViewModel ( {
182196 original : _entry . value ! . original ! ,
183197 modified : _entry . value ! . modified ! ,
184198 } ) ) ;
199+
200+ this . _register ( autorun ( ( reader ) => {
201+ const scrollLeft = this . _scrollLeft . read ( reader ) ;
202+ this . _templateRef . read ( reader ) ?. object . setScrollLeft ( scrollLeft ) ;
203+ } ) ) ;
185204 }
186205
187206 override dispose ( ) : void {
@@ -197,7 +216,10 @@ class DiffEditorItem extends Disposable {
197216 const ref = this . _templateRef . get ( ) ;
198217 transaction ( tx => {
199218 if ( ref ) {
200- this . _lastTemplateHeight . set ( ref . object . height . get ( ) , tx ) ;
219+ this . _lastTemplateData . set ( {
220+ contentHeight : ref . object . height . get ( ) ,
221+ maxScroll : { maxScroll : 0 , width : 0 , } // Reset max scroll
222+ } , tx ) ;
201223 ref . object . hide ( ) ;
202224 }
203225 this . _templateRef . set ( undefined , tx ) ;
0 commit comments