智能照明系统APP-本地串口
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
LightingSystemApp-serial/.svn/pristine/08/0893f45313b3ac8441ca606e2ee...

226 lines
5.4 KiB

3 years ago
/**
* @file domhandler
* @author https://github.com/fb55/domhandler
* @modify tanghao03 hiby
* @date 2018/5/17
*/
var ElementType = require('domelementtype');
var re_whitespace = /\s+/g;
var NodePrototype = require('./lib/node');
var ElementPrototype = require('./lib/element');
function DomHandler(callback, options, elementCB) {
if (typeof callback === 'object') {
elementCB = options;
options = callback;
callback = null;
} else if (typeof options === 'function') {
elementCB = options;
options = defaultOpts;
}
this._callback = callback;
this._options = options || defaultOpts;
this._elementCB = elementCB;
this.dom = [];
this._done = false;
this._tagStack = [];
this._parser = this._parser || null;
}
//default options
var defaultOpts = {
normalizeWhitespace: false, //Replace all whitespace with single spaces
withStartIndices: false, //Add startIndex properties to nodes
withEndIndices: false, //Add endIndex properties to nodes
};
DomHandler.prototype.onparserinit = function (parser) {
this._parser = parser;
};
//Resets the handler back to starting state
DomHandler.prototype.onreset = function () {
DomHandler.call(this, this._callback, this._options, this._elementCB);
};
//Signals the handler that parsing is done
DomHandler.prototype.onend = function () {
if (this._done) return;
this._done = true;
this._parser = null;
this._handleCallback(null);
};
DomHandler.prototype._handleCallback =
DomHandler.prototype.onerror = function (error) {
if (typeof this._callback === 'function') {
this._callback(error, this.dom);
} else {
if (error) throw error;
}
};
DomHandler.prototype.onclosetag = function (name, isSelfClose) {
//if(this._tagStack.pop().name !== name) this._handleCallback(Error('Tagname didn't match!'));
var elem = this._tagStack.pop();
elem.selfclose = !!isSelfClose;
if (this._options.withEndIndices && elem) {
elem.endIndex = this._parser.endIndex;
}
if (this._elementCB) this._elementCB(elem);
};
DomHandler.prototype._createDomElement = function (properties) {
if (!this._options.withDomLvl1) return properties;
var element;
if (properties.type === 'tag') {
element = Object.create(ElementPrototype);
} else {
element = Object.create(NodePrototype);
}
for (var key in properties) {
if (properties.hasOwnProperty(key)) {
element[key] = properties[key];
}
}
return element;
};
DomHandler.prototype._addDomElement = function (element) {
var parent = this._tagStack[this._tagStack.length - 1];
var siblings = parent ? parent.children : this.dom;
var previousSibling = siblings[siblings.length - 1];
// element.next = null;
if (this._options.withStartIndices) {
element.startIndex = this._parser.startIndex;
}
if (this._options.withEndIndices) {
element.endIndex = this._parser.endIndex;
}
// if(previousSibling){
// element.prev = previousSibling;
// previousSibling.next = element;
// } else {
// element.prev = null;
// }
siblings.push(element);
// element.parent = parent || null;
};
DomHandler.prototype.onopentag = function (name, attribs, singleQuoteAttribs) {
var properties = {
type: name === 'script' ? ElementType.Script : name === 'style' ? ElementType.Style : ElementType.Tag,
name: name,
attribs: attribs,
children: []
};
if (singleQuoteAttribs) {
properties.singleQuoteAttribs = singleQuoteAttribs;
}
var element = this._createDomElement(properties);
this._addDomElement(element);
this._tagStack.push(element);
};
DomHandler.prototype.ontext = function (data) {
//the ignoreWhitespace is officially dropped, but for now,
//it's an alias for normalizeWhitespace
var normalize = this._options.normalizeWhitespace || this._options.ignoreWhitespace;
var lastTag;
if (!this._tagStack.length && this.dom.length && (lastTag = this.dom[this.dom.length - 1]).type === ElementType.Text) {
if (normalize) {
lastTag.data = (lastTag.data + data).replace(re_whitespace, ' ');
} else {
lastTag.data += data;
}
} else {
if (
this._tagStack.length &&
(lastTag = this._tagStack[this._tagStack.length - 1]) &&
(lastTag = lastTag.children[lastTag.children.length - 1]) &&
lastTag.type === ElementType.Text
) {
if (normalize) {
lastTag.data = (lastTag.data + data).replace(re_whitespace, ' ');
} else {
lastTag.data += data;
}
} else {
if (normalize) {
data = data.replace(re_whitespace, ' ');
}
var element = this._createDomElement({
data: data,
type: ElementType.Text
});
this._addDomElement(element);
}
}
};
DomHandler.prototype.oncomment = function (data) {
var lastTag = this._tagStack[this._tagStack.length - 1];
if (lastTag && lastTag.type === ElementType.Comment) {
lastTag.data += data;
return;
}
var properties = {
data: data,
type: ElementType.Comment
};
var element = this._createDomElement(properties);
this._addDomElement(element);
this._tagStack.push(element);
};
DomHandler.prototype.oncdatastart = function () {
var properties = {
children: [{
data: '',
type: ElementType.Text
}],
type: ElementType.CDATA
};
var element = this._createDomElement(properties);
this._addDomElement(element);
this._tagStack.push(element);
};
DomHandler.prototype.oncommentend = DomHandler.prototype.oncdataend = function () {
this._tagStack.pop();
};
DomHandler.prototype.onprocessinginstruction = function (name, data) {
var element = this._createDomElement({
name: name,
data: data,
type: ElementType.Directive
});
this._addDomElement(element);
};
module.exports = DomHandler;