diff --git a/js/ext/angular/src/directive/ionicBar.js b/js/ext/angular/src/directive/ionicBar.js index f9c2d7080e..7c327568d9 100644 --- a/js/ext/angular/src/directive/ionicBar.js +++ b/js/ext/angular/src/directive/ionicBar.js @@ -3,39 +3,8 @@ angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize']) -.directive('ionHeaderBar', ['$document', function($document) { - return { - restrict: 'E', - link: function($scope, $element, $attr, scrollCtrl) { - ionic.requestAnimationFrame(function() { - var scrollCtrl = $element.controller('$ionicScroll'); - if (!scrollCtrl) { - return; - } - - ionic.on('tap', onTap, $element[0]); - $scope.$on('$destroy', function() { - ionic.off('tap', onTap, $element[0]); - }); - - function onTap(e) { - if (ionic.DomUtil.getParentOrSelfWithClass(e.target, 'button', 4)) { - return; - } - var touch = e.gesture && e.gesture.touches[0] || e.detail.touches[0]; - var bounds = $element[0].getBoundingClientRect(); - if(ionic.DomUtil.rectContains( - touch.pageX, touch.pageY, - bounds.left, bounds.top - 20, - bounds.left + bounds.width, bounds.top + bounds.height) - ) { - scrollCtrl.scrollTop(true); - } - } - }); - } - }; -}]) +.directive('ionNavBar', TapScrollToTopDirective()) +.directive('ionHeaderBar', TapScrollToTopDirective()) /** * @ngdoc directive @@ -111,6 +80,43 @@ angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize']) */ .directive('ionFooterBar', barDirective(false)); +function TapScrollToTopDirective() { + return ['$document', function($document) { + return { + restrict: 'E', + link: function($scope, $element, $attr, scrollCtrl) { + ionic.requestAnimationFrame(function() { + var scrollCtrl = $element.controller('$ionicScroll'); + if (!scrollCtrl) { + return; + } + + ionic.on('tap', onTap, $element[0]); + $scope.$on('$destroy', function() { + ionic.off('tap', onTap, $element[0]); + }); + + function onTap(e) { + if (ionic.DomUtil.getParentOrSelfWithClass(e.target, 'button', 4)) { + return; + } + var touch = e.gesture && e.gesture.touches[0] || e.detail.touches[0]; + var bounds = $element[0].getBoundingClientRect(); + if(ionic.DomUtil.rectContains( + touch.pageX, touch.pageY, + bounds.left, bounds.top - 20, + bounds.left + bounds.width, bounds.top + bounds.height) + ) { + scrollCtrl.scrollTop(true); + } + } + }); + } + }; + }]; +} + + function barDirective(isHeader) { return ['$parse', function($parse) { return { diff --git a/js/ext/angular/test/directive/ionicBar.unit.js b/js/ext/angular/test/directive/ionicBar.unit.js index 8df8a0e467..4fd9396a4c 100644 --- a/js/ext/angular/test/directive/ionicBar.unit.js +++ b/js/ext/angular/test/directive/ionicBar.unit.js @@ -1,54 +1,56 @@ describe('bar directives', function() { beforeEach(module('ionic')); - describe('tapScrollToTop', function() { - function setup() { - var el; - inject(function($compile, $rootScope) { - el = angular.element('') - var container = angular.element('').append(el); - ionic.requestAnimationFrame = function(cb) { cb(); }; - $compile(container)($rootScope.$new()); - container.controller('$ionicScroll').scrollTop = jasmine.createSpy('scrollTop') - $rootScope.$apply(); + ['', ''].forEach(function(tpl) { + describe('tapScrollToTop ' + tpl, function() { + function setup() { + var el; + inject(function($compile, $rootScope) { + el = angular.element(tpl); + var container = angular.element('').append(el); + ionic.requestAnimationFrame = function(cb) { cb(); }; + $compile(container)($rootScope.$new()); + container.controller('$ionicScroll').scrollTop = jasmine.createSpy('scrollTop'); + $rootScope.$apply(); + }); + return el; + } + it('should listen for tap, unlisten on destroy', function() { + var callback; + spyOn(ionic, 'on').andCallFake(function(name, cb) { + callback = cb; + }); + spyOn(ionic, 'off'); + var el = setup(); + expect(ionic.on).toHaveBeenCalledWith('tap', jasmine.any(Function), el[0]); + expect(ionic.off).not.toHaveBeenCalled(); + el.scope().$destroy(); + expect(ionic.off).toHaveBeenCalledWith('tap', callback, el[0]); }); - return el; - } - it('should listen for tap, unlisten on destroy', function() { - var callback; - spyOn(ionic, 'on').andCallFake(function(name, cb) { - callback = cb; + it('should ignore tap if it\'s in a button', function() { + var el = setup(); + spyOn(ionic.DomUtil, 'rectContains'); + var child = angular.element('
'); + el.append(child); + ionic.trigger('tap', { target: child[0] }, true, true); + expect(ionic.DomUtil.rectContains).not.toHaveBeenCalled(); }); - spyOn(ionic, 'off'); - var el = setup(); - expect(ionic.on).toHaveBeenCalledWith('tap', jasmine.any(Function), el[0]); - expect(ionic.off).not.toHaveBeenCalled(); - el.scope().$destroy(); - expect(ionic.off).toHaveBeenCalledWith('tap', callback, el[0]); - }); - it('should ignore tap if it\'s in a button', function() { - var el = setup(); - spyOn(ionic.DomUtil, 'rectContains'); - var child = angular.element('
'); - el.append(child); - ionic.trigger('tap', { target: child[0] }, true, true); - expect(ionic.DomUtil.rectContains).not.toHaveBeenCalled(); - }); - it('should scrollTop if tap is inside headerBar', function() { - var el = setup(); - spyOn(ionic.DomUtil, 'rectContains').andCallFake(function() { - return true; + it('should scrollTop if tap is inside headerBar', function() { + var el = setup(); + spyOn(ionic.DomUtil, 'rectContains').andCallFake(function() { + return true; + }); + ionic.trigger('tap', { target: el[0], touches: [{pageX:0,pageY:0}] }); + expect(el.controller('$ionicScroll').scrollTop).toHaveBeenCalledWith(true); }); - ionic.trigger('tap', { target: el[0], touches: [{pageX:0,pageY:0}] }); - expect(el.controller('$ionicScroll').scrollTop).toHaveBeenCalledWith(true); - }); - it('should not scrollTop if tap isnt inside headerBar', function() { - var el = setup(); - spyOn(ionic.DomUtil, 'rectContains').andCallFake(function() { - return false; + it('should not scrollTop if tap isnt inside headerBar', function() { + var el = setup(); + spyOn(ionic.DomUtil, 'rectContains').andCallFake(function() { + return false; + }); + ionic.trigger('tap', { target: el[0], touches: [{pageX:0,pageY:0}] }); + expect(el.controller('$ionicScroll').scrollTop).not.toHaveBeenCalled(); }); - ionic.trigger('tap', { target: el[0], touches: [{pageX:0,pageY:0}] }); - expect(el.controller('$ionicScroll').scrollTop).not.toHaveBeenCalled(); }); });