var guid = 0; var ArrayProto = Array.prototype; var nativeForEach = ArrayProto.forEach; /** * Util functions * @namespace clay.core.util */ var util = { /** * Generate GUID * @return {number} * @memberOf clay.core.util */ genGUID: function () { return ++guid; }, /** * Relative path to absolute path * @param {string} path * @param {string} basePath * @return {string} * @memberOf clay.core.util */ relative2absolute: function (path, basePath) { if (!basePath || path.match(/^\//)) { return path; } var pathParts = path.split('/'); var basePathParts = basePath.split('/'); var item = pathParts[0]; while(item === '.' || item === '..') { if (item === '..') { basePathParts.pop(); } pathParts.shift(); item = pathParts[0]; } return basePathParts.join('/') + '/' + pathParts.join('/'); }, /** * Extend target with source * @param {Object} target * @param {Object} source * @return {Object} * @memberOf clay.core.util */ extend: function (target, source) { if (source) { for (var name in source) { if (source.hasOwnProperty(name)) { target[name] = source[name]; } } } return target; }, /** * Extend properties to target if not exist. * @param {Object} target * @param {Object} source * @return {Object} * @memberOf clay.core.util */ defaults: function (target, source) { if (source) { for (var propName in source) { if (target[propName] === undefined) { target[propName] = source[propName]; } } } return target; }, /** * Extend properties with a given property list to avoid for..in.. iteration. * @param {Object} target * @param {Object} source * @param {Array.} propList * @return {Object} * @memberOf clay.core.util */ extendWithPropList: function (target, source, propList) { if (source) { for (var i = 0; i < propList.length; i++) { var propName = propList[i]; target[propName] = source[propName]; } } return target; }, /** * Extend properties to target if not exist. With a given property list avoid for..in.. iteration. * @param {Object} target * @param {Object} source * @param {Array.} propList * @return {Object} * @memberOf clay.core.util */ defaultsWithPropList: function (target, source, propList) { if (source) { for (var i = 0; i < propList.length; i++) { var propName = propList[i]; if (target[propName] == null) { target[propName] = source[propName]; } } } return target; }, /** * @param {Object|Array} obj * @param {Function} iterator * @param {Object} [context] * @memberOf clay.core.util */ each: function (obj, iterator, context) { if (!(obj && iterator)) { return; } if (obj.forEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context); } else if (obj.length === + obj.length) { for (var i = 0, len = obj.length; i < len; i++) { iterator.call(context, obj[i], i, obj); } } else { for (var key in obj) { if (obj.hasOwnProperty(key)) { iterator.call(context, obj[key], key, obj); } } } }, /** * Is object * @param {} obj * @return {boolean} * @memberOf clay.core.util */ isObject: function (obj) { return obj === Object(obj); }, /** * Is array ? * @param {} obj * @return {boolean} * @memberOf clay.core.util */ isArray: function (obj) { return Array.isArray(obj); }, /** * Is array like, which have a length property * @param {} obj * @return {boolean} * @memberOf clay.core.util */ isArrayLike: function (obj) { if (!obj) { return false; } else { return obj.length === + obj.length; } }, /** * @param {} obj * @return {} * @memberOf clay.core.util */ clone: function (obj) { if (!util.isObject(obj)) { return obj; } else if (util.isArray(obj)) { return obj.slice(); } else if (util.isArrayLike(obj)) { // is typed array var ret = new obj.constructor(obj.length); for (var i = 0; i < obj.length; i++) { ret[i] = obj[i]; } return ret; } else { return util.extend({}, obj); } } }; export default util;