compass-ratchet 1.0.1

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 (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
+ }();