X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=editor.coffee;h=a0bd0a41d48864e6120bf7c2bfa90d4b56de99b8;hb=5de51db974972ef00b21121b7472075c0222b551;hp=8367d09b799835b528942d687b0c141fcff76e42;hpb=8e715e94e59e5bd05fea8e073de2750df2be1f8f;p=peach-html5-editor.git diff --git a/editor.coffee b/editor.coffee index 8367d09..a0bd0a4 100644 --- a/editor.coffee +++ b/editor.coffee @@ -16,6 +16,7 @@ # SETTINGS overlay_padding = 10 +breathing_room = 30 # minimum pixels above/below cursor timeout = (ms, cb) -> return setTimeout cb, ms next_frame = (cb) -> @@ -951,8 +952,10 @@ class PeachHTML5Editor when KEY_INSERT return false when KEY_PAGE_UP + @on_page_up_key e return false when KEY_PAGE_DOWN + @on_page_down_key e return false when KEY_TAB return false @@ -1073,6 +1076,89 @@ class PeachHTML5Editor else @kill_cursor() return + on_page_up_key: (e) -> + if @wrap2.scrollTop is 0 + return unless @cursor? + new_cursor = first_cursor_position @tree + if new_cursor? + if new_cursor.n isnt @cursor.n or new_cursor.i isnt @cursor.i + @move_cursor new_cursor + return + if @cursor? + screen_y = @cursor.y - @wrap2.scrollTop + scroll_amount = @wrap2_height - breathing_room + @wrap2.scrollTop = Math.max 0, @wrap2.scrollTop - scroll_amount + if @cursor? + @move_cursor_into_view screen_y + @wrap2.scrollTop + on_page_down_key: (e) -> + lowest_scrollpos = @wrap2.scrollHeight - @wrap2_height + if @wrap2.scrollTop is lowest_scrollpos + return unless @cursor? + new_cursor = last_cursor_position @tree + if new_cursor? + if new_cursor.n isnt @cursor.n or new_cursor.i isnt @cursor.i + @move_cursor new_cursor + return + if @cursor? + screen_y = @cursor.y - @wrap2.scrollTop + scroll_amount = @wrap2_height - breathing_room + @wrap2.scrollTop = Math.min lowest_scrollpos, @wrap2.scrollTop + scroll_amount + if @cursor? + @move_cursor_into_view screen_y + @wrap2.scrollTop + return + move_cursor_into_view: (y_target) -> + return if y_target is @cursor.y + was = @cursor + y_min = @wrap2.scrollTop + unless @wrap2.scrollTop is 0 + y_min += breathing_room + y_max = @wrap2.scrollTop + @wrap2_height + unless @wrap2.scrollTop is @wrap2.scrollHeight - @wrap2_height # downmost + y_max -= breathing_room + y_target = Math.min y_target, y_max + y_target = Math.max y_target, y_min + if y_target < @cursor.y + finder = find_up_cursor_position + far_enough = (cur, target_y) -> + return cur.y + cur.h <= target_y + else + finder = find_down_cursor_position + far_enough = (cur, y_target) -> + return cur.y >= y_target + loop + cur = finder @tree, was, @cursor_ideal_x + break unless cur? + break if far_enough cur, y_target + was = cur + if was is @cursor + was = null + if was? + if was.y + was.h > y_max + was = null + else if was.y < y_min + was = null + if cur? + if cur.y + cur.h > y_max + cur = null + else if cur.y < y_min + cur = null + if cur? and was? + # both valid, pick best + if cur.y < y_min + new_cursor = was + else if was.y + was.h > 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 ? cur + 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] @@ -1234,21 +1320,20 @@ class PeachHTML5Editor @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