From 2bd34cebd40d3c0d9157566a4e04a9fdcaaec04e Mon Sep 17 00:00:00 2001 From: David Lynch Date: Wed, 30 Nov 2016 11:21:38 -0600 Subject: [PATCH] Save Dialog: add shortcut for opening to the review panel Create a new MWSaveDialogAction, which can be hooked up to triggers. Switch the existing save dialog accesskey to just use the trigger system. (Maintaining all the accesskey logic, so we don't change the shortcut on people.) Bug: T149914 Change-Id: I9b4ef8504148703556f802b266a517dd5098c06b --- extension.json | 6 +- .../ve.init.mw.DesktopArticleTarget.js | 2 +- .../ve-mw/init/ve.init.mw.ArticleTarget.js | 36 +++--- .../ui/actions/ve.ui.MWSaveDialogAction.js | 103 ++++++++++++++++++ .../ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js | 2 +- 5 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 modules/ve-mw/ui/actions/ve.ui.MWSaveDialogAction.js diff --git a/extension.json b/extension.json index 987cf438ed..d2f1ff7a39 100644 --- a/extension.json +++ b/extension.json @@ -498,7 +498,8 @@ "scripts": [ "modules/ve-mw/init/ve.init.mw.ArticleTarget.js", "modules/ve-mw/init/ve.init.mw.ArticleTargetEvents.js", - "modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js" + "modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js", + "modules/ve-mw/ui/actions/ve.ui.MWSaveDialogAction.js" ], "styles": [ "modules/ve-mw/init/styles/ve.init.mw.ArticleTarget.css", @@ -506,7 +507,8 @@ ], "dependencies": [ "ext.visualEditor.mediawiki", - "ext.visualEditor.core" + "ext.visualEditor.core", + "ext.visualEditor.mwcore" ], "messages": [ "accesskey-save" diff --git a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js index 29c9e80147..e185a7fab0 100644 --- a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js +++ b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js @@ -1046,7 +1046,7 @@ ve.init.mw.DesktopArticleTarget.prototype.attachToolbarSaveButton = function () * @inheritdoc */ ve.init.mw.DesktopArticleTarget.prototype.getSaveDialogOpeningData = function () { - var data = ve.init.mw.DesktopArticleTarget.super.prototype.getSaveDialogOpeningData.call( this ); + var data = ve.init.mw.DesktopArticleTarget.super.prototype.getSaveDialogOpeningData.apply( this, arguments ); data.editSummary = this.initialEditSummary; return data; }; diff --git a/modules/ve-mw/init/ve.init.mw.ArticleTarget.js b/modules/ve-mw/init/ve.init.mw.ArticleTarget.js index ebae4e7924..b36d76b46d 100644 --- a/modules/ve-mw/init/ve.init.mw.ArticleTarget.js +++ b/modules/ve-mw/init/ve.init.mw.ArticleTarget.js @@ -1773,20 +1773,25 @@ ve.init.mw.ArticleTarget.prototype.updateToolbarSaveButtonState = function () { * Handle clicks on the save button in the toolbar. */ ve.init.mw.ArticleTarget.prototype.onToolbarSaveButtonClick = function () { - if ( this.edited || this.restoring ) { - this.showSaveDialog(); - } + this.showSaveDialog(); }; /** * Show a save dialog * + * @param {string} [action] Window action to trigger after opening + * @param {string} [initialPanel] Initial panel to show in the dialog + * * @fires saveWorkflowBegin */ -ve.init.mw.ArticleTarget.prototype.showSaveDialog = function () { +ve.init.mw.ArticleTarget.prototype.showSaveDialog = function ( action, initialPanel ) { var target = this, windowAction = ve.ui.actionFactory.create( 'window', this.getSurface() ); + if ( !( this.edited || this.restoring ) ) { + return; + } + this.emit( 'saveWorkflowBegin' ); // Preload the serialization @@ -1810,17 +1815,20 @@ ve.init.mw.ArticleTarget.prototype.showSaveDialog = function () { } ); // Open the dialog - windowAction.open( 'mwSave', this.getSaveDialogOpeningData() ); + windowAction.open( 'mwSave', this.getSaveDialogOpeningData( initialPanel ), action ); }; /** * Get opening data to pass to the save dialog + * + * @param {string} [initialPanel] Initial panel to show in the dialog */ -ve.init.mw.ArticleTarget.prototype.getSaveDialogOpeningData = function () { +ve.init.mw.ArticleTarget.prototype.getSaveDialogOpeningData = function ( initialPanel ) { return { saveButtonLabel: this.getSaveButtonLabel(), checkboxFields: this.checkboxFields, - checkboxesByName: this.checkboxesByName + checkboxesByName: this.checkboxesByName, + initialPanel: initialPanel }; }; @@ -1990,17 +1998,3 @@ ve.init.mw.ArticleTarget.prototype.maybeShowWelcomeDialog = function () { this.welcomeDialogPromise.reject(); } }; - -// Register save button with command help dialog -( function () { - var accessKeyPrefix = $.fn.updateTooltipAccessKeys.getAccessKeyPrefix().toUpperCase().replace( /-/g, ' + ' ), - saveShortcut = ve.msg( 'accesskey-save' ); - - if ( saveShortcut !== '-' && saveShortcut !== '' ) { - ve.ui.commandHelpRegistry.register( 'other', 'save', { - shortcuts: [ accessKeyPrefix + saveShortcut.toUpperCase() ], - label: function () { return ve.init.target.getSaveButtonLabel(); }, - demote: true - } ); - } -}() ); diff --git a/modules/ve-mw/ui/actions/ve.ui.MWSaveDialogAction.js b/modules/ve-mw/ui/actions/ve.ui.MWSaveDialogAction.js new file mode 100644 index 0000000000..0b7814e703 --- /dev/null +++ b/modules/ve-mw/ui/actions/ve.ui.MWSaveDialogAction.js @@ -0,0 +1,103 @@ +/*! + * VisualEditor UserInterface MWSaveDialogAction class. + * + * @copyright 2011-2016 VisualEditor Team and others; see http://ve.mit-license.org + */ + +// TODO: Can perhaps extract a lot of the dialog lifecycle management code +// from ArticleTarget and put it here. + +/** + * Save action. + * + * @class + * @extends ve.ui.Action + * + * @constructor + * @param {ve.ui.Surface} surface Surface to act on + */ +ve.ui.MWSaveDialogAction = function VeUiMWSaveDialogAction() { + // Parent constructor + ve.ui.MWSaveDialogAction.super.apply( this, arguments ); +}; + +/* Inheritance */ + +OO.inheritClass( ve.ui.MWSaveDialogAction, ve.ui.Action ); + +/* Static Properties */ + +ve.ui.MWSaveDialogAction.static.name = 'mwSaveDialog'; + +/** + * List of allowed methods for the action. + * + * @static + * @property + */ +ve.ui.MWSaveDialogAction.static.methods = [ 'save', 'review' ]; + +/* Methods */ + +/** + * Open the save dialog + * + * @method + * @return {boolean} Action was executed + */ +ve.ui.MWSaveDialogAction.prototype.save = function () { + ve.init.target.showSaveDialog(); + return true; +}; + +/** + * Open the save dialog, and set it to the review panel + * + * @method + * @return {boolean} Action was executed + */ +ve.ui.MWSaveDialogAction.prototype.review = function () { + ve.init.target.showSaveDialog( 'review', 'review' ); + return true; +}; + +/* Registration */ + +ve.ui.actionFactory.register( ve.ui.MWSaveDialogAction ); + +ve.ui.commandRegistry.register( + new ve.ui.Command( + 'showChanges', 'mwSaveDialog', 'review', + { supportedSelections: [ 'linear', 'table' ] } + ) +); +ve.ui.triggerRegistry.register( + 'showChanges', new ve.ui.Trigger( 'alt+shift+v' ) +); +ve.ui.commandHelpRegistry.register( 'other', 'showChanges', { + trigger: 'showChanges', + label: OO.ui.deferMsg( 'visualeditor-savedialog-label-review' ) +} ); +ve.ui.MWCommandHelpDialog.static.commandGroups.other.demote.push( 'showChanges' ); + +ve.ui.commandRegistry.register( + new ve.ui.Command( + 'showSave', 'mwSaveDialog', 'save', + { supportedSelections: [ 'linear', 'table' ] } + ) +); +( function () { + var accessKeyPrefix = $.fn.updateTooltipAccessKeys.getAccessKeyPrefix().toUpperCase().replace( /-/g, ' + ' ), + saveShortcut = ve.msg( 'accesskey-save' ); + + if ( saveShortcut !== '-' && saveShortcut !== '' ) { + ve.ui.triggerRegistry.register( + 'showSave', new ve.ui.Trigger( accessKeyPrefix + saveShortcut ) + ); + ve.ui.commandHelpRegistry.register( 'other', 'save', { + trigger: 'showSave', + label: function () { return ve.init.target.getSaveButtonLabel(); } + } ); + ve.ui.MWCommandHelpDialog.static.commandGroups.other.demote.push( 'save' ); + } +}() ); diff --git a/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js b/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js index 4147338a47..43d46e3cef 100644 --- a/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js +++ b/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js @@ -534,7 +534,7 @@ ve.ui.MWSaveDialog.prototype.getSetupProcess = function ( data ) { this.checkboxesByName = data.checkboxesByName || {}; // Old messages should not persist this.clearAllMessages(); - this.swapPanel( 'save' ); + this.swapPanel( data.initialPanel || 'save' ); // Update save button label if ( data.saveButtonLabel ) { this.actions.forEach( { actions: 'save' }, function ( action ) {