require=(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 0) { var fn = queue.shift(); fn(); } } }, true); return function nextTick(fn) { queue.push(fn); window.postMessage('process-tick', '*'); }; } return function nextTick(fn) { setTimeout(fn, 0); }; })(); process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); }; // TODO(shtylman) process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; },{}],2:[function(require,module,exports){ /* * Copyright (c) 2014, 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. * * @providesModule Dispatcher * @typechecks */ "use strict"; var invariant = require('./invariant'); var _lastID = 1; var _prefix = 'ID_'; /** * Dispatcher is used to broadcast payloads to registered callbacks. This is * different from generic pub-sub systems in two ways: * * 1) Callbacks are not subscribed to particular events. Every payload is * dispatched to every registered callback. * 2) Callbacks can be deferred in whole or part until other callbacks have * been executed. * * For example, consider this hypothetical flight destination form, which * selects a default city when a country is selected: * * var flightDispatcher = new Dispatcher(); * * // Keeps track of which country is selected * var CountryStore = {country: null}; * * // Keeps track of which city is selected * var CityStore = {city: null}; * * // Keeps track of the base flight price of the selected city * var FlightPriceStore = {price: null} * * When a user changes the selected city, we dispatch the payload: * * flightDispatcher.dispatch({ * actionType: 'city-update', * selectedCity: 'paris' * }); * * This payload is digested by `CityStore`: * * flightDispatcher.register(function(payload) { * if (payload.actionType === 'city-update') { * CityStore.city = payload.selectedCity; * } * }); * * When the user selects a country, we dispatch the payload: * * flightDispatcher.dispatch({ * actionType: 'country-update', * selectedCountry: 'australia' * }); * * This payload is digested by both stores: * * CountryStore.dispatchToken = flightDispatcher.register(function(payload) { * if (payload.actionType === 'country-update') { * CountryStore.country = payload.selectedCountry; * } * }); * * When the callback to update `CountryStore` is registered, we save a reference * to the returned token. Using this token with `waitFor()`, we can guarantee * that `CountryStore` is updated before the callback that updates `CityStore` * needs to query its data. * * CityStore.dispatchToken = flightDispatcher.register(function(payload) { * if (payload.actionType === 'country-update') { * // `CountryStore.country` may not be updated. * flightDispatcher.waitFor([CountryStore.dispatchToken]); * // `CountryStore.country` is now guaranteed to be updated. * * // Select the default city for the new country * CityStore.city = getDefaultCityForCountry(CountryStore.country); * } * }); * * The usage of `waitFor()` can be chained, for example: * * FlightPriceStore.dispatchToken = * flightDispatcher.register(function(payload) { * switch (payload.actionType) { * case 'country-update': * flightDispatcher.waitFor([CityStore.dispatchToken]); * FlightPriceStore.price = * getFlightPriceStore(CountryStore.country, CityStore.city); * break; * * case 'city-update': * FlightPriceStore.price = * FlightPriceStore(CountryStore.country, CityStore.city); * break; * } * }); * * The `country-update` payload will be guaranteed to invoke the stores' * registered callbacks in order: `CountryStore`, `CityStore`, then * `FlightPriceStore`. */ function Dispatcher() { this.$Dispatcher_callbacks = {}; this.$Dispatcher_isPending = {}; this.$Dispatcher_isHandled = {}; this.$Dispatcher_isDispatching = false; this.$Dispatcher_pendingPayload = null; } /** * Registers a callback to be invoked with every dispatched payload. Returns * a token that can be used with `waitFor()`. * * @param {function} callback * @return {string} */ Dispatcher.prototype.register=function(callback) { var id = _prefix + _lastID++; this.$Dispatcher_callbacks[id] = callback; return id; }; /** * Removes a callback based on its token. * * @param {string} id */ Dispatcher.prototype.unregister=function(id) { invariant( this.$Dispatcher_callbacks[id], 'Dispatcher.unregister(...): `%s` does not map to a registered callback.', id ); delete this.$Dispatcher_callbacks[id]; }; /** * Waits for the callbacks specified to be invoked before continuing execution * of the current callback. This method should only be used by a callback in * response to a dispatched payload. * * @param {array} ids */ Dispatcher.prototype.waitFor=function(ids) { invariant( this.$Dispatcher_isDispatching, 'Dispatcher.waitFor(...): Must be invoked while dispatching.' ); for (var ii = 0; ii < ids.length; ii++) { var id = ids[ii]; if (this.$Dispatcher_isPending[id]) { invariant( this.$Dispatcher_isHandled[id], 'Dispatcher.waitFor(...): Circular dependency detected while ' + 'waiting for `%s`.', id ); continue; } invariant( this.$Dispatcher_callbacks[id], 'Dispatcher.waitFor(...): `%s` does not map to a registered callback.', id ); this.$Dispatcher_invokeCallback(id); } }; /** * Dispatches a payload to all registered callbacks. * * @param {object} payload */ Dispatcher.prototype.dispatch=function(payload) { invariant( !this.$Dispatcher_isDispatching, 'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.' ); this.$Dispatcher_startDispatching(payload); try { for (var id in this.$Dispatcher_callbacks) { if (this.$Dispatcher_isPending[id]) { continue; } this.$Dispatcher_invokeCallback(id); } } finally { this.$Dispatcher_stopDispatching(); } }; /** * Is this Dispatcher currently dispatching. * * @return {boolean} */ Dispatcher.prototype.isDispatching=function() { return this.$Dispatcher_isDispatching; }; /** * Call the callback stored with the given id. Also do some internal * bookkeeping. * * @param {string} id * @internal */ Dispatcher.prototype.$Dispatcher_invokeCallback=function(id) { this.$Dispatcher_isPending[id] = true; this.$Dispatcher_callbacks[id](this.$Dispatcher_pendingPayload); this.$Dispatcher_isHandled[id] = true; }; /** * Set up bookkeeping needed when dispatching. * * @param {object} payload * @internal */ Dispatcher.prototype.$Dispatcher_startDispatching=function(payload) { for (var id in this.$Dispatcher_callbacks) { this.$Dispatcher_isPending[id] = false; this.$Dispatcher_isHandled[id] = false; } this.$Dispatcher_pendingPayload = payload; this.$Dispatcher_isDispatching = true; }; /** * Clear bookkeeping used for dispatching. * * @internal */ Dispatcher.prototype.$Dispatcher_stopDispatching=function() { this.$Dispatcher_pendingPayload = null; this.$Dispatcher_isDispatching = false; }; module.exports = Dispatcher; },{"./invariant":3}],3:[function(require,module,exports){ /** * Copyright (c) 2014, 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. * * @providesModule invariant */ "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 invariant = function(condition, format, a, b, c, d, e, f) { if (false) { if (format === undefined) { throw new Error('invariant requires an error message argument'); } } 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( 'Invariant Violation: ' + format.replace(/%s/g, function() { return args[argIndex++]; }) ); } error.framesToPop = 1; // we don't care about invariant's own frame throw error; } }; module.exports = invariant; },{}],4:[function(require,module,exports){ "use strict"; /** * Represents a cancellation caused by navigating away * before the previous transition has fully resolved. */ function Cancellation() {} module.exports = Cancellation; },{}],5:[function(require,module,exports){ "use strict"; var warning = require("react/lib/warning"); var invariant = require("react/lib/invariant"); function checkPropTypes(componentName, propTypes, props) { for (var propName in propTypes) { if (propTypes.hasOwnProperty(propName)) { var error = propTypes[propName](props, propName, componentName); if (error instanceof Error) warning(false, error.message); } } } var Configuration = { statics: { validateProps: function validateProps(props) { checkPropTypes(this.displayName, this.propTypes, props); } }, render: function render() { invariant(false, "%s elements are for router configuration only and should not be rendered", this.constructor.displayName); } }; module.exports = Configuration; },{"react/lib/invariant":182,"react/lib/warning":202}],6:[function(require,module,exports){ "use strict"; var invariant = require("react/lib/invariant"); var canUseDOM = require("react/lib/ExecutionEnvironment").canUseDOM; var History = { /** * The current number of entries in the history. * * Note: This property is read-only. */ length: 1, /** * Sends the browser back one entry in the history. */ back: function back() { invariant(canUseDOM, "Cannot use History.back without a DOM"); // Do this first so that History.length will // be accurate in location change listeners. History.length -= 1; window.history.back(); } }; module.exports = History; },{"react/lib/ExecutionEnvironment":64,"react/lib/invariant":182}],7:[function(require,module,exports){ "use strict"; var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; /* jshint -W084 */ var PathUtils = require("./PathUtils"); function deepSearch(route, pathname, query) { // Check the subtree first to find the most deeply-nested match. var childRoutes = route.childRoutes; if (childRoutes) { var match, childRoute; for (var i = 0, len = childRoutes.length; i < len; ++i) { childRoute = childRoutes[i]; if (childRoute.isDefault || childRoute.isNotFound) continue; // Check these in order later. if (match = deepSearch(childRoute, pathname, query)) { // A route in the subtree matched! Add this route and we're done. match.routes.unshift(route); return match; } } } // No child routes matched; try the default route. var defaultRoute = route.defaultRoute; if (defaultRoute && (params = PathUtils.extractParams(defaultRoute.path, pathname))) { return new Match(pathname, params, query, [route, defaultRoute]); } // Does the "not found" route match? var notFoundRoute = route.notFoundRoute; if (notFoundRoute && (params = PathUtils.extractParams(notFoundRoute.path, pathname))) { return new Match(pathname, params, query, [route, notFoundRoute]); } // Last attempt: check this route. var params = PathUtils.extractParams(route.path, pathname); if (params) { return new Match(pathname, params, query, [route]); }return null; } var Match = (function () { function Match(pathname, params, query, routes) { _classCallCheck(this, Match); this.pathname = pathname; this.params = params; this.query = query; this.routes = routes; } _prototypeProperties(Match, { findMatch: { /** * Attempts to match depth-first a route in the given route's * subtree against the given path and returns the match if it * succeeds, null if no match can be made. */ value: function findMatch(routes, path) { var pathname = PathUtils.withoutQuery(path); var query = PathUtils.extractQuery(path); var match = null; for (var i = 0, len = routes.length; match == null && i < len; ++i) match = deepSearch(routes[i], pathname, query); return match; }, writable: true, configurable: true } }); return Match; })(); module.exports = Match; },{"./PathUtils":10}],8:[function(require,module,exports){ "use strict"; var PropTypes = require("./PropTypes"); /** * A mixin for components that modify the URL. * * Example: * * var MyLink = React.createClass({ * mixins: [ Router.Navigation ], * handleClick: function (event) { * event.preventDefault(); * this.transitionTo('aRoute', { the: 'params' }, { the: 'query' }); * }, * render: function () { * return ( * Click me! * ); * } * }); */ var Navigation = { contextTypes: { makePath: PropTypes.func.isRequired, makeHref: PropTypes.func.isRequired, transitionTo: PropTypes.func.isRequired, replaceWith: PropTypes.func.isRequired, goBack: PropTypes.func.isRequired }, /** * Returns an absolute URL path created from the given route * name, URL parameters, and query values. */ makePath: function makePath(to, params, query) { return this.context.makePath(to, params, query); }, /** * Returns a string that may safely be used as the href of a * link to the route with the given name. */ makeHref: function makeHref(to, params, query) { return this.context.makeHref(to, params, query); }, /** * Transitions to the URL specified in the arguments by pushing * a new URL onto the history stack. */ transitionTo: function transitionTo(to, params, query) { this.context.transitionTo(to, params, query); }, /** * Transitions to the URL specified in the arguments by replacing * the current URL in the history stack. */ replaceWith: function replaceWith(to, params, query) { this.context.replaceWith(to, params, query); }, /** * Transitions to the previous URL. */ goBack: function goBack() { return this.context.goBack(); } }; module.exports = Navigation; },{"./PropTypes":11}],9:[function(require,module,exports){ "use strict"; var PropTypes = require("./PropTypes"); /** * Provides the router with context for Router.Navigation. */ var NavigationContext = { childContextTypes: { makePath: PropTypes.func.isRequired, makeHref: PropTypes.func.isRequired, transitionTo: PropTypes.func.isRequired, replaceWith: PropTypes.func.isRequired, goBack: PropTypes.func.isRequired }, getChildContext: function getChildContext() { return { makePath: this.constructor.makePath.bind(this.constructor), makeHref: this.constructor.makeHref.bind(this.constructor), transitionTo: this.constructor.transitionTo.bind(this.constructor), replaceWith: this.constructor.replaceWith.bind(this.constructor), goBack: this.constructor.goBack.bind(this.constructor) }; } }; module.exports = NavigationContext; },{"./PropTypes":11}],10:[function(require,module,exports){ "use strict"; var invariant = require("react/lib/invariant"); var merge = require("qs/lib/utils").merge; var qs = require("qs"); var paramCompileMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g; var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g; var paramInjectTrailingSlashMatcher = /\/\/\?|\/\?\/|\/\?/g; var queryMatcher = /\?(.+)/; var _compiledPatterns = {}; function compilePattern(pattern) { if (!(pattern in _compiledPatterns)) { var paramNames = []; var source = pattern.replace(paramCompileMatcher, function (match, paramName) { if (paramName) { paramNames.push(paramName); return "([^/?#]+)"; } else if (match === "*") { paramNames.push("splat"); return "(.*?)"; } else { return "\\" + match; } }); _compiledPatterns[pattern] = { matcher: new RegExp("^" + source + "$", "i"), paramNames: paramNames }; } return _compiledPatterns[pattern]; } var PathUtils = { /** * Returns true if the given path is absolute. */ isAbsolute: function isAbsolute(path) { return path.charAt(0) === "/"; }, /** * Joins two URL paths together. */ join: function join(a, b) { return a.replace(/\/*$/, "/") + b; }, /** * Returns an array of the names of all parameters in the given pattern. */ extractParamNames: function extractParamNames(pattern) { return compilePattern(pattern).paramNames; }, /** * Extracts the portions of the given URL path that match the given pattern * and returns an object of param name => value pairs. Returns null if the * pattern does not match the given path. */ extractParams: function extractParams(pattern, path) { var _compilePattern = compilePattern(pattern); var matcher = _compilePattern.matcher; var paramNames = _compilePattern.paramNames; var match = path.match(matcher); if (!match) { return null; }var params = {}; paramNames.forEach(function (paramName, index) { params[paramName] = match[index + 1]; }); return params; }, /** * Returns a version of the given route path with params interpolated. Throws * if there is a dynamic segment of the route path for which there is no param. */ injectParams: function injectParams(pattern, params) { params = params || {}; var splatIndex = 0; return pattern.replace(paramInjectMatcher, function (match, paramName) { paramName = paramName || "splat"; // If param is optional don't check for existence if (paramName.slice(-1) === "?") { paramName = paramName.slice(0, -1); if (params[paramName] == null) return ""; } else { invariant(params[paramName] != null, "Missing \"%s\" parameter for path \"%s\"", paramName, pattern); } var segment; if (paramName === "splat" && Array.isArray(params[paramName])) { segment = params[paramName][splatIndex++]; invariant(segment != null, "Missing splat # %s for path \"%s\"", splatIndex, pattern); } else { segment = params[paramName]; } return segment; }).replace(paramInjectTrailingSlashMatcher, "/"); }, /** * Returns an object that is the result of parsing any query string contained * in the given path, null if the path contains no query string. */ extractQuery: function extractQuery(path) { var match = path.match(queryMatcher); return match && qs.parse(match[1]); }, /** * Returns a version of the given path without the query string. */ withoutQuery: function withoutQuery(path) { return path.replace(queryMatcher, ""); }, /** * Returns a version of the given path with the parameters in the given * query merged into the query string. */ withQuery: function withQuery(path, query) { var existingQuery = PathUtils.extractQuery(path); if (existingQuery) query = query ? merge(existingQuery, query) : existingQuery; var queryString = qs.stringify(query, { indices: false }); if (queryString) { return PathUtils.withoutQuery(path) + "?" + queryString; }return path; } }; module.exports = PathUtils; },{"qs":38,"qs/lib/utils":42,"react/lib/invariant":182}],11:[function(require,module,exports){ "use strict"; var assign = require("react/lib/Object.assign"); var ReactPropTypes = require("react").PropTypes; var PropTypes = assign({ /** * Requires that the value of a prop be falsy. */ falsy: function falsy(props, propName, componentName) { if (props[propName]) { return new Error("<" + componentName + "> may not have a \"" + propName + "\" prop"); } } }, ReactPropTypes); module.exports = PropTypes; },{"react":"react","react/lib/Object.assign":70}],12:[function(require,module,exports){ "use strict"; /** * Encapsulates a redirect to the given route. */ function Redirect(to, params, query) { this.to = to; this.params = params; this.query = query; } module.exports = Redirect; },{}],13:[function(require,module,exports){ "use strict"; var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var assign = require("react/lib/Object.assign"); var invariant = require("react/lib/invariant"); var warning = require("react/lib/warning"); var PathUtils = require("./PathUtils"); var _currentRoute; var Route = (function () { function Route(name, path, ignoreScrollBehavior, isDefault, isNotFound, onEnter, onLeave, handler) { _classCallCheck(this, Route); this.name = name; this.path = path; this.paramNames = PathUtils.extractParamNames(this.path); this.ignoreScrollBehavior = !!ignoreScrollBehavior; this.isDefault = !!isDefault; this.isNotFound = !!isNotFound; this.onEnter = onEnter; this.onLeave = onLeave; this.handler = handler; } _prototypeProperties(Route, { createRoute: { /** * Creates and returns a new route. Options may be a URL pathname string * with placeholders for named params or an object with any of the following * properties: * * - name The name of the route. This is used to lookup a * route relative to its parent route and should be * unique among all child routes of the same parent * - path A URL pathname string with optional placeholders * that specify the names of params to extract from * the URL when the path matches. Defaults to `/${name}` * when there is a name given, or the path of the parent * route, or / * - ignoreScrollBehavior True to make this route (and all descendants) ignore * the scroll behavior of the router * - isDefault True to make this route the default route among all * its siblings * - isNotFound True to make this route the "not found" route among * all its siblings * - onEnter A transition hook that will be called when the * router is going to enter this route * - onLeave A transition hook that will be called when the * router is going to leave this route * - handler A React component that will be rendered when * this route is active * - parentRoute The parent route to use for this route. This option * is automatically supplied when creating routes inside * the callback to another invocation of createRoute. You * only ever need to use this when declaring routes * independently of one another to manually piece together * the route hierarchy * * The callback may be used to structure your route hierarchy. Any call to * createRoute, createDefaultRoute, createNotFoundRoute, or createRedirect * inside the callback automatically uses this route as its parent. */ value: function createRoute(options, callback) { options = options || {}; if (typeof options === "string") options = { path: options }; var parentRoute = _currentRoute; if (parentRoute) { warning(options.parentRoute == null || options.parentRoute === parentRoute, "You should not use parentRoute with createRoute inside another route's child callback; it is ignored"); } else { parentRoute = options.parentRoute; } var name = options.name; var path = options.path || name; if (path && !(options.isDefault || options.isNotFound)) { if (PathUtils.isAbsolute(path)) { if (parentRoute) { invariant(parentRoute.paramNames.length === 0, "You cannot nest path \"%s\" inside \"%s\"; the parent requires URL parameters", path, parentRoute.path); } } else if (parentRoute) { // Relative paths extend their parent. path = PathUtils.join(parentRoute.path, path); } else { path = "/" + path; } } else { path = parentRoute ? parentRoute.path : "/"; } if (options.isNotFound && !/\*$/.test(path)) path += "*"; // Auto-append * to the path of not found routes. var route = new Route(name, path, options.ignoreScrollBehavior, options.isDefault, options.isNotFound, options.onEnter, options.onLeave, options.handler); if (parentRoute) { if (route.isDefault) { invariant(parentRoute.defaultRoute == null, "%s may not have more than one default route", parentRoute); parentRoute.defaultRoute = route; } else if (route.isNotFound) { invariant(parentRoute.notFoundRoute == null, "%s may not have more than one not found route", parentRoute); parentRoute.notFoundRoute = route; } parentRoute.appendChild(route); } // Any routes created in the callback // use this route as their parent. if (typeof callback === "function") { var currentRoute = _currentRoute; _currentRoute = route; callback.call(route, route); _currentRoute = currentRoute; } return route; }, writable: true, configurable: true }, createDefaultRoute: { /** * Creates and returns a route that is rendered when its parent matches * the current URL. */ value: function createDefaultRoute(options) { return Route.createRoute(assign({}, options, { isDefault: true })); }, writable: true, configurable: true }, createNotFoundRoute: { /** * Creates and returns a route that is rendered when its parent matches * the current URL but none of its siblings do. */ value: function createNotFoundRoute(options) { return Route.createRoute(assign({}, options, { isNotFound: true })); }, writable: true, configurable: true }, createRedirect: { /** * Creates and returns a route that automatically redirects the transition * to another route. In addition to the normal options to createRoute, this * function accepts the following options: * * - from An alias for the `path` option. Defaults to * * - to The path/route/route name to redirect to * - params The params to use in the redirect URL. Defaults * to using the current params * - query The query to use in the redirect URL. Defaults * to using the current query */ value: function createRedirect(options) { return Route.createRoute(assign({}, options, { path: options.path || options.from || "*", onEnter: function onEnter(transition, params, query) { transition.redirect(options.to, options.params || params, options.query || query); } })); }, writable: true, configurable: true } }, { appendChild: { /** * Appends the given route to this route's child routes. */ value: function appendChild(route) { invariant(route instanceof Route, "route.appendChild must use a valid Route"); if (!this.childRoutes) this.childRoutes = []; this.childRoutes.push(route); }, writable: true, configurable: true }, toString: { value: function toString() { var string = ""; return string; }, writable: true, configurable: true } }); return Route; })(); module.exports = Route; },{"./PathUtils":10,"react/lib/Object.assign":70,"react/lib/invariant":182,"react/lib/warning":202}],14:[function(require,module,exports){ "use strict"; var React = require("react"); var assign = require("react/lib/Object.assign"); var PropTypes = require("./PropTypes"); var REF_NAME = "__routeHandler__"; var RouteHandlerMixin = { contextTypes: { getRouteAtDepth: PropTypes.func.isRequired, setRouteComponentAtDepth: PropTypes.func.isRequired, routeHandlers: PropTypes.array.isRequired }, childContextTypes: { routeHandlers: PropTypes.array.isRequired }, getChildContext: function getChildContext() { return { routeHandlers: this.context.routeHandlers.concat([this]) }; }, componentDidMount: function componentDidMount() { this._updateRouteComponent(this.refs[REF_NAME]); }, componentDidUpdate: function componentDidUpdate() { this._updateRouteComponent(this.refs[REF_NAME]); }, componentWillUnmount: function componentWillUnmount() { this._updateRouteComponent(null); }, _updateRouteComponent: function _updateRouteComponent(component) { this.context.setRouteComponentAtDepth(this.getRouteDepth(), component); }, getRouteDepth: function getRouteDepth() { return this.context.routeHandlers.length; }, createChildRouteHandler: function createChildRouteHandler(props) { var route = this.context.getRouteAtDepth(this.getRouteDepth()); return route ? React.createElement(route.handler, assign({}, props || this.props, { ref: REF_NAME })) : null; } }; module.exports = RouteHandlerMixin; },{"./PropTypes":11,"react":"react","react/lib/Object.assign":70}],15:[function(require,module,exports){ "use strict"; var invariant = require("react/lib/invariant"); var canUseDOM = require("react/lib/ExecutionEnvironment").canUseDOM; var getWindowScrollPosition = require("./getWindowScrollPosition"); function shouldUpdateScroll(state, prevState) { if (!prevState) { return true; } // Don't update scroll position when only the query has changed. if (state.pathname === prevState.pathname) { return false; }var routes = state.routes; var prevRoutes = prevState.routes; var sharedAncestorRoutes = routes.filter(function (route) { return prevRoutes.indexOf(route) !== -1; }); return !sharedAncestorRoutes.some(function (route) { return route.ignoreScrollBehavior; }); } /** * Provides the router with the ability to manage window scroll position * according to its scroll behavior. */ var ScrollHistory = { statics: { /** * Records curent scroll position as the last known position for the given URL path. */ recordScrollPosition: function recordScrollPosition(path) { if (!this.scrollHistory) this.scrollHistory = {}; this.scrollHistory[path] = getWindowScrollPosition(); }, /** * Returns the last known scroll position for the given URL path. */ getScrollPosition: function getScrollPosition(path) { if (!this.scrollHistory) this.scrollHistory = {}; return this.scrollHistory[path] || null; } }, componentWillMount: function componentWillMount() { invariant(this.constructor.getScrollBehavior() == null || canUseDOM, "Cannot use scroll behavior without a DOM"); }, componentDidMount: function componentDidMount() { this._updateScroll(); }, componentDidUpdate: function componentDidUpdate(prevProps, prevState) { this._updateScroll(prevState); }, _updateScroll: function _updateScroll(prevState) { if (!shouldUpdateScroll(this.state, prevState)) { return; }var scrollBehavior = this.constructor.getScrollBehavior(); if (scrollBehavior) scrollBehavior.updateScrollPosition(this.constructor.getScrollPosition(this.state.path), this.state.action); } }; module.exports = ScrollHistory; },{"./getWindowScrollPosition":30,"react/lib/ExecutionEnvironment":64,"react/lib/invariant":182}],16:[function(require,module,exports){ "use strict"; var PropTypes = require("./PropTypes"); /** * A mixin for components that need to know the path, routes, URL * params and query that are currently active. * * Example: * * var AboutLink = React.createClass({ * mixins: [ Router.State ], * render: function () { * var className = this.props.className; * * if (this.isActive('about')) * className += ' is-active'; * * return React.DOM.a({ className: className }, this.props.children); * } * }); */ var State = { contextTypes: { getCurrentPath: PropTypes.func.isRequired, getCurrentRoutes: PropTypes.func.isRequired, getCurrentPathname: PropTypes.func.isRequired, getCurrentParams: PropTypes.func.isRequired, getCurrentQuery: PropTypes.func.isRequired, isActive: PropTypes.func.isRequired }, /** * Returns the current URL path. */ getPath: function getPath() { return this.context.getCurrentPath(); }, /** * Returns an array of the routes that are currently active. */ getRoutes: function getRoutes() { return this.context.getCurrentRoutes(); }, /** * Returns the current URL path without the query string. */ getPathname: function getPathname() { return this.context.getCurrentPathname(); }, /** * Returns an object of the URL params that are currently active. */ getParams: function getParams() { return this.context.getCurrentParams(); }, /** * Returns an object of the query params that are currently active. */ getQuery: function getQuery() { return this.context.getCurrentQuery(); }, /** * A helper method to determine if a given route, params, and query * are active. */ isActive: function isActive(to, params, query) { return this.context.isActive(to, params, query); } }; module.exports = State; },{"./PropTypes":11}],17:[function(require,module,exports){ "use strict"; var assign = require("react/lib/Object.assign"); var PropTypes = require("./PropTypes"); var PathUtils = require("./PathUtils"); function routeIsActive(activeRoutes, routeName) { return activeRoutes.some(function (route) { return route.name === routeName; }); } function paramsAreActive(activeParams, params) { for (var property in params) if (String(activeParams[property]) !== String(params[property])) { return false; }return true; } function queryIsActive(activeQuery, query) { for (var property in query) if (String(activeQuery[property]) !== String(query[property])) { return false; }return true; } /** * Provides the router with context for Router.State. */ var StateContext = { /** * Returns the current URL path + query string. */ getCurrentPath: function getCurrentPath() { return this.state.path; }, /** * Returns a read-only array of the currently active routes. */ getCurrentRoutes: function getCurrentRoutes() { return this.state.routes.slice(0); }, /** * Returns the current URL path without the query string. */ getCurrentPathname: function getCurrentPathname() { return this.state.pathname; }, /** * Returns a read-only object of the currently active URL parameters. */ getCurrentParams: function getCurrentParams() { return assign({}, this.state.params); }, /** * Returns a read-only object of the currently active query parameters. */ getCurrentQuery: function getCurrentQuery() { return assign({}, this.state.query); }, /** * Returns true if the given route, params, and query are active. */ isActive: function isActive(to, params, query) { if (PathUtils.isAbsolute(to)) { return to === this.state.path; }return routeIsActive(this.state.routes, to) && paramsAreActive(this.state.params, params) && (query == null || queryIsActive(this.state.query, query)); }, childContextTypes: { getCurrentPath: PropTypes.func.isRequired, getCurrentRoutes: PropTypes.func.isRequired, getCurrentPathname: PropTypes.func.isRequired, getCurrentParams: PropTypes.func.isRequired, getCurrentQuery: PropTypes.func.isRequired, isActive: PropTypes.func.isRequired }, getChildContext: function getChildContext() { return { getCurrentPath: this.getCurrentPath, getCurrentRoutes: this.getCurrentRoutes, getCurrentPathname: this.getCurrentPathname, getCurrentParams: this.getCurrentParams, getCurrentQuery: this.getCurrentQuery, isActive: this.isActive }; } }; module.exports = StateContext; },{"./PathUtils":10,"./PropTypes":11,"react/lib/Object.assign":70}],18:[function(require,module,exports){ "use strict"; /* jshint -W058 */ var Cancellation = require("./Cancellation"); var Redirect = require("./Redirect"); /** * Encapsulates a transition to a given path. * * The willTransitionTo and willTransitionFrom handlers receive * an instance of this class as their first argument. */ function Transition(path, retry) { this.path = path; this.abortReason = null; // TODO: Change this to router.retryTransition(transition) this.retry = retry.bind(this); } Transition.prototype.abort = function (reason) { if (this.abortReason == null) this.abortReason = reason || "ABORT"; }; Transition.prototype.redirect = function (to, params, query) { this.abort(new Redirect(to, params, query)); }; Transition.prototype.cancel = function () { this.abort(new Cancellation()); }; Transition.from = function (transition, routes, components, callback) { routes.reduce(function (callback, route, index) { return function (error) { if (error || transition.abortReason) { callback(error); } else if (route.onLeave) { try { route.onLeave(transition, components[index], callback); // If there is no callback in the argument list, call it automatically. if (route.onLeave.length < 3) callback(); } catch (e) { callback(e); } } else { callback(); } }; }, callback)(); }; Transition.to = function (transition, routes, params, query, callback) { routes.reduceRight(function (callback, route) { return function (error) { if (error || transition.abortReason) { callback(error); } else if (route.onEnter) { try { route.onEnter(transition, params, query, callback); // If there is no callback in the argument list, call it automatically. if (route.onEnter.length < 4) callback(); } catch (e) { callback(e); } } else { callback(); } }; }, callback)(); }; module.exports = Transition; },{"./Cancellation":4,"./Redirect":12}],19:[function(require,module,exports){ "use strict"; /** * Actions that modify the URL. */ var LocationActions = { /** * Indicates a new location is being pushed to the history stack. */ PUSH: "push", /** * Indicates the current location should be replaced. */ REPLACE: "replace", /** * Indicates the most recent entry should be removed from the history stack. */ POP: "pop" }; module.exports = LocationActions; },{}],20:[function(require,module,exports){ "use strict"; var LocationActions = require("../actions/LocationActions"); /** * A scroll behavior that attempts to imitate the default behavior * of modern browsers. */ var ImitateBrowserBehavior = { updateScrollPosition: function updateScrollPosition(position, actionType) { switch (actionType) { case LocationActions.PUSH: case LocationActions.REPLACE: window.scrollTo(0, 0); break; case LocationActions.POP: if (position) { window.scrollTo(position.x, position.y); } else { window.scrollTo(0, 0); } break; } } }; module.exports = ImitateBrowserBehavior; },{"../actions/LocationActions":19}],21:[function(require,module,exports){ "use strict"; /** * A scroll behavior that always scrolls to the top of the page * after a transition. */ var ScrollToTopBehavior = { updateScrollPosition: function updateScrollPosition() { window.scrollTo(0, 0); } }; module.exports = ScrollToTopBehavior; },{}],22:[function(require,module,exports){ "use strict"; var React = require("react"); var Configuration = require("../Configuration"); var PropTypes = require("../PropTypes"); /** * A component is a special kind of that * renders when its parent matches but none of its siblings do. * Only one such route may be used at any given level in the * route hierarchy. */ var DefaultRoute = React.createClass({ displayName: "DefaultRoute", mixins: [Configuration], propTypes: { name: PropTypes.string, path: PropTypes.falsy, children: PropTypes.falsy, handler: PropTypes.func.isRequired } }); module.exports = DefaultRoute; },{"../Configuration":5,"../PropTypes":11,"react":"react"}],23:[function(require,module,exports){ "use strict"; var React = require("react"); var classSet = require("react/lib/cx"); var assign = require("react/lib/Object.assign"); var Navigation = require("../Navigation"); var State = require("../State"); var PropTypes = require("../PropTypes"); var Route = require("../Route"); function isLeftClickEvent(event) { return event.button === 0; } function isModifiedEvent(event) { return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); } /** * components are used to create an element that links to a route. * When that route is active, the link gets an "active" class name (or the * value of its `activeClassName` prop). * * For example, assuming you have the following route: * * * * You could use the following component to link to that route: * * * * In addition to params, links may pass along query string parameters * using the `query` prop. * * */ var Link = React.createClass({ displayName: "Link", mixins: [Navigation, State], propTypes: { activeClassName: PropTypes.string.isRequired, to: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Route)]), params: PropTypes.object, query: PropTypes.object, activeStyle: PropTypes.object, onClick: PropTypes.func }, getDefaultProps: function getDefaultProps() { return { activeClassName: "active" }; }, handleClick: function handleClick(event) { var allowTransition = true; var clickResult; if (this.props.onClick) clickResult = this.props.onClick(event); if (isModifiedEvent(event) || !isLeftClickEvent(event)) { return; }if (clickResult === false || event.defaultPrevented === true) allowTransition = false; event.preventDefault(); if (allowTransition) this.transitionTo(this.props.to, this.props.params, this.props.query); }, /** * Returns the value of the "href" attribute to use on the DOM element. */ getHref: function getHref() { return this.makeHref(this.props.to, this.props.params, this.props.query); }, /** * Returns the value of the "class" attribute to use on the DOM element, which contains * the value of the activeClassName property when this is active. */ getClassName: function getClassName() { var classNames = {}; if (this.props.className) classNames[this.props.className] = true; if (this.getActiveState()) classNames[this.props.activeClassName] = true; return classSet(classNames); }, getActiveState: function getActiveState() { return this.isActive(this.props.to, this.props.params, this.props.query); }, render: function render() { var props = assign({}, this.props, { href: this.getHref(), className: this.getClassName(), onClick: this.handleClick }); if (props.activeStyle && this.getActiveState()) props.style = props.activeStyle; return React.DOM.a(props, this.props.children); } }); module.exports = Link; },{"../Navigation":8,"../PropTypes":11,"../Route":13,"../State":16,"react":"react","react/lib/Object.assign":70,"react/lib/cx":160}],24:[function(require,module,exports){ "use strict"; var React = require("react"); var Configuration = require("../Configuration"); var PropTypes = require("../PropTypes"); /** * A is a special kind of that * renders when the beginning of its parent's path matches * but none of its siblings do, including any . * Only one such route may be used at any given level in the * route hierarchy. */ var NotFoundRoute = React.createClass({ displayName: "NotFoundRoute", mixins: [Configuration], propTypes: { name: PropTypes.string, path: PropTypes.falsy, children: PropTypes.falsy, handler: PropTypes.func.isRequired } }); module.exports = NotFoundRoute; },{"../Configuration":5,"../PropTypes":11,"react":"react"}],25:[function(require,module,exports){ "use strict"; var React = require("react"); var Configuration = require("../Configuration"); var PropTypes = require("../PropTypes"); /** * A component is a special kind of that always * redirects to another route when it matches. */ var Redirect = React.createClass({ displayName: "Redirect", mixins: [Configuration], propTypes: { path: PropTypes.string, from: PropTypes.string, // Alias for path. to: PropTypes.string, handler: PropTypes.falsy } }); module.exports = Redirect; },{"../Configuration":5,"../PropTypes":11,"react":"react"}],26:[function(require,module,exports){ "use strict"; var React = require("react"); var Configuration = require("../Configuration"); var PropTypes = require("../PropTypes"); var RouteHandler = require("./RouteHandler"); /** * components specify components that are rendered to the page when the * URL matches a given pattern. * * Routes are arranged in a nested tree structure. When a new URL is requested, * the tree is searched depth-first to find a route whose path matches the URL. * When one is found, all routes in the tree that lead to it are considered * "active" and their components are rendered into the DOM, nested in the same * order as they are in the tree. * * The preferred way to configure a router is using JSX. The XML-like syntax is * a great way to visualize how routes are laid out in an application. * * var routes = [ * * * * * * ]; * * Router.run(routes, function (Handler) { * React.render(, document.body); * }); * * Handlers for Route components that contain children can render their active * child route using a element. * * var App = React.createClass({ * render: function () { * return ( *
* *
* ); * } * }); * * If no handler is provided for the route, it will render a matched child route. */ var Route = React.createClass({ displayName: "Route", mixins: [Configuration], propTypes: { name: PropTypes.string, path: PropTypes.string, handler: PropTypes.func, ignoreScrollBehavior: PropTypes.bool }, getDefaultProps: function getDefaultProps() { return { handler: RouteHandler }; } }); module.exports = Route; },{"../Configuration":5,"../PropTypes":11,"./RouteHandler":27,"react":"react"}],27:[function(require,module,exports){ "use strict"; var React = require("react"); var RouteHandlerMixin = require("../RouteHandlerMixin"); /** * A component renders the active child route handler * when routes are nested. */ var RouteHandler = React.createClass({ displayName: "RouteHandler", mixins: [RouteHandlerMixin], render: function render() { return this.createChildRouteHandler(); } }); module.exports = RouteHandler; },{"../RouteHandlerMixin":14,"react":"react"}],28:[function(require,module,exports){ (function (process){ "use strict"; /* jshint -W058 */ var React = require("react"); var warning = require("react/lib/warning"); var invariant = require("react/lib/invariant"); var canUseDOM = require("react/lib/ExecutionEnvironment").canUseDOM; var LocationActions = require("./actions/LocationActions"); var ImitateBrowserBehavior = require("./behaviors/ImitateBrowserBehavior"); var HashLocation = require("./locations/HashLocation"); var HistoryLocation = require("./locations/HistoryLocation"); var RefreshLocation = require("./locations/RefreshLocation"); var StaticLocation = require("./locations/StaticLocation"); var NavigationContext = require("./NavigationContext"); var ScrollHistory = require("./ScrollHistory"); var StateContext = require("./StateContext"); var createRoutesFromReactChildren = require("./createRoutesFromReactChildren"); var isReactChildren = require("./isReactChildren"); var Transition = require("./Transition"); var PropTypes = require("./PropTypes"); var Redirect = require("./Redirect"); var History = require("./History"); var Cancellation = require("./Cancellation"); var Match = require("./Match"); var Route = require("./Route"); var supportsHistory = require("./supportsHistory"); var PathUtils = require("./PathUtils"); /** * The default location for new routers. */ var DEFAULT_LOCATION = canUseDOM ? HashLocation : "/"; /** * The default scroll behavior for new routers. */ var DEFAULT_SCROLL_BEHAVIOR = canUseDOM ? ImitateBrowserBehavior : null; function hasProperties(object, properties) { for (var propertyName in properties) if (properties.hasOwnProperty(propertyName) && object[propertyName] !== properties[propertyName]) { return false; }return true; } function hasMatch(routes, route, prevParams, nextParams, prevQuery, nextQuery) { return routes.some(function (r) { if (r !== route) return false; var paramNames = route.paramNames; var paramName; // Ensure that all params the route cares about did not change. for (var i = 0, len = paramNames.length; i < len; ++i) { paramName = paramNames[i]; if (nextParams[paramName] !== prevParams[paramName]) return false; } // Ensure the query hasn't changed. return hasProperties(prevQuery, nextQuery) && hasProperties(nextQuery, prevQuery); }); } function addRoutesToNamedRoutes(routes, namedRoutes) { var route; for (var i = 0, len = routes.length; i < len; ++i) { route = routes[i]; if (route.name) { invariant(namedRoutes[route.name] == null, "You may not have more than one route named \"%s\"", route.name); namedRoutes[route.name] = route; } if (route.childRoutes) addRoutesToNamedRoutes(route.childRoutes, namedRoutes); } } /** * Creates and returns a new router using the given options. A router * is a ReactComponent class that knows how to react to changes in the * URL and keep the contents of the page in sync. * * Options may be any of the following: * * - routes (required) The route config * - location The location to use. Defaults to HashLocation when * the DOM is available, "/" otherwise * - scrollBehavior The scroll behavior to use. Defaults to ImitateBrowserBehavior * when the DOM is available, null otherwise * - onError A function that is used to handle errors * - onAbort A function that is used to handle aborted transitions * * When rendering in a server-side environment, the location should simply * be the URL path that was used in the request, including the query string. */ function createRouter(options) { options = options || {}; if (isReactChildren(options)) options = { routes: options }; var mountedComponents = []; var location = options.location || DEFAULT_LOCATION; var scrollBehavior = options.scrollBehavior || DEFAULT_SCROLL_BEHAVIOR; var state = {}; var nextState = {}; var pendingTransition = null; var dispatchHandler = null; if (typeof location === "string") location = new StaticLocation(location); if (location instanceof StaticLocation) { warning(!canUseDOM || process.env.NODE_ENV === "test", "You should not use a static location in a DOM environment because " + "the router will not be kept in sync with the current URL"); } else { invariant(canUseDOM || location.needsDOM === false, "You cannot use %s without a DOM", location); } // Automatically fall back to full page refreshes in // browsers that don't support the HTML history API. if (location === HistoryLocation && !supportsHistory()) location = RefreshLocation; var Router = React.createClass({ displayName: "Router", statics: { isRunning: false, cancelPendingTransition: function cancelPendingTransition() { if (pendingTransition) { pendingTransition.cancel(); pendingTransition = null; } }, clearAllRoutes: function clearAllRoutes() { this.cancelPendingTransition(); this.namedRoutes = {}; this.routes = []; }, /** * Adds routes to this router from the given children object (see ReactChildren). */ addRoutes: function addRoutes(routes) { if (isReactChildren(routes)) routes = createRoutesFromReactChildren(routes); addRoutesToNamedRoutes(routes, this.namedRoutes); this.routes.push.apply(this.routes, routes); }, /** * Replaces routes of this router from the given children object (see ReactChildren). */ replaceRoutes: function replaceRoutes(routes) { this.clearAllRoutes(); this.addRoutes(routes); this.refresh(); }, /** * Performs a match of the given path against this router and returns an object * with the { routes, params, pathname, query } that match. Returns null if no * match can be made. */ match: function match(path) { return Match.findMatch(this.routes, path); }, /** * Returns an absolute URL path created from the given route * name, URL parameters, and query. */ makePath: function makePath(to, params, query) { var path; if (PathUtils.isAbsolute(to)) { path = to; } else { var route = to instanceof Route ? to : this.namedRoutes[to]; invariant(route instanceof Route, "Cannot find a route named \"%s\"", to); path = route.path; } return PathUtils.withQuery(PathUtils.injectParams(path, params), query); }, /** * Returns a string that may safely be used as the href of a link * to the route with the given name, URL parameters, and query. */ makeHref: function makeHref(to, params, query) { var path = this.makePath(to, params, query); return location === HashLocation ? "#" + path : path; }, /** * Transitions to the URL specified in the arguments by pushing * a new URL onto the history stack. */ transitionTo: function transitionTo(to, params, query) { var path = this.makePath(to, params, query); if (pendingTransition) { // Replace so pending location does not stay in history. location.replace(path); } else { location.push(path); } }, /** * Transitions to the URL specified in the arguments by replacing * the current URL in the history stack. */ replaceWith: function replaceWith(to, params, query) { location.replace(this.makePath(to, params, query)); }, /** * Transitions to the previous URL if one is available. Returns true if the * router was able to go back, false otherwise. * * Note: The router only tracks history entries in your application, not the * current browser session, so you can safely call this function without guarding * against sending the user back to some other site. However, when using * RefreshLocation (which is the fallback for HistoryLocation in browsers that * don't support HTML5 history) this method will *always* send the client back * because we cannot reliably track history length. */ goBack: function goBack() { if (History.length > 1 || location === RefreshLocation) { location.pop(); return true; } warning(false, "goBack() was ignored because there is no router history"); return false; }, handleAbort: options.onAbort || function (abortReason) { if (location instanceof StaticLocation) throw new Error("Unhandled aborted transition! Reason: " + abortReason); if (abortReason instanceof Cancellation) { return; } else if (abortReason instanceof Redirect) { location.replace(this.makePath(abortReason.to, abortReason.params, abortReason.query)); } else { location.pop(); } }, handleError: options.onError || function (error) { // Throw so we don't silently swallow async errors. throw error; // This error probably originated in a transition hook. }, handleLocationChange: function handleLocationChange(change) { this.dispatch(change.path, change.type); }, /** * Performs a transition to the given path and calls callback(error, abortReason) * when the transition is finished. If both arguments are null the router's state * was updated. Otherwise the transition did not complete. * * In a transition, a router first determines which routes are involved by beginning * with the current route, up the route tree to the first parent route that is shared * with the destination route, and back down the tree to the destination route. The * willTransitionFrom hook is invoked on all route handlers we're transitioning away * from, in reverse nesting order. Likewise, the willTransitionTo hook is invoked on * all route handlers we're transitioning to. * * Both willTransitionFrom and willTransitionTo hooks may either abort or redirect the * transition. To resolve asynchronously, they may use the callback argument. If no * hooks wait, the transition is fully synchronous. */ dispatch: function dispatch(path, action) { this.cancelPendingTransition(); var prevPath = state.path; var isRefreshing = action == null; if (prevPath === path && !isRefreshing) { return; } // Nothing to do! // Record the scroll position as early as possible to // get it before browsers try update it automatically. if (prevPath && action === LocationActions.PUSH) this.recordScrollPosition(prevPath); var match = this.match(path); warning(match != null, "No route matches path \"%s\". Make sure you have somewhere in your routes", path, path); if (match == null) match = {}; var prevRoutes = state.routes || []; var prevParams = state.params || {}; var prevQuery = state.query || {}; var nextRoutes = match.routes || []; var nextParams = match.params || {}; var nextQuery = match.query || {}; var fromRoutes, toRoutes; if (prevRoutes.length) { fromRoutes = prevRoutes.filter(function (route) { return !hasMatch(nextRoutes, route, prevParams, nextParams, prevQuery, nextQuery); }); toRoutes = nextRoutes.filter(function (route) { return !hasMatch(prevRoutes, route, prevParams, nextParams, prevQuery, nextQuery); }); } else { fromRoutes = []; toRoutes = nextRoutes; } var transition = new Transition(path, this.replaceWith.bind(this, path)); pendingTransition = transition; var fromComponents = mountedComponents.slice(prevRoutes.length - fromRoutes.length); Transition.from(transition, fromRoutes, fromComponents, function (error) { if (error || transition.abortReason) return dispatchHandler.call(Router, error, transition); // No need to continue. Transition.to(transition, toRoutes, nextParams, nextQuery, function (error) { dispatchHandler.call(Router, error, transition, { path: path, action: action, pathname: match.pathname, routes: nextRoutes, params: nextParams, query: nextQuery }); }); }); }, /** * Starts this router and calls callback(router, state) when the route changes. * * If the router's location is static (i.e. a URL path in a server environment) * the callback is called only once. Otherwise, the location should be one of the * Router.*Location objects (e.g. Router.HashLocation or Router.HistoryLocation). */ run: function run(callback) { invariant(!this.isRunning, "Router is already running"); dispatchHandler = function (error, transition, newState) { if (error) Router.handleError(error); if (pendingTransition !== transition) return; pendingTransition = null; if (transition.abortReason) { Router.handleAbort(transition.abortReason); } else { callback.call(this, this, nextState = newState); } }; if (!(location instanceof StaticLocation)) { if (location.addChangeListener) location.addChangeListener(Router.handleLocationChange); this.isRunning = true; } // Bootstrap using the current path. this.refresh(); }, refresh: function refresh() { Router.dispatch(location.getCurrentPath(), null); }, stop: function stop() { this.cancelPendingTransition(); if (location.removeChangeListener) location.removeChangeListener(Router.handleLocationChange); this.isRunning = false; }, getScrollBehavior: function getScrollBehavior() { return scrollBehavior; } }, mixins: [NavigationContext, StateContext, ScrollHistory], propTypes: { children: PropTypes.falsy }, childContextTypes: { getRouteAtDepth: React.PropTypes.func.isRequired, setRouteComponentAtDepth: React.PropTypes.func.isRequired, routeHandlers: React.PropTypes.array.isRequired }, getChildContext: function getChildContext() { return { getRouteAtDepth: this.getRouteAtDepth, setRouteComponentAtDepth: this.setRouteComponentAtDepth, routeHandlers: [this] }; }, getInitialState: function getInitialState() { return state = nextState; }, componentWillReceiveProps: function componentWillReceiveProps() { this.setState(state = nextState); }, componentWillUnmount: function componentWillUnmount() { Router.stop(); }, getLocation: function getLocation() { return location; }, getRouteAtDepth: function getRouteAtDepth(depth) { var routes = this.state.routes; return routes && routes[depth]; }, setRouteComponentAtDepth: function setRouteComponentAtDepth(depth, component) { mountedComponents[depth] = component; }, render: function render() { var route = this.getRouteAtDepth(0); return route ? React.createElement(route.handler, this.props) : null; } }); Router.clearAllRoutes(); if (options.routes) Router.addRoutes(options.routes); return Router; } module.exports = createRouter; }).call(this,require('_process')) },{"./Cancellation":4,"./History":6,"./Match":7,"./NavigationContext":9,"./PathUtils":10,"./PropTypes":11,"./Redirect":12,"./Route":13,"./ScrollHistory":15,"./StateContext":17,"./Transition":18,"./actions/LocationActions":19,"./behaviors/ImitateBrowserBehavior":20,"./createRoutesFromReactChildren":29,"./isReactChildren":31,"./locations/HashLocation":32,"./locations/HistoryLocation":33,"./locations/RefreshLocation":34,"./locations/StaticLocation":35,"./supportsHistory":37,"_process":1,"react":"react","react/lib/ExecutionEnvironment":64,"react/lib/invariant":182,"react/lib/warning":202}],29:[function(require,module,exports){ "use strict"; /* jshint -W084 */ var React = require("react"); var assign = require("react/lib/Object.assign"); var warning = require("react/lib/warning"); var DefaultRouteType = require("./components/DefaultRoute").type; var NotFoundRouteType = require("./components/NotFoundRoute").type; var RedirectType = require("./components/Redirect").type; var Route = require("./Route"); function checkPropTypes(componentName, propTypes, props) { componentName = componentName || "UnknownComponent"; for (var propName in propTypes) { if (propTypes.hasOwnProperty(propName)) { var error = propTypes[propName](props, propName, componentName); if (error instanceof Error) warning(false, error.message); } } } function createRouteOptions(props) { var options = assign({}, props); var handler = options.handler; if (handler) { options.onEnter = handler.willTransitionTo; options.onLeave = handler.willTransitionFrom; } return options; } function createRouteFromReactElement(element) { if (!React.isValidElement(element)) { return; }var type = element.type; var props = element.props; if (type.propTypes) checkPropTypes(type.displayName, type.propTypes, props); if (type === DefaultRouteType) { return Route.createDefaultRoute(createRouteOptions(props)); }if (type === NotFoundRouteType) { return Route.createNotFoundRoute(createRouteOptions(props)); }if (type === RedirectType) { return Route.createRedirect(createRouteOptions(props)); }return Route.createRoute(createRouteOptions(props), function () { if (props.children) createRoutesFromReactChildren(props.children); }); } /** * Creates and returns an array of routes created from the given * ReactChildren, all of which should be one of , , * , or , e.g.: * * var { createRoutesFromReactChildren, Route, Redirect } = require('react-router'); * * var routes = createRoutesFromReactChildren( * * * * * * * ); */ function createRoutesFromReactChildren(children) { var routes = []; React.Children.forEach(children, function (child) { if (child = createRouteFromReactElement(child)) routes.push(child); }); return routes; } module.exports = createRoutesFromReactChildren; },{"./Route":13,"./components/DefaultRoute":22,"./components/NotFoundRoute":24,"./components/Redirect":25,"react":"react","react/lib/Object.assign":70,"react/lib/warning":202}],30:[function(require,module,exports){ "use strict"; var invariant = require("react/lib/invariant"); var canUseDOM = require("react/lib/ExecutionEnvironment").canUseDOM; /** * Returns the current scroll position of the window as { x, y }. */ function getWindowScrollPosition() { invariant(canUseDOM, "Cannot get current scroll position without a DOM"); return { x: window.pageXOffset || document.documentElement.scrollLeft, y: window.pageYOffset || document.documentElement.scrollTop }; } module.exports = getWindowScrollPosition; },{"react/lib/ExecutionEnvironment":64,"react/lib/invariant":182}],31:[function(require,module,exports){ "use strict"; var React = require("react"); function isValidChild(object) { return object == null || React.isValidElement(object); } function isReactChildren(object) { return isValidChild(object) || Array.isArray(object) && object.every(isValidChild); } module.exports = isReactChildren; },{"react":"react"}],32:[function(require,module,exports){ "use strict"; var LocationActions = require("../actions/LocationActions"); var History = require("../History"); /** * Returns the current URL path from the `hash` portion of the URL, including * query string. */ function getHashPath() { return decodeURI( // We can't use window.location.hash here because it's not // consistent across browsers - Firefox will pre-decode it! window.location.href.split("#")[1] || ""); } var _actionType; function ensureSlash() { var path = getHashPath(); if (path.charAt(0) === "/") { return true; }HashLocation.replace("/" + path); return false; } var _changeListeners = []; function notifyChange(type) { if (type === LocationActions.PUSH) History.length += 1; var change = { path: getHashPath(), type: type }; _changeListeners.forEach(function (listener) { listener(change); }); } var _isListening = false; function onHashChange() { if (ensureSlash()) { // If we don't have an _actionType then all we know is the hash // changed. It was probably caused by the user clicking the Back // button, but may have also been the Forward button or manual // manipulation. So just guess 'pop'. notifyChange(_actionType || LocationActions.POP); _actionType = null; } } /** * A Location that uses `window.location.hash`. */ var HashLocation = { addChangeListener: function addChangeListener(listener) { _changeListeners.push(listener); // Do this BEFORE listening for hashchange. ensureSlash(); if (!_isListening) { if (window.addEventListener) { window.addEventListener("hashchange", onHashChange, false); } else { window.attachEvent("onhashchange", onHashChange); } _isListening = true; } }, removeChangeListener: function removeChangeListener(listener) { _changeListeners = _changeListeners.filter(function (l) { return l !== listener; }); if (_changeListeners.length === 0) { if (window.removeEventListener) { window.removeEventListener("hashchange", onHashChange, false); } else { window.removeEvent("onhashchange", onHashChange); } _isListening = false; } }, push: function push(path) { _actionType = LocationActions.PUSH; window.location.hash = path; }, replace: function replace(path) { _actionType = LocationActions.REPLACE; window.location.replace(window.location.pathname + window.location.search + "#" + path); }, pop: function pop() { _actionType = LocationActions.POP; History.back(); }, getCurrentPath: getHashPath, toString: function toString() { return ""; } }; module.exports = HashLocation; },{"../History":6,"../actions/LocationActions":19}],33:[function(require,module,exports){ "use strict"; var LocationActions = require("../actions/LocationActions"); var History = require("../History"); /** * Returns the current URL path from `window.location`, including query string. */ function getWindowPath() { return decodeURI(window.location.pathname + window.location.search); } var _changeListeners = []; function notifyChange(type) { var change = { path: getWindowPath(), type: type }; _changeListeners.forEach(function (listener) { listener(change); }); } var _isListening = false; function onPopState(event) { if (event.state === undefined) { return; } // Ignore extraneous popstate events in WebKit. notifyChange(LocationActions.POP); } /** * A Location that uses HTML5 history. */ var HistoryLocation = { addChangeListener: function addChangeListener(listener) { _changeListeners.push(listener); if (!_isListening) { if (window.addEventListener) { window.addEventListener("popstate", onPopState, false); } else { window.attachEvent("onpopstate", onPopState); } _isListening = true; } }, removeChangeListener: function removeChangeListener(listener) { _changeListeners = _changeListeners.filter(function (l) { return l !== listener; }); if (_changeListeners.length === 0) { if (window.addEventListener) { window.removeEventListener("popstate", onPopState, false); } else { window.removeEvent("onpopstate", onPopState); } _isListening = false; } }, push: function push(path) { window.history.pushState({ path: path }, "", path); History.length += 1; notifyChange(LocationActions.PUSH); }, replace: function replace(path) { window.history.replaceState({ path: path }, "", path); notifyChange(LocationActions.REPLACE); }, pop: History.back, getCurrentPath: getWindowPath, toString: function toString() { return ""; } }; module.exports = HistoryLocation; },{"../History":6,"../actions/LocationActions":19}],34:[function(require,module,exports){ "use strict"; var HistoryLocation = require("./HistoryLocation"); var History = require("../History"); /** * A Location that uses full page refreshes. This is used as * the fallback for HistoryLocation in browsers that do not * support the HTML5 history API. */ var RefreshLocation = { push: function push(path) { window.location = path; }, replace: function replace(path) { window.location.replace(path); }, pop: History.back, getCurrentPath: HistoryLocation.getCurrentPath, toString: function toString() { return ""; } }; module.exports = RefreshLocation; },{"../History":6,"./HistoryLocation":33}],35:[function(require,module,exports){ "use strict"; var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var invariant = require("react/lib/invariant"); function throwCannotModify() { invariant(false, "You cannot modify a static location"); } /** * A location that only ever contains a single path. Useful in * stateless environments like servers where there is no path history, * only the path that was used in the request. */ var StaticLocation = (function () { function StaticLocation(path) { _classCallCheck(this, StaticLocation); this.path = path; } _prototypeProperties(StaticLocation, null, { getCurrentPath: { value: function getCurrentPath() { return this.path; }, writable: true, configurable: true }, toString: { value: function toString() { return ""; }, writable: true, configurable: true } }); return StaticLocation; })(); // TODO: Include these in the above class definition // once we can use ES7 property initializers. StaticLocation.prototype.push = throwCannotModify; StaticLocation.prototype.replace = throwCannotModify; StaticLocation.prototype.pop = throwCannotModify; module.exports = StaticLocation; },{"react/lib/invariant":182}],36:[function(require,module,exports){ "use strict"; var createRouter = require("./createRouter"); /** * A high-level convenience method that creates, configures, and * runs a router in one shot. The method signature is: * * Router.run(routes[, location ], callback); * * Using `window.location.hash` to manage the URL, you could do: * * Router.run(routes, function (Handler) { * React.render(, document.body); * }); * * Using HTML5 history and a custom "cursor" prop: * * Router.run(routes, Router.HistoryLocation, function (Handler) { * React.render(, document.body); * }); * * Returns the newly created router. * * Note: If you need to specify further options for your router such * as error/abort handling or custom scroll behavior, use Router.create * instead. * * var router = Router.create(options); * router.run(function (Handler) { * // ... * }); */ function runRouter(routes, location, callback) { if (typeof location === "function") { callback = location; location = null; } var router = createRouter({ routes: routes, location: location }); router.run(callback); return router; } module.exports = runRouter; },{"./createRouter":28}],37:[function(require,module,exports){ "use strict"; function supportsHistory() { /*! taken from modernizr * https://github.com/Modernizr/Modernizr/blob/master/LICENSE * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586 */ var ua = navigator.userAgent; if ((ua.indexOf("Android 2.") !== -1 || ua.indexOf("Android 4.0") !== -1) && ua.indexOf("Mobile Safari") !== -1 && ua.indexOf("Chrome") === -1 && ua.indexOf("Windows Phone") === -1) { return false; } return window.history && "pushState" in window.history; } module.exports = supportsHistory; },{}],38:[function(require,module,exports){ module.exports = require('./lib/'); },{"./lib/":39}],39:[function(require,module,exports){ // Load modules var Stringify = require('./stringify'); var Parse = require('./parse'); // Declare internals var internals = {}; module.exports = { stringify: Stringify, parse: Parse }; },{"./parse":40,"./stringify":41}],40:[function(require,module,exports){ // Load modules var Utils = require('./utils'); // Declare internals var internals = { delimiter: '&', depth: 5, arrayLimit: 20, parameterLimit: 1000 }; internals.parseValues = function (str, options) { var obj = {}; var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); for (var i = 0, il = parts.length; i < il; ++i) { var part = parts[i]; var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; if (pos === -1) { obj[Utils.decode(part)] = ''; } else { var key = Utils.decode(part.slice(0, pos)); var val = Utils.decode(part.slice(pos + 1)); if (!obj.hasOwnProperty(key)) { obj[key] = val; } else { obj[key] = [].concat(obj[key]).concat(val); } } } return obj; }; internals.parseObject = function (chain, val, options) { if (!chain.length) { return val; } var root = chain.shift(); var obj = {}; if (root === '[]') { obj = []; obj = obj.concat(internals.parseObject(chain, val, options)); } else { var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; var index = parseInt(cleanRoot, 10); var indexString = '' + index; if (!isNaN(index) && root !== cleanRoot && indexString === cleanRoot && index >= 0 && index <= options.arrayLimit) { obj = []; obj[index] = internals.parseObject(chain, val, options); } else { obj[cleanRoot] = internals.parseObject(chain, val, options); } } return obj; }; internals.parseKeys = function (key, val, options) { if (!key) { return; } // The regex chunks var parent = /^([^\[\]]*)/; var child = /(\[[^\[\]]*\])/g; // Get the parent var segment = parent.exec(key); // Don't allow them to overwrite object prototype properties if (Object.prototype.hasOwnProperty(segment[1])) { return; } // Stash the parent if it exists var keys = []; if (segment[1]) { keys.push(segment[1]); } // Loop through children appending to the array until we hit depth var i = 0; while ((segment = child.exec(key)) !== null && i < options.depth) { ++i; if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { keys.push(segment[1]); } } // If there's a remainder, just add whatever is left if (segment) { keys.push('[' + key.slice(segment.index) + ']'); } return internals.parseObject(keys, val, options); }; module.exports = function (str, options) { if (str === '' || str === null || typeof str === 'undefined') { return {}; } options = options || {}; options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter; options.depth = typeof options.depth === 'number' ? options.depth : internals.depth; options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit; options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit; var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; var obj = {}; // Iterate over the keys and setup the new object var keys = Object.keys(tempObj); for (var i = 0, il = keys.length; i < il; ++i) { var key = keys[i]; var newObj = internals.parseKeys(key, tempObj[key], options); obj = Utils.merge(obj, newObj); } return Utils.compact(obj); }; },{"./utils":42}],41:[function(require,module,exports){ // Load modules var Utils = require('./utils'); // Declare internals var internals = { delimiter: '&', indices: true }; internals.stringify = function (obj, prefix, options) { if (Utils.isBuffer(obj)) { obj = obj.toString(); } else if (obj instanceof Date) { obj = obj.toISOString(); } else if (obj === null) { obj = ''; } if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean') { return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; } var values = []; if (typeof obj === 'undefined') { return values; } var objKeys = Object.keys(obj); for (var i = 0, il = objKeys.length; i < il; ++i) { var key = objKeys[i]; if (!options.indices && Array.isArray(obj)) { values = values.concat(internals.stringify(obj[key], prefix, options)); } else { values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', options)); } } return values; }; module.exports = function (obj, options) { options = options || {}; var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; options.indices = typeof options.indices === 'boolean' ? options.indices : internals.indices; var keys = []; if (typeof obj !== 'object' || obj === null) { return ''; } var objKeys = Object.keys(obj); for (var i = 0, il = objKeys.length; i < il; ++i) { var key = objKeys[i]; keys = keys.concat(internals.stringify(obj[key], key, options)); } return keys.join(delimiter); }; },{"./utils":42}],42:[function(require,module,exports){ // Load modules // Declare internals var internals = {}; exports.arrayToObject = function (source) { var obj = {}; for (var i = 0, il = source.length; i < il; ++i) { if (typeof source[i] !== 'undefined') { obj[i] = source[i]; } } return obj; }; exports.merge = function (target, source) { if (!source) { return target; } if (typeof source !== 'object') { if (Array.isArray(target)) { target.push(source); } else { target[source] = true; } return target; } if (typeof target !== 'object') { target = [target].concat(source); return target; } if (Array.isArray(target) && !Array.isArray(source)) { target = exports.arrayToObject(target); } var keys = Object.keys(source); for (var k = 0, kl = keys.length; k < kl; ++k) { var key = keys[k]; var value = source[key]; if (!target[key]) { target[key] = value; } else { target[key] = exports.merge(target[key], value); } } return target; }; exports.decode = function (str) { try { return decodeURIComponent(str.replace(/\+/g, ' ')); } catch (e) { return str; } }; exports.compact = function (obj, refs) { if (typeof obj !== 'object' || obj === null) { return obj; } refs = refs || []; var lookup = refs.indexOf(obj); if (lookup !== -1) { return refs[lookup]; } refs.push(obj); if (Array.isArray(obj)) { var compacted = []; for (var i = 0, il = obj.length; i < il; ++i) { if (typeof obj[i] !== 'undefined') { compacted.push(obj[i]); } } return compacted; } var keys = Object.keys(obj); for (i = 0, il = keys.length; i < il; ++i) { var key = keys[i]; obj[key] = exports.compact(obj[key], refs); } return obj; }; exports.isRegExp = function (obj) { return Object.prototype.toString.call(obj) === '[object RegExp]'; }; exports.isBuffer = function (obj) { if (obj === null || typeof obj === 'undefined') { return false; } return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); }; },{}],43:[function(require,module,exports){ /** * Copyright 2013-2014, 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. * * @providesModule AutoFocusMixin * @typechecks static-only */ "use strict"; var focusNode = require("./focusNode"); var AutoFocusMixin = { componentDidMount: function() { if (this.props.autoFocus) { focusNode(this.getDOMNode()); } } }; module.exports = AutoFocusMixin; },{"./focusNode":167}],44:[function(require,module,exports){ /** * Copyright 2013 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. * * @providesModule BeforeInputEventPlugin * @typechecks static-only */ "use strict"; var EventConstants = require("./EventConstants"); var EventPropagators = require("./EventPropagators"); var ExecutionEnvironment = require("./ExecutionEnvironment"); var SyntheticInputEvent = require("./SyntheticInputEvent"); var keyOf = require("./keyOf"); var canUseTextInputEvent = ( ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !('documentMode' in document || isPresto()) ); /** * Opera <= 12 includes TextEvent in window, but does not fire * text input events. Rely on keypress instead. */ function isPresto() { var opera = window.opera; return ( typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12 ); } var SPACEBAR_CODE = 32; var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); var topLevelTypes = EventConstants.topLevelTypes; // Events and their corresponding property names. var eventTypes = { beforeInput: { phasedRegistrationNames: { bubbled: keyOf({onBeforeInput: null}), captured: keyOf({onBeforeInputCapture: null}) }, dependencies: [ topLevelTypes.topCompositionEnd, topLevelTypes.topKeyPress, topLevelTypes.topTextInput, topLevelTypes.topPaste ] } }; // Track characters inserted via keypress and composition events. var fallbackChars = null; // Track whether we've ever handled a keypress on the space key. var hasSpaceKeypress = false; /** * Return whether a native keypress event is assumed to be a command. * This is required because Firefox fires `keypress` events for key commands * (cut, copy, select-all, etc.) even though no character is inserted. */ function isKeypressCommand(nativeEvent) { return ( (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command. !(nativeEvent.ctrlKey && nativeEvent.altKey) ); } /** * Create an `onBeforeInput` event to match * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. * * This event plugin is based on the native `textInput` event * available in Chrome, Safari, Opera, and IE. This event fires after * `onKeyPress` and `onCompositionEnd`, but before `onInput`. * * `beforeInput` is spec'd but not implemented in any browsers, and * the `input` event does not provide any useful information about what has * actually been added, contrary to the spec. Thus, `textInput` is the best * available event to identify the characters that have actually been inserted * into the target node. */ var BeforeInputEventPlugin = { eventTypes: eventTypes, /** * @param {string} topLevelType Record from `EventConstants`. * @param {DOMEventTarget} topLevelTarget The listening component root node. * @param {string} topLevelTargetID ID of `topLevelTarget`. * @param {object} nativeEvent Native browser event. * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ extractEvents: function( topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) { var chars; if (canUseTextInputEvent) { switch (topLevelType) { case topLevelTypes.topKeyPress: /** * If native `textInput` events are available, our goal is to make * use of them. However, there is a special case: the spacebar key. * In Webkit, preventing default on a spacebar `textInput` event * cancels character insertion, but it *also* causes the browser * to fall back to its default spacebar behavior of scrolling the * page. * * Tracking at: * https://code.google.com/p/chromium/issues/detail?id=355103 * * To avoid this issue, use the keypress event as if no `textInput` * event is available. */ var which = nativeEvent.which; if (which !== SPACEBAR_CODE) { return; } hasSpaceKeypress = true; chars = SPACEBAR_CHAR; break; case topLevelTypes.topTextInput: // Record the characters to be added to the DOM. chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled // it at the keypress level and bail immediately. Android Chrome // doesn't give us keycodes, so we need to blacklist it. if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { return; } // Otherwise, carry on. break; default: // For other native event types, do nothing. return; } } else { switch (topLevelType) { case topLevelTypes.topPaste: // If a paste event occurs after a keypress, throw out the input // chars. Paste events should not lead to BeforeInput events. fallbackChars = null; break; case topLevelTypes.topKeyPress: /** * As of v27, Firefox may fire keypress events even when no character * will be inserted. A few possibilities: * * - `which` is `0`. Arrow keys, Esc key, etc. * * - `which` is the pressed key code, but no char is available. * Ex: 'AltGr + d` in Polish. There is no modified character for * this key combination and no character is inserted into the * document, but FF fires the keypress for char code `100` anyway. * No `input` event will occur. * * - `which` is the pressed key code, but a command combination is * being used. Ex: `Cmd+C`. No character is inserted, and no * `input` event will occur. */ if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { fallbackChars = String.fromCharCode(nativeEvent.which); } break; case topLevelTypes.topCompositionEnd: fallbackChars = nativeEvent.data; break; } // If no changes have occurred to the fallback string, no relevant // event has fired and we're done. if (fallbackChars === null) { return; } chars = fallbackChars; } // If no characters are being inserted, no BeforeInput event should // be fired. if (!chars) { return; } var event = SyntheticInputEvent.getPooled( eventTypes.beforeInput, topLevelTargetID, nativeEvent ); event.data = chars; fallbackChars = null; EventPropagators.accumulateTwoPhaseDispatches(event); return event; } }; module.exports = BeforeInputEventPlugin; },{"./EventConstants":58,"./EventPropagators":63,"./ExecutionEnvironment":64,"./SyntheticInputEvent":143,"./keyOf":189}],45:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, 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. * * @providesModule CSSCore * @typechecks */ var invariant = require("./invariant"); /** * The CSSCore module specifies the API (and implements most of the methods) * that should be used when dealing with the display of elements (via their * CSS classes and visibility on screen. It is an API focused on mutating the * display and not reading it as no logical state should be encoded in the * display of elements. */ var CSSCore = { /** * Adds the class passed in to the element if it doesn't already have it. * * @param {DOMElement} element the element to set the class on * @param {string} className the CSS className * @return {DOMElement} the element passed in */ addClass: function(element, className) { ("production" !== process.env.NODE_ENV ? invariant( !/\s/.test(className), 'CSSCore.addClass takes only a single class name. "%s" contains ' + 'multiple classes.', className ) : invariant(!/\s/.test(className))); if (className) { if (element.classList) { element.classList.add(className); } else if (!CSSCore.hasClass(element, className)) { element.className = element.className + ' ' + className; } } return element; }, /** * Removes the class passed in from the element * * @param {DOMElement} element the element to set the class on * @param {string} className the CSS className * @return {DOMElement} the element passed in */ removeClass: function(element, className) { ("production" !== process.env.NODE_ENV ? invariant( !/\s/.test(className), 'CSSCore.removeClass takes only a single class name. "%s" contains ' + 'multiple classes.', className ) : invariant(!/\s/.test(className))); if (className) { if (element.classList) { element.classList.remove(className); } else if (CSSCore.hasClass(element, className)) { element.className = element.className .replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), '$1') .replace(/\s+/g, ' ') // multiple spaces to one .replace(/^\s*|\s*$/g, ''); // trim the ends } } return element; }, /** * Helper to add or remove a class from an element based on a condition. * * @param {DOMElement} element the element to set the class on * @param {string} className the CSS className * @param {*} bool condition to whether to add or remove the class * @return {DOMElement} the element passed in */ conditionClass: function(element, className, bool) { return (bool ? CSSCore.addClass : CSSCore.removeClass)(element, className); }, /** * Tests whether the element has the class specified. * * @param {DOMNode|DOMWindow} element the element to set the class on * @param {string} className the CSS className * @return {boolean} true if the element has the class, false if not */ hasClass: function(element, className) { ("production" !== process.env.NODE_ENV ? invariant( !/\s/.test(className), 'CSS.hasClass takes only a single class name.' ) : invariant(!/\s/.test(className))); if (element.classList) { return !!className && element.classList.contains(className); } return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1; } }; module.exports = CSSCore; }).call(this,require('_process')) },{"./invariant":182,"_process":1}],46:[function(require,module,exports){ /** * Copyright 2013-2014, 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. * * @providesModule CSSProperty */ "use strict"; /** * CSS properties which accept numbers but are not in units of "px". */ var isUnitlessNumber = { columnCount: true, fillOpacity: true, flex: true, flexGrow: true, flexShrink: true, fontWeight: true, lineClamp: true, lineHeight: true, opacity: true, order: true, orphans: true, widows: true, zIndex: true, zoom: true }; /** * @param {string} prefix vendor-specific prefix, eg: Webkit * @param {string} key style name, eg: transitionDuration * @return {string} style name prefixed with `prefix`, properly camelCased, eg: * WebkitTransitionDuration */ function prefixKey(prefix, key) { return prefix + key.charAt(0).toUpperCase() + key.substring(1); } /** * Support style names that may come passed in prefixed by adding permutations * of vendor prefixes. */ var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an // infinite loop, because it iterates over the newly added props too. Object.keys(isUnitlessNumber).forEach(function(prop) { prefixes.forEach(function(prefix) { isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; }); }); /** * Most style properties can be unset by doing .style[prop] = '' but IE8 * doesn't like doing that with shorthand properties so for the properties that * IE8 breaks on, which are listed here, we instead unset each of the * individual properties. See http://bugs.jquery.com/ticket/12385. * The 4-value 'clock' properties like margin, padding, border-width seem to * behave without any problems. Curiously, list-style works too without any * special prodding. */ var shorthandPropertyExpansions = { background: { backgroundImage: true, backgroundPosition: true, backgroundRepeat: true, backgroundColor: true }, border: { borderWidth: true, borderStyle: true, borderColor: true }, borderBottom: { borderBottomWidth: true, borderBottomStyle: true, borderBottomColor: true }, borderLeft: { borderLeftWidth: true, borderLeftStyle: true, borderLeftColor: true }, borderRight: { borderRightWidth: true, borderRightStyle: true, borderRightColor: true }, borderTop: { borderTopWidth: true, borderTopStyle: true, borderTopColor: true }, font: { fontStyle: true, fontVariant: true, fontWeight: true, fontSize: true, lineHeight: true, fontFamily: true } }; var CSSProperty = { isUnitlessNumber: isUnitlessNumber, shorthandPropertyExpansions: shorthandPropertyExpansions }; module.exports = CSSProperty; },{}],47:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, 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. * * @providesModule CSSPropertyOperations * @typechecks static-only */ "use strict"; var CSSProperty = require("./CSSProperty"); var ExecutionEnvironment = require("./ExecutionEnvironment"); var camelizeStyleName = require("./camelizeStyleName"); var dangerousStyleValue = require("./dangerousStyleValue"); var hyphenateStyleName = require("./hyphenateStyleName"); var memoizeStringOnly = require("./memoizeStringOnly"); var warning = require("./warning"); var processStyleName = memoizeStringOnly(function(styleName) { return hyphenateStyleName(styleName); }); var styleFloatAccessor = 'cssFloat'; if (ExecutionEnvironment.canUseDOM) { // IE8 only supports accessing cssFloat (standard) as styleFloat if (document.documentElement.style.cssFloat === undefined) { styleFloatAccessor = 'styleFloat'; } } if ("production" !== process.env.NODE_ENV) { var warnedStyleNames = {}; var warnHyphenatedStyleName = function(name) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } warnedStyleNames[name] = true; ("production" !== process.env.NODE_ENV ? warning( false, 'Unsupported style property ' + name + '. Did you mean ' + camelizeStyleName(name) + '?' ) : null); }; } /** * Operations for dealing with CSS properties. */ var CSSPropertyOperations = { /** * Serializes a mapping of style properties for use as inline styles: * * > createMarkupForStyles({width: '200px', height: 0}) * "width:200px;height:0;" * * Undefined values are ignored so that declarative programming is easier. * The result should be HTML-escaped before insertion into the DOM. * * @param {object} styles * @return {?string} */ createMarkupForStyles: function(styles) { var serialized = ''; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } if ("production" !== process.env.NODE_ENV) { if (styleName.indexOf('-') > -1) { warnHyphenatedStyleName(styleName); } } var styleValue = styles[styleName]; if (styleValue != null) { serialized += processStyleName(styleName) + ':'; serialized += dangerousStyleValue(styleName, styleValue) + ';'; } } return serialized || null; }, /** * Sets the value for multiple styles on a node. If a value is specified as * '' (empty string), the corresponding style property will be unset. * * @param {DOMElement} node * @param {object} styles */ setValueForStyles: function(node, styles) { var style = node.style; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } if ("production" !== process.env.NODE_ENV) { if (styleName.indexOf('-') > -1) { warnHyphenatedStyleName(styleName); } } var styleValue = dangerousStyleValue(styleName, styles[styleName]); if (styleName === 'float') { styleName = styleFloatAccessor; } if (styleValue) { style[styleName] = styleValue; } else { var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; if (expansion) { // Shorthand property that IE8 won't like unsetting, so unset each // component to placate it for (var individualStyleName in expansion) { style[individualStyleName] = ''; } } else { style[styleName] = ''; } } } } }; module.exports = CSSPropertyOperations; }).call(this,require('_process')) },{"./CSSProperty":46,"./ExecutionEnvironment":64,"./camelizeStyleName":154,"./dangerousStyleValue":161,"./hyphenateStyleName":180,"./memoizeStringOnly":191,"./warning":202,"_process":1}],48:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, 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. * * @providesModule CallbackQueue */ "use strict"; var PooledClass = require("./PooledClass"); var assign = require("./Object.assign"); var invariant = require("./invariant"); /** * A specialized pseudo-event module to help keep track of components waiting to * be notified when their DOM representations are available for use. * * This implements `PooledClass`, so you should never need to instantiate this. * Instead, use `CallbackQueue.getPooled()`. * * @class ReactMountReady * @implements PooledClass * @internal */ function CallbackQueue() { this._callbacks = null; this._contexts = null; } assign(CallbackQueue.prototype, { /** * Enqueues a callback to be invoked when `notifyAll` is invoked. * * @param {function} callback Invoked when `notifyAll` is invoked. * @param {?object} context Context to call `callback` with. * @internal */ enqueue: function(callback, context) { this._callbacks = this._callbacks || []; this._contexts = this._contexts || []; this._callbacks.push(callback); this._contexts.push(context); }, /** * Invokes all enqueued callbacks and clears the queue. This is invoked after * the DOM representation of a component has been created or updated. * * @internal */ notifyAll: function() { var callbacks = this._callbacks; var contexts = this._contexts; if (callbacks) { ("production" !== process.env.NODE_ENV ? invariant( callbacks.length === contexts.length, "Mismatched list of contexts in callback queue" ) : invariant(callbacks.length === contexts.length)); this._callbacks = null; this._contexts = null; for (var i = 0, l = callbacks.length; i < l; i++) { callbacks[i].call(contexts[i]); } callbacks.length = 0; contexts.length = 0; } }, /** * Resets the internal queue. * * @internal */ reset: function() { this._callbacks = null; this._contexts = null; }, /** * `PooledClass` looks for this. */ destructor: function() { this.reset(); } }); PooledClass.addPoolingTo(CallbackQueue); module.exports = CallbackQueue; }).call(this,require('_process')) },{"./Object.assign":70,"./PooledClass":71,"./invariant":182,"_process":1}],49:[function(require,module,exports){ /** * Copyright 2013-2014, 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. * * @providesModule ChangeEventPlugin */ "use strict"; var EventConstants = require("./EventConstants"); var EventPluginHub = require("./EventPluginHub"); var EventPropagators = require("./EventPropagators"); var ExecutionEnvironment = require("./ExecutionEnvironment"); var ReactUpdates = require("./ReactUpdates"); var SyntheticEvent = require("./SyntheticEvent"); var isEventSupported = require("./isEventSupported"); var isTextInputElement = require("./isTextInputElement"); var keyOf = require("./keyOf"); var topLevelTypes = EventConstants.topLevelTypes; var eventTypes = { change: { phasedRegistrationNames: { bubbled: keyOf({onChange: null}), captured: keyOf({onChangeCapture: null}) }, dependencies: [ topLevelTypes.topBlur, topLevelTypes.topChange, topLevelTypes.topClick, topLevelTypes.topFocus, topLevelTypes.topInput, topLevelTypes.topKeyDown, topLevelTypes.topKeyUp, topLevelTypes.topSelectionChange ] } }; /** * For IE shims */ var activeElement = null; var activeElementID = null; var activeElementValue = null; var activeElementValueProp = null; /** * SECTION: handle `change` event */ function shouldUseChangeEvent(elem) { return ( elem.nodeName === 'SELECT' || (elem.nodeName === 'INPUT' && elem.type === 'file') ); } var doesChangeEventBubble = false; if (ExecutionEnvironment.canUseDOM) { // See `handleChange` comment below doesChangeEventBubble = isEventSupported('change') && ( !('documentMode' in document) || document.documentMode > 8 ); } function manualDispatchChangeEvent(nativeEvent) { var event = SyntheticEvent.getPooled( eventTypes.change, activeElementID, nativeEvent ); EventPropagators.accumulateTwoPhaseDispatches(event); // If change and propertychange bubbled, we'd just bind to it like all the // other events and have it go through ReactBrowserEventEmitter. Since it // doesn't, we manually listen for the events and so we have to enqueue and // process the abstract event manually. // // Batching is necessary here in order to ensure that all event handlers run // before the next rerender (including event handlers attached to ancestor // elements instead of directly on the input). Without this, controlled // components don't work properly in conjunction with event bubbling because // the component is rerendered and the value reverted before all the event // handlers can run. See https://github.com/facebook/react/issues/708. ReactUpdates.batchedUpdates(runEventInBatch, event); } function runEventInBatch(event) { EventPluginHub.enqueueEvents(event); EventPluginHub.processEventQueue(); } function startWatchingForChangeEventIE8(target, targetID) { activeElement = target; activeElementID = targetID; activeElement.attachEvent('onchange', manualDispatchChangeEvent); } function stopWatchingForChangeEventIE8() { if (!activeElement) { return; } activeElement.detachEvent('onchange', manualDispatchChangeEvent); activeElement = null; activeElementID = null; } function getTargetIDForChangeEvent( topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topChange) { return topLevelTargetID; } } function handleEventsForChangeEventIE8( topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topFocus) { // stopWatching() should be a noop here but we call it just in case we // missed a blur event somehow. stopWatchingForChangeEventIE8(); startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); } else if (topLevelType === topLevelTypes.topBlur) { stopWatchingForChangeEventIE8(); } } /** * SECTION: handle `input` event */ var isInputEventSupported = false; if (ExecutionEnvironment.canUseDOM) { // IE9 claims to support the input event but fails to trigger it when // deleting text, so we ignore its input events isInputEventSupported = isEventSupported('input') && ( !('documentMode' in document) || document.documentMode > 9 ); } /** * (For old IE.) Replacement getter/setter for the `value` property that gets * set on the active element. */ var newValueProp = { get: function() { return activeElementValueProp.get.call(this); }, set: function(val) { // Cast to a string so we can do equality checks. activeElementValue = '' + val; activeElementValueProp.set.call(this, val); } }; /** * (For old IE.) Starts tracking propertychange events on the passed-in element * and override the value property so that we can distinguish user events from * value changes in JS. */ function startWatchingForValueChange(target, targetID) { activeElement = target; activeElementID = targetID; activeElementValue = target.value; activeElementValueProp = Object.getOwnPropertyDescriptor( target.constructor.prototype, 'value' ); Object.defineProperty(activeElement, 'value', newValueProp); activeElement.attachEvent('onpropertychange', handlePropertyChange); } /** * (For old IE.) Removes the event listeners from the currently-tracked element, * if any exists. */ function stopWatchingForValueChange() { if (!activeElement) { return; } // delete restores the original property definition delete activeElement.value; activeElement.detachEvent('onpropertychange', handlePropertyChange); activeElement = null; activeElementID = null; activeElementValue = null; activeElementValueProp = null; } /** * (For old IE.) Handles a propertychange event, sending a `change` event if * the value of the active element has changed. */ function handlePropertyChange(nativeEvent) { if (nativeEvent.propertyName !== 'value') { return; } var value = nativeEvent.srcElement.value; if (value === activeElementValue) { return; } activeElementValue = value; manualDispatchChangeEvent(nativeEvent); } /** * If a `change` event should be fired, returns the target's ID. */ function getTargetIDForInputEvent( topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topInput) { // In modern browsers (i.e., not IE8 or IE9), the input event is exactly // what we want so fall through here and trigger an abstract event return topLevelTargetID; } } // For IE8 and IE9. function handleEventsForInputEventIE( topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topFocus) { // In IE8, we can capture almost all .value changes by adding a // propertychange handler and looking for events with propertyName // equal to 'value' // In IE9, propertychange fires for most input events but is buggy and // doesn't fire when text is deleted, but conveniently, selectionchange // appears to fire in all of the remaining cases so we catch those and // forward the event if the value has changed // In either case, we don't want to call the event handler if the value // is changed from JS so we redefine a setter for `.value` that updates // our activeElementValue variable, allowing us to ignore those changes // // stopWatching() should be a noop here but we call it just in case we // missed a blur event somehow. stopWatchingForValueChange(); startWatchingForValueChange(topLevelTarget, topLevelTargetID); } else if (topLevelType === topLevelTypes.topBlur) { stopWatchingForValueChange(); } } // For IE8 and IE9. function getTargetIDForInputEventIE( topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topSelectionChange || topLevelType === topLevelTypes.topKeyUp || topLevelType === topLevelTypes.topKeyDown) { // On the selectionchange event, the target is just document which isn't // helpful for us so just check activeElement instead. // // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire // propertychange on the first input event after setting `value` from a // script and fires only keydown, keypress, keyup. Catching keyup usually // gets it and catching keydown lets us fire an event for the first // keystroke if user does a key repeat (it'll be a little delayed: right // before the second keystroke). Other input methods (e.g., paste) seem to // fire selectionchange normally. if (activeElement && activeElement.value !== activeElementValue) { activeElementValue = activeElement.value; return activeElementID; } } } /** * SECTION: handle `click` event */ function shouldUseClickEvent(elem) { // Use the `click` event to detect changes to checkbox and radio inputs. // This approach works across all browsers, whereas `change` does not fire // until `blur` in IE8. return ( elem.nodeName === 'INPUT' && (elem.type === 'checkbox' || elem.type === 'radio') ); } function getTargetIDForClickEvent( topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topClick) { return topLevelTargetID; } } /** * This plugin creates an `onChange` event that normalizes change events * across form elements. This event fires at a time when it's possible to * change the element's value without seeing a flicker. * * Supported elements are: * - input (see `isTextInputElement`) * - textarea * - select */ var ChangeEventPlugin = { eventTypes: eventTypes, /** * @param {string} topLevelType Record from `EventConstants`. * @param {DOMEventTarget} topLevelTarget The listening component root node. * @param {string} topLevelTargetID ID of `topLevelTarget`. * @param {object} nativeEvent Native browser event. * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ extractEvents: function( topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) { var getTargetIDFunc, handleEventFunc; if (shouldUseChangeEvent(topLevelTarget)) { if (doesChangeEventBubble) { getTargetIDFunc = getTargetIDForChangeEvent; } else { handleEventFunc = handleEventsForChangeEventIE8; } } else if (isTextInputElement(topLevelTarget)) { if (isInputEventSupported) { getTargetIDFunc = getTargetIDForInputEvent; } else { getTargetIDFunc = getTargetIDForInputEventIE; handleEventFunc = handleEventsForInputEventIE; } } else if (shouldUseClickEvent(topLevelTarget)) { getTargetIDFunc = getTargetIDForClickEvent; } if (getTargetIDFunc) { var targetID = getTargetIDFunc( topLevelType, topLevelTarget, topLevelTargetID ); if (targetID) { var event = SyntheticEvent.getPooled( eventTypes.change, targetID, nativeEvent ); EventPropagators.accumulateTwoPhaseDispatches(event); return event; } } if (handleEventFunc) { handleEventFunc( topLevelType, topLevelTarget, topLevelTargetID ); } } }; module.exports = ChangeEventPlugin; },{"./EventConstants":58,"./EventPluginHub":60,"./EventPropagators":63,"./ExecutionEnvironment":64,"./ReactUpdates":132,"./SyntheticEvent":141,"./isEventSupported":183,"./isTextInputElement":185,"./keyOf":189}],50:[function(require,module,exports){ /** * Copyright 2013-2014, 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. * * @providesModule ClientReactRootIndex * @typechecks */ "use strict"; var nextReactRootIndex = 0; var ClientReactRootIndex = { createReactRootIndex: function() { return nextReactRootIndex++; } }; module.exports = ClientReactRootIndex; },{}],51:[function(require,module,exports){ /** * Copyright 2013-2014, 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. * * @providesModule CompositionEventPlugin * @typechecks static-only */ "use strict"; var EventConstants = require("./EventConstants"); var EventPropagators = require("./EventPropagators"); var ExecutionEnvironment = require("./ExecutionEnvironment"); var ReactInputSelection = require("./ReactInputSelection"); var SyntheticCompositionEvent = require("./SyntheticCompositionEvent"); var getTextContentAccessor = require("./getTextContentAccessor"); var keyOf = require("./keyOf"); var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space var START_KEYCODE = 229; var useCompositionEvent = ( ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window ); // In IE9+, we have access to composition events, but the data supplied // by the native compositionend event may be incorrect. In Korean, for example, // the compositionend event contains only one character regardless of // how many characters have been composed since compositionstart. // We therefore use the fallback data while still using the native // events as triggers. var useFallbackData = ( !useCompositionEvent || ( 'documentMode' in document && document.documentMode > 8 && document.documentMode <= 11 ) ); var topLevelTypes = EventConstants.topLevelTypes; var currentComposition = null; // Events and their corresponding property names. var eventTypes = { compositionEnd: { phasedRegistrationNames: { bubbled: keyOf({onCompositionEnd: null}), captured: keyOf({onCompositionEndCapture: null}) }, dependencies: [ topLevelTypes.topBlur, topLevelTypes.topCompositionEnd, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown ] }, compositionStart: { phasedRegistrationNames: { bubbled: keyOf({onCompositionStart: null}), captured: keyOf({onCompositionStartCapture: null}) }, dependencies: [ topLevelTypes.topBlur, topLevelTypes.topCompositionStart, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown ] }, compositionUpdate: { phasedRegistrationNames: { bubbled: keyOf({onCompositionUpdate: null}), captured: keyOf({onCompositionUpdateCapture: null}) }, dependencies: [ topLevelTypes.topBlur, topLevelTypes.topCompositionUpdate, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown ] } }; /** * Translate native top level events into event types. * * @param {string} topLevelType * @return {object} */ function getCompositionEventType(topLevelType) { switch (topLevelType) { case topLevelTypes.topCompositionStart: return eventTypes.compositionStart; case topLevelTypes.topCompositionEnd: return eventTypes.compositionEnd; case topLevelTypes.topCompositionUpdate: return eventTypes.compositionUpdate; } } /** * Does our fallback best-guess model think this event signifies that * composition has begun? * * @param {string} topLevelType * @param {object} nativeEvent * @return {boolean} */ function isFallbackStart(topLevelType, nativeEvent) { return ( topLevelType === topLevelTypes.topKeyDown && nativeEvent.keyCode === START_KEYCODE ); } /** * Does our fallback mode think that this event is the end of composition? * * @param {string} topLevelType * @param {object} nativeEvent * @return {boolean} */ function isFallbackEnd(topLevelType, nativeEvent) { switch (topLevelType) { case topLevelTypes.topKeyUp: // Command keys insert or clear IME input. return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); case topLevelTypes.topKeyDown: // Expect IME keyCode on each keydown. If we get any other // code we must have exited earlier. return (nativeEvent.keyCode !== START_KEYCODE); case topLevelTypes.topKeyPress: case topLevelTypes.topMouseDown: case topLevelTypes.topBlur: // Events are not possible without cancelling IME. return true; default: return false; } } /** * Helper class stores information about selection and document state * so we can figure out what changed at a later date. * * @param {DOMEventTarget} root */ function FallbackCompositionState(root) { this.root = root; this.startSelection = ReactInputSelection.getSelection(root); this.startValue = this.getText(); } /** * Get current text of input. * * @return {string} */ FallbackCompositionState.prototype.getText = function() { return this.root.value || this.root[getTextContentAccessor()]; }; /** * Text that has changed since the start of composition. * * @return {string} */ FallbackCompositionState.prototype.getData = function() { var endValue = this.getText(); var prefixLength = this.startSelection.start; var suffixLength = this.startValue.length - this.startSelection.end; return endValue.substr( prefixLength, endValue.length - suffixLength - prefixLength ); }; /** * This plugin creates `onCompositionStart`, `onCompositionUpdate` and * `onCompositionEnd` events on inputs, textareas and contentEditable * nodes. */ var CompositionEventPlugin = { eventTypes: eventTypes, /** * @param {string} topLevelType Record from `EventConstants`. * @param {DOMEventTarget} topLevelTarget The listening component root node. * @param {string} topLevelTargetID ID of `topLevelTarget`. * @param {object} nativeEvent Native browser event. * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ extractEvents: function( topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) { var eventType; var data; if (useCompositionEvent) { eventType = getCompositionEventType(topLevelType); } else if (!currentComposition) { if (isFallbackStart(topLevelType, nativeEvent)) { eventType = eventTypes.compositionStart; } } else if (isFallbackEnd(topLevelType, nativeEvent)) { eventType = eventTypes.compositionEnd; } if (useFallbackData) { // The current composition is stored statically and must not be // overwritten while composition continues. if (!currentComposition && eventType === eventTypes.compositionStart) { currentComposition = new FallbackCompositionState(topLevelTarget); } else if (eventType === eventTypes.compositionEnd) { if (currentComposition) { data = currentComposition.getData(); currentComposition = null; } } } if (eventType) { var event = SyntheticCompositionEvent.getPooled( eventType, topLevelTargetID, nativeEvent ); if (data) { // Inject data generated from fallback path into the synthetic event. // This matches the property of native CompositionEventInterface. event.data = data; } EventPropagators.accumulateTwoPhaseDispatches(event); return event; } } }; module.exports = CompositionEventPlugin; },{"./EventConstants":58,"./EventPropagators":63,"./ExecutionEnvironment":64,"./ReactInputSelection":106,"./SyntheticCompositionEvent":139,"./getTextContentAccessor":177,"./keyOf":189}],52:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, 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. * * @providesModule DOMChildrenOperations * @typechecks static-only */ "use strict"; var Danger = require("./Danger"); var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes"); var getTextContentAccessor = require("./getTextContentAccessor"); var invariant = require("./invariant"); /** * The DOM property to use when setting text content. * * @type {string} * @private */ var textContentAccessor = getTextContentAccessor(); /** * Inserts `childNode` as a child of `parentNode` at the `index`. * * @param {DOMElement} parentNode Parent node in which to insert. * @param {DOMElement} childNode Child node to insert. * @param {number} index Index at which to insert the child. * @internal */ function insertChildAt(parentNode, childNode, index) { // By exploiting arrays returning `undefined` for an undefined index, we can // rely exclusively on `insertBefore(node, null)` instead of also using // `appendChild(node)`. However, using `undefined` is not allowed by all // browsers so we must replace it with `null`. parentNode.insertBefore( childNode, parentNode.childNodes[index] || null ); } var updateTextContent; if (textContentAccessor === 'textContent') { /** * Sets the text content of `node` to `text`. * * @param {DOMElement} node Node to change * @param {string} text New text content */ updateTextContent = function(node, text) { node.textContent = text; }; } else { /** * Sets the text content of `node` to `text`. * * @param {DOMElement} node Node to change * @param {string} text New text content */ updateTextContent = function(node, text) { // In order to preserve newlines correctly, we can't use .innerText to set // the contents (see #1080), so we empty the element then append a text node while (node.firstChild) { node.removeChild(node.firstChild); } if (text) { var doc = node.ownerDocument || document; node.appendChild(doc.createTextNode(text)); } }; } /** * Operations for updating with DOM children. */ var DOMChildrenOperations = { dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, updateTextContent: updateTextContent, /** * Updates a component's children by processing a series of updates. The * update configurations are each expected to have a `parentNode` property. * * @param {array} updates List of update configurations. * @param {array} markupList List of markup strings. * @internal */ processUpdates: function(updates, markupList) { var update; // Mapping from parent IDs to initial child orderings. var initialChildren = null; // List of children that will be moved or removed. var updatedChildren = null; for (var i = 0; update = updates[i]; i++) { if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { var updatedIndex = update.fromIndex; var updatedChild = update.parentNode.childNodes[updatedIndex]; var parentID = update.parentID; ("production" !== process.env.NODE_ENV ? invariant( updatedChild, 'processUpdates(): Unable to find child %s of element. This ' + 'probably means the DOM was unexpectedly mutated (e.g., by the ' + 'browser), usually due to forgetting a when using tables, ' + 'nesting tags like
,

, or , or using non-SVG elements '+ 'in an parent. Try inspecting the child nodes of the element ' + 'with React ID `%s`.', updatedIndex, parentID ) : invariant(updatedChild)); initialChildren = initialChildren || {}; initialChildren[parentID] = initialChildren[parentID] || []; initialChildren[parentID][updatedIndex] = updatedChild; updatedChildren = updatedChildren || []; updatedChildren.push(updatedChild); } } var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); // Remove updated children first so that `toIndex` is consistent. if (updatedChildren) { for (var j = 0; j < updatedChildren.length; j++) { updatedChildren[j].parentNode.removeChild(updatedChildren[j]); } } for (var k = 0; update = updates[k]; k++) { switch (update.type) { case ReactMultiChildUpdateTypes.INSERT_MARKUP: insertChildAt( update.parentNode, renderedMarkup[update.markupIndex], update.toIndex ); break; case ReactMultiChildUpdateTypes.MOVE_EXISTING: insertChildAt( update.parentNode, initialChildren[update.parentID][update.fromIndex], update.toIndex ); break; case ReactMultiChildUpdateTypes.TEXT_CONTENT: updateTextContent( update.parentNode, update.textContent ); break; case ReactMultiChildUpdateTypes.REMOVE_NODE: // Already removed by the for-loop above. break; } } } }; module.exports = DOMChildrenOperations; }).call(this,require('_process')) },{"./Danger":55,"./ReactMultiChildUpdateTypes":113,"./getTextContentAccessor":177,"./invariant":182,"_process":1}],53:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, 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. * * @providesModule DOMProperty * @typechecks static-only */ /*jslint bitwise: true */ "use strict"; var invariant = require("./invariant"); function checkMask(value, bitmask) { return (value & bitmask) === bitmask; } var DOMPropertyInjection = { /** * Mapping from normalized, camelcased property names to a configuration that * specifies how the associated DOM property should be accessed or rendered. */ MUST_USE_ATTRIBUTE: 0x1, MUST_USE_PROPERTY: 0x2, HAS_SIDE_EFFECTS: 0x4, HAS_BOOLEAN_VALUE: 0x8, HAS_NUMERIC_VALUE: 0x10, HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, /** * Inject some specialized knowledge about the DOM. This takes a config object * with the following properties: * * isCustomAttribute: function that given an attribute name will return true * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* * attributes where it's impossible to enumerate all of the possible * attribute names, * * Properties: object mapping DOM property name to one of the * DOMPropertyInjection constants or null. If your attribute isn't in here, * it won't get written to the DOM. * * DOMAttributeNames: object mapping React attribute name to the DOM * attribute name. Attribute names not specified use the **lowercase** * normalized name. * * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. * Property names not specified use the normalized name. * * DOMMutationMethods: Properties that require special mutation methods. If * `value` is undefined, the mutation method should unset the property. * * @param {object} domPropertyConfig the config as described above. */ injectDOMPropertyConfig: function(domPropertyConfig) { var Properties = domPropertyConfig.Properties || {}; var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; if (domPropertyConfig.isCustomAttribute) { DOMProperty._isCustomAttributeFunctions.push( domPropertyConfig.isCustomAttribute ); } for (var propName in Properties) { ("production" !== process.env.NODE_ENV ? invariant( !DOMProperty.isStandardName.hasOwnProperty(propName), 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + '\'%s\' which has already been injected. You may be accidentally ' + 'injecting the same DOM property config twice, or you may be ' + 'injecting two configs that have conflicting property names.', propName ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); DOMProperty.isStandardName[propName] = true; var lowerCased = propName.toLowerCase(); DOMProperty.getPossibleStandardName[lowerCased] = propName; if (DOMAttributeNames.hasOwnProperty(propName)) { var attributeName = DOMAttributeNames[propName]; DOMProperty.getPossibleStandardName[attributeName] = propName; DOMProperty.getAttributeName[propName] = attributeName; } else { DOMProperty.getAttributeName[propName] = lowerCased; } DOMProperty.getPropertyName[propName] = DOMPropertyNames.hasOwnProperty(propName) ? DOMPropertyNames[propName] : propName; if (DOMMutationMethods.hasOwnProperty(propName)) { DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; } else { DOMProperty.getMutationMethod[propName] = null; } var propConfig = Properties[propName]; DOMProperty.mustUseAttribute[propName] = checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); DOMProperty.mustUseProperty[propName] = checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); DOMProperty.hasSideEffects[propName] = checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); DOMProperty.hasBooleanValue[propName] = checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); DOMProperty.hasNumericValue[propName] = checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); DOMProperty.hasPositiveNumericValue[propName] = checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); DOMProperty.hasOverloadedBooleanValue[propName] = checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); ("production" !== process.env.NODE_ENV ? invariant( !DOMProperty.mustUseAttribute[propName] || !DOMProperty.mustUseProperty[propName], 'DOMProperty: Cannot require using both attribute and property: %s', propName ) : invariant(!DOMProperty.mustUseAttribute[propName] || !DOMProperty.mustUseProperty[propName])); ("production" !== process.env.NODE_ENV ? invariant( DOMProperty.mustUseProperty[propName] || !DOMProperty.hasSideEffects[propName], 'DOMProperty: Properties that have side effects must use property: %s', propName ) : invariant(DOMProperty.mustUseProperty[propName] || !DOMProperty.hasSideEffects[propName])); ("production" !== process.env.NODE_ENV ? invariant( !!DOMProperty.hasBooleanValue[propName] + !!DOMProperty.hasNumericValue[propName] + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + 'numeric value, but not a combination: %s', propName ) : invariant(!!DOMProperty.hasBooleanValue[propName] + !!DOMProperty.hasNumericValue[propName] + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); } } }; var defaultValueCache = {}; /** * DOMProperty exports lookup objects that can be used like functions: * * > DOMProperty.isValid['id'] * true * > DOMProperty.isValid['foobar'] * undefined * * Although this may be confusing, it performs better in general. * * @see http://jsperf.com/key-exists * @see http://jsperf.com/key-missing */ var DOMProperty = { ID_ATTRIBUTE_NAME: 'data-reactid', /** * Checks whether a property name is a standard property. * @type {Object} */ isStandardName: {}, /** * Mapping from lowercase property names to the properly cased version, used * to warn in the case of missing properties. * @type {Object} */ getPossibleStandardName: {}, /** * Mapping from normalized names to attribute names that differ. Attribute * names are used when rendering markup or with `*Attribute()`. * @type {Object} */ getAttributeName: {}, /** * Mapping from normalized names to properties on DOM node instances. * (This includes properties that mutate due to external factors.) * @type {Object} */ getPropertyName: {}, /** * Mapping from normalized names to mutation methods. This will only exist if * mutation cannot be set simply by the property or `setAttribute()`. * @type {Object} */ getMutationMethod: {}, /** * Whether the property must be accessed and mutated as an object property. * @type {Object} */ mustUseAttribute: {}, /** * Whether the property must be accessed and mutated using `*Attribute()`. * (This includes anything that fails ` in `.) * @type {Object} */ mustUseProperty: {}, /** * Whether or not setting a value causes side effects such as triggering * resources to be loaded or text selection changes. We must ensure that * the value is only set if it has changed. * @type {Object} */ hasSideEffects: {}, /** * Whether the property should be removed when set to a falsey value. * @type {Object} */ hasBooleanValue: {}, /** * Whether the property must be numeric or parse as a * numeric and should be removed when set to a falsey value. * @type {Object} */ hasNumericValue: {}, /** * Whether the property must be positive numeric or parse as a positive * numeric and should be removed when set to a falsey value. * @type {Object} */ hasPositiveNumericValue: {}, /** * Whether the property can be used as a flag as well as with a value. Removed * when strictly equal to false; present without a value when strictly equal * to true; present with a value otherwise. * @type {Object} */ hasOverloadedBooleanValue: {}, /** * All of the isCustomAttribute() functions that have been injected. */ _isCustomAttributeFunctions: [], /** * Checks whether a property name is a custom attribute. * @method */ isCustomAttribute: function(attributeName) { for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; if (isCustomAttributeFn(attributeName)) { return true; } } return false; }, /** * Returns the default property value for a DOM property (i.e., not an * attribute). Most default values are '' or false, but not all. Worse yet, * some (in particular, `type`) vary depending on the type of element. * * TODO: Is it better to grab all the possible properties when creating an * element to avoid having to create the same element twice? */ getDefaultValueForProperty: function(nodeName, prop) { var nodeDefaults = defaultValueCache[nodeName]; var testElement; if (!nodeDefaults) { defaultValueCache[nodeName] = nodeDefaults = {}; } if (!(prop in nodeDefaults)) { testElement = document.createElement(nodeName); nodeDefaults[prop] = testElement[prop]; } return nodeDefaults[prop]; }, injection: DOMPropertyInjection }; module.exports = DOMProperty; }).call(this,require('_process')) },{"./invariant":182,"_process":1}],54:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, 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. * * @providesModule DOMPropertyOperations * @typechecks static-only */ "use strict"; var DOMProperty = require("./DOMProperty"); var escapeTextForBrowser = require("./escapeTextForBrowser"); var memoizeStringOnly = require("./memoizeStringOnly"); var warning = require("./warning"); function shouldIgnoreValue(name, value) { return value == null || (DOMProperty.hasBooleanValue[name] && !value) || (DOMProperty.hasNumericValue[name] && isNaN(value)) || (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || (DOMProperty.hasOverloadedBooleanValue[name] && value === false); } var processAttributeNameAndPrefix = memoizeStringOnly(function(name) { return escapeTextForBrowser(name) + '="'; }); if ("production" !== process.env.NODE_ENV) { var reactProps = { children: true, dangerouslySetInnerHTML: true, key: true, ref: true }; var warnedProperties = {}; var warnUnknownProperty = function(name) { if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { return; } warnedProperties[name] = true; var lowerCasedName = name.toLowerCase(); // data-* attributes should be lowercase; suggest the lowercase version var standardName = ( DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null ); // For now, only warn when we have a suggested correction. This prevents // logging too much when using transferPropsTo. ("production" !== process.env.NODE_ENV ? warning( standardName == null, 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?' ) : null); }; } /** * Operations for dealing with DOM properties. */ var DOMPropertyOperations = { /** * Creates markup for the ID property. * * @param {string} id Unescaped ID. * @return {string} Markup string. */ createMarkupForID: function(id) { return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) + escapeTextForBrowser(id) + '"'; }, /** * Creates markup for a property. * * @param {string} name * @param {*} value * @return {?string} Markup string, or null if the property was invalid. */ createMarkupForProperty: function(name, value) { if (DOMProperty.isStandardName.hasOwnProperty(name) && DOMProperty.isStandardName[name]) { if (shouldIgnoreValue(name, value)) { return ''; } var attributeName = DOMProperty.getAttributeName[name]; if (DOMProperty.hasBooleanValue[name] || (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { return escapeTextForBrowser(attributeName); } return processAttributeNameAndPrefix(attributeName) + escapeTextForBrowser(value) + '"'; } else if (DOMProperty.isCustomAttribute(name)) { if (value == null) { return ''; } return processAttributeNameAndPrefix(name) + escapeTextForBrowser(value) + '"'; } else if ("production" !== process.env.NODE_ENV) { warnUnknownProperty(name); } return null; }, /** * Sets the value for a property on a node. * * @param {DOMElement} node * @param {string} name * @param {*} value */ setValueForProperty: function(node, name, value) { if (DOMProperty.isStandardName.hasOwnProperty(name) && DOMProperty.isStandardName[name]) { var mutationMethod = DOMProperty.getMutationMethod[name]; if (mutationMethod) { mutationMethod(node, value); } else if (shouldIgnoreValue(name, value)) { this.deleteValueForProperty(node, name); } else if (DOMProperty.mustUseAttribute[name]) { // `setAttribute` with objects becomes only `[object]` in IE8/9, // ('' + value) makes it output the correct toString()-value. node.setAttribute(DOMProperty.getAttributeName[name], '' + value); } else { var propName = DOMProperty.getPropertyName[name]; // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the // property type before comparing; only `value` does and is string. if (!DOMProperty.hasSideEffects[name] || ('' + node[propName]) !== ('' + value)) { // Contrary to `setAttribute`, object properties are properly // `toString`ed by IE8/9. node[propName] = value; } } } else if (DOMProperty.isCustomAttribute(name)) { if (value == null) { node.removeAttribute(name); } else { node.setAttribute(name, '' + value); } } else if ("production" !== process.env.NODE_ENV) { warnUnknownProperty(name); } }, /** * Deletes the value for a property on a node. * * @param {DOMElement} node * @param {string} name */ deleteValueForProperty: function(node, name) { if (DOMProperty.isStandardName.hasOwnProperty(name) && DOMProperty.isStandardName[name]) { var mutationMethod = DOMProperty.getMutationMethod[name]; if (mutationMethod) { mutationMethod(node, undefined); } else if (DOMProperty.mustUseAttribute[name]) { node.removeAttribute(DOMProperty.getAttributeName[name]); } else { var propName = DOMProperty.getPropertyName[name]; var defaultValue = DOMProperty.getDefaultValueForProperty( node.nodeName, propName ); if (!DOMProperty.hasSideEffects[name] || ('' + node[propName]) !== defaultValue) { node[propName] = defaultValue; } } } else if (DOMProperty.isCustomAttribute(name)) { node.removeAttribute(name); } else if ("production" !== process.env.NODE_ENV) { warnUnknownProperty(name); } } }; module.exports = DOMPropertyOperations; }).call(this,require('_process')) },{"./DOMProperty":53,"./escapeTextForBrowser":165,"./memoizeStringOnly":191,"./warning":202,"_process":1}],55:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, 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. * * @providesModule Danger * @typechecks static-only */ /*jslint evil: true, sub: true */ "use strict"; var ExecutionEnvironment = require("./ExecutionEnvironment"); var createNodesFromMarkup = require("./createNodesFromMarkup"); var emptyFunction = require("./emptyFunction"); var getMarkupWrap = require("./getMarkupWrap"); var invariant = require("./invariant"); var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; var RESULT_INDEX_ATTR = 'data-danger-index'; /** * Extracts the `nodeName` from a string of markup. * * NOTE: Extracting the `nodeName` does not require a regular expression match * because we make assumptions about React-generated markup (i.e. there are no * spaces surrounding the opening tag and there is at least one attribute). * * @param {string} markup String of markup. * @return {string} Node name of the supplied markup. * @see http://jsperf.com/extract-nodename */ function getNodeName(markup) { return markup.substring(1, markup.indexOf(' ')); } var Danger = { /** * Renders markup into an array of nodes. The markup is expected to render * into a list of root nodes. Also, the length of `resultList` and * `markupList` should be the same. * * @param {array} markupList List of markup strings to render. * @return {array} List of rendered nodes. * @internal */ dangerouslyRenderMarkup: function(markupList) { ("production" !== process.env.NODE_ENV ? invariant( ExecutionEnvironment.canUseDOM, 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + 'thread. Make sure `window` and `document` are available globally ' + 'before requiring React when unit testing or use ' + 'React.renderToString for server rendering.' ) : invariant(ExecutionEnvironment.canUseDOM)); var nodeName; var markupByNodeName = {}; // Group markup by `nodeName` if a wrap is necessary, else by '*'. for (var i = 0; i < markupList.length; i++) { ("production" !== process.env.NODE_ENV ? invariant( markupList[i], 'dangerouslyRenderMarkup(...): Missing markup.' ) : invariant(markupList[i])); nodeName = getNodeName(markupList[i]); nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; markupByNodeName[nodeName][i] = markupList[i]; } var resultList = []; var resultListAssignmentCount = 0; for (nodeName in markupByNodeName) { if (!markupByNodeName.hasOwnProperty(nodeName)) { continue; } var markupListByNodeName = markupByNodeName[nodeName]; // This for-in loop skips the holes of the sparse array. The order of // iteration should follow the order of assignment, which happens to match // numerical index order, but we don't rely on that. for (var resultIndex in markupListByNodeName) { if (markupListByNodeName.hasOwnProperty(resultIndex)) { var markup = markupListByNodeName[resultIndex]; // Push the requested markup with an additional RESULT_INDEX_ATTR // attribute. If the markup does not start with a < character, it // will be discarded below (with an appropriate console.error). markupListByNodeName[resultIndex] = markup.replace( OPEN_TAG_NAME_EXP, // This index will be parsed back out below. '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' ); } } // Render each group of markup with similar wrapping `nodeName`. var renderNodes = createNodesFromMarkup( markupListByNodeName.join(''), emptyFunction // Do nothing special with

; * } * }); * * Note: This only checks shallow equality for props and state. If these contain * complex data structures this mixin may have false-negatives for deeper * differences. Only mixin to components which have simple props and state, or * use `forceUpdate()` when you know deep data structures have changed. */ var ReactComponentWithPureRenderMixin = { shouldComponentUpdate: function(nextProps, nextState) { return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); } }; module.exports = ReactComponentWithPureRenderMixin; },{"./shallowEqual":197}],81:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, 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. * * @providesModule ReactCompositeComponent */ "use strict"; var ReactComponent = require("./ReactComponent"); var ReactContext = require("./ReactContext"); var ReactCurrentOwner = require("./ReactCurrentOwner"); var ReactElement = require("./ReactElement"); var ReactElementValidator = require("./ReactElementValidator"); var ReactEmptyComponent = require("./ReactEmptyComponent"); var ReactErrorUtils = require("./ReactErrorUtils"); var ReactLegacyElement = require("./ReactLegacyElement"); var ReactOwner = require("./ReactOwner"); var ReactPerf = require("./ReactPerf"); var ReactPropTransferer = require("./ReactPropTransferer"); var ReactPropTypeLocations = require("./ReactPropTypeLocations"); var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames"); var ReactUpdates = require("./ReactUpdates"); var assign = require("./Object.assign"); var instantiateReactComponent = require("./instantiateReactComponent"); var invariant = require("./invariant"); var keyMirror = require("./keyMirror"); var keyOf = require("./keyOf"); var monitorCodeUse = require("./monitorCodeUse"); var mapObject = require("./mapObject"); var shouldUpdateReactComponent = require("./shouldUpdateReactComponent"); var warning = require("./warning"); var MIXINS_KEY = keyOf({mixins: null}); /** * Policies that describe methods in `ReactCompositeComponentInterface`. */ var SpecPolicy = keyMirror({ /** * These methods may be defined only once by the class specification or mixin. */ DEFINE_ONCE: null, /** * These methods may be defined by both the class specification and mixins. * Subsequent definitions will be chained. These methods must return void. */ DEFINE_MANY: null, /** * These methods are overriding the base ReactCompositeComponent class. */ OVERRIDE_BASE: null, /** * These methods are similar to DEFINE_MANY, except we assume they return * objects. We try to merge the keys of the return values of all the mixed in * functions. If there is a key conflict we throw. */ DEFINE_MANY_MERGED: null }); var injectedMixins = []; /** * Composite components are higher-level components that compose other composite * or native components. * * To create a new type of `ReactCompositeComponent`, pass a specification of * your new class to `React.createClass`. The only requirement of your class * specification is that you implement a `render` method. * * var MyComponent = React.createClass({ * render: function() { * return
Hello World
; * } * }); * * The class specification supports a specific protocol of methods that have * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for * more the comprehensive protocol. Any other properties and methods in the * class specification will available on the prototype. * * @interface ReactCompositeComponentInterface * @internal */ var ReactCompositeComponentInterface = { /** * An array of Mixin objects to include when defining your component. * * @type {array} * @optional */ mixins: SpecPolicy.DEFINE_MANY, /** * An object containing properties and methods that should be defined on * the component's constructor instead of its prototype (static methods). * * @type {object} * @optional */ statics: SpecPolicy.DEFINE_MANY, /** * Definition of prop types for this component. * * @type {object} * @optional */ propTypes: SpecPolicy.DEFINE_MANY, /** * Definition of context types for this component. * * @type {object} * @optional */ contextTypes: SpecPolicy.DEFINE_MANY, /** * Definition of context types this component sets for its children. * * @type {object} * @optional */ childContextTypes: SpecPolicy.DEFINE_MANY, // ==== Definition methods ==== /** * Invoked when the component is mounted. Values in the mapping will be set on * `this.props` if that prop is not specified (i.e. using an `in` check). * * This method is invoked before `getInitialState` and therefore cannot rely * on `this.state` or use `this.setState`. * * @return {object} * @optional */ getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, /** * Invoked once before the component is mounted. The return value will be used * as the initial value of `this.state`. * * getInitialState: function() { * return { * isOn: false, * fooBaz: new BazFoo() * } * } * * @return {object} * @optional */ getInitialState: SpecPolicy.DEFINE_MANY_MERGED, /** * @return {object} * @optional */ getChildContext: SpecPolicy.DEFINE_MANY_MERGED, /** * Uses props from `this.props` and state from `this.state` to render the * structure of the component. * * No guarantees are made about when or how often this method is invoked, so * it must not have side effects. * * render: function() { * var name = this.props.name; * return
Hello, {name}!
; * } * * @return {ReactComponent} * @nosideeffects * @required */ render: SpecPolicy.DEFINE_ONCE, // ==== Delegate methods ==== /** * Invoked when the component is initially created and about to be mounted. * This may have side effects, but any external subscriptions or data created * by this method must be cleaned up in `componentWillUnmount`. * * @optional */ componentWillMount: SpecPolicy.DEFINE_MANY, /** * Invoked when the component has been mounted and has a DOM representation. * However, there is no guarantee that the DOM node is in the document. * * Use this as an opportunity to operate on the DOM when the component has * been mounted (initialized and rendered) for the first time. * * @param {DOMElement} rootNode DOM element representing the component. * @optional */ componentDidMount: SpecPolicy.DEFINE_MANY, /** * Invoked before the component receives new props. * * Use this as an opportunity to react to a prop transition by updating the * state using `this.setState`. Current props are accessed via `this.props`. * * componentWillReceiveProps: function(nextProps, nextContext) { * this.setState({ * likesIncreasing: nextProps.likeCount > this.props.likeCount * }); * } * * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop * transition may cause a state change, but the opposite is not true. If you * need it, you are probably looking for `componentWillUpdate`. * * @param {object} nextProps * @optional */ componentWillReceiveProps: SpecPolicy.DEFINE_MANY, /** * Invoked while deciding if the component should be updated as a result of * receiving new props, state and/or context. * * Use this as an opportunity to `return false` when you're certain that the * transition to the new props/state/context will not require a component * update. * * shouldComponentUpdate: function(nextProps, nextState, nextContext) { * return !equal(nextProps, this.props) || * !equal(nextState, this.state) || * !equal(nextContext, this.context); * } * * @param {object} nextProps * @param {?object} nextState * @param {?object} nextContext * @return {boolean} True if the component should update. * @optional */ shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, /** * Invoked when the component is about to update due to a transition from * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` * and `nextContext`. * * Use this as an opportunity to perform preparation before an update occurs. * * NOTE: You **cannot** use `this.setState()` in this method. * * @param {object} nextProps * @param {?object} nextState * @param {?object} nextContext * @param {ReactReconcileTransaction} transaction * @optional */ componentWillUpdate: SpecPolicy.DEFINE_MANY, /** * Invoked when the component's DOM representation has been updated. * * Use this as an opportunity to operate on the DOM when the component has * been updated. * * @param {object} prevProps * @param {?object} prevState * @param {?object} prevContext * @param {DOMElement} rootNode DOM element representing the component. * @optional */ componentDidUpdate: SpecPolicy.DEFINE_MANY, /** * Invoked when the component is about to be removed from its parent and have * its DOM representation destroyed. * * Use this as an opportunity to deallocate any external resources. * * NOTE: There is no `componentDidUnmount` since your component will have been * destroyed by that point. * * @optional */ componentWillUnmount: SpecPolicy.DEFINE_MANY, // ==== Advanced methods ==== /** * Updates the component's currently mounted DOM representation. * * By default, this implements React's rendering and reconciliation algorithm. * Sophisticated clients may wish to override this. * * @param {ReactReconcileTransaction} transaction * @internal * @overridable */ updateComponent: SpecPolicy.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(Constructor, displayName) { Constructor.displayName = displayName; }, mixins: function(Constructor, mixins) { if (mixins) { for (var i = 0; i < mixins.length; i++) { mixSpecIntoComponent(Constructor, mixins[i]); } } }, childContextTypes: function(Constructor, childContextTypes) { validateTypeDef( Constructor, childContextTypes, ReactPropTypeLocations.childContext ); Constructor.childContextTypes = assign( {}, Constructor.childContextTypes, childContextTypes ); }, contextTypes: function(Constructor, contextTypes) { validateTypeDef( Constructor, contextTypes, ReactPropTypeLocations.context ); Constructor.contextTypes = assign( {}, Constructor.contextTypes, contextTypes ); }, /** * Special case getDefaultProps which should move into statics but requires * automatic merging. */ getDefaultProps: function(Constructor, getDefaultProps) { if (Constructor.getDefaultProps) { Constructor.getDefaultProps = createMergedResultFunction( Constructor.getDefaultProps, getDefaultProps ); } else { Constructor.getDefaultProps = getDefaultProps; } }, propTypes: function(Constructor, propTypes) { validateTypeDef( Constructor, propTypes, ReactPropTypeLocations.prop ); Constructor.propTypes = assign( {}, Constructor.propTypes, propTypes ); }, statics: function(Constructor, statics) { mixStaticSpecIntoComponent(Constructor, statics); } }; function getDeclarationErrorAddendum(component) { var owner = component._owner || null; if (owner && owner.constructor && owner.constructor.displayName) { return ' Check the render method of `' + owner.constructor.displayName + '`.'; } return ''; } function validateTypeDef(Constructor, typeDef, location) { for (var propName in typeDef) { if (typeDef.hasOwnProperty(propName)) { ("production" !== process.env.NODE_ENV ? invariant( typeof typeDef[propName] == 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', Constructor.displayName || 'ReactCompositeComponent', ReactPropTypeLocationNames[location], propName ) : invariant(typeof typeDef[propName] == 'function')); } } } function validateMethodOverride(proto, name) { var specPolicy = ReactCompositeComponentInterface.hasOwnProperty(name) ? ReactCompositeComponentInterface[name] : null; // Disallow overriding of base class methods unless explicitly allowed. if (ReactCompositeComponentMixin.hasOwnProperty(name)) { ("production" !== process.env.NODE_ENV ? invariant( specPolicy === SpecPolicy.OVERRIDE_BASE, 'ReactCompositeComponentInterface: You are attempting to override ' + '`%s` from your class specification. Ensure that your method names ' + 'do not overlap with React methods.', name ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE)); } // Disallow defining methods more than once unless explicitly allowed. if (proto.hasOwnProperty(name)) { ("production" !== process.env.NODE_ENV ? invariant( specPolicy === SpecPolicy.DEFINE_MANY || specPolicy === SpecPolicy.DEFINE_MANY_MERGED, 'ReactCompositeComponentInterface: You are attempting to define ' + '`%s` on your component more than once. This conflict may be due ' + 'to a mixin.', name ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY || specPolicy === SpecPolicy.DEFINE_MANY_MERGED)); } } function validateLifeCycleOnReplaceState(instance) { var compositeLifeCycleState = instance._compositeLifeCycleState; ("production" !== process.env.NODE_ENV ? invariant( instance.isMounted() || compositeLifeCycleState === CompositeLifeCycle.MOUNTING, 'replaceState(...): Can only update a mounted or mounting component.' ) : invariant(instance.isMounted() || compositeLifeCycleState === CompositeLifeCycle.MOUNTING)); ("production" !== process.env.NODE_ENV ? invariant( ReactCurrentOwner.current == null, 'replaceState(...): Cannot update during an existing state transition ' + '(such as within `render`). Render methods should be a pure function ' + 'of props and state.' ) : invariant(ReactCurrentOwner.current == null)); ("production" !== process.env.NODE_ENV ? invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING, 'replaceState(...): Cannot update while unmounting component. This ' + 'usually means you called setState() on an unmounted component.' ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING)); } /** * Mixin helper which handles policy validation and reserved * specification keys when building `ReactCompositeComponent` classses. */ function mixSpecIntoComponent(Constructor, spec) { if (!spec) { return; } ("production" !== process.env.NODE_ENV ? invariant( !ReactLegacyElement.isValidFactory(spec), 'ReactCompositeComponent: You\'re attempting to ' + 'use a component class as a mixin. Instead, just use a regular object.' ) : invariant(!ReactLegacyElement.isValidFactory(spec))); ("production" !== process.env.NODE_ENV ? invariant( !ReactElement.isValidElement(spec), 'ReactCompositeComponent: You\'re attempting to ' + 'use a component as a mixin. Instead, just use a regular object.' ) : invariant(!ReactElement.isValidElement(spec))); var proto = Constructor.prototype; // 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]; validateMethodOverride(proto, 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 ReactCompositeComponent methods (in the "interface"). // 2. Overridden methods (that were mixed in). var isCompositeComponentMethod = ReactCompositeComponentInterface.hasOwnProperty(name); var isAlreadyDefined = proto.hasOwnProperty(name); var markedDontBind = property && property.__reactDontBind; var isFunction = typeof property === 'function'; var shouldAutoBind = isFunction && !isCompositeComponentMethod && !isAlreadyDefined && !markedDontBind; if (shouldAutoBind) { if (!proto.__reactAutoBindMap) { proto.__reactAutoBindMap = {}; } proto.__reactAutoBindMap[name] = property; proto[name] = property; } else { if (isAlreadyDefined) { var specPolicy = ReactCompositeComponentInterface[name]; // These cases should already be caught by validateMethodOverride ("production" !== process.env.NODE_ENV ? invariant( isCompositeComponentMethod && ( specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY ), 'ReactCompositeComponent: Unexpected spec policy %s for key %s ' + 'when mixing in component specs.', specPolicy, name ) : invariant(isCompositeComponentMethod && ( specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY ))); // For methods which are defined more than once, call the existing // methods before calling the new property, merging if appropriate. if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { proto[name] = createMergedResultFunction(proto[name], property); } else if (specPolicy === SpecPolicy.DEFINE_MANY) { proto[name] = createChainedFunction(proto[name], property); } } else { proto[name] = property; if ("production" !== process.env.NODE_ENV) { // 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; ("production" !== process.env.NODE_ENV ? invariant( !isReserved, 'ReactCompositeComponent: 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 ) : invariant(!isReserved)); var isInherited = name in Constructor; ("production" !== process.env.NODE_ENV ? invariant( !isInherited, 'ReactCompositeComponent: You are attempting to define ' + '`%s` on your component more than once. This conflict may be ' + 'due to a mixin.', name ) : invariant(!isInherited)); Constructor[name] = property; } } /** * Merge two objects, but throw if both contain the same key. * * @param {object} one The first object, which is mutated. * @param {object} two The second object * @return {object} one after it has been mutated to contain everything in two. */ function mergeObjectsWithNoDuplicateKeys(one, two) { ("production" !== process.env.NODE_ENV ? invariant( one && two && typeof one === 'object' && typeof two === 'object', 'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects' ) : invariant(one && two && typeof one === 'object' && typeof two === 'object')); mapObject(two, function(value, key) { ("production" !== process.env.NODE_ENV ? invariant( one[key] === undefined, 'mergeObjectsWithNoDuplicateKeys(): ' + 'Tried to merge two objects with the same key: `%s`. This conflict ' + 'may be due to a mixin; in particular, this may be caused by two ' + 'getInitialState() or getDefaultProps() methods returning objects ' + 'with clashing keys.', key ) : invariant(one[key] === undefined)); one[key] = value; }); return one; } /** * Creates a function that invokes two functions and merges their return values. * * @param {function} one Function to invoke first. * @param {function} two Function to invoke second. * @return {function} Function that invokes the two argument functions. * @private */ 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; } return mergeObjectsWithNoDuplicateKeys(a, b); }; } /** * Creates a function that invokes two functions and ignores their return vales. * * @param {function} one Function to invoke first. * @param {function} two Function to invoke second. * @return {function} Function that invokes the two argument functions. * @private */ function createChainedFunction(one, two) { return function chainedFunction() { one.apply(this, arguments); two.apply(this, arguments); }; } /** * `ReactCompositeComponent` maintains an auxiliary life cycle state in * `this._compositeLifeCycleState` (which can be null). * * This is different from the life cycle state maintained by `ReactComponent` in * `this._lifeCycleState`. The following diagram shows how the states overlap in * time. There are times when the CompositeLifeCycle is null - at those times it * is only meaningful to look at ComponentLifeCycle alone. * * Top Row: ReactComponent.ComponentLifeCycle * Low Row: ReactComponent.CompositeLifeCycle * * +-------+---------------------------------+--------+ * | UN | MOUNTED | UN | * |MOUNTED| | MOUNTED| * +-------+---------------------------------+--------+ * | ^--------+ +-------+ +--------^ | * | | | | | | | | * | 0--|MOUNTING|-0-|RECEIVE|-0-| UN |--->0 | * | | | |PROPS | |MOUNTING| | * | | | | | | | | * | | | | | | | | * | +--------+ +-------+ +--------+ | * | | | | * +-------+---------------------------------+--------+ */ var CompositeLifeCycle = keyMirror({ /** * Components in the process of being mounted respond to state changes * differently. */ MOUNTING: null, /** * Components in the process of being unmounted are guarded against state * changes. */ UNMOUNTING: null, /** * Components that are mounted and receiving new props respond to state * changes differently. */ RECEIVING_PROPS: null }); /** * @lends {ReactCompositeComponent.prototype} */ var ReactCompositeComponentMixin = { /** * Base constructor for all composite component. * * @param {ReactElement} element * @final * @internal */ construct: function(element) { // Children can be either an array or more than one argument ReactComponent.Mixin.construct.apply(this, arguments); ReactOwner.Mixin.construct.apply(this, arguments); this.state = null; this._pendingState = null; // This is the public post-processed context. The real context and pending // context lives on the element. this.context = null; this._compositeLifeCycleState = null; }, /** * Checks whether or not this composite component is mounted. * @return {boolean} True if mounted, false otherwise. * @protected * @final */ isMounted: function() { return ReactComponent.Mixin.isMounted.call(this) && this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING; }, /** * Initializes the component, renders markup, and registers event listeners. * * @param {string} rootID DOM ID of the root node. * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction * @param {number} mountDepth number of components in the owner hierarchy * @return {?string} Rendered markup to be inserted into the DOM. * @final * @internal */ mountComponent: ReactPerf.measure( 'ReactCompositeComponent', 'mountComponent', function(rootID, transaction, mountDepth) { ReactComponent.Mixin.mountComponent.call( this, rootID, transaction, mountDepth ); this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING; if (this.__reactAutoBindMap) { this._bindAutoBindMethods(); } this.context = this._processContext(this._currentElement._context); this.props = this._processProps(this.props); this.state = this.getInitialState ? this.getInitialState() : null; ("production" !== process.env.NODE_ENV ? invariant( typeof this.state === 'object' && !Array.isArray(this.state), '%s.getInitialState(): must return an object or null', this.constructor.displayName || 'ReactCompositeComponent' ) : invariant(typeof this.state === 'object' && !Array.isArray(this.state))); this._pendingState = null; this._pendingForceUpdate = false; if (this.componentWillMount) { this.componentWillMount(); // When mounting, calls to `setState` by `componentWillMount` will set // `this._pendingState` without triggering a re-render. if (this._pendingState) { this.state = this._pendingState; this._pendingState = null; } } this._renderedComponent = instantiateReactComponent( this._renderValidatedComponent(), this._currentElement.type // The wrapping type ); // Done with mounting, `setState` will now trigger UI changes. this._compositeLifeCycleState = null; var markup = this._renderedComponent.mountComponent( rootID, transaction, mountDepth + 1 ); if (this.componentDidMount) { transaction.getReactMountReady().enqueue(this.componentDidMount, this); } return markup; } ), /** * Releases any resources allocated by `mountComponent`. * * @final * @internal */ unmountComponent: function() { this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING; if (this.componentWillUnmount) { this.componentWillUnmount(); } this._compositeLifeCycleState = null; this._renderedComponent.unmountComponent(); this._renderedComponent = null; ReactComponent.Mixin.unmountComponent.call(this); // Some existing components rely on this.props even after they've been // destroyed (in event handlers). // TODO: this.props = null; // TODO: this.state = null; }, /** * Sets a subset of the state. Always use this or `replaceState` to mutate * state. You should treat `this.state` as immutable. * * There is no guarantee that `this.state` will be immediately updated, so * accessing `this.state` after calling this method may return the old value. * * There is no guarantee that calls to `setState` will run synchronously, * as they may eventually be batched together. You can provide an optional * callback that will be executed when the call to setState is actually * completed. * * @param {object} partialState Next partial state to be merged with state. * @param {?function} callback Called after state is updated. * @final * @protected */ setState: function(partialState, callback) { ("production" !== process.env.NODE_ENV ? invariant( typeof partialState === 'object' || partialState == null, 'setState(...): takes an object of state variables to update.' ) : invariant(typeof partialState === 'object' || partialState == null)); if ("production" !== process.env.NODE_ENV){ ("production" !== process.env.NODE_ENV ? warning( partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().' ) : null); } // Merge with `_pendingState` if it exists, otherwise with existing state. this.replaceState( assign({}, this._pendingState || this.state, partialState), callback ); }, /** * Replaces all of the state. Always use this or `setState` to mutate state. * You should treat `this.state` as immutable. * * There is no guarantee that `this.state` will be immediately updated, so * accessing `this.state` after calling this method may return the old value. * * @param {object} completeState Next state. * @param {?function} callback Called after state is updated. * @final * @protected */ replaceState: function(completeState, callback) { validateLifeCycleOnReplaceState(this); this._pendingState = completeState; if (this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING) { // If we're in a componentWillMount handler, don't enqueue a rerender // because ReactUpdates assumes we're in a browser context (which is wrong // for server rendering) and we're about to do a render anyway. // TODO: The callback here is ignored when setState is called from // componentWillMount. Either fix it or disallow doing so completely in // favor of getInitialState. ReactUpdates.enqueueUpdate(this, callback); } }, /** * Filters the context object to only contain keys specified in * `contextTypes`, and asserts that they are valid. * * @param {object} context * @return {?object} * @private */ _processContext: function(context) { var maskedContext = null; var contextTypes = this.constructor.contextTypes; if (contextTypes) { maskedContext = {}; for (var contextName in contextTypes) { maskedContext[contextName] = context[contextName]; } if ("production" !== process.env.NODE_ENV) { this._checkPropTypes( contextTypes, maskedContext, ReactPropTypeLocations.context ); } } return maskedContext; }, /** * @param {object} currentContext * @return {object} * @private */ _processChildContext: function(currentContext) { var childContext = this.getChildContext && this.getChildContext(); var displayName = this.constructor.displayName || 'ReactCompositeComponent'; if (childContext) { ("production" !== process.env.NODE_ENV ? invariant( typeof this.constructor.childContextTypes === 'object', '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', displayName ) : invariant(typeof this.constructor.childContextTypes === 'object')); if ("production" !== process.env.NODE_ENV) { this._checkPropTypes( this.constructor.childContextTypes, childContext, ReactPropTypeLocations.childContext ); } for (var name in childContext) { ("production" !== process.env.NODE_ENV ? invariant( name in this.constructor.childContextTypes, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', displayName, name ) : invariant(name in this.constructor.childContextTypes)); } return assign({}, currentContext, childContext); } return currentContext; }, /** * Processes props by setting default values for unspecified props and * asserting that the props are valid. Does not mutate its argument; returns * a new props object with defaults merged in. * * @param {object} newProps * @return {object} * @private */ _processProps: function(newProps) { if ("production" !== process.env.NODE_ENV) { var propTypes = this.constructor.propTypes; if (propTypes) { this._checkPropTypes(propTypes, newProps, ReactPropTypeLocations.prop); } } return newProps; }, /** * Assert that the props are valid * * @param {object} propTypes Map of prop name to a ReactPropType * @param {object} props * @param {string} location e.g. "prop", "context", "child context" * @private */ _checkPropTypes: function(propTypes, props, location) { // TODO: Stop validating prop types here and only use the element // validation. var componentName = this.constructor.displayName; for (var propName in propTypes) { if (propTypes.hasOwnProperty(propName)) { var error = propTypes[propName](props, propName, componentName, location); if (error instanceof Error) { // We may want to extend this logic for similar errors in // renderComponent calls, so I'm abstracting it away into // a function to minimize refactoring in the future var addendum = getDeclarationErrorAddendum(this); ("production" !== process.env.NODE_ENV ? warning(false, error.message + addendum) : null); } } } }, /** * If any of `_pendingElement`, `_pendingState`, or `_pendingForceUpdate` * is set, update the component. * * @param {ReactReconcileTransaction} transaction * @internal */ performUpdateIfNecessary: function(transaction) { var compositeLifeCycleState = this._compositeLifeCycleState; // Do not trigger a state transition if we are in the middle of mounting or // receiving props because both of those will already be doing this. if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING || compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) { return; } if (this._pendingElement == null && this._pendingState == null && !this._pendingForceUpdate) { return; } var nextContext = this.context; var nextProps = this.props; var nextElement = this._currentElement; if (this._pendingElement != null) { nextElement = this._pendingElement; nextContext = this._processContext(nextElement._context); nextProps = this._processProps(nextElement.props); this._pendingElement = null; this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS; if (this.componentWillReceiveProps) { this.componentWillReceiveProps(nextProps, nextContext); } } this._compositeLifeCycleState = null; var nextState = this._pendingState || this.state; this._pendingState = null; var shouldUpdate = this._pendingForceUpdate || !this.shouldComponentUpdate || this.shouldComponentUpdate(nextProps, nextState, nextContext); if ("production" !== process.env.NODE_ENV) { if (typeof shouldUpdate === "undefined") { console.warn( (this.constructor.displayName || 'ReactCompositeComponent') + '.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.' ); } } if (shouldUpdate) { this._pendingForceUpdate = false; // Will set `this.props`, `this.state` and `this.context`. this._performComponentUpdate( nextElement, nextProps, nextState, nextContext, transaction ); } else { // If it's determined that a component should not update, we still want // to set props and state. this._currentElement = nextElement; this.props = nextProps; this.state = nextState; this.context = nextContext; // Owner cannot change because shouldUpdateReactComponent doesn't allow // it. TODO: Remove this._owner completely. this._owner = nextElement._owner; } }, /** * Merges new props and state, notifies delegate methods of update and * performs update. * * @param {ReactElement} nextElement Next element * @param {object} nextProps Next public object to set as properties. * @param {?object} nextState Next object to set as state. * @param {?object} nextContext Next public object to set as context. * @param {ReactReconcileTransaction} transaction * @private */ _performComponentUpdate: function( nextElement, nextProps, nextState, nextContext, transaction ) { var prevElement = this._currentElement; var prevProps = this.props; var prevState = this.state; var prevContext = this.context; if (this.componentWillUpdate) { this.componentWillUpdate(nextProps, nextState, nextContext); } this._currentElement = nextElement; this.props = nextProps; this.state = nextState; this.context = nextContext; // Owner cannot change because shouldUpdateReactComponent doesn't allow // it. TODO: Remove this._owner completely. this._owner = nextElement._owner; this.updateComponent( transaction, prevElement ); if (this.componentDidUpdate) { transaction.getReactMountReady().enqueue( this.componentDidUpdate.bind(this, prevProps, prevState, prevContext), this ); } }, receiveComponent: function(nextElement, transaction) { if (nextElement === this._currentElement && nextElement._owner != null) { // Since elements are immutable after the owner is rendered, // we can do a cheap identity compare here to determine if this is a // superfluous reconcile. It's possible for state to be mutable but such // change should trigger an update of the owner which would recreate // the element. We explicitly check for the existence of an owner since // it's possible for a element created outside a composite to be // deeply mutated and reused. return; } ReactComponent.Mixin.receiveComponent.call( this, nextElement, transaction ); }, /** * Updates the component's currently mounted DOM representation. * * By default, this implements React's rendering and reconciliation algorithm. * Sophisticated clients may wish to override this. * * @param {ReactReconcileTransaction} transaction * @param {ReactElement} prevElement * @internal * @overridable */ updateComponent: ReactPerf.measure( 'ReactCompositeComponent', 'updateComponent', function(transaction, prevParentElement) { ReactComponent.Mixin.updateComponent.call( this, transaction, prevParentElement ); var prevComponentInstance = this._renderedComponent; var prevElement = prevComponentInstance._currentElement; var nextElement = this._renderValidatedComponent(); if (shouldUpdateReactComponent(prevElement, nextElement)) { prevComponentInstance.receiveComponent(nextElement, transaction); } else { // These two IDs are actually the same! But nothing should rely on that. var thisID = this._rootNodeID; var prevComponentID = prevComponentInstance._rootNodeID; prevComponentInstance.unmountComponent(); this._renderedComponent = instantiateReactComponent( nextElement, this._currentElement.type ); var nextMarkup = this._renderedComponent.mountComponent( thisID, transaction, this._mountDepth + 1 ); ReactComponent.BackendIDOperations.dangerouslyReplaceNodeWithMarkupByID( prevComponentID, nextMarkup ); } } ), /** * Forces an update. This should only be invoked when it is known with * certainty that we are **not** in a DOM transaction. * * You may want to call this when you know that some deeper aspect of the * component's state has changed but `setState` was not called. * * This will not invoke `shouldUpdateComponent`, but it will invoke * `componentWillUpdate` and `componentDidUpdate`. * * @param {?function} callback Called after update is complete. * @final * @protected */ forceUpdate: function(callback) { var compositeLifeCycleState = this._compositeLifeCycleState; ("production" !== process.env.NODE_ENV ? invariant( this.isMounted() || compositeLifeCycleState === CompositeLifeCycle.MOUNTING, 'forceUpdate(...): Can only force an update on mounted or mounting ' + 'components.' ) : invariant(this.isMounted() || compositeLifeCycleState === CompositeLifeCycle.MOUNTING)); ("production" !== process.env.NODE_ENV ? invariant( compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING && ReactCurrentOwner.current == null, 'forceUpdate(...): Cannot force an update while unmounting component ' + 'or within a `render` function.' ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING && ReactCurrentOwner.current == null)); this._pendingForceUpdate = true; ReactUpdates.enqueueUpdate(this, callback); }, /** * @private */ _renderValidatedComponent: ReactPerf.measure( 'ReactCompositeComponent', '_renderValidatedComponent', function() { var renderedComponent; var previousContext = ReactContext.current; ReactContext.current = this._processChildContext( this._currentElement._context ); ReactCurrentOwner.current = this; try { renderedComponent = this.render(); if (renderedComponent === null || renderedComponent === false) { renderedComponent = ReactEmptyComponent.getEmptyComponent(); ReactEmptyComponent.registerNullComponentID(this._rootNodeID); } else { ReactEmptyComponent.deregisterNullComponentID(this._rootNodeID); } } finally { ReactContext.current = previousContext; ReactCurrentOwner.current = null; } ("production" !== process.env.NODE_ENV ? invariant( ReactElement.isValidElement(renderedComponent), '%s.render(): A valid ReactComponent must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', this.constructor.displayName || 'ReactCompositeComponent' ) : invariant(ReactElement.isValidElement(renderedComponent))); return renderedComponent; } ), /** * @private */ _bindAutoBindMethods: function() { for (var autoBindKey in this.__reactAutoBindMap) { if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { continue; } var method = this.__reactAutoBindMap[autoBindKey]; this[autoBindKey] = this._bindAutoBindMethod(ReactErrorUtils.guard( method, this.constructor.displayName + '.' + autoBindKey )); } }, /** * Binds a method to the component. * * @param {function} method Method to be bound. * @private */ _bindAutoBindMethod: function(method) { var component = this; var boundMethod = method.bind(component); if ("production" !== process.env.NODE_ENV) { boundMethod.__reactBoundContext = component; boundMethod.__reactBoundMethod = method; boundMethod.__reactBoundArguments = null; var componentName = component.constructor.displayName; var _bind = boundMethod.bind; boundMethod.bind = function(newThis ) {var args=Array.prototype.slice.call(arguments,1); // User is trying to bind() an autobound method; we effectively will // ignore the value of "this" that the user is trying to use, so // let's warn. if (newThis !== component && newThis !== null) { monitorCodeUse('react_bind_warning', { component: componentName }); console.warn( 'bind(): React component methods may only be bound to the ' + 'component instance. See ' + componentName ); } else if (!args.length) { monitorCodeUse('react_bind_warning', { component: componentName }); console.warn( 'bind(): You are binding a component method to the component. ' + 'React does this for you automatically in a high-performance ' + 'way, so you can safely remove this call. See ' + componentName ); return boundMethod; } var reboundMethod = _bind.apply(boundMethod, arguments); reboundMethod.__reactBoundContext = component; reboundMethod.__reactBoundMethod = method; reboundMethod.__reactBoundArguments = args; return reboundMethod; }; } return boundMethod; } }; var ReactCompositeComponentBase = function() {}; assign( ReactCompositeComponentBase.prototype, ReactComponent.Mixin, ReactOwner.Mixin, ReactPropTransferer.Mixin, ReactCompositeComponentMixin ); /** * Module for creating composite components. * * @class ReactCompositeComponent * @extends ReactComponent * @extends ReactOwner * @extends ReactPropTransferer */ var ReactCompositeComponent = { LifeCycle: CompositeLifeCycle, Base: ReactCompositeComponentBase, /** * Creates a composite component class given a class specification. * * @param {object} spec Class specification (which must define `render`). * @return {function} Component constructor function. * @public */ createClass: function(spec) { var Constructor = function(props) { // This constructor is overridden by mocks. The argument is used // by mocks to assert on what gets mounted. This will later be used // by the stand-alone class implementation. }; Constructor.prototype = new ReactCompositeComponentBase(); Constructor.prototype.constructor = Constructor; injectedMixins.forEach( mixSpecIntoComponent.bind(null, Constructor) ); mixSpecIntoComponent(Constructor, spec); // Initialize the defaultProps property after all mixins have been merged if (Constructor.getDefaultProps) { Constructor.defaultProps = Constructor.getDefaultProps(); } ("production" !== process.env.NODE_ENV ? invariant( Constructor.prototype.render, 'createClass(...): Class specification must implement a `render` method.' ) : invariant(Constructor.prototype.render)); if ("production" !== process.env.NODE_ENV) { if (Constructor.prototype.componentShouldUpdate) { monitorCodeUse( 'react_component_should_update_warning', { component: spec.displayName } ); console.warn( (spec.displayName || 'A component') + ' has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.' ); } } // Reduce time spent doing lookups by setting these on the prototype. for (var methodName in ReactCompositeComponentInterface) { if (!Constructor.prototype[methodName]) { Constructor.prototype[methodName] = null; } } if ("production" !== process.env.NODE_ENV) { return ReactLegacyElement.wrapFactory( ReactElementValidator.createFactory(Constructor) ); } return ReactLegacyElement.wrapFactory( ReactElement.createFactory(Constructor) ); }, injection: { injectMixin: function(mixin) { injectedMixins.push(mixin); } } }; module.exports = ReactCompositeComponent; }).call(this,require('_process')) },{"./Object.assign":70,"./ReactComponent":78,"./ReactContext":82,"./ReactCurrentOwner":83,"./ReactElement":99,"./ReactElementValidator":100,"./ReactEmptyComponent":101,"./ReactErrorUtils":102,"./ReactLegacyElement":108,"./ReactOwner":115,"./ReactPerf":116,"./ReactPropTransferer":117,"./ReactPropTypeLocationNames":118,"./ReactPropTypeLocations":119,"./ReactUpdates":132,"./instantiateReactComponent":181,"./invariant":182,"./keyMirror":188,"./keyOf":189,"./mapObject":190,"./monitorCodeUse":192,"./shouldUpdateReactComponent":198,"./warning":202,"_process":1}],82:[function(require,module,exports){ /** * Copyright 2013-2014, 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. * * @providesModule ReactContext */ "use strict"; var assign = require("./Object.assign"); /** * Keeps track of the current context. * * The context is automatically passed down the component ownership hierarchy * and is accessible via `this.context` on ReactCompositeComponents. */ var ReactContext = { /** * @internal * @type {object} */ current: {}, /** * Temporarily extends the current context while executing scopedCallback. * * A typical use case might look like * * render: function() { * var children = ReactContext.withContext({foo: 'foo'}, () => ( * * )); * return
{children}
; * } * * @param {object} newContext New context to merge into the existing context * @param {function} scopedCallback Callback to run with the new context * @return {ReactComponent|array} */ withContext: function(newContext, scopedCallback) { var result; var previousContext = ReactContext.current; ReactContext.current = assign({}, previousContext, newContext); try { result = scopedCallback(); } finally { ReactContext.current = previousContext; } return result; } }; module.exports = ReactContext; },{"./Object.assign":70}],83:[function(require,module,exports){ /** * Copyright 2013-2014, 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. * * @providesModule ReactCurrentOwner */ "use strict"; /** * Keeps track of the current owner. * * The current owner is the component who should own any components that are * currently being constructed. * * The depth indicate how many composite components are above this render level. */ var ReactCurrentOwner = { /** * @internal * @type {ReactComponent} */ current: null }; module.exports = ReactCurrentOwner; },{}],84:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, 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. * * @providesModule ReactDOM * @typechecks static-only */ "use strict"; var ReactElement = require("./ReactElement"); var ReactElementValidator = require("./ReactElementValidator"); var ReactLegacyElement = require("./ReactLegacyElement"); var mapObject = require("./mapObject"); /** * Create a factory that creates HTML tag elements. * * @param {string} tag Tag name (e.g. `div`). * @private */ function createDOMFactory(tag) { if ("production" !== process.env.NODE_ENV) { return ReactLegacyElement.markNonLegacyFactory( ReactElementValidator.createFactory(tag) ); } return ReactLegacyElement.markNonLegacyFactory( ReactElement.createFactory(tag) ); } /** * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. * This is also accessible via `React.DOM`. * * @public */ var ReactDOM = mapObject({ a: 'a', abbr: 'abbr', address: 'address', area: 'area', article: 'article', aside: 'aside', audio: 'audio', b: 'b', base: 'base', bdi: 'bdi', bdo: 'bdo', big: 'big', blockquote: 'blockquote', body: 'body', br: 'br', button: 'button', canvas: 'canvas', caption: 'caption', cite: 'cite', code: 'code', col: 'col', colgroup: 'colgroup', data: 'data', datalist: 'datalist', dd: 'dd', del: 'del', details: 'details', dfn: 'dfn', dialog: 'dialog', div: 'div', dl: 'dl', dt: 'dt', em: 'em', embed: 'embed', fieldset: 'fieldset', figcaption: 'figcaption', figure: 'figure', footer: 'footer', form: 'form', h1: 'h1', h2: 'h2', h3: 'h3', h4: 'h4', h5: 'h5', h6: 'h6', head: 'head', header: 'header', hr: 'hr', html: 'html', i: 'i', iframe: 'iframe', img: 'img', input: 'input', ins: 'ins', kbd: 'kbd', keygen: 'keygen', label: 'label', legend: 'legend', li: 'li', link: 'link', main: 'main', map: 'map', mark: 'mark', menu: 'menu', menuitem: 'menuitem', meta: 'meta', meter: 'meter', nav: 'nav', noscript: 'noscript', object: 'object', ol: 'ol', optgroup: 'optgroup', option: 'option', output: 'output', p: 'p', param: 'param', picture: 'picture', pre: 'pre', progress: 'progress', q: 'q', rp: 'rp', rt: 'rt', ruby: 'ruby', s: 's', samp: 'samp', script: 'script', section: 'section', select: 'select', small: 'small', source: 'source', span: 'span', strong: 'strong', style: 'style', sub: 'sub', summary: 'summary', sup: 'sup', table: 'table', tbody: 'tbody', td: 'td', textarea: 'textarea', tfoot: 'tfoot', th: 'th', thead: 'thead', time: 'time', title: 'title', tr: 'tr', track: 'track', u: 'u', ul: 'ul', 'var': 'var', video: 'video', wbr: 'wbr', // SVG circle: 'circle', defs: 'defs', ellipse: 'ellipse', g: 'g', line: 'line', linearGradient: 'linearGradient', mask: 'mask', path: 'path', pattern: 'pattern', polygon: 'polygon', polyline: 'polyline', radialGradient: 'radialGradient', rect: 'rect', stop: 'stop', svg: 'svg', text: 'text', tspan: 'tspan' }, createDOMFactory); module.exports = ReactDOM; }).call(this,require('_process')) },{"./ReactElement":99,"./ReactElementValidator":100,"./ReactLegacyElement":108,"./mapObject":190,"_process":1}],85:[function(require,module,exports){ /** * Copyright 2013-2014, 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. * * @providesModule ReactDOMButton */ "use strict"; var AutoFocusMixin = require("./AutoFocusMixin"); var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); var ReactCompositeComponent = require("./ReactCompositeComponent"); var ReactElement = require("./ReactElement"); var ReactDOM = require("./ReactDOM"); var keyMirror = require("./keyMirror"); // Store a reference to the