Santhosh has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/404234 )

Change subject: Update jquery.uls to fd41bbe
......................................................................

Update jquery.uls to fd41bbe

* 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

Bug: T182539
Change-Id: I7341064cd0de367d933048c4800f951568747d11
---
M lib/jquery.uls/css/jquery.uls.css
M lib/jquery.uls/css/jquery.uls.grid.css
M lib/jquery.uls/css/jquery.uls.lcd.css
M lib/jquery.uls/css/jquery.uls.mobile.css
M lib/jquery.uls/i18n/cop.json
M lib/jquery.uls/i18n/mwl.json
D lib/jquery.uls/images/icon-language.png
D lib/jquery.uls/images/icon-language.svg
A lib/jquery.uls/images/language-ltr.png
A lib/jquery.uls/images/language-ltr.svg
A lib/jquery.uls/images/language-rtl.png
A lib/jquery.uls/images/language-rtl.svg
M lib/jquery.uls/src/jquery.uls.core.js
M lib/jquery.uls/src/jquery.uls.data.utils.js
M lib/jquery.uls/src/jquery.uls.languagefilter.js
M lib/jquery.uls/src/jquery.uls.lcd.js
16 files changed, 285 insertions(+), 275 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/UniversalLanguageSelector 
refs/changes/34/404234/1

diff --git a/lib/jquery.uls/css/jquery.uls.css 
b/lib/jquery.uls/css/jquery.uls.css
index 6af44a5..af531f2 100644
--- a/lib/jquery.uls/css/jquery.uls.css
+++ b/lib/jquery.uls/css/jquery.uls.css
@@ -1,8 +1,8 @@
 .uls-trigger {
-       background: url('../images/icon-language.png') no-repeat left center;
+       background: url( ../images/language-ltr.png ) no-repeat left center;
        /* @embed */
-       background-image: linear-gradient(transparent, transparent), 
url('../images/icon-language.svg');
-       padding-left: 30px;
+       background-image: linear-gradient( transparent, transparent ), url( 
../images/language-ltr.svg );
+       padding-left: 25px;
 }
 
 .uls-menu {
@@ -12,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;
@@ -65,9 +65,9 @@
 }
 
 .uls-search-label {
-       background: url('../images/search.png') no-repeat center center;
+       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;
@@ -88,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;
@@ -110,9 +110,9 @@
 }
 
 .uls-languagefilter-clear {
-       background: url('../images/clear.png') no-repeat left center;
+       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;
diff --git a/lib/jquery.uls/css/jquery.uls.grid.css 
b/lib/jquery.uls/css/jquery.uls.grid.css
index 9caf088..f068a86 100644
--- a/lib/jquery.uls/css/jquery.uls.grid.css
+++ b/lib/jquery.uls/css/jquery.uls.grid.css
@@ -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 {
@@ -48,6 +51,14 @@
        max-width: none;
        min-width: 0;
        margin: 0 -5px;
+}
+
+.grid .column,
+.grid .columns {
+       float: left;
+       min-height: 1px;
+       padding: 0 5px;
+       position: relative;
 }
 
 .grid .row.collapse .column,
@@ -55,25 +66,12 @@
        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;
 }
 
