0

i have a site where i paste my entire source code into a box and update all the td tags with a background color if there isnt currently a "bgcolor" attribute.

I've been messing with this for some time but i can't get my ogSource to update. I've tried many ways such as assigning new variables, returns etc etc. No luck.

the below code properly scans for the appropriate td and adds the background color, it just doesnt apply it to the ogSource. I've removed all my other code to make this as basic as possible.

Can anyone assist with this?

Thanks in advance.

var ogSource = '<table id="test1"> <tr> <td> <table id="test2"> <tr> <td> </td> </tr> </table></td> </tr> </table>'
ogSource.replace(/\<td(.*?)\>/g, function(matches) {
  if (!matches.includes('bgcolor')) {
    var idx = matches.lastIndexOf(">");
    if (idx > -1) {
      matches = matches.substr(0, idx) + " bgcolor='pink'" + matches.substr(idx);
    }
  }
});
console.log(ogSource);

EDIT/UPDATE After a lot of messing around- this was a solution that was able to capture all the source code pasted and make the modification needed.

ogSource = ogSource.replace(/\<td(.*?)\>/g, function( matches , i ) { 
        var idx = matches.lastIndexOf(">"); 
        if (idx > -1) { 
            if (!matches.includes('bgcolor')) { 
                ogSource = matches.substr(0, idx) + " bgcolor='pink'" + matches.substr(idx); 
            } else { 
                ogSource = matches; 
            } 
        } return ogSource; 
    }); 
    
    console.log(ogSource); 
stuckdev
  • 1
  • 2

1 Answers1

1

My initial answer was off the mark but quite a bit, however, I think regex in general may not be the best solution due to the amount of edge cases present and the DOMParser might be a better solution for this.

Essentially, you pass the html string into the DOMParser method parseFromString and store that in a variable, then select all td elements and check if they have a bgColor attribute, if they don't, give them one, then output the new DOM string.

Here's an example:

const domParser = new DOMParser();

const DOM = domParser.parseFromString(`<table id="test1"> <tr> <td> <table id="test2"> <tr> <td> </td> </tr> </table></td> </tr> </table>`, "text/html");

// Find all tds
const tds = DOM.querySelectorAll("td");

for(let i = 0; i < tds.length; i++) {
  let currentTD = tds[i];
  if(!currentTD.hasAttribute("bgColor")) {
    currentTD.setAttribute("bgColor", "someValue");
  }
}

console.log(DOM.body.innerHTML); // If you only want to return the table content
console.log(DOM.querySelector("html").innerHTML); // If you want all of the html code that was added
Ameer
  • 1,980
  • 1
  • 12
  • 24
  • i believe i tried this earlier and it didnt happen. but i pasted your code and i still return this in console.
    – stuckdev Jul 08 '21 at 20:40
  • Just updated my answer, this should work now – Ameer Jul 08 '21 at 21:05
  • so your update fixed it. thank you. but do you know why the parser (i presume) is adding tbody tags? it's not really giving me an exact one to one copy from what i paste in and get out. – stuckdev Jul 08 '21 at 21:19
  • perhaps it's because i had to add parseFromString to get it to properly get the value from the textbox. const parser = new DOMParser(); let ogSource = document.getElementById("og-source").value; let DOM = parser.parseFromString(ogSource, "text/html"); – stuckdev Jul 08 '21 at 21:22
  • it also ignores all all the etc etc. i dont think this will work for me. i need an exact copy with only the td color added. – stuckdev Jul 08 '21 at 21:49
  • If you want the entire html page all you have to change is `DOM.querySelector("html").innerHTML` and that returns the entire html code that was entered + the changes, I updated my answer with that code as an example – Ameer Jul 08 '21 at 22:25
  • Let me know if this solution works for you @stuckdev, if it does, I'd really appreciate if you could accept the answer – Ameer Jul 09 '21 at 22:17
  • Hi, so in the end i realized that this doesnt actually achieve what i needed. This method works pretty well, but it doesnt give me an exact copy of the original pasted code. I've been trying to figure out a way to get your code to do this, and once i get this working i will accept. It really just needs to be the exact copy of source code with the modification where applicable. – stuckdev Jul 10 '21 at 15:10
  • im still testing this but i think this does what i need. ogSource = ogSource.replace(/\/g, function( matches , i ) { var idx = matches.lastIndexOf(">"); if (idx > -1) { if (!matches.includes('bgcolor')) { ogSource = matches.substr(0, idx) + " bgcolor='pink'" + matches.substr(idx); } else { ogSource = matches; } } return ogSource; }); console.log(ogSource); – stuckdev Jul 10 '21 at 15:55
  • Keep in mind it's pretty bad practice to parse any form of html using regex, see https://stackoverflow.com/a/1732454/10213537 for more info. – Ameer Jul 10 '21 at 17:35
  • this might be true for certain circumstance. but other than regex im not sure how to achieve a true capture of a copy/paste of actual source code beforerender without putting in more time than i have. I tried your method of parsing the DOM, but it omitted content that was required. Thank you for trying. I want to accept your answer because it did do the attribute... but at the same time the original ask was for the "Entire source code". – stuckdev Jul 10 '21 at 17:44