mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-26 16:40:33 +00:00
86c9693693
Change I765d3bbf89 pushes the module over the configured maximum allowed size (3 KiB, see bundlesize.config.json); shave off some bytes elsewhere to bring it below the limit again. IMHO all of these changes should be acceptable: * arrow functions are already used elsewhere in this module; * using the mw.config.get() fallback argument is normal (it slightly changes behavior, but I don’t think explicitly setting the search client or URL generator to a falsy value and expecting to get the default behavior should be considered supported); * not quoting [name="search"] matches [name=title] immediately above; * using forEach() with a function reference is still readable (initApp() is now called with extra arguments, but that doesn’t matter). Change-Id: I45dda26cb59279d91804b0c2bbf12174fa78ee12
109 lines
2.6 KiB
JavaScript
109 lines
2.6 KiB
JavaScript
/* global RestResult, SearchResult */
|
|
/** @module restSearchClient */
|
|
|
|
const fetchJson = require( './fetch.js' );
|
|
const urlGenerator = require( './urlGenerator.js' );
|
|
|
|
/**
|
|
* @typedef {Object} RestResponse
|
|
* @property {RestResult[]} pages
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} SearchResponse
|
|
* @property {string} query
|
|
* @property {SearchResult[]} results
|
|
*/
|
|
|
|
/**
|
|
* Nullish coalescing operator (??) helper
|
|
*
|
|
* @param {any} a
|
|
* @param {any} b
|
|
* @return {any}
|
|
*/
|
|
function nullish( a, b ) {
|
|
return ( a !== null && a !== undefined ) ? a : b;
|
|
}
|
|
|
|
/**
|
|
* @param {MwMap} config
|
|
* @param {string} query
|
|
* @param {RestResponse} restResponse
|
|
* @param {boolean} showDescription
|
|
* @return {SearchResponse}
|
|
*/
|
|
function adaptApiResponse( config, query, restResponse, showDescription ) {
|
|
const urlGeneratorInstance = urlGenerator( config );
|
|
return {
|
|
query,
|
|
results: restResponse.pages.map( ( page, index ) => {
|
|
const thumbnail = page.thumbnail;
|
|
return {
|
|
id: page.id,
|
|
value: page.id || -( index + 1 ),
|
|
label: page.title,
|
|
key: page.key,
|
|
title: page.title,
|
|
description: showDescription ? page.description : undefined,
|
|
url: urlGeneratorInstance.generateUrl( page ),
|
|
thumbnail: thumbnail ? {
|
|
url: thumbnail.url,
|
|
width: nullish( thumbnail.width, undefined ),
|
|
height: nullish( thumbnail.height, undefined )
|
|
} : undefined
|
|
};
|
|
} )
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @typedef {Object} AbortableSearchFetch
|
|
* @property {Promise<SearchResponse>} fetch
|
|
* @property {Function} abort
|
|
*/
|
|
|
|
/**
|
|
* @callback fetchByTitle
|
|
* @param {string} query The search term.
|
|
* @param {string} domain The base URL for the wiki without protocol. Example: 'sr.wikipedia.org'.
|
|
* @param {number} [limit] Maximum number of results.
|
|
* @return {AbortableSearchFetch}
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} SearchClient
|
|
* @property {fetchByTitle} fetchByTitle
|
|
*/
|
|
|
|
/**
|
|
* @param {MwMap} config
|
|
* @return {SearchClient}
|
|
*/
|
|
function restSearchClient( config ) {
|
|
return config.get( 'wgVectorSearchClient', {
|
|
/**
|
|
* @type {fetchByTitle}
|
|
*/
|
|
fetchByTitle: ( q, domain, limit = 10, showDescription = true ) => {
|
|
const params = { q, limit };
|
|
const url = '//' + domain + config.get( 'wgScriptPath' ) + '/rest.php/v1/search/title?' + $.param( params );
|
|
const result = fetchJson( url, {
|
|
headers: {
|
|
accept: 'application/json'
|
|
}
|
|
} );
|
|
const searchResponsePromise = result.fetch
|
|
.then( ( /** @type {RestResponse} */ res ) => {
|
|
return adaptApiResponse( config, q, res, showDescription );
|
|
} );
|
|
return {
|
|
abort: result.abort,
|
|
fetch: searchResponsePromise
|
|
};
|
|
}
|
|
} );
|
|
}
|
|
|
|
module.exports = restSearchClient;
|