Respect horizontal scrollbar when rendering the vertical, and vice versa

We set overflow to hidden in the opposite scroll direction only if we
can't actually scroll in that direction, causing the white square where
neither scrollbar overlaps to appear at the lower right corner.
This commit is contained in:
Nathan Sobo
2014-04-23 18:10:26 -06:00
parent d9ba9262bf
commit e6df30e94c
7 changed files with 56 additions and 13 deletions

View File

@@ -547,6 +547,26 @@ describe "EditorComponent", ->
bottomOfEditor = node.getBoundingClientRect().bottom
expect(bottomOfLastLine).toBe bottomOfEditor
it "assigns the overflow to 'hidden' in the opposite direction unless the editor scrollable in that direction", ->
expect(verticalScrollbarNode.style.overflowX).toBe 'hidden'
expect(horizontalScrollbarNode.style.overflowY).toBe 'hidden'
return
node.style.height = 4.5 * lineHeightInPixels + 'px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.style.overflowX).toBe 'hidden'
expect(horizontalScrollbarNode.style.overflowY).toBe ''
node.style.width = 10 * charWidth + 'px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.style.overflowX).toBe ''
expect(horizontalScrollbarNode.style.overflowY).toBe ''
node.style.height = 20 * lineHeightInPixels + 'px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.style.overflowX).toBe ''
expect(horizontalScrollbarNode.style.overflowY).toBe 'hidden'
describe "when a mousewheel event occurs on the editor", ->
it "updates the horizontal or vertical scrollbar depending on which delta is greater (x or y)", ->
node.style.height = 4.5 * lineHeightInPixels + 'px'

View File

@@ -123,9 +123,14 @@ class DisplayBuffer extends Model
horizontallyScrollable: ->
not @getSoftWrap() and @getScrollWidth() > @getWidth()
verticallyScrollable: ->
@getScrollHeight() > @getClientHeight()
getHorizontalScrollbarHeight: -> 15
getWidth: -> @width ? @getScrollWidth()
getWidth: ->
@width ? @getScrollWidth()
setWidth: (newWidth) ->
oldWidth = @width
@width = newWidth
@@ -149,6 +154,8 @@ class DisplayBuffer extends Model
setScrollLeft: (scrollLeft) ->
if @manageScrollPosition
@scrollLeft = Math.max(0, Math.min(@getScrollWidth() - @getWidth(), scrollLeft))
console.log @scrollLeft
@scrollLeft
else
@scrollLeft = scrollLeft

View File

@@ -55,6 +55,7 @@ EditorComponent = React.createClass
onScroll: @onVerticalScroll
scrollTop: scrollTop
scrollHeight: scrollHeight
scrollableInOppositeDirection: editor.horizontallyScrollable() if @isMounted()
ScrollbarComponent
ref: 'horizontalScrollbar'
@@ -63,6 +64,7 @@ EditorComponent = React.createClass
onScroll: @onHorizontalScroll
scrollLeft: scrollLeft
scrollWidth: scrollWidth
scrollableInOppositeDirection: editor.verticallyScrollable() if @isMounted()
getRenderedRowRange: ->
renderedRowRange = @props.editor.getVisibleRowRange()

View File

@@ -182,17 +182,19 @@ EditorScrollViewComponent = React.createClass
measureHeightAndWidth: ->
return unless @isMounted()
node = @getDOMNode()
computedStyle = getComputedStyle(node)
{editor} = @props
node = @getDOMNode()
editorNode = node.parentNode
{position} = getComputedStyle(editorNode)
{width, height} = editorNode.style
unless computedStyle.height is '0px'
clientHeight = node.clientHeight
if position is 'absolute' or height
clientHeight = node.clientHeight
editor.setHeight(clientHeight) if clientHeight > 0
unless computedStyle.width is '0px'
if position is 'absolute' or width
clientWidth = node.clientWidth
editor.setWidth(clientWidth) if clientHeight > 0
editor.setWidth(clientWidth) if clientWidth > 0
focus: ->
@refs.input.focus()

View File

@@ -1851,6 +1851,8 @@ class Editor extends Model
setHeight: (height) -> @displayBuffer.setHeight(height)
getHeight: -> @displayBuffer.getHeight()
getClientHeight: -> @displayBuffer.getClientHeight()
setWidth: (width) -> @displayBuffer.setWidth(width)
getWidth: -> @displayBuffer.getWidth()
@@ -1889,6 +1891,10 @@ class Editor extends Model
scrollToBufferPosition: (bufferPosition) -> @displayBuffer.scrollToBufferPosition(bufferPosition)
horizontallyScrollable: -> @displayBuffer.horizontallyScrollable()
verticallyScrollable: -> @displayBuffer.verticallyScrollable()
# Deprecated: Call {::joinLines} instead.
joinLine: ->
deprecate("Use Editor::joinLines() instead")

View File

@@ -1,13 +1,20 @@
React = require 'react'
{div} = require 'reactionary'
{isEqualForProperties} = require 'underscore-plus'
{extend, isEqualForProperties} = require 'underscore-plus'
module.exports =
ScrollbarComponent = React.createClass
render: ->
{orientation, className, scrollHeight, scrollWidth} = @props
{orientation, className, scrollHeight, scrollWidth, scrollableInOppositeDirection} = @props
div {className, @onScroll},
style = {}
switch orientation
when 'vertical'
style.overflowX = 'hidden' unless scrollableInOppositeDirection
when 'horizontal'
style.overflowY = 'hidden' unless scrollableInOppositeDirection
div {className, style, @onScroll},
switch orientation
when 'vertical'
div className: 'scrollbar-content', style: {height: scrollHeight}
@@ -23,9 +30,9 @@ ScrollbarComponent = React.createClass
shouldComponentUpdate: (newProps) ->
switch @props.orientation
when 'vertical'
not isEqualForProperties(newProps, @props, 'scrollHeight', 'scrollTop')
not isEqualForProperties(newProps, @props, 'scrollHeight', 'scrollTop', 'scrollableInOppositeDirection')
when 'horizontal'
not isEqualForProperties(newProps, @props, 'scrollWidth', 'scrollLeft')
not isEqualForProperties(newProps, @props, 'scrollWidth', 'scrollLeft', 'scrollableInOppositeDirection')
componentDidUpdate: ->
{orientation, scrollTop, scrollLeft} = @props

View File

@@ -24,7 +24,6 @@
height: 15px;
overflow-x: auto;
overflow-y: hidden;
z-index: 3;
.scrollbar-content {