diff options
author | Vincent Petry <pvince81@owncloud.com> | 2014-03-18 13:09:25 +0100 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2014-03-18 13:10:13 +0100 |
commit | fe04106e0f6a88b5e3cf490773f2cb625465e98a (patch) | |
tree | de57ade0958602d15184ea10b2e5fc44703d25f3 /core | |
parent | 285fc5ba96eba1c9046a3c05c39ed7708c13b897 (diff) | |
download | nextcloud-server-fe04106e0f6a88b5e3cf490773f2cb625465e98a.tar.gz nextcloud-server-fe04106e0f6a88b5e3cf490773f2cb625465e98a.zip |
Add/remove main menu action when switching between desktop/mobile mode
Diffstat (limited to 'core')
-rw-r--r-- | core/js/js.js | 59 | ||||
-rw-r--r-- | core/js/tests/specs/coreSpec.js | 101 |
2 files changed, 154 insertions, 6 deletions
diff --git a/core/js/js.js b/core/js/js.js index 23d16b69234..aefca235093 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -488,7 +488,7 @@ var OC={ registerMenu: function($toggle, $menuEl) { $menuEl.addClass('menu'); $toggle.addClass('menutoggle'); - $toggle.on('click', function(event) { + $toggle.on('click.menu', function(event) { if ($menuEl.is(OC._currentMenu)) { $menuEl.hide(); OC._currentMenu = null; @@ -505,6 +505,17 @@ var OC={ OC._currentMenuToggle = $toggle; return false }); + }, + + unregisterMenu: function($toggle, $menuEl) { + // close menu if opened + if ($menuEl.is(OC._currentMenu)) { + $menuEl.hide(); + OC._currentMenu = null; + OC._currentMenuToggle = null; + } + $toggle.off('click.menu').removeClass('menutoggle'); + $menuEl.removeClass('menu'); } }; OC.search.customResults={}; @@ -978,13 +989,49 @@ function initCore() { OC._currentMenuToggle = null; }); - // toggle the navigation on mobile - if (window.matchMedia) { - var mq = window.matchMedia('(max-width: 600px)'); - if (mq && mq.matches) { - OC.registerMenu($('#header #owncloud'), $('#navigation')); + + /** + * Set up the main menu toggle to react to media query changes. + * If the screen is small enough, the main menu becomes a toggle. + * If the screen is bigger, the main menu is not a toggle any more. + */ + function setupMainMenu() { + // toggle the navigation on mobile + if (window.matchMedia) { + var mq = window.matchMedia('(max-width: 600px)'); + var lastMatch = mq.matches; + var $toggle = $('#header #owncloud'); + var $navigation = $('#navigation'); + + function updateMainMenu() { + // mobile mode ? + if (lastMatch && !$toggle.hasClass('menutoggle')) { + // init the menu + OC.registerMenu($toggle, $navigation); + $toggle.data('oldhref', $toggle.attr('href')); + $toggle.attr('href', '#'); + $navigation.hide(); + } + else { + OC.unregisterMenu($toggle, $navigation); + $toggle.attr('href', $toggle.data('oldhref')); + $navigation.show(); + } + } + + updateMainMenu(); + + // TODO: debounce this + $(window).resize(function() { + if (lastMatch !== mq.matches) { + lastMatch = mq.matches; + updateMainMenu(); + } + }); } } + + setupMainMenu(); } $(document).ready(initCore); diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js index 069546387c7..7fa0b8e9e62 100644 --- a/core/js/tests/specs/coreSpec.js +++ b/core/js/tests/specs/coreSpec.js @@ -279,5 +279,106 @@ describe('Core base tests', function() { expect(OC.generateUrl('apps/files/download{file}', {file: '/Welcome.txt'})).toEqual(OC.webroot + '/index.php/apps/files/download/Welcome.txt'); }); }); + describe('Main menu mobile toggle', function() { + var oldMatchMedia; + var $toggle; + var $navigation; + + beforeEach(function() { + oldMatchMedia = window.matchMedia; + window.matchMedia = sinon.stub(); + $('#testArea').append('<div id="header">' + + '<a id="owncloud" href="#"></a>' + + '</div>' + + '<div id="navigation"></div>'); + $toggle = $('#owncloud'); + $navigation = $('#navigation'); + }); + + afterEach(function() { + window.matchMedia = oldMatchMedia; + }); + it('Sets up menu toggle in mobile mode', function() { + window.matchMedia.returns({matches: true}); + window.initCore(); + expect($toggle.hasClass('menutoggle')).toEqual(true); + expect($navigation.hasClass('menu')).toEqual(true); + }); + it('Does not set up menu toggle in desktop mode', function() { + window.matchMedia.returns({matches: false}); + window.initCore(); + expect($toggle.hasClass('menutoggle')).toEqual(false); + expect($navigation.hasClass('menu')).toEqual(false); + }); + it('Switches on menu toggle when mobile mode changes', function() { + var mq = {matches: false}; + window.matchMedia.returns(mq); + window.initCore(); + expect($toggle.hasClass('menutoggle')).toEqual(false); + mq.matches = true; + $(window).trigger('resize'); + expect($toggle.hasClass('menutoggle')).toEqual(true); + }); + it('Switches off menu toggle when mobile mode changes', function() { + var mq = {matches: true}; + window.matchMedia.returns(mq); + window.initCore(); + expect($toggle.hasClass('menutoggle')).toEqual(true); + mq.matches = false; + $(window).trigger('resize'); + expect($toggle.hasClass('menutoggle')).toEqual(false); + }); + it('Clicking menu toggle toggles navigation in mobile mode', function() { + window.matchMedia.returns({matches: true}); + window.initCore(); + $navigation.hide(); // normally done through media query triggered CSS + expect($navigation.is(':visible')).toEqual(false); + $toggle.click(); + expect($navigation.is(':visible')).toEqual(true); + $toggle.click(); + expect($navigation.is(':visible')).toEqual(false); + }); + it('Clicking menu toggle does not toggle navigation in desktop mode', function() { + window.matchMedia.returns({matches: false}); + window.initCore(); + expect($navigation.is(':visible')).toEqual(true); + $toggle.click(); + expect($navigation.is(':visible')).toEqual(true); + }); + it('Switching to mobile mode hides navigation', function() { + var mq = {matches: false}; + window.matchMedia.returns(mq); + window.initCore(); + expect($navigation.is(':visible')).toEqual(true); + mq.matches = true; + $(window).trigger('resize'); + expect($navigation.is(':visible')).toEqual(false); + }); + it('Switching to desktop mode shows navigation', function() { + var mq = {matches: true}; + window.matchMedia.returns(mq); + window.initCore(); + expect($navigation.is(':visible')).toEqual(false); + mq.matches = false; + $(window).trigger('resize'); + expect($navigation.is(':visible')).toEqual(true); + }); + it('Switch to desktop with opened menu then back to mobile resets toggle', function() { + var mq = {matches: true}; + window.matchMedia.returns(mq); + window.initCore(); + expect($navigation.is(':visible')).toEqual(false); + $toggle.click(); + expect($navigation.is(':visible')).toEqual(true); + mq.matches = false; + $(window).trigger('resize'); + expect($navigation.is(':visible')).toEqual(true); + mq.matches = true; + $(window).trigger('resize'); + expect($navigation.is(':visible')).toEqual(false); + $toggle.click(); + expect($navigation.is(':visible')).toEqual(true); + }); + }); }); |