User:TheDJ/mobilemaps.js

// See also: https://github.com/wikimedia/mediawiki-extensions-Kartographer/blob/master/modules/maplink/maplink.js

// Partly based on meta:MediaWiki:Wikiminiatlas.js

( function ( $, mw ) {

var geohacklinks = [],

routerInited = false,

geohackUrl = '//tools.wmflabs.org/geohack/';

if( !window.wma_settings ) {

window.wma_settings = {};

}

// Try to disable wikiminiatlas

window.wma_settings.enabled = false;

function setupKartographer($content) {

var geolinks = document.querySelectorAll('[href^="' + geohackUrl + '"]' );

if( !geolinks.length) {

return;

}

mw.loader.using( [

'mediawiki.router',

'ext.kartographer.linkbox',

'ext.kartographer.style'

] ).then( function( require ) {

var router = require( 'mediawiki.router' );

var kartolink = require( 'ext.kartographer.linkbox' );

var uri, title, coord_params, coord_digits, lat, lon, globe, link,

geohack, zoomlevel, marker, marker_symbol;

var geohack_link_filter = /¶ms=([\d.+-]+)_([\d.+-]*)_?([\d.+-]*)_?([NSZ])_([\d.+-]+)_([\d.+-]*)_?([\d.+-]*)_?([EOW])([^&=<>|]{0,250})/;

var globeRegExp = /_globe:([^_&]+)/;

var typeRegExp = /_type:(country|satellite|state|adm1st|adm2nd|adm3rd|city|isle|river|waterbody|event|glacier|mountain|airport|edu|pass|landmark|railwaystation)/;

var dimRegExp = /_dim:([\d.+-]+)(km|m|_|$)/;

var scaleRegExp = /_scale:(\d+)(_|$)/;

Array.prototype.forEach.call(geolinks, function (elem, index) {

if ( !('href' in elem) || !geohack_link_filter.exec(elem.href)) {

return;

}

coord_params = [];

lat = lon = 0;

globe = 'Earth';

zoomlevel = 12;

marker_symbol = 'marker';

// Convert DMS to DD if needed

lat = (1.0*RegExp.$1) + ((RegExp.$2||0)/60.0) + ((RegExp.$3||0)/3600.0);

if (RegExp.$4!=='N') {

lat *= -1;

}

lon = (1.0*RegExp.$5) + ((RegExp.$6||0)/60.0) + ((RegExp.$7||0)/3600.0);

if (RegExp.$8==='W') {

lon *= -1;

}

coord_params = RegExp.$9;

// Zoom based on coordinate N/S precision

coord_digits = RegExp.$3 ? 4 : RegExp.$2 ? 2 : RegExp.$1.length - (RegExp.$1+'.').indexOf('.') - 1;

zoomlevel = coord_digits * Math.log(10)/Math.log(2);

// Zoom level based on type, and retrieving markers symbols for those types

if( typeRegExp.exec( coord_params ) ) {

type = RegExp.$1;

switch( type ) {

case 'country':

case 'satellite':

zoomlevel = 5;

break;

case 'state':

zoomlevel = 7;

break;

case 'adm1st':

zoomlevel = 9;

break;

case 'adm2nd':

zoomlevel = 11;

break;

case 'adm3rd':

case 'city':

zoomlevel = 12;

marker_symbol = 'city';

break;

case 'isle':

case 'river':

case 'waterbody':

zoomlevel = 12;

break;

case 'event':

case 'glacier':

case 'mountain':

zoomlevel = 13;

break;

case 'airport':

zoomlevel = 14;

marker_symbol = 'airport';

break;

case 'railwaystation':

marker_symbol = 'rail';

break;

case 'camera edu':

case 'pass':

case 'landmark':

zoomlevel = 15;

break;

default:

}

}

// wma shows dim approx 4e7m at zoom 0 or 1.5e8 is the scale of zoomlevel 0

if (dimRegExp.exec(coord_params)) {

zoomlevel = Math.log((RegExp.$2==='km' ? 4e4 : 4e7) / RegExp.$1)/Math.log(2);

}

if (scaleRegExp.exec(coord_params)) {

zoomlevel = Math.log(1.5e8/RegExp.$1) / Math.log(2);

}

if (zoomlevel<0) { zoomlevel = 0; }

// Check which globe

if (globeRegExp.test(coord_params)) {

globe = RegExp.$1;

// All possible globes: ['Earth','Moon','Mars','Venus','Mercury','Io','Titan']

// But we only handle Earth right now

if( globe.toLowerCase() !== 'earth' ) {

return;

}

}

// Retrieve the pagename from the uri if possible

uri = new URL(elem.href, location.origin);

title = uri.query.pagename;

if(title) {

title = title.replace(/_/g,' ');

}

marker = {

"type": "Feature",

"geometry": {

"type": "Point",

"coordinates": [lon, lat]

},

"properties": {

"name": title,

"marker-color": "#3366cc",

"marker-symbol": marker_symbol,

"marker-size": "medium"

}

};

link = geohacklinks[ index ] = kartolink.link( {

featureType: 'maplink',

container: elem,

center: [ lat, lon ],

zoom: zoomlevel,

data: [marker],

captionText: title,

fullScreenRoute: '/geohacklink/' + index

} );

$(elem).addClass('mw-kartographer-maplink').parent().removeClass('plainlinks');

});

if ( routerInited ) {

return;

}

// execute this piece of code only once

routerInited = true;

// Opens a maplink in full screen. #/geohacklink(/:zoom)(/:latitude)(/:longitude)

// Examples:

// #/geohacklink/0

// #/geohacklink/0/5

// #/geohacklink/0/16/-122.4006/37.7873

router.route( /geohacklink\/([0-9]+)(?:\/([0-9]+))?(?:\/([+-]?\d+\.?\d{0,5})?\/([+-]?\d+\.?\d{0,5})?)?/, function ( maptagId, zoom, latitude, longitude ) {

var link = geohacklinks[ maptagId ],

position;

if ( !link ) {

router.navigate( '' );

return;

}

if ( zoom !== undefined && latitude !== undefined && longitude !== undefined ) {

position = {

center: [ +latitude, +longitude ],

zoom: +zoom

};

}

// // We need this hack to differentiate these events from `open` events.

// if ( !link.fullScreenMap && !link.clicked ) {

// mw.track( 'mediawiki.kartographer', {

// action: 'hashopen',

// isFullScreen: true,

// feature: link

// } );

// link.clicked = false;

// }

link.openFullScreen( position );

} );

// Check if we need to open a map in full screen.

router.checkRoute();

});

if( $( '#coordinates' ).length && mw.config.get('skin') === 'minerva' ) {

mw.loader.using( [

'mediawiki.util',

'oojs-ui.styles.icons-location'

] ).then( function() {

mw.util.addCSS(

'#page-actions .mw-show-on-map {' +

' opacity: 0.6;' +

'}'

);

var mapButton = $('

  • ')

    .addClass('page-actions-menu__list-item')

    .removeClass( 'language-selector mw-ui-icon-language-switcher' )

    .append(

    $('').addClass( 'mw-ui-icon mw-ui-icon-element mw-ui-icon-with-label-desktop mw-show-on-map mw-ui-icon-map' ) /*T240644*/

    .attr( {

    href: '', /* empty href to avoid minerva adding ... */

    title: 'Show on map',

    role: 'button'

    } )

    .text( ' Map' )

    .click( openTitleCoord )

    );

    $( '.page-actions-menu__list > li:first-child' ).after( mapButton );

    } );

    }

    }

    var openTitleCoord = function() {

    $( '#coordinates .mw-kartographer-link' ).get( 0 ).click();

    };

    mw.hook( 'wikipage.content' ).add( setupKartographer );

    return geohacklinks;

    }(

    jQuery,

    mediaWiki

    ));