# SETTINGS
overlay_padding = 10
+breathing_room = 30 # minimum pixels above/below cursor
timeout = (ms, cb) -> return setTimeout cb, ms
next_frame = (cb) ->
when KEY_INSERT
return false
when KEY_PAGE_UP
+ @on_page_up_key e
return false
when KEY_PAGE_DOWN
return false
else
@kill_cursor()
return
+ on_page_up_key: (e) ->
+ scroll_amount = @wrap2_height - breathing_room
+ # scroll up a page
+ @wrap2.scrollTop = Math.max 0, @wrap2.scrollTop - scroll_amount
+ # note: if cursor innacuracy causes it no not be within new scroll,
+ # @move_cursor will adjust the scroll a bit.
+ if @cursor?
+ # move cursor up approximately scroll_amount
+ was = @cursor
+ y_target = @cursor.y - scroll_amount
+ y_min = Math.min y_target, @wrap2.scrollTop
+ y_max = Math.min y_target, @wrap2.scrollTop - scroll_amount
+ y_target = Math.min y_target, y_max
+ y_target = Math.max y_target, y_min
+ loop
+ cur = find_up_cursor_position @tree, was, @cursor_ideal_x
+ break unless cur?
+ break if cur.y <= y_target
+ was = cur
+ if was is @cursor
+ if cur?
+ new_cursor = cur
+ else
+ # should this move the cursor to the beginning of the line?
+ new_cursor = null
+ else
+ if cur?
+ # both valid, pick best
+ if cur.y < y_min
+ new_cursor = was
+ else if was.y > y_max
+ new_cursor = cur
+ else if cur.y - y_target < y_target - was.y
+ new_cursor = cur
+ else
+ new_cursor = was
+ else
+ new_cursor = was
+ if new_cursor?
+ saved_ideal_x = @cursor_ideal_x
+ @move_cursor new_cursor
+ @cursor_ideal_x = saved_ideal_x
+ return
clear_dom: -> # remove all the editable content (and cursor, overlays, etc)
while @idoc.body.childNodes.length
@idoc.body.removeChild @idoc.body.childNodes[0]
@annotate cursor.n
@scroll_into_view cursor.y, height
scroll_into_view: (y, h = 0) ->
- closest = 30 # setting: smallest pixels from top/bottom of screet that's OK
y += overlay_padding # convert units from @idoc to @wrap2
# very top of document
- if y <= closest
+ if y <= breathing_room
@wrap2.scrollTop = 0
return
# very bottom of document
- if y + h >= @wrap2.scrollHeight - closest
+ if y + h >= @wrap2.scrollHeight - breathing_room
@wrap2.scrollTop = @wrap2.scrollHeight - @wrap2_height
return
# The most scrolled up (lowest value for scrollTop) that would be OK
- upmost = y + h + closest - @wrap2_height
+ upmost = y + h + breathing_room - @wrap2_height
upmost = Math.max(upmost, 0)
# the most scrolled down (highest value for scrollTop) that would be OK
- downmost = y - closest
+ downmost = y - breathing_room
downmost = Math.min(downmost, @wrap2.scrollHeight - @wrap2_height)
if upmost > downmost # means h is too big to fit
# scroll so top is visible