From 29653980622cfdb2e343c40aa404d2ed3bbb0d8d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 27 Oct 2014 07:38:18 -0600 Subject: [PATCH] Throw on non-release builds if translating positions on destroyed editor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s possible that bundled packages stray into this corner case, so I’d like us to catch and fix misbehaving packages before exposing users to any exceptions. Once we go one release with this turned on, we can enable the exception for all builds. --- src/display-buffer.coffee | 6 +++++- src/text-editor-component.coffee | 15 ++++++++++----- src/text-editor-element.coffee | 2 ++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index e6ae12aa1..a2b9a0bfc 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -736,6 +736,10 @@ class DisplayBuffer extends Model # # Returns a {Point}. screenPositionForBufferPosition: (bufferPosition, options) -> + # TODO: Expand this exception to cover all versions once we burn it in on non-release builds + if @isDestroyed() and not atom.isReleasedVersion() + throw new Error("This TextEditor has been destroyed") + { row, column } = @buffer.clipPosition(bufferPosition) [startScreenRow, endScreenRow] = @rowMap.screenRowRangeForBufferRow(row) for screenRow in [startScreenRow...endScreenRow] @@ -1073,7 +1077,7 @@ class DisplayBuffer extends Model marker.notifyObservers(textChanged: false) destroyed: -> - marker.unsubscribe() for marker in @getMarkers() + marker.unsubscribe() for id, marker of @markers @tokenizedBuffer.destroy() @unsubscribe() diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 63fe4d89f..4b5d23cb4 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -55,6 +55,8 @@ TextEditorComponent = React.createClass hasSelection = editor.getLastSelection()? and !editor.getLastSelection().isEmpty() style = {} + @performedInitialMeasurement = false if editor.isDestroyed() + if @performedInitialMeasurement renderedRowRange = @getRenderedRowRange() [renderedStartRow, renderedEndRow] = renderedRowRange @@ -227,10 +229,10 @@ TextEditorComponent = React.createClass @props.editor.setVisible(true) @performedInitialMeasurement = true @updatesPaused = false - @forceUpdate() if @updateRequestedWhilePaused + @forceUpdate() if @updateRequestedWhilePaused and @canUpdate() requestUpdate: -> - return unless @isMounted() + return unless @canUpdate() if @updatesPaused @updateRequestedWhilePaused = true @@ -242,7 +244,10 @@ TextEditorComponent = React.createClass @updateRequested = true requestAnimationFrame => @updateRequested = false - @forceUpdate() if @isMounted() + @forceUpdate() if @canUpdate() + + canUpdate: -> + @isMounted() and @props.editor.isAlive() requestAnimationFrame: (fn) -> @updatesPaused = true @@ -250,7 +255,7 @@ TextEditorComponent = React.createClass requestAnimationFrame => fn() @updatesPaused = false - if @updateRequestedWhilePaused and @isMounted() + if @updateRequestedWhilePaused and @canUpdate() @updateRequestedWhilePaused = false @forceUpdate() @@ -773,7 +778,7 @@ TextEditorComponent = React.createClass if position is 'absolute' or height if @autoHeight @autoHeight = false - @forceUpdate() unless @updatesPaused + @forceUpdate() if not @updatesPaused and @canUpdate() clientHeight = scrollViewNode.clientHeight editor.setHeight(clientHeight) if clientHeight > 0 diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 8de2bd2d7..3313e3718 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -37,6 +37,8 @@ class TextEditorElement extends HTMLElement setModel: (model) -> throw new Error("Model already assigned on TextEditorElement") if @model? + return if model.isDestroyed() + @model = model @mountComponent() @addGrammarScopeAttribute()