merge keyboard-fixes

This commit is contained in:
Adam Bradley
2014-05-03 22:30:21 -05:00
11 changed files with 797 additions and 173 deletions

View File

@@ -68,7 +68,6 @@
}
function activateElements() {
// console.log('ACTIVATING');
// activate all elements in the queue
for(var key in queueElements) {
if(queueElements[key]) {

View File

@@ -16,18 +16,22 @@ var SCROLL_CONTAINER_CSS = 'scroll';
ionic.keyboard = {
isOpen: false,
height: null
height: null,
landscape: false,
};
function keyboardInit() {
if( keyboardHasPlugin() ) {
window.addEventListener('native.showkeyboard', keyboardNativeShow);
window.addEventListener('native.hidekeyboard', keyboardFocusOut);
}
else {
document.body.addEventListener('focusout', keyboardFocusOut);
}
document.body.addEventListener('ionic.focusin', keyboardBrowserFocusIn);
document.body.addEventListener('focusin', keyboardBrowserFocusIn);
document.body.addEventListener('focusout', keyboardFocusOut);
document.body.addEventListener('orientationchange', keyboardOrientationChange);
document.removeEventListener('touchstart', keyboardInit);
@@ -55,10 +59,25 @@ function keyboardSetShow(e) {
clearTimeout(keyboardFocusOutTimer);
keyboardFocusInTimer = setTimeout(function(){
var keyboardHeight = keyboardGetHeight();
var keyboardHeight;
var elementBounds = keyboardActiveElement.getBoundingClientRect();
var count = 0;
keyboardShow(e.target, elementBounds.top, elementBounds.bottom, keyboardViewportHeight, keyboardHeight);
var pollKeyboardHeight = setInterval(function(){
keyboardHeight = keyboardGetHeight();
if (count > 10){
clearInterval(pollKeyboardHeight);
//waited long enough, just guess
keyboardHeight = 275;
}
if (keyboardHeight){
keyboardShow(e.target, elementBounds.top, elementBounds.bottom, keyboardViewportHeight, keyboardHeight);
clearInterval(pollKeyboardHeight);
}
count++;
}, 100);
}, 32);
}
@@ -70,15 +89,9 @@ function keyboardShow(element, elementTop, elementBottom, viewportHeight, keyboa
keyboardHeight: keyboardHeight
};
if( keyboardIsOverWebView() ) {
// keyboard sits on top of the view, but doesn't adjust the view's height
// lower the content height by subtracting the keyboard height from the view height
details.contentHeight = viewportHeight - keyboardHeight;
} else {
// view's height was shrunk down and the keyboard takes up the space the view doesn't fill
// do not add extra padding at the bottom of the scroll view, native already did that
details.contentHeight = viewportHeight;
}
details.hasPlugin = keyboardHasPlugin();
details.contentHeight = viewportHeight - keyboardHeight;
console.debug('keyboardShow', keyboardHeight, details.contentHeight);
@@ -149,32 +162,70 @@ function keyboardPreventDefault(e) {
}
function keyboardOrientationChange() {
keyboardViewportHeight = window.innerHeight;
setTimeout(function(){
keyboardViewportHeight = window.innerHeight;
}, 999);
var updatedViewportHeight = window.innerHeight;
//too slow, have to wait for updated height
if (updatedViewportHeight === keyboardViewportHeight){
var count = 0;
var pollViewportHeight = setInterval(function(){
//give up
if (count > 10){
clearInterval(pollViewportHeight);
}
updatedViewportHeight = window.innerHeight;
if (updatedViewportHeight !== keyboardViewportHeight){
if (updatedViewportHeight < keyboardViewportHeight){
ionic.keyboard.landscape = true;
}
else {
ionic.keyboard.landscape = false;
}
keyboardViewportHeight = updatedViewportHeight;
clearInterval(pollViewportHeight);
}
count++;
}, 50);
}
else {
keyboardViewportHeight = updatedViewportHeight;
}
}
function keyboardGetHeight() {
// check if we are already have a keyboard height from the plugin
if (ionic.keyboard.height ) {
if ( ionic.keyboard.height ) {
return ionic.keyboard.height;
}
if ( ionic.Platform.isAndroid() ){
//should be using the plugin, no way to know how big the keyboard is, so guess
if ( ionic.Platform.isFullScreen ){
return 275;
}
//otherwise, wait for the screen to resize
if ( window.innerHeight < keyboardViewportHeight ){
return keyboardViewportHeight - window.innerHeight;
}
else {
return 0;
}
}
// fallback for when its the webview without the plugin
// or for just the standard web browser
if( ionic.Platform.isIOS() ) {
if( ionic.Platform.isWebView() ) {
return 260;
if ( ionic.keyboard.landscape ){
return 206;
}
return 216;
} else if( ionic.Platform.isAndroid() ) {
if( ionic.Platform.isWebView() ) {
return 220;
}
if( ionic.Platform.version() <= 4.3) {
return 230;
if (!ionic.Platform.isWebView()){
return 216;
}
return 260;
}
// safe guess
@@ -191,11 +242,6 @@ function keyboardIsWithinScroll(ele) {
return false;
}
function keyboardIsOverWebView() {
return ( ionic.Platform.isIOS() ) ||
( ionic.Platform.isAndroid() && !ionic.Platform.isWebView() );
}
function keyboardHasPlugin() {
return !!(window.cordova && cordova.plugins && cordova.plugins.Keyboard);
}

View File

@@ -90,6 +90,8 @@
if(this.isWebView()) {
this.platforms.push('webview');
this.platforms.push('cordova');
} else {
this.platforms.push('browser');
}
if(this.isIPad()) this.platforms.push('ipad');
@@ -129,7 +131,10 @@
* @returns {boolean} Whether we are running on iPad.
*/
isIPad: function() {
return this.ua.toLowerCase().indexOf('ipad') >= 0;
if( /iPad/i.test(window.navigator.platform) ) {
return true;
}
return /iPad/i.test(this.ua);
},
/**
* @ngdoc method
@@ -170,7 +175,7 @@
} else if(this.ua.indexOf('iPhone') > -1 || this.ua.indexOf('iPad') > -1 || this.ua.indexOf('iPod') > -1) {
platformName = 'ios';
} else {
platformName = '';
platformName = window.navigator.platform && window.navigator.platform.toLowerCase().split(' ')[0] || '';
}
},

View File

@@ -2,6 +2,14 @@
var viewportTag;
var viewportProperties = {};
ionic.viewport = {
orientation: function() {
// 0 = Portrait
// 90 = Landscape
// not using window.orientation because each device has a different implementation
return (window.innerWidth > window.innerHeight ? 90 : 0);
}
};
function viewportLoadTag() {
var x;
@@ -17,41 +25,110 @@ function viewportLoadTag() {
var props = viewportTag.content.toLowerCase().replace(/\s+/g, '').split(',');
var keyValue;
for(x=0; x<props.length; x++) {
keyValue = props[x].split('=');
if(keyValue.length == 2) viewportProperties[ keyValue[0] ] = keyValue[1];
if(props[x] != '') {
keyValue = props[x].split('=');
viewportProperties[ keyValue[0] ] = (keyValue.length > 1 ? keyValue[1] : '_');
}
}
viewportInitWebView();
viewportUpdate();
}
}
function viewportInitWebView() {
var hasViewportChange = false;
function viewportUpdate() {
// unit tests in viewport.unit.js
if( ionic.Platform.isWebView() ) {
if( viewportProperties.height != 'device-height' ) {
viewportProperties.height = 'device-height';
hasViewportChange = true;
var initWidth = viewportProperties.width;
var initHeight = viewportProperties.height;
var p = ionic.Platform;
var version = p.version();
var DEVICE_WIDTH = 'device-width';
var DEVICE_HEIGHT = 'device-height';
var orientation = ionic.viewport.orientation();
// Most times we're removing the height and adding the width
// So this is the default to start with, then modify per platform/version/oreintation
delete viewportProperties.height;
viewportProperties.width = DEVICE_WIDTH;
if( p.isIPad() ) {
// iPad
if( version > 7 ) {
// iPad >= 7.1
// https://issues.apache.org/jira/browse/CB-4323
delete viewportProperties.width;
} else {
// iPad <= 7.0
if( p.isWebView() ) {
// iPad <= 7.0 WebView
if( orientation == 90 ) {
// iPad <= 7.0 WebView Landscape
viewportProperties.height = '0';
} else if(version == 7) {
// iPad <= 7.0 WebView Portait
viewportProperties.height = DEVICE_HEIGHT;
}
} else {
// iPad <= 6.1 Browser
if(version < 7) {
viewportProperties.height = '0';
}
}
}
} else if( viewportProperties.height ) {
delete viewportProperties.height;
hasViewportChange = true;
} else if( p.isIOS() ) {
// iPhone
if( p.isWebView() ) {
// iPhone WebView
if(version > 7) {
// iPhone >= 7.1 WebView
delete viewportProperties.width;
} else if(version < 7) {
// iPhone <= 6.1 WebView
// if height was set it needs to get removed with this hack for <= 6.1
if( initHeight ) viewportProperties.height = '0';
}
} else {
// iPhone Browser
if (version < 7) {
// iPhone <= 6.1 Browser
// if height was set it needs to get removed with this hack for <= 6.1
if( initHeight ) viewportProperties.height = '0';
}
}
}
// only update the viewport tag if there was a change
if(initWidth !== viewportProperties.width || initHeight !== viewportProperties.height) {
viewportTagUpdate();
}
if(hasViewportChange) viewportUpdate();
}
function viewportUpdate(updates) {
if(!viewportTag) return;
ionic.Utils.extend(viewportProperties, updates);
function viewportTagUpdate() {
var key, props = [];
for(key in viewportProperties) {
if(viewportProperties[key]) props.push(key + '=' + viewportProperties[key]);
if( viewportProperties[key] ) {
props.push(key + (viewportProperties[key] == '_' ? '' : '=' + viewportProperties[key]) );
}
}
viewportTag.content = props.join(',');
viewportTag.content = props.join(', ');
}
ionic.DomUtil.ready(function() {
viewportLoadTag();
window.addEventListener("orientationchange", function(){
setTimeout(viewportUpdate, 1000);
}, false);
});

View File

@@ -622,15 +622,26 @@ ionic.views.Scroll = ionic.views.View.inherit({
if( !self.isScrolledIntoView ) {
// shrink scrollview so we can actually scroll if the input is hidden
// if it isn't shrink so we can scroll to inputs under the keyboard
container.style.height = (container.clientHeight - e.detail.keyboardHeight) + "px";
container.style.overflow = "visible";
if (ionic.Platform.isIOS() || ionic.Platform.isFullScreen){
container.style.height = (container.clientHeight - e.detail.keyboardHeight) + "px";
container.style.overflow = "visible";
//update scroll view
self.resize();
}
self.isScrolledIntoView = true;
//update scroll view
self.resize();
}
//If the element is positioned under the keyboard...
if( e.detail.isElementUnderKeyboard ) {
var delay;
// Wait on android for scroll view to resize
if ( !ionic.Platform.isFullScreen && e.detail.hasPlugin ) {
delay = 350;
}
else {
delay = 80;
}
//Put element in middle of visible screen
//Wait for resize() to reset scroll position
ionic.scroll.isScrolling = true;
@@ -642,9 +653,7 @@ ionic.views.Scroll = ionic.views.View.inherit({
ionic.tap.cloneFocusedInput(container, self);
self.scrollBy(0, scrollTop, true);
self.onScroll();
},
(ionic.Platform.isIOS() ? 80 : 350)
);
}, delay);
}
//Only the first scrollView parent of the element that broadcasted this event

View File

@@ -46,8 +46,15 @@
}
}
@media (orientation:landscape) {
.platform-ios7.platform-browser.platform-ipad {
position: fixed; // required for iPad 7 Safari
}
}
.platform-android2:not(.enable-transitions) * {
// disable transitions on Android 2
-webkit-transition: none !important;
transition: none !important;
}

View File

@@ -261,6 +261,42 @@
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
<label class="item item-input">
<textarea placeholder="Description"></textarea>
</label>
</div>
<div class="padding">

View File

@@ -5,6 +5,9 @@ describe('Ionic Platform Service', function() {
beforeEach(inject(function($window, $ionicPlatform, $rootScope) {
window = $window;
window.navigator = {
platform: ''
};
ionic.Platform.ua = '';
ionicPlatform = $ionicPlatform;
rootScope = $rootScope;
@@ -84,6 +87,39 @@ describe('Ionic Platform Service', function() {
expect(ionic.Platform.version()).toEqual(7.0);
});
it('should not be iPad from none iPad user agent', function() {
ionic.Platform.ua = 'Mozilla/5.0 (iPhone; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53';
ionic.Platform.setPlatform(undefined);
ionic.Platform.setVersion(undefined);
expect(ionic.Platform.isIPad()).toEqual(false);
});
it('should be iPad from user agent', function() {
ionic.Platform.ua = 'Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53';
ionic.Platform.setPlatform(undefined);
ionic.Platform.setVersion(undefined);
expect(ionic.Platform.isIPad()).toEqual(true);
});
it('should be iPad from iPad in window.navigator.platform and webview, but iPhone in user agent', function() {
window.cordova = {};
ionic.Platform.ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25';
window.navigator = {
platform: 'iPad Simulator'
};
ionic.Platform.setPlatform(undefined);
ionic.Platform.setVersion(undefined);
expect(ionic.Platform.isIPad()).toEqual(true);
});
it('should not be iPad from no in window.navigator.platform, and iPhone in user agent', function() {
ionic.Platform.ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25';
window.navigator = {};
ionic.Platform.setPlatform(undefined);
ionic.Platform.setVersion(undefined);
expect(ionic.Platform.isIPad()).toEqual(false);
});
it('is iOS', function() {
ionic.Platform.setPlatform('iOS');
expect(ionic.Platform.isIOS()).toEqual(true);
@@ -104,6 +140,7 @@ describe('Ionic Platform Service', function() {
});
it('is WebView', function() {
window.cordova = undefined;
expect(ionic.Platform.isWebView()).toEqual(false);
window.cordova = {};
expect(ionic.Platform.isWebView()).toEqual(true);
@@ -155,7 +192,7 @@ describe('Ionic Platform Service', function() {
expect(ionic.Platform.platforms[1]).toEqual('cordova');
});
it('should not set any platform', function() {
it('should not set if its not a webview but only a browser', function() {
window.cordova = null;
window.PhoneGap = null;
window.phonegap = null;
@@ -164,7 +201,7 @@ describe('Ionic Platform Service', function() {
ionic.Platform._checkPlatforms()
expect(ionic.Platform.platforms.length).toEqual(0);
expect(ionic.Platform.platforms[0]).toEqual('browser');
});
it('sets grade a from iOS7', function() {

View File

@@ -41,6 +41,31 @@ Tested On
- Android 4.2 Cordova
iOS 7.1 Cordova with AND without viewport height DOES resize, DOES NOT fire resize event
iOS 7.1 Safari with AND without viewport height DOES NOT resize
iOS 7.0 Cordova with viewport height DOES resize, DOES fire resize event
iOS 7.0 Cordova without viewport height DOES resize, DOES NOT fire resize event
iOS 7.0 Safari with AND without viewport height DOES NOT resize
iOS 6.1 Cordova with AND without viewport height DOES NOT resize
iOS 6.1 Safari without viewport height DOES NOT resize
NOTES:
-iOS 7.1 Safari with viewport height screws up ionic layout
-iOS 7.0 Safari with viewport height, the scroll view does not resize properly on keyboardhide
-iOS 7.0 Cordova without viewport height, scroll view does not resize properly switching inputs at bottom of page
-iOS 6.1 Cordova and Safari don't work well with viewport height
RECOMMENDATIONS:
-iOS 7.1 Cordova no viewport height, keyboard is not over webview
-iOS 7.1 Safari no viewport height, keyboard is over webview
-iOS 7.0 Cordova yes viewport height, keyboard is not over webview
-iOS 7.0 Safari no viewport height, keyboard is over webview
-iOS 6.1 Cordova no viewport height, keyboard is over webview
-iOS 6.1 Safari no viewport height, keyboard is over webview
Notes:
---------------------------------
@@ -65,6 +90,9 @@ describe('Ionic Keyboard', function() {
ionic.Platform.setPlatform('');
ionic.Platform.setVersion('');
ionic.keyboard.isOpen = false;
ionic.keyboard.height = null;
ionic.Platform.isFullScreen = false;
ionic.keyboard.landscape = false;
}));
afterEach(function(){
@@ -82,45 +110,6 @@ describe('Ionic Keyboard', function() {
expect( details.keyboardHeight ).toEqual(200);
});
it('Should keyboardIsOverWebView()=false if Android and not isWebView', function(){
// Android browser places the keyboard on top of the content and doesn't resize the window
ionic.Platform.setPlatform('Android');
expect( ionic.Platform.isAndroid() ).toEqual(true);
expect( ionic.Platform.isWebView() ).toEqual(false);
expect( ionic.Platform.isIOS() ).toEqual(false);
expect( keyboardIsOverWebView() ).toEqual(true);
});
it('Should keyboardIsOverWebView()=false if Android and isWebView', function(){
// Android webview gets shrunk by cordova and the keyboard fills the gap
ionic.Platform.setPlatform('Android');
window.cordova = {};
expect( ionic.Platform.isAndroid() ).toEqual(true);
expect( ionic.Platform.isWebView() ).toEqual(true);
expect( keyboardIsOverWebView() ).toEqual(false);
});
it('Should keyboardIsOverWebView()=true if iOS 7.0 or greater', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('7.0');
expect( ionic.Platform.isAndroid() ).toEqual(false);
expect( ionic.Platform.isIOS() ).toEqual(true);
expect( keyboardIsOverWebView() ).toEqual(true);
});
it('Should keyboardIsOverWebView()=true if less than iOS 7.0', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('6.0');
expect( ionic.Platform.isAndroid() ).toEqual(false);
expect( ionic.Platform.isIOS() ).toEqual(true);
expect( keyboardIsOverWebView() ).toEqual(true);
});
it('Should keyboardHasPlugin', function() {
expect( keyboardHasPlugin() ).toEqual(false);
@@ -134,10 +123,67 @@ describe('Ionic Keyboard', function() {
expect( keyboardHasPlugin() ).toEqual(true);
});
it('keyboardGetHeight() should = DEFAULT_KEYBOARD_HEIGHT if no plugin or resized view', function(){
it('keyboardGetHeight() should use the keyboard plugin if it is available', function(){
ionic.keyboard.height = 216;
expect( keyboardGetHeight() ).toEqual(216);
});
it('keyboardGetHeight() should = 275 if Cordova Android and is fullscreen', function(){
ionic.Platform.setPlatform('android');
window.cordova = {};
ionic.Platform.isFullScreen = true;
expect( keyboardGetHeight() ).toEqual(275);
});
it('keyboardGetHeight() should = (keyboardViewportHeight - window.innerHeight) if Android and not fullscreen', function(){
ionic.Platform.setPlatform('android');
expect( ionic.Platform.isFullScreen ).toEqual(false);
keyboardViewportHeight = 480;
window.innerHeight = 280
expect( keyboardGetHeight() ).toEqual(200);
});
it('keyboardGetHeight() should = 0 if keyboardViewportHeight = window.innerHeight and Android and not fullscreen', function(){
ionic.Platform.setPlatform('android');
expect( ionic.Platform.isFullScreen ).toEqual(false);
keyboardViewportHeight = 480;
window.innerHeight = 480;
expect( keyboardGetHeight() ).toEqual(0);
});
it('keyboardGetHeight() should = 206 if iOS and in landscape orientation', function(){
ionic.Platform.setPlatform('iOS');
ionic.keyboard.landscape = true;
expect( keyboardGetHeight() ).toEqual(206);
})
it('keyboardGetHeight() should = 216 if iOS Safari', function(){
ionic.Platform.setPlatform('iOS');
expect( ionic.Platform.isWebView() ).toEqual(false);
expect( keyboardGetHeight() ).toEqual(216);
})
it('keyboardGetHeight() should = 260 if iOS Cordova', function(){
ionic.Platform.setPlatform('iOS');
window.cordova = {};
expect( ionic.Platform.isWebView() ).toEqual(true);
expect( keyboardGetHeight() ).toEqual(260);
})
it('keyboardGetHeight() should = 275 if not Android or iOS', function(){
ionic.Platform.setPlatform('WP8');
expect( keyboardGetHeight() ).toEqual(275);
})
it('keyboardUpdateViewportHeight() should update when window.innerHeight > keyboardViewportHeight', function(){
window.innerHeight = 460;
keyboardViewportHeight = 320;
@@ -171,34 +217,10 @@ describe('Ionic Keyboard', function() {
var elementBottom = 200;
var keyboardHeight = 200;
var deviceHeight = 500;
window.innerHeight = 500;
var details = keyboardShow(element, elementTop, elementBottom, deviceHeight, keyboardHeight);
expect( details.isElementUnderKeyboard ).toEqual(false);
});
it('Should not subtract the keyboard height from the contentHeight if not keyboardIsOverWebView()', function(){
var element = document.createElement('textarea');
var elementTop = 300;
var elementBottom = 400;
var keyboardHeight = 200;
var deviceHeight = 260;
var details = keyboardShow(element, elementTop, elementBottom, deviceHeight, keyboardHeight);
expect( details.contentHeight ).toEqual(260);
});
it('Should subtract the keyboard height from the contentHeight if keyboardIsOverWebView()', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('7.1');
var element = document.createElement('textarea');
var elementTop = 300;
var elementBottom = 400;
var keyboardHeight = 200;
var deviceHeight = 568;
var details = keyboardShow(element, elementTop, elementBottom, deviceHeight, keyboardHeight);
expect( details.contentHeight ).toEqual(368);
});
});

View File

@@ -12,10 +12,12 @@
iOS 6.1 Safari without viewport height DOES NOT resize
NOTES:
-iOS 7.1 Safari with viewport height screws up ionic layout
-iOS 7.0 Safari with viewport height, the scroll view does not resize properly on keyboardhide
-iOS 7.0 Cordova without viewport height, scroll view does not resize properly switching inputs at bottom of page
-iOS 6.1 Cordova and Safari don't work well with viewport height
- iOS 7.1 Safari with viewport height screws up ionic layout
- iOS 7.0 Safari with viewport height, the scroll view does not resize properly on keyboardhide
- iOS 7.0 Cordova without viewport height, scroll view does not resize properly switching inputs at bottom of page
- iOS 6.1 Cordova and Safari don't work well with viewport height
- If its not a webview, and a viewport height was set, just removing
the height value doesn't trigger the change, but setting height=0 does the trick
RECOMMENDATIONS:
-iOS 7.1 Cordova no viewport height, keyboard is not over webview
@@ -27,6 +29,9 @@
-iOS 6.1 Cordova no viewport height, keyboard is over webview
-iOS 6.1 Safari no viewport height, keyboard is over webview
http://cordova.apache.org/docs/en/3.3.0/guide_platforms_ios_upgrading.md.html#Upgrading%20iOS
https://issues.apache.org/jira/browse/CB-4323
*/
@@ -40,6 +45,9 @@ describe('Ionic Viewport', function() {
_activeElement = null; // the element which has focus
window.cordova = undefined;
window.device = undefined;
window.navigator = {};
window.innerWidth = 1;
window.innerHeight = 2;
ionic.Platform.ua = '';
ionic.Platform.platforms = null;
ionic.Platform.setPlatform('');
@@ -57,69 +65,446 @@ describe('Ionic Viewport', function() {
if(vportTag) vportTag.parentNode.removeChild(vportTag);
});
it('Should have height=device-height for iOS 7+ on webview', function(){
// iOS 7.1, iPad, WebView
it('Should remove width and height from viewport for iOS >= 7.1, iPad, WebView', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('7.1');
window.cordova = {};
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no');
});
// iOS 7.1, iPad, Browser
it('Should remove width and height from viewport for iOS >= 7.1, iPad, Browser', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('7.1');
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no');
});
// iOS 7.0, iPad, WebView
it('Should keep width and height in viewport for iOS 7.0, iPad, WebView, Portrait', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('7.0');
window.cordova = {};
window.innerWidth = 1;
window.innerHeight = 2;
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=device-height');
});
it('Should add width and height to viewport for iOS 7.0, iPad, WebView, Portrait', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('7.0');
window.cordova = {};
window.innerWidth = 1;
window.innerHeight = 2;
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=device-height');
});
it('Should add width and height=0 to viewport for iOS 7.0, iPad, WebView, Landscape', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('7.0');
window.cordova = {};
window.innerWidth = 2;
window.innerHeight = 1;
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=0');
});
it('Should keep width reset height to 0 in viewport for iOS 7.0, iPad, WebView, Landscape', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('7.0');
window.cordova = {};
window.innerWidth = 2;
window.innerHeight = 1;
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=0');
});
// iOS 7.0, iPad, Browser
it('Should keep width, but remove height from viewport for iOS 7.0, iPad, Browser', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('7.0');
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should add width, but not add height to viewport for iOS 7.0, iPad, Browser', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('7.0');
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
// iOS 6.1, iPad, WebView
it('Should keep width, but remove height from viewport for iOS 6.1, iPad, WebView, Portrait', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('6.1');
window.cordova = {};
window.innerWidth = 1;
window.innerHeight = 2;
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should add width, but not add height to viewport for iOS 6.1, iPad, WebView, Portrait', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('6.1');
window.cordova = {};
window.innerWidth = 1;
window.innerHeight = 2;
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should keep width, but replace height with 0 in viewport for iOS 6.1, iPad, WebView, Landscape', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('6.1');
window.cordova = {};
window.innerWidth = 2;
window.innerHeight = 1;
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=0');
});
it('Should add width and add height=0 to viewport for iOS 6.1, iPad, WebView, Landscape', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('6.1');
window.cordova = {};
window.innerWidth = 2;
window.innerHeight = 1;
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=0');
});
// iOS 6.1, iPad, Browser
it('Should keep width, and set height=0 for viewport for iOS 6.1, iPad, Browser, Portrait', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('6.1');
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=0');
});
it('Should add width, and add height=0 to viewport for iOS 6.1, iPad, Browser', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.ua = 'ipad';
ionic.Platform.setVersion('6.1');
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=0');
});
// iOS 7.1, iPhone, WebView
it('Should remove width and height from viewport for iOS 7.1, iPhone, WebView', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.setVersion('7.1');
window.cordova = {};
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no');
});
it('Should do nothing width and height already in viewport for iOS 7.1, iPhone, WebView', function(){
ionic.Platform.setPlatform('ios');
ionic.Platform.setVersion('7.1');
window.cordova = {};
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no');
});
// iOS 7.1, iPhone, Browser
it('Should keep width, but remove height from viewport for iOS >= 7.1, iPhone, Browser', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('7.1');
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should add width, but not height to viewport for iOS >= 7.1, iPhone, Browser', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('7.1');
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
// iOS 7.0, iPhone, WebView
it('Should keep width, but not height in viewport for iOS 7.0, iPhone, WebView', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('7.0');
expect( ionic.Platform.isAndroid() ).toEqual(false);
expect( ionic.Platform.isIOS() ).toEqual(true);
//so isWebView() is true
window.cordova = {};
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( viewportProperties.height ).toEqual('device-height');
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should not have height=device-height for iOS 7+ on browser', function(){
it('Should add width, but not height to viewport for iOS 7.0, iPhone, WebView', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('7.0');
expect( ionic.Platform.isAndroid() ).toEqual(false);
expect( ionic.Platform.isIOS() ).toEqual(true);
viewportLoadTag();
expect( viewportProperties.height ).not.toEqual('device-height');
});
it('Should have height=device-height for Android on webview', function(){
ionic.Platform.setPlatform('Android');
expect( ionic.Platform.isAndroid() ).toEqual(true);
expect( ionic.Platform.isIOS() ).toEqual(false);
//so isWebView() is true
window.cordova = {};
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( viewportProperties.height ).toEqual('device-height');
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should not have height=device-height for Android on browser', function(){
ionic.Platform.setPlatform('Android');
expect( ionic.Platform.isAndroid() ).toEqual(true);
expect( ionic.Platform.isIOS() ).toEqual(false);
// iOS 7.0, iPhone, Browser
it('Should keep width but remove height from viewport for iOS 7.0, iPhone, Browser', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('7.0');
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( viewportProperties.height ).not.toEqual('device-height');
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should not re-add height=device-height for webview if its already there', function(){
ionic.Platform.setPlatform('ios');
it('Should add width but not height to viewport for iOS 7.0, iPhone, Browser', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('7.0');
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
// iOS 6.1, iPhone, WebView
it('Should add width but not height to viewport for iOS 6.1, iPhone, WebView', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('6.1');
window.cordova = {};
var originalViewport = ' initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width, height=device-height ';
vportTag.setAttribute('content', originalViewport);
vportTag.content = 'user-scalable=no';
viewportLoadTag();
// if it was changed the spaces would have been removed
expect( vportTag.content ).toEqual(originalViewport);
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should not update the viewport if its not a webview and height=device-height wasnt already in', function(){
ionic.Platform.setPlatform('ios');
var originalViewport = ' initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width ';
vportTag.setAttribute('content', originalViewport);
it('Should keep width but replace height=device-height with height=0 in viewport for iOS 6.1, iPhone, WebView', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('6.1');
window.cordova = {};
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
// if it was changed the spaces would have been removed
expect( vportTag.content ).toEqual(originalViewport);
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=0');
});
// iOS 6.1, iPhone, Browser
it('Should add width but not height to viewport for iOS 6.1, iPhone, Browser', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('6.1');
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should keep width but remove height from viewport for iOS 6.1, iPhone, Browser', function(){
ionic.Platform.setPlatform('iOS');
ionic.Platform.setVersion('6.1');
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width, height=0');
});
// Android 4.4, WebView
it('Should add width, but not height to viewport for Android 4.4, WebView', function(){
ionic.Platform.setPlatform('android');
ionic.Platform.setVersion('4.4');
window.cordova = {};
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should keep width, but remove height from viewport for Android 4.4, WebView', function(){
ionic.Platform.setPlatform('android');
ionic.Platform.setVersion('4.4');
window.cordova = {};
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
// Android 4.4, Browser
it('Should add width, but not height to viewport for Android 4.4, Browser', function(){
ionic.Platform.setPlatform('android');
ionic.Platform.setVersion('4.4');
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should keep width, but remove height from viewport for Android 4.4, Browser', function(){
ionic.Platform.setPlatform('android');
ionic.Platform.setVersion('4.4');
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
// Standard Browser
it('Should add width, but not height to viewport for Standard Browser', function(){
ionic.Platform.ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36';
vportTag.content = 'user-scalable=no';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should keep width, but remove height from viewport for Standard Browser', function(){
ionic.Platform.setPlatform('android');
ionic.Platform.setVersion('4.4');
vportTag.content = 'user-scalable=no, width=device-width, height=device-height';
viewportLoadTag();
expect( vportTag.content ).toEqual('user-scalable=no, width=device-width');
});
it('Should set viewport properties that have a key but without a value', function(){
vportTag.content = ' keyonly, , ,, WIDTH=DeViCe-wIDTH , minimal-ui ';
viewportLoadTag();
expect( viewportProperties['keyonly'] ).toEqual('_');
expect( viewportProperties['width'] ).toEqual('device-width');
expect( viewportProperties['minimal-ui'] ).toEqual('_');
viewportTagUpdate();
expect( vportTag.content ).toEqual('keyonly, width=device-width, minimal-ui');
});
it('Should get portrait (0) orientation', function(){
window.innerWidth = 768;
window.innerHeight = 1024;
expect( ionic.viewport.orientation() ).toEqual(0);
window.innerWidth = 500;
window.innerHeight = 500;
expect( ionic.viewport.orientation() ).toEqual(0);
});
it('Should get landscape (90) orientation', function(){
window.innerWidth = 1024;
window.innerHeight = 768;
expect( ionic.viewport.orientation() ).toEqual(90);
});
});

View File

@@ -37,19 +37,20 @@ describe('Scroll View', function() {
it('Should resize when the keyboard is showing', function() {
var element = document.createElement('textarea');
ionic.Platform.setPlatform('ios');
s.appendChild(element);
document.body.appendChild(sc);
var sv = new ionic.views.Scroll({
el: sc,
});
var scHeight = 500;
sc.style.height = scHeight + "px";
sc.style.display = "block";
var keyboardHeight = 200;
details = {
details = {
contentHeight: 260,
elementBottom: 400,
elementTop: 300,