From 216e96795bb8413ace2010b17b16406ca78b10cf Mon Sep 17 00:00:00 2001 From: Travis Sanderson Date: Thu, 6 Oct 2016 20:35:18 -0500 Subject: [PATCH 1/4] Initial implementation of detecting browser and operating system --- .gitignore | 13 ++++ LICENSE | 13 ++++ README.md | 18 +++++ example/index.html | 30 ++++++++ example/main.dart | 26 +++++++ lib/platform_detect.dart | 41 +++++++++++ lib/src/browser.dart | 118 ++++++++++++++++++++++++++++++++ lib/src/navigator.dart | 17 +++++ lib/src/operating_system.dart | 49 +++++++++++++ pubspec.yaml | 20 ++++++ smithy.yml | 24 +++++++ test/browser_test.dart | 100 +++++++++++++++++++++++++++ test/operating_system_test.dart | 62 +++++++++++++++++ 13 files changed, 531 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 example/index.html create mode 100644 example/main.dart create mode 100644 lib/platform_detect.dart create mode 100644 lib/src/browser.dart create mode 100644 lib/src/navigator.dart create mode 100644 lib/src/operating_system.dart create mode 100644 pubspec.yaml create mode 100644 smithy.yml create mode 100644 test/browser_test.dart create mode 100644 test/operating_system_test.dart diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d97e430 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +# Files and directories created by pub +.packages +.pub/ +build/ +coverage/ +packages +pubspec.lock + +# Directory created by dartdoc +doc/api/ + +# JetBrains IDEs +.idea/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9493cb6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2015 Workiva Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index eb70c30..404a1ef 100644 --- a/README.md +++ b/README.md @@ -1 +1,19 @@ # platform_detect + +A library for detecting browser and platform type and version. + +## Usage + +A simple usage example: + + import 'package:platform_detect/platform_detect.dart'; + + main() { + var awesome = new Awesome(); + } + +## Features and bugs + +Please file feature requests and bugs at the [issue tracker][tracker]. + +[tracker]: http://example.com/issues/replaceme diff --git a/example/index.html b/example/index.html new file mode 100644 index 0000000..a70f90e --- /dev/null +++ b/example/index.html @@ -0,0 +1,30 @@ + + + + Platform Detect example + + + +
+

Your Browser:

+ + +
+ Version: +
+

Your Operating System:

