jenkins-bot has submitted this change and it was merged. Change subject: Load photo uploader dynamically ......................................................................
Load photo uploader dynamically Refactor the code in the process (split the button and "controller" code) and rename/move some of the templates so that it's clear where they belong. Initial page load (stable, desktop Chrome) before: 320KB, after: 303KB. Bug: 48718 Change-Id: I1b167dd27ba0488f99cbd3a29287d8af95011647 --- M includes/Resources.php M javascripts/modules/uploads/LeadPhoto.js M javascripts/modules/uploads/LearnMoreOverlay.js M javascripts/modules/uploads/NagOverlay.js M javascripts/modules/uploads/PhotoUploadProgress.js M javascripts/modules/uploads/PhotoUploader.js A javascripts/modules/uploads/PhotoUploaderButton.js M javascripts/modules/uploads/PhotoUploaderPreview.js R templates/uploads/LeadPhoto.html R templates/uploads/LeadPhotoUploaderButton.html R templates/uploads/LearnMoreOverlay.html R templates/uploads/NagOverlay.html R templates/uploads/PhotoUploadPreview.html R templates/uploads/PhotoUploadProgress.html R templates/uploads/PhotoUploaderButton.html 15 files changed, 294 insertions(+), 237 deletions(-) Approvals: JGonera: Looks good to me, approved Jdlrobson: Looks good to me, but someone else must approve jenkins-bot: Verified diff --git a/includes/Resources.php b/includes/Resources.php index d86f3c3..82ae251 100644 --- a/includes/Resources.php +++ b/includes/Resources.php @@ -156,20 +156,6 @@ 'mobile.stable.plumbing' => array( 'messages' => array( - // NagOverlay.js - 'mobile-frontend-photo-license' => array( 'parse' ), - 'mobile-frontend-photo-nag-1-bullet-1-heading', - 'mobile-frontend-photo-nag-1-bullet-1-text' => array( 'parse' ), - 'mobile-frontend-photo-nag-1-bullet-2-heading', - 'mobile-frontend-photo-nag-1-bullet-2-text', - 'mobile-frontend-photo-nag-2-bullet-1-heading', - 'mobile-frontend-photo-nag-3-bullet-1-heading', - 'parentheses', - 'mobile-frontend-learn-more', - 'mobile-frontend-photo-nag-learn-more-heading', - 'mobile-frontend-photo-nag-learn-more-1' => array( 'parse' ), - 'mobile-frontend-photo-nag-learn-more-2' => array( 'parse' ), - 'mobile-frontend-photo-nag-learn-more-3' => array( 'parse' ), // page.js 'mobile-frontend-talk-overlay-header', 'mobile-frontend-language-article-heading', @@ -189,27 +175,21 @@ 'wikitext/commons-upload', // LanguageOverlay.js 'overlays/languages', - // leadphoto.js - 'leadPhoto', 'overlay', 'overlays/cleanup', - 'overlays/learnMore', // search-2.js 'articleList', 'overlays/search/search', // page.js 'page', 'languageSection', - // PhotoUploader.js + // PhotoUploaderButton.js // For new page action menu - 'photoUploadAction', - 'photoUploader', - // PhotoUploaderPreview.js - 'photoUploadPreview', - // PhotoUploadProgress.js - 'photoUploadProgress', - // NagOverlay.js - 'photoNag', + 'uploads/LeadPhotoUploaderButton', + // FIXME: this should be in special.uploads.plumbing (need to split + // code in PhotoUploaderButton.js into separate files too) + 'uploads/PhotoUploaderButton', + 'ctaDrawer', // mf-references.js 'ReferencesDrawer', @@ -254,6 +234,80 @@ 'mobile-frontend-editor-error-loading', 'mobile-frontend-editor-preview-header', 'mobile-frontend-editor-error-preview', + ), + ), + + 'mobile.uploads' => $wgMFMobileResourceBoilerplate + array( + 'dependencies' => array( + 'mobile.stable', + 'mobile.uploads.plumbing', + ), + 'scripts' => array( + 'javascripts/modules/uploads/LearnMoreOverlay.js', + 'javascripts/modules/uploads/PhotoApi.js', + 'javascripts/modules/uploads/NagOverlay.js', + 'javascripts/modules/uploads/PhotoUploadProgress.js', + 'javascripts/modules/uploads/PhotoUploaderPreview.js', + 'javascripts/modules/uploads/LeadPhoto.js', + 'javascripts/modules/uploads/PhotoUploader.js', + ), + ), + + 'mobile.uploads.plumbing' => array( + 'class' => 'MFResourceLoaderModule', + 'localBasePath' => $localBasePath, + 'localTemplateBasePath' => $localBasePath . '/templates', + 'templates' => array( + 'uploads/PhotoUploadPreview', + 'uploads/PhotoUploadProgress', + 'uploads/NagOverlay', + 'uploads/LearnMoreOverlay', + 'uploads/LeadPhoto', + ), + 'messages' => array( + 'mobile-frontend-photo-upload-success-article', + 'mobile-frontend-photo-upload-error', + + // LearnMoreOverlay.js + 'mobile-frontend-photo-ownership-confirm', + + // PhotoApi.js + 'mobile-frontend-photo-article-edit-comment', + 'mobile-frontend-photo-article-donate-comment', + 'mobile-frontend-photo-upload-error-filename', + 'mobile-frontend-photo-upload-comment', + + // PhotoUploaderPreview.js + 'mobile-frontend-photo-ownership', + 'mobile-frontend-photo-ownership-help', + 'mobile-frontend-photo-caption-placeholder', + 'mobile-frontend-image-loading', + 'mobile-frontend-photo-submit', + 'mobile-frontend-photo-cancel', + 'mobile-frontend-photo-ownership-bullet-one', + 'mobile-frontend-photo-ownership-bullet-two', + 'mobile-frontend-photo-ownership-bullet-three', + 'mobile-frontend-photo-upload-error-file-type', + + // PhotoUploadProgress.js + 'mobile-frontend-image-uploading-wait', + 'mobile-frontend-image-uploading-long', + 'mobile-frontend-image-uploading-cancel', + + // NagOverlay.js + 'mobile-frontend-photo-license' => array( 'parse' ), + 'mobile-frontend-photo-nag-1-bullet-1-heading', + 'mobile-frontend-photo-nag-1-bullet-1-text' => array( 'parse' ), + 'mobile-frontend-photo-nag-1-bullet-2-heading', + 'mobile-frontend-photo-nag-1-bullet-2-text', + 'mobile-frontend-photo-nag-2-bullet-1-heading', + 'mobile-frontend-photo-nag-3-bullet-1-heading', + 'parentheses', + 'mobile-frontend-learn-more', + 'mobile-frontend-photo-nag-learn-more-heading', + 'mobile-frontend-photo-nag-learn-more-1' => array( 'parse' ), + 'mobile-frontend-photo-nag-learn-more-2' => array( 'parse' ), + 'mobile-frontend-photo-nag-learn-more-3' => array( 'parse' ), ), ), @@ -432,13 +486,7 @@ 'javascripts/common/notification.js', 'javascripts/views/page.js', // Upload specific code - 'javascripts/modules/uploads/LearnMoreOverlay.js', - 'javascripts/modules/uploads/PhotoApi.js', - 'javascripts/modules/uploads/NagOverlay.js', - 'javascripts/modules/uploads/PhotoUploadProgress.js', - 'javascripts/modules/uploads/PhotoUploaderPreview.js', - 'javascripts/modules/uploads/LeadPhoto.js', - 'javascripts/modules/uploads/PhotoUploader.js', + 'javascripts/modules/uploads/PhotoUploaderButton.js', // Language specific code 'javascripts/common/languages/LanguageOverlay.js', ), @@ -449,36 +497,11 @@ 'mobile-frontend-drawer-cancel', 'mobile-frontend-overlay-escape', - // LearnMoreOverlay.js, newbie.js - 'mobile-frontend-photo-ownership-confirm', - 'cancel', - - // PhotoApi.js - 'mobile-frontend-photo-article-edit-comment', - 'mobile-frontend-photo-article-donate-comment', - 'mobile-frontend-photo-upload-error-filename', - 'mobile-frontend-photo-upload-comment', - - // PhotoUploader.js - 'mobile-frontend-photo-upload-error', + // PhotoUploaderButton.js 'mobile-frontend-photo-upload-cta', - // PhotoUploaderPreview.js - 'mobile-frontend-photo-ownership', - 'mobile-frontend-photo-ownership-help', - 'mobile-frontend-photo-caption-placeholder', - 'mobile-frontend-image-loading', - 'mobile-frontend-photo-submit', - 'mobile-frontend-photo-cancel', - 'mobile-frontend-photo-ownership-bullet-one', - 'mobile-frontend-photo-ownership-bullet-two', - 'mobile-frontend-photo-ownership-bullet-three', - 'mobile-frontend-photo-upload-error-file-type', - - // PhotoUploadProgress.js - 'mobile-frontend-image-uploading-wait', - 'mobile-frontend-image-uploading-long', - 'mobile-frontend-image-uploading-cancel', + // LearnMoreOverlay.js, newbie.js + 'cancel', // LanguageOverlay.js 'mobile-frontend-language-header', @@ -530,7 +553,6 @@ 'mobile-frontend-photo-upload-protected', 'mobile-frontend-photo-upload-anon', 'mobile-frontend-photo-upload-unavailable', - 'mobile-frontend-photo-upload-success-article', 'mobile-frontend-photo-upload', // mf-watchstar.js @@ -560,6 +582,8 @@ /** * Special page modules + * FIXME: Remove the need for these by making more reusable CSS + * FIXME: Rename these modules in the interim to clarify that they are modules for use on special pages * * Note: Use correct names to ensure modules load on pages * Name must be the name of the special page lowercased prefixed by 'mobile.' @@ -681,7 +705,7 @@ ), // Special:Uploads - 'mobile.uploads.plumbing' => $wgMFMobileResourceTemplateBoilerplate + array( + 'mobile.special.uploads.plumbing' => $wgMFMobileResourceTemplateBoilerplate + array( 'templates' => array( 'specials/uploads/carousel', 'specials/uploads/photo', @@ -690,9 +714,10 @@ ), 'mobile.uploads.scripts' => $wgMFMobileResourceBoilerplate + array( 'dependencies' => array( - 'mobile.uploads.plumbing', + 'mobile.special.uploads.plumbing', 'mobile.stable.styles', 'mobile.stable.common', + 'mobile.uploads', ), 'messages' => array( 'mobile-frontend-photo-upload-generic', diff --git a/javascripts/modules/uploads/LeadPhoto.js b/javascripts/modules/uploads/LeadPhoto.js index a7fe59a..2aed30c 100644 --- a/javascripts/modules/uploads/LeadPhoto.js +++ b/javascripts/modules/uploads/LeadPhoto.js @@ -3,7 +3,7 @@ var View = M.require( 'view' ), LeadPhoto; LeadPhoto = View.extend( { - template: M.template.get( 'leadPhoto' ), + template: M.template.get( 'uploads/LeadPhoto' ), animate: function() { this.$el.hide().slideDown(); diff --git a/javascripts/modules/uploads/LearnMoreOverlay.js b/javascripts/modules/uploads/LearnMoreOverlay.js index c843643..9a82fc2 100644 --- a/javascripts/modules/uploads/LearnMoreOverlay.js +++ b/javascripts/modules/uploads/LearnMoreOverlay.js @@ -4,7 +4,7 @@ defaults: { confirmMessage: mw.msg( 'mobile-frontend-photo-ownership-confirm' ) }, - template: M.template.get( 'overlays/learnMore' ) + template: M.template.get( 'uploads/LearnMoreOverlay' ) } ); M.define( 'modules/uploads/LearnMoreOverlay', LearnMoreOverlay ); diff --git a/javascripts/modules/uploads/NagOverlay.js b/javascripts/modules/uploads/NagOverlay.js index a2511f3..f44dfcb 100644 --- a/javascripts/modules/uploads/NagOverlay.js +++ b/javascripts/modules/uploads/NagOverlay.js @@ -8,7 +8,7 @@ learnMore: mw.msg( 'parentheses', mw.msg( 'mobile-frontend-learn-more' ) ) }, - template: M.template.get( 'photoNag' ), + template: M.template.get( 'uploads/NagOverlay' ), initialize: function( options ) { this.learnMoreOverlay = new LearnMoreOverlay( { diff --git a/javascripts/modules/uploads/PhotoUploadProgress.js b/javascripts/modules/uploads/PhotoUploadProgress.js index ff2bd14..0b853cc 100644 --- a/javascripts/modules/uploads/PhotoUploadProgress.js +++ b/javascripts/modules/uploads/PhotoUploadProgress.js @@ -10,7 +10,7 @@ messageInterval: 10000 }, - template: M.template.get( 'photoUploadProgress' ), + template: M.template.get( 'uploads/PhotoUploadProgress' ), className: 'drawer position-fixed text loading', locked: true, diff --git a/javascripts/modules/uploads/PhotoUploader.js b/javascripts/modules/uploads/PhotoUploader.js index bf8a7a0..48d2e72 100644 --- a/javascripts/modules/uploads/PhotoUploader.js +++ b/javascripts/modules/uploads/PhotoUploader.js @@ -1,30 +1,11 @@ ( function( M, $ ) { - var View = M.require( 'view' ), + var Class = M.require( 'Class' ), popup = M.require( 'notifications' ), - CtaDrawer = M.require( 'CtaDrawer' ), NagOverlay = M.require( 'modules/uploads/NagOverlay' ), PhotoApi = M.require( 'modules/uploads/PhotoApi' ), PhotoUploadProgress = M.require( 'modules/uploads/PhotoUploadProgress' ), PhotoUploaderPreview = M.require( 'modules/uploads/PhotoUploaderPreview' ), - PhotoUploader, - PhotoUploaderButton, - LeadPhoto = M.require( 'modules/uploads/LeadPhoto' ), - LeadPhotoUploaderButton; - - function isSupported() { - // FIXME: create a module for browser detection stuff - // deal with known false positives which don't support file input (bug 47374) - if ( navigator.userAgent.match( /Windows Phone (OS 7|8.0)/ ) ) { - return false; - } - 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"> - ); - - return browserSupported && !mw.config.get( 'wgImagesDisabled', false ); - } + PhotoUploader; function getLog( funnel ) { return function( data ) { @@ -43,119 +24,39 @@ }; } - /** - * PhotoUploader is a component for uploading images to the wiki. - * - * @example - * <code> - * var photoUploader = new PhotoUploader( { - * buttonCaption: 'Add a photo', - * } ); - * photoUploader. - * insertAfter( 'h1' ). - * on( 'upload', function( fileName, url ) { - * $( '.someImage' ).attr( 'src', url ); - * } ); - * </code> - * - * @constructor - * @param {Object} options Uploader options. - * @param {string} options.buttonCaption Caption for the upload button. - * @param {boolean} options.insertInPage If the image should be prepended - * to the wikitext of a page specified by options.pageTitle. - * @param {string} options.pageTitle Title of the page to which the image - * belongs (image name will be based on this) and to which it should be - * prepended (if options.insertInPage is true). - * @fires PhotoUploader#start - * @fires PhotoUploader#success - * @fires PhotoUploader#error - * @fires PhotoUploader#cancel - */ - /** - * Triggered when image upload starts. - * - * @event PhotoUploader#start - */ - /** - * Triggered when image upload is finished successfully. - * - * @event PhotoUploader#success - * @property {Object} data Uploaded image data. - * @property {string} data.fileName Name of the uploaded image. - * @property {string} data.description Name of the uploaded image. - * @property {string} data.url URL to the uploaded image (can be a - * local data URL). - */ - /** - * Triggered when image upload fails. - * - * @event PhotoUploader#error - */ - /** - * Triggered when image upload is cancelled. - * - * @event PhotoUploader#cancel - */ - PhotoUploader = View.extend( { + PhotoUploader = Class.extend( { initialize: function( options ) { + var nagCount = parseInt( M.settings.getUserSetting( 'uploadNagCount' ) || 0, 10 ), + shouldNag = parseInt( mw.config.get( 'wgUserEditCount' ), 10 ) < 3, + fileReader = new FileReader(), nagOverlay, preview; + this.log = getLog( options.funnel ); - this._super( options ); - }, + preview = this.preview = new PhotoUploaderPreview( { log: this.log } ); - postRender: function() { - var self = this, $input = this.$( 'input' ), ctaDrawer; + this.options = options; + this.parent = options.parent; + this.file = options.file; - // show CTA instead if not logged in - if ( !M.isLoggedIn() ) { - ctaDrawer = new CtaDrawer( { - content: mw.msg( 'mobile-frontend-photo-upload-cta' ), - queryParams: { - campaign: 'mobile_uploadPageActionCta', - returntoquery: 'article_action=photo-upload' - } - } ); - this.$el.click( function( ev ) { - ctaDrawer.show(); - ev.preventDefault(); - } ); - return; + // nag if never nagged and shouldNag and then keep nagging (3 times) + if ( ( nagCount === 0 && shouldNag ) || ( nagCount > 0 && nagCount < 3 ) ) { + // FIXME: possibly set self.preview.parent = nagOverlay when nagOverlay is present + nagOverlay = this._showNagOverlay( nagCount ); + } else { + this._showPreview(); } - $input. - // accept must be set via attr otherwise cannot use camera on Android - attr( 'accept', 'image/*;' ). - on( 'change', function() { - var nagCount = parseInt( M.settings.getUserSetting( 'uploadNagCount' ) || 0, 10 ), - shouldNag = parseInt( mw.config.get( 'wgUserEditCount' ), 10 ) < 3, - fileReader = new FileReader(), nagOverlay; + fileReader.readAsDataURL( this.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' ); - self.preview = new PhotoUploaderPreview( { log: self.log } ); - - self.file = $input[0].files[0]; - // clear so that change event is fired again when user selects the same file - $input.val( '' ); - - // nag if never nagged and shouldNag and then keep nagging (3 times) - if ( ( nagCount === 0 && shouldNag ) || ( nagCount > 0 && nagCount < 3 ) ) { - // FIXME: possibly set self.preview.parent = nagOverlay when nagOverlay is present - nagOverlay = self._showNagOverlay( nagCount ); - } else { - self._showPreview(); - } - - 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' ); - - if ( nagOverlay ) { - nagOverlay.setImageUrl( dataUrl ); - } - self.preview.setImageUrl( dataUrl ); - }; - } ); + if ( nagOverlay ) { + nagOverlay.setImageUrl( dataUrl ); + } + preview.setImageUrl( dataUrl ); + }; }, _showNagOverlay: function( nagCount ) { @@ -217,13 +118,13 @@ api = new PhotoApi(), progressPopup = new PhotoUploadProgress(); - this.emit( 'start' ); + this.parent.emit( 'start' ); this.preview.hide(); progressPopup.show(); progressPopup.on( 'cancel', function() { api.abort(); self.log( { action: 'cancel' } ); - self.emit( 'cancel' ); + self.parent.emit( 'cancel' ); } ); api.save( { @@ -234,7 +135,7 @@ } ).done( function( fileName, descriptionUrl ) { progressPopup.hide(); self.log( { action: 'success' } ); - self.emit( 'success', { + self.parent.emit( 'success', { fileName: fileName, description: description, descriptionUrl: descriptionUrl, @@ -244,7 +145,7 @@ progressPopup.hide(); popup.show( msg || mw.msg( 'mobile-frontend-photo-upload-error' ), 'toast error' ); self.log( { action: 'error', errorText: err } ); - self.emit( 'error' ); + self.parent.emit( 'error' ); } ); api.on( 'uploadProgress', function( value ) { @@ -253,43 +154,6 @@ } } ); - // An extension of the PhotoUploader which instead of treating it as a button treats it as a full screen bar - PhotoUploaderButton = PhotoUploader.extend( { - template: M.template.get( 'photoUploader' ), - className: 'button photo' - } ); - - LeadPhotoUploaderButton = PhotoUploader.extend( { - template: M.template.get( 'photoUploadAction' ), - className: 'enabled', - initialize: function( options ) { - var self = this; - this._super( options ); - this.on( 'start', function() { - self.$el.removeClass( 'enabled' ); - } ). - on( 'success', function( data ) { - popup.show( mw.msg( 'mobile-frontend-photo-upload-success-article' ), 'toast' ); - // FIXME: workaround for https://bugzilla.wikimedia.org/show_bug.cgi?id=43271 - if ( !$( '#content_0' ).length ) { - $( '<div id="content_0" >' ).insertAfter( $( '#section_0,#page-actions' ).last() ); - } - new LeadPhoto( { - url: data.url, - pageUrl: data.descriptionUrl, - caption: data.description - } ).prependTo( '#content_0' ); - } ). - on( 'error cancel', function() { - self.$el.addClass( 'enabled' ); - } ); - } - } ); - - PhotoUploaderButton.isSupported = LeadPhotoUploaderButton.isSupported = isSupported(); - - // FIXME: should we allow more than one define() per file? - M.define( 'modules/uploads/PhotoUploaderButton', PhotoUploaderButton ); - M.define( 'modules/uploads/LeadPhotoUploaderButton', LeadPhotoUploaderButton ); + M.define( 'modules/uploads/PhotoUploader', PhotoUploader ); }( mw.mobileFrontend, jQuery ) ); diff --git a/javascripts/modules/uploads/PhotoUploaderButton.js b/javascripts/modules/uploads/PhotoUploaderButton.js new file mode 100644 index 0000000..5d289c6 --- /dev/null +++ b/javascripts/modules/uploads/PhotoUploaderButton.js @@ -0,0 +1,168 @@ +( function( M, $ ) { + var View = M.require( 'view' ), + popup = M.require( 'notifications' ), + CtaDrawer = M.require( 'CtaDrawer' ), + LoadingOverlay = M.require( 'LoadingOverlay' ), + PhotoUploaderButton, + LeadPhotoUploaderButton; + + function isSupported() { + // FIXME: create a module for browser detection stuff + // deal with known false positives which don't support file input (bug 47374) + if ( navigator.userAgent.match( /Windows Phone (OS 7|8.0)/ ) ) { + return false; + } + 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"> + ); + + return browserSupported && !mw.config.get( 'wgImagesDisabled', false ); + } + + /** + * PhotoUploaderButton is a component for uploading images to the wiki. + * + * @example + * <code> + * var photoUploaderButton = new PhotoUploaderButton( { + * buttonCaption: 'Add a photo', + * } ); + * photoUploaderButton. + * insertAfter( 'h1' ). + * on( 'upload', function( fileName, url ) { + * $( '.someImage' ).attr( 'src', url ); + * } ); + * </code> + * + * @constructor + * @param {Object} options Uploader options. + * @param {string} options.buttonCaption Caption for the upload button. + * @param {boolean} options.insertInPage If the image should be prepended + * to the wikitext of a page specified by options.pageTitle. + * @param {string} options.pageTitle Title of the page to which the image + * belongs (image name will be based on this) and to which it should be + * prepended (if options.insertInPage is true). + * @param {string} options.funnel Funnel for EventLogging. + * @fires PhotoUploader#start + * @fires PhotoUploader#success + * @fires PhotoUploader#error + * @fires PhotoUploader#cancel + */ + /** + * Triggered when image upload starts. + * + * @event PhotoUploader#start + */ + /** + * Triggered when image upload is finished successfully. + * + * @event PhotoUploader#success + * @property {Object} data Uploaded image data. + * @property {string} data.fileName Name of the uploaded image. + * @property {string} data.description Name of the uploaded image. + * @property {string} data.url URL to the uploaded image (can be a + * local data URL). + */ + /** + * Triggered when image upload fails. + * + * @event PhotoUploader#error + */ + /** + * Triggered when image upload is cancelled. + * + * @event PhotoUploader#cancel + */ + PhotoUploaderButton = View.extend( { + template: M.template.get( 'uploads/PhotoUploaderButton' ), + className: 'button photo', + + initialize: function( options ) { + this._super( options ); + }, + + postRender: function() { + var self = this, $input = this.$( 'input' ), ctaDrawer; + + // show CTA instead if not logged in + if ( !M.isLoggedIn() ) { + ctaDrawer = new CtaDrawer( { + content: mw.msg( 'mobile-frontend-photo-upload-cta' ), + queryParams: { + campaign: 'mobile_uploadPageActionCta', + returntoquery: 'article_action=photo-upload' + } + } ); + this.$el.click( function( ev ) { + ctaDrawer.show(); + ev.preventDefault(); + } ); + return; + } + + $input. + // accept must be set via attr otherwise cannot use camera on Android + attr( 'accept', 'image/*;' ). + on( 'change', function() { + var options = $.extend( {}, self.options, { + file: $input[0].files[0], + parent: self + } ), + loadingOverlay = new LoadingOverlay(); + + loadingOverlay.show(); + mw.loader.using( 'mobile.uploads', function() { + var PhotoUploader = M.require( 'modules/uploads/PhotoUploader' ); + loadingOverlay.hide(); + new PhotoUploader( options ); + } ); + + // clear so that change event is fired again when user selects the same file + $input.val( '' ); + } ); + } + } ); + + LeadPhotoUploaderButton = PhotoUploaderButton.extend( { + template: M.template.get( 'uploads/LeadPhotoUploaderButton' ), + className: 'enabled', + + initialize: function( options ) { + var self = this; + this._super( options ); + this.on( 'start', function() { + self.$el.removeClass( 'enabled' ); + } ). + on( 'success', function( data ) { + popup.show( mw.msg( 'mobile-frontend-photo-upload-success-article' ), 'toast' ); + // FIXME: workaround for https://bugzilla.wikimedia.org/show_bug.cgi?id=43271 + if ( !$( '#content_0' ).length ) { + $( '<div id="content_0" >' ).insertAfter( $( '#section_0,#page-actions' ).last() ); + } + + // just in case, LeadPhoto should be loaded by now anyway + mw.loader.using( 'mobile.uploads', function() { + var LeadPhoto = M.require( 'modules/uploads/LeadPhoto' ); + + new LeadPhoto( { + url: data.url, + pageUrl: data.descriptionUrl, + caption: data.description + } ).prependTo( '#content_0' ); + } ); + } ). + on( 'error cancel', function() { + self.$el.addClass( 'enabled' ); + } ); + } + } ); + + PhotoUploaderButton.isSupported = LeadPhotoUploaderButton.isSupported = isSupported(); + + // FIXME: should we allow more than one define() per file? + M.define( 'modules/uploads/PhotoUploaderButton', PhotoUploaderButton ); + M.define( 'modules/uploads/LeadPhotoUploaderButton', LeadPhotoUploaderButton ); + +}( mw.mobileFrontend, jQuery ) ); diff --git a/javascripts/modules/uploads/PhotoUploaderPreview.js b/javascripts/modules/uploads/PhotoUploaderPreview.js index 53c2abe..a548874 100644 --- a/javascripts/modules/uploads/PhotoUploaderPreview.js +++ b/javascripts/modules/uploads/PhotoUploaderPreview.js @@ -18,7 +18,7 @@ className: 'mw-mf-overlay photo-overlay', - template: M.template.get( 'photoUploadPreview' ), + template: M.template.get( 'uploads/PhotoUploadPreview' ), initialize: function( options ) { this.log = options.log; diff --git a/templates/leadPhoto.html b/templates/uploads/LeadPhoto.html similarity index 100% rename from templates/leadPhoto.html rename to templates/uploads/LeadPhoto.html diff --git a/templates/photoUploadAction.html b/templates/uploads/LeadPhotoUploaderButton.html similarity index 100% rename from templates/photoUploadAction.html rename to templates/uploads/LeadPhotoUploaderButton.html diff --git a/templates/overlays/learnMore.html b/templates/uploads/LearnMoreOverlay.html similarity index 100% rename from templates/overlays/learnMore.html rename to templates/uploads/LearnMoreOverlay.html diff --git a/templates/photoNag.html b/templates/uploads/NagOverlay.html similarity index 100% rename from templates/photoNag.html rename to templates/uploads/NagOverlay.html diff --git a/templates/photoUploadPreview.html b/templates/uploads/PhotoUploadPreview.html similarity index 100% rename from templates/photoUploadPreview.html rename to templates/uploads/PhotoUploadPreview.html diff --git a/templates/photoUploadProgress.html b/templates/uploads/PhotoUploadProgress.html similarity index 100% rename from templates/photoUploadProgress.html rename to templates/uploads/PhotoUploadProgress.html diff --git a/templates/photoUploader.html b/templates/uploads/PhotoUploaderButton.html similarity index 100% rename from templates/photoUploader.html rename to templates/uploads/PhotoUploaderButton.html -- To view, visit https://gerrit.wikimedia.org/r/84032 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1b167dd27ba0488f99cbd3a29287d8af95011647 Gerrit-PatchSet: 5 Gerrit-Project: mediawiki/extensions/MobileFrontend Gerrit-Branch: master Gerrit-Owner: JGonera <jgon...@wikimedia.org> Gerrit-Reviewer: JGonera <jgon...@wikimedia.org> Gerrit-Reviewer: Jdlrobson <jrob...@wikimedia.org> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits