$t: title object searched for
&$params: an array of the default message name and page title (as parameter)
+'SpecialSearchGoResult': If a hook returns false the 'go' feature will be
+canceled and a normal search will be performed. Returning true without setting
+$url does a standard redirect to $title. Setting $url redirects to the
+specified URL.
+$term - The string the user searched for
+$title - The title the 'go' feature has decided to forward the user to
+&$url - Initially null, hook subscribers can set this to specify the final url to redirect to
+
'SpecialSearchNogomatch': Called when user clicked the "Go" button but the
target doesn't exist.
&$title: title object generated from the text entered by the user
# If there's an exact or very near match, jump right there.
$title = SearchEngine::getNearMatch( $term );
- if ( !is_null( $title ) ) {
- $this->getOutput()->redirect( $title->getFullURL() );
+ if ( !is_null( $title ) &&
+ Hooks::run( 'SpecialSearchGoResult', [ $term, $title, &$url ] )
+ ) {
+ if ( $url === null ) {
+ $url = $title->getFullURL();
+ }
+ $this->getOutput()->redirect( $url );
return;
}
'size' => '50',
'autofocus' => trim( $term ) === '',
'class' => 'mw-ui-input mw-ui-input-inline',
+ // identifies the location of the search bar for tracking purposes
+ 'data-search-loc' => 'content',
] ) . "\n";
$out .= Html::hidden( 'fulltext', 'Search' ) . "\n";
$out .= Html::submitButton(
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 );
+ context.config.update.after.call( context.data.$textbox, cache[ val ].metadata );
}
cacheHit = true;
} else {
context.config.fetch.call(
context.data.$textbox,
val,
- function ( suggestions ) {
+ function ( suggestions, metadata ) {
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 );
+ context.config.update.after.call( context.data.$textbox, metadata );
}
if ( context.config.cache ) {
cache[ val ] = {
suggestions: suggestions,
+ metadata: metadata,
timestamp: +new Date()
};
}
namespace: 0,
limit: maxRows,
suggest: true
- } ).done( function ( data ) {
- response( data[ 1 ] );
+ } ).done( function ( data, jqXHR ) {
+ response( data[ 1 ], {
+ type: jqXHR.getResponseHeader( 'X-OpenSearch-Type' ),
+ query: query
+ } );
} );
- },
- // The name of the request api for event logging purposes
- type: 'prefix'
+ }
};
$( function () {
previousSearchText = searchText;
}
+ /**
+ * defines the location of autocomplete. Typically either
+ * header, which is in the top right of vector (for example)
+ * and content which identifies the main search bar on
+ * Special:Search. Defaults to header for skins that don't set
+ * explicitly.
+ *
+ * @ignore
+ */
+ function getInputLocation( context ) {
+ return context.config.$region
+ .closest( 'form' )
+ .find( '[data-search-loc]' )
+ .data( 'search-loc' ) || 'header';
+ }
+
/**
* 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() {
+ function onAfterUpdate( metadata ) {
var context = this.data( 'suggestionsContext' );
mw.track( 'mediawiki.searchSuggest', {
action: 'impression-results',
numberOfResults: context.config.suggestions.length,
- resultSetType: mw.searchSuggest.type
+ resultSetType: metadata.type || 'unknown',
+ query: metadata.query,
+ inputLocation: getInputLocation( context )
} );
}
// linkParams object is modified and reused
formData.linkParams[ formData.textParam ] = text;
+ // Allow trackers to attach tracking information, such
+ // as wprov, to clicked links.
+ mw.track( 'mediawiki.searchSuggest', {
+ action: 'render-one',
+ formData: formData,
+ index: context.config.suggestions.indexOf( text ) + 1
+ } );
+
// this is the container <div>, jQueryfied
this.text( text )
.wrap(
return true;
}
},
+ update: {
+ before: onBeforeUpdate,
+ after: onAfterUpdate
+ },
cache: true,
highlightInput: true
} )
var context = $searchInput.data( 'suggestionsContext' );
mw.track( 'mediawiki.searchSuggest', {
action: 'submit-form',
- numberOfResults: context.config.suggestions.length
+ numberOfResults: context.config.suggestions.length,
+ $form: context.config.$region.closest( 'form' ),
+ inputLocation: getInputLocation( context )
} );
} )
// If the form includes any fallback fulltext search buttons, remove them