Jump to content

User:Lupin/standard.js

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by Lupin (talk | contribs) at 20:35, 4 August 2005. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

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.
////////////////////////////////////////////////////////////////////
// Utility functions
////////////////////////////////////////////////////////////////////

// eg sourceJS('http://www.bosrup.com/web/overlib/overlib.js');

function sourceJS(url) {
  var str='<script type="text/javascript" src="';
  str += url;
  str += '"></script>';
  return document.write(str);
}

// eg sourceWikipediaJS('en.wikipedia.org', 'User:Lupin/overlib.js');

function sourceWikipediaJS(wiki, name) {
  var url='http://' + wiki + '/w/index.php?title=';
  url += name;
  url += '&action=raw&ctype=text/javascript&dontcountme=s';
  return sourceJS(url);
}

// eg sourceLupinJS('overlib');

function sourceLupinJS(name) {
  return sourceWikipediaJS('en.wikipedia.org', 'User:Lupin/'+name + '.js');
}

////////////////////////////////////////////////////////////////////
// Popup stuff
////////////////////////////////////////////////////////////////////

sourceLupinJS('overlib');
sourceLupinJS('md5-2.2alpha');

// this shouldn't be needed. maybe my cache needs purging...
function md5_hex(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }

//////////////////////
// GLOBAL VARIABLES //
//////////////////////

// regexes

var exceptions=/((title=|\/)Special:|section=[0-9])/ ;
var contributions=/(title=|\/)Special:Contributions(&target=|\/|\/User:)(.*)/ ;
var talk=/Talk:/i ;

var re; 
var titlebase;

var whichWiki=window.location.href.split('.org/')[0];

// we're not set up for interwiki stuff yet - only affect en and commons links
if (whichWiki=='http://commons.wikimedia') {
  titlebase='http://commons.wikimedia.org/w/index.php?title=';
  re=/[^:]*:\/\/commons\.wikimedia\.org\/w(iki\/|\/index\.php\?title=)([^&]*)/
} else {
  titlebase='http://en.wikipedia.org/w/index.php?title=';
  re=/[^:]*:\/\/en\.wikipedia\.org\/w(iki\/|\/index\.php\?title=)([^&]*)/
} 

var imageSources=new Array ();
imageSources.push(
   {active: false, wiki: 'en',      thumb: true,  width: popupImageSize}, 
   {active: false, wiki: 'en',      thumb: true,  width: 180}, // default
   {active: false, wiki: 'en',      thumb: true,  width: 120}, // gallery
   {active: false, wiki: 'en',      thumb: true,  width: 200}, // common?
   {active: false, wiki: 'en',      thumb: true,  width: 210},
   {active: false, wiki: 'en',      thumb: true,  width: 230},
   {active: false, wiki: 'en',      thumb: true,  width: 250}, // common?
   {active: false, wiki: 'en',      thumb: true,  width: 300},
   {active: false, wiki: 'en',      thumb: false, width: 0},
   {active: false, wiki: 'commons', thumb: true,  width: popupImageSize},
   {active: false, wiki: 'commons', thumb: true,  width: 180},
   {active: false, wiki: 'commons', thumb: true,  width: 120},
   {active: false, wiki: 'commons', thumb: false, width: 0} // no ,
   );

// downloading images are put here
var imageArray=new Array();

// check to see if images are done with this timer
var popupImageTimer=null;

// misc debug messages
var popupDebug=null;

// These are for checkImages()
var counter=0;
var checkImagesTimer=null;
var loopcounter=0;

// ids change with each popup: popupImage0, popupImage1 etc
var popupImageId=0;

var kateBase='http://kohl.wikimedia.org/~kate/cgi-bin/count_edits' 
             + '?dbname=enwiki&user='

// for myDecodeURI
var decodeExtras = new Array ();
decodeExtras.push ( 
  {from: '%2C', to: ',' },
  {from: '_',   to: ' ' },
  {from: '%26',   to: '&' } // no ,
  );

var popupImagesToggleSize=true;
var popupImageSize=60;

// user-settable parameters and defaults
var dpopupDelay=1.5;
var dpopupFgColor='#CCCCFF';
var dpopupBgColor='#333399';
var dremoveTitles=true;
var dimagePopupsForImages=true;

