JSFiddle - React, Tailwind, and code Playground

by Dhanck

HTML

Enter html:
  <textarea id="input">
&lt;div onclick="alert('hi!')"&gt;Hello.&lt;/div&gt;
&lt;script&gt;alert('hi!')&lt;/script&gt;
&lt;img src="broken" onerror="alert('onerror gotcha!')"&gt;
  </textarea>
  <button onclick="sanitizeIt();">Sanitize it</button><br>
  Sanitized:
  <div id="sanitized-html"></div>
  Rendered:
  <div id="sanitized-rendered"></div>

CSS

#input, #sanitized-html, #sanitized-rendered {
      border: 1px solid black;
      width: 95%;
      height: 10em;
      overflow: auto;
    }

JavaScript

function sanitizeIt() {
  var sanitized = sanitizeHtml(document.getElementById('input').value);
  document.getElementById('sanitized-html').textContent = sanitized;
  document.getElementById('sanitized-rendered').innerHTML = sanitized;
};

var tagWhitelist_ = {
  'A': true,
  'B': true,
  'BODY': true,
  'BR': true,
  'DIV': true,
  'EM': true,
  'HR': true,
  'I': true,
  'IMG': true,
  'P': true,
  'SPAN': true,
  'STRONG': true
};

var attributeWhitelist_ = {
  'href': true,
  'src': true
};

function sanitizeHtml(input) {
  var iframe = document.createElement('iframe');
  if (iframe['sandbox'] === undefined) {
    alert('Your browser does not support sandboxed iframes. Please upgrade to a modern browser.');
    return '';
  }
  iframe['sandbox'] = 'allow-same-origin';
  iframe.style.display = 'none';
  document.body.appendChild(iframe); // necessary so the iframe contains a document
  iframe.contentDocument.body.innerHTML = input;
  
  function makeSanitizedCopy(node) {
    if (node.nodeType == Node.TEXT_NODE) {
      var newNode = node.cloneNode(true);
    } else if (node.nodeType == Node.ELEMENT_NODE && tagWhitelist_[node.tagName]) {
      newNode = iframe.contentDocument.createElement(node.tagName);
      for (var i = 0; i < node.attributes.length; i++) {
        var attr = node.attributes[i];
        if (attributeWhitelist_[attr.name]) {
          newNode.setAttribute(attr.name, attr.value);
        }
      }
      for (i = 0; i < node.childNodes.length; i++) {
        var subCopy = makeSanitizedCopy(node.childNodes[i]);
        newNode.appendChild(subCopy);
      }
    } else {
      newNode = document.createDocumentFragment();
    }
    return newNode;
  };

  var resultElement = makeSanitizedCopy(iframe.contentDocument.body);
  document.body.removeChild(iframe);
  return resultElement.innerHTML;
};