Make GutterComponent a plain JS object instead of a React component

This commit is contained in:
Nathan Sobo 2015-02-11 10:29:05 -07:00
parent 2d771ab8e4
commit 168df987d7
3 changed files with 43 additions and 47 deletions

View File

@ -572,27 +572,27 @@ describe "TextEditorComponent", ->
expect(lineNumbersNode.style.backgroundColor).toBe 'rgb(255, 0, 0)'
it "hides or shows the gutter based on the '::isGutterVisible' property on the model and the global 'editor.showLineNumbers' config setting", ->
expect(component.refs.gutter?).toBe true
expect(component.gutterComponent?).toBe true
editor.setGutterVisible(false)
nextAnimationFrame()
expect(component.refs.gutter?).toBe false
expect(componentNode.querySelector('.gutter')).toBeNull()
atom.config.set("editor.showLineNumbers", false)
expect(nextAnimationFrame).toBe noAnimationFrame
expect(component.refs.gutter?).toBe false
expect(componentNode.querySelector('.gutter')).toBeNull()
editor.setGutterVisible(true)
expect(nextAnimationFrame).toBe noAnimationFrame
expect(component.refs.gutter?).toBe false
expect(componentNode.querySelector('.gutter')).toBeNull()
atom.config.set("editor.showLineNumbers", true)
nextAnimationFrame()
expect(component.refs.gutter?).toBe true
expect(componentNode.querySelector('.gutter')).toBeDefined()
expect(component.lineNumberNodeForScreenRow(3)?).toBe true
describe "fold decorations", ->

View File

@ -1,42 +1,29 @@
_ = require 'underscore-plus'
React = require 'react-atom-fork'
{div} = require 'reactionary-atom-fork'
{isEqual, isEqualForProperties, multiplyString, toArray} = _
Decoration = require './decoration'
SubscriberMixin = require './subscriber-mixin'
WrapperDiv = document.createElement('div')
module.exports =
GutterComponent = React.createClass
displayName: 'GutterComponent'
mixins: [SubscriberMixin]
class GutterComponent
dummyLineNumberNode: null
measuredWidth: null
render: ->
div className: 'gutter',
div className: 'line-numbers', ref: 'lineNumbers'
componentWillMount: ->
constructor: ({@presenter, @onMouseDown, @editor}) ->
@lineNumberNodesById = {}
componentDidMount: ->
@updateSync()
@domNode = document.createElement('div')
@domNode.classList.add('gutter')
@lineNumbersNode = document.createElement('div')
@lineNumbersNode.classList.add('line-numbers')
@domNode.appendChild(@lineNumbersNode)
node = @getDOMNode()
node.addEventListener 'click', @onClick
node.addEventListener 'mousedown', @onMouseDown
@domNode.addEventListener 'click', @onClick
@domNode.addEventListener 'mousedown', @onMouseDown
componentDidUpdate: ->
@updateSync()
updateSync: ->
@newState = @props.presenter.state.gutter
@newState = @presenter.state.gutter
@oldState ?= {lineNumbers: {}}
@lineNumbersNode ?= @refs.lineNumbers.getDOMNode()
@appendDummyLineNumber() unless @dummyLineNumberNode?
if @newState.scrollHeight isnt @oldState.scrollHeight
@ -64,7 +51,7 @@ GutterComponent = React.createClass
appendDummyLineNumber: ->
WrapperDiv.innerHTML = @buildLineNumberHTML({bufferRow: -1})
@dummyLineNumberNode = WrapperDiv.children[0]
@refs.lineNumbers.getDOMNode().appendChild(@dummyLineNumberNode)
@lineNumbersNode.appendChild(@dummyLineNumberNode)
updateDummyLineNumber: ->
@dummyLineNumberNode.innerHTML = @buildLineNumberInnerHTML(0, false)
@ -85,9 +72,9 @@ GutterComponent = React.createClass
if newLineNumberIds?
WrapperDiv.innerHTML = newLineNumbersHTML
newLineNumberNodes = toArray(WrapperDiv.children)
newLineNumberNodes = _.toArray(WrapperDiv.children)
node = @refs.lineNumbers.getDOMNode()
node = @lineNumbersNode
for id, i in newLineNumberIds
lineNumberNode = newLineNumberNodes[i]
@lineNumberNodesById[id] = lineNumberNode
@ -118,7 +105,7 @@ GutterComponent = React.createClass
else
lineNumber = (bufferRow + 1).toString()
padding = multiplyString(' ', maxLineNumberDigits - lineNumber.length)
padding = _.multiplyString(' ', maxLineNumberDigits - lineNumber.length)
iconHTML = '<div class="icon-right"></div>'
padding + lineNumber + iconHTML
@ -149,21 +136,20 @@ GutterComponent = React.createClass
return @lineNumberNodesById[id]
null
onMouseDown: (event) ->
onMouseDown: (event) =>
{target} = event
lineNumber = target.parentNode
unless target.classList.contains('icon-right') and lineNumber.classList.contains('foldable')
@props.onMouseDown(event)
@onMouseDown(event)
onClick: (event) ->
{editor} = @props
onClick: (event) =>
{target} = event
lineNumber = target.parentNode
if target.classList.contains('icon-right') and lineNumber.classList.contains('foldable')
bufferRow = parseInt(lineNumber.getAttribute('data-buffer-row'))
if lineNumber.classList.contains('folded')
editor.unfoldBufferRow(bufferRow)
@editor.unfoldBufferRow(bufferRow)
else
editor.foldBufferRow(bufferRow)
@editor.foldBufferRow(bufferRow)

