Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 87 additions & 62 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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, '&quot;') + '"'
} 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
*
Expand All @@ -64,31 +109,42 @@ 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)

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) {
Expand All @@ -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) : '') + '</' + tag + '>'
result += '<' + tag

if (node.attrs) {
result += attrs(node.attrs)
}

result += '>'

if (node.hasOwnProperty('content')) {
result += html(node.content)
}

result += '</' + tag + '>'
}
})

Expand All @@ -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, '&quot;') + '"'
}
}

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
}