compass-ratchet 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/README.md +67 -0
  2. data/lib/compass-ratchet.rb +3 -0
  3. data/stylesheets/_compass-ratchet.scss +14 -0
  4. data/stylesheets/compass-ratchet/_bars.scss +330 -0
  5. data/stylesheets/compass-ratchet/_base.scss +155 -0
  6. data/stylesheets/compass-ratchet/_buttons.scss +124 -0
  7. data/stylesheets/compass-ratchet/_chevrons.scss +32 -0
  8. data/stylesheets/compass-ratchet/_counts.scss +42 -0
  9. data/stylesheets/compass-ratchet/_forms.scss +126 -0
  10. data/stylesheets/compass-ratchet/_lists.scss +122 -0
  11. data/stylesheets/compass-ratchet/_popovers.scss +158 -0
  12. data/stylesheets/compass-ratchet/_push.scss +30 -0
  13. data/stylesheets/compass-ratchet/_segmented-controllers.scss +67 -0
  14. data/stylesheets/compass-ratchet/_shared.scss +8 -0
  15. data/stylesheets/compass-ratchet/_sliders.scss +40 -0
  16. data/stylesheets/compass-ratchet/_toggles.scss +71 -0
  17. data/templates/project/checkout.html +81 -0
  18. data/templates/project/choose-movie.html +125 -0
  19. data/templates/project/choose-theater.html +110 -0
  20. data/templates/project/config.rb +8 -0
  21. data/templates/project/css/app.css +1 -0
  22. data/templates/project/img/argo.png +0 -0
  23. data/templates/project/img/ralph.png +0 -0
  24. data/templates/project/img/skyfall.png +0 -0
  25. data/templates/project/index.html +160 -0
  26. data/templates/project/js/popovers.js +63 -0
  27. data/templates/project/js/push.js +417 -0
  28. data/templates/project/js/segmented-controllers.js +47 -0
  29. data/templates/project/js/sliders.js +114 -0
  30. data/templates/project/js/toggles.js +94 -0
  31. data/templates/project/manifest.rb +24 -0
  32. data/templates/project/sass/app.scss +13 -0
  33. data/templates/project/settings.html +73 -0
  34. data/templates/project/theaters.html +131 -0
  35. metadata +111 -0
@@ -0,0 +1,417 @@
1
+ /* ----------------------------------
2
+ * PUSH v1.0.0
3
+ * Licensed under The MIT License
4
+ * inspired by chris's jquery.pjax.js
5
+ * http://opensource.org/licenses/MIT
6
+ * ---------------------------------- */
7
+
8
+ !function () {
9
+
10
+ var noop = function () {};
11
+
12
+
13
+ // Pushstate cacheing
14
+ // ==================
15
+
16
+ var isScrolling;
17
+ var maxCacheLength = 20;
18
+ var cacheMapping = sessionStorage;
19
+ var domCache = {};
20
+ var transitionMap = {
21
+ 'slide-in' : 'slide-out',
22
+ 'slide-out' : 'slide-in',
23
+ 'fade' : 'fade'
24
+ };
25
+ var bars = {
26
+ bartab : '.bar-tab',
27
+ bartitle : '.bar-title',
28
+ barfooter : '.bar-footer',
29
+ barheadersecondary : '.bar-header-secondary'
30
+ }
31
+
32
+ var cacheReplace = function (data, updates) {
33
+ PUSH.id = data.id;
34
+ if (updates) data = getCached(data.id);
35
+ cacheMapping[data.id] = JSON.stringify(data);
36
+ window.history.replaceState(data.id, data.title, data.url);
37
+ domCache[data.id] = document.body.cloneNode(true);
38
+ };
39
+
40
+ var cachePush = function () {
41
+ var id = PUSH.id;
42
+
43
+ var cacheForwardStack = JSON.parse(cacheMapping.cacheForwardStack || '[]');
44
+ var cacheBackStack = JSON.parse(cacheMapping.cacheBackStack || '[]');
45
+
46
+ cacheBackStack.push(id);
47
+
48
+ while (cacheForwardStack.length) delete cacheMapping[cacheForwardStack.shift()];
49
+ while (cacheBackStack.length > maxCacheLength) delete cacheMapping[cacheBackStack.shift()];
50
+
51
+ window.history.pushState(null, '', cacheMapping[PUSH.id].url);
52
+
53
+ cacheMapping.cacheForwardStack = JSON.stringify(cacheForwardStack);
54
+ cacheMapping.cacheBackStack = JSON.stringify(cacheBackStack);
55
+ };
56
+
57
+ var cachePop = function (id, direction) {
58
+ var forward = direction == 'forward';
59
+ var cacheForwardStack = JSON.parse(cacheMapping.cacheForwardStack || '[]');
60
+ var cacheBackStack = JSON.parse(cacheMapping.cacheBackStack || '[]');
61
+ var pushStack = forward ? cacheBackStack : cacheForwardStack;
62
+ var popStack = forward ? cacheForwardStack : cacheBackStack;
63
+
64
+ if (PUSH.id) pushStack.push(PUSH.id);
65
+ popStack.pop();
66
+
67
+ cacheMapping.cacheForwardStack = JSON.stringify(cacheForwardStack);
68
+ cacheMapping.cacheBackStack = JSON.stringify(cacheBackStack);
69
+ };
70
+
71
+ var getCached = function (id) {
72
+ return JSON.parse(cacheMapping[id] || null) || {};
73
+ };
74
+
75
+ var getTarget = function (e) {
76
+ var target = findTarget(e.target);
77
+
78
+ if (
79
+ ! target
80
+ || e.which > 1
81
+ || e.metaKey
82
+ || e.ctrlKey
83
+ || isScrolling
84
+ || location.protocol !== target.protocol
85
+ || location.host !== target.host
86
+ || !target.hash && /#/.test(target.href)
87
+ || target.hash && target.href.replace(target.hash, '') === location.href.replace(location.hash, '')
88
+ || target.getAttribute('data-ignore') == 'push'
89
+ ) return;
90
+
91
+ return target;
92
+ };
93
+
94
+
95
+ // Main event handlers (touchend, popstate)
96
+ // ==========================================
97
+
98
+ var touchend = function (e) {
99
+ var target = getTarget(e);
100
+
101
+ if (!target) return;
102
+
103
+ e.preventDefault();
104
+
105
+ PUSH({
106
+ url : target.href,
107
+ hash : target.hash,
108
+ timeout : target.getAttribute('data-timeout'),
109
+ transition : target.getAttribute('data-transition')
110
+ });
111
+ };
112
+
113
+ var popstate = function (e) {
114
+ var key;
115
+ var barElement;
116
+ var activeObj;
117
+ var activeDom;
118
+ var direction;
119
+ var transition;
120
+ var transitionFrom;
121
+ var transitionFromObj;
122
+ var id = e.state;
123
+
124
+ if (!id || !cacheMapping[id]) return;
125
+
126
+ direction = PUSH.id < id ? 'forward' : 'back';
127
+
128
+ cachePop(id, direction);
129
+
130
+ activeObj = getCached(id);
131
+ activeDom = domCache[id];
132
+
133
+ if (activeObj.title) document.title = activeObj.title;
134
+
135
+ if (direction == 'back') {
136
+ transitionFrom = JSON.parse(direction == 'back' ? cacheMapping.cacheForwardStack : cacheMapping.cacheBackStack);
137
+ transitionFromObj = getCached(transitionFrom[transitionFrom.length - 1]);
138
+ } else {
139
+ transitionFromObj = activeObj;
140
+ }
141
+
142
+ if (direction == 'back' && !transitionFromObj.id) return PUSH.id = id;
143
+
144
+ transition = direction == 'back' ? transitionMap[transitionFromObj.transition] : transitionFromObj.transition;
145
+
146
+ if (!activeDom) {
147
+ return PUSH({
148
+ id : activeObj.id,
149
+ url : activeObj.url,
150
+ title : activeObj.title,
151
+ timeout : activeObj.timeout,
152
+ transition : transition,
153
+ ignorePush : true
154
+ });
155
+ }
156
+
157
+ if (transitionFromObj.transition) {
158
+ activeObj = extendWithDom(activeObj, '.content', activeDom.cloneNode(true));
159
+ for (key in bars) {
160
+ barElement = document.querySelector(bars[key])
161
+ if (activeObj[key]) swapContent(activeObj[key], barElement);
162
+ else if (barElement) barElement.parentNode.removeChild(barElement);
163
+ }
164
+ }
165
+
166
+ swapContent(
167
+ (activeObj.contents || activeDom).cloneNode(true),
168
+ document.querySelector('.content'),
169
+ transition
170
+ );
171
+
172
+ PUSH.id = id;
173
+
174
+ document.body.offsetHeight; // force reflow to prevent scroll
175
+ };
176
+
177
+
178
+ // Core PUSH functionality
179
+ // =======================
180
+
181
+ var PUSH = function (options) {
182
+ var key;
183
+ var data = {};
184
+ var xhr = PUSH.xhr;
185
+
186
+ options.container = options.container || options.transition ? document.querySelector('.content') : document.body;
187
+
188
+ for (key in bars) {
189
+ options[key] = options[key] || document.querySelector(bars[key]);
190
+ }
191
+
192
+ if (xhr && xhr.readyState < 4) {
193
+ xhr.onreadystatechange = noop;
194
+ xhr.abort()
195
+ }
196
+
197
+ xhr = new XMLHttpRequest();
198
+ xhr.open('GET', options.url, true);
199
+ xhr.setRequestHeader('X-PUSH', 'true');
200
+
201
+ xhr.onreadystatechange = function () {
202
+ if (options._timeout) clearTimeout(options._timeout);
203
+ if (xhr.readyState == 4) xhr.status == 200 ? success(xhr, options) : failure(options.url);
204
+ };
205
+
206
+ if (!PUSH.id) {
207
+ cacheReplace({
208
+ id : +new Date,
209
+ url : window.location.href,
210
+ title : document.title,
211
+ timeout : options.timeout,
212
+ transition : null
213
+ });
214
+ }
215
+
216
+ if (options.timeout) {
217
+ options._timeout = setTimeout(function () { xhr.abort('timeout'); }, options.timeout);
218
+ }
219
+
220
+ xhr.send();
221
+
222
+ if (xhr.readyState && !options.ignorePush) cachePush();
223
+ };
224
+
225
+
226
+ // Main XHR handlers
227
+ // =================
228
+
229
+ var success = function (xhr, options) {
230
+ var key;
231
+ var barElement;
232
+ var data = parseXHR(xhr, options);
233
+
234
+ if (!data.contents) return locationReplace(options.url);
235
+
236
+ if (data.title) document.title = data.title;
237
+
238
+ if (options.transition) {
239
+ for (key in bars) {
240
+ barElement = document.querySelector(bars[key])
241
+ if (data[key]) swapContent(data[key], barElement);
242
+ else if (barElement) barElement.parentNode.removeChild(barElement);
243
+ }
244
+ }
245
+
246
+ swapContent(data.contents, options.container, options.transition, function () {
247
+ cacheReplace({
248
+ id : options.id || +new Date,
249
+ url : data.url,
250
+ title : data.title,
251
+ timeout : options.timeout,
252
+ transition : options.transition
253
+ }, options.id);
254
+ triggerStateChange();
255
+ });
256
+
257
+ if (!options.ignorePush && window._gaq) _gaq.push(['_trackPageview']) // google analytics
258
+ if (!options.hash) return;
259
+ };
260
+
261
+ var failure = function (url) {
262
+ throw new Error('Could not get: ' + url)
263
+ };
264
+
265
+
266
+ // PUSH helpers
267
+ // ============
268
+
269
+ var swapContent = function (swap, container, transition, complete) {
270
+ var enter;
271
+ var containerDirection;
272
+ var swapDirection;
273
+
274
+ if (!transition) {
275
+ if (container) container.innerHTML = swap.innerHTML;
276
+ else if (swap.classList.contains('content')) document.body.appendChild(swap);
277
+ else document.body.insertBefore(swap, document.querySelector('.content'));
278
+ } else {
279
+ enter = /in$/.test(transition);
280
+
281
+ if (transition == 'fade') {
282
+ container.classList.add('in');
283
+ container.classList.add('fade');
284
+ swap.classList.add('fade');
285
+ }
286
+
287
+ if (/slide/.test(transition)) {
288
+ swap.classList.add(enter ? 'right' : 'left');
289
+ swap.classList.add('slide');
290
+ container.classList.add('slide');
291
+ }
292
+
293
+ container.parentNode.insertBefore(swap, container);
294
+ }
295
+
296
+ if (!transition) complete && complete();
297
+
298
+ if (transition == 'fade') {
299
+ container.offsetWidth; // force reflow
300
+ container.classList.remove('in');
301
+ container.addEventListener('webkitTransitionEnd', fadeContainerEnd);
302
+
303
+ function fadeContainerEnd() {
304
+ container.removeEventListener('webkitTransitionEnd', fadeContainerEnd);
305
+ swap.classList.add('in');
306
+ swap.addEventListener('webkitTransitionEnd', fadeSwapEnd);
307
+ }
308
+ function fadeSwapEnd () {
309
+ swap.removeEventListener('webkitTransitionEnd', fadeSwapEnd);
310
+ container.parentNode.removeChild(container);
311
+ swap.classList.remove('fade');
312
+ swap.classList.remove('in');
313
+ complete && complete();
314
+ }
315
+ }
316
+
317
+ if (/slide/.test(transition)) {
318
+ container.offsetWidth; // force reflow
319
+ swapDirection = enter ? 'right' : 'left'
320
+ containerDirection = enter ? 'left' : 'right'
321
+ container.classList.add(containerDirection);
322
+ swap.classList.remove(swapDirection);
323
+ swap.addEventListener('webkitTransitionEnd', slideEnd);
324
+
325
+ function slideEnd() {
326
+ swap.removeEventListener('webkitTransitionEnd', slideEnd);
327
+ swap.classList.remove('slide');
328
+ swap.classList.remove(swapDirection);
329
+ container.parentNode.removeChild(container);
330
+ complete && complete();
331
+ }
332
+ }
333
+ };
334
+
335
+ var triggerStateChange = function () {
336
+ var e = new CustomEvent('push', {
337
+ detail: { state: getCached(PUSH.id) },
338
+ bubbles: true,
339
+ cancelable: true
340
+ });
341
+
342
+ window.dispatchEvent(e);
343
+ };
344
+
345
+ var findTarget = function (target) {
346
+ var i, toggles = document.querySelectorAll('a');
347
+ for (; target && target !== document; target = target.parentNode) {
348
+ for (i = toggles.length; i--;) { if (toggles[i] === target) return target; }
349
+ }
350
+ };
351
+
352
+ var locationReplace = function (url) {
353
+ window.history.replaceState(null, '', '#');
354
+ window.location.replace(url);
355
+ };
356
+
357
+ var parseURL = function (url) {
358
+ var a = document.createElement('a'); a.href = url; return a;
359
+ };
360
+
361
+ var extendWithDom = function (obj, fragment, dom) {
362
+ var i;
363
+ var result = {};
364
+
365
+ for (i in obj) result[i] = obj[i];
366
+
367
+ Object.keys(bars).forEach(function (key) {
368
+ var el = dom.querySelector(bars[key]);
369
+ if (el) el.parentNode.removeChild(el);
370
+ result[key] = el;
371
+ });
372
+
373
+ result.contents = dom.querySelector(fragment);
374
+
375
+ return result;
376
+ };
377
+
378
+ var parseXHR = function (xhr, options) {
379
+ var head;
380
+ var body;
381
+ var data = {};
382
+ var responseText = xhr.responseText;
383
+
384
+ data.url = options.url;
385
+
386
+ if (!responseText) return data;
387
+
388
+ if (/<html/i.test(responseText)) {
389
+ head = document.createElement('div');
390
+ body = document.createElement('div');
391
+ head.innerHTML = responseText.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]
392
+ body.innerHTML = responseText.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]
393
+ } else {
394
+ head = body = document.createElement('div');
395
+ head.innerHTML = responseText;
396
+ }
397
+
398
+ data.title = head.querySelector('title');
399
+ data.title = data.title && data.title.innerText.trim();
400
+
401
+ if (options.transition) data = extendWithDom(data, '.content', body);
402
+ else data.contents = body;
403
+
404
+ return data;
405
+ };
406
+
407
+
408
+ // Attach PUSH event handlers
409
+ // ==========================
410
+
411
+ window.addEventListener('touchstart', function () { isScrolling = false; });
412
+ window.addEventListener('touchmove', function () { isScrolling = true; })
413
+ window.addEventListener('touchend', touchend);
414
+ window.addEventListener('click', function (e) { if (getTarget(e)) e.preventDefault(); });
415
+ window.addEventListener('popstate', popstate);
416
+
417
+ }();
@@ -0,0 +1,47 @@
1
+ /* ----------------------------------
2
+ * TABS v1.0.0
3
+ * Licensed under The MIT License
4
+ * http://opensource.org/licenses/MIT
5
+ * ---------------------------------- */
6
+
7
+ !function () {
8
+ var getTarget = function (target) {
9
+ var i, popovers = document.querySelectorAll('.segmented-controller li a');
10
+ for (; target && target !== document; target = target.parentNode) {
11
+ for (i = popovers.length; i--;) { if (popovers[i] === target) return target; }
12
+ }
13
+ };
14
+
15
+ window.addEventListener("touchend", function (e) {
16
+ var activeTab;
17
+ var activeBody;
18
+ var targetBody;
19
+ var targetTab;
20
+ var className = 'active';
21
+ var classSelector = '.' + className;
22
+ var targetAnchor = getTarget(e.target);
23
+
24
+ if (!targetAnchor) return;
25
+
26
+ targetTab = targetAnchor.parentNode;
27
+ activeTab = targetTab.parentNode.querySelector(classSelector);
28
+
29
+ if (activeTab) activeTab.classList.remove(className);
30
+
31
+ targetTab.classList.add(className);
32
+
33
+ if (!targetAnchor.hash) return;
34
+
35
+ targetBody = document.querySelector(targetAnchor.hash);
36
+
37
+ if (!targetBody) return;
38
+
39
+ activeBody = targetBody.parentNode.querySelector(classSelector);
40
+
41
+ if (activeBody) activeBody.classList.remove(className);
42
+
43
+ targetBody.classList.add(className)
44
+ });
45
+
46
+ window.addEventListener('click', function (e) { if (getTarget(e.target)) e.preventDefault(); });
47
+ }();