Merge branch 'master' into srpski

This commit is contained in:
Niklas Laxström
2018-02-06 16:31:46 +02:00
committed by GitHub
46 changed files with 644 additions and 631 deletions

1
.eslintignore Normal file
View File

@@ -0,0 +1 @@
src/jquery.uls.data.js

14
.eslintrc.json Normal file
View File

@@ -0,0 +1,14 @@
{
"extends": "wikimedia",
"env": {
"browser": true,
"jquery": true,
"qunit": true
},
"globals": {
"require": false
},
"rules": {
"dot-notation": [ "error", { "allowKeywords": true } ]
}
}

View File

@@ -1,17 +0,0 @@
{
"preserve_newlines": true,
"jslint_happy": true,
"keep_array_indentation": true,
"space_before_conditional": true,
"max_preserve_newlines": 10,
"brace_style": "collapse",
"keep_function_indentation": false,
"break_chained_methods": false,
"eval_code": false,
"unescape_strings": false,
"wrap_line_length": 0,
"space_in_paren": true,
"space_in_square_bracket": true,
"git_happy": true,
"indent_with_tabs": true
}

View File

@@ -1 +0,0 @@
src/jquery.uls.data.js

View File

@@ -1,35 +0,0 @@
{
// Enforcing
"bitwise": true,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"forin": false,
"immed": true,
"latedef": "nofunc",
"newcap": true,
"noarg": true,
"noempty": true,
"nonew": true,
"onevar": true,
"quotmark": "single",
"regexp": false,
"strict": true,
"trailing": true,
"undef": true,
"unused": true,
// Relax
"laxbreak": true,
"multistr": true,
"smarttabs": true,
// Environment
"browser": true,
"predef": [
"_",
"jQuery",
"QUnit"
]
}

3
.stylelintrc.json Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": "stylelint-config-wikimedia"
}

View File

@@ -1,4 +1,4 @@
language: node_js
node_js:
- "0.10"
- 8
sudo: false

View File

