From 7a3930f6ae54415cfb468f3b0beb676c96f231ed Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Mon, 24 Feb 2014 13:40:18 -0600 Subject: [PATCH] improve platform/version/grade fallbacks with user-agents --- .../test/service/ionicPlatform.unit.js | 48 +++++++++++++++---- js/utils/platform.js | 48 ++++++++++++++----- 2 files changed, 75 insertions(+), 21 deletions(-) diff --git a/js/ext/angular/test/service/ionicPlatform.unit.js b/js/ext/angular/test/service/ionicPlatform.unit.js index 263b4b75b63..881b01199c7 100644 --- a/js/ext/angular/test/service/ionicPlatform.unit.js +++ b/js/ext/angular/test/service/ionicPlatform.unit.js @@ -3,26 +3,27 @@ describe('Ionic Platform Service', function() { beforeEach(inject(function($window) { window = $window; + ionic.Platform.ua = ''; })); it('should set platform name', function() { ionic.Platform.setPlatform('Android'); - expect(ionic.Platform.platform()).toEqual('Android'); + expect(ionic.Platform.platform()).toEqual('android'); ionic.Platform.setPlatform('iOS'); - expect(ionic.Platform.platform()).toEqual('iOS'); - - ionic.Platform.setPlatform('wInDoWs'); - expect(ionic.Platform.platform()).toEqual('wInDoWs'); + expect(ionic.Platform.platform()).toEqual('ios'); ionic.Platform.setPlatform(''); - expect(ionic.Platform.platform()).toEqual(undefined); + expect(ionic.Platform.platform()).toEqual('unknown'); + + ionic.Platform.setPlatform(null); + expect(ionic.Platform.platform()).toEqual('unknown'); ionic.Platform.setPlatform(); - expect(ionic.Platform.platform()).toEqual(undefined); + expect(ionic.Platform.platform()).toEqual('unknown'); }); - it('set version', function() { + it('set version with device', function() { ionic.Platform.setVersion('1.2.3'); expect(ionic.Platform.version()).toEqual(1.2); @@ -44,10 +45,37 @@ describe('Ionic Platform Service', function() { ionic.Platform.setVersion(null); expect(ionic.Platform.version()).toEqual(0); + ionic.Platform.setVersion('0'); + expect(ionic.Platform.version()).toEqual(0); + ionic.Platform.setVersion(); expect(ionic.Platform.version()).toEqual(0); }); + it('set android with user agent', function() { + ionic.Platform.ua = 'Mozilla/5.0 (Linux; U; Android 2.2.1; fr-ch; A43 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'; + ionic.Platform.setPlatform(undefined); + ionic.Platform.setVersion(undefined); + expect(ionic.Platform.platform()).toEqual('android'); + expect(ionic.Platform.version()).toEqual(2.2); + }); + + it('set ios with iPhone 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'; + ionic.Platform.setPlatform(undefined); + ionic.Platform.setVersion(undefined); + expect(ionic.Platform.platform()).toEqual('ios'); + expect(ionic.Platform.version()).toEqual(6.1); + }); + + it('set ios with iPad 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.platform()).toEqual('ios'); + expect(ionic.Platform.version()).toEqual(7.0); + }); + it('is iOS', function() { ionic.Platform.setPlatform('iOS'); expect(ionic.Platform.isIOS()).toEqual(true); @@ -66,8 +94,8 @@ describe('Ionic Platform Service', function() { ionic.Platform.setPlatform('android'); expect(ionic.Platform.isAndroid()).toEqual(true); - // ionic.Platform.setPlatform('ios'); - // expect(ionic.Platform.isAndroid()).toEqual(false); + ionic.Platform.setPlatform('ios'); + expect(ionic.Platform.isAndroid()).toEqual(false); }); it('is Cordova', function() { diff --git a/js/utils/platform.js b/js/utils/platform.js index 9806f05636e..fe2cc5651f2 100644 --- a/js/utils/platform.js +++ b/js/utils/platform.js @@ -6,6 +6,7 @@ isFullScreen: false, platforms: null, grade: null, + ua: navigator.userAgent, ready: function(cb) { // run through tasks to complete now that the device is ready @@ -77,7 +78,7 @@ return !(!window.cordova && !window.PhoneGap && !window.phonegap); }, isIPad: function() { - return navigator.userAgent.toLowerCase().indexOf('ipad') >= 0; + return this.ua.toLowerCase().indexOf('ipad') >= 0; }, isIOS: function() { return this.is('ios'); @@ -88,26 +89,51 @@ platform: function() { // singleton to get the platform name - if(!platformName) this.setPlatform(this.device().platform); + if(platformName === null) this.setPlatform(this.device().platform); return platformName; }, setPlatform: function(n) { - platformName = n; + if(typeof n != 'undefined' && n !== null && n.length) { + platformName = n.toLowerCase(); + } else if(this.ua.indexOf('Android') > 0) { + platformName = 'android'; + } else if(this.ua.indexOf('iPhone') > -1 || this.ua.indexOf('iPad') > -1 || this.ua.indexOf('iPod') > -1) { + platformName = 'ios'; + } else { + platformName = 'unknown'; + } }, version: function() { // singleton to get the platform version - if(!platformVersion) this.setVersion(this.device().version); + if(platformVersion === null) this.setVersion(this.device().version); return platformVersion; }, setVersion: function(v) { - if(v) { + if(typeof v != 'undefined' && v !== null) { v = v.split('.'); - platformVersion = parseFloat(v[0] + '.' + (v.length > 1 ? v[1] : 0)); - } else { - platformVersion = 0; + v = parseFloat(v[0] + '.' + (v.length > 1 ? v[1] : 0)); + if(!isNaN(v)) { + platformVersion = v; + return; + } + } + + platformVersion = 0; + + // fallback to user-agent checking + var pName = this.platform(); + var versionMatch = { + 'android': /Android (\d+).(\d+)?/, + 'ios': /OS (\d+)_(\d+)?/ + }; + if(versionMatch[pName]) { + v = this.ua.match( versionMatch[pName] ); + if(v.length > 2) { + platformVersion = parseFloat( v[1] + '.' + v[2] ); + } } }, @@ -127,7 +153,7 @@ } // A quick hack for to check userAgent - return navigator.userAgent.toLowerCase().indexOf(type) >= 0; + return this.ua.toLowerCase().indexOf(type) >= 0; }, exitApp: function() { @@ -174,8 +200,8 @@ }; - var platformName, // just the name, like iOS or Android - platformVersion, // a float of the major and minor, like 7.1 + var platformName = null, // just the name, like iOS or Android + platformVersion = null, // a float of the major and minor, like 7.1 readyCallbacks = []; // setup listeners to know when the device is ready to go