var popupDelay;
var popupFgColor;
var popupBgColor;
var removeTitles;
var imagePopupsForImages;

/////////////////////
// HTML GENERATION //
/////////////////////

// generate html for popup image
// <a id="popupImageLinkn"><img src="" .. id="popupImagen">
// where n=popupImageId
function imageHTML(article) {
  var imgurl=''; // imageURL(article, 'en');
  var ret='';
  if (imgurl != null) {
    popupImageId++;
    ret+='<a id="popupImageLink' + popupImageId + '">';
    ret += '<img src="' + imgurl + 
           '" width=' + popupImageSize + 
           ' align="right" valign="top" + id="popupImage' + popupImageId 
           + '"></img>';
    ret+='</a>';
  }
  return ret;
}


var xmlhttp;

function newDownload() {
  // Source: http://jibbering.com/2002/4/httprequest.html
  xmlhttp=false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
  // JScript gives us Conditional compilation, 
  // we can cope with old IE versions.
  // and security blocked creation of the objects.
  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
    try {
     xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (E) {
     xmlhttp = false;
    }
   }
@end @*/
  if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
    xmlhttp = new XMLHttpRequest();
  }
}

function getWiki(wikipage, pageComplete) {
  var url=titlebase;
  url += wikipage;
  url += '&action=raw';
  // alert('wikipage = '+wikipage+'\nurl = ' +url);
  var completeCached = function () { pageComplete(); addPageToCache();}
  return getPageWithCaching(url, completeCached);
}

function abortCurrentDownload() {
  if (xmlhttp) {
    try { gUrl = null; xmlhttp.abort(); }
    catch (anerror) {return 'could not abort old xmlhttp obj';}
  }
  return true;
}

function cachedPage (url,data) {
  this.url=url;
  this.data=data;
}

var gCachedPages = new Array ();

function findInPageCache(url) {
  alert ('findInPageCache(' + url + 
         ')\n gCachedPages.length = '+gCachedPages.length);
  for (var i=0; i<gCachedPages.length; ++i) {
    if (url==gCachedPages[i].url) return i;
  }
  return -1;  
}

function dummyXmlHttp(data) {
  this.send = function(arg) {return this.onreadystatechange();};
  this.responseText = data;
  this.onreadystatechange = null;
  this.abort = function () {return true;};
}

// add the data to the cache under url gUrl
function addPageToCache() {
  var newPage = new cachedPage(gUrl, xmlhttp.responseText);
  return gCachedPages.push(newPage);
}

// check cache to see if page exists
function getPageWithCaching(url, donefunction) {
  // donefunction should add the page to the cache once it's downloaded
  var i=findInPageCache(url);
  if (i > -1) {
    abortCurrentDownload();
    cachedPage=gCachedPages[i];
    xmlhttp = new dummyXmlHttp(cachedPage.data);
    donefunction();    
  } else {
    return getPage(url, donefunction);
  }
}

var gUrl=null; // yuck :(

function getPage(url, donefunction) {

  abortCurrentDownload();
  
  // init the global xmlhttp object
  newDownload();

  // alert('getting '+url);
  if (!xmlhttp) return null;

  gUrl = url;

  try {xmlhttp.open("GET", url, true); }
  catch(err){ return 'getPage: could not GET';} 
  xmlhttp.onreadystatechange=function() {
    if (xmlhttp.readyState==4) { // finished
      donefunction();
    }
  }
  return xmlhttp.send(null);
}


function doneWiki() { // for testing test
  alert('Download complete. Got\n\n' + xmlhttp.responseText);
}

function articleFromAnchor(a) {
  var h=a.href;

  var contribs=contributions.exec(h);
  if (contribs != null) {
    article='User:'+contribs[3];
  } else {
    var m=re.exec(h);
    article=m[2];
  }
  return article;
}

