mirror of
https://github.com/atom/atom.git
synced 2026-01-25 23:08:18 -05:00
WIP: Redoing overdraw code… it's broken
This commit is contained in:
@@ -8,7 +8,7 @@ $ = require 'jquery'
|
||||
_ = require 'underscore'
|
||||
fs = require 'fs'
|
||||
|
||||
describe "Editor", ->
|
||||
fdescribe "Editor", ->
|
||||
[rootView, buffer, editor, cachedLineHeight] = []
|
||||
|
||||
getLineHeight = ->
|
||||
@@ -30,6 +30,7 @@ describe "Editor", ->
|
||||
this.height(getLineHeight() * heightInLines)
|
||||
$('#jasmine-content').append(this)
|
||||
|
||||
editor.lineOverdraw = 2
|
||||
editor.autoIndent = false
|
||||
editor.enableKeymap()
|
||||
editor.isFocused = true
|
||||
@@ -72,7 +73,6 @@ describe "Editor", ->
|
||||
rootView.remove()
|
||||
newEditor.attachToDom()
|
||||
expect(newEditor.scrollTop()).toBe 1.5 * editor.lineHeight
|
||||
expect(newEditor.visibleLines.css('padding-top')).toBe "#{editor.lineHeight}px"
|
||||
expect(newEditor.scrollView.scrollLeft()).toBe 44
|
||||
|
||||
describe ".setBuffer(buffer)", ->
|
||||
@@ -339,7 +339,7 @@ describe "Editor", ->
|
||||
editor.simulateDomAttachment()
|
||||
expect(openHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe "text rendering", ->
|
||||
ffdescribe "text rendering", ->
|
||||
describe "when all lines in the buffer are visible on screen", ->
|
||||
beforeEach ->
|
||||
editor.attachToDom()
|
||||
@@ -465,10 +465,10 @@ describe "Editor", ->
|
||||
|
||||
describe "when the editor is attached and some lines at the end of the buffer are not visible on screen", ->
|
||||
beforeEach ->
|
||||
editor.lineOverdraw = 2
|
||||
editor.attachToDom(heightInLines: 5.5)
|
||||
console.log "--------------------"
|
||||
|
||||
fit "only renders the visible lines plus the overdrawn lines, setting the padding-bottom of the lines element to account for the missing lines", ->
|
||||
it "only renders the visible lines plus the overdrawn lines, setting the padding-bottom of the lines element to account for the missing lines", ->
|
||||
expect(editor.visibleLines.find('.line').length).toBe 8
|
||||
expectedPaddingBottom = (buffer.numLines() - 8) * editor.lineHeight
|
||||
expect(editor.visibleLines.css('padding-bottom')).toBe "#{expectedPaddingBottom}px"
|
||||
@@ -477,7 +477,7 @@ describe "Editor", ->
|
||||
|
||||
describe "when scrolling vertically", ->
|
||||
describe "whes scrolling less than the editor's height", ->
|
||||
fit "draws new lines and removes old lines when the last visible line will exceed the last rendered line", ->
|
||||
it "draws new lines and removes old lines when the last visible line will exceed the last rendered line", ->
|
||||
editor.scrollTop(editor.lineHeight * 1.5)
|
||||
expect(editor.visibleLines.find('.line').length).toBe 8
|
||||
expect(editor.visibleLines.find('.line:first').text()).toBe buffer.lineForRow(0)
|
||||
@@ -504,7 +504,7 @@ describe "Editor", ->
|
||||
expect(editor.visibleLines.find('.line:last').text()).toBe buffer.lineForRow(7)
|
||||
|
||||
describe "when scrolling more than the editors height", ->
|
||||
fit "removes lines that are offscreen and not in range of the overdraw and builds lines that become visible", ->
|
||||
it "removes lines that are offscreen and not in range of the overdraw and builds lines that become visible", ->
|
||||
editor.scrollTop(editor.scrollView.prop('scrollHeight') - editor.scrollView.height())
|
||||
expect(editor.visibleLines.find('.line').length).toBe 8
|
||||
expect(editor.visibleLines.find('.line:first').text()).toBe buffer.lineForRow(5)
|
||||
@@ -516,58 +516,69 @@ describe "Editor", ->
|
||||
expect(editor.visibleLines.find('.line:first').text()).toBe buffer.lineForRow(0)
|
||||
expect(editor.visibleLines.find('.line:last').text()).toBe buffer.lineForRow(7)
|
||||
|
||||
fit "adjusts the vertical padding of the lines element to account for non-rendered lines", ->
|
||||
editor.scrollTop(editor.lineHeight * 2.5)
|
||||
# first visible row is 2, first rendered is 0
|
||||
expect(editor.visibleLines.css('padding-top')).toBe "0px"
|
||||
expectedPaddingBottom = (buffer.numLines() - 8) * editor.lineHeight
|
||||
it "adjusts the vertical padding of the lines element to account for non-rendered lines", ->
|
||||
editor.scrollTop(editor.lineHeight * 3)
|
||||
firstVisibleBufferRow = 3
|
||||
expectedPaddingTop = (firstVisibleBufferRow - editor.lineOverdraw) * editor.lineHeight
|
||||
expect(editor.visibleLines.css('padding-top')).toBe "#{expectedPaddingTop}px"
|
||||
|
||||
lastVisibleBufferRow = Math.ceil(3 + 5.5) # scroll top in lines + height in lines
|
||||
lastOverdrawnRow = lastVisibleBufferRow + editor.lineOverdraw
|
||||
expectedPaddingBottom = ((buffer.numLines() - lastOverdrawnRow) * editor.lineHeight)
|
||||
expect(editor.visibleLines.css('padding-bottom')).toBe "#{expectedPaddingBottom}px"
|
||||
|
||||
editor.scrollTop(editor.scrollView.prop('scrollHeight') - editor.scrollView.height())
|
||||
editor.scrollToBottom()
|
||||
# scrolled to bottom, first visible row is 5 and first rendered row is 3
|
||||
expect(editor.visibleLines.css('padding-top')).toBe "#{3 * editor.lineHeight}px"
|
||||
firstVisibleBufferRow = Math.floor(buffer.numLines() - 5.5)
|
||||
firstOverdrawnBufferRow = firstVisibleBufferRow - editor.lineOverdraw
|
||||
expectedPaddingTop = firstOverdrawnBufferRow * editor.lineHeight
|
||||
expect(editor.visibleLines.css('padding-top')).toBe "#{expectedPaddingTop}px"
|
||||
expect(editor.visibleLines.css('padding-bottom')).toBe "0px"
|
||||
|
||||
it "renders additional lines when the editor is resized", ->
|
||||
setEditorHeightInLines(editor, 10)
|
||||
$(window).trigger 'resize'
|
||||
|
||||
expect(editor.visibleLines.find('.line').length).toBe 10
|
||||
expect(editor.visibleLines.find('.line').length).toBe 12
|
||||
expect(editor.visibleLines.find('.line:first').text()).toBe buffer.lineForRow(0)
|
||||
expect(editor.visibleLines.find('.line:last').text()).toBe buffer.lineForRow(9)
|
||||
expect(editor.visibleLines.find('.line:last').text()).toBe buffer.lineForRow(11)
|
||||
|
||||
it "renders correctly when scrolling after text added to buffer", ->
|
||||
editor.attachToDom(heightInLines: 5.5)
|
||||
it "renders correctly when scrolling after text is added to the buffer", ->
|
||||
editor.insertText("1\n")
|
||||
_.times 4, -> editor.moveCursorDown()
|
||||
expect(editor.visibleLines.find('.line:eq(0)').text()).toBe editor.buffer.lineForRow(2)
|
||||
expect(editor.visibleLines.find('.line:eq(5)').text()).toBe editor.buffer.lineForRow(7)
|
||||
expect(editor.visibleLines.find('.line:eq(2)').text()).toBe editor.buffer.lineForRow(2)
|
||||
expect(editor.visibleLines.find('.line:eq(7)').text()).toBe editor.buffer.lineForRow(7)
|
||||
|
||||
it "renders correctly when scrolling after text is removed from buffer", ->
|
||||
editor.attachToDom(heightInLines: 5.5)
|
||||
console.log "lastRenderedScreenRow before delete", editor.lastRenderedScreenRow
|
||||
editor.buffer.delete([[0,0],[1,0]])
|
||||
expect(editor.visibleLines.find('.line:eq(0)').text()).toBe editor.buffer.lineForRow(0)
|
||||
expect(editor.visibleLines.find('.line:eq(5)').text()).toBe editor.buffer.lineForRow(5)
|
||||
_.times 4, -> editor.moveCursorDown()
|
||||
expect(editor.visibleLines.find('.line:eq(0)').text()).toBe editor.buffer.lineForRow(1)
|
||||
expect(editor.visibleLines.find('.line:eq(5)').text()).toBe editor.buffer.lineForRow(6)
|
||||
console.log "lastRenderedScreenRow after delete", editor.lastRenderedScreenRow
|
||||
|
||||
editor.scrollTop(3 * editor.lineHeight)
|
||||
expect(editor.visibleLines.find('.line:first').text()).toBe editor.buffer.lineForRow(1)
|
||||
expect(editor.visibleLines.find('.line:last').text()).toBe editor.buffer.lineForRow(10)
|
||||
|
||||
describe "when lines are added", ->
|
||||
beforeEach ->
|
||||
editor.attachToDom()
|
||||
setEditorHeightInLines(editor, 5)
|
||||
editor.attachToDom(heightInLines: 5)
|
||||
spyOn(editor, "scrollTo")
|
||||
|
||||
describe "when the change the precedes the first rendered row", ->
|
||||
it "inserts and removes rendered lines to account for upstream change", ->
|
||||
editor.scrollBottom(editor.scrollView.prop('scrollHeight'))
|
||||
expect(editor.visibleLines.find(".line:first").text()).toBe buffer.lineForRow(8)
|
||||
fffit "inserts and removes rendered lines to account for upstream change", ->
|
||||
console.log "-------------------"
|
||||
editor.scrollToBottom()
|
||||
expect(editor.visibleLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
||||
expect(editor.visibleLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
||||
|
||||
buffer.change([[1,0], [3,0]], "1\n2\n3\n")
|
||||
expect(editor.visibleLines.find(".line").length).toBe 5
|
||||
expect(editor.visibleLines.find(".line:first").text()).toBe buffer.lineForRow(8)
|
||||
expect(editor.visibleLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
||||
expect(editor.visibleLines.find(".line").length).toBe 7
|
||||
expect(editor.visibleLines.find(".line:first").text()).toBe buffer.lineForRow(7)
|
||||
expect(editor.visibleLines.find(".line:last").text()).toBe buffer.lineForRow(13)
|
||||
|
||||
editor.visibleLines.find('.line').each -> console.log $(this).text()
|
||||
|
||||
|
||||
describe "when the change straddles the first rendered row", ->
|
||||
it "doesn't render rows that were not previously rendered", ->
|
||||
|
||||
@@ -225,7 +225,7 @@ class Editor extends View
|
||||
else
|
||||
@gutter.addClass('drop-shadow')
|
||||
|
||||
$(window).on "resize", =>
|
||||
$(window).on "resize.editor#{@id}", =>
|
||||
@updateVisibleLines()
|
||||
|
||||
afterAttach: (onDom) ->
|
||||
@@ -236,11 +236,16 @@ class Editor extends View
|
||||
@calculateDimensions()
|
||||
@setMaxLineLength() if @softWrap
|
||||
@prepareForVerticalScrolling()
|
||||
|
||||
# this also renders the visible lines
|
||||
@setScrollPositionFromActiveEditSession()
|
||||
@renderVisibleLines()
|
||||
# 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
|
||||
|
||||
# TODO: The redundant assignment of scrollLeft below is needed because the
|
||||
# lines weren't 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
|
||||
# length
|
||||
|
||||
@scrollView.scrollLeft(@getActiveEditSession().scrollLeft ? 0)
|
||||
@hiddenInput.width(@charWidth)
|
||||
@focus() if @isFocused
|
||||
@@ -303,54 +308,80 @@ class Editor extends View
|
||||
|
||||
renderFrom = Math.max(0, firstVisibleScreenRow - @lineOverdraw)
|
||||
renderTo = Math.min(@getLastScreenRow(), lastVisibleScreenRow + @lineOverdraw)
|
||||
|
||||
console.log "Rendering lines %d-%d", renderFrom, renderTo
|
||||
|
||||
if firstVisibleScreenRow < @firstRenderedScreenRow
|
||||
newLinesEndRow = Math.min(@firstRenderedScreenRow - 1, lastVisibleScreenRow)
|
||||
lineElements = @buildLineElements(renderFrom, newLinesEndRow)
|
||||
console.log "inserting", renderFrom, "to", newLinesEndRow
|
||||
@insertLineElements(renderFrom, lineElements)
|
||||
@firstRenderedScreenRow = renderFrom
|
||||
adjustPaddingTop = true
|
||||
|
||||
if renderTo < @lastRenderedScreenRow
|
||||
console.log "removing", renderTo + 1, "to", @lastRenderedScreenRow
|
||||
@removeLineElements(renderTo + 1, @lastRenderedScreenRow)
|
||||
adjustPaddingBottom = true
|
||||
|
||||
@removeLineElements(Math.max(@firstRenderedScreenRow, renderTo), @lastRenderedScreenRow)
|
||||
@lastRenderedScreenRow = renderTo
|
||||
@firstRenderedScreenRow = renderFrom
|
||||
newLines = @buildLineElements(renderFrom, Math.min(@firstRenderedScreenRow, renderTo))
|
||||
@insertLineElements(renderFrom, newLines)
|
||||
adjustPadding = true
|
||||
|
||||
if lastVisibleScreenRow > @lastRenderedScreenRow
|
||||
newLinesStartRow = Math.max(@lastRenderedScreenRow + 1, firstVisibleScreenRow)
|
||||
lineElements = @buildLineElements(newLinesStartRow, renderTo)
|
||||
console.log "inserting", newLinesStartRow, "to", renderTo
|
||||
@insertLineElements(newLinesStartRow, lineElements)
|
||||
@lastRenderedScreenRow = renderTo
|
||||
adjustPaddingBottom = true
|
||||
|
||||
if 0 <= @firstRenderedScreenRow < renderFrom
|
||||
console.log "removing", @firstRenderedScreenRow, "to", renderFrom - 1
|
||||
@removeLineElements(@firstRenderedScreenRow, renderFrom - 1)
|
||||
adjustPaddingTop = true
|
||||
|
||||
@removeLineElements(@firstRenderedScreenRow, Math.min(@lastRenderedScreenRow, renderFrom))
|
||||
@firstRenderedScreenRow = renderFrom
|
||||
@lastRenderedScreenRow = renderTo
|
||||
startRowOfNewLines = Math.max(@lastRenderedScreenRow, renderFrom)
|
||||
newLines = @buildLineElements(startRowOfNewLines, renderTo)
|
||||
@insertLineElements(startRowOfNewLines, newLines)
|
||||
adjustPadding = true
|
||||
|
||||
if adjustPaddingTop
|
||||
if adjustPadding
|
||||
paddingTop = @firstRenderedScreenRow * @lineHeight
|
||||
@visibleLines.css('padding-top', paddingTop)
|
||||
@gutter.lineNumbers.css('padding-top', paddingTop)
|
||||
# @firstRenderedScreenRow = firstVisibleScreenRow
|
||||
|
||||
if adjustPaddingBottom
|
||||
paddingBottom = (@getLastScreenRow() - @lastRenderedScreenRow) * @lineHeight
|
||||
@visibleLines.css('padding-bottom', paddingBottom)
|
||||
@gutter.lineNumbers.css('padding-bottom', paddingBottom)
|
||||
|
||||
# if firstVisibleScreenRow < @firstRenderedScreenRow
|
||||
# newLinesEndRow = Math.min(@firstRenderedScreenRow - 1, lastVisibleScreenRow)
|
||||
# lineElements = @buildLineElements(renderFrom, newLinesEndRow)
|
||||
# console.log "inserting", renderFrom, "to", newLinesEndRow
|
||||
# @insertLineElements(renderFrom, lineElements)
|
||||
# @firstRenderedScreenRow = renderFrom
|
||||
# adjustPaddingTop = true
|
||||
|
||||
# if renderTo < @lastRenderedScreenRow
|
||||
# console.log "removing", renderTo + 1, "to", @lastRenderedScreenRow
|
||||
# @removeLineElements(renderTo + 1, @lastRenderedScreenRow)
|
||||
# adjustPaddingBottom = true
|
||||
|
||||
# @lastRenderedScreenRow = renderTo
|
||||
|
||||
# if lastVisibleScreenRow > @lastRenderedScreenRow
|
||||
# newLinesStartRow = Math.max(@lastRenderedScreenRow + 1, renderFrom)
|
||||
# lineElements = @buildLineElements(newLinesStartRow, renderTo)
|
||||
# console.log "inserting", newLinesStartRow, "to", renderTo
|
||||
# @insertLineElements(newLinesStartRow, lineElements)
|
||||
# @lastRenderedScreenRow = renderTo
|
||||
# adjustPaddingBottom = true
|
||||
|
||||
# if 0 <= @firstRenderedScreenRow < renderFrom
|
||||
# console.log "removing", @firstRenderedScreenRow, "to", renderFrom - 1
|
||||
# @removeLineElements(@firstRenderedScreenRow, renderFrom - 1)
|
||||
# adjustPaddingTop = true
|
||||
|
||||
# @firstRenderedScreenRow = renderFrom
|
||||
|
||||
# if adjustPaddingTop
|
||||
# paddingTop = @firstRenderedScreenRow * @lineHeight
|
||||
# @visibleLines.css('padding-top', paddingTop)
|
||||
# @gutter.lineNumbers.css('padding-top', paddingTop)
|
||||
|
||||
# if adjustPaddingBottom
|
||||
# paddingBottom = (@getLastScreenRow() - @lastRenderedScreenRow) * @lineHeight
|
||||
# @visibleLines.css('padding-bottom', paddingBottom)
|
||||
# @gutter.lineNumbers.css('padding-bottom', paddingBottom)
|
||||
|
||||
getFirstVisibleScreenRow: ->
|
||||
Math.floor(@scrollTop() / @lineHeight)
|
||||
|
||||
getLastVisibleScreenRow: ->
|
||||
Math.ceil((@scrollTop() + @scrollView.height()) / @lineHeight) - 1
|
||||
maxVisibleScreenRow = Math.ceil((@scrollTop() + @scrollView.height()) / @lineHeight) - 1
|
||||
Math.min(maxVisibleScreenRow, @getLastScreenRow())
|
||||
|
||||
highlightSelectedFolds: ->
|
||||
screenLines = @screenLinesForRows(@firstRenderedScreenRow, @lastRenderedScreenRow)
|
||||
@@ -441,7 +472,6 @@ class Editor extends View
|
||||
editSession = @getActiveEditSession()
|
||||
@scrollTop(editSession.scrollTop ? 0)
|
||||
@scrollView.scrollLeft(editSession.scrollLeft ? 0)
|
||||
@verticalScrollbar.trigger 'scroll'
|
||||
|
||||
saveCurrentEditSession: ->
|
||||
@editSessions[@activeEditSessionIndex] =
|
||||
@@ -481,19 +511,14 @@ class Editor extends View
|
||||
|
||||
newScreenRange.start.row = Math.max(newScreenRange.start.row, @firstRenderedScreenRow)
|
||||
oldScreenRange.start.row = Math.max(oldScreenRange.start.row, @firstRenderedScreenRow)
|
||||
newScreenRange.end.row = Math.min(newScreenRange.end.row, @lastRenderedScreenRow)
|
||||
oldScreenRange.end.row = Math.min(oldScreenRange.end.row, @lastRenderedScreenRow)
|
||||
|
||||
lineElements = @buildLineElements(newScreenRange.start.row, newScreenRange.end.row)
|
||||
@replaceLineElements(oldScreenRange.start.row, oldScreenRange.end.row, lineElements)
|
||||
|
||||
rowDelta = newScreenRange.end.row - oldScreenRange.end.row
|
||||
|
||||
if rowDelta > 0
|
||||
@removeLineElements(@lastRenderedScreenRow + 1, @lastRenderedScreenRow + rowDelta)
|
||||
else if rowDelta < 0
|
||||
@lastRenderedScreenRow += rowDelta
|
||||
@updateVisibleLines()
|
||||
@lastRenderedScreenRow += rowDelta
|
||||
@updateVisibleLines() if rowDelta < 0
|
||||
|
||||
buildLineElements: (startRow, endRow) ->
|
||||
charWidth = @charWidth
|
||||
@@ -763,6 +788,7 @@ class Editor extends View
|
||||
|
||||
@trigger 'before-remove'
|
||||
@unsubscribeFromBuffer()
|
||||
$(window).off ".editor#{@id}"
|
||||
rootView = @rootView()
|
||||
rootView?.off ".editor#{@id}"
|
||||
if @pane() then @pane().remove() else super
|
||||
|
||||
Reference in New Issue
Block a user