/* 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).*/varAJAXPreview={node:null,txt:null,timer:null,idx:0,spinner:function(){switch(AJAXPreview.idx++){case0:AJAXPreview.node.innerHTML='<center style="font-size:50pt">|</center>';break;case1:AJAXPreview.node.innerHTML='<center style="font-size:50pt">/</center>';break;case2:AJAXPreview.node.innerHTML='<center style="font-size:50pt">–</center>';break;case3: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>';thrownewError('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 innerHTMLwindow.setTimeout(function(){mw.hook('wikipage.content').fire($(AJAXPreview.node));for(vari=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);vard=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';thrownewError('AJAX error: '+textStatus+' '+errorThrown);},doPreview:function(ev){if(!ev)ev=window.event;vartxt=AJAXPreview.getTextContent();varrefs=AJAXPreview.getRefs(txt);varneed=[];vargroups={};for(varginrefs){groups[g]='';for(varninrefs[g]){if(refs[g][n].text===null)need.push([g,n]);}}vardoPreview2=function(wikitext,sts,xhr){if(wikitext){refs=AJAXPreview.getRefs(wikitext);for(vari=need.length-1;i>=0;i--){varx=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(vargingroups){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);}});varx=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 hereif(ev.preventDefault)ev.preventDefault();if(ev.stopPropagation)ev.stopPropagation();ev.returnValue=false;ev.cancelBubble=true;}returnfalse;},getRefs:function(txt){varg;varrefs={};// 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:referencestxt=AJAXPreview.process_templates(txt,function(n,p,o){varc=null,g='';if(n=='Reflist'){for(varj=0;j<p.length;j++){varm=p[j].match(/^\s*refs\s*=\s*((?:.|[\r\n])*?)\s*$/);if(m)c=m[1];varm=p[j].match(/^\s*group\s*=\s*([\x22\x27]?)([^\x22\x27]+?)\1\s*$/);if(m)g=m[2];}if(c===null)c='';}elseif(/^#tag:\s*references$/i.test(n)){c=p.length?p.shift():'';for(varj=0;j<p.length;j++){varm=p[j].match(/^\s*group\s*=\s*([\x22\x27]?)([^\x22\x27]+?)\1\s*$/);if(m)g=m[2];}}else{returnnull;}refs=AJAXPreview.getRefs2(c,g,refs);return'';});returnAJAXPreview.getRefs2(txt,'',refs);},getRefs2:function(txt,defgroup,refs){varg,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)returnnull;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'}returnnull;});// Second, if it looks like there are #tag refs, parse them tooAJAXPreview.process_templates(txt,function(nm,p,o){if(!/^#tag:\s*ref$/i.test(nm))returnnull;g=defgroup;n=null;for(varj=p.length-1;j>=1;j--){varm=p[j].match(/^\s*group\s*=\s*([\x22\x27]?)([^\x22\x27]+?)\1\s*$/);if(m)g=m[2];varm=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'}}returnnull;});returnrefs;},process_templates:function(txt,cb,data){varstack=[],i=0;while(i<txt.length){varx=stack.length?stack[stack.length-1]:null;varxb=null;for(varj=0;j<stack.length;j++){if(stack[j].char=='\x5b')xb=stack[j];}if(txt.substr(i,2)=='\x7b\x7b'){varct;for(ct=2;txt.substr(i+ct,1)=='\x7b';ct++);stack.push({char:'\x7b',start:i,count:ct,pstart:i+ct,params:[]});i+=ct;}elseif(txt.substr(i,2)=='\x5b\x5b'){varct;for(ct=2;txt.substr(i+ct,1)=='\x5b';ct++);stack.push({char:'\x5b',start:i,count:ct,pstart:i+ct,params:[]});i+=ct;}elseif(x&&x.char=='\x7b'&&txt.substr(i,2)=='\x7d\x7d'){varct;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 variableswhile(ct>=3){x.count-=3;ct-=3;vars=x.start-x.count;x.params=[txt.substring(s,i-x.count)];}// Any left is templateswhile(ct>=2){x.count-=2;ct-=2;vars=x.start+x.count;varorig=txt.substring(s,i-ct);varname=x.params.shift();varoname=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);varret=cb(name,x.params,orig,data,oname);if(ret===null){x.params=[orig];}else{ret=""+ret;vard=(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 pstartx.params=[];x.pstart=x.start+x.count;}}elseif(xb&&txt.substr(i,2)=='\x5d\x5d'){// Drop any pending templates, they're not really templateswhile(stack[stack.length-1]!=xb)stack.pop();varct;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 pstartxb.params=[];xb.pstart=xb.start+xb.count;}}elseif(x&&txt.substr(i,1)=='|'){x.params.push(txt.substring(x.pstart,i));x.pstart=++i;}else{i++;}}returntxt;},onLoad:function(){varaction=mw.config.get('wgAction');if(action!='edit'&&action!='submit')return;vareditForm=document.getElementById('editform');if(!editForm)return;varsectionField=editForm.elements['wpSection'];varisSection=(sectionField&§ionField.value!="");varp=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(){varb=newOO.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 functionsif(typeof(window.createCollapseButtons)=='function')AJAXPreview.AddOnLoadHook(createCollapseButtons);if(typeof(window.createNavigationBarToggleButton)=='function')AJAXPreview.AddOnLoadHook(createNavigationBarToggleButton);},getTextContent:function(){returnAJAXPreview.txt.value;},// Add callback functions here.AddOnLoadHook:function(f){AJAXPreview.$OnLoadHooks.push(f);},$OnLoadHooks:[]};$(document).ready(AJAXPreview.onLoad);