JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
code cleanup (move function into class)
authorJason Woofenden <jason@jasonwoof.com>
Thu, 16 Jun 2016 19:07:06 +0000 (15:07 -0400)
committerJason Woofenden <jason@jasonwoof.com>
Thu, 16 Jun 2016 19:07:06 +0000 (15:07 -0400)
editor.coffee

index 2bb3d99..d8e482d 100644 (file)
@@ -517,165 +517,6 @@ tree_remove_empty_text_nodes = (tree) ->
                                n.parent.children.splice i, 1
                                break
 
-# remove whitespace that would be trimmed
-# replace whitespace that would collapse with a single space
-# FIXME delete this, use @collapse_whitespace instead
-collapse_whitespace = (tree) ->
-       prev = cur = next = null
-       prev_i = cur_i = next_i = 0
-       prev_pos = pos = next_pos = null
-       prev_px = cur_px = next_px = null
-       first = true
-       removed_char = null
-
-       tree_remove_empty_text_nodes(tree)
-
-       iterate = (tree, cb) ->
-               for n in tree
-                       if n.type is 'text'
-                               i = 0
-                               while i < n.text.length # don't foreach, cb might remove chars
-                                       advance = cb n, i
-                                       if advance
-                                               i += 1
-                       if n.type is 'tag'
-                               block = is_display_block n.el
-                               if block
-                                       cb null
-                               if n.children.length > 0
-                                       iterate n.children, cb
-                               if block
-                                       cb null
-       # remove cur char
-       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
-       replace_with_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)
-                       if removed_char isnt ' '
-                               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, replace_with_space]
-               # check for common case: single whitespace surrounded by non-whitespace chars
-               if prev? and next?
-                       unless (is_space_code prev.text.charCodeAt prev_i) or (is_space_code next.text.charCodeAt next_i)
-                               dbg = cur.text.charCodeAt cur_i
-                               if cur.text.charAt(cur_i) is ' ' # perens required
-                                       # single space can't collapse, doesn't need fixin'
-                                       return false
-                               else
-                                       # tab, newline, etc, can't collapse, but maybe should be replaced
-                                       fixers = [replace_with_space]
-               bounds = text_range_bounds cur.el, cur_i, cur_i + 1
-               # consistent cases:
-               # 1. zero rects returned by getClientRects() means collapsed space
-               if bounds is null
-                       return remove()
-               # 2. width greater than zero means visible space
-               if bounds.w > 0
-                       # has bounds, don't try removing
-                       fixers = [replace_with_space]
-               # now the weird edge cases...
-               #
-               # firefox and chromium both report zero width for characters at the end
-               # of a line where the text wraps (automatically, due to word-wrap) to
-               # the next line. These do not appear to be distinguishable from
-               # collapsed spaces via the range/bounds api, so...
-               #
-               # remove it from the dom, and if prev or next moves, put it back.
-               #
-               # this block (try changing it, put it back if something moves) is also
-               # used on collapsable whitespace characters besides space. In this case
-               # the character is replaced with a normal space character instead of
-               # removed
-               if prev? and not prev_px?
-                       prev_px = new_cursor_position n: prev, i: prev_i
-               if next? and not next_px?
-                       next_px = new_cursor_position n: next, i: next_i
-               #if prev is null and next is null
-               #       parent_px = cur.parent.el.getBoundingClientRect()
-               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
-               next_i = i
-               next_px = null
-               advance = true
-               if cur?
-                       removed = operate()
-                       # don't advance (to the next character next time) if we removed a
-                       # character from the same text node as ``next``, because doing so
-                       # renumbers the indexes in that string
-                       if removed and cur is next
-                               advance = false
-               else
-                       removed = false
-               unless removed
-                       prev = cur
-                       prev_i = cur_i
-                       prev_px = cur_px
-               cur = next
-               cur_i = next_i
-               cur_px = next_px
-               return advance
-       queue null
-       iterate tree, queue
-       queue null
-
-       tree_remove_empty_text_nodes(tree)
-
 class PeachHTML5Editor
        # Options: (all optional)
        #   editor_id: "id" attribute for outer-most element created by/for editor
