if block
cb null
# remove cur char
- remove = ->
- removed_char = cur.text.charAt(cur_i)
- cur.el.textContent = cur.text = (cur.text.substr 0, cur_i) + (cur.text.substr cur_i + 1)
- if next is cur # in same text node
- if next_i is 0
- throw "how is this possible?"
- next_i -= 1
- return true
- # undo remove()
- put_it_back = ->
- cur.el.textContent = cur.text = (cur.text.substr 0, cur_i) + removed_char + (cur.text.substr cur_i)
- if next is cur # in same text node
- next_i += 1
- return false
+ remove = (undo) ->
+ if undo
+ cur.el.textContent = cur.text = (cur.text.substr 0, cur_i) + removed_char + (cur.text.substr cur_i)
+ if next is cur # in same text node
+ next_i += 1
+ return -1
+ else
+ removed_char = cur.text.charAt(cur_i)
+ cur.el.textContent = cur.text = (cur.text.substr 0, cur_i) + (cur.text.substr cur_i + 1)
+ if next is cur # in same text node
+ if next_i is 0
+ throw "how is this possible?"
+ next_i -= 1
+ return 1
+ whitespace_to_space = (undo) ->
+ if undo
+ cur.text = (cur.text.substr 0, cur_i) + removed_char + (cur.text.substr cur_i + 1)
+ cur.el.textContent = cur.text
+ else
+ removed_char = cur.text.charAt(cur_i)
+ cur.text = (cur.text.substr 0, cur_i) + ' ' + (cur.text.substr cur_i + 1)
+ cur.el.textContent = cur.text
+ return 0
# return true if cur was removed from the dom (ie re-use same prev)
operate = ->
# cur definitately set
# prev and/or next might be null, indicating the start/end of a display:block
return false unless is_space_code cur.text.charCodeAt cur_i
+ fixers = [remove, whitespace_to_space]
bounds = text_range_bounds cur.el, cur_i, cur_i + 1
# consistent cases:
# 1. zero rects returned by getClientRects() means collapsed space
return remove()
# 2. width greater than zero means visible space
if bounds.w > 0
- return false
+ fixers.shift() # don't try removing
# now the weird edge cases...
#
# firefox and chromium both report zero width for characters at the end
next_px = new_cursor_position n: next, i: next_i
#if prev is null and next is null
# parent_px = cur.parent.el.getBoundingClientRect()
- remove()
- if prev?
- if prev_px?
- new_prev_px = new_cursor_position n: prev, i: prev_i
- if new_prev_px.x isnt prev_px.x or new_prev_px.y isnt prev_px.y
- return put_it_back()
- else
- console.log "this shouldn't happen, we remove spaces that don't locate"
- if next?
- if next_px?
- new_next_px = new_cursor_position n: next, i: next_i
- if new_next_px.x isnt next_px.x or new_next_px.y isnt next_px.y
- return put_it_back()
- #else
- # console.log "removing space becase space after it is collapsed"
- return true
+ undo_arg = true # just for readabality
+ removed = 0
+ for fixer in fixers
+ break if removed > 0
+ removed += fixer()
+ need_undo = false
+ if prev?
+ if prev_px?
+ new_prev_px = new_cursor_position n: prev, i: prev_i
+ if new_prev_px?
+ if new_prev_px.x isnt prev_px.x or new_prev_px.y isnt prev_px.y
+ need_undo = true
+ else
+ need_undo = true
+ else
+ console.log "this shouldn't happen, we remove spaces that don't locate"
+ if next? and not need_undo
+ if next_px?
+ new_next_px = new_cursor_position n: next, i: next_i
+ if new_next_px?
+ if new_next_px.x isnt next_px.x or new_next_px.y isnt next_px.y
+ need_undo = true
+ else
+ need_undo = true
+ #else
+ # console.log "removing space becase space after it is collapsed"
+ if need_undo
+ removed += fixer undo_arg
+ if removed > 0
+ return true
+ else
+ return false
# pass null at start/end of display:block
queue = (n, i) ->
next = n