b8425456a31110e103d93fba1b74aced99640da5
[lhc/web/wiklou.git] / resources / src / mediawiki / mediawiki.Upload.js
1 ( function ( mw, $ ) {
2 var UP;
3
4 /**
5 * @class mw.Upload
6 *
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.
11 *
12 * @constructor
13 * @param {Object} apiconfig Passed to the constructor of mw.Api.
14 */
15 function Upload( apiconfig ) {
16 this.api = new mw.Api( apiconfig );
17
18 this.watchlist = false;
19 this.text = '';
20 this.comment = '';
21 this.filename = null;
22 this.file = null;
23 this.state = Upload.State.NEW;
24
25 this.imageinfo = undefined;
26 }
27
28 UP = Upload.prototype;
29
30 /**
31 * Set the text of the file page, to be created on file upload.
32 * @param {string} text
33 */
34 UP.setText = function ( text ) {
35 this.text = text;
36 };
37
38 /**
39 * Set the filename, to be finalized on upload.
40 * @param {string} filename
41 */
42 UP.setFilename = function ( filename ) {
43 this.filename = filename;
44 };
45
46 /**
47 * Sets the filename based on the filename as it was on the upload.
48 */
49 UP.setFilenameFromFile = function () {
50 if ( this.file.nodeType && this.file.nodeType === Node.ELEMENT_NODE ) {
51 // File input element, use getBasename to cut out the path
52 this.setFilename( this.getBasename( this.file.value ) );
53 } else if ( this.file.name && this.file.lastModified ) {
54 // HTML5 FileAPI File object, but use getBasename to be safe
55 this.setFilename( this.getBasename( this.file.name ) );
56 }
57 };
58
59 /**
60 * Set the file to be uploaded.
61 * @param {HTMLInputElement|File} file
62 */
63 UP.setFile = function ( file ) {
64 this.file = file;
65 };
66
67 /**
68 * Set whether the file should be watchlisted after upload.
69 * @param {boolean} watchlist
70 */
71 UP.setWatchlist = function ( watchlist ) {
72 this.watchlist = watchlist;
73 };
74
75 /**
76 * Set the edit comment for the upload.
77 * @param {string} comment
78 */
79 UP.setComment = function ( comment ) {
80 this.comment = comment;
81 };
82
83 /**
84 * Get the text of the file page, to be created on file upload.
85 * @return {string}
86 */
87 UP.getText = function () {
88 return this.text;
89 };
90
91 /**
92 * Get the filename, to be finalized on upload.
93 * @return {string}
94 */
95 UP.getFilename = function () {
96 return this.filename;
97 };
98
99 /**
100 * Get the file being uploaded.
101 * @return {HTMLInputElement|File}
102 */
103 UP.getFile = function () {
104 return this.file;
105 };
106
107 /**
108 * Get the boolean for whether the file will be watchlisted after upload.
109 * @return {boolean}
110 */
111 UP.getWatchlist = function () {
112 return this.watchlist;
113 };
114
115 /**
116 * Get the current value of the edit comment for the upload.
117 * @return {string}
118 */
119 UP.getComment = function () {
120 return this.comment;
121 };
122
123 /**
124 * Gets the base filename from a path name.
125 * @param {string} path
126 * @return {string}
127 */
128 UP.getBasename = function ( path ) {
129 if ( path === undefined || path === null ) {
130 return '';
131 }
132
133 // Find the index of the last path separator in the
134 // path, and add 1. Then, take the entire string after that.
135 return path.slice(
136 Math.max(
137 path.lastIndexOf( '/' ),
138 path.lastIndexOf( '\\' )
139 ) + 1
140 );
141 };
142
143 /**
144 * Gets the state of the upload.
145 * @return {mw.Upload.State}
146 */
147 UP.getState = function () {
148 return this.state;
149 };
150
151 /**
152 * Get the imageinfo object for the finished upload.
153 * Only available once the upload is finished! Don't try to get it
154 * beforehand.
155 * @return {Object|undefined}
156 */
157 UP.getImageInfo = function () {
158 return this.imageinfo;
159 };
160
161 /**
162 * Upload the file directly.
163 * @return {jQuery.Promise}
164 */
165 UP.upload = function () {
166 var upload = this;
167
168 if ( !this.file ) {
169 return $.Deferred().reject( 'No file to upload. Call setFile to add one.' );
170 }
171
172 if ( !this.filename ) {
173 return $.Deferred().reject( 'No filename set. Call setFilename to add one.' );
174 }
175
176 this.state = Upload.State.UPLOADING;
177
178 return this.api.upload( this.file, {
179 watchlist: ( this.watchlist === true ) ? 1 : undefined,
180 comment: this.comment,
181 filename: this.filename,
182 text: this.text
183 } ).then( function ( result ) {
184 upload.state = Upload.State.UPLOADED;
185 upload.imageinfo = result.upload.imageinfo;
186 return result;
187 }, function () {
188 upload.state = Upload.State.ERROR;
189 } );
190 };
191
192 /**
193 * Upload the file to the stash to be completed later.
194 * @return {jQuery.Promise}
195 */
196 UP.uploadToStash = function () {
197 var upload = this;
198
199 if ( !this.file ) {
200 return $.Deferred().reject( 'No file to upload. Call setFile to add one.' );
201 }
202
203 if ( !this.filename ) {
204 this.setFilenameFromFile();
205 }
206
207 this.state = Upload.State.UPLOADING;
208
209 this.stashPromise = this.api.uploadToStash( this.file, {
210 filename: this.filename
211 } ).then( function ( finishStash ) {
212 upload.state = Upload.State.STASHED;
213 return finishStash;
214 }, function () {
215 upload.state = Upload.State.ERROR;
216 } );
217
218 return this.stashPromise;
219 };
220
221 /**
222 * Finish a stash upload.
223 * @return {jQuery.Promise}
224 */
225 UP.finishStashUpload = function () {
226 var upload = this;
227
228 if ( !this.stashPromise ) {
229 return $.Deferred().reject( 'This upload has not been stashed, please upload it to the stash first.' );
230 }
231
232 return this.stashPromise.then( function ( finishStash ) {
233 upload.state = Upload.State.UPLOADING;
234
235 return finishStash( {
236 watchlist: ( upload.watchlist === true ) ? 1 : undefined,
237 comment: upload.getComment(),
238 filename: upload.getFilename(),
239 text: upload.getText()
240 } ).then( function () {
241 upload.state = Upload.State.UPLOADED;
242 }, function () {
243 upload.state = Upload.State.ERROR;
244 } );
245 } );
246 };
247
248 /**
249 * @enum mw.Upload.State
250 * State of uploads represented in simple terms.
251 */
252 Upload.State = {
253 /** Upload not yet started */
254 NEW: 0,
255
256 /** Upload finished, but there was a warning */
257 WARNING: 1,
258
259 /** Upload finished, but there was an error */
260 ERROR: 2,
261
262 /** Upload in progress */
263 UPLOADING: 3,
264
265 /** Upload finished, but not published, call #finishStashUpload */
266 STASHED: 4,
267
268 /** Upload finished and published */
269 UPLOADED: 5
270 };
271
272 mw.Upload = Upload;
273 }( mediaWiki, jQuery ) );