UNPKG

express-yui

Version:

Express extension for YUI Applications

165 lines (135 loc) 4.17 kB
/* * Copyright (c) 2013, Yahoo! Inc. All rights reserved. * Copyrights licensed under the New BSD License. * See the accompanying LICENSE file for terms. */ /*jslint node:true, nomen: true */ 'use strict'; /** Utility functions used across `express-yui` components. @module express-yui @submodule utils **/ /** Extends object with properties from other objects. var a = { foo: 'bar' } , b = { bar: 'baz' } , c = { baz: 'xyz' }; utils.extends(a, b, c); // a => { foo: 'bar', bar: 'baz', baz: 'xyz' } @method extend @param {Object} obj the receiver object to be extended @param {Object*} supplier objects @return {Object} The extended object **/ exports.extend = function (obj) { Array.prototype.slice.call(arguments, 1).forEach(function (source) { var key; if (!source) { return; } for (key in source) { if (source.hasOwnProperty(key)) { obj[key] = source[key]; } } }); return obj; }; /** Walks `obj` recursively looking for functions and replacing those functions with a token that will be added to the `hash` object. This is useful when you try to stringify an object that helds references to functions. This method will modify `obj` and `hash` parameters. @method tokenizeFunctions @param {Object} obj the object to be tokenized @param {Object} hash the object to store tokenized functions @param {string} ns namespace for the tokens **/ exports.tokenizeFunctions = function (obj, hash, ns) { var key, token; if (!obj) { return; } for (key in obj) { if (obj.hasOwnProperty(key)) { if (typeof obj[key] === 'function') { token = '@' + ns + '.' + key + '@'; hash[token] = obj[key]; obj[key] = token; } else if (typeof obj[key] === 'object') { exports.tokenizeFunctions(obj[key], hash, ns + '.' + key); } } } }; /** Serializes an object, which is similar to `JSON.stringify` but with the peculiarity that function refences will be allowed, with means you can fully bake a javascript structure to be reconstructed in the client runtime. In this method, the original object will not be modified. @method serialize @param {Object} obj the object to be serialized @return {string} the serialized object **/ exports.serialize = function (obj) { var token, hash = {}, str; obj = exports.clone(obj); // tokenizing functions within the obj structure exports.tokenizeFunctions(obj, hash, '*'); str = JSON.stringify(obj); for (token in hash) { if (hash.hasOwnProperty(token)) { str = str.replace('"' + token + '"', hash[token].toString()); } } return str; }; /** Deep clone of an object. @method clone @param {Object} oldObj the origal object to be cloned @return {Object} The cloned object **/ exports.clone = function clone(oldObj) { var newObj, key, len; if (!oldObj || typeof oldObj !== 'object') { return oldObj; } if (Array.isArray(oldObj)) { newObj = []; len = oldObj.length; for (key = 0; key < len; key += 1) { newObj[key] = clone(oldObj[key]); } return newObj; } newObj = {}; for (key in oldObj) { if (oldObj.hasOwnProperty(key)) { newObj[key] = clone(oldObj[key]); } } return newObj; }; /** Test if `fn` is a function. This is useful to distinguish functions from objects. @method isFunction @param {Object|Function} fn the function to be tested @return {Boolean} `true` if `fn` is a function, `false` otherwise **/ exports.isFunction = function (fn) { return !!(fn && (Object.prototype.toString.call(fn) === '[object Function]') && fn.toString); }; /** Test if `re` is a regular expression. @method isRegExp @param {Object|Function} re the regular express to be tested @return {Boolean} `true` if `re` is a regular express, `false` otherwise **/ exports.isRegExp = function (re) { return !!(re && (Object.prototype.toString.call(re) === '[object RegExp]')); };