diff options
| -rw-r--r-- | background_scripts/commands.coffee | 2 | ||||
| -rw-r--r-- | content_scripts/marks.coffee | 94 | ||||
| -rw-r--r-- | content_scripts/mode.coffee | 2 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 17 | 
4 files changed, 72 insertions, 43 deletions
| diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee index 64ec36be..b9ab274c 100644 --- a/background_scripts/commands.coffee +++ b/background_scripts/commands.coffee @@ -30,7 +30,7 @@ Commands =        return      options ?= [] -    @keyToCommandRegistry[key] = extend { command, options }, @availableCommands[command] +    @keyToCommandRegistry[key] = extend { command, options, key }, @availableCommands[command]    # Lower-case the appropriate portions of named keys.    # diff --git a/content_scripts/marks.coffee b/content_scripts/marks.coffee index 8ba45fd4..fab509a7 100644 --- a/content_scripts/marks.coffee +++ b/content_scripts/marks.coffee @@ -1,57 +1,77 @@ -exit = (mode, continuation = null) -> -  mode.exit() -  continuation?() -  Marks = +  mode: null +  previousPosition: null + +  exit: (continuation = null) -> +    @mode?.exit() +    @mode = null +    continuation?() + +  # This returns the key which is used for storing mark locations in localStorage. +  getLocationKey: (keyChar) -> +    "vimiumMark|#{window.location.href.split('#')[0]}|#{keyChar}" + +  showMessage: (message, keyChar) -> +    HUD.showForDuration "#{message} \"#{keyChar}\".", 1000 +    activateCreateMode: -> -    mode = new Mode +    @mode = new Mode        name: "create-mark" -      indicator: "Create mark?" +      indicator: "Create mark..."        suppressAllKeyboardEvents: true -      keydown: (event) -> -        keyChar = KeyboardUtils.getKeyChar(event) -        if /[A-Z]/.test keyChar -          exit mode, -> +      keypress: (event) => +        keyChar = String.fromCharCode event.charCode +        # If <Shift> is depressed, then it's a global mark, otherwise it's a local mark.  This is consistent +        # vim's [A-Z] for global marks, [a-z] for local marks.  However, it also admits other non-Latin +        # characters. +        if event.shiftKey +          @exit =>              chrome.runtime.sendMessage                handler: 'createMark'                markName: keyChar                scrollX: window.scrollX                scrollY: window.scrollY -            , -> HUD.showForDuration "Created global mark '#{keyChar}'.", 1000 -        else if /[a-z]/.test keyChar -          [baseLocation, sep, hash] = window.location.href.split '#' -          localStorage["vimiumMark|#{baseLocation}|#{keyChar}"] = JSON.stringify -            scrollX: window.scrollX, -            scrollY: window.scrollY -          exit mode, -> HUD.showForDuration "Created local mark '#{keyChar}'.", 1000 -        else if not event.shiftKey -          exit mode - -  activateGotoMode: -> -    mode = new Mode +            , => @showMessage "Created global mark", keyChar +        else +          @exit => @markPosition keyChar + +  markPosition: (keyChar = null) -> +    markString = JSON.stringify scrollX: window.scrollX, scrollY: window.scrollY +    if keyChar? +      localStorage[@getLocationKey keyChar] = markString +      @showMessage "Created local mark", keyChar +    else +      @previousPosition = markString + +  activateGotoMode: (registryEntry) -> +    # We pick off the last character of the key sequence used to launch this command. Usually this is just "`". +    # We then use that character, so together usually the sequence "``", to jump back to the previous +    # position.  The "previous position" is recorded below, and is registered via @markPosition() elsewhere +    # for various other jump-like commands. +    previousPositionKey = registryEntry.key[registryEntry.key.length-1..] +    @mode = new Mode        name: "goto-mark" -      indicator: "Go to mark?" +      indicator: "Go to mark..."        suppressAllKeyboardEvents: true -      keydown: (event) -> -        keyChar = KeyboardUtils.getKeyChar(event) -        if /[A-Z]/.test keyChar -          exit mode, -> +      keypress: (event) => +        keyChar = String.fromCharCode event.charCode +        if event.shiftKey +          @exit ->              chrome.runtime.sendMessage                handler: 'gotoMark'                markName: keyChar -        else if /[a-z]/.test keyChar -          [baseLocation, sep, hash] = window.location.href.split '#' -          markString = localStorage["vimiumMark|#{baseLocation}|#{keyChar}"] -          exit mode, -> +        else +          markString = +            if keyChar == previousPositionKey then @previousPosition else localStorage[@getLocationKey keyChar] +          @exit =>              if markString? -              mark = JSON.parse markString -              window.scrollTo mark.scrollX, mark.scrollY -              HUD.showForDuration "Jumped to local mark '#{keyChar}'", 1000 +              @markPosition() +              position = JSON.parse markString +              window.scrollTo position.scrollX, position.scrollY +              @showMessage "Jumped to local mark", keyChar              else -              HUD.showForDuration "Local mark not set: '#{keyChar}'.", 1000 -        else if not event.shiftKey -          exit mode +              @showMessage "Local mark not set", keyChar  root = exports ? window  root.Marks =  Marks diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee index cbcc15f7..22b6120f 100644 --- a/content_scripts/mode.coffee +++ b/content_scripts/mode.coffee @@ -54,7 +54,7 @@ class Mode        for type in [ "keydown", "keypress", "keyup" ]          do (type) =>            handler = @options[type] -          @options[type] = (event) -> handler? event; false +          @options[type] = (event) => handler? event; @stopBubblingAndFalse      @push        keydown: @options.keydown || null diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 7ad75514..9ff9b6db 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -241,9 +241,10 @@ unregisterFrame = ->      tab_is_closing: DomUtils.isTopFrame()  executePageCommand = (request) -> +  commandType = request.command.split(".")[0]    # Vomnibar commands are handled in the tab's main/top frame.  They are handled even if Vimium is otherwise    # disabled in the frame. -  if request.command.split(".")[0] == "Vomnibar" +  if commandType == "Vomnibar"      if DomUtils.isTopFrame()        # We pass the frameId from request.  That's the frame which originated the request, so that's the frame        # which should receive the focus when the vomnibar closes. @@ -254,7 +255,9 @@ executePageCommand = (request) ->    # All other commands are handled in their frame (but only if Vimium is enabled).    return unless frameId == request.frameId and isEnabledForUrl -  if request.registryEntry.passCountToFunction +  if commandType == "Marks" +    Utils.invokeCommandString request.command, [request.registryEntry] +  else if request.registryEntry.passCountToFunction      Utils.invokeCommandString(request.command, [request.count])    else      Utils.invokeCommandString(request.command) for i in [0...request.count] @@ -299,8 +302,12 @@ window.focusThisFrame = do ->        setTimeout (-> highlightedFrameElement.remove()), 200  extend window, -  scrollToBottom: -> Scroller.scrollTo "y", "max" -  scrollToTop: -> Scroller.scrollTo "y", 0 +  scrollToBottom: -> +    Marks.markPosition() +    Scroller.scrollTo "y", "max" +  scrollToTop: -> +    Marks.markPosition() +    Scroller.scrollTo "y", 0    scrollToLeft: -> Scroller.scrollTo "x", 0    scrollToRight: -> Scroller.scrollTo "x", "max"    scrollUp: -> Scroller.scrollBy "y", -1 * Settings.get("scrollStepSize") @@ -861,6 +868,7 @@ window.getFindModeQuery = (backwards) ->      findModeQuery.parsedQuery  findAndFocus = (backwards) -> +  Marks.markPosition()    query = getFindModeQuery backwards    findModeQueryHasResults = @@ -1007,6 +1015,7 @@ findModeRestoreSelection = (range = findModeInitialRange) ->  # Enters find mode.  Returns the new find-mode instance.  window.enterFindMode = (options = {}) -> +  Marks.markPosition()    # Save the selection, so performFindInPlace can restore it.    findModeSaveSelection()    findModeQuery = rawQuery: "" | 
