diff --git a/modules/ve/actions/ve.IndentationAction.js b/modules/ve/actions/ve.IndentationAction.js index 2d08551adb..3aa8b860a8 100644 --- a/modules/ve/actions/ve.IndentationAction.js +++ b/modules/ve/actions/ve.IndentationAction.js @@ -40,9 +40,11 @@ ve.IndentationAction.static.methods = ['increase', 'decrease']; * TODO: Refactor functionality into {ve.dm.SurfaceFragment}. * * @method + * @returns {Boolean} Indentation increase occured */ ve.IndentationAction.prototype.increase = function () { var i, group, + increased = false, surfaceModel = this.surface.getModel(), documentModel = surfaceModel.getDocument(), selection = surfaceModel.getSelection(), @@ -53,8 +55,10 @@ ve.IndentationAction.prototype.increase = function () { if ( group.grandparent && group.grandparent.getType() === 'list' ) { // FIXME this doesn't work when trying to work with multiple list items this.indentListItem( group.parent ); + increased = true; } } + return increased; }; /** @@ -63,9 +67,11 @@ ve.IndentationAction.prototype.increase = function () { * TODO: Refactor functionality into {ve.dm.SurfaceFragment}. * * @method + * @returns {Boolean} Indentation decrease occured */ ve.IndentationAction.prototype.decrease = function () { var i, group, + decreased = false, surfaceModel = this.surface.getModel(), documentModel = surfaceModel.getDocument(), selection = surfaceModel.getSelection(), @@ -76,8 +82,10 @@ ve.IndentationAction.prototype.decrease = function () { if ( group.grandparent && group.grandparent.getType() === 'list' ) { // FIXME this doesn't work when trying to work with multiple list items this.outdentListItem( group.parent ); + decreased = true; } } + return decreased; }; /** diff --git a/modules/ve/ce/ve.ce.Surface.js b/modules/ve/ce/ve.ce.Surface.js index eeb6fbdaed..2f47e140bc 100644 --- a/modules/ve/ce/ve.ce.Surface.js +++ b/modules/ve/ce/ve.ce.Surface.js @@ -423,20 +423,6 @@ ve.ce.Surface.prototype.onKeyDown = function ( e ) { hasSlug, newOffset; switch ( e.keyCode ) { - // Tab Key - case 9: - // If possible, trigger a list indent/outdent - // FIXME this way of checking whether indenting is possible is extremely hacky - // Instead, we should allow toolbar tools to subscribe to and intercept keydowns - if ( $( '.ve-ui-toolbarButtonTool-indent' ).is( ':not(.ve-ui-toolbarButtonTool-disabled)' ) ) { - e.preventDefault(); - if ( e.shiftKey ) { - ve.ui.IndentationButtonTool.outdentListItem( this.model ); - } else { - ve.ui.IndentationButtonTool.indentListItem( this.model ); - } - } - break; // Left arrow case 37: offset = this.model.getSelection().start; diff --git a/modules/ve/ve.Action.js b/modules/ve/ve.Action.js index e2a3f127b4..0de65d19b4 100644 --- a/modules/ve/ve.Action.js +++ b/modules/ve/ve.Action.js @@ -30,6 +30,12 @@ ve.Action.static = {}; * To avoid use of methods not intended to be executed via surface.execute(), the methods must be * whitelisted here. This information is checked by ve.Surface before executing an action. * + * If a method returns a value, it will be cast to boolean and be used to determine if the action + * was canceled. Not returning anything, or returning undefined will be treated the same as + * returning true. A canceled action will yield to other default behavior. For example, when + * triggering an action from a keystroke, a canceled action will allow normal insertion behavior to + * be carried out. + * * @static * @member */ diff --git a/modules/ve/ve.CommandRegistry.js b/modules/ve/ve.CommandRegistry.js index 4e46c41306..0fe11b237a 100644 --- a/modules/ve/ve.CommandRegistry.js +++ b/modules/ve/ve.CommandRegistry.js @@ -66,3 +66,5 @@ ve.commandRegistry.register( ve.commandRegistry.register( 'link', ['cmd+k', 'ctrl+k'], 'inspector', 'open', 'link' ); ve.commandRegistry.register( 'undo', ['cmd+z', 'ctrl+z'], 'history', 'undo' ); ve.commandRegistry.register( 'redo', ['cmd+shift+z', 'ctrl+shift+z'], 'history', 'redo' ); +ve.commandRegistry.register( 'indent', ['tab'], 'indentation', 'increase' ); +ve.commandRegistry.register( 'unindent', ['shift+tab'], 'indentation', 'decrease' ); diff --git a/modules/ve/ve.Surface.js b/modules/ve/ve.Surface.js index 2915d2fe65..c3f651d4ba 100644 --- a/modules/ve/ve.Surface.js +++ b/modules/ve/ve.Surface.js @@ -60,7 +60,7 @@ ve.Surface.defaultOptions = { } }, // Items can either be symbolic names or objects with trigger and action properties - 'commands': ['bold', 'italic', 'link', 'undo', 'redo'] + 'commands': ['bold', 'italic', 'link', 'undo', 'redo', 'indent', 'unindent'] }; /* Methods */ @@ -115,18 +115,19 @@ ve.Surface.prototype.getContext = function () { * @returns {Boolean} Action or command was executed */ ve.Surface.prototype.execute = function ( action, method ) { - var trigger, obj; + var trigger, obj, ret; if ( action instanceof ve.Command ) { trigger = action.toString(); if ( trigger in this.commands ) { - this.execute.apply( this, this.commands[trigger] ); + return this.execute.apply( this, this.commands[trigger] ); } } else if ( typeof action === 'string' && typeof method === 'string' ) { // Validate method if ( ve.actionFactory.doesActionSupportMethod( action, method ) ) { // Create an action object and execute the method on it obj = ve.actionFactory.create( action, this ); - obj[method].apply( obj, Array.prototype.slice.call( arguments, 2 ) ); + ret = obj[method].apply( obj, Array.prototype.slice.call( arguments, 2 ) ); + return ret === undefined || !!ret; } } return false;