From 7c5fb2c312b9140c2dd091f792535ae8f592ecdb Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Fri, 26 Feb 2016 16:47:17 +0000 Subject: Key bindings; initial "generic" class. This implements a generic front-end class for key handling (a la normal mode). Also: - supports count prefixes (or not) - supports multi-key mappings (longer than two) Also included is a very poor-man's demo. See the bottom of mode_key_handler.coffee for some hard-wired key bindings. IMPORTANT: This does not actually work as Vimium. It's just a demo. --- content_scripts/vimium_frontend.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 667031dc..bce5f632 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -112,7 +112,8 @@ window.initializeModes = -> # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and # activates/deactivates itself accordingly. - new NormalMode + # new NormalMode + new KeyHandlerMode commandHandler: demoCommandHandler, keyMapping: demoKeyMapping, indicator: "Demo mode." new PassKeysMode new InsertMode permanent: true Scroller.init() -- cgit v1.2.3 From 34b1fb0f4e2ce1696c17e703d0bc43463355d6ba Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 27 Feb 2016 14:20:12 +0000 Subject: Key bindings; initial partially-functioning version. --- content_scripts/vimium_frontend.coffee | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index bce5f632..b46175fb 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -101,19 +101,35 @@ handlerStack.push # Only exported for tests. window.initializeModes = -> - class NormalMode extends Mode + class NormalMode extends KeyHandlerMode constructor: -> super name: "normal" indicator: false # There is no mode indicator in normal mode. - keydown: (event) => onKeydown.call @, event - keypress: (event) => onKeypress.call @, event - keyup: (event) => onKeyup.call @, event + commandHandler: @commandHandler.bind this + keyMapping: {} + + chrome.storage.local.get "normalModeKeyStateMapping", (items) => + @setKeyMapping items.normalModeKeyStateMapping + + chrome.storage.onChanged.addListener (changes, area) => + if area == "local" and changes.normalModeKeyStateMapping?.newValue + @setKeyMapping changes.normalModeKeyStateMapping.newValue + + commandHandler: (registryEntry, count) -> + # TODO: Special handling of Vomnibar. + if registryEntry.isBackgroundCommand + true # Not yet implemnted. + else + count = 1 if registryEntry.noRepeat + if registryEntry.passCountToFunction + Utils.invokeCommandString registryEntry.command, [count] + else + Utils.invokeCommandString registryEntry.command for i in [0...count] # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and # activates/deactivates itself accordingly. - # new NormalMode - new KeyHandlerMode commandHandler: demoCommandHandler, keyMapping: demoKeyMapping, indicator: "Demo mode." + new NormalMode new PassKeysMode new InsertMode permanent: true Scroller.init() -- cgit v1.2.3 From 3f63ceb19046157692eac9e9a13486af7e50a57e Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 27 Feb 2016 14:44:34 +0000 Subject: Key bindings; partially functioning w/ backgound commands. --- content_scripts/vimium_frontend.coffee | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index b46175fb..26942a30 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -117,11 +117,14 @@ window.initializeModes = -> @setKeyMapping changes.normalModeKeyStateMapping.newValue commandHandler: (registryEntry, count) -> + count *= registryEntry.options.count ? 1 + count = 1 if registryEntry.noRepeat + # TODO: Repeat limit. # TODO: Special handling of Vomnibar. + # TODO: Fix passKeys. if registryEntry.isBackgroundCommand - true # Not yet implemnted. + chrome.runtime.sendMessage { handler: "runBackgroundCommand", frameId, registryEntry, count} else - count = 1 if registryEntry.noRepeat if registryEntry.passCountToFunction Utils.invokeCommandString registryEntry.command, [count] else -- cgit v1.2.3 From 47de80f2fcb03c8741ab46308ce982209f74f6ac Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 27 Feb 2016 15:03:09 +0000 Subject: Key bindings; fix passkeys. --- content_scripts/vimium_frontend.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 26942a30..7fe12d62 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -132,8 +132,8 @@ window.initializeModes = -> # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and # activates/deactivates itself accordingly. - new NormalMode - new PassKeysMode + normalMode = new NormalMode + new PassKeysMode normalMode new InsertMode permanent: true Scroller.init() -- cgit v1.2.3 From d388eddd192d925cda43700d7090ce8d52499df0 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 27 Feb 2016 15:25:28 +0000 Subject: Key bindings; remove legacy code. --- content_scripts/vimium_frontend.coffee | 154 ++------------------------------- 1 file changed, 7 insertions(+), 147 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 7fe12d62..0cb402b8 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -5,14 +5,9 @@ # "domReady". # -keyPort = null isEnabledForUrl = true isIncognitoMode = chrome.extension.inIncognitoContext passKeys = null -keyQueue = null -# The user's operating system. -currentCompletionKeys = "" -validFirstKeys = "" # We track whther the current window has the focus or not. windowIsFocused = do -> @@ -119,9 +114,13 @@ window.initializeModes = -> commandHandler: (registryEntry, count) -> count *= registryEntry.options.count ? 1 count = 1 if registryEntry.noRepeat - # TODO: Repeat limit. + + if registryEntry.repeatLimit? and registryEntry.repeatLimit < count + return unless confirm """ + You have asked Vimium to perform #{count} repeats of the command: #{registryEntry.description}.\n + Are you sure you want to continue? """ + # TODO: Special handling of Vomnibar. - # TODO: Fix passKeys. if registryEntry.isBackgroundCommand chrome.runtime.sendMessage { handler: "runBackgroundCommand", frameId, registryEntry, count} else @@ -142,30 +141,13 @@ window.initializeModes = -> # initializePreDomReady = -> checkIfEnabledForUrl() - refreshCompletionKeys() - - # Send the key to the key handler in the background page. - keyPort = chrome.runtime.connect({ name: "keyDown" }) - # If the port is closed, the background page has gone away (since we never close it ourselves). Disable all - # our event listeners, and stub out chrome.runtime.sendMessage/connect (to prevent errors). - # TODO(mrmr1993): Do some actual cleanup to free resources, hide UI, etc. - keyPort.onDisconnect.addListener -> - isEnabledForUrl = false - chrome.runtime.sendMessage = -> - chrome.runtime.connect = -> - window.removeEventListener "focus", onFocus requestHandlers = showHUDforDuration: handleShowHUDforDuration toggleHelpDialog: (request) -> if frameId == request.frameId then HelpDialog.toggle request.dialogHtml focusFrame: (request) -> if (frameId == request.frameId) then focusThisFrame request - refreshCompletionKeys: refreshCompletionKeys getScrollPosition: -> scrollX: window.scrollX, scrollY: window.scrollY setScrollPosition: setScrollPosition - executePageCommand: executePageCommand - currentKeyQueue: (request) -> - keyQueue = request.keyQueue - handlerStack.bubbleEvent "registerKeyQueue", { keyQueue: keyQueue } # A frame has received the focus. We don't care here (the Vomnibar/UI-component handles this). frameFocused: -> checkEnabledAfterURLChange: checkEnabledAfterURLChange @@ -179,7 +161,7 @@ initializePreDomReady = -> return if request.handler and not request.name shouldHandleRequest = isEnabledForUrl # We always handle the message if it's one of these listed message types. - shouldHandleRequest ||= request.name in [ "executePageCommand", "checkEnabledAfterURLChange" ] + shouldHandleRequest ||= request.name in [ "checkEnabledAfterURLChange" ] # Requests with a frameId of zero should always and only be handled in the main/top frame (regardless of # whether Vimium is enabled there). if request.frameId == 0 and DomUtils.isTopFrame() @@ -255,28 +237,6 @@ unregisterFrame = -> frameId: frameId 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 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. - Utils.invokeCommandString request.command, [ request.frameId, request.registryEntry ] - refreshCompletionKeys request - return - - # 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 - Utils.invokeCommandString(request.command, [request.count]) - else - Utils.invokeCommandString(request.command) for i in [0...request.count] - - refreshCompletionKeys(request) - handleShowHUDforDuration = ({ text, duration }) -> if DomUtils.isTopFrame() DomUtils.documentReady -> HUD.showForDuration text, duration @@ -476,94 +436,6 @@ extend window, targetElement: document.activeElement indicator: false -# Track which keydown events we have handled, so that we can subsequently suppress the corresponding keyup -# event. -KeydownEvents = - handledEvents: {} - - getEventCode: (event) -> event.keyCode - - push: (event) -> - @handledEvents[@getEventCode event] = true - - # Yields truthy or falsy depending upon whether a corresponding keydown event is present (and removes that - # event). - pop: (event) -> - detailString = @getEventCode event - value = @handledEvents[detailString] - delete @handledEvents[detailString] - value - - clear: -> @handledEvents = {} - -handlerStack.push - _name: "KeydownEvents-cleanup" - blur: (event) -> KeydownEvents.clear() if event.target == window; true - -# -# Sends everything except i & ESC to the handler in background_page. i & ESC are special because they control -# insert mode which is local state to the page. The key will be are either a single ascii letter or a -# key-modifier pair, e.g. for control a. -# -# Note that some keys will only register keydown events and not keystroke events, e.g. ESC. -# -# @/this, here, is the the normal-mode Mode object. -onKeypress = (event) -> - keyChar = KeyboardUtils.getKeyCharString event - if keyChar - if currentCompletionKeys.indexOf(keyChar) != -1 or isValidFirstKey keyChar - DomUtils.suppressEvent(event) - keyPort.postMessage keyChar:keyChar, frameId:frameId - return @stopBubblingAndTrue - - keyPort.postMessage keyChar:keyChar, frameId:frameId - - return @continueBubbling - -# @/this, here, is the the normal-mode Mode object. -onKeydown = (event) -> - keyChar = KeyboardUtils.getKeyCharString event - - if (HelpDialog.showing && KeyboardUtils.isEscape(event)) - HelpDialog.hide() - DomUtils.suppressEvent event - KeydownEvents.push event - return @stopBubblingAndTrue - - else - if (keyChar) - if (currentCompletionKeys.indexOf(keyChar) != -1 or isValidFirstKey(keyChar)) - DomUtils.suppressEvent event - KeydownEvents.push event - keyPort.postMessage({ keyChar:keyChar, frameId:frameId }) - return @stopBubblingAndTrue - - keyPort.postMessage({ keyChar:keyChar, frameId:frameId }) - - else if (KeyboardUtils.isEscape(event)) - keyPort.postMessage({ keyChar:"", frameId:frameId }) - - # Added to prevent propagating this event to other listeners if it's one that'll trigger a Vimium command. - # The goal is to avoid the scenario where Google Instant Search uses every keydown event to dump us - # back into the search box. As a side effect, this should also prevent overriding by other sites. - # - # Subject to internationalization issues since we're using keyIdentifier instead of charCode (in keypress). - # - # TOOD(ilya): Revisit this. Not sure it's the absolute best approach. - if not keyChar && - (currentCompletionKeys.indexOf(KeyboardUtils.getKeyChar(event)) != -1 || - isValidFirstKey(KeyboardUtils.getKeyChar(event))) - DomUtils.suppressPropagation(event) - KeydownEvents.push event - return @stopBubblingAndTrue - - return @continueBubbling - -# @/this, here, is the the normal-mode Mode object. -onKeyup = (event) -> - return @continueBubbling unless KeydownEvents.pop event - DomUtils.suppressPropagation(event) - @stopBubblingAndTrue # Checks if Vimium should be enabled or not in this frame. As a side effect, it also informs the background # page whether this frame has the focus, allowing the background page to track the active frame's URL. @@ -593,18 +465,6 @@ checkIfEnabledForUrl = (frameIsFocused = windowIsFocused()) -> checkEnabledAfterURLChange = -> checkIfEnabledForUrl() if windowIsFocused() -# Exported to window, but only for DOM tests. -window.refreshCompletionKeys = (response) -> - if (response) - currentCompletionKeys = response.completionKeys - - if (response.validFirstKeys) - validFirstKeys = response.validFirstKeys - else - chrome.runtime.sendMessage({ handler: "getCompletionKeys" }, refreshCompletionKeys) - -isValidFirstKey = (keyChar) -> - validFirstKeys[keyChar] || /^[1-9]/.test(keyChar) window.handleEscapeForFindMode = -> document.body.classList.remove("vimiumFindMode") -- cgit v1.2.3 From 6487c09d98b791b3211679d2f1bf970394a696e6 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 27 Feb 2016 16:05:23 +0000 Subject: Key bindings; rewire vomnibar. --- content_scripts/vimium_frontend.coffee | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 0cb402b8..4acac352 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -120,7 +120,6 @@ window.initializeModes = -> You have asked Vimium to perform #{count} repeats of the command: #{registryEntry.description}.\n Are you sure you want to continue? """ - # TODO: Special handling of Vomnibar. if registryEntry.isBackgroundCommand chrome.runtime.sendMessage { handler: "runBackgroundCommand", frameId, registryEntry, count} else @@ -136,6 +135,9 @@ window.initializeModes = -> new InsertMode permanent: true Scroller.init() +openVomnibar = ({sourceFrameId, registryEntry}) -> + Utils.invokeCommandString registryEntry.command, [sourceFrameId, registryEntry] if DomUtils.isTopFrame() + # # Complete initialization work that sould be done prior to DOMReady. # @@ -151,6 +153,7 @@ initializePreDomReady = -> # A frame has received the focus. We don't care here (the Vomnibar/UI-component handles this). frameFocused: -> checkEnabledAfterURLChange: checkEnabledAfterURLChange + openVomnibar: openVomnibar chrome.runtime.onMessage.addListener (request, sender, sendResponse) -> # In the options page, we will receive requests from both content and background scripts. ignore those @@ -162,11 +165,6 @@ initializePreDomReady = -> shouldHandleRequest = isEnabledForUrl # We always handle the message if it's one of these listed message types. shouldHandleRequest ||= request.name in [ "checkEnabledAfterURLChange" ] - # Requests with a frameId of zero should always and only be handled in the main/top frame (regardless of - # whether Vimium is enabled there). - if request.frameId == 0 and DomUtils.isTopFrame() - request.frameId = frameId - shouldHandleRequest = true sendResponse requestHandlers[request.name](request, sender) if shouldHandleRequest # Ensure the sendResponse callback is freed. false -- cgit v1.2.3 From 560112448d00fc9c69c9db03de8fdd5412c700dc Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sat, 27 Feb 2016 16:16:53 +0000 Subject: Key bindings; rewire vomnibar (tweaked). --- content_scripts/vimium_frontend.coffee | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 4acac352..5c594d1c 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -135,9 +135,6 @@ window.initializeModes = -> new InsertMode permanent: true Scroller.init() -openVomnibar = ({sourceFrameId, registryEntry}) -> - Utils.invokeCommandString registryEntry.command, [sourceFrameId, registryEntry] if DomUtils.isTopFrame() - # # Complete initialization work that sould be done prior to DOMReady. # @@ -153,7 +150,8 @@ initializePreDomReady = -> # A frame has received the focus. We don't care here (the Vomnibar/UI-component handles this). frameFocused: -> checkEnabledAfterURLChange: checkEnabledAfterURLChange - openVomnibar: openVomnibar + openVomnibar: ({sourceFrameId, registryEntry}) -> + Utils.invokeCommandString registryEntry.command, [sourceFrameId, registryEntry] if DomUtils.isTopFrame() chrome.runtime.onMessage.addListener (request, sender, sendResponse) -> # In the options page, we will receive requests from both content and background scripts. ignore those -- cgit v1.2.3 From f89b58f04af3eae05de9e999c39b2fe047fe6f4a Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 28 Feb 2016 06:48:03 +0000 Subject: Key bindings; more tweaks and fixes. Miscellaneous fixes and tweaks, including: - Reinstate key logging. - Fix count handling in line with expected behaviour in #2024. - Remove `noCount` option; we don't need it. - Simplify logic in various places. Fixes #2024. --- content_scripts/vimium_frontend.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 5c594d1c..3220b084 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -7,7 +7,6 @@ isEnabledForUrl = true isIncognitoMode = chrome.extension.inIncognitoContext -passKeys = null # We track whther the current window has the focus or not. windowIsFocused = do -> @@ -162,7 +161,7 @@ initializePreDomReady = -> return if request.handler and not request.name shouldHandleRequest = isEnabledForUrl # We always handle the message if it's one of these listed message types. - shouldHandleRequest ||= request.name in [ "checkEnabledAfterURLChange" ] + shouldHandleRequest ||= request.name in ["checkEnabledAfterURLChange", "openVomnibar"] sendResponse requestHandlers[request.name](request, sender) if shouldHandleRequest # Ensure the sendResponse callback is freed. false -- cgit v1.2.3 From cf7a03dc26415528bc690147ba72c08e67dd65c8 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 28 Feb 2016 11:54:52 +0000 Subject: Key bindings; more minor tweaks. --- content_scripts/vimium_frontend.coffee | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 3220b084..2fc2dc35 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -117,15 +117,14 @@ window.initializeModes = -> if registryEntry.repeatLimit? and registryEntry.repeatLimit < count return unless confirm """ You have asked Vimium to perform #{count} repeats of the command: #{registryEntry.description}.\n - Are you sure you want to continue? """ + Are you sure you want to continue?""" if registryEntry.isBackgroundCommand - chrome.runtime.sendMessage { handler: "runBackgroundCommand", frameId, registryEntry, count} + chrome.runtime.sendMessage {handler: "runBackgroundCommand", frameId, registryEntry, count} + else if registryEntry.passCountToFunction + Utils.invokeCommandString registryEntry.command, [count] else - if registryEntry.passCountToFunction - Utils.invokeCommandString registryEntry.command, [count] - else - Utils.invokeCommandString registryEntry.command for i in [0...count] + Utils.invokeCommandString registryEntry.command for i in [0...count] # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and # activates/deactivates itself accordingly. -- cgit v1.2.3 From 520b63cb1d64fb5a293988122007bd05bacc49db Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 28 Feb 2016 14:01:16 +0000 Subject: Key bindings; fix tests... ... and fix two bugs: - not suppressing keyup event after keyChar matched in keydown. - we cannot check the passKeys keyChar in keyup because the key state has changed; so we track what the next keyup response should be. --- content_scripts/vimium_frontend.coffee | 67 +++++++++++++++++----------------- 1 file changed, 33 insertions(+), 34 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 2fc2dc35..e821b136 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -93,42 +93,41 @@ handlerStack.push target = target.parentElement true -# Only exported for tests. -window.initializeModes = -> - class NormalMode extends KeyHandlerMode - constructor: -> - super - name: "normal" - indicator: false # There is no mode indicator in normal mode. - commandHandler: @commandHandler.bind this - keyMapping: {} - - chrome.storage.local.get "normalModeKeyStateMapping", (items) => - @setKeyMapping items.normalModeKeyStateMapping - - chrome.storage.onChanged.addListener (changes, area) => - if area == "local" and changes.normalModeKeyStateMapping?.newValue - @setKeyMapping changes.normalModeKeyStateMapping.newValue - - commandHandler: (registryEntry, count) -> - count *= registryEntry.options.count ? 1 - count = 1 if registryEntry.noRepeat - - if registryEntry.repeatLimit? and registryEntry.repeatLimit < count - return unless confirm """ - You have asked Vimium to perform #{count} repeats of the command: #{registryEntry.description}.\n - Are you sure you want to continue?""" - - if registryEntry.isBackgroundCommand - chrome.runtime.sendMessage {handler: "runBackgroundCommand", frameId, registryEntry, count} - else if registryEntry.passCountToFunction - Utils.invokeCommandString registryEntry.command, [count] - else - Utils.invokeCommandString registryEntry.command for i in [0...count] - +class NormalMode extends KeyHandlerMode + constructor: (options = {}) -> + super extend options, + name: "normal" + indicator: false # There is no mode indicator in normal mode. + commandHandler: @commandHandler.bind this + + chrome.storage.local.get "normalModeKeyStateMapping", (items) => + @setKeyMapping items.normalModeKeyStateMapping + + chrome.storage.onChanged.addListener (changes, area) => + if area == "local" and changes.normalModeKeyStateMapping?.newValue + @setKeyMapping changes.normalModeKeyStateMapping.newValue + + commandHandler: (registryEntry, count) -> + count *= registryEntry.options.count ? 1 + count = 1 if registryEntry.noRepeat + + if registryEntry.repeatLimit? and registryEntry.repeatLimit < count + return unless confirm """ + You have asked Vimium to perform #{count} repeats of the command: #{registryEntry.description}.\n + Are you sure you want to continue?""" + + if registryEntry.isBackgroundCommand + chrome.runtime.sendMessage {handler: "runBackgroundCommand", frameId, registryEntry, count} + else if registryEntry.passCountToFunction + Utils.invokeCommandString registryEntry.command, [count] + else + Utils.invokeCommandString registryEntry.command for i in [0...count] + +# Only exported for tests; also, "args..." is only for the tests. +window.initializeModes = (args...) -> # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and # activates/deactivates itself accordingly. - normalMode = new NormalMode + normalMode = new NormalMode args... new PassKeysMode normalMode new InsertMode permanent: true Scroller.init() -- cgit v1.2.3 From f2bced459457dcc962d4bafe2fdf2e6245506ee3 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Sun, 28 Feb 2016 16:07:25 +0000 Subject: Key bindings; tweaks. --- content_scripts/vimium_frontend.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index e821b136..ec666a23 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -107,13 +107,13 @@ class NormalMode extends KeyHandlerMode if area == "local" and changes.normalModeKeyStateMapping?.newValue @setKeyMapping changes.normalModeKeyStateMapping.newValue - commandHandler: (registryEntry, count) -> + commandHandler: ({command: registryEntry, count, event}) -> count *= registryEntry.options.count ? 1 count = 1 if registryEntry.noRepeat if registryEntry.repeatLimit? and registryEntry.repeatLimit < count return unless confirm """ - You have asked Vimium to perform #{count} repeats of the command: #{registryEntry.description}.\n + You have asked Vimium to perform #{count} repetitions of the command: #{registryEntry.description}.\n Are you sure you want to continue?""" if registryEntry.isBackgroundCommand -- cgit v1.2.3 From 9cfa00bc7db3e07c3abbeb09e483d9fdf20bbc17 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Mon, 29 Feb 2016 06:07:01 +0000 Subject: Key bindings; refactor passKeys. Previously, the key-handling logic (keyQueue, etc) was and the backend whereas passKeys were handled in the content scripts - so they were a long way apart. Now that they're in the same place, it makes more sense to integrate passKey handling into the regular key handling, because they depend upon the same data structures. --- content_scripts/vimium_frontend.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index ec666a23..46b21ed0 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -98,6 +98,7 @@ class NormalMode extends KeyHandlerMode super extend options, name: "normal" indicator: false # There is no mode indicator in normal mode. + trackState: true # Maintain @passKeys. commandHandler: @commandHandler.bind this chrome.storage.local.get "normalModeKeyStateMapping", (items) => @@ -127,8 +128,7 @@ class NormalMode extends KeyHandlerMode window.initializeModes = (args...) -> # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and # activates/deactivates itself accordingly. - normalMode = new NormalMode args... - new PassKeysMode normalMode + new NormalMode args... new InsertMode permanent: true Scroller.init() -- cgit v1.2.3 From e4193e2752ee7132ff16a7ba977857f70df2946b Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Mon, 29 Feb 2016 06:31:43 +0000 Subject: Key bindings; tweaks. --- content_scripts/vimium_frontend.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 46b21ed0..a4dd6986 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -108,7 +108,7 @@ class NormalMode extends KeyHandlerMode if area == "local" and changes.normalModeKeyStateMapping?.newValue @setKeyMapping changes.normalModeKeyStateMapping.newValue - commandHandler: ({command: registryEntry, count, event}) -> + commandHandler: ({command: registryEntry, count}) -> count *= registryEntry.options.count ? 1 count = 1 if registryEntry.noRepeat -- cgit v1.2.3 From 29708b3297a645966f7943682f8f7b8c2a332297 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Mon, 29 Feb 2016 06:48:27 +0000 Subject: Key bindings; refactor passKeys distribution. It makes more sense to pass the passKeys directly to normalMode. So, do so, and remove the trackState mode option - which isn't otherwise being used. --- content_scripts/vimium_frontend.coffee | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index a4dd6986..5401cf22 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -94,11 +94,12 @@ handlerStack.push true class NormalMode extends KeyHandlerMode + setPassKeys: (@passKeys) -> + constructor: (options = {}) -> super extend options, name: "normal" indicator: false # There is no mode indicator in normal mode. - trackState: true # Maintain @passKeys. commandHandler: @commandHandler.bind this chrome.storage.local.get "normalModeKeyStateMapping", (items) => @@ -127,8 +128,8 @@ class NormalMode extends KeyHandlerMode # Only exported for tests; also, "args..." is only for the tests. window.initializeModes = (args...) -> # Install the permanent modes. The permanently-installed insert mode tracks focus/blur events, and - # activates/deactivates itself accordingly. - new NormalMode args... + # activates/deactivates itself accordingly. normalMode is exported only for the tests. + window.normalMode = new NormalMode args... new InsertMode permanent: true Scroller.init() @@ -440,9 +441,7 @@ checkIfEnabledForUrl = (frameIsFocused = windowIsFocused()) -> if HUD.isReady() and not isEnabledForUrl # Quickly hide any HUD we might already be showing, e.g. if we entered insert mode on page load. HUD.hide() - handlerStack.bubbleEvent "registerStateChange", - enabled: isEnabledForUrl - passKeys: passKeys + normalMode?.setPassKeys passKeys # Update the page icon, if necessary. if windowIsFocused() chrome.runtime.sendMessage -- cgit v1.2.3 From 70151ea99cb86bbbf268ecb737337aa7cc266e2d Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Mon, 29 Feb 2016 07:23:31 +0000 Subject: Key bindings; and yet more tweaks. --- content_scripts/vimium_frontend.coffee | 2 -- 1 file changed, 2 deletions(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 5401cf22..01b02985 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -94,8 +94,6 @@ handlerStack.push true class NormalMode extends KeyHandlerMode - setPassKeys: (@passKeys) -> - constructor: (options = {}) -> super extend options, name: "normal" -- cgit v1.2.3 From 201451d94edefa8c873d417f5f6190d993204b5e Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Tue, 1 Mar 2016 13:13:08 +0000 Subject: Key bindings; move Vomnibar commands back to content scripts. --- content_scripts/vimium_frontend.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 01b02985..72be5510 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -116,7 +116,11 @@ class NormalMode extends KeyHandlerMode You have asked Vimium to perform #{count} repetitions of the command: #{registryEntry.description}.\n Are you sure you want to continue?""" - if registryEntry.isBackgroundCommand + # The Vomnibar needs special handling because it is always activated in the tab's main frame. + if registryEntry.command.startsWith "Vomnibar." + chrome.runtime.sendMessage + handler: "sendMessageToFrames", message: {name: "openVomnibar", sourceFrameId: frameId, registryEntry} + else if registryEntry.isBackgroundCommand chrome.runtime.sendMessage {handler: "runBackgroundCommand", frameId, registryEntry, count} else if registryEntry.passCountToFunction Utils.invokeCommandString registryEntry.command, [count] -- cgit v1.2.3 From fb67cfdd2ca8c09453cc896fd02d08ed5a74a8a4 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Fri, 4 Mar 2016 08:51:39 +0000 Subject: Key bindings; disable on disconnect. This reinstates the feature whereby we disable the content script when we lose contact with the background page, e.g., on upgrade. From my investigations, this doesn't appear to be absolutely necessary. Nevertheless, it's cleaner like this. --- content_scripts/vimium_frontend.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'content_scripts/vimium_frontend.coffee') diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index 72be5510..0ae3d229 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -214,7 +214,11 @@ window.addEventListener "hashchange", onFocus # initializeOnDomReady = -> # Tell the background page we're in the dom ready state. - chrome.runtime.connect({ name: "domReady" }) + chrome.runtime.connect(name: "domReady").onDisconnect.addListener -> + # We disable content scripts when we lose contact with the background page. + isEnabledForUrl = false + chrome.runtime.sendMessage = -> + window.removeEventListener "focus", onFocus # We only initialize the vomnibar in the tab's main frame, because it's only ever opened there. Vomnibar.init() if DomUtils.isTopFrame() HUD.init() -- cgit v1.2.3