UNPKG

can-simple-dom

Version:
86 lines (68 loc) 2.07 kB
var he = require('he'); function HTMLParser(tokenize, document, voidMap) { this.tokenize = tokenize; this.document = document; this.voidMap = voidMap; this.parentStack = []; } HTMLParser.prototype.isVoid = function(element) { return this.voidMap[element.nodeName] === true; }; HTMLParser.prototype.pushElement = function(token) { var el = this.document.createElement(token.tagName); for (var i=0;i<token.attributes.length;i++) { var attr = token.attributes[i]; if(attr[0] !== 'href' && attr[0] !== 'src') { attr[1] = he.encode(attr[1]); } el.setAttribute(attr[0], attr[1]); } if (this.isVoid(el) || token.selfClosing) { return this.appendChild(el); } this.parentStack.push(el); }; HTMLParser.prototype.popElement = function(token) { var el = this.parentStack.pop(); if (el.nodeName !== token.tagName.toUpperCase()) { throw new Error('unbalanced tag'); } this.appendChild(el); }; HTMLParser.prototype.appendText = function(token) { var text = this.document.createTextNode(token.chars); this.appendChild(text); }; HTMLParser.prototype.appendComment = function(token) { var comment = this.document.createComment(token.chars); this.appendChild(comment); }; HTMLParser.prototype.appendChild = function(node) { var parentNode = this.parentStack[this.parentStack.length-1]; parentNode.appendChild(node); }; HTMLParser.prototype.parse = function(html/*, context*/) { // TODO use context for namespaceURI issues var fragment = this.document.createDocumentFragment(); this.parentStack.push(fragment); var tokens = this.tokenize(html); for (var i=0, l=tokens.length; i<l; i++) { var token = tokens[i]; switch (token.type) { case 'StartTag': this.pushElement(token); break; case 'EndTag': this.popElement(token); break; case 'Chars': this.appendText(token); break; case 'Comment': this.appendComment(token); break; } } return this.parentStack.pop(); }; module.exports = HTMLParser;