<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>JSDoc: Source: utils.js</title> | |
<script src="scripts/prettify/prettify.js"> </script> | |
<script src="scripts/prettify/lang-css.js"> </script> | |
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | |
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | |
</head> | |
<body> | |
<div id="main"> | |
<h1 class="page-title">Source: utils.js</h1> | |
<section> | |
<article> | |
<pre class="prettyprint source"><code>/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
'use strict'; | |
/** @module odatajs/utils */ | |
function inBrowser() { | |
return typeof window !== 'undefined'; | |
} | |
/** Creates a new ActiveXObject from the given progId. | |
* @param {String} progId - ProgId string of the desired ActiveXObject. | |
* @returns {Object} The ActiveXObject instance. Null if ActiveX is not supported by the browser. | |
* This function throws whatever exception might occur during the creation | |
* of the ActiveXObject. | |
*/ | |
var activeXObject = function (progId) { | |
if (window.ActiveXObject) { | |
return new window.ActiveXObject(progId); | |
} | |
return null; | |
}; | |
/** Checks whether the specified value is different from null and undefined. | |
* @param [value] Value to check ( may be null) | |
* @returns {Boolean} true if the value is assigned; false otherwise. | |
*/ | |
function assigned(value) { | |
return value !== null && value !== undefined; | |
} | |
/** Checks whether the specified item is in the array. | |
* @param {Array} [arr] Array to check in. | |
* @param item - Item to look for. | |
* @returns {Boolean} true if the item is contained, false otherwise. | |
*/ | |
function contains(arr, item) { | |
var i, len; | |
for (i = 0, len = arr.length; i < len; i++) { | |
if (arr[i] === item) { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** Given two values, picks the first one that is not undefined. | |
* @param a - First value. | |
* @param b - Second value. | |
* @returns a if it's a defined value; else b. | |
*/ | |
function defined(a, b) { | |
return (a !== undefined) ? a : b; | |
} | |
/** Delays the invocation of the specified function until execution unwinds. | |
* @param {Function} callback - Callback function. | |
*/ | |
function delay(callback) { | |
if (arguments.length === 1) { | |
window.setTimeout(callback, 0); | |
return; | |
} | |
var args = Array.prototype.slice.call(arguments, 1); | |
window.setTimeout(function () { | |
callback.apply(this, args); | |
}, 0); | |
} | |
/** Throws an exception in case that a condition evaluates to false. | |
* @param {Boolean} condition - Condition to evaluate. | |
* @param {String} message - Message explaining the assertion. | |
* @param {Object} data - Additional data to be included in the exception. | |
*/ | |
function djsassert(condition, message, data) { | |
if (!condition) { | |
throw { message: "Assert fired: " + message, data: data }; | |
} | |
} | |
/** Extends the target with the specified values. | |
* @param {Object} target - Object to add properties to. | |
* @param {Object} values - Object with properties to add into target. | |
* @returns {Object} The target object. | |
*/ | |
function extend(target, values) { | |
for (var name in values) { | |
target[name] = values[name]; | |
} | |
return target; | |
} | |
function find(arr, callback) { | |
/** Returns the first item in the array that makes the callback function true. | |
* @param {Array} [arr] Array to check in. ( may be null) | |
* @param {Function} callback - Callback function to invoke once per item in the array. | |
* @returns The first item that makes the callback return true; null otherwise or if the array is null. | |
*/ | |
if (arr) { | |
var i, len; | |
for (i = 0, len = arr.length; i < len; i++) { | |
if (callback(arr[i])) { | |
return arr[i]; | |
} | |
} | |
} | |
return null; | |
} | |
function isArray(value) { | |
/** Checks whether the specified value is an array object. | |
* @param value - Value to check. | |
* @returns {Boolean} true if the value is an array object; false otherwise. | |
*/ | |
return Object.prototype.toString.call(value) === "[object Array]"; | |
} | |
/** Checks whether the specified value is a Date object. | |
* @param value - Value to check. | |
* @returns {Boolean} true if the value is a Date object; false otherwise. | |
*/ | |
function isDate(value) { | |
return Object.prototype.toString.call(value) === "[object Date]"; | |
} | |
/** Tests whether a value is an object. | |
* @param value - Value to test. | |
* @returns {Boolean} True is the value is an object; false otherwise. | |
* Per javascript rules, null and array values are objects and will cause this function to return true. | |
*/ | |
function isObject(value) { | |
return typeof value === "object"; | |
} | |
/** Parses a value in base 10. | |
* @param {String} value - String value to parse. | |
* @returns {Number} The parsed value, NaN if not a valid value. | |
*/ | |
function parseInt10(value) { | |
return parseInt(value, 10); | |
} | |
/** Renames a property in an object. | |
* @param {Object} obj - Object in which the property will be renamed. | |
* @param {String} oldName - Name of the property that will be renamed. | |
* @param {String} newName - New name of the property. | |
* This function will not do anything if the object doesn't own a property with the specified old name. | |
*/ | |
function renameProperty(obj, oldName, newName) { | |
if (obj.hasOwnProperty(oldName)) { | |
obj[newName] = obj[oldName]; | |
delete obj[oldName]; | |
} | |
} | |
/** Default error handler. | |
* @param {Object} error - Error to handle. | |
*/ | |
function throwErrorCallback(error) { | |
throw error; | |
} | |
/** Removes leading and trailing whitespaces from a string. | |
* @param {String} str String to trim | |
* @returns {String} The string with no leading or trailing whitespace. | |
*/ | |
function trimString(str) { | |
if (str.trim) { | |
return str.trim(); | |
} | |
return str.replace(/^\s+|\s+$/g, ''); | |
} | |
/** Returns a default value in place of undefined. | |
* @param [value] Value to check (may be null) | |
* @param defaultValue - Value to return if value is undefined. | |
* @returns value if it's defined; defaultValue otherwise. | |
* This should only be used for cases where falsy values are valid; | |
* otherwise the pattern should be 'x = (value) ? value : defaultValue;'. | |
*/ | |
function undefinedDefault(value, defaultValue) { | |
return (value !== undefined) ? value : defaultValue; | |
} | |
// Regular expression that splits a uri into its components: | |
// 0 - is the matched string. | |
// 1 - is the scheme. | |
// 2 - is the authority. | |
// 3 - is the path. | |
// 4 - is the query. | |
// 5 - is the fragment. | |
var uriRegEx = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#:]+)?(\?[^#]*)?(#.*)?/; | |
var uriPartNames = ["scheme", "authority", "path", "query", "fragment"]; | |
/** Gets information about the components of the specified URI. | |
* @param {String} uri - URI to get information from. | |
* @return {Object} An object with an isAbsolute flag and part names (scheme, authority, etc.) if available. | |
*/ | |
function getURIInfo(uri) { | |
var result = { isAbsolute: false }; | |
if (uri) { | |
var matches = uriRegEx.exec(uri); | |
if (matches) { | |
var i, len; | |
for (i = 0, len = uriPartNames.length; i < len; i++) { | |
if (matches[i + 1]) { | |
result[uriPartNames[i]] = matches[i + 1]; | |
} | |
} | |
} | |
if (result.scheme) { | |
result.isAbsolute = true; | |
} | |
} | |
return result; | |
} | |
/** Builds a URI string from its components. | |
* @param {Object} uriInfo - An object with uri parts (scheme, authority, etc.). | |
* @returns {String} URI string. | |
*/ | |
function getURIFromInfo(uriInfo) { | |
return "".concat( | |
uriInfo.scheme || "", | |
uriInfo.authority || "", | |
uriInfo.path || "", | |
uriInfo.query || "", | |
uriInfo.fragment || ""); | |
} | |
// Regular expression that splits a uri authority into its subcomponents: | |
// 0 - is the matched string. | |
// 1 - is the userinfo subcomponent. | |
// 2 - is the host subcomponent. | |
// 3 - is the port component. | |
var uriAuthorityRegEx = /^\/{0,2}(?:([^@]*)@)?([^:]+)(?::{1}(\d+))?/; | |
// Regular expression that matches percentage enconded octects (i.e %20 or %3A); | |
var pctEncodingRegEx = /%[0-9A-F]{2}/ig; | |
/** Normalizes the casing of a URI. | |
* @param {String} uri - URI to normalize, absolute or relative. | |
* @returns {String} The URI normalized to lower case. | |
*/ | |
function normalizeURICase(uri) { | |
var uriInfo = getURIInfo(uri); | |
var scheme = uriInfo.scheme; | |
var authority = uriInfo.authority; | |
if (scheme) { | |
uriInfo.scheme = scheme.toLowerCase(); | |
if (authority) { | |
var matches = uriAuthorityRegEx.exec(authority); | |
if (matches) { | |
uriInfo.authority = "//" + | |
(matches[1] ? matches[1] + "@" : "") + | |
(matches[2].toLowerCase()) + | |
(matches[3] ? ":" + matches[3] : ""); | |
} | |
} | |
} | |
uri = getURIFromInfo(uriInfo); | |
return uri.replace(pctEncodingRegEx, function (str) { | |
return str.toLowerCase(); | |
}); | |
} | |
/** Normalizes a possibly relative URI with a base URI. | |
* @param {String} uri - URI to normalize, absolute or relative | |
* @param {String} base - Base URI to compose with (may be null) | |
* @returns {String} The composed URI if relative; the original one if absolute. | |
*/ | |
function normalizeURI(uri, base) { | |
if (!base) { | |
return uri; | |
} | |
var uriInfo = getURIInfo(uri); | |
if (uriInfo.isAbsolute) { | |
return uri; | |
} | |
var baseInfo = getURIInfo(base); | |
var normInfo = {}; | |
var path; | |
if (uriInfo.authority) { | |
normInfo.authority = uriInfo.authority; | |
path = uriInfo.path; | |
normInfo.query = uriInfo.query; | |
} else { | |
if (!uriInfo.path) { | |
path = baseInfo.path; | |
normInfo.query = uriInfo.query || baseInfo.query; | |
} else { | |
if (uriInfo.path.charAt(0) === '/') { | |
path = uriInfo.path; | |
} else { | |
path = mergeUriPathWithBase(uriInfo.path, baseInfo.path); | |
} | |
normInfo.query = uriInfo.query; | |
} | |
normInfo.authority = baseInfo.authority; | |
} | |
normInfo.path = removeDotsFromPath(path); | |
normInfo.scheme = baseInfo.scheme; | |
normInfo.fragment = uriInfo.fragment; | |
return getURIFromInfo(normInfo); | |
} | |
/** Merges the path of a relative URI and a base URI. | |
* @param {String} uriPath - Relative URI path. | |
* @param {String} basePath - Base URI path. | |
* @returns {String} A string with the merged path. | |
*/ | |
function mergeUriPathWithBase(uriPath, basePath) { | |
var path = "/"; | |
var end; | |
if (basePath) { | |
end = basePath.lastIndexOf("/"); | |
path = basePath.substring(0, end); | |
if (path.charAt(path.length - 1) !== "/") { | |
path = path + "/"; | |
} | |
} | |
return path + uriPath; | |
} | |
/** Removes the special folders . and .. from a URI's path. | |
* @param {string} path - URI path component. | |
* @returns {String} Path without any . and .. folders. | |
*/ | |
function removeDotsFromPath(path) { | |
var result = ""; | |
var segment = ""; | |
var end; | |
while (path) { | |
if (path.indexOf("..") === 0 || path.indexOf(".") === 0) { | |
path = path.replace(/^\.\.?\/?/g, ""); | |
} else if (path.indexOf("/..") === 0) { | |
path = path.replace(/^\/\..\/?/g, "/"); | |
end = result.lastIndexOf("/"); | |
if (end === -1) { | |
result = ""; | |
} else { | |
result = result.substring(0, end); | |
} | |
} else if (path.indexOf("/.") === 0) { | |
path = path.replace(/^\/\.\/?/g, "/"); | |
} else { | |
segment = path; | |
end = path.indexOf("/", 1); | |
if (end !== -1) { | |
segment = path.substring(0, end); | |
} | |
result = result + segment; | |
path = path.replace(segment, ""); | |
} | |
} | |
return result; | |
} | |
function convertByteArrayToHexString(str) { | |
var arr = []; | |
if (window.atob === undefined) { | |
arr = decodeBase64(str); | |
} else { | |
var binaryStr = window.atob(str); | |
for (var i = 0; i < binaryStr.length; i++) { | |
arr.push(binaryStr.charCodeAt(i)); | |
} | |
} | |
var hexValue = ""; | |
var hexValues = "0123456789ABCDEF"; | |
for (var j = 0; j < arr.length; j++) { | |
var t = arr[j]; | |
hexValue += hexValues[t >> 4]; | |
hexValue += hexValues[t & 0x0F]; | |
} | |
return hexValue; | |
} | |
function decodeBase64(str) { | |
var binaryString = ""; | |
for (var i = 0; i < str.length; i++) { | |
var base65IndexValue = getBase64IndexValue(str[i]); | |
var binaryValue = ""; | |
if (base65IndexValue !== null) { | |
binaryValue = base65IndexValue.toString(2); | |
binaryString += addBase64Padding(binaryValue); | |
} | |
} | |
var byteArray = []; | |
var numberOfBytes = parseInt(binaryString.length / 8, 10); | |
for (i = 0; i < numberOfBytes; i++) { | |
var intValue = parseInt(binaryString.substring(i * 8, (i + 1) * 8), 2); | |
byteArray.push(intValue); | |
} | |
return byteArray; | |
} | |
function getBase64IndexValue(character) { | |
var asciiCode = character.charCodeAt(0); | |
var asciiOfA = 65; | |
var differenceBetweenZanda = 6; | |
if (asciiCode >= 65 && asciiCode <= 90) { // between "A" and "Z" inclusive | |
return asciiCode - asciiOfA; | |
} else if (asciiCode >= 97 && asciiCode <= 122) { // between 'a' and 'z' inclusive | |
return asciiCode - asciiOfA - differenceBetweenZanda; | |
} else if (asciiCode >= 48 && asciiCode <= 57) { // between '0' and '9' inclusive | |
return asciiCode + 4; | |
} else if (character == "+") { | |
return 62; | |
} else if (character == "/") { | |
return 63; | |
} else { | |
return null; | |
} | |
} | |
function addBase64Padding(binaryString) { | |
while (binaryString.length < 6) { | |
binaryString = "0" + binaryString; | |
} | |
return binaryString; | |
} | |
function getJsonValueArraryLength(data) { | |
if (data && data.value) { | |
return data.value.length; | |
} | |
return 0; | |
} | |
function sliceJsonValueArray(data, start, end) { | |
if (data === undefined || data.value === undefined) { | |
return data; | |
} | |
if (start < 0) { | |
start = 0; | |
} | |
var length = getJsonValueArraryLength(data); | |
if (length < end) { | |
end = length; | |
} | |
var newdata = {}; | |
for (var property in data) { | |
if (property == "value") { | |
newdata[property] = data[property].slice(start, end); | |
} else { | |
newdata[property] = data[property]; | |
} | |
} | |
return newdata; | |
} | |
function concatJsonValueArray(data, concatData) { | |
if (concatData === undefined || concatData.value === undefined) { | |
return data; | |
} | |
if (data === undefined || Object.keys(data).length === 0) { | |
return concatData; | |
} | |
if (data.value === undefined) { | |
data.value = concatData.value; | |
return data; | |
} | |
data.value = data.value.concat(concatData.value); | |
return data; | |
} | |
function endsWith(input, search) { | |
return input.indexOf(search, input.length - search.length) !== -1; | |
} | |
function startsWith (input, search) { | |
return input.indexOf(search) === 0; | |
} | |
function getFormatKind(format, defaultFormatKind) { | |
var formatKind = defaultFormatKind; | |
if (!assigned(format)) { | |
return formatKind; | |
} | |
var normalizedFormat = format.toLowerCase(); | |
switch (normalizedFormat) { | |
case "none": | |
formatKind = 0; | |
break; | |
case "minimal": | |
formatKind = 1; | |
break; | |
case "full": | |
formatKind = 2; | |
break; | |
default: | |
break; | |
} | |
return formatKind; | |
} | |
exports.inBrowser = inBrowser; | |
exports.activeXObject = activeXObject; | |
exports.assigned = assigned; | |
exports.contains = contains; | |
exports.defined = defined; | |
exports.delay = delay; | |
exports.djsassert = djsassert; | |
exports.extend = extend; | |
exports.find = find; | |
exports.getURIInfo = getURIInfo; | |
exports.isArray = isArray; | |
exports.isDate = isDate; | |
exports.isObject = isObject; | |
exports.normalizeURI = normalizeURI; | |
exports.normalizeURICase = normalizeURICase; | |
exports.parseInt10 = parseInt10; | |
exports.renameProperty = renameProperty; | |
exports.throwErrorCallback = throwErrorCallback; | |
exports.trimString = trimString; | |
exports.undefinedDefault = undefinedDefault; | |
exports.decodeBase64 = decodeBase64; | |
exports.convertByteArrayToHexString = convertByteArrayToHexString; | |
exports.getJsonValueArraryLength = getJsonValueArraryLength; | |
exports.sliceJsonValueArray = sliceJsonValueArray; | |
exports.concatJsonValueArray = concatJsonValueArray; | |
exports.startsWith = startsWith; | |
exports.endsWith = endsWith; | |
exports.getFormatKind = getFormatKind;</code></pre> | |
</article> | |
</section> | |
</div> | |
<nav> | |
<h2><a href="index.html">Index</a></h2><h3>Modules</h3><ul><li><a href="module-cache.html">cache</a></li><li><a href="source.html">cache/source</a></li><li><a href="module-odata.html">odata</a></li><li><a href="batch.html">odata/batch</a></li><li><a href="handler.html">odata/handler</a></li><li><a href="json.html">odata/json</a></li><li><a href="metadata.html">odata/metadata</a></li><li><a href="net.html">odata/net</a></li><li><a href="utils.html">odata/utils</a></li><li><a href="deferred.html">odatajs/deferred</a></li><li><a href="utils_.html">odatajs/utils</a></li><li><a href="xml.html">odatajs/xml</a></li><li><a href="module-store.html">store</a></li><li><a href="dom.html">store/dom</a></li><li><a href="indexeddb.html">store/indexeddb</a></li><li><a href="memory.html">store/memory</a></li></ul><h3>Classes</h3><ul><li><a href="DataCache.html">DataCache</a></li><li><a href="DataCacheOperation.html">DataCacheOperation</a></li><li><a href="DjsDeferred.html">DjsDeferred</a></li><li><a href="dom-DomStore.html">DomStore</a></li><li><a href="indexeddb-IndexedDBStore.html">IndexedDBStore</a></li><li><a href="memory-MemoryStore.html">MemoryStore</a></li><li><a href="ODataCacheSource.html">ODataCacheSource</a></li></ul><h3><a href="global.html">Global</a></h3> | |
</nav> | |
<br clear="both"> | |
<footer> | |
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Apr 09 2015 08:31:26 GMT+0200 (MESZ) | |
</footer> | |
<script> prettyPrint(); </script> | |
<script src="scripts/linenumber.js"> </script> | |
</body> | |
</html> |