From f118d9861e049fbccdbace4a570f6a2f489555c5 Mon Sep 17 00:00:00 2001 From: Ivan Voischev Date: Sun, 18 Aug 2019 16:52:01 +0300 Subject: [PATCH] perf: extra performance --- lib/index.js | 149 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 62 deletions(-) diff --git a/lib/index.js b/lib/index.js index 46903cd..308e2c5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -45,15 +45,60 @@ function render (tree, options) { */ options = options || {} - var singleTags = SINGLE_TAGS.concat(options.singleTags || []) + var singleTags = options.singleTags ? SINGLE_TAGS.concat(options.singleTags) : SINGLE_TAGS var singleRegExp = singleTags.filter(function (tag) { - return tag instanceof RegExp ? tag : false + return tag instanceof RegExp }) var closingSingleTag = options.closingSingleTag return html(tree) + /** @private */ + function isSingleTag (tag) { + if (singleRegExp.length !== 0) { + for (var i = 0; i < singleRegExp.length; i++) { + return singleRegExp[i].test(tag) + } + } + + if (singleTags.indexOf(tag) === -1) { + return false + } + + return true + } + + /** @private */ + function attrs (obj) { + var attr = '' + + for (var key in obj) { + if (typeof obj[key] === 'string') { + attr += ' ' + key + '="' + obj[key].replace(/"/g, '"') + '"' + } else if (obj[key] === true) { + attr += ' ' + key + } else if (typeof obj[key] === 'number') { + attr += ' ' + key + '="' + obj[key] + '"' + } + } + + return attr + } + + /** @private */ + function traverse (tree, cb) { + if (Array.isArray(tree)) { + for (var i = 0, length = tree.length; i < length; i++) { + traverse(cb(tree[i]), cb) + } + } else if (typeof tree === 'object' && tree.hasOwnProperty('content')) { + traverse(tree.content, cb) + } + + return tree + } + /** * HTML Stringifier * @@ -64,21 +109,17 @@ function render (tree, options) { function html (tree) { var result = '' - traverse([].concat(tree), function (node) { - if (!node) return - - if (typeof node === 'string' || typeof node === 'number') { - result += node + tree = Array.isArray(tree) ? tree : [tree] + traverse(tree, function (node) { + // undefined, null, '', [], NaN + if (node === undefined || + node === null || + node.length === 0 || + Number.isNaN(node)) { return } - if (typeof node.tag === 'boolean' && !node.tag) { - typeof node.content !== 'object' && (result += node.content) - - return node.content - } - // treat as new root tree if node is an array if (Array.isArray(node)) { result += html(node) @@ -86,9 +127,24 @@ function render (tree, options) { return } + if (typeof node === 'string' || typeof node === 'number') { + result += node + + return + } + + // skip node + if (node.tag === false) { + if (typeof node.content === 'string' || typeof node.content === 'number') { + result += node.content + } + + return node.content + } + var tag = node.tag || 'div' - if (isSingleTag(tag, singleTags, singleRegExp)) { + if (isSingleTag(tag)) { result += '<' + tag + attrs(node.attrs) switch (closingSingleTag) { @@ -104,9 +160,23 @@ function render (tree, options) { result += '>' } - result += node.content ? html(node.content) : '' + if (node.hasOwnProperty('content')) { + return node.content + } } else { - result += '<' + tag + (node.attrs ? attrs(node.attrs) : '') + '>' + (node.content ? html(node.content) : '') + '' + result += '<' + tag + + if (node.attrs) { + result += attrs(node.attrs) + } + + result += '>' + + if (node.hasOwnProperty('content')) { + result += html(node.content) + } + + result += '' } }) @@ -117,52 +187,7 @@ function render (tree, options) { /** * @module posthtml-render * - * @version 1.0.7 + * @version 1.1.5 * @license MIT */ module.exports = render - -/** @private */ -function attrs (obj) { - var attr = '' - - for (var key in obj) { - if (typeof obj[key] === 'boolean' && obj[key]) { - attr += ' ' + key - } else if (typeof obj[key] === 'number') { - attr += ' ' + key + '="' + obj[key] + '"' - } else if (typeof obj[key] === 'string') { - attr += ' ' + key + '="' + obj[key].replace(/"/g, '"') + '"' - } - } - - return attr -} - -/** @private */ -function traverse (tree, cb) { - if (Array.isArray(tree)) { - for (var i = 0, length = tree.length; i < length; i++) { - traverse(cb(tree[i]), cb) - } - } else if (typeof tree === 'object' && tree.hasOwnProperty('content')) { - traverse(tree.content, cb) - } - - return tree -} - -/** @private */ -function isSingleTag (tag, singleTags, singleRegExp) { - if (singleRegExp.length) { - for (var i = 0; i < singleRegExp.length; i++) { - return !!tag.match(singleRegExp[i]) - } - } - - if (singleTags.indexOf(tag) === -1) { - return false - } - - return true -}