Allow scrollPastEnd to be set from the editor

This commit is contained in:
Antonio Scandurra
2016-06-30 15:05:21 +02:00
parent 7beafa2da6
commit c769b169aa
6 changed files with 60 additions and 29 deletions

View File

@@ -647,17 +647,6 @@ describe "TextEditorPresenter", ->
expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false)
expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight
it "doesn't add the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true but the presenter is created with scrollPastEnd as false", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10, scrollPastEnd: false)
expectStateUpdate presenter, -> presenter.setScrollTop(300)
expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight
expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", true)
expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight
expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false)
expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight
describe ".scrollTop", ->
it "tracks the value of ::scrollTop", ->
presenter = buildPresenter(scrollTop: 10, explicitHeight: 20, horizontalScrollbarHeight: 10)

View File

@@ -5689,6 +5689,40 @@ describe "TextEditor", ->
editor.selectPageUp()
expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [12, 2]]]
describe "scroll past end", ->
it "returns the scrollPastEnd setting on the editor instance if set, or 'editor.scrollPastEnd' otherwise", ->
atom.config.set('editor.scrollPastEnd', true)
expect(editor.getScrollPastEnd()).toBe(true)
atom.config.set('editor.scrollPastEnd', false)
expect(editor.getScrollPastEnd()).toBe(false)
editor.setScrollPastEnd(true)
expect(editor.getScrollPastEnd()).toBe(true)
atom.config.set('editor.scrollPastEnd', true)
atom.config.set('editor.scrollPastEnd', false)
expect(editor.getScrollPastEnd()).toBe(true)
it "emits a onDidChangeScrollPastEnd event when it changes", ->
scrollPastEndSpy = jasmine.createSpy('onDidChangeScrollPastEnd')
editor.onDidChangeScrollPastEnd(scrollPastEndSpy)
atom.config.set('editor.scrollPastEnd', true)
expect(scrollPastEndSpy).toHaveBeenCalled()
scrollPastEndSpy.reset()
editor.setScrollPastEnd(false)
expect(scrollPastEndSpy).toHaveBeenCalled()
scrollPastEndSpy.reset()
editor.setScrollPastEnd(false)
expect(scrollPastEndSpy).not.toHaveBeenCalled()
atom.config.set('editor.scrollPastEnd', false)
atom.config.set('editor.scrollPastEnd', true)
expect(scrollPastEndSpy).not.toHaveBeenCalled()
describe "::setFirstVisibleScreenRow() and ::getFirstVisibleScreenRow()", ->
beforeEach ->
line = Array(9).join('0123456789')

View File

@@ -43,7 +43,7 @@ class TextEditorComponent
@assert domNode?, "TextEditorComponent::domNode was set to null."
@domNodeValue = domNode
constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize, @views, @themes, @config, @workspace, @assert, @grammars, scrollPastEnd}) ->
constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize, @views, @themes, @config, @workspace, @assert, @grammars}) ->
@tileSize = tileSize if tileSize?
@disposables = new CompositeDisposable
@@ -61,7 +61,6 @@ class TextEditorComponent
stoppedScrollingDelay: 200
config: @config
lineTopIndex: lineTopIndex
scrollPastEnd: scrollPastEnd
@presenter.onDidUpdateState(@requestUpdate)

View File

@@ -17,7 +17,6 @@ class TextEditorElement extends HTMLElement
focusOnAttach: false
hasTiledRendering: true
logicalDisplayBuffer: true
scrollPastEnd: true
autoHeight: true
createdCallback: ->
@@ -91,7 +90,7 @@ class TextEditorElement extends HTMLElement
@subscriptions.add @component.onDidChangeScrollLeft =>
@emitter.emit("did-change-scroll-left", arguments...)
initialize: (model, {@views, @config, @themes, @workspace, @assert, @styles, @grammars}, @autoHeight = true, @scrollPastEnd = true) ->
initialize: (model, {@views, @config, @themes, @workspace, @assert, @styles, @grammars}, @autoHeight = true) ->
throw new Error("Must pass a views parameter when initializing TextEditorElements") unless @views?
throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @config?
throw new Error("Must pass a themes parameter when initializing TextEditorElements") unless @themes?
@@ -148,7 +147,6 @@ class TextEditorElement extends HTMLElement
workspace: @workspace
assert: @assert
grammars: @grammars
scrollPastEnd: @scrollPastEnd
)
@rootElement.appendChild(@component.getDomNode())

View File

