Sumit has uploaded a new change for review. https://gerrit.wikimedia.org/r/265547
Change subject: MobileFrontend Remove deprecated Class.extend ...................................................................... MobileFrontend Remove deprecated Class.extend Remove all instances of Class.extend and introduces OO.mfExtend for extending modules. Bug: T123077 Change-Id: I641f9f4145b0e96b33beefcef35bc2cfa243696d --- M resources/mobile.abusefilter/AbuseFilterOverlay.js M resources/mobile.abusefilter/AbuseFilterPanel.js M resources/mobile.backtotop/BackToTopOverlay.js M resources/mobile.betaoptin/BetaOptinPanel.js M resources/mobile.categories.overlays/CategoryAddOverlay.js M resources/mobile.categories.overlays/CategoryOverlay.js M resources/mobile.commonsCategory/CommonsCategoryOverlay.js M resources/mobile.contentOverlays/PointerOverlay.js M resources/mobile.drawers/CtaDrawer.js M resources/mobile.drawers/Drawer.js M resources/mobile.editor.common/EditorOverlayBase.js M resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js M resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js M resources/mobile.editor.overlay/EditorOverlay.js M resources/mobile.editor.ve/VisualEditorOverlay.js M resources/mobile.fontchanger/FontChanger.js M resources/mobile.gallery/PhotoItem.js M resources/mobile.gallery/PhotoList.js M resources/mobile.issues/CleanupOverlay.js M resources/mobile.languages/LanguageOverlay.js M resources/mobile.loggingSchemas/SchemaEdit.js M resources/mobile.loggingSchemas/SchemaMobileWebSectionUsage.js M resources/mobile.mainMenu/MainMenu.js M resources/mobile.mediaViewer.beta/ImageOverlayBeta.js M resources/mobile.mediaViewer/ImageOverlay.js M resources/mobile.messageBox/MessageBox.js M resources/mobile.nearby/Nearby.js M resources/mobile.notifications.overlay/NotificationsOverlay.js M resources/mobile.overlays/ContentOverlay.js M resources/mobile.overlays/LoadingOverlay.js M resources/mobile.overlays/Overlay.js M resources/mobile.pagelist.scripts/WatchstarPageList.js M resources/mobile.pagelist/PageList.js M resources/mobile.references/ReferencesDrawer.js M resources/mobile.search/SearchOverlay.js M resources/mobile.special.mobileoptions.scripts/mobileoptions.js M resources/mobile.startup/Anchor.js M resources/mobile.startup/Button.js M resources/mobile.startup/Icon.js M resources/mobile.startup/Page.js M resources/mobile.startup/Panel.js M resources/mobile.startup/Schema.js M resources/mobile.startup/Section.js M resources/mobile.startup/Skin.js M resources/mobile.startup/Thumbnail.js M resources/mobile.talk.overlays/TalkOverlay.js M resources/mobile.talk.overlays/TalkOverlayBase.js M resources/mobile.talk.overlays/TalkSectionAddOverlay.js M resources/mobile.talk.overlays/TalkSectionOverlay.js M resources/mobile.toc/TableOfContents.js M resources/mobile.view/View.js M resources/mobile.watchlist/WatchList.js M resources/mobile.watchstar/Watchstar.js M tests/qunit/mobile.overlays/test_Overlay.js M tests/qunit/mobile.view/test_View.js 55 files changed, 884 insertions(+), 798 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MobileFrontend refs/changes/47/265547/1 diff --git a/resources/mobile.abusefilter/AbuseFilterOverlay.js b/resources/mobile.abusefilter/AbuseFilterOverlay.js index 5bfd2cc..f649dd6 100644 --- a/resources/mobile.abusefilter/AbuseFilterOverlay.js +++ b/resources/mobile.abusefilter/AbuseFilterOverlay.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var AbuseFilterOverlay, - Button = M.require( 'mobile.startup/Button' ), + var Button = M.require( 'mobile.startup/Button' ), Overlay = M.require( 'mobile.overlays/Overlay' ); /** @@ -9,7 +8,11 @@ * @class AbuseFilterOverlay * @extends Overlay */ - AbuseFilterOverlay = Overlay.extend( { + function AbuseFilterOverlay() { + Overlay.apply( this, arguments ); + } + + OO.mfExtend( AbuseFilterOverlay, Overlay, { /** * @inheritdoc * @cfg {Object} defaults Default options hash. diff --git a/resources/mobile.abusefilter/AbuseFilterPanel.js b/resources/mobile.abusefilter/AbuseFilterPanel.js index 9fbf3b7..f66f761 100644 --- a/resources/mobile.abusefilter/AbuseFilterPanel.js +++ b/resources/mobile.abusefilter/AbuseFilterPanel.js @@ -2,8 +2,7 @@ var View = M.require( 'mobile.view/View' ), AbuseFilterOverlay = M.require( 'mobile.abusefilter/AbuseFilterOverlay' ), - overlayManager = M.require( 'mobile.startup/overlayManager' ), - AbuseFilterPanel; + overlayManager = M.require( 'mobile.startup/overlayManager' ); /** * Panel that shows an error message related to the abusefilter extension. @@ -12,7 +11,12 @@ * @uses AbuseFilterOverlay * FIXME: should extend Panel not View. Or the name should be changed to something meaningful. */ - AbuseFilterPanel = View.extend( { + function AbuseFilterPanel() { + this.isDisallowed = false; + View.apply( this, arguments ); + } + + OO.mfExtend( AbuseFilterPanel, View, { /** * @cfg {Object} defaults Default options hash. * @cfg {String} defaults.readMoreMsg A caption for the button allowing the user to read @@ -23,12 +27,6 @@ }, template: mw.template.get( 'mobile.abusefilter', 'Panel.hogan' ), className: 'panel hidden', - - /** @inheritdoc */ - initialize: function () { - View.prototype.initialize.apply( this, arguments ); - this.isDisallowed = false; - }, /** * Show the panel. Create a route to show AbuseFilterOverlay with message. diff --git a/resources/mobile.backtotop/BackToTopOverlay.js b/resources/mobile.backtotop/BackToTopOverlay.js index c39e320..40dad69 100644 --- a/resources/mobile.backtotop/BackToTopOverlay.js +++ b/resources/mobile.backtotop/BackToTopOverlay.js @@ -1,14 +1,17 @@ ( function ( M, $ ) { - var BackToTopOverlay, - View = M.require( 'mobile.view/View' ); + var View = M.require( 'mobile.view/View' ); /** * Displays a little arrow at the bottom right of the viewport. * @class BackToTopOverlay * @extends View */ - BackToTopOverlay = View.extend( { + function BackToTopOverlay() { + View.apply( this, arguments ); + } + + OO.mfExtend( BackToTopOverlay, View, { /** * @inheritdoc */ diff --git a/resources/mobile.betaoptin/BetaOptinPanel.js b/resources/mobile.betaoptin/BetaOptinPanel.js index bfafe64..2529b6f 100644 --- a/resources/mobile.betaoptin/BetaOptinPanel.js +++ b/resources/mobile.betaoptin/BetaOptinPanel.js @@ -1,14 +1,17 @@ ( function ( M, $ ) { - var BetaOptinPanel, - Button = M.require( 'mobile.startup/Button' ), + var Button = M.require( 'mobile.startup/Button' ), Panel = M.require( 'mobile.startup/Panel' ); /** * @class BetaOptinPanel * @extends Panel */ - BetaOptinPanel = Panel.extend( { + function BetaOptinPanel() { + Panel.apply( this, arguments ); + } + + OO.mfExtend( BetaOptinPanel, Panel, { className: 'panel panel-inline visible', templatePartials: $.extend( {}, Panel.prototype.templatePartials, { button: Button.prototype.template diff --git a/resources/mobile.categories.overlays/CategoryAddOverlay.js b/resources/mobile.categories.overlays/CategoryAddOverlay.js index 4b71541..316d54b 100644 --- a/resources/mobile.categories.overlays/CategoryAddOverlay.js +++ b/resources/mobile.categories.overlays/CategoryAddOverlay.js @@ -1,7 +1,6 @@ ( function ( M, $ ) { - var CategoryAddOverlay, - Overlay = M.require( 'mobile.overlays/Overlay' ), + var Overlay = M.require( 'mobile.overlays/Overlay' ), CategoryGateway = M.require( 'mobile.categories.overlays/CategoryGateway' ), CategoryLookupInputWidget = M.require( 'mobile.categories.overlays/CategoryLookupInputWidget' ), icons = M.require( 'mobile.startup/icons' ), @@ -13,7 +12,12 @@ * @extends Overlay * @uses CategoryGateway */ - CategoryAddOverlay = Overlay.extend( { + function CategoryAddOverlay( options ) { + options.heading = mw.msg( 'mobile-frontend-categories-add-heading', options.title ); + Overlay.apply( this, arguments ); + } + + OO.mfExtend( CategoryAddOverlay, Overlay, { /** * @inheritdoc * @cfg {Object} defaults Default options hash. @@ -49,14 +53,6 @@ header: mw.template.get( 'mobile.categories.overlays', 'CategoryAddOverlayHeader.hogan' ), saveHeader: mw.template.get( 'mobile.editor.common', 'saveHeader.hogan' ) } ), - - /** - * @inheritdoc - */ - initialize: function ( options ) { - options.heading = mw.msg( 'mobile-frontend-categories-add-heading', options.title ); - Overlay.prototype.initialize.apply( this, arguments ); - }, /** * @inheritdoc diff --git a/resources/mobile.categories.overlays/CategoryOverlay.js b/resources/mobile.categories.overlays/CategoryOverlay.js index 297b3c3..7a9667a 100644 --- a/resources/mobile.categories.overlays/CategoryOverlay.js +++ b/resources/mobile.categories.overlays/CategoryOverlay.js @@ -1,7 +1,6 @@ ( function ( M, $ ) { - var CategoryOverlay, - Overlay = M.require( 'mobile.overlays/Overlay' ), + var Overlay = M.require( 'mobile.overlays/Overlay' ), CategoryGateway = M.require( 'mobile.categories.overlays/CategoryGateway' ); /** @@ -10,7 +9,11 @@ * @extends Overlay * @uses CategoryGateway */ - CategoryOverlay = Overlay.extend( { + function CategoryOverlay() { + Overlay.apply( this, arguments ); + } + + OO.mfExtend( CategoryOverlay, Overlay, { /** * @inheritdoc * @cfg {Object} defaults Default options hash. diff --git a/resources/mobile.commonsCategory/CommonsCategoryOverlay.js b/resources/mobile.commonsCategory/CommonsCategoryOverlay.js index 051682d..85e9b6e 100644 --- a/resources/mobile.commonsCategory/CommonsCategoryOverlay.js +++ b/resources/mobile.commonsCategory/CommonsCategoryOverlay.js @@ -1,14 +1,17 @@ ( function ( M ) { var Overlay = M.require( 'mobile.overlays/Overlay' ), - PhotoList = M.require( 'mobile.gallery/PhotoList' ), - CommonsCategoryOverlay; + PhotoList = M.require( 'mobile.gallery/PhotoList' ); /** * Overlay for displaying page issues * @class CommonsCategoryOverlay * @extends Overlay */ - CommonsCategoryOverlay = Overlay.extend( { + function CommonsCategoryOverlay() { + Overlay.apply( this, arguments ); + } + + OO.mfExtend( CommonsCategoryOverlay, Overlay, { /** @inheritdoc */ postRender: function () { Overlay.prototype.postRender.apply( this ); diff --git a/resources/mobile.contentOverlays/PointerOverlay.js b/resources/mobile.contentOverlays/PointerOverlay.js index 0c7c8f9..a00af7f 100644 --- a/resources/mobile.contentOverlays/PointerOverlay.js +++ b/resources/mobile.contentOverlays/PointerOverlay.js @@ -1,13 +1,19 @@ ( function ( M, $ ) { - var PointerOverlay, - Overlay = M.require( 'mobile.overlays/Overlay' ); + var Overlay = M.require( 'mobile.overlays/Overlay' ); /** * Page overlay prompting a user for given action * @class PointerOverlay * @extends Overlay */ - PointerOverlay = Overlay.extend( { + function PointerOverlay( options ) { + // FIXME: This should not have a default fallback. This is a non-optional parameter. + // Remove when all existing uses in Gather have been updated. + this.appendToElement = options.appendToElement || '#mw-mf-page-center'; + Overlay.apply( this, arguments ); + } + + OO.mfExtend( PointerOverlay, Overlay, { className: 'overlay pointer-overlay tutorial-overlay', /** * @inheritdoc @@ -42,15 +48,6 @@ alignment: 'center', confirmMsg: undefined } ), - /** - * @inheritdoc - */ - initialize: function ( options ) { - // FIXME: This should not have a default fallback. This is a non-optional parameter. - // Remove when all existing uses in Gather have been updated. - this.appendToElement = options.appendToElement || '#mw-mf-page-center'; - Overlay.prototype.initialize.apply( this, arguments ); - }, /** * @inheritdoc */ diff --git a/resources/mobile.drawers/CtaDrawer.js b/resources/mobile.drawers/CtaDrawer.js index 76447e3..b57f80c 100644 --- a/resources/mobile.drawers/CtaDrawer.js +++ b/resources/mobile.drawers/CtaDrawer.js @@ -2,8 +2,7 @@ var Drawer = M.require( 'mobile.drawers/Drawer' ), Icon = M.require( 'mobile.startup/Icon' ), Button = M.require( 'mobile.startup/Button' ), - Anchor = M.require( 'mobile.startup/Anchor' ), - CtaDrawer; + Anchor = M.require( 'mobile.startup/Anchor' ); /** * This creates the drawer at the bottom of the screen that appears when an anonymous @@ -15,7 +14,11 @@ * @uses Icon * @uses Anchor */ - CtaDrawer = Drawer.extend( { + function CtaDrawer() { + Drawer.apply( this, arguments ); + } + + OO.mfExtend( CtaDrawer, Drawer, { /** * @cfg {Object} defaults Default options hash. * @cfg {Object} defaults.collapseIcon options for Icon for collapsing the drawer diff --git a/resources/mobile.drawers/Drawer.js b/resources/mobile.drawers/Drawer.js index 09c1790..f6eab4e 100644 --- a/resources/mobile.drawers/Drawer.js +++ b/resources/mobile.drawers/Drawer.js @@ -1,15 +1,18 @@ ( function ( M, $ ) { var Panel = M.require( 'mobile.startup/Panel' ), - Icon = M.require( 'mobile.startup/Icon' ), - Drawer; + Icon = M.require( 'mobile.startup/Icon' ); /** * A {@link View} that pops up from the bottom of the screen. * @class Drawer * @extends Panel */ - Drawer = Panel.extend( { + function Drawer() { + Panel.apply( this, arguments ); + } + + OO.mfExtend( Drawer, Panel, { /** * @inheritdoc * @cfg {Object} defaults Default options hash. diff --git a/resources/mobile.editor.common/EditorOverlayBase.js b/resources/mobile.editor.common/EditorOverlayBase.js index a71f02b..4ed104d 100644 --- a/resources/mobile.editor.common/EditorOverlayBase.js +++ b/resources/mobile.editor.common/EditorOverlayBase.js @@ -4,8 +4,7 @@ browser = M.require( 'mobile.browser/browser' ), Icon = M.require( 'mobile.startup/Icon' ), toast = M.require( 'mobile.toast/toast' ), - user = M.require( 'mobile.user/user' ), - EditorOverlayBase; + user = M.require( 'mobile.user/user' ); /** * 'Edit' button @@ -44,7 +43,41 @@ * @uses Icon * @uses user */ - EditorOverlayBase = Overlay.extend( { + function EditorOverlayBase( options ) { + var self = this; + + if ( options.isNewPage ) { + options.placeholder = mw.msg( 'mobile-frontend-editor-placeholder-new-page', mw.user ); + } + // change the message to request a summary when not in article namespace + if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 ) { + options.summaryRequestMsg = mw.msg( 'mobile-frontend-editor-summary' ); + } + this.pageGateway = new PageGateway( options.api ); + this.editCount = user.getEditCount(); + this.isNewPage = options.isNewPage; + this.isNewEditor = options.isNewEditor; + this.sectionId = options.sectionId; + this.schema = options.editSchema; + this.config = mw.config.get( 'wgMFEditorOptions' ); + this.sessionId = options.sessionId; + this.allowCloseWindow = mw.confirmCloseWindow( { + /** Returns true, if content has changed, otherwise false */ + test: function () { + // Check if content has changed + return self.hasChanged(); + }, + + /** Message to show the user, if content has changed */ + message: mw.msg( 'mobile-frontend-editor-cancel-confirm' ), + /** Event namespace */ + namespace: 'editwarning' + } ); + + Overlay.apply( this, arguments ); + } + + OO.mfExtend( EditorOverlayBase, Overlay, { /** * @inheritdoc * @cfg {Object} defaults Default options hash. @@ -173,40 +206,6 @@ $.cookie( 'mobileEditor', 'true', { expires: 30 } ); - }, - /** @inheritdoc **/ - initialize: function ( options ) { - var self = this; - - if ( options.isNewPage ) { - options.placeholder = mw.msg( 'mobile-frontend-editor-placeholder-new-page', mw.user ); - } - // change the message to request a summary when not in article namespace - if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 ) { - options.summaryRequestMsg = mw.msg( 'mobile-frontend-editor-summary' ); - } - this.pageGateway = new PageGateway( options.api ); - this.editCount = user.getEditCount(); - this.isNewPage = options.isNewPage; - this.isNewEditor = options.isNewEditor; - this.sectionId = options.sectionId; - this.schema = options.editSchema; - this.config = mw.config.get( 'wgMFEditorOptions' ); - this.sessionId = options.sessionId; - this.allowCloseWindow = mw.confirmCloseWindow( { - /** Returns true, if content has changed, otherwise false */ - test: function () { - // Check if content has changed - return self.hasChanged(); - }, - - /** Message to show the user, if content has changed */ - message: mw.msg( 'mobile-frontend-editor-cancel-confirm' ), - /** Event namespace */ - namespace: 'editwarning' - } ); - - Overlay.prototype.initialize.apply( this, arguments ); }, /** * Report load errors back to the user. Silently record the error using EventLogging. diff --git a/resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js b/resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js index 030a955..dd1a41b 100644 --- a/resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js +++ b/resources/mobile.editor.overlay.withtoolbar/AddReferenceOverlay.js @@ -1,13 +1,16 @@ ( function ( M, $ ) { - var AddReferenceOverlay, - Overlay = M.require( 'mobile.overlays/Overlay' ); + var Overlay = M.require( 'mobile.overlays/Overlay' ); /** * Overlay that shows an editor * @class AddReferenceOverlay * @extends Overlay */ - AddReferenceOverlay = Overlay.extend( { + function AddReferenceOverlay() { + Overlay.apply( this, arguments ); + } + + OO.mfExtend( AddReferenceOverlay, Overlay, { /** * @inheritdoc * @cfg {Object} defaults Default options hash. diff --git a/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js b/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js index 612bfce..6cfc547 100644 --- a/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js +++ b/resources/mobile.editor.overlay.withtoolbar/EditorOverlayWithToolbar.js @@ -1,14 +1,17 @@ ( function ( M, $ ) { var EditorOverlay = M.require( 'mobile.editor.overlay/EditorOverlay' ), - AddReferenceOverlay = M.require( 'mobile.editor.overlay.withtoolbar/AddReferenceOverlay' ), - EditorOverlayWithToolbar; + AddReferenceOverlay = M.require( 'mobile.editor.overlay.withtoolbar/AddReferenceOverlay' ); /** * Overlay that shows an editor * @class EditorOverlayWithToolbar * @extends EditorOverlay */ - EditorOverlayWithToolbar = EditorOverlay.extend( { + function EditorOverlayWithToolbar() { + EditorOverlay.apply( this, arguments ); + } + + OO.mfExtend( EditorOverlayWithToolbar, EditorOverlay, { templatePartials: $.extend( {}, EditorOverlay.prototype.templatePartials, { footer: mw.template.get( 'mobile.editor.overlay.withtoolbar', 'editorFooter.hogan' ) } ), diff --git a/resources/mobile.editor.overlay/EditorOverlay.js b/resources/mobile.editor.overlay/EditorOverlay.js index 7be9a82..7e200d7 100644 --- a/resources/mobile.editor.overlay/EditorOverlay.js +++ b/resources/mobile.editor.overlay/EditorOverlay.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var EditorOverlay, - EditorOverlayBase = M.require( 'mobile.editor.common/EditorOverlayBase' ), + var EditorOverlayBase = M.require( 'mobile.editor.common/EditorOverlayBase' ), Section = M.require( 'mobile.startup/Section' ), EditorGateway = M.require( 'mobile.editor.api/EditorGateway' ), AbuseFilterPanel = M.require( 'mobile.abusefilter/AbuseFilterPanel' ), @@ -19,7 +18,35 @@ * @uses VisualEditorOverlay * @extends EditorOverlayBase */ - EditorOverlay = EditorOverlayBase.extend( { + function EditorOverlay( options ) { + this.gateway = new EditorGateway( { + api: options.api, + title: options.title, + sectionId: options.sectionId, + oldId: options.oldId, + isNewPage: options.isNewPage + } ); + this.readOnly = options.oldId ? true : false; // If old revision, readOnly mode + if ( this.isVisualEditorEnabled() ) { + options.editSwitcher = true; + } + if ( this.readOnly ) { + options.readOnly = true; + options.editingMsg = mw.msg( 'mobile-frontend-editor-viewing-source-page', options.title ); + } else { + options.editingMsg = mw.msg( 'mobile-frontend-editor-editing-page', options.title ); + } + if ( options.isAnon ) { + // add required data for anonymous editing warning + options = this._prepareAnonWarning( options ); + } + // be explicit here. This may have been initialized from VE. + options.isVisualEditor = false; + options.previewingMsg = mw.msg( 'mobile-frontend-editor-previewing-page', options.title ); + EditorOverlayBase.call( this, options ); + } + + OO.mfExtend( EditorOverlay, EditorOverlayBase, { /** @inheritdoc **/ isBorderBox: false, /** @inheritdoc **/ @@ -70,35 +97,6 @@ $.inArray( mw.config.get( 'wgNamespaceNumber' ), mw.config.get( 'wgVisualEditorConfig' ).namespaces ) > -1 && mw.config.get( 'wgTranslatePageTranslation' ) !== 'translation' && mw.config.get( 'wgPageContentModel' ) === 'wikitext'; - }, - - /** @inheritdoc **/ - initialize: function ( options ) { - this.gateway = new EditorGateway( { - api: options.api, - title: options.title, - sectionId: options.sectionId, - oldId: options.oldId, - isNewPage: options.isNewPage - } ); - this.readOnly = options.oldId ? true : false; // If old revision, readOnly mode - if ( this.isVisualEditorEnabled() ) { - options.editSwitcher = true; - } - if ( this.readOnly ) { - options.readOnly = true; - options.editingMsg = mw.msg( 'mobile-frontend-editor-viewing-source-page', options.title ); - } else { - options.editingMsg = mw.msg( 'mobile-frontend-editor-editing-page', options.title ); - } - if ( options.isAnon ) { - // add required data for anonymous editing warning - options = this._prepareAnonWarning( options ); - } - // be explicit here. This may have been initialized from VE. - options.isVisualEditor = false; - options.previewingMsg = mw.msg( 'mobile-frontend-editor-previewing-page', options.title ); - EditorOverlayBase.prototype.initialize.call( this, options ); }, events: $.extend( {}, EditorOverlayBase.prototype.events, { 'input .wikitext-editor': 'onInputWikitextEditor' diff --git a/resources/mobile.editor.ve/VisualEditorOverlay.js b/resources/mobile.editor.ve/VisualEditorOverlay.js index df072ce..e8a80ea 100644 --- a/resources/mobile.editor.ve/VisualEditorOverlay.js +++ b/resources/mobile.editor.ve/VisualEditorOverlay.js @@ -1,15 +1,20 @@ ( function ( M, $, ve ) { var EditorOverlayBase = M.require( 'mobile.editor.common/EditorOverlayBase' ), settings = M.require( 'mobile.settings/settings' ), - overlayManager = M.require( 'mobile.startup/overlayManager' ), - VisualEditorOverlay; + overlayManager = M.require( 'mobile.startup/overlayManager' ); /** * Overlay for VisualEditor view * @class VisualEditorOverlay * @extends EditorOverlayBase */ - VisualEditorOverlay = EditorOverlayBase.extend( { + function VisualEditorOverlay( options ) { + this.applyHeaderOptions( options, true ); + EditorOverlayBase.apply( this, arguments ); + this.isNewPage = options.isNewPage; + } + + OO.mfExtend( VisualEditorOverlay, EditorOverlayBase, { /** @inheritdoc **/ isBorderBox: false, /** @inheritdoc **/ @@ -33,12 +38,6 @@ // Set things that are known to be true. options.hasToolbar = isVE; options.isVisualEditor = isVE; - }, - /** @inheritdoc **/ - initialize: function ( options ) { - this.applyHeaderOptions( options, true ); - EditorOverlayBase.prototype.initialize.apply( this, arguments ); - this.isNewPage = options.isNewPage; }, /** * Destroy the existing VisualEditor target. diff --git a/resources/mobile.fontchanger/FontChanger.js b/resources/mobile.fontchanger/FontChanger.js index dff22d2..4226df4 100644 --- a/resources/mobile.fontchanger/FontChanger.js +++ b/resources/mobile.fontchanger/FontChanger.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var FontChanger, - View = M.require( 'mobile.view/View' ), + var View = M.require( 'mobile.view/View' ), Button = M.require( 'mobile.startup/Button' ), settings = M.require( 'mobile.settings/settings' ); @@ -9,7 +8,11 @@ * @class FontChanger * @extends View */ - FontChanger = View.extend( { + function FontChanger() { + View.apply( this, arguments ); + } + + OO.mfExtend( FontChanger, View, { /** * @cfg {Object} defaults Default options hash. * @cfg {Object} defaults.viewLink Anchor options for a link to wikidata page. diff --git a/resources/mobile.gallery/PhotoItem.js b/resources/mobile.gallery/PhotoItem.js index 0cae5ef..abd84b5 100644 --- a/resources/mobile.gallery/PhotoItem.js +++ b/resources/mobile.gallery/PhotoItem.js @@ -1,13 +1,16 @@ ( function ( M ) { - var PhotoItem, - View = M.require( 'mobile.view/View' ); + var View = M.require( 'mobile.view/View' ); /** * Single photo item in gallery * @class PhotoItem * @extends View */ - PhotoItem = View.extend( { + function PhotoItem() { + View.apply( this, arguments ); + } + + OO.mfExtend( PhotoItem, View, { template: mw.template.get( 'mobile.gallery', 'PhotoItem.hogan' ), tagName: 'li' } ); diff --git a/resources/mobile.gallery/PhotoList.js b/resources/mobile.gallery/PhotoList.js index ddaa692..6bae624 100644 --- a/resources/mobile.gallery/PhotoList.js +++ b/resources/mobile.gallery/PhotoList.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var PhotoList, - icons = M.require( 'mobile.startup/icons' ), + var icons = M.require( 'mobile.startup/icons' ), PhotoListGateway = M.require( 'mobile.gallery/PhotoListGateway' ), PhotoItem = M.require( 'mobile.gallery/PhotoItem' ), InfiniteScroll = M.require( 'mobile.infiniteScroll/InfiniteScroll' ), @@ -14,7 +13,24 @@ * @uses InfiniteScroll * @extends View */ - PhotoList = View.extend( { + function PhotoList( options ) { + var gatewayOptions = { + api: options.api + }; + + if ( options.username ) { + gatewayOptions.username = options.username; + } else if ( options.category ) { + gatewayOptions.category = options.category; + } + this.gateway = new PhotoListGateway( gatewayOptions ); + // Set up infinite scroll + this.infiniteScroll = new InfiniteScroll( 1000 ); + this.infiniteScroll.on( 'load', $.proxy( this, '_loadPhotos' ) ); + View.call( this, options ); + } + + OO.mfExtend( PhotoList, View, { template: mw.template.get( 'mobile.gallery', 'PhotoList.hogan' ), /** * @cfg {Object} defaults Default options hash. @@ -23,23 +39,6 @@ */ defaults: { spinner: icons.spinner().toHtmlString() - }, - /** @inheritdoc */ - initialize: function ( options ) { - var gatewayOptions = { - api: options.api - }; - - if ( options.username ) { - gatewayOptions.username = options.username; - } else if ( options.category ) { - gatewayOptions.category = options.category; - } - this.gateway = new PhotoListGateway( gatewayOptions ); - // Set up infinite scroll - this.infiniteScroll = new InfiniteScroll( 1000 ); - this.infiniteScroll.on( 'load', $.proxy( this, '_loadPhotos' ) ); - View.prototype.initialize.apply( this, arguments ); }, /** @inheritdoc */ preRender: function () { diff --git a/resources/mobile.issues/CleanupOverlay.js b/resources/mobile.issues/CleanupOverlay.js index 798d40e..dbc6d82 100644 --- a/resources/mobile.issues/CleanupOverlay.js +++ b/resources/mobile.issues/CleanupOverlay.js @@ -5,15 +5,19 @@ name: 'cleanup-gray', additionalClassNames: 'issue-notice', hasText: true - } ), - CleanupOverlay; + } ); /** * Overlay for displaying page issues * @class CleanupOverlay * @extends Overlay */ - CleanupOverlay = Overlay.extend( { + function CleanupOverlay( options ) { + options.heading = '<strong>' + options.headingText + '</strong>'; + Overlay.call( this, options ); + } + + OO.mfExtend( CleanupOverlay, Overlay, { templatePartials: $.extend( {}, Overlay.prototype.templatePartials, { content: mw.template.get( 'mobile.issues', 'OverlayContent.hogan' ) } ), @@ -24,12 +28,7 @@ */ defaults: $.extend( {}, Overlay.prototype.defaults, { className: icon.getClassName() - } ), - /** @inheritdoc */ - initialize: function ( options ) { - options.heading = '<strong>' + options.headingText + '</strong>'; - Overlay.prototype.initialize.call( this, options ); - } + } ) } ); M.define( 'mobile.issues/CleanupOverlay', CleanupOverlay ); }( mw.mobileFrontend, jQuery ) ); diff --git a/resources/mobile.languages/LanguageOverlay.js b/resources/mobile.languages/LanguageOverlay.js index 588a7ab..a929b3d 100644 --- a/resources/mobile.languages/LanguageOverlay.js +++ b/resources/mobile.languages/LanguageOverlay.js @@ -1,15 +1,32 @@ ( function ( M, $ ) { var Overlay = M.require( 'mobile.overlays/Overlay' ), - settings = M.require( 'mobile.settings/settings' ), - LanguageOverlay; + settings = M.require( 'mobile.settings/settings' ); /** * Overlay displaying list of languages for a page * @class LanguageOverlay * @extends Overlay */ - LanguageOverlay = Overlay.extend( { + function LanguageOverlay( options ) { + var langMap; + + if ( options.languages && options.languages.length ) { + options.header = mw.msg( 'mobile-frontend-language-header', options.languages.length ); + } + if ( options.variants && options.variants.length ) { + options.variantHeader = mw.msg( 'mobile-frontend-language-variant-header' ); + } + langMap = settings.get( 'langMap' ); + this.languageMap = langMap ? $.parseJSON( langMap ) : {}; + if ( options.currentLanguage ) { + this.trackLanguage( options.currentLanguage ); + } + options = this._sortLanguages( options ); + Overlay.apply( this, arguments ); + } + + OO.mfExtend( LanguageOverlay, Overlay, { /** * @inheritdoc * @cfg {Object} defaults Default options hash. @@ -38,25 +55,6 @@ 'click ul a': 'onLinkClick', 'input .search': 'onSearchInput' } ), - - /** @inheritdoc */ - initialize: function ( options ) { - var langMap; - - if ( options.languages && options.languages.length ) { - options.header = mw.msg( 'mobile-frontend-language-header', options.languages.length ); - } - if ( options.variants && options.variants.length ) { - options.variantHeader = mw.msg( 'mobile-frontend-language-variant-header' ); - } - langMap = settings.get( 'langMap' ); - this.languageMap = langMap ? $.parseJSON( langMap ) : {}; - if ( options.currentLanguage ) { - this.trackLanguage( options.currentLanguage ); - } - options = this._sortLanguages( options ); - Overlay.prototype.initialize.apply( this, arguments ); - }, /** * Sorts the provided languages based on previous usage and tags them * with a property preferred for template usage diff --git a/resources/mobile.loggingSchemas/SchemaEdit.js b/resources/mobile.loggingSchemas/SchemaEdit.js index 9f79b6b..e632e40 100644 --- a/resources/mobile.loggingSchemas/SchemaEdit.js +++ b/resources/mobile.loggingSchemas/SchemaEdit.js @@ -1,13 +1,16 @@ ( function ( M, $ ) { - var SchemaEdit, - Schema = M.require( 'mobile.startup/Schema' ), + var Schema = M.require( 'mobile.startup/Schema' ), user = M.require( 'mobile.user/user' ); /** * @class SchemaEdit * @extends Schema */ - SchemaEdit = Schema.extend( { + function SchemaEdit() { + Schema.apply( this, arguments ); + } + + OO.mfExtend( SchemaEdit, Schema, { /** @inheritdoc **/ name: 'Edit', /** diff --git a/resources/mobile.loggingSchemas/SchemaMobileWebSectionUsage.js b/resources/mobile.loggingSchemas/SchemaMobileWebSectionUsage.js index 14235da..b934d2a 100644 --- a/resources/mobile.loggingSchemas/SchemaMobileWebSectionUsage.js +++ b/resources/mobile.loggingSchemas/SchemaMobileWebSectionUsage.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var SchemaMobileWebSectionUsage, - Schema = M.require( 'mobile.startup/Schema' ), + var Schema = M.require( 'mobile.startup/Schema' ), user = M.require( 'mobile.user/user' ), browser = M.require( 'mobile.browser/browser' ), experiments = mw.config.get( 'wgMFExperiments' ); @@ -9,7 +8,11 @@ * @class SchemaMobileWebSectionUsage * @extends Schema */ - SchemaMobileWebSectionUsage = Schema.extend( { + function SchemaMobileWebSectionUsage() { + Schema.apply( this, arguments ); + } + + OO.mfExtend( SchemaMobileWebSectionUsage, Schema, { /** * @inheritdoc */ diff --git a/resources/mobile.mainMenu/MainMenu.js b/resources/mobile.mainMenu/MainMenu.js index c31a2f9..15d6de4 100644 --- a/resources/mobile.mainMenu/MainMenu.js +++ b/resources/mobile.mainMenu/MainMenu.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var MainMenu, - browser = M.require( 'mobile.browser/browser' ), + var browser = M.require( 'mobile.browser/browser' ), View = M.require( 'mobile.view/View' ); /** @@ -9,7 +8,12 @@ * @class MainMenu * @extends View */ - MainMenu = View.extend( { + function MainMenu( options ) { + this.activator = options.activator; + View.call( this, options ); + } + + OO.mfExtend( MainMenu, View, { /** @inheritdoc */ isTemplateMode: true, /** @inheritdoc */ @@ -61,13 +65,6 @@ } ); } ); return d; - }, - - /** @inheritdoc **/ - initialize: function ( options ) { - - this.activator = options.activator; - View.prototype.initialize.call( this, options ); }, /** diff --git a/resources/mobile.mediaViewer.beta/ImageOverlayBeta.js b/resources/mobile.mediaViewer.beta/ImageOverlayBeta.js index 4992d84..b1ba8b6 100644 --- a/resources/mobile.mediaViewer.beta/ImageOverlayBeta.js +++ b/resources/mobile.mediaViewer.beta/ImageOverlayBeta.js @@ -1,14 +1,17 @@ ( function ( M, $ ) { var ImageOverlay = M.require( 'mobile.mediaViewer/ImageOverlay' ), - Swipe = M.require( 'mobile.swipe/Swipe' ), - ImageOverlayBeta; + Swipe = M.require( 'mobile.swipe/Swipe' ); /** * Extends ImageOverlay to add a swipe functionality * @class ImageOverlayBeta * @extends ImageOverlay */ - ImageOverlayBeta = ImageOverlay.extend( { + function ImageOverlayBeta() { + ImageOverlay.apply( this, arguments ); + } + + OO.mfExtend( ImageOverlayBeta, ImageOverlay, { /** @inheritdoc */ _enableArrowImages: function ( thumbs ) { var self = this; diff --git a/resources/mobile.mediaViewer/ImageOverlay.js b/resources/mobile.mediaViewer/ImageOverlay.js index 70caa30..70f7a01 100644 --- a/resources/mobile.mediaViewer/ImageOverlay.js +++ b/resources/mobile.mediaViewer/ImageOverlay.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var ImageOverlay, - Overlay = M.require( 'mobile.overlays/Overlay' ), + var Overlay = M.require( 'mobile.overlays/Overlay' ), Icon = M.require( 'mobile.startup/Icon' ), Button = M.require( 'mobile.startup/Button' ), ImageGateway = M.require( 'mobile.mediaViewer/ImageGateway' ); @@ -12,7 +11,14 @@ * @uses Icon * @uses ImageGateway */ - ImageOverlay = Overlay.extend( { + function ImageOverlay( options ) { + this.gateway = new ImageGateway( { + api: options.api + } ); + Overlay.apply( this, arguments ); + } + + OO.mfExtend( ImageOverlay, Overlay, { // allow pinch zooming hasFixedHeader: false, className: 'overlay media-viewer', @@ -56,14 +62,6 @@ // Click tracking for table of contents so we can see if people interact with it 'click .slider-button': 'onSlide' } ), - - /** @inheritdoc */ - initialize: function ( options ) { - this.gateway = new ImageGateway( { - api: options.api - } ); - Overlay.prototype.initialize.apply( this, arguments ); - }, /** * Event handler for slide event * @param {jQuery.Event} ev diff --git a/resources/mobile.messageBox/MessageBox.js b/resources/mobile.messageBox/MessageBox.js index 0864a3f..2ed00e0 100644 --- a/resources/mobile.messageBox/MessageBox.js +++ b/resources/mobile.messageBox/MessageBox.js @@ -1,12 +1,15 @@ ( function ( M ) { - var MessageBox, - View = M.require( 'mobile.view/View' ); + var View = M.require( 'mobile.view/View' ); /** * @class MessageBox * @extends View */ - MessageBox = View.extend( { + function MessageBox() { + View.apply( this, arguments ); + } + + OO.mfExtend( MessageBox, View, { /** @inheritdoc */ isTemplateMode: true, /** diff --git a/resources/mobile.nearby/Nearby.js b/resources/mobile.nearby/Nearby.js index 76b2dac..e420251 100644 --- a/resources/mobile.nearby/Nearby.js +++ b/resources/mobile.nearby/Nearby.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var Nearby, - MessageBox = M.require( 'mobile.messageBox/MessageBox' ), + var MessageBox = M.require( 'mobile.messageBox/MessageBox' ), NearbyGateway = M.require( 'mobile.nearby/NearbyGateway' ), WatchstarPageList = M.require( 'mobile.pagelist.scripts/WatchstarPageList' ), browser = M.require( 'mobile.browser/browser' ), @@ -8,12 +7,58 @@ /** * List of nearby pages - * @class Nearby * @uses NearbyGateway * @extends WatchstarPageList */ - Nearby = WatchstarPageList.extend( { + function Nearby( options ) { + var self = this, + _super = WatchstarPageList; + + this.range = options.range || mw.config.get( 'wgMFNearbyRange' ) || 1000; + this.source = options.source || 'nearby'; + this.nearbyApi = new NearbyGateway( { + api: options.api + } ); + + if ( options.errorType ) { + options.errorOptions = self._errorOptions( options.errorType ); + } + + // Re-run after api/geolocation request + if ( options.useCurrentLocation ) { + // Flush any existing list of pages + options.pages = []; + + // Get some new pages + this.getCurrentPosition().done( function ( coordOptions ) { + $.extend( options, coordOptions ); + self._find( options ).done( function ( options ) { + _super.call( self, options ); + } ); + } ).fail( function ( errorType ) { + options.errorType = errorType; + _super.call( self, options ); + } ); + } else if ( ( options.latitude && options.longitude ) || options.pageTitle ) { + // Flush any existing list of pages + options.pages = []; + + // Get some new pages + this._find( options ).done( function ( options ) { + _super.call( self, options ); + } ).fail( function ( errorType ) { + options.errorType = errorType; + _super.call( self, options ); + } ); + } + + // Run it once for loader etc + this._isLoading = true; + _super.apply( this, arguments ); + } + + OO.mfExtend( Nearby, WatchstarPageList, { errorMessages: { empty: { heading: mw.msg( 'mobile-frontend-nearby-noresults' ), @@ -89,56 +134,6 @@ result.reject( 'incompatible' ); } return result; - }, - /** - * Get pages within a nearby range of current location - * @inheritdoc - */ - initialize: function ( options ) { - var self = this, - _super = WatchstarPageList.prototype.initialize; - - this.range = options.range || mw.config.get( 'wgMFNearbyRange' ) || 1000; - this.source = options.source || 'nearby'; - this.nearbyApi = new NearbyGateway( { - api: options.api - } ); - - if ( options.errorType ) { - options.errorOptions = self._errorOptions( options.errorType ); - } - - // Re-run after api/geolocation request - if ( options.useCurrentLocation ) { - // Flush any existing list of pages - options.pages = []; - - // Get some new pages - this.getCurrentPosition().done( function ( coordOptions ) { - $.extend( options, coordOptions ); - self._find( options ).done( function ( options ) { - _super.call( self, options ); - } ); - } ).fail( function ( errorType ) { - options.errorType = errorType; - _super.call( self, options ); - } ); - } else if ( ( options.latitude && options.longitude ) || options.pageTitle ) { - // Flush any existing list of pages - options.pages = []; - - // Get some new pages - this._find( options ).done( function ( options ) { - _super.call( self, options ); - } ).fail( function ( errorType ) { - options.errorType = errorType; - _super.call( self, options ); - } ); - } - - // Run it once for loader etc - this._isLoading = true; - _super.apply( this, arguments ); }, /** * Request pages from api based on provided options. diff --git a/resources/mobile.notifications.overlay/NotificationsOverlay.js b/resources/mobile.notifications.overlay/NotificationsOverlay.js index e03187b..7078083 100644 --- a/resources/mobile.notifications.overlay/NotificationsOverlay.js +++ b/resources/mobile.notifications.overlay/NotificationsOverlay.js @@ -1,8 +1,7 @@ ( function ( M, $ ) { var Overlay = M.require( 'mobile.overlays/Overlay' ), api = new mw.Api(), - Anchor = M.require( 'mobile.startup/Anchor' ), - NotificationsOverlay; + Anchor = M.require( 'mobile.startup/Anchor' ); /** * Overlay for notifications @@ -10,7 +9,87 @@ * @extend Overlay * @uses mw.Api */ - NotificationsOverlay = Overlay.extend( { + function NotificationsOverlay( options ) { + var self = this; + Overlay.apply( this, options ); + // Anchor tag that corresponds to a notifications badge + this.$badge = options.$badge; + // On error use the url as a fallback + if ( options.error ) { + this.onError(); + } else { + // FIXME: Move to NotificationApi class + api.get( { + action: 'query', + meta: 'notifications', + notformat: 'flyout', + notprop: 'index|list|count', + uselang: 'user' + } ).done( function ( result ) { + var notifications; + if ( result.query && result.query.notifications ) { + notifications = $.map( result.query.notifications.list, function ( a ) { + return { + message: a['*'], + timestamp: a.timestamp.mw, + unread: ( a.hasOwnProperty( 'read' ) ? 'mw-echo-notification-read' : 'mw-echo-notification-unread' ) + }; + } ).sort( function ( a, b ) { + return a.timestamp < b.timestamp ? 1 : -1; + } ); + if ( notifications.length ) { + options.notifications = notifications; + } else { + options.errorMessage = mw.msg( 'echo-none' ); + } + + self.render( options ); + self.$( '.mw-echo-notification' ).each( function () { + var $notification = $( this ), + $primaryLink = $notification.find( '.mw-echo-notification-primary-link' ), + eventId = $notification.attr( 'data-notification-event' ), + eventType = $notification.attr( 'data-notification-type' ); + + // If there is a primary link, make the entire notification clickable. + if ( $primaryLink.length ) { + $notification.addClass( 'mw-echo-linked-notification' ); + $notification.on( 'click', function () { + mw.echo.logger.logInteraction( + mw.echo.Logger.static.actions.notificationClick, + 'mobile-overlay', + eventId, + eventType, + true + ); + window.location.href = $primaryLink.attr( 'href' ); + } ); + } + // Log notification impression + mw.echo.logger.logInteraction( + mw.echo.Logger.static.actions.notificationImpression, + 'mobile-overlay', + eventId, + eventType, + true + ); + } ); + // Only fire 'mark as read' API call when unread notification + // count is not zero. Question: why does this fire an API call + // for 'mark all as read', the overlay may not load all unread + // notifications + if ( result.query.notifications.rawcount !== 0 ) { + self.markAllAsRead(); + } + } else { + self.onError(); + } + } ).fail( function () { + self.onError(); + } ); + } + } + + OO.mfExtend( NotificationsOverlay, Overlay, { className: 'overlay notifications-overlay navigation-drawer', templatePartials: $.extend( {}, Overlay.prototype.templatePartials, { content: mw.template.get( 'mobile.notifications.overlay', 'content.hogan' ) @@ -42,86 +121,6 @@ */ markAsRead: function () { this.$badge.find( '.notification-count' ).remove(); - }, - /** @inheritdoc */ - initialize: function ( options ) { - var self = this; - Overlay.prototype.initialize.apply( this, options ); - // Anchor tag that corresponds to a notifications badge - this.$badge = options.$badge; - // On error use the url as a fallback - if ( options.error ) { - this.onError(); - } else { - // FIXME: Move to NotificationApi class - api.get( { - action: 'query', - meta: 'notifications', - notformat: 'flyout', - notprop: 'index|list|count', - uselang: 'user' - } ).done( function ( result ) { - var notifications; - if ( result.query && result.query.notifications ) { - notifications = $.map( result.query.notifications.list, function ( a ) { - return { - message: a['*'], - timestamp: a.timestamp.mw, - unread: ( a.hasOwnProperty( 'read' ) ? 'mw-echo-notification-read' : 'mw-echo-notification-unread' ) - }; - } ).sort( function ( a, b ) { - return a.timestamp < b.timestamp ? 1 : -1; - } ); - if ( notifications.length ) { - options.notifications = notifications; - } else { - options.errorMessage = mw.msg( 'echo-none' ); - } - - self.render( options ); - self.$( '.mw-echo-notification' ).each( function () { - var $notification = $( this ), - $primaryLink = $notification.find( '.mw-echo-notification-primary-link' ), - eventId = $notification.attr( 'data-notification-event' ), - eventType = $notification.attr( 'data-notification-type' ); - - // If there is a primary link, make the entire notification clickable. - if ( $primaryLink.length ) { - $notification.addClass( 'mw-echo-linked-notification' ); - $notification.on( 'click', function () { - mw.echo.logger.logInteraction( - mw.echo.Logger.static.actions.notificationClick, - 'mobile-overlay', - eventId, - eventType, - true - ); - window.location.href = $primaryLink.attr( 'href' ); - } ); - } - // Log notification impression - mw.echo.logger.logInteraction( - mw.echo.Logger.static.actions.notificationImpression, - 'mobile-overlay', - eventId, - eventType, - true - ); - } ); - // Only fire 'mark as read' API call when unread notification - // count is not zero. Question: why does this fire an API call - // for 'mark all as read', the overlay may not load all unread - // notifications - if ( result.query.notifications.rawcount !== 0 ) { - self.markAllAsRead(); - } - } else { - self.onError(); - } - } ).fail( function () { - self.onError(); - } ); - } }, /** * Mark notifications as read in the server. Make an API request. diff --git a/resources/mobile.overlays/ContentOverlay.js b/resources/mobile.overlays/ContentOverlay.js index eb90519..b09c0ce 100644 --- a/resources/mobile.overlays/ContentOverlay.js +++ b/resources/mobile.overlays/ContentOverlay.js @@ -1,7 +1,6 @@ ( function ( M ) { - var ContentOverlay, - mContentOverlay, + var mContentOverlay, Overlay = M.require( 'mobile.overlays/Overlay' ); /** @@ -10,7 +9,11 @@ * @class ContentOverlay * @extends Overlay */ - ContentOverlay = Overlay.extend( { + function ContentOverlay() { + ContentOverlay.apply( this, arguments ); + } + + OO.mfExtend( ContentOverlay, Overlay, { /** @inheritdoc */ templatePartials: {}, className: 'overlay content-overlay', diff --git a/resources/mobile.overlays/LoadingOverlay.js b/resources/mobile.overlays/LoadingOverlay.js index bfc9ac9..12ae158 100644 --- a/resources/mobile.overlays/LoadingOverlay.js +++ b/resources/mobile.overlays/LoadingOverlay.js @@ -1,14 +1,17 @@ ( function ( M ) { - var LoadingOverlay, - Overlay = M.require( 'mobile.overlays/Overlay' ); + var Overlay = M.require( 'mobile.overlays/Overlay' ); /** * Overlay that initially shows loading animation until - ** caller hides it with .hide() + * caller hides it with .hide() * @class LoadingOverlay * @extends Overlay */ - LoadingOverlay = Overlay.extend( { + function LoadingOverlay() { + Overlay.apply( this, arguments ); + } + + OO.mfExtend( LoadingOverlay, Overlay, { template: mw.template.get( 'mobile.overlays', 'LoadingOverlay.hogan' ) } ); diff --git a/resources/mobile.overlays/Overlay.js b/resources/mobile.overlays/Overlay.js index d1c008e..6822f21 100644 --- a/resources/mobile.overlays/Overlay.js +++ b/resources/mobile.overlays/Overlay.js @@ -1,15 +1,13 @@ /*jshint unused:vars */ ( function ( M, $ ) { - var - View = M.require( 'mobile.view/View' ), + var View = M.require( 'mobile.view/View' ), Icon = M.require( 'mobile.startup/Icon' ), Button = M.require( 'mobile.startup/Button' ), Anchor = M.require( 'mobile.startup/Anchor' ), icons = M.require( 'mobile.startup/icons' ), browser = M.require( 'mobile.browser/browser' ), - $window = $( window ), - Overlay; + $window = $( window ); /** * Mobile modal window @@ -18,7 +16,18 @@ * @uses Icon * @uses Button */ - Overlay = View.extend( { + function Overlay() { + this.isIos = browser.isIos(); + this.isIos8 = browser.isIos( 8 ); + // https://phabricator.wikimedia.org/T106934 + // tldr: closing keyboard doesn't trigger a blur event + if ( this.isIos8 ) { + this.hasFixedHeader = false; + } + View.apply( this, arguments ); + } + + OO.mfExtend( Overlay, View, { /** * Identify whether the element contains position fixed elements * @property {Boolean} @@ -105,17 +114,6 @@ this.$spinner.addClass( 'hidden' ); }, - /** @inheritdoc */ - initialize: function ( options ) { - this.isIos = browser.isIos(); - this.isIos8 = browser.isIos( 8 ); - // https://phabricator.wikimedia.org/T106934 - // tldr: closing keyboard doesn't trigger a blur event - if ( this.isIos8 ) { - this.hasFixedHeader = false; - } - View.prototype.initialize.apply( this, arguments ); - }, /** @inheritdoc */ postRender: function () { var self = this; diff --git a/resources/mobile.pagelist.scripts/WatchstarPageList.js b/resources/mobile.pagelist.scripts/WatchstarPageList.js index 0dc412a..9c6046c 100644 --- a/resources/mobile.pagelist.scripts/WatchstarPageList.js +++ b/resources/mobile.pagelist.scripts/WatchstarPageList.js @@ -1,7 +1,6 @@ ( function ( M, $ ) { - var WatchstarPageList, - mWatchstar, + var mWatchstar, PageList = M.require( 'mobile.pagelist/PageList' ), Watchstar = M.require( 'mobile.watchstar/Watchstar' ), user = M.require( 'mobile.user/user' ), @@ -16,19 +15,17 @@ * @uses Watchstar * @extends View */ - WatchstarPageList = PageList.extend( { + function WatchstarPageList( options ) { + this.wsGateway = new WatchstarGateway( options.api ); + PageList.apply( this, arguments ); + } + + OO.mfExtend( WatchstarPageList, PageList, { /** * @inheritdoc * @cfg {Object} defaults Default options hash. * @cfg {mw.Api} defaults.api */ - /** - * @inheritdoc - */ - initialize: function ( options ) { - this.wsGateway = new WatchstarGateway( options.api ); - PageList.prototype.initialize.apply( this, arguments ); - }, /** * Retrieve pages * diff --git a/resources/mobile.pagelist/PageList.js b/resources/mobile.pagelist/PageList.js index 1d09656..4c5d785 100644 --- a/resources/mobile.pagelist/PageList.js +++ b/resources/mobile.pagelist/PageList.js @@ -1,7 +1,6 @@ ( function ( M, $ ) { - var PageList, - View = M.require( 'mobile.view/View' ), + var View = M.require( 'mobile.view/View' ), browser = M.require( 'mobile.browser/browser' ); /** @@ -9,7 +8,11 @@ * @class PageList * @extends View */ - PageList = View.extend( { + function PageList() { + View.apply( this, arguments ); + } + + OO.mfExtend( PageList, View, { /** * @cfg {Object} defaults Default options hash. * @cfg {Boolean} defaults.imagesDisabled whether to show images or not. diff --git a/resources/mobile.references/ReferencesDrawer.js b/resources/mobile.references/ReferencesDrawer.js index 0c3a14f..12b20f4 100644 --- a/resources/mobile.references/ReferencesDrawer.js +++ b/resources/mobile.references/ReferencesDrawer.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var ReferencesDrawer, - Drawer = M.require( 'mobile.drawers/Drawer' ), + var Drawer = M.require( 'mobile.drawers/Drawer' ), Icon = M.require( 'mobile.startup/Icon' ), SchemaMobileWebUIClickTracking = M.require( 'mobile.loggingSchemas/SchemaMobileWebUIClickTracking' ), @@ -12,7 +11,11 @@ * @extends Drawer * @uses Icon */ - ReferencesDrawer = Drawer.extend( { + function ReferencesDrawer() { + Drawer.apply( this, arguments ); + } + + OO.mfExtend( ReferencesDrawer, Drawer, { /** * @cfg {Object} defaults Default options hash. * @cfg {String} defaults.cancelButton HTML of the button that closes the drawer. diff --git a/resources/mobile.search/SearchOverlay.js b/resources/mobile.search/SearchOverlay.js index 5283b0a..4d9553c 100644 --- a/resources/mobile.search/SearchOverlay.js +++ b/resources/mobile.search/SearchOverlay.js @@ -8,8 +8,7 @@ SEARCH_DELAY = 300, $html = $( 'html' ), router = M.require( 'mobile.startup/router' ), - feedbackLink = mw.config.get( 'wgCirrusSearchFeedbackLink' ), - SearchOverlay; + feedbackLink = mw.config.get( 'wgCirrusSearchFeedbackLink' ); /** * Overlay displaying search results @@ -18,7 +17,20 @@ * @uses SearchGateway * @uses Icon */ - SearchOverlay = Overlay.extend( { + function SearchOverlay( options ) { + var self = this; + Overlay.call( this, options ); + this.api = options.api; + this.gateway = new options.gatewayClass( this.api ); + + // FIXME: Remove when search registers route with overlay manager + // we need this because of the focus/delay hack in search.js + router.once( 'route', function () { + self._hideOnRoute(); + } ); + } + + OO.mfExtend( SearchOverlay, Overlay, { templatePartials: $.extend( {}, Overlay.prototype.templatePartials, { anchor: Anchor.prototype.template, icon: Icon.prototype.template @@ -97,20 +109,6 @@ ev.preventDefault(); self._hideOnRoute(); } - } ); - }, - - /** @inheritdoc */ - initialize: function ( options ) { - var self = this; - Overlay.prototype.initialize.call( this, options ); - this.api = options.api; - this.gateway = new options.gatewayClass( this.api ); - - // FIXME: Remove when search registers route with overlay manager - // we need this because of the focus/delay hack in search.js - router.once( 'route', function () { - self._hideOnRoute(); } ); }, diff --git a/resources/mobile.special.mobileoptions.scripts/mobileoptions.js b/resources/mobile.special.mobileoptions.scripts/mobileoptions.js index b46ca07..438de06 100644 --- a/resources/mobile.special.mobileoptions.scripts/mobileoptions.js +++ b/resources/mobile.special.mobileoptions.scripts/mobileoptions.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var Checkbox, - context = M.require( 'mobile.context/context' ), + var context = M.require( 'mobile.context/context' ), FontChanger = M.require( 'mobile.fontchanger/FontChanger' ), View = M.require( 'mobile.view/View' ), settings = M.require( 'mobile.settings/settings' ); @@ -10,7 +9,11 @@ * @class Checkbox * @extends View */ - Checkbox = View.extend( { + function Checkbox() { + View.apply( this, arguments ); + } + + OO.mfExtend( Checkbox, View, { template: mw.template.get( 'mobile.special.mobileoptions.scripts', 'Checkbox.hogan' ), /** * Save the current state of the checkbox to the settings diff --git a/resources/mobile.startup/Anchor.js b/resources/mobile.startup/Anchor.js index e987cbc..b7cdb6d 100644 --- a/resources/mobile.startup/Anchor.js +++ b/resources/mobile.startup/Anchor.js @@ -1,14 +1,17 @@ ( function ( M ) { - var Anchor, - View = M.require( 'mobile.view/View' ); + var View = M.require( 'mobile.view/View' ); /** * A wrapper for creating an anchor. * @class Anchor * @extends View */ - Anchor = View.extend( { + function Anchor() { + View.apply( this, arguments ); + } + + OO.mfExtend( Anchor, View, { /** @inheritdoc */ isTemplateMode: true, /** diff --git a/resources/mobile.startup/Button.js b/resources/mobile.startup/Button.js index c1f2485..4cb799e 100644 --- a/resources/mobile.startup/Button.js +++ b/resources/mobile.startup/Button.js @@ -1,14 +1,20 @@ ( function ( M ) { - var Button, - View = M.require( 'mobile.view/View' ); + var View = M.require( 'mobile.view/View' ); /** * A wrapper for creating a button. * @class Button * @extends View */ - Button = View.extend( { + function Button( options ) { + if ( options.href ) { + options.tagName = 'a'; + } + View.call( this, options ); + } + + OO.mfExtend( Button, View, { /** @inheritdoc */ isTemplateMode: true, /** @@ -33,13 +39,6 @@ additionalClassNames: '', href: undefined, label: undefined - }, - /** @inheritdoc */ - initialize: function ( options ) { - if ( options.href ) { - options.tagName = 'a'; - } - View.prototype.initialize.call( this, options ); }, template: mw.template.get( 'mobile.startup', 'button.hogan' ) } ); diff --git a/resources/mobile.startup/Icon.js b/resources/mobile.startup/Icon.js index ce03dfb..6f6de07 100644 --- a/resources/mobile.startup/Icon.js +++ b/resources/mobile.startup/Icon.js @@ -1,14 +1,23 @@ ( function ( M, $ ) { - var View = M.require( 'mobile.view/View' ), - Icon; + var View = M.require( 'mobile.view/View' ); /** * A wrapper for creating an icon. * @class Icon * @extends View */ - Icon = View.extend( { + function Icon( options ) { + if ( options.hasText ) { + options.modifier = 'mw-ui-icon-before'; + } + if ( options.href ) { + options.tagName = 'a'; + } + View.call( this, options ); + } + + OO.mfExtend( Icon, View, { /** @inheritdoc */ isTemplateMode: true, /** @@ -47,16 +56,6 @@ */ getGlyphClassName: function () { return this.options.base + '-' + this.options.name; - }, - /** @inheritdoc */ - initialize: function ( options ) { - if ( options.hasText ) { - options.modifier = 'mw-ui-icon-before'; - } - if ( options.href ) { - options.tagName = 'a'; - } - View.prototype.initialize.call( this, options ); }, /** * Return the HTML representation of this view diff --git a/resources/mobile.startup/Page.js b/resources/mobile.startup/Page.js index 1fc513b..eedc3d1 100644 --- a/resources/mobile.startup/Page.js +++ b/resources/mobile.startup/Page.js @@ -1,7 +1,6 @@ ( function ( HTML, M, $ ) { - var Page, - time = M.require( 'mobile.modifiedBar/time' ), + var time = M.require( 'mobile.modifiedBar/time' ), View = M.require( 'mobile.view/View' ), Section = M.require( 'mobile.startup/Section' ), Thumbnail = M.require( 'mobile.startup/Thumbnail' ); @@ -13,7 +12,29 @@ * @uses Section * @extends View */ - Page = View.extend( { + function Page( options ) { + var thumb; + this.options = options; + options.languageUrl = mw.util.getUrl( 'Special:MobileLanguages/' + options.title ); + View.call( this, options ); + // Fallback if no displayTitle provided + options.displayTitle = this.getDisplayTitle(); + // allow usage in templates. + // FIXME: Should View map all options to properties? + this.title = options.title; + this.displayTitle = options.displayTitle; + this.thumbnail = options.thumbnail; + this.url = options.url || mw.util.getUrl( options.title ); + this.id = options.id; + this.isMissing = options.isMissing; + thumb = this.thumbnail; + if ( thumb && thumb.width ) { + this.thumbnail.isLandscape = thumb.width > thumb.height; + } + this.wikidataDescription = options.wikidataDescription; + } + + OO.mfExtend( Page, View, { /** * @cfg {Object} defaults Default options hash. * @cfg {Number} defaults.id Page ID. The default value of 0 represents a new page. @@ -59,31 +80,6 @@ * @inheritdoc */ isBorderBox: false, - /** - * @inheritdoc - */ - initialize: function ( options ) { - var thumb; - - this.options = options; - options.languageUrl = mw.util.getUrl( 'Special:MobileLanguages/' + options.title ); - View.prototype.initialize.apply( this, arguments ); - // Fallback if no displayTitle provided - options.displayTitle = this.getDisplayTitle(); - // allow usage in templates. - // FIXME: Should View map all options to properties? - this.title = options.title; - this.displayTitle = options.displayTitle; - this.thumbnail = options.thumbnail; - this.url = options.url || mw.util.getUrl( options.title ); - this.id = options.id; - this.isMissing = options.isMissing; - thumb = this.thumbnail; - if ( thumb && thumb.width ) { - this.thumbnail.isLandscape = thumb.width > thumb.height; - } - this.wikidataDescription = options.wikidataDescription; - }, /** * Retrieve the title that should be displayed to the user * @method diff --git a/resources/mobile.startup/Panel.js b/resources/mobile.startup/Panel.js index f25f0c2..1bd2078 100644 --- a/resources/mobile.startup/Panel.js +++ b/resources/mobile.startup/Panel.js @@ -1,14 +1,17 @@ ( function ( M ) { - var View = M.require( 'mobile.view/View' ), - Panel; + var View = M.require( 'mobile.view/View' ); /** * An abstract class for a {@link View} that comprises a simple panel. * @class Panel * @extends View */ - Panel = View.extend( { + function Panel() { + View.apply( this, arguments ); + } + + OO.mfExtend( Panel, View, { /** @inheritdoc */ className: 'panel', // in milliseconds diff --git a/resources/mobile.startup/Schema.js b/resources/mobile.startup/Schema.js index 40b556b..bc04eea 100644 --- a/resources/mobile.startup/Schema.js +++ b/resources/mobile.startup/Schema.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var Class = M.require( 'mobile.oo/Class' ), - settings = M.require( 'mobile.settings/settings' ), + var settings = M.require( 'mobile.settings/settings' ), BEACON_SETTING_KEY = 'mobileFrontend/beacon'; /** @@ -168,10 +167,6 @@ deleteBeacon(); }; - // FIXME: Needed to give time for Gather to update - Schema.extend = Class.extend; - mw.log.deprecate( Schema, 'extend', Schema.extend, - 'Schema.extend is deprecated. Do not use this. Use OO.mfExtend' ); M.define( 'mobile.startup/Schema', Schema ); diff --git a/resources/mobile.startup/Section.js b/resources/mobile.startup/Section.js index 5ee523d..e11130b 100644 --- a/resources/mobile.startup/Section.js +++ b/resources/mobile.startup/Section.js @@ -1,7 +1,6 @@ ( function ( M, $ ) { var View = M.require( 'mobile.view/View' ), - Section, icons = M.require( 'mobile.startup/icons' ); /** @@ -9,7 +8,22 @@ * @class Section * @extends View */ - Section = View.extend( { + function Section( options ) { + var self = this; + options.tag = 'h' + options.level; + this.line = options.line; + this.text = options.text; + this.hasReferences = options.hasReferences || false; + this.id = options.id || null; + this.anchor = options.anchor; + this.children = []; + $.each( options.children || [], function () { + self.children.push( new Section( this ) ); + } ); + View.call( this, options ); + } + + OO.mfExtend( Section, View, { template: mw.template.get( 'mobile.startup', 'Section.hogan' ), /** * @cfg {Object} defaults Default options hash. @@ -20,21 +34,6 @@ line: undefined, text: '', spinner: icons.spinner().toHtmlString() - }, - /** @inheritdoc */ - initialize: function ( options ) { - var self = this; - options.tag = 'h' + options.level; - this.line = options.line; - this.text = options.text; - this.hasReferences = options.hasReferences || false; - this.id = options.id || null; - this.anchor = options.anchor; - this.children = []; - $.each( options.children || [], function () { - self.children.push( new Section( this ) ); - } ); - View.prototype.initialize.apply( self, arguments ); } } ); M.define( 'mobile.startup/Section', Section ); diff --git a/resources/mobile.startup/Skin.js b/resources/mobile.startup/Skin.js index 0d5c195..c2a06d1 100644 --- a/resources/mobile.startup/Skin.js +++ b/resources/mobile.startup/Skin.js @@ -1,7 +1,6 @@ ( function ( M, $ ) { - var Skin, - browser = M.require( 'mobile.browser/browser' ), + var browser = M.require( 'mobile.browser/browser' ), View = M.require( 'mobile.view/View' ); /** @@ -12,7 +11,39 @@ * @uses Browser * @uses Page */ - Skin = View.extend( { + function Skin( options ) { + var self = this; + + this.page = options.page; + this.name = options.name; + this.mainMenu = options.mainMenu; + View.call( this, options ); + // Must be run after merging with defaults as must be defined. + this.tabletModules = options.tabletModules; + + /** + * Tests current window size and if suitable loads styles and scripts specific for larger devices + * + * @method + * @ignore + */ + function loadWideScreenModules() { + if ( browser.isWideScreen() ) { + // Adjust screen for tablets + if ( self.page.inNamespace( '' ) ) { + mw.loader.using( self.tabletModules ).always( function () { + self.off( '_resize' ); + self.emit.call( self, 'changed' ); + } ); + } + } + } + M.on( 'resize', $.proxy( this, 'emit', '_resize' ) ); + this.on( '_resize', loadWideScreenModules ); + this.emit( '_resize' ); + } + + OO.mfExtend( Skin, View, { /** * @inheritdoc * Skin contains components that we do not control @@ -91,40 +122,6 @@ $el.add( '.overlay' ).height( scrollBottom ); } } ); - }, - /** - * @inheritdoc - */ - initialize: function ( options ) { - var self = this; - - this.page = options.page; - this.name = options.name; - this.mainMenu = options.mainMenu; - View.prototype.initialize.apply( this, arguments ); - // Must be run after merging with defaults as must be defined. - this.tabletModules = options.tabletModules; - - /** - * Tests current window size and if suitable loads styles and scripts specific for larger devices - * - * @method - * @ignore - */ - function loadWideScreenModules() { - if ( browser.isWideScreen() ) { - // Adjust screen for tablets - if ( self.page.inNamespace( '' ) ) { - mw.loader.using( self.tabletModules ).always( function () { - self.off( '_resize' ); - self.emit.call( self, 'changed' ); - } ); - } - } - } - M.on( 'resize', $.proxy( this, 'emit', '_resize' ) ); - this.on( '_resize', loadWideScreenModules ); - this.emit( '_resize' ); }, /** * @inheritdoc diff --git a/resources/mobile.startup/Thumbnail.js b/resources/mobile.startup/Thumbnail.js index df7efce..ad6b9a8 100644 --- a/resources/mobile.startup/Thumbnail.js +++ b/resources/mobile.startup/Thumbnail.js @@ -1,8 +1,6 @@ ( function ( M ) { - var - View = M.require( 'mobile.view/View' ), - Thumbnail; + var View = M.require( 'mobile.view/View' ); /** * Representation of a thumbnail @@ -10,7 +8,10 @@ * @class Thumbnail * @extends View */ - Thumbnail = View.extend( { + function Thumbnail() { + View.apply( this, arguments ); + } + OO.mfExtend( Thumbnail, View, { /** * @cfg {Object} defaults options * @cfg {String} defaults.filename uri decoded filename including File: prefix associated with thumbnail diff --git a/resources/mobile.talk.overlays/TalkOverlay.js b/resources/mobile.talk.overlays/TalkOverlay.js index 6ce403c..4a388a0 100644 --- a/resources/mobile.talk.overlays/TalkOverlay.js +++ b/resources/mobile.talk.overlays/TalkOverlay.js @@ -1,154 +1,157 @@ ( function ( M, $ ) { - var - TalkOverlayBase = M.require( 'mobile.talk.overlays/TalkOverlayBase' ), + var TalkOverlayBase = M.require( 'mobile.talk.overlays/TalkOverlayBase' ), Page = M.require( 'mobile.startup/Page' ), Anchor = M.require( 'mobile.startup/Anchor' ), - user = M.require( 'mobile.user/user' ), + user = M.require( 'mobile.user/user' ); + /** + * Overlay for talk page + * @extends Overlay + * @class TalkOverlay + * @uses Page + * @uses TalkSectionOverlay + * @uses TalkSectionAddOverlay + */ + function TalkOverlay() { + TalkOverlayBase.apply( this, arguments ); + } + + OO.mfExtend( TalkOverlay, TalkOverlayBase, { + templatePartials: $.extend( {}, TalkOverlayBase.prototype.templatePartials, { + content: mw.template.get( 'mobile.talk.overlays', 'content.hogan' ) + } ), /** - * Overlay for talk page - * @extends Overlay - * @class TalkOverlay - * @uses Page - * @uses TalkSectionOverlay - * @uses TalkSectionAddOverlay + * @inheritdoc + * @cfg {Object} defaults Default options hash. + * @cfg {Array} defaults.headings A list of {Section} objects to render heading links + * for. If not set ajax request will be performed. + * @cfg {String} defaults.heading Heading for talk overlay. + * @cfg {String} defaults.leadHeading Heading for a discussion which has no heading + * (lead section of talk page). + * @cfg {String} defaults.headerButtonsListClassName Class name of the header buttons + * list + * @cfg {Array} defaults.headerButtons Objects that will be used as defaults for + * generating header buttons. Default list includes an 'add' button, which opens + * a new talk overlay. */ - TalkOverlay = TalkOverlayBase.extend( { - templatePartials: $.extend( {}, TalkOverlayBase.prototype.templatePartials, { - content: mw.template.get( 'mobile.talk.overlays', 'content.hogan' ) - } ), - /** - * @inheritdoc - * @cfg {Object} defaults Default options hash. - * @cfg {Array} defaults.headings A list of {Section} objects to render heading links - * for. If not set ajax request will be performed. - * @cfg {String} defaults.heading Heading for talk overlay. - * @cfg {String} defaults.leadHeading Heading for a discussion which has no heading - * (lead section of talk page). - * @cfg {String} defaults.headerButtonsListClassName Class name of the header buttons - * list - * @cfg {Array} defaults.headerButtons Objects that will be used as defaults for - * generating header buttons. Default list includes an 'add' button, which opens - * a new talk overlay. - */ - defaults: $.extend( {}, TalkOverlayBase.prototype.defaults, { - headings: undefined, - heading: '<strong>' + mw.msg( 'mobile-frontend-talk-overlay-header' ) + '</strong>', - leadHeading: mw.msg( 'mobile-frontend-talk-overlay-lead-header' ), - headerButtonsListClassName: 'overlay-action', - headerButtons: [ { - href: '#/talk/new', - className: 'add continue hidden', - msg: mw.msg( 'mobile-frontend-talk-add-overlay-submit' ) - } ], - footerAnchor: new Anchor( { - progressive: true, - additionalClassNames: 'footer-link talk-fullpage', - label: mw.msg( 'mobile-frontend-talk-fullpage' ) - } ).options - } ), + defaults: $.extend( {}, TalkOverlayBase.prototype.defaults, { + headings: undefined, + heading: '<strong>' + mw.msg( 'mobile-frontend-talk-overlay-header' ) + '</strong>', + leadHeading: mw.msg( 'mobile-frontend-talk-overlay-lead-header' ), + headerButtonsListClassName: 'overlay-action', + headerButtons: [ { + href: '#/talk/new', + className: 'add continue hidden', + msg: mw.msg( 'mobile-frontend-talk-add-overlay-submit' ) + } ], + footerAnchor: new Anchor( { + progressive: true, + additionalClassNames: 'footer-link talk-fullpage', + label: mw.msg( 'mobile-frontend-talk-fullpage' ) + } ).options + } ), - /** @inheritdoc */ - postRender: function () { - TalkOverlayBase.prototype.postRender.apply( this ); - this.$board = this.$( '.board' ); - this.$( '.talk-fullpage' ).attr( 'href', mw.util.getUrl( this.options.title ) ) - .removeClass( 'hidden' ); - if ( !this.options.headings ) { - this._loadContent( this.options ); - } - this._setupAddDiscussionButton( this.options ); - this.showHidden( '.initial-header' ); - }, - - /** - * Show a loading spinner - * @method - */ - showSpinner: function () { - this.$board.hide(); - TalkOverlayBase.prototype.showSpinner.apply( this, arguments ); - }, - - /** - * Hide the loading spinner - * @method - */ - clearSpinner: function () { - TalkOverlayBase.prototype.clearSpinner.apply( this, arguments ); - this.$board.show(); - }, - - /** - * Load content of the talk page into the overlay - * @method - * @param {Object} options for the overlay - * @private - */ - _loadContent: function ( options ) { - var self = this; - - // show a spinner - this.showSpinner(); - - // clear actual content, if any - this.$( '.topic-title-list' ).empty(); - - this.pageGateway.getPage( options.title ).fail( function ( resp ) { - // If the API returns the error code 'missingtitle', that means the - // talk page doesn't exist yet. - if ( resp === 'missingtitle' ) { - // Create an empty page for new pages - self._addContent( { - title: options.title, - sections: [] - }, options ); - } else { - // If the API request fails for any other reason, load the talk - // page manually rather than leaving the spinner spinning. - window.location = mw.util.getUrl( options.title ); - } - } ).done( function ( pageData ) { - self._addContent( pageData, options ); - } ); - }, - - /** - * Adds the content received from _loadContent to the Overlay and re-renders it. - * @method - * @private - * @param {Object} pageData As returned from PageApi#getPage - * @param {Object} options for the overlay - */ - _addContent: function ( pageData, options ) { - var page = new Page( pageData ), - sections = page.getSections(); - - this.page = page; - - options.explanation = sections.length > 0 ? mw.msg( 'mobile-frontend-talk-explained' ) : - mw.msg( 'mobile-frontend-talk-explained-empty' ); - options.headings = sections; - - // content is there so re-render and hide the spinner - this.render( options ); - this.clearSpinner(); - }, - /** - * Shows the add topic button to logged in users. - * Ensures the overlay refreshes when a discussion is added. - * @method - * @private - */ - _setupAddDiscussionButton: function () { - var $add = this.$( '.overlay-action .add' ); - M.on( 'talk-discussion-added', $.proxy( this, '_loadContent', this.options ) ); - if ( !user.isAnon() ) { - $add.removeClass( 'hidden' ); - } else { - $add.remove(); - } + /** @inheritdoc */ + postRender: function () { + TalkOverlayBase.prototype.postRender.apply( this ); + this.$board = this.$( '.board' ); + this.$( '.talk-fullpage' ).attr( 'href', mw.util.getUrl( this.options.title ) ) + .removeClass( 'hidden' ); + if ( !this.options.headings ) { + this._loadContent( this.options ); } - } ); + this._setupAddDiscussionButton( this.options ); + this.showHidden( '.initial-header' ); + }, + + /** + * Show a loading spinner + * @method + */ + showSpinner: function () { + this.$board.hide(); + TalkOverlayBase.prototype.showSpinner.apply( this, arguments ); + }, + + /** + * Hide the loading spinner + * @method + */ + clearSpinner: function () { + TalkOverlayBase.prototype.clearSpinner.apply( this, arguments ); + this.$board.show(); + }, + + /** + * Load content of the talk page into the overlay + * @method + * @param {Object} options for the overlay + * @private + */ + _loadContent: function ( options ) { + var self = this; + + // show a spinner + this.showSpinner(); + + // clear actual content, if any + this.$( '.topic-title-list' ).empty(); + + this.pageGateway.getPage( options.title ).fail( function ( resp ) { + // If the API returns the error code 'missingtitle', that means the + // talk page doesn't exist yet. + if ( resp === 'missingtitle' ) { + // Create an empty page for new pages + self._addContent( { + title: options.title, + sections: [] + }, options ); + } else { + // If the API request fails for any other reason, load the talk + // page manually rather than leaving the spinner spinning. + window.location = mw.util.getUrl( options.title ); + } + } ).done( function ( pageData ) { + self._addContent( pageData, options ); + } ); + }, + + /** + * Adds the content received from _loadContent to the Overlay and re-renders it. + * @method + * @private + * @param {Object} pageData As returned from PageApi#getPage + * @param {Object} options for the overlay + */ + _addContent: function ( pageData, options ) { + var page = new Page( pageData ), + sections = page.getSections(); + + this.page = page; + + options.explanation = sections.length > 0 ? mw.msg( 'mobile-frontend-talk-explained' ) : + mw.msg( 'mobile-frontend-talk-explained-empty' ); + options.headings = sections; + + // content is there so re-render and hide the spinner + this.render( options ); + this.clearSpinner(); + }, + /** + * Shows the add topic button to logged in users. + * Ensures the overlay refreshes when a discussion is added. + * @method + * @private + */ + _setupAddDiscussionButton: function () { + var $add = this.$( '.overlay-action .add' ); + M.on( 'talk-discussion-added', $.proxy( this, '_loadContent', this.options ) ); + if ( !user.isAnon() ) { + $add.removeClass( 'hidden' ); + } else { + $add.remove(); + } + } + } ); M.define( 'mobile.talk.overlays/TalkOverlay', TalkOverlay ); diff --git a/resources/mobile.talk.overlays/TalkOverlayBase.js b/resources/mobile.talk.overlays/TalkOverlayBase.js index 63ac261..0b39c8b 100644 --- a/resources/mobile.talk.overlays/TalkOverlayBase.js +++ b/resources/mobile.talk.overlays/TalkOverlayBase.js @@ -1,6 +1,5 @@ ( function ( M ) { - var TalkOverlayBase, - PageGateway = M.require( 'mobile.startup/PageGateway' ), + var PageGateway = M.require( 'mobile.startup/PageGateway' ), Overlay = M.require( 'mobile.overlays/Overlay' ); /** @@ -10,14 +9,13 @@ * @uses Page * @uses PageGateway */ - TalkOverlayBase = Overlay.extend( { - /** @inheritdoc */ - initialize: function ( options ) { - this.pageGateway = new PageGateway( options.api ); - // FIXME: This should be using a gateway e.g. TalkGateway, PageGateway or EditorGateway - this.editorApi = options.api; - Overlay.prototype.initialize.apply( this, arguments ); - } + function TalkOverlayBase( options ) { + this.pageGateway = new PageGateway( options.api ); + // FIXME: This should be using a gateway e.g. TalkGateway, PageGateway or EditorGateway + this.editorApi = options.api; + Overlay.apply( this, arguments ); + } + OO.mfExtend( TalkOverlayBase, Overlay, { } ); M.define( 'mobile.talk.overlays/TalkOverlayBase', TalkOverlayBase ); diff --git a/resources/mobile.talk.overlays/TalkSectionAddOverlay.js b/resources/mobile.talk.overlays/TalkSectionAddOverlay.js index 10e6220..8dbfe09 100644 --- a/resources/mobile.talk.overlays/TalkSectionAddOverlay.js +++ b/resources/mobile.talk.overlays/TalkSectionAddOverlay.js @@ -1,8 +1,7 @@ ( function ( M, $ ) { var TalkOverlayBase = M.require( 'mobile.talk.overlays/TalkOverlayBase' ), toast = M.require( 'mobile.toast/toast' ), - Icon = M.require( 'mobile.startup/Icon' ), - TalkSectionAddOverlay; + Icon = M.require( 'mobile.startup/Icon' ); /** * Overlay for adding a talk section @@ -10,7 +9,15 @@ * @extends TalkOverlayBase * @uses Toast */ - TalkSectionAddOverlay = TalkOverlayBase.extend( { + function TalkSectionAddOverlay( options ) { + TalkOverlayBase.apply( this, arguments ); + this.title = options.title; + // Variable to indicate, if the overlay will be closed by the save function or by the user. If this is false and there is content in the input fields, + // the user will be asked, if he want to abandon his changes before we close the Overlay, otherwise the Overlay will be closed without any question. + this._saveHit = false; + } + + OO.mfExtend( TalkSectionAddOverlay, TalkOverlayBase, { /** * @inheritdoc * @cfg {Object} defaults Default options hash. @@ -43,14 +50,6 @@ 'change .wikitext-editor, .summary': 'onTextInput', 'click .confirm-save': 'onSaveClick' } ), - /** @inheritdoc */ - initialize: function ( options ) { - TalkOverlayBase.prototype.initialize.apply( this, arguments ); - this.title = options.title; - // Variable to indicate, if the overlay will be closed by the save function or by the user. If this is false and there is content in the input fields, - // the user will be asked, if he want to abandon his changes before we close the Overlay, otherwise the Overlay will be closed without any question. - this._saveHit = false; - }, /** @inheritdoc */ postRender: function () { TalkOverlayBase.prototype.postRender.call( this ); diff --git a/resources/mobile.talk.overlays/TalkSectionOverlay.js b/resources/mobile.talk.overlays/TalkSectionOverlay.js index 2962f9e..76fc304 100644 --- a/resources/mobile.talk.overlays/TalkSectionOverlay.js +++ b/resources/mobile.talk.overlays/TalkSectionOverlay.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var TalkSectionOverlay, - TalkOverlayBase = M.require( 'mobile.talk.overlays/TalkOverlayBase' ), + var TalkOverlayBase = M.require( 'mobile.talk.overlays/TalkOverlayBase' ), popup = M.require( 'mobile.toast/toast' ), user = M.require( 'mobile.user/user' ), Page = M.require( 'mobile.startup/Page' ), @@ -14,7 +13,11 @@ * @uses Button * @uses Toast */ - TalkSectionOverlay = TalkOverlayBase.extend( { + function TalkSectionOverlay() { + TalkOverlayBase.apply( this, arguments ); + } + + OO.mfExtend( TalkSectionOverlay, TalkOverlayBase, { templatePartials: $.extend( {}, TalkOverlayBase.prototype.templatePartials, { header: mw.template.get( 'mobile.talk.overlays', 'Section/header.hogan' ), content: mw.template.get( 'mobile.talk.overlays', 'Section/content.hogan' ) diff --git a/resources/mobile.toc/TableOfContents.js b/resources/mobile.toc/TableOfContents.js index 07ecf16..2cdd17e 100644 --- a/resources/mobile.toc/TableOfContents.js +++ b/resources/mobile.toc/TableOfContents.js @@ -1,6 +1,5 @@ ( function ( M ) { - var TableOfContents, - SchemaMobileWebUIClickTracking = M.require( + var SchemaMobileWebUIClickTracking = M.require( 'mobile.loggingSchemas/SchemaMobileWebUIClickTracking' ), uiSchema = new SchemaMobileWebUIClickTracking(), View = M.require( 'mobile.view/View' ), @@ -13,7 +12,11 @@ * @uses Icon * @uses SchemaMobileWebClickTracking */ - TableOfContents = View.extend( { + function TableOfContents() { + View.apply( this, arguments ); + } + + OO.mfExtend( TableOfContents, View, { templatePartials: { tocHeading: mw.template.get( 'mobile.toc', 'heading.hogan' ) }, diff --git a/resources/mobile.view/View.js b/resources/mobile.view/View.js index 10ce3c4..9f326ef 100644 --- a/resources/mobile.view/View.js +++ b/resources/mobile.view/View.js @@ -332,28 +332,6 @@ } } ); - /** - * Helper function for generating a View. - * - * @param {Object} prototype - * @return {View} - */ - function extend( prototype ) { - var Child, - Parent = this; - - /** - * @ignore - */ - Child = function () { - Parent.apply( this, arguments ); - }; - Child.extend = extend; - OO.mfExtend( Child, this, prototype ); - return Child; - } - View.extend = extend; - $.each( [ 'append', 'prepend', diff --git a/resources/mobile.watchlist/WatchList.js b/resources/mobile.watchlist/WatchList.js index 877be0d..acf0dcd 100644 --- a/resources/mobile.watchlist/WatchList.js +++ b/resources/mobile.watchlist/WatchList.js @@ -1,6 +1,5 @@ ( function ( M, $ ) { - var WatchList, - WatchstarPageList = M.require( 'mobile.pagelist.scripts/WatchstarPageList' ), + var WatchstarPageList = M.require( 'mobile.pagelist.scripts/WatchstarPageList' ), InfiniteScroll = M.require( 'mobile.infiniteScroll/InfiniteScroll' ), WatchListGateway = M.require( 'mobile.watchlist/WatchListGateway' ); @@ -10,23 +9,23 @@ * @class WatchList * @uses InfiniteScroll */ - WatchList = WatchstarPageList.extend( { + function WatchList( options ) { + var lastTitle; + + // Set up infinite scroll helper and listen to events + this.infiniteScroll = new InfiniteScroll(); + this.infiniteScroll.on( 'load', $.proxy( this, '_loadPages' ) ); + + if ( options.el ) { + lastTitle = this.getLastTitle( options.el ); + } + this.gateway = new WatchListGateway( options.api, lastTitle ); + + WatchstarPageList.apply( this, arguments ); + } + + OO.mfExtend( WatchList, WatchstarPageList, { isBorderBox: false, - /** @inheritdoc */ - initialize: function ( options ) { - var lastTitle; - - // Set up infinite scroll helper and listen to events - this.infiniteScroll = new InfiniteScroll(); - this.infiniteScroll.on( 'load', $.proxy( this, '_loadPages' ) ); - - if ( options.el ) { - lastTitle = this.getLastTitle( options.el ); - } - this.gateway = new WatchListGateway( options.api, lastTitle ); - - WatchstarPageList.prototype.initialize.apply( this, arguments ); - }, /** @inheritdoc */ preRender: function () { this.infiniteScroll.disable(); diff --git a/resources/mobile.watchstar/Watchstar.js b/resources/mobile.watchstar/Watchstar.js index 79c3e06..87622e6 100644 --- a/resources/mobile.watchstar/Watchstar.js +++ b/resources/mobile.watchstar/Watchstar.js @@ -1,7 +1,6 @@ ( function ( M ) { - var Watchstar, - View = M.require( 'mobile.view/View' ), + var View = M.require( 'mobile.view/View' ), SchemaMobileWebWatching = M.require( 'mobile.loggingSchemas/SchemaMobileWebWatching' ), WatchstarGateway = M.require( 'mobile.watchstar/WatchstarGateway' ), Icon = M.require( 'mobile.startup/Icon' ), @@ -26,7 +25,32 @@ * @uses WatchstarGateway * @uses Toast */ - Watchstar = View.extend( { + function Watchstar( options ) { + var self = this, + _super = View, + page = options.page; + + // FIXME: Remove default when Gather has been updated to use new gateway. (T113753) + options.api = options.api || new mw.Api(); + this.gateway = new WatchstarGateway( options.api ); + + if ( user.isAnon() ) { + _super.call( self, options ); + } else if ( options.isWatched === undefined ) { + this.gateway.loadWatchStatus( page.getId() ).done( function () { + options.isWatched = self.gateway.isWatchedPage( page ); + _super.call( self, options ); + } ); + } else { + this.gateway.setWatchedPage( options.page, options.isWatched ); + _super.call( self, options ); + } + this.schema = new SchemaMobileWebWatching( { + funnel: options.funnel + } ); + } + + OO.mfExtend( Watchstar, View, { /** * @inheritdoc */ diff --git a/tests/qunit/mobile.overlays/test_Overlay.js b/tests/qunit/mobile.overlays/test_Overlay.js index 580a5f6..a0f3d71 100644 --- a/tests/qunit/mobile.overlays/test_Overlay.js +++ b/tests/qunit/mobile.overlays/test_Overlay.js @@ -18,9 +18,13 @@ } ); QUnit.test( 'HTML overlay', 2, function ( assert ) { - var TestOverlay, overlay; + var overlay; - TestOverlay = Overlay.extend( { + function TestOverlay() { + Overlay.apply( this, arguments ); + } + + OO.mfExtend( TestOverlay, Overlay, { templatePartials: $.extend( Overlay.prototype.templatePartials, { content: mw.template.compile( '<div class="content">YO</div>', 'hogan' ) } ) diff --git a/tests/qunit/mobile.view/test_View.js b/tests/qunit/mobile.view/test_View.js index e9fe6f0..c266567 100644 --- a/tests/qunit/mobile.view/test_View.js +++ b/tests/qunit/mobile.view/test_View.js @@ -57,8 +57,12 @@ } ); QUnit.test( 'View.extend, with el property', 1, function ( assert ) { - var ChildView, $testEl, view; - ChildView = View.extend( { + var $testEl, view; + function ChildView() { + View.apply( this, arguments ); + } + + OO.mfExtend( ChildView, View, { firstHeading: function () { return this.$( 'h1' ).text(); } @@ -73,8 +77,12 @@ } ); QUnit.test( 'View.extend, with defined template', 4, function ( assert ) { - var ChildView, view; - ChildView = View.extend( { + var view; + function ChildView() { + View.apply( this, arguments ); + } + + OO.mfExtend( ChildView, View, { className: 'my-class', template: mw.template.compile( '<h1>{{title}}</h1><p>{{content}}</p>', 'xyz' ), title: function () { @@ -96,13 +104,21 @@ } ); QUnit.test( 'View.extend, with partials', 2, function ( assert ) { - var ParentView, ChildView, view; + var view; - ParentView = View.extend( { + function ParentView() { + View.apply( this, arguments ); + } + + OO.mfExtend( ParentView, View, { template: mw.template.compile( '<h1>{{title}}</h1>{{>content}}', 'xyz' ) } ); - ChildView = ParentView.extend( { + function ChildView() { + ParentView.apply( this, arguments ); + } + + OO.mfExtend( ChildView, ParentView, { templatePartials: { content: mw.template.compile( '<p>{{text}}</p>', 'xyz' ) } @@ -117,16 +133,24 @@ } ); QUnit.test( 'View.extend, extending partials', 1, function ( assert ) { - var ParentView, ChildView, view; + var view; - ParentView = View.extend( { + function ParentView() { + View.apply( this, arguments ); + } + + OO.mfExtend( ParentView, View, { templatePartials: { a: 1, b: 2 } } ); - ChildView = ParentView.extend( { + function ChildView() { + ParentView.apply( this, arguments ); + } + + OO.mfExtend( ChildView, ParentView, { templatePartials: $.extend( ParentView.prototype.templatePartials, { b: 3, c: 4 @@ -142,16 +166,24 @@ } ); QUnit.test( 'View.extend, extending defaults', 1, function ( assert ) { - var ParentView, ChildView, view; + var view; - ParentView = View.extend( { + function ParentView() { + View.apply( this, arguments ); + } + + OO.mfExtend( ParentView, View, { defaults: { a: 1, b: 2 } } ); - ChildView = ParentView.extend( { + function ChildView() { + ParentView.apply( this, arguments ); + } + + OO.mfExtend( ChildView, ParentView, { defaults: $.extend( ParentView.prototype.defaults, { b: 3, c: 4 @@ -169,8 +201,12 @@ } ); QUnit.test( 'View#preRender', 1, function ( assert ) { - var ChildView, view; - ChildView = View.extend( { + var view; + function ChildView() { + View.apply( this, arguments ); + } + + OO.mfExtend( ChildView, View, { template: mw.template.compile( '<p>{{text}}</p>', 'xyz' ), preRender: function () { this.options.text = 'hello'; @@ -182,8 +218,12 @@ } ); QUnit.test( 'View#postRender', 1, function ( assert ) { - var ChildView, view, spy = this.sandbox.spy(); - ChildView = View.extend( { + var view, spy = this.sandbox.spy(); + function ChildView() { + View.apply( this, arguments ); + } + + OO.mfExtend( ChildView, View, { postRender: function () { spy(); } @@ -195,7 +235,12 @@ QUnit.test( 'View#delegateEvents', 3, function ( assert ) { - var view, EventsView = View.extend( { + var view; + function EventsView() { + View.apply( this, arguments ); + } + + OO.mfExtend( EventsView, View, { template: mw.template.compile( '<p><span>test</span></p>', 'xyz' ), events: { 'click p span': function ( ev ) { @@ -229,15 +274,24 @@ } ); QUnit.test( 'View#render (with isTemplateMode)', 2, function ( assert ) { - var view, view2, - TemplateModeView = View.extend( { - template: mw.template.compile( '<p class="foo"><span>test</span></p>', 'html' ), - isTemplateMode: true - } ), - ContainerView = View.extend( { - className: 'bar', - template: mw.template.compile( '<p class="foo"><span>test</span></p>', 'html' ) - } ); + var view, view2; + function TemplateModeView() { + View.apply( this, arguments ); + } + + OO.mfExtend( TemplateModeView, View, { + template: mw.template.compile( '<p class="foo"><span>test</span></p>', 'html' ), + isTemplateMode: true + } ); + + function ContainerView() { + View.apply( this, arguments ); + } + + OO.mfExtend( ContainerView, View, { + className: 'bar', + template: mw.template.compile( '<p class="foo"><span>test</span></p>', 'html' ) + } ); view = new TemplateModeView(); view2 = new ContainerView(); @@ -248,17 +302,21 @@ } ); QUnit.test( 'View#render events (with isTemplateMode)', 4, function ( assert ) { - var view, - TemplateModeView = View.extend( { - events: { - 'click span': 'onClick' - }, - onClick: function () { - this.$el.empty().text( 'hello world' ); - }, - template: mw.template.compile( '<p class="foo"><span>test</span></p>', 'html' ), - isTemplateMode: true - } ); + var view; + function TemplateModeView() { + View.apply( this, arguments ); + } + + OO.mfExtend( TemplateModeView, View, { + events: { + 'click span': 'onClick' + }, + onClick: function () { + this.$el.empty().text( 'hello world' ); + }, + template: mw.template.compile( '<p class="foo"><span>test</span></p>', 'html' ), + isTemplateMode: true + } ); view = new TemplateModeView(); // trigger event -- To view, visit https://gerrit.wikimedia.org/r/265547 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I641f9f4145b0e96b33beefcef35bc2cfa243696d Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/MobileFrontend Gerrit-Branch: master Gerrit-Owner: Sumit <asthana.sumi...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits