7 * Used to represent an upload in progress on the frontend.
8 * Most of the functionality is implemented in mw.Api.plugin.upload,
9 * but this model class will tie it together as well as let you perform
10 * actions in a logical way.
14 * var file = new OO.ui.SelectFileWidget(),
15 * button = new OO.ui.ButtonWidget( { label: 'Save' } ),
16 * upload = new mw.Upload;
18 * button.on( 'click', function () {
19 * upload.setFile( file.getValue() );
20 * upload.setFilename( file.getValue().name );
24 * $( 'body' ).append( file.$element, button.$element );
26 * You can also choose to {@link #uploadToStash stash the upload} and
27 * {@link #finishStashUpload finalize} it later:
29 * var file, // Some file object
30 * upload = new mw.Upload,
31 * stashPromise = $.Deferred();
33 * upload.setFile( file );
34 * upload.uploadToStash().then( function () {
35 * stashPromise.resolve();
38 * stashPromise.then( function () {
39 * upload.setFilename( 'foo' );
40 * upload.setText( 'bar' );
41 * upload.finishStashUpload().then( function () {
42 * console.log( 'Done!' );
47 * @param {Object} apiconfig Passed to the constructor of mw.Api.
49 function Upload( apiconfig
) {
50 this.api
= new mw
.Api( apiconfig
);
52 this.watchlist
= false;
57 this.state
= Upload
.State
.NEW
;
59 this.imageinfo
= undefined;
62 UP
= Upload
.prototype;
65 * Set the text of the file page, to be created on file upload.
66 * @param {string} text
68 UP
.setText = function ( text
) {
73 * Set the filename, to be finalized on upload.
74 * @param {string} filename
76 UP
.setFilename = function ( filename
) {
77 this.filename
= filename
;
81 * Sets the filename based on the filename as it was on the upload.
83 UP
.setFilenameFromFile = function () {
84 if ( this.file
.nodeType
&& this.file
.nodeType
=== Node
.ELEMENT_NODE
) {
85 // File input element, use getBasename to cut out the path
86 this.setFilename( this.getBasename( this.file
.value
) );
87 } else if ( this.file
.name
&& this.file
.lastModified
) {
88 // HTML5 FileAPI File object, but use getBasename to be safe
89 this.setFilename( this.getBasename( this.file
.name
) );
94 * Set the file to be uploaded.
95 * @param {HTMLInputElement|File} file
97 UP
.setFile = function ( file
) {
102 * Set whether the file should be watchlisted after upload.
103 * @param {boolean} watchlist
105 UP
.setWatchlist = function ( watchlist
) {
106 this.watchlist
= watchlist
;
110 * Set the edit comment for the upload.
111 * @param {string} comment
113 UP
.setComment = function ( comment
) {
114 this.comment
= comment
;
118 * Get the text of the file page, to be created on file upload.
121 UP
.getText = function () {
126 * Get the filename, to be finalized on upload.
129 UP
.getFilename = function () {
130 return this.filename
;
134 * Get the file being uploaded.
135 * @return {HTMLInputElement|File}
137 UP
.getFile = function () {
142 * Get the boolean for whether the file will be watchlisted after upload.
145 UP
.getWatchlist = function () {
146 return this.watchlist
;
150 * Get the current value of the edit comment for the upload.
153 UP
.getComment = function () {
158 * Gets the base filename from a path name.
159 * @param {string} path
162 UP
.getBasename = function ( path
) {
163 if ( path
=== undefined || path
=== null ) {
167 // Find the index of the last path separator in the
168 // path, and add 1. Then, take the entire string after that.
171 path
.lastIndexOf( '/' ),
172 path
.lastIndexOf( '\\' )
178 * Gets the state of the upload.
179 * @return {mw.Upload.State}
181 UP
.getState = function () {
186 * Get the imageinfo object for the finished upload.
187 * Only available once the upload is finished! Don't try to get it
189 * @return {Object|undefined}
191 UP
.getImageInfo = function () {
192 return this.imageinfo
;
196 * Upload the file directly.
197 * @return {jQuery.Promise}
199 UP
.upload = function () {
203 return $.Deferred().reject( 'No file to upload. Call setFile to add one.' );
206 if ( !this.filename
) {
207 return $.Deferred().reject( 'No filename set. Call setFilename to add one.' );
210 this.state
= Upload
.State
.UPLOADING
;
212 return this.api
.upload( this.file
, {
213 watchlist
: ( this.watchlist
=== true ) ? 1 : undefined,
214 comment
: this.comment
,
215 filename
: this.filename
,
217 } ).then( function ( result
) {
218 upload
.state
= Upload
.State
.UPLOADED
;
219 upload
.imageinfo
= result
.upload
.imageinfo
;
222 upload
.state
= Upload
.State
.ERROR
;
227 * Upload the file to the stash to be completed later.
228 * @return {jQuery.Promise}
230 UP
.uploadToStash = function () {
234 return $.Deferred().reject( 'No file to upload. Call setFile to add one.' );
237 if ( !this.filename
) {
238 this.setFilenameFromFile();
241 this.state
= Upload
.State
.UPLOADING
;
243 this.stashPromise
= this.api
.uploadToStash( this.file
, {
244 filename
: this.filename
245 } ).then( function ( finishStash
) {
246 upload
.state
= Upload
.State
.STASHED
;
249 upload
.state
= Upload
.State
.ERROR
;
252 return this.stashPromise
;
256 * Finish a stash upload.
257 * @return {jQuery.Promise}
259 UP
.finishStashUpload = function () {
262 if ( !this.stashPromise
) {
263 return $.Deferred().reject( 'This upload has not been stashed, please upload it to the stash first.' );
266 return this.stashPromise
.then( function ( finishStash
) {
267 upload
.state
= Upload
.State
.UPLOADING
;
269 return finishStash( {
270 watchlist
: ( upload
.watchlist
=== true ) ? 1 : undefined,
271 comment
: upload
.getComment(),
272 filename
: upload
.getFilename(),
273 text
: upload
.getText()
274 } ).then( function () {
275 upload
.state
= Upload
.State
.UPLOADED
;
277 upload
.state
= Upload
.State
.ERROR
;
283 * @enum mw.Upload.State
284 * State of uploads represented in simple terms.
287 /** Upload not yet started */
290 /** Upload finished, but there was a warning */
293 /** Upload finished, but there was an error */
296 /** Upload in progress */
299 /** Upload finished, but not published, call #finishStashUpload */
302 /** Upload finished and published */
307 }( mediaWiki
, jQuery
) );