]> git.gir.st - VimFx.git/blob - extension/packages/events.coffee
Key handling bug fixing
[VimFx.git] / extension / packages / events.coffee
1 utils = require 'utils'
2 keyUtils = require 'key-utils'
3 { getCommand } = require 'commands'
4 { Vim } = require 'vim'
5 { getPref } = require 'prefs'
6 { setWindowBlacklisted } = require 'button'
7
8 { interfaces: Ci } = Components
9
10 vimBucket = new utils.Bucket utils.getWindowId, (obj) -> new Vim obj
11
12 suppressEvent = (event) ->
13 event.preventDefault()
14 event.stopPropagation()
15
16 # *************************
17 # NB! All this shit needs to be redone!!
18 # *************************
19
20 # The following listeners are installed on every top level Chrome window
21 windowsListener =
22 'keydown': (event) ->
23
24 if getPref 'disabled'
25 return
26
27 try
28 isEditable = utils.isElementEditable event.originalTarget
29
30 { ctrlKey: ctrl, metaKey: meta, altKey: alt, shiftKey: shift } = event
31
32 # any keys modified with meta or alt should be ignored
33 if meta or alt
34 return
35
36 # Extract keyChar from keyCode and apply modifiers
37 if keyChar = keyUtils.keyCharFromCode(event.keyCode, shift)
38 keyStr = keyUtils.applyModifiers(keyChar, ctrl, alt, meta)
39
40 # We only handle the key if it's recognized by `keyCharFromCode`
41 # and if there is no focused editable element # or if it's the *Esc* key,
42 # which will remove the focus from the currently focused element
43 if keyStr and (not isEditable or keyStr == 'Esc')
44 if window = utils.getCurrentTabWindow event
45 if vim = vimBucket.get(window)
46 # No action if blacklisted
47 if vim.blacklisted
48 return
49
50 if vim.handleKeyDown(event, keyStr)
51 if keyStr != 'Esc'
52 suppressEvent event
53 catch err
54 console.log err, 'keydown'
55 console.stacktrace()
56
57 'keypress': (event) ->
58 if getPref 'disabled'
59 return
60
61 try
62 isEditable = utils.isElementEditable event.originalTarget
63
64 # Try to execute keys that were accumulated so far.
65 # Suppress event if there is a matching command.
66 if window = utils.getCurrentTabWindow event
67 if vim = vimBucket.get(window)
68 # No action on blacklisted locations
69 if vim.blacklisted
70 return
71
72 lastKeyStr = vim.keys[vim.keys.length - 1]
73
74 # Blur from any active element on Esc. Calling before `handleKeyPress`
75 # because `vim.keys` will be reset afterwards`
76 blur_on_esc = lastKeyStr == 'Esc' and getPref 'blur_on_esc'
77
78 # Process event if there is no editable element in focus
79 # Or last key was Esc key
80 if not isEditable or lastKeyStr == 'Esc'
81 result = vim.handleKeyPress event
82
83 # If there was some processing done then suppress the eveng
84 # unless it's the Esc key
85 if result or lastKeyStr == 'Esc'
86 suppressEvent event
87
88 # Calling after the command has been executed
89 if blur_on_esc
90 event.originalTarget?.ownerDocument?.activeElement?.blur()
91
92 catch err
93 console.log err, 'keypress'
94 console.stacktrace()
95
96 # When the top level window closes we should release all Vims that were
97 # associated with tabs in this window
98 'DOMWindowClose': (event) ->
99 if gBrowser = event.originalTarget.gBrowser
100 for tab in gBrowser.tabs
101 if browser = gBrowser.getBrowserForTab tab
102 vimBucket.forget browser.contentWindow
103
104 'TabClose': (event) ->
105 if gBrowser = utils.getEventTabBrowser event
106 if browser = gBrowser.getBrowserForTab event.originalTarget
107 vimBucket.forget browser.contentWindow
108
109 # Update the toolbar button icon to reflect the blacklisted state
110 'TabSelect': (event) ->
111 if vim = vimBucket.get event.originalTarget?.linkedBrowser?.contentDocument?.defaultView
112 if rootWindow = utils.getRootWindow vim.window
113 setWindowBlacklisted rootWindow, vim.blacklisted
114
115 # This listener works on individual tabs within Chrome Window
116 # User for: listening for location changes and disabling the extension
117 # on black listed urls
118 tabsListener =
119 onLocationChange: (browser, webProgress, request, location) ->
120 blacklisted = utils.isBlacklisted location.spec, getPref 'black_list'
121 if vim = vimBucket.get(browser.contentWindow)
122 vim.blacklisted = blacklisted
123 if rootWindow = utils.getRootWindow vim.window
124 setWindowBlacklisted rootWindow, vim.blacklisted
125
126 addEventListeners = (window) ->
127 for name, listener of windowsListener
128 window.addEventListener name, listener, true
129
130 # Install onLocationChange listener
131 window.gBrowser.addTabsProgressListener tabsListener
132
133 removeEventListeners = ->
134 for name, listener of windowsListener
135 window.removeEventListener name, listener, true
136
137 unload ->
138 removeEventListeners window
139 window.gBrowser.removeTabsProgressListener tabsListener
140
141 exports.addEventListeners = addEventListeners
Imprint / Impressum