Example #1
0
    constructor() {
      if (!wasApplied) {
        Class.proto(); // prepare prototype...
      }

      if (arguments.length > 0) {
        initProperties = [arguments[0]];
      }

      this.__defineNonEnumerable(GUID_KEY_PROPERTY);
      let m = meta(this);
      let proto = m.proto;
      m.proto = this;

      if (initFactory) {
        m.factory = initFactory;
        initFactory = null;
      }
      if (initProperties) {
        // capture locally so we can clear the closed over variable
        let props = initProperties;
        initProperties = null;

        let concatenatedProperties = this.concatenatedProperties;
        let mergedProperties = this.mergedProperties;

        for (let i = 0; i < props.length; i++) {
          let properties = props[i];

          assert(
            'Ember.Object.create only accepts objects.',
            typeof properties === 'object' || properties === undefined
          );

          assert(
            'Ember.Object.create no longer supports mixing in other ' +
            'definitions, use .extend & .create separately instead.',
            !(properties instanceof Mixin)
          );

          if (!properties) { continue; }

          let keyNames = Object.keys(properties);

          for (let j = 0; j < keyNames.length; j++) {
            let keyName = keyNames[j];
            let value = properties[keyName];

            if (detectBinding(keyName)) {
              m.writeBindings(keyName, value);
            }

            let possibleDesc = this[keyName];
            let desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined;

            assert(
              'Ember.Object.create no longer supports defining computed ' +
              'properties. Define computed properties using extend() or reopen() ' +
              'before calling create().',
              !(value instanceof ComputedProperty)
            );
            assert(
              'Ember.Object.create no longer supports defining methods that call _super.',
              !(typeof value === 'function' && value.toString().indexOf('._super') !== -1)
            );
            assert(
              '`actions` must be provided at extend time, not at create time, ' +
              'when Ember.ActionHandler is used (i.e. views, controllers & routes).',
              !((keyName === 'actions') && ActionHandler.detect(this))
            );

            if (concatenatedProperties &&
                concatenatedProperties.length > 0 &&
                concatenatedProperties.indexOf(keyName) > -1) {
              let baseValue = this[keyName];

              if (baseValue) {
                if ('function' === typeof baseValue.concat) {
                  value = baseValue.concat(value);
                } else {
                  value = makeArray(baseValue).concat(value);
                }
              } else {
                value = makeArray(value);
              }
            }

            if (mergedProperties &&
                mergedProperties.length > 0 &&
                mergedProperties.indexOf(keyName) > -1) {
              let originalValue = this[keyName];

              value = assign({}, originalValue, value);
            }

            if (desc) {
              desc.set(this, keyName, value);
            } else {
              if (typeof this.setUnknownProperty === 'function' && !(keyName in this)) {
                this.setUnknownProperty(keyName, value);
              } else {
                if (MANDATORY_SETTER) {
                  defineProperty(this, keyName, null, value); // setup mandatory setter
                } else {
                  this[keyName] = value;
                }
              }
            }
          }
        }
      }

      finishPartial(this, m);

      this.init(...arguments);

      this[POST_INIT]();

      m.proto = proto;
      finishChains(m);
      sendEvent(this, 'init', undefined, undefined, undefined, m);
    }
