Move decision to measure lineHeight/charWidths to EditorComponent

This prevents the double-update of the lines component when changing
the font-size, line-height and font-family. We detect the update of
these values in the root component and trigger a measurement. If the
measurement determines that the pixel values have changed, *then* we
update the lines.
This commit is contained in:
Nathan Sobo
2014-06-02 12:35:07 +09:00
parent 3052fe3f3b
commit f467e3eed4
2 changed files with 28 additions and 21 deletions

View File

@@ -1,6 +1,6 @@
React = require 'react-atom-fork'
{div, span} = require 'reactionary-atom-fork'
{debounce, defaults} = require 'underscore-plus'
{debounce, defaults, isEqualForProperties} = require 'underscore-plus'
scrollbarStyle = require 'scrollbar-style'
GutterComponent = require './gutter-component'
@@ -35,6 +35,7 @@ EditorComponent = React.createClass
scrollViewMeasurementRequested: false
overflowChangedEventsPaused: false
overflowChangedWhilePaused: false
measureLineHeightInPixelsAndCharWidthWhenShown: false
render: ->
{focused, fontSize, lineHeight, fontFamily, showIndentGuide, showInvisibles, visible} = @state
@@ -52,6 +53,7 @@ EditorComponent = React.createClass
scrollTop = editor.getScrollTop()
scrollLeft = editor.getScrollLeft()
lineHeightInPixels = editor.getLineHeightInPixels()
defaultCharWidth = editor.getDefaultCharWidth()
scrollViewHeight = editor.getHeight()
horizontalScrollbarHeight = editor.getHorizontalScrollbarHeight()
verticalScrollbarWidth = editor.getVerticalScrollbarWidth()
@@ -86,7 +88,7 @@ EditorComponent = React.createClass
fontSize, fontFamily, lineHeightInPixels
}
LinesComponent {
ref: 'lines', editor, fontSize, fontFamily, lineHeight, lineHeightInPixels,
ref: 'lines', editor, lineHeightInPixels, defaultCharWidth,
showIndentGuide, renderedRowRange, @pendingChanges, scrollTop, scrollLeft, @scrollingVertically,
selectionScreenRanges, scrollHeight, scrollWidth, mouseWheelScreenRow, invisibles,
visible, scrollViewHeight
@@ -161,11 +163,15 @@ EditorComponent = React.createClass
componentWillUpdate: ->
@props.parentView.trigger 'cursor:moved' if @cursorsMoved
componentDidUpdate: ->
componentDidUpdate: (prevProps, prevState) ->
@pendingChanges.length = 0
@cursorsMoved = false
@refreshingScrollbars = false
@measureScrollbars() if @measuringScrollbars
@measureLineHeightInPixelsAndCharWidthIfNeeded(prevState)
unless isEqualForProperties(prevState, @state, 'fontSize', 'fontFamily')
@refs.lines.clearScopedCharWidths()
@refs.lines.measureCharactersInNewLines()
@pauseOverflowChangedEvents()
@props.parentView.trigger 'editor:display-updated'
@@ -566,6 +572,21 @@ EditorComponent = React.createClass
clientWidth = scrollViewNode.clientWidth
editor.setWidth(clientWidth) if clientWidth > 0
measureLineHeightInPixelsAndCharWidthIfNeeded: (prevState) ->
unless isEqualForProperties(prevState, @state, 'lineHeight', 'fontSize', 'fontFamily')
if @state.visible
@measureLineHeightInPixelsAndCharWidth()
else
@measureLineHeightInPixelsAndCharWidthWhenShown = true
return
if @measureLineHeightInPixelsAndCharWidthWhenShown and @state.visible and not prevState.visible
@measureLineHeightInPixelsAndCharWidth()
measureLineHeightInPixelsAndCharWidth: ->
@measureLineHeightInPixelsAndCharWidthWhenShown = false
@refs.lines.measureLineHeightInPixelsAndCharWidth()
measureScrollbars: ->
@measuringScrollbars = false

View File

@@ -13,8 +13,6 @@ module.exports =
LinesComponent = React.createClass
displayName: 'LinesComponent'
measureWhenShown: false
render: ->
if @isMounted()
{editor, selectionScreenRanges, scrollTop, scrollLeft, scrollHeight, scrollWidth, lineHeightInPixels, scrollViewHeight} = @props
@@ -37,9 +35,9 @@ LinesComponent = React.createClass
shouldComponentUpdate: (newProps) ->
return true unless isEqualForProperties(newProps, @props,
'renderedRowRange', 'selectionScreenRanges', 'fontSize', 'fontFamily', 'lineHeight',
'lineHeightInPixels', 'scrollTop', 'scrollLeft', 'showIndentGuide', 'scrollingVertically',
'invisibles', 'visible', 'scrollViewHeight', 'mouseWheelScreenRow'
'renderedRowRange', 'selectionScreenRanges', 'lineHeightInPixels', 'defaultCharWidth',
'scrollTop', 'scrollLeft', 'showIndentGuide', 'scrollingVertically', 'invisibles', 'visible',
'scrollViewHeight', 'mouseWheelScreenRow'
)
{renderedRowRange, pendingChanges} = newProps
@@ -52,11 +50,9 @@ LinesComponent = React.createClass
componentDidUpdate: (prevProps) ->
{visible, scrollingVertically} = @props
@measureLineHeightInPixelsAndCharWidthIfNeeded(prevProps)
@clearScreenRowCaches() unless prevProps.lineHeightInPixels is @props.lineHeightInPixels
@removeLineNodes() unless isEqualForProperties(prevProps, @props, 'showIndentGuide', 'invisibles')
@updateLines()
@clearScopedCharWidths() unless isEqualForProperties(prevProps, @props, 'fontSize', 'fontFamily')
@measureCharactersInNewLines() if visible and not scrollingVertically
clearScreenRowCaches: ->
@@ -204,16 +200,6 @@ LinesComponent = React.createClass
lineNodeForScreenRow: (screenRow) ->
@lineNodesByLineId[@lineIdsByScreenRow[screenRow]]
measureLineHeightInPixelsAndCharWidthIfNeeded: (prevProps) ->
{visible} = @props
unless isEqualForProperties(prevProps, @props, 'fontSize', 'fontFamily', 'lineHeight')
if visible
@measureLineHeightInPixelsAndCharWidth()
else
@measureWhenShown = true
@measureLineHeightInPixelsAndCharWidth() if visible and not prevProps.visible and @measureWhenShown
measureLineHeightInPixelsAndCharWidth: ->
@measureWhenShown = false
node = @getDOMNode()