// Generate html for whole popup
// this is ugly
function popupHTML (a) {

  var c=a.className;
  // if (c=='new') alert('new!');

  var article = articleFromAnchor(a);

  var hint=a.originalTitle;
  if (hint == '' || hint == null)
    hint = myDecodeURI(article);

  var html='';
  
  html +=imageHTML(article);

  html+='<b>';
  html+=titledWikiLink(article, 'view', myDecodeURI(article), hint);
  html+='</b>';

  html+='<span id="popupImageStatus'+popupImageId+'"></span>';

  // Get rid of anchor now
  article=removeAnchor(article);

  if (userName(article) != null) {
    html += ' ' + contribsLink(article, 'contribs');
    html += ' ' + kateLink(article, 'count');
  }

  html += '<br>' + wikiLink(article, 'edit', 'edit');
  html += ' ' + wikiLink(article, 'history', 'history');
  html += ' (' + wikiLink(article, 'unwatch', 'un') + ')';
  html += wikiLink(article, 'watch', 'watch');
  var t=talkPage(article);
  if (t != null) html += ' ' + wikiLink(t, 'view', 'talk') + 
                         ' ' + wikiLink(t, 'edit', 'editTalk') +
                         ' ' + wikiLink(t, 'edit&section=new', 'newTopic');
  var ta=articleFromTalkPage(article);
  if (ta != null) html +=' ' + 
                         wikiLink(article, 'edit&section=new', 'newTopic') +
                         ' ' + wikiLink(ta, 'view', 'article') + 
                         ' ' + wikiLink(ta, 'edit', 'editArticle');
                         
  html += '<br>' + specialLink(article, 'Whatlinkshere', 'whatLinksHere');
  html += ' ' + specialLink(article, 'Recentchangeslinked', 'relatedChanges');

  html += '<span id="popupGubbins' + popupImageId + '"></span>';

  return html;
}  

/////////////////////
// LINK GENERATION //
/////////////////////

function wikiLink(article, action, text) {
  var prehint=null;

  switch (action) {
    case 'edit':             prehint = 'Edit ';                 break;
    case 'history':          prehint = 'Show history for ';     break;
    case 'unwatch':          prehint = 'Stop watching ';        break;
    case 'watch':            prehint = 'Watch ';                break;
    case 'view':             prehint = 'Go to ';                break;
    case 'edit&section=new': prehint = 'Start a new topic on '; break;
    default: true;
  }
  
  var hint;
  if (prehint != null) hint=prehint + myDecodeURI(article);
  else prehint = myDecodeURI(article + '&action=' + action);
  return titledWikiLink(article, action, text, hint);
}

function titledWikiLink(article, action, text, title) {
  var base = titlebase +  article;
  var url=base;
  // no need to add action&view, and this confuses anchors
  if (action != 'view') url = base + '&action=' + action;

  var hint;
  if (title == null || title == '')
    hint = ''
  else 
    hint = 'title="' + title + '"'; 

  return '<a href="' + url + '"' + hint + '>' + text + '</a>';
}

function specialLink(article, specialpage, text) {
  var base = titlebase +  'Special:'+specialpage;
  var url = base + '&target=' + article;
  var prehint=null;
  switch (specialpage) {
    case 'Whatlinkshere': 
          prehint='Show the articles which link to '; break;
    case 'Recentchangeslinked': 
          prehint='Show recent changes in articles related to '; break;
    case 'Contributions': 
          prehint='Show the contributions made by '; break;
  }
  var hint;
  if (prehint != null) hint = prehint + myDecodeURI(article);
  else hint = myDecodeURI(specialpage+':'+article) ;
  return '<a href="' + url + '" title="' + hint + '">' + text + '</a>';
}

function contribsLink(article, text) {
  return specialLink(userName(article), 'Contributions', text);
}

function kateLink(article, text) {
  var uN=userName(article);
  return '<a href="' + kateBase + uN + '" title="'
          + 'Count the contributions made by ' + uN + '">' + text + '</a>';
}

////////////////////////////
// MANIPULATION FUNCTIONS //
////////////////////////////

function talkPage(article) {
  if (article.indexOf('Talk:') > -1 || article.indexOf('talk:') > -1 ) 
    return null;

  var i=article.indexOf(':');
  if (i == -1) return 'Talk:'+article;
  else return article.substring(0,i)+'_talk:' + article.substring(i+1);
}

function articleFromTalkPage(talkpage) {
  var i=talkpage.indexOf('Talk:');
  var j=talkpage.indexOf('_talk:');
  if ( i == -1 && j  == -1 ) 
    return null;
  if ( i > -1 ) return talkpage.substring(i+5);
  return talkpage.split('_talk:').join(':');
}

