middleman-wizard-template 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (25) hide show
  1. checksums.yaml +7 -0
  2. data/lib/middleman-wizard-template/template/source/index.html.erb +1 -89
  3. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/Matrix.js +449 -0
  4. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/PxLoader/PxLoader.js +395 -0
  5. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/PxLoader/PxLoaderImage.js +96 -0
  6. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/PxLoader/PxLoaderSwiffy.js +68 -0
  7. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/RouteRecognizer.js +506 -0
  8. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/Slides.js +846 -0
  9. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/Transform.js +312 -0
  10. data/lib/middleman-wizard-template/template/source/javascripts/_lib/{Tween.js → ww/Tween.js} +26 -11
  11. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/base.js +8 -0
  12. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/raf.js +131 -0
  13. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/statemachine.js +1024 -0
  14. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/useragent.js +1244 -0
  15. data/lib/middleman-wizard-template/template/source/javascripts/_lib/{util.js → ww/util.js} +48 -50
  16. data/lib/middleman-wizard-template/template/source/javascripts/_lib/ww/viewport.js +89 -0
  17. data/lib/middleman-wizard-template/template/source/javascripts/{app.js → site.js} +5 -5
  18. data/lib/middleman-wizard-template/template/source/layouts/layout.erb +85 -0
  19. data/lib/middleman-wizard-template/template/source/stylesheets/default.css +2 -1
  20. data/lib/middleman-wizard-template/template/source/stylesheets/site.css.scss +11 -3
  21. data/lib/middleman-wizard-template/version.rb +1 -1
  22. metadata +23 -23
  23. data/lib/middleman-wizard-template/template/source/javascripts/_lib/Transform.js +0 -401
  24. data/lib/middleman-wizard-template/template/source/javascripts/_lib/raf.js +0 -26
  25. data/lib/middleman-wizard-template/template/source/javascripts/_lib/router.js +0 -679
