UNPKG

ember-source

Version:

A JavaScript framework for creating ambitious web applications

122 lines (109 loc) 3.54 kB
import { s as setProxy } from './is_proxy-Bzg0d4m4.js'; import { isEmberArray } from '../@ember/array/-internals.js'; import { t as track, x as isTracking, a as consumeTag } from './cache-BIlOoPA7.js'; import { t as tagFor } from './meta-B9mldqPL.js'; import { C as Cache } from './cache-qDyqAcpg.js'; const firstDotIndexCache = new Cache(1000, key => key.indexOf('.')); function isPath(path) { return typeof path === 'string' && firstDotIndexCache.get(path) !== -1; } /** @module @ember/object */ const PROXY_CONTENT = Symbol('PROXY_CONTENT'); function hasUnknownProperty(val) { return typeof val === 'object' && val !== null && typeof val.unknownProperty === 'function'; } // .......................................................... // GET AND SET // // If we are on a platform that supports accessors we can use those. // Otherwise simulate accessors by looking up the property directly on the // object. /** Gets the value of a property on an object. If the property is computed, the function will be invoked. If the property is not defined but the object implements the `unknownProperty` method then that will be invoked. ```javascript import { get } from '@ember/object'; get(obj, "name"); ``` You only need to use this method to retrieve properties if the property might not be defined on the object and you want to respect the `unknownProperty` handler. Otherwise you can access the property directly. Note that if the object itself is `undefined`, this method will throw an error. @method get @for @ember/object @static @param {Object} obj The object to retrieve from. @param {String} keyName The property key to retrieve @return {Object} the property value or `null`. @public */ function get(obj, keyName) { return isPath(keyName) ? _getPath(obj, keyName) : _getProp(obj, keyName); } function _getProp(obj, keyName) { if (obj == null) { return; } let value; if (typeof obj === 'object' || typeof obj === 'function') { { value = obj[keyName]; } if (value === undefined && typeof obj === 'object' && !(keyName in obj) && hasUnknownProperty(obj)) { value = obj.unknownProperty(keyName); } if (isTracking()) { consumeTag(tagFor(obj, keyName)); if (Array.isArray(value) || isEmberArray(value)) { // Add the tag of the returned value if it is an array, since arrays // should always cause updates if they are consumed and then changed consumeTag(tagFor(value, '[]')); } } } else { // SAFETY: It should be ok to access properties on any non-nullish value value = obj[keyName]; } return value; } function _getPath(obj, path, forSet) { let parts = typeof path === 'string' ? path.split('.') : path; for (let part of parts) { if (obj === undefined || obj === null || obj.isDestroyed) { return undefined; } if (forSet && (part === '__proto__' || part === 'constructor')) { return; } obj = _getProp(obj, part); } return obj; } // Warm it up _getProp('foo', 'a'); _getProp('foo', 1); _getProp({}, 'a'); _getProp({}, 1); _getProp({ unknownProperty() {} }, 'a'); _getProp({ unknownProperty() {} }, 1); get({}, 'foo'); get({}, 'foo.bar'); let fakeProxy = {}; setProxy(fakeProxy); track(() => _getProp({}, 'a')); track(() => _getProp({}, 1)); track(() => _getProp({ a: [] }, 'a')); track(() => _getProp({ a: fakeProxy }, 'a')); export { PROXY_CONTENT as P, _getPath as _, _getProp as a, get as g, hasUnknownProperty as h, isPath as i };