@@ -13,7 +13,7 @@ class TextEditorPresenter
minimumReflowInterval: 200
constructor: (params) ->
{@model, @config, @lineTopIndex, scrollPastEnd} = params
{@model, @config, @lineTopIndex} = params
{@cursorBlinkPeriod, @cursorBlinkResumeDelay, @stoppedScrollingDelay, @tileSize} = params
{@contentFrameWidth} = params
{@displayLayer} = @model
@@ -44,8 +44,6 @@ class TextEditorPresenter
@startReflowing() if @continuousReflow
@updating = false
@scrollPastEndOverride = scrollPastEnd ? true
setLinesYardstick: (@linesYardstick) ->
getLinesYardstick: -> @linesYardstick
@@ -160,6 +158,9 @@ class TextEditorPresenter
@disposables.add @model.onDidChangeMini =>
@shouldUpdateDecorations = true
@emitDidUpdateState()
@disposables.add @model.onDidChangeScrollPastEnd =>
@updateScrollHeight()
@emitDidUpdateState()
@disposables.add @model.onDidChangeLineNumberGutterVisible(@emitDidUpdateState.bind(this))
@@ -173,7 +174,6 @@ class TextEditorPresenter
observeConfig: ->
configParams = {scope: @model.getRootScopeDescriptor()}
@scrollPastEnd = @config.get('editor.scrollPastEnd', configParams)
@showLineNumbers = @config.get('editor.showLineNumbers', configParams)
if @configDisposables?
@@ -183,11 +183,6 @@ class TextEditorPresenter
@configDisposables = new CompositeDisposable
@disposables.add(@configDisposables)
@configDisposables.add @config.onDidChange 'editor.scrollPastEnd', configParams, ({newValue}) =>
@scrollPastEnd = newValue
@updateScrollHeight()
@emitDidUpdateState()
@configDisposables.add @config.onDidChange 'editor.showLineNumbers', configParams, ({newValue}) =>
@showLineNumbers = newValue
@emitDidUpdateState()
@@ -651,7 +646,7 @@ class TextEditorPresenter
return unless @contentHeight? and @clientHeight?
contentHeight = @contentHeight
if @scrollPastEnd and @scrollPastEndOverride
if @model.getScrollPastEnd()
extraScrollHeight = @clientHeight - (@lineHeight * 3)
contentHeight += extraScrollHeight if extraScrollHeight > 0
scrollHeight = Math.max(contentHeight, @height)

View File

@@ -142,7 +142,6 @@ class TextEditor extends Model
@cursorsByMarkerId = new Map
@selections = []
@autoHeight ?= true
@scrollPastEnd ?= true
@hasTerminatedPendingState = false
@showInvisibles ?= true
@@ -283,6 +282,9 @@ class TextEditor extends Model
subscriptions.add @config.onDidChange 'editor.softWrapHangingIndent', scope: scopeDescriptor, @resetDisplayLayer.bind(this)
subscriptions.add @config.onDidChange 'editor.softWrapAtPreferredLineLength', scope: scopeDescriptor, @resetDisplayLayer.bind(this)
subscriptions.add @config.onDidChange 'editor.preferredLineLength', scope: scopeDescriptor, @resetDisplayLayer.bind(this)
subscriptions.add @config.onDidChange 'editor.scrollPastEnd', scope: scopeDescriptor, =>
unless @scrollPastEnd?
@emitter.emit('did-change-scroll-past-end')
@resetDisplayLayer()
@@ -3320,6 +3322,20 @@ class TextEditor extends Model
scrollEvent = {screenRange, options}
@emitter.emit "did-request-autoscroll", scrollEvent
getScrollPastEnd: ->
if @scrollPastEnd?
@scrollPastEnd
else
@config.get('editor.scrollPastEnd', scope: @getRootScopeDescriptor())
setScrollPastEnd: (scrollPastEnd) ->
if scrollPastEnd isnt @scrollPastEnd
@scrollPastEnd = scrollPastEnd
@emitter.emit('did-change-scroll-past-end')
onDidChangeScrollPastEnd: (callback) ->
@emitter.on('did-change-scroll-past-end', callback)
getHorizontalScrollbarHeight: ->
Grim.deprecate("This is now a view method. Call TextEditorElement::getHorizontalScrollbarHeight instead.")
@@ -3376,7 +3392,7 @@ class TextEditor extends Model
# Get the Element for the editor.
getElement: ->
@editorElement ?= new TextEditorElement().initialize(this, atom, @autoHeight, @scrollPastEnd)
@editorElement ?= new TextEditorElement().initialize(this, atom, @autoHeight)
# Essential: Retrieves the greyed out placeholder of a mini editor.
#
@@ -3470,7 +3486,7 @@ class TextEditor extends Model
setFirstVisibleScreenRow: (screenRow, fromView) ->
unless fromView
maxScreenRow = @getScreenLineCount() - 1
unless @config.get('editor.scrollPastEnd') and @scrollPastEnd
unless @getScrollPastEnd()
if @height? and @lineHeightInPixels?
maxScreenRow -= Math.floor(@height / @lineHeightInPixels)
screenRow = Math.max(Math.min(screenRow, maxScreenRow), 0)