diff options
| author | Stephen Blott | 2015-02-03 07:37:54 +0000 | 
|---|---|---|
| committer | Stephen Blott | 2015-02-03 07:37:54 +0000 | 
| commit | c1681fea2f2629c6bee1e27c5dfc704d77553d96 (patch) | |
| tree | 563af53ca6d5ca0e65003ce911287d730560d509 /content_scripts/mode_visual_edit.coffee | |
| parent | 95e086563b918364d3038f6489cc97c73fcb7180 (diff) | |
| download | vimium-c1681fea2f2629c6bee1e27c5dfc704d77553d96.tar.bz2 | |
Visual/edit modes: better (?) guessing for caret mode.
When caret mode guesses a selection score text nodes by their visible
area and the number of non-whitespace characters they contain.  Choose
the first non-whitespace character in the highest-scoring node.
The intention is to avoid making a poor choice for the initial caret
position.
Diffstat (limited to 'content_scripts/mode_visual_edit.coffee')
| -rw-r--r-- | content_scripts/mode_visual_edit.coffee | 39 | 
1 files changed, 23 insertions, 16 deletions
diff --git a/content_scripts/mode_visual_edit.coffee b/content_scripts/mode_visual_edit.coffee index caecfbde..5b622e4d 100644 --- a/content_scripts/mode_visual_edit.coffee +++ b/content_scripts/mode_visual_edit.coffee @@ -619,25 +619,32 @@ class CaretMode extends Movement      @selection.modify "extend", forward, character    # When visual mode starts and there's no existing selection, we launch CaretMode and try to establish a -  # selection.  As a heuristic, we pick the first non-whitespace character of the first visible text node -  # which seems to be big enough to be interesting. -  # TODO(smblott).  It might be better to do something similar to Clearly or Readability; that is, try to find -  # the start of the page's main textual content. +  # selection.  As a heuristic, we score visible text nodes by their visible area and the number of +  # non-whitespace characters they contain.  We pick the first non-whitespece character in the highest scoring +  # node.    establishInitialSelectionAnchor: ->      nodes = document.createTreeWalker document.body, NodeFilter.SHOW_TEXT -    while node = nodes.nextNode() -      # Don't choose short text nodes; they're likely to be part of a banner. -      if node.nodeType == 3 and 50 <= node.data.trim().length + +    # Find and score candidate text nodes. +    candidates = +      for node in (n while n = nodes.nextNode()) +        continue unless node.nodeType == 3 and 0 < node.data.trim().length          element = node.parentElement -        if DomUtils.getVisibleClientRect(element) and not DomUtils.isEditable element -          # Start at the offset of the first non-whitespace character. -          offset = node.data.length - node.data.replace(/^\s+/, "").length -          range = document.createRange() -          range.setStart node, offset -          range.setEnd node, offset -          @setSelectionRange range -          return true -    false +        rect = DomUtils.getVisibleClientRect element +        continue unless rect and not DomUtils.isEditable element +        area = (rect.bottom - rect.top) * (rect.right - rect.left) +        chars = node.data.split(/\s+/).join().length +        { node: node, score: chars * area } + +    if 0 < candidates.length +      node = (candidates.sort (a,b) -> b.score - a.score)[0].node +      # Start at the offset of the first non-whitespace character. +      offset = node.data.length - node.data.replace(/^\s+/, "").length +      range = document.createRange() +      range.setStart node, offset +      range.setEnd node, offset +      @setSelectionRange range +      return range  class EditMode extends Movement    constructor: (options = {}) ->  | 
