Jump to content

User:Arkanosis/iKiwi.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*
***************************************************************************
** iKiwi - Permet de récupérer des interwikis sur d'autres Wikipédia
** Compatibilité : {de,en,es,fr,it,ja,nl,pl,pt,ru,sv}wiki
** Support : Discussion_utilisateur:Arkanosis
** Licence : MIT/X11
**
** Installation : ajouter
**  importScript('User:Arkanosis/iKiwi.js');
** dans le monobook.js ou vector.js de toutes les Wikipédia d'où et dans lesquelles
** on souhaite pouvoir récupérer des interwikis
** (important : si l'ajout n'est pas fait sur d'autres Wikipédia, le script ne
** fonctionnera pas)
*/

iKiwiVersion = '0.5.0a';

var iKiwiDefaultDistantWiki = 'en';
if (typeof (iKiwiDistantWikis) == 'undefined')
  var iKiwiDistantWikis = ['de', 'en', 'es', 'fr', 'it', 'ja', 'nl', 'pl', 'pt', 'ru', 'sv'];
else
{
  iKiwiDefaultDistantWiki = iKiwiDistantWikis[0];
}
if (iKiwiDistantWikis.indexOf(wgContentLanguage) != -1)
{
  iKiwiDistantWikis[iKiwiDistantWikis.indexOf(wgContentLanguage)] = iKiwiDistantWikis[iKiwiDistantWikis.length - 1];
  iKiwiDistantWikis.pop();
}
iKiwiDistantWikis.sort();
if (typeof (iKiwiWatchMain) == 'undefined')
  var iKiwiWatchMain = false;
if (typeof (iKiwiWatchOthers) == 'undefined')
  var iKiwiWatchOthers = false;

if (typeof (iKiwiDisplayPanel) == 'undefined')
  var iKiwiDisplayPanel = true;

var iKiwiInterWiki = new RegExp('^\\s*\\[\\[([a-z][a-z].?(x?-[^\\]]+)?|simple|tokipona):([^\\]]*)\\]\\]\\s*$');
var iKiwiBlank = new RegExp('^\\s*$');
var iKiwiHtmlInterWiki = new RegExp('<a href="/wiki/([^"]+)" title="([^"]+)">fr:([^<]+)</a>');
var iKiwiRedirect = new RegExp('^\\s*#(?:redirect|redirection|omdirigering|перенаправление|перенапр|redirecionamento|patrz|przekieruj|tam|doorverwijzing|転送|リダイレクト|転送|リダイレクト|rinvia|rinvio|rimando|redirección|redireccion|weiterleitung)\\s*\\[\\[([^\\]\\#]+)\\]\\]', 'i');

var iKiwiPanelNextState = 0;
var iKiwiStates = [ 'none', 'block' ];

