From 33c1a0b4a02ca6d83381fc1076cee0d41d9a7346 Mon Sep 17 00:00:00 2001 From: surgesoft Date: Fri, 10 Oct 2014 17:54:02 +0800 Subject: [PATCH] Change keyboard shortcut context closes #4247 - added scope to every shortcut, the scope of shortcut is default to 'default' - add shortcut `enter` to modal which confirm the modal - shortcut `enter` and `esc` now have scope 'modal' - when lunch a modal, scope is switching to 'modal', and set back to 'default' when close - shortcut `enter` now confirm the dialog without conflicting with route shortcuts --- mixins/shortcuts-route.js | 28 ++++++++++++++++++++-------- routes/application.js | 16 +++++++++++++++- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/mixins/shortcuts-route.js b/mixins/shortcuts-route.js index bc9d21d1d..1d74d5380 100644 --- a/mixins/shortcuts-route.js +++ b/mixins/shortcuts-route.js @@ -7,6 +7,7 @@ key.filter = function () { return true; }; +key.setScope('default'); /** * Only routes can implement shortcuts. * If you need to trigger actions on the controller, @@ -30,6 +31,15 @@ key.filter = function () { * 'ctrl+k': {action: 'markdownShortcut', options: 'createLink'} * } * ``` + * You can set the scope of your shortcut by passing a scope property. + * ```javascript + * shortcuts : { + * 'enter': {action : 'confirmModal', scope: 'modal'} + * } + * ``` + * If you don't specify a scope, we use a default scope called "default". + * To have all your shortcut work in all scopes, give it the scope "all". + * Find out more at the keymaster docs */ var ShortcutsRoute = Ember.Mixin.create({ registerShortcuts: function () { @@ -37,14 +47,16 @@ var ShortcutsRoute = Ember.Mixin.create({ shortcuts = this.get('shortcuts'); Ember.keys(shortcuts).forEach(function (shortcut) { - key(shortcut, function (event) { - var action = shortcuts[shortcut], - options; - if (Ember.typeOf(action) !== 'string') { - options = action.options; - action = action.action; - } - + var scope = shortcuts[shortcut].scope || 'default', + action = shortcuts[shortcut], + options; + + if (Ember.typeOf(action) !== 'string') { + options = action.options; + action = action.action; + } + + key(shortcut, scope, function (event) { //stop things like ctrl+s from actually opening a save dialogue event.preventDefault(); self.send(action, options); diff --git a/routes/application.js b/routes/application.js index d47628b24..a1240ded7 100644 --- a/routes/application.js +++ b/routes/application.js @@ -1,3 +1,4 @@ +/* global key */ import ShortcutsRoute from 'ghost/mixins/shortcuts-route'; var ApplicationRoute = Ember.Route.extend(SimpleAuth.ApplicationRouteMixin, ShortcutsRoute, { @@ -9,7 +10,8 @@ var ApplicationRoute = Ember.Route.extend(SimpleAuth.ApplicationRouteMixin, Shor }, shortcuts: { - 'esc': 'closePopups' + 'esc': {action: 'closePopups', scope: 'all'}, + 'enter': {action: 'confirmModal', scope: 'modal'} }, actions: { @@ -79,7 +81,9 @@ var ApplicationRoute = Ember.Route.extend(SimpleAuth.ApplicationRouteMixin, Shor openModal: function (modalName, model, type) { this.get('dropdown').closeDropdowns(); + key.setScope('modal'); modalName = 'modals/' + modalName; + this.set('modalName', modalName); // We don't always require a modal to have a controller // so we're skipping asserting if one exists if (this.controllerFor(modalName, true)) { @@ -90,17 +94,27 @@ var ApplicationRoute = Ember.Route.extend(SimpleAuth.ApplicationRouteMixin, Shor this.controllerFor(modalName).set('src', model.get(type)); } } + return this.render(modalName, { into: 'application', outlet: 'modal' }); }, + confirmModal : function () { + var modalName = this.get('modalName'); + this.send('closeModal'); + if (this.controllerFor(modalName, true)) { + this.controllerFor(modalName).send('confirmAccept'); + } + }, + closeModal: function () { this.disconnectOutlet({ outlet: 'modal', parentView: 'application' }); + key.setScope('default'); }, loadServerNotifications: function (isDelayed) {