(bug 35870) Fix pre-upload preview on IE 10 for Special:Upload
authorBrion Vibber <brion@pobox.com>
Fri, 13 Apr 2012 21:54:01 +0000 (14:54 -0700)
committerKaldari <rkaldari@wikimedia.org>
Sat, 21 Apr 2012 01:43:59 +0000 (18:43 -0700)
When loading thumbnails, we fetch the actual file data so we can find EXIF data in JPEGs
and do suitable rotation fixes.

This currently uses binary strings via FileReader.readAsBinaryString, but that's not
implemented in IE 10.

Workaround uses FileReader.readAsArrayBuffer and converts to a binary string in case
FileReader.readAsBinaryString is missing but readAsArrayBuffer is there.

Patchset 2: fixed bug number, expanded details
Patchset 3: cleaned up
Patchset 4: summary fix
Patchset 5: whitespace clean-up

Change-Id: Ia0258f5f400a2a52a484f33fbffed7d848245d22

resources/mediawiki.special/mediawiki.special.upload.js

index 85b3f3f..f7a4b1f 100644 (file)
@@ -156,17 +156,33 @@ jQuery( function( $ ) {
         */
        function fetchPreview( file, callback, callbackBinary ) {
                var reader = new FileReader();
-               if ( callbackBinary ) {
+               if ( callbackBinary && 'readAsBinaryString' in reader ) {
                        // To fetch JPEG metadata we need a binary string; start there.
                        // todo: 
                        reader.onload = function() {
                                callbackBinary( reader.result );
 
                                // Now run back through the regular code path.
-                               fetchPreview(file, callback );
+                               fetchPreview( file, callback );
                        };
                        reader.readAsBinaryString( file );
-               } else if ('URL' in window && 'createObjectURL' in window.URL) {
+               } else if ( callbackBinary && 'readAsArrayBuffer' in reader ) {
+                       // readAsArrayBuffer replaces readAsBinaryString
+                       // However, our JPEG metadata library wants a string.
+                       // So, this is going to be an ugly conversion.
+                       reader.onload = function() {
+                               var buffer = new Uint8Array( reader.result ),
+                                       string = '';
+                               for ( var i = 0; i < buffer.byteLength; i++ ) {
+                                       string += String.fromCharCode( buffer[i] );
+                               }
+                               callbackBinary( string );
+
+                               // Now run back through the regular code path.
+                               fetchPreview( file, callback );
+                       };
+                       reader.readAsArrayBuffer( file );
+               } else if ( 'URL' in window && 'createObjectURL' in window.URL ) {
                        // Supported in Firefox 4.0 and above <https://developer.mozilla.org/en/DOM/window.URL.createObjectURL>
                        // WebKit has it in a namespace for now but that's ok. ;)
                        //
@@ -176,7 +192,7 @@ jQuery( function( $ ) {
                        //
                        // Prefer this over readAsDataURL for Firefox 7 due to bug reading
                        // some SVG files from data URIs <https://bugzilla.mozilla.org/show_bug.cgi?id=694165>
-                       callback(window.URL.createObjectURL(file));
+                       callback( window.URL.createObjectURL( file ) );
                } else {
                        // This ends up decoding the file to base-64 and back again, which
                        // feels horribly inefficient.