From 54fcaa613203c74c8faea04812f5cd00550e548d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 11 Feb 2015 23:01:08 -0700 Subject: [PATCH] Precompute ::scrollHeight and cache ::scrollPastEnd config value --- spec/text-editor-presenter-spec.coffee | 24 ++++++++++---------- src/text-editor-presenter.coffee | 31 ++++++++++++++++---------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index d93e0d13e..7cb081f5b 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -278,16 +278,16 @@ describe "TextEditorPresenter", -> it "never exceeds the computed scrollHeight minus the computed clientHeight", -> presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10) expectStateUpdate presenter, -> presenter.setScrollTop(100) - expect(presenter.state.verticalScrollbar.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> presenter.setExplicitHeight(60) - expect(presenter.state.verticalScrollbar.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> presenter.setHorizontalScrollbarHeight(5) - expect(presenter.state.verticalScrollbar.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> editor.getBuffer().delete([[8, 0], [12, 0]]) - expect(presenter.state.verticalScrollbar.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight # Scroll top only gets smaller when needed as dimensions change, never bigger scrollTopBefore = presenter.state.verticalScrollbar.scrollTop @@ -425,16 +425,16 @@ describe "TextEditorPresenter", -> it "never exceeds the computed scroll height minus the computed client height", -> presenter = buildPresenter(scrollTop: 10, lineHeight: 10, explicitHeight: 50, horizontalScrollbarHeight: 10) expectStateUpdate presenter, -> presenter.setScrollTop(100) - expect(presenter.state.content.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> presenter.setExplicitHeight(60) - expect(presenter.state.content.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> presenter.setHorizontalScrollbarHeight(5) - expect(presenter.state.content.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> editor.getBuffer().delete([[8, 0], [12, 0]]) - expect(presenter.state.content.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight # Scroll top only gets smaller when needed as dimensions change, never bigger scrollTopBefore = presenter.state.verticalScrollbar.scrollTop @@ -1542,16 +1542,16 @@ describe "TextEditorPresenter", -> it "never exceeds the computed scrollHeight minus the computed clientHeight", -> presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10) expectStateUpdate presenter, -> presenter.setScrollTop(100) - expect(presenter.state.gutter.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.gutter.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> presenter.setExplicitHeight(60) - expect(presenter.state.gutter.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.gutter.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> presenter.setHorizontalScrollbarHeight(5) - expect(presenter.state.gutter.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.gutter.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> editor.getBuffer().delete([[8, 0], [12, 0]]) - expect(presenter.state.gutter.scrollTop).toBe presenter.computeScrollHeight() - presenter.clientHeight + expect(presenter.state.gutter.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight # Scroll top only gets smaller when needed as dimensions change, never bigger scrollTopBefore = presenter.state.verticalScrollbar.scrollTop diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 3088fcaca..55d0928f9 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -72,8 +72,12 @@ class TextEditorPresenter @observeCursor(cursor) for cursor in @model.getCursors() observeConfig: -> + @scrollPastEnd = atom.config.get('editor.scrollPastEnd') + @disposables.add atom.config.onDidChange 'editor.showIndentGuide', scope: @model.getRootScopeDescriptor(), @updateContentState.bind(this) - @disposables.add atom.config.onDidChange 'editor.scrollPastEnd', scope: @model.getRootScopeDescriptor(), => + @disposables.add atom.config.onDidChange 'editor.scrollPastEnd', scope: @model.getRootScopeDescriptor(), ({newValue}) => + @scrollPastEnd = newValue + @updateScrollHeight() @updateVerticalScrollState() @updateScrollbarsState() @@ -118,10 +122,9 @@ class TextEditorPresenter @emitter.emit 'did-update-state' updateVerticalScrollState: -> - scrollHeight = @computeScrollHeight() - @state.content.scrollHeight = scrollHeight - @state.gutter.scrollHeight = scrollHeight - @state.verticalScrollbar.scrollHeight = scrollHeight + @state.content.scrollHeight = @scrollHeight + @state.gutter.scrollHeight = @scrollHeight + @state.verticalScrollbar.scrollHeight = @scrollHeight scrollTop = @computeScrollTop() @state.content.scrollTop = scrollTop @@ -352,12 +355,12 @@ class TextEditorPresenter updateScrollWidth: -> @scrollWidth = Math.max(@contentWidth, @clientWidth) - computeScrollHeight: -> + updateScrollHeight: -> contentHeight = @contentHeight - if atom.config.get('editor.scrollPastEnd') + if @scrollPastEnd extraScrollHeight = @clientHeight - (@lineHeight * 3) contentHeight += extraScrollHeight if extraScrollHeight > 0 - Math.max(contentHeight, @height) + @scrollHeight = Math.max(contentHeight, @height) updateContentWidth: -> contentWidth = @pixelPositionForScreenPosition([@model.getLongestScreenRow(), Infinity]).left @@ -373,9 +376,13 @@ class TextEditorPresenter @contentHeight = contentHeight @updateHeight() @updateScrollbarDimensions() + @updateScrollHeight() updateClientHeight: -> - @clientHeight = @height - @horizontalScrollbarHeight + clientHeight = @height - @horizontalScrollbarHeight + unless @clientHeight is clientHeight + @clientHeight = clientHeight + @updateScrollHeight() updateClientWidth: -> clientWidth = @contentFrameWidth - @verticalScrollbarWidth @@ -388,7 +395,7 @@ class TextEditorPresenter constrainScrollTop: (scrollTop) -> if @hasRequiredMeasurements() - Math.max(0, Math.min(scrollTop, @computeScrollHeight() - @clientHeight)) + Math.max(0, Math.min(scrollTop, @scrollHeight - @clientHeight)) else Math.max(0, scrollTop) if scrollTop? @@ -548,6 +555,7 @@ class TextEditorPresenter @height = height @updateScrollbarDimensions() @updateClientHeight() + @updateScrollHeight() setContentFrameWidth: (contentFrameWidth) -> unless @contentFrameWidth is contentFrameWidth @@ -579,9 +587,8 @@ class TextEditorPresenter unless @lineHeight is lineHeight @lineHeight = lineHeight @model.setLineHeightInPixels(lineHeight) - @updateContentHeight() - + @updateScrollHeight() @updateHeightState() @updateVerticalScrollState() @updateDecorations()