Jump to content

User:Topbanana/regexReplace.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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);
}