JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
code cleanup: better checking for tree-top
[peach-html5-editor.git] / editor.coffee
index 3ccd200..f025506 100644 (file)
@@ -665,6 +665,7 @@ class PeachHTML5Editor
                @options = options ? {}
                @in_el = in_el
                @tree = null
+               @tree_parent = null # top-level nodes in @tree should have this .parent
                @matting = []
                @init_1_called = false # when iframes have loaded
                @outer_iframe # iframe to hold editor
@@ -946,6 +947,7 @@ class PeachHTML5Editor
                                        @kill_cursor()
                                return false
                        when KEY_ENTER
+                               @on_key_enter e
                                return false
                        when KEY_ESCAPE
                                @kill_cursor()
@@ -979,6 +981,44 @@ class PeachHTML5Editor
                                console.log "ERROR: couldn't find cursor position after insert"
                                @kill_cursor()
                return false
+       on_key_enter: (e) -> # enter key pressed
+               return unless @cursor_visible
+               cur_block = @cursor.n
+               loop
+                       if cur_block.type is 'tag'
+                               if is_display_block cur_block.el
+                                       break
+                       return unless cur_block.parent?
+                       cur_block = cur_block.parent
+               # find array to insert new element into
+               if cur_block.parent is @tree_parent # top-level
+                       parent_el = @idoc.body
+                       pc = @tree
+               else
+                       parent_el = cur_block.parent.el
+                       pc = cur_block.parent.children
+               # find index of current block in its parent
+               for n, i in pc
+                       break if n is cur_block
+               i += 1 # we want to be after it
+               if i < pc.length
+                       before = pc[i].el
+               else
+                       before = null
+               # TODO if content after cursor
+               #       TODO new block is empty
+               new_text = new peach_parser.Node 'text', text: ' '
+               new_node = new peach_parser.Node 'tag', name: 'p', parent: cur_block.parent, attrs: {style: 'white-space: pre-wrap'}, children: [new_text]
+               new_text.parent = new_node
+               new_text.el = domify @idoc, text: ' '
+               new_node.el = domify @idoc, p: style: 'white-space: pre-wrap', children: [new_text.el]
+               pc.splice i, 0, new_node
+               parent_el.insertBefore new_node.el, before
+               @changed()
+               new_cursor = new_cursor_position n: new_text, i: 0
+               throw 'bork bork' unless new_cursor?
+               @move_cursor new_cursor
+               # TODO move content past cursor into this new block
        clear_dom: -> # remove all the editable content (and cursor, overlays, etc)
                while @idoc.body.childNodes.length
                        @idoc.body.removeChild @idoc.body.childNodes[0]
@@ -986,6 +1026,7 @@ class PeachHTML5Editor
                return
        load_html: (html) ->
                @tree = peach_parser.parse html, @parser_opts
+               @tree_parent = @tree[0]?.parent
                @clear_dom()
                instantiate_tree @tree, @idoc.body
                tree_dedup_space @tree
@@ -1066,15 +1107,28 @@ class PeachHTML5Editor
                                if needle is n.attrs.style.substr n.attrs.style.length - needle
                                        n.attrs.style = n.attrs.style.substr 0, n.attrs.style.length - needle
                                        n.el.setAttribute n.attrs.style
+       # detect special case: typing before a space that's the only thing in a block/doc
+       # reason: enter key creates blocks with just a space in them
+       insert_should_replace: (n, i) ->
+               return false unless i is 0
+               return false unless n.text is ' '
+               return true if n.parent is @tree_parent
+               if n.parent.children.length is 1
+                       if n.parent.children[0] is n
+                               # n is only child
+                               return true
+               return false
        # after calling this, you MUST call changed() and adjust_whitespace_style()
        insert_character: (n, i, char) ->
+               return if @cursor.n.parent is @tree_parent # top-level text not supported atm
                parent = @cursor.n.parent
-               return unless parent
-               return unless parent.el?
                # insert the character
-               if i is 0
+               if @insert_should_replace n, i
+                       n.text = char
+               else if i is 0
                        n.text = char + n.text
                else if i is n.text.length
+                       # replace the space
                        n.text += char
                else
                        n.text =