UNPKG

react-redux-infuser

Version:

A thin layer wrapping react-redux tools to simplify creating more powerful React containers

1,608 lines (1,373 loc) 837 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor); } }return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor; }; }(); /** * import React from 'react'; * import { Component } from 'react'; * import infuse from 'react-redux-infuser'; * * import * as appActions from './actions/appActions'; * import * as miscActions from './actions/miscActions'; * import * as appHandlers from './handlers/appHandlers'; * import * as helpers from './lib/helpers'; * * class AppContainer extends Component { * render() { * const { foo, bar, appActions, miscActions, appHandlers, helpers } = this.props; * * // Where `foo, bar` are values bound to the state * // Where `appActions, miscActions`, trigger redux actions * // Where `appHandlers` is an object of handler functions bound to this container * // Where `helpers` is an object of utility functions * * return ( * <div>Hello, world!</div> * ) * } * } * * export default infuse(AppContainer, { * * actions: { * appActions: appActions, * miscActions: miscActions * }, * * binders: { * appHandlers: appHandlers * }, * * modules: { * helpers: helpers * }, * * values: state => ({ * foo: state.app.foo, * bar: state.app.bar * }) * * }) */ /* * Import peer dependencies. */ var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _redux = require('redux'); var _reactRedux = require('react-redux'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); }return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass))); }subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * @class Binders * * Ok, this is the craziest part. Here's what's going on: * * PURPOSE: In order to bind functions to an instance, we need that instance to * be available. Therefore, we can't just modify props before instantiation because * they are generated before instantiation. Instead, we need a way to allow * props to be immutable but still bind prop functions to the instance after * instantiation. */ var Binders = function () { /* * The `binders` property of our `propsFor` object consists of many sub-objects. * Each of these sub-objects is full of functions that should be bound to the * container. * * This function will instead attach prop functions that stand in as proxies. * Each proxy, when called, will check to see if the necessary bound function * exists. If so, it'll call it. If not, it'll make it, then call it. */ function Binders(binders) { var _this = this; _classCallCheck(this, Binders); /* * This tracks the value the functions will bind to, I.E. the class instance. * That instance doesn't exist at the moment the constructor runs so it has to be * null for now and we'll attach a value to it after we have the instance. */ this.__bindTo__ = null; /* * Loop over each sub-object and create a corresponding sub-object for it * on `this`. */ Object.keys(binders).forEach(function (binderPackName) { var binderPack = binders[binderPackName]; var isFunction = typeof binderPack === 'function'; /* * Loop over each function. We intend to turn it into a function bound * to the container instance. To do that, we'll create a closure var * that will hold a reference to the bound function once it exists. * We then actually create a function that checks to see if this reference * exists and creates it if not. Then it calls it. * * To create the bound function, we expect that we have already set a * value for `this.__bindTo__` which we can only get once we the instance exists. */ if (!isFunction) { var destBinderPack = _this[binderPackName] = {}; Object.keys(binderPack).forEach(function (fnName) { var boundFn = null; destBinderPack[fnName] = function () { if (!boundFn) { boundFn = binderPack[fnName].bind(_this.__bindTo__); } return boundFn.apply(undefined, arguments); }; }); /* * For a single function instead of an object of functions, * just create a single binder. */ } else { var boundFn = null; _this[binderPackName] = function () { if (!boundFn) { boundFn = binderPack.bind(_this.__bindTo__); } return boundFn.apply(undefined, arguments); }; } }); } /* * This function attaches a value to `this.__bindTo__` so that when our * prop functions attempt to create necessary bound functions, they'll * have a value to bind to. */ _createClass(Binders, [{ key: 'use', value: function use(bindTo) { this.__bindTo__ = bindTo; } }]); return Binders; }(); /** * Returns a new, connected component with actions, state values, and * bound functions in place. * * @param {Class} Container A container class for a React app. * @param {Object} propsFor Takes `actions`, `binders`, `values`, all optionally. * * @return {Class} A new, connected React class. */ function infuse(Container, propsFor) { var binderCache = void 0; /* * Make sure we have all 3 values or fallbacks for each one. * This makes each one optional. */ var actions = propsFor.actions || {}; var binders = propsFor.binders || {}; var modules = propsFor.modules || {}; var values = propsFor.values || function () { return {}; }; /* * There's a potential pitfall in that the `values` property is a function, not an object. * It's an easy mistake to make so let's throw an error if the user provides an object * instead of a function. */ if (typeof values !== 'function') { throw new Error('The values property must be a function that selects values from the redux state.'); } /** * Runs on update and maps state values to class props. * * @param {Object} state Redux state * * @return {Object} Defines which state values should be mapped to properties. */ function mapStateToProps(state) { return values(state); } /** * The `actions` property of the `propsFor` config is an object full of sub-objects. * Each of these sub-objects is full of functions. Here, we'll turn each sub-object * into a class prop and we'll translate each function into an action creator. * * @param {Function} dispatch Reduxy dispatch stuff. * * @return {Object} Each value becomes a prop. */ function mapDispatchToProps(dispatch) { var actionCreators = {}; /* * For every collection of functions, create a destination in `actionCreators` * where we'll store translated functions. */ Object.keys(actions).forEach(function (actionPackName) { var actionPack = actions[actionPackName]; var isFunction = typeof actionPack === 'function'; if (!isFunction) { var destActionPack = actionCreators[actionPackName] = {}; /* * For each function, turn it into a function that triggers an action * and store it in its destination location. */ Object.keys(actionPack).forEach(function (fnName) { destActionPack[fnName] = (0, _redux.bindActionCreators)(actionPack[fnName], dispatch); }); } else { /* * For functions, just bind the single function. */ actionCreators[actionPackName] = (0, _redux.bindActionCreators)(actionPack, dispatch); } }); /* * Here, we'll take the opportunity to piggyback off of `connect`'s mapDispatchToProps * to add any other modules to the props that the user might have given us * but this time, we won't use bindActionCreators on them. We can just transfer * them over. */ return Object.assign({}, actionCreators, modules); } /* * In order for everything to work properly, we need a reference to a container instance. * In order to get that reference, we need to return a proxy class. That proxy class gets * run through `connect` so that it can have all the mapped state and action props ready to go. * It's job is then simply to pass its props down the container instance when it's returned. */ return (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(function (_React$Component) { _inherits(_class, _React$Component); function _class() { _classCallCheck(this, _class); return _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments)); } _createClass(_class, [{ key: 'shouldComponentUpdate', /* * Only update the component if a prop has actually changed. */ value: function shouldComponentUpdate(nextProps) { var curProps = this.props; var shouldUpdate = false; Object.keys(curProps).some(function (propName) { if (curProps[propName] !== nextProps[propName]) { return shouldUpdate = true; } }); return shouldUpdate; } }, { key: 'render', value: function render() { /* * Either generate our binder functions or pull them from the * cache so we don't have to remake them on every render call. */ var newBinders = void 0; if (binderCache) { newBinders = binderCache; } else { newBinders = binderCache = new Binders(binders); } /* * Create our collection of new props to add to the child */ var newProps = Object.assign({}, this.props); Object.keys(newBinders).forEach(function (key) { if (key !== '__bindTo__') { newProps[key] = newBinders[key]; } }); /* * Instantiate the container and pass down our props to it, including our binder functions as * well as children in case any exist. * * Now that the element exists, pass it into the `use` method on the `Binders` class so that * when each binder proxy creates the actual bound function upon its first time being * called, we'll have the value to bind to. */ var container = _react2.default.createElement(Container, newProps, this.props.children); newBinders.use(container); /* * Return the cloned element. */ return container; } }]); return _class; }(_react2.default.Component)); } infuse.Binders = Binders; module.exports = exports = infuse; },{"react":217,"react-redux":186,"redux":223}],2:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateFoo = updateFoo; exports.updateBar = updateBar; function updateFoo(payload) { return { type: 'UPDATE_FOO', payload: payload }; } function updateBar(payload) { return { type: 'UPDATE_BAR', payload: payload }; } },{}],3:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.clickMe = clickMe; function clickMe(evt) { var _props = this.props, helpers = _props.helpers, appActions = _props.appActions, miscActions = _props.miscActions; evt && evt.preventDefault(); helpers.logStuff(); appActions.updateFoo('foo was updated after click'); appActions.updateBar('bar was updated after click'); miscActions.updateName('name was updated after click'); } },{}],4:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.logStuff = logStuff; function logStuff() { console.log('I am logging stuff because I am a helper'); } },{}],5:[function(require,module,exports){ 'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _reactRedux = require('react-redux'); var _index = require('../../../bin/index'); var _index2 = _interopRequireDefault(_index); var _store = require('./store'); var _store2 = _interopRequireDefault(_store); var _appActions = require('./appActions'); var appActions = _interopRequireWildcard(_appActions); var _miscActions = require('./miscActions'); var miscActions = _interopRequireWildcard(_miscActions); var _appHandlers = require('./appHandlers'); var appHandlers = _interopRequireWildcard(_appHandlers); var _helpers = require('./helpers'); var helpers = _interopRequireWildcard(_helpers); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var App = function (_Component) { _inherits(App, _Component); function App() { _classCallCheck(this, App); return _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).apply(this, arguments)); } _createClass(App, [{ key: 'render', value: function render() { return _react2.default.createElement('input', { type: 'text' }); } }]); return App; }(_react.Component); var AppContainer = function (_Component2) { _inherits(AppContainer, _Component2); _createClass(AppContainer, [{ key: 'componentDidUpdate', value: function componentDidUpdate() { console.log('updated'); } }]); function AppContainer() { _classCallCheck(this, AppContainer); var _this2 = _possibleConstructorReturn(this, (AppContainer.__proto__ || Object.getPrototypeOf(AppContainer)).call(this)); _this2.state = { stateVal: 'this is the stateVal' }; return _this2; } _createClass(AppContainer, [{ key: 'componentDidMount', value: function componentDidMount() { var _props = this.props, appActions = _props.appActions, miscActions = _props.miscActions, updateBazzer = _props.updateBazzer, appHandlers = _props.appHandlers, helpers = _props.helpers; setTimeout(function () { helpers.logStuff(); appActions.updateFoo('foo was updated'); appActions.updateBar('bar was updated'); miscActions.updateName('name was updated'); updateBazzer(); }, 3000); } }, { key: 'render', value: function render() { var _props2 = this.props, appHandlers = _props2.appHandlers, handleNothing = _props2.handleNothing; return _react2.default.createElement( 'div', null, _react2.default.createElement( 'a', { onClick: appHandlers.clickMe }, 'Click me' ), _react2.default.createElement( 'div', null, 'Misc name: ', this.props.name ), _react2.default.createElement( 'div', null, 'App foo: ', this.props.foo ), _react2.default.createElement( 'div', null, 'App bar: ', this.props.bar ), _react2.default.createElement( 'div', null, 'App bazzer: ', this.props.bazzer ), _react2.default.createElement( 'a', { onClick: handleNothing }, 'Click me too' ), _react2.default.createElement('br', null), _react2.default.createElement(App, { appActions: this.props.appActions, miscActions: this.props.miscActions, appHandlers: this.props.appHandlers, helpers: this.props.helpers }) ); } }]); return AppContainer; }(_react.Component); var Infused = (0, _index2.default)(AppContainer, { actions: { appActions: appActions, miscActions: miscActions, updateBazzer: function updateBazzer() { return { type: 'BAZZER' }; } }, binders: { appHandlers: appHandlers, handleNothing: function handleNothing() { console.log('my props are', this.props); } }, modules: { helpers: helpers }, values: function values(state) { return { name: state.misc.name, foo: state.app.foo, bar: state.app.bar, bazzer: state.app.bazzer }; } }); _reactDom2.default.render(_react2.default.createElement( _reactRedux.Provider, { store: _store2.default }, _react2.default.createElement(Infused, null) ), document.getElementById('app')); },{"../../../bin/index":1,"./appActions":2,"./appHandlers":3,"./helpers":4,"./miscActions":6,"./store":7,"react":217,"react-dom":51,"react-redux":186}],6:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.updateName = updateName; function updateName(payload) { return { type: 'UPDATE_NAME', payload: payload }; } },{}],7:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _redux = require('redux'); var initialState = { misc: { name: 'Papa John' }, app: { foo: 'foofoofoo', bar: 'barbarbar', bazzer: 1 } }; function miscReducer() { var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState.misc; var action = arguments[1]; switch (action.type) { case 'UPDATE_NAME': return Object.assign({}, state, { name: action.payload }); default: return state; } } function appReducer() { var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState.app; var action = arguments[1]; switch (action.type) { case 'UPDATE_FOO': return Object.assign({}, state, { foo: action.payload }); case 'UPDATE_BAR': return Object.assign({}, state, { bar: action.payload }); case 'BAZZER': return Object.assign({}, state, { bazzer: state.bazzer + 1 }); default: return state; } } var reducers = { misc: miscReducer, app: appReducer }; function devToolsCompose() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } if (window.__REDUX_DEVTOOLS_EXTENSION__) { args.push(window.__REDUX_DEVTOOLS_EXTENSION__()); } return _redux.compose.apply(null, args); } var store = (0, _redux.createStore)((0, _redux.combineReducers)(reducers), initialState, devToolsCompose()); exports.default = store; },{"redux":223}],8:[function(require,module,exports){ (function (process){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @typechecks */ var emptyFunction = require('./emptyFunction'); /** * Upstream version of event listener. Does not take into account specific * nature of platform. */ var EventListener = { /** * Listen to DOM events during the bubble phase. * * @param {DOMEventTarget} target DOM element to register listener on. * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. * @param {function} callback Callback function. * @return {object} Object with a `remove` method. */ listen: function listen(target, eventType, callback) { if (target.addEventListener) { target.addEventListener(eventType, callback, false); return { remove: function remove() { target.removeEventListener(eventType, callback, false); } }; } else if (target.attachEvent) { target.attachEvent('on' + eventType, callback); return { remove: function remove() { target.detachEvent('on' + eventType, callback); } }; } }, /** * Listen to DOM events during the capture phase. * * @param {DOMEventTarget} target DOM element to register listener on. * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. * @param {function} callback Callback function. * @return {object} Object with a `remove` method. */ capture: function capture(target, eventType, callback) { if (target.addEventListener) { target.addEventListener(eventType, callback, true); return { remove: function remove() { target.removeEventListener(eventType, callback, true); } }; } else { if (process.env.NODE_ENV !== 'production') { console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.'); } return { remove: emptyFunction }; } }, registerDefault: function registerDefault() {} }; module.exports = EventListener; }).call(this,require('_process')) },{"./emptyFunction":15,"_process":44}],9:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ 'use strict'; var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); /** * Simple, lightweight module assisting with the detection and context of * Worker. Helps avoid circular dependencies and allows code to reason about * whether or not they are in a Worker, even if they never include the main * `ReactWorker` dependency. */ var ExecutionEnvironment = { canUseDOM: canUseDOM, canUseWorkers: typeof Worker !== 'undefined', canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent), canUseViewport: canUseDOM && !!window.screen, isInWorker: !canUseDOM // For now, this is true - might change in the future. }; module.exports = ExecutionEnvironment; },{}],10:[function(require,module,exports){ "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ var _hyphenPattern = /-(.)/g; /** * Camelcases a hyphenated string, for example: * * > camelize('background-color') * < "backgroundColor" * * @param {string} string * @return {string} */ function camelize(string) { return string.replace(_hyphenPattern, function (_, character) { return character.toUpperCase(); }); } module.exports = camelize; },{}],11:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ 'use strict'; var camelize = require('./camelize'); var msPattern = /^-ms-/; /** * Camelcases a hyphenated CSS property name, for example: * * > camelizeStyleName('background-color') * < "backgroundColor" * > camelizeStyleName('-moz-transition') * < "MozTransition" * > camelizeStyleName('-ms-transition') * < "msTransition" * * As Andi Smith suggests * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix * is converted to lowercase `ms`. * * @param {string} string * @return {string} */ function camelizeStyleName(string) { return camelize(string.replace(msPattern, 'ms-')); } module.exports = camelizeStyleName; },{"./camelize":10}],12:[function(require,module,exports){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * */ var isTextNode = require('./isTextNode'); /*eslint-disable no-bitwise */ /** * Checks if a given DOM node contains or is another DOM node. */ function containsNode(outerNode, innerNode) { if (!outerNode || !innerNode) { return false; } else if (outerNode === innerNode) { return true; } else if (isTextNode(outerNode)) { return false; } else if (isTextNode(innerNode)) { return containsNode(outerNode, innerNode.parentNode); } else if ('contains' in outerNode) { return outerNode.contains(innerNode); } else if (outerNode.compareDocumentPosition) { return !!(outerNode.compareDocumentPosition(innerNode) & 16); } else { return false; } } module.exports = containsNode; },{"./isTextNode":25}],13:[function(require,module,exports){ (function (process){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ var invariant = require('./invariant'); /** * Convert array-like objects to arrays. * * This API assumes the caller knows the contents of the data type. For less * well defined inputs use createArrayFromMixed. * * @param {object|function|filelist} obj * @return {array} */ function toArray(obj) { var length = obj.length; // Some browsers builtin objects can report typeof 'function' (e.g. NodeList // in old versions of Safari). !(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : void 0; !(typeof length === 'number') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : void 0; !(length === 0 || length - 1 in obj) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : void 0; !(typeof obj.callee !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object can\'t be `arguments`. Use rest params ' + '(function(...args) {}) or Array.from() instead.') : invariant(false) : void 0; // Old IE doesn't give collections access to hasOwnProperty. Assume inputs // without method will throw during the slice call and skip straight to the // fallback. if (obj.hasOwnProperty) { try { return Array.prototype.slice.call(obj); } catch (e) { // IE < 9 does not support Array#slice on collections objects } } // Fall back to copying key by key. This assumes all keys have a value, // so will not preserve sparsely populated inputs. var ret = Array(length); for (var ii = 0; ii < length; ii++) { ret[ii] = obj[ii]; } return ret; } /** * Perform a heuristic test to determine if an object is "array-like". * * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" * Joshu replied: "Mu." * * This function determines if its argument has "array nature": it returns * true if the argument is an actual array, an `arguments' object, or an * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). * * It will return false for other array-like objects like Filelist. * * @param {*} obj * @return {boolean} */ function hasArrayNature(obj) { return ( // not null/false !!obj && ( // arrays are objects, NodeLists are functions in Safari typeof obj == 'object' || typeof obj == 'function') && // quacks like an array 'length' in obj && // not window !('setInterval' in obj) && // no DOM node should be considered an array-like // a 'select' element has 'length' and 'item' properties on IE8 typeof obj.nodeType != 'number' && ( // a real array Array.isArray(obj) || // arguments 'callee' in obj || // HTMLCollection/NodeList 'item' in obj) ); } /** * Ensure that the argument is an array by wrapping it in an array if it is not. * Creates a copy of the argument if it is already an array. * * This is mostly useful idiomatically: * * var createArrayFromMixed = require('createArrayFromMixed'); * * function takesOneOrMoreThings(things) { * things = createArrayFromMixed(things); * ... * } * * This allows you to treat `things' as an array, but accept scalars in the API. * * If you need to convert an array-like object, like `arguments`, into an array * use toArray instead. * * @param {*} obj * @return {array} */ function createArrayFromMixed(obj) { if (!hasArrayNature(obj)) { return [obj]; } else if (Array.isArray(obj)) { return obj.slice(); } else { return toArray(obj); } } module.exports = createArrayFromMixed; }).call(this,require('_process')) },{"./invariant":23,"_process":44}],14:[function(require,module,exports){ (function (process){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ /*eslint-disable fb-www/unsafe-html*/ var ExecutionEnvironment = require('./ExecutionEnvironment'); var createArrayFromMixed = require('./createArrayFromMixed'); var getMarkupWrap = require('./getMarkupWrap'); var invariant = require('./invariant'); /** * Dummy container used to render all markup. */ var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; /** * Pattern used by `getNodeName`. */ var nodeNamePattern = /^\s*<(\w+)/; /** * Extracts the `nodeName` of the first element in a string of markup. * * @param {string} markup String of markup. * @return {?string} Node name of the supplied markup. */ function getNodeName(markup) { var nodeNameMatch = markup.match(nodeNamePattern); return nodeNameMatch && nodeNameMatch[1].toLowerCase(); } /** * Creates an array containing the nodes rendered from the supplied markup. The * optionally supplied `handleScript` function will be invoked once for each * <script> element that is rendered. If no `handleScript` function is supplied, * an exception is thrown if any <script> elements are rendered. * * @param {string} markup A string of valid HTML markup. * @param {?function} handleScript Invoked once for each rendered <script>. * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. */ function createNodesFromMarkup(markup, handleScript) { var node = dummyNode; !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup dummy not initialized') : invariant(false) : void 0; var nodeName = getNodeName(markup); var wrap = nodeName && getMarkupWrap(nodeName); if (wrap) { node.innerHTML = wrap[1] + markup + wrap[2]; var wrapDepth = wrap[0]; while (wrapDepth--) { node = node.lastChild; } } else { node.innerHTML = markup; } var scripts = node.getElementsByTagName('script'); if (scripts.length) { !handleScript ? process.env.NODE_ENV !== 'production' ? invariant(false, 'createNodesFromMarkup(...): Unexpected <script> element rendered.') : invariant(false) : void 0; createArrayFromMixed(scripts).forEach(handleScript); } var nodes = Array.from(node.childNodes); while (node.lastChild) { node.removeChild(node.lastChild); } return nodes; } module.exports = createNodesFromMarkup; }).call(this,require('_process')) },{"./ExecutionEnvironment":9,"./createArrayFromMixed":13,"./getMarkupWrap":19,"./invariant":23,"_process":44}],15:[function(require,module,exports){ "use strict"; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * */ function makeEmptyFunction(arg) { return function () { return arg; }; } /** * This function accepts and discards inputs; it has no side effects. This is * primarily useful idiomatically for overridable function endpoints which * always need to be callable, since JS lacks a null-call idiom ala Cocoa. */ var emptyFunction = function emptyFunction() {}; emptyFunction.thatReturns = makeEmptyFunction; emptyFunction.thatReturnsFalse = makeEmptyFunction(false); emptyFunction.thatReturnsTrue = makeEmptyFunction(true); emptyFunction.thatReturnsNull = makeEmptyFunction(null); emptyFunction.thatReturnsThis = function () { return this; }; emptyFunction.thatReturnsArgument = function (arg) { return arg; }; module.exports = emptyFunction; },{}],16:[function(require,module,exports){ (function (process){ /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ 'use strict'; var emptyObject = {}; if (process.env.NODE_ENV !== 'production') { Object.freeze(emptyObject); } module.exports = emptyObject; }).call(this,require('_process')) },{"_process":44}],17:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ 'use strict'; /** * @param {DOMElement} node input/textarea to focus */ function focusNode(node) { // IE8 can throw "Can't move focus to the control because it is invisible, // not enabled, or of a type that does not accept the focus." for all kinds of // reasons that are too expensive and fragile to test. try { node.focus(); } catch (e) {} } module.exports = focusNode; },{}],18:[function(require,module,exports){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ /* eslint-disable fb-www/typeof-undefined */ /** * Same as document.activeElement but wraps in a try-catch block. In IE it is * not safe to call document.activeElement if there is nothing focused. * * The activeElement will be null only if the document or document body is not * yet defined. * * @param {?DOMDocument} doc Defaults to current document. * @return {?DOMElement} */ function getActiveElement(doc) /*?DOMElement*/{ doc = doc || (typeof document !== 'undefined' ? document : undefined); if (typeof doc === 'undefined') { return null; } try { return doc.activeElement || doc.body; } catch (e) { return doc.body; } } module.exports = getActiveElement; },{}],19:[function(require,module,exports){ (function (process){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ /*eslint-disable fb-www/unsafe-html */ var ExecutionEnvironment = require('./ExecutionEnvironment'); var invariant = require('./invariant'); /** * Dummy container used to detect which wraps are necessary. */ var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; /** * Some browsers cannot use `innerHTML` to render certain elements standalone, * so we wrap them, render the wrapped nodes, then extract the desired node. * * In IE8, certain elements cannot render alone, so wrap all elements ('*'). */ var shouldWrap = {}; var selectWrap = [1, '<select multiple="true">', '</select>']; var tableWrap = [1, '<table>', '</table>']; var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>']; var markupWrap = { '*': [1, '?<div>', '</div>'], 'area': [1, '<map>', '</map>'], 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], 'legend': [1, '<fieldset>', '</fieldset>'], 'param': [1, '<object>', '</object>'], 'tr': [2, '<table><tbody>', '</tbody></table>'], 'optgroup': selectWrap, 'option': selectWrap, 'caption': tableWrap, 'colgroup': tableWrap, 'tbody': tableWrap, 'tfoot': tableWrap, 'thead': tableWrap, 'td': trWrap, 'th': trWrap }; // Initialize the SVG elements since we know they'll always need to be wrapped // consistently. If they are created inside a <div> they will be initialized in // the wrong namespace (and will not display). var svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan']; svgElements.forEach(function (nodeName) { markupWrap[nodeName] = svgWrap; shouldWrap[nodeName] = true; }); /** * Gets the markup wrap configuration for the supplied `nodeName`. * * NOTE: This lazily detects which wraps are necessary for the current browser. * * @param {string} nodeName Lowercase `nodeName`. * @return {?array} Markup wrap configuration, if applicable. */ function getMarkupWrap(nodeName) { !!!dummyNode ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Markup wrapping node not initialized') : invariant(false) : void 0; if (!markupWrap.hasOwnProperty(nodeName)) { nodeName = '*'; } if (!shouldWrap.hasOwnProperty(nodeName)) { if (nodeName === '*') { dummyNode.innerHTML = '<link />'; } else { dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; } shouldWrap[nodeName] = !dummyNode.firstChild; } return shouldWrap[nodeName] ? markupWrap[nodeName] : null; } module.exports = getMarkupWrap; }).call(this,require('_process')) },{"./ExecutionEnvironment":9,"./invariant":23,"_process":44}],20:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ 'use strict'; /** * Gets the scroll position of the supplied element or window. * * The return values are unbounded, unlike `getScrollPosition`. This means they * may be negative or exceed the element boundaries (which is possible using * inertial scrolling). * * @param {DOMWindow|DOMElement} scrollable * @return {object} Map with `x` and `y` keys. */ function getUnboundedScrollPosition(scrollable) { if (scrollable.Window && scrollable instanceof scrollable.Window) { return { x: scrollable.pageXOffset || scrollable.document.documentElement.scrollLeft, y: scrollable.pageYOffset || scrollable.document.documentElement.scrollTop }; } return { x: scrollable.scrollLeft, y: scrollable.scrollTop }; } module.exports = getUnboundedScrollPosition; },{}],21:[function(require,module,exports){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ var _uppercasePattern = /([A-Z])/g; /** * Hyphenates a camelcased string, for example: * * > hyphenate('backgroundColor') * < "background-color" * * For CSS style names, use `hyphenateStyleName` instead which works properly * with all vendor prefixes, including `ms`. * * @param {string} string * @return {string} */ function hyphenate(string) { return string.replace(_uppercasePattern, '-$1').toLowerCase(); } module.exports = hyphenate; },{}],22:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ 'use strict'; var hyphenate = require('./hyphenate'); var msPattern = /^ms-/; /** * Hyphenates a camelcased CSS property name, for example: * * > hyphenateStyleName('backgroundColor') * < "background-color" * > hyphenateStyleName('MozTransition') * < "-moz-transition" * > hyphenateStyleName('msTransition') * < "-ms-transition" * * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix * is converted to `-ms-`. * * @param {string} string * @return {string} */ function hyphenateStyleName(string) { return hyphenate(string).replace(msPattern, '-ms-'); } module.exports = hyphenateStyleName; },{"./hyphenate":21}],23:[function(require,module,exports){ (function (process){ /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ 'use strict'; /** * Use invariant() to assert state which your program assumes to be true. * * Provide sprintf-style format (only %s is supported) and arguments * to provide information about what broke and what you were * expecting. * * The invariant message will be stripped in production, but the invariant * will remain to ensure logic does not differ in production. */ var validateFormat = function validateFormat(format) {}; if (process.env.NODE_ENV !== 'production') { validateFormat = function validateFormat(format) { if (format === undefined) { throw new Error('invariant requires an error message argument'); } }; } function invariant(condition, format, a, b, c, d, e, f) { validateFormat(format); 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; } } module.exports = invariant; }).call(this,require('_process')) },{"_process":44}],24:[function(require,module,exports){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ /** * @param {*} object The object to check. * @return {boolean} Whether or not the object is a DOM node. */ function isNode(object) { var doc = object ? object.ownerDocument || object : document; var defaultView = doc.defaultView || window; return !!(object && (typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string')); } module.exports = isNode; },{}],25:[function(require,module,exports){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * @typechecks */ var isNode = require('./isNode'); /** * @param {*} object The object to check. * @return {boolean} Whether or not the object is a DOM text node. */ function isTextNode(object) { return isNode(object) && object.nodeType == 3; } module.exports = isTextNode; },{"./isNode":24}],26:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the