{"version":3,"sources":["webpack://mfModules.[name]/./src/mobile.special.watchlist.scripts/WatchList.js","webpack://mfModules.[name]/./src/mobile.special.watchlist.scripts/WatchListGateway.js","webpack://mfModules.[name]/./src/mobile.special.watchlist.scripts/mobile.special.watchlist.scripts.js","webpack://mfModules.[name]/./src/mobile.startup/ScrollEndEventEmitter.js"],"names":["mfExtend","require","PageList","WatchstarPageList","ScrollEndEventEmitter","util","WatchListGateway","WatchList","params","lastTitle","options","extend","isBorderBox","this","scrollEndEventEmitter","eventBus","on","EVENT_SCROLL_END","_loadPages","bind","el","getLastTitle","gateway","api","call","preRender","disable","setElement","$el","postRender","$items","statuses","prototype","apply","queryUnitializedItems","Object","keys","parsePagesFromItems","reduce","arr","title","renderItems","enable","loadWatchlist","then","pages","forEach","page","appendPage","render","templateOptions","wikidataDescription","undefined","append","templatePartials","item","find","last","attr","module","exports","pageJSONParser","extendSearchParams","limit","continueParams","continue","gwrcontinue","replace","shouldSkipFirstTitle","canContinue","self","prop","rvprop","generator","gwrnamespace","gwrlimit","Deferred","resolve","get","url","apiUrl","data","parseData","query","sort","p1","p2","slice","map","parse","userOptions","mw","user","$","$watchlist","Api","view","filter","length","funnel","skipTemplateRender","remove","saveOption","threshold","OO","EventEmitter","mixinClass","_bindScroll","_scrollHandler","_onScroll","_unbindScroll","off","enabled","scrollNearEnd","emit","$window","getWindow","scrollBottom","scrollTop","height","endPosition","offset","top","outerHeight"],"mappings":"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","file":"mobile.special.watchlist.scripts.js","sourcesContent":["var\n\tmfExtend = require( '../mobile.startup/mfExtend' ),\n\tPageList = require( '../mobile.startup/PageList' ),\n\tWatchstarPageList = require( '../mobile.startup/watchstar/WatchstarPageList' ),\n\tScrollEndEventEmitter = require( '../mobile.startup/ScrollEndEventEmitter' ),\n\tutil = require( '../mobile.startup/util' ),\n\tWatchListGateway = require( './WatchListGateway' );\n\n/**\n * An extension of the WatchstarPageList which preloads pages as all being\n * watched.\n *\n * @extends WatchstarPageList\n * @class WatchList\n * @uses ScrollEndEventEmitter\n *\n * @fires watched\n * @fires watch\n * @param {Object} params Configuration options\n * @param {OO.EventEmitter} params.eventBus Object used to listen for scroll:throttled events\n */\nfunction WatchList( params ) {\n\tvar lastTitle,\n\t\toptions = util.extend( {}, {\n\t\t\tisBorderBox: false\n\t\t}, params );\n\n\t// Set up infinite scroll helper and listen to events\n\tthis.scrollEndEventEmitter = new ScrollEndEventEmitter( options.eventBus );\n\tthis.scrollEndEventEmitter.on( ScrollEndEventEmitter.EVENT_SCROLL_END,\n\t\tthis._loadPages.bind( this ) );\n\n\tif ( options.el ) {\n\t\tlastTitle = this.getLastTitle( options.el );\n\t}\n\tthis.gateway = new WatchListGateway( options.api, lastTitle );\n\n\tWatchstarPageList.call( this, options );\n}\n\nmfExtend( WatchList, WatchstarPageList, {\n\t/**\n\t * @inheritdoc\n\t * @memberof WatchList\n\t * @instance\n\t */\n\tpreRender: function () {\n\t\t// The DOM will be modified. Prevent any false scroll end events from\n\t\t// being emitted.\n\t\tthis.scrollEndEventEmitter.disable();\n\t\tthis.scrollEndEventEmitter.setElement( this.$el );\n\t},\n\t/**\n\t * Also sets a watch uploads funnel.\n\t *\n\t * @inheritdoc\n\t * @memberof WatchList\n\t * @instance\n\t */\n\tpostRender: function () {\n\t\tvar\n\t\t\t$items,\n\t\t\tstatuses;\n\n\t\t// Skip a level from WatchstarPageList directly to PageList.\n\t\tPageList.prototype.postRender.apply( this );\n\n\t\t$items = this.queryUnitializedItems();\n\n\t\t// WatchList requests list of watched pages. The list contains only\n\t\t// watched pages so it's safe to transform the title map to a status map\n\t\t// with each entry marked watched (true).\n\t\tstatuses = Object.keys( this.parsePagesFromItems( $items ) )\n\t\t\t.reduce( function ( arr, title ) {\n\t\t\t\tarr[ title ] = true;\n\t\t\t\treturn arr;\n\t\t\t}, {} );\n\t\tthis.renderItems( $items, statuses );\n\n\t\t// The list has been extended. Re-enable scroll end events.\n\t\tthis.scrollEndEventEmitter.enable();\n\t},\n\n\t/**\n\t * Loads pages from the api and triggers render.\n\t * Infinite scroll is re-enabled in postRender.\n\t *\n\t * @memberof WatchList\n\t * @instance\n\t */\n\t_loadPages: function () {\n\t\tthis.gateway.loadWatchlist().then( function ( pages ) {\n\t\t\tpages.forEach( function ( page ) {\n\t\t\t\tthis.appendPage( page );\n\t\t\t}.bind( this ) );\n\t\t\tthis.render();\n\t\t}.bind( this ) );\n\t},\n\n\t/**\n\t * Appends a list item\n\t *\n\t * @memberof WatchList\n\t * @instance\n\t * @param {Page} page\n\t */\n\tappendPage: function ( page ) {\n\t\t// wikidata descriptions should not show in this view.\n\t\tvar templateOptions = util.extend( {}, page, {\n\t\t\twikidataDescription: undefined\n\t\t} );\n\t\tthis.$el.append( this.templatePartials.item.render( templateOptions ) );\n\t},\n\n\t/**\n\t * Get the last title from the rendered HTML.\n\t * Used for initializing the API\n\t *\n\t * @memberof WatchList\n\t * @instance\n\t * @param {jQuery.Object} $el Dom element of the list\n\t * @return {string}\n\t */\n\tgetLastTitle: function ( $el ) {\n\t\treturn $el.find( 'li' ).last().attr( 'title' );\n\t}\n} );\n\nmodule.exports = WatchList;\n","var\n\tpageJSONParser = require( '../mobile.startup/page/pageJSONParser' ),\n\tutil = require( '../mobile.startup/util' ),\n\textendSearchParams = require( '../mobile.startup/extendSearchParams' );\n\n/**\n * @class WatchListGateway\n * @param {mw.Api} api\n * @param {string} lastTitle of page listed in Watchlist to be used as a continuation parameter\n */\nfunction WatchListGateway( api, lastTitle ) {\n\tthis.api = api;\n\t// Try to keep it in sync with SpecialMobileWatchlist::LIMIT (php)\n\tthis.limit = 50;\n\n\tif ( lastTitle ) {\n\t\tthis.continueParams = {\n\t\t\tcontinue: 'gwrcontinue||',\n\t\t\tgwrcontinue: '0|' + lastTitle.replace( / /g, '_' )\n\t\t};\n\t\tthis.shouldSkipFirstTitle = true;\n\t} else {\n\t\tthis.continueParams = {\n\t\t\tcontinue: ''\n\t\t};\n\t\tthis.shouldSkipFirstTitle = false;\n\t}\n\n\tthis.canContinue = true;\n}\n\nWatchListGateway.prototype = {\n\t/**\n\t * Load the list of items on the watchlist\n\t *\n\t * @return {jQuery.Deferred}\n\t */\n\tloadWatchlist: function () {\n\t\tvar self = this,\n\t\t\tparams = extendSearchParams( 'watchlist', {\n\t\t\t\tprop: [ 'info', 'revisions' ],\n\t\t\t\trvprop: 'timestamp|user',\n\t\t\t\tgenerator: 'watchlistraw',\n\t\t\t\tgwrnamespace: '0',\n\t\t\t\tgwrlimit: this.limit\n\t\t\t}, this.continueParams );\n\n\t\tif ( this.canContinue === false ) {\n\t\t\treturn util.Deferred().resolve( [] );\n\t\t}\n\t\treturn this.api.get( params, {\n\t\t\turl: this.apiUrl\n\t\t} ).then( function ( data ) {\n\t\t\tif ( data.continue !== undefined ) {\n\t\t\t\tself.continueParams = data.continue;\n\t\t\t} else {\n\t\t\t\tself.canContinue = false;\n\t\t\t}\n\n\t\t\treturn self.parseData( data );\n\t\t} );\n\t},\n\n\t/**\n\t * Parse api response data into pagelist item format\n\t *\n\t * @param {Object[]} data\n\t * @return {Page[]}\n\t */\n\tparseData: function ( data ) {\n\t\tvar pages;\n\n\t\tif ( !data.query || !data.query.pages ) {\n\t\t\treturn [];\n\t\t}\n\n\t\tpages = data.query.pages;\n\n\t\t// Sort results alphabetically (the api map doesn't have any order). The\n\t\t// watchlist is ordered alphabetically right now.\n\t\tpages.sort( function ( p1, p2 ) {\n\t\t\treturn p1.title === p2.title ? 0 : ( p1.title < p2.title ? -1 : 1 );\n\t\t} );\n\n\t\t// If we requested from the last item of the previous page, we shall\n\t\t// remove the first result (to avoid it being repeated)\n\t\tif ( this.shouldSkipFirstTitle ) {\n\t\t\tpages = pages.slice( 1 );\n\t\t\tthis.shouldSkipFirstTitle = false;\n\t\t}\n\n\t\t// Transform the items to a sensible format\n\t\treturn pages.map( pageJSONParser.parse );\n\t}\n\n};\n\nmodule.exports = WatchListGateway;\n","/* global $ */\nvar WatchList = require( './WatchList' ),\n\teventBus = require( '../mobile.startup/eventBusSingleton' ),\n\tVIEW_OPTION_NAME = 'mfWatchlistView',\n\tuserOptions = mw.user.options.get(),\n\tFILTER_OPTION_NAME = 'mfWatchlistFilter';\n\n/**\n * Initialises JavaScript on Special:Watchlist\n */\nfunction init() {\n\tvar $watchlist = $( 'ul.mw-mf-watchlist-page-list' );\n\n\t// FIXME: find more elegant way to not show watchlist stars on recent changes\n\tif ( $( '.mw-mf-watchlist-selector' ).length === 0 ) {\n\t\t// eslint-disable-next-line no-new\n\t\tnew WatchList( {\n\t\t\tapi: new mw.Api(),\n\t\t\tel: $watchlist,\n\t\t\tfunnel: 'watchlist',\n\t\t\tskipTemplateRender: true,\n\t\t\teventBus: eventBus\n\t\t} );\n\t}\n\t// not needed now we have JS view which has infinite scrolling\n\t$watchlist.find( '.mw-mf-watchlist-more' ).remove();\n}\n\n$( function () {\n\tvar api = new mw.Api(),\n\t\tview = $( '.mw-mf-watchlist-button-bar .is-on a' ).data( 'view' ),\n\t\tfilter = $( '.mw-mf-watchlist-selector .selected a' ).data( 'filter' );\n\n\tinit();\n\t// Only save if the value has changed.\n\tif ( view !== userOptions[VIEW_OPTION_NAME] ) {\n\t\tapi.saveOption( VIEW_OPTION_NAME, view );\n\t}\n\tif ( filter && filter !== userOptions[FILTER_OPTION_NAME] ) {\n\t\tapi.saveOption( FILTER_OPTION_NAME, filter );\n\t}\n} );\n","var util = require( './util' ),\n\tmfExtend = require( './mfExtend' );\n\n/**\n * Class to assist a view in implementing infinite scrolling on some DOM\n * element. This module itself is only responsible for emitting an Event when\n * the bottom of an Element is scrolled to.\n *\n * @class ScrollEndEventEmitter\n * @mixins OO.EventEmitter\n *\n * Use this class in a view to help it do infinite scrolling.\n *\n * 1. Initialize it in the constructor `initialize` and listen to the\n *   EVENT_SCROLL_END event it emits (and call your loading function then)\n * 2. On preRender (once we have the DOM element) set it into the infinite\n *   scrolling object and disable it until we've loaded.\n * 3. Once you have loaded the list and put it in the DOM, enable the\n *   infinite scrolling detection.\n *   - Every time the scroller detection triggers a load, it auto disables\n *     to not trigger multiple times. After you have loaded, manually\n *     re-enable it.\n *\n * Example:\n *     @example\n *     <code>\n *       var\n *         mfExtend = require( './mfExtend' ),\n *         ScrollEndEventEmitter = require( './ScrollEndEventEmitter' ),\n *         eventBus = require( './eventBusSingleton' );\n *       mfExtend( PhotoList, View, {\n *         //...\n *         initialize: function ( options ) {\n *           this.gateway = new PhotoListGateway( {\n *             username: options.username\n *           } );\n *           // 1. Set up infinite scroll helper and listen to events\n *           this.scrollEndEventEmitter = new ScrollEndEventEmitter( eventBus, 1000 );\n *           this.scrollEndEventEmitter.on( ScrollEndEventEmitter.EVENT_SCROLL_END,\n *             this._loadPhotos.bind( this ) );\n *           View.prototype.initialize.apply( this, arguments );\n *         },\n *         preRender: function () {\n *           // 2. Disable until we've got the list rendered and set DOM el\n *           this.scrollEndEventEmitter.setElement( this.$el );\n *           this.scrollEndEventEmitter.disable();\n *         },\n *         _loadPhotos: function () {\n *           var self = this;\n *           this.gateway.getPhotos().then( function ( photos ) {\n *             // load photos into the DOM ...\n *             // 3. and (re-)enable infinite scrolling\n *             self.scrollEndEventEmitter.enable();\n *           } );\n *         }\n *       } );\n *     </code>\n *\n * @fires ScrollEndEventEmitter#ScrollEndEventEmitter-scrollEnd\n * @param {Object} eventBus object to listen for scroll:throttled events\n * @param {number} [threshold=100] distance in pixels used to calculate if scroll\n * position is near the end of the $el\n */\nfunction ScrollEndEventEmitter( eventBus, threshold ) {\n\tthis.threshold = threshold || 100;\n\tthis.eventBus = eventBus;\n\tthis.enable();\n\tOO.EventEmitter.call( this );\n}\nOO.mixinClass( ScrollEndEventEmitter, OO.EventEmitter );\n\n/**\n * Fired when scroll bottom has been reached.\n *\n * @event ScrollEndEventEmitter#ScrollEndEventEmitter-scrollEnd\n */\nScrollEndEventEmitter.EVENT_SCROLL_END = 'ScrollEndEventEmitter-scrollEnd';\n\nmfExtend( ScrollEndEventEmitter, {\n\t/**\n\t * Listen to scroll on window and notify this._onScroll\n\t *\n\t * @memberof ScrollEndEventEmitter\n\t * @instance\n\t * @private\n\t */\n\t_bindScroll: function () {\n\t\tif ( !this._scrollHandler ) {\n\t\t\tthis._scrollHandler = this._onScroll.bind( this );\n\t\t\tthis.eventBus.on( 'scroll:throttled', this._scrollHandler );\n\t\t}\n\t},\n\t/**\n\t * Unbind scroll handler\n\t *\n\t * @memberof ScrollEndEventEmitter\n\t * @instance\n\t * @private\n\t */\n\t_unbindScroll: function () {\n\t\tif ( this._scrollHandler ) {\n\t\t\tthis.eventBus.off( 'scroll:throttled', this._scrollHandler );\n\t\t\tthis._scrollHandler = null;\n\t\t}\n\t},\n\t/**\n\t * Scroll handler. Triggers load event when near the end of the container.\n\t *\n\t * @memberof ScrollEndEventEmitter\n\t * @instance\n\t * @private\n\t */\n\t_onScroll: function () {\n\t\tif ( this.$el && this.enabled && this.scrollNearEnd() ) {\n\t\t\t// Disable when triggering an event. Won't trigger again until\n\t\t\t// re-enabled.\n\t\t\tthis.disable();\n\t\t\tthis.emit( ScrollEndEventEmitter.EVENT_SCROLL_END );\n\t\t}\n\t},\n\t/**\n\t * Is the scroll position near the end of the container element?\n\t *\n\t * @memberof ScrollEndEventEmitter\n\t * @instance\n\t * @private\n\t * @return {boolean}\n\t */\n\tscrollNearEnd: function () {\n\t\tvar $window = util.getWindow(),\n\t\t\tscrollBottom = $window.scrollTop() + $window.height(),\n\t\t\tendPosition = this.$el.offset().top + this.$el.outerHeight();\n\t\treturn scrollBottom + this.threshold > endPosition;\n\t},\n\t/**\n\t * Enable the ScrollEndEventEmitter so that it triggers events.\n\t *\n\t * @memberof ScrollEndEventEmitter\n\t * @instance\n\t */\n\tenable: function () {\n\t\tthis.enabled = true;\n\t\tthis._bindScroll();\n\t},\n\t/**\n\t * Disable the ScrollEndEventEmitter so that it doesn't trigger events.\n\t *\n\t * @memberof ScrollEndEventEmitter\n\t * @instance\n\t */\n\tdisable: function () {\n\t\tthis.enabled = false;\n\t\tthis._unbindScroll();\n\t},\n\t/**\n\t * Set the element to compare to scroll position to\n\t *\n\t * @memberof ScrollEndEventEmitter\n\t * @instance\n\t * @param {jQuery.Object} $el jQuery element where we want to listen for\n\t * scroll end.\n\t */\n\tsetElement: function ( $el ) {\n\t\tthis.$el = $el;\n\t}\n} );\n\nmodule.exports = ScrollEndEventEmitter;\n"],"sourceRoot":""}