diff --git a/src/lines-component.coffee b/src/lines-component.coffee index 547b54e56..fda77a76a 100644 --- a/src/lines-component.coffee +++ b/src/lines-component.coffee @@ -21,6 +21,7 @@ class LinesComponent constructor: ({@presenter, @hostElement, @useShadowDOM, visible}) -> @tileComponentsByTileId = {} + @freeDomNodes = [] @domNode = document.createElement('div') @domNode.classList.add('lines') @@ -81,7 +82,10 @@ class LinesComponent return removeTileNode: (id) -> - @tileComponentsByTileId[id].getDomNode().remove() + node = @tileComponentsByTileId[id].getDomNode() + + node.style.display = "none" + @freeDomNodes.push(node) delete @tileComponentsByTileId[id] delete @oldState.tiles[id] @@ -91,10 +95,13 @@ class LinesComponent @removeTileNode(id) for id, tileState of @newState.tiles - tileComponent = @tileComponentsByTileId[id] ?= new TileComponent({id, @presenter}) + if @oldState.tiles.hasOwnProperty(id) + tileComponent = @tileComponentsByTileId[id] + else + domNode = @freeDomNodes.pop() + tileComponent = @tileComponentsByTileId[id] = new TileComponent({id, @presenter, domNode}) - unless @oldState.tiles.hasOwnProperty(id) - @domNode.appendChild(tileComponent.getDomNode()) + @domNode.appendChild(tileComponent.getDomNode()) unless domNode? @oldState.tiles[id] = cloneObject(tileState) tileComponent.updateSync(@newState) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 071195ec3..4ff358cec 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -318,7 +318,7 @@ class TextEditorPresenter for index, tile of @state.content.tiles continue if index is @scrollingTile - continue if index in visibleTilesIndexes + continue if startIndex <= index <= endIndex delete @state.content.tiles[index] delete @linesPresentersByTileIndex[index] @@ -329,10 +329,12 @@ class TextEditorPresenter presenter.endRow = Math.ceil(Math.min(@model.getScreenLineCount(), (index + 1) * linesPerTile)) presenter.lineHeight = @lineHeight + isNewTile = not @state.content.tiles.hasOwnProperty(index) tile = @state.content.tiles[index] ?= {} tile.top = (index * linesPerTile * @lineHeight) - @scrollTop tile.lines = presenter.getState() tile.height = linesPerTile * @lineHeight + tile.newlyCreated = isNewTile updateCursorsState: -> @state.content.cursors = {} diff --git a/src/tile-component.coffee b/src/tile-component.coffee index ff2d7eb46..023f9a369 100644 --- a/src/tile-component.coffee +++ b/src/tile-component.coffee @@ -15,14 +15,15 @@ module.exports = class TileComponent placeholderTextDiv: null - constructor: ({@presenter, @id}) -> + constructor: ({@presenter, @id, @domNode}) -> @measuredLines = new Set @lineNodesByLineId = {} @screenRowsByLineId = {} @lineIdsByScreenRow = {} - @domNode = document.createElement("div") + @domNode ?= document.createElement("div") @domNode.addEventListener("mousewheel", @onMouseWheel) @domNode.style.position = "absolute" + @domNode.style.display = "block" @domNode.classList.add("tile") onMouseWheel: => @@ -45,8 +46,27 @@ class TileComponent @domNode.style['-webkit-transform'] = "translate3d(0, #{@newState.tiles[@id].top}px, 0px)" @oldState.tiles[@id]?.top = @newState.tiles[@id].top - @removeLineNodes() unless @oldState.indentGuidesVisible is @newState.indentGuidesVisible - @updateLineNodes() + if @newState.tiles[@id].newlyCreated + newLineIds = [] + newLinesHTML = "" + + for id, lineState of @newState.tiles[@id].lines + newLineIds.push(id) + newLinesHTML += @buildLineHTML(id) + @screenRowsByLineId[id] = lineState.screenRow + @lineIdsByScreenRow[lineState.screenRow] = id + @oldState.tiles[@id]?.lines[id] = cloneObject(lineState) + + return if newLineIds.length is 0 + + @domNode.innerHTML = newLinesHTML + newLineNodes = _.toArray(@domNode.children) + for id, i in newLineIds + lineNode = newLineNodes[i] + @lineNodesByLineId[id] = lineNode + else + @removeLineNodes() unless @oldState.indentGuidesVisible is @newState.indentGuidesVisible + @updateLineNodes() if @newState.scrollWidth isnt @oldState.scrollWidth @domNode.style.width = @newState.scrollWidth + 'px'