diff --git a/docs/_config.yml b/docs/_config.yml index f14db0ba7b..ae6de3dda0 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -36,13 +36,13 @@ sass: sass_dir: _css gems: - jekyll-redirect-from -react_version: 0.14.7 +react_version: 15.0.0 react_hashes: - dev: xQae1pUPdAKUe0u0KUTNt09zzdwheX4VSUsV8vatqM+t6X7rta01qOzessL808ox - prod: zTm/dblzLXQNp3CgY+hfaC/WJ6h4XtNrePh2CW2+rO9GPuNiPb9jmthvAL+oI/dQ - addons_dev: I5TF2q2QDmB31aN5lcClArdUo+WJH/Yi3hcH3PBVXFe5DYtYCFh7Jx/dmpba12zn - addons_prod: KPHTQfiYMhtsIRbZcY4ri1lBYZQbj4ePsSdzODR2Bu5L5ts3APVyqwKPBThO5Hgc - dom_dev: A1t0GCrR06cTHvMjaxeSE8XOiz6j7NvWdmxhN/9z748wEvJTVk13Rr8gMzTUnd8G - dom_prod: ntqCsHbLdMxT352UbhPbT7fqjE8xi4jLmQYQa8mYR+ylAapbXRfdsDweueDObf7m - dom_server_dev: 3I5+eGB/ILYa6pQQX+rM9O0SyDltamM40RiZ5JvIijSYEfVGZU0vY4Iwx9a1eYyD - dom_server_prod: Kt9dEqXzv00orFPW2o3H+kxQtSiNO8EqXsXJT3i99rCcp74N/Km98V0kUxAzy44k + dev: Cq98Gnp/9Q99TFfuPlSLebblQc+9qMrZtWD0FCe4s7GUZxPiQs3xrnDfXGa4ViyS + prod: 9BYbHhdnftnl0BXeFq2Vu9/Q4PbgcQEzhgGVV+AdFn45HLRsjIt7quhJDydhEhXy + addons_dev: Qztew90JWMrd/+bXguDKMh+COfzS4qdH8OErl+vquQj4AUkbHVmLuhrvSYMt0vMP + addons_prod: MKtYvu68gr8fPQLs3JN5YEdJWxG31GD1kTLWu/bdTs+c5PzBVqGtiOT7zPREK/G8 + dom_dev: WsglX3Pa1NYQZilMa8GLvlqA5nD7k1WkNmpEHgGxsVvwkb8jVAe9Xyk2FkusiMXH + dom_prod: UAMUzFqVISGZygGa8Jiue1c43+A/XIz5Vqo/nhhQ+nDxFYvWtiHF88BDiqUdQeEl + dom_server_dev: WTVIOMLvdH0B5Ci5GizQ6EijmhJ42lwT9AlLpxjvRxWNgAqBye3+CQjap+v3IvAn + dom_server_prod: lYJlraCIcrpyivOoXRj6kFa1mPZndbT5R2Hjq70IPkxwL1MxcGOxg+14bWolaeWs diff --git a/docs/downloads/react-15.0.0.zip b/docs/downloads/react-15.0.0.zip new file mode 100644 index 0000000000..05503065e3 Binary files /dev/null and b/docs/downloads/react-15.0.0.zip differ diff --git a/docs/js/react-dom.js b/docs/js/react-dom.js index 117e1393c6..cf146b5e08 100644 --- a/docs/js/react-dom.js +++ b/docs/js/react-dom.js @@ -1,7 +1,7 @@ /** - * ReactDOM v0.14.7 + * ReactDOM v15.0.0 * - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the diff --git a/docs/js/react.js b/docs/js/react.js index b8c9f67553..4d02463462 100644 --- a/docs/js/react.js +++ b/docs/js/react.js @@ -1,50 +1,9 @@ /** - * React v0.14.7 + * React v15.0.0 */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.React = f()}})(function(){var define,module,exports;return (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 -1) { - warnHyphenatedStyleName(name); + warnHyphenatedStyleName(name, owner); } else if (badVendoredStyleNamePattern.test(name)) { - warnBadVendoredStyleName(name); + warnBadVendoredStyleName(name, owner); } else if (badStyleValueWithSemicolonPattern.test(value)) { - warnStyleValueWithSemicolon(name, value); + warnStyleValueWithSemicolon(name, value, owner); + } + + if (typeof value === 'number' && isNaN(value)) { + warnStyleValueIsNaN(name, value, owner); } }; } @@ -737,9 +704,10 @@ var CSSPropertyOperations = { * The result should be HTML-escaped before insertion into the DOM. * * @param {object} styles + * @param {ReactDOMComponent} component * @return {?string} */ - createMarkupForStyles: function (styles) { + createMarkupForStyles: function (styles, component) { var serialized = ''; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { @@ -747,11 +715,11 @@ var CSSPropertyOperations = { } var styleValue = styles[styleName]; if ("development" !== 'production') { - warnValidStyle(styleName, styleValue); + warnValidStyle(styleName, styleValue, component); } if (styleValue != null) { serialized += processStyleName(styleName) + ':'; - serialized += dangerousStyleValue(styleName, styleValue) + ';'; + serialized += dangerousStyleValue(styleName, styleValue, component) + ';'; } } return serialized || null; @@ -763,18 +731,19 @@ var CSSPropertyOperations = { * * @param {DOMElement} node * @param {object} styles + * @param {ReactDOMComponent} component */ - setValueForStyles: function (node, styles) { + setValueForStyles: function (node, styles, component) { var style = node.style; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } if ("development" !== 'production') { - warnValidStyle(styleName, styles[styleName]); + warnValidStyle(styleName, styles[styleName], component); } - var styleValue = dangerousStyleValue(styleName, styles[styleName]); - if (styleName === 'float') { + var styleValue = dangerousStyleValue(styleName, styles[styleName], component); + if (styleName === 'float' || styleName === 'cssFloat') { styleName = styleFloatAccessor; } if (styleValue) { @@ -801,9 +770,9 @@ ReactPerf.measureMethods(CSSPropertyOperations, 'CSSPropertyOperations', { }); module.exports = CSSPropertyOperations; -},{"105":105,"130":130,"132":132,"143":143,"150":150,"155":155,"4":4,"71":71}],6:[function(_dereq_,module,exports){ +},{"116":116,"142":142,"144":144,"155":155,"162":162,"166":166,"3":3,"80":80}],5:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -815,10 +784,11 @@ module.exports = CSSPropertyOperations; 'use strict'; -var PooledClass = _dereq_(24); +var _assign = _dereq_(167); -var assign = _dereq_(23); -var invariant = _dereq_(144); +var PooledClass = _dereq_(23); + +var invariant = _dereq_(156); /** * A specialized pseudo-event module to help keep track of components waiting to @@ -836,7 +806,7 @@ function CallbackQueue() { this._contexts = null; } -assign(CallbackQueue.prototype, { +_assign(CallbackQueue.prototype, { /** * Enqueues a callback to be invoked when `notifyAll` is invoked. @@ -862,7 +832,7 @@ assign(CallbackQueue.prototype, { var callbacks = this._callbacks; var contexts = this._contexts; if (callbacks) { - !(callbacks.length === contexts.length) ? "development" !== 'production' ? invariant(false, 'Mismatched list of contexts in callback queue') : invariant(false) : undefined; + !(callbacks.length === contexts.length) ? "development" !== 'production' ? invariant(false, 'Mismatched list of contexts in callback queue') : invariant(false) : void 0; this._callbacks = null; this._contexts = null; for (var i = 0; i < callbacks.length; i++) { @@ -873,6 +843,17 @@ assign(CallbackQueue.prototype, { } }, + checkpoint: function () { + return this._callbacks ? this._callbacks.length : 0; + }, + + rollback: function (len) { + if (this._callbacks) { + this._callbacks.length = len; + this._contexts.length = len; + } + }, + /** * Resets the internal queue. * @@ -895,9 +876,9 @@ assign(CallbackQueue.prototype, { PooledClass.addPoolingTo(CallbackQueue); module.exports = CallbackQueue; -},{"144":144,"23":23,"24":24}],7:[function(_dereq_,module,exports){ +},{"156":156,"167":167,"23":23}],6:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -912,14 +893,15 @@ module.exports = CallbackQueue; var EventConstants = _dereq_(15); var EventPluginHub = _dereq_(16); var EventPropagators = _dereq_(19); -var ExecutionEnvironment = _dereq_(130); -var ReactUpdates = _dereq_(83); -var SyntheticEvent = _dereq_(92); +var ExecutionEnvironment = _dereq_(142); +var ReactDOMComponentTree = _dereq_(38); +var ReactUpdates = _dereq_(92); +var SyntheticEvent = _dereq_(101); -var getEventTarget = _dereq_(114); -var isEventSupported = _dereq_(119); -var isTextInputElement = _dereq_(120); -var keyOf = _dereq_(148); +var getEventTarget = _dereq_(124); +var isEventSupported = _dereq_(131); +var isTextInputElement = _dereq_(132); +var keyOf = _dereq_(160); var topLevelTypes = EventConstants.topLevelTypes; @@ -937,7 +919,7 @@ var eventTypes = { * For IE shims */ var activeElement = null; -var activeElementID = null; +var activeElementInst = null; var activeElementValue = null; var activeElementValueProp = null; @@ -956,7 +938,7 @@ if (ExecutionEnvironment.canUseDOM) { } function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled(eventTypes.change, activeElementID, nativeEvent, getEventTarget(nativeEvent)); + var event = SyntheticEvent.getPooled(eventTypes.change, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); EventPropagators.accumulateTwoPhaseDispatches(event); // If change and propertychange bubbled, we'd just bind to it like all the @@ -978,9 +960,9 @@ function runEventInBatch(event) { EventPluginHub.processEventQueue(false); } -function startWatchingForChangeEventIE8(target, targetID) { +function startWatchingForChangeEventIE8(target, targetInst) { activeElement = target; - activeElementID = targetID; + activeElementInst = targetInst; activeElement.attachEvent('onchange', manualDispatchChangeEvent); } @@ -990,20 +972,20 @@ function stopWatchingForChangeEventIE8() { } activeElement.detachEvent('onchange', manualDispatchChangeEvent); activeElement = null; - activeElementID = null; + activeElementInst = null; } -function getTargetIDForChangeEvent(topLevelType, topLevelTarget, topLevelTargetID) { +function getTargetInstForChangeEvent(topLevelType, targetInst) { if (topLevelType === topLevelTypes.topChange) { - return topLevelTargetID; + return targetInst; } } -function handleEventsForChangeEventIE8(topLevelType, topLevelTarget, topLevelTargetID) { +function handleEventsForChangeEventIE8(topLevelType, target, targetInst) { 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); + startWatchingForChangeEventIE8(target, targetInst); } else if (topLevelType === topLevelTypes.topBlur) { stopWatchingForChangeEventIE8(); } @@ -1015,12 +997,14 @@ function handleEventsForChangeEventIE8(topLevelType, topLevelTarget, topLevelTar 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); + // deleting text, so we ignore its input events. + // IE10+ fire input events to often, such when a placeholder + // changes or when an input with a placeholder is focused. + isInputEventSupported = isEventSupported('input') && (!('documentMode' in document) || document.documentMode > 11); } /** - * (For old IE.) Replacement getter/setter for the `value` property that gets + * (For IE <=11) Replacement getter/setter for the `value` property that gets * set on the active element. */ var newValueProp = { @@ -1035,24 +1019,28 @@ var newValueProp = { }; /** - * (For old IE.) Starts tracking propertychange events on the passed-in element + * (For IE <=11) 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) { +function startWatchingForValueChange(target, targetInst) { activeElement = target; - activeElementID = targetID; + activeElementInst = targetInst; activeElementValue = target.value; activeElementValueProp = Object.getOwnPropertyDescriptor(target.constructor.prototype, 'value'); // Not guarded in a canDefineProperty check: IE8 supports defineProperty only // on DOM elements Object.defineProperty(activeElement, 'value', newValueProp); - activeElement.attachEvent('onpropertychange', handlePropertyChange); + if (activeElement.attachEvent) { + activeElement.attachEvent('onpropertychange', handlePropertyChange); + } else { + activeElement.addEventListener('propertychange', handlePropertyChange, false); + } } /** - * (For old IE.) Removes the event listeners from the currently-tracked element, + * (For IE <=11) Removes the event listeners from the currently-tracked element, * if any exists. */ function stopWatchingForValueChange() { @@ -1062,16 +1050,21 @@ function stopWatchingForValueChange() { // delete restores the original property definition delete activeElement.value; - activeElement.detachEvent('onpropertychange', handlePropertyChange); + + if (activeElement.detachEvent) { + activeElement.detachEvent('onpropertychange', handlePropertyChange); + } else { + activeElement.removeEventListener('propertychange', handlePropertyChange, false); + } activeElement = null; - activeElementID = null; + activeElementInst = null; activeElementValue = null; activeElementValueProp = null; } /** - * (For old IE.) Handles a propertychange event, sending a `change` event if + * (For IE <=11) Handles a propertychange event, sending a `change` event if * the value of the active element has changed. */ function handlePropertyChange(nativeEvent) { @@ -1090,21 +1083,20 @@ function handlePropertyChange(nativeEvent) { /** * If a `change` event should be fired, returns the target's ID. */ -function getTargetIDForInputEvent(topLevelType, topLevelTarget, topLevelTargetID) { +function getTargetInstForInputEvent(topLevelType, targetInst) { 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; + return targetInst; } } -// For IE8 and IE9. -function handleEventsForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) { +function handleEventsForInputEventIE(topLevelType, target, targetInst) { 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 + // In IE9-11, 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 @@ -1115,14 +1107,14 @@ function handleEventsForInputEventIE(topLevelType, topLevelTarget, topLevelTarge // stopWatching() should be a noop here but we call it just in case we // missed a blur event somehow. stopWatchingForValueChange(); - startWatchingForValueChange(topLevelTarget, topLevelTargetID); + startWatchingForValueChange(target, targetInst); } else if (topLevelType === topLevelTypes.topBlur) { stopWatchingForValueChange(); } } // For IE8 and IE9. -function getTargetIDForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) { +function getTargetInstForInputEventIE(topLevelType, targetInst) { 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. @@ -1136,7 +1128,7 @@ function getTargetIDForInputEventIE(topLevelType, topLevelTarget, topLevelTarget // fire selectionchange normally. if (activeElement && activeElement.value !== activeElementValue) { activeElementValue = activeElement.value; - return activeElementID; + return activeElementInst; } } } @@ -1151,9 +1143,9 @@ function shouldUseClickEvent(elem) { return elem.nodeName && elem.nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); } -function getTargetIDForClickEvent(topLevelType, topLevelTarget, topLevelTargetID) { +function getTargetInstForClickEvent(topLevelType, targetInst) { if (topLevelType === topLevelTypes.topClick) { - return topLevelTargetID; + return targetInst; } } @@ -1171,38 +1163,31 @@ 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, nativeEventTarget) { + extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { + var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window; - var getTargetIDFunc, handleEventFunc; - if (shouldUseChangeEvent(topLevelTarget)) { + var getTargetInstFunc, handleEventFunc; + if (shouldUseChangeEvent(targetNode)) { if (doesChangeEventBubble) { - getTargetIDFunc = getTargetIDForChangeEvent; + getTargetInstFunc = getTargetInstForChangeEvent; } else { handleEventFunc = handleEventsForChangeEventIE8; } - } else if (isTextInputElement(topLevelTarget)) { + } else if (isTextInputElement(targetNode)) { if (isInputEventSupported) { - getTargetIDFunc = getTargetIDForInputEvent; + getTargetInstFunc = getTargetInstForInputEvent; } else { - getTargetIDFunc = getTargetIDForInputEventIE; + getTargetInstFunc = getTargetInstForInputEventIE; handleEventFunc = handleEventsForInputEventIE; } - } else if (shouldUseClickEvent(topLevelTarget)) { - getTargetIDFunc = getTargetIDForClickEvent; + } else if (shouldUseClickEvent(targetNode)) { + getTargetInstFunc = getTargetInstForClickEvent; } - if (getTargetIDFunc) { - var targetID = getTargetIDFunc(topLevelType, topLevelTarget, topLevelTargetID); - if (targetID) { - var event = SyntheticEvent.getPooled(eventTypes.change, targetID, nativeEvent, nativeEventTarget); + if (getTargetInstFunc) { + var inst = getTargetInstFunc(topLevelType, targetInst); + if (inst) { + var event = SyntheticEvent.getPooled(eventTypes.change, inst, nativeEvent, nativeEventTarget); event.type = 'change'; EventPropagators.accumulateTwoPhaseDispatches(event); return event; @@ -1210,40 +1195,16 @@ var ChangeEventPlugin = { } if (handleEventFunc) { - handleEventFunc(topLevelType, topLevelTarget, topLevelTargetID); + handleEventFunc(topLevelType, targetNode, targetInst); } } }; module.exports = ChangeEventPlugin; -},{"114":114,"119":119,"120":120,"130":130,"148":148,"15":15,"16":16,"19":19,"83":83,"92":92}],8:[function(_dereq_,module,exports){ +},{"101":101,"124":124,"131":131,"132":132,"142":142,"15":15,"16":16,"160":160,"19":19,"38":38,"92":92}],7:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, 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; -},{}],9:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -1251,18 +1212,27 @@ module.exports = ClientReactRootIndex; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule DOMChildrenOperations - * @typechecks static-only */ 'use strict'; +var DOMLazyTree = _dereq_(8); var Danger = _dereq_(12); -var ReactMultiChildUpdateTypes = _dereq_(67); -var ReactPerf = _dereq_(71); +var ReactMultiChildUpdateTypes = _dereq_(75); +var ReactPerf = _dereq_(80); -var setInnerHTML = _dereq_(124); -var setTextContent = _dereq_(125); -var invariant = _dereq_(144); +var createMicrosoftUnsafeLocalFunction = _dereq_(115); +var setInnerHTML = _dereq_(136); +var setTextContent = _dereq_(137); + +function getNodeAfter(parentNode, node) { + // Special case for text components, which return [open, close] comments + // from getNativeNode. + if (Array.isArray(node)) { + node = node[1]; + } + return node ? node.nextSibling : parentNode.firstChild; +} /** * Inserts `childNode` as a child of `parentNode` at the `index`. @@ -1272,17 +1242,78 @@ var invariant = _dereq_(144); * @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`. +var insertChildAt = createMicrosoftUnsafeLocalFunction(function (parentNode, childNode, referenceNode) { + // We rely exclusively on `insertBefore(node, null)` instead of also using + // `appendChild(node)`. (Using `undefined` is not allowed by all browsers so + // we are careful to use `null`.) + parentNode.insertBefore(childNode, referenceNode); +}); - // fix render order error in safari - // IE8 will throw error when index out of list size. - var beforeChild = index >= parentNode.childNodes.length ? null : parentNode.childNodes.item(index); +function insertLazyTreeChildAt(parentNode, childTree, referenceNode) { + DOMLazyTree.insertTreeBefore(parentNode, childTree, referenceNode); +} - parentNode.insertBefore(childNode, beforeChild); +function moveChild(parentNode, childNode, referenceNode) { + if (Array.isArray(childNode)) { + moveDelimitedText(parentNode, childNode[0], childNode[1], referenceNode); + } else { + insertChildAt(parentNode, childNode, referenceNode); + } +} + +function removeChild(parentNode, childNode) { + if (Array.isArray(childNode)) { + var closingComment = childNode[1]; + childNode = childNode[0]; + removeDelimitedText(parentNode, childNode, closingComment); + parentNode.removeChild(closingComment); + } + parentNode.removeChild(childNode); +} + +function moveDelimitedText(parentNode, openingComment, closingComment, referenceNode) { + var node = openingComment; + while (true) { + var nextNode = node.nextSibling; + insertChildAt(parentNode, node, referenceNode); + if (node === closingComment) { + break; + } + node = nextNode; + } +} + +function removeDelimitedText(parentNode, startNode, closingComment) { + while (true) { + var node = startNode.nextSibling; + if (node === closingComment) { + // The closing comment is removed by ReactMultiChild. + break; + } else { + parentNode.removeChild(node); + } + } +} + +function replaceDelimitedText(openingComment, closingComment, stringText) { + var parentNode = openingComment.parentNode; + var nodeAfterComment = openingComment.nextSibling; + if (nodeAfterComment === closingComment) { + // There are no text nodes between the opening and closing comments; insert + // a new one if stringText isn't empty. + if (stringText) { + insertChildAt(parentNode, document.createTextNode(stringText), nodeAfterComment); + } + } else { + if (stringText) { + // Set the text content of the first node after the opening comment, and + // remove all following nodes up until the closing comment. + setTextContent(nodeAfterComment, stringText); + removeDelimitedText(parentNode, nodeAfterComment, closingComment); + } else { + removeDelimitedText(parentNode, openingComment, closingComment); + } + } } /** @@ -1292,73 +1323,33 @@ var DOMChildrenOperations = { dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, - updateTextContent: setTextContent, + replaceDelimitedText: replaceDelimitedText, /** * 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; i < updates.length; i++) { - update = updates[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; - - !updatedChild ? "development" !== 'production' ? invariant(false, '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(false) : undefined; - - initialChildren = initialChildren || {}; - initialChildren[parentID] = initialChildren[parentID] || []; - initialChildren[parentID][updatedIndex] = updatedChild; - - updatedChildren = updatedChildren || []; - updatedChildren.push(updatedChild); - } - } - - var renderedMarkup; - // markupList is either a list of markup or just a list of elements - if (markupList.length && typeof markupList[0] === 'string') { - renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); - } else { - renderedMarkup = 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]); - } - } - + processUpdates: function (parentNode, updates) { for (var k = 0; k < updates.length; k++) { - update = updates[k]; + var update = updates[k]; switch (update.type) { case ReactMultiChildUpdateTypes.INSERT_MARKUP: - insertChildAt(update.parentNode, renderedMarkup[update.markupIndex], update.toIndex); + insertLazyTreeChildAt(parentNode, update.content, getNodeAfter(parentNode, update.afterNode)); break; case ReactMultiChildUpdateTypes.MOVE_EXISTING: - insertChildAt(update.parentNode, initialChildren[update.parentID][update.fromIndex], update.toIndex); + moveChild(parentNode, update.fromNode, getNodeAfter(parentNode, update.afterNode)); break; case ReactMultiChildUpdateTypes.SET_MARKUP: - setInnerHTML(update.parentNode, update.content); + setInnerHTML(parentNode, update.content); break; case ReactMultiChildUpdateTypes.TEXT_CONTENT: - setTextContent(update.parentNode, update.content); + setTextContent(parentNode, update.content); break; case ReactMultiChildUpdateTypes.REMOVE_NODE: - // Already removed by the for-loop above. + removeChild(parentNode, update.fromNode); break; } } @@ -1367,13 +1358,140 @@ var DOMChildrenOperations = { }; ReactPerf.measureMethods(DOMChildrenOperations, 'DOMChildrenOperations', { - updateTextContent: 'updateTextContent' + replaceDelimitedText: 'replaceDelimitedText' }); module.exports = DOMChildrenOperations; -},{"12":12,"124":124,"125":125,"144":144,"67":67,"71":71}],10:[function(_dereq_,module,exports){ +},{"115":115,"12":12,"136":136,"137":137,"75":75,"8":8,"80":80}],8:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMLazyTree + */ + +'use strict'; + +var createMicrosoftUnsafeLocalFunction = _dereq_(115); +var setTextContent = _dereq_(137); + +/** + * In IE (8-11) and Edge, appending nodes with no children is dramatically + * faster than appending a full subtree, so we essentially queue up the + * .appendChild calls here and apply them so each node is added to its parent + * before any children are added. + * + * In other browsers, doing so is slower or neutral compared to the other order + * (in Firefox, twice as slow) so we only do this inversion in IE. + * + * See https://github.com/spicyj/innerhtml-vs-createelement-vs-clonenode. + */ +var enableLazy = typeof document !== 'undefined' && typeof document.documentMode === 'number' || typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string' && /\bEdge\/\d/.test(navigator.userAgent); + +function insertTreeChildren(tree) { + if (!enableLazy) { + return; + } + var node = tree.node; + var children = tree.children; + if (children.length) { + for (var i = 0; i < children.length; i++) { + insertTreeBefore(node, children[i], null); + } + } else if (tree.html != null) { + node.innerHTML = tree.html; + } else if (tree.text != null) { + setTextContent(node, tree.text); + } +} + +var insertTreeBefore = createMicrosoftUnsafeLocalFunction(function (parentNode, tree, referenceNode) { + // DocumentFragments aren't actually part of the DOM after insertion so + // appending children won't update the DOM. We need to ensure the fragment + // is properly populated first, breaking out of our lazy approach for just + // this level. + if (tree.node.nodeType === 11) { + insertTreeChildren(tree); + parentNode.insertBefore(tree.node, referenceNode); + } else { + parentNode.insertBefore(tree.node, referenceNode); + insertTreeChildren(tree); + } +}); + +function replaceChildWithTree(oldNode, newTree) { + oldNode.parentNode.replaceChild(newTree.node, oldNode); + insertTreeChildren(newTree); +} + +function queueChild(parentTree, childTree) { + if (enableLazy) { + parentTree.children.push(childTree); + } else { + parentTree.node.appendChild(childTree.node); + } +} + +function queueHTML(tree, html) { + if (enableLazy) { + tree.html = html; + } else { + tree.node.innerHTML = html; + } +} + +function queueText(tree, text) { + if (enableLazy) { + tree.text = text; + } else { + setTextContent(tree.node, text); + } +} + +function DOMLazyTree(node) { + return { + node: node, + children: [], + html: null, + text: null + }; +} + +DOMLazyTree.insertTreeBefore = insertTreeBefore; +DOMLazyTree.replaceChildWithTree = replaceChildWithTree; +DOMLazyTree.queueChild = queueChild; +DOMLazyTree.queueHTML = queueHTML; +DOMLazyTree.queueText = queueText; + +module.exports = DOMLazyTree; +},{"115":115,"137":137}],9:[function(_dereq_,module,exports){ +/** + * Copyright 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMNamespaces + */ + +'use strict'; + +var DOMNamespaces = { + html: 'http://www.w3.org/1999/xhtml', + mathml: 'http://www.w3.org/1998/Math/MathML', + svg: 'http://www.w3.org/2000/svg' +}; + +module.exports = DOMNamespaces; +},{}],10:[function(_dereq_,module,exports){ +/** + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -1381,12 +1499,11 @@ module.exports = DOMChildrenOperations; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule DOMProperty - * @typechecks static-only */ 'use strict'; -var invariant = _dereq_(144); +var invariant = _dereq_(156); function checkMask(value, bitmask) { return (value & bitmask) === bitmask; @@ -1397,13 +1514,12 @@ 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, + MUST_USE_PROPERTY: 0x1, + HAS_SIDE_EFFECTS: 0x2, + HAS_BOOLEAN_VALUE: 0x4, + HAS_NUMERIC_VALUE: 0x8, + HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8, + HAS_OVERLOADED_BOOLEAN_VALUE: 0x20, /** * Inject some specialized knowledge about the DOM. This takes a config object @@ -1446,7 +1562,7 @@ var DOMPropertyInjection = { } for (var propName in Properties) { - !!DOMProperty.properties.hasOwnProperty(propName) ? "development" !== 'production' ? invariant(false, '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(false) : undefined; + !!DOMProperty.properties.hasOwnProperty(propName) ? "development" !== 'production' ? invariant(false, '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(false) : void 0; var lowerCased = propName.toLowerCase(); var propConfig = Properties[propName]; @@ -1457,7 +1573,6 @@ var DOMPropertyInjection = { propertyName: propName, mutationMethod: null, - mustUseAttribute: checkMask(propConfig, Injection.MUST_USE_ATTRIBUTE), mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY), hasSideEffects: checkMask(propConfig, Injection.HAS_SIDE_EFFECTS), hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE), @@ -1466,9 +1581,8 @@ var DOMPropertyInjection = { hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE) }; - !(!propertyInfo.mustUseAttribute || !propertyInfo.mustUseProperty) ? "development" !== 'production' ? invariant(false, 'DOMProperty: Cannot require using both attribute and property: %s', propName) : invariant(false) : undefined; - !(propertyInfo.mustUseProperty || !propertyInfo.hasSideEffects) ? "development" !== 'production' ? invariant(false, 'DOMProperty: Properties that have side effects must use property: %s', propName) : invariant(false) : undefined; - !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? "development" !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + 'numeric value, but not a combination: %s', propName) : invariant(false) : undefined; + !(propertyInfo.mustUseProperty || !propertyInfo.hasSideEffects) ? "development" !== 'production' ? invariant(false, 'DOMProperty: Properties that have side effects must use property: %s', propName) : invariant(false) : void 0; + !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? "development" !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + 'numeric value, but not a combination: %s', propName) : invariant(false) : void 0; if ("development" !== 'production') { DOMProperty.getPossibleStandardName[lowerCased] = propName; @@ -1498,7 +1612,10 @@ var DOMPropertyInjection = { } } }; -var defaultValueCache = {}; + +/* eslint-disable max-len */ +var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'; +/* eslint-enable max-len */ /** * DOMProperty exports lookup objects that can be used like functions: @@ -1516,6 +1633,10 @@ var defaultValueCache = {}; var DOMProperty = { ID_ATTRIBUTE_NAME: 'data-reactid', + ROOT_ATTRIBUTE_NAME: 'data-reactroot', + + ATTRIBUTE_NAME_START_CHAR: ATTRIBUTE_NAME_START_CHAR, + ATTRIBUTE_NAME_CHAR: ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\uB7\\u0300-\\u036F\\u203F-\\u2040', /** * Map from property "standard name" to an object with info about how to set @@ -1530,9 +1651,6 @@ var DOMProperty = { * mutationMethod: * If non-null, used instead of the property or `setAttribute()` after * initial render. - * mustUseAttribute: - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails ` in `.) * mustUseProperty: * Whether the property must be accessed and mutated as an object property. * hasSideEffects: @@ -1581,34 +1699,13 @@ var DOMProperty = { 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; -},{"144":144}],11:[function(_dereq_,module,exports){ +},{"156":156}],11:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -1616,19 +1713,18 @@ module.exports = DOMProperty; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule DOMPropertyOperations - * @typechecks static-only */ 'use strict'; var DOMProperty = _dereq_(10); -var ReactPerf = _dereq_(71); +var ReactDOMInstrumentation = _dereq_(46); +var ReactPerf = _dereq_(80); -var quoteAttributeValueForBrowser = _dereq_(122); -var warning = _dereq_(155); +var quoteAttributeValueForBrowser = _dereq_(134); +var warning = _dereq_(166); -// Simplified subset -var VALID_ATTRIBUTE_NAME_REGEX = /^[a-zA-Z_][\w\.\-]*$/; +var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + DOMProperty.ATTRIBUTE_NAME_START_CHAR + '][' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$'); var illegalAttributeNameCache = {}; var validatedAttributeNameCache = {}; @@ -1644,7 +1740,7 @@ function isAttributeNameSafe(attributeName) { return true; } illegalAttributeNameCache[attributeName] = true; - "development" !== 'production' ? warning(false, 'Invalid attribute name: `%s`', attributeName) : undefined; + "development" !== 'production' ? warning(false, 'Invalid attribute name: `%s`', attributeName) : void 0; return false; } @@ -1652,32 +1748,6 @@ function shouldIgnoreValue(propertyInfo, value) { return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false; } -if ("development" !== 'production') { - 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. - "development" !== 'production' ? warning(standardName == null, 'Unknown DOM property %s. Did you mean %s?', name, standardName) : undefined; - }; -} - /** * Operations for dealing with DOM properties. */ @@ -1697,6 +1767,14 @@ var DOMPropertyOperations = { node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id); }, + createMarkupForRoot: function () { + return DOMProperty.ROOT_ATTRIBUTE_NAME + '=""'; + }, + + setAttributeForRoot: function (node) { + node.setAttribute(DOMProperty.ROOT_ATTRIBUTE_NAME, ''); + }, + /** * Creates markup for a property. * @@ -1705,6 +1783,9 @@ var DOMPropertyOperations = { * @return {?string} Markup string, or null if the property was invalid. */ createMarkupForProperty: function (name, value) { + if ("development" !== 'production') { + ReactDOMInstrumentation.debugTool.onCreateMarkupForProperty(name, value); + } var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; if (propertyInfo) { if (shouldIgnoreValue(propertyInfo, value)) { @@ -1720,8 +1801,6 @@ var DOMPropertyOperations = { return ''; } return name + '=' + quoteAttributeValueForBrowser(value); - } else if ("development" !== 'production') { - warnUnknownProperty(name); } return null; }, @@ -1748,6 +1827,9 @@ var DOMPropertyOperations = { * @param {*} value */ setValueForProperty: function (node, name, value) { + if ("development" !== 'production') { + ReactDOMInstrumentation.debugTool.onSetValueForProperty(node, name, value); + } var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; if (propertyInfo) { var mutationMethod = propertyInfo.mutationMethod; @@ -1755,7 +1837,17 @@ var DOMPropertyOperations = { mutationMethod(node, value); } else if (shouldIgnoreValue(propertyInfo, value)) { this.deleteValueForProperty(node, name); - } else if (propertyInfo.mustUseAttribute) { + } else if (propertyInfo.mustUseProperty) { + var propName = propertyInfo.propertyName; + // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the + // property type before comparing; only `value` does and is string. + // Must set `value` property if it is not null and not yet set. + if (!propertyInfo.hasSideEffects || '' + node[propName] !== '' + value || !node.hasAttribute(propertyInfo.attributeName)) { + // Contrary to `setAttribute`, object properties are properly + // `toString`ed by IE8/9. + node[propName] = value; + } + } else { var attributeName = propertyInfo.attributeName; var namespace = propertyInfo.attributeNamespace; // `setAttribute` with objects becomes only `[object]` in IE8/9, @@ -1767,20 +1859,9 @@ var DOMPropertyOperations = { } else { node.setAttribute(attributeName, '' + value); } - } else { - var propName = propertyInfo.propertyName; - // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the - // property type before comparing; only `value` does and is string. - if (!propertyInfo.hasSideEffects || '' + node[propName] !== '' + value) { - // Contrary to `setAttribute`, object properties are properly - // `toString`ed by IE8/9. - node[propName] = value; - } } } else if (DOMProperty.isCustomAttribute(name)) { DOMPropertyOperations.setValueForAttribute(node, name, value); - } else if ("development" !== 'production') { - warnUnknownProperty(name); } }, @@ -1802,24 +1883,29 @@ var DOMPropertyOperations = { * @param {string} name */ deleteValueForProperty: function (node, name) { + if ("development" !== 'production') { + ReactDOMInstrumentation.debugTool.onDeleteValueForProperty(node, name); + } var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; if (propertyInfo) { var mutationMethod = propertyInfo.mutationMethod; if (mutationMethod) { mutationMethod(node, undefined); - } else if (propertyInfo.mustUseAttribute) { - node.removeAttribute(propertyInfo.attributeName); - } else { + } else if (propertyInfo.mustUseProperty) { var propName = propertyInfo.propertyName; - var defaultValue = DOMProperty.getDefaultValueForProperty(node.nodeName, propName); - if (!propertyInfo.hasSideEffects || '' + node[propName] !== defaultValue) { - node[propName] = defaultValue; + if (propertyInfo.hasBooleanValue) { + // No HAS_SIDE_EFFECTS logic here, only `value` has it and is string. + node[propName] = false; + } else { + if (!propertyInfo.hasSideEffects || '' + node[propName] !== '') { + node[propName] = ''; + } } + } else { + node.removeAttribute(propertyInfo.attributeName); } } else if (DOMProperty.isCustomAttribute(name)) { node.removeAttribute(name); - } else if ("development" !== 'production') { - warnUnknownProperty(name); } } @@ -1832,9 +1918,9 @@ ReactPerf.measureMethods(DOMPropertyOperations, 'DOMPropertyOperations', { }); module.exports = DOMPropertyOperations; -},{"10":10,"122":122,"155":155,"71":71}],12:[function(_dereq_,module,exports){ +},{"10":10,"134":134,"166":166,"46":46,"80":80}],12:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -1842,17 +1928,17 @@ module.exports = DOMPropertyOperations; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule Danger - * @typechecks static-only */ 'use strict'; -var ExecutionEnvironment = _dereq_(130); +var DOMLazyTree = _dereq_(8); +var ExecutionEnvironment = _dereq_(142); -var createNodesFromMarkup = _dereq_(135); -var emptyFunction = _dereq_(136); -var getMarkupWrap = _dereq_(140); -var invariant = _dereq_(144); +var createNodesFromMarkup = _dereq_(147); +var emptyFunction = _dereq_(148); +var getMarkupWrap = _dereq_(152); +var invariant = _dereq_(156); var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; var RESULT_INDEX_ATTR = 'data-danger-index'; @@ -1884,12 +1970,12 @@ var Danger = { * @internal */ dangerouslyRenderMarkup: function (markupList) { - !ExecutionEnvironment.canUseDOM ? "development" !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + 'thread. Make sure `window` and `document` are available globally ' + 'before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString for server rendering.') : invariant(false) : undefined; + !ExecutionEnvironment.canUseDOM ? "development" !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + 'thread. Make sure `window` and `document` are available globally ' + 'before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString for server rendering.') : invariant(false) : void 0; var nodeName; var markupByNodeName = {}; // Group markup by `nodeName` if a wrap is necessary, else by '*'. for (var i = 0; i < markupList.length; i++) { - !markupList[i] ? "development" !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Missing markup.') : invariant(false) : undefined; + !markupList[i] ? "development" !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Missing markup.') : invariant(false) : void 0; nodeName = getNodeName(markupList[i]); nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; @@ -1931,7 +2017,7 @@ var Danger = { resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR); renderNode.removeAttribute(RESULT_INDEX_ATTR); - !!resultList.hasOwnProperty(resultIndex) ? "development" !== 'production' ? invariant(false, 'Danger: Assigning to an already-occupied result index.') : invariant(false) : undefined; + !!resultList.hasOwnProperty(resultIndex) ? "development" !== 'production' ? invariant(false, 'Danger: Assigning to an already-occupied result index.') : invariant(false) : void 0; resultList[resultIndex] = renderNode; @@ -1946,9 +2032,9 @@ var Danger = { // Although resultList was populated out of order, it should now be a dense // array. - !(resultListAssignmentCount === resultList.length) ? "development" !== 'production' ? invariant(false, 'Danger: Did not assign to every index of resultList.') : invariant(false) : undefined; + !(resultListAssignmentCount === resultList.length) ? "development" !== 'production' ? invariant(false, 'Danger: Did not assign to every index of resultList.') : invariant(false) : void 0; - !(resultList.length === markupList.length) ? "development" !== 'production' ? invariant(false, 'Danger: Expected markup to render %s nodes, but rendered %s.', markupList.length, resultList.length) : invariant(false) : undefined; + !(resultList.length === markupList.length) ? "development" !== 'production' ? invariant(false, 'Danger: Expected markup to render %s nodes, but rendered %s.', markupList.length, resultList.length) : invariant(false) : void 0; return resultList; }, @@ -1962,25 +2048,24 @@ var Danger = { * @internal */ dangerouslyReplaceNodeWithMarkup: function (oldChild, markup) { - !ExecutionEnvironment.canUseDOM ? "development" !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + 'worker thread. Make sure `window` and `document` are available ' + 'globally before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString() for server rendering.') : invariant(false) : undefined; - !markup ? "development" !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(false) : undefined; - !(oldChild.tagName.toLowerCase() !== 'html') ? "development" !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + ' node. This is because browser quirks make this unreliable ' + 'and/or slow. If you want to render to the root you must use ' + 'server rendering. See ReactDOMServer.renderToString().') : invariant(false) : undefined; + !ExecutionEnvironment.canUseDOM ? "development" !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + 'worker thread. Make sure `window` and `document` are available ' + 'globally before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString() for server rendering.') : invariant(false) : void 0; + !markup ? "development" !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(false) : void 0; + !(oldChild.nodeName !== 'HTML') ? "development" !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + ' node. This is because browser quirks make this unreliable ' + 'and/or slow. If you want to render to the root you must use ' + 'server rendering. See ReactDOMServer.renderToString().') : invariant(false) : void 0; - var newChild; if (typeof markup === 'string') { - newChild = createNodesFromMarkup(markup, emptyFunction)[0]; + var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; + oldChild.parentNode.replaceChild(newChild, oldChild); } else { - newChild = markup; + DOMLazyTree.replaceChildWithTree(oldChild, markup); } - oldChild.parentNode.replaceChild(newChild, oldChild); } }; module.exports = Danger; -},{"130":130,"135":135,"136":136,"140":140,"144":144}],13:[function(_dereq_,module,exports){ +},{"142":142,"147":147,"148":148,"152":152,"156":156,"8":8}],13:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -1992,7 +2077,7 @@ module.exports = Danger; 'use strict'; -var keyOf = _dereq_(148); +var keyOf = _dereq_(160); /** * Module that is injectable into `EventPluginHub`, that specifies a @@ -2006,9 +2091,9 @@ var keyOf = _dereq_(148); var DefaultEventPluginOrder = [keyOf({ ResponderEventPlugin: null }), keyOf({ SimpleEventPlugin: null }), keyOf({ TapEventPlugin: null }), keyOf({ EnterLeaveEventPlugin: null }), keyOf({ ChangeEventPlugin: null }), keyOf({ SelectEventPlugin: null }), keyOf({ BeforeInputEventPlugin: null })]; module.exports = DefaultEventPluginOrder; -},{"148":148}],14:[function(_dereq_,module,exports){ +},{"160":160}],14:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -2016,20 +2101,18 @@ module.exports = DefaultEventPluginOrder; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule EnterLeaveEventPlugin - * @typechecks static-only */ 'use strict'; var EventConstants = _dereq_(15); var EventPropagators = _dereq_(19); -var SyntheticMouseEvent = _dereq_(96); +var ReactDOMComponentTree = _dereq_(38); +var SyntheticMouseEvent = _dereq_(105); -var ReactMount = _dereq_(65); -var keyOf = _dereq_(148); +var keyOf = _dereq_(160); var topLevelTypes = EventConstants.topLevelTypes; -var getFirstReactDOM = ReactMount.getFirstReactDOM; var eventTypes = { mouseEnter: { @@ -2042,8 +2125,6 @@ var eventTypes = { } }; -var extractedEvents = [null, null]; - var EnterLeaveEventPlugin = { eventTypes: eventTypes, @@ -2054,15 +2135,8 @@ var EnterLeaveEventPlugin = { * we do not extract duplicate events. However, moving the mouse into the * browser from outside will not fire a `mouseout` event. In this case, we use * the `mouseover` top-level event. - * - * @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, nativeEventTarget) { + extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { if (topLevelType === topLevelTypes.topMouseOver && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { return null; } @@ -2072,12 +2146,12 @@ var EnterLeaveEventPlugin = { } var win; - if (topLevelTarget.window === topLevelTarget) { - // `topLevelTarget` is probably a window object. - win = topLevelTarget; + if (nativeEventTarget.window === nativeEventTarget) { + // `nativeEventTarget` is probably a window object. + win = nativeEventTarget; } else { // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. - var doc = topLevelTarget.ownerDocument; + var doc = nativeEventTarget.ownerDocument; if (doc) { win = doc.defaultView || doc.parentWindow; } else { @@ -2087,22 +2161,14 @@ var EnterLeaveEventPlugin = { var from; var to; - var fromID = ''; - var toID = ''; if (topLevelType === topLevelTypes.topMouseOut) { - from = topLevelTarget; - fromID = topLevelTargetID; - to = getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement); - if (to) { - toID = ReactMount.getID(to); - } else { - to = win; - } - to = to || win; + from = targetInst; + var related = nativeEvent.relatedTarget || nativeEvent.toElement; + to = related ? ReactDOMComponentTree.getClosestInstanceFromNode(related) : null; } else { - from = win; - to = topLevelTarget; - toID = topLevelTargetID; + // Moving to a node from outside the window. + from = null; + to = targetInst; } if (from === to) { @@ -2110,30 +2176,30 @@ var EnterLeaveEventPlugin = { return null; } - var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, fromID, nativeEvent, nativeEventTarget); + var fromNode = from == null ? win : ReactDOMComponentTree.getNodeFromInstance(from); + var toNode = to == null ? win : ReactDOMComponentTree.getNodeFromInstance(to); + + var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, from, nativeEvent, nativeEventTarget); leave.type = 'mouseleave'; - leave.target = from; - leave.relatedTarget = to; + leave.target = fromNode; + leave.relatedTarget = toNode; - var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, toID, nativeEvent, nativeEventTarget); + var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, to, nativeEvent, nativeEventTarget); enter.type = 'mouseenter'; - enter.target = to; - enter.relatedTarget = from; + enter.target = toNode; + enter.relatedTarget = fromNode; - EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID); + EventPropagators.accumulateEnterLeaveDispatches(leave, enter, from, to); - extractedEvents[0] = leave; - extractedEvents[1] = enter; - - return extractedEvents; + return [leave, enter]; } }; module.exports = EnterLeaveEventPlugin; -},{"148":148,"15":15,"19":19,"65":65,"96":96}],15:[function(_dereq_,module,exports){ +},{"105":105,"15":15,"160":160,"19":19,"38":38}],15:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -2145,7 +2211,7 @@ module.exports = EnterLeaveEventPlugin; 'use strict'; -var keyMirror = _dereq_(147); +var keyMirror = _dereq_(159); var PropagationPhases = keyMirror({ bubbled: null, captured: null }); @@ -2154,6 +2220,9 @@ var PropagationPhases = keyMirror({ bubbled: null, captured: null }); */ var topLevelTypes = keyMirror({ topAbort: null, + topAnimationEnd: null, + topAnimationIteration: null, + topAnimationStart: null, topBlur: null, topCanPlay: null, topCanPlayThrough: null, @@ -2181,6 +2250,7 @@ var topLevelTypes = keyMirror({ topError: null, topFocus: null, topInput: null, + topInvalid: null, topKeyDown: null, topKeyPress: null, topKeyUp: null, @@ -2213,6 +2283,7 @@ var topLevelTypes = keyMirror({ topTouchEnd: null, topTouchMove: null, topTouchStart: null, + topTransitionEnd: null, topVolumeChange: null, topWaiting: null, topWheel: null @@ -2224,9 +2295,9 @@ var EventConstants = { }; module.exports = EventConstants; -},{"147":147}],16:[function(_dereq_,module,exports){ +},{"159":159}],16:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -2240,12 +2311,11 @@ module.exports = EventConstants; var EventPluginRegistry = _dereq_(17); var EventPluginUtils = _dereq_(18); -var ReactErrorUtils = _dereq_(56); +var ReactErrorUtils = _dereq_(63); -var accumulateInto = _dereq_(102); -var forEachAccumulated = _dereq_(110); -var invariant = _dereq_(144); -var warning = _dereq_(155); +var accumulateInto = _dereq_(112); +var forEachAccumulated = _dereq_(120); +var invariant = _dereq_(156); /** * Internal store for event listeners @@ -2281,17 +2351,6 @@ var executeDispatchesAndReleaseTopLevel = function (e) { return executeDispatchesAndRelease(e, false); }; -/** - * - `InstanceHandle`: [required] Module that performs logical traversals of DOM - * hierarchy given ids of the logical DOM elements involved. - */ -var InstanceHandle = null; - -function validateInstanceHandle() { - var valid = InstanceHandle && InstanceHandle.traverseTwoPhase && InstanceHandle.traverseEnterLeave; - "development" !== 'production' ? warning(valid, 'InstanceHandle not injected before use!') : undefined; -} - /** * This is a unified interface for event plugins to be installed and configured. * @@ -2321,30 +2380,6 @@ var EventPluginHub = { */ injection: { - /** - * @param {object} InjectedMount - * @public - */ - injectMount: EventPluginUtils.injection.injectMount, - - /** - * @param {object} InjectedInstanceHandle - * @public - */ - injectInstanceHandle: function (InjectedInstanceHandle) { - InstanceHandle = InjectedInstanceHandle; - if ("development" !== 'production') { - validateInstanceHandle(); - } - }, - - getInstanceHandle: function () { - if ("development" !== 'production') { - validateInstanceHandle(); - } - return InstanceHandle; - }, - /** * @param {array} InjectedEventPluginOrder * @public @@ -2358,75 +2393,71 @@ var EventPluginHub = { }, - eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs, - - registrationNameModules: EventPluginRegistry.registrationNameModules, - /** * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent. * - * @param {string} id ID of the DOM element. + * @param {object} inst The instance, which is the source of events. * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {?function} listener The callback to store. + * @param {function} listener The callback to store. */ - putListener: function (id, registrationName, listener) { - !(typeof listener === 'function') ? "development" !== 'production' ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : invariant(false) : undefined; + putListener: function (inst, registrationName, listener) { + !(typeof listener === 'function') ? "development" !== 'production' ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : invariant(false) : void 0; var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {}); - bankForRegistrationName[id] = listener; + bankForRegistrationName[inst._rootNodeID] = listener; var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; if (PluginModule && PluginModule.didPutListener) { - PluginModule.didPutListener(id, registrationName, listener); + PluginModule.didPutListener(inst, registrationName, listener); } }, /** - * @param {string} id ID of the DOM element. + * @param {object} inst The instance, which is the source of events. * @param {string} registrationName Name of listener (e.g. `onClick`). * @return {?function} The stored callback. */ - getListener: function (id, registrationName) { + getListener: function (inst, registrationName) { var bankForRegistrationName = listenerBank[registrationName]; - return bankForRegistrationName && bankForRegistrationName[id]; + return bankForRegistrationName && bankForRegistrationName[inst._rootNodeID]; }, /** * Deletes a listener from the registration bank. * - * @param {string} id ID of the DOM element. + * @param {object} inst The instance, which is the source of events. * @param {string} registrationName Name of listener (e.g. `onClick`). */ - deleteListener: function (id, registrationName) { + deleteListener: function (inst, registrationName) { var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; if (PluginModule && PluginModule.willDeleteListener) { - PluginModule.willDeleteListener(id, registrationName); + PluginModule.willDeleteListener(inst, registrationName); } var bankForRegistrationName = listenerBank[registrationName]; // TODO: This should never be null -- when is it? if (bankForRegistrationName) { - delete bankForRegistrationName[id]; + delete bankForRegistrationName[inst._rootNodeID]; } }, /** * Deletes all listeners for the DOM element with the supplied ID. * - * @param {string} id ID of the DOM element. + * @param {object} inst The instance, which is the source of events. */ - deleteAllListeners: function (id) { + deleteAllListeners: function (inst) { for (var registrationName in listenerBank) { - if (!listenerBank[registrationName][id]) { + if (!listenerBank[registrationName][inst._rootNodeID]) { continue; } var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; if (PluginModule && PluginModule.willDeleteListener) { - PluginModule.willDeleteListener(id, registrationName); + PluginModule.willDeleteListener(inst, registrationName); } - delete listenerBank[registrationName][id]; + delete listenerBank[registrationName][inst._rootNodeID]; } }, @@ -2434,21 +2465,17 @@ var EventPluginHub = { * Allows registered plugins an opportunity to extract events from top-level * native browser events. * - * @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. * @internal */ - extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { + extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { var events; var plugins = EventPluginRegistry.plugins; for (var i = 0; i < plugins.length; i++) { // Not every plugin in the ordering may be loaded at runtime. var possiblePlugin = plugins[i]; if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget); + var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); if (extractedEvents) { events = accumulateInto(events, extractedEvents); } @@ -2485,7 +2512,7 @@ var EventPluginHub = { } else { forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); } - !!eventQueue ? "development" !== 'production' ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing ' + 'an event queue. Support for this has not yet been implemented.') : invariant(false) : undefined; + !!eventQueue ? "development" !== 'production' ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing ' + 'an event queue. Support for this has not yet been implemented.') : invariant(false) : void 0; // This would be a good time to rethrow if any of the event handlers threw. ReactErrorUtils.rethrowCaughtError(); }, @@ -2504,9 +2531,9 @@ var EventPluginHub = { }; module.exports = EventPluginHub; -},{"102":102,"110":110,"144":144,"155":155,"17":17,"18":18,"56":56}],17:[function(_dereq_,module,exports){ +},{"112":112,"120":120,"156":156,"17":17,"18":18,"63":63}],17:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -2514,12 +2541,11 @@ module.exports = EventPluginHub; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule EventPluginRegistry - * @typechecks static-only */ 'use strict'; -var invariant = _dereq_(144); +var invariant = _dereq_(156); /** * Injectable ordering of event plugins. @@ -2544,15 +2570,15 @@ function recomputePluginOrdering() { for (var pluginName in namesToPlugins) { var PluginModule = namesToPlugins[pluginName]; var pluginIndex = EventPluginOrder.indexOf(pluginName); - !(pluginIndex > -1) ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + 'the plugin ordering, `%s`.', pluginName) : invariant(false) : undefined; + !(pluginIndex > -1) ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + 'the plugin ordering, `%s`.', pluginName) : invariant(false) : void 0; if (EventPluginRegistry.plugins[pluginIndex]) { continue; } - !PluginModule.extractEvents ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + 'method, but `%s` does not.', pluginName) : invariant(false) : undefined; + !PluginModule.extractEvents ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + 'method, but `%s` does not.', pluginName) : invariant(false) : void 0; EventPluginRegistry.plugins[pluginIndex] = PluginModule; var publishedEvents = PluginModule.eventTypes; for (var eventName in publishedEvents) { - !publishEventForPlugin(publishedEvents[eventName], PluginModule, eventName) ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : invariant(false) : undefined; + !publishEventForPlugin(publishedEvents[eventName], PluginModule, eventName) ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : invariant(false) : void 0; } } } @@ -2566,7 +2592,7 @@ function recomputePluginOrdering() { * @private */ function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { - !!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? "development" !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'event name, `%s`.', eventName) : invariant(false) : undefined; + !!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? "development" !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'event name, `%s`.', eventName) : invariant(false) : void 0; EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; @@ -2594,9 +2620,14 @@ function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { * @private */ function publishRegistrationName(registrationName, PluginModule, eventName) { - !!EventPluginRegistry.registrationNameModules[registrationName] ? "development" !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName) : invariant(false) : undefined; + !!EventPluginRegistry.registrationNameModules[registrationName] ? "development" !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName) : invariant(false) : void 0; EventPluginRegistry.registrationNameModules[registrationName] = PluginModule; EventPluginRegistry.registrationNameDependencies[registrationName] = PluginModule.eventTypes[eventName].dependencies; + + if ("development" !== 'production') { + var lowerCasedName = registrationName.toLowerCase(); + EventPluginRegistry.possibleRegistrationNames[lowerCasedName] = registrationName; + } } /** @@ -2626,6 +2657,14 @@ var EventPluginRegistry = { */ registrationNameDependencies: {}, + /** + * Mapping from lowercase registration names to the properly cased version, + * used to warn in the case of missing event handlers. Available + * only in __DEV__. + * @type {Object} + */ + possibleRegistrationNames: "development" !== 'production' ? {} : null, + /** * Injects an ordering of plugins (by plugin name). This allows the ordering * to be decoupled from injection of the actual plugins so that ordering is @@ -2636,7 +2675,7 @@ var EventPluginRegistry = { * @see {EventPluginHub.injection.injectEventPluginOrder} */ injectEventPluginOrder: function (InjectedEventPluginOrder) { - !!EventPluginOrder ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + 'once. You are likely trying to load more than one copy of React.') : invariant(false) : undefined; + !!EventPluginOrder ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + 'once. You are likely trying to load more than one copy of React.') : invariant(false) : void 0; // Clone the ordering so it cannot be dynamically mutated. EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder); recomputePluginOrdering(); @@ -2660,7 +2699,7 @@ var EventPluginRegistry = { } var PluginModule = injectedNamesToPlugins[pluginName]; if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== PluginModule) { - !!namesToPlugins[pluginName] ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins ' + 'using the same name, `%s`.', pluginName) : invariant(false) : undefined; + !!namesToPlugins[pluginName] ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins ' + 'using the same name, `%s`.', pluginName) : invariant(false) : void 0; namesToPlugins[pluginName] = PluginModule; isOrderingDirty = true; } @@ -2720,14 +2759,23 @@ var EventPluginRegistry = { delete registrationNameModules[registrationName]; } } + + if ("development" !== 'production') { + var possibleRegistrationNames = EventPluginRegistry.possibleRegistrationNames; + for (var lowerCasedName in possibleRegistrationNames) { + if (possibleRegistrationNames.hasOwnProperty(lowerCasedName)) { + delete possibleRegistrationNames[lowerCasedName]; + } + } + } } }; module.exports = EventPluginRegistry; -},{"144":144}],18:[function(_dereq_,module,exports){ +},{"156":156}],18:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -2740,25 +2788,32 @@ module.exports = EventPluginRegistry; 'use strict'; var EventConstants = _dereq_(15); -var ReactErrorUtils = _dereq_(56); +var ReactErrorUtils = _dereq_(63); -var invariant = _dereq_(144); -var warning = _dereq_(155); +var invariant = _dereq_(156); +var warning = _dereq_(166); /** * Injected dependencies: */ /** - * - `Mount`: [required] Module that can convert between React dom IDs and - * actual node references. + * - `ComponentTree`: [required] Module that can convert between React instances + * and actual node references. */ +var ComponentTree; +var TreeTraversal; var injection = { - Mount: null, - injectMount: function (InjectedMount) { - injection.Mount = InjectedMount; + injectComponentTree: function (Injected) { + ComponentTree = Injected; if ("development" !== 'production') { - "development" !== 'production' ? warning(InjectedMount && InjectedMount.getNode && InjectedMount.getID, 'EventPluginUtils.injection.injectMount(...): Injected Mount ' + 'module is missing getNode or getID.') : undefined; + "development" !== 'production' ? warning(Injected && Injected.getNodeFromInstance && Injected.getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0; + } + }, + injectTreeTraversal: function (Injected) { + TreeTraversal = Injected; + if ("development" !== 'production') { + "development" !== 'production' ? warning(Injected && Injected.isAncestor && Injected.getLowestCommonAncestor, 'EventPluginUtils.injection.injectTreeTraversal(...): Injected ' + 'module is missing isAncestor or getLowestCommonAncestor.') : void 0; } } }; @@ -2780,14 +2835,15 @@ var validateEventDispatches; if ("development" !== 'production') { validateEventDispatches = function (event) { var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; + var dispatchInstances = event._dispatchInstances; var listenersIsArr = Array.isArray(dispatchListeners); - var idsIsArr = Array.isArray(dispatchIDs); - var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0; var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; - "development" !== 'production' ? warning(idsIsArr === listenersIsArr && IDsLen === listenersLen, 'EventPluginUtils: Invalid `event`.') : undefined; + var instancesIsArr = Array.isArray(dispatchInstances); + var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; + + "development" !== 'production' ? warning(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.') : void 0; }; } @@ -2796,15 +2852,15 @@ if ("development" !== 'production') { * @param {SyntheticEvent} event SyntheticEvent to handle * @param {boolean} simulated If the event is simulated (changes exn behavior) * @param {function} listener Application-level callback - * @param {string} domID DOM id to pass to the callback. + * @param {*} inst Internal component instance */ -function executeDispatch(event, simulated, listener, domID) { +function executeDispatch(event, simulated, listener, inst) { var type = event.type || 'unknown-event'; - event.currentTarget = injection.Mount.getNode(domID); + event.currentTarget = EventPluginUtils.getNodeFromInstance(inst); if (simulated) { - ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event, domID); + ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event); } else { - ReactErrorUtils.invokeGuardedCallback(type, listener, event, domID); + ReactErrorUtils.invokeGuardedCallback(type, listener, event); } event.currentTarget = null; } @@ -2814,7 +2870,7 @@ function executeDispatch(event, simulated, listener, domID) { */ function executeDispatchesInOrder(event, simulated) { var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; + var dispatchInstances = event._dispatchInstances; if ("development" !== 'production') { validateEventDispatches(event); } @@ -2823,14 +2879,14 @@ function executeDispatchesInOrder(event, simulated) { if (event.isPropagationStopped()) { break; } - // Listeners and IDs are two parallel arrays that are always in sync. - executeDispatch(event, simulated, dispatchListeners[i], dispatchIDs[i]); + // Listeners and Instances are two parallel arrays that are always in sync. + executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]); } } else if (dispatchListeners) { - executeDispatch(event, simulated, dispatchListeners, dispatchIDs); + executeDispatch(event, simulated, dispatchListeners, dispatchInstances); } event._dispatchListeners = null; - event._dispatchIDs = null; + event._dispatchInstances = null; } /** @@ -2842,7 +2898,7 @@ function executeDispatchesInOrder(event, simulated) { */ function executeDispatchesInOrderStopAtTrueImpl(event) { var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; + var dispatchInstances = event._dispatchInstances; if ("development" !== 'production') { validateEventDispatches(event); } @@ -2851,14 +2907,14 @@ function executeDispatchesInOrderStopAtTrueImpl(event) { if (event.isPropagationStopped()) { break; } - // Listeners and IDs are two parallel arrays that are always in sync. - if (dispatchListeners[i](event, dispatchIDs[i])) { - return dispatchIDs[i]; + // Listeners and Instances are two parallel arrays that are always in sync. + if (dispatchListeners[i](event, dispatchInstances[i])) { + return dispatchInstances[i]; } } } else if (dispatchListeners) { - if (dispatchListeners(event, dispatchIDs)) { - return dispatchIDs; + if (dispatchListeners(event, dispatchInstances)) { + return dispatchInstances; } } return null; @@ -2869,7 +2925,7 @@ function executeDispatchesInOrderStopAtTrueImpl(event) { */ function executeDispatchesInOrderStopAtTrue(event) { var ret = executeDispatchesInOrderStopAtTrueImpl(event); - event._dispatchIDs = null; + event._dispatchInstances = null; event._dispatchListeners = null; return ret; } @@ -2888,11 +2944,13 @@ function executeDirectDispatch(event) { validateEventDispatches(event); } var dispatchListener = event._dispatchListeners; - var dispatchID = event._dispatchIDs; - !!Array.isArray(dispatchListener) ? "development" !== 'production' ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : invariant(false) : undefined; - var res = dispatchListener ? dispatchListener(event, dispatchID) : null; + var dispatchInstance = event._dispatchInstances; + !!Array.isArray(dispatchListener) ? "development" !== 'production' ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : invariant(false) : void 0; + event.currentTarget = EventPluginUtils.getNodeFromInstance(dispatchInstance); + var res = dispatchListener ? dispatchListener(event) : null; + event.currentTarget = null; event._dispatchListeners = null; - event._dispatchIDs = null; + event._dispatchInstances = null; return res; } @@ -2917,20 +2975,35 @@ var EventPluginUtils = { executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, hasDispatches: hasDispatches, - getNode: function (id) { - return injection.Mount.getNode(id); + getInstanceFromNode: function (node) { + return ComponentTree.getInstanceFromNode(node); }, - getID: function (node) { - return injection.Mount.getID(node); + getNodeFromInstance: function (node) { + return ComponentTree.getNodeFromInstance(node); + }, + isAncestor: function (a, b) { + return TreeTraversal.isAncestor(a, b); + }, + getLowestCommonAncestor: function (a, b) { + return TreeTraversal.getLowestCommonAncestor(a, b); + }, + getParentInstance: function (inst) { + return TreeTraversal.getParentInstance(inst); + }, + traverseTwoPhase: function (target, fn, arg) { + return TreeTraversal.traverseTwoPhase(target, fn, arg); + }, + traverseEnterLeave: function (from, to, fn, argFrom, argTo) { + return TreeTraversal.traverseEnterLeave(from, to, fn, argFrom, argTo); }, injection: injection }; module.exports = EventPluginUtils; -},{"144":144,"15":15,"155":155,"56":56}],19:[function(_dereq_,module,exports){ +},{"15":15,"156":156,"166":166,"63":63}],19:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -2944,11 +3017,11 @@ module.exports = EventPluginUtils; var EventConstants = _dereq_(15); var EventPluginHub = _dereq_(16); +var EventPluginUtils = _dereq_(18); -var warning = _dereq_(155); - -var accumulateInto = _dereq_(102); -var forEachAccumulated = _dereq_(110); +var accumulateInto = _dereq_(112); +var forEachAccumulated = _dereq_(120); +var warning = _dereq_(166); var PropagationPhases = EventConstants.PropagationPhases; var getListener = EventPluginHub.getListener; @@ -2957,9 +3030,9 @@ var getListener = EventPluginHub.getListener; * Some event types have a notion of different registration names for different * "phases" of propagation. This finds listeners by a given phase. */ -function listenerAtPhase(id, event, propagationPhase) { +function listenerAtPhase(inst, event, propagationPhase) { var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; - return getListener(id, registrationName); + return getListener(inst, registrationName); } /** @@ -2968,15 +3041,15 @@ function listenerAtPhase(id, event, propagationPhase) { * Mutating the event's members allows us to not have to create a wrapping * "dispatch" object that pairs the event with the listener. */ -function accumulateDirectionalDispatches(domID, upwards, event) { +function accumulateDirectionalDispatches(inst, upwards, event) { if ("development" !== 'production') { - "development" !== 'production' ? warning(domID, 'Dispatching id must not be null') : undefined; + "development" !== 'production' ? warning(inst, 'Dispatching inst must not be null') : void 0; } var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured; - var listener = listenerAtPhase(domID, event, phase); + var listener = listenerAtPhase(inst, event, phase); if (listener) { event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); - event._dispatchIDs = accumulateInto(event._dispatchIDs, domID); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); } } @@ -2989,7 +3062,7 @@ function accumulateDirectionalDispatches(domID, upwards, event) { */ function accumulateTwoPhaseDispatchesSingle(event) { if (event && event.dispatchConfig.phasedRegistrationNames) { - EventPluginHub.injection.getInstanceHandle().traverseTwoPhase(event.dispatchMarker, accumulateDirectionalDispatches, event); + EventPluginUtils.traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); } } @@ -2998,7 +3071,9 @@ function accumulateTwoPhaseDispatchesSingle(event) { */ function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { if (event && event.dispatchConfig.phasedRegistrationNames) { - EventPluginHub.injection.getInstanceHandle().traverseTwoPhaseSkipTarget(event.dispatchMarker, accumulateDirectionalDispatches, event); + var targetInst = event._targetInst; + var parentInst = targetInst ? EventPluginUtils.getParentInstance(targetInst) : null; + EventPluginUtils.traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); } } @@ -3007,13 +3082,13 @@ function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { * registration names. Same as `accumulateDirectDispatchesSingle` but without * requiring that the `dispatchMarker` be the same as the dispatched ID. */ -function accumulateDispatches(id, ignoredDirection, event) { +function accumulateDispatches(inst, ignoredDirection, event) { if (event && event.dispatchConfig.registrationName) { var registrationName = event.dispatchConfig.registrationName; - var listener = getListener(id, registrationName); + var listener = getListener(inst, registrationName); if (listener) { event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); - event._dispatchIDs = accumulateInto(event._dispatchIDs, id); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); } } } @@ -3025,7 +3100,7 @@ function accumulateDispatches(id, ignoredDirection, event) { */ function accumulateDirectDispatchesSingle(event) { if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event.dispatchMarker, null, event); + accumulateDispatches(event._targetInst, null, event); } } @@ -3037,8 +3112,8 @@ function accumulateTwoPhaseDispatchesSkipTarget(events) { forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); } -function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) { - EventPluginHub.injection.getInstanceHandle().traverseEnterLeave(fromID, toID, accumulateDispatches, leave, enter); +function accumulateEnterLeaveDispatches(leave, enter, from, to) { + EventPluginUtils.traverseEnterLeave(from, to, accumulateDispatches, leave, enter); } function accumulateDirectDispatches(events) { @@ -3064,9 +3139,9 @@ var EventPropagators = { }; module.exports = EventPropagators; -},{"102":102,"110":110,"15":15,"155":155,"16":16}],20:[function(_dereq_,module,exports){ +},{"112":112,"120":120,"15":15,"16":16,"166":166,"18":18}],20:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -3074,15 +3149,15 @@ module.exports = EventPropagators; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule FallbackCompositionState - * @typechecks static-only */ 'use strict'; -var PooledClass = _dereq_(24); +var _assign = _dereq_(167); -var assign = _dereq_(23); -var getTextContentAccessor = _dereq_(117); +var PooledClass = _dereq_(23); + +var getTextContentAccessor = _dereq_(128); /** * This helper class stores information about text content of a target node, @@ -3101,7 +3176,7 @@ function FallbackCompositionState(root) { this._fallbackText = null; } -assign(FallbackCompositionState.prototype, { +_assign(FallbackCompositionState.prototype, { destructor: function () { this._root = null; this._startText = null; @@ -3160,9 +3235,9 @@ assign(FallbackCompositionState.prototype, { PooledClass.addPoolingTo(FallbackCompositionState); module.exports = FallbackCompositionState; -},{"117":117,"23":23,"24":24}],21:[function(_dereq_,module,exports){ +},{"128":128,"167":167,"23":23}],21:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -3175,9 +3250,7 @@ module.exports = FallbackCompositionState; 'use strict'; var DOMProperty = _dereq_(10); -var ExecutionEnvironment = _dereq_(130); -var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE; var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS; @@ -3185,188 +3258,182 @@ var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE; var HAS_POSITIVE_NUMERIC_VALUE = DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; var HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; -var hasSVG; -if (ExecutionEnvironment.canUseDOM) { - var implementation = document.implementation; - hasSVG = implementation && implementation.hasFeature && implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1'); -} - var HTMLDOMPropertyConfig = { - isCustomAttribute: RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/), + isCustomAttribute: RegExp.prototype.test.bind(new RegExp('^(data|aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$')), Properties: { /** * Standard Properties */ - accept: null, - acceptCharset: null, - accessKey: null, - action: null, - allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - allowTransparency: MUST_USE_ATTRIBUTE, - alt: null, + accept: 0, + acceptCharset: 0, + accessKey: 0, + action: 0, + allowFullScreen: HAS_BOOLEAN_VALUE, + allowTransparency: 0, + alt: 0, async: HAS_BOOLEAN_VALUE, - autoComplete: null, + autoComplete: 0, // autoFocus is polyfilled/normalized by AutoFocusUtils // autoFocus: HAS_BOOLEAN_VALUE, autoPlay: HAS_BOOLEAN_VALUE, - capture: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - cellPadding: null, - cellSpacing: null, - charSet: MUST_USE_ATTRIBUTE, - challenge: MUST_USE_ATTRIBUTE, + capture: HAS_BOOLEAN_VALUE, + cellPadding: 0, + cellSpacing: 0, + charSet: 0, + challenge: 0, checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - classID: MUST_USE_ATTRIBUTE, - // To set className on SVG elements, it's necessary to use .setAttribute; - // this works on HTML elements too in all browsers except IE8. Conveniently, - // IE8 doesn't support SVG and so we can simply use the attribute in - // browsers that support SVG and the property in browsers that don't, - // regardless of whether the element is HTML or SVG. - className: hasSVG ? MUST_USE_ATTRIBUTE : MUST_USE_PROPERTY, - cols: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, - colSpan: null, - content: null, - contentEditable: null, - contextMenu: MUST_USE_ATTRIBUTE, - controls: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - coords: null, - crossOrigin: null, - data: null, // For `` acts as `src`. - dateTime: MUST_USE_ATTRIBUTE, + cite: 0, + classID: 0, + className: 0, + cols: HAS_POSITIVE_NUMERIC_VALUE, + colSpan: 0, + content: 0, + contentEditable: 0, + contextMenu: 0, + controls: HAS_BOOLEAN_VALUE, + coords: 0, + crossOrigin: 0, + data: 0, // For `` acts as `src`. + dateTime: 0, 'default': HAS_BOOLEAN_VALUE, defer: HAS_BOOLEAN_VALUE, - dir: null, - disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, + dir: 0, + disabled: HAS_BOOLEAN_VALUE, download: HAS_OVERLOADED_BOOLEAN_VALUE, - draggable: null, - encType: null, - form: MUST_USE_ATTRIBUTE, - formAction: MUST_USE_ATTRIBUTE, - formEncType: MUST_USE_ATTRIBUTE, - formMethod: MUST_USE_ATTRIBUTE, + draggable: 0, + encType: 0, + form: 0, + formAction: 0, + formEncType: 0, + formMethod: 0, formNoValidate: HAS_BOOLEAN_VALUE, - formTarget: MUST_USE_ATTRIBUTE, - frameBorder: MUST_USE_ATTRIBUTE, - headers: null, - height: MUST_USE_ATTRIBUTE, - hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, - high: null, - href: null, - hrefLang: null, - htmlFor: null, - httpEquiv: null, - icon: null, - id: MUST_USE_PROPERTY, - inputMode: MUST_USE_ATTRIBUTE, - integrity: null, - is: MUST_USE_ATTRIBUTE, - keyParams: MUST_USE_ATTRIBUTE, - keyType: MUST_USE_ATTRIBUTE, - kind: null, - label: null, - lang: null, - list: MUST_USE_ATTRIBUTE, - loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - low: null, - manifest: MUST_USE_ATTRIBUTE, - marginHeight: null, - marginWidth: null, - max: null, - maxLength: MUST_USE_ATTRIBUTE, - media: MUST_USE_ATTRIBUTE, - mediaGroup: null, - method: null, - min: null, - minLength: MUST_USE_ATTRIBUTE, + formTarget: 0, + frameBorder: 0, + headers: 0, + height: 0, + hidden: HAS_BOOLEAN_VALUE, + high: 0, + href: 0, + hrefLang: 0, + htmlFor: 0, + httpEquiv: 0, + icon: 0, + id: 0, + inputMode: 0, + integrity: 0, + is: 0, + keyParams: 0, + keyType: 0, + kind: 0, + label: 0, + lang: 0, + list: 0, + loop: HAS_BOOLEAN_VALUE, + low: 0, + manifest: 0, + marginHeight: 0, + marginWidth: 0, + max: 0, + maxLength: 0, + media: 0, + mediaGroup: 0, + method: 0, + min: 0, + minLength: 0, + // Caution; `option.selected` is not updated if `select.multiple` is + // disabled with `removeAttribute`. multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - name: null, - nonce: MUST_USE_ATTRIBUTE, + name: 0, + nonce: 0, noValidate: HAS_BOOLEAN_VALUE, open: HAS_BOOLEAN_VALUE, - optimum: null, - pattern: null, - placeholder: null, - poster: null, - preload: null, - radioGroup: null, - readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - rel: null, + optimum: 0, + pattern: 0, + placeholder: 0, + poster: 0, + preload: 0, + profile: 0, + radioGroup: 0, + readOnly: HAS_BOOLEAN_VALUE, + rel: 0, required: HAS_BOOLEAN_VALUE, reversed: HAS_BOOLEAN_VALUE, - role: MUST_USE_ATTRIBUTE, - rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, - rowSpan: null, - sandbox: null, - scope: null, + role: 0, + rows: HAS_POSITIVE_NUMERIC_VALUE, + rowSpan: HAS_NUMERIC_VALUE, + sandbox: 0, + scope: 0, scoped: HAS_BOOLEAN_VALUE, - scrolling: null, - seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, + scrolling: 0, + seamless: HAS_BOOLEAN_VALUE, selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - shape: null, - size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, - sizes: MUST_USE_ATTRIBUTE, + shape: 0, + size: HAS_POSITIVE_NUMERIC_VALUE, + sizes: 0, span: HAS_POSITIVE_NUMERIC_VALUE, - spellCheck: null, - src: null, - srcDoc: MUST_USE_PROPERTY, - srcLang: null, - srcSet: MUST_USE_ATTRIBUTE, + spellCheck: 0, + src: 0, + srcDoc: 0, + srcLang: 0, + srcSet: 0, start: HAS_NUMERIC_VALUE, - step: null, - style: null, - summary: null, - tabIndex: null, - target: null, - title: null, - type: null, - useMap: null, + step: 0, + style: 0, + summary: 0, + tabIndex: 0, + target: 0, + title: 0, + // Setting .type throws on non-') : undefined; + "development" !== 'production' ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + '') : void 0; var expectedFeatures = [ // shims - Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.split, String.prototype.trim, - - // shams - Object.create, Object.freeze]; + Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.split, String.prototype.trim]; for (var i = 0; i < expectedFeatures.length; i++) { if (!expectedFeatures[i]) { - console.error('One or more ES5 shim/shams expected by React are not available: ' + 'https://fb.me/react-warning-polyfills'); + "development" !== 'production' ? warning(false, 'One or more ES5 shims expected by React are not available: ' + 'https://fb.me/react-warning-polyfills') : void 0; break; } } @@ -6170,9 +6264,9 @@ if ("development" !== 'production') { } module.exports = React; -},{"108":108,"123":123,"130":130,"155":155,"34":34,"46":46,"49":49,"61":61,"65":65,"71":71,"76":76,"83":83,"84":84}],36:[function(_dereq_,module,exports){ +},{"118":118,"126":126,"135":135,"142":142,"166":166,"38":38,"57":57,"73":73,"80":80,"85":85,"92":92,"93":93}],35:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -6203,7 +6297,7 @@ var mouseListenerNames = { * when `disabled` is set. */ var ReactDOMButton = { - getNativeProps: function (inst, props, context) { + getNativeProps: function (inst, props) { if (!props.disabled) { return props; } @@ -6221,9 +6315,9 @@ var ReactDOMButton = { }; module.exports = ReactDOMButton; -},{}],37:[function(_dereq_,module,exports){ +},{}],36:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -6231,54 +6325,59 @@ module.exports = ReactDOMButton; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule ReactDOMComponent - * @typechecks static-only */ /* global hasOwnProperty:true */ 'use strict'; -var AutoFocusUtils = _dereq_(2); -var CSSPropertyOperations = _dereq_(5); +var _assign = _dereq_(167); + +var AutoFocusUtils = _dereq_(1); +var CSSPropertyOperations = _dereq_(4); +var DOMLazyTree = _dereq_(8); +var DOMNamespaces = _dereq_(9); var DOMProperty = _dereq_(10); var DOMPropertyOperations = _dereq_(11); var EventConstants = _dereq_(15); -var ReactBrowserEventEmitter = _dereq_(26); -var ReactComponentBrowserEnvironment = _dereq_(31); -var ReactDOMButton = _dereq_(36); -var ReactDOMInput = _dereq_(41); -var ReactDOMOption = _dereq_(42); -var ReactDOMSelect = _dereq_(43); -var ReactDOMTextarea = _dereq_(47); -var ReactMount = _dereq_(65); -var ReactMultiChild = _dereq_(66); -var ReactPerf = _dereq_(71); -var ReactUpdateQueue = _dereq_(82); +var EventPluginHub = _dereq_(16); +var EventPluginRegistry = _dereq_(17); +var ReactBrowserEventEmitter = _dereq_(25); +var ReactComponentBrowserEnvironment = _dereq_(30); +var ReactDOMButton = _dereq_(35); +var ReactDOMComponentFlags = _dereq_(37); +var ReactDOMComponentTree = _dereq_(38); +var ReactDOMInput = _dereq_(45); +var ReactDOMOption = _dereq_(47); +var ReactDOMSelect = _dereq_(48); +var ReactDOMTextarea = _dereq_(52); +var ReactMultiChild = _dereq_(74); +var ReactPerf = _dereq_(80); -var assign = _dereq_(23); -var canDefineProperty = _dereq_(104); -var escapeTextContentForBrowser = _dereq_(107); -var invariant = _dereq_(144); -var isEventSupported = _dereq_(119); -var keyOf = _dereq_(148); -var setInnerHTML = _dereq_(124); -var setTextContent = _dereq_(125); -var shallowEqual = _dereq_(153); -var validateDOMNesting = _dereq_(128); -var warning = _dereq_(155); +var escapeTextContentForBrowser = _dereq_(117); +var invariant = _dereq_(156); +var isEventSupported = _dereq_(131); +var keyOf = _dereq_(160); +var shallowEqual = _dereq_(165); +var validateDOMNesting = _dereq_(140); +var warning = _dereq_(166); -var deleteListener = ReactBrowserEventEmitter.deleteListener; +var Flags = ReactDOMComponentFlags; +var deleteListener = EventPluginHub.deleteListener; +var getNode = ReactDOMComponentTree.getNodeFromInstance; var listenTo = ReactBrowserEventEmitter.listenTo; -var registrationNameModules = ReactBrowserEventEmitter.registrationNameModules; +var registrationNameModules = EventPluginRegistry.registrationNameModules; // For quickly matching children type, to test if can be treated as content. var CONTENT_TYPES = { 'string': true, 'number': true }; -var CHILDREN = keyOf({ children: null }); var STYLE = keyOf({ style: null }); var HTML = keyOf({ __html: null }); - -var ELEMENT_NODE_TYPE = 1; +var RESERVED_PROPS = { + children: null, + dangerouslySetInnerHTML: null, + suppressContentEditableWarning: null +}; function getDeclarationErrorAddendum(internalInstance) { if (internalInstance) { @@ -6293,71 +6392,6 @@ function getDeclarationErrorAddendum(internalInstance) { return ''; } -var legacyPropsDescriptor; -if ("development" !== 'production') { - legacyPropsDescriptor = { - props: { - enumerable: false, - get: function () { - var component = this._reactInternalComponent; - "development" !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .props of a DOM node; instead, ' + 'recreate the props as `render` did originally or read the DOM ' + 'properties/attributes directly from this node (e.g., ' + 'this.refs.box.className).%s', getDeclarationErrorAddendum(component)) : undefined; - return component._currentElement.props; - } - } - }; -} - -function legacyGetDOMNode() { - if ("development" !== 'production') { - var component = this._reactInternalComponent; - "development" !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .getDOMNode() of a DOM node; ' + 'instead, use the node directly.%s', getDeclarationErrorAddendum(component)) : undefined; - } - return this; -} - -function legacyIsMounted() { - var component = this._reactInternalComponent; - if ("development" !== 'production') { - "development" !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .isMounted() of a DOM node.%s', getDeclarationErrorAddendum(component)) : undefined; - } - return !!component; -} - -function legacySetStateEtc() { - if ("development" !== 'production') { - var component = this._reactInternalComponent; - "development" !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .setState(), .replaceState(), or ' + '.forceUpdate() of a DOM node. This is a no-op.%s', getDeclarationErrorAddendum(component)) : undefined; - } -} - -function legacySetProps(partialProps, callback) { - var component = this._reactInternalComponent; - if ("development" !== 'production') { - "development" !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .setProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined; - } - if (!component) { - return; - } - ReactUpdateQueue.enqueueSetPropsInternal(component, partialProps); - if (callback) { - ReactUpdateQueue.enqueueCallbackInternal(component, callback); - } -} - -function legacyReplaceProps(partialProps, callback) { - var component = this._reactInternalComponent; - if ("development" !== 'production') { - "development" !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .replaceProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined; - } - if (!component) { - return; - } - ReactUpdateQueue.enqueueReplacePropsInternal(component, partialProps); - if (callback) { - ReactUpdateQueue.enqueueCallbackInternal(component, callback); - } -} - function friendlyStringify(obj) { if (typeof obj === 'object') { if (Array.isArray(obj)) { @@ -6377,7 +6411,7 @@ function friendlyStringify(obj) { } else if (typeof obj === 'function') { return '[function object]'; } - // Differs from JSON.stringify in that undefined becauses undefined and that + // Differs from JSON.stringify in that undefined because undefined and that // inf and nan don't become null return String(obj); } @@ -6407,7 +6441,7 @@ function checkAndWarnForMutatedStyle(style1, style2, component) { styleMutationWarning[hash] = true; - "development" !== 'production' ? warning(false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` is deprecated. Consider cloning it beforehand. Check ' + 'the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', friendlyStringify(style1), friendlyStringify(style2)) : undefined; + "development" !== 'production' ? warning(false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` is deprecated. Consider cloning it beforehand. Check ' + 'the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', friendlyStringify(style1), friendlyStringify(style2)) : void 0; } /** @@ -6419,35 +6453,36 @@ function assertValidProps(component, props) { return; } // Note the use of `==` which checks for null or undefined. - if ("development" !== 'production') { - if (voidElementTags[component._tag]) { - "development" !== 'production' ? warning(props.children == null && props.dangerouslySetInnerHTML == null, '%s is a void element tag and must not have `children` or ' + 'use `props.dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : undefined; - } + if (voidElementTags[component._tag]) { + !(props.children == null && props.dangerouslySetInnerHTML == null) ? "development" !== 'production' ? invariant(false, '%s is a void element tag and must not have `children` or ' + 'use `props.dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : invariant(false) : void 0; } if (props.dangerouslySetInnerHTML != null) { - !(props.children == null) ? "development" !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : undefined; - !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? "development" !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + 'for more information.') : invariant(false) : undefined; + !(props.children == null) ? "development" !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : void 0; + !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? "development" !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + 'for more information.') : invariant(false) : void 0; } if ("development" !== 'production') { - "development" !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : undefined; - "development" !== 'production' ? warning(!props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : undefined; + "development" !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : void 0; + "development" !== 'production' ? warning(props.suppressContentEditableWarning || !props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : void 0; + "development" !== 'production' ? warning(props.onFocusIn == null && props.onFocusOut == null, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.') : void 0; } - !(props.style == null || typeof props.style === 'object') ? "development" !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, ' + 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' + 'using JSX.%s', getDeclarationErrorAddendum(component)) : invariant(false) : undefined; + !(props.style == null || typeof props.style === 'object') ? "development" !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, ' + 'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' + 'using JSX.%s', getDeclarationErrorAddendum(component)) : invariant(false) : void 0; } -function enqueuePutListener(id, registrationName, listener, transaction) { +function enqueuePutListener(inst, registrationName, listener, transaction) { if ("development" !== 'production') { // IE8 has no API for event capturing and the `onScroll` event doesn't // bubble. - "development" !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : undefined; + "development" !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : void 0; } - var container = ReactMount.findReactContainerForID(id); - if (container) { - var doc = container.nodeType === ELEMENT_NODE_TYPE ? container.ownerDocument : container; - listenTo(registrationName, doc); + var containerInfo = inst._nativeContainerInfo; + var doc = containerInfo._ownerDocument; + if (!doc) { + // Server rendering. + return; } + listenTo(registrationName, doc); transaction.getReactMountReady().enqueue(putListener, { - id: id, + inst: inst, registrationName: registrationName, listener: listener }); @@ -6455,7 +6490,7 @@ function enqueuePutListener(id, registrationName, listener, transaction) { function putListener() { var listenerToPut = this; - ReactBrowserEventEmitter.putListener(listenerToPut.id, listenerToPut.registrationName, listenerToPut.listener); + EventPluginHub.putListener(listenerToPut.inst, listenerToPut.registrationName, listenerToPut.listener); } // There are so many media events, it makes sense to just @@ -6490,19 +6525,20 @@ function trapBubbledEventsLocal() { var inst = this; // If a component renders to null or if another component fatals and causes // the state of the tree to be corrupted, `node` here can be null. - !inst._rootNodeID ? "development" !== 'production' ? invariant(false, 'Must be mounted to trap events') : invariant(false) : undefined; - var node = ReactMount.getNode(inst._rootNodeID); - !node ? "development" !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : invariant(false) : undefined; + !inst._rootNodeID ? "development" !== 'production' ? invariant(false, 'Must be mounted to trap events') : invariant(false) : void 0; + var node = getNode(inst); + !node ? "development" !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : invariant(false) : void 0; switch (inst._tag) { case 'iframe': + case 'object': inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)]; break; case 'video': case 'audio': inst._wrapperState.listeners = []; - // create listener for each media event + // Create listener for each media event for (var event in mediaEvents) { if (mediaEvents.hasOwnProperty(event)) { inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes[event], mediaEvents[event], node)); @@ -6516,19 +6552,20 @@ function trapBubbledEventsLocal() { case 'form': inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit', node)]; break; + case 'input': + case 'select': + case 'textarea': + inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topInvalid, 'invalid', node)]; + break; } } -function mountReadyInputWrapper() { - ReactDOMInput.mountReadyWrapper(this); -} - function postUpdateSelectWrapper() { ReactDOMSelect.postUpdateWrapper(this); } // For HTML, certain tags should omit their close tag. We keep a whitelist for -// those special cased tags. +// those special-case tags. var omittedCloseTags = { 'area': true, @@ -6558,7 +6595,7 @@ var newlineEatingTags = { // For HTML, certain tags cannot have children. This has the same purpose as // `omittedCloseTags` except that `menuitem` should still have its closing tag. -var voidElementTags = assign({ +var voidElementTags = _assign({ 'menuitem': true }, omittedCloseTags); @@ -6568,27 +6605,21 @@ var voidElementTags = assign({ var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset var validatedTagCache = {}; -var hasOwnProperty = ({}).hasOwnProperty; +var hasOwnProperty = {}.hasOwnProperty; function validateDangerousTag(tag) { if (!hasOwnProperty.call(validatedTagCache, tag)) { - !VALID_TAG_REGEX.test(tag) ? "development" !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : invariant(false) : undefined; + !VALID_TAG_REGEX.test(tag) ? "development" !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : invariant(false) : void 0; validatedTagCache[tag] = true; } } -function processChildContextDev(context, inst) { - // Pass down our tag name to child components for validation purposes - context = assign({}, context); - var info = context[validateDOMNesting.ancestorInfoContextKey]; - context[validateDOMNesting.ancestorInfoContextKey] = validateDOMNesting.updatedAncestorInfo(info, inst._tag, inst); - return context; -} - function isCustomComponent(tagName, props) { return tagName.indexOf('-') >= 0 || props.is != null; } +var globalIdCounter = 1; + /** * Creates a new React class that is idempotent and capable of containing other * React components. It accepts event listeners and DOM properties that are @@ -6603,19 +6634,25 @@ function isCustomComponent(tagName, props) { * @constructor ReactDOMComponent * @extends ReactMultiChild */ -function ReactDOMComponent(tag) { +function ReactDOMComponent(element) { + var tag = element.type; validateDangerousTag(tag); + this._currentElement = element; this._tag = tag.toLowerCase(); + this._namespaceURI = null; this._renderedChildren = null; this._previousStyle = null; this._previousStyleCopy = null; + this._nativeNode = null; + this._nativeParent = null; this._rootNodeID = null; + this._domID = null; + this._nativeContainerInfo = null; this._wrapperState = null; this._topLevelWrapper = null; - this._nodeWithLegacyProperties = null; + this._flags = 0; if ("development" !== 'production') { - this._unprocessedContextDev = null; - this._processedContextDev = null; + this._ancestorInfo = null; } } @@ -6623,27 +6660,28 @@ ReactDOMComponent.displayName = 'ReactDOMComponent'; ReactDOMComponent.Mixin = { - construct: function (element) { - this._currentElement = element; - }, - /** * Generates root tag markup then recurses. This method has side effects and * is not idempotent. * * @internal - * @param {string} rootID The root DOM ID for this node. * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @param {?ReactDOMComponent} the containing DOM component instance + * @param {?object} info about the native container * @param {object} context * @return {string} The computed markup. */ - mountComponent: function (rootID, transaction, context) { - this._rootNodeID = rootID; + mountComponent: function (transaction, nativeParent, nativeContainerInfo, context) { + this._rootNodeID = globalIdCounter++; + this._domID = nativeContainerInfo._idCounter++; + this._nativeParent = nativeParent; + this._nativeContainerInfo = nativeContainerInfo; var props = this._currentElement.props; switch (this._tag) { case 'iframe': + case 'object': case 'img': case 'form': case 'video': @@ -6654,50 +6692,96 @@ ReactDOMComponent.Mixin = { transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); break; case 'button': - props = ReactDOMButton.getNativeProps(this, props, context); + props = ReactDOMButton.getNativeProps(this, props, nativeParent); break; case 'input': - ReactDOMInput.mountWrapper(this, props, context); - props = ReactDOMInput.getNativeProps(this, props, context); + ReactDOMInput.mountWrapper(this, props, nativeParent); + props = ReactDOMInput.getNativeProps(this, props); + transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); break; case 'option': - ReactDOMOption.mountWrapper(this, props, context); - props = ReactDOMOption.getNativeProps(this, props, context); + ReactDOMOption.mountWrapper(this, props, nativeParent); + props = ReactDOMOption.getNativeProps(this, props); break; case 'select': - ReactDOMSelect.mountWrapper(this, props, context); - props = ReactDOMSelect.getNativeProps(this, props, context); - context = ReactDOMSelect.processChildContext(this, props, context); + ReactDOMSelect.mountWrapper(this, props, nativeParent); + props = ReactDOMSelect.getNativeProps(this, props); + transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); break; case 'textarea': - ReactDOMTextarea.mountWrapper(this, props, context); - props = ReactDOMTextarea.getNativeProps(this, props, context); + ReactDOMTextarea.mountWrapper(this, props, nativeParent); + props = ReactDOMTextarea.getNativeProps(this, props); + transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); break; } assertValidProps(this, props); - if ("development" !== 'production') { - if (context[validateDOMNesting.ancestorInfoContextKey]) { - validateDOMNesting(this._tag, this, context[validateDOMNesting.ancestorInfoContextKey]); + + // We create tags in the namespace of their parent container, except HTML + // tags get no namespace. + var namespaceURI; + var parentTag; + if (nativeParent != null) { + namespaceURI = nativeParent._namespaceURI; + parentTag = nativeParent._tag; + } else if (nativeContainerInfo._tag) { + namespaceURI = nativeContainerInfo._namespaceURI; + parentTag = nativeContainerInfo._tag; + } + if (namespaceURI == null || namespaceURI === DOMNamespaces.svg && parentTag === 'foreignobject') { + namespaceURI = DOMNamespaces.html; + } + if (namespaceURI === DOMNamespaces.html) { + if (this._tag === 'svg') { + namespaceURI = DOMNamespaces.svg; + } else if (this._tag === 'math') { + namespaceURI = DOMNamespaces.mathml; } } + this._namespaceURI = namespaceURI; if ("development" !== 'production') { - this._unprocessedContextDev = context; - this._processedContextDev = processChildContextDev(context, this); - context = this._processedContextDev; + var parentInfo; + if (nativeParent != null) { + parentInfo = nativeParent._ancestorInfo; + } else if (nativeContainerInfo._tag) { + parentInfo = nativeContainerInfo._ancestorInfo; + } + if (parentInfo) { + // parentInfo should always be present except for the top-level + // component when server rendering + validateDOMNesting(this._tag, this, parentInfo); + } + this._ancestorInfo = validateDOMNesting.updatedAncestorInfo(parentInfo, this._tag, this); } var mountImage; if (transaction.useCreateElement) { - var ownerDocument = context[ReactMount.ownerDocumentContextKey]; - var el = ownerDocument.createElement(this._currentElement.type); - DOMPropertyOperations.setAttributeForID(el, this._rootNodeID); - // Populate node cache - ReactMount.getID(el); - this._updateDOMProperties({}, props, transaction, el); - this._createInitialChildren(transaction, props, context, el); - mountImage = el; + var ownerDocument = nativeContainerInfo._ownerDocument; + var el; + if (namespaceURI === DOMNamespaces.html) { + if (this._tag === 'script') { + // Create the script via .innerHTML so its "parser-inserted" flag is + // set to true and it does not execute + var div = ownerDocument.createElement('div'); + var type = this._currentElement.type; + div.innerHTML = '<' + type + '>'; + el = div.removeChild(div.firstChild); + } else { + el = ownerDocument.createElement(this._currentElement.type); + } + } else { + el = ownerDocument.createElementNS(namespaceURI, this._currentElement.type); + } + ReactDOMComponentTree.precacheNode(this, el); + this._flags |= Flags.hasCachedChildNodes; + if (!this._nativeParent) { + DOMPropertyOperations.setAttributeForRoot(el); + } + this._updateDOMProperties(null, props, transaction); + var lazyTree = DOMLazyTree(el); + this._createInitialChildren(transaction, props, context, lazyTree); + mountImage = lazyTree; } else { var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props); var tagContent = this._createContentMarkup(transaction, props, context); @@ -6709,10 +6793,8 @@ ReactDOMComponent.Mixin = { } switch (this._tag) { - case 'input': - transaction.getReactMountReady().enqueue(mountReadyInputWrapper, this); - // falls through case 'button': + case 'input': case 'select': case 'textarea': if (props.autoFocus) { @@ -6750,7 +6832,7 @@ ReactDOMComponent.Mixin = { } if (registrationNameModules.hasOwnProperty(propKey)) { if (propValue) { - enqueuePutListener(this._rootNodeID, propKey, propValue, transaction); + enqueuePutListener(this, propKey, propValue, transaction); } } else { if (propKey === STYLE) { @@ -6759,13 +6841,13 @@ ReactDOMComponent.Mixin = { // See `_updateDOMProperties`. style block this._previousStyle = propValue; } - propValue = this._previousStyleCopy = assign({}, props.style); + propValue = this._previousStyleCopy = _assign({}, props.style); } - propValue = CSSPropertyOperations.createMarkupForStyles(propValue); + propValue = CSSPropertyOperations.createMarkupForStyles(propValue, this); } var markup = null; if (this._tag != null && isCustomComponent(this._tag, props)) { - if (propKey !== CHILDREN) { + if (!RESERVED_PROPS.hasOwnProperty(propKey)) { markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue); } } else { @@ -6783,8 +6865,11 @@ ReactDOMComponent.Mixin = { return ret; } - var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID); - return ret + ' ' + markupForID; + if (!this._nativeParent) { + ret += ' ' + DOMPropertyOperations.createMarkupForRoot(); + } + ret += ' ' + DOMPropertyOperations.createMarkupForID(this._domID); + return ret; }, /** @@ -6833,23 +6918,23 @@ ReactDOMComponent.Mixin = { } }, - _createInitialChildren: function (transaction, props, context, el) { + _createInitialChildren: function (transaction, props, context, lazyTree) { // Intentional use of != to avoid catching zero/false. var innerHTML = props.dangerouslySetInnerHTML; if (innerHTML != null) { if (innerHTML.__html != null) { - setInnerHTML(el, innerHTML.__html); + DOMLazyTree.queueHTML(lazyTree, innerHTML.__html); } } else { var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null; var childrenToUse = contentToUse != null ? null : props.children; if (contentToUse != null) { // TODO: Validate that text is allowed as a child of this node - setTextContent(el, contentToUse); + DOMLazyTree.queueText(lazyTree, contentToUse); } else if (childrenToUse != null) { var mountImages = this.mountChildren(childrenToUse, transaction, context); for (var i = 0; i < mountImages.length; i++) { - el.appendChild(mountImages[i]); + DOMLazyTree.queueChild(lazyTree, mountImages[i]); } } } @@ -6908,25 +6993,10 @@ ReactDOMComponent.Mixin = { break; } - if ("development" !== 'production') { - // If the context is reference-equal to the old one, pass down the same - // processed object so the update bailout in ReactReconciler behaves - // correctly (and identically in dev and prod). See #5005. - if (this._unprocessedContextDev !== context) { - this._unprocessedContextDev = context; - this._processedContextDev = processChildContextDev(context, this); - } - context = this._processedContextDev; - } - assertValidProps(this, nextProps); - this._updateDOMProperties(lastProps, nextProps, transaction, null); + this._updateDOMProperties(lastProps, nextProps, transaction); this._updateDOMChildren(lastProps, nextProps, transaction, context); - if (!canDefineProperty && this._nodeWithLegacyProperties) { - this._nodeWithLegacyProperties.props = nextProps; - } - if (this._tag === 'select') { // native component that allows setting these optional * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. @@ -7524,11 +7876,15 @@ function forceUpdateIfMounted() { * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html */ var ReactDOMInput = { - getNativeProps: function (inst, props, context) { + getNativeProps: function (inst, props) { var value = LinkedValueUtils.getValue(props); var checked = LinkedValueUtils.getChecked(props); - var nativeProps = assign({}, props, { + var nativeProps = _assign({ + // Make sure we set .type before any other properties (setting .value + // before .type means .value is lost in IE11 and below) + type: undefined + }, props, { defaultChecked: undefined, defaultValue: undefined, value: value != null ? value : inst._wrapperState.initialValue, @@ -7542,39 +7898,71 @@ var ReactDOMInput = { mountWrapper: function (inst, props) { if ("development" !== 'production') { LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner); + + if (props.valueLink !== undefined && !didWarnValueLink) { + "development" !== 'production' ? warning(false, '`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0; + didWarnValueLink = true; + } + if (props.checkedLink !== undefined && !didWarnCheckedLink) { + "development" !== 'production' ? warning(false, '`checkedLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0; + didWarnCheckedLink = true; + } + if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { + "development" !== 'production' ? warning(false, 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; + didWarnCheckedDefaultChecked = true; + } + if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { + "development" !== 'production' ? warning(false, 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; + didWarnValueDefaultValue = true; + } + warnIfValueIsNull(props); } var defaultValue = props.defaultValue; inst._wrapperState = { initialChecked: props.defaultChecked || false, initialValue: defaultValue != null ? defaultValue : null, + listeners: null, onChange: _handleChange.bind(inst) }; - }, - mountReadyWrapper: function (inst) { - // Can't be in mountWrapper or else server rendering leaks. - instancesByReactID[inst._rootNodeID] = inst; - }, - - unmountWrapper: function (inst) { - delete instancesByReactID[inst._rootNodeID]; + if ("development" !== 'production') { + inst._wrapperState.controlled = props.checked !== undefined || props.value !== undefined; + } }, updateWrapper: function (inst) { var props = inst._currentElement.props; + if ("development" !== 'production') { + warnIfValueIsNull(props); + + var initialValue = inst._wrapperState.initialChecked || inst._wrapperState.initialValue; + var defaultValue = props.defaultChecked || props.defaultValue; + var controlled = props.checked !== undefined || props.value !== undefined; + var owner = inst._currentElement._owner; + + if ((initialValue || !inst._wrapperState.controlled) && controlled && !didWarnUncontrolledToControlled) { + "development" !== 'production' ? warning(false, '%s is changing a uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; + didWarnUncontrolledToControlled = true; + } + if (inst._wrapperState.controlled && (defaultValue || !controlled) && !didWarnControlledToUncontrolled) { + "development" !== 'production' ? warning(false, '%s is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; + didWarnControlledToUncontrolled = true; + } + } + // TODO: Shouldn't this be getChecked(props)? var checked = props.checked; if (checked != null) { - ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'checked', checked || false); + DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'checked', checked || false); } var value = LinkedValueUtils.getValue(props); if (value != null) { // Cast `value` to a string to ensure the value is set correctly. While // browsers typically do this as necessary, jsdom doesn't. - ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value); + DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'value', '' + value); } } }; @@ -7591,7 +7979,7 @@ function _handleChange(event) { var name = props.name; if (props.type === 'radio' && name != null) { - var rootNode = ReactMount.getNode(this._rootNodeID); + var rootNode = ReactDOMComponentTree.getNodeFromInstance(this); var queryRoot = rootNode; while (queryRoot.parentNode) { @@ -7614,11 +8002,9 @@ function _handleChange(event) { // This will throw if radio buttons rendered by different copies of React // and the same name are rendered into the same form (same as #1939). // That's probably okay; we don't support it just as we don't support - // mixing React with non-React. - var otherID = ReactMount.getID(otherNode); - !otherID ? "development" !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.') : invariant(false) : undefined; - var otherInstance = instancesByReactID[otherID]; - !otherInstance ? "development" !== 'production' ? invariant(false, 'ReactDOMInput: Unknown radio button ID %s.', otherID) : invariant(false) : undefined; + // mixing React radio buttons with non-React ones. + var otherInstance = ReactDOMComponentTree.getInstanceFromNode(otherNode); + !otherInstance ? "development" !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.') : invariant(false) : void 0; // If this is a controlled radio button group, forcing the input that // was previously checked to update will cause it to be come re-checked // as appropriate. @@ -7630,9 +8016,26 @@ function _handleChange(event) { } module.exports = ReactDOMInput; -},{"144":144,"22":22,"23":23,"40":40,"65":65,"83":83}],42:[function(_dereq_,module,exports){ +},{"11":11,"156":156,"166":166,"167":167,"22":22,"38":38,"92":92}],46:[function(_dereq_,module,exports){ /** - * Copyright 2013-2015, Facebook, Inc. + * Copyright 2013-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOMInstrumentation + */ + +'use strict'; + +var ReactDOMDebugTool = _dereq_(40); + +module.exports = { debugTool: ReactDOMDebugTool }; +},{"40":40}],47:[function(_dereq_,module,exports){ +/** + * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -7644,28 +8047,30 @@ module.exports = ReactDOMInput; 'use strict'; -var ReactChildren = _dereq_(28); -var ReactDOMSelect = _dereq_(43); +var _assign = _dereq_(167); -var assign = _dereq_(23); -var warning = _dereq_(155); +var ReactChildren = _dereq_(27); +var ReactDOMSelect = _dereq_(48); -var valueContextKey = ReactDOMSelect.valueContextKey; +var warning = _dereq_(166); /** * Implements an