User:Gerbrant/edit/regexReplace.js
From OpenWetWare
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.
document.write("<style>span.GerbrantEditRegexReplaceHit{font-weight:bold;background:lightsteelblue}span.GerbrantEditRegexReplaceHitOff{font-weight:bold;background:mistyrose}span.GerbrantEditRegexReplaceMaskFailed{font-weight:normal;color:red}</style>"); hookEvent("load", function() { var lang, textBox = document.getElementById("wpTextbox1"); if(!textBox) return; try{ lang = Gerbrant.edit.regexReplace.lang; }catch(nopresets){} if(!lang) lang = wgUserLanguage; switch(lang) { // Localized strings: case "nl": str = { finished: "Voltooid; $1 items werden vervangen.", finished2: "Voltooid; $1 van $2 items werden vervangen.", notFound: "De gevraagde tekst is niet gevonden.", replace: "Vervangen...", replaceSel: "Vervang selectie", errorNoCheckBox: "Kan het corresponderende keuzevakje niet vinden.", textHasChanged: "Waarschuwing! De tekst is gewijzigd nadat op 'Vervangen...' werd geklikt. Deze wijzigingen zullen verloren gaan bij het vervangen. Wilt u doorgaan?", looksLikeFunction: "Waarschuwing! De tekst die u wilt gebruiken om de gevonden tekst mee te vervangen ziet eruit als een JavaScript functie. Weet u zeker dat u deze als tekst wilt gebruiken, en dus niet als vervangingsfunctie?", maskFailed: "Masker faalde: $1", useRepFun: "< functie >" }; break; default: str = { finished: "Finished; $1 items were replaced.", finished2: "Finished; $1 out of $2 items were replaced.", notFound: "Requested text was not found.", replace: "Replace...", replaceSel: "Replace selection", 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: "< function >" }; // Don't localize anything beyond this point. } var mask, regex, text, minFrag = 30, minDel = 10, repFun; var results = document.createElement("DIV"); var tbRegex = document.createElement("INPUT"); //tbRegex.value = "[A-Z]{2,}"; 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, "&").replace( /</g, "<").replace( /\u0001/g, "<").replace( /\n[ \t]/g, "\n ").replace( /[ \t](?=[ \t])/g, " ").replace( /\n/g, "<br>"); } 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; var div = document.createElement("DIV"); div.style.whiteSpace = "nowrap"; div.appendChild(tbRegex); div.appendChild(hl); div.appendChild(ok); var tbReplace = document.createElement("INPUT"); 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); if(typeof module == "function") module("Gerbrant.edit.regexReplace", {replace: function(what, ulcase, repl, isjs) { if(isjs == undefined && typeof repl == "function") { repFun = repl; tbReplace.value = str.useRepFun; chkJS.checked = true; } else { tbReplace.value = repl; chkJS.checked = isjs; } if(what instanceof RegExp) { regex = what; mask = ulcase ? ulcase : returnTrue; findMatches(); } else { tbRegex.value = what; hl.checked = ulcase; getRegexAndFind(); } }, toggleCB: function(cb) { var p = cb.parentNode; if(cb.checked) { if(p.className.slice(-3) == "Off") p.className = p.className.slice(0, -3); } else if(p.className.slice(-3) != "Off") p.className += "Off"; }}); }); if(typeof loadModule == "function") { new function() { var presets; try{ presets = Gerbrant.edit.regexReplace.presets; }catch(nopresets){} if(presets) loadModule("Gerbrant.gui.lilink", function(l) { hookEvent("load", function() { var i, p, e = function(s) { return s.toString().replace(/["\\]/g, function(a) { return "\\" + a; }); }; if(!document.getElementById("wpTextbox1")) return; for(i in presets) { p = presets[i]; l.addToolboxLink('javascript:Gerbrant.edit.regexReplace.replace(' + (p.regex instanceof RegExp ? p.regex + ',' + p.mask : '"' + (p.mask ? e(p.mask) + '**' : '') + e(p.regex) + '",' + !!p.caseSens) + ',"' + e(p.replace) + '",' + (typeof p.replace == "function") + ');', i); } }); }); }; }