jenkins-bot has submitted this change and it was merged. Change subject: Automatically set map view if not defined explicitly ......................................................................
Automatically set map view if not defined explicitly Bug: T137678 Change-Id: I3b7f0cb1017ae5c7c4d5394568ffa4a02a09b63d --- M i18n/en.json M i18n/qqq.json M includes/Tag/MapFrame.php M includes/Tag/MapLink.php M includes/Tag/TagHandler.php M modules/kartographer.js M tests/parserTests.txt 7 files changed, 116 insertions(+), 25 deletions(-) Approvals: Yurik: Looks good to me, approved jenkins-bot: Verified diff --git a/i18n/en.json b/i18n/en.json index d356df9..be99bc3 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -24,6 +24,7 @@ "kartographer-error-missing-attr": "Attribute \"$1\" is missing", "kartographer-error-bad_attr": "Attribute \"$1\" has an invalid value", "kartographer-error-bad_data": "The JSON content is not valid GeoJSON+simplestyle", + "kartographer-error-latlon": "Either both \"latitude\" and \"longitude\" parameters should be supplied or neither of them", "kartographer-tracking-category": "Pages with maps", "kartographer-tracking-category-desc": "The page includes a map", "kartographer-coord-combined": "$1 $2", diff --git a/i18n/qqq.json b/i18n/qqq.json index b40c092..34714cc 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -27,6 +27,7 @@ "kartographer-error-missing-attr": "Error shown instead of a map when required parameter(s) is missing.\n\nParameters:\n* $1 - non-localized attribute name, such as 'height', 'latitude', etc", "kartographer-error-bad_attr": "Error shown instead of a map in case of a problem with parameters.\n\nParameters:\n* $1 - non-localized attribute name, such as 'height', 'latitude', etc", "kartographer-error-bad_data": "This error is shown if the content of the tag is syntactically valid JSON however it does not adhere to GeoJSON and simplestyle specifications", + "kartographer-error-latlon": "Error shown by <maplink> or <mapframe> when certain parameters are incorrect", "kartographer-tracking-category": "Name of the tracking category", "kartographer-tracking-category-desc": "Description on [[Special:TrackingCategories]] for the {{msg-mw|kartographer-tracking-category}} tracking category.", "kartographer-coord-combined": "{{optional}}\nJoins two parts of geogrpahical coordinates. $1 and $2 are latitude and longitude, respectively.", diff --git a/includes/Tag/MapFrame.php b/includes/Tag/MapFrame.php index f5a0792..a7f1022 100644 --- a/includes/Tag/MapFrame.php +++ b/includes/Tag/MapFrame.php @@ -86,10 +86,15 @@ 'mw-data' => 'interface', 'style' => "width:{$width}; height:{$this->height}px;", 'data-style' => $this->mapStyle, - 'data-zoom' => $this->zoom, - 'data-lat' => $this->lat, - 'data-lon' => $this->lon, ]; + if ( $this->zoom !== null ) { + $attrs['data-zoom'] = $this->zoom; + } + if ( $this->lat !== null && $this->lon !== null ) { + $attrs['data-lat'] = $this->lat; + $attrs['data-lon'] = $this->lon; + + } if ( isset( $alignClasses[$this->align] ) ) { $attrs['class'] .= ' ' . $alignClasses[$this->align]; } diff --git a/includes/Tag/MapLink.php b/includes/Tag/MapLink.php index 639724f..cab6e18 100644 --- a/includes/Tag/MapLink.php +++ b/includes/Tag/MapLink.php @@ -39,10 +39,15 @@ 'class' => 'mw-kartographer-link', 'mw-data' => 'interface', 'data-style' => $this->mapStyle, - 'data-zoom' => $this->zoom, - 'data-lat' => $this->lat, - 'data-lon' => $this->lon, ]; + if ( $this->zoom !== null ) { + $attrs['data-zoom'] = $this->zoom; + } + if ( $this->lat !== null && $this->lon !== null ) { + $attrs['data-lat'] = $this->lat; + $attrs['data-lon'] = $this->lon; + + } $style = $this->extractMarkerCss(); if ( $style ) { $attrs['class'] .= ' mw-kartographer-autostyled'; diff --git a/includes/Tag/TagHandler.php b/includes/Tag/TagHandler.php index e2c3e0d..695c50d 100644 --- a/includes/Tag/TagHandler.php +++ b/includes/Tag/TagHandler.php @@ -149,9 +149,13 @@ protected function parseArgs() { global $wgKartographerStyles, $wgKartographerDfltStyle; - $this->lat = $this->getFloat( 'latitude' ); - $this->lon = $this->getFloat( 'longitude' ); - $this->zoom = $this->getInt( 'zoom' ); + $this->lat = $this->getFloat( 'latitude', null ); + $this->lon = $this->getFloat( 'longitude', null ); + if ( ( $this->lat === null ) ^ ( $this->lon === null ) ) { + $this->status->fatal( 'kartographer-error-latlon' ); + } + + $this->zoom = $this->getInt( 'zoom', null ); $regexp = '/^(' . implode( '|', $wgKartographerStyles ) . ')$/'; $this->mapStyle = $this->getText( 'mapstyle', $wgKartographerDfltStyle, $regexp ); } @@ -190,7 +194,7 @@ protected function getInt( $name, $default = false ) { $value = $this->getText( $name, $default, '/^-?[0-9]+$/' ); - if ( $value !== false ) { + if ( $value !== false && $value !== null ) { $value = intval( $value ); } @@ -204,7 +208,7 @@ */ protected function getFloat( $name, $default = false ) { $value = $this->getText( $name, $default, '/^-?[0-9]*\.?[0-9]+$/' ); - if ( $value !== false ) { + if ( $value !== false && $value !== null ) { $value = floatval( $value ); } diff --git a/modules/kartographer.js b/modules/kartographer.js index 371791a..c171404 100644 --- a/modules/kartographer.js +++ b/modules/kartographer.js @@ -5,7 +5,8 @@ mapServer = mw.config.get( 'wgKartographerMapServer' ), forceHttps = mapServer[ 4 ] === 's', config = L.mapbox.config, - router = mw.loader.require( 'mediawiki.router' ); + router = mw.loader.require( 'mediawiki.router' ), + worldLatLng = new L.LatLngBounds( [ -90, -180 ], [ 90, 180 ] ); config.REQUIRE_ACCESS_TOKEN = false; config.FORCE_HTTPS = forceHttps; @@ -84,6 +85,46 @@ } ); /** + * Gets the valid bounds of a map/layer. + * + * @param {L.Map|L.Layer} layer + * @return {L.LatLngBounds} Extended bounds + * @private + */ + function getValidBounds( layer ) { + var layerBounds = new L.LatLngBounds(); + if ( typeof layer.eachLayer === 'function' ) { + layer.eachLayer( function ( child ) { + layerBounds.extend( getValidBounds( child ) ); + } ); + } else { + layerBounds.extend( validateBounds( layer ) ); + } + return layerBounds; + } + + /** + * Validate that the bounds contain no outlier. + * + * An outlier is a layer whom bounds do not fit into the world, + * i.e. `-180 <= longitude <= 180 && -90 <= latitude <= 90` + * + * @param {L.Layer} layer Layer to get and validate the bounds. + * @return {L.LatLng|boolean} Bounds if valid. + * @private + */ + function validateBounds( layer ) { + var bounds = ( typeof layer.getBounds === 'function' ) && layer.getBounds(); + + bounds = bounds || ( typeof layer.getLatLng === 'function' ) && layer.getLatLng(); + + if ( bounds && worldLatLng.contains( bounds ) ) { + return bounds; + } + return false; + } + + /** * Create a new interactive map * * @param {HTMLElement} container Map container @@ -100,7 +141,8 @@ var map, $container = $( container ), style = data.style || mw.config.get( 'wgKartographerDfltStyle' ), - width, height; + width, height, + maxBounds; $container.addClass( 'mw-kartographer-map' ); @@ -119,14 +161,6 @@ /*jscs:disable disallowDanglingUnderscores */ map._size = new L.Point( width, height ); /*jscs:enable disallowDanglingUnderscores */ - } - map.setView( [ data.latitude, data.longitude ], data.zoom, true ); - map.attributionControl.setPrefix( '' ); - - if ( data.enableFullScreenButton ) { - map.addControl( new mw.kartographer.FullScreenControl( { - mapData: data - } ) ); } /** @@ -156,6 +190,42 @@ } ); } + + // Position the map + if ( isNaN( data.longitude ) && isNaN( data.latitude ) ) { + // Determines best center of the map + maxBounds = getValidBounds( map ); + if ( maxBounds.isValid() ) { + map.fitBounds( maxBounds ); + } else { + map.fitWorld(); + } + // (Re-)Applies expected zoom + if ( !isNaN( data.zoom ) ) { + map.setZoom( data.zoom ); + } + // Updates map data. + data.zoom = map.getZoom(); + data.longitude = map.getCenter().lng; + data.latitude = map.getCenter().lat; + // Updates container's data attributes to avoid `NaN` errors + $( map.getContainer() ).closest( '.mw-kartographer-interactive' ).data( { + zoom: data.zoom, + lon: data.longitude, + lat: data.latitude + } ); + } else { + map.setView( [ data.latitude, data.longitude ], data.zoom, true ); + } + + map.attributionControl.setPrefix( '' ); + + if ( data.enableFullScreenButton ) { + map.addControl( new mw.kartographer.FullScreenControl( { + mapData: data + } ) ); + } + return map; }; diff --git a/tests/parserTests.txt b/tests/parserTests.txt index 9fda8c6..fa114f6 100644 --- a/tests/parserTests.txt +++ b/tests/parserTests.txt @@ -1,9 +1,11 @@ !! test -<maplink> - custom link text +<maplink> !! input +<maplink /> <maplink latitude=10 longitude=20 zoom=13 text='Foo & bar'/> !! result -<p><a class="mw-kartographer-link" mw-data="interface" data-style="osm-intl" data-zoom="13" data-lat="10" data-lon="20">Foo & bar</a> +<p><a class="mw-kartographer-link" mw-data="interface" data-style="osm-intl">0°0′0″N 0°0′0″E</a> +<a class="mw-kartographer-link" mw-data="interface" data-style="osm-intl" data-zoom="13" data-lat="10" data-lon="20">Foo & bar</a> </p> !! end @@ -145,12 +147,13 @@ } } </mapframe> +<mapframe width=200 height=200 latitude=100/> +<mapframe width=200 height=200 longitude=100/> !! result <div class="mw-kartographer-error"><p><maplink> problems: </p> <ul><li> Couldn't parse JSON: Syntax error</li> -<li> Attribute "longitude" has an invalid value</li> -<li> Attribute "zoom" is missing</li></ul> +<li> Attribute "longitude" has an invalid value</li></ul> </div> <div class="mw-kartographer-error"><p><mapframe> problems: </p> @@ -167,6 +170,8 @@ <li> Attribute "mapstyle" has an invalid value</li> <li> Attribute "align" has an invalid value</li></ul> </div> +<div class="mw-kartographer-error"><mapframe>: Either both "latitude" and "longitude" parameters should be supplied or neither of them</div> +<div class="mw-kartographer-error"><mapframe>: Either both "latitude" and "longitude" parameters should be supplied or neither of them</div> !! end -- To view, visit https://gerrit.wikimedia.org/r/294364 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I3b7f0cb1017ae5c7c4d5394568ffa4a02a09b63d Gerrit-PatchSet: 6 Gerrit-Project: mediawiki/extensions/Kartographer Gerrit-Branch: master Gerrit-Owner: MaxSem <maxsem.w...@gmail.com> Gerrit-Reviewer: JGirault <julien.inbox.w...@gmail.com> Gerrit-Reviewer: Siebrand <siebr...@kitano.nl> Gerrit-Reviewer: Yurik <yu...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits