Search code examples
javascriptregextheoryreplace

Replace with RegEx and JavaScript


I am attempting to do a quick replace of the 'innerHTML' of the 'code' element. I thought this may work:

function codeDisplay ( ) {
    var code = document.getElementsByTagName('code').innerHTML;

    var codeExam1 = new RegExp('<', 'gm');
    var codeExam2 = new RegExp('>', 'gm');

    code.replace(codeExam1, '&lt;');
    code.replace(codeExam2, '&gt;');
      }

Do I need to perform any additional steps to push the information back to the browser or conversion of data types maybe? Or am I completely wrong in how 'RegEx' and 'innerHTML' work? I appreciate the feedback in advance.


Solution

  • So, first fo all:

    var code = document.getElementsByTagName('code').innerHTML;
    

    document.getElementsByTagName returns a list of elements not just one. So, if your purpose is escaping all the code tags you have in the page, you need to iterate them. Second, I believe you can avoid regexp just using textContent (where supported) or innerText.

    var codes = document.getElementsByTagName("code");
    
    for (var i = 0, code; code = codes[i++];) {
        if ("textContent" in code)
            code.textContent = code.innerHTML;
        else if ("innerText" in code)
            code.innerText = code.innerHTML;
    }
    

    or create a new text node:

    var codes = document.getElementsByTagName("code");
    
    for (var i = 0, code, html; code = codes[i++];) {
        html = code.innerHTML;
    
        code.innerHTML = "";
    
        code.appendChild(document.createTextNode(html));
    }
    

    That's should escape every html entities. If you still want to use the regexp, maybe as fallback, you can have this kind of function:

    var escapeEntities = (function(){
        var entities = {"<" : "lt", ">" : "gt", "&" : "amp" };
        var re = new RegExp("[" + Object.keys(entities).join("") + "]", "g");
    
        function replaceEntities(match) {
            return match in entities ? "&" + entities[match] + ";" : match;
        }
    
        return function(value) {
            return value.replace(re, replaceEntities);
        }
    })()    
    

    And then in your code:

    code.innerHTML = escapeEntities(code.innerHTML);
    

    Note that if Object.keys is not supported you can easily use a shims (as indicated in the link); or simply replace manually the list of entities you support:

     var entities = {"<" : "lt", ">" : "gt", "&" : "amp" };
     var re = /[<>&]/g;
    

    In that case you need to remember to add in both entities and re variables a new entity you want to support in the future; Object.keys just help you in maintenance.