User:Zocky/foo.js
From Wikipedia
Note: After saving, you may have to bypass your browser's cache to see the changes. Mozilla / Firefox / Safari: hold down Shift while clicking Reload, or press Ctrl-Shift-R (Cmd-Shift-R on Apple Mac); IE: hold Ctrl while clicking Refresh, or press Ctrl-F5; Konqueror:: simply click the Reload button, or press F5; Opera users may need to completely clear their cache in Tools→Preferences.
document.write('<link rel="stylesheet" type="text/css" href="'
+ 'http://test.wikipedia.org/w/index.php?title=User:Zocky/foo.css'
+ '&action=raw&ctype=text/css"/>');
addLoadEvent (fooInit);
var fooActions=
{
toggleDebug: function(fooElement)
{
if ($('foo-debug'))
{
if ($a(document.body,'fooDebug') == 'show')
a$(document.body,'fooDebug', 'hide')
else
a$(document.body,'fooDebug', 'show')
}
return false;
},
showId: function(fooElement)
{
fooDebug (fooElement.id); return false;
},
evalScript: function(fooElement)
{
try
{
if ($(fooElement.fooParams.source).fooScript)
{
res=eval($$(fooElement.fooParams.source) || $(fooElement.fooParams.source).textContent);
fooElement.fooParams.target && insertOver(fooElement.fooParams.target,res);
}
else fooDebug ("#" + fooElement.fooParams.source + " is not a script");
}
catch (e)
{
fooDebugError (e);
}
return false;
}
};
function fooRegisterAction(name,fn)
{
fooActions[name]=fn;
}
function fooClick(fooElement)
{
var res=false;
try
{
res = fooActions[fooElement.fooParams.action](fooElement);
}
catch(e){ fooDebugError(e)}
return res;
}
function fooInit()
{
if ($('foo-application'))
{
$('foo-application').style.display='none';
insertTop('content', '<div style="border:green solid 1px;background:#dfd;margin:1em;padding:1em;" id="foo-run"><center><b>This page contains an embedded application. If you trust the maintainer(s) of the page, you can <a href="javascript:fooRun()">run it</a>.</b></center></div>');
}
}
function fooRun()
{
$('foo-run').style.display="none";
fooConvertTags
({
inTag: 'div',
inClass: 'foo-place',
outTag: 'div',
inOutTag: 'tag',
inOutAttr: {'$text$':'$html$',style:'style'},
finalAction: function (In,Out)
{
if ($(Out.fooParams.ref))
{
fooPlace($(Out.fooParams.ref),Out,$(Out.fooParams.where) || 'bottom')
In.innerHTML='';
}
else over$(In,Out)
}
});
fooConvertTags
({
inTag: 'span',
inClass: 'foo-input',
outTag: 'input',
outAttr: {type:'text'},
inOutAttr: {size:'size',value:'$text$',style:'style'},
finalAction: function (In,Out) { over$(In,Out) }
});
fooConvertTags
({
inTag: 'span',
inClass: 'foo-checkbox',
outTag: 'input',
outAttr: {type:'checkbox'},
inOutAttr: {size:'size', style:'style'},
finalAction: function (In,Out) { Out.fooParams.place=='after' && bottom$(In,Out) || top$(In,Out) }
});
fooConvertTags
({
inTag: 'div',
inClass: 'foo-textarea',
outTag: 'textarea',
inOutAttr: {cols:'cols',rows:'rows',$text$:'$text$',style:'style'},
finalAction: function (In,Out) { over$(In,Out) }
});
fooConvertTags
({
inTag: 'span',
inClass: 'foo-button',
outTag: 'input',
outAttr: {type:'button',onClick:'fooClick(this)'},
inOutAttr: {size:'size',value:'$text$',style:'style'},
finalAction: function (In,Out) { over$(In,Out) }
});
fooConvertTags
({
inTag: 'span',
inClass: 'foo-link',
outTag: 'a',
outAttr: {href:'javascript:return false', onClick:'fooClick(this)'},
inOutAttr: {'$text$':'$text$',style:'style'},
finalAction: function (In,Out) { over$(In,Out) }
});
if ($('foo-debug'))
fooConvertTags
({
inTag: 'div',
inClass: 'foo-script',
outTag: 'textarea',
outAttr: {'style':'display:block'},
inOutAttr: {cols:'cols',rows:'rows',$text$:'$text$'},
finalAction: function (In,Out)
{
Out.fooScript=true;
a$(In,'class','foo-debug-script');
over$(In,Out)
}
});
else
fooConvertTags
({
inTag: 'div',
inClass: 'foo-script',
outTag: 'div',
outAttr: {style:'display:none'},
inOutAttr: {$text$:'$text$'},
finalAction: function (In,Out) { Out.fooScript=true; over$(In,Out) }
});
}
function fooDebug(text)
{
if ($('foo-debug'))
{
insertBottom('foo-debug', '<div class="fooDebugPrint">' + text + '</div>');
}
else alert(text);
}
function fooDebugError(err)
{
if ($('foo-debug'))
{
insertBottom('foo-debug', '<div class="fooDebugError">' + '<b>' + err.name + '</b>: ' + err.message + '</div>');
}
else alert('<b>' + err.name + '</b>: ' + err.message);
}
function fooConvertTags(args)
{
try
{
// find tags with the appropriate class - will need xpath 2.0 to work 100% correctly
var fooInTags=xNodes("//" + args.inTag + "[not (@foo) and contains(@class,'" + args.inClass +" ')]");
// iterate found tags
for ( var j=0 ; j < fooInTags.snapshotLength; j++ )
{
var fooInTag=fooInTags.snapshotItem(j);
//extract params
var params = fooExtractFromClass(fooInTag);
//make new element
var fooOutTag=c$(params[args.inOutTag] || args.outTag);
fooOutTag.fooParams=params;
fooOutTag.id=fooInTag.id;
fooOutTag.name=fooInTag.id;
fooInTag.id += '-container';
//set preset attributes
for (i in (args.outAttr || []))
{
var value=args.outAttr[i];
if (i=='$text$') fooOutTag.innerHTML = value
else (value!=null) && a$(fooOutTag,i,value);
}
//extract attributes from params
for (i in (args.inOutAttr || []))
{
var value=args.inOutAttr[i];
switch (value)
{
case '$text$':
value=fooInTag.textContent; break;
case '$html$':
value=fooInTag.innerHTML; break;
default:
value=(value in fooOutTag.fooParams) ? fooOutTag.fooParams[value] : null;
}
if (i=='$text$') fooOutTag.innerHTML = value
else (value!=null) && a$(fooOutTag,i,value);
}
a$(fooInTag,'foo','bar');
//
if (!$('foo-debug'))
{
while($a(fooInTag,'class')!='foo-wrapper') fooInTag=fooInTag.parentNode;
a$(fooInTag,'style','');
}
args.finalAction(fooInTag, fooOutTag);
}
} catch (e) {fooDebugError(e)};
}
function fooPlace(into,what,where)
{
switch(where)
{
case 'top':
top$(into,what); break;
case 'before':
before$(into,what); break;
case 'after':
after$(into,what); break;
case 'bottom':
bottom$(into,what); break;
case 'over':
default:
over$(into,what); break;
}
}
function fooExtractFromClass(el)
{
var text;
if(text=$a(el,'class'))
{
var p=text.replace(/^.* foo:\{/,'{');
a$(el,'class',text.replace(/ foo:.*?$/,''));
return p.parseJSON();
}
else return [];
}
var top$ = function (ref,el) {ref.insertBefore(el,ref.firstChild)}
var bottom$ = function (ref,el) {ref.appendChild(el)}
var over$ = function (ref,el) {ref.innerHTML = '';ref.appendChild(el)}
var before$ = function (ref,el) {ref.parentNode.insertBefore(el,ref)}
var after$ = function (ref,el) {
if (ref.nextSibling) ref.parentNode.insertBefore(el,ref.nextSibling);
else ref.parentNode.appendChild(el)
}
var $ = function (id) { return document.getElementById(id)}
var $$ = function (id) { return document.getElementById(id).value}
var c$ = function(tag) {return document.createElement(tag); el.id=id; return el}
var $a = function (element,name) {return element.getAttribute(name)}
var a$ = function (element,name,value) {return element.setAttribute(name,value)}
var insertTop = function (id,what) {$(id).innerHTML = what + $(id).innerHTML}
var insertBottom = function (id,what) {$(id).innerHTML += what}
var insertOver = function (id,what) {$(id).innerHTML = what}
var xNodes=function(x,n)
{
return document.evaluate(x, n||document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
};
var xNode=function(x,n)
{
return document.evaluate(x, n||document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
};
var xString=function(x,n)
{
return document.evaluate(x, n||document, null, XPathResult.STRING_TYPE, null).stringValue;
};
String.prototype.parseJSON = function () {
try {
return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
this.replace(/"(\\.|[^"\\])*"/g, ''))) &&
eval('(' + this + ')');
} catch (e) {
return false;
}
};

