summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/JQTouch/jqtouch.js
Unidiff
Diffstat (limited to 'frontend/gamma/js/JQTouch/jqtouch.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/JQTouch/jqtouch.js889
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