Revision as of 15:49, 5 August 2005 view sourceLupin (talk | contribs)19,513 edits useful new features: preview first image on any article, detect redirects, give basic page information. let's hope this doesn't break...← Previous edit |
Latest revision as of 14:34, 9 February 2021 view source Xaosflux (talk | contribs)Edit filter managers, Autopatrolled, Bureaucrats, Importers, Interface administrators, Oversighters, Administrators83,869 edits expand directions |
(108 intermediate revisions by 17 users not shown) |
Line 1: |
Line 1: |
|
|
var popScript = '//en.wikipedia.org/search/?action=raw&ctype=text/javascript&title=MediaWiki:Gadget-popups.js'; |
|
//////////////////////////////////////////////////////////////////// |
|
|
|
var popStyleSheet = '//en.wikipedia.org/search/?action=raw&ctype=text/css&title=MediaWiki:Gadget-navpop.css'; |
|
// Utility functions |
|
|
|
if ( window.localCSS ) { popStyleSheet = 'http://localhost:8080/js/navpop.css'; } |
|
//////////////////////////////////////////////////////////////////// |
|
|
|
|
|
|
function time() { |
|
function popups_importScriptURI(url) { |
|
|
var s = document.createElement('script'); |
|
var d=new Date(); |
|
|
|
s.setAttribute('src',url); |
|
return d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + |
|
|
|
s.setAttribute('type','text/javascript'); |
|
'.' + (d.getTime() % 1000);warn |
|
|
|
document.getElementsByTagName('head').appendChild(s); |
|
|
return s; |
|
} |
|
} |
|
|
|
|
|
|
function popups_importStylesheetURI(url) { |
|
var gMsg=''; |
|
|
|
return document.createStyleSheet ? document.createStyleSheet(url) : popups_appendCSS('@import "' + url + '";'); |
|
function log(x) { if(gMsg!='')gMsg += '\n'; gMsg+=time() + ' ' + x; } |
|
|
|
|
|
function myalert(x) { return alert(time()+'\n'+ x); } |
|
|
|
|
|
|
|
|
// 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); |
|
|
} |
|
} |
|
|
|
|
|
|
function popups_appendCSS(text) { |
|
// eg sourceWikipediaJS('en.wikipedia.org', 'User:Lupin/overlib.js'); |
|
|
|
var s = document.createElement('style'); |
|
|
|
|
|
s.type = 'text/css'; |
|
function sourceWikipediaJS(wiki, name) { |
|
|
|
s.rel = 'stylesheet'; |
|
var url='http://' + wiki + '/search/?title='; |
|
|
|
if (s.styleSheet) s.styleSheet.cssText = text //IE |
|
url += name; |
|
|
|
else s.appendChild(document.createTextNode(text + '')) //Safari sometimes borks on null |
|
url += '&action=raw&ctype=text/javascript&dontcountme=s'; |
|
|
|
document.getElementsByTagName('head').appendChild(s); |
|
return sourceJS(url); |
|
|
|
return s; |
|
} |
|
} |
|
|
|
|
|
|
popups_importStylesheetURI(popStyleSheet); |
|
// eg sourceLupinJS('overlib'); |
|
|
|
popups_importScriptURI(popScript); |
|
|
|
|
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=)/ ; |
|
|
var contributions=/(title=|\/)Special:Contributions(&target=|\/|\/User:)(.*)/ ; |
|
|
var talk=/Talk:/i ; |
|
|
|
|
|
var re; |
|
|
var titlebase; |
|
|
|
|
|
var whichWiki=window.location.href.split('.org/'); |
|
|
|
|
|
// 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/search/?title='; |
|
|
re=/*:\/\/commons\.wikimedia\.org\/w(iki\/|\/index\.php\?title=)(*)/ |
|
|
} else { |
|
|
titlebase='http://en.wikipedia.org/search/?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; |
|
|
} |
|
|
|
|
|
function articleFromAnchor(a) { |
|
|
var h=a.href; |
|
|
|
|
|
var contribs=contributions.exec(h); |
|
|
if (contribs != null) { |
|
|
article='User:'+contribs; |
|
|
} else { |
|
|
var m=re.exec(h); |
|
|
article=m; |
|
|
} |
|
|
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§ion=new', 'newTopic'); |
|
|
var ta=articleFromTalkPage(article); |
|
|
if (ta != null) html +=' ' + |
|
|
wikiLink(article, 'edit§ion=new', 'newTopic') + |
|
|
' ' + wikiLink(ta, 'view', 'article') + |
|
|
' ' + wikiLink(ta, 'edit', 'editArticle'); |
|
|
|
|
|
html += '<br>' + specialLink(article, 'Whatlinkshere', 'whatLinksHere'); |
|
|
html += ' ' + specialLink(article, 'Recentchangeslinked', 'relatedChanges'); |
|
|
|
|
|
html += '<span id="popupWarnRedir' + popupImageId + '"></span>'; |
|
|
html += '<span id="popupGubbins' + popupImageId + '"></span>'; |
|
|
return html; |
|
|
} |
|
|
|
|
|
///////////////// |
|
|
// DOWNLOADING // |
|
|
///////////////// |
|
|
|
|
|
////////////// |
|
|
// |
|
|
// downloader |
|
|
// |
|
|
// |
|
|
|
|
|
function downloader(url) { |
|
|
// Source: http://jibbering.com/2002/4/httprequest.html |
|
|
this.http= 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 { |
|
|
this.http = new ActiveXObject("Msxml2.XMLHTTP"); |
|
|
} catch (e) { |
|
|
try { |
|
|
this.http = new ActiveXObject("Microsoft.XMLHTTP"); |
|
|
} catch (E) { |
|
|
// this.http = false; |
|
|
} |
|
|
} |
|
|
@end @*/ |
|
|
|
|
|
if (! this.http && typeof XMLHttpRequest!='undefined') { |
|
|
this.http = new XMLHttpRequest(); |
|
|
} |
|
|
|
|
|
this.url = url; |
|
|
this.id=null; |
|
|
this.callbackFunction = null; |
|
|
|
|
|
if (this.http) { |
|
|
// public |
|
|
this.send = this.http.send; |
|
|
this.abort = this.http.abort; |
|
|
} |
|
|
else this.http=false; |
|
|
} |
|
|
|
|
|
new downloader(); |
|
|
|
|
|
downloader.prototype.setCallback = function (f) { |
|
|
if(!this.http) return; |
|
|
this.http.onreadystatechange = f; |
|
|
this.callbackFunction = f; |
|
|
} |
|
|
|
|
|
downloader.prototype.runCallback = function () { |
|
|
this.callbackFunction(this); |
|
|
} |
|
|
|
|
|
downloader.prototype.getData = function () { |
|
|
if(!this.http) return; |
|
|
return this.http.responseText; |
|
|
} |
|
|
|
|
|
downloader.prototype.setTarget = function () { |
|
|
if(!this.http) return; |
|
|
this.http.open("GET", this.url, true); |
|
|
} |
|
|
|
|
|
downloader.prototype.start=function () { |
|
|
// alert('downloader instance got told to start()'); |
|
|
if(!this.http) return; |
|
|
return this.http.send(null); |
|
|
} |
|
|
|
|
|
downloader.prototype.getReadyState=function () { |
|
|
if(!this.http) return; |
|
|
return this.http.readyState; |
|
|
} |
|
|
|
|
|
function newDownload(url, id, callback) { |
|
|
var d=new downloader(url); |
|
|
d.id=id; |
|
|
d.setTarget(); |
|
|
var f = function () { |
|
|
if (d.getReadyState() == 4) |
|
|
{ d.data=d.getData(); callback(d);} |
|
|
}; |
|
|
d.setCallback(f); |
|
|
return d;//d.start(); |
|
|
} |
|
|
|
|
|
function fakeDownload(url,id,callback,data) { |
|
|
var d=newDownload(url,callback); |
|
|
d.id=id; |
|
|
d.data=data; |
|
|
return callback(d); |
|
|
} |
|
|
|
|
|
function startDownload(url, id, callback) { |
|
|
var d=newDownload(url, id, callback); |
|
|
d.start(); |
|
|
} |
|
|
|
|
|
// |
|
|
// |
|
|
// downloader |
|
|
// |
|
|
////////////// |
|
|
|
|
|
|
|
|
function getWiki(wikipage, onComplete) { |
|
|
log('getWiki, wikipage='+wikipage); |
|
|
// myalert(gMsg); |
|
|
var url = titlebase + removeAnchor(wikipage) + '&action=raw'; |
|
|
return getPageWithCaching(url, onComplete); |
|
|
} |
|
|
|
|
|
// check cache to see if page exists |
|
|
|
|
|
function getPageWithCaching(url, onComplete) { |
|
|
log ('getPageWithCaching, url='+url); |
|
|
var i=findInPageCache(url); |
|
|
if (i > -1) { |
|
|
return fakeDownload(url, popupImageId, onComplete, gCachedPages.data); |
|
|
} |
|
|
return getPage(url, onComplete); |
|
|
} |
|
|
|
|
|
function getPage(url, onComplete) { |
|
|
log ('getPage, url='+url); |
|
|
|
|
|
var callback= function (d) { |
|
|
log('callback from getPage activated'); |
|
|
addPageToCache(d); onComplete(d) } ; |
|
|
return startDownload(url, popupImageId, callback); |
|
|
} |
|
|
|
|
|
function findInPageCache(url) { |
|
|
for (var i=0; i<gCachedPages.length; ++i) { |
|
|
if (url==gCachedPages.url) { |
|
|
log('found url at index '+i); |
|
|
return i; |
|
|
} |
|
|
} |
|
|
log('did not find url='+url); |
|
|
|
|
|
return -1; |
|
|
} |
|
|
|
|
|
|
|
|
function cachedPage (url,data) { |
|
|
this.url=url; |
|
|
this.data=data; |
|
|
} |
|
|
|
|
|
function addPageToCache(download) { |
|
|
log ('addPageToCache, page.url='+download.url); |
|
|
/* |
|
|
log ('addPageToCache now calling findInPageCache'); |
|
|
if (findInPageCache(download) > -1) { |
|
|
log ('not adding - already there'); return; |
|
|
} |
|
|
log ('new page - adding'); |
|
|
*/ |
|
|
var page = new cachedPage(download.url, download.data); |
|
|
return gCachedPages.push(page); |
|
|
} |
|
|
|
|
|
/* |
|
|
var gCurrentDownload = null; |
|
|
|
|
|
function abortCurrentDownload(download) { |
|
|
if (gCurrentDownload) { |
|
|
try { gCurrentDownload.abort(); } |
|
|
catch (anerror) {return 'could not abort download object';} |
|
|
} |
|
|
return true; |
|
|
} |
|
|
*/ |
|
|
|
|
|
var gCachedPages = new Array (); |
|
|
|
|
|
///////////////////// |
|
|
// 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§ion=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; |
|
|
} |
|
|
|
|
|
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="http://upload.wikimedia.org/wikipedia/" + wiki + '/' |
|
|
+ pathcpt + stripped; |
|
|
} |
|
|
return imgurl; |
|
|
} |
|
|
|
|
|
function imageThumbURL(img, wiki, width) { |
|
|
// |
|
|
// eg http://upload.wikimedia.org/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="http://upload.wikimedia.org/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.from; |
|
|
var to=decodeExtras.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.from; |
|
|
var to=decodeExtras.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.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.active=false; |
|
|
|
|
|
|
|
|
if (imageSources.thumb) |
|
|
url=imageThumbURL(image, imageSources.wiki, imageSources.width); |
|
|
else |
|
|
url=imageURL(image, imageSources.wiki); |
|
|
|
|
|
msg += '\n'+url; |
|
|
|
|
|
imageArray=new Image(); |
|
|
imageArray.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; |
|
|
} |
|
|
|
|
|
popupHTMLTimers=new Array(); |
|
|
|
|
|
var popupHTMLLoopFunctions = new Array(); |
|
|
|
|
|
function setPopupHTML (str, elementId, popupId) { |
|
|
if (typeof popupId === 'undefined') popupId = popupImageId; |
|
|
var popupElement= |
|
|
document.getElementById(elementId+popupId); |
|
|
var timer; |
|
|
|
|
|
if (typeof popupHTMLTimers == 'undefined') { |
|
|
timer=null; |
|
|
} |
|
|
else { |
|
|
timer=popupHTMLTimers; |
|
|
} |
|
|
|
|
|
if (popupElement != null) { |
|
|
if(timer) clearInterval(timer); |
|
|
popupHTMLTimers=null; |
|
|
popupElement.innerHTML=str; |
|
|
log('setPopupElement found the '+elementId+popupId+ ' element' + |
|
|
'\nstr='+str+ |
|
|
'\npopupElement.innerHTML=' + popupElement.innerHTML); |
|
|
return true; |
|
|
} else { |
|
|
log('setPopupElement did not find the '+elementId+popupId+ ' element' + |
|
|
'\nstr='+str); |
|
|
var loopFunction=function() { setPopupHTML(str,elementId,popupId);} |
|
|
popupHTMLLoopFunctions = loopFunction; |
|
|
if (!timer) { |
|
|
var doThis = 'popupHTMLLoopFunctions()'; |
|
|
popupHTMLTimers = setInterval(doThis, 600); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function setPopupTrailer(str,id) { |
|
|
return setPopupHTML(str, 'popupGubbins', id);} |
|
|
|
|
|
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)) { |
|
|
// stop all the gubbins, assign the image and return |
|
|
|
|
|
clearInterval(popupImageTimer); |
|
|
|
|
|
if(isImage(gImage)) { |
|
|
popupImage.src=imageArray.src; |
|
|
imageSources.active=true; |
|
|
setPopupImageLink(gImage, imageSources.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.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.width=' + |
|
|
imgContainer.childNodes.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; |
|
|
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 addPostPopupHook(f) { |
|
|
var r = runPostPopupHooks; |
|
|
runPostPopupHooks = function () { r(); f(); }; |
|
|
} |
|
|
|
|
|
function runPostPopupHooks() { |
|
|
return true; |
|
|
} |
|
|
|
|
|
function mouseOverWikiLink() { |
|
|
// FIXME: should not generate the HTML until the delay has elapsed, |
|
|
// and then popup immediately. Can be a CPU hog otherwise. |
|
|
|
|
|
/* // good idea? dunno |
|
|
if ( typeof o3_showingsticky != "undefined" && o3_showingsticky != 0 ) { |
|
|
return; |
|
|
} |
|
|
*/ |
|
|
|
|
|
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; |
|
|
|
|
|
// registerHook("createPopup",runPostPopupHooks, FAFTER); |
|
|
|
|
|
// setPopupTrailer('testing1'); |
|
|
|
|
|
log('running overlib'); |
|
|
overlib(html, STICKY, MOUSEOFF, WRAP, CELLPAD, 5, |
|
|
OFFSETX, 2, OFFSETY, 2, DELAY, popupDelay*1000, |
|
|
FGCOLOR, popupFgColor, BGCOLOR, popupBgColor); |
|
|
|
|
|
// setPopupTrailer('testing2'); |
|
|
|
|
|
//log('running postPopupHooks:\n'+runPostPopupHooks); |
|
|
//runPostPopupHooks(); |
|
|
|
|
|
if (imagePopupsForImages == null) |
|
|
imagePopupsForImages = dimagePopupsForImages; |
|
|
|
|
|
var previewImage=true; |
|
|
|
|
|
gImage=null; |
|
|
|
|
|
if ( |
|
|
isImage(article) && |
|
|
( imagePopupsForImages || ! anchorContainsImage(a) ) |
|
|
) |
|
|
{ |
|
|
loadImages(article); |
|
|
} |
|
|
else if (!isImage(article) && previewImage) { |
|
|
//myalert('calling loadPreviewImage'); |
|
|
redirCount=0; |
|
|
loadPreviewImage(article); |
|
|
} |
|
|
} |
|
|
|
|
|
function loadPreviewImage(article) { |
|
|
|
|
|
// myalert ('loadPreviewImage'); |
|
|
/* var imgStatus; |
|
|
imgStatus=''; |
|
|
for (var i=0; i<redirCount+2; ++i) imgStatus += '.'; |
|
|
setImageStatus(imgStatus); */ |
|
|
var ret=getWiki(article, insertPreviewImage); |
|
|
|
|
|
return ret; |
|
|
} |
|
|
|
|
|
var redirCount=0; |
|
|
|
|
|
function countLinks(wikiText) { |
|
|
// this could be improved! |
|
|
return wikiText.split('[[').length - 1; |
|
|
} |
|
|
|
|
|
function insertPreviewImage(download) { |
|
|
log('starting insertPreviewImage'); |
|
|
if (download.id != popupImageId) { |
|
|
log('download.id='+download.id |
|
|
+' does not match popupImageId='+popupImageId); |
|
|
return; |
|
|
} |
|
|
var wikiText=download.data; |
|
|
|
|
|
log ('considering '+wikiText.length+' bytes of data, starting\n' |
|
|
+ wikiText.substring(0,50) ); |
|
|
|
|
|
var redirectRegex= /*redirect*\\]/i ; |
|
|
var redirMatch = redirectRegex.exec(wikiText); |
|
|
|
|
|
var extraPageInfo = true; |
|
|
|
|
|
var warnRedir = ''; |
|
|
|
|
|
if (redirMatch && redirCount==0) { |
|
|
log ('found a first redirect to' + redirMatch); |
|
|
// alert ('redirecting to '+redirMatch); |
|
|
// document.title= 'redirecting to '+redirMatch; |
|
|
++redirCount; |
|
|
warnRedir='<br>Redirects to '+ |
|
|
titledWikiLink(redirMatch, |
|
|
'view', |
|
|
myDecodeURI(redirMatch), |
|
|
'Bypass redirect') |
|
|
+''; |
|
|
setPopupHTML(warnRedir, 'popupWarnRedir'); |
|
|
// why doesn't this work? :( |
|
|
// myalert(warnRedir); |
|
|
return loadPreviewImage(redirMatch); |
|
|
} else redirCount=0; |
|
|
|
|
|
log('not a redirect'); |
|
|
|
|
|
setImageStatus(''); |
|
|
|
|
|
if (extraPageInfo) |
|
|
setPopupTrailer(warnRedir + '<br>'+download.data.length +' bytes, '+ |
|
|
'~'+countLinks(download.data) + ' wikiLinks' ); |
|
|
|
|
|
|
|
|
|
|
|
var imageRegex= /\]* ]) */i ; |
|
|
var match=imageRegex.exec(wikiText); |
|
|
var imagePage=null; |
|
|
if (match) { |
|
|
var matched=match; |
|
|
if (matched >= 'a' && matched <= 'z') { |
|
|
// upcase first character if ascii |
|
|
matched = matched.toUpperCase() + matched.substring(1); |
|
|
} |
|
|
imagePage='Image:'+matched; |
|
|
} |
|
|
if(imagePage) { |
|
|
log ('found imagePage='+imagePage); |
|
|
// alert('wikiText='+wikiText+'\n\nimagePage=' + imagePage); |
|
|
// alert ('imagePage=' + imagePage); |
|
|
imagePage=myEncodeURI(imagePage); |
|
|
loadThisImage(imagePage); |
|
|
} |
|
|
else log('no image found'); |
|
|
|
|
|
log ('done insertPreviewImage'); |
|
|
// myalert(gMsg); // gMsg=''; |
|
|
} |
|
|
|
|
|
function mouseOutWikiLink () { |
|
|
// o3_showingsticky should be defined in overlib.js |
|
|
if ( typeof o3_showingsticky != "undefined" && o3_showingsticky == 0 ) { |
|
|
cClick(); |
|
|
// abortCurrentDownload(); |
|
|
stopImagesDownloading(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
if ( typeof mw !== 'undefined' ) { |
|
//////////////////////////////////////////////////////////////////// |
|
|
|
mw.loader.using( , function() { |
|
// Run things |
|
|
|
var k = 'User:Lupin/popups.js', |
|
//////////////////////////////////////////////////////////////////// |
|
|
|
t = 'Information: You are importing User:Lupin/popups.js' + |
|
|
' into your User:USERNAME/common.js or User:USERNAME/<skin>.js!\n' + |
|
|
'This script is unmaintained. Please remove this inclusion and enable the Navigation popups Gadget in the preferences of your account instead.', |
|
|
x = mw.storage.get( k ); |
|
|
|
|
|
|
if ( !x ) { |
|
if (window.addEventListener) |
|
|
|
mw.storage.set( k, 1 ); |
|
window.addEventListener("load",setupTooltips,false); |
|
|
|
alert( t ); |
|
else if (window.attachEvent) |
|
|
|
} else { |
|
window.attachEvent("onload",setupTooltips); |
|
|
|
x++; |
|
else { |
|
|
|
mw.storage.set( k, x ); |
|
window._old_ABCD_onload = window.onload; |
|
|
window.onload = function() { |
|
if ( x % 25 === 0 ) { |
|
|
mw.notify( t ); |
|
window._old_ABCD_onload(); |
|
|
|
} |
|
setupTooltips(); |
|
|
} |
|
} |
|
|
}); |
|
} |
|
} |