Skip to content

Commit 71da0b2

Browse files
authored
Merge pull request #176 from televator-apps/172-isolation
Normal mode isolation
2 parents 362da89 + fc7e011 commit 71da0b2

File tree

3 files changed

+804
-542
lines changed

3 files changed

+804
-542
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Changelog
66
* Update Vimari interface to allow users access to their configuration.
77
* Remove `closeTabReverse` action.
88

9+
* Normal mode now isolates keybindings from the underlying website, this means that to interact with the underlying website you need to enter insert mode.
10+
* You can enter insert mode by pressing <kbd>i</kbd> and exit the mode by pressing <kbd>esc</kbd>.
11+
* In insert mode Vimari keybindings are disabled (except for <kbd>esc</kbd> which brings you back to normal mode) allowing you to interact with the underlying website.
12+
913
### 2.0.3 (2019-09-26)
1014

1115
* Fix newTabHintToggle to use shift+f instead of F

Vimari Extension/js/injected.js

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ var actionMap = {
8484
};
8585

8686
// Meant to be overridden, but still has to be copy/pasted from the original...
87-
Mousetrap.stopCallback = function(e, element, combo) {
87+
Mousetrap.prototype.stopCallback = function(e, element, combo) {
8888
// Escape key is special, no need to stop. Vimari-specific.
8989
if (combo === 'esc' || combo === 'ctrl+[') { return false; }
9090

@@ -159,8 +159,27 @@ function executeAction(actionName) {
159159

160160
function unbindKeyCodes() {
161161
Mousetrap.reset();
162+
document.removeEventListener("keydown", stopSitePropagation);
162163
}
163164

165+
// Stops propagation of keyboard events in normal mode. Adding this
166+
// callback to the document using the useCapture flag allows us to
167+
// prevent custom key behaviour implemented by the underlying website.
168+
function stopSitePropagation() {
169+
return function (e) {
170+
if (insertMode == false && !isActiveElementEditable()) {
171+
e.stopPropagation()
172+
}
173+
}
174+
}
175+
176+
// Check whether the current active element is editable.
177+
function isActiveElementEditable() {
178+
const el = document.activeElement;
179+
return (el != null && isEditable(el))
180+
}
181+
182+
164183
// Adds an optional modifier to the configured key code for the action
165184
function getKeyCode(actionName) {
166185
var keyCode = '';
@@ -210,24 +229,24 @@ function isEmbed(element) { return ["EMBED", "OBJECT"].indexOf(element.tagName)
210229
// Message handling functions
211230
// ==========================
212231

232+
function messageHandler(event){
233+
if (event.name == "updateSettingsEvent") {
234+
setSettings(event.message);
235+
}
236+
}
237+
213238
/*
214239
* Callback to pass settings to injected script
215240
*/
216241
function setSettings(msg) {
217242
settings = msg;
218-
bindKeyCodesToActions(msg);
243+
activateExtension(settings);
219244
}
220245

221-
/*
222-
* Enable or disable the extension on this tab
223-
*/
224-
function setActive(msg) {
225-
extensionActive = msg;
226-
if(msg) {
227-
bindKeyCodesToActions();
228-
} else {
229-
unbindKeyCodes();
230-
}
246+
function activateExtension(settings) {
247+
// Stop keydown propagation
248+
document.addEventListener("keydown", stopSitePropagation(), true);
249+
bindKeyCodesToActions(settings);
231250
}
232251

233252
function isExcludedUrl(storedExcludedUrls, currentUrl) {
@@ -275,12 +294,6 @@ function inIframe () {
275294
if(!inIframe()){
276295
extensionCommunicator.requestSettingsUpdate()
277296
}
278-
279-
function messageHandler(event){
280-
if (event.name == "updateSettingsEvent") {
281-
setSettings(event.message);
282-
}
283-
}
284297

285298
// Export to make it testable
286299
window.isExcludedUrl = isExcludedUrl;

0 commit comments

Comments
 (0)