function userName(article) {
  var i=article.indexOf('User');
  var j=article.indexOf(':');
  if  (i != 0 || j < -1) return null;
  var k=article.indexOf('/');
  if (k==-1) return article.substring(j+1);
  else return article.substring(j+1,k);
}

function stripNamespace(article) {
  // this isn't very sophisticated 
  // it just removes everything up to the final :
  var list = article.split(':');
  return list[list.length-1];
}

function imagePathComponent(article) {
  if (isImage(article)) {
    var stripped=stripNamespace(article);
    var forhash=myDecodeURI(stripped).split(' ').join('_');
    var hash=md5_hex(forhash);
    var pathcpt=hash.substring(0,1) + '/' + hash.substring(0,2) + '/';
    return pathcpt;
  }
  else return null;
}

function imageURL(img, wiki) {
  if (popupDebug > 10) alert ('imageURL\n\nimg=' + img + '\nwiki='+wiki);
  var imgurl=null;
  if (isImage(img)) {
    var pathcpt = imagePathComponent(img);
    var stripped=stripNamespace(img);
    imgurl="/media/wikipedia/" + wiki + '/'
            + pathcpt + stripped;
  }
  return imgurl;
}

function imageThumbURL(img, wiki, width) {
  //  
  // eg /media/wikipedia/en/thumb/6/61/ 
  //           Rubiks_cube_solved.jpg/120px-Rubiks_cube_solved.jpg

  var imgurl=null;
  if (isImage(img)) {
    var pathcpt = imagePathComponent(img);
    var stripped=stripNamespace(img);
    imgurl="/media/wikipedia/" + wiki + "/thumb/"
            + pathcpt + stripped + '/' + width +"px-" + stripped;
  }
  return imgurl;
}

function myDecodeURI (str) {
  var ret=decodeURI(str);
  for (var i=0; i<decodeExtras.length; ++i) {
    var from=decodeExtras[i].from;
    var to=decodeExtras[i].to;
    ret=ret.split(from).join(to);
  }
  return ret;
}

function myEncodeURI (str) {
  var ret=str;
  for (var i=0; i<decodeExtras.length; ++i) {
    var from=decodeExtras[i].from;
    var to=decodeExtras[i].to;
    ret=ret.split(to).join(from);
  }
  ret=encodeURI(ret);
  return ret;
}


function removeAnchor(article) {
  // is there a #? if not, we're done
  var i=article.indexOf('#');
  if (i == -1) return article;

  // head#tail
  var head = article.substring(0,i);
  var tail = article.substring(i+1);

  return head;
}

///////////
// TESTS //
///////////

function isInNamespace(article, namespace) {
  var i=article.indexOf(namespace+':');
  var j=article.indexOf(namespace+'_talk:');
  if  (i == -1 && j == -1) return false;
  return true;
}

function isImage(thing) {
  return isInNamespace(thing, 'Image');
}

function isImageOk(img)
{   
    // IE test
    if (!img.complete)
        return false;

    // gecko test
    if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0)
        return false;

    // No other way of checking: assume it's ok.
    return true;
}

function anchorContainsImage(a) {
  // iterate over children of anchor a
  // see if any are images
  if (a===null) return false;
  kids=a.childNodes;
  for (var i=0; i<kids.length; ++i) {
    if (kids[i].nodeName=='IMG') return true;
  }
  return false;
}

/////////////
// ACTIONS //
/////////////

// popupDebug=5;

function loadThisImage (image) {
  var msg = '';
  msg += 'loadImages; image=' + image;
  msg += '\nimagePathComponent(image) = ' + imagePathComponent;
  var stripped=stripNamespace(image);
  var forhash=myDecodeURI(stripped).split(' ').join('_');
  var hash=md5_hex(forhash);
  var pathcpt=hash.substring(0,1) + '/' + hash.substring(0,2) + '/';
  msg +='\n\nbreakdown:\n stripped==stripNamespace(image)='+stripped;
  msg +='\nforhash=myDecodeURI(stripped).split(" ").join("_")='+forhash;
  msg +='\nhash=md5_hex(forhash)-' +hash;
  msg +='\npathcpt='+pathcpt;
  
  if(popupDebug != null)
    alert(msg);
  
  msg='List of urls:\n';
  for (var i=0; i<imageSources.length; ++i) {

    var url;
    
    // reset
    imageSources[i].active=false;

    
    if (imageSources[i].thumb) 
      url=imageThumbURL(image, imageSources[i].wiki, imageSources[i].width);
    else 
      url=imageURL(image, imageSources[i].wiki);
    
    msg += '\n'+url;    

    imageArray[i]=new Image();
    imageArray[i].src=url;

  }
  
  if (popupDebug) alert (msg);

  if (popupImageTimer != null) {
    clearInterval(popupImageTimer);
    counter=0;
  }
  gImage=image;
  popupImageTimer=setInterval("checkImages()", 250);
  return;
}


