From b5540861338a6590f571a1336f95401681f4b4a1 Mon Sep 17 00:00:00 2001 From: Baha Man Date: Mon, 23 Mar 2015 19:11:21 -0400 Subject: [PATCH] Track search events Tracking works only for the skin-provided search box (top right search box on desktop). Also, add the 'update' option the jQuery suggestions extension. Change-Id: Icc0afcd6c9fa8c82a95d9decf988a19ae3edc165 --- resources/src/jquery/jquery.suggestions.js | 20 +++++- .../src/mediawiki/mediawiki.searchSuggest.js | 61 ++++++++++++++++++- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/resources/src/jquery/jquery.suggestions.js b/resources/src/jquery/jquery.suggestions.js index 813c37ce87..7c9bec3220 100644 --- a/resources/src/jquery/jquery.suggestions.js +++ b/resources/src/jquery/jquery.suggestions.js @@ -53,6 +53,12 @@ * @param {Function} options.result.select Called in context of the suggestions-result-current element. * @param {jQuery} options.result.select.$textbox * + * @param {Object} [options.update] Set of callbacks for listening to a change in the text input. + * + * @param {Function} options.update.before Called right after the user changes the textbox text. + * @param {Function} options.update.after Called after results are updated either from the cache or + * the API as a result of the user input. + * * @param {jQuery} [options.$region=this] The element to place the suggestions below and match width of. * * @param {string[]} [options.suggestions] Array of suggestions to display. @@ -83,7 +89,7 @@ * @param {boolean} [options.positionFromLeft] Sets `expandFrom=left`, for backwards * compatibility. * - * @param {boolean} [options.highlightInput=false] Whether to hightlight matched portions of the + * @param {boolean} [options.highlightInput=false] Whether to highlight matched portions of the * input or not. */ ( function ( $ ) { @@ -144,6 +150,10 @@ $.suggestions = { cache = context.data.cache, cacheHit; + if ( typeof context.config.update.before === 'function' ) { + context.config.update.before.call( context.data.$textbox ); + } + // Only fetch if the value in the textbox changed and is not empty, or if the results were hidden // if the textbox is empty then clear the result div, but leave other settings intouched if ( val.length === 0 ) { @@ -158,6 +168,9 @@ $.suggestions = { if ( context.config.cache && hasOwn.call( cache, val ) ) { if ( +new Date() - cache[ val ].timestamp < context.config.cacheMaxAge ) { context.data.$textbox.suggestions( 'suggestions', cache[ val ].suggestions ); + if ( typeof context.config.update.after === 'function' ) { + context.config.update.after.call( context.data.$textbox ); + } cacheHit = true; } else { // Cache expired @@ -171,6 +184,9 @@ $.suggestions = { function ( suggestions ) { suggestions = suggestions.slice( 0, context.config.maxRows ); context.data.$textbox.suggestions( 'suggestions', suggestions ); + if ( typeof context.config.update.after === 'function' ) { + context.config.update.after.call( context.data.$textbox ); + } if ( context.config.cache ) { cache[ val ] = { suggestions: suggestions, @@ -227,6 +243,7 @@ $.suggestions = { case 'cancel': case 'special': case 'result': + case 'update': case '$region': case 'expandFrom': context.config[property] = value; @@ -559,6 +576,7 @@ $.fn.suggestions = function () { cancel: function () {}, special: {}, result: {}, + update: {}, $region: $( this ), suggestions: [], maxRows: 10, diff --git a/resources/src/mediawiki/mediawiki.searchSuggest.js b/resources/src/mediawiki/mediawiki.searchSuggest.js index 7b7ccf3f55..f981b90acc 100644 --- a/resources/src/mediawiki/mediawiki.searchSuggest.js +++ b/resources/src/mediawiki/mediawiki.searchSuggest.js @@ -12,7 +12,8 @@ // element (not the search form, as that would leave the buttons // vertically between the input and the suggestions). $searchRegion = $( '#simpleSearch, #searchInput' ).first(), - $searchInput = $( '#searchInput' ); + $searchInput = $( '#searchInput' ), + previousSearchText = $searchInput.val(); // Compatibility map map = { @@ -50,6 +51,39 @@ }; } + /** + * Callback that's run when the user changes the search input text + * 'this' is the search input box (jQuery object) + * @ignore + */ + function onBeforeUpdate() { + var searchText = this.val(); + + if ( searchText && searchText !== previousSearchText ) { + mw.track( 'mediawiki.searchSuggest', { + action: 'session-start' + } ); + } + previousSearchText = searchText; + } + + /** + * Callback that's run when suggestions have been updated either from the cache or the API + * 'this' is the search input box (jQuery object) + * @ignore + */ + function onAfterUpdate() { + var context = this.data( 'suggestionsContext' ); + + mw.track( 'mediawiki.searchSuggest', { + action: 'impression-results', + numberOfResults: context.config.suggestions.length, + // FIXME: when other types of search become available change this value accordingly + // See the API call below (opensearch = prefix) + resultSetType: 'prefix' + } ); + } + // The function used to render the suggestions. function renderFunction( text, context ) { if ( !resultRenderCache ) { @@ -69,6 +103,21 @@ ); } + // The function used when the user makes a selection + function selectFunction( $input ) { + var context = $input.data( 'suggestionsContext' ), + text = $input.val(); + + mw.track( 'mediawiki.searchSuggest', { + action: 'click-result', + numberOfResults: context.config.suggestions.length, + clickIndex: context.config.suggestions.indexOf( text ) + 1 + } ); + + // allow the form to be submitted + return true; + } + function specialRenderFunction( query, context ) { var $el = this; @@ -177,8 +226,16 @@ return; } - // Special suggestions functionality for skin-provided search box + // Special suggestions functionality and tracking for skin-provided search box $searchInput.suggestions( { + update: { + before: onBeforeUpdate, + after: onAfterUpdate + }, + result: { + render: renderFunction, + select: selectFunction + }, special: { render: specialRenderFunction, select: function ( $input ) { -- 2.20.1