diff --git a/lib/jquery.uls/css/jquery.uls.lcd.css 
b/lib/jquery.uls/css/jquery.uls.lcd.css
index 2e836b6..2f62b13 100644
--- a/lib/jquery.uls/css/jquery.uls.lcd.css
+++ b/lib/jquery.uls/css/jquery.uls.lcd.css
@@ -36,6 +36,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.
@@ -51,17 +61,6 @@
 
 .grid .uls-language-block > ul:last-child {
        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 {
@@ -103,6 +102,18 @@
        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;
diff --git a/lib/jquery.uls/css/jquery.uls.mobile.css 
b/lib/jquery.uls/css/jquery.uls.mobile.css
index f7dc7b6..f6ba97b 100644
--- a/lib/jquery.uls/css/jquery.uls.mobile.css
+++ b/lib/jquery.uls/css/jquery.uls.mobile.css
@@ -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;
diff --git a/lib/jquery.uls/i18n/cop.json b/lib/jquery.uls/i18n/cop.json
index 6680102..a6b8361 100644
--- a/lib/jquery.uls/i18n/cop.json
+++ b/lib/jquery.uls/i18n/cop.json
@@ -7,7 +7,7 @@
        },
        "uls-region-WW": "ⲧⲏⲣⲙⲁⲓ",
        "uls-region-AM": "ⲁⲙⲉⲣⲓⲕⲏ",
-       "uls-region-AF": "ⲁϥⲣⲓⲕⲏ",
+       "uls-region-AF": "ⲁⲫⲣⲓⲕⲏ",
        "uls-region-EU": "ⲉⲩⲣⲱⲡⲏ",
        "uls-region-AS": "ⲁⲥⲓⲁ",
        "uls-region-ME": "ⲡⲓⲉⲃⲧ `ⲛⲑⲙⲏϯ",
@@ -15,5 +15,6 @@
        "uls-region-all": "ⲁⲥⲡⲓ ⲛⲓⲃⲉⲛ",
        "uls-no-results-found": "ⲁⲩϫⲓⲙⲓ ⲁⲛ ⲛⲓⲁⲡⲟⲧⲉⲗⲉⲥⲙⲁ",
        "uls-common-languages": "ⲛⲓⲁⲥⲡⲓ ⲁⲩϯⲙⲉⲩⲓ",
-       "uls-search-help": "ⲧⲉⲧⲉⲛϫⲉⲙϫⲟⲙ ϫⲉⲙⲣⲁⲧ ϩⲉⲛ `ⲫⲣⲁⲛ ⲛⲧⲉ ⲁⲥⲡⲓ, `ⲫⲣⲁⲛ ⲛⲧⲉ 
ⲓⲟⲡⲓⲥϧⲁⲓ , ISO ⲕⲱⲇⲓⲕⲟⲥ ⲛⲧⲉ ⲁⲥⲡⲓ ⲓⲉ ⲧⲉⲧⲉⲛϫⲉⲙϫⲟⲙ ⲥⲓⲛⲓ ϧⲁⲧⲉⲛⲙⲁⲛⲧⲉϭⲁ."
+       "uls-search-help": "ⲧⲉⲧⲉⲛϫⲉⲙϫⲟⲙ ϫⲉⲙⲣⲁⲧ ϩⲉⲛ `ⲫⲣⲁⲛ ⲛⲧⲉ ⲁⲥⲡⲓ, `ⲫⲣⲁⲛ ⲛⲧⲉ 
ⲓⲟⲡⲓⲥϧⲁⲓ , ISO ⲕⲱⲇⲓⲕⲟⲥ ⲛⲧⲉ ⲁⲥⲡⲓ ⲓⲉ ⲧⲉⲧⲉⲛϫⲉⲙϫⲟⲙ ⲥⲓⲛⲓ ϧⲁⲧⲉⲛⲙⲁⲛⲧⲉϭⲁ.",
+       "uls-search-placeholder": "ϫⲉⲙⲣⲁⲧⲕ `ⲛⲟⲩⲁⲥⲡⲓ"
 }
diff --git a/lib/jquery.uls/i18n/mwl.json b/lib/jquery.uls/i18n/mwl.json
index 53de32c..a8f5c79 100644
--- a/lib/jquery.uls/i18n/mwl.json
+++ b/lib/jquery.uls/i18n/mwl.json
@@ -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"
 }
