mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-12 09:21:11 +00:00
Merge "[search] Instrument Vue.js-based search widget"
This commit is contained in:
commit
707862df60
|
@ -357,6 +357,7 @@ class Hooks {
|
|||
],
|
||||
"packageFiles" => [
|
||||
"resources/skins.vector.search/skins.vector.search.js",
|
||||
"resources/skins.vector.search/instrumentation.js",
|
||||
"resources/skins.vector.search/App.vue",
|
||||
[
|
||||
"name" => "resources/skins.vector.search/config.json",
|
||||
|
|
19
resources/mediawiki.d.ts
vendored
19
resources/mediawiki.d.ts
vendored
|
@ -4,6 +4,13 @@ interface MwApi {
|
|||
|
||||
type MwApiConstructor = new( options?: Object ) => MwApi;
|
||||
|
||||
interface MwUri {
|
||||
query: Record<string, unknown>;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
type UriConstructor = new( uri: string ) => MwUri;
|
||||
|
||||
interface MediaWiki {
|
||||
util: {
|
||||
/**
|
||||
|
@ -71,6 +78,18 @@ interface MediaWiki {
|
|||
* @param messageName i18n message name
|
||||
*/
|
||||
msg( messageName: string|null ): string;
|
||||
|
||||
/**
|
||||
* Track an analytic event.
|
||||
*
|
||||
* See https://gerrit.wikimedia.org/g/mediawiki/core/+/d7fe1ff0fe52735b1f41e91879c9617b376e807d/resources/src/mediawiki.base/mediawiki.base.js#375.
|
||||
*
|
||||
* @param topic The topic name
|
||||
* @param [data] The data describing the event
|
||||
*/
|
||||
track(topic: string, data?: Record<string, unknown>|number|string): void;
|
||||
|
||||
Uri: UriConstructor;
|
||||
}
|
||||
|
||||
declare const mw: MediaWiki;
|
||||
|
|
|
@ -16,17 +16,25 @@
|
|||
:search-language="language"
|
||||
:show-thumbnail="showThumbnail"
|
||||
:show-description="showDescription"
|
||||
@fetch-end="instrumentation.onFetchEnd"
|
||||
@suggestion-click="instrumentation.onSuggestionClick"
|
||||
>
|
||||
<input type="hidden"
|
||||
name="title"
|
||||
value="Special:Search"
|
||||
>
|
||||
<input type="hidden"
|
||||
name="wprov"
|
||||
:value="wprov"
|
||||
>
|
||||
</wvui-typeahead-search>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
var wvui = require( 'wvui' );
|
||||
/* global SubmitEvent */
|
||||
var wvui = require( 'wvui' ),
|
||||
instrumentation = require( './instrumentation.js' );
|
||||
|
||||
module.exports = {
|
||||
name: 'App',
|
||||
|
@ -91,6 +99,26 @@ module.exports = {
|
|||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
// -1 here is the default "active suggestion index" defined in the
|
||||
// `wvui-typeahead-search` component (see
|
||||
// https://gerrit.wikimedia.org/r/plugins/gitiles/wvui/+/c7af5d6d091ffb3beb4fd2723fdf50dc6bb2789b/src/components/typeahead-search/TypeaheadSearch.vue#167).
|
||||
wprov: instrumentation.getWprovFromResultIndex( -1 ),
|
||||
|
||||
instrumentation: instrumentation.listeners
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* @param {SubmitEvent} event
|
||||
*/
|
||||
onSubmit: function ( event ) {
|
||||
this.wprov = instrumentation.getWprovFromResultIndex( event.index );
|
||||
|
||||
instrumentation.listeners.onSubmit( event );
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
114
resources/skins.vector.search/instrumentation.js
Normal file
114
resources/skins.vector.search/instrumentation.js
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* global FetchEndEvent, SuggestionClickEvent, SubmitEvent */
|
||||
/** @module Instrumentation */
|
||||
|
||||
/**
|
||||
* The value of the `inputLocation` property of any and all SearchSatisfaction events sent by the
|
||||
* corresponding instrumentation.
|
||||
*
|
||||
* @see https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/skins/Vector/+/refs/heads/master/includes/Constants.php
|
||||
*/
|
||||
var INPUT_LOCATION_MOVED = 'header-moved',
|
||||
wgScript = mw.config.get( 'wgScript' );
|
||||
|
||||
/**
|
||||
* @param {FetchEndEvent} event
|
||||
*/
|
||||
function onFetchEnd( event ) {
|
||||
mw.track( 'mediawiki.searchSuggest', {
|
||||
action: 'impression-results',
|
||||
numberOfResults: event.numberOfResults,
|
||||
// resultSetType: '',
|
||||
// searchId: '',
|
||||
query: event.query,
|
||||
inputLocation: INPUT_LOCATION_MOVED
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SuggestionClickEvent|SubmitEvent} event
|
||||
*/
|
||||
function onSuggestionClick( event ) {
|
||||
mw.track( 'mediawiki.searchSuggest', {
|
||||
action: 'click-result',
|
||||
numberOfResults: event.numberOfResults,
|
||||
index: event.index
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the value of the `wprov` parameter to be used in the URL of a search result and the
|
||||
* `wprov` hidden input.
|
||||
*
|
||||
* See https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/WikimediaEvents/+/refs/heads/master/modules/ext.wikimediaEvents/searchSatisfaction.js
|
||||
* and also the top of that file for additional detail about the shape of the parameter.
|
||||
*
|
||||
* @param {number} index
|
||||
* @return {string}
|
||||
*/
|
||||
function getWprovFromResultIndex( index ) {
|
||||
|
||||
// If the user hasn't highlighted an autocomplete result.
|
||||
if ( index === -1 ) {
|
||||
return 'acrw1';
|
||||
}
|
||||
|
||||
return 'acrw1' + index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} SearchResultPartial
|
||||
* @property {string} title
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} GenerateUrlMeta
|
||||
* @property {number} index
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used by the `wvui-typeahead-search` component to generate URLs for the search results. Adds a
|
||||
* `wprov` paramater to the URL to satisfy the SearchSatisfaction instrumentation.
|
||||
*
|
||||
* @see getWprovFromResultIndex
|
||||
*
|
||||
* @param {SearchResultPartial|string} suggestion
|
||||
* @param {GenerateUrlMeta} meta
|
||||
* @return {string}
|
||||
*/
|
||||
function generateUrl( suggestion, meta ) {
|
||||
var result = new mw.Uri( wgScript );
|
||||
|
||||
if ( typeof suggestion !== 'string' ) {
|
||||
suggestion = suggestion.title;
|
||||
}
|
||||
|
||||
result.query.title = 'Special:Search';
|
||||
result.query.suggestion = suggestion;
|
||||
result.query.wprov = getWprovFromResultIndex( meta.index );
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
listeners: {
|
||||
onFetchEnd: onFetchEnd,
|
||||
onSuggestionClick: onSuggestionClick,
|
||||
|
||||
// As of writing (2020/12/08), both the "click-result" and "submit-form" kind of
|
||||
// mediawiki.searchSuggestion events result in a "click" SearchSatisfaction event being
|
||||
// logged [0]. However, when processing the "submit-form" kind of mediawiki.searchSuggestion
|
||||
// event, the SearchSatisfaction instrument will modify the DOM, adding a hidden input
|
||||
// element, in order to set the appropriate provenance parameter (see [1] for additional
|
||||
// detail).
|
||||
//
|
||||
// In this implementation of the mediawiki.searchSuggestion protocol, we don't want to
|
||||
// trigger the above behavior as we're using Vue.js, which doesn't expect the DOM to be
|
||||
// modified underneath it.
|
||||
//
|
||||
// [0] https://gerrit.wikimedia.org/g/mediawiki/extensions/WikimediaEvents/+/df97aa9c9407507e8c48827666beeab492fd56a8/modules/ext.wikimediaEvents/searchSatisfaction.js#735
|
||||
// [1] https://phabricator.wikimedia.org/T257698#6416826
|
||||
onSubmit: onSuggestionClick
|
||||
},
|
||||
getWprovFromResultIndex: getWprovFromResultIndex,
|
||||
generateUrl: generateUrl
|
||||
};
|
|
@ -1,3 +1,4 @@
|
|||
/** @module search */
|
||||
var
|
||||
Vue = require( 'vue' ).default || require( 'vue' ),
|
||||
App = require( './App.vue' ),
|
||||
|
|
17
resources/skins.vector.search/types.js
Normal file
17
resources/skins.vector.search/types.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @typedef {Object} FetchEndEvent
|
||||
* @property {number} numberOfResults
|
||||
* @property {string} query
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SuggestionClickEvent
|
||||
* @property {number} numberOfResults
|
||||
* @property {number} index
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {SuggestionClickEvent} SubmitEvent
|
||||
*/
|
||||
|
||||
/* exported SuggestionClickEvent, SubmitEvent, FetchEndEvent */
|
Loading…
Reference in a new issue