diff --git a/README.md b/README.md index 01c96ea..d204d19 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,31 @@ controller('MyCtrl', function (myOffCanvas) { ``` +### Promises + +When the menu is opened with toggle(), it will return a promise that is resolved when the menu is closed. + +```javascript +myOffCanvas.toggle() + .then(function() { + console.log('The menu has been closed!'); + }); + +myOffCanvas.toggle(); // The menu will close and display the message. +``` + +If the menu is already opened, then the promise will be immediately rejected. + +```javascript +myOffCanvas.toggle(); // The menu will open and nothing will be displayed in the console. +myOffCanvas.toggle() + .then(function() { + console.log('The menu has been closed!'); + }, function() { + console.log('The menu was already opened.'); + }); // The menu will close and the message "The menu was already open" will be displayed immediately. +``` + ## API @@ -136,7 +161,8 @@ A `navService` has just two methods: `activate` and `deactivate`. #### `navService.toggle` -Add or remove a class to open/hide the nav with CSS +Add or remove a class to open/hide the nav with CSS. +Returns a promise that will be resolved when the off canvas menu closes, or is immediately rejected if the toggle closes an already opened menu. ## Tests diff --git a/off-canvas.js b/off-canvas.js index 8a62412..261953c 100644 --- a/off-canvas.js +++ b/off-canvas.js @@ -19,6 +19,7 @@ angular.module('cn.offCanvas', []) controller = config.controller || angular.noop, controllerAs = config.controllerAs, element = null, + promise = null, html; if(config.template) { @@ -45,13 +46,38 @@ angular.module('cn.offCanvas', []) }) function toggle() { - this.isOpened = !this.isOpened; - container.toggleClass(containerClass); + if (this.isOpened) { + return this.close(); + } else { + return this.open(); + } + } + + function open() { + if (!this.isOpened) { + this.isOpened = true; + container.toggleClass(containerClass); + } + promise = $q.defer(); + return promise.promise; + } + + function close() { + if (this.isOpened) { + this.isOpened = false; + container.toggleClass(containerClass); + } + promise.resolve(); + var defered = $q.defer(); + defered.reject(); + return defered.promise; } return { toggle: toggle, + open: open, + close: close, isOpened: false } } - }); \ No newline at end of file + }); diff --git a/off-canvas.min.js b/off-canvas.min.js index 4e427c5..1c0b6b9 100644 --- a/off-canvas.min.js +++ b/off-canvas.min.js @@ -1 +1 @@ -"use strict";angular.module("cn.offCanvas",[]).factory("cnOffCanvas",["$compile","$rootScope","$controller","$http","$templateCache","$q",function($compile,$rootScope,$controller,$http,$templateCache,$q){return function(config){function toggle(){this.isOpened=!this.isOpened,container.toggleClass(containerClass)}if(+!!config.template+ +!!config.templateUrl!==1)throw new Error;var html,container=angular.element(config.container||document.body),containerClass=config.containerClass||"is-off-canvas-opened",controller=config.controller||angular.noop,controllerAs=config.controllerAs,element=null;if(config.template){var deferred=$q.defer();deferred.resolve(config.template),html=deferred.promise}else html=$http.get(config.templateUrl,{cache:$templateCache}).then(function(response){return response.data});return html.then(function(html){var scope=$rootScope.$new(),ctrl=$controller(controller,{$scope:scope});controllerAs&&(scope[controllerAs]=ctrl),element=angular.element(html),container.prepend(element),$compile(element)(scope)}),{toggle:toggle,isOpened:!1}}}]); \ No newline at end of file +"use strict";angular.module("cn.offCanvas",[]).factory("cnOffCanvas",["$compile","$rootScope","$controller","$http","$templateCache","$q",function($compile,$rootScope,$controller,$http,$templateCache,$q){return function(config){function toggle(){return this.isOpened?this.close():this.open()}function open(){return this.isOpened||(this.isOpened=!0,container.toggleClass(containerClass)),promise=$q.defer(),promise.promise}function close(){this.isOpened&&(this.isOpened=!1,container.toggleClass(containerClass)),promise.resolve();var defered=$q.defer();return defered.reject(),defered.promise}if(+!!config.template+ +!!config.templateUrl!==1)throw new Error;var html,container=angular.element(config.container||document.body),containerClass=config.containerClass||"is-off-canvas-opened",controller=config.controller||angular.noop,controllerAs=config.controllerAs,element=null,promise=null;if(config.template){var deferred=$q.defer();deferred.resolve(config.template),html=deferred.promise}else html=$http.get(config.templateUrl,{cache:$templateCache}).then(function(response){return response.data});return html.then(function(html){var scope=$rootScope.$new(),ctrl=$controller(controller,{$scope:scope});controllerAs&&(scope[controllerAs]=ctrl),element=angular.element(html),container.prepend(element),$compile(element)(scope)}),{toggle:toggle,open:open,close:close,isOpened:!1}}}]); \ No newline at end of file diff --git a/off-canvas.spec.js b/off-canvas.spec.js index 205c563..0351142 100644 --- a/off-canvas.spec.js +++ b/off-canvas.spec.js @@ -111,4 +111,44 @@ describe('cnOffCanvas', function() { expect(container.hasClass('is-opened-nav')).toBeTruthy(); }); }); + + describe('promises', function() { + var offCanvas; + beforeEach(function() { + offCanvas = cnOffCanvas({ + templateUrl: 'test.html', + container: container + }); + }); + it('should be created on toggle', function() { + var promise = offCanvas.toggle(); + expect(promise).toBeDefined(); + promise = offCanvas.toggle(); + expect(promise).toBeDefined(); + }); + + it('should be resolved after closed', inject(function($rootScope) { + var resolved = false; + offCanvas.toggle() + .then(function() { + resolved = true; + }); + expect(resolved).toBe(false); + offCanvas.toggle(); + $rootScope.$apply(); + expect(resolved).toBe(true); + })); + + it('should be rejected if the toggle closes', inject(function($rootScope) { + offCanvas.toggle(); + var result = "nothing"; + offCanvas.toggle() + .then(function() { + resolved = "success"; + }, function() { + resolved = "rejected"; + }); + expect(resolved).toBe("rejected"); + })); + }); }); \ No newline at end of file