-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
120 lines (102 loc) · 4 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
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));
};
};
exports.params = params;
exports.parse = parse;
exports.partial = partial;
return exports;
}({}));