User:Gerbrant/edit/multiReplace.js

From OpenWetWare

Jump to: navigation, search

Note - After saving, you may have to bypass your browser's cache to see the changes. Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh); Konqueror: click Reload or press F5; Opera: clear the cache in Tools → Preferences; Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.

try
{
	"A".replace(/A|(B)/, function(a, b)
	{
		if(b != undefined) throw false;
		return a;
	});
}
catch(e)
{
	(function(m)
	{
		alert(m);
		throw new Error(m);
	})("The script Gerbrant.edit.multiReplace cannot be used because your browser's implementation of String.prototype.replace is buggy. More specifically, it doesn't handle non-participating capturing groups correctly.");
}
 
module("Gerbrant.edit.multiReplace", function()
{
 
patterns = [];
handlers = [];
indices = [];
var j = 1;
 
this.add = function(p, h)
{
	var n = p.match(/\((?!\?)/g);
	if(n) n = n.length + j;
	else n = j;
	patterns.push(p.replace(/\\(\d+)/, function(a, b)
	{
		return "\\" + (+b + n - 1);
	}));
	handlers.push(h);
	indices.push([j, ++n]);
	j = n;
}
 
//equivalent aan a.slice(b, e), maar dat werkt niet voor arguments
function sliceArg(a, b, e)
{
	n = [];
	while(b < e) n.push(a[b++]);
	return n;
}
 
this.handler = function(a)
{
	var i, idx;
	for(i in indices)
	{
		idx = indices[i];
		if(arguments[idx[0]] != undefined)
			try
			{
				return handlers[i].apply(a, sliceArg(arguments, idx[0], idx[1]));
			}
			catch(e)
			{
				alert(e.message + "\n\n" + handlers[i]);
				return a;
			}
	}
	throw "Failed sanity check.";
}
 
this.getRE = function()
{
	return new RegExp("(" + patterns.join(")|(") + ")", "g")
};
 
this.replace = function(t)
{
	return t.replace(this.getRE(), this.handler);
};
 
});
Personal tools