Skip to content

Commit

Permalink
fix(viewport): Auto update viewport tag
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Bradley committed May 2, 2014
1 parent 2094d83 commit 5f8e904
Show file tree
Hide file tree
Showing 7 changed files with 576 additions and 60 deletions.
9 changes: 7 additions & 2 deletions js/utils/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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] || '';
}
},

Expand Down
102 changes: 86 additions & 16 deletions js/utils/viewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -20,43 +28,105 @@ function viewportLoadTag() {
keyValue = props[x].split('=');
if(keyValue.length == 2) viewportProperties[ keyValue[0] ] = keyValue[1];
}
viewportInitWebView();
viewportUpdate();
}
}

function viewportInitWebView() {
function viewportUpdate() {
// unit tests in viewport.unit.js

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( p.isIOS() ) {
// iPhone

if( p.isWebView() ) {
// iPhone WebView

if( ionic.Platform.isWebView() ) {
viewportProperties.height = 'device-height';
if(version > 7) {
// iPhone >= 7.1 WebView
delete viewportProperties.width;

} else if( ionic.Platform.isIOS() && viewportProperties.height ) {
// if its not a webview, and a viewport height was set, just removing
// the height value doesn't trigger the change, but setting to 0 does the trick
viewportProperties.height = '0';
} 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';
}
}

} else if( viewportProperties.height ) {
delete viewportProperties.height;
}

// only update the viewport tag if there was a change
if(initHeight !== viewportProperties.height) viewportUpdate();
console.debug(viewportTag.content)
if(initWidth !== viewportProperties.width || initHeight !== viewportProperties.height) {
viewportTagUpdate();
}
}

function viewportUpdate(updates) {
if(!viewportTag) return;

function viewportTagUpdate(updates) {
ionic.Utils.extend(viewportProperties, updates);

var key, props = [];
for(key in viewportProperties) {
if(viewportProperties[key]) props.push(key + '=' + viewportProperties[key]);
if( viewportProperties[key] ) props.push(key + '=' + viewportProperties[key]);
}

viewportTag.content = props.join(', ');
}

ionic.DomUtil.ready(function() {
viewportLoadTag();

window.addEventListener("orientationchange", function(){
setTimeout(viewportUpdate, 1000);
}, false);
});
8 changes: 7 additions & 1 deletion scss/_platform.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
top: $bar-height + $ios7-statusbar-height;
}

.has-header,
.has-header,
.bar-subheader {
top: $bar-height + $ios7-statusbar-height;
}
Expand All @@ -45,3 +45,9 @@
margin-bottom: 20px;
}
}

@media (orientation:landscape) {
.platform-ios7.platform-browser.platform-ipad {
position: fixed; // required for iPad 7 Safari
}
}
36 changes: 36 additions & 0 deletions test/html/viewState.html
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,42 @@ <h2>{{ auto.year }} {{ auto.make }} {{ auto.model }}</h2>
<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">
Expand Down
41 changes: 39 additions & 2 deletions test/unit/angular/service/platform.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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() {
Expand Down
Loading

0 comments on commit 5f8e904

Please sign in to comment.