瀏覽代碼

Improve BrowserService

- Differentiate between IE and Edge
- Add tests
Danilo Bargen 7 年之前
父節點
當前提交
4785f8ea56
共有 4 個文件被更改,包括 191 次插入17 次删除
  1. 39 14
      src/services/browser.ts
  2. 14 3
      src/threema.d.ts
  3. 137 0
      tests/service/browser.js
  4. 1 0
      tests/testsuite.html

+ 39 - 14
src/services/browser.ts

@@ -15,16 +15,20 @@
  * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  */
 
+import BrowserName = threema.BrowserName;
+
 export class BrowserService {
     private browser: threema.BrowserInfo;
     private $log: ng.ILogService;
+    private $window: ng.IWindowService;
     private isPageVisible = true;
 
-    public static $inject = ['$log'];
+    public static $inject = ['$log', '$window'];
 
-    constructor($log: ng.ILogService) {
+    constructor($log: ng.ILogService, $window: ng.IWindowService) {
         // Angular services
         this.$log = $log;
+        this.$window = $window;
         this.initializePageVisibility();
     }
 
@@ -85,18 +89,18 @@ export class BrowserService {
             this.browser = {
                 chrome: false,
                 firefox: false,
-                msie: false,
+                ie: false,
+                edge: false,
                 opera: false,
                 safari: false,
-                version: '',
-                textInfo: 'Unknown',
             } as threema.BrowserInfo;
 
-            const uagent = navigator.userAgent.toLowerCase();
+            const uagent = this.$window.navigator.userAgent.toLowerCase();
 
             this.browser.chrome  = /webkit/.test(uagent)  && /chrome/.test(uagent) && !/edge/.test(uagent);
             this.browser.firefox = /mozilla/.test(uagent) && /firefox/.test(uagent);
-            this.browser.msie    = /msie/.test(uagent) || /trident/.test(uagent) || /edge/.test(uagent);
+            this.browser.ie      = (/msie/.test(uagent) || /trident/.test(uagent)) && !/edge/.test(uagent);
+            this.browser.edge    = /edge/.test(uagent);
             this.browser.safari  = /safari/.test(uagent)  && /applewebkit/.test(uagent) && !/chrome/.test(uagent);
             this.browser.opera   = /mozilla/.test(uagent) && /applewebkit/.test(uagent)
                 && /chrome/.test(uagent) && /safari/.test(uagent) && /opr/.test(uagent);
@@ -109,8 +113,10 @@ export class BrowserService {
             for (const x in this.browser) {
                 if (this.browser[x]) {
                     let b;
-                    if (x === 'msie') {
-                        b = 'msie|edge';
+                    if (x === 'ie') {
+                        b = 'msie';
+                    } else if (x === 'edge') {
+                        b = 'edge';
                     } else if (x === 'opera') {
                         b = 'opr';
                     } else if (x === 'safari') {
@@ -130,11 +136,30 @@ export class BrowserService {
                 }
             }
 
-            if (this.browser.chrome) { this.browser.textInfo = 'Chrome ' + this.browser.version; }
-            if (this.browser.firefox) { this.browser.textInfo = 'Firefox ' + this.browser.version; }
-            if (this.browser.msie) { this.browser.textInfo = 'IE/Edge ' + this.browser.version; }
-            if (this.browser.safari) { this.browser.textInfo = 'Safari ' + this.browser.version; }
-            if (this.browser.opera) { this.browser.textInfo = 'Opera ' + this.browser.version; }
+            if (this.browser.chrome) {
+                this.browser.name = BrowserName.Chrome;
+                this.browser.textInfo = 'Chrome ' + this.browser.version;
+            }
+            if (this.browser.firefox) {
+                this.browser.name = BrowserName.Firefox;
+                this.browser.textInfo = 'Firefox ' + this.browser.version;
+            }
+            if (this.browser.ie) {
+                this.browser.name = BrowserName.InternetExplorer;
+                this.browser.textInfo = 'Internet Explorer ' + this.browser.version;
+            }
+            if (this.browser.edge) {
+                this.browser.name = BrowserName.Edge;
+                this.browser.textInfo = 'Edge ' + this.browser.version;
+            }
+            if (this.browser.safari) {
+                this.browser.name = BrowserName.Safari;
+                this.browser.textInfo = 'Safari ' + this.browser.version;
+            }
+            if (this.browser.opera) {
+                this.browser.name = BrowserName.Opera;
+                this.browser.textInfo = 'Opera ' + this.browser.version;
+            }
         }
 
         return this.browser;

+ 14 - 3
src/threema.d.ts

@@ -406,14 +406,25 @@ declare namespace threema {
         pushToken: string | null;
     }
 
+    const enum BrowserName {
+        Chrome = 'chrome',
+        Firefox = 'firefox',
+        InternetExplorer = 'ie',
+        Edge = 'edge',
+        Opera = 'opera',
+        Safari = 'safari',
+    }
+
     interface BrowserInfo {
         chrome: boolean;
         firefox: boolean;
-        msie: boolean;
+        ie: boolean;
+        edge: boolean;
         opera: boolean;
         safari: boolean;
-        version: string;
-        textInfo: string;
+        name?: BrowserName;
+        version?: string;
+        textInfo?: string;
     }
 
     interface PromiseCallbacks {

+ 137 - 0
tests/service/browser.js

@@ -0,0 +1,137 @@
+describe('BrowserService', function() {
+
+    function testUserAgent(agent) {
+        let $service;
+        module('3ema.services');
+        module(function($provide) {
+            $provide.value('$window', {
+                navigator: { userAgent: agent }
+            });
+        });
+        inject(function(BrowserService) {
+            $service = BrowserService;
+        });
+        return $service;
+    }
+
+    it('firefox', () => {
+        const ua = 'Mozilla/5.0 (X11; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0';
+        const service = testUserAgent(ua);
+        const browser = service.getBrowser();
+        expect(browser.chrome).toBe(false);
+        expect(browser.firefox).toBe(true);
+        expect(browser.ie).toBe(false);
+        expect(browser.edge).toBe(false);
+        expect(browser.opera).toBe(false);
+        expect(browser.safari).toBe(false);
+        expect(browser.name).toEqual('firefox');
+        expect(browser.version).toEqual('59');
+        expect(browser.textInfo).toEqual('Firefox 59');
+    });
+
+    it('chrome', () => {
+        const ua = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36';
+        const service = testUserAgent(ua);
+        const browser = service.getBrowser();
+        expect(browser.chrome).toBe(true);
+        expect(browser.firefox).toBe(false);
+        expect(browser.ie).toBe(false);
+        expect(browser.edge).toBe(false);
+        expect(browser.opera).toBe(false);
+        expect(browser.safari).toBe(false);
+        expect(browser.name).toEqual('chrome');
+        expect(browser.version).toEqual('65');
+        expect(browser.textInfo).toEqual('Chrome 65');
+    });
+
+    it('ie9', () => {
+        const ua = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)';
+        const service = testUserAgent(ua);
+        const browser = service.getBrowser();
+        expect(browser.chrome).toBe(false);
+        expect(browser.firefox).toBe(false);
+        expect(browser.ie).toBe(true);
+        expect(browser.edge).toBe(false);
+        expect(browser.opera).toBe(false);
+        expect(browser.safari).toBe(false);
+        expect(browser.name).toEqual('ie');
+        expect(browser.version).toEqual('9');
+        expect(browser.textInfo).toEqual('Internet Explorer 9');
+    });
+
+    it('ie11', () => {
+        const ua = 'Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko';
+        const service = testUserAgent(ua);
+        const browser = service.getBrowser();
+        expect(browser.chrome).toBe(false);
+        expect(browser.firefox).toBe(false);
+        expect(browser.ie).toBe(true);
+        expect(browser.edge).toBe(false);
+        expect(browser.opera).toBe(false);
+        expect(browser.safari).toBe(false);
+        expect(browser.name).toEqual('ie');
+        expect(browser.version).toEqual('11');
+        expect(browser.textInfo).toEqual('Internet Explorer 11');
+    });
+
+    it('edge12', () => {
+        const ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246';
+        const service = testUserAgent(ua);
+        const browser = service.getBrowser();
+        expect(browser.chrome).toBe(false);
+        expect(browser.firefox).toBe(false);
+        expect(browser.ie).toBe(false);
+        expect(browser.edge).toBe(true);
+        expect(browser.opera).toBe(false);
+        expect(browser.safari).toBe(false);
+        expect(browser.name).toEqual('edge');
+        expect(browser.version).toEqual('12');
+        expect(browser.textInfo).toEqual('Edge 12');
+    });
+
+    it('opera', () => {
+        const ua = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36 OPR/51.0.2830.55';
+        const service = testUserAgent(ua);
+        const browser = service.getBrowser();
+        expect(browser.chrome).toBe(false);
+        expect(browser.firefox).toBe(false);
+        expect(browser.ie).toBe(false);
+        expect(browser.edge).toBe(false);
+        expect(browser.opera).toBe(true);
+        expect(browser.safari).toBe(false);
+        expect(browser.name).toEqual('opera');
+        expect(browser.version).toEqual('51');
+        expect(browser.textInfo).toEqual('Opera 51');
+    });
+
+    it('safari7', () => {
+        const ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A';
+        const service = testUserAgent(ua);
+        const browser = service.getBrowser();
+        expect(browser.chrome).toBe(false);
+        expect(browser.firefox).toBe(false);
+        expect(browser.ie).toBe(false);
+        expect(browser.edge).toBe(false);
+        expect(browser.opera).toBe(false);
+        expect(browser.safari).toBe(true);
+        expect(browser.name).toEqual('safari');
+        expect(browser.version).toEqual('7');
+        expect(browser.textInfo).toEqual('Safari 7');
+    });
+
+    it('safari11', () => {
+        const ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/604.5.6 (KHTML, like Gecko) Version/11.0.3 Safari/604.5.6';
+        const service = testUserAgent(ua);
+        const browser = service.getBrowser();
+        expect(browser.chrome).toBe(false);
+        expect(browser.firefox).toBe(false);
+        expect(browser.ie).toBe(false);
+        expect(browser.edge).toBe(false);
+        expect(browser.opera).toBe(false);
+        expect(browser.safari).toBe(true);
+        expect(browser.name).toEqual('safari');
+        expect(browser.version).toEqual('11');
+        expect(browser.textInfo).toEqual('Safari 11');
+    });
+
+});

+ 1 - 0
tests/testsuite.html

@@ -28,6 +28,7 @@
         <script src="service/uri.js"></script>
         <script src="service/webclient.js"></script>
         <script src="service/string.js"></script>
+        <script src="service/browser.js"></script>
         <script src="helpers.js"></script>
     </head>
     <body>