@@ -33,6 +33,9 @@ define(function (require, exports, module) {
3333 const EventDispatcher = require ( "utils/EventDispatcher" ) ;
3434
3535 const EVENT_BEFORE_EXECUTE_COMMAND = "beforeExecuteCommand" ;
36+ const SOURCE_KEYBOARD_SHORTCUT = "keyboardShortcut" ,
37+ SOURCE_UI_MENU_CLICK = "uiMenuClick" ,
38+ SOURCE_OTHER = "otherExecAction" ;
3639
3740
3841 /**
@@ -62,13 +65,15 @@ define(function (require, exports, module) {
6265 * @param {function } commandFn - the function that is called when the command is executed.
6366 *
6467 * TODO: where should this be triggered, The Command or Exports?
68+ * @param [options]
6569 */
66- function Command ( name , id , commandFn ) {
70+ function Command ( name , id , commandFn , options = { } ) {
6771 this . _name = name ;
6872 this . _id = id ;
6973 this . _commandFn = commandFn ;
7074 this . _checked = undefined ;
7175 this . _enabled = true ;
76+ this . _options = options ;
7277 }
7378 EventDispatcher . makeEventDispatcher ( Command . prototype ) ;
7479
@@ -89,8 +94,17 @@ define(function (require, exports, module) {
8994 if ( ! this . _enabled ) {
9095 return ( new $ . Deferred ( ) ) . reject ( ) . promise ( ) ;
9196 }
92-
93- var result = this . _commandFn . apply ( this , arguments ) ;
97+ let args = arguments ;
98+ if ( this . _options . eventSource ) {
99+ // This command has been registered with the optional source details set we have to ensure the event
100+ // argument is inserted first. The event source may be already injected by the executor,
101+ // if not we have to do it now.
102+ if ( ! args . length || ! ( typeof args [ 0 ] === 'object' && args [ 0 ] . eventSource ) ) {
103+ const event = { eventSource : SOURCE_OTHER } ; // default we don't know the source
104+ args = [ event ] . concat ( args ) ;
105+ }
106+ }
107+ let result = this . _commandFn . apply ( this , args ) ;
94108 if ( ! result ) {
95109 // If command does not return a promise, assume that it handled the
96110 // command and return a resolved promise
@@ -184,9 +198,13 @@ define(function (require, exports, module) {
184198 * execute() (after the id) are passed as arguments to the function. If the function is asynchronous,
185199 * it must return a jQuery promise that is resolved when the command completes. Otherwise, the
186200 * CommandManager will assume it is synchronous, and return a promise that is already resolved.
201+ * @param {Object } [options]
202+ * @param {boolean } options.eventSource If set to true, the commandFn will be called with the first argument `event`
203+ * with details about the source(invoker) as event.eventSource(one of the `CommandManager.SOURCE_*`) and
204+ * event.sourceType(Eg. Ctrl-K) parameter.
187205 * @return {?Command }
188206 */
189- function register ( name , id , commandFn ) {
207+ function register ( name , id , commandFn , options = { } ) {
190208 if ( _commands [ id ] ) {
191209 console . log ( "Attempting to register an already-registered command: " + id ) ;
192210 return null ;
@@ -196,7 +214,7 @@ define(function (require, exports, module) {
196214 return null ;
197215 }
198216
199- var command = new Command ( name , id , commandFn ) ;
217+ var command = new Command ( name , id , commandFn , options ) ;
200218 _commands [ id ] = command ;
201219
202220 exports . trigger ( "commandRegistered" , command ) ;
@@ -283,8 +301,18 @@ define(function (require, exports, module) {
283301 } catch ( err ) {
284302 console . error ( err ) ;
285303 }
304+ let args = Array . prototype . slice . call ( arguments , 1 ) ; // remove id
305+ if ( command . _options . eventSource ) {
306+ // This command has been registered with the optional source details set we have to ensure the event
307+ // argument is inserted first. The event source may be already injected by the executor,
308+ // if not we have to do it now.
309+ if ( ! args . length || ! ( typeof args [ 0 ] === 'object' && args [ 0 ] . eventSource ) ) {
310+ const event = { eventSource : SOURCE_OTHER } ; // default we don't know the source
311+ args = [ event ] . concat ( args ) ;
312+ }
313+ }
286314
287- return command . execute . apply ( command , Array . prototype . slice . call ( arguments , 1 ) ) ;
315+ return command . execute . apply ( command , args ) ;
288316 }
289317 return ( new $ . Deferred ( ) ) . reject ( ) . promise ( ) ;
290318
@@ -301,4 +329,7 @@ define(function (require, exports, module) {
301329 exports . _testReset = _testReset ;
302330 exports . _testRestore = _testRestore ;
303331 exports . EVENT_BEFORE_EXECUTE_COMMAND = EVENT_BEFORE_EXECUTE_COMMAND ;
332+ exports . SOURCE_KEYBOARD_SHORTCUT = SOURCE_KEYBOARD_SHORTCUT ;
333+ exports . SOURCE_UI_MENU_CLICK = SOURCE_UI_MENU_CLICK ;
334+ exports . SOURCE_OTHER = SOURCE_OTHER ;
304335} ) ;
0 commit comments