var iKiwiI18nText = {
  'de': {
    'usertalk': 'Benutzer_Diskussion',
    'redirectfrom': 'Weitergeleitet von',
    'alreadylinked': 'Der remote Artikel ist bereits im Zusammenhang mit',
    'nomoreiw': 'Es gibt kein interWiki mehr zu hinzufügen',
    'noarticle': 'Es gibt kein Artikel mit diesem Name',
    'extpage': 'Remote Artikel:',
    'panel': 'Die interWiki aus einer anderen Version des Artikels hinzufügen',
    'autopreview': 'auto Vorschau',
    'adding': 'Adding',
    'from': 'von',
    'iwadded': 'interWiki',
    'iwsadded': 'interWikis',
    'follow': 'Diese Seite beobachten',
    'preview': 'Vorschau zeigen',
    'publish': 'Seite speichern',
  },
  'en': {
    'usertalk': 'User_talk',
    'redirectfrom': 'Redirected from',
    'alreadylinked': 'The remote article is already linked to ',
    'twolocallinks': 'The local article is linked twice to ',
    'twodistantlinks': 'The distant article is linked twice to ',
    'twolinks': 'The local article and the distant article have different links to ',
    'nomoreiw': 'There is no additional interWiki to add',
    'noarticle': 'There is no article with this name',
    'extpage': 'Remote article:',
    'panel': 'Get the interWikis from another version of the article',
    'autopreview': 'auto preview',
    'adding': 'Adding',
    'from': 'from',
    'iwadded': 'interWiki',
    'iwsadded': 'interWikis',
    'follow': 'Watch this page',
    'preview': 'Show preview',
    'publish': 'Save page',
  },
  'es': {
    'usertalk': 'Usuario_Discusión',
    'redirectfrom': 'Redirigido desde',
    'from': 'desde',
    'follow': 'Vigilar esta página',
    'preview': 'Mostrar previsualización',
    'publish': 'Grabar la página',
  },
  'fr': {
    'usertalk': 'Discussion_utilisateur',
    'redirectfrom': 'Redirigé depuis',
    'alreadylinked': 'L\'article distant est déjà lié à l\'article',
    'twolocallinks': 'L\'article local est lié deux fois à ',
    'twodistantlinks': 'L\'article distant est lié deux fois à ',
    'twolinks': 'L\'article local et l\'article distant ont des liens différents vers ',
    'nomoreiw': 'Il n\'y a pas d\'interWiki supplémentaire à ajouter',
    'noarticle': 'Il n\'y a pas d\'article avec ce nom',
    'extpage': 'Page d\'où récupérer les interWikis :',
    'panel': 'Rapatrier les interWikis d\'une autre version de l\'article',
    'autopreview': 'aperçu automatique',
    'adding': 'Ajout de',
    'from': 'depuis',
    'iwadded': 'interWiki rapatrié',
    'iwsadded': 'interWikis rapatriés',
    'follow': 'Suivre cette page',
    'preview': 'Prévisualiser',
    'publish': 'Publier',
  },
  'it': {
    'usertalk': 'Discussioni_utente',
    'redirectfrom': 'Reindirizzamento da',
    'from': 'da',
    'follow': 'Tieni d\'occhio questa pagina',
    'preview': 'Visualizza anteprima',
    'publish': 'Salva la pagina',
  },
  'ja': {
    'usertalk': '利用者‐会話',
    'redirectfrom': 'から転送',
    'follow': 'ウォッチリストに追加',
    'preview': 'プレビューを表示',
    'publish': '編集を保存',
  },
  'nl': {
    'usertalk': 'Overleg gebruiker',
    'redirectfrom': 'Doorverwezen vanaf',
    'from': 'vanaf',
    'follow': 'Deze pagina volgen',
    'preview': 'Toon bewerking ter controle',
    'publish': 'Pagina opslaan',
  },
  'pl': {
    'usertalk': 'Dyskusja wikipedysty',
    'redirectfrom': 'Przekierowano z',
    'from': 'z',
    'follow': 'Obserwuj',
    'preview': 'Pokaż podgląd',
    'publish': 'Zapisz',
  },
  'pt': {
    'usertalk': 'Usuário_Discussão',
    'redirectfrom': 'Redireccionado de',
    'from': 'de',
    'follow': 'Vigiar esta página',
    'preview': 'Mostrar previsão',
    'publish': 'Gravar página',
  },
  'ru': {
    'usertalk': 'Обсуждение_участника',
    'redirectfrom': 'Перенаправлено с',
    'from': 'c',
    'follow': 'Включить эту страницу в список наблюдения',
    'preview': 'Предварительный просмотр',
    'publish': 'Записать страницу',
  },
  'sv': {
    'usertalk': 'Användardiskussion',
    'redirectfrom': 'Omdirigerad från',
    'from': 'från',
    'follow': 'Bevaka denna sida',
    'preview': 'Visa förhandsgranskning',
    'publish': 'Spara',
  },
};

function iKiwiI18n(lang, message)
{
  if (typeof (iKiwiI18nText[lang]) == 'undefined')
    lang = 'en';
  if (typeof (iKiwiI18nText[lang][message]) == 'undefined')
    return iKiwiI18nText['en'][message];
  return iKiwiI18nText[lang][message];
}

var iKiwiDocPage = iKiwiI18n(wgContentLanguage, 'usertalk') + ':Arkanosis/iKiwi.js';

function iKiwiNormalize(string)
{
    return string
      .replace(/[àáâãäåą]/g, 'a')
      .replace(/[æ]/g, 'ae')
      .replace(/[çć]/g, 'c')
      .replace(/[èéêëę]/g, 'e')
      .replace(/[ìíîï]/g, 'i')
      .replace(/[ł]/g, 'l')
      .replace(/[ñ]/g, 'n')
      .replace(/[òóôõöø]/g, 'o')
      .replace(/[œ]/g, 'oe')
      .replace(/[ś]/g, 's')
      .replace(/[ß]/g, 'ss')
      .replace(/[ùúûü]/g, 'u')
      .replace(/[ýÿ]/g, 'y')
      .replace(/[źż]/g, 'z')

      .replace(/[ÀÁÂÃÄÅĄ]/g, 'A')
      .replace(/[Æ]/g, 'AE')
      .replace(/[ÇĆ]/g, 'C')
      .replace(/[ÈÉÊËĘ]/g, 'E')
      .replace(/[ÌÍÎÏ]/g, 'I')
      .replace(/[Ł]/g, 'L')
      .replace(/[Ñ]/g, 'N')
      .replace(/[ÒÓÔÕÖØ]/g, 'O')
      .replace(/[Œ]/g, 'OE')
      .replace(/[Ś]/g, 'S')
      .replace(/[ÙÚÛÜ]/g, 'U')
      .replace(/[Ý]/g, 'Y')
      .replace(/[ŹŻ]/g, 'Z');
}

