var ReactComponent = React.Component;
var _assign = Object.assign;
var _invariant = function _invariant(condition, format, a, b, c, d, e, f) {
if (!condition) {
var error;
if (format === undefined) {
error = new Error(
"Minified exception occurred; use the non-minified dev environment " +
"for the full error message and additional helpful warnings."
);
} else {
var args = [a, b, c, d, e, f];
var argIndex = 0;
error = new Error(
format.replace(/%s/g, function() {
return args[argIndex++];
})
);
error.name = "Invariant Violation";
}
error.framesToPop = 1; // we don't care about invariant's own frame
throw error;
}
};
var MIXINS_KEY = "mixins";
/**
* Policies that describe methods in `ReactClassInterface`.
*/
var injectedMixins = [];
var ReactClassInterface = {
mixins: "DEFINE_MANY",
statics: "DEFINE_MANY",
propTypes: "DEFINE_MANY",
contextTypes: "DEFINE_MANY",
childContextTypes: "DEFINE_MANY",
getDefaultProps: "DEFINE_MANY_MERGED",
getInitialState: "DEFINE_MANY_MERGED",
getChildContext: "DEFINE_MANY_MERGED",
render: "DEFINE_ONCE",
componentWillMount: "DEFINE_MANY",
componentDidMount: "DEFINE_MANY",
componentWillReceiveProps: "DEFINE_MANY",
shouldComponentUpdate: "DEFINE_ONCE",
componentWillUpdate: "DEFINE_MANY",
componentDidUpdate: "DEFINE_MANY",
componentWillUnmount: "DEFINE_MANY",
updateComponent: "OVERRIDE_BASE"
};
/**
* Mapping from class specification keys to special processing functions.
*
* Although these are declared like instance properties in the specification
* when defining classes using `React.createClass`, they are actually static
* and are accessible on the constructor instead of the prototype. Despite
* being static, they must be defined outside of the "statics" key under
* which all other static methods are defined.
*/
var RESERVED_SPEC_KEYS = {
displayName: function displayName(Constructor, _displayName) {
return (Constructor.displayName = _displayName);
},
mixins: function mixins(Constructor, _mixins) {
if (_mixins) {
for (var i = 0; i < _mixins.length; i++) {
mixSpecIntoComponent(Constructor, _mixins[i]);
}
}
},
childContextTypes: function childContextTypes(
Constructor,
_childContextTypes
) {
return (Constructor.childContextTypes = _assign(
{},
Constructor.childContextTypes,
_childContextTypes
));
},
contextTypes: function contextTypes(Constructor, _contextTypes) {
return (Constructor.contextTypes = _assign(
{},
Constructor.contextTypes,
_contextTypes
));
},
/**
* Special case getDefaultProps which should move into statics but requires
* automatic merging.
*/
getDefaultProps: function getDefaultProps(Constructor, _getDefaultProps) {
if (Constructor.getDefaultProps) {
Constructor.getDefaultProps = createMergedResultFunction(
Constructor.getDefaultProps,
_getDefaultProps
);
} else {
Constructor.getDefaultProps = _getDefaultProps;
}
},
propTypes: function propTypes(Constructor, _propTypes) {
Constructor.propTypes = _assign({}, Constructor.propTypes, _propTypes);
},
statics: function statics(Constructor, _statics) {
mixStaticSpecIntoComponent(Constructor, _statics);
},
autobind: function autobind() {}
};
function validateMethodOverride(isAlreadyDefined, name) {
var specPolicy = ReactClassInterface.hasOwnProperty(name)
? ReactClassInterface[name]
: null;
// Disallow overriding of base class methods unless explicitly allowed.
if (ReactClassMixin.hasOwnProperty(name)) {
_invariant(
specPolicy === "OVERRIDE_BASE",
"ReactClassInterface: You are attempting to override " +
"`%s` from your class specification. Ensure that your method names " +
"do not overlap with React methods.",
name
);
}
// Disallow defining methods more than once unless explicitly allowed.
if (isAlreadyDefined) {
_invariant(
specPolicy === "DEFINE_MANY" || specPolicy === "DEFINE_MANY_MERGED",
"ReactClassInterface: You are attempting to define " +
"`%s` on your component more than once. This conflict may be due " +
"to a mixin.",
name
);
}
}
/**
* Mixin helper which handles policy validation and reserved
* specification keys when building React classes.
*/
function mixSpecIntoComponent(Constructor, spec) {
if (!spec) {
return;
}
_invariant(
typeof spec !== "function",
"ReactClass: You're attempting to " +
"use a component class or function as a mixin. Instead, just use a " +
"regular object."
);
var proto = Constructor.prototype;
var autoBindPairs = proto.__reactAutoBindPairs;
// By handling mixins before any other properties, we ensure the same
// chaining order is applied to methods with DEFINE_MANY policy, whether
// mixins are listed before or after these methods in the spec.
if (spec.hasOwnProperty(MIXINS_KEY)) {
RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins);
}
for (var name in spec) {
if (!spec.hasOwnProperty(name)) {
continue;
}
if (name === MIXINS_KEY) {
// We have already handled mixins in a special case above.
continue;
}
var property = spec[name];
var isAlreadyDefined = proto.hasOwnProperty(name);
validateMethodOverride(isAlreadyDefined, name);
if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
RESERVED_SPEC_KEYS[name](Constructor, property);
} else {
// Setup methods on prototype:
// The following member methods should not be automatically bound:
// 1. Expected ReactClass methods (in the "interface").
// 2. Overridden methods (that were mixed in).
var isReactClassMethod = ReactClassInterface.hasOwnProperty(name);
var isFunction = typeof property === "function";
var shouldAutoBind =
isFunction &&
!isReactClassMethod &&
!isAlreadyDefined &&
spec.autobind !== false;
if (shouldAutoBind) {
autoBindPairs.push(name, property);
proto[name] = property;
} else {
if (isAlreadyDefined) {
var specPolicy = ReactClassInterface[name];
// These cases should already be caught by validateMethodOverride.
_invariant(
isReactClassMethod &&
(specPolicy === "DEFINE_MANY_MERGED" ||
specPolicy === "DEFINE_MANY"),
"ReactClass: Unexpected spec policy %s for key %s " +
"when mixing in component specs.",
specPolicy,
name
);
// For methods which are defined more than once, call the existing
// methods before calling the new property, merging if appropriate.
if (specPolicy === "DEFINE_MANY_MERGED") {
console.log(name, "createMergedResultFunction");
proto[name] = createMergedResultFunction(proto[name], property);
} else if (specPolicy === "DEFINE_MANY") {
proto[name] = createChainedFunction(proto[name], property);
}
} else {
proto[name] = property;
{
// Add verbose displayName to the function, which helps when looking
// at profiling tools.
if (typeof property === "function" && spec.displayName) {
proto[name].displayName = spec.displayName + "_" + name;
}
}
}
}
}
}
}
function mixStaticSpecIntoComponent(Constructor, statics) {
if (!statics) {
return;
}
for (var name in statics) {
var property = statics[name];
if (!statics.hasOwnProperty(name)) {
continue;
}
var isReserved = name in RESERVED_SPEC_KEYS;
_invariant(
!isReserved,
"ReactClass: You are attempting to define a reserved " +
'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' +
"as an instance property instead; it will still be accessible on the " +
"constructor.",
name
);
var isInherited = name in Constructor;
_invariant(
!isInherited,
"ReactClass: You are attempting to define " +
"`%s` on your component more than once. This conflict may be " +
"due to a mixin.",
name
);
Constructor[name] = property;
}
}
function mergeIntoWithNoDuplicateKeys(one, two) {
_invariant(
one &&
two &&
(typeof one === "undefined" ? "undefined" : _typeof(one)) ===
"object" &&
(typeof two === "undefined" ? "undefined" : _typeof(two)) === "object",
"mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects."
);
for (var key in two) {
if (two.hasOwnProperty(key)) {
one[key] = two[key];
}
}
return one;
}
function createMergedResultFunction(one, two) {
return function mergedResult() {
var a = one.apply(this, arguments);
var b = two.apply(this, arguments);
if (a == null) {
return b;
} else if (b == null) {
return a;
}
var c = {};
mergeIntoWithNoDuplicateKeys(c, a);
mergeIntoWithNoDuplicateKeys(c, b);
return c;
};
}
function createChainedFunction(one, two) {
return function chainedFunction() {
one.apply(this, arguments);
two.apply(this, arguments);
};
}
function bindAutoBindMethod(component, method) {
var boundMethod = method.bind(component);
return boundMethod;
}
function bindAutoBindMethods(component) {
var pairs = component.__reactAutoBindPairs;
for (var i = 0; i < pairs.length; i += 2) {
var autoBindKey = pairs[i];
var method = pairs[i + 1];
component[autoBindKey] = bindAutoBindMethod(component, method);
}
}
var ReactClassMixin = {
/**
* TODO: This will be deprecated because state should always keep a consistent
* type signature and the only use case for this, is to avoid that.
*/
replaceState: function replaceState(newState, callback) {
// this.updater.enqueueReplaceState(this, newState, callback);
},
/**
* Checks whether or not this composite component is mounted.
* @return {boolean} True if mounted, false otherwise.
* @protected
* @final
*/
isMounted: function isMounted() {
return !!this._rendered && this._rendered._hostNode;
}
};
var ReactClassComponent = function ReactClassComponent() {};
_assign(
ReactClassComponent.prototype,
ReactComponent.prototype,
ReactClassMixin
);
/**
* Creates a composite component class given a class specification.
* See https://facebook.github.io/react/docs/top-level-api.html#react.createclass
*
* @param {object} spec Class specification (which must define `render`).
* @return {function} Component constructor function.
* @public
*/
function newCtor(className, ReactComponent, bindAutoBindMethods) {
var curry = Function(
"ReactComponent",
"bindAutoBindMethods",
`return function ${className}(props, context) {
ReactComponent.call(this, props, context);
var initialState = this.getInitialState ? this.getInitialState() : {};
this.state = initialState;
// This constructor gets overridden by mocks. The argument is used
// by mocks to assert on what gets mounted.
// Wire up auto-binding
if (this.__reactAutoBindPairs.length) {
bindAutoBindMethods(this);
}
};`
);
return curry(ReactComponent, bindAutoBindMethods);
}
function createClass(spec) {
// To keep our warnings more understandable, we'll use a little hack here to
// ensure that Constructor.name !== 'Constructor'. This makes sure we don't
// unnecessarily identify a class without displayName as 'Constructor'.
var Constructor = newCtor(
spec.displayName || "Component",
ReactComponent,
bindAutoBindMethods
);
Constructor.prototype = new ReactClassComponent();
Constructor.prototype.constructor = Constructor;
Constructor.prototype.__reactAutoBindPairs = [];
injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor));
// mixSpecIntoComponent(Constructor, IsMountedPreMixin);
mixSpecIntoComponent(Constructor, spec);
// mixSpecIntoComponent(Constructor, IsMountedPostMixin);
// Initialize the defaultProps property after all mixins have been merged.
if (Constructor.getDefaultProps) {
Constructor.defaultProps = Constructor.getDefaultProps();
}
_invariant(
Constructor.prototype.render,
"createClass(...): Class specification must implement a `render` method."
);
// Reduce time spent doing lookups by setting these on the prototype.
for (var methodName in ReactClassInterface) {
if (!Constructor.prototype[methodName]) {
Constructor.prototype[methodName] = null;
}
}
return Constructor;
}
React.createClass = createClass;