author | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2013-04-21 15:53:34 (UTC) |
---|---|---|
committer | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2013-04-21 15:53:34 (UTC) |
commit | 0608e045f6aa471916829468f48082ea07a453f4 (patch) (unidiff) | |
tree | 57748b9a76e592ae35b165cd6a203e12493d4044 /frontend/gamma/js/JQTouch/jqtouch.js | |
parent | 074e70457c90344b3c1cb236105638d692a0066b (diff) | |
download | clipperz-0608e045f6aa471916829468f48082ea07a453f4.zip clipperz-0608e045f6aa471916829468f48082ea07a453f4.tar.gz clipperz-0608e045f6aa471916829468f48082ea07a453f4.tar.bz2 |
Removed extra JS libraries no longer used for the mobile version
Diffstat (limited to 'frontend/gamma/js/JQTouch/jqtouch.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/gamma/js/JQTouch/jqtouch.js | 889 |
1 files changed, 0 insertions, 889 deletions
diff --git a/frontend/gamma/js/JQTouch/jqtouch.js b/frontend/gamma/js/JQTouch/jqtouch.js deleted file mode 100644 index bdc6d2e..0000000 --- a/frontend/gamma/js/JQTouch/jqtouch.js +++ b/dev/null | |||
@@ -1,889 +0,0 @@ | |||
1 | /* | ||
2 | |||
3 | _/ _/_/ _/_/_/_/_/ _/ | ||
4 | _/ _/ _/ _/_/ _/ _/ _/_/_/ _/_/_/ | ||
5 | _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ | ||
6 | _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ | ||
7 | _/ _/_/ _/ _/ _/_/ _/_/_/ _/_/_/ _/ _/ | ||
8 | _/ | ||
9 | _/ | ||
10 | |||
11 | Created by David Kaneda <http://www.davidkaneda.com> | ||
12 | Maintained by Thomas Yip <http://beedesk.com/> | ||
13 | Sponsored by Sencha Labs <http://www.sencha.com/> | ||
14 | Special thanks to Jonathan Stark <http://www.jonathanstark.com/> | ||
15 | |||
16 | Documentation and issue tracking on GitHub <http://github.com/senchalabs/jQTouch/> | ||
17 | |||
18 | (c) 2009-2011 Sencha Labs | ||
19 | jQTouch may be freely distributed under the MIT license. | ||
20 | |||
21 | */ | ||
22 | (function() { | ||
23 | |||
24 | var fx; | ||
25 | if ('Zepto' in window) { | ||
26 | fx = window.Zepto; | ||
27 | fx.fn.prop = fx.fn.attr; | ||
28 | |||
29 | Event.prototype.isDefaultPrevented = function() { | ||
30 | return this.defaultPrevented; | ||
31 | }; | ||
32 | } else if ('jQuery' in window) { | ||
33 | fx = window.jQuery; | ||
34 | |||
35 | // trick to get Zepto/touch.js to work for jQuery | ||
36 | window.Zepto = $; | ||
37 | } else { | ||
38 | throw('Either Zepto or jQuery is required but neither can be found.'); | ||
39 | } | ||
40 | |||
41 | $.jQTouch = function(options) { | ||
42 | // Initialize internal jQT variables | ||
43 | var $ = fx, | ||
44 | $body, | ||
45 | $head=$('head'), | ||
46 | history=[], | ||
47 | newPageCount=0, | ||
48 | jQTSettings={}, | ||
49 | $currentPage='', | ||
50 | orientation='portrait', | ||
51 | touchSelectors=[], | ||
52 | publicObj={}, | ||
53 | tapBuffer=100, // High click delay = ~350, quickest animation (slide) = 250 | ||
54 | extensions=$.jQTouch.prototype.extensions, | ||
55 | extTapHandlers=$.jQTouch.prototype.tapHandlers, | ||
56 | tapHandlers=[], | ||
57 | animations=[], | ||
58 | hairExtensions='', | ||
59 | defaults = { | ||
60 | addGlossToIcon: true, | ||
61 | backSelector: '.back, .cancel, .goback', | ||
62 | cacheGetRequests: true, | ||
63 | debug: true, | ||
64 | defaultAnimation: 'slideleft', | ||
65 | fixedViewport: true, | ||
66 | formSelector: 'form', | ||
67 | fullScreen: true, | ||
68 | fullScreenClass: 'fullscreen', | ||
69 | icon: null, | ||
70 | icon4: null, // available in iOS 4.2 and later. | ||
71 | preloadImages: false, | ||
72 | startupScreen: null, | ||
73 | statusBar: 'default', // other options: black-translucent, black | ||
74 | submitSelector: '.submit', | ||
75 | touchSelector: 'a, .touch', | ||
76 | trackScrollPositions: true, | ||
77 | useAnimations: true, | ||
78 | useFastTouch: true, | ||
79 | useTouchScroll: true, | ||
80 | animations: [ // highest to lowest priority | ||
81 | {name:'cubeleft', selector:'.cubeleft, .cube', is3d: true}, | ||
82 | {name:'cuberight', selector:'.cuberight', is3d: true}, | ||
83 | {name:'dissolve', selector:'.dissolve'}, | ||
84 | {name:'fade', selector:'.fade'}, | ||
85 | {name:'flipleft', selector:'.flipleft, .flip', is3d: true}, | ||
86 | {name:'flipright', selector:'.flipright', is3d: true}, | ||
87 | {name:'pop', selector:'.pop', is3d: true}, | ||
88 | {name:'swapleft', selector:'.swap', is3d: true}, | ||
89 | {name:'slidedown', selector:'.slidedown'}, | ||
90 | {name:'slideright', selector:'.slideright'}, | ||
91 | {name:'slideup', selector:'.slideup'}, | ||
92 | {name:'slideleft', selector:'.slideleft, .slide, #jqt > * > ul li a'} | ||
93 | ] | ||
94 | }; // end defaults | ||
95 | |||
96 | function warn(message) { | ||
97 | if (window.console !== undefined && jQTSettings.debug === true) { | ||
98 | console.warn(message); | ||
99 | } | ||
100 | } | ||
101 | function addAnimation(animation) { | ||
102 | if (typeof(animation.selector) === 'string' && typeof(animation.name) === 'string') { | ||
103 | animations.push(animation); | ||
104 | } | ||
105 | } | ||
106 | function addTapHandler(tapHandler) { | ||
107 | if (typeof(tapHandler.name) === 'string' | ||
108 | && typeof(tapHandler.isSupported) === 'function' | ||
109 | && typeof(tapHandler.fn) === 'function') { | ||
110 | |||
111 | tapHandlers.push(tapHandler); | ||
112 | } | ||
113 | } | ||
114 | function addPageToHistory(page, animation) { | ||
115 | history.unshift({ | ||
116 | page: page, | ||
117 | animation: animation, | ||
118 | hash: '#' + page.attr('id'), | ||
119 | id: page.attr('id') | ||
120 | }); | ||
121 | } | ||
122 | |||
123 | // Unfortunately, we can not assume the "tap" event | ||
124 | // is being used for links, forms, etc. | ||
125 | function clickHandler(e) { | ||
126 | // Figure out whether to prevent default | ||
127 | var $el = $(e.target); | ||
128 | |||
129 | // Find the nearest tappable ancestor | ||
130 | if (!$el.is(touchSelectors.join(', '))) { | ||
131 | $el = $(e.target).closest(touchSelectors.join(', ')); | ||
132 | } | ||
133 | |||
134 | // Prevent default if we found an internal link (relative or absolute) | ||
135 | if ($el && $el.attr('href') && !$el.isExternalLink()) { | ||
136 | warn('Need to prevent default click behavior'); | ||
137 | e.preventDefault(); | ||
138 | } else { | ||
139 | warn('No need to prevent default click behavior'); | ||
140 | } | ||
141 | |||
142 | // Trigger a tap event if touchstart is not on the job | ||
143 | if ($.support.touch) { | ||
144 | warn('Not converting click to a tap event because touch handler is on the job'); | ||
145 | } else { | ||
146 | warn('Converting click event to a tap event because touch handlers are not present or off'); | ||
147 | $(e.target).trigger('tap', e); | ||
148 | } | ||
149 | |||
150 | } | ||
151 | function doNavigation(fromPage, toPage, animation, goingBack) { | ||
152 | |||
153 | goingBack = goingBack ? goingBack : false; | ||
154 | |||
155 | // Error check for target page | ||
156 | if (toPage === undefined || toPage.length === 0) { | ||
157 | $.fn.unselect(); | ||
158 | warn('Target element is missing.'); | ||
159 | return false; | ||
160 | } | ||
161 | |||
162 | // Error check for fromPage===toPage | ||
163 | if (toPage.hasClass('current')) { | ||
164 | $.fn.unselect(); | ||
165 | warn('You are already on the page you are trying to navigate to.'); | ||
166 | return false; | ||
167 | } | ||
168 | |||
169 | // Collapse the keyboard | ||
170 | $(':focus').trigger('blur'); | ||
171 | |||
172 | fromPage.trigger('pageAnimationStart', { direction: 'out', back: goingBack }); | ||
173 | toPage.trigger('pageAnimationStart', { direction: 'in', back: goingBack }); | ||
174 | |||
175 | if ($.support.animationEvents && animation && jQTSettings.useAnimations) { | ||
176 | // Fail over to 2d animation if need be | ||
177 | if (!$.support.transform3d && animation.is3d) { | ||
178 | warn('Did not detect support for 3d animations, falling back to ' + jQTSettings.defaultAnimation); | ||
179 | animation.name = jQTSettings.defaultAnimation; | ||
180 | } | ||
181 | |||
182 | // Reverse animation if need be | ||
183 | var finalAnimationName = animation.name, | ||
184 | is3d = animation.is3d ? 'animating3d' : ''; | ||
185 | |||
186 | if (goingBack) { | ||
187 | finalAnimationName = finalAnimationName.replace(/left|right|up|down|in|out/, reverseAnimation ); | ||
188 | } | ||
189 | |||
190 | warn('finalAnimationName is ' + finalAnimationName); | ||
191 | |||
192 | // Bind internal "cleanup" callback | ||
193 | fromPage.bind('webkitAnimationEnd', navigationEndHandler); | ||
194 | |||
195 | // Trigger animations | ||
196 | $body.addClass('animating ' + is3d); | ||
197 | |||
198 | var lastScroll = window.pageYOffset; | ||
199 | |||
200 | // Position the incoming page so toolbar is at top of viewport regardless of scroll position on from page | ||
201 | if (jQTSettings.trackScrollPositions === true) { | ||
202 | toPage.css('top', window.pageYOffset - (toPage.data('lastScroll') || 0)); | ||
203 | } | ||
204 | |||
205 | toPage.addClass(finalAnimationName + ' in current'); | ||
206 | fromPage.removeClass('current').addClass(finalAnimationName + ' out inmotion'); | ||
207 | |||
208 | if (jQTSettings.trackScrollPositions === true) { | ||
209 | fromPage.data('lastScroll', lastScroll); | ||
210 | $('.scroll', fromPage).each(function(){ | ||
211 | $(this).data('lastScroll', this.scrollTop); | ||
212 | }); | ||
213 | } | ||
214 | } else { | ||
215 | toPage.addClass('current in'); | ||
216 | fromPage.removeClass('current'); | ||
217 | navigationEndHandler(); | ||
218 | } | ||
219 | |||
220 | // Housekeeping | ||
221 | $currentPage = toPage; | ||
222 | if (goingBack) { | ||
223 | history.shift(); | ||
224 | } else { | ||
225 | addPageToHistory($currentPage, animation); | ||
226 | } | ||
227 | setHash($currentPage.attr('id')); | ||
228 | |||
229 | // Private navigationEnd callback | ||
230 | function navigationEndHandler(event) { | ||
231 | var bufferTime = tapBuffer; | ||
232 | |||
233 | if ($.support.animationEvents && animation && jQTSettings.useAnimations) { | ||
234 | fromPage.unbind('webkitAnimationEnd', navigationEndHandler); | ||
235 | fromPage.removeClass(finalAnimationName + ' out inmotion'); | ||
236 | if (finalAnimationName) { | ||
237 | toPage.removeClass(finalAnimationName); | ||
238 | } | ||
239 | $body.removeClass('animating animating3d'); | ||
240 | if (jQTSettings.trackScrollPositions === true) { | ||
241 | toPage.css('top', -toPage.data('lastScroll')); | ||
242 | |||
243 | // Have to make sure the scroll/style resets | ||
244 | // are outside the flow of this function. | ||
245 | setTimeout(function(){ | ||
246 | toPage.css('top', 0); | ||
247 | window.scroll(0, toPage.data('lastScroll')); | ||
248 | $('.scroll', toPage).each(function(){ | ||
249 | this.scrollTop = - $(this).data('lastScroll'); | ||
250 | }); | ||
251 | }, 0); | ||
252 | } | ||
253 | } else { | ||
254 | fromPage.removeClass(finalAnimationName + ' out inmotion'); | ||
255 | if (finalAnimationName) { | ||
256 | toPage.removeClass(finalAnimationName); | ||
257 | } | ||
258 | bufferTime += 260; | ||
259 | } | ||
260 | |||
261 | // In class is intentionally delayed, as it is our ghost click hack | ||
262 | setTimeout(function(){ | ||
263 | toPage.removeClass('in'); | ||
264 | window.scroll(0,0); | ||
265 | }, bufferTime); | ||
266 | |||
267 | fromPage.unselect(); | ||
268 | |||
269 | // Trigger custom events | ||
270 | toPage.trigger('pageAnimationEnd', { | ||
271 | direction:'in', animation: animation, back: goingBack | ||
272 | }); | ||
273 | fromPage.trigger('pageAnimationEnd', { | ||
274 | direction:'out', animation: animation, back: goingBack | ||
275 | }); | ||
276 | } | ||
277 | |||
278 | return true; | ||
279 | } | ||
280 | function reverseAnimation(animation) { | ||
281 | var opposites={ | ||
282 | 'up' : 'down', | ||
283 | 'down' : 'up', | ||
284 | 'left' : 'right', | ||
285 | 'right' : 'left', | ||
286 | 'in' : 'out', | ||
287 | 'out' : 'in' | ||
288 | }; | ||
289 | |||
290 | return opposites[animation] || animation; | ||
291 | } | ||
292 | function getOrientation() { | ||
293 | return orientation; | ||
294 | } | ||
295 | function goBack() { | ||
296 | |||
297 | // Error checking | ||
298 | if (history.length < 1 ) { | ||
299 | warn('History is empty.'); | ||
300 | } | ||
301 | |||
302 | if (history.length === 1 ) { | ||
303 | warn('You are on the first panel.'); | ||
304 | window.history.go(-1); | ||
305 | } | ||
306 | |||
307 | var from = history[0], | ||
308 | to = history[1]; | ||
309 | |||
310 | if (doNavigation(from.page, to.page, from.animation, true)) { | ||
311 | return publicObj; | ||
312 | } else { | ||
313 | warn('Could not go back.'); | ||
314 | return false; | ||
315 | } | ||
316 | |||
317 | } | ||
318 | function goTo(toPage, animation) { | ||
319 | |||
320 | var fromPage = history[0].page; | ||
321 | |||
322 | if (typeof animation === 'string') { | ||
323 | for (var i=0, max=animations.length; i < max; i++) { | ||
324 | if (animations[i].name === animation) { | ||
325 | animation = animations[i]; | ||
326 | break; | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | |||
331 | if (typeof toPage === 'string') { | ||
332 | var nextPage = $(toPage); | ||
333 | |||
334 | if (nextPage.length < 1) { | ||
335 | showPageByHref(toPage, { | ||
336 | animation: animation | ||
337 | }); | ||
338 | return; | ||
339 | } else { | ||
340 | toPage = nextPage; | ||
341 | } | ||
342 | } | ||
343 | if (doNavigation(fromPage, toPage, animation)) { | ||
344 | return publicObj; | ||
345 | } else { | ||
346 | warn('Could not animate pages.'); | ||
347 | return false; | ||
348 | } | ||
349 | } | ||
350 | function hashChangeHandler(e) { | ||
351 | if (location.hash === history[0].hash) { | ||
352 | warn('We are on the right panel'); | ||
353 | return true; | ||
354 | } else if (location.hash === '') { | ||
355 | goBack(); | ||
356 | return true; | ||
357 | } else { | ||
358 | if( (history[1] && location.hash === history[1].hash) ) { | ||
359 | goBack(); | ||
360 | return true; | ||
361 | } else { | ||
362 | // Lastly, just try going to the ID... | ||
363 | warn('Could not find ID in history, just forwarding to DOM element.'); | ||
364 | goTo($(location.hash), jQTSettings.defaultAnimation); | ||
365 | } | ||
366 | } | ||
367 | } | ||
368 | function init(options) { | ||
369 | jQTSettings = $.extend({}, defaults, options); | ||
370 | |||
371 | // Preload images | ||
372 | if (jQTSettings.preloadImages) { | ||
373 | for (var i = jQTSettings.preloadImages.length - 1; i >= 0; i--) { | ||
374 | (new Image()).src = jQTSettings.preloadImages[i]; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | // Set appropriate icon (retina display available in iOS 4.2 and later.) | ||
379 | var precomposed = (jQTSettings.addGlossToIcon) ? '' : '-precomposed'; | ||
380 | if (jQTSettings.icon) { | ||
381 | hairExtensions += '<link rel="apple-touch-icon' + precomposed + '" href="' + jQTSettings.icon + '" />'; | ||
382 | } | ||
383 | if (jQTSettings.icon4) { | ||
384 | hairExtensions += '<link rel="apple-touch-icon' + precomposed + '" sizes="114x114" href="' + jQTSettings.icon4 + '" />'; | ||
385 | } | ||
386 | // Set startup screen | ||
387 | if (jQTSettings.startupScreen) { | ||
388 | hairExtensions += '<link rel="apple-touch-startup-image" href="' + jQTSettings.startupScreen + '" />'; | ||
389 | } | ||
390 | |||
391 | // Set viewport | ||
392 | if (jQTSettings.fixedViewport) { | ||
393 | hairExtensions += '<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>'; | ||
394 | } | ||
395 | |||
396 | // Set full-screen | ||
397 | if (jQTSettings.fullScreen) { | ||
398 | hairExtensions += '<meta name="apple-mobile-web-app-capable" content="yes" />'; | ||
399 | if (jQTSettings.statusBar) { | ||
400 | hairExtensions += '<meta name="apple-mobile-web-app-status-bar-style" content="' + jQTSettings.statusBar + '" />'; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | // Attach hair extensions | ||
405 | if (hairExtensions) { | ||
406 | $head.prepend(hairExtensions); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | function getAnimation(el) { | ||
411 | var animation; | ||
412 | |||
413 | for (var i=0, max=animations.length; i < max; i++) { | ||
414 | if (el.is(animations[i].selector)) { | ||
415 | animation = animations[i]; | ||
416 | break; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | if (!animation) { | ||
421 | warn('Animation could not be found. Using ' + jQTSettings.defaultAnimation + '.'); | ||
422 | animation = jQTSettings.defaultAnimation; | ||
423 | } | ||
424 | return animation; | ||
425 | } | ||
426 | |||
427 | function insertPages(nodes, animation) { | ||
428 | |||
429 | var targetPage = null; | ||
430 | |||
431 | // Call dom.createElement element directly instead of relying on $(nodes), | ||
432 | // to work around: https://github.com/madrobby/zepto/issues/312 | ||
433 | var div = document.createElement('div'); | ||
434 | div.innerHTML = nodes; | ||
435 | |||
436 | $(div).children().each(function(index, node) { | ||
437 | var $node = $(this); | ||
438 | if (!$node.attr('id')) { | ||
439 | $node.attr('id', 'page-' + (++newPageCount)); | ||
440 | } | ||
441 | |||
442 | // Remove any existing instance | ||
443 | $('#' + $node.attr('id')).remove(); | ||
444 | |||
445 | $body.append($node); | ||
446 | $body.trigger('pageInserted', {page: $node}); | ||
447 | |||
448 | if ($node.hasClass('current') || !targetPage) { | ||
449 | targetPage = $node; | ||
450 | } | ||
451 | }); | ||
452 | if (targetPage !== null) { | ||
453 | goTo(targetPage, animation); | ||
454 | return targetPage; | ||
455 | } else { | ||
456 | return false; | ||
457 | } | ||
458 | } | ||
459 | |||
460 | function orientationChangeHandler() { | ||
461 | $body.css('minHeight', 1000); | ||
462 | scrollTo(0,0); | ||
463 | var bodyHeight = window.innerHeight; | ||
464 | $body.css('minHeight', bodyHeight); | ||
465 | |||
466 | orientation = Math.abs(window.orientation) == 90 ? 'landscape' : 'portrait'; | ||
467 | $body.removeClass('portrait landscape').addClass(orientation).trigger('turn', {orientation: orientation}); | ||
468 | } | ||
469 | function setHash(hash) { | ||
470 | // Sanitize | ||
471 | location.hash = '#' + hash.replace(/^#/, ''); | ||
472 | } | ||
473 | function showPageByHref(href, options) { | ||
474 | |||
475 | var defaults = { | ||
476 | data: null, | ||
477 | method: 'GET', | ||
478 | animation: null, | ||
479 | callback: null, | ||
480 | $referrer: null | ||
481 | }; | ||
482 | |||
483 | var settings = $.extend({}, defaults, options); | ||
484 | |||
485 | if (href != '#') { | ||
486 | $.ajax({ | ||
487 | url: href, | ||
488 | data: settings.data, | ||
489 | type: settings.method, | ||
490 | success: function (data) { | ||
491 | var firstPage = insertPages(data, settings.animation); | ||
492 | if (firstPage) { | ||
493 | if (settings.method == 'GET' && jQTSettings.cacheGetRequests === true && settings.$referrer) { | ||
494 | settings.$referrer.attr('href', '#' + firstPage.attr('id')); | ||
495 | } | ||
496 | if (settings.callback) { | ||
497 | settings.callback(true); | ||
498 | } | ||
499 | } | ||
500 | }, | ||
501 | error: function (data) { | ||
502 | if (settings.$referrer) { | ||
503 | settings.$referrer.unselect(); | ||
504 | } | ||
505 | if (settings.callback) { | ||
506 | settings.callback(false); | ||
507 | } | ||
508 | } | ||
509 | }); | ||
510 | } else if (settings.$referrer) { | ||
511 | settings.$referrer.unselect(); | ||
512 | } | ||
513 | } | ||
514 | function submitHandler(e, callback) { | ||
515 | |||
516 | $(':focus').trigger('blur'); | ||
517 | |||
518 | e.preventDefault(); | ||
519 | |||
520 | var $form = (typeof(e)==='string') ? $(e).eq(0) : (e.target ? $(e.target) : $(e)); | ||
521 | |||
522 | if ($form.length && $form.is(jQTSettings.formSelector) && $form.attr('action')) { | ||
523 | showPageByHref($form.attr('action'), { | ||
524 | data: $form.serialize(), | ||
525 | method: $form.attr('method') || "POST", | ||
526 | animation: getAnimation($form), | ||
527 | callback: callback | ||
528 | }); | ||
529 | return false; | ||
530 | } | ||
531 | return true; | ||
532 | } | ||
533 | function submitParentForm($el) { | ||
534 | |||
535 | var $form = $el.closest('form'); | ||
536 | if ($form.length === 0) { | ||
537 | warn('No parent form found'); | ||
538 | } else { | ||
539 | warn('About to submit parent form'); | ||
540 | $form.trigger('submit'); | ||
541 | return false; | ||
542 | } | ||
543 | return true; | ||
544 | } | ||
545 | function supportForTransform3d() { | ||
546 | |||
547 | var head, body, style, div, result; | ||
548 | |||
549 | head = document.getElementsByTagName('head')[0]; | ||
550 | body = document.body; | ||
551 | |||
552 | style = document.createElement('style'); | ||
553 | style.textContent = '@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-webkit-transform-3d){#jqt-3dtest{height:3px}}'; | ||
554 | |||
555 | div = document.createElement('div'); | ||
556 | div.id = 'jqt-3dtest'; | ||
557 | |||
558 | // Add to the page | ||
559 | head.appendChild(style); | ||
560 | body.appendChild(div); | ||
561 | |||
562 | // Check the result | ||
563 | result = div.offsetHeight === 3; | ||
564 | |||
565 | // Clean up | ||
566 | style.parentNode.removeChild(style); | ||
567 | div.parentNode.removeChild(div); | ||
568 | |||
569 | // Pass back result | ||
570 | warn('Support for 3d transforms: ' + result); | ||
571 | return result; | ||
572 | } | ||
573 | function supportIOS5() { | ||
574 | var support = false; | ||
575 | var REGEX_IOS_VERSION = /OS (\d+)(_\d+)* like Mac OS X/i; | ||
576 | |||
577 | var agentString = window.navigator.userAgent; | ||
578 | if (REGEX_IOS_VERSION.test(agentString)) { | ||
579 | support = (REGEX_IOS_VERSION.exec(agentString)[1] >= 5); | ||
580 | } | ||
581 | return support; | ||
582 | } | ||
583 | function touchStartHandler(e){ | ||
584 | |||
585 | var $el = $(e.target), | ||
586 | selectors = touchSelectors.join(', '); | ||
587 | |||
588 | // Find the nearest tappable ancestor | ||
589 | if (!$el.is(selectors)) { | ||
590 | $el = $el.closest(selectors); | ||
591 | } | ||
592 | |||
593 | // Make sure we have a tappable element | ||
594 | if ($el.length && $el.attr('href')) { | ||
595 | $el.addClass('active'); | ||
596 | } | ||
597 | |||
598 | // Remove our active class if we move | ||
599 | $el.on($.support.touch ? 'touchmove' : 'mousemove', function(){ | ||
600 | $el.removeClass('active'); | ||
601 | }); | ||
602 | |||
603 | $el.on('touchend', function(){ | ||
604 | $el.unbind('touchmove mousemove'); | ||
605 | }); | ||
606 | |||
607 | } | ||
608 | function tapHandler(e){ | ||
609 | |||
610 | if (e.isDefaultPrevented()) { | ||
611 | return true; | ||
612 | } | ||
613 | |||
614 | // Grab the target element | ||
615 | var $el = $(e.target); | ||
616 | |||
617 | // Find the nearest tappable ancestor | ||
618 | if (!$el.is(touchSelectors.join(', '))) { | ||
619 | $el = $el.closest(touchSelectors.join(', ')); | ||
620 | } | ||
621 | |||
622 | // Make sure we have a tappable element | ||
623 | if (!$el.length || !$el.attr('href')) { | ||
624 | warn('Could not find a link related to tapped element'); | ||
625 | return true; | ||
626 | } | ||
627 | |||
628 | // Init some vars | ||
629 | var target = $el.attr('target'), | ||
630 | hash = $el.prop('hash'), | ||
631 | href = $el.attr('href'); | ||
632 | |||
633 | var params = { | ||
634 | e: e, | ||
635 | $el: $el, | ||
636 | target: target, | ||
637 | hash: hash, | ||
638 | href: href, | ||
639 | jQTSettings: jQTSettings | ||
640 | }; | ||
641 | |||
642 | // Loop thru all handlers | ||
643 | for (var i=0, len=tapHandlers.length; i<len; i++) { | ||
644 | var handler = tapHandlers[i]; | ||
645 | var supported = handler.isSupported(e, params); | ||
646 | if (supported) { | ||
647 | var flag = handler.fn(e, params); | ||
648 | return flag; | ||
649 | } | ||
650 | } | ||
651 | } | ||
652 | function addDefaultTapHandlers() { | ||
653 | addTapHandler({ | ||
654 | name: 'external-link', | ||
655 | isSupported: function(e, params) { | ||
656 | return params.$el.isExternalLink(); | ||
657 | }, | ||
658 | fn: function(e, params) { | ||
659 | params.$el.unselect(); | ||
660 | return true; | ||
661 | } | ||
662 | }); | ||
663 | addTapHandler({ | ||
664 | name: 'back-selector', | ||
665 | isSupported: function(e, params) { | ||
666 | return params.$el.is(params.jQTSettings.backSelector); | ||
667 | }, | ||
668 | fn: function(e, params) { | ||
669 | // User clicked or tapped a back button | ||
670 | goBack(params.hash); | ||
671 | } | ||
672 | }); | ||
673 | addTapHandler({ | ||
674 | name: 'submit-selector', | ||
675 | isSupported: function(e, params) { | ||
676 | return params.$el.is(params.jQTSettings.submitSelector); | ||
677 | }, | ||
678 | fn: function(e, params) { | ||
679 | // User clicked or tapped a submit element | ||
680 | submitParentForm(params.$el); | ||
681 | } | ||
682 | }); | ||
683 | addTapHandler({ | ||
684 | name: 'webapp', | ||
685 | isSupported: function(e, params) { | ||
686 | return params.target === '_webapp'; | ||
687 | }, | ||
688 | fn: function(e, params) { | ||
689 | // User clicked or tapped an internal link, fullscreen mode | ||
690 | window.location = params.href; | ||
691 | return false; | ||
692 | } | ||
693 | }); | ||
694 | addTapHandler({ | ||
695 | name: 'no-op', | ||
696 | isSupported: function(e, params) { | ||
697 | return params.href === '#'; | ||
698 | }, | ||
699 | fn: function(e, params) { | ||
700 | // Allow tap on item with no href | ||
701 | params.$el.unselect(); | ||
702 | return true; | ||
703 | } | ||
704 | }); | ||
705 | addTapHandler({ | ||
706 | name: 'standard', | ||
707 | isSupported: function(e, params) { | ||
708 | return params.hash && params.hash !== '#'; | ||
709 | }, | ||
710 | fn: function(e, params) { | ||
711 | var animation = getAnimation(params.$el); | ||
712 | // Internal href | ||
713 | params.$el.addClass('active'); | ||
714 | goTo( | ||
715 | $(params.hash).data('referrer', params.$el), | ||
716 | animation, | ||
717 | params.$el.hasClass('reverse') | ||
718 | ); | ||
719 | return false; | ||
720 | } | ||
721 | }); | ||
722 | addTapHandler({ | ||
723 | name: 'external', | ||
724 | isSupported: function(e, params) { | ||
725 | return true; | ||
726 | }, | ||
727 | fn: function(e, params) { | ||
728 | var animation = getAnimation(params.$el); | ||
729 | |||
730 | // External href | ||
731 | params.$el.addClass('loading active'); | ||
732 | showPageByHref(params.$el.attr('href'), { | ||
733 | animation: animation, | ||
734 | callback: function() { | ||
735 | params.$el.removeClass('loading'); | ||
736 | setTimeout($.fn.unselect, 250, params.$el); | ||
737 | }, | ||
738 | $referrer: params.$el | ||
739 | }); | ||
740 | return false; | ||
741 | } | ||
742 | }); | ||
743 | }; | ||
744 | |||
745 | // Get the party started | ||
746 | init(options); | ||
747 | |||
748 | // Document ready stuff | ||
749 | $(document).ready(function RUMBLE() { | ||
750 | // Store some properties in a support object | ||
751 | if (!$.support) $.support = {}; | ||
752 | $.support.animationEvents = (typeof window.WebKitAnimationEvent != 'undefined'); | ||
753 | $.support.touch = (typeof window.TouchEvent != 'undefined') && (window.navigator.userAgent.indexOf('Mobile') > -1) && jQTSettings.useFastTouch; | ||
754 | $.support.transform3d = supportForTransform3d(); | ||
755 | $.support.ios5 = supportIOS5(); | ||
756 | |||
757 | if (!$.support.touch) { | ||
758 | warn('This device does not support touch interaction, or it has been deactivated by the developer. Some features might be unavailable.'); | ||
759 | } | ||
760 | if (!$.support.transform3d) { | ||
761 | warn('This device does not support 3d animation. 2d animations will be used instead.'); | ||
762 | } | ||
763 | |||
764 | // Define public jQuery functions | ||
765 | $.fn.isExternalLink = function() { | ||
766 | var $el = $(this); | ||
767 | return ($el.attr('target') == '_blank' || $el.attr('rel') == 'external' || $el.is('a[href^="http://maps.google.com"], a[href^="mailto:"], a[href^="tel:"], a[href^="javascript:"], a[href*="youtube.com/v"], a[href*="youtube.com/watch"]')); | ||
768 | }; | ||
769 | $.fn.makeActive = function() { | ||
770 | return $(this).addClass('active'); | ||
771 | }; | ||
772 | $.fn.unselect = function(obj) { | ||
773 | if (obj) { | ||
774 | obj.removeClass('active'); | ||
775 | } else { | ||
776 | $('.active').removeClass('active'); | ||
777 | } | ||
778 | }; | ||
779 | |||
780 | // Add extensions | ||
781 | for (var i=0, max=extensions.length; i < max; i++) { | ||
782 | var fn = extensions[i]; | ||
783 | if ($.isFunction(fn)) { | ||
784 | $.extend(publicObj, fn(publicObj)); | ||
785 | } | ||
786 | } | ||
787 | |||
788 | // Add extensions tapHandlers | ||
789 | for (var i=0, max=extTapHandlers.length; i < max; i++) { | ||
790 | addTapHandler(extTapHandlers[i]); | ||
791 | } | ||
792 | // Add default tapHandlers | ||
793 | addDefaultTapHandlers(); | ||
794 | |||
795 | // Add animations | ||
796 | for (var j=0, max_anims=defaults.animations.length; j < max_anims; j++) { | ||
797 | var animation = defaults.animations[j]; | ||
798 | if(jQTSettings[animation.name + 'Selector'] !== undefined){ | ||
799 | animation.selector = jQTSettings[animation.name + 'Selector']; | ||
800 | } | ||
801 | addAnimation(animation); | ||
802 | } | ||
803 | |||
804 | // Create an array of stuff that needs touch event handling | ||
805 | touchSelectors.push(jQTSettings.touchSelector); | ||
806 | touchSelectors.push(jQTSettings.backSelector); | ||
807 | touchSelectors.push(jQTSettings.submitSelector); | ||
808 | $(touchSelectors.join(', ')).css('-webkit-touch-callout', 'none'); | ||
809 | |||
810 | // Make sure we have a jqt element | ||
811 | $body = $('#jqt'); | ||
812 | var anatomy_lessons = []; | ||
813 | |||
814 | if ($body.length === 0) { | ||
815 | warn('Could not find an element with the id "jqt", so the body id has been set to "jqt". If you are having any problems, wrapping your panels in a div with the id "jqt" might help.'); | ||
816 | $body = $(document.body).attr('id', 'jqt'); | ||
817 | } | ||
818 | |||
819 | // Add some specific css if need be | ||
820 | if ($.support.transform3d) { | ||
821 | anatomy_lessons.push('supports3d'); | ||
822 | } | ||
823 | if ($.support.ios5 && jQTSettings.useTouchScroll) { | ||
824 | anatomy_lessons.push('touchscroll'); | ||
825 | } | ||
826 | |||
827 | if (jQTSettings.fullScreenClass && window.navigator.standalone === true) { | ||
828 | anatomy_lessons.push(jQTSettings.fullScreenClass, jQTSettings.statusBar); | ||
829 | } | ||
830 | |||
831 | // Bind events | ||
832 | |||
833 | $body | ||
834 | .addClass(anatomy_lessons.join(' ')) | ||
835 | .bind('click', clickHandler) | ||
836 | .bind('orientationchange', orientationChangeHandler) | ||
837 | .bind('submit', submitHandler) | ||
838 | .bind('tap', tapHandler) | ||
839 | .bind( $.support.touch ? 'touchstart' : 'mousedown', touchStartHandler) | ||
840 | .trigger('orientationchange'); | ||
841 | |||
842 | $(window).bind('hashchange', hashChangeHandler); | ||
843 | |||
844 | var startHash = location.hash; | ||
845 | |||
846 | // Determine what the initial view should be | ||
847 | if ($('#jqt > .current').length === 0) { | ||
848 | $currentPage = $('#jqt > *:first-child').addClass('current'); | ||
849 | } else { | ||
850 | $currentPage = $('#jqt > .current'); | ||
851 | } | ||
852 | |||
853 | setHash($currentPage.attr('id')); | ||
854 | addPageToHistory($currentPage); | ||
855 | |||
856 | if ($(startHash).length === 1) { | ||
857 | goTo(startHash); | ||
858 | } | ||
859 | }); | ||
860 | |||
861 | // Expose public methods and properties | ||
862 | publicObj = { | ||
863 | addAnimation: addAnimation, | ||
864 | animations: animations, | ||
865 | getOrientation: getOrientation, | ||
866 | goBack: goBack, | ||
867 | insertPages: insertPages, | ||
868 | goTo: goTo, | ||
869 | history: history, | ||
870 | settings: jQTSettings, | ||
871 | submitForm: submitHandler | ||
872 | }; | ||
873 | return publicObj; | ||
874 | }; | ||
875 | |||
876 | $.jQTouch.prototype.extensions = []; | ||
877 | $.jQTouch.prototype.tapHandlers = []; | ||
878 | |||
879 | // Extensions directly manipulate the jQTouch object, before it's initialized. | ||
880 | $.jQTouch.addExtension = function(extension) { | ||
881 | $.jQTouch.prototype.extensions.push(extension); | ||
882 | }; | ||
883 | |||
884 | // Experimental tap hanlders that can bypass default jQTouch tap handling | ||
885 | $.jQTouch.addTapHandler = function(extension) { | ||
886 | $.jQTouch.prototype.tapHandlers.push(extension); | ||
887 | }; | ||
888 | |||
889 | })(); // Double closure, ALL THE WAY ACROSS THE SKY | ||