View File

@ -40,6 +40,7 @@ TextEditorComponent = React.createClass
measureLineHeightAndDefaultCharWidthWhenShown: true
remeasureCharacterWidthsWhenShown: false
stylingChangeAnimationFrameRequested: false
gutterComponent: null
render: ->
{focused, showLineNumbers} = @state
@ -62,12 +63,6 @@ TextEditorComponent = React.createClass
className += ' has-selection' if hasSelection
div {className, style},
if @gutterVisible
GutterComponent {
ref: 'gutter', onMouseDown: @onGutterMouseDown,
@presenter, editor
}
div ref: 'scrollView', className: 'scroll-view',
InputComponent
ref: 'input'
@ -121,6 +116,8 @@ TextEditorComponent = React.createClass
componentDidMount: ->
{editor, stylesElement, hostElement, useShadowDOM} = @props
@mountGutterComponent() if @gutterVisible
@linesComponent = new LinesComponent({@presenter, hostElement, useShadowDOM})
scrollViewNode = @refs.scrollView.getDOMNode()
horizontalScrollbarNode = @refs.horizontalScrollbar.getDOMNode()
@ -158,6 +155,13 @@ TextEditorComponent = React.createClass
@cursorMoved = false
@selectionChanged = false
if @gutterVisible
@mountGutterComponent() unless @gutterComponent?
@gutterComponent.updateSync()
else
@gutterComponent?.domNode?.remove()
@gutterComponent = null
@linesComponent.updateSync(@isVisible())
if @props.editor.isAlive()
@ -167,6 +171,12 @@ TextEditorComponent = React.createClass
@props.hostElement.__spacePenView.trigger 'selection:changed' if selectionChanged
@props.hostElement.__spacePenView.trigger 'editor:display-updated'
mountGutterComponent: ->
{editor} = @props
@gutterComponent = new GutterComponent({@presenter, editor, onMouseDown: @onGutterMouseDown})
node = @getDOMNode()
node.insertBefore(@gutterComponent.domNode, node.firstChild)
becameVisible: ->
@updatesPaused = true
@measureScrollbars() if @measureScrollbarsWhenShown
@ -680,8 +690,8 @@ TextEditorComponent = React.createClass
@presenter.setBackgroundColor(backgroundColor)
if @refs.gutter?
gutterBackgroundColor = getComputedStyle(@refs.gutter.getDOMNode()).backgroundColor
if @gutterComponent?
gutterBackgroundColor = getComputedStyle(@gutterComponent.domNode).backgroundColor
@presenter.setGutterBackgroundColor(gutterBackgroundColor)
measureLineHeightAndDefaultCharWidth: ->
@ -761,7 +771,7 @@ TextEditorComponent = React.createClass
lineNodeForScreenRow: (screenRow) -> @linesComponent.lineNodeForScreenRow(screenRow)
lineNumberNodeForScreenRow: (screenRow) -> @refs.gutter.lineNumberNodeForScreenRow(screenRow)
lineNumberNodeForScreenRow: (screenRow) -> @gutterComponent.lineNumberNodeForScreenRow(screenRow)
screenRowForNode: (node) ->
while node?