diff options
Diffstat (limited to 'tools/eslint/node_modules/parse5/lib/serializer/index.js')
-rw-r--r-- | tools/eslint/node_modules/parse5/lib/serializer/index.js | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/tools/eslint/node_modules/parse5/lib/serializer/index.js b/tools/eslint/node_modules/parse5/lib/serializer/index.js new file mode 100644 index 00000000000..4c0d8855f34 --- /dev/null +++ b/tools/eslint/node_modules/parse5/lib/serializer/index.js @@ -0,0 +1,180 @@ +'use strict'; + +var defaultTreeAdapter = require('../tree_adapters/default'), + doctype = require('../common/doctype'), + mergeOptions = require('../common/merge_options'), + HTML = require('../common/html'); + +//Aliases +var $ = HTML.TAG_NAMES, + NS = HTML.NAMESPACES; + +//Default serializer options +/** + * @typedef {Object} SerializerOptions + * + * @property {TreeAdapter} [treeAdapter=parse5.treeAdapters.default] - Specifies input tree format. + */ +var DEFAULT_OPTIONS = { + treeAdapter: defaultTreeAdapter +}; + +//Escaping regexes +var AMP_REGEX = /&/g, + NBSP_REGEX = /\u00a0/g, + DOUBLE_QUOTE_REGEX = /"/g, + LT_REGEX = /</g, + GT_REGEX = />/g; + +//Serializer +var Serializer = module.exports = function (node, options) { + this.options = mergeOptions(DEFAULT_OPTIONS, options); + this.treeAdapter = this.options.treeAdapter; + + this.html = ''; + this.startNode = node; +}; + +// NOTE: exported as static method for the testing purposes +Serializer.escapeString = function (str, attrMode) { + str = str + .replace(AMP_REGEX, '&') + .replace(NBSP_REGEX, ' '); + + if (attrMode) + str = str.replace(DOUBLE_QUOTE_REGEX, '"'); + + else { + str = str + .replace(LT_REGEX, '<') + .replace(GT_REGEX, '>'); + } + + return str; +}; + + +//API +Serializer.prototype.serialize = function () { + this._serializeChildNodes(this.startNode); + + return this.html; +}; + + +//Internals +Serializer.prototype._serializeChildNodes = function (parentNode) { + var childNodes = this.treeAdapter.getChildNodes(parentNode); + + if (childNodes) { + for (var i = 0, cnLength = childNodes.length; i < cnLength; i++) { + var currentNode = childNodes[i]; + + if (this.treeAdapter.isElementNode(currentNode)) + this._serializeElement(currentNode); + + else if (this.treeAdapter.isTextNode(currentNode)) + this._serializeTextNode(currentNode); + + else if (this.treeAdapter.isCommentNode(currentNode)) + this._serializeCommentNode(currentNode); + + else if (this.treeAdapter.isDocumentTypeNode(currentNode)) + this._serializeDocumentTypeNode(currentNode); + } + } +}; + +Serializer.prototype._serializeElement = function (node) { + var tn = this.treeAdapter.getTagName(node), + ns = this.treeAdapter.getNamespaceURI(node); + + this.html += '<' + tn; + this._serializeAttributes(node); + this.html += '>'; + + if (tn !== $.AREA && tn !== $.BASE && tn !== $.BASEFONT && tn !== $.BGSOUND && tn !== $.BR && tn !== $.BR && + tn !== $.COL && tn !== $.EMBED && tn !== $.FRAME && tn !== $.HR && tn !== $.IMG && tn !== $.INPUT && + tn !== $.KEYGEN && tn !== $.LINK && tn !== $.MENUITEM && tn !== $.META && tn !== $.PARAM && tn !== $.SOURCE && + tn !== $.TRACK && tn !== $.WBR) { + + if (tn === $.PRE || tn === $.TEXTAREA || tn === $.LISTING) { + var firstChild = this.treeAdapter.getFirstChild(node); + + if (firstChild && this.treeAdapter.isTextNode(firstChild)) { + var content = this.treeAdapter.getTextNodeContent(firstChild); + + if (content[0] === '\n') + this.html += '\n'; + } + } + + var childNodesHolder = tn === $.TEMPLATE && ns === NS.HTML ? + this.treeAdapter.getTemplateContent(node) : + node; + + this._serializeChildNodes(childNodesHolder); + this.html += '</' + tn + '>'; + } +}; + +Serializer.prototype._serializeAttributes = function (node) { + var attrs = this.treeAdapter.getAttrList(node); + + for (var i = 0, attrsLength = attrs.length; i < attrsLength; i++) { + var attr = attrs[i], + value = Serializer.escapeString(attr.value, true); + + this.html += ' '; + + if (!attr.namespace) + this.html += attr.name; + + else if (attr.namespace === NS.XML) + this.html += 'xml:' + attr.name; + + else if (attr.namespace === NS.XMLNS) { + if (attr.name !== 'xmlns') + this.html += 'xmlns:'; + + this.html += attr.name; + } + + else if (attr.namespace === NS.XLINK) + this.html += 'xlink:' + attr.name; + + else + this.html += attr.namespace + ':' + attr.name; + + this.html += '="' + value + '"'; + } +}; + +Serializer.prototype._serializeTextNode = function (node) { + var content = this.treeAdapter.getTextNodeContent(node), + parent = this.treeAdapter.getParentNode(node), + parentTn = void 0; + + if (parent && this.treeAdapter.isElementNode(parent)) + parentTn = this.treeAdapter.getTagName(parent); + + if (parentTn === $.STYLE || parentTn === $.SCRIPT || parentTn === $.XMP || parentTn === $.IFRAME || + parentTn === $.NOEMBED || parentTn === $.NOFRAMES || parentTn === $.PLAINTEXT || parentTn === $.NOSCRIPT) + + this.html += content; + + else + this.html += Serializer.escapeString(content, false); +}; + +Serializer.prototype._serializeCommentNode = function (node) { + this.html += '<!--' + this.treeAdapter.getCommentNodeContent(node) + '-->'; +}; + +Serializer.prototype._serializeDocumentTypeNode = function (node) { + var name = this.treeAdapter.getDocumentTypeNodeName(node), + publicId = this.treeAdapter.getDocumentTypeNodePublicId(node), + systemId = this.treeAdapter.getDocumentTypeNodeSystemId(node); + + this.html += '<' + doctype.serializeContent(name, publicId, systemId) + '>'; +}; |