From 9b3470422695adbe3067c0b57dacdfeb324d5587 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 25 Jan 2015 11:01:04 +0000 Subject: Visual/edit modes: better reverseSelection(). There's an efficient way to implement reverseSelection, and an inefficient way. Unfortunately, the efficient way does not work for text inputs like textareas. So we fall back to the inefficient method in that case. --- content_scripts/mode_visual_edit.coffee | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'content_scripts') diff --git a/content_scripts/mode_visual_edit.coffee b/content_scripts/mode_visual_edit.coffee index 261166f9..6f327807 100644 --- a/content_scripts/mode_visual_edit.coffee +++ b/content_scripts/mode_visual_edit.coffee @@ -73,6 +73,27 @@ class Movement extends MaintainCount chrome.runtime.sendMessage handler: "pasteFromClipboard", (response) -> callback response + # Swap the anchor node/offset and the focus node/offset. + reverseSelection: -> + element = document.activeElement + if element and DomUtils.isEditable(element) and not element. isContentEditable + # Note(smblott). This implementation is unacceptably inefficient if the selection is large. We only use + # it if we have to. However, the normal method does not work for input elements. + direction = @getDirection() + length = @selection.toString().length + @selection[if direction == forward then "collapseToEnd" else "collapseToStart"]() + @selection.modify "extend", @opposite[direction], character for [0...length] + else + # Normal method. + direction = @getDirection() + original = @selection.getRangeAt(0).cloneRange() + range = original.cloneRange() + range.collapse direction == backward + @selection.removeAllRanges() + @selection.addRange range + which = if direction == forward then "start" else "end" + @selection.extend original["#{which}Container"], original["#{which}Offset"], + # Run a movement command. runMovement: (movement) -> @selection.modify @alterMethod, movement.split(" ")... @@ -105,14 +126,6 @@ class Movement extends MaintainCount movements = [ "forward word", "forward word", "backward word" ] @runMovement movement for movement in movements - # Swap the focus and anchor. - # FIXME(smblott). This implementation is rediculously inefficient if the selection is large. - reverseSelection: -> - direction = @getDirection() - length = @selection.toString().length - @selection[if direction == forward then "collapseToEnd" else "collapseToStart"]() - @selection.modify "extend", @opposite[direction], character for [0...length] - movements: "l": "forward character" "h": "backward character" @@ -322,7 +335,7 @@ class VisualMode extends Movement class VisualLineMode extends VisualMode constructor: (options = {}) -> super options - @selectLine() + @selectLine() unless @selection?.type == "None" handleMovementKeyChar: (keyChar) -> super keyChar -- cgit v1.2.3