@@ -1,401 +0,0 @@
1
- goog.provide('ww.transform');
2
-
3
- /**
4
- * CSS Transform support. Handle detection of 3d Transforms or falls back to the
5
- * 2d versions if they are available. Fixes cross-browser and browser-prefix
6
- * issues.
7
- */
8
- ww.transform = (function() {
9
- var Sylvester = {
10
- version: '0.1.3',
11
- precision: 1e-6
12
- };
13
-
14
- function Matrix() {}
15
- Matrix.prototype = {
16
-
17
- // Returns element (i,j) of the matrix
18
- e: function(i, j) {
19
- if ((i < 1) ||
20
- (i > this.elements.length) ||
21
- (j < 1) ||
22
- (j > this.elements[0].length)) { return null; }
23
- return this.elements[i - 1][j - 1];
24
- },
25
-
26
- // Maps the matrix to another matrix (of the same dimensions) according
27
- // to the given function
28
- map: function(fn) {
29
- var els = [], ni = this.elements.length, ki = ni, i, nj,
30
- kj = this.elements[0].length, j;
31
- do { i = ki - ni;
32
- nj = kj;
33
- els[i] = [];
34
- do { j = kj - nj;
35
- els[i][j] = fn(this.elements[i][j], i + 1, j + 1);
36
- } while (--nj);
37
- } while (--ni);
38
- return Matrix.create(els);
39
- },
40
-
41
- // Returns the result of multiplying the matrix from the right by the
42
- // argument. If the argument is a scalar then just multiply all the
43
- // elements. If the argument is a vector, a vector is returned, which
44
- // saves you having to remember calling
45
- // col(1) on the result.
46
- multiply: function(matrix) {
47
- if (!matrix.elements) {
48
- return this.map(function(x) { return x * matrix; });
49
- }
50
- var returnVector = matrix.modulus ? true : false;
51
- var M = matrix.elements || matrix;
52
- if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }
53
- if (!this.canMultiplyFromLeft(M)) { return null; }
54
- var ni = this.elements.length, ki = ni, i, nj, kj = M[0].length, j;
55
- var cols = this.elements[0].length, elements = [], sum, nc, c;
56
- do { i = ki - ni;
57
- elements[i] = [];
58
- nj = kj;
59
- do { j = kj - nj;
60
- sum = 0;
61
- nc = cols;
62
- do { c = cols - nc;
63
- sum += this.elements[i][c] * M[c][j];
64
- } while (--nc);
65
- elements[i][j] = sum;
66
- } while (--nj);
67
- } while (--ni);
68
- M = Matrix.create(elements);
69
- return returnVector ? M.col(1) : M;
70
- },
71
-
72
- x: function(matrix) { return this.multiply(matrix); },
73
-
74
- // Returns true iff the matrix can multiply the argument from the left
75
- canMultiplyFromLeft: function(matrix) {
76
- var M = matrix.elements || matrix;
77
- if (typeof(M[0][0]) == 'undefined') { M = Matrix.create(M).elements; }
78
- // this.columns should equal matrix.rows
79
- return (this.elements[0].length == M.length);
80
- },
81
-
82
- // Set the matrix's elements from an array. If the argument passed
83
- // is a vector, the resulting matrix will be a single column.
84
- setElements: function(els) {
85
- var i, elements = els.elements || els;
86
- if (typeof(elements[0][0]) != 'undefined') {
87
- var ni = elements.length, ki = ni, nj, kj, j;
88
- this.elements = [];
89
- do { i = ki - ni;
90
- nj = elements[i].length; kj = nj;
91
- this.elements[i] = [];
92
- do { j = kj - nj;
93
- this.elements[i][j] = elements[i][j];
94
- } while (--nj);
95
- } while (--ni);
96
- return this;
97
- }
98
- var n = elements.length, k = n;
99
- this.elements = [];
100
- do { i = k - n;
101
- this.elements.push([elements[i]]);
102
- } while (--n);
103
- return this;
104
- }
105
- };
106
-
107
- /**
108
- * Create a new Matrix.
109
- * @param {Array} elements Components of the matrix.
110
- * @return {Matrix} The matrix.
111
- */
112
- Matrix.create = function(elements) {
113
- var M = new Matrix();
114
- return M.setElements(elements);
115
- };
116
-
117
- // Utility functions
118
- var $M = Matrix.create;
119
- // }).apply(this);
120
-
121
- // (function() {
122
- var translationUnit = '',
123
- prop = 'transform',
124
- supportedProp, supports3d, supports2d;
125
-
126
- supports3d = Modernizr['csstransforms3d'];
127
- supports2d = Modernizr['csstransforms'];
128
- supportedProp = Modernizr['prefixed'](prop);
129
-
130
- var div = document.createElement('div');
131
- if ('MozTransform' in div.style) {
132
- translationUnit = 'px';
133
- }
134
-
135
- var transformProperty = supportedProp;
136
-
137
- var properties = {
138
- 'rotateX': {
139
- defaultValue: 0,
140
- matrix: function(a) {
141
- if (supports3d) {
142
- return $M([
143
- [1, 0, 0, 0],
144
- [0, Math.cos(a), Math.sin(-a), 0],
145
- [0, Math.sin(a), Math.cos(a), 0],
146
- [0, 0, 0, 1]
147
- ]);
148
- }
149
- else {
150
- return $M([
151
- [1, 0, 0],
152
- [0, 1, 0],
153
- [0, 0, 1]
154
- ]);
155
- }
156
- }
157
- },
158
- 'rotateY': {
159
- defaultValue: 0,
160
- matrix: function(b) {
161
- if (supports3d) {
162
- return $M([
163
- [Math.cos(b), 0, Math.sin(b), 0],
164
- [0, 1, 0, 0],
165
- [Math.sin(-b), 0, Math.cos(b), 0],
166
- [0, 0, 0, 1]
167
- ]);
168
- }
169
- else {
170
- return $M([
171
- [1, 0, 0],
172
- [0, 1, 0],
173
- [0, 0, 1]
174
- ]);
175
- }
176
- }
177
- },
178
- 'rotateZ': {
179
- defaultValue: 0,
180
- matrix: function(c) {
181
- if (supports3d) {
182
- return $M([
183
- [Math.cos(c), Math.sin(-c), 0, 0],
184
- [Math.sin(c), Math.cos(c), 0, 0],
185
- [0, 0, 1, 0],
186
- [0, 0, 0, 1]
187
- ]);
188
- }
189
- else {
190
- return $M([
191
- [Math.cos(c), Math.sin(-c), 0],
192
- [Math.sin(c), Math.cos(c), 0],
193
- [0, 0, 1]
194
- ]);
195
- }
196
- }
197
- },
198
- 'perspective': {
199
- defaultValue: 0,
200
- matrix: function(ps) {
201
- ps = (ps === 0) ? 0 : -1 / ps;
202
- if (supports3d) {
203
- return $M([
204
- [1, 0, 0, 0],
205
- [0, 1, 0, 0],
206
- [0, 0, 1, ps],
207
- [0, 0, 0, 1]
208
- ]);
209
- } else {
210
- return $M([
211
- [1, 0, 0],
212
- [0, 1, 0],
213
- [0, 0, 1]
214
- ]);
215
- }
216
- }
217
- },
218
- 'scale': {
219
- defaultValue: 1,
220
- matrix: function(s) {
221
- if (supports3d) {
222
- return $M([
223
- [s, 0, 0, 0],
224
- [0, s, 0, 0],
225
- [0, 0, s, 0],
226
- [0, 0, 0, 1]
227
- ]);
228
- }
229
- else {
230
- return $M([
231
- [s, 0, 0],
232
- [0, s, 0],
233
- [0, 0, 1]
234
- ]);
235
- }
236
- }
237
- },
238
- 'translateX': {
239
- defaultValue: 0,
240
- matrix: function(tx) {
241
- if (supports3d) {
242
- return $M([
243
- [1, 0, 0, 0],
244
- [0, 1, 0, 0],
245
- [0, 0, 1, 0],
246
- [tx, 0, 0, 1]
247
- ]);
248
- }
249
- else {
250
- return $M([
251
- [1, 0, 0],
252
- [0, 1, 0],
253
- [tx, 0, 1]
254
- ]);
255
- }
256
- }
257
- },
258
- 'translateY': {
259
- defaultValue: 0,
260
- matrix: function(ty) {
261
- if (supports3d) {
262
- return $M([
263
- [1, 0, 0, 0],
264
- [0, 1, 0, 0],
265
- [0, 0, 1, 0],
266
- [0, ty, 0, 1]
267
- ]);
268
- }
269
- else {
270
- return $M([
271
- [1, 0, 0],
272
- [0, 1, 0],
273
- [0, ty, 1]
274
- ]);
275
- }
276
- }
277
- },
278
- 'translateZ': {
279
- defaultValue: 0,
280
- matrix: function(tz) {
281
- if (supports3d) {
282
- return $M([
283
- [1, 0, 0, 0],
284
- [0, 1, 0, 0],
285
- [0, 0, 1, 0],
286
- [0, 0, tz, 1]
287
- ]);
288
- }
289
- else {
290
- return $M([
291
- [1, 0, 0],
292
- [0, 1, 0],
293
- [0, 0, 1]
294
- ]);
295
- }
296
- }
297
- }
298
- };
299
-
300
- var applyMatrix = function(elem) {
301
- var transforms = getTransformsForElem(elem);
302
- var tM, s;
303
-
304
- if (supports3d) {
305
- tM = $M([
306
- [1, 0, 0, 0],
307
- [0, 1, 0, 0],
308
- [0, 0, 1, -1],
309
- [0, 0, 0, 1]
310
- ]);
311
- } else {
312
- tM = $M([
313
- [1, 0, 0],
314
- [0, 1, 0],
315
- [0, 0, 1]
316
- ]);
317
- }
318
-
319
- for (var name in properties) {
320
- if (properties.hasOwnProperty(name)) {
321
- var curVal = transforms[name] || properties[name].defaultValue;
322
- var propVal = properties[name];
323
- tM = tM.x(propVal.matrix(curVal));
324
- }
325
- }
326
-
327
- if (supports3d) {
328
- s = 'matrix3d(';
329
- s += tM.e(1, 1).toFixed(10) + ',' + tM.e(1, 2).toFixed(10) + ',';
330
- s += tM.e(1, 3).toFixed(10) + ',' + tM.e(1, 4).toFixed(10) + ',';
331
- s += tM.e(2, 1).toFixed(10) + ',' + tM.e(2, 2).toFixed(10) + ',';
332
- s += tM.e(2, 3).toFixed(10) + ',' + tM.e(2, 4).toFixed(10) + ',';
333
- s += tM.e(3, 1).toFixed(10) + ',' + tM.e(3, 2).toFixed(10) + ',';
334
- s += tM.e(3, 3).toFixed(10) + ',' + tM.e(3, 4).toFixed(10) + ',';
335
- s += tM.e(4, 1).toFixed(10) + ',' + tM.e(4, 2).toFixed(10) + ',';
336
- s += tM.e(4, 3).toFixed(10) + ',' + tM.e(4, 4).toFixed(10);
337
- s += ')';
338
- } else if (supports2d) {
339
- s = 'matrix(';
340
- s += tM.e(1, 1).toFixed(10) + ',' + tM.e(1, 2).toFixed(10) + ',';
341
- s += tM.e(2, 1).toFixed(10) + ',' + tM.e(2, 2).toFixed(10) + ',';
342
- s += tM.e(3, 1).toFixed(10) + translationUnit + ',';
343
- s += tM.e(3, 2).toFixed(10) + translationUnit;
344
- s += ')';
345
- }
346
-
347
- if (s) {
348
- elem.style[transformProperty] = s;
349
- }
350
- };
351
-
352
- var transformsCache = {};
353
-
354
- function getTransformsForElem(elem) {
355
- return transformsCache[elem.id];
356
- }
357
-
358
- function setTransformsForElem(elem, transforms) {
359
- if (!elem.id || !elem.id.length) {
360
- throw 'Cannot set current transforms for element without id';
361
- }
362
-
363
- transformsCache[elem.id] = transforms;
364
- }
365
-
366
- function getValueForElemAndName(elem, name) {
367
- var transforms = getTransformsForElem(elem);
368
-
369
- if (transforms === undefined) {
370
- transforms = {};
371
- }
372
-
373
- return transforms[name] || properties[name].defaultValue;
374
- }
375
-
376
- function setValueForElemAndName(elem, name, value) {
377
- elem.id = elem.id ||
378
- 'transform_cache_' + (new Date()).getTime() + Math.random();
379
- var transforms = getTransformsForElem(elem);
380
-
381
- if (transforms === undefined) transforms = {};
382
- var propInfo = properties[name];
383
-
384
- if (typeof propInfo.apply === 'function') {
385
- var curVal = transforms[name] || propInfo.defaultValue;
386
- transforms[name] = propInfo.apply(curVal, value);
387
- } else {
388
- transforms[name] = value;
389
- }
390
-
391
- setTransformsForElem(elem, transforms);
392
-
393
- applyMatrix(elem);
394
- }
395
-
396
- // Expose API
397
- return {
398
- getValue: getValueForElemAndName,
399
- setValue: setValueForElemAndName
400
- };
401
- }).call(this);
@@ -1,26 +0,0 @@
1
- (function() {
2
- var lastTime = 0;
3
- var vendors = ['ms', 'moz', 'webkit', 'o'];
4
- for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
5
- var cancelName1 = vendors[x] + 'CancelAnimationFrame';
6
- var cancelName2 = vendors[x] + 'CancelRequestAnimationFrame';
7
- window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
8
- window.cancelAnimationFrame = window[cancelName1] || window[cancelName2];
9
- }
10
-
11
- if (!window.requestAnimationFrame)
12
- window.requestAnimationFrame = function(callback, element) {
13
- var currTime = new Date().getTime();
14
- var timeToCall = Math.max(0, 16 - (currTime - lastTime));
15
- var id = window.setTimeout(
16
- function() { callback(currTime + timeToCall); },
17
- timeToCall
18
- );
19
- lastTime = currTime + timeToCall;
20
- return id;
21
- };
22
- if (!window.cancelAnimationFrame)
23
- window.cancelAnimationFrame = function(id) {
24
- clearTimeout(id);
25
- };
26
- }());
@@ -1,679 +0,0 @@
1
- goog.provide('ww.router');
2
-
3
- /**
4
- * Helper method to escape a Regex.
5
- * @private
6
- * @param {String} text The text to escape.
7
- * @return {String} The resulting regex string.
8
- */
9
- function regexEscape_(text) {
10
- if (!arguments.callee.sRE) {
11
- var specials = [
12
- '/', '.', '*', '+', '?', '|',
13
- '(', ')', '[', ']', '{', '}', '\\'
14
- ];
15
- arguments.callee.sRE = new RegExp(
16
- '(\\' + specials.join('|\\') + ')', 'g'
17
- );
18
- }
19
- return text.replace(arguments.callee.sRE, '\\$1');
20
- }
21
-
22
- /**
23
- * A Router.
24
- * @constructor
25
- * @param {Object} options Router opts.
26
- */
27
- ww.router.Router = function Router(options) {
28
- this.routes = {};
29
- this.root = new ww.router.Node();
30
- this.requestKeys = options && options['requestKeys'] || ['method'];
31
- };
32
-
33
- /**
34
- * Generate a URL from the router.
35
- * @param {String} name The name of the route.
36
- * @param {Object} params Options for the route.
37
- * @return {String} The resulting URL.
38
- */
39
- ww.router.Router.prototype.generate = function routerGenerate(name, params) {
40
- return this.routes[name].generate(params);
41
- };
42
-
43
- /**
44
- * Add a route to this router.
45
- * @param {String} uri The route uri.
46
- * @param {Object} options Params for the route.
47
- * @return {ww.router.Route} The new route.
48
- */
49
- ww.router.Router.prototype.add = function routerAdd(uri, options) {
50
- var route = new ww.router.Route(this, uri);
51
- if (options) route.withOptions(options);
52
- return route;
53
- };
54
-
55
- /**
56
- * Recognize a route given a URL.
57
- * @param {String} path The URL.
58
- * @param {Object} request The request.
59
- * @return {ww.router.Route} The found route.
60
- */
61
- ww.router.Router.prototype.recognize = function routerRecognize(path, request) {
62
- if (path.substring(0, 1) == '/') path = path.substring(1);
63
- return this.root.find(path == '' ? [] : path.split(/\//), request, []);
64
- };
65
-
66
- /**
67
- * A Route path
68
- * @constructor
69
- * @param {String} route The path route.
70
- * @param {String} uri The path uri.
71
- */
72
- ww.router.Path = function Path(route, uri) {
73
- this.route = route;
74
- var splitUri = this.pathSplit(uri);
75
-
76
- // this.compiledUri = [];
77
-
78
- // for (var splitUriIdx = 0; splitUriIdx != splitUri.length; splitUriIdx++) {
79
- // if (splitUri[splitUriIdx].substring(0, 1) == ':') {
80
- // this.compiledUri.push(
81
- // "params['" + splitUri[splitUriIdx].substring(1) + "']"
82
- // );
83
- // } else {
84
- // this.compiledUri.push("'" + splitUri[splitUriIdx] + "'");
85
- // }
86
- // }
87
-
88
- this.compiledUri = uri;
89
-
90
- this.groups = [];
91
-
92
- for (var splitIndex = 0; splitIndex < splitUri.length; splitIndex++) {
93
- var part = splitUri[splitIndex];
94
- if (part == '/') {
95
- this.groups.push([]);
96
- } else if (part != '') {
97
- this.groups[this.groups.length - 1].push(part);
98
- }
99
- }
100
- };
101
-
102
- /**
103
- * Split a Path.
104
- * @param {String} path The path.
105
- * @return {Array} The split parts.
106
- */
107
- ww.router.Path.prototype.pathSplit = function pathSplit(path) {
108
- var splitParts = [];
109
- var parts = path.split('/');
110
- if (parts[0] == '') parts.shift();
111
-
112
- for (var i = 0; i != parts.length; i++) {
113
- splitParts.push('/');
114
- splitParts.push('');
115
- partChars = parts[i].split('');
116
-
117
- var inVariable = false;
118
-
119
- for (var j = 0; j != partChars.length; j++) {
120
- if (inVariable) {
121
- var code = partChars[j].charCodeAt(0);
122
- if ((code >= 48 && code <= 57) || (code >= 65 && code <= 90) ||
123
- (code >= 97 && code <= 122) || code == 95) {
124
- splitParts[splitParts.length - 1] += partChars[j];
125
- } else {
126
- inVariable = false;
127
- splitParts.push(partChars[j]);
128
- }
129
- } else if (partChars[j] == ':') {
130
- inVariable = true;
131
- if (splitParts[splitParts.length - 1] == '') {
132
- splitParts[splitParts.length - 1] += ':';
133
- } else {
134
- splitParts.push(':');
135
- }
136
- } else {
137
- splitParts[splitParts.length - 1] += partChars[j];
138
- }
139
- }
140
- }
141
- return splitParts;
142
- };
143
-
144
- /**
145
- * Generate a path.
146
- * @param {Object} params The params.
147
- * @return {String} The path.
148
- */
149
- ww.router.Path.prototype.generate = function pathGenerate(params) {
150
- for (var varIdx = 0; varIdx != this.variableNames.length; varIdx++) {
151
- if (!params[this.variableNames[varIdx]]) return undefined;
152
- }
153
- for (var varIdx = 0; varIdx != this.variableNames.length; varIdx++) {
154
- var condition = this.route.matchingConditions[this.variableNames[varIdx]];
155
- if (condition) {
156
- var varName = params[this.variableNames[varIdx]].toString();
157
- if (condition.exec(varName) != params[varName]) {
158
- return undefined;
159
- }
160
- }
161
- }
162
- var path = this.compiledUri;
163
- if (path.indexOf(':') >= 0) {
164
- for (var varIdx = 0; varIdx != this.variableNames.length; varIdx++) {
165
- path = path.replace(
166
- ':' + this.variableNames[varIdx],
167
- params[this.variableNames[varIdx]]
168
- );
169
- delete params[this.variableNames[varIdx]];
170
- }
171
- } else {
172
- for (var varIdx = 0; varIdx != this.variableNames.length; varIdx++) {
173
- delete params[this.variableNames[varIdx]];
174
- }
175
- }
176
- return path;
177
- };
178
-
179
- /**
180
- * Compile a path.
181
- */
182
- ww.router.Path.prototype.compile = function pathCompile() {
183
- this.variableNames = [];
184
- var currentNode = this.route.router.root;
185
- for (var groupIdx = 0; groupIdx != this.groups.length; groupIdx++) {
186
- var group = this.groups[groupIdx];
187
- if (group.length > 1) {
188
- var pattern = '^';
189
- for (var partIndex = 0; partIndex != group.length; partIndex++) {
190
- var part = group[partIndex];
191
- var captureCount = 0;
192
- if (part.substring(0, 1) == ':') {
193
- var variableName = part.substring(1);
194
- this.variableNames.push(variableName);
195
- if (this.route.matchingConditions[variableName]) {
196
- pattern += this.route.matchingConditions[variableName].toString();
197
- } else {
198
- pattern += '(.*?)';
199
- }
200
- captureCount += 1;
201
- } else {
202
- pattern += regexEscape_(part);
203
- }
204
- }
205
- currentNode = currentNode.addLinear(new RegExp(pattern), captureCount);
206
- } else if (group.length == 1) {
207
- var part = group[0];
208
- if (part.substring(0, 1) == ':') {
209
- var variableName = part.substring(1);
210
- this.variableNames.push(variableName);
211
- if (this.route.matchingConditions[variableName]) {
212
- var matched = this.route.matchingConditions[variableName];
213
- currentNode = currentNode.addLinear(matched, 1);
214
- } else {
215
- currentNode = currentNode.addCatchall();
216
- }
217
- } else {
218
- currentNode = currentNode.addLookup(part);
219
- }
220
- }
221
- }
222
- var nodes = currentNode.compileRequestConditions(
223
- this.route.router,
224
- this.route.requestConditions
225
- );
226
- for (var nodeIdx = 0; nodeIdx != nodes.length; nodeIdx++) {
227
- nodes[nodeIdx].destination = this;
228
- }
229
- };
230
-
231
- /**
232
- * A Route.
233
- * @constructor
234
- * @param {ww.router.Router} router The parent router.
235
- * @param {String} uri The route uri.
236
- */
237
- ww.router.Route = function Route(router, uri) {
238
- this.router = router;
239
- this.requestConditions = {};
240
- this.matchingConditions = {};
241
- this.variableNames = [];
242
- var paths = [''];
243
- var chars = uri.split('');
244
-
245
- var startIndex = 0;
246
- var endIndex = 1;
247
-
248
- for (var charIndex = 0; charIndex < chars.length; charIndex++) {
249
- var c = chars[charIndex];
250
- if (c == '(') {
251
- // over current working set, double paths
252
- for (var pathIndex = startIndex; pathIndex != endIndex; pathIndex++) {
253
- paths.push(paths[pathIndex]);
254
- }
255
- // move working set to newly copied paths
256
- startIndex = endIndex;
257
- endIndex = paths.length;
258
- } else if (c == ')') {
259
- // expand working set scope
260
- startIndex -= (endIndex - startIndex);
261
- } else {
262
- for (var i = startIndex; i != endIndex; i++) {
263
- paths[i] += c;
264
- }
265
- }
266
- }
267
-
268
- this.partial = false;
269
- this.paths = [];
270
- for (var pathsIdx = 0; pathsIdx != paths.length; pathsIdx++) {
271
- this.paths.push(new ww.router.Path(this, paths[pathsIdx]));
272
- }
273
- };
274
-
275
- /**
276
- * Set options on this route.
277
- * @param {Object} options The route options.
278
- * @return {ww.router.route} This router, for chaining.
279
- */
280
- ww.router.Route.prototype.withOptions = function routeWithOptions(options) {
281
- if (options['conditions']) {
282
- this.condition(options['conditions']);
283
- }
284
- if (options['matchesWith']) {
285
- this.matchesWith(options['matchesWith']);
286
- }
287
- if (options['matchPartially']) {
288
- this.matchPartially(options['matchPartially']);
289
- }
290
- if (options['name']) {
291
- this.matchPartially(options['name']);
292
- }
293
- return this;
294
- };
295
-
296
- /**
297
- * Set name on this route.
298
- * @param {String} routeName The route's name.
299
- * @return {ww.router.route} This router, for chaining.
300
- */
301
- ww.router.Route.prototype.name = function routeName(routeName) {
302
- this.router.routes[routeName] = this;
303
- return this;
304
- };
305
-
306
- /**
307
- * Whether the route matches partially.
308
- * @param {Boolena} partial The partial.
309
- * @return {ww.router.route} This router, for chaining.
310
- */
311
- ww.router.Route.prototype.matchPartially = function routeMatchPartial(partial) {
312
- this.partial = (partial === undefined || partial === true);
313
- return this;
314
- };
315
-
316
- /**
317
- * Set route matches.
318
- * @param {Object} matches Match keys.
319
- * @return {ww.router.route} This router, for chaining.
320
- */
321
- ww.router.Route.prototype.matchesWith = function routeMatchesWith(matches) {
322
- for (var matchesKey in matches) {
323
- this.matchingConditions[matchesKey] = matches[matchesKey];
324
- }
325
- return this;
326
- };
327
-
328
- /**
329
- * Compile route.
330
- */
331
- ww.router.Route.prototype.compile = function routeCompile() {
332
- for (var pathIdx = 0; pathIdx != this.paths.length; pathIdx++) {
333
- this.paths[pathIdx].compile();
334
- var varNames = this.paths[pathIdx].variableNames;
335
- for (var variableIdx = 0; variableIdx != varNames.length; variableIdx++) {
336
- if (goog.array.indexOf(this.variableNames, varNames[variableIdx]) == -1) {
337
- this.variableNames.push(varNames[variableIdx]);
338
- }
339
- }
340
- }
341
- };
342
-
343
- /**
344
- * Set route destination.
345
- * @param {String} destination The destination.
346
- * @return {ww.router.route} This router, for chaining.
347
- */
348
- ww.router.Route.prototype.to = function routeTo(destination) {
349
- this.compile();
350
- this.destination = destination;
351
- return this;
352
- };
353
-
354
- /**
355
- * Set conditions on this route.
356
- * @param {Object} conditions The route conditions.
357
- * @return {ww.router.route} This router, for chaining.
358
- */
359
- ww.router.Route.prototype.condition = function routeCondition(conditions) {
360
- for (var conditionKey in conditions) {
361
- this.requestConditions[conditionKey] = conditions[conditionKey];
362
- }
363
- return this;
364
- };
365
-
366
- /**
367
- * Generate a URL from this route.
368
- * @param {Object} params The route params.
369
- * @return {String} The URL.
370
- */
371
- ww.router.Route.prototype.generate = function routeGenerate(params) {
372
- var path = undefined;
373
- if (params == undefined || this.paths.length == 1) {
374
- path = this.paths[0].generate(params);
375
- } else {
376
- for (var pathIdx = this.paths.length - 1; pathIdx >= 0; pathIdx--) {
377
- path = this.paths[pathIdx].generate(params);
378
- if (path) break;
379
- }
380
- }
381
-
382
- if (path) {
383
- path = encodeURI(path);
384
- var query = '';
385
- for (var key in params) {
386
- query += (query == '' ? '?' : '&');
387
- query += encodeURIComponent(key).replace(/%20/g, '+') + '=';
388
- query += encodeURIComponent(params[key]).replace(/%20/g, '+');
389
- }
390
- return path + query;
391
- } else {
392
- return undefined;
393
- }
394
- };
395
-
396
- /**
397
- * A Router Node.
398
- * @constructor
399
- */
400
- ww.router.Node = function Node() {
401
- this.reset();
402
- };
403
-
404
- /**
405
- * Reset the node.
406
- */
407
- ww.router.Node.prototype.reset = function nodeReset() {
408
- this.linear = [];
409
- this.lookup = {};
410
- this.catchall = null;
411
- };
412
-
413
- /**
414
- * Duplicate the node.
415
- * @return {ww.router.Node} The duplicated node.
416
- */
417
- ww.router.Node.prototype.dup = function nodeDup() {
418
- var newNode = new ww.router.Node();
419
- for (var idx = 0; idx != this.linear.length; idx++) {
420
- newNode.linear.push(this.linear[idx]);
421
- }
422
- for (var key in this.lookup) {
423
- newNode.lookup[key] = this.lookup[key];
424
- }
425
- newNode.catchall = this.catchall;
426
- return newNode;
427
- };
428
-
429
- /**
430
- * Add a linear to this node.
431
- * @param {RegExp} regex The regex.
432
- * @param {Number} count The count.
433
- * @return {ww.router.Node} The new node.
434
- */
435
- ww.router.Node.prototype.addLinear = function nodeAddLinear(regex, count) {
436
- var newNode = new ww.router.Node();
437
- this.linear.push([regex, count, newNode]);
438
- return newNode;
439
- };
440
-
441
- /**
442
- * Add a catchall to this node.
443
- * @return {ww.router.Node} Catchall node.
444
- */
445
- ww.router.Node.prototype.addCatchall = function nodeAddCatchall() {
446
- if (!this.catchall) {
447
- this.catchall = new ww.router.Node();
448
- }
449
- return this.catchall;
450
- };
451
-
452
- /**
453
- * Add lookup to this node.
454
- * @param {String} part Lookup name.
455
- * @return {ww.router.Node} The lookup node.
456
- */
457
- ww.router.Node.prototype.addLookup = function nodeAddLookup(part) {
458
- if (!this.lookup[part]) {
459
- this.lookup[part] = new ww.router.Node();
460
- }
461
- return this.lookup[part];
462
- };
463
-
464
- /**
465
- * Add a request node.
466
- * @return {ww.router.Node} The request node.
467
- */
468
- ww.router.Node.prototype.addRequestNode = function nodeAddRequestNode() {
469
- if (!this.requestNode) {
470
- this.requestNode = new ww.router.Node();
471
- this.requestNode.requestMethod = null;
472
- }
473
- return this.requestNode;
474
- };
475
-
476
- /**
477
- * Find a node.
478
- * @param {Array} parts Node parts.
479
- * @param {Request} request The request.
480
- * @param {Object} params Find params.
481
- * @return {ww.router.Response} The found response.
482
- */
483
- ww.router.Node.prototype.find = function nodeFind(parts, request, params) {
484
- if (this.requestNode || this.destination && this.destination.route.partial) {
485
- var target = this;
486
- if (target.requestNode) {
487
- target = target.requestNode.findRequest(request);
488
- }
489
- if (target && target.destination && target.destination.route.partial) {
490
- return new ww.router.Response(target.destination, params);
491
- }
492
- }
493
- if (parts.length == 0) {
494
- var target = this;
495
- if (this.requestNode) {
496
- target = this.requestNode.findRequest(request);
497
- }
498
- if (target && target.destination) {
499
- return new ww.router.Response(target.destination, params);
500
- } else {
501
- return undefined;
502
- }
503
- } else {
504
- if (this.linear.length != 0) {
505
- var wholePath = parts.join('/');
506
- for (var linearIdx = 0; linearIdx != this.linear.length; linearIdx++) {
507
- var lin = this.linear[linearIdx];
508
- var match = lin[0].exec(wholePath);
509
- if (match) {
510
- var matchedParams = [];
511
- if (match[1] === undefined) {
512
- matchedParams.push(match[0]);
513
- } else {
514
- for (var matchIdx = 1; matchIdx <= lin[1] + 1; matchIdx++) {
515
- matchedParams.push(match[matchIdx]);
516
- }
517
- }
518
-
519
- var newParams = params.concat(matchedParams);
520
- matchedIndex = match.shift().length;
521
- var resplitParts = wholePath.substring(matchedIndex).split('/');
522
- if (resplitParts.length == 1 && resplitParts[0] == '') {
523
- resplitParts.shift();
524
- }
525
- var potentialMatch = lin[2].find(resplitParts, request, newParams);
526
- if (potentialMatch) return potentialMatch;
527
- }
528
- }
529
- }
530
- if (this.lookup[parts[0]]) {
531
- var potentialMatch = this.lookup[parts[0]].find(
532
- parts.slice(1, parts.length),
533
- request,
534
- params
535
- );
536
- if (potentialMatch) return potentialMatch;
537
- }
538
- if (this.catchall) {
539
- var part = parts.shift();
540
- params.push(part);
541
- return this.catchall.find(parts, request, params);
542
- }
543
- }
544
- return undefined;
545
- };
546
-
547
- /**
548
- * Find the request.
549
- * @param {Request} request The request.
550
- * @return {ww.router.Node} The found node.
551
- */
552
- ww.router.Node.prototype.findRequest = function nodeFindRequest(request) {
553
- if (this.requestMethod) {
554
- if (this.linear.length != 0 && request[this.requestMethod]) {
555
- for (var linearIdx = 0; linearIdx != this.linear.length; linearIdx++) {
556
- var lin = this.linear[linearIdx];
557
- var match = lin[0].exec(request[this.requestMethod]);
558
- if (match) {
559
- matchedIndex = match.shift().length;
560
- var potentialMatch = lin[2].findRequest(request);
561
- if (potentialMatch) return potentialMatch;
562
- }
563
- }
564
- }
565
- var foundMeth = this.lookup[request[this.requestMethod]];
566
- if (request[this.requestMethod] && foundMeth) {
567
- var potentialMatch = foundMeth.findRequest(request);
568
- if (potentialMatch) {
569
- return potentialMatch;
570
- }
571
- }
572
- if (this.catchall) {
573
- return this.catchall.findRequest(request);
574
- }
575
- } else if (this.destination) {
576
- return this;
577
- } else {
578
- return undefined;
579
- }
580
- };
581
-
582
- /**
583
- * Transplant the value.
584
- */
585
- ww.router.Node.prototype.transplantValue = function nodeTransplantValue() {
586
- if (this.destination && this.requestNode) {
587
- var targetNode = this.requestNode;
588
- while (targetNode.requestMethod) {
589
- targetNode = (targetNode.addCatchall());
590
- }
591
- targetNode.destination = this.destination;
592
- this.destination = undefined;
593
- }
594
- };
595
-
596
- /**
597
- * Compile request conditions.
598
- * @param {ww.router.Router} router The router.
599
- * @param {Object} reqConds The request conditions.
600
- * @return {Array} The current nodes.
601
- */
602
- ww.router.Node.prototype.compileRequestConditions =
603
- function nodeCompileReqConds(router, reqConds) {
604
- var cNodes = [this];
605
- var reqMeths = router.requestKeys;
606
- for (var requestMethodIdx in reqMeths) {
607
- var method = reqMeths[requestMethodIdx];
608
- // so, the request method we care about it ..
609
- if (reqConds[method]) {
610
- if (cNodes.length == 1 && cNodes[0] === this) {
611
- cNodes = [this.addRequestNode()];
612
- }
613
-
614
- for (var cNodeIndex = 0; cNodeIndex != cNodes.length; cNodeIndex++) {
615
- var cNode = cNodes[cNodeIndex];
616
- if (!cNode.requestMethod) {
617
- cNode.requestMethod = method;
618
- }
619
-
620
- var masterPosition = goog.array.indexOf(reqMeths, method);
621
- var currentPosition = goog.array.indexOf(
622
- reqMeths,
623
- cNode.requestMethod
624
- );
625
-
626
- if (masterPosition == currentPosition) {
627
- if (reqConds[method].compile) {
628
- cNodes[cNodeIndex] = cNodes[cNodeIndex].addLinear(
629
- reqConds[method],
630
- 0
631
- );
632
- } else {
633
- cNodes[cNodeIndex] = cNodes[cNodeIndex].addLookup(
634
- reqConds[method]
635
- );
636
- }
637
- } else if (masterPosition < currentPosition) {
638
- cNodes[cNodeIndex] = cNodes[cNodeIndex].addCatchall();
639
- } else {
640
- var nextNode = cNode.dup();
641
- cNode.reset();
642
- cNode.requestMethod = method;
643
- cNode.catchall = nextNode;
644
- cNodeIndex--;
645
- }
646
- }
647
- } else {
648
- for (var cNodeIndex = 0; cNodeIndex != cNodes.length; cNodeIndex++) {
649
- var node = cNodes[cNodeIndex];
650
- if (!node.requestMethod && node.requestNode) {
651
- node = node.requestNode;
652
- }
653
- if (node.requestMethod) {
654
- cNodes[cNodeIndex] = node.addCatchall();
655
- cNodes[cNodeIndex].requestMethod = null;
656
- }
657
- }
658
- }
659
- }
660
- this.transplantValue();
661
- return cNodes;
662
- };
663
-
664
- /**
665
- * A Router response.
666
- * @constructor
667
- * @param {String} path The response path.
668
- * @param {Object} params Additional options.
669
- */
670
- ww.router.Response = function Response(path, params) {
671
- this.path = path;
672
- this.route = path.route;
673
- this.paramsArray = params;
674
- this.destination = this.route.destination;
675
- this.params = {};
676
- for (var varIdx = 0; varIdx != this.path.variableNames.length; varIdx++) {
677
- this.params[this.path.variableNames[varIdx]] = this.paramsArray[varIdx];
678
- }
679
- };