From 2fbdebcdea97ba2896106b80ca8c061588434c66 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Mon, 31 Mar 2014 13:53:49 -0500 Subject: [PATCH] fix(range): Fix range being able to slide when in a side menu, closes #318 --- js/ext/angular/src/directive/ionicSideMenu.js | 29 ++++---- .../test/directive/ionicSideMenu.unit.js | 70 +++++++++++++++++++ js/ext/angular/test/sideMenu2.html | 6 ++ 3 files changed, 92 insertions(+), 13 deletions(-) diff --git a/js/ext/angular/src/directive/ionicSideMenu.js b/js/ext/angular/src/directive/ionicSideMenu.js index ee810a516d1..d3b2d1e28f8 100644 --- a/js/ext/angular/src/directive/ionicSideMenu.js +++ b/js/ext/angular/src/directive/ionicSideMenu.js @@ -79,9 +79,9 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * @name $ionicSideMenuDelegate#getOpenRatio * @description Gets the ratio of open amount over menu width. For example, a * menu of width 100 that is opened by 50 pixels is 50% opened, and would return - * a ratio of 0.5. + * a ratio of 0.5. * - * @returns {float} 0 if nothing is open, between 0 and 1 if left menu is + * @returns {float} 0 if nothing is open, between 0 and 1 if left menu is * opened/opening, and between 0 and -1 if right menu is opened/opening. */ 'getOpenRatio', @@ -104,7 +104,7 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * side menus. * @returns {boolean} Whether the content can be dragged to open side menus. */ - 'canDragContent', + 'canDragContent' /** * @ngdoc method * @name $ionicSideMenuDelegate#$getByHandle @@ -171,8 +171,6 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie return { restrict: 'ECA', controller: ['$scope', '$attrs', '$ionicSideMenuDelegate', function($scope, $attrs, $ionicSideMenuDelegate) { - var _this = this; - angular.extend(this, ionic.controllers.SideMenuController.prototype); ionic.controllers.SideMenuController.call(this, { @@ -187,6 +185,14 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie return $scope.dragContent; }; + this.isDraggableTarget = function(e) { + return $scope.dragContent && + (!e.gesture.srcEvent.defaultPrevented && + !e.target.tagName.match(/input|textarea|select|object|embed/i) && + !e.target.isContentEditable && + !(e.target.dataset ? e.target.dataset.preventScroll : e.target.getAttribute('data-prevent-default') == 'true')); + }; + $scope.sideMenuContentTranslateX = 0; var deregisterInstance = $ionicSideMenuDelegate._registerInstance( @@ -225,6 +231,7 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * */ .directive('ionSideMenuContent', ['$timeout', '$ionicGesture', function($timeout, $ionicGesture) { + return { restrict: 'EA', //DEPRECATED 'A' require: '^ionSideMenus', @@ -256,14 +263,10 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie ionic.on('tap', contentTap, $element[0]); var dragFn = function(e) { - if($scope.dragContent) { - if(defaultPrevented || e.gesture.srcEvent.defaultPrevented) { - return; - } - isDragging = true; - sideMenuCtrl._handleDrag(e); - e.gesture.srcEvent.preventDefault(); - } + if(defaultPrevented || !sideMenuCtrl.isDraggableTarget(e)) return; + isDragging = true; + sideMenuCtrl._handleDrag(e); + e.gesture.srcEvent.preventDefault(); }; var dragVertFn = function(e) { diff --git a/js/ext/angular/test/directive/ionicSideMenu.unit.js b/js/ext/angular/test/directive/ionicSideMenu.unit.js index 75c34d399ce..9c7344c7b9c 100644 --- a/js/ext/angular/test/directive/ionicSideMenu.unit.js +++ b/js/ext/angular/test/directive/ionicSideMenu.unit.js @@ -38,6 +38,76 @@ describe('Ionic Angular Side Menu', function() { expect(el.controller('ionSideMenus').canDragContent()).toBe(true); expect(el.scope().dragContent).toBe(true); })); + + it('should isDraggableTarget', inject(function($compile, $rootScope) { + var el = $compile('')($rootScope.$new()); + $rootScope.$apply(); + + expect(el.controller('ionSideMenus').canDragContent()).toBe(true); + + var e = { + gesture: { + srcEvent: { + defaultPrevented: false + } + }, + target: { + tagName: 'DIV', + dataset: { + preventScroll: false + } + } + }; + + var ctrl = el.controller('ionSideMenus'); + expect(ctrl.isDraggableTarget(e)).toBe(true); + + el.controller('ionSideMenus').canDragContent(false); + expect(ctrl.isDraggableTarget(e)).toBe(false); + el.controller('ionSideMenus').canDragContent(true); + + e.gesture.srcEvent.defaultPrevented = true; + expect(ctrl.isDraggableTarget(e)).toBe(false); + e.gesture.srcEvent.defaultPrevented = false; + + e.target.tagName = 'INPUT'; + expect(ctrl.isDraggableTarget(e)).toBe(false); + + e.target.tagName = 'TEXTAREA'; + expect(ctrl.isDraggableTarget(e)).toBe(false); + + e.target.tagName = 'SELECT'; + expect(ctrl.isDraggableTarget(e)).toBe(false); + + e.target.tagName = 'OBJECT'; + expect(ctrl.isDraggableTarget(e)).toBe(false); + + e.target.tagName = 'EMBED'; + expect(ctrl.isDraggableTarget(e)).toBe(false); + + e.target.tagName = 'DIV'; + expect(ctrl.isDraggableTarget(e)).toBe(true); + + e.target.isContentEditable = true; + expect(ctrl.isDraggableTarget(e)).toBe(false); + e.target.isContentEditable = false; + + e.target.dataset.preventScroll = true + expect(ctrl.isDraggableTarget(e)).toBe(false); + e.target.isContentEditable = false; + + e.target.dataset = undefined; + e.target.getAttribute = function(val){ + return (val == 'data-prevent-default' ? 'true' : undefined); + } + expect(ctrl.isDraggableTarget(e)).toBe(false); + + e.target.getAttribute = function(){ + return null; + } + expect(ctrl.isDraggableTarget(e)).toBe(true); + + })); }); describe('Ionic Side Menu Content Directive', function () { diff --git a/js/ext/angular/test/sideMenu2.html b/js/ext/angular/test/sideMenu2.html index 12cf0a4c5ca..785a814f271 100644 --- a/js/ext/angular/test/sideMenu2.html +++ b/js/ext/angular/test/sideMenu2.html @@ -69,6 +69,12 @@

Swipe to the right to reveal the left menu.

+
+ Range + 5 km + + 700 km +
{{$index}} :