UNPKG

@desertnet/html-parser

Version:

HTML parser and non-strict validator

244 lines (189 loc) 14.4 kB
"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==