/** * Universal Language Selector * Language category display component - Used for showing the search results, * grouped by regions, scripts * * Copyright (C) 2012 Alolita Sharma, Amir Aharoni, Arun Ganesh, Brandon Harris, * Niklas Laxström, Pau Giner, Santhosh Thottingal, Siebrand Mazeland and other * contributors. See CREDITS for a list. * * UniversalLanguageSelector is dual licensed GPLv2 or later and MIT. You don't * have to do anything special to choose one license or the other and you don't * have to notify anyone which license you are using. You are free to use * UniversalLanguageSelector in commercial projects as long as the copyright * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. * * @file * @ingroup Extensions * @licence GNU General Public Licence 2.0 or later * @licence MIT License */ ( function ( $ ) { 'use strict'; var noResultsTemplate, LanguageCategoryDisplay; /*jshint multistr:true */ noResultsTemplate = '\
\

\ No results found\

\
\
\

\ You can search by language name, \ script name, ISO code of language or \ you can browse by region:\ America, \ Europe, \ Middle East, \ Africa, \ Asia, \ Pacific, \ Worldwide.\

\
\
\
'; /*jshint multistr:false */ LanguageCategoryDisplay = function ( element, options ) { this.$element = $( element ); this.options = $.extend( {}, $.fn.lcd.defaults, options ); this.$element.addClass( 'lcd' ); this.regionLanguages = {}; this.renderTimeout = null; this.cachedQuicklist = null; this.$element.append( $( noResultsTemplate ) ); this.$noResults = this.$element.children( '.uls-no-results-view' ); this.render(); this.listen(); }; LanguageCategoryDisplay.prototype = { constructor: LanguageCategoryDisplay, /** * Adds language to the language list. * @param {string} langCode * @param {string} [regionCode] * @return {bool} Whether the language was added. */ append: function ( langCode, regionCode ) { var lcd = this, i, regions; if ( !this.options.languages[langCode] ) { // Language is unknown or not in the list of languages for this context. return false; } if ( regionCode ) { regions = [regionCode]; } else { regions = $.uls.data.getRegions( langCode ); } // Worldwides only displayed once if ( $.inArray( 'WW', regions ) > -1 ) { regions = ['WW']; } for ( i = 0; i < regions.length; i++ ) { this.regionLanguages[regions[i]].push( langCode ); } // 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 ); return true; }, render: function () { var $section, lcd = this, regions = [], regionNames = { // These are fallback text when i18n library not present WW: 'Worldwide', SP: 'Special', AM: 'America', EU: 'Europe', ME: 'Middle East', AS: 'Asia', AF: 'Africa', PA: 'Pacific' }; regions.push( this.buildQuicklist() ); $.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; } $section = $( '
' ) .addClass( 'eleven columns offset-by-one uls-lcd-region-section hide' ) .attr( 'id', regionCode ) .append( $( '

' ) .attr( 'data-i18n', 'uls-region-' + regionCode ) .addClass( 'eleven columns uls-lcd-region-title' ) .text( regionNames[regionCode] ) ); regions.push( $section ); } ); lcd.$element.append( regions ); this.i18n(); }, /** * Renders a region and displays it if it has content. */ renderRegions: function () { var lcd = this, languages, items = lcd.options.itemsPerColumn, columns = 4; this.$noResults.addClass( 'hide' ); this.$element.find( '.uls-lcd-region-section' ).each( function () { var $region = $( this ), regionCode = $region.attr( 'id' ); if ( $region.is( '#uls-lcd-quicklist' ) ) { return; } $region.children( '.uls-language-block' ).remove(); languages = lcd.regionLanguages[regionCode]; if ( !languages || languages.length === 0 ) { $region.addClass( 'hide' ); return; } lcd.renderRegion( $region, languages, items, columns ); $region.removeClass( 'hide' ); lcd.regionLanguages[regionCode] = []; } ); }, /** * Adds given languages sorted into rows and columns into given element. * @param {jQuery} $region Element to add language list. * @param {array} languages List of language codes. * @param {number} itemsPerColumn How many languages fit in a column. * @param {number} columnsPerRow How many columns fit in a row. */ renderRegion: function( $region, languages, itemsPerColumn, columnsPerRow ) { var i, lastItem, currentScript, nextScript, force, len = languages.length, items = [], columns = [], rows = []; for ( i = 0; i < len; i++ ) { force = false; nextScript = $.uls.data.getScriptGroupOfLanguage( languages[i+1] ); lastItem = len - i === 1; // Force column break if script changes and column has more than one row already if ( i === 0 ) { currentScript = $.uls.data.getScriptGroupOfLanguage( languages[i] ); } else if ( currentScript !== nextScript && items.length > 1 ) { force = true; } currentScript = nextScript; items.push( this.renderItem( languages[i] ) ); if ( items.length >= itemsPerColumn || lastItem || force ) { columns.push( $( '