JGirault has uploaded a new change for review. https://gerrit.wikimedia.org/r/317995
Change subject: Implement first phase of map event logging. ...................................................................... Implement first phase of map event logging. * Uses mw.track to track analytical events. * Fixes dialog sidebar so it keeps track of sidebar state when switching to another map from hash. Bug: T149140 Change-Id: I66ba00cc2d86d9f1e49cbb46bd9ebd39650e3bea --- M modules/box/Map.js M modules/box/openfullscreen_control.js M modules/dialog-sidebar/sidebar.js M modules/dialog/dialog.js M modules/linkbox/Link.js M modules/mapframe/mapframe.js M modules/maplink/maplink.js M modules/staticframe/staticframe.js M templates/dialog-sidebar-externalservices.mustache 9 files changed, 195 insertions(+), 36 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Kartographer refs/changes/95/317995/1 diff --git a/modules/box/Map.js b/modules/box/Map.js index 3d43045..333cf9a 100644 --- a/modules/box/Map.js +++ b/modules/box/Map.js @@ -177,6 +177,19 @@ this.parentMap = options.parentMap || null; /** + * @property {Kartographer.Box.MapClass} [parentLink=null] Reference + * to the parent link. + * @protected + */ + this.parentLink = options.parentLink || null; + + /** + * @property {string} The feature type identifier. + * @protected + */ + this.featureType = options.featureType; + + /** * @property {Kartographer.Box.MapClass} [fullScreenMap=null] Reference * to the child full screen map. * @protected @@ -236,6 +249,13 @@ if ( options.allowFullScreen ) { // embed maps, and full screen is allowed this.on( 'dblclick', function () { + // We need this hack to differentiate these events from `hashopen` events. + map.clicked = true; + mw.track( 'mediawiki.kartographer', { + action: 'open', + isFullScreen: true, + feature: map + } ); map.openFullScreen(); } ); @@ -469,6 +489,7 @@ container: L.DomUtil.create( 'div', 'mw-kartographer-mapDialog-map' ), center: position.center, zoom: position.zoom, + featureType: this.featureType, fullscreen: true, captionText: this.captionText, fullScreenRoute: this.fullScreenRoute, @@ -670,12 +691,20 @@ * @chainable */ remove: function () { + var parent = this.parentMap || this.parentLink; + if ( this.fullScreenMap ) { L.Map.prototype.remove.call( this.fullScreenMap ); this.fullScreenMap = null; } - if ( this.parentMap ) { - this.parentMap.fullScreenMap = null; + if ( parent ) { + parent.fullScreenMap = null; + mw.track( 'mediawiki.kartographer', { + action: 'close', + isFullScreen: true, + feature: parent + } ); + parent.clicked = false; } return L.Map.prototype.remove.call( this ); diff --git a/modules/box/openfullscreen_control.js b/modules/box/openfullscreen_control.js index d712b4f..50d5536 100644 --- a/modules/box/openfullscreen_control.js +++ b/modules/box/openfullscreen_control.js @@ -30,6 +30,7 @@ if ( this._map.useRouter ) { this.updateHash(); this._map.on( 'moveend', this.onMapMove, this ); + L.DomEvent.addListener( this.link, 'click', this.logOpenEvent, this ); } else { // the router will handle it otherwise L.DomEvent.addListener( this.link, 'click', this.openFullScreen, this ); @@ -60,6 +61,21 @@ }, /** + * Ability to log an `open` event on click. + * + * @protected + */ + logOpenEvent: function () { + // We need this hack to differentiate these events from `hashopen` events. + this._map.clicked = true; + mw.track( 'mediawiki.kartographer', { + action: 'open', + isFullScreen: true, + feature: this._map + } ); + }, + + /** * Opens the full screen dialog on `click`. * * @param {Event} e @@ -67,6 +83,7 @@ */ openFullScreen: function ( e ) { L.DomEvent.stop( e ); + this.logOpenEvent(); this._map.openFullScreen(); } } ); diff --git a/modules/dialog-sidebar/sidebar.js b/modules/dialog-sidebar/sidebar.js index 5cc2db8..4a76618 100644 --- a/modules/dialog-sidebar/sidebar.js +++ b/modules/dialog-sidebar/sidebar.js @@ -45,6 +45,7 @@ * Toggles the sidebar * * @param {boolean} open Whether to open the sidebar or close it. + * @chainable */ SideBar.prototype.toggle = function ( open ) { @@ -56,52 +57,69 @@ } this.render(); + return this; }; /** - * Renders the sidebar + * Renders the sidebar. + * + * @chainable */ SideBar.prototype.render = function () { + var sidebar = this, + dialog = sidebar.dialog; /** * @property {jQuery} */ - this.$el = $( '<div class="mw-kartographer-mapDialog-sidebar">' ); + sidebar.$el = $( '<div class="mw-kartographer-mapDialog-sidebar">' ); /** * @property {Object} */ - this.mapPosition = this.dialog.map.getMapPosition( { scaled: true } ); + sidebar.mapPosition = this.dialog.map.getMapPosition( { scaled: true } ); - this.createCloseButton().$element.appendTo( this.$el ); + sidebar.createCloseButton().$element.appendTo( sidebar.$el ); /** * @property {jQuery} */ - this.$mapDetailsContainer = $( '<div>' ).addClass( 'mw-kartographer-mapdetails' ).appendTo( this.$el ); + sidebar.$mapDetailsContainer = $( '<div>' ).addClass( 'mw-kartographer-mapdetails' ).appendTo( sidebar.$el ); /** * @property {jQuery} */ - this.$descriptionContainer = $( '<div>' ).addClass( 'mw-kartographer-description' ).appendTo( this.$el ); + sidebar.$descriptionContainer = $( '<div>' ).addClass( 'mw-kartographer-description' ).appendTo( sidebar.$el ); /** * @property {jQuery} */ - this.$filterContainer = $( '<div>' ).addClass( 'mw-kartographer-filterservices' ).appendTo( this.$el ); + sidebar.$filterContainer = $( '<div>' ).addClass( 'mw-kartographer-filterservices' ).appendTo( sidebar.$el ); /** * @property {jQuery} */ - this.$servicesContainer = $( '<div>' ).addClass( 'mw-kartographer-externalservices' ).appendTo( this.$el ); + sidebar.$servicesContainer = $( '<div>' ).addClass( 'mw-kartographer-externalservices' ).appendTo( sidebar.$el ); - this.renderMapDetails(); - this.renderDescription(); - this.renderTypeFilter(); - this.renderExternalServices(); + sidebar.renderMapDetails(); + sidebar.renderDescription(); + sidebar.renderTypeFilter(); + sidebar.renderExternalServices(); - this.$el.appendTo( this.dialog.$body ); + sidebar.$el.appendTo( dialog.$body ); - this.dialog.map.on( 'move', this.onMapMove, this ); + dialog.map.on( 'move', sidebar.onMapMove, sidebar ); + + sidebar.$servicesContainer.on( 'click', 'a', function () { + mw.track( 'mediawiki.kartographer', { + action: 'sidebar-click', + isFullScreen: true, + service: $( this ).data( 'service' ), + type: selectedType, + feature: dialog.map.parentMap || dialog.map.parentLink + } ); + } ); + + return sidebar; }; /** @@ -146,11 +164,23 @@ SideBar.prototype.renderTypeFilter = function () { var sidebar = this, dropdown = sidebar.createFilterDropdown(), - defaultType = sidebar.metadata.types[ 0 ] ; + defaultType = sidebar.metadata.types[ 0 ], + first = true; dropdown.getMenu().on( 'select', function ( item ) { selectedType = item.getData(); sidebar.renderExternalServices(); + + // First selection is the default, skip it. + if ( !first ) { + mw.track( 'mediawiki.kartographer', { + action: 'sidebar-type', + isFullScreen: true, + type: selectedType, + feature: sidebar.dialog.map.parentMap || sidebar.dialog.map.parentLink + } ); + } + first = false; } ); dropdown.getMenu().selectItemByData( selectedType || defaultType ); @@ -280,12 +310,15 @@ /** * Detaches events and removes the element. + * + * @chainable */ SideBar.prototype.tearDown = function () { this.dialog.map.off( 'move', this.onMapMove, this ); this.$el.remove(); this.$el = null; + return this; }; return SideBar; diff --git a/modules/dialog/dialog.js b/modules/dialog/dialog.js index fbbdc6b..40765b4 100644 --- a/modules/dialog/dialog.js +++ b/modules/dialog/dialog.js @@ -88,8 +88,15 @@ if ( dialog.$mapDetailsButton.value !== open ) { dialog.$mapDetailsButton.setValue( open ); + // This `change` event callback is fired again, so skip here. + return; } + mw.track( 'mediawiki.kartographer', { + action: open ? 'sidebar-show' : 'sidebar-hide', + isFullScreen: true, + feature: dialog.map.parentMap || dialog.map.parentLink + } ); dialog.sideBar.toggle( open ); } ); }; @@ -146,32 +153,36 @@ MapDialog.prototype.getSetupProcess = function ( options ) { return MapDialog.super.prototype.getSetupProcess.call( this, options ) .next( function () { + var dialog = this; - if ( options.map && options.map !== this.map ) { + if ( options.map && options.map !== dialog.map ) { - if ( this.map ) { - this.map.remove(); + if ( dialog.map ) { + dialog.map.remove(); } - this.map = options.map; + dialog.map = options.map; - this.map.closeFullScreenControl = new CloseFullScreenControl( { position: 'topright' } ) - .addTo( this.map ); + dialog.map.closeFullScreenControl = new CloseFullScreenControl( { position: 'topright' } ) + .addTo( dialog.map ); - this.$body.empty().append( - this.map.$container.css( 'position', '' ) + dialog.$body.append( + dialog.map.$container.css( 'position', '' ) ); - if ( this.$captionContainer ) { - this.$captionContainer - .attr( 'title', this.map.captionText ) - .text( this.map.captionText ); + if ( dialog.$captionContainer ) { + dialog.$captionContainer + .attr( 'title', dialog.map.captionText ) + .text( dialog.map.captionText ); } - if ( !this.$mapDetailsButton ) { - this.addFooterButton(); - } else { - this.$mapDetailsButton.setValue( false ); + if ( !dialog.$mapDetailsButton ) { + dialog.addFooterButton(); + } else if ( dialog.sideBar ) { + dialog.sideBar.tearDown(); + dialog.map.doWhenReady( function () { + dialog.sideBar.render(); + } ); } } }, this ); diff --git a/modules/linkbox/Link.js b/modules/linkbox/Link.js index 7b79e51..34df7ac 100644 --- a/modules/linkbox/Link.js +++ b/modules/linkbox/Link.js @@ -54,6 +54,7 @@ link.captionText = options.captionText || ''; link.dataGroups = options.dataGroups; link.data = options.data; + link.featureType = options.featureType; /** * @property {Kartographer.Box.MapClass} [fullScreenMap=null] Reference @@ -110,8 +111,10 @@ el.className = 'mw-kartographer-mapDialog-map'; mapObject = { container: el, + featureType: link.featureType, fullscreen: true, link: true, + parentLink: this, center: position.center, zoom: position.zoom, captionText: link.captionText, diff --git a/modules/mapframe/mapframe.js b/modules/mapframe/mapframe.js index 80619ff..a82d3eb 100644 --- a/modules/mapframe/mapframe.js +++ b/modules/mapframe/mapframe.js @@ -86,6 +86,7 @@ data.enableFullScreenButton = true; map = kartobox.map( { + featureType: 'mapframe', container: container, center: [ data.latitude, data.longitude ], zoom: data.zoom, @@ -93,6 +94,11 @@ allowFullScreen: true, dataGroups: data.overlays, captionText: data.captionText + } ); + mw.track( 'mediawiki.kartographer', { + action: 'view', + isFullScreen: false, + feature: map } ); mapsInArticle.push( map ); @@ -146,6 +152,15 @@ position = map.getInitialMapPosition(); } + // We need this hack to differentiate these events from `open` events. + if ( !map.fullScreenMap && !map.clicked ) { + mw.track( 'mediawiki.kartographer', { + action: 'hashopen', + isFullScreen: true, + feature: map + } ); + map.clicked = false; + } map.openFullScreen( position ); } ); diff --git a/modules/maplink/maplink.js b/modules/maplink/maplink.js index f2291c4..e31bdbb 100644 --- a/modules/maplink/maplink.js +++ b/modules/maplink/maplink.js @@ -68,15 +68,32 @@ // search outside. This is an anti-pattern and should be improved... // Meanwhile #content is better than searching the full document. $( '.mw-kartographer-maplink', '#content' ).each( function ( index ) { - var data = getMapData( this ); + var data = getMapData( this ), + link; - maplinks[ index ] = kartolink.link( { + link = maplinks[ index ] = kartolink.link( { + featureType: 'maplink', container: this, center: [ data.latitude, data.longitude ], zoom: data.zoom, dataGroups: data.overlays, captionText: data.captionText, fullScreenRoute: '/maplink/' + index + } ); + mw.track( 'mediawiki.kartographer', { + action: 'view', + isFullScreen: false, + feature: link + } ); + link.$container.click( function () { + // We need this hack to differentiate these events from `hashopen` events. + link.clicked = true; + + mw.track( 'mediawiki.kartographer', { + action: 'open', + isFullScreen: true, + feature: link + } ); } ); } ); @@ -107,6 +124,15 @@ }; } + // 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 ); } ); diff --git a/modules/staticframe/staticframe.js b/modules/staticframe/staticframe.js index 5d974e6..11d1ee3 100644 --- a/modules/staticframe/staticframe.js +++ b/modules/staticframe/staticframe.js @@ -100,12 +100,28 @@ data.enableFullScreenButton = true; link = kartolink.link( { + featureType: 'mapframe', container: container, center: [ data.latitude, data.longitude ], zoom: data.zoom, dataGroups: data.overlays, captionText: data.captionText, fullScreenRoute: '/map/' + index + } ); + mw.track( 'mediawiki.kartographer', { + action: 'view', + isFullScreen: false, + feature: link + } ); + link.$container.click( function () { + // We need this hack to differentiate these events from `hashopen` events. + link.clicked = true; + + mw.track( 'mediawiki.kartographer', { + action: 'open', + isFullScreen: true, + feature: link + } ); } ); mapsInArticle.push( link ); @@ -145,6 +161,15 @@ }; } + // 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 ); } ); diff --git a/templates/dialog-sidebar-externalservices.mustache b/templates/dialog-sidebar-externalservices.mustache index dddfa3f..93b43a2 100644 --- a/templates/dialog-sidebar-externalservices.mustache +++ b/templates/dialog-sidebar-externalservices.mustache @@ -13,7 +13,7 @@ <th>{{name}} </th> <td> - <a rel="nofollow" class="external free" href="{{link}}">{{linkLabel}}</a> + <a rel="nofollow" class="external free" href="{{link}}" data-service="{{id}}">{{linkLabel}}</a> </td> </tr> {{/services}} -- To view, visit https://gerrit.wikimedia.org/r/317995 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I66ba00cc2d86d9f1e49cbb46bd9ebd39650e3bea Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Kartographer Gerrit-Branch: master Gerrit-Owner: JGirault <julien.inbox.w...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits