Участник:Js/templateLogic.js

Материал из Википедии — свободной энциклопедии
//do NOT add this to your vector/monobook.js, this is designed to run on load

function templateLogic(){

if (!window.templateLogicCSS) templateLogic = appendCSS('\
.argument_name {color:#f67}\
.argument_default {color:#7a7a3d}\
div.indent {padding-left:1.5em; border-left:1px dashed #aaa;\
 padding-bottom:0.3em; border-bottom:1px dashed #ddd}\
div.operator {padding-left:0.5em}\
span.keyword {font-weight:bold} .expr {background:#eee}\
.choice {font-style:italic}\
.magicvar {font-family:monospace}\
.link {text-decoration:underline}\
div.simple {display:inline; padding:0 0.5em; border:none}\
.tag {background:#eefac7}\
.cell {background:#f5f5f5}\
div.btn {float:right; cursor:pointer; border:2px ridge white; padding:2px; margin:2px}\
}')


var txt, hidden = []


//FUNCTIONS

function r(r1, r2){ txt = txt.replace(r1, r2) }

function hide(re){ 
 r(re,  function(s){ return '\x01'+hidden.push(s)+'\x02' }) 
}

String.prototype.wrap = function(def){ //'123'.wrap('div.my')  ->  <div class=my>123</div>
 var el = 'span', cls = def
 def = def.split('.')
 if (def.length == 2) { el = def[0]; cls = def[1] }
 return '<'+el+' class='+cls+'>'+this+'</'+el+'>'
}

String.prototype.splitOnce = function(ch){
 var pos = this.indexOf(ch)
 if (pos == -1) return [this.toString(), ""]
 else return [this.substring(0,pos), this.substring(pos+1)]
}
String.prototype.substrBefore = function(ch){
 return this.substring(0,this.indexOf(ch))
}


function showNext(s){
 if (/^{{{/.test(s)) return showArgument(s.substring(3,s.length-3))
 if (/^\[\[/.test(s)) return s.wrap('link')
 s = s.substring(2,s.length-2).replace(/[\r\n]/g,'').replace(/^\s+/,'');
 var ma = /^(#?\w+):(.*)/.exec(s)
 if (ma) return showFunc(ma[1], ma[2])
 ma = /^([^|]+)\|(.*)/.exec(s)
 if (ma) return showTemplate(ma[1], ma[2])
 return ('{{'+s+'}}').wrap('magicvar')
}
 

function showArgument(ar){ // like {{{name|}}}
 var pos = ar.indexOf('|'), defa = ''
 if (pos != -1){
   defa = ar.substring(pos+1).wrap('argument_default')
   ar = ar.substring(0, pos+1)
 }  
 return ('$' + ar).wrap('argument_name') + defa
}
 
function showSwitch(arg){// like |a = 5
 var res2 = '', choice, pos, block
 for (var i=0; i<arg.length; i++){
   block = '<b>|</b> '
   if ((pos=arg[i].indexOf('=')) != -1){
     block += arg[i].substring(0,pos).wrap('choice') + ' = '
     arg[i] = arg[i].substring(pos+1)
   }
   block += arg[i].wrap('div.indent')
   res2 += block.wrap('div.block')
 }
 return res2
}
 
function showTemplate(name, args){
 var arg = args.split('|'), res = '<br>'+('{{'+name).wrap('template')
 res += showSwitch(arg).wrap('div.indent')
 return res + '}}'.wrap('template')
}
 
function showFunc(ff, args){
 var arg = args.split('|')
 switch(ff){
  case '#ifeq':
    arg[0] = arg.shift() + ' = ' + arg[0]//and continue to the next
  case '#if': case '#iferror': case '#ifexpr': case '#ifexist':
   res = ff.wrap('keyword') +' ( '+arg[0] +' )'+arg[1].wrap('div.indent')
   if (!arg[2]) break
   res += 'else'.wrap('keyword')+arg[2].wrap('div.indent')
   break
  case '#switch':
   res =  ff.wrap('keyword') + ' ( ' + arg[0] + ' )' 
   arg.shift()
   res += showSwitch(arg).wrap('div.indent')
   break
  case '#expr':
   //res = ma[2].wrap('div.expr')
   res = ff.wrap('keyword') + args.wrap('div.indent')
   break
  default: res = '{{'+ff+':'+args+'}}'
 }
 return res.wrap('div.operator')
}

function removeOutput(){ $('#template-logic').remove() }






function processTxt(){
 txt = '\n' + txt 
 r(/&/g,'&amp;');  r(/</g,'&lt;');  r(/>/g,'&gt;')
 /*
 r(/(style|class|width|height|v?align|(row|col)span|border-\w+|background-\w+|cellspacing) *= *[\w"#% ]+/g,'<span class=style>$&</span>') //mark tags
 */

 //first hide all arguments, templates and functions
 do {
   do {
       txtOld = txt
       hide(/{{{([^{}]+)}}}/g)
   } while (txtOld != txt)
   hide(/\[\[[^{}\]]+\]\]/g)
   hide(/{{([^{}]+)}}/g)
 } while (txtOld != txt)

 //unhide them
 for (var i=hidden.length; i>0; i--)
   r( '\x01'+i+'\x02', showNext(hidden.pop()) )

  r(/&lt;\/?[a-z]+[^&<]{0,100}&gt;/g,'<span class=tag>$&</span>') //mark tags
 r(/\n{\|[\w %=#:"-]+/g, '<span class=cell>$&</span>') //table: {|
 r(/\n\|-.*/g,'<span class=cell>$&</span>') // row: |-
 r(/\n[\|!][\w %=#:;"-]+\|(?!\|)/g, '<span class=cell>$&</span>') //cell: |some style| 

 r(/\n/g,'<br>')
 
 $('#wikiDiff, #wikiPreview').hide()
 removeOutput()

 var outputDiv = $('<div id=template-logic>\
<div class="btn closeme" title="Close">X</div>\
<div class="btn aboutme" title="About">?</div>'
 +txt+'</div>')
 .insertAfter($('#contentSub, #siteSub').eq(0))

 outputDiv.find('div.closeme').click(function(){removeOutput()})
 outputDiv.find('div.aboutme').click(function(){
   window.open(mw.config.get('wgServer')+mw.config.get('wgArticlePath').replace(/\$1/,'')+'user_talk:js/templateLogic.js')
 })

 //add 'simple' class
 outputDiv.find('div.indent').each(function(i, el){
  el = $(el)
  if (el.find('div').length == 0 && el.text().length < 60) 
    el.addClass('simple')
 })

 outputDiv.get(0).scrollIntoView()

}//processTxt



 
// MAIN

if (/edit|submit/.test(mw.config.get('wgAction'))){
  var txt = $('#wpTextbox1').val()
  processTxt()
}else{
  $.get( mw.config.get('wgScript') + '?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&action=raw',
  function(data){ txt = data; processTxt() } )
}
 
 
} //templateLogic


$(templateLogic)