User:Topbanana/sandbox/regexReplace.js

/* This is a slightly modified copy of User:Gerbrant/edit/regexReplace.js as I couldn't  make the original do what I wanted.

// Add some useful styles mw.util.addCSS( 'span.GerbrantEditRegexReplaceHit{font-weight:bold;background:lightsteelblue}'); mw.util.addCSS( 'span.GerbrantEditRegexReplaceHitOff{font-weight:bold;background:mistyrose}'); mw.util.addCSS( 'span.GerbrantEditRegexReplaceMaskFailed{font-weight:normal;color:red}');

function createRegexControls {  var lang, textBox = document.getElementById("wpTextbox1"); if(!textBox) return;

str = { finished: "Finished; $1 items were replaced.", finished2: "Finished; $1 out of $2 items were replaced.", notFound: "Requested text was not found.", replace: "Find", replaceSel: "Replace", errorNoCheckBox: "Cannot find the corresponding checkbox.", textHasChanged: "Warning! The text has changed after 'Replace...' was clicked. These changes will be lost during replacement. Do you want to continue?", looksLikeFunction: "Warning! The text you intend to use to replace the matched text looks like a JavaScript function. Are you really sure you want to use this as replacement text, and not as a replacement function?", maskFailed: "Mask failed: $1", useRepFun: " " };

var mask, regex, text, minFrag = 30, minDel = 10, repFun;

var results = document.createElement("DIV"); var tbRegex = document.createElement("INPUT"); tbRegex.id = "tbRegex_SearchTextBox";

var hl = document.createElement("INPUT"); hl.type = "checkbox";

var rep = document.createElement("DIV"); rep.style.display = "none"; rep.style.whiteSpace = "nowrap";

function returnTrue{ return true; }

function evalError(e){ alert(e.message); }

function getMaskAndRegex(t) {     var p = t.indexOf("**"), r;      if(p < 0) return [returnTrue, t]; else {        try{ eval("r=" + t.slice(0, p)) } catch(x){ evalError(x); r = returnTrue; } return [r, t.slice(p + 2)]; }  }

function findMatches {     var m = [], r = [], i = 0; text = textBox.value;

var t = text.replace(regex, function(a)     {         try         {            if(!mask.apply(null, arguments)) return a;         }         catch(e)         {            m.push(a + ' \u0001span class="GerbrantEditRegexReplaceMaskFailed">(' + str.maskFailed.replace("$1", e.message) + ')\u0001/span>');            return "\u0001";         }         m.push(a);         return "\u0001";      }).split("\u0001");

if(m.length == 0) {        results.innerHTML = str.notFound; return; }

if(t[0].length > minFrag + minDel) {        r.push(" \u2026 "); r.push(t[0].slice(-minFrag)); }     else r.push(t[0]); while(true) {        r.push('\u0001span class="GerbrantEditRegexReplaceHit">\u0001input type="checkbox" checked id="Gerbrant-errCB');         r.push(i);         r.push('" onclick="Gerbrant.edit.regexReplace.toggleCB(this)">'); r.push(m[i]); r.push('\u0001/span>'); if(++i >= m.length) break; if(t[i].length > 2 * minFrag + minDel) {           r.push(t[i].slice(0, minFrag)); r.push(" \u2026 "); r.push(t[i].slice(-minFrag)); }        else r.push(t[i]); }     if(t[i].length > minFrag + minDel) {        r.push(t[i].slice(0, minFrag)); r.push(" \u2026 "); }     else r.push(t[i]);

rep.style.display = ""; onResize; results.innerHTML = r.join("").replace(        /&/g, "&amp;").replace(         /</g, "&lt;").replace(         /\u0001/g, "<").replace(         /\n[ \t]/g, "\n ").replace(         /[ \t](?=[ \t])/g, " ").replace(         /\n/g, " "); }

function getRegexAndFind {     mask = getMaskAndRegex(tbRegex.value); regex = new RegExp(mask[1], hl.checked ? "g" : "ig"); mask = mask[0]; findMatches; }

var ok = document.createElement("INPUT"); ok.type = "button"; ok.value = str.replace; ok.onclick = getRegexAndFind; ok.id = "tbRegex_FindButton";

var div = document.createElement("DIV"); div.style.whiteSpace = "nowrap"; div.appendChild(tbRegex); div.appendChild(hl); div.appendChild(ok);

var tbReplace = document.createElement("INPUT"); tbReplace.id = "tbRegex_ReplaceTextBox";

var chkJS = document.createElement("INPUT"); chkJS.type = "checkbox";

function doReplace {     var rjs = chkJS.checked, i = 0, j = 0, r, nt, ohno = false; if(text != textBox.value) if(!confirm(str.textHasChanged)) return; r = tbReplace.value; if(rjs) if(r == str.useRepFun) r = repFun; else try{ eval("r=" + r); } catch(x){ evalError(x); return; } else if(r == str.useRepFun || /^\s*function\s*\([0-9A-Za-z$_, ]*\)\s*\{/.test(r)) if(!confirm(str.looksLikeFunction)) return; try {        nt = text.replace(regex, function(a)         {            try{ if(!mask.apply(null, arguments)) return a; }catch(e){/* mask failed; assume true */}            var c = document.getElementById("Gerbrant-errCB" + i++);            if(c)               if(c.checked)               {                  j++;                  if(rjs)                     return r.apply(null, arguments);                  else return r;               }               else return a;            else ohno = true;         }); }     catch(e) {        alert(e.message); return; }     if(ohno) {        alert(str.errorNoCheckBox); return; }     if(j < i) results.innerHTML = str.finished2.replace("$1", j).replace("$2", i); else results.innerHTML = str.finished.replace("$1", j); rep.style.display = "none"; textBox.value = nt; }

var finish = document.createElement("INPUT"); finish.type = "button"; finish.value = str.replaceSel; finish.onclick = doReplace;

rep.appendChild(tbReplace); rep.appendChild(chkJS); rep.appendChild(finish);

textBox.parentNode.insertBefore(div, textBox); textBox.parentNode.insertBefore(results, textBox); textBox.parentNode.insertBefore(rep, textBox);

function onResize {     finish.style.height = ok.style.height = tbRegex.offsetHeight + "px"; tbRegex.style.width = textBox.offsetWidth - ok.offsetWidth - hl.offsetWidth - 14 + "px"; tbReplace.style.width = textBox.offsetWidth - finish.offsetWidth - chkJS.offsetWidth - 14 + "px"; }  onResize; //  hookEvent("resize", onResize); }