summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2014-03-18 13:09:25 +0100
committerVincent Petry <pvince81@owncloud.com>2014-03-18 13:10:13 +0100
commitfe04106e0f6a88b5e3cf490773f2cb625465e98a (patch)
treede57ade0958602d15184ea10b2e5fc44703d25f3 /core
parent285fc5ba96eba1c9046a3c05c39ed7708c13b897 (diff)
downloadnextcloud-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.js59
-rw-r--r--core/js/tests/specs/coreSpec.js101
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);
+ });
+ });
});