Always add 1 prefixsearch match when searching for templates

We do this additional prefixsearch anyway. What we did before
was ignoring the result when it was not a 100% exact match.
Instead we can always add this 1 prefixsearch result when it
was not already part of the CirrusSearch result set.

This won't happen often. Usually the 1st prefixsearch result
was already part of the CirrusSearch result set anyway. But
if it wasn't, that's a serious issue for expert users that
expect the search to behave similar to the suggester at the
top of the MediaWiki interface (which is also a prefixsearch).

Change-Id: I959d2b058a3d64596a8cfbe5476ab351e40f8760
This commit is contained in:
Thiemo Kreuz 2021-07-08 11:09:17 +02:00
parent c2bc8c7e26
commit ba1718ea11

View file

@ -196,8 +196,7 @@ ve.ui.MWTemplateTitleInputWidget.prototype.getLookupRequest = function () {
ve.ui.MWTemplateTitleInputWidget.prototype.addExactMatch = function ( response ) {
var widget = this,
query = this.getQueryValue(),
namespace = this.namespace,
title = mw.Title.newFromText( query, namespace );
title = mw.Title.newFromText( query, this.namespace );
// No point in trying anything when the title is invalid
if ( !response.query || !title ) {
return response;
@ -213,6 +212,17 @@ ve.ui.MWTemplateTitleInputWidget.prototype.addExactMatch = function ( response )
return response;
}
/**
* @param {{pageid: number}[]} pages
* @param {number} pageId
* @return {boolean}
*/
function containsPageId( pages, pageId ) {
return pageId && pages.some( function ( page ) {
return page.pageid === pageId;
} );
}
/**
* @param {{index: number}[]} pages
* @param {Object} [newPage]
@ -260,23 +270,21 @@ ve.ui.MWTemplateTitleInputWidget.prototype.addExactMatch = function ( response )
}
return this.getApi().get( {
action: 'query',
// Can't use a direct lookup by title because we need this to be case-insensitive
action: 'opensearch',
format: 'json',
search: query,
namespace: namespace,
limit: 1,
formatversion: 2
} ).then( function ( openSearchResult ) {
// OpenSearch will perform a prefix search, but we only care about exact matches
var titles = openSearchResult[ 1 ].filter( function ( searchResult ) {
return searchResult.toLowerCase() === lowerTitle;
} );
for ( i = titles.length; i--; ) {
unshiftPages( response.query.pages, {
ns: namespace,
title: titles[ i ]
} );
generator: 'prefixsearch',
gpssearch: query,
gpsnamespace: this.namespace,
gpslimit: 1
} ).then( function ( prefixMatches ) {
// action=query returns page objects in `{ query: { pages: [] } }`, not keyed by page id
if ( prefixMatches.query ) {
for ( var index in prefixMatches.query.pages ) {
var prefixMatch = prefixMatches.query.pages[ index ];
if ( !containsPageId( response.query.pages, prefixMatch.pageid ) ) {
unshiftPages( response.query.pages, prefixMatch );
}
}
}
return response;
}, function () {