JSFiddle - React, Tailwind, and code Playground

by George Y

HTML

<strong>Initial Text</strong>
<br>
<br>
<span id="yo" data-editableproperty="text"><span style="font-family: Open Sans;"><span style="font-style: italic;"><span style="font-weight: 700;">fdsfdsfdsfsdfdsfds</span></span>
</span>
<br>Hello World
<br><strong>What is up world?</strong>
<br><u style="font-weight:700">wow this is a u style font weight!!!</u>
<br>
<div style="text-align: left;"><u><span style="color: rgba(232,0,0,1);"><span style="font-family: Open Sans;"><span style="font-weight: 600;">Everything</span></span></span></u> is <span style="font-family: Open Sans;"><span style="font-weight: 600;">good world?</span></span>
</div>Really?
<br>
</span>
<br>
<br>
<strong>Initial HTML</strong>
<div id="initial-html">
</div>
<br>
<br>
<hr/>
<strong>After Text</strong>
<div id="after-text">
</div>
<br>
<br>
<strong>After HTML</strong>
<div id="after-html">
</div>

CSS

//var fontSizeRegex = /(<span [^>]*font-size[^>]*>)/gi;
   var myRegex=mappingsOfStyledWithRegex[style];
   var spansRegex=mappingsOfStyledWithRegexForTag[style];
   var matches=[];
   var toRemove=[];
   var res,
   count,
   fontSizeMatch;
   while (res=spansRegex.exec(text)) {
     //Find all spans beginning and ending and pushing to array (in the right order)
     matches.push( {
       text: res[0], index: res.index
     }
     );
   }
   
   while(fontSizeMatch=myRegex.exec(text)) {
     //looking for style match with regex
     toRemove.push( {
       index: fontSizeMatch.index, length: fontSizeMatch[0].length
     }
     ); //placing strings that we want to remove in the 'toRemove'
     count=0;
     for(var i=0;
     i < matches.length;
     i++) {
       //looping all found opening and closing tags
       if(matches[i].index <=fontSizeMatch.index) //before the fontsize span or in case it is equal it is the actual font size span
       continue; //skip it
       if(matches[i].text==="<span") //
       count++;
       else count--;
       if(count < 0) break;
     }
     if(matches[i]===undefined) //not euqal number of opening and closing tags
     console.log('bad html!') if(matches[i].text==="<span") //if found and it is an opening tag we have a problem
     console.log('MAJOR PROBLEM') toRemove.push( {
       index: matches[i].index, length: matches[i].text.length
     }
     ); //Match! Closing tag, where it starts and length
     //while continous since you may find more font size spans
   }
   
   toRemove.sort(function(a, b) {
     //sorting because we want to start removing from the end, since in other case we are goind to break the indexes
     if(a.index < b.index) //first is the one with the highest index
     return 1;
     return -1;
   }
   
   ) console.log(toRemove) for(var i=0;
   i<toRemove.length;
   i++) {
     //remove = getting text before the index of the span, getting text after span
     text=text.substring(0, toRemove[i].index) +...

JavaScript

var text = $('#yo').html()
$('#initial-html').text(text)
var style = 'bold'

stipItYo(text, style);

function stipItYo(text, style) {

  var mappingsOfStyledWithRegex = {
    'bold': /(<strong>)/gi,
    'italic': [/(<em>)/gi, /(<span\s+[^>]*?\s*style\s*=\s*(?:\'|")(?:\S+\s+)?font-style(?:\s+\S+)?\1[^>]*>)/gi],
    'underline': [/(<u>)/gi, /(<span\s+[^>]*?\s*style\s*=\s*(?:\'|")(?:\S+\s+)?text-decoration(?:\s+\S+)?\1[^>]*>)/gi],
    'color': /(<span\s+[^>]*?\s*style\s*=\s*(?:\'|")(?:\S+\s+)?color(?:\s+\S+)?\1[^>]*>)/gi,
    'letter-spacing': /(<span\s+[^>]*?\s*style\s*=\s*(?:\'|")(?:\S+\s+)?letter-spacing(?:\s+\S+)?\1[^>]*>)/gi,
    'line-height': /(<span\s+[^>]*?\s*style\s*=\s*(?:\'|")(?:\S+\s+)?line-height(?:\s+\S+)?\1[^>]*>)/gi,
    'font-size': /(<span\s+[^>]*?\s*style\s*=\s*(?:\'|")(?:\S+\s+)?font-size(?:\s+\S+)?\1[^>]*>)/gi,
    'font-family': /(<span\s+[^>]*?\s*style\s*=\s*(?:\'|")(?:\S+\s+)?font-family(?:\s+\S+)?\1[^>]*>)/gi,
    'text-align': /(<div\s+[^>]*?\s*style\s*=\s*(?:\'|")(?:\S+\s+)?text-align(?:\s+\S+)?\1[^>]*>)/gi
  }

  var mappingsOfStyledWithRegexForTag = {
    'bold': /(<\/strong>)|(<strong)/gi,
    'italic': [/(<\/em>)|(<em)/gi, /(<\/span>)|(<span)/gi],
    'underline': [/(<\/u>)|(<u)/gi, /(<\/span>)|(<span)/gi],
    'color': /(<\/span>)|(<span)/gi,
    'letter-spacing': /(<\/span>)|(<span)/gi,
    'line-height': /(<\/span>)|(<span)/gi,
    'font-size': /(<\/span>)|(<span)/gi,
    'font-family': /(<\/span>)|(<span)/gi,
    'text-align': /(<\/div>)|(<div)/gi
  }

  var extraCheckMappings = {
    'bold': '<strong'
  }

  //var fontSizeRegex = /(<span [^>]*font-size[^>]*>)/gi;
  var myRegex = mappingsOfStyledWithRegex[style]
  var tagsRegex = mappingsOfStyledWithRegexForTag[style]

  var matches = [];
  var toRemove = [];
  var res, count, styleMatch;

  if (style == 'bold') {
    var fontWeightRegex = /[<span|<u|<em|<div]\s+[^>]*?\s*style\s*=\s*(?:\'|")(?:\S+\s+)?(font-weight(?:\s+\S+)?\1[^;"]*;?)/gi;
     while ((m =...