From 08e10b55a8bef9097196004c19a63dae711f714a Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Thu, 24 Aug 2017 12:42:53 -0400 Subject: [PATCH] jqtouch is now jqt, though it looks like we should just drop this instead. --- client/bower.json | 1 - client/galaxy/scripts/libs/jquery/jqtouch.js | 1566 ++++++++---------- client/grunt-tasks/install-libs.js | 1 - client/gulpfile.js | 1 + client/package.json | 1 + client/yarn.lock | 4 + static/scripts/libs/jquery/jqtouch.js | 2 +- 7 files changed, 722 insertions(+), 854 deletions(-) diff --git a/client/bower.json b/client/bower.json index 115c495dac0..30e8eaae596 100644 --- a/client/bower.json +++ b/client/bower.json @@ -12,7 +12,6 @@ "bootstrap-tour": "~0.10.2", "farbtastic": "~2.0.0-alpha.1", "toastr": "~2.1.0", - "jQTouch": "git://github.com/senchalabs/jQTouch#~1.0.0", "jquery-form": "~3.46.0", "jquery-autocomplete": "git://github.com/dyve/jquery-autocomplete", "select2": "~3.5.2", diff --git a/client/galaxy/scripts/libs/jquery/jqtouch.js b/client/galaxy/scripts/libs/jquery/jqtouch.js index 0f5426d07c5..d29f65204f6 100644 --- a/client/galaxy/scripts/libs/jquery/jqtouch.js +++ b/client/galaxy/scripts/libs/jquery/jqtouch.js @@ -1,883 +1,747 @@ +/* + _/ _/_/ _/_/_/_/_/ _/ + _/ _/ _/ _/_/ _/ _/ _/_/_/ _/_/_/ + _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ + _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ + _/ _/_/ _/ _/ _/_/ _/_/_/ _/_/_/ _/ _/ + _/ + _/ + + Created by David Kaneda + Maintained by Thomas Yip + Sponsored by Sencha Labs + Special thanks to Jonathan Stark + + Documentation and issue tracking on GitHub + + (c) 2009-2015 Sencha Labs + + Version: 1.0.1- - 2015-01-31 + + jQTouch may be freely distributed under the MIT license. +*/ (function() { + $.jQT = (function() { + var $body, $currentPage, $head, animations, customHistory, newPageCount, tapBuffer, touchSelectors; - $.jQTouch = function(options) { - // Initialize internal jQT variables - var $body, - $head=$('head'), - history=[], - newPageCount=0, - jQTSettings={}, - $currentPage='', - orientation='portrait', - touchSelectors=[], - publicObj={}, - tapBuffer=100, // High click delay = ~350, quickest animation (slide) = 250 - extensions=$.jQTouch.prototype.extensions, - extTapHandlers=$.jQTouch.prototype.tapHandlers, - tapHandlers=[], - animations=[], - hairExtensions='', - defaults = { - addGlossToIcon: true, - backSelector: '.back, .cancel, .goback', - cacheGetRequests: true, - debug: true, - defaultAnimation: 'slideleft', - fixedViewport: true, - formSelector: 'form', - fullScreen: true, - fullScreenClass: 'fullscreen', - icon: null, - icon4: null, // available in iOS 4.2 and later - preloadImages: false, - starter: $(document).ready, - startupScreen: null, - statusBar: 'default', // other options: black-translucent, black - submitSelector: '.submit', - touchSelector: 'a, .touch', - trackScrollPositions: true, - updateHash: true, - useAnimations: true, - useFastTouch: true, - useTouchScroll: true, - animations: [ // highest to lowest priority - {name:'cubeleft', selector:'.cubeleft, .cube', is3d: true}, - {name:'cuberight', selector:'.cuberight', is3d: true}, - {name:'dissolve', selector:'.dissolve'}, - {name:'fade', selector:'.fade'}, - {name:'flipleft', selector:'.flipleft, .flip', is3d: true}, - {name:'flipright', selector:'.flipright', is3d: true}, - {name:'pop', selector:'.pop', is3d: true}, - {name:'swapleft', selector:'.swapleft, .swap', is3d: true}, - {name:'swapright', selector:'.swapright', is3d: true}, - {name:'slidedown', selector:'.slidedown'}, - {name:'slideright', selector:'.slideright'}, - {name:'slideup', selector:'.slideup'}, - {name:'slideleft', selector:'.slideleft, .slide, #jqt > * > ul li a'} - ] - }; // end defaults + jQT.prototype.extensions = []; - function warn(message) { - if (window.console !== undefined && jQTSettings.debug === true) { - console.warn(message); - } - } + jQT.prototype.animations = [ + { + name: "cubeleft", + selector: ".cubeleft, .cube", + is3d: true + }, { + name: "cuberight", + selector: ".cuberight", + is3d: true + }, { + name: "dissolve", + selector: ".dissolve" + }, { + name: "fade", + selector: ".fade" + }, { + name: "flipleft", + selector: ".flipleft, .flip", + is3d: true + }, { + name: "flipright", + selector: ".flipright", + is3d: true + }, { + name: "pop", + selector: ".pop", + is3d: true + }, { + name: "swapleft", + selector: ".swapleft, .swap", + is3d: true + }, { + name: "swapright", + selector: ".swapright", + is3d: true + }, { + name: "slidedown", + selector: ".slidedown" + }, { + name: "slideright", + selector: ".slideright" + }, { + name: "slideup", + selector: ".slideup" + }, { + name: "slideleft", + selector: ".slideleft, .slide, #jqt > * > ul li a" + } + ]; - function addAnimation(animation) { - if (typeof(animation.selector) === 'string' && typeof(animation.name) === 'string') { - animations.push(animation); - } - } + jQT.prototype.orientation = 'portrait'; - function addTapHandler(tapHandler) { - if (typeof(tapHandler.name) === 'string' && typeof(tapHandler.isSupported) === 'function' && typeof(tapHandler.fn) === 'function') { - tapHandlers.push(tapHandler); - } - } + jQT.prototype.tapHandlers = []; - function addPageToHistory(page, animation) { - history.unshift({ - page: page, - animation: animation, - hash: '#' + page.attr('id'), - id: page.attr('id') - }); - } + jQT.prototype.defaults = { + addGlossToIcon: true, + backSelector: ".back, .cancel, .goback", + cacheGetRequests: true, + defaultAnimation: "slideleft", + fixedViewport: true, + formSelector: "form", + fullScreen: true, + fullScreenClass: "fullscreen", + icon: null, + icon4: null, + minimalUIViewport: true, + preloadImages: false, + starter: $(document).ready, + startupScreen: null, + statusBar: "default", + submitSelector: ".submit", + touchSelector: "a, .touch", + updateHash: true, + useAnimations: true, + useFastTouch: true, + useTouchScroll: true + }; - // Unfortunately, we can not assume the 'tap' event - // is being used for links, forms, etc. - function clickHandler(e) { - // Figure out whether to prevent default - var $el = $(e.target); + jQT.addExtension = function(extension) { + return this.prototype.extensions.push(extension); + }; - // Find the nearest tappable ancestor - if (!$el.is(touchSelectors.join(', '))) { - $el = $(e.target).closest(touchSelectors.join(', ')); - } + jQT.addTapHandler = function(tapHandler) { + if (typeof tapHandler.name === "string" && typeof tapHandler.isSupported === "function" && typeof tapHandler.fn === "function") { + return this.prototype.tapHandlers.push(tapHandler); + } + }; - // Prevent default if we found an internal link - // (relative or absolute) - if ($el && $el.attr('href') && !$el.isExternalLink()) { - warn('Need to prevent default click behavior.'); - e.preventDefault(); - } else { - warn('No need to prevent default click behavior.'); - } + jQT.addAnimation = function(animation) { + if (typeof animation.selector === "string" && typeof animation.name === "string") { + return this.animations.push(animation); + } + }; - // Trigger a tap event if touchstart is not on the job - if ($.support.touch) { - warn('Not converting click to a tap event because touch handler is on the job.'); - } else { - warn('Converting click event to a tap event because touch handlers are not present or off.'); - $(e.target).trigger('tap', e); - } - } + $body = void 0; - function doNavigation(fromPage, toPage, animation, goingBack) { + $head = $("head"); - goingBack = goingBack ? goingBack : false; + animations = jQT.prototype.animations; - // Error check for target page - if (toPage === undefined || toPage.length === 0) { - $.fn.unselect(); - warn('Target element is missing.'); - return false; - } + customHistory = []; - // Error check for fromPage === toPage - if (toPage.hasClass('current')) { - $.fn.unselect(); - warn('You are already on the page you are trying to navigate to.'); - return false; - } + newPageCount = 0; - // Collapse the keyboard - $(':focus').trigger('blur'); + $currentPage = ""; - fromPage.trigger('pageAnimationStart', { direction: 'out', back: goingBack }); - toPage.trigger('pageAnimationStart', { direction: 'in', back: goingBack }); + touchSelectors = []; - if ($.support.animationEvents && animation && jQTSettings.useAnimations) { - // Fail over to 2d animation if need be - if (!$.support.transform3d && animation.is3d) { - warn('Did not detect support for 3d animations, falling back to ' + jQTSettings.defaultAnimation + '.'); - animation.name = jQTSettings.defaultAnimation; - } - - // Reverse animation if need be - var finalAnimationName = animation.name, - is3d = animation.is3d ? 'animating3d' : ''; - - if (goingBack) { - finalAnimationName = finalAnimationName.replace(/left|right|up|down|in|out/, reverseAnimation); - } - - warn('finalAnimationName is ' + finalAnimationName + '.'); - - // Bind internal 'cleanup' callback - fromPage.bind('webkitAnimationEnd', navigationEndHandler); - - // Trigger animations - $body.addClass('animating ' + is3d); - - var lastScroll = window.pageYOffset; - - // Position the incoming page so toolbar is at top of - // viewport regardless of scroll position on from page - if (jQTSettings.trackScrollPositions === true) { - toPage.css('top', window.pageYOffset - (toPage.data('lastScroll') || 0)); - } - - toPage.addClass(finalAnimationName + ' in current'); - fromPage.removeClass('current').addClass(finalAnimationName + ' out inmotion'); - - if (jQTSettings.trackScrollPositions === true) { - fromPage.data('lastScroll', lastScroll); - $('.scroll', fromPage).each(function() { - $(this).data('lastScroll', this.scrollTop); - }); - } - } else { - toPage.addClass('current in'); - fromPage.removeClass('current'); - navigationEndHandler(); - } - - // Housekeeping - $currentPage = toPage; - if (goingBack) { - history.shift(); - } else { - addPageToHistory($currentPage, animation); - } - setHash($currentPage.attr('id')); - - // Private navigationEnd callback - function navigationEndHandler(event) { - var bufferTime = tapBuffer; - - if ($.support.animationEvents && animation && jQTSettings.useAnimations) { - fromPage.unbind('webkitAnimationEnd', navigationEndHandler); - fromPage.removeClass(finalAnimationName + ' out inmotion'); - if (finalAnimationName) { - toPage.removeClass(finalAnimationName); - } - $body.removeClass('animating animating3d'); - if (jQTSettings.trackScrollPositions === true) { - toPage.css('top', -toPage.data('lastScroll')); - - // Have to make sure the scroll/style resets - // are outside the flow of this function. - setTimeout(function() { - toPage.css('top', 0); - window.scroll(0, toPage.data('lastScroll')); - $('.scroll', toPage).each(function() { - this.scrollTop = - $(this).data('lastScroll'); - }); - }, 0); - } - } else { - fromPage.removeClass(finalAnimationName + ' out inmotion'); - if (finalAnimationName) { - toPage.removeClass(finalAnimationName); - } - bufferTime += 260; - } - - // 'in' class is intentionally delayed, - // as it is our ghost click hack - setTimeout(function() { - toPage.removeClass('in'); - window.scroll(0,0); - }, bufferTime); - - fromPage.unselect(); - - // Trigger custom events - toPage.trigger('pageAnimationEnd', { - direction:'in', - animation: animation, - back: goingBack - }); - fromPage.trigger('pageAnimationEnd', { - direction:'out', - animation: animation, - back: goingBack - }); - } + tapBuffer = 100; + function jQT(options) { + var addPageToHistory, clickHandler, doNavigation, getAnimation, hashChangeHandler, initHairExtensions, insertPages, isExternalLink, orientationChangeHandler, reverseAnimation, setHash, showPageByHref, start, submitHandler, submitParentForm, support, tapHandler, touchStartHandler; + this.tapHandlers = this.tapHandlers.concat([ + { + name: "external-link", + isSupported: function(e, params) { + return isExternalLink(params.$el); + }, + fn: function(e, params) { + params.$el.removeClass('active'); return true; - } - - function reverseAnimation(animation) { - var opposites={ - 'up' : 'down', - 'down' : 'up', - 'left' : 'right', - 'right' : 'left', - 'in' : 'out', - 'out' : 'in' + } + }, { + name: "back-selector", + isSupported: (function(_this) { + return function(e, params) { + return params.$el.is(_this.settings.backSelector); }; - - return opposites[animation] || animation; - } - - function getOrientation() { - return orientation; - } - - function goBack() { - // Error checking - if (history.length < 1) { - warn('History is empty.'); - } - - if (history.length === 1) { - warn('You are on the first panel.'); - window.history.go(-1); - } - - var from = history[0], - to = history[1]; - - if (doNavigation(from.page, to.page, from.animation, true)) { - return publicObj; - } else { - warn('Could not go back.'); - return false; - } - } - - function goTo(toPage, animation) { - var fromPage = history[0].page; - - if (typeof animation === 'string') { - for (var i=0, max=animations.length; i < max; i++) { - if (animations[i].name === animation) { - animation = animations[i]; - break; - } - } - } - - if (typeof toPage === 'string') { - var nextPage = $(toPage); - - if (nextPage.length < 1) { - showPageByHref(toPage, { - animation: animation - }); - return; - } else { - toPage = nextPage; - } - } - if (doNavigation(fromPage, toPage, animation)) { - return publicObj; - } else { - warn('Could not animate pages.'); - return false; - } - } - - function hashChangeHandler(e) { - if (location.hash === history[0].hash) { - warn('We are on the right panel.'); - return true; - } else if (location.hash === '') { - goBack(); - return true; - } else if (history[1] && location.hash === history[1].hash) { - goBack(); - return true; - } else { - // Lastly, just try going to the ID... - warn('Could not find ID in history, just forwarding to DOM element.'); - goTo($(location.hash), jQTSettings.defaultAnimation); - } - } - - function initHairExtensions(options) { - // Preload images - if (jQTSettings.preloadImages) { - for (var i = jQTSettings.preloadImages.length - 1; i >= 0; i--) { - (new Image()).src = jQTSettings.preloadImages[i]; - } - } - - // Set appropriate icon - // (retina display available in iOS 4.2 and later.) - var precomposed = (jQTSettings.addGlossToIcon) ? '' : '-precomposed'; - if (jQTSettings.icon) { - hairExtensions += ''; - } - if (jQTSettings.icon4) { - hairExtensions += ''; - } - // Set startup screen - if (jQTSettings.startupScreen) { - hairExtensions += ''; - } - - // Set viewport - if (jQTSettings.fixedViewport) { - hairExtensions += ''; - } - - // Set full-screen - if (jQTSettings.fullScreen) { - hairExtensions += ''; - if (jQTSettings.statusBar) { - hairExtensions += ''; - } - } - - // Attach hair extensions - if (hairExtensions) { - $head.prepend(hairExtensions); - } - } - - function initFXExtensions() { - // Define public jQuery functions - $.fn.isExternalLink = function() { - var $el = $(this); - 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"]')); + })(this), + fn: (function(_this) { + return function(e, params) { + _this.goBack(params.hash); + return false; }; - $.fn.makeActive = function() { - return $(this).addClass('active'); + })(this) + }, { + name: "submit-selector", + isSupported: (function(_this) { + return function(e, params) { + return params.$el.is(_this.settings.submitSelector); }; - $.fn.unselect = function(obj) { - if (obj) { - obj.removeClass('active'); - } else { - $('.active').removeClass('active'); - } + })(this), + fn: function(e, params) { + submitParentForm(params.$el); + } + }, { + name: "webapp", + isSupported: function(e, params) { + return params.target === "_webapp"; + }, + fn: function(e, params) { + window.location = params.href; + return false; + } + }, { + name: "no-op", + isSupported: function(e, params) { + return params.href === "#"; + }, + fn: function(e, params) { + params.$el.removeClass('active'); + return true; + } + }, { + name: "standard", + isSupported: function(e, params) { + return params.hash && params.hash !== "#"; + }, + fn: (function(_this) { + return function(e, params) { + var animation; + animation = getAnimation(params.$el); + params.$el.addClass("active"); + _this.goTo($(params.hash).data("referrer", params.$el), animation, params.$el.hasClass("reverse")); + return false; }; - } - - function getAnimation(el) { + })(this) + }, { + name: "external", + isSupported: function(e, params) { + return true; + }, + fn: function(e, params) { var animation; - - for (var i=0, max=animations.length; i < max; i++) { - if (el.is(animations[i].selector)) { - animation = animations[i]; - break; - } - } - - if (!animation) { - warn('Animation could not be found. Using ' + jQTSettings.defaultAnimation + '.'); - animation = jQTSettings.defaultAnimation; - } - return animation; - } - - function insertPages(nodes, animation) { - - var targetPage = null; - - // Call dom.createElement element directly - // instead of relying on $(nodes), to work around: - // https://github.com/madrobby/zepto/issues/312 - var div = document.createElement('div'); - div.innerHTML = nodes; - - $(div).children().each(function(index, node) { - var $node = $(this); - if (!$node.attr('id')) { - $node.attr('id', 'page-' + (++newPageCount)); - } - - // Remove any existing instance - $('#' + $node.attr('id')).remove(); - - $body.append($node); - $body.trigger('pageInserted', {page: $node}); - - if ($node.hasClass('current') || !targetPage) { - targetPage = $node; - } + animation = getAnimation(params.$el); + params.$el.addClass("loading active"); + showPageByHref(params.$el.attr("href"), { + animation: animation, + callback: function() { + params.$el.removeClass("loading"); + return setTimeout(function() { + return params.$el.removeClass('active'); + }, 250); + }, + $referrer: params.$el }); - if (targetPage !== null) { - goTo(targetPage, animation); - return targetPage; + return false; + } + } + ]); + this.goTo = (function(_this) { + return function(toPage, animation) { + var anim, fromPage, nextPage, _i, _len; + fromPage = customHistory[0].page; + if (typeof animation === "string") { + for (_i = 0, _len = animations.length; _i < _len; _i++) { + anim = animations[_i]; + if (anim.name === animation) { + animation = anim; + break; + } + } + } + if (typeof toPage === "string") { + nextPage = $(toPage); + if (!nextPage.length) { + showPageByHref(toPage, { + animation: animation + }); + return; } else { - return false; + toPage = nextPage; } - } - - function orientationChangeHandler() { - scrollTo(0,0); - orientation = Math.abs(window.orientation) === 90 ? 'landscape' : 'portrait'; - $body.removeClass('portrait landscape').addClass(orientation).trigger('turn', {orientation: orientation}); - } - - function setHash(hash) { - // Sanitize - if (jQTSettings.updateHash) { - location.hash = '#' + hash.replace(/^#/, ''); - } - } - - // Document ready stuff - function start() { - // Store some properties in a support object - if (!$.support) $.support = {}; - $.support.animationEvents = (typeof window.WebKitAnimationEvent !== 'undefined'); - $.support.touch = (typeof window.TouchEvent !== 'undefined') && (window.navigator.userAgent.indexOf('Mobile') > -1) && jQTSettings.useFastTouch; - $.support.transform3d = supportForTransform3d(); - $.support.ios5 = supportIOS5(); - - if (!$.support.touch) { - warn('This device does not support touch interaction, or it has been deactivated by the developer. Some features might be unavailable.'); - } - if (!$.support.transform3d) { - warn('This device does not support 3d animation. 2d animations will be used instead.'); - } - - // Add extensions - for (var i=0, max=extensions.length; i < max; i++) { - var fn = extensions[i]; - if ($.isFunction(fn)) { - $.extend(publicObj, fn(publicObj)); - } - } - - // Add extensions tapHandlers - for (var j=0, maxTapHandlers=extTapHandlers.length; j < maxTapHandlers; j++) { - addTapHandler(extTapHandlers[j]); - } - // Add default tapHandlers - addDefaultTapHandlers(); - - // Add animations - for (var k=0, maxAnimations=defaults.animations.length; k < maxAnimations; k++) { - var animation = defaults.animations[k]; - if (jQTSettings[animation.name + 'Selector'] !== undefined) { - animation.selector = jQTSettings[animation.name + 'Selector']; - } - addAnimation(animation); - } - - // Create an array of stuff that needs touch event handling - touchSelectors.push(jQTSettings.touchSelector); - touchSelectors.push(jQTSettings.backSelector); - touchSelectors.push(jQTSettings.submitSelector); - $(touchSelectors.join(', ')).css('-webkit-touch-callout', 'none'); - - // Make sure we have a jqt element - $body = $('#jqt'); - var anatomyLessons = []; - - if ($body.length === 0) { - 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.'); - $body = $(document.body).attr('id', 'jqt'); - } - - // Add some specific css if need be - if ($.support.transform3d) { - anatomyLessons.push('supports3d'); - } - - if (jQTSettings.useTouchScroll) { - if ($.support.ios5) { - anatomyLessons.push('touchscroll'); - } else { - anatomyLessons.push('autoscroll'); - } - } - - if (jQTSettings.fullScreenClass && window.navigator.standalone === true) { - anatomyLessons.push(jQTSettings.fullScreenClass, jQTSettings.statusBar); - } - - // Bind events - $body - .addClass(anatomyLessons.join(' ')) - .bind('click', clickHandler) - .bind('orientationchange', orientationChangeHandler) - .bind('submit', submitHandler) - .bind('tap', tapHandler) - .bind($.support.touch ? 'touchstart' : 'mousedown', touchStartHandler) - .trigger('orientationchange'); - - $(window).bind('hashchange', hashChangeHandler); - - var startHash = location.hash; - - // Determine what the initial view should be - if ($('#jqt > .current').length === 0) { - $currentPage = $('#jqt > *:first-child').addClass('current'); - } else { - $currentPage = $('#jqt > .current'); - } - - setHash($currentPage.attr('id')); - addPageToHistory($currentPage); - - if ($(startHash).length === 1) { - goTo(startHash); - } - } - - function showPageByHref(href, options) { - - var defaults = { - data: null, - method: 'GET', - animation: null, - callback: null, - $referrer: null - }; - - var settings = $.extend({}, defaults, options); - - if (href !== '#') { - $.ajax({ - url: href, - data: settings.data, - type: settings.method, - success: function (data) { - var firstPage = insertPages(data, settings.animation); - if (firstPage) { - if (settings.method === 'GET' && jQTSettings.cacheGetRequests === true && settings.$referrer) { - settings.$referrer.attr('href', '#' + firstPage.attr('id')); - } - if (settings.callback) { - settings.callback(true); - } - } - }, - error: function (data) { - if (settings.$referrer) { - settings.$referrer.unselect(); - } - if (settings.callback) { - settings.callback(false); - } - } - }); - } else if (settings.$referrer) { - settings.$referrer.unselect(); - } - } - - function submitHandler(e, callback) { - - $(':focus').trigger('blur'); - - e.preventDefault(); - - var $form = (typeof(e)==='string') ? $(e).eq(0) : (e.target ? $(e.target) : $(e)); - - if ($form.length && $form.is(jQTSettings.formSelector) && $form.attr('action')) { - showPageByHref($form.attr('action'), { - data: $form.serialize(), - method: $form.attr('method') || 'POST', - animation: getAnimation($form), - callback: callback - }); - return false; - } - return true; - } - - function submitParentForm($el) { - - var $form = $el.closest('form'); - if ($form.length === 0) { - warn('No parent form found.'); - } else { - warn('About to submit parent form.'); - $form.trigger('submit'); - return false; - } - return true; - } - - function supportForTransform3d() { - - var head, body, style, div, result; - - head = document.getElementsByTagName('head')[0]; - body = document.body; - - style = document.createElement('style'); - style.textContent = '@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-webkit-transform-3d){#jqt-3dtest{height:3px}}'; - - div = document.createElement('div'); - div.id = 'jqt-3dtest'; - - // Add to the page - head.appendChild(style); - body.appendChild(div); - - // Check the result - result = div.offsetHeight === 3; - - // Clean up - style.parentNode.removeChild(style); - div.parentNode.removeChild(div); - - // Pass back result - warn('Support for 3d transforms: ' + result + '.'); - return result; - } - - function supportIOS5() { - var support = false; - var REGEX_IOS_VERSION = /OS (\d+)(_\d+)* like Mac OS X/i; - - var agentString = window.navigator.userAgent; - if (REGEX_IOS_VERSION.test(agentString)) { - support = (REGEX_IOS_VERSION.exec(agentString)[1] >= 5); - } - return support; - } - - function touchStartHandler(e) { - - var $el = $(e.target), - selectors = touchSelectors.join(', '); - - // Find the nearest tappable ancestor - if (!$el.is(selectors)) { - $el = $el.closest(selectors); - } - - // Make sure we have a tappable element - if ($el.length && $el.attr('href')) { - $el.addClass('active'); - } - - // Remove our active class if we move - $el.on($.support.touch ? 'touchmove' : 'mousemove', function() { - $el.removeClass('active'); - }); - - $el.on('touchend', function() { - $el.unbind('touchmove mousemove'); - }); - } - - function tapHandler(e) { - - if (e.isDefaultPrevented()) { - return true; - } - - // Grab the target element - var $el = $(e.target); - - // Find the nearest tappable ancestor - if (!$el.is(touchSelectors.join(', '))) { - $el = $el.closest(touchSelectors.join(', ')); - } - - // Make sure we have a tappable element - if (!$el.length || !$el.attr('href')) { - warn('Could not find a link related to tapped element.'); - return true; - } - - // Init some vars - var target = $el.attr('target'), - hash = $el.prop('hash'), - href = $el.attr('href'); - - var params = { - e: e, - $el: $el, - target: target, - hash: hash, - href: href, - jQTSettings: jQTSettings - }; - - // Loop thru all handlers - for (var i=0, len=tapHandlers.length; i 0) { + customHistory.splice(1, toPage); + } else if (toPage < 0) { + customHistory.splice(1, customHistory.length + toPage - 1); + } + } else if (/^#.+/.test(toPage)) { + end = 0; + for (i = _i = 0, _len = customHistory.length; _i < _len; i = ++_i) { + h = customHistory[i]; + if (h.hash === toPage) { + end = i; + break; + } + } + customHistory.splice(1, end - 1); + } + from = customHistory[0]; + to = customHistory[1]; + if (!((from != null) && (to != null))) { + return; + } + if (doNavigation(from.page, to.page, from.animation, true)) { + _this; + } else { + console.warn("Could not go back."); + return false; + } + }; + })(this); + this.history = customHistory; + initHairExtensions = (function(_this) { + return function(options) { + var hairExtensions, i, precomposed, viewports, _i, _len, _ref; + _ref = _this.settings.preloadImages; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + i = _ref[_i]; + (new Image()).src = _this.settings.preloadImages[i]; + } + hairExtensions = []; + precomposed = _this.settings.addGlossToIcon ? '' : '-precomposed'; + if (_this.settings.icon) { + hairExtensions.push(""); + } + if (_this.settings.icon4) { + hairExtensions.push(""); + } + if (_this.settings.startupScreen) { + hairExtensions.push(""); + } + viewports = []; + if (_this.settings.fixedViewport) { + viewports.push("initial-scale=1.0", "maximum-scale=1.0", "user-scalable=0"); + } + if (_this.settings.minimalUIViewport) { + viewports.push("minimal-ui"); + } + if (viewports) { + hairExtensions.push(""); + } + if (_this.settings.fullScreen) { + hairExtensions.push(""); + if (_this.settings.statusBar) { + hairExtensions.push(""); + } + } + if (hairExtensions.length) { + return $head.prepend(hairExtensions.join('')); + } + }; + })(this); + insertPages = (function(_this) { + return function(nodes, animation) { + var targetPage; + targetPage = null; + $(nodes).each(function(index, node) { + var $node; + $node = $(this); + if (!$node.attr("id")) { + $node.attr("id", "page-" + (++newPageCount)); + } + $("#" + $node.attr("id")).remove(); + $body.append($node); + $body.trigger("pageInserted", { + page: $node + }); + if ($node.hasClass("current") || !targetPage) { + return targetPage = $node; + } + }); + if (targetPage != null) { + _this.goTo(targetPage, animation); + targetPage; + } else { + return false; + } + }; + })(this); + addPageToHistory = function(page, animation) { + var id; + id = page.attr('id'); + return customHistory.unshift({ + page: page, + animation: animation, + hash: "#" + id, + id: id + }); + }; + clickHandler = (function(_this) { + return function(e) { + var $el; + $el = $(e.target); + if (!$el.is(touchSelectors.join(", "))) { + $el = $el.closest(touchSelectors.join(", ")); + } + if ($el && $el.attr("href") && !isExternalLink($el)) { + console.warn("Need to prevent default click behavior."); + e.preventDefault(); + } else { + console.warn("No need to prevent default click behavior."); + } + if (!support.touch) { + console.warn("Converting click event to a tap event because touch handlers are not present or off."); + $(e.target).trigger("tap", e); + } + }; + })(this); + hashChangeHandler = (function(_this) { + return function(e) { + if (location.hash === customHistory[0].hash) { + console.log("We are on the right panel."); + return true; + } else if (location.hash === "") { + _this.goBack(); + return true; + } else if (customHistory[1] && location.hash === customHistory[1].hash) { + _this.goBack(); + return true; + } else { + console.warn("Could not find ID in history, just forwarding to DOM element."); + _this.goTo($(location.hash), _this.settings.defaultAnimation); + } + }; + })(this); + isExternalLink = function($el) { + 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\"]"); + }; + getAnimation = (function(_this) { + return function($el) { + var animation, resultAnimation, _i, _len; + for (_i = 0, _len = animations.length; _i < _len; _i++) { + animation = animations[_i]; + if ($el.is(animation.selector)) { + resultAnimation = animation; + break; + } + } + if (!resultAnimation) { + console.warn("Animation could not be found. Using " + _this.settings.defaultAnimation + "."); + resultAnimation = _this.settings.defaultAnimation; + } + return resultAnimation; + }; + })(this); + showPageByHref = (function(_this) { + return function(href, options) { + options = $.extend({}, { + data: null, + method: "GET", + animation: null, + $referrer: null + }, options); + if (href.charAt(0) !== '#') { + return $.ajax({ + url: href, + data: options.data, + type: options.method, + success: function(data) { + var firstPage; + firstPage = insertPages(data, options.animation); + if (firstPage) { + if (options.method === "GET" && _this.settings.cacheGetRequests === true && options.$referrer) { + return options.$referrer.attr("href", "#" + firstPage.attr("id")); + } + } + }, + error: function(data) { + if (options.$referrer) { + return options.$referrer.removeClass('active'); + } + } + }); + } else { + if (options.$referrer) { + return options.$referrer.removeClass('active'); + } + } + }; + })(this); + support = void 0; + start = (function(_this) { + return function() { + var $touchSelectors, anatomyLessons, extFn, startHash, _i, _len, _ref; + support = $.support || {}; + $.extend(support, { + animationEvents: typeof window.WebKitAnimationEvent !== "undefined", + touch: (typeof window.TouchEvent !== "undefined") && (window.navigator.userAgent.indexOf("Mobile") > -1) && _this.settings.useFastTouch, + transform3d: function() { + var body, div, head, result, style; + head = $head.get(0); + body = document.body; + style = document.createElement("style"); + style.textContent = "@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-webkit-transform-3d){#jqt-3dtest{height:3px}}"; + div = document.createElement("div"); + div.id = "jqt-3dtest"; + head.appendChild(style); + body.appendChild(div); + result = div.offsetHeight === 3; + style.parentNode.removeChild(style); + div.parentNode.removeChild(div); + console.warn("Support for 3d transforms: " + result + "."); + return result; + } + }); + if (!support.touch) { + console.warn("This device does not support touch interaction, or it has been deactivated by the developer. Some features might be unavailable."); + } + if (!support.transform3d) { + console.warn("This device does not support 3d animation. 2d animations will be used instead."); + } + _ref = _this.extensions; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + extFn = _ref[_i]; + if ($.isFunction(extFn)) { + $.extend(_this, extFn(_this)); + } + } + touchSelectors.push(_this.settings.touchSelector.concat(_this.settings.backSelector, _this.settings.submitSelector)); + $touchSelectors = $(touchSelectors.join(', ')).css('-webkit-touch-callout', 'none'); + $body = $("#jqt"); + anatomyLessons = []; + if (!$body.length) { + console.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."); + $body = $(document.body).attr("id", "jqt"); + } + if (support.transform3d) { + anatomyLessons.push("supports3d"); + } + anatomyLessons.push(_this.settings.useTouchScroll ? 'touchscroll' : 'autoscroll'); + if (_this.settings.fullScreenClass && window.navigator.standalone) { + anatomyLessons.push(_this.settings.fullScreenClass, _this.settings.statusBar); + } + $body.addClass(anatomyLessons.join(" ")).on("click", clickHandler).on("orientationchange", orientationChangeHandler).on("submit", submitHandler).on("tap", tapHandler).on((support.touch ? "touchstart" : "mousedown"), touchStartHandler).trigger("orientationchange"); + if (_this.settings.updateHash) { + $(window).on("hashchange", hashChangeHandler); + } + startHash = location.hash; + if (!$("#jqt > .current").length) { + $currentPage = $("#jqt > *:first-child").addClass("current"); + } else { + $currentPage = $("#jqt > .current"); + } + setHash($currentPage.attr("id")); + addPageToHistory($currentPage); + if (_this.settings.updateHash && $(startHash).length) { + return _this.goTo(startHash); + } + }; + })(this); + orientationChangeHandler = function() { + var orientation; + scrollTo(0, 0); + orientation = (Math.abs(window.orientation) === 90 ? "landscape" : "portrait"); + return $body.removeClass("portrait landscape").addClass(orientation).trigger("turn", { + orientation: orientation + }); + }; + reverseAnimation = function(animation) { + var opposites; + opposites = { + up: "down", + down: "up", + left: "right", + right: "left", + "in": "out", + out: "in" + }; + return opposites[animation] || animation; + }; + setHash = (function(_this) { + return function(hash) { + if (_this.settings.updateHash) { + return location.hash = "#" + hash.replace(/^#/, ""); + } + }; + })(this); + submitHandler = (function(_this) { + return function(e, callback) { + var $form; + $(":focus").trigger("blur"); + $form = (typeof e === "string" ? $(e).eq(0) : (e.target ? $(e.target) : $(e))); + if ($form.length && $form.is(_this.settings.formSelector) && $form.attr("action")) { + e.preventDefault(); + return showPageByHref($form.attr("action"), { + data: $form.serialize(), + method: $form.attr("method") || "POST", + animation: getAnimation($form), + callback: callback + }); + } + }; + })(this); + submitParentForm = function($el) { + var $form; + $form = $el.closest("form"); + if ($form.length) { + console.warn("About to submit parent form."); + $form.trigger("submit"); + return false; + } else { + console.warn("No parent form found."); + return true; + } + }; + tapHandler = (function(_this) { + return function(e) { + var $el, flag, handler, hash, href, params, selectors, target, _i, _len, _ref; + if (e.isDefaultPrevented()) { + return true; + } + $el = $(e.target); + selectors = touchSelectors.join(','); + if (!$el.is(selectors)) { + $el = $el.closest(selectors); + } + if (!$el.length || !$el.attr("href")) { + console.warn("Could not find a link related to tapped element."); + return true; + } + target = $el.attr("target"); + hash = $el.prop("hash"); + href = $el.attr("href"); + params = { + e: e, + $el: $el, + target: target, + hash: hash, + href: href + }; + _ref = _this.tapHandlers; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + handler = _ref[_i]; + if (handler.isSupported(e, params)) { + return flag = handler.fn(e, params); + } + } + }; + })(this); + touchStartHandler = function(e) { + var $el, selectors; + $el = $(e.target); + selectors = touchSelectors.join(", "); + if (!$el.is(selectors)) { + $el = $el.closest(selectors); + } + if ($el.length && $el.attr("href")) { + $el.addClass("active"); + } + $el.on((support.touch ? "touchmove" : "mousemove"), function() { + return $el.removeClass("active"); + }); + return $el.on("touchend", function() { + $el.off("touchend mouseup"); + return $el.off("touchmove mousemove"); + }); + }; + doNavigation = (function(_this) { + return function(fromPage, toPage, animation, goingBack) { + var finalAnimationName, is3d, navigationEndHandler; + if (goingBack == null) { + goingBack = false; + } + navigationEndHandler = function(event) { + if (support.animationEvents && animation && _this.settings.useAnimations) { + fromPage.off("webkitAnimationEnd", navigationEndHandler); + fromPage.removeClass(finalAnimationName + " out"); + if (finalAnimationName) { + toPage.removeClass(finalAnimationName); + } + $body.removeClass("animating animating3d"); + } else { + fromPage.removeClass(finalAnimationName + " out"); + if (finalAnimationName) { + toPage.removeClass(finalAnimationName); + } + } + setTimeout(function() { + toPage.removeClass('in'); + return window.scroll(0, 0); + }, tapBuffer); + fromPage.find('.active').removeClass('active'); + toPage.trigger("pageAnimationEnd", { + direction: "in", + animation: animation, + back: goingBack + }); + return fromPage.trigger("pageAnimationEnd", { + direction: "out", + animation: animation, + back: goingBack + }); + }; + if (!toPage.length) { + $('.active').removeClass('active'); + console.warn("Target element is missing."); + return false; + } + if (toPage.hasClass("current")) { + $('.active').removeClass('active'); + console.warn("You are already on the page you are trying to navigate to."); + return false; + } + $(":focus").trigger("blur"); + fromPage.trigger("pageAnimationStart", { + direction: "out", + back: goingBack + }); + toPage.trigger("pageAnimationStart", { + direction: "in", + back: goingBack + }); + if (support.animationEvents && animation && _this.settings.useAnimations) { + finalAnimationName = animation.name; + is3d = animation.is3d ? " animating3d" : ""; + if (!support.transform3d && animation.is3d) { + console.warn("Did not detect support for 3d animations, falling back to " + _this.settings.defaultAnimation + "."); + finalAnimationName = _this.settings.defaultAnimation; + is3d = ''; + } + if (goingBack) { + finalAnimationName = finalAnimationName.replace(/left|right|up|down|in|out/, reverseAnimation); + } + if (finalAnimationName == null) { + finalAnimationName = _this.settings.defaultAnimation; + } + console.warn("finalAnimationName:", finalAnimationName); + fromPage.on("webkitAnimationEnd", navigationEndHandler); + $body.addClass("animating" + is3d); + toPage.addClass(finalAnimationName + " in current"); + fromPage.removeClass("current").addClass(finalAnimationName + " out"); + } else { + toPage.addClass("current in"); + fromPage.removeClass("current"); + navigationEndHandler(); + } + $currentPage = toPage; + if (goingBack) { + customHistory.shift(); + } else { + addPageToHistory($currentPage, animation); + } + setHash($currentPage.attr("id")); + return true; + }; + })(this); + this.settings = $.extend({}, this.defaults, options); + initHairExtensions(); + this.settings.starter(start); + } - return publicObj; - }; + return jQT; - $.jQTouch.prototype.extensions = []; - $.jQTouch.prototype.tapHandlers = []; + })(); - // Extensions directly manipulate the jQTouch object, - // before it's initialized - $.jQTouch.addExtension = function(extension) { - $.jQTouch.prototype.extensions.push(extension); - }; + $.jQTouch = $.jQT; - // Experimental tap handlers that can bypass - // default jQTouch tap handling - $.jQTouch.addTapHandler = function(extension) { - $.jQTouch.prototype.tapHandlers.push(extension); - }; - -})(); // Double closure, ALL THE WAY ACROSS THE SKY +}).call(this); diff --git a/client/grunt-tasks/install-libs.js b/client/grunt-tasks/install-libs.js index 20f2123a40c..3a3c63c5412 100644 --- a/client/grunt-tasks/install-libs.js +++ b/client/grunt-tasks/install-libs.js @@ -11,7 +11,6 @@ module.exports = function( grunt ){ // where to move fetched bower components into the build structure (libName: [ bower-location, libs-location ]) libraryLocations = { 'farbtastic': [ 'src/farbtastic.js', 'farbtastic.js' ], - 'jQTouch': [ 'src/reference/jqtouch.js', 'jquery/jqtouch.js' ], 'bootstrap-tour': [ 'build/js/bootstrap-tour.js', 'bootstrap-tour.js' ], 'jquery.complexify': [ 'jquery.complexify.js', 'jquery.complexify.js' ], diff --git a/client/gulpfile.js b/client/gulpfile.js index 63048c6adcf..09107191c82 100644 --- a/client/gulpfile.js +++ b/client/gulpfile.js @@ -25,6 +25,7 @@ var paths = { 'bib2json': [ 'Parser.js', 'bibtex.js' ], 'jquery': ['dist/jquery.js', 'jquery/jquery.js'], 'jquery-migrate': [ 'dist/jquery-migrate.js', 'jquery/jquery.migrate.js' ], + 'jqt': [ 'dist/src/jqt.js', 'jquery/jqtouch.js' ], 'raven-js': ['dist/raven.js', 'raven.js'], 'requirejs': [ 'require.js', 'require.js' ], 'underscore': [ 'underscore.js', 'underscore.js' ], diff --git a/client/package.json b/client/package.json index cf4881a1e29..fd5e51ad806 100644 --- a/client/package.json +++ b/client/package.json @@ -36,6 +36,7 @@ "gulp-sourcemaps": "^2.5.1", "gulp-uglify": "^3.0.0", "gulp-watch": "^4.3.11", + "jqt": "^1.0.1", "jquery": "1.12", "jquery-migrate": "~1.4", "jshint": "^2.9.4", diff --git a/client/yarn.lock b/client/yarn.lock index 203e39f61c9..3cccfdd7379 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -2648,6 +2648,10 @@ jpeg-js@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.1.2.tgz#135b992c0575c985cfa0f494a3227ed238583ece" +jqt@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/jqt/-/jqt-1.0.1.tgz#483dcb7a41ffae4e7625cdc2ee4e8442d6908ed3" + jquery-migrate@~1.4: version "1.4.1" resolved "https://registry.yarnpkg.com/jquery-migrate/-/jquery-migrate-1.4.1.tgz#85152f3ec99a95625f4f7d0bcf62e9b8638f5a76" diff --git a/static/scripts/libs/jquery/jqtouch.js b/static/scripts/libs/jquery/jqtouch.js index 4581bb97c36..e246a724d7a 100644 --- a/static/scripts/libs/jquery/jqtouch.js +++ b/static/scripts/libs/jquery/jqtouch.js @@ -1 +1 @@ -$.jQTouch=function(t){function e(t){void 0!==window.console&&!0===x.debug&&console.warn(t)}function n(t){"string"==typeof t.selector&&"string"==typeof t.name&&B.push(t)}function a(t){"string"==typeof t.name&&"function"==typeof t.isSupported&&"function"==typeof t.fn&&P.push(t)}function o(t,e){j.unshift({page:t,animation:e,hash:"#"+t.attr("id"),id:t.attr("id")})}function r(t){var n=$(t.target);n.is(Q.join(", "))||(n=$(t.target).closest(Q.join(", "))),n&&n.attr("href")&&!n.isExternalLink()?(e("Need to prevent default click behavior."),t.preventDefault()):e("No need to prevent default click behavior."),$.support.touch?e("Not converting click to a tap event because touch handler is on the job."):(e("Converting click event to a tap event because touch handlers are not present or off."),$(t.target).trigger("tap",t))}function i(t,n,a,r){function i(e){var o=H;$.support.animationEvents&&a&&x.useAnimations?(t.unbind("webkitAnimationEnd",i),t.removeClass(l+" out inmotion"),l&&n.removeClass(l),y.removeClass("animating animating3d"),!0===x.trackScrollPositions&&(n.css("top",-n.data("lastScroll")),setTimeout(function(){n.css("top",0),window.scroll(0,n.data("lastScroll")),$(".scroll",n).each(function(){this.scrollTop=-$(this).data("lastScroll")})},0))):(t.removeClass(l+" out inmotion"),l&&n.removeClass(l),o+=260),setTimeout(function(){n.removeClass("in"),window.scroll(0,0)},o),t.unselect(),n.trigger("pageAnimationEnd",{direction:"in",animation:a,back:r}),t.trigger("pageAnimationEnd",{direction:"out",animation:a,back:r})}if(r=r||!1,void 0===n||0===n.length)return $.fn.unselect(),e("Target element is missing."),!1;if(n.hasClass("current"))return $.fn.unselect(),e("You are already on the page you are trying to navigate to."),!1;if($(":focus").trigger("blur"),t.trigger("pageAnimationStart",{direction:"out",back:r}),n.trigger("pageAnimationStart",{direction:"in",back:r}),$.support.animationEvents&&a&&x.useAnimations){!$.support.transform3d&&a.is3d&&(e("Did not detect support for 3d animations, falling back to "+x.defaultAnimation+"."),a.name=x.defaultAnimation);var l=a.name,c=a.is3d?"animating3d":"";r&&(l=l.replace(/left|right|up|down|in|out/,s)),e("finalAnimationName is "+l+"."),t.bind("webkitAnimationEnd",i),y.addClass("animating "+c);var u=window.pageYOffset;!0===x.trackScrollPositions&&n.css("top",window.pageYOffset-(n.data("lastScroll")||0)),n.addClass(l+" in current"),t.removeClass("current").addClass(l+" out inmotion"),!0===x.trackScrollPositions&&(t.data("lastScroll",u),$(".scroll",t).each(function(){$(this).data("lastScroll",this.scrollTop)}))}else n.addClass("current in"),t.removeClass("current"),i();return E=n,r?j.shift():o(E,a),h(E.attr("id")),!0}function s(t){return{up:"down",down:"up",left:"right",right:"left",in:"out",out:"in"}[t]||t}function l(){j.length<1&&e("History is empty."),1===j.length&&(e("You are on the first panel."),window.history.go(-1));var t=j[0],n=j[1];return i(t.page,n.page,t.animation,!0)?I:(e("Could not go back."),!1)}function c(t,n){var a=j[0].page;if("string"==typeof n)for(var o=0,r=B.length;o=5),t}function S(t){var e=$(t.target),n=Q.join(", ");e.is(n)||(e=e.closest(n)),e.length&&e.attr("href")&&e.addClass("active"),e.on($.support.touch?"touchmove":"mousemove",function(){e.removeClass("active")}),e.on("touchend",function(){e.unbind("touchmove mousemove")})}function k(t){if(t.isDefaultPrevented())return!0;var n=$(t.target);if(n.is(Q.join(", "))||(n=n.closest(Q.join(", "))),!n.length||!n.attr("href"))return e("Could not find a link related to tapped element."),!0;for(var a={e:t,$el:n,target:n.attr("target"),hash:n.prop("hash"),href:n.attr("href"),jQTSettings:x},o=0,r=P.length;o * > ul li a"}]};return x=$.extend({},G,t),function(t){if(x.preloadImages)for(var e=x.preloadImages.length-1;e>=0;e--)(new Image).src=x.preloadImages[e];var n=x.addGlossToIcon?"":"-precomposed";x.icon&&(D+=''),x.icon4&&(D+=''),x.startupScreen&&(D+=''),x.fixedViewport&&(D+=''),x.fullScreen&&(D+='',x.statusBar&&(D+='')),D&&T.prepend(D)}(),$.fn.isExternalLink=function(){var t=$(this);return"_blank"===t.attr("target")||"external"===t.attr("rel")||t.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"]')},$.fn.makeActive=function(){return $(this).addClass("active")},$.fn.unselect=function(t){t?t.removeClass("active"):$(".active").removeClass("active")},I={addAnimation:n,animations:B,getOrientation:function(){return q},goBack:l,insertPages:p,goTo:c,history:j,settings:x,submitForm:g},x.starter(function(){$.support||($.support={}),$.support.animationEvents=void 0!==window.WebKitAnimationEvent,$.support.touch=void 0!==window.TouchEvent&&window.navigator.userAgent.indexOf("Mobile")>-1&&x.useFastTouch,$.support.transform3d=b(),$.support.ios5=w(),$.support.touch||e("This device does not support touch interaction, or it has been deactivated by the developer. Some features might be unavailable."),$.support.transform3d||e("This device does not support 3d animation. 2d animations will be used instead.");for(var t=0,i=N.length;t .current").length?$("#jqt > *:first-child").addClass("current"):$("#jqt > .current")).attr("id")),o(E),1===$(j).length&&c(j)}),I},$.jQTouch.prototype.extensions=[],$.jQTouch.prototype.tapHandlers=[],$.jQTouch.addExtension=function(t){$.jQTouch.prototype.extensions.push(t)},$.jQTouch.addTapHandler=function(t){$.jQTouch.prototype.tapHandlers.push(t)}; \ No newline at end of file +(function(){$.jQT=function(){function t(t){var u,c,d,f,h,p,m,g,v,w,b,C,y,k,S,j,T,A;this.tapHandlers=this.tapHandlers.concat([{name:"external-link",isSupported:function(t,e){return g(e.$el)},fn:function(t,e){return e.$el.removeClass("active"),!0}},{name:"back-selector",isSupported:function(t){return function(e,n){return n.$el.is(t.settings.backSelector)}}(this),fn:function(t){return function(e,n){return t.goBack(n.hash),!1}}(this)},{name:"submit-selector",isSupported:function(t){return function(e,n){return n.$el.is(t.settings.submitSelector)}}(this),fn:function(t,e){S(e.$el)}},{name:"webapp",isSupported:function(t,e){return"_webapp"===e.target},fn:function(t,e){return window.location=e.href,!1}},{name:"no-op",isSupported:function(t,e){return"#"===e.href},fn:function(t,e){return e.$el.removeClass("active"),!0}},{name:"standard",isSupported:function(t,e){return e.hash&&"#"!==e.hash},fn:function(t){return function(e,n){var r;return r=f(n.$el),n.$el.addClass("active"),t.goTo($(n.hash).data("referrer",n.$el),r,n.$el.hasClass("reverse")),!1}}(this)},{name:"external",isSupported:function(t,e){return!0},fn:function(t,e){var n;return n=f(e.$el),e.$el.addClass("loading active"),C(e.$el.attr("href"),{animation:n,callback:function(){return e.$el.removeClass("loading"),setTimeout(function(){return e.$el.removeClass("active")},250)},$referrer:e.$el}),!1}}]),this.goTo=function(t,e){var n,r,a,s,l;if(r=i[0].page,"string"==typeof e)for(s=0,l=o.length;s0?i.splice(1,t):t<0&&i.splice(1,i.length+t-1);else if(/^#.+/.test(t)){for(e=0,r=a=0,s=i.length;a'),t.settings.icon4&&n.push(''),t.settings.startupScreen&&n.push(''),a=[],t.settings.fixedViewport&&a.push("initial-scale=1.0","maximum-scale=1.0","user-scalable=0"),t.settings.minimalUIViewport&&a.push("minimal-ui"),a&&n.push(''),t.settings.fullScreen&&(n.push(''),t.settings.statusBar&&n.push('')),n.length)return r.prepend(n.join(""))}}(this),m=function(t){return function(n,r){var o;if(o=null,$(n).each(function(t,n){var r;if((r=$(this)).attr("id")||r.attr("id","page-"+ ++a),$("#"+r.attr("id")).remove(),e.append(r),e.trigger("pageInserted",{page:r}),r.hasClass("current")||!o)return o=r}),null==o)return!1;t.goTo(o,r)}}(this),u=function(t,e){var n;return n=t.attr("id"),i.unshift({page:t,animation:e,hash:"#"+n,id:n})},c=function(t){var e;(e=$(t.target)).is(l.join(", "))||(e=e.closest(l.join(", "))),e&&e.attr("href")&&!g(e)?(console.warn("Need to prevent default click behavior."),t.preventDefault()):console.warn("No need to prevent default click behavior."),j.touch||(console.warn("Converting click event to a tap event because touch handlers are not present or off."),$(t.target).trigger("tap",t))},h=function(t){return function(e){return location.hash===i[0].hash?(console.log("We are on the right panel."),!0):""===location.hash?(t.goBack(),!0):i[1]&&location.hash===i[1].hash?(t.goBack(),!0):(console.warn("Could not find ID in history, just forwarding to DOM element."),void t.goTo($(location.hash),t.settings.defaultAnimation))}}(this),g=function(t){return"_blank"===t.attr("target")||"external"===t.attr("rel")||t.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"]')},f=function(t){return function(e){var n,r,i,a;for(i=0,a=o.length;i-1&&t.settings.useFastTouch,transform3d:function(){var t,e,n,o,i;return n=r.get(0),t=document.body,i=document.createElement("style"),i.textContent="@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-webkit-transform-3d){#jqt-3dtest{height:3px}}",e=document.createElement("div"),e.id="jqt-3dtest",n.appendChild(i),t.appendChild(e),o=3===e.offsetHeight,i.parentNode.removeChild(i),e.parentNode.removeChild(e),console.warn("Support for 3d transforms: "+o+"."),o}}),j.touch||console.warn("This device does not support touch interaction, or it has been deactivated by the developer. Some features might be unavailable."),j.transform3d||console.warn("This device does not support 3d animation. 2d animations will be used instead."),s=0,d=(f=t.extensions).length;s .current").length?$("#jqt > .current"):$("#jqt > *:first-child").addClass("current"),b(n.attr("id")),u(n),t.settings.updateHash&&$(a).length)return t.goTo(a)}}(this),v=function(){var t;return scrollTo(0,0),t=90===Math.abs(window.orientation)?"landscape":"portrait",e.removeClass("portrait landscape").addClass(t).trigger("turn",{orientation:t})},w=function(t){return{up:"down",down:"up",left:"right",right:"left",in:"out",out:"in"}[t]||t},b=function(t){return function(e){if(t.settings.updateHash)return location.hash="#"+e.replace(/^#/,"")}}(this),k=function(t){return function(e,n){var r;if($(":focus").trigger("blur"),(r="string"==typeof e?$(e).eq(0):e.target?$(e.target):$(e)).length&&r.is(t.settings.formSelector)&&r.attr("action"))return e.preventDefault(),C(r.attr("action"),{data:r.serialize(),method:r.attr("method")||"POST",animation:f(r),callback:n})}}(this),S=function(t){var e;return(e=t.closest("form")).length?(console.warn("About to submit parent form."),e.trigger("submit"),!1):(console.warn("No parent form found."),!0)},T=function(t){return function(e){var n,r,o,i,a,s,u;if(e.isDefaultPrevented())return!0;if(n=$(e.target),i=l.join(","),n.is(i)||(n=n.closest(i)),!n.length||!n.attr("href"))return console.warn("Could not find a link related to tapped element."),!0;for(o={e:e,$el:n,target:n.attr("target"),hash:n.prop("hash"),href:n.attr("href")},a=0,s=(u=t.tapHandlers).length;a * > ul li a"}],t.prototype.orientation="portrait",t.prototype.tapHandlers=[],t.prototype.defaults={addGlossToIcon:!0,backSelector:".back, .cancel, .goback",cacheGetRequests:!0,defaultAnimation:"slideleft",fixedViewport:!0,formSelector:"form",fullScreen:!0,fullScreenClass:"fullscreen",icon:null,icon4:null,minimalUIViewport:!0,preloadImages:!1,starter:$(document).ready,startupScreen:null,statusBar:"default",submitSelector:".submit",touchSelector:"a, .touch",updateHash:!0,useAnimations:!0,useFastTouch:!0,useTouchScroll:!0},t.addExtension=function(t){return this.prototype.extensions.push(t)},t.addTapHandler=function(t){if("string"==typeof t.name&&"function"==typeof t.isSupported&&"function"==typeof t.fn)return this.prototype.tapHandlers.push(t)},t.addAnimation=function(t){if("string"==typeof t.selector&&"string"==typeof t.name)return this.animations.push(t)},e=void 0,r=$("head"),o=t.prototype.animations,i=[],a=0,n="",l=[],s=100,t}(),$.jQTouch=$.jQT}).call(this); \ No newline at end of file