Introduce regionfilter
RegionFilter is a basic jquery plugin to work with ULS to select languages based on regions. PS2: Added a css class for elements with regionfilter. Used it for visual indication of selection. Plus some clean up. Change-Id: Ib01b4077435f98665075310e285e68f8538eeb4e
This commit is contained in:
@@ -59,7 +59,7 @@ class UniversalLanguageSelectorHooks {
|
|||||||
$languages = Language::fetchLanguageNames( $wgContLang->getCode() );
|
$languages = Language::fetchLanguageNames( $wgContLang->getCode() );
|
||||||
$languageData = htmlspecialchars( FormatJSON::encode( $languages ) );
|
$languageData = htmlspecialchars( FormatJSON::encode( $languages ) );
|
||||||
$data .= "
|
$data .= "
|
||||||
<div class=\"uls-menu\">
|
<div class=\"uls-menu\" data-languages=\"" . $languageData . "\">
|
||||||
<span class=\"icon-close\"></span>
|
<span class=\"icon-close\"></span>
|
||||||
<div class=\"uls-menu-header\">
|
<div class=\"uls-menu-header\">
|
||||||
<div class=\"uls-menu-header-left\">
|
<div class=\"uls-menu-header-left\">
|
||||||
@@ -67,13 +67,13 @@ class UniversalLanguageSelectorHooks {
|
|||||||
</div>
|
</div>
|
||||||
<div class=\"uls-menu-header-right\">
|
<div class=\"uls-menu-header-right\">
|
||||||
<div class='uls-worldmap'>
|
<div class='uls-worldmap'>
|
||||||
<div class='uls-region' id='uls-region-1'>
|
<div class='uls-region' id='uls-region-1' data-region='1'>
|
||||||
<a>North America<br>Latin America<br>South America</a>
|
<a>North America<br>Latin America<br>South America</a>
|
||||||
</div>
|
</div>
|
||||||
<div class='uls-region' id='uls-region-2'>
|
<div class='uls-region' id='uls-region-2' data-region='2'>
|
||||||
<a>Europe<br>Middle East<br>Africa</a>
|
<a>Europe<br>Middle East<br>Africa</a>
|
||||||
</div>
|
</div>
|
||||||
<div class='uls-region' id='uls-region-3'>
|
<div class='uls-region' id='uls-region-3' data-region='3'>
|
||||||
<a>Asia<br>Australia<br>Pacific</a>
|
<a>Asia<br>Australia<br>Pacific</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,7 +83,7 @@ class UniversalLanguageSelectorHooks {
|
|||||||
<div class=\"uls-lang-selector\">
|
<div class=\"uls-lang-selector\">
|
||||||
<form action=\"#\" class=\"filterform\">
|
<form action=\"#\" class=\"filterform\">
|
||||||
<input type=\"text\" placeholder=\"Language search\" id=\"languagefilter\"
|
<input type=\"text\" placeholder=\"Language search\" id=\"languagefilter\"
|
||||||
class=\"filterinput\" data-languages=\"" . $languageData . "\">
|
class=\"filterinput\">
|
||||||
<span class=\"search-button\"></span>
|
<span class=\"search-button\"></span>
|
||||||
</form>
|
</form>
|
||||||
<div class=\"uls-language-list\" >
|
<div class=\"uls-language-list\" >
|
||||||
|
|||||||
@@ -78,11 +78,9 @@
|
|||||||
|
|
||||||
.uls-region:hover {
|
.uls-region:hover {
|
||||||
outline: 1px solid #0E90D2;
|
outline: 1px solid #0E90D2;
|
||||||
background: black;
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.uls-region.active {
|
.regionselector.active {
|
||||||
background: black;
|
background: black;
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
(function ( $, mw ) {
|
(function ( $ ) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var ULS = function( element, options ) {
|
var ULS = function( element, options ) {
|
||||||
this.$element = $( element );
|
this.$element = $( element );
|
||||||
this.options = $.extend( {}, $.fn.uls.defaults, options );
|
this.options = $.extend( {}, $.fn.uls.defaults, options );
|
||||||
this.$menu = $( this.options.menu );
|
this.$menu = $( this.options.menu );
|
||||||
|
this.languages = this.$menu.data( 'languages' );
|
||||||
this.shown = false;
|
this.shown = false;
|
||||||
this.render();
|
this.render();
|
||||||
this.listen();
|
this.listen();
|
||||||
@@ -36,29 +37,36 @@
|
|||||||
render: function() {
|
render: function() {
|
||||||
// Rendering stuff here
|
// Rendering stuff here
|
||||||
},
|
},
|
||||||
listen: function() {
|
setLang: function( langCode ) {
|
||||||
// Register all event listeners to the ULS here.
|
|
||||||
this.$element.on( 'click', $.proxy( this.click, this ) );
|
|
||||||
$( ".icon-close" ).on( 'click', $.proxy( this.click, this ) );
|
|
||||||
$( "#languagefilter" ).languagefilter( {
|
|
||||||
$target: $( 'ul.uls-language-filter-result' ),
|
|
||||||
clickhandler: function( item ) {
|
|
||||||
// TODO: dependency on MediaWiki
|
// TODO: dependency on MediaWiki
|
||||||
var uri = new mw.Uri( window.location.href );
|
var uri = new mw.Uri( window.location.href );
|
||||||
uri.extend( { setlang: item.value } );
|
uri.extend( { setlang: langCode } );
|
||||||
window.location.href = uri.toString();
|
window.location.href = uri.toString();
|
||||||
}
|
},
|
||||||
|
listen: function() {
|
||||||
|
var that = this;
|
||||||
|
// Register all event listeners to the ULS here.
|
||||||
|
that.$element.on( 'click', $.proxy( that.click, that ) );
|
||||||
|
$( ".icon-close" ).on( 'click', $.proxy( that.click, that ) );
|
||||||
|
$( "#languagefilter" ).languagefilter( {
|
||||||
|
$target: $( 'ul.uls-language-filter-result' ),
|
||||||
|
clickhandler: function( langCode ) {
|
||||||
|
that.setLang( langCode );
|
||||||
|
},
|
||||||
|
languages: that.languages
|
||||||
} );
|
} );
|
||||||
$( '.uls-region' ).live( 'click', function ( e ) {
|
// Create region selectors, one per region
|
||||||
var id = $( this ).attr( 'id' );
|
$( '.uls-region' ).regionselector( {
|
||||||
var active = $( this ).hasClass( 'active' );
|
$target: $( 'ul.uls-language-filter-result' ),
|
||||||
$( this ).parent().find( '.uls-region' ).removeClass( 'active' );
|
clickhandler: function( langCode ) {
|
||||||
if ( active ) {
|
that.setLang( langCode );
|
||||||
$( '.uls-language-list li' ).show();
|
},
|
||||||
} else {
|
//FIXME This is confusing: languages and source are acturally data for ULS.
|
||||||
$( this ).addClass( 'active' );
|
languages: that.languages,
|
||||||
$( '.uls-language-list li' ).not( '.' + id ).hide();
|
source: langdb,
|
||||||
$( '.uls-language-list li.' + id ).show();
|
callback: function () {
|
||||||
|
// clear the search field.
|
||||||
|
$( "#languagefilter" ).val( "" );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
// trigger a search for all languages.
|
// trigger a search for all languages.
|
||||||
@@ -97,7 +105,8 @@
|
|||||||
} else {
|
} else {
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ULS PLUGIN DEFINITION
|
/* ULS PLUGIN DEFINITION
|
||||||
@@ -121,4 +130,4 @@
|
|||||||
|
|
||||||
$.fn.uls.Constructor = ULS;
|
$.fn.uls.Constructor = ULS;
|
||||||
|
|
||||||
} )( jQuery, mediaWiki );
|
} )( jQuery );
|
||||||
|
|||||||
@@ -6,18 +6,14 @@
|
|||||||
* the data is in the format of languagecode:languagename format.
|
* the data is in the format of languagecode:languagename format.
|
||||||
* Credits: http://jqueryui.com/demos/autocomplete
|
* Credits: http://jqueryui.com/demos/autocomplete
|
||||||
*/
|
*/
|
||||||
jQuery( function( $ ) {
|
(function ( $ ) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
$.widget( "ui.languagefilter", {
|
var LanguageFilter = {
|
||||||
options: {
|
|
||||||
$target: null, // where to append the results
|
|
||||||
languages: null, // languages as code:name format. default values is from data-languages
|
|
||||||
clickhandler: null
|
|
||||||
},
|
|
||||||
_create: function() {
|
_create: function() {
|
||||||
var self = this.element,
|
var that = this;
|
||||||
options = this.options;
|
var self = that.element,
|
||||||
|
options = that.options;
|
||||||
$( self ).autocomplete( {
|
$( self ).autocomplete( {
|
||||||
delay: 0,
|
delay: 0,
|
||||||
minLength: 0,
|
minLength: 0,
|
||||||
@@ -26,7 +22,6 @@ jQuery( function( $ ) {
|
|||||||
position: { offset: "-10000 -10000" },
|
position: { offset: "-10000 -10000" },
|
||||||
source: function( request, response ) {
|
source: function( request, response ) {
|
||||||
var term = request.term;
|
var term = request.term;
|
||||||
var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), 'i' );
|
|
||||||
var languages = options.languages;
|
var languages = options.languages;
|
||||||
|
|
||||||
if ( languages === null ) {
|
if ( languages === null ) {
|
||||||
@@ -38,7 +33,7 @@ jQuery( function( $ ) {
|
|||||||
if ( term === "" ) {
|
if ( term === "" ) {
|
||||||
return { label: name, value: code };
|
return { label: name, value: code };
|
||||||
}
|
}
|
||||||
if ( matcher.test( name ) ) {
|
if ( that.filter.call( this, name, term ) ) {
|
||||||
return {
|
return {
|
||||||
label: name.replace(
|
label: name.replace(
|
||||||
new RegExp(
|
new RegExp(
|
||||||
@@ -59,45 +54,140 @@ jQuery( function( $ ) {
|
|||||||
} ); // /autocomplete
|
} ); // /autocomplete
|
||||||
|
|
||||||
$( self ).data( "autocomplete" )._renderItem = function ( $target, item ) {
|
$( self ).data( "autocomplete" )._renderItem = function ( $target, item ) {
|
||||||
var activeregion, classes, region, i, regionlist;
|
|
||||||
|
|
||||||
$target = options.$target;
|
$target = options.$target;
|
||||||
if ( !$target ) {
|
if ( !$target ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regionlist = langdb.languages[item.value] || ["unknown", ["unknown"]];
|
|
||||||
regionlist = regionlist[1];
|
|
||||||
for ( i = 0; i < regionlist.length; i++ ) {
|
|
||||||
region = langdb.regiongroups[regionlist[i]]
|
|
||||||
if ( region ) {
|
|
||||||
classes = classes + " uls-region-" + region;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var $li = $( "<li>" )
|
var $li = $( "<li>" )
|
||||||
.data( "code", item.value )
|
.data( "code", item.value )
|
||||||
.addClass( classes )
|
|
||||||
.data( "item.autocomplete", item )
|
.data( "item.autocomplete", item )
|
||||||
.append( $( "<a>" ).prop( 'href', '#' ). html( item.label ) )
|
.append( $( "<a>" ).prop( 'href', '#' ). html( item.label ) )
|
||||||
.appendTo( $target );
|
.appendTo( $target );
|
||||||
|
|
||||||
activeregion = $( '.uls-region.active' ).attr( 'id' );
|
|
||||||
if ( activeregion && !$li.hasClass( activeregion ) ) {
|
|
||||||
$li.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( options.clickhandler ) {
|
if ( options.clickhandler ) {
|
||||||
$li.click( function() {
|
$li.click( function() {
|
||||||
options.clickhandler.call( this, item );
|
options.clickhandler.call( this, item.value );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
return $li;
|
return $li;
|
||||||
|
|
||||||
};
|
};
|
||||||
}, // End of _create
|
}, // End of _create
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
$.Widget.prototype.destroy.call( this );
|
$.Widget.prototype.destroy.call( this );
|
||||||
|
},
|
||||||
|
|
||||||
|
filter: function( langName, searchTerm ) {
|
||||||
|
var matcher = new RegExp( $.ui.autocomplete.escapeRegex( searchTerm ), 'i' );
|
||||||
|
return matcher.test( langName );
|
||||||
|
},
|
||||||
|
|
||||||
|
options: {
|
||||||
|
$target: null, // where to append the results
|
||||||
|
languages: null, // languages as code:name format. default values is from data-languages
|
||||||
|
clickhandler: null,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.widget( "ui.languagefilter", LanguageFilter );
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Region selector is a language selector based on regions.
|
||||||
|
* Usage: $( 'jqueryselector' ).regionselector(options);
|
||||||
|
* The attached element should have data-region attribute
|
||||||
|
* that defines the region for the selector.
|
||||||
|
*/
|
||||||
|
var RegionSelector = function( element, options ) {
|
||||||
|
this.$element = $( element );
|
||||||
|
this.options = $.extend( {}, $.fn.regionselector.defaults, options );
|
||||||
|
this.$element.addClass( 'regionselector' );
|
||||||
|
this.listen();
|
||||||
|
this.region = this.$element.data( 'region' );
|
||||||
|
};
|
||||||
|
|
||||||
|
RegionSelector.prototype = {
|
||||||
|
constructor: RegionSelector,
|
||||||
|
test: function( langCode ) {
|
||||||
|
var that = this;
|
||||||
|
var languages = that.options.source.languages;
|
||||||
|
var regionGroups = that.options.source.regiongroups;
|
||||||
|
var regions = languages[langCode][1];
|
||||||
|
// 1. loop over all regions - like {EU: 2, AF: 2, AS: 3 ...}
|
||||||
|
// 2. check that the region matches the active region group
|
||||||
|
// 3. if this language is included in that region, show it
|
||||||
|
// 4. if none of the conditions match, the language is not shown
|
||||||
|
$.each( regionGroups, function( regionGroup, groupId ) {
|
||||||
|
if ( groupId === that.region && $.inArray( regionGroup, regions ) >= 0 ) {
|
||||||
|
that.render( langCode );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
show: function() {
|
||||||
|
var that = this;
|
||||||
|
var languages = that.options.source.languages;
|
||||||
|
// Make the selected region (and it only) active
|
||||||
|
$( '.regionselector' ).removeClass( 'active' );
|
||||||
|
that.$element.addClass( 'active' );
|
||||||
|
// Repopulate the list of languages
|
||||||
|
that.options.$target.empty();
|
||||||
|
$.each( languages, function( langCode, langDef ) {
|
||||||
|
that.test( langCode );
|
||||||
} );
|
} );
|
||||||
|
if ( that.options.callback ) {
|
||||||
|
that.options.callback.call();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render: function( langCode ) {
|
||||||
|
var that = this;
|
||||||
|
var langName = that.options.languages[langCode] || langCode;
|
||||||
|
var $li = $( "<li>" )
|
||||||
|
.data( "code", langCode )
|
||||||
|
.append( $( "<a>" ).prop( 'href', '#' ).html( langName ) )
|
||||||
|
.appendTo( this.options.$target );
|
||||||
|
|
||||||
|
if ( that.options.clickhandler ) {
|
||||||
|
$li.click( function() {
|
||||||
|
that.options.clickhandler.call( this, langCode );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
listen: function(){
|
||||||
|
this.$element.on( 'click', $.proxy( this.click, this ) );
|
||||||
|
},
|
||||||
|
click: function( e ) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/* RegionSelector Plugin Definition */
|
||||||
|
|
||||||
|
$.fn.regionselector = function( option ) {
|
||||||
|
return this.each( function() {
|
||||||
|
var $this = $( this ),
|
||||||
|
data = $this.data( 'regionselector' ),
|
||||||
|
options = typeof option == 'object' && option;
|
||||||
|
if ( !data ) {
|
||||||
|
$this.data( 'regionselector', ( data = new RegionSelector( this, options ) ) );
|
||||||
|
}
|
||||||
|
if ( typeof option === 'string' ) {
|
||||||
|
data[option]();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.regionselector.defaults = {
|
||||||
|
$target: null, // Where to render the results. Must be a ul element
|
||||||
|
clickhandler: null, // Click handler to handle click events on results
|
||||||
|
source: null, // The language database
|
||||||
|
languages:null, // Language names for the current UI language
|
||||||
|
callback: null // Callback - will be called after results are displayed.
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.regionselector.Constructor = RegionSelector;
|
||||||
|
|
||||||
|
|
||||||
|
} )( jQuery );
|
||||||
Reference in New Issue
Block a user