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; |