From: Jason Woofenden Date: Sat, 26 Mar 2016 21:31:53 +0000 (-0400) Subject: can delete empty blocks with backspace (rough) X-Git-Url: https://jasonwoof.com/gitweb/?p=peach-html5-editor.git;a=commitdiff_plain;h=8ef2ac71a968742051ccec0b4f20dad33e609602 can delete empty blocks with backspace (rough) --- diff --git a/editor.coffee b/editor.coffee index f025506..636bf19 100644 --- a/editor.coffee +++ b/editor.coffee @@ -664,8 +664,8 @@ class PeachHTML5Editor constructor: (in_el, options) -> @options = options ? {} @in_el = in_el - @tree = null - @tree_parent = null # top-level nodes in @tree should have this .parent + @tree = null # array of Nodes, all editable content + @tree_parent = null # @tree is this.children. .el might === @idoc.body @matting = [] @init_1_called = false # when iframes have loaded @outer_iframe # iframe to hold editor @@ -923,16 +923,7 @@ class PeachHTML5Editor @move_cursor new_cursor return false when KEY_BACKSPACE - return false unless @cursor? - return false unless @cursor.i > 0 - @remove_character @cursor.n, @cursor.i - 1 - @adjust_whitespace_style @cursor.n - @changed() - new_cursor = new_cursor_position n: @cursor.n, i: @cursor.i - 1 - if new_cursor? - @move_cursor new_cursor - else - @kill_cursor() + @on_key_backspace e return false when KEY_DELETE return false unless @cursor? @@ -1019,6 +1010,60 @@ class PeachHTML5Editor throw 'bork bork' unless new_cursor? @move_cursor new_cursor # TODO move content past cursor into this new block + on_key_backspace: (e) -> + return false unless @cursor? + if @is_lone_space @cursor.n # false if it's not in a tag + if @cursor.i is 1 + # don't delete the space, because then it would collapse + # instead leave a space after the cursor + new_cursor = new_cursor_position n: @cursor.n, i: 0 + if new_cursor? + @move_cursor new_cursor + else + @kill_cursor() + else + parent = @cursor.n.parent + new_cursor = find_prev_cursor_position @tree, @cursor + if new_cursor? + if new_cursor.n is @cursor.n or new_cursor.n is parent + new_cursor = null + tag = @cursor.n.parent + if tag is @tree_parent + console.log "top-level text not supported" # FIXME + return false + for n, i in tag.parent.children + if n is tag + tag.parent.el.removeChild tag.el + tag.parent.children.splice i, 1 + break + @changed() + if new_cursor? + # re-check, in case it moved or is invalid now + new_cursor = new_cursor_position n: new_cursor.n, i: new_cursor.i + if new_cursor? + @move_cursor new_cursor + return + new_cursor = first_cursor_position @tree + if new_cursor? + @move_cursor new_cursor + else + @kill_cursor + return + else if @cursor.i is 0 + console.log 'not implemented yet' + # TODO if block, merge parent into prev + # TODO if inline, delete char from prev text node + return false + else + # TODO handle case of removing last char + @remove_character @cursor.n, @cursor.i - 1 + @adjust_whitespace_style @cursor.n + @changed() + new_cursor = new_cursor_position n: @cursor.n, i: @cursor.i - 1 + if new_cursor? + @move_cursor new_cursor + else + @kill_cursor() clear_dom: -> # remove all the editable content (and cursor, overlays, etc) while @idoc.body.childNodes.length @idoc.body.removeChild @idoc.body.childNodes[0] @@ -1026,9 +1071,12 @@ class PeachHTML5Editor return load_html: (html) -> @tree = peach_parser.parse html, @parser_opts + if !@tree[0]?.parent + @tree = peach_parser.parse '

', @parser_opts @tree_parent = @tree[0]?.parent + @tree_parent.el = @idoc.body @clear_dom() - instantiate_tree @tree, @idoc.body + instantiate_tree @tree, @tree_parent.el tree_dedup_space @tree @changed() changed: -> @@ -1107,6 +1155,16 @@ 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 + # true if n is text node with just a space in it, and the only child of a tag + is_lone_space: (n, i) -> + return false unless n.type is 'text' + return false unless n.text is ' ' + return false 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 # 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) -> @@ -1120,7 +1178,7 @@ class PeachHTML5Editor 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 + return if @cursor.n.parent is @tree_parent # FIXME implement text nodes at top level parent = @cursor.n.parent # insert the character if @insert_should_replace n, i @@ -1197,7 +1255,7 @@ class PeachHTML5Editor return unless n? prev_bounds = x: 0, y: 0, w: 0, h: 0 alpha = 0.1 - while n?.el? + while n?.el? and n isnt @tree_parent if n.type is 'text' n = n.parent continue