-
Routes and Views can subscribe to shortcuts via some API to be determined. Fundamentally it will map key sequences (eg.
esc
,g i
,ctrl+x ctrl+c
) to actions on that object. The parsing and implementation of the key sequence can be left to an external library. Ember could ship with a basic one, ie. only length one sequences. -
The keyboard shortcuts service would register a listener on the document object (or the ApplicationView, but Firefox has some weird focus behaviour when not using tab indices).
-
When a key event is caught, Ember inspects event.target for the nearest containing view (if any) and begins walking up the view tree, until it matches a shortcut on some view. If one matches then the associated action is called and the process stops.
-
If no view has a matching shortcut, then Ember checks to see if any global shortcuts are registered by a route.
-
Because the event is caught on the document
event.stopPropagation
is not needed. Typically, a shortcut will want to callevent.preventDefault
so this is the default behaviour. It can be overriden by passing indefault: true
. A distinction could be made for key up events as well by passingkeyUp: true
.
App.ApplicationRoute = Ember.Route.Extend({
shortcuts: {
// Call the action on the route
'cmr+r': 'refresh',
// Call the action on the route's controller
'?': { action: 'toggleHelpModal', target: 'controller' },
// or...
'?': { action: 'toggleHelpModal', controller: true },
// Call the action on another controller
'ctrl+q': { action: 'logout', controller: 'session' }
}
})
App.CommentView = Ember.View.Extend({
shortcuts: {
// Call the action on the view
'esc': 'cancel',
// Call the action on a different target such as controller or parentView
'shift+enter': { action: 'submit', target: 'controller' },
// Don't call `preventDefault`
'x': { action: 'userTypedX', default: true }
}
})