From df5785852111f7bb5c913ac9e3237b107d5b9838 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Fri, 29 Aug 2014 22:25:55 -0500 Subject: [PATCH] fix(menuContent): gestures do not stop_browser_behavior The gestures which were being added to side menu content were also adding the `disable-user-behavior` class, which disabled contenteditable elements. Now passing in the gesture option stop_browser_behavior=false, along with adding the options param to the gestures service. Fixes #421 --- js/angular/directive/sideMenuContent.js | 19 ++++++++++--------- js/angular/service/gesture.js | 4 ++-- js/utils/events.js | 4 ++-- js/utils/tap.js | 4 ++-- test/unit/utils/tap.unit.js | 23 +++++++++++++++++++++++ 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/js/angular/directive/sideMenuContent.js b/js/angular/directive/sideMenuContent.js index d29e251a2b4..f6efa69b705 100644 --- a/js/angular/directive/sideMenuContent.js +++ b/js/angular/directive/sideMenuContent.js @@ -60,13 +60,13 @@ function($timeout, $ionicGesture, $window) { } // Listen for taps on the content to close the menu - function onContentTap(e) { + function onContentTap(gestureEvt) { if(sideMenuCtrl.getOpenAmount() !== 0) { sideMenuCtrl.close(); - e.gesture.srcEvent.preventDefault(); + gestureEvt.gesture.srcEvent.preventDefault(); startCoord = null; primaryScrollAxis = null; - } else if(gestureEvt && gestureEvt.gesture && !startCoord) { + } else if(!startCoord) { startCoord = ionic.tap.pointerCoord(gestureEvt.gesture.srcEvent); } } @@ -168,12 +168,13 @@ function($timeout, $ionicGesture, $window) { sideMenuCtrl.setContent(content); // add gesture handlers - var contentTapGesture = $ionicGesture.on('tap', onContentTap, $element); - var dragRightGesture = $ionicGesture.on('dragright', onDragX, $element); - var dragLeftGesture = $ionicGesture.on('dragleft', onDragX, $element); - var dragUpGesture = $ionicGesture.on('dragup', onDragY, $element); - var dragDownGesture = $ionicGesture.on('dragdown', onDragY, $element); - var releaseGesture = $ionicGesture.on('release', onDragRelease, $element); + var gestureOpts = { stop_browser_behavior: false }; + var contentTapGesture = $ionicGesture.on('tap', onContentTap, $element, gestureOpts); + var dragRightGesture = $ionicGesture.on('dragright', onDragX, $element, gestureOpts); + var dragLeftGesture = $ionicGesture.on('dragleft', onDragX, $element, gestureOpts); + var dragUpGesture = $ionicGesture.on('dragup', onDragY, $element, gestureOpts); + var dragDownGesture = $ionicGesture.on('dragdown', onDragY, $element, gestureOpts); + var releaseGesture = $ionicGesture.on('release', onDragRelease, $element, gestureOpts); // Cleanup $scope.$on('$destroy', function() { diff --git a/js/angular/service/gesture.js b/js/angular/service/gesture.js index ecdad265d37..858d5c378f1 100644 --- a/js/angular/service/gesture.js +++ b/js/angular/service/gesture.js @@ -18,8 +18,8 @@ IonicModule * @param {element} $element The angular element to listen for the event on. * @returns {ionic.Gesture} The gesture object (use this to remove the gesture later on). */ - on: function(eventType, cb, $element) { - return window.ionic.onGesture(eventType, cb, $element[0]); + on: function(eventType, cb, $element, options) { + return window.ionic.onGesture(eventType, cb, $element[0], options); }, /** * @ngdoc method diff --git a/js/utils/events.js b/js/utils/events.js index e7b87b836c8..24ca5c31334 100644 --- a/js/utils/events.js +++ b/js/utils/events.js @@ -128,8 +128,8 @@ * happens. * @param {DOMElement} element The angular element to listen for the event on. */ - onGesture: function(type, callback, element) { - var gesture = new ionic.Gesture(element); + onGesture: function(type, callback, element, options) { + var gesture = new ionic.Gesture(element, options); gesture.on(type, callback); return gesture; }, diff --git a/js/utils/tap.js b/js/utils/tap.js index 6de7d05f6c5..a85634a36ac 100644 --- a/js/utils/tap.js +++ b/js/utils/tap.js @@ -484,7 +484,7 @@ function tapHandleFocus(ele) { // already is the active element and has focus triggerFocusIn = true; - } else if( (/^(input|textarea)$/i).test(ele.tagName) ) { + } else if( (/^(input|textarea)$/i).test(ele.tagName) || ele.isContentEditable ) { triggerFocusIn = true; ele.focus && ele.focus(); ele.value = ele.value; @@ -506,7 +506,7 @@ function tapHandleFocus(ele) { function tapFocusOutActive() { var ele = tapActiveElement(); - if(ele && (/^(input|textarea|select)$/i).test(ele.tagName) ) { + if(ele && ((/^(input|textarea|select)$/i).test(ele.tagName) || ele.isContentEditable) ) { console.log('tapFocusOutActive', ele.tagName); ele.blur(); } diff --git a/test/unit/utils/tap.unit.js b/test/unit/utils/tap.unit.js index bae9ba24c2e..d7b91961474 100644 --- a/test/unit/utils/tap.unit.js +++ b/test/unit/utils/tap.unit.js @@ -902,6 +902,18 @@ describe('Ionic Tap', function() { expect( tapTouchFocusedInput ).toEqual(null); }); + it('Should focus contenteditable div', function() { + var ele = { + tagName: 'DIV', + isContentEditable: true, + focus: function(){ this.hasFocus=true; }, + dispatchEvent: function(){} + }; + tapHandleFocus(ele); + expect( ele.hasFocus ).toEqual(true); + expect( tapTouchFocusedInput ).toEqual(null); + }); + it('Should not focus on common elements', function() { var tags = ['div', 'span', 'i', 'body', 'section', 'article', 'aside', 'li', 'p', 'header', 'button', 'ion-content']; function setFocus() { @@ -958,6 +970,17 @@ describe('Ionic Tap', function() { } }); + it('Should focus out on contenteditable elements', function() { + var ele = { + tagName: 'DIV', + isContentEditable: true, + blur: function() { this.hasBlurred=true; } + }; + tapActiveElement(ele); + tapFocusOutActive(ele); + expect( ele.hasBlurred ).toEqual(true); + }); + it('Should get containing element of label when passed a deeply nested div', function() { var label = document.createElement('label'); var div1 = document.createElement('div');