Recycle gutter nodes

This commit is contained in:
Antonio Scandurra
2015-09-14 17:25:30 +02:00
parent ece15b2a24
commit 93ed0853a2
2 changed files with 42 additions and 31 deletions

View File

@@ -1,7 +1,7 @@
TiledComponent = require './tiled-component'
LineNumbersTileComponent = require './line-numbers-tile-component'
WrapperDiv = document.createElement('div')
DummyLineNumberComponent = LineNumbersTileComponent.createDummy()
DomElementsPool = require './dom-elements-pool'
module.exports =
class LineNumberGutterComponent extends TiledComponent
@@ -10,6 +10,10 @@ class LineNumberGutterComponent extends TiledComponent
constructor: ({@onMouseDown, @editor, @gutter}) ->
@visible = true
@elementsPool = new DomElementsPool
@dummyLineNumberComponent = LineNumbersTileComponent.createDummy(@elementsPool)
@domNode = atom.views.getView(@gutter)
@lineNumbersNode = @domNode.firstChild
@lineNumbersNode.innerHTML = ''
@@ -60,7 +64,7 @@ class LineNumberGutterComponent extends TiledComponent
@oldState.styles = {}
@oldState.maxLineNumberDigits = @newState.maxLineNumberDigits
buildComponentForTile: (id) -> new LineNumbersTileComponent({id})
buildComponentForTile: (id) -> new LineNumbersTileComponent({id, @elementsPool})
###
Section: Private Methods
@@ -69,14 +73,14 @@ class LineNumberGutterComponent extends TiledComponent
# This dummy line number element holds the gutter to the appropriate width,
# since the real line numbers are absolutely positioned for performance reasons.
appendDummyLineNumber: ->
DummyLineNumberComponent.newState = @newState
WrapperDiv.innerHTML = DummyLineNumberComponent.buildLineNumberHTML({bufferRow: -1})
@dummyLineNumberNode = WrapperDiv.children[0]
@dummyLineNumberComponent.newState = @newState
@dummyLineNumberNode = @dummyLineNumberComponent.buildLineNumberNode({bufferRow: -1})
@lineNumbersNode.appendChild(@dummyLineNumberNode)
updateDummyLineNumber: ->
DummyLineNumberComponent.newState = @newState
@dummyLineNumberNode.innerHTML = DummyLineNumberComponent.buildLineNumberInnerHTML(0, false)
@dummyLineNumberComponent.newState = @newState
@dummyLineNumberNode.innerHTML = ""
@dummyLineNumberComponent.appendLineNumberInnerNodes(0, false, @dummyLineNumberNode)
onMouseDown: (event) =>
{target} = event

View File

@@ -3,19 +3,18 @@ WrapperDiv = document.createElement('div')
module.exports =
class LineNumbersTileComponent
@createDummy: ->
new LineNumbersTileComponent({id: -1})
@createDummy: (elementsPool) ->
new LineNumbersTileComponent({id: -1, elementsPool})
constructor: ({@id}) ->
constructor: ({@id, @elementsPool}) ->
@lineNumberNodesById = {}
@domNode = document.createElement("div")
@domNode.classList.add("tile")
@domNode = @elementsPool.build("div", "tile")
@domNode.style.position = "absolute"
@domNode.style.display = "block"
@domNode.style.top = 0 # Cover the space occupied by a dummy lineNumber
destroy: ->
@domNode.remove()
@elementsPool.freeElementAndDescendants(@domNode)
getDomNode: ->
@domNode
@@ -50,7 +49,9 @@ class LineNumbersTileComponent
@oldTileState.zIndex = @newTileState.zIndex
if @newState.maxLineNumberDigits isnt @oldState.maxLineNumberDigits
node.remove() for id, node of @lineNumberNodesById
for id, node of @lineNumberNodesById
@elementsPool.freeElementAndDescendants(node)
@oldState.tiles[@id] = {lineNumbers: {}}
@oldTileState = @oldState.tiles[@id]
@lineNumberNodesById = {}
@@ -60,11 +61,11 @@ class LineNumbersTileComponent
updateLineNumbers: ->
newLineNumberIds = null
newLineNumbersHTML = null
newLineNumberNodes = null
for id, lineNumberState of @oldTileState.lineNumbers
unless @newTileState.lineNumbers.hasOwnProperty(id)
@lineNumberNodesById[id].remove()
@elementsPool.freeElementAndDescendants(@lineNumberNodesById[id])
delete @lineNumberNodesById[id]
delete @oldTileState.lineNumbers[id]
@@ -73,15 +74,12 @@ class LineNumbersTileComponent
@updateLineNumberNode(id, lineNumberState)
else
newLineNumberIds ?= []
newLineNumbersHTML ?= ""
newLineNumberNodes ?= []
newLineNumberIds.push(id)
newLineNumbersHTML += @buildLineNumberHTML(lineNumberState)
newLineNumberNodes.push(@buildLineNumberNode(lineNumberState))
@oldTileState.lineNumbers[id] = _.clone(lineNumberState)
if newLineNumberIds?
WrapperDiv.innerHTML = newLineNumbersHTML
newLineNumberNodes = _.toArray(WrapperDiv.children)
node = @domNode
for id, i in newLineNumberIds
lineNumberNode = newLineNumberNodes[i]
@@ -90,18 +88,25 @@ class LineNumbersTileComponent
return
buildLineNumberHTML: (lineNumberState) ->
buildLineNumberNode: (lineNumberState) ->
{screenRow, bufferRow, softWrapped, top, decorationClasses, zIndex} = lineNumberState
if screenRow?
style = "position: absolute; top: #{top}px; z-index: #{zIndex};"
else
style = "visibility: hidden;"
className = @buildLineNumberClassName(lineNumberState)
innerHTML = @buildLineNumberInnerHTML(bufferRow, softWrapped)
lineNumberNode = @elementsPool.build("div", className)
lineNumberNode.dataset.screenRow = screenRow
lineNumberNode.dataset.bufferRow = bufferRow
"<div class=\"#{className}\" style=\"#{style}\" data-buffer-row=\"#{bufferRow}\" data-screen-row=\"#{screenRow}\">#{innerHTML}</div>"
if screenRow?
lineNumberNode.style.position = "absolute"
lineNumberNode.style.top = top + "px"
lineNumberNode.style.zIndex = zIndex
else
lineNumberNode.style.visibility = "hidden"
buildLineNumberInnerHTML: (bufferRow, softWrapped) ->
@appendLineNumberInnerNodes(bufferRow, softWrapped, lineNumberNode)
lineNumberNode
appendLineNumberInnerNodes: (bufferRow, softWrapped, lineNumberNode) ->
{maxLineNumberDigits} = @newState
if softWrapped
@@ -110,8 +115,10 @@ class LineNumbersTileComponent
lineNumber = (bufferRow + 1).toString()
padding = _.multiplyString('&nbsp;', maxLineNumberDigits - lineNumber.length)
iconHTML = '<div class="icon-right"></div>'
padding + lineNumber + iconHTML
iconRight = @elementsPool.build("div", "icon-right")
lineNumberNode.innerHTML = padding + lineNumber
lineNumberNode.appendChild(iconRight)
updateLineNumberNode: (lineNumberId, newLineNumberState) ->
oldLineNumberState = @oldTileState.lineNumbers[lineNumberId]