mirror of
https://github.com/atom/atom.git
synced 2026-01-26 15:28:27 -05:00
Render only visible and yet-to-be-measured block decorations
This commit is contained in:
@@ -2129,62 +2129,61 @@ describe "TextEditorPresenter", ->
|
||||
isVisible: false
|
||||
}
|
||||
|
||||
waitsForStateToUpdate presenter, ->
|
||||
editor.getBuffer().insert([0, 0], 'Hello world \n\n\n\n')
|
||||
presenter.setBlockDecorationDimensions(blockDecoration1, 0, 10)
|
||||
presenter.setBlockDecorationDimensions(blockDecoration4, 0, 20)
|
||||
|
||||
runs ->
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration1), {
|
||||
decoration: blockDecoration1
|
||||
screenRow: 4
|
||||
isVisible: true
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration2), {
|
||||
decoration: blockDecoration2
|
||||
screenRow: 8
|
||||
isVisible: false
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration3), {
|
||||
decoration: blockDecoration3
|
||||
screenRow: 8
|
||||
isVisible: false
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration4), {
|
||||
decoration: blockDecoration4
|
||||
screenRow: 14
|
||||
isVisible: false
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration1), {
|
||||
decoration: blockDecoration1
|
||||
screenRow: 0
|
||||
isVisible: true
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration2), {
|
||||
decoration: blockDecoration2
|
||||
screenRow: 4
|
||||
isVisible: false
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration3), {
|
||||
decoration: blockDecoration3
|
||||
screenRow: 4
|
||||
isVisible: false
|
||||
}
|
||||
expect(stateForBlockDecoration(presenter, blockDecoration4)).toBeUndefined()
|
||||
|
||||
waitsForStateToUpdate presenter, ->
|
||||
blockDecoration2.destroy()
|
||||
blockDecoration4.destroy()
|
||||
presenter.setBlockDecorationDimensions(blockDecoration1, 0, 20)
|
||||
presenter.setScrollTop(90)
|
||||
|
||||
runs ->
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration1), {
|
||||
decoration: blockDecoration1
|
||||
screenRow: 4
|
||||
isVisible: true
|
||||
}
|
||||
expect(stateForBlockDecoration(presenter, blockDecoration2)).toBeUndefined()
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration3), {
|
||||
decoration: blockDecoration3
|
||||
screenRow: 8
|
||||
isVisible: false
|
||||
}
|
||||
expect(stateForBlockDecoration(presenter, blockDecoration4)).toBeUndefined()
|
||||
expect(stateForBlockDecoration(presenter, blockDecoration1)).toBeUndefined()
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration2), {
|
||||
decoration: blockDecoration2
|
||||
screenRow: 4
|
||||
isVisible: false
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration3), {
|
||||
decoration: blockDecoration3
|
||||
screenRow: 4
|
||||
isVisible: false
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration4), {
|
||||
decoration: blockDecoration4
|
||||
screenRow: 10
|
||||
isVisible: true
|
||||
}
|
||||
|
||||
presenter.setScrollTop(80)
|
||||
presenter.invalidateBlockDecorationDimensions(blockDecoration1)
|
||||
presenter.setBlockDecorationDimensions(blockDecoration2, 0, 10)
|
||||
presenter.setBlockDecorationDimensions(blockDecoration3, 0, 10)
|
||||
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration1), {
|
||||
decoration: blockDecoration1
|
||||
screenRow: 4
|
||||
isVisible: false
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration3), {
|
||||
decoration: blockDecoration3
|
||||
screenRow: 8
|
||||
isVisible: true
|
||||
}
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration1), {
|
||||
decoration: blockDecoration1
|
||||
screenRow: 0
|
||||
isVisible: false
|
||||
}
|
||||
expect(stateForBlockDecoration(presenter, blockDecoration2)).toBeUndefined()
|
||||
expect(stateForBlockDecoration(presenter, blockDecoration3)).toBeUndefined()
|
||||
expectValues stateForBlockDecoration(presenter, blockDecoration4), {
|
||||
decoration: blockDecoration4
|
||||
screenRow: 10
|
||||
isVisible: true
|
||||
}
|
||||
|
||||
describe ".overlays", ->
|
||||
[item] = []
|
||||
|
||||
@@ -60,9 +60,9 @@ class BlockDecorationsComponent
|
||||
oldBlockDecorationState = @oldState.blockDecorations[id]
|
||||
blockDecorationNode = @blockDecorationNodesById[id]
|
||||
|
||||
if newBlockDecorationState.isVisible and not oldBlockDecorationState.isVisible
|
||||
if newBlockDecorationState.isVisible
|
||||
blockDecorationNode.classList.remove("atom--invisible-block-decoration")
|
||||
else if not newBlockDecorationState.isVisible and oldBlockDecorationState.isVisible
|
||||
else
|
||||
blockDecorationNode.classList.add("atom--invisible-block-decoration")
|
||||
|
||||
if newBlockDecorationState.screenRow isnt oldBlockDecorationState.screenRow
|
||||
|
||||
@@ -14,6 +14,7 @@ class BlockDecorationsPresenter {
|
||||
this.blocksByDecoration = new Map
|
||||
this.decorationsByBlock = new Map
|
||||
this.observedDecorations = new Set
|
||||
this.measuredDecorations = new Set
|
||||
|
||||
this.observeModel()
|
||||
}
|
||||
@@ -62,6 +63,12 @@ class BlockDecorationsPresenter {
|
||||
this.lineTopIndex.resizeBlock(block, height)
|
||||
}
|
||||
|
||||
this.measuredDecorations.add(decoration)
|
||||
this.emitter.emit("did-update-state")
|
||||
}
|
||||
|
||||
invalidateDimensionsForDecoration (decoration) {
|
||||
this.measuredDecorations.delete(decoration)
|
||||
this.emitter.emit("did-update-state")
|
||||
}
|
||||
|
||||
@@ -70,14 +77,16 @@ class BlockDecorationsPresenter {
|
||||
return blocks.map((block) => this.decorationsByBlock.get(block.id)).filter((decoration) => decoration)
|
||||
}
|
||||
|
||||
getAllDecorationsByScreenRow () {
|
||||
decorationsForScreenRowRange (startRow, endRow) {
|
||||
let blocks = this.lineTopIndex.allBlocks()
|
||||
let decorationsByScreenRow = new Map
|
||||
for (let block of blocks) {
|
||||
let decoration = this.decorationsByBlock.get(block.id)
|
||||
if (decoration) {
|
||||
let hasntMeasuredDecoration = !this.measuredDecorations.has(decoration)
|
||||
let isVisible = startRow <= block.row && block.row < endRow
|
||||
if (decoration && (isVisible || hasntMeasuredDecoration)) {
|
||||
let decorations = decorationsByScreenRow.get(block.row) || []
|
||||
decorations.push(decoration)
|
||||
decorations.push({decoration, isVisible})
|
||||
decorationsByScreenRow.set(block.row, decorations)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,6 +456,9 @@ class TextEditorComponent
|
||||
@editor.screenPositionForBufferPosition(bufferPosition)
|
||||
)
|
||||
|
||||
invalidateBlockDecorationDimensions: ->
|
||||
@presenter.invalidateBlockDecorationDimensions(arguments...)
|
||||
|
||||
onMouseDown: (event) =>
|
||||
unless event.button is 0 or (event.button is 1 and process.platform is 'linux')
|
||||
# Only handle mouse down events for left mouse button on all platforms
|
||||
|
||||
@@ -347,4 +347,7 @@ class TextEditorElement extends HTMLElement
|
||||
getHeight: ->
|
||||
@offsetHeight
|
||||
|
||||
invalidateBlockDecorationDimensions: ->
|
||||
@component.invalidateBlockDecorationDimensions(arguments...)
|
||||
|
||||
module.exports = TextEditorElement = document.registerElement 'atom-text-editor', prototype: TextEditorElement.prototype
|
||||
|
||||
@@ -1213,9 +1213,11 @@ class TextEditorPresenter
|
||||
updateBlockDecorationsState: ->
|
||||
@state.content.blockDecorations = {}
|
||||
|
||||
@blockDecorationsPresenter.getAllDecorationsByScreenRow().forEach (decorations, screenRow) =>
|
||||
for decoration in decorations
|
||||
isVisible = @getStartTileRow() <= screenRow < @getEndTileRow() + @tileSize
|
||||
startRow = @getStartTileRow()
|
||||
endRow = @getEndTileRow() + @tileSize
|
||||
decorations = @blockDecorationsPresenter.decorationsForScreenRowRange(startRow, endRow)
|
||||
decorations.forEach (decorations, screenRow) =>
|
||||
for {decoration, isVisible} in decorations
|
||||
@state.content.blockDecorations[decoration.id] = {decoration, screenRow, isVisible}
|
||||
|
||||
updateLineDecorations: ->
|
||||
@@ -1414,6 +1416,9 @@ class TextEditorPresenter
|
||||
setBlockDecorationDimensions: ->
|
||||
@blockDecorationsPresenter.setDimensionsForDecoration(arguments...)
|
||||
|
||||
invalidateBlockDecorationDimensions: ->
|
||||
@blockDecorationsPresenter.invalidateDimensionsForDecoration(arguments...)
|
||||
|
||||
observeCursor: (cursor) ->
|
||||
didChangePositionDisposable = cursor.onDidChangePosition =>
|
||||
@shouldUpdateHiddenInputState = true if cursor.isLastCursor()
|
||||
|
||||
Reference in New Issue
Block a user