JSFiddle - React, Tailwind, and code Playground

by Oski Krawczyk

JavaScript

Helpers.extractPartsFromHTML = function(fullHtml){

  let title = null
  let css   = ""
  let js    = ""

  // Extract and remove <title> contents
  fullHtml = fullHtml.replace(/<title[^>]*>([\s\S]*?)<\/title>/gi, (match, content) => {
    title = content.trim()
    return ""
  })

  // Extract and remove <style> contents
  fullHtml = fullHtml.replace(/<style[^>]*>([\s\S]*?)<\/style>/gi, (match, content) => {
    css += `${content.trim()}\n\n`
    return ""
  })

  // Extract and remove <script> contents
  fullHtml = fullHtml.replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi, (match, attrs, content) => {

    // Leave <script> in HTML if it has type="application/ld+json" or a src attribute
    if (
      /\btype\s*=\s*(['"])application\/ld\+json\1/i.test(attrs) ||
      /\bsrc\s*=\s*(['"])[^'"]+\1/i.test(attrs)
    ) {
      return match
    } else {
      js += `${content.trim()}\n\n`
      return ""
    }
  })

  // Remove DOCTYPE, HTML, META, HEAD, BODY tags and their closing counterparts
  fullHtml = fullHtml.replace(/<!DOCTYPE[^>]*>/i, "")
  fullHtml = fullHtml.replace(/<\/?(?:html|head(?!er\b)|body)[^>]*>/gi, "")
  fullHtml = fullHtml.replace(/<meta[^>]*>/gi, "")

  // Compress multiple empty lines into a single empty line
  fullHtml = fullHtml.replace(/([ \t]*\n){3,}/g, "\n\n")

  return {
    css:   css.trim(),
    js:    js.trim(),
    html:  fullHtml.trim(),
    title: title
  }
}