- else if @cursor.i is 0 # start of non-empty tag
- # TODO factor out function for moving children around
- # find containing block
- containing_block = @cursor.n
- loop
- containing_block = containing_block.parent
- return unless containing_block?
- return if containing_block is @tree_parent
- break if is_display_block containing_block
- # FIXME only continue if first child, else inline merge here
- # find contaning_block's previous sibling
- prev = null
- for n, contaning_block_i in contaning_block.parent.children
- break if n is containing_block
- prev = n
- containing_block.el.parent.removeChild containing_block.el
- containing_block.parent.children.splice contaning_block_i, 1
- if prev is null
- console.log "inimplemented: backspace at start of nested blocks" # FIXME
+ else if @cursor.i is 0 # start of text chunk
+ # FIXME clean this up: use new code for text runs
+ # FIXME handle backspacing a <br> even if it's near a inline tag boundary
+ # determine if cursor is at start of text run (text formatted inline)
+ block = @find_block_parent @cursor.n
+ return unless block
+ at_block_start = true
+ prev_pos = find_prev_cursor_position @tree, @cursor
+ unless prev_pos?
+ # if the cursor can't go back, then there's probably nowhere we can merge into
+ # TODO consider case of nested blocks. should backspace remove one?
+ return
+ prev_pos_block = @find_block_parent prev_pos.n
+ if prev_pos_block is block
+ # context: there is text before the cursor within the same block.
+ # FIXME clean up this hack for looking for <br>
+ cursor_text_pi = @cursor.n.parent.children.indexOf @cursor.n
+ if cursor_text_pi > 0
+ prev_node = @cursor.n.parent.children[cursor_text_pi - 1]
+ if prev_node.type is 'tag' and prev_node.name is 'br'
+ @remove_node prev_node
+ @text_cleanup @cursor.n.parent
+ @changed()
+ new_cursor = new_cursor_position n: prev_pos.n, i: prev_pos.i
+ if new_cursor?
+ @move_cursor new_cursor
+ else
+ @kill_cursor
+ return
+ # note: find_prev_cursor_position just crossed a boundary, not a character
+ # prev_pos is within the same block, try deleting there
+ @move_cursor prev_pos
+ # FIXME cleanup: don't call @move_cursor twice if the next line succeeds
+ return @on_key_backspace()
+ # context: backspace pressed at start of a display:block
+ return if block is @tree_parent # top level text
+ parent = block.parent
+ parent_i = parent.children.indexOf block
+ if parent_i is -1
+ throw "BUG #98270918347"