MediaWiki:Gadget-mobilemaps.js
Appearance
This page is loaded as a part of the MobileMaps gadget, used by 4,243 users. |
// 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 mw.Uri( elem.href );
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, #p-views .mw-show-on-map {' +
' opacity: 0.6;' +
'}'
);
var mapButton = $('<li>')
.addClass('page-actions-menu__list-item')
.removeClass( 'language-selector mw-ui-icon-language-switcher' )
.append(
$('<a>').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 );
} );
}
}
function openTitleCoord( e ) {
e.preventDefault(); /*T247664*/
$( '#coordinates .mw-kartographer-link' ).get( 0 ).click();
};
mw.hook( 'wikipage.content' ).add( setupKartographer );
return geohacklinks;
}(
jQuery,
mediaWiki
));