diff --git a/Popups.hooks.php b/Popups.hooks.php index 07e62cb0e..0bd8e8da9 100644 --- a/Popups.hooks.php +++ b/Popups.hooks.php @@ -40,6 +40,7 @@ class PopupsHooks { && class_exists( 'ApiQueryPageImages' ) ) { $out->addModules( array( 'ext.popups' ) ); + $out->addModules( array( 'schema.Popups' ) ); } } } diff --git a/Popups.php b/Popups.php index a9f3a6ca3..cf0b313c7 100644 --- a/Popups.php +++ b/Popups.php @@ -34,7 +34,7 @@ $localBasePath = dirname( __DIR__ ) . '/Popups'; $remoteExtPath = 'Popups'; $wgResourceModules = array_merge( $wgResourceModules, array( - "ext.popups" => array( + 'ext.popups' => array( 'scripts' => array( 'resources/ext.popups.core.js', ), @@ -56,6 +56,12 @@ $wgResourceModules = array_merge( $wgResourceModules, array( 'remoteExtPath' => $remoteExtPath, 'localBasePath' => $localBasePath, ), + + 'schema.Popups' => array( + 'class' => 'ResourceLoaderSchemaModule', + 'schema' => 'Popups', + 'revision' => 7536956, + ), ) ); $wgAutoloadClasses['PopupsHooks'] = __DIR__ . '/Popups.hooks.php'; diff --git a/resources/ext.popups.core.js b/resources/ext.popups.core.js index f3870f4d7..f7947786b 100644 --- a/resources/ext.popups.core.js +++ b/resources/ext.popups.core.js @@ -9,6 +9,10 @@ var closeTimer, // The timer use to delay `closeBox` openTimer, // The timer used to delay sending the API request/opening the popup form cache + elTime, // EL: UNIX timestamp of when the popup was rendered + elDuration, // EL: How long was the popup open in milliseconds + elAction, // EL: Was the popup clicked or middle clicked or dismissed + elSessionId, // EL: Get defined after the getSessionId method is created currentLink, // DOM element of the current anchor tag cache = {}, curRequest, // Current API request @@ -70,7 +74,11 @@ ); } - $a = $( '' ).append( $thumbnail, $contentbox, $timestamp).attr( 'href', href ); + $a = $( '' ) + .append( $thumbnail, $contentbox, $timestamp) + .attr( 'href', href ) + .on( 'click', logClick ); + cache[ href ] = { box: $a, thumbnail: thumbnail, tall: tall }; createBox( href, $el ); }); @@ -121,6 +129,10 @@ var bar = cache[ href ], offsetTop = $el.offset().top + $el.height() + 5, offsetLeft = $el.offset().left; + + elTime = mw.now(); + elAction = 'dismissed'; + $box .children() .detach() @@ -170,6 +182,8 @@ * `currentLink` to undefined. */ function closeBox () { + elDuration = mw.now() - elTime; + $( currentLink ).removeClass( 'mwe-popups-anchor-hover' ).off( 'mouseleave', leaveActive ); $box @@ -187,9 +201,81 @@ if ( closeTimer ){ clearTimeout( closeTimer ); } + + logEvent(); currentLink = closeTimer = undefined; } + /** + * @method logClick + * Logs different actions such as meta and shift click on the popup. + * Is bound to the `click` event. + * @param {Object} e + */ + function logClick ( e ) { + if ( e.which === 2) { // middle click + elAction = 'opened in new tab'; + } else if ( e.which === 1) { + if ( e.ctrlKey || e.metaKey ) { + elAction = 'opened in new tab'; + } else if ( e.shiftKey ){ + elAction = 'opened in new window'; + } else { + elAction = 'opened in same tab'; + elDuration = mw.now() - elTime; + logEvent( this.href ); + e.preventDefault(); + } + } + } + + /** + * @method logEvent + * Logs the Popup event as defined in the following schema - + * https://meta.wikimedia.org/wiki/Schema:Popups + * If `href` is passed it redirects to that location after the event is logged. + * @param {string} href + */ + function logEvent ( href ) { + var dfd = $.Deferred(), + event = { + 'duration': Math.round( elDuration ), + 'action': elAction + }; + + if ( elSessionId !== null ) { + event.sessionId = elSessionId; + } + + if ( href ) { + dfd.always( function () { + location.href = href; + } ); + } + + mw.eventLog.logEvent( 'Popups', event ).then( dfd.resolve, dfd.reject ); + setTimeout( dfd.reject, 1000 ); + elTime = elDuration = elAction = undefined; + } + + /** + * @method getSessionId + * Generates a unique sessionId or pulls an existing one from localStorage + * @return {string} sessionId + */ + function getSessionId () { + var sessionId = null; + try { + sessionId = localStorage.getItem( 'popupsSessionId' ); + if ( sessionId === null ) { + sessionId = mw.user.generateRandomSessionId(); + localStorage.setItem( 'popupsSessionId', sessionId ); + } + } catch ( e ) {} + return sessionId; + } + elSessionId = getSessionId(); + // Remove title attribute to remove the default yellow tooltip // Put the title back after the hover $( '#mw-content-text a' )