Example #2
0
      constructor(properties) {
        if (!wasApplied) {
          Class.proto(); // prepare prototype...
        }

        let self = this;

        if (initFactory !== void 0) {
          FACTORY_FOR.set(this, initFactory);
          initFactory = void 0;
        }

        let beforeInitCalled; // only used in debug builds to enable the proxy trap

        // using DEBUG here to avoid the extraneous variable when not needed
        if (DEBUG) {
          beforeInitCalled = true;
        }

        if (DEBUG && HAS_NATIVE_PROXY && typeof self.unknownProperty === 'function') {
          let messageFor = (obj, property) => {
            return (
              `You attempted to access the \`${String(property)}\` property (of ${obj}).\n` +
              `Since Ember 3.1, this is usually fine as you no longer need to use \`.get()\`\n` +
              `to access computed properties. However, in this case, the object in question\n` +
              `is a special kind of Ember object (a proxy). Therefore, it is still necessary\n` +
              `to use \`.get('${String(property)}')\` in this case.\n\n` +
              `If you encountered this error because of third-party code that you don't control,\n` +
              `there is more information at https://github.com/emberjs/ember.js/issues/16148, and\n` +
              `you can help us improve this error message by telling us more about what happened in\n` +
              `this situation.`
            );
          };

          /* globals Proxy Reflect */
          self = new Proxy(this, {
            get(target, property, receiver) {
              if (property === PROXY_CONTENT) {
                return target;
              } else if (
                beforeInitCalled ||
                typeof property === 'symbol' ||
                isInternalSymbol(property) ||
                property === 'toJSON' ||
                property === 'toString' ||
                property === 'toStringExtension' ||
                property === 'didDefineProperty' ||
                property === 'willWatchProperty' ||
                property === 'didUnwatchProperty' ||
                property === 'didAddListener' ||
                property === 'didRemoveListener' ||
                property === 'isDescriptor' ||
                property === '_onLookup' ||
                property in target
              ) {
                return Reflect.get(target, property, receiver);
              }

              let value = target.unknownProperty.call(receiver, property);

              if (typeof value !== 'function') {
                assert(messageFor(receiver, property), value === undefined || value === null);
              }
            },
          });

          FACTORY_FOR.set(self, FACTORY_FOR.get(this));
        }

        let m = meta(self);
        let proto = m.proto;
        m.proto = self;

        if (properties !== undefined) {
          assert(
            'EmberObject.create only accepts objects.',
            typeof properties === 'object' && properties !== null
          );

          assert(
            'EmberObject.create no longer supports mixing in other ' +
              'definitions, use .extend & .create separately instead.',
            !(properties instanceof Mixin)
          );

          let concatenatedProperties = self.concatenatedProperties;
          let mergedProperties = self.mergedProperties;
          let hasConcatenatedProps =
            concatenatedProperties !== undefined && concatenatedProperties.length > 0;
          let hasMergedProps = mergedProperties !== undefined && mergedProperties.length > 0;

          let keyNames = Object.keys(properties);

          for (let i = 0; i < keyNames.length; i++) {
            let keyName = keyNames[i];
            let value = properties[keyName];

            if (BINDING_SUPPORT && ENV._ENABLE_BINDING_SUPPORT && Mixin.detectBinding(keyName)) {
              m.writeBindings(keyName, value);
            }

            assert(
              'EmberObject.create no longer supports defining computed ' +
                'properties. Define computed properties using extend() or reopen() ' +
                'before calling create().',
              !(value instanceof ComputedProperty)
            );
            assert(
              'EmberObject.create no longer supports defining methods that call _super.',
              !(typeof value === 'function' && value.toString().indexOf('._super') !== -1)
            );
            assert(
              '`actions` must be provided at extend time, not at create time, ' +
                'when Ember.ActionHandler is used (i.e. views, controllers & routes).',
              !(keyName === 'actions' && ActionHandler.detect(this))
            );

            let possibleDesc = descriptorFor(self, keyName, m);
            let isDescriptor = possibleDesc !== undefined;

            if (!isDescriptor) {
              let baseValue = self[keyName];

              if (hasConcatenatedProps && concatenatedProperties.indexOf(keyName) > -1) {
                if (baseValue) {
                  value = makeArray(baseValue).concat(value);
                } else {
                  value = makeArray(value);
                }
              }

              if (hasMergedProps && mergedProperties.indexOf(keyName) > -1) {
                value = assign({}, baseValue, value);
              }
            }

            if (isDescriptor) {
              possibleDesc.set(self, keyName, value);
            } else if (typeof self.setUnknownProperty === 'function' && !(keyName in self)) {
              self.setUnknownProperty(keyName, value);
            } else {
              if (DEBUG) {
                defineProperty(self, keyName, null, value); // setup mandatory setter
              } else {
                self[keyName] = value;
              }
            }
          }
        }

        if (BINDING_SUPPORT && ENV._ENABLE_BINDING_SUPPORT) {
          Mixin.finishPartial(self, m);
        }

        // using DEBUG here to avoid the extraneous variable when not needed
        if (DEBUG) {
          beforeInitCalled = false;
        }
        self.init(...arguments);

        m.proto = proto;
        finishChains(m);
        sendEvent(self, 'init', undefined, undefined, undefined, m);

        // only return when in debug builds and `self` is the proxy created above
        if (DEBUG && self !== this) {
          return self;
        }
      }