in JSDOMParser.js [1138:1238]
readNode() {
var c = this.nextChar();
if (c === undefined) {
return null;
}
// Read any text as Text node
var textNode;
if (c !== "<") {
--this.currentChar;
textNode = new Text();
var n = this.html.indexOf("<", this.currentChar);
// We're not expecting XSS type exploitation inside JSDOMParser,
// we just have to implement innerHTML stuff...
/* eslint-disable no-unsanitized/property */
if (n === -1) {
textNode.innerHTML = this.html.substring(
this.currentChar,
this.html.length
);
this.currentChar = this.html.length;
} else {
textNode.innerHTML = this.html.substring(this.currentChar, n);
this.currentChar = n;
}
/* eslint-enable no-unsanitized/property */
return textNode;
}
if (this.match("![CDATA[")) {
var endChar = this.html.indexOf("]]>", this.currentChar);
if (endChar === -1) {
this.error("unclosed CDATA section");
return null;
}
textNode = new Text();
textNode.textContent = this.html.substring(this.currentChar, endChar);
this.currentChar = endChar + "]]>".length;
return textNode;
}
c = this.peekNext();
// Read Comment node. Normally, Comment nodes know their inner
// textContent, but we don't really care about Comment nodes (we throw
// them away in readChildren()). So just returning an empty Comment node
// here is sufficient.
if (c === "!" || c === "?") {
// We're still before the ! or ? that is starting this comment:
this.currentChar++;
return this.discardNextComment();
}
// If we're reading a closing tag, return null. This means we've reached
// the end of this set of child nodes.
if (c === "/") {
--this.currentChar;
return null;
}
// Otherwise, we're looking at an Element node
var result = this.makeElementNode(this.retPair);
if (!result) {
return null;
}
var node = this.retPair[0];
var closed = this.retPair[1];
var localName = node.localName;
// If this isn't a void Element, read its child nodes
if (!closed) {
this.readChildren(node);
var closingTag = "</" + node._matchingTag + ">";
if (!this.match(closingTag)) {
this.error(
"expected '" +
closingTag +
"' and got " +
this.html.substr(this.currentChar, closingTag.length)
);
return null;
}
}
// Only use the first title, because SVG might have other
// title elements which we don't care about (medium.com
// does this, at least).
if (localName === "title" && !this.doc.title) {
this.doc.title = node.textContent.trim();
} else if (localName === "head") {
this.doc.head = node;
} else if (localName === "body") {
this.doc.body = node;
} else if (localName === "html") {
this.doc.documentElement = node;
}
return node;
},