diff --git a/src/editor-component.coffee b/src/editor-component.coffee index 6a45168ae..172e66707 100644 --- a/src/editor-component.coffee +++ b/src/editor-component.coffee @@ -28,10 +28,10 @@ EditorComponent = React.createClass className += ' is-focused' if focused div className: className, style: {fontSize, lineHeight, fontFamily}, tabIndex: -1, onFocus: @onFocus, - GutterComponent({editor, visibleRowRange, scrollTop}) + GutterComponent({editor, visibleRowRange, scrollTop, @pendingChanges}) EditorScrollViewComponent { - ref: 'scrollView', editor, visibleRowRange, @onInputFocused, @onInputBlurred + ref: 'scrollView', editor, visibleRowRange, @pendingChanges, @onInputFocused, @onInputBlurred cursorBlinkPeriod, cursorBlinkResumeDelay, showIndentGuide, fontSize, fontFamily, lineHeight } @@ -58,6 +58,7 @@ EditorComponent = React.createClass cursorBlinkResumeDelay: 200 componentDidMount: -> + @pendingChanges = [] @props.editor.manageScrollPosition = true @listenForDOMEvents() @@ -72,6 +73,7 @@ EditorComponent = React.createClass @stopBlinkingCursors() componentDidUpdate: -> + @pendingChanges.length = 0 @props.parentView.trigger 'editor:display-updated' observeEditor: -> @@ -272,9 +274,10 @@ EditorComponent = React.createClass if updateRequested @forceUpdate() - onScreenLinesChanged: ({start, end}) -> + onScreenLinesChanged: (change) -> {editor} = @props - @requestUpdate() if editor.intersectsVisibleRowRange(start, end + 1) # TODO: Use closed-open intervals for change events + @pendingChanges.push(change) + @requestUpdate() if editor.intersectsVisibleRowRange(change.start, change.end + 1) # TODO: Use closed-open intervals for change events onSelectionAdded: (selection) -> {editor} = @props diff --git a/src/editor-scroll-view-component.coffee b/src/editor-scroll-view-component.coffee index dd1937e2f..d0aec653b 100644 --- a/src/editor-scroll-view-component.coffee +++ b/src/editor-scroll-view-component.coffee @@ -12,7 +12,7 @@ EditorScrollViewComponent = React.createClass render: -> {editor, fontSize, fontFamily, lineHeight, showIndentGuide, cursorBlinkPeriod, cursorBlinkResumeDelay} = @props - {visibleRowRange, onInputFocused, onInputBlurred} = @props + {visibleRowRange, pendingChanges, onInputFocused, onInputBlurred} = @props contentStyle = height: editor.getScrollHeight() WebkitTransform: "translate(#{-editor.getScrollLeft()}px, #{-editor.getScrollTop()}px)" @@ -28,7 +28,7 @@ EditorScrollViewComponent = React.createClass div className: 'scroll-view-content', style: contentStyle, onMouseDown: @onMouseDown, CursorsComponent({editor, cursorBlinkPeriod, cursorBlinkResumeDelay}) - LinesComponent({ref: 'lines', editor, fontSize, fontFamily, lineHeight, visibleRowRange, showIndentGuide}) + LinesComponent({ref: 'lines', editor, fontSize, fontFamily, lineHeight, visibleRowRange, pendingChanges, showIndentGuide}) div className: 'underlayer', SelectionsComponent({editor}) diff --git a/src/gutter-component.coffee b/src/gutter-component.coffee index 4fcff9828..7ab6c4846 100644 --- a/src/gutter-component.coffee +++ b/src/gutter-component.coffee @@ -41,10 +41,6 @@ GutterComponent = React.createClass div className: 'spacer', key: 'bottom-spacer', style: {height: followingHeight} ] - componentDidMount: -> - @pendingChanges = [] - @subscribe @props.editor, 'screen-lines-changed', @onScreenLinesChanged - componentWillUnmount: -> @unsubscribe() @@ -52,22 +48,16 @@ GutterComponent = React.createClass # non-zero-delta change to the screen lines has occurred within the current # visible row range. shouldComponentUpdate: (newProps) -> - {visibleRowRange, scrollTop} = @props + {visibleRowRange, pendingChanges, scrollTop} = @props return true unless newProps.scrollTop is scrollTop return true unless isEqual(newProps.visibleRowRange, visibleRowRange) - for change in @pendingChanges when change.screenDelta > 0 or change.bufferDelta > 0 + 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: -> - @pendingChanges.length = 0 - - onScreenLinesChanged: (change) -> - @pendingChanges.push(change) - LineNumberComponent = React.createClass displayName: 'LineNumberComponent' diff --git a/src/lines-component.coffee b/src/lines-component.coffee index 9b9e8d5c5..e3d81ab5e 100644 --- a/src/lines-component.coffee +++ b/src/lines-component.coffee @@ -1,6 +1,6 @@ React = require 'react' {div, span} = require 'reactionary' -{debounce, isEqualForProperties, multiplyString} = require 'underscore-plus' +{debounce, isEqual, isEqualForProperties, multiplyString} = require 'underscore-plus' {$$} = require 'space-pen' DummyLineNode = $$(-> @div className: 'line', style: 'position: absolute; visibility: hidden;', => @span 'x')[0] @@ -28,6 +28,15 @@ LinesComponent = React.createClass @measuredLines = new WeakSet @updateModelDimensions() + shouldComponentUpdate: (newProps) -> + return true unless isEqualForProperties(newProps, @props, 'visibleRowRange', 'fontSize', 'fontFamily', 'lineHeight', 'showIndentGuide') + + {visibleRowRange, pendingChanges} = newProps + for change in pendingChanges + return true unless change.end <= visibleRowRange.start or visibleRowRange.end <= change.start + + false + componentDidUpdate: (prevProps) -> @updateModelDimensions() unless isEqualForProperties(prevProps, @props, 'fontSize', 'fontFamily', 'lineHeight') @clearScopedCharWidths() unless isEqualForProperties(prevProps, @props, 'fontSize', 'fontFamily')