MinervaNeue/resources/skins.minerva.scripts/init.js

265 lines
7.7 KiB
JavaScript
Raw Normal View History

( function ( M, $ ) {
var inSample, inStable, experiment,
toast = M.require( 'mobile.startup/toast' ),
time = M.require( 'mobile.startup/time' ),
browser = M.require( 'mobile.startup/Browser' ).getSingleton(),
token = mw.storage.get( 'mobile-betaoptin-token' ),
BetaOptinPanel = M.require( 'mobile.betaoptin/BetaOptinPanel' ),
loader = M.require( 'mobile.startup/rlModuleLoader' ),
router = require( 'mediawiki.router' ),
context = M.require( 'mobile.startup/context' ),
OverlayManager = M.require( 'mobile.startup/OverlayManager' ),
overlayManager = new OverlayManager( require( 'mediawiki.router' ) ),
page = M.getCurrentPage(),
thumbs = page.getThumbnails(),
experiments = mw.config.get( 'wgMFExperiments' ) || {},
betaOptinPanel;
/**
* Event handler for clicking on an image thumbnail
* @param {jQuery.Event} ev
* @ignore
*/
function onClickImage( ev ) {
ev.preventDefault();
router.navigate( '#/media/' + encodeURIComponent( $( this ).data( 'thumb' ).getFileName() ) );
}
/**
* Add routes to images and handle clicks
* @method
* @ignore
*/
function initMediaViewer() {
thumbs.forEach( function ( thumb ) {
thumb.$el.off().data( 'thumb', thumb ).on( 'click', onClickImage );
} );
}
/**
* Hijack the Special:Languages link and replace it with a trigger to a LanguageOverlay
* that displays the same data
* @ignore
*/
function initButton() {
// This catches language selectors in page actions and in secondary actions (e.g. Main Page)
var $primaryBtn = $( '.language-selector' );
if ( $primaryBtn.length ) {
// We only bind the click event to the first language switcher in page
$primaryBtn.on( 'click', function ( ev ) {
ev.preventDefault();
if ( $primaryBtn.attr( 'href' ) || $primaryBtn.find( 'a' ).length ) {
router.navigate( '/languages' );
} else {
toast.show( mw.msg( 'mobile-frontend-languages-not-available' ) );
}
} );
}
}
/**
* Return the language code of the device in lowercase
*
* @ignore
* @return {string|undefined}
*/
function getDeviceLanguage() {
var lang = navigator && navigator.languages ?
navigator.languages[0] :
navigator.language || navigator.userLanguage ||
navigator.browserLanguage || navigator.systemLanguage;
return lang ? lang.toLowerCase() : undefined;
}
/**
* Loads tablet modules when the skin is in tablet mode and the
* current page is in the main namespace.
* @method
* @ignore
*/
function loadTabletModules() {
if ( browser.isWideScreen() && page.inNamespace( '' ) ) {
mw.loader.using( 'skins.minerva.tablet.scripts' );
}
}
/**
* Load image overlay
* @method
* @ignore
* @uses ImageOverlay
* @param {string} title Url of image
* @return {jQuery.Deferred}
*/
function loadImageOverlay( title ) {
if ( mw.loader.getState( 'mmv.bootstrap' ) === 'ready' ) {
// This means MultimediaViewer has been installed and is loaded.
// Avoid loading it (T169622)
return $.Deferred().reject();
} else {
return loader.loadModule( 'mobile.mediaViewer' ).then( function () {
var ImageOverlay = M.require( 'mobile.mediaViewer/ImageOverlay' );
return new ImageOverlay( {
api: new mw.Api(),
thumbnails: thumbs,
title: decodeURIComponent( title )
} );
} );
}
}
// Routes
overlayManager.add( /^\/media\/(.+)$/, loadImageOverlay );
overlayManager.add( /^\/languages$/, function () {
var result = $.Deferred(),
lang = mw.config.get( 'wgUserLanguage' );
loader.loadModule( 'mobile.languages.structured', true ).done( function ( loadingOverlay ) {
var PageGateway = M.require( 'mobile.startup/PageGateway' ),
gateway = new PageGateway( new mw.Api() ),
LanguageOverlay = M.require( 'mobile.languages.structured/LanguageOverlay' );
gateway.getPageLanguages( mw.config.get( 'wgPageName' ), lang ).done( function ( data ) {
loadingOverlay.hide();
result.resolve( new LanguageOverlay( {
currentLanguage: mw.config.get( 'wgContentLanguage' ),
languages: data.languages,
variants: data.variants,
deviceLanguage: getDeviceLanguage()
} ) );
} );
} );
return result;
} );
// Setup
$( function () {
initButton();
initMediaViewer();
} );
// Access the beta optin experiment if available.
experiment = experiments.betaoptin || false;
// local storage is supported in this case, when ~ means it was dismissed
if ( experiment && token !== false && token !== '~' && !page.isMainPage() && !page.inNamespace( 'special' ) ) {
if ( !token ) {
token = mw.user.generateRandomSessionId();
mw.storage.set( 'mobile-betaoptin-token', token );
}
inStable = context.getMode() === 'stable';
inSample = mw.experiments.getBucket( experiment, token ) === 'A';
if ( inStable && ( inSample || mw.util.getParamValue( 'debug' ) ) ) {
betaOptinPanel = new BetaOptinPanel( {
postUrl: mw.util.getUrl( 'Special:MobileOptions', {
returnto: page.title
} )
} )
.on( 'hide', function () {
mw.storage.set( 'mobile-betaoptin-token', '~' );
} )
.appendTo( M.getCurrentPage().getLeadSectionElement() );
}
}
// let the interested parties know whether the panel is shown
mw.track( 'minerva.betaoptin', {
isPanelShown: betaOptinPanel !== undefined
} );
/**
* Initialisation function for last modified module.
*
* Enhances an element representing a time
* to show a human friendly date in seconds, minutes, hours, days
* months or years
* @ignore
* @param {JQuery.Object} [$lastModifiedLink]
*/
function initHistoryLink( $lastModifiedLink ) {
var delta, historyUrl, msg, $bar,
ts, username, gender;
historyUrl = $lastModifiedLink.attr( 'href' );
ts = $lastModifiedLink.data( 'timestamp' );
username = $lastModifiedLink.data( 'user-name' ) || false;
gender = $lastModifiedLink.data( 'user-gender' );
if ( ts ) {
delta = time.getTimeAgoDelta( parseInt( ts, 10 ) );
if ( time.isRecent( delta ) ) {
$bar = $lastModifiedLink.closest( '.last-modified-bar' );
$bar.addClass( 'active' );
// in beta update icons to be inverted
$bar.find( '.mw-ui-icon' ).each( function () {
$( this ).attr( 'class', $( this ).attr( 'class' ).replace( '-gray', '-invert' ) );
} );
}
msg = time.getLastModifiedMessage( ts, username, gender, historyUrl );
$lastModifiedLink.replaceWith( msg );
}
}
/**
* Initialisation function for last modified times
*
* Enhances .modified-enhancement element
* to show a human friendly date in seconds, minutes, hours, days
* months or years
* @ignore
*/
function initModifiedInfo() {
$( '.modified-enhancement' ).each( function () {
initHistoryLink( $( this ) );
} );
}
/**
* Initialisation function for user creation module.
*
* Enhances an element representing a time
+ to show a human friendly date in seconds, minutes, hours, days
* months or years
* @ignore
* @param {JQuery.Object} [$tagline]
*/
function initRegistrationDate( $tagline ) {
var msg, ts;
ts = $tagline.data( 'userpage-registration-date' );
if ( ts ) {
msg = time.getRegistrationMessage( ts, $tagline.data( 'userpage-gender' ) );
$tagline.text( msg );
}
}
/**
* Initialisation function for registration date on user page
*
* Enhances .tagline-userpage element
* to show human friendly date in seconds, minutes, hours, days
* months or years
* @ignore
*/
function initRegistrationInfo() {
$( '#tagline-userpage' ).each( function () {
initRegistrationDate( $( this ) );
} );
}
$( function () {
// Update anything else that needs enhancing (e.g. watchlist)
initModifiedInfo();
initRegistrationInfo();
initHistoryLink( $( '.last-modifier-tagline a' ) );
M.on( 'resize', loadTabletModules );
loadTabletModules();
} );
M.define( 'skins.minerva.scripts/overlayManager', overlayManager );
}( mw.mobileFrontend, jQuery ) );