Splice LineTopIndex when DisplayBuffer changes

We invalidate whole screen lines accordingly to `DisplayBuffer`, so that we can
catch if there was any screen-only transformation and move block decorations
accordingly.
This commit is contained in:
Antonio Scandurra
2015-12-19 11:21:45 +01:00
parent 8710089cb7
commit 5fa9d3bc40
2 changed files with 101 additions and 50 deletions

View File

@@ -169,38 +169,87 @@ describe "TextEditorPresenter", ->
expect(stateFn(presenter).tiles[12]).toBeUndefined()
it "computes each tile's height and scrollTop based on block decorations' height", ->
presenter = buildPresenter(explicitHeight: 120, scrollTop: 0, lineHeight: 10, tileSize: 2)
describe "when there are block decorations", ->
it "computes each tile's height and scrollTop based on block decorations' height", ->
presenter = buildPresenter(explicitHeight: 120, scrollTop: 0, lineHeight: 10, tileSize: 2)
blockDecoration1 = editor.addBlockDecorationForScreenRow(0)
blockDecoration2 = editor.addBlockDecorationForScreenRow(3)
blockDecoration3 = editor.addBlockDecorationForScreenRow(5)
presenter.setBlockDecorationDimensions(blockDecoration1, 0, 1)
presenter.setBlockDecorationDimensions(blockDecoration2, 0, 30)
presenter.setBlockDecorationDimensions(blockDecoration3, 0, 40)
blockDecoration1 = editor.addBlockDecorationForScreenRow(0)
blockDecoration2 = editor.addBlockDecorationForScreenRow(3)
blockDecoration3 = editor.addBlockDecorationForScreenRow(5)
presenter.setBlockDecorationDimensions(blockDecoration1, 0, 1)
presenter.setBlockDecorationDimensions(blockDecoration2, 0, 30)
presenter.setBlockDecorationDimensions(blockDecoration3, 0, 40)
expect(stateFn(presenter).tiles[0].height).toBe(20 + 1)
expect(stateFn(presenter).tiles[0].top).toBe(0)
expect(stateFn(presenter).tiles[2].height).toBe(20 + 30)
expect(stateFn(presenter).tiles[2].top).toBe(20 + 1)
expect(stateFn(presenter).tiles[4].height).toBe(20 + 40)
expect(stateFn(presenter).tiles[4].top).toBe(20 + 30 + 20 + 1)
expect(stateFn(presenter).tiles[6].height).toBe(20)
expect(stateFn(presenter).tiles[6].top).toBe((20 + 40) + (20 + 30) + 20 + 1)
expect(stateFn(presenter).tiles[8]).toBeUndefined()
expect(stateFn(presenter).tiles[0].height).toBe(20 + 1)
expect(stateFn(presenter).tiles[0].top).toBe(0)
expect(stateFn(presenter).tiles[2].height).toBe(20 + 30)
expect(stateFn(presenter).tiles[2].top).toBe(20 + 1)
expect(stateFn(presenter).tiles[4].height).toBe(20 + 40)
expect(stateFn(presenter).tiles[4].top).toBe(20 + 30 + 20 + 1)
expect(stateFn(presenter).tiles[6].height).toBe(20)
expect(stateFn(presenter).tiles[6].top).toBe((20 + 40) + (20 + 30) + 20 + 1)
expect(stateFn(presenter).tiles[8]).toBeUndefined()
presenter.setScrollTop(21)
presenter.setScrollTop(21)
expect(stateFn(presenter).tiles[0]).toBeUndefined()
expect(stateFn(presenter).tiles[2].height).toBe(20 + 30)
expect(stateFn(presenter).tiles[2].top).toBe(0)
expect(stateFn(presenter).tiles[4].height).toBe(20 + 40)
expect(stateFn(presenter).tiles[4].top).toBe(30 + 20)
expect(stateFn(presenter).tiles[6].height).toBe(20)
expect(stateFn(presenter).tiles[6].top).toBe((20 + 40) + (20 + 30))
expect(stateFn(presenter).tiles[8].height).toBe(20)
expect(stateFn(presenter).tiles[8].top).toBe((20 + 40) + (20 + 30) + 20)
expect(stateFn(presenter).tiles[10]).toBeUndefined()
expect(stateFn(presenter).tiles[0]).toBeUndefined()
expect(stateFn(presenter).tiles[2].height).toBe(20 + 30)
expect(stateFn(presenter).tiles[2].top).toBe(0)
expect(stateFn(presenter).tiles[4].height).toBe(20 + 40)
expect(stateFn(presenter).tiles[4].top).toBe(30 + 20)
expect(stateFn(presenter).tiles[6].height).toBe(20)
expect(stateFn(presenter).tiles[6].top).toBe((20 + 40) + (20 + 30))
expect(stateFn(presenter).tiles[8].height).toBe(20)
expect(stateFn(presenter).tiles[8].top).toBe((20 + 40) + (20 + 30) + 20)
expect(stateFn(presenter).tiles[10]).toBeUndefined()
it "works correctly when soft wrapping is enabled", ->
blockDecoration1 = editor.addBlockDecorationForScreenRow(0, null)
blockDecoration2 = editor.addBlockDecorationForScreenRow(4, null)
blockDecoration3 = editor.addBlockDecorationForScreenRow(8, null)
presenter = buildPresenter(explicitHeight: 330, lineHeight: 10, tileSize: 2, baseCharacterWidth: 5)
presenter.setBlockDecorationDimensions(blockDecoration1, 0, 10)
presenter.setBlockDecorationDimensions(blockDecoration2, 0, 20)
presenter.setBlockDecorationDimensions(blockDecoration3, 0, 30)
expect(stateFn(presenter).tiles[0].top).toBe(0 * 10)
expect(stateFn(presenter).tiles[2].top).toBe(2 * 10 + 10)
expect(stateFn(presenter).tiles[4].top).toBe(4 * 10 + 10)
expect(stateFn(presenter).tiles[6].top).toBe(6 * 10 + 10 + 20)
expect(stateFn(presenter).tiles[8].top).toBe(8 * 10 + 10 + 20)
expect(stateFn(presenter).tiles[10].top).toBe(10 * 10 + 10 + 20 + 30)
expect(stateFn(presenter).tiles[12].top).toBe(12 * 10 + 10 + 20 + 30)
editor.setSoftWrapped(true)
presenter.setContentFrameWidth(5 * 25)
expect(stateFn(presenter).tiles[0].top).toBe(0 * 10)
expect(stateFn(presenter).tiles[2].top).toBe(2 * 10 + 10)
expect(stateFn(presenter).tiles[4].top).toBe(4 * 10 + 10)
expect(stateFn(presenter).tiles[6].top).toBe(6 * 10 + 10)
expect(stateFn(presenter).tiles[8].top).toBe(8 * 10 + 10)
expect(stateFn(presenter).tiles[10].top).toBe(10 * 10 + 10)
expect(stateFn(presenter).tiles[12].top).toBe(12 * 10 + 10 + 20)
expect(stateFn(presenter).tiles[14].top).toBe(14 * 10 + 10 + 20)
expect(stateFn(presenter).tiles[16].top).toBe(16 * 10 + 10 + 20)
expect(stateFn(presenter).tiles[18].top).toBe(18 * 10 + 10 + 20)
expect(stateFn(presenter).tiles[20].top).toBe(20 * 10 + 10 + 20)
expect(stateFn(presenter).tiles[22].top).toBe(22 * 10 + 10 + 20 + 30)
expect(stateFn(presenter).tiles[24].top).toBe(24 * 10 + 10 + 20 + 30)
expect(stateFn(presenter).tiles[26].top).toBe(26 * 10 + 10 + 20 + 30)
expect(stateFn(presenter).tiles[28].top).toBe(28 * 10 + 10 + 20 + 30)
editor.setSoftWrapped(false)
expect(stateFn(presenter).tiles[0].top).toBe(0 * 10)
expect(stateFn(presenter).tiles[2].top).toBe(2 * 10 + 10)
expect(stateFn(presenter).tiles[4].top).toBe(4 * 10 + 10)
expect(stateFn(presenter).tiles[6].top).toBe(6 * 10 + 10 + 20)
expect(stateFn(presenter).tiles[8].top).toBe(8 * 10 + 10 + 20)
expect(stateFn(presenter).tiles[10].top).toBe(10 * 10 + 10 + 20 + 30)
expect(stateFn(presenter).tiles[12].top).toBe(12 * 10 + 10 + 20 + 30)
it "includes state for all tiles if no external ::explicitHeight is assigned", ->
presenter = buildPresenter(explicitHeight: null, tileSize: 2)