-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.js
85 lines (82 loc) · 2.18 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
/*! (C) 2017-2018 Andrea Giammarchi - MIT Style License */
function template(fn, $str, $object) {'use strict';
// reset cache every 32M
if (33554432 < template.$) {
template._ = {};
template.$ = 0;
}
var
hasTransformer = typeof fn === 'function',
str = hasTransformer ? $str : fn,
object = hasTransformer ? $object : $str,
_ = template._,
known = _.hasOwnProperty(str),
parsed = known ? _[str] : (_[str] = template.parse(str)),
chunks = parsed.chunks,
values = parsed.values,
strings
;
// add str length only if not known
if (!known)
template.$ += str.length;
if (hasTransformer) {
str = 'function' + (Math.random() * 1e5 | 0);
strings = [
str,
'with(this)return ' + str + '([' + chunks + ']' + (
values.length ? (',' + values.join(',')) : ''
) + ')'
];
} else {
strings = chunks.slice(0, 1);
for (var i = 1, length = chunks.length; i < length; i++)
strings.push(values[i - 1], chunks[i]);
strings = ['with(this)return ' + strings.join('+')];
}
return Function.apply(null, strings).apply(
object,
hasTransformer ? [fn] : []
);
}
template._ = {};
template.$ = 0;
template.asMethod = function (fn, object) {'use strict';
return typeof fn === 'function' ?
template(fn, this, object) :
template(this, fn);
};
template.parse = function (str) {
var
stringify = JSON.stringify,
open = 0, close = 0, counter = 0,
i = 0, length = str.length,
chunks = i < length ? [] : ['""'],
values = []
;
while (i < length) {
open = str.indexOf('${', i);
if (-1 < open) {
chunks.push(stringify(str.slice(i, open)));
open += 2;
close = open;
counter = 1;
while (close < length) {
switch (str.charAt(close++)) {
case '}': --counter; break;
case '{': ++counter; break;
}
if (counter < 1) {
values.push('(' + str.slice(open, close - 1) + ')');
break;
}
}
i = close;
} else {
chunks.push(stringify(str.slice(i)));
i = length;
}
}
if (chunks.length === values.length)
chunks.push('""');
return {chunks: chunks, values: values};
};