User:Tgr/popups.js
A Wikipédiából, a szabad lexikonból.
Megjegyzés: A beállítások elmentése után frissítened kell a böngésződ gyorsítótárát, hogy a változások érvénybe lépjenek. Mozilla / Firefox / Safari: tartsd lenyomva a Shift gombot és kattints a Reload / Frissítés gombra az eszköztáron, vagy használd a Ctrl–F5 billentyűkombinációt (Apple Mac-en Cmd–Shift–R); Internet Explorer: tartsd nyomva a Ctrl-t, és kattints a Reload / Frissítés gombra, vagy nyomj Ctrl–F5-öt; Konqueror: egyszerűen csak kattints a Reload / Frissítés gombra (vagy Ctrl–R vagy F5); Opera felhasználóknak teljesen ki kell üríteniük a gyorsítótárat a Tools→Preferences menüben.
var popupVersion="Thu Aug 11 20:38:46 EDT 2005"; // CONTENTS // Utility functions // Popup stuff // global variables // html generation // downloading // link generation // manipulation functions // tests // actions // thingies //////////////////////////////////////////////////////////////////// // Utility functions //////////////////////////////////////////////////////////////////// function time() { var d=new Date(); return d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + '.' + (d.getTime() % 1000); }; var gMsg=''; 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); }; // 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('livepreview'); 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=|\/)Speciális:|section=[0-9])/ ; var contributions=/(title=|\/)Speciális:Contributions(&target=|\/|\/User:)(.*)/ ; var emailuser=/(title=|\/)Speciális:Emailuser(&target=|\/|\/User:)(.*)/ ; var talk=/Vita:/i ; var imageRegex= /(^|\[\[)(image|kép): *([^|\]]*[^|\] ]) */img ; var imageRegexBracketCount = 2; var categoryRegex= /\[\[(category|kategória): *([^|\]]*[^|\] ]) */i ; var categoryRegexBracketCount = 1; var stubRegex= /[{][{]csonk|Ez a .* lap sajnos még .*nagyon rövid \(„csonk”\).*/im ; var disambigRegex= /[{][{]egy[eé]rt|Ez egy .*egyértelműsítő lap/im ; var ipUserRegex=/(User:)?((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])/; var re; var splitLoc=window.location.href.split('/'); var thisWiki=splitLoc[2]; var protocol=splitLoc[0].split(':')[0]; var titletail='/w/index.php?title='; // /REGEX // we're not set up for interwiki stuff yet - only affect en, commons // and wiktionary links if (thisWiki=='hu.wikibooks.org') { re=/[^:]*:\/\/hu\.wikibooks\.org\/w(iki\/|\/index\.php\?title=)([^&]*)/ ; } else if (thisWiki=='hu.wiktionary.org') { re=/[^:]*:\/\/hu\.wiktionary\.org\/w(iki\/|\/index\.php\?title=)([^&]*)/ ; } else if (thisWiki=='hu.wikiquote.org') { re=/[^:]*:\/\/hu\.wikiquote\.org\/w(iki\/|\/index\.php\?title=)([^&]*)/ ; } else { re=/[^:]*:\/\/hu\.wikipedia\.org\/w(iki\/|\/index\.php\?title=)([^&]*)/ ; } var titlebase=protocol+'://'+thisWiki+titletail; var wikibase=protocol+'://'+thisWiki+'/wiki/'; var popupImagesToggleSize=true; var popupImageSize=60; var imageSources=new Array (); imageSources.push( {active: false, wiki: thisWiki, thumb: true, width: popupImageSize}, {active: false, wiki: thisWiki, thumb: true, width: 180}, // default {active: false, wiki: thisWiki, thumb: true, width: 120}, // gallery {active: false, wiki: thisWiki, thumb: true, width: 200}, // common? {active: false, wiki: thisWiki, thumb: true, width: 210}, {active: false, wiki: thisWiki, thumb: true, width: 230}, {active: false, wiki: thisWiki, thumb: true, width: 250}, // common? {active: false, wiki: thisWiki, thumb: true, width: 300}, {active: false, wiki: thisWiki, thumb: false, width: 0} // no comma ); imageSources.push( {active: false, wiki: 'commons.wikimedia.org', thumb: true, width: popupImageSize}, {active: false, wiki: 'commons.wikimedia.org', thumb: true, width: 180}, {active: false, wiki: 'commons.wikimedia.org', thumb: true, width: 120}, {active: false, wiki: 'commons.wikimedia.org', thumb: false, width: 0} // no trailing comma ); // downloading images are put here var imageArray=new Array(); // page caching var gCachedPages = new Array (); var gImageCache = new Array(); // FIXME what is this for? var gImage=null; // global for image // 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=' switch(thisWiki) { case 'hu.wikibooks.org': kateBase += 'huwikibooks'; break; case 'hu.wikiquote.org': kateBase += 'huwikiquote'; break; case 'hu.wiktionary.org': kateBase += 'huwiktionary'; break; default: kateBase += 'huwiki'; } kateBase += '&user='; // for myDecodeURI var decodeExtras = new Array (); decodeExtras.push ( {from: '%2C', to: ',' }, {from: '_', to: ' ' }, {from: '%26', to: '&' } // no , ); // for setPopupHTML - needed for timers and stuff var popupHTMLTimers=new Array(); var popupHTMLLoopFunctions = new Array(); // FIXME - eliminate this var redirCount=0; // user-settable parameters and defaults if (typeof popupDelay == 'undefined') { var popupDelay=null; } var dpopupDelay=0.5; if (typeof popupFgColor == 'undefined') { var popupFgColor=null; } var dpopupFgColor='#CCCCFF'; if (typeof popupBgColor == 'undefined') { var popupBgColor=null; } var dpopupBgColor='#333399'; if (typeof removeTitles == 'undefined') { var removeTitles=null; } var dremoveTitles=true; if (typeof imagePopupsForImages == 'undefined') { var imagePopupsForImages=null; } var dimagePopupsForImages=true; if (typeof popupSummaryData == 'undefined') { var popupSummaryData = null; } var dpopupSummaryData=true; if (typeof simplePopups == 'undefined') { var simplePopups=null; } var dsimplePopups = false; if (typeof popupImages == 'undefined') { var popupImages=null; } var dpopupImages=true; if (typeof popupPreviews == 'undefined') { var popupPreviews=null; } var dpopupPreviews=true; if (typeof maxPreviewSentences == 'undefined') { var maxPreviewSentences=null; } var dmaxPreviewSentences=4; if (typeof maxPreviewCharacters == 'undefined') { var maxPreviewCharacters=null; } var dmaxPreviewCharacters=600; if (typeof popupNavLinks == 'undefined') { var popupNavLinks=null; } var dpopupNavLinks=true; if (typeof popupNavLinkSeparator == 'undefined') { var popupNavLinkSeparator=null; } var dpopupNavLinkSeparator=' ⋅ '; if (typeof popupOnlyArticleLinks == 'undefined') { var popupOnlyArticleLinks=null; } var dpopupOnlyArticleLinks=true; if (typeof popupNeverGetThumbs == 'undefined' ) { var popupNeverGetThumbs=null; } var dpopupNeverGetThumbs=false; if (typeof popupImagesFromThisWikiOnly == 'undefined' ) { var popupImagesFromThisWikiOnly=null; } var dpopupImagesFromThisWikiOnly=false; if (typeof popupAppendRedirNavLinks == 'undefined' ) { var popupAppendRedirNavLinks=null; } var dpopupAppendRedirNavLinks=true; // browser-specific hacks // if (typeof window.opera != 'undefined') {} if ((self.navigator.appName)=='Konqueror') { dpopupNavLinkSeparator=' • '; } if (String('abc'.split(/(b)/))!='a,b,c') { // broken String.split, e.g. konq, IE String.prototype.parenSplit=function (re) { var m=re.exec(this); if (!m) return this; return [this.substring(0,m.index)].concat(m.slice(1)).concat(this.substring(m.index+m[0].length).parenSplit(re)); }; //alert('using parenSplit hack'); } else { String.prototype.parenSplit=function (re) {return this.split(re);} } ///////////////////// // HTML GENERATION // ///////////////////// // generate html for popup image // <a id="popupImageLinkn"><img id="popupImagen"> // where n=popupImageId function imageHTML(article) { var ret=''; popupImageId++; ret+='<a id="popupImageLink' + popupImageId + '">'; ret += '<img ' + // src="' + imgurl + '" ' + /*'width=' + popupImageSize + */ ' align="right" valign="top" + id="popupImage' + popupImageId + '" style="display: none;"></img>'; ret+='</a>'; return ret; }; function isInToc(a) { return isSubElementOf(a,'toc'); } function isInArticle(a) { // content is for monobook.. damn. was hoping to avoid skin references if (document.getElementById('article')) return isSubElementOf(a, 'article'); else return isSubElementOf(a, 'content'); } function isSubElementOf(a, tag) { var obj = a; var i=0; var tagged=document.getElementById(tag); if (!tagged) return false; do {obj = obj.parentNode; ++i; } while (obj != tagged && obj.nodeName != 'HTML'); if (obj.nodeName == 'HTML') return false; return true; } function articleFromAnchor(a) { log('articleFromAnchor'); var h=a.href; var article=null; log('h='+h); var contribs=contributions.exec(h); if (contribs != null) { article='User:'+contribs[3]; return article; } var email=emailuser.exec(h); if (email != null) { article='User:'+email[3]; return article; } // no more special cases to check -- // hopefully it's not a disguised user-related page var m=re.exec(h); if(m===null) return null; 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 html=''; html +=imageHTML(article); if (popupNavLinks===null) popupNavLinks=dpopupNavLinks; var hint=a.originalTitle; if (hint == '' || hint == null) hint = myDecodeURI(article); if (popupNavLinks) html += navLinkHTML(article, hint); html += '<span id="popupWarnRedir' + popupImageId + '"></span>'; html += '<span id="popupGubbins' + popupImageId + '"></span>'; html += '<span id="popupPreview' + popupImageId + '"></span>'; return html; }; function isIpUser(user) { return ipUserRegex.test(user); } function navLinkHTML (article, hint) { var html=''; var simplifyMainLink = true; var visibleMainLinkText=myDecodeURI(article); if ( simplifyMainLink ) { var s= visibleMainLinkText.split('/'); visibleMainLinkText = s[s.length-1]; if (visibleMainLinkText == '' && s.length > 1) { // shouldn't happen... visibleMainLinkText=s[s.length-2]; } } html+='<b>'; if (typeof hint =='undefined') hint=myDecodeURI(article); html+=titledWikiLink(article, 'view', visibleMainLinkText, hint); html+='</b>'; html+='<span id="popupImageStatus'+popupImageId+'"></span>'; // Get rid of anchor now article=removeAnchor(article); if (popupNavLinkSeparator===null) popupNavLinkSeparator=dpopupNavLinkSeparator; if (userName(article) != null) { html += '<br>' + contribsLink(article, 'közre'); if (! isIpUser(userName(article))) { html += popupNavLinkSeparator + kateLink(article, 'szám'); } html += popupNavLinkSeparator + emailLink(article, 'email'); } html += '<br>' + wikiLink(article, 'edit', 'szerk'); var ta=articleFromTalkPage(article); if (ta != null) html +='|' + wikiLink(article, 'edit§ion=new', 'új'); html += popupNavLinkSeparator + wikiLink(article, 'history', 'tört'); html += popupNavLinkSeparator + wikiLink(article, 'unwatch', 'nem') + '|'; html += wikiLink(article, 'watch', 'figyel'); var t=talkPage(article); if (t != null) html += popupNavLinkSeparator + '<b>' + wikiLink(t, 'view', 'vita') + '</b>' + '|' + wikiLink(t, 'edit', 'szerk') + '|' + wikiLink(t, 'edit§ion=new', 'új'); if (ta != null) html +=popupNavLinkSeparator + '<b>' + wikiLink(ta, 'view', 'cikk') + '</b>' + '|' + wikiLink(ta, 'edit', 'szerk'); html += '<br>' + specialLink(article, 'Whatlinkshere', 'miHiv'); html += popupNavLinkSeparator + specialLink(article, 'Recentchangeslinked', 'kapcsVált'); 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 // ////////////// // Schematic for a getWiki call // // getWiki->-getPageWithCaching // | // false | true // getPage<-[findPictureInCache]->-onComplete(a fake download) // \. // (async)->addPageToCache(download)->-onComplete(download) function getWiki(wikipage, onComplete) { log('getWiki, wikipage='+wikipage); // set ctype=text/css to get around opera bug var url = titlebase + removeAnchor(wikipage) + '&action=raw&ctype=text/css'; 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[i].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[i].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); 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; } */ ///////////////////// // LINK GENERATION // ///////////////////// function wikiLink(article, action, text) { var prehint=null; switch (action) { case 'edit': prehint = 'Szerkesztés: '; break; case 'history': prehint = 'Laptörténet: '; break; case 'unwatch': prehint = 'Figyelés vége: '; break; case 'watch': prehint = 'Figyelés: '; break; case 'view': prehint = 'Ugrás: '; break; case 'edit§ion=new': prehint = 'Új fejezet: '; break; default: true; } var hint; if (prehint != null) hint=prehint + myDecodeURI(article); else hint = 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 + 'Speciális:'+specialpage; var url = base + '&target=' + article; var prehint=null; switch (specialpage) { case 'Whatlinkshere': prehint='Cikkek, amik erre hivatkoznak: '; break; case 'Recentchangeslinked': prehint='Ehhez kapcsolódó változtatások: '; break; case 'Contributions': prehint='Felhasználó közreműködései: '; break; case 'Emailuser': prehint='Email küldése: '; break; } var hint; if (prehint != null) hint = prehint + myDecodeURI(article); else hint = myDecodeURI(specialpage+':'+article) ; return '<a href="' + url + '" title="' + hint + '">' + text + '</a>'; }; function redirLink(redirMatch) { /* NB redirMatch is in wikiText */ if (popupAppendRedirNavLinks===null) popupAppendRedirNavLinks=dpopupAppendRedirNavLinks; if (popupNavLinks===null) popupNavLinks=dpopupNavLinks; if (popupAppendRedirNavLinks && popupNavLinks) return '<hr>' + 'Átirányít erre: ' + navLinkHTML(wikiMarkupToAddressFragment(redirMatch)); else return '<br> Átirányít erre: ' + titledWikiLink(myEncodeURI(redirMatch), 'view', myDecodeURI(redirMatch), 'Átirányítás átugrása'); }; function doNotRedirLink(redirPage, linkText, hintText) { /* NB redirPage is in wikiText */ var ret=titledWikiLink(myEncodeURI(redirPage), 'edit', linkText, hintText); return ret; }; function contribsLink(article, text) { return specialLink(userName(article), 'Contributions', text); }; function emailLink(article, text) { return specialLink(userName(article), 'Emailuser', text); }; function kateLink(article, text) { var uN=myDecodeURI(userName(article)); return '<a href="' + kateBase + uN + '" title="' + 'Count the contributions made by ' + uN + '">' + text + '</a>'; }; //////////////////////////// // MANIPULATION FUNCTIONS // //////////////////////////// function upcaseFirst(str) { return str.charAt(0).toUpperCase() + str.substring(1); }; function formatBytes(num) { ret = (num > 949) ? (Math.round(num/100)/10+'kB') : (num +' bájt' ) ; return ret; } function popupFilterStubDetect(data) { return (isStub(data)) ? 'csonk' : ''; } function popupFilterDisambigDetect(data) { return (isDisambig(data)) ? 'egyért' : ''; } function popupFilterPageSize(data) { return formatBytes(data.length); }; function popupFilterCountLinks(data) { var num=countLinks(data); return String(num) + ' wikiLink'; }; function popupFilterCountImages(data) { var num=countImages(data); return String(num) + ' kép'; }; function popupFilterCountCategories(data) { var num=countCategories(data); return String(num) + ' kategória'; } var popupFilters=new Array(); popupFilters.push(popupFilterStubDetect); popupFilters.push(popupFilterDisambigDetect); popupFilters.push(popupFilterPageSize); popupFilters.push(popupFilterCountLinks); popupFilters.push(popupFilterCountImages); popupFilters.push(popupFilterCountCategories); if (typeof extraPopupFilters=='undefined') { var extraPopupFilters=new Array();} function getPageInfo(data) { if (data.length == 0) return 'Üres lap'; var pageInfoArray=new Array(); for (var i=0; i<popupFilters.length; ++i) { var s=popupFilters[i](data); if (s!='') pageInfoArray.push(s); } for (var i=0; i<extraPopupFilters.length; ++i) { var s=extraPopupFilters[i](data); if (s!='') pageInfoArray.push(s); } var pageInfo=pageInfoArray.join(', '); if (pageInfo != '' ) pageInfo = upcaseFirst(pageInfo); return pageInfo; }; function getValidImageFromWikiText(wikiText) { var imagePage=null; // nb in imageRegex we're interested in the second bracketed expression // this may change if the regex changes :-( //var match=imageRegex.exec(wikiText); var matched=null; var match; while ( match = imageRegex.exec(wikiText)) { /* now find a sane image name - exclude templates by seeking { */ var m = match[2]; log('is '+m+' a valid name for an image?'); if ( isValidImageName(m) ) { matched=m; log('yes!'); break;} log('no...'); } imageRegex.lastIndex=0; if (!matched) return null; if (matched.charAt(0) >= 'a' && matched.charAt(0) <= 'z') { // upcase first character if ascii matched = upcaseFirst(matched); } imagePage='Kép:'+matched; return imagePage; }; function countLinks(wikiText) { // this could be improved! return wikiText.split('[[').length - 1; }; // if N = # matches, n = # brackets, then // String.parenSplit(regex) intersperses the N+1 split elements // with Nn other elements. So total length is // L= N+1 + Nn = N(n+1)+1. So N=(L-1)/(n+1). function countImages(wikiText) { return (wikiText.parenSplit(imageRegex).length - 1) / (imageRegexBracketCount + 1); }; function countCategories(wikiText) { return (wikiText.parenSplit(categoryRegex).length - 1) / (categoryRegexBracketCount + 1); }; function talkPage(article) { if (article.indexOf('Vita:') > -1 || article.indexOf('vita:') > -1 ) return null; var i=article.indexOf(':'); if (i == -1) return 'Vita:'+article; else return article.substring(0,i)+'_vita:' + article.substring(i+1); }; function articleFromTalkPage(talkpage) { var i=talkpage.indexOf('Vita:'); var j=talkpage.indexOf('_vita:'); if ( i == -1 && j == -1 ) return null; if ( i > -1 ) return talkpage.substring(i+5); return talkpage.split('_vita:').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 getImageUrlStart(wiki) { // this returns a trailing slash switch (wiki) { case 'hu.wikipedia.org': return 'http://upload.wikimedia.org/wikipedia/hu/'; case 'hu.wiktionary.org': return 'http://hu.wiktionary.org/upload/hu/'; default: // unsupported - take a guess var lang=wiki.split('.')[0]; return 'http://' + wiki + '/upload/' + lang +'/'; } } function imageURL(img, wiki) { if (popupImagesFromThisWikiOnly===null) popupImagesFromThisWikiOnly=dpopupImagesFromThisWikiOnly; if (popupImagesFromThisWikiOnly && wiki != thisWiki) return null; 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=getImageUrlStart(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 if (popupImagesFromThisWikiOnly===null) popupImagesFromThisWikiOnly=dpopupImagesFromThisWikiOnly; if (popupImagesFromThisWikiOnly && wiki != thisWiki) return null; if (popupNeverGetThumbs===null) popupNeverGetThumbs=dpopupNeverGetThumbs; if (popupNeverGetThumbs) return null; var imgurl=null; if (isImage(img)) { var pathcpt = imagePathComponent(img); var stripped=stripNamespace(img); imgurl=getImageUrlStart(wiki) + "thumb/" + pathcpt + stripped + '/' + width +"px-" + stripped; } return imgurl; }; // (a) myDecodeURI (first standard decodeURI, then exceptions) // (b) change spaces to underscores // (c) encodeURI (just the straight one, no exceptions) function wikiMarkupToAddressFragment (str) { // for images var ret = myDecodeURI(str); ret = ret.split(' ').join('_'); ret = encodeURI(ret); return ret; }; function addressFragmentToWikiMarkup (str) { // seemingly, not :( the inverse of wikiMarkupToAddressFragment return myDecodeURI(str); }; 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) { log ('myEncodeURI: str='+str); var ret=str; ret=encodeURI(ret); for (var i=0; i<decodeExtras.length; ++i) { var from=decodeExtras[i].from; var to=decodeExtras[i].to; ret=ret.split(to).join(from); } return ret; }; function removeAnchor(article) { // is there a #? if not, we're done var i=article.indexOf('#'); if (i == -1) return article; return article.substring(0,i); }; /////////// // TESTS // /////////// function isStub(data) { return stubRegex.test(data); } function isDisambig(data) { return disambigRegex.test(data); } function isValidImageName(str){ // extend as needed... return ( str.split('{').length == 1 ); }; function isInNamespace(article, namespace) { var i=article.indexOf(namespace+':'); var j=article.indexOf(namespace+'_vita:'); if (i == -1 && j == -1) return false; return true; }; function isImage(thing) { return isInNamespace(thing, 'Kép'); }; function isImageOk(img) { // IE test if (!img.complete) return false; // gecko test if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) return false; // maybe this'll work in konqueror and opera // konq seems to give "broken images" width 16, presumably an icon width // stupid konq // maybe it'll work with safari now :-) // note that img.width is not defined in the html with a width="..." // it's set later when the image is made visible // this would probably work in gecko too, *except for very small images* if (typeof img.width == 'undefined' || img.width <= 16) 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 // ///////////// var imageCache = new Array (); function loadThisImage (image) { if (!popupImages) return; if (!isValidImageName(image)) return false; if(popupDebug != null) alert(msg); msg='List of urls:\n'; var imageUrls=new Array(); for (var i=0; i<imageSources.length; ++i) { var url; if (imageSources[i].thumb) url=imageThumbURL(image, imageSources[i].wiki, imageSources[i].width); else url=imageURL(image, imageSources[i].wiki); for (var j=0; j<gImageCache.length; ++j) { if (url == gImageCache[j]) return loadThisImageAtThisUrl(image, url); } if (url!=null) imageUrls.push(url); } msg='imageUrls:\n'; for (var i=0; i<imageUrls.length; ++i) { var url = imageUrls[i]; imageSources[i].active=false; msg += '\n'+url; imageArray[i]=new Image(); imageArray[i].src=url; } //myalert(msg); if (popupDebug) alert (msg); if (popupImageTimer != null) { clearInterval(popupImageTimer); counter=0; } gImage=image; popupImageTimer=setInterval("checkImages()", 250); return; }; function loadThisImageAtThisUrl(image, url) { //myalert('loading "best" image:\n'+url); gImage=image; imageArray = new Array(); imageArray[0] = new Image(); imageArray[0].src=url; if (popupImageTimer != null) { clearInterval(popupImageTimer); counter=0; } popupImageTimer=setInterval("checkImages()", 250); return; }; function loadImages(article) { if(! isImage(article) ) return; if (popupDebug) alert('loadImages, article='+article); return loadThisImage(article); }; function setPopupHTML (str, elementId, popupId) { if (typeof popupId === 'undefined') popupId = popupImageId; var popupElement= document.getElementById(elementId+popupId); var timer; if (typeof popupHTMLTimers[elementId] == 'undefined') { timer=null; } else { timer=popupHTMLTimers[elementId]; } if (popupElement != null) { if(timer) clearInterval(timer); popupHTMLTimers[elementId]=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[elementId] = loopFunction; if (!timer) { var doThis = 'popupHTMLLoopFunctions["'+elementId+'"]()'; popupHTMLTimers[elementId] = setInterval(doThis, 600); } } }; function setImageStatus(str, id) { return setPopupHTML(str, 'popupImageStatus', id); }; 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++; 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; popupImage.width=popupImageSize; popupImage.style.display='inline'; imageSources[i].active=true; // should we check to see if it's already there? maybe... gImageCache.push(imageArray[i].src); setPopupImageLink(gImage, imageSources[i].wiki); stopImagesDownloading(); } setImageStatus(''); // reset evil nonconstant globals delete imageArray; 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=''; // this is a REALLY BAD IDEA delete imageArray[i]; //imageArray[i] = new Image(); } imageArray = new Array (); 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='Képméret változtatása'; } else { a.href=linkURL; a.title='Megnyitás eredeti méretben'; } } return linkURL; }; function setupTooltips() { var anchors; if (popupOnlyArticleLinks===null) popupOnlyArticleLinks=dpopupOnlyArticleLinks; if (popupOnlyArticleLinks) anchors=( document.getElementById('article') || document.getElementById('content') ).getElementsByTagName('A'); else 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 email=emailuser.exec(h); var exc=exceptions.exec(h); var m=re.exec(h); if ( (! isInToc(a)) && (contribs != null || (exc == null && m != null) ) ) { a.onmouseover=mouseOverWikiLink; a.onmouseout= mouseOutWikiLink; a.onclick= killPopup; if (removeTitles) { a.originalTitle=a.title; a.title=''; } } } }; ////////////// // THINGIES // ////////////// // How the URLs for images in the popup come about // loadPreviewImage // | // getWiki // |<----------------see other schematic for details // insertPreviewImage (insertPreviewImage = onComplete) // | // | insertPreviewImage gets a wikiText fragment from // | the wikiText downloaded by getWiki // | // [wikiMarkupToAddressFragment] // | // | mouseOverWikiLink (gets an "address fragment", // | | no processing needed) // \->-loadThisImage---<----loadImages // | // [image(Thumb)URL]-->--hopefully valid image urls var currentLink=null; 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; if (a==currentLink) return; else currentLink=a; 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; if (popupImages==null) popupImages=dpopupImages; log('running overlib now'); var setmaxwidth = function () { over.style.maxWidth = '300px'; } registerHook("createPopup", setmaxwidth, FAFTER); overlib(html, STICKY, WRAP, CELLPAD, 5, OFFSETX, 2, OFFSETY, 2, DELAY, popupDelay*1000, FGCOLOR, popupFgColor, BGCOLOR, popupBgColor); if (simplePopups===null) simplePopups = dsimplePopups; if(simplePopups) return; 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) { return getWiki(article, insertPreviewImage); }; function loadPreviewImageFromRedir(redirPage, redirMatch) { /* redirMatch is a regex match */ var target = redirMatch[1]; var trailingRubbish=redirMatch[2]; ++redirCount; var warnRedir = redirLink(target); /*if (trailingRubbish.length > 0) { warnRedir += ', '+formatBytes(trailingRubbish.length); warnRedir += ' ' + doNotRedirLink(redirPage, 'hidden', 'Show text hidden after #redirect[[...]]'); } */ setPopupHTML(warnRedir, 'popupWarnRedir'); return loadPreviewImage(myEncodeURI(target)); }; function extractChunk(str, header, breakChar) { if (str.indexOf(header) != 0) return null; if (!breakChar) return str.substring(header.length); var findChar=str.indexOf(breakChar); if (findChar==-1) return str.substring(header.length); return str.substring(header.length, findChar); } function urlToWikiPage (url) { log ('urlToWikiPage\nurl='+url); var urlFragment=null; if (!urlFragment) urlFragment=extractChunk(url, titlebase, '&'); if (!urlFragment) urlFragment=extractChunk(url, wikibase, '?'); if (!urlFragment) return null; return addressFragmentToWikiMarkup(urlFragment); } function insertPreviewImage(download) { if (download.id != popupImageId) return; var wikiText=download.data; var redirectRegex= /^[ \n]*[#]redirect[: \n]*\[\[([^\]]*)\]\]\s*(.*)/i ; var redirMatch = redirectRegex.exec(wikiText); if (redirMatch && redirCount==0) { return loadPreviewImageFromRedir(urlToWikiPage(download.url), redirMatch); } else redirCount=0; if (popupSummaryData===null) popupSummaryData=dpopupSummaryData; if (popupSummaryData) { var pgInfo=getPageInfo(wikiText); setPopupTrailer('<br>' + pgInfo); } var imagePage=getValidImageFromWikiText(wikiText); if(imagePage) { // loadThisImage expects an "address fragment" imagePage = wikiMarkupToAddressFragment(imagePage); loadThisImage(imagePage); } if (popupPreviews===null) popupPreviews=dpopupPreviews; if (popupPreviews) {popupPreview(download);} }; var localTest=false; function popupPreview(download) { // FIXME: horizonal rules should be skipped // FIXME: get rid of html tagsx if (localTest) var data = download.substring(0,8000); // FOR TESTING else var data=download.data.substring(0,10000); // huge pages be gone var datum=new Array(); datum.push(data.substring(0,1000)); // we strip in order: // // * html comments <!-- ... --> // * contents of <div...> ... </div> and <gallery> ... </gallery> // * HACK: {{taxobox_start ... taxobox_end}} // * templates {{ .... }} (replace with spaces so that '''{{template}}''' works // * wikitext tables // * wikitext images and category tags // * wikitext rules ---- // * lines starting with a : // * html tables // * a mop-up: delete all lines starting with < // * all html tags // * "chunks" of italic text (heuristics alert) // * __TOC__, __NOTOC__ // hasta la vista, comments data=data.replace(RegExp('<!--(\\n|[^-]|-[^-]|--[^>])*-->', 'g'), ''); // say goodbye, divs data=data.replace(RegExp('< *div[^>]* *>(.|\\n)*< */ *div *>', 'gi'), ''); // and galleries data=data.replace(RegExp('< *gallery[^>]* *>(.|\\n)*< */ *gallery *>', 'gi'), ''); // taxobox hack... in fact, there's a saudiprincebox_begin, so let's be more general data=data.replace(RegExp('[{][{][^}\\s|]*box_begin(.|\\n)*[^{\\s|]*box_end *[}][}]', 'gi'), ''); // try to remove templates data=data.replace(RegExp('[{][{]([{][{][^}]*[}][}]|[^{}])*[}][}]', 'g'), ' '); //datum.push(data); // tables are bad, too data=data.replace (RegExp('[{]\\|([{][|]([^\\|]|\\|[^}])*[|][}]|[^\\|]|\\|[^}])*\\|[}]', 'g') , ''); datum.push(data.substring(0,1000)); // images are a nono // who says regexes aren't fun? // this ain't so good, try it on [[User:dbenbenn]] // i think we should match: // [[image: ...... ]] where ....... is consists of repetitions of any of: // 1. not [ or ] // 2. [[ (not ])* ]] // 3. [ (not ])* ] var imagedetector ='[[][[]\\s*(image|category|kép|kategória)\\s*:([^\\[\\]]|\\[\\[[^\\]]*\\]\\]|\\[[^\\]]*\\])*\\]\\]'; var crudeImageRegex = RegExp(imagedetector, 'gi'); // alert(data.match(crudeImageRegex).join('\n-\n')); data=data.replace(crudeImageRegex, ''); // we simply *can't* be doing with horizontal rules right now data=data.replace(RegExp('^-{4,}','mg'),''); // no indented lines data=data.replace(RegExp('(^|\\n) *:[^\\n]*','g'), '\n'); // or html tables // this doesn't cope with embedded tables //data=data.replace(RegExp('<table[^>]*>([\\n\\s]|[^<]|<[^/]|</[^t]|'+ // may this is good enough? data=data.replace(RegExp('<table[^>]*>(.|\\n.)*\\n?</ *table *>\\n+', 'gi'), ''); // let's delete lines starting with <. it's worth a try. data=data.replace(RegExp('(^|\\n) *<[^\\n]*', 'g'), '\n'); // and those pesky html tags data=data.replace(RegExp('<[^>]*>','g'),''); // chunks of italic text? you crazy, man? var italicChunkRegex=new RegExp ("((^|\\n)\\s*:*\\s*''[^']([^']|'''|'[^']){20}(.|\\n[^\\n])*''[.!?\\s]*\\n)*" , 'g'); data=data.replace(italicChunkRegex, ''); // return data; //TESTING // replace __TOC__, __NOTOC__ and whatever else there is // this'll probably do data=data.replace(RegExp('^__[A-Z_]*__ *$', 'gmi'),''); // dont't be givin' me no subsequent paragraphs, either, you hear me? /// first we "normalize" section headings, removing whitespace after, adding before data=data.replace(RegExp('\\s*(==+[^=]*==+)\\s*', 'g'), '\n\n$1 '); /// then we want to get rid of paragraph breaks whose text ends badly data=data.replace(RegExp('([:;]) *\\n{2,}', 'g'), '$1\n'); stuff=(RegExp('^\\s*([^\\n]|\\n[^\\n])*')).exec(data); if (stuff) data = stuff[0]; /// now put \n\n after sections so that bullets and numbered lists work data=data.replace(RegExp('(==+[^=]*==+)\\s*', 'g'), '$1\n\n'); // superfluous sentences are RIGHT OUT. // note: 1 set of parens here needed to make the slice work data = data.parenSplit(RegExp('([!?.]+["'+"'"+']*\\s)','g')); // leading space is bad, mmkay? data[0]=data[0].replace(RegExp('^\\s*'), ''); var notSentenceEnds=RegExp('([^.][a-z][.][a-z]|etc|sic|Dr|Mr|Mrs|Ms)$' + '|' + '\\[[^\\]]*$' , 'i'); data = fixSentenceEnds(data, notSentenceEnds); if (maxPreviewSentences===null) maxPreviewSentences = dmaxPreviewSentences; if (maxPreviewCharacters===null) maxPreviewCharacters = dmaxPreviewCharacters; var n=maxPreviewSentences; var d; do {d=firstSentences(data,n); --n; } while ( d.length > maxPreviewCharacters && n > 0 ); data = d; datum.push('\n\nfinal one:'); datum.push(data.substring(0,1000)); if (localTest) return data; // FOR TESTING var newhtml=wiki2html(data); // needs livepreview if (popupNavLinks || popupSummaryData) newhtml = '<hr>' + newhtml; setPopupHTML(newhtml, 'popupPreview'); }; function fixSentenceEnds(strs, reg) { // take an array of strings, strs // join strs[i] to strs[i+1] & strs[i+2] if strs[i] matches regex reg for (var i=0; i<strs.length-2; ++i) { if (reg.test(strs[i])) { a=new Array (); for (var j=0; j<strs.length; ++j) { if (j<i) a[j]=strs[j]; if (j==i) a[i]=strs[i]+strs[i+1]+strs[i+2]; if (j>i+2) a[j-2]=strs[j]; } return fixSentenceEnds(a,reg); } } //alert('returning '+strs.join('\n\n')); return strs; } function firstSentences(strs, howmany) { var t=strs.slice(0, 2*howmany); return t.join(''); } var stopPopupTimer=null; function fuzzyCursorOff(fuzz) { if (!over) return null; var left = parseInt(over.style.left); var top = parseInt(over.style.top); var right = left + (over.offsetWidth >= parseInt(o3_width) ? over.offsetWidth : parseInt(o3_width)); var bottom = top + (over.offsetHeight >= o3_aboveheight ? over.offsetHeight : o3_aboveheight); if (o3_x < left-fuzz || o3_x > right+fuzz || o3_y < top-fuzz || o3_y > bottom + fuzz) return true; return false; } // seems that fuzzyCursorOff should precede mouseOutWikiLink in the source // or sometimes during page loads, errors are generated function mouseOutWikiLink () { // document.title += '!'; if (fuzzyCursorOff(5)) { if (stopPopupTimer) { clearInterval(stopPopupTimer); stopPopupTimer=null; } killPopup(); return; } if (!stopPopupTimer) stopPopupTimer=setInterval("mouseOutWikiLink()", 500); }; function killPopup() { // o3_showingsticky should be defined in overlib.js //if ( typeof o3_showingsticky != "undefined" && o3_showingsticky == 0 ) { cClick(); currentLink=null; // abortCurrentDownload(); stopImagesDownloading(); if (checkImagesTimer != null) { clearInterval(checkImagesTimer); checkImagesTimer=null; } if (popupImageTimer != null) { clearInterval(popupImageTimer); popupImageTimer=null; } //} return true; // preserve default action (eg from onclick) }; //////////////////////////////////////////////////////////////////// // Run things //////////////////////////////////////////////////////////////////// if (window.addEventListener) window.addEventListener("load",setupTooltips,false); else if (window.attachEvent) window.attachEvent("onload",setupTooltips); else { window._old_ABCD_onload = window.onload; window.onload = function() { window._old_ABCD_onload(); setupTooltips(); } } /// Local Variables: /// /// mode:c /// /// End: ///