From 4dbc64ae7880f30a1dfdf22a3afb9a9426c100cc Mon Sep 17 00:00:00 2001 From: Kai Mallea Date: Sat, 4 Jul 2015 18:10:39 -0400 Subject: [PATCH 1/4] Handle Facebook's integrated browser UAs - Strip Facebook's verbose UA - Add tests for Facebook's integrated browsers - Update minified file - Fixes #22 --- isMobile.js | 8 ++++++- isMobile.min.js | 2 +- tests/spec/AppleSpec.js | 50 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/isMobile.js b/isMobile.js index dfd36aa..b2540e2 100644 --- a/isMobile.js +++ b/isMobile.js @@ -53,11 +53,17 @@ var IsMobileClass = function(userAgent) { var ua = userAgent || navigator.userAgent; + // Facebook mobile app's integrated browser adds a bunch of strings that + // match everything. Strip it out if it exists. + var tmp = ua.split('[FBAN'); + if (typeof tmp[1] !== 'undefined') { + ua = tmp[0]; + } this.apple = { phone: match(apple_phone, ua), ipod: match(apple_ipod, ua), - tablet: match(apple_tablet, ua), + tablet: !match(apple_phone, ua) && match(apple_tablet, ua), device: match(apple_phone, ua) || match(apple_ipod, ua) || match(apple_tablet, ua) }; this.android = { diff --git a/isMobile.min.js b/isMobile.min.js index 5fe235f..85e2ebb 100644 --- a/isMobile.min.js +++ b/isMobile.min.js @@ -1 +1 @@ -!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/IEMobile/i,h=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,i=/BlackBerry/i,j=/BB10/i,k=/Opera Mini/i,l=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,m=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),n=function(a,b){return a.test(b)},o=function(a){var o=a||navigator.userAgent;return this.apple={phone:n(b,o),ipod:n(c,o),tablet:n(d,o),device:n(b,o)||n(c,o)||n(d,o)},this.android={phone:n(e,o),tablet:!n(e,o)&&n(f,o),device:n(e,o)||n(f,o)},this.windows={phone:n(g,o),tablet:n(h,o),device:n(g,o)||n(h,o)},this.other={blackberry:n(i,o),blackberry10:n(j,o),opera:n(k,o),firefox:n(l,o),device:n(i,o)||n(j,o)||n(k,o)||n(l,o)},this.seven_inch=n(m,o),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window?this:void 0},p=function(){var a=new o;return a.Class=o,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=o:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=p():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=p()):a.isMobile=p()}(this); \ No newline at end of file +!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/IEMobile/i,h=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,i=/BlackBerry/i,j=/BB10/i,k=/Opera Mini/i,l=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,m=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),n=function(a,b){return a.test(b)},o=function(a){var o=a||navigator.userAgent,p=o.split("[FBAN");return"undefined"!=typeof p[1]&&(o=p[0]),this.apple={phone:n(b,o),ipod:n(c,o),tablet:!n(b,o)&&n(d,o),device:n(b,o)||n(c,o)||n(d,o)},this.android={phone:n(e,o),tablet:!n(e,o)&&n(f,o),device:n(e,o)||n(f,o)},this.windows={phone:n(g,o),tablet:n(h,o),device:n(g,o)||n(h,o)},this.other={blackberry:n(i,o),blackberry10:n(j,o),opera:n(k,o),firefox:n(l,o),device:n(i,o)||n(j,o)||n(k,o)||n(l,o)},this.seven_inch=n(m,o),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window?this:void 0},p=function(){var a=new o;return a.Class=o,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=o:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=p():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=p()):a.isMobile=p()}(this); \ No newline at end of file diff --git a/tests/spec/AppleSpec.js b/tests/spec/AppleSpec.js index 3d3435f..65c0722 100644 --- a/tests/spec/AppleSpec.js +++ b/tests/spec/AppleSpec.js @@ -90,4 +90,54 @@ describe("Apple", function(){ }); + describe("Facebook iPhone App UserAgent", function() { + + beforeEach(function() { + userAgent = "Mozilla/5.0 (iPhone; CPU OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B410 [FBAN/FBIOS;FBAV/20.1.0.15.10;FBBV/5758778;FBDV/iPad5,4;FBMD/iPad;FBSN/iPhone OS;FBSV/8.1;FBSS/2; FBCR/;FBID/tablet;FBLC/fi_FI;FBOP/1]"; + mobile = new isMobile.Class(userAgent); + }); + + it("should be an iPhone", function() { + expect(mobile.apple.phone).toBe(true); + }); + + it("should not be an iPad", function() { + expect(mobile.apple.tablet).not.toBe(true); + }); + + it("should not be an iPod", function() { + expect(mobile.apple.ipod).not.toBe(true); + }); + + it("should be an Apple device", function() { + expect(mobile.apple.device).toBe(true); + }); + + }); + + describe("Facebook iPad App UserAgent", function() { + + beforeEach(function() { + userAgent = "Mozilla/5.0 (iPad; CPU OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B410 [FBAN/FBIOS;FBAV/20.1.0.15.10;FBBV/5758778;FBDV/iPad5,4;FBMD/iPad;FBSN/iPhone OS;FBSV/8.1;FBSS/2; FBCR/;FBID/tablet;FBLC/fi_FI;FBOP/1]"; + mobile = new isMobile.Class(userAgent); + }); + + it("should not be an iPhone", function() { + expect(mobile.apple.phone).not.toBe(true); + }); + + it("should be an iPad", function() { + expect(mobile.apple.tablet).toBe(true); + }); + + it("should not be an iPod", function() { + expect(mobile.apple.ipod).not.toBe(true); + }); + + it("should be an Apple device", function() { + expect(mobile.apple.device).toBe(true); + }); + + }); + }); From a23816af981c420cb5b13e8420c52dc51df35c82 Mon Sep 17 00:00:00 2001 From: Kai Mallea Date: Sat, 4 Jul 2015 18:18:09 -0400 Subject: [PATCH 2/4] Update README --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bd81532..db3fc86 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ I couldn't do detection on the back-end, because the entire site was cached and So I resorted to UA sniffing. -I tried to keep the script small (**currently ~1.3k bytes, minified**) and simple, because it would need to execute in the ``, which is generally a bad idea, since JS blocks downloading and rendering of anything else while it parses and executes. In the case of mobile redirection, I don't mind so much, because I want to start the redirect as soon as possible, before the device has a chance to start downloading and rendering stuff. For non-mobile platforms, the script should execute fast, so the browser can quickly get back to downloading and rendering. +I tried to keep the script small (**currently ~1.4k bytes, minified**) and simple, because it would need to execute in the ``, which is generally a bad idea, since JS blocks downloading and rendering of anything else while it parses and executes. In the case of mobile redirection, I don't mind so much, because I want to start the redirect as soon as possible, before the device has a chance to start downloading and rendering stuff. For non-mobile platforms, the script should execute fast, so the browser can quickly get back to downloading and rendering. ## How it works @@ -75,7 +75,7 @@ The following properies of the `isMobile` object will either be `true` or `false ## Example Usage -I include the minified version of the script, inline, and at the top of the ``. Cellular connections tend to suck, so it would be wasteful overhead to open another connection, just to download <1kb of JS: +I include the minified version of the script, inline, and at the top of the ``. Cellular connections tend to suck, so it would be wasteful overhead to open another connection, just to download ~1.4kb of JS: ```html @@ -84,8 +84,8 @@ I include the minified version of the script, inline, and at the top of the `