%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 ) );