compass-ratchet 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +67 -0
- data/lib/compass-ratchet.rb +3 -0
- data/stylesheets/_compass-ratchet.scss +14 -0
- data/stylesheets/compass-ratchet/_bars.scss +330 -0
- data/stylesheets/compass-ratchet/_base.scss +155 -0
- data/stylesheets/compass-ratchet/_buttons.scss +124 -0
- data/stylesheets/compass-ratchet/_chevrons.scss +32 -0
- data/stylesheets/compass-ratchet/_counts.scss +42 -0
- data/stylesheets/compass-ratchet/_forms.scss +126 -0
- data/stylesheets/compass-ratchet/_lists.scss +122 -0
- data/stylesheets/compass-ratchet/_popovers.scss +158 -0
- data/stylesheets/compass-ratchet/_push.scss +30 -0
- data/stylesheets/compass-ratchet/_segmented-controllers.scss +67 -0
- data/stylesheets/compass-ratchet/_shared.scss +8 -0
- data/stylesheets/compass-ratchet/_sliders.scss +40 -0
- data/stylesheets/compass-ratchet/_toggles.scss +71 -0
- data/templates/project/checkout.html +81 -0
- data/templates/project/choose-movie.html +125 -0
- data/templates/project/choose-theater.html +110 -0
- data/templates/project/config.rb +8 -0
- data/templates/project/css/app.css +1 -0
- data/templates/project/img/argo.png +0 -0
- data/templates/project/img/ralph.png +0 -0
- data/templates/project/img/skyfall.png +0 -0
- data/templates/project/index.html +160 -0
- data/templates/project/js/popovers.js +63 -0
- data/templates/project/js/push.js +417 -0
- data/templates/project/js/segmented-controllers.js +47 -0
- data/templates/project/js/sliders.js +114 -0
- data/templates/project/js/toggles.js +94 -0
- data/templates/project/manifest.rb +24 -0
- data/templates/project/sass/app.scss +13 -0
- data/templates/project/settings.html +73 -0
- data/templates/project/theaters.html +131 -0
- 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
|
+
}();
|