User:Gerbrant/edit/multiReplace.js

From OpenWetWare
Revision as of 14:34, 26 July 2009 by Bill Flanagan (talk | contribs) (1 revision)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: 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);
};

});