@move_cursor new_cursor
return false
when KEY_DOWN
+ if @cursor?
+ new_cursor = @cursor
+ # go next until we move on the y axis
+ while new_cursor.y <= @cursor.y
+ new_cursor = find_next_cursor_position @tree, new_cursor
+ return false unless new_cursor?
+ # done early if we're already right of old cursor position
+ if new_cursor.x >= @cursor.x
+ # this would be strange, but could happen due to runaround
+ @move_cursor new_cursor
+ return false
+ target_y = new_cursor.y
+ # search rightward, until we find the closest position
+ # new_cursor is the next-most position we've checked
+ # prev_cursor is the older value, so it's not as next as new_cursor
+ while new_cursor.x < @cursor.x and new_cursor.y is target_y
+ prev_cursor = new_cursor
+ new_cursor = find_next_cursor_position @tree, new_cursor
+ break unless new_cursor?
+ # move cursor to prev_cursor or new_cursor
+ if new_cursor?
+ if new_cursor.y is target_y
+ # both valid, and on the same line, use closest
+ if (new_cursor.x - @cursor.x) < (@cursor.x - prev_cursor.x)
+ @move_cursor new_cursor
+ else
+ @move_cursor prev_cursor
+ else
+ # new_cursor on wrong line, use prev_cursor
+ @move_cursor prev_cursor
+ else
+ # can't go any further prev, use prev_cursor
+ @move_cursor prev_cursor
+ else
+ # move cursor to first position in document
+ new_cursor = last_cursor_position @tree
+ if new_cursor?
+ @move_cursor new_cursor
return false
when KEY_END
return false
when KEY_BACKSPACE
return false unless @cursor?
- return false unless @cursor[1] > 0
- @cursor[0].text = @cursor[0].text.substr(0, @cursor[1] - 1) + @cursor[0].text.substr(@cursor[1])
- @cursor[0].el.nodeValue = @cursor[0].text
- @move_cursor [@cursor[0], @cursor[1] - 1]
+ return false unless @cursor.i > 0
+ @cursor.n.text = @cursor.n.text.substr(0, @cursor.i - 1) + @cursor.n.text.substr(@cursor.i)
+ @cursor.n.el.nodeValue = @cursor.n.text
+ new_cursor = new_cursor_position n: @cursor.n, i: @cursor.i - 1
+ if new_cursor?
+ @move_cursor new_cursor
+ else
+ @kill_cursor()
@changed()
return false
when KEY_DELETE
return false unless @cursor?
- return false unless @cursor[1] < @cursor[0].text.length
- @cursor[0].text = @cursor[0].text.substr(0, @cursor[1]) + @cursor[0].text.substr(@cursor[1] + 1)
- @cursor[0].el.nodeValue = @cursor[0].text
- @move_cursor [@cursor[0], @cursor[1]]
+ return false unless @cursor.i < @cursor.n.text.length
+ @cursor.n.text = @cursor.n.text.substr(0, @cursor.i) + @cursor.n.text.substr(@cursor.i + 1)
+ @cursor.n.el.nodeValue = @cursor.n.text
+ new_cursor = new_cursor_position n: @cursor.n, i: @cursor.i
+ if new_cursor?
+ @move_cursor new_cursor
+ else
+ @kill_cursor()
@changed()
return false
when KEY_ENTER
char = e.charCode ? e.keyCode
if char and @cursor?
char = String.fromCharCode char
- if @cursor[1] is 0
- @cursor[0].text = char + @cursor[0].text
- else if @cursor[1] is @cursor[0].text.length - 1
- @cursor[0].text += char
+ if @cursor.i is 0
+ @cursor.n.text = char + @cursor.n.text
+ else if @cursor.i is @cursor.n.text.length - 1
+ @cursor.n.text += char
else
- @cursor[0].text =
- @cursor[0].text.substr(0, @cursor[1]) +
+ @cursor.n.text =
+ @cursor.n.text.substr(0, @cursor.i) +
char +
- @cursor[0].text.substr(@cursor[1])
- @cursor[0].el.nodeValue = @cursor[0].text
- @move_cursor [@cursor[0], @cursor[1] + 1]
+ @cursor.n.text.substr(@cursor.i)
+ @cursor.n.el.nodeValue = @cursor.n.text
+ new_cursor = new_cursor_position n: @cursor.n, i: @cursor.i + 1
+ unless new_cursor
+ # probably pressed space, and browser isn't displaying it
+ # FIXME insert instead, rip it out later if possible, etc.
+ # for now, remove it
+ @cursor.n.text =
+ @cursor.n.text.substr(0, @cursor.i) +
+ @cursor.n.text.substr(@cursor.i + 1)
+ @cursor.n.el.nodeValue = @cursor.n.text
+ return false
+ @move_cursor new_cursor
@changed()
return false
clear_dom: -> # remove all the editable content (and cursor, overlays, etc)