var iKiwiTranslations =
[
  {
    'en': ['disambiguation'],
    'fr': ['homonymie'],
  },
  {
    'en': ['book', 'story'],
    'fr': ['livre', 'roman', 'nouvelle']
  },
  {
    'en': ['&', 'and'],
    'fr': ['&', 'et'],
  },
];

function iKiwiTranslate(from, to, string)
{
  var translations = [string];

  if (['de', 'es', 'fr', 'nl', 'pl', 'pt', 'sv'].indexOf(from) != -1 && ['en', 'it', 'ja', 'ru'].indexOf(to) != -1)
  {
    var normalizedString = iKiwiNormalize(string);
    if (normalizedString != string)
      translations.push(normalizedString);
  }

  if (/.*\(.+\)/.exec(string))
  {
    // TODO develop an heuristic: it should be better to have the versions without parenthesis at the end                                                             
    translations.push(string.replace(/(\s|_)*\([^\)]+\)$/, ''));
    if (translations.length == 3)
    {
      translations.push(translations[1].replace(/(\s|_)*\([^\)]+\)$/, ''));
      if (translations[2] == translations[3])
        translations.pop();
    }
  }

  for (var translationItemId = 0; translationItemId < iKiwiTranslations.length; ++translationItemId)
  {
    var originalTokens = iKiwiTranslations[translationItemId][from];
    var replacementTokens = iKiwiTranslations[translationItemId][to];

    for (var originalTokenId = 0; originalTokenId < originalTokens.length; ++originalTokenId)
    {
      var originalToken = originalTokens[originalTokenId];
      var newTranslations = translations.slice(0);

      for (var currentTranslationId = 0; currentTranslationId < translations.length; ++currentTranslationId)
      {
        var currentTranslation = translations[currentTranslationId];
        if (translations[currentTranslationId].indexOf(originalToken))
          for (var replacementTokenId = 0; replacementTokenId < replacementTokens.length; ++replacementTokenId)
          {
            var replacementToken = replacementTokens[replacementTokenId];
            if (originalToken != replacementToken)
            {
              var newTranslation = currentTranslation.replace(new RegExp('\\b' + originalToken.replace(/[.*+?|()\[\]{}\\]/g, '\\$&') + '\\b', 'g'), replacementToken);
              if (newTranslations.indexOf(newTranslation) == -1)
                newTranslations.push(newTranslation);
            }
          }
      }
      translations = newTranslations;
    }
  }

  return translations.slice(1);
}

// Taken from http://meta.wikimedia.org/wiki/Interwiki_sorting_order
var iKiwiSpecialOrdered = [
  'en', 'pl'
];
var iKiwiSpecialOrder = [
  'ace', 'af', 'ak', 'als', 'am', 'ang', 'ab', 'ar', 'an', 'arc',
  'roa-rup', 'frp', 'as', 'ast', 'gn', 'av', 'ay', 'az', 'bm', 'bn',
  'zh-min-nan', 'nan', 'map-bms', 'ba', 'be', 'be-x-old', 'bh', 'bcl',
  'bi', 'bar', 'bo', 'bs', 'br', 'bg', 'bxr', 'ca', 'cv', 'ceb', 'cs',
  'ch', 'cbk-zam', 'ny', 'sn', 'tum', 'cho', 'co', 'cy', 'da', 'dk',
  'pdc', 'de', 'dv', 'nv', 'dsb', 'dz', 'mh', 'et', 'el', 'eml', 'en',
  'myv', 'es', 'eo', 'ext', 'eu', 'ee', 'fa', 'hif', 'fo', 'fr', 'fy',
  'ff', 'fur', 'ga', 'gv', 'gd', 'gl', 'gan', 'ki', 'glk', 'gu',
  'got', 'hak', 'xal', 'ko', 'ha', 'haw', 'hy', 'hi', 'ho', 'hsb',
  'hr', 'io', 'ig', 'ilo', 'bpy', 'id', 'ia', 'ie', 'iu', 'ik', 'os',
  'xh', 'zu', 'is', 'it', 'he', 'jv', 'kl', 'kn', 'kr', 'pam', 'ka',
  'ks', 'csb', 'kk', 'kw', 'rw', 'ky', 'rn', 'sw', 'kv', 'kg', 'ht',
  'ku', 'kj', 'lad', 'lbe', 'lo', 'la', 'lv', 'lb', 'lt', 'lij', 'li',
  'ln', 'jbo', 'lg', 'lmo', 'hu', 'mk', 'mg', 'ml', 'mt', 'mi', 'mr',
  'arz', 'mzn', 'ms', 'cdo', 'mwl', 'mdf', 'mo', 'mn', 'mus', 'my',
  'nah', 'na', 'fj', 'nl', 'nds-nl', 'cr', 'ne', 'new', 'ja', 'nap',
  'ce', 'pih', 'no', 'nb', 'nn', 'nrm', 'nov', 'ii', 'oc', 'mhr',
  'or', 'om', 'ng', 'hz', 'uz', 'pa', 'pi', 'pag', 'pnb', 'pap', 'ps',
  'km', 'pcd', 'pms', 'tpi', 'nds', 'pl', 'tokipona', 'tp', 'pnt',
  'pt', 'aa', 'kaa', 'crh', 'ty', 'ksh', 'ro', 'rmy', 'rm', 'qu',
  'ru', 'sah', 'se', 'sm', 'sa', 'sg', 'sc', 'sco', 'stq', 'st', 'tn',
  'sq', 'scn', 'si', 'simple', 'sd', 'ss', 'sk', 'cu', 'sl', 'szl',
  'so', 'ckb', 'srn', 'sr', 'sh', 'su', 'fi', 'sv', 'tl', 'ta', 'kab',
  'roa-tara', 'tt', 'te', 'tet', 'th', 'ti', 'tg', 'to', 'chr', 'chy',
  've', 'tr', 'tk', 'tw', 'udm', 'bug', 'uk', 'ur', 'ug', 'za', 'vec',
  'vi', 'vo', 'fiu-vro', 'wa', 'zh-classical', 'vls', 'war', 'wo',
  'wuu', 'ts', 'yi', 'yo', 'zh-yue', 'diq', 'zea', 'bat-smg', 'zh',
  'zh-tw', 'zh-cn'
];

