forked from WebReflection/tag-params
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
146 lines (125 loc) · 4.91 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
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
self.tagParams = (function (exports) {
'use strict';
/**
* @typedef {object} ParseResult an object with parsed results
* @property {string[]} template - the list of chunks around interpolations
* @property {string[]} values - interpolations as strings
*/
/**
* @typedef {[string[], ...any[]]} TagArguments an array to use as template
* literals tag arguments
*/
/**
* @callback Partial a callback that re-evaluate each time new data associated
* to the same template-like array.
* @param {object} [object] the optional data to evaluate as interpolated values
* @returns {TagArguments} an array to use as template literals tag arguments
*/
/**
* The default `transform` callback
* @param {string} value the interpolation value as string
*/
var noop = function noop(value) {
return value;
};
/**
* The default "null" fallback when no object is passed to the Partial.
*/
var fallback = Object.create(null);
/**
* Given a string and an optional object carrying references used through
* such string interpolation, returns an array that can be used within any
* template literal function tag.
* @param {string} content the string to parse/convert as template chunks
* @param {object} [object] the optional data to evaluate as interpolated values
* @returns {TagArguments} an array to use as template literals tag arguments
*/
var params = function params(content, object) {
return partial(content)(object);
};
/**
* Given a string and an optional function used to transform each value
* found as interpolated content, returns an object with a `template` and
* a `values` properties, as arrays, containing the template chunks,
* and all its interpolations as strings.
* @param {string} content the string to parse/convert as template chunks
* @param {function} [transform] the optional function to modify string values
* @returns {ParseResult} an object with `template` and `values` arrays.
*/
var parse = function parse(content, transform) {
var fn = transform || noop;
var template = [];
var values = [];
var length = content.length;
var i = 0;
while (i <= length) {
var open = content.indexOf('${', i);
if (-1 < open) {
template.push(content.slice(i, open));
open = i = open + 2;
var close = 1; // TODO: this *might* break if the interpolation has strings
// containing random `{}` chars ... but implementing
// a whole JS parser here doesn't seem worth it
// for such irrelevant edge-case ... or does it?
while (0 < close && i < length) {
var c = content[i++];
close += c === '{' ? 1 : c === '}' ? -1 : 0;
}
values.push(fn(content.slice(open, i - 1)));
} else {
template.push(content.slice(i));
i = length + 1;
}
}
return {
template: template,
values: values
};
};
/**
* Given a string and an optional function used to transform each value
* found as interpolated content, returns a callback that can be used to
* repeatedly generate new content from the same template array.
* @param {string} content the string to parse/convert as template chunks
* @param {function} [transform] the optional function to modify string values
* @returns {Partial} a function that accepts an optional object to generate
* new content, through the same template, each time.
*/
var partial = function partial(content, transform) {
var _parse = parse(content, transform),
template = _parse.template,
values = _parse.values;
var args = [template];
var rest = Function('return function(){with(arguments[0])return[' + values + ']}')();
return function (object) {
return args.concat(rest(object || fallback));
};
};
/**
* Create a template result
* @param {function} contentfn a function that has multiline comments to string.
* @param {function} [transform] the optional function to modify string values
* @param {function} [othereval] the optional function to eval the values
* @returns {ParseResult} a function that accepts an optional object to generate
* new content, through the same template, each time.
*/
var multiline = function multiline(contentfn, transform, othereval) {
var content = contentfn.toString().
replace(/^[^\/]+\/\*!?/, '').
replace(/\*\/[^\/]+$/, '');
var _parse = parse(content, transform),
template = _parse.template,
values = _parse.values;
var exec = othereval || contentfn;
values = exec("[" + values + "]");
return {
template: tempalte,
values: values
}
};
exports.params = params;
exports.parse = parse;
exports.partial = partial;
exports.multiline = multiline;
return exports;
}({}));