_ = require 'underscore-plus' WrapperDiv = document.createElement('div') module.exports = class GutterComponent dummyLineNumberNode: null constructor: ({@presenter, @onMouseDown, @editor}) -> @lineNumberNodesById = {} @domNode = document.createElement('div') @domNode.classList.add('gutter') @lineNumbersNode = document.createElement('div') @lineNumbersNode.classList.add('line-numbers') @domNode.appendChild(@lineNumbersNode) @domNode.addEventListener 'click', @onClick @domNode.addEventListener 'mousedown', @onMouseDown updateSync: (state) -> @newState = state.gutter @oldState ?= {lineNumbers: {}} @appendDummyLineNumber() unless @dummyLineNumberNode? if @newState.scrollHeight isnt @oldState.scrollHeight @lineNumbersNode.style.height = @newState.scrollHeight + 'px' @oldState.scrollHeight = @newState.scrollHeight if @newState.scrollTop isnt @oldState.scrollTop @lineNumbersNode.style['-webkit-transform'] = "translate3d(0px, #{-@newState.scrollTop}px, 0px)" @oldState.scrollTop = @newState.scrollTop if @newState.backgroundColor isnt @oldState.backgroundColor @lineNumbersNode.style.backgroundColor = @newState.backgroundColor @oldState.backgroundColor = @newState.backgroundColor if @newState.maxLineNumberDigits isnt @oldState.maxLineNumberDigits @updateDummyLineNumber() node.remove() for id, node of @lineNumberNodesById @oldState = {maxLineNumberDigits: @newState.maxLineNumberDigits, lineNumbers: {}} @lineNumberNodesById = {} @updateLineNumbers() # This dummy line number element holds the gutter to the appropriate width, # since the real line numbers are absolutely positioned for performance reasons. appendDummyLineNumber: -> WrapperDiv.innerHTML = @buildLineNumberHTML({bufferRow: -1}) @dummyLineNumberNode = WrapperDiv.children[0] @lineNumbersNode.appendChild(@dummyLineNumberNode) updateDummyLineNumber: -> @dummyLineNumberNode.innerHTML = @buildLineNumberInnerHTML(0, false) updateLineNumbers: -> newLineNumberIds = null newLineNumbersHTML = null for id, lineNumberState of @newState.lineNumbers if @oldState.lineNumbers.hasOwnProperty(id) @updateLineNumberNode(id, lineNumberState) else newLineNumberIds ?= [] newLineNumbersHTML ?= "" newLineNumberIds.push(id) newLineNumbersHTML += @buildLineNumberHTML(lineNumberState) @oldState.lineNumbers[id] = _.clone(lineNumberState) if newLineNumberIds? WrapperDiv.innerHTML = newLineNumbersHTML newLineNumberNodes = _.toArray(WrapperDiv.children) node = @lineNumbersNode for id, i in newLineNumberIds lineNumberNode = newLineNumberNodes[i] @lineNumberNodesById[id] = lineNumberNode node.appendChild(lineNumberNode) for id, lineNumberState of @oldState.lineNumbers unless @newState.lineNumbers.hasOwnProperty(id) @lineNumberNodesById[id].remove() delete @lineNumberNodesById[id] delete @oldState.lineNumbers[id] return buildLineNumberHTML: (lineNumberState) -> {screenRow, bufferRow, softWrapped, top, decorationClasses} = lineNumberState if screenRow? style = "position: absolute; top: #{top}px;" else style = "visibility: hidden;" className = @buildLineNumberClassName(lineNumberState) innerHTML = @buildLineNumberInnerHTML(bufferRow, softWrapped) "