Skip to content

Commit

Permalink
Initial getBounds implementation and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jhchen committed Nov 21, 2014
1 parent f446af1 commit 1ec7b46
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/core/editor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,36 @@ class Editor
else
@root.focus()

getBounds: (index) ->
this.checkUpdate()
[leaf, offset] = @doc.findLeafAt(index, true)
throw new Error('Invalid position') unless leaf?
containerBounds = @root.parentNode.getBoundingClientRect()
if offset == 0
bounds = leaf.node.parentNode.getBoundingClientRect()
return {
height: bounds.height
left: bounds.left - containerBounds.left,
top: bounds.top - containerBounds.top
}
else if offset == leaf.length
bounds = leaf.node.parentNode.getBoundingClientRect()
return {
height: bounds.height
left: bounds.right - containerBounds.left,
top: bounds.top - containerBounds.top
}
else
range = document.createRange()
range.setStart(leaf.node, offset)
range.setEnd(leaf.node, offset + 1)
bounds = range.getBoundingClientRect()
return {
height: bounds.height
left: bounds.left - containerBounds.left,
top: bounds.top - containerBounds.top
}

getDelta: ->
return @delta

Expand Down
3 changes: 3 additions & 0 deletions src/quill.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ class Quill extends EventEmitter2
delta = new Delta().retain(start).retain(end - start, formats)
@editor.applyDelta(delta, source)

getBounds: (index) ->
return @editor.getBounds(index)

getContents: (start = 0, end = null) ->
if _.isObject(start)
end = start.end
Expand Down
77 changes: 77 additions & 0 deletions test/unit/core/editor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -270,4 +270,81 @@ describe('Editor', ->
expect(@editor.checkUpdate).not.toHaveBeenCalled()
)
)

describe('getBounds()', ->
reference = null

beforeEach( ->
@editor.root.style.fontFamily = 'monospace'
unless reference?
@editor.root.innerHTML = '<div><span>0</span></div>'
reference =
normal:
height: @editor.root.firstChild.firstChild.offsetHeight
width: @editor.root.firstChild.firstChild.offsetWidth
@editor.root.innerHTML = '<div><span style="font-size: 32px;">0</span></div>'
reference.large =
height: @editor.root.firstChild.firstChild.offsetHeight
width: @editor.root.firstChild.firstChild.offsetWidth
@editor.root.innerHTML = '<div>01<span style="font-size: 32px;">23</span>45</div>'
)

it('empty line', ->
@editor.root.innerHTML = "<div><br></div>"
bounds = @editor.getBounds(0)
expect(bounds.height).toBeApproximately(reference.normal.height, 1)
expect(bounds.left).toBeApproximately(0, 1)
expect(bounds.top).toBeApproximately(0, 1)
)

it('start of line', ->
bounds = @editor.getBounds(0)
expect(bounds.height).toBeApproximately(reference.normal.height, 1)
expect(bounds.left).toBeApproximately(0, 1)
expect(bounds.top).toBeApproximately(0, 1)
)

it('end of line', ->
bounds = @editor.getBounds(6)
expect(bounds.height).toBeApproximately(reference.normal.height, 1)
expect(bounds.left).toBeApproximately(4*reference.normal.width + 2*reference.large.width, 1)
expect(bounds.top).toBeApproximately(0, 1)
)

it('middle of plain text', ->
bounds = @editor.getBounds(1)
expect(bounds.height).toBeApproximately(reference.normal.height, 1)
expect(bounds.left).toBeApproximately(reference.normal.width, 1)
expect(bounds.top).toBeApproximately(0, 1)
)

it('middle of formatted text', ->
bounds = @editor.getBounds(3)
expect(bounds.height).toBeApproximately(reference.large.height, 1)
expect(bounds.left).toBeApproximately(2*reference.normal.width + reference.large.width, 1)
expect(bounds.top).toBeApproximately(0, 1)
)

it('end of plain text start of formatted text', ->
bounds = @editor.getBounds(2)
expect(bounds.height).toBeApproximately(reference.normal.height, 1)
expect(bounds.left).toBeApproximately(2*reference.normal.width, 1)
expect(bounds.top).toBeApproximately(0, 1)
)

it('end of formatted text start of plain text', ->
bounds = @editor.getBounds(4)
expect(bounds.height).toBeApproximately(reference.large.height, 1)
expect(bounds.left).toBeApproximately(2*reference.normal.width + 2*reference.large.width, 1)
expect(bounds.top).toBeApproximately(0, 1)
)

it('second line', ->
@editor.root.innerHTML = "<div><br></div><div>0</div>"
bounds = @editor.getBounds(2)
expect(bounds.height).toBeApproximately(reference.normal.height, 1)
expect(bounds.left).toBeApproximately(0, 1)
expect(bounds.top).toBeApproximately(reference.normal.height, 1)
)
)
)

0 comments on commit 1ec7b46

Please sign in to comment.