From: Jason Woofenden Date: Wed, 30 Mar 2016 14:54:37 +0000 (-0400) Subject: optimize whitespace dedup X-Git-Url: https://jasonwoof.com/gitweb/?p=peach-html5-editor.git;a=commitdiff_plain;h=30aee05f9c37a3954f5f849823b2e84a304423ff optimize whitespace dedup --- diff --git a/editor.coffee b/editor.coffee index a0bd0a4..dd39c62 100644 --- a/editor.coffee +++ b/editor.coffee @@ -559,21 +559,32 @@ tree_dedup_space = (tree) -> throw "how is this possible?" next_i -= 1 return 1 - whitespace_to_space = (undo) -> + 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) - cur.text = (cur.text.substr 0, cur_i) + ' ' + (cur.text.substr cur_i + 1) - cur.el.textContent = cur.text + 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, whitespace_to_space] + 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 @@ -581,7 +592,8 @@ tree_dedup_space = (tree) -> return remove() # 2. width greater than zero means visible space if bounds.w > 0 - fixers.shift() # don't try removing + # 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 @@ -590,6 +602,11 @@ tree_dedup_space = (tree) -> # 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?