diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index f94881b4d..2cba35f58 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -45,7 +45,14 @@ describe "Editor", -> describe ".copy()", -> it "builds a new editor with the same edit sessions, cursor position, and scroll position as the receiver", -> - editor.setCursorScreenPosition([1, 1]) + rootView.attachToDom() + rootView.height(8 * editor.lineHeight) + rootView.width(50 * editor.charWidth) + + editor.setCursorScreenPosition([5, 20]) + advanceClock() + editor.verticalScrollbar.scrollTop(1.5 * editor.lineHeight) + editor.scrollView.scrollLeft(44) # prove this test covers serialization and deserialization spyOn(editor, 'serialize').andCallThrough() @@ -54,12 +61,21 @@ describe "Editor", -> newEditor = editor.copy() expect(editor.serialize).toHaveBeenCalled() expect(Editor.deserialize).toHaveBeenCalled() + expect(newEditor.buffer).toBe editor.buffer expect(newEditor.getCursorScreenPosition()).toEqual editor.getCursorScreenPosition() - expect(newEditor.editSessions[0]).toEqual(editor.editSessions[0]) expect(newEditor.editSessions[0]).not.toBe(editor.editSessions[0]) + newEditor.height(editor.height()) + newEditor.width(editor.width()) + rootView.remove() + newEditor.attachToDom() + advanceClock() # ensure any deferred scrollTo code completes (this was causing a regression) + expect(newEditor.verticalScrollbar.scrollTop()).toBe 1.5 * editor.lineHeight + expect(newEditor.lines.css('padding-top')).toBe "#{editor.lineHeight}px" + expect(newEditor.scrollView.scrollLeft()).toBe 44 + describe ".setBuffer(buffer)", -> it "sets the cursor to the beginning of the file", -> expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 289235690..ffdba9736 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -232,9 +232,15 @@ class Editor extends View @attached = true @subscribeToFontSize() @calculateDimensions() - @renderLines() - @hiddenInput.width(@charWidth) @setMaxLineLength() if @softWrap + @prepareForVerticalScrolling() + @setScrollPositionFromActiveEditSession() + @renderLines() + # TODO: The redundant assignment of scrollLeft below is needed because the lines weren't render + # rendered when we called setScrollPositionFromActiveEditSession above. Remove this when we fix + # that problem by setting the width of the lines container based on the max line width + @scrollView.scrollLeft(@getActiveEditSession().scrollLeft ? 0) + @hiddenInput.width(@charWidth) @focus() if @isFocused @trigger 'editor-open', [this] @@ -250,18 +256,22 @@ class Editor extends View @compositeSelection.mergeIntersectingSelections({reverse}) @syncCursorAnimations() + prepareForVerticalScrolling: -> + linesHeight = @lineHeight * @screenLineCount() + @verticalScrollbarContent.height(linesHeight) + @lines.css('padding-bottom', linesHeight) + renderLines: -> @lineCache = [] @lines.find('.line').remove() - @firstRenderedScreenRow = 0 + @firstRenderedScreenRow = @getFirstVisibleScreenRow() @lastRenderedScreenRow = @getLastVisibleScreenRow() @insertLineElements(0, @buildLineElements(@firstRenderedScreenRow, @lastRenderedScreenRow)) + @lines.css('padding-top', @firstRenderedScreenRow * @lineHeight) @lines.css('padding-bottom', (@getLastScreenRow() - @lastRenderedScreenRow) * @lineHeight) - @verticalScrollbarContent.height(@lineHeight * @screenLineCount()) - updateLines: -> firstVisibleScreenRow = @getFirstVisibleScreenRow() lastVisibleScreenRow = @getLastVisibleScreenRow() @@ -355,10 +365,18 @@ class Editor extends View editSession = @editSessions[index] throw new Error("Edit session not found") unless editSession @setBuffer(editSession.buffer) unless @buffer == editSession.buffer + @activeEditSessionIndex = index + @setScrollPositionFromActiveEditSession() if @attached @setCursorScreenPosition(editSession.cursorScreenPosition ? [0, 0]) + + getActiveEditSession: -> + @editSessions[@activeEditSessionIndex] + + setScrollPositionFromActiveEditSession: -> + editSession = @getActiveEditSession() @verticalScrollbar.scrollTop(editSession.scrollTop ? 0) @scrollView.scrollLeft(editSession.scrollLeft ? 0) - @activeEditSessionIndex = index + @verticalScrollbar.trigger 'scroll' saveCurrentEditSession: -> @editSessions[@activeEditSessionIndex] = @@ -657,6 +675,7 @@ class Editor extends View @buffer.getMode() scrollTo: (pixelPosition) -> + return unless @attached _.defer => # Optimization @scrollVertically(pixelPosition) @scrollHorizontally(pixelPosition)