UNPKG

crossbrowdy

Version:

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

10 lines (9 loc) 3.58 MB
<html> <head> </head> <body style="background: transparent;"> <script src="scripts/docstrap.lib.js"></script> <script src="scripts/lunr.min.js"></script> <script src="scripts/fulltext-search.js"></script> <script type="text/x-docstrap-searchdb"> {"CrossBase_general_CB_Arrays.js.html":{"id":"CrossBase_general_CB_Arrays.js.html","title":"Source: CrossBase/general/CB_Arrays.js","body":" CrossBrowdy API documentation [printable] Namespaces CB_ArraysCB_AudioDetectorCB_ClientCB_CollisionsCB_ConfigurationCB_Configuration.CrossBaseCB_Configuration.CrossBrowdyCB_ControllersCB_Controllers_ProprietaryCB_Controllers_Proprietary.WIICB_Controllers_Proprietary.WII_UCB_DeviceCB_Device.AmbientLightCB_Device.BatteryCB_Device.LocationCB_Device.MotionCB_Device.OrientationCB_Device.ProximityCB_Device.VibrationCB_ElementsCB_EventsCB_KeyboardCB_Keyboard.charsCB_Keyboard.extendedCB_Keyboard.keysCB_ModulesCB_MouseCB_Mouse.CursorImageCB_NetCB_Net.FetchCB_Net.RESTCB_Net.SocketsCB_Net.Sockets.SockJSCB_Net.XHRCB_PointerCB_ScreenCB_SpeakerCB_TouchCB_baseSymbols Classes CB_AudioFileCB_AudioFileCacheCB_AudioFileSpritesCB_AudioFileSpritesPoolCB_AudioFile_API.AAPICB_AudioFile_API.ACMPCB_AudioFile_API.SM2CB_AudioFile_API.WAAPICB_CanvasCB_GraphicSpritesCB_GraphicSpritesScene Global CB_BASE_NAMECB_CREDITS_DEFAULTCB_NAMECB_OPTIONSCB_VERSIONCB_addCreditsCB_baseToBaseCB_baseToIntCB_br2nlCB_brToNlCB_combineArraysOrObjectsCB_combineAutomaticallyCB_combineJSONCB_combineURIParametersCB_combineURLParametersCB_consoleCB_copyObjectCB_countDecimalDigitsCB_countDecimalPartCB_countDecimalsCB_countIntegerDigitsCB_countIntegerPartCB_creditsCB_forEachCB_forceStringCB_getBase64StringObjectCB_getCookieCB_getDatumCB_getJSONPropertyValueCB_getLZStringObjectCB_getValueIndexCB_getValuePathCB_includeJSFileCB_indexOfCB_initCB_intToBaseCB_isArrayCB_isEmailCB_isFileLocalCB_isStringCB_lastIndexOfCB_ltrimCB_nl2brCB_nlToBrCB_numberFormatCB_numberOfDecimalDigitsCB_numberOfDecimalsCB_numberOfIntegerDigitsCB_parseJSONCB_parseStringCB_regularExpressionStringCB_renderStringCB_replaceAllCB_rtrimCB_scriptPathCB_scriptPathCalculateCB_setCookieCB_setDatumCB_sizeOfCB_sizeofCB_stringifyJSONCB_symmetricCallCB_symmetricCallClearCB_thisCB_trim Source: CrossBase/general/CB_Arrays.js /** * @file Arrays management. Contains the {@link CB_Arrays} static class. * @author Joan Alba Maldonado &lt;workindalian@gmail.com&gt; * @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 arrays. It will return itself if it is tried to be instantiated. * @namespace * @borrows CB_lastIndexOf as lastIndexOf * @borrows CB_indexOf as indexOf * @borrows CB_forEach as forEach * @borrows CB_isArray as isArray * @borrows CB_sizeOf as sizeOf * @borrows CB_replaceAll as replaceAll * @borrows CB_trim as trim * @borrows CB_rtrim as rtrim * @borrows CB_ltrim as ltrim * @borrows CB_combineArraysOrObjects as combine */ var CB_Arrays = function() { return CB_Arrays; }; { CB_Arrays.initialized = false; //It will tells whether the object has been initialized or not. //Initializes all values: CB_Arrays.init = function() { if (CB_Arrays.initialized) { return CB_Arrays; } //The object has been initialized: CB_Arrays.initialized = true; //TODO. return CB_Arrays; } CB_Arrays.lastIndexOf = function(array, searchElement, fromIndex) { return CB_lastIndexOf(array, searchElement, fromIndex, false); } //Returns the first index of a given element in an array (starting from an index if desired): CB_Arrays.indexOf = function(array, searchElement, fromIndex) { return CB_indexOf(array, searchElement, fromIndex, false); } //Tells whether an variable given is an array or not: CB_Arrays.isArray = function(variable) { return CB_isArray(variable, false); } /** * Alias for {@link CB_Arrays.sizeOf}. * @function CB_Arrays.sizeof * @see {@link CB_Arrays.sizeOf} */ /** * Alias for {@link CB_Arrays.sizeOf}. * @function CB_Arrays.count * @see {@link CB_Arrays.sizeOf} */ //Returns the size of an object given (does not need to be an array!): CB_Arrays.sizeOf = CB_Arrays.sizeof = CB_Arrays.count = function(object, onlyOwn) { return CB_sizeof(object, onlyOwn); } //Returns the given array of strings with the desired occurrences replaced. Calls itself recursively and calls the CB_replaceAll function internally. CB_Arrays.replaceAll = function(stringOrArray, stringOrArrayFind, stringReplace, caseInsensitive) //Either \"stringOrArray\" or \"stringOrArrayFind\" can also be an array of arrays of strings (as many levels as you wish). { return CB_replaceAll(stringOrArray, stringOrArrayFind, stringReplace, caseInsensitive); } //Trims all the strings that contains a given array (undesired strings can be set or otherwise will be spaces, etc.): CB_Arrays.trim = function(array, undesiredStrings) { return CB_trim(array, undesiredStrings); } //Trims all the strings from the right side that contains a given array (undesired strings can be set or otherwise will be spaces, etc.): CB_Arrays.rtrim = function(array, undesiredStrings) { return CB_rtrim(array, undesiredStrings); } //Trims all the strings from the left side that contains a given array (undesired strings can be set or otherwise will be spaces, etc.): CB_Arrays.ltrim = function(array, undesiredStrings) { return CB_ltrim(array, undesiredStrings); } //Returns a combined array or object from two arrays or objects: CB_Arrays.combine = function(arrayOrObjectA, arrayOrObjectB, avoidDuplicatedValuesInArray) { return CB_combineArraysOrObjects(arrayOrObjectA, arrayOrObjectB, avoidDuplicatedValuesInArray); } //Performs a desired function for each element of a given array (changing the value of \"this\" if desired): CB_Arrays.forEach = function(array, fun, thisObject) { return CB_forEach(array, fun, thisObject, false); } /** * Callback that is used for each iteration when looping the array. Being \"this\" the value itself. * @memberof CB_Arrays * @callback CB_Arrays.executeFunctionAll_ON_LOOP_CALLBACK * @param {*} item - Element (item) which belongs to the index which is being checked in the current iteration of the given array. * @param {integer} index - Index which is being checked in the current iteration. * @param {array} array - Whole array which is being looped. * @param {integer} delay - The \"delayBetweenEach\" used for this loop. * @returns {number} When used as a function to calculate the delay, it should return the delay desired as a number. */ /** * Callback that is used when finishes all iterations after looping the array. Being \"this\" the array itself. * @memberof CB_Arrays * @callback CB_Arrays.executeFunctionAll_ON_FINISH_CALLBACK * @param {array} array - Whole array which was being looped. * @param {integer} itemsAffected - The number of times that the \"functionEach\" callback was called (the most likely, matches the number of elements unless they are undefined or null). * @param {integer} delayMaximum - The maximum \"delay\" used. */ /** * Object used by the {@link CB_Arrays#executeFunctionAll} method when the \"returnSetTimeoutsArray\" parameter is set to true. * @memberof CB_Arrays * @typedef {Object} CB_Arrays.executeFunctionAll_OBJECT * @property {*} item - The element affected. * @property {integer} setTimeoutReturningValue - The returning value of calling the [setTimeout]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout} internally or null if it was not called, depending on the \"delayBetweenEach\" parameter. * @property {number} setTimeoutDelay - The value used as the second parameter when calling the [setTimeout]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout} internally or zero if it was not called, depending on the \"delayBetweenEach\" parameter. */ /** * Alias for {@link CB_Arrays#executeFunctionAll}. * @function CB_Arrays#executeAll * @see {@link CB_Arrays#executeFunctionAll} */ /** * Alias for {@link CB_Arrays#executeFunctionAll}. * @function CB_Arrays#forEachDelay * @see {@link CB_Arrays#executeFunctionAll} */ /** * Performs a desired action, using the provided function, on all the existing elements of a given array. Elements which are undefined or null will be skipped without calling the \"functionEach\" function. * @function * @param {array} array - A numeric array containing the elements that we want to loop. * @param {CB_Arrays.executeFunctionAll_ON_LOOP_CALLBACK} functionEach - Function that will be called for each element of the given array. As the first parameter it receives the element of the \"array\" provided being looped, as the second parameter the position of this element in the \"array\" provided, the third parameter is the array being looped and the fourth parameter will be the \"delayBetweenEach\" being used, being \"this\" the element itself. * @param {number|CB_Arrays.executeFunctionAll_ON_LOOP_CALLBACK} [delayBetweenEach=0] - If a value greater than zero is used, it will be used as the delay desired between each call to the \"functionEach\" function (calling them using the [setTimeout]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout} function internally). If not provided or the value is 0 (zero) or lower, each call to the \"functionEach\" function will be performed immediately one after the other. If a function is provided, it will be called with the same parameters as the \"functionEach\" function and its returning value will be used as the delay (executed every loop for each item). * @param {boolean} [returnSetTimeoutsArray=false] - Defines whether we want the method to return an integer or a numeric array with information of each [setTimeout]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout} call. Returning an array with information of each [setTimeout]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout} call is only useful when the [setTimeout]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout} function is called internally, which happens when the \"delayBetweenEach\" parameter is greater than 0 (zero). * @param {boolean} [delayBetweenEachAffectsFirst=false] - If set to true, the desired delay (if any) will also affect the first call to the \"functionEach\" function. * @param {CB_Arrays.executeFunctionAll_ON_FINISH_CALLBACK} [functionFinish] - Function that will be called for when it has finished looping all the items. The first parameter will be the array which was looped, the second parameter will be the number of times that the \"functionEach\" callback was called (the most likely, matches the number of elements unless they are undefined or null), and the third parameter will be the maximum \"delay\" used, being \"this\" the array itself. * @returns {integer|array} If the \"returnSetTimeoutsArray\" parameter is set to false, it will return the number of calls to the \"functionEach\" function that were performed (which should be the same number as the elements given in the \"array\" parameter). Otherwise, if the \"returnSetTimeoutsArray\" is set to true, it will return a numeric array with a {@link CB_Arrays.executeFunctionAll_OBJECT} object for each element given. The length of this array will also be the number of calls to the \"functionEach\" function that were performed. Note that if a value greater than 0 (zero) for the \"delayBetweenEach\" parameter has been provided, perhaps not all calls of the \"functionEach\" function will have been performed yet when exiting this method because of the asynchronous nature of the [setTimeout]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout} function. */ CB_Arrays.executeFunctionAll = CB_Arrays.executeAll = CB_Arrays.forEachDelay = function(array, functionEach, delayBetweenEach, returnSetTimeoutsArray, delayBetweenEachAffectsFirst, functionFinish) { if (typeof(functionEach) !== \"function\" || !CB_isArray(array)) { if (typeof(functionFinish) === \"function\") { functionFinish.call(array, array, 0, 0); } return returnSetTimeoutsArray ? [] : 0; } if (typeof(delayBetweenEach) !== \"function\" &amp;&amp; (typeof(delayBetweenEach) === \"undefined\" || delayBetweenEach === null || isNaN(delayBetweenEach) || delayBetweenEach &lt; 0)) { delayBetweenEach = 0; } var setTimeoutsInformation = []; var arrayLength = array.length; var y = 0; var setTimeoutReturningValue = null; var setTimeoutDelay = 0; var delay; var setTimeoutDelayMax = 0; for (var x = 0; x &lt; arrayLength; x++) { //If the object exists: if (typeof(array[x]) !== \"undefined\" &amp;&amp; array[x] !== null) { delay = typeof(delayBetweenEach) === \"function\" ? delayBetweenEach() : delayBetweenEach; delay = parseInt(delay) || 0; //Executes the given function (\"this\" parameters will point to the current object): if (delay === 0) { functionEach.call(array[x], array[x], x, array, delay); //\"x\" is the position of the object in the array. } else { new function(x, delay) //Closure to get unique value of \"x\" variable for each loop. { setTimeoutDelay = delayBetweenEachAffectsFirst ? delay * (y + 1) : delay * y; setTimeoutReturningValue = setTimeout ( function() { functionEach.call(array[x], array[x], x, array, delay); //\"x\" is the position of the object in the array. }, setTimeoutDelay ); setTimeoutDelayMax = setTimeoutDelay &gt; setTimeoutDelayMax ? setTimeoutDelay : setTimeoutDelayMax; }(x, delay); } setTimeoutsInformation[setTimeoutsInformation.length] = { \"item\" : array[x], \"setTimeoutReturningValue\" : setTimeoutReturningValue, \"setTimeoutDelay\" : setTimeoutDelay }; y++; } } if (typeof(functionFinish) === \"function\") { if (setTimeoutDelayMax === 0) { functionFinish.call(array, array, y, setTimeoutDelayMax); } else { setTimeout(function() { functionFinish.call(array, array, y, setTimeoutDelayMax); }, setTimeoutDelayMax + 1); } } if (returnSetTimeoutsArray) { return setTimeoutsInformation; } else { return y; } } /** * Returns an array copied from the given one. It will also make a copy of the arrays found in the values (if any), calling itself recursively. * @function * @param {array} array - The array whose values we want to copy. * @returns {object} Returns an array copied from the given one. Returns an empty array if the given \"array\" was not an array. */ CB_Arrays.copy = function(array) { if (!CB_isArray(array)) { return []; } //Removes possible duplicated values or not desired: var newArray = []; for (var x = array.length - 1; x &gt;= 0; x--) { newArray[x] = CB_isArray(array[x]) ? CB_Arrays.copy(array[x]) : array[x]; } return newArray; } /** * Alias for {@link CB_Arrays.insertElement}. * @function CB_Arrays.insert * @see {@link CB_Arrays.insertElement} */ /** * Alias for {@link CB_Arrays.insertElement}. * @function CB_Arrays.insertElementByPosition * @see {@link CB_Arrays.insertElement} */ /** * Inserts an element in the desired position of a given an array. Elements which are placed after it will be moved a position to the right (increasing their index). * @function * @param {array} array - The array whose element we want to delete. * @param {integer} [index=0] - Position of the element in the given array that we want to remove. * @param {*} item - Element (item) which belongs to the index which is being checked in the current iteration of the given array. * @param {CB_Arrays.removeDuplicated_PURGE_FUNCTION} [onInsert] - Function to call if the element is inserted, after inserting it. * @returns {array} Returns the new array (with the element inserted if it was possible). If no valid array is given, it will return an empty array. */ CB_Arrays.insertElement = CB_Arrays.insertElementByPosition = CB_Arrays.insert = function(array, index, element, onInsert) { index = parseInt(index); index = isNaN(index) ? 0 : index; if (!CB_isArray(array)) { return []; } if (index &lt; 0) { index *= -1; } //It must be a positive integer. if (index &gt; array.length) { index = array.length; } array.splice(index, 0, element); if (typeof(onInsert) === \"function\") { onInsert.call(element, element, index, array); } return array; } /** * Callback that is used as the \"purgeFunction\" parameter of the {@link CB_Arrays.removeDuplicated} function. Being \"this\" the current element (item). It should return false when we want to keep the value or true otherwise. * @memberof CB_Arrays * @callback CB_Arrays.removeDuplicated_PURGE_FUNCTION * @param {*} item - Element (item) which belongs to the index which is being checked in the current iteration used in {@link CB_Arrays.removeDuplicated}. * @param {integer} index - Index which is being checked in the current iteration used in {@link CB_Arrays.removeDuplicated}. * @param {array} array - Whole array which is being checked. * @returns {boolean} It should return false when we want to keep the value or true otherwise. */ /** * Deletes duplicated and/or not desired values (with a checking function to purge) from a numeric array. Values can be of any type. Internally, loops through the given array backwards (from the last index to the first one). * @function * @param {array} array - The array whose values we want to purge. * @param {CB_Arrays.removeDuplicated_PURGE_FUNCTION} [purgeFunction] - Callback that will be called for each item, being \"this\" the current item. It should return false when we want to keep the value or true otherwise. If the \"ignoreDuplicated\" parameter is set to true, all duplicated elements will be removed regardless of the returning value of the \"purgeFunction\" function. * @param {boolean} [ignoreDuplicated=false] - If it is set to true, it will keep duplicated values (unless the given \"purgeFunction\" purge them). * @returns {array} Returns the array purged. If no valid array is given, it will return an empty array. */ CB_Arrays.removeDuplicated = function(array, purgeFunction, ignoreDuplicated) { if (!CB_isArray(array)) { return []; } //Removes possible duplicated values or not desired: var keysDuplicatedChecker = []; for (var x = array.length - 1; x &gt;= 0; x--) { //if (typeof(purgeFunction) === \"function\" &amp;&amp; purgeFunction(array[x]) || (typeof(purgeFunction) !== \"function\" || !ignoreDuplicated) &amp;&amp; CB_indexOf(keysDuplicatedChecker, array[x]) !== -1) if (typeof(purgeFunction) === \"function\" &amp;&amp; purgeFunction.call(array[x], array[x], x, array) || !ignoreDuplicated &amp;&amp; CB_indexOf(keysDuplicatedChecker, array[x]) !== -1) { array[x] = undefined; array.splice(x, 1); continue; } keysDuplicatedChecker[keysDuplicatedChecker.length] = array[x]; } return array; } /** * Alias for {@link CB_Arrays.removeElementByPosition}. * @function CB_Arrays.removeElementByIndex * @see {@link CB_Arrays.removeElementByPosition} */ /** * Deletes an element from an array which is placed in the desired position. Elements which were after it will be moved a position to the left (decreasing their index). * @function * @param {array} array - The array whose element we want to delete. * @param {integer} [index=0] - Position of the element in the given array that we want to remove. * @param {CB_Arrays.removeDuplicated_PURGE_FUNCTION} [onRemove] - Function to call if the element is removed, before removing it. * @returns {array} Returns the new array (with the element removed if it was possible). If no valid array is given, it will return an empty array. */ CB_Arrays.removeElementByPosition = CB_Arrays.removeElementByIndex = function(array, index, onRemove) { index = parseInt(index); index = isNaN(index) ? 0 : index; if (index &lt; 0) { index *= -1; } //It must be a positive integer. return CB_Arrays.removeDuplicated(array, function(value, position, array) { if (position === index) { if (typeof(onRemove) === \"function\") { onRemove.call(value, value, position, array); } return true; } return false; }, true); } /** * Deletes a given element from an array. All occurrences will be deleted. Elements which were after a removed element will be moved a position to the left (decreasing their index). * @function * @param {array} array - The array whose element we want to delete. * @param {*} [element=undefined] - The element we want to remove. All occurrences will be deleted. Note that it is type sensitive. * @param {CB_Arrays.removeDuplicated_PURGE_FUNCTION} [onRemove] - Function to call if the element is removed, before removing it. * @returns {array} Returns the new array (with the element removed if it was possible). If no valid array is given, it will return an empty array. */ CB_Arrays.removeElement = function(array, element) { return CB_Arrays.removeDuplicated(array, function(value, position, array) { if (value === element) { if (typeof(onRemove) === \"function\") { onRemove.call(value, value, position, array); } return true; } return false; }, true); } /** * Deletes the given elements from an array. All occurrences will be deleted. Elements which were after a removed element will be moved a position to the left (decreasing their index). * @function * @param {array} array - The array whose element we want to delete. * @param {array} elements - An array with the elements we want to remove. All occurrences will be deleted. Note that it is type sensitive. * @returns {array} Returns the new array (with the element removed if it was possible). If no valid array is given, it will return an empty array. */ CB_Arrays.removeElements = function(array, elements) { if (!CB_isArray(elements)) { elements = []; } return CB_Arrays.removeDuplicated(array, function(value, position, array) { return CB_Arrays.lastIndexOf(elements, value, position) !== -1; }, true); } /** * Sorts the values of an array (using the native [Array.sort]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort} method). * @function * @param {array} array - The array whose elements we want to sort. * @param {boolean} [reversed=false] - Defines whether to sort in the reverse order or not. Only applies when comparingFunction is not provided. * @param {function} [comparingFunction] - Comparing function with the same rules as the native [Array.sort]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort} method. If provided, the \"reversed\" parameter will be ignored. * @returns {array} Returns the array ordered. If another value which is not an array is given, it will be returned again. */ CB_Arrays.sort = function(array, reversed, comparingFunction) { if (typeof(array) === \"undefined\" || array === null || !CB_Arrays.isArray(array)) { return array; } if (typeof(comparingFunction) !== \"function\") { if (reversed) { comparingFunction = function(a, b) { return b-a; }; } else { comparingFunction = function(a, b) { return a-b; }; } } return array.sort(comparingFunction); } /** * Sorts an array using the [bubble sort (sinking sort) method]{@link https://en.wikipedia.org/wiki/Bubble_sort}. Internally, it uses the \"&gt;\" operator for comparing values as they will be treated as numbers. * @function * @param {array} array - The array whose elements we want to sort. * @param {boolean} [reversed=false] - Defines whether to sort in the reverse order or not. * @todo Think about accepting a comparing function (as the \"sort\" method). * @returns {array} Returns the array ordered. If another value which is not an array is given, it will be returned again. */ CB_Arrays.bsort = function(array, reversed, comparingFunction) //NOTE: think about accepting a comparing function. { if (typeof(array) === \"undefined\" || array === null || !CB_Arrays.isArray(array)) { return array; } var arrayLength = array.length; for (var x = 1; x &lt; arrayLength; x++) { for (var y = 0; y &lt; arrayLength-x; y++) { if (!reversed &amp;&amp; array[y] &gt; array[y+1] || reversed &amp;&amp; array[y] &lt; array[y+1]) { var aux = array[y]; array[y] = array[y+1]; array[y+1] = aux; } } } return array; } //Sorts an array using merge sort method: CB_Arrays.msort = function(array, reversed, comparingFunction) //NOTE: think about accepting a comparing function. { if (typeof(array) === \"undefined\" || array === null || !CB_Arrays.isArray(array)) { return array; } //TODO. array = CB_Arrays.sort(array, reversed, comparingFunction); //DELETE THIS! return array; } //Sorts an array using quick sort method: CB_Arrays.qsort = function(array, reversed, comparingFunction) //NOTE: think about accepting a comparing function. { if (typeof(array) === \"undefined\" || array === null || !CB_Arrays.isArray(array)) { return array; } //TODO. array = CB_Arrays.sort(array, reversed, comparingFunction); //DELETE THIS! return array; } //Sorts an array using selection sort method: CB_Arrays.ssort = function(array, reversed, comparingFunction) //NOTE: think about accepting a comparing function. { if (typeof(array) === \"undefined\" || array === null || !CB_Arrays.isArray(array)) { return array; } //TODO. array = CB_Arrays.sort(array, reversed, comparingFunction); //DELETE THIS! return array; } //Sorts an array using insertion sort method: CB_Arrays.isort = function(array, reversed, comparingFunction) //NOTE: think about accepting a comparing function. { if (typeof(array) === \"undefined\" || array === null || !CB_Arrays.isArray(array)) { return array; } //TODO. array = CB_Arrays.sort(array, reversed, comparingFunction); //DELETE THIS! return array; } //Sorts an array using cocktail sort (bidirectional bubble) method: CB_Arrays.csort = function(array, reversed, comparingFunction) //NOTE: think about accepting a comparing function. { if (typeof(array) === \"undefined\" || array === null || !CB_Arrays.isArray(array)) { return array; } //TODO. array = CB_Arrays.sort(array, reversed, comparingFunction); //DELETE THIS! return array; } } × Search results Close "},"CrossBase_general_CB_data.js.html":{"id":"CrossBase_general_CB_data.js.html","title":"Source: CrossBase/general/CB_data.js","body":" CrossBrowdy API documentation [printable] Namespaces CB_ArraysCB_AudioDetectorCB_ClientCB_CollisionsCB_ConfigurationCB_Configuration.CrossBaseCB_Configuration.CrossBrowdyCB_ControllersCB_Controllers_ProprietaryCB_Controllers_Proprietary.WIICB_Controllers_Proprietary.WII_UCB_DeviceCB_Device.AmbientLightCB_Device.BatteryCB_Device.LocationCB_Device.MotionCB_Device.OrientationCB_Device.ProximityCB_Device.VibrationCB_ElementsCB_EventsCB_KeyboardCB_Keyboard.charsCB_Keyboard.extendedCB_Keyboard.keysCB_ModulesCB_MouseCB_Mouse.CursorImageCB_NetCB_Net.FetchCB_Net.RESTCB_Net.SocketsCB_Net.Sockets.SockJSCB_Net.XHRCB_PointerCB_ScreenCB_SpeakerCB_TouchCB_baseSymbols Classes CB_AudioFileCB_AudioFileCacheCB_AudioFileSpritesCB_AudioFileSpritesPoolCB_AudioFile_API.AAPICB_AudioFile_API.ACMPCB_AudioFile_API.SM2CB_AudioFile_API.WAAPICB_CanvasCB_GraphicSpritesCB_GraphicSpritesScene Global CB_BASE_NAMECB_CREDITS_DEFAULTCB_NAMECB_OPTIONSCB_VERSIONCB_addCreditsCB_baseToBaseCB_baseToIntCB_br2nlCB_brToNlCB_combineArraysOrObjectsCB_combineAutomaticallyCB_combineJSONCB_combineURIParametersCB_combineURLParametersCB_consoleCB_copyObjectCB_countDecimalDigitsCB_countDecimalPartCB_countDecimalsCB_countIntegerDigitsCB_countIntegerPartCB_creditsCB_forEachCB_forceStringCB_getBase64StringObjectCB_getCookieCB_getDatumCB_getJSONPropertyValueCB_getLZStringObjectCB_getValueIndexCB_getValuePathCB_includeJSFileCB_indexOfCB_initCB_intToBaseCB_isArrayCB_isEmailCB_isFileLocalCB_isStringCB_lastIndexOfCB_ltrimCB_nl2brCB_nlToBrCB_numberFormatCB_numberOfDecimalDigitsCB_numberOfDecimalsCB_numberOfIntegerDigitsCB_parseJSONCB_parseStringCB_regularExpressionStringCB_renderStringCB_replaceAllCB_rtrimCB_scriptPathCB_scriptPathCalculateCB_setCookieCB_setDatumCB_sizeOfCB_sizeofCB_stringifyJSONCB_symmetricCallCB_symmetricCallClearCB_thisCB_trim Source: CrossBase/general/CB_data.js /** * @file Data and related management. * @author Joan Alba Maldonado &lt;workindalian@gmail.com&gt; * @license Creative Commons Attribution 4.0 International. See more at {@link https://crossbrowdy.com/about#what_is_the_crossbrowdy_copyright_and_license}. * @todo A function equivalent to htmlentities/htmlspecialchars (as in PHP). */ //If we want to extend the DOM, we do it: if (CB_Configuration[CB_BASE_NAME].EXTEND_DOM) { try { if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement, fromIndex) { CB_indexOf(this, searchElement, fromIndex, true); } } if (!Array.prototype.lastIndexOf) { Array.prototype.lastIndexOf = function(searchElement, fromIndex) { CB_lastIndexOf(this, searchElement, fromIndex, true); } } if (!Array.isArray) { Array.isArray = function() { return CB_isArray(this, true); } } //isArray is a method which is not in the prototype. //if (!Array.prototype.isArray) { Array.prototype.isArray = function() { return CB_isArray(this, true); } } if (!Array.prototype.forEach) { Array.prototype.forEach = function(callback, thisArg) { CB_forEach(this, callback, thisArg, true); } } if (!NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; } if (!HTMLCollection.prototype.forEach) { HTMLCollection.prototype.forEach = Array.prototype.forEach; } } catch(E) {} } /** * Implementation of [Array.lastIndexOf]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf} method for browsers that do not support it natively. &lt;br&gt; Returns the last index of a given element that exists in an array (starting from a certain index if desired) or -1 if not found. * @function * @param {array} array - Desired array. * @param {*} searchElement - Element we want to search. Note that it is type sensitive. * @param {integer} [fromIndex=array.length - 1] - First index of the given array where the search will start. * @param {boolean} [extendedDOM=false] - Defines whether the function is being called by a native function which was extended. Internal usage recommended only. * @returns {integer} * @todo Implement the \"fromIndex\" in the polyfill. */ //* Polyfill source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf function CB_lastIndexOf(array, searchElement, fromIndex, extendedDOM) { 'use strict'; if (!extendedDOM) { if (array &amp;&amp; array.lastIndexOf) { return array.lastIndexOf.call(array, searchElement, fromIndex || array.length); } //It can be a string. if (Array.prototype.lastIndexOf) { return Array.prototype.lastIndexOf.call(array, searchElement, fromIndex || array.length); } } if (typeof(array) === \"undefined\" || array === null) { throw new TypeError(); } var n, k, t = Object(array), len = t.length &gt;&gt;&gt; 0; if (len === 0) { return -1; } n = len - 1; if (arguments.length &gt; 2 &amp;&amp; typeof(arguments[2]) !== \"undefined\" &amp;&amp; arguments[2] !== null &amp;&amp; !isNaN(arguments[2])) { n = Number(arguments[2]); if (n != n) { n = 0; } //if (n != n) { n = len - 1; } else if (n != 0 &amp;&amp; n != (1 / 0) &amp;&amp; n != -(1 / 0)) { n = (n &gt; 0 || -1) * Math.floor(Math.abs(n)); } } for (k = n &gt;= 0 ? Math.min(n, len - 1) : len - Math.abs(n); k &gt;= 0; k--) { if (k in t &amp;&amp; t[k] === searchElement) { return k; } } return -1; } /** * Implementation of [Array.indexOf]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf} method for arrays in browsers that do not support it natively. &lt;br&gt; Returns the first index of a given element that exists in an array (starting from a certain index if desired) or -1 if not found. * @function * @param {array} array - Desired array. * @param {*} searchElement - Element we want to search. Note that it is type sensitive. * @param {integer} [fromIndex=0] - First index of the given array where the search will start. * @param {boolean} [extendedDOM=false] - Defines whether the function is being called by a native function which was extended. Internal usage recommended only. * @returns {integer} */ //* Polyfill source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf function CB_indexOf(array, searchElement, fromIndex, extendedDOM) { if (!extendedDOM) { if (array &amp;&amp; array.indexOf) { return array.indexOf.call(array, searchElement, fromIndex); } //It can be a string. if (Array.prototype.indexOf) { return Array.prototype.indexOf.call(array, searchElement, fromIndex); } } if (typeof(array) === \"undefined\" || array === null) { throw new TypeError( '\"array\" is null or not defined' ); } var length = array.length &gt;&gt;&gt; 0; // Hack to convert object.length to a UInt32 fromIndex = +fromIndex || 0; if (Math.abs(fromIndex) === Infinity) { fromIndex = 0; } if (fromIndex &lt; 0) { fromIndex += length; if (fromIndex &lt; 0) { fromIndex = 0; } } for (;fromIndex &lt; length; fromIndex++) { if (array[fromIndex] === searchElement) { return fromIndex; } } return -1; } /** * Implementation of the [Array.forEach]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach} method for browsers that do not support it natively. &lt;br&gt; Executes a function for each element of a given array. * @function * @param {array} array - Desired array. * @param {function} callback - Function that will be executed for each element of the given array. Following the same rules as the native [Array.forEach]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach} method, it will receive three arguments: currentValue, currentIndex and the array given. * @param {*} [thisArg] - Value that will be passed as \"this\" every time the function is called. * @param {boolean} [extendedDOM=false] - Defines whether the function is being called by a native function which was extended. Internal usage recommended only. * @returns {array|undefined} If the \"extendedDOM\" parameter is set to false, returns the given \"array\" again. Otherwise, returns undefined. */ //* Polyfill source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach function CB_forEach(array, callback, thisArg, extendedDOM) { \"use strict\"; if (!extendedDOM) { if (array.forEach) { array.forEach.call(array, callback, thisArg); return array; } else if (Array.prototype.forEach) { Array.prototype.forEach.call(array, callback, thisArg); return array; } } if (array === void 0 || array === null) { throw new TypeError(); } if (typeof callback !== \"function\") { throw new TypeError(); } var t = Object(array); var len = t.length &gt;&gt;&gt; 0; //thisArg = arguments.length &gt;= 2 ? arguments[1] : void 0; for (var i = 0; i &lt; len; i++) { if (i in t) { callback.call(thisArg, t[i], i, t); } } return extendedDOM ? undefined : array; } /** * Implementation of [Array.isArray]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray} method for browsers that do not support it natively. &lt;br&gt; Returns whether a given element is an array or not. * @function * @param {*} element - The element we want to check. * @param {boolean} [extendedDOM=false] - Defines whether the function is being called by a native function which was extended. Internal usage recommended only. * @returns {boolean} * @todo Think about a parameter to check whether the given array is a typed array (for example, 'Uint8Array') or not. */ function CB_isArray(element, extendedDOM) { if (typeof(element) === \"undefined\" || element === null) { return false; } var isArray = false; if (Array) { if (Array.isArray &amp;&amp; !extendedDOM) { isArray = Array.isArray(element); } else { isArray = element instanceof Array; if (!isArray) //It could still be an Array from another frame. { isArray = (Object.prototype.toString.call(element) === '[object Array]'); } } } return isArray; } /** * Alias for {@link CB_sizeOf}. * @function CB_sizeof * @see {@link CB_sizeOf} */ /** * Returns the size of an object or array. * @function * @param {Object|array} element - The element whose size we want to know. It should be an object or an array. * @param {boolean} [onlyOwn=false] - If the \"element\" given is not an object, this parameter will be ignored. Otherwise, if it is set to true, it will only have into account the properties which the object has as their own property and have not been inherited (using the [Object.hasOwnProperty]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty} method). * @returns {integer} If an object is provided, the size will be the number of its properties. Otherwise, if an array is given, the size will be the numbers of its indexes ([Array.length]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length} property). */ function CB_sizeOf(object, onlyOwn) { var size = 0; if (CB_isArray(object) &amp;&amp; typeof(object.length) !== \"undefined\" &amp;&amp; object.length !== null &amp;&amp; !isNaN(object.length) &amp;&amp; object.length &gt; 0) { return object.length; } for (var key in object) { if (!onlyOwn || object.hasOwnProperty(key)) { size++; } } return size; } var CB_sizeof = CB_sizeOf; //Alias for the function. /** * Returns whether a given element is a string or not. * @function * @param {*} element - The element we want to check. * @returns {boolean} */ function CB_isString(element) { return (typeof(element) === \"string\" || element instanceof String); } /** * Returns back the given element if it is a string or an empty string otherwise. * @function * @param {*} element - The element that will be checked. * @returns {string} */ function CB_forceString(element) { if (!CB_isString(element)) { return \"\"; } else { return element; } } /** * Returns back the given element as a string if it could be parsed or an empty string otherwise. * @function * @param {*} element - The element that will be checked. * @returns {string} */ function CB_parseString(element) { if (typeof(element) === \"undefined\" || element === null || element === true || element === false || !CB_isString(element) &amp;&amp; isNaN(element)) { return \"\"; } else { return element + \"\"; } } /** * Trims a given string or array of strings (modifying the given array), taking off the desired strings or otherwise trimming spaces, tabs (\"\\t\"), new lines (\"\\n\") and carriage returns (\"\\r\"). Case sensitive. * @function * @param {string|array} element - The element that will be trimmed. It should be either a string or an array of strings. * @param {string|array} [undesiredStrings=[ \" \", \"\\n\", \"\\r\", \"\\t\" ]] - String or an array with the strings that we want to trim off the given element. * @returns {string|array} Returns the given element again if it was an string, a number (it will be casted to a string) or an array of strings, trimmed if it has been possible. If it was another type, returns an empty string. * @todo Accept a \"recursive\" parameter (boolean) to affect multiple levels (array of arrays of strings, etc.). * @todo Consider accepting objects instead of arrays in the \"element\" parameter. */ function CB_trim(element, undesiredStrings) { if (CB_isArray(element)) { for (var x = 0, elementLength = element.length; x &lt; elementLength; x++) { element[x] = CB_trim(element[x], undesiredStrings); } return element; } //else if (typeof(element) !== \"undefined\" &amp;&amp; element !== null &amp;&amp; !isNaN(element)) { return element; } else if (typeof(element) === \"undefined\" || element === null) { return \"\"; } else if (element === true || element === false) { return \"\"; } else if (!isNaN(element)) { element = element + \"\"; } else if (!CB_isString(element)) { return \"\"; } else if (typeof(element.trim) === \"function\") { //Only calls the native function when the \"undesiredStringFound\" parameter is the default one (it will not just trim blank spaces but also \"\\r\", \"\\n\"...): if (!CB_isArray(undesiredStrings) &amp;&amp; !CB_isString(undesiredStrings)) { return element.trim(); } } //return element.replace(/^\\s+|\\s+$/g, \"\"); element = CB_rtrim(element, undesiredStrings); element = CB_ltrim(element, undesiredStrings); return element; } /** * Trims the right side of a given string or array of strings (modifying the given array), taking off the desired strings or otherwise trimming spaces, tabs (\"\\t\"), new lines (\"\\n\") and carriage returns (\"\\r\"). Case sensitive. * @function * @param {string|array} element - The element that will be trimmed. It should be either a string or an array of strings. * @param {string|array} [undesiredStrings=[ \" \", \"\\n\", \"\\r\", \"\\t\" ]] - String or an array with the strings that we want to trim off the given element. * @returns {string|array} Returns the given element again if it was an string, a number (it will be casted to a string) or an array of strings, trimmed if it has been possible. If it was another type, returns an empty string. * @todo Accept a \"recursive\" parameter (boolean) to affect multiple levels (array of arrays of strings, etc.). * @todo Consider accepting objects instead of arrays in the \"element\" parameter. * @todo Think about optimizing (using a counter for the number of occurrences in the loop and trim all the occurrences when finished). */ function CB_rtrim(element, undesiredStrings) { if (CB_isArray(element)) { for (var x = 0, elementLength = element.length; x &lt; elementLength; x++) { element[x] = CB_rtrim(element[x], undesiredStrings); } return element; } //else if (typeof(element) !== \"undefined\" &amp;&amp; element !== null &amp;&amp; !isNaN(element)) { return element; } else if (typeof(element) === \"undefined\" || element === null) { return \"\"; } else if (element === true || element === false) { return \"\"; } else if (!isNaN(element)) { element = element + \"\"; } else if (!CB_isString(element)) { return \"\"; } if (CB_isString(undesiredStrings)) { undesiredStrings = [ undesiredStrings ]; } else if (!CB_isArray(undesiredStrings)) { undesiredStrings = [ \" \", \"\\n\", \"\\r\", \"\\t\" ]; //Only calls the native function when the \"undesiredStringFound\" parameter is the default one (it will not just trim blank spaces but also \"\\r\", \"\\n\"...): if (typeof(element.trimEnd) === \"function\") { return element.trimEnd(); } } //Loops through the undesired strings: var undesiredStringsLength = undesiredStrings.length; var undesiredStringFound = false; for (var x = 0; x &lt; undesiredStringsLength; x++) { //Trims undesired string at the end: while (element.substring(element.length - undesiredStrings[x].length, element.length) === undesiredStrings[x]) { element = element.substring(0, element.length - undesiredStrings[x].length); undesiredStringFound = true; } //If an undesired string has been found, we are looking for more than one undesired strings and the loop is at the end, starts the loop again: if (undesiredStringFound &amp;&amp; undesiredStringsLength &gt; 1 &amp;&amp; x + 1 === undesiredStringsLength) { undesiredStringFound = false; x = -1; } } return element; } /** * Trims the left side of a given string or array of strings (modifying the given array), taking off the desired strings or otherwise trimming spaces, tabs (\"\\t\"), new lines (\"\\n\") and carriage returns (\"\\r\"). Case sensitive. * @function * @param {string|array} element - The element that will be trimmed. It should be either a string or an array of strings. * @param {string|array} [undesiredStrings=[ \" \", \"\\n\", \"\\r\", \"\\t\" ]] - String or an array with the strings that we want to trim off the given element. * @returns {string|array} Returns the given element again if it was an string, a number (it will be casted to a string) or an array of strings, trimmed if it has been possible. If it was another type, returns an empty string. * @todo Accept a \"recursive\" parameter (boolean) to affect multiple levels (array of arrays of strings, etc.). * @todo Consider accepting objects instead of arrays in the \"element\" parameter. * @todo Think about optimizing (using a counter for the number of occurrences in the loop and trim all the occurrences when finished). */ function CB_ltrim(element, undesiredStrings) { if (CB_isArray(element)) { for (var x = 0, elementLength = element.length; x &lt; elementLength; x++) { element[x] = CB_ltrim(element[x], undesiredStrings); } return element; } //else if (typeof(element) !== \"undefined\" &amp;&amp; element !== null &amp;&amp; !isNaN(element)) { return element; } else if (typeof(element) === \"undefined\" || element === null) { return \"\"; } else if (element === true || element === false) { return \"\"; } else if (!isNaN(element)) { element = element + \"\"; } else if (!CB_isString(element)) { return \"\"; } if (CB_isString(undesiredStrings)) { undesiredStrings = [ undesiredStrings ]; } else if (!CB_isArray(undesiredStrings)) { undesiredStrings = [ \" \", \"\\n\", \"\\r\", \"\\t\" ]; //Only calls the native function when the \"undesiredStringFound\" parameter is the default one (it will not just trim blank spaces but also \"\\r\", \"\\n\"...): if (typeof(element.trimStart) === \"function\") { return element.trimStart(); } } //Loops through the undesired strings: var undesiredStringsLength = undesiredStrings.length; var undesiredStringFound = false; for (var x = 0; x &lt; undesiredStringsLength; x++) { //Trims undesired string at the beginning: while (element.substring(0, undesiredStrings[x].length) === undesiredStrings[x]) { element = element.substring(undesiredStrings[x].length, element.length); undesiredStringFound = true; } //If an undesired string has been found, we are looking for more than one undesired strings and the loop is at the end, starts the loop again: if (undesiredStringFound &amp;&amp; undesiredStringsLength &gt; 1 &amp;&amp; x + 1 === undesiredStringsLength) { undesiredStringFound = false; x = -1; } } return element; } /** * Alias for {@link CB_nl2br}. * @function CB_nlToBr * @see {@link CB_nl2br} */ /** * Changes new lines (\\n) for &amp;lt;br /&amp;gt;'s in a given string. * @function * @param {string} string - The string we want to modify. * @returns {string} Returns the string with all the occurrences replaced or an empty string if the element given was not a string. */ function CB_nl2br(string) { //If it is not a string, uses an empty string instead: if (!CB_isString(string)) { string = \"\"; } //Parses the variable to string type: string = string.toString(); string = string.replace(/\\n/gi, \"&lt;br /&gt;\"); return string; } var CB_nlToBr = CB_nl2br; //Alias for the function. /** * Alias for {@link CB_br2nl}. * @function CB_brToNl * @see {@link CB_br2nl} */ /** * Changes &amp;lt;br /&amp;gt;'s, &amp;lt;br/&amp;gt;'s and &amp;lt;br&amp;gt;'s for new lines (\\n) in a given string. * @function * @param {string} string - The string we want to modify. * @returns {string} Returns the string with all the occurrences replaced or an empty string if the element given was not a string. */ function CB_br2nl(string) { //If it is not a string, uses an empty string instead: if (!CB_isString(string)) { string = \"\"; } //Parses the variable to string type: string = string.toString(); string = string.replace(/&lt;br \\/&gt;/gi, \"\\n\"); string = string.replace(/&lt;br\\/&gt;/gi, \"\\n\"); string = string.replace(/&lt;br&gt;/gi, \"\\n\"); return string; } var CB_brToNl = CB_br2nl; //Alias for the function. /** * Tries to guess whether a given file path (absolute or relative) is a local address or not. It will be assumed as local if the path uses the \"file:\" protocol or the current script is running locally and the path does not use the \"http:\", \"https:\" or \"ftp:\" protocols. * @function * @param {string} filePath - The file path we want to check. * @returns {boolean} Returns whether the given file path is a local address or not. */ function CB_isFileLocal(filePath) { var isFileLocal = false; filePath = CB_trim(filePath); if (filePath !== \"\") { if (filePath.substring(0, 5) === \"file:\" || CB_Client.isRunningLocally() &amp;&amp; filePath.substring(0, 5) !== \"http:\" &amp;&amp; filePath.substring(0, 6) !== \"https:\" &amp;&amp; filePath.substring(0, 4) !== \"ftp:\") { isFileLocal = true; } } return isFileLocal; } /** * Processes a given string as a template and returns it rendered (if possible) with the values of the given JSON object. Tries to use [Handlebars]{@link https://handlebarsjs.com/} as the first choice but if is is not available it will just replace all occurrences with vanilla JavaScript. * @function * @param {string} str - The string we want to render. * @param {Object} [JSONObject=CB_JSONData] - The JSON object which contains the values. If not provided, it will try to use the global CB_JSONData object in the case it exists. * @param {boolean} [forceVanilla=false] - Forces vanilla JavaScript rendering instead of using [Handlebars]{@link https://handlebarsjs.com/}. * @param {integer} [depthLevelMax=10] - Maximum depth level allowed to read the object to render the string. Only applies when it is rendered by vanilla JavaScript. For performance purposes. * @returns {str} */ function CB_renderString(string, JSONObject, forceVanilla, depthLevelMax) { string = CB_trim(string); //If a JSON object is not given, uses the default one (if any): if (typeof(JSONObject) === \"undefined\" || JSONObject === null) { if (typeof(CB_JSONData) !== \"undefined\" &amp;&amp; CB_JSONData !== null) { JSONObject = CB_JSONData; } } //If we do not want vanilla JavaScript rendering and Handlebars is present, uses it: if (!forceVanilla &amp;&amp; typeof(Handlebars) !== \"undefined\" &amp;&amp; Handlebars !== null &amp;&amp; typeof(Handlebars.compile) === \"function\") { //Returns the template rendered: return Handlebars.compile(string)(JSONObject); //Using Handlebars. } //...otherwise, just replaces all occurrences in the given string: else { return CB_renderStringRecursively(string, JSONObject, false, depthLevelMax); } } //Renders a given string recursively with the g