Skip to content
This repository has been archived by the owner on Jan 16, 2024. It is now read-only.

Commit

Permalink
Scrolls to cursor if not visible after enter/deletion/paste, fixing i…
Browse files Browse the repository at this point in the history
…ssue slab#433
  • Loading branch information
emannes committed Aug 3, 2015
1 parent 84fe3e8 commit 3f08564
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 4 deletions.
13 changes: 13 additions & 0 deletions src/core/editor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,19 @@ class Editor
top: bounds.top - containerBounds.top
}

scrollCursorIntoView: () ->
return unless @selection.range
startBounds = this.getBounds(@selection.range.start)
endBounds = this.getBounds(@selection.range.end)
containerBounds = @root.parentNode.getBoundingClientRect()
containerHeight = containerBounds.bottom - containerBounds.top
if containerHeight < endBounds.top + endBounds.height
[line, offset] = @doc.findLineAt(@selection.range.end)
line.node.scrollIntoView(false)
else if startBounds.top < 0
[line, offset] = @doc.findLineAt(@selection.range.start)
line.node.scrollIntoView()

_deleteAt: (index, length) ->
return if length <= 0
@selection.shiftAfter(index, -1 * length, =>
Expand Down
2 changes: 2 additions & 0 deletions src/modules/keyboard.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Keyboard
@toolbar.setActive(format, value) if @toolbar?
return
)
@quill.editor.scrollCursorIntoView()
return false
)

Expand All @@ -78,6 +79,7 @@ class Keyboard
@quill.deleteText(range.start - 1, range.start, Quill.sources.USER)
else if range.start < @quill.getLength() - 1
@quill.deleteText(range.start, range.start + 1, Quill.sources.USER)
@quill.editor.scrollCursorIntoView()
return false
)

Expand Down
5 changes: 1 addition & 4 deletions src/modules/paste-manager.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ class PasteManager
@quill.updateContents(delta, 'user')
@quill.setSelection(range.start + lengthAdded, range.start + lengthAdded)
# Make sure bottom of pasted content is visible
[line, offset] = @quill.editor.doc.findLineAt(range.start + lengthAdded)
lineBottom = line.node.getBoundingClientRect().bottom
windowBottom = document.documentElement.clientHeight
line.node.scrollIntoView(false) if lineBottom > windowBottom
@quill.editor.scrollCursorIntoView()
@container.innerHTML = ""
)

Expand Down
41 changes: 41 additions & 0 deletions test/unit/core/editor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -395,4 +395,45 @@ describe('Editor', ->
)
)
)

describe('scrollCursorIntoView()', ->
beforeEach( ->
@editor.root.style.height = "50px"
@editor.root.style.overflow = "auto"
@editor.root.innerHTML = '<div><span style="font-size: 32px;">a<br>b<br>c<br>d</span></div>'
)

it('scrolls down when cursor too low', ->
bounds = @editor.getBounds(7)
expect(bounds.top).toBeGreaterThan(100)
@editor.selection.setRange(new Quill.Lib.Range(7, 7))
@editor.scrollCursorIntoView()
bounds = @editor.getBounds(7)
expect(bounds.top).not.toBeLessThan(0)
expect(bounds.top + bounds.height).not.toBeGreaterThan(100)
)

it('scrolls up when cursor too high', ->
@editor.root.scrollTop = 50
bounds = @editor.getBounds(1)
expect(bounds.top + bounds.height).toBeLessThan(0)
@editor.selection.setRange(new Quill.Lib.Range(1, 1))
@editor.scrollCursorIntoView()
bounds = @editor.getBounds(1)
expect(bounds.top).not.toBeLessThan(0)
expect(bounds.top + bounds.height).not.toBeGreaterThan(100)
)

it('does not scroll if cursor in view', ->
bounds = @editor.getBounds(1)
expect(bounds.top).not.toBeLessThan(0)
expect(bounds.top + bounds.height).not.toBeGreaterThan(100)
@editor.selection.setRange(new Quill.Lib.Range(1, 1))
@editor.scrollCursorIntoView()
newBounds = @editor.getBounds(1)
expect(bounds.top).toBe(newBounds.top)
expect(bounds.height).toBe(newBounds.height)
expect(bounds.left).toBe(newBounds.left)
)
)
)

0 comments on commit 3f08564

Please sign in to comment.