jenkins-bot has submitted this change and it was merged. Change subject: Use map snapshot service until user interacts ......................................................................
Use map snapshot service until user interacts * Move the Link class outside of ext.kartographer.box so it can be loaded without mapbox * Make Link class delegate creating the map to the dialog so that the dialog can open first and create the map second * Add a spinner for when dialog is open and map being created Bug: T148070 Change-Id: Iba40a37130220576185c075cdec9be3f75afcad6 --- M extension.json M includes/Tag/MapFrame.php D modules/box/Link.js M modules/box/index.js M modules/dialog/closefullscreen_control.js M modules/dialog/dialog.js M modules/dialog/index.js A modules/linkbox/Link.js A modules/linkbox/index.js M modules/maplink/maplink.js A modules/staticframe/staticframe.js M styles/dialog.less A styles/images/ajax-loader.gif M styles/kartographer.less M tests/parserTests.txt 15 files changed, 543 insertions(+), 206 deletions(-) Approvals: Yurik: Looks good to me, approved jenkins-bot: Verified diff --git a/extension.json b/extension.json index 2bfb185..ed3fb40 100644 --- a/extension.json +++ b/extension.json @@ -152,7 +152,7 @@ "ext.kartographer.link": { "dependencies": [ "mediawiki.router", - "ext.kartographer.box" + "ext.kartographer.linkbox" ], "scripts": [ "modules/maplink/maplink.js" @@ -182,12 +182,21 @@ "modules/box/dataLayerOpts.js", "modules/box/data.js", "modules/box/Map.js", - "modules/box/Link.js", "modules/box/enablePreview.js", "modules/box/index.js" ], "messages": [ "kartographer-attribution" + ], + "targets": [ + "mobile", + "desktop" + ] + }, + "ext.kartographer.linkbox": { + "scripts": [ + "modules/linkbox/Link.js", + "modules/linkbox/index.js" ], "targets": [ "mobile", @@ -211,8 +220,7 @@ "ext.kartographer.dialog": { "dependencies": [ "oojs-ui-windows", - "mediawiki.router", - "ext.kartographer.box" + "mediawiki.router" ], "scripts": [ "modules/dialog/closefullscreen_control.js", @@ -280,6 +288,23 @@ "desktop" ] }, + "ext.kartographer.staticframe": { + "dependencies": [ + "mediawiki.router", + "oojs-ui.styles.icons-media", + "ext.kartographer.linkbox" + ], + "scripts": [ + "modules/staticframe/staticframe.js" + ], + "messages": [ + "kartographer-fullscreen-text" + ], + "targets": [ + "mobile", + "desktop" + ] + }, "ext.kartographer.preview": { "scripts": [ "modules/preview/preview.js" diff --git a/includes/Tag/MapFrame.php b/includes/Tag/MapFrame.php index 739a376..ecab4a9 100644 --- a/includes/Tag/MapFrame.php +++ b/includes/Tag/MapFrame.php @@ -29,7 +29,10 @@ * @return string */ protected function render() { - global $wgKartographerFrameMode, $wgKartographerMapServer; + global $wgKartographerFrameMode, + $wgKartographerMapServer, + $wgServerName, + $wgKartographerStaticMapframe; $alignClasses = [ 'left' => 'floatleft', @@ -85,7 +88,11 @@ */ case 'interactive': - $output->addModules( 'ext.kartographer.frame' ); + if ( $wgKartographerStaticMapframe ) { + $output->addModules( 'ext.kartographer.staticframe' ); + } else { + $output->addModules( 'ext.kartographer.frame' ); + } $fullWidth = false; @@ -149,13 +156,18 @@ $containerClass .= ' mw-kartographer-full'; } - $attrs['style'] = "background-image: url({$wgKartographerMapServer}/img/{$this->mapStyle},{$staticZoom},{$staticLat},{$staticLon},{$staticWidth}x{$this->height}.png);"; + $title = urlencode( $this->parser->getTitle()->getPrefixedText() ); + $groupList = implode( ',', $this->showGroups ); + + $bgUrl = "{$wgKartographerMapServer}/img/{$this->mapStyle},{$staticZoom},{$staticLat},{$staticLon},{$staticWidth}x{$this->height}.png"; + $bgUrl .= "?domain={$wgServerName}&title={$title}&groups={$groupList}"; + $attrs['style'] = "background-image: url({$bgUrl});"; if ( !$framed ) { $attrs['style'] .= " width: {$width}; height: {$height};"; $attrs['class'] .= " {$containerClass} {$alignClasses[$this->align]}"; - return Html::rawElement( 'div', $attrs ); + return Html::rawElement( $wgKartographerStaticMapframe ? 'a' : 'div', $attrs ); } $attrs['style'] .= " height: {$height};"; @@ -164,7 +176,7 @@ $captionFrame = Html::rawElement( 'div', [ 'class' => 'thumbcaption' ], $this->parser->recursiveTagParse( $caption ) ); - $mapDiv = Html::rawElement( 'div', $attrs ); + $mapDiv = Html::rawElement( $wgKartographerStaticMapframe ? 'a' : 'div', $attrs ); return Html::rawElement( 'div', [ 'class' => $containerClass ], Html::rawElement( 'div', [ diff --git a/modules/box/Link.js b/modules/box/Link.js deleted file mode 100644 index b2835fd..0000000 --- a/modules/box/Link.js +++ /dev/null @@ -1,117 +0,0 @@ -/* globals module */ -/** - * # Kartographer Link class - * - * Binds a `click` event to a `container`, that creates - * {@link Kartographer.Box.MapClass a map with layers, markers, and - * interactivity}, and opens it in a full screen dialog. - * - * @alias KartographerLink - * @class Kartographer.Box.LinkClass - */ -module.Link = ( function ( $ ) { - - /*jscs:disable disallowDanglingUnderscores */ - /** - * @constructor - * @param {Object} options **Configuration and options:** - * @param {HTMLElement} options.container **Link container.** - * @param {string[]} [options.dataGroups] **List of known data groups, - * fetchable from the server, to add as overlays onto the map.** - * @param {Object|Array} [options.data] **Inline GeoJSON features to - * add to the map.** - * @param {Array|L.LatLng} [options.center] **Initial map center.** - * @param {number} [options.zoom] **Initial map zoom.** - * @param {string} [options.fullScreenRoute] Route associated to this map - * _(internal, used by "`<maplink>`")_. - * @member Kartographer.Box.LinkClass - * @type {Kartographer.Box.LinkClass} - * @method - */ - var Link = function ( options ) { - /** - * Reference to the link container. - * - * @type {HTMLElement} - */ - this.container = options.container; - - /** - * Reference to the map container as a jQuery element. - * - * @type {jQuery} - */ - this.$container = $( this.container ); - this.$container.addClass( 'mw-kartographer-link' ); - - this.center = options.center || 'auto'; - this.zoom = options.zoom || 'auto'; - - this.opened = false; - - this.useRouter = !!options.fullScreenRoute; - this.fullScreenRoute = options.fullScreenRoute || null; - this.captionText = options.captionText || ''; - this.dataGroups = options.dataGroups; - this.data = options.data; - - /** - * @property {Kartographer.Box.MapClass} [fullScreenMap=null] Reference - * to the associated full screen map. - * @protected - */ - this.fullScreenMap = null; - - if ( this.useRouter && this.container.tagName === 'A' ) { - this.container.href = '#' + this.fullScreenRoute; - } else { - this.$container.on( 'click.kartographer', L.Util.bind( function () { - this.openFullScreen(); - }, this ) ); - } - }; - - /** - * Opens the map associated to the link in a full screen dialog. - * - * **Uses Resource Loader module: {@link Kartographer.Dialog ext.kartographer.dialog}** - * - * @param {Object} [position] Map `center` and `zoom`. - * @member Kartographer.Box.LinkClass - */ - Link.prototype.openFullScreen = function ( position ) { - - var map = this.map; - - position = position || {}; - position.center = position.center || this.center; - position.zoom = typeof position.zoom === 'number' ? position.zoom : this.zoom; - - if ( this.fullScreenMap && this.fullScreenMap._container._leaflet ) { - map = this.fullScreenMap; - - map.setView( - position.center, - position.zoom - ); - } else { - map = this.fullScreenMap = L.kartographer.map( { - container: L.DomUtil.create( 'div', 'mw-kartographer-mapDialog-map' ), - fullscreen: true, - link: true, - center: position.center, - zoom: position.zoom, - captionText: this.captionText, - dataGroups: this.dataGroups, - data: this.data, - fullScreenRoute: this.fullScreenRoute - } ); - } - - mw.loader.using( 'ext.kartographer.dialog' ).done( function () { - mw.loader.require( 'ext.kartographer.dialog' ).render( map ); - } ); - }; - - return Link; -} )( jQuery ); diff --git a/modules/box/index.js b/modules/box/index.js index e8f4fdb..1a33dcd 100644 --- a/modules/box/index.js +++ b/modules/box/index.js @@ -37,24 +37,5 @@ map: function ( options ) { var Map = this.Map; return new Map( options ); - }, - - /** - * @type {Kartographer.Box.LinkClass} - * @ignore - */ - Link: module.Link, - - /** - * Use this method to create a {@link Kartographer.Box.LinkClass Link} - * object. - * - * See {@link Kartographer.Box.LinkClass#constructor} for the list of options. - * - * @return {Kartographer.Box.LinkClass} - */ - link: function ( options ) { - var Link = this.Link; - return new Link( options ); } }; diff --git a/modules/dialog/closefullscreen_control.js b/modules/dialog/closefullscreen_control.js index 1055d66..120efcc 100644 --- a/modules/dialog/closefullscreen_control.js +++ b/modules/dialog/closefullscreen_control.js @@ -9,38 +9,57 @@ * @class Kartographer.Dialog.CloseFullScreenControl * @extends L.Control */ -module.CloseFullScreenControl = L.Control.extend( { - options: { - position: 'topright' - }, +module.CloseFullScreenControl = ( function () { - /** - * Creates the control element. - * - * @override - * @protected - */ - onAdd: function () { - var container = L.DomUtil.create( 'div', 'leaflet-bar' ), - link = L.DomUtil.create( 'a', 'oo-ui-icon-close', container ); + var ControlClass, + createControl = function ( options ) { + var control = this; - link.href = ''; - link.title = mw.msg( 'kartographer-fullscreen-close' ); + // Since the control is added to an existing map, by the time we get here, + // `ext.kartographer.box` was loaded, so this will be synchronous. + // We need this hack because `L` is undefined until a map was created. + mw.loader.using( 'ext.kartographer.box' ).then( function () { + ControlClass = ControlClass || L.Control.extend( { + options: { + position: 'topright' + }, - L.DomEvent.addListener( link, 'click', this.closeFullScreen, this ); - L.DomEvent.disableClickPropagation( container ); + /** + * Creates the control element. + * + * @override + * @protected + */ + onAdd: function () { + var container = L.DomUtil.create( 'div', 'leaflet-bar' ), + link = L.DomUtil.create( 'a', 'oo-ui-icon-close', container ); - return container; - }, + link.href = ''; + link.title = mw.msg( 'kartographer-fullscreen-close' ); - /** - * Closes the full screen dialog on `click`. - * - * @param {Event} e - * @protected - */ - closeFullScreen: function ( e ) { - L.DomEvent.stop( e ); - this._map.closeFullScreen(); - } -} ); + L.DomEvent.addListener( link, 'click', this.closeFullScreen, this ); + L.DomEvent.disableClickPropagation( container ); + + return container; + }, + + /** + * Closes the full screen dialog on `click`. + * + * @param {Event} e + * @protected + */ + closeFullScreen: function ( e ) { + L.DomEvent.stop( e ); + this._map.closeFullScreen(); + } + } ); + + control = new ControlClass( options ); + } ); + return control; + }; + + return createControl; + +} )( ); diff --git a/modules/dialog/dialog.js b/modules/dialog/dialog.js index d98cb48..b7dbace 100644 --- a/modules/dialog/dialog.js +++ b/modules/dialog/dialog.js @@ -8,7 +8,7 @@ * @class Kartographer.Dialog.DialogClass * @extends OO.ui.Dialog */ -module.Dialog = ( function ( $, mw, CloseFullScreenControl, kartobox, router ) { +module.Dialog = ( function ( $, mw, CloseFullScreenControl, router ) { /** * @constructor @@ -34,6 +34,9 @@ // Parent method MapDialog.super.prototype.initialize.apply( this, arguments ); + + dialog.$body + .append( '<div class="kartographer-mapDialog-loading"></div>' ); mw.loader.using( 'oojs-ui-widgets' ).done( function () { $( function () { @@ -92,9 +95,11 @@ if ( !action ) { return new OO.ui.Process( function () { - dialog.map.closeFullScreen(); - dialog.map.remove(); - dialog.map = null; + if ( dialog.map ) { + dialog.map.closeFullScreen(); + dialog.map.remove(); + dialog.map = null; + } } ); } return MapDialog.super.prototype.getActionProcess.call( this, action ); @@ -138,7 +143,7 @@ return MapDialog.super.prototype.getSetupProcess.call( this, options ) .next( function () { - if ( options.map !== this.map ) { + if ( options.map && options.map !== this.map ) { if ( this.map ) { this.map.remove(); @@ -166,12 +171,14 @@ return MapDialog.super.prototype.getReadyProcess.call( this, data ) .next( function () { + if ( !this.map ) { + return; + } this.map.doWhenReady( function ( ) { if ( this.map.useRouter ) { this.map.on( 'moveend', this.onMapMove, this ); } - mw.hook( 'wikipage.maps' ).fire( this.map, true /* isFullScreen */ ); }, this ); }, this ); @@ -196,6 +203,5 @@ jQuery, mediaWiki, module.CloseFullScreenControl, - require( 'ext.kartographer.box' ), require( 'mediawiki.router' ) ); diff --git a/modules/dialog/index.js b/modules/dialog/index.js index a7116d6..09d3a90 100644 --- a/modules/dialog/index.js +++ b/modules/dialog/index.js @@ -74,6 +74,54 @@ }, /** + * Opens the map dialog, creates the map and renders it. + * + * @param {Object} mapObject + * @param {Function} mapCb + */ + renderNewMap: function ( mapObject, mapCb ) { + + var window = getWindowManager(), + dialog = getMapDialog(), + map; + + if ( !window.opened ) { + getWindowManager() + .openWindow( dialog, {} ) + .then( function ( opened ) { + return opened; + } ) + .then( function ( closing ) { + if ( map.parentMap ) { + map.parentMap.setView( + map.getCenter(), + map.getZoom() + ); + } + dialog.close(); + mapDialog = null; + windowManager = null; + return closing; + } ); + } + + mw.loader.using( 'ext.kartographer.box' ).then( function () { + map = mw.loader.require( 'ext.kartographer.box' ).map( mapObject ); + + if ( map.useRouter && !routerEnabled ) { + router.route( '', function () { + close(); + } ); + } + + dialog.setup.call( dialog, { map: map } ); + dialog.ready.call( dialog, { map: map } ); + + mapCb( map ); + } ); + }, + + /** * Closes the map dialog. */ close: function () { diff --git a/modules/linkbox/Link.js b/modules/linkbox/Link.js new file mode 100644 index 0000000..d4e2c35 --- /dev/null +++ b/modules/linkbox/Link.js @@ -0,0 +1,128 @@ +/* globals module */ +/** + * # Kartographer Link class + * + * Binds a `click` event to a `container`, that opens a {@link Kartographer.Box.MapClass map with + * layers, markers, and interactivity} in a full screen dialog. + * + * @class Kartographer.Linkbox.LinkClass + */ +module.Link = ( function ( $ ) { + + /*jscs:disable disallowDanglingUnderscores */ + /** + * @constructor + * @param {Object} options **Configuration and options:** + * @param {HTMLElement} options.container **Link container.** + * @param {string[]} [options.dataGroups] **List of known data groups, + * fetchable from the server, to add as overlays onto the map.** + * @param {Object|Array} [options.data] **Inline GeoJSON features to + * add to the map.** + * @param {Array|L.LatLng} [options.center] **Initial map center.** + * @param {number} [options.zoom] **Initial map zoom.** + * @param {string} [options.fullScreenRoute] Route associated to this map + * _(internal, used by "`<maplink>`")_. + * @member Kartographer.Linkbox.LinkClass + * @type {Kartographer.Linkbox.LinkClass} + * @method + */ + var Link = function ( options ) { + var link = this; + + /** + * Reference to the link container. + * + * @type {HTMLElement} + */ + link.container = options.container; + + /** + * Reference to the map container as a jQuery element. + * + * @type {jQuery} + */ + link.$container = $( link.container ); + link.$container.addClass( 'mw-kartographer-link' ); + + link.center = options.center || 'auto'; + link.zoom = options.zoom || 'auto'; + + link.opened = false; + + link.useRouter = !!options.fullScreenRoute; + link.fullScreenRoute = options.fullScreenRoute || null; + link.captionText = options.captionText || ''; + link.dataGroups = options.dataGroups; + link.data = options.data; + + /** + * @property {Kartographer.Box.MapClass} [fullScreenMap=null] Reference + * to the associated full screen map. + * @protected + */ + link.fullScreenMap = null; + + if ( link.useRouter && link.container.tagName === 'A' ) { + link.container.href = '#' + link.fullScreenRoute; + } else { + link.$container.on( 'click.kartographer', function () { + link.openFullScreen(); + } ); + } + }; + + /** + * Opens the map associated to the link in a full screen dialog. + * + * **Uses Resource Loader module: {@link Kartographer.Dialog ext.kartographer.dialog}** + * + * @param {Object} [position] Map `center` and `zoom`. + * @member Kartographer.Linkbox.LinkClass + */ + Link.prototype.openFullScreen = function ( position ) { + + var link = this, + map = link.map, + mapObject, + el; + + position = position || {}; + position.center = position.center || link.center; + position.zoom = typeof position.zoom === 'number' ? position.zoom : link.zoom; + + if ( link.fullScreenMap && link.fullScreenMap._container._leaflet ) { + map = link.fullScreenMap; + + map.setView( + position.center, + position.zoom + ); + + mw.loader.using( 'ext.kartographer.dialog' ).done( function () { + mw.loader.require( 'ext.kartographer.dialog' ).render( map ); + } ); + } else { + el = document.createElement( 'div' ); + el.className = 'mw-kartographer-mapDialog-map'; + mapObject = { + container: el, + fullscreen: true, + link: true, + center: position.center, + zoom: position.zoom, + captionText: link.captionText, + dataGroups: link.dataGroups, + data: link.data, + fullScreenRoute: link.fullScreenRoute + }; + + mw.loader.using( 'ext.kartographer.dialog' ).done( function () { + mw.loader.require( 'ext.kartographer.dialog' ).renderNewMap( mapObject, function ( map ) { + link.fullScreenMap = map; + } ); + } ); + } + }; + + return Link; +} )( jQuery ); diff --git a/modules/linkbox/index.js b/modules/linkbox/index.js new file mode 100644 index 0000000..f2244ba --- /dev/null +++ b/modules/linkbox/index.js @@ -0,0 +1,29 @@ +/* globals module */ +/** + * **Resource Loader module: {@link Kartographer.Linkbox ext.kartographer.linkbox}** + * + * @alias ext.kartographer.linkbox + * @class Kartographer.Linkbox + * @singleton + */ +module.exports = { + + /** + * @type {Kartographer.Linkbox.LinkClass} + * @ignore + */ + Link: module.Link, + + /** + * Use this method to create a {@link Kartographer.Linkbox.LinkClass Link} + * object. + * + * See {@link Kartographer.Linkbox.LinkClass#constructor} for the list of options. + * + * @return {Kartographer.Linkbox.LinkClass} + */ + link: function ( options ) { + var Link = this.Link; + return new Link( options ); + } +}; diff --git a/modules/maplink/maplink.js b/modules/maplink/maplink.js index bbd9839..f2291c4 100644 --- a/modules/maplink/maplink.js +++ b/modules/maplink/maplink.js @@ -10,7 +10,7 @@ * @class Kartographer.Link * @singleton */ -module.exports = ( function ( $, mw, router, kartobox, undefined ) { +module.exports = ( function ( $, mw, router, kartolink, undefined ) { /** * References the maplinks of the page. @@ -70,7 +70,7 @@ $( '.mw-kartographer-maplink', '#content' ).each( function ( index ) { var data = getMapData( this ); - maplinks[ index ] = kartobox.link( { + maplinks[ index ] = kartolink.link( { container: this, center: [ data.latitude, data.longitude ], zoom: data.zoom, @@ -119,5 +119,5 @@ jQuery, mediaWiki, require( 'mediawiki.router' ), - require( 'ext.kartographer.box' ) + require( 'ext.kartographer.linkbox' ) ); diff --git a/modules/staticframe/staticframe.js b/modules/staticframe/staticframe.js new file mode 100644 index 0000000..5d974e6 --- /dev/null +++ b/modules/staticframe/staticframe.js @@ -0,0 +1,162 @@ +/* globals module, require */ +/** + * Static Frame module. + * + * Once the page is loaded and ready, turn all `<mapframe/>` tags into links + * that open a full screen map. + * + * @alias ext.kartographer.staticframe + * @class Kartographer.StaticFrame + * @singleton + */ +module.exports = ( function ( $, mw, kartolink, router ) { + + /** + * References the mapframe containers of the page. + * + * @type {HTMLElement[]} + */ + var maps = [], + /** + * @private + * @ignore + */ + routerInited = false; + + /** + * Gets the map data attached to an element. + * + * @param {HTMLElement} element Element + * @return {Object|null} Map properties + * @return {number} return.latitude + * @return {number} return.longitude + * @return {number} return.zoom + * @return {string} return.style Map style + * @return {string[]} return.overlays Overlay groups + */ + function getMapData( element ) { + var $el = $( element ), + $caption = $el.parent().find( '.thumbcaption' ), + captionText = ''; + + // Prevent users from adding map divs directly via wikitext + if ( $el.attr( 'mw-data' ) !== 'interface' ) { + return null; + } + + if ( $caption[ 0 ] ) { + captionText = $caption.text(); + } + + return { + latitude: +$el.data( 'lat' ), + longitude: +$el.data( 'lon' ), + zoom: +$el.data( 'zoom' ), + style: $el.data( 'style' ), + overlays: $el.data( 'overlays' ) || [], + captionText: captionText + }; + } + + /** + * This code will be executed once the article is rendered and ready. + * + * @ignore + */ + mw.hook( 'wikipage.content' ).add( function ( $content ) { + var mapsInArticle = [], + promises = []; + + // `wikipage.content` may be fired more than once. + $.each( maps, function () { + maps.pop().remove(); + } ); + + // need to find .mw-kartographer-interactive:not(.mw-kartographer-map) for backward compatibility + $content.find( '.mw-kartographer-map, .mw-kartographer-interactive:not(.mw-kartographer-map)' ).each( function ( index ) { + + var container = this, + $container = $( container ), + link, + data, + deferred = $.Deferred(); + + mw.loader.using( 'oojs-ui', function () { + var button = new OO.ui.ButtonWidget( { + icon: 'fullScreen', + title: mw.msg( 'kartographer-fullscreen-text' ), + framed: true + } ), + $div = $( '<div class="mw-kartographer-fullScreen"></div>' ).append( button.$element ); + + $container.append( $div ); + } ); + + $container.attr( 'href', '#/map/' + index ); + + data = getMapData( container ); + + if ( data ) { + data.enableFullScreenButton = true; + + link = kartolink.link( { + container: container, + center: [ data.latitude, data.longitude ], + zoom: data.zoom, + dataGroups: data.overlays, + captionText: data.captionText, + fullScreenRoute: '/map/' + index + } ); + + mapsInArticle.push( link ); + maps[ index ] = link; + + promises.push( deferred.promise() ); + } + } ); + + // Allow customizations of interactive maps in article. + $.when( promises ).then( function () { + + if ( routerInited ) { + return; + } + // execute this piece of code only once + routerInited = true; + + // Opens a map in full screen. #/map(/:zoom)(/:latitude)(/:longitude) + // Examples: + // #/map/0 + // #/map/0/5 + // #/map/0/16/-122.4006/37.7873 + router.route( /map\/([0-9]+)(?:\/([0-9]+))?(?:\/([\-\+]?\d+\.?\d{0,5})?\/([\-\+]?\d+\.?\d{0,5})?)?/, function ( maptagId, zoom, latitude, longitude ) { + var link = maps[ maptagId ], + position; + + if ( !link ) { + router.navigate( '' ); + return; + } + + if ( zoom !== undefined && latitude !== undefined && longitude !== undefined ) { + position = { + center: [ +latitude, +longitude ], + zoom: +zoom + }; + } + + link.openFullScreen( position ); + } ); + + // Check if we need to open a map in full screen. + router.checkRoute(); + } ); + } ); + + return maps; +} )( + jQuery, + mediaWiki, + require( 'ext.kartographer.linkbox' ), + require( 'mediawiki.router' ) +); diff --git a/styles/dialog.less b/styles/dialog.less index faa849c..ae9e9aa 100644 --- a/styles/dialog.less +++ b/styles/dialog.less @@ -120,3 +120,17 @@ .skin-minerva .mw-kartographer-mapDialog-sidebar h2 { margin-bottom: 0.6em; } + +.kartographer-mapDialog-loading { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 4.5em; + + /* @embed */ + background-image: url( ./images/ajax-loader.gif ); + background-position: center center; + background-size: 32px; + background-repeat: no-repeat; +} diff --git a/styles/images/ajax-loader.gif b/styles/images/ajax-loader.gif new file mode 100644 index 0000000..c519155 --- /dev/null +++ b/styles/images/ajax-loader.gif Binary files differ diff --git a/styles/kartographer.less b/styles/kartographer.less index aee2168..5cc1c95 100644 --- a/styles/kartographer.less +++ b/styles/kartographer.less @@ -1,3 +1,5 @@ +@import 'mediawiki.ui/variables'; + .mw-kartographer-mapDialog-map { position: absolute; top: 0; @@ -58,14 +60,34 @@ } .mw-kartographer-map { + position: relative; background-position: center; background-repeat: no-repeat; + background-size: contain; + + &.leaflet-container { + background-size: contain; + } +} + +.mw-kartographer-fullScreen { + position: absolute; + top: 10px; + right: 10px; + margin-right: 0; } .client-js .mw-kartographer-map { - /* stylelint-disable declaration-no-important */ - background: none !important; - /* stylelint-enable declaration-no-important */ + cursor: pointer; +} + +.client-js .mw-kartographer-map:hover { + .mw-kartographer-fullScreen { + background-color: #fff; + } + .oo-ui-buttonElement-button { + background-color: #fff; + } } .client-js .mw-kartographer-maplink:not(.mw-kartographer-link) { @@ -97,3 +119,7 @@ .mw-kartographer-container.mw-kartographer-full { width: 100%; } + +a.mw-kartographer-map { + display: block; +} diff --git a/tests/parserTests.txt b/tests/parserTests.txt index c6b7dfb..a1890bb 100644 --- a/tests/parserTests.txt +++ b/tests/parserTests.txt @@ -125,18 +125,18 @@ <mapframe latitude=10 longitude=20 zoom=13 width=full height=480 frameless /> !! result -<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png); height: 480px;"></div><div class="thumbcaption"></div></div></div> -<div class="mw-kartographer-container thumb tleft"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png); height: 480px;"></div><div class="thumbcaption"></div></div></div> -<div class="mw-kartographer-container thumb center"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png); height: 480px;"></div><div class="thumbcaption"></div></div></div> -<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 300px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="50%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,300x480.png); height: 480px;"></div><div class="thumbcaption"></div></div></div> -<div class="mw-kartographer-container mw-kartographer-full thumb tright"><div class="thumbinner" style="width: 100%;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="100%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png); height: 480px;"></div><div class="thumbcaption"></div></div></div> -<div class="mw-kartographer-container mw-kartographer-full thumb tright"><div class="thumbinner" style="width: 100%;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="full" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png); height: 480px;"></div><div class="thumbcaption"></div></div></div> -<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png); height: 480px;"></div><div class="thumbcaption"></div></div></div> -<div class="mw-kartographer-map mw-kartographer-container floatleft" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png); width: 640px; height: 480px;"></div> -<div class="mw-kartographer-map mw-kartographer-container center" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png); width: 640px; height: 480px;"></div> -<div class="mw-kartographer-map mw-kartographer-container floatright" mw-data="interface" data-style="osm-intl" data-width="50%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,300x480.png); width: 300px; height: 480px;"></div> -<div class="mw-kartographer-map mw-kartographer-container mw-kartographer-full floatright" mw-data="interface" data-style="osm-intl" data-width="100%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png); width: 100%; height: 480px;"></div> -<div class="mw-kartographer-map mw-kartographer-container mw-kartographer-full floatright" mw-data="interface" data-style="osm-intl" data-width="full" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png); width: 100%; height: 480px;"></div> +<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-container thumb tleft"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-container thumb center"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 300px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="50%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,300x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-container mw-kartographer-full thumb tright"><div class="thumbinner" style="width: 100%;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="100%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-container mw-kartographer-full thumb tright"><div class="thumbinner" style="width: 100%;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="full" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-map mw-kartographer-container floatleft" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png?domain=example.org&title=Parser+test&groups=); width: 640px; height: 480px;"></div> +<div class="mw-kartographer-map mw-kartographer-container center" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png?domain=example.org&title=Parser+test&groups=); width: 640px; height: 480px;"></div> +<div class="mw-kartographer-map mw-kartographer-container floatright" mw-data="interface" data-style="osm-intl" data-width="50%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,300x480.png?domain=example.org&title=Parser+test&groups=); width: 300px; height: 480px;"></div> +<div class="mw-kartographer-map mw-kartographer-container mw-kartographer-full floatright" mw-data="interface" data-style="osm-intl" data-width="100%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png?domain=example.org&title=Parser+test&groups=); width: 100%; height: 480px;"></div> +<div class="mw-kartographer-map mw-kartographer-container mw-kartographer-full floatright" mw-data="interface" data-style="osm-intl" data-width="full" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png?domain=example.org&title=Parser+test&groups=); width: 100%; height: 480px;"></div> !! end @@ -150,12 +150,12 @@ <mapframe latitude=10 longitude=20 zoom=13 width=100% height=480 text="Foo is a [https://example.com bar]"" /> <mapframe latitude=10 longitude=20 zoom=13 width=full height=480 text="<div>Muhaha</div>" /> !! result -<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png); height: 480px;"></div><div class="thumbcaption">Foo is a <b>bar</b></div></div></div> +<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 640px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="640" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,640x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption">Foo is a <b>bar</b></div></div></div> <p><mapframe latitude=10 longitude=20 zoom=13 width=640 height=480 align=left text="Foo is a <b>bar</b>" /> <mapframe latitude=10 longitude=20 zoom=13 width=640 height=480 align=center text="Foo is a <script>" /> </p> -<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 300px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="50%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,300x480.png); height: 480px;"></div><div class="thumbcaption">Frameless gets cynically ignored here</div></div></div> -<div class="mw-kartographer-container mw-kartographer-full thumb tright"><div class="thumbinner" style="width: 100%;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="100%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png); height: 480px;"></div><div class="thumbcaption">"Foo</div></div></div> +<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 300px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="50%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,300x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption">Frameless gets cynically ignored here</div></div></div> +<div class="mw-kartographer-container mw-kartographer-full thumb tright"><div class="thumbinner" style="width: 100%;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="100%" data-height="480" data-zoom="13" data-lat="10" data-lon="20" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,13,10,20,800x480.png?domain=example.org&title=Parser+test&groups=); height: 480px;"></div><div class="thumbcaption">"Foo</div></div></div> <mapframe latitude=10 longitude=20 zoom=13 width=full height=480 text="<div>Muhaha</div>" /> !! end @@ -302,6 +302,7 @@ wgKartographerWikivoyageMode=true !! input <maplink zoom=0 latitude=0 longitude=0 group=ponies/> +<maplink zoom=0 latitude=0 longitude=0 show="ponies,horses"/> <mapframe zoom=0 latitude=0 longitude=0 width=300 height=300 group=ponies> { "type": "Feature", @@ -315,10 +316,13 @@ } } </mapframe> +<mapframe zoom=0 latitude=0 longitude=0 width=300 height=300 show="ponies,horses"/> !! result <p><a class="mw-kartographer-maplink" mw-data="interface" data-style="osm-intl" href="/wiki/Special:Map/0/0/0" data-zoom="0" data-lat="0" data-lon="0" data-overlays="["ponies"]">0°0′0″N 0°0′0″E</a> +<a class="mw-kartographer-maplink" mw-data="interface" data-style="osm-intl" href="/wiki/Special:Map/0/0/0" data-zoom="0" data-lat="0" data-lon="0" data-overlays="["ponies","horses"]">0°0′0″N 0°0′0″E</a> </p> -<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 300px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="300" data-height="300" data-zoom="0" data-lat="0" data-lon="0" data-overlays="["ponies"]" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,0,0,0,300x300.png); height: 300px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 300px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="300" data-height="300" data-zoom="0" data-lat="0" data-lon="0" data-overlays="["ponies"]" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,0,0,0,300x300.png?domain=example.org&title=Parser+test&groups=ponies); height: 300px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 300px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="300" data-height="300" data-zoom="0" data-lat="0" data-lon="0" data-overlays="["ponies","horses"]" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,0,0,0,300x300.png?domain=example.org&title=Parser+test&groups=ponies,horses); height: 300px;"></div><div class="thumbcaption"></div></div></div> !! end @@ -344,7 +348,7 @@ !! result <p><a class="mw-kartographer-maplink" mw-data="interface" data-style="osm-intl" href="/wiki/Special:Map/0/0/0" data-zoom="0" data-lat="0" data-lon="0">0°0′0″N 0°0′0″E</a> </p> -<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 300px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="300" data-height="300" data-zoom="0" data-lat="0" data-lon="0" data-overlays="["_a724df91b09b20c8c7ea0dc28127eaed1727511b"]" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,0,0,0,300x300.png); height: 300px;"></div><div class="thumbcaption"></div></div></div> +<div class="mw-kartographer-container thumb tright"><div class="thumbinner" style="width: 300px;"><div class="mw-kartographer-map" mw-data="interface" data-style="osm-intl" data-width="300" data-height="300" data-zoom="0" data-lat="0" data-lon="0" data-overlays="["_a724df91b09b20c8c7ea0dc28127eaed1727511b"]" style="background-image: url(https://maps.wikimedia.org/img/osm-intl,0,0,0,300x300.png?domain=example.org&title=Parser+test&groups=_a724df91b09b20c8c7ea0dc28127eaed1727511b); height: 300px;"></div><div class="thumbcaption"></div></div></div> !! end @@ -394,4 +398,4 @@ <li> Invalid cartographic service "lulzifier"</li></ul> </div> -!! end \ No newline at end of file +!! end -- To view, visit https://gerrit.wikimedia.org/r/317018 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iba40a37130220576185c075cdec9be3f75afcad6 Gerrit-PatchSet: 8 Gerrit-Project: mediawiki/extensions/Kartographer Gerrit-Branch: master Gerrit-Owner: JGirault <julien.inbox.w...@gmail.com> Gerrit-Reviewer: JGirault <julien.inbox.w...@gmail.com> Gerrit-Reviewer: MaxSem <maxsem.w...@gmail.com> 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