foam-framework
Version:
MVC metaprogramming framework
69 lines (59 loc) • 2 kB
JavaScript
// TODO: used in saturnmail/bg.js, see if can be merged with Action keyboard support.
function KeyboardShortcutController(win, view) {
this.contexts_ = {};
this.body_ = {};
this.processView_(view);
win.addEventListener('keydown', this.processKey_.bind(this));
}
KeyboardShortcutController.prototype.processView_ = function(view) {
var keyShortcuts = view.shortcuts;
if (keyShortcuts) {
keyShortcuts.forEach(function(nav) {
var key = nav[0];
var cb = nav[1];
var context = nav[2];
this.addAccelerator(key, cb, context);
}.bind(this));
}
try {
var children = view.children;
children.forEach(this.processView_.bind(this));
} catch(e) { console.log(e); }
};
KeyboardShortcutController.prototype.addAccelerator = function(key, callback, context) {
if (context) {
if (typeof(context) != 'string')
throw "Context must be an identifier for a DOM node.";
if (!(context in this.contexts_))
this.contexts_[context] = {};
this.contexts_[context][key] = callback;
} else {
this.body_[key] = callback;
}
};
KeyboardShortcutController.prototype.shouldIgnoreKeyEventsForTarget_ = function(event) {
var target = event.target;
return target.isContentEditable || target.tagName == 'INPUT' || target.tagName == 'TEXTAREA';
};
KeyboardShortcutController.prototype.processKey_ = function(event) {
if (this.shouldIgnoreKeyEventsForTarget_(event))
return;
for ( var node = event.target; node && node != document.body; node = node.parentNode ) {
var id = node.id;
if ( id && (id in this.contexts_) ) {
var cbs = this.contexts_[id];
if ( event.keyIdentifier in cbs ) {
var cb = cbs[event.keyIdentifier];
cb(event);
event.preventDefault();
return;
}
}
}
console.log('Looking for ' + event.keyIdentifier);
if ( event.keyIdentifier in this.body_ ) {
var cb = this.body_[event.keyIdentifier];
cb(event);
event.preventDefault();
}
};