mirror of
https://github.com/atom/atom.git
synced 2026-01-24 22:38:20 -05:00
Correctly autoscroll if a horizontal scrollbar appears in the same frame
This commit is contained in:
committed by
Antonio Scandurra
parent
5d82dcf87a
commit
5c7208751f
@@ -404,6 +404,21 @@ describe('TextEditorComponent', () => {
|
||||
|
||||
expect(scroller.scrollLeft).toBe(component.getScrollWidth() - scroller.clientWidth)
|
||||
})
|
||||
|
||||
it('accounts for the presence of horizontal scrollbars that appear during the same frame as the autoscroll', async () => {
|
||||
const {component, element, editor} = buildComponent()
|
||||
const {scroller} = component.refs
|
||||
element.style.height = component.getScrollHeight() + 'px'
|
||||
element.style.width = component.getScrollWidth() + 'px'
|
||||
await component.getNextUpdatePromise()
|
||||
|
||||
editor.setCursorScreenPosition([10, Infinity])
|
||||
editor.insertText('\n\n' + 'x'.repeat(100))
|
||||
await component.getNextUpdatePromise()
|
||||
|
||||
expect(scroller.scrollTop).toBe(component.getScrollHeight() - scroller.clientHeight)
|
||||
expect(scroller.scrollLeft).toBe(component.getScrollWidth() - scroller.clientWidth)
|
||||
})
|
||||
})
|
||||
|
||||
describe('line and line number decorations', () => {
|
||||
|
||||
@@ -46,7 +46,6 @@ class TextEditorComponent {
|
||||
this.textNodesByScreenLineId = new Map()
|
||||
this.pendingAutoscroll = null
|
||||
this.autoscrollTop = null
|
||||
this.contentDimensionsChanged = false
|
||||
this.previousScrollWidth = 0
|
||||
this.previousScrollHeight = 0
|
||||
this.lastKeydown = null
|
||||
@@ -96,7 +95,6 @@ class TextEditorComponent {
|
||||
}
|
||||
|
||||
this.horizontalPositionsToMeasure.clear()
|
||||
if (this.contentDimensionsChanged) this.measureClientDimensions()
|
||||
if (this.pendingAutoscroll) this.initiateAutoscroll()
|
||||
this.populateVisibleRowRange()
|
||||
const longestLineToMeasure = this.checkForNewLongestLine()
|
||||
@@ -111,10 +109,34 @@ class TextEditorComponent {
|
||||
|
||||
etch.updateSync(this)
|
||||
|
||||
// If scrollHeight or scrollWidth changed, we may have shown or hidden
|
||||
// scrollbars, affecting the clientWidth or clientHeight
|
||||
if (this.checkIfScrollDimensionsChanged()) {
|
||||
this.measureClientDimensions()
|
||||
// If the clientHeight changed, our previous vertical autoscroll may have
|
||||
// been off by the height of the horizontal scrollbar. If we *still* need
|
||||
// to autoscroll, just re-render the frame.
|
||||
if (this.pendingAutoscroll && this.initiateAutoscroll()) {
|
||||
this.updateSync()
|
||||
return
|
||||
}
|
||||
}
|
||||
if (this.pendingAutoscroll) this.finalizeAutoscroll()
|
||||
this.currentFrameLineNumberGutterProps = null
|
||||
}
|
||||
|
||||
checkIfScrollDimensionsChanged () {
|
||||
const scrollHeight = this.getScrollHeight()
|
||||
const scrollWidth = this.getScrollWidth()
|
||||
if (scrollHeight !== this.previousScrollHeight || scrollWidth !== this.previousScrollWidth) {
|
||||
this.previousScrollHeight = scrollHeight
|
||||
this.previousScrollWidth = scrollWidth
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const model = this.getModel()
|
||||
|
||||
@@ -272,12 +294,6 @@ class TextEditorComponent {
|
||||
if (this.measurements) {
|
||||
const contentWidth = this.getContentWidth()
|
||||
const scrollHeight = this.getScrollHeight()
|
||||
if (contentWidth !== this.previousScrollWidth || scrollHeight !== this.previousScrollHeight) {
|
||||
this.contentDimensionsChanged = true
|
||||
this.previousScrollWidth = contentWidth
|
||||
this.previousScrollHeight = scrollHeight
|
||||
}
|
||||
|
||||
const width = contentWidth + 'px'
|
||||
const height = scrollHeight + 'px'
|
||||
style.width = width
|
||||
@@ -1055,21 +1071,27 @@ class TextEditorComponent {
|
||||
if (desiredScrollBottom > this.getScrollBottom()) {
|
||||
this.autoscrollTop = desiredScrollBottom - this.measurements.clientHeight
|
||||
this.measurements.scrollTop = this.autoscrollTop
|
||||
return true
|
||||
}
|
||||
if (desiredScrollTop < this.getScrollTop()) {
|
||||
this.autoscrollTop = desiredScrollTop
|
||||
this.measurements.scrollTop = this.autoscrollTop
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if (desiredScrollTop < this.getScrollTop()) {
|
||||
this.autoscrollTop = desiredScrollTop
|
||||
this.measurements.scrollTop = this.autoscrollTop
|
||||
return true
|
||||
}
|
||||
if (desiredScrollBottom > this.getScrollBottom()) {
|
||||
this.autoscrollTop = desiredScrollBottom - this.measurements.clientHeight
|
||||
this.measurements.scrollTop = this.autoscrollTop
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
finalizeAutoscroll () {
|
||||
@@ -1187,19 +1209,14 @@ class TextEditorComponent {
|
||||
}
|
||||
|
||||
measureClientDimensions () {
|
||||
let clientDimensionsChanged = false
|
||||
const {clientHeight, clientWidth} = this.refs.scroller
|
||||
if (clientHeight !== this.measurements.clientHeight) {
|
||||
this.measurements.clientHeight = clientHeight
|
||||
clientDimensionsChanged = true
|
||||
}
|
||||
if (clientWidth !== this.measurements.clientWidth) {
|
||||
this.measurements.clientWidth = clientWidth
|
||||
this.getModel().setWidth(clientWidth - this.getGutterContainerWidth(), true)
|
||||
clientDimensionsChanged = true
|
||||
}
|
||||
this.contentDimensionsChanged = false
|
||||
return clientDimensionsChanged
|
||||
}
|
||||
|
||||
measureCharacterDimensions () {
|
||||
|
||||
Reference in New Issue
Block a user