@@ -1458,8 +1299,162 @@ class PeachHTML5Editor
                                delete n.attrs.style
        # remove whitespace that would be trimmed
        # replace whitespace that would collapse with a single space
+       # FIXME remove whitespace from after <br> (but not before)
        collapse_whitespace: (tree = @tree) ->
-               return collapse_whitespace tree # FIXME CONTINUE
+               prev = cur = next = null
+               prev_i = cur_i = next_i = 0
+               prev_pos = pos = next_pos = null
+               prev_px = cur_px = next_px = null
+               first = true
+               removed_char = null
+
+               tree_remove_empty_text_nodes(tree)
+
+               iterate = (tree, cb) ->
+                       for n in tree
+                               if n.type is 'text'
+                                       i = 0
+                                       while i < n.text.length # don't foreach, cb might remove chars
+                                               advance = cb n, i
+                                               if advance
+                                                       i += 1
+                               if n.type is 'tag'
+                                       block = is_display_block n.el
+                                       if block
+                                               cb null
+                                       if n.children.length > 0
+                                               iterate n.children, cb
+                                       if block
+                                               cb null
+               # remove cur char
+               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
+               replace_with_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)
+                               if removed_char isnt ' '
+                                       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, replace_with_space]
+                       # check for common case: single whitespace surrounded by non-whitespace chars
+                       if prev? and next?
+                               unless (is_space_code prev.text.charCodeAt prev_i) or (is_space_code next.text.charCodeAt next_i)
+                                       dbg = cur.text.charCodeAt cur_i
+                                       if cur.text.charAt(cur_i) is ' ' # perens required
+                                               # single space can't collapse, doesn't need fixin'
+                                               return false
+                                       else
+                                               # tab, newline, etc, can't collapse, but maybe should be replaced
+                                               fixers = [replace_with_space]
+                       bounds = text_range_bounds cur.el, cur_i, cur_i + 1
+                       # consistent cases:
+                       # 1. zero rects returned by getClientRects() means collapsed space
+                       if bounds is null
+                               return remove()
+                       # 2. width greater than zero means visible space
+                       if bounds.w > 0
+                               # has bounds, don't try removing
+                               fixers = [replace_with_space]
+                       # now the weird edge cases...
+                       #
+                       # firefox and chromium both report zero width for characters at the end
+                       # of a line where the text wraps (automatically, due to word-wrap) to
+                       # the next line. These do not appear to be distinguishable from
+                       # collapsed spaces via the range/bounds api, so...
+                       #
+                       # remove it from the dom, and if prev or next moves, put it back.
+                       #
+                       # this block (try changing it, put it back if something moves) is also
+                       # used on collapsable whitespace characters besides space. In this case
+                       # the character is replaced with a normal space character instead of
+                       # removed
+                       if prev? and not prev_px?
+                               prev_px = new_cursor_position n: prev, i: prev_i
+                       if next? and not next_px?
+                               next_px = new_cursor_position n: next, i: next_i
+                       #if prev is null and next is null
+                       #       parent_px = cur.parent.el.getBoundingClientRect()
+                       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
+                       next_i = i
+                       next_px = null
+                       advance = true
+                       if cur?
+                               removed = operate()
+                               # don't advance (to the next character next time) if we removed a
+                               # character from the same text node as ``next``, because doing so
+                               # renumbers the indexes in that string
+                               if removed and cur is next
+                                       advance = false
+                       else
+                               removed = false
+                       unless removed
+                               prev = cur
+                               prev_i = cur_i
+                               prev_px = cur_px
+                       cur = next
+                       cur_i = next_i
+                       cur_px = next_px
+                       return advance
+               queue null
+               iterate tree, queue
+               queue null
+
+               tree_remove_empty_text_nodes(tree)
                return
        # call this after you insert or remove inline nodes. It will:
        #    merge consecutive text nodes