function iKiwiSpecialOrderCompare(first, second)
{
  var firstInterWiki = iKiwiInterWiki.exec(first);
  var secondInterWiki = iKiwiInterWiki.exec(second);

  return iKiwiSpecialOrder.indexOf(firstInterWiki[1]) - iKiwiSpecialOrder.indexOf(secondInterWiki[1]);
}

function iKiwiDistantWiki()
{
  return document.getElementById('iKiwiDistantWiki').value;
}

function iKiwiUrl(wiki, page)
{
  return 'http://' + wiki + '.wikipedia.org' + wgScript + '?title=' + encodeURIComponent(page);
}

function iKiwiLocalUrl(page)
{
  return iKiwiUrl(wgContentLanguage, page);
}

function iKiwiDistantUrl(page)
{
  return iKiwiUrl(iKiwiDistantWiki(), page);
}

function iKiwiError(message)
{
  document.getElementById('iKiwiExtPage').setAttribute('style', 'background-color:#D66;');
  with (document.getElementById('iKiwiWarning'))
  {
    innerHTML = ' ' + message;
    setAttribute('style', 'color:red;');
  }
  document.getElementById('iKiwiSubmit').setAttribute('disabled', 'disabled');

  var textarea = document.getElementById('iKiwiText');
  if (textarea)
  {
    textarea.setAttribute('style', 'display:none;');
    document.getElementById('iKiwiDiff').setAttribute('style', 'display:none;');
  }
}

function iKiwiExtractInterWikis(text)
{
  var lines = text.split('\n');
  var interWikis = new Array();
  for (var lineId = 0; lineId < lines.length; ++lineId)
  {
    var interWiki = iKiwiInterWiki.exec(lines[lineId]);
    if (interWiki)
      interWikis.push(interWiki[0].replace(/^\s+/g, '').replace(/\s+$/g, '').replace(/_/g, ' '));
  }
  return interWikis;
}

function iKiwiRemoveInterWikis(text)
{
  var lines = text.split('\n');
  for (var lineId = lines.length - 1; lineId >= 0; --lineId)
    if (!iKiwiInterWiki.exec(lines[lineId]) && !iKiwiBlank.exec(lines[lineId]))
      return lines.slice(0, lineId + 1).join('\n');
}

function iKiwiXssRequest(url)
{
  var xssFrame = document.getElementById('iKiwiXssFrame');
  if (xssFrame)
    xssFrame.setAttribute('src', url);
  else
  {
    document.domain = 'wikipedia.org';
    document.getElementsByTagName('body')[0].innerHTML += '<iframe id="iKiwiXssFrame" src="' + url + '" width="0px" height="0px"></iframe>';
  }
}

