Jump to content

User:Topbanana/regexReplace.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*
  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: "< function >"
      };


   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";
   hl.id = "tbRegex_SearchCaseSensitive"

   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&nbsp;").replace(
         /[ \t](?=[ \t])/g, "&nbsp;").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;
   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);
}