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
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Loader plugin to load swiffy.
3
+ * @constructor
4
+ * @param {String} name Name of the Swiffy.
5
+ * @param {Array} tags Array of tag names.
6
+ * @param {Number} priority Load order.
7
+ */
8
+ ww.LoaderSwiffy = function LoaderSwiffy(name, tags, priority) {
9
+ var self = this,
10
+ loader = null,
11
+ complete = false;
12
+
13
+ this.tags = tags;
14
+ this.priority = priority;
15
+ var data = null;
16
+
17
+ this.start = function(pxloader) {
18
+ // we need the loader ref so we can notify upon completion
19
+ loader = pxloader;
20
+
21
+ var xhr = new XMLHttpRequest();
22
+ xhr.open('GET', name, false);
23
+ xhr.onreadystatechange = function() {
24
+ if (xhr['readyState'] !== 4) { return; }
25
+ if (xhr['status'] !== 200) {
26
+ loader.onError(self);
27
+ return;
28
+ }
29
+
30
+ var serverResponse = xhr['responseText'];
31
+ try {
32
+ data = JSON.parse(serverResponse);
33
+ loader.onLoad(self);
34
+ } catch (e) {
35
+ loader.onError(self);
36
+ }
37
+ }
38
+ xhr.send(null);
39
+ };
40
+
41
+ // called by ww.Loader to check status of image (fallback in case
42
+ // the event listeners are not triggered).
43
+ this.checkStatus = function() {
44
+ if (complete) {
45
+ loader.onLoad(self);
46
+ }
47
+ };
48
+
49
+ // called by ww.Loader when it is no longer waiting
50
+ this.onTimeout = function() {
51
+ if (complete) {
52
+ loader.onLoad(self);
53
+ } else {
54
+ loader.onTimeout(self);
55
+ }
56
+ };
57
+
58
+ // returns a name for the resource that can be used in logging
59
+ this.getName = function() {
60
+ return name;
61
+ };
62
+
63
+ this.getData = function() {
64
+ return data;
65
+ }
66
+ };
67
+
68
+ goog.exportSymbol('ww.LoaderSwiffy', ww.LoaderSwiffy);
@@ -0,0 +1,506 @@
1
+ goog.provide('ww.RouteRecognizer');
2
+
3
+ var specials = [
4
+ '/', '.', '*', '+', '?', '|',
5
+ '(', ')', '[', ']', '{', '}', '\\'
6
+ ];
7
+
8
+ var escapeRegex = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
9
+
10
+ // A Segment represents a segment in the original route description.
11
+ // Each Segment type provides an `eachChar` and `regex` method.
12
+ //
13
+ // The `eachChar` method invokes the callback with one or more character
14
+ // specifications. A character specification consumes one or more input
15
+ // characters.
16
+ //
17
+ // The `regex` method returns a regex fragment for the segment. If the
18
+ // segment is a dynamic of star segment, the regex fragment also includes
19
+ // a capture.
20
+ //
21
+ // A character specification contains:
22
+ //
23
+ // * `validChars`: a String with a list of all valid characters, or
24
+ // * `invalidChars`: a String with a list of all invalid characters
25
+ // * `repeat`: true if the character specification can repeat
26
+
27
+ function StaticSegment(string) { this.string = string; }
28
+ StaticSegment.prototype = {
29
+ eachChar: function(callback) {
30
+ var string = this.string, char;
31
+
32
+ for (var i=0, l=string.length; i<l; i++) {
33
+ char = string.charAt(i);
34
+ callback({ validChars: char });
35
+ }
36
+ },
37
+
38
+ regex: function() {
39
+ return this.string.replace(escapeRegex, '\\$1');
40
+ },
41
+
42
+ generate: function() {
43
+ return this.string;
44
+ }
45
+ };
46
+
47
+ function DynamicSegment(name) { this.name = name; }
48
+ DynamicSegment.prototype = {
49
+ eachChar: function(callback) {
50
+ callback({ invalidChars: "/", repeat: true });
51
+ },
52
+
53
+ regex: function() {
54
+ return "([^/]+)";
55
+ },
56
+
57
+ generate: function(params) {
58
+ return params[this.name];
59
+ }
60
+ };
61
+
62
+ function StarSegment(name) { this.name = name; }
63
+ StarSegment.prototype = {
64
+ eachChar: function(callback) {
65
+ callback({ invalidChars: "", repeat: true });
66
+ },
67
+
68
+ regex: function() {
69
+ return "(.+)";
70
+ },
71
+
72
+ generate: function(params) {
73
+ return params[this.name];
74
+ }
75
+ };
76
+
77
+ function EpsilonSegment() {}
78
+ EpsilonSegment.prototype = {
79
+ eachChar: function() {},
80
+ regex: function() { return ""; },
81
+ generate: function() { return ""; }
82
+ };
83
+
84
+ function parse(route, names, types) {
85
+ // normalize route as not starting with a "/". Recognition will
86
+ // also normalize.
87
+ if (route.charAt(0) === "/") { route = route.substr(1); }
88
+
89
+ var segments = route.split("/"), results = [];
90
+
91
+ for (var i=0, l=segments.length; i<l; i++) {
92
+ var segment = segments[i], match;
93
+
94
+ if (match = segment.match(/^:([^\/]+)$/)) {
95
+ results.push(new DynamicSegment(match[1]));
96
+ names.push(match[1]);
97
+ types.dynamics++;
98
+ } else if (match = segment.match(/^\*([^\/]+)$/)) {
99
+ results.push(new StarSegment(match[1]));
100
+ names.push(match[1]);
101
+ types.stars++;
102
+ } else if(segment === "") {
103
+ results.push(new EpsilonSegment());
104
+ } else {
105
+ results.push(new StaticSegment(segment));
106
+ types.statics++;
107
+ }
108
+ }
109
+
110
+ return results;
111
+ }
112
+
113
+ // A State has a character specification and (`charSpec`) and a list of possible
114
+ // subsequent states (`nextStates`).
115
+ //
116
+ // If a State is an accepting state, it will also have several additional
117
+ // properties:
118
+ //
119
+ // * `regex`: A regular expression that is used to extract parameters from paths
120
+ // that reached this accepting state.
121
+ // * `handlers`: Information on how to convert the list of captures into calls
122
+ // to registered handlers with the specified parameters
123
+ // * `types`: How many static, dynamic or star segments in this route. Used to
124
+ // decide which route to use if multiple registered routes match a path.
125
+ //
126
+ // Currently, State is implemented naively by looping over `nextStates` and
127
+ // comparing a character specification against a character. A more efficient
128
+ // implementation would use a hash of keys pointing at one or more next states.
129
+
130
+ function State(charSpec) {
131
+ this.charSpec = charSpec;
132
+ this.nextStates = [];
133
+ }
134
+
135
+ State.prototype = {
136
+ get: function(charSpec) {
137
+ var nextStates = this.nextStates;
138
+
139
+ for (var i=0, l=nextStates.length; i<l; i++) {
140
+ var child = nextStates[i];
141
+
142
+ var isEqual = child.charSpec.validChars === charSpec.validChars;
143
+ isEqual = isEqual && child.charSpec.invalidChars === charSpec.invalidChars;
144
+
145
+ if (isEqual) { return child; }
146
+ }
147
+ },
148
+
149
+ put: function(charSpec) {
150
+ var state;
151
+
152
+ // If the character specification already exists in a child of the current
153
+ // state, just return that state.
154
+ if (state = this.get(charSpec)) { return state; }
155
+
156
+ // Make a new state for the character spec
157
+ state = new State(charSpec);
158
+
159
+ // Insert the new state as a child of the current state
160
+ this.nextStates.push(state);
161
+
162
+ // If this character specification repeats, insert the new state as a child
163
+ // of itself. Note that this will not trigger an infinite loop because each
164
+ // transition during recognition consumes a character.
165
+ if (charSpec.repeat) {
166
+ state.nextStates.push(state);
167
+ }
168
+
169
+ // Return the new state
170
+ return state;
171
+ },
172
+
173
+ // Find a list of child states matching the next character
174
+ match: function(char) {
175
+ // DEBUG "Processing `" + char + "`:"
176
+ var nextStates = this.nextStates,
177
+ child, charSpec, chars;
178
+
179
+ // DEBUG " " + debugState(this)
180
+ var returned = [];
181
+
182
+ for (var i=0, l=nextStates.length; i<l; i++) {
183
+ child = nextStates[i];
184
+
185
+ charSpec = child.charSpec;
186
+
187
+ if (typeof (chars = charSpec.validChars) !== 'undefined') {
188
+ if (chars.indexOf(char) !== -1) { returned.push(child); }
189
+ } else if (typeof (chars = charSpec.invalidChars) !== 'undefined') {
190
+ if (chars.indexOf(char) === -1) { returned.push(child); }
191
+ }
192
+ }
193
+
194
+ return returned;
195
+ }
196
+
197
+ /** IF DEBUG
198
+ , debug: function() {
199
+ var charSpec = this.charSpec,
200
+ debug = "[",
201
+ chars = charSpec.validChars || charSpec.invalidChars;
202
+
203
+ if (charSpec.invalidChars) { debug += "^"; }
204
+ debug += chars;
205
+ debug += "]";
206
+
207
+ if (charSpec.repeat) { debug += "+"; }
208
+
209
+ return debug;
210
+ }
211
+ END IF **/
212
+ };
213
+
214
+ /** IF DEBUG
215
+ function debug(log) {
216
+ console.log(log);
217
+ }
218
+
219
+ function debugState(state) {
220
+ return state.nextStates.map(function(n) {
221
+ if (n.nextStates.length === 0) { return "( " + n.debug() + " [accepting] )"; }
222
+ return "( " + n.debug() + " <then> " + n.nextStates.map(function(s) { return s.debug() }).join(" or ") + " )";
223
+ }).join(", ")
224
+ }
225
+ END IF **/
226
+
227
+ // This is a somewhat naive strategy, but should work in a lot of cases
228
+ // A better strategy would properly resolve /posts/:id/new and /posts/edit/:id
229
+ function sortSolutions(states) {
230
+ return states.sort(function(a, b) {
231
+ if (a.types.stars !== b.types.stars) { return a.types.stars - b.types.stars; }
232
+ if (a.types.dynamics !== b.types.dynamics) { return a.types.dynamics - b.types.dynamics; }
233
+ if (a.types.statics !== b.types.statics) { return a.types.statics - b.types.statics; }
234
+
235
+ return 0;
236
+ });
237
+ }
238
+
239
+ function recognizeChar(states, char) {
240
+ var nextStates = [];
241
+
242
+ for (var i=0, l=states.length; i<l; i++) {
243
+ var state = states[i];
244
+
245
+ nextStates = nextStates.concat(state.match(char));
246
+ }
247
+
248
+ return nextStates;
249
+ }
250
+
251
+ function findHandler(state, path) {
252
+ var handlers = state.handlers, regex = state.regex;
253
+ var captures = path.match(regex), currentCapture = 1;
254
+ var result = [];
255
+
256
+ for (var i=0, l=handlers.length; i<l; i++) {
257
+ var handler = handlers[i], names = handler.names, params = {};
258
+
259
+ for (var j=0, m=names.length; j<m; j++) {
260
+ params[names[j]] = captures[currentCapture++];
261
+ }
262
+
263
+ result.push({ handler: handler.handler, params: params, isDynamic: !!names.length });
264
+ }
265
+
266
+ return result;
267
+ }
268
+
269
+ function addSegment(currentState, segment) {
270
+ segment.eachChar(function(char) {
271
+ var state;
272
+
273
+ currentState = currentState.put(char);
274
+ });
275
+
276
+ return currentState;
277
+ }
278
+
279
+ // The main interface
280
+
281
+ var RouteRecognizer = function() {
282
+ this.rootState = new State();
283
+ this.names = {};
284
+ };
285
+
286
+
287
+ RouteRecognizer.prototype = {
288
+ add: function(routes, options) {
289
+ var currentState = this.rootState, regex = "^",
290
+ types = { statics: 0, dynamics: 0, stars: 0 },
291
+ handlers = [], allSegments = [], name;
292
+
293
+ var isEmpty = true;
294
+
295
+ for (var i=0, l=routes.length; i<l; i++) {
296
+ var route = routes[i], names = [];
297
+
298
+ var segments = parse(route.path, names, types);
299
+
300
+ allSegments = allSegments.concat(segments);
301
+
302
+ for (var j=0, m=segments.length; j<m; j++) {
303
+ var segment = segments[j];
304
+
305
+ if (segment instanceof EpsilonSegment) { continue; }
306
+
307
+ isEmpty = false;
308
+
309
+ // Add a "/" for the new segment
310
+ currentState = currentState.put({ validChars: "/" });
311
+ regex += "/";
312
+
313
+ // Add a representation of the segment to the NFA and regex
314
+ currentState = addSegment(currentState, segment);
315
+ regex += segment.regex();
316
+ }
317
+
318
+ handlers.push({ handler: route.handler, names: names });
319
+ }
320
+
321
+ if (isEmpty) {
322
+ currentState = currentState.put({ validChars: "/" });
323
+ regex += "/";
324
+ }
325
+
326
+ currentState.handlers = handlers;
327
+ currentState.regex = new RegExp(regex + "$");
328
+ currentState.types = types;
329
+
330
+ if (name = options && options.as) {
331
+ this.names[name] = {
332
+ segments: allSegments,
333
+ handlers: handlers
334
+ };
335
+ }
336
+ },
337
+
338
+ handlersFor: function(name) {
339
+ var route = this.names[name], result = [];
340
+ if (!route) { throw new Error("There is no route named " + name); }
341
+
342
+ for (var i=0, l=route.handlers.length; i<l; i++) {
343
+ result.push(route.handlers[i]);
344
+ }
345
+
346
+ return result;
347
+ },
348
+
349
+ hasRoute: function(name) {
350
+ return !!this.names[name];
351
+ },
352
+
353
+ generate: function(name, params) {
354
+ var route = this.names[name], output = "";
355
+ if (!route) { throw new Error("There is no route named " + name); }
356
+
357
+ var segments = route.segments;
358
+
359
+ for (var i=0, l=segments.length; i<l; i++) {
360
+ var segment = segments[i];
361
+
362
+ if (segment instanceof EpsilonSegment) { continue; }
363
+
364
+ output += "/";
365
+ output += segment.generate(params);
366
+ }
367
+
368
+ if (output.charAt(0) !== '/') { output = '/' + output; }
369
+
370
+ return output;
371
+ },
372
+
373
+ recognize: function(path) {
374
+ var states = [ this.rootState ],
375
+ pathLen, i, l;
376
+
377
+ // DEBUG GROUP path
378
+
379
+ if (path.charAt(0) !== "/") { path = "/" + path; }
380
+
381
+ pathLen = path.length;
382
+ if (pathLen > 1 && path.charAt(pathLen - 1) === "/") {
383
+ path = path.substr(0, pathLen - 1);
384
+ }
385
+
386
+ for (i=0, l=path.length; i<l; i++) {
387
+ states = recognizeChar(states, path.charAt(i));
388
+ if (!states.length) { break; }
389
+ }
390
+
391
+ // END DEBUG GROUP
392
+
393
+ var solutions = [];
394
+ for (i=0, l=states.length; i<l; i++) {
395
+ if (states[i].handlers) { solutions.push(states[i]); }
396
+ }
397
+
398
+ states = sortSolutions(solutions);
399
+
400
+ var state = solutions[0];
401
+
402
+ if (state && state.handlers) {
403
+ return findHandler(state, path);
404
+ }
405
+ }
406
+ };
407
+
408
+ function Target(path, matcher, delegate) {
409
+ this.path = path;
410
+ this.matcher = matcher;
411
+ this.delegate = delegate;
412
+ }
413
+
414
+ Target.prototype = {
415
+ to: function(target, callback) {
416
+ var delegate = this.delegate;
417
+
418
+ if (delegate && delegate.willAddRoute) {
419
+ target = delegate.willAddRoute(this.matcher.target, target);
420
+ }
421
+
422
+ this.matcher.add(this.path, target);
423
+
424
+ if (callback) {
425
+ if (callback.length === 0) { throw new Error("You must have an argument in the function passed to `to`"); }
426
+ this.matcher.addChild(this.path, target, callback, this.delegate);
427
+ }
428
+ }
429
+ };
430
+
431
+ function Matcher(target) {
432
+ this.routes = {};
433
+ this.children = {};
434
+ this.target = target;
435
+ }
436
+
437
+ Matcher.prototype = {
438
+ add: function(path, handler) {
439
+ this.routes[path] = handler;
440
+ },
441
+
442
+ addChild: function(path, target, callback, delegate) {
443
+ var matcher = new Matcher(target);
444
+ this.children[path] = matcher;
445
+
446
+ var match = generateMatch(path, matcher, delegate);
447
+
448
+ if (delegate && delegate.contextEntered) {
449
+ delegate.contextEntered(target, match);
450
+ }
451
+
452
+ callback(match);
453
+ }
454
+ };
455
+
456
+ function generateMatch(startingPath, matcher, delegate) {
457
+ return function(path, nestedCallback) {
458
+ var fullPath = startingPath + path;
459
+
460
+ if (nestedCallback) {
461
+ nestedCallback(generateMatch(fullPath, matcher, delegate));
462
+ } else {
463
+ return new Target(startingPath + path, matcher, delegate);
464
+ }
465
+ };
466
+ }
467
+
468
+ function addRoute(routeArray, path, handler) {
469
+ var len = 0;
470
+ for (var i=0, l=routeArray.length; i<l; i++) {
471
+ len += routeArray[i].path.length;
472
+ }
473
+
474
+ path = path.substr(len);
475
+ routeArray.push({ path: path, handler: handler });
476
+ }
477
+
478
+ function eachRoute(baseRoute, matcher, callback, binding) {
479
+ var routes = matcher.routes;
480
+
481
+ for (var path in routes) {
482
+ if (routes.hasOwnProperty(path)) {
483
+ var routeArray = baseRoute.slice();
484
+ addRoute(routeArray, path, routes[path]);
485
+
486
+ if (matcher.children[path]) {
487
+ eachRoute(routeArray, matcher.children[path], callback, binding);
488
+ } else {
489
+ callback.call(binding, routeArray);
490
+ }
491
+ }
492
+ }
493
+ }
494
+
495
+ RouteRecognizer.prototype.map = function(callback, addRouteCallback) {
496
+ var matcher = new Matcher();
497
+
498
+ callback(generateMatch("", matcher, this.delegate));
499
+
500
+ eachRoute([], matcher, function(route) {
501
+ if (addRouteCallback) { addRouteCallback(this, route); }
502
+ else { this.add(route); }
503
+ }, this);
504
+ };
505
+
506
+ ww.RouteRecognizer = RouteRecognizer;