function iKiwiXssServer()
{
  document.domain = 'wikipedia.org';

  var text = document.getElementById('wpTextbox1').value;

  if (!text.length)
  {
    var destinationLanguage = /iKiwiDestinationLanguage=([^&]+)/.exec(location.href);
    if (destinationLanguage)
    {
      var translations = iKiwiTranslate(destinationLanguage[1], wgContentLanguage, wgPageName);
      for (var translationId = 0; translationId < translations.length; ++translationId)
      {
        var translation = translations[translationId];
        var xhr = sajax_init_object();
        xhr.open('GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?title=' + encodeURIComponent(translation) + '&action=raw', false);
        xhr.send('');
        text = xhr.responseText;
        if (text)
        {
          window.parent.iKiwiRedirectCallBack(translation);
          break;
        }
      }
    }
  }

  for (var nbFollowedRedirects = 0; nbFollowedRedirects < 10; ++nbFollowedRedirects) // avoid circular redirections
  {
    var redirect = iKiwiRedirect.exec(text);
    if (!redirect)
      break;

    var xhr = sajax_init_object();
    xhr.open('GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?title=' + encodeURIComponent(redirect[1]) + '&action=raw', false);
    xhr.send('');
    text = xhr.responseText;

    window.parent.iKiwiRedirectCallBack(redirect[1]);
  }

  if (text.length) {
    window.parent.iKiwiAddInterWikisCallBack(text);
  } else {
    // TODO /w/api.php?action=query&list=search&srsearch=<SUBJECT>
    window.parent.iKiwiSuggestCallBack();
  }
}

function iKiwiGetForm()
{
  var xhr = sajax_init_object();

  xhr.open('GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&action=edit', false);
  xhr.send('');

  var parser = new DOMParser();
  return parser.parseFromString(xhr.responseText, 'application/xhtml+xml');
}

function iKiwiPostRequest(request, editForm, text, summary)
{
  var inputs = editForm.getElementsByTagName('input');
  for (inputId = 0; inputId < inputs.length; ++inputId)
    switch (inputs[inputId].name)
    {
      case 'wpStarttime':
        var wpStarttime = inputs[inputId].value;
        break;
      case 'wpEdittime':
        var wpEdittime = inputs[inputId].value;
        break;
      case 'wpEditToken':
        var wpEditToken = inputs[inputId].value;
        break;
      default:
        break;
    }
 
  var parameters = 'wp' + request + '=1'
    + '&wpTextbox1=' + encodeURIComponent(text)
    + '&wpStarttime=' + encodeURIComponent(wpStarttime)
    + '&wpEdittime=' + encodeURIComponent(wpEdittime)
    + '&wpEditToken=' + encodeURIComponent(wpEditToken)
    + '&wpSummary=' + encodeURIComponent('[[' + iKiwiDocPage + '|iKiwi]] : ' + summary)
    + '&wpMinoredit=on';

  if (document.getElementById('iKiwiFollow').checked)
    parameters += '&wpWatchthis=on';
 
  var xhr = sajax_init_object();

  with (xhr)
  {
    open('POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&action=submit', false);
 
    setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    setRequestHeader('Content-length', parameters.length);
    setRequestHeader('Connection', 'close');
 
    send(parameters);
  }

  return xhr;
}

function iKiwiPreview(editForm, text, summary)
{
  var xhr = iKiwiPostRequest('Diff', editForm, text, summary);
  var parser = new DOMParser();
  return parser.parseFromString(xhr.responseText, 'application/xhtml+xml');
}

function iKiwiPublish()
{
  iKiwiPostRequest('Save', document.editForm, document.newText, document.summary);
  iKiwiSelectPage();
}

function iKiwiRedirectCallBack(page)
{
  var extPage = document.getElementById('iKiwiExtPage');
  var distantPageName = iKiwiDistantWiki() + ':' + extPage.value;

  var redirect = document.getElementById('iKiwiRedirect');
  redirect.innerHTML = ' ' + iKiwiI18n(wgUserLanguage, 'redirectfrom') + ' <a href="' + iKiwiDistantUrl(extPage.value) + '&redirect=no" title="' + distantPageName + '">' + distantPageName + '</a>';
  redirect.setAttribute('style', 'display:inline;');
  extPage.value = page;
}

function iKiwiSuggestCallBack()
{

  iKiwiError(iKiwiI18n(wgUserLanguage, 'noarticle'));
}