+
+ + + + + diff --git a/example/main.dart b/example/main.dart new file mode 100644 index 0000000..6c3802d --- /dev/null +++ b/example/main.dart @@ -0,0 +1,26 @@ +import 'dart:html'; +import 'package:platform_detect/platform_detect.dart'; + +main() { + document.querySelector('#current-browser').text = browser.name; + document.querySelector('#current-vendor').text = window.navigator.vendor; + document.querySelector('#current-appVersion').text = window.navigator.appVersion; + document.querySelector('#current-appName').text = window.navigator.appName; + document.querySelector('#current-userAgent').text = window.navigator.userAgent; + + CheckboxInputElement isChrome = document.querySelector('#current-is-chrome'); + isChrome.checked = browser.isChrome; + + CheckboxInputElement isFirefox = document.querySelector('#current-is-firefox'); + isFirefox.checked = browser.isFirefox; + + CheckboxInputElement isSafari = document.querySelector('#current-is-safari'); + isSafari.checked = browser.isSafari; + + CheckboxInputElement isInternetExplorer = document.querySelector('#current-is-ie'); + isInternetExplorer.checked = browser.isInternetExplorer; + + document.querySelector('#current-version').text = browser.version.toString(); + + document.querySelector('#current-os').text = operatingSystem.name; +} diff --git a/lib/platform_detect.dart b/lib/platform_detect.dart new file mode 100644 index 0000000..f600a60 --- /dev/null +++ b/lib/platform_detect.dart @@ -0,0 +1,41 @@ +/// Enables detection of browser type and version and operating system +/// +/// Use browser.isChrome or operatingSystem.isMac +library platform_detect; + +import 'dart:html'; + +import 'package:platform_detect/src/browser.dart'; +import 'package:platform_detect/src/navigator.dart'; +import 'package:platform_detect/src/operating_system.dart'; + +Browser _browser; + +/// Current browser info +Browser get browser { + if (_browser == null) { + Browser.navigator = new _HtmlNavigator(); + _browser = Browser.getCurrentBrowser(); + } + + return _browser; +} + +OperatingSystem _operatingSystem; + +/// Current operating system info +OperatingSystem get operatingSystem { + if (_operatingSystem == null) { + OperatingSystem.navigator = new _HtmlNavigator(); + _operatingSystem = OperatingSystem.getCurrentOperatingSystem(); + } + + return _operatingSystem; +} + +class _HtmlNavigator implements NavigatorProvider { + String get vendor => window.navigator.vendor; + String get appVersion => window.navigator.appVersion; + String get appName => window.navigator.appName; + String get userAgent => window.navigator.userAgent; +} diff --git a/lib/src/browser.dart b/lib/src/browser.dart new file mode 100644 index 0000000..13bd5c9 --- /dev/null +++ b/lib/src/browser.dart @@ -0,0 +1,118 @@ +library platform_detect.browser; + +import 'package:pub_semver/pub_semver.dart'; +import 'package:platform_detect/src/navigator.dart'; + +/// Matches a browser name with how it is represented in window.navigator +class Browser { + static NavigatorProvider navigator; + + static Browser getCurrentBrowser() { + return _knownBrowsers.firstWhere( + (browser) => browser._matchesNavigator(navigator), + orElse: () => UnknownBrowser); + } + + static Browser UnknownBrowser = new Browser('Unknown', null, null); + + Browser(this.name, bool matchesNavigator(NavigatorProvider navigator), + Version parseVersion(NavigatorProvider navigator)) + : this._matchesNavigator = matchesNavigator, + this._parseVersion = parseVersion; + + final String name; + final Function _matchesNavigator; + final Function _parseVersion; + + Version _version; + + Version get version { + if (_version == null) { + if (_parseVersion != null) { + _version = _parseVersion(Browser.navigator); + } else { + _version = new Version(0, 0, 0); + } + } + + return _version; + } + + static List _knownBrowsers = [ + _chrome, + _firefox, + _safari, + _internetExplorer + ]; + + bool get isChrome => this == _chrome; + bool get isFirefox => this == _firefox; + bool get isSafari => this == _safari; + bool get isInternetExplorer => this == _internetExplorer; + + static Browser _chrome = new Browser('Chrome', (NavigatorProvider navigator) { + var vendor = navigator.vendor; + return vendor != null && vendor.contains('Google'); + }, (NavigatorProvider navigator) { + Match match = new RegExp(r"Chrome/(\d+)\.(\d+)\.(\d+)\.(\d+)\s") + .firstMatch(navigator.appVersion); + var major = int.parse(match.group(1)); + var minor = int.parse(match.group(2)); + var patch = int.parse(match.group(3)); + var build = match.group(4); + return new Version(major, minor, patch, build: build); + }); + + static Browser _firefox = + new Browser('Firefox', (NavigatorProvider navigator) { + return navigator.userAgent.contains('Firefox'); + }, (NavigatorProvider navigator) { + Match match = + new RegExp(r'rv:(\d+)\.(\d+)\)').firstMatch(navigator.userAgent); + var major = int.parse(match.group(1)); + var minor = int.parse(match.group(2)); + return new Version(major, minor, 0); + }); + + static Browser _safari = new Browser('Safari', (NavigatorProvider navigator) { + return navigator.vendor.contains('Apple'); + }, (NavigatorProvider navigator) { + Match match = new RegExp(r'Version/(\d+)\.(\d+)\.(\d+)') + .firstMatch(navigator.appVersion); + var major = int.parse(match.group(1)); + var minor = int.parse(match.group(2)); + var patch = int.parse(match.group(3)); + return new Version(major, minor, patch); + }); + + static Browser _internetExplorer = + new Browser('Internet Explorer', (NavigatorProvider navigator) { + return navigator.appName.contains('Microsoft') || + navigator.appVersion.contains('Trident') || + navigator.appVersion.contains('Edge'); + }, (NavigatorProvider navigator) { + Match match = + new RegExp(r'MSIE (\d+)\.(\d+);').firstMatch(navigator.appVersion); + if (match != null) { + var major = int.parse(match.group(1)); + var minor = int.parse(match.group(2)); + return new Version(major, minor, 0); + } + + match = new RegExp(r'rv[: ](\d+)\.(\d+)').firstMatch(navigator.appVersion); + if (match != null) { + var major = int.parse(match.group(1)); + var minor = int.parse(match.group(2)); + return new Version(major, minor, 0); + } + + match = new RegExp(r'Edge/(\d+)\.(\d+)$').firstMatch(navigator.appVersion); + if (match != null) { + var major = int.parse(match.group(1)); + var minor = int.parse(match.group(2)); + return new Version(major, minor, 0); + } + + return new Version(0, 0, 0); + }); +} diff --git a/lib/src/navigator.dart b/lib/src/navigator.dart new file mode 100644 index 0000000..efd192d --- /dev/null +++ b/lib/src/navigator.dart @@ -0,0 +1,17 @@ +library platform_detect.navigator; + +/// Abstraction over window.navigator so we can run tests in the VM +abstract class NavigatorProvider { + String get vendor; + String get appVersion; + String get appName; + String get userAgent; +} + +/// Simple implementation that enables ease of unit testing +class TestNavigator implements NavigatorProvider { + String vendor = ''; + String appVersion = ''; + String appName = ''; + String userAgent = ''; +} diff --git a/lib/src/operating_system.dart b/lib/src/operating_system.dart new file mode 100644 index 0000000..ba14f04 --- /dev/null +++ b/lib/src/operating_system.dart @@ -0,0 +1,49 @@ +library platform_detect.operating_system; + +import 'package:platform_detect/src/navigator.dart'; + +/// Matches an operating system name with how it is represented in window.navigator +class OperatingSystem { + static NavigatorProvider navigator; + + static OperatingSystem getCurrentOperatingSystem() { + return _knownSystems.firstWhere( + (system) => system._matchesNavigator(navigator), + orElse: () => UnknownOS); + } + + static OperatingSystem UnknownOS = new OperatingSystem('Unknown', null); + + final String name; + final Function _matchesNavigator; + + OperatingSystem(this.name, bool matchesNavigator(NavigatorProvider navigator)) + : this._matchesNavigator = matchesNavigator; + + static List _knownSystems = [_mac, _windows, _unix, _linux]; + + get isMac => this == _mac; + get isWindows => this == _windows; + get isUnix => this == _unix; + get isLinux => this == _linux; + + static OperatingSystem _mac = + new OperatingSystem('Mac', (NavigatorProvider navigator) { + return navigator.appVersion.contains('Mac'); + }); + + static OperatingSystem _windows = + new OperatingSystem('Windows', (NavigatorProvider navigator) { + return navigator.appVersion.contains('Win'); + }); + + static OperatingSystem _unix = + new OperatingSystem('Unix', (NavigatorProvider navigator) { + return navigator.appVersion.contains('X11'); + }); + + static OperatingSystem _linux = + new OperatingSystem('Linux', (NavigatorProvider navigator) { + return navigator.appVersion.contains('Linux'); + }); +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..43cb5d3 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,20 @@ +name: platform_detect +description: A lightweight library for detecting the running browser and OS +version: 0.0.1 +author: Workiva Client Platform Team +homepage: https://github.com/Workiva/platform_detect +documentation: https://docs.workiva.org/platform_detect/latest/ +publish_to: https://pub.workiva.org + +environment: + sdk: ">=1.12.1 <2.0.0" + +dependencies: + pub_semver: ^1.0.0 + +dev_dependencies: + dart_style: 0.2.10 + coverage: ^0.7.9 + browser: any + dart_dev: ^1.4.2 + test: ^0.12.0 diff --git a/smithy.yml b/smithy.yml new file mode 100644 index 0000000..4e2d873 --- /dev/null +++ b/smithy.yml @@ -0,0 +1,24 @@ +project: dart +language: dart + +# dart 1.19.1, built from https://github.com/Workiva/smithy-runner-dart/tree/0.0.4 +runner_image: drydock-prod.workiva.org/workiva/smithy-runner-dart:74173 + +script: + - pub get + - pub run dart_dev format --check + - pub run dart_dev analyze + - pub run dart_dev test + +after_script: + - pub run dart_dev docs --no-open + - cd doc/api && tar -zcvf api.tar.gz * && cd ../.. + - tar czvf platform_detect.pub.tgz LICENSE README.md pubspec.yaml lib/ + +artifacts: + build: + - ./pubspec.lock + documentation: + - ./doc/api/api.tar.gz + pub: + - ./platform_detect.pub.tgz \ No newline at end of file diff --git a/test/browser_test.dart b/test/browser_test.dart new file mode 100644 index 0000000..bd1df2f --- /dev/null +++ b/test/browser_test.dart @@ -0,0 +1,100 @@ +@TestOn('vm') +import 'package:platform_detect/src/browser.dart'; +import 'package:platform_detect/src/navigator.dart'; +import 'package:pub_semver/pub_semver.dart'; +import 'package:test/test.dart'; + +void main() { + group('browser detects', () { + tearDown(() { + Browser.navigator = null; + }); + + test('Unknown Browser', () { + Browser.navigator = new TestNavigator(); + var browser = Browser.getCurrentBrowser(); + expect(browser.name, Browser.UnknownBrowser.name); + expect(browser.version, Browser.UnknownBrowser.version); + expect(browser.isChrome, false); + expect(browser.isFirefox, false); + expect(browser.isSafari, false); + expect(browser.isInternetExplorer, false); + }); + + test('Fake Browser', () { + Browser browser = new Browser( + 'Fake', (_) => true, (_) => new Version(1, 1, 0)); + expect(browser.name, 'Fake'); + expect(browser.version, new Version(1, 1, 0)); + expect(browser.isChrome, false); + expect(browser.isFirefox, false); + expect(browser.isSafari, false); + expect(browser.isInternetExplorer, false); + }); + + test('Chrome', () { + var navigator = new TestNavigator() + ..userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36' + ..appVersion = '5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36' + ..vendor = 'Google Inc.'; + Browser.navigator = navigator; + Browser browser = Browser.getCurrentBrowser(); + + expect(browser.name, 'Chrome'); + expect(browser.isChrome, true); + expect(browser.isFirefox, false); + expect(browser.isSafari, false); + expect(browser.isInternetExplorer, false); + expect(browser.version, new Version(53, 0, 2785, build: '143')); + }); + + test('Internet Explorer', () { + var navigator = new TestNavigator() + ..userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko' + ..appVersion = '5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko' + ..appName = 'Netscape'; + Browser.navigator = navigator; + Browser browser = Browser.getCurrentBrowser(); + + expect(browser.name, 'Internet Explorer'); + expect(browser.isChrome, false); + expect(browser.isFirefox, false); + expect(browser.isSafari, false); + expect(browser.isInternetExplorer, true); + expect(browser.version, new Version(11, 0, 0)); + }); + + test('Firefox', () { + var navigator = new TestNavigator() + ..userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:48.0) Gecko/20100101 Firefox/48.0' + ..appVersion = '5.0 (Macintosh)' + ..appName = 'Netscape'; + Browser.navigator = navigator; + Browser browser = Browser.getCurrentBrowser(); + + expect(browser.name, 'Firefox'); + expect(browser.isChrome, false); + expect(browser.isFirefox, true); + expect(browser.isSafari, false); + expect(browser.isInternetExplorer, false); + expect(browser.version, new Version(48, 0, 0)); + }); + + test('Safari', () { + var navigator = new TestNavigator() + ..vendor = 'Apple Computer, Inc.' + ..userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.8 (KHTML, like Gecko) Version/9.1.3 Safari/601.7.8' + ..appVersion = '5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.8 (KHTML, like Gecko) Version/9.1.3 Safari/601.7.8' + ..appName = 'Netscape'; + Browser.navigator = navigator; + Browser browser = Browser.getCurrentBrowser(); + + expect(browser.name, 'Safari'); + expect(browser.isChrome, false); + expect(browser.isFirefox, false); + expect(browser.isSafari, true); + expect(browser.isInternetExplorer, false); + expect(browser.version, new Version(9, 1, 3)); + }); + }); +} diff --git a/test/operating_system_test.dart b/test/operating_system_test.dart new file mode 100644 index 0000000..4e8e8a8 --- /dev/null +++ b/test/operating_system_test.dart @@ -0,0 +1,62 @@ +@TestOn('vm') +import 'package:platform_detect/src/operating_system.dart'; +import 'package:platform_detect/src/navigator.dart'; +import 'package:test/test.dart'; + +void main() { + group('operating system detects', () { + tearDown(() { + OperatingSystem.navigator = null; + }); + + test('Unknown Operating System', () { + OperatingSystem.navigator = new TestNavigator(); + var os = OperatingSystem.getCurrentOperatingSystem(); + expect(os.name, OperatingSystem.UnknownOS.name); + expect(os.isMac, false); + expect(os.isWindows, false); + expect(os.isUnix, false); + expect(os.isLinux, false); + }); + + test('Windows Operating System', () { + OperatingSystem.navigator = new TestNavigator()..appVersion = 'Windows'; + var os = OperatingSystem.getCurrentOperatingSystem(); + expect(os.name, 'Windows'); + expect(os.isMac, false); + expect(os.isWindows, true); + expect(os.isUnix, false); + expect(os.isLinux, false); + }); + + test('Mac Operating System', () { + OperatingSystem.navigator = new TestNavigator()..appVersion = 'Macintosh'; + var os = OperatingSystem.getCurrentOperatingSystem(); + expect(os.name, 'Mac'); + expect(os.isMac, true); + expect(os.isWindows, false); + expect(os.isUnix, false); + expect(os.isLinux, false); + }); + + test('Unix Operating System', () { + OperatingSystem.navigator = new TestNavigator()..appVersion = 'X11'; + var os = OperatingSystem.getCurrentOperatingSystem(); + expect(os.name, 'Unix'); + expect(os.isMac, false); + expect(os.isWindows, false); + expect(os.isUnix, true); + expect(os.isLinux, false); + }); + + test('Linux Operating System', () { + OperatingSystem.navigator = new TestNavigator()..appVersion = 'Linux'; + var os = OperatingSystem.getCurrentOperatingSystem(); + expect(os.name, 'Linux'); + expect(os.isMac, false); + expect(os.isWindows, false); + expect(os.isUnix, false); + expect(os.isLinux, true); + }); + }); +} From 99427817df4419521c4b601cd03887c7780e1b33 Mon Sep 17 00:00:00 2001 From: Travis Sanderson Date: Thu, 6 Oct 2016 20:44:18 -0500 Subject: [PATCH 2/4] Initial implementation of detecting browser and operating system --- README.md | 24 +++++++++++++----------- pubspec.yaml | 1 + 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 404a1ef..74b71d1 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,16 @@ A library for detecting browser and platform type and version. A simple usage example: - import 'package:platform_detect/platform_detect.dart'; - - main() { - var awesome = new Awesome(); - } - -## Features and bugs - -Please file feature requests and bugs at the [issue tracker][tracker]. - -[tracker]: http://example.com/issues/replaceme +```dart +import 'package:platform_detect/platform_detect.dart'; + +main() { + if (browser.isChrome) { + print('thank you for being a friend'); + } + + if (operatingSystem.isMac) { + print(''); + } +} +``` diff --git a/pubspec.yaml b/pubspec.yaml index 43cb5d3..6c1cbbf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,6 +13,7 @@ dependencies: pub_semver: ^1.0.0 dev_dependencies: + dartdoc: ^0.9.7 dart_style: 0.2.10 coverage: ^0.7.9 browser: any From 9abcae92398a3d5cc51423bc7c12228b92f7fcbc Mon Sep 17 00:00:00 2001 From: Travis Sanderson Date: Fri, 7 Oct 2016 10:09:14 -0500 Subject: [PATCH 3/4] Expand the example app to facilitate easily testing other navigator string values --- example/index.html | 32 ++++++++++++++++++++++++++++++-- example/main.dart | 27 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/example/index.html b/example/index.html index a70f90e..1fab873 100644 --- a/example/index.html +++ b/example/index.html @@ -6,7 +6,8 @@
-

