MediaWiki:MarkerTooltip-es.js
Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Internet Explorer/Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
- Opera: Strg+F5
//<nowiki>
/***************************************************************************
* MarkerTooltip.js v1.4, 2021-05-02
* Displays an extended marker tooltip on mouse over on desktops
* or on click on smartphones
* Displays tooltip for abbreviations on smartphones
* Original author: Roland Unger
* Support of both desktop and mobile views
* Documentation: https://de.wikivoyage.org/wiki/Wikivoyage:MarkerTooltip.js
* License: GPL-2.0+, CC-by-sa 3.0
***************************************************************************/
( function ( $ ) {
'use strict';
var mkTooltip = function() {
var wmflabsToolsURL = 'https://tools.wmflabs.org/geohack/geohack.php?';
var wvToolsURL = '/w/index.php?title=Special%3AMapsources';
var maxZoomLevel = 19; // see also getScaleFromZoom
var mapHint = '<b>Haga clic aquí para abrir el mapa</b>';
var decLabel = 'Decimal';
var decTitle = 'La coordenada sigue en forma decimal. Se puede iniciar una aplicación de mapas a través del enlace Geo-URI adyacente.';
var geoUriTitle = 'El navegador inicia una aplicación de mapas a través de este enlace, p. ej. mapas de Google. Ya está configurado en muchos teléfonos inteligentes Android.';
var hexLabel = 'GMS';
var hexTitle = 'La coordenada sigue en forma de grados-minutos-segundos.';
var plusLabel = 'Plus Code';
var plusTitle = 'La coordenada sigue como un código de ubicación abierto.';
var ch1903Label = 'CH1903';
var ch1903Title = 'A esto le sigue la coordenada en forma de coordenadas nacionales suizas.';
var toolsLabel = 'Instrumentos';
var toolsTitle = 'A continuación se muestran varias Enlace a de plantilla.';
var templateId = 'Ancla';
var templateIdLabel = 'Muestra el nombre del ancla de la plantilla.';
var templateIdText = 'El nombre del ancla de la plantilla es:\n\n';
var linkTo = 'Enlace a';
var wvTools = 'instrumentos de Wikiviajes';
var wvToolsTitle = 'Abre un sitio web de Wikiviajes que enumera numerosas fuentes y instrumentos de mapas.';
var wmflabsTools = 'instrumentos de WMF Labs';
var wmflabsToolsTitle = 'Abre un sitio web de WMF Labs que enumera numerosas fuentes y instrumentos de mapas.';
var copyTitle = 'Copia la información opuesta al portapapeles. Desafortunadamente, los navegadores más antiguos en particular no admiten esta función.';
var clipboard = 'Portapapeles';
var NS = 'NS';
var EW = 'EO'; // international: 'EW'
var isMobile = false;
var timeouts = [];
var wrapper;
// Only n digits
var round = function( coord, n ) {
var m = Math.pow( 10, n );
return Math.round( coord * m ) / m;
};
// Converting decimal to DMS coordinates
var toDMS = function( dec, letters ) {
var deg, min, sec, letter;
if ( dec < 0 )
letter = letters.charAt( 1 );
else
letter = letters.charAt( 0 );
var angle = Math.abs( dec );
deg = Math.floor( angle );
min = ( angle - deg ) * 60;
sec = Math.round( ( min - Math.floor( min ) ) * 60 );
min = Math.floor( min );
if ( sec >= 60 ) {
sec -= 60;
min += 1;
}
if ( min >= 60 ) {
min -= 60;
deg += 1;
}
return deg + '° ' + min + '′ ' + sec + '″ ' + letter;
};
// Converting decimal to CH1903 coordinates
// see: https://de.wikipedia.org/wiki/Schweizer_Landeskoordinaten
var toCH1903 = function( lat, lon ) {
var ch1903 = {
easting: 0,
northing: 0,
error: true
};
if ( lat < 45.5 || lat > 48 || lon < 5.0 || lon > 11 )
return ch1903;
var phi = ( lat * 3600 - 169028.66 ) / 10000;
var phi2 = phi * phi;
var lambda = ( lon * 3600 - 26782.5 ) / 10000;
var lambda2 = lambda * lambda;
ch1903.northing = Math.round( 200147.07 + 308807.95 * phi + 3745.25 * lambda2 +
76.63 * phi2 - 194.56 * lambda2 * phi + 119.79 * phi2 * phi );
ch1903.easting = Math.round( 600072.37 + 211455.93 * lambda - 10938.51 * lambda * phi -
0.36 * lambda * phi2 - 44.54 * lambda2 * lambda );
ch1903.error = false;
return ch1903;
};
// Converting decimal to Open Location Code (Plus Code)
// see: https://en.wikipedia.org/wiki/Open_Location_Code
var toPlusCode = function( lat, lon ) {
var codeChars = '23456789CFGHJMPQRVWX';
var resolutions = [ 20.0, 1.0, 0.05, 0.0025, 0.000125 ];
var code = '';
var modLat = lat;
modLat = Math.max( -90, modLat );
modLat = Math.min( modLat, 90 - 0.000025 );
// 0.000025 = resolutions[ 4 ] / 5 [rows]
modLat += 90; // starting from 0
var modLon = lon;
while ( modLon < -180 )
modLon += 360;
while ( modLon >= 180 )
modLon -= 360;
modLon += 180; // starting from 0
// first 10 + 1 digits
var col, digit, i, latRes, lonRes, res, row;
for ( i = 0; i < 5; i++ ) {
res = resolutions[ i ];
digit = Math.floor( modLat / res );
modLat -= digit * res;
code += codeChars.charAt( digit );
digit = Math.floor( modLon / res );
modLon -= digit * res;
code += codeChars.charAt( digit );
if ( i === 3 )
code += '+';
}
// last digit
latRes = res; // resolutions[ 4 ]
lonRes = res;
latRes /= 5;
lonRes /= 4;
row = Math.floor( modLat / latRes );
col = Math.floor( modLon / lonRes );
code += codeChars.charAt( 4 * row + col );
return code;
};
// zoom level 19 -> 1:1000, 0 -> 500000000
var getScaleFromZoom = function( zoom ) {
var scales = [ 1000, 2000, 4000, 8000, 15000, 35000, 70000, 150000, 250000,
500000, 1000000, 2000000, 4000000, 10000000, 15000000, 35000000, 70000000,
150000000, 250000000, 500000000 ];
if ( zoom >= maxZoomLevel )
return scales[ 0 ];
if ( zoom <= 0 )
return scales[ scales.length - 1 ];
return scales[ maxZoomLevel - Math.round( zoom ) ];
};
var copyToClipboard = function( selector, container ) {
var clipboard = $( '<textarea id="mkClipboard"></textarea>' )
.css( { 'width': 1, 'border': 'none', 'opacity': 0 } );
$( 'body' ).append( clipboard );
var text = ( selector !== '.mkClip5' ) ? $( selector, container ).text()
: $( '#templateId', container ).text();
clipboard.val( text ).select();
document.execCommand( 'copy' );
clipboard.remove();
};
var clipboardLink = function( aClass ) {
return mw.format( '[ <a href="javascript:" class="$1" title="$2">$3</a> ]',
aClass, copyTitle, clipboard );
};
var makeTableRow = function( label, title, clipClass, buttonClass, text ) {
return mw.format( '<tr><td><span title="$1">$2:</span> <span class="$3">$4</span></td><td>$5</td></tr>',
title, label, clipClass, text, clipboardLink( buttonClass ) );
};
var makeContent = function( $origin ) {
var link = $( '.mw-kartographer-maplink', $origin ).first();
var lat = round( link.attr( 'data-lat' ), 6 );
var latStr = toDMS( lat, NS );
var lon = round( link.attr( 'data-lon' ), 6 );
var lonStr = toDMS( lon, EW );
var zoom = link.attr( 'data-zoom' );
wrapper = $origin.closest( '.vcard' );
var color = wrapper.attr( 'data-color' );
var lang = wrapper.attr( 'data-wikilang' );
var region = wrapper.attr( 'data-region' );
if ( !region )
region = '';
var name = wrapper.attr( 'data-name' );
if ( !name ) {
name = $( '.listing-name', wrapper ).first();
var wikiLink = $( 'a', name ).first();
if ( wikiLink.length )
name = wikiLink.text();
else
name = name.text();
}
name = encodeURI( name.replace( /\s/g, '+' ) ).replace( /&/g, '%26' );
var id = $( '.listing-name', wrapper ).attr( 'id' );
var params = '¶ms=';
if ( lat < 0 )
params += Math.abs( lat ) + '_S_';
else
params += lat + '_N_';
if ( lon < 0 )
params += Math.abs( lon ) + '_W';
else
params += lon + '_E';
params += '_scale%3A' + getScaleFromZoom( zoom )
+ '_type%3Alandmark_globe%3Aearth';
if ( region !== '' )
params += '_region%3A' + region;
var ch1903 = toCH1903( lat, lon );
var plusCode = toPlusCode( lat, lon );
var table = '<table>'
+ makeTableRow( hexLabel, hexTitle, 'mkClip1', 'mkButton1',
latStr + ' ' + lonStr )
+ makeTableRow( decLabel, decTitle, 'mkClip2', 'mkButton2',
'<a href="geo:' + lat + ',' + lon + '" title="'
+ geoUriTitle + '">' + lat + ', ' + lon + '</a>' )
+ makeTableRow( plusLabel, plusTitle, 'mkClip3', 'mkButton3',
'<span class="plusCode">' + plusCode.substr( 0, 4 ) + '</span>'
+ plusCode.substr( 4 ) );
if ( !ch1903.error )
table += makeTableRow( ch1903Label, ch1903Title,
'mkClip4', 'mkButton4', '<span title="CH1903 easting">'
+ ch1903.easting + '</span> / <span title="CH1903 northing">'
+ ch1903.northing + '</span>' );
if ( id ) {
var html = [];
var infobutton = $( '.listing-info-button a', wrapper ).prop( 'outerHTML' ) || '';
if ( infobutton !== '' )
html.push( '<span id="infobutton">' + infobutton + '</span>' );
var editbutton = $( '.listing-edit-button a', wrapper ).prop( 'outerHTML' ) || '';
if ( editbutton !== '' )
html.push( '<span id="editbutton">' + editbutton + '</span>' );
html.push( mw.format( '<a href="javascript:" id="templateIdLink" title="$1">$2</a><span id="templateId" style="display: none">$3</span>',
templateIdLabel, templateId, id ) );
table += makeTableRow( toolsLabel, toolsTitle,
'mkClip5', 'mkButton5', html.join( ' | ' ) );
}
table += '</table>';
return $( '<div class="mkTooltipInner"></div>' )
.css( 'border-left-color', color )
.append( $( '<div>' + mapHint + '</div>' )
.css( { 'margin-bottom': '0.5em' } ) )
.append( $( table ) )
.append( $( mw.format( '<div>$1 <a href="$2&locname=$3" title="$4" target="_blank" rel="noopener">$5</a></div>',
linkTo, wvToolsURL + params, name, wvToolsTitle, wvTools ) ) )
.append( $( mw.format( '<div>$1 <a href="$2pagename=$3&language=$4" title="$5" target="_blank" rel="noopener">$6</a></div>',
linkTo, wmflabsToolsURL, name, lang + params, wmflabsToolsTitle, wmflabsTools ) ) )
.append( $( '<div class="mkTooltipTail"></div>' ) );
};
// setting tooltip position
var setTooltipPosition = function( e, tooltip, $this ) {
var tail = $( '.mkTooltipTail', tooltip ), left, offset, right, width;
var winWidth = $( window ).width();
if ( e.clientY < $( window ).height() / 2 )
tooltip.css( 'top', $this.innerHeight() - 4 )
.addClass('mkBelow');
else
tooltip.css( 'bottom', $this.innerHeight() - 4 )
.addClass('mkAbove');
if ( e.clientX < winWidth / 2 ) {
tooltip.css( 'left', $this.innerWidth() / 2 - 16 )
.addClass('mkLeft');
if ( isMobile ) {
offset = tooltip.offset();
right = offset.left + tooltip.outerWidth();
if ( right > winWidth - 1 ) {
left = offset.left - ( right - winWidth ) - 2;
if ( left < 2 ) left = 2;
width = tooltip.innerWidth();
tooltip.offset( { top: offset.top, left: left } );
tooltip.innerWidth( width );
width = offset.left - left;
offset = tail.offset();
offset.left += width;
tail.offset( offset );
}
}
}
else {
tooltip.css( 'right', $this.innerWidth() / 2 - 13 )
.addClass('mkRight');
if ( isMobile ) {
offset = tooltip.offset();
left = offset.left;
if ( left < 2 ) {
width = tooltip.innerWidth();
tooltip.offset( { top: offset.top, left: 2 } );
tooltip.innerWidth( width );
offset = tail.offset();
offset.left += left;
tail.offset( offset );
}
}
}
};
var showMarkerTooltip = function( e ) {
var $this = $( e.target ).closest( '.listing-tooltip' );
e.stopPropagation();
var id = $this.attr( 'data-id' );
var $origin = $this;
if ( $this.hasClass( 'copy-marker' ) ) {
// getting from original marker
var attr = $this.attr( 'data-copy-marker-attribute' );
var content = $this.attr( 'data-copy-marker-content' );
$origin = $( '*[' + attr + '="' + content + '"]' ).first();
}
var tooltip = $( '<div class="mkTooltip" role="tooltip"></div>' )
.append( makeContent( $origin ) );
if ( !isMobile )
tooltip.hide(); // later fade-in
else
tooltip.addClass( 'mkTooltipMobile' );
$this.append( tooltip );
setTooltipPosition( e, tooltip, $this );
$( '.mkButton1', tooltip )
.click( function() { copyToClipboard( '.mkClip1', tooltip ); } );
$( '.mkButton2', tooltip )
.click( function() { copyToClipboard( '.mkClip2', tooltip ); } );
$( '.mkButton3', tooltip )
.click( function() { copyToClipboard( '.mkClip3', tooltip ); } );
$( '.mkButton4', tooltip )
.click( function() { copyToClipboard( '.mkClip4', tooltip ); } );
$( '.mkButton5', tooltip )
.click( function() { copyToClipboard( '.mkClip5', tooltip ); } );
$( '#templateIdLink', tooltip )
.click( function() {
var alertText = templateIdText + $( '#templateId', tooltip ).text();
removeAllTooltips();
alert( alertText );
} );
$( '#infobutton', tooltip )
.click( function() {
$( '.listing-info-button a', wrapper ).trigger( 'click' );
removeAllTooltips();
} );
$( '#editbutton', tooltip )
.click( function() {
$( '.listing-edit-button a', wrapper ).trigger( 'click' );
removeAllTooltips();
} );
if ( isMobile ) {
// removing tooltip after 10 sec in mobile mode
timeouts[ id ] =
setTimeout( function() { removeTooltip( $this ) }, 10000 );
$( 'body' ).click( handleOutsideClick );
}
else
// fading-in hidden tooltip in desktop mode
setTimeout( function() { tooltip.fadeIn( 500 ); }, 300 );
return tooltip;
};
// Click event handler if clicked outside any tooltip
var handleOutsideClick = function( event ) {
if ( !$( event.target ).closest( '.mkTooltip' ).length
&& $( '.mkTooltip' ).is( ':visible' ) )
removeAllTooltips();
};
var removeTooltip = function( marker ) {
var id = marker.attr( 'data-id' );
if ( id )
clearTimeout( timeouts[ id ] );
$( '.mkTooltip', marker ).remove();
$( '.listing-tooltip-button', marker ).text( '▼' );
};
var removeAllTooltips = function() {
if ( isMobile )
$( 'body' ).off( 'click', handleOutsideClick );
var markers = $( '.listing-tooltip' ).add( $( 'abbr' ) );
markers.each( function() {
removeTooltip( $( this ) );
});
};
var showMobileMarker = function( e ) {
var $this = $( e.target ).closest( '.listing-tooltip-button' );
var text = $this.text();
removeAllTooltips();
if ( text === '▼' ) {
$this.text( '▲' );
showMarkerTooltip( e );
}
};
var initMarkerTooltip = function() {
$( '.listing-map' ).addClass( 'listing-tooltip' );
$( '.copy-marker' ).addClass( 'listing-tooltip' ); // Marker-Kopie
var markers = $( '.listing-tooltip' )
.attr( 'title', '' )
.css( { 'position': 'relative', 'cursor': 'default' } );
var id = 0;
// setting id for timeout handler
markers.each( function() {
$( this ).attr( 'data-id', 'tt' + id );
id += 1;
} );
if ( isMobile ) {
var mobileMarker = $( '<span class="listing-tooltip-button">▼</span>' )
.click( function( e ) {
showMobileMarker( e );
});
markers.append( mobileMarker );
}
else {
markers.mouseenter( function( e ) {
showMarkerTooltip( e );
})
.mouseleave( function( e ) {
$( '.mkTooltip' ).remove();
});
}
};
var initAbbrTooltip = function() {
var abbr = $( 'abbr' )
.css( { 'position': 'relative', 'cursor': 'pointer' } );
var id = 0;
// setting id for timeout handler
abbr.each( function() {
$( this ).attr( 'data-id', 'at' + id );
id += 1;
} );
abbr.click( function( e ) {
e.stopPropagation();
var $this = $( e.target ).closest( 'abbr' );
var id = $this.attr( 'data-id' ), div, title;
var tooltip = $( '.mkTooltip', $this );
removeAllTooltips();
if ( tooltip.length === 0 ) {
title = $this.attr( 'title' );
if ( title ) {
div = $( '<div class="mkTooltipInner mkTooltipMaxWidth">'
+ title + '</div>' )
.append( $( '<div class="mkTooltipTail"></div>' ) );
tooltip = $( '<div class="mkTooltip mkTooltipMobile" role="tooltip"></div>' )
.append( div );
$this.append( tooltip );
setTooltipPosition( e, tooltip, $this );
timeouts[ id ] =
setTimeout( function() { removeTooltip( $this ) }, 10000 );
$( 'body' ).click( handleOutsideClick );
}
}
} );
};
var init = function() {
$('head').append('<link rel="stylesheet" type="text/css" href="/w/index.php?title=MediaWiki:MarkerTooltip.css&action=raw&ctype=text/css">');
isMobile = ( /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test( navigator.userAgent.toLowerCase() ) );
// isMobile = true;
initMarkerTooltip();
if ( isMobile )
initAbbrTooltip();
};
return { init: init };
} ();
$( mkTooltip.init );
} ( jQuery ) );
//</nowiki>