# lib/goog/labs/useragent/util.js

1 | // Copyright 2013 The Closure Library Authors. All Rights Reserved.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS-IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | /**
16 | * @fileoverview Utilities used by goog.labs.userAgent tools. These functions
17 | * should not be used outside of goog.labs.userAgent.*.
18 | *
19 | *
20 | * @author nnaze@google.com (Nathan Naze)
21 | */
22 |
23 | goog.provide('goog.labs.userAgent.util');
24 |
25 | goog.require('goog.string');
26 |
27 |
28 | /**
29 | * Gets the native userAgent string from navigator if it exists.
30 | * If navigator or navigator.userAgent string is missing, returns an empty
31 | * string.
32 | * @return {string}
33 | * @private
34 | */
35 | goog.labs.userAgent.util.getNativeUserAgentString_ = function() {
36 | var navigator = goog.labs.userAgent.util.getNavigator_();
37 | if (navigator) {
38 | var userAgent = navigator.userAgent;
39 | if (userAgent) {
40 | return userAgent;
41 | }
42 | }
43 | return '';
44 | };
45 |
46 |
47 | /**
48 | * Getter for the native navigator.
49 | * This is a separate function so it can be stubbed out in testing.
50 | * @return {Navigator}
51 | * @private
52 | */
53 | goog.labs.userAgent.util.getNavigator_ = function() {
54 | return goog.global.navigator;
55 | };
56 |
57 |
58 | /**
59 | * A possible override for applications which wish to not check
60 | * navigator.userAgent but use a specified value for detection instead.
61 | * @private {string}
62 | */
63 | goog.labs.userAgent.util.userAgent_ =
64 | goog.labs.userAgent.util.getNativeUserAgentString_();
65 |
66 |
67 | /**
68 | * Applications may override browser detection on the built in
69 | * navigator.userAgent object by setting this string. Set to null to use the
70 | * browser object instead.
71 | * @param {?string=} opt_userAgent The User-Agent override.
72 | */
73 | goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) {
74 | goog.labs.userAgent.util.userAgent_ = opt_userAgent ||
75 | goog.labs.userAgent.util.getNativeUserAgentString_();
76 | };
77 |
78 |
79 | /**
80 | * @return {string} The user agent string.
81 | */
82 | goog.labs.userAgent.util.getUserAgent = function() {
83 | return goog.labs.userAgent.util.userAgent_;
84 | };
85 |
86 |
87 | /**
88 | * @param {string} str
89 | * @return {boolean} Whether the user agent contains the given string, ignoring
90 | * case.
91 | */
92 | goog.labs.userAgent.util.matchUserAgent = function(str) {
93 | var userAgent = goog.labs.userAgent.util.getUserAgent();
94 | return goog.string.contains(userAgent, str);
95 | };
96 |
97 |
98 | /**
99 | * @param {string} str
100 | * @return {boolean} Whether the user agent contains the given string.
101 | */
102 | goog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) {
103 | var userAgent = goog.labs.userAgent.util.getUserAgent();
104 | return goog.string.caseInsensitiveContains(userAgent, str);
105 | };
106 |
107 |
108 | /**
109 | * Parses the user agent into tuples for each section.
110 | * @param {string} userAgent
111 | * @return {!Array<!Array<string>>} Tuples of key, version, and the contents
112 | * of the parenthetical.
113 | */
114 | goog.labs.userAgent.util.extractVersionTuples = function(userAgent) {
115 | // Matches each section of a user agent string.
116 | // Example UA:
117 | // Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us)
118 | // AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405
119 | // This has three version tuples: Mozilla, AppleWebKit, and Mobile.
120 |
121 | var versionRegExp = new RegExp(
122 | // Key. Note that a key may have a space.
123 | // (i.e. 'Mobile Safari' in 'Mobile Safari/5.0')
124 | '(\\w[\\w ]+)' +
125 |
126 | '/' + // slash
127 | '([^\\s]+)' + // version (i.e. '5.0b')
128 | '\\s*' + // whitespace
129 | '(?:\\((.*?)\\))?', // parenthetical info. parentheses not matched.
130 | 'g');
131 |
132 | var data = [];
133 | var match;
134 |
135 | // Iterate and collect the version tuples. Each iteration will be the
136 | // next regex match.
137 | while (match = versionRegExp.exec(userAgent)) {
138 | data.push([
139 | match[1], // key
140 | match[2], // value
141 | // || undefined as this is not undefined in IE7 and IE8
142 | match[3] || undefined // info
143 | ]);
144 | }
145 |
146 | return data;
147 | };
148 |