/**
* @class window.env.Browser
* Provides information about browser.
*
* Should not be manually instantiated unless for unit-testing.
* Access the global instance stored in {@link window.env.browser} instead.
* @private
*/
;(window.env || (window.env = {})).Browser = function (userAgent, publish) {
// @define window.env.Browser
// @define window.env.browser
function isEmpty (value, allowEmptyString) {
return (value === undefined || value === null) || (!allowEmptyString ? value === '' : false) || (isArray(value) && value.length === 0);
}
function isArray (value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
function apply (object, config, defaults) {
var enumerables = ['valueOf', 'toLocaleString', 'toString', 'constructor'];
if (defaults) {
apply(object, defaults);
}
if (object && config && typeof config === 'object') {
var i, j, k;
for (i in config) {
if (config.hasOwnProperty(i)) {
object[i] = config[i];
}
}
if (enumerables) {
for (j = enumerables.length; j--;) {
k = enumerables[j];
if (config.hasOwnProperty(k)) {
object[k] = config[k];
}
}
}
}
return object;
}
function getValues (object) {
var values = [],
property;
for (property in object) {
if (object.hasOwnProperty(property)) {
values.push(object[property]);
}
}
return values;
}
function getKey (object, value) {
for (var property in object) {
if (object.hasOwnProperty(property) && object[property] === value) {
return property;
}
}
return null;
}
function Version (version) {
var me = this,
padModes = me.padModes,
ch, i, pad, parts, release, releaseStartIndex, ver;
me.version = ver = String(version).toLowerCase().replace(/_/g, '.').replace(/[\-+]/g, '');
ch = ver.charAt(0);
if (ch in padModes) {
ver = ver.substring(1);
pad = padModes[ch];
} else {
pad = 0;
}
me.pad = pad;
releaseStartIndex = ver.search(/([^\d\.])/);
me.shortVersion = ver;
if (releaseStartIndex !== -1) {
me.release = release = ver.substr(releaseStartIndex, version.length);
me.shortVersion = ver.substr(0, releaseStartIndex);
release = Version.releaseValueMap[release] || release;
}
me.releaseValue = release || pad;
me.shortVersion = me.shortVersion.replace(/[^\d]/g, '');
/**
* @property {Number[]} parts
* The split array of version number components found in the version string.
* For example, for "1.2.3", this would be `[1, 2, 3]`.
* @readonly
* @private
*/
me.parts = parts = ver.split('.');
for (i = parts.length; i--;) {
parts[i] = parseInt(parts[i], 10);
}
if (pad === Infinity) {
// have to add this to the end to create an upper bound:
parts.push(pad);
}
/**
* @property {Number} major
* The first numeric part of the version number string.
* @readonly
*/
me.major = parts[0] || pad;
return me;
}
Version.releaseValueMap = {
dev: -6,
alpha: -5,
a: -5,
beta: -4,
b: -4,
rc: -3,
'#': -2,
p: -1,
pl: -1
};
Version.prototype = {
padModes: {
'~': NaN,
'^': Infinity
},
/**
* Returns the major component value.
* @return {Number}
*/
getMajor: function() {
return this.major;
},
/**
* Returns shortVersion version without dots and release
* @return {String}
*/
getShortVersion: function() {
return this.shortVersion;
}
};
var me = this,
browserPrefixes = {
ie: 'MSIE ',
edge: 'Edge/',
firefox: 'Firefox/',
chrome: 'Chrome/',
safari: 'Version/',
opera: 'OPR/',
dolfin: 'Dolfin/',
webosbrowser: 'wOSBrowser/',
chromeMobile: 'CrMo/',
chromeiOS: 'CriOS/',
silk: 'Silk/'
},
browserNames = {
ie: 'IE',
firefox: 'Firefox',
safari: 'Safari',
chrome: 'Chrome',
opera: 'Opera',
dolfin: 'Dolfin',
edge: 'Edge',
webosbrowser: 'webOSBrowser',
chromeMobile: 'ChromeMobile',
chromeiOS: 'ChromeiOS',
silk: 'Silk',
other: 'Other'
},
enginePrefixes = me.enginePrefixes,
engineNames = me.engineNames,
browserMatch = userAgent.match(new RegExp('((?:' + getValues(browserPrefixes).join(')|(?:') + '))([\\w\\._]+)')),
engineMatch = userAgent.match(new RegExp('((?:' + getValues(enginePrefixes).join(')|(?:') + '))([\\w\\._]+)')),
browserName = browserNames.other,
engineName = engineNames.other,
browserVersion = '',
engineVersion = '',
majorVer = '',
isWebView = false,
i, prefix, mode, name, maxIEVersion;
/**
* @property {String}
* Browser User Agent string.
*/
me.userAgent = userAgent;
/**
* A "hybrid" property, can be either accessed as a method call, for example:
*
* if (window.env.browser.is('IE')) {
* // ...
* }
*
* Or as an object with Boolean properties, for example:
*
* if (window.env.browser.is.IE) {
* // ...
* }
*
* Versions can be conveniently checked as well. For example:
*
* if (window.env.browser.is.IE10) {
* // Equivalent to (window.env.browser.is.IE && window.env.browser.version.equals(10))
* }
*
* __Note:__ Only {@link Version#getMajor major component} and {@link Version#getShortVersion simplified}
* value of the version are available via direct property checking.
*
* Supported values are:
*
* - IE
* - Firefox
* - Safari
* - Chrome
* - Opera
* - WebKit
* - Gecko
* - Presto
* - Trident
* - WebView
* - Other
*
* @param {String} name The OS name to check.
* @return {Boolean}
*/
this.is = function (name) {
// Since this function reference also acts as a map, we do not want it to be
// shared between instances, so it is defined here, not on the prototype.
return !!this.is[name];
};
// Edge has a userAgent with All browsers so we manage it separately
// "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240"
if (/Edge\//.test(userAgent)) {
browserMatch = userAgent.match(/(Edge\/)([\w.]+)/);
}
if (browserMatch) {
browserName = browserNames[getKey(browserPrefixes, browserMatch[1])];
//<feature legacyBrowser>
if (browserName === 'Safari' && /^Opera/.test(userAgent)) {
// Prevent Opera 12 and earlier from being incorrectly reported as Safari
browserName = 'Opera';
}
//</feature>
browserVersion = new Version(browserMatch[2]);
}
if (engineMatch) {
engineName = engineNames[getKey(enginePrefixes, engineMatch[1])];
engineVersion = new Version(engineMatch[2]);
}
if (engineName === 'Trident' && browserName !== 'IE') {
browserName = 'IE';
var version = userAgent.match(/.*rv:(\d+.\d+)/);
if (version && version.length) {
version = version[1];
browserVersion = new Version(version);
}
}
/**
* @property chromeVersion
* The current version of Chrome (0 if the browser is not Chrome).
* @readonly
* @type Number
*/
/**
* @property firefoxVersion
* The current version of Firefox (0 if the browser is not Firefox).
* @readonly
* @type Number
*/
/**
* @property ieVersion
* The current version of IE (0 if the browser is not IE). This does not account
* for the documentMode of the current page, which is factored into {@link #isIE8},
* and {@link #isIE9}. Thus this is not always true:
*
* window.env.isIE8 == (window.env.ieVersion == 8)
*
* @readonly
* @type Number
*/
/**
* @property isChrome
* True if the detected browser is Chrome.
* @readonly
* @type Boolean
*/
/**
* @property isGecko
* True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
* @readonly
* @type Boolean
*/
/**
* @property isIE
* True if the detected browser is Internet Explorer.
* @readonly
* @type Boolean
*/
/**
* @property isIE8
* True if the detected browser is Internet Explorer 8.x.
* @readonly
* @type Boolean
*/
/**
* @property isIE8m
* True if the detected browser is Internet Explorer 8.x or lower.
* @readonly
* @type Boolean
*/
/**
* @property isIE8p
* True if the detected browser is Internet Explorer 8.x or higher.
* @readonly
* @type Boolean
*/
/**
* @property isIE9
* True if the detected browser is Internet Explorer 9.x.
* @readonly
* @type Boolean
*/
/**
* @property isIE9m
* True if the detected browser is Internet Explorer 9.x or lower.
* @readonly
* @type Boolean
*/
/**
* @property isIE9p
* True if the detected browser is Internet Explorer 9.x or higher.
* @readonly
* @type Boolean
*/
/**
* @property isIE10
* True if the detected browser is Internet Explorer 10.x.
* @readonly
* @type Boolean
*/
/**
* @property isIE10m
* True if the detected browser is Internet Explorer 10.x or lower.
* @readonly
* @type Boolean
*/
/**
* @property isIE10p
* True if the detected browser is Internet Explorer 10.x or higher.
* @readonly
* @type Boolean
*/
/**
* @property isIE11
* True if the detected browser is Internet Explorer 11.x.
* @readonly
* @type Boolean
*/
/**
* @property isIE11m
* True if the detected browser is Internet Explorer 11.x or lower.
* @readonly
* @type Boolean
*/
/**
* @property isIE11p
* True if the detected browser is Internet Explorer 11.x or higher.
* @readonly
* @type Boolean
*/
/**
* @property isEdge
* True if the detected browser is Edge.
* @readonly
* @type Boolean
*/
/**
* @property isLinux
* True if the detected platform is Linux.
* @readonly
* @type Boolean
*/
/**
* @property isMac
* True if the detected platform is Mac OS.
* @readonly
* @type Boolean
*/
/**
* @property isOpera
* True if the detected browser is Opera.
* @readonly
* @type Boolean
*/
/**
* @property isSafari
* True if the detected browser is Safari.
* @readonly
* @type Boolean
*/
/**
* @property isWebKit
* True if the detected browser uses WebKit.
* @readonly
* @type Boolean
*/
/**
* @property isWindows
* True if the detected platform is Windows.
* @readonly
* @type Boolean
*/
/**
* @property operaVersion
* The current version of Opera (0 if the browser is not Opera).
* @readonly
* @type Number
*/
/**
* @property safariVersion
* The current version of Safari (0 if the browser is not Safari).
* @readonly
* @type Number
*/
/**
* @property webKitVersion
* The current version of WebKit (0 if the browser does not use WebKit).
* @readonly
* @type Number
*/
// Facebook changes the userAgent when you view a website within their iOS app. For some reason, the strip out information
// about the browser, so we have to detect that and fake it...
if (userAgent.match(/FB/) && browserName === "Other") {
browserName = browserNames.safari;
engineName = engineNames.webkit;
}
if (userAgent.match(/Android.*Chrome/g)) {
browserName = 'ChromeMobile';
}
if (userAgent.match(/OPR/)) {
browserName = 'Opera';
browserMatch = userAgent.match(/OPR\/(\d+.\d+)/);
browserVersion = new Version(browserMatch[1]);
}
apply(this, {
engineName: engineName,
engineVersion: engineVersion,
name: browserName,
version: browserVersion
});
this.setFlag(browserName, true, publish); // e.g., window.env.isIE
if (browserVersion) {
majorVer = browserVersion.getMajor() || '';
//<feature legacyBrowser>
if (me.is.IE) {
majorVer = parseInt(majorVer, 10);
mode = document.documentMode;
// IE's Developer Tools allows switching of Browser Mode (userAgent) and
// Document Mode (actual behavior) independently. While this makes no real
// sense, the bottom line is that document.documentMode holds the key to
// getting the proper "version" determined. That value is always 5 when in
// Quirks Mode.
if (mode === 7 || (majorVer === 7 && mode !== 8 && mode !== 9 && mode !== 10)) {
majorVer = 7;
} else if (mode === 8 || (majorVer === 8 && mode !== 8 && mode !== 9 && mode !== 10)) {
majorVer = 8;
} else if (mode === 9 || (majorVer === 9 && mode !== 7 && mode !== 8 && mode !== 10)) {
majorVer = 9;
} else if (mode === 10 || (majorVer === 10 && mode !== 7 && mode !== 8 && mode !== 9)) {
majorVer = 10;
} else if (mode === 11 || (majorVer === 11 && mode !== 7 && mode !== 8 && mode !== 9 && mode !== 10)) {
majorVer = 11;
}
maxIEVersion = Math.max(majorVer, 12);
for (i = 7; i <= maxIEVersion; ++i) {
prefix = 'isIE' + i;
if (majorVer <= i) {
window.env[prefix + 'm'] = true;
}
if (majorVer === i) {
window.env[prefix] = true;
}
if (majorVer >= i) {
window.env[prefix + 'p'] = true;
}
}
}
if (me.is.Opera && parseInt(majorVer, 10) <= 12) {
window.env.isOpera12m = true;
}
//</feature>
window.env.chromeVersion = window.env.isChrome ? majorVer : 0;
window.env.firefoxVersion = window.env.isFirefox ? majorVer : 0;
window.env.ieVersion = window.env.isIE ? majorVer : 0;
window.env.operaVersion = window.env.isOpera ? majorVer : 0;
window.env.safariVersion = window.env.isSafari ? majorVer : 0;
window.env.webKitVersion = window.env.isWebKit ? majorVer : 0;
this.setFlag(browserName + majorVer, true, publish); // window.env.isIE10
this.setFlag(browserName + browserVersion.getShortVersion());
}
for (i in browserNames) {
if (browserNames.hasOwnProperty(i)) {
name = browserNames[i];
this.setFlag(name, browserName === name);
}
}
this.setFlag(name);
if (engineVersion) {
this.setFlag(engineName + (engineVersion.getMajor() || ''));
this.setFlag(engineName + engineVersion.getShortVersion());
}
for (i in engineNames) {
if (engineNames.hasOwnProperty(i)) {
name = engineNames[i];
this.setFlag(name, engineName === name, publish);
}
}
this.setFlag('Standalone', !!navigator.standalone);
this.setFlag('Ripple', !!document.getElementById("tinyhippos-injected") && !isEmpty(window.top.ripple));
this.setFlag('WebWorks', !!window.blackberry);
if (window.PhoneGap !== undefined || window.Cordova !== undefined || window.cordova !== undefined) {
isWebView = true;
this.setFlag('PhoneGap');
this.setFlag('Cordova');
}
// Check if running in UIWebView
if (/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)(?!.*FBAN)/i.test(userAgent)) {
isWebView = true;
}
// Flag to check if it we are in the WebView
this.setFlag('WebView', isWebView);
/**
* @property {Boolean}
* `true` if browser is using strict mode.
*/
this.isStrict = window.env.isStrict = document.compatMode === "CSS1Compat";
/**
* @property {Boolean}
* `true` if page is running over SSL.
*/
this.isSecure = /^https/i.test(window.location.protocol);
// IE10Quirks, Chrome26Strict, etc.
this.identity = browserName + majorVer + (this.isStrict ? 'Strict' : 'Quirks');
};
window.env.Browser.prototype = {
constructor: window.env.Browser,
engineNames: {
webkit: 'WebKit',
gecko: 'Gecko',
presto: 'Presto',
trident: 'Trident',
other: 'Other'
},
enginePrefixes: {
webkit: 'AppleWebKit/',
gecko: 'Gecko/',
presto: 'Presto/',
trident: 'Trident/'
},
styleDashPrefixes: {
WebKit: '-webkit-',
Gecko: '-moz-',
Trident: '-ms-',
Presto: '-o-',
Other: ''
},
stylePrefixes: {
WebKit: 'Webkit',
Gecko: 'Moz',
Trident: 'ms',
Presto: 'O',
Other: ''
},
propertyPrefixes: {
WebKit: 'webkit',
Gecko: 'moz',
Trident: 'ms',
Presto: 'o',
Other: ''
},
// scope: window.env.Browser.prototype
/**
* The full name of the current browser.
* Possible values are:
*
* - IE
* - Firefox
* - Safari
* - Chrome
* - Opera
* - Other
* @type String
* @readonly
*/
name: null,
/**
* Refer to {@link Version}.
* @type Version
* @readonly
*/
version: null,
/**
* The full name of the current browser's engine.
* Possible values are:
*
* - WebKit
* - Gecko
* - Presto
* - Trident
* - Other
* @type String
* @readonly
*/
engineName: null,
/**
* Refer to {@link Version}.
* @type Version
* @readonly
*/
engineVersion: null,
setFlag: function(name, value, publish) {
if (value === undefined) {
value = true;
}
this.is[name] = value;
this.is[name.toLowerCase()] = value;
if (publish) {
window.env['is' + name] = value;
}
return this;
},
getStyleDashPrefix: function() {
return this.styleDashPrefixes[this.engineName];
},
getStylePrefix: function() {
return this.stylePrefixes[this.engineName];
},
getVendorProperyName: function(name) {
function capitalize (string) {
if (string) {
string = string.charAt(0).toUpperCase() + string.substr(1);
}
return string || '';
}
var prefix = this.propertyPrefixes[this.engineName];
if (prefix.length > 0) {
return prefix + capitalize(name);
}
return name;
},
getPreferredTranslationMethod: function(config) {
if (typeof config === 'object' && 'translationMethod' in config && config.translationMethod !== 'auto') {
return config.translationMethod;
} else {
return 'csstransform';
}
}
};
/**
* @class window.env.browser
* @extends window.env.Browser
* @singleton
* Provides useful information about the current browser.
*
* Example:
*
* if (window.env.browser.is.IE) {
* // IE specific code here
* }
*
* if (window.env.browser.is.WebKit) {
* // WebKit specific code here
* }
*
* console.log("Version " + window.env.browser.version);
*
* For a full list of supported values, refer to {@link #is} property/method.
*
*/
;(function (userAgent) {
window.env.browser = new window.env.Browser(userAgent, true);
window.env.userAgent = userAgent.toLowerCase();
/**
* @property {String} SSL_SECURE_URL
* URL to a blank file used when in secure mode for iframe src and onReady src
* to prevent the IE insecure content warning (`'about:blank'`, except for IE
* in secure mode, which is `'javascript:""'`).
*/
window.env.SSL_SECURE_URL = /^https/i.test(window.location.protocol) && window.env.isIE ? 'javascript:\'\'' : 'about:blank'; // jshint ignore:line
})(window.navigator.userAgent);
console.log(window.env.browser.name);
console.log(window.env.browser.version.version);
Комментариев нет:
Отправить комментарий