mirror of
https://github.com/StarCitizenTools/mediawiki-skins-Citizen.git
synced 2024-09-23 10:19:43 +00:00
refactor(search): ♻️ partial cleanup on typeahead DOM
This commit is contained in:
parent
22e1324a80
commit
99b3523cd6
|
@ -15,74 +15,82 @@
|
|||
// Well this won't be loaded before .citizen-animation-ready anyways
|
||||
.citizen-card-transition();
|
||||
|
||||
&-suggestion {
|
||||
padding-top: 0.375rem;
|
||||
padding-bottom: 0.375rem;
|
||||
|
||||
&__thumbnail {
|
||||
overflow: hidden;
|
||||
height: 60px;
|
||||
border-radius: var( --border-radius--medium );
|
||||
background-color: #eaecf0;
|
||||
|
||||
img,
|
||||
source {
|
||||
object-fit: cover;
|
||||
}
|
||||
&__item {
|
||||
&--active {
|
||||
background-color: var( --background-color-primary--hover );
|
||||
}
|
||||
}
|
||||
|
||||
&__text {
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
white-space: nowrap;
|
||||
&__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.375rem 0.75rem;
|
||||
color: var( --color-base );
|
||||
}
|
||||
|
||||
&__thumbnail {
|
||||
overflow: hidden;
|
||||
height: 60px;
|
||||
border-radius: var( --border-radius--medium );
|
||||
background-color: #eaecf0;
|
||||
|
||||
img,
|
||||
source {
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
&__text {
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&__title {
|
||||
flex-shrink: 0;
|
||||
color: var( --color-base--emphasized );
|
||||
font-weight: var( --font-weight-semibold );
|
||||
}
|
||||
|
||||
&__highlight {
|
||||
color: var( --color-base--subtle );
|
||||
font-weight: var( --font-weight-medium );
|
||||
}
|
||||
|
||||
&__label {
|
||||
display: flex;
|
||||
margin-left: var( --space-xs );
|
||||
color: var( --color-base );
|
||||
font-size: 0.8125rem;
|
||||
gap: var( --space-xxs );
|
||||
|
||||
.citizen-ui-icon {
|
||||
width: 0.8125rem;
|
||||
height: 0.8125rem;
|
||||
margin-right: var( --space-xxs );
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
flex-shrink: 0;
|
||||
color: var( --color-base--emphasized );
|
||||
font-weight: var( --font-weight-semibold );
|
||||
}
|
||||
&__labelItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__highlight {
|
||||
color: var( --color-base--subtle );
|
||||
font-weight: var( --font-weight-medium );
|
||||
}
|
||||
&__description {
|
||||
margin-top: 0.1rem;
|
||||
color: var( --color-base--subtle );
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
&__label {
|
||||
display: flex;
|
||||
margin-left: var( --space-xs );
|
||||
color: var( --color-base );
|
||||
font-size: 0.8125rem;
|
||||
gap: var( --space-xxs );
|
||||
|
||||
.citizen-ui-icon {
|
||||
width: 0.8125rem;
|
||||
height: 0.8125rem;
|
||||
margin-right: var( --space-xxs );
|
||||
}
|
||||
}
|
||||
|
||||
&__labelItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__description {
|
||||
margin-top: 0.1rem;
|
||||
color: var( --color-base--subtle );
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
&__title,
|
||||
&__description {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
&__title,
|
||||
&__description {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
|
@ -104,20 +112,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
&-option {
|
||||
&--active {
|
||||
background-color: var( --background-color-primary--hover );
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 0.75rem;
|
||||
padding-left: 0.75rem;
|
||||
color: var( --color-base );
|
||||
}
|
||||
|
||||
picture {
|
||||
width: 100%;
|
||||
max-width: 70px;
|
||||
|
|
|
@ -3,26 +3,26 @@
|
|||
}}
|
||||
|
||||
<ol id="searchform-suggestions" class="citizen-typeahead" role="listbox">
|
||||
<li role="option">
|
||||
<a href="" id="searchform-suggestions-footer" class="citizen-typeahead-footer">
|
||||
<li role="option" class="citizen-typeahead__item">
|
||||
<a href="" id="searchform-suggestions-footer" class="citizen-typeahead-footer citizen-typeahead__content">
|
||||
<picture class="citizen-typeahead-footer__icon">
|
||||
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+DQoJPHBhdGggZmlsbD0iIzM2YyIgZD0iTTcuNSAxM2MzLjA0IDAgNS41LTIuNDYgNS41LTUuNVMxMC41NCAyIDcuNSAyIDIgNC40NiAyIDcuNSA0LjQ2IDEzIDcuNSAxM3ptNC41NS40NkE3LjQzMiA3LjQzMiAwIDAgMSA3LjUgMTVDMy4zNiAxNSAwIDExLjY0IDAgNy41UzMuMzYgMCA3LjUgMEMxMS42NCAwIDE1IDMuMzYgMTUgNy41YzAgMS43MS0uNTcgMy4yOS0xLjU0IDQuNTVsNi40OSA2LjQ5LTEuNDEgMS40MS02LjQ5LTYuNDl6Ii8+DQoJPHBhdGggZmlsbD0iIzM2YyIgZD0iTTQgNWg3djFINHptMCAyaDd2MUg0em0wIDJoNS40NDR2MUg0eiIvPg0KPC9zdmc+DQo="/>
|
||||
</picture>
|
||||
<div class="citizen-typeahead-footer__text">{{{msg-citizen-search-fulltext}}}</div>
|
||||
</a>
|
||||
</li>
|
||||
<template id="citizen-typeahead-suggestion-template">
|
||||
<li role="option">
|
||||
<a href="" class="citizen-typeahead-suggestion">
|
||||
<picture class="citizen-typeahead-suggestion__thumbnail">
|
||||
<template id="citizen-typeahead-template">
|
||||
<li role="option" class="citizen-typeahead__item">
|
||||
<a href="" class="citizen-typeahead__content">
|
||||
<picture class="citizen-typeahead__thumbnail">
|
||||
<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNTYgNTYiPg0KCTxwYXRoIGZpbGw9IiNlYWVjZjAiIGQ9Ik0wIDBoNTZ2NTZIMCIvPg0KCTxwYXRoIGZpbGw9IiM3Mjc3N2QiIGQ9Ik0zNi40IDEzLjVIMTcuOHYyNC45YzAgMS40LjkgMi4zIDIuMyAyLjNoMTguN3YtMjVjLjEtMS40LTEtMi4yLTIuNC0yLjJ6TTMwLjIgMTdoNS4xdjYuNGgtNS4xVjE3em0tOC44IDBoNnYxLjhoLTZWMTd6bTAgNC42aDZ2MS44aC02di0xLjh6bTAgMTUuNXYtMS44aDEzLjh2MS44SDIxLjR6bTEzLjgtNC41SDIxLjR2LTEuOGgxMy44djEuOHptMC00LjdIMjEuNHYtMS44aDEzLjh2MS44eiIvPg0KPC9zdmc+DQo="/>
|
||||
</picture>
|
||||
<div class="citizen-typeahead-suggestion__text">
|
||||
<div class="citizen-typeahead-suggestion__header">
|
||||
<div class="citizen-typeahead-suggestion__title"></div>
|
||||
<div class="citizen-typeahead-suggestion__label"></div>
|
||||
<div class="citizen-typeahead__text">
|
||||
<div class="citizen-typeahead__header">
|
||||
<div class="citizen-typeahead__title"></div>
|
||||
<div class="citizen-typeahead__label"></div>
|
||||
</div>
|
||||
<div class="citizen-typeahead-suggestion__description"></div>
|
||||
<div class="citizen-typeahead__description"></div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const
|
||||
config = require( './config.json' ),
|
||||
PREFIX = 'citizen-typeahead-suggestion',
|
||||
PREFIX = 'citizen-typeahead',
|
||||
SEARCH_LOADING_CLASS = 'citizen-loading';
|
||||
|
||||
const activeIndex = {
|
||||
|
@ -37,8 +37,8 @@ let typeahead, searchInput;
|
|||
* @return {void}
|
||||
*/
|
||||
function toggleActive( element ) {
|
||||
const typeaheadItems = typeahead.querySelectorAll( 'li > a' ),
|
||||
activeClass = 'citizen-typeahead-option--active';
|
||||
const typeaheadItems = typeahead.querySelectorAll( '.' + PREFIX + '__item' ),
|
||||
activeClass = PREFIX + '__item--active';
|
||||
|
||||
for ( let i = 0; i < typeaheadItems.length; i++ ) {
|
||||
if ( element !== typeaheadItems[ i ] ) {
|
||||
|
@ -68,7 +68,7 @@ function keyboardEvents( event ) {
|
|||
}
|
||||
|
||||
// Is children slower?
|
||||
const typeaheadItems = typeahead.querySelectorAll( 'li > a' );
|
||||
const typeaheadItems = typeahead.querySelectorAll( '.' + PREFIX + '__item' );
|
||||
|
||||
if ( event.key === 'ArrowDown' || event.key === 'ArrowUp' ) {
|
||||
if ( event.key === 'ArrowDown' ) {
|
||||
|
@ -86,6 +86,18 @@ function keyboardEvents( event ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach mouse eventlistener to all typeahead items
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
function attachMouseListener() {
|
||||
const items = typeahead.querySelectorAll( '.' + PREFIX + '__item' );
|
||||
items.forEach( ( item ) => {
|
||||
bindMouseHoverEvent( item );
|
||||
} );
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind mouseenter and mouseleave event to reproduce mouse hover event
|
||||
*
|
||||
|
@ -157,26 +169,10 @@ function getSuggestions( searchQuery ) {
|
|||
return text.replace( regex, '<span class="' + PREFIX + '__highlight">$&</span>' );
|
||||
};
|
||||
|
||||
const getSuggestionTitle = ( title, matchedTitle ) => {
|
||||
let html;
|
||||
// Result is a redirect
|
||||
// Show the redirect title and highlight it
|
||||
if ( matchedTitle && isRedirectUseful( title, matchedTitle ) ) {
|
||||
html = title +
|
||||
'<span class="' + PREFIX + '__redirect">' +
|
||||
mw.message( 'search-redirect', highlightTitle( matchedTitle ) ).plain() +
|
||||
'</span>';
|
||||
} else {
|
||||
// Highlight title
|
||||
html = highlightTitle( title );
|
||||
}
|
||||
return html;
|
||||
};
|
||||
|
||||
const getRedirectLabel = ( title, matchedTitle ) => {
|
||||
// Check if the redirect is useful
|
||||
// See T303013
|
||||
const isRedirectUseful = ( title, matchedTitle ) => {
|
||||
const isRedirectUseful = () => {
|
||||
// Change to lowercase then remove space and dashes
|
||||
const cleanup = ( text ) => {
|
||||
return text.toLowerCase().replace( /-|\s/g, '' );
|
||||
|
@ -190,7 +186,7 @@ function getSuggestions( searchQuery ) {
|
|||
|
||||
// Result is a redirect
|
||||
// Show the redirect title and highlight it
|
||||
if ( matchedTitle && isRedirectUseful( title, matchedTitle ) ) {
|
||||
if ( matchedTitle && isRedirectUseful() ) {
|
||||
html = '<div class="' + PREFIX + '__labelItem" title="' + mw.message( 'search-redirect', matchedTitle ).plain() + '">' +
|
||||
/* Article redirect icon */
|
||||
'<span class="citizen-ui-icon mw-ui-icon-wikimedia-articleRedirect"></span>' +
|
||||
|
@ -217,14 +213,6 @@ function getSuggestions( searchQuery ) {
|
|||
typeahead.prepend( fragment );
|
||||
};
|
||||
|
||||
// Attach mouseenter events to newly created suggestions
|
||||
const attachMouseListener = () => {
|
||||
const suggestions = typeahead.querySelectorAll( '.citizen-typeahead-suggestion' );
|
||||
suggestions.forEach( ( suggestion ) => {
|
||||
bindMouseHoverEvent( suggestion );
|
||||
} );
|
||||
};
|
||||
|
||||
// Add loading animation
|
||||
searchInput.parentNode.classList.add( SEARCH_LOADING_CLASS );
|
||||
|
||||
|
@ -278,7 +266,7 @@ function getMenuItem( data ) {
|
|||
|
||||
const
|
||||
item = template.content.cloneNode( true ),
|
||||
link = item.querySelector( '.' + PREFIX ),
|
||||
link = item.querySelector( '.' + PREFIX + '__content' ),
|
||||
thumbnail = item.querySelector( '.' + PREFIX + '__thumbnail img' ),
|
||||
title = item.querySelector( '.' + PREFIX + '__title' ),
|
||||
label = item.querySelector( '.' + PREFIX + '__label' ),
|
||||
|
@ -376,8 +364,8 @@ function initTypeahead( searchForm, input ) {
|
|||
searchInput.setAttribute( 'aria-autocomplete', 'list' );
|
||||
searchInput.setAttribute( 'aria-controls', 'searchform-suggestions' );
|
||||
|
||||
const footer = document.getElementById( 'searchform-suggestions-footer' );
|
||||
bindMouseHoverEvent( footer );
|
||||
// Attach mouse listener to inital typeahead items
|
||||
attachMouseListener();
|
||||
|
||||
// Since searchInput is focused before the event listener is set up
|
||||
onFocus();
|
||||
|
|
Loading…
Reference in a new issue