var gImage=null; // global for image

function loadImages(article) {
  if(! isImage(article) ) return;
  if (popupDebug) alert('loadImages, article='+article);
  return loadThisImage(article);
}

function getImageStatus() { // this doesn't seem to work :(
  var popupImageStatus=
           document.getElementById("popupImageStatus"+popupImageId);
  if (popupImageStatus != null) {
    return popupImageStatus.innerHTML;
  } else return null;
}

function setImageStatus(str) {
  var popupImageStatus=
           document.getElementById("popupImageStatus"+popupImageId);
  if (popupImageStatus != null) {
    popupImageStatus.innerHTML=str;
    return true;
  } else return null;
}

function checkImages() {

  if (checkImagesTimer!=null) {
    clearInterval(checkImagesTimer);
    checkImagesTimer=null;
    if (loopcounter > 10); {loopcounter=0; return;}
    loopcounter++;
  } else counter++;

  // document.title=counter + ',' + loopcounter;

  var status =  ( counter % 2 ) ? '*' : '.' ;
  setImageStatus(status);

  if (counter > 100) {counter = 0; clearInterval(popupImageTimer);}

  var popupImage=null;
  popupImage=document.getElementById("popupImage"+popupImageId);
  if (popupImage == null) {
    // this doesn't seem to happen any more in practise for some reason
    // still, I'll leave it in
    checkImagesTimer=setInterval("checkImages()",333);
    return;
  }
      
  // get the first image to successfully load
  // and put it in the popupImage
  for(var i = 0; i < imageArray.length; i++) {
    if(isImageOk(imageArray[i])) {
      // stop all the gubbins, assign the image and return

      clearInterval(popupImageTimer);

      if(isImage(gImage)) {
        popupImage.src=imageArray[i].src;
        imageSources[i].active=true;
        setPopupImageLink(gImage, imageSources[i].wiki);
        stopImagesDownloading();
      }

      setImageStatus('');

      // reset evil nonconstant globals
      var l=imageArray.length;
      imageArray=null; imageArray=new Array();
      popupImageTimer=null;

      counter=0;
      loopcounter=0;

      return popupImage.src; 
    }
  }
}

function stopImagesDownloading() {
  gImage=null;
  if (imageArray == null) return null;
  var i;
  for (i=0; i<imageArray.length; ++i) {
    imageArray[i].src='';
  }
  return i;
}

function toggleSize() {
  var imgContainer=this;
  if (!imgContainer) { alert('imgContainer is null :/'); return;}
  img=imgContainer.firstChild;
  if (!img) { alert('img is null :/'); return;}
  var msg='';  
  for (var i=0; i<imgContainer.childNodes.length; ++i)
    msg += '\nimgContainer.childNodes['+i+'].width=' +            
              imgContainer.childNodes[i].width;
  if (!img.style.width || img.style.width=='')
    img.style.width='100%'; 
  else img.style.width=''; // popupImageSize+'px';
}

function setPopupImageLink (img, wiki) {
  if( wiki === null || img === null ) return null;
  
  var a=document.getElementById("popupImageLink"+popupImageId);
  if (a === null) return null; 

  var linkURL = imageURL(img, wiki); 
  if (linkURL != null) {
    if (popupImagesToggleSize) {
      a.onclick=toggleSize;
      a.title='Toggle image size';
    } else {
    a.href=linkURL;
    a.title='Open full-size image';
    }
  }
  return linkURL;
}

