Skip to content

Commit 5f8e904

Browse files
author
Adam Bradley
committed
fix(viewport): Auto update viewport tag
1 parent 2094d83 commit 5f8e904

File tree

7 files changed

+576
-60
lines changed

7 files changed

+576
-60
lines changed

Diff for: js/utils/platform.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@
9090
if(this.isWebView()) {
9191
this.platforms.push('webview');
9292
this.platforms.push('cordova');
93+
} else {
94+
this.platforms.push('browser');
9395
}
9496
if(this.isIPad()) this.platforms.push('ipad');
9597

@@ -129,7 +131,10 @@
129131
* @returns {boolean} Whether we are running on iPad.
130132
*/
131133
isIPad: function() {
132-
return this.ua.toLowerCase().indexOf('ipad') >= 0;
134+
if( /iPad/i.test(window.navigator.platform) ) {
135+
return true;
136+
}
137+
return /iPad/i.test(this.ua);
133138
},
134139
/**
135140
* @ngdoc method
@@ -170,7 +175,7 @@
170175
} else if(this.ua.indexOf('iPhone') > -1 || this.ua.indexOf('iPad') > -1 || this.ua.indexOf('iPod') > -1) {
171176
platformName = 'ios';
172177
} else {
173-
platformName = '';
178+
platformName = window.navigator.platform && window.navigator.platform.toLowerCase().split(' ')[0] || '';
174179
}
175180
},
176181

Diff for: js/utils/viewport.js

+86-16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
var viewportTag;
33
var viewportProperties = {};
44

5+
ionic.viewport = {
6+
orientation: function() {
7+
// 0 = Portrait
8+
// 90 = Landscape
9+
// not using window.orientation because each device has a different implementation
10+
return (window.innerWidth > window.innerHeight ? 90 : 0);
11+
}
12+
};
513

614
function viewportLoadTag() {
715
var x;
@@ -20,43 +28,105 @@ function viewportLoadTag() {
2028
keyValue = props[x].split('=');
2129
if(keyValue.length == 2) viewportProperties[ keyValue[0] ] = keyValue[1];
2230
}
23-
viewportInitWebView();
31+
viewportUpdate();
2432
}
2533
}
2634

27-
function viewportInitWebView() {
35+
function viewportUpdate() {
36+
// unit tests in viewport.unit.js
37+
38+
var initWidth = viewportProperties.width;
2839
var initHeight = viewportProperties.height;
40+
var p = ionic.Platform;
41+
var version = p.version();
42+
var DEVICE_WIDTH = 'device-width';
43+
var DEVICE_HEIGHT = 'device-height';
44+
var orientation = ionic.viewport.orientation();
45+
46+
// Most times we're removing the height and adding the width
47+
// So this is the default to start with, then modify per platform/version/oreintation
48+
delete viewportProperties.height;
49+
viewportProperties.width = DEVICE_WIDTH;
50+
51+
if( p.isIPad() ) {
52+
// iPad
53+
54+
if( version > 7 ) {
55+
// iPad >= 7.1
56+
// https://issues.apache.org/jira/browse/CB-4323
57+
delete viewportProperties.width;
58+
59+
} else {
60+
// iPad <= 7.0
61+
62+
if( p.isWebView() ) {
63+
// iPad <= 7.0 WebView
64+
65+
if( orientation == 90 ) {
66+
// iPad <= 7.0 WebView Landscape
67+
viewportProperties.height = '0';
68+
69+
} else if(version == 7) {
70+
// iPad <= 7.0 WebView Portait
71+
viewportProperties.height = DEVICE_HEIGHT;
72+
}
73+
} else {
74+
// iPad <= 6.1 Browser
75+
if(version < 7) {
76+
viewportProperties.height = '0';
77+
}
78+
}
79+
}
80+
81+
} else if( p.isIOS() ) {
82+
// iPhone
83+
84+
if( p.isWebView() ) {
85+
// iPhone WebView
2986

30-
if( ionic.Platform.isWebView() ) {
31-
viewportProperties.height = 'device-height';
87+
if(version > 7) {
88+
// iPhone >= 7.1 WebView
89+
delete viewportProperties.width;
3290

33-
} else if( ionic.Platform.isIOS() && viewportProperties.height ) {
34-
// if its not a webview, and a viewport height was set, just removing
35-
// the height value doesn't trigger the change, but setting to 0 does the trick
36-
viewportProperties.height = '0';
91+
} else if(version < 7) {
92+
// iPhone <= 6.1 WebView
93+
// if height was set it needs to get removed with this hack for <= 6.1
94+
if( initHeight ) viewportProperties.height = '0';
95+
}
96+
97+
} else {
98+
// iPhone Browser
99+
100+
if (version < 7) {
101+
// iPhone <= 6.1 Browser
102+
// if height was set it needs to get removed with this hack for <= 6.1
103+
if( initHeight ) viewportProperties.height = '0';
104+
}
105+
}
37106

38-
} else if( viewportProperties.height ) {
39-
delete viewportProperties.height;
40107
}
41108

42109
// only update the viewport tag if there was a change
43-
if(initHeight !== viewportProperties.height) viewportUpdate();
44-
console.debug(viewportTag.content)
110+
if(initWidth !== viewportProperties.width || initHeight !== viewportProperties.height) {
111+
viewportTagUpdate();
112+
}
45113
}
46114

47-
function viewportUpdate(updates) {
48-
if(!viewportTag) return;
49-
115+
function viewportTagUpdate(updates) {
50116
ionic.Utils.extend(viewportProperties, updates);
51117

52118
var key, props = [];
53119
for(key in viewportProperties) {
54-
if(viewportProperties[key]) props.push(key + '=' + viewportProperties[key]);
120+
if( viewportProperties[key] ) props.push(key + '=' + viewportProperties[key]);
55121
}
56122

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

60126
ionic.DomUtil.ready(function() {
61127
viewportLoadTag();
128+
129+
window.addEventListener("orientationchange", function(){
130+
setTimeout(viewportUpdate, 1000);
131+
}, false);
62132
});

Diff for: scss/_platform.scss

+7-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
top: $bar-height + $ios7-statusbar-height;
2727
}
2828

29-
.has-header,
29+
.has-header,
3030
.bar-subheader {
3131
top: $bar-height + $ios7-statusbar-height;
3232
}
@@ -45,3 +45,9 @@
4545
margin-bottom: 20px;
4646
}
4747
}
48+
49+
@media (orientation:landscape) {
50+
.platform-ios7.platform-browser.platform-ipad {
51+
position: fixed; // required for iPad 7 Safari
52+
}
53+
}

Diff for: test/html/viewState.html

+36
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,42 @@ <h2>{{ auto.year }} {{ auto.make }} {{ auto.model }}</h2>
258258
<label class="item item-input">
259259
<textarea placeholder="Description"></textarea>
260260
</label>
261+
<label class="item item-input">
262+
<textarea placeholder="Description"></textarea>
263+
</label>
264+
<label class="item item-input">
265+
<textarea placeholder="Description"></textarea>
266+
</label>
267+
<label class="item item-input">
268+
<textarea placeholder="Description"></textarea>
269+
</label>
270+
<label class="item item-input">
271+
<textarea placeholder="Description"></textarea>
272+
</label>
273+
<label class="item item-input">
274+
<textarea placeholder="Description"></textarea>
275+
</label>
276+
<label class="item item-input">
277+
<textarea placeholder="Description"></textarea>
278+
</label>
279+
<label class="item item-input">
280+
<textarea placeholder="Description"></textarea>
281+
</label>
282+
<label class="item item-input">
283+
<textarea placeholder="Description"></textarea>
284+
</label>
285+
<label class="item item-input">
286+
<textarea placeholder="Description"></textarea>
287+
</label>
288+
<label class="item item-input">
289+
<textarea placeholder="Description"></textarea>
290+
</label>
291+
<label class="item item-input">
292+
<textarea placeholder="Description"></textarea>
293+
</label>
294+
<label class="item item-input">
295+
<textarea placeholder="Description"></textarea>
296+
</label>
261297
</div>
262298

263299
<div class="padding">

Diff for: test/unit/angular/service/platform.unit.js

+39-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ describe('Ionic Platform Service', function() {
55

66
beforeEach(inject(function($window, $ionicPlatform, $rootScope) {
77
window = $window;
8+
window.navigator = {
9+
platform: ''
10+
};
811
ionic.Platform.ua = '';
912
ionicPlatform = $ionicPlatform;
1013
rootScope = $rootScope;
@@ -84,6 +87,39 @@ describe('Ionic Platform Service', function() {
8487
expect(ionic.Platform.version()).toEqual(7.0);
8588
});
8689

90+
it('should not be iPad from none iPad user agent', function() {
91+
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';
92+
ionic.Platform.setPlatform(undefined);
93+
ionic.Platform.setVersion(undefined);
94+
expect(ionic.Platform.isIPad()).toEqual(false);
95+
});
96+
97+
it('should be iPad from user agent', function() {
98+
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';
99+
ionic.Platform.setPlatform(undefined);
100+
ionic.Platform.setVersion(undefined);
101+
expect(ionic.Platform.isIPad()).toEqual(true);
102+
});
103+
104+
it('should be iPad from iPad in window.navigator.platform and webview, but iPhone in user agent', function() {
105+
window.cordova = {};
106+
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';
107+
window.navigator = {
108+
platform: 'iPad Simulator'
109+
};
110+
ionic.Platform.setPlatform(undefined);
111+
ionic.Platform.setVersion(undefined);
112+
expect(ionic.Platform.isIPad()).toEqual(true);
113+
});
114+
115+
it('should not be iPad from no in window.navigator.platform, and iPhone in user agent', function() {
116+
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';
117+
window.navigator = {};
118+
ionic.Platform.setPlatform(undefined);
119+
ionic.Platform.setVersion(undefined);
120+
expect(ionic.Platform.isIPad()).toEqual(false);
121+
});
122+
87123
it('is iOS', function() {
88124
ionic.Platform.setPlatform('iOS');
89125
expect(ionic.Platform.isIOS()).toEqual(true);
@@ -104,6 +140,7 @@ describe('Ionic Platform Service', function() {
104140
});
105141

106142
it('is WebView', function() {
143+
window.cordova = undefined;
107144
expect(ionic.Platform.isWebView()).toEqual(false);
108145
window.cordova = {};
109146
expect(ionic.Platform.isWebView()).toEqual(true);
@@ -155,7 +192,7 @@ describe('Ionic Platform Service', function() {
155192
expect(ionic.Platform.platforms[1]).toEqual('cordova');
156193
});
157194

158-
it('should not set any platform', function() {
195+
it('should not set if its not a webview but only a browser', function() {
159196
window.cordova = null;
160197
window.PhoneGap = null;
161198
window.phonegap = null;
@@ -164,7 +201,7 @@ describe('Ionic Platform Service', function() {
164201

165202
ionic.Platform._checkPlatforms()
166203

167-
expect(ionic.Platform.platforms.length).toEqual(0);
204+
expect(ionic.Platform.platforms[0]).toEqual('browser');
168205
});
169206

170207
it('sets grade a from iOS7', function() {

0 commit comments

Comments
 (0)