middleman-ratchet 0.1.0
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.
- data/.gitignore +17 -0
- data/Gemfile +3 -0
- data/LICENSE.md +22 -0
- data/README.md +18 -0
- data/Rakefile +1 -0
- data/lib/middleman-ratchet.rb +6 -0
- data/lib/middleman-ratchet/template.rb +33 -0
- data/lib/middleman-ratchet/template/source/images/apple-touch-icon-114x114.png +0 -0
- data/lib/middleman-ratchet/template/source/images/apple-touch-icon-57x57.png +0 -0
- data/lib/middleman-ratchet/template/source/images/apple-touch-icon-72x72.png +0 -0
- data/lib/middleman-ratchet/template/source/index.html.haml +17 -0
- data/lib/middleman-ratchet/template/source/javascripts/all.js +1 -0
- data/lib/middleman-ratchet/template/source/javascripts/ratchet.js +741 -0
- data/lib/middleman-ratchet/template/source/layouts/layout.html.haml +22 -0
- data/lib/middleman-ratchet/template/source/page1.html.haml +9 -0
- data/lib/middleman-ratchet/template/source/stylesheets/all.css +3 -0
- data/lib/middleman-ratchet/template/source/stylesheets/ratchet.css +1260 -0
- data/lib/middleman-ratchet/version.rb +5 -0
- data/lib/middleman_extension.rb +1 -0
- data/middleman-ratchet.gemspec +25 -0
- metadata +116 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 caedes
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# middleman-ratchet
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## Install
|
|
5
|
+
|
|
6
|
+
```shell
|
|
7
|
+
gem install middleman
|
|
8
|
+
gem install middleman-ratchet
|
|
9
|
+
middleman init --template ratchet
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Contributing
|
|
13
|
+
|
|
14
|
+
1. Fork it
|
|
15
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
16
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
17
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
18
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'bundler/gem_tasks'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'middleman-core/templates'
|
|
2
|
+
|
|
3
|
+
module Middleman
|
|
4
|
+
module Ratchet
|
|
5
|
+
|
|
6
|
+
class Template < Middleman::Templates::Base
|
|
7
|
+
class_option 'css_dir',
|
|
8
|
+
default: 'stylesheets',
|
|
9
|
+
desc: 'The path to the css files'
|
|
10
|
+
class_option 'js_dir',
|
|
11
|
+
default: 'javascripts',
|
|
12
|
+
desc: 'The path to the javascript files'
|
|
13
|
+
class_option 'images_dir',
|
|
14
|
+
default: 'images',
|
|
15
|
+
desc: 'The path to the image files'
|
|
16
|
+
|
|
17
|
+
def self.source_root
|
|
18
|
+
File.join(File.dirname(__FILE__), 'template')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def build_scaffold
|
|
22
|
+
template 'shared/config.tt', File.join(location, 'config.rb')
|
|
23
|
+
directory 'source', File.join(location, 'source')
|
|
24
|
+
|
|
25
|
+
empty_directory File.join(location, 'source', options[:css_dir])
|
|
26
|
+
empty_directory File.join(location, 'source', options[:js_dir])
|
|
27
|
+
empty_directory File.join(location, 'source', options[:images_dir])
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Middleman::Templates.register :ratchet, Middleman::Ratchet::Template
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Index
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
/ Make sure all your bars are the first things in your <body>
|
|
6
|
+
%header.bar-title
|
|
7
|
+
%h1.title= 'Index'
|
|
8
|
+
|
|
9
|
+
/ Wrap all non-bar HTML in the .content div (this is actually what scrolls)
|
|
10
|
+
.content
|
|
11
|
+
.content-padded
|
|
12
|
+
%p= 'Fake Index Description'
|
|
13
|
+
%ul.list.inset
|
|
14
|
+
%li
|
|
15
|
+
= link_to 'page1.html', data: { transition: 'slide-in'} do
|
|
16
|
+
%strong= 'Page 1'
|
|
17
|
+
%span.chevron
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//= require_tree .
|
|
@@ -0,0 +1,741 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ==================================
|
|
3
|
+
* Ratchet v1.0.0
|
|
4
|
+
* Licensed under The MIT License
|
|
5
|
+
* http://opensource.org/licenses/MIT
|
|
6
|
+
* ==================================
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/* ----------------------------------
|
|
10
|
+
* POPOVER v1.0.0
|
|
11
|
+
* Licensed under The MIT License
|
|
12
|
+
* http://opensource.org/licenses/MIT
|
|
13
|
+
* ---------------------------------- */
|
|
14
|
+
|
|
15
|
+
!function () {
|
|
16
|
+
|
|
17
|
+
var popover;
|
|
18
|
+
|
|
19
|
+
var findPopovers = function (target) {
|
|
20
|
+
var i, popovers = document.querySelectorAll('a');
|
|
21
|
+
for (; target && target !== document; target = target.parentNode) {
|
|
22
|
+
for (i = popovers.length; i--;) { if (popovers[i] === target) return target; }
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
var onPopoverHidden = function () {
|
|
27
|
+
document.body.removeChild(backdrop);
|
|
28
|
+
popover.style.display = 'none';
|
|
29
|
+
popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var backdrop = function () {
|
|
33
|
+
var element = document.createElement('div');
|
|
34
|
+
|
|
35
|
+
element.classList.add('backdrop');
|
|
36
|
+
|
|
37
|
+
element.addEventListener('touchend', function () {
|
|
38
|
+
popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
|
|
39
|
+
popover.classList.remove('visible');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return element;
|
|
43
|
+
}();
|
|
44
|
+
|
|
45
|
+
var getPopover = function (e) {
|
|
46
|
+
var anchor = findPopovers(e.target);
|
|
47
|
+
|
|
48
|
+
if (!anchor || !anchor.hash) return;
|
|
49
|
+
|
|
50
|
+
popover = document.querySelector(anchor.hash);
|
|
51
|
+
|
|
52
|
+
if (!popover || !popover.classList.contains('popover')) return;
|
|
53
|
+
|
|
54
|
+
return popover;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
window.addEventListener('touchend', function (e) {
|
|
58
|
+
var popover = getPopover(e);
|
|
59
|
+
|
|
60
|
+
if (!popover) return;
|
|
61
|
+
|
|
62
|
+
popover.style.display = 'block';
|
|
63
|
+
popover.offsetHeight;
|
|
64
|
+
popover.classList.add('visible');
|
|
65
|
+
|
|
66
|
+
popover.parentNode.appendChild(backdrop);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
window.addEventListener('click', function (e) { if (getPopover(e)) e.preventDefault(); });
|
|
70
|
+
|
|
71
|
+
}();
|
|
72
|
+
/* ----------------------------------
|
|
73
|
+
* PUSH v1.0.0
|
|
74
|
+
* Licensed under The MIT License
|
|
75
|
+
* inspired by chris's jquery.pjax.js
|
|
76
|
+
* http://opensource.org/licenses/MIT
|
|
77
|
+
* ---------------------------------- */
|
|
78
|
+
|
|
79
|
+
!function () {
|
|
80
|
+
|
|
81
|
+
var noop = function () {};
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
// Pushstate cacheing
|
|
85
|
+
// ==================
|
|
86
|
+
|
|
87
|
+
var isScrolling;
|
|
88
|
+
var maxCacheLength = 20;
|
|
89
|
+
var cacheMapping = sessionStorage;
|
|
90
|
+
var domCache = {};
|
|
91
|
+
var transitionMap = {
|
|
92
|
+
'slide-in' : 'slide-out',
|
|
93
|
+
'slide-out' : 'slide-in',
|
|
94
|
+
'fade' : 'fade'
|
|
95
|
+
};
|
|
96
|
+
var bars = {
|
|
97
|
+
bartab : '.bar-tab',
|
|
98
|
+
bartitle : '.bar-title',
|
|
99
|
+
barfooter : '.bar-footer',
|
|
100
|
+
barheadersecondary : '.bar-header-secondary'
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
var cacheReplace = function (data, updates) {
|
|
104
|
+
PUSH.id = data.id;
|
|
105
|
+
if (updates) data = getCached(data.id);
|
|
106
|
+
cacheMapping[data.id] = JSON.stringify(data);
|
|
107
|
+
window.history.replaceState(data.id, data.title, data.url);
|
|
108
|
+
domCache[data.id] = document.body.cloneNode(true);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
var cachePush = function () {
|
|
112
|
+
var id = PUSH.id;
|
|
113
|
+
|
|
114
|
+
var cacheForwardStack = JSON.parse(cacheMapping.cacheForwardStack || '[]');
|
|
115
|
+
var cacheBackStack = JSON.parse(cacheMapping.cacheBackStack || '[]');
|
|
116
|
+
|
|
117
|
+
cacheBackStack.push(id);
|
|
118
|
+
|
|
119
|
+
while (cacheForwardStack.length) delete cacheMapping[cacheForwardStack.shift()];
|
|
120
|
+
while (cacheBackStack.length > maxCacheLength) delete cacheMapping[cacheBackStack.shift()];
|
|
121
|
+
|
|
122
|
+
window.history.pushState(null, '', cacheMapping[PUSH.id].url);
|
|
123
|
+
|
|
124
|
+
cacheMapping.cacheForwardStack = JSON.stringify(cacheForwardStack);
|
|
125
|
+
cacheMapping.cacheBackStack = JSON.stringify(cacheBackStack);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
var cachePop = function (id, direction) {
|
|
129
|
+
var forward = direction == 'forward';
|
|
130
|
+
var cacheForwardStack = JSON.parse(cacheMapping.cacheForwardStack || '[]');
|
|
131
|
+
var cacheBackStack = JSON.parse(cacheMapping.cacheBackStack || '[]');
|
|
132
|
+
var pushStack = forward ? cacheBackStack : cacheForwardStack;
|
|
133
|
+
var popStack = forward ? cacheForwardStack : cacheBackStack;
|
|
134
|
+
|
|
135
|
+
if (PUSH.id) pushStack.push(PUSH.id);
|
|
136
|
+
popStack.pop();
|
|
137
|
+
|
|
138
|
+
cacheMapping.cacheForwardStack = JSON.stringify(cacheForwardStack);
|
|
139
|
+
cacheMapping.cacheBackStack = JSON.stringify(cacheBackStack);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
var getCached = function (id) {
|
|
143
|
+
return JSON.parse(cacheMapping[id] || null) || {};
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
var getTarget = function (e) {
|
|
147
|
+
var target = findTarget(e.target);
|
|
148
|
+
|
|
149
|
+
if (
|
|
150
|
+
! target
|
|
151
|
+
|| e.which > 1
|
|
152
|
+
|| e.metaKey
|
|
153
|
+
|| e.ctrlKey
|
|
154
|
+
|| isScrolling
|
|
155
|
+
|| location.protocol !== target.protocol
|
|
156
|
+
|| location.host !== target.host
|
|
157
|
+
|| !target.hash && /#/.test(target.href)
|
|
158
|
+
|| target.hash && target.href.replace(target.hash, '') === location.href.replace(location.hash, '')
|
|
159
|
+
|| target.getAttribute('data-ignore') == 'push'
|
|
160
|
+
) return;
|
|
161
|
+
|
|
162
|
+
return target;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
// Main event handlers (touchend, popstate)
|
|
167
|
+
// ==========================================
|
|
168
|
+
|
|
169
|
+
var touchend = function (e) {
|
|
170
|
+
var target = getTarget(e);
|
|
171
|
+
|
|
172
|
+
if (!target) return;
|
|
173
|
+
|
|
174
|
+
e.preventDefault();
|
|
175
|
+
|
|
176
|
+
PUSH({
|
|
177
|
+
url : target.href,
|
|
178
|
+
hash : target.hash,
|
|
179
|
+
timeout : target.getAttribute('data-timeout'),
|
|
180
|
+
transition : target.getAttribute('data-transition')
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
var popstate = function (e) {
|
|
185
|
+
var key;
|
|
186
|
+
var barElement;
|
|
187
|
+
var activeObj;
|
|
188
|
+
var activeDom;
|
|
189
|
+
var direction;
|
|
190
|
+
var transition;
|
|
191
|
+
var transitionFrom;
|
|
192
|
+
var transitionFromObj;
|
|
193
|
+
var id = e.state;
|
|
194
|
+
|
|
195
|
+
if (!id || !cacheMapping[id]) return;
|
|
196
|
+
|
|
197
|
+
direction = PUSH.id < id ? 'forward' : 'back';
|
|
198
|
+
|
|
199
|
+
cachePop(id, direction);
|
|
200
|
+
|
|
201
|
+
activeObj = getCached(id);
|
|
202
|
+
activeDom = domCache[id];
|
|
203
|
+
|
|
204
|
+
if (activeObj.title) document.title = activeObj.title;
|
|
205
|
+
|
|
206
|
+
if (direction == 'back') {
|
|
207
|
+
transitionFrom = JSON.parse(direction == 'back' ? cacheMapping.cacheForwardStack : cacheMapping.cacheBackStack);
|
|
208
|
+
transitionFromObj = getCached(transitionFrom[transitionFrom.length - 1]);
|
|
209
|
+
} else {
|
|
210
|
+
transitionFromObj = activeObj;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (direction == 'back' && !transitionFromObj.id) return PUSH.id = id;
|
|
214
|
+
|
|
215
|
+
transition = direction == 'back' ? transitionMap[transitionFromObj.transition] : transitionFromObj.transition;
|
|
216
|
+
|
|
217
|
+
if (!activeDom) {
|
|
218
|
+
return PUSH({
|
|
219
|
+
id : activeObj.id,
|
|
220
|
+
url : activeObj.url,
|
|
221
|
+
title : activeObj.title,
|
|
222
|
+
timeout : activeObj.timeout,
|
|
223
|
+
transition : transition,
|
|
224
|
+
ignorePush : true
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (transitionFromObj.transition) {
|
|
229
|
+
activeObj = extendWithDom(activeObj, '.content', activeDom.cloneNode(true));
|
|
230
|
+
for (key in bars) {
|
|
231
|
+
barElement = document.querySelector(bars[key])
|
|
232
|
+
if (activeObj[key]) swapContent(activeObj[key], barElement);
|
|
233
|
+
else if (barElement) barElement.parentNode.removeChild(barElement);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
swapContent(
|
|
238
|
+
(activeObj.contents || activeDom).cloneNode(true),
|
|
239
|
+
document.querySelector('.content'),
|
|
240
|
+
transition
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
PUSH.id = id;
|
|
244
|
+
|
|
245
|
+
document.body.offsetHeight; // force reflow to prevent scroll
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
// Core PUSH functionality
|
|
250
|
+
// =======================
|
|
251
|
+
|
|
252
|
+
var PUSH = function (options) {
|
|
253
|
+
var key;
|
|
254
|
+
var data = {};
|
|
255
|
+
var xhr = PUSH.xhr;
|
|
256
|
+
|
|
257
|
+
options.container = options.container || options.transition ? document.querySelector('.content') : document.body;
|
|
258
|
+
|
|
259
|
+
for (key in bars) {
|
|
260
|
+
options[key] = options[key] || document.querySelector(bars[key]);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (xhr && xhr.readyState < 4) {
|
|
264
|
+
xhr.onreadystatechange = noop;
|
|
265
|
+
xhr.abort()
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
xhr = new XMLHttpRequest();
|
|
269
|
+
xhr.open('GET', options.url, true);
|
|
270
|
+
xhr.setRequestHeader('X-PUSH', 'true');
|
|
271
|
+
|
|
272
|
+
xhr.onreadystatechange = function () {
|
|
273
|
+
if (options._timeout) clearTimeout(options._timeout);
|
|
274
|
+
if (xhr.readyState == 4) xhr.status == 200 ? success(xhr, options) : failure(options.url);
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
if (!PUSH.id) {
|
|
278
|
+
cacheReplace({
|
|
279
|
+
id : +new Date,
|
|
280
|
+
url : window.location.href,
|
|
281
|
+
title : document.title,
|
|
282
|
+
timeout : options.timeout,
|
|
283
|
+
transition : null
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (options.timeout) {
|
|
288
|
+
options._timeout = setTimeout(function () { xhr.abort('timeout'); }, options.timeout);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
xhr.send();
|
|
292
|
+
|
|
293
|
+
if (xhr.readyState && !options.ignorePush) cachePush();
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
// Main XHR handlers
|
|
298
|
+
// =================
|
|
299
|
+
|
|
300
|
+
var success = function (xhr, options) {
|
|
301
|
+
var key;
|
|
302
|
+
var barElement;
|
|
303
|
+
var data = parseXHR(xhr, options);
|
|
304
|
+
|
|
305
|
+
if (!data.contents) return locationReplace(options.url);
|
|
306
|
+
|
|
307
|
+
if (data.title) document.title = data.title;
|
|
308
|
+
|
|
309
|
+
if (options.transition) {
|
|
310
|
+
for (key in bars) {
|
|
311
|
+
barElement = document.querySelector(bars[key])
|
|
312
|
+
if (data[key]) swapContent(data[key], barElement);
|
|
313
|
+
else if (barElement) barElement.parentNode.removeChild(barElement);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
swapContent(data.contents, options.container, options.transition, function () {
|
|
318
|
+
cacheReplace({
|
|
319
|
+
id : options.id || +new Date,
|
|
320
|
+
url : data.url,
|
|
321
|
+
title : data.title,
|
|
322
|
+
timeout : options.timeout,
|
|
323
|
+
transition : options.transition
|
|
324
|
+
}, options.id);
|
|
325
|
+
triggerStateChange();
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
if (!options.ignorePush && window._gaq) _gaq.push(['_trackPageview']) // google analytics
|
|
329
|
+
if (!options.hash) return;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
var failure = function (url) {
|
|
333
|
+
throw new Error('Could not get: ' + url)
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
// PUSH helpers
|
|
338
|
+
// ============
|
|
339
|
+
|
|
340
|
+
var swapContent = function (swap, container, transition, complete) {
|
|
341
|
+
var enter;
|
|
342
|
+
var containerDirection;
|
|
343
|
+
var swapDirection;
|
|
344
|
+
|
|
345
|
+
if (!transition) {
|
|
346
|
+
if (container) container.innerHTML = swap.innerHTML;
|
|
347
|
+
else if (swap.classList.contains('content')) document.body.appendChild(swap);
|
|
348
|
+
else document.body.insertBefore(swap, document.querySelector('.content'));
|
|
349
|
+
} else {
|
|
350
|
+
enter = /in$/.test(transition);
|
|
351
|
+
|
|
352
|
+
if (transition == 'fade') {
|
|
353
|
+
container.classList.add('in');
|
|
354
|
+
container.classList.add('fade');
|
|
355
|
+
swap.classList.add('fade');
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (/slide/.test(transition)) {
|
|
359
|
+
swap.classList.add(enter ? 'right' : 'left');
|
|
360
|
+
swap.classList.add('slide');
|
|
361
|
+
container.classList.add('slide');
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
container.parentNode.insertBefore(swap, container);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (!transition) complete && complete();
|
|
368
|
+
|
|
369
|
+
if (transition == 'fade') {
|
|
370
|
+
container.offsetWidth; // force reflow
|
|
371
|
+
container.classList.remove('in');
|
|
372
|
+
container.addEventListener('webkitTransitionEnd', fadeContainerEnd);
|
|
373
|
+
|
|
374
|
+
function fadeContainerEnd() {
|
|
375
|
+
container.removeEventListener('webkitTransitionEnd', fadeContainerEnd);
|
|
376
|
+
swap.classList.add('in');
|
|
377
|
+
swap.addEventListener('webkitTransitionEnd', fadeSwapEnd);
|
|
378
|
+
}
|
|
379
|
+
function fadeSwapEnd () {
|
|
380
|
+
swap.removeEventListener('webkitTransitionEnd', fadeSwapEnd);
|
|
381
|
+
container.parentNode.removeChild(container);
|
|
382
|
+
swap.classList.remove('fade');
|
|
383
|
+
swap.classList.remove('in');
|
|
384
|
+
complete && complete();
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (/slide/.test(transition)) {
|
|
389
|
+
container.offsetWidth; // force reflow
|
|
390
|
+
swapDirection = enter ? 'right' : 'left'
|
|
391
|
+
containerDirection = enter ? 'left' : 'right'
|
|
392
|
+
container.classList.add(containerDirection);
|
|
393
|
+
swap.classList.remove(swapDirection);
|
|
394
|
+
swap.addEventListener('webkitTransitionEnd', slideEnd);
|
|
395
|
+
|
|
396
|
+
function slideEnd() {
|
|
397
|
+
swap.removeEventListener('webkitTransitionEnd', slideEnd);
|
|
398
|
+
swap.classList.remove('slide');
|
|
399
|
+
swap.classList.remove(swapDirection);
|
|
400
|
+
container.parentNode.removeChild(container);
|
|
401
|
+
complete && complete();
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
var triggerStateChange = function () {
|
|
407
|
+
var e = new CustomEvent('push', {
|
|
408
|
+
detail: { state: getCached(PUSH.id) },
|
|
409
|
+
bubbles: true,
|
|
410
|
+
cancelable: true
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
window.dispatchEvent(e);
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
var findTarget = function (target) {
|
|
417
|
+
var i, toggles = document.querySelectorAll('a');
|
|
418
|
+
for (; target && target !== document; target = target.parentNode) {
|
|
419
|
+
for (i = toggles.length; i--;) { if (toggles[i] === target) return target; }
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
var locationReplace = function (url) {
|
|
424
|
+
window.history.replaceState(null, '', '#');
|
|
425
|
+
window.location.replace(url);
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
var parseURL = function (url) {
|
|
429
|
+
var a = document.createElement('a'); a.href = url; return a;
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
var extendWithDom = function (obj, fragment, dom) {
|
|
433
|
+
var i;
|
|
434
|
+
var result = {};
|
|
435
|
+
|
|
436
|
+
for (i in obj) result[i] = obj[i];
|
|
437
|
+
|
|
438
|
+
Object.keys(bars).forEach(function (key) {
|
|
439
|
+
var el = dom.querySelector(bars[key]);
|
|
440
|
+
if (el) el.parentNode.removeChild(el);
|
|
441
|
+
result[key] = el;
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
result.contents = dom.querySelector(fragment);
|
|
445
|
+
|
|
446
|
+
return result;
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
var parseXHR = function (xhr, options) {
|
|
450
|
+
var head;
|
|
451
|
+
var body;
|
|
452
|
+
var data = {};
|
|
453
|
+
var responseText = xhr.responseText;
|
|
454
|
+
|
|
455
|
+
data.url = options.url;
|
|
456
|
+
|
|
457
|
+
if (!responseText) return data;
|
|
458
|
+
|
|
459
|
+
if (/<html/i.test(responseText)) {
|
|
460
|
+
head = document.createElement('div');
|
|
461
|
+
body = document.createElement('div');
|
|
462
|
+
head.innerHTML = responseText.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]
|
|
463
|
+
body.innerHTML = responseText.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]
|
|
464
|
+
} else {
|
|
465
|
+
head = body = document.createElement('div');
|
|
466
|
+
head.innerHTML = responseText;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
data.title = head.querySelector('title');
|
|
470
|
+
data.title = data.title && data.title.innerText.trim();
|
|
471
|
+
|
|
472
|
+
if (options.transition) data = extendWithDom(data, '.content', body);
|
|
473
|
+
else data.contents = body;
|
|
474
|
+
|
|
475
|
+
return data;
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
// Attach PUSH event handlers
|
|
480
|
+
// ==========================
|
|
481
|
+
|
|
482
|
+
window.addEventListener('touchstart', function () { isScrolling = false; });
|
|
483
|
+
window.addEventListener('touchmove', function () { isScrolling = true; })
|
|
484
|
+
window.addEventListener('touchend', touchend);
|
|
485
|
+
window.addEventListener('click', function (e) { if (getTarget(e)) e.preventDefault(); });
|
|
486
|
+
window.addEventListener('popstate', popstate);
|
|
487
|
+
|
|
488
|
+
}();/* ----------------------------------
|
|
489
|
+
* TABS v1.0.0
|
|
490
|
+
* Licensed under The MIT License
|
|
491
|
+
* http://opensource.org/licenses/MIT
|
|
492
|
+
* ---------------------------------- */
|
|
493
|
+
|
|
494
|
+
!function () {
|
|
495
|
+
var getTarget = function (target) {
|
|
496
|
+
var i, popovers = document.querySelectorAll('.segmented-controller li a');
|
|
497
|
+
for (; target && target !== document; target = target.parentNode) {
|
|
498
|
+
for (i = popovers.length; i--;) { if (popovers[i] === target) return target; }
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
window.addEventListener("touchend", function (e) {
|
|
503
|
+
var activeTab;
|
|
504
|
+
var activeBody;
|
|
505
|
+
var targetBody;
|
|
506
|
+
var targetTab;
|
|
507
|
+
var className = 'active';
|
|
508
|
+
var classSelector = '.' + className;
|
|
509
|
+
var targetAnchor = getTarget(e.target);
|
|
510
|
+
|
|
511
|
+
if (!targetAnchor) return;
|
|
512
|
+
|
|
513
|
+
targetTab = targetAnchor.parentNode;
|
|
514
|
+
activeTab = targetTab.parentNode.querySelector(classSelector);
|
|
515
|
+
|
|
516
|
+
if (activeTab) activeTab.classList.remove(className);
|
|
517
|
+
|
|
518
|
+
targetTab.classList.add(className);
|
|
519
|
+
|
|
520
|
+
if (!targetAnchor.hash) return;
|
|
521
|
+
|
|
522
|
+
targetBody = document.querySelector(targetAnchor.hash);
|
|
523
|
+
|
|
524
|
+
if (!targetBody) return;
|
|
525
|
+
|
|
526
|
+
activeBody = targetBody.parentNode.querySelector(classSelector);
|
|
527
|
+
|
|
528
|
+
if (activeBody) activeBody.classList.remove(className);
|
|
529
|
+
|
|
530
|
+
targetBody.classList.add(className)
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
window.addEventListener('click', function (e) { if (getTarget(e.target)) e.preventDefault(); });
|
|
534
|
+
}();/* ----------------------------------
|
|
535
|
+
* SLIDER v1.0.0
|
|
536
|
+
* Licensed under The MIT License
|
|
537
|
+
* Adapted from Brad Birdsall's swipe
|
|
538
|
+
* http://opensource.org/licenses/MIT
|
|
539
|
+
* ---------------------------------- */
|
|
540
|
+
|
|
541
|
+
!function () {
|
|
542
|
+
|
|
543
|
+
var pageX;
|
|
544
|
+
var pageY;
|
|
545
|
+
var slider;
|
|
546
|
+
var deltaX;
|
|
547
|
+
var deltaY;
|
|
548
|
+
var offsetX;
|
|
549
|
+
var lastSlide;
|
|
550
|
+
var startTime;
|
|
551
|
+
var resistance;
|
|
552
|
+
var sliderWidth;
|
|
553
|
+
var slideNumber;
|
|
554
|
+
var isScrolling;
|
|
555
|
+
var scrollableArea;
|
|
556
|
+
|
|
557
|
+
var getSlider = function (target) {
|
|
558
|
+
var i, sliders = document.querySelectorAll('.slider ul');
|
|
559
|
+
for (; target && target !== document; target = target.parentNode) {
|
|
560
|
+
for (i = sliders.length; i--;) { if (sliders[i] === target) return target; }
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
var getScroll = function () {
|
|
565
|
+
var translate3d = slider.style.webkitTransform.match(/translate3d\(([^,]*)/);
|
|
566
|
+
return parseInt(translate3d ? translate3d[1] : 0)
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
var setSlideNumber = function (offset) {
|
|
570
|
+
var round = offset ? (deltaX < 0 ? 'ceil' : 'floor') : 'round';
|
|
571
|
+
slideNumber = Math[round](getScroll() / ( scrollableArea / slider.children.length) );
|
|
572
|
+
slideNumber += offset;
|
|
573
|
+
slideNumber = Math.min(slideNumber, 0);
|
|
574
|
+
slideNumber = Math.max(-(slider.children.length - 1), slideNumber);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
var onTouchStart = function (e) {
|
|
578
|
+
slider = getSlider(e.target);
|
|
579
|
+
|
|
580
|
+
if (!slider) return;
|
|
581
|
+
|
|
582
|
+
var firstItem = slider.querySelector('li');
|
|
583
|
+
|
|
584
|
+
scrollableArea = firstItem.offsetWidth * slider.children.length;
|
|
585
|
+
isScrolling = undefined;
|
|
586
|
+
sliderWidth = slider.offsetWidth;
|
|
587
|
+
resistance = 1;
|
|
588
|
+
lastSlide = -(slider.children.length - 1);
|
|
589
|
+
startTime = +new Date;
|
|
590
|
+
pageX = e.touches[0].pageX;
|
|
591
|
+
pageY = e.touches[0].pageY;
|
|
592
|
+
|
|
593
|
+
setSlideNumber(0);
|
|
594
|
+
|
|
595
|
+
slider.style['-webkit-transition-duration'] = 0;
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
var onTouchMove = function (e) {
|
|
599
|
+
if (e.touches.length > 1 || !slider) return; // Exit if a pinch || no slider
|
|
600
|
+
|
|
601
|
+
deltaX = e.touches[0].pageX - pageX;
|
|
602
|
+
deltaY = e.touches[0].pageY - pageY;
|
|
603
|
+
pageX = e.touches[0].pageX;
|
|
604
|
+
pageY = e.touches[0].pageY;
|
|
605
|
+
|
|
606
|
+
if (typeof isScrolling == 'undefined') {
|
|
607
|
+
isScrolling = Math.abs(deltaY) > Math.abs(deltaX);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if (isScrolling) return;
|
|
611
|
+
|
|
612
|
+
offsetX = (deltaX / resistance) + getScroll();
|
|
613
|
+
|
|
614
|
+
e.preventDefault();
|
|
615
|
+
|
|
616
|
+
resistance = slideNumber == 0 && deltaX > 0 ? (pageX / sliderWidth) + 1.25 :
|
|
617
|
+
slideNumber == lastSlide && deltaX < 0 ? (Math.abs(pageX) / sliderWidth) + 1.25 : 1;
|
|
618
|
+
|
|
619
|
+
slider.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
var onTouchEnd = function (e) {
|
|
623
|
+
if (!slider || isScrolling) return;
|
|
624
|
+
|
|
625
|
+
setSlideNumber(
|
|
626
|
+
(+new Date) - startTime < 1000 && Math.abs(deltaX) > 15 ? (deltaX < 0 ? -1 : 1) : 0
|
|
627
|
+
);
|
|
628
|
+
|
|
629
|
+
offsetX = slideNumber * sliderWidth;
|
|
630
|
+
|
|
631
|
+
slider.style['-webkit-transition-duration'] = '.2s';
|
|
632
|
+
slider.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';
|
|
633
|
+
|
|
634
|
+
e = new CustomEvent('slide', {
|
|
635
|
+
detail: { slideNumber: Math.abs(slideNumber) },
|
|
636
|
+
bubbles: true,
|
|
637
|
+
cancelable: true
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
slider.parentNode.dispatchEvent(e);
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
window.addEventListener('touchstart', onTouchStart);
|
|
644
|
+
window.addEventListener('touchmove', onTouchMove);
|
|
645
|
+
window.addEventListener('touchend', onTouchEnd);
|
|
646
|
+
|
|
647
|
+
}();
|
|
648
|
+
/* ----------------------------------
|
|
649
|
+
* TOGGLE v1.0.0
|
|
650
|
+
* Licensed under The MIT License
|
|
651
|
+
* http://opensource.org/licenses/MIT
|
|
652
|
+
* ---------------------------------- */
|
|
653
|
+
|
|
654
|
+
!function () {
|
|
655
|
+
|
|
656
|
+
var start = {};
|
|
657
|
+
var touchMove = false;
|
|
658
|
+
var distanceX = false;
|
|
659
|
+
var toggle = false;
|
|
660
|
+
|
|
661
|
+
var findToggle = function (target) {
|
|
662
|
+
var i, toggles = document.querySelectorAll('.toggle');
|
|
663
|
+
for (; target && target !== document; target = target.parentNode) {
|
|
664
|
+
for (i = toggles.length; i--;) { if (toggles[i] === target) return target; }
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
window.addEventListener('touchstart', function (e) {
|
|
669
|
+
e = e.originalEvent || e;
|
|
670
|
+
|
|
671
|
+
toggle = findToggle(e.target);
|
|
672
|
+
|
|
673
|
+
if (!toggle) return;
|
|
674
|
+
|
|
675
|
+
var handle = toggle.querySelector('.toggle-handle');
|
|
676
|
+
var toggleWidth = toggle.offsetWidth;
|
|
677
|
+
var handleWidth = handle.offsetWidth;
|
|
678
|
+
var offset = toggle.classList.contains('active') ? toggleWidth - handleWidth : 0;
|
|
679
|
+
|
|
680
|
+
start = { pageX : e.touches[0].pageX - offset, pageY : e.touches[0].pageY };
|
|
681
|
+
touchMove = false;
|
|
682
|
+
|
|
683
|
+
// todo: probably should be moved to the css
|
|
684
|
+
toggle.style['-webkit-transition-duration'] = 0;
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
window.addEventListener('touchmove', function (e) {
|
|
688
|
+
e = e.originalEvent || e;
|
|
689
|
+
|
|
690
|
+
if (e.touches.length > 1) return; // Exit if a pinch
|
|
691
|
+
|
|
692
|
+
if (!toggle) return;
|
|
693
|
+
|
|
694
|
+
var handle = toggle.querySelector('.toggle-handle');
|
|
695
|
+
var current = e.touches[0];
|
|
696
|
+
var toggleWidth = toggle.offsetWidth;
|
|
697
|
+
var handleWidth = handle.offsetWidth;
|
|
698
|
+
var offset = toggleWidth - handleWidth;
|
|
699
|
+
|
|
700
|
+
touchMove = true;
|
|
701
|
+
distanceX = current.pageX - start.pageX;
|
|
702
|
+
|
|
703
|
+
if (Math.abs(distanceX) < Math.abs(current.pageY - start.pageY)) return;
|
|
704
|
+
|
|
705
|
+
e.preventDefault();
|
|
706
|
+
|
|
707
|
+
if (distanceX < 0) return handle.style.webkitTransform = 'translate3d(0,0,0)';
|
|
708
|
+
if (distanceX > offset) return handle.style.webkitTransform = 'translate3d(' + offset + 'px,0,0)';
|
|
709
|
+
|
|
710
|
+
handle.style.webkitTransform = 'translate3d(' + distanceX + 'px,0,0)';
|
|
711
|
+
|
|
712
|
+
toggle.classList[(distanceX > (toggleWidth/2 - handleWidth/2)) ? 'add' : 'remove']('active');
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
window.addEventListener('touchend', function (e) {
|
|
716
|
+
if (!toggle) return;
|
|
717
|
+
|
|
718
|
+
var handle = toggle.querySelector('.toggle-handle');
|
|
719
|
+
var toggleWidth = toggle.offsetWidth;
|
|
720
|
+
var handleWidth = handle.offsetWidth;
|
|
721
|
+
var offset = toggleWidth - handleWidth;
|
|
722
|
+
var slideOn = (!touchMove && !toggle.classList.contains('active')) || (touchMove && (distanceX > (toggleWidth/2 - handleWidth/2)));
|
|
723
|
+
|
|
724
|
+
if (slideOn) handle.style.webkitTransform = 'translate3d(' + offset + 'px,0,0)';
|
|
725
|
+
else handle.style.webkitTransform = 'translate3d(0,0,0)';
|
|
726
|
+
|
|
727
|
+
toggle.classList[slideOn ? 'add' : 'remove']('active');
|
|
728
|
+
|
|
729
|
+
e = new CustomEvent('toggle', {
|
|
730
|
+
detail: { isActive: slideOn },
|
|
731
|
+
bubbles: true,
|
|
732
|
+
cancelable: true
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
toggle.dispatchEvent(e);
|
|
736
|
+
|
|
737
|
+
touchMove = false;
|
|
738
|
+
toggle = false;
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
}();
|