forked from dominictarr/h
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
94 lines (84 loc) · 2.48 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
var escape = require('html-escape')
var cssesc = require('cssesc')
function isString(s) {
return 'string' === typeof s
}
var rx_tagname = /^[a-zA-Z]+(?:[\-a-zA-Z0-9])*$/
var rx_tagname = /^[a-zA-Z]+(?:[\-a-zA-Z0-9])*$/
var rx_tagname_with_class = /^[a-zA-Z]+(?:[\-a-zA-Z0-9])*([\.#][^\s#.]+)+$/
function isName(t) {
return isString(t) && rx_tagname.test(t)
}
function isNameWithClass (n) {
return isString(n) && rx_tagname_with_class.test(n)
}
var isArray = Array.isArray
function isObject (o) {
return o && 'object' == typeof o && !isArray(o)
}
module.exports = function toHTML (ary, options = {}) {
if(isString(ary)) return escape(ary)
var str = '', innerHTML
if(isArray(ary) && ary.every(isArray)) {
return ary.map(function(elem){return toHTML(elem, options)}).join('')
}
if(isArray(ary)) {
var i = 1, tag, attrs, innerHTML
if(isName(ary[0]))
var tag = ary[0]
else if(isNameWithClass(ary[0])) {
var parts = ary[0].split(/([\.#])/g)
var tag = parts.shift()
var id = '', _class = ''
for(var j = 0; j < parts.length; j+=2)
if(parts[j] === '.')
_class = (_class +' '+cssesc(parts[j+1], {isIdentifier: true})).trim()
else if(parts[j] === '#')
id = cssesc(parts[j+1], {isIdentifier: true})
}
else
throw new Error('expected tag name, got:'+ary[0])
if(isObject(ary[1])) {
attrs = ary[1]
if(attrs.className) {
_class = attrs.className
delete attrs.className
}
i = 2
}
str = '<'+tag
if(_class) str += ' class="'+_class+'"'
if(id) str += ' id="'+id+'"'
if(options.verbose === true) {
console.log("ARY", isObject(ary[1]), ary, attrs, innerHTML)
}
if(!attrs) str += '>'
else if(attrs.innerHTML) {
str +='>'
innerHTML = attrs.innerHTML
delete attrs.innerHTML
}
else {
for(var k in attrs) {
if(!isName(k)) throw new Error('attribute key not a name:'+k)
if(attrs[k] === true)
str += ' ' + k
else if(attrs[k] != null)
str += ' ' + k + '="' + escape(attrs[k]) + '"'
}
str += '>'
}
if(innerHTML)
str += innerHTML //CAUTION: explicitly not escaped.
else
for(;i < ary.length; i++) {
if(isArray(ary[i]) && isArray(ary[i][0]))
str += ary[i].map(function(elem){return toHTML(elem, options)}).join('')
else
str += toHTML(ary[i], options)
}
str += '</'+tag+'>'
return str
}
else return ''
}