4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore/**
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * The YUI module contains the components required for building the YUI
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * seed file. This includes the script loading mechanism, a simple queue,
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * and the core utilities for the library.
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore * @module yui
2c5ce90c334a2d0f18474e85c93b424b6ec9daaaAdam Moore * @submodule yui-base
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * Adds utilities to the YUI instance for working with objects.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @class Object
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
3e4a3c30997cfa913fabd7b346e3a71388441bedRyan Grovevar Lang = Y.Lang,
3e4a3c30997cfa913fabd7b346e3a71388441bedRyan Grove hasOwn = Object.prototype.hasOwnProperty,
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove
3e4a3c30997cfa913fabd7b346e3a71388441bedRyan Grove UNDEFINED, // <-- Note the comma. We're still declaring vars.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * Returns a new object that uses _obj_ as its prototype. This method wraps the
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * native ES5 `Object.create()` method if available, but doesn't currently
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * pass through `Object.create()`'s second argument (properties) in order to
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * ensure compatibility with older browsers.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method ()
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @param {Object} obj Prototype object.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @return {Object} New object using _obj_ as its prototype.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
3e4a3c30997cfa913fabd7b346e3a71388441bedRyan GroveO = Y.Object = Lang._isNative(Object.create) ? function (obj) {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove // We currently wrap the native Object.create instead of simply aliasing it
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove // to ensure consistency with our fallback shim, which currently doesn't
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove // support Object.create()'s second argument (properties). Once we have a
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove // safe fallback for the properties arg, we can stop wrapping
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove // Object.create().
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove return Object.create(obj);
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove} : (function () {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove // Reusable constructor function for the Object.create() shim.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove function F() {}
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove // The actual shim.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove return function (obj) {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove F.prototype = obj;
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove return new F();
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove };
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove}()),
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
67e8ed2937abc262dbe7537695d632143294269fRyan Grove/**
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * Property names that IE doesn't enumerate in for..in loops, even when they
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * should be enumerable. When `_hasEnumBug` is `true`, it's necessary to
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * manually enumerate these properties.
67e8ed2937abc262dbe7537695d632143294269fRyan Grove *
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @property _forceEnum
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @type String[]
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @protected
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @static
67e8ed2937abc262dbe7537695d632143294269fRyan Grove */
67e8ed2937abc262dbe7537695d632143294269fRyan GroveforceEnum = O._forceEnum = [
67e8ed2937abc262dbe7537695d632143294269fRyan Grove 'hasOwnProperty',
67e8ed2937abc262dbe7537695d632143294269fRyan Grove 'isPrototypeOf',
67e8ed2937abc262dbe7537695d632143294269fRyan Grove 'propertyIsEnumerable',
67e8ed2937abc262dbe7537695d632143294269fRyan Grove 'toString',
67e8ed2937abc262dbe7537695d632143294269fRyan Grove 'toLocaleString',
67e8ed2937abc262dbe7537695d632143294269fRyan Grove 'valueOf'
67e8ed2937abc262dbe7537695d632143294269fRyan Grove],
67e8ed2937abc262dbe7537695d632143294269fRyan Grove
67e8ed2937abc262dbe7537695d632143294269fRyan Grove/**
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * `true` if this browser has the JScript enumeration bug that prevents
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * enumeration of the properties named in the `_forceEnum` array, `false`
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * otherwise.
67e8ed2937abc262dbe7537695d632143294269fRyan Grove *
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * See:
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * - <https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug>
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * - <http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation>
67e8ed2937abc262dbe7537695d632143294269fRyan Grove *
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @property _hasEnumBug
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * @type Boolean
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @protected
67e8ed2937abc262dbe7537695d632143294269fRyan Grove * @static
67e8ed2937abc262dbe7537695d632143294269fRyan Grove */
67e8ed2937abc262dbe7537695d632143294269fRyan GrovehasEnumBug = O._hasEnumBug = !{valueOf: 0}.propertyIsEnumerable('valueOf'),
67e8ed2937abc262dbe7537695d632143294269fRyan Grove
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove/**
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * `true` if this browser incorrectly considers the `prototype` property of
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * functions to be enumerable. Currently known to affect Opera 11.50.
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove *
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * @property _hasProtoEnumBug
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * @type Boolean
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * @protected
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove * @static
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove */
6ed148777f04d35c42c9370c8108484f14be78a2Ryan GrovehasProtoEnumBug = O._hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'),
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove/**
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * Returns `true` if _key_ exists on _obj_, `false` if _key_ doesn't exist or
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * exists only on _obj_'s prototype. This is essentially a safer version of
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * `obj.hasOwnProperty()`.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove *
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @method owns
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @param {Object} obj Object to test.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @param {String} key Property name to look for.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @static
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove */
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Groveowns = O.owns = function (obj, key) {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove return !!obj && hasOwn.call(obj, key);
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove}; // <-- End of var declarations.
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove/**
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * Alias for `owns()`.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove *
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @method hasKey
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @param {Object} obj Object to test.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @param {String} key Property name to look for.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @return {Boolean} `true` if _key_ exists on _obj_, `false` otherwise.
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove * @static
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove */
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan GroveO.hasKey = owns;
9fb523cf517ad4d6a53ae9f461d672cba63835d2Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore/**
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * Returns an array containing the object's enumerable keys. Does not include
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * prototype keys or non-enumerable keys.
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove *
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * Note that keys are returned in enumeration order (that is, in the same order
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * that they would be enumerated by a `for-in` loop), which may not be the same
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * as the order in which they were defined.
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove *
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * This method is an alias for the native ES5 `Object.keys()` method if
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * available.
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove *
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * @example
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove *
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * Y.Object.keys({a: 'foo', b: 'bar', c: 'baz'});
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * // => ['a', 'b', 'c']
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method keys
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * @param {Object} obj An object.
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove * @return {String[]} Array of keys.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @static
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
3e4a3c30997cfa913fabd7b346e3a71388441bedRyan GroveO.keys = Lang._isNative(Object.keys) ? Object.keys : function (obj) {
3e4a3c30997cfa913fabd7b346e3a71388441bedRyan Grove if (!Lang.isObject(obj)) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove throw new TypeError('Object.keys called on a non-object');
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove
67e8ed2937abc262dbe7537695d632143294269fRyan Grove var keys = [],
67e8ed2937abc262dbe7537695d632143294269fRyan Grove i, key, len;
67e8ed2937abc262dbe7537695d632143294269fRyan Grove
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove if (hasProtoEnumBug && typeof obj === 'function') {
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove for (key in obj) {
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove if (owns(obj, key) && key !== 'prototype') {
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove keys.push(key);
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove }
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove }
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove } else {
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove for (key in obj) {
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove if (owns(obj, key)) {
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove keys.push(key);
6ed148777f04d35c42c9370c8108484f14be78a2Ryan Grove }
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore
67e8ed2937abc262dbe7537695d632143294269fRyan Grove if (hasEnumBug) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove for (i = 0, len = forceEnum.length; i < len; ++i) {
67e8ed2937abc262dbe7537695d632143294269fRyan Grove key = forceEnum[i];
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove if (owns(obj, key)) {
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove keys.push(key);
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove }
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove }
67e8ed2937abc262dbe7537695d632143294269fRyan Grove }
c97ced1ebe127b04e46886f1b43dc0b00672e34bRyan Grove
67e8ed2937abc262dbe7537695d632143294269fRyan Grove return keys;
67e8ed2937abc262dbe7537695d632143294269fRyan Grove};
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore/**
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * Returns an array containing the values of the object's enumerable keys.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove *
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * Note that values are returned in enumeration order (that is, in the same
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * order that they would be enumerated by a `for-in` loop), which may not be the
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * same as the order in which they were defined.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove *
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @example
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove *
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * Y.Object.values({a: 'foo', b: 'bar', c: 'baz'});
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * // => ['foo', 'bar', 'baz']
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method values
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @param {Object} obj An object.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @return {Array} Array of values.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @static
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan GroveO.values = function (obj) {
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove var keys = O.keys(obj),
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove i = 0,
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove len = keys.length,
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove values = [];
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove for (; i < len; ++i) {
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove values.push(obj[keys[i]]);
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove }
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove return values;
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore};
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore/**
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * Returns the number of enumerable keys owned by an object.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method size
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @param {Object} obj An object.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @return {Number} The object's size.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @static
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan GroveO.size = function (obj) {
20ed23d33369bdd43b18a992b6fda8cbff77cc2cRyan Grove try {
20ed23d33369bdd43b18a992b6fda8cbff77cc2cRyan Grove return O.keys(obj).length;
20ed23d33369bdd43b18a992b6fda8cbff77cc2cRyan Grove } catch (ex) {
20ed23d33369bdd43b18a992b6fda8cbff77cc2cRyan Grove return 0; // Legacy behavior for non-objects.
20ed23d33369bdd43b18a992b6fda8cbff77cc2cRyan Grove }
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore};
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore/**
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * Returns `true` if the object owns an enumerable property with the specified
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * value.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method hasValue
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @param {Object} obj An object.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @param {any} value The value to search for.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @return {Boolean} `true` if _obj_ contains _value_, `false` otherwise.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @static
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan GroveO.hasValue = function (obj, value) {
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove return Y.Array.indexOf(O.values(obj), value) > -1;
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore};
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * Executes a function on each enumerable property in _obj_. The function
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * receives the value, the key, and the object itself as parameters (in that
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * order).
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove *
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * By default, only properties owned by _obj_ are enumerated. To include
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * prototype properties, set the _proto_ parameter to `true`.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method each
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Object} obj Object to enumerate.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Function} fn Function to execute on each enumerable property.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {mixed} fn.value Value of the current property.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {String} fn.key Key of the current property.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Object} fn.obj Object being enumerated.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Object} [thisObj] `this` object to use when calling _fn_.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Boolean} [proto=false] Include prototype properties.
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * @return {YUI} the YUI instance.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @chainable
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan GroveO.each = function (obj, fn, thisObj, proto) {
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove var key;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove for (key in obj) {
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove if (proto || owns(obj, key)) {
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove fn.call(thisObj || Y, obj[key], key, obj);
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return Y;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore};
c4e6d94ea429e473a6732b6eb5e0fc980e822881Adam Moore
7cd8fe832d4f91bed468c7498ff957c446f90aaaAdam Moore/**
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * Executes a function on each enumerable property in _obj_, but halts if the
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * function returns a truthy value. The function receives the value, the key,
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * and the object itself as paramters (in that order).
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove *
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * By default, only properties owned by _obj_ are enumerated. To include
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * prototype properties, set the _proto_ parameter to `true`.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove *
23209f57fce338501bc1dc828a991d103732b92fAdam Moore * @method some
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Object} obj Object to enumerate.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Function} fn Function to execute on each enumerable property.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {mixed} fn.value Value of the current property.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {String} fn.key Key of the current property.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Object} fn.obj Object being enumerated.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Object} [thisObj] `this` object to use when calling _fn_.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @param {Boolean} [proto=false] Include prototype properties.
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * @return {Boolean} `true` if any execution of _fn_ returns a truthy value,
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove * `false` otherwise.
23209f57fce338501bc1dc828a991d103732b92fAdam Moore * @static
23209f57fce338501bc1dc828a991d103732b92fAdam Moore */
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan GroveO.some = function (obj, fn, thisObj, proto) {
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove var key;
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove for (key in obj) {
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove if (proto || owns(obj, key)) {
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove if (fn.call(thisObj || Y, obj[key], key, obj)) {
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore return true;
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore }
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore }
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore }
582df4bc8549d0008b29f98cfe582ad0dc217c9eRyan Grove
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore return false;
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore};
23209f57fce338501bc1dc828a991d103732b92fAdam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore/**
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * Retrieves the sub value at the provided path,
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * from the value object provided.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore *
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @method getValue
02b581ebfa9969c32cac8cd44ebe35e0e47f00ceAdam Moore * @static
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * @param o The object from which to extract the property value.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @param path {Array} A path array, specifying the object traversal path
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * from which to obtain the sub value.
0dca577a07715960da42d47787eecc25b285182fAdam Moore * @return {Any} The value stored in the path, undefined if not found,
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * undefined if the source is not an object. Returns the source object
0dca577a07715960da42d47787eecc25b285182fAdam Moore * if an empty path is provided.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore */
b39897a381c2203466da5568bfd2862a54a81311Adam MooreO.getValue = function(o, path) {
3e4a3c30997cfa913fabd7b346e3a71388441bedRyan Grove if (!Lang.isObject(o)) {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove return UNDEFINED;
0dca577a07715960da42d47787eecc25b285182fAdam Moore }
0dca577a07715960da42d47787eecc25b285182fAdam Moore
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore var i,
b39897a381c2203466da5568bfd2862a54a81311Adam Moore p = Y.Array(path),
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore l = p.length;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove for (i = 0; o !== UNDEFINED && i < l; i++) {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore o = o[p[i]];
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore return o;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore};
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore/**
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * Sets the sub-attribute value at the provided path on the
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * value object. Returns the modified value object, or
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * undefined if the path is invalid.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore *
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @method setValue
02b581ebfa9969c32cac8cd44ebe35e0e47f00ceAdam Moore * @static
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @param o The object on which to set the sub value.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @param path {Array} A path array, specifying the object traversal path
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * at which to set the sub value.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @param val {Any} The new value for the sub-attribute.
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * @return {Object} The modified object, with the new sub value set, or
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * undefined, if the path was invalid.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore */
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam MooreO.setValue = function(o, path, val) {
b39897a381c2203466da5568bfd2862a54a81311Adam Moore var i,
b39897a381c2203466da5568bfd2862a54a81311Adam Moore p = Y.Array(path),
b39897a381c2203466da5568bfd2862a54a81311Adam Moore leafIdx = p.length - 1,
b39897a381c2203466da5568bfd2862a54a81311Adam Moore ref = o;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore if (leafIdx >= 0) {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove for (i = 0; ref !== UNDEFINED && i < leafIdx; i++) {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore ref = ref[p[i]];
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove if (ref !== UNDEFINED) {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore ref[p[i]] = val;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore } else {
58ce26ddee9c5cc583f031eeb1ed36aea797bdcaRyan Grove return UNDEFINED;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore return o;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore};
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore/**
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * Returns `true` if the object has no enumerable properties of its own.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove *
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore * @method isEmpty
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @param {Object} obj An object.
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan Grove * @return {Boolean} `true` if the object is empty.
02b581ebfa9969c32cac8cd44ebe35e0e47f00ceAdam Moore * @static
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore * @since 3.2.0
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore */
3ecd40c854dca8089986ee76cac93c15f4f5f5f3Ryan GroveO.isEmpty = function (obj) {
efb046dfa7ee18351c62b6efc9934c09058fcc74Ryan Grove return !O.keys(Object(obj)).length;
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore};