JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
fix left/right cursor past non-visible whitespace
authorJason Woofenden <jason@jasonwoof.com>
Sat, 5 Mar 2016 02:55:09 +0000 (21:55 -0500)
committerJason Woofenden <jason@jasonwoof.com>
Sat, 5 Mar 2016 02:55:09 +0000 (21:55 -0500)
editor.coffee

index 52ffa0c..0d6e761 100644 (file)
@@ -19,20 +19,17 @@ TYPE_TEXT = peach_parser.TYPE_TEXT
 TYPE_COMMENT = peach_parser.TYPE_COMMENT
 TYPE_DOCTYPE = peach_parser.TYPE_DOCTYPE
 
-# text nodes don't have getBoundingClientRect(), so wrap it in a span, measure
-# and then put it back
+# text nodes don't have getBoundingClientRect(), so use selection api to find
+# it.
 get_text_bounding_rect = (el) ->
-       span = el.ownerDocument.createElement 'span'
-       el.parentNode.replaceChild span, el
-       span.appendChild el
-       ret = span.getBoundingClientRect()
-       span.parentNode.replaceChild el, span
-       return ret
 get_el_bounds = (el) ->
-       if el.getBoundingClientRect
+       if el.getBoundingClientRect?
                rect = el.getBoundingClientRect()
        else
-               rect = get_text_bounding_rect el
+               # text nodes don't have getBoundingClientRect(), so use range api
+               range = document.createRange()
+               range.selectNodeContents el
+               rect = range.getBoundingClientRect()
        doc = el.ownerDocument.documentElement
        win = el.ownerDocument.defaultView
        y_fix = win.pageYOffset - doc.clientTop
@@ -229,7 +226,11 @@ traverse_tree = (tree, state, cb) ->
 # TODO make it so cursor can go places that don't have text but could
 find_next_cursor_position = (tree, n, i) ->
        if n? and n.type is TYPE_TEXT and n.text.length > i
-               return [n, i + 1]
+               orig_xyh = cursor_to_xyh n, i
+               for next_i in [i+1 .. n.text.length] # inclusive is valid (after last char)
+                       next_xyh = cursor_to_xyh n, next_i
+                       if next_xyh.x > orig_xyh.x or next_xyh.y > orig_xyh.y
+                               return [n, next_i]
        found = traverse_tree tree, before: n?, (node, state) ->
                if node.type is TYPE_TEXT and state.before is false
                        state.node = node
@@ -243,6 +244,11 @@ find_next_cursor_position = (tree, n, i) ->
 # TODO make it so cursor can go places that don't have text but could
 find_prev_cursor_position = (tree, n, i) ->
        if n? and n.type is TYPE_TEXT and i > 0
+               orig_xyh = cursor_to_xyh n, i
+               for prev_i in [i-1 .. 0]
+                       prev_xyh = cursor_to_xyh n, prev_i
+                       if prev_xyh.x < orig_xyh.x or prev_xyh.y < orig_xyh.y
+                               return [n, prev_i]
                return [n, i - 1]
        found = traverse_tree tree, before: n?, (node, state) ->
                if node.type is TYPE_TEXT