function iKiwiAddInterWikisCallBack(text)
{
  var editForm = iKiwiGetForm();

  var originalText = editForm.getElementById('wpTextbox1').value;

  var newText = iKiwiRemoveInterWikis(originalText);

  var interWikis = [];
  var originalInterWikis = iKiwiExtractInterWikis(originalText);
  var distantInterWikis = iKiwiExtractInterWikis(text);

  var distantPageName = iKiwiDistantWiki() + ':' + document.getElementById('iKiwiExtPage').value;

  interWikis.push('[[' + distantPageName + ']]');

  var distantWikis = [ iKiwiDistantWiki() ];

  for (var originalInterWikiId = 0; originalInterWikiId < originalInterWikis.length; ++originalInterWikiId)
    if (interWikis.indexOf(originalInterWikis[originalInterWikiId]) == -1)
    {
      var interWiki = iKiwiInterWiki.exec(originalInterWikis[originalInterWikiId]);
      if (distantWikis.indexOf(interWiki[1]) != -1) {
          iKiwiError(iKiwiI18n(wgUserLanguage, 'twolocallinks') + interWiki[1]);
          return;
      }
      interWikis.push(originalInterWikis[originalInterWikiId]);
      distantWikis.push(interWiki[1]);
    }

  var originalLinksCount = distantWikis.length;

  for (var distantInterWikiId = 0; distantInterWikiId < distantInterWikis.length; ++distantInterWikiId)
    if (interWikis.indexOf(distantInterWikis[distantInterWikiId]) == -1)
    {
      if (distantInterWikis[distantInterWikiId].indexOf('[[' + wgContentLanguage + ':') != -1)
      {
        if (distantInterWikis[distantInterWikiId].indexOf('[[' + wgContentLanguage + ':' +  wgPageName.replace(/_/g, ' ')) == -1)
        {
          var interWiki = iKiwiInterWiki.exec(distantInterWikis[distantInterWikiId]);
          iKiwiError(iKiwiI18n(wgUserLanguage, 'alreadylinked') + ' <a href="/wiki/' + interWiki[3] + '" title="' + interWiki[3] + '">' + interWiki[3] + '</a>');
          return;
        }
      } else {
        var interWiki = iKiwiInterWiki.exec(distantInterWikis[distantInterWikiId]);
        var distantWikiId = distantWikis.indexOf(interWiki[1]);
        if (distantWikiId != -1) {
            if (distantWikiId < originalLinksCount) {
              iKiwiError(iKiwiI18n(wgUserLanguage, 'twolinks') + interWiki[1]);
            } else {
              iKiwiError(iKiwiI18n(wgUserLanguage, 'twodistantlinks') + interWiki[1] + ': <a href="' + iKiwiDistantUrl(document.getElementById('iKiwiExtPage').value) + '&redirect=no" title="' + distantPageName + '">' + distantPageName + '</a>');
            }
            return;
        }
        interWikis.push(distantInterWikis[distantInterWikiId]);
        distantWikis.push(interWiki[1]);
      }
    }

  var nbNewInterWikis = interWikis.length - originalInterWikis.length;

  if (!nbNewInterWikis)
  {
    iKiwiError(iKiwiI18n(wgUserLanguage, 'nomoreiw'));
    return;
  }

  if (iKiwiSpecialOrdered.indexOf(wgContentLanguage) != -1)
    interWikis.sort(iKiwiSpecialOrderCompare);
  else
    interWikis.sort();

  newText += '\n\n'

  for (var interWikiId = 0; interWikiId < interWikis.length; ++interWikiId)
      newText += interWikis[interWikiId] + '\n';

  document.getElementById('iKiwiExtPage').removeAttribute('style');
  with (document.getElementById('iKiwiWarning'))
  {
    if (nbNewInterWikis > 1)
      innerHTML = ' ' + nbNewInterWikis + ' ' + iKiwiI18n(wgUserLanguage, 'iwsadded');
    else
      innerHTML = ' ' + nbNewInterWikis + ' ' + iKiwiI18n(wgUserLanguage, 'iwadded');
    innerHTML += ' ' + iKiwiI18n(wgUserLanguage, 'from') + ' <a href="' + iKiwiDistantUrl(document.getElementById('iKiwiExtPage').value) + '&redirect=no" title="' + distantPageName + '">' + distantPageName + '</a>';
    setAttribute('style', 'color:green;');
  }
  document.getElementById('iKiwiSubmit').removeAttribute('disabled');

  document.editForm = editForm;
  document.newText = newText;
  document.summary = iKiwiI18n(wgContentLanguage, 'adding') + ' ' + nbNewInterWikis + ' interWiki' + (nbNewInterWikis > 1 ? 's' : '') + ' ' + iKiwiI18n(wgContentLanguage, 'from') + ' [[:' + distantPageName + ']]';

  if (location.href.indexOf('&iKiwiFromPIW') != -1)
    document.summary += ' (Détecté par [[P:IW]])';

  var preview = iKiwiPreview(editForm, newText, document.summary);
  var diff = preview.getElementById('wikiDiff');
  diff.setAttribute('id', 'iKiwiDiff');

  var textarea = document.getElementById('iKiwiText');
  if (!textarea)
  {
    textarea = document.createElement('textarea');
    with (textarea)
    {
      setAttribute('id', 'iKiwiText');
      setAttribute('rows', 10);
      setAttribute('readonly', 'readonly');
      appendChild(document.createTextNode(text));
    }

    var fieldSet = document.getElementById('iKiwiFieldSet');
    var follow = document.getElementById('iKiwiFollow');

    fieldSet.insertBefore(textarea, follow);
    fieldSet.insertBefore(document.createElement('br'), follow);

    document.getElementsByTagName('head')[0].innerHTML+='<link rel="stylesheet" href="http://bits.wikimedia.org/skins-1.5/common/diff.css?257z23" type="text/css" media="all" />';

    fieldSet.insertBefore(diff, follow);
  } else {
    textarea.value = text;
    textarea.setAttribute('style', 'display:block;');

    document.getElementById('iKiwiFieldSet').replaceChild(diff, document.getElementById('iKiwiDiff'));
  }
}

