diff --git a/src/topbar/test/topbar.spec.js b/src/topbar/test/topbar.spec.js index 130263a..5f75948 100644 --- a/src/topbar/test/topbar.spec.js +++ b/src/topbar/test/topbar.spec.js @@ -1,131 +1,161 @@ -describe('topbar directive', function () { - var $rootScope, element, $document; +describe('topbar directive', function() { + var $rootScope, $document, $compile, $window, element, containerElement; - var setMobile = function(windowMock){ - windowMock.matchMedia.andReturn({matches: false}); - }; - - var setDesktop = function(windowMock){ - windowMock.matchMedia.andReturn({matches: true}); - }; + beforeEach(function() { + $window = angular.extend(window, { + pageYOffset: 0, + scrollTo: jasmine.createSpy('scrollTo'), + matchMedia: jasmine.createSpy('matchMedia').andReturn({matches: false}), + }); - beforeEach(module('template/topbar/top-bar.html')); - beforeEach(module('template/topbar/has-dropdown.html')); - beforeEach(module('template/topbar/toggle-top-bar.html')); - beforeEach(module('template/topbar/top-bar-section.html')); - beforeEach(module('template/topbar/top-bar-dropdown.html')); + module( + 'mm.foundation.topbar', + 'template/topbar/top-bar.html', + 'template/topbar/has-dropdown.html', + 'template/topbar/toggle-top-bar.html', + 'template/topbar/top-bar-section.html', + 'template/topbar/top-bar-dropdown.html', + {$window: $window}); - beforeEach(module('mm.foundation.topbar', function($provide){ - window.matchMedia = jasmine.createSpy('matchMedia').andReturn({matches: false}); - $provide.value('$window', window); - })); - - beforeEach(inject(function(_$compile_, _$rootScope_, _$document_) { - $compile = _$compile_; - $rootScope = _$rootScope_; - $document = _$document_; - - element = $compile( - '' + - '
' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '
Content
' + - '
' + - '')($rootScope); - $('body', $document).append(element); - $rootScope.$digest(); - })); + inject(function(_$compile_, _$rootScope_, _$document_) { + $compile = _$compile_; + $rootScope = _$rootScope_; + $document = _$document_; + }); + }); beforeEach(inject(function ($rootScope) { this.addMatchers({ toHaveDropDownsOpen: function(noOfLevels) { - var dropDownDomEls = this.actual.find('li.has-dropdown.not-click'); + var dropDownDomEls = element.find('li.has-dropdown.not-click'); return dropDownDomEls.length === noOfLevels; }, toHaveMobileMenuOpen: function() { - var els = this.actual.find('nav.top-bar.expanded'); - return !!els.length; + return element.hasClass("expanded"); } }); })); - it('has a "top-bar" css class', function() { - expect(element.children('nav')).toHaveClass('top-bar'); - }); + var setMobile = function() { + $window.matchMedia.andReturn({matches: false}); + }; - it('has a drop down open on large screen', inject(function($window) { - setDesktop($window); - $('#dropdown', element).trigger('mouseenter'); - expect($window.matchMedia).toHaveBeenCalled(); - expect(element).toHaveDropDownsOpen(1); - })); + var setDesktop = function() { + $window.matchMedia.andReturn({matches: true}); + }; - it('has no drop downs open on small screen', inject(function($window) { - setMobile($window); - $('#dropdown', element).trigger('mouseenter'); - expect($window.matchMedia).toHaveBeenCalled(); - expect(element).toHaveDropDownsOpen(0); - })); + var compileDirective = function(markup) { + if (angular.isUndefined(markup)) { + markup = + '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
Content
' + + '
'; + } - it('has no mobile menu opening on large screen', inject(function($window) { - setDesktop($window); - $('#menu-toggle', element).trigger('click'); - expect($window.matchMedia).toHaveBeenCalled(); - expect(element).not.toHaveMobileMenuOpen(); - })); + containerElement = $compile(markup)($rootScope); + $('body', $document).append(element); + $rootScope.$digest(); + element = containerElement.find("nav"); + }; - it('opens and closes mobile menu on small screen', inject(function($window) { - setMobile($window); - $('#menu-toggle', element).trigger('click'); - expect($window.matchMedia).toHaveBeenCalled(); - expect(element).toHaveMobileMenuOpen(); - $('#menu-toggle', element).trigger('click'); - expect(element).not.toHaveMobileMenuOpen(); - })); + describe("basic behavior", function() { + beforeEach(function() { + compileDirective(); + }); - it('opens the submenu when a dropdown is clicked on mobile', inject(function($window) { - setMobile($window); - $('#menu-toggle', element).trigger('click'); - expect($window.matchMedia).toHaveBeenCalled(); - var beforeHeight = $('.top-bar', element)[0].style.height; - $('#dropdown', element).trigger('click'); - var afterHeight = $('.top-bar', element)[0].style.height; - expect(afterHeight).toNotEqual(beforeHeight); - expect($('#top-section', element)[0].style.left).toEqual('-100%'); - })); + it('has a "top-bar" css class', function() { + expect(element).toHaveClass('top-bar'); + }); + + it('has a drop down open on large screen', inject(function($window) { + setDesktop(); + $('#dropdown', element).trigger('mouseenter'); + expect($window.matchMedia).toHaveBeenCalled(); + expect(element).toHaveDropDownsOpen(1); + })); + + it('has no drop downs open on small screen', inject(function($window) { + setMobile(); + $('#dropdown', element).trigger('mouseenter'); + expect($window.matchMedia).toHaveBeenCalled(); + expect(element).toHaveDropDownsOpen(0); + })); - // it('has f-topbar-fixed class on body after link is clicked on a fixed mobile topbar', inject(function($window) { - // setMobile($window); - // $('#menu-toggle', element).trigger('click'); - // expect($window.matchMedia).toHaveBeenCalled(); - // $('#dropdown', element).trigger('click'); - // $('#alink', element).trigger('click'); - // expect($('body', $document)).toHaveClass('f-topbar-fixed'); - // })); + it('has no mobile menu opening on large screen', inject(function($window) { + setDesktop($window); + $('#menu-toggle', element).trigger('click'); + expect($window.matchMedia).toHaveBeenCalled(); + expect(element).not.toHaveMobileMenuOpen(); + })); + it('opens and closes mobile menu on small screen', inject(function($window) { + setMobile(); + $('#menu-toggle', element).trigger('click'); + expect($window.matchMedia).toHaveBeenCalled(); + expect(element).toHaveMobileMenuOpen(); + $('#menu-toggle', element).trigger('click'); + expect(element).not.toHaveMobileMenuOpen(); + })); + + it('opens the submenu when a dropdown is clicked on mobile', inject(function($window) { + var topSection = element.find('#top-section'); + var menuToggle = element.find('#menu-toggle'); + setMobile(); + expect(element.hasClass("expanded")).toBe(false); + menuToggle.trigger('click'); + expect($window.matchMedia).toHaveBeenCalled(); + expect(element.hasClass("expanded")).toBe(true); + })); + }); + + describe("sticky", function() { + var markup; + + beforeEach(function() { + markup = + '
' + + '' + + '' + + '' + + '
'; + }); + + it('does not apply the fixed class on initial load', function() { + compileDirective(markup); + expect(containerElement.hasClass('fixed')).toBe(false); + }); + }); }); diff --git a/src/topbar/topbar.js b/src/topbar/topbar.js index 17b91dd..bcb3fc3 100644 --- a/src/topbar/topbar.js +++ b/src/topbar/topbar.js @@ -150,14 +150,13 @@ angular.module("mm.foundation.topbar", ['mm.foundation.mediaQueries']) return; } - var $class = angular.element($document[0].querySelector('.' + scope.settings.stickyClass)); var distance = stickyoffset; - if ($window.pageYOffset > distance && !$class.hasClass('fixed')) { - $class.addClass('fixed'); + if ($window.pageYOffset > distance && !topbarContainer.hasClass('fixed')) { + topbarContainer.addClass('fixed'); body.css('padding-top', scope.originalHeight + 'px'); - } else if ($window.pageYOffset <= distance && $class.hasClass('fixed')) { - $class.removeClass('fixed'); + } else if ($window.pageYOffset <= distance && topbarContainer.hasClass('fixed')) { + topbarContainer.removeClass('fixed'); body.css('padding-top', ''); } }; @@ -193,7 +192,7 @@ angular.module("mm.foundation.topbar", ['mm.foundation.mediaQueries']) var expand = (on === undefined) ? !topbar.hasClass('expanded') : on; - if (expand){ + if (expand) { topbar.addClass('expanded'); } else { @@ -233,7 +232,7 @@ angular.module("mm.foundation.topbar", ['mm.foundation.mediaQueries']) if(topbarContainer.hasClass('fixed') || isSticky() ) { scope.stickyTopbar = true; scope.height = topbarContainer[0].offsetHeight; - var stickyoffset = topbarContainer[0].getBoundingClientRect().top; + var stickyoffset = topbarContainer[0].getBoundingClientRect().top + $window.pageYOffset; } else { scope.height = topbar[0].offsetHeight; } @@ -248,13 +247,12 @@ angular.module("mm.foundation.topbar", ['mm.foundation.mediaQueries']) } }); - angular.element($window).bind('resize', onResize); - angular.element($window).bind("scroll", onScroll); + angular.element($window).bind('scroll', onScroll); scope.$on('$destroy', function() { - angular.element($window).unbind("scroll", onResize); - angular.element($window).unbind("resize", onScroll); + angular.element($window).unbind('scroll', onResize); + angular.element($window).unbind('resize', onScroll); }); if (topbarContainer.hasClass('fixed')) {