Update jquery.uls to d122f37

* Do not group search results by region
* Replace ULS trigger icon with monochromatic one
* Custom no-results message support
* Upgrade jquery in the example to 3.2.1
* Use .siblings to locate the suggestions, clear elements for efficiency
* Removing assigned ids to elements that are not guaranteed to be unique
* Use eslint and stylelint, fix all errors

Update the language icon in ext.uls.pt module with new monochromatic one
Also use custom style for monobook skin.

Bug: T182539
Bug: T175769
Change-Id: I7341064cd0de367d933048c4800f951568747d11
This commit is contained in:
Santhosh Thottingal
2018-01-15 09:47:15 +05:30
parent 4489bf100a
commit fd7b9ec652
17 changed files with 421 additions and 349 deletions

View File

@@ -22,43 +22,48 @@
( function ( $ ) {
'use strict';
var noResultsTemplate, LanguageCategoryDisplay;
// eslint-disable-next-line no-multi-str
var noResultsTemplate = '<div class="uls-no-results-view"> \
<h2 data-i18n="uls-no-results-found" class="uls-no-results-found-title">No results found</h2> \
<div class="uls-no-results-suggestions"></div> \
<div class="uls-no-found-more"> \
<div><p> \
<span data-i18n="uls-search-help">You can search by language name, script name, ISO code of language or you can browse by region.</span>\
</p></div> \
</div></div>';
noResultsTemplate = $( '<div>' ).addClass( 'uls-no-results-view hide' );
noResultsTemplate.append(
$( '<h2>' )
.attr( 'data-i18n', 'uls-no-results-found' )
.addClass( 'uls-no-results-found-title' )
.text( 'No results found' ),
$( '<div>' )
.addClass( 'uls-no-found-more' )
.append(
$( '<div>' )
.addClass( '' )
.append(
$( '<p>' ).append(
$( '<span>' )
.attr( 'data-i18n', 'uls-search-help' )
.text( 'You can search by language name, script name, ISO code of language or you can browse by region.' )
)
)
)
);
LanguageCategoryDisplay = function ( element, options ) {
/**
* Language category display
* @param {Element} element The container element to which the languages to be displayed
* @param {Object} [options] Configuration object
* @cfg {Object} [languages] Selectable languages. Keyed by language code, values are autonyms.
* @cfg {string[]} [showRegions] Array of region codes to show. Default is
* [ 'WW', 'AM', 'EU', 'ME', 'AF', 'AS', 'PA' ]
* @cfg {number} [itemsPerColumn] Number of languages per column.
* @cfg {number} [columns] Number of columns for languages. Default is 4.
* @cfg {Function} [languageDecorator] Callback function to be called when a language
* link is prepared - for custom decoration.
* @cfg {Function|string[]} [quickList] The languages to display as suggestions for quick selection.
* @cfg {Function} [clickhandler] Callback when language is selected.
* @cfg {jQuery|Function} [noResultsTemplate]
*/
function LanguageCategoryDisplay( element, options ) {
this.$element = $( element );
this.options = $.extend( {}, $.fn.lcd.defaults, options );
// Ensure the internal region 'all' is always present
if ( this.options.showRegions.indexOf( 'all' ) === -1 ) {
this.options.showRegions.push( 'all' );
}
this.$element.addClass( 'uls-lcd' );
this.regionLanguages = {};
this.renderTimeout = null;
this.cachedQuicklist = null;
this.$element.append( noResultsTemplate.clone() );
this.$noResults = this.$element.children( '.uls-no-results-view' );
this.groupByRegionOverride = null;
this.render();
this.listen();
};
}
LanguageCategoryDisplay.prototype = {
constructor: LanguageCategoryDisplay,
@@ -67,24 +72,21 @@
* Adds language to the language list.
* @param {string} langCode
* @param {string} [regionCode]
* @return {boolean} Whether the language was added.
* @return {boolean} Whether the language was known and accepted
*/
append: function ( langCode, regionCode ) {
var lcd = this,
i, regions;
var i, regions;
if ( !$.uls.data.languages[ langCode ] ) {
// Language is unknown or not in the list of languages for this context.
return false;
}
// Show everything in one region when there is only one column
if ( lcd.options.columns === 1 ) {
regions = [ 'WW' ];
if ( !this.isGroupingByRegionEnabled() ) {
regions = [ 'all' ];
// Languages are expected to be repeated in this case,
// and we only want to show them once
if ( $.inArray( langCode, this.regionLanguages.WW ) > -1 ) {
// Make sure we do not get duplicates
if ( this.regionLanguages.all.indexOf( langCode ) > -1 ) {
return true;
}
} else {
@@ -101,21 +103,45 @@
// Work around the bad interface, delay rendering until we have got
// all the languages to speed up performance.
window.clearTimeout( this.renderTimeout );
this.renderTimeout = window.setTimeout( function () {
lcd.renderRegions();
}, 50 );
clearTimeout( this.renderTimeout );
this.renderTimeout = setTimeout( function () {
this.renderRegions();
}.bind( this ), 50 );
return true;
},
/**
* Whether we should render languages grouped to geographic regions.
* @return {boolean}
*/
isGroupingByRegionEnabled: function () {
if ( this.groupByRegionOverride !== null ) {
return this.groupByRegionOverride;
} else if ( this.options.groupByRegion !== 'auto' ) {
return this.options.groupByRegion;
} else {
return this.options.columns > 1;
}
},
/**
* Override the default region grouping setting.
* This is to allow LanguageFilter to disable grouping when displaying search results.
*
* @param {boolean|null} val True to force grouping, false to disable, null to undo override.
*/
setGroupByRegionOverride: function ( val ) {
this.groupByRegionOverride = val;
},
render: function () {
var $section, $quicklist,
lcd = this,
narrowMode = this.options.columns === 1,
var $section,
$quicklist = this.buildQuicklist(),
regions = [],
regionNames = {
// These are fallback text when i18n library not present
all: 'All languages', // Used if there is quicklist and no region grouping
WW: 'Worldwide',
SP: 'Special',
AM: 'America',
@@ -126,42 +152,30 @@
PA: 'Pacific'
};
$quicklist = this.buildQuicklist();
regions.push( $quicklist );
if ( narrowMode && $quicklist.length ) {
regions.push( $( '<h3>' )
.attr( 'data-i18n', 'uls-region-all' )
.addClass( 'uls-lcd-region-title' )
.text( 'All languages' )
);
if ( $quicklist.length ) {
regions.push( $quicklist );
} else {
// We use CSS to hide the header for 'all' when quicklist is NOT present
this.$element.addClass( 'uls-lcd--no-quicklist' );
}
$.each( $.uls.data.regiongroups, function ( regionCode ) {
lcd.regionLanguages[ regionCode ] = [];
// Don't show the region unless it was enabled
if ( $.inArray( regionCode, lcd.options.showRegions ) === -1 ) {
return;
}
this.options.showRegions.forEach( function ( regionCode ) {
this.regionLanguages[ regionCode ] = [];
$section = $( '<div>' )
.addClass( 'uls-lcd-region-section hide' )
.attr( 'id', regionCode );
.attr( 'data-region', regionCode );
// Show a region heading, unless we are using a narrow ULS
if ( !narrowMode ) {
$section.append( $( '<h3>' )
.attr( 'data-i18n', 'uls-region-' + regionCode )
.addClass( 'uls-lcd-region-title' )
.text( regionNames[ regionCode ] )
);
}
$( '<h3>' )
.attr( 'data-i18n', 'uls-region-' + regionCode )
.addClass( 'uls-lcd-region-title' )
.text( regionNames[ regionCode ] )
.appendTo( $section );
regions.push( $section );
} );
}.bind( this ) );
lcd.$element.append( regions );
this.$element.append( regions );
this.i18n();
},
@@ -173,12 +187,12 @@
var languages,
lcd = this;
this.$noResults.addClass( 'hide' );
this.$element.removeClass( 'uls-no-results' );
this.$element.children( '.uls-lcd-region-section' ).each( function () {
var $region = $( this ),
regionCode = $region.attr( 'id' );
regionCode = $region.data( 'region' );
if ( $region.is( '#uls-lcd-quicklist' ) ) {
if ( $region.is( '.uls-lcd-quicklist' ) ) {
return;
}
@@ -241,8 +255,9 @@
nextScript = $.uls.data.getScriptGroupOfLanguage( languages[ i + 1 ] );
lastItem = languagesCount - i === 1;
// Force column break if script changes and column has more than one row already
if ( i === 0 ) {
// Force column break if script changes and column has more than one row already,
// but only if grouping by region
if ( i === 0 || !this.isGroupingByRegionEnabled() ) {
currentScript = $.uls.data.getScriptGroupOfLanguage( languages[ i ] );
} else if ( currentScript !== nextScript && items.length > 1 ) {
force = true;
@@ -287,7 +302,6 @@
a.lang = code;
a.dir = $.uls.data.getDir( code );
li.appendChild( a );
if ( this.options.languageDecorator ) {
this.options.languageDecorator( $( a ), code );
@@ -303,7 +317,7 @@
* Adds quicklist as a region.
*/
quicklist: function () {
this.$element.find( '#uls-lcd-quicklist' ).removeClass( 'hide' );
this.$element.find( '.uls-lcd-quicklist' ).removeClass( 'hide' );
},
buildQuicklist: function () {
@@ -328,8 +342,7 @@
quickList.sort( $.uls.data.sortByAutonym );
$quickListSection = $( '<div>' )
.addClass( 'uls-lcd-region-section' )
.attr( 'id', 'uls-lcd-quicklist' );
.addClass( 'uls-lcd-region-section uls-lcd-quicklist' );
$quickListSectionTitle = $( '<h3>' )
.attr( 'data-i18n', 'uls-common-languages' )
@@ -356,30 +369,41 @@
}
},
/**
* Called when a fresh search is started
*/
empty: function () {
this.$element.find( '#uls-lcd-quicklist' ).addClass( 'hide' );
this.$element.addClass( 'uls-lcd--no-quicklist' );
this.$element.find( '.uls-lcd-quicklist' ).addClass( 'hide' );
},
focus: function () {
this.$element.focus();
},
noResults: function () {
this.$noResults.removeClass( 'hide' );
this.$noResults.siblings( '.uls-lcd-region-section' ).addClass( 'hide' );
/**
* No-results event handler
* @param {Event} event
* @param {string} [currentSearchQuery] Current search query that gave mp results
*/
noResults: function ( event, currentSearchQuery ) {
var $noResults;
// Only build the data once
if ( this.$noResults.find( '.uls-lcd-region-title' ).length ) {
return;
this.$element.addClass( 'uls-no-results' );
this.$element.find( '.uls-no-results-view' ).remove();
if ( typeof this.options.noResultsTemplate === 'function' ) {
$noResults =
this.options.noResultsTemplate.call( this, currentSearchQuery );
} else if ( this.options.noResultsTemplate instanceof jQuery ) {
$noResults = this.options.noResultsTemplate;
} else {
throw new Error( 'noResultsTemplate option must be ' +
'either jQuery or function returning jQuery' );
}
var $suggestions = this.buildQuicklist().clone();
$suggestions.removeClass( 'hide' ).removeAttr( 'id' );
$suggestions.find( 'h3' )
.data( 'i18n', 'uls-no-results-suggestion-title' )
.text( 'You may be interested in:' )
.i18n();
this.$noResults.find( 'h2' ).after( $suggestions );
this.$element.append( $noResults.addClass( 'uls-no-results-view' ) );
},
listen: function () {
@@ -410,15 +434,37 @@
};
$.fn.lcd.defaults = {
languages: null,
// List of languages to show
languages: [],
// List of regions to show
showRegions: [ 'WW', 'AM', 'EU', 'ME', 'AF', 'AS', 'PA' ],
// Whether to group by region, defaults to true when columns > 1
groupByRegion: 'auto',
// How many items per column until new "row" starts
itemsPerColumn: 8,
// Other supported values are 1 and 2.
// Other values will have rendering issues.
// Number of columns, only 1, 2 and 4 are supported
columns: 4,
languageDecorator: null,
quickList: []
// Callback function for language item styling
languageDecorator: undefined,
// Likely candidates
quickList: [],
// Callback function for language selection
clickhandler: undefined,
// Callback function when no search results
noResultsTemplate: function () {
var $suggestionsContainer, $suggestions,
$noResultsTemplate = $( noResultsTemplate );
$suggestions = this.buildQuicklist().clone();
$suggestions.removeClass( 'hide' )
.find( 'h3' )
.data( 'i18n', 'uls-no-results-suggestion-title' )
.text( 'You may be interested in:' )
.i18n();
$suggestionsContainer = $noResultsTemplate.find( '.uls-no-results-suggestions' );
$suggestionsContainer.append( $suggestions );
return $noResultsTemplate;
}
};
$.fn.lcd.Constructor = LanguageCategoryDisplay;
}( jQuery ) );