Brion VIBBER has uploaded a new change for review. https://gerrit.wikimedia.org/r/51287
Change subject: (bug 45500) Support photo uploads on Firefox OS ...................................................................... (bug 45500) Support photo uploads on Firefox OS Firefox OS 1.0 doesn't support <input type="file"> in the browser, but it does have a 'web activities' system which allows a web page to call into apps on the system, such as to pick a photo. * no <input type="file"> https://bugzilla.mozilla.org/show_bug.cgi?id=832923 When <input type="file"> is detected missing and MozActivity class is detected present, we drop in a shim event handler to trigger the picker when you click the photo button. Currently this has some minor issues due to bugs in the Firefox OS Gallery app: * all images flattened to JPEG - https://bugzilla.mozilla.org/show_bug.cgi?id=839630 * EXIF data is stripped - https://bugzilla.mozilla.org/show_bug.cgi?id=846015 * images are recompressed, possibly losing quality Among default apps, you can also choose from the Camera and the system wallpapers. Change-Id: I0068f34a5888cda6c563dddac42dbdb6a73697ac --- M javascripts/modules/mf-photo.js 1 file changed, 79 insertions(+), 29 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MobileFrontend refs/changes/87/51287/1 diff --git a/javascripts/modules/mf-photo.js b/javascripts/modules/mf-photo.js index 35ef0c3..9cbb27e 100644 --- a/javascripts/modules/mf-photo.js +++ b/javascripts/modules/mf-photo.js @@ -25,7 +25,7 @@ var browserSupported = ( typeof FileReader !== 'undefined' && typeof FormData !== 'undefined' && - ($('<input type="file"/>').prop('type') === 'file') // Firefox OS 1.0 turns <input type="file"> into <input type="text"> + (typeof window.MozActivity !== 'undefined' || $('<input type="file"/>').prop('type') === 'file') // Firefox OS 1.0 turns <input type="file"> into <input type="text"> ); return ( @@ -59,8 +59,30 @@ name = name.replace( String.fromCharCode( 27 ), '-' ); name = name.replace( /[\x7f\.\[#<>\[\]\|\{\}\/:]/g, '-' ); - extension = file.name.slice( file.name.lastIndexOf( '.' ) + 1 ); + if (typeof file.name === 'string' && file.name !== '') { + extension = file.name.slice( file.name.lastIndexOf( '.' ) + 1 ); + } else { + // We got a blob without a filename. + extension = extensionForType(file.type); + } return name + '.' + extension; + } + + function extensionForType( type ) { + var extensions = { + 'image/jpeg': 'jpg', + 'image/png': 'png', + 'image/gif': 'gif', + 'image/svg': 'svg', + 'application/pdf': 'pdf' + // add more types + }; + if ( type in extensions ) { + return extensions[type]; + } else { + // uh-oh + return ''; + } } PhotoApi = Api.extend( { @@ -316,42 +338,70 @@ this.options = options; this.log = getLog( options.funnel ); - + $input. // accept must be set via attr otherwise cannot use camera on Android attr( 'accept', 'image/*;' ). on( 'change', function() { - var preview = self.preview = new PhotoUploaderPreview(), - fileReader = new FileReader(); - self.file = $input[0].files[0]; + // clear so that change event is fired again when user selects the same file $input.val( '' ); - self.log( { action: 'preview' } ); - preview. - on( 'cancel', function() { - self.log( { action: 'previewCancel' } ); - nav.closeOverlay(); - } ). - on( 'submit', function() { - self.log( { action: 'previewSubmit' } ); - self._submit(); - } ); - - // FIXME: replace if we make overlay an object (and inherit from it?) - nav.createOverlay( null, preview.$el ); - // skip the URL bar if possible - window.scrollTo( 0, 1 ); - - fileReader.readAsDataURL( self.file ); - fileReader.onload = function() { - var dataUrl = fileReader.result; - // add mimetype if not present (some browsers need it, e.g. Android browser) - dataUrl = dataUrl.replace( /^data:base64/, 'data:image/jpeg;base64' ); - preview.setImageUrl( dataUrl ); - }; + self._handleFile(); } ); + + // Hack for FirefoxOS 1.0 + // <input type="file"> isn't supported, so use Web Activities to pick photo + if (typeof window.MozActivity !== 'undefined' && $('<input type="file"/>').prop('type') !== 'file') { + $input.on( 'mousedown', function(event) { + event.preventDefault(); + var activity = new MozActivity({ + name: "pick", + data: { + // type: ["image/jpeg", "image/png", "image/gif"] + type: ["image/jpeg"] // Gallery misbehaves if you request multiple types -- https://bugzilla.mozilla.org/show_bug.cgi?id=839630 + } + }); + activity.onsuccess = function(event) { + self.file = this.result.blob; + self._handleFile(); + } + }); + } + }, + + /** + * Triggered when a file has been selected to upload + */ + _handleFile: function() { + var self = this; + var preview = self.preview = new PhotoUploaderPreview(), + fileReader = new FileReader(); + + self.log( { action: 'preview' } ); + preview. + on( 'cancel', function() { + self.log( { action: 'previewCancel' } ); + nav.closeOverlay(); + } ). + on( 'submit', function() { + self.log( { action: 'previewSubmit' } ); + self._submit(); + } ); + + // FIXME: replace if we make overlay an object (and inherit from it?) + nav.createOverlay( null, preview.$el ); + // skip the URL bar if possible + window.scrollTo( 0, 1 ); + + fileReader.readAsDataURL( self.file ); + fileReader.onload = function() { + var dataUrl = fileReader.result; + // add mimetype if not present (some browsers need it, e.g. Android browser) + dataUrl = dataUrl.replace( /^data:base64/, 'data:image/jpeg;base64' ); + preview.setImageUrl( dataUrl ); + }; }, _submit: function() { -- To view, visit https://gerrit.wikimedia.org/r/51287 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0068f34a5888cda6c563dddac42dbdb6a73697ac Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/MobileFrontend Gerrit-Branch: master Gerrit-Owner: Brion VIBBER <br...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits