mirror of
https://github.com/StarCitizenTools/mediawiki-skins-Citizen.git
synced 2024-11-15 02:24:04 +00:00
refactor(core): ♻️ move some suggestion functions to searchResults
This commit is contained in:
parent
434ec2ebaf
commit
ae7a01f690
|
@ -2,8 +2,77 @@
|
|||
// const htmlHelper = require( './htmlHelper.js' )();
|
||||
const searchAction = require( './searchAction.js' )();
|
||||
|
||||
/**
|
||||
* Returns an object with methods related to search results handling.
|
||||
*
|
||||
* @return {Object} An object with the following methods:
|
||||
* - getRedirectLabel: A function that generates HTML for a search result label with redirection information.
|
||||
* - highlightTitle: A function that highlights a matched title within a given text.
|
||||
* - fetch: A function that fetches search results based on a query value using an active search client.
|
||||
* - render: A function that renders search results in a specified typeahead element.
|
||||
* - clear: A function that clears search results from a typeahead element.
|
||||
*/
|
||||
function searchResults() {
|
||||
return {
|
||||
getRedirectLabel: function ( title, matchedTitle, queryValue ) {
|
||||
const normalizeText = ( text ) => {
|
||||
return text.replace( /[-\s]/g, ( match ) => match.toLowerCase() ).toLowerCase();
|
||||
};
|
||||
|
||||
const redirectMessageCache = {};
|
||||
const getRedirectMessage = () => {
|
||||
if ( !redirectMessageCache[ matchedTitle ] ) {
|
||||
redirectMessageCache[ matchedTitle ] = mw.message( 'search-redirect', matchedTitle ).plain();
|
||||
}
|
||||
return redirectMessageCache[ matchedTitle ];
|
||||
};
|
||||
|
||||
const isRedirectUseful = () => {
|
||||
const cleanTitle = normalizeText( title );
|
||||
const cleanMatchedTitle = normalizeText( matchedTitle );
|
||||
|
||||
return !(
|
||||
cleanTitle.includes( cleanMatchedTitle ) ||
|
||||
cleanMatchedTitle.includes( cleanTitle )
|
||||
);
|
||||
};
|
||||
|
||||
const generateRedirectHtml = () => {
|
||||
const div = document.createElement( 'div' );
|
||||
div.classList.add( 'citizen-typeahead__labelItem' );
|
||||
div.title = getRedirectMessage( matchedTitle );
|
||||
|
||||
const spanIcon = document.createElement( 'span' );
|
||||
spanIcon.classList.add( 'citizen-ui-icon', 'mw-ui-icon-wikimedia-articleRedirect' );
|
||||
div.appendChild( spanIcon );
|
||||
|
||||
const spanText = document.createElement( 'span' );
|
||||
spanText.textContent = this.highlightTitle( matchedTitle, queryValue );
|
||||
div.appendChild( spanText );
|
||||
|
||||
return div.outerHTML;
|
||||
};
|
||||
|
||||
let html = '';
|
||||
if ( matchedTitle && isRedirectUseful() ) {
|
||||
html = generateRedirectHtml();
|
||||
}
|
||||
|
||||
return html;
|
||||
},
|
||||
highlightTitle: ( function () {
|
||||
const regexCache = {};
|
||||
return function ( title, match ) {
|
||||
if ( !match ) {
|
||||
return title;
|
||||
}
|
||||
if ( !regexCache[ match ] ) {
|
||||
regexCache[ match ] = new RegExp( mw.util.escapeRegExp( match ), 'i' );
|
||||
}
|
||||
const regex = regexCache[ match ];
|
||||
return title.replace( regex, '<span class="citizen-typeahead__highlight">$&</span>' );
|
||||
};
|
||||
}() ),
|
||||
fetch: function ( queryValue, activeSearchClient ) {
|
||||
return activeSearchClient.fetchByTitle( queryValue );
|
||||
},
|
||||
|
|
|
@ -344,57 +344,6 @@ async function getSuggestions() {
|
|||
const renderSuggestions = ( results ) => {
|
||||
const fragment = document.createDocumentFragment();
|
||||
if ( results.length > 0 ) {
|
||||
/**
|
||||
* Return the redirect title with search query highlight
|
||||
*
|
||||
* @param {string} text
|
||||
* @return {string}
|
||||
*/
|
||||
const highlightTitle = ( text ) => {
|
||||
const regex = new RegExp( mw.util.escapeRegExp( searchQuery.valueHtml ), 'i' );
|
||||
return text.replace( regex, `<span class="${ PREFIX }__highlight">$&</span>` );
|
||||
};
|
||||
/**
|
||||
* Return the HTML of the redirect label
|
||||
*
|
||||
* @param {string} title
|
||||
* @param {string} matchedTitle
|
||||
* @return {string}
|
||||
*/
|
||||
const getRedirectLabel = ( title, matchedTitle ) => {
|
||||
/**
|
||||
* Check if the redirect is useful (T303013)
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
const isRedirectUseful = () => {
|
||||
// Change to lowercase then remove space and dashes
|
||||
const cleanup = ( text ) => {
|
||||
return text.toLowerCase().replace( /[-\s]/g, '' );
|
||||
};
|
||||
const
|
||||
cleanTitle = cleanup( title ),
|
||||
cleanMatchedTitle = cleanup( matchedTitle );
|
||||
|
||||
return !(
|
||||
cleanTitle.includes( cleanMatchedTitle ) ||
|
||||
cleanMatchedTitle.includes( cleanTitle )
|
||||
);
|
||||
};
|
||||
|
||||
let html = '';
|
||||
// Result is a redirect
|
||||
// Show the redirect title and highlight it
|
||||
if ( matchedTitle && isRedirectUseful() ) {
|
||||
html = `<div class="${ PREFIX }__labelItem" title="${ mw.message( 'search-redirect', matchedTitle ).plain() }">
|
||||
<span class="citizen-ui-icon mw-ui-icon-wikimedia-articleRedirect"></span>
|
||||
<span>${ highlightTitle( matchedTitle ) }</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
// Create suggestion items
|
||||
const itemGroupData = {
|
||||
id: 'suggestion',
|
||||
|
@ -405,10 +354,10 @@ async function getSuggestions() {
|
|||
type: 'page',
|
||||
size: 'md',
|
||||
link: result.url,
|
||||
title: highlightTitle( result.title ),
|
||||
title: searchResults.highlightTitle( result.title, searchQuery.valueHtml ),
|
||||
desc: result.description
|
||||
};
|
||||
data.label = getRedirectLabel( result.title, result.label );
|
||||
data.label = searchResults.getRedirectLabel( result.title, result.label );
|
||||
if ( result.thumbnail ) {
|
||||
data.thumbnail = result.thumbnail.url;
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue