UNPKG

crossbrowdy

Version:

A Multimedia JavaScript framework to create real cross-platform and hybrid game engines, games, emulators, multimedia libraries and apps.

944 lines (803 loc) 55.2 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>CrossBrowdy API documentation [printable] Source: CrossBase/general/CB_Client.js</title> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/sunlight.default.css"> <link type="text/css" rel="stylesheet" href="styles/site.yeti.css"> </head> <body style="min-width:800px; overflow-wrap:break-word; word-wrap:break-word; word-break:break-word; line-break:strict; hyphens:none; -webkit-hyphens:none; -moz-hyphens:none;"> <div class="navbar navbar-default navbar-fixed-top "> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="index.html">CrossBrowdy API documentation [printable]</a> <button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#topNavigation"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="navbar-collapse collapse" id="topNavigation"> <ul class="nav navbar-nav"> <li class="dropdown"> <a href="namespaces.list.html" class="dropdown-toggle" data-toggle="dropdown">Namespaces<b class="caret"></b></a> <ul class="dropdown-menu inline"> <li><a href="CB_Arrays.html">CB_Arrays</a></li><li><a href="CB_AudioDetector.html">CB_AudioDetector</a></li><li><a href="CB_Client.html">CB_Client</a></li><li><a href="CB_Collisions.html">CB_Collisions</a></li><li><a href="CB_Configuration.html">CB_Configuration</a></li><li><a href="CB_Configuration.CrossBase.html">CB_Configuration.CrossBase</a></li><li><a href="CB_Configuration.CrossBrowdy.html">CB_Configuration.CrossBrowdy</a></li><li><a href="CB_Controllers.html">CB_Controllers</a></li><li><a href="CB_Controllers_Proprietary.html">CB_Controllers_Proprietary</a></li><li><a href="CB_Controllers_Proprietary.WII.html">CB_Controllers_Proprietary.WII</a></li><li><a href="CB_Controllers_Proprietary.WII_U.html">CB_Controllers_Proprietary.WII_U</a></li><li><a href="CB_Device.html">CB_Device</a></li><li><a href="CB_Device.AmbientLight.html">CB_Device.AmbientLight</a></li><li><a href="CB_Device.Battery.html">CB_Device.Battery</a></li><li><a href="CB_Device.Location.html">CB_Device.Location</a></li><li><a href="CB_Device.Motion.html">CB_Device.Motion</a></li><li><a href="CB_Device.Orientation.html">CB_Device.Orientation</a></li><li><a href="CB_Device.Proximity.html">CB_Device.Proximity</a></li><li><a href="CB_Device.Vibration.html">CB_Device.Vibration</a></li><li><a href="CB_Elements.html">CB_Elements</a></li><li><a href="CB_Events.html">CB_Events</a></li><li><a href="CB_Keyboard.html">CB_Keyboard</a></li><li><a href="CB_Keyboard.chars.html">CB_Keyboard.chars</a></li><li><a href="CB_Keyboard.extended.html">CB_Keyboard.extended</a></li><li><a href="CB_Keyboard.keys.html">CB_Keyboard.keys</a></li><li><a href="CB_Modules.html">CB_Modules</a></li><li><a href="CB_Mouse.html">CB_Mouse</a></li><li><a href="CB_Mouse.CursorImage.html">CB_Mouse.CursorImage</a></li><li><a href="CB_Net.html">CB_Net</a></li><li><a href="CB_Net.Fetch.html">CB_Net.Fetch</a></li><li><a href="CB_Net.REST.html">CB_Net.REST</a></li><li><a href="CB_Net.Sockets.html">CB_Net.Sockets</a></li><li><a href="CB_Net.Sockets.SockJS.html">CB_Net.Sockets.SockJS</a></li><li><a href="CB_Net.XHR.html">CB_Net.XHR</a></li><li><a href="CB_Pointer.html">CB_Pointer</a></li><li><a href="CB_Screen.html">CB_Screen</a></li><li><a href="CB_Speaker.html">CB_Speaker</a></li><li><a href="CB_Touch.html">CB_Touch</a></li><li><a href="CB_baseSymbols.html">CB_baseSymbols</a></li> </ul> </li> <li class="dropdown"> <a href="classes.list.html" class="dropdown-toggle" data-toggle="dropdown">Classes<b class="caret"></b></a> <ul class="dropdown-menu inline"> <li><a href="CB_AudioFile.html">CB_AudioFile</a></li><li><a href="CB_AudioFileCache.html">CB_AudioFileCache</a></li><li><a href="CB_AudioFileSprites.html">CB_AudioFileSprites</a></li><li><a href="CB_AudioFileSpritesPool.html">CB_AudioFileSpritesPool</a></li><li><a href="CB_AudioFile_API.AAPI.html">CB_AudioFile_API.AAPI</a></li><li><a href="CB_AudioFile_API.ACMP.html">CB_AudioFile_API.ACMP</a></li><li><a href="CB_AudioFile_API.SM2.html">CB_AudioFile_API.SM2</a></li><li><a href="CB_AudioFile_API.WAAPI.html">CB_AudioFile_API.WAAPI</a></li><li><a href="CB_Canvas.html">CB_Canvas</a></li><li><a href="CB_GraphicSprites.html">CB_GraphicSprites</a></li><li><a href="CB_GraphicSpritesScene.html">CB_GraphicSpritesScene</a></li> </ul> </li> <li class="dropdown"> <a href="global.html" class="dropdown-toggle" data-toggle="dropdown">Global<b class="caret"></b></a> <ul class="dropdown-menu inline"> <li><a href="global.html#CB_BASE_NAME">CB_BASE_NAME</a></li><li><a href="global.html#CB_CREDITS_DEFAULT">CB_CREDITS_DEFAULT</a></li><li><a href="global.html#CB_NAME">CB_NAME</a></li><li><a href="global.html#CB_OPTIONS">CB_OPTIONS</a></li><li><a href="global.html#CB_VERSION">CB_VERSION</a></li><li><a href="global.html#CB_addCredits">CB_addCredits</a></li><li><a href="global.html#CB_baseToBase">CB_baseToBase</a></li><li><a href="global.html#CB_baseToInt">CB_baseToInt</a></li><li><a href="global.html#CB_br2nl">CB_br2nl</a></li><li><a href="global.html#CB_brToNl">CB_brToNl</a></li><li><a href="global.html#CB_combineArraysOrObjects">CB_combineArraysOrObjects</a></li><li><a href="global.html#CB_combineAutomatically">CB_combineAutomatically</a></li><li><a href="global.html#CB_combineJSON">CB_combineJSON</a></li><li><a href="global.html#CB_combineURIParameters">CB_combineURIParameters</a></li><li><a href="global.html#CB_combineURLParameters">CB_combineURLParameters</a></li><li><a href="global.html#CB_console">CB_console</a></li><li><a href="global.html#CB_copyObject">CB_copyObject</a></li><li><a href="global.html#CB_countDecimalDigits">CB_countDecimalDigits</a></li><li><a href="global.html#CB_countDecimalPart">CB_countDecimalPart</a></li><li><a href="global.html#CB_countDecimals">CB_countDecimals</a></li><li><a href="global.html#CB_countIntegerDigits">CB_countIntegerDigits</a></li><li><a href="global.html#CB_countIntegerPart">CB_countIntegerPart</a></li><li><a href="global.html#CB_credits">CB_credits</a></li><li><a href="global.html#CB_forEach">CB_forEach</a></li><li><a href="global.html#CB_forceString">CB_forceString</a></li><li><a href="global.html#CB_getBase64StringObject">CB_getBase64StringObject</a></li><li><a href="global.html#CB_getCookie">CB_getCookie</a></li><li><a href="global.html#CB_getDatum">CB_getDatum</a></li><li><a href="global.html#CB_getJSONPropertyValue">CB_getJSONPropertyValue</a></li><li><a href="global.html#CB_getLZStringObject">CB_getLZStringObject</a></li><li><a href="global.html#CB_getValueIndex">CB_getValueIndex</a></li><li><a href="global.html#CB_getValuePath">CB_getValuePath</a></li><li><a href="global.html#CB_includeJSFile">CB_includeJSFile</a></li><li><a href="global.html#CB_indexOf">CB_indexOf</a></li><li><a href="global.html#CB_init">CB_init</a></li><li><a href="global.html#CB_intToBase">CB_intToBase</a></li><li><a href="global.html#CB_isArray">CB_isArray</a></li><li><a href="global.html#CB_isEmail">CB_isEmail</a></li><li><a href="global.html#CB_isFileLocal">CB_isFileLocal</a></li><li><a href="global.html#CB_isString">CB_isString</a></li><li><a href="global.html#CB_lastIndexOf">CB_lastIndexOf</a></li><li><a href="global.html#CB_ltrim">CB_ltrim</a></li><li><a href="global.html#CB_nl2br">CB_nl2br</a></li><li><a href="global.html#CB_nlToBr">CB_nlToBr</a></li><li><a href="global.html#CB_numberFormat">CB_numberFormat</a></li><li><a href="global.html#CB_numberOfDecimalDigits">CB_numberOfDecimalDigits</a></li><li><a href="global.html#CB_numberOfDecimals">CB_numberOfDecimals</a></li><li><a href="global.html#CB_numberOfIntegerDigits">CB_numberOfIntegerDigits</a></li><li><a href="global.html#CB_parseJSON">CB_parseJSON</a></li><li><a href="global.html#CB_parseString">CB_parseString</a></li><li><a href="global.html#CB_regularExpressionString">CB_regularExpressionString</a></li><li><a href="global.html#CB_renderString">CB_renderString</a></li><li><a href="global.html#CB_replaceAll">CB_replaceAll</a></li><li><a href="global.html#CB_rtrim">CB_rtrim</a></li><li><a href="global.html#CB_scriptPath">CB_scriptPath</a></li><li><a href="global.html#CB_scriptPathCalculate">CB_scriptPathCalculate</a></li><li><a href="global.html#CB_setCookie">CB_setCookie</a></li><li><a href="global.html#CB_setDatum">CB_setDatum</a></li><li><a href="global.html#CB_sizeOf">CB_sizeOf</a></li><li><a href="global.html#CB_sizeof">CB_sizeof</a></li><li><a href="global.html#CB_stringifyJSON">CB_stringifyJSON</a></li><li><a href="global.html#CB_symmetricCall">CB_symmetricCall</a></li><li><a href="global.html#CB_symmetricCallClear">CB_symmetricCallClear</a></li><li><a href="global.html#CB_this">CB_this</a></li><li><a href="global.html#CB_trim">CB_trim</a></li> </ul> </li> </ul> <div class="col-sm-3 col-md-3"> <form class="navbar-form" role="search"> <div class="input-group"> <input type="text" class="form-control" placeholder="Search" name="q" id="search-input"> <div class="input-group-btn"> <button class="btn btn-default" id="search-submit"><i class="glyphicon glyphicon-search"></i></button> </div> </div> </form> </div> </div> </div> </div> <div class="container" id="toc-content" style="width:100%;"> <div class="row" style="width:100%;"> <div class="col-md-12"> <div id="main"> <h1 class="page-title">Source: CrossBase/general/CB_Client.js</h1> <section> <article> <pre class="sunlight-highlight-javascript linenums">/** * @file Web client (browser or engine) management. Contains the {@link CB_Client} static class. * @author Joan Alba Maldonado &lt;workindalian@gmail.com> * @license Creative Commons Attribution 4.0 International. See more at {@link https://crossbrowdy.com/about#what_is_the_crossbrowdy_copyright_and_license}. */ /** * Static class to manage the current client. It will return itself if it is tried to be instantiated. It can use [BrowserDetect]{@link https://quirksmode.org/js/detect.html} ([source code rescued]{@link https://gist.github.com/mitchellhislop/2018348}). * @namespace * @todo Think about implementing a getDocumentParents function (similar to {@link CB_Client.getWindowParents}). * @todo Think about implementing "onClose" event (to fire when app/web is going to be closed). */ var CB_Client = function() { return CB_Client; }; { CB_Client.initialized = false; //It will tells whether the object has been initialized or not. //Initializes all values: CB_Client.init = function() { //If this is the fist time: if (CB_Client.initialized) { return CB_Client; } //The object has been initialized: CB_Client.initialized = true; return CB_Client; } //Returns the most preferred language: CB_Client._getLanguagePreferred = function(allowNavigatorLanguages, PHPAcceptedLanguagesFirst) { return CB_Client._getLanguagesPreferred(allowNavigatorLanguages, PHPAcceptedLanguagesFirst)[0]; }; /** * Returns the most preferred language as a string. * @function * @param {boolean} [allowNavigatorLanguages={@link CB_Configuration.CrossBase.CB_Client_allowNavigatorLanguages_DEFAULT}] - Defines whether to allow using the [window.navigator.languages]{@link https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/languages} property (if not available, it will proceed normally). * @param {boolean} [PHPAcceptedLanguagesFirst={@link CB_Configuration.CrossBase.CB_Client_PHPAcceptedLanguagesFirst_DEFAULT}] - If it is set to true, it will try to return the accepted languages found out by [PHP]{@link https://en.wikipedia.org/wiki/PHP} (if [PHP]{@link https://en.wikipedia.org/wiki/PHP} is available) in [$_SERVER]{@link http://php.net/manual/en/reserved.variables.server.php}['HTTP_ACCEPT_LANGUAGE'] or it will proceed normally otherwise. * @returns {string} * @todo Use other back-end ways to calculate the language (using Node.js, for example). */ CB_Client.getLanguage = function(allowNavigatorLanguages, PHPAcceptedLanguagesFirst) { return CB_Client._getLanguagePreferred(allowNavigatorLanguages, PHPAcceptedLanguagesFirst); } //Returns the most preferred languages (an array): CB_Client._getLanguagesPreferred = function(allowNavigatorLanguages, PHPAcceptedLanguagesFirst) { if (typeof(PHPAcceptedLanguagesFirst) !== true &amp;&amp; PHPAcceptedLanguagesFirst !== false) { PHPAcceptedLanguagesFirst = CB_Configuration[CB_BASE_NAME].CB_Client_PHPAcceptedLanguagesFirst_DEFAULT; } if (PHPAcceptedLanguagesFirst &amp;&amp; typeof(CB_PHPAcceptedLanguages) !== "undefined" &amp;&amp; CB_isArray(CB_PHPAcceptedLanguages) &amp;&amp; CB_PHPAcceptedLanguages.length > 0) { return CB_PHPAcceptedLanguages; } if (allowNavigatorLanguages !== true &amp;&amp; allowNavigatorLanguages !== false) { allowNavigatorLanguages = CB_Configuration[CB_BASE_NAME].CB_Client_allowNavigatorLanguages_DEFAULT; } if (allowNavigatorLanguages &amp;&amp; window.navigator.languages) { return window.navigator.languages; } var languages = []; if (window.navigator.language &amp;&amp; CB_indexOf(languages, window.navigator.language) === -1) { languages[languages.length] = window.navigator.language; } if (window.navigator.userLanguage &amp;&amp; CB_indexOf(languages, window.navigator.userLanguage) === -1) { languages[languages.length] = window.navigator.userLanguage; } if (window.navigator.browserLanguage &amp;&amp; CB_indexOf(languages, window.navigator.browserLanguage) === -1) { languages[languages.length] = window.navigator.browserLanguage; } if (window.navigator.systemLanguage &amp;&amp; CB_indexOf(languages, window.navigator.systemLanguage) === -1) { languages[languages.length] = window.navigator.systemLanguage; } if (languages.length > 0) { return languages; } else { return [CB_Configuration[CB_BASE_NAME].CB_Client_language_DEFAULT]; } }; /** * Returns the most preferred languages as an array of strings. * @function * @param {boolean} [allowNavigatorLanguages={@link CB_Configuration.CrossBase.CB_Client_allowNavigatorLanguages_DEFAULT}] - Defines whether to allow using the [window.navigator.languages]{@link https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/languages} property (if not available, it will proceed normally). * @param {boolean} [PHPAcceptedLanguagesFirst={@link CB_Configuration.CrossBase.CB_Client_PHPAcceptedLanguagesFirst_DEFAULT}] - If it is set to true, it will try to return the accepted languages found out by [PHP]{@link https://en.wikipedia.org/wiki/PHP} (if [PHP]{@link https://en.wikipedia.org/wiki/PHP} is available) in [$_SERVER]{@link http://php.net/manual/en/reserved.variables.server.php}['HTTP_ACCEPT_LANGUAGE'] or it will proceed normally otherwise. * @returns {array} * @todo Use other back-end ways to calculate languages (using Node.js, for example). */ CB_Client.getLanguages = function(allowNavigatorLanguages, PHPAcceptedLanguagesFirst) { return CB_Client._getLanguagesPreferred(allowNavigatorLanguages, PHPAcceptedLanguagesFirst); } /** * Sets a function to execute when the [languagechange]{@link https://developer.mozilla.org/en-US/docs/Web/Events/languagechange} event is fired (only for some web clients) or removes it. * @function * @param {function|null} eventFunction - Function that represents the event listener that will be called when the event is fired. If a null value is used, the event will be removed. * @param {boolean} [keepOldFunction=true] - Defines whether to also keep the previous listeners or remove them otherwise. * @param {boolean} [useCapture=false] - Defines whether the event we want to add will use capture or not. This parameter will be effective only if the current client supports the [addEventListener]{@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener} method and will be used as its third parameter. */ CB_Client.onLanguageChanges = function(eventFunction, keepOldFunction, useCapture) { CB_Client._setEvent("languagechange", eventFunction, keepOldFunction, useCapture, window); } /** * Alias for {@link CB_Client.get}. * @function CB_Client.getBrowser * @see {@link CB_Client.get} */ /** * Returns the current web client (if possible) as a string. It uses [BrowserDetect]{@link https://quirksmode.org/js/detect.html} ([source code rescued]{@link https://gist.github.com/mitchellhislop/2018348}) internally. * @function * @returns {string} */ CB_Client.get = CB_Client.getBrowser = function() { return BrowserDetect.browser; } /** * Alias for {@link CB_Client.getVersion}. * @function CB_Client.getBrowserVersion * @see {@link CB_Client.getVersion} */ /** * Returns the current web client version (if possible) as a string. It uses [BrowserDetect]{@link https://quirksmode.org/js/detect.html} ([source code rescued]{@link https://gist.github.com/mitchellhislop/2018348}) internally. * @function * @returns {string} */ CB_Client.getVersion = CB_Client.getBrowserVersion = function() { return BrowserDetect.version + ""; } /** * Alias for {@link CB_Client.getVersionMain}. * @function CB_Client.getBrowserVersionMain * @see {@link CB_Client.getVersionMain} */ /** * Returns the current web client main version (first number), if possible, as an integer. It uses [BrowserDetect]{@link https://quirksmode.org/js/detect.html} ([source code rescued]{@link https://gist.github.com/mitchellhislop/2018348}) internally. * @function * @returns {integer} */ CB_Client.getVersionMain = CB_Client.getBrowserVersionMain = function() { return parseInt(CB_Client.getBrowserVersion().split(".")[0]); } CB_Client._getWindowParentsReturnCache; //Stores the return result in order to optimize the execution next times. /** * Returns all the [window]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window} objects, parents and last son (main one) in an array (with the topmost parent in the highest index). Useful in case the script is running in an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more. * @function * @returns {array} */ CB_Client.getWindowParents = function() { //If it is not the first time we execute this function, uses the cache to return always the same: if (typeof(CB_Client._getWindowParentsReturnCache) !== "undefined" &amp;&amp; CB_Client._getWindowParentsReturnCache !== null) { return CB_Client._getWindowParentsReturnCache; } var windowParents = [ window.self ]; try { if (typeof(window.parent) !== "undefined" &amp;&amp; window.parent !== null) { var currentParent = windowParents[0];//windowParents[windowParents.length - 1]; while (typeof(currentParent.parent) !== "undefined" &amp;&amp; currentParent !== currentParent.parent) { currentParent = currentParent.parent; windowParents[windowParents.length] = currentParent; } ///////windowBase = currentParent; } } catch(E) {} CB_Client._getWindowParentsReturnCache = windowParents; return windowParents; } CB_Client._getWindowBaseReturnCache; //Stores the return result in order to optimize the execution next times. /** * Returns the [window]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window} object of the first parent (the topmost one). Useful in case the script is running in an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more. * @function * @returns {Object} */ CB_Client.getWindowBase = function() { //If it is not the first time we execute this function, uses the cache to return always the same: if (typeof(CB_Client._getWindowBaseReturnCache) !== "undefined" &amp;&amp; CB_Client._getWindowBaseReturnCache !== null) { return CB_Client._getWindowBaseReturnCache; } //By default, uses the current window object: var windowBase = window.self; //window; //Tries to get the topmost window (it can fail if it is not in the same domain or it is running locally): try { //If defined, we use window.top to get the topmost window: if (typeof(window.top) !== "undefined" &amp;&amp; window.top !== null) { windowBase = window.top; } //...otherwise, we get all the parents and chose the last one (which will be the topmost): else { var windowParents = CB_Client.getWindowParents(); windowBase = windowParents[windowParents.length - 1]; } } catch(E) {} CB_Client._getWindowBaseReturnCache = windowBase; return windowBase; } CB_Client._getWindowReturnCache; //Stores the return result in order to optimize the execution next times. /** * Returns the [window]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window} object (having in mind whether the script is running in one [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more, if we want). * @function * @param {boolean} [mindIframes={@link CB_Configuration.CrossBase.MIND_IFRAMES}] - If set to true, it will try to get and return the topmost [window]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window} object. Useful in case the script is running in an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more. * @returns {Object} */ CB_Client.getWindow = function(mindIframes) { if (typeof(mindIframes) === "undefined" || mindIframes === null) { mindIframes = CB_Configuration[CB_BASE_NAME].MIND_IFRAMES; } //If it is not the first time we execute this function, uses the cache to return always the same: if (!mindIframes) { return window.self; } else if (typeof(CB_Client._getWindowReturnCache) !== "undefined" &amp;&amp; CB_Client._getWindowReturnCache !== null) { return CB_Client._getWindowReturnCache; } //Gets the window chosen (if we arrived here, it means we mind iframes): CB_Client._getWindowReturnCache = CB_Client.getWindowBase(); //Stores the window chosen in the cache: return CB_Client._getWindowReturnCache; } /** * Returns the [document]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/document} object of the first parent (the topmost one). Useful in case the script is running in an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more. * @function * @returns {Object} */ CB_Client.getDocumentBase = function() { //By default, uses the current document object: var documentBase = document; //Tries to get the document object of the topmost window (it can fail if it is not in the same domain or it is running locally): try { documentBase = CB_Client.getWindowBase().document; } catch(E) {} return documentBase; } /** * Returns the [document]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/document} object (having in mind whether the script is running in one [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more, if we want). * @function * @param {boolean} [mindIframes={@link CB_Configuration.CrossBase.MIND_IFRAMES}] - If set to true, it will try to get and return the topmost [document]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/document} object. Useful in case the script is running in an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more. * @returns {Object} */ CB_Client.getDocument = function(mindIframes) { if (typeof(mindIframes) === "undefined" || mindIframes === null) { mindIframes = CB_Configuration[CB_BASE_NAME].MIND_IFRAMES; } var documentChosen = document; if (mindIframes) { documentChosen = CB_Client.getDocumentBase(); } return documentChosen; } /** * Tells whether the [canvas]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas} element is supported natively or not. * @function * @returns {boolean} */ CB_Client.supportsCanvas = function() { return CB_Configuration[CB_BASE_NAME]._supportsCanvas(); } CB_Client._supportsCSS3TransformReturnCache; /** * Tells whether [CSS3]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS3} [transform]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/transform} is supported natively or not. * @function * @returns {boolean} */ CB_Client.supportsCSS3Transform = function() { if (typeof(CB_Client._supportsCSS3TransformReturnCache) === "undefined" || CB_Client._supportsCSS3TransformReturnCache === null) { var documentBodyStyle = document.body.style; CB_Client._supportsCSS3TransformReturnCache = (typeof(documentBodyStyle.transform) !== "undefined" || typeof(documentBodyStyle.WebkitTransform) !== "undefined" || typeof(documentBodyStyle.MozTransform) !== "undefined" || typeof(documentBodyStyle.OTransform) !== "undefined" || typeof(documentBodyStyle.MsTransform) !== "undefined" || typeof(documentBodyStyle.KhtmlTransform) !== "undefined"); } return CB_Client._supportsCSS3TransformReturnCache; } /** * Function that tells whether [PHP]{@link https://en.wikipedia.org/wiki/PHP} is available or not. * @function * @returns {boolean} */ CB_Client.supportsPHP = function() { return (typeof(CB_supportedPHP) !== "undefined" &amp;&amp; CB_supportedPHP === "YES"); } /** * Returns the available version of [PHP]{@link https://en.wikipedia.org/wiki/PHP} (if any), as either an array of strings or as a string. * @function * @param {boolean} [asString=false] - If set to true, returns the version as a string. * @returns {array|string} */ CB_Client.getPHPVersion = function(asString) { if (typeof(CB_PHPVersion) === "undefined") { CB_PHPVersion = 0; } return asString ? (CB_PHPVersion + "") : (CB_PHPVersion + "").split("."); } /** * Function that tells whether [Node.js]{@link https://en.wikipedia.org/wiki/Node.js} is available (checks the availability of [process.versions.node]{@link https://nodejs.org/api/process.html#process_process_versions}) or not. * @function * @returns {boolean} */ //* Source: Dan. B. @ http://stackoverflow.com/questions/17575790/environment-detection-node-js-or-browser CB_Client.supportsNodeJS = function() { return (typeof(process) === "object" &amp;&amp; process !== null &amp;&amp; typeof(process.versions) === "object" &amp;&amp; typeof(process.versions.node) !== "undefined"); } /** * Returns the available version of [Node.js]{@link https://en.wikipedia.org/wiki/Node.js} (if any), as either an array of strings or as a string. * @function * @param {boolean} [asString=false] - If set to true, returns the version as a string. * @returns {array|string} */ CB_Client.getNodeJSVersion = function(asString) { if (typeof(process) === "object" &amp;&amp; process !== null &amp;&amp; CB_isString(process.version)) { return asString ? process.version : process.version.replace(CB_regularExpressionString("-", true, true), ".").split("."); } else { return asString ? "0.0.0" : [0, 0, 0]; } } /** * Function that tells whether [Microsoft Silverlight]{@link https://en.wikipedia.org/wiki/Microsoft_Silverlight} plugin is available or not. * @function * @returns {boolean} */ CB_Client.supportsSilverlight = function() { var isSilverlightInstalled = false; try { isSilverlightInstalled = !!(new ActiveXObject("AgControl.AgControl")); } catch(E) { if (navigator.plugins["Silverlight Plug-In"]) { isSilverlightInstalled = true; } else { isSilverlightInstalled = false; } } return isSilverlightInstalled; } /** * Returns the available version of [Microsoft Silverlight]{@link https://en.wikipedia.org/wiki/Microsoft_Silverlight} plugin (if any), as either an array of strings or as a string. * @function * @param {boolean} [asString=false] - If set to true, returns the version as a string. * @returns {array|string} */ CB_Client.getSilverlightVersion = function(asString) { if (navigator.plugins["Silverlight Plug-In"] &amp;&amp; navigator.plugins["Silverlight Plug-In"].description &amp;&amp; CB_isString(navigator.plugins["Silverlight Plug-In"].description) &amp;&amp; CB_trim(navigator.plugins["Silverlight Plug-In"].description) !== "") { return asString ? navigator.plugins["Silverlight Plug-In"].description : navigator.plugins["Silverlight Plug-In"].description.replace(CB_regularExpressionString("-", true, true), ".").split("."); } else { return asString ? "0.0.0" : [0, 0, 0]; } } /** * Function that tells whether [Adobe Flash (formerly Macromedia Flash)]{@link https://en.wikipedia.org/wiki/Adobe_Flash_Player} plugin is available or not. * @function * @returns {boolean} */ CB_Client.supportsFlash = function() { var isFlashInstalled = false; if ("ActiveXObject" in window) { try { isFlashInstalled = !!(new ActiveXObject("ShockwaveFlash.ShockwaveFlash")); } catch(E) { isFlashInstalled = false; } } if (!isFlashInstalled &amp;&amp; typeof(navigator.mimeTypes) !== "undefined") { var mime = navigator.mimeTypes['application/x-shockwave-flash'] if (typeof(mime) !== "undefined" &amp;&amp; mime !== null &amp;&amp; mime.enabledPlugin) { isFlashInstalled = true;//!!mime; } } if (!isFlashInstalled &amp;&amp; typeof(navigator.plugins) !== "undefined") { var plugin = navigator.plugins["Shockwave Flash"]; isFlashInstalled = !!plugin; } return isFlashInstalled; } /** * Returns the available version of [Adobe Flash (formerly Macromedia Flash)]{@link https://en.wikipedia.org/wiki/Adobe_Flash_Player} plugin, if any, as either an array of strings or as a string. * @function * @param {boolean} [asString=false] - If set to true, returns the version as a string. * @returns {array|string} */ CB_Client.getFlashVersion = function(asString) { var version = "0.0.0"; try { try { var axo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6'); try { axo.AllowScriptAccess = 'always'; } catch(E) { return asString ? '6.0.0' : '6.0.0'.split('.'); } } catch(E) {} version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; version = version.replace(CB_regularExpressionString(",", true, true), "."); return asString ? version : version.split('.'); } catch(E) { try { if (navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin) { version = (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1]; version = version.replace(CB_regularExpressionString(",", true, true), "."); return asString ? version : version.split('.'); } } catch(E) {} } return asString ? version : version.split('.'); } /** * Tells whether the script is running locally (using "file:" protocol) or not. * @function * @param {boolean} [mindIframes={@link CB_Configuration.CrossBase.MIND_IFRAMES}] - If set to true, it will try to check the protocol of the topmost [window]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window} object. Useful in case the script is running in an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more. * @returns {boolean} */ CB_Client.isRunningLocally = function(mindIframes) { if (typeof(mindIframes) === "undefined" || mindIframes === null) { mindIframes = CB_Configuration[CB_BASE_NAME].MIND_IFRAMES; } var isRunningLocally = false; //We assume that the script is not running locally by default. var protocolUsed = ""; try { var windowObject = CB_Client.getWindow(mindIframes); if (typeof(windowObject.location) !== "undefined" &amp;&amp; typeof(windowObject.location.protocol) !== "undefined") { protocolUsed = windowObject.location.protocol; } } catch(E) { if (typeof(window.location) !== "undefined" &amp;&amp; typeof(window.location.protocol) !== "undefined") { protocolUsed = window.location.protocol; } } if (protocolUsed === "file:") { isRunningLocally = true; } //else if (protocolUsed === "http:" || protocolUsed === "https:") { isRunningLocally = false; } return isRunningLocally; } CB_Client._isRunningOnNWjsReturnCache = null; /** * Tells whether the script is running on [NW.js (formerly node-webkit)]{@link https://nwjs.io/} or not. * @function * @returns {boolean} */ //* Source: Kuf @ http://stackoverflow.com/questions/31968355/detect-if-web-app-is-running-in-nwjs CB_Client.isRunningOnNWjs = function() { if (typeof(CB_Client._isRunningOnNWjsReturnCache) !== "undefined" &amp;&amp; CB_Client._isRunningOnNWjsReturnCache !== null) { return CB_Client._isRunningOnNWjsReturnCache; } if (typeof(nw) !== "undefined" &amp;&amp; nw !== null) { return CB_Client._isRunningOnNWjsReturnCache = true; } try { return CB_Client._isRunningOnNWjsReturnCache = (typeof(require) === "function" &amp;&amp; (typeof(nw) !== "undefined" &amp;&amp; nw !== null &amp;&amp; nw.App || typeof(require("nw.gui")) !== "undefined")); } catch(E) { return CB_Client._isRunningOnNWjsReturnCache = false; } } CB_Client._isRunningOnElctronReturnCache = null; /** * Tells whether the script is running on [Electron (Electron.js)]{@link https://electronjs.org/} or not. * @function * @returns {boolean} */ //* Source: cheton @ https://github.com/cheton/is-electron/blob/master/index.js CB_Client.isRunningOnElectron = function() { if (typeof(CB_Client._isRunningOnElectronReturnCache) !== "undefined" &amp;&amp; CB_Client._isRunningOnElectronReturnCache !== null) { return CB_Client._isRunningOnElectronReturnCache; } //if (typeof(nw) !== "undefined" &amp;&amp; nw !== null) { return CB_Client._isRunningOnElectronReturnCache = true; } try { return CB_Client._isRunningOnElectronReturnCache = (typeof(navigator) === "object" &amp;&amp; navigator !== null &amp;&amp; typeof(navigator.userAgent) === "string" &amp;&amp; navigator.userAgent.indexOf("Electron") !== -1); } catch(E) { return CB_Client._isRunningOnElectronReturnCache = false; } } /** * Exits and finishes the script. In a browser, it will try to close the window or at least abandon it redirecting to an empty one (or to a desired URL). In an app ([NW.js (formerly node-webkit)]{@link https://nwjs.io/}/[Electron (Electron.js)]{@link https://electronjs.org/}/[Apache Cordova]{@link https://cordova.apache.org/}/[Adobe PhoneGap]{@link https://phonegap.com/}/[Appcelerator Titanium SDK]{@link https://en.wikipedia.org/wiki/Appcelerator_Titanium}/[Appcelerator TideSDK (Titanium Desktop)]{@link https://github.com/appcelerator-archive/titanium_desktop}/[Weixin (WeChat)]{@link https://en.wikipedia.org/wiki/WeChat}/etc.), it will try to close the app. * @function * @param {boolean} [allowWindowCloseFallback=true] - Defines whether to allow using the [window.close]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window/close} method as a fallback. * @param {boolean} [allowRedirectionFallback=true] - Defines whether to redirect the current client as a fallback (to the URL defined in the "redirectionAddress" parameter). * @param {boolean} [redirectionAddress='about:blank'] - Defines the URL where the current client will be redirected to in the case that the window cannot be closed. Only used if the "allowRedirectionFallback" parameter is set to true. * @todo Have in mind iframes (think about it). */ CB_Client.exit = function(allowWindowCloseFallback, allowRedirectionFallback, redirectionAddress) { if (typeof(allowRedirectionFallback) === "undefined" || allowRedirectionFallback === null) { allowRedirectionFallback = true; } if (typeof(allowWindowCloseFallback) === "undefined" || allowWindowCloseFallback === null) { allowWindowCloseFallback = true; } if (typeof(redirectionAddress) === "undefined" || redirectionAddress === null) { redirectionAddress = "about:blank"; } var useFallback = true; //Tries to use NW.js (node-webkit) if available to quit the app: if (CB_Client.isRunningOnNWjs()) { if (typeof(nw) !== "undefined" &amp;&amp; nw !== null &amp;&amp; nw.App &amp;&amp; typeof(nw.App.closeAllWindows) === "function") { try { nw.App.closeAllWindows(); useFallback = false; } catch(E) { useFallback = true; } } if (useFallback &amp;&amp; typeof(require) === "function") { try { var gui = require("nw.gui"); if (typeof(gui) !== "undefined" &amp;&amp; gui !== null &amp;&amp; gui.App) { if (typeof(gui.App.closeAllWindows) === "function") { try { gui.App.closeAllWindows(); useFallback = false; } catch(E) { useFallback = true; } } if (useFallback &amp;&amp; typeof(gui.App.quit) === "function") { try { gui.App.quit(); useFallback = false; } catch(E) { useFallback = true; } } } } catch(E) { useFallback = true; } } if (useFallback &amp;&amp; typeof(nw) !== "undefined" &amp;&amp; nw !== null &amp;&amp; nw.App &amp;&amp; typeof(nw.App.quit) === "function") { try { nw.App.quit(); useFallback = false; } catch(E) { useFallback = true; } } } //Tries to use Electron (Electron.js) if available to quit the app: if (CB_Client.isRunningOnElectron() &amp;&amp; typeof(require) === "function") { try { var app = require('app'); app.on("window-all-closed", app.quit); app.quit(); useFallback = false; } catch(E) { useFallback = true; } } //If able, uses PhoneGap with navigator.app: if (typeof(navigator) !== "undefined" &amp;&amp; typeof(navigator.app) !== "undefined" &amp;&amp; typeof(navigator.app.exitApp) !== "undefined") { try { navigator.app.exitApp(); useFallback = false; } catch(E) { useFallback = true; } } //If able uses PhoneGap with navigator.device: if (typeof(navigator) !== "undefined" &amp;&amp; typeof(navigator.device) !== "undefined" &amp;&amp; typeof(navigator.device.exitApp) !== "undefined") { try { navigator.device.exitApp(); useFallback = false; } catch(E) { useFallback = true; } } //If able uses WeixinJSBridge (Weixin / Wechat JavaScript Bridge): if (typeof(WeixinJSBridge) !== "undefined" &amp;&amp; typeof(WeixinJSBridge.call) !== "undefined") { //WeixinJSBridge.invoke("closeWindow", {}, function(e){}); try { WeixinJSBridge.call("closeWindow"); useFallback = false; } catch(E) { useFallback = true; } } //If able uses Titanium/TideSDK: if (typeof(Ti) !== "undefined" &amp;&amp; typeof(Ti.App) !== "undefined" &amp;&amp; typeof(Ti.App.exit) !== "undefined") { try { Ti.App.exit(); useFallback = false; } catch(E) { useFallback = true; } } //If we want to close using the fallback: if (useFallback) { //Uses redirection if it is allowed: if (allowRedirectionFallback) { setTimeout(function() { location.href = redirectionAddress; }, 200); //Lets a little bit time to process window.close() (if allowed). } //Uses window.close() if it is allowed: if (allowWindowCloseFallback) { try { //if (navigator.userAgent.indexOf('MSIE') !== -1 &amp;&amp; (navigator.appVersion.indexOf("MSIE 5") !== -1 || navigator.appVersion.indexOf("MSIE 6") !== -1)) //{ //CB_Client.getWindow().opener = top; //CB_Client.getWindow().close(); //} //else //{ //var ventana = CB_Client.getWindow().open("", "_self"); //ventana.close(); //} var thisWindow = window.open(allowRedirectionFallback ? redirectionAddress : "", "_self", "", "true"); thisWindow.opener = top; CB_windowCloseEncapsulated = thisWindow.close; CB_windowCloseEncapsulated(); //if (navigator.userAgent.indexOf('MSIE') !== -1 &amp;&amp; (navigator.appVersion.indexOf("MSIE 5") !== -1 || navigator.appVersion.indexOf("MSIE 6") !== -1)) //{ //window.opener = top; //window.close(); //} //var thisWindow = window.parent.open(allowRedirectionFallback ? redirectionAddress : location.href, "_self"); //window.parent.close(); //else //{ //var thisWindow = CB_Client.getWindow(true).open(allowRedirectionFallback ? redirectionAddress : "", "_self", "", "true"); //thisWindow.opener = CB_Client.getWindow().top; //CB_windowCloseEncapsulated = thisWindow.close; //CB_windowCloseEncapsulated(); //} } catch(E) { try { var thisWindow = window.open(allowRedirectionFallback ? redirectionAddress : location.href, "_self"); thisWindow.close(); } catch(E) { try { window.opener = top; window.close(); } catch(E) { try { window.opener = window; window.close(); } catch(E) { try { window.opener = "CB_TryingToCloseWindow"; window.close(); } catch(E) { try { window.close(); } catch(E) { } } } } } } } } } /** * Redirects the current client to the desired location (having in mind whether the script is running in one [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more, if we want). * @function * @param {string} address - The address where we want to go. * @param {string} [getData] - Any URL (GET) variables we want to send (as for example "data1=value1&amp;data2=value2"). * @param {boolean} [mindIframes={@link CB_Configuration.CrossBase.MIND_IFRAMES}] - If set to true, it will try to redirect the topmost [window]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window} object. Useful in case the script is running in an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more. */ CB_Client.redirectTo = function(address, getData, mindIframes) { getData = CB_ltrim(CB_trim(getData), ["&amp;", "?"]); if (getData !== "") { if (address.indexOf("?") === -1) { getData = "?" + getData; } else { getData = "&amp;" + getData; } } try { CB_Client.getWindow(mindIframes).location = address + getData; } catch(E) { window.location = address + getData; } } /** * Returns the current URL, if possible (having in mind whether the script is running in one [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more, if we want). * @function * @param {boolean} [mindIframes={@link CB_Configuration.CrossBase.MIND_IFRAMES}] - If set to true, it will try to get the location of the topmost [window]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window} object. Useful in case the script is running in an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more. * @returns {string} */ CB_Client.getLocation = function(mindIframes) { var address = ""; try { address = CB_Client.getWindow(mindIframes).location.href; } catch(E) { address = ""; } if (!address) { address = window.location.href; } return address; } /** * Returns the given address without the file (for example, if "http://whatever.com/index.html" is given, it will return "http://whatever.com/"). * @function * @param {string} address - The address that we want to filter. * @param {string} [fallbackURL] - The address that we want it to return in the case that the given one is not allowed (used when "allowsLocal" does not allow a local address). If it contains a file, it will not be stripped out. * @param {boolean} [allowsLocal=true] - Defines whether to allow returning a local address or not. If it is set to false and the address is local, it will return the "fallbackURL" instead (without stripping out the file, if any). * @returns {string} */ CB_Client.getAddressWithoutFile = function(address, fallbackURL, allowsLocal) { if (allowsLocal !== true &amp;&amp; allowsLocal !== false) { allowsLocal = true; } address = CB_trim(address); address = CB_rtrim(address.substring(0, address.lastIndexOf("/")), "/") + "/"; if (allowsLocal || address.indexOf("://localhost") === -1 &amp;&amp; address.indexOf("://127.0.0.1") === -1 &amp;&amp; address.indexOf("://192.168") === -1 || !CB_isString(fallbackURL)) { return address; } else { return fallbackURL; } } /** * Returns the current URL without the file (for example, if "http://whatever.com/index.html" is the current URL, it will return "http://whatever.com/"), if possible (having in mind whether the script is running in one [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more, if we want). * @function * @param {string} [fallbackURL] - The address that we want it to return in the case that the current one is not allowed (used when "allowsLocal" does not allow a local address). If it contains a file, it will not be stripped out. * @param {boolean} [allowsLocal=true] - Defines whether to allow returning a local address or not. If it is set to false and the current address is local, it will return the "fallbackURL" instead (without stripping out the file, if any). * @param {boolean} [mindIframes={@link CB_Configuration.CrossBase.MIND_IFRAMES}] - If set to true, it will try to get the location of the topmost [window]{@link https://developer.mozilla.org/en-US/docs/Web/API/Window} object. Useful in case the script is running in an [iframe]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe} or more. * @returns {string} */ CB_Client.getLocationWithoutFile = function(fallbackURL, allowsLocal, mindIframes) { return CB_Client.getAddressWithoutFile(CB_Client.getLocation(mindIframes), fallbackURL, allowsLocal); } //var firstTimeShit = 0; /** * Gets the starting pixel of top or left coordinates for [getBoundingClientRect]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect} (it's not 0 in some Internet Explorer versions). * @function * @param {('left'|'top')} [leftOrTop='left'] - String that defines whether we want it to return the values for "left" or for "top". * @returns {integer} */ CB_Client.getBoundingClientRectMargin = function(leftOrTop) { leftOrTop = leftOrTop.toLowerCase(); if (leftOrTop === "" || leftOrTop !== "left" &amp;&amp; leftOrTop !== "top") { leftOrTop = "left"; } var getBoundingClientRectMarginDiv = CB_Elements.id("getBoundingClientRectMarginDiv"); if (getBoundingClientRectMarginDiv === null) { var getBoundingClientRectMarginDiv = document.createElement("div"); getBoundingClientRectMarginDiv.id = "getBoundingClientRectMarginDiv"; getBoundingClientRectMarginDiv.style.position = "absolute"; getBoundingClientRectMarginDiv.style.width = getBoundingClientRectMarginDiv.style.height = "0px"; getBoundingClientRectMarginDiv.style.visibility = "hidden"; getBoundingClientRectMarginDiv.style.left = "0px"; getBoundingClientRectMarginDiv.style.top = "0px"; var tagBody = CB_Elements.tag("body", document); if (typeof(tagBody) !== "undefined" &amp;&amp; tagBody !== null &amp;&amp; typeof(tagBody[0]) !== "undefined" &amp;&amp; tagBody[0] !== null) { tagBody[0].appendChild(getBoundingClientRectMarginDiv); //firstTimeShit = true; } } if (typeof(getBoundingClientRectMarginDiv.getBoundingClientRect) !== "undefined" &amp;&amp; getBoundingClientRectMarginDiv.getBoundingClientRect !== null) { var rectMargin = getBoundingClientRectMarginDiv.getBoundingClientRect(); var margin = 0; if (typeof(rectMargin[leftOrTop]) !== "undefined" &amp;&amp; rectMargin[leftOrTop] !== null &amp;&amp; !isNaN(rectMargin[leftOrTop])) { margin = rectMargin[leftOrTop]; } } if (margin &lt; 0) { if (leftOrTop === "left") { margin += CB_Screen.getScrollLeft(); } else { margin += CB_Screen.getScrollTop(); } if (margin &lt; 0) { margin = 0; } } return margin; } /** * Tries to change the [document title]{@link https://developer.mozilla.org/en-US/docs/Web/API/Document/title} and returns it. * @function * @param {newTitle} newTitle - The desired new title. * @returns {string} */ CB_Client.setTitle = function(newTitle) { CB_Client.getDocumentBase().title = newTitle; //Chrome and Opera fix: var tagTitle = CB_Elements.tag("title"); if (typeof(tagTitle) !== "undefined" &amp;&amp; tagTitle !== null &amp;&amp; typeof(tagTitle[0]) !== "undefined" &amp;&amp; tagTitle[0] !== null) { tagTitle = tagTitle[0]; try { tagTitle.innerHTML = newTitle; } catch(E) {} //Catch to avoid IE8 error. } titleCurrent = CB_Cli