function setupTooltips() {
  var anchors=document.getElementsByTagName('A');
  // alert(anchors.length + 'anchors');
  var s='';
  
  if (removeTitles==null) removeTitles=dremoveTitles;

  for (var i=0; i<anchors.length; ++i)
  {
    var a=anchors[i];
    var h=a.href;
    var contribs=contributions.exec(h);
    var exc=exceptions.exec(h);
    var m=re.exec(h);
    if (contribs != null || (exc == null && m != null) ) {
      a.onmouseover=mouseOverWikiLink;
      a.onmouseout= mouseOutWikiLink;
      if (removeTitles) {
        a.originalTitle=a.title;
        a.title='';
      }
    }
  }
}


//////////////
// THINGIES //
//////////////

function mouseOverWikiLink() {
  // FIXME: should not generate the HTML until the delay has elapsed,
  //        and then popup immediately. Can be a CPU hog otherwise.
  
  var a=this;
  var html = popupHTML(a);
  var article=articleFromAnchor(a);  

  if (popupImageTimer != null) {
    clearInterval(popupImageTimer);
    counter=0;
  }

  if (popupDelay==null) popupDelay=dpopupDelay;
  if (popupFgColor==null) popupFgColor=dpopupFgColor;
  if (popupBgColor==null) popupBgColor=dpopupBgColor;

  overlib(html, STICKY, MOUSEOFF, WRAP, CELLPAD, 5, 
	  OFFSETX, 2, OFFSETY, 2, DELAY, popupDelay*1000,
          FGCOLOR, popupFgColor, BGCOLOR, popupBgColor);
  
  if (imagePopupsForImages == null) 
    imagePopupsForImages = dimagePopupsForImages;

  var previewImage=true;

  gImage=null;

  if (  
      isImage(article) &&   
        ( imagePopupsForImages || ! anchorContainsImage(a) )
     ) 
  {
    loadImages(article);
  }
  else if (!isImage(article) && previewImage) {
    redirCount=0;
    loadPreviewImage(article);
  }
}

function loadPreviewImage(article) {
  var imgStatus; 
  //=getImageStatus();
  //if(imgStatus!=null) setImageStatus(imgStatus + '.');
  //else { 
    imgStatus='';
    for (var i=0; i<redirCount+2; ++i) imgStatus += '.';
    // alert('imgStatus='+imgStatus);
    setImageStatus(imgStatus);
  //} 
  var ret=getWiki(article, insertPreviewImage);

  // alert ('loadPreviewImage\narticle = '+article+'\nret='+ret);
  // document.title='loadPreviewImage, getWiki('+article+')='+ret;
  return ret;
}

var redirCount=0;

