Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/useragent/useragent.js
4504 views
1
/**
2
* @license
3
* Copyright The Closure Library Authors.
4
* SPDX-License-Identifier: Apache-2.0
5
*/
6
7
/**
8
* @fileoverview Rendering engine detection.
9
* @see <a href="http://www.useragentstring.com/">User agent strings</a>
10
* For information on the browser brand (such as Safari versus Chrome), see
11
* goog.userAgent.product.
12
* @see ../demos/useragent.html
13
*/
14
15
goog.provide('goog.userAgent');
16
17
goog.require('goog.labs.userAgent.browser');
18
goog.require('goog.labs.userAgent.engine');
19
goog.require('goog.labs.userAgent.platform');
20
goog.require('goog.labs.userAgent.util');
21
goog.require('goog.reflect');
22
goog.require('goog.string.internal');
23
24
25
/**
26
* @define {boolean} Whether we know at compile-time that the browser is IE.
27
*/
28
goog.userAgent.ASSUME_IE = goog.define('goog.userAgent.ASSUME_IE', false);
29
30
31
/**
32
* @define {boolean} Whether we know at compile-time that the browser is EDGE,
33
* referring to EdgeHTML based Edge.
34
*/
35
goog.userAgent.ASSUME_EDGE = goog.define('goog.userAgent.ASSUME_EDGE', false);
36
37
38
/**
39
* @define {boolean} Whether we know at compile-time that the browser is GECKO.
40
*/
41
goog.userAgent.ASSUME_GECKO = goog.define('goog.userAgent.ASSUME_GECKO', false);
42
43
44
/**
45
* @define {boolean} Whether we know at compile-time that the browser is WEBKIT.
46
*/
47
goog.userAgent.ASSUME_WEBKIT =
48
goog.define('goog.userAgent.ASSUME_WEBKIT', false);
49
50
51
/**
52
* @define {boolean} Whether we know at compile-time that the browser is a
53
* mobile device running WebKit e.g. iPhone or Android.
54
*/
55
goog.userAgent.ASSUME_MOBILE_WEBKIT =
56
goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false);
57
58
59
/**
60
* @define {boolean} Whether we know at compile-time that the browser is OPERA,
61
* referring to Presto-based Opera.
62
*/
63
goog.userAgent.ASSUME_OPERA = goog.define('goog.userAgent.ASSUME_OPERA', false);
64
65
66
/**
67
* @define {boolean} Whether the
68
* `goog.userAgent.isVersionOrHigher`
69
* function will return true for any version.
70
*/
71
goog.userAgent.ASSUME_ANY_VERSION =
72
goog.define('goog.userAgent.ASSUME_ANY_VERSION', false);
73
74
75
/**
76
* Whether we know the browser engine at compile-time.
77
* @type {boolean}
78
* @private
79
*/
80
goog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE ||
81
goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_GECKO ||
82
goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT ||
83
goog.userAgent.ASSUME_OPERA;
84
85
86
/**
87
* Returns the userAgent string for the current browser.
88
*
89
* @return {string} The userAgent string.
90
*/
91
goog.userAgent.getUserAgentString = function() {
92
'use strict';
93
return goog.labs.userAgent.util.getUserAgent();
94
};
95
96
97
/**
98
* @return {?Navigator} The native navigator object.
99
*/
100
goog.userAgent.getNavigatorTyped = function() {
101
'use strict';
102
// Need a local navigator reference instead of using the global one,
103
// to avoid the rare case where they reference different objects.
104
// (in a WorkerPool, for example).
105
return goog.global['navigator'] || null;
106
};
107
108
109
/**
110
* TODO(nnaze): Change type to "Navigator" and update compilation targets.
111
* @return {?Object} The native navigator object.
112
*/
113
goog.userAgent.getNavigator = function() {
114
'use strict';
115
return goog.userAgent.getNavigatorTyped();
116
};
117
118
119
/**
120
* Whether the user agent is Presto-based Opera.
121
* @type {boolean}
122
*/
123
goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ?
124
goog.userAgent.ASSUME_OPERA :
125
goog.labs.userAgent.browser.isOpera();
126
127
128
/**
129
* Whether the user agent is Internet Explorer.
130
* @type {boolean}
131
*/
132
goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ?
133
goog.userAgent.ASSUME_IE :
134
goog.labs.userAgent.browser.isIE();
135
136
137
/**
138
* Whether the user agent is Microsoft Edge (EdgeHTML based).
139
* @type {boolean}
140
*/
141
goog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ?
142
goog.userAgent.ASSUME_EDGE :
143
goog.labs.userAgent.engine.isEdge();
144
145
146
/**
147
* Whether the user agent is MS Internet Explorer or MS Edge (EdgeHTML based).
148
* @type {boolean}
149
*/
150
goog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE;
151
152
153
/**
154
* Whether the user agent is Gecko. Gecko is the rendering engine used by
155
* Mozilla, Firefox, and others.
156
* @type {boolean}
157
*/
158
goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ?
159
goog.userAgent.ASSUME_GECKO :
160
goog.labs.userAgent.engine.isGecko();
161
162
163
/**
164
* Whether the user agent is WebKit. WebKit is the rendering engine that
165
* Safari, Edge Chromium, Opera Chromium, Android and others use.
166
* @type {boolean}
167
*/
168
goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ?
169
goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT :
170
goog.labs.userAgent.engine.isWebKit();
171
172
173
/**
174
* Whether the user agent is running on a mobile device.
175
*
176
* This is a separate function so that the logic can be tested.
177
*
178
* TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile().
179
*
180
* @return {boolean} Whether the user agent is running on a mobile device.
181
* @private
182
*/
183
goog.userAgent.isMobile_ = function() {
184
'use strict';
185
return goog.userAgent.WEBKIT &&
186
goog.labs.userAgent.util.matchUserAgent('Mobile');
187
};
188
189
190
/**
191
* Whether the user agent is running on a mobile device.
192
*
193
* TODO(nnaze): Consider deprecating MOBILE when labs.userAgent
194
* is promoted as the gecko/webkit logic is likely inaccurate.
195
*
196
* @type {boolean}
197
*/
198
goog.userAgent.MOBILE =
199
goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_();
200
201
202
/**
203
* Used while transitioning code to use WEBKIT instead.
204
* @type {boolean}
205
* @deprecated Use {@link goog.userAgent.product.SAFARI} instead.
206
* TODO(nicksantos): Delete this from goog.userAgent.
207
*/
208
goog.userAgent.SAFARI = goog.userAgent.WEBKIT;
209
210
211
/**
212
* @return {string} the platform (operating system) the user agent is running
213
* on. Default to empty string because navigator.platform may not be defined
214
* (on Rhino, for example).
215
* @private
216
*/
217
goog.userAgent.determinePlatform_ = function() {
218
'use strict';
219
var navigator = goog.userAgent.getNavigatorTyped();
220
return navigator && navigator.platform || '';
221
};
222
223
224
/**
225
* The platform (operating system) the user agent is running on. Default to
226
* empty string because navigator.platform may not be defined (on Rhino, for
227
* example).
228
* @type {string}
229
*/
230
goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();
231
232
233
/**
234
* @define {boolean} Whether the user agent is running on a Macintosh operating
235
* system.
236
*/
237
goog.userAgent.ASSUME_MAC = goog.define('goog.userAgent.ASSUME_MAC', false);
238
239
240
/**
241
* @define {boolean} Whether the user agent is running on a Windows operating
242
* system.
243
*/
244
goog.userAgent.ASSUME_WINDOWS =
245
goog.define('goog.userAgent.ASSUME_WINDOWS', false);
246
247
248
/**
249
* @define {boolean} Whether the user agent is running on a Linux operating
250
* system.
251
*/
252
goog.userAgent.ASSUME_LINUX = goog.define('goog.userAgent.ASSUME_LINUX', false);
253
254
255
/**
256
* @define {boolean} Whether the user agent is running on a X11 windowing
257
* system.
258
*/
259
goog.userAgent.ASSUME_X11 = goog.define('goog.userAgent.ASSUME_X11', false);
260
261
262
/**
263
* @define {boolean} Whether the user agent is running on Android.
264
*/
265
goog.userAgent.ASSUME_ANDROID =
266
goog.define('goog.userAgent.ASSUME_ANDROID', false);
267
268
269
/**
270
* @define {boolean} Whether the user agent is running on an iPhone.
271
*/
272
goog.userAgent.ASSUME_IPHONE =
273
goog.define('goog.userAgent.ASSUME_IPHONE', false);
274
275
276
/**
277
* @define {boolean} Whether the user agent is running on an iPad.
278
*/
279
goog.userAgent.ASSUME_IPAD = goog.define('goog.userAgent.ASSUME_IPAD', false);
280
281
282
/**
283
* @define {boolean} Whether the user agent is running on an iPod.
284
*/
285
goog.userAgent.ASSUME_IPOD = goog.define('goog.userAgent.ASSUME_IPOD', false);
286
287
288
/**
289
* @define {boolean} Whether the user agent is running on KaiOS.
290
*/
291
goog.userAgent.ASSUME_KAIOS = goog.define('goog.userAgent.ASSUME_KAIOS', false);
292
293
294
/**
295
* @type {boolean}
296
* @private
297
*/
298
goog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC ||
299
goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX ||
300
goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID ||
301
goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||
302
goog.userAgent.ASSUME_IPOD;
303
304
305
/**
306
* Whether the user agent is running on a Macintosh operating system.
307
* @type {boolean}
308
*/
309
goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ?
310
goog.userAgent.ASSUME_MAC :
311
goog.labs.userAgent.platform.isMacintosh();
312
313
314
/**
315
* Whether the user agent is running on a Windows operating system.
316
* @type {boolean}
317
*/
318
goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ?
319
goog.userAgent.ASSUME_WINDOWS :
320
goog.labs.userAgent.platform.isWindows();
321
322
323
/**
324
* Whether the user agent is Linux per the legacy behavior of
325
* goog.userAgent.LINUX, which considered ChromeOS to also be
326
* Linux.
327
* @return {boolean}
328
* @private
329
*/
330
goog.userAgent.isLegacyLinux_ = function() {
331
'use strict';
332
return goog.labs.userAgent.platform.isLinux() ||
333
goog.labs.userAgent.platform.isChromeOS();
334
};
335
336
337
/**
338
* Whether the user agent is running on a Linux operating system.
339
*
340
* Note that goog.userAgent.LINUX considers ChromeOS to be Linux,
341
* while goog.labs.userAgent.platform considers ChromeOS and
342
* Linux to be different OSes.
343
*
344
* @type {boolean}
345
*/
346
goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ?
347
goog.userAgent.ASSUME_LINUX :
348
goog.userAgent.isLegacyLinux_();
349
350
351
/**
352
* @return {boolean} Whether the user agent is an X11 windowing system.
353
* @private
354
*/
355
goog.userAgent.isX11_ = function() {
356
'use strict';
357
var navigator = goog.userAgent.getNavigatorTyped();
358
return !!navigator &&
359
goog.string.internal.contains(navigator['appVersion'] || '', 'X11');
360
};
361
362
363
/**
364
* Whether the user agent is running on a X11 windowing system.
365
* @type {boolean}
366
*/
367
goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ?
368
goog.userAgent.ASSUME_X11 :
369
goog.userAgent.isX11_();
370
371
372
/**
373
* Whether the user agent is running on Android.
374
* @type {boolean}
375
*/
376
goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ?
377
goog.userAgent.ASSUME_ANDROID :
378
goog.labs.userAgent.platform.isAndroid();
379
380
381
/**
382
* Whether the user agent is running on an iPhone.
383
* @type {boolean}
384
*/
385
goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ?
386
goog.userAgent.ASSUME_IPHONE :
387
goog.labs.userAgent.platform.isIphone();
388
389
390
/**
391
* Whether the user agent is running on an iPad.
392
* @type {boolean}
393
*/
394
goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ?
395
goog.userAgent.ASSUME_IPAD :
396
goog.labs.userAgent.platform.isIpad();
397
398
399
/**
400
* Whether the user agent is running on an iPod.
401
* @type {boolean}
402
*/
403
goog.userAgent.IPOD = goog.userAgent.PLATFORM_KNOWN_ ?
404
goog.userAgent.ASSUME_IPOD :
405
goog.labs.userAgent.platform.isIpod();
406
407
408
/**
409
* Whether the user agent is running on iOS.
410
* @type {boolean}
411
*/
412
goog.userAgent.IOS = goog.userAgent.PLATFORM_KNOWN_ ?
413
(goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||
414
goog.userAgent.ASSUME_IPOD) :
415
goog.labs.userAgent.platform.isIos();
416
417
/**
418
* Whether the user agent is running on KaiOS.
419
* @type {boolean}
420
*/
421
goog.userAgent.KAIOS = goog.userAgent.PLATFORM_KNOWN_ ?
422
goog.userAgent.ASSUME_KAIOS :
423
goog.labs.userAgent.platform.isKaiOS();
424
425
426
/**
427
* @return {string} The string that describes the version number of the user
428
* agent.
429
* @private
430
*/
431
goog.userAgent.determineVersion_ = function() {
432
'use strict';
433
// All browsers have different ways to detect the version and they all have
434
// different naming schemes.
435
// version is a string rather than a number because it may contain 'b', 'a',
436
// and so on.
437
var version = '';
438
var arr = goog.userAgent.getVersionRegexResult_();
439
if (arr) {
440
version = arr ? arr[1] : '';
441
}
442
443
if (goog.userAgent.IE) {
444
// IE9 can be in document mode 9 but be reporting an inconsistent user agent
445
// version. If it is identifying as a version lower than 9 we take the
446
// documentMode as the version instead. IE8 has similar behavior.
447
// It is recommended to set the X-UA-Compatible header to ensure that IE9
448
// uses documentMode 9.
449
var docMode = goog.userAgent.getDocumentMode_();
450
if (docMode != null && docMode > parseFloat(version)) {
451
return String(docMode);
452
}
453
}
454
455
return version;
456
};
457
458
459
/**
460
* @return {?IArrayLike<string>|undefined} The version regex matches from
461
* parsing the user
462
* agent string. These regex statements must be executed inline so they can
463
* be compiled out by the closure compiler with the rest of the useragent
464
* detection logic when ASSUME_* is specified.
465
* @private
466
*/
467
goog.userAgent.getVersionRegexResult_ = function() {
468
'use strict';
469
var userAgent = goog.userAgent.getUserAgentString();
470
if (goog.userAgent.GECKO) {
471
return /rv\:([^\);]+)(\)|;)/.exec(userAgent);
472
}
473
if (goog.userAgent.EDGE) {
474
return /Edge\/([\d\.]+)/.exec(userAgent);
475
}
476
if (goog.userAgent.IE) {
477
return /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(userAgent);
478
}
479
if (goog.userAgent.WEBKIT) {
480
// WebKit/125.4
481
return /WebKit\/(\S+)/.exec(userAgent);
482
}
483
if (goog.userAgent.OPERA) {
484
// If none of the above browsers were detected but the browser is Opera, the
485
// only string that is of interest is 'Version/<number>'.
486
return /(?:Version)[ \/]?(\S+)/.exec(userAgent);
487
}
488
return undefined;
489
};
490
491
492
/**
493
* @return {number|undefined} Returns the document mode (for testing).
494
* @private
495
*/
496
goog.userAgent.getDocumentMode_ = function() {
497
'use strict';
498
// NOTE(user): goog.userAgent may be used in context where there is no DOM.
499
var doc = goog.global['document'];
500
return doc ? doc['documentMode'] : undefined;
501
};
502
503
504
/**
505
* The version of the user agent. This is a string because it might contain
506
* 'b' (as in beta) as well as multiple dots.
507
* @type {string}
508
*/
509
goog.userAgent.VERSION = goog.userAgent.determineVersion_();
510
511
512
/**
513
* Compares two version numbers.
514
*
515
* @param {string} v1 Version of first item.
516
* @param {string} v2 Version of second item.
517
*
518
* @return {number} 1 if first argument is higher
519
* 0 if arguments are equal
520
* -1 if second argument is higher.
521
* @deprecated Use goog.string.compareVersions.
522
*/
523
goog.userAgent.compare = function(v1, v2) {
524
'use strict';
525
return goog.string.internal.compareVersions(v1, v2);
526
};
527
528
529
/**
530
* Cache for {@link goog.userAgent.isVersionOrHigher}.
531
* Calls to compareVersions are surprisingly expensive and, as a browser's
532
* version number is unlikely to change during a session, we cache the results.
533
* @const
534
* @private
535
*/
536
goog.userAgent.isVersionOrHigherCache_ = {};
537
538
539
/**
540
* Whether the user agent version is higher or the same as the given version.
541
* NOTE: When checking the version numbers for Firefox and Safari, be sure to
542
* use the engine's version, not the browser's version number. For example,
543
* Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11.
544
* Opera and Internet Explorer versions match the product release number.<br>
545
* @see <a href="http://en.wikipedia.org/wiki/Safari_version_history">
546
* Webkit</a>
547
* @see <a href="http://en.wikipedia.org/wiki/Gecko_engine">Gecko</a>
548
*
549
* @param {string|number} version The version to check.
550
* @return {boolean} Whether the user agent version is higher or the same as
551
* the given version.
552
*/
553
goog.userAgent.isVersionOrHigher = function(version) {
554
'use strict';
555
return goog.userAgent.ASSUME_ANY_VERSION ||
556
goog.reflect.cache(
557
goog.userAgent.isVersionOrHigherCache_, version, function() {
558
'use strict';
559
return goog.string.internal.compareVersions(
560
goog.userAgent.VERSION, version) >= 0;
561
});
562
};
563
564
565
/**
566
* Whether the IE effective document mode is higher or the same as the given
567
* document mode version.
568
* NOTE: Only for IE, return false for another browser.
569
*
570
* @param {number} documentMode The document mode version to check.
571
* @return {boolean} Whether the IE effective document mode is higher or the
572
* same as the given version.
573
*/
574
goog.userAgent.isDocumentModeOrHigher = function(documentMode) {
575
'use strict';
576
return Number(goog.userAgent.DOCUMENT_MODE) >= documentMode;
577
};
578
579
580
/**
581
* Deprecated alias to `goog.userAgent.isDocumentModeOrHigher`.
582
* @param {number} version The version to check.
583
* @return {boolean} Whether the IE effective document mode is higher or the
584
* same as the given version.
585
* @deprecated Use goog.userAgent.isDocumentModeOrHigher().
586
*/
587
goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;
588
589
590
/**
591
* For IE version < 7, documentMode is undefined, so attempt to use the
592
* CSS1Compat property to see if we are in standards mode. If we are in
593
* standards mode, treat the browser version as the document mode. Otherwise,
594
* IE is emulating version 5.
595
*
596
* NOTE(user): Support for IE < 7 is long gone, so this is now simplified.
597
* It returns document.documentMode for IE and undefined for everything else.
598
*
599
* @type {number|undefined}
600
* @const
601
*/
602
goog.userAgent.DOCUMENT_MODE = (function() {
603
'use strict';
604
var doc = goog.global['document'];
605
if (!doc || !goog.userAgent.IE) return undefined;
606
// This must be an IE user agent.
607
var documentMode = goog.userAgent.getDocumentMode_();
608
if (documentMode) return documentMode;
609
// The user agent version string begins with the major version.
610
// Parse the major version and truncate anything following.
611
var ieVersion = parseInt(goog.userAgent.VERSION, 10);
612
return ieVersion || undefined;
613
})();
614
615