User:Aude/MapView.js

From Wikidata
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
(function($, mw, wb, L) {

	function MapView(apiUrl, coordProp) {
		this.apiUrl = apiUrl;
		this.coordProp = coordProp;
		
		this.center = null;
		this.precision = null;

		this.$mapContainer = null;
		this.$mapLink = null;
	}

    MapView.prototype.renderLeaflet = function( mapElement ) {
		var mapView = L.map(mapElement).setView(this.center, 8);

        L.tileLayer('https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png', {
            maxZoom: 18,
            attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors'
        }).addTo(mapView);

		L.marker(this.center).addTo(mapView);
    };

	MapView.prototype.renderMap = function( e ) {
		e.preventDefault();

		var self = this,
			$snakViewContainer = $( e.target ).closest( '.wikibase-snakview-value-container' ),
			valueDivs = $snakViewContainer.find('.wikibase-snakview-value');

		if (valueDivs.length !== 1) {
			return;
		}
		
		var coordinateDiv = valueDivs[0];
		
		this.$mapContainer = $('<div>')
			.attr({
				'id': 'map-' + this.coordProp,
				'class': 'mapview'
			})
			.css({
				'width': '400px',
				'height': '300px'
			})
			.appendTo( $snakViewContainer );

		$snakViewContainer.append( this.$mapContainer );

		this.parseCoordinates( coordinateDiv )
			.done( function( data ) {
                if (data.results && data.results.length > 0) {
                    // TODO handle globe
                    var coordinates = data.results[0].value;

                    self.center = [
                    	coordinates.latitude,
						coordinates.longitude
                    ] 

                    self.precision = coordinates.precision;
                
					self.renderLeaflet( 'map-' + self.coordProp );
				}
			});
	};

	MapView.prototype.parseCoordinates = function( coordinateDiv ) {
		return $.get( this.apiUrl, {
			'action': 'wbparsevalue',
			'format': 'json',
			'datatype': 'globe-coordinate',
			'values': $(coordinateDiv).text()
		});

		// TODO handle error
	};

	MapView.prototype.renderIcon = function() {
		var self = this;

		var $iconContainer = $('<span>').attr({
			'class': 'mapview-link-container'
		});

		this.$mapLink = $('<a>').attr({
				'class': 'mapview-link',
				'href': '#'
			})
			.text('map')
			.on('click', function( e ) {
				self.renderMap( e );
			})
			.appendTo( $iconContainer );

		$('#' + this.coordProp ).find('.wikibase-snakview-value-container').append( $iconContainer );
	};

	MapView.prototype.init = function() {
		var self = this;

		if ( mw.config.get( 'wgNamespaceNumber' ) !== 0 ) {
			return;
		}		

		mw.hook( 'wikipage.content' ).add( function() {
			self.renderIcon();
		});
	};

	wb.MapView = MapView;

})(jQuery, mediaWiki, wikibase, L);