@@ -41,6 +41,7 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
4141 private stackLimit = 10 ;
4242 private updateCount = 0 ;
4343 private renderCount = 0 ;
44+ private internalScrollCount = 0 ;
4445 private editCellRef : Cell | null = null ;
4546 private mainPanel : HTMLDivElement | null = null ;
4647 private variableExplorerRef : React . RefObject < VariableExplorer > ;
@@ -68,7 +69,8 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
6869 editorOptions : this . computeEditorOptions ( ) ,
6970 currentExecutionCount : 0 ,
7071 debugging : false ,
71- enableGather : getSettings && getSettings ( ) . enableGather
72+ enableGather : getSettings && getSettings ( ) . enableGather ,
73+ isAtBottom : true
7274 } ;
7375
7476 // Add test state if necessary
@@ -151,7 +153,7 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
151153 < section id = 'main-panel-variable' aria-label = { getLocString ( 'DataScience.collapseVariableExplorerLabel' , 'Variables' ) } >
152154 { this . renderVariablePanel ( baseTheme ) }
153155 </ section >
154- < main id = 'main-panel-content' >
156+ < main id = 'main-panel-content' onScroll = { this . handleScroll } >
155157 { this . renderContentPanel ( baseTheme ) }
156158 </ main >
157159 < section id = 'main-panel-footer' aria-label = { getLocString ( 'DataScience.editSection' , 'Input new cells here' ) } >
@@ -161,6 +163,26 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
161163 ) ;
162164 }
163165
166+ // This handles the scrolling. Its called from the props of contentPanel.
167+ // We only scroll when the state indicates we are at the bottom of the interactive window,
168+ // otherwise it sometimes scrolls when the user wasn't at the bottom.
169+ public scrollDiv = ( div : HTMLDivElement ) => {
170+ if ( this . state . isAtBottom ) {
171+ this . internalScrollCount += 1 ;
172+ div . scrollIntoView ( { behavior : 'auto' , block : 'start' , inline : 'nearest' } ) ;
173+ }
174+ }
175+
176+ public handleScroll = ( e : React . UIEvent < HTMLDivElement > ) => {
177+ if ( this . internalScrollCount > 0 ) {
178+ this . internalScrollCount -= 1 ;
179+ } else {
180+ this . setState ( {
181+ isAtBottom : e . currentTarget . scrollHeight - e . currentTarget . scrollTop === e . currentTarget . clientHeight
182+ } ) ;
183+ }
184+ }
185+
164186 // tslint:disable-next-line:no-any cyclomatic-complexity max-func-body-length
165187 public handleMessage = ( msg : string , payload ?: any ) => {
166188 switch ( msg ) {
@@ -445,7 +467,8 @@ export class MainPanel extends React.Component<IMainPanelProps, IMainPanelState>
445467 openLink : this . openLink ,
446468 expandImage : this . showPlot ,
447469 gatherCode : this . gatherCode ,
448- enableGather : this . state . enableGather
470+ enableGather : this . state . enableGather ,
471+ scrollToBottom : this . scrollDiv
449472 } ;
450473 }
451474 private getToolbarProps = ( baseTheme : string ) : IToolbarPanelProps => {
0 commit comments