Wikipedysta:Matma Rex/infobox.js
//Wstawiacz infoboksów v. 1.6vector by ABX i Matma Rex
//Instrukcja użycia, pomoc i dyskusja: [[Dyskusja wikipedysty:Matma Rex/infobox.js]]
//Wersja rozwojowa: [[Wikipedysta:Matma Rex/infobox_r.js]]
// <pre>
if(typeof infobox=='undefined') var infobox={}
else alert('Błąd krytyczny - jeden ze skryptów używa już zmiennej "infobox".')
infobox.infoboxes=[]
importScript('Wikipedysta:Matma Rex/infoboksy.js')
importStylesheet('Wikipedysta:Matma Rex/infobox.css')
if(typeof dodajOpis=='undefined') //powinna już być taka funkcja, ale gdyby nie...
{
function dodajOpis(opis)
{
var wpS = document.editform.wpSummary;
if (wpS.value != '' && wpS.value.charAt(wpS.value.length-2) != '/')
{
wpS.value += ', ' + opis
}
else
{
wpS.value += opis
}
}
}
function showhide(el) //pokaż/ukryj el; można podać id elementu
{
if(typeof el=='string') el=document.getElementById(el)
if(el.style.display=='none') el.style.display=''
else el.style.display='none'
}
function remove(el) //alias, usuwa i zwraca element/false, gdy nie ma; el może być id elementu
{
if(typeof el=='string') el=document.getElementById(el)
if(!el) return false
// fix the new toolbar bug
infobox.refreshSection();
return el.parentNode.removeChild(el)
}
function hl(el,h) //podświetl/anuluj podświetlenie
{
if(h==undefined) h=true
if(h) el.style.border='3px solid red'
else el.style.border=''
}
infobox.message=function(txt,id) //wstawia przed wpTextbox1 diva, zwraca referencję
{
var box = document.getElementById(id);
if (!box)
box=document.createElement('div')
;
box.innerHTML=txt
box.id=id
var el = document.getElementById('infoboxSelectorBox');
if (!el)
el=document.getElementById('editform')
;
el.parentNode.insertBefore(box,el)
// fix the new toolbar bug
infobox.refreshSection();
return box
}
infobox.insertSelector=function() //wstawia selectboksa
{
var txt = ""
txt += '<form onsubmit="infobox.openInsertingForm(); return false" style="display:inline"><select id="infobox_selector" size="1">';
txt += '<option selected="selected" value="-1">Wybierz infobox:'
for(ibx=0;ibx<infobox.infoboxes.length;ibx++)
{
txt += '<option value="' + ibx + '">' + infobox.infoboxes[ibx].selname
}
txt += '</select> <input id="wpInfobox" type="submit" value="Wypełnij" accesskey="i" title="Rozpocznij wypełnianie infoboksu"></form> <input type="button" value="Wczytaj infobox z artykułu" onclick="infobox.loadFromArticle()" /> '
txtexpanded='<span style="display:none" id="infobox_txtexpanded"><input type="button" value="Wczytaj infobox z kodu" onclick="infobox.spawnInsertCodeBox()" /> <input type="button" value="Pobierz wywołanie infoboksu" onclick="z=prompt(\'Podaj nazwę infoboksu (wraz z \\\'infobox\\\' na końcu):\');if(typeof z!=\'undefined\'){infobox.loadCodeFromTemplateName(z)}" /> <input type="button" value="«" onclick="showhide(\'infobox_txtexpanded\');showhide(\'infobox_txtnonexp\')" /></span>'
txtnonexp='<span id="infobox_txtnonexp"><input type="button" value="»" onclick="showhide(\'infobox_txtexpanded\');showhide(\'infobox_txtnonexp\')" /></span>'
txt+=txtnonexp+txtexpanded
infobox.message(txt,'infoboxSelectorBox')
}
infobox.findInText=function(text) //znajduje infoboksy w wikitekście; opis zwracanych wartości pod koniec funkcji
{
arr=[] //przechowuje znalezione infoboksy
//regexp na znajdowanie infoboksów - dzięki, Nux
text.replace(/\{\{([^|}]+ infobo[^|}]+)([^{}]{40,}|(?:\s|\|[^|{}=]*|\|[^|{}=]*=(?:[^|{}]*|(?:[^|{}]*(?:\{\{[^{}]+\}\}|\[\[[^\[\]]+\]\])[^|{}]*)+))+)\}\}/g, function(a,n,z)
{
arr.push('{{'+n+z+'}}') //wrzucamy infoboks do tablicy
})
//zwracane wartości:
// 0 - nic nie znaleziono
// string - kod infoboksu
// array - tablica z kodami infoboksów, gdy są dwa lub więcej
if(arr.length==0) return 0
else if(arr.length==1) return arr[0]
else return arr
}
infobox.loadFromArticle=function()
{
ib=infobox.findInText(document.getElementById('wpTextbox1').value)
if(ib==0) alert('W kodzie artykułu nie znaleziono żadnych infoboksów. Jeśli jesteś pewien, że jakieś są, spróbuj użyć funkcji "Wczytaj infobox z kodu" i zgłoś błąd autorom skryptu.')
else if(typeof ib=='string') infobox.loadTemplateFromCode(ib)
else
{
txt='W kodzie artykułu znaleziono '+ib.length+' infoboksy/ów. Wybierz, który z nich chcesz edytować:'
for(i in ib)
{
n=''
ib[i].replace(/^\{\{(.+?)\s*\|/,function(a,nazwa)
{
nazwa=nazwa.substring(0,1).toUpperCase()+nazwa.substring(1)
n=nazwa
return ''
})
txt+='<br /><input type="submit" value="'+n+'" onclick="infobox.loadTemplateFromCode(\''+ib[i].replace(/\r?\n/g,' ')+'\');remove(this.parentNode)" />'
}
infobox.message(txt,'')
}
}
infobox.spawnInsertCodeBox=function()
{
infobox.hideInsertCodeBox()
infobox.message(
'Wklej pełny kod infoboksu: <textarea style="width:50px;height:1em;display:inline" id="infoboxCode"></textarea> <input type="submit" value="OK" onclick=\'infobox.loadTemplateFromCode(document.getElementById("infoboxCode").value);infobox.hideInsertCodeBox()\' />',
'insertInfoboxCodeBox'
)
document.getElementById('infoboxCode').focus()
}
infobox.hideInsertCodeBox=function()
{
remove('insertInfoboxCodeBox')
}
infobox.openInsertingForm=function() //umożliwia wypełnianie pól
{
if(document.getElementById('insertingInfoboxForm')) return //tylko jedno na raz
var selector = document.getElementById('infobox_selector')
if (!selector) return
var n = Number(selector.options[selector.selectedIndex].value)
if(n<0) return //jeśli nic nie wybrano
txt='<form id="insertingInfoboxForm" action="index.php" method="POST" onsubmit="infobox.pasteCode();dodajOpis(\'[[User:Matma Rex/infobox.js|edycja/dodanie infoboksu]]\');return false">'
txt+='{{<input type="hidden" id="__name" value="'+infobox.infoboxes[n].name+'" />'+infobox.infoboxes[n].name+' <input type="submit" value="Wstaw" /> <input type="button" value="Podgląd wypełnienia" onclick="infobox.loadPreview(infobox.createCode())"> <input type="button" value="Podgląd pustego infoboksu" onclick="infobox.loadPreview(\'{{'+infobox.infoboxes[n].name+'}}\')"> <input type="reset" value="Anuluj" onclick="infobox.closeInsertingForm()" /><br /><div id="insertingInfobox">'
for(i in infobox.infoboxes[n].para)
{
pname=infobox.infoboxes[n].para[i][0]
pval=infobox.infoboxes[n].para[i][1]||''
pinfo=infobox.infoboxes[n].para[i][2]||false
txt+=infobox.parseTemplateLine(pname,pval,pinfo)
}
txt+='</div>}} <input type="submit" value="Wstaw" /> <input type="reset" value="Anuluj" onclick="infobox.closeInsertingForm()" /></form>'
infobox.message(txt,'insertingInfoboxFormDiv')
}
infobox.closeInsertingForm=function() //ukrywa wypełnianie pól
{
remove('insertingInfoboxFormDiv')
}
infobox.parseTemplateLine=function(name,val,info) //parsowanie zmiennych <<>>
{
if(val.indexOf('<<')==-1) //brak specjalnych znaków - jeden zwykły input/textarea
{
z=val.match(/\n/g) //jakieś entery?
if(z==null) box='<input value="'+val+'" size="20" />' //nie - zwykły input
else //tak - textarea
{
box='<textarea cols="20" rows="'+Math.min(z.length,3)+'">'+val+'</textarea>'
//wysokość max 3 wiersze
}
txt=
' | '+name+(info?' <dfn class="info">('+info+')</dfn>':'')+
' = '+
'<span id="ibox-'+name+'">'+
box+
'</span><br />'
return txt
}
else //parsujemy wszystkie <<>>
{
arr=[]
//tablica, w niej na przemian string, <<>>, string, <<>>, itd.
//w razie potrzeby (gdy po sobie są dwa <<>>) string jest pusty
//pierwszy element to zawsze string
//ostatni to <<>> lub string
//substr to nie to samo co substring!
while(val.indexOf('<<')!=-1) //dopóki jest tu jeszcze jakieś <<>>
{
idx=val.indexOf('<<') //pozycja <<
if(idx!=0) //gdy mamy najpierw zwykły string
{
arr.push(val.substring(0,idx)) //wrzucamy do tablicy ów string
val=val.substr(idx) //po czym odcinamy do od val
}
else
{
arr.push('') //a gdy nie, wrzucamy pusty
}
//teraz index << jest równy 0
idx=val.indexOf('>>') //dokąd wycinamy?
arr.push(val.substring(2,idx)) //wrzucamy do tablicy to, co jest pomiędzy << a >>
val=val.substr(idx+2) //odcinamy <<>> z początku
}
if(val!='') //jeszcze jakiś string na końcu
{
arr.push(val)
val=''
}
txt='' //to będzie to, co jest między = a kolejnym |
for(i in arr)
{
if(i%2==0) //liczba parzysta - string
{
txt+=arr[i] //po prostu dopisujemy string
}
else //nieparzysta - <<>>
{
if(arr[i].indexOf(':')!=-1) //zawiera domyślną wartość
{
idx=arr[i].indexOf(':')
_name=arr[i].substring(0,idx)
_default=arr[i].substr(idx+1)
}
else
{
_name=arr[i]
_default=''
}
// _name - nazwa zmiennej
// _default - wartość domyślna
//parametr "alt" to regex, który musi pasować do zawartości pola
//w przeciwnym razie wstawienie jest anulowane
switch(_name) //parsujemy!
{
case 'input': //podstawowy input
txt+='<input value="'+_default+'" />'
break
case 'rok':
txt+='<input maxlength="4" value="'+_default+'" alt="^[0-9]{1,4}$" />'
break
default:
txt+='<strong>Błąd! Nieznany typ "'+_name+'"!</strong>'
}
}
}
txt=
' | '+name+(info?' <dfn class="info">('+info+')</dfn>':'')+
' = '+
'<span id="ibox-'+name+'">'+
txt+
'</span><br />'
return txt
}
}
infobox.createCode=function() //generuje i zwraca kod, bez walidacji
{
form=document.getElementById('insertingInfoboxForm')
txt='{{'+form.__name.value+"\n"
span=form.getElementsByTagName('span')
for(i=0;i<span.length;i++)
{
if(span[i].id.indexOf('ibox-')==-1||span[i].id==undefined)
{
alert('Błąd!')
continue //pomijamy
}
txt+=' | '+span[i].id.replace('ibox-','')+' = '+infobox.getRealNodeValue(span[i])+"\n"
}
txt+='}}'
return txt
}
infobox.pasteCode=function() //generuje kod, waliduje i wstawia do wpTextbox1
{
form=document.getElementById('insertingInfoboxForm')
ipts=document.getElementById('insertingInfobox').getElementsByTagName('input')
for(z=0;z<ipts.length;z++) hl(ipts[z],false) //wyłącz podświetlenie wszystkich inputów
txt='{{'+form.__name.value+"\n"
span=form.getElementsByTagName('span')
errors=0
for(i=0;i<span.length;i++)
{
if(span[i].id.indexOf('ibox-')==-1||span[i].id==undefined)
{
alert('Błąd!')
continue //pomijamy
}
for(j=0;j<ipts.length;j++)
{
if(!ipts[j].alt) ipts[j].alt='' //sprawdzamy pole walidacji
regex=new RegExp(ipts[j].alt) //robimy z niego regexa
if(ipts[j].value.search(regex)==-1 && ipts[j].value.replace(/^\s+|\s+$/g,'')!='') //po czym sprawdzamy, czy regex pasuje lub czy pole jest puste
{
hl(ipts[j])
errors++ //i w razie potrzeby wywalamy error
}
}
txt+=' | '+span[i].id.replace('ibox-','')+' = '+infobox.getRealNodeValue(span[i])+"\n"
}
if(errors>0)
{
alert('W formularzu pojawiły się błędy ('+errors+')! Odpowiednie pola zostały podświetlone, popraw je i kliknij "Wstaw" ponownie.')
return
}
txt+='}}'+"\n"
document.getElementById('wpTextbox1').value=txt+document.getElementById('wpTextbox1').value
remove(form.parentNode)
}
infobox.getRealNodeValue=function(el) //pobiera ciągi tekstowe + wartości inputów w elemencie
{
val=''
for(z=0;z<el.childNodes.length;z++)
{
if(el.childNodes[z].nodeType==3) //string
{
val+=el.childNodes[z].nodeValue
}
else //nie string - element HTML, zapewne input/textarea
{
if(el.childNodes[z].value) val+=el.childNodes[z].value
}
}
return val
}
infobox.loadTemplateFromCode=function(code,options) //generuje wypełnianie na podstawie wywołania, wczytuje także wartości
{
if(typeof options=='undefined') options={}
code=code.replace(/^\s*/g,'').replace(/\s*$/g,'') //trim
if(code.indexOf('{{')!=0 || code.lastIndexOf('}}')!=(code.length-2) || code.indexOf('|')==-1)
{
alert('Kod musi zawierać tylko infobox - zaczynający się od {{, kończący }} i zawierający co najmniej jedno |.')
return false
}
newInfobox={}
code=code.replace(/^\{\{(.+?)\s*\|/,function(a,nazwa)
{
nazwa=nazwa.substring(0,1).toUpperCase()+nazwa.substring(1)
newInfobox.name=nazwa
if(typeof options.forceSelname=='undefined') newInfobox.selname=nazwa+', wczytany z kodu'
else newInfobox.selname=options.forceSelname.replace('{nazwa}',nazwa)
return ''
})
code=code.replace(/\s*\}\}$/,'')
// escapowanie parametrów - autor kodu: Nux
// wewnętrzne szablony
code = code.replace(/<<<(#+)>>>/g,'<<<#$1>>>').replace(/\{\{[^}]+\}\}/g,function(a){ return a.replace(/\|/g,'<<<#>>>') })
// wewnętrzne linki
code = code.replace(/\[\[[^\]]+\]\]/g,function(a){ return a.replace(/\|/g,'<<<#>>>') })
lines=code.split('|')
newInfobox.para=[]
for(i=0;i<lines.length;i++)
{
line=lines[i]
// odescapowanie parametrów - autor kodu: Nux
line=line.replace(/<<<#>>>/g,'|').replace(/<<<#(#+)>>>/g,'<<<$1>>>')
line=line.replace(/^\s*(.+?)\s*=\s*([\s\S]*?)\s*$/,function(str,p1,p2)
{
p3=''
p2=p2.replace(/(\s*)<!--([\s\S]+)-->(\s*)/,function(a,s1,info,s2)
{
if(s1+s2=='') rv=''
else rv=' '
p3=info.replace(/^\s*/g,'').replace(/\s*$/g,'') //trim
return rv
})
newInfobox.para.push([p1,p2,p3])
return ''
})
if(line!='') alert('Błędny parametr infoboksu:'+"\n"+line)
}
infobox.infoboxes[infobox.infoboxes.length]=newInfobox //gotowe - dołączamy do listy
//odświeżamy selectboksa
//remove('infoboxSelectorBox')
infobox.insertSelector()
sel=document.getElementById('infobox_selector')
sel.selectedIndex=sel.options.length-1 //zaznacz ostatnie
infobox.openInsertingForm() //pokaż pole wypełniania
}
infobox.callApi=function(query) //z biblioteki Beau
{
var url = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?';
for (var field in query)
{
var value = query[field];
url += '&' + field + '=' + encodeURIComponent(value);
}
url += '&format=json';
mw.loader.load(url);
}
infobox.loadCodeFromTemplateName=function(name) //na podstawie http://pl.wikipedia.org/wiki/Wikipedysta:Beau/infobox.js - dzięki, Beau
{
infobox.callApi(
{
action: 'query',
prop: 'revisions',
titles: 'Szablon:' + name + "|Szablon:" + name + "/opis|Dyskusja szablonu:" + name,
rvprop: 'content',
callback: 'infobox.parseInstructionQuery'
}
)
}
infobox.parseInstructionQuery=function(response) //na podstawie http://pl.wikipedia.org/wiki/Wikipedysta:Beau/infobox.js - dzięki, Beau
{
var instr;
for (var page_id in response.query.pages)
{
var page = response.query.pages[page_id];
if (!page.revisions) continue;
var rvcontent = page.revisions[0]['*'];
var found = rvcontent.match(/<pre>\s*?(\{\{(?:.|\s)+?)<\/pre>/im);
if (found)
{
instr = found[0]
break
}
}
if (!instr)
{
alert("Nie udało się znaleźć wywołania. Upomnij się o nie na wikiprojekcie: [[Wikiprojekt:Infoboksy]]. Jeśli jesteś pewien, że wywołanie jest, a skrypt go nie znalazł, zgłoś błąd autorom.");
return;
}
ib=infobox.findInText(instr)
if(typeof ib=='string') infobox.loadTemplateFromCode(ib,{forceSelname:'{nazwa}, wywołanie pobrane automatycznie'})
}
infobox.loadPreview=function(infoboxCode)
{
infobox.callApi(
{
action:'parse',
text:infoboxCode,
callback:'infobox.showPreview'
}
)
}
infobox.showPreview=function(response)
{
text=response.parse.text['*']
infobox.message('<input type="submit" value="Zamknij podgląd" onclick="remove(\'infoboxPreview\')" />'+text+'<div style="clear:both"> </div>','infoboxPreview')
}
if(mw.config.get('wgAction')=='edit' || mw.config.get('wgAction')=='submit') addOnloadHook(infobox.insertSelector)
// ----------------------------------------------------
// Move whole toolbar to a section of the New Toolbar
//
infobox.moveToNew = function()
{
var nbar = document.getElementById('wikiEditor-ui-toolbar');
if (!nbar)
{
return;
}
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', {
'sections': {
'mrinfoboksy': {
'type': 'toolbar',
'label': (mw.config.get('wgUserLanguage')=='pl' ? "Infoboksy" : "Infoboxes")
}
}
} );
infobox.elBoxSec = getElementsByClassName(nbar, "div", "section-mrinfoboksy")[0];
// move toolbar to proper place
var el = document.getElementById('infoboxSelectorBox');
infobox.elBoxSec.appendChild(el);
// fix the new toolbar bug
infobox.refreshSection();
}
// fix the new toolbar bug
infobox.refreshSection = function()
{
if (infobox.elBoxSec)
{
setTimeout(function()
{
if (infobox.elBoxSec.clientHeight>2)
{
infobox.elBoxSec.parentNode.style.height = (infobox.elBoxSec.clientHeight+1) + 'px';
}
}, 100);
}
}
// </pre>
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.