diff options
author | Thomas Müller <thomas.mueller@tmit.eu> | 2014-04-02 08:48:37 +0200 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2014-04-02 08:48:37 +0200 |
commit | 7086c386fdd1cfcec0ddc0db19615bd4586bade3 (patch) | |
tree | 26d7a890bc0350af5260bb7a3736610e533e6d3b /core/js | |
parent | 229e3dcba86db3bd91bbddd78079bf340edff710 (diff) | |
parent | 73dd5ff26c2d7652fd4abacbac53d734f64fde96 (diff) | |
download | nextcloud-server-7086c386fdd1cfcec0ddc0db19615bd4586bade3.tar.gz nextcloud-server-7086c386fdd1cfcec0ddc0db19615bd4586bade3.zip |
Merge branch 'master' into append-error-document
Conflicts:
lib/private/setup.php
lib/private/updater.php
Diffstat (limited to 'core/js')
-rw-r--r-- | core/js/core.json | 1 | ||||
-rw-r--r-- | core/js/jquery.avatar.js | 41 | ||||
-rw-r--r-- | core/js/js.js | 151 | ||||
-rw-r--r-- | core/js/router.js | 81 | ||||
-rw-r--r-- | core/js/setup.js | 2 | ||||
-rw-r--r-- | core/js/share.js | 32 | ||||
-rw-r--r-- | core/js/tags.js | 18 | ||||
-rw-r--r-- | core/js/tests/specHelper.js | 16 | ||||
-rw-r--r-- | core/js/tests/specs/coreSpec.js | 127 |
9 files changed, 320 insertions, 149 deletions
diff --git a/core/js/core.json b/core/js/core.json index 4beab7cf796..665e2485a90 100644 --- a/core/js/core.json +++ b/core/js/core.json @@ -17,7 +17,6 @@ "eventsource.js", "config.js", "multiselect.js", - "router.js", "oc-requesttoken.js" ] } diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js index 02a40c088b4..381c42d9dbb 100644 --- a/core/js/jquery.avatar.js +++ b/core/js/jquery.avatar.js @@ -75,31 +75,32 @@ var $div = this; - OC.Router.registerLoadedCallback(function() { - var url = OC.Router.generate('core_avatar_get', {user: user, size: size})+'?requesttoken='+oc_requesttoken; - $.get(url, function(result) { - if (typeof(result) === 'object') { - if (!hidedefault) { - if (result.data && result.data.displayname) { - $div.imageplaceholder(user, result.data.displayname); - } else { - $div.imageplaceholder(user); - } + var url = OC.generateUrl( + '/avatar/{user}/{size}?requesttoken={requesttoken}', + {user: user, size: size, requesttoken: oc_requesttoken}); + + $.get(url, function(result) { + if (typeof(result) === 'object') { + if (!hidedefault) { + if (result.data && result.data.displayname) { + $div.imageplaceholder(user, result.data.displayname); } else { - $div.hide(); + $div.imageplaceholder(user); } } else { - $div.show(); - if (ie8fix === true) { - $div.html('<img src="'+url+'#'+Math.floor(Math.random()*1000)+'">'); - } else { - $div.html('<img src="'+url+'">'); - } + $div.hide(); } - if(typeof callback === 'function') { - callback(); + } else { + $div.show(); + if (ie8fix === true) { + $div.html('<img src="'+url+'#'+Math.floor(Math.random()*1000)+'">'); + } else { + $div.html('<img src="'+url+'">'); } - }); + } + if(typeof callback === 'function') { + callback(); + } }); }; }(jQuery)); diff --git a/core/js/js.js b/core/js/js.js index 21ccee0f1d5..302b6b4d9fa 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -27,7 +27,7 @@ if (oc_debug !== true || typeof console === "undefined" || typeof console.log == if (!window.console) { window.console = {}; } - var methods = ['log', 'debug', 'warn', 'info', 'error', 'assert']; + var methods = ['log', 'debug', 'warn', 'info', 'error', 'assert', 'time', 'timeEnd']; for (var i = 0; i < methods.length; i++) { console[methods[i]] = function () { }; } @@ -194,6 +194,30 @@ var OC={ linkToRemoteBase:function(service) { return OC.webroot + '/remote.php/' + service; }, + + /** + * Generates the absolute url for the given relative url, which can contain parameters. + * + * @returns {string} + * @param {string} url + * @param params + */ + generateUrl: function(url, params) { + var _build = function (text, vars) { + return text.replace(/{([^{}]*)}/g, + function (a, b) { + var r = vars[b]; + return typeof r === 'string' || typeof r === 'number' ? r : a; + } + ); + }; + if (url.charAt(0) !== '/') { + url = '/' + url; + + } + return OC.webroot + '/index.php' + _build(url, params); + }, + /** * @brief Creates an absolute url for remote use * @param string $service id @@ -458,6 +482,53 @@ var OC={ }).show(); }, 'html'); } + }, + + // for menu toggling + registerMenu: function($toggle, $menuEl) { + $menuEl.addClass('menu'); + $toggle.addClass('menutoggle'); + $toggle.on('click.menu', function(event) { + if ($menuEl.is(OC._currentMenu)) { + $menuEl.hide(); + OC._currentMenu = null; + OC._currentMenuToggle = null; + return false; + } + // another menu was open? + else if (OC._currentMenu) { + // close it + OC._currentMenu.hide(); + } + $menuEl.show(); + OC._currentMenu = $menuEl; + 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'); + }, + + /** + * Wrapper for matchMedia + * + * This is makes it possible for unit tests to + * stub matchMedia (which doesn't work in PhantomJS) + */ + _matchMedia: function(media) { + if (window.matchMedia) { + return window.matchMedia(media); + } + return false; } }; OC.search.customResults={}; @@ -638,6 +709,9 @@ if(typeof localStorage !=='undefined' && localStorage !== null){ setItem:function(name,item){ return localStorage.setItem(OC.localStorage.namespace+name,JSON.stringify(item)); }, + removeItem:function(name,item){ + return localStorage.removeItem(OC.localStorage.namespace+name); + }, getItem:function(name){ var item = localStorage.getItem(OC.localStorage.namespace+name); if(item===null) { @@ -685,11 +759,11 @@ SVGSupport.checkMimeType=function(){ if(value[0]==='"'){ value=value.substr(1,value.length-2); } - headers[parts[0]]=value; + headers[parts[0].toLowerCase()]=value; } } }); - if(headers["Content-Type"]!=='image/svg+xml'){ + if(headers["content-type"]!=='image/svg+xml'){ replaceSVG(); SVGSupport.checkMimeType.correct=false; } @@ -791,12 +865,10 @@ function initCore() { if (interval < 60) { interval = 60; } - OC.Router.registerLoadedCallback(function(){ - var url = OC.Router.generate('heartbeat'); - setInterval(function(){ - $.post(url); - }, interval * 1000); - }); + var url = OC.generateUrl('/heartbeat'); + setInterval(function(){ + $.post(url); + }, interval * 1000); } // session heartbeat (defaults to enabled) @@ -915,6 +987,67 @@ function initCore() { $('a.action').tipsy({gravity:'s', fade:true, live:true}); $('td .modified').tipsy({gravity:'s', fade:true, live:true}); $('input').tipsy({gravity:'w', fade:true}); + + // toggle for menus + $(document).on('mouseup.closemenus', function(event) { + var $el = $(event.target); + if ($el.closest('.menu').length || $el.closest('.menutoggle').length) { + // don't close when clicking on the menu directly or a menu toggle + return false; + } + if (OC._currentMenu) { + OC._currentMenu.hide(); + } + OC._currentMenu = null; + OC._currentMenuToggle = null; + }); + + + /** + * 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 (!OC._matchMedia) { + return; + } + var mq = OC._matchMedia('(max-width: 768px)'); + 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(); + } + }); + } + + if (window.matchMedia) { + setupMainMenu(); + } } $(document).ready(initCore); diff --git a/core/js/router.js b/core/js/router.js deleted file mode 100644 index e6ef54a1864..00000000000 --- a/core/js/router.js +++ /dev/null @@ -1,81 +0,0 @@ -OC.router_base_url = OC.webroot + '/index.php'; -OC.Router = { - // register your ajax requests to load after the loading of the routes - // has finished. otherwise you face problems with race conditions - registerLoadedCallback: function(callback){ - if (!this.routes_request){ - return; - } - this.routes_request.done(callback); - }, - routes_request: !window.TESTING && $.ajax(OC.router_base_url + '/core/routes.json', { - dataType: 'json', - success: function(jsondata) { - if (jsondata.status === 'success') { - OC.Router.routes = jsondata.data; - } - } - }), - generate:function(name, opt_params) { - if (!('routes' in this)) { - if(this.routes_request.state() != 'resolved') { - console.warn('To avoid race conditions, please register a callback');// wait - } - } - if (!(name in this.routes)) { - throw new Error('The route "' + name + '" does not exist.'); - } - var route = this.routes[name]; - var params = opt_params || {}; - var unusedParams = $.extend(true, {}, params); - var url = ''; - var optional = true; - $(route.tokens).each(function(i, token) { - if ('text' === token[0]) { - url = token[1] + url; - optional = false; - - return; - } - - if ('variable' === token[0]) { - if (false === optional || !(token[3] in route.defaults) - || ((token[3] in params) && params[token[3]] != route.defaults[token[3]])) { - var value; - if (token[3] in params) { - value = params[token[3]]; - delete unusedParams[token[3]]; - } else if (token[3] in route.defaults) { - value = route.defaults[token[3]]; - } else if (optional) { - return; - } else { - throw new Error('The route "' + name + '" requires the parameter "' + token[3] + '".'); - } - - var empty = true === value || false === value || '' === value; - - if (!empty || !optional) { - url = token[1] + encodeURIComponent(value).replace(/%2F/g, '/') + url; - } - - optional = false; - } - - return; - } - - throw new Error('The token type "' + token[0] + '" is not supported.'); - }); - if (url === '') { - url = '/'; - } - - unusedParams = $.param(unusedParams); - if (unusedParams.length > 0) { - url += '?'+unusedParams; - } - - return OC.router_base_url + url; - } -} diff --git a/core/js/setup.js b/core/js/setup.js index 279b5fbebb9..96719540f96 100644 --- a/core/js/setup.js +++ b/core/js/setup.js @@ -36,6 +36,7 @@ $(document).ready(function() { $('#showAdvanced').click(function() { $('#datadirContent').slideToggle(250); + $('#databaseBackend').slideToggle(250); $('#databaseField').slideToggle(250); }); $("form").submit(function(){ @@ -73,6 +74,7 @@ $(document).ready(function() { if (currentDbType === 'sqlite' || (dbtypes.sqlite && currentDbType === undefined)){ $('#datadirContent').hide(250); + $('#databaseBackend').hide(250); $('#databaseField').hide(250); } diff --git a/core/js/share.js b/core/js/share.js index 0939259b7da..ef71cc7999a 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -48,7 +48,7 @@ OC.Share={ var action = $(file).find('.fileactions .action[data-action="Share"]'); var img = action.find('img').attr('src', image); action.addClass('permanent'); - action.html(' '+t('core', 'Shared')).prepend(img); + action.html(' <span>'+t('core', 'Shared')+'</span>').prepend(img); } else { var dir = $('#dir').val(); if (dir.length > 1) { @@ -63,7 +63,7 @@ OC.Share={ if (img.attr('src') != OC.imagePath('core', 'actions/public')) { img.attr('src', image); $(action).addClass('permanent'); - $(action).html(' '+t('core', 'Shared')).prepend(img); + $(action).html(' <span>'+t('core', 'Shared')+'</span>').prepend(img); } }); } @@ -103,10 +103,10 @@ OC.Share={ var img = action.find('img').attr('src', image); if (shares) { action.addClass('permanent'); - action.html(' '+ escapeHTML(t('core', 'Shared'))).prepend(img); + action.html(' <span>'+ escapeHTML(t('core', 'Shared'))+'</span>').prepend(img); } else { action.removeClass('permanent'); - action.html(' '+ escapeHTML(t('core', 'Share'))).prepend(img); + action.html(' <span>'+ escapeHTML(t('core', 'Share'))+'</span>').prepend(img); } } } @@ -551,7 +551,7 @@ $(document).ready(function() { var itemType = $('#dropdown').data('item-type'); var itemSource = $('#dropdown').data('item-source'); var shareType = $li.data('share-type'); - var shareWith = $li.data('share-with'); + var shareWith = $li.attr('data-share-with'); OC.Share.unshare(itemType, itemSource, shareType, shareWith, function() { $li.remove(); var index = OC.Share.itemShares[shareType].indexOf(shareWith); @@ -584,8 +584,8 @@ $(document).ready(function() { $(checkboxes).filter('input[name="edit"]').attr('checked', false); // Check Edit if Create, Update, or Delete is checked } else if (($(this).attr('name') == 'create' - || $(this).attr('name') == 'update' - || $(this).attr('name') == 'delete')) + || $(this).attr('name') == 'update' + || $(this).attr('name') == 'delete')) { $(checkboxes).filter('input[name="edit"]').attr('checked', true); } @@ -597,7 +597,7 @@ $(document).ready(function() { OC.Share.setPermissions($('#dropdown').data('item-type'), $('#dropdown').data('item-source'), li.data('share-type'), - li.data('share-with'), + li.attr('data-share-with'), permissions); }); @@ -718,9 +718,21 @@ $(document).ready(function() { $(document).on('change', '#dropdown #expirationDate', function() { var itemType = $('#dropdown').data('item-type'); var itemSource = $('#dropdown').data('item-source'); + + $(this).tipsy('hide'); + $(this).removeClass('error'); + $.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'setExpirationDate', itemType: itemType, itemSource: itemSource, date: $(this).val() }, function(result) { if (!result || result.status !== 'success') { - OC.dialogs.alert(t('core', 'Error setting expiration date'), t('core', 'Error')); + var expirationDateField = $('#dropdown #expirationDate'); + if (!result.data.message) { + expirationDateField.attr('original-title', t('core', 'Error setting expiration date')); + } else { + expirationDateField.attr('original-title', result.data.message); + } + expirationDateField.tipsy({gravity: 'n', fade: true}); + expirationDateField.tipsy('show'); + expirationDateField.addClass('error'); } }); }); @@ -770,7 +782,7 @@ $(document).ready(function() { } var shareType = $li.data('share-type'); - var shareWith = $li.data('share-with'); + var shareWith = $li.attr('data-share-with'); $.post(OC.filePath('core', 'ajax', 'share.php'), {action: action, recipient: shareWith, shareType: shareType, itemSource: itemSource, itemType: itemType}, function(result) { if (result.status !== 'success') { diff --git a/core/js/tags.js b/core/js/tags.js index bc6d7b4e071..bc2b42bf5ff 100644 --- a/core/js/tags.js +++ b/core/js/tags.js @@ -69,7 +69,7 @@ OC.Tags= { type = type ? type : this.type; var defer = $.Deferred(), self = this, - url = OC.Router.generate('core_tags_ids_for_tag', {type: type}); + url = OC.generateUrl('/tags/{type}/ids', {type: type}); $.getJSON(url, {tag: tag}, function(response) { if(response.status === 'success') { defer.resolve(response.ids); @@ -90,7 +90,7 @@ OC.Tags= { type = type ? type : this.type; var defer = $.Deferred(), self = this, - url = OC.Router.generate('core_tags_favorites', {type: type}); + url = OC.generateUrl('/tags/{type}/favorites', {type: type}); $.getJSON(url, function(response) { if(response.status === 'success') { defer.resolve(response.ids); @@ -111,7 +111,7 @@ OC.Tags= { type = type ? type : this.type; var defer = $.Deferred(), self = this, - url = OC.Router.generate('core_tags_tags', {type: type}); + url = OC.generateUrl('/tags/{type}', {type: type}); $.getJSON(url, function(response) { if(response.status === 'success') { defer.resolve(response.tags); @@ -133,7 +133,7 @@ OC.Tags= { type = type ? type : this.type; var defer = $.Deferred(), self = this, - url = OC.Router.generate('core_tags_tag', {type: type, id: id}); + url = OC.generateUrl('/tags/{type}/tag/{id}/', {type: type, id: id}); $.post(url, {tag: tag}, function(response) { if(response.status === 'success') { defer.resolve(response); @@ -157,7 +157,7 @@ OC.Tags= { type = type ? type : this.type; var defer = $.Deferred(), self = this, - url = OC.Router.generate('core_tags_untag', {type: type, id: id}); + url = OC.generateUrl('/tags/{type}/untag/{id}/', {type: type, id: id}); $.post(url, {tag: tag}, function(response) { if(response.status === 'success') { defer.resolve(response); @@ -181,7 +181,7 @@ OC.Tags= { type = type ? type : this.type; var defer = $.Deferred(), self = this, - url = OC.Router.generate('core_tags_favorite', {type: type, id: id}); + url = OC.generateUrl('/tags/{type}/favorite/{id}/', {type: type, id: id}); $.post(url, function(response) { if(response.status === 'success') { defer.resolve(response); @@ -205,7 +205,7 @@ OC.Tags= { type = type ? type : this.type; var defer = $.Deferred(), self = this, - url = OC.Router.generate('core_tags_unfavorite', {type: type, id: id}); + url = OC.generateUrl('/tags/{type}/unfavorite/{id}/', {type: type, id: id}); $.post(url, function(response) { if(response.status === 'success') { defer.resolve(); @@ -229,7 +229,7 @@ OC.Tags= { type = type ? type : this.type; var defer = $.Deferred(), self = this, - url = OC.Router.generate('core_tags_add', {type: type}); + url = OC.generateUrl('/tags/{type}/add', {type: type}); $.post(url,{tag:tag}, function(response) { if(typeof cb == 'function') { cb(response); @@ -256,7 +256,7 @@ OC.Tags= { type = type ? type : this.type; var defer = $.Deferred(), self = this, - url = OC.Router.generate('core_tags_delete', {type: type}); + url = OC.generateUrl('/tags/{type}/delete', {type: type}); if(!tags || !tags.length) { throw new Error(t('core', 'No tags selected for deletion.')); } diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js index b1193240580..d86cd81cda8 100644 --- a/core/js/tests/specHelper.js +++ b/core/js/tests/specHelper.js @@ -68,9 +68,14 @@ window.oc_defaults = {}; // global setup for all tests (function setupTests() { var fakeServer = null, + $testArea = null, routesRequestStub; beforeEach(function() { + // test area for elements that need absolute selector access or measure widths/heights + // which wouldn't work for detached or hidden elements + $testArea = $('<div id="testArea" style="position: absolute; width: 1280px; height: 800px; top: -3000px; left: -3000px;"></div>'); + $('body').append($testArea); // enforce fake XHR, tests should not depend on the server and // must use fake responses for expected calls fakeServer = sinon.fakeServer.create(); @@ -86,21 +91,14 @@ window.oc_defaults = {}; // make it globally available, so that other tests can define // custom responses window.fakeServer = fakeServer; - - OC.Router.routes = []; - OC.Router.routes_request = { - state: sinon.stub().returns('resolved'), - done: sinon.stub() - }; }); afterEach(function() { - OC.Router.routes_request.state.reset(); - OC.Router.routes_request.done.reset(); - // uncomment this to log requests // console.log(window.fakeServer.requests); fakeServer.restore(); + + $testArea.remove(); }); })(); diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js index 478505e9287..57ea5be8be0 100644 --- a/core/js/tests/specs/coreSpec.js +++ b/core/js/tests/specs/coreSpec.js @@ -179,7 +179,7 @@ describe('Core base tests', function() { }); it('Encodes special characters', function() { expect(OC.buildQueryString({ - unicode: '汉字', + unicode: '汉字' })).toEqual('unicode=%E6%B1%89%E5%AD%97'); expect(OC.buildQueryString({ b: 'spaace value', @@ -199,22 +199,20 @@ describe('Core base tests', function() { 'booleantrue': true })).toEqual('booleanfalse=false&booleantrue=true'); expect(OC.buildQueryString({ - 'number': 123, + 'number': 123 })).toEqual('number=123'); }); }); describe('Session heartbeat', function() { var clock, oldConfig, - loadedStub, routeStub, counter; beforeEach(function() { clock = sinon.useFakeTimers(); oldConfig = window.oc_config; - loadedStub = sinon.stub(OC.Router, 'registerLoadedCallback'); - routeStub = sinon.stub(OC.Router, 'generate').returns('/heartbeat'); + routeStub = sinon.stub(OC, 'generateUrl').returns('/heartbeat'); counter = 0; fakeServer.autoRespond = true; @@ -227,7 +225,6 @@ describe('Core base tests', function() { afterEach(function() { clock.restore(); window.oc_config = oldConfig; - loadedStub.restore(); routeStub.restore(); }); it('sends heartbeat half the session lifetime when heartbeat enabled', function() { @@ -236,9 +233,7 @@ describe('Core base tests', function() { session_lifetime: 300 }; window.initCore(); - expect(loadedStub.calledOnce).toEqual(true); - loadedStub.yield(); - expect(routeStub.calledWith('heartbeat')).toEqual(true); + expect(routeStub.calledWith('/heartbeat')).toEqual(true); expect(counter).toEqual(0); @@ -264,7 +259,6 @@ describe('Core base tests', function() { session_lifetime: 300 }; window.initCore(); - expect(loadedStub.notCalled).toEqual(true); expect(routeStub.notCalled).toEqual(true); expect(counter).toEqual(0); @@ -276,5 +270,118 @@ describe('Core base tests', function() { }); }); + describe('Generate Url', function() { + it('returns absolute urls', function() { + expect(OC.generateUrl('heartbeat')).toEqual(OC.webroot + '/index.php/heartbeat'); + expect(OC.generateUrl('/heartbeat')).toEqual(OC.webroot + '/index.php/heartbeat'); + }); + it('substitutes parameters', 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 = OC._matchMedia; + // a separate method was needed because window.matchMedia + // cannot be stubbed due to a bug in PhantomJS: + // https://github.com/ariya/phantomjs/issues/12069 + OC._matchMedia = sinon.stub(); + $('#testArea').append('<div id="header">' + + '<a id="owncloud" href="#"></a>' + + '</div>' + + '<div id="navigation"></div>'); + $toggle = $('#owncloud'); + $navigation = $('#navigation'); + }); + + afterEach(function() { + OC._matchMedia = oldMatchMedia; + }); + it('Sets up menu toggle in mobile mode', function() { + OC._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() { + OC._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}; + OC._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}; + OC._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() { + OC._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() { + OC._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}; + OC._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}; + OC._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}; + OC._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); + }); + }); }); |