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 */
20goog.provide('bot.userAgent');
21
22goog.require('goog.string');
23goog.require('goog.userAgent');
24goog.require('goog.userAgent.product');
25goog.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 */
42bot.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 */
68bot.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 */
86bot.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 */
95bot.userAgent.FIREFOX_EXTENSION_IS_PRODUCT_VERSION_;
96
97
98/**
99 * Whether we are in a Firefox extension.
100 *
101 * @const
102 * @type {boolean}
103 */
104bot.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 */
150bot.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 */
160bot.userAgent.MOBILE = bot.userAgent.IOS || goog.userAgent.product.ANDROID;
161
162
163/**
164 * Android Operating System Version.
165 * @private {string}
166 * @const
167 */
168bot.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 */
184bot.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 */
193bot.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 */
201bot.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 */
210bot.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 */
218bot.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 */
227bot.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 */
236bot.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 */
245bot.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 */
254bot.userAgent.WINDOWS_PHONE = goog.userAgent.IE &&
255 goog.userAgent.getUserAgentString().indexOf('IEMobile') != -1;