MediaWiki:Common.js: Difference between revisions

From Wikimini Stock
Jump to navigation Jump to search
No edit summary
No edit summary
 
(3 intermediate revisions by the same user not shown)
(No difference)

Latest revision as of 16:23, 23 February 2017

/* Any JavaScript here will be loaded for all users on every page load. */



// ============================================================
//////////// FONCTION : .indexOf (Patch IE) //////////////

if (!Array.indexOf) {
  Array.prototype.indexOf = function(obj,idx) {
    var len = this.length;
    if (len == 0) return -1;
    if (!idx) idx = 0;
    while (idx < 0) idx = len + idx;
    for (var i = 0; i < len; i++)
      if (this[i] == obj)
        return i;
    return -1;
  }
}
// ============================================================

// ============================================================
//////////// FONCTION : .HTMLize (évite des attaques XSS) //////////////
if(!String.HTMLize){
  String.prototype.HTMLize = function() {
    var chars = new Array('&','<','>','"');
    var entities = new Array('amp','lt','gt','quot');
    var string = this;
    for (var i=0; i<chars.length; i++) {
      var regex = new RegExp(chars[i], "g");
      string = string.replace(regex, '&' + entities[i] + ';');
    }
    return string;
  }
}
// ============================================================

// ==================================================================================================
//////////// FONCTIONS RELATIVES AUX COOKIES //////////////
function setCookie (cookieName, cookieValue, expires, path) {
        document.cookie = escape(cookieName) + '=' + escape(cookieValue) + (expires ? '; EXPIRES=' + expires.toGMTString() : '') + "; PATH=/" ; 
}
  
function getCookie(cookieName) {
        var cookieValue = null;
        var posName = document.cookie.indexOf(escape(cookieName) + '=' );
        if (posName != -1) {
                        var posValue = posName + (escape(cookieName) + '=' ).length;
                        var endPos = document.cookie.indexOf(';', posValue) ;
                if (endPos != -1) {
                        cookieValue = unescape(document.cookie.substring(posValue, endPos));
                } else {
                        cookieValue = unescape(document.cookie.substring(posValue));
                }
        }
        return decodeURIComponent(cookieValue);
}
// ============================================================

// ============================================================
//////////// FONCTIONS : MANIPULATION DE CLASSES //////////////
function hasClass(node, className) {
  if (node.className == className) {
    return true;
  }
  var reg = new RegExp('(^| )'+ className +'($| )')
  if (reg.test(node.className)) {
    return true;
  }
  return false;
}

function addClass(node, className) {
    if (hasClass(node, className)) {
        return false;
    }
    node.className += ' '+ className;
    return true;
}
 
function removeClass(node, className) {
  if (!hasClass(node, className)) {
    return false;
  }
  node.className = eregReplace('(^|\\s+)'+ className +'($|\\s+)', ' ', node.className);
  return true;
}
 
function eregReplace(search, replace, subject) {
    return subject.replace(new RegExp(search,'g'), replace);
}

// ============================================================
//////////// FONCTION : RECUPERE LE CONTENU TEXTUEL D'UN ELEMENT //////////////
function getTextContent(oNode) {
  if (typeof(oNode.textContent)!="undefined") {return oNode.textContent;}
  switch (oNode.nodeType) {
    case 3: // TEXT_NODE
    case 4: // CDATA_SECTION_NODE
      return oNode.nodeValue;
      break;
    case 7: // PROCESSING_INSTRUCTION_NODE
    case 8: // COMMENT_NODE
      if (getTextContent.caller!=getTextContent) {
        return oNode.nodeValue;
      }
      break;
    case 9: // DOCUMENT_NODE
    case 10: // DOCUMENT_TYPE_NODE
    case 12: // NOTATION_NODE
      return null;
      break;
  }
  var _textContent = "";
  oNode = oNode.firstChild;
  while (oNode) {
    _textContent += getTextContent(oNode);
    oNode = oNode.nextSibling;
  }
  return _textContent;
}
// ===============================================


// ===============================================
//////////// FONCTION : INSERE UN ELEMENT APRES UN ELEMENT DE REFERENCE //////////////
function insertAfter(element, reference) {
    if(reference.nextSibling!=null){
        reference.parentNode.insertBefore(element, reference.nextSibling);
    }else{
        reference.parentNode.appendChild(element);
    }
}
// ===============================================


// ===============================================
//////////// FONCTION : DECODE LE HTML ISSU D'UNE REQUETE API //////////////
function API_HTMLDecode(text){
      var EncodedCharacter = new Array();
      var DecodedCharacter = new Array();
      var CharacterCount = 0;
 
      EncodedCharacter[CharacterCount] = "&amp;";
      DecodedCharacter[CharacterCount] = "&";
      CharacterCount++;
      EncodedCharacter[CharacterCount] = "&#039;";
      DecodedCharacter[CharacterCount] = "'";
      CharacterCount++;
      EncodedCharacter[CharacterCount] = "&quot;";
      DecodedCharacter[CharacterCount] = '"';
      CharacterCount++;
 
      for(var a=0;a<EncodedCharacter.length;a++){
            while(text.indexOf(EncodedCharacter[a])!=-1){
                  text = text.split(EncodedCharacter[a]).join(DecodedCharacter[a]);
                  if(text.indexOf(EncodedCharacter[a])==-1) break;
            }
      }
      return text;
}
// ===============================================


// ===============================================
// Wikiminicustom (om)
// ===============================================

// <source lang="javascript">
 
/*
  Upload form rewrite
 
  Author: [[User:Lupo]], March 2008
  License: Quadruple licensed GFDL, GPL, LGPL and Creative Commons Attribution 3.0 (CC-BY-3.0)
 
  Choose whichever license of these you like best :-)
*/
 
//mw.loader.load( '/w/index.php?title=MediaWiki:Gadget-HotCat.js&action=raw&ctype=text/javascript' );
mw.loader.load( '/w/index.php?title=MediaWiki:TextCleaner.js&action=raw&ctype=text/javascript' );
mw.loader.load( '/w/index.php?title=MediaWiki:LanguageHandler.js&action=raw&ctype=text/javascript' );
mw.loader.load( '/w/index.php?title=MediaWiki:FormRestorer.js&action=raw&ctype=text/javascript' );
mw.loader.load( '/w/index.php?title=MediaWiki:UIElements.js&action=raw&ctype=text/javascript' );
mw.loader.load( '/w/index.php?title=MediaWiki:Tooltips.js&action=raw&ctype=text/javascript' );
 
