TYPE_COMMENT = peach_parser.TYPE_COMMENT
TYPE_DOCTYPE = peach_parser.TYPE_DOCTYPE
-get_el_offset = (el) ->
+get_el_bounds = (el) ->
rect = el.getBoundingClientRect()
doc = el.ownerDocument.documentElement
win = el.ownerDocument.defaultView
+ y_fix = win.pageYOffset - doc.clientTop
+ x_fix = win.pageXOffset - doc.clientLeft
return {
- top: rect.top + win.pageYOffset - doc.clientTop
- left: rect.left + win.pageXOffset - doc.clientLeft
+ x: rect.left + x_fix
+ y: rect.top + y_fix
+ w: rect.width ? (rect.right - rect.left)
+ h: rect.height ? (rect.top - rect.bottom)
}
# figure out the top/left coordinates of where the cursor should be if it's at
# implementation: insert a span tag where we want the cursor, and ask the
# browser where it put that span
cursor_to_loc = (n, i) ->
- span = domify span: style: "height: 1em; width: 0", children: [domify text: "|"]
+ span = domify span: style: "height: 1em; border-left: 1px solid black; margin-left: -1px"
parent = n.el.parentNode
- if i is 0
- # cursor at start of text
- parent.insertBefore span, n.el
- ret = get_el_offset span
- span.parentNode.removeChild span
- return ret
- else if i is n.text.length
- # cursor at end of text
- parent.insertBefore span, n.el.nextSibling
- ret = get_el_offset span
- span.parentNode.removeChild span
- return ret
- # cursor in middle of text
- # split the text node
- t0 = n.el.ownerDocument.createTextNode n.text.substr 0, i
- t1 = n.el.ownerDocument.createTextNode n.text.substr i
- parent.insertBefore t0, n.el
- parent.insertBefore span, n.el
- parent.insertBefore t1, n.el
- parent.removeChild n.el
- ret = get_el_offset span
- parent.insertBefore n.el, t0
- parent.removeChild t0
- parent.removeChild span
- parent.removeChild t1
+ els = []
+ txts = []
+ plus_width = false
+ if n.text.length < 2
+ bounds = get_el_offset n.el
+ if i is 1
+ plus_width = true
+ else
+ if i is 0 # cursor at start of text
+ check_i = 0
+ txts.push n.text.substr 0, 1
+ txts.push n.text.substr 1
+ else if i is n.text.length # cursor at end of text
+ check_i = 1
+ plus_width = true
+ txts.push n.text.substr 0, n.text.length - 1
+ txts.push n.text.substr n.text.length - 1
+ else
+ check_i = 1
+ txts.push n.text.substr 0, i
+ txts.push n.text.substr i, 1
+ txts.push n.text.substr i + 1
+ for txt, txt_i in txts
+ el = n.el.ownerDocument.createTextNode txt
+ if txt_i is check_i
+ span = n.el.ownerDocument.createElement 'span'
+ span.appendChild el
+ el = span
+ els.push el
+ parent.insertBefore el, n.el
+ parent.removeChild n.el
+ bounds = get_el_bounds els[check_i]
+ parent.insertBefore n.el, els[0]
+ for el in els
+ parent.removeChild el
+ ret = top: bounds.y, left: bounds.x
+ if plus_width
+ ret.left += bounds.w
+ # fudge case where bounds are BS because we're on non-significant whitespace
+ if i > 0
+ first = cursor_to_loc n, 0
+ if ret.left <= first.left
+ # no need for a loop here, because recursion
+ ret = cursor_to_loc n, i - 1
return ret
# TODO