2023-10-03 11:14:36 +08:00
|
|
|
var isArray;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Strip leading and trailing whitespace from a string.
|
|
|
|
* @param {string} input
|
|
|
|
* @return {string} Stripped input.
|
|
|
|
*/
|
|
|
|
exports.strip = function (input) {
|
|
|
|
return input.replace(/^\s+|\s+$/g, '');
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test if a string starts with a given prefix.
|
|
|
|
* @param {string} str String to test against.
|
|
|
|
* @param {string} prefix Prefix to check for.
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
exports.startsWith = function (str, prefix) {
|
|
|
|
return str.indexOf(prefix) === 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test if a string ends with a given suffix.
|
|
|
|
* @param {string} str String to test against.
|
|
|
|
* @param {string} suffix Suffix to check for.
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
exports.endsWith = function (str, suffix) {
|
|
|
|
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Iterate over an array or object.
|
|
|
|
* @param {array|object} obj Enumerable object.
|
|
|
|
* @param {Function} fn Callback function executed for each item.
|
|
|
|
* @return {array|object} The original input object.
|
|
|
|
*/
|
|
|
|
exports.each = function (obj, fn) {
|
|
|
|
var i, l;
|
|
|
|
|
|
|
|
if (isArray(obj)) {
|
|
|
|
i = 0;
|
|
|
|
l = obj.length;
|
|
|
|
for (i; i < l; i += 1) {
|
|
|
|
if (fn(obj[i], i, obj) === false) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i in obj) {
|
|
|
|
if (obj.hasOwnProperty(i)) {
|
|
|
|
if (fn(obj[i], i, obj) === false) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test if an object is an Array.
|
|
|
|
* @param {object} obj
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
exports.isArray = isArray = (Array.hasOwnProperty('isArray')) ? Array.isArray : function (obj) {
|
|
|
|
return (obj) ? (typeof obj === 'object' && Object.prototype.toString.call(obj).indexOf() !== -1) : false;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test if an item in an enumerable matches your conditions.
|
|
|
|
* @param {array|object} obj Enumerable object.
|
|
|
|
* @param {Function} fn Executed for each item. Return true if your condition is met.
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
exports.some = function (obj, fn) {
|
|
|
|
var i = 0,
|
|
|
|
result,
|
|
|
|
l;
|
|
|
|
if (isArray(obj)) {
|
|
|
|
l = obj.length;
|
|
|
|
|
|
|
|
for (i; i < l; i += 1) {
|
|
|
|
result = fn(obj[i], i, obj);
|
|
|
|
if (result) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
exports.each(obj, function (value, index, collection) {
|
|
|
|
result = fn(value, index, obj);
|
|
|
|
return !(result);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return !!result;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a new enumerable, mapped by a given iteration function.
|
|
|
|
* @param {object} obj Enumerable object.
|
|
|
|
* @param {Function} fn Executed for each item. Return the item to replace the original item with.
|
|
|
|
* @return {object} New mapped object.
|
|
|
|
*/
|
|
|
|
exports.map = function (obj, fn) {
|
|
|
|
var i = 0,
|
|
|
|
result = [],
|
|
|
|
l;
|
|
|
|
|
|
|
|
if (isArray(obj)) {
|
|
|
|
l = obj.length;
|
|
|
|
for (i; i < l; i += 1) {
|
|
|
|
result[i] = fn(obj[i], i);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i in obj) {
|
|
|
|
if (obj.hasOwnProperty(i)) {
|
|
|
|
result[i] = fn(obj[i], i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy all of the properties in the source objects over to the destination object, and return the destination object. It's in-order, so the last source will override properties of the same name in previous arguments.
|
|
|
|
* @param {...object} arguments
|
|
|
|
* @return {object}
|
|
|
|
*/
|
|
|
|
exports.extend = function () {
|
|
|
|
var args = arguments,
|
|
|
|
target = args[0],
|
|
|
|
objs = (args.length > 1) ? Array.prototype.slice.call(args, 1) : [],
|
|
|
|
i = 0,
|
|
|
|
l = objs.length,
|
|
|
|
key,
|
|
|
|
obj;
|
|
|
|
|
|
|
|
for (i; i < l; i += 1) {
|
|
|
|
obj = objs[i] || {};
|
|
|
|
for (key in obj) {
|
|
|
|
if (obj.hasOwnProperty(key)) {
|
|
|
|
target[key] = obj[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return target;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get all of the keys on an object.
|
|
|
|
* @param {object} obj
|
|
|
|
* @return {array}
|
|
|
|
*/
|
|
|
|
exports.keys = function (obj) {
|
|
|
|
if (Object.keys) {
|
|
|
|
return Object.keys(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
return exports.map(obj, function (v, k) {
|
|
|
|
return k;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Throw an error with possible line number and source file.
|
|
|
|
* @param {string} message Error message
|
|
|
|
* @param {number} [line] Line number in template.
|
|
|
|
* @param {string} [file] Template file the error occured in.
|
|
|
|
* @throws {Error} No seriously, the point is to throw an error.
|
|
|
|
*/
|
|
|
|
exports.throwError = function (message, line, file) {
|
|
|
|
if (line) {
|
|
|
|
message += ' on line ' + line;
|
|
|
|
}
|
|
|
|
if (file) {
|
|
|
|
message += ' in file ' + file;
|
|
|
|
}
|
|
|
|
throw new Error(message + '.');
|
|
|
|
};
|