I need to write a Javascript or (preferably) Typescript function that takes a string of mostly HTML, does something to it, and returns valid HTML. I had the idea that "</>" would be replaced with the correct closing tag, for example:
<button>I'm a button</> I'm text!
would give:
<button>I'm a button</button> I'm text!
And should work with attributes & nested "</>" occurrences too. What I've tried:
const parse = (html: string): string => {
// regex to match </> tags
const regex = /<\/>/g;
// stack to keep track of open tags
const stack: string[] = [];
// use a parser to parse the HTML and fill the stack with open tags
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
// loop through all nodes and fill the stack with open tag names
const nodes = doc.documentElement.childNodes;
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (node.nodeType === Node.ELEMENT_NODE) {
// add the tag name to the stack
stack.push((node as Element).tagName.toLowerCase());
}
}
// replace </> with corresponding closing tag
const result = html.replace(regex, () => {
// get the last open tag from the stack
const lastOpenTag = stack.pop();
// construct the closing tag
return `</${lastOpenTag}>`;
});
// return the HTML code
return result
}
However, when trying it, this happened:
input:
<button>I'm a button!</>
I am text!
output:
<button>I'm a button! I am text!</button>
Can you help me fix this function?