%PDF- %PDF-
Direktori : /www/varak.net/wiki.varak.net/extensions/MobileFrontend/resources/mobile.nearby/ |
Current File : /www/varak.net/wiki.varak.net/extensions/MobileFrontend/resources/mobile.nearby/Nearby.js |
( function ( M ) { /** @event */ var NEARBY_EVENT_POST_RENDER = 'Nearby-postRender', MessageBox = M.require( 'mobile.messageBox/MessageBox' ), NearbyGateway = M.require( 'mobile.nearby/NearbyGateway' ), util = M.require( 'mobile.startup/util' ), WatchstarPageList = M.require( 'mobile.pagelist.scripts/WatchstarPageList' ); /** * List of nearby pages * @class Nearby * @uses NearbyGateway * @extends WatchstarPageList * * @param {Object} options Configuration options * @param {Function} [options.onItemClick] Callback invoked when a result is * clicked. Defaults to nop. */ 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 ); } this.onItemClick = options.onItemClick; _super.apply( this, arguments ); } OO.mfExtend( Nearby, WatchstarPageList, { /** * @memberof Nearby * @instance */ errorMessages: { empty: { heading: mw.msg( 'mobile-frontend-nearby-noresults' ), hasHeading: true, msg: mw.msg( 'mobile-frontend-nearby-noresults-guidance' ) }, http: { heading: mw.msg( 'mobile-frontend-nearby-error' ), hasHeading: true, msg: mw.msg( 'mobile-frontend-nearby-error-guidance' ) }, incompatible: { heading: mw.msg( 'mobile-frontend-nearby-requirements' ), hasHeading: true, msg: mw.msg( 'mobile-frontend-nearby-requirements-guidance' ) } }, /** * @memberof Nearby * @instance */ templatePartials: util.extend( {}, WatchstarPageList.prototype.templatePartials, { pageList: WatchstarPageList.prototype.template, messageBox: MessageBox.prototype.template } ), /** * @memberof Nearby * @instance */ template: mw.template.get( 'mobile.nearby', 'Nearby.hogan' ), /** * @memberof Nearby * @instance * @mixes WatchstarPageList#defaults * @property {Object} defaults Default options hash. * @property {mw.Api} defaults.api * @property {Object} defaults.errorOptions options to pass to a messagebox template * tells the user that their location is being looked up */ defaults: util.extend( {}, WatchstarPageList.prototype.defaults, { errorOptions: undefined } ), /** * Request pages from api based on provided options. * When options.longitude and options.latitude set getPages near that location. * If those are not present use options.title to find pages near that title. * If no valid options given resolve return object with error message. * @memberof Nearby * @instance * @param {Object} options Configuration options * @return {jQuery.Deferred} * @private */ _find: function ( options ) { var result = util.Deferred(), self = this; /** * Handler for successful query * @param {Array} pages as passed by then callback of Nearby##getPages */ function pagesSuccess( pages ) { options.pages = pages; if ( pages && pages.length === 0 ) { options.errorOptions = self._errorOptions( 'empty' ); } self._isLoading = false; result.resolve( options ); } /** * Handler for failed query * * @param {string} code Error Code */ function pagesError( code ) { self._isLoading = false; options.errorOptions = self._errorOptions( code ); result.resolve( options ); } if ( options.latitude && options.longitude ) { this.nearbyApi.getPages( { latitude: options.latitude, longitude: options.longitude }, this.range, options.exclude ).then( pagesSuccess, pagesError ); } else if ( options.pageTitle ) { this.nearbyApi.getPagesAroundPage( options.pageTitle, this.range ) .then( pagesSuccess, pagesError ); } else { if ( options.errorType ) { options.errorOptions = this._errorOptions( options.errorType ); } result.resolve( options ); } return result; }, /** * Generate a list of options that can be passed to a messagebox template. * @memberof Nearby * @instance * @private * @param {string} key to a defined error message * @param {string} msg Message to use, instead of a mapped error message * from this.errorMessages * @return {Object} */ _errorOptions: function ( key ) { var message = this.errorMessages[ key ] || this.errorMessages.http; return util.extend( { className: 'errorbox' }, message ); }, /** * @inheritdoc * @memberof Nearby * @instance */ postRender: function () { if ( !this._isLoading ) { this.$( '.page-list' ).removeClass( 'hidden' ); } WatchstarPageList.prototype.postRender.apply( this ); this._postRenderLinks(); this.$( function () { // todo: use the local emitter when refresh() doesn't recreate the // OO.EventEmitter by calling the super's constructor. M.emit( NEARBY_EVENT_POST_RENDER ); } ); }, /** * Hijack links to apply several customisations to them: * Ensure that when clicked they register an uploads funnel. * Ensure that when a user navigates back to the page their page position is restored using * fragment identifier trickery. * @private * @memberof Nearby * @instance */ _postRenderLinks: function () { var self = this; this.$( 'a' ).each( function ( i ) { // FIXME: not unique if multiple Nearby objects on same page self.$( this ).attr( 'id', 'nearby-page-list-item-' + i ); } ).on( 'click', this.onItemClick ); }, /** * Refresh the list of the nearby articles depending on the options. * The current location, latitude/longitude, or page title can be used * to find the articles. * @memberof Nearby * @instance * @param {Object} options Configuration options * @throws {Error} If Nearby has not been initialised correctly. * @return {jQuery.Deferred} */ refresh: function ( options ) { var self = this, _super = WatchstarPageList; this.$( '.page-list' ).addClass( 'hidden' ); // Run it once for loader etc this._isLoading = true; if ( ( options.latitude && options.longitude ) || options.pageTitle ) { // Flush any existing list of pages options.pages = []; // Get some new pages return this._find( options ).then( function ( options ) { _super.call( self, options ); }, function ( errorType ) { options.errorOptions = self._errorOptions( errorType ); self._isLoading = false; _super.call( self, options ); } ); } else { throw new Error( 'No title or longitude, latitude options have been passed' ); } } } ); M.define( 'mobile.nearby/Nearby', Nearby ); }( mw.mobileFrontend ) );