react / wstein / node_modules / jest-cli / node_modules / jsdom / node_modules / htmlparser2 / node_modules / domhandler / index.js
81146 viewsvar ElementType = require("domelementtype");12var re_whitespace = /\s+/g;3var NodePrototype = require("./lib/node");4var ElementPrototype = require("./lib/element");56function DomHandler(callback, options, elementCB){7if(typeof callback === "object"){8elementCB = options;9options = callback;10callback = null;11} else if(typeof options === "function"){12elementCB = options;13options = defaultOpts;14}15this._callback = callback;16this._options = options || defaultOpts;17this._elementCB = elementCB;18this.dom = [];19this._done = false;20this._tagStack = [];21this._parser = this._parser || null;22}2324//default options25var defaultOpts = {26normalizeWhitespace: false, //Replace all whitespace with single spaces27withStartIndices: false, //Add startIndex properties to nodes28};2930DomHandler.prototype.onparserinit = function(parser){31this._parser = parser;32};3334//Resets the handler back to starting state35DomHandler.prototype.onreset = function(){36DomHandler.call(this, this._callback, this._options, this._elementCB);37};3839//Signals the handler that parsing is done40DomHandler.prototype.onend = function(){41if(this._done) return;42this._done = true;43this._parser = null;44this._handleCallback(null);45};4647DomHandler.prototype._handleCallback =48DomHandler.prototype.onerror = function(error){49if(typeof this._callback === "function"){50this._callback(error, this.dom);51} else {52if(error) throw error;53}54};5556DomHandler.prototype.onclosetag = function(){57//if(this._tagStack.pop().name !== name) this._handleCallback(Error("Tagname didn't match!"));58var elem = this._tagStack.pop();59if(this._elementCB) this._elementCB(elem);60};6162DomHandler.prototype._addDomElement = function(element){63var parent = this._tagStack[this._tagStack.length - 1];64var siblings = parent ? parent.children : this.dom;65var previousSibling = siblings[siblings.length - 1];6667element.next = null;6869if(this._options.withStartIndices){70element.startIndex = this._parser.startIndex;71}7273if (this._options.withDomLvl1) {74element.__proto__ = element.type === "tag" ? ElementPrototype : NodePrototype;75}7677if(previousSibling){78element.prev = previousSibling;79previousSibling.next = element;80} else {81element.prev = null;82}8384siblings.push(element);85element.parent = parent || null;86};8788DomHandler.prototype.onopentag = function(name, attribs){89var element = {90type: name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag,91name: name,92attribs: attribs,93children: []94};9596this._addDomElement(element);9798this._tagStack.push(element);99};100101DomHandler.prototype.ontext = function(data){102//the ignoreWhitespace is officially dropped, but for now,103//it's an alias for normalizeWhitespace104var normalize = this._options.normalizeWhitespace || this._options.ignoreWhitespace;105106var lastTag;107108if(!this._tagStack.length && this.dom.length && (lastTag = this.dom[this.dom.length-1]).type === ElementType.Text){109if(normalize){110lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");111} else {112lastTag.data += data;113}114} else {115if(116this._tagStack.length &&117(lastTag = this._tagStack[this._tagStack.length - 1]) &&118(lastTag = lastTag.children[lastTag.children.length - 1]) &&119lastTag.type === ElementType.Text120){121if(normalize){122lastTag.data = (lastTag.data + data).replace(re_whitespace, " ");123} else {124lastTag.data += data;125}126} else {127if(normalize){128data = data.replace(re_whitespace, " ");129}130131this._addDomElement({132data: data,133type: ElementType.Text134});135}136}137};138139DomHandler.prototype.oncomment = function(data){140var lastTag = this._tagStack[this._tagStack.length - 1];141142if(lastTag && lastTag.type === ElementType.Comment){143lastTag.data += data;144return;145}146147var element = {148data: data,149type: ElementType.Comment150};151152this._addDomElement(element);153this._tagStack.push(element);154};155156DomHandler.prototype.oncdatastart = function(){157var element = {158children: [{159data: "",160type: ElementType.Text161}],162type: ElementType.CDATA163};164165this._addDomElement(element);166this._tagStack.push(element);167};168169DomHandler.prototype.oncommentend = DomHandler.prototype.oncdataend = function(){170this._tagStack.pop();171};172173DomHandler.prototype.onprocessinginstruction = function(name, data){174this._addDomElement({175name: name,176data: data,177type: ElementType.Directive178});179};180181module.exports = DomHandler;182183184