From 4636cb0ee4541004d9b0d2895f2a11a7a112d73c Mon Sep 17 00:00:00 2001 From: Tim Lancina Date: Mon, 2 Mar 2015 15:40:48 -0600 Subject: [PATCH] fix(keyboard): shrink scrollView on date and select focus on iOS --- js/utils/keyboard.js | 3 +- js/utils/tap.js | 18 +++++++---- test/unit/utils/tap.unit.js | 59 +++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/js/utils/keyboard.js b/js/utils/keyboard.js index 8662571f1e0..5d1f2f53e2c 100644 --- a/js/utils/keyboard.js +++ b/js/utils/keyboard.js @@ -143,8 +143,9 @@ function keyboardNativeShow(e) { } function keyboardBrowserFocusIn(e) { - if( !e.target || e.target.readOnly || !ionic.tap.isTextInput(e.target) || ionic.tap.isDateInput(e.target) || !keyboardIsWithinScroll(e.target) ) return; + if( !e.target || e.target.readOnly || !ionic.tap.isKeyboardElement(e.target) || !keyboardIsWithinScroll(e.target) ) return; + console.log("keyboardBrowserFocusIn"); document.addEventListener('keydown', keyboardOnKeyDown, false); document.body.scrollTop = 0; diff --git a/js/utils/tap.js b/js/utils/tap.js index 67f891473bf..c38b6a4204f 100644 --- a/js/utils/tap.js +++ b/js/utils/tap.js @@ -162,7 +162,7 @@ ionic.tap = { return !!ele && (ele.tagName == 'TEXTAREA' || ele.contentEditable === 'true' || - (ele.tagName == 'INPUT' && !(/^(radio|checkbox|range|file|submit|reset)$/i).test(ele.type))); + (ele.tagName == 'INPUT' && !(/^(radio|checkbox|range|file|submit|reset|color|image|button)$/i).test(ele.type))); }, isDateInput: function(ele) { @@ -170,6 +170,14 @@ ionic.tap = { (ele.tagName == 'INPUT' && (/^(date|time|datetime-local|month|week)$/i).test(ele.type)); }, + isKeyboardElement: function(ele) { + if ( !ionic.Platform.isIOS() ) { + return ionic.tap.isTextInput(ele) && !ionic.tap.isDateInput(ele); + } else { + return ionic.tap.isTextInput(ele) || ( !!ele && ele.tagName == "SELECT"); + } + }, + isLabelWithTextInput: function(ele) { var container = tapContainingElement(ele, false); @@ -181,7 +189,7 @@ ionic.tap = { return ionic.tap.isTextInput(ele) || ionic.tap.isLabelWithTextInput(ele); }, - cloneFocusedInput: function(container, scrollIntance) { + cloneFocusedInput: function(container) { if (ionic.tap.hasCheckedClone) return; ionic.tap.hasCheckedClone = true; @@ -189,7 +197,7 @@ ionic.tap = { var focusInput = container.querySelector(':focus'); if (ionic.tap.isTextInput(focusInput)) { var clonedInput = focusInput.cloneNode(true); - + clonedInput.value = focusInput.value; clonedInput.classList.add('cloned-text-input'); clonedInput.readOnly = true; @@ -207,7 +215,7 @@ ionic.tap = { hasCheckedClone: false, - removeClonedInputs: function(container, scrollIntance) { + removeClonedInputs: function(container) { ionic.tap.hasCheckedClone = false; ionic.requestAnimationFrame(function() { @@ -509,7 +517,7 @@ function tapFocusOutActive() { function tapFocusIn(e) { // Because a text input doesn't preventDefault (so the caret still works) there's a chance - // that it's mousedown event 300ms later will change the focus to another element after + // that its mousedown event 300ms later will change the focus to another element after // the keyboard shows up. if (tapEnabledTouchEvents && diff --git a/test/unit/utils/tap.unit.js b/test/unit/utils/tap.unit.js index 716cbaad4ac..f522b889f08 100644 --- a/test/unit/utils/tap.unit.js +++ b/test/unit/utils/tap.unit.js @@ -1215,6 +1215,15 @@ describe('Ionic Tap', function() { ele.type = 'checkbox'; expect( ionic.tap.isTextInput(ele) ).toEqual(false); + ele.type = 'color'; + expect( ionic.tap.isTextInput(ele) ).toEqual(false); + + ele.type = 'button'; + expect( ionic.tap.isTextInput(ele) ).toEqual(false); + + ele.type = 'image'; + expect( ionic.tap.isTextInput(ele) ).toEqual(false); + ele = document.createElement('select'); expect( ionic.tap.isTextInput(ele) ).toEqual(false); @@ -1255,7 +1264,57 @@ describe('Ionic Tap', function() { ele.type = 'text'; expect( ionic.tap.isDateInput(ele) ).toEqual(false); + }); + + it('Should isKeyboardElement on date and select on iOS', function() { + expect( ionic.tap.isKeyboardElement(null) ).toEqual(false); + + ionic.Platform.setPlatform('ios'); + + var ele = document.createElement('input'); + ele.type = 'date'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true); + + ele.type = 'datetime-local'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true); + + ele.type = 'month'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true); + + ele.type = 'week'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true); + + ele.type = 'time'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true); + + ele = document.createElement('select'); + expect ( ionic.tap.isKeyboardElement(ele)).toEqual(true); + + }); + + it('Should not isKeyboardElement on date and select on Android', function() { + expect( ionic.tap.isKeyboardElement(null) ).toEqual(false); + + ionic.Platform.setPlatform('android'); + + var ele = document.createElement('input'); + ele.type = 'date'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false); + + ele.type = 'datetime-local'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false); + + ele.type = 'month'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false); + ele.type = 'week'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false); + + ele.type = 'time'; + expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false); + + ele = document.createElement('select'); + expect ( ionic.tap.isKeyboardElement(ele)).toEqual(false); }); it('Should isLabelWithTextInput', function() {