Skip to content

Commit

Permalink
Respect horizontal scrollbar when rendering the vertical, and vice versa
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Nathan Sobo committed May 9, 2014
1 parent d9ba926 commit e6df30e
Showing 7 changed files with 56 additions and 13 deletions.
20 changes: 20 additions & 0 deletions spec/editor-component-spec.coffee
Original file line number Diff line number Diff line change
@@ -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'
9 changes: 8 additions & 1 deletion src/display-buffer.coffee
Original file line number Diff line number Diff line change
@@ -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

2 changes: 2 additions & 0 deletions src/editor-component.coffee
Original file line number Diff line number Diff line change
@@ -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()
14 changes: 8 additions & 6 deletions src/editor-scroll-view-component.coffee
Original file line number Diff line number Diff line change
@@ -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()
6 changes: 6 additions & 0 deletions src/editor.coffee
Original file line number Diff line number Diff line change
@@ -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")
17 changes: 12 additions & 5 deletions src/scrollbar-component.coffee
Original file line number Diff line number Diff line change
@@ -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
1 change: 0 additions & 1 deletion static/editor.less
Original file line number Diff line number Diff line change
@@ -24,7 +24,6 @@

height: 15px;
overflow-x: auto;
overflow-y: hidden;
z-index: 3;

.scrollbar-content {

0 comments on commit e6df30e

Please sign in to comment.