diff --git a/lib/jquery.uls/images/icon-language.png 
b/lib/jquery.uls/images/icon-language.png
deleted file mode 100644
index d1f1317..0000000
--- a/lib/jquery.uls/images/icon-language.png
+++ /dev/null
Binary files differ
diff --git a/lib/jquery.uls/images/icon-language.svg 
b/lib/jquery.uls/images/icon-language.svg
deleted file mode 100644
index 9f439be..0000000
--- a/lib/jquery.uls/images/icon-language.svg
+++ /dev/null
@@ -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>
\ No newline at end of file
diff --git a/lib/jquery.uls/images/language-ltr.png 
b/lib/jquery.uls/images/language-ltr.png
new file mode 100644
index 0000000..dc27718
--- /dev/null
+++ b/lib/jquery.uls/images/language-ltr.png
Binary files differ
diff --git a/lib/jquery.uls/images/language-ltr.svg 
b/lib/jquery.uls/images/language-ltr.svg
new file mode 100644
index 0000000..cd1cc73
--- /dev/null
+++ b/lib/jquery.uls/images/language-ltr.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg"; 
width="24" height="24" viewBox="0 0 24 24"><path d="M18.738 15.673l1.137 
3.15h1.575L17.775 7.448h-2.188l-3.85 11.375h1.575l1.05-3.15h4.375zM16.55 
8.76l1.837 5.427h-3.675l1.838-5.425zM8.325 
6.573h.787l-.875-1.75h-1.75l.438.875a1.56 1.56 0 0 0 1.4.875zm.877 6.301c.7.525 
1.486.963 2.45 1.225l-.438 1.31a9.17 9.17 0 0 1-3.063-1.574c-1.49 1.137-3.063 
1.837-4.813 2.363L2.9 14.885c1.486-.525 2.974-1.05 
4.2-2.013-1.138-1.224-1.926-2.537-2.45-4.114H2.987v-1.31h10.85l-.438 
1.312h-1.75c-.308 1.33-1.255 2.957-2.45 4.114zm1.05-4.114H6.138c.35 1.226 1.138 
2.363 2.013 3.238.926-1 1.617-1.957 2.1-3.237z"/></svg>
\ No newline at end of file
diff --git a/lib/jquery.uls/images/language-rtl.png 
b/lib/jquery.uls/images/language-rtl.png
new file mode 100644
index 0000000..c085994
--- /dev/null
+++ b/lib/jquery.uls/images/language-rtl.png
Binary files differ
diff --git a/lib/jquery.uls/images/language-rtl.svg 
b/lib/jquery.uls/images/language-rtl.svg
new file mode 100644
index 0000000..976695d
--- /dev/null
+++ b/lib/jquery.uls/images/language-rtl.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg"; 
width="24" height="24" viewBox="0 0 24 24"><path d="M5.612 15.673l-1.137 
3.15H2.9L6.575 7.448h2.188l3.85 11.375h-1.575l-1.05-3.15H5.613zM7.8 8.76l-1.837 
5.427h3.675L7.8 8.762zM16.384 
6.573h.787l-.873-1.75h-1.75l.438.875c.26.535.805.874 1.4.875zM15.15 
12.874c-.7.525-1.486.963-2.45 1.225l.438 1.31a9.17 9.17 0 0 0 3.063-1.575c1.49 
1.137 3.064 1.837 4.814 2.363l.438-1.313c-1.486-.525-2.974-1.05-4.2-2.013 
1.138-1.224 1.926-2.537 2.45-4.114h1.663v-1.31h-10.85l.438 1.312h1.75c.308 1.33 
1.255 2.957 2.45 4.114zM14.1 8.76h4.114c-.35 1.226-1.138 2.363-2.013 
3.238-.925-1-1.616-1.957-2.1-3.237z"/></svg>
\ No newline at end of file
diff --git a/lib/jquery.uls/src/jquery.uls.core.js 
b/lib/jquery.uls/src/jquery.uls.core.js
index a4071e3..99fcb51 100644
--- a/lib/jquery.uls/src/jquery.uls.core.js
+++ b/lib/jquery.uls/src/jquery.uls.core.js
@@ -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,13 +120,12 @@
                                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,
@@ -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 );
@@ -214,13 +191,6 @@
                },
 
                /**
-                * Callback for no results found context.
-                */
-               noresults: function () {
-                       this.$resultsView.lcd( 'noResults' );
-               },
-
-               /**
                 * Callback for results found context.
                 */
                success: function () {
@@ -255,7 +225,7 @@
                                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() ],
@@ -264,7 +234,8 @@
                                clickhandler: $.proxy( this.select, this ),
                                source: this.$languageFilter,
                                showRegions: this.options.showRegions,
