diff --git a/ionic/platform/platform.ts b/ionic/platform/platform.ts index e9fc1820d3..619b51698d 100644 --- a/ionic/platform/platform.ts +++ b/ionic/platform/platform.ts @@ -460,14 +460,6 @@ export class Platform { return valueSplit.indexOf(queryTestValue) > -1; } - /** - * @private - */ - testUserAgent(userAgentExpression): boolean { - let rgx = new RegExp(userAgentExpression, 'i'); - return rgx.test(this._ua || ''); - } - /** * @private */ @@ -494,17 +486,28 @@ export class Platform { /** * @private */ - isPlatform(queryTestValue: string, userAgentExpression: string): boolean { - if (!userAgentExpression) { - userAgentExpression = queryTestValue; - } - + isPlatformMatch(queryStringName: string, userAgentAtLeastHas?: string[], userAgentMustNotHave: string[] = []): boolean { let queryValue = this.query('ionicplatform'); if (queryValue) { - return this.testQuery(queryValue, queryTestValue); + return this.testQuery(queryValue, queryStringName); } - return this.testUserAgent(userAgentExpression); + userAgentAtLeastHas = userAgentAtLeastHas || [queryStringName]; + + let userAgent = this._ua.toLowerCase(); + + for (var i = 0; i < userAgentAtLeastHas.length; i++) { + if (userAgent.indexOf(userAgentAtLeastHas[i]) > -1) { + for (var j = 0; j < userAgentMustNotHave.length; j++) { + if (userAgent.indexOf(userAgentMustNotHave[j]) > -1) { + return false; + } + } + return true; + } + } + + return false; } /** diff --git a/ionic/platform/registry.ts b/ionic/platform/registry.ts index 7681469ab4..fdda9e9231 100644 --- a/ionic/platform/registry.ts +++ b/ionic/platform/registry.ts @@ -77,7 +77,7 @@ Platform.register({ scrollAssist: true, }, isMatch(p: Platform): boolean { - return p.isPlatform('android', 'android|silk'); + return p.isPlatformMatch('android', ['android', 'silk'], ['windows phone']); }, versionParser(p: Platform): any { return p.matchUserAgentVersion(/Android (\d+).(\d+)?/); @@ -105,7 +105,7 @@ Platform.register({ tapPolyfill: isIOSDevice, }, isMatch(p: Platform): boolean { - return p.isPlatform('ios', 'iphone|ipad|ipod'); + return p.isPlatformMatch('ios', ['iphone', 'ipad', 'ipod']); }, versionParser(p: Platform): any { return p.matchUserAgentVersion(/OS (\d+)_(\d+)?/); @@ -120,7 +120,7 @@ Platform.register({ keyboardHeight: 500, }, isMatch(p: Platform): boolean { - return p.isPlatform('ios', 'ipad'); + return p.isPlatformMatch('ipad'); } }); @@ -131,7 +131,7 @@ Platform.register({ 'phablet' ], isMatch(p: Platform): boolean { - return p.isPlatform('ios', 'iphone'); + return p.isPlatformMatch('iphone'); } }); @@ -150,7 +150,7 @@ Platform.register({ hoverCSS: false }, isMatch(p: Platform): boolean { - return p.isPlatform('windows', 'windows'); + return p.isPlatformMatch('windows', ['windows phone']); }, versionParser(p: Platform): any { return p.matchUserAgentVersion(/Windows Phone (\d+).(\d+)?/); diff --git a/ionic/platform/test/platform.spec.ts b/ionic/platform/test/platform.spec.ts index 03807648e4..bfff65d1b3 100644 --- a/ionic/platform/test/platform.spec.ts +++ b/ionic/platform/test/platform.spec.ts @@ -41,14 +41,26 @@ export function run() { platform.load('ios'); expect(platform.is('android')).toEqual(false); + expect(platform.is('windows')).toEqual(false); expect(platform.is('ios')).toEqual(true); }); + it('should set windows via platformOverride, despite android querystring', () => { + let platform = new Platform(); + platform.setUrl('/?ionicplatform=android'); + platform.load('windows'); + + expect(platform.is('android')).toEqual(false); + expect(platform.is('windows')).toEqual(true); + expect(platform.is('ios')).toEqual(false); + }); + it('should set ios via platformOverride', () => { let platform = new Platform(); platform.load('ios'); expect(platform.is('android')).toEqual(false); + expect(platform.is('windows')).toEqual(false); expect(platform.is('ios')).toEqual(true); }); @@ -57,6 +69,18 @@ export function run() { platform.load('android'); expect(platform.is('android')).toEqual(true); + expect(platform.is('windows')).toEqual(false); + expect(platform.is('ios')).toEqual(false); + }); + + it('should set windows via querystring', () => { + let platform = new Platform(); + platform.setUrl('/?ionicplatform=windows'); + platform.load(); + + expect(platform.is('mobile')).toEqual(true); + expect(platform.is('android')).toEqual(false); + expect(platform.is('windows')).toEqual(true); expect(platform.is('ios')).toEqual(false); }); @@ -67,9 +91,21 @@ export function run() { expect(platform.is('mobile')).toEqual(true); expect(platform.is('android')).toEqual(false); + expect(platform.is('windows')).toEqual(false); expect(platform.is('ios')).toEqual(true); }); + it('should set windows via querystring, even with android user agent', () => { + let platform = new Platform(); + platform.setUrl('/?ionicplatform=windows'); + platform.setUserAgent(ANDROID_UA); + platform.load(); + + expect(platform.is('android')).toEqual(false); + expect(platform.is('windows')).toEqual(true); + expect(platform.is('ios')).toEqual(false); + }); + it('should set ios via querystring, even with android user agent', () => { let platform = new Platform(); platform.setUrl('/?ionicplatform=ios'); @@ -77,6 +113,7 @@ export function run() { platform.load(); expect(platform.is('android')).toEqual(false); + expect(platform.is('windows')).toEqual(false); expect(platform.is('ios')).toEqual(true); }); @@ -86,6 +123,7 @@ export function run() { platform.load(); expect(platform.is('android')).toEqual(true); + expect(platform.is('windows')).toEqual(false); expect(platform.is('ios')).toEqual(false); }); @@ -96,6 +134,40 @@ export function run() { platform.load(); expect(platform.is('android')).toEqual(true); + expect(platform.is('windows')).toEqual(false); + expect(platform.is('ios')).toEqual(false); + }); + + it('should set windows via user agent', () => { + let platform = new Platform(); + platform.setUserAgent(WINDOWS_UA); + platform.load(); + + expect(platform.is('mobile')).toEqual(true); + expect(platform.is('windows')).toEqual(true); + expect(platform.is('android')).toEqual(false); + expect(platform.is('ios')).toEqual(false); + }); + + it('should set windows8 via user agent', () => { + let platform = new Platform(); + platform.setUserAgent(WINDOWS8_UA); + platform.load(); + + expect(platform.is('mobile')).toEqual(true); + expect(platform.is('windows')).toEqual(true); + expect(platform.is('android')).toEqual(false); + expect(platform.is('ios')).toEqual(false); + }); + + it('should set windows7 via user agent', () => { + let platform = new Platform(); + platform.setUserAgent(WINDOWS7_UA); + platform.load(); + + expect(platform.is('mobile')).toEqual(true); + expect(platform.is('windows')).toEqual(true); + expect(platform.is('android')).toEqual(false); expect(platform.is('ios')).toEqual(false); }); @@ -105,6 +177,7 @@ export function run() { platform.load(); expect(platform.is('mobile')).toEqual(true); + expect(platform.is('windows')).toEqual(false); expect(platform.is('android')).toEqual(true); expect(platform.is('ios')).toEqual(false); }); @@ -115,6 +188,7 @@ export function run() { platform.load(); expect(platform.is('mobile')).toEqual(true); + expect(platform.is('windows')).toEqual(false); expect(platform.is('android')).toEqual(false); expect(platform.is('ios')).toEqual(true); expect(platform.is('iphone')).toEqual(true); @@ -127,6 +201,7 @@ export function run() { platform.load(); expect(platform.is('mobile')).toEqual(true); + expect(platform.is('windows')).toEqual(false); expect(platform.is('android')).toEqual(false); expect(platform.is('ios')).toEqual(true); expect(platform.is('ipad')).toEqual(true); @@ -135,6 +210,9 @@ export function run() { } +const WINDOWS_UA = 'Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 930) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537'; +const WINDOWS8_UA = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)'; +const WINDOWS7_UA = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; LG; GW910)'; const ANDROID_UA = 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.20 Mobile Safari/537.36'; const IPHONE_UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4'; const IPAD_UA = 'Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53';