Presenter positions overlays when the overlay doesn’t have a size

Fix presenter specs
This commit is contained in:
Ben Ogle
2015-04-01 14:44:38 -07:00
parent 77139104fd
commit bed09cf0ef
2 changed files with 39 additions and 24 deletions

View File

@@ -29,6 +29,9 @@ describe "TextEditorPresenter", ->
model: editor
explicitHeight: 130
contentFrameWidth: 500
windowWidth: 500
windowHeight: 130
boundingClientRect: {left: 0, top: 0, width: 500, height: 130}
lineHeight: 10
baseCharacterWidth: 10
horizontalScrollbarHeight: 10
@@ -1497,14 +1500,14 @@ describe "TextEditorPresenter", ->
# Initial state
expectValues stateForOverlay(presenter, decoration), {
item: item
pixelPosition: {top: 2 * 10, left: 13 * 10}
pixelPosition: {top: 3 * 10 - presenter.state.content.scrollTop, left: 13 * 10}
}
# Change range
expectStateUpdate presenter, -> marker.setBufferRange([[2, 13], [4, 6]])
expectValues stateForOverlay(presenter, decoration), {
item: item
pixelPosition: {top: 4 * 10, left: 6 * 10}
pixelPosition: {top: 5 * 10 - presenter.state.content.scrollTop, left: 6 * 10}
}
# Valid -> invalid
@@ -1515,14 +1518,14 @@ describe "TextEditorPresenter", ->
expectStateUpdate presenter, -> editor.undo()
expectValues stateForOverlay(presenter, decoration), {
item: item
pixelPosition: {top: 4 * 10, left: 6 * 10}
pixelPosition: {top: 5 * 10 - presenter.state.content.scrollTop, left: 6 * 10}
}
# Reverse direction
expectStateUpdate presenter, -> marker.setBufferRange([[2, 13], [4, 6]], reversed: true)
expectValues stateForOverlay(presenter, decoration), {
item: item
pixelPosition: {top: 2 * 10, left: 13 * 10}
pixelPosition: {top: 3 * 10 - presenter.state.content.scrollTop, left: 13 * 10}
}
# Destroy
@@ -1533,53 +1536,56 @@ describe "TextEditorPresenter", ->
decoration2 = editor.decorateMarker(marker, {type: 'overlay', item})
expectValues stateForOverlay(presenter, decoration2), {
item: item
pixelPosition: {top: 2 * 10, left: 13 * 10}
pixelPosition: {top: 3 * 10 - presenter.state.content.scrollTop, left: 13 * 10}
}
it "updates when ::baseCharacterWidth changes", ->
item = {}
scrollTop = 20
marker = editor.markBufferPosition([2, 13], invalidate: 'touch')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
presenter = buildPresenter(explicitHeight: 30, scrollTop: 20)
presenter = buildPresenter({explicitHeight: 30, scrollTop})
expectValues stateForOverlay(presenter, decoration), {
item: item
pixelPosition: {top: 2 * 10, left: 13 * 10}
pixelPosition: {top: 3 * 10 - scrollTop, left: 13 * 10}
}
expectStateUpdate presenter, -> presenter.setBaseCharacterWidth(5)
expectValues stateForOverlay(presenter, decoration), {
item: item
pixelPosition: {top: 2 * 10, left: 13 * 5}
pixelPosition: {top: 3 * 10 - scrollTop, left: 13 * 5}
}
it "updates when ::lineHeight changes", ->
item = {}
scrollTop = 20
marker = editor.markBufferPosition([2, 13], invalidate: 'touch')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
presenter = buildPresenter(explicitHeight: 30, scrollTop: 20)
presenter = buildPresenter({explicitHeight: 30, scrollTop})
expectValues stateForOverlay(presenter, decoration), {
item: item
pixelPosition: {top: 2 * 10, left: 13 * 10}
pixelPosition: {top: 3 * 10 - scrollTop, left: 13 * 10}
}
expectStateUpdate presenter, -> presenter.setLineHeight(5)
expectValues stateForOverlay(presenter, decoration), {
item: item
pixelPosition: {top: 2 * 5, left: 13 * 10}
pixelPosition: {top: 3 * 5 - scrollTop, left: 13 * 10}
}
it "honors the 'position' option on overlay decorations", ->
item = {}
scrollTop = 20
marker = editor.markBufferRange([[2, 13], [4, 14]], invalidate: 'touch')
decoration = editor.decorateMarker(marker, {type: 'overlay', position: 'tail', item})
presenter = buildPresenter(explicitHeight: 30, scrollTop: 20)
presenter = buildPresenter({explicitHeight: 30, scrollTop})
expectValues stateForOverlay(presenter, decoration), {
item: item
pixelPosition: {top: 2 * 10, left: 13 * 10}
pixelPosition: {top: 3 * 10 - scrollTop, left: 13 * 10}
}
it "is empty until all of the required measurements are assigned", ->
@@ -1587,13 +1593,19 @@ describe "TextEditorPresenter", ->
marker = editor.markBufferRange([[2, 13], [4, 14]], invalidate: 'touch')
decoration = editor.decorateMarker(marker, {type: 'overlay', position: 'tail', item})
presenter = buildPresenter(baseCharacterWidth: null, lineHeight: null)
presenter = buildPresenter(baseCharacterWidth: null, lineHeight: null, windowWidth: null, windowHeight: null, boundingClientRect: null)
expect(presenter.getState().content.overlays).toEqual({})
presenter.setBaseCharacterWidth(10)
expect(presenter.getState().content.overlays).toEqual({})
presenter.setLineHeight(10)
expect(presenter.getState().content.overlays).toEqual({})
presenter.setWindowSize(500, 100)
expect(presenter.getState().content.overlays).toEqual({})
presenter.setBoundingClientRect({top: 0, left: 0, height: 100, width: 500})
expect(presenter.getState().content.overlays).not.toEqual({})
describe ".gutter", ->

