pulsar/src/gutter-component.coffee

96 lines
3.2 KiB
CoffeeScript
Raw Normal View History

2014-04-14 20:11:11 +04:00
React = require 'react'
{div} = require 'reactionary'
{isEqual, isEqualForProperties, multiplyString} = require 'underscore-plus'
SubscriberMixin = require './subscriber-mixin'
2014-04-14 20:11:11 +04:00
module.exports =
GutterComponent = React.createClass
2014-04-15 20:39:47 +04:00
displayName: 'GutterComponent'
mixins: [SubscriberMixin]
2014-04-15 20:39:47 +04:00
lastMeasuredWidth: null
2014-04-14 20:11:11 +04:00
render: ->
{width} = @props
div className: 'gutter', style: {width},
div className: 'line-numbers', ref: 'lineNumbers',
if @isMounted()
@renderLineNumbers()
else
@renderLineNumberForMeasurement()
renderLineNumbers: ->
{editor, visibleRowRange, lineOverdraw, scrollTop, lineHeight, showIndentGuide} = @props
[startRow, endRow] = visibleRowRange
maxLineNumberDigits = @getMaxLineNumberDigits()
scrollOffset = -scrollTop % lineHeight
wrapCount = 0
for bufferRow, index in editor.bufferRowsForScreenRows(startRow, endRow - 1)
if bufferRow is lastBufferRow
lineNumber = ''
key = "#{bufferRow + 1}-#{++wrapCount}"
else
lastBufferRow = bufferRow
wrapCount = 0
lineNumber = "#{bufferRow + 1}"
key = lineNumber
LineNumberComponent({key, lineNumber, maxLineNumberDigits, index, lineHeight, scrollOffset})
renderLineNumberForMeasurement: ->
LineNumberComponent(
key: 'forMeasurement'
lineNumber: ''
maxLineNumberDigits: @getMaxLineNumberDigits()
index: 0
lineHeight: 0
scrollOffset: 0
)
getMaxLineNumberDigits: ->
@props.editor.getLineCount().toString().length
2014-04-14 20:11:11 +04:00
# Only update the gutter if the visible row range has changed or if a
# non-zero-delta change to the screen lines has occurred within the current
# visible row range.
shouldComponentUpdate: (newProps) ->
return true unless isEqualForProperties(newProps, @props, 'visibleRowRange', 'scrollTop', 'lineHeight', 'fontSize')
{visibleRowRange, pendingChanges} = newProps
for change in pendingChanges when change.screenDelta > 0 or change.bufferDelta > 0
return true unless change.end <= visibleRowRange.start or visibleRowRange.end <= change.start
false
componentDidUpdate: (oldProps) ->
unless @lastMeasuredWidth? and isEqualForProperties(oldProps, @props, 'maxLineNumberDigits', 'fontSize', 'fontFamily')
width = @refs.lineNumbers.getDOMNode().firstChild.offsetWidth
if width isnt @lastMeasuredWidth
@lastMeasuredWidth = width
@props.onWidthChanged(width)
2014-04-14 20:11:11 +04:00
LineNumberComponent = React.createClass
2014-04-16 03:17:30 +04:00
displayName: 'LineNumberComponent'
2014-04-14 20:11:11 +04:00
render: ->
{index, lineHeight, scrollOffset} = @props
2014-04-14 20:11:11 +04:00
div
className: "line-number editor-colors"
style: {WebkitTransform: "translate3d(0px, #{index * lineHeight + scrollOffset}px, 0px)"}
2014-04-14 20:11:11 +04:00
dangerouslySetInnerHTML: {__html: @buildInnerHTML()}
buildInnerHTML: ->
{lineNumber, maxLineNumberDigits} = @props
if lineNumber.length < maxLineNumberDigits
padding = multiplyString('&nbsp;', maxLineNumberDigits - lineNumber.length)
2014-04-14 20:11:11 +04:00
padding + lineNumber + @iconDivHTML
else
lineNumber + @iconDivHTML
iconDivHTML: '<div class="icon-right"></div>'
2014-04-15 04:07:43 +04:00
shouldComponentUpdate: (newProps) ->
not isEqualForProperties(newProps, @props, 'index', 'lineHeight', 'scrollOffset')