function iKiwiAddInterWikis()
{
  document.getElementById('iKiwiRedirect').setAttribute('style', 'display:none;');

  var distantWiki = document.getElementById('iKiwiDistantWiki').value;
  var page = document.getElementById('iKiwiExtPage').value;
  var follow = document.getElementById('iKiwiFollow').checked;

  iKiwiXssRequest(iKiwiDistantUrl(page) + '&action=edit&xssServe&iKiwiDestinationLanguage=' + wgContentLanguage);

  document.getElementById('iKiwiExtPage').value = page;
  document.getElementById('iKiwiDistantWiki').value = distantWiki;
  if (follow)
    document.getElementById('iKiwiFollow').checked = 'checked';
  else
    document.getElementById('iKiwiFollow').removeAttribute('checked');
}

function iKiwiSelectPage(autoPreview)
{
  var iForm = document.getElementById('iKiwiForm');

  if (iForm) {
    iForm.setAttribute('style', 'display:' + iKiwiStates[iKiwiPanelNextState] + ';');
    iKiwiPanelNextState = !iKiwiPanelNextState + 0;
    document.getElementById('iKiwiLinks').setAttribute('style', 'display:' + iKiwiStates[iKiwiPanelNextState] + ';');
  } else {
    document.getElementById('iKiwiLinks').setAttribute('style', 'display:none;');

    iForm = document.createElement('form');
    iForm.setAttribute('id', 'iKiwiForm');

    var fieldSet = document.createElement('fieldset');
    fieldSet.setAttribute('id', 'iKiwiFieldSet');

    var link = document.createElement('a');
    with (link)
    {
      setAttribute('href', 'javascript:iKiwiSelectPage();');
      setAttribute('id', 'iKiwiHidePanel');
      setAttribute('title', 'Masquer le panneau iKiwi');
      appendChild(document.createTextNode('[iKiwi — ' + iKiwiVersion + ']'));
    }

    var doc = document.createElement('a');
    with (doc)
    {
      setAttribute('href', iKiwiLocalUrl(iKiwiDocPage));
      setAttribute('id', 'iKiwiDoc');
      setAttribute('title', 'Documentation');
      appendChild(document.createTextNode('(documentation)'));
    }

    var legend = document.createElement('legend');
    with (legend)
    {
      appendChild(link);
      appendChild(document.createTextNode(' '));
      appendChild(doc);
    }
 
    var label = document.createElement('label');
    with (label)
    {
      setAttribute('for', 'iKiwiExtPage');
      appendChild(document.createTextNode(iKiwiI18n(wgUserLanguage, 'extpage')));
    }

    var distantLanguage = /iKiwiSourceLanguage=([^&]+)/.exec(location.href);
    if (distantLanguage)
      iKiwiDefaultDistantWiki = distantLanguage[1];

    var distantWiki = document.createElement('select');
    distantWiki.setAttribute('id', 'iKiwiDistantWiki');
    for (var wikiId = 0; wikiId < iKiwiDistantWikis.length; ++wikiId)
    {
      var option = document.createElement('option');
      with (option)
      {
        setAttribute('id', 'iKiwiDistantWiki-' + iKiwiDistantWikis[wikiId]);
        setAttribute('value', iKiwiDistantWikis[wikiId]);
        appendChild(document.createTextNode(iKiwiDistantWikis[wikiId]));
      }
      if (iKiwiDistantWikis[wikiId] == iKiwiDefaultDistantWiki)
        option.setAttribute('selected', 'selected');
      distantWiki.appendChild(option);
    }

    // TODO autocomplétion
    var input = document.createElement('input');
    with (input)
    {
      setAttribute('id', 'iKiwiExtPage');
      setAttribute('type', 'text');
      setAttribute('value', wgPageName.replace(/_/g, ' '));
    }

    var warning = document.createElement('strong');
    with (warning)
    {
      setAttribute('id', 'iKiwiWarning');
      setAttribute('style', 'display:none');
      appendChild(document.createTextNode(''));
    }

    var redirect = document.createElement('em');
    with (redirect)
    {
      setAttribute('id', 'iKiwiRedirect');
      setAttribute('style', 'display:none;');
      appendChild(document.createTextNode(''));
    }

    var follow = document.createElement('input');
    with (follow)
    {
      setAttribute('id', 'iKiwiFollow');
      setAttribute('type', 'checkbox');
      if (!document.getElementById('ca-watch') || iKiwiWatchOthers || iKiwiWatchMain && !wgNamespaceNumber)
        setAttribute('checked', 'checked');
    }

    var followLabel = document.createElement('label');
    with (followLabel)
    {
      setAttribute('for', 'iKiwiFollow');
      appendChild(document.createTextNode(iKiwiI18n(wgUserLanguage, 'follow')));
    }

    var submit = document.createElement('input');
    with (submit)
    {
      setAttribute('id', 'iKiwiSubmit');
      setAttribute('name', 'iKiwiSubmit');
      setAttribute('type', 'submit');
      setAttribute('value', iKiwiI18n(wgUserLanguage, 'publish'));
      setAttribute('disabled', 'disabled');
      setAttribute('onClick', 'javascript:iKiwiPublish(); return false;')
    }

    var preview = document.createElement('input');
    with (preview)
    {
      setAttribute('id', 'iKiwiPreview');
      setAttribute('name', 'iKiwiPreview');
      setAttribute('type', 'submit');
      setAttribute('value', iKiwiI18n(wgUserLanguage, 'preview'));
      setAttribute('onClick', 'javascript:iKiwiAddInterWikis(); return false;')
    }

    iForm.appendChild(fieldSet);

    with (fieldSet)
    {
      appendChild(legend);
      appendChild(label);
      appendChild(document.createElement('br'));
      appendChild(distantWiki);
      appendChild(document.createTextNode(' '));
      appendChild(input);
      appendChild(warning);
      appendChild(redirect);
      appendChild(document.createElement('br'));
      appendChild(follow);
      appendChild(followLabel);
      appendChild(document.createElement('br'));
      appendChild(submit);
      appendChild(preview);
    }

    document.getElementById('content').insertBefore(iForm, document.getElementById('firstHeading'));
  }

  if (!iKiwiPanelNextState && typeof (autoPreview) != 'undefined' && autoPreview)
    iKiwiAddInterWikis();
}

