mirror of
https://github.com/atom/atom.git
synced 2026-01-24 06:18:03 -05:00
Pass view measurements to model via presenter
Someday, we won’t need to pass measurements to the model anymore.
This commit is contained in:
@@ -137,7 +137,7 @@ describe "TextEditorPresenter", ->
|
||||
expect(presenter.state.horizontalScrollbar.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide
|
||||
|
||||
it "updates when ::softWrapped changes on the editor", ->
|
||||
presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10)
|
||||
presenter = buildPresenter(contentFrameWidth: 470, baseCharacterWidth: 10)
|
||||
expect(presenter.state.horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1
|
||||
expectStateUpdate presenter, -> editor.setSoftWrapped(true)
|
||||
expect(presenter.state.horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength()
|
||||
@@ -180,6 +180,11 @@ describe "TextEditorPresenter", ->
|
||||
expectStateUpdate presenter, -> editor.getBuffer().insert([6, 0], new Array(100).join('x'))
|
||||
expect(presenter.state.horizontalScrollbar.scrollLeft).toBe scrollLeftBefore
|
||||
|
||||
it "never goes negative", ->
|
||||
presenter = buildPresenter(scrollLeft: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500)
|
||||
expectStateUpdate presenter, -> presenter.setScrollLeft(-300)
|
||||
expect(presenter.state.horizontalScrollbar.scrollLeft).toBe 0
|
||||
|
||||
describe ".verticalScrollbar", ->
|
||||
describe ".visible", ->
|
||||
it "is true if the scrollHeight exceeds the computed client height", ->
|
||||
@@ -278,6 +283,11 @@ describe "TextEditorPresenter", ->
|
||||
expectStateUpdate presenter, -> editor.getBuffer().insert([9, Infinity], '\n\n\n')
|
||||
expect(presenter.state.verticalScrollbar.scrollTop).toBe scrollTopBefore
|
||||
|
||||
it "never goes negative", ->
|
||||
presenter = buildPresenter(scrollTop: 10, height: 50, horizontalScrollbarHeight: 10)
|
||||
expectStateUpdate presenter, -> presenter.setScrollTop(-100)
|
||||
expect(presenter.state.verticalScrollbar.scrollTop).toBe 0
|
||||
|
||||
describe ".content", ->
|
||||
describe ".scrollingVertically", ->
|
||||
it "is true for ::stoppedScrollingDelay milliseconds following a changes to ::scrollTop", ->
|
||||
@@ -354,7 +364,7 @@ describe "TextEditorPresenter", ->
|
||||
expect(presenter.state.content.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide
|
||||
|
||||
it "updates when ::softWrapped changes on the editor", ->
|
||||
presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10)
|
||||
presenter = buildPresenter(contentFrameWidth: 470, baseCharacterWidth: 10)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1
|
||||
expectStateUpdate presenter, -> editor.setSoftWrapped(true)
|
||||
expect(presenter.state.content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength()
|
||||
@@ -397,6 +407,12 @@ describe "TextEditorPresenter", ->
|
||||
expectStateUpdate presenter, -> editor.getBuffer().insert([9, Infinity], '\n\n\n')
|
||||
expect(presenter.state.content.scrollTop).toBe scrollTopBefore
|
||||
|
||||
it "never goes negative", ->
|
||||
presenter = buildPresenter(scrollTop: 10, height: 50, horizontalScrollbarHeight: 10)
|
||||
expectStateUpdate presenter, -> presenter.setScrollTop(-100)
|
||||
expect(presenter.state.content.scrollTop).toBe 0
|
||||
|
||||
describe ".scrollLeft", ->
|
||||
it "tracks the value of ::scrollLeft", ->
|
||||
presenter = buildPresenter(scrollLeft: 10, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500)
|
||||
expect(presenter.state.content.scrollLeft).toBe 10
|
||||
@@ -422,6 +438,11 @@ describe "TextEditorPresenter", ->
|
||||
expectStateUpdate presenter, -> editor.getBuffer().insert([6, 0], new Array(100).join('x'))
|
||||
expect(presenter.state.content.scrollLeft).toBe scrollLeftBefore
|
||||
|
||||
it "never goes negative", ->
|
||||
presenter = buildPresenter(scrollLeft: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500)
|
||||
expectStateUpdate presenter, -> presenter.setScrollLeft(-300)
|
||||
expect(presenter.state.content.scrollLeft).toBe 0
|
||||
|
||||
describe ".indentGuidesVisible", ->
|
||||
it "is initialized based on the editor.showIndentGuide config setting", ->
|
||||
presenter = buildPresenter()
|
||||
@@ -1477,6 +1498,11 @@ describe "TextEditorPresenter", ->
|
||||
expectStateUpdate presenter, -> editor.getBuffer().insert([9, Infinity], '\n\n\n')
|
||||
expect(presenter.state.gutter.scrollTop).toBe scrollTopBefore
|
||||
|
||||
it "never goes negative", ->
|
||||
presenter = buildPresenter(scrollTop: 10, height: 50, horizontalScrollbarHeight: 10)
|
||||
expectStateUpdate presenter, -> presenter.setScrollTop(-100)
|
||||
expect(presenter.state.gutter.scrollTop).toBe 0
|
||||
|
||||
describe ".backgroundColor", ->
|
||||
it "is assigned to ::gutterBackgroundColor if present, and to ::backgroundColor otherwise", ->
|
||||
presenter = buildPresenter(backgroundColor: "rgba(255, 0, 0, 0)", gutterBackgroundColor: "rgba(0, 255, 0, 0)")
|
||||
|
||||
@@ -230,8 +230,6 @@ TextEditorComponent = React.createClass
|
||||
@subscribe editor.observeGrammar(@onGrammarChanged)
|
||||
@subscribe editor.observeCursors(@onCursorAdded)
|
||||
@subscribe editor.observeSelections(@onSelectionAdded)
|
||||
@subscribe editor.$scrollTop.changes, @onScrollTopChanged
|
||||
@subscribe editor.$scrollLeft.changes, @onScrollLeftChanged
|
||||
@subscribe editor.$verticalScrollbarWidth.changes, @requestUpdate
|
||||
@subscribe editor.$horizontalScrollbarHeight.changes, @requestUpdate
|
||||
@subscribe editor.$height.changes, @requestUpdate
|
||||
@@ -356,7 +354,6 @@ TextEditorComponent = React.createClass
|
||||
pendingScrollTop = @pendingScrollTop
|
||||
@pendingScrollTop = null
|
||||
@presenter.setScrollTop(pendingScrollTop)
|
||||
@props.editor.setScrollTop(pendingScrollTop)
|
||||
|
||||
onHorizontalScroll: (scrollLeft) ->
|
||||
{editor} = @props
|
||||
@@ -367,7 +364,6 @@ TextEditorComponent = React.createClass
|
||||
@pendingScrollLeft = scrollLeft
|
||||
unless animationFramePending
|
||||
@requestAnimationFrame =>
|
||||
@props.editor.setScrollLeft(@pendingScrollLeft)
|
||||
@presenter.setScrollLeft(@pendingScrollLeft)
|
||||
@pendingScrollLeft = null
|
||||
|
||||
@@ -389,13 +385,13 @@ TextEditorComponent = React.createClass
|
||||
if Math.abs(wheelDeltaX) > Math.abs(wheelDeltaY)
|
||||
# Scrolling horizontally
|
||||
previousScrollLeft = editor.getScrollLeft()
|
||||
editor.setScrollLeft(previousScrollLeft - Math.round(wheelDeltaX * @scrollSensitivity))
|
||||
@presenter.setScrollLeft(previousScrollLeft - Math.round(wheelDeltaX * @scrollSensitivity))
|
||||
event.preventDefault() unless previousScrollLeft is editor.getScrollLeft()
|
||||
else
|
||||
# Scrolling vertically
|
||||
@presenter.setMouseWheelScreenRow(@screenRowForNode(event.target))
|
||||
previousScrollTop = editor.getScrollTop()
|
||||
editor.setScrollTop(previousScrollTop - Math.round(wheelDeltaY * @scrollSensitivity))
|
||||
previousScrollTop = @presenter.scrollTop
|
||||
@presenter.setScrollTop(previousScrollTop - Math.round(wheelDeltaY * @scrollSensitivity))
|
||||
event.preventDefault() unless previousScrollTop is editor.getScrollTop()
|
||||
|
||||
onScrollViewScroll: ->
|
||||
@@ -550,24 +546,6 @@ TextEditorComponent = React.createClass
|
||||
@selectionChanged = true
|
||||
@requestUpdate()
|
||||
|
||||
onScrollTopChanged: ->
|
||||
@presenter.setScrollTop(@props.editor.getScrollTop())
|
||||
@requestUpdate()
|
||||
@onStoppedScrollingAfterDelay ?= debounce(@onStoppedScrolling, 200)
|
||||
@onStoppedScrollingAfterDelay()
|
||||
|
||||
onScrollLeftChanged: ->
|
||||
@presenter.setScrollLeft(@props.editor.getScrollLeft())
|
||||
@requestUpdate()
|
||||
|
||||
onStoppedScrolling: ->
|
||||
return unless @isMounted()
|
||||
|
||||
@mouseWheelScreenRow = null
|
||||
@requestUpdate()
|
||||
|
||||
onStoppedScrollingAfterDelay: null # created lazily
|
||||
|
||||
onCursorAdded: (cursor) ->
|
||||
@subscribe cursor.onDidChangePosition @onCursorMoved
|
||||
|
||||
@@ -675,18 +653,15 @@ TextEditorComponent = React.createClass
|
||||
height = hostElement.offsetHeight
|
||||
if height > 0
|
||||
@presenter.setHeight(height)
|
||||
editor.setHeight(height)
|
||||
else
|
||||
@presenter.setAutoHeight(true)
|
||||
@presenter.setHeight(null)
|
||||
editor.setHeight(null)
|
||||
|
||||
clientWidth = scrollViewNode.clientWidth
|
||||
paddingLeft = parseInt(getComputedStyle(scrollViewNode).paddingLeft)
|
||||
clientWidth -= paddingLeft
|
||||
if clientWidth > 0
|
||||
@presenter.setContentFrameWidth(clientWidth)
|
||||
editor.setWidth(clientWidth)
|
||||
|
||||
sampleFontStyling: ->
|
||||
oldFontSize = @fontSize
|
||||
@@ -737,9 +712,7 @@ TextEditorComponent = React.createClass
|
||||
width = (cornerNode.offsetWidth - cornerNode.clientWidth) or 15
|
||||
height = (cornerNode.offsetHeight - cornerNode.clientHeight) or 15
|
||||
|
||||
editor.setVerticalScrollbarWidth(width)
|
||||
@presenter.setVerticalScrollbarWidth(width)
|
||||
editor.setHorizontalScrollbarHeight(height)
|
||||
@presenter.setHorizontalScrollbarHeight(height)
|
||||
|
||||
cornerNode.style.display = originalDisplayValue
|
||||
|
||||
@@ -18,6 +18,7 @@ class TextEditorPresenter
|
||||
@disposables = new CompositeDisposable
|
||||
@emitter = new Emitter
|
||||
@charWidthsByScope = {}
|
||||
@transferMeasurementsToModel()
|
||||
@observeModel()
|
||||
@observeConfig()
|
||||
@buildState()
|
||||
@@ -29,6 +30,16 @@ class TextEditorPresenter
|
||||
onDidUpdateState: (callback) ->
|
||||
@emitter.on 'did-update-state', callback
|
||||
|
||||
transferMeasurementsToModel: ->
|
||||
@model.setHeight(@height) if @height?
|
||||
@model.setWidth(@contentFrameWidth) if @contentFrameWidth?
|
||||
@model.setLineHeightInPixels(@lineHeight) if @lineHeight?
|
||||
@model.setDefaultCharWidth(@baseCharacterWidth) if @baseCharacterWidth?
|
||||
@model.setScrollTop(@scrollTop) if @scrollTop?
|
||||
@model.setScrollLeft(@scrollLeft) if @scrollLeft?
|
||||
@model.setVerticalScrollbarWidth(@verticalScrollbarWidth) if @verticalScrollbarWidth?
|
||||
@model.setHorizontalScrollbarHeight(@horizontalScrollbarHeight) if @horizontalScrollbarHeight?
|
||||
|
||||
observeModel: ->
|
||||
@disposables.add @model.onDidChange =>
|
||||
@updateHeightState()
|
||||
@@ -49,6 +60,8 @@ class TextEditorPresenter
|
||||
@updateLineNumbersState()
|
||||
@disposables.add @model.onDidAddDecoration(@didAddDecoration.bind(this))
|
||||
@disposables.add @model.onDidAddCursor(@didAddCursor.bind(this))
|
||||
@disposables.add @model.onDidChangeScrollTop(@setScrollTop.bind(this))
|
||||
@disposables.add @model.onDidChangeScrollLeft(@setScrollLeft.bind(this))
|
||||
@observeDecoration(decoration) for decoration in @model.getDecorations()
|
||||
@observeCursor(cursor) for cursor in @model.getCursors()
|
||||
|
||||
@@ -346,16 +359,22 @@ class TextEditorPresenter
|
||||
@contentFrameWidth - @computeVerticalScrollbarWidth()
|
||||
|
||||
computeScrollTop: ->
|
||||
@scrollTop = @constrainScrollTop(@scrollTop)
|
||||
|
||||
constrainScrollTop: (scrollTop) ->
|
||||
if @hasRequiredMeasurements()
|
||||
@scrollTop = Math.min(@scrollTop, @computeScrollHeight() - @computeClientHeight())
|
||||
Math.max(0, Math.min(scrollTop, @computeScrollHeight() - @computeClientHeight()))
|
||||
else
|
||||
@scrollTop
|
||||
Math.max(0, scrollTop) if scrollTop?
|
||||
|
||||
computeScrollLeft: ->
|
||||
@scrollLeft = @constrainScrollLeft(@scrollLeft)
|
||||
|
||||
constrainScrollLeft: (scrollLeft) ->
|
||||
if @hasRequiredMeasurements()
|
||||
@scrollLeft = Math.min(@scrollLeft, @computeScrollWidth() - @computeClientWidth())
|
||||
Math.max(0, Math.min(scrollLeft, @computeScrollWidth() - @computeClientWidth()))
|
||||
else
|
||||
@scrollLeft
|
||||
Math.max(0, scrollLeft) if scrollLeft?
|
||||
|
||||
computeHorizontalScrollbarHeight: ->
|
||||
contentWidth = @computeContentWidth()
|
||||
@@ -423,8 +442,10 @@ class TextEditorPresenter
|
||||
@horizontalScrollbarHeight?
|
||||
|
||||
setScrollTop: (scrollTop) ->
|
||||
scrollTop = @constrainScrollTop(scrollTop)
|
||||
unless @scrollTop is scrollTop
|
||||
@scrollTop = scrollTop
|
||||
@model.setScrollTop(scrollTop)
|
||||
@didStartScrolling()
|
||||
@updateVerticalScrollState()
|
||||
@updateDecorations()
|
||||
@@ -450,19 +471,23 @@ class TextEditorPresenter
|
||||
@emitter.emit 'did-update-state'
|
||||
|
||||
setScrollLeft: (scrollLeft) ->
|
||||
scrollLeft = @constrainScrollLeft(scrollLeft)
|
||||
unless @scrollLeft is scrollLeft
|
||||
@scrollLeft = scrollLeft
|
||||
@model.setScrollLeft(scrollLeft)
|
||||
@updateHorizontalScrollState()
|
||||
|
||||
setHorizontalScrollbarHeight: (horizontalScrollbarHeight) ->
|
||||
unless @horizontalScrollbarHeight is horizontalScrollbarHeight
|
||||
@horizontalScrollbarHeight = horizontalScrollbarHeight
|
||||
@model.setHorizontalScrollbarHeight(horizontalScrollbarHeight)
|
||||
@updateScrollbarsState()
|
||||
@updateVerticalScrollState()
|
||||
|
||||
setVerticalScrollbarWidth: (verticalScrollbarWidth) ->
|
||||
unless @verticalScrollbarWidth is verticalScrollbarWidth
|
||||
@verticalScrollbarWidth = verticalScrollbarWidth
|
||||
@model.setVerticalScrollbarWidth(verticalScrollbarWidth)
|
||||
@updateScrollbarsState()
|
||||
@updateHorizontalScrollState()
|
||||
|
||||
@@ -474,6 +499,7 @@ class TextEditorPresenter
|
||||
setHeight: (height) ->
|
||||
unless @height is height
|
||||
@height = height
|
||||
@model.setHeight(height)
|
||||
@updateVerticalScrollState()
|
||||
@updateScrollbarsState()
|
||||
@updateDecorations()
|
||||
@@ -487,6 +513,7 @@ class TextEditorPresenter
|
||||
setContentFrameWidth: (contentFrameWidth) ->
|
||||
unless @contentFrameWidth is contentFrameWidth
|
||||
@contentFrameWidth = contentFrameWidth
|
||||
@model.setWidth(contentFrameWidth)
|
||||
@updateVerticalScrollState()
|
||||
@updateHorizontalScrollState()
|
||||
@updateScrollbarsState()
|
||||
@@ -523,6 +550,7 @@ class TextEditorPresenter
|
||||
setBaseCharacterWidth: (baseCharacterWidth) ->
|
||||
unless @baseCharacterWidth is baseCharacterWidth
|
||||
@baseCharacterWidth = baseCharacterWidth
|
||||
@model.setDefaultCharWidth(baseCharacterWidth)
|
||||
@characterWidthsChanged()
|
||||
|
||||
getScopedCharWidth: (scopeNames, char) ->
|
||||
|
||||
Reference in New Issue
Block a user