aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--background_scripts/commands.coffee3
-rw-r--r--content_scripts/mode.coffee2
-rw-r--r--content_scripts/mode_edit.coffee33
-rw-r--r--content_scripts/vimium_frontend.coffee18
-rw-r--r--manifest.json1
5 files changed, 52 insertions, 5 deletions
diff --git a/background_scripts/commands.coffee b/background_scripts/commands.coffee
index 485195a9..f8167042 100644
--- a/background_scripts/commands.coffee
+++ b/background_scripts/commands.coffee
@@ -112,6 +112,7 @@ Commands =
"goToRoot",
"enterInsertMode",
"enterVisualMode",
+ "enterEditMode",
"focusInput",
"LinkHints.activateMode",
"LinkHints.activateModeToOpenInNewTab",
@@ -197,6 +198,7 @@ defaultKeyMappings =
"i": "enterInsertMode"
"v": "enterVisualMode"
+ "gv": "enterEditMode"
"H": "goBack"
"L": "goForward"
@@ -286,6 +288,7 @@ commandDescriptions =
enterInsertMode: ["Enter insert mode", { noRepeat: true }]
enterVisualMode: ["Enter visual mode (not yet implemented)", { noRepeat: true }]
+ enterEditMode: ["Enter vim-like edit mode (not yet implemented)", { noRepeat: true }]
focusInput: ["Focus the first text box on the page. Cycle between them using tab",
{ passCountToFunction: true }]
diff --git a/content_scripts/mode.coffee b/content_scripts/mode.coffee
index acc3978e..a74acfed 100644
--- a/content_scripts/mode.coffee
+++ b/content_scripts/mode.coffee
@@ -34,7 +34,7 @@ count = 0
class Mode
# If Mode.debug is true, then we generate a trace of modes being activated and deactivated on the console.
- debug: false
+ debug: true
@modes: []
# Constants; short, readable names for the return values expected by handlerStack.bubbleEvent.
diff --git a/content_scripts/mode_edit.coffee b/content_scripts/mode_edit.coffee
new file mode 100644
index 00000000..32f2e796
--- /dev/null
+++ b/content_scripts/mode_edit.coffee
@@ -0,0 +1,33 @@
+
+class EditMode extends Mode
+ @activeElements = []
+
+ constructor: (options = {}) ->
+ defaults =
+ name: "edit"
+ exitOnEscape: true
+ keydown: (event) => if @isActive() then @handleKeydown event else @continueBubbling
+ keypress: (event) => if @isActive() then @handleKeypress event else @continueBubbling
+ keyup: (event) => if @isActive() then @handleKeyup event else @continueBubbling
+
+ @element = document.activeElement
+ if @element and DomUtils.isEditable @element
+ super extend defaults, options
+
+ handleKeydown: (event) -> @suppressEvent
+ handleKeypress: (event) -> @suppressEvent
+ handleKeyup: (event) -> @suppressEvent
+
+ isActive: ->
+ document.activeElement and DomUtils.isDOMDescendant @element, document.activeElement
+
+ exit: (event, target) ->
+ super()
+ @element.blur() if target? and DomUtils.isDOMDescendant @element, target
+ EditMode.activeElements = EditMode.activeElements.filter (element) => element != @element
+
+ updateBadge: (badge) ->
+ badge.badge = "E" if @isActive()
+
+root = exports ? window
+root.EditMode = EditMode
diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee
index 725d8a53..79302930 100644
--- a/content_scripts/vimium_frontend.coffee
+++ b/content_scripts/vimium_frontend.coffee
@@ -328,9 +328,12 @@ extend window,
enterInsertMode: ->
new InsertMode global: true
- enterVisualMode: =>
+ enterVisualMode: ->
new VisualMode()
+ enterEditMode: ->
+ @focusInput 1, EditMode
+
focusInput: do ->
# Track the most recently focused input element.
recentlyFocusedElement = null
@@ -340,10 +343,11 @@ extend window,
recentlyFocusedElement = event.target if DomUtils.isEditable event.target
true
- (count) ->
+ (count, mode = InsertMode) ->
# Focus the first input element on the page, and create overlays to highlight all the input elements, with
# the currently-focused element highlighted specially. Tabbing will shift focus to the next input element.
# Pressing any other key will remove the overlays and the special tab behavior.
+ # If mode is provided, then enter that mode on exit. Otherwise, just let insert mode take over.
resultSet = DomUtils.evaluateXPath textInputXPath, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
visibleInputs =
for i in [0...resultSet.snapshotLength] by 1
@@ -395,8 +399,7 @@ extend window,
@exit()
@continueBubbling
- @onExit -> DomUtils.removeElement hintContainingDiv
- hintContainingDiv = DomUtils.addElementList hints,
+ @hintContainingDiv = DomUtils.addElementList hints,
id: "vimiumInputMarkerContainer"
className: "vimiumReset"
@@ -406,6 +409,13 @@ extend window,
else
hints[selectedInputIndex].classList.add 'internalVimiumSelectedInputHint'
+ exit: ->
+ super()
+ DomUtils.removeElement @hintContainingDiv
+ if mode and DomUtils.isEditable document.activeElement
+ new mode
+ singleton: document.activeElement
+
# Decide whether this keyChar should be passed to the underlying page.
# Keystrokes are *never* considered passKeys if the keyQueue is not empty. So, for example, if 't' is a
# passKey, then 'gt' and '99t' will neverthless be handled by vimium.
diff --git a/manifest.json b/manifest.json
index a04d8c0e..e8b0f8ee 100644
--- a/manifest.json
+++ b/manifest.json
@@ -48,6 +48,7 @@
"content_scripts/mode_passkeys.js",
"content_scripts/mode_find.js",
"content_scripts/mode_visual.js",
+ "content_scripts/mode_edit.js",
"content_scripts/vimium_frontend.js"
],
"css": ["content_scripts/vimium.css"],