@microsoft/applicationinsights-core-js
Version:
Microsoft Application Insights Core Javascript SDK
316 lines (314 loc) • 11.6 kB
JavaScript
/*
* Application Insights JavaScript SDK - Core, 3.3.9
* Copyright (c) Microsoft and contributors. All rights reserved.
*/
;
import { getGlobal, strShimObject, strShimPrototype, strShimUndefined } from "@microsoft/applicationinsights-shims";
import { getDocument, getInst, getNavigator, getPerformance, hasNavigator, isFunction, isString, isUndefined, mathMax, strIndexOf } from "@nevware21/ts-utils";
import { _DYN_LENGTH, _DYN_NAME, _DYN_SPLIT, _DYN_TO_LOWER_CASE, _DYN_USER_AGENT } from "../__DynamicConstants";
import { strContains } from "./HelperFuncs";
import { STR_EMPTY } from "./InternalConstants";
/**
* This file exists to hold environment utilities that are required to check and
* validate the current operating environment. Unless otherwise required, please
* only use defined methods (functions) in this class so that users of these
* functions/properties only need to include those that are used within their own modules.
*/
var strDocumentMode = "documentMode";
var strLocation = "location";
var strConsole = "console";
var strJSON = "JSON";
var strCrypto = "crypto";
var strMsCrypto = "msCrypto";
var strReactNative = "ReactNative";
var strMsie = "msie";
var strTrident = "trident/";
var strXMLHttpRequest = "XMLHttpRequest";
var _isTrident = null;
var _navUserAgentCheck = null;
var _enableMocks = false;
var _useXDomainRequest = null;
var _beaconsSupported = null;
function _hasProperty(theClass, property) {
var supported = false;
if (theClass) {
try {
supported = property in theClass;
if (!supported) {
var proto = theClass[strShimPrototype];
if (proto) {
supported = property in proto;
}
}
}
catch (e) {
// Do Nothing
}
if (!supported) {
try {
var tmp = new theClass();
supported = !isUndefined(tmp[property]);
}
catch (e) {
// Do Nothing
}
}
}
return supported;
}
/**
* Enable the lookup of test mock objects if requested
* @param enabled - A flag to enable or disable the mock
*/
export function setEnableEnvMocks(enabled) {
_enableMocks = enabled;
}
/**
* Returns the global location object if it is present otherwise null.
* This helper is used to access the location object without causing an exception
* "Uncaught ReferenceError: location is not defined"
*/
export function getLocation(checkForMock) {
if (checkForMock && _enableMocks) {
var mockLocation = getInst("__mockLocation");
if (mockLocation) {
return mockLocation;
}
}
if (typeof location === strShimObject && location) {
return location;
}
return getInst(strLocation);
}
/**
* Returns the global console object
*/
export function getConsole() {
if (typeof console !== strShimUndefined) {
return console;
}
return getInst(strConsole);
}
/**
* Checks if JSON object is available, this is required as we support the API running without a
* window /document (eg. Node server, electron webworkers) and if we attempt to assign a history
* object to a local variable or pass as an argument an "Uncaught ReferenceError: JSON is not defined"
* exception will be thrown.
* Defined as a function to support lazy / late binding environments.
*/
export function hasJSON() {
return Boolean((typeof JSON === strShimObject && JSON) || getInst(strJSON) !== null);
}
/**
* Returns the global JSON object if it is present otherwise null.
* This helper is used to access the JSON object without causing an exception
* "Uncaught ReferenceError: JSON is not defined"
*/
export function getJSON() {
if (hasJSON()) {
return JSON || getInst(strJSON);
}
return null;
}
/**
* Returns the crypto object if it is present otherwise null.
* This helper is used to access the crypto object from the current
* global instance which could be window or globalThis for a web worker
*/
export function getCrypto() {
return getInst(strCrypto);
}
/**
* Returns the crypto object if it is present otherwise null.
* This helper is used to access the crypto object from the current
* global instance which could be window or globalThis for a web worker
*/
export function getMsCrypto() {
return getInst(strMsCrypto);
}
/**
* Returns whether the environment is reporting that we are running in a React Native Environment
*/
export function isReactNative() {
// If running in React Native, navigator.product will be populated
var nav = getNavigator();
if (nav && nav.product) {
return nav.product === strReactNative;
}
return false;
}
/**
* Identifies whether the current environment appears to be IE
*/
export function isIE() {
var nav = getNavigator();
if (nav && (nav[_DYN_USER_AGENT /* @min:%2euserAgent */] !== _navUserAgentCheck || _isTrident === null)) {
// Added to support test mocking of the user agent
_navUserAgentCheck = nav[_DYN_USER_AGENT /* @min:%2euserAgent */];
var userAgent = (_navUserAgentCheck || STR_EMPTY)[_DYN_TO_LOWER_CASE /* @min:%2etoLowerCase */]();
_isTrident = (strContains(userAgent, strMsie) || strContains(userAgent, strTrident));
}
return _isTrident;
}
/**
* Gets IE version returning the document emulation mode if we are running on IE, or null otherwise
*/
export function getIEVersion(userAgentStr) {
if (userAgentStr === void 0) { userAgentStr = null; }
if (!userAgentStr) {
var navigator_1 = getNavigator() || {};
userAgentStr = navigator_1 ? (navigator_1.userAgent || STR_EMPTY)[_DYN_TO_LOWER_CASE /* @min:%2etoLowerCase */]() : STR_EMPTY;
}
var ua = (userAgentStr || STR_EMPTY)[_DYN_TO_LOWER_CASE /* @min:%2etoLowerCase */]();
// Also check for documentMode in case X-UA-Compatible meta tag was included in HTML.
if (strContains(ua, strMsie)) {
var doc = getDocument() || {};
return mathMax(parseInt(ua[_DYN_SPLIT /* @min:%2esplit */](strMsie)[1]), (doc[strDocumentMode] || 0));
}
else if (strContains(ua, strTrident)) {
var tridentVer = parseInt(ua[_DYN_SPLIT /* @min:%2esplit */](strTrident)[1]);
if (tridentVer) {
return tridentVer + 4;
}
}
return null;
}
export function isSafari(userAgentStr) {
if (!userAgentStr || !isString(userAgentStr)) {
var navigator_2 = getNavigator() || {};
userAgentStr = navigator_2 ? (navigator_2.userAgent || STR_EMPTY)[_DYN_TO_LOWER_CASE /* @min:%2etoLowerCase */]() : STR_EMPTY;
}
var ua = (userAgentStr || STR_EMPTY)[_DYN_TO_LOWER_CASE /* @min:%2etoLowerCase */]();
return (strIndexOf(ua, "safari") >= 0);
}
/**
* Checks if HTML5 Beacons are supported in the current environment.
* @param useCached - [Optional] used for testing to bypass the cached lookup, when `true` this will
* cause the cached global to be reset.
* @returns True if supported, false otherwise.
*/
export function isBeaconsSupported(useCached) {
if (_beaconsSupported === null || useCached === false) {
_beaconsSupported = hasNavigator() && Boolean(getNavigator().sendBeacon);
}
return _beaconsSupported;
}
/**
* Checks if the Fetch API is supported in the current environment.
* @param withKeepAlive - [Optional] If True, check if fetch is available and it supports the keepalive feature, otherwise only check if fetch is supported
* @returns True if supported, otherwise false
*/
export function isFetchSupported(withKeepAlive) {
var isSupported = false;
try {
isSupported = !!getInst("fetch");
var request = getInst("Request");
if (isSupported && withKeepAlive && request) {
isSupported = _hasProperty(request, "keepalive");
}
}
catch (e) {
// Just Swallow any failure during availability checks
}
return isSupported;
}
export function useXDomainRequest() {
if (_useXDomainRequest === null) {
_useXDomainRequest = (typeof XDomainRequest !== strShimUndefined);
if (_useXDomainRequest && isXhrSupported()) {
_useXDomainRequest = _useXDomainRequest && !_hasProperty(getInst(strXMLHttpRequest), "withCredentials");
}
}
return _useXDomainRequest;
}
/**
* Checks if XMLHttpRequest is supported
* @returns True if supported, otherwise false
*/
export function isXhrSupported() {
var isSupported = false;
try {
var xmlHttpRequest = getInst(strXMLHttpRequest);
isSupported = !!xmlHttpRequest;
}
catch (e) {
// Just Swallow any failure during availability checks
}
return isSupported;
}
function _getNamedValue(values, name) {
if (values) {
for (var i = 0; i < values[_DYN_LENGTH /* @min:%2elength */]; i++) {
var value = values[i];
if (value[_DYN_NAME /* @min:%2ename */]) {
if (value[_DYN_NAME /* @min:%2ename */] === name) {
return value;
}
}
}
}
return {};
}
/**
* Helper function to fetch the named meta-tag from the page.
* @param name - The name of the meta-tag to find.
*/
export function findMetaTag(name) {
var doc = getDocument();
if (doc && name) {
// Look for a meta-tag
return _getNamedValue(doc.querySelectorAll("meta"), name).content;
}
return null;
}
/**
* Helper function to fetch the named server timing value from the page response (first navigation event).
* @param name - The name of the server timing value to find.
*/
export function findNamedServerTiming(name) {
var value;
var perf = getPerformance();
if (perf) {
// Try looking for a server-timing header
var navPerf = perf.getEntriesByType("navigation") || [];
value = _getNamedValue((navPerf[_DYN_LENGTH /* @min:%2elength */] > 0 ? navPerf[0] : {}).serverTiming, name).description;
}
return value;
}
// TODO: should reuse this method for analytics plugin
export function dispatchEvent(target, evnt) {
if (target && target.dispatchEvent && evnt) {
target.dispatchEvent(evnt);
return true;
}
return false;
}
export function createCustomDomEvent(eventName, details) {
var event = null;
var detail = { detail: details || null };
if (isFunction(CustomEvent)) { // Use CustomEvent constructor when available
event = new CustomEvent(eventName, detail);
}
else { // CustomEvent has no constructor in IE
var doc = getDocument();
if (doc && doc.createEvent) {
event = doc.createEvent("CustomEvent");
event.initCustomEvent(eventName, true, true, detail);
}
}
return event;
}
export function sendCustomEvent(evtName, cfg, customDetails) {
var global = getGlobal();
if (global && global.CustomEvent) {
try {
var details = { cfg: cfg || null, customDetails: customDetails || null };
return dispatchEvent(global, createCustomDomEvent(evtName, details));
}
catch (e) {
// eslint-disable-next-line no-empty
}
}
return false;
}
//# sourceMappingURL=EnvUtils.js.map