/* If you want to use this script, simply add the following line to your monobook.js: importScript('User:Anomie/ajaxpreview.js'); // Linkback: [[User:Anomie/ajaxpreview.js]] * (Please keep the comment so I can see how many people use this).*/var AJAXPreview={ node:null, txt:null, timer:null, idx:0, spinner:function(){ switch(AJAXPreview.idx++){ case 0: AJAXPreview.node.innerHTML='<center style="font-size:50pt">|</center>'; break; case 1: AJAXPreview.node.innerHTML='<center style="font-size:50pt">/</center>'; break; case 2: AJAXPreview.node.innerHTML='<center style="font-size:50pt">–</center>'; break; case 3: AJAXPreview.node.innerHTML='<center style="font-size:50pt">\\</center>'; AJAXPreview.idx=0; break; } AJAXPreview.node.style.display='block'; }, callback:function(r){ if(AJAXPreview.timer) window.clearInterval(AJAXPreview.timer); AJAXPreview.timer=null; if(!r.parse || !r.parse.text || !r.parse.text['*']){ AJAXPreview.node.innerHTML='<div style="border:1px solid #f00;background-color:#fcc;color:#f00;text-align:center">Bad response</div>'; throw new Error('Bad response'); } AJAXPreview.node.innerHTML=r.parse.text['*']+'<br />'; AJAXPreview.node.style.display='block'; // Set a timeout to allow the browser a chance to parse the innerHTML window.setTimeout(function(){ mw.hook( 'wikipage.content' ).fire( $( AJAXPreview.node ) ); for(var i=AJAXPreview.$OnLoadHooks.length-1; i>=0; i--) AJAXPreview.$OnLoadHooks[i].call(window, AJAXPreview.node); }, 250); }, doError:function(xhr,textStatus,errorThrown){ if(AJAXPreview.timer) window.clearInterval(AJAXPreview.timer); AJAXPreview.timer=null; while(AJAXPreview.node.firstChild) AJAXPreview.node.removeChild(AJAXPreview.node.firstChild); var d=document.createElement('DIV'); d.style.border='1px solid #f00'; d.style.backgroundColor='#fcc'; d.style.color='#f00'; d.style.textAlign='center'; d.appendChild(document.createTextNode('AJAX Error: '+textStatus+' '+errorThrown)); AJAXPreview.node.appendChild(d); AJAXPreview.node.style.display='block'; throw new Error('AJAX error: '+textStatus+' '+errorThrown); }, doPreview:function(ev){ if(!ev) ev=window.event; var txt=AJAXPreview.getTextContent(); var refs=AJAXPreview.getRefs(txt); var need=[]; var groups={}; for(var g in refs){ groups[g]=''; for(var n in refs[g]){ if(refs[g][n].text===null) need.push([g,n]); } } var doPreview2=function(wikitext,sts,xhr){ if(wikitext){ refs=AJAXPreview.getRefs(wikitext); for(var i=need.length-1; i>=0; i--){ var x=refs[need[i][0]][need[i][1]]; if(!x) continue; if(x.type=='tag'){ groups[need[i][0]]+='\x7b\x7b#tag:ref|'+x.text+'|name='+need[i][1]+'|group='+need[i][0]+'\x7d\x7d'; } else { groups[need[i][0]]+='\x3cref name="'+need[i][1]+'" group="'+need[i][0]+'"\x3e'+x.text+'\x3c/ref\x3e'; } } } txt+='\n\n\x7b\x7b-\x7d\x7d\n----\n'; for(var g in groups){ txt+='\n;'+(g?'Group '+g:'References')+'\n\x7b\x7breflist|2|group='+g+'|refs='+groups[g]+'\x7d\x7d'; } jQuery.ajax({ url:mw.util.wikiScript('api'), dataType:'json', type:'POST', data:{ format:'json', action:'parse', pst:1, text:txt, title:mw.config.get('wgPageName'), prop:'text', disableeditsection:1, preview:1, templatesandboxtitle:mw.config.get('wgPageName'), templatesandboxtext:txt }, success:AJAXPreview.callback, error:AJAXPreview.doError }); }; mw.loader.using('mediawiki.util', function(){ if(need.length>0){ jQuery.ajax({ url:mw.util.wikiScript('index'), dataType:'text', type:'GET', data:{ action:'raw', title:mw.config.get('wgPageName') }, success:doPreview2, error:AJAXPreview.doError }); } else { doPreview2(null,null,null); } }); var x=document.getElementById('wikiDiff'); if(x) x.parentNode.removeChild(x); if(AJAXPreview.timer) window.clearInterval(AJAXPreview.timer); AJAXPreview.timer=window.setInterval(AJAXPreview.spinner, 250); this.blur(); window.scrollTo(0,0); if(ev){ // OOUI may not have an event here if(ev.preventDefault) ev.preventDefault(); if(ev.stopPropagation) ev.stopPropagation(); ev.returnValue=false; ev.cancelBubble=true; } return false; }, getRefs:function(txt){ var g; var refs={}; // The new "list-defined references" have to be handled specially, // which means we have to manage to pull them out of the wikitext. Fun. // First, do the XML-style tags. txt=txt.replace(/<references((?:\s+[^>]*[^\/>])?)(?:\/>|>((?:.|[\r\n])*?)(<\/references>|$))/ig, function(x,p,t,c){ p=p.replace(/\s+$/g,''); g=p.match(/\sgroup="([^\x22]*)"/i); if(!g) g=p.match(/\sgroup='([^\x27]*)'/i); if(!g) g=p.match(/\sgroup=(\S*)/i); g=g?g[1]:''; refs=AJAXPreview.getRefs2(t,g,refs); return ''; }); // Next, to reflist and #tag:references txt=AJAXPreview.process_templates(txt,function(n,p,o){ var c=null, g=''; if(n=='Reflist'){ for(var j=0; j<p.length; j++){ var m=p[j].match(/^\s*refs\s*=\s*((?:.|[\r\n])*?)\s*$/); if(m) c=m[1]; var m=p[j].match(/^\s*group\s*=\s*([\x22\x27]?)([^\x22\x27]+?)\1\s*$/); if(m) g=m[2]; } if(c===null) c=''; } else if(/^#tag:\s*references$/i.test(n)){ c=p.length ? p.shift() : ''; for(var j=0; j<p.length; j++){ var m=p[j].match(/^\s*group\s*=\s*([\x22\x27]?)([^\x22\x27]+?)\1\s*$/); if(m) g=m[2]; } } else { return null; } refs=AJAXPreview.getRefs2(c,g,refs); return ''; }); return AJAXPreview.getRefs2(txt,'',refs); }, getRefs2:function(txt,defgroup,refs){ var g,n; // First, pull out regular <refs>. We can do this with a regex. txt.replace(/<ref((?:\s+\S+=(?:"[^\x22]*"|'[^\x27]*'|\S*?))*)\s*(?:\/>|>((?:.|[\r\n])*?)<\/ref>)/ig, function(x,p,t){ g=p.match(/\sgroup="([^\x22]*)"/i); if(!g) g=p.match(/\sgroup='([^\x27]*)'/i); if(!g) g=p.match(/\sgroup=(\S*)/i); g=g?g[1]:defgroup; if(typeof(refs[g])=='undefined') refs[g]={}; n=p.match(/\sname="([^\x22]*)"/i); if(!n) n=p.match(/\sname='([^\x27]*)'/i); if(!n) n=p.match(/\sname=(\S*)/i); if(!n) return null; n=n[1]; if(typeof(refs[g][n])=='undefined') refs[g][n]={text:null,type:'?'}; if(refs[g][n].text===null && typeof(t)!='undefined' && t!=='' && t!==null){ refs[g][n].text=t; refs[g][n].type='ref' } return null; }); // Second, if it looks like there are #tag refs, parse them too AJAXPreview.process_templates(txt,function(nm,p,o){ if(!/^#tag:\s*ref$/i.test(nm)) return null; g=defgroup; n=null; for(var j=p.length-1; j>=1; j--){ var m=p[j].match(/^\s*group\s*=\s*([\x22\x27]?)([^\x22\x27]+?)\1\s*$/); if(m) g=m[2]; var m=p[j].match(/^\s*name\s*=\s*([\x22\x27]?)([^\x22\x27]+?)\1\s*$/); if(m) n=m[2]; } if(typeof(refs[g])=='undefined') refs[g]={}; if(n!==null){ if(typeof(refs[g][n])=='undefined') refs[g][n]={text:null,type:'?'}; if(refs[g][n].text===null && p[0]!==''){ refs[g][n].text=p[0]; refs[g][n].type='tag' } } return null; }); return refs; }, process_templates:function(txt,cb,data){ var stack=[], i=0; while(i<txt.length){ var x=stack.length?stack[stack.length-1]:null; var xb=null; for(var j=0; j<stack.length; j++){ if(stack[j].char=='\x5b') xb=stack[j]; } if(txt.substr(i,2)=='\x7b\x7b'){ var ct; for(ct=2; txt.substr(i+ct,1)=='\x7b'; ct++); stack.push({char:'\x7b',start:i,count:ct,pstart:i+ct,params:[]}); i+=ct; } else if(txt.substr(i,2)=='\x5b\x5b'){ var ct; for(ct=2; txt.substr(i+ct,1)=='\x5b'; ct++); stack.push({char:'\x5b',start:i,count:ct,pstart:i+ct,params:[]}); i+=ct; } else if(x && x.char=='\x7b' && txt.substr(i,2)=='\x7d\x7d'){ var ct; for(ct=2; txt.substr(i+ct,1)=='\x7d'; ct++); if(ct>x.count) ct=x.count; i+=ct; x.params.push(txt.substring(x.pstart,i-ct)); // First, parse out variables while(ct>=3){ x.count-=3; ct-=3; var s=x.start-x.count; x.params=[txt.substring(s,i-x.count)]; } // Any left is templates while(ct>=2){ x.count-=2; ct-=2; var s=x.start+x.count; var orig=txt.substring(s,i-ct); var name=x.params.shift(); var oname=name; name=name.replace(/_/g,' '); name=name.replace(/^\s+|\s+$/g,''); name=name.replace(/ +/g,' '); name=name.replace(/^Template\s*:\s*/ig,''); name=name.substr(0,1).toUpperCase()+name.substr(1); var ret=cb(name, x.params, orig, data, oname); if(ret===null){ x.params=[orig]; } else { ret=""+ret; var d=(ret=='' && (s==0 || txt.substr(s-1,1)=='\n') && txt.substr(i-ct,1)=='\n')?1:0; txt=txt.substr(0,s)+ret+txt.substr(i-ct+d); i=s+ret.length+ct; x.params=[ret]; } } if(x.count<2){ stack.pop(); } else { // The one we just completed might not be the end of the // param, so reset the param array and pstart x.params=[]; x.pstart=x.start+x.count; } } else if(xb && txt.substr(i,2)=='\x5d\x5d'){ // Drop any pending templates, they're not really templates while(stack[stack.length-1]!=xb) stack.pop(); var ct; for(ct=2; txt.substr(i+ct,1)=='\x5d'; ct++); if(ct>xb.count) ct=xb.count; i+=ct; xb.count-=ct; if(xb.count<2){ stack.pop(); } else { // The one we just completed might not be the end of the // param, so reset the param array and pstart xb.params=[]; xb.pstart=xb.start+xb.count; } } else if(x && txt.substr(i,1)=='|'){ x.params.push(txt.substring(x.pstart,i)); x.pstart=++i; } else { i++; } } return txt; }, onLoad:function(){ var action=mw.config.get('wgAction'); if(action!='edit' && action!='submit') return; var editForm=document.getElementById('editform'); if(!editForm) return; var sectionField = editForm.elements['wpSection']; var isSection=(sectionField && sectionField.value!=""); var p=editForm.elements["wpPreview"]; if(!p) return; AJAXPreview.node=document.getElementById('wikiPreview'); if(!AJAXPreview.node) return; AJAXPreview.txt=editForm.elements["wpTextbox1"]; if(!AJAXPreview.txt) return; mw.loader.using( [ 'oojs-ui-core' ] ).done( function () { var b = new OO.ui.ButtonWidget( { label: 'Ajax Preview'+(isSection?' w/Refs':''), tabIndex: p.tabIndex } ); b.on( 'click', AJAXPreview.doPreview ); $( p ).before( b.$element, ' ' ); } ); p.value='Preview'; // Hooks for standard functions if(typeof(window.createCollapseButtons) == 'function') AJAXPreview.AddOnLoadHook(createCollapseButtons); if(typeof(window.createNavigationBarToggleButton) == 'function') AJAXPreview.AddOnLoadHook(createNavigationBarToggleButton); }, getTextContent:function(){ return AJAXPreview.txt.value; }, // Add callback functions here. AddOnLoadHook:function(f){ AJAXPreview.$OnLoadHooks.push(f); }, $OnLoadHooks:[]};$(document).ready(AJAXPreview.onLoad);
🔥 Top keywords: Main PageSpecial:SearchPage 3Wikipedia:Featured picturesHouse of the DragonUEFA Euro 2024Bryson DeChambeauJuneteenthInside Out 2Eid al-AdhaCleopatraDeaths in 2024Merrily We Roll Along (musical)Jonathan GroffJude Bellingham.xxx77th Tony AwardsBridgertonGary PlauchéKylian MbappéDaniel RadcliffeUEFA European Championship2024 ICC Men's T20 World CupUnit 731The Boys (TV series)Rory McIlroyN'Golo KantéUEFA Euro 2020YouTubeRomelu LukakuOpinion polling for the 2024 United Kingdom general electionThe Boys season 4Romania national football teamNicola CoughlanStereophonic (play)Gene WilderErin DarkeAntoine GriezmannProject 2025