Follow up r47852. Unlike forkWorkers(), the start() method doesn't get the $procs...
[mediawiki.git] / resources / mediawiki.special / mediawiki.special.upload.js
blobaa26a9e0bf5b35f8b1eefd4a4614f9b3931f857d
1 /*
2  * JavaScript for Special:Upload
3  * Note that additional code still lives in skins/common/upload.js
4  */
6 $( function() {
7         /**
8          * Is the FileAPI available with sufficient functionality?
9          */
10         function hasFileAPI(){
11                 return typeof window.FileReader !== 'undefined';
12         }
14         /**
15          * Check if this is a recognizable image type...
16          * Also excludes files over 10M to avoid going insane on memory usage.
17          *
18          * @todo is there a way we can ask the browser what's supported in <img>s?
19          *
20          * @param {File} file
21          * @return boolean
22          */
23         function fileIsPreviewable( file ) {
24                 var known = ['image/png', 'image/gif', 'image/jpeg', 'image/svg+xml'];
25                 var tooHuge = 10 * 1024 * 1024;
26                 return ($.inArray( file.type, known ) !== -1) && file.size > 0 && file.size < tooHuge;
27         }
29         /**
30          * Show a thumbnail preview of PNG, JPEG, GIF, and SVG files prior to upload
31          * in browsers supporting HTML5 FileAPI.
32          *
33          * As of this writing, known good:
34          * - Firefox 3.6+
35          * - Chrome 7.something
36          *
37          * @todo check file size limits and warn of likely failures
38          *
39          * @param {File} file
40          */
41         function showPreview( file ) {
42                 var previewSize = 180;
43                 
44                 var thumb = $( '<div id="mw-upload-thumbnail" class="thumb tright">' +
45                                                 '<div class="thumbinner">' +
46                                                         '<canvas width="' + previewSize + '" height="' + previewSize + '" ></canvas>' +
47                                                         '<div class="thumbcaption"><div class="filename"></div><div class="fileinfo"></div></div>' +
48                                                 '</div>' +
49                                         '</div>' );
50                 thumb.find( '.filename' ).text( file.name ).end()
51                         .find( '.fileinfo' ).text( prettySize( file.size ) ).end();
52                 
53                 var ctx = thumb.find( 'canvas' )[0].getContext( '2d' );
54                 var spinner = new Image();
55                 spinner.onload = function() { 
56                         ctx.drawImage( spinner, (previewSize - spinner.width) / 2, 
57                                         (previewSize - spinner.height) / 2 ); 
58                 };
59                 spinner.src = wgScriptPath + '/skins/common/images/spinner.gif';
60                 $( '#mw-htmlform-source' ).parent().prepend( thumb );
62                 fetchPreview( file, function( dataURL ) {       
63                         var img = new Image();
64                         var rotation = 0;
65                         img.onload = function() {
66                                 // Fit the image within the previewSizexpreviewSize box
67                                 if ( img.width > img.height ) {
68                                         width = previewSize;
69                                         height = img.height / img.width * previewSize;
70                                 } else {
71                                         height = previewSize;
72                                         width = img.width / img.height * previewSize;
73                                 }
74                                 // Determine the offset required to center the image
75                                 dx = (180 - width) / 2;
76                                 dy = (180 - height) / 2;
77                                 switch ( rotation ) {
78                                         // If a rotation is applied, the direction of the axis
79                                         // changes as well. You can derive the values below by 
80                                         // drawing on paper an axis system, rotate it and see
81                                         // where the positive axis direction is
82                                         case 0:
83                                                 x = dx;
84                                                 y = dy;
85                                                 break;
86                                         case 90:
87                                                 x = dx;
88                                                 y = dy - previewSize;
89                                                 break;
90                                         case 180:
91                                                 x = dx - previewSize;
92                                                 y = dy - previewSize;
93                                                 break;
94                                         case 270:
95                                                 x = dx - previewSize;
96                                                 y = dy;
97                                                 break;
98                                 }
99                                 
100                                 ctx.clearRect( 0, 0, 180, 180 );
101                                 ctx.rotate( rotation / 180 * Math.PI );
102                                 ctx.drawImage( img, x, y, width, height );
103                                 
104                                 // Image size
105                                 var info = mw.msg( 'widthheight', img.width, img.height ) +
106                                         ', ' + prettySize( file.size );
107                                 $( '#mw-upload-thumbnail .fileinfo' ).text( info );
108                         };
109                         img.src = dataURL;
110                 } );
111         }
113         /**
114          * Start loading a file into memory; when complete, pass it as a
115          * data URL to the callback function.
116          *
117          * @param {File} file
118          * @param {function} callback
119          */
120         function fetchPreview( file, callback ) {
121                 var reader = new FileReader();
122                 reader.onload = function() {
123                         callback( reader.result );
124                 };
125                 reader.readAsDataURL( file );
126         }
128         /**
129          * Format a file size attractively.
130          * @todo match numeric formatting
131          *
132          * @param {number} s
133          * @return string
134          */
135         function prettySize( s ) {
136                 var sizes = ['size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes'];
137                 while ( s >= 1024 && sizes.length > 1 ) {
138                         s /= 1024;
139                         sizes = sizes.slice( 1 );
140                 }
141                 return mw.msg( sizes[0], Math.round( s ) );
142         }
144         /**
145          * Clear the file upload preview area.
146          */
147         function clearPreview() {
148                 $( '#mw-upload-thumbnail' ).remove();
149         }
150         
152         if ( hasFileAPI() ) {
153                 // Update thumbnail when the file selection control is updated.
154                 $( '#wpUploadFile' ).change( function() {
155                         clearPreview();
156                         if ( this.files && this.files.length ) {
157                                 // Note: would need to be updated to handle multiple files.
158                                 var file = this.files[0];
159                                 if ( fileIsPreviewable( file ) ) {
160                                         showPreview( file );
161                                 }
162                         }
163                 } );
164         }
165 } );