dummer.js
3.2 KB
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
var dummer, object, sanitizer,
__hasProp = {}.hasOwnProperty;
object = require('utila').object;
sanitizer = require('./sanitizer');
module.exports = dummer = {
toDom: function(o) {
if (!Array.isArray(o)) {
if (!object.isBareObject(o)) {
throw Error("toDom() only accepts arrays and bare objects as input");
}
}
o = sanitizer.sanitize(o);
return dummer._children(o);
},
_children: function(a, parent) {
var children, node, prev, v, _i, _len;
if (parent == null) {
parent = null;
}
children = [];
prev = null;
for (_i = 0, _len = a.length; _i < _len; _i++) {
v = a[_i];
if (typeof v === 'string') {
node = dummer._textNode(v);
} else {
node = dummer._objectToDom(v, parent);
node.prev = null;
node.next = null;
node.parent = parent;
if (prev != null) {
node.prev = prev;
prev.next = node;
}
prev = node;
}
children.push(node);
}
return children;
},
_objectToDom: function(o) {
var attribs, children, i, k, key, name, node, v, val, _ref;
i = 0;
for (k in o) {
if (!__hasProp.call(o, k)) continue;
v = o[k];
if (i > 0) {
throw Error("_objectToDom() only accepts an object with one key/value");
}
key = k;
val = v;
i++;
}
node = {};
if (typeof key !== 'string') {
throw Error("_objectToDom()'s key must be a string of tag name and classes");
}
if (typeof val === 'string') {
children = [dummer._textNode(val)];
} else if (Array.isArray(val)) {
children = dummer._children(val, node);
} else {
inspect(o);
throw Error("_objectToDom()'s key's value must only be a string or an array");
}
node.type = 'tag';
_ref = dummer._parseTag(key), name = _ref.name, attribs = _ref.attribs;
node.name = name;
node.attribs = attribs;
node.children = children;
return node;
},
_textNode: function(s) {
return {
type: 'text',
data: s
};
},
_nameRx: /^[a-zA-Z\-\_]{1}[a-zA-Z0-9\-\_]*$/,
_parseTag: function(k) {
var attribs, classes, cls, id, m, name, parts;
if (!k.match(/^[a-zA-Z0-9\#\-\_\.\[\]\"\'\=\,\s]+$/) || k.match(/^[0-9]+/)) {
throw Error("cannot parse tag `" + k + "`");
}
attribs = {};
parts = {
name: '',
attribs: attribs
};
if (m = k.match(/^([^\.#]+)/)) {
name = m[1];
if (!name.match(dummer._nameRx)) {
throw Error("tag name `" + name + "` is not valid");
}
parts.name = name;
k = k.substr(name.length, k.length);
}
if (m = k.match(/^#([a-zA-Z0-9\-]+)/)) {
id = m[1];
if (!id.match(dummer._nameRx)) {
throw Error("tag id `" + id + "` is not valid");
}
attribs.id = id;
k = k.substr(id.length + 1, k.length);
}
classes = [];
while (m = k.match(/\.([a-zA-Z0-9\-\_]+)/)) {
cls = m[1];
if (!cls.match(dummer._nameRx)) {
throw Error("tag class `" + cls + "` is not valid");
}
classes.push(cls);
k = k.replace('.' + cls, '');
}
if (classes.length) {
attribs["class"] = classes.join(" ");
}
return parts;
}
};