Thumbnail previews for PNG, JPEG, GIF, and SVG files on Special:Upload in browsers...
[lhc/web/wiklou.git] / resources / mediawiki.special / mediawiki.special.upload.js
1 /*
2 * JavaScript for Special:Upload
3 * Note that additional code still lives in skins/common/upload.js
4 */
5
6 $(function() {
7 /**
8 * Is the FileAPI available with sufficient functionality?
9 */
10 function hasFileAPI() {
11 return (typeof window.FileReader != "undefined");
12 }
13
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 }
28
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 thumb = $("<div id='mw-upload-thumbnail' class='thumb tright'>" +
43 "<div class='thumbinner'>" +
44 "<img style='max-width: 180px; max-height: 180px' />" +
45 "<div class='thumbcaption'><div class='filename'></div><div class='fileinfo'></div></div>" +
46 "</div>" +
47 "</div>");
48 thumb.find('.filename').text(file.name).end()
49 .find('.fileinfo').text(prettySize(file.size)).end()
50 .find('img').attr('src', wgScriptPath + '/skins/common/images/spinner.gif');
51 $('#mw-htmlform-source').parent().prepend(thumb);
52
53 fetchPreview(file, function(dataURL) {
54 var img = $('#mw-upload-thumbnail img');
55 img.load(function() {
56 if ('naturalWidth' in img[0]) {
57 var w = img[0].naturalWidth, h = img[0].naturalHeight;
58 var info = mediaWiki.msg('widthheight', w, h) +
59 ', ' + prettySize(file.size);
60 $('#mw-upload-thumbnail .fileinfo').text(info);
61 }
62 });
63 img.attr('src', dataURL);
64 });
65 }
66
67 /**
68 * Start loading a file into memory; when complete, pass it as a
69 * data URL to the callback function.
70 *
71 * @param {File} file
72 * @param {function} callback
73 */
74 function fetchPreview(file, callback) {
75 var reader = new FileReader();
76 reader.onload = function() {
77 callback(reader.result);
78 };
79 reader.readAsDataURL(file);
80 }
81
82 /**
83 * Format a file size attractively.
84 * @todo match numeric formatting
85 *
86 * @param {number} s
87 * @return string
88 */
89 function prettySize(s) {
90 var sizes = ['size-bytes', 'size-kilobytes', 'size-megabytes', 'size-gigabytes'];
91 while (s >= 1024 && sizes.length > 1) {
92 s /= 1024;
93 sizes = sizes.slice(1);
94 }
95 return mediaWiki.msg(sizes[0], Math.round(s))
96 }
97
98 /**
99 * Clear the file upload preview area.
100 */
101 function clearPreview() {
102 $('#mw-upload-thumbnail').remove();
103 }
104
105 if (hasFileAPI()) {
106 // Update thumbnail when the file selection control is updated.
107 $('#wpUploadFile').change(function() {
108 clearPreview();
109 if (this.files && this.files.length) {
110 // Note: would need to be updated to handle multiple files.
111 var file = this.files[0];
112 if (fileIsPreviewable(file)) {
113 showPreview(file);
114 }
115 }
116 });
117 }
118 });