View File

@@ -12,7 +12,7 @@ class TextEditorPresenter
overlayDimensions: {}
constructor: (params) ->
{@model, @autoHeight, @explicitHeight, @contentFrameWidth, @scrollTop, @scrollLeft} = params
{@model, @autoHeight, @explicitHeight, @contentFrameWidth, @scrollTop, @scrollLeft, @boundingClientRect, @windowWidth, @windowHeight} = params
{horizontalScrollbarHeight, verticalScrollbarWidth} = params
{@lineHeight, @baseCharacterWidth, @lineOverdrawMargin, @backgroundColor, @gutterBackgroundColor} = params
{@cursorBlinkPeriod, @cursorBlinkResumeDelay, @stoppedScrollingDelay, @focused} = params
@@ -315,7 +315,7 @@ class TextEditorPresenter
@emitDidUpdateState()
updateOverlaysState: -> @batch "shouldUpdateOverlaysState", ->
return unless @hasPixelRectRequirements()
return unless @hasOverlayPositionRequirements()
visibleDecorationIds = {}
@@ -330,14 +330,14 @@ class TextEditorPresenter
pixelPosition = @pixelPositionForScreenPosition(screenPosition)
{scrollTop, scrollLeft} = @state.content
gutterWidth = @boundingClientRect.width - @contentFrameWidth
left = pixelPosition.left - scrollLeft + gutterWidth
top = pixelPosition.top + @lineHeight - scrollTop
if overlayDimensions = @overlayDimensions[decoration.id]
{itemWidth, itemHeight, contentMargin} = overlayDimensions
{scrollTop, scrollLeft} = @state.content
gutterWidth = @boundingClientRect.width - @contentFrameWidth
left = pixelPosition.left - scrollLeft + gutterWidth
top = pixelPosition.top + @lineHeight - scrollTop
rightDiff = left + @boundingClientRect.left + itemWidth + contentMargin - @windowWidth
left -= rightDiff if rightDiff > 0
@@ -348,8 +348,8 @@ class TextEditorPresenter
if top + @boundingClientRect.top + itemHeight > @windowHeight
top -= itemHeight + @lineHeight
pixelPosition.top = top
pixelPosition.left = left
pixelPosition.top = top
pixelPosition.left = left
@state.content.overlays[decoration.id] ?= {item}
@state.content.overlays[decoration.id].pixelPosition = pixelPosition
@@ -824,6 +824,9 @@ class TextEditorPresenter
hasPixelRectRequirements: ->
@hasPixelPositionRequirements() and @scrollWidth?
hasOverlayPositionRequirements: ->
@hasPixelRectRequirements() and @boundingClientRect? and @windowWidth and @windowHeight
pixelRectForScreenRange: (screenRange) ->
if screenRange.end.row > screenRange.start.row
top = @pixelPositionForScreenPosition(screenRange.start).top