// Guard against multiple inclusions!
if (typeof (UploadForm) == 'undefined') {
 
// Configuration. These can be set by a user in their monobook.js/modern.js. The typeof checks
// are not really needed when this script is globally enabled, but until then, we have to be
// careful not to overwrite a user's settings if he defines these first and then includes this
// script in his monobook.js.
if (typeof (UploadForm_forcebasic) == 'undefined')
  // If non-null, use the basic form
  var UploadForm_forcebasic     =
    (typeof (JSconfig) == 'undefined' || JSconfig.keys['UploadForm_newlayout']) ? null : true;
if (typeof (UploadForm_ownwork_author) == 'undefined')
  var UploadForm_ownwork_author = "\[\[User:" + mw.config.get('wgUserName') + "|" + mw.config.get('wgUserName') + "\]\]";
  // Change to use something else
if (typeof (UploadForm_ownwork_date) == 'undefined')
  var UploadForm_ownwork_date   = null;
  // Set to define a pre-fill value for the date field
if (typeof (UploadForm_own_language_first) == 'undefined')
  var UploadForm_own_language_first = true; //Wikiminicustom (om) set to true
  // Set to true to have own language description on top
if (typeof (UploadForm_additional_info_height) == 'undefined')
  var UploadForm_additional_info_height = 2;
if (typeof (UploadForm_description_height) == 'undefined')
  var UploadForm_description_height = 2;
if (typeof (UploadForm_source_field_size) == 'undefined')
  var UploadForm_source_field_size = 1;
if (typeof (UploadForm_author_field_size) == 'undefined')
  var UploadForm_author_field_size = 1;
if (typeof (UploadForm_page_preview_in_tooltip) == 'undefined')
  var UploadForm_page_preview_in_tooltip = false;
if (typeof (UploadForm_description_languages) == 'undefined')
  var UploadForm_description_languages = null;
if (typeof (UploadForm_autofill) == 'undefined')
  var UploadForm_autofill = true;
  // If false, don't pre-fill description field in basic mode. May be useful
  // for people who have their own scripts pre-filling this field.
 
// Don't set the focus initially, it makes the page scroll, and people won't see the
// introductory texts
var EditTools_set_focus_initially = false;
 
var UFUtils =
{
  makeLink : function (name, url)
  {
    var link = document.createElement ('a');
    link.setAttribute ('href', url);
    link.appendChild (document.createTextNode (name));
    return link;    
  },
 
  convert_td_div : function (td)
  {
    // Replace the contents with a div, fixate the width, and give the div the id of the td
    var div = document.createElement ('div');
    var w = UFUtils.getWidth (td);
    if (w) {
      td.setAttribute ('width', "" + w);
      td.style.maxWidth = "" + w + 'px';
    }
    div.setAttribute ('width', (w ? "" + w : '100%'));
    if (w) div.style.maxWidth = "" + w + 'px';
    // Clear the warning_cell and add the div instead
    while (td.firstChild) td.removeChild (td.firstChild);
    td.appendChild (div);
    var id = td.id;
    td.id = "";
    div.id = id;
    return div;
  },
 
  getHeight : function (rows, minimum, maximum)
  {
    if (rows == null) return minimum;
    try {
      var x = rows / 2;
    } catch (ex) {
      // It's not a number
      return minimum;
    }
    if      (rows < minimum) return minimum;
    else if (rows > maximum) return maximum;
    return rows;
  },
 
  getWidth : function (element)
  {
    try {
      if (element.clientWidth)          // From IE, but Gecko has this, too.
        return element.clientWidth;
      else if (window.getComputedStyle) // Gecko, Opera
        return document.defaultView
                       .getComputedStyle (element, null)
                       .getPropertyValue ('width');
    } catch (ex) {
    }
    return null;
  },
 
  isChildOf : function (child, ancestor)
  {
    if (!ancestor) return false;
    while (child && child != ancestor) child = child.parentNode;
    return (child == ancestor);
  }
 
}; // end UFUtils
 
var UFUI =
{
  // Encapsulate all UI stuff, with checks such that it works in degraded mode
  // (built-in defaults only) if UIElements doesn't exist.
 
  defaultLanguage  : 'en',     // Default.
  userLanguage     : 'en',     // Sanitized wgUserLanguage.
  internalLanguage : 'en',     // Same, but with dashes replaced by underscores.
  isOwnWork        : false,    // True if uselang="*ownwork"
  isFromFlickr     : false,    // True if uselang="*fromflickr"
  isExperienced    : false,    // True if uselang="experienced"
 
  sanitizeUserLanguage : function ()
  {
    // Try to make sense of wgUserLanguage even if it has been hacked to have special
    // pages for particular upload sources. Also sets isOwnWork and isFromFlickr.
    if (mw.config.get('wgUserLanguage') == null || mw.config.get('wgUserLanguage').length == 0) return;    
    UFUI.userLanguage = mw.config.get('wgUserLanguage');
    if (mw.config.get('wgUserLanguage').length > 3) {
      // Special "hacked" uselang parameters...
      var hacks = ['ownwork', 'fromflickr', 'experienced', 'fromwikimedia', 'fromgov'];
      var found = false;
      for (var i = 0; i < hacks.length; i++) {
        var idx = mw.config.get('wgUserLanguage').indexOf (hacks[i]);
        if (idx >= 0) {
          found = true;
          if (idx > 0)
            UFUI.userLanguage = mw.config.get('wgUserLanguage').substring (0, idx);
          else
            UFUI.userLanguage = UFUI.defaultLanguage;
          if (i == 0)
            UFUI.isOwnWork = true;
          else if (i == 1)
            UFUI.isFromFlickr = true;
          else if (i == 2)
            UFUI.isExperienced = true;
          break;
        }
      }
      if (!found
          && typeof (LanguageHandler) != 'undefined'
          && typeof (LanguageHandler.getPrefix) == 'function')
      {
        // None of the "standard" hacks. Try an alternate approach.
        var lang_code_length = LanguageHandler.getPrefix (mw.config.get('wgUserLanguage'));
        if (lang_code_length > 0 && lang_code_length < mw.config.get('wgUserLanguage').length) {
          UFUI.userLanguage = mw.config.get('wgUserLanguage').substr (0, lang_code_length);
        }
      } 
    } // end if
    if (UFUI.userLanguage == 'en-gb') UFUI.userLanguage = 'en';
    UFUI.internalLanguage = UFUI.userLanguage.replace (/-/g, '_');
  },
 
  defaultLabels : {
    wpSourceUploadLbl:         'Source:',
    wpAuthorUploadLbl:         'Author:',
    wpDateUploadLbl:           'Date:',
    wpDescUploadLbl:           'Description:',
    wpPermissionUploadLbl:     'Permission:',
    wpCategoriesUploadLbl:     'Categories:',
    wpOtherVersionsUploadLbl:  'Other versions:',
    wpAdditionalInfoUploadLbl: 'Additional information:',
    wpPreviewLicenseUploadLbl: 'Preview the chosen license',
    wpOwnWorkUploadLbl:        'Own work',
    wpUnknownLanguageUploadLbl:'Unknown language',
    wpPreviewUploadLbl:        'Preview',
    wpOkUploadLbl:             'OK',
    wpCancelUploadLbl:         'Cancel'
  },
 
  defaultErrorMsgs : {
    wpUploadWarningError: 
      'You must provide the original source of the image, the author of the work, and a license.',
    wpNoFilenameError:
      'The target filename must not be empty.',
    wpHttpFilenameError: 
      'The target file name appears to be a URL.',
    wpNoSlashError:
      'The target file name must not contain "/".',
    wpNondescriptFilenameError:
      'Please use a more descriptive target file name.',
    wpNoExtensionError:
      'The target file name must have a file type extension (like for example ".jpg").',
    wpIllegalExtensionError:
      'Files of this type cannot be uploaded.',
    wpDoubleExtensionError:
      'Please correct the double file type in the target file name.',
    wpFlickrURLError:
      'The source must be a URL pointing to the image at Flickr.',
    wpNoDescriptionError:
      'Please give a description of the contents of the file you want to upload.',
    wpNoHelpTextError:
      'Help text not found.',
    wpPreviewOverwriteError:
      'You will upload over an already existing file. Please choose a different filename,'
     +'unless you are uploading a technically improved version of the same file.'
     +'Don\'t overwrite a file with a different image of the same topic.'
     +'If you overwrite, the information in this form will not appear on the description page.',
 
    wpReuploadNoSummaryError:
      'Please describe the file changes in the text box.'
  },
 
  defaultHints: {
    wpUploadFormDestFileHint:
      'Name of the file at Wikimini after the upload.',
    wpUploadFormSourceHint:
      'Where does this file come from?',
    wpUploadFormAuthorHint:
      'Who created this file? If it shows some artwork, who created that?',
    wpUploadFormDateHint:
      'Date of creation and/or first publication of the work.',
    wpUploadFormPermissionHint:
      'Not your own file? Or already published elsewhere? Use \{\{OTRS pending\}\} and send permission by e-mail. '
     +'Also for specialized license tags.',
    wpUploadFormAdditionalInfoHint:
      'Use for geolocation tags and other specialized information.',
    wpUploadFormCategoryHint:
      'Click (+) to add categories.'
  },
 
  // Do *not* use "-" here (as in "be-tarask")!! Use "_" instead: "be_tarask".
  translate: {
    en: 'translate',
    af: 'vertaal',
    ar: 'ترجم',
    be: 'перакласці',
    be_tarask: 'перакласьці',
    br: 'treiñ',
    bg: 'превеждам',
    ca: 'traduïu',
    cs: 'přeložit',
    cy: 'cyfieithu',
    da: 'oversæt',
    de: 'übersetzen',
    el: 'μεταφράστε',
    eo: 'traduki',
    es: 'traducir',
    et: 'tõlkima',
    fa: 'ترجمه\u200cکردن',
    fi: 'suomenna',
    fo: 'umseta',
    fr: 'traduire',
    gl: 'traducir',
    he: 'לתרגם',
    hr: 'prevesti',
    hu: 'fordítás',
    hy: 'թարգմանել',
    id: 'terjemah',
    io: 'tradukar',
    is: 'þýða',
    it: 'tradurre',
    ja: '訳す',
    ko: '번역하기',
    la: 'traducere',
    mk: 'преведи',
    ml: 'തര്‍ജ്ജമ',
    mn: 'орчуулах',
    mt: 'traduci',
    nn: 'oversett',
    no: 'oversett',
    nl: 'vertalen',
    pap: 'tradusí',
    pl: 'przetłumacz',
    pt: 'traduzir',
    ro: 'a traduce',
    ru: 'перевести',
    sk: 'preložit',
    sl: 'perovodit',
    sq: 'përkthej',
    ss: 'kuhúmusha',
    sv: 'översätt',
    ta: 'மொழிபெயர்',
    tr: 'tercüme',
    ty: 'ʻauvaha',
    uk: 'перекласти',
    vi: 'dịch',
    zh: '翻譯',
    zh_min_nan: 'hoan-e̍k',
    nan: 'hoan-e̍k',
    minnan: 'hoan-e̍k'
  },
 
  labels     : null,  // Repository for form labels
  help       : null,  // Repository for help texts (and the help button)
  error_msgs : null,  // Repository for error messages
  uiElements : null,  // Repository for graphical UI elements
  hints      : null,  // Repository for brief hints
 
  setupRepositories : function ()
  {
    if (!UFUI.labels) {
      if (typeof (UIElements) != 'undefined') {
        UFUI.labels     = UIElements.emptyRepository ();
        UFUI.help       = UIElements.emptyRepository ();
        UFUI.error_msgs = UIElements.emptyRepository ();
        UFUI.uiElements = UIElements.emptyRepository ();
        UFUI.hints      = UIElements.emptyRepository ();
 
        /* Wikiminicustom (lj): replaced this block by the following one (because wpDescUploadLbl label can be a normal label, like the ones, i.e. with no link)
        for (var id in UFUI.defaultLabels) {
          if (id == 'wpDescUploadLbl') {
            UIElements.setEntry
              (  id
               , UFUI.labels
               , UFUtils.makeLink (  UFUI.defaultLabels[id]
                                   , '/wiki/Commons:First_steps/Quality_and_description')
              );
          } else {
            UIElements.setEntry
              (id, UFUI.labels, document.createTextNode (UFUI.defaultLabels[id]));
          }
        }*/
        /* Wikiminicustom (lj): New block (begin) */
        for (var id in UFUI.defaultLabels) {
          UIElements.setEntry
              (id, UFUI.labels, document.createTextNode (UFUI.defaultLabels[id]));
        }
        /* Wikiminicustom (lj): New block (end) */
        for (var id in UFUI.defaultErrorMsgs) {
          UIElements.setEntry (id, UFUI.error_msgs,
                               document.createTextNode (UFUI.defaultErrorMsgs[id]));
        }
        for (var id in UFUI.defaultHints) {
          UIElements.setEntry (id, UFUI.hints,
                               document.createTextNode (UFUI.defaultHints[id]));
        }
 
        // Now try to read the localized stuff from the uploadfooter.
        UIElements.load ('wpUploadFormLabels', null, 'span', UFUI.labels);
        UIElements.load ('wpUploadFormErrorMessages', null, 'span', UFUI.error_msgs);
        UIElements.load ('wpUploadFormHints', null, 'span', UFUI.hints);
        UIElements.load ('wpUploadFormUIElements', null, 'div', UFUI.uiElements);
        UIElements.load ('wpUploadFormHelp', null, 'div', UFUI.help);
        UFUI.basic = false;
      } else {
        UFUI.labels     = UFUI.defaultLabels;
        UFUI.error_msgs = UFUI.defaultErrorMsgs;
        UFUI.hints      = UFUI.defaultHints;
        UFUI.basic      = true;
      }
    }  
  },
 
  getUI : function (id, repository, basic)
  {
    if (!UFUI.labels) {
      UFUI.sanitizeUserLanguage ();
      UFUI.setupRepositories ();
    }
    if (!UFUI[repository]) return null;
    var result   = null;
    var add_plea = false;
    if (UFUI.basic) {
      result = document.createTextNode (UFUI[repository][id]);
      add_plea = (UFUI.internalLanguage != UFUI.defaultLanguage);
    } else {
      result = UIElements.getEntry (id, UFUI[repository], UFUI.internalLanguage, null);
      add_plea = !result;
      if (!result) result = UIElements.getEntry (id, UFUI[repository]);
      if (!result) return null; // Hmmm... what happened here? We normally have defaults...
      result = result.cloneNode (true);
    }
    if (add_plea && !basic) {
      // Wrap it all into a span -- we can return only one element
      var span = document.createElement ('span');
      span.appendChild (result);
      //Wikiminicustom (om)
      //span.appendChild (UFUI.plea (repository, id));
      result = span;
    }
    return result;
  },
 
  plea : function (what, msg_id)
  {
    var span = document.createElement ('sub');
    span.appendChild (document.createTextNode (' ('));
    span.appendChild (
      UFUtils.makeLink (
         UFUI.translate[UFUI.internalLanguage] || UFUI.translate.en
       , 'http://commons.wikimedia.org/wiki/MediaWiki_talk:UploadFormLabels/UploadFormTranslations?action=edit'
         +'&section=new' 
         +'&withJS=MediaWiki:UploadFormTranslator.js&language='
         +encodeURIComponent (UFUI.userLanguage)
         +'&uploadformurl=' + encodeURIComponent (document.URL)
         +(what ? '&uploadformitems=' + encodeURIComponent (what) : "")
         +(msg_id ? '&uploadformmsg=' + encodeURIComponent (msg_id) : "")));
    span.appendChild (document.createTextNode (')'));
    return span;
  },
 
  getLabel : function (id, basic)
  {
    return UFUI.getUI (id, 'labels', basic);
  },
 
  getErrorMsg : function (id, basic)
  {
    return UFUI.getUI (id, 'error_msgs', basic);
  },
 
  getHint : function (id, basic)
  {
    return UFUI.getUI (id, 'hints', basic);
  },
 
  getEntry : function (id, repository, lang, sel)
  {
    if (!UFUI.labels) {
      UFUI.sanitizeUserLanguage ();
      UFUI.setupRepositories ();
    }
    if (!UFUI.basic)
      return UIElements.getEntry (id, UFUI[repository], lang, sel);
    if (!UFUI[repository] || lang != UFUI.defaultLanguage || !!sel && sel != 'default')
      return null;
    return UFUI[repository][id];
  }
 
}; // end UFUI
 
var UFHelp =  // Collects all help-related stuff
{
  help_close_imgs : null,
 
  precreate_tooltip_closer : function ()
  {
    if (typeof (Tooltip) != 'undefined' && typeof (Buttons) != 'undefined') {
      var close_imgs =
        UFUI.getEntry ('wpUploadFormHelpCloseButton', 'uiElements', UFUI.internalLanguage);
      if (!close_imgs)
        close_imgs = UFUI.getEntry ('wpUploadFormHelpCloseButton', 'uiElements');
      if (close_imgs) close_imgs = close_imgs.getElementsByTagName ('img');
      if (!close_imgs || close_imgs.length == 0)
        close_imgs = null;
      else
        close_imgs =  Buttons.createClass (close_imgs, 'wpUploadFormHelpCloseClass');
      UFHelp.help_close_imgs = close_imgs;
    }
  },
 
  tooltip_styles : // The style for all our tooltips
   {  border          : '1px solid #8888aa'
    , backgroundColor : '#f7f8ff'
    , padding         : '0.3em'
    , fontSize        : ((mw.config.get('skin') && (mw.config.get('skin') == 'monobook' || mw.config.get('skin') == 'modern')) ? '127%' : '100%')
      // Scale up to default text size
   },
 
  getHelp : function (help_id, with_ext) 
  {
    // This is a Tooltip callback! Sets the help texts dynamically, depending of the file
    // type the user has chosen in wpDestFile.
    var fn = null;
    if (with_ext) {
      fn = document.getElementById ('wpDestFile');
      if (fn != null) fn = fn.value;
      if (fn != null) {
        fn = fn.split ('.');
        if (fn.length >= 2) fn = fn[fn.length-1]; else fn = null;
      }
    }
 
    var add_plea   = false;
    var extensions = [fn, 'default'];
    var help_main  = null;
    for (var i = 0; i < extensions.length && !help_main; i++) {
      if (extensions[i] && extensions[i].length > 0) {
        help_main = UFUI.getEntry (help_id, 'help', UFUI.internalLanguage, extensions[i]);
        if (!help_main) {
          help_main = UFUI.getEntry (help_id, 'help', null, extensions[i]);
          add_plea  = (help_main != null);
        }
      }
    }
    var help_base = UFUI.getEntry (help_id, 'help', UFUI.internalLanguage);
    if (!help_base) {
      help_base = UFUI.getEntry (help_id, 'help');
      add_plea  = add_plea || (help_base != null);
    }
    var help = document.createElement ('div');
    if (help_base) help.appendChild (help_base);
    if (help_main) help.appendChild (help_main);
    if (!help_main && !help_base) {
      help.appendChild (UFUI.getErrorMsg ('wpNoHelpTextError'));
    } else if (add_plea) {
      help.appendChild (UFUI.plea ('help', help_id));
    }
    return help;
  },
 
  showHelp : function (evt, id) // Onclick handler for setup without tooltips
  {
    var e = evt || window.event;
    var node = e.target || e.srcElement;
    if (!node) {
      var error = UFUI.getErrorMsg ('wpNoHelpTextError', true);
      // We need the text contents... and IE doesn't know Node.TEXT_NODE
      while (error && error.nodeType != 3) error = error.firstChild;
      if (error) alert (error.data);
      // Otherwise what??
    } else if (!document.getElementById (id + '_Div')) {
      var help = UFHelp.getHelp (id, false);
      help.style.fontSize = 'small';
      help.style.color    = '#666666';
      // Now add a new table row after the current one
      var tr = node.parentNode;
      while (tr && tr.nodeName.toLowerCase () != 'tr') tr = tr.parentNode;
      if (!tr) {
        var error = UFUI.getErrorMsg ('wpNoHelpTextError', true);
        while (error && error.nodeType != 3) error = error.firstChild;
        if (error) alert (error.data);
      } else {
        var new_tr = document.createElement ('tr');
        var cell = document.createElement ('td');
        new_tr.appendChild (cell);
        cell = document.createElement ('td');
        cell.id = id + '_Div';
        new_tr.appendChild (cell);
        tr.parentNode.insertBefore (new_tr, tr.nextSibling);
        cell = UFUtils.convert_td_div (cell);
        cell.appendChild (help);
      }
    }
    if (!!e.stopPropagation) {
      e.stopPropagation ();
      e.preventDefault ();
    } else if (typeof (e.cancelBubble) != 'undefined') {
      e.cancelBubble = true;
    }
    return false;
  },
 
  setupHelp : function (is_reupload)
  {
    if (!UFUI.help) return; // Help not loaded
 
    function setHelp (id, imgs, lk, maximum_width, is_reupload)
    {
      // Figure out where to place the help "button"
      var field = document.getElementById (id);
      var insert_in = null, before = null;
      var help_id = id + 'Help';
      if (!UFUI.help[help_id]) return; // Don't add if we have no help at all.
      var offset = -5; // Pixels.
      switch (id) {
        case 'wpWatchthis':
        case 'wpIgnoreWarning':
          // Right of the element
          if (!field) return;
          insert_in = field.parentNode;
          // Find the label.
          {
            var lbls = insert_in.getElementsByTagName ('label');
            if (!lbls) {
              before = field.nextSibling;
            } else {
              for (var i = 0; i < lbls.length; i++) {
                if (lbls[i].htmlFor && lbls[i].htmlFor == id) {
                  before = lbls[i].nextSibling; break;
                }
              }
            }
          }
          offset = Math.abs (offset);
          break;
        case 'wpCategories':
          field = document.getElementById ('hotcatLabelTranslated');
          if (!field) return;
          insert_in = field;
          before    = null;
          if (field.firstChild) {
            field  = field.firstChild;
            offset = Math.abs (offset);
          }
          break;
        case 'wpAuthor':
        case 'wpSource':
          if (!field) return;
          field     = field.parentNode; // Because the field itself may vanish.
          insert_in = field.parentNode.cells[0];
          before    = null;
          break;
        case 'wpDestFile':
          if (!field) return;
          insert_in = field.parentNode.parentNode.cells[0];
          before    = null;
          if (is_reupload) {
            help_id = 'wpReuploadDestHelp';
            field   = null; // Field is hidden: attach the help text to the button instead
          }
          break;          
        case 'wpDesc':
          if (!field) {
            field = document.getElementById ('wpUploadDescription');
            if (field) { // Basic form
              help_id = (is_reupload ? 'wpReuploadSummaryHelp' : 'wpUploadDescriptionHelp');
            } else {
              insert_in = document.getElementById ('wpDescLabel');
              if (!insert_in) return;
              field     = insert_in;
              offset    = Math.abs (offset);
              before    = insert_in.nextSibling;
              insert_in = insert_in.parentNode;
              break;
            }
          }
          // Fall through
        default:
          if (!field) return;
          // In the table cell to the left
          insert_in = field.parentNode.parentNode.cells[0];
          before    = null;
      }
      // Create and insert the help "button"
      var button_construct = null, button = null;
      if (imgs && typeof (Buttons) != 'undefined') {
        button = Buttons.makeButton (imgs, id + '_HelpButton', '#');
        button.style.position = 'relative';
        button.style.top      = '-0.4em';
        button_construct      = button;
      } else {
        button_construct = lk.cloneNode (true);
        button = button_construct.getElementsByTagName ('a')[0];
      }
      insert_in.insertBefore (button_construct, before);
      if (typeof (Tooltip) != 'undefined') {
        // Create the tooltip
        var tooltip =
          new Tooltip
            (  button
             , function () { var hlp = help_id; return UFHelp.getHelp (hlp, true); }
             , { activate     : Tooltip.CLICK
                ,deactivate   : (UFHelp.help_close_imgs
                                 ? Tooltip.CLICK_ELEM
                                 : Tooltip.CLICK_TIP|Tooltip.CLICK_ELEM|Tooltip.LOSE_FOCUS)
                ,close_button : UFHelp.help_close_imgs
                ,mode         : Tooltip.FIXED
                ,fixed_offset : {x:10, y: offset}
                ,max_pixels   : maximum_width
                ,target       : field
                ,open_delay   : 0
                ,hide_delay   : 0
               }
             , UFHelp.tooltip_styles
            );
      } else {
        // Alternative setup without Tooltips: insert help text statically in a table field below the
        // button.
        button.onclick =
          function (evt) { var hlp = help_id; return UFHelp.showHelp (evt, hlp); };
      }
    }
 
    var button_imgs = null, button_lk   = null;
    if (typeof (Buttons) != 'undefined') {
      var button_imgs = UFUI.getEntry ('wpUploadFormHelpOpenButton', 'uiElements', UFUI.internalLanguage);
      if (!button_imgs) button_imgs = UFUI.getEntry ('wpUploadFormHelpOpenButton', 'uiElements');
      var button_lk   = null;
      if (button_imgs) button_imgs = button_imgs.getElementsByTagName ('img');
    }
    if (!button_imgs || button_imgs.length == 0) {
      // Alternative text-based "button"
      button_lk = document.createElement ('sup');
      button_lk.appendChild (document.createElement ('b'));
      button_lk.firstChild.appendChild (document.createTextNode (' ['));
      button_lk.firstChild.appendChild (UFUtils.makeLink ('?', '#'));
      button_lk.firstChild.appendChild (document.createTextNode (']'));
      button_imgs = null;
    } else {
      button_imgs = Buttons.createClass (button_imgs, 'wpUploadFormHelpOpenClass');
    }
 
    var widest_field = document.getElementById ('wpAdditionalInfo');
    var max_width    = 0;
    if (!widest_field) widest_field = document.getElementById ('wpUploadDescription');
    if (widest_field) {
      var w = UFUtils.getWidth (widest_field);
      try {
        max_width = Math.round (w * 0.9);
      } catch (ex) {
        max_width = 0;
      }
    }
    setHelp ('wpUploadFile', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpDestFile', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpSource', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpAuthor', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpDate', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpDesc', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpPermission', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpOtherVersions', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpAdditionalInfo', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpLicense', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpCategories', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpWatchthis', button_imgs, button_lk, max_width, is_reupload);
    setHelp ('wpIgnoreWarning', button_imgs, button_lk, max_width, is_reupload);
  }
 
}; // end UFHelp
 
var UploadFormBasic =
{
  on_error_form : false, // True iff we're on a re-sent form (error case).
 
  setup : function (auto_fill)
  {
    // Special setup: don't use separate input fields; just verify the filename and that the
    // description isn't empty.
    var desc = document.getElementById ('wpUploadDescription');
    var previous_form = null;
    UploadForm.previous_hotcat_state = null;
    if (!UploadForm.isReupload) {
      if (typeof (FormRestorer) != 'undefined') {
        var current_dest_file = document.getElementById ('wpDestFile');
        var original_dest_file = null;
        if (current_dest_file != null) {
          current_dest_file  = current_dest_file.value;
          original_dest_file = current_dest_file.defaultValue;
        }
        if (original_dest_file && original_dest_file.length > 0) {
          // If original_dest_file was set to something, we're not on the original upload form but
          // on the re-sent form in error cases.
          UploadFormBasic.on_error_form = true;
        } else if (current_dest_file && current_dest_file.length > 0) {
          previous_form = FormRestorer.readForm ('UploadFormBasic');
          if (!previous_form && desc && desc.value && desc.value.length > 0) {
            // Hmmm... IE sometimes cannot read the cookie (because it wasn't stored, due to some
            // strange security settings on some computers that I've been unable to track down).
            // If we're here, we have a target file name *and* a description: assume the description
            // comes from the browser's field value cache and make sure we don't overwrite it.
            auto_fill = false;
          }
        }
      }
      if (previous_form) {
        var additional_data = previous_form[0].val;
        if (additional_data) {
          additional_data    = additional_data.split ('\t');
          var previous_file  = additional_data[0];
          if (previous_file == current_dest_file) {
            if (additional_data.length >= 2) UploadForm.previous_hotcat_state = additional_data[1];
          } else {
            previous_form = null;
          }
        }
      }
    }
    UploadForm.formModified = true;
    if (document.getElementById ('wpLicense') != null)
      UploadForm.setup_license_preview ();      
    UploadForm.oldOnSubmit = UploadForm.the_form.onsubmit;
    UploadForm.the_form.onsubmit = UploadFormBasic.submit;
    if (!UploadForm.isReupload) {
      UploadForm.addPreviewButton (UploadFormBasic.preview);
    }
    if (previous_form) {
      // Restore form values.
      if (desc) {
        var prev = UploadForm.getPrevValue (previous_form, desc.id);
        if (prev) desc.value = prev;
      }
      if (UploadForm.previous_hotcat_state != null && typeof (hotcat_set_state) == 'function') {
        var input = document.getElementById ('hotcat_text');
        if (input != null) hotcat_cancel ();
        UploadForm.previous_hotcat_state = hotcat_set_state (UploadForm.previous_hotcat_state);
      }
    } else {
      if (!!UploadForm_autofill && auto_fill && !UploadForm.isReupload) {
        if (desc) desc.value = UploadForm.empty_template ('Information');
      }
    }
    if (desc && desc.value && desc.value.indexOf ('\{\{Information') >= 0) {
      // Only hide the box in the Uploadtext if there is really an inormation-template in the
      // summary!
      var infobox = document.getElementById ('Uploadtext-template-box');
      if (infobox) infobox.style.display = 'none';
    }
  },
 
  submit : function (evt)
  {
    var overwrite = false;
    if (!UploadForm.isReupload) overwrite = UploadForm.isOverwrite ();
    if (!UploadFormBasic.verify (overwrite)) return false;
 
    if (!UploadForm.isReupload) {
      var target_name = document.getElementById ('wpDestFile');
      if (target_name != null && target_name.value != null) // Strip whitespace
        target_name.value = target_name.value.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
      if (!UploadFormBasic.on_error_form
          && typeof (FormRestorer) != 'undefined'
          && target_name != null && target_name.value != null) {
        var hotcat_state = null;
        if (typeof (hotcat_get_state) == 'function') {
          var input = document.getElementById ('hotcat_text');
          if (input != null) hotcat_closeform ();
          hotcat_state = hotcat_get_state ();
        }
        // We already know that target_name.value is set!
        FormRestorer.saveForm
          (  'UploadFormBasic'
           , UploadForm.the_form.id
           , target_name.value
             + (hotcat_state != null ? '\t' + hotcat_state : '')
           , ';path=' + document.location.pathname
             + ';max-age=1800');
        // Expire after half an hour.
      }
    } // end if (UploadForm.isReupload)
 
    var desc = document.getElementById ('wpUploadDescription');
    var old_desc_value = desc.value;
    var do_submit = UploadForm.call_onsubmit (evt || window.event);
    if (!do_submit)
      desc.value = old_desc_value;
    else {
      desc.value = UploadForm.fixCategoryTransclusion (UploadForm.clean (desc.value));
      UploadForm.hidePreview ();
      document.getElementById ('wpDestFile').disabled = false;
    }
    return do_submit;
  },
 
  preview : function (evt)
  {
    var overwrite = UploadForm.isOverwrite ();
    if (!UploadFormBasic.verify (overwrite)) return false;
 
    var desc = document.getElementById ('wpUploadDescription');
    UploadForm.makePreview (UploadForm.clean (desc.value), overwrite);
    return true;
  },
 
  verify : function (overwrite)
  {
    var desc = document.getElementById ('wpUploadDescription');
    var ok   = true;
 
    if (UploadForm.isReupload) {
      // Only check that the description isn't empty
      if (UploadForm.errorMsgs != null) delete UploadForm.errorMsgs;
      UploadForm.errorMsgs = new Array ();
      UploadForm.warning_pushed = false;
      if (!desc.value || desc.value.search (/\S/) < 0) {
        desc.style.backgroundColor = UploadForm.errorColor;
        desc.onkeyup = UploadForm.resetBg;
        UploadForm.errorMsgs.push ('wpReuploadNoSummaryError');
        ok = false;
      }
    } else {
      if (!overwrite) {
        if (UploadForm.errorMsgs != null) delete UploadForm.errorMsgs;
        UploadForm.errorMsgs = new Array ();
        UploadForm.warning_pushed = false;
 
        if (!UploadForm.verifyMandatoryField (desc)) {
          desc.onkeyup = UploadForm.resetBg;
          ok = false;
        } else {
          // We do have a non-empty description. Try to split it up and check that the fields for
          // author, source, and description are filled in.
          var fields = UploadForm.split_description (desc.value);
          if (fields != null && fields.length == 4) {
            if (   fields[1] == null || fields[1].search (/\S/) < 0  // Author
                || fields[2] == null || fields[2].search (/\S/) < 0) // Source
            {
              desc.style.backgroundColor = UploadForm.errorColor;
              desc.onkeyup = UploadForm.resetBg;
              if (!UploadForm.warning_pushed) {
                if (UploadForm.errorMsgs != null)
                  UploadForm.errorMsgs.push ('wpUploadWarningError');
                UploadForm.warning_pushed = true;
              }
              ok = false;
            }
            if (   UploadForm.templates[fields[0]].desc_mandatory
                && (fields[3] == null || fields[3].search (/\S/) < 0)) // Description
            {
              desc.style.backgroundColor = UploadForm.errorColor;
              desc.onkeyup = UploadForm.resetBg;
              UploadForm.errorMsgs.push ('wpNoDescriptionError');
              ok = false;
            }
          }
        }
        // Try a license check
        var license = document.getElementById ('wpLicense');
        if (license == null || license.selectedIndex == 0) {
          // There must be a license somewhere in the description.
          if (!UploadForm.has_license ([desc])) {
            var d = desc.value.replace (/\{\{\s*([Ii]nformation|[Pp]ainting|[Ff]lickr)\s*\n/g,"");  
            if (d.indexOf ('\{\{') < 0) {
              // No transcludion that could provide a license either
              desc.style.backgroundColor = UploadForm.errorColor;
              desc.onkeyup = UploadForm.resetBg;
              if (!UploadForm.warning_pushed) {
                if (UploadForm.errorMsgs != null)
                  UploadForm.errorMsgs.push ('wpUploadWarningError');
                UploadForm.warning_pushed = true;
              }
              ok = false;
            } else {
              // Assume it's ok.
            }
          }
        } // end license check
        var target_name = document.getElementById ('wpDestFile');
        if (target_name != null) {
          // Trim leading and trailing whitespace
          target_name.value = target_name.value.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
          if (!UploadForm.verifyFileName (target_name.value)) {
            target_name.style.backgroundColor = UploadForm.errorColor;
            target_name.onkeyup =
              function (evt)
              {
                UploadForm.resetBg (evt);
                if (typeof (wgUploadWarningObj.keypress) == 'function' && !UploadForm.isReupload)
                  wgUploadWarningObj.keypress();
              };
            ok = false;
          }
        }
      }
    } // end if (reupload or not)
    if (!ok) {
      UploadForm.hidePreview ();
      UploadForm.display_errors ();
    } else {
      // It's ok: hide our warning box
      var my_warning = document.getElementById ('wpUploadVerifyWarning');
      if (my_warning != null) my_warning.style.display = 'none';
    }
    return ok;
  } // end verify
 
}; // end UploadFormBasic
 
var UploadFormFull =
{
  form_type             : 0,     // 0 - single desc field; 1 - one desc field per language
  field_state           : null,  // Will be initialized in setup below.
 
  multi_inputs : null,
  // If we're using several description fields, this is an array of objects
 
  pushMultiInput : function (sel, text)
  {
    if (UploadFormFull.multi_inputs == null) {
      UploadFormFull.multi_inputs = [{selector : sel, textfield : text}];
    } else {
      UploadFormFull.multi_inputs[UploadFormFull.multi_inputs.length] =
        {selector : sel, textfield : text};
    }
    var idx   = UploadFormFull.multi_inputs.length;
    sel.id    = 'wpLangSel' + idx;
    sel.name  = sel.id;
    text.id   = 'wpDescText' + idx;
    text.name = text.id;  
  },
 
  addDescField : function (content, lang, idx, stored_form)
  {
    var selector = LanguageHandler.getSelect
                     (null, lang, UFUI.getLabel ('wpUnknownLanguageUploadLbl', true));
    // These style definitions are needed for IE, which otherwise creates excessively wide
    // selectors, pushing the main form to the right.
    selector.style.maxWidth = '12em';
    selector.style.width    = '12em';
    selector.style.overflow = 'hidden';
    var textfield  = document.createElement ('textarea');
    textfield.setAttribute ('rows', UFUtils.getHeight (UploadForm_description_height, 2, 6));
    textfield.style.width = '100%';
    UploadFormFull.pushMultiInput (selector, textfield);
 
    var new_row = content.insertRow (idx == null ? content.rows.length : idx);
    var first_cell = document.createElement ('td');
    first_cell.classList.add('mw-label');
    first_cell.setAttribute ('vAlign', 'top');
    first_cell.appendChild (selector);
    var second_cell = document.createElement ('td');
    second_cell.classList.add('mw-input');
    second_cell.setAttribute ('vAlign', 'top');
    second_cell.appendChild (textfield);
    new_row.appendChild (first_cell);
    new_row.appendChild (second_cell);
 
    if (stored_form != null) {
      var prev_idx = UploadForm.getPrevValue (stored_form, selector.id);
      var prev_val = UploadForm.getPrevValue (stored_form, textfield.id);
      if (prev_val != null) textfield.value = prev_val;
      if (prev_idx != null) {
        selector.options[selector.selectedIndex].selected = false;
        selector.options[prev_idx].selected = true;
      }
    }
    UploadFormFull.enable_edittools (textfield);
  },
 
  addOneDescField : function (evt) // onclick handler for the button
  {
    var button = document.getElementById ('wpUploadAddDescription');
    var table_row = button.parentNode.parentNode;
    var idx = table_row.rowIndex;
    UploadFormFull.addDescField (table_row.parentNode, null, idx, null);
  },
 
  addMultiDesc : function (table, idx, stored_form)
  {
    // Add en and user language, if different
    var userLang = LanguageHandler.closestLanguage (UFUI.userLanguage);
 
    if (userLang == 'pt-br') userLang = 'pt'; // Per request from Portuguese and Brazilians
    var first_cell = document.createElement ('td');
    first_cell.classList.add('mw-label');
    var second_cell = document.createElement ('td');
    var new_label = document.createElement ('label');
    new_label.id = 'wpDescLabel';
    new_label.appendChild (UFUI.getLabel ('wpDescUploadLbl'));
    first_cell.appendChild (new_label);
 
    var new_row = table.insertRow (idx);
    new_row.appendChild (first_cell);
    new_row.appendChild (second_cell);
    idx++;
 
    var added = false;
    if (stored_form != null) {
      // Maybe we had more... find 'wpLangSel1'
      var curr = 0;
      for (var i = 1; i < stored_form.length; i++) {
        if (stored_form[i].id == 'wpLangSel1') {
          curr = i; break;
        }
      }
      if (curr > 0) {
        while (   curr < stored_form.length
               && stored_form[curr].id.indexOf ('wpLangSel') == 0) {
          UploadFormFull.addDescField (table, null, idx++, stored_form);
          added = true; curr++;
          if (curr < stored_form.length && stored_form[curr].id.indexOf ('wpDescText') == 0)
            curr++;
        }
      }
    } // end if
    if (!added) {
      if (   UploadForm_description_languages
          && UploadForm_description_languages.constructor == Array
          && UploadForm_description_languages.length > 0) {
        for (var i = 0; i < UploadForm_description_languages.length; i++) {
          var lang = LanguageHandler.closestLanguage (UploadForm_description_languages[i]);
          UploadFormFull.addDescField (table, lang, idx++, stored_form);
        }
      } else {
        if (UploadForm_own_language_first) {
		
		/* Wikiminicustom (lj): Replaced this block by following one (we do not want the English field to be shown by default)
          if (userLang != null && userLang != UFUI.defaultLanguage)
            UploadFormFull.addDescField (table, userLang, idx++, stored_form);
          UploadFormFull.addDescField (table, UFUI.defaultLanguage, idx++, stored_form);
        } else {
          UploadFormFull.addDescField (table, UFUI.defaultLanguage, idx++, stored_form);
          if (userLang != null && userLang != UFUI.defaultLanguage)
            UploadFormFull.addDescField (table, userLang, idx++, stored_form);
        }
        */
        
          if (userLang != null)
			UploadFormFull.addDescField (table, userLang, idx++, stored_form);
		  } else {
			 UploadFormFull.addDescField (table, UFUI.defaultLanguage, idx++, stored_form);
		  } /* Wikiminicustom (lj): End of custom replacement */
			
      }
    }
    // Now add a "+" button
    var additional =
      UploadForm.customFormButton
        (  'wpUploadFormAddDescButton'     // Customization ID
         , 'wpUploadAddDescription'        // ID of button
         , '+'                             // Default text
         , UploadFormFull.addOneDescField  // Event handler
        );
 
    new_row = table.insertRow (idx++);
    first_cell = document.createElement ('td');
    second_cell = document.createElement ('td');
    second_cell.classList.add('mw-input');
    second_cell.appendChild (additional);
    new_row.appendChild (first_cell);
    new_row.appendChild (second_cell);
 
    return idx;
  },
 
  changeField : function (field_id) // Callback for changeable field button
  {
    function get_selection (field)
    {
      // Based on code from Jonas Raoni Soares Silva at http://jsfromhell.com/forms/selection
      // License: {{tl|attribution}}
      // Warning: simplified because we apply it only to an INPUT field. For TEXTAREAs, see the
      // URL given.
      if (typeof (field.selectionStart) != 'undefined')
        return {start: field.selectionStart, end: field.selectionEnd};
      else if (!!field.createTextRange) {
        field.focus ();
        var s = document.selection.createRange();
        if (s.parentElement() != field) return {start: 0, end: 0};
        var r = field.createTextRange(); r.setEndPoint ("EndToStart", s);
        return {start: r.text.length, end: r.text.length + s.text.length};
      }
      return {start: 0, end: 0};
    }
 
    var field  = document.getElementById (field_id);
    if (field.disabled) return; // Don't do anything if the field isn't enabled.
 
    var button = document.getElementById (field_id + '_Button');
    var cell   = field.parentNode;
    if (!field || !button || !cell) return; // Error message here?
    var new_field = document.createElement ('textarea');
    var height = UFUtils.getHeight (UploadFormFull.field_state[field_id].height, 2, 4);
    new_field.setAttribute ('rows', height);
    new_field.style.width = '100%';
    new_field.value = field.value;
    var sel = get_selection (field);
    var tab_idx = field.getAttribute ('tabindex');
    cell.removeChild (button);
    cell.replaceChild (new_field, field);
    field.id = "";
    field.onfocus = null;
    new_field.id = field_id;
    new_field.setAttribute ('tabindex', tab_idx);
    UploadFormFull.enable_edittools (new_field);
    // Restore the selection
    if (!!new_field.setSelectionRange) // e.g. khtml
      new_field.setSelectionRange (sel.start, sel.end);
    else if (typeof (new_field.selectionStart) != 'undefined') {
      new_field.selectionStart = sel.start;
      new_field.selectionEnd   = sel.end;
    } else if (new_field.createTextRange) { // IE
      var new_selection = new_field.createTextRange();
      new_selection.move ("character", sel.start);
      new_selection.moveEnd ("character", sel.end - sel.start);
      new_selection.select();
    }
    new_field.focus ();
    UploadFormFull.field_state[field_id].height = height;
  },
 
  enable_edittools : function (textfield)
  {
    // To be called on each dynamically added field to ensure the edit toolbar works there
    if (typeof (EditTools) != 'undefined' && typeof (EditTools.registerTextField) == 'function') {
      // We have EditTools
      if (insertTags == EditTools.insertTags) {
        // EditTools is already set up: we have to add an onfocus handler ourselves
        addEvent (textfield, 'focus', EditTools.registerTextField);
      }
      // Otherwise, EditTools will be set up later, and will catch this field, so we don't have
      // to do anything.
    }
  },
 
  switch_intro_text : function ()
  {
    // Set up the display of [[MediaWiki:Uploadtext]]
    var long_text  = document.getElementById ('wpUploadFormLongText');
    var short_text = document.getElementById ('wpUploadFormShortText');
    if (long_text && short_text) {
      long_text.style.display = 'none';
      if (UFUtils.isChildOf (long_text, short_text)) {
        // If long_text is a child of short_text, then short_text is already shown, and
        // long_text is just a part that isn't needed for the new upload form. Hence
        // we're done.
        return;
      }
      if (UFUtils.isChildOf (short_text, long_text)) {
        // If the short_text is within the long_text, we need to take it out; otherwise
        // it won't be shown.
        short_text.parentNode.removeChild (short_text);
        long_text.parentNode.insertBefore (short_text, long_text.nextSibling);
      }
      short_text.style.display = "";
    } else {
      // Remove the redundant infobox in the uploadtext explanation. People should *not*
      // insert this template into description.
      var infobox = document.getElementById ('Uploadtext-template-box');
      if (infobox) infobox.style.display = 'none';
    }
  },
 
  set_hints : function ()
  {
    UploadForm.addAfterField ('wpDestFile', UFUI.getHint ('wpUploadFormDestFileHint'));
    UploadForm.addAfterField ('wpSource', UFUI.getHint ('wpUploadFormSourceHint'));
    UploadForm.addAfterField ('wpAuthor', UFUI.getHint ('wpUploadFormAuthorHint'));
    UploadForm.addAfterField ('wpDate', UFUI.getHint ('wpUploadFormDateHint'));
    UploadForm.addAfterField ('wpPermission', UFUI.getHint ('wpUploadFormPermissionHint'));
    UploadForm.addAfterField ('wpAdditionalInfo', UFUI.getHint ('wpUploadFormAdditionalInfoHint'));
    UploadForm.addAfterField ('catlinks', UFUI.getHint ('wpUploadFormCategoryHint'));
  },
 
  setup : function ()
  {
    function addField (table, idx, id, label, field, stored_form)
    {
      if (label == null) label = UFUI.getLabel (id + 'UploadLbl');
      var new_row = table.insertRow (idx);
      var firstCell = document.createElement ('td');
      firstCell.classList.add('mw-label');
      var new_label = document.createElement ('label');
      new_label.htmlFor = id;
      new_label.appendChild (label);
      firstCell.appendChild (new_label);
      var secondCell = document.createElement ('td');
      secondCell.classList.add('mw-input');
      field.setAttribute ('name', id);
      field.setAttribute ('id', id);
      secondCell.appendChild (field);
      new_row.appendChild (firstCell);
      new_row.appendChild (secondCell);
      var prev_value = UploadForm.getPrevValue (stored_form, id);
      if (prev_value != null) field.value = prev_value;
      UploadFormFull.enable_edittools (field);
    }
 
    function addInput (table, idx, id, label, width, stored_form)
    {
      var new_field = document.createElement ('input');
      new_field.setAttribute ('type', 'text');
      new_field.setAttribute ('size', '' + width);
      addField (table, idx, id, label, new_field, stored_form);
      UploadFormFull.enable_edittools (new_field);
      return new_field;
    }
 
    function addChangeableField (height, table, idx, id, label, width, stored_form)
    {
      var new_field = null;
      var field_id = 'wp' + id;
      if (height == 0)
        height = UFUtils.getHeight (UploadFormFull.field_state[field_id].height, 1, 4);
      if (height > 1) {
        new_field = document.createElement ('textarea');
        new_field.setAttribute ('rows', height);
        new_field.style.width = '100%';
        addField (table, idx, 'wp' + id, null, new_field, stored_form);
      } else {
		//Wikiminicustom (om)
		//new_field  = addInput (table, idx, field_id, null, 80, stored_form);
        new_field  = addInput (table, idx, field_id, null, 60, stored_form);
        var button =
          UploadForm.customFormButton
            (  'wpUploadForm' + id + 'Button'
             , field_id + '_Button'
             , '...'
             , function () { UploadFormFull.changeField (field_id); }
            );
        new_field.parentNode.insertBefore (button, new_field.nextSibling);
      }
      UploadFormFull.field_state[field_id].height = height;
      UploadFormFull.enable_edittools (new_field);
    }
 
    function setCheckBoxes (previous_form, boxes)
    {
      if (boxes == null || boxes.length == 0 || previous_form == null) return;
      for (var i = 0; i < boxes.length; i++) {
        if (boxes[i] != null) {
          var prev_val = UploadForm.getPrevValue (previous_form, boxes[i].id);
          if (prev_val != null) boxes[i].checked = prev_val;
        }
      }
    }
 
    // Init the field states. Cannot be done earlier, otherwise definitions in user's
    // monobook.js (or modern.js, or ...) won't be taken aboard.
    UploadFormFull.field_state =
      { wpSource: {height: UploadForm_source_field_size}
       ,wpAuthor: {height: UploadForm_author_field_size}
      };
 
    var previous_form         = null;
    var previous_type         = -1; // unknown
    var previous_fields       = [0, 0];
    UploadForm.previous_hotcat_state = null;
    if (typeof (FormRestorer) != 'undefined') {
      // We know that when we arrive here originally, wpDestFile.value is empty, as is
      // wpDestFile.defaultValue. If we entered something, submitted, and then come back,
      // modern browsers restore form entries, at least for the fields in the static XHTML.
      // wpDestFile is such a static field (it isn't added by Javascript), so if we have a
      // non-empty value here, we know that the form needs to restored. (But see the caveat
      // about IE and onload handling at the bottom of the file!)
      var current_dest_file = document.getElementById ('wpDestFile');
      if (current_dest_file != null) current_dest_file = current_dest_file.value;
      if (current_dest_file != null && current_dest_file.length > 0) {
        previous_form = FormRestorer.readForm ('UploadForm');
      }
      if (previous_form) {
        var additional_data = previous_form[0].val;
        if (additional_data) {
          additional_data    = additional_data.split ('\t');
          var previous_file  = additional_data[1];
          if (previous_file == current_dest_file) {
            previous_type      = parseInt (additional_data[0], 10);
            previous_fields[0] = parseInt (additional_data[2], 10);
            previous_fields[1] = parseInt (additional_data[3], 10);          
            if (additional_data.length >= 5) UploadForm.previous_hotcat_state = additional_data[4];
          } else {
            previous_form = null;
          }
        }
      }
    }
    var original_desc = document.getElementById ('wpUploadDescription');
    var original_row  = original_desc.parentNode.parentNode;
    var table         = original_row.parentNode;
    var original_idx  = original_row.rowIndex;
    UploadForm.formModified = true;
    original_desc.setAttribute ('id', "");
    UploadForm.oldOnSubmit = UploadForm.the_form.onsubmit;
    UploadForm.the_form.onsubmit = UploadFormFull.submit;
    table.deleteRow (original_idx);
    var idx = original_idx;
    // Insert source field
    var new_field = null;
    // Wikiminicustom (om)
    //addChangeableField (previous_fields[0], table, idx++, 'Source', null, 80, previous_form);
    //addChangeableField (previous_fields[1], table, idx++, 'Author', null, 80, previous_form);
    //addInput (table, idx++, 'wpDate', null, 80, previous_form);
    // Insert description field
    if (typeof (LanguageHandler) == 'undefined' || previous_type == 0) {
      // Basic setup
      new_field = document.createElement ('textarea');
      new_field.setAttribute ('rows', UFUtils.getHeight (UploadForm_description_height, 6, 12));
      // Wikiminicustom (om)
      //new_field.style.width = '100%';
      new_field.style.width = '80%';
      // Do not name the new field 'wpUploadDescription', otherwise MediaWiki:Upload.js
      // might prefill it with an information template!
      addField (table, idx++, 'wpDesc', null, new_field, previous_form);
      UploadFormFull.form_type = 0;
    } else {
      idx = UploadFormFull.addMultiDesc (table, idx, previous_form);
      UploadFormFull.form_type = 1;
    }
    //Wikiminicustom (om)
    addChangeableField (previous_fields[0], table, idx++, 'Source', null, 80, previous_form);
    addChangeableField (previous_fields[1], table, idx++, 'Author', null, 80, previous_form);
    //addInput (table, idx++, 'wpOtherVersions', null, 80, previous_form);
    //addInput (table, idx++, 'wpPermission', null, 80, previous_form);
    new_field = document.createElement ('textarea');
    new_field.setAttribute
      ('rows', UFUtils.getHeight (UploadForm_additional_info_height, 2, 10));
    new_field.style.width = '100%';
    // Work-around Firefox's "one additional line" bug
    //Wikiminicustom (om)
    //addField (table, idx++, 'wpAdditionalInfo', null, new_field, previous_form);
    // Add a preview button.
    //Wikiminicustom (om)
    // UploadForm.addPreviewButton (UploadFormFull.preview);
    // Correct tab indices.
    for (var i = 0; i < UploadForm.the_form.length; i++) {
      UploadForm.the_form.elements[i].setAttribute ('tabindex', '' + i);
    }
    var license = document.getElementById ('wpLicense');
    // Change the license previewer to not cause a table re-layout
    if (license != null) {
      // These style definitions are because long option labels result in excessively wide
      // selectors, causing also the description fields to go beyond the right border of the
      // page.
      license.style.maxWidth = '100%';
      license.style.width    = '100%';
      license.style.overflow = 'hidden';
    }
    UploadForm.setup_license_preview ();
    if (license != null) {
      var prev = UploadForm.getPrevValue (previous_form, 'wpLicense');
      if (prev != null) {
        try {
          license.options[license.selectedIndex].selected = false;
          license.options[prev].selected = true;
        } catch (ex) {
        }
      }
    }
    // Pre-fill in some cases
    if (UFUI.isOwnWork) {
      var src     = document.getElementById ('wpSource');
      var author  = document.getElementById ('wpAuthor');
      if (src != null && (src.value == null || src.value.length == 0)) {
        src.value = UploadForm.getOwnWorkSource ();
      }
      if (author != null && (author.value == null || author.value.length == 0)) {
        author.value = UploadForm.getOwnWorkAuthor ();
      }
      if (typeof (UploadForm_ownwork_date) == 'string'
          && UploadForm_ownwork_date.search (/\S/) >= 0) {
        var date = document.getElementById ('wpDate');
        if (date != null && (date.value == null || date.value.length == 0)) {
          date.value = UploadForm_ownwork_date;
        }
      }
    }
    if (previous_form != null) {
      setCheckBoxes
        (  previous_form
         , [  document.getElementById ('wpWatchthis')
            , document.getElementById ('wpIgnoreWarning')]);
    }     
    UploadFormFull.switch_intro_text ();    
    // If HotCat is present, restore its state, too.
    if (UploadForm.previous_hotcat_state != null && typeof (hotcat_set_state) == 'function') {
      var input = document.getElementById ('hotcat_text');
      if (input != null) hotcat_cancel ();
      UploadForm.previous_hotcat_state = hotcat_set_state (UploadForm.previous_hotcat_state);
    }
    
    UploadFormFull.set_hints ();
  }, // end setup
 
  get_desc_text : function (basic)
  {
    var desc_text = "";
    if (UploadFormFull.multi_inputs == null) {
      var desc = document.getElementById ('wpDesc');
      if (desc != null && !desc.disabled) desc_text = UploadForm.clean (desc.value);
    } else {
      for (var i = 0; i < UploadFormFull.multi_inputs.length; i++) {
        if (!UploadFormFull.multi_inputs[i].textfield.disabled) {
          var text     = UploadFormFull.multi_inputs[i].textfield.value;
          var selector = UploadFormFull.multi_inputs[i].selector;
          var lang     = selector.options[selector.selectedIndex].value;
          if (text != null && text.length > 0) {
            text = UploadForm.clean (text);
            if (desc_text.length > 0) desc_text = desc_text + '\n';
            if (!basic && lang != null && lang.length > 0 && lang != 'unknown') {
              // This is Commons-specific! The tl-template is already used, the template for
              // Tagalog is tgl!
              if (lang == 'tl') lang = 'tgl';
              
              //Wikiminicustom (lj): replaced following line by next one (we want a more readable output)
              //desc_text = desc_text + '\{\{' + lang + '|1=' + text + '\}\}';
              desc_text = desc_text + '  \{\{' + lang + '| ' + text + ' \}\}';
              
            } else
            
              //Wikiminicustom (lj): replaced following line by next one (we want a more readable output)
              //desc_text = desc_text + text;
              desc_text = desc_text + '  \{\{xx| ' + text + ' \}\}'; // (lj: I will create a "xx" template for unknown languages)
              
          }
        } // end if !disabled
      }
    }
    var more_info  = document.getElementById ('wpAdditionalInfo');
    if (!basic) {
      var src        = document.getElementById ('wpSource');
      var author     = document.getElementById ('wpAuthor');
      //Wikiminicustom (om)
      //var date       = document.getElementById ('wpDate');
      //var other      = document.getElementById ('wpPermission');
      //var othervers  = document.getElementById ('wpOtherVersions');
      
      //Wikiminicustom (lj): a few spaces and \n added in the next block (we want a more readable output) 
 
      desc_text = '\{\{Information\n\n'
                   + '|Description =\n'+ desc_text + '\n'
                   + '|Source = ' + (!src.disabled ? UploadForm.clean (src.value) : "") + '\n'
                   + '|Author = ' + (!author.disabled ? UploadForm.clean (author.value) : "") + '\n\n'
                   + '\}\}\n';
    } else {
      desc_text = desc_text + '\n';
    }
    // Append the additional info, if any
    if (more_info && !more_info.disabled && more_info.value)
      desc_text = desc_text + UploadForm.clean (more_info.value);
    return desc_text;
  },
 
  submit : function (evt)
  {
    var overwrite = UploadForm.isOverwrite ();
    if (!UploadFormFull.verify (overwrite)) return false;
 
    // Now put together an information-template
    var desc_text = UploadFormFull.get_desc_text (overwrite);
 
    var do_submit = true;
 
    var target_name = document.getElementById ('wpDestFile');
    if (target_name != null && target_name.value != null) // Strip whitespace
      target_name.value = target_name.value.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
 
    var dummy_desc = document.getElementById ('wpUploadDescription');
    // Sometimes, we do restore from scratch, and sometimes, the browser manages to keep everything.
    // If so, we may have a wpUploadDescription from an earlier submission. Remove it.
    if (dummy_desc != null) dummy_desc.parentNode.removeChild (dummy_desc);
 
    if (   typeof (FormRestorer) != 'undefined'
        && target_name != null && target_name.value != null) {
      var hotcat_state = null;
      if (typeof (hotcat_get_state) == 'function') {
        var input = document.getElementById ('hotcat_text');
        if (input != null) hotcat_closeform ();
        hotcat_state = hotcat_get_state ();
      }
      // We already know that target_name.value is set!
      FormRestorer.saveForm
        (  'UploadForm'
         , UploadForm.the_form.id
         , "" + UploadFormFull.form_type
           + '\t' + target_name.value
           + '\t' + UploadFormFull.field_state.wpSource.height
           + '\t' + UploadFormFull.field_state.wpAuthor.height
           + (hotcat_state != null ? '\t' + hotcat_state : '')
         , ';path=' + document.location.pathname
           + ';max-age=1800');
      // Expire after half an hour.
    }
 
    dummy_desc = document.createElement ('textarea');
    dummy_desc.setAttribute ('rows', '6');
    dummy_desc.setAttribute ('cols', '80');
    dummy_desc.style.display = 'none';
    dummy_desc.setAttribute ('name', 'wpUploadDescription');
    dummy_desc.setAttribute ('id', 'wpUploadDescription');
    UploadForm.the_form.appendChild (dummy_desc);
    dummy_desc.value = UploadForm.fixCategoryTransclusion (desc_text);
 
    do_submit = UploadForm.call_onsubmit (evt || window.event);
    if (!do_submit) {
      // Oops. We actually don't submit. Remove the hidden field
      UploadForm.the_form.removeChild (dummy_desc);
    } else {
      UploadForm.hidePreview ();
      document.getElementById ('wpDestFile').disabled = false;
      document.getElementById ('wpEditToken').disabled = false;
    }
    return do_submit;
  },
 
  preview : function (evt)
  {
    var overwrite = UploadForm.isOverwrite ();
    if (!UploadFormFull.verify (overwrite)) return false;
 
    UploadForm.makePreview (UploadFormFull.get_desc_text (overwrite), overwrite);
    return true;
  },
 
  verify : function (overwrite)
  {
    var src       = document.getElementById ('wpSource');
    var author    = document.getElementById ('wpAuthor');
    var date      = document.getElementById ('wpDate');
    var other     = document.getElementById ('wpPermission');
    var othervers = document.getElementById ('wpOtherVersions');
    var moreInfo  = document.getElementById ('wpAdditionalInfo');
    var ok        = true;
 
    if (!overwrite) {
      if (UploadForm.errorMsgs != null) delete UploadForm.errorMsgs;
      UploadForm.errorMsgs = new Array ();
      UploadForm.warning_pushed = false;
 
      if (!UploadForm.verifyMandatoryField
            (src,
             function (src)
             {
                var flickr_ok = !UFUI.isFromFlickr ||
                                src.search (/http:\/\/(www\.)?flickr\.com/) >= 0;
                if (!flickr_ok) UploadForm.errorMsgs.push ('wpFlickrURLError');
                return flickr_ok;
             }
            )
         ) 
      {
        src.onkeyup = UploadForm.resetBg;
        ok = false;
      }
      if (!UploadForm.verifyMandatoryField (author)) {
        author.onkeyup = UploadForm.resetBg;
        ok = false;
      }
      // Piece the description(s) together
      var all_descs = "";
      if (UploadFormFull.multi_inputs == null) {
        var desc = document.getElementById ('wpDesc');
        if (desc != null) all_descs = desc.value;
      } else {
        for (var input_idx = 0; input_idx < UploadFormFull.multi_inputs.length; input_idx++) {
          all_descs = all_descs + UploadFormFull.multi_inputs[input_idx].textfield.value;
        }
      }
      // License check
      var license_field = document.getElementById ('wpLicense');
      var license_chosen = license_field == null || license_field.selectedIndex > 0;
      if (!license_chosen && !UploadForm.has_license ([all_descs, other, moreInfo])) {
        if (!UploadForm.warning_pushed) {
          UploadForm.errorMsgs.push ('wpUploadWarningError');
          UploadForm.warning_pushed = true;
        }
        ok = false;
      }
      var target_name = document.getElementById ('wpDestFile');
      if (target_name != null) {
        // Trim leading and trailing whitespace
        target_name.value = target_name.value.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
        if (!UploadForm.verifyFileName (target_name.value)) {
          target_name.style.backgroundColor = UploadForm.errorColor;
          target_name.onkeyup =
            function (evt)
            {
              UploadForm.resetBg (evt);
              if (typeof (wgUploadWarningObj.keypress) == 'function' && !UploadForm.isReupload)
                wgUploadWarningObj.keypress();
            };
          ok = false;
        }
      }
      if (UploadForm.templates[0].desc_mandatory) {
        if (all_descs.search (/\S/) < 0) {
          if (UploadFormFull.multi_inputs == null) {
            var desc = document.getElementById ('wpDesc');
            if (desc != null) {
              desc.style.backgroundColor = UploadForm.errorColor;
              desc.onkeyup = UploadForm.resetBg;
            }
          } else {
            UploadFormFull.setMultiBg (UploadForm.errorColor, UploadFormFull.resetMultiBg);
          }
          UploadForm.errorMsgs.push ('wpNoDescriptionError');
          ok = false;
        }
      } // end description check
    } // end overwrite
    if (!ok) {
      UploadForm.hidePreview ();
      UploadForm.display_errors ();
    } else {
       // It's ok: hide our warning box
      var my_warning = document.getElementById ('wpUploadVerifyWarning');
      if (my_warning != null) my_warning.style.display = 'none';
    }
    return ok;
  },
 
  setMultiBg : function (color, handler)
  {
    if (UploadFormFull.multi_inputs == null) return;
    for (var i = 0; i < UploadFormFull.multi_inputs.length; i++) {
      var field = UploadFormFull.multi_inputs[i].textfield;
      field.style.backgroundColor = color;
      field.onkeyup               = handler;
    }
  },
 
  resetMultiBg : function (evt)
  {
    if (UploadForm.resetBg (evt)) {
      // Reset the backgrounds of all description fields
      UploadFormFull.setMultiBg ('#FFFFFF', null);
    }
  }
 
}; // end UploadFormFull
 
var UploadForm =
{
  isInstalled  : false, // Set to true when the onload hook runs
 
  debug        : false, // Can be set to true by adding "&debug=true" to the URL
 
  oldOnSubmit  : null,        // Possibly already existing onsubmit handler
  errorColor   : 'lightpink', // The light red from Template:Copyvio
  formModified : false,
 
  isReupload   : false,
 
  setup_hotcat_label : function ()
  {
    // If HotCat is present, translate its label if we can find it
    var hotcat_label_cell = document.getElementById ('hotcatLabel');
    if (hotcat_label_cell != null) {
      // Change its ID, just to be sure
      hotcat_label_cell.setAttribute ('id', 'hotcatLabelTranslated');
      // Assumes that the cell has only one child (which is normally the case)
      hotcat_label_cell.replaceChild
        (  UFUI.getLabel ('wpCategoriesUploadLbl')
         , hotcat_label_cell.firstChild);
    }
  },
 
  setup_error_display : function ()
  {
    var warning_cell = document.getElementById ('wpDestFile-warning');
    if (!warning_cell) return;
    var row      = warning_cell.parentNode;
    var new_cell = document.createElement ('td');
    new_cell.style.padding = '0';
    // Remove the colspan, if any, and insert a new cell to the left
    warning_cell.colspan = "";
    warning_cell.padding = '0';
    row.insertBefore (new_cell, warning_cell);
    UFUtils.convert_td_div (warning_cell);
  },
 
  set_fields_enabled : function (enabled, except)
  {
    // Enables or disables all named fields in the form, except those whose ids are
    // listed in except
    var skip    = except.join (' ');
    var elems   = UploadForm.the_form.elements;
    var changed = false;
    for (var i = 0; i < elems.length; i++) {
      if (elems[i].type == 'hidden') continue; // Don't fool around with hidden elements
      var id = elems[i].id;
      if (!id || id.length == 0) id = elems[i].name;
      if (id && id.length > 0) {
        if (skip.indexOf (id) < 0) {
          if (elems[i].disabled != !enabled) {
            changed = true;
            if (elems[i].type == 'text' || elems[i].type == 'textarea') {
              // Set the background. Actually, I'd like to just reset it to whatever the
              // default was, but setting it to null doesn't do anything in IE6... We
              // force a light gray for disabled fields since IE6 doesn't have a real
              // visual "disabled" indicator for input fields.
              try {
                elems[i].style.backgroundColor = (enabled ? '#FFFFFF' : '#EEEEEE');
              } catch (some_error) {
                // Swallow
              }
            }
            elems[i].disabled = !enabled;
          }
        }
      }
    }
    if (changed) {
      // Clear warning messages. If we disabled fields, they're obsolete; if we enabled fields,
      // new warnings will be generated upon submit if necessary.
      var my_warning = document.getElementById ('wpUploadVerifyWarning');
      if (my_warning != null) my_warning.style.display = 'none';
    }
  },
 
  previous_hotcat_state : null,
 
  getPrevValue : function (stored_form, element_id)
  {
    // Return a field's previous value, if known
    if (   stored_form == null || stored_form.length <= 1
        || element_id == null || element_id.length == 0)
      return null;
    for (var i = 1; i < stored_form.length; i++) {
      if (stored_form[i] != null && element_id == stored_form[i].id)
        return stored_form[i].val;
    }
    return null;
  },
 
  license_button          : null,
  license_button_shown    : false,
  current_license_preview : '&nbsp;',
 
  get_license_preview : function () // Tooltip callback
  {
    var div = document.createElement ('div');
    div.style.display = 'none';
    document.body.appendChild (div);
    div.innerHTML = UploadForm.current_license_preview;
    document.body.removeChild (div);
    div.style.fontSize = 'smaller';
    div.style.display  = "";
    var wrapper = document.createElement ('div');
    wrapper.appendChild (div);
    return wrapper;
  },
 
  create_license_button : function ()
  {
    // Will be called only from our rewritten wgUploadLicenseObj.showPreview, i.e.
    // we *know* that we *do* have Tooltips and Buttons here.
    var previewButton =
      UploadForm.customFormButton
        (  'wpUploadFormPreviewLicenseButton' // Customization ID
         , 'wpUploadPreviewLicense'           // ID of button
         , null                               // Default text
         , null                               // Event handler, will be set below
         , 'wpPreviewLicenseUploadLbl'        // default label ID
          );
    var tooltip =
      new Tooltip
        (  previewButton
         , UploadForm.get_license_preview
         , { activate     : Tooltip.CLICK
            ,deactivate   : (UFHelp.help_close_imgs
                             ? Tooltip.CLICK_ELEM
                             : Tooltip.CLICK_TIP|Tooltip.CLICK_ELEM|Tooltip.LOSE_FOCUS)
            ,close_button : UFHelp.help_close_imgs
            ,mode         : Tooltip.FIXED
            ,anchor       : Tooltip.TOP_LEFT
            ,fixed_offset : {x:10, y: 5, dy: -1}
            ,open_delay   : 0
            ,hide_delay   : 0
           }
         , UFHelp.tooltip_styles
        );                            
    UploadForm.license_button = previewButton;
  },
 
  setup_license_preview : function ()
  {
    var preview_panel = document.getElementById ('mw-license-preview');
    if (preview_panel != null) UFUtils.convert_td_div (preview_panel);
    // Change the license previewer to not overwrite our warning message, if any.
    if (   typeof (wgUploadLicenseObj) != 'undefined'
        && typeof (wgUploadLicenseObj.showPreview) != 'undefined'
        && typeof (Tooltip) != 'undefined') {
 
      wgUploadLicenseObj.showPreview = 
        function (preview)
        {
          var preview_panel = document.getElementById ('mw-license-preview');
          if (preview_panel == null) return;
          if (preview == UploadForm.current_license_preview) return;
 
          UploadForm.current_license_preview = preview;
          var contents = null;
          var new_state = false;
          if (!preview || preview.length == 0 || preview == '&nbsp;') {
            contents = document.createTextNode ('\xa0'); // a single &nbsp;
            new_state = false;
          } else {
            if (!UploadForm.license_button) {
              UploadForm.create_license_button ();
            }
            if (!UploadForm.license_button_shown)
              contents = UploadForm.license_button;
            new_state = true;
          }
          if (contents && new_state != UploadForm.license_button_shown) {
            if (preview_panel.firstChild)
              preview_panel.replaceChild (contents, preview_panel.firstChild);
            else
              preview_panel.appendChild (contents);
          }
          UploadForm.license_button_shown = new_state;
        }; // end function
    }
  },
 
  preview_tooltip : null, // Tooltip, if preview so configured
  do_preview      : null, // Function to call to actually generate the preview
 
  addPreviewButton : function (handler)
  {
    // If we don't have Ajax, our preview won't work anyway.
    if (!window.XMLHttpRequest && !window.ActiveXObject) return;
 
    var uploadButton = document.getElementsByName ('wpUpload')[0]; // Has no ID...
    // If we can't find the upload button, we don't know where to insert the preview button.
    if (uploadButton == null) return;
 
    try {
      var previewButton =
        UploadForm.customFormButton
          (  'wpUploadFormPreviewButton' // Customization ID
           , 'wpUploadPreview'           // ID of button
           , null                        // Default text
           , UploadForm.generatePreview  // Event handler
           , 'wpPreviewUploadLbl'        // default label ID
          );
      if (   UploadForm_page_preview_in_tooltip
          && typeof (Tooltip) != 'undefined') {
        UploadForm.preview_tooltip =
          new Tooltip (  previewButton
                       , UploadForm.getPreview
                       , {  activate     : Tooltip.NONE // We'll show it manually in generatePreview.
                          , deactivate   : Tooltip.CLICK_TIP
                          , close_button : UFHelp.help_close_imgs
                          , mode         : Tooltip.FIXED
                          , target       : uploadButton
                          , anchor       : Tooltip.TOP_LEFT
                          , fixed_offset : {x:0, y: 5, dy:-1}
                          , open_delay   : 0
                          , hide_delay   : 0
                         }
                       , UFHelp.tooltip_styles
                      );
      }
      UploadForm.do_preview = handler;
      previewButton.setAttribute ('style', 'margin-left: 0.5em;');
      var hotKey = 'p';
      previewButton.setAttribute ('accesskey', hotKey);
      if (mw && mw.util) {
        if (!(/\[\w+\]$/.test(previewButton.title))) previewButton.title += ' [' + hotKey + ']';
        mw.util.updateTooltipAccessKeys([previewButton]);
      }
      uploadButton.parentNode.insertBefore (previewButton, uploadButton.nextSibling);
    } catch (ex) {
    }
  },
 
  getOwnWorkAuthor : function ()
  {
    if (   typeof (UploadForm_ownwork_author) == 'string'
        && UploadForm_ownwork_author.search (/\S/) >= 0) {
      // It's a non-empty string
      return UploadForm_ownwork_author;
    } else {
      return '\[\[User:' + mw.config.get('wgUserName') + '|' + mw.config.get('wgUserName') + '\]\]';
    }
  },
 
  getOwnWorkSource : function ()
  {
    var text   = UFUI.getLabel ('wpOwnWorkUploadLbl', true);
    var result = null;
    try {
      // Must have a text node. IE6 doesn't know Node.TEXT_NODE...
      while (text && text.nodeType != 3) text = text.firstChild;
      if (text) result = text.data.replace (/^\s+/, "").replace (/\s+$/, "");
    } catch (ex) {
      result = null;
    }
    if (!result) result = 'Own work by ' + UploadForm.getOwnWorkAuthor ();
    return result;
  },
 
  customFormButton : function (ui_id, id, default_text, handler, default_id)
  {
    function getButtonSpan (container, idx)
    {
      if (!container) return null;
      var spans = container.getElementsByTagName ('span');
      var span  = null;
      if (!spans || spans.length <= idx) {
        // No spans... if idx is zero, try simply to take the first text node within container.
        if (idx == 0) span = container;
      } else {
        span = spans[idx];
      }
      // Ok, let's see if we have some text... IE6 doesn't know Node.TEXT_NODE!
      while (span && span.nodeType != 3) span = span.firstChild;
      if (span) return span.data.replace (/^\s+/, "").replace (/\s+$/, "");
      return null;
    }
 
    function getDefault (default_text, default_id)
    {
      if (!default_text) {
        if (default_id) {
          var default_text = UFUI.getLabel (default_id, true);
          // Must have a text node
          while (default_text && default_text.nodeType != 3) // IE6 doesn't know Node.TEXT_NODE
            default_text = default_text.firstChild;
          if (default_text)
            default_text = default_text.data.replace (/^\s+/, "").replace (/\s+$/, "");
        } else
          default_text = 'X'; // Hmmm... a serious misconfiguration
      }
      return default_text;
    }
 
    var button = null, imgs = null;
    button = UFUI.getEntry (ui_id, 'uiElements', UFUI.internalLanguage);
    if (!button) button = UFUI.getEntry (ui_id, 'uiElements');
    if (button) imgs = button.getElementsByTagName ('img');
    if (!imgs || imgs.length == 0 || typeof (Buttons) == 'undefined') {
      var buttonText = null;
      var buttonText = getButtonSpan (button, 0);
      if (!buttonText) buttonText = getDefault (default_text, default_id);
      var alternateText = getButtonSpan (button, 1);
      button = document.createElement ('input');
      button.setAttribute ('id', id);
      button.setAttribute ('name', id);
      button.type    = 'button';
      button.value   = buttonText;
      if (alternateText) button.title   = alternateText;
      button.onclick = handler;
    } else {
      button = Buttons.makeButton (imgs, id, handler);
    }
    return button;
  },
 
  the_form : null,
 
  // If a needed script that is included hasn't loaded yet, we try at most install_max_attempts
  // times install_delay. If it then still has not loaded, we install all the same, and the
  // setup routine will have to deal with it. (Note that script loading is asynchronous!)
  install_delay        : 500, // Milliseconds
  install_attempts     : 0,
  install_max_attempts : 5,   // Five times: maximum delay 2.5s
 
  really_install : function (force_basic)
  {
    UploadForm.install_attempts++;
    if (UploadForm.install_attempts <= UploadForm.install_max_attempts &&
        (   typeof (LanguageHandler) == 'undefined'
         || typeof (UIElements) == 'undefined'
         || typeof (Tooltips) == 'undefined')) {
      // Add needed scripts in the condition above.
      window.setTimeout (function() {
        UploadForm.really_install(force_basic);
      }, UploadForm.install_delay);
    } else {
      UFUI.sanitizeUserLanguage ();
      var use_basic = force_basic || !!UploadForm_forcebasic || UFUI.isExperienced;
      if (use_basic && !force_basic) {
        // Only for autoconfirmed users!
        var is_auto = false;
        for (var i = 0; i < wgUserGroups.length && !is_auto; i++)
          is_auto = wgUserGroups[i] == 'autoconfirmed';
        if (!is_auto) use_basic = false;
      }
      try {
        UFHelp.precreate_tooltip_closer ();
        UploadForm.setFileExtensions ();
        if (   use_basic
            || document.URL.indexOf ('uploadformstyle=basic') >= 0
            || document.URL.search (/uselang\=(\w|-)*fromwikimedia/) >= 0) {
          // The fromwikimedia forms are special enough to warrant a special setup.
          UploadFormBasic.setup (!force_basic);
        } else {
          UploadFormFull.setup ();
        }
        UploadForm.setup_error_display ();
        UploadForm.setup_hotcat_label ();
        UFHelp.setupHelp (UploadForm.isReupload);
        if (!UploadForm.isReupload) UFFixes.fixAutocompletion ();
        UploadForm.setupOverwriteMsg ();
        // Handle the "Upload new version" links, these have &wpDestFile=... in the URL, which
        // defeats overwrite detection. Because someone might construct such a URL manually
        // *not* actually overwriting an existing file, we still do the check:
        if (!UploadForm.isReupload) UploadForm.check_initial_dest_file (); 
      } catch (ex) {
        // Not good at all. Something went badly wrong. If we have already modified the form,
        // the best thing is probably to reload and make sure we don't try again:
        if (UploadForm.formModified) {
          var reload_url = document.URL;
          reload_url = reload_url
                     + ((reload_url.indexOf ('?') >= 0) ? '&' : '?')
                     + 'uploadformstyle=plain';
          window.location.href = reload_url;
        }
      }
    }
  },
 
  install : function ()
  {
    if (UploadForm.isInstalled) return; // Do this only once per page!
    UploadForm.isInstalled = true;
 
    if (document.URL.indexOf ('uploadformstyle=plain') >= 0) return; // We're disabled
 
    // Also don't do anything if we're not on an upload form.
    if (mw.config.get('wgCanonicalNamespace') != 'Special' || mw.config.get('wgCanonicalSpecialPageName') != 'Upload') return;         
    var form =    document.getElementById ('upload')
               || document.getElementById ('mw-upload-form');
    var original_desc = document.getElementById ('wpUploadDescription');
    if (!form || !original_desc) return; // Oops. Not good: bail out; don't do anything.
 
    var reupload = document.getElementById ('wpForReUpload');
    var destFile = document.getElementById ('wpDestFile');
    if (reupload)
      UploadForm.isReupload = !!reupload.value;
    else {
      UploadForm.isReupload = destFile && (destFile.disabled || destFile.readOnly);
    }
    if (destFile && !!destFile.disabled) {
      destFile.readOnly = true;
      destFile.disabled = false;
    }
    if (destFile && UploadForm.isReupload) {
      destFile.onkeyup = function (evt) {};
      destFile.onchange = function (evt) {};
    }
    // Use the basic form if the description was set *initially*, or if it's a re-upload, or if it's a special
    // form
    var use_basic =
         (original_desc.defaultValue != null && original_desc.defaultValue.length > 0)
      || UploadForm.isReupload
      || document.URL.indexOf ('uselang=nlwikilovesmonuments') > 0
    ;
 
    UploadForm.the_form = form;
    if (document.URL.indexOf ('debug=true') >= 0) UploadForm.debug = true;
    UploadForm.really_install (use_basic);
  },
 
  check_initial_dest_file : function ()
  {
    var dest_file = document.getElementById ('wpDestFile');
    if (   dest_file && dest_file.value && dest_file.value.length > 0
        && wgUploadWarningObj && typeof (wgUploadWarningObj.keypress) == 'function')
    {
      wgUploadWarningObj.keypress();
    }
  },
 
  errorMsgs      : null,
  warning_pushed : false,
 
  display_errors : function ()
  {
    // Give user feedback about what is not ok.      
    var my_warning = document.getElementById ('wpUploadVerifyWarning');
    if (my_warning == null) {
      // Find the upload button
      var uploadButton = document.getElementsByName ('wpUpload');
      var warningBox   = null;
      if (uploadButton) uploadButton = uploadButton[0];
      if (!uploadButton) {
        warningBox = document.getElementById ('wpDestFile-warning');
        if (!warningBox) return; // We just have the field colors to indicate errors...
      }
      my_warning = document.createElement ('div');
      my_warning.style.border = '1px #FF0000 solid';
      my_warning.style.backgroundColor = UploadForm.errorColor;
      my_warning.style.padding = '0.5em';
      my_warning.style.marginTop = '0.5em';
      my_warning.style.marginBottom = '0.5em';
      my_warning.setAttribute ('id', 'wpUploadVerifyWarning');
      my_warning.setAttribute ('width', '100%');
      my_warning.style.display = 'none';
      if (uploadButton) {
        uploadButton.parentNode.insertBefore (my_warning, uploadButton);
      } else {
        warningBox.parentNode.insertBefore (my_warning, warningBox.nextSibling);
      }
    }
    // Now collect all the error messages into one div.
    var msgs = document.createElement ('ul');
    msgs.style.paddingLeft = '1.0em';
    msgs.style.marginLeft = '0';
    for (var i = 0; i < UploadForm.errorMsgs.length; i++) {
      var msg = UFUI.getErrorMsg (UploadForm.errorMsgs[i]);
      if (msg) {
        var li = document.createElement ('li');
        li.appendChild (msg);
        msgs.appendChild (li);
      }
    }
    delete UploadForm.errorMsgs;
    UploadForm.errorMsgs = null;
    // And then display the messages
    if (my_warning.firstChild != null)
      my_warning.replaceChild (msgs, my_warning.firstChild);
    else
      my_warning.appendChild (msgs);
    my_warning.style.display = 'block';
  },
 
  call_onsubmit : function (evt)
  {
    var do_submit = true;
    if (UploadForm.oldOnSubmit != null) {
      if (typeof UploadForm.oldOnSubmit == 'string')
        do_submit = eval (UploadForm.oldOnSubmit);
      else if (typeof UploadForm.oldOnSubmit == 'function')
        do_submit = UploadForm.oldOnSubmit (evt);
    }
    return do_submit;
  },
 
  templates: [
   {name          : 'information',
    fields        : ['Description', 'Source', 'Author'],
    extract       : [3, 1, 0],    
    desc_mandatory: true,
    regexp        : null
   },
   {name          : 'painting',
    fields        : ['Artist', 'Title', 'Year', 'Technique', 'Dimensions', 'Gallery',
                     'Location', 'Notes', 'Source', 'Permission',
                     'other_versions', 'Other versions'],
    extract       : [0, 8, 7],    
    desc_mandatory: false,
    regexp        : null
   },
   {name          : 'flickr',
    fields        : ['description', 'flickr_url', 'title', 'taken', 'photographer_url',
                     'photographer', 'photographer_location', 'reviewer', 'permission'],
    extract       : [new Array (5, 4), 1, 0],    
    desc_mandatory: true,
    regexp        : null
   }
  ],
 
  empty_template : function (name)
  {
    if (name == null) return null;
    var test_name = name.toLowerCase ();
    for (var i = 0; i < UploadForm.templates.length; i++) {
      if (UploadForm.templates[i].name == test_name) {
        var result = '\{\{' + name;
        for (var j = 0; j < UploadForm.templates[i].fields.length; j++) {
          result = result + '\n|' + UploadForm.templates[i].fields[j] + '=';
          if (UFUI.isOwnWork && i == 0) {
            // Pre-fill some fields if we're on an own-work form and it's an
            // information-template
            switch (j) {
              case 1: // Source-field
                result = result + UploadForm.clean (UploadForm.getOwnWorkSource ());
                break;
              case 2: // Date
                if (typeof (UploadForm_ownwork_date) == 'string'
                    && UploadForm_ownwork_date.search (/\S/) >= 0) {
                  result = result + UploadForm.clean (UploadForm_ownwork_date);
                }
                break;
              case 3: // Author
                result = result + UploadForm.clean (UploadForm.getOwnWorkAuthor ());
                break;
              default:
                break;
            } // end switch
          } // end if information for ownWork
        }
        return result + '\n\}\}';
      }
    }
    return null;
  },
 
  extract_fields : function (desc, template_idx, list)
  {
    function get (desc, field, regexp)
    {
      var match_start = new RegExp ('\\n\\s*\\| *' + field + ' *\\=');
      var start = desc.match (match_start);
      if (start == null) return null;
      var rest = desc.substring (start.index + start[0].length);
      var end = rest.search (regexp);
      if (end < 0) return rest;
      return rest.substring (0, end);
    }
 
    var result  = list;
    var names   = UploadForm.templates[template_idx].fields;
    var extract = UploadForm.templates[template_idx].extract;
    if (UploadForm.templates[template_idx].regexp == null) {
      // Build the regexp
      var regexp_str = '\\n\\s*(\\| *(' + names.join ('|') + ') *\\=|\\}\\})';
      UploadForm.templates[template_idx].regexp = new RegExp (regexp_str);
    }
    for (var i = 0; i < extract.length; i++) {
      var txt = null;
      if (extract[i].constructor == Array) {
        // It's an array giving alternatives...
        var alternatives = extract[i];
        for (var j = 0; j < alternatives.length; j++) {
          txt = get (desc, names [alternatives[j]], UploadForm.templates[template_idx].regexp);
          if (txt != null && txt.search (/\S/) >= 0) break; // Non-empty: don't look further
          txt = null;
        }
      } else {
        txt = get (desc, names [extract[i]], UploadForm.templates[template_idx].regexp);
      }
      if (txt != null) result[result.length] = txt; // Push one.
      // Don't use "if (txt)", it's false if the string is != null, but empty!
    }
    return result;
  },
 
  split_description : function (desc)
  {
    if (desc == null || desc.length == 0) return null;
    // Returns an array containing (in that order):
    // index of template, author, source, description
    for (var i = 0; i < UploadForm.templates.length; i++) {
      var regexp = new RegExp ('\\{\\{' + UploadForm.templates[i].name + '\\s*(\\||\\n)');
      var start = desc.toLowerCase ().search (regexp);
      if (start >= 0) {
        var result = new Array (1);
        result[0] = i;
        // Now try to extract the fields:
        return UploadForm.extract_fields (desc.substring (start), i, result);
      }
    }
    return null;
  },
 
  generatePreview : function (evt)
  {
    if (   UploadForm.preview_tooltip
        && UploadForm.preview_tooltip.popup.style.display != 'none'
        && UploadForm.preview_tooltip.popup.style.display != null) {
      UploadForm.preview_tooltip.hide_now (null);
    } else {
      UploadForm.do_preview (evt || window.event);
    }
  },
 
  outerHTML : function (node)
  {
    if (!node) return "";
    if (node.nodeType == 3) return node.nodeValue; // Text node
    if (node.outerHTML) return node.outerHTML;
    var div = document.createElement ('div');
    div.style.display    = 'none';
    div.style.position   = 'absolute';
    div.appendChild (node);
    document.body.appendChild (div);
    var txt = div.innerHTML;
    document.body.removeChild (div);
    return txt;
  },
 
  makePreview : function (description, is_overwrite)
  {
    if (is_overwrite) {
      UploadForm.showPreview (
          '\<div style="border:1px solid red; padding:0.5em;"\>'
        + '\<div class="previewnote"\>'
        + UploadForm.outerHTML (UFUI.getErrorMsg ('wpPreviewOverwriteError'))
        + '\<\/div\>'
        + '\<\/div\>'
      );
    } else {
      var text = '\<div style="border:1px solid red; padding:0.5em;"\>\n'
               + '\<div class="previewnote"\>\n'
               + '\{\{MediaWiki:Previewnote/' + UFUI.userLanguage +'\}\}\n'
               + '\<\/div>\n';
      var license = document.getElementById ('wpLicense');
      var license_text = null;
      if (   license != null && license.selectedIndex > 0
          && license.options[license.selectedIndex].value.length > 0) {
        license_text = '\{\{' + license.options[license.selectedIndex].value + '\}\}';
      }
      if (license_text) {
		  
		// Wikiminicustom (lj): added two \n in the following block (we want a more readable output)
		
		  
        text = text
             + '\<h2\>\{\{int:filedesc\}\}\<\/h2\>\n\n'
             + description + '\n'
             + '\<h2\>\{\{int:license-header\}\}\<\/h2\>\n\n'
             + license_text;
      } else {
        text = text + description + '\n';
      }
      // Add categories
      if (typeof (hotcat_get_state) == 'function') {
        var input = document.getElementById ('hotcat_text');
        if (input != null) hotcat_closeform ();
        var hotcat_categories = hotcat_get_state ();
        if (hotcat_categories && hotcat_categories.length > 0) {
          hotcat_categories = hotcat_categories.split ('\n');
          for (var i=0; i < hotcat_categories.length; i++) {
            if (hotcat_categories[i] && hotcat_categories[i].length > 0)
              text = text + '[[Category:' + hotcat_categories[i] + ']]';
          }
        }
      }
      text = text + '\<\/div\>';
 
      // Make the Ajax call
      var req;
      if (window.XMLHttpRequest) req = new window.XMLHttpRequest();
      if (!req && window.ActiveXObject) {
        try {
          req = new window.ActiveXObject('Microsoft.XMLHTTP');
        } catch (any) {}
      }
      if (!req) return;
      var button = document.getElementById ('wpUploadPreview');
      var page   = document.getElementById ('wpDestFile');
      if (page) page = page.value;
      if (page != null && page.length == 0) page = null;
      if (button && typeof (injectSpinner) == 'function')
        injectSpinner (button, 'wpUploadPreviewSpinner');
      var uri  = wgServer + wgScriptPath + '/api.php';
      var args = 'action=parse&pst&text=' + encodeURIComponent (text)
               + (page ? '&title=File:' + encodeURIComponent (page.replace (/ /g, '_')) : "")
               + '&prop=text|categories&format=json';
      // "&pst" is "Pre-save transform": tilde replacement, pipe magic for links like [[foo|foo]].
      // Don't use a callback directly, add the function call ourselves *after* the call, since
      // the API somehow resolves tildes to an IP number instead of the username if a callback
      // is used. C.f. https://bugzilla.wikimedia.org/show_bug.cgi?id=16616
      // Apparently, that's a feature, not a bug...
      var request_length = uri.length + args.length + 1;
      if (request_length > 2000) {
        // Long URLs are problematic for GET requests
        req.open ('POST', uri, true);
        req.setRequestHeader ('Content-Type', 'application/x-www-form-urlencoded');
      } else {
        uri += '?' + args; args = null;
        req.open ('GET', uri, true);
      }
      req.setRequestHeader ('Pragma', 'cache=no');
      req.setRequestHeader ('Cache-Control', 'no-transform');
      req.onreadystatechange =
        function ()
        {
          if (req.readyState != 4) return;
          if (typeof (removeSpinner) == 'function') removeSpinner ('wpUploadPreviewSpinner');
          if (req.status != 200) return;
          // Add the "callback"...
          if (req.responseText && req.responseText.indexOf ('{') == 0)
            // Primitive sanity check. If the response text does *not* start with '{', it might have been
            // spoofed and contain a function call... of course, this simple check cannot catch more
            // elaborate spoof attempts.
            eval ('UploadForm.jsonPreview (' + req.responseText + ')');
        };
      req.send (args);
    }
  },
 
  jsonPreview : function (result)
  {
    if (result && result.parse && result.parse.text && result.parse.text['*'] != null) {
      var txt = result.parse.text['*'];
      var categories = result.parse.categories;
      if (categories && categories.length > 0) {
        // Add a mock-up of a category bar. We don't care about non-existing categories, and we
        // can't identify hidden categories.
        var catbar = '<div class="catlinks"><div id="mw-normal-catlinks">'
                   + UploadForm.outerHTML (UFUI.getLabel ('wpCategoriesUploadLbl'));
        categories.sort (
          function (a, b) {
            var key_a = a['*'].toLowerCase (), key_b = b['*'].toLowerCase ();
            if (key_a < key_b) return -1;
            if (key_a > key_b) return 1;
            return 0;
          }
        );
        for (var i = 0; i < categories.length; i++) {
          var catname = categories[i]['*'];
          if (catname && catname.length > 0) {
            if (i > 0) catbar += ' |';
            catbar += ' <a href="/wiki/Category:' + encodeURI (catname) + '">'
                      + catname.replace(/_/g, ' ') + '</a>';
          }
        }
        catbar += '</div></div>';
        // Now insert it into text.
        var end = txt.lastIndexOf ('</div>');
        txt = txt.substring (0, end) + catbar + '</div>';
      }
      UploadForm.showPreview (txt);
    }
  },
 
  showPreview : function (result)
  {
    if (UploadForm.preview_tooltip) {
      UploadForm.preview_content = result;
      UploadForm.preview_tooltip.show_tip (null, false);
    } else {
      var preview = document.getElementById ('wpUploadPreviewDisplay');
      if (preview == null) {
        var before = document.getElementById ('mw-upload-permitted');
        if (!before || UFUtils.isChildOf (before, UploadForm.the_form))
          before = UploadForm.the_form;
        if (!before) return; // Don't know where to insert preview display. Error message here?
        preview = document.createElement ('div');
        preview.setAttribute ('id', 'wpUploadPreviewDisplay');
        before.parentNode.insertBefore (preview, before);
      }
      try {
        preview.innerHTML = result;
      } catch (ex) {
        preview.innerHTML = ""; // Error message here instead?
      }
      preview.style.display = ""; // Show it 
    }
  },
 
  hidePreview : function ()
  {
    if (UploadForm.preview_tooltip)
      UploadForm.preview_tooltip.hide_now (null);
    else {
      var preview = document.getElementById ('wpUploadPreviewDisplay');
      if (preview) preview.style.display = 'none';
    }
  },
 
  getPreview : function () // Callback for the tooltip
  {
    var div = document.createElement ('div');
    div.style.display = 'none';
    document.body.appendChild (div);
    div.innerHTML = UploadForm.preview_content;
    document.body.removeChild (div);
    div.style.fontSize = 'smaller';
    div.style.display = "";
    var wrapper = document.createElement ('div');
    wrapper.appendChild (div);
    return wrapper;
  },
 
  licenses_regexp     :
    /\{\{(self|pd|gfdl|cc|l?gpl|fal|cecill|attribution|copyrighted free use|SOlicence|geograph|UN map|BArch-License|Apache)/i,
  user_license_regexp :
    new RegExp (  '\\{\\{[Ss]ubst:[Uu]ser:'
                + (mw.config.get('wgUserName') || "null").replace(/([\\\^\$\.\?\*\+\(\)\[\]\|\{\}])/g, "\\$1")
                + '/'),
 
  has_license : function (fields)
  {
    if (fields == null || fields.length == 0) return false;
    for (var i = 0; i < fields.length; i++) {
      if (fields[i] != null) {
        if (typeof (fields[i]) == 'string') {
          if (fields[i].search (UploadForm.licenses_regexp) >= 0) return true;
        } else {
          if (fields[i].value.search (UploadForm.licenses_regexp) >= 0) return true;
        }
      }
    }
    for (var j = 0; j < fields.length; j++) {
      if (fields[j] != null) {
        if (typeof (fields[j]) == 'string') {
          if (fields[j].search (UploadForm.user_license_regexp) >= 0) return true;
        } else {
          if (fields[j].value.search (UploadForm.user_license_regexp) >= 0) return true;
        }
      }
    }
    return false;
  },
 
  addAfterField : function (elem_id, element)
  {
    if (!element) return;
    var elem = document.getElementById (elem_id);
    if (!elem) return;
    // Find enclosing table cell.
    while (elem && elem.nodeName.toLowerCase () != 'td') elem = elem.parentNode;
    if (!elem) return;
    var container = document.createElement ('div');
    container.style.fontSize = 'smaller';
    container.style.color = '#808080'; /* Wikiminicustom (lj) */
    container.appendChild (element);
    elem.appendChild (container);
  },
 
  old_overwrite_warning : null,
 
  setupOverwriteMsg : function ()
  {
    if (   typeof (wgUploadWarningObj) == 'undefined'
        || typeof (wgUploadWarningObj.setWarning) == 'undefined')
      return;
    var msg = document.createElement ('div');
    msg.id = 'wpUploadFormScriptOverwriteWarning';
    msg.style.display = 'none';
    msg.style.color = 'red';
    msg.appendChild (UFUI.getErrorMsg ('wpPreviewOverwriteError'));
    UploadForm.addAfterField ('wpDestFile', msg);
    UploadForm.old_overwrite_warning = wgUploadWarningObj.setWarning;    
    wgUploadWarningObj.setWarning = UploadForm.overwriteMsg;
  },
 
  overwriteMsg : function (warning)
  {
    if (!UploadForm.old_overwrite_warning || UploadForm.isReupload) return;
    // Make sure that 'this' is set to 'wgUploadWarningObj' in the call below!
    UploadForm.old_overwrite_warning.apply (wgUploadWarningObj, [warning]);
    var is_overwrite = UploadForm.isOverwrite ();
    var my_overwrite_warning = document.getElementById ('wpUploadFormScriptOverwriteWarning');
    if (my_overwrite_warning) {
      my_overwrite_warning.style.display = (is_overwrite ? "" : 'none');
    }
    UploadForm.set_fields_enabled
      (!is_overwrite
       , [  'wpUploadFile', 'wpDestFile', 'wpUploadDescription', 'wpAdditionalInfo'
          , 'wpLicense', 'wpWatchthis', 'wpIgnoreWarning', 'wpUpload']
      );
  },
 
  isOverwrite : function ()
  {
    if (document.getElementById ('wpUploadWarningFileexists') != null) return true;
    var destfile_warning = document.getElementById ('wpDestFile-warning');
    if (destfile_warning == null) return false;
    var dest_file = document.getElementById ('wpDestFile');
    if (dest_file == null || dest_file.value == null || dest_file.value.length == 0) return false;
    var lks = destfile_warning.getElementsByTagName ('a');
    if (lks == null || lks.length == 0) return false;
 
    var fn1 =
      dest_file.value.replace(/^\s\s*/, '').replace(/\s\s*$/, '').replace(/ /g, '_');
    fn1     = fn1.substr (0, 1).toUpperCase () + fn1.substring (1);
    var fn0 = 'Image:' + fn1;
    fn1     = 'File:' + fn1;
    // Trimmed, blanks replaced by underscores, first character capitalized
 
    for (var i = 0; i < lks.length; i++) {
      var href = lks[i].getAttribute ('href', 2);
      if (href.indexOf (wgScript) == 0 || href.indexOf (wgServer + wgScript) == 0) {
        var m = /[&?]title=([^&]*)/.exec (href);
        if (m && m.length > 1) href = m[1]; else href = null;
      } else {
        var prefix = wgArticlePath.replace ('$1', "");
        if (href.indexOf (prefix) != 0) prefix = wgServer + prefix; // Fully expanded URL?
        if (href.indexOf (prefix) == 0) href = href.substring (prefix.length); else href = null;
      }
      if (!href) continue;
      href = decodeURIComponent (href).replace (/ /g, '_');
      if (href == fn0 || href == fn1) return true;
    }
    return false;
  },
 
  allowedFileTypes : null,
  forbiddenFileTypes : null,
 
  badFileNames : /^(test|image|img|bild|example|(dsc|img)?(\s|_|-)*|\d{10}(\s|_|-)[0123456789abcdef]{10}(\s|_|-)[a-z])$/i,
  // Filenames that have only components (separated by periods) that fully match this regexp
  // are considered illegal. The second-but-last one catches DSC01234, or DSC_01234, or
  // DSC_012_34 or also filenames conatining only digits and non-alphanumeric characters.
  // The last catches Flickr's raw filenames. How to relax that last expression without catching
  // too many legit file names?
  // Matching is case-insensitive.
 
  extractFileExtensions : function (div, list)
  {
    var list = null;
    // Get a mw-upload-permitted or mw-upload-prohibited div, extracts all extensions listed
    var txt = div;
    while (txt && txt.nodeType != 3) txt = txt.lastChild;
    if (!txt) return null;
    // Try to figure out which comma to use (localizeable through MediaWiki:Comma-separator!)
    if (txt.data.indexOf (',') >= 0) // Standard
      txt = txt.data.split (',');
    else if (txt.data.indexOf ('،') >= 0) // Arabic etc.
      txt = txt.data.split ('،');
    else if (txt.data.indexOf ('、') >= 0) // Chinese
      txt = txt.data.split ('、');
    else
      return null;
    if (!txt || txt.length == 0) return null;
    for (var i = 0; i < txt.length; i++) {
      var match = /(\w+)\W*$/.exec (txt[i]);
      if (match) {
        match = match[1].toLowerCase (); // The extension
        if (list == null) list = {};
        list[match] = true;
      }
    }
    return list;
  },
 
  setFileExtensions : function ()
  {
    if (typeof (mw.config.get('wgFileExtensions')) != 'undefined' && mw.config.get('wgFileExtensions').length) { // New as of 2009-09-17
      UploadForm.allowedFileTypes = {};
      for (var i = 0; i < mw.config.get('wgFileExtensions').length; i++) {
        UploadForm.allowedFileTypes[mw.config.get('wgFileExtensions')[i]] = true;
      }
      UploadForm.forbiddenFileTypes = null;
      return;
    }
 
    UploadForm.allowedFileTypes =
      UploadForm.extractFileExtensions (document.getElementById ('mw-upload-permitted'));
    UploadForm.forbiddenFileTypes =
      UploadForm.extractFileExtensions (document.getElementById ('mw-upload-prohibited'));
    if (UploadForm.allowedFileTypes != null) {
      // Alternate OGG extensions
      if (UploadForm.allowedFileTypes.ogg) {
        if (UploadForm.forbiddenFileTypes == null || !UploadForm.forbiddenFileTypes.ogv)
          UploadForm.allowedFileTypes.ogv = true;
        if (UploadForm.forbiddenFileTypes == null || !UploadForm.forbiddenFileTypes.oga)
          UploadForm.allowedFileTypes.oga = true;
        if (UploadForm.forbiddenFileTypes == null || !UploadForm.forbiddenFileTypes.ogx)
          UploadForm.allowedFileTypes.ogx = true;
      }
      // OpenDoc extensions (are these needed?)
      if (UploadForm.forbiddenFileTypes == null || !UploadForm.forbiddenFileTypes.sxi)
        UploadForm.allowedFileTypes.sxi = true;
      if (UploadForm.forbiddenFileTypes == null || !UploadForm.forbiddenFileTypes.sxc)
        UploadForm.allowedFileTypes.sxc = true;
      if (UploadForm.forbiddenFileTypes == null || !UploadForm.forbiddenFileTypes.sxd)
        UploadForm.allowedFileTypes.sxd = true;
      if (UploadForm.forbiddenFileTypes == null || !UploadForm.forbiddenFileTypes.sxw)
        UploadForm.allowedFileTypes.sxw = true;
      // PDF (allowed, but may be hidden in the interface)
      if (UploadForm.forbiddenFileTypes == null || !UploadForm.forbiddenFileTypes.pdf)
        UploadForm.allowedFileTypes.pdf = true;
    }
  },
 
  checkFileExtension : function (ext, presence_only)
  {
    if (presence_only)
      return   (UploadForm.allowedFileTypes != null && UploadForm.allowedFileTypes[ext] == true)
            || (UploadForm.forbiddenFileTypes != null && UploadForm.forbiddenFileTypes[ext] == true);
    return    (UploadForm.allowedFileTypes == null || UploadForm.allowedFileTypes[ext] == true)
           && (UploadForm.forbiddenFileTypes == null || !(UploadForm.forbiddenFileTypes[ext] == true));
  },
 
  verifyFileName : function (filename)
  {
    if (filename == null || filename.length == 0) {
      UploadForm.errorMsgs.push ('wpNoFilenameError');
      return false;
    }
    if (filename.search (/(https?|file|ftp):\/\//i) >= 0) {
      UploadForm.errorMsgs.push ('wpHttpFilenameError');
      return false;
    }
    var ok = true;
 
    // Don't allow slashes
    if (filename.indexOf ('/') >= 0) {
      UploadForm.errorMsgs.push ('wpNoSlashError');
      ok = false;
    }
    // Check for double extensions
    var fn = filename.split ('.');
    if (fn.length < 2 || fn[fn.length-1].length == 0) {
      UploadForm.errorMsgs.push ('wpNoExtensionError');
      ok = false;
    }
    // Check extension
    var nof_extensions = 0;
    if (fn.length >= 2) {
      nof_extensions++;
      if (UploadForm.checkFileExtension (fn[fn.length-1].toLowerCase ())) {
        // It's ok, check for double extension
        if (fn.length > 2) {
          if (UploadForm.checkFileExtension (fn[fn.length-2].toLowerCase (), true)) {
            nof_extensions++;
            UploadForm.errorMsgs.push ('wpDoubleExtensionError');
            ok = false;
          }
        }
      } else {
        UploadForm.errorMsgs.push ('wpIllegalExtensionError');
        ok = false;
      }
    }
    // Check for allowed file name
    var one_ok = false;
    for (var i = 0; i < fn.length - nof_extensions && !one_ok; i++) {
      if (fn[i].length > 0 && fn[i].search (UploadForm.badFileNames) < 0) one_ok = true;
    }
    if (!one_ok) {
      UploadForm.errorMsgs.push ('wpNondescriptFilenameError');
      ok = false;
    }
    return ok;
  },
 
  cleaner : null,
 
  clean : function (input)
  {
    if (UploadForm.cleaner == null) {
      // Because of asynchronous script loading, we need to check whether the TextCleaner is
      // already defined. If not, just return the input.
      if (   typeof (TextCleaner) != 'undefined'
          && typeof (TextCleaner.sanitizeWikiText) == 'function')
      {
        UploadForm.cleaner = TextCleaner.sanitizeWikiText;
      }
    }
    if (UploadForm.cleaner && input && typeof (input) == 'string')
      return UploadForm.cleaner (input, true);
    else
      return input;   
  },
 
  resetBg : function (evt)
  {
    var e = evt || window.event; // W3C, IE
    return UploadForm.verifyMandatoryField (e.target || e.srcElement);
  },
 
  verifyMandatoryField: function (node, handler)
  {
    if (!node) return true;
    try {
      if (   !node.value
          || node.value.search (/\S/) < 0
          || handler && typeof (handler) == 'function' && handler.length == 1
             && !handler (node.value))
      {
        // No value set, or a handler was given and it is a function taking one parameter, and
        // it returned false
        var is_error = node.id != 'wpPermission';
        if (!is_error) {
          var license_field = document.getElementById ('wpLicense');
          // Careful here. The fromwikimedia forms appear not to have a license selector!
          is_error = license_field == null || license_field.selectedIndex == 0
        }
        if (is_error) {
          node.style.backgroundColor = UploadForm.errorColor;
          if (!UploadForm.warning_pushed) {
            if (UploadForm.errorMsgs != null)
              UploadForm.errorMsgs.push ('wpUploadWarningError');
            UploadForm.warning_pushed = true;
          }
          return false;
        }
      }
    } catch (ex) {
      // Swallow the exception  
    }
    try {
      node.style.backgroundColor = '#FFFFFF';
    } catch (some_error) {
      // Swallow.
    }
    return true;
  },
 
  fixCategoryTransclusion : function (str)
  {
    return str.replace (/(\{\{)\s*(:?\s*[Cc]ategory\s*:[^|}]*(\|[^}]*)?)(\}\})/g, "[[$2]]");
  }
 
}; // end UploadForm
 
var UFFixes =
{
  fixAutocompletion : function ()
  {
    // Do the overwrite check also for selections from the browser's "previous entry list"
    var dest_file = document.getElementById ('wpDestFile');
    if (dest_file && dest_file.onkeyup) {
      // For some reason, onchange doesn't fire upon autocompletion in FF and IE6. Don't use
      // onblur (recommended as a workaround on some Internet sites), it cancels button clicks
      // that cause the focus change. Unfortunately, FF also doesn't fire the DOMAttrModified
      // event upon autocompletion. Thus we're stuck for FF. At least the FF people are about
      // to correct this bug (https://bugzilla.mozilla.org/show_bug.cgi?id=388558). On IE,
      // there is a workaround.
      if (window.ActiveXObject) { // We're on IE...
        // See http://msdn2.microsoft.com/en-us/library/ms533032.aspx and
        // http://msdn2.microsoft.com/en-us/library/ms536956.aspx
        if (!dest_file.onpropertychange) {
          previous_onkeyup_handler  = dest_file.onkeyup;
          previous_onchange_handler = dest_file.onchange;
          addEvent (dest_file, 'propertychange',
            function (evt)
            {
              var e = evt || window.event;
              if (e && e.propertyName && e.propertyName == 'value') {
                if (typeof (previous_onkeyup_handler) == 'string')
                  eval (previous_onkeyup_handler);
                else if (typeof (previous_onkeyup_handler) == 'function')
                  previous_onkeyup_handler (e);
                if (typeof (previous_onchange_handler) == 'string')
                  eval (previous_onchange_handler);
                else if (typeof (previous_onchange_handler) == 'function')
                  previous_onchange_handler (e);
              }
            });
          dest_file.onkeyup  = null; // Otherwise, both may fire...
          dest_file.onchange = null;
        }
      } else {
        //Wikiminicustom (om)
        //addEvent (dest_file, 'change', dest_file.onkeyup);
        try{
           addEvent (dest_file, 'change', dest_file.onkeyup);
        }
        catch(ex) 
        {
          //alert('An error has occurred: '+ex.message)
        }
      }
    }
  }
 
}; // end UFFixes
 
} // end if (guard against double inclusions)
 
 
// Do *not* use addOnloadHook!!! Functions added through addOnloadHook are actually executed
// *before* the onload event occurs through an inline script at the bottom of each page served
// by the WikiMedia servers. Normally, that is fine and dandy and speeds up page creation since
// the hooks may run before all elements (such as images) of the page have completely loaded.
// But it breaks our form restoration mechanism on IE. wpDestFile.value is set on IE6 only at
// the time when the onload event fires. If this script runs before, wpDestFile.value is always
// empty on IE. Since the upload form does not contain many images, it won't make a difference
// for the user if we use hookEvent and thus run a tiny little bit later. It also has the nice
// side effect that we can run even if one of the other functions registered through
// addOnloadHook raises an exception.
 
if (window.$) {
  $(UploadForm.install)
} else {
  hookEvent ('load', UploadForm.install);
}
 
// </source>
Wikiboo Personal tools