Merge "Make concurrent runs of FileBackendTest independent"
[mediawiki.git] / skins / common / upload.js
blobdf819e190dbc0f118c375bbd788bc43f470c19d1
1 ( function ( mw, $ ) {
2 var     ajaxUploadDestCheck = mw.config.get( 'wgAjaxUploadDestCheck' ),
3         fileExtensions = mw.config.get( 'wgFileExtensions' );
5 window.licenseSelectorCheck = function() {
6         var selector = document.getElementById( "wpLicense" );
7         var selection = selector.options[selector.selectedIndex].value;
8         if( selector.selectedIndex > 0 ) {
9                 if( selection == "" ) {
10                         // Option disabled, but browser is broken and doesn't respect this
11                         selector.selectedIndex = 0;
12                 }
13         }
14         // We might show a preview
15         wgUploadLicenseObj.fetchPreview( selection );
18 function uploadSetup() {
19         // Disable URL box if the URL copy upload source type is not selected
20         var e = document.getElementById( 'wpSourceTypeurl' );
21         if( e ) {
22                 if( !e.checked ) {
23                         var ein = document.getElementById( 'wpUploadFileURL' );
24                         if(ein)
25                                 ein.setAttribute( 'disabled', 'disabled' );
26                 }
27         }
29         // For MSIE/Mac: non-breaking spaces cause the <option> not to render.
30         // But for some reason, setting the text to itself works
31         var selector = document.getElementById("wpLicense");
32         if (selector) {
33                 var ua = navigator.userAgent;
34                 var isMacIe = (ua.indexOf("MSIE") != -1) && (ua.indexOf("Mac") != -1);
35                 if (isMacIe) {
36                         for (var i = 0; i < selector.options.length; i++) {
37                                 selector.options[i].text = selector.options[i].text;
38                         }
39                 }
40         }
42         // AJAX wpDestFile warnings
43         if ( ajaxUploadDestCheck ) {
44                 // Insert an event handler that fetches upload warnings when wpDestFile
45                 // has been changed
46                 document.getElementById( 'wpDestFile' ).onchange = function ( e ) {
47                         wgUploadWarningObj.checkNow(this.value);
48                 };
49                 // Insert a row where the warnings will be displayed just below the
50                 // wpDestFile row
51                 var optionsTable = document.getElementById( 'mw-htmlform-description' ).tBodies[0];
52                 var row = optionsTable.insertRow( 1 );
53                 var td = document.createElement( 'td' );
54                 td.id = 'wpDestFile-warning';
55                 td.colSpan = 2;
57                 row.appendChild( td );
58         }
60         var wpLicense = document.getElementById( 'wpLicense' );
61         if ( mw.config.get( 'wgAjaxLicensePreview' ) && wpLicense ) {
62                 // License selector check
63                 wpLicense.onchange = licenseSelectorCheck;
65                 // License selector table row
66                 var wpLicenseRow = wpLicense.parentNode.parentNode;
67                 var wpLicenseTbody = wpLicenseRow.parentNode;
69                 var row = document.createElement( 'tr' );
70                 var td = document.createElement( 'td' );
71                 row.appendChild( td );
72                 td = document.createElement( 'td' );
73                 td.id = 'mw-license-preview';
74                 row.appendChild( td );
76                 wpLicenseTbody.insertBefore( row, wpLicenseRow.nextSibling );
77         }
80         // fillDestFile setup
81         var     i,
82                 uploadSourceIds = mw.config.get( 'wgUploadSourceIds' ),
83                 len = uploadSourceIds.length;
84         for ( i = 0; i < len; i += 1 )
85                 document.getElementById( uploadSourceIds[i] ).onchange = function (e) {
86                         fillDestFilename( this.id );
87                 };
91 window.wgUploadWarningObj = {
92         'responseCache' : { '' : '&nbsp;' },
93         'nameToCheck' : '',
94         'typing': false,
95         'delay': 500, // ms
96         'timeoutID': false,
98         'keypress': function () {
99                 if ( !ajaxUploadDestCheck || !sajax_init_object() ) return;
101                 // Find file to upload
102                 var destFile = document.getElementById('wpDestFile');
103                 var warningElt = document.getElementById( 'wpDestFile-warning' );
104                 if ( !destFile || !warningElt ) return ;
106                 this.nameToCheck = destFile.value ;
108                 // Clear timer
109                 if ( this.timeoutID ) {
110                         window.clearTimeout( this.timeoutID );
111                 }
112                 // Check response cache
113                 for (cached in this.responseCache) {
114                         if (this.nameToCheck == cached) {
115                                 this.setWarning(this.responseCache[this.nameToCheck]);
116                                 return;
117                         }
118                 }
120                 this.timeoutID = window.setTimeout( 'wgUploadWarningObj.timeout()', this.delay );
121         },
123         'checkNow': function (fname) {
124                 if ( !ajaxUploadDestCheck || !sajax_init_object() ) return;
125                 if ( this.timeoutID ) {
126                         window.clearTimeout( this.timeoutID );
127                 }
128                 this.nameToCheck = fname;
129                 this.timeout();
130         },
132         'timeout' : function() {
133                 if ( !ajaxUploadDestCheck || !sajax_init_object() ) return;
134                 injectSpinner( document.getElementById( 'wpDestFile' ), 'destcheck' );
136                 // Get variables into local scope so that they will be preserved for the
137                 // anonymous callback. fileName is copied so that multiple overlapping
138                 // ajax requests can be supported.
139                 var obj = this;
140                 var fileName = this.nameToCheck;
141                 sajax_do_call( 'SpecialUpload::ajaxGetExistsWarning', [this.nameToCheck],
142                         function (result) {
143                                 obj.processResult(result, fileName)
144                         }
145                 );
146         },
148         'processResult' : function (result, fileName) {
149                 removeSpinner( 'destcheck' );
150                 this.setWarning(result.responseText);
151                 this.responseCache[fileName] = result.responseText;
152         },
154         'setWarning' : function (warning) {
155                 var warningElt = document.getElementById( 'wpDestFile-warning' );
156                 var ackElt = document.getElementsByName( 'wpDestFileWarningAck' );
158                 this.setInnerHTML(warningElt, warning);
160                 // Set a value in the form indicating that the warning is acknowledged and
161                 // doesn't need to be redisplayed post-upload
162                 if ( warning == '' || warning == '&nbsp;' ) {
163                         ackElt[0].value = '';
164                 } else {
165                         ackElt[0].value = '1';
166                 }
168         },
169         'setInnerHTML' : function (element, text) {
170                 // Check for no change to avoid flicker in IE 7
171                 if (element.innerHTML != text) {
172                         element.innerHTML = text;
173                 }
174         }
177 window.fillDestFilename = function(id) {
178         if ( !mw.config.get( 'wgUploadAutoFill' ) ) {
179                 return;
180         }
181         if (!document.getElementById) {
182                 return;
183         }
184         // Remove any previously flagged errors
185         var e = document.getElementById( 'mw-upload-permitted' );
186         if( e ) e.className = '';
188         var e = document.getElementById( 'mw-upload-prohibited' );
189         if( e ) e.className = '';
191         var path = document.getElementById(id).value;
192         // Find trailing part
193         var slash = path.lastIndexOf('/');
194         var backslash = path.lastIndexOf('\\');
195         var fname;
196         if (slash == -1 && backslash == -1) {
197                 fname = path;
198         } else if (slash > backslash) {
199                 fname = path.substring(slash+1, 10000);
200         } else {
201                 fname = path.substring(backslash+1, 10000);
202         }
204         // Clear the filename if it does not have a valid extension.
205         // URLs are less likely to have a useful extension, so don't include them in the
206         // extension check.
207         if ( mw.config.get( 'wgStrictFileExtensions' ) && fileExtensions && id !== 'wpUploadFileURL' ) {
208                 var found = false;
209                 if ( fname.lastIndexOf( '.' ) !== -1 ) {
210                         var ext = fname.substr( fname.lastIndexOf( '.' ) + 1 );
211                         for ( var i = 0; i < fileExtensions.length; i += 1 ) {
212                                 if ( fileExtensions[i].toLowerCase() === ext.toLowerCase() ) {
213                                         found = true;
214                                         break;
215                                 }
216                         }
217                 }
218                 if( !found ) {
219                         // Not a valid extension
220                         // Clear the upload and set mw-upload-permitted to error
221                         document.getElementById(id).value = '';
222                         var e = document.getElementById( 'mw-upload-permitted' );
223                         if( e ) e.className = 'error';
225                         var e = document.getElementById( 'mw-upload-prohibited' );
226                         if( e ) e.className = 'error';
228                         // Clear wpDestFile as well
229                         var e = document.getElementById( 'wpDestFile' );
230                         if( e ) e.value = '';
232                         return false;
233                 }
234         }
236         // Replace spaces by underscores
237         fname = fname.replace( / /g, '_' );
238         // Capitalise first letter if needed
239         if ( mw.config.get( 'wgCapitalizeUploads' ) ) {
240                 fname = fname.charAt( 0 ).toUpperCase().concat( fname.substring( 1, 10000 ) );
241         }
243         // Output result
244         var destFile = document.getElementById( 'wpDestFile' );
245         if ( destFile ) {
246                 // Call decodeURIComponent function to remove possible URL-encoded characters
247                 // from the file name (bug 30390). Especially likely with upload-form-url.
248                 // decodeURIComponent can throw an exception in input is invalid utf-8
249                 try {
250                         destFile.value = decodeURIComponent( fname );
251                 } catch ( e ) {
252                         destFile.value = fname;
253                 }
254                 wgUploadWarningObj.checkNow( fname );
255         }
258 window.toggleFilenameFiller = function() {
259         if(!document.getElementById) return;
260         var upfield = document.getElementById('wpUploadFile');
261         var destName = document.getElementById('wpDestFile').value;
262         wgUploadAutoFill = ( destName == '' || destName == ' ' );
265 window.wgUploadLicenseObj = {
267         'responseCache' : { '' : '' },
269         'fetchPreview': function( license ) {
270                 if ( !mw.config.get( 'wgAjaxLicensePreview' ) ) return;
271                 for (cached in this.responseCache) {
272                         if (cached == license) {
273                                 this.showPreview( this.responseCache[license] );
274                                 return;
275                         }
276                 }
277                 injectSpinner( document.getElementById( 'wpLicense' ), 'license' );
279                 var title = document.getElementById('wpDestFile').value;
280                 if ( !title ) title = 'File:Sample.jpg';
282                 var url = mw.util.wikiScript( 'api' )
283                         + '?action=parse&text={{' + encodeURIComponent( license ) + '}}'
284                         + '&title=' + encodeURIComponent( title )
285                         + '&prop=text&pst&format=json';
287                 var req = sajax_init_object();
288                 req.onreadystatechange = function() {
289                         if ( req.readyState == 4 && req.status == 200 )
290                                 wgUploadLicenseObj.processResult( eval( '(' + req.responseText + ')' ), license );
291                 };
292                 req.open( 'GET', url, true );
293                 req.send( '' );
294         },
296         'processResult' : function( result, license ) {
297                 removeSpinner( 'license' );
298                 this.responseCache[license] = result['parse']['text']['*'];
299                 this.showPreview( this.responseCache[license] );
300         },
302         'showPreview' : function( preview ) {
303                 var previewPanel = document.getElementById( 'mw-license-preview' );
304                 if( previewPanel.innerHTML != preview )
305                         previewPanel.innerHTML = preview;
306         }
310 $( document ).ready( uploadSetup );
312 }( mediaWiki, jQuery ) );