# lib/atoms/userAgent.js

1 | // Copyright 2011 WebDriver committers
2 | // Copyright 2011 Google Inc.
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 |
16 | /**
17 | * @fileoverview Similar to goog.userAgent.isVersion, but with support for
18 | * getting the version information when running in a firefox extension.
19 | */
20 | goog.provide('bot.userAgent');
21 |
22 | goog.require('goog.string');
23 | goog.require('goog.userAgent');
24 | goog.require('goog.userAgent.product');
25 | goog.require('goog.userAgent.product.isVersion');
26 |
27 |
28 | /**
29 | * Whether the rendering engine version of the current browser is equal to or
30 | * greater than the given version. This implementation differs from
31 | * goog.userAgent.isVersion in the following ways:
32 | * <ol>
33 | * <li>in a Firefox extension, tests the engine version through the XUL version
34 | * comparator service, because no window.navigator object is available
35 | * <li>in IE, compares the given version to the current documentMode
36 | * </ol>
37 | *
38 | * @param {string|number} version The version number to check.
39 | * @return {boolean} Whether the browser engine version is the same or higher
40 | * than the given version.
41 | */
42 | bot.userAgent.isEngineVersion = function(version) {
43 | if (bot.userAgent.FIREFOX_EXTENSION) {
44 | return bot.userAgent.FIREFOX_EXTENSION_IS_ENGINE_VERSION_(version);
45 | } else if (goog.userAgent.IE) {
46 | return goog.string.compareVersions(
47 | /** @type {number} */ (goog.userAgent.DOCUMENT_MODE), version) >= 0;
48 | } else {
49 | return goog.userAgent.isVersionOrHigher(version);
50 | }
51 | };
52 |
53 |
54 | /**
55 | * Whether the product version of the current browser is equal to or greater
56 | * than the given version. This implementation differs from
57 | * goog.userAgent.product.isVersion in the following ways:
58 | * <ol>
59 | * <li>in a Firefox extension, tests the product version through the XUL version
60 | * comparator service, because no window.navigator object is available
61 | * <li>on Android, always compares to the version to the OS version
62 | * </ol>
63 | *
64 | * @param {string|number} version The version number to check.
65 | * @return {boolean} Whether the browser product version is the same or higher
66 | * than the given version.
67 | */
68 | bot.userAgent.isProductVersion = function(version) {
69 | if (bot.userAgent.FIREFOX_EXTENSION) {
70 | return bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_(version);
71 | } else if (goog.userAgent.product.ANDROID) {
72 | return goog.string.compareVersions(
73 | bot.userAgent.ANDROID_VERSION_, version) >= 0;
74 | } else {
75 | return goog.userAgent.product.isVersion(version);
76 | }
77 | };
78 |
79 |
80 | /**
81 | * When we are in a Firefox extension, this is a function that accepts a version
82 | * and returns whether the version of Gecko we are on is the same or higher
83 | * than the given version. When we are not in a Firefox extension, this is null.
84 | * @private {(undefined|function((string|number)): boolean)}
85 | */
86 | bot.userAgent.FIREFOX_EXTENSION_IS_ENGINE_VERSION_;
87 |
88 |
89 | /**
90 | * When we are in a Firefox extension, this is a function that accepts a version
91 | * and returns whether the version of Firefox we are on is the same or higher
92 | * than the given version. When we are not in a Firefox extension, this is null.
93 | * @private {(undefined|function((string|number)): boolean)}
94 | */
95 | bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_;
96 |
97 |
98 | /**
99 | * Whether we are in a Firefox extension.
100 | *
101 | * @const
102 | * @type {boolean}
103 | */
104 | bot.userAgent.FIREFOX_EXTENSION = (function() {
105 | // False if this browser is not a Gecko browser.
106 | if (!goog.userAgent.GECKO) {
107 | return false;
108 | }
109 |
110 | // False if this code isn't running in an extension.
111 | var Components = goog.global.Components;
112 | if (!Components) {
113 | return false;
114 | }
115 | try {
116 | if (!Components['classes']) {
117 | return false;
118 | }
119 | } catch (e) {
120 | return false;
121 | }
122 |
123 | // Populate the version checker functions.
124 | var cc = Components['classes'];
125 | var ci = Components['interfaces'];
126 | var versionComparator = cc['@mozilla.org/xpcom/version-comparator;1'][
127 | 'getService'](ci['nsIVersionComparator']);
128 | var appInfo = cc['@mozilla.org/xre/app-info;1']['getService'](
129 | ci['nsIXULAppInfo']);
130 | var geckoVersion = appInfo['platformVersion'];
131 | var firefoxVersion = appInfo['version'];
132 |
133 | bot.userAgent.FIREFOX_EXTENSION_IS_ENGINE_VERSION_ = function(version) {
134 | return versionComparator.compare(geckoVersion, '' + version) >= 0;
135 | };
136 | bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_ = function(version) {
137 | return versionComparator.compare(firefoxVersion, '' + version) >= 0;
138 | };
139 |
140 | return true;
141 | })();
142 |
143 |
144 | /**
145 | * Whether we are on IOS.
146 | *
147 | * @const
148 | * @type {boolean}
149 | */
150 | bot.userAgent.IOS = goog.userAgent.product.IPAD ||
151 | goog.userAgent.product.IPHONE;
152 |
153 |
154 | /**
155 | * Whether we are on a mobile browser.
156 | *
157 | * @const
158 | * @type {boolean}
159 | */
160 | bot.userAgent.MOBILE = bot.userAgent.IOS || goog.userAgent.product.ANDROID;
161 |
162 |
163 | /**
164 | * Android Operating System Version.
165 | * @private {string}
166 | * @const
167 | */
168 | bot.userAgent.ANDROID_VERSION_ = (function() {
169 | if (goog.userAgent.product.ANDROID) {
170 | var userAgentString = goog.userAgent.getUserAgentString();
171 | var match = /Android\s+([0-9\.]+)/.exec(userAgentString);
172 | return match ? match[1] : '0';
173 | } else {
174 | return '0';
175 | }
176 | })();
177 |
178 |
179 | /**
180 | * Whether the current document is IE in a documentMode older than 8.
181 | * @type {boolean}
182 | * @const
183 | */
184 | bot.userAgent.IE_DOC_PRE8 = goog.userAgent.IE &&
185 | !goog.userAgent.isDocumentModeOrHigher(8);
186 |
187 |
188 | /**
189 | * Whether the current document is IE in IE9 (or newer) standards mode.
190 | * @type {boolean}
191 | * @const
192 | */
193 | bot.userAgent.IE_DOC_9 = goog.userAgent.isDocumentModeOrHigher(9);
194 |
195 |
196 | /**
197 | * Whether the current document is IE in a documentMode older than 9.
198 | * @type {boolean}
199 | * @const
200 | */
201 | bot.userAgent.IE_DOC_PRE9 = goog.userAgent.IE &&
202 | !goog.userAgent.isDocumentModeOrHigher(9);
203 |
204 |
205 | /**
206 | * Whether the current document is IE in IE10 (or newer) standards mode.
207 | * @type {boolean}
208 | * @const
209 | */
210 | bot.userAgent.IE_DOC_10 = goog.userAgent.isDocumentModeOrHigher(10);
211 |
212 |
213 | /**
214 | * Whether the current document is IE in a documentMode older than 10.
215 | * @type {boolean}
216 | * @const
217 | */
218 | bot.userAgent.IE_DOC_PRE10 = goog.userAgent.IE &&
219 | !goog.userAgent.isDocumentModeOrHigher(10);
220 |
221 |
222 | /**
223 | * Whether the current browser is Android pre-gingerbread.
224 | * @type {boolean}
225 | * @const
226 | */
227 | bot.userAgent.ANDROID_PRE_GINGERBREAD = goog.userAgent.product.ANDROID &&
228 | !bot.userAgent.isProductVersion(2.3);
229 |
230 |
231 | /**
232 | * Whether the current browser is Android pre-icecreamsandwich
233 | * @type {boolean}
234 | * @const
235 | */
236 | bot.userAgent.ANDROID_PRE_ICECREAMSANDWICH = goog.userAgent.product.ANDROID &&
237 | !bot.userAgent.isProductVersion(4);
238 |
239 |
240 | /**
241 | * Whether the current browser is Safari 6.
242 | * @type {boolean}
243 | * @const
244 | */
245 | bot.userAgent.SAFARI_6 = goog.userAgent.product.SAFARI &&
246 | bot.userAgent.isProductVersion(6);
247 |
248 |
249 | /**
250 | * Whether the current browser is Windows Phone.
251 | * @type {boolean}
252 | * @const
253 | */
254 | bot.userAgent.WINDOWS_PHONE = goog.userAgent.IE &&
255 | goog.userAgent.getUserAgentString().indexOf('IEMobile') != -1;