bfdotcom-theme 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/_includes/comments.html +35 -0
- data/_includes/head.html +22 -0
- data/_layouts/default.html +1 -0
- data/_layouts/post.html +4 -0
- data/assets/auth/signin.html +10 -0
- data/assets/scripts/CryptoJS/components/enc-base64.js +109 -0
- data/assets/scripts/CryptoJS/components/hmac.js +131 -0
- data/assets/scripts/CryptoJS/rollups/hmac-sha256.js +18 -0
- data/assets/scripts/CryptoJS/rollups/sha256.js +16 -0
- data/assets/scripts/apiGatewayCore/apiGatewayClient.js +53 -0
- data/assets/scripts/apiGatewayCore/sigV4Client.js +219 -0
- data/assets/scripts/apiGatewayCore/simpleHttpClient.js +81 -0
- data/assets/scripts/apiGatewayCore/utils.js +80 -0
- data/assets/scripts/axios/dist/axios.standalone.js +1089 -0
- data/assets/scripts/core.js +93 -0
- data/assets/scripts/signin.js +16 -0
- data/assets/scripts/url-template/url-template.js +438 -0
- metadata +16 -2
@@ -0,0 +1,93 @@
|
|
1
|
+
function startLogin() {
|
2
|
+
myWindow=window.open(auth_url + '/login?response_type=token&client_id=' + user_pool_client_id + '&redirect_uri=https://' + window.location.hostname + '/assets/auth/signin.html','','width=600,height=600')
|
3
|
+
myWindow.focus()
|
4
|
+
}
|
5
|
+
|
6
|
+
function refreshLogin(id_token) {
|
7
|
+
localStorage.setItem("id_token", credentials.accessKeyId)
|
8
|
+
|
9
|
+
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
|
10
|
+
IdentityPoolId: identity_pool_id,
|
11
|
+
Logins: {
|
12
|
+
['cognito-idp.' + aws_region + '.amazonaws.com/' + user_pool_id]: id_token
|
13
|
+
}
|
14
|
+
})
|
15
|
+
AWS.config.update({region: 'ap-southeast-2'})
|
16
|
+
|
17
|
+
AWS.config.credentials.refresh((error) => {
|
18
|
+
if (error) {
|
19
|
+
console.error(error)
|
20
|
+
signOut()
|
21
|
+
} else {
|
22
|
+
localStorage.setItem("accessKeyId", credentials.accessKeyId)
|
23
|
+
localStorage.setItem("secretAccessKey", credentials.secretAccessKey)
|
24
|
+
localStorage.setItem("sessionToken", credentials.sessionToken)
|
25
|
+
var now = Date.now()
|
26
|
+
localStorage.setItem("expiresAt", addMinutes(now, 60))
|
27
|
+
refreshSignedInStatus()
|
28
|
+
}
|
29
|
+
})
|
30
|
+
}
|
31
|
+
|
32
|
+
function getUserInfo() {
|
33
|
+
var jwt = localStorage.getItem("id_token")
|
34
|
+
var jwt_segments = jwt.split('.')
|
35
|
+
var payload = JSON.parse(atob(jwt_segments[1]))
|
36
|
+
return payload
|
37
|
+
}
|
38
|
+
|
39
|
+
function setDisplayElements() {
|
40
|
+
var userInfo = getUserInfo()
|
41
|
+
$('#currentUserName').innerText(userInfo.email)
|
42
|
+
}
|
43
|
+
|
44
|
+
function refreshSignedInStatus() {
|
45
|
+
var accessKeyId = localStorage.getItem("accessKeyId")
|
46
|
+
var secretAccessKey = localStorage.getItem("secretAccessKey")
|
47
|
+
var sessionToken = localStorage.getItem("sessionToken")
|
48
|
+
var expiresAt = localStorage.getItem("expiresAt")
|
49
|
+
|
50
|
+
var now = Date.now()
|
51
|
+
if (expiresAt !== null && expiresAt < now) {
|
52
|
+
// session was there, but has expired, so force a sign out
|
53
|
+
signOut()
|
54
|
+
return
|
55
|
+
} else if (accessKeyId === null || secretAccessKey === null || sessionToken === null) {
|
56
|
+
// user is not signed in
|
57
|
+
setSignInDisplay(false)
|
58
|
+
} else if (accessKeyId !== null && secretAccessKey !== null && sessionToken !== null) {
|
59
|
+
// user is signed in
|
60
|
+
setSignInDisplay(true)
|
61
|
+
}
|
62
|
+
|
63
|
+
// if we get to here, we just don't know, so force a signed out state
|
64
|
+
signOut()
|
65
|
+
}
|
66
|
+
|
67
|
+
function setSignInDisplay(signedIn) {
|
68
|
+
if (signedIn) {
|
69
|
+
setDisplayElements()
|
70
|
+
$('.showSignedIn').show()
|
71
|
+
$('.showSignedOut').hide()
|
72
|
+
} else {
|
73
|
+
$('.showSignedIn').hide()
|
74
|
+
$('.showSignedOut').show()
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
function signOut() {
|
79
|
+
localStorage.removeItem("accessKeyId")
|
80
|
+
localStorage.removeItem("secretAccessKey")
|
81
|
+
localStorage.removeItem("sessionToken")
|
82
|
+
localStorage.removeItem("expiresAt")
|
83
|
+
localStorage.removeItem("id_token")
|
84
|
+
refreshSignedInStatus()
|
85
|
+
}
|
86
|
+
|
87
|
+
function addMinutes(date, minutes) {
|
88
|
+
return new Date(date + minutes*60000)
|
89
|
+
}
|
90
|
+
|
91
|
+
$(document).onload(function() {
|
92
|
+
refreshSignedInStatus()
|
93
|
+
})
|
@@ -0,0 +1,16 @@
|
|
1
|
+
function getQueryVariable(variable) {
|
2
|
+
var query = window.location.hash.substring(1);
|
3
|
+
var vars = query.split('&');
|
4
|
+
for (var i = 0; i < vars.length; i++) {
|
5
|
+
var pair = vars[i].split('=');
|
6
|
+
if (decodeURIComponent(pair[0]) == variable) {
|
7
|
+
return decodeURIComponent(pair[1]);
|
8
|
+
}
|
9
|
+
}
|
10
|
+
console.log('Query variable %s not found', variable);
|
11
|
+
}
|
12
|
+
|
13
|
+
var id_token = getQueryVariable('id_token')
|
14
|
+
|
15
|
+
window.opener.refreshLogin(id_token)
|
16
|
+
window.close()
|
@@ -0,0 +1,438 @@
|
|
1
|
+
/*
|
2
|
+
UriTemplates Template Processor - Version: @VERSION - Dated: @DATE
|
3
|
+
(c) marc.portier@gmail.com - 2011-2012
|
4
|
+
Licensed under APLv2 (http://opensource.org/licenses/Apache-2.0)
|
5
|
+
*/
|
6
|
+
|
7
|
+
;
|
8
|
+
var uritemplate = (function() {
|
9
|
+
|
10
|
+
// Below are the functions we originally used from jQuery.
|
11
|
+
// The implementations below are often more naive then what is inside jquery, but they suffice for our needs.
|
12
|
+
|
13
|
+
function isFunction(fn) {
|
14
|
+
return typeof fn == 'function';
|
15
|
+
}
|
16
|
+
|
17
|
+
function isEmptyObject (obj) {
|
18
|
+
for(var name in obj){
|
19
|
+
return false;
|
20
|
+
}
|
21
|
+
return true;
|
22
|
+
}
|
23
|
+
|
24
|
+
function extend(base, newprops) {
|
25
|
+
for (var name in newprops) {
|
26
|
+
base[name] = newprops[name];
|
27
|
+
}
|
28
|
+
return base;
|
29
|
+
}
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Create a runtime cache around retrieved values from the context.
|
33
|
+
* This allows for dynamic (function) results to be kept the same for multiple
|
34
|
+
* occuring expansions within one template.
|
35
|
+
* Note: Uses key-value tupples to be able to cache null values as well.
|
36
|
+
*/
|
37
|
+
//TODO move this into prep-processing
|
38
|
+
function CachingContext(context) {
|
39
|
+
this.raw = context;
|
40
|
+
this.cache = {};
|
41
|
+
}
|
42
|
+
CachingContext.prototype.get = function(key) {
|
43
|
+
var val = this.lookupRaw(key);
|
44
|
+
var result = val;
|
45
|
+
|
46
|
+
if (isFunction(val)) { // check function-result-cache
|
47
|
+
var tupple = this.cache[key];
|
48
|
+
if (tupple !== null && tupple !== undefined) {
|
49
|
+
result = tupple.val;
|
50
|
+
} else {
|
51
|
+
result = val(this.raw);
|
52
|
+
this.cache[key] = {key: key, val: result};
|
53
|
+
// NOTE: by storing tupples we make sure a null return is validly consistent too in expansions
|
54
|
+
}
|
55
|
+
}
|
56
|
+
return result;
|
57
|
+
};
|
58
|
+
|
59
|
+
CachingContext.prototype.lookupRaw = function(key) {
|
60
|
+
return CachingContext.lookup(this, this.raw, key);
|
61
|
+
};
|
62
|
+
|
63
|
+
CachingContext.lookup = function(me, context, key) {
|
64
|
+
var result = context[key];
|
65
|
+
if (result !== undefined) {
|
66
|
+
return result;
|
67
|
+
} else {
|
68
|
+
var keyparts = key.split('.');
|
69
|
+
var i = 0, keysplits = keyparts.length - 1;
|
70
|
+
for (i = 0; i<keysplits; i++) {
|
71
|
+
var leadKey = keyparts.slice(0, keysplits - i).join('.');
|
72
|
+
var trailKey = keyparts.slice(-i-1).join('.');
|
73
|
+
var leadContext = context[leadKey];
|
74
|
+
if (leadContext !== undefined) {
|
75
|
+
return CachingContext.lookup(me, leadContext, trailKey);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
return undefined;
|
79
|
+
}
|
80
|
+
};
|
81
|
+
|
82
|
+
|
83
|
+
function UriTemplate(set) {
|
84
|
+
this.set = set;
|
85
|
+
}
|
86
|
+
|
87
|
+
UriTemplate.prototype.expand = function(context) {
|
88
|
+
var cache = new CachingContext(context);
|
89
|
+
var res = "";
|
90
|
+
var i = 0, cnt = this.set.length;
|
91
|
+
for (i = 0; i<cnt; i++ ) {
|
92
|
+
res += this.set[i].expand(cache);
|
93
|
+
}
|
94
|
+
return res;
|
95
|
+
};
|
96
|
+
|
97
|
+
//TODO: change since draft-0.6 about characters in literals
|
98
|
+
/* extract:
|
99
|
+
The characters outside of expressions in a URI Template string are intended to be copied literally to the URI-reference if the character is allowed in a URI (reserved / unreserved / pct-encoded) or, if not allowed, copied to the URI-reference in its UTF-8 pct-encoded form.
|
100
|
+
*/
|
101
|
+
function Literal(txt ) {
|
102
|
+
this.txt = txt;
|
103
|
+
}
|
104
|
+
|
105
|
+
Literal.prototype.expand = function() {
|
106
|
+
return this.txt;
|
107
|
+
};
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
var RESERVEDCHARS_RE = new RegExp("[:/?#\\[\\]@!$&()*+,;=']","g");
|
112
|
+
function encodeNormal(val) {
|
113
|
+
return encodeURIComponent(val).replace(RESERVEDCHARS_RE, function(s) {return escape(s);} );
|
114
|
+
}
|
115
|
+
|
116
|
+
//var SELECTEDCHARS_RE = new RegExp("[]","g");
|
117
|
+
function encodeReserved(val) {
|
118
|
+
//return encodeURI(val).replace(SELECTEDCHARS_RE, function(s) {return escape(s)} );
|
119
|
+
return encodeURI(val); // no need for additional replace if selected-chars is empty
|
120
|
+
}
|
121
|
+
|
122
|
+
|
123
|
+
function addUnNamed(name, key, val) {
|
124
|
+
return key + (key.length > 0 ? "=" : "") + val;
|
125
|
+
}
|
126
|
+
|
127
|
+
function addNamed(name, key, val, noName) {
|
128
|
+
noName = noName || false;
|
129
|
+
if (noName) { name = ""; }
|
130
|
+
|
131
|
+
if (!key || key.length === 0) {
|
132
|
+
key = name;
|
133
|
+
}
|
134
|
+
return key + (key.length > 0 ? "=" : "") + val;
|
135
|
+
}
|
136
|
+
|
137
|
+
function addLabeled(name, key, val, noName) {
|
138
|
+
noName = noName || false;
|
139
|
+
if (noName) { name = ""; }
|
140
|
+
|
141
|
+
if (!key || key.length === 0) {
|
142
|
+
key = name;
|
143
|
+
}
|
144
|
+
return key + (key.length > 0 && val ? "=" : "") + val;
|
145
|
+
}
|
146
|
+
|
147
|
+
|
148
|
+
var simpleConf = {
|
149
|
+
prefix : "", joiner : ",", encode : encodeNormal, builder : addUnNamed
|
150
|
+
};
|
151
|
+
var reservedConf = {
|
152
|
+
prefix : "", joiner : ",", encode : encodeReserved, builder : addUnNamed
|
153
|
+
};
|
154
|
+
var fragmentConf = {
|
155
|
+
prefix : "#", joiner : ",", encode : encodeReserved, builder : addUnNamed
|
156
|
+
};
|
157
|
+
var pathParamConf = {
|
158
|
+
prefix : ";", joiner : ";", encode : encodeNormal, builder : addLabeled
|
159
|
+
};
|
160
|
+
var formParamConf = {
|
161
|
+
prefix : "?", joiner : "&", encode : encodeNormal, builder : addNamed
|
162
|
+
};
|
163
|
+
var formContinueConf = {
|
164
|
+
prefix : "&", joiner : "&", encode : encodeNormal, builder : addNamed
|
165
|
+
};
|
166
|
+
var pathHierarchyConf = {
|
167
|
+
prefix : "/", joiner : "/", encode : encodeNormal, builder : addUnNamed
|
168
|
+
};
|
169
|
+
var labelConf = {
|
170
|
+
prefix : ".", joiner : ".", encode : encodeNormal, builder : addUnNamed
|
171
|
+
};
|
172
|
+
|
173
|
+
|
174
|
+
function Expression(conf, vars ) {
|
175
|
+
extend(this, conf);
|
176
|
+
this.vars = vars;
|
177
|
+
}
|
178
|
+
|
179
|
+
Expression.build = function(ops, vars) {
|
180
|
+
var conf;
|
181
|
+
switch(ops) {
|
182
|
+
case '' : conf = simpleConf; break;
|
183
|
+
case '+' : conf = reservedConf; break;
|
184
|
+
case '#' : conf = fragmentConf; break;
|
185
|
+
case ';' : conf = pathParamConf; break;
|
186
|
+
case '?' : conf = formParamConf; break;
|
187
|
+
case '&' : conf = formContinueConf; break;
|
188
|
+
case '/' : conf = pathHierarchyConf; break;
|
189
|
+
case '.' : conf = labelConf; break;
|
190
|
+
default : throw "Unexpected operator: '"+ops+"'";
|
191
|
+
}
|
192
|
+
return new Expression(conf, vars);
|
193
|
+
};
|
194
|
+
|
195
|
+
Expression.prototype.expand = function(context) {
|
196
|
+
var joiner = this.prefix;
|
197
|
+
var nextjoiner = this.joiner;
|
198
|
+
var buildSegment = this.builder;
|
199
|
+
var res = "";
|
200
|
+
var i = 0, cnt = this.vars.length;
|
201
|
+
|
202
|
+
for (i = 0 ; i< cnt; i++) {
|
203
|
+
var varspec = this.vars[i];
|
204
|
+
varspec.addValues(context, this.encode, function(key, val, noName) {
|
205
|
+
var segm = buildSegment(varspec.name, key, val, noName);
|
206
|
+
if (segm !== null && segm !== undefined) {
|
207
|
+
res += joiner + segm;
|
208
|
+
joiner = nextjoiner;
|
209
|
+
}
|
210
|
+
});
|
211
|
+
}
|
212
|
+
return res;
|
213
|
+
};
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
var UNBOUND = {};
|
218
|
+
|
219
|
+
/**
|
220
|
+
* Helper class to help grow a string of (possibly encoded) parts until limit is reached
|
221
|
+
*/
|
222
|
+
function Buffer(limit) {
|
223
|
+
this.str = "";
|
224
|
+
if (limit === UNBOUND) {
|
225
|
+
this.appender = Buffer.UnboundAppend;
|
226
|
+
} else {
|
227
|
+
this.len = 0;
|
228
|
+
this.limit = limit;
|
229
|
+
this.appender = Buffer.BoundAppend;
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
Buffer.prototype.append = function(part, encoder) {
|
234
|
+
return this.appender(this, part, encoder);
|
235
|
+
};
|
236
|
+
|
237
|
+
Buffer.UnboundAppend = function(me, part, encoder) {
|
238
|
+
part = encoder ? encoder(part) : part;
|
239
|
+
me.str += part;
|
240
|
+
return me;
|
241
|
+
};
|
242
|
+
|
243
|
+
Buffer.BoundAppend = function(me, part, encoder) {
|
244
|
+
part = part.substring(0, me.limit - me.len);
|
245
|
+
me.len += part.length;
|
246
|
+
|
247
|
+
part = encoder ? encoder(part) : part;
|
248
|
+
me.str += part;
|
249
|
+
return me;
|
250
|
+
};
|
251
|
+
|
252
|
+
|
253
|
+
function arrayToString(arr, encoder, maxLength) {
|
254
|
+
var buffer = new Buffer(maxLength);
|
255
|
+
var joiner = "";
|
256
|
+
|
257
|
+
var i = 0, cnt = arr.length;
|
258
|
+
for (i=0; i<cnt; i++) {
|
259
|
+
if (arr[i] !== null && arr[i] !== undefined) {
|
260
|
+
buffer.append(joiner).append(arr[i], encoder);
|
261
|
+
joiner = ",";
|
262
|
+
}
|
263
|
+
}
|
264
|
+
return buffer.str;
|
265
|
+
}
|
266
|
+
|
267
|
+
function objectToString(obj, encoder, maxLength) {
|
268
|
+
var buffer = new Buffer(maxLength);
|
269
|
+
var joiner = "";
|
270
|
+
var k;
|
271
|
+
|
272
|
+
for (k in obj) {
|
273
|
+
if (obj.hasOwnProperty(k) ) {
|
274
|
+
if (obj[k] !== null && obj[k] !== undefined) {
|
275
|
+
buffer.append(joiner + k + ',').append(obj[k], encoder);
|
276
|
+
joiner = ",";
|
277
|
+
}
|
278
|
+
}
|
279
|
+
}
|
280
|
+
return buffer.str;
|
281
|
+
}
|
282
|
+
|
283
|
+
|
284
|
+
function simpleValueHandler(me, val, valprops, encoder, adder) {
|
285
|
+
var result;
|
286
|
+
|
287
|
+
if (valprops.isArr) {
|
288
|
+
result = arrayToString(val, encoder, me.maxLength);
|
289
|
+
} else if (valprops.isObj) {
|
290
|
+
result = objectToString(val, encoder, me.maxLength);
|
291
|
+
} else {
|
292
|
+
var buffer = new Buffer(me.maxLength);
|
293
|
+
result = buffer.append(val, encoder).str;
|
294
|
+
}
|
295
|
+
|
296
|
+
adder("", result);
|
297
|
+
}
|
298
|
+
|
299
|
+
function explodeValueHandler(me, val, valprops, encoder, adder) {
|
300
|
+
if (valprops.isArr) {
|
301
|
+
var i = 0, cnt = val.length;
|
302
|
+
for (i = 0; i<cnt; i++) {
|
303
|
+
adder("", encoder(val[i]) );
|
304
|
+
}
|
305
|
+
} else if (valprops.isObj) {
|
306
|
+
var k;
|
307
|
+
for (k in val) {
|
308
|
+
if (val.hasOwnProperty(k)) {
|
309
|
+
adder(k, encoder(val[k]) );
|
310
|
+
}
|
311
|
+
}
|
312
|
+
} else { // explode-requested, but single value
|
313
|
+
adder("", encoder(val));
|
314
|
+
}
|
315
|
+
}
|
316
|
+
|
317
|
+
function valueProperties(val) {
|
318
|
+
var isArr = false;
|
319
|
+
var isObj = false;
|
320
|
+
var isUndef = true; //note: "" is empty but not undef
|
321
|
+
|
322
|
+
if (val !== null && val !== undefined) {
|
323
|
+
isArr = (val.constructor === Array);
|
324
|
+
isObj = (val.constructor === Object);
|
325
|
+
isUndef = (isArr && val.length === 0) || (isObj && isEmptyObject(val));
|
326
|
+
}
|
327
|
+
|
328
|
+
return {isArr: isArr, isObj: isObj, isUndef: isUndef};
|
329
|
+
}
|
330
|
+
|
331
|
+
|
332
|
+
function VarSpec (name, vhfn, nums) {
|
333
|
+
this.name = unescape(name);
|
334
|
+
this.valueHandler = vhfn;
|
335
|
+
this.maxLength = nums;
|
336
|
+
}
|
337
|
+
|
338
|
+
|
339
|
+
VarSpec.build = function(name, expl, part, nums) {
|
340
|
+
var valueHandler, valueModifier;
|
341
|
+
|
342
|
+
if (!!expl) { //interprete as boolean
|
343
|
+
valueHandler = explodeValueHandler;
|
344
|
+
} else {
|
345
|
+
valueHandler = simpleValueHandler;
|
346
|
+
}
|
347
|
+
|
348
|
+
if (!part) {
|
349
|
+
nums = UNBOUND;
|
350
|
+
}
|
351
|
+
|
352
|
+
return new VarSpec(name, valueHandler, nums);
|
353
|
+
};
|
354
|
+
|
355
|
+
|
356
|
+
VarSpec.prototype.addValues = function(context, encoder, adder) {
|
357
|
+
var val = context.get(this.name);
|
358
|
+
var valprops = valueProperties(val);
|
359
|
+
if (valprops.isUndef) { return; } // ignore empty values
|
360
|
+
this.valueHandler(this, val, valprops, encoder, adder);
|
361
|
+
};
|
362
|
+
|
363
|
+
|
364
|
+
|
365
|
+
//----------------------------------------------parsing logic
|
366
|
+
// How each varspec should look like
|
367
|
+
var VARSPEC_RE=/([^*:]*)((\*)|(:)([0-9]+))?/;
|
368
|
+
|
369
|
+
var match2varspec = function(m) {
|
370
|
+
var name = m[1];
|
371
|
+
var expl = m[3];
|
372
|
+
var part = m[4];
|
373
|
+
var nums = parseInt(m[5], 10);
|
374
|
+
|
375
|
+
return VarSpec.build(name, expl, part, nums);
|
376
|
+
};
|
377
|
+
|
378
|
+
|
379
|
+
// Splitting varspecs in list with:
|
380
|
+
var LISTSEP=",";
|
381
|
+
|
382
|
+
// How each template should look like
|
383
|
+
var TEMPL_RE=/(\{([+#.;?&\/])?(([^.*:,{}|@!=$()][^*:,{}$()]*)(\*|:([0-9]+))?(,([^.*:,{}][^*:,{}]*)(\*|:([0-9]+))?)*)\})/g;
|
384
|
+
// Note: reserved operators: |!@ are left out of the regexp in order to make those templates degrade into literals
|
385
|
+
// (as expected by the spec - see tests.html "reserved operators")
|
386
|
+
|
387
|
+
|
388
|
+
var match2expression = function(m) {
|
389
|
+
var expr = m[0];
|
390
|
+
var ops = m[2] || '';
|
391
|
+
var vars = m[3].split(LISTSEP);
|
392
|
+
var i = 0, len = vars.length;
|
393
|
+
for (i = 0; i<len; i++) {
|
394
|
+
var match;
|
395
|
+
if ( (match = vars[i].match(VARSPEC_RE)) === null) {
|
396
|
+
throw "unexpected parse error in varspec: " + vars[i];
|
397
|
+
}
|
398
|
+
vars[i] = match2varspec(match);
|
399
|
+
}
|
400
|
+
|
401
|
+
return Expression.build(ops, vars);
|
402
|
+
};
|
403
|
+
|
404
|
+
|
405
|
+
var pushLiteralSubstr = function(set, src, from, to) {
|
406
|
+
if (from < to) {
|
407
|
+
var literal = src.substr(from, to - from);
|
408
|
+
set.push(new Literal(literal));
|
409
|
+
}
|
410
|
+
};
|
411
|
+
|
412
|
+
var parse = function(str) {
|
413
|
+
var lastpos = 0;
|
414
|
+
var comp = [];
|
415
|
+
|
416
|
+
var match;
|
417
|
+
var pattern = TEMPL_RE;
|
418
|
+
pattern.lastIndex = 0; // just to be sure
|
419
|
+
while ((match = pattern.exec(str)) !== null) {
|
420
|
+
var newpos = match.index;
|
421
|
+
pushLiteralSubstr(comp, str, lastpos, newpos);
|
422
|
+
|
423
|
+
comp.push(match2expression(match));
|
424
|
+
lastpos = pattern.lastIndex;
|
425
|
+
}
|
426
|
+
pushLiteralSubstr(comp, str, lastpos, str.length);
|
427
|
+
|
428
|
+
return new UriTemplate(comp);
|
429
|
+
};
|
430
|
+
|
431
|
+
|
432
|
+
//-------------------------------------------comments and ideas
|
433
|
+
|
434
|
+
//TODO: consider building cache of previously parsed uris or even parsed expressions?
|
435
|
+
|
436
|
+
return parse;
|
437
|
+
|
438
|
+
}());
|