blob: 511602e704bc72d51b8c06754631f39ca9039ec0 (
plain)
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 | 
class InsertMode extends Mode
  constructor: (options = {}) ->
    # There is one permanently-installed instance of InsertMode.  It tracks focus changes and
    # activates/deactivates itself (by setting @insertModeLock) accordingly.
    @permanent = options.permanent
    # If truthy, then we were activated by the user (with "i").
    @global = options.global
    handleKeyEvent = (event) =>
      return @continueBubbling unless @isActive event
      # See comment here: https://github.com/philc/vimium/commit/48c169bd5a61685bb4e67b1e76c939dbf360a658.
      activeElement = @getActiveElement()
      return @passEventToPage if activeElement == document.body and activeElement.isContentEditable
      # Check for a pass-next-key key.
      if KeyboardUtils.getKeyCharString(event) in Settings.get "passNextKeyKeys"
        new PassNextKeyMode
      else if event.type == 'keydown' and KeyboardUtils.isEscape(event)
        activeElement.blur() if DomUtils.isFocusable activeElement
        @exit() unless @permanent
      else
        return @passEventToPage
      return @suppressEvent
    defaults =
      name: "insert"
      indicator: if not @permanent and not Settings.get "hideHud"  then "Insert mode"
      keypress: handleKeyEvent
      keydown: handleKeyEvent
    super extend defaults, options
    # Only for tests.  This gives us a hook to test the status of the permanently-installed instance.
    InsertMode.permanentInstance = this if @permanent
  isActive: (event) ->
    return false if event == InsertMode.suppressedEvent
    return true if @global
    DomUtils.isFocusable @getActiveElement()
  getActiveElement: ->
    activeElement = document.activeElement
    while activeElement?.shadowRoot?.activeElement
      activeElement = activeElement.shadowRoot.activeElement
    activeElement
  # Static stuff. This allows PostFindMode to suppress the permanently-installed InsertMode instance.
  @suppressedEvent: null
  @suppressEvent: (event) -> @suppressedEvent = event
# This implements the pasNexKey command.
class PassNextKeyMode extends Mode
  constructor: (count = 1) ->
    seenKeyDown = false
    keyDownCount = 0
    super
      name: "pass-next-key"
      indicator: "Pass next key."
      # We exit on blur because, once we lose the focus, we can no longer track key events.
      exitOnBlur: window
      keypress: =>
        @passEventToPage
      keydown: =>
        seenKeyDown = true
        keyDownCount += 1
        @passEventToPage
      keyup: =>
        if seenKeyDown
          unless 0 < --keyDownCount
            unless 0 < --count
              @exit()
        @passEventToPage
root = exports ? (window.root ?= {})
root.InsertMode = InsertMode
root.PassNextKeyMode = PassNextKeyMode
extend window, root unless exports?
 |