function iKiwiAddLinks()
{
  var link1 = document.createElement('a');
  with (link1)
  {
    setAttribute('href', 'javascript:iKiwiSelectPage();');
    setAttribute('id', 'iKiwiDisplayPanel');
    setAttribute('title', iKiwiI18n(wgUserLanguage, 'panel'));
    appendChild(document.createTextNode('iKiwi'));
  }
 
  var link2 = document.createElement('a');
  with (link2)
  {
    setAttribute('href', 'javascript:iKiwiSelectPage(true);');
    setAttribute('id', 'iKiwiDisplayPanel');
    setAttribute('title', iKiwiI18n(wgUserLanguage, 'panel') + ' (' + iKiwiI18n(wgUserLanguage, 'autopreview') + ')');
    appendChild(document.createTextNode('+'));
  }

  var links = document.createElement('p');
  with (links)
  {
    setAttribute('id', 'iKiwiLinks');
    appendChild(document.createTextNode('['));
    appendChild(link1);
    appendChild(document.createTextNode('|'));
    appendChild(link2);
    appendChild(document.createTextNode(']'));
  }

  document.getElementById('content').insertBefore(links, document.getElementById('firstHeading'));
}

function iKiwiAddPreviewLinks()
{
  var lis = document.getElementsByTagName('li');
  for (var liId = 0; liId < lis.length; ++liId)
  {
    var sourceLanguage = 'en';
    var language = /\/([a-z]{2})fr/.exec(location.href);
    if (language)
      sourceLanguage = language[1];
    // TODO set iKiwiSourceArticle
    // TODO add another iKiwi link for the distant wiki article
    var interWiki = iKiwiHtmlInterWiki.exec(lis[liId].innerHTML);
    if (interWiki)
      lis[liId].innerHTML = lis[liId].innerHTML.replace(iKiwiHtmlInterWiki, interWiki[0] + ' <sup><a href="' + mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?title=' + interWiki[1] + '&iKiwiAutoPreview&iKiwiFromPIW&iKiwiSourceLanguage=' + sourceLanguage + '" title="' + interWiki[2] + ' (iKiwi)"><img alt="iKiwi" src="http://upload.wikimedia.org/wikipedia/commons/e/eb/Demi_kiwi.gif" width="10px" /></a></sup>');
  }
}

function iKiwi()
{
  if (location.href.indexOf('&xssServe') != -1)
    iKiwiXssServer();
  else
  {
    var autoPreview = location.href.indexOf('&iKiwiAutoPreview') != -1;
    if ((iKiwiDisplayPanel || autoPreview) && [0, 2, 4, 6, 10, 12, 14, 100, 102, 104].indexOf(wgNamespaceNumber) != -1)
      iKiwiAddLinks();
    if (autoPreview)
      iKiwiSelectPage(true);
    if (location.href.indexOf('Projet:Interwikification/') != -1)
      iKiwiAddPreviewLinks();
  }
}

$(iKiwi);