diff --git a/components/ionActionSheet/ionActionSheet.js b/components/ionActionSheet/ionActionSheet.js index e38ee5b..e66f6c8 100644 --- a/components/ionActionSheet/ionActionSheet.js +++ b/components/ionActionSheet/ionActionSheet.js @@ -76,17 +76,17 @@ IonActionSheet = { } }; -Template.ionActionSheet.rendered = function () { +Template.ionActionSheet.onRendered(function () { $(window).on('keyup.ionActionSheet', function(event) { if (event.which == 27) { IonActionSheet.cancel(); } }); -}; +}); -Template.ionActionSheet.destroyed = function () { +Template.ionActionSheet.onDestroyed(function () { $(window).off('keyup.ionActionSheet'); -}; +}); Template.ionActionSheet.events({ // Handle clicking the backdrop diff --git a/components/ionBody/ionBody.js b/components/ionBody/ionBody.js index 726f802..c82b255 100644 --- a/components/ionBody/ionBody.js +++ b/components/ionBody/ionBody.js @@ -3,10 +3,32 @@ Platform = { return (!!navigator.userAgent.match(/iPad/i) || !!navigator.userAgent.match(/iPhone/i) || !!navigator.userAgent.match(/iPod/i)) || Session.get('platformOverride') === 'iOS'; }, - isAndroid: function () { return navigator.userAgent.indexOf('Android') > 0 || Session.get('platformOverride') === 'Android'; + }, + isWeb: function () { + return !Platform.isIOS() && !Platform.isAndroid(); + }, + set: function(platform) { + if (!_.contains(['android', 'ios', 'web'], platform)) return; + var $ionicBody = $('.ionic-body'); + $ionicBody.removeClass('platform-web platform-cordova platform-ios platform-android'); + if (platform === 'android') { + $ionicBody.addClass('platform-cordova platform-android'); + } + if (platform === 'ios') { + $ionicBody.addClass('platform-cordova platform-ios'); + } + if (platform === 'web') { + $ionicBody.addClass('platform-web'); + } + }, + get: function() { + var $ionicBody = $('.ionic-body'); + if ($ionicBody.hasClass('platform-ios')) return 'ios'; + if ($ionicBody.hasClass('platform-android')) return 'android'; + return 'web'; } }; @@ -18,6 +40,10 @@ Template.registerHelper('isAndroid', function () { return Platform.isAndroid(); }); +Template.registerHelper('isWeb', function () { + return Platform.isWeb(); +}); + Template.ionBody.helpers({ platformClasses: function () { var classes = ['grade-a']; @@ -39,13 +65,13 @@ Template.ionBody.helpers({ } }); -Template.ionBody.rendered = function () { +Template.ionBody.onRendered(function () { window.addEventListener('statusTap', function() { $('.content.overflow-scroll').animate({ scrollTop: 0 }, 500); }); -}; +}); Template.ionBody.events({ 'click [data-ion-modal]': function (event, template) { @@ -59,8 +85,15 @@ Template.ionBody.events({ }, 'click [data-nav-direction]': function (event, template) { - $('[data-nav-container]').addClass('nav-view-direction-' + $(event.target).data('nav-direction')); - $('[data-navbar-container]').addClass('nav-bar-direction-' + $(event.target).data('nav-direction')); + var direction = $(event.currentTarget).data('nav-direction'); + $('[data-nav-container]').addClass('nav-view-direction-' + direction); + $('[data-navbar-container]').addClass('nav-bar-direction-' + direction); + if (!_.contains(['back', 'forward'], direction)) { + setTimeout(function() { + $('[data-nav-container]').removeClass('nav-view-direction-' + direction); + $('[data-navbar-container]').removeClass('nav-bar-direction-' + direction); + }, 500); + } }, 'click [data-ion-menu-toggle]': function (event, template) { diff --git a/components/ionFooterBar/ionFooterBar.js b/components/ionFooterBar/ionFooterBar.js index 0a1c3b8..1a9b8e7 100644 --- a/components/ionFooterBar/ionFooterBar.js +++ b/components/ionFooterBar/ionFooterBar.js @@ -1,10 +1,10 @@ -Template.ionFooterBar.rendered = function () { +Template.ionFooterBar.onRendered(function () { Session.set('hasFooter', true); -}; +}); -Template.ionFooterBar.destroyed = function () { +Template.ionFooterBar.onDestroyed(function () { Session.set('hasFooter', false); -}; +}); Template.ionFooterBar.helpers({ classes: function () { diff --git a/components/ionHeaderBar/ionHeaderBar.js b/components/ionHeaderBar/ionHeaderBar.js index ddd7263..cceb104 100644 --- a/components/ionHeaderBar/ionHeaderBar.js +++ b/components/ionHeaderBar/ionHeaderBar.js @@ -1,26 +1,23 @@ IonHeaderBar = { alignTitle: function () { - var align = this.alignTitle || 'center'; - var $title = this.$('.title'); - if (Platform.isAndroid() && !this.alignTitle) { - $title.addClass('title-left'); - return; - } + var platform = Platform.get(); + var platformAligns = { + android: 'left', + ios: 'center' + }; + var align = this.data.alignTitle || platformAligns[platform] || 'center'; + var titleClass = 'title-' + align; + + var $title = this.$('.title'); + $title.removeClass('title-left title-center title-right').addClass(titleClass); - if (align === 'center') { - $title.addClass('title-center'); - } else if (align === 'left') { - $title.addClass('title-left'); - } else if (align === 'right') { - $title.addClass('title-right'); - } }, positionTitle: function () { var $title = this.$('.title'); - var $leftButton = $('.button.pull-left'); - var $rightButton = $('.button.pull-right'); + var $leftButton = this.$('.button.pull-left'); + var $rightButton = this.$('.button.pull-right'); // Find out which button is wider, // use that to offset the title on both sides @@ -45,30 +42,28 @@ IonHeaderBar = { } }; -Template.ionHeaderBar.created = function () { +Template.ionHeaderBar.onCreated(function () { this.data = this.data || {}; -}; +}); -Template.ionHeaderBar.rendered = function () { +Template.ionHeaderBar.onRendered(function () { Session.set('hasHeader', true); IonHeaderBar.alignTitle.call(this); IonHeaderBar.positionTitle.call(this); -}; +}); -Template.ionHeaderBar.destroyed = function () { +Template.ionHeaderBar.onDestroyed(function () { Session.set('hasHeader', false); -}; +}); Template.ionHeaderBar.helpers({ classes: function () { var classes = ['bar', 'bar-header']; - if (this.class) { classes.push(this.class); } else { classes.push('bar-stable'); } - return classes.join(' '); } }); diff --git a/components/ionModal/ionModal.js b/components/ionModal/ionModal.js index 083bb4d..e793513 100644 --- a/components/ionModal/ionModal.js +++ b/components/ionModal/ionModal.js @@ -42,54 +42,79 @@ IonModal = { delete this.templateClosed; var view = (this.view[templateName] || []).slice(-1)[0]; - if (!view) return; - var $modalBackdrop = $(view.firstNode()); - var $modal = $('.modal', $modalBackdrop); + if (view) { + var $modalBackdrop = $(view.firstNode()); + var $modal = $('.modal', $modalBackdrop); + } else { + var $modal = $('.modal'); + var $modalBackdrop = $modal.parents('.modal-backdrop').get(0); + } - $modal.addClass(this.leaveClasses.join(' ')); - Meteor.setTimeout(function () { - $modal.addClass(this.leaveActiveClass); - }.bind(this), 50); + if ($modal) { + $modal.addClass(this.leaveClasses.join(' ')); + Meteor.setTimeout(function () { + $modal.addClass(this.leaveActiveClass); + }.bind(this), 50); + } - $modalBackdrop.fadeOut(500, function() { - $('body').removeClass('modal-open'); - }); + if ($modalBackdrop) { + $modalBackdrop.fadeOut(500, function() { + if ($('.modal-backdrop').length) return; + $('body').removeClass('modal-open'); + }); + } }.bind(this), 0); } }; +var isOpening = function($modal) { + return $modal.hasClass(IonModal.enterClasses.join(' ')) || $modal.hasClass(IonModal.enterActiveClasse); +}; + +var afterOpen = function($modal) { + $modal.removeClass(IonModal.enterClasses.join(' ')).removeClass(IonModal.enterActiveClass); + $('body').addClass('modal-open'); +}; + +var isClosing = function($modal) { + return $modal.hasClass(IonModal.leaveClasses.join(' ')) || $modal.hasClass(IonModal.leaveActiveClasse); +}; + +var afterClose = function($modal, e) { + var firstChild = $modal.children().first(); + var templateName = getElementModalTemplateName(firstChild); + IonModal.views = _.without(IonModal.views, templateName); + var view = IonModal.view[templateName].pop(); + var $modalBackdrop = $(view.firstNode()); + $modalBackdrop.removeClass('active'); + $modal.removeClass(IonModal.leaveClasses.join(' ')).removeClass(IonModal.leaveActiveClass).off(IonModal.transitionEndEvent); + $('body').removeClass('modal-open'); + $(e.target).parents('.modal-backdrop').remove(); + Blaze.remove(view); +}; + $(document).delegate('.modal', IonModal.transitionEndEvent, function(e) { var $modal = $(e.currentTarget); - if ($modal.hasClass(IonModal.enterClasses.join(' ')) || $modal.hasClass(IonModal.enterActiveClasse)) { - $modal.removeClass(IonModal.enterClasses.join(' ')).removeClass(IonModal.enterActiveClass); - $('body').addClass('modal-open'); - } else if ($modal.hasClass(IonModal.leaveClasses.join(' ')) || $modal.hasClass(IonModal.leaveActiveClasse)) { - var firstChild = $modal.children().first(); - var templateName = getElementModalTemplateName(firstChild); - IonModal.views = _.without(IonModal.views, templateName); - var view = IonModal.view[templateName].pop(); - var $modalBackdrop = $(view.firstNode()); - $modalBackdrop.removeClass('active'); - $modal.removeClass(IonModal.leaveClasses.join(' ')).removeClass(IonModal.leaveActiveClass).off(IonModal.transitionEndEvent); - $('body').removeClass('modal-open'); - $(e.target).parents('.modal-backdrop').remove(); - Blaze.remove(view); + if (isOpening($modal)) { + afterOpen($modal); + } else if (isClosing($modal)) { + afterClose($modal, e); } }); -Template.ionModal.created = function () { +Template.ionModal.onCreated(function () { this.data = this.data || {}; this.customTemplate = this.data.customTemplate || false; this.title = this.data.title; this.title = this.data.closeText; this.focusFirstInput = _.isUndefined(this.data.focusFirstInput) ? true : this.data.focusFirstInput; this.animation = this.data.animation || 'slide-in-up'; -}; +}); -Template.ionModal.rendered = function () { +Template.ionModal.onRendered(function () { if (this.focusFirstInput) { Meteor.setTimeout(function () { if (!this._domrange) return; @@ -102,13 +127,13 @@ Template.ionModal.rendered = function () { IonModal.close(); } }); -}; +}); -Template.ionModal.destroyed = function () { +Template.ionModal.onDestroyed(function () { if (!IonModal.views.length) { $(window).off('keyup.ionModal'); } -}; +}); Template.ionModal.helpers({ barClass: function () { diff --git a/components/ionNavBackButton/ionNavBackButton.js b/components/ionNavBackButton/ionNavBackButton.js index 991eb7a..c43a95e 100644 --- a/components/ionNavBackButton/ionNavBackButton.js +++ b/components/ionNavBackButton/ionNavBackButton.js @@ -17,11 +17,11 @@ Template.ionNavBackButton.events({ } }); -Template.ionNavBackButton.created = function () { +Template.ionNavBackButton.onCreated(function () { this.data = this.data || {}; -}; +}); -Template.ionNavBackButton.rendered = function () { +Template.ionNavBackButton.onRendered(function () { this.backUrl = null; this.data = this.data || {}; @@ -39,7 +39,7 @@ Template.ionNavBackButton.rendered = function () { this.backUrl = backRoute.path(Template.parentData(1)); } -}; +}); Template.ionNavBackButton.helpers({ classes: function () { diff --git a/components/ionNavBar/ionNavBar.js b/components/ionNavBar/ionNavBar.js index ae2de3b..c4edcf0 100644 --- a/components/ionNavBar/ionNavBar.js +++ b/components/ionNavBar/ionNavBar.js @@ -1,4 +1,4 @@ -Template.ionNavBar.created = function () { +Template.ionNavBar.onCreated(function () { this.data = this.data || {}; if (Platform.isAndroid()) { @@ -17,9 +17,9 @@ Template.ionNavBar.created = function () { } else { this.transitionDuration = 200; } -}; +}); -Template.ionNavBar.rendered = function () { +Template.ionNavBar.onRendered(function () { Session.set('hasHeader', true); IonHeaderBar.alignTitle.call(this); @@ -89,11 +89,11 @@ Template.ionNavBar.rendered = function () { } } }; -}; +}); -Template.ionNavBar.destroyed = function () { +Template.ionNavBar.onDestroyed(function () { Session.set('hasHeader', false); -}; +}); Template.ionNavBar.helpers({ classes: function () { diff --git a/components/ionNavView/ionNavView.js b/components/ionNavView/ionNavView.js index c54de3c..6f6cd6c 100644 --- a/components/ionNavView/ionNavView.js +++ b/components/ionNavView/ionNavView.js @@ -2,7 +2,7 @@ IonNavigation = { skipTransitions: false }; -Template.ionNavView.created = function () { +Template.ionNavView.onCreated(function () { this.data = this.data || {}; Session.setDefault('ionNavDirection', 'forward'); @@ -22,9 +22,9 @@ Template.ionNavView.created = function () { } else { this.transitionDuration = 320; } -}; +}); -Template.ionNavView.rendered = function () { +Template.ionNavView.onRendered(function () { var template = this; this.find('[data-nav-container]')._uihooks = { @@ -64,7 +64,7 @@ Template.ionNavView.rendered = function () { }, template.transitionDuration); } }; -}; +}); Template.ionNavView.helpers({ transition: function () { diff --git a/components/ionPopover/ionPopover.js b/components/ionPopover/ionPopover.js index b8141ea..bb348fa 100644 --- a/components/ionPopover/ionPopover.js +++ b/components/ionPopover/ionPopover.js @@ -7,42 +7,55 @@ IonPopover = { var $backdrop = $(this.view.firstNode()); var $popover = $backdrop.find('.popover'); - var $button = $(button); var $arrow = $backdrop.find('.popover-arrow'); + var $body = $('.ionic-body').length ? $('.ionic-body') : $('body'); + var $button = $(button); - var bodyWidth = $('body').width(); - var bodyHeight = $(window).innerHeight; + var windowHeight = window.innerHeight; + var bodyWidth = $body.outerWidth(); + var bodyPosition = $body.offset(); var buttonPosition = $button.offset(); var buttonWidth = $button.outerWidth(); var buttonHeight = $button.outerHeight(); var popoverWidth = $popover.outerWidth(); var popoverHeight = $popover.outerHeight(); + var arrowWidth = $arrow.outerWidth(); var popoverCSS = { marginLeft: '0', opacity: 1, - left: buttonPosition.left + buttonWidth / 2 - popoverWidth / 2 + left: buttonPosition.left + buttonWidth / 2 - popoverWidth / 2, + maxWidth: bodyWidth - POPOVER_BODY_PADDING * 2 }; - if (popoverCSS.left < POPOVER_BODY_PADDING) { + var overflowsOnLeft = popoverCSS.left < POPOVER_BODY_PADDING; + if (overflowsOnLeft) { popoverCSS.left = POPOVER_BODY_PADDING; - } else if(popoverCSS.left + popoverWidth + POPOVER_BODY_PADDING > bodyWidth) { + } + + var overflowsOnRight = popoverCSS.left + popoverWidth + POPOVER_BODY_PADDING * 2 > bodyWidth; + if (overflowsOnRight) { popoverCSS.left = bodyWidth - popoverWidth - POPOVER_BODY_PADDING; } - if (buttonPosition.top + buttonHeight + popoverHeight > bodyHeight) { - popoverCSS.top = buttonPosition.top - popoverHeight; + var shouldBeBelowButton = buttonPosition.top + buttonHeight + popoverHeight > windowHeight; + if (shouldBeBelowButton) { + popoverCSS.top = buttonPosition.top - bodyPosition.top - popoverHeight; $popover.addClass('popover-bottom'); } else { - popoverCSS.top = buttonPosition.top + buttonHeight; + popoverCSS.top = buttonPosition.top - bodyPosition.top + buttonHeight; $popover.removeClass('popover-bottom'); } + var buttonRelativeCenter = buttonPosition.left - bodyPosition.left + buttonWidth / 2; + var arrowCSS = { + left: buttonRelativeCenter - arrowWidth / 2 - popoverCSS.left + 'px' + }; + $backdrop.addClass('active'); - $arrow.css({ - left: buttonPosition.left + buttonWidth / 2 - $arrow.outerWidth() / 2 - popoverCSS.left + 'px' - }); $popover.css(popoverCSS); + $arrow.css(arrowCSS); + }, hide: function () { @@ -56,17 +69,17 @@ IonPopover = { } }; -Template.ionPopover.rendered = function () { +Template.ionPopover.onRendered(function () { $(window).on('keyup.ionPopover', function(event) { if (event.which == 27) { IonPopover.hide(); } }); -}; +}); -Template.ionPopover.destroyed = function () { +Template.ionPopover.onDestroyed(function () { $(window).off('keyup.ionPopover'); -}; +}); Template.ionPopover.events({ // Handle clicking the backdrop diff --git a/components/ionPopup/ionPopup.html b/components/ionPopup/ionPopup.html index f6aeadf..15e2563 100644 --- a/components/ionPopup/ionPopup.html +++ b/components/ionPopup/ionPopup.html @@ -1,7 +1,7 @@