mirror of
https://github.com/atom/atom.git
synced 2026-01-22 21:38:10 -05:00
Merge pull request #2681 from atom/ns-react-batch-updates
Batch all editor updates together automatically via process.nextTick
This commit is contained in:
@@ -89,7 +89,7 @@
|
||||
"image-view": "0.35.0",
|
||||
"keybinding-resolver": "0.18.0",
|
||||
"link": "0.24.0",
|
||||
"markdown-preview": "0.82.0",
|
||||
"markdown-preview": "0.83.0",
|
||||
"metrics": "0.32.0",
|
||||
"open-on-github": "0.28.0",
|
||||
"package-generator": "0.31.0",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,7 @@ Project = require '../src/project'
|
||||
Editor = require '../src/editor'
|
||||
EditorView = require '../src/editor-view'
|
||||
TokenizedBuffer = require '../src/tokenized-buffer'
|
||||
EditorComponent = require '../src/editor-component'
|
||||
pathwatcher = require 'pathwatcher'
|
||||
clipboard = require 'clipboard'
|
||||
|
||||
@@ -100,6 +101,8 @@ beforeEach ->
|
||||
|
||||
# make editor display updates synchronous
|
||||
spyOn(EditorView.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
|
||||
EditorComponent.performSyncUpdates = true
|
||||
|
||||
spyOn(WorkspaceView.prototype, 'setTitle').andCallFake (@title) ->
|
||||
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
|
||||
spyOn(window, "clearTimeout").andCallFake window.fakeClearTimeout
|
||||
|
||||
@@ -17,10 +17,12 @@ EditorComponent = React.createClass
|
||||
displayName: 'EditorComponent'
|
||||
mixins: [SubscriberMixin]
|
||||
|
||||
statics:
|
||||
performSyncUpdates: false
|
||||
|
||||
pendingScrollTop: null
|
||||
pendingScrollLeft: null
|
||||
selectOnMouseMove: false
|
||||
batchingUpdates: false
|
||||
updateRequested: false
|
||||
cursorsMoved: false
|
||||
selectionChanged: false
|
||||
@@ -168,10 +170,9 @@ EditorComponent = React.createClass
|
||||
|
||||
editor.setVisible(true)
|
||||
|
||||
editor.batchUpdates =>
|
||||
@measureLineHeightAndDefaultCharWidth()
|
||||
@measureScrollView()
|
||||
@measureScrollbars()
|
||||
@measureLineHeightAndDefaultCharWidth()
|
||||
@measureScrollView()
|
||||
@measureScrollbars()
|
||||
|
||||
componentWillUnmount: ->
|
||||
@unsubscribe()
|
||||
@@ -179,24 +180,33 @@ EditorComponent = React.createClass
|
||||
@scrollViewMeasurementIntervalId = null
|
||||
|
||||
componentWillUpdate: ->
|
||||
if @props.editor.isAlive()
|
||||
@props.parentView.trigger 'cursor:moved' if @cursorsMoved
|
||||
@props.parentView.trigger 'selection:changed' if @selectionChanged
|
||||
|
||||
componentDidUpdate: (prevProps, prevState) ->
|
||||
cursorsMoved = @cursorsMoved
|
||||
selectionChanged = @selectionChanged
|
||||
@pendingChanges.length = 0
|
||||
@cursorsMoved = false
|
||||
@selectionChanged = false
|
||||
@refreshingScrollbars = false
|
||||
@updateParentViewFocusedClassIfNeeded(prevState)
|
||||
|
||||
if @props.editor.isAlive()
|
||||
@updateParentViewFocusedClassIfNeeded(prevState)
|
||||
@props.parentView.trigger 'cursor:moved' if cursorsMoved
|
||||
@props.parentView.trigger 'selection:changed' if selectionChanged
|
||||
@props.parentView.trigger 'editor:display-updated'
|
||||
|
||||
@measureScrollbars() if @measuringScrollbars
|
||||
@measureLineHeightAndCharWidthsIfNeeded(prevState)
|
||||
@remeasureCharacterWidthsIfNeeded(prevState)
|
||||
@props.parentView.trigger 'editor:display-updated'
|
||||
|
||||
requestUpdate: ->
|
||||
if @batchingUpdates
|
||||
@updateRequested = true
|
||||
else
|
||||
if @performSyncUpdates ? EditorComponent.performSyncUpdates
|
||||
@forceUpdate()
|
||||
else unless @updateRequested
|
||||
@updateRequested = true
|
||||
process.nextTick =>
|
||||
@updateRequested = false
|
||||
@forceUpdate() if @isMounted()
|
||||
|
||||
getRenderedRowRange: ->
|
||||
{editor, lineOverdrawMargin} = @props
|
||||
@@ -263,8 +273,6 @@ EditorComponent = React.createClass
|
||||
|
||||
observeEditor: ->
|
||||
{editor} = @props
|
||||
@subscribe editor, 'batched-updates-started', @onBatchedUpdatesStarted
|
||||
@subscribe editor, 'batched-updates-ended', @onBatchedUpdatesEnded
|
||||
@subscribe editor, 'screen-lines-changed', @onScreenLinesChanged
|
||||
@subscribe editor, 'cursors-moved', @onCursorsMoved
|
||||
@subscribe editor, 'selection-removed selection-screen-range-changed', @onSelectionChanged
|
||||
@@ -586,16 +594,6 @@ EditorComponent = React.createClass
|
||||
onStylesheetsChanged: (stylesheet) ->
|
||||
@refreshScrollbars() if @containsScrollbarSelector(stylesheet)
|
||||
|
||||
onBatchedUpdatesStarted: ->
|
||||
@batchingUpdates = true
|
||||
|
||||
onBatchedUpdatesEnded: ->
|
||||
updateRequested = @updateRequested
|
||||
@updateRequested = false
|
||||
@batchingUpdates = false
|
||||
if updateRequested
|
||||
@requestUpdate()
|
||||
|
||||
onScreenLinesChanged: (change) ->
|
||||
{editor} = @props
|
||||
@pendingChanges.push(change)
|
||||
@@ -634,9 +632,7 @@ EditorComponent = React.createClass
|
||||
@requestUpdate()
|
||||
|
||||
onDecorationChanged: ->
|
||||
@decorationChangedImmediate ?= setImmediate =>
|
||||
@requestUpdate() if @isMounted()
|
||||
@decorationChangedImmediate = null
|
||||
@requestUpdate()
|
||||
|
||||
onCharacterWidthsChanged: (@scopedCharacterWidthsChangeCount) ->
|
||||
@requestUpdate()
|
||||
@@ -694,14 +690,13 @@ EditorComponent = React.createClass
|
||||
{position} = getComputedStyle(editorNode)
|
||||
{width, height} = editorNode.style
|
||||
|
||||
editor.batchUpdates ->
|
||||
if position is 'absolute' or height
|
||||
clientHeight = scrollViewNode.clientHeight
|
||||
editor.setHeight(clientHeight) if clientHeight > 0
|
||||
if position is 'absolute' or height
|
||||
clientHeight = scrollViewNode.clientHeight
|
||||
editor.setHeight(clientHeight) if clientHeight > 0
|
||||
|
||||
if position is 'absolute' or width
|
||||
clientWidth = scrollViewNode.clientWidth
|
||||
editor.setWidth(clientWidth) if clientWidth > 0
|
||||
if position is 'absolute' or width
|
||||
clientWidth = scrollViewNode.clientWidth
|
||||
editor.setWidth(clientWidth) if clientWidth > 0
|
||||
|
||||
measureLineHeightAndCharWidthsIfNeeded: (prevState) ->
|
||||
if not isEqualForProperties(prevState, @state, 'lineHeight', 'fontSize', 'fontFamily')
|
||||
@@ -756,17 +751,17 @@ EditorComponent = React.createClass
|
||||
# visible, so first we need to hide scrollbars so we can redisplay them and
|
||||
# force Chromium to apply updates.
|
||||
@refreshingScrollbars = true
|
||||
@requestUpdate()
|
||||
@forceUpdate()
|
||||
|
||||
# Next, we display only the scrollbar corner so we can measure the new
|
||||
# scrollbar dimensions. The ::measuringScrollbars property will be set back
|
||||
# to false after the scrollbars are measured.
|
||||
@measuringScrollbars = true
|
||||
@requestUpdate()
|
||||
@forceUpdate()
|
||||
|
||||
# Finally, we restore the scrollbars based on the newly-measured dimensions
|
||||
# if the editor's content and dimensions require them to be visible.
|
||||
@requestUpdate()
|
||||
@forceUpdate()
|
||||
|
||||
clearMouseWheelScreenRow: ->
|
||||
if @mouseWheelScreenRow?
|
||||
|
||||
@@ -1601,11 +1601,10 @@ class Editor extends Model
|
||||
|
||||
moveCursors: (fn) ->
|
||||
@movingCursors = true
|
||||
@batchUpdates =>
|
||||
fn(cursor) for cursor in @getCursors()
|
||||
@mergeCursors()
|
||||
@movingCursors = false
|
||||
@emit 'cursors-moved'
|
||||
fn(cursor) for cursor in @getCursors()
|
||||
@mergeCursors()
|
||||
@movingCursors = false
|
||||
@emit 'cursors-moved'
|
||||
|
||||
cursorMoved: (event) ->
|
||||
@emit 'cursor-moved', event
|
||||
@@ -1925,9 +1924,7 @@ class Editor extends Model
|
||||
# execution and revert any changes performed up to the abortion.
|
||||
#
|
||||
# fn - A {Function} to call inside the transaction.
|
||||
transact: (fn) ->
|
||||
@batchUpdates =>
|
||||
@buffer.transact(fn)
|
||||
transact: (fn) -> @buffer.transact(fn)
|
||||
|
||||
# Public: Start an open-ended transaction.
|
||||
#
|
||||
@@ -1947,14 +1944,6 @@ class Editor extends Model
|
||||
# within the transaction.
|
||||
abortTransaction: -> @buffer.abortTransaction()
|
||||
|
||||
batchUpdates: (fn) ->
|
||||
@emit 'batched-updates-started' if @updateBatchDepth is 0
|
||||
@updateBatchDepth++
|
||||
result = fn()
|
||||
@updateBatchDepth--
|
||||
@emit 'batched-updates-ended' if @updateBatchDepth is 0
|
||||
result
|
||||
|
||||
inspect: ->
|
||||
"<Editor #{@id}>"
|
||||
|
||||
|
||||
@@ -236,9 +236,8 @@ LinesComponent = React.createClass
|
||||
node.removeChild(DummyLineNode)
|
||||
|
||||
{editor} = @props
|
||||
editor.batchUpdates ->
|
||||
editor.setLineHeightInPixels(lineHeightInPixels)
|
||||
editor.setDefaultCharWidth(charWidth)
|
||||
editor.setLineHeightInPixels(lineHeightInPixels)
|
||||
editor.setDefaultCharWidth(charWidth)
|
||||
|
||||
remeasureCharacterWidths: ->
|
||||
@clearScopedCharWidths()
|
||||
@@ -249,11 +248,10 @@ LinesComponent = React.createClass
|
||||
[visibleStartRow, visibleEndRow] = @props.renderedRowRange
|
||||
node = @getDOMNode()
|
||||
|
||||
editor.batchUpdates =>
|
||||
for tokenizedLine in editor.linesForScreenRows(visibleStartRow, visibleEndRow - 1)
|
||||
unless @measuredLines.has(tokenizedLine)
|
||||
lineNode = @lineNodesByLineId[tokenizedLine.id]
|
||||
@measureCharactersInLine(tokenizedLine, lineNode)
|
||||
for tokenizedLine in editor.linesForScreenRows(visibleStartRow, visibleEndRow - 1)
|
||||
unless @measuredLines.has(tokenizedLine)
|
||||
lineNode = @lineNodesByLineId[tokenizedLine.id]
|
||||
@measureCharactersInLine(tokenizedLine, lineNode)
|
||||
|
||||
measureCharactersInLine: (tokenizedLine, lineNode) ->
|
||||
{editor} = @props
|
||||
|
||||
Reference in New Issue
Block a user