Your Browser:

+

Current platform

+

Your Browser:

  • @@ -21,7 +22,34 @@

    Your Browser:

    Version:
    -

    Your Operating System:

    +

    Your Operating System:

    + +

    Test other values

    + + + + + + + + + + + + + + + + + +
    vendor
    appVersion
    appName
    userAgent
    + +

    Evaluates to:

    +
      +
    • +
    • +
    • +
diff --git a/example/main.dart b/example/main.dart index 6c3802d..8712337 100644 --- a/example/main.dart +++ b/example/main.dart @@ -1,7 +1,16 @@ import 'dart:html'; +import 'package:platform_detect/src/navigator.dart'; +import 'package:platform_detect/src/browser.dart'; +import 'package:platform_detect/src/operating_system.dart'; import 'package:platform_detect/platform_detect.dart'; main() { + _parseCurrentBrowser(); + ButtonElement evaluate = querySelector('#evaluate-test'); + evaluate.onClick.listen((_) => _parseTestValues()); +} + +void _parseCurrentBrowser() { document.querySelector('#current-browser').text = browser.name; document.querySelector('#current-vendor').text = window.navigator.vendor; document.querySelector('#current-appVersion').text = window.navigator.appVersion; @@ -24,3 +33,21 @@ main() { document.querySelector('#current-os').text = operatingSystem.name; } + +void _parseTestValues() { + InputElement testVendor = querySelector('#test-vendor'); + InputElement testAppVersion = querySelector('#test-appVersion'); + InputElement testAppName = querySelector('#test-appName'); + InputElement testUserAgent = querySelector('#test-userAgent'); + var navigator = new TestNavigator(); + navigator.vendor = testVendor.value.trim(); + navigator.appVersion = testAppVersion.value.trim(); + navigator.appName = testAppName.value.trim(); + navigator.userAgent = testUserAgent.value.trim(); + Browser.navigator = navigator; + OperatingSystem.navigator = navigator; + + querySelector('#test-browser-name').text = browser.name; + querySelector('#test-browser-version').text = browser.version.toString(); + querySelector('#test-os-name').text = operatingSystem.name; +} \ No newline at end of file From e3e80a8039d026b8f185dd985de26da72d466a0c Mon Sep 17 00:00:00 2001 From: Travis Sanderson Date: Fri, 7 Oct 2016 10:32:41 -0500 Subject: [PATCH 4/4] Refactor to compartmentalize the specific browser a bit better to make it easier to follow --- lib/src/browser.dart | 56 +++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/lib/src/browser.dart b/lib/src/browser.dart index 13bd5c9..1cf7304 100644 --- a/lib/src/browser.dart +++ b/lib/src/browser.dart @@ -49,11 +49,22 @@ class Browser { bool get isFirefox => this == _firefox; bool get isSafari => this == _safari; bool get isInternetExplorer => this == _internetExplorer; +} + +Browser _chrome = new _Chrome(); +Browser _firefox = new _Firefox(); +Browser _safari = new _Safari(); +Browser _internetExplorer = new _InternetExplorer(); + +class _Chrome extends Browser { + _Chrome() : super('Chrome', _isChrome, _getVersion); - static Browser _chrome = new Browser('Chrome', (NavigatorProvider navigator) { + static bool _isChrome(NavigatorProvider navigator) { var vendor = navigator.vendor; return vendor != null && vendor.contains('Google'); - }, (NavigatorProvider navigator) { + } + + static Version _getVersion(NavigatorProvider navigator) { Match match = new RegExp(r"Chrome/(\d+)\.(\d+)\.(\d+)\.(\d+)\s") .firstMatch(navigator.appVersion); var major = int.parse(match.group(1)); @@ -61,36 +72,53 @@ class Browser { var patch = int.parse(match.group(3)); var build = match.group(4); return new Version(major, minor, patch, build: build); - }); + } +} + +class _Firefox extends Browser { + _Firefox() : super('Firefox', _isFirefox, _getVersion); - static Browser _firefox = - new Browser('Firefox', (NavigatorProvider navigator) { + static bool _isFirefox(NavigatorProvider navigator) { return navigator.userAgent.contains('Firefox'); - }, (NavigatorProvider navigator) { + } + + static Version _getVersion(NavigatorProvider navigator) { Match match = new RegExp(r'rv:(\d+)\.(\d+)\)').firstMatch(navigator.userAgent); var major = int.parse(match.group(1)); var minor = int.parse(match.group(2)); return new Version(major, minor, 0); - }); + } +} + +class _Safari extends Browser { + _Safari() : super('Safari', _isSafari, _getVersion); - static Browser _safari = new Browser('Safari', (NavigatorProvider navigator) { + static bool _isSafari(NavigatorProvider navigator) { return navigator.vendor.contains('Apple'); - }, (NavigatorProvider navigator) { + } + + static Version _getVersion(NavigatorProvider navigator) { Match match = new RegExp(r'Version/(\d+)\.(\d+)\.(\d+)') .firstMatch(navigator.appVersion); var major = int.parse(match.group(1)); var minor = int.parse(match.group(2)); var patch = int.parse(match.group(3)); return new Version(major, minor, patch); - }); + } +} + +class _InternetExplorer extends Browser { + _InternetExplorer() + : super('Internet Explorer', _isInternetExplorer, _getVersion); - static Browser _internetExplorer = - new Browser('Internet Explorer', (NavigatorProvider navigator) { + static bool _isInternetExplorer(NavigatorProvider navigator) { return navigator.appName.contains('Microsoft') || navigator.appVersion.contains('Trident') || navigator.appVersion.contains('Edge'); - }, (NavigatorProvider navigator) { + } + + static Version _getVersion(NavigatorProvider navigator) { Match match = new RegExp(r'MSIE (\d+)\.(\d+);').firstMatch(navigator.appVersion); if (match != null) { @@ -114,5 +142,5 @@ class Browser { } return new Version(0, 0, 0); - }); + } }