function insertPreviewImage() {
  var wikiText=xmlhttp.responseText;
  // document.title += '; got '+wikiText.length+' characters';
  // alert ('insertPreviewImage\nwikiText='+wikiText);
  var redirectRegex= /[ \n]*[#]redirect[ \n]*\[\[(.*)\]\]/i ;
  var redirMatch = redirectRegex.exec(wikiText);
  if (redirMatch && redirCount==0) {
    // alert ('redirecting to '+redirMatch[1]);
    // document.title= 'redirecting to '+redirMatch[1];
    ++redirCount;
    return loadPreviewImage(redirMatch[1], insertPreviewImage);
  } else redirCount=0;
  setImageStatus('');

  var imageRegex= /\[\[Image: *([^|\]]*[^|\] ]) */ ;
  var match=imageRegex.exec(wikiText);
  var imagePage=null;
  if (match) {
    var matched=match[1];
    if (matched[0] >= 'a' && matched[0] <= 'z') {
      // upcase first character if ascii
      matched = matched[0].toUpperCase() + matched.substring(1);
    }
    imagePage='Image:'+matched;
  }
  if(imagePage) {
    // alert('wikiText='+wikiText+'\n\nimagePage=' + imagePage);
    // alert ('imagePage=' + imagePage);
    imagePage=myEncodeURI(imagePage);
    loadThisImage(imagePage);
  }
}

function mouseOutWikiLink () {
  // o3_showingsticky should be defined in overlib.js
  if ( typeof o3_showingsticky != "undefined" && o3_showingsticky == 0 ) {
    cClick();
    abortCurrentDownload();
    stopImagesDownloading();
  }
}

////////////////////////////////////////////////////////////////////
// Live Preview stuff
// [[User:Pilaf/livepreview.js]] 
////////////////////////////////////////////////////////////////////
wpUserName   = 'Lupin';   // User name to display in signatures
wpShowImages = true;      // Enable downloading and displaying of images

document.write('<script type="text/javascript" src="http://en.wikipedia.org/w/index.php?title=User:Pilaf/livepreview.js&action=raw&ctype=text/javascript&dontcountme=s"></script>');

function livePreview() {
  var cleaner = "<br style=\\'clear:both;\\' />";
  document.getElementById('PreviewBox').innerHTML = wiki2html(document.editform.wpTextbox1.value) + cleaner;
  window.location.replace(window.location.href + '#livePreview');
}

function installLivePreview()
{
 copywarn = document.getElementById('editpage-copywarn');
 if (copywarn != null) {
  LivePreviewHTML = '<a name="livePreview"><input type="button" accesskey="r" title="Live preview [alt-R]" value="Live Preview" onclick="livePreview();" /></a>';
  LivePreviewHTML += '<div style="margin-top: 5px; margin-bottom: 5px; padding: 5px; border: 3px double orange;" id="PreviewBox"></div>';
  copywarn.innerHTML = LivePreviewHTML + copywarn.innerHTML;
  } 
}

////////////////////////////////////////////////////////////////////
// Editing tools
////////////////////////////////////////////////////////////////////

var editbox;
var lastsearch='';

function getSearchStart() {
  l=editbox.value.length;
  m=editbox.selectionEnd;
  // alert('length: '+l+'\nselectionEnd:'+m);                                                                                                            
  if ( l > m ) return m;
  else return 0;
}

function taFind(str) {
  if (str == null || str == '') {
    searchRe=prompt('Find regex:', lastsearch);
    if (searchRe == null || searchRe == '') return;
    lastsearch=searchRe;
  }
  else searchRe=str;
  re=new RegExp(searchRe, "");
  n=getSearchStart();
  txt=editbox.value.substring(n); // forward searching                                                                                                   
  // alert('searching in\n'+txt);                                                                                                                        
  match=re.exec(txt);
  if (!match) {
    editbox.focus();
    alert ('Could not match this regex:\n\n'+searchRe);
    return;
  }
  pos=match.index;
  len=match[0].length;
  editbox.setSelectionRange(n+pos,n+pos+len);
  editbox.focus();
}

function replaceInteractive() {
  var s = prompt("Replace regexp?", lastsearch);
  if(s) {
    var r = prompt("Replace regexp\n\n" + s + "\nwith what?");
    if(!r && r != '') return;
    lastsearch=s;
    replace(s,r);
  }
}

function replace(s,r) {
  editbox.value = editbox.value.replace(new RegExp(s, "g"), r);
  editbox.focus();
}

function fixExternalLinks() {
  replace('==* *[Ee]xternal *[Ll]inks* *=* *', '== External links ==');
}

function gotoLine() {
  var lines=editbox.value.split('\n');
  var lineno=parseInt(prompt('Go to which line?'));
  if (lineno===null) {alert('Bad line: '+lineno); return; }
  var ch=0;
  for (var i=0; i<lineno; ++i) {
    ch += lines[i].length + 1;
  }
  editbox.setSelectionRange(ch,ch);
  editbox.focus();
} 
  

function morelinks() {
  if(document.title.indexOf("Editing ") == 0){
    editbox=document.editform.wpTextbox1;
    if (!editbox) lupinlog ('editbox is null on edit page' + window.location);
    (
      addlink('quickbar', 
            'javascript:replaceInteractive()', 'Replace', 'e', '')   &&
      addlink('quickbar', 
            'javascript:fixExternalLinks()', 'FixExtLinks', 'x', '') &&
      addlink('quickbar', 
              'javascript:taFind(null)', 'Find', 'f', '')            &&
      addlink('quickbar', 
              'javascript:gotoLine()', 'Go to line', '', '')            &&
      addlink('quickbar', 
              'javascript:taFind(lastsearch)', 'FindAgain', 'g', '')
    ) || lupinlog('could not add to quickbar on edit page' + window.location);

  }
  else addEditAccessKey('e');

  h=window.location.href;
  var m=re.exec(h);
  article=m[2];

  addlink ('quickbar', titlebase + m[2] + '&action=edit&section=0', 
           'EditLead', '0', '');

}

function addEditAccessKey(key) {
  // give edit this page an accesskey
  qb=document.getElementById('quickbar');
  if (qb==null) return;
  list = qb.childNodes;
  var i;
  for (var i=0; i<list.length && i > -1; ++i) {
    // this is a style-dependent hack 
    if (list[i].nodeName == 'STRONG') {
      list[i].childNodes[0].accessKey = key;
      i=-2;
    }
  }
}

function addlink(location, url, text, accesskey, id){
  var qb = document.getElementById(location);
  if (qb==null) return null;
  var na = document.createElement('a');
  na.href = url;
  na.id = id;
  if (accesskey != null && accesskey != '') na.accessKey = accesskey;
  na.title = '[alt-' + accesskey + ']';
  na.innerHTML = text;
  qb.appendChild(na);
  qb.appendChild(document.createElement('br'));
  return na;
}  

////////////////////////////////////////////////////////////////////
// Trim diffs
////////////////////////////////////////////////////////////////////
function cesarb_fixDiffOverflowTableCell(cell)
{
    var div = document.createElement("div");
    div.style.overflow = "auto";
    cell.insertBefore(div, cell.firstChild);

    while (div.nextSibling)
    {
        div.appendChild(div.nextSibling);
    }
}

function cesarb_fixDiffOverflowTable(table)
{
    var cells = table.getElementsByTagName("td");

    for (var i = 0; i < cells.length; i++)
    {
        var cell = cells[i];
        var classes = cell.className.split(" ");

        for (var j = 0; j < classes.length; j++)
        {
            if (classes[j] == "diff-context" || classes[j] == "diff-addedline" || classes[j] == "diff-deletedline")
            {
                cesarb_fixDiffOverflowTableCell(cell);
                break;
            }
        }
    }
}

function cesarb_fixDiffOverflowLoadListener(evt)
{
    var tables = document.getElementsByTagName("table");

loop:
    for (var i = 0; i < tables.length; i++)
    {
        var table = tables[i];
        var classes = table.className.split(" ");

        for (var j = 0; j < classes.length; j++)
        {
            if (classes[j] == "diff")
            {
                cesarb_fixDiffOverflowTable(table);
                break loop;
            }
        }
    }
}

////////////////////////////////////////////////////////////////////
// Trim quickbar
////////////////////////////////////////////////////////////////////

function trimQuickbar() {
  qb=document.getElementById('quickbar');
  if (qb==null) return;
  
  list=qb.childNodes;

  mode='findlink';
  for (var i=0; i<list.length; ++i)
  {
    text=list[i].innerHTML;
    if (text=='Donations' || text=='Contact us' || text=='Help')
      {
        list[i].style.display="none";
        mode='findbr';
      }
    else if (mode=='findbr' && list[i].nodeName=='BR')
      {
        list[i].style.display="none";
        mode='findlink';
      }
  }
}

////////////////////////////////////////////////////////////////////
// Crap
////////////////////////////////////////////////////////////////////

function newWin(){
  // show what the browser's seen, including document.write()s,
  // in a popup window
  win= window.open('','_blank');
  var results =document.documentElement.innerHTML;
  var match = "<";
  var re = new RegExp("<", "g");
  var newresults = results.replace(re, "&lt;");
  win.document.write(newresults );
}

var lupinMessages=''

function lupinlog(aMessage) {
  lupinMessages += aMessage + '\n';
}



////////////////////////////////////////////////////////////////////
// Run things
////////////////////////////////////////////////////////////////////

function myLoadFuncs() {
  installLivePreview();
  trimQuickbar()
  morelinks();
  cesarb_fixDiffOverflowLoadListener();
  setupTooltips();
  //  newWin();
  if (lupinMessages != '') alert (lupinMessages);
}


if (window.addEventListener) window.addEventListener("load",myLoadFuncs,false);
else if (window.attachEvent) window.attachEvent("onload",myLoadFuncs);
else{
    window._old_ABCD_onload = window.onload;
    window.onload = function(){
        window._old_ABCD_onload();
        myLoadFuncs();
    }
}

////////////////////////////////////////////////////////////////////
// Set params
////////////////////////////////////////////////////////////////////

// delay before popup appears, in seconds
popupDelay=0.6;

// show images in popups for all images (set to true)
//                       or just text links to images (set to false).
imagePopupsForImages=true;