From a039f291ace5652b69aae3dcfe197a785e36d253 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sun, 26 Dec 2010 22:01:26 +0000 Subject: [PATCH] Thumbnail previews for PNG, JPEG, GIF, and SVG files on Special:Upload in browsers supporting HTML 5 FileAPI Known good: * Firefox 3.6+ * Chrome 7.something+ --- includes/specials/SpecialUpload.php | 8 +- resources/Resources.php | 5 + .../mediawiki.special.upload.js | 118 ++++++++++++++++++ 3 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 resources/mediawiki.special/mediawiki.special.upload.js diff --git a/includes/specials/SpecialUpload.php b/includes/specials/SpecialUpload.php index 35a04c729d..0e81f91a5a 100644 --- a/includes/specials/SpecialUpload.php +++ b/includes/specials/SpecialUpload.php @@ -1082,8 +1082,12 @@ class UploadForm extends HTMLForm { $wgOut->addScript( Skin::makeVariablesScript( $scriptVars ) ); - // For support - $wgOut->addModules( array( 'mediawiki.legacy.edit', 'mediawiki.legacy.upload' ) ); + + $wgOut->addModules( array( + 'mediawiki.legacy.edit', // For support + 'mediawiki.legacy.upload', // Old form stuff... + 'mediawiki.special.upload', // Newer extras for thumbnail preview. + ) ); } /** diff --git a/resources/Resources.php b/resources/Resources.php index 82911fd944..27d94e65b7 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -360,6 +360,11 @@ return array( 'mediawiki.special.search' => array( 'scripts' => 'resources/mediawiki.special/mediawiki.special.search.js', ), + 'mediawiki.special.upload' => array( + // @todo: merge in remainder of mediawiki.legacy.upload + 'scripts' => 'resources/mediawiki.special/mediawiki.special.upload.js', + 'messages' => array( 'widthheight', 'size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes' ), + ), 'mediawiki.language' => array( 'scripts' => 'resources/mediawiki.language/mediawiki.language.js', 'languageScripts' => array( diff --git a/resources/mediawiki.special/mediawiki.special.upload.js b/resources/mediawiki.special/mediawiki.special.upload.js new file mode 100644 index 0000000000..e47d71d42c --- /dev/null +++ b/resources/mediawiki.special/mediawiki.special.upload.js @@ -0,0 +1,118 @@ +/* + * JavaScript for Special:Upload + * Note that additional code still lives in skins/common/upload.js + */ + +$(function() { + /** + * Is the FileAPI available with sufficient functionality? + */ + function hasFileAPI() { + return (typeof window.FileReader != "undefined"); + } + + /** + * Check if this is a recognizable image type... + * Also excludes files over 10M to avoid going insane on memory usage. + * + * @todo is there a way we can ask the browser what's supported in s? + * + * @param {File} file + * @return boolean + */ + function fileIsPreviewable(file) { + var known = ['image/png', 'image/gif', 'image/jpeg', 'image/svg+xml']; + var tooHuge = 10 * 1024 * 1024; + return ($.inArray(file.type, known) != -1) && (file.size > 0) && (file.size < tooHuge); + } + + /** + * Show a thumbnail preview of PNG, JPEG, GIF, and SVG files prior to upload + * in browsers supporting HTML5 FileAPI. + * + * As of this writing, known good: + * - Firefox 3.6+ + * - Chrome 7.something + * + * @todo check file size limits and warn of likely failures + * + * @param {File} file + */ + function showPreview(file) { + var thumb = $("
" + + "
" + + "" + + "
" + + "
" + + "
"); + thumb.find('.filename').text(file.name).end() + .find('.fileinfo').text(prettySize(file.size)).end() + .find('img').attr('src', wgScriptPath + '/skins/common/images/spinner.gif'); + $('#mw-htmlform-source').parent().prepend(thumb); + + fetchPreview(file, function(dataURL) { + var img = $('#mw-upload-thumbnail img'); + img.load(function() { + if ('naturalWidth' in img[0]) { + var w = img[0].naturalWidth, h = img[0].naturalHeight; + var info = mediaWiki.msg('widthheight', w, h) + + ', ' + prettySize(file.size); + $('#mw-upload-thumbnail .fileinfo').text(info); + } + }); + img.attr('src', dataURL); + }); + } + + /** + * Start loading a file into memory; when complete, pass it as a + * data URL to the callback function. + * + * @param {File} file + * @param {function} callback + */ + function fetchPreview(file, callback) { + var reader = new FileReader(); + reader.onload = function() { + callback(reader.result); + }; + reader.readAsDataURL(file); + } + + /** + * Format a file size attractively. + * @todo match numeric formatting + * + * @param {number} s + * @return string + */ + function prettySize(s) { + var sizes = ['size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes']; + while (s >= 1024 && sizes.length > 1) { + s /= 1024; + sizes = sizes.slice(1); + } + return mediaWiki.msg(sizes[0], Math.round(s)) + } + + /** + * Clear the file upload preview area. + */ + function clearPreview() { + $('#mw-upload-thumbnail').remove(); + } + + if (hasFileAPI()) { + // Update thumbnail when the file selection control is updated. + $('#wpUploadFile').change(function() { + clearPreview(); + if (this.files && this.files.length) { + // Note: would need to be updated to handle multiple files. + var file = this.files[0]; + if (fileIsPreviewable(file)) { + showPreview(file); + } + } + }); + } +}); -- 2.20.1