@@ -1,22 +1,35 @@
/*jshint node:true */
'use strict';
module.exports = function ( grunt ) {
grunt.loadNpmTasks( 'grunt-contrib-jshint' );
grunt.loadNpmTasks( 'grunt-eslint' );
grunt.loadNpmTasks( 'grunt-stylelint' );
grunt.loadNpmTasks( 'grunt-contrib-qunit' );
grunt.initConfig( {
jshint: {
eslint: {
all: [
'**/*.js',
'src/jquery.uls.data.js',
'!examples/**',
'!node_modules/**',
'!vendor/**'
]
},
stylelint: {
options: {
jshintrc: true
syntax: 'css'
},
all: ['*.js', 'src/*.js']
src: [
'**/*.css',
'!node_modules/**'
]
},
qunit: {
all: 'test/index.html'
}
} );
grunt.registerTask( 'lint', 'jshint' );
grunt.registerTask( 'test', ['lint', 'qunit'] );
grunt.registerTask( 'lint', [ 'eslint' ] );
grunt.registerTask( 'test', [ 'lint', 'qunit' ] );
grunt.registerTask( 'default', 'test' );
};

View File

@@ -1,10 +1,8 @@
jQuery Universal Language Selector
Universal Language Selector jQuery library
==================================
Universal Language Selector
[![Build Status](https://secure.travis-ci.org/wikimedia/jquery.uls.png)](http://travis-ci.org/wikimedia/jquery.uls)
This is a [Wikimedia Foundation Language Engineering team project](https://www.mediawiki.org/wiki/Project_Milkshake).
This is a [Wikimedia Foundation project](https://www.mediawiki.org/wiki/Project_Milkshake).
![Universal Language Selector](https://upload.wikimedia.org/wikipedia/commons/a/a1/UniversalLanguageSelector-Compact.png "Universal Language Selector")
@@ -19,86 +17,70 @@ git clone https://github.com/wikimedia/jquery.uls.git
Documentation
-------------
The quick and easy way to learn usage of jquery.uls is trying out the examples/index.html in some webserver. Try it from here: http://thottingal.in/projects/js/jquery.uls/examples/
The quick and easy way to learn usage of jquery.uls is trying out the examples/index.html in webserver. Try it online at http://thottingal.in/projects/js/jquery.uls/examples/
The jQuery.uls provides a jQuery extension ```$.fn.uls``` that can be attached to a trigger element. The expected behavior is, when you click on the trigger, the language selector opens up.
The jquery.uls provides a jQuery extension ```$.fn.uls``` that can be attached to a trigger element. When you click on the trigger element, the language selector is shown.
The trigger can be a link, button or any valid jQuery element.
Example:
```javascript
$( '.uls-trigger' ).uls( );
$( '.uls-trigger' ).uls();
```
To use the selected language, you need define a selection Handler as shown below
To use the selected language, you need define a selection handler:
```javascript
$( '.uls-trigger' ).uls( {
onSelect : function( language ) {
// language is a ISO 639 language code. eg: en, hi, fi, he etc
onSelect: function( language ) {
// language is a IETF language tag in lowercase, for example: en, fi, ku-latn
// Your selection handler code goes here.
}
} );
```
In some usecases, you may need to provide a quick list of languages to select before going through all languages. For eg, it can a list of recently selected languages, language suggestions based on Geo IP.
That can be done as follows
You can provide a quick list of likely useful languages, for example based on Geo IP or recently selected languages:
```javascript
$( '.uls-trigger' ).uls( {
onSelect : function( language ) {
// language is a ISO 639 language code. eg: en, hi, fi, he etc
// Your selection handler code goes here.
},
quickList: [ 'en', 'ml', 'hi' ] // An array of language codes. Can be a function that returns this array too.
onSelect: function( language ) { ... },
quickList: [ 'en', 'ml', 'hi' ] // Can be a function returning an array too.
} );
```
If the search needs to be more complex(such as cross language search, spelling error tolerating etc), a search API option can be provided.
jquery.uls knows about 500 languages. You can specify a subset of those languages:
```javascript
$( '.uls-trigger' ).uls( {
onSelect : function( language ) {
// language is a ISO 639 language code. eg: en, hi, fi, he etc
// Your selection handler code goes here.
},
searchAPI: apiURL,
quickList: [ 'en', 'ml', 'hi' ] // An array of language codes. Can be a function that returns this array too.
onSelect: function( language ) { ... },
languages: { languageCode1: languageName, languageCode2: languageName2, .... },
} );
```
Example for such an api is used in Wikipedia: http://en.wikipedia.org/w/api.php?action=languagesearch&search=Te
ULS knows about 500 languages. If you dont want to use that many languages for your usecase, use languages option.
```javascript
$( '.uls-trigger' ).uls( {
onSelect : function( language ) {
// language is a ISO 639 language code. eg: en, hi, fi, he etc
// Your selection handler code goes here.
},
languages: { languageCode1: languageName, languageCode2: languageName2 , .... },
searchAPI: apiURL,
quickList: [ 'en', 'ml', 'hi' ] // An array of language codes. Can be a function that returns this array too.
} );
```
*Other Options*
*All options*
| Option | Description |
|-------------|---------------------|
| left | left position of ULS. eg: 100px, 20%|
| top | top position of ULS. eg: 100px, 20%|
| onCancel | function to be handled when language selection is not done. ie. language selector is closed without selecting any |
| showRegions | Regions to be shown in the language selector. Default: ['WW', 'AM', 'EU', 'ME', 'AF', 'AS', 'PA'] |
| left | Left position of ULS dialog. E.g: 100px or 20% |
| top | Top position of ULS dialog. E.g: 100px or 20% |
| onCancel | Callback function when the dialog is closed without selecting a language. |
| onReady | Callback function when ULS has initialized. |
| onVisible | Callback function when ULS dialog is shown. |
| onSelect | Callback function when user selects a language. |
| languages | List of selectable languages. Defaults to all known languages. |
| quicklist | List of suggested languages. Defaults to empty list. |
| searchAPI | API URL. Parameter query with the user query is appened to it. |
| menuWidth | Override the automatic choice of menu width. One of narrow, medium, wide (1, 2, 4 columns respectively). |
| showRegions | Regions to be shown in the language selector. Defaults to [ WW, AM, EU, ME, AF, AS, PA ] |
| groupByRegion | Whether to group languages by the regions: true of false. Default value depends on the menu width. |
| itemsPerColumn | Number of languages per column. Default is 8 |
| languageDecorator | Callback function to be called when a language link is prepared - for custom decoration. Arguments: (a) the $language - the language link jQuery object (b) languageCode. The function can do any styling, changing properties etc on the passed link. See examples/decorator.html for example usage.|
| noResultsTemplate | A jQuery object or a function that returns a jQuery object. This will be used as the template to display when no results found from the search. The function will receive the current search query as argument|
Features
--------
jQuery.uls has an elaborative language information collection and it is based on https://github.com/wikimedia/language-data.git. It knows about
jquery.uls has an elaborative language information collection and it is based on https://github.com/wikimedia/language-data.git. It knows about
1. The script in which a language is written.
2. The script code
@@ -107,14 +89,7 @@ jQuery.uls has an elaborative language information collection and it is based on
5. The autonym - language name written in its own script
6. The directionality of the text
With all these information the search becomes very effective. Based on the spoken regions, the UI organize the languages. In side regions
the language is again organized based on scripts.
A user can search for a language based on script name.
ULS can autocomplete a language name search.
An advanced usage of jQuery.uls can be tried out from wikimedia sites. For eg, see the language icon at the top of http://mediawiki.org or the cog icon near to the languages list in wikipedia in any language
With all these information the search becomes very effective. An advanced usage of jquery.uls can be tried out from Wikimedia sites. For example, see the language icon at the top of https://mediawiki.org or the cog icon near to the languages list in Wikipedia in any language.
More details
------------
@@ -122,7 +97,7 @@ More details
* UX Design https://www.mediawiki.org/wiki/Universal_Language_Selector/Design
How to build and test jQuery ULS
How to build and test jquery.uls
----------------------------------
First, get a copy of the git repo by running:
@@ -150,4 +125,4 @@ You can also run the tests in a browser by navigating to the `test/` directory,
Coding style
-------------
Please follow [jQuery coding guidelines](http://docs.jquery.com/JQuery_Core_Style_Guidelines)
Please follow [MediaWiki coding conventions](https://www.mediawiki.org/wiki/Manual:Coding_conventions/JavaScript)

View File

@@ -1,11 +1,8 @@
.uls-trigger {
background: url( ../images/language.png ) no-repeat left center;
/* @embed */
background: url('../images/icon-language.png') no-repeat left center;
/* @embed */
background-image: -webkit-linear-gradient(transparent, transparent), url('../images/icon-language.svg');
/* @embed */
background-image: linear-gradient(transparent, transparent), url('../images/icon-language.svg');
padding-left: 30px;
background-image: linear-gradient( transparent, transparent ), url( ../images/language.svg );
padding-left: 24px;
}
.uls-menu {
@@ -15,10 +12,10 @@
margin-top: 1px;
background-color: #fff;
border: 1px solid #ccc;
border-color: rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
border-color: rgba( 0, 0, 0, 0.2 );
-webkit-box-shadow: 0 5px 10px rgba( 0, 0, 0, 0.2 );
-moz-box-shadow: 0 5px 10px rgba( 0, 0, 0, 0.2 );
box-shadow: 0 5px 10px rgba( 0, 0, 0, 0.2 );
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
@@ -68,10 +65,9 @@
}
.uls-search-label {
background: url('../images/search.png') no-repeat center center;
background-image: -webkit-linear-gradient(transparent, transparent), url('../images/search.svg');
background: url( ../images/search.png ) no-repeat center center;
/* @embed */
background-image: linear-gradient(transparent, transparent), url('../images/search.svg');
background-image: linear-gradient( transparent, transparent ), url( ../images/search.svg );
background-size: 20px;
height: 32px;
width: 44px;
@@ -92,7 +88,7 @@
width: 100%;
/* For the custom clear (X) icon */
padding: 6px 25px 6px 0;
outline: none;
outline: 0;
border: 0;
display: block;
position: absolute;
@@ -114,10 +110,9 @@
}
.uls-languagefilter-clear {
background: url('../images/clear.png') no-repeat left center;
background-image: -webkit-linear-gradient(transparent, transparent), url('../images/clear.svg');
background: url( ../images/clear.png ) no-repeat left center;
/* @embed */
background-image: linear-gradient(transparent, transparent), url('../images/clear.svg');
background-image: linear-gradient( transparent, transparent ), url( ../images/clear.svg );
background-size: 15px;
cursor: pointer;
height: 15px;

View File

@@ -32,15 +32,18 @@
}
.grid .highlight {
background: #ffff99;
background: #ff9;
}
/* The Grid ---------------------- */
.grid .row {
width: 100%;
max-width: none;
min-width: 600px;
margin: 0 auto;
/* Nicolas Gallagher's micro clearfix */
*zoom: 1;
}
.grid .row .row {
@@ -50,30 +53,25 @@
margin: 0 -5px;
}
.grid .column,
.grid .columns {
float: left;
min-height: 1px;
padding: 0 5px;
position: relative;
}
.grid .row.collapse .column,
.grid .row.collapse .columns {
padding: 0;
}
.grid .row .row {
width: auto;
max-width: none;
min-width: 0;
margin: 0 -5px;
}
.grid .row .row.collapse {
margin: 0;
}
.grid .column, .grid .columns {
float: left;
min-height: 1px;
padding: 0 5px;
position: relative;
}
.grid .column.centered, .grid .columns.centered {
.grid .column.centered,
.grid .columns.centered {
float: none;
margin: 0 auto;
}
@@ -238,13 +236,9 @@
right: 83.333%;
}
/* Nicolas Gallagher's micro clearfix */
.grid .row {
*zoom: 1;
}
.grid .row:before, .grid .row:after {
content: "";
.grid .row:before,
.grid .row:after {
content: '';
display: table;
}

View File

@@ -17,6 +17,10 @@
padding: 0 16px;
}
.uls-lcd--no-quicklist [data-region="all"] .uls-lcd-region-title {
display: none;
}
.uls-lcd-region-section {
margin-top: 10px;
}
@@ -36,6 +40,16 @@
margin: 0;
}
.uls-language-block > ul {
/*
* We don't want any visible bullets in this list. Not by default anyway.
* Using very unspecific selector here to allow other classes to override.
* Bug because overflow: hidden is incompatible with bullets, also render
* the bullets inside the list in case there should be any.
*/
list-style: none none;
}
/*
* Each block should have 16px padding on both sides. But because we already gave
* 16px for the whole menu, we need to remove it for first and last items the blocks.
@@ -53,17 +67,6 @@
padding-right: 0;
}
.uls-language-block > ul {
/*
* We don't want any visible bullets in this list. Not by default anyway.
* Using very unspecific selector here to allow other classes to override.
* Bug because overflow: hidden is incompatible with bullets, also render
* the bullets inside the list in case there should be any.
*/
list-style: none none;
}
.uls-language-block > ul > li {
cursor: pointer;
margin-left: 20px;
@@ -103,16 +106,30 @@
vertical-align: middle;
}
.uls-no-results-view {
display: none;
}
.uls-lcd.uls-no-results > .uls-lcd-region-section {
display: none;
}
.uls-lcd.uls-no-results > .uls-no-results-view {
display: block;
}
.uls-no-results-found-title {
font-size: 16px;
padding: 0 16px 0 28px;
margin: 20px 0;
border-bottom: 0;
color: #555;
color: #54595d;
}
.uls-no-found-more {
background: #f8f8f8;
padding: 0 16px 0 44px;
border-top: 1px solid #eaecf0;
color: #54595d;
padding: 12px 16px 12px 44px;
font-size: 0.9em;
width: 100%;
margin-top: 1.6em;

View File

@@ -1,4 +1,4 @@
@media only screen and (max-width: 767px) {
@media only screen and ( max-width: 767px ) {
.uls-mobile.uls-menu {
width: 95%;
@@ -40,7 +40,7 @@
float: none;
}
.uls-mobile [class*="column"] + [class*="column"]:last-child {
.uls-mobile [ class*='column' ] + [ class*='column' ]:last-child {
float: none;
}
@@ -48,7 +48,7 @@
.uls-mobile .uls-mobile .columns:before,
.uls-mobile .column:after,
.columns:after {
content: "";
content: '';
display: table;
}
@@ -197,11 +197,12 @@
}
/* Very large display targeting */
@media only screen and (min-width: 1441px) {
@media only screen and ( min-width: 1441px ) {
.uls-mobile .hide-for-small,
.uls-mobile .hide-for-medium,
.uls-mobile .hide-for-medium-down,
.hide-for-large, .show-for-large-up,
.hide-for-large,
.show-for-large-up,
.show-for-xlarge {
display: block !important;
}
@@ -217,7 +218,7 @@
}
/* Medium display targeting */
@media only screen and (max-width: 1279px) and (min-width: 768px) {
@media only screen and ( max-width: 1279px ) and ( min-width: 768px ) {
.uls-mobile .hide-for-small,
.uls-mobile .show-for-medium,
.uls-mobile .show-for-medium-down,
@@ -238,7 +239,7 @@
}
/* Small display targeting */
@media only screen and (max-width: 767px) {
@media only screen and ( max-width: 767px ) {
.uls-mobile .show-for-small,
.uls-mobile .hide-for-medium,
.uls-mobile .show-for-medium-down,
@@ -268,7 +269,7 @@
display: none !important;
}
@media screen and (orientation: landscape) {
@media screen and ( orientation: landscape ) {
.uls-mobile .show-for-landscape,
.uls-mobile .hide-for-portrait {
display: block !important;
@@ -279,7 +280,7 @@
}
}
@media screen and (orientation: portrait) {
@media screen and ( orientation: portrait ) {
.uls-mobile .show-for-portrait,
.uls-mobile .hide-for-landscape {
display: block !important;

View File

@@ -10,7 +10,7 @@
<!-- demo -->
<link href="resources/demo.css" rel="stylesheet">
<!-- Libs -->
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- Source -->
<script src="../src/jquery.uls.data.js"></script>
<script src="../src/jquery.uls.data.utils.js"></script>

View File

@@ -10,7 +10,7 @@
<!-- demo -->
<link href="resources/demo.css" rel="stylesheet">
<!-- Libs -->
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- Source -->
<script src="../src/jquery.uls.data.js"></script>
<script src="../src/jquery.uls.data.utils.js"></script>

View File

@@ -21,7 +21,7 @@
<!-- demo -->
<link href="resources/demo.css" rel="stylesheet">
<!-- Libs -->
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- Source -->
<script src="../src/jquery.uls.data.js"></script>
<script src="../src/jquery.uls.data.utils.js"></script>

View File

@@ -10,7 +10,7 @@
<!-- demo -->
<link href="resources/demo.css" rel="stylesheet">
<!-- Libs -->
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- Source -->
<script src="../src/jquery.uls.data.js"></script>
<script src="../src/jquery.uls.data.utils.js"></script>

View File

@@ -20,7 +20,7 @@
<!-- demo -->
<link href="resources/demo.css" rel="stylesheet">
<!-- Libs -->
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- Source -->
<script src="../src/jquery.uls.data.js"></script>
<script src="../src/jquery.uls.data.utils.js"></script>
@@ -30,7 +30,7 @@
<script>
$( document ).ready( function() {
$( '.uls-trigger' ).uls( {
onSelect : function( language ) {
onSelect: function( language ) {
var languageName = $.uls.data.getAutonym( language );
$( '.uls-trigger' ).text( languageName );
},
@@ -42,12 +42,11 @@
<body>
<div class="navbar navbar-fixed-top">
<span class="active uls-trigger">Select Language</span>
<span class="active uls-trigger">Select language</span>
<h1>Universal Language Selector</h1>
<p>
Demonstration of jQuery plugin
Demonstration of jQuery.uls plugin
</p>
</div>
<div class="container"></div>
</body>
</html>

View File

@@ -13,7 +13,7 @@
<!-- demo -->
<link href="resources/demo.css" rel="stylesheet">
<!-- Libs -->
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- Source -->
<script src="../src/jquery.uls.data.js"></script>
<script src="../src/jquery.uls.data.utils.js"></script>

View File

@@ -1,18 +1,18 @@
body {
padding-left: 10%;
padding-right: 10%;
font-family: Arial, Helvetica, sans-serif;
font-family: 'Arial', 'Helvetica', sans-serif;
}
div.navbar {
background-color: #333;
color: #FFFFFF;
color: #fff;
padding: 20px;
}
span.uls-trigger {
float: right;
cursor: pointer;
color: #FFFFFF;
color: #fff;
font-weight: bold;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -20,34 +20,23 @@
<!-- demo -->
<link href="resources/demo.css" rel="stylesheet">
<!-- Libs -->
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- Source -->
<script src="../src/jquery.uls.data.js"></script>
<script src="../src/jquery.uls.data.utils.js"></script>
<script src="../src/jquery.uls.lcd.js"></script>
<script src="../src/jquery.uls.languagefilter.js"></script>
<script src="../src/jquery.uls.core.js"></script>
<style>
@font-face {
font-family: 'Autonym';
src: url('resources/font/Autonym.eot');
src: local('Autonym'),
url('resources/font/Autonym.woff') format('woff'),
url('resources/font/Autonym.ttf') format('truetype');
font-style: normal;
}
.autonym {
font-family: 'Autonym', sans-serif;
}
</style>
<script>
$( document ).ready( function() {
$( '.uls-trigger' ).uls( {
onSelect : function( language ) {
onSelect: function( language ) {
var languageName = $.uls.data.getAutonym( language );
$( '.uls-trigger' ).text( languageName );
},
quickList: ['en', 'hi', 'he', 'ml', 'ta', 'fr'] //FIXME
noResultsTemplate: function( query ) {
return $( '<div>No article exists in the language ' + query + '</div>' )
}
} );
} );
</script>
@@ -55,12 +44,11 @@
<body>
<div class="navbar navbar-fixed-top">
<span class="active uls-trigger">Select Language</span>
<span class="active uls-trigger">Select language</span>
<h1>Universal Language Selector</h1>
<p>
Demonstration of jQuery plugin
Demonstration of jQuery.uls plugin
</p>
</div>
<div class="container"></div>
</body>
</html>

View File

@@ -18,8 +18,8 @@
"uls-region-PA": "Stille Oseaan",
"uls-region-all": "Alle tale",
"uls-no-results-found": "Geen resultate gevind nie",
"uls-common-languages": "Voorgestelde Tale",
"uls-common-languages": "Voorgestelde tale",
"uls-no-results-suggestion-title": "U mag geïnteresseerd wees in:",
"uls-search-help": "Soektogte kan volgende taalnaam, skripnaam, ISO-kode, of volgens streek geskied.",
"uls-search-help": "Soek gerus volgens taalnaam, skrifnaam of ISO-kode, of blaai volgens streek.",
"uls-search-placeholder": "Soek na n taal"
}

11
i18n/ais.json Normal file
View File

@@ -0,0 +1,11 @@
{
"@metadata": {
"authors": [
"Benel"
]
},
"uls-region-AM": "Amilikaco",
"uls-region-AF": "Afilika",
"uls-region-EU": "Ouco",
"uls-region-AS": "Yaco"
}

View File

@@ -3,7 +3,8 @@
"authors": [
"Calak",
"Asoxor",
"Lost Whispers"
"Lost Whispers",
"Épine"
]
},
"uls-region-WW": "لە گشت جیھاندا",

View File

@@ -1,12 +1,20 @@
{
"@metadata": {
"authors": [
"ⲁϩⲙⲉⲧ"
"ⲁϩⲙⲉⲧ",
"Bloomaround"
]
},
"uls-region-WW": "ⲧⲏⲣⲙⲁⲓ",
"uls-region-AM": "ⲁⲙⲉⲣⲓⲕⲏ",
"uls-region-AF": "ⲁϥⲣⲓⲕⲏ",
"uls-region-AF": "ⲁⲣⲓⲕⲏ",
"uls-region-EU": "ⲉⲩⲣⲱⲡⲏ",
"uls-region-AS": "ⲁⲥⲓⲁ",
"uls-region-all": "ⲁⲥⲡⲓ ⲛⲓⲃⲉⲛ"
"uls-region-ME": "ⲡⲓⲉⲃⲧ `ⲛⲑⲙⲏϯ",
"uls-region-PA": "ⲱⲕⲉⲁⲛⲓⲁ",
"uls-region-all": "ⲁⲥⲡⲓ ⲛⲓⲃⲉⲛ",
"uls-no-results-found": "ⲁⲩϫⲓⲙⲓ ⲁⲛ ⲛⲓⲁⲡⲟⲧⲉⲗⲉⲥⲙⲁ",
"uls-common-languages": "ⲛⲓⲁⲥⲡⲓ ⲁⲩϯⲙⲉⲩⲓ",
"uls-search-help": "ⲧⲉⲧⲉⲛϫⲉⲙϫⲟⲙ ϫⲉⲙⲣⲁⲧ ϩⲉⲛ `ⲫⲣⲁⲛ ⲛⲧⲉ ⲁⲥⲡⲓ, `ⲫⲣⲁⲛ ⲛⲧⲉ ⲓⲟⲡⲓⲥϧⲁⲓ , ISO ⲕⲱⲇⲓⲕⲟⲥ ⲛⲧⲉ ⲁⲥⲡⲓ ⲓⲉ ⲧⲉⲧⲉⲛϫⲉⲙϫⲟⲙ ⲥⲓⲛⲓ ϧⲁⲧⲉⲛⲙⲁⲛⲧⲉϭⲁ.",
"uls-search-placeholder": "ϫⲉⲙⲣⲁⲧⲕ `ⲛⲟⲩⲁⲥⲡⲓ"
}

View File

@@ -16,5 +16,6 @@
"uls-no-results-found": "𑢮𑣁𑣓𑣄 𑣌𑣁 𑣓𑣖 𑣎𑣓𑣁",
"uls-common-languages": "𑢨𑣒𑣄 𑣎𑣈𑣋𑣁𑣜 𑣌𑣉",
"uls-no-results-suggestion-title": "𑢳𑣈𑣓𑣁 𑣌𑣉 𑣏𑣂 𑣗𑣈𑣓 𑣓𑣖 𑣕𑣓𑣁:",
"uls-search-help": "𑢮𑣈𑣋𑣁𑣜 𑣓𑣃𑣕𑣃𑣖 𑣕𑣈, 𑣏𑣂𑣕𑣂 𑣓𑣃𑣕𑣃𑣖 𑣕𑣈, 𑣎𑣈𑣋𑣁𑣜 𑣜𑣈𑣅𑣄 ISO 𑣌𑣉𑣉𑣑 𑣕𑣈 𑣌𑣁𑣜𑣈 𑣕𑣅𑣑 𑣓𑣃𑣕𑣃𑣖 𑣕𑣈 𑣉𑣉 𑣓𑣖-𑣓𑣈𑣚 𑣔𑣆𑣅𑣉𑣄𑣁.",
"uls-search-placeholder": "𑢶𑣂𑣈𑣑 𑣎𑣈𑣋𑣁𑣓 𑣓𑣈𑣚-𑣓𑣖𑣈"
}

View File

@@ -1,7 +1,8 @@
{
"@metadata": {
"authors": [
"MokaAkashiyaPT"
"MokaAkashiyaPT",
"Athena in Wonderland"
]
},
"uls-region-WW": "Global",
@@ -12,6 +13,10 @@
"uls-region-AS": "Ásia",
"uls-region-ME": "Médio Ouriente",
"uls-region-PA": "Pacífico",
"uls-region-all": "Todas las lhénguas",
"uls-no-results-found": "Nó fúrun ancontrados resultados",
"uls-common-languages": "Lhénguas sugeridas",
"uls-no-results-suggestion-title": "Puode star antressado an:",
"uls-search-help": "Puode percurar pul nome de la lhéngua, pul tipo de abc, código ISO de la lhéngua, ó puode nabegar por region.",
"uls-search-placeholder": "Percurar por lhéngua"
}

View File

@@ -2,7 +2,8 @@
"@metadata": {
"authors": [
"Siebrand",
"Sjoerddebruin"
"Sjoerddebruin",
"Mar(c)"
]
},
"uls-region-WW": "Wereldwijd",
@@ -16,7 +17,7 @@
"uls-region-all": "Alle talen",
"uls-no-results-found": "Geen resultaten gevonden",
"uls-common-languages": "Taalsuggesties",
"uls-no-results-suggestion-title": "Wellicht wilt u een van de volgende talen kiezen:",
"uls-search-help": "U kunt zoeken op taalnaam, schriftnaam, ISO-code van de taal of u kunt bladeren per regio.",
"uls-no-results-suggestion-title": "Mogelijk bent u geïnteresseerd in:",
"uls-search-help": "U kunt zoeken op taalnaam, schriftnaam of ISO-code van de taal, of u kunt bladeren per regio.",
"uls-search-placeholder": "Zoeken naar een taal"
}

21
i18n/roa-tara.json Normal file
View File

@@ -0,0 +1,21 @@
{
"@metadata": {
"authors": [
"Joetaras"
]
},
"uls-region-WW": "Tutte 'u munne",
"uls-region-SP": "Speciale",
"uls-region-AM": "Americhe",
"uls-region-AF": "Afriche",
"uls-region-EU": "Europe",
"uls-region-AS": "Asia",
"uls-region-ME": "Medie oriende",
"uls-region-PA": "Pacifeche",
"uls-region-all": "Tutte le lènghe",
"uls-no-results-found": "Nisciune resultate acchiate",
"uls-common-languages": "Lènghe suggerite",
"uls-no-results-suggestion-title": "Puè essere 'nderessate a:",
"uls-search-help": "Puè cercà pe nome d'a lènghe, nome d'u script, codece ISO d'a lènghe o puè navegà passanne pa reggione.",
"uls-search-placeholder": "Cirche 'na lènghe"
}

11
i18n/twd.json Normal file
View File

@@ -0,0 +1,11 @@
{
"@metadata": {
"authors": [
"Robin van der Vliet"
]
},
"uls-region-WW": "Wearldwied",
"uls-region-AM": "Amerika",
"uls-region-AF": "Afrika",
"uls-region-EU": "Europa"
}

View File

@@ -5,16 +5,17 @@
]
},
"uls-region-WW": "Tuto el mondo",
"uls-region-SP": "Speciałi",
"uls-region-SP": "Speciaƚi",
"uls-region-AM": "Mèrica",
"uls-region-AF": "Àfrica",
"uls-region-EU": "Eoropa",
"uls-region-AS": "Axia",
"uls-region-ME": "Levante mexan",
"uls-region-PA": "Pasifego",
"uls-region-all": "Tute ƚe ƚengue",
"uls-no-results-found": "Nisun rixultado",
"uls-common-languages": "Lengue pì sielte",
"uls-common-languages": "Lengue sugerìe",
"uls-no-results-suggestion-title": "Te pol èsar interesà a:",
"uls-search-help": "Xe posibiłe sercar par nome, nome del script, còdexe ISO de ła lengua o se pol navegar par region:",
"uls-search-placeholder": "Serca lengua"
"uls-search-help": "Xe posibiƚe sercar par nòme, nòme del script, còdexe ISO de ƚa lengua o se pol navegar par region.",
"uls-search-placeholder": "Serca na lengua"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 802 B

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="27" height="16"><path fill="#D3E3F4" d="M0 0h11.876v16h-11.876v-16z"/><path fill="#E9E9E9" d="M12.819 0v15.969h10.755c1.085-2.578 1.837-4.991 3.062-8.591l-3.062-7.378h-10.755z"/><path fill="#434343" d="M14.828 4.146c.32.023.639.035.951.035.471 0 .922-.016 1.354-.046l.023-.258.034-.367.081-.711.033-.333.873.058c-.073.577-.133 1.091-.179 1.542 1.116-.119 2.233-.331 3.349-.637l.092.809c-1.078.271-2.251.472-3.521.602-.05.463-.082.968-.098 1.514.524-.187 1.14-.313 1.847-.378.064-.207.136-.461.213-.763l.865.201c-.027.123-.088.315-.184.579.814.104 1.461.34 1.938.711.681.542 1.021 1.252 1.021 2.128 0 .963-.406 1.746-1.221 2.351-.635.47-1.505.784-2.609.94l-.505-.779c.968-.104 1.739-.337 2.317-.7.733-.458 1.101-1.066 1.101-1.823 0-.772-.341-1.363-1.021-1.772-.345-.21-.764-.344-1.256-.401-.604 1.422-1.4 2.598-2.387 3.527.035.352.102.715.201 1.09l-.849.314-.126-.773c-.654.462-1.27.693-1.847.693-.696 0-1.044-.407-1.044-1.222 0-1.104.591-2.103 1.771-2.993.227-.165.532-.352.918-.562.012-.524.046-1.128.104-1.812-.585.046-1.143.069-1.675.069l-.493-.011-.071-.822m2.127 3.384c-.268.161-.545.392-.831.694-.612.619-.94 1.226-.986 1.817l-.017.121.017.138c0 .252.112.378.339.378.492 0 1.02-.258 1.582-.773-.057-.613-.092-1.404-.104-2.375m2.455-.884c-.57.08-1.111.226-1.623.436 0 .883.018 1.581.052 2.093.634-.707 1.158-1.55 1.571-2.529"/><path fill="#1A1A1A" d="M8.517 11.735l-.734-2.409h-3.69l-.734 2.409h-2.313l3.573-10.165h2.625l3.587 10.165h-2.314m-1.246-4.21c-.679-2.183-1.062-3.418-1.149-3.704-.083-.286-.143-.512-.18-.678-.153.59-.589 2.051-1.309 4.382h2.638"/><path fill="#BCBCBC" d="M12.817 13.5v2.5h10.757l.98-2.5h-11.737z"/><path fill="#3692D0" d="M.011 13.511h3.569l2.367-3.116 2.367 3.116h3.57v2.484h-11.873v-2.484z"/></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

BIN
images/language.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

4
images/language.svg Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20">
<path d="M20 18h-1.44a.61.61 0 0 1-.4-.12.81.81 0 0 1-.23-.31L17 15h-5l-1 2.54a.77.77 0 0 1-.22.3.59.59 0 0 1-.4.14H9l4.55-11.47h1.89zm-3.53-4.31L14.89 9.5a11.62 11.62 0 0 1-.39-1.24q-.09.37-.19.69l-.19.56-1.58 4.19zm-6.3-1.58a13.43 13.43 0 0 1-2.91-1.41 11.46 11.46 0 0 0 2.81-5.37H12V4H7.31a4 4 0 0 0-.2-.56C6.87 2.79 6.6 2 6.6 2l-1.47.5s.4.89.6 1.5H0v1.33h2.15A11.23 11.23 0 0 0 5 10.7a17.19 17.19 0 0 1-5 2.1q.56.82.87 1.38a23.28 23.28 0 0 0 5.22-2.51 15.64 15.64 0 0 0 3.56 1.77zM3.63 5.33h4.91a8.11 8.11 0 0 1-2.45 4.45 9.11 9.11 0 0 1-2.46-4.45z" fill="#54595d"/>
</svg>

After

Width:  |  Height:  |  Size: 685 B

View File

@@ -25,20 +25,23 @@
"Siebrand Mazeland"
],
"devDependencies": {
"eslint-config-wikimedia": "0.5.0",
"grunt": "^1.0.1",
"grunt-cli": "^1.2.0",
"grunt-contrib-jshint": "^1.0.0",
"grunt-contrib-qunit": "^1.2.0"
"grunt-eslint": "20.0.0",
"grunt-stylelint": "0.8.0",
"stylelint": "8.2.0",
"grunt-contrib-qunit": "^1.2.0",
"stylelint-config-wikimedia": "0.4.2"
},
"repository": {
"type": "git",
"url": "git://github.com/wikimedia/jquery.uls.git"
},
"bugs": {
"url" : "http://github.com/wikimedia/jquery.uls/issues"
"url" : "https://github.com/wikimedia/jquery.uls/issues"
},
"engine": {
"node": ">=0.10.x"
"node": ">=6.11.1"
},
"license": "(MIT OR GPL-2.0+)",
"scripts": {

View File

@@ -1,10 +1,11 @@
var through = require( 'through' );
var through = require( 'through' ); // eslint-disable-line no-implicit-globals
module.exports = function ( file ) {
module.exports = function () {
var data, end, write;
data = '( function ( $ ) {\n\t$.uls = $.uls || {};\n\t$.uls.data = ';
write = function ( buf ) {
return data += buf;
data += buf;
return data;
};
end = function () {
data += '\n} ( jQuery ) );';

View File

@@ -24,17 +24,17 @@
var template, ULS;
// Region numbers in id attributes also appear in the langdb.
/*jshint multistr:true */
// eslint-disable-next-line no-multi-str
template = '<div class="grid uls-menu"> \
<div id="search" class="row uls-search"> \
<div class="uls-search-wrapper"> \
<label class="uls-search-label" for="uls-languagefilter"></label>\
<div class="uls-search-input-wrapper">\
<span id="uls-languagefilter-clear" class="uls-languagefilter-clear"></span>\
<span class="uls-languagefilter-clear"></span>\
<input type="text" class="uls-filterinput uls-filtersuggestion"\
id="uls-filtersuggestion" disabled="true" autocomplete="off">\
disabled="true" autocomplete="off">\
<input type="text" class="uls-filterinput uls-languagefilter"\
id="uls-languagefilter" data-clear="uls-languagefilter-clear"\
data-clear="uls-languagefilter-clear"\
data-suggestion="uls-filtersuggestion"\
placeholder="Search for a language" autocomplete="off">\
</div>\
@@ -43,42 +43,20 @@
<div class="row uls-language-list"></div>\
<div class="row" id="uls-settings-block"></div>\
</div>';
/*jshint multistr:false */
/**
* Count the number of keys in an object.
* Works in a cross-browser way.
* @param {Object} The object.
*/
function objectLength ( obj ) {
var count, key;
// Some old browsers don't support Object.keys
if ( Object.keys ) {
return Object.keys( obj ).length;
}
count = 0;
for ( key in obj ) {
if ( Object.prototype.hasOwnProperty.call( obj, key ) ) {
count++;
}
}
return count;
}
/**
* ULS Public class definition
* @param {Element} element
* @param {Object} options
*/
ULS = function ( element, options ) {
var code;
this.$element = $( element );
this.options = $.extend( {}, $.fn.uls.defaults, options );
this.$menu = $( template );
this.languages = this.options.languages;
for ( var code in this.languages ) {
for ( code in this.languages ) {
if ( $.uls.data.languages[ code ] === undefined ) {
// Language is unknown to ULS.
delete this.languages[ code ];
@@ -90,7 +68,7 @@
this.shown = false;
this.initialized = false;
this.$languageFilter = this.$menu.find( '#uls-languagefilter' );
this.$languageFilter = this.$menu.find( '.uls-languagefilter' );
this.$resultsView = this.$menu.find( '.uls-language-list' );
this.render();
@@ -131,7 +109,7 @@
/**
* Calculate the position of ULS
* Returns an object with top and left properties.
* @returns {Object}
* @return {Object}
*/
position: function () {
var pos,
@@ -142,14 +120,13 @@
pos = $.extend( {}, this.$element.offset(), {
height: this.$element[ 0 ].offsetHeight
} );
top = pos.top + pos.height;
top = pos.top + pos.height;
}
if ( left === undefined ) {
left = $( window ).width() / 2 - this.$menu.outerWidth() / 2;
}
return {
top: top,
left: left
@@ -166,7 +143,7 @@
narrow: 'uls-narrow'
};
this.$menu.addClass( widthClasses[this.getMenuWidth()] );
this.$menu.addClass( widthClasses[ this.getMenuWidth() ] );
if ( !this.initialized ) {
$( 'body' ).prepend( this.$menu );
@@ -213,13 +190,6 @@
// Rendering stuff here
},
/**
* Callback for no results found context.
*/
noresults: function () {
this.$resultsView.lcd( 'noResults' );
},
/**
* Callback for results found context.
*/
@@ -248,33 +218,30 @@
} );
// Handle key press events on the menu
this.$menu.on( 'keypress', $.proxy( this.keypress, this ) )
.on( 'keyup', $.proxy( this.keyup, this ) );
this.$menu.on( 'keydown', $.proxy( this.keypress, this ) );
if ( this.eventSupported( 'keydown' ) ) {
this.$menu.on( 'keydown', $.proxy( this.keypress, this ) );
}
languagesCount = objectLength( this.options.languages );
languagesCount = Object.keys( this.options.languages ).length;
lcd = this.$resultsView.lcd( {
languages: this.languages,
columns: columnsOptions[ this.getMenuWidth() ],
quickList: languagesCount > 12 ? this.options.quickList : [],
clickhandler: $.proxy( this.select, this ),
source: this.$languageFilter,
showRegions: this.options.showRegions,
languageDecorator: this.options.languageDecorator
languageDecorator: this.options.languageDecorator,
noResultsTemplate: this.options.noResultsTemplate,
itemsPerColumn: this.options.itemsPerColumn,
groupByRegion: this.options.groupByRegion
} ).data( 'lcd' );
this.$languageFilter.languagefilter( {
$target: lcd,
lcd: lcd,
languages: this.languages,
searchAPI: this.options.searchAPI,
onSelect: $.proxy( this.select, this )
} );
this.$languageFilter.on( 'noresults.uls', $.proxy( this.noresults, this ) );
this.$languageFilter.on( 'noresults.uls', $.proxy( lcd.noResults, lcd ) );
this.$languageFilter.on( 'resultsfound.uls', $.proxy( this.success, this ) );
$( 'html' ).click( $.proxy( this.cancel, this ) );
@@ -282,7 +249,7 @@
/**
* On select handler for search results
* @param langCode
* @param {string} langCode
*/
select: function ( langCode ) {
this.hide();
@@ -293,27 +260,16 @@
/**
* On cancel handler for the uls menu
* @param {Event} e
*/
cancel: function ( e ) {
if ( e && ( this.$element.is( e.target ) || $.contains( this.$element[0], e.target ) ) ) {
if ( e && ( this.$element.is( e.target ) || $.contains( this.$element[ 0 ], e.target ) ) ) {
return;
}
this.hide();
},
keyup: function ( e ) {
if ( !this.shown ) {
return;
}
if ( e.keyCode === 27 ) { // escape
this.cancel();
e.preventDefault();
e.stopPropagation();
}
},
keypress: function ( e ) {
if ( !this.shown ) {
return;
@@ -334,20 +290,9 @@
}
},
eventSupported: function ( eventName ) {
var isSupported = eventName in this.$menu;
if ( !isSupported ) {
this.$element.setAttribute( eventName, 'return;' );
isSupported = typeof this.$element[ eventName ] === 'function';
}
return isSupported;
},
/**
* Get the panel menu width parameter
* @return string
* @return {string}
*/
getMenuWidth: function () {
var languagesCount;
@@ -356,7 +301,7 @@
return this.options.menuWidth;
}
languagesCount = objectLength( this.options.languages );
languagesCount = Object.keys( this.options.languages ).length;
if ( languagesCount < 25 ) {
return 'narrow';
@@ -394,15 +339,35 @@
};
$.fn.uls.defaults = {
onSelect: null, // Callback function to be called when a language is selected
searchAPI: null, // Language search API
languages: $.uls.data.getAutonyms(), // Languages to be used for ULS, default is all languages
quickList: [], // Array of language codes or function that returns such
// CSS top position for the dialog
top: undefined,
// CSS left position for the dialog
left: undefined,
// Callback function when user selects a language
onSelect: undefined,
// Callback function when the dialog is closed without selecting a language
onCancel: undefined,
// Callback function when ULS has initialized
onReady: undefined,
// Callback function when ULS dialog is shown
onVisible: undefined,
// Languages to be used for ULS, default is all languages
languages: $.uls.data.getAutonyms(),
// The options are wide (4 columns), medium (2 columns), and narrow (1 column).
// If not specified, it will be set automatically.
menuWidth: null,
showRegions: [ 'WW', 'AM', 'EU', 'ME', 'AF', 'AS', 'PA' ],
languageDecorator: null // Callback function to be called when a language link is prepared - for custom decoration.
menuWidth: undefined,
// Used by LCD
quickList: [],
// Used by LCD
showRegions: undefined,
// Used by LCD
languageDecorator: undefined,
// Used by LCD
itemsPerColumn: undefined,
// Used by LCD
groupByRegion: undefined,
// Used by LanguageFilter
searchAPI: undefined
};
// Define a dummy i18n function, if jquery.i18n not integrated.

View File

@@ -897,7 +897,8 @@ module.exports=( function ( $ ) {
"EU",
"AM",
"AF",
"WW"
"WW",
"PA"
],
"español"
],
@@ -1360,6 +1361,14 @@ module.exports=( function ( $ ) {
],
"Հայերեն"
],
"hyw": [
"Armn",
[
"EU",
"ME"
],
"արեւմտահայերէն"
],
"hz": [
"Latn",
[
@@ -1801,6 +1810,13 @@ module.exports=( function ( $ ) {
],
"Kurdî"
],
"kum": [
"Cyrl",
[
"EU"
],
"къумукъ"
],
"kv": [
"Cyrl",
[
@@ -5084,6 +5100,7 @@ module.exports=( function ( $ ) {
"kbd",
"myv",
"mdf",
"kum",
"kv",
"lez",
"krc",
@@ -5449,6 +5466,5 @@ module.exports=( function ( $ ) {
]
}
}
} ( jQuery ) );
},{}]},{},[1]);

View File

@@ -22,18 +22,18 @@
/**
* Is this language a redirect to another language?
* @param language string Language code
* @return Target language code if it's a redirect or false if it's not
* @param {string} language Language code
* @return {string|boolean} Target language code if it's a redirect or false if it's not
*/
$.uls.data.isRedirect = function ( language ) {
return ( $.uls.data.languages[language] !== undefined &&
$.uls.data.languages[language].length === 1 ) ? $.uls.data.languages[language][0] : false;
return ( $.uls.data.languages[ language ] !== undefined &&
$.uls.data.languages[ language ].length === 1 ) ? $.uls.data.languages[ language ][ 0 ] : false;
};
/**
* Returns the script of the language.
* @param language string Language code
* @return string
* @param {string} language Language code
* @return {string}
*/
$.uls.data.getScript = function ( language ) {
var target = $.uls.data.isRedirect( language );
@@ -42,18 +42,18 @@
return $.uls.data.getScript( target );
}
if ( !$.uls.data.languages[language] ) {
if ( !$.uls.data.languages[ language ] ) {
// Undetermined
return 'Zyyy';
}
return $.uls.data.languages[language][0];
return $.uls.data.languages[ language ][ 0 ];
};
/**
* Returns the regions in which a language is spoken.
* @param language string Language code
* @return array|string 'UNKNOWN'
* @param {string} language Language code
* @return {string|string[]}
*/
$.uls.data.getRegions = function ( language ) {
var target = $.uls.data.isRedirect( language );
@@ -62,13 +62,13 @@
return $.uls.data.getRegions( target );
}
return ( $.uls.data.languages[language] && $.uls.data.languages[language][1] ) || 'UNKNOWN';
return ( $.uls.data.languages[ language ] && $.uls.data.languages[ language ][ 1 ] ) || 'UNKNOWN';
};
/**
* Returns the autonym of the language.
* @param language string Language code
* @return string
* @param {string} language Language code
* @return {string}
*/
$.uls.data.getAutonym = function ( language ) {
var target = $.uls.data.isRedirect( language );
@@ -77,12 +77,12 @@
return $.uls.data.getAutonym( target );
}
return ( $.uls.data.languages[language] && $.uls.data.languages[language][2] ) || language;
return ( $.uls.data.languages[ language ] && $.uls.data.languages[ language ][ 2 ] ) || language;
};
/**
* Returns all language codes and corresponding autonyms
* @return array
* @return {string[]}
*/
$.uls.data.getAutonyms = function () {
var language,
@@ -93,7 +93,7 @@
continue;
}
autonymsByCode[language] = $.uls.data.getAutonym( language );
autonymsByCode[ language ] = $.uls.data.getAutonym( language );
}
return autonymsByCode;
@@ -101,8 +101,8 @@
/**
* Returns all languages written in script.
* @param script string
* @return array of strings (languages codes)
* @param {string} script string
* @return {string[]} languages codes
*/
$.uls.data.getLanguagesInScript = function ( script ) {
return $.uls.data.getLanguagesInScripts( [ script ] );
@@ -110,8 +110,8 @@
/**
* Returns all languages written in the given scripts.
* @param scripts array of strings
* @return array of strings (languages codes)
* @param {string[]} scripts
* @return {string[]} languages codes
*/
$.uls.data.getLanguagesInScripts = function ( scripts ) {
var language, i,
@@ -123,7 +123,7 @@
}
for ( i = 0; i < scripts.length; i++ ) {
if ( scripts[i] === $.uls.data.getScript( language ) ) {
if ( scripts[ i ] === $.uls.data.getScript( language ) ) {
languagesInScripts.push( language );
break;
}
@@ -136,8 +136,8 @@
/**
* Returns an associative array of languages in a region,
* grouped by script group.
* @param region string Region code
* @return associative array
* @param {string} region Region code
* @return {object}
*/
$.uls.data.getLanguagesByScriptGroupInRegion = function ( region ) {
return $.uls.data.getLanguagesByScriptGroupInRegions( [ region ] );
@@ -145,7 +145,7 @@
/**
* Get the given list of languages grouped by script.
* @param languages Array of language codes
* @param {string} languages Array of language codes
* @return {Object} Array of languages indexed by script codes
*/
$.uls.data.getLanguagesByScriptGroup = function ( languages ) {
@@ -157,11 +157,11 @@
langScriptGroup = $.uls.data.getScriptGroupOfLanguage( resolvedRedirect );
if ( !languagesByScriptGroup[langScriptGroup] ) {
languagesByScriptGroup[langScriptGroup] = [];
if ( !languagesByScriptGroup[ langScriptGroup ] ) {
languagesByScriptGroup[ langScriptGroup ] = [];
}
languagesByScriptGroup[langScriptGroup].push( language );
languagesByScriptGroup[ langScriptGroup ].push( language );
}
return languagesByScriptGroup;
@@ -170,8 +170,8 @@
/**
* Returns an associative array of languages in several regions,
* grouped by script group.
* @param regions array of strings - region codes
* @return associative array
* @param {string[]} regions region codes
* @return {Object}
*/
$.uls.data.getLanguagesByScriptGroupInRegions = function ( regions ) {
var language, i, scriptGroup,
@@ -183,14 +183,14 @@
}
for ( i = 0; i < regions.length; i++ ) {
if ( $.inArray( regions[i], $.uls.data.getRegions( language ) ) !== -1 ) {
if ( $.inArray( regions[ i ], $.uls.data.getRegions( language ) ) !== -1 ) {
scriptGroup = $.uls.data.getScriptGroupOfLanguage( language );
if ( languagesByScriptGroupInRegions[scriptGroup] === undefined ) {
languagesByScriptGroupInRegions[scriptGroup] = [];
if ( languagesByScriptGroupInRegions[ scriptGroup ] === undefined ) {
languagesByScriptGroupInRegions[ scriptGroup ] = [];
}
languagesByScriptGroupInRegions[scriptGroup].push( language );
languagesByScriptGroupInRegions[ scriptGroup ].push( language );
break;
}
}
@@ -202,14 +202,14 @@
/**
* Returns the script group of a script or 'Other' if it doesn't
* belong to any group.
* @param script string Script code
* @return string script group name
* @param {string} script Script code
* @return {string} script group name
*/
$.uls.data.getGroupOfScript = function ( script ) {
var scriptGroup;
for ( scriptGroup in $.uls.data.scriptgroups ) {
if ( $.inArray( script, $.uls.data.scriptgroups[scriptGroup] ) !== -1 ) {
if ( $.inArray( script, $.uls.data.scriptgroups[ scriptGroup ] ) !== -1 ) {
return scriptGroup;
}
}
@@ -219,8 +219,8 @@
/**
* Returns the script group of a language.
* @param language string Language code
* @return string script group name
* @param {string} language Language code
* @return {string} script group name
*/
$.uls.data.getScriptGroupOfLanguage = function ( language ) {
return $.uls.data.getGroupOfScript( $.uls.data.getScript( language ) );
@@ -229,8 +229,9 @@
/**
* A callback for sorting languages by autonym.
* Can be used as an argument to a sort function.
* @param a string Language code
* @param b string Language code
* @param {string} a Language code
* @param {string} b Language code
* @return {number}
*/
$.uls.data.sortByAutonym = function ( a, b ) {
var autonymA = $.uls.data.getAutonym( a ) || a,
@@ -241,8 +242,8 @@
/**
* Check if a language is right-to-left.
* @param language string Language code
* @return boolean
* @param {string} language Language code
* @return {boolean}
*/
$.uls.data.isRtl = function ( language ) {
return $.inArray( $.uls.data.getScript( language ), $.uls.data.rtlscripts ) !== -1;
@@ -250,8 +251,8 @@
/**
* Return the direction of the language
* @param language string Language code
* @return string
* @param {string} language Language code
* @return {string}
*/
$.uls.data.getDir = function ( language ) {
return $.uls.data.isRtl( language ) ? 'rtl' : 'ltr';
@@ -259,11 +260,11 @@
/**
* Returns the languages spoken in a territory.
* @param territory string Territory code
* @return list of language codes
* @param {string} territory Territory code
* @return {string[]} list of language codes
*/
$.uls.data.getLanguagesInTerritory = function ( territory ) {
return $.uls.data.territories[territory];
return $.uls.data.territories[ territory ];
};
/**
@@ -271,30 +272,30 @@
* If the target option is provided, the language is defined as a redirect.
* Other possible options are script, regions and autonym.
*
* @param code string New language code.
* @param options Object Language properties.
* @param {string} code New language code.
* @param {Object} options Language properties.
*/
$.uls.data.addLanguage = function( code, options ) {
$.uls.data.addLanguage = function ( code, options ) {
if ( options.target ) {
$.uls.data.languages[code] = [options.target];
$.uls.data.languages[ code ] = [ options.target ];
} else {
$.uls.data.languages[code] = [options.script, options.regions, options.autonym];
$.uls.data.languages[ code ] = [ options.script, options.regions, options.autonym ];
}
};
/**
* Removes a language from the langdb in run time.
*
* @param code string Language code to delete.
* @return true if the language was removed, false otherwise.
* @param {string} code Language code to delete.
* @return {boolean} true if the language was removed, false otherwise.
*/
$.uls.data.deleteLanguage = function( code ) {
if ( $.uls.data.languages[code] ) {
delete $.uls.data.languages[code];
$.uls.data.deleteLanguage = function ( code ) {
if ( $.uls.data.languages[ code ] ) {
delete $.uls.data.languages[ code ];
return true;
}
return false;
};
} ( jQuery ) );
}( jQuery ) );

View File

@@ -19,21 +19,34 @@
/**
* Usage: $( 'inputbox' ).languagefilter();
* The values for autocompletion is from the options.languages.
* The data is in the format of languagecode:languagename.
* The values for autocompletion is from the options.languages or options.searchAPI.
*/
( function ( $ ) {
'use strict';
var LanguageFilter, delay;
/**
* Check if a prefix is visually prefix of a string
*
* @param {string} prefix
* @param {string} string
* @return {boolean}
*/
function isVisualPrefix( prefix, string ) {
// Pre-base vowel signs of Indic languages. A vowel sign is called pre-base if
// consonant + vowel becomes [vowel][consonant] when rendered. Eg: ക + െ => കെ
var prebases = 'െേൈൊോൌெேைொோௌେୈୋୌિਿिিেৈোৌෙේෛොෝෞ';
return prebases.indexOf( string[ prefix.length ] ) <= 0;
}
LanguageFilter = function ( element, options ) {
this.$element = $( element );
this.options = $.extend( {}, $.fn.languagefilter.defaults, options );
this.$element.addClass( 'languagefilter' );
this.resultCount = 0;
this.$suggestion = this.$element.parents().find( '#' + this.$element.data( 'suggestion' ) );
this.$clear = this.$element.parents().find( '#' + this.$element.data( 'clear' ) );
this.$suggestion = this.$element.siblings( '.' + this.$element.data( 'suggestion' ) );
this.$clear = this.$element.siblings( '.' + this.$element.data( 'clear' ) );
this.selectedLanguage = null;
this.init();
this.listen();
@@ -54,12 +67,8 @@
},
listen: function () {
this.$element.on( 'keypress', $.proxy( this.keyup, this ) )
.on( 'keyup', $.proxy( this.keyup, this ) );
if ( this.eventSupported( 'keydown' ) ) {
this.$element.on( 'keydown', $.proxy( this.keyup, this ) );
}
this.$element.on( 'keydown', $.proxy( this.keypress, this ) );
if ( this.$clear.length ) {
this.$clear.on( 'click', $.proxy( this.clear, this ) );
@@ -68,62 +77,62 @@
this.toggleClear();
},
keyup: function ( e ) {
keypress: function ( e ) {
var suggestion, query, languageFilter;
switch ( e.keyCode ) {
case 9: // Tab -> Autocomplete
suggestion = this.$suggestion.val();
case 9: // Tab -> Autocomplete
suggestion = this.$suggestion.val();
if ( suggestion && suggestion !== this.$element.val() ) {
this.$element.val( suggestion );
if ( suggestion && suggestion !== this.$element.val() ) {
this.$element.val( suggestion );
e.preventDefault();
e.stopPropagation();
}
break;
case 13: // Enter
if ( !this.options.onSelect ) {
break;
}
// Avoid bubbling this 'enter' to background page elements
e.preventDefault();
e.stopPropagation();
}
break;
case 13: // Enter
if ( !this.options.onSelect ) {
break;
}
// Avoid bubbling this 'enter' to background page elements
e.preventDefault();
e.stopPropagation();
query = $.trim( this.$element.val() ).toLowerCase();
query = $.trim( this.$element.val() ).toLowerCase();
if ( this.selectedLanguage ) {
// this.selectLanguage will be populated from a matching search
this.options.onSelect( this.selectedLanguage );
} else if ( this.options.languages[ query ] ) {
// Search is yet to happen (in timeout delay),
// but we have a matching language code.
this.options.onSelect( query );
}
break;
default:
languageFilter = this;
if ( e.which < 32 &&
e.which !== 8 // Backspace
) {
// ignore any ASCII control characters
break;
}
this.selectedLanguage = null;
delay( function () {
if ( !languageFilter.$element.val() ) {
languageFilter.clear();
} else {
languageFilter.options.$target.empty();
languageFilter.search();
if ( this.selectedLanguage ) {
// this.selectLanguage will be populated from a matching search
this.options.onSelect( this.selectedLanguage );
} else if ( this.options.languages[ query ] ) {
// Search is yet to happen (in timeout delay),
// but we have a matching language code.
this.options.onSelect( query );
}
}, 300 );
this.toggleClear();
break;
default:
languageFilter = this;
if ( e.which < 32 &&
e.which !== 8 // Backspace
) {
// ignore any ASCII control characters
break;
}
this.selectedLanguage = null;
delay( function () {
if ( !languageFilter.$element.val() ) {
languageFilter.clear();
} else {
languageFilter.options.lcd.empty();
languageFilter.search();
}
}, 300 );
this.toggleClear();
}
},
@@ -167,86 +176,75 @@
},
search: function () {
var langCode, scriptGroup, langNum, languagesInScript,
languages = $.uls.data.getLanguagesByScriptGroup( this.options.languages ),
query = $.trim( this.$element.val() );
var languages = Object.keys( this.options.languages ),
results = [],
query = $.trim( this.$element.val() ).toLowerCase();
this.resultCount = 0;
for ( scriptGroup in languages ) {
languagesInScript = languages[ scriptGroup ];
languagesInScript.sort( $.uls.data.sortByAutonym );
for ( langNum = 0; langNum < languagesInScript.length; langNum++ ) {
langCode = languagesInScript[ langNum ];
if ( query === '' || this.filter( langCode, query ) ) {
if ( this.resultCount === 0 ) {
// Autofill the first result.
this.autofill( langCode );
}
if ( query.toLowerCase() === langCode ) {
this.selectedLanguage = langCode;
}
if ( this.render( langCode ) ) {
this.resultCount++;
}
}
}
if ( query === '' ) {
this.options.lcd.setGroupByRegionOverride( null );
this.resultHandler( query, languages );
return;
}
// Also do a search by search API
if ( !this.resultCount && this.options.searchAPI && query ) {
this.searchAPI( query );
this.options.lcd.setGroupByRegionOverride( false );
// Local search results
results = languages.filter( function ( langCode ) {
return this.filter( langCode, query );
}.bind( this ) );
// Use the searchAPI if available, assuming that it has superior search results.
if ( this.options.searchAPI ) {
this.searchAPI( query )
.done( this.resultHandler.bind( this ) )
.fail( this.resultHandler.bind( this, query, results, undefined ) );
} else {
this.resultHandler( query );
this.resultHandler( query, results );
}
},
searchAPI: function ( query ) {
var languageFilter = this;
return $.get( this.options.searchAPI, { search: query } ).then( function ( result ) {
var autofillLabel,
results = [];
$.get( languageFilter.options.searchAPI, {
search: query
}, function ( result ) {
$.each( result.languagesearch, function ( code, name ) {
var target;
if ( languageFilter.resultCount === 0 ) {
// Autofill the first result.
languageFilter.autofill( code, name );
}
if ( languageFilter.options.languages[ code ] &&
languageFilter.render( code )
) {
languageFilter.resultCount++;
if ( this.options.languages[ code ] ) {
autofillLabel = autofillLabel || name;
results.push( code );
return;
}
// Try to hide issues caused by inconsistent language codes
target = $.uls.data.isRedirect( code );
if ( languageFilter.options.languages[ target ] &&
languageFilter.render( target )
) {
languageFilter.resultCount++;
if ( target && this.options.languages[ target ] ) {
autofillLabel = autofillLabel || name;
results.push( target );
}
} );
languageFilter.resultHandler( query );
} );
return $.Deferred().resolve( query, results, autofillLabel );
}.bind( this ) );
},
/**
* Handler method to be called once search is over.
* Based on search result triggers resultsfound or noresults events
* @param query string
* @param {string} query
* @param {string[]} results
* @param {string} [autofillLabel]
*/
resultHandler: function ( query ) {
if ( this.resultCount === 0 ) {
resultHandler: function ( query, results, autofillLabel ) {
if ( results.length === 0 ) {
this.$suggestion.val( '' );
this.$element.trigger( 'noresults.uls', query );
} else {
this.$element.trigger( 'resultsfound.uls', [ query, this.resultCount ] );
return;
}
if ( query ) {
this.selectedLanguage = results[ 0 ];
this.autofill( results[ 0 ], autofillLabel );
}
results.map( this.render.bind( this ) );
this.$element.trigger( 'resultsfound.uls', [ query, results.length ] );
},
autofill: function ( langCode, languageName ) {
@@ -261,7 +259,6 @@
return;
}
this.selectedLanguage = langCode;
languageName = languageName || this.options.languages[ langCode ];
if ( !languageName ) {
@@ -291,17 +288,11 @@
},
render: function ( langCode ) {
var $target = this.options.$target;
if ( !$target ) {
return false;
}
return $target.append( langCode );
return this.options.lcd.append( langCode );
},
escapeRegex: function ( value ) {
return value.replace( /[\-\[\]{}()*+?.,\\\^$\|#\s]/g, '\\$&' );
return value.replace( /[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&' );
},
/**
@@ -311,6 +302,9 @@
* b) Language autonym 'starts with' search string.
* c) ISO 639 code match with search string.
* d) ISO 15924 code for the script match the search string.
* @param {string} langCode
* @param {string} searchTerm
* @return {boolean}
*/
filter: function ( langCode, searchTerm ) {
// FIXME script is ISO 15924 code. We might need actual name of script.
@@ -321,17 +315,6 @@
matcher.test( $.uls.data.getAutonym( langCode ) ) ||
matcher.test( langCode ) ||
matcher.test( $.uls.data.getScript( langCode ) );
},
eventSupported: function ( eventName ) {
var isSupported = eventName in this.$element;
if ( !isSupported ) {
this.$element.setAttribute( eventName, 'return;' );
isSupported = typeof this.$element[ eventName ] === 'function';
}
return isSupported;
}
};
@@ -352,24 +335,16 @@
};
$.fn.languagefilter.defaults = {
$target: null, // Where to append the results
searchAPI: null,
languages: null, // Languages as code:name format.
onSelect: null // Language select handler - like enter in filter textbox.
// LanguageCategoryDisplay
lcd: undefined,
// URL to which we append query parameter with the query value
searchAPI: undefined,
// Object of language tags to language names
languages: [],
// Callback function when language is selected
onSelect: undefined
};
$.fn.languagefilter.Constructor = LanguageFilter;
/**
* Check if a prefix is visually prefix of a string
*
* @param {string} prefix
* @param {string} string
*/
function isVisualPrefix( prefix, string ) {
// Pre-base vowel signs of Indic languages. A vowel sign is called pre-base if
// consonant + vowel becomes [vowel][consonant] when rendered. Eg: ക + െ => കെ
var prebases = 'െേൈൊോൌெேைொோௌେୈୋୌિਿिিেৈোৌෙේෛොෝෞ';
return prebases.indexOf( string[ prefix.length ] ) <= 0;
}
}( jQuery ) );

View File

@@ -22,43 +22,46 @@
( 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 data-i18n="uls-search-help">You can search by language name, script name, ISO code of language or you can browse by region.</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 +70,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 +101,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 +150,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 +185,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 +253,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 +300,6 @@
a.lang = code;
a.dir = $.uls.data.getDir( code );
li.appendChild( a );
if ( this.options.languageDecorator ) {
this.options.languageDecorator( $( a ), code );
@@ -303,7 +315,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 +340,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 +367,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 +432,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 ) );

View File

@@ -13,8 +13,6 @@
*
*/
/*jshint sub:true */
( function ( $ ) {
'use strict';