-                               languageDecorator: 
this.options.languageDecorator
+                               languageDecorator: 
this.options.languageDecorator,
+                               noResultsTemplate: 
this.options.noResultsTemplate
                        } ).data( 'lcd' );
 
                        this.$languageFilter.languagefilter( {
@@ -274,7 +245,7 @@
                                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 +253,7 @@
 
                /**
                 * On select handler for search results
-                * @param langCode
+                * @param {string} langCode
                 */
                select: function ( langCode ) {
                        this.hide();
@@ -293,9 +264,10 @@
 
                /**
                 * 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;
                        }
 
@@ -347,7 +319,7 @@
 
                /**
                 * Get the panel menu width parameter
-                * @return string
+                * @return {string}
                 */
                getMenuWidth: function () {
                        var languagesCount;
@@ -356,7 +328,7 @@
                                return this.options.menuWidth;
                        }
 
-                       languagesCount = objectLength( this.options.languages );
+                       languagesCount = Object.keys( this.options.languages 
).length;
 
                        if ( languagesCount < 25 ) {
                                return 'narrow';
diff --git a/lib/jquery.uls/src/jquery.uls.data.utils.js 
b/lib/jquery.uls/src/jquery.uls.data.utils.js
index 440ddf6..4dcee07 100644
--- a/lib/jquery.uls/src/jquery.uls.data.utils.js
+++ b/lib/jquery.uls/src/jquery.uls.data.utils.js
@@ -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 ) );
diff --git a/lib/jquery.uls/src/jquery.uls.languagefilter.js 
b/lib/jquery.uls/src/jquery.uls.languagefilter.js
index a3c31ff..2f7d93f 100644
--- a/lib/jquery.uls/src/jquery.uls.languagefilter.js
+++ b/lib/jquery.uls/src/jquery.uls.languagefilter.js
@@ -27,13 +27,27 @@
 
        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();
@@ -72,58 +86,58 @@
                        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 ) {
+                                       if ( this.selectedLanguage ) {
                                        // this.selectLanguage will be 
populated from a matching search
-                                       this.options.onSelect( 
this.selectedLanguage );
-                               } else if ( this.options.languages[ query ] ) {
+                                               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();
+                                               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.$target.empty();
+                                                       languageFilter.search();
+                                               }
+                                       }, 300 );
+
+                                       this.toggleClear();
                        }
                },
 
@@ -213,7 +227,7 @@
                 * Handler method to be called once search is over.
                 * Based on search result triggers resultsfound or noresults 
events
                 * @param {string} query
-                * @param {number} resultCount
+                * @param {string[]} results
                 * @param {string} [autofillLabel]
                 */
                resultHandler: function ( query, results, autofillLabel ) {
@@ -284,7 +298,7 @@
                },
 
                escapeRegex: function ( value ) {
-                       return value.replace( /[\-\[\]{}()*+?.,\\\^$\|#\s]/g, 
'\\$&' );
+                       return value.replace( /[-[\]{}()*+?.,\\^$|#\s]/g, 
'\\$&' );
                },
 
                /**
@@ -294,6 +308,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.
@@ -343,16 +360,4 @@
 
        $.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 ) );
diff --git a/lib/jquery.uls/src/jquery.uls.lcd.js 
b/lib/jquery.uls/src/jquery.uls.lcd.js
index 2bba056..a447c03 100644
--- a/lib/jquery.uls/src/jquery.uls.lcd.js
+++ b/lib/jquery.uls/src/jquery.uls.lcd.js
@@ -22,30 +22,31 @@
 ( 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] Languages known to the ULS. 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 selectoin.
+        * @cfg {jQuery|Function} [noResultsTemplate]
+        */
+       function LanguageCategoryDisplay( element, options ) {
                this.$element = $( element );
                this.options = $.extend( {}, $.fn.lcd.defaults, options );
                this.$element.addClass( 'uls-lcd' );
@@ -53,12 +54,9 @@
                this.renderTimeout = null;
                this.cachedQuicklist = null;
 
-               this.$element.append( noResultsTemplate.clone() );
-               this.$noResults = this.$element.children( 
'.uls-no-results-view' );
-
                this.render();
                this.listen();
-       };
+       }
 
        LanguageCategoryDisplay.prototype = {
                constructor: LanguageCategoryDisplay,
@@ -147,7 +145,7 @@
 
                                $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 ) {
@@ -173,12 +171,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;
                                }
 
@@ -287,7 +285,6 @@
                        a.lang = code;
                        a.dir = $.uls.data.getDir( code );
 
-
                        li.appendChild( a );
                        if ( this.options.languageDecorator ) {
                                this.options.languageDecorator( $( a ), code );
@@ -303,7 +300,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 +325,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 +352,40 @@
                        }
                },
 
+               /**
+                * Called when a fresh search is started
+                */
                empty: function () {
-                       this.$element.find( '#uls-lcd-quicklist' ).addClass( 
'hide' );
+                       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 () {
@@ -417,8 +423,21 @@
                // Other values will have rendering issues.
                columns: 4,
                languageDecorator: null,
-               quickList: []
+               quickList: [],
+               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 ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/404234
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7341064cd0de367d933048c4800f951568747d11
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/UniversalLanguageSelector
Gerrit-Branch: master
Gerrit-Owner: Santhosh <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to