middleman-wizard-template 1.0.2 → 1.0.3

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.
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;