MediaWiki:Gadget-LanguageSelect.js/branch/nav-tab.js
Appearance
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/**
* to benefit of [[:Template:Multilingual description]]
*
* Implements language selection for multilingual elements
*
* WARNING: DON'T RELY ON COMMONS-STUFF. THIS SCRIPT IS FOREIGN-USED
* THE SCRIPT IS ALSO USED BY SOME GADGETS THAT LOAD CONTENT DYNAMICALLY
*
* In certain environments, it's not feasible to neatly box away each
* different language into its own section of the site. By marking elements
* multilingual, you can emulate this behavior by only displaying the
* message in the user's language. This reduces the "Tower of Babel" effect.
*
* @author Edward Z. Yang (Ambush Commander), Rewritten by DieBuche
*/
/*global mediaWiki:false, jQuery:false, wpAvailableLanguages:false*/
/*jshint curly:false*/
(function($, mw) {
'use strict';
var multilingual,
conf = mw.config.get([
'wgUserLanguage',
'wgNamespaceNumber',
'wgAction'
]);
multilingual = window.multilingual = {
/* Configuration: */
// the cookie name we use to stash the info.
cookie: 'commonswiki_language_js',
// link to the language select page
helpUrl: '//meta.wikimedia.org/wiki/Meta:Language_select',
// how many languages are required to collapse
langCountThreshold: 4,
// The element that's children should be checked
$p: $('#mw-content-text'),
// How to add the selector?
method: 'prepend',
// To which element should $container be added
$OuterContainer: $('.mw-body').first(),
// strings that are part of the widgets
stringHelp: {
'be-tarask': 'Выбар мовы',
'be-x-old': 'Выбар мовы',
'bn': 'ভাষা নির্বাচন',
'cs': 'Výběr jazyka:',
'da': 'Vælg sprog:',
'de': 'Sprachauswahl:',
'en': 'Language select:',
'et': 'Keelevalik:',
'eo': 'Lingvoelekto:',
'es': 'Seleccionar idioma:',
'fa': 'انتخاب زبان:',
'fr': 'Sélecteur de langue :',
'gl': 'Selección de lingua:',
'hu': 'Nyelvválasztás:',
'it': 'Seleziona lingua:',
'ko': '언어 선택:',
'mk': 'Јазик:',
'ml': 'ഭാഷ തിരഞ്ഞെടുക്കുക:',
'nds': 'Spraakutwahl:',
'nl': 'Taal:',
'pl': 'Wybierz język:',
'pt': 'Seleção do idioma:',
'pt-br': 'Seleção do idioma:',
'ru': 'Выбор языка:',
'sv': 'Välj språk:',
'tr': 'Dil seçimi:',
'zh-hans': '语言选择'
},
stringShowAll: {
'be-tarask': 'Паказаць усе',
'be-x-old': 'Паказаць усе',
'bn': 'সব দেখান',
'cs': 'Zobrazit všechny',
'da': 'Vis alle',
'de': 'Alle anzeigen',
'en': 'Show all',
'eo': 'ĉiuj',
'es': 'Mostrar todos',
'et': 'Näita kõiki',
'fa': 'نمایش همه',
'fr': 'Toutes les langues',
'gl': 'Mostrar todas',
'hu': 'Mutasd mind',
'it': 'Mostra tutte',
'ko': '모두 보기',
'mk': 'Сите',
'ml': 'എല്ലാം',
'nds': 'All wiesen',
'nl': 'Toon alles',
'pl': 'Pokaż wszystkie',
'pt': 'Mostrar todos',
'pt-br': 'Mostrar todos',
'ru': 'Показать все',
'sv': 'Visa alla',
'tr': 'Tümünü göster',
'zh-hans': '全部显示'
},
/* Code: */
// autodetects a browser language
getBrowserLanguage: function () {
return navigator.userLanguage || navigator.language || navigator.browserLanguage;
},
// sets a new language to the cookie
setCookieLanguage: function (language) {
$.cookie(this.cookie, language, {
expires: 100,
path: '/'
});
},
// deletes the cookie
deleteCookieLanguage: function (language) {
$.cookie(this.cookie, null, {
path: '/'
});
},
// grabs the ISO 639 language code based
// on either the browser or a supplied cookie
getLanguage: function () {
var language = '';
// Priority:
// 1. Cookie
// 2. wgUserLanguage global variable
// 3. Browser autodetection
// grab according to cookie
language = $.cookie(this.cookie);
// grab according to wgUserLanguage if user is logged in
if (!language && conf.wgUserLanguage && !mw.user.isAnon()) {
language = conf.wgUserLanguage;
}
// grab according to browser if none defined
if (!language) language = this.getBrowserLanguage();
// inflexible: can't accept multiple languages
// remove dialect/region code, leaving only the ISO 639 code
// language = language.replace(/(-.*)+/, '');
return language;
},
// build widget for changing the language cookie
buildWidget: function (language) {
this.$container = $('<div>')
.attr('id', 'langselectorcontainer')
// link to language select description page
.append(
$('<a>')
.attr('href', this.helpUrl)
.addClass('ls_link')
.text(this.stringHelpText)
)
// Space between <a> and <select>
.append(' ');
this.$select = $('<select>');
var seen = {};
this.mls.find('[lang]').each(function () {
var lang = $(this).attr('lang');
if (!seen[lang]) {
seen[lang] = true;
var verboseLang = lang;
if (window.wpAvailableLanguages) verboseLang = wpAvailableLanguages[lang] || lang;
multilingual.$select.append($('<option>').text(verboseLang).val(lang));
}
});
this.$select
.prepend($('<option value="showall"></option>').text(this.stringShowallText))
.attr('id', 'langselector')
.val(this.getLanguage())
.on('change', function () {
multilingual.setCookieLanguage($(this).val());
multilingual.apply($(this).val());
});
this.$container.append(this.$select);
// Finally insert the select using the specified method to the specified OuterContainer to the DOM-tree
this.$OuterContainer[this.method](this.$container);
},
// main body of the function
init: function () {
if (typeof ls_enable !== 'undefined') return;
// Disable the gadget on special pages
if (conf.wgNamespaceNumber < 0) return;
// Only activate on view, purge, historysubmit or submit actions
if (-1 === $.inArray(conf.wgAction, ['view', 'purge', 'edit', 'historysubmit', 'submit'])) return;
// Fire an event just before doing anything: This allows gadgets to first adjust the variables and then run it
$(document).triggerHandler('scriptLoaded', ['Multilingual description', multilingual]);
var language = this.getLanguage();
this.stringHelpText = (this.stringHelp[language] || this.stringHelp[conf.wgUserLanguage.split('-')[0]] || this.stringHelp.en);
this.stringShowallText = (this.stringShowAll[language] || this.stringShowAll[conf.wgUserLanguage.split('-')[0]] || this.stringShowAll.en);
// Find loose {{en|...}} and wrap them in a div.multilingual
// Select all blockelement.description[lang] which have at least one of their kind preceding them.
var blockElements = ['div', 'table'];
$.each(blockElements, function(i, tag) {
multilingual.$p.find(tag + '.description[lang]+' + tag + '.description[lang]').each(function () {
var $this = $(this);
// Already in a multiling, nothing to do here
if ($this.parent().hasClass('multilingual')) return;
var group = $(this).prevUntil(':not(' + tag + '.description[lang])')
.add($this)
.add($this.nextUntil(':not(' + tag + '.description[lang])'));
// Check how many associating language <blocks> exist
if (group.length < multilingual.langCountThreshold) {
return true;
}
group.wrapAll('<div class="multilingual"></div>');
});
});
// grab an array of multilingual elements
this.mls = multilingual.$p.find('.multilingual');
// Only build form if there are MLDs on page.
if (!this.mls.length) return;
this.buildWidget();
this.apply(this.getLanguage());
},
apply: function (language) {
// if language is blank, delete the cookie and then recalculate
if (!language) {
this.deleteCookieLanguage();
language = this.getLanguage();
}
this.mls.each(function () {
// Cache selector
var $ml = $(this);
if ($ml.parent('[class^="image_annotation_content"]').length) return true;
var id = $ml.attr('id');
if ($ml.hasClass('mw-body-content') || $.inArray(id, ['wikiPreview', 'LangTableLangs']) >= 0) return true;
var $reqLang = $ml.find('[lang="' + language + '"]');
if ($reqLang.length) {
$ml.children('[lang][lang!="' + language + '"]').hide();
$ml.children('[lang="' + language + '"]').show();
} else {
$ml.children('[lang]').show();
}
});
}
};
// Depends on 'site' (what we need for wpAvailableLanguages) and user (ls_enable variable)
// These dependencies must remain here because other wikis use the raw script
mw.loader.using(['jquery.cookie', 'mediawiki.user', 'mediawiki.util', 'site', 'user'], function () {
$(document).ready(function () {
var $fileContainer = $('#file');
if ($fileContainer.length) {
multilingual.method = 'append';
multilingual.$OuterContainer = $fileContainer;
}
multilingual.init();
});
});
})(jQuery, mediaWiki);