react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / src / vendor / immutable / ImmutableObject.js
81158 views/**1* Copyright 2013-2014, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under the BSD-style license found in the5* LICENSE file in the root directory of this source tree. An additional grant6* of patent rights can be found in the PATENTS file in the same directory.7*8* @providesModule ImmutableObject9*/1011"use strict";1213var Immutable = require('Immutable');1415var invariant = require('invariant');16var keyOf = require('keyOf');17var mergeHelpers = require('mergeHelpers');1819var checkMergeObjectArgs = mergeHelpers.checkMergeObjectArgs;20var isTerminal = mergeHelpers.isTerminal;2122var SECRET_KEY = keyOf({_DONT_EVER_TYPE_THIS_SECRET_KEY: null});2324/**25* Static methods creating and operating on instances of `Immutable`.26*/27function assertImmutable(immutable) {28invariant(29immutable instanceof Immutable,30'ImmutableObject: Attempted to set fields on an object that is not an ' +31'instance of Immutable.'32);33}3435/**36* Static methods for reasoning about instances of `ImmutableObject`. Execute37* the freeze commands in `__DEV__` mode to alert the programmer that something38* is attempting to mutate. Since freezing is very expensive, we avoid doing it39* at all in production.40*/41class ImmutableObject extends Immutable {42/**43* @arguments {array<object>} The arguments is an array of objects that, when44* merged together, will form the immutable objects.45*/46constructor() {47super(Immutable[SECRET_KEY]);48Immutable.mergeAllPropertiesInto(this, arguments);49if (__DEV__) {50Immutable.deepFreezeRootNode(this);51}52}5354/**55* DEPRECATED - prefer to instantiate with new ImmutableObject().56*57* @arguments {array<object>} The arguments is an array of objects that, when58* merged together, will form the immutable objects.59*/60static create() {61var obj = Object.create(ImmutableObject.prototype);62ImmutableObject.apply(obj, arguments);63return obj;64}6566/**67* Returns a new `Immutable` that is identical to the supplied `Immutable`68* but with the specified changes, `put`. Any keys that are in the69* intersection of `immutable` and `put` retain the ordering of `immutable.70* New keys are placed after keys that exist in `immutable`.71*72* @param {Immutable} immutable Starting object.73* @param {?object} put Fields to merge into the object.74* @return {Immutable} The result of merging in `put` fields.75*/76static set(immutable, put) {77assertImmutable(immutable);78invariant(79typeof put === 'object' && put !== undefined && !Array.isArray(put),80'Invalid ImmutableMap.set argument `put`'81);82return new ImmutableObject(immutable, put);83}8485/**86* Sugar for `ImmutableObject.set(ImmutableObject, {fieldName: putField})`.87* Look out for key crushing: Use `keyOf()` to guard against it.88*89* @param {Immutable} immutable Object on which to set properties.90* @param {string} fieldName Name of the field to set.91* @param {*} putField Value of the field to set.92* @return {Immutable} new Immutable as described in `set`.93*/94static setProperty(immutableObject, fieldName, putField) {95var put = {};96put[fieldName] = putField;97return ImmutableObject.set(immutableObject, put);98}99100/**101* Returns a new `Immutable` that is identical to the supplied object but102* with the supplied changes recursively applied.103*104* Experimental. Likely does not handle `Arrays` correctly.105*106* @param {Immutable} immutable Object on which to set fields.107* @param {object} put Fields to merge into the object.108* @return {Immutable} The result of merging in `put` fields.109*/110static setDeep(immutable, put) {111assertImmutable(immutable);112return _setDeep(immutable, put);113}114}115116function _setDeep(obj, put) {117checkMergeObjectArgs(obj, put);118var totalNewFields = {};119120// To maintain the order of the keys, copy the base object's entries first.121var keys = Object.keys(obj);122for (var ii = 0; ii < keys.length; ii++) {123var key = keys[ii];124if (!put.hasOwnProperty(key)) {125totalNewFields[key] = obj[key];126} else if (isTerminal(obj[key]) || isTerminal(put[key])) {127totalNewFields[key] = put[key];128} else {129totalNewFields[key] = _setDeep(obj[key], put[key]);130}131}132133// Apply any new keys that the base obj didn't have.134var newKeys = Object.keys(put);135for (ii = 0; ii < newKeys.length; ii++) {136var newKey = newKeys[ii];137if (obj.hasOwnProperty(newKey)) {138continue;139}140totalNewFields[newKey] = put[newKey];141}142143return (144obj instanceof Immutable ? new ImmutableObject(totalNewFields) :145put instanceof Immutable ? new ImmutableObject(totalNewFields) :146totalNewFields147);148}149150module.exports = ImmutableObject;151152153