Explicitly assign dummy scrollbars to the correct width/height

Previously, dummy scrollbars were always 15px wide/tall. This caused
them to obscure the ability to click for the entire 15px region, even if
the actual scrollbar was styled to be much thinner. Now we explicitly
measure the size of scrollbars on mount and when the stylesheets change
and set the height/width explicitly.
This commit is contained in:
Nathan Sobo
2014-05-02 12:32:03 -07:00
parent e1b4b921ba
commit bdd605e85b
4 changed files with 53 additions and 4 deletions

View File

@@ -603,6 +603,21 @@ describe "EditorComponent", ->
expect(verticalScrollbarNode.style.display).toBe 'none'
expect(horizontalScrollbarNode.style.display).toBe ''
it "makes the dummy scrollbar divs only as tall/wide as the actual scrollbars", ->
atom.themes.applyStylesheet "test", """
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
"""
node.style.height = 4 * lineHeightInPixels + 'px'
node.style.width = 10 * charWidth + 'px'
component.measureHeightAndWidth()
expect(verticalScrollbarNode.offsetWidth).toBe 8
expect(horizontalScrollbarNode.offsetHeight).toBe 8
it "assigns the bottom/right of the scrollbars to the width of the opposite scrollbar if it is visible", ->
scrollbarCornerNode = node.querySelector('.scrollbar-corner')

View File

@@ -22,6 +22,7 @@ EditorComponent = React.createClass
preservedRowRange: null
scrollingVertically: false
gutterWidth: 0
measuringScrollbars: true
render: ->
{focused, fontSize, lineHeight, fontFamily, showIndentGuide} = @state
@@ -64,8 +65,9 @@ EditorComponent = React.createClass
onScroll: @onVerticalScroll
scrollTop: scrollTop
scrollHeight: scrollHeight
visible: verticallyScrollable
visible: not @measuringScrollbars and verticallyScrollable
scrollableInOppositeDirection: horizontallyScrollable
verticalScrollbarWidth: verticalScrollbarWidth
horizontalScrollbarHeight: horizontalScrollbarHeight
ScrollbarComponent
@@ -75,12 +77,16 @@ EditorComponent = React.createClass
onScroll: @onHorizontalScroll
scrollLeft: scrollLeft
scrollWidth: scrollWidth + @gutterWidth
visible: horizontallyScrollable
visible: not @measuringScrollbars and horizontallyScrollable
scrollableInOppositeDirection: verticallyScrollable
verticalScrollbarWidth: verticalScrollbarWidth
horizontalScrollbarHeight: horizontalScrollbarHeight
# Also used to measure the height/width of scrollbars after the initial render
ScrollbarCornerComponent
visible: horizontallyScrollable and verticallyScrollable
ref: 'scrollbarCorner'
visible: @measuringScrollbars or horizontallyScrollable and verticallyScrollable
measuringScrollbars: @measuringScrollbars
height: horizontalScrollbarHeight
width: verticalScrollbarWidth
@@ -106,6 +112,8 @@ EditorComponent = React.createClass
@observeEditor()
@listenForDOMEvents()
@listenForCommands()
@measureScrollbars()
@subscribe atom.themes, 'stylesheets-changed', @onStylesheetsChanged
@props.editor.setVisible(true)
@requestUpdate()
@@ -119,6 +127,7 @@ EditorComponent = React.createClass
componentDidUpdate: ->
@pendingChanges.length = 0
@cursorsMoved = false
@measureScrollbars() if @measuringScrollbars
@props.parentView.trigger 'editor:display-updated'
observeEditor: ->
@@ -250,6 +259,14 @@ EditorComponent = React.createClass
@subscribe atom.config.observe 'editor.fontSize', @setFontSize
@subscribe atom.config.observe 'editor.showIndentGuide', @setShowIndentGuide
measureScrollbars: ->
@measuringScrollbars = false
{editor} = @props
scrollbarCornerNode = @refs.scrollbarCorner.getDOMNode()
editor.setVerticalScrollbarWidth(scrollbarCornerNode.offsetWidth - scrollbarCornerNode.clientWidth)
editor.setHorizontalScrollbarHeight(scrollbarCornerNode.offsetHeight - scrollbarCornerNode.clientHeight)
setFontSize: (fontSize) ->
@setState({fontSize})
@@ -305,6 +322,16 @@ EditorComponent = React.createClass
event.preventDefault()
onStylesheetsChanged: ->
# Request that scrollbars be re-measured. This hides both scrollbars and
# measures the scrollbar corner.
@measuringScrollbars = true
@requestUpdate()
# Update again now that the scrollbars have been measured. This makes them
# visible again if necessary, and ensures they are the correct width/height.
@requestUpdate()
clearPreservedRowRange: ->
@preservedRowRange = null
@scrollingVertically = false

View File

@@ -12,8 +12,10 @@ ScrollbarComponent = React.createClass
style.display = 'none' unless visible
switch orientation
when 'vertical'
style.width = verticalScrollbarWidth
style.bottom = horizontalScrollbarHeight if scrollableInOppositeDirection
when 'horizontal'
style.height = horizontalScrollbarHeight
style.right = verticalScrollbarWidth if scrollableInOppositeDirection
div {className, style, @onScroll},

View File

@@ -4,7 +4,12 @@ React = require 'react'
module.exports =
ScrollbarComponent = React.createClass
render: ->
{visible, width, height} = @props
{visible, measuringScrollbars, width, height} = @props
if measuringScrollbars
height = 25
width = 25
display = 'none' unless visible
div className: 'scrollbar-corner', style: {display, width, height},