refactor(search): ♻️ clean up clearSuggestion

This commit is contained in:
alistair3149 2022-12-14 00:45:43 -05:00
parent 4d1225b96f
commit 6aa587635d
No known key found for this signature in database

View file

@ -1,7 +1,8 @@
const const
config = require( './config.json' ), config = require( './config.json' ),
PREFIX = 'citizen-typeahead', PREFIX = 'citizen-typeahead',
SEARCH_LOADING_CLASS = 'citizen-loading'; SEARCH_LOADING_CLASS = 'citizen-loading',
HIDDEN_CLASS = PREFIX + '__item--hidden';
const activeIndex = { const activeIndex = {
index: -1, index: -1,
@ -123,29 +124,22 @@ function bindMouseHoverEvent( element ) {
* @return {void} * @return {void}
*/ */
function clearSuggestions() { function clearSuggestions() {
const typeaheadItems = typeahead.children, const typeaheadItems = typeahead.children;
nonSuggestionCount = 3;
if ( typeaheadItems.length > nonSuggestionCount ) { if ( typeaheadItems.length > 0 ) {
// Splice would be cleaner but it is slower (?) // Do all the work in document fragment then replace the whole list
const fragment = new DocumentFragment(), // It is more performant this way
nonSuggestionItems = [ ...typeaheadItems ].slice( const
typeaheadItems.length - nonSuggestionCount, typeaheadItems.length fragment = new DocumentFragment(),
); template = document.getElementById( PREFIX + '-template' );
nonSuggestionItems.forEach( ( item ) => { [ ...typeaheadItems ].forEach( ( item ) => {
fragment.append( item ); if ( !item.classList.contains( PREFIX + '__item--page' ) ) {
} ); fragment.append( item );
// TODO: Just use replaceChildren when browser support is >90%
if ( typeof typeahead.replaceChildren !== 'undefined' ) {
typeahead.replaceChildren( fragment );
} else {
while ( typeahead.hasChildNodes() ) {
typeahead.removeChild( typeahead.lastChild );
} }
typeahead.appendChild( fragment ); } );
} fragment.append( template );
typeahead.replaceChildren( fragment );
} }
// Remove loading animation // Remove loading animation
@ -227,7 +221,7 @@ function getSuggestions( searchQuery, htmlSafeSearchQuery, placeholder ) {
fragment.append( getMenuItem( data ) ); fragment.append( getMenuItem( data ) );
} ); } );
// Hide placeholder // Hide placeholder
placeholder.classList.add( PREFIX + '__item--hidden' ); placeholder.classList.add( HIDDEN_CLASS );
typeahead.prepend( fragment ); typeahead.prepend( fragment );
} else { } else {
// Update placeholder with no result content // Update placeholder with no result content
@ -240,7 +234,7 @@ function getSuggestions( searchQuery, htmlSafeSearchQuery, placeholder ) {
description: mw.message( 'citizen-search-noresults-desc' ).text() description: mw.message( 'citizen-search-noresults-desc' ).text()
} }
); );
placeholder.classList.remove( PREFIX + '__item--hidden' ); placeholder.classList.remove( HIDDEN_CLASS );
} }
}; };
@ -356,46 +350,51 @@ function updateTypeahead( messages ) {
hasQuery = searchQuery.length > 0, hasQuery = searchQuery.length > 0,
placeholder = typeahead.querySelector( '.' + PREFIX + '__item--placeholder' ); placeholder = typeahead.querySelector( '.' + PREFIX + '__item--placeholder' );
const updateFullTextSearchItem = () => { const updateToolItem = ( data ) => {
const const
FULLTEXT_ID = PREFIX + '-fulltext', itemId = PREFIX + '-' + data.id,
HIDDEN_CLASS = PREFIX + '__item--hidden';
const
fulltextEl = document.getElementById( FULLTEXT_ID ),
query = '<span class="citizen-typeahead__query">' + htmlSafeSearchQuery + '</span>', query = '<span class="citizen-typeahead__query">' + htmlSafeSearchQuery + '</span>',
fulltextLink = config.wgScriptPath + '/index.php?title=Special:Search&fulltext=1&search=' + htmlSafeSearchQuery, itemLink = data.link + htmlSafeSearchQuery,
fulltextText = mw.message( 'citizen-search-fulltext', query ); /* eslint-disable-next-line mediawiki/msg-doc */
itemDesc = mw.message( data.msg, query );
let item = document.getElementById( itemId );
// Update existing element instead of creating a new one // Update existing element instead of creating a new one
if ( fulltextEl ) { if ( item ) {
// FIXME: Probably more efficient to just replace the query than the whole messaage? // FIXME: Probably more efficient to just replace the query than the whole messaage?
updateMenuItem( updateMenuItem(
fulltextEl, item,
{ {
link: fulltextLink, link: itemLink,
description: fulltextText description: itemDesc
} }
); );
// FIXME: There is probably a more efficient way // FIXME: There is probably a more efficient way
if ( hasQuery ) { if ( hasQuery ) {
fulltextEl.classList.remove( HIDDEN_CLASS ); item.classList.remove( HIDDEN_CLASS );
} else { } else {
fulltextEl.classList.add( HIDDEN_CLASS ); item.classList.add( HIDDEN_CLASS );
} }
} else { } else {
const item = getMenuItem( { item = getMenuItem( {
icon: 'articleSearch', icon: data.icon,
id: FULLTEXT_ID, id: itemId,
type: 'tool', type: 'tool',
link: fulltextLink, link: itemLink,
description: fulltextText description: itemDesc
} ); } );
typeahead.append( item ); typeahead.append( item );
} }
}; };
updateFullTextSearchItem(); // Fulltext search
updateToolItem( {
id: 'fulltext',
link: config.wgScriptPath + '/index.php?title=Special:Search&fulltext=1&search=',
icon: 'articleSearch',
msg: 'citizen-search-fulltext'
} );
if ( hasQuery ) { if ( hasQuery ) {
getSuggestions( searchQuery, htmlSafeSearchQuery, placeholder ); getSuggestions( searchQuery, htmlSafeSearchQuery, placeholder );
@ -410,7 +409,7 @@ function updateTypeahead( messages ) {
description: messages.fulltextEmpty description: messages.fulltextEmpty
} }
); );
placeholder.classList.remove( PREFIX + '__item--hidden' ); placeholder.classList.remove( HIDDEN_CLASS );
} }
} }