Restore scrollbar positions correctly on reload

This commit is contained in:
Antonio Scandurra
2017-04-21 16:54:59 +02:00
parent 72d6316459
commit 37b5d2eb4d
2 changed files with 21 additions and 18 deletions

View File

@@ -212,10 +212,13 @@ describe('TextEditorComponent', () => {
})
it('updates the bottom/right of dummy scrollbars and client height/width measurements when scrollbar styles change', async () => {
it('updates the bottom/right of dummy scrollbars and client height/width measurements without forgetting the previous scroll top/left when scrollbar styles change', async () => {
const {component, element, editor} = buildComponent({height: 100, width: 100})
expect(getHorizontalScrollbarHeight(component)).toBeGreaterThan(10)
expect(getVerticalScrollbarWidth(component)).toBeGreaterThan(10)
setScrollTop(component, 20)
setScrollLeft(component, 10)
await component.getNextUpdatePromise()
const style = document.createElement('style')
style.textContent = '::-webkit-scrollbar { height: 10px; width: 10px; }'
@@ -228,6 +231,8 @@ describe('TextEditorComponent', () => {
expect(getVerticalScrollbarWidth(component)).toBe(10)
expect(component.refs.horizontalScrollbar.element.style.right).toBe('10px')
expect(component.refs.verticalScrollbar.element.style.bottom).toBe('10px')
expect(component.refs.horizontalScrollbar.element.scrollLeft).toBe(10)
expect(component.refs.verticalScrollbar.element.scrollTop).toBe(20)
expect(component.getScrollContainerClientHeight()).toBe(100 - 10)
expect(component.getScrollContainerClientWidth()).toBe(100 - component.getGutterContainerWidth() - 10)
})

View File

@@ -339,6 +339,14 @@ class TextEditorComponent {
this.scrollTopPending = false
this.scrollLeftPending = false
if (this.remeasureScrollbars) {
// Flush stored scroll positions to the vertical and the horizontal
// scrollbars. This is because they have just been destroyed and recreated
// as a result of their remeasurement, but we could not assign the scroll
// top while they were initialized because they were not attached to the
// DOM yet.
this.refs.verticalScrollbar.flushScrollPosition()
this.refs.horizontalScrollbar.flushScrollPosition()
this.measureScrollbarDimensions()
this.remeasureScrollbars = false
etch.updateSync(this)
@@ -2585,31 +2593,21 @@ class DummyScrollbarComponent {
constructor (props) {
this.props = props
etch.initialize(this)
if (this.props.orientation === 'horizontal') {
this.element.scrollLeft = this.props.scrollLeft
} else {
this.element.scrollTop = this.props.scrollTop
}
}
update (newProps) {
const oldProps = this.props
this.props = newProps
etch.updateSync(this)
if (this.props.orientation === 'horizontal') {
if (newProps.scrollLeft !== oldProps.scrollLeft) {
this.element.scrollLeft = this.props.scrollLeft
}
} else {
if (newProps.scrollTop !== oldProps.scrollTop) {
this.element.scrollTop = this.props.scrollTop
}
}
const shouldFlushScrollPosition = (
newProps.scrollTop !== oldProps.scrollTop ||
newProps.scrollLeft !== oldProps.scrollLeft
)
if (shouldFlushScrollPosition) this.flushScrollPosition()
}
// Scroll position must be updated after the inner element is updated to
// ensure the element has an adequate scrollHeight/scrollWidth
updateScrollPosition () {
flushScrollPosition () {
if (this.props.orientation === 'horizontal') {
this.element.scrollLeft = this.props.scrollLeft
} else {