From babbdbf9e5ec9f0f665b132d9c5203ff620bcdf6 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 23 Apr 2014 13:57:49 -0600 Subject: [PATCH] Don't obscure the last line of the editor with the horizontal scrollbar This assumes the scrollbar is 15px high, which is incorrect when using overlay scrollbars or when the scrollbar is styled to have a different height. We'll need to measure it in a subsequent commit. --- spec/editor-component-spec.coffee | 21 ++++++++++++++++++++- src/display-buffer.coffee | 17 ++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/spec/editor-component-spec.coffee b/spec/editor-component-spec.coffee index 7ae9765eb..94aa9c1e7 100644 --- a/spec/editor-component-spec.coffee +++ b/spec/editor-component-spec.coffee @@ -1,4 +1,4 @@ -{extend, flatten, toArray} = require 'underscore-plus' +{extend, flatten, toArray, last} = require 'underscore-plus' ReactEditorView = require '../src/react-editor-view' nbsp = String.fromCharCode(160) @@ -526,6 +526,25 @@ describe "EditorComponent", -> expect(editor.getScrollLeft()).toBe 100 + it "does not obscure the last line with the horizontal scrollbar", -> + node.style.height = 4.5 * lineHeightInPixels + 'px' + node.style.width = 10 * charWidth + 'px' + component.measureHeightAndWidth() + editor.setScrollBottom(editor.getScrollHeight()) + lastLineNode = last(node.querySelectorAll('.line')) + bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom + topOfHorizontalScrollbar = horizontalScrollbarNode.getBoundingClientRect().top + expect(bottomOfLastLine).toBe topOfHorizontalScrollbar + + # Render no space below the last line when there's no horizontal scrollbar + node.style.width = 100 * charWidth + 'px' + component.measureHeightAndWidth() + editor.setScrollBottom(editor.getScrollHeight()) + lastLineNode = last(node.querySelectorAll('.line')) + bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom + bottomOfEditor = node.getBoundingClientRect().bottom + expect(bottomOfLastLine).toBe bottomOfEditor + 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' diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index f590920c6..a9c4e3ca4 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -114,6 +114,17 @@ class DisplayBuffer extends Model getHeight: -> @height ? @getScrollHeight() setHeight: (@height) -> @height + getClientHeight: -> + if @horizontallyScrollable() + @getHeight() - @getHorizontalScrollbarHeight() + else + @getHeight() + + horizontallyScrollable: -> + not @getSoftWrap() and @getScrollWidth() > @getWidth() + + getHorizontalScrollbarHeight: -> 15 + getWidth: -> @width ? @getScrollWidth() setWidth: (newWidth) -> oldWidth = @width @@ -124,13 +135,13 @@ class DisplayBuffer extends Model getScrollTop: -> @scrollTop setScrollTop: (scrollTop) -> if @manageScrollPosition - @scrollTop = Math.max(0, Math.min(@getScrollHeight() - @getHeight(), scrollTop)) + @scrollTop = Math.max(0, Math.min(@getScrollHeight() - @getClientHeight(), scrollTop)) else @scrollTop = scrollTop getScrollBottom: -> @scrollTop + @height setScrollBottom: (scrollBottom) -> - @setScrollTop(scrollBottom - @height) + @setScrollTop(scrollBottom - @getClientHeight()) @getScrollBottom() getScrollLeft: -> @scrollLeft @@ -184,7 +195,7 @@ class DisplayBuffer extends Model unless @getLineHeight() > 0 throw new Error("You must assign a non-zero lineHeight before calling ::getVisibleRowRange()") - heightInLines = Math.ceil(@getHeight() / @getLineHeight()) + 1 + heightInLines = Math.ceil(@getClientHeight() / @getLineHeight()) + 1 startRow = Math.floor(@getScrollTop() / @getLineHeight()) endRow = Math.min(@getLineCount(), Math.ceil(startRow + heightInLines)) [startRow, endRow]