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