Difference between revisions of "MediaWiki:Common.js"

From FloraWiki - das Wiki zur Schweizer Flora
Jump to: navigation, search
m
m (ESlint fix: single quotes for string)
Line 12: Line 12:
  
 
/* should go into mw.config: wgPageName, wgServer, wgScript, wgAction, wgCanonicalNamespace */
 
/* should go into mw.config: wgPageName, wgServer, wgScript, wgAction, wgCanonicalNamespace */
"use strict"; // set ECMAScript 5 Strict Mode
+
'use strict'; // set ECMAScript 5 Strict Mode
  
 
/**
 
/**
Line 20: Line 20:
 
  */
 
  */
 
$.jqueryEscapeId = function (myid) {
 
$.jqueryEscapeId = function (myid) {
   if(myid.substr(0, 1) === "#"){
+
   if(myid.substr(0, 1) === '#'){
 
     return myid.replace(/(:|\.)/g,'\\$1');
 
     return myid.replace(/(:|\.)/g,'\\$1');
 
   } else {
 
   } else {
Line 41: Line 41:
 
$.jI18n = {
 
$.jI18n = {
 
   en: {
 
   en: {
     ClueTip_newWindow :              "(New Window …)",
+
     ClueTip_newWindow :              '(New Window …)',
     ClueTip_toolTipClose  :          "Click to close",
+
     ClueTip_toolTipClose  :          'Click to close',
     ClueTip_toolTipNewWindow :      "(click to open content in a new window or tab)",
+
     ClueTip_toolTipNewWindow :      '(click to open content in a new window or tab)',
     ClueTip_toolTipNoContentLoadable:"<i>No content could be loaded</i>",
+
     ClueTip_toolTipNoContentLoadable:'<i>No content could be loaded</i>',
     CollapseBox_captionCollapse :        "&nbsp;(show less)&nbsp;",
+
     CollapseBox_captionCollapse :        '&nbsp;(show less)&nbsp;',
     CollapseBox_captionExpand :          "&nbsp;(more...)&nbsp;",
+
     CollapseBox_captionExpand :          '&nbsp;(more...)&nbsp;',
     CollapseBox_toolTipCollapse :        "(click to hide information below)",
+
     CollapseBox_toolTipCollapse :        '(click to hide information below)',
     CollapseBox_toolTipExpand :          "(click to show more information below)",
+
     CollapseBox_toolTipExpand :          '(click to show more information below)',
 
     // see MediaWiki:jKey.js
 
     // see MediaWiki:jKey.js
     jKey_expandAll :              "Show all extras",
+
     jKey_expandAll :              'Show all extras',
     jKey_iconOverview  :          "http://upload.wikimedia.org/wikipedia/commons/thumb/2/22/View-pause_Gion_simple.svg/20px-View-pause_Gion_simple.svg.png",
+
     jKey_iconOverview  :          'http://upload.wikimedia.org/wikipedia/commons/thumb/2/22/View-pause_Gion_simple.svg/20px-View-pause_Gion_simple.svg.png',
     jKey_iconResume  :            "http://upload.wikimedia.org/wikipedia/commons/thumb/4/49/View-playback_Gion_simple.svg/20px-View-playback_Gion_simple.svg.png",
+
     jKey_iconResume  :            'http://upload.wikimedia.org/wikipedia/commons/thumb/4/49/View-playback_Gion_simple.svg/20px-View-playback_Gion_simple.svg.png',
     jKey_iconStart1st  :          "http://upload.wikimedia.org/wikipedia/commons/thumb/4/49/View-playback_Gion_simple.svg/20px-View-playback_Gion_simple.svg.png",
+
     jKey_iconStart1st  :          'http://upload.wikimedia.org/wikipedia/commons/thumb/4/49/View-playback_Gion_simple.svg/20px-View-playback_Gion_simple.svg.png',
     jKey_iconStartNew  :          "http://upload.wikimedia.org/wikipedia/commons/thumb/0/05/View-refresh_Gion_simple.svg/20px-View-refresh_Gion_simple.svg.png"
+
     jKey_iconStartNew  :          'http://upload.wikimedia.org/wikipedia/commons/thumb/0/05/View-refresh_Gion_simple.svg/20px-View-refresh_Gion_simple.svg.png'
 
   },
 
   },
 
   de: {
 
   de: {
     ClueTip_newWindow :              "(Neues Fenster …)",
+
     ClueTip_newWindow :              '(Neues Fenster …)',
     ClueTip_toolTipClose  :          "Zum Schließen klicken",
+
     ClueTip_toolTipClose  :          'Zum Schließen klicken',
     ClueTip_toolTipNewWindow :      "(klicken um Inhalt in neuem Fenster oder Reiter zu öffnen)",
+
     ClueTip_toolTipNewWindow :      '(klicken um Inhalt in neuem Fenster oder Reiter zu öffnen)',
     ClueTip_toolTipNoContentLoadable:"<i>Leider konnte der Inhalt nicht geladen werden.</i>",
+
     ClueTip_toolTipNoContentLoadable:'<i>Leider konnte der Inhalt nicht geladen werden.</i>',
     CollapseBox_captionCollapse :        "&nbsp;(weniger anzeigen)&nbsp;",
+
     CollapseBox_captionCollapse :        '&nbsp;(weniger anzeigen)&nbsp;',
     CollapseBox_captionExpand :          "&nbsp;(mehr...)&nbsp;",
+
     CollapseBox_captionExpand :          '&nbsp;(mehr...)&nbsp;',
     CollapseBox_toolTipCollapse :        "(klicken um Zusatzinformationen zu verbergen)",
+
     CollapseBox_toolTipCollapse :        '(klicken um Zusatzinformationen zu verbergen)',
     CollapseBox_toolTipExpand :          "(klicken um Zusatzinformationen anzuzeigen)",
+
     CollapseBox_toolTipExpand :          '(klicken um Zusatzinformationen anzuzeigen)',
     jKey_expandAll :              "Alle Zusatzinformationen zeigen"
+
     jKey_expandAll :              'Alle Zusatzinformationen zeigen'
 
   },
 
   },
 
   fr: {
 
   fr: {
     ClueTip_newWindow :              "(Nouvelle fenêtre …)",
+
     ClueTip_newWindow :              '(Nouvelle fenêtre …)',
     ClueTip_toolTipClose  :          "Cliquez pour fermer",
+
     ClueTip_toolTipClose  :          'Cliquez pour fermer',
     ClueTip_toolTipNewWindow :      "(Cliquez pour ouvrir le contenu dans une nouvelle fenêtre ou onglet)",
+
     ClueTip_toolTipNewWindow :      '(Cliquez pour ouvrir le contenu dans une nouvelle fenêtre ou onglet)',
     ClueTip_toolTipNoContentLoadable:"<i>Malheureusement, le Contenu n'est pas chargé.</i>",
+
     ClueTip_toolTipNoContentLoadable:'<i>Malheureusement, le Contenu n’est pas chargé.</i>',
     CollapseBox_captionCollapse :        "&nbsp;(afficher moins)&nbsp;",
+
     CollapseBox_captionCollapse :        '&nbsp;(afficher moins)&nbsp;',
     CollapseBox_captionExpand :          "&nbsp;(plus...)&nbsp;",
+
     CollapseBox_captionExpand :          '&nbsp;(plus...)&nbsp;',
     CollapseBox_toolTipCollapse :        "(cliquez pour masquer les informations ci-dessous)",
+
     CollapseBox_toolTipCollapse :        '(cliquez pour masquer les informations ci-dessous)',
     CollapseBox_toolTipExpand :          "(cliquez pour afficher plus d’informations ci-dessous)",
+
     CollapseBox_toolTipExpand :          '(cliquez pour afficher plus d’informations ci-dessous)',
 
     // see MediaWiki:jKey.js
 
     // see MediaWiki:jKey.js
     jKey_expandAll :              "afficher toutes les informations supplémentaires"
+
     jKey_expandAll :              'afficher toutes les informations supplémentaires'
 
   },
 
   },
 
   it: {
 
   it: {
     ClueTip_toolTipClose  :          "Clicca per chiudere",
+
     ClueTip_toolTipClose  :          'Clicca per chiudere',
     CollapseBox_captionCollapse :        "&nbsp;(mostra di meno)&nbsp;",
+
     CollapseBox_captionCollapse :        '&nbsp;(mostra di meno)&nbsp;',
     CollapseBox_captionExpand :          "&nbsp;(più...)&nbsp;",
+
     CollapseBox_captionExpand :          '&nbsp;(più...)&nbsp;',
     jKey_expandAll :              "Mostra tutti informazione" //REVISE
+
     jKey_expandAll :              'Mostra tutti informazione' //REVISE
 
   }
 
   }
 
};
 
};
Line 90: Line 90:
 
/**
 
/**
 
  * @description Get resource string (text, image URLs) for a given language, based on a string-key
 
  * @description Get resource string (text, image URLs) for a given language, based on a string-key
  *  If no resource is defined in a given language for a resource key, the resource for "en" will be returned,
+
  *  If no resource is defined in a given language for a resource key, the resource for 'en' will be returned,
 
  *  if this is missing as well an error message.
 
  *  if this is missing as well an error message.
 
  * @augments $
 
  * @augments $
Line 98: Line 98:
 
  */
 
  */
 
$.resource = function (resourceKey) {
 
$.resource = function (resourceKey) {
     var lang = mw.config.get('wgUserLanguage').split("-")[0]; // language: "pt-BR", "de-formal", etc.
+
     var lang = mw.config.get('wgUserLanguage').split('-')[0]; // language: 'pt-BR', 'de-formal', etc.
 
     return ($.jI18n[lang] && $.jI18n[lang][resourceKey] ?
 
     return ($.jI18n[lang] && $.jI18n[lang][resourceKey] ?
 
       $.jI18n[lang][resourceKey] :
 
       $.jI18n[lang][resourceKey] :
       ($.jI18n.en[resourceKey]) ? $.jI18n.en[resourceKey] : "MISSING RESOURCE: no $.jI18n.en." + resourceKey + " defined.");
+
       ($.jI18n.en[resourceKey]) ? $.jI18n.en[resourceKey] : 'MISSING RESOURCE: no $.jI18n.en.' + resourceKey + ' defined.');
 
  };
 
  };
 
/**
 
/**
Line 113: Line 113:
 
  */
 
  */
 
$.linkBuilder = function (txtResourceKey, txtContent, href, attributes) {
 
$.linkBuilder = function (txtResourceKey, txtContent, href, attributes) {
   return (txtResourceKey.length ? "<a "
+
   return (txtResourceKey.length ? '<a '
     + " href='" + href + "' "
+
     + ' href="' + href + '" '
     + " " + (attributes.length ? attributes : "") + ">"
+
     + ' ' + (attributes.length ? attributes : '') + '>'
 
     + $.resource(txtResourceKey)
 
     + $.resource(txtResourceKey)
     + "</a>" : (txtContent.length ? "<a "
+
     + '</a>' : (txtContent.length ? '<a '
       + " href='" + href + "' "
+
       + ' href="' + href + '" '
       + " " + (attributes.length ? attributes : "") + ">"
+
       + ' ' + (attributes.length ? attributes : '') + '>'
 
       + txtContent +
 
       + txtContent +
       "</a>" : "")
+
       '</a>' : '')
 
   );
 
   );
 
};
 
};
Line 133: Line 133:
 
  */
 
  */
 
$.imglinkBuilder = function (imgResourceKey, txtResourceKey, attributes) {
 
$.imglinkBuilder = function (imgResourceKey, txtResourceKey, attributes) {
   return (imgResourceKey.length ? "<a "
+
   return (imgResourceKey.length ? '<a '
     + " href='#'" + (attributes.length ? " " + attributes : "") + "><img src='" + $.resource(imgResourceKey) + "' /></a>&nbsp;" : "")
+
     + ' href="#" ' + (attributes.length ? ' ' + attributes : '') + '><img src="' + $.resource(imgResourceKey) + '" /></a>&nbsp;' : '')
     + $.linkBuilder(txtResourceKey, null, "#", attributes);
+
     + $.linkBuilder(txtResourceKey, null, '#', attributes);
 
};
 
};
 
/**
 
/**
Line 155: Line 155:
 
  * $('.decisiontree').each (function (i, element) { $(element).find('.mw-customtoggle.is-collapsed').trigger('click') });
 
  * $('.decisiontree').each (function (i, element) { $(element).find('.mw-customtoggle.is-collapsed').trigger('click') });
 
  * $('.decisiontree').each (function (i, element) { $(element).find('.mw-customtoggle').not('.is-collapsed').trigger('click') });
 
  * $('.decisiontree').each (function (i, element) { $(element).find('.mw-customtoggle').not('.is-collapsed').trigger('click') });
 +
* @requires MediaWiki:Mw-customcollapsible.js
 
  * @requires MediaWiki:JKey.js
 
  * @requires MediaWiki:JKey.js
 
  * @param {boolean} shallExpandThisKey
 
  * @param {boolean} shallExpandThisKey
Line 161: Line 162:
 
  */
 
  */
 
$.toggleAllCollapsible = function (shallExpandThisKey, caller) {
 
$.toggleAllCollapsible = function (shallExpandThisKey, caller) {
   var $decisionTree = $(caller).closest(".decisiontree");
+
   var $decisionTree = $(caller).closest('.decisiontree');
 
   // debug log messages
 
   // debug log messages
 
   if ($decisionTree.length) {
 
   if ($decisionTree.length) {
Line 177: Line 178:
 
};// $.toggleAllCollapsible()
 
};// $.toggleAllCollapsible()
  
 +
/**
 +
*
 +
* @requires MediaWiki:Mw-customcollapsible.js
 +
* @requires MediaWiki:JKey.js
 +
* @returns {undefined}
 +
*/
 
window.expandToggleAllExtras = function () {
 
window.expandToggleAllExtras = function () {
 
   $('div.decisiontree input.toggleAllExtras').each(function (i, element){
 
   $('div.decisiontree input.toggleAllExtras').each(function (i, element){
Line 182: Line 189:
 
     $(element)
 
     $(element)
 
       .prop( 'checked' , true);
 
       .prop( 'checked' , true);
     console.log("DEBUG jkey:initialized expandToggleAllExtras done");
+
     console.log('DEBUG jkey:initialized expandToggleAllExtras done');
 
     console.log(element);
 
     console.log(element);
 
   });
 
   });
Line 201: Line 208:
 
                     └ div.switcher
 
                     └ div.switcher
 
                     └ div.collapsecontent */
 
                     └ div.collapsecontent */
   var hasSwitcher = $("div.switcher .show, div.switcher .hide");
+
   var hasSwitcher = $('div.switcher .show, div.switcher .hide');
 
   if(hasSwitcher.length){
 
   if(hasSwitcher.length){
 
     $.each(hasSwitcher, function(index){// add tooltip
 
     $.each(hasSwitcher, function(index){// add tooltip
       hasSwitcher[index].title = hasSwitcher[index].className === "show"? $.resource("CollapseBox_toolTipExpand") : $.resource("CollapseBox_toolTipCollapse");
+
       hasSwitcher[index].title = hasSwitcher[index].className === 'show'? $.resource('CollapseBox_toolTipExpand') : $.resource('CollapseBox_toolTipCollapse');
 
     });
 
     });
     $("div.collapsebox div.switcher").on('click',
+
     $('div.collapsebox div.switcher').on('click',
 
       function() {
 
       function() {
         $(this).nextAll("div.collapsecontent:first").slideToggle(250);
+
         $(this).nextAll('div.collapsecontent:first').slideToggle(250);
 
         /* $(this).toggle() does not work in live as toggle is a bind()
 
         /* $(this).toggle() does not work in live as toggle is a bind()
 
             therefore toggle must be bound to a different DOM element */
 
             therefore toggle must be bound to a different DOM element */
         $(this).find(".show, .hide").toggle();
+
         $(this).find('.show, .hide').toggle();
 
       });
 
       });
 
     /* is in a table: tr.collapsebox
 
     /* is in a table: tr.collapsebox
 
                         └ div.switcher
 
                         └ div.switcher
 
                       tr.collapsecontent */
 
                       tr.collapsecontent */
     $("tr.collapsebox div.switcher").on('click',
+
     $('tr.collapsebox div.switcher').on('click',
 
       function() {
 
       function() {
         $(this).closest("tr.collapsebox").nextAll("tr.collapsecontent:first").toggle();
+
         $(this).closest('tr.collapsebox').nextAll('tr.collapsecontent:first').toggle();
         $(this).find(".show, .hide").toggle();
+
         $(this).find('.show, .hide').toggle();
 
       });
 
       });
 
     // TODO is a better generic check possible?
 
     // TODO is a better generic check possible?
     if (mw.config.get('wgPageName') === "Spezial:Suche") {
+
     if (mw.config.get('wgPageName') === 'Spezial:Suche') {
       if (!$(".mw-search-results").length) {
+
       if (!$('.mw-search-results').length) {
 
         // open box with additional search possibilities
 
         // open box with additional search possibilities
         $(".switcher .show").trigger('click');
+
         $('.switcher .show').trigger('click');
 
       }
 
       }
 
     }
 
     }
Line 287: Line 294:
 
  */
 
  */
 
$.prepareSpecialContact4Info = function () {
 
$.prepareSpecialContact4Info = function () {
   var placeholderMessage = "", warningMessageDoesNotWork = "";
+
   var placeholderMessage = '', warningMessageDoesNotWork = '';
 
   switch (mw.config.get( 'wgCanonicalSpecialPageName' )) {
 
   switch (mw.config.get( 'wgCanonicalSpecialPageName' )) {
     case "Contact": // is a Special:Contact page regardless of language
+
     case 'Contact': // is a Special:Contact page regardless of language
 
       switch (mw.config.get('wgPageName')) {
 
       switch (mw.config.get('wgPageName')) {
         case "Special:Contact":
+
         case 'Special:Contact':
         case "Spécial:Contact":
+
         case 'Spécial:Contact':
 
           placeholderMessage = 'Leave it empty or add e-mail in message (mfn-berlin.de works only)';
 
           placeholderMessage = 'Leave it empty or add e-mail in message (mfn-berlin.de works only)';
 
           warningMessageDoesNotWork = 'Only mfn-berlin.de addresses do work. Leave it empty please and add your address in the message. Thank you.';
 
           warningMessageDoesNotWork = 'Only mfn-berlin.de addresses do work. Leave it empty please and add your address in the message. Thank you.';
 
           break;
 
           break;
         case "Spezial:Kontakt":
+
         case 'Spezial:Kontakt':
 
           placeholderMessage = 'E-Mail in Nachricht dazu oder leer lassen (nur mfn-berlin.de geht)';
 
           placeholderMessage = 'E-Mail in Nachricht dazu oder leer lassen (nur mfn-berlin.de geht)';
 
           warningMessageDoesNotWork = 'Nur mfn-berlin.de Adressen können verarbeitet werden. Bitte leer lassen oder E-Mail im Text angeben. Danke.';
 
           warningMessageDoesNotWork = 'Nur mfn-berlin.de Adressen können verarbeitet werden. Bitte leer lassen oder E-Mail im Text angeben. Danke.';
Line 329: Line 336:
  
  
if (mw.config.get('wgAction') == "edit" || mw.config.get('wgAction') == "submit" ) {
+
if (mw.config.get('wgAction') === 'edit'
 +
  || mw.config.get('wgAction') === 'submit' ) {
 
     mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKeyWikiEditorHelp.js&action=raw&ctype=text/javascript' );; // load help for the wikiEditor
 
     mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKeyWikiEditorHelp.js&action=raw&ctype=text/javascript' );; // load help for the wikiEditor
 
     mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:WikiEditor-insert-Zitat.js&action=raw&ctype=text/javascript' );;// Wizard to insert template:Zitat
 
     mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:WikiEditor-insert-Zitat.js&action=raw&ctype=text/javascript' );;// Wizard to insert template:Zitat
Line 345: Line 353:
 
// Page-specific scripts:
 
// Page-specific scripts:
 
switch (mw.config.get( 'wgPageName' )) { // Minimize the pages on which the code will be loaded
 
switch (mw.config.get( 'wgPageName' )) { // Minimize the pages on which the code will be loaded
   case "Hilfe:Konvertierung_geschachtelt-eingerückter_Schlüssel_in_das_ON-Format":
+
   case 'Hilfe:Konvertierung_geschachtelt-eingerückter_Schlüssel_in_das_ON-Format':
 
     mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKeyTextToLeadTemplateTool.js&action=raw&ctype=text/javascript' );;
 
     mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKeyTextToLeadTemplateTool.js&action=raw&ctype=text/javascript' );;
 
     break;
 
     break;
Line 351: Line 359:
  
 
jQuery(document).ready(function($) {
 
jQuery(document).ready(function($) {
   if(mw.config.get( 'wgAction' )==="view") {
+
   if(mw.config.get( 'wgAction' )==='view') {
     if($(".decisiontree").length != 0) {
+
     if($('.decisiontree').length !== 0) {
 
       mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKeyRenderLanguageTaggedText2wgUserLanguage.js&action=raw&ctype=text/javascript' );;
 
       mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKeyRenderLanguageTaggedText2wgUserLanguage.js&action=raw&ctype=text/javascript' );;
 
     }
 
     }
 
   }
 
   }
   if(mw.config.get( 'wgAction' )==="edit"
+
   if(mw.config.get( 'wgAction' )==='edit'
     || mw.config.get( 'wgAction' )==="view"
+
     || mw.config.get( 'wgAction' )==='view'
     /* || mw.config.get( 'wgAction' )==="submit" does not work somehow in MW. 1.20.7 */
+
     /* || mw.config.get( 'wgAction' )==='submit' does not work somehow in MW. 1.20.7 */
 
   ){
 
   ){
 
     init_character_ui_tabs();
 
     init_character_ui_tabs();
Line 364: Line 372:
 
   $.initCollapsebox(); //collapsible parts
 
   $.initCollapsebox(); //collapsible parts
 
   $.prepareSpecialContact4Info();
 
   $.prepareSpecialContact4Info();
  expandToggleAllExtras();
 
 
}); // end jQuery(document).ready()
 
}); // end jQuery(document).ready()

Revision as of 14:10, 24 August 2017

/*global jQuery, $, document, screen, window, location, navigator, unescape, Image, clearTimeout, addOnloadHook, importScript, setTimeout, appendCSS, mw, mw.config, mw.config.get */

/*
 * TODO cluetip plugin
 * @requires: MediaWiki:JKey.js
 * @requires: MediaWiki:JKeyWikiEditorHelp.js
 * @requires: MediaWiki:JKeyRenderLanguageTaggedText2wgUserLanguage.js
 * @requires: MediaWiki:JKeyTextToLeadTemplateTool.js
 * @requires: MediaWiki:Mw-customcollapsible.js
 * @requires: MediaWiki:Ui-custom-show-on-select.js
*/

/* should go into mw.config: wgPageName, wgServer, wgScript, wgAction, wgCanonicalNamespace */
'use strict'; // set ECMAScript 5 Strict Mode

/**
 * @description: helper function to escape jQuery IDs
 * @param {string} myid HTML ID
 * @returns {string}
 */
$.jqueryEscapeId = function (myid) {
  if(myid.substr(0, 1) === '#'){
    return myid.replace(/(:|\.)/g,'\\$1');
  } else {
    return '#' + myid.replace(/(:|\.)/g,'\\$1');
  }
};

/**
 * @namespace resource string dictionary
 *
 * Note: Commons uses collapse/expand ▲/▼, but this looks better in strict box
 * layouts that in the free-wrapping key statements
 *
 * Nomenclature proposal: if an extra plugin is used, strings can be designated as
 * “plugin_toolTipSomthing” otherwise just “toolTipSomthing” (global string). So it’s more clear if
 * somebody wants to deactivate a plugin and remove strings from the resource dictionary.
 * @augments $
 * @type object
 */
$.jI18n = {
  en: {
    ClueTip_newWindow :              '(New Window …)',
    ClueTip_toolTipClose  :          'Click to close',
    ClueTip_toolTipNewWindow :       '(click to open content in a new window or tab)',
    ClueTip_toolTipNoContentLoadable:'<i>No content could be loaded</i>',
    CollapseBox_captionCollapse :        '&nbsp;(show less)&nbsp;',
    CollapseBox_captionExpand :          '&nbsp;(more...)&nbsp;',
    CollapseBox_toolTipCollapse :        '(click to hide information below)',
    CollapseBox_toolTipExpand :          '(click to show more information below)',
    // see MediaWiki:jKey.js
    jKey_expandAll :              'Show all extras',
    jKey_iconOverview  :          'http://upload.wikimedia.org/wikipedia/commons/thumb/2/22/View-pause_Gion_simple.svg/20px-View-pause_Gion_simple.svg.png',
    jKey_iconResume  :            'http://upload.wikimedia.org/wikipedia/commons/thumb/4/49/View-playback_Gion_simple.svg/20px-View-playback_Gion_simple.svg.png',
    jKey_iconStart1st  :          'http://upload.wikimedia.org/wikipedia/commons/thumb/4/49/View-playback_Gion_simple.svg/20px-View-playback_Gion_simple.svg.png',
    jKey_iconStartNew  :          'http://upload.wikimedia.org/wikipedia/commons/thumb/0/05/View-refresh_Gion_simple.svg/20px-View-refresh_Gion_simple.svg.png'
  },
  de: {
    ClueTip_newWindow :              '(Neues Fenster …)',
    ClueTip_toolTipClose  :          'Zum Schließen klicken',
    ClueTip_toolTipNewWindow :       '(klicken um Inhalt in neuem Fenster oder Reiter zu öffnen)',
    ClueTip_toolTipNoContentLoadable:'<i>Leider konnte der Inhalt nicht geladen werden.</i>',
    CollapseBox_captionCollapse :        '&nbsp;(weniger anzeigen)&nbsp;',
    CollapseBox_captionExpand :          '&nbsp;(mehr...)&nbsp;',
    CollapseBox_toolTipCollapse :        '(klicken um Zusatzinformationen zu verbergen)',
    CollapseBox_toolTipExpand :          '(klicken um Zusatzinformationen anzuzeigen)',
    jKey_expandAll :              'Alle Zusatzinformationen zeigen'
  },
  fr: {
    ClueTip_newWindow :              '(Nouvelle fenêtre …)',
    ClueTip_toolTipClose  :          'Cliquez pour fermer',
    ClueTip_toolTipNewWindow :       '(Cliquez pour ouvrir le contenu dans une nouvelle fenêtre ou onglet)',
    ClueTip_toolTipNoContentLoadable:'<i>Malheureusement, le Contenu n’est pas chargé.</i>',
    CollapseBox_captionCollapse :        '&nbsp;(afficher moins)&nbsp;',
    CollapseBox_captionExpand :          '&nbsp;(plus...)&nbsp;',
    CollapseBox_toolTipCollapse :        '(cliquez pour masquer les informations ci-dessous)',
    CollapseBox_toolTipExpand :          '(cliquez pour afficher plus d’informations ci-dessous)',
    // see MediaWiki:jKey.js
    jKey_expandAll :              'afficher toutes les informations supplémentaires'
  },
  it: {
    ClueTip_toolTipClose  :          'Clicca per chiudere',
    CollapseBox_captionCollapse :        '&nbsp;(mostra di meno)&nbsp;',
    CollapseBox_captionExpand :          '&nbsp;(più...)&nbsp;',
    jKey_expandAll :              'Mostra tutti informazione' //REVISE
  }
};


/**
 * @description Get resource string (text, image URLs) for a given language, based on a string-key
 *  If no resource is defined in a given language for a resource key, the resource for 'en' will be returned,
 *  if this is missing as well an error message.
 * @augments $
 * @requires mw.config for getting global variables
 * @param {string} resourceKey key for the resource
 * @returns {String}
 */
$.resource = function (resourceKey) {
    var lang = mw.config.get('wgUserLanguage').split('-')[0]; // language: 'pt-BR', 'de-formal', etc.
    return ($.jI18n[lang] && $.jI18n[lang][resourceKey] ?
      $.jI18n[lang][resourceKey] :
      ($.jI18n.en[resourceKey]) ? $.jI18n.en[resourceKey] : 'MISSING RESOURCE: no $.jI18n.en.' + resourceKey + ' defined.');
 };
/**
 * @description Create html string for link with image and/or text content
 * @requires $.resource()
 * @param {string} txtResourceKey resource keys (multilingual {@link $.resource()}
 * @param {html} txtContent displayed content of a link
 * @param {string} href
 * @param {string} attributes string of combined other attributes of link element; must use ' as inner quotes, and \" inside event functions
 * @returns {string}
 */
$.linkBuilder = function (txtResourceKey, txtContent, href, attributes) {
  return (txtResourceKey.length ? '<a '
    + ' href="' + href + '" '
    + ' ' + (attributes.length ? attributes : '') + '>'
    + $.resource(txtResourceKey)
    + '</a>' : (txtContent.length ? '<a '
      + ' href="' + href + '" '
      + ' ' + (attributes.length ? attributes : '') + '>'
      + txtContent +
      '</a>' : '')
  );
};
/**
 *
 * @param {string} imgResourceKey resource key {@link $.resource()}
 * @param {string} txtResourceKey resource key {@link $.resource()}
 * @param {string} attributes HTML
 * @requires: $.linkBuilder
 * @returns {String}
 */
$.imglinkBuilder = function (imgResourceKey, txtResourceKey, attributes) {
  return (imgResourceKey.length ? '<a '
    + ' href="#" ' + (attributes.length ? ' ' + attributes : '') + '><img src="' + $.resource(imgResourceKey) + '" /></a>&nbsp;' : '')
    + $.linkBuilder(txtResourceKey, null, '#', attributes);
};
/**
 * @description return a random integer
 * @param {integer} min
 * @param {integer} max
 * @returns {*}
 */
$.random = function (min, max) { // NO CHECKS: if(min>max) {return -1;}  if(min==max) {return min;}
  return (min + parseInt(Math.random() * (max - min + 1), 10));
};

/**
 * @description collapse all collapsible key tables on wiki page
 * using the MediaWiki mw-customtoggle mechanism on all CSS class of
 * class="decisiontree"
 * Toggle all
 * 
 * $('.decisiontree').each (function (i, element) { $(element).find('.mw-customtoggle.is-collapsed').trigger('click') });
 * $('.decisiontree').each (function (i, element) { $(element).find('.mw-customtoggle').not('.is-collapsed').trigger('click') });
 * @requires MediaWiki:Mw-customcollapsible.js
 * @requires MediaWiki:JKey.js
 * @param {boolean} shallExpandThisKey
 * @param {selector} caller
 * @returns {undefined}
 */
$.toggleAllCollapsible = function (shallExpandThisKey, caller) {
  var $decisionTree = $(caller).closest('.decisiontree');
  // debug log messages
  if ($decisionTree.length) {
    if(shallExpandThisKey) {
      $decisionTree.each (function (i, element) {
        $(element).find('.mw-customtoggle.is-collapsed').trigger('click');
      });
      
    } else {
      $decisionTree.each (function (i, element) {
        $(element).find('.mw-customtoggle').not('.is-collapsed').trigger('click');
      });
    }
  }
};// $.toggleAllCollapsible()

/**
 * 
 * @requires MediaWiki:Mw-customcollapsible.js
 * @requires MediaWiki:JKey.js
 * @returns {undefined}
 */
window.expandToggleAllExtras = function () {
  $('div.decisiontree input.toggleAllExtras').each(function (i, element){
    $.toggleAllCollapsible(true, element);
    $(element)
      .prop( 'checked' , true);
    console.log('DEBUG jkey:initialized expandToggleAllExtras done');
    console.log(element);
  });
};
/**
 * @description: collapsible parts: div and tr → Template:Hidden
 *   may be fused later with toggleCollapse
 *   main difference: $.initCollapsebox() uses a switcher defined by the Wikitemplate
 *   and is not using a javascript resource title.
 *   * the only advanced feature it has: collpsible table rows
 *   * otherwise use http://www.mediawiki.org/wiki/RL/DM#jQuery.makeCollapsible
 * @requires $.resources()
 * @requires $.jl18n.en.CollapseBox_toolTipExpand, $.jl18n.en.CollapseBox_toolTipCollapse
 * @returns {Boolean}
 */
$.initCollapsebox = function () {
  /* is nested in: div.collapsebox
                    └ div.switcher
                    └ div.collapsecontent */
  var hasSwitcher = $('div.switcher .show, div.switcher .hide');
  if(hasSwitcher.length){
    $.each(hasSwitcher, function(index){// add tooltip
      hasSwitcher[index].title = hasSwitcher[index].className === 'show'? $.resource('CollapseBox_toolTipExpand') : $.resource('CollapseBox_toolTipCollapse');
    });
    $('div.collapsebox div.switcher').on('click',
      function() {
        $(this).nextAll('div.collapsecontent:first').slideToggle(250);
        /* $(this).toggle() does not work in live as toggle is a bind()
            therefore toggle must be bound to a different DOM element */
        $(this).find('.show, .hide').toggle();
      });
    /* is in a table: tr.collapsebox
                        └ div.switcher
                      tr.collapsecontent */
    $('tr.collapsebox div.switcher').on('click',
      function() {
        $(this).closest('tr.collapsebox').nextAll('tr.collapsecontent:first').toggle();
        $(this).find('.show, .hide').toggle();
      });
    // TODO is a better generic check possible?
    if (mw.config.get('wgPageName') === 'Spezial:Suche') {
      if (!$('.mw-search-results').length) {
        // open box with additional search possibilities
        $('.switcher .show').trigger('click');
      }
    }
    return true;
  }
  return false;
};// END $.initCollapsebox()

/**
 * @description: Get jQuery ui tabs loaded for characters displayed as nested ui tabs
 * @requires: jquery.ui.tabs
 * @requires: template:Character_images_tabs
 * @returns {undefined}
 */
window.init_character_ui_tabs = function () {
  var character_ui_tabs_nested=$('#character_ui_tabs_nested');
  if (character_ui_tabs_nested.length) {
    mw.loader.using('jquery.ui.tabs', function () {
      var ui_version =$.ui.version.split('.').map(function(x) { return parseInt(x, 10); })
       , first_tab_index =  character_ui_tabs_nested.find('li').index(
              character_ui_tabs_nested.find('li').not('.no-image-content').first()
            );
      if (ui_version[0] <= 1 
        && ui_version[1] < 10) {
        character_ui_tabs_nested.tabs({
          fx: [{opacity:'toggle', duration: 'slow'}, {opacity:'toggle', duration: 'slow'}],
          active: first_tab_index
        });
        character_ui_tabs_nested.find('.inner-tabs-container').tabs({
          fx: [{opacity:'toggle', duration: 'slow'}, {opacity:'toggle', duration: 'slow'}]
        });
      } else {
        character_ui_tabs_nested.tabs({
          hide: {effect: 'fadeOut', duration: 'slow'},
          show: {effect: 'fadeIn', duration: 'slow'},
          heightStyle: 'auto',
          active: first_tab_index
        });
        character_ui_tabs_nested.find('.inner-tabs-container').tabs({
          hide: {effect: 'fadeOut', duration: 'slow'},
          show: {effect: 'fadeIn', duration: 'slow'},
          heightStyle: 'auto'
        });
      }
    });
  }
};

// jKey Source
mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKey.js&action=raw&ctype=text/javascript' );

/**
 * Add a placeholder message and checks on Special:Contact
 *
 * Due to e-mail configurations all non @mfn-berlin.de addresses fail to work
 * as from-address on Special:Contact. This functions adds a placeholder and checks the
 * user’s input
 * @requires extension:ContactPage
 * @requires mw.config
 * @requires $
 */
$.prepareSpecialContact4Info = function () {
  var placeholderMessage = '', warningMessageDoesNotWork = '';
  switch (mw.config.get( 'wgCanonicalSpecialPageName' )) {
    case 'Contact': // is a Special:Contact page regardless of language
      switch (mw.config.get('wgPageName')) {
        case 'Special:Contact':
        case 'Spécial:Contact':
          placeholderMessage = 'Leave it empty or add e-mail in message (mfn-berlin.de works only)';
          warningMessageDoesNotWork = 'Only mfn-berlin.de addresses do work. Leave it empty please and add your address in the message. Thank you.';
          break;
        case 'Spezial:Kontakt':
          placeholderMessage = 'E-Mail in Nachricht dazu oder leer lassen (nur mfn-berlin.de geht)';
          warningMessageDoesNotWork = 'Nur mfn-berlin.de Adressen können verarbeitet werden. Bitte leer lassen oder E-Mail im Text angeben. Danke.';
          break;
        default:
          placeholderMessage = 'Leave it empty or add e-mail in message (mfn-berlin.de works only)';
          warningMessageDoesNotWork = 'Only mfn-berlin.de addresses do work. Leave it empty please and add your address in the message. Thank you.';
          break;
      }
      // check input
      if (!$('input[name="wpFromAddress"]').val() || $('input[name="wpFromAddress"]').val().match(/.*@mfn-berlin.de/)) {
        $('input[name="wpFromAddress"]')
          .css({'background-color': '', 'cursor': ''})
          .attr({'title': ''});
      } else {
        $('input[name="wpFromAddress"]')
          .css({'background-color': 'orange', 'cursor': 'help'})
          .attr({'title': warningMessageDoesNotWork});
      }
      $('input[name="wpFromAddress"]').on('focusout', function () {
        if (!$(this).val() || $(this).val().match(/.*@mfn-berlin.de/)) {
          $(this).css({'background-color': '', 'cursor': 'help'}).attr({'title': warningMessageDoesNotWork});
        } else {
          $(this).css({'background-color': 'orange', 'cursor': 'help'}).attr({'title': warningMessageDoesNotWork});
        }
      });
      $('input[name="wpFromAddress"]').attr({'placeholder': placeholderMessage});

    break;
  }// switch is a contact page
};// end $.prepareSpecialContact4Info()


if (mw.config.get('wgAction') === 'edit' 
  || mw.config.get('wgAction') === 'submit' ) {
    mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKeyWikiEditorHelp.js&action=raw&ctype=text/javascript' );; // load help for the wikiEditor
    mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:WikiEditor-insert-Zitat.js&action=raw&ctype=text/javascript' );;// Wizard to insert template:Zitat
    mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:WikiEditor-insert-file-with-preview.js&action=raw&ctype=text/javascript' );;// Wizard to insert file showing a preview
}
// click-text modifications for mw-customcollapsible triggering from outside of mw-collapsible
mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:Mw-customcollapsible.js&action=raw&ctype=text/javascript' );;
mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:Ui-custom-show-on-select.js&action=raw&ctype=text/javascript' );;
// attempted BUG fix mw.Title, should be loaded normally
if (typeof mw.Title==='undefined') {
  mw.loader.load( 'mediawiki.Title' ); // seems not loaded on any page
}

// specific to  http://wiki.infoflora.de
// Page-specific scripts:
switch (mw.config.get( 'wgPageName' )) { // Minimize the pages on which the code will be loaded
  case 'Hilfe:Konvertierung_geschachtelt-eingerückter_Schlüssel_in_das_ON-Format':
    mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKeyTextToLeadTemplateTool.js&action=raw&ctype=text/javascript' );;
    break;
}

jQuery(document).ready(function($) {
  if(mw.config.get( 'wgAction' )==='view') {
    if($('.decisiontree').length !== 0) {
      mw.loader.load( mw.config.get('wgScript') + '?title=MediaWiki:JKeyRenderLanguageTaggedText2wgUserLanguage.js&action=raw&ctype=text/javascript' );;
    }
  }
  if(mw.config.get( 'wgAction' )==='edit'
    || mw.config.get( 'wgAction' )==='view'
    /* || mw.config.get( 'wgAction' )==='submit' does not work somehow in MW. 1.20.7 */
  ){
    init_character_ui_tabs();
  }
  $.initCollapsebox(); //collapsible parts
  $.prepareSpecialContact4Info();
}); // end jQuery(document).ready()