From: Ed Sanders Date: Mon, 21 Sep 2015 21:08:17 +0000 (+0100) Subject: mediawiki.Upload.Dialog: Factor out booklet layout X-Git-Tag: 1.31.0-rc.0~9891^2 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=fca8cd7923cd4669ce449687891bb0d75c2f646f mediawiki.Upload.Dialog: Factor out booklet layout So that it can be used outside of the upload dialog. Change-Id: Ic6e7e4499611e64a905f2828bdf0ee538168c9ec --- diff --git a/resources/Resources.php b/resources/Resources.php index 4e593128d0..54d14a9f76 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1151,19 +1151,31 @@ return array( ), ), 'mediawiki.Upload.Dialog' => array( - 'scripts' => 'resources/src/mediawiki/mediawiki.Upload.Dialog.js', + 'scripts' => array( + 'resources/src/mediawiki/mediawiki.Upload.Dialog.js', + ), 'dependencies' => array( - 'oojs-ui', - 'mediawiki.Upload', + 'mediawiki.Upload.BookletLayout', ), 'messages' => array( 'upload-dialog-title', - 'upload-dialog-error', - 'upload-dialog-warning', 'upload-dialog-button-cancel', 'upload-dialog-button-done', 'upload-dialog-button-save', 'upload-dialog-button-upload', + ), + ), + 'mediawiki.Upload.BookletLayout' => array( + 'scripts' => array( + 'resources/src/mediawiki/mediawiki.Upload.BookletLayout.js', + ), + 'dependencies' => array( + 'oojs-ui', + 'mediawiki.Upload', + ), + 'messages' => array( + 'upload-dialog-error', + 'upload-dialog-warning', 'upload-dialog-label-select-file', 'upload-dialog-label-infoform-title', 'upload-dialog-label-infoform-name', diff --git a/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js b/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js new file mode 100644 index 0000000000..0f85154ace --- /dev/null +++ b/resources/src/mediawiki/mediawiki.Upload.BookletLayout.js @@ -0,0 +1,414 @@ +( function ( $, mw ) { + + /** + * mw.Upload.BookletLayout encapsulates the process of uploading a file + * to MediaWiki using the {@link mw.Upload upload model}. + * The booklet emits events that can be used to get the stashed + * upload and the final file. It can be extended to accept + * additional fields from the user for specific scenarios like + * for Commons, or campaigns. + * + * ## Structure + * + * The {@link OO.ui.BookletLayout booklet layout} has three steps: + * + * - **Upload**: Has a {@link OO.ui.SelectFileWidget field} to get the file object. + * + * - **Information**: Has a {@link OO.ui.FormLayout form} to collect metadata. This can be + * extended. + * + * - **Insert**: Has details on how to use the file that was uploaded. + * + * Each step has a form associated with it defined in + * {@link #renderUploadForm renderUploadForm}, + * {@link #renderInfoForm renderInfoForm}, and + * {@link #renderInsertForm renderInfoForm}. The + * {@link #getFile getFile}, + * {@link #getFilename getFilename}, and + * {@link #getText getText} methods are used to get + * the information filled in these forms, required to call + * {@link mw.Upload mw.Upload}. + * + * ## Usage + * + * See the {@link mw.Upload.Dialog upload dialog}. + * + * The {@link #event-fileUploaded fileUploaded}, + * and {@link #event-fileSaved fileSaved} events can + * be used to get details of the upload. + * + * ## Extending + * + * To extend using {@link mw.Upload mw.Upload}, override + * {@link #renderInfoForm renderInfoForm} to render + * the form required for the specific use-case. Update the + * {@link #getFilename getFilename}, and + * {@link #getText getText} methods to return data + * from your newly created form. If you added new fields you'll also have + * to update the {@link #clear} method. + * + * If you plan to use a different upload model, apart from what is mentioned + * above, you'll also have to override the + * {@link #createUpload createUpload} method to + * return the new model. The {@link #saveFile saveFile}, and + * the {@link #uploadFile uploadFile} methods need to be + * overriden to use the new model and data returned from the forms. + * + * @class + * @extends OO.ui.BookletLayout + * + * @constructor + * @param {Object} config Configuration options + */ + mw.Upload.BookletLayout = function ( config ) { + // Parent constructor + mw.Upload.BookletLayout.parent.call( this, config ); + + this.renderUploadForm(); + this.renderInfoForm(); + this.renderInsertForm(); + + this.addPages( [ + new OO.ui.PageLayout( 'upload', { + scrollable: true, + padded: true, + content: [ this.uploadForm ] + } ), + new OO.ui.PageLayout( 'info', { + scrollable: true, + padded: true, + content: [ this.infoForm ] + } ), + new OO.ui.PageLayout( 'insert', { + scrollable: true, + padded: true, + content: [ this.insertForm ] + } ) + ] ); + }; + + /* Setup */ + + OO.inheritClass( mw.Upload.BookletLayout, OO.ui.BookletLayout ); + + /* Events */ + + /** + * The file has finished uploading + * + * @event fileUploaded + */ + + /** + * The file has been saved to the database + * + * @event fileSaved + */ + + /** + * The upload form has changed + * + * @event uploadValid + * @param {boolean} isValid The form is valid + */ + + /** + * The info form has changed + * + * @event infoValid + * @param {boolean} isValid The form is valid + */ + + /* Properties */ + + /** + * @property {OO.ui.FormLayout} uploadForm + * The form rendered in the first step to get the file object. + * Rendered in {@link #renderUploadForm renderUploadForm}. + */ + + /** + * @property {OO.ui.FormLayout} infoForm + * The form rendered in the second step to get metadata. + * Rendered in {@link #renderInfoForm renderInfoForm} + */ + + /** + * @property {OO.ui.FormLayout} insertForm + * The form rendered in the third step to show usage + * Rendered in {@link #renderInsertForm renderInsertForm} + */ + + /* Methods */ + + /** + * Initialize for a new upload + */ + mw.Upload.BookletLayout.prototype.initialize = function () { + this.clear(); + this.upload = this.createUpload(); + this.setPage( 'upload' ); + }; + + /** + * Create a new upload model + * + * @protected + * @return {mw.Upload} Upload model + */ + mw.Upload.BookletLayout.prototype.createUpload = function () { + return new mw.Upload(); + }; + + /* Uploading */ + + /** + * Uploads the file that was added in the upload form. Uses + * {@link #getFile getFile} to get the HTML5 + * file object. + * + * @protected + * @fires fileUploaded + * @return {jQuery.Promise} + */ + mw.Upload.BookletLayout.prototype.uploadFile = function () { + var file = this.getFile(); + + this.filenameWidget.setValue( file.name ); + this.setPage( 'info' ); + + this.upload.setFile( file ); + this.uploadPromise = this.upload.uploadToStash(); + this.uploadPromise.then( this.emit.bind( this, 'fileUploaded' ) ); + + return this.uploadPromise; + }; + + /** + * Saves the stash finalizes upload. Uses + * {@link #getFilename getFilename}, and + * {@link #getText getText} to get details from + * the form. + * + * @protected + * @fires fileSaved + * @returns {jQuery.Promise} Rejects the promise with an + * {@link OO.ui.Error error}, or resolves if the upload was successful. + */ + mw.Upload.BookletLayout.prototype.saveFile = function () { + var layout = this, + deferred = $.Deferred(); + + this.upload.setFilename( this.getFilename() ); + this.upload.setText( this.getText() ); + + this.uploadPromise.always( function () { + + if ( layout.upload.getState() === mw.Upload.State.ERROR ) { + deferred.reject( new OO.ui.Error( mw.msg( 'upload-dialog-error' ) ) ); + return false; + } + + if ( layout.upload.getState() === mw.Upload.State.WARNING ) { + deferred.reject( new OO.ui.Error( mw.msg( 'upload-dialog-error' ) ) ); + return false; + } + + layout.upload.finishStashUpload().always( function () { + var name; + + if ( layout.upload.getState() === mw.Upload.State.ERROR ) { + deferred.reject( new OO.ui.Error( mw.msg( 'upload-dialog-error' ) ) ); + return false; + } + + if ( layout.upload.getState() === mw.Upload.State.WARNING ) { + deferred.reject( new OO.ui.Error( mw.msg( 'upload-dialog-warning' ) ) ); + return false; + } + + // Normalize page name and localise the 'File:' prefix + name = new mw.Title( 'File:' + layout.upload.getFilename() ).toString(); + layout.filenameUsageWidget.setValue( '[[' + name + ']]' ); + layout.setPage( 'insert' ); + + deferred.resolve(); + layout.emit( 'fileSaved' ); + } ); + } ); + + return deferred.promise(); + }; + + /* Form renderers */ + + /** + * Renders and returns the upload form and sets the + * {@link #uploadForm uploadForm} property. + * + * @protected + * @fires selectFile + * @returns {OO.ui.FormLayout} + */ + mw.Upload.BookletLayout.prototype.renderUploadForm = function () { + var fieldset; + + this.selectFileWidget = new OO.ui.SelectFileWidget(); + fieldset = new OO.ui.FieldsetLayout( { label: mw.msg( 'upload-dialog-label-select-file' ) } ); + fieldset.addItems( [ this.selectFileWidget ] ); + this.uploadForm = new OO.ui.FormLayout( { items: [ fieldset ] } ); + + // Validation + this.selectFileWidget.on( 'change', this.onUploadFormChange.bind( this ) ); + + return this.uploadForm; + }; + + /** + * Handle change events to the upload form + * + * @protected + * @fires uploadValid + */ + mw.Upload.BookletLayout.prototype.onUploadFormChange = function () { + this.emit( 'uploadValid', !!this.selectFileWidget.getValue() ); + }; + + /** + * Renders and returns the information form for collecting + * metadata and sets the {@link #infoForm infoForm} + * property. + * + * @protected + * @returns {OO.ui.FormLayout} + */ + mw.Upload.BookletLayout.prototype.renderInfoForm = function () { + var fieldset; + + this.filenameWidget = new OO.ui.TextInputWidget( { + indicator: 'required', + required: true, + validate: /.+/ + } ); + this.descriptionWidget = new OO.ui.TextInputWidget( { + indicator: 'required', + required: true, + validate: /.+/, + multiline: true, + autosize: true + } ); + + fieldset = new OO.ui.FieldsetLayout( { + label: mw.msg( 'upload-dialog-label-infoform-title' ) + } ); + fieldset.addItems( [ + new OO.ui.FieldLayout( this.filenameWidget, { + label: mw.msg( 'upload-dialog-label-infoform-name' ), + align: 'top' + } ), + new OO.ui.FieldLayout( this.descriptionWidget, { + label: mw.msg( 'upload-dialog-label-infoform-description' ), + align: 'top' + } ) + ] ); + this.infoForm = new OO.ui.FormLayout( { items: [ fieldset ] } ); + + this.filenameWidget.on( 'change', this.onInfoFormChange.bind( this ) ); + this.descriptionWidget.on( 'change', this.onInfoFormChange.bind( this ) ); + + return this.infoForm; + }; + + /** + * Handle change events to the info form + * + * @protected + * @fires infoValid + */ + mw.Upload.BookletLayout.prototype.onInfoFormChange = function () { + var layout = this; + $.when( + this.filenameWidget.getValidity(), + this.descriptionWidget.getValidity() + ).done( function () { + layout.emit( 'infoValid', true ); + } ).fail( function () { + layout.emit( 'infoValid', false ); + } ); + }; + + /** + * Renders and returns the insert form to show file usage and + * sets the {@link #insertForm insertForm} property. + * + * @protected + * @returns {OO.ui.FormLayout} + */ + mw.Upload.BookletLayout.prototype.renderInsertForm = function () { + var fieldset; + + this.filenameUsageWidget = new OO.ui.TextInputWidget(); + fieldset = new OO.ui.FieldsetLayout( { + label: mw.msg( 'upload-dialog-label-usage-title' ) + } ); + fieldset.addItems( [ + new OO.ui.FieldLayout( this.filenameUsageWidget, { + label: mw.msg( 'upload-dialog-label-usage-filename' ), + align: 'top' + } ) + ] ); + this.insertForm = new OO.ui.FormLayout( { items: [ fieldset ] } ); + + return this.insertForm; + }; + + /* Getters */ + + /** + * Gets the file object from the + * {@link #uploadForm upload form}. + * + * @protected + * @returns {File|null} + */ + mw.Upload.BookletLayout.prototype.getFile = function () { + return this.selectFileWidget.getValue(); + }; + + /** + * Gets the file name from the + * {@link #infoForm information form}. + * + * @protected + * @returns {string} + */ + mw.Upload.BookletLayout.prototype.getFilename = function () { + return this.filenameWidget.getValue(); + }; + + /** + * Gets the page text from the + * {@link #infoForm information form}. + * + * @protected + * @returns {string} + */ + mw.Upload.BookletLayout.prototype.getText = function () { + return this.descriptionWidget.getValue(); + }; + + /* Setters */ + + /** + * Clear the values of all fields + * + * @protected + */ + mw.Upload.BookletLayout.prototype.clear = function () { + this.selectFileWidget.setValue( null ); + this.filenameWidget.setValue( null ).setValidityFlag( true ); + this.descriptionWidget.setValue( null ).setValidityFlag( true ); + this.filenameUsageWidget.setValue( null ); + }; + +}( jQuery, mediaWiki ) ); diff --git a/resources/src/mediawiki/mediawiki.Upload.Dialog.js b/resources/src/mediawiki/mediawiki.Upload.Dialog.js index 36fbd4656c..de005f8a68 100644 --- a/resources/src/mediawiki/mediawiki.Upload.Dialog.js +++ b/resources/src/mediawiki/mediawiki.Upload.Dialog.js @@ -1,33 +1,7 @@ ( function ( $, mw ) { /** - * mw.Upload.Dialog encapsulates the process of uploading a file - * to MediaWiki using the {@link mw.Upload mw.Upload} model. - * The dialog emits events that can be used to get the stashed - * upload and the final file. It can be extended to accept - * additional fields from the user for specific scenarios like - * for Commons, or campaigns. - * - * ## Structure - * - * The {@link OO.ui.ProcessDialog dialog} has three steps: - * - * - **Upload**: Has a {@link OO.ui.SelectFileWidget field} to get the file object. - * - * - **Information**: Has a {@link OO.ui.FormLayout form} to collect metadata. This can be - * extended. - * - * - **Insert**: Has details on how to use the file that was uploaded. - * - * Each step has a form associated with it defined in - * {@link mw.Upload.Dialog#renderUploadForm renderUploadForm}, - * {@link mw.Upload.Dialog#renderInfoForm renderInfoForm}, and - * {@link mw.Upload.Dialog#renderInsertForm renderInfoForm}. The - * {@link mw.Upload.Dialog#getFile getFile}, - * {@link mw.Upload.Dialog#getFilename getFilename}, and - * {@link mw.Upload.Dialog#getText getText} methods are used to get - * the information filled in these forms, required to call - * {@link mw.Upload mw.Upload}. + * mw.Upload.Dialog controls a {@link mw.Upload.BookletLayout BookletLayout}. * * ## Usage * @@ -40,27 +14,7 @@ * windowManager.addWindows( [ uploadDialog ] ); * windowManager.openWindow( uploadDialog ); * - * The dialog's closing promise, - * {@link mw.Upload.Dialog#event-fileUploaded fileUploaded}, - * and {@link mw.Upload.Dialog#event-fileSaved fileSaved} events can - * be used to get details of the upload. - * - * ## Extending - * - * To extend using {@link mw.Upload mw.Upload}, override - * {@link mw.Upload.Dialog#renderInfoForm renderInfoForm} to render - * the form required for the specific use-case. Update the - * {@link mw.Upload.Dialog#getFilename getFilename}, and - * {@link mw.Upload.Dialog#getText getText} methods to return data - * from your newly created form. If you added new fields you'll also have - * to update the {@link #getTeardownProcess} method. - * - * If you plan to use a different upload model, apart from what is mentioned - * above, you'll also have to override the - * {@link mw.Upload.Dialog#getUploadObject getUploadObject} method to - * return the new model. The {@link mw.Upload.Dialog#saveFile saveFile}, and - * the {@link mw.Upload.Dialog#uploadFile uploadFile} methods need to be - * overriden to use the new model and data returned from the forms. + * The dialog's closing promise can be used to get details of the upload. * * @class mw.Upload.Dialog * @uses mw.Upload @@ -93,7 +47,7 @@ flags: 'safe', action: 'cancel', label: mw.msg( 'upload-dialog-button-cancel' ), - modes: [ 'upload', 'insert', 'save' ] + modes: [ 'upload', 'insert', 'info' ] }, { flags: [ 'primary', 'progressive' ], @@ -105,7 +59,7 @@ flags: [ 'primary', 'constructive' ], label: mw.msg( 'upload-dialog-button-save' ), action: 'save', - modes: 'save' + modes: 'info' }, { flags: [ 'primary', 'progressive' ], @@ -114,109 +68,80 @@ modes: 'upload' } ]; - /*jshint +W024*/ - /* Properties */ + /*jshint +W024*/ - /** - * @property {OO.ui.FormLayout} uploadForm - * The form rendered in the first step to get the file object. - * Rendered in {@link mw.Upload.Dialog#renderUploadForm renderUploadForm}. - */ + /* Methods */ /** - * @property {OO.ui.FormLayout} infoForm - * The form rendered in the second step to get metadata. - * Rendered in {@link mw.Upload.Dialog#renderInfoForm renderInfoForm} + * @inheritdoc */ + mw.Upload.Dialog.prototype.initialize = function () { + // Parent method + mw.Upload.Dialog.parent.prototype.initialize.call( this ); - /** - * @property {OO.ui.FormLayout} insertForm - * The form rendered in the third step to show usage - * Rendered in {@link mw.Upload.Dialog#renderInsertForm renderInsertForm} - */ + this.uploadBooklet = this.createUploadBooklet(); + this.uploadBooklet.connect( this, { + set: 'onUploadBookletSet', + uploadValid: 'onUploadValid', + infoValid: 'onInfoValid' + } ); - /* Events */ + this.$body.append( this.uploadBooklet.$element ); + }; /** - * A `fileUploaded` event is emitted from the - * {@link mw.Upload.Dialog#uploadFile uploadFile} method. + * Create an upload booklet * - * @event fileUploaded + * @protected + * @return {mw.Upload.BookletLayout} An upload booklet */ + mw.Upload.Dialog.prototype.createUploadBooklet = function () { + return new mw.Upload.BookletLayout(); + }; /** - * A `fileSaved` event is emitted from the - * {@link mw.Upload.Dialog#saveFile saveFile} method. - * - * @event fileSaved + * @inheritdoc */ - - /* Methods */ + mw.Upload.Dialog.prototype.getBodyHeight = function () { + return 300; + }; /** - * @inheritdoc + * Handle panelNameSet events from the upload booklet + * + * @protected + * @param {OO.ui.PageLayout} page Current page */ - mw.Upload.Dialog.prototype.initialize = function () { - mw.Upload.Dialog.parent.prototype.initialize.call( this ); - - this.renderUploadForm(); - this.renderInfoForm(); - this.renderInsertForm(); - - this.uploadFormPanel = new OO.ui.PanelLayout( { - scrollable: true, - padded: true, - content: [ this.uploadForm ] - } ); - this.infoFormPanel = new OO.ui.PanelLayout( { - scrollable: true, - padded: true, - content: [ this.infoForm ] - } ); - this.insertFormPanel = new OO.ui.PanelLayout( { - scrollable: true, - padded: true, - content: [ this.insertForm ] - } ); - - this.panels = new OO.ui.StackLayout(); - this.panels.addItems( [ - this.uploadFormPanel, - this.infoFormPanel, - this.insertFormPanel - ] ); - - this.$body.append( this.panels.$element ); + mw.Upload.Dialog.prototype.onUploadBookletSet = function ( page ) { + this.actions.setMode( page.getName() ); + this.actions.setAbilities( { upload: false, save: false } ); }; /** - * @inheritdoc + * Handle uploadValid events + * + * {@link OO.ui.ActionSet#setAbilities Sets abilities} + * for the dialog accordingly. + * + * @protected + * @param {boolean} isValid The panel is complete and valid */ - mw.Upload.Dialog.prototype.getBodyHeight = function () { - return 300; + mw.Upload.Dialog.prototype.onUploadValid = function ( isValid ) { + this.actions.setAbilities( { upload: isValid } ); }; /** - * Switch between the panels. + * Handle infoValid events * - * @param {string} panel Panel name: 'upload', 'info', 'insert' + * {@link OO.ui.ActionSet#setAbilities Sets abilities} + * for the dialog accordingly. + * + * @protected + * @param {boolean} isValid The panel is complete and valid */ - mw.Upload.Dialog.prototype.switchPanels = function ( panel ) { - switch ( panel ) { - case 'upload': - this.panels.setItem( this.uploadFormPanel ); - this.actions.setMode( 'upload' ); - break; - case 'info': - this.panels.setItem( this.infoFormPanel ); - this.actions.setMode( 'save' ); - break; - case 'insert': - this.panels.setItem( this.insertFormPanel ); - this.actions.setMode( 'insert' ); - break; - } + mw.Upload.Dialog.prototype.onInfoValid = function ( isValid ) { + this.actions.setAbilities( { save: isValid } ); }; /** @@ -225,9 +150,7 @@ mw.Upload.Dialog.prototype.getSetupProcess = function ( data ) { return mw.Upload.Dialog.parent.prototype.getSetupProcess.call( this, data ) .next( function () { - this.upload = this.getUploadObject(); - this.switchPanels( 'upload' ); - this.actions.setAbilities( { upload: false } ); + this.uploadBooklet.initialize(); }, this ); }; @@ -238,15 +161,10 @@ var dialog = this; if ( action === 'upload' ) { - return new OO.ui.Process( function () { - dialog.filenameWidget.setValue( dialog.getFile().name ); - dialog.switchPanels( 'info' ); - dialog.actions.setAbilities( { save: false } ); - return dialog.uploadFile(); - } ); + return new OO.ui.Process( this.uploadBooklet.uploadFile() ); } if ( action === 'save' ) { - return new OO.ui.Process( dialog.saveFile() ); + return new OO.ui.Process( this.uploadBooklet.saveFile() ); } if ( action === 'insert' ) { return new OO.ui.Process( function () { @@ -254,7 +172,7 @@ } ); } if ( action === 'cancel' ) { - return new OO.ui.Process( dialog.close() ); + return new OO.ui.Process( this.close() ); } return mw.Upload.Dialog.parent.prototype.getActionProcess.call( this, action ); @@ -266,249 +184,8 @@ mw.Upload.Dialog.prototype.getTeardownProcess = function ( data ) { return mw.Upload.Dialog.parent.prototype.getTeardownProcess.call( this, data ) .next( function () { - // Clear the values of all fields - this.selectFileWidget.setValue( null ); - this.filenameWidget.setValue( null ).setValidityFlag( true ); - this.descriptionWidget.setValue( null ).setValidityFlag( true ); - this.filenameUsageWidget.setValue( null ); + this.uploadBooklet.clear(); }, this ); }; - /* Uploading */ - - /** - * Get the upload model object required for this dialog. Can be - * extended to different models. - * - * @return {mw.Upload} - */ - mw.Upload.Dialog.prototype.getUploadObject = function () { - return new mw.Upload(); - }; - - /** - * Uploads the file that was added in the upload form. Uses - * {@link mw.Upload.Dialog#getFile getFile} to get the HTML5 - * file object. - * - * @protected - * @fires fileUploaded - * @return {jQuery.Promise} - */ - mw.Upload.Dialog.prototype.uploadFile = function () { - var dialog = this, - file = this.getFile(); - this.upload.setFile( file ); - this.uploadPromise = this.upload.uploadToStash(); - this.uploadPromise.then( function () { - dialog.emit( 'fileUploaded' ); - } ); - - return this.uploadPromise; - }; - - /** - * Saves the stash finalizes upload. Uses - * {@link mw.Upload.Dialog#getFilename getFilename}, and - * {@link mw.Upload.Dialog#getText getText} to get details from - * the form. - * - * @protected - * @fires fileSaved - * @returns {jQuery.Promise} Rejects the promise with an - * {@link OO.ui.Error error}, or resolves if the upload was successful. - */ - mw.Upload.Dialog.prototype.saveFile = function () { - var dialog = this, - promise = $.Deferred(); - - this.upload.setFilename( this.getFilename() ); - this.upload.setText( this.getText() ); - - this.uploadPromise.always( function () { - - if ( dialog.upload.getState() === mw.Upload.State.ERROR ) { - promise.reject( new OO.ui.Error( mw.msg( 'upload-dialog-error' ) ) ); - return false; - } - - if ( dialog.upload.getState() === mw.Upload.State.WARNING ) { - promise.reject( new OO.ui.Error( mw.msg( 'upload-dialog-error' ) ) ); - return false; - } - - dialog.upload.finishStashUpload().always( function () { - var name; - - if ( dialog.upload.getState() === mw.Upload.State.ERROR ) { - promise.reject( new OO.ui.Error( mw.msg( 'upload-dialog-error' ) ) ); - return false; - } - - if ( dialog.upload.getState() === mw.Upload.State.WARNING ) { - promise.reject( new OO.ui.Error( mw.msg( 'upload-dialog-warning' ) ) ); - return false; - } - - // Normalize page name and localise the 'File:' prefix - name = new mw.Title( 'File:' + dialog.upload.getFilename() ).toString(); - dialog.filenameUsageWidget.setValue( '[[' + name + ']]' ); - dialog.switchPanels( 'insert' ); - - promise.resolve(); - dialog.emit( 'fileSaved' ); - } ); - } ); - - return promise.promise(); - }; - - /* Form renderers */ - - /** - * Renders and returns the upload form and sets the - * {@link mw.Upload.Dialog#uploadForm uploadForm} property. - * Validates the form and - * {@link OO.ui.ActionSet#setAbilities sets abilities} - * for the dialog accordingly. - * - * @protected - * @returns {OO.ui.FormLayout} - */ - mw.Upload.Dialog.prototype.renderUploadForm = function () { - var fieldset, - dialog = this; - - this.selectFileWidget = new OO.ui.SelectFileWidget(); - fieldset = new OO.ui.FieldsetLayout( { label: mw.msg( 'upload-dialog-label-select-file' ) } ); - fieldset.addItems( [ this.selectFileWidget ] ); - this.uploadForm = new OO.ui.FormLayout( { items: [ fieldset ] } ); - - // Validation - this.selectFileWidget.on( 'change', function ( value ) { - dialog.actions.setAbilities( { upload: !!value } ); - } ); - - return this.uploadForm; - }; - - /** - * Renders and returns the information form for collecting - * metadata and sets the {@link mw.Upload.Dialog#infoForm infoForm} - * property. - * Validates the form and - * {@link OO.ui.ActionSet#setAbilities sets abilities} - * for the dialog accordingly. - * - * @protected - * @returns {OO.ui.FormLayout} - */ - mw.Upload.Dialog.prototype.renderInfoForm = function () { - var fieldset, - dialog = this; - - this.filenameWidget = new OO.ui.TextInputWidget( { - indicator: 'required', - required: true, - validate: /.+/ - } ); - this.descriptionWidget = new OO.ui.TextInputWidget( { - indicator: 'required', - required: true, - validate: /.+/, - multiline: true, - autosize: true - } ); - - fieldset = new OO.ui.FieldsetLayout( { - label: mw.msg( 'upload-dialog-label-infoform-title' ) - } ); - fieldset.addItems( [ - new OO.ui.FieldLayout( this.filenameWidget, { - label: mw.msg( 'upload-dialog-label-infoform-name' ), - align: 'top' - } ), - new OO.ui.FieldLayout( this.descriptionWidget, { - label: mw.msg( 'upload-dialog-label-infoform-description' ), - align: 'top' - } ) - ] ); - this.infoForm = new OO.ui.FormLayout( { items: [ fieldset ] } ); - - // Validation - function checkValidity() { - $.when( - dialog.filenameWidget.getValidity(), - dialog.descriptionWidget.getValidity() - ).done( function () { - dialog.actions.setAbilities( { save: true } ); - } ).fail( function () { - dialog.actions.setAbilities( { save: false } ); - } ); - } - this.filenameWidget.on( 'change', checkValidity ); - this.descriptionWidget.on( 'change', checkValidity ); - - return this.infoForm; - }; - - /** - * Renders and returns the insert form to show file usage and - * sets the {@link mw.Upload.Dialog#insertForm insertForm} property. - * - * @protected - * @returns {OO.ui.FormLayout} - */ - mw.Upload.Dialog.prototype.renderInsertForm = function () { - var fieldset; - - this.filenameUsageWidget = new OO.ui.TextInputWidget(); - fieldset = new OO.ui.FieldsetLayout( { - label: mw.msg( 'upload-dialog-label-usage-title' ) - } ); - fieldset.addItems( [ - new OO.ui.FieldLayout( this.filenameUsageWidget, { - label: mw.msg( 'upload-dialog-label-usage-filename' ), - align: 'top' - } ) - ] ); - this.insertForm = new OO.ui.FormLayout( { items: [ fieldset ] } ); - - return this.insertForm; - }; - - /* Getters */ - - /** - * Gets the file object from the - * {@link mw.Upload.Dialog#uploadForm upload form}. - * - * @protected - * @returns {File|null} - */ - mw.Upload.Dialog.prototype.getFile = function () { - return this.selectFileWidget.getValue(); - }; - - /** - * Gets the file name from the - * {@link mw.Upload.Dialog#infoForm information form}. - * - * @protected - * @returns {string} - */ - mw.Upload.Dialog.prototype.getFilename = function () { - return this.filenameWidget.getValue(); - }; - - /** - * Gets the page text from the - * {@link mw.Upload.Dialog#infoForm information form}. - * - * @protected - * @returns {string} - */ - mw.Upload.Dialog.prototype.getText = function () { - return this.descriptionWidget.getValue(); - }; }( jQuery, mediaWiki ) );