mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2025-01-08 08:07:32 +03:00
🐎 Cache gutterVisible state in React component
This avoids a config read on every render.
This commit is contained in:
parent
f00b0b7f7a
commit
002918049d
@ -561,12 +561,12 @@ describe "TextEditorComponent", ->
|
|||||||
expect(component.refs.gutter?).toBe false
|
expect(component.refs.gutter?).toBe false
|
||||||
|
|
||||||
atom.config.set("editor.showLineNumbers", false)
|
atom.config.set("editor.showLineNumbers", false)
|
||||||
nextAnimationFrame()
|
expect(nextAnimationFrame).toBe noAnimationFrame
|
||||||
|
|
||||||
expect(component.refs.gutter?).toBe false
|
expect(component.refs.gutter?).toBe false
|
||||||
|
|
||||||
editor.setGutterVisible(true)
|
editor.setGutterVisible(true)
|
||||||
nextAnimationFrame()
|
expect(nextAnimationFrame).toBe noAnimationFrame
|
||||||
|
|
||||||
expect(component.refs.gutter?).toBe false
|
expect(component.refs.gutter?).toBe false
|
||||||
|
|
||||||
@ -2517,7 +2517,8 @@ describe "TextEditorComponent", ->
|
|||||||
|
|
||||||
describe "when the 'mini' property is true", ->
|
describe "when the 'mini' property is true", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
component.setProps(mini: true)
|
editor.setMini(true)
|
||||||
|
nextAnimationFrame()
|
||||||
|
|
||||||
it "does not render the gutter", ->
|
it "does not render the gutter", ->
|
||||||
expect(componentNode.querySelector('.gutter')).toBeNull()
|
expect(componentNode.querySelector('.gutter')).toBeNull()
|
||||||
|
@ -23,12 +23,12 @@ LinesComponent = React.createClass
|
|||||||
if performedInitialMeasurement
|
if performedInitialMeasurement
|
||||||
{editor, overlayDecorations, highlightDecorations, scrollHeight, scrollWidth, placeholderText, backgroundColor} = @props
|
{editor, overlayDecorations, highlightDecorations, scrollHeight, scrollWidth, placeholderText, backgroundColor} = @props
|
||||||
{lineHeightInPixels, defaultCharWidth, scrollViewHeight, scopedCharacterWidthsChangeCount} = @props
|
{lineHeightInPixels, defaultCharWidth, scrollViewHeight, scopedCharacterWidthsChangeCount} = @props
|
||||||
{scrollTop, scrollLeft, cursorPixelRects, mini} = @props
|
{scrollTop, scrollLeft, cursorPixelRects} = @props
|
||||||
style =
|
style =
|
||||||
height: Math.max(scrollHeight, scrollViewHeight)
|
height: Math.max(scrollHeight, scrollViewHeight)
|
||||||
width: scrollWidth
|
width: scrollWidth
|
||||||
WebkitTransform: @getTransform()
|
WebkitTransform: @getTransform()
|
||||||
backgroundColor: if mini then null else backgroundColor
|
backgroundColor: if editor.isMini() then null else backgroundColor
|
||||||
|
|
||||||
div {className: 'lines', style},
|
div {className: 'lines', style},
|
||||||
div className: 'placeholder-text', placeholderText if placeholderText?
|
div className: 'placeholder-text', placeholderText if placeholderText?
|
||||||
@ -162,7 +162,7 @@ LinesComponent = React.createClass
|
|||||||
@lineNodesByLineId.hasOwnProperty(lineId)
|
@lineNodesByLineId.hasOwnProperty(lineId)
|
||||||
|
|
||||||
buildLineHTML: (line, screenRow) ->
|
buildLineHTML: (line, screenRow) ->
|
||||||
{mini, showIndentGuide, lineHeightInPixels, lineDecorations, lineWidth} = @props
|
{showIndentGuide, lineHeightInPixels, lineDecorations, lineWidth} = @props
|
||||||
{tokens, text, lineEnding, fold, isSoftWrapped, indentLevel} = line
|
{tokens, text, lineEnding, fold, isSoftWrapped, indentLevel} = line
|
||||||
|
|
||||||
classes = ''
|
classes = ''
|
||||||
@ -208,7 +208,7 @@ LinesComponent = React.createClass
|
|||||||
@buildEndOfLineHTML(line) or ' '
|
@buildEndOfLineHTML(line) or ' '
|
||||||
|
|
||||||
buildLineInnerHTML: (line) ->
|
buildLineInnerHTML: (line) ->
|
||||||
{mini, showIndentGuide} = @props
|
{editor, showIndentGuide} = @props
|
||||||
{tokens, text} = line
|
{tokens, text} = line
|
||||||
innerHTML = ""
|
innerHTML = ""
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ LinesComponent = React.createClass
|
|||||||
lineIsWhitespaceOnly = firstTrailingWhitespacePosition is 0
|
lineIsWhitespaceOnly = firstTrailingWhitespacePosition is 0
|
||||||
for token in tokens
|
for token in tokens
|
||||||
innerHTML += @updateScopeStack(scopeStack, token.scopes)
|
innerHTML += @updateScopeStack(scopeStack, token.scopes)
|
||||||
hasIndentGuide = not mini and showIndentGuide and (token.hasLeadingWhitespace() or (token.hasTrailingWhitespace() and lineIsWhitespaceOnly))
|
hasIndentGuide = not editor.isMini() and showIndentGuide and (token.hasLeadingWhitespace() or (token.hasTrailingWhitespace() and lineIsWhitespaceOnly))
|
||||||
innerHTML += token.getValueAsHtml({hasIndentGuide})
|
innerHTML += token.getValueAsHtml({hasIndentGuide})
|
||||||
|
|
||||||
innerHTML += @popScope(scopeStack) while scopeStack.length > 0
|
innerHTML += @popScope(scopeStack) while scopeStack.length > 0
|
||||||
|
@ -48,7 +48,7 @@ TextEditorComponent = React.createClass
|
|||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
{focused, showIndentGuide, showLineNumbers, visible} = @state
|
{focused, showIndentGuide, showLineNumbers, visible} = @state
|
||||||
{editor, mini, cursorBlinkPeriod, cursorBlinkResumeDelay, hostElement, useShadowDOM} = @props
|
{editor, cursorBlinkPeriod, cursorBlinkResumeDelay, hostElement, useShadowDOM} = @props
|
||||||
maxLineNumberDigits = editor.getLineCount().toString().length
|
maxLineNumberDigits = editor.getLineCount().toString().length
|
||||||
hasSelection = editor.getLastSelection()? and !editor.getLastSelection().isEmpty()
|
hasSelection = editor.getLastSelection()? and !editor.getLastSelection().isEmpty()
|
||||||
style = {}
|
style = {}
|
||||||
@ -96,7 +96,7 @@ TextEditorComponent = React.createClass
|
|||||||
className += ' has-selection' if hasSelection
|
className += ' has-selection' if hasSelection
|
||||||
|
|
||||||
div {className, style},
|
div {className, style},
|
||||||
if @shouldRenderGutter()
|
if @gutterVisible
|
||||||
GutterComponent {
|
GutterComponent {
|
||||||
ref: 'gutter', onMouseDown: @onGutterMouseDown, lineDecorations,
|
ref: 'gutter', onMouseDown: @onGutterMouseDown, lineDecorations,
|
||||||
defaultCharWidth, editor, renderedRowRange, maxLineNumberDigits, scrollViewHeight,
|
defaultCharWidth, editor, renderedRowRange, maxLineNumberDigits, scrollViewHeight,
|
||||||
@ -118,7 +118,7 @@ TextEditorComponent = React.createClass
|
|||||||
@scrollingVertically, scrollHeight, scrollWidth, mouseWheelScreenRow,
|
@scrollingVertically, scrollHeight, scrollWidth, mouseWheelScreenRow,
|
||||||
visible, scrollViewHeight, @scopedCharacterWidthsChangeCount, lineWidth, @useHardwareAcceleration,
|
visible, scrollViewHeight, @scopedCharacterWidthsChangeCount, lineWidth, @useHardwareAcceleration,
|
||||||
placeholderText, @performedInitialMeasurement, @backgroundColor, cursorPixelRects,
|
placeholderText, @performedInitialMeasurement, @backgroundColor, cursorPixelRects,
|
||||||
cursorBlinkPeriod, cursorBlinkResumeDelay, mini, useShadowDOM
|
cursorBlinkPeriod, cursorBlinkResumeDelay, useShadowDOM
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollbarComponent
|
ScrollbarComponent
|
||||||
@ -159,9 +159,6 @@ TextEditorComponent = React.createClass
|
|||||||
{editor} = @props
|
{editor} = @props
|
||||||
Math.max(1, Math.ceil(editor.getHeight() / editor.getLineHeightInPixels()))
|
Math.max(1, Math.ceil(editor.getHeight() / editor.getLineHeightInPixels()))
|
||||||
|
|
||||||
shouldRenderGutter: ->
|
|
||||||
not @props.mini and @props.editor.isGutterVisible() and atom.config.get('editor.showLineNumbers')
|
|
||||||
|
|
||||||
getInitialState: -> {}
|
getInitialState: -> {}
|
||||||
|
|
||||||
getDefaultProps: ->
|
getDefaultProps: ->
|
||||||
@ -190,7 +187,7 @@ TextEditorComponent = React.createClass
|
|||||||
|
|
||||||
@domPollingIntervalId = setInterval(@pollDOM, @domPollingInterval)
|
@domPollingIntervalId = setInterval(@pollDOM, @domPollingInterval)
|
||||||
@updateParentViewFocusedClassIfNeeded({})
|
@updateParentViewFocusedClassIfNeeded({})
|
||||||
@updateParentViewMiniClassIfNeeded({})
|
@updateParentViewMiniClass()
|
||||||
@checkForVisibilityChange()
|
@checkForVisibilityChange()
|
||||||
|
|
||||||
componentWillUnmount: ->
|
componentWillUnmount: ->
|
||||||
@ -202,9 +199,6 @@ TextEditorComponent = React.createClass
|
|||||||
clearInterval(@domPollingIntervalId)
|
clearInterval(@domPollingIntervalId)
|
||||||
@domPollingIntervalId = null
|
@domPollingIntervalId = null
|
||||||
|
|
||||||
componentWillReceiveProps: (newProps) ->
|
|
||||||
@props.editor.setMini(newProps.mini)
|
|
||||||
|
|
||||||
componentDidUpdate: (prevProps, prevState) ->
|
componentDidUpdate: (prevProps, prevState) ->
|
||||||
cursorMoved = @cursorMoved
|
cursorMoved = @cursorMoved
|
||||||
selectionChanged = @selectionChanged
|
selectionChanged = @selectionChanged
|
||||||
@ -214,7 +208,7 @@ TextEditorComponent = React.createClass
|
|||||||
|
|
||||||
if @props.editor.isAlive()
|
if @props.editor.isAlive()
|
||||||
@updateParentViewFocusedClassIfNeeded(prevState)
|
@updateParentViewFocusedClassIfNeeded(prevState)
|
||||||
@updateParentViewMiniClassIfNeeded(prevState)
|
@updateParentViewMiniClass()
|
||||||
@props.hostElement.__spacePenView.trigger 'cursor:moved' if cursorMoved
|
@props.hostElement.__spacePenView.trigger 'cursor:moved' if cursorMoved
|
||||||
@props.hostElement.__spacePenView.trigger 'selection:changed' if selectionChanged
|
@props.hostElement.__spacePenView.trigger 'selection:changed' if selectionChanged
|
||||||
@props.hostElement.__spacePenView.trigger 'editor:display-updated'
|
@props.hostElement.__spacePenView.trigger 'editor:display-updated'
|
||||||
@ -308,8 +302,8 @@ TextEditorComponent = React.createClass
|
|||||||
cursorPixelRects
|
cursorPixelRects
|
||||||
|
|
||||||
getLineDecorations: (decorationsByMarkerId) ->
|
getLineDecorations: (decorationsByMarkerId) ->
|
||||||
{editor, mini} = @props
|
{editor} = @props
|
||||||
return {} if mini
|
return {} if editor.isMini()
|
||||||
|
|
||||||
decorationsByScreenRow = {}
|
decorationsByScreenRow = {}
|
||||||
for markerId, decorations of decorationsByMarkerId
|
for markerId, decorations of decorationsByMarkerId
|
||||||
@ -377,6 +371,8 @@ TextEditorComponent = React.createClass
|
|||||||
observeEditor: ->
|
observeEditor: ->
|
||||||
{editor} = @props
|
{editor} = @props
|
||||||
@subscribe editor.onDidChange(@onScreenLinesChanged)
|
@subscribe editor.onDidChange(@onScreenLinesChanged)
|
||||||
|
@subscribe editor.onDidChangeGutterVisible(@updateGutterVisible)
|
||||||
|
@subscribe editor.onDidChangeMini(@setMini)
|
||||||
@subscribe editor.observeGrammar(@onGrammarChanged)
|
@subscribe editor.observeGrammar(@onGrammarChanged)
|
||||||
@subscribe editor.observeCursors(@onCursorAdded)
|
@subscribe editor.observeCursors(@onCursorAdded)
|
||||||
@subscribe editor.observeSelections(@onSelectionAdded)
|
@subscribe editor.observeSelections(@onSelectionAdded)
|
||||||
@ -463,8 +459,7 @@ TextEditorComponent = React.createClass
|
|||||||
scopeDescriptor = editor.getRootScopeDescriptor()
|
scopeDescriptor = editor.getRootScopeDescriptor()
|
||||||
|
|
||||||
subscriptions.add atom.config.observe 'editor.showIndentGuide', scope: scopeDescriptor, @setShowIndentGuide
|
subscriptions.add atom.config.observe 'editor.showIndentGuide', scope: scopeDescriptor, @setShowIndentGuide
|
||||||
subscriptions.add atom.config.onDidChange 'editor.showLineNumbers', scope: scopeDescriptor, @requestUpdate
|
subscriptions.add atom.config.observe 'editor.showLineNumbers', scope: scopeDescriptor, @updateGutterVisible
|
||||||
subscriptions.add editor.onDidChangeGutterVisible @requestUpdate
|
|
||||||
subscriptions.add atom.config.observe 'editor.scrollSensitivity', scope: scopeDescriptor, @setScrollSensitivity
|
subscriptions.add atom.config.observe 'editor.scrollSensitivity', scope: scopeDescriptor, @setScrollSensitivity
|
||||||
|
|
||||||
focused: ->
|
focused: ->
|
||||||
@ -882,7 +877,7 @@ TextEditorComponent = React.createClass
|
|||||||
@backgroundColor = backgroundColor
|
@backgroundColor = backgroundColor
|
||||||
@requestUpdate() unless suppressUpdate
|
@requestUpdate() unless suppressUpdate
|
||||||
|
|
||||||
if @shouldRenderGutter()
|
if @refs.gutter?
|
||||||
gutterBackgroundColor = getComputedStyle(@refs.gutter.getDOMNode()).backgroundColor
|
gutterBackgroundColor = getComputedStyle(@refs.gutter.getDOMNode()).backgroundColor
|
||||||
if gutterBackgroundColor isnt @gutterBackgroundColor
|
if gutterBackgroundColor isnt @gutterBackgroundColor
|
||||||
@gutterBackgroundColor = gutterBackgroundColor
|
@gutterBackgroundColor = gutterBackgroundColor
|
||||||
@ -1002,6 +997,16 @@ TextEditorComponent = React.createClass
|
|||||||
setShowIndentGuide: (showIndentGuide) ->
|
setShowIndentGuide: (showIndentGuide) ->
|
||||||
@setState({showIndentGuide})
|
@setState({showIndentGuide})
|
||||||
|
|
||||||
|
setMini: ->
|
||||||
|
@updateGutterVisible()
|
||||||
|
@requestUpdate()
|
||||||
|
|
||||||
|
updateGutterVisible: ->
|
||||||
|
gutterVisible = not @props.editor.isMini() and @props.editor.isGutterVisible() and atom.config.get('editor.showLineNumbers')
|
||||||
|
if gutterVisible isnt @gutterVisible
|
||||||
|
@gutterVisible = gutterVisible
|
||||||
|
@requestUpdate()
|
||||||
|
|
||||||
# Deprecated
|
# Deprecated
|
||||||
setInvisibles: (invisibles={}) ->
|
setInvisibles: (invisibles={}) ->
|
||||||
grim.deprecate "Use config.set('editor.invisibles', invisibles) instead"
|
grim.deprecate "Use config.set('editor.invisibles', invisibles) instead"
|
||||||
@ -1045,10 +1050,9 @@ TextEditorComponent = React.createClass
|
|||||||
@props.hostElement.classList.toggle('is-focused', @state.focused)
|
@props.hostElement.classList.toggle('is-focused', @state.focused)
|
||||||
@props.rootElement.classList.toggle('is-focused', @state.focused)
|
@props.rootElement.classList.toggle('is-focused', @state.focused)
|
||||||
|
|
||||||
updateParentViewMiniClassIfNeeded: (prevProps) ->
|
updateParentViewMiniClass: ->
|
||||||
if prevProps.mini isnt @props.mini
|
@props.hostElement.classList.toggle('mini', @props.editor.isMini())
|
||||||
@props.hostElement.classList.toggle('mini', @props.mini)
|
@props.rootElement.classList.toggle('mini', @props.editor.isMini())
|
||||||
@props.rootElement.classList.toggle('mini', @props.mini)
|
|
||||||
|
|
||||||
runScrollBenchmark: ->
|
runScrollBenchmark: ->
|
||||||
unless process.env.NODE_ENV is 'production'
|
unless process.env.NODE_ENV is 'production'
|
||||||
|
@ -109,7 +109,6 @@ class TextEditorElement extends HTMLElement
|
|||||||
rootElement: @rootElement
|
rootElement: @rootElement
|
||||||
stylesElement: @stylesElement
|
stylesElement: @stylesElement
|
||||||
editor: @model
|
editor: @model
|
||||||
mini: @model.mini
|
|
||||||
lineOverdrawMargin: @lineOverdrawMargin
|
lineOverdrawMargin: @lineOverdrawMargin
|
||||||
useShadowDOM: @useShadowDOM
|
useShadowDOM: @useShadowDOM
|
||||||
)
|
)
|
||||||
|
@ -533,9 +533,14 @@ class TextEditor extends Model
|
|||||||
if mini isnt @mini
|
if mini isnt @mini
|
||||||
@mini = mini
|
@mini = mini
|
||||||
@updateInvisibles()
|
@updateInvisibles()
|
||||||
|
@emitter.emit 'did-change-mini', @mini
|
||||||
|
@mini
|
||||||
|
|
||||||
isMini: -> @mini
|
isMini: -> @mini
|
||||||
|
|
||||||
|
onDidChangeMini: (callback) ->
|
||||||
|
@emitter.on 'did-change-mini', callback
|
||||||
|
|
||||||
setGutterVisible: (gutterVisible) ->
|
setGutterVisible: (gutterVisible) ->
|
||||||
unless gutterVisible is @gutterVisible
|
unless gutterVisible is @gutterVisible
|
||||||
@gutterVisible = gutterVisible
|
@gutterVisible = gutterVisible
|
||||||
|
Loading…
Reference in New Issue
Block a user