Followup to r99653 (bug 31643) -- reenable client-side thumbnailing of SVGs on Specia...
authorBrion Vibber <brion@users.mediawiki.org>
Sat, 15 Oct 2011 02:23:22 +0000 (02:23 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Sat, 15 Oct 2011 02:23:22 +0000 (02:23 +0000)
Upstream firefox bug for hang loading some SVGs via data URI: https://bugzilla.mozilla.org/show_bug.cgi?id=694165
A fix may land as soon as Firefox 8.

This rev works around the bug by using window.URL.createObjectURL() instead of loading a data URI via FileReader; the object URL loads more cleanly and doesn't have the same hanging bug.

Needs to be replicated to UploadWizard (or moved to a shared lib!), some other fixes coming so no rush.

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

index d7b86d7..3fc9481 100644 (file)
@@ -25,7 +25,7 @@ jQuery( function( $ ) {
         * @return boolean
         */
        function fileIsPreviewable( file ) {
-               var     known = ['image/png', 'image/gif', 'image/jpeg'],
+               var     known = ['image/png', 'image/gif', 'image/jpeg', 'image/svg+xml'],
                        tooHuge = 10 * 1024 * 1024;
                return ( $.inArray( file.type, known ) !== -1 ) && file.size > 0 && file.size < tooHuge;
        }
@@ -160,20 +160,33 @@ jQuery( function( $ ) {
         */
        function fetchPreview( file, callback, callbackBinary ) {
                var reader = new FileReader();
-               reader.onload = function() {
-                       if ( callbackBinary ) {
-                               callbackBinary( reader.result );
-                               reader.onload = function() {
-                                       callback( reader.result );
-                               };
-                               reader.readAsDataURL( file );
-                       } else {
-                               callback( reader.result );
-                       }
-               };
                if ( callbackBinary ) {
+                       // 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 );
+                       };
                        reader.readAsBinaryString( 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. ;)
+                       //
+                       // Lifetime of this URL is until document close, which is fine
+                       // for Special:Upload -- if this code gets used on longer-running
+                       // pages, add a revokeObjectURL() when it's no longer needed.
+                       //
+                       // 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));
                } else {
+                       // This ends up decoding the file to base-64 and back again, which
+                       // feels horribly inefficient.
+                       reader.onload = function() {
+                               callback( reader.result );
+                       };
                        reader.readAsDataURL( file );
                }
        }