@desertnet/html-parser
Version:
HTML parser and non-strict validator
244 lines (189 loc) • 14.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _HTMLNode2 = require("./HTMLNode");
var _HTMLNode3 = _interopRequireDefault(_HTMLNode2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* @type {Object.<string,boolean>}
*/
var _voidTags = null;
/**
* HTML tag node.
*/
var TagNode = function (_HTMLNode) {
_inherits(TagNode, _HTMLNode);
function TagNode() {
_classCallCheck(this, TagNode);
/**
* @private
* @type {string}
*/
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(TagNode).call(this));
_this._tagName;
/**
* @private
* @type {Array.<AttrNode>?}
*/
_this._attributes = null;
/**
* @private
* @type {CloseTagNode?}
*/
_this._closeTag = null;
return _this;
}
/**
* @override
*/
_createClass(TagNode, [{
key: "hasRawtextContent",
/**
* @return {boolean}
*/
value: function hasRawtextContent() {
return !!this.tagName.match(/^(script|style|xmp)$/);
}
/**
* @override
*/
}, {
key: "appendChild",
value: function appendChild(child) {
var foundOurClosingTag = false;
if (child.type === _HTMLNode2.NodeType.CLOSETAG) {
var closingTag = /** @type {CloseTagNode} */child;
if (closingTag.tagName === this.tagName) {
this._closeTag = closingTag;
foundOurClosingTag = true;
}
}
if (!foundOurClosingTag) {
_get(Object.getPrototypeOf(TagNode.prototype), "appendChild", this).call(this, child);
}
return this;
}
/**
* @override
*/
}, {
key: "toString",
value: function toString() {
var inside = this._attributes ? " " + this._attributes.join(" ") : "";
var openTag = "<" + this.tagName + inside + ">";
var children = this.children ? this.children.join("") : "";
var closingTag = this.closingTag ? this.closingTag.toString() : "";
return openTag + children + closingTag;
}
/**
* @override
* @param {Foundation.Scanner.Token} token
*/
}, {
key: "addToken",
value: function addToken(token) {
_get(Object.getPrototypeOf(TagNode.prototype), "addToken", this).call(this, token);
if (token.type === "tagStart") {
this.tagName = token.value.replace(/^</, "");
}
}
/**
* @return {string}
*/
}, {
key: "addAttribute",
/**
* @param {AttrNode} attribute
* @return {TagNode}
*/
value: function addAttribute(attribute) {
if (!this._attributes) {
this._attributes = [];
}
this._attributes.push(attribute);
return this;
}
/**
* @return {Array.<AttrNode>}
*/
}, {
key: "type",
get: function get() {
return _HTMLNode2.NodeType.TAG;
}
/**
* @override
*/
}, {
key: "canHaveChildren",
get: function get() {
var result = true;
if (!_voidTags) {
var voidTagList = ["area", "col", "command", "keygen", "track", "wbr", "base", "link", "meta", "br", "hr", "img", "embed", "param", "source", "input"];
_voidTags = {};
voidTagList.forEach(function (voidTag) {
_voidTags[voidTag] = true;
});
}
if (_voidTags[this.tagName]) {
result = false;
}
return result;
}
}, {
key: "tagName",
get: function get() {
return this._tagName;
}
/**
* @param {string} name
*/
,
set: function set(name) {
this._tagName = name.toLowerCase();
}
}, {
key: "attributes",
get: function get() {
if (this._attributes) {
return this._attributes.slice(0);
} else {
return [];
}
}
/**
* @return {CloseTagNode?}
*/
}, {
key: "closingTag",
get: function get() {
return this._closeTag;
}
/**
* @override
*/
}, {
key: "errors",
get: function get() {
var errors = _get(Object.getPrototypeOf(TagNode.prototype), "errors", this);
var attrErrors = [];
this.attributes.forEach(function (attribute) {
attrErrors = attrErrors.concat(attribute.errors);
});
var closingTagErrors = [];
if (this.closingTag) {
closingTagErrors = this.closingTag.errors;
}
return attrErrors.concat(errors, closingTagErrors);
}
}]);
return TagNode;
}(_HTMLNode3.default);
exports.default = TagNode;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9IVE1MTm9kZS9UYWdOb2RlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7O0FBRUE7OztBQUdBLElBQUksWUFBWSxJQUFoQjs7QUFFQTs7OztJQUdxQixPOzs7QUFDbkIscUJBQWU7QUFBQTs7QUFHYjs7OztBQUhhOztBQU9iLFVBQUssUUFBTDs7QUFFQTs7OztBQUlBLFVBQUssV0FBTCxHQUFtQixJQUFuQjs7QUFFQTs7OztBQUlBLFVBQUssU0FBTCxHQUFpQixJQUFqQjtBQW5CYTtBQW9CZDs7QUFFRDs7Ozs7Ozs7O0FBNkJBOzs7d0NBR3FCO0FBQ25CLGFBQU8sQ0FBQyxDQUFFLEtBQUssT0FBTCxDQUFhLEtBQWIsQ0FBbUIsc0JBQW5CLENBQVY7QUFDRDs7QUFFRDs7Ozs7O2dDQUdhLEssRUFBTztBQUNsQixVQUFJLHFCQUFxQixLQUF6QjtBQUNBLFVBQUksTUFBTSxJQUFOLEtBQWUsb0JBQVMsUUFBNUIsRUFBc0M7QUFDcEMsWUFBSSxhQUFhLDJCQUE2QixLQUE5QztBQUNBLFlBQUksV0FBVyxPQUFYLEtBQXVCLEtBQUssT0FBaEMsRUFBeUM7QUFDdkMsZUFBSyxTQUFMLEdBQWlCLFVBQWpCO0FBQ0EsK0JBQXFCLElBQXJCO0FBQ0Q7QUFDRjs7QUFFRCxVQUFJLENBQUMsa0JBQUwsRUFBeUI7QUFDdkIsdUZBQWtCLEtBQWxCO0FBQ0Q7O0FBRUQsYUFBTyxJQUFQO0FBQ0Q7O0FBRUQ7Ozs7OzsrQkFHWTtBQUNWLFVBQUksU0FBUyxLQUFLLFdBQUwsR0FBbUIsTUFBTSxLQUFLLFdBQUwsQ0FBaUIsSUFBakIsQ0FBc0IsR0FBdEIsQ0FBekIsR0FBc0QsRUFBbkU7QUFDQSxVQUFJLFVBQVUsTUFBTSxLQUFLLE9BQVgsR0FBcUIsTUFBckIsR0FBOEIsR0FBNUM7QUFDQSxVQUFJLFdBQVcsS0FBSyxRQUFMLEdBQWdCLEtBQUssUUFBTCxDQUFjLElBQWQsQ0FBbUIsRUFBbkIsQ0FBaEIsR0FBeUMsRUFBeEQ7QUFDQSxVQUFJLGFBQWEsS0FBSyxVQUFMLEdBQWtCLEtBQUssVUFBTCxDQUFnQixRQUFoQixFQUFsQixHQUErQyxFQUFoRTtBQUNBLGFBQU8sVUFBVSxRQUFWLEdBQXFCLFVBQTVCO0FBQ0Q7O0FBRUQ7Ozs7Ozs7NkJBSVUsSyxFQUFPO0FBQ2Ysa0ZBQWUsS0FBZjs7QUFFQSxVQUFJLE1BQU0sSUFBTixLQUFlLFVBQW5CLEVBQStCO0FBQzdCLGFBQUssT0FBTCxHQUFlLE1BQU0sS0FBTixDQUFZLE9BQVosQ0FBb0IsSUFBcEIsRUFBMEIsRUFBMUIsQ0FBZjtBQUNEO0FBQ0Y7O0FBRUQ7Ozs7Ozs7O0FBY0E7Ozs7aUNBSWMsUyxFQUFXO0FBQ3ZCLFVBQUksQ0FBRSxLQUFLLFdBQVgsRUFBd0I7QUFDdEIsYUFBSyxXQUFMLEdBQW1CLEVBQW5CO0FBQ0Q7O0FBRUQsV0FBSyxXQUFMLENBQWlCLElBQWpCLENBQXNCLFNBQXRCOztBQUVBLGFBQU8sSUFBUDtBQUNEOztBQUVEOzs7Ozs7d0JBeEdZO0FBQUUsYUFBTyxvQkFBUyxHQUFoQjtBQUFxQjs7QUFFbkM7Ozs7Ozt3QkFHdUI7QUFDckIsVUFBSSxTQUFTLElBQWI7O0FBRUEsVUFBSSxDQUFDLFNBQUwsRUFBZ0I7QUFDZCxZQUFNLGNBQWMsQ0FDbEIsTUFEa0IsRUFDVixLQURVLEVBQ0gsU0FERyxFQUNRLFFBRFIsRUFDa0IsT0FEbEIsRUFDMkIsS0FEM0IsRUFFbEIsTUFGa0IsRUFFVixNQUZVLEVBRUYsTUFGRSxFQUVNLElBRk4sRUFFWSxJQUZaLEVBRWtCLEtBRmxCLEVBRXlCLE9BRnpCLEVBRWtDLE9BRmxDLEVBRTJDLFFBRjNDLEVBR2xCLE9BSGtCLENBQXBCOztBQU1BLG9CQUFZLEVBQVo7QUFDQSxvQkFBWSxPQUFaLENBQW9CLG1CQUFXO0FBQUUsb0JBQVUsT0FBVixJQUFxQixJQUFyQjtBQUEyQixTQUE1RDtBQUNEOztBQUVELFVBQUksVUFBVSxLQUFLLE9BQWYsQ0FBSixFQUE2QjtBQUMzQixpQkFBUyxLQUFUO0FBQ0Q7O0FBRUQsYUFBTyxNQUFQO0FBQ0Q7Ozt3QkF1RGM7QUFDYixhQUFPLEtBQUssUUFBWjtBQUNEOztBQUVEOzs7O3NCQUdhLEksRUFBTTtBQUNqQixXQUFLLFFBQUwsR0FBZ0IsS0FBSyxXQUFMLEVBQWhCO0FBQ0Q7Ozt3QkFtQmlCO0FBQ2hCLFVBQUksS0FBSyxXQUFULEVBQXNCO0FBQ3BCLGVBQU8sS0FBSyxXQUFMLENBQWlCLEtBQWpCLENBQXVCLENBQXZCLENBQVA7QUFDRCxPQUZELE1BR0s7QUFDSCxlQUFPLEVBQVA7QUFDRDtBQUNGOztBQUVEOzs7Ozs7d0JBR2tCO0FBQ2hCLGFBQU8sS0FBSyxTQUFaO0FBQ0Q7O0FBRUQ7Ozs7Ozt3QkFHYztBQUNaLFVBQUksdUVBQUo7O0FBRUEsVUFBSSxhQUFhLEVBQWpCO0FBQ0EsV0FBSyxVQUFMLENBQWdCLE9BQWhCLENBQXdCLHFCQUFhO0FBQ25DLHFCQUFhLFdBQVcsTUFBWCxDQUFrQixVQUFVLE1BQTVCLENBQWI7QUFDRCxPQUZEOztBQUlBLFVBQUksbUJBQW1CLEVBQXZCO0FBQ0EsVUFBSSxLQUFLLFVBQVQsRUFBcUI7QUFDbkIsMkJBQW1CLEtBQUssVUFBTCxDQUFnQixNQUFuQztBQUNEOztBQUVELGFBQU8sV0FBVyxNQUFYLENBQWtCLE1BQWxCLEVBQTBCLGdCQUExQixDQUFQO0FBQ0Q7Ozs7OztrQkF0S2tCLE8iLCJmaWxlIjoiVGFnTm9kZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBIVE1MTm9kZSwge05vZGVUeXBlfSBmcm9tICcuL0hUTUxOb2RlJ1xuXG4vKipcbiAqIEB0eXBlIHtPYmplY3QuPHN0cmluZyxib29sZWFuPn1cbiAqL1xubGV0IF92b2lkVGFncyA9IG51bGw7XG5cbi8qKlxuICogSFRNTCB0YWcgbm9kZS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGFnTm9kZSBleHRlbmRzIEhUTUxOb2RlIHtcbiAgY29uc3RydWN0b3IgKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5fdGFnTmFtZTtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5LjxBdHRyTm9kZT4/fVxuICAgICAqL1xuICAgIHRoaXMuX2F0dHJpYnV0ZXMgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Q2xvc2VUYWdOb2RlP31cbiAgICAgKi9cbiAgICB0aGlzLl9jbG9zZVRhZyA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogQG92ZXJyaWRlXG4gICAqL1xuICBnZXQgdHlwZSAoKSB7IHJldHVybiBOb2RlVHlwZS5UQUcgfVxuXG4gIC8qKlxuICAgKiBAb3ZlcnJpZGVcbiAgICovXG4gIGdldCBjYW5IYXZlQ2hpbGRyZW4gKCkge1xuICAgIHZhciByZXN1bHQgPSB0cnVlO1xuXG4gICAgaWYgKCFfdm9pZFRhZ3MpIHtcbiAgICAgIGNvbnN0IHZvaWRUYWdMaXN0ID0gW1xuICAgICAgICBcImFyZWFcIiwgXCJjb2xcIiwgXCJjb21tYW5kXCIsIFwia2V5Z2VuXCIsIFwidHJhY2tcIiwgXCJ3YnJcIixcbiAgICAgICAgXCJiYXNlXCIsIFwibGlua1wiLCBcIm1ldGFcIiwgXCJiclwiLCBcImhyXCIsIFwiaW1nXCIsIFwiZW1iZWRcIiwgXCJwYXJhbVwiLCBcInNvdXJjZVwiLFxuICAgICAgICBcImlucHV0XCJcbiAgICAgIF07XG5cbiAgICAgIF92b2lkVGFncyA9IHt9O1xuICAgICAgdm9pZFRhZ0xpc3QuZm9yRWFjaCh2b2lkVGFnID0+IHsgX3ZvaWRUYWdzW3ZvaWRUYWddID0gdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAoX3ZvaWRUYWdzW3RoaXMudGFnTmFtZV0pIHtcbiAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGhhc1Jhd3RleHRDb250ZW50ICgpIHtcbiAgICByZXR1cm4gISEgdGhpcy50YWdOYW1lLm1hdGNoKC9eKHNjcmlwdHxzdHlsZXx4bXApJC8pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBvdmVycmlkZVxuICAgKi9cbiAgYXBwZW5kQ2hpbGQgKGNoaWxkKSB7XG4gICAgdmFyIGZvdW5kT3VyQ2xvc2luZ1RhZyA9IGZhbHNlO1xuICAgIGlmIChjaGlsZC50eXBlID09PSBOb2RlVHlwZS5DTE9TRVRBRykge1xuICAgICAgdmFyIGNsb3NpbmdUYWcgPSAvKiogQHR5cGUge0Nsb3NlVGFnTm9kZX0gKi8gKGNoaWxkKTtcbiAgICAgIGlmIChjbG9zaW5nVGFnLnRhZ05hbWUgPT09IHRoaXMudGFnTmFtZSkge1xuICAgICAgICB0aGlzLl9jbG9zZVRhZyA9IGNsb3NpbmdUYWc7XG4gICAgICAgIGZvdW5kT3VyQ2xvc2luZ1RhZyA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFmb3VuZE91ckNsb3NpbmdUYWcpIHtcbiAgICAgIHN1cGVyLmFwcGVuZENoaWxkKGNoaWxkKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAb3ZlcnJpZGVcbiAgICovXG4gIHRvU3RyaW5nICgpIHtcbiAgICB2YXIgaW5zaWRlID0gdGhpcy5fYXR0cmlidXRlcyA/IFwiIFwiICsgdGhpcy5fYXR0cmlidXRlcy5qb2luKFwiIFwiKSA6IFwiXCI7XG4gICAgdmFyIG9wZW5UYWcgPSBcIjxcIiArIHRoaXMudGFnTmFtZSArIGluc2lkZSArIFwiPlwiO1xuICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW4gPyB0aGlzLmNoaWxkcmVuLmpvaW4oXCJcIikgOiBcIlwiO1xuICAgIHZhciBjbG9zaW5nVGFnID0gdGhpcy5jbG9zaW5nVGFnID8gdGhpcy5jbG9zaW5nVGFnLnRvU3RyaW5nKCkgOiBcIlwiO1xuICAgIHJldHVybiBvcGVuVGFnICsgY2hpbGRyZW4gKyBjbG9zaW5nVGFnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAcGFyYW0ge0ZvdW5kYXRpb24uU2Nhbm5lci5Ub2tlbn0gdG9rZW5cbiAgICovXG4gIGFkZFRva2VuICh0b2tlbikge1xuICAgIHN1cGVyLmFkZFRva2VuKHRva2VuKTtcblxuICAgIGlmICh0b2tlbi50eXBlID09PSBcInRhZ1N0YXJ0XCIpIHtcbiAgICAgIHRoaXMudGFnTmFtZSA9IHRva2VuLnZhbHVlLnJlcGxhY2UoL148LywgXCJcIik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICovXG4gIGdldCB0YWdOYW1lICgpIHtcbiAgICByZXR1cm4gdGhpcy5fdGFnTmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgKi9cbiAgc2V0IHRhZ05hbWUgKG5hbWUpIHtcbiAgICB0aGlzLl90YWdOYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7QXR0ck5vZGV9IGF0dHJpYnV0ZVxuICAgKiBAcmV0dXJuIHtUYWdOb2RlfVxuICAgKi9cbiAgYWRkQXR0cmlidXRlIChhdHRyaWJ1dGUpIHtcbiAgICBpZiAoISB0aGlzLl9hdHRyaWJ1dGVzKSB7XG4gICAgICB0aGlzLl9hdHRyaWJ1dGVzID0gW107XG4gICAgfVxuXG4gICAgdGhpcy5fYXR0cmlidXRlcy5wdXNoKGF0dHJpYnV0ZSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheS48QXR0ck5vZGU+fVxuICAgKi9cbiAgZ2V0IGF0dHJpYnV0ZXMgKCkge1xuICAgIGlmICh0aGlzLl9hdHRyaWJ1dGVzKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYXR0cmlidXRlcy5zbGljZSgwKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0Nsb3NlVGFnTm9kZT99XG4gICAqL1xuICBnZXQgY2xvc2luZ1RhZyAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Nsb3NlVGFnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBvdmVycmlkZVxuICAgKi9cbiAgZ2V0IGVycm9ycyAoKSB7XG4gICAgdmFyIGVycm9ycyA9IHN1cGVyLmVycm9ycztcblxuICAgIHZhciBhdHRyRXJyb3JzID0gW107XG4gICAgdGhpcy5hdHRyaWJ1dGVzLmZvckVhY2goYXR0cmlidXRlID0+IHtcbiAgICAgIGF0dHJFcnJvcnMgPSBhdHRyRXJyb3JzLmNvbmNhdChhdHRyaWJ1dGUuZXJyb3JzKTtcbiAgICB9KTtcblxuICAgIHZhciBjbG9zaW5nVGFnRXJyb3JzID0gW107XG4gICAgaWYgKHRoaXMuY2xvc2luZ1RhZykge1xuICAgICAgY2xvc2luZ1RhZ0Vycm9ycyA9IHRoaXMuY2xvc2luZ1RhZy5lcnJvcnM7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF0dHJFcnJvcnMuY29uY2F0KGVycm9ycywgY2xvc2luZ1RhZ0Vycm9ycyk7XG4gIH1cbn1cbiJdfQ==